• R/O
  • HTTP
  • SSH
  • HTTPS

Commit

Tags
No Tags

Frequently used words (click to add to your profile)

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

Commit MetaInfo

Revisióncbe82eaffd526bfa36b0d199edbdc6a782fdace3 (tree)
Tiempo2022-11-22 15:38:28
AutorYoshinori Sato <yo-satoh@sios...>
CommiterYoshinori Sato

Log Message

WIP: RX pic support

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

Cambiar Resumen

Diferencia incremental

--- a/gcc/config/rx/linux.h
+++ b/gcc/config/rx/linux.h
@@ -226,6 +226,11 @@
226226 while (0)
227227
228228 #undef PREFERRED_DEBUGGING_TYPE
229+#undef PREFERRED_DEBUGGING_TYPE
230+#define PREFERRED_DEBUGGING_TYPE DWARF2_DEBUG
229231
230232 #undef TARGET_AS100_SYNTAX
231233 #define TARGET_AS100_SYNTAX 0
234+
235+#define PIC_REGNUM 13
236+#define GOT_SYMBOL_NAME "*_GLOBAL_OFFSET_TABLE_"
--- a/gcc/config/rx/rx-protos.h
+++ b/gcc/config/rx/rx-protos.h
@@ -171,4 +171,6 @@ rx_find_use_of_reg (rtx reg, rtx_insn* insn, F stepfunc)
171171
172172 #endif
173173
174+bool nonpic_symbol_mentioned_p (rtx x);
175+
174176 #endif /* GCC_RX_PROTOS_H */
--- a/gcc/config/rx/rx.cc
+++ b/gcc/config/rx/rx.cc
@@ -143,11 +143,16 @@ rx_pid_data_operand (rtx op)
143143 return PID_NOT_PID;
144144 }
145145
146+rtx
147+legitimize_pic_address (rtx orig, machine_mode mode ATTRIBUTE_UNUSED, rtx reg);
148+
146149 static rtx
147-rx_legitimize_address (rtx x,
148- rtx oldx ATTRIBUTE_UNUSED,
150+rx_legitimize_address (rtx x, rtx oldx ,
149151 machine_mode mode ATTRIBUTE_UNUSED)
150152 {
153+ if (flag_pic)
154+ return legitimize_pic_address (oldx, mode, NULL_RTX);
155+
151156 if (rx_pid_data_operand (x) == PID_UNENCODED)
152157 {
153158 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,
271276 return rx_small_data_operand (x);
272277 }
273278
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+
274344 /* Returns TRUE for simple memory addresses, ie ones
275345 that do not involve register indirect addressing
276346 or pre/post increment/decrement. */
@@ -460,7 +530,20 @@ rx_print_operand_address (FILE * file, machine_mode /*mode*/, rtx addr)
460530 break;
461531
462532 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+ }
464547 /* Fall through. */
465548 case LABEL_REF:
466549 case SYMBOL_REF:
@@ -933,6 +1016,47 @@ rx_print_operand (FILE * file, rtx op, int letter)
9331016 }
9341017 }
9351018
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+
9361060 /* Maybe convert an operand into its PID format. */
9371061
9381062 rtx
@@ -968,6 +1092,7 @@ rx_gen_move_template (rtx * operands, bool is_movu)
9681092 rtx dest = operands[0];
9691093 rtx src = operands[1];
9701094
1095+ printf("%s\n", __func__);
9711096 /* Decide which extension, if any, should be given to the move instruction. */
9721097 switch (CONST_INT_P (src) ? GET_MODE (dest) : GET_MODE (src))
9731098 {
@@ -1496,7 +1621,8 @@ rx_get_stack_layout (unsigned int * lowest,
14961621 they can be used in the fast interrupt handler without
14971622 saving them on the stack. */
14981623 || (is_fast_interrupt_func (NULL_TREE)
1499- && ! IN_RANGE (reg, 10, 13))))
1624+ && ! IN_RANGE (reg, 10, 13)))
1625+ || (flag_pic && reg == PIC_REGNUM))
15001626 {
15011627 if (low == 0)
15021628 low = reg;
@@ -1767,6 +1893,9 @@ rx_expand_prologue (void)
17671893 else if (low)
17681894 push_regs (high, low);
17691895
1896+ // if (flag_pic && df_regs_ever_live_p (PIC_REGNUM))
1897+ // emit_insn (gen_GOTaddr2picreg (const0_rtx));
1898+
17701899 if (MUST_SAVE_ACC_REGISTER)
17711900 {
17721901 unsigned int acc_high, acc_low;
@@ -1847,6 +1976,10 @@ rx_expand_prologue (void)
18471976 gen_safe_add (stack_pointer_rtx, frame_pointer_rtx, NULL_RTX,
18481977 false /* False because the epilogue will use the FP not the SP. */);
18491978 }
1979+ if (crtl->uses_pic_offset_table)
1980+ {
1981+ emit_insn (gen_loadGOT (gen_rtx_REG (SImode, PIC_REG)));
1982+ }
18501983 }
18511984
18521985 static void
@@ -2955,7 +3088,9 @@ rx_is_legitimate_constant (machine_mode mode ATTRIBUTE_UNUSED, rtx x)
29553088 return true;
29563089
29573090 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;
29593094
29603095 default:
29613096 /* FIXME: Can this ever happen ? */
@@ -3648,6 +3783,20 @@ rx_modes_tieable_p (machine_mode mode1, machine_mode mode2)
36483783 == (GET_MODE_CLASS (mode2) == MODE_FLOAT
36493784 || GET_MODE_CLASS (mode2) == MODE_COMPLEX_FLOAT));
36503785 }
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+}
36513800
36523801 #undef TARGET_NARROW_VOLATILE_BITFIELD
36533802 #define TARGET_NARROW_VOLATILE_BITFIELD rx_narrow_volatile_bitfield
@@ -3807,6 +3956,13 @@ rx_modes_tieable_p (machine_mode mode1, machine_mode mode2)
38073956 #undef TARGET_HAVE_SPECULATION_SAFE_VALUE
38083957 #define TARGET_HAVE_SPECULATION_SAFE_VALUE speculation_safe_value_not_needed
38093958
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+
38103965 struct gcc_target targetm = TARGET_INITIALIZER;
38113966
38123967 #include "gt-rx.h"
3968+
--- a/gcc/config/rx/rx.h
+++ b/gcc/config/rx/rx.h
@@ -644,3 +644,15 @@ typedef unsigned int CUMULATIVE_ARGS;
644644 (LENGTH) = rx_adjust_insn_length ((INSN), (LENGTH)); \
645645 } \
646646 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))
--- a/gcc/config/rx/rx.md
+++ b/gcc/config/rx/rx.md
@@ -76,6 +76,15 @@
7676
7777 (UNSPEC_PID_ADDR 52)
7878
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+
7988 (CTRLREG_PSW 0)
8089 (CTRLREG_PC 1)
8190 (CTRLREG_USP 2)
@@ -85,7 +94,9 @@
8594 (CTRLREG_ISP 10)
8695 (CTRLREG_FINTV 11)
8796 (CTRLREG_INTB 12)
88- ]
97+
98+ (PIC_REG 13)
99+]
89100 )
90101
91102 (define_attr "length" "" (const_int 8))
@@ -739,7 +750,7 @@
739750 (clobber (reg:CC CC_REG))])]
740751 ""
741752 {
742- /* Make sure that we have an integer comparison... */
753+/* Make sure that we have an integer comparison... */
743754 if (GET_MODE (XEXP (operands[1], 0)) != CCmode
744755 && GET_MODE (XEXP (operands[1], 0)) != SImode)
745756 FAIL;
@@ -2873,3 +2884,117 @@
28732884 [(set_attr "length" "16")
28742885 (set_attr "timings" "22")]
28752886 )
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+)