OSDN Git Service

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