リビジョン | 50b396be383a5c84c8142feeb8ef8ea0ecda80bd (tree) |
---|---|
日時 | 2022-11-25 17:39:56 |
作者 | Yoshinori Sato <yo-satoh@sios...> |
コミッター | Yoshinori Sato |
WIP: fix PLT.
Signed-off-by: Yoshinori Sato <yo-satoh@sios.com>
@@ -172,5 +172,7 @@ rx_find_use_of_reg (rtx reg, rtx_insn* insn, F stepfunc) | ||
172 | 172 | #endif |
173 | 173 | |
174 | 174 | bool nonpic_symbol_mentioned_p (rtx x); |
175 | +rtx legitimize_pic_address (rtx orig, | |
176 | + machine_mode mode ATTRIBUTE_UNUSED, rtx reg); | |
175 | 177 | |
176 | 178 | #endif /* GCC_RX_PROTOS_H */ |
@@ -143,11 +143,9 @@ rx_pid_data_operand (rtx op) | ||
143 | 143 | return PID_NOT_PID; |
144 | 144 | } |
145 | 145 | |
146 | -rtx | |
147 | -legitimize_pic_address (rtx orig, machine_mode mode ATTRIBUTE_UNUSED, rtx reg); | |
148 | - | |
149 | 146 | static rtx |
150 | -rx_legitimize_address (rtx x, rtx oldx , | |
147 | +rx_legitimize_address (rtx x, | |
148 | + rtx oldx ATTRIBUTE_UNUSED, | |
151 | 149 | machine_mode mode ATTRIBUTE_UNUSED) |
152 | 150 | { |
153 | 151 | if (flag_pic) |
@@ -168,6 +166,32 @@ rx_legitimize_address (rtx x, rtx oldx , | ||
168 | 166 | return x; |
169 | 167 | } |
170 | 168 | |
169 | +/* Convert a non-PIC address in `orig' to a PIC address using @GOT or | |
170 | + @GOTOFF in `reg'. */ | |
171 | +rtx | |
172 | +legitimize_pic_address (rtx orig, machine_mode mode ATTRIBUTE_UNUSED, rtx reg) | |
173 | +{ | |
174 | + if (GET_CODE (orig) == LABEL_REF || GET_CODE (orig) == SYMBOL_REF) | |
175 | + { | |
176 | + if (reg == NULL_RTX) | |
177 | + reg = gen_reg_rtx (Pmode); | |
178 | + | |
179 | + emit_insn (gen_symGOTOFF2reg (reg, orig)); | |
180 | + crtl->uses_pic_offset_table = 1; | |
181 | + return reg; | |
182 | + } | |
183 | + else if (GET_CODE (orig) == SYMBOL_REF) | |
184 | + { | |
185 | + if (reg == NULL_RTX) | |
186 | + reg = gen_reg_rtx (Pmode); | |
187 | + | |
188 | + emit_insn (gen_symGOT2reg (reg, orig)); | |
189 | + crtl->uses_pic_offset_table = 1; | |
190 | + return reg; | |
191 | + } | |
192 | + return orig; | |
193 | +} | |
194 | + | |
171 | 195 | /* Return true if OP is a reference to an object in a small data area. */ |
172 | 196 | |
173 | 197 | static bool |
@@ -303,44 +327,18 @@ nonpic_symbol_mentioned_p (rtx x) | ||
303 | 327 | for (int i = GET_RTX_LENGTH (GET_CODE (x)) - 1; i >= 0; i--) |
304 | 328 | { |
305 | 329 | if (fmt[i] == 'E') |
306 | - { | |
330 | + { | |
307 | 331 | for (int j = XVECLEN (x, i) - 1; j >= 0; j--) |
308 | 332 | if (nonpic_symbol_mentioned_p (XVECEXP (x, i, j))) |
309 | 333 | return true; |
310 | - } | |
334 | + } | |
311 | 335 | else if (fmt[i] == 'e' && nonpic_symbol_mentioned_p (XEXP (x, i))) |
312 | - return true; | |
336 | + return true; | |
313 | 337 | } |
314 | 338 | |
315 | 339 | return false; |
316 | 340 | } |
317 | 341 | |
318 | -/* Convert a non-PIC address in `orig' to a PIC address using @GOT or | |
319 | - @GOTOFF in `reg'. */ | |
320 | -rtx | |
321 | -legitimize_pic_address (rtx orig, machine_mode mode ATTRIBUTE_UNUSED, rtx reg) | |
322 | -{ | |
323 | - if (GET_CODE (orig) == LABEL_REF || GET_CODE (orig) == SYMBOL_REF) | |
324 | - { | |
325 | - if (reg == NULL_RTX) | |
326 | - reg = gen_reg_rtx (Pmode); | |
327 | - | |
328 | - emit_insn (gen_symGOTOFF2reg (reg, orig)); | |
329 | - crtl->uses_pic_offset_table = 1; | |
330 | - return reg; | |
331 | - } | |
332 | - else if (GET_CODE (orig) == SYMBOL_REF) | |
333 | - { | |
334 | - if (reg == NULL_RTX) | |
335 | - reg = gen_reg_rtx (Pmode); | |
336 | - | |
337 | - emit_insn (gen_symGOT2reg (reg, orig)); | |
338 | - crtl->uses_pic_offset_table = 1; | |
339 | - return reg; | |
340 | - } | |
341 | - return orig; | |
342 | -} | |
343 | - | |
344 | 342 | /* Returns TRUE for simple memory addresses, ie ones |
345 | 343 | that do not involve register indirect addressing |
346 | 344 | or pre/post increment/decrement. */ |
@@ -539,8 +537,6 @@ rx_print_operand_address (FILE * file, machine_mode /*mode*/, rtx addr) | ||
539 | 537 | fprintf (file, "#"); |
540 | 538 | output_addr_const (file, addr); |
541 | 539 | fprintf (file, "@GOTOFF"); |
542 | - crtl->uses_pic_offset_table = 1; | |
543 | - printf("%s %p %d\n", __func__, &(crtl->uses_pic_offset_table), crtl->uses_pic_offset_table); | |
544 | 540 | return; |
545 | 541 | } |
546 | 542 | } |
@@ -1016,47 +1012,6 @@ rx_print_operand (FILE * file, rtx op, int letter) | ||
1016 | 1012 | } |
1017 | 1013 | } |
1018 | 1014 | |
1019 | -/* Implement TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA. */ | |
1020 | -static bool | |
1021 | -rx_asm_output_addr_const_extra (FILE *file, rtx x) | |
1022 | -{ | |
1023 | - if (GET_CODE (x) == UNSPEC) | |
1024 | - { | |
1025 | - switch (XINT (x, 1)) | |
1026 | - { | |
1027 | - case UNSPEC_PIC: | |
1028 | - /* GLOBAL_OFFSET_TABLE or local symbols, no suffix. */ | |
1029 | - output_addr_const (file, XVECEXP (x, 0, 0)); | |
1030 | - break; | |
1031 | - case UNSPEC_GOT: | |
1032 | - output_addr_const (file, XVECEXP (x, 0, 0)); | |
1033 | - fputs ("@GOT", file); | |
1034 | - break; | |
1035 | - case UNSPEC_GOTOFF: | |
1036 | - output_addr_const (file, XVECEXP (x, 0, 0)); | |
1037 | - fputs ("@GOTOFF", file); | |
1038 | - break; | |
1039 | - case UNSPEC_PLT: | |
1040 | - output_addr_const (file, XVECEXP (x, 0, 0)); | |
1041 | - fputs ("@PLT", file); | |
1042 | - break; | |
1043 | - case UNSPEC_GOTPLT: | |
1044 | - output_addr_const (file, XVECEXP (x, 0, 0)); | |
1045 | - fputs ("@GOTPLT", file); | |
1046 | - break; | |
1047 | - case UNSPEC_PCREL: | |
1048 | - output_addr_const (file, XVECEXP (x, 0, 0)); | |
1049 | - fputs ("@PCREL", file); | |
1050 | - break; | |
1051 | - default: | |
1052 | - return false; | |
1053 | - } | |
1054 | - return true; | |
1055 | - } | |
1056 | - else | |
1057 | - return false; | |
1058 | -} | |
1059 | - | |
1060 | 1015 | /* Maybe convert an operand into its PID format. */ |
1061 | 1016 | |
1062 | 1017 | rtx |
@@ -1092,7 +1047,6 @@ rx_gen_move_template (rtx * operands, bool is_movu) | ||
1092 | 1047 | rtx dest = operands[0]; |
1093 | 1048 | rtx src = operands[1]; |
1094 | 1049 | |
1095 | - printf("%s\n", __func__); | |
1096 | 1050 | /* Decide which extension, if any, should be given to the move instruction. */ |
1097 | 1051 | switch (CONST_INT_P (src) ? GET_MODE (dest) : GET_MODE (src)) |
1098 | 1052 | { |
@@ -1621,8 +1575,8 @@ rx_get_stack_layout (unsigned int * lowest, | ||
1621 | 1575 | they can be used in the fast interrupt handler without |
1622 | 1576 | saving them on the stack. */ |
1623 | 1577 | || (is_fast_interrupt_func (NULL_TREE) |
1624 | - && ! IN_RANGE (reg, 10, 13))) | |
1625 | 1578 | || (flag_pic && reg == PIC_REGNUM)) |
1579 | + && ! IN_RANGE (reg, 10, 13))) | |
1626 | 1580 | { |
1627 | 1581 | if (low == 0) |
1628 | 1582 | low = reg; |
@@ -1893,9 +1847,6 @@ rx_expand_prologue (void) | ||
1893 | 1847 | else if (low) |
1894 | 1848 | push_regs (high, low); |
1895 | 1849 | |
1896 | - // if (flag_pic && df_regs_ever_live_p (PIC_REGNUM)) | |
1897 | - // emit_insn (gen_GOTaddr2picreg (const0_rtx)); | |
1898 | - | |
1899 | 1850 | if (MUST_SAVE_ACC_REGISTER) |
1900 | 1851 | { |
1901 | 1852 | unsigned int acc_high, acc_low; |
@@ -3089,8 +3040,8 @@ rx_is_legitimate_constant (machine_mode mode ATTRIBUTE_UNUSED, rtx x) | ||
3089 | 3040 | |
3090 | 3041 | case UNSPEC: |
3091 | 3042 | return XINT (x, 1) == UNSPEC_CONST || |
3092 | - XINT (x, 1) == UNSPEC_PID_ADDR || | |
3093 | - XINT (x, 1) == UNSPEC_GOTOFF; | |
3043 | + XINT (x, 1) == UNSPEC_PID_ADDR || | |
3044 | + XINT (x, 1) == UNSPEC_GOTOFF; | |
3094 | 3045 | |
3095 | 3046 | default: |
3096 | 3047 | /* FIXME: Can this ever happen ? */ |
@@ -3792,11 +3743,6 @@ int rx_legitimate_pic_operand_p(rtx x) | ||
3792 | 3743 | || ! nonpic_symbol_mentioned_p (get_pool_constant (x))))); |
3793 | 3744 | } |
3794 | 3745 | |
3795 | -static void | |
3796 | -rx_asm_final_postscan_insn (FILE *, rtx_insn *insn, rtx operands[], int num_rtx) | |
3797 | -{ | |
3798 | - return; | |
3799 | -} | |
3800 | 3746 | |
3801 | 3747 | #undef TARGET_NARROW_VOLATILE_BITFIELD |
3802 | 3748 | #define TARGET_NARROW_VOLATILE_BITFIELD rx_narrow_volatile_bitfield |
@@ -3956,13 +3902,6 @@ rx_asm_final_postscan_insn (FILE *, rtx_insn *insn, rtx operands[], int num_rtx) | ||
3956 | 3902 | #undef TARGET_HAVE_SPECULATION_SAFE_VALUE |
3957 | 3903 | #define TARGET_HAVE_SPECULATION_SAFE_VALUE speculation_safe_value_not_needed |
3958 | 3904 | |
3959 | -#undef TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA | |
3960 | -#define TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA rx_asm_output_addr_const_extra | |
3961 | - | |
3962 | -#undef TARGET_ASM_FINAL_POSTSCAN_INSN | |
3963 | -#define TARGET_ASM_FINAL_POSTSCAN_INSN rx_asm_final_postscan_insn | |
3964 | - | |
3965 | 3905 | struct gcc_target targetm = TARGET_INITIALIZER; |
3966 | 3906 | |
3967 | 3907 | #include "gt-rx.h" |
3968 | - |
@@ -650,7 +650,7 @@ typedef unsigned int CUMULATIVE_ARGS; | ||
650 | 650 | /* We can't directly access anything that contains a symbol, |
651 | 651 | nor can we indirect via the constant pool. */ |
652 | 652 | int rx_legitimate_pic_operand_p(rtx x); |
653 | -#define LEGITIMATE_PIC_OPERAND_P(X) \ | |
653 | +#define LEGITIMATE_PIC_OPERAND_P(X) \ | |
654 | 654 | rx_legitimate_pic_operand_p (X) |
655 | 655 | |
656 | 656 | #define SYMBOLIC_CONST_P(X) \ |
@@ -465,15 +465,26 @@ | ||
465 | 465 | (call (match_operand:QI 1 "general_operand") |
466 | 466 | (match_operand:SI 2 "general_operand")))] |
467 | 467 | "" |
468 | - { | |
469 | - rtx dest = XEXP (operands[1], 0); | |
468 | +{ | |
469 | + rtx dest = XEXP (operands[1], 0); | |
470 | 470 | |
471 | - if (! rx_call_operand (dest, Pmode)) | |
472 | - dest = force_reg (Pmode, dest); | |
473 | - emit_call_insn (gen_call_value_internal (operands[0], dest)); | |
474 | - DONE; | |
475 | - } | |
476 | -) | |
471 | + if (flag_pic && | |
472 | + (GET_CODE (dest) == SYMBOL_REF) && (!SYMBOL_REF_LOCAL_P (dest))) | |
473 | + { | |
474 | + if (flag_plt) | |
475 | + emit_call_insn (gen_call_value_internal_plt (operands[0], dest)); | |
476 | + else | |
477 | + emit_call_insn (gen_call_value_internal_got (operands[0], dest)); | |
478 | + DONE; | |
479 | + } | |
480 | + else | |
481 | + { | |
482 | + if (! rx_call_operand (dest, Pmode)) | |
483 | + dest = force_reg (Pmode, dest); | |
484 | + emit_call_insn (gen_call_value_internal (operands[0], dest)); | |
485 | + } | |
486 | + DONE; | |
487 | +}) | |
477 | 488 | |
478 | 489 | (define_insn "call_value_internal" |
479 | 490 | [(set (match_operand 0 "register_operand" "=r,r") |
@@ -2885,27 +2896,6 @@ | ||
2885 | 2896 | (set_attr "timings" "22")] |
2886 | 2897 | ) |
2887 | 2898 | |
2888 | -;; PIC stuff | |
2889 | - | |
2890 | -(define_expand "sym_label2reg" | |
2891 | - [(set (match_operand:SI 0 "" "") | |
2892 | - (const:SI (unspec:SI [(match_operand:SI 1 "" "") | |
2893 | - (const (plus:SI (match_operand:SI 2 "" "") | |
2894 | - (const_int 2)))] | |
2895 | - UNSPEC_SYMOFF)))] | |
2896 | - "" | |
2897 | - "") | |
2898 | - | |
2899 | -(define_expand "symPCREL_label2reg" | |
2900 | - [(set (match_operand:SI 0 "" "") | |
2901 | - (const:SI | |
2902 | - (unspec:SI | |
2903 | - [(const:SI (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PCREL)) | |
2904 | - (const:SI (plus:SI (match_operand:SI 2 "" "") | |
2905 | - (const_int 2)))] UNSPEC_PCREL_SYMOFF)))] | |
2906 | - "" | |
2907 | - "") | |
2908 | - | |
2909 | 2899 | (define_expand "sym2GOT" |
2910 | 2900 | [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOT))] |
2911 | 2901 | "" |
@@ -2920,38 +2910,19 @@ | ||
2920 | 2910 | DONE; |
2921 | 2911 | }) |
2922 | 2912 | |
2923 | -(define_expand "symGOTPLT2reg" | |
2924 | - [(match_operand 0 "" "") (match_operand 1 "" "")] | |
2925 | - "" | |
2926 | -{ | |
2927 | - rtx pltsym = gen_rtx_CONST (Pmode, | |
2928 | - gen_rtx_UNSPEC (Pmode, | |
2929 | - gen_rtvec (1, operands[1]), | |
2930 | - UNSPEC_GOTPLT)); | |
2931 | - DONE; | |
2932 | -}) | |
2933 | - | |
2934 | 2913 | (define_expand "sym2GOTOFF" |
2935 | 2914 | [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTOFF))] |
2936 | 2915 | "" |
2937 | 2916 | "") |
2938 | 2917 | |
2939 | -(define_insn "mov_from_rirb" | |
2940 | - [(match_operand 0 "" "") (match_operand 1 "" "")] | |
2941 | - "" | |
2942 | -{ | |
2943 | - return "mov.l\t[%0,%1],%0"; | |
2944 | -} | |
2945 | -) | |
2946 | - | |
2947 | 2918 | (define_expand "symGOTOFF2reg" |
2948 | 2919 | [(match_operand 0 "" "") (match_operand 1 "" "")] |
2949 | 2920 | "" |
2950 | 2921 | { |
2951 | 2922 | rtx gotoffsym; |
2952 | 2923 | rtx t = (!can_create_pseudo_p () |
2953 | - ? operands[0] | |
2954 | - : gen_reg_rtx (GET_MODE (operands[0]))); | |
2924 | + ? operands[0] | |
2925 | + : gen_reg_rtx (GET_MODE (operands[0]))); | |
2955 | 2926 | |
2956 | 2927 | rtx picreg = gen_rtx_REG (Pmode, PIC_REG); |
2957 | 2928 |
@@ -2963,38 +2934,51 @@ | ||
2963 | 2934 | DONE; |
2964 | 2935 | }) |
2965 | 2936 | |
2966 | -(define_expand "symPLT_label2reg" | |
2967 | - [(set (match_operand:SI 0 "" "") | |
2968 | - (const:SI | |
2969 | - (unspec:SI | |
2970 | - [(const:SI (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PLT)) | |
2971 | - (const:SI (plus:SI (match_operand:SI 2 "" "") | |
2972 | - (const_int 2)))] UNSPEC_PCREL_SYMOFF))) | |
2973 | - ;; Even though the PIC register is not really used by the call | |
2974 | - ;; sequence in which this is expanded, the PLT code assumes the PIC | |
2975 | - ;; register is set, so we must not skip its initialization. Since | |
2976 | - ;; we only use this expand as part of calling sequences, and never | |
2977 | - ;; to take the address of a function, this is the best point to | |
2978 | - ;; insert the (use). Using the PLT to take the address of a | |
2979 | - ;; function would be wrong, not only because the PLT entry could | |
2980 | - ;; then be called from a function that doesn't initialize the PIC | |
2981 | - ;; register to the proper GOT, but also because pointers to the | |
2982 | - ;; same function might not compare equal, should they be set by | |
2983 | - ;; different shared libraries. | |
2984 | - (use (reg:SI PIC_REG))] | |
2985 | - "" | |
2986 | - "") | |
2987 | - | |
2988 | -(define_expand "sym2PIC" | |
2989 | - [(const (unspec [(match_operand:SI 0 "" "")] UNSPEC_PIC))] | |
2937 | +(define_insn "mov_from_rirb" | |
2938 | + [(match_operand 0 "register_operand" "r") (match_operand 1 "register_operand" "r")] | |
2990 | 2939 | "" |
2991 | - "") | |
2940 | +{ | |
2941 | + return "mov.l\t[%0,%1],%0"; | |
2942 | +}) | |
2992 | 2943 | |
2993 | 2944 | (define_insn "loadGOT" |
2994 | 2945 | [(set (match_operand:SI 0 "register_operand" "=r") |
2995 | - (unspec:SI [(const_int 0)] UNSPEC_GOT))] | |
2946 | + (unspec:SI [(const_int 0)] UNSPEC_GOT))] | |
2996 | 2947 | "" |
2997 | 2948 | { |
2998 | 2949 | return "mvfc\tpc,%0\n\tadd\t#_GLOBAL_OFFSET_TABLE_,%0"; |
2999 | -} | |
2950 | +}) | |
2951 | + | |
2952 | +(define_expand "call_value_internal_got" | |
2953 | + [(set (match_operand 0 "register_operand" "=r,r") | |
2954 | + (call (mem:QI (match_operand:SI 1 "rx_call_operand" "r,CALL_OP_SYMBOL_REF")) | |
2955 | + (const_int 0))) | |
2956 | + (clobber (reg:CC CC_REG))] | |
2957 | + "" | |
2958 | +{ | |
2959 | + rtx gotoffsym; | |
2960 | + rtx t = (!can_create_pseudo_p () | |
2961 | + ? operands[0] | |
2962 | + : gen_reg_rtx (GET_MODE (operands[0]))); | |
2963 | + | |
2964 | + rtx picreg = gen_rtx_REG (Pmode, PIC_REG); | |
2965 | + | |
2966 | + gotoffsym = gen_sym2GOTOFF (operands[1]); | |
2967 | + emit_move_insn (t, gotoffsym); | |
2968 | + emit_move_insn (operands[0], t); | |
2969 | + emit_insn(gen_mov_from_rirb(operands[0], picreg)); | |
2970 | + emit_call_insn (gen_call_internal (operands[0])); | |
2971 | + DONE; | |
2972 | +}) | |
2973 | + | |
2974 | +(define_insn "call_value_internal_plt" | |
2975 | + [(set (match_operand 0 "register_operand" "=r") | |
2976 | + (call (mem:QI (match_operand:SI 1 "rx_symbolic_call_operand" "")) | |
2977 | + (const_int 0))) | |
2978 | + (use (reg:SI PIC_REG)) | |
2979 | + (clobber (reg:CC CC_REG))] | |
2980 | + "" | |
2981 | + "bsr\t%A1@PLT" | |
2982 | + [(set_attr "length" "4") | |
2983 | + (set_attr "timings" "33")] | |
3000 | 2984 | ) |