diff options
Diffstat (limited to 'meta/packages/gcc/gcc-4.2.3/arm-crunch-cirrus-bugfixes.patch')
-rw-r--r-- | meta/packages/gcc/gcc-4.2.3/arm-crunch-cirrus-bugfixes.patch | 573 |
1 files changed, 0 insertions, 573 deletions
diff --git a/meta/packages/gcc/gcc-4.2.3/arm-crunch-cirrus-bugfixes.patch b/meta/packages/gcc/gcc-4.2.3/arm-crunch-cirrus-bugfixes.patch deleted file mode 100644 index cb0af8546d..0000000000 --- a/meta/packages/gcc/gcc-4.2.3/arm-crunch-cirrus-bugfixes.patch +++ /dev/null | |||
@@ -1,573 +0,0 @@ | |||
1 | diff -ruN /home/hwilliams/openembedded/build/tmp/work/ep9312-angstrom-linux-gnueabi/gcc-cross-4.1.2-r0/gcc-4.1.2/gcc/config/arm/arm.c gcc-4.1.2/gcc/config/arm/arm.c | ||
2 | --- /home/hwilliams/openembedded/build/tmp/work/ep9312-angstrom-linux-gnueabi/gcc-cross-4.1.2-r0/gcc-4.1.2/gcc/config/arm/arm.c 2007-05-09 16:32:29.000000000 +1000 | ||
3 | +++ gcc-4.1.2/gcc/config/arm/arm.c 2007-05-15 09:39:41.000000000 +1000 | ||
4 | @@ -4,6 +4,7 @@ | ||
5 | Contributed by Pieter `Tiggr' Schoenmakers (rcpieter@win.tue.nl) | ||
6 | and Martin Simmons (@harleqn.co.uk). | ||
7 | More major hacks by Richard Earnshaw (rearnsha@arm.com). | ||
8 | + Cirrus Crunch bugfixes by Vladimir Ivanov (vladit@nucleusys.com) | ||
9 | |||
10 | This file is part of GCC. | ||
11 | |||
12 | @@ -131,9 +132,17 @@ | ||
13 | static bool arm_xscale_rtx_costs (rtx, int, int, int *); | ||
14 | static bool arm_9e_rtx_costs (rtx, int, int, int *); | ||
15 | static int arm_address_cost (rtx); | ||
16 | -static bool arm_memory_load_p (rtx); | ||
17 | +// static bool arm_memory_load_p (rtx); | ||
18 | static bool arm_cirrus_insn_p (rtx); | ||
19 | -static void cirrus_reorg (rtx); | ||
20 | +// static void cirrus_reorg (rtx); | ||
21 | +static bool arm_mem_access_p (rtx); | ||
22 | +static bool cirrus_dest_regn_p (rtx, int); | ||
23 | +static rtx cirrus_prev_next_mach_insn (rtx, int *, int); | ||
24 | +static rtx cirrus_prev_mach_insn (rtx, int *); | ||
25 | +static rtx cirrus_next_mach_insn (rtx, int *); | ||
26 | +static void cirrus_reorg_branch (rtx); | ||
27 | +static void cirrus_reorg_bug1 (rtx); | ||
28 | +static void cirrus_reorg_bug10_12 (rtx); | ||
29 | static void arm_init_builtins (void); | ||
30 | static rtx arm_expand_builtin (tree, rtx, rtx, enum machine_mode, int); | ||
31 | static void arm_init_iwmmxt_builtins (void); | ||
32 | @@ -5399,41 +5412,6 @@ | ||
33 | || TREE_CODE (valtype) == COMPLEX_TYPE)); | ||
34 | } | ||
35 | |||
36 | -/* Returns TRUE if INSN is an "LDR REG, ADDR" instruction. | ||
37 | - Use by the Cirrus Maverick code which has to workaround | ||
38 | - a hardware bug triggered by such instructions. */ | ||
39 | -static bool | ||
40 | -arm_memory_load_p (rtx insn) | ||
41 | -{ | ||
42 | - rtx body, lhs, rhs;; | ||
43 | - | ||
44 | - if (insn == NULL_RTX || GET_CODE (insn) != INSN) | ||
45 | - return false; | ||
46 | - | ||
47 | - body = PATTERN (insn); | ||
48 | - | ||
49 | - if (GET_CODE (body) != SET) | ||
50 | - return false; | ||
51 | - | ||
52 | - lhs = XEXP (body, 0); | ||
53 | - rhs = XEXP (body, 1); | ||
54 | - | ||
55 | - lhs = REG_OR_SUBREG_RTX (lhs); | ||
56 | - | ||
57 | - /* If the destination is not a general purpose | ||
58 | - register we do not have to worry. */ | ||
59 | - if (GET_CODE (lhs) != REG | ||
60 | - || REGNO_REG_CLASS (REGNO (lhs)) != GENERAL_REGS) | ||
61 | - return false; | ||
62 | - | ||
63 | - /* As well as loads from memory we also have to react | ||
64 | - to loads of invalid constants which will be turned | ||
65 | - into loads from the minipool. */ | ||
66 | - return (GET_CODE (rhs) == MEM | ||
67 | - || GET_CODE (rhs) == SYMBOL_REF | ||
68 | - || note_invalid_constants (insn, -1, false)); | ||
69 | -} | ||
70 | - | ||
71 | /* Return TRUE if INSN is a Cirrus instruction. */ | ||
72 | static bool | ||
73 | arm_cirrus_insn_p (rtx insn) | ||
74 | @@ -5452,124 +5433,218 @@ | ||
75 | return attr != CIRRUS_NOT; | ||
76 | } | ||
77 | |||
78 | -/* Cirrus reorg for invalid instruction combinations. */ | ||
79 | -static void | ||
80 | -cirrus_reorg (rtx first) | ||
81 | +/* Return TRUE if ISN does memory access. */ | ||
82 | +static bool | ||
83 | +arm_mem_access_p (rtx insn) | ||
84 | { | ||
85 | - enum attr_cirrus attr; | ||
86 | - rtx body = PATTERN (first); | ||
87 | - rtx t; | ||
88 | - int nops; | ||
89 | + enum attr_type attr; | ||
90 | |||
91 | - /* Any branch must be followed by 2 non Cirrus instructions. */ | ||
92 | - if (GET_CODE (first) == JUMP_INSN && GET_CODE (body) != RETURN) | ||
93 | - { | ||
94 | - nops = 0; | ||
95 | - t = next_nonnote_insn (first); | ||
96 | + /* get_attr aborts on USE and CLOBBER. */ | ||
97 | + if (!insn | ||
98 | + || GET_CODE (insn) != INSN | ||
99 | + || GET_CODE (PATTERN (insn)) == USE | ||
100 | + || GET_CODE (PATTERN (insn)) == CLOBBER) | ||
101 | + return 0; | ||
102 | |||
103 | - if (arm_cirrus_insn_p (t)) | ||
104 | - ++ nops; | ||
105 | + attr = get_attr_type (insn); | ||
106 | |||
107 | - if (arm_cirrus_insn_p (next_nonnote_insn (t))) | ||
108 | - ++ nops; | ||
109 | + return attr == TYPE_LOAD_BYTE | ||
110 | + || attr == TYPE_LOAD1 || attr == TYPE_LOAD2 || attr == TYPE_LOAD3 || attr == TYPE_LOAD4 | ||
111 | + || attr == TYPE_F_CVT | ||
112 | + || attr == TYPE_F_MEM_R || attr == TYPE_R_MEM_F || attr == TYPE_F_2_R || attr == TYPE_R_2_F | ||
113 | + || attr == TYPE_F_LOAD || attr == TYPE_F_LOADS || attr == TYPE_F_LOADD | ||
114 | + || attr == TYPE_F_STORE || attr == TYPE_F_STORES || attr == TYPE_F_STORED | ||
115 | + || attr == TYPE_STORE1 || attr == TYPE_STORE2 || attr == TYPE_STORE3 || attr == TYPE_STORE4; | ||
116 | + | ||
117 | +} | ||
118 | |||
119 | - while (nops --) | ||
120 | - emit_insn_after (gen_nop (), first); | ||
121 | +/* Return TRUE if destination is certain Cirrus register. */ | ||
122 | +static bool | ||
123 | +cirrus_dest_regn_p (rtx body, int regn) | ||
124 | +{ | ||
125 | + rtx lhs; | ||
126 | + int reg; | ||
127 | + lhs = XEXP (body, 0); | ||
128 | + if (GET_CODE (lhs) != REG) | ||
129 | + return 0; | ||
130 | |||
131 | - return; | ||
132 | - } | ||
133 | + reg = REGNO (lhs); | ||
134 | + if (REGNO_REG_CLASS (reg) != CIRRUS_REGS) | ||
135 | + return 0; | ||
136 | |||
137 | - /* (float (blah)) is in parallel with a clobber. */ | ||
138 | - if (GET_CODE (body) == PARALLEL && XVECLEN (body, 0) > 0) | ||
139 | - body = XVECEXP (body, 0, 0); | ||
140 | + return reg == regn; | ||
141 | +} | ||
142 | + | ||
143 | +/* Get previous/next machine instruction during Cirrus workaround scans. | ||
144 | + Assume worst case (for the purpose of Cirrus workarounds) | ||
145 | + for JUMP / CALL instructions. */ | ||
146 | +static rtx | ||
147 | +cirrus_prev_next_mach_insn (rtx insn, int *len, int next) | ||
148 | +{ | ||
149 | + rtx t; | ||
150 | + int l = 0; | ||
151 | |||
152 | - if (GET_CODE (body) == SET) | ||
153 | + /* It seems that we can count only on INSN length. */ | ||
154 | + for ( ; ; ) | ||
155 | { | ||
156 | - rtx lhs = XEXP (body, 0), rhs = XEXP (body, 1); | ||
157 | + if (next) | ||
158 | + insn = NEXT_INSN (insn); | ||
159 | + else | ||
160 | + insn = PREV_INSN (insn); | ||
161 | + if (!insn) | ||
162 | + break; | ||
163 | |||
164 | - /* cfldrd, cfldr64, cfstrd, cfstr64 must | ||
165 | - be followed by a non Cirrus insn. */ | ||
166 | - if (get_attr_cirrus (first) == CIRRUS_DOUBLE) | ||
167 | - { | ||
168 | - if (arm_cirrus_insn_p (next_nonnote_insn (first))) | ||
169 | - emit_insn_after (gen_nop (), first); | ||
170 | + if (GET_CODE (insn) == INSN) | ||
171 | + { | ||
172 | + l = get_attr_length (insn) / 4; | ||
173 | + if (l) | ||
174 | + break; | ||
175 | + } | ||
176 | + else if (GET_CODE (insn) == JUMP_INSN) | ||
177 | + { | ||
178 | + l = 1; | ||
179 | + t = is_jump_table (insn); | ||
180 | + if (t) | ||
181 | + l += get_jump_table_size (t) / 4; | ||
182 | + break; | ||
183 | + } | ||
184 | + else if (GET_CODE (insn) == CALL_INSN) | ||
185 | + { | ||
186 | + l = 1; | ||
187 | + break; | ||
188 | + } | ||
189 | + } | ||
190 | |||
191 | - return; | ||
192 | - } | ||
193 | - else if (arm_memory_load_p (first)) | ||
194 | - { | ||
195 | - unsigned int arm_regno; | ||
196 | + if (len) | ||
197 | + *len = l; | ||
198 | |||
199 | - /* Any ldr/cfmvdlr, ldr/cfmvdhr, ldr/cfmvsr, ldr/cfmv64lr, | ||
200 | - ldr/cfmv64hr combination where the Rd field is the same | ||
201 | - in both instructions must be split with a non Cirrus | ||
202 | - insn. Example: | ||
203 | - | ||
204 | - ldr r0, blah | ||
205 | - nop | ||
206 | - cfmvsr mvf0, r0. */ | ||
207 | - | ||
208 | - /* Get Arm register number for ldr insn. */ | ||
209 | - if (GET_CODE (lhs) == REG) | ||
210 | - arm_regno = REGNO (lhs); | ||
211 | - else | ||
212 | - { | ||
213 | - gcc_assert (GET_CODE (rhs) == REG); | ||
214 | - arm_regno = REGNO (rhs); | ||
215 | - } | ||
216 | + return insn; | ||
217 | +} | ||
218 | |||
219 | - /* Next insn. */ | ||
220 | - first = next_nonnote_insn (first); | ||
221 | +static rtx | ||
222 | +cirrus_prev_mach_insn (rtx insn, int *len) | ||
223 | +{ | ||
224 | + return cirrus_prev_next_mach_insn (insn, len, 0); | ||
225 | +} | ||
226 | |||
227 | - if (! arm_cirrus_insn_p (first)) | ||
228 | - return; | ||
229 | +static rtx | ||
230 | +cirrus_next_mach_insn (rtx insn, int *len) | ||
231 | +{ | ||
232 | + return cirrus_prev_next_mach_insn (insn, len, 1); | ||
233 | +} | ||
234 | |||
235 | - body = PATTERN (first); | ||
236 | +/* Cirrus reorg for branch slots. */ | ||
237 | +static void | ||
238 | +cirrus_reorg_branch (rtx insn) | ||
239 | +{ | ||
240 | + rtx t; | ||
241 | + int nops, l; | ||
242 | |||
243 | - /* (float (blah)) is in parallel with a clobber. */ | ||
244 | - if (GET_CODE (body) == PARALLEL && XVECLEN (body, 0)) | ||
245 | - body = XVECEXP (body, 0, 0); | ||
246 | - | ||
247 | - if (GET_CODE (body) == FLOAT) | ||
248 | - body = XEXP (body, 0); | ||
249 | - | ||
250 | - if (get_attr_cirrus (first) == CIRRUS_MOVE | ||
251 | - && GET_CODE (XEXP (body, 1)) == REG | ||
252 | - && arm_regno == REGNO (XEXP (body, 1))) | ||
253 | - emit_insn_after (gen_nop (), first); | ||
254 | + /* TODO: handle jump-tables. */ | ||
255 | + t = is_jump_table (insn); | ||
256 | + if (t) | ||
257 | + return; | ||
258 | + | ||
259 | + /* Any branch must be followed by 2 non Cirrus instructions. */ | ||
260 | + t = insn; | ||
261 | + for (nops = 2; nops > 0; ) | ||
262 | + { | ||
263 | + if (!cirrus_next_mach_insn (t, 0)) | ||
264 | + { | ||
265 | + insn = t; | ||
266 | + break; | ||
267 | + } | ||
268 | + t = cirrus_next_mach_insn (t, &l); | ||
269 | + if (arm_cirrus_insn_p (t)) | ||
270 | + break; | ||
271 | + nops -= l; | ||
272 | |||
273 | - return; | ||
274 | - } | ||
275 | } | ||
276 | |||
277 | - /* get_attr cannot accept USE or CLOBBER. */ | ||
278 | - if (!first | ||
279 | - || GET_CODE (first) != INSN | ||
280 | - || GET_CODE (PATTERN (first)) == USE | ||
281 | - || GET_CODE (PATTERN (first)) == CLOBBER) | ||
282 | - return; | ||
283 | + while (nops-- > 0) | ||
284 | + emit_insn_after (gen_nop (), insn); /* WARNING: this appears to cause "bad immediate value for offset" errors in the assembler */ | ||
285 | +} | ||
286 | |||
287 | - attr = get_attr_cirrus (first); | ||
288 | +/* Cirrus reorg for bug #1 (cirrus + cfcmpxx). */ | ||
289 | +static void | ||
290 | +cirrus_reorg_bug1 (rtx insn) | ||
291 | +{ | ||
292 | + rtx body = PATTERN (insn), body2; | ||
293 | + rtx t; | ||
294 | + int i, nops, l; | ||
295 | + enum attr_cirrus attr; | ||
296 | |||
297 | - /* Any coprocessor compare instruction (cfcmps, cfcmpd, ...) | ||
298 | - must be followed by a non-coprocessor instruction. */ | ||
299 | - if (attr == CIRRUS_COMPARE) | ||
300 | + /* Check if destination or clobber is Cirrus register. */ | ||
301 | + if (GET_CODE (body) == PARALLEL) | ||
302 | { | ||
303 | - nops = 0; | ||
304 | - | ||
305 | - t = next_nonnote_insn (first); | ||
306 | + for (i = 0; i < XVECLEN (body, 0); i++) | ||
307 | + { | ||
308 | + body2 = XVECEXP (body, 0, i); | ||
309 | + if (GET_CODE (body2) == SET) | ||
310 | + { | ||
311 | + if (cirrus_dest_regn_p (body2, LAST_CIRRUS_FP_REGNUM)) | ||
312 | + { | ||
313 | + nops = 5; | ||
314 | + goto fix; | ||
315 | + } | ||
316 | + } | ||
317 | + else if (GET_CODE (body2) == CLOBBER) | ||
318 | + { | ||
319 | + if (cirrus_dest_regn_p (body2, LAST_CIRRUS_FP_REGNUM)) | ||
320 | + { | ||
321 | + nops = 4; | ||
322 | + goto fix; | ||
323 | + } | ||
324 | + } | ||
325 | + } | ||
326 | + } | ||
327 | + else if (GET_CODE (body) == SET) | ||
328 | + { | ||
329 | + if (cirrus_dest_regn_p (body, LAST_CIRRUS_FP_REGNUM)) | ||
330 | + { | ||
331 | + nops = 5; | ||
332 | + goto fix; | ||
333 | + } | ||
334 | + } | ||
335 | + return; | ||
336 | |||
337 | - if (arm_cirrus_insn_p (t)) | ||
338 | - ++ nops; | ||
339 | +fix: | ||
340 | + t = insn; | ||
341 | + for ( ; nops > 0; ) | ||
342 | + { | ||
343 | + t = cirrus_next_mach_insn (t, &l); | ||
344 | + if (!t) | ||
345 | + break; | ||
346 | + if (GET_CODE (t) == JUMP_INSN | ||
347 | + || GET_CODE (t) == CALL_INSN) | ||
348 | + { | ||
349 | + nops -= l; | ||
350 | + break; | ||
351 | + } | ||
352 | + else if (arm_cirrus_insn_p (t)) | ||
353 | + { | ||
354 | + attr = get_attr_cirrus (t); | ||
355 | + if (attr == CIRRUS_COMPARE) | ||
356 | + break; | ||
357 | + } | ||
358 | + nops -= l; | ||
359 | + } | ||
360 | |||
361 | - if (arm_cirrus_insn_p (next_nonnote_insn (t))) | ||
362 | - ++ nops; | ||
363 | + while (nops-- > 0) | ||
364 | + emit_insn_after (gen_nop (), insn); /* WARNING: this appears to cause "bad immediate value for offset" errors in the assembler */ | ||
365 | +} | ||
366 | |||
367 | - while (nops --) | ||
368 | - emit_insn_after (gen_nop (), first); | ||
369 | +/* Cirrus reorg for bugs #10 and #12 (data aborts). */ | ||
370 | +static void | ||
371 | +cirrus_reorg_bug10_12 (rtx insn) | ||
372 | +{ | ||
373 | + rtx t; | ||
374 | |||
375 | - return; | ||
376 | - } | ||
377 | + t = cirrus_next_mach_insn (insn, 0); | ||
378 | + if (arm_cirrus_insn_p (t)) | ||
379 | + if (TARGET_CIRRUS_D0 || | ||
380 | + get_attr_cirrus (t) == CIRRUS_DOUBLE) | ||
381 | + emit_insn_after (gen_nop (), insn); /* WARNING: this appears to cause "bad immediate value for offset" errors in the assembler */ | ||
382 | } | ||
383 | |||
384 | /* Return TRUE if X references a SYMBOL_REF. */ | ||
385 | @@ -7727,7 +7796,7 @@ | ||
386 | { | ||
387 | Mnode * mp; | ||
388 | Mnode * nmp; | ||
389 | - int align64 = 0; | ||
390 | + int align64 = 0, stuffnop = 0; | ||
391 | |||
392 | if (ARM_DOUBLEWORD_ALIGN) | ||
393 | for (mp = minipool_vector_head; mp != NULL; mp = mp->next) | ||
394 | @@ -7742,8 +7811,27 @@ | ||
395 | ";; Emitting minipool after insn %u; address %ld; align %d (bytes)\n", | ||
396 | INSN_UID (scan), (unsigned long) minipool_barrier->address, align64 ? 8 : 4); | ||
397 | |||
398 | + /* Check if branch before minipool is already stuffed with nops. */ | ||
399 | + if (TARGET_CIRRUS_D0 || TARGET_CIRRUS_D1) | ||
400 | + { | ||
401 | + rtx t; | ||
402 | + | ||
403 | + t = prev_active_insn (scan); | ||
404 | + if (GET_CODE (t) != INSN | ||
405 | + || PATTERN (t) != const0_rtx) | ||
406 | + stuffnop = 1; | ||
407 | + } | ||
408 | scan = emit_label_after (gen_label_rtx (), scan); | ||
409 | scan = emit_insn_after (align64 ? gen_align_8 () : gen_align_4 (), scan); | ||
410 | + /* Last instruction was branch, so put two non-Cirrus opcodes. */ | ||
411 | + if (stuffnop) | ||
412 | + { | ||
413 | +#if TARGET_CIRRUS /* This is doubling up on nops, so I don't think this is a good idea */ | ||
414 | + emit_insn_before (gen_nop (), scan); /* WARNING: this appears to cause "bad immediate value for offset" errors in the assembler */ | ||
415 | + emit_insn_before (gen_nop (), scan); /* WARNING: this appears to cause "bad immediate value for offset" errors in the assembler */ | ||
416 | +#endif | ||
417 | + } | ||
418 | + | ||
419 | scan = emit_label_after (minipool_vector_label, scan); | ||
420 | |||
421 | for (mp = minipool_vector_head; mp != NULL; mp = nmp) | ||
422 | @@ -8151,15 +8239,38 @@ | ||
423 | gcc_assert (GET_CODE (insn) == NOTE); | ||
424 | minipool_pad = 0; | ||
425 | |||
426 | +#if TARGET_CIRRUS /* I think this is a double-up */ | ||
427 | + /* Scan all the insn and fix Cirrus issues. */ | ||
428 | + if (TARGET_CIRRUS_D0 || TARGET_CIRRUS_D1) | ||
429 | + { | ||
430 | + rtx t, s; | ||
431 | + | ||
432 | + for (t = cirrus_next_mach_insn (insn, 0); t; t = cirrus_next_mach_insn (t, 0)) | ||
433 | + if (arm_mem_access_p (t)) | ||
434 | + cirrus_reorg_bug10_12 (t); | ||
435 | + | ||
436 | + if (TARGET_CIRRUS_D0) | ||
437 | + for (t = cirrus_next_mach_insn (insn, 0); t; t = cirrus_next_mach_insn (t, 0)) | ||
438 | + if (arm_cirrus_insn_p (t)) | ||
439 | + cirrus_reorg_bug1 (t); | ||
440 | + | ||
441 | + /* Find last insn. */ | ||
442 | + for (t = insn; ; t = s) | ||
443 | + { | ||
444 | + s = cirrus_next_mach_insn (t, 0); | ||
445 | + if (!s) | ||
446 | + break; | ||
447 | + } | ||
448 | + /* Scan backward and fix branches. - WARNING: appears to cause "bad immediate value for offset" problems! */ | ||
449 | + for ( ; t; t = cirrus_prev_mach_insn (t, 0)) | ||
450 | + if (GET_CODE (t) == JUMP_INSN | ||
451 | + || GET_CODE (t) == CALL_INSN) | ||
452 | + cirrus_reorg_branch (t); | ||
453 | + } | ||
454 | +#endif | ||
455 | /* Scan all the insns and record the operands that will need fixing. */ | ||
456 | for (insn = next_nonnote_insn (insn); insn; insn = next_nonnote_insn (insn)) | ||
457 | { | ||
458 | - if (TARGET_CIRRUS_FIX_INVALID_INSNS | ||
459 | - && (arm_cirrus_insn_p (insn) | ||
460 | - || GET_CODE (insn) == JUMP_INSN | ||
461 | - || arm_memory_load_p (insn))) | ||
462 | - cirrus_reorg (insn); | ||
463 | - | ||
464 | if (GET_CODE (insn) == BARRIER) | ||
465 | push_minipool_barrier (insn, address); | ||
466 | else if (INSN_P (insn)) | ||
467 | @@ -11755,16 +11910,10 @@ | ||
468 | || get_attr_conds (this_insn) != CONDS_NOCOND) | ||
469 | fail = TRUE; | ||
470 | |||
471 | - /* A conditional cirrus instruction must be followed by | ||
472 | - a non Cirrus instruction. However, since we | ||
473 | - conditionalize instructions in this function and by | ||
474 | - the time we get here we can't add instructions | ||
475 | - (nops), because shorten_branches() has already been | ||
476 | - called, we will disable conditionalizing Cirrus | ||
477 | - instructions to be safe. */ | ||
478 | - if (GET_CODE (scanbody) != USE | ||
479 | - && GET_CODE (scanbody) != CLOBBER | ||
480 | - && get_attr_cirrus (this_insn) != CIRRUS_NOT) | ||
481 | + /* To avoid erratic behaviour, we avoid conditional Cirrus | ||
482 | + instructions when doing workarounds. */ | ||
483 | + if (arm_cirrus_insn_p(this_insn) | ||
484 | + && (TARGET_CIRRUS_D0 || TARGET_CIRRUS_D1)) | ||
485 | fail = TRUE; | ||
486 | break; | ||
487 | |||
488 | diff -ruN /home/hwilliams/openembedded/build/tmp/work/ep9312-angstrom-linux-gnueabi/gcc-cross-4.1.2-r0/gcc-4.1.2/gcc/config/arm/arm.h gcc-4.1.2/gcc/config/arm/arm.h | ||
489 | --- /home/hwilliams/openembedded/build/tmp/work/ep9312-angstrom-linux-gnueabi/gcc-cross-4.1.2-r0/gcc-4.1.2/gcc/config/arm/arm.h 2005-11-05 01:02:51.000000000 +1000 | ||
490 | +++ gcc-4.1.2/gcc/config/arm/arm.h 2007-05-15 10:15:05.000000000 +1000 | ||
491 | @@ -5,6 +5,7 @@ | ||
492 | and Martin Simmons (@harleqn.co.uk). | ||
493 | More major hacks by Richard Earnshaw (rearnsha@arm.com) | ||
494 | Minor hacks by Nick Clifton (nickc@cygnus.com) | ||
495 | + Cirrus Crunch fixes by Vladimir Ivanov (vladitx@nucleusys.com) | ||
496 | |||
497 | This file is part of GCC. | ||
498 | |||
499 | @@ -140,7 +141,9 @@ | ||
500 | %{msoft-float:%{mhard-float: \ | ||
501 | %e-msoft-float and -mhard_float may not be used together}} \ | ||
502 | %{mbig-endian:%{mlittle-endian: \ | ||
503 | - %e-mbig-endian and -mlittle-endian may not be used together}}" | ||
504 | + %e-mbig-endian and -mlittle-endian may not be used together}} \ | ||
505 | +%{mfix-crunch-d0:%{mfix-crunch-d1: \ | ||
506 | + %e-mfix-crunch-d0 and -mfix-crunch-d1 may not be used together}}" | ||
507 | |||
508 | #ifndef CC1_SPEC | ||
509 | #define CC1_SPEC "" | ||
510 | @@ -179,6 +182,9 @@ | ||
511 | #define TARGET_HARD_FLOAT_ABI (arm_float_abi == ARM_FLOAT_ABI_HARD) | ||
512 | #define TARGET_FPA (arm_fp_model == ARM_FP_MODEL_FPA) | ||
513 | #define TARGET_MAVERICK (arm_fp_model == ARM_FP_MODEL_MAVERICK) | ||
514 | +#define TARGET_CIRRUS (arm_arch_cirrus) | ||
515 | +#define TARGET_CIRRUS_D0 0 /* (target_flags & ARM_FLAG_CIRRUS_D0) */ | ||
516 | +#define TARGET_CIRRUS_D1 1 /* (target_flags & ARM_FLAG_CIRRUS_D1) */ | ||
517 | #define TARGET_VFP (arm_fp_model == ARM_FP_MODEL_VFP) | ||
518 | #define TARGET_IWMMXT (arm_arch_iwmmxt) | ||
519 | #define TARGET_REALLY_IWMMXT (TARGET_IWMMXT && TARGET_ARM) | ||
520 | diff -ruN /home/hwilliams/openembedded/build/tmp/work/ep9312-angstrom-linux-gnueabi/gcc-cross-4.1.2-r0/gcc-4.1.2/gcc/config/arm/arm.opt gcc-4.1.2/gcc/config/arm/arm.opt | ||
521 | --- /home/hwilliams/openembedded/build/tmp/work/ep9312-angstrom-linux-gnueabi/gcc-cross-4.1.2-r0/gcc-4.1.2/gcc/config/arm/arm.opt 2005-11-05 01:02:51.000000000 +1000 | ||
522 | +++ gcc-4.1.2/gcc/config/arm/arm.opt 2007-05-15 10:09:31.000000000 +1000 | ||
523 | @@ -68,6 +68,14 @@ | ||
524 | Target Report Mask(CIRRUS_FIX_INVALID_INSNS) | ||
525 | Cirrus: Place NOPs to avoid invalid instruction combinations | ||
526 | |||
527 | +fix-crunch-d0 | ||
528 | +Target Report Mask(ARM_FLAG_CIRRUS_D0) | ||
529 | +Cirrus: workarounds for Crunch coprocessor revision D0 | ||
530 | + | ||
531 | +fix-crunch-d1 | ||
532 | +Target Report Mask(ARM_FLAG_CIRRUS_D1) | ||
533 | +Cirrus: workarounds for Crunch coprocessor revision D1 | ||
534 | + | ||
535 | mcpu= | ||
536 | Target RejectNegative Joined | ||
537 | Specify the name of the target CPU | ||
538 | diff -ruN /home/hwilliams/openembedded/build/tmp/work/ep9312-angstrom-linux-gnueabi/gcc-cross-4.1.2-r0/gcc-4.1.2/gcc/doc/invoke.texi gcc-4.1.2/gcc/doc/invoke.texi | ||
539 | --- /home/hwilliams/openembedded/build/tmp/work/ep9312-angstrom-linux-gnueabi/gcc-cross-4.1.2-r0/gcc-4.1.2/gcc/doc/invoke.texi 2006-09-26 07:21:58.000000000 +1000 | ||
540 | +++ gcc-4.1.2/gcc/doc/invoke.texi 2007-05-15 10:07:04.000000000 +1000 | ||
541 | @@ -408,7 +408,7 @@ | ||
542 | -msingle-pic-base -mno-single-pic-base @gol | ||
543 | -mpic-register=@var{reg} @gol | ||
544 | -mnop-fun-dllimport @gol | ||
545 | --mcirrus-fix-invalid-insns -mno-cirrus-fix-invalid-insns @gol | ||
546 | +-mfix-crunch-d0 -mfix-crunch-d1 @gol | ||
547 | -mpoke-function-name @gol | ||
548 | -mthumb -marm @gol | ||
549 | -mtpcs-frame -mtpcs-leaf-frame @gol | ||
550 | @@ -7435,17 +7435,12 @@ | ||
551 | Specify the register to be used for PIC addressing. The default is R10 | ||
552 | unless stack-checking is enabled, when R9 is used. | ||
553 | |||
554 | -@item -mcirrus-fix-invalid-insns | ||
555 | -@opindex mcirrus-fix-invalid-insns | ||
556 | -@opindex mno-cirrus-fix-invalid-insns | ||
557 | -Insert NOPs into the instruction stream to in order to work around | ||
558 | -problems with invalid Maverick instruction combinations. This option | ||
559 | -is only valid if the @option{-mcpu=ep9312} option has been used to | ||
560 | -enable generation of instructions for the Cirrus Maverick floating | ||
561 | -point co-processor. This option is not enabled by default, since the | ||
562 | -problem is only present in older Maverick implementations. The default | ||
563 | -can be re-enabled by use of the @option{-mno-cirrus-fix-invalid-insns} | ||
564 | -switch. | ||
565 | +@item -mfix-crunch-d0 | ||
566 | +@itemx -mfix-crunch-d1 | ||
567 | +@opindex mfix-crunch-d0 | ||
568 | +@opindex mfix-crunch-d1 | ||
569 | +Enable workarounds for the Cirrus MaverickCrunch coprocessor revisions | ||
570 | +D0 and D1 respectively. | ||
571 | |||
572 | @item -mpoke-function-name | ||
573 | @opindex mpoke-function-name | ||