mirror of
git://git.openembedded.org/meta-openembedded
synced 2026-04-02 02:49:12 +00:00
This needs further investigation, but for now we can get the tested sources into the poky gcc harness Signed-off-by: Koen Kooi <k-kooi@ti.com>
198 lines
5.8 KiB
Diff
198 lines
5.8 KiB
Diff
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--;
|
||
+ }
|
||
+}
|
||
|