OSDN Git Service

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