1 Index: gcc/config/arm/arm-protos.h
2 ===================================================================
3 RCS file: /cvsroot/gcc/gcc/gcc/config/arm/arm-protos.h,v
4 retrieving revision 1.60.4.20
5 diff -u -r1.60.4.20 arm-protos.h
6 --- gcc/config/arm/arm-protos.h 29 Mar 2005 03:00:11 -0000 1.60.4.20
7 +++ gcc/config/arm/arm-protos.h 23 Apr 2005 04:41:06 -0000
9 extern enum reg_class vfp_secondary_reload_class (enum machine_mode, rtx);
10 extern int tls_symbolic_operand (rtx, enum machine_mode);
11 extern bool arm_tls_operand_p (rtx x);
12 +extern bool arm_pc_pic_operand_p (rtx x);
15 extern int s_register_operand (rtx, enum machine_mode);
16 Index: gcc/config/arm/arm.c
17 ===================================================================
18 RCS file: /cvsroot/gcc/gcc/gcc/config/arm/arm.c,v
19 retrieving revision 1.303.2.79
20 diff -u -r1.303.2.79 arm.c
21 --- gcc/config/arm/arm.c 12 Apr 2005 06:17:07 -0000 1.303.2.79
22 +++ gcc/config/arm/arm.c 23 Apr 2005 04:41:09 -0000
25 /* If stack checking is disabled, we can use r10 as the PIC register,
26 which keeps r9 available. */
29 arm_pic_register = TARGET_APCS_STACK ? 9 : 10;
31 if (TARGET_APCS_FLOAT)
32 @@ -3120,6 +3120,10 @@
34 legitimize_pic_address (rtx orig, enum machine_mode mode, rtx reg)
36 + if (GET_CODE (orig) == UNSPEC
37 + && XINT (orig, 1) == UNSPEC_GOTSLOTPC)
40 if (GET_CODE (orig) == SYMBOL_REF
41 || GET_CODE (orig) == LABEL_REF)
43 @@ -3149,27 +3153,80 @@
48 - emit_insn (gen_pic_load_addr_arm (address, orig));
50 - emit_insn (gen_pic_load_addr_thumb (address, orig));
51 + if (arm_pic_register != INVALID_REGNUM)
53 + /* Using GP-based PIC addressing. */
55 + emit_insn (gen_pic_load_addr_arm (address, orig));
57 + emit_insn (gen_pic_load_addr_thumb (address, orig));
59 + if ((GET_CODE (orig) == LABEL_REF
60 + || (GET_CODE (orig) == SYMBOL_REF &&
61 + SYMBOL_REF_LOCAL_P (orig)))
63 + pic_ref = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, address);
66 + pic_ref = gen_rtx_MEM (Pmode,
67 + gen_rtx_PLUS (Pmode, pic_offset_table_rtx,
69 + RTX_UNCHANGING_P (pic_ref) = 1;
72 - if ((GET_CODE (orig) == LABEL_REF
73 - || (GET_CODE (orig) == SYMBOL_REF &&
74 - SYMBOL_REF_LOCAL_P (orig)))
76 - pic_ref = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, address);
77 + current_function_uses_pic_offset_table = 1;
81 - pic_ref = gen_rtx_MEM (Pmode,
82 - gen_rtx_PLUS (Pmode, pic_offset_table_rtx,
84 - RTX_UNCHANGING_P (pic_ref) = 1;
85 + /* Using PC-based PIC addressing. */
89 + label = gen_label_rtx ();
90 + offset = TARGET_ARM ? 8 : 4;
92 + if (GET_CODE (orig) == LABEL_REF
93 + || (GET_CODE (orig) == SYMBOL_REF && SYMBOL_REF_LOCAL_P (orig)))
95 + /* This symbol is defined locally. We don't need a GOT entry. */
96 + tmp = gen_rtx_MINUS (Pmode, gen_rtx_UNSPEC (Pmode, gen_rtvec (1, orig), UNSPEC_PIC_SYM), gen_rtx_PLUS (Pmode,
97 + gen_rtx_LABEL_REF (Pmode, label),
100 + load_tls_operand (tmp, address);
103 + emit_insn (gen_pic_add_dot_plus_eight (address, label));
105 + emit_insn (gen_pic_add_dot_plus_four (address, label));
109 + rtx x = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, orig), UNSPEC_GOTSLOTPC);
112 + dummy_label = gen_label_rtx ();
113 + LABEL_PRESERVE_P (dummy_label) = 1;
114 + LABEL_NUSES (dummy_label) = 1;
116 + tmp = gen_rtx_MINUS (Pmode, x, gen_rtx_PLUS (Pmode,
117 + gen_rtx_LABEL_REF (Pmode, label),
118 + GEN_INT (offset)));
120 + load_tls_operand (tmp, address);
123 + emit_insn (gen_tls_load_dot_plus_eight (address, address, label, dummy_label));
125 + emit_insn (gen_tls_load_dot_plus_four (address, address, label, dummy_label));
131 insn = emit_move_insn (reg, pic_ref);
133 - current_function_uses_pic_offset_table = 1;
135 /* Put a REG_EQUAL note on this insn, so that it can be optimized
137 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, orig,
138 @@ -3179,11 +3236,17 @@
139 else if (GET_CODE (orig) == CONST)
142 + bool minus = FALSE;
144 if (GET_CODE (XEXP (orig, 0)) == PLUS
145 && XEXP (XEXP (orig, 0), 0) == pic_offset_table_rtx)
148 + if (GET_CODE (XEXP (orig, 0)) == MINUS
149 + && GET_CODE (XEXP (XEXP (orig, 0), 0)) == UNSPEC
150 + && XINT (XEXP (XEXP (orig, 0), 0), 1) == UNSPEC_GOTSLOTPC)
153 if (GET_CODE (XEXP (orig, 0)) == UNSPEC)
156 @@ -3201,6 +3264,13 @@
157 offset = legitimize_pic_address (XEXP (XEXP (orig, 0), 1), Pmode,
158 base == reg ? 0 : reg);
160 + else if (GET_CODE (XEXP (orig, 0)) == MINUS)
163 + base = legitimize_pic_address (XEXP (XEXP (orig, 0), 0), Pmode, reg);
164 + offset = legitimize_pic_address (XEXP (XEXP (orig, 0), 1), Pmode,
165 + base == reg ? 0 : reg);
170 @@ -3228,7 +3298,7 @@
174 - return gen_rtx_PLUS (Pmode, base, offset);
175 + return minus ? gen_rtx_MINUS (Pmode, base, offset) : gen_rtx_PLUS (Pmode, base, offset);
179 @@ -3267,7 +3337,7 @@
180 rtx l1, pic_tmp, pic_tmp2, pic_rtx;
181 rtx global_offset_table;
183 - if (current_function_uses_pic_offset_table == 0 || TARGET_SINGLE_PIC_BASE)
184 + if (current_function_uses_pic_offset_table == 0 || TARGET_SINGLE_PIC_BASE || arm_pic_register == INVALID_REGNUM)
188 @@ -3341,8 +3411,11 @@
190 pcrel_constant_p (rtx x)
192 + if (GET_CODE (x) == CONST)
193 + return pcrel_constant_p (XEXP (x, 0));
195 if (GET_CODE (x) == MINUS)
196 - return symbol_mentioned_p (XEXP (x, 0)) && label_mentioned_p (XEXP (x, 1));
197 + return (((GET_CODE (XEXP (x, 0)) == UNSPEC && XINT (XEXP (x, 0), 1) == UNSPEC_PIC_SYM)) || symbol_mentioned_p (XEXP (x, 0))) && label_mentioned_p (XEXP (x, 1));
199 if (GET_CODE (x) == UNSPEC
200 && XINT (x, 1) == UNSPEC_TLS
201 @@ -3946,12 +4019,32 @@
202 return SYMBOL_REF_TLS_MODEL (op);
206 +arm_pc_pic_operand_p (rtx op)
208 + if (GET_CODE (op) == CONST
209 + && GET_CODE (XEXP (op, 0)) == MINUS
210 + && GET_CODE (XEXP (XEXP (op, 0), 0)) == UNSPEC
211 + && XINT (XEXP (XEXP (op, 0), 0), 1) == UNSPEC_GOTSLOTPC)
214 + if (GET_CODE (op) == CONST
215 + && GET_CODE (XEXP (op, 0)) == MINUS
216 + && GET_CODE (XEXP (XEXP (op, 0), 0)) == UNSPEC
217 + && XINT (XEXP (XEXP (op, 0), 0), 1) == UNSPEC_PIC_SYM)
223 /* Valid input to a move instruction. */
225 move_input_operand (rtx op, enum machine_mode mode)
227 if (tls_symbolic_operand (op, mode))
229 + if (pcrel_constant_p (op))
231 return general_operand (op, mode);
234 @@ -15634,11 +15727,34 @@
239 +arm_emit_got_decoration (FILE *fp, rtx x)
243 + val = XVECEXP (x, 0, 0);
245 + fputs ("_gotslotpc_(", fp);
247 + output_addr_const (fp, val);
255 arm_output_addr_const_extra (FILE *fp, rtx x)
257 if (GET_CODE (x) == UNSPEC && XINT (x, 1) == UNSPEC_TLS)
258 return arm_emit_tls_decoration (fp, x);
259 + else if (GET_CODE (x) == UNSPEC && XINT (x, 1) == UNSPEC_GOTSLOTPC)
260 + return arm_emit_got_decoration (fp, x);
261 + else if (GET_CODE (x) == UNSPEC && XINT (x, 1) == UNSPEC_PIC_SYM)
263 + output_addr_const (fp, XVECEXP (x, 0, 0));
266 else if (GET_CODE (x) == CONST_VECTOR)
267 return arm_emit_vector_const (fp, x);
269 Index: gcc/config/arm/arm.md
270 ===================================================================
271 RCS file: /cvsroot/gcc/gcc/gcc/config/arm/arm.md,v
272 retrieving revision 1.145.2.31
273 diff -u -r1.145.2.31 arm.md
274 --- gcc/config/arm/arm.md 28 Mar 2005 19:04:37 -0000 1.145.2.31
275 +++ gcc/config/arm/arm.md 23 Apr 2005 04:41:11 -0000
277 (UNSPEC_WMADDS 18) ; Used by the intrinsic form of the iWMMXt WMADDS instruction.
278 (UNSPEC_WMADDU 19) ; Used by the intrinsic form of the iWMMXt WMADDU instruction.
279 (UNSPEC_TLS 20) ; A symbol that has been treated properly for TLS usage.
280 + (UNSPEC_GOTSLOTPC 21)
284 @@ -4179,7 +4180,8 @@
285 && (CONSTANT_P (operands[1])
286 || symbol_mentioned_p (operands[1])
287 || label_mentioned_p (operands[1]))
288 - && ! tls_mentioned_p (operands[1]))
289 + && ! tls_mentioned_p (operands[1])
290 + && ! arm_pc_pic_operand_p (operands[1]))
291 operands[1] = legitimize_pic_address (operands[1], SImode,
292 (no_new_pseudos ? operands[0] : 0));
294 @@ -4412,7 +4414,8 @@
295 (mem:SI (unspec:SI [(plus:SI (match_dup 0)
296 (const (plus:SI (pc) (const_int 8))))]
298 - (use (label_ref (match_operand 1 "" "")))])]
299 + (use (label_ref (match_operand 1 "" "")))
300 + (use (label_ref (match_operand 1 "" "")))])]