summaryrefslogtreecommitdiffstats
path: root/meta-oe/recipes-devtools/gcc/gcc-4.6.0/linaro/gcc-4.6-linaro-r106754.patch
diff options
context:
space:
mode:
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.patch329
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 @@
12011-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
172011-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