Revisión | cbe82eaffd526bfa36b0d199edbdc6a782fdace3 (tree) |
---|---|
Tiempo | 2022-11-22 15:38:28 |
Autor | Yoshinori Sato <yo-satoh@sios...> |
Commiter | Yoshinori Sato |
WIP: RX pic support
Signed-off-by: Yoshinori Sato <yo-satoh@sios.com>
@@ -226,6 +226,11 @@ | ||
226 | 226 | while (0) |
227 | 227 | |
228 | 228 | #undef PREFERRED_DEBUGGING_TYPE |
229 | +#undef PREFERRED_DEBUGGING_TYPE | |
230 | +#define PREFERRED_DEBUGGING_TYPE DWARF2_DEBUG | |
229 | 231 | |
230 | 232 | #undef TARGET_AS100_SYNTAX |
231 | 233 | #define TARGET_AS100_SYNTAX 0 |
234 | + | |
235 | +#define PIC_REGNUM 13 | |
236 | +#define GOT_SYMBOL_NAME "*_GLOBAL_OFFSET_TABLE_" |
@@ -171,4 +171,6 @@ rx_find_use_of_reg (rtx reg, rtx_insn* insn, F stepfunc) | ||
171 | 171 | |
172 | 172 | #endif |
173 | 173 | |
174 | +bool nonpic_symbol_mentioned_p (rtx x); | |
175 | + | |
174 | 176 | #endif /* GCC_RX_PROTOS_H */ |
@@ -143,11 +143,16 @@ 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 | + | |
146 | 149 | static rtx |
147 | -rx_legitimize_address (rtx x, | |
148 | - rtx oldx ATTRIBUTE_UNUSED, | |
150 | +rx_legitimize_address (rtx x, rtx oldx , | |
149 | 151 | machine_mode mode ATTRIBUTE_UNUSED) |
150 | 152 | { |
153 | + if (flag_pic) | |
154 | + return legitimize_pic_address (oldx, mode, NULL_RTX); | |
155 | + | |
151 | 156 | if (rx_pid_data_operand (x) == PID_UNENCODED) |
152 | 157 | { |
153 | 158 | rtx rv = gen_pid_addr (gen_rtx_REG (SImode, rx_pid_base_regnum ()), x); |
@@ -271,6 +276,71 @@ rx_is_legitimate_address (machine_mode mode, rtx x, | ||
271 | 276 | return rx_small_data_operand (x); |
272 | 277 | } |
273 | 278 | |
279 | +/* Return TRUE if X references a SYMBOL_REF or LABEL_REF whose symbol | |
280 | + isn't protected by a PIC unspec. */ | |
281 | +bool | |
282 | +nonpic_symbol_mentioned_p (rtx x) | |
283 | +{ | |
284 | + if (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == LABEL_REF | |
285 | + || GET_CODE (x) == PC) | |
286 | + return true; | |
287 | + | |
288 | + /* We don't want to look into the possible MEM location of a | |
289 | + CONST_DOUBLE, since we're not going to use it, in general. */ | |
290 | + if (GET_CODE (x) == CONST_DOUBLE) | |
291 | + return false; | |
292 | + | |
293 | + if (GET_CODE (x) == UNSPEC | |
294 | + && (XINT (x, 1) == UNSPEC_PIC | |
295 | + || XINT (x, 1) == UNSPEC_GOT | |
296 | + || XINT (x, 1) == UNSPEC_GOTOFF | |
297 | + || XINT (x, 1) == UNSPEC_GOTPLT | |
298 | + || XINT (x, 1) == UNSPEC_PLT | |
299 | + || XINT (x, 1) == UNSPEC_PCREL)) | |
300 | + return false; | |
301 | + | |
302 | + const char* fmt = GET_RTX_FORMAT (GET_CODE (x)); | |
303 | + for (int i = GET_RTX_LENGTH (GET_CODE (x)) - 1; i >= 0; i--) | |
304 | + { | |
305 | + if (fmt[i] == 'E') | |
306 | + { | |
307 | + for (int j = XVECLEN (x, i) - 1; j >= 0; j--) | |
308 | + if (nonpic_symbol_mentioned_p (XVECEXP (x, i, j))) | |
309 | + return true; | |
310 | + } | |
311 | + else if (fmt[i] == 'e' && nonpic_symbol_mentioned_p (XEXP (x, i))) | |
312 | + return true; | |
313 | + } | |
314 | + | |
315 | + return false; | |
316 | +} | |
317 | + | |
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 | + | |
274 | 344 | /* Returns TRUE for simple memory addresses, ie ones |
275 | 345 | that do not involve register indirect addressing |
276 | 346 | or pre/post increment/decrement. */ |
@@ -460,7 +530,20 @@ rx_print_operand_address (FILE * file, machine_mode /*mode*/, rtx addr) | ||
460 | 530 | break; |
461 | 531 | |
462 | 532 | case UNSPEC: |
463 | - addr = XVECEXP (addr, 0, 0); | |
533 | + { | |
534 | + int post = XINT (addr, 1); | |
535 | + addr = XVECEXP (addr, 0, 0); | |
536 | + switch (post) | |
537 | + { | |
538 | + case UNSPEC_GOTOFF: | |
539 | + fprintf (file, "#"); | |
540 | + output_addr_const (file, addr); | |
541 | + 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 | + return; | |
545 | + } | |
546 | + } | |
464 | 547 | /* Fall through. */ |
465 | 548 | case LABEL_REF: |
466 | 549 | case SYMBOL_REF: |
@@ -933,6 +1016,47 @@ rx_print_operand (FILE * file, rtx op, int letter) | ||
933 | 1016 | } |
934 | 1017 | } |
935 | 1018 | |
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 | + | |
936 | 1060 | /* Maybe convert an operand into its PID format. */ |
937 | 1061 | |
938 | 1062 | rtx |
@@ -968,6 +1092,7 @@ rx_gen_move_template (rtx * operands, bool is_movu) | ||
968 | 1092 | rtx dest = operands[0]; |
969 | 1093 | rtx src = operands[1]; |
970 | 1094 | |
1095 | + printf("%s\n", __func__); | |
971 | 1096 | /* Decide which extension, if any, should be given to the move instruction. */ |
972 | 1097 | switch (CONST_INT_P (src) ? GET_MODE (dest) : GET_MODE (src)) |
973 | 1098 | { |
@@ -1496,7 +1621,8 @@ rx_get_stack_layout (unsigned int * lowest, | ||
1496 | 1621 | they can be used in the fast interrupt handler without |
1497 | 1622 | saving them on the stack. */ |
1498 | 1623 | || (is_fast_interrupt_func (NULL_TREE) |
1499 | - && ! IN_RANGE (reg, 10, 13)))) | |
1624 | + && ! IN_RANGE (reg, 10, 13))) | |
1625 | + || (flag_pic && reg == PIC_REGNUM)) | |
1500 | 1626 | { |
1501 | 1627 | if (low == 0) |
1502 | 1628 | low = reg; |
@@ -1767,6 +1893,9 @@ rx_expand_prologue (void) | ||
1767 | 1893 | else if (low) |
1768 | 1894 | push_regs (high, low); |
1769 | 1895 | |
1896 | + // if (flag_pic && df_regs_ever_live_p (PIC_REGNUM)) | |
1897 | + // emit_insn (gen_GOTaddr2picreg (const0_rtx)); | |
1898 | + | |
1770 | 1899 | if (MUST_SAVE_ACC_REGISTER) |
1771 | 1900 | { |
1772 | 1901 | unsigned int acc_high, acc_low; |
@@ -1847,6 +1976,10 @@ rx_expand_prologue (void) | ||
1847 | 1976 | gen_safe_add (stack_pointer_rtx, frame_pointer_rtx, NULL_RTX, |
1848 | 1977 | false /* False because the epilogue will use the FP not the SP. */); |
1849 | 1978 | } |
1979 | + if (crtl->uses_pic_offset_table) | |
1980 | + { | |
1981 | + emit_insn (gen_loadGOT (gen_rtx_REG (SImode, PIC_REG))); | |
1982 | + } | |
1850 | 1983 | } |
1851 | 1984 | |
1852 | 1985 | static void |
@@ -2955,7 +3088,9 @@ rx_is_legitimate_constant (machine_mode mode ATTRIBUTE_UNUSED, rtx x) | ||
2955 | 3088 | return true; |
2956 | 3089 | |
2957 | 3090 | case UNSPEC: |
2958 | - return XINT (x, 1) == UNSPEC_CONST || XINT (x, 1) == UNSPEC_PID_ADDR; | |
3091 | + return XINT (x, 1) == UNSPEC_CONST || | |
3092 | + XINT (x, 1) == UNSPEC_PID_ADDR || | |
3093 | + XINT (x, 1) == UNSPEC_GOTOFF; | |
2959 | 3094 | |
2960 | 3095 | default: |
2961 | 3096 | /* FIXME: Can this ever happen ? */ |
@@ -3648,6 +3783,20 @@ rx_modes_tieable_p (machine_mode mode1, machine_mode mode2) | ||
3648 | 3783 | == (GET_MODE_CLASS (mode2) == MODE_FLOAT |
3649 | 3784 | || GET_MODE_CLASS (mode2) == MODE_COMPLEX_FLOAT)); |
3650 | 3785 | } |
3786 | + | |
3787 | +int rx_legitimate_pic_operand_p(rtx x) | |
3788 | +{ | |
3789 | + return ((! nonpic_symbol_mentioned_p (x) | |
3790 | + && (GET_CODE (x) != SYMBOL_REF | |
3791 | + || ! CONSTANT_POOL_ADDRESS_P (x) | |
3792 | + || ! nonpic_symbol_mentioned_p (get_pool_constant (x))))); | |
3793 | +} | |
3794 | + | |
3795 | +static void | |
3796 | +rx_asm_final_postscan_insn (FILE *, rtx_insn *insn, rtx operands[], int num_rtx) | |
3797 | +{ | |
3798 | + return; | |
3799 | +} | |
3651 | 3800 | |
3652 | 3801 | #undef TARGET_NARROW_VOLATILE_BITFIELD |
3653 | 3802 | #define TARGET_NARROW_VOLATILE_BITFIELD rx_narrow_volatile_bitfield |
@@ -3807,6 +3956,13 @@ rx_modes_tieable_p (machine_mode mode1, machine_mode mode2) | ||
3807 | 3956 | #undef TARGET_HAVE_SPECULATION_SAFE_VALUE |
3808 | 3957 | #define TARGET_HAVE_SPECULATION_SAFE_VALUE speculation_safe_value_not_needed |
3809 | 3958 | |
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 | + | |
3810 | 3965 | struct gcc_target targetm = TARGET_INITIALIZER; |
3811 | 3966 | |
3812 | 3967 | #include "gt-rx.h" |
3968 | + |
@@ -644,3 +644,15 @@ typedef unsigned int CUMULATIVE_ARGS; | ||
644 | 644 | (LENGTH) = rx_adjust_insn_length ((INSN), (LENGTH)); \ |
645 | 645 | } \ |
646 | 646 | while (0) |
647 | + | |
648 | +/* Position Independent Code. */ | |
649 | + | |
650 | +/* We can't directly access anything that contains a symbol, | |
651 | + nor can we indirect via the constant pool. */ | |
652 | +int rx_legitimate_pic_operand_p(rtx x); | |
653 | +#define LEGITIMATE_PIC_OPERAND_P(X) \ | |
654 | + rx_legitimate_pic_operand_p (X) | |
655 | + | |
656 | +#define SYMBOLIC_CONST_P(X) \ | |
657 | +((GET_CODE (X) == SYMBOL_REF || GET_CODE (X) == LABEL_REF) \ | |
658 | + && nonpic_symbol_mentioned_p (X)) |
@@ -76,6 +76,15 @@ | ||
76 | 76 | |
77 | 77 | (UNSPEC_PID_ADDR 52) |
78 | 78 | |
79 | + (UNSPEC_PIC 60) | |
80 | + (UNSPEC_GOT 61) | |
81 | + (UNSPEC_GOTOFF 62) | |
82 | + (UNSPEC_PLT 63) | |
83 | + (UNSPEC_GOTPLT 64) | |
84 | + (UNSPEC_PCREL 65) | |
85 | + (UNSPEC_SYMOFF 66) | |
86 | + (UNSPEC_PCREL_SYMOFF 67) | |
87 | + | |
79 | 88 | (CTRLREG_PSW 0) |
80 | 89 | (CTRLREG_PC 1) |
81 | 90 | (CTRLREG_USP 2) |
@@ -85,7 +94,9 @@ | ||
85 | 94 | (CTRLREG_ISP 10) |
86 | 95 | (CTRLREG_FINTV 11) |
87 | 96 | (CTRLREG_INTB 12) |
88 | - ] | |
97 | + | |
98 | + (PIC_REG 13) | |
99 | +] | |
89 | 100 | ) |
90 | 101 | |
91 | 102 | (define_attr "length" "" (const_int 8)) |
@@ -739,7 +750,7 @@ | ||
739 | 750 | (clobber (reg:CC CC_REG))])] |
740 | 751 | "" |
741 | 752 | { |
742 | - /* Make sure that we have an integer comparison... */ | |
753 | +/* Make sure that we have an integer comparison... */ | |
743 | 754 | if (GET_MODE (XEXP (operands[1], 0)) != CCmode |
744 | 755 | && GET_MODE (XEXP (operands[1], 0)) != SImode) |
745 | 756 | FAIL; |
@@ -2873,3 +2884,117 @@ | ||
2873 | 2884 | [(set_attr "length" "16") |
2874 | 2885 | (set_attr "timings" "22")] |
2875 | 2886 | ) |
2887 | + | |
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 | +(define_expand "sym2GOT" | |
2910 | + [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOT))] | |
2911 | + "" | |
2912 | + "") | |
2913 | + | |
2914 | +(define_expand "symGOT2reg" | |
2915 | + [(match_operand 0 "" "") (match_operand 1 "" "")] | |
2916 | + "" | |
2917 | +{ | |
2918 | + gen_sym2GOT (operands[1]); | |
2919 | + | |
2920 | + DONE; | |
2921 | +}) | |
2922 | + | |
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 | +(define_expand "sym2GOTOFF" | |
2935 | + [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTOFF))] | |
2936 | + "" | |
2937 | + "") | |
2938 | + | |
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 | +(define_expand "symGOTOFF2reg" | |
2948 | + [(match_operand 0 "" "") (match_operand 1 "" "")] | |
2949 | + "" | |
2950 | +{ | |
2951 | + rtx gotoffsym; | |
2952 | + rtx t = (!can_create_pseudo_p () | |
2953 | + ? operands[0] | |
2954 | + : gen_reg_rtx (GET_MODE (operands[0]))); | |
2955 | + | |
2956 | + rtx picreg = gen_rtx_REG (Pmode, PIC_REG); | |
2957 | + | |
2958 | + gotoffsym = gen_sym2GOTOFF (operands[1]); | |
2959 | + emit_move_insn (t, gotoffsym); | |
2960 | + emit_move_insn (operands[0], t); | |
2961 | + emit_insn(gen_mov_from_rirb(operands[0], picreg)); | |
2962 | +// set_unique_reg_note (insn, REG_EQUAL, operands[1]); | |
2963 | + DONE; | |
2964 | +}) | |
2965 | + | |
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))] | |
2990 | + "" | |
2991 | + "") | |
2992 | + | |
2993 | +(define_insn "loadGOT" | |
2994 | + [(set (match_operand:SI 0 "register_operand" "=r") | |
2995 | + (unspec:SI [(const_int 0)] UNSPEC_GOT))] | |
2996 | + "" | |
2997 | +{ | |
2998 | + return "mvfc\tpc,%0\n\tadd\t#_GLOBAL_OFFSET_TABLE_,%0"; | |
2999 | +} | |
3000 | +) |