0007-fdpic.diff 68 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069
  1. diff --git a/gcc/config/sh/constraints.md b/gcc/config/sh/constraints.md
  2. index 4d1eb2d..41c88a2 100644
  3. --- a/gcc/config/sh/constraints.md
  4. +++ b/gcc/config/sh/constraints.md
  5. @@ -25,6 +25,7 @@
  6. ;; Bsc: SCRATCH - for the scratch register in movsi_ie in the
  7. ;; fldi0 / fldi0 cases
  8. ;; Cxx: Constants other than only CONST_INT
  9. +;; Ccl: call site label
  10. ;; Css: signed 16-bit constant, literal or symbolic
  11. ;; Csu: unsigned 16-bit constant, literal or symbolic
  12. ;; Csy: label or symbol
  13. @@ -233,6 +234,11 @@
  14. hence mova is being used, hence do not select this pattern."
  15. (match_code "scratch"))
  16. +(define_constraint "Ccl"
  17. + "A call site label, for bsrf."
  18. + (and (match_code "unspec")
  19. + (match_test "XINT (op, 1) == UNSPEC_CALLER")))
  20. +
  21. (define_constraint "Css"
  22. "A signed 16-bit constant, literal or symbolic."
  23. (and (match_code "const")
  24. diff --git a/gcc/config/sh/linux.h b/gcc/config/sh/linux.h
  25. index a9dd43a..5d4dd1f 100644
  26. --- a/gcc/config/sh/linux.h
  27. +++ b/gcc/config/sh/linux.h
  28. @@ -69,7 +69,8 @@ along with GCC; see the file COPYING3. If not see
  29. #define GLIBC_DYNAMIC_LINKER "/lib/ld-linux.so.2"
  30. #undef SUBTARGET_LINK_EMUL_SUFFIX
  31. -#define SUBTARGET_LINK_EMUL_SUFFIX "_linux"
  32. +#define SUBTARGET_LINK_EMUL_SUFFIX "%{mfdpic:_fd;:_linux}"
  33. +
  34. #undef SUBTARGET_LINK_SPEC
  35. #define SUBTARGET_LINK_SPEC \
  36. "%{shared:-shared} \
  37. diff --git a/gcc/config/sh/sh-c.c b/gcc/config/sh/sh-c.c
  38. index a98c148..01a12e6 100644
  39. --- a/gcc/config/sh/sh-c.c
  40. +++ b/gcc/config/sh/sh-c.c
  41. @@ -141,6 +141,11 @@ sh_cpu_cpp_builtins (cpp_reader* pfile)
  42. builtin_define ("__HITACHI__");
  43. if (TARGET_FMOVD)
  44. builtin_define ("__FMOVD_ENABLED__");
  45. + if (TARGET_FDPIC)
  46. + {
  47. + builtin_define ("__SH_FDPIC__");
  48. + builtin_define ("__FDPIC__");
  49. + }
  50. builtin_define (TARGET_LITTLE_ENDIAN
  51. ? "__LITTLE_ENDIAN__" : "__BIG_ENDIAN__");
  52. diff --git a/gcc/config/sh/sh-mem.cc b/gcc/config/sh/sh-mem.cc
  53. index 23a7287..58a5fd0 100644
  54. --- a/gcc/config/sh/sh-mem.cc
  55. +++ b/gcc/config/sh/sh-mem.cc
  56. @@ -122,11 +122,13 @@ expand_block_move (rtx *operands)
  57. rtx func_addr_rtx = gen_reg_rtx (Pmode);
  58. rtx r4 = gen_rtx_REG (SImode, 4);
  59. rtx r5 = gen_rtx_REG (SImode, 5);
  60. + rtx lab;
  61. - function_symbol (func_addr_rtx, "__movmemSI12_i4", SFUNC_STATIC);
  62. + function_symbol (func_addr_rtx, "__movmemSI12_i4", SFUNC_STATIC,
  63. + &lab);
  64. force_into (XEXP (operands[0], 0), r4);
  65. force_into (XEXP (operands[1], 0), r5);
  66. - emit_insn (gen_block_move_real_i4 (func_addr_rtx));
  67. + emit_insn (gen_block_move_real_i4 (func_addr_rtx, lab));
  68. return true;
  69. }
  70. else if (! optimize_size)
  71. @@ -137,15 +139,16 @@ expand_block_move (rtx *operands)
  72. rtx r4 = gen_rtx_REG (SImode, 4);
  73. rtx r5 = gen_rtx_REG (SImode, 5);
  74. rtx r6 = gen_rtx_REG (SImode, 6);
  75. + rtx lab;
  76. entry_name = (bytes & 4 ? "__movmem_i4_odd" : "__movmem_i4_even");
  77. - function_symbol (func_addr_rtx, entry_name, SFUNC_STATIC);
  78. + function_symbol (func_addr_rtx, entry_name, SFUNC_STATIC, &lab);
  79. force_into (XEXP (operands[0], 0), r4);
  80. force_into (XEXP (operands[1], 0), r5);
  81. dwords = bytes >> 3;
  82. emit_insn (gen_move_insn (r6, GEN_INT (dwords - 1)));
  83. - emit_insn (gen_block_lump_real_i4 (func_addr_rtx));
  84. + emit_insn (gen_block_lump_real_i4 (func_addr_rtx, lab));
  85. return true;
  86. }
  87. else
  88. @@ -157,12 +160,13 @@ expand_block_move (rtx *operands)
  89. rtx func_addr_rtx = gen_reg_rtx (Pmode);
  90. rtx r4 = gen_rtx_REG (SImode, 4);
  91. rtx r5 = gen_rtx_REG (SImode, 5);
  92. + rtx lab;
  93. sprintf (entry, "__movmemSI%d", bytes);
  94. - function_symbol (func_addr_rtx, entry, SFUNC_STATIC);
  95. + function_symbol (func_addr_rtx, entry, SFUNC_STATIC, &lab);
  96. force_into (XEXP (operands[0], 0), r4);
  97. force_into (XEXP (operands[1], 0), r5);
  98. - emit_insn (gen_block_move_real (func_addr_rtx));
  99. + emit_insn (gen_block_move_real (func_addr_rtx, lab));
  100. return true;
  101. }
  102. @@ -175,8 +179,9 @@ expand_block_move (rtx *operands)
  103. rtx r4 = gen_rtx_REG (SImode, 4);
  104. rtx r5 = gen_rtx_REG (SImode, 5);
  105. rtx r6 = gen_rtx_REG (SImode, 6);
  106. + rtx lab;
  107. - function_symbol (func_addr_rtx, "__movmem", SFUNC_STATIC);
  108. + function_symbol (func_addr_rtx, "__movmem", SFUNC_STATIC, &lab);
  109. force_into (XEXP (operands[0], 0), r4);
  110. force_into (XEXP (operands[1], 0), r5);
  111. @@ -189,7 +194,7 @@ expand_block_move (rtx *operands)
  112. final_switch = 16 - ((bytes / 4) % 16);
  113. while_loop = ((bytes / 4) / 16 - 1) * 16;
  114. emit_insn (gen_move_insn (r6, GEN_INT (while_loop + final_switch)));
  115. - emit_insn (gen_block_lump_real (func_addr_rtx));
  116. + emit_insn (gen_block_lump_real (func_addr_rtx, lab));
  117. return true;
  118. }
  119. diff --git a/gcc/config/sh/sh-protos.h b/gcc/config/sh/sh-protos.h
  120. index f94459f..222f4d5 100644
  121. --- a/gcc/config/sh/sh-protos.h
  122. +++ b/gcc/config/sh/sh-protos.h
  123. @@ -377,7 +377,7 @@ extern void fpscr_set_from_mem (int, HARD_REG_SET);
  124. extern void sh_pr_interrupt (struct cpp_reader *);
  125. extern void sh_pr_trapa (struct cpp_reader *);
  126. extern void sh_pr_nosave_low_regs (struct cpp_reader *);
  127. -extern rtx function_symbol (rtx, const char *, enum sh_function_kind);
  128. +extern rtx function_symbol (rtx, const char *, enum sh_function_kind, rtx *);
  129. extern rtx sh_get_pr_initial_val (void);
  130. extern void sh_init_cumulative_args (CUMULATIVE_ARGS *, tree, rtx, tree,
  131. @@ -396,4 +396,6 @@ extern bool sh_hard_regno_mode_ok (unsigned int, machine_mode);
  132. extern machine_mode sh_hard_regno_caller_save_mode (unsigned int, unsigned int,
  133. machine_mode);
  134. extern bool sh_can_use_simple_return_p (void);
  135. +extern rtx sh_load_function_descriptor (rtx);
  136. +extern rtx sh_our_fdpic_reg (void);
  137. #endif /* ! GCC_SH_PROTOS_H */
  138. diff --git a/gcc/config/sh/sh.c b/gcc/config/sh/sh.c
  139. index 904201b..b468d69 100644
  140. --- a/gcc/config/sh/sh.c
  141. +++ b/gcc/config/sh/sh.c
  142. @@ -268,6 +268,7 @@ static rtx sh_expand_builtin (tree, rtx, rtx, machine_mode, int);
  143. static void sh_output_mi_thunk (FILE *, tree, HOST_WIDE_INT,
  144. HOST_WIDE_INT, tree);
  145. static void sh_file_start (void);
  146. +static bool sh_assemble_integer (rtx, unsigned, int);
  147. static bool flow_dependent_p (rtx, rtx);
  148. static void flow_dependent_p_1 (rtx, const_rtx, void *);
  149. static int shiftcosts (rtx);
  150. @@ -276,6 +277,7 @@ static int addsubcosts (rtx);
  151. static int multcosts (rtx);
  152. static bool unspec_caller_rtx_p (rtx);
  153. static bool sh_cannot_copy_insn_p (rtx_insn *);
  154. +static bool sh_cannot_force_const_mem_p (machine_mode, rtx);
  155. static bool sh_rtx_costs (rtx, int, int, int, int *, bool);
  156. static int sh_address_cost (rtx, machine_mode, addr_space_t, bool);
  157. static int sh_pr_n_sets (void);
  158. @@ -333,6 +335,7 @@ static void sh_encode_section_info (tree, rtx, int);
  159. static bool sh2a_function_vector_p (tree);
  160. static void sh_trampoline_init (rtx, tree, rtx);
  161. static rtx sh_trampoline_adjust_address (rtx);
  162. +static int sh_reloc_rw_mask (void);
  163. static void sh_conditional_register_usage (void);
  164. static bool sh_legitimate_constant_p (machine_mode, rtx);
  165. static int mov_insn_size (machine_mode, bool);
  166. @@ -421,6 +424,9 @@ static const struct attribute_spec sh_attribute_table[] =
  167. #undef TARGET_ASM_FILE_START_FILE_DIRECTIVE
  168. #define TARGET_ASM_FILE_START_FILE_DIRECTIVE true
  169. +#undef TARGET_ASM_INTEGER
  170. +#define TARGET_ASM_INTEGER sh_assemble_integer
  171. +
  172. #undef TARGET_REGISTER_MOVE_COST
  173. #define TARGET_REGISTER_MOVE_COST sh_register_move_cost
  174. @@ -679,6 +685,12 @@ static const struct attribute_spec sh_attribute_table[] =
  175. #undef TARGET_ATOMIC_TEST_AND_SET_TRUEVAL
  176. #define TARGET_ATOMIC_TEST_AND_SET_TRUEVAL 0x80
  177. +#undef TARGET_CANNOT_FORCE_CONST_MEM
  178. +#define TARGET_CANNOT_FORCE_CONST_MEM sh_cannot_force_const_mem_p
  179. +
  180. +#undef TARGET_ASM_RELOC_RW_MASK
  181. +#define TARGET_ASM_RELOC_RW_MASK sh_reloc_rw_mask
  182. +
  183. struct gcc_target targetm = TARGET_INITIALIZER;
  184. @@ -996,6 +1008,13 @@ sh_option_override (void)
  185. if (! global_options_set.x_TARGET_ZDCBRANCH && TARGET_HARD_SH4)
  186. TARGET_ZDCBRANCH = 1;
  187. + if (TARGET_FDPIC && !flag_pic)
  188. + flag_pic = 2;
  189. +
  190. + if (TARGET_FDPIC
  191. + && (TARGET_SHMEDIA || TARGET_SHCOMPACT || !TARGET_SH2))
  192. + sorry ("non-SH2 FDPIC");
  193. +
  194. for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
  195. if (! VALID_REGISTER_P (regno))
  196. sh_register_names[regno][0] = '\0';
  197. @@ -1004,7 +1023,7 @@ sh_option_override (void)
  198. if (! VALID_REGISTER_P (ADDREGNAMES_REGNO (regno)))
  199. sh_additional_register_names[regno][0] = '\0';
  200. - if ((flag_pic && ! TARGET_PREFERGOT)
  201. + if (((flag_pic || TARGET_FDPIC) && ! TARGET_PREFERGOT)
  202. || (TARGET_SHMEDIA && !TARGET_PT_FIXED))
  203. flag_no_function_cse = 1;
  204. @@ -1687,6 +1706,14 @@ sh_asm_output_addr_const_extra (FILE *file, rtx x)
  205. output_addr_const (file, XVECEXP (x, 0, 1));
  206. fputs ("-.)", file);
  207. break;
  208. + case UNSPEC_GOTFUNCDESC:
  209. + output_addr_const (file, XVECEXP (x, 0, 0));
  210. + fputs ("@GOTFUNCDESC", file);
  211. + break;
  212. + case UNSPEC_GOTOFFFUNCDESC:
  213. + output_addr_const (file, XVECEXP (x, 0, 0));
  214. + fputs ("@GOTOFFFUNCDESC", file);
  215. + break;
  216. default:
  217. return false;
  218. }
  219. @@ -1713,8 +1740,10 @@ sh_encode_section_info (tree decl, rtx rtl, int first)
  220. void
  221. prepare_move_operands (rtx operands[], machine_mode mode)
  222. {
  223. + rtx tmp, base, offset;
  224. +
  225. if ((mode == SImode || mode == DImode)
  226. - && flag_pic
  227. + && (flag_pic || TARGET_FDPIC)
  228. && ! ((mode == Pmode || mode == ptr_mode)
  229. && tls_symbolic_operand (operands[1], Pmode) != TLS_MODEL_NONE))
  230. {
  231. @@ -1850,7 +1879,7 @@ prepare_move_operands (rtx operands[], machine_mode mode)
  232. {
  233. rtx tga_op1, tga_ret, tmp, tmp2;
  234. - if (! flag_pic
  235. + if (! flag_pic && ! TARGET_FDPIC
  236. && (tls_kind == TLS_MODEL_GLOBAL_DYNAMIC
  237. || tls_kind == TLS_MODEL_LOCAL_DYNAMIC
  238. || tls_kind == TLS_MODEL_INITIAL_EXEC))
  239. @@ -1871,6 +1900,11 @@ prepare_move_operands (rtx operands[], machine_mode mode)
  240. {
  241. case TLS_MODEL_GLOBAL_DYNAMIC:
  242. tga_ret = gen_rtx_REG (Pmode, R0_REG);
  243. + if (TARGET_FDPIC)
  244. + {
  245. + rtx pic_reg = gen_rtx_REG (Pmode, PIC_REG);
  246. + emit_move_insn (pic_reg, OUR_FDPIC_REG);
  247. + }
  248. emit_call_insn (gen_tls_global_dynamic (tga_ret, op1));
  249. tmp = gen_reg_rtx (Pmode);
  250. emit_move_insn (tmp, tga_ret);
  251. @@ -1879,6 +1913,11 @@ prepare_move_operands (rtx operands[], machine_mode mode)
  252. case TLS_MODEL_LOCAL_DYNAMIC:
  253. tga_ret = gen_rtx_REG (Pmode, R0_REG);
  254. + if (TARGET_FDPIC)
  255. + {
  256. + rtx pic_reg = gen_rtx_REG (Pmode, PIC_REG);
  257. + emit_move_insn (pic_reg, OUR_FDPIC_REG);
  258. + }
  259. emit_call_insn (gen_tls_local_dynamic (tga_ret, op1));
  260. tmp = gen_reg_rtx (Pmode);
  261. @@ -1896,6 +1935,11 @@ prepare_move_operands (rtx operands[], machine_mode mode)
  262. case TLS_MODEL_INITIAL_EXEC:
  263. tga_op1 = !can_create_pseudo_p () ? op0 : gen_reg_rtx (Pmode);
  264. tmp = gen_sym2GOTTPOFF (op1);
  265. + if (TARGET_FDPIC)
  266. + {
  267. + rtx pic_reg = gen_rtx_REG (Pmode, PIC_REG);
  268. + emit_move_insn (pic_reg, OUR_FDPIC_REG);
  269. + }
  270. emit_insn (gen_tls_initial_exec (tga_op1, tmp));
  271. op1 = tga_op1;
  272. break;
  273. @@ -1922,6 +1966,20 @@ prepare_move_operands (rtx operands[], machine_mode mode)
  274. operands[1] = op1;
  275. }
  276. }
  277. +
  278. + if (SH_OFFSETS_MUST_BE_WITHIN_SECTIONS_P)
  279. + {
  280. + split_const (operands[1], &base, &offset);
  281. + if (GET_CODE (base) == SYMBOL_REF
  282. + && !offset_within_block_p (base, INTVAL (offset)))
  283. + {
  284. + tmp = can_create_pseudo_p () ? gen_reg_rtx (mode) : operands[0];
  285. + emit_move_insn (tmp, base);
  286. + if (!arith_operand (offset, mode))
  287. + offset = force_reg (mode, offset);
  288. + emit_insn (gen_add3_insn (operands[0], tmp, offset));
  289. + }
  290. + }
  291. }
  292. /* Implement the canonicalize_comparison target hook for the combine
  293. @@ -3026,6 +3084,26 @@ sh_file_start (void)
  294. }
  295. }
  296. +/* Implementation of TARGET_ASM_INTEGER for SH. Pointers to functions
  297. + need to be output as pointers to function descriptors for
  298. + FDPIC. */
  299. +
  300. +static bool
  301. +sh_assemble_integer (rtx value, unsigned int size, int aligned_p)
  302. +{
  303. + if (TARGET_FDPIC
  304. + && size == UNITS_PER_WORD
  305. + && GET_CODE (value) == SYMBOL_REF
  306. + && SYMBOL_REF_FUNCTION_P (value))
  307. + {
  308. + fputs ("\t.long\t", asm_out_file);
  309. + output_addr_const (asm_out_file, value);
  310. + fputs ("@FUNCDESC\n", asm_out_file);
  311. + return true;
  312. + }
  313. + return default_assemble_integer (value, size, aligned_p);
  314. +}
  315. +
  316. /* Check if PAT includes UNSPEC_CALLER unspec pattern. */
  317. static bool
  318. unspec_caller_rtx_p (rtx pat)
  319. @@ -3052,7 +3130,7 @@ sh_cannot_copy_insn_p (rtx_insn *insn)
  320. {
  321. rtx pat;
  322. - if (!reload_completed || !flag_pic)
  323. + if (!reload_completed || (!flag_pic && !TARGET_FDPIC))
  324. return false;
  325. if (!NONJUMP_INSN_P (insn))
  326. @@ -3061,6 +3139,19 @@ sh_cannot_copy_insn_p (rtx_insn *insn)
  327. return false;
  328. pat = PATTERN (insn);
  329. +
  330. + if (GET_CODE (pat) == CLOBBER || GET_CODE (pat) == USE)
  331. + return false;
  332. +
  333. + if (TARGET_FDPIC
  334. + && GET_CODE (pat) == PARALLEL)
  335. + {
  336. + rtx t = XVECEXP (pat, 0, XVECLEN (pat, 0) - 1);
  337. + if (GET_CODE (t) == USE
  338. + && unspec_caller_rtx_p (XEXP (t, 0)))
  339. + return true;
  340. + }
  341. +
  342. if (GET_CODE (pat) != SET)
  343. return false;
  344. pat = SET_SRC (pat);
  345. @@ -4037,6 +4128,7 @@ expand_ashiftrt (rtx *operands)
  346. rtx wrk;
  347. char func[18];
  348. int value;
  349. + rtx lab;
  350. if (TARGET_DYNSHIFT)
  351. {
  352. @@ -4102,8 +4194,8 @@ expand_ashiftrt (rtx *operands)
  353. /* Load the value into an arg reg and call a helper. */
  354. emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
  355. sprintf (func, "__ashiftrt_r4_%d", value);
  356. - function_symbol (wrk, func, SFUNC_STATIC);
  357. - emit_insn (gen_ashrsi3_n (GEN_INT (value), wrk));
  358. + function_symbol (wrk, func, SFUNC_STATIC, &lab);
  359. + emit_insn (gen_ashrsi3_n (GEN_INT (value), wrk, lab));
  360. emit_move_insn (operands[0], gen_rtx_REG (SImode, 4));
  361. return true;
  362. }
  363. @@ -7954,7 +8046,9 @@ sh_expand_prologue (void)
  364. stack_usage += d;
  365. }
  366. - if (flag_pic && df_regs_ever_live_p (PIC_OFFSET_TABLE_REGNUM))
  367. + if (flag_pic
  368. + && !TARGET_FDPIC
  369. + && df_regs_ever_live_p (PIC_OFFSET_TABLE_REGNUM))
  370. emit_insn (gen_GOTaddr2picreg (const0_rtx));
  371. if (SHMEDIA_REGS_STACK_ADJUST ())
  372. @@ -7964,7 +8058,7 @@ sh_expand_prologue (void)
  373. function_symbol (gen_rtx_REG (Pmode, R0_REG),
  374. (TARGET_FPU_ANY
  375. ? "__GCC_push_shmedia_regs"
  376. - : "__GCC_push_shmedia_regs_nofpu"), SFUNC_GOT);
  377. + : "__GCC_push_shmedia_regs_nofpu"), SFUNC_GOT, NULL);
  378. emit_insn (gen_shmedia_save_restore_regs_compact
  379. (GEN_INT (-SHMEDIA_REGS_STACK_ADJUST ())));
  380. }
  381. @@ -7987,7 +8081,7 @@ sh_expand_prologue (void)
  382. /* This must NOT go through the PLT, otherwise mach and macl
  383. may be clobbered. */
  384. function_symbol (gen_rtx_REG (Pmode, R0_REG),
  385. - "__GCC_shcompact_incoming_args", SFUNC_GOT);
  386. + "__GCC_shcompact_incoming_args", SFUNC_GOT, NULL);
  387. emit_insn (gen_shcompact_incoming_args ());
  388. }
  389. @@ -8077,7 +8171,7 @@ sh_expand_epilogue (bool sibcall_p)
  390. function_symbol (gen_rtx_REG (Pmode, R0_REG),
  391. (TARGET_FPU_ANY
  392. ? "__GCC_pop_shmedia_regs"
  393. - : "__GCC_pop_shmedia_regs_nofpu"), SFUNC_GOT);
  394. + : "__GCC_pop_shmedia_regs_nofpu"), SFUNC_GOT, NULL);
  395. /* This must NOT go through the PLT, otherwise mach and macl
  396. may be clobbered. */
  397. emit_insn (gen_shmedia_save_restore_regs_compact
  398. @@ -10458,7 +10552,9 @@ nonpic_symbol_mentioned_p (rtx x)
  399. || XINT (x, 1) == UNSPEC_PLT
  400. || XINT (x, 1) == UNSPEC_PCREL
  401. || XINT (x, 1) == UNSPEC_SYMOFF
  402. - || XINT (x, 1) == UNSPEC_PCREL_SYMOFF))
  403. + || XINT (x, 1) == UNSPEC_PCREL_SYMOFF
  404. + || XINT (x, 1) == UNSPEC_GOTFUNCDESC
  405. + || XINT (x, 1) == UNSPEC_GOTOFFFUNCDESC))
  406. return false;
  407. fmt = GET_RTX_FORMAT (GET_CODE (x));
  408. @@ -10493,7 +10589,28 @@ legitimize_pic_address (rtx orig, machine_mode mode ATTRIBUTE_UNUSED,
  409. if (reg == NULL_RTX)
  410. reg = gen_reg_rtx (Pmode);
  411. - emit_insn (gen_symGOTOFF2reg (reg, orig));
  412. + if (TARGET_FDPIC
  413. + && GET_CODE (orig) == SYMBOL_REF
  414. + && SYMBOL_REF_FUNCTION_P (orig))
  415. + {
  416. + /* Weak functions may be NULL which doesn't work with
  417. + GOTOFFFUNCDESC because the runtime offset is not known. */
  418. + if (SYMBOL_REF_WEAK (orig))
  419. + emit_insn (gen_symGOTFUNCDESC2reg (reg, orig));
  420. + else
  421. + emit_insn (gen_symGOTOFFFUNCDESC2reg (reg, orig));
  422. + }
  423. + else if (TARGET_FDPIC
  424. + && (GET_CODE (orig) == LABEL_REF
  425. + || (GET_CODE (orig) == SYMBOL_REF
  426. + && SYMBOL_REF_DECL (orig)
  427. + && (TREE_READONLY (SYMBOL_REF_DECL (orig))
  428. + || SYMBOL_REF_EXTERNAL_P (orig)
  429. + || DECL_SECTION_NAME(SYMBOL_REF_DECL(orig))) )))
  430. + /* In FDPIC, GOTOFF can only be used for writable data. */
  431. + emit_insn (gen_symGOT2reg (reg, orig));
  432. + else
  433. + emit_insn (gen_symGOTOFF2reg (reg, orig));
  434. return reg;
  435. }
  436. else if (GET_CODE (orig) == SYMBOL_REF)
  437. @@ -10501,7 +10618,10 @@ legitimize_pic_address (rtx orig, machine_mode mode ATTRIBUTE_UNUSED,
  438. if (reg == NULL_RTX)
  439. reg = gen_reg_rtx (Pmode);
  440. - emit_insn (gen_symGOT2reg (reg, orig));
  441. + if (TARGET_FDPIC && SYMBOL_REF_FUNCTION_P (orig))
  442. + emit_insn (gen_symGOTFUNCDESC2reg (reg, orig));
  443. + else
  444. + emit_insn (gen_symGOT2reg (reg, orig));
  445. return reg;
  446. }
  447. return orig;
  448. @@ -11675,20 +11795,40 @@ sh_trampoline_init (rtx tramp_mem, tree fndecl, rtx cxt)
  449. emit_insn (gen_initialize_trampoline (tramp, cxt, fnaddr));
  450. return;
  451. }
  452. - emit_move_insn (change_address (tramp_mem, SImode, NULL_RTX),
  453. - gen_int_mode (TARGET_LITTLE_ENDIAN ? 0xd301d202 : 0xd202d301,
  454. - SImode));
  455. - emit_move_insn (adjust_address (tramp_mem, SImode, 4),
  456. - gen_int_mode (TARGET_LITTLE_ENDIAN ? 0x0009422b : 0x422b0009,
  457. - SImode));
  458. - emit_move_insn (adjust_address (tramp_mem, SImode, 8), cxt);
  459. - emit_move_insn (adjust_address (tramp_mem, SImode, 12), fnaddr);
  460. + if (TARGET_FDPIC)
  461. + {
  462. + rtx a = force_reg (Pmode, plus_constant (Pmode, XEXP (tramp_mem, 0), 8));
  463. + emit_move_insn (adjust_address (tramp_mem, SImode, 0), a);
  464. + emit_move_insn (adjust_address (tramp_mem, SImode, 4), OUR_FDPIC_REG);
  465. + emit_move_insn (adjust_address (tramp_mem, SImode, 8),
  466. + gen_int_mode (TARGET_LITTLE_ENDIAN ? 0xd203d302 : 0xd302d203,
  467. + SImode));
  468. + emit_move_insn (adjust_address (tramp_mem, SImode, 12),
  469. + gen_int_mode (TARGET_LITTLE_ENDIAN ? 0x5c216122 : 0x61225c21,
  470. + SImode));
  471. + emit_move_insn (adjust_address (tramp_mem, SImode, 16),
  472. + gen_int_mode (TARGET_LITTLE_ENDIAN ? 0x0009412b : 0x412b0009,
  473. + SImode));
  474. + emit_move_insn (adjust_address (tramp_mem, SImode, 20), cxt);
  475. + emit_move_insn (adjust_address (tramp_mem, SImode, 24), fnaddr);
  476. + }
  477. + else
  478. + {
  479. + emit_move_insn (change_address (tramp_mem, SImode, NULL_RTX),
  480. + gen_int_mode (TARGET_LITTLE_ENDIAN ? 0xd301d202 : 0xd202d301,
  481. + SImode));
  482. + emit_move_insn (adjust_address (tramp_mem, SImode, 4),
  483. + gen_int_mode (TARGET_LITTLE_ENDIAN ? 0x0009422b : 0x422b0009,
  484. + SImode));
  485. + emit_move_insn (adjust_address (tramp_mem, SImode, 8), cxt);
  486. + emit_move_insn (adjust_address (tramp_mem, SImode, 12), fnaddr);
  487. + }
  488. if (TARGET_HARD_SH4 || TARGET_SH5)
  489. {
  490. if (!TARGET_INLINE_IC_INVALIDATE
  491. || (!(TARGET_SH4A || TARGET_SH4_300) && TARGET_USERMODE))
  492. emit_library_call (function_symbol (NULL, "__ic_invalidate",
  493. - FUNCTION_ORDINARY),
  494. + FUNCTION_ORDINARY, NULL),
  495. LCT_NORMAL, VOIDmode, 1, tramp, SImode);
  496. else
  497. emit_insn (gen_ic_invalidate_line (tramp));
  498. @@ -11718,7 +11858,7 @@ sh_function_ok_for_sibcall (tree decl, tree exp ATTRIBUTE_UNUSED)
  499. && (! TARGET_SHCOMPACT
  500. || crtl->args.info.stack_regs == 0)
  501. && ! sh_cfun_interrupt_handler_p ()
  502. - && (! flag_pic
  503. + && (! flag_pic || TARGET_FDPIC
  504. || (decl && ! (TREE_PUBLIC (decl) || DECL_WEAK (decl)))
  505. || (decl && DECL_VISIBILITY (decl) != VISIBILITY_DEFAULT)));
  506. }
  507. @@ -11732,7 +11872,7 @@ sh_expand_sym_label2reg (rtx reg, rtx sym, rtx lab, bool sibcall_p)
  508. if (!is_weak && SYMBOL_REF_LOCAL_P (sym))
  509. emit_insn (gen_sym_label2reg (reg, sym, lab));
  510. - else if (sibcall_p)
  511. + else if (sibcall_p && SYMBOL_REF_LOCAL_P (sym))
  512. emit_insn (gen_symPCREL_label2reg (reg, sym, lab));
  513. else
  514. emit_insn (gen_symPLT_label2reg (reg, sym, lab));
  515. @@ -12731,10 +12871,18 @@ sh_output_mi_thunk (FILE *file, tree thunk_fndecl ATTRIBUTE_UNUSED,
  516. sibcall = gen_sibcalli_thunk (funexp, const0_rtx);
  517. else
  518. #endif
  519. - if (TARGET_SH2 && flag_pic)
  520. + if (TARGET_SH2 && (flag_pic || TARGET_FDPIC))
  521. {
  522. - sibcall = gen_sibcall_pcrel (funexp, const0_rtx);
  523. - XEXP (XVECEXP (sibcall, 0, 2), 0) = scratch2;
  524. + if (TARGET_FDPIC)
  525. + {
  526. + sibcall = gen_sibcall_pcrel_fdpic (funexp, const0_rtx);
  527. + XEXP (XVECEXP (sibcall, 0, 3), 0) = scratch2;
  528. + }
  529. + else
  530. + {
  531. + sibcall = gen_sibcall_pcrel (funexp, const0_rtx);
  532. + XEXP (XVECEXP (sibcall, 0, 2), 0) = scratch2;
  533. + }
  534. }
  535. else
  536. {
  537. @@ -12775,11 +12923,24 @@ sh_output_mi_thunk (FILE *file, tree thunk_fndecl ATTRIBUTE_UNUSED,
  538. epilogue_completed = 0;
  539. }
  540. +/* Return an RTX for the address of a function NAME of kind KIND,
  541. + placing the result in TARGET if not NULL. LAB should be non-NULL
  542. + for SFUNC_STATIC, if FDPIC; it will be set to (const_int 0) if jsr
  543. + should be used, or a label_ref if bsrf should be used. For FDPIC,
  544. + both SFUNC_GOT and SFUNC_STATIC will return the address of the
  545. + function itself, not a function descriptor, so they can only be
  546. + used with functions not using the FDPIC register that are known to
  547. + be called directory without a PLT entry. */
  548. +
  549. rtx
  550. -function_symbol (rtx target, const char *name, enum sh_function_kind kind)
  551. +function_symbol (rtx target, const char *name, enum sh_function_kind kind,
  552. + rtx *lab)
  553. {
  554. rtx sym;
  555. + if (lab)
  556. + *lab = const0_rtx;
  557. +
  558. /* If this is not an ordinary function, the name usually comes from a
  559. string literal or an sprintf buffer. Make sure we use the same
  560. string consistently, so that cse will be able to unify address loads. */
  561. @@ -12787,7 +12948,7 @@ function_symbol (rtx target, const char *name, enum sh_function_kind kind)
  562. name = IDENTIFIER_POINTER (get_identifier (name));
  563. sym = gen_rtx_SYMBOL_REF (Pmode, name);
  564. SYMBOL_REF_FLAGS (sym) = SYMBOL_FLAG_FUNCTION;
  565. - if (flag_pic)
  566. + if (flag_pic || TARGET_FDPIC)
  567. switch (kind)
  568. {
  569. case FUNCTION_ORDINARY:
  570. @@ -12802,14 +12963,27 @@ function_symbol (rtx target, const char *name, enum sh_function_kind kind)
  571. }
  572. case SFUNC_STATIC:
  573. {
  574. - /* ??? To allow cse to work, we use GOTOFF relocations.
  575. - We could add combiner patterns to transform this into
  576. - straight pc-relative calls with sym2PIC / bsrf when
  577. - label load and function call are still 1:1 and in the
  578. - same basic block during combine. */
  579. rtx reg = target ? target : gen_reg_rtx (Pmode);
  580. - emit_insn (gen_symGOTOFF2reg (reg, sym));
  581. + if (TARGET_FDPIC)
  582. + {
  583. + /* We use PC-relative calls, since GOTOFF can only refer
  584. + to writable data. This works along with
  585. + sh_sfunc_call. */
  586. + gcc_assert (lab != NULL);
  587. + *lab = PATTERN (gen_call_site ());
  588. + emit_insn (gen_sym_label2reg (reg, sym, *lab));
  589. + }
  590. + else
  591. + {
  592. + /* ??? To allow cse to work, we use GOTOFF relocations.
  593. + we could add combiner patterns to transform this into
  594. + straight pc-relative calls with sym2PIC / bsrf when
  595. + label load and function call are still 1:1 and in the
  596. + same basic block during combine. */
  597. + emit_insn (gen_symGOTOFF2reg (reg, sym));
  598. + }
  599. +
  600. sym = reg;
  601. break;
  602. }
  603. @@ -13432,6 +13606,12 @@ sh_conditional_register_usage (void)
  604. fixed_regs[PIC_OFFSET_TABLE_REGNUM] = 1;
  605. call_used_regs[PIC_OFFSET_TABLE_REGNUM] = 1;
  606. }
  607. + if (TARGET_FDPIC)
  608. + {
  609. + fixed_regs[PIC_REG] = 1;
  610. + call_used_regs[PIC_REG] = 1;
  611. + call_really_used_regs[PIC_REG] = 1;
  612. + }
  613. /* Renesas saves and restores mac registers on call. */
  614. if (TARGET_HITACHI && ! TARGET_NOMACSAVE)
  615. {
  616. @@ -13460,14 +13640,32 @@ sh_conditional_register_usage (void)
  617. static bool
  618. sh_legitimate_constant_p (machine_mode mode, rtx x)
  619. {
  620. - return (TARGET_SHMEDIA
  621. - ? ((mode != DFmode && GET_MODE_CLASS (mode) != MODE_VECTOR_FLOAT)
  622. - || x == CONST0_RTX (mode)
  623. - || !TARGET_SHMEDIA_FPU
  624. - || TARGET_SHMEDIA64)
  625. - : (GET_CODE (x) != CONST_DOUBLE
  626. - || mode == DFmode || mode == SFmode
  627. - || mode == DImode || GET_MODE (x) == VOIDmode));
  628. + if (SH_OFFSETS_MUST_BE_WITHIN_SECTIONS_P)
  629. + {
  630. + rtx base, offset;
  631. +
  632. + split_const (x, &base, &offset);
  633. + if (GET_CODE (base) == SYMBOL_REF
  634. + && !offset_within_block_p (base, INTVAL (offset)))
  635. + return false;
  636. + }
  637. +
  638. + if (TARGET_FDPIC
  639. + && (SYMBOLIC_CONST_P (x)
  640. + || (GET_CODE (x) == CONST && GET_CODE (XEXP (x, 0)) == PLUS
  641. + && SYMBOLIC_CONST_P (XEXP (XEXP (x, 0), 0)))))
  642. + return false;
  643. +
  644. + if (TARGET_SHMEDIA
  645. + && ((mode != DFmode && GET_MODE_CLASS (mode) != MODE_VECTOR_FLOAT)
  646. + || x == CONST0_RTX (mode)
  647. + || !TARGET_SHMEDIA_FPU
  648. + || TARGET_SHMEDIA64))
  649. + return false;
  650. +
  651. + return (GET_CODE (x) != CONST_DOUBLE
  652. + || mode == DFmode || mode == SFmode
  653. + || mode == DImode || GET_MODE (x) == VOIDmode);
  654. }
  655. enum sh_divide_strategy_e sh_div_strategy = SH_DIV_STRATEGY_DEFAULT;
  656. @@ -14558,4 +14756,53 @@ sh_use_by_pieces_infrastructure_p (unsigned HOST_WIDE_INT size,
  657. }
  658. }
  659. +bool
  660. +sh_cannot_force_const_mem_p (machine_mode mode ATTRIBUTE_UNUSED,
  661. + rtx x ATTRIBUTE_UNUSED)
  662. +{
  663. + if (TARGET_FDPIC)
  664. + return true;
  665. +
  666. + return false;
  667. +}
  668. +
  669. +/* Emit insns to load the function address from FUNCDESC (an FDPIC
  670. + function descriptor) into r1 and the GOT address into r12,
  671. + returning an rtx for r1. */
  672. +
  673. +rtx
  674. +sh_load_function_descriptor (rtx funcdesc)
  675. +{
  676. + rtx r1 = gen_rtx_REG (Pmode, R1_REG);
  677. + rtx pic_reg = gen_rtx_REG (Pmode, PIC_REG);
  678. + rtx fnaddr = gen_rtx_MEM (Pmode, funcdesc);
  679. + rtx gotaddr = gen_rtx_MEM (Pmode, plus_constant (Pmode, funcdesc, 4));
  680. +
  681. + emit_move_insn (r1, fnaddr);
  682. + /* The ABI requires the entry point address to be loaded first, so
  683. + prevent the load from being moved after that of the GOT
  684. + address. */
  685. + emit_insn (gen_blockage ());
  686. + emit_move_insn (pic_reg, gotaddr);
  687. + return r1;
  688. +}
  689. +
  690. +/* Return an rtx holding the initial value of the FDPIC register (the
  691. + FDPIC pointer passed in from the caller). */
  692. +
  693. +rtx
  694. +sh_our_fdpic_reg (void)
  695. +{
  696. + return get_hard_reg_initial_val (Pmode, PIC_REG);
  697. +}
  698. +
  699. +/* Relocatable data for FDPIC binaries is not permitted in read-only
  700. + segments. */
  701. +
  702. +static int
  703. +sh_reloc_rw_mask (void)
  704. +{
  705. + return (flag_pic || TARGET_FDPIC) ? 3 : 0;
  706. +}
  707. +
  708. #include "gt-sh.h"
  709. diff --git a/gcc/config/sh/sh.h b/gcc/config/sh/sh.h
  710. index aafcf28..6abfb00 100644
  711. --- a/gcc/config/sh/sh.h
  712. +++ b/gcc/config/sh/sh.h
  713. @@ -321,7 +321,7 @@ extern int code_for_indirect_jump_scratch;
  714. #endif
  715. #ifndef SUBTARGET_ASM_SPEC
  716. -#define SUBTARGET_ASM_SPEC ""
  717. +#define SUBTARGET_ASM_SPEC "%{mfdpic:--fdpic}"
  718. #endif
  719. #if TARGET_ENDIAN_DEFAULT == MASK_LITTLE_ENDIAN
  720. @@ -349,7 +349,7 @@ extern int code_for_indirect_jump_scratch;
  721. #define ASM_ISA_DEFAULT_SPEC ""
  722. #endif /* MASK_SH5 */
  723. -#define SUBTARGET_LINK_EMUL_SUFFIX ""
  724. +#define SUBTARGET_LINK_EMUL_SUFFIX "%{mfdpic:_fd}"
  725. #define SUBTARGET_LINK_SPEC ""
  726. /* Go via SH_LINK_SPEC to avoid code replication. */
  727. @@ -383,8 +383,18 @@ extern int code_for_indirect_jump_scratch;
  728. "%{m2a*:%eSH2a does not support little-endian}}"
  729. #endif
  730. +#ifdef FDPIC_DEFAULT
  731. +#define FDPIC_SELF_SPECS "%{!mno-fdpic:-mfdpic}"
  732. +#else
  733. +#define FDPIC_SELF_SPECS
  734. +#endif
  735. +
  736. #undef DRIVER_SELF_SPECS
  737. -#define DRIVER_SELF_SPECS UNSUPPORTED_SH2A
  738. +#define DRIVER_SELF_SPECS UNSUPPORTED_SH2A SUBTARGET_DRIVER_SELF_SPECS \
  739. + FDPIC_SELF_SPECS
  740. +
  741. +#undef SUBTARGET_DRIVER_SELF_SPECS
  742. +#define SUBTARGET_DRIVER_SELF_SPECS
  743. #define ASSEMBLER_DIALECT assembler_dialect
  744. @@ -942,6 +952,14 @@ extern char sh_additional_register_names[ADDREGNAMES_SIZE] \
  745. code access to data items. */
  746. #define PIC_OFFSET_TABLE_REGNUM (flag_pic ? PIC_REG : INVALID_REGNUM)
  747. +/* For FDPIC, the FDPIC register is call-clobbered (otherwise PLT
  748. + entries would need to handle saving and restoring it). */
  749. +#define PIC_OFFSET_TABLE_REG_CALL_CLOBBERED TARGET_FDPIC
  750. +
  751. +/* An rtx holding the initial value of the FDPIC register (the FDPIC
  752. + pointer passed in from the caller). */
  753. +#define OUR_FDPIC_REG sh_our_fdpic_reg ()
  754. +
  755. #define GOT_SYMBOL_NAME "*_GLOBAL_OFFSET_TABLE_"
  756. /* Definitions for register eliminations.
  757. @@ -1566,7 +1584,9 @@ struct sh_args {
  758. 6 000c 00000000 l2: .long function */
  759. /* Length in units of the trampoline for entering a nested function. */
  760. -#define TRAMPOLINE_SIZE (TARGET_SHMEDIA64 ? 40 : TARGET_SH5 ? 24 : 16)
  761. +// FIXME: what happens if someone tries fdpic on SH5?
  762. +#define TRAMPOLINE_SIZE \
  763. + (TARGET_SHMEDIA64 ? 40 : TARGET_SH5 ? 24 : TARGET_FDPIC ? 32 : 16)
  764. /* Alignment required for a trampoline in bits. */
  765. #define TRAMPOLINE_ALIGNMENT \
  766. @@ -1622,6 +1642,11 @@ struct sh_args {
  767. || GENERAL_REGISTER_P ((unsigned) reg_renumber[(REGNO)])) \
  768. : (REGNO) == R0_REG || (unsigned) reg_renumber[(REGNO)] == R0_REG)
  769. +/* True if SYMBOL + OFFSET constants must refer to something within
  770. + SYMBOL's section. */
  771. +// FIXME: is this correct?
  772. +#define SH_OFFSETS_MUST_BE_WITHIN_SECTIONS_P TARGET_FDPIC
  773. +
  774. /* Maximum number of registers that can appear in a valid memory
  775. address. */
  776. #define MAX_REGS_PER_ADDRESS 2
  777. @@ -2262,9 +2287,12 @@ extern int current_function_interrupt;
  778. /* We have to distinguish between code and data, so that we apply
  779. datalabel where and only where appropriate. Use sdataN for data. */
  780. #define ASM_PREFERRED_EH_DATA_FORMAT(CODE, GLOBAL) \
  781. - ((flag_pic && (GLOBAL) ? DW_EH_PE_indirect : 0) \
  782. - | (flag_pic ? DW_EH_PE_pcrel : DW_EH_PE_absptr) \
  783. - | ((CODE) ? 0 : (TARGET_SHMEDIA64 ? DW_EH_PE_sdata8 : DW_EH_PE_sdata4)))
  784. + ((TARGET_FDPIC \
  785. + ? ((GLOBAL) ? DW_EH_PE_indirect | DW_EH_PE_datarel \
  786. + : DW_EH_PE_pcrel) \
  787. + : ((flag_pic && (GLOBAL) ? DW_EH_PE_indirect : 0) \
  788. + | (flag_pic ? DW_EH_PE_pcrel : DW_EH_PE_absptr))) \
  789. + | ((CODE) ? 0 : (TARGET_SHMEDIA64 ? DW_EH_PE_sdata8 : DW_EH_PE_sdata4)))
  790. /* Handle special EH pointer encodings. Absolute, pc-relative, and
  791. indirect are handled automatically. */
  792. @@ -2277,6 +2305,17 @@ extern int current_function_interrupt;
  793. SYMBOL_REF_FLAGS (ADDR) |= SYMBOL_FLAG_FUNCTION; \
  794. if (0) goto DONE; \
  795. } \
  796. + if (TARGET_FDPIC \
  797. + && ((ENCODING) & 0xf0) == (DW_EH_PE_indirect | DW_EH_PE_datarel)) \
  798. + { \
  799. + fputs ("\t.ualong ", FILE); \
  800. + output_addr_const (FILE, ADDR); \
  801. + if (GET_CODE (ADDR) == SYMBOL_REF && SYMBOL_REF_FUNCTION_P (ADDR)) \
  802. + fputs ("@GOTFUNCDESC", FILE); \
  803. + else \
  804. + fputs ("@GOT", FILE); \
  805. + goto DONE; \
  806. + } \
  807. } while (0)
  808. #if (defined CRT_BEGIN || defined CRT_END) && ! __SHMEDIA__
  809. diff --git a/gcc/config/sh/sh.md b/gcc/config/sh/sh.md
  810. index d758e3b..0b2acec 100644
  811. --- a/gcc/config/sh/sh.md
  812. +++ b/gcc/config/sh/sh.md
  813. @@ -100,6 +100,7 @@
  814. (R8_REG 8)
  815. (R9_REG 9)
  816. (R10_REG 10)
  817. + (R12_REG 12)
  818. (R20_REG 20)
  819. (R21_REG 21)
  820. (R22_REG 22)
  821. @@ -170,6 +171,9 @@
  822. UNSPEC_SYMOFF
  823. ;; (unspec [OFFSET ANCHOR] UNSPEC_PCREL_SYMOFF) == OFFSET - (ANCHOR - .).
  824. UNSPEC_PCREL_SYMOFF
  825. + ;; For FDPIC
  826. + UNSPEC_GOTFUNCDESC
  827. + UNSPEC_GOTOFFFUNCDESC
  828. ;; Misc builtins
  829. UNSPEC_BUILTIN_STRLEN
  830. ])
  831. @@ -2591,15 +2595,18 @@
  832. ;; This reload would clobber the value in r0 we are trying to store.
  833. ;; If we let reload allocate r0, then this problem can never happen.
  834. (define_insn "udivsi3_i1"
  835. - [(set (match_operand:SI 0 "register_operand" "=z")
  836. + [(set (match_operand:SI 0 "register_operand" "=z,z")
  837. (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
  838. (clobber (reg:SI T_REG))
  839. (clobber (reg:SI PR_REG))
  840. (clobber (reg:SI R1_REG))
  841. (clobber (reg:SI R4_REG))
  842. - (use (match_operand:SI 1 "arith_reg_operand" "r"))]
  843. + (use (match_operand:SI 1 "arith_reg_operand" "r,r"))
  844. + (use (match_operand 2 "" "Z,Ccl"))]
  845. "TARGET_SH1 && TARGET_DIVIDE_CALL_DIV1"
  846. - "jsr @%1%#"
  847. + "@
  848. + jsr @%1%#
  849. + bsrf %1\\n%O2:%#"
  850. [(set_attr "type" "sfunc")
  851. (set_attr "needs_delay_slot" "yes")])
  852. @@ -2648,7 +2655,7 @@
  853. })
  854. (define_insn "udivsi3_i4"
  855. - [(set (match_operand:SI 0 "register_operand" "=y")
  856. + [(set (match_operand:SI 0 "register_operand" "=y,y")
  857. (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
  858. (clobber (reg:SI T_REG))
  859. (clobber (reg:SI PR_REG))
  860. @@ -2660,16 +2667,19 @@
  861. (clobber (reg:SI R4_REG))
  862. (clobber (reg:SI R5_REG))
  863. (clobber (reg:SI FPSCR_STAT_REG))
  864. - (use (match_operand:SI 1 "arith_reg_operand" "r"))
  865. + (use (match_operand:SI 1 "arith_reg_operand" "r,r"))
  866. + (use (match_operand 2 "" "Z,Ccl"))
  867. (use (reg:SI FPSCR_MODES_REG))]
  868. "TARGET_FPU_DOUBLE && ! TARGET_FPU_SINGLE"
  869. - "jsr @%1%#"
  870. + "@
  871. + jsr @%1%#
  872. + bsrf %1\\n%O2:%#"
  873. [(set_attr "type" "sfunc")
  874. (set_attr "fp_mode" "double")
  875. (set_attr "needs_delay_slot" "yes")])
  876. (define_insn "udivsi3_i4_single"
  877. - [(set (match_operand:SI 0 "register_operand" "=y")
  878. + [(set (match_operand:SI 0 "register_operand" "=y,y")
  879. (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
  880. (clobber (reg:SI T_REG))
  881. (clobber (reg:SI PR_REG))
  882. @@ -2680,10 +2690,13 @@
  883. (clobber (reg:SI R1_REG))
  884. (clobber (reg:SI R4_REG))
  885. (clobber (reg:SI R5_REG))
  886. - (use (match_operand:SI 1 "arith_reg_operand" "r"))]
  887. + (use (match_operand:SI 1 "arith_reg_operand" "r,r"))
  888. + (use (match_operand 2 "" "Z,Ccl"))]
  889. "(TARGET_FPU_SINGLE_ONLY || TARGET_FPU_DOUBLE || TARGET_SHCOMPACT)
  890. && TARGET_FPU_SINGLE"
  891. - "jsr @%1%#"
  892. + "@
  893. + jsr @%1%#
  894. + bsrf %1\\n%O2:%#"
  895. [(set_attr "type" "sfunc")
  896. (set_attr "needs_delay_slot" "yes")])
  897. @@ -2737,16 +2750,17 @@
  898. emit_move_insn (operands[0], operands[2]);
  899. DONE;
  900. }
  901. - function_symbol (operands[3], "__udivsi3_i4i", SFUNC_GOT);
  902. + function_symbol (operands[3], "__udivsi3_i4i", SFUNC_GOT, NULL);
  903. last = gen_udivsi3_i4_int (operands[0], operands[3]);
  904. }
  905. else if (TARGET_DIVIDE_CALL_FP)
  906. {
  907. - function_symbol (operands[3], "__udivsi3_i4", SFUNC_STATIC);
  908. + rtx lab;
  909. + function_symbol (operands[3], "__udivsi3_i4", SFUNC_STATIC, &lab);
  910. if (TARGET_FPU_SINGLE)
  911. - last = gen_udivsi3_i4_single (operands[0], operands[3]);
  912. + last = gen_udivsi3_i4_single (operands[0], operands[3], lab);
  913. else
  914. - last = gen_udivsi3_i4 (operands[0], operands[3]);
  915. + last = gen_udivsi3_i4 (operands[0], operands[3], lab);
  916. }
  917. else if (TARGET_SHMEDIA_FPU)
  918. {
  919. @@ -2766,19 +2780,20 @@
  920. {
  921. function_symbol (operands[3],
  922. TARGET_FPU_ANY ? "__udivsi3_i4" : "__udivsi3",
  923. - SFUNC_STATIC);
  924. + SFUNC_STATIC, NULL);
  925. if (TARGET_SHMEDIA)
  926. last = gen_udivsi3_i1_media (operands[0], operands[3]);
  927. else if (TARGET_FPU_ANY)
  928. - last = gen_udivsi3_i4_single (operands[0], operands[3]);
  929. + last = gen_udivsi3_i4_single (operands[0], operands[3], const0_rtx);
  930. else
  931. - last = gen_udivsi3_i1 (operands[0], operands[3]);
  932. + last = gen_udivsi3_i1 (operands[0], operands[3], const0_rtx);
  933. }
  934. else
  935. {
  936. - function_symbol (operands[3], "__udivsi3", SFUNC_STATIC);
  937. - last = gen_udivsi3_i1 (operands[0], operands[3]);
  938. + rtx lab;
  939. + function_symbol (operands[3], "__udivsi3", SFUNC_STATIC, &lab);
  940. + last = gen_udivsi3_i1 (operands[0], operands[3], lab);
  941. }
  942. emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
  943. emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
  944. @@ -2906,7 +2921,7 @@
  945. emit_move_insn (gen_rtx_REG (DImode, R20_REG), x);
  946. break;
  947. }
  948. - sym = function_symbol (NULL, name, kind);
  949. + sym = function_symbol (NULL, name, kind, NULL);
  950. emit_insn (gen_divsi3_media_2 (operands[0], sym));
  951. DONE;
  952. }
  953. @@ -2926,31 +2941,37 @@
  954. })
  955. (define_insn "divsi3_i4"
  956. - [(set (match_operand:SI 0 "register_operand" "=y")
  957. + [(set (match_operand:SI 0 "register_operand" "=y,y")
  958. (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
  959. (clobber (reg:SI PR_REG))
  960. (clobber (reg:DF DR0_REG))
  961. (clobber (reg:DF DR2_REG))
  962. (clobber (reg:SI FPSCR_STAT_REG))
  963. - (use (match_operand:SI 1 "arith_reg_operand" "r"))
  964. + (use (match_operand:SI 1 "arith_reg_operand" "r,r"))
  965. + (use (match_operand 2 "" "Z,Ccl"))
  966. (use (reg:SI FPSCR_MODES_REG))]
  967. "TARGET_FPU_DOUBLE && ! TARGET_FPU_SINGLE"
  968. - "jsr @%1%#"
  969. + "@
  970. + jsr @%1%#
  971. + bsrf %1\\n%O2:%#"
  972. [(set_attr "type" "sfunc")
  973. (set_attr "fp_mode" "double")
  974. (set_attr "needs_delay_slot" "yes")])
  975. (define_insn "divsi3_i4_single"
  976. - [(set (match_operand:SI 0 "register_operand" "=y")
  977. + [(set (match_operand:SI 0 "register_operand" "=y,y")
  978. (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
  979. (clobber (reg:SI PR_REG))
  980. (clobber (reg:DF DR0_REG))
  981. (clobber (reg:DF DR2_REG))
  982. (clobber (reg:SI R2_REG))
  983. - (use (match_operand:SI 1 "arith_reg_operand" "r"))]
  984. + (use (match_operand:SI 1 "arith_reg_operand" "r,r"))
  985. + (use (match_operand 2 "" "Z,Ccl"))]
  986. "(TARGET_FPU_SINGLE_ONLY || TARGET_FPU_DOUBLE || TARGET_SHCOMPACT)
  987. && TARGET_FPU_SINGLE"
  988. - "jsr @%1%#"
  989. + "@
  990. + jsr @%1%#
  991. + bsrf %1\\n%O2:%#"
  992. [(set_attr "type" "sfunc")
  993. (set_attr "needs_delay_slot" "yes")])
  994. @@ -2989,16 +3010,17 @@
  995. /* Emit the move of the address to a pseudo outside of the libcall. */
  996. if (TARGET_DIVIDE_CALL_TABLE)
  997. {
  998. - function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_GOT);
  999. + function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_GOT, NULL);
  1000. last = gen_divsi3_i4_int (operands[0], operands[3]);
  1001. }
  1002. else if (TARGET_DIVIDE_CALL_FP)
  1003. {
  1004. - function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_STATIC);
  1005. + rtx lab;
  1006. + function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_STATIC, &lab);
  1007. if (TARGET_FPU_SINGLE)
  1008. - last = gen_divsi3_i4_single (operands[0], operands[3]);
  1009. + last = gen_divsi3_i4_single (operands[0], operands[3], lab);
  1010. else
  1011. - last = gen_divsi3_i4 (operands[0], operands[3]);
  1012. + last = gen_divsi3_i4 (operands[0], operands[3], lab);
  1013. }
  1014. else if (TARGET_SH2A)
  1015. {
  1016. @@ -3103,23 +3125,23 @@
  1017. emit_move_insn (gen_rtx_REG (Pmode, R20_REG), tab_base);
  1018. }
  1019. if (TARGET_FPU_ANY && TARGET_SH1)
  1020. - function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_STATIC);
  1021. + function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_STATIC, NULL);
  1022. else if (TARGET_DIVIDE_CALL2)
  1023. - function_symbol (operands[3], "__sdivsi3_2", SFUNC_STATIC);
  1024. + function_symbol (operands[3], "__sdivsi3_2", SFUNC_STATIC, NULL);
  1025. else
  1026. - function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_GOT);
  1027. + function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_GOT, NULL);
  1028. if (TARGET_SHMEDIA)
  1029. last = ((TARGET_DIVIDE_CALL2 ? gen_divsi3_media_2 : gen_divsi3_i1_media)
  1030. (operands[0], operands[3]));
  1031. else if (TARGET_FPU_ANY)
  1032. - last = gen_divsi3_i4_single (operands[0], operands[3]);
  1033. + last = gen_divsi3_i4_single (operands[0], operands[3], const0_rtx);
  1034. else
  1035. last = gen_divsi3_i1 (operands[0], operands[3]);
  1036. }
  1037. else
  1038. {
  1039. - function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_GOT);
  1040. + function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_GOT, NULL);
  1041. last = gen_divsi3_i1 (operands[0], operands[3]);
  1042. }
  1043. emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
  1044. @@ -3713,7 +3735,7 @@ label:
  1045. {
  1046. /* The address must be set outside the libcall,
  1047. since it goes into a pseudo. */
  1048. - rtx sym = function_symbol (NULL, "__mulsi3", SFUNC_STATIC);
  1049. + rtx sym = function_symbol (NULL, "__mulsi3", SFUNC_STATIC, NULL);
  1050. rtx addr = force_reg (SImode, sym);
  1051. rtx insns = gen_mulsi3_call (operands[0], operands[1],
  1052. operands[2], addr);
  1053. @@ -4970,8 +4992,9 @@ label:
  1054. {
  1055. emit_move_insn (gen_rtx_REG (SImode, R4_REG), operands[1]);
  1056. rtx funcaddr = gen_reg_rtx (Pmode);
  1057. - function_symbol (funcaddr, "__ashlsi3_r0", SFUNC_STATIC);
  1058. - emit_insn (gen_ashlsi3_d_call (operands[0], operands[2], funcaddr));
  1059. + rtx lab;
  1060. + function_symbol (funcaddr, "__ashlsi3_r0", SFUNC_STATIC, &lab);
  1061. + emit_insn (gen_ashlsi3_d_call (operands[0], operands[2], funcaddr, lab));
  1062. DONE;
  1063. }
  1064. @@ -5024,15 +5047,18 @@ label:
  1065. ;; In order to make combine understand the truncation of the shift amount
  1066. ;; operand we have to allow it to use pseudo regs for the shift operands.
  1067. (define_insn "ashlsi3_d_call"
  1068. - [(set (match_operand:SI 0 "arith_reg_dest" "=z")
  1069. + [(set (match_operand:SI 0 "arith_reg_dest" "=z,z")
  1070. (ashift:SI (reg:SI R4_REG)
  1071. - (and:SI (match_operand:SI 1 "arith_reg_operand" "z")
  1072. + (and:SI (match_operand:SI 1 "arith_reg_operand" "z,z")
  1073. (const_int 31))))
  1074. - (use (match_operand:SI 2 "arith_reg_operand" "r"))
  1075. + (use (match_operand:SI 2 "arith_reg_operand" "r,r"))
  1076. + (use (match_operand 3 "" "Z,Ccl"))
  1077. (clobber (reg:SI T_REG))
  1078. (clobber (reg:SI PR_REG))]
  1079. "TARGET_SH1 && !TARGET_DYNSHIFT"
  1080. - "jsr @%2%#"
  1081. + "@
  1082. + jsr @%2%#
  1083. + bsrf %2\\n%O3:%#"
  1084. [(set_attr "type" "sfunc")
  1085. (set_attr "needs_delay_slot" "yes")])
  1086. @@ -5374,12 +5400,15 @@ label:
  1087. (define_insn "ashrsi3_n"
  1088. [(set (reg:SI R4_REG)
  1089. (ashiftrt:SI (reg:SI R4_REG)
  1090. - (match_operand:SI 0 "const_int_operand" "i")))
  1091. + (match_operand:SI 0 "const_int_operand" "i,i")))
  1092. (clobber (reg:SI T_REG))
  1093. (clobber (reg:SI PR_REG))
  1094. - (use (match_operand:SI 1 "arith_reg_operand" "r"))]
  1095. + (use (match_operand:SI 1 "arith_reg_operand" "r,r"))
  1096. + (use (match_operand 2 "" "Z,Ccl"))]
  1097. "TARGET_SH1"
  1098. - "jsr @%1%#"
  1099. + "@
  1100. + jsr @%1%#
  1101. + bsrf %1\\n%O2:%#"
  1102. [(set_attr "type" "sfunc")
  1103. (set_attr "needs_delay_slot" "yes")])
  1104. @@ -5532,8 +5561,9 @@ label:
  1105. {
  1106. emit_move_insn (gen_rtx_REG (SImode, R4_REG), operands[1]);
  1107. rtx funcaddr = gen_reg_rtx (Pmode);
  1108. - function_symbol (funcaddr, "__lshrsi3_r0", SFUNC_STATIC);
  1109. - emit_insn (gen_lshrsi3_d_call (operands[0], operands[2], funcaddr));
  1110. + rtx lab;
  1111. + function_symbol (funcaddr, "__lshrsi3_r0", SFUNC_STATIC, &lab);
  1112. + emit_insn (gen_lshrsi3_d_call (operands[0], operands[2], funcaddr, lab));
  1113. DONE;
  1114. }
  1115. })
  1116. @@ -5585,15 +5615,18 @@ label:
  1117. ;; In order to make combine understand the truncation of the shift amount
  1118. ;; operand we have to allow it to use pseudo regs for the shift operands.
  1119. (define_insn "lshrsi3_d_call"
  1120. - [(set (match_operand:SI 0 "arith_reg_dest" "=z")
  1121. + [(set (match_operand:SI 0 "arith_reg_dest" "=z,z")
  1122. (lshiftrt:SI (reg:SI R4_REG)
  1123. - (and:SI (match_operand:SI 1 "arith_reg_operand" "z")
  1124. + (and:SI (match_operand:SI 1 "arith_reg_operand" "z,z")
  1125. (const_int 31))))
  1126. - (use (match_operand:SI 2 "arith_reg_operand" "r"))
  1127. + (use (match_operand:SI 2 "arith_reg_operand" "r,r"))
  1128. + (use (match_operand 3 "" "Z,Ccl"))
  1129. (clobber (reg:SI T_REG))
  1130. (clobber (reg:SI PR_REG))]
  1131. "TARGET_SH1 && !TARGET_DYNSHIFT"
  1132. - "jsr @%2%#"
  1133. + "@
  1134. + jsr @%2%#
  1135. + bsrf %2\\n%O3:%#"
  1136. [(set_attr "type" "sfunc")
  1137. (set_attr "needs_delay_slot" "yes")])
  1138. @@ -7315,7 +7348,8 @@ label:
  1139. }
  1140. else if (TARGET_SHCOMPACT)
  1141. {
  1142. - operands[1] = function_symbol (NULL, "__ic_invalidate", SFUNC_STATIC);
  1143. + operands[1] = function_symbol (NULL, "__ic_invalidate", SFUNC_STATIC,
  1144. + NULL);
  1145. operands[1] = force_reg (Pmode, operands[1]);
  1146. emit_insn (gen_ic_invalidate_line_compact (operands[0], operands[1]));
  1147. DONE;
  1148. @@ -7397,7 +7431,7 @@ label:
  1149. tramp = force_reg (Pmode, operands[0]);
  1150. sfun = force_reg (Pmode, function_symbol (NULL, "__init_trampoline",
  1151. - SFUNC_STATIC));
  1152. + SFUNC_STATIC, NULL));
  1153. emit_move_insn (gen_rtx_REG (SImode, R2_REG), operands[1]);
  1154. emit_move_insn (gen_rtx_REG (SImode, R3_REG), operands[2]);
  1155. @@ -9459,7 +9493,27 @@ label:
  1156. (match_operand 1 "" ""))
  1157. (use (reg:SI FPSCR_MODES_REG))
  1158. (clobber (reg:SI PR_REG))]
  1159. - "TARGET_SH1"
  1160. + "TARGET_SH1 && !TARGET_FDPIC"
  1161. +{
  1162. + if (TARGET_SH2A && (dbr_sequence_length () == 0))
  1163. + return "jsr/n @%0";
  1164. + else
  1165. + return "jsr @%0%#";
  1166. +}
  1167. + [(set_attr "type" "call")
  1168. + (set (attr "fp_mode")
  1169. + (if_then_else (eq_attr "fpu_single" "yes")
  1170. + (const_string "single") (const_string "double")))
  1171. + (set_attr "needs_delay_slot" "yes")
  1172. + (set_attr "fp_set" "unknown")])
  1173. +
  1174. +(define_insn "calli_fdpic"
  1175. + [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
  1176. + (match_operand 1 "" ""))
  1177. + (use (reg:SI FPSCR_MODES_REG))
  1178. + (use (reg:SI PIC_REG))
  1179. + (clobber (reg:SI PR_REG))]
  1180. + "TARGET_SH1 && TARGET_FDPIC"
  1181. {
  1182. if (TARGET_SH2A && (dbr_sequence_length () == 0))
  1183. return "jsr/n @%0";
  1184. @@ -9588,7 +9642,28 @@ label:
  1185. (match_operand 2 "" "")))
  1186. (use (reg:SI FPSCR_MODES_REG))
  1187. (clobber (reg:SI PR_REG))]
  1188. - "TARGET_SH1"
  1189. + "TARGET_SH1 && !TARGET_FDPIC"
  1190. +{
  1191. + if (TARGET_SH2A && (dbr_sequence_length () == 0))
  1192. + return "jsr/n @%1";
  1193. + else
  1194. + return "jsr @%1%#";
  1195. +}
  1196. + [(set_attr "type" "call")
  1197. + (set (attr "fp_mode")
  1198. + (if_then_else (eq_attr "fpu_single" "yes")
  1199. + (const_string "single") (const_string "double")))
  1200. + (set_attr "needs_delay_slot" "yes")
  1201. + (set_attr "fp_set" "unknown")])
  1202. +
  1203. +(define_insn "call_valuei_fdpic"
  1204. + [(set (match_operand 0 "" "=rf")
  1205. + (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
  1206. + (match_operand 2 "" "")))
  1207. + (use (reg:SI FPSCR_REG))
  1208. + (use (reg:SI PIC_REG))
  1209. + (clobber (reg:SI PR_REG))]
  1210. + "TARGET_SH1 && TARGET_FDPIC"
  1211. {
  1212. if (TARGET_SH2A && (dbr_sequence_length () == 0))
  1213. return "jsr/n @%1";
  1214. @@ -9725,6 +9800,12 @@ label:
  1215. (clobber (reg:SI PR_REG))])]
  1216. ""
  1217. {
  1218. + if (TARGET_FDPIC)
  1219. + {
  1220. + rtx pic_reg = gen_rtx_REG (Pmode, PIC_REG);
  1221. + emit_move_insn (pic_reg, OUR_FDPIC_REG);
  1222. + }
  1223. +
  1224. if (TARGET_SHMEDIA)
  1225. {
  1226. operands[0] = shmedia_prepare_call_address (operands[0], 0);
  1227. @@ -9760,7 +9841,8 @@ label:
  1228. emit_insn (gen_force_mode_for_call ());
  1229. operands[0]
  1230. - = function_symbol (NULL, "__GCC_shcompact_call_trampoline", SFUNC_GOT);
  1231. + = function_symbol (NULL, "__GCC_shcompact_call_trampoline",
  1232. + SFUNC_GOT, NULL);
  1233. operands[0] = force_reg (SImode, operands[0]);
  1234. emit_move_insn (r0, func);
  1235. @@ -9784,7 +9866,7 @@ label:
  1236. emit_insn (gen_symGOTPLT2reg (reg, XEXP (operands[0], 0)));
  1237. XEXP (operands[0], 0) = reg;
  1238. }
  1239. - if (!flag_pic && TARGET_SH2A
  1240. + if (!flag_pic && !TARGET_FDPIC && TARGET_SH2A
  1241. && MEM_P (operands[0])
  1242. && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF)
  1243. {
  1244. @@ -9795,7 +9877,7 @@ label:
  1245. DONE;
  1246. }
  1247. }
  1248. - if (flag_pic && TARGET_SH2
  1249. + if ((flag_pic || TARGET_FDPIC) && TARGET_SH2
  1250. && MEM_P (operands[0])
  1251. && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF)
  1252. {
  1253. @@ -9808,7 +9890,13 @@ label:
  1254. operands[1] = operands[2];
  1255. }
  1256. - emit_call_insn (gen_calli (operands[0], operands[1]));
  1257. + if (TARGET_FDPIC)
  1258. + {
  1259. + operands[0] = sh_load_function_descriptor (operands[0]);
  1260. + emit_call_insn (gen_calli_fdpic (operands[0], operands[1]));
  1261. + }
  1262. + else
  1263. + emit_call_insn (gen_calli (operands[0], operands[1]));
  1264. DONE;
  1265. })
  1266. @@ -9888,7 +9976,7 @@ label:
  1267. emit_insn (gen_force_mode_for_call ());
  1268. operands[0] = function_symbol (NULL, "__GCC_shcompact_call_trampoline",
  1269. - SFUNC_GOT);
  1270. + SFUNC_GOT, NULL);
  1271. operands[0] = force_reg (SImode, operands[0]);
  1272. emit_move_insn (r0, func);
  1273. @@ -9913,6 +10001,12 @@ label:
  1274. (clobber (reg:SI PR_REG))])]
  1275. ""
  1276. {
  1277. + if (TARGET_FDPIC)
  1278. + {
  1279. + rtx pic_reg = gen_rtx_REG (Pmode, PIC_REG);
  1280. + emit_move_insn (pic_reg, OUR_FDPIC_REG);
  1281. + }
  1282. +
  1283. if (TARGET_SHMEDIA)
  1284. {
  1285. operands[1] = shmedia_prepare_call_address (operands[1], 0);
  1286. @@ -9949,7 +10043,8 @@ label:
  1287. emit_insn (gen_force_mode_for_call ());
  1288. operands[1]
  1289. - = function_symbol (NULL, "__GCC_shcompact_call_trampoline", SFUNC_GOT);
  1290. + = function_symbol (NULL, "__GCC_shcompact_call_trampoline",
  1291. + SFUNC_GOT, NULL);
  1292. operands[1] = force_reg (SImode, operands[1]);
  1293. emit_move_insn (r0, func);
  1294. @@ -9975,7 +10070,7 @@ label:
  1295. emit_insn (gen_symGOTPLT2reg (reg, XEXP (operands[1], 0)));
  1296. XEXP (operands[1], 0) = reg;
  1297. }
  1298. - if (!flag_pic && TARGET_SH2A
  1299. + if (!flag_pic && !TARGET_FDPIC && TARGET_SH2A
  1300. && MEM_P (operands[1])
  1301. && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF)
  1302. {
  1303. @@ -9986,7 +10081,7 @@ label:
  1304. DONE;
  1305. }
  1306. }
  1307. - if (flag_pic && TARGET_SH2
  1308. + if ((flag_pic || TARGET_FDPIC) && TARGET_SH2
  1309. && MEM_P (operands[1])
  1310. && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF)
  1311. {
  1312. @@ -9997,7 +10092,14 @@ label:
  1313. else
  1314. operands[1] = force_reg (SImode, XEXP (operands[1], 0));
  1315. - emit_call_insn (gen_call_valuei (operands[0], operands[1], operands[2]));
  1316. + if (TARGET_FDPIC)
  1317. + {
  1318. + operands[1] = sh_load_function_descriptor (operands[1]);
  1319. + emit_call_insn (gen_call_valuei_fdpic (operands[0], operands[1],
  1320. + operands[2]));
  1321. + }
  1322. + else
  1323. + emit_call_insn (gen_call_valuei (operands[0], operands[1], operands[2]));
  1324. DONE;
  1325. })
  1326. @@ -10006,7 +10108,21 @@ label:
  1327. (match_operand 1 "" ""))
  1328. (use (reg:SI FPSCR_MODES_REG))
  1329. (return)]
  1330. - "TARGET_SH1"
  1331. + "TARGET_SH1 && !TARGET_FDPIC"
  1332. + "jmp @%0%#"
  1333. + [(set_attr "needs_delay_slot" "yes")
  1334. + (set (attr "fp_mode")
  1335. + (if_then_else (eq_attr "fpu_single" "yes")
  1336. + (const_string "single") (const_string "double")))
  1337. + (set_attr "type" "jump_ind")])
  1338. +
  1339. +(define_insn "sibcalli_fdpic"
  1340. + [(call (mem:SI (match_operand:SI 0 "register_operand" "k"))
  1341. + (match_operand 1 "" ""))
  1342. + (use (reg:SI FPSCR_MODES_REG))
  1343. + (use (reg:SI PIC_REG))
  1344. + (return)]
  1345. + "TARGET_SH1 && TARGET_FDPIC"
  1346. "jmp @%0%#"
  1347. [(set_attr "needs_delay_slot" "yes")
  1348. (set (attr "fp_mode")
  1349. @@ -10020,7 +10136,25 @@ label:
  1350. (use (match_operand 2 "" ""))
  1351. (use (reg:SI FPSCR_MODES_REG))
  1352. (return)]
  1353. - "TARGET_SH2"
  1354. + "TARGET_SH2 && !TARGET_FDPIC"
  1355. +{
  1356. + return "braf %0" "\n"
  1357. + "%O2:%#";
  1358. +}
  1359. + [(set_attr "needs_delay_slot" "yes")
  1360. + (set (attr "fp_mode")
  1361. + (if_then_else (eq_attr "fpu_single" "yes")
  1362. + (const_string "single") (const_string "double")))
  1363. + (set_attr "type" "jump_ind")])
  1364. +
  1365. +(define_insn "sibcalli_pcrel_fdpic"
  1366. + [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "k"))
  1367. + (match_operand 1 "" ""))
  1368. + (use (match_operand 2 "" ""))
  1369. + (use (reg:SI FPSCR_MODES_REG))
  1370. + (use (reg:SI PIC_REG))
  1371. + (return)]
  1372. + "TARGET_SH2 && TARGET_FDPIC"
  1373. {
  1374. return "braf %0" "\n"
  1375. "%O2:%#";
  1376. @@ -10053,7 +10187,7 @@ label:
  1377. (use (reg:SI FPSCR_MODES_REG))
  1378. (clobber (match_scratch:SI 2 "=k"))
  1379. (return)]
  1380. - "TARGET_SH2"
  1381. + "TARGET_SH2 && !TARGET_FDPIC"
  1382. "#"
  1383. "reload_completed"
  1384. [(const_int 0)]
  1385. @@ -10073,6 +10207,33 @@ label:
  1386. (const_string "single") (const_string "double")))
  1387. (set_attr "type" "jump_ind")])
  1388. +(define_insn_and_split "sibcall_pcrel_fdpic"
  1389. + [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" ""))
  1390. + (match_operand 1 "" ""))
  1391. + (use (reg:SI FPSCR_MODES_REG))
  1392. + (use (reg:SI PIC_REG))
  1393. + (clobber (match_scratch:SI 2 "=k"))
  1394. + (return)]
  1395. + "TARGET_SH2 && TARGET_FDPIC"
  1396. + "#"
  1397. + "reload_completed"
  1398. + [(const_int 0)]
  1399. +{
  1400. + rtx lab = PATTERN (gen_call_site ());
  1401. + rtx call_insn;
  1402. +
  1403. + sh_expand_sym_label2reg (operands[2], operands[0], lab, true);
  1404. + call_insn = emit_call_insn (gen_sibcalli_pcrel_fdpic (operands[2], operands[1],
  1405. + copy_rtx (lab)));
  1406. + SIBLING_CALL_P (call_insn) = 1;
  1407. + DONE;
  1408. +}
  1409. + [(set_attr "needs_delay_slot" "yes")
  1410. + (set (attr "fp_mode")
  1411. + (if_then_else (eq_attr "fpu_single" "yes")
  1412. + (const_string "single") (const_string "double")))
  1413. + (set_attr "type" "jump_ind")])
  1414. +
  1415. (define_insn "sibcall_compact"
  1416. [(call (mem:SI (match_operand:SI 0 "register_operand" "k,k"))
  1417. (match_operand 1 "" ""))
  1418. @@ -10117,6 +10278,12 @@ label:
  1419. (return)])]
  1420. ""
  1421. {
  1422. + if (TARGET_FDPIC)
  1423. + {
  1424. + rtx pic_reg = gen_rtx_REG (Pmode, PIC_REG);
  1425. + emit_move_insn (pic_reg, OUR_FDPIC_REG);
  1426. + }
  1427. +
  1428. if (TARGET_SHMEDIA)
  1429. {
  1430. operands[0] = shmedia_prepare_call_address (operands[0], 1);
  1431. @@ -10162,7 +10329,8 @@ label:
  1432. emit_insn (gen_force_mode_for_call ());
  1433. operands[0]
  1434. - = function_symbol (NULL, "__GCC_shcompact_call_trampoline", SFUNC_GOT);
  1435. + = function_symbol (NULL, "__GCC_shcompact_call_trampoline",
  1436. + SFUNC_GOT, NULL);
  1437. operands[0] = force_reg (SImode, operands[0]);
  1438. /* We don't need a return trampoline, since the callee will
  1439. @@ -10188,7 +10356,7 @@ label:
  1440. emit_insn (gen_symGOT2reg (reg, XEXP (operands[0], 0)));
  1441. XEXP (operands[0], 0) = reg;
  1442. }
  1443. - if (flag_pic && TARGET_SH2
  1444. + if ((flag_pic || TARGET_FDPIC) && TARGET_SH2
  1445. && MEM_P (operands[0])
  1446. && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
  1447. /* The PLT needs the PIC register, but the epilogue would have
  1448. @@ -10196,13 +10364,24 @@ label:
  1449. static functions. */
  1450. && SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
  1451. {
  1452. - emit_call_insn (gen_sibcall_pcrel (XEXP (operands[0], 0), operands[1]));
  1453. + if (TARGET_FDPIC)
  1454. + emit_call_insn (gen_sibcall_pcrel_fdpic (XEXP (operands[0], 0),
  1455. + operands[1]));
  1456. + else
  1457. + emit_call_insn (gen_sibcall_pcrel (XEXP (operands[0], 0),
  1458. + operands[1]));
  1459. DONE;
  1460. }
  1461. else
  1462. operands[0] = force_reg (SImode, XEXP (operands[0], 0));
  1463. - emit_call_insn (gen_sibcalli (operands[0], operands[1]));
  1464. + if (TARGET_FDPIC)
  1465. + {
  1466. + operands[0] = sh_load_function_descriptor (operands[0]);
  1467. + emit_call_insn (gen_sibcalli_fdpic (operands[0], operands[1]));
  1468. + }
  1469. + else
  1470. + emit_call_insn (gen_sibcalli (operands[0], operands[1]));
  1471. DONE;
  1472. })
  1473. @@ -10212,7 +10391,22 @@ label:
  1474. (match_operand 2 "" "")))
  1475. (use (reg:SI FPSCR_MODES_REG))
  1476. (return)]
  1477. - "TARGET_SH1"
  1478. + "TARGET_SH1 && !TARGET_FDPIC"
  1479. + "jmp @%1%#"
  1480. + [(set_attr "needs_delay_slot" "yes")
  1481. + (set (attr "fp_mode")
  1482. + (if_then_else (eq_attr "fpu_single" "yes")
  1483. + (const_string "single") (const_string "double")))
  1484. + (set_attr "type" "jump_ind")])
  1485. +
  1486. +(define_insn "sibcall_valuei_fdpic"
  1487. + [(set (match_operand 0 "" "=rf")
  1488. + (call (mem:SI (match_operand:SI 1 "register_operand" "k"))
  1489. + (match_operand 2 "" "")))
  1490. + (use (reg:SI FPSCR_MODES_REG))
  1491. + (use (reg:SI PIC_REG))
  1492. + (return)]
  1493. + "TARGET_SH1 && TARGET_FDPIC"
  1494. "jmp @%1%#"
  1495. [(set_attr "needs_delay_slot" "yes")
  1496. (set (attr "fp_mode")
  1497. @@ -10227,7 +10421,26 @@ label:
  1498. (use (match_operand 3 "" ""))
  1499. (use (reg:SI FPSCR_MODES_REG))
  1500. (return)]
  1501. - "TARGET_SH2"
  1502. + "TARGET_SH2 && !TARGET_FDPIC"
  1503. +{
  1504. + return "braf %1" "\n"
  1505. + "%O3:%#";
  1506. +}
  1507. + [(set_attr "needs_delay_slot" "yes")
  1508. + (set (attr "fp_mode")
  1509. + (if_then_else (eq_attr "fpu_single" "yes")
  1510. + (const_string "single") (const_string "double")))
  1511. + (set_attr "type" "jump_ind")])
  1512. +
  1513. +(define_insn "sibcall_valuei_pcrel_fdpic"
  1514. + [(set (match_operand 0 "" "=rf")
  1515. + (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "k"))
  1516. + (match_operand 2 "" "")))
  1517. + (use (match_operand 3 "" ""))
  1518. + (use (reg:SI FPSCR_MODES_REG))
  1519. + (use (reg:SI PIC_REG))
  1520. + (return)]
  1521. + "TARGET_SH2 && TARGET_FDPIC"
  1522. {
  1523. return "braf %1" "\n"
  1524. "%O3:%#";
  1525. @@ -10245,7 +10458,7 @@ label:
  1526. (use (reg:SI FPSCR_MODES_REG))
  1527. (clobber (match_scratch:SI 3 "=k"))
  1528. (return)]
  1529. - "TARGET_SH2"
  1530. + "TARGET_SH2 && !TARGET_FDPIC"
  1531. "#"
  1532. "reload_completed"
  1533. [(const_int 0)]
  1534. @@ -10258,6 +10471,38 @@ label:
  1535. operands[3],
  1536. operands[2],
  1537. copy_rtx (lab)));
  1538. +
  1539. + SIBLING_CALL_P (call_insn) = 1;
  1540. + DONE;
  1541. +}
  1542. + [(set_attr "needs_delay_slot" "yes")
  1543. + (set (attr "fp_mode")
  1544. + (if_then_else (eq_attr "fpu_single" "yes")
  1545. + (const_string "single") (const_string "double")))
  1546. + (set_attr "type" "jump_ind")])
  1547. +
  1548. +(define_insn_and_split "sibcall_value_pcrel_fdpic"
  1549. + [(set (match_operand 0 "" "=rf")
  1550. + (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" ""))
  1551. + (match_operand 2 "" "")))
  1552. + (use (reg:SI FPSCR_MODES_REG))
  1553. + (use (reg:SI PIC_REG))
  1554. + (clobber (match_scratch:SI 3 "=k"))
  1555. + (return)]
  1556. + "TARGET_SH2 && TARGET_FDPIC"
  1557. + "#"
  1558. + "reload_completed"
  1559. + [(const_int 0)]
  1560. +{
  1561. + rtx lab = PATTERN (gen_call_site ());
  1562. + rtx call_insn;
  1563. +
  1564. + sh_expand_sym_label2reg (operands[3], operands[1], lab, true);
  1565. + call_insn = emit_call_insn (gen_sibcall_valuei_pcrel_fdpic (operands[0],
  1566. + operands[3],
  1567. + operands[2],
  1568. + copy_rtx (lab)));
  1569. +
  1570. SIBLING_CALL_P (call_insn) = 1;
  1571. DONE;
  1572. }
  1573. @@ -10314,6 +10559,12 @@ label:
  1574. (return)])]
  1575. ""
  1576. {
  1577. + if (TARGET_FDPIC)
  1578. + {
  1579. + rtx pic_reg = gen_rtx_REG (Pmode, PIC_REG);
  1580. + emit_move_insn (pic_reg, OUR_FDPIC_REG);
  1581. + }
  1582. +
  1583. if (TARGET_SHMEDIA)
  1584. {
  1585. operands[1] = shmedia_prepare_call_address (operands[1], 1);
  1586. @@ -10360,7 +10611,8 @@ label:
  1587. emit_insn (gen_force_mode_for_call ());
  1588. operands[1]
  1589. - = function_symbol (NULL, "__GCC_shcompact_call_trampoline", SFUNC_GOT);
  1590. + = function_symbol (NULL, "__GCC_shcompact_call_trampoline",
  1591. + SFUNC_GOT, NULL);
  1592. operands[1] = force_reg (SImode, operands[1]);
  1593. /* We don't need a return trampoline, since the callee will
  1594. @@ -10387,7 +10639,7 @@ label:
  1595. emit_insn (gen_symGOT2reg (reg, XEXP (operands[1], 0)));
  1596. XEXP (operands[1], 0) = reg;
  1597. }
  1598. - if (flag_pic && TARGET_SH2
  1599. + if ((flag_pic || TARGET_FDPIC) && TARGET_SH2
  1600. && MEM_P (operands[1])
  1601. && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
  1602. /* The PLT needs the PIC register, but the epilogue would have
  1603. @@ -10395,15 +10647,28 @@ label:
  1604. static functions. */
  1605. && SYMBOL_REF_LOCAL_P (XEXP (operands[1], 0)))
  1606. {
  1607. - emit_call_insn (gen_sibcall_value_pcrel (operands[0],
  1608. - XEXP (operands[1], 0),
  1609. - operands[2]));
  1610. + if (TARGET_FDPIC)
  1611. + emit_call_insn (gen_sibcall_value_pcrel_fdpic (operands[0],
  1612. + XEXP (operands[1], 0),
  1613. + operands[2]));
  1614. + else
  1615. + emit_call_insn (gen_sibcall_value_pcrel (operands[0],
  1616. + XEXP (operands[1], 0),
  1617. + operands[2]));
  1618. DONE;
  1619. }
  1620. else
  1621. operands[1] = force_reg (SImode, XEXP (operands[1], 0));
  1622. - emit_call_insn (gen_sibcall_valuei (operands[0], operands[1], operands[2]));
  1623. + if (TARGET_FDPIC)
  1624. + {
  1625. + operands[1] = sh_load_function_descriptor (operands[1]);
  1626. + emit_call_insn (gen_sibcall_valuei_fdpic (operands[0], operands[1],
  1627. + operands[2]));
  1628. + }
  1629. + else
  1630. + emit_call_insn (gen_sibcall_valuei (operands[0], operands[1],
  1631. + operands[2]));
  1632. DONE;
  1633. })
  1634. @@ -10487,7 +10752,7 @@ label:
  1635. emit_insn (gen_force_mode_for_call ());
  1636. operands[1] = function_symbol (NULL, "__GCC_shcompact_call_trampoline",
  1637. - SFUNC_GOT);
  1638. + SFUNC_GOT, NULL);
  1639. operands[1] = force_reg (SImode, operands[1]);
  1640. emit_move_insn (r0, func);
  1641. @@ -10685,6 +10950,13 @@ label:
  1642. DONE;
  1643. }
  1644. + if (TARGET_FDPIC)
  1645. + {
  1646. + rtx pic_reg = gen_rtx_REG (Pmode, PIC_REG);
  1647. + emit_move_insn (pic_reg, OUR_FDPIC_REG);
  1648. + DONE;
  1649. + }
  1650. +
  1651. operands[1] = gen_rtx_REG (Pmode, PIC_REG);
  1652. operands[2] = gen_rtx_SYMBOL_REF (VOIDmode, GOT_SYMBOL_NAME);
  1653. @@ -10817,9 +11089,15 @@ label:
  1654. (set (match_operand 0 "" "") (mem (match_dup 3)))]
  1655. ""
  1656. {
  1657. + rtx picreg;
  1658. rtx mem;
  1659. bool stack_chk_guard_p = false;
  1660. + if (TARGET_FDPIC)
  1661. + picreg = OUR_FDPIC_REG;
  1662. + else
  1663. + picreg = gen_rtx_REG (Pmode, PIC_REG);
  1664. +
  1665. operands[2] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
  1666. operands[3] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
  1667. @@ -10859,11 +11137,11 @@ label:
  1668. insn to avoid combining (set A (plus rX r12)) and (set op0 (mem A))
  1669. when rX is a GOT address for the guard symbol. Ugly but doesn't
  1670. matter because this is a rare situation. */
  1671. +// FIXME: original fdpic patch did not have ssp case here ??
  1672. if (stack_chk_guard_p)
  1673. emit_insn (gen_chk_guard_add (operands[3], operands[2]));
  1674. else
  1675. - emit_move_insn (operands[3], gen_rtx_PLUS (Pmode, operands[2],
  1676. - gen_rtx_REG (Pmode, PIC_REG)));
  1677. + emit_move_insn (operands[3], gen_rtx_PLUS (Pmode, operands[2], picreg));
  1678. /* N.B. This is not constant for a GOTPLT relocation. */
  1679. mem = gen_rtx_MEM (Pmode, operands[3]);
  1680. @@ -10894,6 +11172,26 @@ label:
  1681. DONE;
  1682. })
  1683. +(define_expand "sym2GOTFUNCDESC"
  1684. + [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTFUNCDESC))]
  1685. + "TARGET_FDPIC"
  1686. + "")
  1687. +
  1688. +(define_expand "symGOTFUNCDESC2reg"
  1689. + [(match_operand 0 "" "") (match_operand 1 "" "")]
  1690. + "TARGET_FDPIC"
  1691. +{
  1692. + rtx gotsym, insn;
  1693. +
  1694. + gotsym = gen_sym2GOTFUNCDESC (operands[1]);
  1695. + PUT_MODE (gotsym, Pmode);
  1696. + insn = emit_insn (gen_symGOT_load (operands[0], gotsym));
  1697. +
  1698. + MEM_READONLY_P (SET_SRC (PATTERN (insn))) = 1;
  1699. +
  1700. + DONE;
  1701. +})
  1702. +
  1703. (define_expand "symGOTPLT2reg"
  1704. [(match_operand 0 "" "") (match_operand 1 "" "")]
  1705. ""
  1706. @@ -10915,23 +11213,49 @@ label:
  1707. [(match_operand 0 "" "") (match_operand 1 "" "")]
  1708. ""
  1709. {
  1710. + rtx picreg;
  1711. rtx gotoffsym, insn;
  1712. rtx t = (!can_create_pseudo_p ()
  1713. ? operands[0]
  1714. : gen_reg_rtx (GET_MODE (operands[0])));
  1715. + if (TARGET_FDPIC)
  1716. + picreg = OUR_FDPIC_REG;
  1717. + else
  1718. + picreg = gen_rtx_REG (Pmode, PIC_REG);
  1719. +
  1720. gotoffsym = gen_sym2GOTOFF (operands[1]);
  1721. PUT_MODE (gotoffsym, Pmode);
  1722. emit_move_insn (t, gotoffsym);
  1723. - insn = emit_move_insn (operands[0],
  1724. - gen_rtx_PLUS (Pmode, t,
  1725. - gen_rtx_REG (Pmode, PIC_REG)));
  1726. + insn = emit_move_insn (operands[0], gen_rtx_PLUS (Pmode, t, picreg));
  1727. set_unique_reg_note (insn, REG_EQUAL, operands[1]);
  1728. DONE;
  1729. })
  1730. +(define_expand "sym2GOTOFFFUNCDESC"
  1731. + [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTOFFFUNCDESC))]
  1732. + "TARGET_FDPIC"
  1733. + "")
  1734. +
  1735. +(define_expand "symGOTOFFFUNCDESC2reg"
  1736. + [(match_operand 0 "" "") (match_operand 1 "" "")]
  1737. + "TARGET_FDPIC"
  1738. +{
  1739. + rtx picreg = OUR_FDPIC_REG;
  1740. + rtx gotoffsym;
  1741. + rtx t = (!can_create_pseudo_p ()
  1742. + ? operands[0]
  1743. + : gen_reg_rtx (GET_MODE (operands[0])));
  1744. +
  1745. + gotoffsym = gen_sym2GOTOFFFUNCDESC (operands[1]);
  1746. + PUT_MODE (gotoffsym, Pmode);
  1747. + emit_move_insn (t, gotoffsym);
  1748. + emit_move_insn (operands[0], gen_rtx_PLUS (Pmode, t, picreg));
  1749. + DONE;
  1750. +})
  1751. +
  1752. (define_expand "symPLT_label2reg"
  1753. [(set (match_operand:SI 0 "" "")
  1754. (const:SI
  1755. @@ -11608,7 +11932,8 @@ label:
  1756. {
  1757. rtx reg = gen_rtx_REG (Pmode, R0_REG);
  1758. - function_symbol (reg, "__GCC_shcompact_return_trampoline", SFUNC_STATIC);
  1759. + function_symbol (reg, "__GCC_shcompact_return_trampoline", SFUNC_STATIC,
  1760. + NULL);
  1761. emit_jump_insn (gen_shcompact_return_tramp_i ());
  1762. DONE;
  1763. })
  1764. @@ -12688,18 +13013,22 @@ label:
  1765. (define_insn "block_move_real"
  1766. [(parallel [(set (mem:BLK (reg:SI R4_REG))
  1767. (mem:BLK (reg:SI R5_REG)))
  1768. - (use (match_operand:SI 0 "arith_reg_operand" "r"))
  1769. + (use (match_operand:SI 0 "arith_reg_operand" "r,r"))
  1770. + (use (match_operand 1 "" "Z,Ccl"))
  1771. (clobber (reg:SI PR_REG))
  1772. (clobber (reg:SI R0_REG))])]
  1773. "TARGET_SH1 && ! TARGET_HARD_SH4"
  1774. - "jsr @%0%#"
  1775. + "@
  1776. + jsr @%0%#
  1777. + bsrf %0\\n%O1:%#"
  1778. [(set_attr "type" "sfunc")
  1779. (set_attr "needs_delay_slot" "yes")])
  1780. (define_insn "block_lump_real"
  1781. [(parallel [(set (mem:BLK (reg:SI R4_REG))
  1782. (mem:BLK (reg:SI R5_REG)))
  1783. - (use (match_operand:SI 0 "arith_reg_operand" "r"))
  1784. + (use (match_operand:SI 0 "arith_reg_operand" "r,r"))
  1785. + (use (match_operand 1 "" "Z,Ccl"))
  1786. (use (reg:SI R6_REG))
  1787. (clobber (reg:SI PR_REG))
  1788. (clobber (reg:SI T_REG))
  1789. @@ -12708,27 +13037,33 @@ label:
  1790. (clobber (reg:SI R6_REG))
  1791. (clobber (reg:SI R0_REG))])]
  1792. "TARGET_SH1 && ! TARGET_HARD_SH4"
  1793. - "jsr @%0%#"
  1794. + "@
  1795. + jsr @%0%#
  1796. + bsrf %0\\n%O1:%#"
  1797. [(set_attr "type" "sfunc")
  1798. (set_attr "needs_delay_slot" "yes")])
  1799. (define_insn "block_move_real_i4"
  1800. [(parallel [(set (mem:BLK (reg:SI R4_REG))
  1801. (mem:BLK (reg:SI R5_REG)))
  1802. - (use (match_operand:SI 0 "arith_reg_operand" "r"))
  1803. + (use (match_operand:SI 0 "arith_reg_operand" "r,r"))
  1804. + (use (match_operand 1 "" "Z,Ccl"))
  1805. (clobber (reg:SI PR_REG))
  1806. (clobber (reg:SI R0_REG))
  1807. (clobber (reg:SI R1_REG))
  1808. (clobber (reg:SI R2_REG))])]
  1809. "TARGET_HARD_SH4"
  1810. - "jsr @%0%#"
  1811. + "@
  1812. + jsr @%0%#
  1813. + bsrf %0\\n%O1:%#"
  1814. [(set_attr "type" "sfunc")
  1815. (set_attr "needs_delay_slot" "yes")])
  1816. (define_insn "block_lump_real_i4"
  1817. [(parallel [(set (mem:BLK (reg:SI R4_REG))
  1818. (mem:BLK (reg:SI R5_REG)))
  1819. - (use (match_operand:SI 0 "arith_reg_operand" "r"))
  1820. + (use (match_operand:SI 0 "arith_reg_operand" "r,r"))
  1821. + (use (match_operand 1 "" "Z,Ccl"))
  1822. (use (reg:SI R6_REG))
  1823. (clobber (reg:SI PR_REG))
  1824. (clobber (reg:SI T_REG))
  1825. @@ -12740,7 +13075,9 @@ label:
  1826. (clobber (reg:SI R2_REG))
  1827. (clobber (reg:SI R3_REG))])]
  1828. "TARGET_HARD_SH4"
  1829. - "jsr @%0%#"
  1830. + "@
  1831. + jsr @%0%#
  1832. + bsrf %0\\n%O1:%#"
  1833. [(set_attr "type" "sfunc")
  1834. (set_attr "needs_delay_slot" "yes")])
  1835. diff --git a/gcc/config/sh/sh.opt b/gcc/config/sh/sh.opt
  1836. index 8875b5d..7a50ca0 100644
  1837. --- a/gcc/config/sh/sh.opt
  1838. +++ b/gcc/config/sh/sh.opt
  1839. @@ -264,6 +264,10 @@ mdivsi3_libfunc=
  1840. Target RejectNegative Joined Var(sh_divsi3_libfunc) Init("")
  1841. Specify name for 32 bit signed division function
  1842. +mfdpic
  1843. +Target Report Var(TARGET_FDPIC)
  1844. +Generate ELF FDPIC code
  1845. +
  1846. mfmovd
  1847. Target RejectNegative Mask(FMOVD)
  1848. Enable the use of 64-bit floating point registers in fmov instructions. See -mdalign if 64-bit alignment is required.
  1849. diff --git a/gcc/config.gcc b/gcc/config.gcc
  1850. index bf26776..ed118f3 100644
  1851. --- a/gcc/config.gcc
  1852. +++ b/gcc/config.gcc
  1853. @@ -2621,6 +2621,9 @@ sh-*-elf* | sh[12346l]*-*-elf* | \
  1854. tm_file="${tm_file} dbxelf.h elfos.h sh/elf.h"
  1855. case ${target} in
  1856. sh*-*-linux*) tmake_file="${tmake_file} sh/t-linux"
  1857. + if test x$enable_fdpic = xyes; then
  1858. + tm_defines="$tm_defines FDPIC_DEFAULT=1"
  1859. + fi
  1860. tm_file="${tm_file} gnu-user.h linux.h glibc-stdint.h sh/linux.h" ;;
  1861. sh*-*-netbsd*)
  1862. tm_file="${tm_file} netbsd.h netbsd-elf.h sh/netbsd-elf.h"
  1863. diff --git a/gcc/doc/install.texi b/gcc/doc/install.texi
  1864. index 1fd773e..fe57b97 100644
  1865. --- a/gcc/doc/install.texi
  1866. +++ b/gcc/doc/install.texi
  1867. @@ -1810,6 +1810,9 @@ When neither of these configure options are used, the default will be
  1868. 128-bit @code{long double} when built against GNU C Library 2.4 and later,
  1869. 64-bit @code{long double} otherwise.
  1870. +@item --enable-fdpic
  1871. +On SH Linux systems, generate ELF FDPIC code.
  1872. +
  1873. @item --with-gmp=@var{pathname}
  1874. @itemx --with-gmp-include=@var{pathname}
  1875. @itemx --with-gmp-lib=@var{pathname}
  1876. diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
  1877. index ebfaaa1..8b26eac 100644
  1878. --- a/gcc/doc/invoke.texi
  1879. +++ b/gcc/doc/invoke.texi
  1880. @@ -21178,6 +21178,10 @@ in effect.
  1881. Prefer zero-displacement conditional branches for conditional move instruction
  1882. patterns. This can result in faster code on the SH4 processor.
  1883. +@item -mfdpic
  1884. +@opindex fdpic
  1885. +Generate code using the FDPIC ABI.
  1886. +
  1887. @end table
  1888. @node Solaris 2 Options
  1889. diff --git a/libitm/config/sh/sjlj.S b/libitm/config/sh/sjlj.S
  1890. index 410cef6..76ec6df 100644
  1891. --- a/libitm/config/sh/sjlj.S
  1892. +++ b/libitm/config/sh/sjlj.S
  1893. @@ -58,9 +58,6 @@ _ITM_beginTransaction:
  1894. jsr @r1
  1895. mov r15, r5
  1896. #else
  1897. - mova .Lgot, r0
  1898. - mov.l .Lgot, r12
  1899. - add r0, r12
  1900. mov.l .Lbegin, r1
  1901. bsrf r1
  1902. mov r15, r5
  1903. @@ -80,13 +77,11 @@ _ITM_beginTransaction:
  1904. cfi_endproc
  1905. .align 2
  1906. -.Lgot:
  1907. - .long _GLOBAL_OFFSET_TABLE_
  1908. .Lbegin:
  1909. #if defined HAVE_ATTRIBUTE_VISIBILITY || !defined __PIC__
  1910. .long GTM_begin_transaction
  1911. #else
  1912. - .long GTM_begin_transaction@PLT-(.Lbegin0-.)
  1913. + .long GTM_begin_transaction@PCREL-(.Lbegin0-.)
  1914. #endif
  1915. .size _ITM_beginTransaction, . - _ITM_beginTransaction
  1916. diff --git a/include/longlong.h b/include/longlong.h
  1917. index a0b2ce1..19164ed 100644
  1918. --- a/include/longlong.h
  1919. +++ b/include/longlong.h
  1920. @@ -1102,6 +1102,29 @@ extern UDItype __umulsidi3 (USItype, USItype);
  1921. /* This is the same algorithm as __udiv_qrnnd_c. */
  1922. #define UDIV_NEEDS_NORMALIZATION 1
  1923. +#ifdef __FDPIC__
  1924. +#define udiv_qrnnd(q, r, n1, n0, d) \
  1925. + do { \
  1926. + extern UWtype __udiv_qrnnd_16 (UWtype, UWtype) \
  1927. + __attribute__ ((visibility ("hidden"))); \
  1928. + /* r0: rn r1: qn */ /* r0: n1 r4: n0 r5: d r6: d1 */ /* r2: __m */ \
  1929. + __asm__ ( \
  1930. + "mov%M4 %4,r5\n" \
  1931. +" swap.w %3,r4\n" \
  1932. +" swap.w r5,r6\n" \
  1933. +" mov.l @%5,r2\n" \
  1934. +" jsr @r2\n" \
  1935. +" shll16 r6\n" \
  1936. +" swap.w r4,r4\n" \
  1937. +" mov.l @%5,r2\n" \
  1938. +" jsr @r2\n" \
  1939. +" swap.w r1,%0\n" \
  1940. +" or r1,%0" \
  1941. + : "=r" (q), "=&z" (r) \
  1942. + : "1" (n1), "r" (n0), "rm" (d), "r" (&__udiv_qrnnd_16) \
  1943. + : "r1", "r2", "r4", "r5", "r6", "pr", "t"); \
  1944. + } while (0)
  1945. +#else
  1946. #define udiv_qrnnd(q, r, n1, n0, d) \
  1947. do { \
  1948. extern UWtype __udiv_qrnnd_16 (UWtype, UWtype) \
  1949. @@ -1121,6 +1144,7 @@ extern UDItype __umulsidi3 (USItype, USItype);
  1950. : "1" (n1), "r" (n0), "rm" (d), "r" (&__udiv_qrnnd_16) \
  1951. : "r1", "r2", "r4", "r5", "r6", "pr", "t"); \
  1952. } while (0)
  1953. +#endif
  1954. #define UDIV_TIME 80