diff options
Diffstat (limited to 'toolchain-layer/recipes-devtools/gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99319.patch')
-rw-r--r-- | toolchain-layer/recipes-devtools/gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99319.patch | 197 |
1 files changed, 197 insertions, 0 deletions
diff --git a/toolchain-layer/recipes-devtools/gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99319.patch b/toolchain-layer/recipes-devtools/gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99319.patch new file mode 100644 index 0000000000..a649c9542a --- /dev/null +++ b/toolchain-layer/recipes-devtools/gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99319.patch @@ -0,0 +1,197 @@ +2010-07-24 Sandra Loosemore <sandra@codesourcery.com> + + Backport from mainline: + + 2010-04-10 Wei Guozhi <carrot@google.com> + + PR target/42601 + gcc/ + * config/arm/arm.c (arm_pic_static_addr): New function. + (legitimize_pic_address): Call arm_pic_static_addr when it detects + a static symbol. + (arm_output_addr_const_extra): Output expression for new pattern. + * config/arm/arm.md (UNSPEC_SYMBOL_OFFSET): New unspec symbol. + + 2010-07-22 Sandra Loosemore <sandra@codesourcery.com> + + PR tree-optimization/39839 + gcc/testsuite/ + * gcc.target/arm/pr39839.c: New test case. + + 2010-07-24 Jie Zhang <jie@codesourcery.com> + + Issue #9079 + +=== modified file 'gcc/config/arm/arm.c' +--- old/gcc/config/arm/arm.c 2010-08-03 13:55:46 +0000 ++++ new/gcc/config/arm/arm.c 2010-08-05 12:06:40 +0000 +@@ -225,6 +225,7 @@ + static void arm_asm_trampoline_template (FILE *); + static void arm_trampoline_init (rtx, tree, rtx); + static rtx arm_trampoline_adjust_address (rtx); ++static rtx arm_pic_static_addr (rtx orig, rtx reg); + + + /* Table of machine attributes. */ +@@ -4986,29 +4987,16 @@ + { + rtx pic_ref, address; + rtx insn; +- int subregs = 0; +- +- /* If this function doesn't have a pic register, create one now. */ +- require_pic_register (); + + if (reg == 0) + { + gcc_assert (can_create_pseudo_p ()); + reg = gen_reg_rtx (Pmode); +- +- subregs = 1; ++ address = gen_reg_rtx (Pmode); + } +- +- if (subregs) +- address = gen_reg_rtx (Pmode); + else + address = reg; + +- if (TARGET_32BIT) +- emit_insn (gen_pic_load_addr_32bit (address, orig)); +- else /* TARGET_THUMB1 */ +- emit_insn (gen_pic_load_addr_thumb1 (address, orig)); +- + /* VxWorks does not impose a fixed gap between segments; the run-time + gap can be different from the object-file gap. We therefore can't + use GOTOFF unless we are absolutely sure that the symbol is in the +@@ -5020,16 +5008,23 @@ + SYMBOL_REF_LOCAL_P (orig))) + && NEED_GOT_RELOC + && !TARGET_VXWORKS_RTP) +- pic_ref = gen_rtx_PLUS (Pmode, cfun->machine->pic_reg, address); ++ insn = arm_pic_static_addr (orig, reg); + else + { ++ /* If this function doesn't have a pic register, create one now. */ ++ require_pic_register (); ++ ++ if (TARGET_32BIT) ++ emit_insn (gen_pic_load_addr_32bit (address, orig)); ++ else /* TARGET_THUMB1 */ ++ emit_insn (gen_pic_load_addr_thumb1 (address, orig)); ++ + pic_ref = gen_const_mem (Pmode, + gen_rtx_PLUS (Pmode, cfun->machine->pic_reg, + address)); ++ insn = emit_move_insn (reg, pic_ref); + } + +- insn = emit_move_insn (reg, pic_ref); +- + /* Put a REG_EQUAL note on this insn, so that it can be optimized + by loop. */ + set_unique_reg_note (insn, REG_EQUAL, orig); +@@ -5236,6 +5231,43 @@ + emit_use (pic_reg); + } + ++/* Generate code to load the address of a static var when flag_pic is set. */ ++static rtx ++arm_pic_static_addr (rtx orig, rtx reg) ++{ ++ rtx l1, labelno, offset_rtx, insn; ++ ++ gcc_assert (flag_pic); ++ ++ /* We use an UNSPEC rather than a LABEL_REF because this label ++ never appears in the code stream. */ ++ labelno = GEN_INT (pic_labelno++); ++ l1 = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, labelno), UNSPEC_PIC_LABEL); ++ l1 = gen_rtx_CONST (VOIDmode, l1); ++ ++ /* On the ARM the PC register contains 'dot + 8' at the time of the ++ addition, on the Thumb it is 'dot + 4'. */ ++ offset_rtx = plus_constant (l1, TARGET_ARM ? 8 : 4); ++ offset_rtx = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, orig, offset_rtx), ++ UNSPEC_SYMBOL_OFFSET); ++ offset_rtx = gen_rtx_CONST (Pmode, offset_rtx); ++ ++ if (TARGET_32BIT) ++ { ++ emit_insn (gen_pic_load_addr_32bit (reg, offset_rtx)); ++ if (TARGET_ARM) ++ insn = emit_insn (gen_pic_add_dot_plus_eight (reg, reg, labelno)); ++ else ++ insn = emit_insn (gen_pic_add_dot_plus_four (reg, reg, labelno)); ++ } ++ else /* TARGET_THUMB1 */ ++ { ++ emit_insn (gen_pic_load_addr_thumb1 (reg, offset_rtx)); ++ insn = emit_insn (gen_pic_add_dot_plus_four (reg, reg, labelno)); ++ } ++ ++ return insn; ++} + + /* Return nonzero if X is valid as an ARM state addressing register. */ + static int +@@ -21461,6 +21493,16 @@ + fputc (')', fp); + return TRUE; + } ++ else if (GET_CODE (x) == UNSPEC && XINT (x, 1) == UNSPEC_SYMBOL_OFFSET) ++ { ++ output_addr_const (fp, XVECEXP (x, 0, 0)); ++ if (GOT_PCREL) ++ fputs ("+.", fp); ++ fputs ("-(", fp); ++ output_addr_const (fp, XVECEXP (x, 0, 1)); ++ fputc (')', fp); ++ return TRUE; ++ } + else if (GET_CODE (x) == CONST_VECTOR) + return arm_emit_vector_const (fp, x); + + +=== modified file 'gcc/config/arm/arm.md' +--- old/gcc/config/arm/arm.md 2010-07-30 14:17:05 +0000 ++++ new/gcc/config/arm/arm.md 2010-08-05 12:06:40 +0000 +@@ -101,6 +101,8 @@ + ; a given symbolic address. + (UNSPEC_THUMB1_CASESI 25) ; A Thumb1 compressed dispatch-table call. + (UNSPEC_RBIT 26) ; rbit operation. ++ (UNSPEC_SYMBOL_OFFSET 27) ; The offset of the start of the symbol from ++ ; another symbolic address. + ] + ) + + +=== added file 'gcc/testsuite/gcc.target/arm/pr39839.c' +--- old/gcc/testsuite/gcc.target/arm/pr39839.c 1970-01-01 00:00:00 +0000 ++++ new/gcc/testsuite/gcc.target/arm/pr39839.c 2010-08-05 12:06:40 +0000 +@@ -0,0 +1,24 @@ ++/* { dg-options "-mthumb -Os -march=armv5te -mthumb-interwork -fpic" } */ ++/* { dg-require-effective-target arm_thumb1_ok } */ ++/* { dg-final { scan-assembler-not "str\[\\t \]*r.,\[\\t \]*.sp," } } */ ++ ++struct S ++{ ++ int count; ++ char *addr; ++}; ++ ++void func(const char*, const char*, int, const char*); ++ ++/* This function should not need to spill to the stack. */ ++void test(struct S *p) ++{ ++ int off = p->count; ++ while (p->count >= 0) ++ { ++ const char *s = "xyz"; ++ if (*p->addr) s = "pqr"; ++ func("abcde", p->addr + off, off, s); ++ p->count--; ++ } ++} + |