diff options
Diffstat (limited to 'meta-oe/recipes-devtools/gcc/gcc-4.6.0/linaro/gcc-4.6-linaro-r106754.patch')
-rw-r--r-- | meta-oe/recipes-devtools/gcc/gcc-4.6.0/linaro/gcc-4.6-linaro-r106754.patch | 329 |
1 files changed, 329 insertions, 0 deletions
diff --git a/meta-oe/recipes-devtools/gcc/gcc-4.6.0/linaro/gcc-4.6-linaro-r106754.patch b/meta-oe/recipes-devtools/gcc/gcc-4.6.0/linaro/gcc-4.6-linaro-r106754.patch new file mode 100644 index 000000000..b64991836 --- /dev/null +++ b/meta-oe/recipes-devtools/gcc/gcc-4.6.0/linaro/gcc-4.6-linaro-r106754.patch | |||
@@ -0,0 +1,329 @@ | |||
1 | 2011-06-07 Andrew Stubbs <ams@codesourcery.com> | ||
2 | |||
3 | Backport from FSF: | ||
4 | |||
5 | 2011-06-07 Andrew Stubbs <ams@codesourcery.com> | ||
6 | |||
7 | gcc/ | ||
8 | * config/arm/arm.md (*maddhidi4tb, *maddhidi4tt): New define_insns. | ||
9 | (*maddhisi4tb, *maddhisi4tt): New define_insns. | ||
10 | |||
11 | gcc/testsuite/ | ||
12 | * gcc.target/arm/smlatb-1.c: New file. | ||
13 | * gcc.target/arm/smlatt-1.c: New file. | ||
14 | * gcc.target/arm/smlaltb-1.c: New file. | ||
15 | * gcc.target/arm/smlaltt-1.c: New file. | ||
16 | |||
17 | 2011-06-07 Andrew Stubbs <ams@codesourcery.com> | ||
18 | |||
19 | Backport from FSF: | ||
20 | |||
21 | 2011-06-07 Bernd Schmidt <bernds@codesourcery.com> | ||
22 | Andrew Stubbs <ams@codesourcery.com> | ||
23 | |||
24 | gcc/ | ||
25 | * simplify-rtx.c (simplify_unary_operation_1): Canonicalize widening | ||
26 | multiplies. | ||
27 | * doc/md.texi (Canonicalization of Instructions): Document widening | ||
28 | multiply canonicalization. | ||
29 | |||
30 | gcc/testsuite/ | ||
31 | * gcc.target/arm/mla-2.c: New test. | ||
32 | |||
33 | === modified file 'gcc/config/arm/arm.md' | ||
34 | --- old/gcc/config/arm/arm.md 2011-05-13 13:42:39 +0000 | ||
35 | +++ new/gcc/config/arm/arm.md 2011-06-02 15:58:33 +0000 | ||
36 | @@ -1809,6 +1809,36 @@ | ||
37 | (set_attr "predicable" "yes")] | ||
38 | ) | ||
39 | |||
40 | +;; Note: there is no maddhisi4ibt because this one is canonical form | ||
41 | +(define_insn "*maddhisi4tb" | ||
42 | + [(set (match_operand:SI 0 "s_register_operand" "=r") | ||
43 | + (plus:SI (mult:SI (ashiftrt:SI | ||
44 | + (match_operand:SI 1 "s_register_operand" "r") | ||
45 | + (const_int 16)) | ||
46 | + (sign_extend:SI | ||
47 | + (match_operand:HI 2 "s_register_operand" "r"))) | ||
48 | + (match_operand:SI 3 "s_register_operand" "r")))] | ||
49 | + "TARGET_DSP_MULTIPLY" | ||
50 | + "smlatb%?\\t%0, %1, %2, %3" | ||
51 | + [(set_attr "insn" "smlaxy") | ||
52 | + (set_attr "predicable" "yes")] | ||
53 | +) | ||
54 | + | ||
55 | +(define_insn "*maddhisi4tt" | ||
56 | + [(set (match_operand:SI 0 "s_register_operand" "=r") | ||
57 | + (plus:SI (mult:SI (ashiftrt:SI | ||
58 | + (match_operand:SI 1 "s_register_operand" "r") | ||
59 | + (const_int 16)) | ||
60 | + (ashiftrt:SI | ||
61 | + (match_operand:SI 2 "s_register_operand" "r") | ||
62 | + (const_int 16))) | ||
63 | + (match_operand:SI 3 "s_register_operand" "r")))] | ||
64 | + "TARGET_DSP_MULTIPLY" | ||
65 | + "smlatt%?\\t%0, %1, %2, %3" | ||
66 | + [(set_attr "insn" "smlaxy") | ||
67 | + (set_attr "predicable" "yes")] | ||
68 | +) | ||
69 | + | ||
70 | (define_insn "*maddhidi4" | ||
71 | [(set (match_operand:DI 0 "s_register_operand" "=r") | ||
72 | (plus:DI | ||
73 | @@ -1822,6 +1852,39 @@ | ||
74 | [(set_attr "insn" "smlalxy") | ||
75 | (set_attr "predicable" "yes")]) | ||
76 | |||
77 | +;; Note: there is no maddhidi4ibt because this one is canonical form | ||
78 | +(define_insn "*maddhidi4tb" | ||
79 | + [(set (match_operand:DI 0 "s_register_operand" "=r") | ||
80 | + (plus:DI | ||
81 | + (mult:DI (sign_extend:DI | ||
82 | + (ashiftrt:SI | ||
83 | + (match_operand:SI 1 "s_register_operand" "r") | ||
84 | + (const_int 16))) | ||
85 | + (sign_extend:DI | ||
86 | + (match_operand:HI 2 "s_register_operand" "r"))) | ||
87 | + (match_operand:DI 3 "s_register_operand" "0")))] | ||
88 | + "TARGET_DSP_MULTIPLY" | ||
89 | + "smlaltb%?\\t%Q0, %R0, %1, %2" | ||
90 | + [(set_attr "insn" "smlalxy") | ||
91 | + (set_attr "predicable" "yes")]) | ||
92 | + | ||
93 | +(define_insn "*maddhidi4tt" | ||
94 | + [(set (match_operand:DI 0 "s_register_operand" "=r") | ||
95 | + (plus:DI | ||
96 | + (mult:DI (sign_extend:DI | ||
97 | + (ashiftrt:SI | ||
98 | + (match_operand:SI 1 "s_register_operand" "r") | ||
99 | + (const_int 16))) | ||
100 | + (sign_extend:DI | ||
101 | + (ashiftrt:SI | ||
102 | + (match_operand:SI 2 "s_register_operand" "r") | ||
103 | + (const_int 16)))) | ||
104 | + (match_operand:DI 3 "s_register_operand" "0")))] | ||
105 | + "TARGET_DSP_MULTIPLY" | ||
106 | + "smlaltt%?\\t%Q0, %R0, %1, %2" | ||
107 | + [(set_attr "insn" "smlalxy") | ||
108 | + (set_attr "predicable" "yes")]) | ||
109 | + | ||
110 | (define_expand "mulsf3" | ||
111 | [(set (match_operand:SF 0 "s_register_operand" "") | ||
112 | (mult:SF (match_operand:SF 1 "s_register_operand" "") | ||
113 | |||
114 | === modified file 'gcc/doc/md.texi' | ||
115 | --- old/gcc/doc/md.texi 2011-05-05 15:43:06 +0000 | ||
116 | +++ new/gcc/doc/md.texi 2011-06-07 11:18:20 +0000 | ||
117 | @@ -5929,6 +5929,23 @@ | ||
118 | will be written using @code{zero_extract} rather than the equivalent | ||
119 | @code{and} or @code{sign_extract} operations. | ||
120 | |||
121 | +@cindex @code{mult}, canonicalization of | ||
122 | +@item | ||
123 | +@code{(sign_extend:@var{m1} (mult:@var{m2} (sign_extend:@var{m2} @var{x}) | ||
124 | +(sign_extend:@var{m2} @var{y})))} is converted to @code{(mult:@var{m1} | ||
125 | +(sign_extend:@var{m1} @var{x}) (sign_extend:@var{m1} @var{y}))}, and likewise | ||
126 | +for @code{zero_extend}. | ||
127 | + | ||
128 | +@item | ||
129 | +@code{(sign_extend:@var{m1} (mult:@var{m2} (ashiftrt:@var{m2} | ||
130 | +@var{x} @var{s}) (sign_extend:@var{m2} @var{y})))} is converted | ||
131 | +to @code{(mult:@var{m1} (sign_extend:@var{m1} (ashiftrt:@var{m2} | ||
132 | +@var{x} @var{s})) (sign_extend:@var{m1} @var{y}))}, and likewise for | ||
133 | +patterns using @code{zero_extend} and @code{lshiftrt}. If the second | ||
134 | +operand of @code{mult} is also a shift, then that is extended also. | ||
135 | +This transformation is only applied when it can be proven that the | ||
136 | +original operation had sufficient precision to prevent overflow. | ||
137 | + | ||
138 | @end itemize | ||
139 | |||
140 | Further canonicalization rules are defined in the function | ||
141 | |||
142 | === modified file 'gcc/simplify-rtx.c' | ||
143 | --- old/gcc/simplify-rtx.c 2011-05-27 14:31:18 +0000 | ||
144 | +++ new/gcc/simplify-rtx.c 2011-06-02 12:32:16 +0000 | ||
145 | @@ -1000,6 +1000,48 @@ | ||
146 | && GET_CODE (XEXP (XEXP (op, 0), 1)) == LABEL_REF) | ||
147 | return XEXP (op, 0); | ||
148 | |||
149 | + /* Extending a widening multiplication should be canonicalized to | ||
150 | + a wider widening multiplication. */ | ||
151 | + if (GET_CODE (op) == MULT) | ||
152 | + { | ||
153 | + rtx lhs = XEXP (op, 0); | ||
154 | + rtx rhs = XEXP (op, 1); | ||
155 | + enum rtx_code lcode = GET_CODE (lhs); | ||
156 | + enum rtx_code rcode = GET_CODE (rhs); | ||
157 | + | ||
158 | + /* Widening multiplies usually extend both operands, but sometimes | ||
159 | + they use a shift to extract a portion of a register. */ | ||
160 | + if ((lcode == SIGN_EXTEND | ||
161 | + || (lcode == ASHIFTRT && CONST_INT_P (XEXP (lhs, 1)))) | ||
162 | + && (rcode == SIGN_EXTEND | ||
163 | + || (rcode == ASHIFTRT && CONST_INT_P (XEXP (rhs, 1))))) | ||
164 | + { | ||
165 | + enum machine_mode lmode = GET_MODE (lhs); | ||
166 | + enum machine_mode rmode = GET_MODE (rhs); | ||
167 | + int bits; | ||
168 | + | ||
169 | + if (lcode == ASHIFTRT) | ||
170 | + /* Number of bits not shifted off the end. */ | ||
171 | + bits = GET_MODE_PRECISION (lmode) - INTVAL (XEXP (lhs, 1)); | ||
172 | + else /* lcode == SIGN_EXTEND */ | ||
173 | + /* Size of inner mode. */ | ||
174 | + bits = GET_MODE_PRECISION (GET_MODE (XEXP (lhs, 0))); | ||
175 | + | ||
176 | + if (rcode == ASHIFTRT) | ||
177 | + bits += GET_MODE_PRECISION (rmode) - INTVAL (XEXP (rhs, 1)); | ||
178 | + else /* rcode == SIGN_EXTEND */ | ||
179 | + bits += GET_MODE_PRECISION (GET_MODE (XEXP (rhs, 0))); | ||
180 | + | ||
181 | + /* We can only widen multiplies if the result is mathematiclly | ||
182 | + equivalent. I.e. if overflow was impossible. */ | ||
183 | + if (bits <= GET_MODE_PRECISION (GET_MODE (op))) | ||
184 | + return simplify_gen_binary | ||
185 | + (MULT, mode, | ||
186 | + simplify_gen_unary (SIGN_EXTEND, mode, lhs, lmode), | ||
187 | + simplify_gen_unary (SIGN_EXTEND, mode, rhs, rmode)); | ||
188 | + } | ||
189 | + } | ||
190 | + | ||
191 | /* Check for a sign extension of a subreg of a promoted | ||
192 | variable, where the promotion is sign-extended, and the | ||
193 | target mode is the same as the variable's promotion. */ | ||
194 | @@ -1071,6 +1113,48 @@ | ||
195 | && GET_MODE_SIZE (mode) <= GET_MODE_SIZE (GET_MODE (XEXP (op, 0)))) | ||
196 | return rtl_hooks.gen_lowpart_no_emit (mode, op); | ||
197 | |||
198 | + /* Extending a widening multiplication should be canonicalized to | ||
199 | + a wider widening multiplication. */ | ||
200 | + if (GET_CODE (op) == MULT) | ||
201 | + { | ||
202 | + rtx lhs = XEXP (op, 0); | ||
203 | + rtx rhs = XEXP (op, 1); | ||
204 | + enum rtx_code lcode = GET_CODE (lhs); | ||
205 | + enum rtx_code rcode = GET_CODE (rhs); | ||
206 | + | ||
207 | + /* Widening multiplies usually extend both operands, but sometimes | ||
208 | + they use a shift to extract a portion of a register. */ | ||
209 | + if ((lcode == ZERO_EXTEND | ||
210 | + || (lcode == LSHIFTRT && CONST_INT_P (XEXP (lhs, 1)))) | ||
211 | + && (rcode == ZERO_EXTEND | ||
212 | + || (rcode == LSHIFTRT && CONST_INT_P (XEXP (rhs, 1))))) | ||
213 | + { | ||
214 | + enum machine_mode lmode = GET_MODE (lhs); | ||
215 | + enum machine_mode rmode = GET_MODE (rhs); | ||
216 | + int bits; | ||
217 | + | ||
218 | + if (lcode == LSHIFTRT) | ||
219 | + /* Number of bits not shifted off the end. */ | ||
220 | + bits = GET_MODE_PRECISION (lmode) - INTVAL (XEXP (lhs, 1)); | ||
221 | + else /* lcode == ZERO_EXTEND */ | ||
222 | + /* Size of inner mode. */ | ||
223 | + bits = GET_MODE_PRECISION (GET_MODE (XEXP (lhs, 0))); | ||
224 | + | ||
225 | + if (rcode == LSHIFTRT) | ||
226 | + bits += GET_MODE_PRECISION (rmode) - INTVAL (XEXP (rhs, 1)); | ||
227 | + else /* rcode == ZERO_EXTEND */ | ||
228 | + bits += GET_MODE_PRECISION (GET_MODE (XEXP (rhs, 0))); | ||
229 | + | ||
230 | + /* We can only widen multiplies if the result is mathematiclly | ||
231 | + equivalent. I.e. if overflow was impossible. */ | ||
232 | + if (bits <= GET_MODE_PRECISION (GET_MODE (op))) | ||
233 | + return simplify_gen_binary | ||
234 | + (MULT, mode, | ||
235 | + simplify_gen_unary (ZERO_EXTEND, mode, lhs, lmode), | ||
236 | + simplify_gen_unary (ZERO_EXTEND, mode, rhs, rmode)); | ||
237 | + } | ||
238 | + } | ||
239 | + | ||
240 | /* (zero_extend:M (zero_extend:N <X>)) is (zero_extend:M <X>). */ | ||
241 | if (GET_CODE (op) == ZERO_EXTEND) | ||
242 | return simplify_gen_unary (ZERO_EXTEND, mode, XEXP (op, 0), | ||
243 | |||
244 | === added file 'gcc/testsuite/gcc.target/arm/mla-2.c' | ||
245 | --- old/gcc/testsuite/gcc.target/arm/mla-2.c 1970-01-01 00:00:00 +0000 | ||
246 | +++ new/gcc/testsuite/gcc.target/arm/mla-2.c 2011-06-02 12:32:16 +0000 | ||
247 | @@ -0,0 +1,9 @@ | ||
248 | +/* { dg-do compile } */ | ||
249 | +/* { dg-options "-O2 -march=armv7-a" } */ | ||
250 | + | ||
251 | +long long foolong (long long x, short *a, short *b) | ||
252 | +{ | ||
253 | + return x + *a * *b; | ||
254 | +} | ||
255 | + | ||
256 | +/* { dg-final { scan-assembler "smlalbb" } } */ | ||
257 | |||
258 | === added file 'gcc/testsuite/gcc.target/arm/smlaltb-1.c' | ||
259 | --- old/gcc/testsuite/gcc.target/arm/smlaltb-1.c 1970-01-01 00:00:00 +0000 | ||
260 | +++ new/gcc/testsuite/gcc.target/arm/smlaltb-1.c 2011-06-02 15:58:33 +0000 | ||
261 | @@ -0,0 +1,13 @@ | ||
262 | +/* { dg-do compile } */ | ||
263 | +/* { dg-options "-O2 -march=armv7-a" } */ | ||
264 | + | ||
265 | +long long int | ||
266 | +foo (long long x, int in) | ||
267 | +{ | ||
268 | + short a = in & 0xffff; | ||
269 | + short b = (in & 0xffff0000) >> 16; | ||
270 | + | ||
271 | + return x + b * a; | ||
272 | +} | ||
273 | + | ||
274 | +/* { dg-final { scan-assembler "smlaltb" } } */ | ||
275 | |||
276 | === added file 'gcc/testsuite/gcc.target/arm/smlaltt-1.c' | ||
277 | --- old/gcc/testsuite/gcc.target/arm/smlaltt-1.c 1970-01-01 00:00:00 +0000 | ||
278 | +++ new/gcc/testsuite/gcc.target/arm/smlaltt-1.c 2011-06-02 15:58:33 +0000 | ||
279 | @@ -0,0 +1,13 @@ | ||
280 | +/* { dg-do compile } */ | ||
281 | +/* { dg-options "-O2 -march=armv7-a" } */ | ||
282 | + | ||
283 | +long long int | ||
284 | +foo (long long x, int in1, int in2) | ||
285 | +{ | ||
286 | + short a = (in1 & 0xffff0000) >> 16; | ||
287 | + short b = (in2 & 0xffff0000) >> 16; | ||
288 | + | ||
289 | + return x + b * a; | ||
290 | +} | ||
291 | + | ||
292 | +/* { dg-final { scan-assembler "smlaltt" } } */ | ||
293 | |||
294 | === added file 'gcc/testsuite/gcc.target/arm/smlatb-1.c' | ||
295 | --- old/gcc/testsuite/gcc.target/arm/smlatb-1.c 1970-01-01 00:00:00 +0000 | ||
296 | +++ new/gcc/testsuite/gcc.target/arm/smlatb-1.c 2011-06-02 15:58:33 +0000 | ||
297 | @@ -0,0 +1,13 @@ | ||
298 | +/* { dg-do compile } */ | ||
299 | +/* { dg-options "-O2 -march=armv7-a" } */ | ||
300 | + | ||
301 | +int | ||
302 | +foo (int x, int in) | ||
303 | +{ | ||
304 | + short a = in & 0xffff; | ||
305 | + short b = (in & 0xffff0000) >> 16; | ||
306 | + | ||
307 | + return x + b * a; | ||
308 | +} | ||
309 | + | ||
310 | +/* { dg-final { scan-assembler "smlatb" } } */ | ||
311 | |||
312 | === added file 'gcc/testsuite/gcc.target/arm/smlatt-1.c' | ||
313 | --- old/gcc/testsuite/gcc.target/arm/smlatt-1.c 1970-01-01 00:00:00 +0000 | ||
314 | +++ new/gcc/testsuite/gcc.target/arm/smlatt-1.c 2011-06-02 15:58:33 +0000 | ||
315 | @@ -0,0 +1,13 @@ | ||
316 | +/* { dg-do compile } */ | ||
317 | +/* { dg-options "-O2 -march=armv7-a" } */ | ||
318 | + | ||
319 | +int | ||
320 | +foo (int x, int in1, int in2) | ||
321 | +{ | ||
322 | + short a = (in1 & 0xffff0000) >> 16; | ||
323 | + short b = (in2 & 0xffff0000) >> 16; | ||
324 | + | ||
325 | + return x + b * a; | ||
326 | +} | ||
327 | + | ||
328 | +/* { dg-final { scan-assembler "smlatt" } } */ | ||
329 | |||