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
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)
10 This file is part of GCC.
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));
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. */
40 -arm_memory_load_p (rtx insn)
42 - rtx body, lhs, rhs;;
44 - if (insn == NULL_RTX || GET_CODE (insn) != INSN)
47 - body = PATTERN (insn);
49 - if (GET_CODE (body) != SET)
52 - lhs = XEXP (body, 0);
53 - rhs = XEXP (body, 1);
55 - lhs = REG_OR_SUBREG_RTX (lhs);
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)
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));
71 /* Return TRUE if INSN is a Cirrus instruction. */
73 arm_cirrus_insn_p (rtx insn)
74 @@ -5452,124 +5433,218 @@
75 return attr != CIRRUS_NOT;
78 -/* Cirrus reorg for invalid instruction combinations. */
80 -cirrus_reorg (rtx first)
81 +/* Return TRUE if ISN does memory access. */
83 +arm_mem_access_p (rtx insn)
85 - enum attr_cirrus attr;
86 - rtx body = PATTERN (first);
89 + enum attr_type attr;
91 - /* Any branch must be followed by 2 non Cirrus instructions. */
92 - if (GET_CODE (first) == JUMP_INSN && GET_CODE (body) != RETURN)
95 - t = next_nonnote_insn (first);
96 + /* get_attr aborts on USE and CLOBBER. */
98 + || GET_CODE (insn) != INSN
99 + || GET_CODE (PATTERN (insn)) == USE
100 + || GET_CODE (PATTERN (insn)) == CLOBBER)
103 - if (arm_cirrus_insn_p (t))
105 + attr = get_attr_type (insn);
107 - if (arm_cirrus_insn_p (next_nonnote_insn (t)))
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;
120 - emit_insn_after (gen_nop (), first);
121 +/* Return TRUE if destination is certain Cirrus register. */
123 +cirrus_dest_regn_p (rtx body, int regn)
127 + lhs = XEXP (body, 0);
128 + if (GET_CODE (lhs) != REG)
134 + if (REGNO_REG_CLASS (reg) != CIRRUS_REGS)
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;
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. */
147 +cirrus_prev_next_mach_insn (rtx insn, int *len, int next)
152 - if (GET_CODE (body) == SET)
153 + /* It seems that we can count only on INSN length. */
156 - rtx lhs = XEXP (body, 0), rhs = XEXP (body, 1);
158 + insn = NEXT_INSN (insn);
160 + insn = PREV_INSN (insn);
164 - /* cfldrd, cfldr64, cfstrd, cfstr64 must
165 - be followed by a non Cirrus insn. */
166 - if (get_attr_cirrus (first) == CIRRUS_DOUBLE)
168 - if (arm_cirrus_insn_p (next_nonnote_insn (first)))
169 - emit_insn_after (gen_nop (), first);
170 + if (GET_CODE (insn) == INSN)
172 + l = get_attr_length (insn) / 4;
176 + else if (GET_CODE (insn) == JUMP_INSN)
179 + t = is_jump_table (insn);
181 + l += get_jump_table_size (t) / 4;
184 + else if (GET_CODE (insn) == CALL_INSN)
193 - else if (arm_memory_load_p (first))
195 - unsigned int arm_regno;
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
206 - cfmvsr mvf0, r0. */
208 - /* Get Arm register number for ldr insn. */
209 - if (GET_CODE (lhs) == REG)
210 - arm_regno = REGNO (lhs);
213 - gcc_assert (GET_CODE (rhs) == REG);
214 - arm_regno = REGNO (rhs);
220 - first = next_nonnote_insn (first);
222 +cirrus_prev_mach_insn (rtx insn, int *len)
224 + return cirrus_prev_next_mach_insn (insn, len, 0);
227 - if (! arm_cirrus_insn_p (first))
230 +cirrus_next_mach_insn (rtx insn, int *len)
232 + return cirrus_prev_next_mach_insn (insn, len, 1);
235 - body = PATTERN (first);
236 +/* Cirrus reorg for branch slots. */
238 +cirrus_reorg_branch (rtx insn)
243 - /* (float (blah)) is in parallel with a clobber. */
244 - if (GET_CODE (body) == PARALLEL && XVECLEN (body, 0))
245 - body = XVECEXP (body, 0, 0);
247 - if (GET_CODE (body) == FLOAT)
248 - body = XEXP (body, 0);
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);
259 + /* Any branch must be followed by 2 non Cirrus instructions. */
261 + for (nops = 2; nops > 0; )
263 + if (!cirrus_next_mach_insn (t, 0))
268 + t = cirrus_next_mach_insn (t, &l);
269 + if (arm_cirrus_insn_p (t))
277 - /* get_attr cannot accept USE or CLOBBER. */
279 - || GET_CODE (first) != INSN
280 - || GET_CODE (PATTERN (first)) == USE
281 - || GET_CODE (PATTERN (first)) == CLOBBER)
284 + emit_insn_after (gen_nop (), insn); /* WARNING: this appears to cause "bad immediate value for offset" errors in the assembler */
287 - attr = get_attr_cirrus (first);
288 +/* Cirrus reorg for bug #1 (cirrus + cfcmpxx). */
290 +cirrus_reorg_bug1 (rtx insn)
292 + rtx body = PATTERN (insn), body2;
295 + enum attr_cirrus attr;
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)
305 - t = next_nonnote_insn (first);
306 + for (i = 0; i < XVECLEN (body, 0); i++)
308 + body2 = XVECEXP (body, 0, i);
309 + if (GET_CODE (body2) == SET)
311 + if (cirrus_dest_regn_p (body2, LAST_CIRRUS_FP_REGNUM))
317 + else if (GET_CODE (body2) == CLOBBER)
319 + if (cirrus_dest_regn_p (body2, LAST_CIRRUS_FP_REGNUM))
327 + else if (GET_CODE (body) == SET)
329 + if (cirrus_dest_regn_p (body, LAST_CIRRUS_FP_REGNUM))
337 - if (arm_cirrus_insn_p (t))
341 + for ( ; nops > 0; )
343 + t = cirrus_next_mach_insn (t, &l);
346 + if (GET_CODE (t) == JUMP_INSN
347 + || GET_CODE (t) == CALL_INSN)
352 + else if (arm_cirrus_insn_p (t))
354 + attr = get_attr_cirrus (t);
355 + if (attr == CIRRUS_COMPARE)
361 - if (arm_cirrus_insn_p (next_nonnote_insn (t)))
364 + emit_insn_after (gen_nop (), insn); /* WARNING: this appears to cause "bad immediate value for offset" errors in the assembler */
368 - emit_insn_after (gen_nop (), first);
369 +/* Cirrus reorg for bugs #10 and #12 (data aborts). */
371 +cirrus_reorg_bug10_12 (rtx insn)
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 */
384 /* Return TRUE if X references a SYMBOL_REF. */
385 @@ -7727,7 +7796,7 @@
390 + int align64 = 0, stuffnop = 0;
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);
398 + /* Check if branch before minipool is already stuffed with nops. */
399 + if (TARGET_CIRRUS_D0 || TARGET_CIRRUS_D1)
403 + t = prev_active_insn (scan);
404 + if (GET_CODE (t) != INSN
405 + || PATTERN (t) != const0_rtx)
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. */
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 */
419 scan = emit_label_after (minipool_vector_label, scan);
421 for (mp = minipool_vector_head; mp != NULL; mp = nmp)
422 @@ -8151,15 +8239,38 @@
423 gcc_assert (GET_CODE (insn) == NOTE);
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)
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);
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);
441 + /* Find last insn. */
442 + for (t = insn; ; t = s)
444 + s = cirrus_next_mach_insn (t, 0);
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);
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))
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);
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)
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))
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
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)
497 This file is part of GCC.
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}}"
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
524 Target Report Mask(CIRRUS_FIX_INVALID_INSNS)
525 Cirrus: Place NOPs to avoid invalid instruction combinations
528 +Target Report Mask(ARM_FLAG_CIRRUS_D0)
529 +Cirrus: workarounds for Crunch coprocessor revision D0
532 +Target Report Mask(ARM_FLAG_CIRRUS_D1)
533 +Cirrus: workarounds for Crunch coprocessor revision D1
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
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
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.
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}
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.
572 @item -mpoke-function-name
573 @opindex mpoke-function-name