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 cb0af8546d5..00000000000 --- a/meta/packages/gcc/gcc-4.2.3/arm-crunch-cirrus-bugfixes.patch +++ /dev/null @@ -1,573 +0,0 @@ -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 ---- /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 -+++ gcc-4.1.2/gcc/config/arm/arm.c 2007-05-15 09:39:41.000000000 +1000 -@@ -4,6 +4,7 @@ - Contributed by Pieter `Tiggr' Schoenmakers (rcpieter@win.tue.nl) - and Martin Simmons (@harleqn.co.uk). - More major hacks by Richard Earnshaw (rearnsha@arm.com). -+ Cirrus Crunch bugfixes by Vladimir Ivanov (vladit@nucleusys.com) - - This file is part of GCC. - -@@ -131,9 +132,17 @@ - static bool arm_xscale_rtx_costs (rtx, int, int, int *); - static bool arm_9e_rtx_costs (rtx, int, int, int *); - static int arm_address_cost (rtx); --static bool arm_memory_load_p (rtx); -+// static bool arm_memory_load_p (rtx); - static bool arm_cirrus_insn_p (rtx); --static void cirrus_reorg (rtx); -+// static void cirrus_reorg (rtx); -+static bool arm_mem_access_p (rtx); -+static bool cirrus_dest_regn_p (rtx, int); -+static rtx cirrus_prev_next_mach_insn (rtx, int *, int); -+static rtx cirrus_prev_mach_insn (rtx, int *); -+static rtx cirrus_next_mach_insn (rtx, int *); -+static void cirrus_reorg_branch (rtx); -+static void cirrus_reorg_bug1 (rtx); -+static void cirrus_reorg_bug10_12 (rtx); - static void arm_init_builtins (void); - static rtx arm_expand_builtin (tree, rtx, rtx, enum machine_mode, int); - static void arm_init_iwmmxt_builtins (void); -@@ -5399,41 +5412,6 @@ - || TREE_CODE (valtype) == COMPLEX_TYPE)); - } - --/* Returns TRUE if INSN is an "LDR REG, ADDR" instruction. -- Use by the Cirrus Maverick code which has to workaround -- a hardware bug triggered by such instructions. */ --static bool --arm_memory_load_p (rtx insn) --{ -- rtx body, lhs, rhs;; -- -- if (insn == NULL_RTX || GET_CODE (insn) != INSN) -- return false; -- -- body = PATTERN (insn); -- -- if (GET_CODE (body) != SET) -- return false; -- -- lhs = XEXP (body, 0); -- rhs = XEXP (body, 1); -- -- lhs = REG_OR_SUBREG_RTX (lhs); -- -- /* If the destination is not a general purpose -- register we do not have to worry. */ -- if (GET_CODE (lhs) != REG -- || REGNO_REG_CLASS (REGNO (lhs)) != GENERAL_REGS) -- return false; -- -- /* As well as loads from memory we also have to react -- to loads of invalid constants which will be turned -- into loads from the minipool. */ -- return (GET_CODE (rhs) == MEM -- || GET_CODE (rhs) == SYMBOL_REF -- || note_invalid_constants (insn, -1, false)); --} -- - /* Return TRUE if INSN is a Cirrus instruction. */ - static bool - arm_cirrus_insn_p (rtx insn) -@@ -5452,124 +5433,218 @@ - return attr != CIRRUS_NOT; - } - --/* Cirrus reorg for invalid instruction combinations. */ --static void --cirrus_reorg (rtx first) -+/* Return TRUE if ISN does memory access. */ -+static bool -+arm_mem_access_p (rtx insn) - { -- enum attr_cirrus attr; -- rtx body = PATTERN (first); -- rtx t; -- int nops; -+ enum attr_type attr; - -- /* Any branch must be followed by 2 non Cirrus instructions. */ -- if (GET_CODE (first) == JUMP_INSN && GET_CODE (body) != RETURN) -- { -- nops = 0; -- t = next_nonnote_insn (first); -+ /* get_attr aborts on USE and CLOBBER. */ -+ if (!insn -+ || GET_CODE (insn) != INSN -+ || GET_CODE (PATTERN (insn)) == USE -+ || GET_CODE (PATTERN (insn)) == CLOBBER) -+ return 0; - -- if (arm_cirrus_insn_p (t)) -- ++ nops; -+ attr = get_attr_type (insn); - -- if (arm_cirrus_insn_p (next_nonnote_insn (t))) -- ++ nops; -+ return attr == TYPE_LOAD_BYTE -+ || attr == TYPE_LOAD1 || attr == TYPE_LOAD2 || attr == TYPE_LOAD3 || attr == TYPE_LOAD4 -+ || attr == TYPE_F_CVT -+ || attr == TYPE_F_MEM_R || attr == TYPE_R_MEM_F || attr == TYPE_F_2_R || attr == TYPE_R_2_F -+ || attr == TYPE_F_LOAD || attr == TYPE_F_LOADS || attr == TYPE_F_LOADD -+ || attr == TYPE_F_STORE || attr == TYPE_F_STORES || attr == TYPE_F_STORED -+ || attr == TYPE_STORE1 || attr == TYPE_STORE2 || attr == TYPE_STORE3 || attr == TYPE_STORE4; -+ -+} - -- while (nops --) -- emit_insn_after (gen_nop (), first); -+/* Return TRUE if destination is certain Cirrus register. */ -+static bool -+cirrus_dest_regn_p (rtx body, int regn) -+{ -+ rtx lhs; -+ int reg; -+ lhs = XEXP (body, 0); -+ if (GET_CODE (lhs) != REG) -+ return 0; - -- return; -- } -+ reg = REGNO (lhs); -+ if (REGNO_REG_CLASS (reg) != CIRRUS_REGS) -+ return 0; - -- /* (float (blah)) is in parallel with a clobber. */ -- if (GET_CODE (body) == PARALLEL && XVECLEN (body, 0) > 0) -- body = XVECEXP (body, 0, 0); -+ return reg == regn; -+} -+ -+/* Get previous/next machine instruction during Cirrus workaround scans. -+ Assume worst case (for the purpose of Cirrus workarounds) -+ for JUMP / CALL instructions. */ -+static rtx -+cirrus_prev_next_mach_insn (rtx insn, int *len, int next) -+{ -+ rtx t; -+ int l = 0; - -- if (GET_CODE (body) == SET) -+ /* It seems that we can count only on INSN length. */ -+ for ( ; ; ) - { -- rtx lhs = XEXP (body, 0), rhs = XEXP (body, 1); -+ if (next) -+ insn = NEXT_INSN (insn); -+ else -+ insn = PREV_INSN (insn); -+ if (!insn) -+ break; - -- /* cfldrd, cfldr64, cfstrd, cfstr64 must -- be followed by a non Cirrus insn. */ -- if (get_attr_cirrus (first) == CIRRUS_DOUBLE) -- { -- if (arm_cirrus_insn_p (next_nonnote_insn (first))) -- emit_insn_after (gen_nop (), first); -+ if (GET_CODE (insn) == INSN) -+ { -+ l = get_attr_length (insn) / 4; -+ if (l) -+ break; -+ } -+ else if (GET_CODE (insn) == JUMP_INSN) -+ { -+ l = 1; -+ t = is_jump_table (insn); -+ if (t) -+ l += get_jump_table_size (t) / 4; -+ break; -+ } -+ else if (GET_CODE (insn) == CALL_INSN) -+ { -+ l = 1; -+ break; -+ } -+ } - -- return; -- } -- else if (arm_memory_load_p (first)) -- { -- unsigned int arm_regno; -+ if (len) -+ *len = l; - -- /* Any ldr/cfmvdlr, ldr/cfmvdhr, ldr/cfmvsr, ldr/cfmv64lr, -- ldr/cfmv64hr combination where the Rd field is the same -- in both instructions must be split with a non Cirrus -- insn. Example: -- -- ldr r0, blah -- nop -- cfmvsr mvf0, r0. */ -- -- /* Get Arm register number for ldr insn. */ -- if (GET_CODE (lhs) == REG) -- arm_regno = REGNO (lhs); -- else -- { -- gcc_assert (GET_CODE (rhs) == REG); -- arm_regno = REGNO (rhs); -- } -+ return insn; -+} - -- /* Next insn. */ -- first = next_nonnote_insn (first); -+static rtx -+cirrus_prev_mach_insn (rtx insn, int *len) -+{ -+ return cirrus_prev_next_mach_insn (insn, len, 0); -+} - -- if (! arm_cirrus_insn_p (first)) -- return; -+static rtx -+cirrus_next_mach_insn (rtx insn, int *len) -+{ -+ return cirrus_prev_next_mach_insn (insn, len, 1); -+} - -- body = PATTERN (first); -+/* Cirrus reorg for branch slots. */ -+static void -+cirrus_reorg_branch (rtx insn) -+{ -+ rtx t; -+ int nops, l; - -- /* (float (blah)) is in parallel with a clobber. */ -- if (GET_CODE (body) == PARALLEL && XVECLEN (body, 0)) -- body = XVECEXP (body, 0, 0); -- -- if (GET_CODE (body) == FLOAT) -- body = XEXP (body, 0); -- -- if (get_attr_cirrus (first) == CIRRUS_MOVE -- && GET_CODE (XEXP (body, 1)) == REG -- && arm_regno == REGNO (XEXP (body, 1))) -- emit_insn_after (gen_nop (), first); -+ /* TODO: handle jump-tables. */ -+ t = is_jump_table (insn); -+ if (t) -+ return; -+ -+ /* Any branch must be followed by 2 non Cirrus instructions. */ -+ t = insn; -+ for (nops = 2; nops > 0; ) -+ { -+ if (!cirrus_next_mach_insn (t, 0)) -+ { -+ insn = t; -+ break; -+ } -+ t = cirrus_next_mach_insn (t, &l); -+ if (arm_cirrus_insn_p (t)) -+ break; -+ nops -= l; - -- return; -- } - } - -- /* get_attr cannot accept USE or CLOBBER. */ -- if (!first -- || GET_CODE (first) != INSN -- || GET_CODE (PATTERN (first)) == USE -- || GET_CODE (PATTERN (first)) == CLOBBER) -- return; -+ while (nops-- > 0) -+ emit_insn_after (gen_nop (), insn); /* WARNING: this appears to cause "bad immediate value for offset" errors in the assembler */ -+} - -- attr = get_attr_cirrus (first); -+/* Cirrus reorg for bug #1 (cirrus + cfcmpxx). */ -+static void -+cirrus_reorg_bug1 (rtx insn) -+{ -+ rtx body = PATTERN (insn), body2; -+ rtx t; -+ int i, nops, l; -+ enum attr_cirrus attr; - -- /* Any coprocessor compare instruction (cfcmps, cfcmpd, ...) -- must be followed by a non-coprocessor instruction. */ -- if (attr == CIRRUS_COMPARE) -+ /* Check if destination or clobber is Cirrus register. */ -+ if (GET_CODE (body) == PARALLEL) - { -- nops = 0; -- -- t = next_nonnote_insn (first); -+ for (i = 0; i < XVECLEN (body, 0); i++) -+ { -+ body2 = XVECEXP (body, 0, i); -+ if (GET_CODE (body2) == SET) -+ { -+ if (cirrus_dest_regn_p (body2, LAST_CIRRUS_FP_REGNUM)) -+ { -+ nops = 5; -+ goto fix; -+ } -+ } -+ else if (GET_CODE (body2) == CLOBBER) -+ { -+ if (cirrus_dest_regn_p (body2, LAST_CIRRUS_FP_REGNUM)) -+ { -+ nops = 4; -+ goto fix; -+ } -+ } -+ } -+ } -+ else if (GET_CODE (body) == SET) -+ { -+ if (cirrus_dest_regn_p (body, LAST_CIRRUS_FP_REGNUM)) -+ { -+ nops = 5; -+ goto fix; -+ } -+ } -+ return; - -- if (arm_cirrus_insn_p (t)) -- ++ nops; -+fix: -+ t = insn; -+ for ( ; nops > 0; ) -+ { -+ t = cirrus_next_mach_insn (t, &l); -+ if (!t) -+ break; -+ if (GET_CODE (t) == JUMP_INSN -+ || GET_CODE (t) == CALL_INSN) -+ { -+ nops -= l; -+ break; -+ } -+ else if (arm_cirrus_insn_p (t)) -+ { -+ attr = get_attr_cirrus (t); -+ if (attr == CIRRUS_COMPARE) -+ break; -+ } -+ nops -= l; -+ } - -- if (arm_cirrus_insn_p (next_nonnote_insn (t))) -- ++ nops; -+ while (nops-- > 0) -+ emit_insn_after (gen_nop (), insn); /* WARNING: this appears to cause "bad immediate value for offset" errors in the assembler */ -+} - -- while (nops --) -- emit_insn_after (gen_nop (), first); -+/* Cirrus reorg for bugs #10 and #12 (data aborts). */ -+static void -+cirrus_reorg_bug10_12 (rtx insn) -+{ -+ rtx t; - -- return; -- } -+ t = cirrus_next_mach_insn (insn, 0); -+ if (arm_cirrus_insn_p (t)) -+ if (TARGET_CIRRUS_D0 || -+ get_attr_cirrus (t) == CIRRUS_DOUBLE) -+ emit_insn_after (gen_nop (), insn); /* WARNING: this appears to cause "bad immediate value for offset" errors in the assembler */ - } - - /* Return TRUE if X references a SYMBOL_REF. */ -@@ -7727,7 +7796,7 @@ - { - Mnode * mp; - Mnode * nmp; -- int align64 = 0; -+ int align64 = 0, stuffnop = 0; - - if (ARM_DOUBLEWORD_ALIGN) - for (mp = minipool_vector_head; mp != NULL; mp = mp->next) -@@ -7742,8 +7811,27 @@ - ";; Emitting minipool after insn %u; address %ld; align %d (bytes)\n", - INSN_UID (scan), (unsigned long) minipool_barrier->address, align64 ? 8 : 4); - -+ /* Check if branch before minipool is already stuffed with nops. */ -+ if (TARGET_CIRRUS_D0 || TARGET_CIRRUS_D1) -+ { -+ rtx t; -+ -+ t = prev_active_insn (scan); -+ if (GET_CODE (t) != INSN -+ || PATTERN (t) != const0_rtx) -+ stuffnop = 1; -+ } - scan = emit_label_after (gen_label_rtx (), scan); - scan = emit_insn_after (align64 ? gen_align_8 () : gen_align_4 (), scan); -+ /* Last instruction was branch, so put two non-Cirrus opcodes. */ -+ if (stuffnop) -+ { -+#if TARGET_CIRRUS /* This is doubling up on nops, so I don't think this is a good idea */ -+ emit_insn_before (gen_nop (), scan); /* WARNING: this appears to cause "bad immediate value for offset" errors in the assembler */ -+ emit_insn_before (gen_nop (), scan); /* WARNING: this appears to cause "bad immediate value for offset" errors in the assembler */ -+#endif -+ } -+ - scan = emit_label_after (minipool_vector_label, scan); - - for (mp = minipool_vector_head; mp != NULL; mp = nmp) -@@ -8151,15 +8239,38 @@ - gcc_assert (GET_CODE (insn) == NOTE); - minipool_pad = 0; - -+#if TARGET_CIRRUS /* I think this is a double-up */ -+ /* Scan all the insn and fix Cirrus issues. */ -+ if (TARGET_CIRRUS_D0 || TARGET_CIRRUS_D1) -+ { -+ rtx t, s; -+ -+ for (t = cirrus_next_mach_insn (insn, 0); t; t = cirrus_next_mach_insn (t, 0)) -+ if (arm_mem_access_p (t)) -+ cirrus_reorg_bug10_12 (t); -+ -+ if (TARGET_CIRRUS_D0) -+ for (t = cirrus_next_mach_insn (insn, 0); t; t = cirrus_next_mach_insn (t, 0)) -+ if (arm_cirrus_insn_p (t)) -+ cirrus_reorg_bug1 (t); -+ -+ /* Find last insn. */ -+ for (t = insn; ; t = s) -+ { -+ s = cirrus_next_mach_insn (t, 0); -+ if (!s) -+ break; -+ } -+ /* Scan backward and fix branches. - WARNING: appears to cause "bad immediate value for offset" problems! */ -+ for ( ; t; t = cirrus_prev_mach_insn (t, 0)) -+ if (GET_CODE (t) == JUMP_INSN -+ || GET_CODE (t) == CALL_INSN) -+ cirrus_reorg_branch (t); -+ } -+#endif - /* Scan all the insns and record the operands that will need fixing. */ - for (insn = next_nonnote_insn (insn); insn; insn = next_nonnote_insn (insn)) - { -- if (TARGET_CIRRUS_FIX_INVALID_INSNS -- && (arm_cirrus_insn_p (insn) -- || GET_CODE (insn) == JUMP_INSN -- || arm_memory_load_p (insn))) -- cirrus_reorg (insn); -- - if (GET_CODE (insn) == BARRIER) - push_minipool_barrier (insn, address); - else if (INSN_P (insn)) -@@ -11755,16 +11910,10 @@ - || get_attr_conds (this_insn) != CONDS_NOCOND) - fail = TRUE; - -- /* A conditional cirrus instruction must be followed by -- a non Cirrus instruction. However, since we -- conditionalize instructions in this function and by -- the time we get here we can't add instructions -- (nops), because shorten_branches() has already been -- called, we will disable conditionalizing Cirrus -- instructions to be safe. */ -- if (GET_CODE (scanbody) != USE -- && GET_CODE (scanbody) != CLOBBER -- && get_attr_cirrus (this_insn) != CIRRUS_NOT) -+ /* To avoid erratic behaviour, we avoid conditional Cirrus -+ instructions when doing workarounds. */ -+ if (arm_cirrus_insn_p(this_insn) -+ && (TARGET_CIRRUS_D0 || TARGET_CIRRUS_D1)) - fail = TRUE; - break; - -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 ---- /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 -+++ gcc-4.1.2/gcc/config/arm/arm.h 2007-05-15 10:15:05.000000000 +1000 -@@ -5,6 +5,7 @@ - and Martin Simmons (@harleqn.co.uk). - More major hacks by Richard Earnshaw (rearnsha@arm.com) - Minor hacks by Nick Clifton (nickc@cygnus.com) -+ Cirrus Crunch fixes by Vladimir Ivanov (vladitx@nucleusys.com) - - This file is part of GCC. - -@@ -140,7 +141,9 @@ - %{msoft-float:%{mhard-float: \ - %e-msoft-float and -mhard_float may not be used together}} \ - %{mbig-endian:%{mlittle-endian: \ -- %e-mbig-endian and -mlittle-endian may not be used together}}" -+ %e-mbig-endian and -mlittle-endian may not be used together}} \ -+%{mfix-crunch-d0:%{mfix-crunch-d1: \ -+ %e-mfix-crunch-d0 and -mfix-crunch-d1 may not be used together}}" - - #ifndef CC1_SPEC - #define CC1_SPEC "" -@@ -179,6 +182,9 @@ - #define TARGET_HARD_FLOAT_ABI (arm_float_abi == ARM_FLOAT_ABI_HARD) - #define TARGET_FPA (arm_fp_model == ARM_FP_MODEL_FPA) - #define TARGET_MAVERICK (arm_fp_model == ARM_FP_MODEL_MAVERICK) -+#define TARGET_CIRRUS (arm_arch_cirrus) -+#define TARGET_CIRRUS_D0 0 /* (target_flags & ARM_FLAG_CIRRUS_D0) */ -+#define TARGET_CIRRUS_D1 1 /* (target_flags & ARM_FLAG_CIRRUS_D1) */ - #define TARGET_VFP (arm_fp_model == ARM_FP_MODEL_VFP) - #define TARGET_IWMMXT (arm_arch_iwmmxt) - #define TARGET_REALLY_IWMMXT (TARGET_IWMMXT && TARGET_ARM) -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 ---- /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 -+++ gcc-4.1.2/gcc/config/arm/arm.opt 2007-05-15 10:09:31.000000000 +1000 -@@ -68,6 +68,14 @@ - Target Report Mask(CIRRUS_FIX_INVALID_INSNS) - Cirrus: Place NOPs to avoid invalid instruction combinations - -+fix-crunch-d0 -+Target Report Mask(ARM_FLAG_CIRRUS_D0) -+Cirrus: workarounds for Crunch coprocessor revision D0 -+ -+fix-crunch-d1 -+Target Report Mask(ARM_FLAG_CIRRUS_D1) -+Cirrus: workarounds for Crunch coprocessor revision D1 -+ - mcpu= - Target RejectNegative Joined - Specify the name of the target CPU -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 ---- /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 -+++ gcc-4.1.2/gcc/doc/invoke.texi 2007-05-15 10:07:04.000000000 +1000 -@@ -408,7 +408,7 @@ - -msingle-pic-base -mno-single-pic-base @gol - -mpic-register=@var{reg} @gol - -mnop-fun-dllimport @gol ---mcirrus-fix-invalid-insns -mno-cirrus-fix-invalid-insns @gol -+-mfix-crunch-d0 -mfix-crunch-d1 @gol - -mpoke-function-name @gol - -mthumb -marm @gol - -mtpcs-frame -mtpcs-leaf-frame @gol -@@ -7435,17 +7435,12 @@ - Specify the register to be used for PIC addressing. The default is R10 - unless stack-checking is enabled, when R9 is used. - --@item -mcirrus-fix-invalid-insns --@opindex mcirrus-fix-invalid-insns --@opindex mno-cirrus-fix-invalid-insns --Insert NOPs into the instruction stream to in order to work around --problems with invalid Maverick instruction combinations. This option --is only valid if the @option{-mcpu=ep9312} option has been used to --enable generation of instructions for the Cirrus Maverick floating --point co-processor. This option is not enabled by default, since the --problem is only present in older Maverick implementations. The default --can be re-enabled by use of the @option{-mno-cirrus-fix-invalid-insns} --switch. -+@item -mfix-crunch-d0 -+@itemx -mfix-crunch-d1 -+@opindex mfix-crunch-d0 -+@opindex mfix-crunch-d1 -+Enable workarounds for the Cirrus MaverickCrunch coprocessor revisions -+D0 and D1 respectively. - - @item -mpoke-function-name - @opindex mpoke-function-name |