OSDN Git Service

2d5003bcfee277d2235eb3b791bef99b2be9b728
[pf3gnuchains/gcc-fork.git] / gcc / config / arm / arm.md
1 ;;- Machine description for ARM for GNU compiler
2 ;;  Copyright 1991, 1993, 1994, 1995, 1996, 1996, 1997, 1998, 1999, 2000,
3 ;;  2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
4 ;;  Free Software Foundation, Inc.
5 ;;  Contributed by Pieter `Tiggr' Schoenmakers (rcpieter@win.tue.nl)
6 ;;  and Martin Simmons (@harleqn.co.uk).
7 ;;  More major hacks by Richard Earnshaw (rearnsha@arm.com).
8
9 ;; This file is part of GCC.
10
11 ;; GCC is free software; you can redistribute it and/or modify it
12 ;; under the terms of the GNU General Public License as published
13 ;; by the Free Software Foundation; either version 3, or (at your
14 ;; option) any later version.
15
16 ;; GCC is distributed in the hope that it will be useful, but WITHOUT
17 ;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
18 ;; or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
19 ;; License for more details.
20
21 ;; You should have received a copy of the GNU General Public License
22 ;; along with GCC; see the file COPYING3.  If not see
23 ;; <http://www.gnu.org/licenses/>.
24
25 ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
26
27 \f
28 ;;---------------------------------------------------------------------------
29 ;; Constants
30
31 ;; Register numbers
32 (define_constants
33   [(R0_REGNUM        0)         ; First CORE register
34    (IP_REGNUM       12)         ; Scratch register
35    (SP_REGNUM       13)         ; Stack pointer
36    (LR_REGNUM       14)         ; Return address register
37    (PC_REGNUM       15)         ; Program counter
38    (CC_REGNUM       24)         ; Condition code pseudo register
39    (LAST_ARM_REGNUM 15)         ;
40    (FPA_F0_REGNUM   16)         ; FIRST_FPA_REGNUM
41    (FPA_F7_REGNUM   23)         ; LAST_FPA_REGNUM
42   ]
43 )
44 ;; 3rd operand to select_dominance_cc_mode
45 (define_constants
46   [(DOM_CC_X_AND_Y  0)
47    (DOM_CC_NX_OR_Y  1)
48    (DOM_CC_X_OR_Y   2)
49   ]
50 )
51
52 ;; UNSPEC Usage:
53 ;; Note: sin and cos are no-longer used.
54 ;; Unspec constants for Neon are defined in neon.md.
55
56 (define_constants
57   [(UNSPEC_SIN       0) ; `sin' operation (MODE_FLOAT):
58                         ;   operand 0 is the result,
59                         ;   operand 1 the parameter.
60    (UNPSEC_COS       1) ; `cos' operation (MODE_FLOAT):
61                         ;   operand 0 is the result,
62                         ;   operand 1 the parameter.
63    (UNSPEC_PUSH_MULT 2) ; `push multiple' operation:
64                         ;   operand 0 is the first register,
65                         ;   subsequent registers are in parallel (use ...)
66                         ;   expressions.
67    (UNSPEC_PIC_SYM   3) ; A symbol that has been treated properly for pic
68                         ;   usage, that is, we will add the pic_register
69                         ;   value to it before trying to dereference it.
70    (UNSPEC_PIC_BASE  4) ; Add PC and all but the last operand together,
71                         ;   The last operand is the number of a PIC_LABEL
72                         ;   that points at the containing instruction.
73    (UNSPEC_PRLG_STK  5) ; A special barrier that prevents frame accesses 
74                         ;   being scheduled before the stack adjustment insn.
75    (UNSPEC_PROLOGUE_USE 6) ; As USE insns are not meaningful after reload,
76                         ; this unspec is used to prevent the deletion of
77                         ; instructions setting registers for EH handling
78                         ; and stack frame generation.  Operand 0 is the
79                         ; register to "use".
80    (UNSPEC_CHECK_ARCH 7); Set CCs to indicate 26-bit or 32-bit mode.
81    (UNSPEC_WSHUFH    8) ; Used by the intrinsic form of the iWMMXt WSHUFH instruction.
82    (UNSPEC_WACC      9) ; Used by the intrinsic form of the iWMMXt WACC instruction.
83    (UNSPEC_TMOVMSK  10) ; Used by the intrinsic form of the iWMMXt TMOVMSK instruction.
84    (UNSPEC_WSAD     11) ; Used by the intrinsic form of the iWMMXt WSAD instruction.
85    (UNSPEC_WSADZ    12) ; Used by the intrinsic form of the iWMMXt WSADZ instruction.
86    (UNSPEC_WMACS    13) ; Used by the intrinsic form of the iWMMXt WMACS instruction.
87    (UNSPEC_WMACU    14) ; Used by the intrinsic form of the iWMMXt WMACU instruction.
88    (UNSPEC_WMACSZ   15) ; Used by the intrinsic form of the iWMMXt WMACSZ instruction.
89    (UNSPEC_WMACUZ   16) ; Used by the intrinsic form of the iWMMXt WMACUZ instruction.
90    (UNSPEC_CLRDI    17) ; Used by the intrinsic form of the iWMMXt CLRDI instruction.
91    (UNSPEC_WMADDS   18) ; Used by the intrinsic form of the iWMMXt WMADDS instruction.
92    (UNSPEC_WMADDU   19) ; Used by the intrinsic form of the iWMMXt WMADDU instruction.
93    (UNSPEC_TLS      20) ; A symbol that has been treated properly for TLS usage.
94    (UNSPEC_PIC_LABEL 21) ; A label used for PIC access that does not appear in the
95                          ; instruction stream.
96    (UNSPEC_STACK_ALIGN 22) ; Doubleword aligned stack pointer.  Used to
97                            ; generate correct unwind information.
98    (UNSPEC_PIC_OFFSET 23) ; A symbolic 12-bit OFFSET that has been treated
99                           ; correctly for PIC usage.
100    (UNSPEC_GOTSYM_OFF 24) ; The offset of the start of the the GOT from a
101                           ; a given symbolic address.
102    (UNSPEC_THUMB1_CASESI 25) ; A Thumb1 compressed dispatch-table call.
103    (UNSPEC_RBIT 26)       ; rbit operation.
104    (UNSPEC_SYMBOL_OFFSET 27) ; The offset of the start of the symbol from
105                              ; another symbolic address.
106   ]
107 )
108
109 ;; UNSPEC_VOLATILE Usage:
110
111 (define_constants
112   [(VUNSPEC_BLOCKAGE 0) ; `blockage' insn to prevent scheduling across an
113                         ;   insn in the code.
114    (VUNSPEC_EPILOGUE 1) ; `epilogue' insn, used to represent any part of the
115                         ;   instruction epilogue sequence that isn't expanded
116                         ;   into normal RTL.  Used for both normal and sibcall
117                         ;   epilogues.
118    (VUNSPEC_ALIGN    2) ; `align' insn.  Used at the head of a minipool table 
119                         ;   for inlined constants.
120    (VUNSPEC_POOL_END 3) ; `end-of-table'.  Used to mark the end of a minipool
121                         ;   table.
122    (VUNSPEC_POOL_1   4) ; `pool-entry(1)'.  An entry in the constant pool for
123                         ;   an 8-bit object.
124    (VUNSPEC_POOL_2   5) ; `pool-entry(2)'.  An entry in the constant pool for
125                         ;   a 16-bit object.
126    (VUNSPEC_POOL_4   6) ; `pool-entry(4)'.  An entry in the constant pool for
127                         ;   a 32-bit object.
128    (VUNSPEC_POOL_8   7) ; `pool-entry(8)'.  An entry in the constant pool for
129                         ;   a 64-bit object.
130    (VUNSPEC_POOL_16  8) ; `pool-entry(16)'.  An entry in the constant pool for
131                         ;   a 128-bit object.
132    (VUNSPEC_TMRC     9) ; Used by the iWMMXt TMRC instruction.
133    (VUNSPEC_TMCR     10) ; Used by the iWMMXt TMCR instruction.
134    (VUNSPEC_ALIGN8   11) ; 8-byte alignment version of VUNSPEC_ALIGN
135    (VUNSPEC_WCMP_EQ  12) ; Used by the iWMMXt WCMPEQ instructions
136    (VUNSPEC_WCMP_GTU 13) ; Used by the iWMMXt WCMPGTU instructions
137    (VUNSPEC_WCMP_GT  14) ; Used by the iwMMXT WCMPGT instructions
138    (VUNSPEC_EH_RETURN 20); Use to override the return address for exception
139                          ; handling.
140   ]
141 )
142 \f
143 ;;---------------------------------------------------------------------------
144 ;; Attributes
145
146 ; IS_THUMB is set to 'yes' when we are generating Thumb code, and 'no' when
147 ; generating ARM code.  This is used to control the length of some insn
148 ; patterns that share the same RTL in both ARM and Thumb code.
149 (define_attr "is_thumb" "no,yes" (const (symbol_ref "thumb_code")))
150
151 ;; Operand number of an input operand that is shifted.  Zero if the
152 ;; given instruction does not shift one of its input operands.
153 (define_attr "shift" "" (const_int 0))
154
155 ; Floating Point Unit.  If we only have floating point emulation, then there
156 ; is no point in scheduling the floating point insns.  (Well, for best
157 ; performance we should try and group them together).
158 (define_attr "fpu" "none,fpa,fpe2,fpe3,maverick,vfp"
159   (const (symbol_ref "arm_fpu_attr")))
160
161 ; LENGTH of an instruction (in bytes)
162 (define_attr "length" "" (const_int 4))
163
164 ; POOL_RANGE is how far away from a constant pool entry that this insn
165 ; can be placed.  If the distance is zero, then this insn will never
166 ; reference the pool.
167 ; NEG_POOL_RANGE is nonzero for insns that can reference a constant pool entry
168 ; before its address.
169 (define_attr "pool_range" "" (const_int 0))
170 (define_attr "neg_pool_range" "" (const_int 0))
171
172 ; An assembler sequence may clobber the condition codes without us knowing.
173 ; If such an insn references the pool, then we have no way of knowing how,
174 ; so use the most conservative value for pool_range.
175 (define_asm_attributes
176  [(set_attr "conds" "clob")
177   (set_attr "length" "4")
178   (set_attr "pool_range" "250")])
179
180 ;; The instruction used to implement a particular pattern.  This
181 ;; information is used by pipeline descriptions to provide accurate
182 ;; scheduling information.
183
184 (define_attr "insn"
185         "mov,mvn,smulxy,smlaxy,smlalxy,smulwy,smlawx,mul,muls,mla,mlas,umull,umulls,umlal,umlals,smull,smulls,smlal,smlals,smlawy,smuad,smuadx,smlad,smladx,smusd,smusdx,smlsd,smlsdx,smmul,smmulr,smmla,umaal,smlald,smlsld,clz,mrs,msr,xtab,sdiv,udiv,other"
186         (const_string "other"))
187
188 ; TYPE attribute is used to detect floating point instructions which, if
189 ; running on a co-processor can run in parallel with other, basic instructions
190 ; If write-buffer scheduling is enabled then it can also be used in the
191 ; scheduling of writes.
192
193 ; Classification of each insn
194 ; Note: vfp.md has different meanings for some of these, and some further
195 ; types as well.  See that file for details.
196 ; alu           any alu  instruction that doesn't hit memory or fp
197 ;               regs or have a shifted source operand
198 ; alu_shift     any data instruction that doesn't hit memory or fp
199 ;               regs, but has a source operand shifted by a constant
200 ; alu_shift_reg any data instruction that doesn't hit memory or fp
201 ;               regs, but has a source operand shifted by a register value
202 ; mult          a multiply instruction
203 ; block         blockage insn, this blocks all functional units
204 ; float         a floating point arithmetic operation (subject to expansion)
205 ; fdivd         DFmode floating point division
206 ; fdivs         SFmode floating point division
207 ; fmul          Floating point multiply
208 ; ffmul         Fast floating point multiply
209 ; farith        Floating point arithmetic (4 cycle)
210 ; ffarith       Fast floating point arithmetic (2 cycle)
211 ; float_em      a floating point arithmetic operation that is normally emulated
212 ;               even on a machine with an fpa.
213 ; f_load        a floating point load from memory
214 ; f_store       a floating point store to memory
215 ; f_load[sd]    single/double load from memory
216 ; f_store[sd]   single/double store to memory
217 ; f_flag        a transfer of co-processor flags to the CPSR
218 ; f_mem_r       a transfer of a floating point register to a real reg via mem
219 ; r_mem_f       the reverse of f_mem_r
220 ; f_2_r         fast transfer float to arm (no memory needed)
221 ; r_2_f         fast transfer arm to float
222 ; f_cvt         convert floating<->integral
223 ; branch        a branch
224 ; call          a subroutine call
225 ; load_byte     load byte(s) from memory to arm registers
226 ; load1         load 1 word from memory to arm registers
227 ; load2         load 2 words from memory to arm registers
228 ; load3         load 3 words from memory to arm registers
229 ; load4         load 4 words from memory to arm registers
230 ; store         store 1 word to memory from arm registers
231 ; store2        store 2 words
232 ; store3        store 3 words
233 ; store4        store 4 (or more) words
234 ;  Additions for Cirrus Maverick co-processor:
235 ; mav_farith    Floating point arithmetic (4 cycle)
236 ; mav_dmult     Double multiplies (7 cycle)
237 ;
238
239 (define_attr "type"
240         "alu,alu_shift,alu_shift_reg,mult,block,float,fdivx,fdivd,fdivs,fmul,fmuls,fmuld,fmacs,fmacd,ffmul,farith,ffarith,f_flag,float_em,f_load,f_store,f_loads,f_loadd,f_stores,f_stored,f_mem_r,r_mem_f,f_2_r,r_2_f,f_cvt,branch,call,load_byte,load1,load2,load3,load4,store1,store2,store3,store4,mav_farith,mav_dmult,fconsts,fconstd,fadds,faddd,ffariths,ffarithd,fcmps,fcmpd,fcpys"
241         (if_then_else 
242          (eq_attr "insn" "smulxy,smlaxy,smlalxy,smulwy,smlawx,mul,muls,mla,mlas,umull,umulls,umlal,umlals,smull,smulls,smlal,smlals")
243          (const_string "mult")
244          (const_string "alu")))
245
246 ; Load scheduling, set from the arm_ld_sched variable
247 ; initialized by arm_override_options() 
248 (define_attr "ldsched" "no,yes" (const (symbol_ref "arm_ld_sched")))
249
250 ;; Classification of NEON instructions for scheduling purposes.
251 ;; Do not set this attribute and the "type" attribute together in
252 ;; any one instruction pattern.
253 (define_attr "neon_type"
254    "neon_int_1,\
255    neon_int_2,\
256    neon_int_3,\
257    neon_int_4,\
258    neon_int_5,\
259    neon_vqneg_vqabs,\
260    neon_vmov,\
261    neon_vaba,\
262    neon_vsma,\
263    neon_vaba_qqq,\
264    neon_mul_ddd_8_16_qdd_16_8_long_32_16_long,\
265    neon_mul_qqq_8_16_32_ddd_32,\
266    neon_mul_qdd_64_32_long_qqd_16_ddd_32_scalar_64_32_long_scalar,\
267    neon_mla_ddd_8_16_qdd_16_8_long_32_16_long,\
268    neon_mla_qqq_8_16,\
269    neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long,\
270    neon_mla_qqq_32_qqd_32_scalar,\
271    neon_mul_ddd_16_scalar_32_16_long_scalar,\
272    neon_mul_qqd_32_scalar,\
273    neon_mla_ddd_16_scalar_qdd_32_16_long_scalar,\
274    neon_shift_1,\
275    neon_shift_2,\
276    neon_shift_3,\
277    neon_vshl_ddd,\
278    neon_vqshl_vrshl_vqrshl_qqq,\
279    neon_vsra_vrsra,\
280    neon_fp_vadd_ddd_vabs_dd,\
281    neon_fp_vadd_qqq_vabs_qq,\
282    neon_fp_vsum,\
283    neon_fp_vmul_ddd,\
284    neon_fp_vmul_qqd,\
285    neon_fp_vmla_ddd,\
286    neon_fp_vmla_qqq,\
287    neon_fp_vmla_ddd_scalar,\
288    neon_fp_vmla_qqq_scalar,\
289    neon_fp_vrecps_vrsqrts_ddd,\
290    neon_fp_vrecps_vrsqrts_qqq,\
291    neon_bp_simple,\
292    neon_bp_2cycle,\
293    neon_bp_3cycle,\
294    neon_ldr,\
295    neon_str,\
296    neon_vld1_1_2_regs,\
297    neon_vld1_3_4_regs,\
298    neon_vld2_2_regs_vld1_vld2_all_lanes,\
299    neon_vld2_4_regs,\
300    neon_vld3_vld4,\
301    neon_vst1_1_2_regs_vst2_2_regs,\
302    neon_vst1_3_4_regs,\
303    neon_vst2_4_regs_vst3_vst4,\
304    neon_vst3_vst4,\
305    neon_vld1_vld2_lane,\
306    neon_vld3_vld4_lane,\
307    neon_vst1_vst2_lane,\
308    neon_vst3_vst4_lane,\
309    neon_vld3_vld4_all_lanes,\
310    neon_mcr,\
311    neon_mcr_2_mcrr,\
312    neon_mrc,\
313    neon_mrrc,\
314    neon_ldm_2,\
315    neon_stm_2,\
316    none"
317  (const_string "none"))
318
319 ; condition codes: this one is used by final_prescan_insn to speed up
320 ; conditionalizing instructions.  It saves having to scan the rtl to see if
321 ; it uses or alters the condition codes.
322
323 ; USE means that the condition codes are used by the insn in the process of
324 ;   outputting code, this means (at present) that we can't use the insn in
325 ;   inlined branches
326 ;
327 ; SET means that the purpose of the insn is to set the condition codes in a
328 ;   well defined manner.
329 ;
330 ; CLOB means that the condition codes are altered in an undefined manner, if
331 ;   they are altered at all
332 ;
333 ; UNCONDITIONAL means the instions can not be conditionally executed.
334 ;
335 ; NOCOND means that the condition codes are neither altered nor affect the
336 ;   output of this insn
337
338 (define_attr "conds" "use,set,clob,unconditional,nocond"
339         (if_then_else (eq_attr "type" "call")
340          (const_string "clob")
341          (if_then_else (eq_attr "neon_type" "none")
342           (const_string "nocond")
343           (const_string "unconditional"))))
344
345 ; Predicable means that the insn can be conditionally executed based on
346 ; an automatically added predicate (additional patterns are generated by 
347 ; gen...).  We default to 'no' because no Thumb patterns match this rule
348 ; and not all ARM patterns do.
349 (define_attr "predicable" "no,yes" (const_string "no"))
350
351 ; Only model the write buffer for ARM6 and ARM7.  Earlier processors don't
352 ; have one.  Later ones, such as StrongARM, have write-back caches, so don't
353 ; suffer blockages enough to warrant modelling this (and it can adversely
354 ; affect the schedule).
355 (define_attr "model_wbuf" "no,yes" (const (symbol_ref "arm_tune_wbuf")))
356
357 ; WRITE_CONFLICT implies that a read following an unrelated write is likely
358 ; to stall the processor.  Used with model_wbuf above.
359 (define_attr "write_conflict" "no,yes"
360   (if_then_else (eq_attr "type"
361                  "block,float_em,f_load,f_store,f_mem_r,r_mem_f,call,load1")
362                 (const_string "yes")
363                 (const_string "no")))
364
365 ; Classify the insns into those that take one cycle and those that take more
366 ; than one on the main cpu execution unit.
367 (define_attr "core_cycles" "single,multi"
368   (if_then_else (eq_attr "type"
369                  "alu,alu_shift,float,fdivx,fdivd,fdivs,fmul,ffmul,farith,ffarith")
370                 (const_string "single")
371                 (const_string "multi")))
372
373 ;; FAR_JUMP is "yes" if a BL instruction is used to generate a branch to a
374 ;; distant label.  Only applicable to Thumb code.
375 (define_attr "far_jump" "yes,no" (const_string "no"))
376
377
378 ;; The number of machine instructions this pattern expands to.
379 ;; Used for Thumb-2 conditional execution.
380 (define_attr "ce_count" "" (const_int 1))
381
382 ;;---------------------------------------------------------------------------
383 ;; Mode iterators
384
385 ; A list of modes that are exactly 64 bits in size.  We use this to expand
386 ; some splits that are the same for all modes when operating on ARM 
387 ; registers.
388 (define_mode_iterator ANY64 [DI DF V8QI V4HI V2SI V2SF])
389
390 ;; The integer modes up to word size
391 (define_mode_iterator QHSI [QI HI SI])
392
393 ;;---------------------------------------------------------------------------
394 ;; Predicates
395
396 (include "predicates.md")
397 (include "constraints.md")
398
399 ;;---------------------------------------------------------------------------
400 ;; Pipeline descriptions
401
402 ;; Processor type.  This is created automatically from arm-cores.def.
403 (include "arm-tune.md")
404
405 (define_attr "tune_cortexr4" "yes,no"
406   (const (if_then_else
407           (eq_attr "tune" "cortexr4,cortexr4f")
408           (const_string "yes")
409           (const_string "no"))))
410
411 ;; True if the generic scheduling description should be used.
412
413 (define_attr "generic_sched" "yes,no"
414   (const (if_then_else 
415           (ior (eq_attr "tune" "arm926ejs,arm1020e,arm1026ejs,arm1136js,arm1136jfs,cortexa8,cortexa9")
416               (eq_attr "tune_cortexr4" "yes"))
417           (const_string "no")
418           (const_string "yes"))))
419
420 (define_attr "generic_vfp" "yes,no"
421   (const (if_then_else
422           (and (eq_attr "fpu" "vfp")
423                (eq_attr "tune" "!arm1020e,arm1022e,cortexa8,cortexa9")
424                (eq_attr "tune_cortexr4" "no"))
425           (const_string "yes")
426           (const_string "no"))))
427
428 (include "arm-generic.md")
429 (include "arm926ejs.md")
430 (include "arm1020e.md")
431 (include "arm1026ejs.md")
432 (include "arm1136jfs.md")
433 (include "cortex-a8.md")
434 (include "cortex-a9.md")
435 (include "cortex-r4.md")
436 (include "cortex-r4f.md")
437 (include "vfp11.md")
438
439 \f
440 ;;---------------------------------------------------------------------------
441 ;; Insn patterns
442 ;;
443 ;; Addition insns.
444
445 ;; Note: For DImode insns, there is normally no reason why operands should
446 ;; not be in the same register, what we don't want is for something being
447 ;; written to partially overlap something that is an input.
448 ;; Cirrus 64bit additions should not be split because we have a native
449 ;; 64bit addition instructions.
450
451 (define_expand "adddi3"
452  [(parallel
453    [(set (match_operand:DI           0 "s_register_operand" "")
454           (plus:DI (match_operand:DI 1 "s_register_operand" "")
455                    (match_operand:DI 2 "s_register_operand" "")))
456     (clobber (reg:CC CC_REGNUM))])]
457   "TARGET_EITHER"
458   "
459   if (TARGET_HARD_FLOAT && TARGET_MAVERICK)
460     {
461       if (!cirrus_fp_register (operands[0], DImode))
462         operands[0] = force_reg (DImode, operands[0]);
463       if (!cirrus_fp_register (operands[1], DImode))
464         operands[1] = force_reg (DImode, operands[1]);
465       emit_insn (gen_cirrus_adddi3 (operands[0], operands[1], operands[2]));
466       DONE;
467     }
468
469   if (TARGET_THUMB1)
470     {
471       if (GET_CODE (operands[1]) != REG)
472         operands[1] = force_reg (DImode, operands[1]);
473       if (GET_CODE (operands[2]) != REG)
474         operands[2] = force_reg (DImode, operands[2]);
475      }
476   "
477 )
478
479 (define_insn "*thumb1_adddi3"
480   [(set (match_operand:DI          0 "register_operand" "=l")
481         (plus:DI (match_operand:DI 1 "register_operand" "%0")
482                  (match_operand:DI 2 "register_operand" "l")))
483    (clobber (reg:CC CC_REGNUM))
484   ]
485   "TARGET_THUMB1"
486   "add\\t%Q0, %Q0, %Q2\;adc\\t%R0, %R0, %R2"
487   [(set_attr "length" "4")]
488 )
489
490 (define_insn_and_split "*arm_adddi3"
491   [(set (match_operand:DI          0 "s_register_operand" "=&r,&r")
492         (plus:DI (match_operand:DI 1 "s_register_operand" "%0, 0")
493                  (match_operand:DI 2 "s_register_operand" "r,  0")))
494    (clobber (reg:CC CC_REGNUM))]
495   "TARGET_32BIT && !(TARGET_HARD_FLOAT && TARGET_MAVERICK)"
496   "#"
497   "TARGET_32BIT && reload_completed"
498   [(parallel [(set (reg:CC_C CC_REGNUM)
499                    (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
500                                  (match_dup 1)))
501               (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
502    (set (match_dup 3) (plus:SI (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))
503                                (plus:SI (match_dup 4) (match_dup 5))))]
504   "
505   {
506     operands[3] = gen_highpart (SImode, operands[0]);
507     operands[0] = gen_lowpart (SImode, operands[0]);
508     operands[4] = gen_highpart (SImode, operands[1]);
509     operands[1] = gen_lowpart (SImode, operands[1]);
510     operands[5] = gen_highpart (SImode, operands[2]);
511     operands[2] = gen_lowpart (SImode, operands[2]);
512   }"
513   [(set_attr "conds" "clob")
514    (set_attr "length" "8")]
515 )
516
517 (define_insn_and_split "*adddi_sesidi_di"
518   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
519         (plus:DI (sign_extend:DI
520                   (match_operand:SI 2 "s_register_operand" "r,r"))
521                  (match_operand:DI 1 "s_register_operand" "0,r")))
522    (clobber (reg:CC CC_REGNUM))]
523   "TARGET_32BIT && !(TARGET_HARD_FLOAT && TARGET_MAVERICK)"
524   "#"
525   "TARGET_32BIT && reload_completed"
526   [(parallel [(set (reg:CC_C CC_REGNUM)
527                    (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
528                                  (match_dup 1)))
529               (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
530    (set (match_dup 3) (plus:SI (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))
531                                (plus:SI (ashiftrt:SI (match_dup 2)
532                                                      (const_int 31))
533                                         (match_dup 4))))]
534   "
535   {
536     operands[3] = gen_highpart (SImode, operands[0]);
537     operands[0] = gen_lowpart (SImode, operands[0]);
538     operands[4] = gen_highpart (SImode, operands[1]);
539     operands[1] = gen_lowpart (SImode, operands[1]);
540     operands[2] = gen_lowpart (SImode, operands[2]);
541   }"
542   [(set_attr "conds" "clob")
543    (set_attr "length" "8")]
544 )
545
546 (define_insn_and_split "*adddi_zesidi_di"
547   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
548         (plus:DI (zero_extend:DI
549                   (match_operand:SI 2 "s_register_operand" "r,r"))
550                  (match_operand:DI 1 "s_register_operand" "0,r")))
551    (clobber (reg:CC CC_REGNUM))]
552   "TARGET_32BIT && !(TARGET_HARD_FLOAT && TARGET_MAVERICK)"
553   "#"
554   "TARGET_32BIT && reload_completed"
555   [(parallel [(set (reg:CC_C CC_REGNUM)
556                    (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
557                                  (match_dup 1)))
558               (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
559    (set (match_dup 3) (plus:SI (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))
560                                (plus:SI (match_dup 4) (const_int 0))))]
561   "
562   {
563     operands[3] = gen_highpart (SImode, operands[0]);
564     operands[0] = gen_lowpart (SImode, operands[0]);
565     operands[4] = gen_highpart (SImode, operands[1]);
566     operands[1] = gen_lowpart (SImode, operands[1]);
567     operands[2] = gen_lowpart (SImode, operands[2]);
568   }"
569   [(set_attr "conds" "clob")
570    (set_attr "length" "8")]
571 )
572
573 (define_expand "addsi3"
574   [(set (match_operand:SI          0 "s_register_operand" "")
575         (plus:SI (match_operand:SI 1 "s_register_operand" "")
576                  (match_operand:SI 2 "reg_or_int_operand" "")))]
577   "TARGET_EITHER"
578   "
579   if (TARGET_32BIT && GET_CODE (operands[2]) == CONST_INT)
580     {
581       arm_split_constant (PLUS, SImode, NULL_RTX,
582                           INTVAL (operands[2]), operands[0], operands[1],
583                           optimize && can_create_pseudo_p ());
584       DONE;
585     }
586   "
587 )
588
589 ; If there is a scratch available, this will be faster than synthesizing the
590 ; addition.
591 (define_peephole2
592   [(match_scratch:SI 3 "r")
593    (set (match_operand:SI          0 "arm_general_register_operand" "")
594         (plus:SI (match_operand:SI 1 "arm_general_register_operand" "")
595                  (match_operand:SI 2 "const_int_operand"  "")))]
596   "TARGET_32BIT &&
597    !(const_ok_for_arm (INTVAL (operands[2]))
598      || const_ok_for_arm (-INTVAL (operands[2])))
599     && const_ok_for_arm (~INTVAL (operands[2]))"
600   [(set (match_dup 3) (match_dup 2))
601    (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 3)))]
602   ""
603 )
604
605 ;; The r/r/k alternative is required when reloading the address
606 ;;  (plus (reg rN) (reg sp)) into (reg rN).  In this case reload will
607 ;; put the duplicated register first, and not try the commutative version.
608 (define_insn_and_split "*arm_addsi3"
609   [(set (match_operand:SI          0 "s_register_operand" "=r, !k, r,r, !k,r")
610         (plus:SI (match_operand:SI 1 "s_register_operand" "%rk,!k, r,rk,!k,rk")
611                  (match_operand:SI 2 "reg_or_int_operand" "rI, rI,!k,L, L,?n")))]
612   "TARGET_32BIT"
613   "@
614    add%?\\t%0, %1, %2
615    add%?\\t%0, %1, %2
616    add%?\\t%0, %2, %1
617    sub%?\\t%0, %1, #%n2
618    sub%?\\t%0, %1, #%n2
619    #"
620   "TARGET_32BIT
621    && GET_CODE (operands[2]) == CONST_INT
622    && !(const_ok_for_arm (INTVAL (operands[2]))
623         || const_ok_for_arm (-INTVAL (operands[2])))
624    && (reload_completed || !arm_eliminable_register (operands[1]))"
625   [(clobber (const_int 0))]
626   "
627   arm_split_constant (PLUS, SImode, curr_insn,
628                       INTVAL (operands[2]), operands[0],
629                       operands[1], 0);
630   DONE;
631   "
632   [(set_attr "length" "4,4,4,4,4,16")
633    (set_attr "predicable" "yes")]
634 )
635
636 ;; Register group 'k' is a single register group containing only the stack
637 ;; register.  Trying to reload it will always fail catastrophically,
638 ;; so never allow those alternatives to match if reloading is needed.
639
640 (define_insn_and_split "*thumb1_addsi3"
641   [(set (match_operand:SI          0 "register_operand" "=l,l,l,*rk,*hk,l,!k,l,l")
642         (plus:SI (match_operand:SI 1 "register_operand" "%0,0,l,*0,*0,!k,!k,0,l")
643                  (match_operand:SI 2 "nonmemory_operand" "I,J,lL,*hk,*rk,!M,!O,Pa,Pb")))]
644   "TARGET_THUMB1"
645   "*
646    static const char * const asms[] = 
647    {
648      \"add\\t%0, %0, %2\",
649      \"sub\\t%0, %0, #%n2\",
650      \"add\\t%0, %1, %2\",
651      \"add\\t%0, %0, %2\",
652      \"add\\t%0, %0, %2\",
653      \"add\\t%0, %1, %2\",
654      \"add\\t%0, %1, %2\",
655      \"#\",
656      \"#\"
657    };
658    if ((which_alternative == 2 || which_alternative == 6)
659        && GET_CODE (operands[2]) == CONST_INT
660        && INTVAL (operands[2]) < 0)
661      return \"sub\\t%0, %1, #%n2\";
662    return asms[which_alternative];
663   "
664   "&& reload_completed && CONST_INT_P (operands[2])
665    && operands[1] != stack_pointer_rtx
666    && (INTVAL (operands[2]) > 255 || INTVAL (operands[2]) < -255)"
667   [(set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))
668    (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 3)))]
669   {
670     HOST_WIDE_INT offset = INTVAL (operands[2]);
671     if (offset > 255)
672       offset = 255;
673     else if (offset < -255)
674       offset = -255;
675     
676     operands[3] = GEN_INT (offset);
677     operands[2] = GEN_INT (INTVAL (operands[2]) - offset);
678   }
679   [(set_attr "length" "2,2,2,2,2,2,2,4,4")]
680 )
681
682 ;; Reloading and elimination of the frame pointer can
683 ;; sometimes cause this optimization to be missed.
684 (define_peephole2
685   [(set (match_operand:SI 0 "arm_general_register_operand" "")
686         (match_operand:SI 1 "const_int_operand" ""))
687    (set (match_dup 0)
688         (plus:SI (match_dup 0) (reg:SI SP_REGNUM)))]
689   "TARGET_THUMB1
690    && (unsigned HOST_WIDE_INT) (INTVAL (operands[1])) < 1024
691    && (INTVAL (operands[1]) & 3) == 0"
692   [(set (match_dup 0) (plus:SI (reg:SI SP_REGNUM) (match_dup 1)))]
693   ""
694 )
695
696 ;; ??? Make Thumb-2 variants which prefer low regs
697 (define_insn "*addsi3_compare0"
698   [(set (reg:CC_NOOV CC_REGNUM)
699         (compare:CC_NOOV
700          (plus:SI (match_operand:SI 1 "s_register_operand" "r, r")
701                   (match_operand:SI 2 "arm_add_operand"    "rI,L"))
702          (const_int 0)))
703    (set (match_operand:SI 0 "s_register_operand" "=r,r")
704         (plus:SI (match_dup 1) (match_dup 2)))]
705   "TARGET_32BIT"
706   "@
707    add%.\\t%0, %1, %2
708    sub%.\\t%0, %1, #%n2"
709   [(set_attr "conds" "set")]
710 )
711
712 (define_insn "*addsi3_compare0_scratch"
713   [(set (reg:CC_NOOV CC_REGNUM)
714         (compare:CC_NOOV
715          (plus:SI (match_operand:SI 0 "s_register_operand" "r, r")
716                   (match_operand:SI 1 "arm_add_operand"    "rI,L"))
717          (const_int 0)))]
718   "TARGET_32BIT"
719   "@
720    cmn%?\\t%0, %1
721    cmp%?\\t%0, #%n1"
722   [(set_attr "conds" "set")]
723 )
724
725 (define_insn "*compare_negsi_si"
726   [(set (reg:CC_Z CC_REGNUM)
727         (compare:CC_Z
728          (neg:SI (match_operand:SI 0 "s_register_operand" "r"))
729          (match_operand:SI 1 "s_register_operand" "r")))]
730   "TARGET_32BIT"
731   "cmn%?\\t%1, %0"
732   [(set_attr "conds" "set")]
733 )
734
735 ;; This is the canonicalization of addsi3_compare0_for_combiner when the
736 ;; addend is a constant.
737 (define_insn "*cmpsi2_addneg"
738   [(set (reg:CC CC_REGNUM)
739         (compare:CC
740          (match_operand:SI 1 "s_register_operand" "r,r")
741          (match_operand:SI 2 "arm_addimm_operand" "I,L")))
742    (set (match_operand:SI 0 "s_register_operand" "=r,r")
743         (plus:SI (match_dup 1)
744                  (match_operand:SI 3 "arm_addimm_operand" "L,I")))]
745   "TARGET_32BIT && INTVAL (operands[2]) == -INTVAL (operands[3])"
746   "@
747    sub%.\\t%0, %1, %2
748    add%.\\t%0, %1, #%n2"
749   [(set_attr "conds" "set")]
750 )
751
752 ;; Convert the sequence
753 ;;  sub  rd, rn, #1
754 ;;  cmn  rd, #1 (equivalent to cmp rd, #-1)
755 ;;  bne  dest
756 ;; into
757 ;;  subs rd, rn, #1
758 ;;  bcs  dest   ((unsigned)rn >= 1)
759 ;; similarly for the beq variant using bcc.
760 ;; This is a common looping idiom (while (n--))
761 (define_peephole2
762   [(set (match_operand:SI 0 "arm_general_register_operand" "")
763         (plus:SI (match_operand:SI 1 "arm_general_register_operand" "")
764                  (const_int -1)))
765    (set (match_operand 2 "cc_register" "")
766         (compare (match_dup 0) (const_int -1)))
767    (set (pc)
768         (if_then_else (match_operator 3 "equality_operator"
769                        [(match_dup 2) (const_int 0)])
770                       (match_operand 4 "" "")
771                       (match_operand 5 "" "")))]
772   "TARGET_32BIT && peep2_reg_dead_p (3, operands[2])"
773   [(parallel[
774     (set (match_dup 2)
775          (compare:CC
776           (match_dup 1) (const_int 1)))
777     (set (match_dup 0) (plus:SI (match_dup 1) (const_int -1)))])
778    (set (pc)
779         (if_then_else (match_op_dup 3 [(match_dup 2) (const_int 0)])
780                       (match_dup 4)
781                       (match_dup 5)))]
782   "operands[2] = gen_rtx_REG (CCmode, CC_REGNUM);
783    operands[3] = gen_rtx_fmt_ee ((GET_CODE (operands[3]) == NE
784                                   ? GEU : LTU),
785                                  VOIDmode, 
786                                  operands[2], const0_rtx);"
787 )
788
789 ;; The next four insns work because they compare the result with one of
790 ;; the operands, and we know that the use of the condition code is
791 ;; either GEU or LTU, so we can use the carry flag from the addition
792 ;; instead of doing the compare a second time.
793 (define_insn "*addsi3_compare_op1"
794   [(set (reg:CC_C CC_REGNUM)
795         (compare:CC_C
796          (plus:SI (match_operand:SI 1 "s_register_operand" "r,r")
797                   (match_operand:SI 2 "arm_add_operand" "rI,L"))
798          (match_dup 1)))
799    (set (match_operand:SI 0 "s_register_operand" "=r,r")
800         (plus:SI (match_dup 1) (match_dup 2)))]
801   "TARGET_32BIT"
802   "@
803    add%.\\t%0, %1, %2
804    sub%.\\t%0, %1, #%n2"
805   [(set_attr "conds" "set")]
806 )
807
808 (define_insn "*addsi3_compare_op2"
809   [(set (reg:CC_C CC_REGNUM)
810         (compare:CC_C
811          (plus:SI (match_operand:SI 1 "s_register_operand" "r,r")
812                   (match_operand:SI 2 "arm_add_operand" "rI,L"))
813          (match_dup 2)))
814    (set (match_operand:SI 0 "s_register_operand" "=r,r")
815         (plus:SI (match_dup 1) (match_dup 2)))]
816   "TARGET_32BIT"
817   "@
818    add%.\\t%0, %1, %2
819    sub%.\\t%0, %1, #%n2"
820   [(set_attr "conds" "set")]
821 )
822
823 (define_insn "*compare_addsi2_op0"
824   [(set (reg:CC_C CC_REGNUM)
825         (compare:CC_C
826          (plus:SI (match_operand:SI 0 "s_register_operand" "r,r")
827                   (match_operand:SI 1 "arm_add_operand" "rI,L"))
828          (match_dup 0)))]
829   "TARGET_32BIT"
830   "@
831    cmn%?\\t%0, %1
832    cmp%?\\t%0, #%n1"
833   [(set_attr "conds" "set")]
834 )
835
836 (define_insn "*compare_addsi2_op1"
837   [(set (reg:CC_C CC_REGNUM)
838         (compare:CC_C
839          (plus:SI (match_operand:SI 0 "s_register_operand" "r,r")
840                   (match_operand:SI 1 "arm_add_operand" "rI,L"))
841          (match_dup 1)))]
842   "TARGET_32BIT"
843   "@
844    cmn%?\\t%0, %1
845    cmp%?\\t%0, #%n1"
846   [(set_attr "conds" "set")]
847 )
848
849 (define_insn "*addsi3_carryin"
850   [(set (match_operand:SI 0 "s_register_operand" "=r")
851         (plus:SI (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))
852                  (plus:SI (match_operand:SI 1 "s_register_operand" "r")
853                           (match_operand:SI 2 "arm_rhs_operand" "rI"))))]
854   "TARGET_32BIT"
855   "adc%?\\t%0, %1, %2"
856   [(set_attr "conds" "use")]
857 )
858
859 (define_insn "*addsi3_carryin_shift"
860   [(set (match_operand:SI 0 "s_register_operand" "=r")
861         (plus:SI (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))
862                  (plus:SI
863                    (match_operator:SI 2 "shift_operator"
864                       [(match_operand:SI 3 "s_register_operand" "r")
865                        (match_operand:SI 4 "reg_or_int_operand" "rM")])
866                     (match_operand:SI 1 "s_register_operand" "r"))))]
867   "TARGET_32BIT"
868   "adc%?\\t%0, %1, %3%S2"
869   [(set_attr "conds" "use")
870    (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
871                       (const_string "alu_shift")
872                       (const_string "alu_shift_reg")))]
873 )
874
875 (define_insn "*addsi3_carryin_alt1"
876   [(set (match_operand:SI 0 "s_register_operand" "=r")
877         (plus:SI (plus:SI (match_operand:SI 1 "s_register_operand" "r")
878                           (match_operand:SI 2 "arm_rhs_operand" "rI"))
879                  (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
880   "TARGET_32BIT"
881   "adc%?\\t%0, %1, %2"
882   [(set_attr "conds" "use")]
883 )
884
885 (define_insn "*addsi3_carryin_alt2"
886   [(set (match_operand:SI 0 "s_register_operand" "=r")
887         (plus:SI (plus:SI (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))
888                           (match_operand:SI 1 "s_register_operand" "r"))
889                  (match_operand:SI 2 "arm_rhs_operand" "rI")))]
890   "TARGET_32BIT"
891   "adc%?\\t%0, %1, %2"
892   [(set_attr "conds" "use")]
893 )
894
895 (define_insn "*addsi3_carryin_alt3"
896   [(set (match_operand:SI 0 "s_register_operand" "=r")
897         (plus:SI (plus:SI (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))
898                           (match_operand:SI 2 "arm_rhs_operand" "rI"))
899                  (match_operand:SI 1 "s_register_operand" "r")))]
900   "TARGET_32BIT"
901   "adc%?\\t%0, %1, %2"
902   [(set_attr "conds" "use")]
903 )
904
905 (define_expand "incscc"
906   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
907         (plus:SI (match_operator:SI 2 "arm_comparison_operator"
908                     [(match_operand:CC 3 "cc_register" "") (const_int 0)])
909                  (match_operand:SI 1 "s_register_operand" "0,?r")))]
910   "TARGET_32BIT"
911   ""
912 )
913
914 (define_insn "*arm_incscc"
915   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
916         (plus:SI (match_operator:SI 2 "arm_comparison_operator"
917                     [(match_operand:CC 3 "cc_register" "") (const_int 0)])
918                  (match_operand:SI 1 "s_register_operand" "0,?r")))]
919   "TARGET_ARM"
920   "@
921   add%d2\\t%0, %1, #1
922   mov%D2\\t%0, %1\;add%d2\\t%0, %1, #1"
923   [(set_attr "conds" "use")
924    (set_attr "length" "4,8")]
925 )
926
927 ; transform ((x << y) - 1) to ~(~(x-1) << y)  Where X is a constant.
928 (define_split
929   [(set (match_operand:SI 0 "s_register_operand" "")
930         (plus:SI (ashift:SI (match_operand:SI 1 "const_int_operand" "")
931                             (match_operand:SI 2 "s_register_operand" ""))
932                  (const_int -1)))
933    (clobber (match_operand:SI 3 "s_register_operand" ""))]
934   "TARGET_32BIT"
935   [(set (match_dup 3) (match_dup 1))
936    (set (match_dup 0) (not:SI (ashift:SI (match_dup 3) (match_dup 2))))]
937   "
938   operands[1] = GEN_INT (~(INTVAL (operands[1]) - 1));
939 ")
940
941 (define_expand "addsf3"
942   [(set (match_operand:SF          0 "s_register_operand" "")
943         (plus:SF (match_operand:SF 1 "s_register_operand" "")
944                  (match_operand:SF 2 "arm_float_add_operand" "")))]
945   "TARGET_32BIT && TARGET_HARD_FLOAT"
946   "
947   if (TARGET_MAVERICK
948       && !cirrus_fp_register (operands[2], SFmode))
949     operands[2] = force_reg (SFmode, operands[2]);
950 ")
951
952 (define_expand "adddf3"
953   [(set (match_operand:DF          0 "s_register_operand" "")
954         (plus:DF (match_operand:DF 1 "s_register_operand" "")
955                  (match_operand:DF 2 "arm_float_add_operand" "")))]
956   "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
957   "
958   if (TARGET_MAVERICK
959       && !cirrus_fp_register (operands[2], DFmode))
960     operands[2] = force_reg (DFmode, operands[2]);
961 ")
962
963 (define_expand "subdi3"
964  [(parallel
965    [(set (match_operand:DI            0 "s_register_operand" "")
966           (minus:DI (match_operand:DI 1 "s_register_operand" "")
967                     (match_operand:DI 2 "s_register_operand" "")))
968     (clobber (reg:CC CC_REGNUM))])]
969   "TARGET_EITHER"
970   "
971   if (TARGET_HARD_FLOAT && TARGET_MAVERICK
972       && TARGET_32BIT
973       && cirrus_fp_register (operands[0], DImode)
974       && cirrus_fp_register (operands[1], DImode))
975     {
976       emit_insn (gen_cirrus_subdi3 (operands[0], operands[1], operands[2]));
977       DONE;
978     }
979
980   if (TARGET_THUMB1)
981     {
982       if (GET_CODE (operands[1]) != REG)
983         operands[1] = force_reg (DImode, operands[1]);
984       if (GET_CODE (operands[2]) != REG)
985         operands[2] = force_reg (DImode, operands[2]);
986      }  
987   "
988 )
989
990 (define_insn "*arm_subdi3"
991   [(set (match_operand:DI           0 "s_register_operand" "=&r,&r,&r")
992         (minus:DI (match_operand:DI 1 "s_register_operand" "0,r,0")
993                   (match_operand:DI 2 "s_register_operand" "r,0,0")))
994    (clobber (reg:CC CC_REGNUM))]
995   "TARGET_32BIT"
996   "subs\\t%Q0, %Q1, %Q2\;sbc\\t%R0, %R1, %R2"
997   [(set_attr "conds" "clob")
998    (set_attr "length" "8")]
999 )
1000
1001 (define_insn "*thumb_subdi3"
1002   [(set (match_operand:DI           0 "register_operand" "=l")
1003         (minus:DI (match_operand:DI 1 "register_operand"  "0")
1004                   (match_operand:DI 2 "register_operand"  "l")))
1005    (clobber (reg:CC CC_REGNUM))]
1006   "TARGET_THUMB1"
1007   "sub\\t%Q0, %Q0, %Q2\;sbc\\t%R0, %R0, %R2"
1008   [(set_attr "length" "4")]
1009 )
1010
1011 (define_insn "*subdi_di_zesidi"
1012   [(set (match_operand:DI           0 "s_register_operand" "=&r,&r")
1013         (minus:DI (match_operand:DI 1 "s_register_operand"  "0,r")
1014                   (zero_extend:DI
1015                    (match_operand:SI 2 "s_register_operand"  "r,r"))))
1016    (clobber (reg:CC CC_REGNUM))]
1017   "TARGET_32BIT"
1018   "subs\\t%Q0, %Q1, %2\;sbc\\t%R0, %R1, #0"
1019   [(set_attr "conds" "clob")
1020    (set_attr "length" "8")]
1021 )
1022
1023 (define_insn "*subdi_di_sesidi"
1024   [(set (match_operand:DI            0 "s_register_operand" "=&r,&r")
1025         (minus:DI (match_operand:DI  1 "s_register_operand"  "0,r")
1026                   (sign_extend:DI
1027                    (match_operand:SI 2 "s_register_operand"  "r,r"))))
1028    (clobber (reg:CC CC_REGNUM))]
1029   "TARGET_32BIT"
1030   "subs\\t%Q0, %Q1, %2\;sbc\\t%R0, %R1, %2, asr #31"
1031   [(set_attr "conds" "clob")
1032    (set_attr "length" "8")]
1033 )
1034
1035 (define_insn "*subdi_zesidi_di"
1036   [(set (match_operand:DI            0 "s_register_operand" "=&r,&r")
1037         (minus:DI (zero_extend:DI
1038                    (match_operand:SI 2 "s_register_operand"  "r,r"))
1039                   (match_operand:DI  1 "s_register_operand" "0,r")))
1040    (clobber (reg:CC CC_REGNUM))]
1041   "TARGET_ARM"
1042   "rsbs\\t%Q0, %Q1, %2\;rsc\\t%R0, %R1, #0"
1043   [(set_attr "conds" "clob")
1044    (set_attr "length" "8")]
1045 )
1046
1047 (define_insn "*subdi_sesidi_di"
1048   [(set (match_operand:DI            0 "s_register_operand" "=&r,&r")
1049         (minus:DI (sign_extend:DI
1050                    (match_operand:SI 2 "s_register_operand"   "r,r"))
1051                   (match_operand:DI  1 "s_register_operand"  "0,r")))
1052    (clobber (reg:CC CC_REGNUM))]
1053   "TARGET_ARM"
1054   "rsbs\\t%Q0, %Q1, %2\;rsc\\t%R0, %R1, %2, asr #31"
1055   [(set_attr "conds" "clob")
1056    (set_attr "length" "8")]
1057 )
1058
1059 (define_insn "*subdi_zesidi_zesidi"
1060   [(set (match_operand:DI            0 "s_register_operand" "=r")
1061         (minus:DI (zero_extend:DI
1062                    (match_operand:SI 1 "s_register_operand"  "r"))
1063                   (zero_extend:DI
1064                    (match_operand:SI 2 "s_register_operand"  "r"))))
1065    (clobber (reg:CC CC_REGNUM))]
1066   "TARGET_32BIT"
1067   "subs\\t%Q0, %1, %2\;sbc\\t%R0, %1, %1"
1068   [(set_attr "conds" "clob")
1069    (set_attr "length" "8")]
1070 )
1071
1072 (define_expand "subsi3"
1073   [(set (match_operand:SI           0 "s_register_operand" "")
1074         (minus:SI (match_operand:SI 1 "reg_or_int_operand" "")
1075                   (match_operand:SI 2 "s_register_operand" "")))]
1076   "TARGET_EITHER"
1077   "
1078   if (GET_CODE (operands[1]) == CONST_INT)
1079     {
1080       if (TARGET_32BIT)
1081         {
1082           arm_split_constant (MINUS, SImode, NULL_RTX,
1083                               INTVAL (operands[1]), operands[0],
1084                               operands[2], optimize && can_create_pseudo_p ());
1085           DONE;
1086         }
1087       else /* TARGET_THUMB1 */
1088         operands[1] = force_reg (SImode, operands[1]);
1089     }
1090   "
1091 )
1092
1093 (define_insn "*thumb1_subsi3_insn"
1094   [(set (match_operand:SI           0 "register_operand" "=l")
1095         (minus:SI (match_operand:SI 1 "register_operand" "l")
1096                   (match_operand:SI 2 "register_operand" "l")))]
1097   "TARGET_THUMB1"
1098   "sub\\t%0, %1, %2"
1099   [(set_attr "length" "2")]
1100 )
1101
1102 ; ??? Check Thumb-2 split length
1103 (define_insn_and_split "*arm_subsi3_insn"
1104   [(set (match_operand:SI           0 "s_register_operand" "=r,rk,r")
1105         (minus:SI (match_operand:SI 1 "reg_or_int_operand" "rI,!k,?n")
1106                   (match_operand:SI 2 "s_register_operand" "r, r, r")))]
1107   "TARGET_32BIT"
1108   "@
1109    rsb%?\\t%0, %2, %1
1110    sub%?\\t%0, %1, %2
1111    #"
1112   "TARGET_32BIT
1113    && GET_CODE (operands[1]) == CONST_INT
1114    && !const_ok_for_arm (INTVAL (operands[1]))"
1115   [(clobber (const_int 0))]
1116   "
1117   arm_split_constant (MINUS, SImode, curr_insn,
1118                       INTVAL (operands[1]), operands[0], operands[2], 0);
1119   DONE;
1120   "
1121   [(set_attr "length" "4,4,16")
1122    (set_attr "predicable" "yes")]
1123 )
1124
1125 (define_peephole2
1126   [(match_scratch:SI 3 "r")
1127    (set (match_operand:SI 0 "arm_general_register_operand" "")
1128         (minus:SI (match_operand:SI 1 "const_int_operand" "")
1129                   (match_operand:SI 2 "arm_general_register_operand" "")))]
1130   "TARGET_32BIT
1131    && !const_ok_for_arm (INTVAL (operands[1]))
1132    && const_ok_for_arm (~INTVAL (operands[1]))"
1133   [(set (match_dup 3) (match_dup 1))
1134    (set (match_dup 0) (minus:SI (match_dup 3) (match_dup 2)))]
1135   ""
1136 )
1137
1138 (define_insn "*subsi3_compare0"
1139   [(set (reg:CC_NOOV CC_REGNUM)
1140         (compare:CC_NOOV
1141          (minus:SI (match_operand:SI 1 "arm_rhs_operand" "r,I")
1142                    (match_operand:SI 2 "arm_rhs_operand" "rI,r"))
1143          (const_int 0)))
1144    (set (match_operand:SI 0 "s_register_operand" "=r,r")
1145         (minus:SI (match_dup 1) (match_dup 2)))]
1146   "TARGET_32BIT"
1147   "@
1148    sub%.\\t%0, %1, %2
1149    rsb%.\\t%0, %2, %1"
1150   [(set_attr "conds" "set")]
1151 )
1152
1153 (define_expand "decscc"
1154   [(set (match_operand:SI            0 "s_register_operand" "=r,r")
1155         (minus:SI (match_operand:SI  1 "s_register_operand" "0,?r")
1156                   (match_operator:SI 2 "arm_comparison_operator"
1157                    [(match_operand   3 "cc_register" "") (const_int 0)])))]
1158   "TARGET_32BIT"
1159   ""
1160 )
1161
1162 (define_insn "*arm_decscc"
1163   [(set (match_operand:SI            0 "s_register_operand" "=r,r")
1164         (minus:SI (match_operand:SI  1 "s_register_operand" "0,?r")
1165                   (match_operator:SI 2 "arm_comparison_operator"
1166                    [(match_operand   3 "cc_register" "") (const_int 0)])))]
1167   "TARGET_ARM"
1168   "@
1169    sub%d2\\t%0, %1, #1
1170    mov%D2\\t%0, %1\;sub%d2\\t%0, %1, #1"
1171   [(set_attr "conds" "use")
1172    (set_attr "length" "*,8")]
1173 )
1174
1175 (define_expand "subsf3"
1176   [(set (match_operand:SF           0 "s_register_operand" "")
1177         (minus:SF (match_operand:SF 1 "arm_float_rhs_operand" "")
1178                   (match_operand:SF 2 "arm_float_rhs_operand" "")))]
1179   "TARGET_32BIT && TARGET_HARD_FLOAT"
1180   "
1181   if (TARGET_MAVERICK)
1182     {
1183       if (!cirrus_fp_register (operands[1], SFmode))
1184         operands[1] = force_reg (SFmode, operands[1]);
1185       if (!cirrus_fp_register (operands[2], SFmode))
1186         operands[2] = force_reg (SFmode, operands[2]);
1187     }
1188 ")
1189
1190 (define_expand "subdf3"
1191   [(set (match_operand:DF           0 "s_register_operand" "")
1192         (minus:DF (match_operand:DF 1 "arm_float_rhs_operand" "")
1193                   (match_operand:DF 2 "arm_float_rhs_operand" "")))]
1194   "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
1195   "
1196   if (TARGET_MAVERICK)
1197     {
1198        if (!cirrus_fp_register (operands[1], DFmode))
1199          operands[1] = force_reg (DFmode, operands[1]);
1200        if (!cirrus_fp_register (operands[2], DFmode))
1201          operands[2] = force_reg (DFmode, operands[2]);
1202     }
1203 ")
1204
1205 \f
1206 ;; Multiplication insns
1207
1208 (define_expand "mulsi3"
1209   [(set (match_operand:SI          0 "s_register_operand" "")
1210         (mult:SI (match_operand:SI 2 "s_register_operand" "")
1211                  (match_operand:SI 1 "s_register_operand" "")))]
1212   "TARGET_EITHER"
1213   ""
1214 )
1215
1216 ;; Use `&' and then `0' to prevent the operands 0 and 1 being the same
1217 (define_insn "*arm_mulsi3"
1218   [(set (match_operand:SI          0 "s_register_operand" "=&r,&r")
1219         (mult:SI (match_operand:SI 2 "s_register_operand" "r,r")
1220                  (match_operand:SI 1 "s_register_operand" "%0,r")))]
1221   "TARGET_32BIT && !arm_arch6"
1222   "mul%?\\t%0, %2, %1"
1223   [(set_attr "insn" "mul")
1224    (set_attr "predicable" "yes")]
1225 )
1226
1227 (define_insn "*arm_mulsi3_v6"
1228   [(set (match_operand:SI          0 "s_register_operand" "=r")
1229         (mult:SI (match_operand:SI 1 "s_register_operand" "r")
1230                  (match_operand:SI 2 "s_register_operand" "r")))]
1231   "TARGET_32BIT && arm_arch6"
1232   "mul%?\\t%0, %1, %2"
1233   [(set_attr "insn" "mul")
1234    (set_attr "predicable" "yes")]
1235 )
1236
1237 ; Unfortunately with the Thumb the '&'/'0' trick can fails when operands 
1238 ; 1 and 2; are the same, because reload will make operand 0 match 
1239 ; operand 1 without realizing that this conflicts with operand 2.  We fix 
1240 ; this by adding another alternative to match this case, and then `reload' 
1241 ; it ourselves.  This alternative must come first.
1242 (define_insn "*thumb_mulsi3"
1243   [(set (match_operand:SI          0 "register_operand" "=&l,&l,&l")
1244         (mult:SI (match_operand:SI 1 "register_operand" "%l,*h,0")
1245                  (match_operand:SI 2 "register_operand" "l,l,l")))]
1246   "TARGET_THUMB1 && !arm_arch6"
1247   "*
1248   if (which_alternative < 2)
1249     return \"mov\\t%0, %1\;mul\\t%0, %2\";
1250   else
1251     return \"mul\\t%0, %2\";
1252   "
1253   [(set_attr "length" "4,4,2")
1254    (set_attr "insn" "mul")]
1255 )
1256
1257 (define_insn "*thumb_mulsi3_v6"
1258   [(set (match_operand:SI          0 "register_operand" "=l,l,l")
1259         (mult:SI (match_operand:SI 1 "register_operand" "0,l,0")
1260                  (match_operand:SI 2 "register_operand" "l,0,0")))]
1261   "TARGET_THUMB1 && arm_arch6"
1262   "@
1263    mul\\t%0, %2
1264    mul\\t%0, %1
1265    mul\\t%0, %1"
1266   [(set_attr "length" "2")
1267    (set_attr "insn" "mul")]
1268 )
1269
1270 (define_insn "*mulsi3_compare0"
1271   [(set (reg:CC_NOOV CC_REGNUM)
1272         (compare:CC_NOOV (mult:SI
1273                           (match_operand:SI 2 "s_register_operand" "r,r")
1274                           (match_operand:SI 1 "s_register_operand" "%0,r"))
1275                          (const_int 0)))
1276    (set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1277         (mult:SI (match_dup 2) (match_dup 1)))]
1278   "TARGET_ARM && !arm_arch6"
1279   "mul%.\\t%0, %2, %1"
1280   [(set_attr "conds" "set")
1281    (set_attr "insn" "muls")]
1282 )
1283
1284 (define_insn "*mulsi3_compare0_v6"
1285   [(set (reg:CC_NOOV CC_REGNUM)
1286         (compare:CC_NOOV (mult:SI
1287                           (match_operand:SI 2 "s_register_operand" "r")
1288                           (match_operand:SI 1 "s_register_operand" "r"))
1289                          (const_int 0)))
1290    (set (match_operand:SI 0 "s_register_operand" "=r")
1291         (mult:SI (match_dup 2) (match_dup 1)))]
1292   "TARGET_ARM && arm_arch6 && optimize_size"
1293   "mul%.\\t%0, %2, %1"
1294   [(set_attr "conds" "set")
1295    (set_attr "insn" "muls")]
1296 )
1297
1298 (define_insn "*mulsi_compare0_scratch"
1299   [(set (reg:CC_NOOV CC_REGNUM)
1300         (compare:CC_NOOV (mult:SI
1301                           (match_operand:SI 2 "s_register_operand" "r,r")
1302                           (match_operand:SI 1 "s_register_operand" "%0,r"))
1303                          (const_int 0)))
1304    (clobber (match_scratch:SI 0 "=&r,&r"))]
1305   "TARGET_ARM && !arm_arch6"
1306   "mul%.\\t%0, %2, %1"
1307   [(set_attr "conds" "set")
1308    (set_attr "insn" "muls")]
1309 )
1310
1311 (define_insn "*mulsi_compare0_scratch_v6"
1312   [(set (reg:CC_NOOV CC_REGNUM)
1313         (compare:CC_NOOV (mult:SI
1314                           (match_operand:SI 2 "s_register_operand" "r")
1315                           (match_operand:SI 1 "s_register_operand" "r"))
1316                          (const_int 0)))
1317    (clobber (match_scratch:SI 0 "=r"))]
1318   "TARGET_ARM && arm_arch6 && optimize_size"
1319   "mul%.\\t%0, %2, %1"
1320   [(set_attr "conds" "set")
1321    (set_attr "insn" "muls")]
1322 )
1323
1324 ;; Unnamed templates to match MLA instruction.
1325
1326 (define_insn "*mulsi3addsi"
1327   [(set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r,&r")
1328         (plus:SI
1329           (mult:SI (match_operand:SI 2 "s_register_operand" "r,r,r,r")
1330                    (match_operand:SI 1 "s_register_operand" "%0,r,0,r"))
1331           (match_operand:SI 3 "s_register_operand" "r,r,0,0")))]
1332   "TARGET_32BIT && !arm_arch6"
1333   "mla%?\\t%0, %2, %1, %3"
1334   [(set_attr "insn" "mla")
1335    (set_attr "predicable" "yes")]
1336 )
1337
1338 (define_insn "*mulsi3addsi_v6"
1339   [(set (match_operand:SI 0 "s_register_operand" "=r")
1340         (plus:SI
1341           (mult:SI (match_operand:SI 2 "s_register_operand" "r")
1342                    (match_operand:SI 1 "s_register_operand" "r"))
1343           (match_operand:SI 3 "s_register_operand" "r")))]
1344   "TARGET_32BIT && arm_arch6"
1345   "mla%?\\t%0, %2, %1, %3"
1346   [(set_attr "insn" "mla")
1347    (set_attr "predicable" "yes")]
1348 )
1349
1350 (define_insn "*mulsi3addsi_compare0"
1351   [(set (reg:CC_NOOV CC_REGNUM)
1352         (compare:CC_NOOV
1353          (plus:SI (mult:SI
1354                    (match_operand:SI 2 "s_register_operand" "r,r,r,r")
1355                    (match_operand:SI 1 "s_register_operand" "%0,r,0,r"))
1356                   (match_operand:SI 3 "s_register_operand" "r,r,0,0"))
1357          (const_int 0)))
1358    (set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r,&r")
1359         (plus:SI (mult:SI (match_dup 2) (match_dup 1))
1360                  (match_dup 3)))]
1361   "TARGET_ARM && arm_arch6"
1362   "mla%.\\t%0, %2, %1, %3"
1363   [(set_attr "conds" "set")
1364    (set_attr "insn" "mlas")]
1365 )
1366
1367 (define_insn "*mulsi3addsi_compare0_v6"
1368   [(set (reg:CC_NOOV CC_REGNUM)
1369         (compare:CC_NOOV
1370          (plus:SI (mult:SI
1371                    (match_operand:SI 2 "s_register_operand" "r")
1372                    (match_operand:SI 1 "s_register_operand" "r"))
1373                   (match_operand:SI 3 "s_register_operand" "r"))
1374          (const_int 0)))
1375    (set (match_operand:SI 0 "s_register_operand" "=r")
1376         (plus:SI (mult:SI (match_dup 2) (match_dup 1))
1377                  (match_dup 3)))]
1378   "TARGET_ARM && arm_arch6 && optimize_size"
1379   "mla%.\\t%0, %2, %1, %3"
1380   [(set_attr "conds" "set")
1381    (set_attr "insn" "mlas")]
1382 )
1383
1384 (define_insn "*mulsi3addsi_compare0_scratch"
1385   [(set (reg:CC_NOOV CC_REGNUM)
1386         (compare:CC_NOOV
1387          (plus:SI (mult:SI
1388                    (match_operand:SI 2 "s_register_operand" "r,r,r,r")
1389                    (match_operand:SI 1 "s_register_operand" "%0,r,0,r"))
1390                   (match_operand:SI 3 "s_register_operand" "?r,r,0,0"))
1391          (const_int 0)))
1392    (clobber (match_scratch:SI 0 "=&r,&r,&r,&r"))]
1393   "TARGET_ARM && !arm_arch6"
1394   "mla%.\\t%0, %2, %1, %3"
1395   [(set_attr "conds" "set")
1396    (set_attr "insn" "mlas")]
1397 )
1398
1399 (define_insn "*mulsi3addsi_compare0_scratch_v6"
1400   [(set (reg:CC_NOOV CC_REGNUM)
1401         (compare:CC_NOOV
1402          (plus:SI (mult:SI
1403                    (match_operand:SI 2 "s_register_operand" "r")
1404                    (match_operand:SI 1 "s_register_operand" "r"))
1405                   (match_operand:SI 3 "s_register_operand" "r"))
1406          (const_int 0)))
1407    (clobber (match_scratch:SI 0 "=r"))]
1408   "TARGET_ARM && arm_arch6 && optimize_size"
1409   "mla%.\\t%0, %2, %1, %3"
1410   [(set_attr "conds" "set")
1411    (set_attr "insn" "mlas")]
1412 )
1413
1414 (define_insn "*mulsi3subsi"
1415   [(set (match_operand:SI 0 "s_register_operand" "=r")
1416         (minus:SI
1417           (match_operand:SI 3 "s_register_operand" "r")
1418           (mult:SI (match_operand:SI 2 "s_register_operand" "r")
1419                    (match_operand:SI 1 "s_register_operand" "r"))))]
1420   "TARGET_32BIT && arm_arch_thumb2"
1421   "mls%?\\t%0, %2, %1, %3"
1422   [(set_attr "insn" "mla")
1423    (set_attr "predicable" "yes")]
1424 )
1425
1426 ;; Unnamed template to match long long multiply-accumulate (smlal)
1427
1428 (define_insn "*mulsidi3adddi"
1429   [(set (match_operand:DI 0 "s_register_operand" "=&r")
1430         (plus:DI
1431          (mult:DI
1432           (sign_extend:DI (match_operand:SI 2 "s_register_operand" "%r"))
1433           (sign_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1434          (match_operand:DI 1 "s_register_operand" "0")))]
1435   "TARGET_32BIT && arm_arch3m && !arm_arch6"
1436   "smlal%?\\t%Q0, %R0, %3, %2"
1437   [(set_attr "insn" "smlal")
1438    (set_attr "predicable" "yes")]
1439 )
1440
1441 (define_insn "*mulsidi3adddi_v6"
1442   [(set (match_operand:DI 0 "s_register_operand" "=r")
1443         (plus:DI
1444          (mult:DI
1445           (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r"))
1446           (sign_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1447          (match_operand:DI 1 "s_register_operand" "0")))]
1448   "TARGET_32BIT && arm_arch6"
1449   "smlal%?\\t%Q0, %R0, %3, %2"
1450   [(set_attr "insn" "smlal")
1451    (set_attr "predicable" "yes")]
1452 )
1453
1454 ;; 32x32->64 widening multiply.
1455 ;; As with mulsi3, the only difference between the v3-5 and v6+
1456 ;; versions of these patterns is the requirement that the output not
1457 ;; overlap the inputs, but that still means we have to have a named
1458 ;; expander and two different starred insns.
1459
1460 (define_expand "mulsidi3"
1461   [(set (match_operand:DI 0 "s_register_operand" "")
1462         (mult:DI
1463          (sign_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1464          (sign_extend:DI (match_operand:SI 2 "s_register_operand" ""))))]
1465   "TARGET_32BIT && arm_arch3m"
1466   ""
1467 )
1468
1469 (define_insn "*mulsidi3_nov6"
1470   [(set (match_operand:DI 0 "s_register_operand" "=&r")
1471         (mult:DI
1472          (sign_extend:DI (match_operand:SI 1 "s_register_operand" "%r"))
1473          (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1474   "TARGET_32BIT && arm_arch3m && !arm_arch6"
1475   "smull%?\\t%Q0, %R0, %1, %2"
1476   [(set_attr "insn" "smull")
1477    (set_attr "predicable" "yes")]
1478 )
1479
1480 (define_insn "*mulsidi3_v6"
1481   [(set (match_operand:DI 0 "s_register_operand" "=r")
1482         (mult:DI
1483          (sign_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1484          (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1485   "TARGET_32BIT && arm_arch6"
1486   "smull%?\\t%Q0, %R0, %1, %2"
1487   [(set_attr "insn" "smull")
1488    (set_attr "predicable" "yes")]
1489 )
1490
1491 (define_expand "umulsidi3"
1492   [(set (match_operand:DI 0 "s_register_operand" "")
1493         (mult:DI
1494          (zero_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1495          (zero_extend:DI (match_operand:SI 2 "s_register_operand" ""))))]
1496   "TARGET_32BIT && arm_arch3m"
1497   ""
1498 )
1499
1500 (define_insn "*umulsidi3_nov6"
1501   [(set (match_operand:DI 0 "s_register_operand" "=&r")
1502         (mult:DI
1503          (zero_extend:DI (match_operand:SI 1 "s_register_operand" "%r"))
1504          (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1505   "TARGET_32BIT && arm_arch3m && !arm_arch6"
1506   "umull%?\\t%Q0, %R0, %1, %2"
1507   [(set_attr "insn" "umull")
1508    (set_attr "predicable" "yes")]
1509 )
1510
1511 (define_insn "*umulsidi3_v6"
1512   [(set (match_operand:DI 0 "s_register_operand" "=r")
1513         (mult:DI
1514          (zero_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1515          (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1516   "TARGET_32BIT && arm_arch6"
1517   "umull%?\\t%Q0, %R0, %1, %2"
1518   [(set_attr "insn" "umull")
1519    (set_attr "predicable" "yes")]
1520 )
1521
1522 ;; Unnamed template to match long long unsigned multiply-accumulate (umlal)
1523
1524 (define_insn "*umulsidi3adddi"
1525   [(set (match_operand:DI 0 "s_register_operand" "=&r")
1526         (plus:DI
1527          (mult:DI
1528           (zero_extend:DI (match_operand:SI 2 "s_register_operand" "%r"))
1529           (zero_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1530          (match_operand:DI 1 "s_register_operand" "0")))]
1531   "TARGET_32BIT && arm_arch3m && !arm_arch6"
1532   "umlal%?\\t%Q0, %R0, %3, %2"
1533   [(set_attr "insn" "umlal")
1534    (set_attr "predicable" "yes")]
1535 )
1536
1537 (define_insn "*umulsidi3adddi_v6"
1538   [(set (match_operand:DI 0 "s_register_operand" "=r")
1539         (plus:DI
1540          (mult:DI
1541           (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r"))
1542           (zero_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1543          (match_operand:DI 1 "s_register_operand" "0")))]
1544   "TARGET_32BIT && arm_arch6"
1545   "umlal%?\\t%Q0, %R0, %3, %2"
1546   [(set_attr "insn" "umlal")
1547    (set_attr "predicable" "yes")]
1548 )
1549
1550 (define_expand "smulsi3_highpart"
1551   [(parallel
1552     [(set (match_operand:SI 0 "s_register_operand" "")
1553           (truncate:SI
1554            (lshiftrt:DI
1555             (mult:DI
1556              (sign_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1557              (sign_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1558             (const_int 32))))
1559      (clobber (match_scratch:SI 3 ""))])]
1560   "TARGET_32BIT && arm_arch3m"
1561   ""
1562 )
1563
1564 (define_insn "*smulsi3_highpart_nov6"
1565   [(set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1566         (truncate:SI
1567          (lshiftrt:DI
1568           (mult:DI
1569            (sign_extend:DI (match_operand:SI 1 "s_register_operand" "%0,r"))
1570            (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r,r")))
1571           (const_int 32))))
1572    (clobber (match_scratch:SI 3 "=&r,&r"))]
1573   "TARGET_32BIT && arm_arch3m && !arm_arch6"
1574   "smull%?\\t%3, %0, %2, %1"
1575   [(set_attr "insn" "smull")
1576    (set_attr "predicable" "yes")]
1577 )
1578
1579 (define_insn "*smulsi3_highpart_v6"
1580   [(set (match_operand:SI 0 "s_register_operand" "=r")
1581         (truncate:SI
1582          (lshiftrt:DI
1583           (mult:DI
1584            (sign_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1585            (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r")))
1586           (const_int 32))))
1587    (clobber (match_scratch:SI 3 "=r"))]
1588   "TARGET_32BIT && arm_arch6"
1589   "smull%?\\t%3, %0, %2, %1"
1590   [(set_attr "insn" "smull")
1591    (set_attr "predicable" "yes")]
1592 )
1593
1594 (define_expand "umulsi3_highpart"
1595   [(parallel
1596     [(set (match_operand:SI 0 "s_register_operand" "")
1597           (truncate:SI
1598            (lshiftrt:DI
1599             (mult:DI
1600              (zero_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1601               (zero_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1602             (const_int 32))))
1603      (clobber (match_scratch:SI 3 ""))])]
1604   "TARGET_32BIT && arm_arch3m"
1605   ""
1606 )
1607
1608 (define_insn "*umulsi3_highpart_nov6"
1609   [(set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1610         (truncate:SI
1611          (lshiftrt:DI
1612           (mult:DI
1613            (zero_extend:DI (match_operand:SI 1 "s_register_operand" "%0,r"))
1614            (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r,r")))
1615           (const_int 32))))
1616    (clobber (match_scratch:SI 3 "=&r,&r"))]
1617   "TARGET_32BIT && arm_arch3m && !arm_arch6"
1618   "umull%?\\t%3, %0, %2, %1"
1619   [(set_attr "insn" "umull")
1620    (set_attr "predicable" "yes")]
1621 )
1622
1623 (define_insn "*umulsi3_highpart_v6"
1624   [(set (match_operand:SI 0 "s_register_operand" "=r")
1625         (truncate:SI
1626          (lshiftrt:DI
1627           (mult:DI
1628            (zero_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1629            (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r")))
1630           (const_int 32))))
1631    (clobber (match_scratch:SI 3 "=r"))]
1632   "TARGET_32BIT && arm_arch6"
1633   "umull%?\\t%3, %0, %2, %1"
1634   [(set_attr "insn" "umull")
1635    (set_attr "predicable" "yes")]
1636 )
1637
1638 (define_insn "mulhisi3"
1639   [(set (match_operand:SI 0 "s_register_operand" "=r")
1640         (mult:SI (sign_extend:SI
1641                   (match_operand:HI 1 "s_register_operand" "%r"))
1642                  (sign_extend:SI
1643                   (match_operand:HI 2 "s_register_operand" "r"))))]
1644   "TARGET_DSP_MULTIPLY"
1645   "smulbb%?\\t%0, %1, %2"
1646   [(set_attr "insn" "smulxy")
1647    (set_attr "predicable" "yes")]
1648 )
1649
1650 (define_insn "*mulhisi3tb"
1651   [(set (match_operand:SI 0 "s_register_operand" "=r")
1652         (mult:SI (ashiftrt:SI
1653                   (match_operand:SI 1 "s_register_operand" "r")
1654                   (const_int 16))
1655                  (sign_extend:SI
1656                   (match_operand:HI 2 "s_register_operand" "r"))))]
1657   "TARGET_DSP_MULTIPLY"
1658   "smultb%?\\t%0, %1, %2"
1659   [(set_attr "insn" "smulxy")
1660    (set_attr "predicable" "yes")]
1661 )
1662
1663 (define_insn "*mulhisi3bt"
1664   [(set (match_operand:SI 0 "s_register_operand" "=r")
1665         (mult:SI (sign_extend:SI
1666                   (match_operand:HI 1 "s_register_operand" "r"))
1667                  (ashiftrt:SI
1668                   (match_operand:SI 2 "s_register_operand" "r")
1669                   (const_int 16))))]
1670   "TARGET_DSP_MULTIPLY"
1671   "smulbt%?\\t%0, %1, %2"
1672   [(set_attr "insn" "smulxy")
1673    (set_attr "predicable" "yes")]
1674 )
1675
1676 (define_insn "*mulhisi3tt"
1677   [(set (match_operand:SI 0 "s_register_operand" "=r")
1678         (mult:SI (ashiftrt:SI
1679                   (match_operand:SI 1 "s_register_operand" "r")
1680                   (const_int 16))
1681                  (ashiftrt:SI
1682                   (match_operand:SI 2 "s_register_operand" "r")
1683                   (const_int 16))))]
1684   "TARGET_DSP_MULTIPLY"
1685   "smultt%?\\t%0, %1, %2"
1686   [(set_attr "insn" "smulxy")
1687    (set_attr "predicable" "yes")]
1688 )
1689
1690 (define_insn "*mulhisi3addsi"
1691   [(set (match_operand:SI 0 "s_register_operand" "=r")
1692         (plus:SI (match_operand:SI 1 "s_register_operand" "r")
1693                  (mult:SI (sign_extend:SI
1694                            (match_operand:HI 2 "s_register_operand" "%r"))
1695                           (sign_extend:SI
1696                            (match_operand:HI 3 "s_register_operand" "r")))))]
1697   "TARGET_DSP_MULTIPLY"
1698   "smlabb%?\\t%0, %2, %3, %1"
1699   [(set_attr "insn" "smlaxy")
1700    (set_attr "predicable" "yes")]
1701 )
1702
1703 (define_insn "*mulhidi3adddi"
1704   [(set (match_operand:DI 0 "s_register_operand" "=r")
1705         (plus:DI
1706           (match_operand:DI 1 "s_register_operand" "0")
1707           (mult:DI (sign_extend:DI
1708                     (match_operand:HI 2 "s_register_operand" "%r"))
1709                    (sign_extend:DI
1710                     (match_operand:HI 3 "s_register_operand" "r")))))]
1711   "TARGET_DSP_MULTIPLY"
1712   "smlalbb%?\\t%Q0, %R0, %2, %3"
1713   [(set_attr "insn" "smlalxy")
1714    (set_attr "predicable" "yes")])
1715
1716 (define_expand "mulsf3"
1717   [(set (match_operand:SF          0 "s_register_operand" "")
1718         (mult:SF (match_operand:SF 1 "s_register_operand" "")
1719                  (match_operand:SF 2 "arm_float_rhs_operand" "")))]
1720   "TARGET_32BIT && TARGET_HARD_FLOAT"
1721   "
1722   if (TARGET_MAVERICK
1723       && !cirrus_fp_register (operands[2], SFmode))
1724     operands[2] = force_reg (SFmode, operands[2]);
1725 ")
1726
1727 (define_expand "muldf3"
1728   [(set (match_operand:DF          0 "s_register_operand" "")
1729         (mult:DF (match_operand:DF 1 "s_register_operand" "")
1730                  (match_operand:DF 2 "arm_float_rhs_operand" "")))]
1731   "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
1732   "
1733   if (TARGET_MAVERICK
1734       && !cirrus_fp_register (operands[2], DFmode))
1735     operands[2] = force_reg (DFmode, operands[2]);
1736 ")
1737 \f
1738 ;; Division insns
1739
1740 (define_expand "divsf3"
1741   [(set (match_operand:SF 0 "s_register_operand" "")
1742         (div:SF (match_operand:SF 1 "arm_float_rhs_operand" "")
1743                 (match_operand:SF 2 "arm_float_rhs_operand" "")))]
1744   "TARGET_32BIT && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP)"
1745   "")
1746
1747 (define_expand "divdf3"
1748   [(set (match_operand:DF 0 "s_register_operand" "")
1749         (div:DF (match_operand:DF 1 "arm_float_rhs_operand" "")
1750                 (match_operand:DF 2 "arm_float_rhs_operand" "")))]
1751   "TARGET_32BIT && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP_DOUBLE)"
1752   "")
1753 \f
1754 ;; Modulo insns
1755
1756 (define_expand "modsf3"
1757   [(set (match_operand:SF 0 "s_register_operand" "")
1758         (mod:SF (match_operand:SF 1 "s_register_operand" "")
1759                 (match_operand:SF 2 "arm_float_rhs_operand" "")))]
1760   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_FPA"
1761   "")
1762
1763 (define_expand "moddf3"
1764   [(set (match_operand:DF 0 "s_register_operand" "")
1765         (mod:DF (match_operand:DF 1 "s_register_operand" "")
1766                 (match_operand:DF 2 "arm_float_rhs_operand" "")))]
1767   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_FPA"
1768   "")
1769 \f
1770 ;; Boolean and,ior,xor insns
1771
1772 ;; Split up double word logical operations
1773
1774 ;; Split up simple DImode logical operations.  Simply perform the logical
1775 ;; operation on the upper and lower halves of the registers.
1776 (define_split
1777   [(set (match_operand:DI 0 "s_register_operand" "")
1778         (match_operator:DI 6 "logical_binary_operator"
1779           [(match_operand:DI 1 "s_register_operand" "")
1780            (match_operand:DI 2 "s_register_operand" "")]))]
1781   "TARGET_32BIT && reload_completed
1782    && ! IS_IWMMXT_REGNUM (REGNO (operands[0]))"
1783   [(set (match_dup 0) (match_op_dup:SI 6 [(match_dup 1) (match_dup 2)]))
1784    (set (match_dup 3) (match_op_dup:SI 6 [(match_dup 4) (match_dup 5)]))]
1785   "
1786   {
1787     operands[3] = gen_highpart (SImode, operands[0]);
1788     operands[0] = gen_lowpart (SImode, operands[0]);
1789     operands[4] = gen_highpart (SImode, operands[1]);
1790     operands[1] = gen_lowpart (SImode, operands[1]);
1791     operands[5] = gen_highpart (SImode, operands[2]);
1792     operands[2] = gen_lowpart (SImode, operands[2]);
1793   }"
1794 )
1795
1796 (define_split
1797   [(set (match_operand:DI 0 "s_register_operand" "")
1798         (match_operator:DI 6 "logical_binary_operator"
1799           [(sign_extend:DI (match_operand:SI 2 "s_register_operand" ""))
1800            (match_operand:DI 1 "s_register_operand" "")]))]
1801   "TARGET_32BIT && reload_completed"
1802   [(set (match_dup 0) (match_op_dup:SI 6 [(match_dup 1) (match_dup 2)]))
1803    (set (match_dup 3) (match_op_dup:SI 6
1804                         [(ashiftrt:SI (match_dup 2) (const_int 31))
1805                          (match_dup 4)]))]
1806   "
1807   {
1808     operands[3] = gen_highpart (SImode, operands[0]);
1809     operands[0] = gen_lowpart (SImode, operands[0]);
1810     operands[4] = gen_highpart (SImode, operands[1]);
1811     operands[1] = gen_lowpart (SImode, operands[1]);
1812     operands[5] = gen_highpart (SImode, operands[2]);
1813     operands[2] = gen_lowpart (SImode, operands[2]);
1814   }"
1815 )
1816
1817 ;; The zero extend of operand 2 means we can just copy the high part of
1818 ;; operand1 into operand0.
1819 (define_split
1820   [(set (match_operand:DI 0 "s_register_operand" "")
1821         (ior:DI
1822           (zero_extend:DI (match_operand:SI 2 "s_register_operand" ""))
1823           (match_operand:DI 1 "s_register_operand" "")))]
1824   "TARGET_32BIT && operands[0] != operands[1] && reload_completed"
1825   [(set (match_dup 0) (ior:SI (match_dup 1) (match_dup 2)))
1826    (set (match_dup 3) (match_dup 4))]
1827   "
1828   {
1829     operands[4] = gen_highpart (SImode, operands[1]);
1830     operands[3] = gen_highpart (SImode, operands[0]);
1831     operands[0] = gen_lowpart (SImode, operands[0]);
1832     operands[1] = gen_lowpart (SImode, operands[1]);
1833   }"
1834 )
1835
1836 ;; The zero extend of operand 2 means we can just copy the high part of
1837 ;; operand1 into operand0.
1838 (define_split
1839   [(set (match_operand:DI 0 "s_register_operand" "")
1840         (xor:DI
1841           (zero_extend:DI (match_operand:SI 2 "s_register_operand" ""))
1842           (match_operand:DI 1 "s_register_operand" "")))]
1843   "TARGET_32BIT && operands[0] != operands[1] && reload_completed"
1844   [(set (match_dup 0) (xor:SI (match_dup 1) (match_dup 2)))
1845    (set (match_dup 3) (match_dup 4))]
1846   "
1847   {
1848     operands[4] = gen_highpart (SImode, operands[1]);
1849     operands[3] = gen_highpart (SImode, operands[0]);
1850     operands[0] = gen_lowpart (SImode, operands[0]);
1851     operands[1] = gen_lowpart (SImode, operands[1]);
1852   }"
1853 )
1854
1855 (define_insn "anddi3"
1856   [(set (match_operand:DI         0 "s_register_operand" "=&r,&r")
1857         (and:DI (match_operand:DI 1 "s_register_operand"  "%0,r")
1858                 (match_operand:DI 2 "s_register_operand"   "r,r")))]
1859   "TARGET_32BIT && ! TARGET_IWMMXT"
1860   "#"
1861   [(set_attr "length" "8")]
1862 )
1863
1864 (define_insn_and_split "*anddi_zesidi_di"
1865   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1866         (and:DI (zero_extend:DI
1867                  (match_operand:SI 2 "s_register_operand" "r,r"))
1868                 (match_operand:DI 1 "s_register_operand" "0,r")))]
1869   "TARGET_32BIT"
1870   "#"
1871   "TARGET_32BIT && reload_completed"
1872   ; The zero extend of operand 2 clears the high word of the output
1873   ; operand.
1874   [(set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))
1875    (set (match_dup 3) (const_int 0))]
1876   "
1877   {
1878     operands[3] = gen_highpart (SImode, operands[0]);
1879     operands[0] = gen_lowpart (SImode, operands[0]);
1880     operands[1] = gen_lowpart (SImode, operands[1]);
1881   }"
1882   [(set_attr "length" "8")]
1883 )
1884
1885 (define_insn "*anddi_sesdi_di"
1886   [(set (match_operand:DI          0 "s_register_operand" "=&r,&r")
1887         (and:DI (sign_extend:DI
1888                  (match_operand:SI 2 "s_register_operand" "r,r"))
1889                 (match_operand:DI  1 "s_register_operand" "0,r")))]
1890   "TARGET_32BIT"
1891   "#"
1892   [(set_attr "length" "8")]
1893 )
1894
1895 (define_expand "andsi3"
1896   [(set (match_operand:SI         0 "s_register_operand" "")
1897         (and:SI (match_operand:SI 1 "s_register_operand" "")
1898                 (match_operand:SI 2 "reg_or_int_operand" "")))]
1899   "TARGET_EITHER"
1900   "
1901   if (TARGET_32BIT)
1902     {
1903       if (GET_CODE (operands[2]) == CONST_INT)
1904         {
1905           arm_split_constant (AND, SImode, NULL_RTX,
1906                               INTVAL (operands[2]), operands[0],
1907                               operands[1], optimize && can_create_pseudo_p ());
1908
1909           DONE;
1910         }
1911     }
1912   else /* TARGET_THUMB1 */
1913     {
1914       if (GET_CODE (operands[2]) != CONST_INT)
1915         {
1916           rtx tmp = force_reg (SImode, operands[2]);
1917           if (rtx_equal_p (operands[0], operands[1]))
1918             operands[2] = tmp;
1919           else
1920             {
1921               operands[2] = operands[1];
1922               operands[1] = tmp;
1923             }
1924         }
1925       else
1926         {
1927           int i;
1928           
1929           if (((unsigned HOST_WIDE_INT) ~INTVAL (operands[2])) < 256)
1930             {
1931               operands[2] = force_reg (SImode,
1932                                        GEN_INT (~INTVAL (operands[2])));
1933               
1934               emit_insn (gen_bicsi3 (operands[0], operands[2], operands[1]));
1935               
1936               DONE;
1937             }
1938
1939           for (i = 9; i <= 31; i++)
1940             {
1941               if ((((HOST_WIDE_INT) 1) << i) - 1 == INTVAL (operands[2]))
1942                 {
1943                   emit_insn (gen_extzv (operands[0], operands[1], GEN_INT (i),
1944                                         const0_rtx));
1945                   DONE;
1946                 }
1947               else if ((((HOST_WIDE_INT) 1) << i) - 1
1948                        == ~INTVAL (operands[2]))
1949                 {
1950                   rtx shift = GEN_INT (i);
1951                   rtx reg = gen_reg_rtx (SImode);
1952                 
1953                   emit_insn (gen_lshrsi3 (reg, operands[1], shift));
1954                   emit_insn (gen_ashlsi3 (operands[0], reg, shift));
1955                   
1956                   DONE;
1957                 }
1958             }
1959
1960           operands[2] = force_reg (SImode, operands[2]);
1961         }
1962     }
1963   "
1964 )
1965
1966 ; ??? Check split length for Thumb-2
1967 (define_insn_and_split "*arm_andsi3_insn"
1968   [(set (match_operand:SI         0 "s_register_operand" "=r,r,r")
1969         (and:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
1970                 (match_operand:SI 2 "reg_or_int_operand" "rI,K,?n")))]
1971   "TARGET_32BIT"
1972   "@
1973    and%?\\t%0, %1, %2
1974    bic%?\\t%0, %1, #%B2
1975    #"
1976   "TARGET_32BIT
1977    && GET_CODE (operands[2]) == CONST_INT
1978    && !(const_ok_for_arm (INTVAL (operands[2]))
1979         || const_ok_for_arm (~INTVAL (operands[2])))"
1980   [(clobber (const_int 0))]
1981   "
1982   arm_split_constant  (AND, SImode, curr_insn, 
1983                        INTVAL (operands[2]), operands[0], operands[1], 0);
1984   DONE;
1985   "
1986   [(set_attr "length" "4,4,16")
1987    (set_attr "predicable" "yes")]
1988 )
1989
1990 (define_insn "*thumb1_andsi3_insn"
1991   [(set (match_operand:SI         0 "register_operand" "=l")
1992         (and:SI (match_operand:SI 1 "register_operand" "%0")
1993                 (match_operand:SI 2 "register_operand" "l")))]
1994   "TARGET_THUMB1"
1995   "and\\t%0, %0, %2"
1996   [(set_attr "length" "2")]
1997 )
1998
1999 (define_insn "*andsi3_compare0"
2000   [(set (reg:CC_NOOV CC_REGNUM)
2001         (compare:CC_NOOV
2002          (and:SI (match_operand:SI 1 "s_register_operand" "r,r")
2003                  (match_operand:SI 2 "arm_not_operand" "rI,K"))
2004          (const_int 0)))
2005    (set (match_operand:SI          0 "s_register_operand" "=r,r")
2006         (and:SI (match_dup 1) (match_dup 2)))]
2007   "TARGET_32BIT"
2008   "@
2009    and%.\\t%0, %1, %2
2010    bic%.\\t%0, %1, #%B2"
2011   [(set_attr "conds" "set")]
2012 )
2013
2014 (define_insn "*andsi3_compare0_scratch"
2015   [(set (reg:CC_NOOV CC_REGNUM)
2016         (compare:CC_NOOV
2017          (and:SI (match_operand:SI 0 "s_register_operand" "r,r")
2018                  (match_operand:SI 1 "arm_not_operand" "rI,K"))
2019          (const_int 0)))
2020    (clobber (match_scratch:SI 2 "=X,r"))]
2021   "TARGET_32BIT"
2022   "@
2023    tst%?\\t%0, %1
2024    bic%.\\t%2, %0, #%B1"
2025   [(set_attr "conds" "set")]
2026 )
2027
2028 (define_insn "*zeroextractsi_compare0_scratch"
2029   [(set (reg:CC_NOOV CC_REGNUM)
2030         (compare:CC_NOOV (zero_extract:SI
2031                           (match_operand:SI 0 "s_register_operand" "r")
2032                           (match_operand 1 "const_int_operand" "n")
2033                           (match_operand 2 "const_int_operand" "n"))
2034                          (const_int 0)))]
2035   "TARGET_32BIT
2036   && (INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) < 32
2037       && INTVAL (operands[1]) > 0 
2038       && INTVAL (operands[1]) + (INTVAL (operands[2]) & 1) <= 8
2039       && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32)"
2040   "*
2041   operands[1] = GEN_INT (((1 << INTVAL (operands[1])) - 1)
2042                          << INTVAL (operands[2]));
2043   output_asm_insn (\"tst%?\\t%0, %1\", operands);
2044   return \"\";
2045   "
2046   [(set_attr "conds" "set")]
2047 )
2048
2049 (define_insn_and_split "*ne_zeroextractsi"
2050   [(set (match_operand:SI 0 "s_register_operand" "=r")
2051         (ne:SI (zero_extract:SI
2052                 (match_operand:SI 1 "s_register_operand" "r")
2053                 (match_operand:SI 2 "const_int_operand" "n")
2054                 (match_operand:SI 3 "const_int_operand" "n"))
2055                (const_int 0)))
2056    (clobber (reg:CC CC_REGNUM))]
2057   "TARGET_32BIT
2058    && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2059        && INTVAL (operands[2]) > 0 
2060        && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2061        && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)"
2062   "#"
2063   "TARGET_32BIT
2064    && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2065        && INTVAL (operands[2]) > 0 
2066        && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2067        && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)"
2068   [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2069                    (compare:CC_NOOV (and:SI (match_dup 1) (match_dup 2))
2070                                     (const_int 0)))
2071               (set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))])
2072    (set (match_dup 0)
2073         (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2074                          (match_dup 0) (const_int 1)))]
2075   "
2076   operands[2] = GEN_INT (((1 << INTVAL (operands[2])) - 1)
2077                          << INTVAL (operands[3])); 
2078   "
2079   [(set_attr "conds" "clob")
2080    (set (attr "length")
2081         (if_then_else (eq_attr "is_thumb" "yes")
2082                       (const_int 12)
2083                       (const_int 8)))]
2084 )
2085
2086 (define_insn_and_split "*ne_zeroextractsi_shifted"
2087   [(set (match_operand:SI 0 "s_register_operand" "=r")
2088         (ne:SI (zero_extract:SI
2089                 (match_operand:SI 1 "s_register_operand" "r")
2090                 (match_operand:SI 2 "const_int_operand" "n")
2091                 (const_int 0))
2092                (const_int 0)))
2093    (clobber (reg:CC CC_REGNUM))]
2094   "TARGET_ARM"
2095   "#"
2096   "TARGET_ARM"
2097   [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2098                    (compare:CC_NOOV (ashift:SI (match_dup 1) (match_dup 2))
2099                                     (const_int 0)))
2100               (set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))])
2101    (set (match_dup 0)
2102         (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2103                          (match_dup 0) (const_int 1)))]
2104   "
2105   operands[2] = GEN_INT (32 - INTVAL (operands[2]));
2106   "
2107   [(set_attr "conds" "clob")
2108    (set_attr "length" "8")]
2109 )
2110
2111 (define_insn_and_split "*ite_ne_zeroextractsi"
2112   [(set (match_operand:SI 0 "s_register_operand" "=r")
2113         (if_then_else:SI (ne (zero_extract:SI
2114                               (match_operand:SI 1 "s_register_operand" "r")
2115                               (match_operand:SI 2 "const_int_operand" "n")
2116                               (match_operand:SI 3 "const_int_operand" "n"))
2117                              (const_int 0))
2118                          (match_operand:SI 4 "arm_not_operand" "rIK")
2119                          (const_int 0)))
2120    (clobber (reg:CC CC_REGNUM))]
2121   "TARGET_ARM
2122    && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2123        && INTVAL (operands[2]) > 0 
2124        && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2125        && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)
2126    && !reg_overlap_mentioned_p (operands[0], operands[4])"
2127   "#"
2128   "TARGET_ARM
2129    && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2130        && INTVAL (operands[2]) > 0 
2131        && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2132        && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)
2133    && !reg_overlap_mentioned_p (operands[0], operands[4])"
2134   [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2135                    (compare:CC_NOOV (and:SI (match_dup 1) (match_dup 2))
2136                                     (const_int 0)))
2137               (set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))])
2138    (set (match_dup 0)
2139         (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2140                          (match_dup 0) (match_dup 4)))]
2141   "
2142   operands[2] = GEN_INT (((1 << INTVAL (operands[2])) - 1)
2143                          << INTVAL (operands[3])); 
2144   "
2145   [(set_attr "conds" "clob")
2146    (set_attr "length" "8")]
2147 )
2148
2149 (define_insn_and_split "*ite_ne_zeroextractsi_shifted"
2150   [(set (match_operand:SI 0 "s_register_operand" "=r")
2151         (if_then_else:SI (ne (zero_extract:SI
2152                               (match_operand:SI 1 "s_register_operand" "r")
2153                               (match_operand:SI 2 "const_int_operand" "n")
2154                               (const_int 0))
2155                              (const_int 0))
2156                          (match_operand:SI 3 "arm_not_operand" "rIK")
2157                          (const_int 0)))
2158    (clobber (reg:CC CC_REGNUM))]
2159   "TARGET_ARM && !reg_overlap_mentioned_p (operands[0], operands[3])"
2160   "#"
2161   "TARGET_ARM && !reg_overlap_mentioned_p (operands[0], operands[3])"
2162   [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2163                    (compare:CC_NOOV (ashift:SI (match_dup 1) (match_dup 2))
2164                                     (const_int 0)))
2165               (set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))])
2166    (set (match_dup 0)
2167         (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2168                          (match_dup 0) (match_dup 3)))]
2169   "
2170   operands[2] = GEN_INT (32 - INTVAL (operands[2]));
2171   "
2172   [(set_attr "conds" "clob")
2173    (set_attr "length" "8")]
2174 )
2175
2176 (define_split
2177   [(set (match_operand:SI 0 "s_register_operand" "")
2178         (zero_extract:SI (match_operand:SI 1 "s_register_operand" "")
2179                          (match_operand:SI 2 "const_int_operand" "")
2180                          (match_operand:SI 3 "const_int_operand" "")))
2181    (clobber (match_operand:SI 4 "s_register_operand" ""))]
2182   "TARGET_THUMB1"
2183   [(set (match_dup 4) (ashift:SI (match_dup 1) (match_dup 2)))
2184    (set (match_dup 0) (lshiftrt:SI (match_dup 4) (match_dup 3)))]
2185   "{
2186      HOST_WIDE_INT temp = INTVAL (operands[2]);
2187
2188      operands[2] = GEN_INT (32 - temp - INTVAL (operands[3]));
2189      operands[3] = GEN_INT (32 - temp);
2190    }"
2191 )
2192
2193 ;; ??? Use Thumb-2 has bitfield insert/extract instructions.
2194 (define_split
2195   [(set (match_operand:SI 0 "s_register_operand" "")
2196         (match_operator:SI 1 "shiftable_operator"
2197          [(zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
2198                            (match_operand:SI 3 "const_int_operand" "")
2199                            (match_operand:SI 4 "const_int_operand" ""))
2200           (match_operand:SI 5 "s_register_operand" "")]))
2201    (clobber (match_operand:SI 6 "s_register_operand" ""))]
2202   "TARGET_ARM"
2203   [(set (match_dup 6) (ashift:SI (match_dup 2) (match_dup 3)))
2204    (set (match_dup 0)
2205         (match_op_dup 1
2206          [(lshiftrt:SI (match_dup 6) (match_dup 4))
2207           (match_dup 5)]))]
2208   "{
2209      HOST_WIDE_INT temp = INTVAL (operands[3]);
2210
2211      operands[3] = GEN_INT (32 - temp - INTVAL (operands[4]));
2212      operands[4] = GEN_INT (32 - temp);
2213    }"
2214 )
2215   
2216 (define_split
2217   [(set (match_operand:SI 0 "s_register_operand" "")
2218         (sign_extract:SI (match_operand:SI 1 "s_register_operand" "")
2219                          (match_operand:SI 2 "const_int_operand" "")
2220                          (match_operand:SI 3 "const_int_operand" "")))]
2221   "TARGET_THUMB1"
2222   [(set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))
2223    (set (match_dup 0) (ashiftrt:SI (match_dup 0) (match_dup 3)))]
2224   "{
2225      HOST_WIDE_INT temp = INTVAL (operands[2]);
2226
2227      operands[2] = GEN_INT (32 - temp - INTVAL (operands[3]));
2228      operands[3] = GEN_INT (32 - temp);
2229    }"
2230 )
2231
2232 (define_split
2233   [(set (match_operand:SI 0 "s_register_operand" "")
2234         (match_operator:SI 1 "shiftable_operator"
2235          [(sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
2236                            (match_operand:SI 3 "const_int_operand" "")
2237                            (match_operand:SI 4 "const_int_operand" ""))
2238           (match_operand:SI 5 "s_register_operand" "")]))
2239    (clobber (match_operand:SI 6 "s_register_operand" ""))]
2240   "TARGET_ARM"
2241   [(set (match_dup 6) (ashift:SI (match_dup 2) (match_dup 3)))
2242    (set (match_dup 0)
2243         (match_op_dup 1
2244          [(ashiftrt:SI (match_dup 6) (match_dup 4))
2245           (match_dup 5)]))]
2246   "{
2247      HOST_WIDE_INT temp = INTVAL (operands[3]);
2248
2249      operands[3] = GEN_INT (32 - temp - INTVAL (operands[4]));
2250      operands[4] = GEN_INT (32 - temp);
2251    }"
2252 )
2253   
2254 ;;; ??? This pattern is bogus.  If operand3 has bits outside the range
2255 ;;; represented by the bitfield, then this will produce incorrect results.
2256 ;;; Somewhere, the value needs to be truncated.  On targets like the m68k,
2257 ;;; which have a real bit-field insert instruction, the truncation happens
2258 ;;; in the bit-field insert instruction itself.  Since arm does not have a
2259 ;;; bit-field insert instruction, we would have to emit code here to truncate
2260 ;;; the value before we insert.  This loses some of the advantage of having
2261 ;;; this insv pattern, so this pattern needs to be reevalutated.
2262
2263 (define_expand "insv"
2264   [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "")
2265                          (match_operand:SI 1 "general_operand" "")
2266                          (match_operand:SI 2 "general_operand" ""))
2267         (match_operand:SI 3 "reg_or_int_operand" ""))]
2268   "TARGET_ARM || arm_arch_thumb2"
2269   "
2270   {
2271     int start_bit = INTVAL (operands[2]);
2272     int width = INTVAL (operands[1]);
2273     HOST_WIDE_INT mask = (((HOST_WIDE_INT)1) << width) - 1;
2274     rtx target, subtarget;
2275
2276     if (arm_arch_thumb2)
2277       {
2278         bool use_bfi = TRUE;
2279
2280         if (GET_CODE (operands[3]) == CONST_INT)
2281           {
2282             HOST_WIDE_INT val = INTVAL (operands[3]) & mask;
2283
2284             if (val == 0)
2285               {
2286                 emit_insn (gen_insv_zero (operands[0], operands[1],
2287                                           operands[2]));
2288                 DONE;
2289               }
2290
2291             /* See if the set can be done with a single orr instruction.  */
2292             if (val == mask && const_ok_for_arm (val << start_bit))
2293               use_bfi = FALSE;
2294           }
2295           
2296         if (use_bfi)
2297           {
2298             if (GET_CODE (operands[3]) != REG)
2299               operands[3] = force_reg (SImode, operands[3]);
2300
2301             emit_insn (gen_insv_t2 (operands[0], operands[1], operands[2],
2302                                     operands[3]));
2303             DONE;
2304           }
2305       }
2306
2307     target = copy_rtx (operands[0]);
2308     /* Avoid using a subreg as a subtarget, and avoid writing a paradoxical 
2309        subreg as the final target.  */
2310     if (GET_CODE (target) == SUBREG)
2311       {
2312         subtarget = gen_reg_rtx (SImode);
2313         if (GET_MODE_SIZE (GET_MODE (SUBREG_REG (target)))
2314             < GET_MODE_SIZE (SImode))
2315           target = SUBREG_REG (target);
2316       }
2317     else
2318       subtarget = target;    
2319
2320     if (GET_CODE (operands[3]) == CONST_INT)
2321       {
2322         /* Since we are inserting a known constant, we may be able to
2323            reduce the number of bits that we have to clear so that
2324            the mask becomes simple.  */
2325         /* ??? This code does not check to see if the new mask is actually
2326            simpler.  It may not be.  */
2327         rtx op1 = gen_reg_rtx (SImode);
2328         /* ??? Truncate operand3 to fit in the bitfield.  See comment before
2329            start of this pattern.  */
2330         HOST_WIDE_INT op3_value = mask & INTVAL (operands[3]);
2331         HOST_WIDE_INT mask2 = ((mask & ~op3_value) << start_bit);
2332
2333         emit_insn (gen_andsi3 (op1, operands[0],
2334                                gen_int_mode (~mask2, SImode)));
2335         emit_insn (gen_iorsi3 (subtarget, op1,
2336                                gen_int_mode (op3_value << start_bit, SImode)));
2337       }
2338     else if (start_bit == 0
2339              && !(const_ok_for_arm (mask)
2340                   || const_ok_for_arm (~mask)))
2341       {
2342         /* A Trick, since we are setting the bottom bits in the word,
2343            we can shift operand[3] up, operand[0] down, OR them together
2344            and rotate the result back again.  This takes 3 insns, and
2345            the third might be mergeable into another op.  */
2346         /* The shift up copes with the possibility that operand[3] is
2347            wider than the bitfield.  */
2348         rtx op0 = gen_reg_rtx (SImode);
2349         rtx op1 = gen_reg_rtx (SImode);
2350
2351         emit_insn (gen_ashlsi3 (op0, operands[3], GEN_INT (32 - width)));
2352         emit_insn (gen_lshrsi3 (op1, operands[0], operands[1]));
2353         emit_insn (gen_iorsi3  (op1, op1, op0));
2354         emit_insn (gen_rotlsi3 (subtarget, op1, operands[1]));
2355       }
2356     else if ((width + start_bit == 32)
2357              && !(const_ok_for_arm (mask)
2358                   || const_ok_for_arm (~mask)))
2359       {
2360         /* Similar trick, but slightly less efficient.  */
2361
2362         rtx op0 = gen_reg_rtx (SImode);
2363         rtx op1 = gen_reg_rtx (SImode);
2364
2365         emit_insn (gen_ashlsi3 (op0, operands[3], GEN_INT (32 - width)));
2366         emit_insn (gen_ashlsi3 (op1, operands[0], operands[1]));
2367         emit_insn (gen_lshrsi3 (op1, op1, operands[1]));
2368         emit_insn (gen_iorsi3 (subtarget, op1, op0));
2369       }
2370     else
2371       {
2372         rtx op0 = gen_int_mode (mask, SImode);
2373         rtx op1 = gen_reg_rtx (SImode);
2374         rtx op2 = gen_reg_rtx (SImode);
2375
2376         if (!(const_ok_for_arm (mask) || const_ok_for_arm (~mask)))
2377           {
2378             rtx tmp = gen_reg_rtx (SImode);
2379
2380             emit_insn (gen_movsi (tmp, op0));
2381             op0 = tmp;
2382           }
2383
2384         /* Mask out any bits in operand[3] that are not needed.  */
2385            emit_insn (gen_andsi3 (op1, operands[3], op0));
2386
2387         if (GET_CODE (op0) == CONST_INT
2388             && (const_ok_for_arm (mask << start_bit)
2389                 || const_ok_for_arm (~(mask << start_bit))))
2390           {
2391             op0 = gen_int_mode (~(mask << start_bit), SImode);
2392             emit_insn (gen_andsi3 (op2, operands[0], op0));
2393           }
2394         else
2395           {
2396             if (GET_CODE (op0) == CONST_INT)
2397               {
2398                 rtx tmp = gen_reg_rtx (SImode);
2399
2400                 emit_insn (gen_movsi (tmp, op0));
2401                 op0 = tmp;
2402               }
2403
2404             if (start_bit != 0)
2405               emit_insn (gen_ashlsi3 (op0, op0, operands[2]));
2406             
2407             emit_insn (gen_andsi_notsi_si (op2, operands[0], op0));
2408           }
2409
2410         if (start_bit != 0)
2411           emit_insn (gen_ashlsi3 (op1, op1, operands[2]));
2412
2413         emit_insn (gen_iorsi3 (subtarget, op1, op2));
2414       }
2415
2416     if (subtarget != target)
2417       {
2418         /* If TARGET is still a SUBREG, then it must be wider than a word,
2419            so we must be careful only to set the subword we were asked to.  */
2420         if (GET_CODE (target) == SUBREG)
2421           emit_move_insn (target, subtarget);
2422         else
2423           emit_move_insn (target, gen_lowpart (GET_MODE (target), subtarget));
2424       }
2425
2426     DONE;
2427   }"
2428 )
2429
2430 (define_insn "insv_zero"
2431   [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r")
2432                          (match_operand:SI 1 "const_int_operand" "M")
2433                          (match_operand:SI 2 "const_int_operand" "M"))
2434         (const_int 0))]
2435   "arm_arch_thumb2"
2436   "bfc%?\t%0, %2, %1"
2437   [(set_attr "length" "4")
2438    (set_attr "predicable" "yes")]
2439 )
2440
2441 (define_insn "insv_t2"
2442   [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r")
2443                          (match_operand:SI 1 "const_int_operand" "M")
2444                          (match_operand:SI 2 "const_int_operand" "M"))
2445         (match_operand:SI 3 "s_register_operand" "r"))]
2446   "arm_arch_thumb2"
2447   "bfi%?\t%0, %3, %2, %1"
2448   [(set_attr "length" "4")
2449    (set_attr "predicable" "yes")]
2450 )
2451
2452 ; constants for op 2 will never be given to these patterns.
2453 (define_insn_and_split "*anddi_notdi_di"
2454   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2455         (and:DI (not:DI (match_operand:DI 1 "s_register_operand" "0,r"))
2456                 (match_operand:DI 2 "s_register_operand" "r,0")))]
2457   "TARGET_32BIT"
2458   "#"
2459   "TARGET_32BIT && reload_completed && ! IS_IWMMXT_REGNUM (REGNO (operands[0]))"
2460   [(set (match_dup 0) (and:SI (not:SI (match_dup 1)) (match_dup 2)))
2461    (set (match_dup 3) (and:SI (not:SI (match_dup 4)) (match_dup 5)))]
2462   "
2463   {
2464     operands[3] = gen_highpart (SImode, operands[0]);
2465     operands[0] = gen_lowpart (SImode, operands[0]);
2466     operands[4] = gen_highpart (SImode, operands[1]);
2467     operands[1] = gen_lowpart (SImode, operands[1]);
2468     operands[5] = gen_highpart (SImode, operands[2]);
2469     operands[2] = gen_lowpart (SImode, operands[2]);
2470   }"
2471   [(set_attr "length" "8")
2472    (set_attr "predicable" "yes")]
2473 )
2474   
2475 (define_insn_and_split "*anddi_notzesidi_di"
2476   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2477         (and:DI (not:DI (zero_extend:DI
2478                          (match_operand:SI 2 "s_register_operand" "r,r")))
2479                 (match_operand:DI 1 "s_register_operand" "0,?r")))]
2480   "TARGET_32BIT"
2481   "@
2482    bic%?\\t%Q0, %Q1, %2
2483    #"
2484   ; (not (zero_extend ...)) allows us to just copy the high word from
2485   ; operand1 to operand0.
2486   "TARGET_32BIT
2487    && reload_completed
2488    && operands[0] != operands[1]"
2489   [(set (match_dup 0) (and:SI (not:SI (match_dup 2)) (match_dup 1)))
2490    (set (match_dup 3) (match_dup 4))]
2491   "
2492   {
2493     operands[3] = gen_highpart (SImode, operands[0]);
2494     operands[0] = gen_lowpart (SImode, operands[0]);
2495     operands[4] = gen_highpart (SImode, operands[1]);
2496     operands[1] = gen_lowpart (SImode, operands[1]);
2497   }"
2498   [(set_attr "length" "4,8")
2499    (set_attr "predicable" "yes")]
2500 )
2501   
2502 (define_insn_and_split "*anddi_notsesidi_di"
2503   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2504         (and:DI (not:DI (sign_extend:DI
2505                          (match_operand:SI 2 "s_register_operand" "r,r")))
2506                 (match_operand:DI 1 "s_register_operand" "0,r")))]
2507   "TARGET_32BIT"
2508   "#"
2509   "TARGET_32BIT && reload_completed"
2510   [(set (match_dup 0) (and:SI (not:SI (match_dup 2)) (match_dup 1)))
2511    (set (match_dup 3) (and:SI (not:SI
2512                                 (ashiftrt:SI (match_dup 2) (const_int 31)))
2513                                (match_dup 4)))]
2514   "
2515   {
2516     operands[3] = gen_highpart (SImode, operands[0]);
2517     operands[0] = gen_lowpart (SImode, operands[0]);
2518     operands[4] = gen_highpart (SImode, operands[1]);
2519     operands[1] = gen_lowpart (SImode, operands[1]);
2520   }"
2521   [(set_attr "length" "8")
2522    (set_attr "predicable" "yes")]
2523 )
2524   
2525 (define_insn "andsi_notsi_si"
2526   [(set (match_operand:SI 0 "s_register_operand" "=r")
2527         (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
2528                 (match_operand:SI 1 "s_register_operand" "r")))]
2529   "TARGET_32BIT"
2530   "bic%?\\t%0, %1, %2"
2531   [(set_attr "predicable" "yes")]
2532 )
2533
2534 (define_insn "bicsi3"
2535   [(set (match_operand:SI                 0 "register_operand" "=l")
2536         (and:SI (not:SI (match_operand:SI 1 "register_operand" "l"))
2537                 (match_operand:SI         2 "register_operand" "0")))]
2538   "TARGET_THUMB1"
2539   "bic\\t%0, %0, %1"
2540   [(set_attr "length" "2")]
2541 )
2542
2543 (define_insn "andsi_not_shiftsi_si"
2544   [(set (match_operand:SI 0 "s_register_operand" "=r")
2545         (and:SI (not:SI (match_operator:SI 4 "shift_operator"
2546                          [(match_operand:SI 2 "s_register_operand" "r")
2547                           (match_operand:SI 3 "arm_rhs_operand" "rM")]))
2548                 (match_operand:SI 1 "s_register_operand" "r")))]
2549   "TARGET_ARM"
2550   "bic%?\\t%0, %1, %2%S4"
2551   [(set_attr "predicable" "yes")
2552    (set_attr "shift" "2")
2553    (set (attr "type") (if_then_else (match_operand 3 "const_int_operand" "")
2554                       (const_string "alu_shift")
2555                       (const_string "alu_shift_reg")))]
2556 )
2557
2558 (define_insn "*andsi_notsi_si_compare0"
2559   [(set (reg:CC_NOOV CC_REGNUM)
2560         (compare:CC_NOOV
2561          (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
2562                  (match_operand:SI 1 "s_register_operand" "r"))
2563          (const_int 0)))
2564    (set (match_operand:SI 0 "s_register_operand" "=r")
2565         (and:SI (not:SI (match_dup 2)) (match_dup 1)))]
2566   "TARGET_32BIT"
2567   "bic%.\\t%0, %1, %2"
2568   [(set_attr "conds" "set")]
2569 )
2570
2571 (define_insn "*andsi_notsi_si_compare0_scratch"
2572   [(set (reg:CC_NOOV CC_REGNUM)
2573         (compare:CC_NOOV
2574          (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
2575                  (match_operand:SI 1 "s_register_operand" "r"))
2576          (const_int 0)))
2577    (clobber (match_scratch:SI 0 "=r"))]
2578   "TARGET_32BIT"
2579   "bic%.\\t%0, %1, %2"
2580   [(set_attr "conds" "set")]
2581 )
2582
2583 (define_insn "iordi3"
2584   [(set (match_operand:DI         0 "s_register_operand" "=&r,&r")
2585         (ior:DI (match_operand:DI 1 "s_register_operand"  "%0,r")
2586                 (match_operand:DI 2 "s_register_operand"   "r,r")))]
2587   "TARGET_32BIT && ! TARGET_IWMMXT"
2588   "#"
2589   [(set_attr "length" "8")
2590    (set_attr "predicable" "yes")]
2591 )
2592
2593 (define_insn "*iordi_zesidi_di"
2594   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2595         (ior:DI (zero_extend:DI
2596                  (match_operand:SI 2 "s_register_operand" "r,r"))
2597                 (match_operand:DI 1 "s_register_operand" "0,?r")))]
2598   "TARGET_32BIT"
2599   "@
2600    orr%?\\t%Q0, %Q1, %2
2601    #"
2602   [(set_attr "length" "4,8")
2603    (set_attr "predicable" "yes")]
2604 )
2605
2606 (define_insn "*iordi_sesidi_di"
2607   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2608         (ior:DI (sign_extend:DI
2609                  (match_operand:SI 2 "s_register_operand" "r,r"))
2610                 (match_operand:DI 1 "s_register_operand" "0,r")))]
2611   "TARGET_32BIT"
2612   "#"
2613   [(set_attr "length" "8")
2614    (set_attr "predicable" "yes")]
2615 )
2616
2617 (define_expand "iorsi3"
2618   [(set (match_operand:SI         0 "s_register_operand" "")
2619         (ior:SI (match_operand:SI 1 "s_register_operand" "")
2620                 (match_operand:SI 2 "reg_or_int_operand" "")))]
2621   "TARGET_EITHER"
2622   "
2623   if (GET_CODE (operands[2]) == CONST_INT)
2624     {
2625       if (TARGET_32BIT)
2626         {
2627           arm_split_constant (IOR, SImode, NULL_RTX,
2628                               INTVAL (operands[2]), operands[0], operands[1],
2629                               optimize && can_create_pseudo_p ());
2630           DONE;
2631         }
2632       else /* TARGET_THUMB1 */
2633         {
2634           rtx tmp = force_reg (SImode, operands[2]);
2635           if (rtx_equal_p (operands[0], operands[1]))
2636             operands[2] = tmp;
2637           else
2638             {
2639               operands[2] = operands[1];
2640               operands[1] = tmp;
2641             }
2642         }
2643     }
2644   "
2645 )
2646
2647 (define_insn_and_split "*arm_iorsi3"
2648   [(set (match_operand:SI         0 "s_register_operand" "=r,r")
2649         (ior:SI (match_operand:SI 1 "s_register_operand" "r,r")
2650                 (match_operand:SI 2 "reg_or_int_operand" "rI,?n")))]
2651   "TARGET_ARM"
2652   "@
2653    orr%?\\t%0, %1, %2
2654    #"
2655   "TARGET_ARM
2656    && GET_CODE (operands[2]) == CONST_INT
2657    && !const_ok_for_arm (INTVAL (operands[2]))"
2658   [(clobber (const_int 0))]
2659   "
2660   arm_split_constant (IOR, SImode, curr_insn, 
2661                       INTVAL (operands[2]), operands[0], operands[1], 0);
2662   DONE;
2663   "
2664   [(set_attr "length" "4,16")
2665    (set_attr "predicable" "yes")]
2666 )
2667
2668 (define_insn "*thumb1_iorsi3"
2669   [(set (match_operand:SI         0 "register_operand" "=l")
2670         (ior:SI (match_operand:SI 1 "register_operand" "%0")
2671                 (match_operand:SI 2 "register_operand" "l")))]
2672   "TARGET_THUMB1"
2673   "orr\\t%0, %0, %2"
2674   [(set_attr "length" "2")]
2675 )
2676
2677 (define_peephole2
2678   [(match_scratch:SI 3 "r")
2679    (set (match_operand:SI 0 "arm_general_register_operand" "")
2680         (ior:SI (match_operand:SI 1 "arm_general_register_operand" "")
2681                 (match_operand:SI 2 "const_int_operand" "")))]
2682   "TARGET_ARM
2683    && !const_ok_for_arm (INTVAL (operands[2]))
2684    && const_ok_for_arm (~INTVAL (operands[2]))"
2685   [(set (match_dup 3) (match_dup 2))
2686    (set (match_dup 0) (ior:SI (match_dup 1) (match_dup 3)))]
2687   ""
2688 )
2689
2690 (define_insn "*iorsi3_compare0"
2691   [(set (reg:CC_NOOV CC_REGNUM)
2692         (compare:CC_NOOV (ior:SI (match_operand:SI 1 "s_register_operand" "%r")
2693                                  (match_operand:SI 2 "arm_rhs_operand" "rI"))
2694                          (const_int 0)))
2695    (set (match_operand:SI 0 "s_register_operand" "=r")
2696         (ior:SI (match_dup 1) (match_dup 2)))]
2697   "TARGET_32BIT"
2698   "orr%.\\t%0, %1, %2"
2699   [(set_attr "conds" "set")]
2700 )
2701
2702 (define_insn "*iorsi3_compare0_scratch"
2703   [(set (reg:CC_NOOV CC_REGNUM)
2704         (compare:CC_NOOV (ior:SI (match_operand:SI 1 "s_register_operand" "%r")
2705                                  (match_operand:SI 2 "arm_rhs_operand" "rI"))
2706                          (const_int 0)))
2707    (clobber (match_scratch:SI 0 "=r"))]
2708   "TARGET_32BIT"
2709   "orr%.\\t%0, %1, %2"
2710   [(set_attr "conds" "set")]
2711 )
2712
2713 (define_insn "xordi3"
2714   [(set (match_operand:DI         0 "s_register_operand" "=&r,&r")
2715         (xor:DI (match_operand:DI 1 "s_register_operand"  "%0,r")
2716                 (match_operand:DI 2 "s_register_operand"   "r,r")))]
2717   "TARGET_32BIT && !TARGET_IWMMXT"
2718   "#"
2719   [(set_attr "length" "8")
2720    (set_attr "predicable" "yes")]
2721 )
2722
2723 (define_insn "*xordi_zesidi_di"
2724   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2725         (xor:DI (zero_extend:DI
2726                  (match_operand:SI 2 "s_register_operand" "r,r"))
2727                 (match_operand:DI 1 "s_register_operand" "0,?r")))]
2728   "TARGET_32BIT"
2729   "@
2730    eor%?\\t%Q0, %Q1, %2
2731    #"
2732   [(set_attr "length" "4,8")
2733    (set_attr "predicable" "yes")]
2734 )
2735
2736 (define_insn "*xordi_sesidi_di"
2737   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2738         (xor:DI (sign_extend:DI
2739                  (match_operand:SI 2 "s_register_operand" "r,r"))
2740                 (match_operand:DI 1 "s_register_operand" "0,r")))]
2741   "TARGET_32BIT"
2742   "#"
2743   [(set_attr "length" "8")
2744    (set_attr "predicable" "yes")]
2745 )
2746
2747 (define_expand "xorsi3"
2748   [(set (match_operand:SI         0 "s_register_operand" "")
2749         (xor:SI (match_operand:SI 1 "s_register_operand" "")
2750                 (match_operand:SI 2 "reg_or_int_operand" "")))]
2751   "TARGET_EITHER"
2752   "if (GET_CODE (operands[2]) == CONST_INT)
2753     {
2754       if (TARGET_32BIT)
2755         {
2756           arm_split_constant (XOR, SImode, NULL_RTX,
2757                               INTVAL (operands[2]), operands[0], operands[1],
2758                               optimize && can_create_pseudo_p ());
2759           DONE;
2760         }
2761       else /* TARGET_THUMB1 */
2762         {
2763           rtx tmp = force_reg (SImode, operands[2]);
2764           if (rtx_equal_p (operands[0], operands[1]))
2765             operands[2] = tmp;
2766           else
2767             {
2768               operands[2] = operands[1];
2769               operands[1] = tmp;
2770             }
2771         }
2772     }"
2773 )
2774
2775 (define_insn "*arm_xorsi3"
2776   [(set (match_operand:SI         0 "s_register_operand" "=r")
2777         (xor:SI (match_operand:SI 1 "s_register_operand" "r")
2778                 (match_operand:SI 2 "arm_rhs_operand" "rI")))]
2779   "TARGET_32BIT"
2780   "eor%?\\t%0, %1, %2"
2781   [(set_attr "predicable" "yes")]
2782 )
2783
2784 (define_insn "*thumb1_xorsi3"
2785   [(set (match_operand:SI         0 "register_operand" "=l")
2786         (xor:SI (match_operand:SI 1 "register_operand" "%0")
2787                 (match_operand:SI 2 "register_operand" "l")))]
2788   "TARGET_THUMB1"
2789   "eor\\t%0, %0, %2"
2790   [(set_attr "length" "2")]
2791 )
2792
2793 (define_insn "*xorsi3_compare0"
2794   [(set (reg:CC_NOOV CC_REGNUM)
2795         (compare:CC_NOOV (xor:SI (match_operand:SI 1 "s_register_operand" "r")
2796                                  (match_operand:SI 2 "arm_rhs_operand" "rI"))
2797                          (const_int 0)))
2798    (set (match_operand:SI 0 "s_register_operand" "=r")
2799         (xor:SI (match_dup 1) (match_dup 2)))]
2800   "TARGET_32BIT"
2801   "eor%.\\t%0, %1, %2"
2802   [(set_attr "conds" "set")]
2803 )
2804
2805 (define_insn "*xorsi3_compare0_scratch"
2806   [(set (reg:CC_NOOV CC_REGNUM)
2807         (compare:CC_NOOV (xor:SI (match_operand:SI 0 "s_register_operand" "r")
2808                                  (match_operand:SI 1 "arm_rhs_operand" "rI"))
2809                          (const_int 0)))]
2810   "TARGET_32BIT"
2811   "teq%?\\t%0, %1"
2812   [(set_attr "conds" "set")]
2813 )
2814
2815 ; By splitting (IOR (AND (NOT A) (NOT B)) C) as D = AND (IOR A B) (NOT C), 
2816 ; (NOT D) we can sometimes merge the final NOT into one of the following
2817 ; insns.
2818
2819 (define_split
2820   [(set (match_operand:SI 0 "s_register_operand" "")
2821         (ior:SI (and:SI (not:SI (match_operand:SI 1 "s_register_operand" ""))
2822                         (not:SI (match_operand:SI 2 "arm_rhs_operand" "")))
2823                 (match_operand:SI 3 "arm_rhs_operand" "")))
2824    (clobber (match_operand:SI 4 "s_register_operand" ""))]
2825   "TARGET_32BIT"
2826   [(set (match_dup 4) (and:SI (ior:SI (match_dup 1) (match_dup 2))
2827                               (not:SI (match_dup 3))))
2828    (set (match_dup 0) (not:SI (match_dup 4)))]
2829   ""
2830 )
2831
2832 (define_insn "*andsi_iorsi3_notsi"
2833   [(set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r")
2834         (and:SI (ior:SI (match_operand:SI 1 "s_register_operand" "%0,r,r")
2835                         (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI"))
2836                 (not:SI (match_operand:SI 3 "arm_rhs_operand" "rI,rI,rI"))))]
2837   "TARGET_32BIT"
2838   "orr%?\\t%0, %1, %2\;bic%?\\t%0, %0, %3"
2839   [(set_attr "length" "8")
2840    (set_attr "ce_count" "2")
2841    (set_attr "predicable" "yes")]
2842 )
2843
2844 ; ??? Are these four splitters still beneficial when the Thumb-2 bitfield
2845 ; insns are available?
2846 (define_split
2847   [(set (match_operand:SI 0 "s_register_operand" "")
2848         (match_operator:SI 1 "logical_binary_operator"
2849          [(zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
2850                            (match_operand:SI 3 "const_int_operand" "")
2851                            (match_operand:SI 4 "const_int_operand" ""))
2852           (match_operator:SI 9 "logical_binary_operator"
2853            [(lshiftrt:SI (match_operand:SI 5 "s_register_operand" "")
2854                          (match_operand:SI 6 "const_int_operand" ""))
2855             (match_operand:SI 7 "s_register_operand" "")])]))
2856    (clobber (match_operand:SI 8 "s_register_operand" ""))]
2857   "TARGET_32BIT
2858    && GET_CODE (operands[1]) == GET_CODE (operands[9])
2859    && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
2860   [(set (match_dup 8)
2861         (match_op_dup 1
2862          [(ashift:SI (match_dup 2) (match_dup 4))
2863           (match_dup 5)]))
2864    (set (match_dup 0)
2865         (match_op_dup 1
2866          [(lshiftrt:SI (match_dup 8) (match_dup 6))
2867           (match_dup 7)]))]
2868   "
2869   operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
2870 ")
2871
2872 (define_split
2873   [(set (match_operand:SI 0 "s_register_operand" "")
2874         (match_operator:SI 1 "logical_binary_operator"
2875          [(match_operator:SI 9 "logical_binary_operator"
2876            [(lshiftrt:SI (match_operand:SI 5 "s_register_operand" "")
2877                          (match_operand:SI 6 "const_int_operand" ""))
2878             (match_operand:SI 7 "s_register_operand" "")])
2879           (zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
2880                            (match_operand:SI 3 "const_int_operand" "")
2881                            (match_operand:SI 4 "const_int_operand" ""))]))
2882    (clobber (match_operand:SI 8 "s_register_operand" ""))]
2883   "TARGET_32BIT
2884    && GET_CODE (operands[1]) == GET_CODE (operands[9])
2885    && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
2886   [(set (match_dup 8)
2887         (match_op_dup 1
2888          [(ashift:SI (match_dup 2) (match_dup 4))
2889           (match_dup 5)]))
2890    (set (match_dup 0)
2891         (match_op_dup 1
2892          [(lshiftrt:SI (match_dup 8) (match_dup 6))
2893           (match_dup 7)]))]
2894   "
2895   operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
2896 ")
2897
2898 (define_split
2899   [(set (match_operand:SI 0 "s_register_operand" "")
2900         (match_operator:SI 1 "logical_binary_operator"
2901          [(sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
2902                            (match_operand:SI 3 "const_int_operand" "")
2903                            (match_operand:SI 4 "const_int_operand" ""))
2904           (match_operator:SI 9 "logical_binary_operator"
2905            [(ashiftrt:SI (match_operand:SI 5 "s_register_operand" "")
2906                          (match_operand:SI 6 "const_int_operand" ""))
2907             (match_operand:SI 7 "s_register_operand" "")])]))
2908    (clobber (match_operand:SI 8 "s_register_operand" ""))]
2909   "TARGET_32BIT
2910    && GET_CODE (operands[1]) == GET_CODE (operands[9])
2911    && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
2912   [(set (match_dup 8)
2913         (match_op_dup 1
2914          [(ashift:SI (match_dup 2) (match_dup 4))
2915           (match_dup 5)]))
2916    (set (match_dup 0)
2917         (match_op_dup 1
2918          [(ashiftrt:SI (match_dup 8) (match_dup 6))
2919           (match_dup 7)]))]
2920   "
2921   operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
2922 ")
2923
2924 (define_split
2925   [(set (match_operand:SI 0 "s_register_operand" "")
2926         (match_operator:SI 1 "logical_binary_operator"
2927          [(match_operator:SI 9 "logical_binary_operator"
2928            [(ashiftrt:SI (match_operand:SI 5 "s_register_operand" "")
2929                          (match_operand:SI 6 "const_int_operand" ""))
2930             (match_operand:SI 7 "s_register_operand" "")])
2931           (sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
2932                            (match_operand:SI 3 "const_int_operand" "")
2933                            (match_operand:SI 4 "const_int_operand" ""))]))
2934    (clobber (match_operand:SI 8 "s_register_operand" ""))]
2935   "TARGET_32BIT
2936    && GET_CODE (operands[1]) == GET_CODE (operands[9])
2937    && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
2938   [(set (match_dup 8)
2939         (match_op_dup 1
2940          [(ashift:SI (match_dup 2) (match_dup 4))
2941           (match_dup 5)]))
2942    (set (match_dup 0)
2943         (match_op_dup 1
2944          [(ashiftrt:SI (match_dup 8) (match_dup 6))
2945           (match_dup 7)]))]
2946   "
2947   operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
2948 ")
2949 \f
2950
2951 ;; Minimum and maximum insns
2952
2953 (define_expand "smaxsi3"
2954   [(parallel [
2955     (set (match_operand:SI 0 "s_register_operand" "")
2956          (smax:SI (match_operand:SI 1 "s_register_operand" "")
2957                   (match_operand:SI 2 "arm_rhs_operand" "")))
2958     (clobber (reg:CC CC_REGNUM))])]
2959   "TARGET_32BIT"
2960   "
2961   if (operands[2] == const0_rtx || operands[2] == constm1_rtx)
2962     {
2963       /* No need for a clobber of the condition code register here.  */
2964       emit_insn (gen_rtx_SET (VOIDmode, operands[0],
2965                               gen_rtx_SMAX (SImode, operands[1],
2966                                             operands[2])));
2967       DONE;
2968     }
2969 ")
2970
2971 (define_insn "*smax_0"
2972   [(set (match_operand:SI 0 "s_register_operand" "=r")
2973         (smax:SI (match_operand:SI 1 "s_register_operand" "r")
2974                  (const_int 0)))]
2975   "TARGET_32BIT"
2976   "bic%?\\t%0, %1, %1, asr #31"
2977   [(set_attr "predicable" "yes")]
2978 )
2979
2980 (define_insn "*smax_m1"
2981   [(set (match_operand:SI 0 "s_register_operand" "=r")
2982         (smax:SI (match_operand:SI 1 "s_register_operand" "r")
2983                  (const_int -1)))]
2984   "TARGET_32BIT"
2985   "orr%?\\t%0, %1, %1, asr #31"
2986   [(set_attr "predicable" "yes")]
2987 )
2988
2989 (define_insn "*arm_smax_insn"
2990   [(set (match_operand:SI          0 "s_register_operand" "=r,r")
2991         (smax:SI (match_operand:SI 1 "s_register_operand"  "%0,?r")
2992                  (match_operand:SI 2 "arm_rhs_operand"    "rI,rI")))
2993    (clobber (reg:CC CC_REGNUM))]
2994   "TARGET_ARM"
2995   "@
2996    cmp\\t%1, %2\;movlt\\t%0, %2
2997    cmp\\t%1, %2\;movge\\t%0, %1\;movlt\\t%0, %2"
2998   [(set_attr "conds" "clob")
2999    (set_attr "length" "8,12")]
3000 )
3001
3002 (define_expand "sminsi3"
3003   [(parallel [
3004     (set (match_operand:SI 0 "s_register_operand" "")
3005          (smin:SI (match_operand:SI 1 "s_register_operand" "")
3006                   (match_operand:SI 2 "arm_rhs_operand" "")))
3007     (clobber (reg:CC CC_REGNUM))])]
3008   "TARGET_32BIT"
3009   "
3010   if (operands[2] == const0_rtx)
3011     {
3012       /* No need for a clobber of the condition code register here.  */
3013       emit_insn (gen_rtx_SET (VOIDmode, operands[0],
3014                               gen_rtx_SMIN (SImode, operands[1],
3015                                             operands[2])));
3016       DONE;
3017     }
3018 ")
3019
3020 (define_insn "*smin_0"
3021   [(set (match_operand:SI 0 "s_register_operand" "=r")
3022         (smin:SI (match_operand:SI 1 "s_register_operand" "r")
3023                  (const_int 0)))]
3024   "TARGET_32BIT"
3025   "and%?\\t%0, %1, %1, asr #31"
3026   [(set_attr "predicable" "yes")]
3027 )
3028
3029 (define_insn "*arm_smin_insn"
3030   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3031         (smin:SI (match_operand:SI 1 "s_register_operand" "%0,?r")
3032                  (match_operand:SI 2 "arm_rhs_operand" "rI,rI")))
3033    (clobber (reg:CC CC_REGNUM))]
3034   "TARGET_ARM"
3035   "@
3036    cmp\\t%1, %2\;movge\\t%0, %2
3037    cmp\\t%1, %2\;movlt\\t%0, %1\;movge\\t%0, %2"
3038   [(set_attr "conds" "clob")
3039    (set_attr "length" "8,12")]
3040 )
3041
3042 (define_expand "umaxsi3"
3043   [(parallel [
3044     (set (match_operand:SI 0 "s_register_operand" "")
3045          (umax:SI (match_operand:SI 1 "s_register_operand" "")
3046                   (match_operand:SI 2 "arm_rhs_operand" "")))
3047     (clobber (reg:CC CC_REGNUM))])]
3048   "TARGET_32BIT"
3049   ""
3050 )
3051
3052 (define_insn "*arm_umaxsi3"
3053   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
3054         (umax:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
3055                  (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
3056    (clobber (reg:CC CC_REGNUM))]
3057   "TARGET_ARM"
3058   "@
3059    cmp\\t%1, %2\;movcc\\t%0, %2
3060    cmp\\t%1, %2\;movcs\\t%0, %1
3061    cmp\\t%1, %2\;movcs\\t%0, %1\;movcc\\t%0, %2"
3062   [(set_attr "conds" "clob")
3063    (set_attr "length" "8,8,12")]
3064 )
3065
3066 (define_expand "uminsi3"
3067   [(parallel [
3068     (set (match_operand:SI 0 "s_register_operand" "")
3069          (umin:SI (match_operand:SI 1 "s_register_operand" "")
3070                   (match_operand:SI 2 "arm_rhs_operand" "")))
3071     (clobber (reg:CC CC_REGNUM))])]
3072   "TARGET_32BIT"
3073   ""
3074 )
3075
3076 (define_insn "*arm_uminsi3"
3077   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
3078         (umin:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
3079                  (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
3080    (clobber (reg:CC CC_REGNUM))]
3081   "TARGET_ARM"
3082   "@
3083    cmp\\t%1, %2\;movcs\\t%0, %2
3084    cmp\\t%1, %2\;movcc\\t%0, %1
3085    cmp\\t%1, %2\;movcc\\t%0, %1\;movcs\\t%0, %2"
3086   [(set_attr "conds" "clob")
3087    (set_attr "length" "8,8,12")]
3088 )
3089
3090 (define_insn "*store_minmaxsi"
3091   [(set (match_operand:SI 0 "memory_operand" "=m")
3092         (match_operator:SI 3 "minmax_operator"
3093          [(match_operand:SI 1 "s_register_operand" "r")
3094           (match_operand:SI 2 "s_register_operand" "r")]))
3095    (clobber (reg:CC CC_REGNUM))]
3096   "TARGET_32BIT"
3097   "*
3098   operands[3] = gen_rtx_fmt_ee (minmax_code (operands[3]), SImode,
3099                                 operands[1], operands[2]);
3100   output_asm_insn (\"cmp\\t%1, %2\", operands);
3101   if (TARGET_THUMB2)
3102     output_asm_insn (\"ite\t%d3\", operands);
3103   output_asm_insn (\"str%d3\\t%1, %0\", operands);
3104   output_asm_insn (\"str%D3\\t%2, %0\", operands);
3105   return \"\";
3106   "
3107   [(set_attr "conds" "clob")
3108    (set (attr "length")
3109         (if_then_else (eq_attr "is_thumb" "yes")
3110                       (const_int 14)
3111                       (const_int 12)))
3112    (set_attr "type" "store1")]
3113 )
3114
3115 ; Reject the frame pointer in operand[1], since reloading this after
3116 ; it has been eliminated can cause carnage.
3117 (define_insn "*minmax_arithsi"
3118   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3119         (match_operator:SI 4 "shiftable_operator"
3120          [(match_operator:SI 5 "minmax_operator"
3121            [(match_operand:SI 2 "s_register_operand" "r,r")
3122             (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
3123           (match_operand:SI 1 "s_register_operand" "0,?r")]))
3124    (clobber (reg:CC CC_REGNUM))]
3125   "TARGET_32BIT && !arm_eliminable_register (operands[1])"
3126   "*
3127   {
3128     enum rtx_code code = GET_CODE (operands[4]);
3129     bool need_else;
3130
3131     if (which_alternative != 0 || operands[3] != const0_rtx
3132         || (code != PLUS && code != MINUS && code != IOR && code != XOR))
3133       need_else = true;
3134     else
3135       need_else = false;
3136
3137     operands[5] = gen_rtx_fmt_ee (minmax_code (operands[5]), SImode,
3138                                   operands[2], operands[3]);
3139     output_asm_insn (\"cmp\\t%2, %3\", operands);
3140     if (TARGET_THUMB2)
3141       {
3142         if (need_else)
3143           output_asm_insn (\"ite\\t%d5\", operands);
3144         else
3145           output_asm_insn (\"it\\t%d5\", operands);
3146       }
3147     output_asm_insn (\"%i4%d5\\t%0, %1, %2\", operands);
3148     if (need_else)
3149       output_asm_insn (\"%i4%D5\\t%0, %1, %3\", operands);
3150     return \"\";
3151   }"
3152   [(set_attr "conds" "clob")
3153    (set (attr "length")
3154         (if_then_else (eq_attr "is_thumb" "yes")
3155                       (const_int 14)
3156                       (const_int 12)))]
3157 )
3158
3159 \f
3160 ;; Shift and rotation insns
3161
3162 (define_expand "ashldi3"
3163   [(set (match_operand:DI            0 "s_register_operand" "")
3164         (ashift:DI (match_operand:DI 1 "s_register_operand" "")
3165                    (match_operand:SI 2 "reg_or_int_operand" "")))]
3166   "TARGET_32BIT"
3167   "
3168   if (GET_CODE (operands[2]) == CONST_INT)
3169     {
3170       if ((HOST_WIDE_INT) INTVAL (operands[2]) == 1)
3171         {
3172           emit_insn (gen_arm_ashldi3_1bit (operands[0], operands[1]));
3173           DONE;
3174         }
3175         /* Ideally we shouldn't fail here if we could know that operands[1] 
3176            ends up already living in an iwmmxt register. Otherwise it's
3177            cheaper to have the alternate code being generated than moving
3178            values to iwmmxt regs and back.  */
3179         FAIL;
3180     }
3181   else if (!TARGET_REALLY_IWMMXT && !(TARGET_HARD_FLOAT && TARGET_MAVERICK))
3182     FAIL;
3183   "
3184 )
3185
3186 (define_insn "arm_ashldi3_1bit"
3187   [(set (match_operand:DI            0 "s_register_operand" "=&r,r")
3188         (ashift:DI (match_operand:DI 1 "s_register_operand" "0,r")
3189                    (const_int 1)))
3190    (clobber (reg:CC CC_REGNUM))]
3191   "TARGET_32BIT"
3192   "movs\\t%Q0, %Q1, asl #1\;adc\\t%R0, %R1, %R1"
3193   [(set_attr "conds" "clob")
3194    (set_attr "length" "8")]
3195 )
3196
3197 (define_expand "ashlsi3"
3198   [(set (match_operand:SI            0 "s_register_operand" "")
3199         (ashift:SI (match_operand:SI 1 "s_register_operand" "")
3200                    (match_operand:SI 2 "arm_rhs_operand" "")))]
3201   "TARGET_EITHER"
3202   "
3203   if (GET_CODE (operands[2]) == CONST_INT
3204       && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) > 31)
3205     {
3206       emit_insn (gen_movsi (operands[0], const0_rtx));
3207       DONE;
3208     }
3209   "
3210 )
3211
3212 (define_insn "*thumb1_ashlsi3"
3213   [(set (match_operand:SI            0 "register_operand" "=l,l")
3214         (ashift:SI (match_operand:SI 1 "register_operand" "l,0")
3215                    (match_operand:SI 2 "nonmemory_operand" "N,l")))]
3216   "TARGET_THUMB1"
3217   "lsl\\t%0, %1, %2"
3218   [(set_attr "length" "2")]
3219 )
3220
3221 (define_expand "ashrdi3"
3222   [(set (match_operand:DI              0 "s_register_operand" "")
3223         (ashiftrt:DI (match_operand:DI 1 "s_register_operand" "")
3224                      (match_operand:SI 2 "reg_or_int_operand" "")))]
3225   "TARGET_32BIT"
3226   "
3227   if (GET_CODE (operands[2]) == CONST_INT)
3228     {
3229       if ((HOST_WIDE_INT) INTVAL (operands[2]) == 1)
3230         {
3231           emit_insn (gen_arm_ashrdi3_1bit (operands[0], operands[1]));
3232           DONE;
3233         }
3234         /* Ideally we shouldn't fail here if we could know that operands[1] 
3235            ends up already living in an iwmmxt register. Otherwise it's
3236            cheaper to have the alternate code being generated than moving
3237            values to iwmmxt regs and back.  */
3238         FAIL;
3239     }
3240   else if (!TARGET_REALLY_IWMMXT)
3241     FAIL;
3242   "
3243 )
3244
3245 (define_insn "arm_ashrdi3_1bit"
3246   [(set (match_operand:DI              0 "s_register_operand" "=&r,r")
3247         (ashiftrt:DI (match_operand:DI 1 "s_register_operand" "0,r")
3248                      (const_int 1)))
3249    (clobber (reg:CC CC_REGNUM))]
3250   "TARGET_32BIT"
3251   "movs\\t%R0, %R1, asr #1\;mov\\t%Q0, %Q1, rrx"
3252   [(set_attr "conds" "clob")
3253    (set_attr "length" "8")]
3254 )
3255
3256 (define_expand "ashrsi3"
3257   [(set (match_operand:SI              0 "s_register_operand" "")
3258         (ashiftrt:SI (match_operand:SI 1 "s_register_operand" "")
3259                      (match_operand:SI 2 "arm_rhs_operand" "")))]
3260   "TARGET_EITHER"
3261   "
3262   if (GET_CODE (operands[2]) == CONST_INT
3263       && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) > 31)
3264     operands[2] = GEN_INT (31);
3265   "
3266 )
3267
3268 (define_insn "*thumb1_ashrsi3"
3269   [(set (match_operand:SI              0 "register_operand" "=l,l")
3270         (ashiftrt:SI (match_operand:SI 1 "register_operand" "l,0")
3271                      (match_operand:SI 2 "nonmemory_operand" "N,l")))]
3272   "TARGET_THUMB1"
3273   "asr\\t%0, %1, %2"
3274   [(set_attr "length" "2")]
3275 )
3276
3277 (define_expand "lshrdi3"
3278   [(set (match_operand:DI              0 "s_register_operand" "")
3279         (lshiftrt:DI (match_operand:DI 1 "s_register_operand" "")
3280                      (match_operand:SI 2 "reg_or_int_operand" "")))]
3281   "TARGET_32BIT"
3282   "
3283   if (GET_CODE (operands[2]) == CONST_INT)
3284     {
3285       if ((HOST_WIDE_INT) INTVAL (operands[2]) == 1)
3286         {
3287           emit_insn (gen_arm_lshrdi3_1bit (operands[0], operands[1]));
3288           DONE;
3289         }
3290         /* Ideally we shouldn't fail here if we could know that operands[1] 
3291            ends up already living in an iwmmxt register. Otherwise it's
3292            cheaper to have the alternate code being generated than moving
3293            values to iwmmxt regs and back.  */
3294         FAIL;
3295     }
3296   else if (!TARGET_REALLY_IWMMXT)
3297     FAIL;
3298   "
3299 )
3300
3301 (define_insn "arm_lshrdi3_1bit"
3302   [(set (match_operand:DI              0 "s_register_operand" "=&r,r")
3303         (lshiftrt:DI (match_operand:DI 1 "s_register_operand" "0,r")
3304                      (const_int 1)))
3305    (clobber (reg:CC CC_REGNUM))]
3306   "TARGET_32BIT"
3307   "movs\\t%R0, %R1, lsr #1\;mov\\t%Q0, %Q1, rrx"
3308   [(set_attr "conds" "clob")
3309    (set_attr "length" "8")]
3310 )
3311
3312 (define_expand "lshrsi3"
3313   [(set (match_operand:SI              0 "s_register_operand" "")
3314         (lshiftrt:SI (match_operand:SI 1 "s_register_operand" "")
3315                      (match_operand:SI 2 "arm_rhs_operand" "")))]
3316   "TARGET_EITHER"
3317   "
3318   if (GET_CODE (operands[2]) == CONST_INT
3319       && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) > 31)
3320     {
3321       emit_insn (gen_movsi (operands[0], const0_rtx));
3322       DONE;
3323     }
3324   "
3325 )
3326
3327 (define_insn "*thumb1_lshrsi3"
3328   [(set (match_operand:SI              0 "register_operand" "=l,l")
3329         (lshiftrt:SI (match_operand:SI 1 "register_operand" "l,0")
3330                      (match_operand:SI 2 "nonmemory_operand" "N,l")))]
3331   "TARGET_THUMB1"
3332   "lsr\\t%0, %1, %2"
3333   [(set_attr "length" "2")]
3334 )
3335
3336 (define_expand "rotlsi3"
3337   [(set (match_operand:SI              0 "s_register_operand" "")
3338         (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
3339                      (match_operand:SI 2 "reg_or_int_operand" "")))]
3340   "TARGET_32BIT"
3341   "
3342   if (GET_CODE (operands[2]) == CONST_INT)
3343     operands[2] = GEN_INT ((32 - INTVAL (operands[2])) % 32);
3344   else
3345     {
3346       rtx reg = gen_reg_rtx (SImode);
3347       emit_insn (gen_subsi3 (reg, GEN_INT (32), operands[2]));
3348       operands[2] = reg;
3349     }
3350   "
3351 )
3352
3353 (define_expand "rotrsi3"
3354   [(set (match_operand:SI              0 "s_register_operand" "")
3355         (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
3356                      (match_operand:SI 2 "arm_rhs_operand" "")))]
3357   "TARGET_EITHER"
3358   "
3359   if (TARGET_32BIT)
3360     {
3361       if (GET_CODE (operands[2]) == CONST_INT
3362           && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) > 31)