リビジョン | 3d739910f83f10f081de6f7586fb5932a51f499b (tree) |
---|---|
日時 | 2022-11-28 15:53:18 |
作者 | Yoshinori Sato <yo-satoh@sios...> |
コミッター | Yoshinori Sato |
wip: RX fdpic.
Signed-off-by: Yoshinori Sato <yo-satoh@sios.com>
@@ -174,5 +174,6 @@ rx_find_use_of_reg (rtx reg, rtx_insn* insn, F stepfunc) | ||
174 | 174 | bool nonpic_symbol_mentioned_p (rtx x); |
175 | 175 | rtx legitimize_pic_address (rtx orig, |
176 | 176 | machine_mode mode ATTRIBUTE_UNUSED, rtx reg); |
177 | +rtx rx_get_fdpic_reg_initial_val (void); | |
177 | 178 | |
178 | 179 | #endif /* GCC_RX_PROTOS_H */ |
@@ -171,12 +171,33 @@ rx_legitimize_address (rtx x, | ||
171 | 171 | rtx |
172 | 172 | legitimize_pic_address (rtx orig, machine_mode mode ATTRIBUTE_UNUSED, rtx reg) |
173 | 173 | { |
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)))) | |
175 | 177 | { |
176 | 178 | if (reg == NULL_RTX) |
177 | 179 | reg = gen_reg_rtx (Pmode); |
178 | 180 | |
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)); | |
180 | 201 | crtl->uses_pic_offset_table = 1; |
181 | 202 | return reg; |
182 | 203 | } |
@@ -185,7 +206,11 @@ legitimize_pic_address (rtx orig, machine_mode mode ATTRIBUTE_UNUSED, rtx reg) | ||
185 | 206 | if (reg == NULL_RTX) |
186 | 207 | reg = gen_reg_rtx (Pmode); |
187 | 208 | |
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)); | |
189 | 214 | crtl->uses_pic_offset_table = 1; |
190 | 215 | return reg; |
191 | 216 | } |
@@ -318,9 +343,9 @@ nonpic_symbol_mentioned_p (rtx x) | ||
318 | 343 | && (XINT (x, 1) == UNSPEC_PIC |
319 | 344 | || XINT (x, 1) == UNSPEC_GOT |
320 | 345 | || XINT (x, 1) == UNSPEC_GOTOFF |
321 | - || XINT (x, 1) == UNSPEC_GOTPLT | |
322 | 346 | || XINT (x, 1) == UNSPEC_PLT |
323 | - || XINT (x, 1) == UNSPEC_PCREL)) | |
347 | + || XINT (x, 1) == UNSPEC_GOTFUNCDESC | |
348 | + || XINT (x, 1) == UNSPEC_GOTOFFFUNCDESC)) | |
324 | 349 | return false; |
325 | 350 | |
326 | 351 | const char* fmt = GET_RTX_FORMAT (GET_CODE (x)); |
@@ -530,12 +555,24 @@ rx_print_operand_address (FILE * file, machine_mode /*mode*/, rtx addr) | ||
530 | 555 | case UNSPEC: |
531 | 556 | { |
532 | 557 | int post = XINT (addr, 1); |
558 | + const char *attr = NULL; | |
533 | 559 | addr = XVECEXP (addr, 0, 0); |
534 | 560 | switch (post) |
535 | 561 | { |
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, "#"); | |
537 | 574 | output_addr_const (file, addr); |
538 | - fprintf (file, "@GOTOFF"); | |
575 | + fprintf(file, "@%s", attr); | |
539 | 576 | return; |
540 | 577 | } |
541 | 578 | } |
@@ -1927,7 +1964,7 @@ rx_expand_prologue (void) | ||
1927 | 1964 | gen_safe_add (stack_pointer_rtx, frame_pointer_rtx, NULL_RTX, |
1928 | 1965 | false /* False because the epilogue will use the FP not the SP. */); |
1929 | 1966 | } |
1930 | - if (crtl->uses_pic_offset_table) | |
1967 | + if (crtl->uses_pic_offset_table && !TARGET_FDPIC) | |
1931 | 1968 | { |
1932 | 1969 | emit_insn (gen_loadGOT (gen_rtx_REG (SImode, PIC_REG))); |
1933 | 1970 | } |
@@ -2933,6 +2970,13 @@ rx_option_override (void) | ||
2933 | 2970 | if (flag_strict_volatile_bitfields < 0 && abi_version_at_least(2)) |
2934 | 2971 | flag_strict_volatile_bitfields = 1; |
2935 | 2972 | |
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 | + | |
2936 | 2980 | rx_override_options_after_change (); |
2937 | 2981 | |
2938 | 2982 | /* These values are bytes, not log. */ |
@@ -3042,7 +3086,10 @@ rx_is_legitimate_constant (machine_mode mode ATTRIBUTE_UNUSED, rtx x) | ||
3042 | 3086 | case UNSPEC: |
3043 | 3087 | return XINT (x, 1) == UNSPEC_CONST || |
3044 | 3088 | XINT (x, 1) == UNSPEC_PID_ADDR || |
3089 | + XINT (x, 1) == UNSPEC_GOT || | |
3045 | 3090 | XINT (x, 1) == UNSPEC_GOTOFF || |
3091 | + XINT (x, 1) == UNSPEC_GOTFUNCDESC || | |
3092 | + XINT (x, 1) == UNSPEC_GOTOFFFUNCDESC || | |
3046 | 3093 | XINT (x, 1) == UNSPEC_PLT; |
3047 | 3094 | |
3048 | 3095 | default: |
@@ -3745,6 +3792,36 @@ int rx_legitimate_pic_operand_p(rtx x) | ||
3745 | 3792 | || ! nonpic_symbol_mentioned_p (get_pool_constant (x))))); |
3746 | 3793 | } |
3747 | 3794 | |
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 | + | |
3748 | 3825 | |
3749 | 3826 | #undef TARGET_NARROW_VOLATILE_BITFIELD |
3750 | 3827 | #define TARGET_NARROW_VOLATILE_BITFIELD rx_narrow_volatile_bitfield |
@@ -72,6 +72,12 @@ | ||
72 | 72 | builtin_define ("__RX_ALLOW_STRING_INSNS__"); \ |
73 | 73 | else \ |
74 | 74 | builtin_define ("__RX_DISALLOW_STRING_INSNS__");\ |
75 | + \ | |
76 | + if (TARGET_FDPIC) \ | |
77 | + { \ | |
78 | + builtin_define ("__FDPIC__"); \ | |
79 | + builtin_define ("__RX_FDPIC__"); \ | |
80 | + } \ | |
75 | 81 | } \ |
76 | 82 | while (0) |
77 | 83 |
@@ -106,6 +112,7 @@ | ||
106 | 112 | %{mint-register=*} \ |
107 | 113 | %{mgcc-abi:-mgcc-abi} %{!mgcc-abi:-mrx-abi} \ |
108 | 114 | %{mcpu=*} \ |
115 | +%{mfdpic:--fdpic} \ | |
109 | 116 | " |
110 | 117 | |
111 | 118 | #undef LIB_SPEC |
@@ -35,6 +35,8 @@ | ||
35 | 35 | (define_constants |
36 | 36 | [ |
37 | 37 | (SP_REG 0) |
38 | + (R2_REG 2) | |
39 | + (PIC_REG 13) | |
38 | 40 | (CC_REG 16) |
39 | 41 | |
40 | 42 | (UNSPEC_LOW_REG 0) |
@@ -80,10 +82,8 @@ | ||
80 | 82 | (UNSPEC_GOT 61) |
81 | 83 | (UNSPEC_GOTOFF 62) |
82 | 84 | (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) | |
87 | 87 | |
88 | 88 | (CTRLREG_PSW 0) |
89 | 89 | (CTRLREG_PC 1) |
@@ -94,8 +94,6 @@ | ||
94 | 94 | (CTRLREG_ISP 10) |
95 | 95 | (CTRLREG_FINTV 11) |
96 | 96 | (CTRLREG_INTB 12) |
97 | - | |
98 | - (PIC_REG 13) | |
99 | 97 | ] |
100 | 98 | ) |
101 | 99 |
@@ -441,10 +439,22 @@ | ||
441 | 439 | { |
442 | 440 | rtx dest = XEXP (operands[0], 0); |
443 | 441 | |
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 | + } | |
448 | 458 | } |
449 | 459 | ) |
450 | 460 |
@@ -536,9 +546,23 @@ | ||
536 | 546 | (return)])] |
537 | 547 | "" |
538 | 548 | { |
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 | + } | |
542 | 566 | DONE; |
543 | 567 | } |
544 | 568 | ) |
@@ -2906,8 +2930,15 @@ | ||
2906 | 2930 | [(match_operand 0 "" "") (match_operand 1 "" "")] |
2907 | 2931 | "" |
2908 | 2932 | { |
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); | |
2910 | 2936 | |
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))); | |
2911 | 2942 | DONE; |
2912 | 2943 | }) |
2913 | 2944 |
@@ -2920,28 +2951,51 @@ | ||
2920 | 2951 | [(match_operand 0 "" "") (match_operand 1 "" "")] |
2921 | 2952 | "" |
2922 | 2953 | { |
2923 | - rtx gotoffsym; | |
2924 | - rtx t = (!can_create_pseudo_p () | |
2925 | - ? operands[0] | |
2926 | - : gen_reg_rtx (GET_MODE (operands[0]))); | |
2927 | - | |
2928 | 2954 | rtx picreg = gen_rtx_REG (Pmode, PIC_REG); |
2929 | 2955 | |
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))); | |
2935 | 2960 | DONE; |
2936 | 2961 | }) |
2937 | 2962 | |
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 | +}) | |
2945 | 2999 | |
2946 | 3000 | (define_insn "loadGOT" |
2947 | 3001 | [(set (match_operand:SI 0 "register_operand" "=r") |
@@ -2951,25 +3005,82 @@ | ||
2951 | 3005 | return "mvfc\tpc,%0\n\tadd\t#_GLOBAL_OFFSET_TABLE_,%0"; |
2952 | 3006 | }) |
2953 | 3007 | |
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 | + | |
2954 | 3051 | (define_expand "call_value_internal_got" |
2955 | 3052 | [(set (match_operand 0 "register_operand" "=r,r") |
2956 | 3053 | (call (mem:QI (match_operand:SI 1 "rx_call_operand" "r,CALL_OP_SYMBOL_REF")) |
2957 | 3054 | (const_int 0))) |
3055 | + (use (reg:SI PIC_REG)) | |
2958 | 3056 | (clobber (reg:CC CC_REG))] |
2959 | 3057 | "" |
2960 | 3058 | { |
2961 | - rtx gotoffsym; | |
2962 | - rtx t = (!can_create_pseudo_p () | |
2963 | - ? operands[0] | |
2964 | - : gen_reg_rtx (GET_MODE (operands[0]))); | |
3059 | + rtx gotsym; | |
2965 | 3060 | |
2966 | 3061 | 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 | + } | |
2973 | 3084 | DONE; |
2974 | 3085 | }) |
2975 | 3086 |
@@ -2985,34 +3096,96 @@ | ||
2985 | 3096 | (set_attr "timings" "33")] |
2986 | 3097 | ) |
2987 | 3098 | |
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)) | |
2992 | 3103 | (clobber (reg:CC CC_REG))] |
2993 | 3104 | "" |
2994 | 3105 | { |
2995 | - rtx gotoffsym; | |
2996 | - rtx t = (!can_create_pseudo_p () | |
2997 | - ? operands[0] | |
2998 | - : gen_reg_rtx (GET_MODE (operands[0]))); | |
3106 | + rtx gotsym; | |
2999 | 3107 | |
3000 | 3108 | 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 | + } | |
3007 | 3131 | DONE; |
3008 | 3132 | }) |
3009 | 3133 | |
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" "")) | |
3012 | 3136 | (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)) | |
3013 | 3186 | (clobber (reg:CC CC_REG))] |
3014 | 3187 | "" |
3015 | - "bsr\t%T0" | |
3188 | + "bra\t%A1@PLT" | |
3016 | 3189 | [(set_attr "length" "4") |
3017 | 3190 | (set_attr "timings" "33")] |
3018 | 3191 | ) |
@@ -143,3 +143,10 @@ Enables or disables the use of the SMOVF, SMOVB, SMOVU, SUNTIL, SWHILE and RMPA | ||
143 | 143 | mjsr |
144 | 144 | Target Mask(JSR) |
145 | 145 | 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 | + |