aboutsummaryrefslogtreecommitdiffstats
path: root/meta-oe/recipes-devtools/gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99404.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta-oe/recipes-devtools/gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99404.patch')
-rw-r--r--meta-oe/recipes-devtools/gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99404.patch386
1 files changed, 386 insertions, 0 deletions
diff --git a/meta-oe/recipes-devtools/gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99404.patch b/meta-oe/recipes-devtools/gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99404.patch
new file mode 100644
index 0000000000..2753300925
--- /dev/null
+++ b/meta-oe/recipes-devtools/gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99404.patch
@@ -0,0 +1,386 @@
+2010-09-20 Jie Zhang <jie@codesourcery.com>
+
+ Issue #9019
+
+ Backport from mainline:
+
+ gcc/
+ 2010-09-20 Jie Zhang <jie@codesourcery.com>
+ * config/arm/arm.c (arm_address_offset_is_imm): New.
+ (arm_early_store_addr_dep): New.
+ (arm_early_load_addr_dep): New.
+ * config/arm/arm-protos.h (arm_early_store_addr_dep): Declare.
+ (arm_early_load_addr_dep): Declare.
+ (arm_address_offset_is_imm): Declare.
+ * config/arm/cortex-m4.md: New file.
+ * config/arm/cortex-m4-fpu.md: New file.
+ * config/arm/arm.md: Include cortex-m4.md and cortex-m4-fpu.md.
+ (attr generic_sched): Exclude cortexm4.
+ (attr generic_vfp): Exclude cortexm4.
+
+=== modified file 'gcc/config/arm/arm-protos.h'
+Index: gcc-4.5/gcc/config/arm/arm-protos.h
+===================================================================
+--- gcc-4.5.orig/gcc/config/arm/arm-protos.h
++++ gcc-4.5/gcc/config/arm/arm-protos.h
+@@ -87,6 +87,8 @@ extern int arm_coproc_mem_operand (rtx,
+ extern int neon_vector_mem_operand (rtx, int);
+ extern int neon_struct_mem_operand (rtx);
+ extern int arm_no_early_store_addr_dep (rtx, rtx);
++extern int arm_early_store_addr_dep (rtx, rtx);
++extern int arm_early_load_addr_dep (rtx, rtx);
+ extern int arm_no_early_alu_shift_dep (rtx, rtx);
+ extern int arm_no_early_alu_shift_value_dep (rtx, rtx);
+ extern int arm_no_early_mul_dep (rtx, rtx);
+@@ -131,6 +133,7 @@ extern const char *output_move_quad (rtx
+ extern const char *output_move_vfp (rtx *operands);
+ extern const char *output_move_neon (rtx *operands);
+ extern int arm_attr_length_move_neon (rtx);
++extern int arm_address_offset_is_imm (rtx);
+ extern const char *output_add_immediate (rtx *);
+ extern const char *arithmetic_instr (rtx, int);
+ extern void output_ascii_pseudo_op (FILE *, const unsigned char *, int);
+Index: gcc-4.5/gcc/config/arm/arm.c
+===================================================================
+--- gcc-4.5.orig/gcc/config/arm/arm.c
++++ gcc-4.5/gcc/config/arm/arm.c
+@@ -13542,6 +13542,34 @@ arm_attr_length_move_neon (rtx insn)
+ return 4;
+ }
+
++/* Return nonzero if the offset in the address is an immediate. Otherwise,
++ return zero. */
++
++int
++arm_address_offset_is_imm (rtx insn)
++{
++ rtx mem, addr;
++
++ extract_insn_cached (insn);
++
++ if (REG_P (recog_data.operand[0]))
++ return 0;
++
++ mem = recog_data.operand[0];
++
++ gcc_assert (MEM_P (mem));
++
++ addr = XEXP (mem, 0);
++
++ if (GET_CODE (addr) == REG
++ || (GET_CODE (addr) == PLUS
++ && GET_CODE (XEXP (addr, 0)) == REG
++ && GET_CODE (XEXP (addr, 1)) == CONST_INT))
++ return 1;
++ else
++ return 0;
++}
++
+ /* Output an ADD r, s, #n where n may be too big for one instruction.
+ If adding zero to one register, output nothing. */
+ const char *
+@@ -21620,6 +21648,38 @@ arm_no_early_store_addr_dep (rtx produce
+ return !reg_overlap_mentioned_p (value, addr);
+ }
+
++/* Return nonzero if the CONSUMER instruction (a store) does need
++ PRODUCER's value to calculate the address. */
++
++int
++arm_early_store_addr_dep (rtx producer, rtx consumer)
++{
++ return !arm_no_early_store_addr_dep (producer, consumer);
++}
++
++/* Return nonzero if the CONSUMER instruction (a load) does need
++ PRODUCER's value to calculate the address. */
++
++int
++arm_early_load_addr_dep (rtx producer, rtx consumer)
++{
++ rtx value = PATTERN (producer);
++ rtx addr = PATTERN (consumer);
++
++ if (GET_CODE (value) == COND_EXEC)
++ value = COND_EXEC_CODE (value);
++ if (GET_CODE (value) == PARALLEL)
++ value = XVECEXP (value, 0, 0);
++ value = XEXP (value, 0);
++ if (GET_CODE (addr) == COND_EXEC)
++ addr = COND_EXEC_CODE (addr);
++ if (GET_CODE (addr) == PARALLEL)
++ addr = XVECEXP (addr, 0, 0);
++ addr = XEXP (addr, 1);
++
++ return reg_overlap_mentioned_p (value, addr);
++}
++
+ /* Return nonzero if the CONSUMER instruction (an ALU op) does not
+ have an early register shift value or amount dependency on the
+ result of PRODUCER. */
+Index: gcc-4.5/gcc/config/arm/arm.md
+===================================================================
+--- gcc-4.5.orig/gcc/config/arm/arm.md
++++ gcc-4.5/gcc/config/arm/arm.md
+@@ -434,16 +434,16 @@
+ ;; True if the generic scheduling description should be used.
+
+ (define_attr "generic_sched" "yes,no"
+- (const (if_then_else
+- (ior (eq_attr "tune" "arm926ejs,arm1020e,arm1026ejs,arm1136js,arm1136jfs,cortexa5,cortexa8,cortexa9")
+- (eq_attr "tune_cortexr4" "yes"))
++ (const (if_then_else
++ (ior (eq_attr "tune" "arm926ejs,arm1020e,arm1026ejs,arm1136js,arm1136jfs,cortexa5,cortexa8,cortexa9,cortexm4")
++ (eq_attr "tune_cortexr4" "yes"))
+ (const_string "no")
+ (const_string "yes"))))
+
+ (define_attr "generic_vfp" "yes,no"
+ (const (if_then_else
+ (and (eq_attr "fpu" "vfp")
+- (eq_attr "tune" "!arm1020e,arm1022e,cortexa5,cortexa8,cortexa9")
++ (eq_attr "tune" "!arm1020e,arm1022e,cortexa5,cortexa8,cortexa9,cortexm4")
+ (eq_attr "tune_cortexr4" "no"))
+ (const_string "yes")
+ (const_string "no"))))
+@@ -472,6 +472,8 @@
+ (include "cortex-a9.md")
+ (include "cortex-r4.md")
+ (include "cortex-r4f.md")
++(include "cortex-m4.md")
++(include "cortex-m4-fpu.md")
+ (include "vfp11.md")
+
+
+Index: gcc-4.5/gcc/config/arm/cortex-m4-fpu.md
+===================================================================
+--- /dev/null
++++ gcc-4.5/gcc/config/arm/cortex-m4-fpu.md
+@@ -0,0 +1,111 @@
++;; ARM Cortex-M4 FPU pipeline description
++;; Copyright (C) 2010 Free Software Foundation, Inc.
++;; Contributed by CodeSourcery.
++;;
++;; This file is part of GCC.
++;;
++;; GCC is free software; you can redistribute it and/or modify it
++;; under the terms of the GNU General Public License as published by
++;; the Free Software Foundation; either version 3, or (at your option)
++;; any later version.
++;;
++;; GCC is distributed in the hope that it will be useful, but
++;; WITHOUT ANY WARRANTY; without even the implied warranty of
++;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++;; General Public License for more details.
++;;
++;; You should have received a copy of the GNU General Public License
++;; along with GCC; see the file COPYING3. If not see
++;; <http://www.gnu.org/licenses/>.
++
++;; Use an artifial unit to model FPU.
++(define_cpu_unit "cortex_m4_v" "cortex_m4")
++
++(define_reservation "cortex_m4_ex_v" "cortex_m4_ex+cortex_m4_v")
++
++;; Integer instructions following VDIV or VSQRT complete out-of-order.
++(define_insn_reservation "cortex_m4_fdivs" 15
++ (and (eq_attr "tune" "cortexm4")
++ (eq_attr "type" "fdivs"))
++ "cortex_m4_ex_v,cortex_m4_v*13")
++
++(define_insn_reservation "cortex_m4_vmov_1" 1
++ (and (eq_attr "tune" "cortexm4")
++ (eq_attr "type" "fcpys,fconsts"))
++ "cortex_m4_ex_v")
++
++(define_insn_reservation "cortex_m4_vmov_2" 2
++ (and (eq_attr "tune" "cortexm4")
++ (eq_attr "type" "f_2_r,r_2_f"))
++ "cortex_m4_ex_v*2")
++
++(define_insn_reservation "cortex_m4_fmuls" 2
++ (and (eq_attr "tune" "cortexm4")
++ (eq_attr "type" "fmuls"))
++ "cortex_m4_ex_v")
++
++(define_insn_reservation "cortex_m4_fmacs" 4
++ (and (eq_attr "tune" "cortexm4")
++ (eq_attr "type" "fmacs"))
++ "cortex_m4_ex_v*3")
++
++(define_insn_reservation "cortex_m4_ffariths" 1
++ (and (eq_attr "tune" "cortexm4")
++ (eq_attr "type" "ffariths"))
++ "cortex_m4_ex_v")
++
++(define_insn_reservation "cortex_m4_fadds" 2
++ (and (eq_attr "tune" "cortexm4")
++ (eq_attr "type" "fadds"))
++ "cortex_m4_ex_v")
++
++(define_insn_reservation "cortex_m4_fcmps" 1
++ (and (eq_attr "tune" "cortexm4")
++ (eq_attr "type" "fcmps"))
++ "cortex_m4_ex_v")
++
++(define_insn_reservation "cortex_m4_f_flag" 1
++ (and (eq_attr "tune" "cortexm4")
++ (eq_attr "type" "f_flag"))
++ "cortex_m4_ex_v")
++
++(define_insn_reservation "cortex_m4_f_cvt" 2
++ (and (eq_attr "tune" "cortexm4")
++ (eq_attr "type" "f_cvt"))
++ "cortex_m4_ex_v")
++
++(define_insn_reservation "cortex_m4_f_load" 2
++ (and (eq_attr "tune" "cortexm4")
++ (eq_attr "type" "f_load"))
++ "cortex_m4_ex_v*2")
++
++(define_insn_reservation "cortex_m4_f_store" 2
++ (and (eq_attr "tune" "cortexm4")
++ (eq_attr "type" "f_store"))
++ "cortex_m4_ex_v*2")
++
++(define_insn_reservation "cortex_m4_f_loadd" 3
++ (and (eq_attr "tune" "cortexm4")
++ (eq_attr "type" "f_loadd"))
++ "cortex_m4_ex_v*3")
++
++(define_insn_reservation "cortex_m4_f_stored" 3
++ (and (eq_attr "tune" "cortexm4")
++ (eq_attr "type" "f_stored"))
++ "cortex_m4_ex_v*3")
++
++;; MAC instructions consume their addend one cycle later. If the result
++;; of an arithmetic instruction is consumed as the addend of the following
++;; MAC instruction, the latency can be decreased by one.
++
++(define_bypass 1 "cortex_m4_fadds,cortex_m4_fmuls,cortex_m4_f_cvt"
++ "cortex_m4_fmacs"
++ "arm_no_early_mul_dep")
++
++(define_bypass 3 "cortex_m4_fmacs"
++ "cortex_m4_fmacs"
++ "arm_no_early_mul_dep")
++
++(define_bypass 14 "cortex_m4_fdivs"
++ "cortex_m4_fmacs"
++ "arm_no_early_mul_dep")
+Index: gcc-4.5/gcc/config/arm/cortex-m4.md
+===================================================================
+--- /dev/null
++++ gcc-4.5/gcc/config/arm/cortex-m4.md
+@@ -0,0 +1,111 @@
++;; ARM Cortex-M4 pipeline description
++;; Copyright (C) 2010 Free Software Foundation, Inc.
++;; Contributed by CodeSourcery.
++;;
++;; This file is part of GCC.
++;;
++;; GCC is free software; you can redistribute it and/or modify it
++;; under the terms of the GNU General Public License as published by
++;; the Free Software Foundation; either version 3, or (at your option)
++;; any later version.
++;;
++;; GCC is distributed in the hope that it will be useful, but
++;; WITHOUT ANY WARRANTY; without even the implied warranty of
++;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++;; General Public License for more details.
++;;
++;; You should have received a copy of the GNU General Public License
++;; along with GCC; see the file COPYING3. If not see
++;; <http://www.gnu.org/licenses/>.
++
++(define_automaton "cortex_m4")
++
++;; We model the pipelining of LDR instructions by using two artificial units.
++
++(define_cpu_unit "cortex_m4_a" "cortex_m4")
++
++(define_cpu_unit "cortex_m4_b" "cortex_m4")
++
++(define_reservation "cortex_m4_ex" "cortex_m4_a+cortex_m4_b")
++
++;; ALU and multiply is one cycle.
++(define_insn_reservation "cortex_m4_alu" 1
++ (and (eq_attr "tune" "cortexm4")
++ (eq_attr "type" "alu,alu_shift,alu_shift_reg,mult"))
++ "cortex_m4_ex")
++
++;; Byte, half-word and word load is two cycles.
++(define_insn_reservation "cortex_m4_load1" 2
++ (and (eq_attr "tune" "cortexm4")
++ (eq_attr "type" "load_byte,load1"))
++ "cortex_m4_a, cortex_m4_b")
++
++;; str rx, [ry, #imm] is always one cycle.
++(define_insn_reservation "cortex_m4_store1_1" 1
++ (and (and (eq_attr "tune" "cortexm4")
++ (eq_attr "type" "store1"))
++ (ne (symbol_ref ("arm_address_offset_is_imm (insn)")) (const_int 0)))
++ "cortex_m4_a")
++
++;; Other byte, half-word and word load is two cycles.
++(define_insn_reservation "cortex_m4_store1_2" 2
++ (and (and (eq_attr "tune" "cortexm4")
++ (eq_attr "type" "store1"))
++ (eq (symbol_ref ("arm_address_offset_is_imm (insn)")) (const_int 0)))
++ "cortex_m4_a*2")
++
++(define_insn_reservation "cortex_m4_load2" 3
++ (and (eq_attr "tune" "cortexm4")
++ (eq_attr "type" "load2"))
++ "cortex_m4_ex*3")
++
++(define_insn_reservation "cortex_m4_store2" 3
++ (and (eq_attr "tune" "cortexm4")
++ (eq_attr "type" "store2"))
++ "cortex_m4_ex*3")
++
++(define_insn_reservation "cortex_m4_load3" 4
++ (and (eq_attr "tune" "cortexm4")
++ (eq_attr "type" "load3"))
++ "cortex_m4_ex*4")
++
++(define_insn_reservation "cortex_m4_store3" 4
++ (and (eq_attr "tune" "cortexm4")
++ (eq_attr "type" "store3"))
++ "cortex_m4_ex*4")
++
++(define_insn_reservation "cortex_m4_load4" 5
++ (and (eq_attr "tune" "cortexm4")
++ (eq_attr "type" "load4"))
++ "cortex_m4_ex*5")
++
++(define_insn_reservation "cortex_m4_store4" 5
++ (and (eq_attr "tune" "cortexm4")
++ (eq_attr "type" "store4"))
++ "cortex_m4_ex*5")
++
++;; If the address of load or store depends on the result of the preceding
++;; instruction, the latency is increased by one.
++
++(define_bypass 2 "cortex_m4_alu"
++ "cortex_m4_load1"
++ "arm_early_load_addr_dep")
++
++(define_bypass 2 "cortex_m4_alu"
++ "cortex_m4_store1_1,cortex_m4_store1_2"
++ "arm_early_store_addr_dep")
++
++(define_insn_reservation "cortex_m4_branch" 3
++ (and (eq_attr "tune" "cortexm4")
++ (eq_attr "type" "branch"))
++ "cortex_m4_ex*3")
++
++(define_insn_reservation "cortex_m4_call" 3
++ (and (eq_attr "tune" "cortexm4")
++ (eq_attr "type" "call"))
++ "cortex_m4_ex*3")
++
++(define_insn_reservation "cortex_m4_block" 1
++ (and (eq_attr "tune" "cortexm4")
++ (eq_attr "type" "block"))
++ "cortex_m4_ex")