• R/O
  • HTTP
  • SSH
  • HTTPS

Commit

Tags
Aucun tag

Frequently used words (click to add to your profile)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

Commit MetaInfo

Révision3d739910f83f10f081de6f7586fb5932a51f499b (tree)
l'heure2022-11-28 15:53:18
AuteurYoshinori Sato <yo-satoh@sios...>
CommiterYoshinori Sato

Message de Log

wip: RX fdpic.

Signed-off-by: Yoshinori Sato <yo-satoh@sios.com>

Change Summary

Modification

--- a/gcc/config/rx/rx-protos.h
+++ b/gcc/config/rx/rx-protos.h
@@ -174,5 +174,6 @@ rx_find_use_of_reg (rtx reg, rtx_insn* insn, F stepfunc)
174174 bool nonpic_symbol_mentioned_p (rtx x);
175175 rtx legitimize_pic_address (rtx orig,
176176 machine_mode mode ATTRIBUTE_UNUSED, rtx reg);
177+rtx rx_get_fdpic_reg_initial_val (void);
177178
178179 #endif /* GCC_RX_PROTOS_H */
--- a/gcc/config/rx/rx.cc
+++ b/gcc/config/rx/rx.cc
@@ -171,12 +171,33 @@ rx_legitimize_address (rtx x,
171171 rtx
172172 legitimize_pic_address (rtx orig, machine_mode mode ATTRIBUTE_UNUSED, rtx reg)
173173 {
174- if (GET_CODE (orig) == LABEL_REF || GET_CODE (orig) == SYMBOL_REF)
174+ if (flag_plt && (GET_CODE (orig) == LABEL_REF ||
175+ (GET_CODE (orig) == SYMBOL_REF &&
176+ !SYMBOL_REF_LOCAL_P (orig))))
175177 {
176178 if (reg == NULL_RTX)
177179 reg = gen_reg_rtx (Pmode);
178180
179- emit_insn (gen_symGOTOFF2reg (reg, orig));
181+ if (TARGET_FDPIC
182+ && GET_CODE (orig) == SYMBOL_REF && SYMBOL_REF_FUNCTION_P (orig))
183+ {
184+ /* Weak functions may be NULL which doesn't work with
185+ GOTOFFFUNCDESC because the runtime offset is not known. */
186+ if (SYMBOL_REF_WEAK (orig))
187+ emit_insn (gen_symGOTFUNCDESC2reg (reg, orig));
188+ else
189+ emit_insn (gen_symGOTOFFFUNCDESC2reg (reg, orig));
190+ }
191+ else if (TARGET_FDPIC
192+ && (GET_CODE (orig) == LABEL_REF
193+ || (GET_CODE (orig) == SYMBOL_REF && SYMBOL_REF_DECL (orig)
194+ && (TREE_READONLY (SYMBOL_REF_DECL (orig))
195+ || SYMBOL_REF_EXTERNAL_P (orig)
196+ || DECL_SECTION_NAME(SYMBOL_REF_DECL (orig))))))
197+ /* In FDPIC, GOTOFF can only be used for writable data. */
198+ emit_insn (gen_symGOT2reg (reg, orig));
199+ else
200+ emit_insn (gen_symGOTOFF2reg (reg, orig));
180201 crtl->uses_pic_offset_table = 1;
181202 return reg;
182203 }
@@ -185,7 +206,11 @@ legitimize_pic_address (rtx orig, machine_mode mode ATTRIBUTE_UNUSED, rtx reg)
185206 if (reg == NULL_RTX)
186207 reg = gen_reg_rtx (Pmode);
187208
188- emit_insn (gen_symGOT2reg (reg, orig));
209+ if (TARGET_FDPIC &&
210+ SYMBOL_REF_FUNCTION_P (orig) && SYMBOL_REF_EXTERNAL_P(orig))
211+ emit_insn (gen_symGOTFUNCDESC2reg (reg, orig));
212+ else
213+ emit_insn (gen_symGOT2reg (reg, orig));
189214 crtl->uses_pic_offset_table = 1;
190215 return reg;
191216 }
@@ -318,9 +343,9 @@ nonpic_symbol_mentioned_p (rtx x)
318343 && (XINT (x, 1) == UNSPEC_PIC
319344 || XINT (x, 1) == UNSPEC_GOT
320345 || XINT (x, 1) == UNSPEC_GOTOFF
321- || XINT (x, 1) == UNSPEC_GOTPLT
322346 || XINT (x, 1) == UNSPEC_PLT
323- || XINT (x, 1) == UNSPEC_PCREL))
347+ || XINT (x, 1) == UNSPEC_GOTFUNCDESC
348+ || XINT (x, 1) == UNSPEC_GOTOFFFUNCDESC))
324349 return false;
325350
326351 const char* fmt = GET_RTX_FORMAT (GET_CODE (x));
@@ -530,12 +555,24 @@ rx_print_operand_address (FILE * file, machine_mode /*mode*/, rtx addr)
530555 case UNSPEC:
531556 {
532557 int post = XINT (addr, 1);
558+ const char *attr = NULL;
533559 addr = XVECEXP (addr, 0, 0);
534560 switch (post)
535561 {
536- case UNSPEC_GOTOFF:
562+#define ATTR_STR(_name) \
563+ case UNSPEC_##_name: \
564+ attr = #_name; \
565+ break;
566+ ATTR_STR(GOT)
567+ ATTR_STR(GOTOFF)
568+ ATTR_STR(GOTFUNCDESC)
569+ ATTR_STR(GOTOFFFUNCDESC)
570+ }
571+ if (attr)
572+ {
573+ fprintf (file, "#");
537574 output_addr_const (file, addr);
538- fprintf (file, "@GOTOFF");
575+ fprintf(file, "@%s", attr);
539576 return;
540577 }
541578 }
@@ -1927,7 +1964,7 @@ rx_expand_prologue (void)
19271964 gen_safe_add (stack_pointer_rtx, frame_pointer_rtx, NULL_RTX,
19281965 false /* False because the epilogue will use the FP not the SP. */);
19291966 }
1930- if (crtl->uses_pic_offset_table)
1967+ if (crtl->uses_pic_offset_table && !TARGET_FDPIC)
19311968 {
19321969 emit_insn (gen_loadGOT (gen_rtx_REG (SImode, PIC_REG)));
19331970 }
@@ -2933,6 +2970,13 @@ rx_option_override (void)
29332970 if (flag_strict_volatile_bitfields < 0 && abi_version_at_least(2))
29342971 flag_strict_volatile_bitfields = 1;
29352972
2973+ /* FDPIC code is a special form of PIC, and the vast majority of code
2974+ generation constraints that apply to PIC also apply to FDPIC, so we
2975+ set flag_pic to avoid the need to check TARGET_FDPIC everywhere
2976+ flag_pic is checked. */
2977+ if (TARGET_FDPIC && !flag_pic)
2978+ flag_pic = 2;
2979+
29362980 rx_override_options_after_change ();
29372981
29382982 /* These values are bytes, not log. */
@@ -3042,7 +3086,10 @@ rx_is_legitimate_constant (machine_mode mode ATTRIBUTE_UNUSED, rtx x)
30423086 case UNSPEC:
30433087 return XINT (x, 1) == UNSPEC_CONST ||
30443088 XINT (x, 1) == UNSPEC_PID_ADDR ||
3089+ XINT (x, 1) == UNSPEC_GOT ||
30453090 XINT (x, 1) == UNSPEC_GOTOFF ||
3091+ XINT (x, 1) == UNSPEC_GOTFUNCDESC ||
3092+ XINT (x, 1) == UNSPEC_GOTOFFFUNCDESC ||
30463093 XINT (x, 1) == UNSPEC_PLT;
30473094
30483095 default:
@@ -3745,6 +3792,36 @@ int rx_legitimate_pic_operand_p(rtx x)
37453792 || ! nonpic_symbol_mentioned_p (get_pool_constant (x)))));
37463793 }
37473794
3795+/* Emit insns to load the function address from FUNCDESC (an FDPIC
3796+ function descriptor) into r2 and the GOT address into r13,
3797+ returning an rtx for r2. */
3798+
3799+rtx
3800+rx_load_function_descriptor (rtx funcdesc)
3801+{
3802+ rtx r2 = gen_rtx_REG (Pmode, R2_REG);
3803+ rtx pic_reg = gen_rtx_REG (Pmode, PIC_REG);
3804+ rtx fnaddr = gen_rtx_MEM (Pmode, funcdesc);
3805+ rtx gotaddr = gen_rtx_MEM (Pmode, plus_constant (Pmode, funcdesc, 4));
3806+
3807+ emit_move_insn (r2, fnaddr);
3808+ /* The ABI requires the entry point address to be loaded first, so
3809+ prevent the load from being moved after that of the GOT
3810+ address. */
3811+ emit_insn (gen_blockage ());
3812+ emit_move_insn (pic_reg, gotaddr);
3813+ return r2;
3814+}
3815+
3816+/* Return an rtx holding the initial value of the FDPIC register (the
3817+ FDPIC pointer passed in from the caller). */
3818+
3819+rtx
3820+rx_get_fdpic_reg_initial_val (void)
3821+{
3822+ return get_hard_reg_initial_val (Pmode, PIC_REG);
3823+}
3824+
37483825
37493826 #undef TARGET_NARROW_VOLATILE_BITFIELD
37503827 #define TARGET_NARROW_VOLATILE_BITFIELD rx_narrow_volatile_bitfield
--- a/gcc/config/rx/rx.h
+++ b/gcc/config/rx/rx.h
@@ -72,6 +72,12 @@
7272 builtin_define ("__RX_ALLOW_STRING_INSNS__"); \
7373 else \
7474 builtin_define ("__RX_DISALLOW_STRING_INSNS__");\
75+ \
76+ if (TARGET_FDPIC) \
77+ { \
78+ builtin_define ("__FDPIC__"); \
79+ builtin_define ("__RX_FDPIC__"); \
80+ } \
7581 } \
7682 while (0)
7783
@@ -106,6 +112,7 @@
106112 %{mint-register=*} \
107113 %{mgcc-abi:-mgcc-abi} %{!mgcc-abi:-mrx-abi} \
108114 %{mcpu=*} \
115+%{mfdpic:--fdpic} \
109116 "
110117
111118 #undef LIB_SPEC
--- a/gcc/config/rx/rx.md
+++ b/gcc/config/rx/rx.md
@@ -35,6 +35,8 @@
3535 (define_constants
3636 [
3737 (SP_REG 0)
38+ (R2_REG 2)
39+ (PIC_REG 13)
3840 (CC_REG 16)
3941
4042 (UNSPEC_LOW_REG 0)
@@ -80,10 +82,8 @@
8082 (UNSPEC_GOT 61)
8183 (UNSPEC_GOTOFF 62)
8284 (UNSPEC_PLT 63)
83- (UNSPEC_GOTPLT 64)
84- (UNSPEC_PCREL 65)
85- (UNSPEC_SYMOFF 66)
86- (UNSPEC_PCREL_SYMOFF 67)
85+ (UNSPEC_GOTFUNCDESC 64)
86+ (UNSPEC_GOTOFFFUNCDESC 65)
8787
8888 (CTRLREG_PSW 0)
8989 (CTRLREG_PC 1)
@@ -94,8 +94,6 @@
9494 (CTRLREG_ISP 10)
9595 (CTRLREG_FINTV 11)
9696 (CTRLREG_INTB 12)
97-
98- (PIC_REG 13)
9997 ]
10098 )
10199
@@ -441,10 +439,22 @@
441439 {
442440 rtx dest = XEXP (operands[0], 0);
443441
444- if (! rx_call_operand (dest, Pmode))
445- dest = force_reg (Pmode, dest);
446- emit_call_insn (gen_call_internal (dest));
447- DONE;
442+ if (flag_pic &&
443+ (GET_CODE (dest) == SYMBOL_REF) && (!SYMBOL_REF_LOCAL_P (dest)))
444+ {
445+ if (flag_plt)
446+ emit_call_insn (gen_call_internal_plt (dest));
447+ else
448+ emit_call_insn (gen_call_internal_got (dest));
449+ DONE;
450+ }
451+ else
452+ {
453+ if (! rx_call_operand (dest, Pmode))
454+ dest = force_reg (Pmode, dest);
455+ emit_call_insn (gen_call_internal (dest));
456+ DONE;
457+ }
448458 }
449459 )
450460
@@ -536,9 +546,23 @@
536546 (return)])]
537547 ""
538548 {
539- if (MEM_P (operands[1]))
540- operands[1] = XEXP (operands[1], 0);
541- emit_call_insn (gen_sibcall_value_internal (operands[0], operands[1]));
549+ if (flag_pic &&
550+ (GET_CODE (operands[1]) == SYMBOL_REF) &&
551+ (!SYMBOL_REF_LOCAL_P (operands[1])))
552+ {
553+ if (flag_plt)
554+ emit_call_insn (gen_sibcall_value_internal_plt (operands[0],
555+ operands[1]));
556+ else
557+ emit_call_insn (gen_sibcall_value_internal_got (operands[0],
558+ operands[1]));
559+ }
560+ else
561+ {
562+ if (MEM_P (operands[1]))
563+ operands[1] = XEXP (operands[1], 0);
564+ emit_call_insn (gen_sibcall_value_internal (operands[0], operands[1]));
565+ }
542566 DONE;
543567 }
544568 )
@@ -2906,8 +2930,15 @@
29062930 [(match_operand 0 "" "") (match_operand 1 "" "")]
29072931 ""
29082932 {
2909- gen_sym2GOT (operands[1]);
2933+ rtx gotsym = gen_sym2GOT (operands[1]);
2934+ PUT_MODE (gotsym, Pmode);
2935+ rtx picreg = gen_rtx_REG (Pmode, PIC_REG);
29102936
2937+ if (TARGET_FDPIC)
2938+ emit_move_insn (picreg, rx_get_fdpic_reg_initial_val ());
2939+ emit_move_insn (operands[0],
2940+ gen_rtx_MEM(Pmode,
2941+ gen_rtx_PLUS(Pmode, picreg, gotsym)));
29112942 DONE;
29122943 })
29132944
@@ -2920,28 +2951,51 @@
29202951 [(match_operand 0 "" "") (match_operand 1 "" "")]
29212952 ""
29222953 {
2923- rtx gotoffsym;
2924- rtx t = (!can_create_pseudo_p ()
2925- ? operands[0]
2926- : gen_reg_rtx (GET_MODE (operands[0])));
2927-
29282954 rtx picreg = gen_rtx_REG (Pmode, PIC_REG);
29292955
2930- gotoffsym = gen_sym2GOTOFF (operands[1]);
2931- emit_insn (gen_mov_from_got(t, picreg, gotoffsym));
2932- emit_move_insn (operands[0], t);
2933- //emit_insn(gen_mov_from_rirb(operands[0], picreg));
2934-// set_unique_reg_note (insn, REG_EQUAL, operands[1]);
2956+ rtx gotoffsym = gen_sym2GOTOFF (operands[1]);
2957+ emit_move_insn (operands[0],
2958+ gen_rtx_MEM(Pmode,
2959+ gen_rtx_PLUS(Pmode, picreg, gotoffsym)));
29352960 DONE;
29362961 })
29372962
2938-(define_insn "mov_from_got"
2939- [(match_operand 0 "register_operand" "r")
2940- (match_operand 1 "register_operand" "r")
2941- (match_operand 2 "" "g")]
2942- ""
2943- "mov.l\t%A2[%1],%0"
2944-)
2963+(define_expand "sym2GOTFUNCDESC"
2964+ [(const (unspec [(match_operand 0)] UNSPEC_GOTFUNCDESC))]
2965+ "TARGET_FDPIC")
2966+
2967+(define_expand "symGOTFUNCDESC2reg"
2968+ [(match_operand 0) (match_operand 1)]
2969+ "TARGET_FDPIC"
2970+{
2971+ rtx picreg = gen_rtx_REG (Pmode, PIC_REG);
2972+ rtx gotsym = gen_sym2GOTFUNCDESC (operands[1]);
2973+ PUT_MODE (gotsym, Pmode);
2974+ emit_move_insn (operands[0],
2975+ gen_rtx_MEM(Pmode,
2976+ gen_rtx_PLUS(Pmode, picreg, gotsym)));
2977+ DONE;
2978+})
2979+
2980+(define_expand "sym2GOTOFFFUNCDESC"
2981+ [(const (unspec [(match_operand 0)] UNSPEC_GOTOFFFUNCDESC))]
2982+ "TARGET_FDPIC")
2983+
2984+(define_expand "symGOTOFFFUNCDESC2reg"
2985+ [(match_operand 0) (match_operand 1)]
2986+ "TARGET_FDPIC"
2987+{
2988+ rtx picreg = rx_get_fdpic_reg_initial_val ();
2989+ rtx t = !can_create_pseudo_p ()
2990+ ? operands[0]
2991+ : gen_reg_rtx (GET_MODE (operands[0]));
2992+
2993+ rtx gotoffsym = gen_sym2GOTOFFFUNCDESC (operands[1]);
2994+ PUT_MODE (gotoffsym, Pmode);
2995+ emit_move_insn (t, gotoffsym);
2996+ emit_move_insn (operands[0], gen_rtx_PLUS (Pmode, t, picreg));
2997+ DONE;
2998+})
29452999
29463000 (define_insn "loadGOT"
29473001 [(set (match_operand:SI 0 "register_operand" "=r")
@@ -2951,25 +3005,82 @@
29513005 return "mvfc\tpc,%0\n\tadd\t#_GLOBAL_OFFSET_TABLE_,%0";
29523006 })
29533007
3008+(define_expand "call_internal_got"
3009+ [(call (mem:QI (match_operand:SI 0 "rx_call_operand" "r,CALL_OP_SYMBOL_REF"))
3010+ (const_int 0))
3011+ (use (reg:SI PIC_REG))
3012+ (clobber (reg:CC CC_REG))]
3013+ ""
3014+{
3015+ rtx gotsym;
3016+
3017+ rtx picreg = gen_rtx_REG (Pmode, PIC_REG);
3018+ if (!TARGET_FDPIC)
3019+ {
3020+ gotsym = gen_sym2GOT (operands[0]);
3021+ PUT_MODE (gotsym, Pmode);
3022+ emit_move_insn (operands[0],
3023+ gen_rtx_MEM(Pmode,
3024+ gen_rtx_PLUS(Pmode, picreg, gotsym)));
3025+ }
3026+ else
3027+ {
3028+ emit_move_insn (picreg, rx_get_fdpic_reg_initial_val ());
3029+ gotsym = gen_sym2GOTFUNCDESC (operands[0]);
3030+ PUT_MODE (gotsym, Pmode);
3031+ emit_move_insn(picreg, gen_rtx_PLUS(Pmode, picreg, gotsym));
3032+ emit_move_insn(operands[0], gen_rtx_MEM(Pmode, picreg));
3033+ emit_move_insn(picreg, gen_rtx_MEM(Pmode,
3034+ plus_constant(Pmode, picreg, 4)));
3035+ }
3036+ emit_call_insn (gen_call_internal (operands[0]));
3037+ DONE;
3038+})
3039+
3040+(define_insn "call_internal_plt"
3041+ [(call (mem:QI (match_operand:SI 0 "rx_symbolic_call_operand" ""))
3042+ (const_int 0))
3043+ (use (reg:SI PIC_REG))
3044+ (clobber (reg:CC CC_REG))]
3045+ ""
3046+ "bsr\t%A0@PLT"
3047+ [(set_attr "length" "4")
3048+ (set_attr "timings" "33")]
3049+)
3050+
29543051 (define_expand "call_value_internal_got"
29553052 [(set (match_operand 0 "register_operand" "=r,r")
29563053 (call (mem:QI (match_operand:SI 1 "rx_call_operand" "r,CALL_OP_SYMBOL_REF"))
29573054 (const_int 0)))
3055+ (use (reg:SI PIC_REG))
29583056 (clobber (reg:CC CC_REG))]
29593057 ""
29603058 {
2961- rtx gotoffsym;
2962- rtx t = (!can_create_pseudo_p ()
2963- ? operands[0]
2964- : gen_reg_rtx (GET_MODE (operands[0])));
3059+ rtx gotsym;
29653060
29663061 rtx picreg = gen_rtx_REG (Pmode, PIC_REG);
2967-
2968- gotoffsym = gen_sym2GOTOFF (operands[1]);
2969- emit_move_insn (t, gotoffsym);
2970- emit_insn (gen_mov_from_got(t, picreg, gotoffsym));
2971- emit_move_insn (operands[0], t);
2972- emit_call_insn (gen_call_internal (operands[0]));
3062+ if (!TARGET_FDPIC)
3063+ {
3064+ gotsym = gen_sym2GOT (operands[1]);
3065+ PUT_MODE (gotsym, Pmode);
3066+ emit_move_insn (operands[0],
3067+ gen_rtx_MEM(Pmode,
3068+ gen_rtx_PLUS(Pmode, picreg, gotsym)));
3069+ emit_call_insn (gen_call_value_internal (operands[0], operands[1]));
3070+ }
3071+ else
3072+ {
3073+ rtx t = !can_create_pseudo_p ()
3074+ ? operands[1] : gen_reg_rtx (GET_MODE (operands[1]));
3075+ emit_move_insn (picreg, rx_get_fdpic_reg_initial_val ());
3076+ gotsym = gen_sym2GOTFUNCDESC (operands[1]);
3077+ PUT_MODE (gotsym, Pmode);
3078+ emit_move_insn(picreg, gen_rtx_PLUS(Pmode, picreg, gotsym));
3079+ emit_move_insn(t, gen_rtx_MEM(Pmode, picreg));
3080+ emit_move_insn(picreg, gen_rtx_MEM(Pmode,
3081+ plus_constant(Pmode, picreg, 4)));
3082+ emit_call_insn (gen_call_value_internal (operands[0], t));
3083+ }
29733084 DONE;
29743085 })
29753086
@@ -2985,34 +3096,96 @@
29853096 (set_attr "timings" "33")]
29863097 )
29873098
2988-(define_expand "call_value_got"
2989- [(set (match_operand 0 "register_operand" "=r,r")
2990- (call (mem:QI (match_operand:SI 1 "rx_call_operand" "r,CALL_OP_SYMBOL_REF"))
2991- (const_int 0)))
3099+(define_expand "sibcall_internal_got"
3100+ [(call (mem:QI (match_operand:SI 0 "rx_call_operand" "r,CALL_OP_SYMBOL_REF"))
3101+ (const_int 0))
3102+ (use (reg:SI PIC_REG))
29923103 (clobber (reg:CC CC_REG))]
29933104 ""
29943105 {
2995- rtx gotoffsym;
2996- rtx t = (!can_create_pseudo_p ()
2997- ? operands[0]
2998- : gen_reg_rtx (GET_MODE (operands[0])));
3106+ rtx gotsym;
29993107
30003108 rtx picreg = gen_rtx_REG (Pmode, PIC_REG);
3001-
3002- gotoffsym = gen_sym2GOTOFF (operands[1]);
3003- emit_move_insn (t, gotoffsym);
3004- emit_insn (gen_mov_from_got(t, picreg, gotoffsym));
3005- emit_move_insn (operands[0], t);
3006- emit_call_insn (gen_call_internal (operands[0]));
3109+ if (!TARGET_FDPIC)
3110+ {
3111+ gotsym = gen_sym2GOT (operands[0]);
3112+ PUT_MODE (gotsym, Pmode);
3113+ emit_move_insn (operands[0],
3114+ gen_rtx_MEM(Pmode,
3115+ gen_rtx_PLUS(Pmode, picreg, gotsym)));
3116+ emit_call_insn (gen_sibcall_internal (operands[0]));
3117+ }
3118+ else
3119+ {
3120+ rtx t = !can_create_pseudo_p ()
3121+ ? operands[0] : gen_reg_rtx (GET_MODE (operands[0]));
3122+ emit_move_insn (picreg, rx_get_fdpic_reg_initial_val ());
3123+ gotsym = gen_sym2GOTFUNCDESC (operands[0]);
3124+ PUT_MODE (gotsym, Pmode);
3125+ emit_move_insn(picreg, gen_rtx_PLUS(Pmode, picreg, gotsym));
3126+ emit_move_insn(t, gen_rtx_MEM(Pmode, picreg));
3127+ emit_move_insn(picreg, gen_rtx_MEM(Pmode,
3128+ plus_constant(Pmode, picreg, 4)));
3129+ emit_call_insn (gen_sibcall_internal (t));
3130+ }
30073131 DONE;
30083132 })
30093133
3010-(define_insn "call_value_plt"
3011- [(call (mem:QI (match_operand:SI 0 "rx_call_operand" "CALL_OP_SYMBOL_REF"))
3134+(define_insn "sibcall_internal_plt"
3135+ [(call (mem:QI (match_operand:SI 0 "rx_symbolic_call_operand" ""))
30123136 (const_int 0))
3137+ (use (reg:SI PIC_REG))
3138+ (clobber (reg:CC CC_REG))]
3139+ ""
3140+ "bra\t%A0@PLT"
3141+ [(set_attr "length" "4")
3142+ (set_attr "timings" "33")]
3143+)
3144+
3145+(define_expand "sibcall_value_internal_got"
3146+ [(set (match_operand 0 "register_operand" "=r,r")
3147+ (call (mem:QI (match_operand:SI 1 "rx_call_operand" "r,CALL_OP_SYMBOL_REF"))
3148+ (const_int 0)))
3149+ (use (reg:SI PIC_REG))
3150+ (clobber (reg:CC CC_REG))]
3151+ ""
3152+{
3153+ rtx gotsym;
3154+
3155+ rtx picreg = gen_rtx_REG (Pmode, PIC_REG);
3156+ if (!TARGET_FDPIC)
3157+ {
3158+ gotsym = gen_sym2GOT (operands[1]);
3159+ PUT_MODE (gotsym, Pmode);
3160+ emit_move_insn (operands[0],
3161+ gen_rtx_MEM(Pmode,
3162+ gen_rtx_PLUS(Pmode, picreg, gotsym)));
3163+ emit_call_insn (gen_sibcall_value_internal (operands[0], operands[1]));
3164+ }
3165+ else
3166+ {
3167+ rtx t = !can_create_pseudo_p ()
3168+ ? operands[1] : gen_reg_rtx (GET_MODE (operands[1]));
3169+ emit_move_insn (picreg, rx_get_fdpic_reg_initial_val ());
3170+ gotsym = gen_sym2GOTFUNCDESC (operands[1]);
3171+ PUT_MODE (gotsym, Pmode);
3172+ emit_move_insn(picreg, gen_rtx_PLUS(Pmode, picreg, gotsym));
3173+ emit_move_insn(t, gen_rtx_MEM(Pmode, picreg));
3174+ emit_move_insn(picreg, gen_rtx_MEM(Pmode,
3175+ plus_constant(Pmode, picreg, 4)));
3176+ emit_call_insn (gen_sibcall_value_internal (operands[0], t));
3177+ }
3178+ DONE;
3179+})
3180+
3181+(define_insn "sibcall_value_internal_plt"
3182+ [(set (match_operand 0 "register_operand" "=r")
3183+ (call (mem:QI (match_operand:SI 1 "rx_symbolic_call_operand" ""))
3184+ (const_int 0)))
3185+ (use (reg:SI PIC_REG))
30133186 (clobber (reg:CC CC_REG))]
30143187 ""
3015- "bsr\t%T0"
3188+ "bra\t%A1@PLT"
30163189 [(set_attr "length" "4")
30173190 (set_attr "timings" "33")]
30183191 )
--- a/gcc/config/rx/rx.opt
+++ b/gcc/config/rx/rx.opt
@@ -143,3 +143,10 @@ Enables or disables the use of the SMOVF, SMOVB, SMOVU, SUNTIL, SWHILE and RMPA
143143 mjsr
144144 Target Mask(JSR)
145145 Always use JSR, never BSR, for calls.
146+
147+;---------------------------------------------------
148+
149+mfdpic
150+Target Var(TARGET_FDPIC) Init(0)
151+Generate ELF FDPIC code.
152+