0007-fdpic.diff 63 KB

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