aboutsummaryrefslogtreecommitdiffstats
path: root/recipes/gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99319.patch
diff options
context:
space:
mode:
Diffstat (limited to 'recipes/gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99319.patch')
-rw-r--r--recipes/gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99319.patch197
1 files changed, 197 insertions, 0 deletions
diff --git a/recipes/gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99319.patch b/recipes/gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99319.patch
new file mode 100644
index 0000000000..a649c9542a
--- /dev/null
+++ b/recipes/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--;
++ }
++}
+