diff options
Diffstat (limited to 'recipes-devtools/gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99319.patch')
-rw-r--r-- | recipes-devtools/gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99319.patch | 197 |
1 files changed, 197 insertions, 0 deletions
diff --git a/recipes-devtools/gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99319.patch b/recipes-devtools/gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99319.patch new file mode 100644 index 0000000000..a649c9542a --- /dev/null +++ b/recipes-devtools/gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99319.patch | |||
@@ -0,0 +1,197 @@ | |||
1 | 2010-07-24 Sandra Loosemore <sandra@codesourcery.com> | ||
2 | |||
3 | Backport from mainline: | ||
4 | |||
5 | 2010-04-10 Wei Guozhi <carrot@google.com> | ||
6 | |||
7 | PR target/42601 | ||
8 | gcc/ | ||
9 | * config/arm/arm.c (arm_pic_static_addr): New function. | ||
10 | (legitimize_pic_address): Call arm_pic_static_addr when it detects | ||
11 | a static symbol. | ||
12 | (arm_output_addr_const_extra): Output expression for new pattern. | ||
13 | * config/arm/arm.md (UNSPEC_SYMBOL_OFFSET): New unspec symbol. | ||
14 | |||
15 | 2010-07-22 Sandra Loosemore <sandra@codesourcery.com> | ||
16 | |||
17 | PR tree-optimization/39839 | ||
18 | gcc/testsuite/ | ||
19 | * gcc.target/arm/pr39839.c: New test case. | ||
20 | |||
21 | 2010-07-24 Jie Zhang <jie@codesourcery.com> | ||
22 | |||
23 | Issue #9079 | ||
24 | |||
25 | === modified file 'gcc/config/arm/arm.c' | ||
26 | --- old/gcc/config/arm/arm.c 2010-08-03 13:55:46 +0000 | ||
27 | +++ new/gcc/config/arm/arm.c 2010-08-05 12:06:40 +0000 | ||
28 | @@ -225,6 +225,7 @@ | ||
29 | static void arm_asm_trampoline_template (FILE *); | ||
30 | static void arm_trampoline_init (rtx, tree, rtx); | ||
31 | static rtx arm_trampoline_adjust_address (rtx); | ||
32 | +static rtx arm_pic_static_addr (rtx orig, rtx reg); | ||
33 | |||
34 | |||
35 | /* Table of machine attributes. */ | ||
36 | @@ -4986,29 +4987,16 @@ | ||
37 | { | ||
38 | rtx pic_ref, address; | ||
39 | rtx insn; | ||
40 | - int subregs = 0; | ||
41 | - | ||
42 | - /* If this function doesn't have a pic register, create one now. */ | ||
43 | - require_pic_register (); | ||
44 | |||
45 | if (reg == 0) | ||
46 | { | ||
47 | gcc_assert (can_create_pseudo_p ()); | ||
48 | reg = gen_reg_rtx (Pmode); | ||
49 | - | ||
50 | - subregs = 1; | ||
51 | + address = gen_reg_rtx (Pmode); | ||
52 | } | ||
53 | - | ||
54 | - if (subregs) | ||
55 | - address = gen_reg_rtx (Pmode); | ||
56 | else | ||
57 | address = reg; | ||
58 | |||
59 | - if (TARGET_32BIT) | ||
60 | - emit_insn (gen_pic_load_addr_32bit (address, orig)); | ||
61 | - else /* TARGET_THUMB1 */ | ||
62 | - emit_insn (gen_pic_load_addr_thumb1 (address, orig)); | ||
63 | - | ||
64 | /* VxWorks does not impose a fixed gap between segments; the run-time | ||
65 | gap can be different from the object-file gap. We therefore can't | ||
66 | use GOTOFF unless we are absolutely sure that the symbol is in the | ||
67 | @@ -5020,16 +5008,23 @@ | ||
68 | SYMBOL_REF_LOCAL_P (orig))) | ||
69 | && NEED_GOT_RELOC | ||
70 | && !TARGET_VXWORKS_RTP) | ||
71 | - pic_ref = gen_rtx_PLUS (Pmode, cfun->machine->pic_reg, address); | ||
72 | + insn = arm_pic_static_addr (orig, reg); | ||
73 | else | ||
74 | { | ||
75 | + /* If this function doesn't have a pic register, create one now. */ | ||
76 | + require_pic_register (); | ||
77 | + | ||
78 | + if (TARGET_32BIT) | ||
79 | + emit_insn (gen_pic_load_addr_32bit (address, orig)); | ||
80 | + else /* TARGET_THUMB1 */ | ||
81 | + emit_insn (gen_pic_load_addr_thumb1 (address, orig)); | ||
82 | + | ||
83 | pic_ref = gen_const_mem (Pmode, | ||
84 | gen_rtx_PLUS (Pmode, cfun->machine->pic_reg, | ||
85 | address)); | ||
86 | + insn = emit_move_insn (reg, pic_ref); | ||
87 | } | ||
88 | |||
89 | - insn = emit_move_insn (reg, pic_ref); | ||
90 | - | ||
91 | /* Put a REG_EQUAL note on this insn, so that it can be optimized | ||
92 | by loop. */ | ||
93 | set_unique_reg_note (insn, REG_EQUAL, orig); | ||
94 | @@ -5236,6 +5231,43 @@ | ||
95 | emit_use (pic_reg); | ||
96 | } | ||
97 | |||
98 | +/* Generate code to load the address of a static var when flag_pic is set. */ | ||
99 | +static rtx | ||
100 | +arm_pic_static_addr (rtx orig, rtx reg) | ||
101 | +{ | ||
102 | + rtx l1, labelno, offset_rtx, insn; | ||
103 | + | ||
104 | + gcc_assert (flag_pic); | ||
105 | + | ||
106 | + /* We use an UNSPEC rather than a LABEL_REF because this label | ||
107 | + never appears in the code stream. */ | ||
108 | + labelno = GEN_INT (pic_labelno++); | ||
109 | + l1 = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, labelno), UNSPEC_PIC_LABEL); | ||
110 | + l1 = gen_rtx_CONST (VOIDmode, l1); | ||
111 | + | ||
112 | + /* On the ARM the PC register contains 'dot + 8' at the time of the | ||
113 | + addition, on the Thumb it is 'dot + 4'. */ | ||
114 | + offset_rtx = plus_constant (l1, TARGET_ARM ? 8 : 4); | ||
115 | + offset_rtx = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, orig, offset_rtx), | ||
116 | + UNSPEC_SYMBOL_OFFSET); | ||
117 | + offset_rtx = gen_rtx_CONST (Pmode, offset_rtx); | ||
118 | + | ||
119 | + if (TARGET_32BIT) | ||
120 | + { | ||
121 | + emit_insn (gen_pic_load_addr_32bit (reg, offset_rtx)); | ||
122 | + if (TARGET_ARM) | ||
123 | + insn = emit_insn (gen_pic_add_dot_plus_eight (reg, reg, labelno)); | ||
124 | + else | ||
125 | + insn = emit_insn (gen_pic_add_dot_plus_four (reg, reg, labelno)); | ||
126 | + } | ||
127 | + else /* TARGET_THUMB1 */ | ||
128 | + { | ||
129 | + emit_insn (gen_pic_load_addr_thumb1 (reg, offset_rtx)); | ||
130 | + insn = emit_insn (gen_pic_add_dot_plus_four (reg, reg, labelno)); | ||
131 | + } | ||
132 | + | ||
133 | + return insn; | ||
134 | +} | ||
135 | |||
136 | /* Return nonzero if X is valid as an ARM state addressing register. */ | ||
137 | static int | ||
138 | @@ -21461,6 +21493,16 @@ | ||
139 | fputc (')', fp); | ||
140 | return TRUE; | ||
141 | } | ||
142 | + else if (GET_CODE (x) == UNSPEC && XINT (x, 1) == UNSPEC_SYMBOL_OFFSET) | ||
143 | + { | ||
144 | + output_addr_const (fp, XVECEXP (x, 0, 0)); | ||
145 | + if (GOT_PCREL) | ||
146 | + fputs ("+.", fp); | ||
147 | + fputs ("-(", fp); | ||
148 | + output_addr_const (fp, XVECEXP (x, 0, 1)); | ||
149 | + fputc (')', fp); | ||
150 | + return TRUE; | ||
151 | + } | ||
152 | else if (GET_CODE (x) == CONST_VECTOR) | ||
153 | return arm_emit_vector_const (fp, x); | ||
154 | |||
155 | |||
156 | === modified file 'gcc/config/arm/arm.md' | ||
157 | --- old/gcc/config/arm/arm.md 2010-07-30 14:17:05 +0000 | ||
158 | +++ new/gcc/config/arm/arm.md 2010-08-05 12:06:40 +0000 | ||
159 | @@ -101,6 +101,8 @@ | ||
160 | ; a given symbolic address. | ||
161 | (UNSPEC_THUMB1_CASESI 25) ; A Thumb1 compressed dispatch-table call. | ||
162 | (UNSPEC_RBIT 26) ; rbit operation. | ||
163 | + (UNSPEC_SYMBOL_OFFSET 27) ; The offset of the start of the symbol from | ||
164 | + ; another symbolic address. | ||
165 | ] | ||
166 | ) | ||
167 | |||
168 | |||
169 | === added file 'gcc/testsuite/gcc.target/arm/pr39839.c' | ||
170 | --- old/gcc/testsuite/gcc.target/arm/pr39839.c 1970-01-01 00:00:00 +0000 | ||
171 | +++ new/gcc/testsuite/gcc.target/arm/pr39839.c 2010-08-05 12:06:40 +0000 | ||
172 | @@ -0,0 +1,24 @@ | ||
173 | +/* { dg-options "-mthumb -Os -march=armv5te -mthumb-interwork -fpic" } */ | ||
174 | +/* { dg-require-effective-target arm_thumb1_ok } */ | ||
175 | +/* { dg-final { scan-assembler-not "str\[\\t \]*r.,\[\\t \]*.sp," } } */ | ||
176 | + | ||
177 | +struct S | ||
178 | +{ | ||
179 | + int count; | ||
180 | + char *addr; | ||
181 | +}; | ||
182 | + | ||
183 | +void func(const char*, const char*, int, const char*); | ||
184 | + | ||
185 | +/* This function should not need to spill to the stack. */ | ||
186 | +void test(struct S *p) | ||
187 | +{ | ||
188 | + int off = p->count; | ||
189 | + while (p->count >= 0) | ||
190 | + { | ||
191 | + const char *s = "xyz"; | ||
192 | + if (*p->addr) s = "pqr"; | ||
193 | + func("abcde", p->addr + off, off, s); | ||
194 | + p->count--; | ||
195 | + } | ||
196 | +} | ||
197 | |||