summaryrefslogtreecommitdiffstats
path: root/recipes-devtools/gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99301.patch
diff options
context:
space:
mode:
authorKoen Kooi <koen@dominion.thruhere.net>2010-11-02 22:03:58 +0100
committerKoen Kooi <koen@dominion.thruhere.net>2010-11-02 22:12:02 +0100
commitbe10a6b1321f250b1034c7d9d0a8ef18b296eef1 (patch)
tree9249025cbfbfbee4cc430d62b27f75301dd4dfde /recipes-devtools/gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99301.patch
parent93b28937ac67ba46d65f55637e42552e224aa7e2 (diff)
downloadmeta-openembedded-be10a6b1321f250b1034c7d9d0a8ef18b296eef1.tar.gz
angstrom-layers: meta-openembedded: replace poky gcc 4.5 sources with OE ones
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>
Diffstat (limited to 'recipes-devtools/gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99301.patch')
-rw-r--r--recipes-devtools/gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99301.patch675
1 files changed, 675 insertions, 0 deletions
diff --git a/recipes-devtools/gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99301.patch b/recipes-devtools/gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99301.patch
new file mode 100644
index 0000000000..95907eeb87
--- /dev/null
+++ b/recipes-devtools/gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99301.patch
@@ -0,0 +1,675 @@
1 2010-07-02 Daniel Jacobowitz <dan@codesourcery.com>
2 Julian Brown <julian@codesourcery.com>
3 Sandra Loosemore <sandra@codesourcery.com>
4
5 gcc/
6 * config/arm/arm.c (arm_canonicalize_comparison): Canonicalize DImode
7 comparisons. Adjust to take both operands.
8 (arm_select_cc_mode): Handle DImode comparisons.
9 (arm_gen_compare_reg): Generate a scratch register for DImode
10 comparisons which require one. Use xor for Thumb equality checks.
11 (arm_const_double_by_immediates): New.
12 (arm_print_operand): Allow 'Q' and 'R' for constants.
13 (get_arm_condition_code): Handle new CC_CZmode and CC_NCVmode.
14 * config/arm/arm.h (CANONICALIZE_COMPARISON): Always use
15 arm_canonicalize_comparison.
16 * config/arm/arm-modes.def: Add CC_CZmode and CC_NCVmode.
17 * config/arm/arm-protos.h (arm_canonicalize_comparison): Update
18 prototype.
19 (arm_const_double_by_immediates): Declare.
20 * config/arm/constraints.md (Di): New constraint.
21 * config/arm/predicates.md (arm_immediate_di_operand)
22 (arm_di_operand, cmpdi_operand): New.
23 * config/arm/arm.md (cbranchdi4): Handle non-Cirrus also.
24 (*arm_cmpdi_insn, *arm_cmpdi_unsigned)
25 (*arm_cmpdi_zero, *thumb_cmpdi_zero): New insns.
26 (cstoredi4): Handle non-Cirrus also.
27
28 gcc/testsuite/
29 * gcc.c-torture/execute/20100416-1.c: New test case.
30
312010-07-08 Sandra Loosemore <sandra@codesourcery.com>
32
33 Backport from upstream (originally from Sourcery G++ 4.4):
34
35 2010-07-02 Sandra Loosemore <sandra@codesourcery.com>
36
37 gcc/
38
39=== modified file 'gcc/config/arm/arm-modes.def'
40--- old/gcc/config/arm/arm-modes.def 2009-06-18 11:24:10 +0000
41+++ new/gcc/config/arm/arm-modes.def 2010-07-29 16:58:56 +0000
42@@ -35,10 +35,16 @@
43 CC_NOOVmode should be used with SImode integer equalities.
44 CC_Zmode should be used if only the Z flag is set correctly
45 CC_Nmode should be used if only the N (sign) flag is set correctly
46+ CC_CZmode should be used if only the C and Z flags are correct
47+ (used for DImode unsigned comparisons).
48+ CC_NCVmode should be used if only the N, C, and V flags are correct
49+ (used for DImode signed comparisons).
50 CCmode should be used otherwise. */
51
52 CC_MODE (CC_NOOV);
53 CC_MODE (CC_Z);
54+CC_MODE (CC_CZ);
55+CC_MODE (CC_NCV);
56 CC_MODE (CC_SWP);
57 CC_MODE (CCFP);
58 CC_MODE (CCFPE);
59
60=== modified file 'gcc/config/arm/arm-protos.h'
61--- old/gcc/config/arm/arm-protos.h 2009-11-11 14:23:03 +0000
62+++ new/gcc/config/arm/arm-protos.h 2010-07-29 16:58:56 +0000
63@@ -49,8 +49,7 @@
64 extern int const_ok_for_arm (HOST_WIDE_INT);
65 extern int arm_split_constant (RTX_CODE, enum machine_mode, rtx,
66 HOST_WIDE_INT, rtx, rtx, int);
67-extern RTX_CODE arm_canonicalize_comparison (RTX_CODE, enum machine_mode,
68- rtx *);
69+extern RTX_CODE arm_canonicalize_comparison (RTX_CODE, rtx *, rtx *);
70 extern int legitimate_pic_operand_p (rtx);
71 extern rtx legitimize_pic_address (rtx, enum machine_mode, rtx);
72 extern rtx legitimize_tls_address (rtx, rtx);
73@@ -116,6 +115,7 @@
74 extern void arm_reload_out_hi (rtx *);
75 extern int arm_const_double_inline_cost (rtx);
76 extern bool arm_const_double_by_parts (rtx);
77+extern bool arm_const_double_by_immediates (rtx);
78 extern const char *fp_immediate_constant (rtx);
79 extern void arm_emit_call_insn (rtx, rtx);
80 extern const char *output_call (rtx *);
81
82=== modified file 'gcc/config/arm/arm.c'
83--- old/gcc/config/arm/arm.c 2010-07-29 15:59:12 +0000
84+++ new/gcc/config/arm/arm.c 2010-07-29 16:58:56 +0000
85@@ -3190,13 +3190,82 @@
86 immediate value easier to load. */
87
88 enum rtx_code
89-arm_canonicalize_comparison (enum rtx_code code, enum machine_mode mode,
90- rtx * op1)
91+arm_canonicalize_comparison (enum rtx_code code, rtx *op0, rtx *op1)
92 {
93- unsigned HOST_WIDE_INT i = INTVAL (*op1);
94- unsigned HOST_WIDE_INT maxval;
95+ enum machine_mode mode;
96+ unsigned HOST_WIDE_INT i, maxval;
97+
98+ mode = GET_MODE (*op0);
99+ if (mode == VOIDmode)
100+ mode = GET_MODE (*op1);
101+
102 maxval = (((unsigned HOST_WIDE_INT) 1) << (GET_MODE_BITSIZE(mode) - 1)) - 1;
103
104+ /* For DImode, we have GE/LT/GEU/LTU comparisons. In ARM mode
105+ we can also use cmp/cmpeq for GTU/LEU. GT/LE must be either
106+ reversed or (for constant OP1) adjusted to GE/LT. Similarly
107+ for GTU/LEU in Thumb mode. */
108+ if (mode == DImode)
109+ {
110+ rtx tem;
111+
112+ /* To keep things simple, always use the Cirrus cfcmp64 if it is
113+ available. */
114+ if (TARGET_ARM && TARGET_HARD_FLOAT && TARGET_MAVERICK)
115+ return code;
116+
117+ if (code == GT || code == LE
118+ || (!TARGET_ARM && (code == GTU || code == LEU)))
119+ {
120+ /* Missing comparison. First try to use an available
121+ comparison. */
122+ if (GET_CODE (*op1) == CONST_INT)
123+ {
124+ i = INTVAL (*op1);
125+ switch (code)
126+ {
127+ case GT:
128+ case LE:
129+ if (i != maxval
130+ && arm_const_double_by_immediates (GEN_INT (i + 1)))
131+ {
132+ *op1 = GEN_INT (i + 1);
133+ return code == GT ? GE : LT;
134+ }
135+ break;
136+ case GTU:
137+ case LEU:
138+ if (i != ~((unsigned HOST_WIDE_INT) 0)
139+ && arm_const_double_by_immediates (GEN_INT (i + 1)))
140+ {
141+ *op1 = GEN_INT (i + 1);
142+ return code == GTU ? GEU : LTU;
143+ }
144+ break;
145+ default:
146+ gcc_unreachable ();
147+ }
148+ }
149+
150+ /* If that did not work, reverse the condition. */
151+ tem = *op0;
152+ *op0 = *op1;
153+ *op1 = tem;
154+ return swap_condition (code);
155+ }
156+
157+ return code;
158+ }
159+
160+ /* Comparisons smaller than DImode. Only adjust comparisons against
161+ an out-of-range constant. */
162+ if (GET_CODE (*op1) != CONST_INT
163+ || const_ok_for_arm (INTVAL (*op1))
164+ || const_ok_for_arm (- INTVAL (*op1)))
165+ return code;
166+
167+ i = INTVAL (*op1);
168+
169 switch (code)
170 {
171 case EQ:
172@@ -9912,6 +9981,55 @@
173 && (rtx_equal_p (XEXP (x, 0), y) || rtx_equal_p (XEXP (x, 1), y)))
174 return CC_Cmode;
175
176+ if (GET_MODE (x) == DImode || GET_MODE (y) == DImode)
177+ {
178+ /* To keep things simple, always use the Cirrus cfcmp64 if it is
179+ available. */
180+ if (TARGET_ARM && TARGET_HARD_FLOAT && TARGET_MAVERICK)
181+ return CCmode;
182+
183+ switch (op)
184+ {
185+ case EQ:
186+ case NE:
187+ /* A DImode comparison against zero can be implemented by
188+ or'ing the two halves together. */
189+ if (y == const0_rtx)
190+ return CC_Zmode;
191+
192+ /* We can do an equality test in three Thumb instructions. */
193+ if (!TARGET_ARM)
194+ return CC_Zmode;
195+
196+ /* FALLTHROUGH */
197+
198+ case LTU:
199+ case LEU:
200+ case GTU:
201+ case GEU:
202+ /* DImode unsigned comparisons can be implemented by cmp +
203+ cmpeq without a scratch register. Not worth doing in
204+ Thumb-2. */
205+ if (TARGET_ARM)
206+ return CC_CZmode;
207+
208+ /* FALLTHROUGH */
209+
210+ case LT:
211+ case LE:
212+ case GT:
213+ case GE:
214+ /* DImode signed and unsigned comparisons can be implemented
215+ by cmp + sbcs with a scratch register, but that does not
216+ set the Z flag - we must reverse GT/LE/GTU/LEU. */
217+ gcc_assert (op != EQ && op != NE);
218+ return CC_NCVmode;
219+
220+ default:
221+ gcc_unreachable ();
222+ }
223+ }
224+
225 return CCmode;
226 }
227
228@@ -9921,10 +10039,39 @@
229 rtx
230 arm_gen_compare_reg (enum rtx_code code, rtx x, rtx y)
231 {
232- enum machine_mode mode = SELECT_CC_MODE (code, x, y);
233- rtx cc_reg = gen_rtx_REG (mode, CC_REGNUM);
234-
235- emit_set_insn (cc_reg, gen_rtx_COMPARE (mode, x, y));
236+ enum machine_mode mode;
237+ rtx cc_reg;
238+ int dimode_comparison = GET_MODE (x) == DImode || GET_MODE (y) == DImode;
239+
240+ /* We might have X as a constant, Y as a register because of the predicates
241+ used for cmpdi. If so, force X to a register here. */
242+ if (dimode_comparison && !REG_P (x))
243+ x = force_reg (DImode, x);
244+
245+ mode = SELECT_CC_MODE (code, x, y);
246+ cc_reg = gen_rtx_REG (mode, CC_REGNUM);
247+
248+ if (dimode_comparison
249+ && !(TARGET_HARD_FLOAT && TARGET_MAVERICK)
250+ && mode != CC_CZmode)
251+ {
252+ rtx clobber, set;
253+
254+ /* To compare two non-zero values for equality, XOR them and
255+ then compare against zero. Not used for ARM mode; there
256+ CC_CZmode is cheaper. */
257+ if (mode == CC_Zmode && y != const0_rtx)
258+ {
259+ x = expand_binop (DImode, xor_optab, x, y, NULL_RTX, 0, OPTAB_WIDEN);
260+ y = const0_rtx;
261+ }
262+ /* A scratch register is required. */
263+ clobber = gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (SImode));
264+ set = gen_rtx_SET (VOIDmode, cc_reg, gen_rtx_COMPARE (mode, x, y));
265+ emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, set, clobber)));
266+ }
267+ else
268+ emit_set_insn (cc_reg, gen_rtx_COMPARE (mode, x, y));
269
270 return cc_reg;
271 }
272@@ -11253,6 +11400,34 @@
273 return false;
274 }
275
276+/* Return true if it is possible to inline both the high and low parts
277+ of a 64-bit constant into 32-bit data processing instructions. */
278+bool
279+arm_const_double_by_immediates (rtx val)
280+{
281+ enum machine_mode mode = GET_MODE (val);
282+ rtx part;
283+
284+ if (mode == VOIDmode)
285+ mode = DImode;
286+
287+ part = gen_highpart_mode (SImode, mode, val);
288+
289+ gcc_assert (GET_CODE (part) == CONST_INT);
290+
291+ if (!const_ok_for_arm (INTVAL (part)))
292+ return false;
293+
294+ part = gen_lowpart (SImode, val);
295+
296+ gcc_assert (GET_CODE (part) == CONST_INT);
297+
298+ if (!const_ok_for_arm (INTVAL (part)))
299+ return false;
300+
301+ return true;
302+}
303+
304 /* Scan INSN and note any of its operands that need fixing.
305 If DO_PUSHES is false we do not actually push any of the fixups
306 needed. The function returns TRUE if any fixups were needed/pushed.
307@@ -15097,8 +15272,18 @@
308 the value being loaded is big-wordian or little-wordian. The
309 order of the two register loads can matter however, if the address
310 of the memory location is actually held in one of the registers
311- being overwritten by the load. */
312+ being overwritten by the load.
313+
314+ The 'Q' and 'R' constraints are also available for 64-bit
315+ constants. */
316 case 'Q':
317+ if (GET_CODE (x) == CONST_INT || GET_CODE (x) == CONST_DOUBLE)
318+ {
319+ rtx part = gen_lowpart (SImode, x);
320+ fprintf (stream, "#" HOST_WIDE_INT_PRINT_DEC, INTVAL (part));
321+ return;
322+ }
323+
324 if (GET_CODE (x) != REG || REGNO (x) > LAST_ARM_REGNUM)
325 {
326 output_operand_lossage ("invalid operand for code '%c'", code);
327@@ -15109,6 +15294,18 @@
328 return;
329
330 case 'R':
331+ if (GET_CODE (x) == CONST_INT || GET_CODE (x) == CONST_DOUBLE)
332+ {
333+ enum machine_mode mode = GET_MODE (x);
334+ rtx part;
335+
336+ if (mode == VOIDmode)
337+ mode = DImode;
338+ part = gen_highpart_mode (SImode, mode, x);
339+ fprintf (stream, "#" HOST_WIDE_INT_PRINT_DEC, INTVAL (part));
340+ return;
341+ }
342+
343 if (GET_CODE (x) != REG || REGNO (x) > LAST_ARM_REGNUM)
344 {
345 output_operand_lossage ("invalid operand for code '%c'", code);
346@@ -15801,6 +15998,28 @@
347 default: gcc_unreachable ();
348 }
349
350+ case CC_CZmode:
351+ switch (comp_code)
352+ {
353+ case NE: return ARM_NE;
354+ case EQ: return ARM_EQ;
355+ case GEU: return ARM_CS;
356+ case GTU: return ARM_HI;
357+ case LEU: return ARM_LS;
358+ case LTU: return ARM_CC;
359+ default: gcc_unreachable ();
360+ }
361+
362+ case CC_NCVmode:
363+ switch (comp_code)
364+ {
365+ case GE: return ARM_GE;
366+ case LT: return ARM_LT;
367+ case GEU: return ARM_CS;
368+ case LTU: return ARM_CC;
369+ default: gcc_unreachable ();
370+ }
371+
372 case CCmode:
373 switch (comp_code)
374 {
375
376=== modified file 'gcc/config/arm/arm.h'
377--- old/gcc/config/arm/arm.h 2009-12-23 16:36:40 +0000
378+++ new/gcc/config/arm/arm.h 2010-07-29 16:58:56 +0000
379@@ -2253,19 +2253,7 @@
380 : reverse_condition (code))
381
382 #define CANONICALIZE_COMPARISON(CODE, OP0, OP1) \
383- do \
384- { \
385- if (GET_CODE (OP1) == CONST_INT \
386- && ! (const_ok_for_arm (INTVAL (OP1)) \
387- || (const_ok_for_arm (- INTVAL (OP1))))) \
388- { \
389- rtx const_op = OP1; \
390- CODE = arm_canonicalize_comparison ((CODE), GET_MODE (OP0), \
391- &const_op); \
392- OP1 = const_op; \
393- } \
394- } \
395- while (0)
396+ (CODE) = arm_canonicalize_comparison (CODE, &(OP0), &(OP1))
397
398 /* The arm5 clz instruction returns 32. */
399 #define CLZ_DEFINED_VALUE_AT_ZERO(MODE, VALUE) ((VALUE) = 32, 1)
400
401=== modified file 'gcc/config/arm/arm.md'
402--- old/gcc/config/arm/arm.md 2010-07-29 15:59:12 +0000
403+++ new/gcc/config/arm/arm.md 2010-07-29 16:58:56 +0000
404@@ -6718,17 +6718,45 @@
405 operands[3])); DONE;"
406 )
407
408-;; this uses the Cirrus DI compare instruction
409 (define_expand "cbranchdi4"
410 [(set (pc) (if_then_else
411 (match_operator 0 "arm_comparison_operator"
412- [(match_operand:DI 1 "cirrus_fp_register" "")
413- (match_operand:DI 2 "cirrus_fp_register" "")])
414+ [(match_operand:DI 1 "cmpdi_operand" "")
415+ (match_operand:DI 2 "cmpdi_operand" "")])
416 (label_ref (match_operand 3 "" ""))
417 (pc)))]
418- "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_MAVERICK"
419- "emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
420- operands[3])); DONE;"
421+ "TARGET_32BIT"
422+ "{
423+ rtx swap = NULL_RTX;
424+ enum rtx_code code = GET_CODE (operands[0]);
425+
426+ /* We should not have two constants. */
427+ gcc_assert (GET_MODE (operands[1]) == DImode
428+ || GET_MODE (operands[2]) == DImode);
429+
430+ /* Flip unimplemented DImode comparisons to a form that
431+ arm_gen_compare_reg can handle. */
432+ switch (code)
433+ {
434+ case GT:
435+ swap = gen_rtx_LT (VOIDmode, operands[2], operands[1]); break;
436+ case LE:
437+ swap = gen_rtx_GE (VOIDmode, operands[2], operands[1]); break;
438+ case GTU:
439+ swap = gen_rtx_LTU (VOIDmode, operands[2], operands[1]); break;
440+ case LEU:
441+ swap = gen_rtx_GEU (VOIDmode, operands[2], operands[1]); break;
442+ default:
443+ break;
444+ }
445+ if (swap)
446+ emit_jump_insn (gen_cbranch_cc (swap, operands[2], operands[1],
447+ operands[3]));
448+ else
449+ emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
450+ operands[3]));
451+ DONE;
452+ }"
453 )
454
455 (define_insn "*cbranchsi4_insn"
456@@ -7880,6 +7908,52 @@
457 (const_string "alu_shift_reg")))]
458 )
459
460+;; DImode comparisons. The generic code generates branches that
461+;; if-conversion can not reduce to a conditional compare, so we do
462+;; that directly.
463+
464+(define_insn "*arm_cmpdi_insn"
465+ [(set (reg:CC_NCV CC_REGNUM)
466+ (compare:CC_NCV (match_operand:DI 0 "s_register_operand" "r")
467+ (match_operand:DI 1 "arm_di_operand" "rDi")))
468+ (clobber (match_scratch:SI 2 "=r"))]
469+ "TARGET_32BIT && !(TARGET_HARD_FLOAT && TARGET_MAVERICK)"
470+ "cmp\\t%Q0, %Q1\;sbcs\\t%2, %R0, %R1"
471+ [(set_attr "conds" "set")
472+ (set_attr "length" "8")]
473+)
474+
475+(define_insn "*arm_cmpdi_unsigned"
476+ [(set (reg:CC_CZ CC_REGNUM)
477+ (compare:CC_CZ (match_operand:DI 0 "s_register_operand" "r")
478+ (match_operand:DI 1 "arm_di_operand" "rDi")))]
479+ "TARGET_ARM"
480+ "cmp%?\\t%R0, %R1\;cmpeq\\t%Q0, %Q1"
481+ [(set_attr "conds" "set")
482+ (set_attr "length" "8")]
483+)
484+
485+(define_insn "*arm_cmpdi_zero"
486+ [(set (reg:CC_Z CC_REGNUM)
487+ (compare:CC_Z (match_operand:DI 0 "s_register_operand" "r")
488+ (const_int 0)))
489+ (clobber (match_scratch:SI 1 "=r"))]
490+ "TARGET_32BIT"
491+ "orr%.\\t%1, %Q0, %R0"
492+ [(set_attr "conds" "set")]
493+)
494+
495+(define_insn "*thumb_cmpdi_zero"
496+ [(set (reg:CC_Z CC_REGNUM)
497+ (compare:CC_Z (match_operand:DI 0 "s_register_operand" "l")
498+ (const_int 0)))
499+ (clobber (match_scratch:SI 1 "=l"))]
500+ "TARGET_THUMB1"
501+ "orr\\t%1, %Q0, %R0"
502+ [(set_attr "conds" "set")
503+ (set_attr "length" "2")]
504+)
505+
506 ;; Cirrus SF compare instruction
507 (define_insn "*cirrus_cmpsf"
508 [(set (reg:CCFP CC_REGNUM)
509@@ -8183,18 +8257,45 @@
510 operands[2], operands[3])); DONE;"
511 )
512
513-;; this uses the Cirrus DI compare instruction
514 (define_expand "cstoredi4"
515 [(set (match_operand:SI 0 "s_register_operand" "")
516 (match_operator:SI 1 "arm_comparison_operator"
517- [(match_operand:DI 2 "cirrus_fp_register" "")
518- (match_operand:DI 3 "cirrus_fp_register" "")]))]
519- "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_MAVERICK"
520- "emit_insn (gen_cstore_cc (operands[0], operands[1],
521- operands[2], operands[3])); DONE;"
522+ [(match_operand:DI 2 "cmpdi_operand" "")
523+ (match_operand:DI 3 "cmpdi_operand" "")]))]
524+ "TARGET_32BIT"
525+ "{
526+ rtx swap = NULL_RTX;
527+ enum rtx_code code = GET_CODE (operands[1]);
528+
529+ /* We should not have two constants. */
530+ gcc_assert (GET_MODE (operands[2]) == DImode
531+ || GET_MODE (operands[3]) == DImode);
532+
533+ /* Flip unimplemented DImode comparisons to a form that
534+ arm_gen_compare_reg can handle. */
535+ switch (code)
536+ {
537+ case GT:
538+ swap = gen_rtx_LT (VOIDmode, operands[3], operands[2]); break;
539+ case LE:
540+ swap = gen_rtx_GE (VOIDmode, operands[3], operands[2]); break;
541+ case GTU:
542+ swap = gen_rtx_LTU (VOIDmode, operands[3], operands[2]); break;
543+ case LEU:
544+ swap = gen_rtx_GEU (VOIDmode, operands[3], operands[2]); break;
545+ default:
546+ break;
547+ }
548+ if (swap)
549+ emit_insn (gen_cstore_cc (operands[0], swap, operands[3],
550+ operands[2]));
551+ else
552+ emit_insn (gen_cstore_cc (operands[0], operands[1], operands[2],
553+ operands[3]));
554+ DONE;
555+ }"
556 )
557
558-
559 (define_expand "cstoresi_eq0_thumb1"
560 [(parallel
561 [(set (match_operand:SI 0 "s_register_operand" "")
562
563=== modified file 'gcc/config/arm/constraints.md'
564--- old/gcc/config/arm/constraints.md 2009-12-07 20:34:53 +0000
565+++ new/gcc/config/arm/constraints.md 2010-07-29 16:58:56 +0000
566@@ -29,7 +29,7 @@
567 ;; in Thumb-1 state: I, J, K, L, M, N, O
568
569 ;; The following multi-letter normal constraints have been used:
570-;; in ARM/Thumb-2 state: Da, Db, Dc, Dn, Dl, DL, Dv, Dy
571+;; in ARM/Thumb-2 state: Da, Db, Dc, Dn, Dl, DL, Dv, Dy, Di
572 ;; in Thumb-1 state: Pa, Pb
573 ;; in Thumb-2 state: Ps, Pt
574
575@@ -191,6 +191,13 @@
576 (match_test "TARGET_32BIT && arm_const_double_inline_cost (op) == 4
577 && !(optimize_size || arm_ld_sched)")))
578
579+(define_constraint "Di"
580+ "@internal
581+ In ARM/Thumb-2 state a const_int or const_double where both the high
582+ and low SImode words can be generated as immediates in 32-bit instructions."
583+ (and (match_code "const_double,const_int")
584+ (match_test "TARGET_32BIT && arm_const_double_by_immediates (op)")))
585+
586 (define_constraint "Dn"
587 "@internal
588 In ARM/Thumb-2 state a const_vector which can be loaded with a Neon vmov
589
590=== modified file 'gcc/config/arm/predicates.md'
591--- old/gcc/config/arm/predicates.md 2010-07-29 15:59:12 +0000
592+++ new/gcc/config/arm/predicates.md 2010-07-29 16:58:56 +0000
593@@ -86,6 +86,12 @@
594 (and (match_code "const_int")
595 (match_test "const_ok_for_arm (INTVAL (op))")))
596
597+;; A constant value which fits into two instructions, each taking
598+;; an arithmetic constant operand for one of the words.
599+(define_predicate "arm_immediate_di_operand"
600+ (and (match_code "const_int,const_double")
601+ (match_test "arm_const_double_by_immediates (op)")))
602+
603 (define_predicate "arm_neg_immediate_operand"
604 (and (match_code "const_int")
605 (match_test "const_ok_for_arm (-INTVAL (op))")))
606@@ -115,6 +121,10 @@
607 (ior (match_operand 0 "arm_rhs_operand")
608 (match_operand 0 "arm_not_immediate_operand")))
609
610+(define_predicate "arm_di_operand"
611+ (ior (match_operand 0 "s_register_operand")
612+ (match_operand 0 "arm_immediate_di_operand")))
613+
614 ;; True if the operand is a memory reference which contains an
615 ;; offsettable address.
616 (define_predicate "offsettable_memory_operand"
617@@ -522,4 +532,12 @@
618 (define_predicate "neon_lane_number"
619 (and (match_code "const_int")
620 (match_test "INTVAL (op) >= 0 && INTVAL (op) <= 7")))
621+;; Predicates for named expanders that overlap multiple ISAs.
622+
623+(define_predicate "cmpdi_operand"
624+ (if_then_else (match_test "TARGET_HARD_FLOAT && TARGET_MAVERICK")
625+ (and (match_test "TARGET_ARM")
626+ (match_operand 0 "cirrus_fp_register"))
627+ (and (match_test "TARGET_32BIT")
628+ (match_operand 0 "arm_di_operand"))))
629
630
631=== added file 'gcc/testsuite/gcc.c-torture/execute/20100416-1.c'
632--- old/gcc/testsuite/gcc.c-torture/execute/20100416-1.c 1970-01-01 00:00:00 +0000
633+++ new/gcc/testsuite/gcc.c-torture/execute/20100416-1.c 2010-07-29 16:58:56 +0000
634@@ -0,0 +1,40 @@
635+void abort(void);
636+
637+int
638+movegt(int x, int y, long long a)
639+{
640+ int i;
641+ int ret = 0;
642+ for (i = 0; i < y; i++)
643+ {
644+ if (a >= (long long) 0xf000000000000000LL)
645+ ret = x;
646+ else
647+ ret = y;
648+ }
649+ return ret;
650+}
651+
652+struct test
653+{
654+ long long val;
655+ int ret;
656+} tests[] = {
657+ { 0xf000000000000000LL, -1 },
658+ { 0xefffffffffffffffLL, 1 },
659+ { 0xf000000000000001LL, -1 },
660+ { 0x0000000000000000LL, -1 },
661+ { 0x8000000000000000LL, 1 },
662+};
663+
664+int
665+main()
666+{
667+ int i;
668+ for (i = 0; i < sizeof (tests) / sizeof (tests[0]); i++)
669+ {
670+ if (movegt (-1, 1, tests[i].val) != tests[i].ret)
671+ abort ();
672+ }
673+ return 0;
674+}
675