]>
Commit | Line | Data |
---|---|---|
d405059b | 1 | # DP: Some fixes for ARM from Philip Blundell |
2 | ||
3 | Tue Jul 27 18:42:12 1999 Bernd Schmidt <bernds@cygnus.co.uk> | |
4 | ||
5 | * reload1.c (reload_reg_free_for_value_p): RELOAD_OTHER reloads with | |
6 | an earlyclobbered output conflict with RELOAD_INPUT reloads. | |
7 | ||
8 | Tue Jul 27 18:42:12 1999 Bernd Schmidt <bernds@cygnus.co.uk> | |
9 | ||
10 | * reload1.c (reload_reg_free_for_value_p): If two reloads overlap in | |
11 | their lifetimes, and one of them has an output, they conflict. | |
12 | ||
13 | Fri Jul 16 10:29:48 1999 Philip Blundell <pb@nexus.co.uk> | |
14 | ||
15 | * config/arm/arm.c (legitimize_pic_address): Handle LABEL_REF | |
16 | correctly. | |
17 | (arm_poke_function_name): Avoid warning. | |
18 | * config/arm/arm.h (LEGITIMATE_CONSTANT_P): Allow anything when | |
19 | generating PIC. | |
20 | (GO_IF_LEGITIMATE_INDEX): Fix handling of HImode values. | |
21 | (LEGITIMATE_PIC_OPERAND): Disallow references to labels. | |
22 | * config/arm/linux-elf.h (MULTILIB_DEFAULTS): Define. | |
23 | (SUBTARGET_EXTRA_LINK_SPEC): Provide alternative definition for | |
24 | use with new binutils. | |
25 | * config/arm/linux-elf26.h (MULTILIB_DEFAULTS): Define. | |
26 | * config/arm/t-linux (EXTRA_MULTILIB_PARTS): Define. | |
27 | (MULTILIB_OPTIONS, MULTILIB_DIRNAMES): Multilib for hard/soft | |
28 | float by default. | |
29 | ||
30 | * function.c (rtx_equal_for_addressof_p): New function. | |
31 | (purge_addressof_1): Use it instead of rtx_equal_p. | |
32 | ||
33 | --- gcc/function.c 1999/05/20 22:26:35 1.90.4.1 | |
34 | +++ gcc/function.c 1999/07/16 09:30:04 | |
35 | @@ -3042,6 +3042,105 @@ | |
36 | extracted by usage MEM with narrower mode. */ | |
37 | static rtx purge_addressof_replacements; | |
38 | ||
39 | +/* Return 1 if X and Y are identical-looking rtx's. | |
40 | + This is the Lisp function EQUAL for rtx arguments. */ | |
41 | + | |
42 | +int | |
43 | +rtx_equal_for_addressof_p (x, y) | |
44 | + rtx x, y; | |
45 | +{ | |
46 | + register int i; | |
47 | + register int j; | |
48 | + register enum rtx_code code; | |
49 | + register char *fmt; | |
50 | + | |
51 | + if (x == y) | |
52 | + return 1; | |
53 | + if (x == 0 || y == 0) | |
54 | + return 0; | |
55 | + | |
56 | + code = GET_CODE (x); | |
57 | + /* Rtx's of different codes cannot be equal. */ | |
58 | + if (code != GET_CODE (y)) | |
59 | + return 0; | |
60 | + | |
61 | + /* (MULT:SI x y) and (MULT:HI x y) are NOT equivalent. | |
62 | + (REG:SI x) and (REG:HI x) are NOT equivalent. | |
63 | + But (MEM:SI x) and (MEM:HI x) are equivalent for our purposes. */ | |
64 | + | |
65 | + if (code != MEM && (GET_MODE (x) != GET_MODE (y))) | |
66 | + return 0; | |
67 | + | |
68 | + /* REG, LABEL_REF, and SYMBOL_REF can be compared nonrecursively. */ | |
69 | + | |
70 | + if (code == REG) | |
71 | + return REGNO (x) == REGNO (y); | |
72 | + else if (code == LABEL_REF) | |
73 | + return XEXP (x, 0) == XEXP (y, 0); | |
74 | + else if (code == SYMBOL_REF) | |
75 | + return XSTR (x, 0) == XSTR (y, 0); | |
76 | + else if (code == SCRATCH || code == CONST_DOUBLE) | |
77 | + return 0; | |
78 | + | |
79 | + /* Compare the elements. If any pair of corresponding elements | |
80 | + fail to match, return 0 for the whole things. */ | |
81 | + | |
82 | + fmt = GET_RTX_FORMAT (code); | |
83 | + for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--) | |
84 | + { | |
85 | + switch (fmt[i]) | |
86 | + { | |
87 | + case 'w': | |
88 | + if (XWINT (x, i) != XWINT (y, i)) | |
89 | + return 0; | |
90 | + break; | |
91 | + | |
92 | + case 'n': | |
93 | + case 'i': | |
94 | + if (XINT (x, i) != XINT (y, i)) | |
95 | + return 0; | |
96 | + break; | |
97 | + | |
98 | + case 'V': | |
99 | + case 'E': | |
100 | + /* Two vectors must have the same length. */ | |
101 | + if (XVECLEN (x, i) != XVECLEN (y, i)) | |
102 | + return 0; | |
103 | + | |
104 | + /* And the corresponding elements must match. */ | |
105 | + for (j = 0; j < XVECLEN (x, i); j++) | |
106 | + if (rtx_equal_p (XVECEXP (x, i, j), XVECEXP (y, i, j)) == 0) | |
107 | + return 0; | |
108 | + break; | |
109 | + | |
110 | + case 'e': | |
111 | + if (rtx_equal_p (XEXP (x, i), XEXP (y, i)) == 0) | |
112 | + return 0; | |
113 | + break; | |
114 | + | |
115 | + case 'S': | |
116 | + case 's': | |
117 | + if (strcmp (XSTR (x, i), XSTR (y, i))) | |
118 | + return 0; | |
119 | + break; | |
120 | + | |
121 | + case 'u': | |
122 | + /* These are just backpointers, so they don't matter. */ | |
123 | + break; | |
124 | + | |
125 | + case '0': | |
126 | + break; | |
127 | + | |
128 | + /* It is believed that rtx's at this level will never | |
129 | + contain anything but integers and other rtx's, | |
130 | + except for within LABEL_REFs and SYMBOL_REFs. */ | |
131 | + default: | |
132 | + abort (); | |
133 | + } | |
134 | + } | |
135 | + return 1; | |
136 | +} | |
137 | + | |
138 | /* Helper function for purge_addressof. See if the rtx expression at *LOC | |
139 | in INSN needs to be changed. If FORCE, always put any ADDRESSOFs into | |
140 | the stack. */ | |
141 | @@ -3122,7 +3221,7 @@ | |
142 | for (tem = purge_bitfield_addressof_replacements; | |
143 | tem != NULL_RTX; | |
144 | tem = XEXP (XEXP (tem, 1), 1)) | |
145 | - if (rtx_equal_p (x, XEXP (tem, 0))) | |
146 | + if (rtx_equal_for_addressof_p (x, XEXP (tem, 0))) | |
147 | { | |
148 | *loc = XEXP (XEXP (tem, 1), 0); | |
149 | return; | |
150 | @@ -3132,7 +3231,7 @@ | |
151 | for (tem = purge_addressof_replacements; | |
152 | tem != NULL_RTX; | |
153 | tem = XEXP (XEXP (tem, 1), 1)) | |
154 | - if (rtx_equal_p (XEXP (x, 0), XEXP (tem, 0))) | |
155 | + if (rtx_equal_for_addressof_p (XEXP (x, 0), XEXP (tem, 0))) | |
156 | { | |
157 | rtx z = XEXP (XEXP (tem, 1), 0); | |
158 | ||
159 | --- gcc/config/arm/arm.c 1999/06/19 06:34:36 1.43.4.5 | |
160 | +++ gcc/config/arm/arm.c 1999/07/16 09:27:53 | |
161 | @@ -1528,7 +1528,20 @@ legitimize_pic_address (orig, mode, reg) | |
162 | return gen_rtx_PLUS (Pmode, base, offset); | |
163 | } | |
164 | else if (GET_CODE (orig) == LABEL_REF) | |
165 | - current_function_uses_pic_offset_table = 1; | |
166 | + { | |
167 | + current_function_uses_pic_offset_table = 1; | |
168 | + | |
169 | + if (NEED_PLT_GOT) | |
170 | + { | |
171 | + rtx pic_ref, address = gen_reg_rtx (Pmode); | |
172 | + | |
173 | + emit_insn (gen_pic_load_addr (address, orig)); | |
174 | + pic_ref = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, | |
175 | + address); | |
176 | + emit_move_insn (address, pic_ref); | |
177 | + return address; | |
178 | + } | |
179 | + } | |
180 | ||
181 | return orig; | |
182 | } | |
183 | @@ -5445,7 +5458,7 @@ arm_poke_function_name (stream, name) | |
184 | rtx x; | |
185 | ||
186 | length = strlen (name); | |
187 | - alignlength = (length + 1) + 3 & ~3; | |
188 | + alignlength = ((length + 1) + 3) & ~3; | |
189 | ||
190 | ASM_OUTPUT_ASCII (stream, name, length + 1); | |
191 | ASM_OUTPUT_ALIGN (stream, 2); | |
192 | --- gcc/config/arm/arm.h 1999/06/19 05:37:07 1.34.4.3 | |
193 | +++ gcc/config/arm/arm.h 1999/07/16 09:28:04 | |
194 | @@ -1378,9 +1378,11 @@ do { \ | |
195 | ||
196 | On the ARM, allow any integer (invalid ones are removed later by insn | |
197 | patterns), nice doubles and symbol_refs which refer to the function's | |
198 | - constant pool XXX. */ | |
199 | -#define LEGITIMATE_CONSTANT_P(X) (! label_mentioned_p (X)) | |
200 | + constant pool XXX. | |
201 | ||
202 | + When generating PIC code, allow anything. */ | |
203 | +#define LEGITIMATE_CONSTANT_P(X) (flag_pic || ! label_mentioned_p (X)) | |
204 | + | |
205 | /* Symbols in the text segment can be accessed without indirecting via the | |
206 | constant pool; it may take an extra binary operation, but this is still | |
207 | faster than indirecting via memory. Don't do this when not optimizing, | |
208 | @@ -1495,9 +1497,8 @@ do \ | |
209 | && INTVAL (op) <= 31) \ | |
210 | goto LABEL; \ | |
211 | } \ | |
212 | - /* NASTY: Since this limits the addressing of unsigned byte loads */ \ | |
213 | range = ((MODE) == HImode || (MODE) == QImode) \ | |
214 | - ? (arm_arch4 ? 256 : 4095) : 4096; \ | |
215 | + ? (((MODE) == HImode && arm_arch4) ? 256 : 4095) : 4096; \ | |
216 | if (code == CONST_INT && INTVAL (INDEX) < range \ | |
217 | && INTVAL (INDEX) > -range) \ | |
218 | goto LABEL; \ | |
219 | @@ -1813,12 +1814,13 @@ extern int arm_pic_register; | |
220 | ||
221 | #define FINALIZE_PIC arm_finalize_pic () | |
222 | ||
223 | -/* We can't directly access anything that contains a symbol, | |
224 | +/* We can't directly access anything that contains a symbol or label, | |
225 | nor can we indirect via the constant pool. */ | |
226 | #define LEGITIMATE_PIC_OPERAND_P(X) \ | |
227 | - (! symbol_mentioned_p (X) \ | |
228 | + (! symbol_mentioned_p (X) && ! label_mentioned_p (X) \ | |
229 | && (! CONSTANT_POOL_ADDRESS_P (X) \ | |
230 | - || ! symbol_mentioned_p (get_pool_constant (X)))) | |
231 | + || (! symbol_mentioned_p (get_pool_constant (X))) \ | |
232 | + && (! label_mentioned_p (get_pool_constant (X))))) | |
233 | ||
234 | /* We need to know when we are making a constant pool; this determines | |
235 | whether data needs to be in the GOT or can be referenced via a GOT | |
236 | --- gcc/config/arm/arm.md 1999/06/02 06:43:14 1.27.4.2 | |
237 | +++ gcc/config/arm/arm.md 1999/07/16 09:28:31 | |
238 | @@ -2627,7 +2627,8 @@ | |
239 | : preserve_subexpressions_p ())); | |
240 | DONE; | |
241 | } | |
242 | - if (CONSTANT_P (operands[1]) && flag_pic) | |
243 | + if ((CONSTANT_P (operands[1]) || symbol_mentioned_p (operands[1]) | |
244 | + || label_mentioned_p (operands[1])) && flag_pic) | |
245 | operands[1] = legitimize_pic_address (operands[1], SImode, | |
246 | ((reload_in_progress | |
247 | || reload_completed) | |
248 | --- gcc/config/arm/linux-elf.h 1999/03/31 10:25:34 1.7 | |
249 | +++ gcc/config/arm/linux-elf.h 1999/07/16 09:28:33 | |
250 | @@ -28,10 +28,16 @@ Boston, MA 02111-1307, USA. */ | |
251 | /* Default is to use APCS-32 mode. */ | |
252 | #ifndef SUBTARGET_DEFAULT_APCS26 | |
253 | #define TARGET_DEFAULT (ARM_FLAG_APCS_32 | ARM_FLAG_SHORT_BYTE) | |
254 | +#if 1 | |
255 | #define SUBTARGET_EXTRA_LINK_SPEC \ | |
256 | + " %{mapcs-26:-m armelf_linux26} %{!mapcs-26:-m armelf_linux} -p" | |
257 | +#else | |
258 | +#define SUBTARGET_EXTRA_LINK_SPEC \ | |
259 | " %{mapcs-26:-m elf32arm26} %{!mapcs-26:-m elf32arm}" | |
260 | +#endif | |
261 | #define SUBTARGET_EXTRA_ASM_SPEC \ | |
262 | " %{mapcs-26:-mapcs-26} %(!mapcs-26:-mapcs-32}" | |
263 | +#define MULTILIB_DEFAULTS { "mlittle-endian", "mhard-float", "mapcs-32", "mno-thumb-interwork" } | |
264 | #endif | |
265 | ||
266 | /* This was defined in linux.h. Define it here also. */ | |
267 | --- gcc/config/arm/linux-elf26.h 1998/12/16 21:01:40 1.2 | |
268 | +++ gcc/config/arm/linux-elf26.h 1999/07/16 09:28:33 | |
269 | @@ -29,4 +29,6 @@ Boston, MA 02111-1307, USA. */ | |
270 | ||
271 | #define TARGET_DEFAULT (ARM_FLAG_SHORT_BYTE) | |
272 | ||
273 | +#define MULTILIB_DEFAULTS { "mlittle-endian", "mhard-float", "mapcs-26", "mno-thumb-interwork" } | |
274 | + | |
275 | #include "arm/linux-elf.h" | |
276 | --- gcc/config/arm/t-linux 1999/03/26 15:30:20 1.5 | |
277 | +++ gcc/config/arm/t-linux 1999/07/16 09:28:33 | |
278 | @@ -13,10 +13,15 @@ LIBGCC1 = libgcc1-asm.a | |
279 | LIB1ASMSRC = arm/lib1funcs.asm | |
280 | LIB1ASMFUNCS = _udivsi3 _divsi3 _umodsi3 _modsi3 _dvmd_lnx | |
281 | ||
282 | +MULTILIB_OPTIONS = mhard-float/msoft-float | |
283 | +MULTILIB_DIRNAMES = hard-float soft-float | |
284 | + | |
285 | # If you want to build both APCS variants as multilib options this is how | |
286 | # to do it. | |
287 | -#MULTILIB_OPTIONS = mapcs-32/apcs-26 | |
288 | -#MULTILIB_DIRNAMES = apcs-32 apcs-26 | |
289 | +#MULTILIB_OPTIONS += mapcs-32/mapcs-26 | |
290 | +#MULTILIB_DIRNAMES += apcs-32 apcs-26 | |
291 | + | |
292 | +EXTRA_MULTILIB_PARTS = crtbegin.o crtend.o | |
293 | ||
294 | LIBGCC = stmp-multilib | |
295 | INSTALL_LIBGCC = install-multilib | |
296 | --- gcc/jump.c 1999/05/31 13:30:06 1.59.4.2 | |
297 | +++ gcc/jump.c 1999/07/30 10:14:30 | |
298 | @@ -115,7 +115,7 @@ | |
299 | static rtx delete_unreferenced_labels PROTO((rtx)); | |
300 | static void delete_noop_moves PROTO((rtx)); | |
301 | static int calculate_can_reach_end PROTO((rtx, int, int)); | |
302 | -static int duplicate_loop_exit_test PROTO((rtx)); | |
303 | +static int duplicate_loop_exit_test PROTO((rtx, int)); | |
304 | static void find_cross_jump PROTO((rtx, rtx, int, rtx *, rtx *)); | |
305 | static void do_cross_jump PROTO((rtx, rtx, rtx)); | |
306 | static int jump_back_p PROTO((rtx, rtx)); | |
307 | @@ -338,7 +338,7 @@ | |
308 | && simplejump_p (temp1)) | |
309 | { | |
310 | temp = PREV_INSN (insn); | |
311 | - if (duplicate_loop_exit_test (insn)) | |
312 | + if (duplicate_loop_exit_test (insn, after_regscan)) | |
313 | { | |
314 | changed = 1; | |
315 | next = NEXT_INSN (temp); | |
316 | @@ -2544,8 +2544,9 @@ | |
317 | values of regno_first_uid and regno_last_uid. */ | |
318 | ||
319 | static int | |
320 | -duplicate_loop_exit_test (loop_start) | |
321 | +duplicate_loop_exit_test (loop_start, after_regscan) | |
322 | rtx loop_start; | |
323 | + int after_regscan; | |
324 | { | |
325 | rtx insn, set, reg, p, link; | |
326 | rtx copy = 0; | |
327 | @@ -2658,6 +2659,9 @@ | |
328 | reg_map[REGNO (reg)] = gen_reg_rtx (GET_MODE (reg)); | |
329 | } | |
330 | } | |
331 | + | |
332 | + if (after_regscan) | |
333 | + reg_scan_update (exitcode, lastexit, max_reg); | |
334 | ||
335 | /* Now copy each insn. */ | |
336 | for (insn = exitcode; insn != lastexit; insn = NEXT_INSN (insn)) | |
337 | --- gcc/reload1.c 1999/07/07 01:05:39 1.145.4.1 | |
338 | +++ gcc/reload1.c 1999/07/30 10:15:23 | |
339 | @@ -5281,7 +5281,7 @@ | |
340 | if (! reload_in[i] || ! rtx_equal_p (reload_in[i], value) | |
341 | || reload_out[i] || out) | |
342 | { | |
343 | - int time2; | |
344 | + int j, time2; | |
345 | switch (reload_when_needed[i]) | |
346 | { | |
347 | case RELOAD_FOR_OTHER_ADDRESS: | |
348 | @@ -5360,6 +5360,11 @@ | |
349 | if (! reload_in[i] || rtx_equal_p (reload_in[i], value)) | |
350 | { | |
351 | time2 = MAX_RECOG_OPERANDS * 4 + 4; | |
352 | + /* Earlyclobbered outputs must conflict with inputs. */ | |
353 | + for (j = 0; j < n_earlyclobbers; j++) | |
354 | + if (reload_out[i] == reload_earlyclobbers[j]) | |
355 | + time2 = MAX_RECOG_OPERANDS * 4 + 3; | |
356 | + | |
357 | break; | |
358 | } | |
359 | time2 = 1; | |
360 | @@ -5375,7 +5380,8 @@ | |
361 | } | |
362 | if ((time1 >= time2 | |
363 | && (! reload_in[i] || reload_out[i] | |
364 | - || ! rtx_equal_p (reload_in[i], value))) | |
365 | + || ! rtx_equal_p (reload_in[i], value) | |
366 | + || out)) | |
367 | || (out && reload_out_reg[reloadnum] | |
368 | && time2 >= MAX_RECOG_OPERANDS * 4 + 3)) | |
369 | return 0; | |
370 | ||
371 | ||
372 |