OSDN Git Service

6493a791a4a20c1118a608a8c3977ad7dd385a0f
[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 )
853
854 (define_insn "*compare_negsi_si"
855   [(set (reg:CC_Z CC_REGNUM)
856         (compare:CC_Z
857          (neg:SI (match_operand:SI 0 "s_register_operand" "r"))
858          (match_operand:SI 1 "s_register_operand" "r")))]
859   "TARGET_32BIT"
860   "cmn%?\\t%1, %0"
861   [(set_attr "conds" "set")]
862 )
863
864 ;; This is the canonicalization of addsi3_compare0_for_combiner when the
865 ;; addend is a constant.
866 (define_insn "*cmpsi2_addneg"
867   [(set (reg:CC CC_REGNUM)
868         (compare:CC
869          (match_operand:SI 1 "s_register_operand" "r,r")
870          (match_operand:SI 2 "arm_addimm_operand" "L,I")))
871    (set (match_operand:SI 0 "s_register_operand" "=r,r")
872         (plus:SI (match_dup 1)
873                  (match_operand:SI 3 "arm_addimm_operand" "I,L")))]
874   "TARGET_32BIT && INTVAL (operands[2]) == -INTVAL (operands[3])"
875   "@
876    add%.\\t%0, %1, %3
877    sub%.\\t%0, %1, #%n3"
878   [(set_attr "conds" "set")]
879 )
880
881 ;; Convert the sequence
882 ;;  sub  rd, rn, #1
883 ;;  cmn  rd, #1 (equivalent to cmp rd, #-1)
884 ;;  bne  dest
885 ;; into
886 ;;  subs rd, rn, #1
887 ;;  bcs  dest   ((unsigned)rn >= 1)
888 ;; similarly for the beq variant using bcc.
889 ;; This is a common looping idiom (while (n--))
890 (define_peephole2
891   [(set (match_operand:SI 0 "arm_general_register_operand" "")
892         (plus:SI (match_operand:SI 1 "arm_general_register_operand" "")
893                  (const_int -1)))
894    (set (match_operand 2 "cc_register" "")
895         (compare (match_dup 0) (const_int -1)))
896    (set (pc)
897         (if_then_else (match_operator 3 "equality_operator"
898                        [(match_dup 2) (const_int 0)])
899                       (match_operand 4 "" "")
900                       (match_operand 5 "" "")))]
901   "TARGET_32BIT && peep2_reg_dead_p (3, operands[2])"
902   [(parallel[
903     (set (match_dup 2)
904          (compare:CC
905           (match_dup 1) (const_int 1)))
906     (set (match_dup 0) (plus:SI (match_dup 1) (const_int -1)))])
907    (set (pc)
908         (if_then_else (match_op_dup 3 [(match_dup 2) (const_int 0)])
909                       (match_dup 4)
910                       (match_dup 5)))]
911   "operands[2] = gen_rtx_REG (CCmode, CC_REGNUM);
912    operands[3] = gen_rtx_fmt_ee ((GET_CODE (operands[3]) == NE
913                                   ? GEU : LTU),
914                                  VOIDmode, 
915                                  operands[2], const0_rtx);"
916 )
917
918 ;; The next four insns work because they compare the result with one of
919 ;; the operands, and we know that the use of the condition code is
920 ;; either GEU or LTU, so we can use the carry flag from the addition
921 ;; instead of doing the compare a second time.
922 (define_insn "*addsi3_compare_op1"
923   [(set (reg:CC_C CC_REGNUM)
924         (compare:CC_C
925          (plus:SI (match_operand:SI 1 "s_register_operand" "r,r")
926                   (match_operand:SI 2 "arm_add_operand" "rI,L"))
927          (match_dup 1)))
928    (set (match_operand:SI 0 "s_register_operand" "=r,r")
929         (plus:SI (match_dup 1) (match_dup 2)))]
930   "TARGET_32BIT"
931   "@
932    add%.\\t%0, %1, %2
933    sub%.\\t%0, %1, #%n2"
934   [(set_attr "conds" "set")]
935 )
936
937 (define_insn "*addsi3_compare_op2"
938   [(set (reg:CC_C CC_REGNUM)
939         (compare:CC_C
940          (plus:SI (match_operand:SI 1 "s_register_operand" "r,r")
941                   (match_operand:SI 2 "arm_add_operand" "rI,L"))
942          (match_dup 2)))
943    (set (match_operand:SI 0 "s_register_operand" "=r,r")
944         (plus:SI (match_dup 1) (match_dup 2)))]
945   "TARGET_32BIT"
946   "@
947    add%.\\t%0, %1, %2
948    sub%.\\t%0, %1, #%n2"
949   [(set_attr "conds" "set")]
950 )
951
952 (define_insn "*compare_addsi2_op0"
953   [(set (reg:CC_C CC_REGNUM)
954         (compare:CC_C
955          (plus:SI (match_operand:SI 0 "s_register_operand" "r,r")
956                   (match_operand:SI 1 "arm_add_operand" "rI,L"))
957          (match_dup 0)))]
958   "TARGET_32BIT"
959   "@
960    cmn%?\\t%0, %1
961    cmp%?\\t%0, #%n1"
962   [(set_attr "conds" "set")]
963 )
964
965 (define_insn "*compare_addsi2_op1"
966   [(set (reg:CC_C CC_REGNUM)
967         (compare:CC_C
968          (plus:SI (match_operand:SI 0 "s_register_operand" "r,r")
969                   (match_operand:SI 1 "arm_add_operand" "rI,L"))
970          (match_dup 1)))]
971   "TARGET_32BIT"
972   "@
973    cmn%?\\t%0, %1
974    cmp%?\\t%0, #%n1"
975   [(set_attr "conds" "set")]
976 )
977
978 (define_insn "*addsi3_carryin_<optab>"
979   [(set (match_operand:SI 0 "s_register_operand" "=r")
980         (plus:SI (plus:SI (match_operand:SI 1 "s_register_operand" "%r")
981                           (match_operand:SI 2 "arm_rhs_operand" "rI"))
982                  (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))))]
983   "TARGET_32BIT"
984   "adc%?\\t%0, %1, %2"
985   [(set_attr "conds" "use")]
986 )
987
988 (define_insn "*addsi3_carryin_alt2_<optab>"
989   [(set (match_operand:SI 0 "s_register_operand" "=r")
990         (plus:SI (plus:SI (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))
991                           (match_operand:SI 1 "s_register_operand" "%r"))
992                  (match_operand:SI 2 "arm_rhs_operand" "rI")))]
993   "TARGET_32BIT"
994   "adc%?\\t%0, %1, %2"
995   [(set_attr "conds" "use")]
996 )
997
998 (define_insn "*addsi3_carryin_shift_<optab>"
999   [(set (match_operand:SI 0 "s_register_operand" "=r")
1000         (plus:SI (plus:SI
1001                   (match_operator:SI 2 "shift_operator"
1002                     [(match_operand:SI 3 "s_register_operand" "r")
1003                      (match_operand:SI 4 "reg_or_int_operand" "rM")])
1004                   (match_operand:SI 1 "s_register_operand" "r"))
1005                  (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))))]
1006   "TARGET_32BIT"
1007   "adc%?\\t%0, %1, %3%S2"
1008   [(set_attr "conds" "use")
1009    (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
1010                       (const_string "alu_shift")
1011                       (const_string "alu_shift_reg")))]
1012 )
1013
1014 (define_insn "*addsi3_carryin_clobercc_<optab>"
1015   [(set (match_operand:SI 0 "s_register_operand" "=r")
1016         (plus:SI (plus:SI (match_operand:SI 1 "s_register_operand" "%r")
1017                           (match_operand:SI 2 "arm_rhs_operand" "rI"))
1018                  (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))))
1019    (clobber (reg:CC CC_REGNUM))]
1020    "TARGET_32BIT"
1021    "adc%.\\t%0, %1, %2"
1022    [(set_attr "conds" "set")]
1023 )
1024
1025 (define_expand "incscc"
1026   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
1027         (plus:SI (match_operator:SI 2 "arm_comparison_operator"
1028                     [(match_operand:CC 3 "cc_register" "") (const_int 0)])
1029                  (match_operand:SI 1 "s_register_operand" "0,?r")))]
1030   "TARGET_32BIT"
1031   ""
1032 )
1033
1034 (define_insn "*arm_incscc"
1035   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
1036         (plus:SI (match_operator:SI 2 "arm_comparison_operator"
1037                     [(match_operand:CC 3 "cc_register" "") (const_int 0)])
1038                  (match_operand:SI 1 "s_register_operand" "0,?r")))]
1039   "TARGET_ARM"
1040   "@
1041   add%d2\\t%0, %1, #1
1042   mov%D2\\t%0, %1\;add%d2\\t%0, %1, #1"
1043   [(set_attr "conds" "use")
1044    (set_attr "length" "4,8")]
1045 )
1046
1047 ; transform ((x << y) - 1) to ~(~(x-1) << y)  Where X is a constant.
1048 (define_split
1049   [(set (match_operand:SI 0 "s_register_operand" "")
1050         (plus:SI (ashift:SI (match_operand:SI 1 "const_int_operand" "")
1051                             (match_operand:SI 2 "s_register_operand" ""))
1052                  (const_int -1)))
1053    (clobber (match_operand:SI 3 "s_register_operand" ""))]
1054   "TARGET_32BIT"
1055   [(set (match_dup 3) (match_dup 1))
1056    (set (match_dup 0) (not:SI (ashift:SI (match_dup 3) (match_dup 2))))]
1057   "
1058   operands[1] = GEN_INT (~(INTVAL (operands[1]) - 1));
1059 ")
1060
1061 (define_expand "addsf3"
1062   [(set (match_operand:SF          0 "s_register_operand" "")
1063         (plus:SF (match_operand:SF 1 "s_register_operand" "")
1064                  (match_operand:SF 2 "arm_float_add_operand" "")))]
1065   "TARGET_32BIT && TARGET_HARD_FLOAT"
1066   "
1067   if (TARGET_MAVERICK
1068       && !cirrus_fp_register (operands[2], SFmode))
1069     operands[2] = force_reg (SFmode, operands[2]);
1070 ")
1071
1072 (define_expand "adddf3"
1073   [(set (match_operand:DF          0 "s_register_operand" "")
1074         (plus:DF (match_operand:DF 1 "s_register_operand" "")
1075                  (match_operand:DF 2 "arm_float_add_operand" "")))]
1076   "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
1077   "
1078   if (TARGET_MAVERICK
1079       && !cirrus_fp_register (operands[2], DFmode))
1080     operands[2] = force_reg (DFmode, operands[2]);
1081 ")
1082
1083 (define_expand "subdi3"
1084  [(parallel
1085    [(set (match_operand:DI            0 "s_register_operand" "")
1086           (minus:DI (match_operand:DI 1 "s_register_operand" "")
1087                     (match_operand:DI 2 "s_register_operand" "")))
1088     (clobber (reg:CC CC_REGNUM))])]
1089   "TARGET_EITHER"
1090   "
1091   if (TARGET_HARD_FLOAT && TARGET_MAVERICK
1092       && TARGET_32BIT
1093       && cirrus_fp_register (operands[0], DImode)
1094       && cirrus_fp_register (operands[1], DImode))
1095     {
1096       emit_insn (gen_cirrus_subdi3 (operands[0], operands[1], operands[2]));
1097       DONE;
1098     }
1099
1100   if (TARGET_THUMB1)
1101     {
1102       if (GET_CODE (operands[1]) != REG)
1103         operands[1] = force_reg (DImode, operands[1]);
1104       if (GET_CODE (operands[2]) != REG)
1105         operands[2] = force_reg (DImode, operands[2]);
1106      }  
1107   "
1108 )
1109
1110 (define_insn "*arm_subdi3"
1111   [(set (match_operand:DI           0 "s_register_operand" "=&r,&r,&r")
1112         (minus:DI (match_operand:DI 1 "s_register_operand" "0,r,0")
1113                   (match_operand:DI 2 "s_register_operand" "r,0,0")))
1114    (clobber (reg:CC CC_REGNUM))]
1115   "TARGET_32BIT && !TARGET_NEON"
1116   "subs\\t%Q0, %Q1, %Q2\;sbc\\t%R0, %R1, %R2"
1117   [(set_attr "conds" "clob")
1118    (set_attr "length" "8")]
1119 )
1120
1121 (define_insn "*thumb_subdi3"
1122   [(set (match_operand:DI           0 "register_operand" "=l")
1123         (minus:DI (match_operand:DI 1 "register_operand"  "0")
1124                   (match_operand:DI 2 "register_operand"  "l")))
1125    (clobber (reg:CC CC_REGNUM))]
1126   "TARGET_THUMB1"
1127   "sub\\t%Q0, %Q0, %Q2\;sbc\\t%R0, %R0, %R2"
1128   [(set_attr "length" "4")]
1129 )
1130
1131 (define_insn "*subdi_di_zesidi"
1132   [(set (match_operand:DI           0 "s_register_operand" "=&r,&r")
1133         (minus:DI (match_operand:DI 1 "s_register_operand"  "0,r")
1134                   (zero_extend:DI
1135                    (match_operand:SI 2 "s_register_operand"  "r,r"))))
1136    (clobber (reg:CC CC_REGNUM))]
1137   "TARGET_32BIT"
1138   "subs\\t%Q0, %Q1, %2\;sbc\\t%R0, %R1, #0"
1139   [(set_attr "conds" "clob")
1140    (set_attr "length" "8")]
1141 )
1142
1143 (define_insn "*subdi_di_sesidi"
1144   [(set (match_operand:DI            0 "s_register_operand" "=&r,&r")
1145         (minus:DI (match_operand:DI  1 "s_register_operand"  "0,r")
1146                   (sign_extend:DI
1147                    (match_operand:SI 2 "s_register_operand"  "r,r"))))
1148    (clobber (reg:CC CC_REGNUM))]
1149   "TARGET_32BIT"
1150   "subs\\t%Q0, %Q1, %2\;sbc\\t%R0, %R1, %2, asr #31"
1151   [(set_attr "conds" "clob")
1152    (set_attr "length" "8")]
1153 )
1154
1155 (define_insn "*subdi_zesidi_di"
1156   [(set (match_operand:DI            0 "s_register_operand" "=&r,&r")
1157         (minus:DI (zero_extend:DI
1158                    (match_operand:SI 2 "s_register_operand"  "r,r"))
1159                   (match_operand:DI  1 "s_register_operand" "0,r")))
1160    (clobber (reg:CC CC_REGNUM))]
1161   "TARGET_ARM"
1162   "rsbs\\t%Q0, %Q1, %2\;rsc\\t%R0, %R1, #0"
1163   [(set_attr "conds" "clob")
1164    (set_attr "length" "8")]
1165 )
1166
1167 (define_insn "*subdi_sesidi_di"
1168   [(set (match_operand:DI            0 "s_register_operand" "=&r,&r")
1169         (minus:DI (sign_extend:DI
1170                    (match_operand:SI 2 "s_register_operand"   "r,r"))
1171                   (match_operand:DI  1 "s_register_operand"  "0,r")))
1172    (clobber (reg:CC CC_REGNUM))]
1173   "TARGET_ARM"
1174   "rsbs\\t%Q0, %Q1, %2\;rsc\\t%R0, %R1, %2, asr #31"
1175   [(set_attr "conds" "clob")
1176    (set_attr "length" "8")]
1177 )
1178
1179 (define_insn "*subdi_zesidi_zesidi"
1180   [(set (match_operand:DI            0 "s_register_operand" "=r")
1181         (minus:DI (zero_extend:DI
1182                    (match_operand:SI 1 "s_register_operand"  "r"))
1183                   (zero_extend:DI
1184                    (match_operand:SI 2 "s_register_operand"  "r"))))
1185    (clobber (reg:CC CC_REGNUM))]
1186   "TARGET_32BIT"
1187   "subs\\t%Q0, %1, %2\;sbc\\t%R0, %1, %1"
1188   [(set_attr "conds" "clob")
1189    (set_attr "length" "8")]
1190 )
1191
1192 (define_expand "subsi3"
1193   [(set (match_operand:SI           0 "s_register_operand" "")
1194         (minus:SI (match_operand:SI 1 "reg_or_int_operand" "")
1195                   (match_operand:SI 2 "s_register_operand" "")))]
1196   "TARGET_EITHER"
1197   "
1198   if (GET_CODE (operands[1]) == CONST_INT)
1199     {
1200       if (TARGET_32BIT)
1201         {
1202           arm_split_constant (MINUS, SImode, NULL_RTX,
1203                               INTVAL (operands[1]), operands[0],
1204                               operands[2], optimize && can_create_pseudo_p ());
1205           DONE;
1206         }
1207       else /* TARGET_THUMB1 */
1208         operands[1] = force_reg (SImode, operands[1]);
1209     }
1210   "
1211 )
1212
1213 (define_insn "thumb1_subsi3_insn"
1214   [(set (match_operand:SI           0 "register_operand" "=l")
1215         (minus:SI (match_operand:SI 1 "register_operand" "l")
1216                   (match_operand:SI 2 "reg_or_int_operand" "lPd")))]
1217   "TARGET_THUMB1"
1218   "sub\\t%0, %1, %2"
1219   [(set_attr "length" "2")
1220    (set_attr "conds" "set")])
1221
1222 ; ??? Check Thumb-2 split length
1223 (define_insn_and_split "*arm_subsi3_insn"
1224   [(set (match_operand:SI           0 "s_register_operand" "=r,r,rk,r")
1225         (minus:SI (match_operand:SI 1 "reg_or_int_operand" "rI,r,k,?n")
1226                   (match_operand:SI 2 "reg_or_int_operand" "r,rI,r, r")))]
1227   "TARGET_32BIT"
1228   "@
1229    rsb%?\\t%0, %2, %1
1230    sub%?\\t%0, %1, %2
1231    sub%?\\t%0, %1, %2
1232    #"
1233   "&& (GET_CODE (operands[1]) == CONST_INT
1234        && !const_ok_for_arm (INTVAL (operands[1])))"
1235   [(clobber (const_int 0))]
1236   "
1237   arm_split_constant (MINUS, SImode, curr_insn,
1238                       INTVAL (operands[1]), operands[0], operands[2], 0);
1239   DONE;
1240   "
1241   [(set_attr "length" "4,4,4,16")
1242    (set_attr "predicable" "yes")]
1243 )
1244
1245 (define_peephole2
1246   [(match_scratch:SI 3 "r")
1247    (set (match_operand:SI 0 "arm_general_register_operand" "")
1248         (minus:SI (match_operand:SI 1 "const_int_operand" "")
1249                   (match_operand:SI 2 "arm_general_register_operand" "")))]
1250   "TARGET_32BIT
1251    && !const_ok_for_arm (INTVAL (operands[1]))
1252    && const_ok_for_arm (~INTVAL (operands[1]))"
1253   [(set (match_dup 3) (match_dup 1))
1254    (set (match_dup 0) (minus:SI (match_dup 3) (match_dup 2)))]
1255   ""
1256 )
1257
1258 (define_insn "*subsi3_compare0"
1259   [(set (reg:CC_NOOV CC_REGNUM)
1260         (compare:CC_NOOV
1261          (minus:SI (match_operand:SI 1 "arm_rhs_operand" "r,I")
1262                    (match_operand:SI 2 "arm_rhs_operand" "rI,r"))
1263          (const_int 0)))
1264    (set (match_operand:SI 0 "s_register_operand" "=r,r")
1265         (minus:SI (match_dup 1) (match_dup 2)))]
1266   "TARGET_32BIT"
1267   "@
1268    sub%.\\t%0, %1, %2
1269    rsb%.\\t%0, %2, %1"
1270   [(set_attr "conds" "set")]
1271 )
1272
1273 (define_insn "*subsi3_compare"
1274   [(set (reg:CC CC_REGNUM)
1275         (compare:CC (match_operand:SI 1 "arm_rhs_operand" "r,I")
1276                     (match_operand:SI 2 "arm_rhs_operand" "rI,r")))
1277    (set (match_operand:SI 0 "s_register_operand" "=r,r")
1278         (minus:SI (match_dup 1) (match_dup 2)))]
1279   "TARGET_32BIT"
1280   "@
1281    sub%.\\t%0, %1, %2
1282    rsb%.\\t%0, %2, %1"
1283   [(set_attr "conds" "set")]
1284 )
1285
1286 (define_expand "decscc"
1287   [(set (match_operand:SI            0 "s_register_operand" "=r,r")
1288         (minus:SI (match_operand:SI  1 "s_register_operand" "0,?r")
1289                   (match_operator:SI 2 "arm_comparison_operator"
1290                    [(match_operand   3 "cc_register" "") (const_int 0)])))]
1291   "TARGET_32BIT"
1292   ""
1293 )
1294
1295 (define_insn "*arm_decscc"
1296   [(set (match_operand:SI            0 "s_register_operand" "=r,r")
1297         (minus:SI (match_operand:SI  1 "s_register_operand" "0,?r")
1298                   (match_operator:SI 2 "arm_comparison_operator"
1299                    [(match_operand   3 "cc_register" "") (const_int 0)])))]
1300   "TARGET_ARM"
1301   "@
1302    sub%d2\\t%0, %1, #1
1303    mov%D2\\t%0, %1\;sub%d2\\t%0, %1, #1"
1304   [(set_attr "conds" "use")
1305    (set_attr "length" "*,8")]
1306 )
1307
1308 (define_expand "subsf3"
1309   [(set (match_operand:SF           0 "s_register_operand" "")
1310         (minus:SF (match_operand:SF 1 "arm_float_rhs_operand" "")
1311                   (match_operand:SF 2 "arm_float_rhs_operand" "")))]
1312   "TARGET_32BIT && TARGET_HARD_FLOAT"
1313   "
1314   if (TARGET_MAVERICK)
1315     {
1316       if (!cirrus_fp_register (operands[1], SFmode))
1317         operands[1] = force_reg (SFmode, operands[1]);
1318       if (!cirrus_fp_register (operands[2], SFmode))
1319         operands[2] = force_reg (SFmode, operands[2]);
1320     }
1321 ")
1322
1323 (define_expand "subdf3"
1324   [(set (match_operand:DF           0 "s_register_operand" "")
1325         (minus:DF (match_operand:DF 1 "arm_float_rhs_operand" "")
1326                   (match_operand:DF 2 "arm_float_rhs_operand" "")))]
1327   "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
1328   "
1329   if (TARGET_MAVERICK)
1330     {
1331        if (!cirrus_fp_register (operands[1], DFmode))
1332          operands[1] = force_reg (DFmode, operands[1]);
1333        if (!cirrus_fp_register (operands[2], DFmode))
1334          operands[2] = force_reg (DFmode, operands[2]);
1335     }
1336 ")
1337
1338 \f
1339 ;; Multiplication insns
1340
1341 (define_expand "mulsi3"
1342   [(set (match_operand:SI          0 "s_register_operand" "")
1343         (mult:SI (match_operand:SI 2 "s_register_operand" "")
1344                  (match_operand:SI 1 "s_register_operand" "")))]
1345   "TARGET_EITHER"
1346   ""
1347 )
1348
1349 ;; Use `&' and then `0' to prevent the operands 0 and 1 being the same
1350 (define_insn "*arm_mulsi3"
1351   [(set (match_operand:SI          0 "s_register_operand" "=&r,&r")
1352         (mult:SI (match_operand:SI 2 "s_register_operand" "r,r")
1353                  (match_operand:SI 1 "s_register_operand" "%0,r")))]
1354   "TARGET_32BIT && !arm_arch6"
1355   "mul%?\\t%0, %2, %1"
1356   [(set_attr "insn" "mul")
1357    (set_attr "predicable" "yes")]
1358 )
1359
1360 (define_insn "*arm_mulsi3_v6"
1361   [(set (match_operand:SI          0 "s_register_operand" "=r")
1362         (mult:SI (match_operand:SI 1 "s_register_operand" "r")
1363                  (match_operand:SI 2 "s_register_operand" "r")))]
1364   "TARGET_32BIT && arm_arch6"
1365   "mul%?\\t%0, %1, %2"
1366   [(set_attr "insn" "mul")
1367    (set_attr "predicable" "yes")]
1368 )
1369
1370 ; Unfortunately with the Thumb the '&'/'0' trick can fails when operands 
1371 ; 1 and 2; are the same, because reload will make operand 0 match 
1372 ; operand 1 without realizing that this conflicts with operand 2.  We fix 
1373 ; this by adding another alternative to match this case, and then `reload' 
1374 ; it ourselves.  This alternative must come first.
1375 (define_insn "*thumb_mulsi3"
1376   [(set (match_operand:SI          0 "register_operand" "=&l,&l,&l")
1377         (mult:SI (match_operand:SI 1 "register_operand" "%l,*h,0")
1378                  (match_operand:SI 2 "register_operand" "l,l,l")))]
1379   "TARGET_THUMB1 && !arm_arch6"
1380   "*
1381   if (which_alternative < 2)
1382     return \"mov\\t%0, %1\;mul\\t%0, %2\";
1383   else
1384     return \"mul\\t%0, %2\";
1385   "
1386   [(set_attr "length" "4,4,2")
1387    (set_attr "insn" "mul")]
1388 )
1389
1390 (define_insn "*thumb_mulsi3_v6"
1391   [(set (match_operand:SI          0 "register_operand" "=l,l,l")
1392         (mult:SI (match_operand:SI 1 "register_operand" "0,l,0")
1393                  (match_operand:SI 2 "register_operand" "l,0,0")))]
1394   "TARGET_THUMB1 && arm_arch6"
1395   "@
1396    mul\\t%0, %2
1397    mul\\t%0, %1
1398    mul\\t%0, %1"
1399   [(set_attr "length" "2")
1400    (set_attr "insn" "mul")]
1401 )
1402
1403 (define_insn "*mulsi3_compare0"
1404   [(set (reg:CC_NOOV CC_REGNUM)
1405         (compare:CC_NOOV (mult:SI
1406                           (match_operand:SI 2 "s_register_operand" "r,r")
1407                           (match_operand:SI 1 "s_register_operand" "%0,r"))
1408                          (const_int 0)))
1409    (set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1410         (mult:SI (match_dup 2) (match_dup 1)))]
1411   "TARGET_ARM && !arm_arch6"
1412   "mul%.\\t%0, %2, %1"
1413   [(set_attr "conds" "set")
1414    (set_attr "insn" "muls")]
1415 )
1416
1417 (define_insn "*mulsi3_compare0_v6"
1418   [(set (reg:CC_NOOV CC_REGNUM)
1419         (compare:CC_NOOV (mult:SI
1420                           (match_operand:SI 2 "s_register_operand" "r")
1421                           (match_operand:SI 1 "s_register_operand" "r"))
1422                          (const_int 0)))
1423    (set (match_operand:SI 0 "s_register_operand" "=r")
1424         (mult:SI (match_dup 2) (match_dup 1)))]
1425   "TARGET_ARM && arm_arch6 && optimize_size"
1426   "mul%.\\t%0, %2, %1"
1427   [(set_attr "conds" "set")
1428    (set_attr "insn" "muls")]
1429 )
1430
1431 (define_insn "*mulsi_compare0_scratch"
1432   [(set (reg:CC_NOOV CC_REGNUM)
1433         (compare:CC_NOOV (mult:SI
1434                           (match_operand:SI 2 "s_register_operand" "r,r")
1435                           (match_operand:SI 1 "s_register_operand" "%0,r"))
1436                          (const_int 0)))
1437    (clobber (match_scratch:SI 0 "=&r,&r"))]
1438   "TARGET_ARM && !arm_arch6"
1439   "mul%.\\t%0, %2, %1"
1440   [(set_attr "conds" "set")
1441    (set_attr "insn" "muls")]
1442 )
1443
1444 (define_insn "*mulsi_compare0_scratch_v6"
1445   [(set (reg:CC_NOOV CC_REGNUM)
1446         (compare:CC_NOOV (mult:SI
1447                           (match_operand:SI 2 "s_register_operand" "r")
1448                           (match_operand:SI 1 "s_register_operand" "r"))
1449                          (const_int 0)))
1450    (clobber (match_scratch:SI 0 "=r"))]
1451   "TARGET_ARM && arm_arch6 && optimize_size"
1452   "mul%.\\t%0, %2, %1"
1453   [(set_attr "conds" "set")
1454    (set_attr "insn" "muls")]
1455 )
1456
1457 ;; Unnamed templates to match MLA instruction.
1458
1459 (define_insn "*mulsi3addsi"
1460   [(set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r,&r")
1461         (plus:SI
1462           (mult:SI (match_operand:SI 2 "s_register_operand" "r,r,r,r")
1463                    (match_operand:SI 1 "s_register_operand" "%0,r,0,r"))
1464           (match_operand:SI 3 "s_register_operand" "r,r,0,0")))]
1465   "TARGET_32BIT && !arm_arch6"
1466   "mla%?\\t%0, %2, %1, %3"
1467   [(set_attr "insn" "mla")
1468    (set_attr "predicable" "yes")]
1469 )
1470
1471 (define_insn "*mulsi3addsi_v6"
1472   [(set (match_operand:SI 0 "s_register_operand" "=r")
1473         (plus:SI
1474           (mult:SI (match_operand:SI 2 "s_register_operand" "r")
1475                    (match_operand:SI 1 "s_register_operand" "r"))
1476           (match_operand:SI 3 "s_register_operand" "r")))]
1477   "TARGET_32BIT && arm_arch6"
1478   "mla%?\\t%0, %2, %1, %3"
1479   [(set_attr "insn" "mla")
1480    (set_attr "predicable" "yes")]
1481 )
1482
1483 (define_insn "*mulsi3addsi_compare0"
1484   [(set (reg:CC_NOOV CC_REGNUM)
1485         (compare:CC_NOOV
1486          (plus:SI (mult:SI
1487                    (match_operand:SI 2 "s_register_operand" "r,r,r,r")
1488                    (match_operand:SI 1 "s_register_operand" "%0,r,0,r"))
1489                   (match_operand:SI 3 "s_register_operand" "r,r,0,0"))
1490          (const_int 0)))
1491    (set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r,&r")
1492         (plus:SI (mult:SI (match_dup 2) (match_dup 1))
1493                  (match_dup 3)))]
1494   "TARGET_ARM && arm_arch6"
1495   "mla%.\\t%0, %2, %1, %3"
1496   [(set_attr "conds" "set")
1497    (set_attr "insn" "mlas")]
1498 )
1499
1500 (define_insn "*mulsi3addsi_compare0_v6"
1501   [(set (reg:CC_NOOV CC_REGNUM)
1502         (compare:CC_NOOV
1503          (plus:SI (mult:SI
1504                    (match_operand:SI 2 "s_register_operand" "r")
1505                    (match_operand:SI 1 "s_register_operand" "r"))
1506                   (match_operand:SI 3 "s_register_operand" "r"))
1507          (const_int 0)))
1508    (set (match_operand:SI 0 "s_register_operand" "=r")
1509         (plus:SI (mult:SI (match_dup 2) (match_dup 1))
1510                  (match_dup 3)))]
1511   "TARGET_ARM && arm_arch6 && optimize_size"
1512   "mla%.\\t%0, %2, %1, %3"
1513   [(set_attr "conds" "set")
1514    (set_attr "insn" "mlas")]
1515 )
1516
1517 (define_insn "*mulsi3addsi_compare0_scratch"
1518   [(set (reg:CC_NOOV CC_REGNUM)
1519         (compare:CC_NOOV
1520          (plus:SI (mult:SI
1521                    (match_operand:SI 2 "s_register_operand" "r,r,r,r")
1522                    (match_operand:SI 1 "s_register_operand" "%0,r,0,r"))
1523                   (match_operand:SI 3 "s_register_operand" "?r,r,0,0"))
1524          (const_int 0)))
1525    (clobber (match_scratch:SI 0 "=&r,&r,&r,&r"))]
1526   "TARGET_ARM && !arm_arch6"
1527   "mla%.\\t%0, %2, %1, %3"
1528   [(set_attr "conds" "set")
1529    (set_attr "insn" "mlas")]
1530 )
1531
1532 (define_insn "*mulsi3addsi_compare0_scratch_v6"
1533   [(set (reg:CC_NOOV CC_REGNUM)
1534         (compare:CC_NOOV
1535          (plus:SI (mult:SI
1536                    (match_operand:SI 2 "s_register_operand" "r")
1537                    (match_operand:SI 1 "s_register_operand" "r"))
1538                   (match_operand:SI 3 "s_register_operand" "r"))
1539          (const_int 0)))
1540    (clobber (match_scratch:SI 0 "=r"))]
1541   "TARGET_ARM && arm_arch6 && optimize_size"
1542   "mla%.\\t%0, %2, %1, %3"
1543   [(set_attr "conds" "set")
1544    (set_attr "insn" "mlas")]
1545 )
1546
1547 (define_insn "*mulsi3subsi"
1548   [(set (match_operand:SI 0 "s_register_operand" "=r")
1549         (minus:SI
1550           (match_operand:SI 3 "s_register_operand" "r")
1551           (mult:SI (match_operand:SI 2 "s_register_operand" "r")
1552                    (match_operand:SI 1 "s_register_operand" "r"))))]
1553   "TARGET_32BIT && arm_arch_thumb2"
1554   "mls%?\\t%0, %2, %1, %3"
1555   [(set_attr "insn" "mla")
1556    (set_attr "predicable" "yes")]
1557 )
1558
1559 (define_expand "maddsidi4"
1560   [(set (match_operand:DI 0 "s_register_operand" "")
1561         (plus:DI
1562          (mult:DI
1563           (sign_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1564           (sign_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1565          (match_operand:DI 3 "s_register_operand" "")))]
1566   "TARGET_32BIT && arm_arch3m"
1567   "")
1568
1569 (define_insn "*mulsidi3adddi"
1570   [(set (match_operand:DI 0 "s_register_operand" "=&r")
1571         (plus:DI
1572          (mult:DI
1573           (sign_extend:DI (match_operand:SI 2 "s_register_operand" "%r"))
1574           (sign_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1575          (match_operand:DI 1 "s_register_operand" "0")))]
1576   "TARGET_32BIT && arm_arch3m && !arm_arch6"
1577   "smlal%?\\t%Q0, %R0, %3, %2"
1578   [(set_attr "insn" "smlal")
1579    (set_attr "predicable" "yes")]
1580 )
1581
1582 (define_insn "*mulsidi3adddi_v6"
1583   [(set (match_operand:DI 0 "s_register_operand" "=r")
1584         (plus:DI
1585          (mult:DI
1586           (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r"))
1587           (sign_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1588          (match_operand:DI 1 "s_register_operand" "0")))]
1589   "TARGET_32BIT && arm_arch6"
1590   "smlal%?\\t%Q0, %R0, %3, %2"
1591   [(set_attr "insn" "smlal")
1592    (set_attr "predicable" "yes")]
1593 )
1594
1595 ;; 32x32->64 widening multiply.
1596 ;; As with mulsi3, the only difference between the v3-5 and v6+
1597 ;; versions of these patterns is the requirement that the output not
1598 ;; overlap the inputs, but that still means we have to have a named
1599 ;; expander and two different starred insns.
1600
1601 (define_expand "mulsidi3"
1602   [(set (match_operand:DI 0 "s_register_operand" "")
1603         (mult:DI
1604          (sign_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1605          (sign_extend:DI (match_operand:SI 2 "s_register_operand" ""))))]
1606   "TARGET_32BIT && arm_arch3m"
1607   ""
1608 )
1609
1610 (define_insn "*mulsidi3_nov6"
1611   [(set (match_operand:DI 0 "s_register_operand" "=&r")
1612         (mult:DI
1613          (sign_extend:DI (match_operand:SI 1 "s_register_operand" "%r"))
1614          (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1615   "TARGET_32BIT && arm_arch3m && !arm_arch6"
1616   "smull%?\\t%Q0, %R0, %1, %2"
1617   [(set_attr "insn" "smull")
1618    (set_attr "predicable" "yes")]
1619 )
1620
1621 (define_insn "*mulsidi3_v6"
1622   [(set (match_operand:DI 0 "s_register_operand" "=r")
1623         (mult:DI
1624          (sign_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1625          (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1626   "TARGET_32BIT && arm_arch6"
1627   "smull%?\\t%Q0, %R0, %1, %2"
1628   [(set_attr "insn" "smull")
1629    (set_attr "predicable" "yes")]
1630 )
1631
1632 (define_expand "umulsidi3"
1633   [(set (match_operand:DI 0 "s_register_operand" "")
1634         (mult:DI
1635          (zero_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1636          (zero_extend:DI (match_operand:SI 2 "s_register_operand" ""))))]
1637   "TARGET_32BIT && arm_arch3m"
1638   ""
1639 )
1640
1641 (define_insn "*umulsidi3_nov6"
1642   [(set (match_operand:DI 0 "s_register_operand" "=&r")
1643         (mult:DI
1644          (zero_extend:DI (match_operand:SI 1 "s_register_operand" "%r"))
1645          (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1646   "TARGET_32BIT && arm_arch3m && !arm_arch6"
1647   "umull%?\\t%Q0, %R0, %1, %2"
1648   [(set_attr "insn" "umull")
1649    (set_attr "predicable" "yes")]
1650 )
1651
1652 (define_insn "*umulsidi3_v6"
1653   [(set (match_operand:DI 0 "s_register_operand" "=r")
1654         (mult:DI
1655          (zero_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1656          (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1657   "TARGET_32BIT && arm_arch6"
1658   "umull%?\\t%Q0, %R0, %1, %2"
1659   [(set_attr "insn" "umull")
1660    (set_attr "predicable" "yes")]
1661 )
1662
1663 (define_expand "umaddsidi4"
1664   [(set (match_operand:DI 0 "s_register_operand" "")
1665         (plus:DI
1666          (mult:DI
1667           (zero_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1668           (zero_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1669          (match_operand:DI 3 "s_register_operand" "")))]
1670   "TARGET_32BIT && arm_arch3m"
1671   "")
1672
1673 (define_insn "*umulsidi3adddi"
1674   [(set (match_operand:DI 0 "s_register_operand" "=&r")
1675         (plus:DI
1676          (mult:DI
1677           (zero_extend:DI (match_operand:SI 2 "s_register_operand" "%r"))
1678           (zero_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1679          (match_operand:DI 1 "s_register_operand" "0")))]
1680   "TARGET_32BIT && arm_arch3m && !arm_arch6"
1681   "umlal%?\\t%Q0, %R0, %3, %2"
1682   [(set_attr "insn" "umlal")
1683    (set_attr "predicable" "yes")]
1684 )
1685
1686 (define_insn "*umulsidi3adddi_v6"
1687   [(set (match_operand:DI 0 "s_register_operand" "=r")
1688         (plus:DI
1689          (mult:DI
1690           (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r"))
1691           (zero_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1692          (match_operand:DI 1 "s_register_operand" "0")))]
1693   "TARGET_32BIT && arm_arch6"
1694   "umlal%?\\t%Q0, %R0, %3, %2"
1695   [(set_attr "insn" "umlal")
1696    (set_attr "predicable" "yes")]
1697 )
1698
1699 (define_expand "smulsi3_highpart"
1700   [(parallel
1701     [(set (match_operand:SI 0 "s_register_operand" "")
1702           (truncate:SI
1703            (lshiftrt:DI
1704             (mult:DI
1705              (sign_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1706              (sign_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1707             (const_int 32))))
1708      (clobber (match_scratch:SI 3 ""))])]
1709   "TARGET_32BIT && arm_arch3m"
1710   ""
1711 )
1712
1713 (define_insn "*smulsi3_highpart_nov6"
1714   [(set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1715         (truncate:SI
1716          (lshiftrt:DI
1717           (mult:DI
1718            (sign_extend:DI (match_operand:SI 1 "s_register_operand" "%0,r"))
1719            (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r,r")))
1720           (const_int 32))))
1721    (clobber (match_scratch:SI 3 "=&r,&r"))]
1722   "TARGET_32BIT && arm_arch3m && !arm_arch6"
1723   "smull%?\\t%3, %0, %2, %1"
1724   [(set_attr "insn" "smull")
1725    (set_attr "predicable" "yes")]
1726 )
1727
1728 (define_insn "*smulsi3_highpart_v6"
1729   [(set (match_operand:SI 0 "s_register_operand" "=r")
1730         (truncate:SI
1731          (lshiftrt:DI
1732           (mult:DI
1733            (sign_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1734            (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r")))
1735           (const_int 32))))
1736    (clobber (match_scratch:SI 3 "=r"))]
1737   "TARGET_32BIT && arm_arch6"
1738   "smull%?\\t%3, %0, %2, %1"
1739   [(set_attr "insn" "smull")
1740    (set_attr "predicable" "yes")]
1741 )
1742
1743 (define_expand "umulsi3_highpart"
1744   [(parallel
1745     [(set (match_operand:SI 0 "s_register_operand" "")
1746           (truncate:SI
1747            (lshiftrt:DI
1748             (mult:DI
1749              (zero_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1750               (zero_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1751             (const_int 32))))
1752      (clobber (match_scratch:SI 3 ""))])]
1753   "TARGET_32BIT && arm_arch3m"
1754   ""
1755 )
1756
1757 (define_insn "*umulsi3_highpart_nov6"
1758   [(set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1759         (truncate:SI
1760          (lshiftrt:DI
1761           (mult:DI
1762            (zero_extend:DI (match_operand:SI 1 "s_register_operand" "%0,r"))
1763            (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r,r")))
1764           (const_int 32))))
1765    (clobber (match_scratch:SI 3 "=&r,&r"))]
1766   "TARGET_32BIT && arm_arch3m && !arm_arch6"
1767   "umull%?\\t%3, %0, %2, %1"
1768   [(set_attr "insn" "umull")
1769    (set_attr "predicable" "yes")]
1770 )
1771
1772 (define_insn "*umulsi3_highpart_v6"
1773   [(set (match_operand:SI 0 "s_register_operand" "=r")
1774         (truncate:SI
1775          (lshiftrt:DI
1776           (mult:DI
1777            (zero_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1778            (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r")))
1779           (const_int 32))))
1780    (clobber (match_scratch:SI 3 "=r"))]
1781   "TARGET_32BIT && arm_arch6"
1782   "umull%?\\t%3, %0, %2, %1"
1783   [(set_attr "insn" "umull")
1784    (set_attr "predicable" "yes")]
1785 )
1786
1787 (define_insn "mulhisi3"
1788   [(set (match_operand:SI 0 "s_register_operand" "=r")
1789         (mult:SI (sign_extend:SI
1790                   (match_operand:HI 1 "s_register_operand" "%r"))
1791                  (sign_extend:SI
1792                   (match_operand:HI 2 "s_register_operand" "r"))))]
1793   "TARGET_DSP_MULTIPLY"
1794   "smulbb%?\\t%0, %1, %2"
1795   [(set_attr "insn" "smulxy")
1796    (set_attr "predicable" "yes")]
1797 )
1798
1799 (define_insn "*mulhisi3tb"
1800   [(set (match_operand:SI 0 "s_register_operand" "=r")
1801         (mult:SI (ashiftrt:SI
1802                   (match_operand:SI 1 "s_register_operand" "r")
1803                   (const_int 16))
1804                  (sign_extend:SI
1805                   (match_operand:HI 2 "s_register_operand" "r"))))]
1806   "TARGET_DSP_MULTIPLY"
1807   "smultb%?\\t%0, %1, %2"
1808   [(set_attr "insn" "smulxy")
1809    (set_attr "predicable" "yes")]
1810 )
1811
1812 (define_insn "*mulhisi3bt"
1813   [(set (match_operand:SI 0 "s_register_operand" "=r")
1814         (mult:SI (sign_extend:SI
1815                   (match_operand:HI 1 "s_register_operand" "r"))
1816                  (ashiftrt:SI
1817                   (match_operand:SI 2 "s_register_operand" "r")
1818                   (const_int 16))))]
1819   "TARGET_DSP_MULTIPLY"
1820   "smulbt%?\\t%0, %1, %2"
1821   [(set_attr "insn" "smulxy")
1822    (set_attr "predicable" "yes")]
1823 )
1824
1825 (define_insn "*mulhisi3tt"
1826   [(set (match_operand:SI 0 "s_register_operand" "=r")
1827         (mult:SI (ashiftrt:SI
1828                   (match_operand:SI 1 "s_register_operand" "r")
1829                   (const_int 16))
1830                  (ashiftrt:SI
1831                   (match_operand:SI 2 "s_register_operand" "r")
1832                   (const_int 16))))]
1833   "TARGET_DSP_MULTIPLY"
1834   "smultt%?\\t%0, %1, %2"
1835   [(set_attr "insn" "smulxy")
1836    (set_attr "predicable" "yes")]
1837 )
1838
1839 (define_insn "maddhisi4"
1840   [(set (match_operand:SI 0 "s_register_operand" "=r")
1841         (plus:SI (mult:SI (sign_extend:SI
1842                            (match_operand:HI 1 "s_register_operand" "r"))
1843                           (sign_extend:SI
1844                            (match_operand:HI 2 "s_register_operand" "r")))
1845                  (match_operand:SI 3 "s_register_operand" "r")))]
1846   "TARGET_DSP_MULTIPLY"
1847   "smlabb%?\\t%0, %1, %2, %3"
1848   [(set_attr "insn" "smlaxy")
1849    (set_attr "predicable" "yes")]
1850 )
1851
1852 ;; Note: there is no maddhisi4ibt because this one is canonical form
1853 (define_insn "*maddhisi4tb"
1854   [(set (match_operand:SI 0 "s_register_operand" "=r")
1855         (plus:SI (mult:SI (ashiftrt:SI
1856                            (match_operand:SI 1 "s_register_operand" "r")
1857                            (const_int 16))
1858                           (sign_extend:SI
1859                            (match_operand:HI 2 "s_register_operand" "r")))
1860                  (match_operand:SI 3 "s_register_operand" "r")))]
1861   "TARGET_DSP_MULTIPLY"
1862   "smlatb%?\\t%0, %1, %2, %3"
1863   [(set_attr "insn" "smlaxy")
1864    (set_attr "predicable" "yes")]
1865 )
1866
1867 (define_insn "*maddhisi4tt"
1868   [(set (match_operand:SI 0 "s_register_operand" "=r")
1869         (plus:SI (mult:SI (ashiftrt:SI
1870                            (match_operand:SI 1 "s_register_operand" "r")
1871                            (const_int 16))
1872                           (ashiftrt:SI
1873                            (match_operand:SI 2 "s_register_operand" "r")
1874                            (const_int 16)))
1875                  (match_operand:SI 3 "s_register_operand" "r")))]
1876   "TARGET_DSP_MULTIPLY"
1877   "smlatt%?\\t%0, %1, %2, %3"
1878   [(set_attr "insn" "smlaxy")
1879    (set_attr "predicable" "yes")]
1880 )
1881
1882 (define_insn "maddhidi4"
1883   [(set (match_operand:DI 0 "s_register_operand" "=r")
1884         (plus:DI
1885           (mult:DI (sign_extend:DI
1886                     (match_operand:HI 1 "s_register_operand" "r"))
1887                    (sign_extend:DI
1888                     (match_operand:HI 2 "s_register_operand" "r")))
1889           (match_operand:DI 3 "s_register_operand" "0")))]
1890   "TARGET_DSP_MULTIPLY"
1891   "smlalbb%?\\t%Q0, %R0, %1, %2"
1892   [(set_attr "insn" "smlalxy")
1893    (set_attr "predicable" "yes")])
1894
1895 ;; Note: there is no maddhidi4ibt because this one is canonical form
1896 (define_insn "*maddhidi4tb"
1897   [(set (match_operand:DI 0 "s_register_operand" "=r")
1898         (plus:DI
1899           (mult:DI (sign_extend:DI
1900                     (ashiftrt:SI
1901                      (match_operand:SI 1 "s_register_operand" "r")
1902                      (const_int 16)))
1903                    (sign_extend:DI
1904                     (match_operand:HI 2 "s_register_operand" "r")))
1905           (match_operand:DI 3 "s_register_operand" "0")))]
1906   "TARGET_DSP_MULTIPLY"
1907   "smlaltb%?\\t%Q0, %R0, %1, %2"
1908   [(set_attr "insn" "smlalxy")
1909    (set_attr "predicable" "yes")])
1910
1911 (define_insn "*maddhidi4tt"
1912   [(set (match_operand:DI 0 "s_register_operand" "=r")
1913         (plus:DI
1914           (mult:DI (sign_extend:DI
1915                     (ashiftrt:SI
1916                      (match_operand:SI 1 "s_register_operand" "r")
1917                      (const_int 16)))
1918                    (sign_extend:DI
1919                     (ashiftrt:SI
1920                      (match_operand:SI 2 "s_register_operand" "r")
1921                      (const_int 16))))
1922           (match_operand:DI 3 "s_register_operand" "0")))]
1923   "TARGET_DSP_MULTIPLY"
1924   "smlaltt%?\\t%Q0, %R0, %1, %2"
1925   [(set_attr "insn" "smlalxy")
1926    (set_attr "predicable" "yes")])
1927
1928 (define_expand "mulsf3"
1929   [(set (match_operand:SF          0 "s_register_operand" "")
1930         (mult:SF (match_operand:SF 1 "s_register_operand" "")
1931                  (match_operand:SF 2 "arm_float_rhs_operand" "")))]
1932   "TARGET_32BIT && TARGET_HARD_FLOAT"
1933   "
1934   if (TARGET_MAVERICK
1935       && !cirrus_fp_register (operands[2], SFmode))
1936     operands[2] = force_reg (SFmode, operands[2]);
1937 ")
1938
1939 (define_expand "muldf3"
1940   [(set (match_operand:DF          0 "s_register_operand" "")
1941         (mult:DF (match_operand:DF 1 "s_register_operand" "")
1942                  (match_operand:DF 2 "arm_float_rhs_operand" "")))]
1943   "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
1944   "
1945   if (TARGET_MAVERICK
1946       && !cirrus_fp_register (operands[2], DFmode))
1947     operands[2] = force_reg (DFmode, operands[2]);
1948 ")
1949 \f
1950 ;; Division insns
1951
1952 (define_expand "divsf3"
1953   [(set (match_operand:SF 0 "s_register_operand" "")
1954         (div:SF (match_operand:SF 1 "arm_float_rhs_operand" "")
1955                 (match_operand:SF 2 "arm_float_rhs_operand" "")))]
1956   "TARGET_32BIT && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP)"
1957   "")
1958
1959 (define_expand "divdf3"
1960   [(set (match_operand:DF 0 "s_register_operand" "")
1961         (div:DF (match_operand:DF 1 "arm_float_rhs_operand" "")
1962                 (match_operand:DF 2 "arm_float_rhs_operand" "")))]
1963   "TARGET_32BIT && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP_DOUBLE)"
1964   "")
1965 \f
1966 ;; Modulo insns
1967
1968 (define_expand "modsf3"
1969   [(set (match_operand:SF 0 "s_register_operand" "")
1970         (mod:SF (match_operand:SF 1 "s_register_operand" "")
1971                 (match_operand:SF 2 "arm_float_rhs_operand" "")))]
1972   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_FPA"
1973   "")
1974
1975 (define_expand "moddf3"
1976   [(set (match_operand:DF 0 "s_register_operand" "")
1977         (mod:DF (match_operand:DF 1 "s_register_operand" "")
1978                 (match_operand:DF 2 "arm_float_rhs_operand" "")))]
1979   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_FPA"
1980   "")
1981 \f
1982 ;; Boolean and,ior,xor insns
1983
1984 ;; Split up double word logical operations
1985
1986 ;; Split up simple DImode logical operations.  Simply perform the logical
1987 ;; operation on the upper and lower halves of the registers.
1988 (define_split
1989   [(set (match_operand:DI 0 "s_register_operand" "")
1990         (match_operator:DI 6 "logical_binary_operator"
1991           [(match_operand:DI 1 "s_register_operand" "")
1992            (match_operand:DI 2 "s_register_operand" "")]))]
1993   "TARGET_32BIT && reload_completed
1994    && ! (TARGET_NEON && IS_VFP_REGNUM (REGNO (operands[0])))
1995    && ! IS_IWMMXT_REGNUM (REGNO (operands[0]))"
1996   [(set (match_dup 0) (match_op_dup:SI 6 [(match_dup 1) (match_dup 2)]))
1997    (set (match_dup 3) (match_op_dup:SI 6 [(match_dup 4) (match_dup 5)]))]
1998   "
1999   {
2000     operands[3] = gen_highpart (SImode, operands[0]);
2001     operands[0] = gen_lowpart (SImode, operands[0]);
2002     operands[4] = gen_highpart (SImode, operands[1]);
2003     operands[1] = gen_lowpart (SImode, operands[1]);
2004     operands[5] = gen_highpart (SImode, operands[2]);
2005     operands[2] = gen_lowpart (SImode, operands[2]);
2006   }"
2007 )
2008
2009 (define_split
2010   [(set (match_operand:DI 0 "s_register_operand" "")
2011         (match_operator:DI 6 "logical_binary_operator"
2012           [(sign_extend:DI (match_operand:SI 2 "s_register_operand" ""))
2013            (match_operand:DI 1 "s_register_operand" "")]))]
2014   "TARGET_32BIT && reload_completed"
2015   [(set (match_dup 0) (match_op_dup:SI 6 [(match_dup 1) (match_dup 2)]))
2016    (set (match_dup 3) (match_op_dup:SI 6
2017                         [(ashiftrt:SI (match_dup 2) (const_int 31))
2018                          (match_dup 4)]))]
2019   "
2020   {
2021     operands[3] = gen_highpart (SImode, operands[0]);
2022     operands[0] = gen_lowpart (SImode, operands[0]);
2023     operands[4] = gen_highpart (SImode, operands[1]);
2024     operands[1] = gen_lowpart (SImode, operands[1]);
2025     operands[5] = gen_highpart (SImode, operands[2]);
2026     operands[2] = gen_lowpart (SImode, operands[2]);
2027   }"
2028 )
2029
2030 ;; The zero extend of operand 2 means we can just copy the high part of
2031 ;; operand1 into operand0.
2032 (define_split
2033   [(set (match_operand:DI 0 "s_register_operand" "")
2034         (ior:DI
2035           (zero_extend:DI (match_operand:SI 2 "s_register_operand" ""))
2036           (match_operand:DI 1 "s_register_operand" "")))]
2037   "TARGET_32BIT && operands[0] != operands[1] && reload_completed"
2038   [(set (match_dup 0) (ior:SI (match_dup 1) (match_dup 2)))
2039    (set (match_dup 3) (match_dup 4))]
2040   "
2041   {
2042     operands[4] = gen_highpart (SImode, operands[1]);
2043     operands[3] = gen_highpart (SImode, operands[0]);
2044     operands[0] = gen_lowpart (SImode, operands[0]);
2045     operands[1] = gen_lowpart (SImode, operands[1]);
2046   }"
2047 )
2048
2049 ;; The zero extend of operand 2 means we can just copy the high part of
2050 ;; operand1 into operand0.
2051 (define_split
2052   [(set (match_operand:DI 0 "s_register_operand" "")
2053         (xor:DI
2054           (zero_extend:DI (match_operand:SI 2 "s_register_operand" ""))
2055           (match_operand:DI 1 "s_register_operand" "")))]
2056   "TARGET_32BIT && operands[0] != operands[1] && reload_completed"
2057   [(set (match_dup 0) (xor:SI (match_dup 1) (match_dup 2)))
2058    (set (match_dup 3) (match_dup 4))]
2059   "
2060   {
2061     operands[4] = gen_highpart (SImode, operands[1]);
2062     operands[3] = gen_highpart (SImode, operands[0]);
2063     operands[0] = gen_lowpart (SImode, operands[0]);
2064     operands[1] = gen_lowpart (SImode, operands[1]);
2065   }"
2066 )
2067
2068 (define_expand "anddi3"
2069   [(set (match_operand:DI         0 "s_register_operand" "")
2070         (and:DI (match_operand:DI 1 "s_register_operand" "")
2071                 (match_operand:DI 2 "neon_inv_logic_op2" "")))]
2072   "TARGET_32BIT"
2073   ""
2074 )
2075
2076 (define_insn "*anddi3_insn"
2077   [(set (match_operand:DI         0 "s_register_operand" "=&r,&r")
2078         (and:DI (match_operand:DI 1 "s_register_operand"  "%0,r")
2079                 (match_operand:DI 2 "s_register_operand"   "r,r")))]
2080   "TARGET_32BIT && !TARGET_IWMMXT && !TARGET_NEON"
2081   "#"
2082   [(set_attr "length" "8")]
2083 )
2084
2085 (define_insn_and_split "*anddi_zesidi_di"
2086   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2087         (and:DI (zero_extend:DI
2088                  (match_operand:SI 2 "s_register_operand" "r,r"))
2089                 (match_operand:DI 1 "s_register_operand" "0,r")))]
2090   "TARGET_32BIT"
2091   "#"
2092   "TARGET_32BIT && reload_completed"
2093   ; The zero extend of operand 2 clears the high word of the output
2094   ; operand.
2095   [(set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))
2096    (set (match_dup 3) (const_int 0))]
2097   "
2098   {
2099     operands[3] = gen_highpart (SImode, operands[0]);
2100     operands[0] = gen_lowpart (SImode, operands[0]);
2101     operands[1] = gen_lowpart (SImode, operands[1]);
2102   }"
2103   [(set_attr "length" "8")]
2104 )
2105
2106 (define_insn "*anddi_sesdi_di"
2107   [(set (match_operand:DI          0 "s_register_operand" "=&r,&r")
2108         (and:DI (sign_extend:DI
2109                  (match_operand:SI 2 "s_register_operand" "r,r"))
2110                 (match_operand:DI  1 "s_register_operand" "0,r")))]
2111   "TARGET_32BIT"
2112   "#"
2113   [(set_attr "length" "8")]
2114 )
2115
2116 (define_expand "andsi3"
2117   [(set (match_operand:SI         0 "s_register_operand" "")
2118         (and:SI (match_operand:SI 1 "s_register_operand" "")
2119                 (match_operand:SI 2 "reg_or_int_operand" "")))]
2120   "TARGET_EITHER"
2121   "
2122   if (TARGET_32BIT)
2123     {
2124       if (GET_CODE (operands[2]) == CONST_INT)
2125         {
2126           if (INTVAL (operands[2]) == 255 && arm_arch6)
2127             {
2128               operands[1] = convert_to_mode (QImode, operands[1], 1);
2129               emit_insn (gen_thumb2_zero_extendqisi2_v6 (operands[0],
2130                                                          operands[1]));
2131             }
2132           else
2133             arm_split_constant (AND, SImode, NULL_RTX,
2134                                 INTVAL (operands[2]), operands[0],
2135                                 operands[1],
2136                                 optimize && can_create_pseudo_p ());
2137
2138           DONE;
2139         }
2140     }
2141   else /* TARGET_THUMB1 */
2142     {
2143       if (GET_CODE (operands[2]) != CONST_INT)
2144         {
2145           rtx tmp = force_reg (SImode, operands[2]);
2146           if (rtx_equal_p (operands[0], operands[1]))
2147             operands[2] = tmp;
2148           else
2149             {
2150               operands[2] = operands[1];
2151               operands[1] = tmp;
2152             }
2153         }
2154       else
2155         {
2156           int i;
2157           
2158           if (((unsigned HOST_WIDE_INT) ~INTVAL (operands[2])) < 256)
2159             {
2160               operands[2] = force_reg (SImode,
2161                                        GEN_INT (~INTVAL (operands[2])));
2162               
2163               emit_insn (gen_thumb1_bicsi3 (operands[0], operands[2], operands[1]));
2164               
2165               DONE;
2166             }
2167
2168           for (i = 9; i <= 31; i++)
2169             {
2170               if ((((HOST_WIDE_INT) 1) << i) - 1 == INTVAL (operands[2]))
2171                 {
2172                   emit_insn (gen_extzv (operands[0], operands[1], GEN_INT (i),
2173                                         const0_rtx));
2174                   DONE;
2175                 }
2176               else if ((((HOST_WIDE_INT) 1) << i) - 1
2177                        == ~INTVAL (operands[2]))
2178                 {
2179                   rtx shift = GEN_INT (i);
2180                   rtx reg = gen_reg_rtx (SImode);
2181                 
2182                   emit_insn (gen_lshrsi3 (reg, operands[1], shift));
2183                   emit_insn (gen_ashlsi3 (operands[0], reg, shift));
2184                   
2185                   DONE;
2186                 }
2187             }
2188
2189           operands[2] = force_reg (SImode, operands[2]);
2190         }
2191     }
2192   "
2193 )
2194
2195 ; ??? Check split length for Thumb-2
2196 (define_insn_and_split "*arm_andsi3_insn"
2197   [(set (match_operand:SI         0 "s_register_operand" "=r,r,r")
2198         (and:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
2199                 (match_operand:SI 2 "reg_or_int_operand" "rI,K,?n")))]
2200   "TARGET_32BIT"
2201   "@
2202    and%?\\t%0, %1, %2
2203    bic%?\\t%0, %1, #%B2
2204    #"
2205   "TARGET_32BIT
2206    && GET_CODE (operands[2]) == CONST_INT
2207    && !(const_ok_for_arm (INTVAL (operands[2]))
2208         || const_ok_for_arm (~INTVAL (operands[2])))"
2209   [(clobber (const_int 0))]
2210   "
2211   arm_split_constant  (AND, SImode, curr_insn, 
2212                        INTVAL (operands[2]), operands[0], operands[1], 0);
2213   DONE;
2214   "
2215   [(set_attr "length" "4,4,16")
2216    (set_attr "predicable" "yes")]
2217 )
2218
2219 (define_insn "*thumb1_andsi3_insn"
2220   [(set (match_operand:SI         0 "register_operand" "=l")
2221         (and:SI (match_operand:SI 1 "register_operand" "%0")
2222                 (match_operand:SI 2 "register_operand" "l")))]
2223   "TARGET_THUMB1"
2224   "and\\t%0, %2"
2225   [(set_attr "length" "2")
2226    (set_attr "conds" "set")])
2227
2228 (define_insn "*andsi3_compare0"
2229   [(set (reg:CC_NOOV CC_REGNUM)
2230         (compare:CC_NOOV
2231          (and:SI (match_operand:SI 1 "s_register_operand" "r,r")
2232                  (match_operand:SI 2 "arm_not_operand" "rI,K"))
2233          (const_int 0)))
2234    (set (match_operand:SI          0 "s_register_operand" "=r,r")
2235         (and:SI (match_dup 1) (match_dup 2)))]
2236   "TARGET_32BIT"
2237   "@
2238    and%.\\t%0, %1, %2
2239    bic%.\\t%0, %1, #%B2"
2240   [(set_attr "conds" "set")]
2241 )
2242
2243 (define_insn "*andsi3_compare0_scratch"
2244   [(set (reg:CC_NOOV CC_REGNUM)
2245         (compare:CC_NOOV
2246          (and:SI (match_operand:SI 0 "s_register_operand" "r,r")
2247                  (match_operand:SI 1 "arm_not_operand" "rI,K"))
2248          (const_int 0)))
2249    (clobber (match_scratch:SI 2 "=X,r"))]
2250   "TARGET_32BIT"
2251   "@
2252    tst%?\\t%0, %1
2253    bic%.\\t%2, %0, #%B1"
2254   [(set_attr "conds" "set")]
2255 )
2256
2257 (define_insn "*zeroextractsi_compare0_scratch"
2258   [(set (reg:CC_NOOV CC_REGNUM)
2259         (compare:CC_NOOV (zero_extract:SI
2260                           (match_operand:SI 0 "s_register_operand" "r")
2261                           (match_operand 1 "const_int_operand" "n")
2262                           (match_operand 2 "const_int_operand" "n"))
2263                          (const_int 0)))]
2264   "TARGET_32BIT
2265   && (INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) < 32
2266       && INTVAL (operands[1]) > 0 
2267       && INTVAL (operands[1]) + (INTVAL (operands[2]) & 1) <= 8
2268       && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32)"
2269   "*
2270   operands[1] = GEN_INT (((1 << INTVAL (operands[1])) - 1)
2271                          << INTVAL (operands[2]));
2272   output_asm_insn (\"tst%?\\t%0, %1\", operands);
2273   return \"\";
2274   "
2275   [(set_attr "conds" "set")]
2276 )
2277
2278 (define_insn_and_split "*ne_zeroextractsi"
2279   [(set (match_operand:SI 0 "s_register_operand" "=r")
2280         (ne:SI (zero_extract:SI
2281                 (match_operand:SI 1 "s_register_operand" "r")
2282                 (match_operand:SI 2 "const_int_operand" "n")
2283                 (match_operand:SI 3 "const_int_operand" "n"))
2284                (const_int 0)))
2285    (clobber (reg:CC CC_REGNUM))]
2286   "TARGET_32BIT
2287    && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2288        && INTVAL (operands[2]) > 0 
2289        && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2290        && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)"
2291   "#"
2292   "TARGET_32BIT
2293    && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2294        && INTVAL (operands[2]) > 0 
2295        && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2296        && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)"
2297   [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2298                    (compare:CC_NOOV (and:SI (match_dup 1) (match_dup 2))
2299                                     (const_int 0)))
2300               (set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))])
2301    (set (match_dup 0)
2302         (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2303                          (match_dup 0) (const_int 1)))]
2304   "
2305   operands[2] = GEN_INT (((1 << INTVAL (operands[2])) - 1)
2306                          << INTVAL (operands[3])); 
2307   "
2308   [(set_attr "conds" "clob")
2309    (set (attr "length")
2310         (if_then_else (eq_attr "is_thumb" "yes")
2311                       (const_int 12)
2312                       (const_int 8)))]
2313 )
2314
2315 (define_insn_and_split "*ne_zeroextractsi_shifted"
2316   [(set (match_operand:SI 0 "s_register_operand" "=r")
2317         (ne:SI (zero_extract:SI
2318                 (match_operand:SI 1 "s_register_operand" "r")
2319                 (match_operand:SI 2 "const_int_operand" "n")
2320                 (const_int 0))
2321                (const_int 0)))
2322    (clobber (reg:CC CC_REGNUM))]
2323   "TARGET_ARM"
2324   "#"
2325   "TARGET_ARM"
2326   [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2327                    (compare:CC_NOOV (ashift:SI (match_dup 1) (match_dup 2))
2328                                     (const_int 0)))
2329               (set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))])
2330    (set (match_dup 0)
2331         (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2332                          (match_dup 0) (const_int 1)))]
2333   "
2334   operands[2] = GEN_INT (32 - INTVAL (operands[2]));
2335   "
2336   [(set_attr "conds" "clob")
2337    (set_attr "length" "8")]
2338 )
2339
2340 (define_insn_and_split "*ite_ne_zeroextractsi"
2341   [(set (match_operand:SI 0 "s_register_operand" "=r")
2342         (if_then_else:SI (ne (zero_extract:SI
2343                               (match_operand:SI 1 "s_register_operand" "r")
2344                               (match_operand:SI 2 "const_int_operand" "n")
2345                               (match_operand:SI 3 "const_int_operand" "n"))
2346                              (const_int 0))
2347                          (match_operand:SI 4 "arm_not_operand" "rIK")
2348                          (const_int 0)))
2349    (clobber (reg:CC CC_REGNUM))]
2350   "TARGET_ARM
2351    && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2352        && INTVAL (operands[2]) > 0 
2353        && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2354        && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)
2355    && !reg_overlap_mentioned_p (operands[0], operands[4])"
2356   "#"
2357   "TARGET_ARM
2358    && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2359        && INTVAL (operands[2]) > 0 
2360        && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2361        && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)
2362    && !reg_overlap_mentioned_p (operands[0], operands[4])"
2363   [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2364                    (compare:CC_NOOV (and:SI (match_dup 1) (match_dup 2))
2365                                     (const_int 0)))
2366               (set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))])
2367    (set (match_dup 0)
2368         (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2369                          (match_dup 0) (match_dup 4)))]
2370   "
2371   operands[2] = GEN_INT (((1 << INTVAL (operands[2])) - 1)
2372                          << INTVAL (operands[3])); 
2373   "
2374   [(set_attr "conds" "clob")
2375    (set_attr "length" "8")]
2376 )
2377
2378 (define_insn_and_split "*ite_ne_zeroextractsi_shifted"
2379   [(set (match_operand:SI 0 "s_register_operand" "=r")
2380         (if_then_else:SI (ne (zero_extract:SI
2381                               (match_operand:SI 1 "s_register_operand" "r")
2382                               (match_operand:SI 2 "const_int_operand" "n")
2383                               (const_int 0))
2384                              (const_int 0))
2385                          (match_operand:SI 3 "arm_not_operand" "rIK")
2386                          (const_int 0)))
2387    (clobber (reg:CC CC_REGNUM))]
2388   "TARGET_ARM && !reg_overlap_mentioned_p (operands[0], operands[3])"
2389   "#"
2390   "TARGET_ARM && !reg_overlap_mentioned_p (operands[0], operands[3])"
2391   [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2392                    (compare:CC_NOOV (ashift:SI (match_dup 1) (match_dup 2))
2393                                     (const_int 0)))
2394               (set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))])
2395    (set (match_dup 0)
2396         (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2397                          (match_dup 0) (match_dup 3)))]
2398   "
2399   operands[2] = GEN_INT (32 - INTVAL (operands[2]));
2400   "
2401   [(set_attr "conds" "clob")
2402    (set_attr "length" "8")]
2403 )
2404
2405 (define_split
2406   [(set (match_operand:SI 0 "s_register_operand" "")
2407         (zero_extract:SI (match_operand:SI 1 "s_register_operand" "")
2408                          (match_operand:SI 2 "const_int_operand" "")
2409                          (match_operand:SI 3 "const_int_operand" "")))
2410    (clobber (match_operand:SI 4 "s_register_operand" ""))]
2411   "TARGET_THUMB1"
2412   [(set (match_dup 4) (ashift:SI (match_dup 1) (match_dup 2)))
2413    (set (match_dup 0) (lshiftrt:SI (match_dup 4) (match_dup 3)))]
2414   "{
2415      HOST_WIDE_INT temp = INTVAL (operands[2]);
2416
2417      operands[2] = GEN_INT (32 - temp - INTVAL (operands[3]));
2418      operands[3] = GEN_INT (32 - temp);
2419    }"
2420 )
2421
2422 ;; ??? Use Thumb-2 has bitfield insert/extract instructions.
2423 (define_split
2424   [(set (match_operand:SI 0 "s_register_operand" "")
2425         (match_operator:SI 1 "shiftable_operator"
2426          [(zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
2427                            (match_operand:SI 3 "const_int_operand" "")
2428                            (match_operand:SI 4 "const_int_operand" ""))
2429           (match_operand:SI 5 "s_register_operand" "")]))
2430    (clobber (match_operand:SI 6 "s_register_operand" ""))]
2431   "TARGET_ARM"
2432   [(set (match_dup 6) (ashift:SI (match_dup 2) (match_dup 3)))
2433    (set (match_dup 0)
2434         (match_op_dup 1
2435          [(lshiftrt:SI (match_dup 6) (match_dup 4))
2436           (match_dup 5)]))]
2437   "{
2438      HOST_WIDE_INT temp = INTVAL (operands[3]);
2439
2440      operands[3] = GEN_INT (32 - temp - INTVAL (operands[4]));
2441      operands[4] = GEN_INT (32 - temp);
2442    }"
2443 )
2444   
2445 (define_split
2446   [(set (match_operand:SI 0 "s_register_operand" "")
2447         (sign_extract:SI (match_operand:SI 1 "s_register_operand" "")
2448                          (match_operand:SI 2 "const_int_operand" "")
2449                          (match_operand:SI 3 "const_int_operand" "")))]
2450   "TARGET_THUMB1"
2451   [(set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))
2452    (set (match_dup 0) (ashiftrt:SI (match_dup 0) (match_dup 3)))]
2453   "{
2454      HOST_WIDE_INT temp = INTVAL (operands[2]);
2455
2456      operands[2] = GEN_INT (32 - temp - INTVAL (operands[3]));
2457      operands[3] = GEN_INT (32 - temp);
2458    }"
2459 )
2460
2461 (define_split
2462   [(set (match_operand:SI 0 "s_register_operand" "")
2463         (match_operator:SI 1 "shiftable_operator"
2464          [(sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
2465                            (match_operand:SI 3 "const_int_operand" "")
2466                            (match_operand:SI 4 "const_int_operand" ""))
2467           (match_operand:SI 5 "s_register_operand" "")]))
2468    (clobber (match_operand:SI 6 "s_register_operand" ""))]
2469   "TARGET_ARM"
2470   [(set (match_dup 6) (ashift:SI (match_dup 2) (match_dup 3)))
2471    (set (match_dup 0)
2472         (match_op_dup 1
2473          [(ashiftrt:SI (match_dup 6) (match_dup 4))
2474           (match_dup 5)]))]
2475   "{
2476      HOST_WIDE_INT temp = INTVAL (operands[3]);
2477
2478      operands[3] = GEN_INT (32 - temp - INTVAL (operands[4]));
2479      operands[4] = GEN_INT (32 - temp);
2480    }"
2481 )
2482   
2483 ;;; ??? This pattern is bogus.  If operand3 has bits outside the range
2484 ;;; represented by the bitfield, then this will produce incorrect results.
2485 ;;; Somewhere, the value needs to be truncated.  On targets like the m68k,
2486 ;;; which have a real bit-field insert instruction, the truncation happens
2487 ;;; in the bit-field insert instruction itself.  Since arm does not have a
2488 ;;; bit-field insert instruction, we would have to emit code here to truncate
2489 ;;; the value before we insert.  This loses some of the advantage of having
2490 ;;; this insv pattern, so this pattern needs to be reevalutated.
2491
2492 (define_expand "insv"
2493   [(set (zero_extract (match_operand 0 "nonimmediate_operand" "")
2494                       (match_operand 1 "general_operand" "")
2495                       (match_operand 2 "general_operand" ""))
2496         (match_operand 3 "reg_or_int_operand" ""))]
2497   "TARGET_ARM || arm_arch_thumb2"
2498   "
2499   {
2500     int start_bit = INTVAL (operands[2]);
2501     int width = INTVAL (operands[1]);
2502     HOST_WIDE_INT mask = (((HOST_WIDE_INT)1) << width) - 1;
2503     rtx target, subtarget;
2504
2505     if (arm_arch_thumb2)
2506       {
2507         if (unaligned_access && MEM_P (operands[0])
2508             && s_register_operand (operands[3], GET_MODE (operands[3]))
2509             && (width == 16 || width == 32) && (start_bit % BITS_PER_UNIT) == 0)
2510           {
2511             rtx base_addr;
2512
2513             if (BYTES_BIG_ENDIAN)
2514               start_bit = GET_MODE_BITSIZE (GET_MODE (operands[3])) - width
2515                           - start_bit;
2516
2517             if (width == 32)
2518               {
2519                 base_addr = adjust_address (operands[0], SImode,
2520                                             start_bit / BITS_PER_UNIT);
2521                 emit_insn (gen_unaligned_storesi (base_addr, operands[3]));
2522               }
2523             else
2524               {
2525                 rtx tmp = gen_reg_rtx (HImode);
2526
2527                 base_addr = adjust_address (operands[0], HImode,
2528                                             start_bit / BITS_PER_UNIT);
2529                 emit_move_insn (tmp, gen_lowpart (HImode, operands[3]));
2530                 emit_insn (gen_unaligned_storehi (base_addr, tmp));
2531               }
2532             DONE;
2533           }
2534         else if (s_register_operand (operands[0], GET_MODE (operands[0])))
2535           {
2536             bool use_bfi = TRUE;
2537
2538             if (GET_CODE (operands[3]) == CONST_INT)
2539               {
2540                 HOST_WIDE_INT val = INTVAL (operands[3]) & mask;
2541
2542                 if (val == 0)
2543                   {
2544                     emit_insn (gen_insv_zero (operands[0], operands[1],
2545                                               operands[2]));
2546                     DONE;
2547                   }
2548
2549                 /* See if the set can be done with a single orr instruction.  */
2550                 if (val == mask && const_ok_for_arm (val << start_bit))
2551                   use_bfi = FALSE;
2552               }
2553
2554             if (use_bfi)
2555               {
2556                 if (GET_CODE (operands[3]) != REG)
2557                   operands[3] = force_reg (SImode, operands[3]);
2558
2559                 emit_insn (gen_insv_t2 (operands[0], operands[1], operands[2],
2560                                         operands[3]));
2561                 DONE;
2562               }
2563           }
2564         else
2565           FAIL;
2566       }
2567
2568     if (!s_register_operand (operands[0], GET_MODE (operands[0])))
2569       FAIL;
2570
2571     target = copy_rtx (operands[0]);
2572     /* Avoid using a subreg as a subtarget, and avoid writing a paradoxical 
2573        subreg as the final target.  */
2574     if (GET_CODE (target) == SUBREG)
2575       {
2576         subtarget = gen_reg_rtx (SImode);
2577         if (GET_MODE_SIZE (GET_MODE (SUBREG_REG (target)))
2578             < GET_MODE_SIZE (SImode))
2579           target = SUBREG_REG (target);
2580       }
2581     else
2582       subtarget = target;    
2583
2584     if (GET_CODE (operands[3]) == CONST_INT)
2585       {
2586         /* Since we are inserting a known constant, we may be able to
2587            reduce the number of bits that we have to clear so that
2588            the mask becomes simple.  */
2589         /* ??? This code does not check to see if the new mask is actually
2590            simpler.  It may not be.  */
2591         rtx op1 = gen_reg_rtx (SImode);
2592         /* ??? Truncate operand3 to fit in the bitfield.  See comment before
2593            start of this pattern.  */
2594         HOST_WIDE_INT op3_value = mask & INTVAL (operands[3]);
2595         HOST_WIDE_INT mask2 = ((mask & ~op3_value) << start_bit);
2596
2597         emit_insn (gen_andsi3 (op1, operands[0],
2598                                gen_int_mode (~mask2, SImode)));
2599         emit_insn (gen_iorsi3 (subtarget, op1,
2600                                gen_int_mode (op3_value << start_bit, SImode)));
2601       }
2602     else if (start_bit == 0
2603              && !(const_ok_for_arm (mask)
2604                   || const_ok_for_arm (~mask)))
2605       {
2606         /* A Trick, since we are setting the bottom bits in the word,
2607            we can shift operand[3] up, operand[0] down, OR them together
2608            and rotate the result back again.  This takes 3 insns, and
2609            the third might be mergeable into another op.  */
2610         /* The shift up copes with the possibility that operand[3] is
2611            wider than the bitfield.  */
2612         rtx op0 = gen_reg_rtx (SImode);
2613         rtx op1 = gen_reg_rtx (SImode);
2614
2615         emit_insn (gen_ashlsi3 (op0, operands[3], GEN_INT (32 - width)));
2616         emit_insn (gen_lshrsi3 (op1, operands[0], operands[1]));
2617         emit_insn (gen_iorsi3  (op1, op1, op0));
2618         emit_insn (gen_rotlsi3 (subtarget, op1, operands[1]));
2619       }
2620     else if ((width + start_bit == 32)
2621              && !(const_ok_for_arm (mask)
2622                   || const_ok_for_arm (~mask)))
2623       {
2624         /* Similar trick, but slightly less efficient.  */
2625
2626         rtx op0 = gen_reg_rtx (SImode);
2627         rtx op1 = gen_reg_rtx (SImode);
2628
2629         emit_insn (gen_ashlsi3 (op0, operands[3], GEN_INT (32 - width)));
2630         emit_insn (gen_ashlsi3 (op1, operands[0], operands[1]));
2631         emit_insn (gen_lshrsi3 (op1, op1, operands[1]));
2632         emit_insn (gen_iorsi3 (subtarget, op1, op0));
2633       }
2634     else
2635       {
2636         rtx op0 = gen_int_mode (mask, SImode);
2637         rtx op1 = gen_reg_rtx (SImode);
2638         rtx op2 = gen_reg_rtx (SImode);
2639
2640         if (!(const_ok_for_arm (mask) || const_ok_for_arm (~mask)))
2641           {
2642             rtx tmp = gen_reg_rtx (SImode);
2643
2644             emit_insn (gen_movsi (tmp, op0));
2645             op0 = tmp;
2646           }
2647
2648         /* Mask out any bits in operand[3] that are not needed.  */
2649            emit_insn (gen_andsi3 (op1, operands[3], op0));
2650
2651         if (GET_CODE (op0) == CONST_INT
2652             && (const_ok_for_arm (mask << start_bit)
2653                 || const_ok_for_arm (~(mask << start_bit))))
2654           {
2655             op0 = gen_int_mode (~(mask << start_bit), SImode);
2656             emit_insn (gen_andsi3 (op2, operands[0], op0));
2657           }
2658         else
2659           {
2660             if (GET_CODE (op0) == CONST_INT)
2661               {
2662                 rtx tmp = gen_reg_rtx (SImode);
2663
2664                 emit_insn (gen_movsi (tmp, op0));
2665                 op0 = tmp;
2666               }
2667
2668             if (start_bit != 0)
2669               emit_insn (gen_ashlsi3 (op0, op0, operands[2]));
2670             
2671             emit_insn (gen_andsi_notsi_si (op2, operands[0], op0));
2672           }
2673
2674         if (start_bit != 0)
2675           emit_insn (gen_ashlsi3 (op1, op1, operands[2]));
2676
2677         emit_insn (gen_iorsi3 (subtarget, op1, op2));
2678       }
2679
2680     if (subtarget != target)
2681       {
2682         /* If TARGET is still a SUBREG, then it must be wider than a word,
2683            so we must be careful only to set the subword we were asked to.  */
2684         if (GET_CODE (target) == SUBREG)
2685           emit_move_insn (target, subtarget);
2686         else
2687           emit_move_insn (target, gen_lowpart (GET_MODE (target), subtarget));
2688       }
2689
2690     DONE;
2691   }"
2692 )
2693
2694 (define_insn "insv_zero"
2695   [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r")
2696                          (match_operand:SI 1 "const_int_operand" "M")
2697                          (match_operand:SI 2 "const_int_operand" "M"))
2698         (const_int 0))]
2699   "arm_arch_thumb2"
2700   "bfc%?\t%0, %2, %1"
2701   [(set_attr "length" "4")
2702    (set_attr "predicable" "yes")]
2703 )
2704
2705 (define_insn "insv_t2"
2706   [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r")
2707                          (match_operand:SI 1 "const_int_operand" "M")
2708                          (match_operand:SI 2 "const_int_operand" "M"))
2709         (match_operand:SI 3 "s_register_operand" "r"))]
2710   "arm_arch_thumb2"
2711   "bfi%?\t%0, %3, %2, %1"
2712   [(set_attr "length" "4")
2713    (set_attr "predicable" "yes")]
2714 )
2715
2716 ; constants for op 2 will never be given to these patterns.
2717 (define_insn_and_split "*anddi_notdi_di"
2718   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2719         (and:DI (not:DI (match_operand:DI 1 "s_register_operand" "0,r"))
2720                 (match_operand:DI 2 "s_register_operand" "r,0")))]
2721   "TARGET_32BIT"
2722   "#"
2723   "TARGET_32BIT && reload_completed
2724    && ! (TARGET_NEON && IS_VFP_REGNUM (REGNO (operands[0])))
2725    && ! IS_IWMMXT_REGNUM (REGNO (operands[0]))"
2726   [(set (match_dup 0) (and:SI (not:SI (match_dup 1)) (match_dup 2)))
2727    (set (match_dup 3) (and:SI (not:SI (match_dup 4)) (match_dup 5)))]
2728   "
2729   {
2730     operands[3] = gen_highpart (SImode, operands[0]);
2731     operands[0] = gen_lowpart (SImode, operands[0]);
2732     operands[4] = gen_highpart (SImode, operands[1]);
2733     operands[1] = gen_lowpart (SImode, operands[1]);
2734     operands[5] = gen_highpart (SImode, operands[2]);
2735     operands[2] = gen_lowpart (SImode, operands[2]);
2736   }"
2737   [(set_attr "length" "8")
2738    (set_attr "predicable" "yes")]
2739 )
2740   
2741 (define_insn_and_split "*anddi_notzesidi_di"
2742   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2743         (and:DI (not:DI (zero_extend:DI
2744                          (match_operand:SI 2 "s_register_operand" "r,r")))
2745                 (match_operand:DI 1 "s_register_operand" "0,?r")))]
2746   "TARGET_32BIT"
2747   "@
2748    bic%?\\t%Q0, %Q1, %2
2749    #"
2750   ; (not (zero_extend ...)) allows us to just copy the high word from
2751   ; operand1 to operand0.
2752   "TARGET_32BIT
2753    && reload_completed
2754    && operands[0] != operands[1]"
2755   [(set (match_dup 0) (and:SI (not:SI (match_dup 2)) (match_dup 1)))
2756    (set (match_dup 3) (match_dup 4))]
2757   "
2758   {
2759     operands[3] = gen_highpart (SImode, operands[0]);
2760     operands[0] = gen_lowpart (SImode, operands[0]);
2761     operands[4] = gen_highpart (SImode, operands[1]);
2762     operands[1] = gen_lowpart (SImode, operands[1]);
2763   }"
2764   [(set_attr "length" "4,8")
2765    (set_attr "predicable" "yes")]
2766 )
2767   
2768 (define_insn_and_split "*anddi_notsesidi_di"
2769   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2770         (and:DI (not:DI (sign_extend:DI
2771                          (match_operand:SI 2 "s_register_operand" "r,r")))
2772                 (match_operand:DI 1 "s_register_operand" "0,r")))]
2773   "TARGET_32BIT"
2774   "#"
2775   "TARGET_32BIT && reload_completed"
2776   [(set (match_dup 0) (and:SI (not:SI (match_dup 2)) (match_dup 1)))
2777    (set (match_dup 3) (and:SI (not:SI
2778                                 (ashiftrt:SI (match_dup 2) (const_int 31)))
2779                                (match_dup 4)))]
2780   "
2781   {
2782     operands[3] = gen_highpart (SImode, operands[0]);
2783     operands[0] = gen_lowpart (SImode, operands[0]);
2784     operands[4] = gen_highpart (SImode, operands[1]);
2785     operands[1] = gen_lowpart (SImode, operands[1]);
2786   }"
2787   [(set_attr "length" "8")
2788    (set_attr "predicable" "yes")]
2789 )
2790   
2791 (define_insn "andsi_notsi_si"
2792   [(set (match_operand:SI 0 "s_register_operand" "=r")
2793         (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
2794                 (match_operand:SI 1 "s_register_operand" "r")))]
2795   "TARGET_32BIT"
2796   "bic%?\\t%0, %1, %2"
2797   [(set_attr "predicable" "yes")]
2798 )
2799
2800 (define_insn "thumb1_bicsi3"
2801   [(set (match_operand:SI                 0 "register_operand" "=l")
2802         (and:SI (not:SI (match_operand:SI 1 "register_operand" "l"))
2803                 (match_operand:SI         2 "register_operand" "0")))]
2804   "TARGET_THUMB1"
2805   "bic\\t%0, %1"
2806   [(set_attr "length" "2")
2807    (set_attr "conds" "set")])
2808
2809 (define_insn "andsi_not_shiftsi_si"
2810   [(set (match_operand:SI 0 "s_register_operand" "=r")
2811         (and:SI (not:SI (match_operator:SI 4 "shift_operator"
2812                          [(match_operand:SI 2 "s_register_operand" "r")
2813                           (match_operand:SI 3 "arm_rhs_operand" "rM")]))
2814                 (match_operand:SI 1 "s_register_operand" "r")))]
2815   "TARGET_ARM"
2816   "bic%?\\t%0, %1, %2%S4"
2817   [(set_attr "predicable" "yes")
2818    (set_attr "shift" "2")
2819    (set (attr "type") (if_then_else (match_operand 3 "const_int_operand" "")
2820                       (const_string "alu_shift")
2821                       (const_string "alu_shift_reg")))]
2822 )
2823
2824 (define_insn "*andsi_notsi_si_compare0"
2825   [(set (reg:CC_NOOV CC_REGNUM)
2826         (compare:CC_NOOV
2827          (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
2828                  (match_operand:SI 1 "s_register_operand" "r"))
2829          (const_int 0)))
2830    (set (match_operand:SI 0 "s_register_operand" "=r")
2831         (and:SI (not:SI (match_dup 2)) (match_dup 1)))]
2832   "TARGET_32BIT"
2833   "bic%.\\t%0, %1, %2"
2834   [(set_attr "conds" "set")]
2835 )
2836
2837 (define_insn "*andsi_notsi_si_compare0_scratch"
2838   [(set (reg:CC_NOOV CC_REGNUM)
2839         (compare:CC_NOOV
2840          (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
2841                  (match_operand:SI 1 "s_register_operand" "r"))
2842          (const_int 0)))
2843    (clobber (match_scratch:SI 0 "=r"))]
2844   "TARGET_32BIT"
2845   "bic%.\\t%0, %1, %2"
2846   [(set_attr "conds" "set")]
2847 )
2848
2849 (define_expand "iordi3"
2850   [(set (match_operand:DI         0 "s_register_operand" "")
2851         (ior:DI (match_operand:DI 1 "s_register_operand" "")
2852                 (match_operand:DI 2 "neon_logic_op2" "")))]
2853   "TARGET_32BIT"
2854   ""
2855 )
2856
2857 (define_insn "*iordi3_insn"
2858   [(set (match_operand:DI         0 "s_register_operand" "=&r,&r")
2859         (ior:DI (match_operand:DI 1 "s_register_operand"  "%0,r")
2860                 (match_operand:DI 2 "s_register_operand"   "r,r")))]
2861   "TARGET_32BIT && !TARGET_IWMMXT && !TARGET_NEON"
2862   "#"
2863   [(set_attr "length" "8")
2864    (set_attr "predicable" "yes")]
2865 )
2866
2867 (define_insn "*iordi_zesidi_di"
2868   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2869         (ior:DI (zero_extend:DI
2870                  (match_operand:SI 2 "s_register_operand" "r,r"))
2871                 (match_operand:DI 1 "s_register_operand" "0,?r")))]
2872   "TARGET_32BIT"
2873   "@
2874    orr%?\\t%Q0, %Q1, %2
2875    #"
2876   [(set_attr "length" "4,8")
2877    (set_attr "predicable" "yes")]
2878 )
2879
2880 (define_insn "*iordi_sesidi_di"
2881   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2882         (ior:DI (sign_extend:DI
2883                  (match_operand:SI 2 "s_register_operand" "r,r"))
2884                 (match_operand:DI 1 "s_register_operand" "0,r")))]
2885   "TARGET_32BIT"
2886   "#"
2887   [(set_attr "length" "8")
2888    (set_attr "predicable" "yes")]
2889 )
2890
2891 (define_expand "iorsi3"
2892   [(set (match_operand:SI         0 "s_register_operand" "")
2893         (ior:SI (match_operand:SI 1 "s_register_operand" "")
2894                 (match_operand:SI 2 "reg_or_int_operand" "")))]
2895   "TARGET_EITHER"
2896   "
2897   if (GET_CODE (operands[2]) == CONST_INT)
2898     {
2899       if (TARGET_32BIT)
2900         {
2901           arm_split_constant (IOR, SImode, NULL_RTX,
2902                               INTVAL (operands[2]), operands[0], operands[1],
2903                               optimize && can_create_pseudo_p ());
2904           DONE;
2905         }
2906       else /* TARGET_THUMB1 */
2907         {
2908           rtx tmp = force_reg (SImode, operands[2]);
2909           if (rtx_equal_p (operands[0], operands[1]))
2910             operands[2] = tmp;
2911           else
2912             {
2913               operands[2] = operands[1];
2914               operands[1] = tmp;
2915             }
2916         }
2917     }
2918   "
2919 )
2920
2921 (define_insn_and_split "*iorsi3_insn"
2922   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
2923         (ior:SI (match_operand:SI 1 "s_register_operand" "%r,r,r")
2924                 (match_operand:SI 2 "reg_or_int_operand" "rI,K,?n")))]
2925   "TARGET_32BIT"
2926   "@
2927    orr%?\\t%0, %1, %2
2928    orn%?\\t%0, %1, #%B2
2929    #"
2930   "TARGET_32BIT
2931    && GET_CODE (operands[2]) == CONST_INT
2932    && !(const_ok_for_arm (INTVAL (operands[2]))
2933         || (TARGET_THUMB2 && const_ok_for_arm (~INTVAL (operands[2]))))"
2934   [(clobber (const_int 0))]
2935 {
2936   arm_split_constant (IOR, SImode, curr_insn, 
2937                       INTVAL (operands[2]), operands[0], operands[1], 0);
2938   DONE;
2939 }
2940   [(set_attr "length" "4,4,16")
2941    (set_attr "arch" "32,t2,32")
2942    (set_attr "predicable" "yes")])
2943
2944 (define_insn "*thumb1_iorsi3_insn"
2945   [(set (match_operand:SI         0 "register_operand" "=l")
2946         (ior:SI (match_operand:SI 1 "register_operand" "%0")
2947                 (match_operand:SI 2 "register_operand" "l")))]
2948   "TARGET_THUMB1"
2949   "orr\\t%0, %2"
2950   [(set_attr "length" "2")
2951    (set_attr "conds" "set")])
2952
2953 (define_peephole2
2954   [(match_scratch:SI 3 "r")
2955    (set (match_operand:SI 0 "arm_general_register_operand" "")
2956         (ior:SI (match_operand:SI 1 "arm_general_register_operand" "")
2957                 (match_operand:SI 2 "const_int_operand" "")))]
2958   "TARGET_ARM
2959    && !const_ok_for_arm (INTVAL (operands[2]))
2960    && const_ok_for_arm (~INTVAL (operands[2]))"
2961   [(set (match_dup 3) (match_dup 2))
2962    (set (match_dup 0) (ior:SI (match_dup 1) (match_dup 3)))]
2963   ""
2964 )
2965
2966 (define_insn "*iorsi3_compare0"
2967   [(set (reg:CC_NOOV CC_REGNUM)
2968         (compare:CC_NOOV (ior:SI (match_operand:SI 1 "s_register_operand" "%r")
2969                                  (match_operand:SI 2 "arm_rhs_operand" "rI"))
2970                          (const_int 0)))
2971    (set (match_operand:SI 0 "s_register_operand" "=r")
2972         (ior:SI (match_dup 1) (match_dup 2)))]
2973   "TARGET_32BIT"
2974   "orr%.\\t%0, %1, %2"
2975   [(set_attr "conds" "set")]
2976 )
2977
2978 (define_insn "*iorsi3_compare0_scratch"
2979   [(set (reg:CC_NOOV CC_REGNUM)
2980         (compare:CC_NOOV (ior:SI (match_operand:SI 1 "s_register_operand" "%r")
2981                                  (match_operand:SI 2 "arm_rhs_operand" "rI"))
2982                          (const_int 0)))
2983    (clobber (match_scratch:SI 0 "=r"))]
2984   "TARGET_32BIT"
2985   "orr%.\\t%0, %1, %2"
2986   [(set_attr "conds" "set")]
2987 )
2988
2989 (define_expand "xordi3"
2990   [(set (match_operand:DI         0 "s_register_operand" "")
2991         (xor:DI (match_operand:DI 1 "s_register_operand" "")
2992                 (match_operand:DI 2 "s_register_operand" "")))]
2993   "TARGET_32BIT"
2994   ""
2995 )
2996
2997 (define_insn "*xordi3_insn"
2998   [(set (match_operand:DI         0 "s_register_operand" "=&r,&r")
2999         (xor:DI (match_operand:DI 1 "s_register_operand"  "%0,r")
3000                 (match_operand:DI 2 "s_register_operand"   "r,r")))]
3001   "TARGET_32BIT && !TARGET_IWMMXT && !TARGET_NEON"
3002   "#"
3003   [(set_attr "length" "8")
3004    (set_attr "predicable" "yes")]
3005 )
3006
3007 (define_insn "*xordi_zesidi_di"
3008   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
3009         (xor:DI (zero_extend:DI
3010                  (match_operand:SI 2 "s_register_operand" "r,r"))
3011                 (match_operand:DI 1 "s_register_operand" "0,?r")))]
3012   "TARGET_32BIT"
3013   "@
3014    eor%?\\t%Q0, %Q1, %2
3015    #"
3016   [(set_attr "length" "4,8")
3017    (set_attr "predicable" "yes")]
3018 )
3019
3020 (define_insn "*xordi_sesidi_di"
3021   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
3022         (xor:DI (sign_extend:DI
3023                  (match_operand:SI 2 "s_register_operand" "r,r"))
3024                 (match_operand:DI 1 "s_register_operand" "0,r")))]
3025   "TARGET_32BIT"
3026   "#"
3027   [(set_attr "length" "8")
3028    (set_attr "predicable" "yes")]
3029 )
3030
3031 (define_expand "xorsi3"
3032   [(set (match_operand:SI         0 "s_register_operand" "")
3033         (xor:SI (match_operand:SI 1 "s_register_operand" "")
3034                 (match_operand:SI 2 "reg_or_int_operand" "")))]
3035   "TARGET_EITHER"
3036   "if (GET_CODE (operands[2]) == CONST_INT)
3037     {
3038       if (TARGET_32BIT)
3039         {
3040           arm_split_constant (XOR, SImode, NULL_RTX,
3041                               INTVAL (operands[2]), operands[0], operands[1],
3042                               optimize && can_create_pseudo_p ());
3043           DONE;
3044         }
3045       else /* TARGET_THUMB1 */
3046         {
3047           rtx tmp = force_reg (SImode, operands[2]);
3048           if (rtx_equal_p (operands[0], operands[1]))
3049             operands[2] = tmp;
3050           else
3051             {
3052               operands[2] = operands[1];
3053               operands[1] = tmp;
3054             }
3055         }
3056     }"
3057 )
3058
3059 (define_insn "*arm_xorsi3"
3060   [(set (match_operand:SI         0 "s_register_operand" "=r")
3061         (xor:SI (match_operand:SI 1 "s_register_operand" "r")
3062                 (match_operand:SI 2 "arm_rhs_operand" "rI")))]
3063   "TARGET_32BIT"
3064   "eor%?\\t%0, %1, %2"
3065   [(set_attr "predicable" "yes")]
3066 )
3067
3068 (define_insn "*thumb1_xorsi3_insn"
3069   [(set (match_operand:SI         0 "register_operand" "=l")
3070         (xor:SI (match_operand:SI 1 "register_operand" "%0")
3071                 (match_operand:SI 2 "register_operand" "l")))]
3072   "TARGET_THUMB1"
3073   "eor\\t%0, %2"
3074   [(set_attr "length" "2")
3075    (set_attr "conds" "set")])
3076
3077 (define_insn "*xorsi3_compare0"
3078   [(set (reg:CC_NOOV CC_REGNUM)
3079         (compare:CC_NOOV (xor:SI (match_operand:SI 1 "s_register_operand" "r")
3080                                  (match_operand:SI 2 "arm_rhs_operand" "rI"))
3081                          (const_int 0)))
3082    (set (match_operand:SI 0 "s_register_operand" "=r")
3083         (xor:SI (match_dup 1) (match_dup 2)))]
3084   "TARGET_32BIT"
3085   "eor%.\\t%0, %1, %2"
3086   [(set_attr "conds" "set")]
3087 )
3088
3089 (define_insn "*xorsi3_compare0_scratch"
3090   [(set (reg:CC_NOOV CC_REGNUM)
3091         (compare:CC_NOOV (xor:SI (match_operand:SI 0 "s_register_operand" "r")
3092                                  (match_operand:SI 1 "arm_rhs_operand" "rI"))
3093                          (const_int 0)))]
3094   "TARGET_32BIT"
3095   "teq%?\\t%0, %1"
3096   [(set_attr "conds" "set")]
3097 )
3098
3099 ; By splitting (IOR (AND (NOT A) (NOT B)) C) as D = AND (IOR A B) (NOT C), 
3100 ; (NOT D) we can sometimes merge the final NOT into one of the following
3101 ; insns.
3102
3103 (define_split
3104   [(set (match_operand:SI 0 "s_register_operand" "")
3105         (ior:SI (and:SI (not:SI (match_operand:SI 1 "s_register_operand" ""))
3106                         (not:SI (match_operand:SI 2 "arm_rhs_operand" "")))
3107                 (match_operand:SI 3 "arm_rhs_operand" "")))
3108    (clobber (match_operand:SI 4 "s_register_operand" ""))]
3109   "TARGET_32BIT"
3110   [(set (match_dup 4) (and:SI (ior:SI (match_dup 1) (match_dup 2))
3111                               (not:SI (match_dup 3))))
3112    (set (match_dup 0) (not:SI (match_dup 4)))]
3113   ""
3114 )
3115
3116 (define_insn "*andsi_iorsi3_notsi"
3117   [(set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r")
3118         (and:SI (ior:SI (match_operand:SI 1 "s_register_operand" "%0,r,r")
3119                         (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI"))
3120                 (not:SI (match_operand:SI 3 "arm_rhs_operand" "rI,rI,rI"))))]
3121   "TARGET_32BIT"
3122   "orr%?\\t%0, %1, %2\;bic%?\\t%0, %0, %3"
3123   [(set_attr "length" "8")
3124    (set_attr "ce_count" "2")
3125    (set_attr "predicable" "yes")]
3126 )
3127
3128 ; ??? Are these four splitters still beneficial when the Thumb-2 bitfield
3129 ; insns are available?
3130 (define_split
3131   [(set (match_operand:SI 0 "s_register_operand" "")
3132         (match_operator:SI 1 "logical_binary_operator"
3133          [(zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
3134                            (match_operand:SI 3 "const_int_operand" "")
3135                            (match_operand:SI 4 "const_int_operand" ""))
3136           (match_operator:SI 9 "logical_binary_operator"
3137            [(lshiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3138                          (match_operand:SI 6 "const_int_operand" ""))
3139             (match_operand:SI 7 "s_register_operand" "")])]))
3140    (clobber (match_operand:SI 8 "s_register_operand" ""))]
3141   "TARGET_32BIT
3142    && GET_CODE (operands[1]) == GET_CODE (operands[9])
3143    && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3144   [(set (match_dup 8)
3145         (match_op_dup 1
3146          [(ashift:SI (match_dup 2) (match_dup 4))
3147           (match_dup 5)]))
3148    (set (match_dup 0)
3149         (match_op_dup 1
3150          [(lshiftrt:SI (match_dup 8) (match_dup 6))
3151           (match_dup 7)]))]
3152   "
3153   operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3154 ")
3155
3156 (define_split
3157   [(set (match_operand:SI 0 "s_register_operand" "")
3158         (match_operator:SI 1 "logical_binary_operator"
3159          [(match_operator:SI 9 "logical_binary_operator"
3160            [(lshiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3161                          (match_operand:SI 6 "const_int_operand" ""))
3162             (match_operand:SI 7 "s_register_operand" "")])
3163           (zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
3164                            (match_operand:SI 3 "const_int_operand" "")
3165                            (match_operand:SI 4 "const_int_operand" ""))]))
3166    (clobber (match_operand:SI 8 "s_register_operand" ""))]
3167   "TARGET_32BIT
3168    && GET_CODE (operands[1]) == GET_CODE (operands[9])
3169    && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3170   [(set (match_dup 8)
3171         (match_op_dup 1
3172          [(ashift:SI (match_dup 2) (match_dup 4))
3173           (match_dup 5)]))
3174    (set (match_dup 0)
3175         (match_op_dup 1
3176          [(lshiftrt:SI (match_dup 8) (match_dup 6))
3177           (match_dup 7)]))]
3178   "
3179   operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3180 ")
3181
3182 (define_split
3183   [(set (match_operand:SI 0 "s_register_operand" "")
3184         (match_operator:SI 1 "logical_binary_operator"
3185          [(sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
3186                            (match_operand:SI 3 "const_int_operand" "")
3187                            (match_operand:SI 4 "const_int_operand" ""))
3188           (match_operator:SI 9 "logical_binary_operator"
3189            [(ashiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3190                          (match_operand:SI 6 "const_int_operand" ""))
3191             (match_operand:SI 7 "s_register_operand" "")])]))
3192    (clobber (match_operand:SI 8 "s_register_operand" ""))]
3193   "TARGET_32BIT
3194    && GET_CODE (operands[1]) == GET_CODE (operands[9])
3195    && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3196   [(set (match_dup 8)
3197         (match_op_dup 1
3198          [(ashift:SI (match_dup 2) (match_dup 4))
3199           (match_dup 5)]))
3200    (set (match_dup 0)
3201         (match_op_dup 1
3202          [(ashiftrt:SI (match_dup 8) (match_dup 6))
3203           (match_dup 7)]))]
3204   "
3205   operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3206 ")
3207
3208 (define_split
3209   [(set (match_operand:SI 0 "s_register_operand" "")
3210         (match_operator:SI 1 "logical_binary_operator"
3211          [(match_operator:SI 9 "logical_binary_operator"
3212            [(ashiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3213                          (match_operand:SI 6 "const_int_operand" ""))
3214             (match_operand:SI 7 "s_register_operand" "")])
3215           (sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
3216                            (match_operand:SI 3 "const_int_operand" "")
3217                            (match_operand:SI 4 "const_int_operand" ""))]))
3218    (clobber (match_operand:SI 8 "s_register_operand" ""))]
3219   "TARGET_32BIT
3220    && GET_CODE (operands[1]) == GET_CODE (operands[9])
3221    && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3222   [(set (match_dup 8)
3223         (match_op_dup 1
3224          [(ashift:SI (match_dup 2) (match_dup 4))
3225           (match_dup 5)]))
3226    (set (match_dup 0)
3227         (match_op_dup 1
3228          [(ashiftrt:SI (match_dup 8) (match_dup 6))
3229           (match_dup 7)]))]
3230   "
3231   operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3232 ")
3233 \f
3234
3235 ;; Minimum and maximum insns
3236
3237 (define_expand "smaxsi3"
3238   [(parallel [
3239     (set (match_operand:SI 0 "s_register_operand" "")
3240          (smax:SI (match_operand:SI 1 "s_register_operand" "")
3241                   (match_operand:SI 2 "arm_rhs_operand" "")))
3242     (clobber (reg:CC CC_REGNUM))])]
3243   "TARGET_32BIT"
3244   "
3245   if (operands[2] == const0_rtx || operands[2] == constm1_rtx)
3246     {
3247       /* No need for a clobber of the condition code register here.  */
3248       emit_insn (gen_rtx_SET (VOIDmode, operands[0],
3249                               gen_rtx_SMAX (SImode, operands[1],
3250                                             operands[2])));
3251       DONE;
3252     }
3253 ")
3254
3255 (define_insn "*smax_0"
3256   [(set (match_operand:SI 0 "s_register_operand" "=r")
3257         (smax:SI (match_operand:SI 1 "s_register_operand" "r")
3258                  (const_int 0)))]
3259   "TARGET_32BIT"
3260   "bic%?\\t%0, %1, %1, asr #31"
3261   [(set_attr "predicable" "yes")]
3262 )
3263
3264 (define_insn "*smax_m1"
3265   [(set (match_operand:SI 0 "s_register_operand" "=r")
3266         (smax:SI (match_operand:SI 1 "s_register_operand" "r")
3267                  (const_int -1)))]
3268   "TARGET_32BIT"
3269   "orr%?\\t%0, %1, %1, asr #31"
3270   [(set_attr "predicable" "yes")]
3271 )
3272
3273 (define_insn "*arm_smax_insn"
3274   [(set (match_operand:SI          0 "s_register_operand" "=r,r")
3275         (smax:SI (match_operand:SI 1 "s_register_operand"  "%0,?r")
3276                  (match_operand:SI 2 "arm_rhs_operand"    "rI,rI")))
3277    (clobber (reg:CC CC_REGNUM))]
3278   "TARGET_ARM"
3279   "@
3280    cmp\\t%1, %2\;movlt\\t%0, %2
3281    cmp\\t%1, %2\;movge\\t%0, %1\;movlt\\t%0, %2"
3282   [(set_attr "conds" "clob")
3283    (set_attr "length" "8,12")]
3284 )
3285
3286 (define_expand "sminsi3"
3287   [(parallel [
3288     (set (match_operand:SI 0 "s_register_operand" "")
3289          (smin:SI (match_operand:SI 1 "s_register_operand" "")
3290                   (match_operand:SI 2 "arm_rhs_operand" "")))
3291     (clobber (reg:CC CC_REGNUM))])]
3292   "TARGET_32BIT"
3293   "
3294   if (operands[2] == const0_rtx)
3295     {
3296       /* No need for a clobber of the condition code register here.  */
3297       emit_insn (gen_rtx_SET (VOIDmode, operands[0],
3298                               gen_rtx_SMIN (SImode, operands[1],
3299                                             operands[2])));
3300       DONE;
3301     }
3302 ")
3303
3304 (define_insn "*smin_0"
3305   [(set (match_operand:SI 0 "s_register_operand" "=r")
3306         (smin:SI (match_operand:SI 1 "s_register_operand" "r")
3307                  (const_int 0)))]
3308   "TARGET_32BIT"
3309   "and%?\\t%0, %1, %1, asr #31"
3310   [(set_attr "predicable" "yes")]
3311 )
3312
3313 (define_insn "*arm_smin_insn"
3314   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3315         (smin:SI (match_operand:SI 1 "s_register_operand" "%0,?r")
3316                  (match_operand:SI 2 "arm_rhs_operand" "rI,rI")))
3317    (clobber (reg:CC CC_REGNUM))]
3318   "TARGET_ARM"
3319   "@
3320    cmp\\t%1, %2\;movge\\t%0, %2
3321    cmp\\t%1, %2\;movlt\\t%0, %1\;movge\\t%0, %2"
3322   [(set_attr "conds" "clob")
3323    (set_attr "length" "8,12")]
3324 )
3325
3326 (define_expand "umaxsi3"
3327   [(parallel [
3328     (set (match_operand:SI 0 "s_register_operand" "")
3329          (umax:SI (match_operand:SI 1 "s_register_operand" "")
3330                   (match_operand:SI 2 "arm_rhs_operand" "")))
3331     (clobber (reg:CC CC_REGNUM))])]
3332   "TARGET_32BIT"
3333   ""
3334 )
3335
3336 (define_insn "*arm_umaxsi3"
3337   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
3338         (umax:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
3339                  (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
3340    (clobber (reg:CC CC_REGNUM))]
3341   "TARGET_ARM"
3342   "@
3343    cmp\\t%1, %2\;movcc\\t%0, %2
3344    cmp\\t%1, %2\;movcs\\t%0, %1
3345    cmp\\t%1, %2\;movcs\\t%0, %1\;movcc\\t%0, %2"
3346   [(set_attr "conds" "clob")
3347    (set_attr "length" "8,8,12")]
3348 )
3349
3350 (define_expand "uminsi3"
3351   [(parallel [
3352     (set (match_operand:SI 0 "s_register_operand" "")
3353          (umin:SI (match_operand:SI 1 "s_register_operand" "")
3354                   (match_operand:SI 2 "arm_rhs_operand" "")))
3355     (clobber (reg:CC CC_REGNUM))])]
3356   "TARGET_32BIT"
3357   ""
3358 )
3359
3360 (define_insn "*arm_uminsi3"
3361   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
3362         (umin:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
3363                  (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
3364    (clobber (reg:CC CC_REGNUM))]
3365   "TARGET_ARM"
3366   "@
3367    cmp\\t%1, %2\;movcs\\t%0, %2
3368    cmp\\t%1, %2\;movcc\\t%0, %1
3369    cmp\\t%1, %2\;movcc\\t%0, %1\;movcs\\t%0, %2"
3370   [(set_attr "conds" "clob")
3371    (set_attr "length" "8,8,12")]
3372 )
3373
3374 (define_insn "*store_minmaxsi"
3375   [(set (match_operand:SI 0 "memory_operand" "=m")
3376         (match_operator:SI 3 "minmax_operator"
3377          [(match_operand:SI 1 "s_register_operand" "r")
3378           (match_operand:SI 2 "s_register_operand" "r")]))
3379    (clobber (reg:CC CC_REGNUM))]
3380   "TARGET_32BIT"
3381   "*
3382   operands[3] = gen_rtx_fmt_ee (minmax_code (operands[3]), SImode,
3383                                 operands[1], operands[2]);
3384   output_asm_insn (\"cmp\\t%1, %2\", operands);
3385   if (TARGET_THUMB2)
3386     output_asm_insn (\"ite\t%d3\", operands);
3387   output_asm_insn (\"str%d3\\t%1, %0\", operands);
3388   output_asm_insn (\"str%D3\\t%2, %0\", operands);
3389   return \"\";
3390   "
3391   [(set_attr "conds" "clob")
3392    (set (attr "length")
3393         (if_then_else (eq_attr "is_thumb" "yes")
3394                       (const_int 14)
3395                       (const_int 12)))
3396    (set_attr "type" "store1")]
3397 )
3398
3399 ; Reject the frame pointer in operand[1], since reloading this after
3400 ; it has been eliminated can cause carnage.
3401 (define_insn "*minmax_arithsi"
3402   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3403         (match_operator:SI 4 "shiftable_operator"
3404          [(match_operator:SI 5 "minmax_operator"
3405            [(match_operand:SI 2 "s_register_operand" "r,r")
3406             (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
3407           (match_operand:SI 1 "s_register_operand" "0,?r")]))
3408    (clobber (reg:CC CC_REGNUM))]
3409   "TARGET_32BIT && !arm_eliminable_register (operands[1])"
3410   "*
3411   {
3412     enum rtx_code code = GET_CODE (operands[4]);
3413     bool need_else;
3414
3415     if (which_alternative != 0 || operands[3] != const0_rtx
3416         || (code != PLUS && code != IOR && code != XOR))
3417       need_else = true;
3418     else
3419       need_else = false;
3420
3421     operands[5] = gen_rtx_fmt_ee (minmax_code (operands[5]), SImode,
3422                                   operands[2], operands[3]);
3423     output_asm_insn (\"cmp\\t%2, %3\", operands);
3424     if (TARGET_THUMB2)
3425       {
3426         if (need_else)
3427           output_asm_insn (\"ite\\t%d5\", operands);
3428         else
3429           output_asm_insn (\"it\\t%d5\", operands);
3430       }
3431     output_asm_insn (\"%i4%d5\\t%0, %1, %2\", operands);
3432     if (need_else)
3433       output_asm_insn (\"%i4%D5\\t%0, %1, %3\", operands);
3434     return \"\";
3435   }"
3436   [(set_attr "conds" "clob")
3437    (set (attr "length")
3438         (if_then_else (eq_attr "is_thumb" "yes")
3439                       (const_int 14)
3440                       (const_int 12)))]
3441 )
3442
3443 \f
3444 ;; Shift and rotation insns
3445
3446 (define_expand "ashldi3"
3447   [(set (match_operand:DI            0 "s_register_operand" "")
3448         (ashift:DI (match_operand:DI 1 "s_register_operand" "")
3449                    (match_operand:SI 2 "reg_or_int_operand" "")))]
3450   "TARGET_32BIT"
3451   "
3452   if (GET_CODE (operands[2]) == CONST_INT)
3453     {
3454       if ((HOST_WIDE_INT) INTVAL (operands[2]) == 1)
3455         {
3456           emit_insn (gen_arm_ashldi3_1bit (operands[0], operands[1]));
3457           DONE;
3458         }
3459         /* Ideally we shouldn't fail here if we could know that operands[1] 
3460            ends up already living in an iwmmxt register. Otherwise it's
3461            cheaper to have the alternate code being generated than moving
3462            values to iwmmxt regs and back.  */
3463         FAIL;
3464     }
3465   else if (!TARGET_REALLY_IWMMXT && !(TARGET_HARD_FLOAT && TARGET_MAVERICK))
3466     FAIL;
3467   "
3468 )
3469
3470 (define_insn "arm_ashldi3_1bit"
3471   [(set (match_operand:DI            0 "s_register_operand" "=r,&r")
3472         (ashift:DI (match_operand:DI 1 "s_register_operand" "0,r")
3473                    (const_int 1)))
3474    (clobber (reg:CC CC_REGNUM))]
3475   "TARGET_32BIT"
3476   "movs\\t%Q0, %Q1, asl #1\;adc\\t%R0, %R1, %R1"
3477   [(set_attr "conds" "clob")
3478    (set_attr "length" "8")]
3479 )
3480
3481 (define_expand "ashlsi3"
3482   [(set (match_operand:SI            0 "s_register_operand" "")
3483         (ashift:SI (match_operand:SI 1 "s_register_operand" "")
3484                    (match_operand:SI 2 "arm_rhs_operand" "")))]
3485   "TARGET_EITHER"
3486   "
3487   if (GET_CODE (operands[2]) == CONST_INT
3488       && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) > 31)
3489     {
3490       emit_insn (gen_movsi (operands[0], const0_rtx));
3491       DONE;
3492     }
3493   "
3494 )
3495
3496 (define_insn "*thumb1_ashlsi3"
3497   [(set (match_operand:SI            0 "register_operand" "=l,l")
3498         (ashift:SI (match_operand:SI 1 "register_operand" "l,0")
3499                    (match_operand:SI 2 "nonmemory_operand" "N,l")))]
3500   "TARGET_THUMB1"
3501   "lsl\\t%0, %1, %2"
3502   [(set_attr "length" "2")
3503    (set_attr "conds" "set")])
3504
3505 (define_expand "ashrdi3"
3506   [(set (match_operand:DI              0 "s_register_operand" "")
3507         (ashiftrt:DI (match_operand:DI 1 "s_register_operand" "")
3508                      (match_operand:SI 2 "reg_or_int_operand" "")))]
3509   "TARGET_32BIT"
3510   "
3511   if (GET_CODE (operands[2]) == CONST_INT)
3512     {
3513       if ((HOST_WIDE_INT) INTVAL (operands[2]) == 1)
3514         {
3515           emit_insn (gen_arm_ashrdi3_1bit (operands[0], operands[1]));
3516           DONE;
3517         }
3518         /* Ideally we shouldn't fail here if we could know that operands[1] 
3519            ends up already living in an iwmmxt register. Otherwise it's
3520            cheaper to have the alternate code being generated than moving
3521            values to iwmmxt regs and back.  */
3522         FAIL;
3523     }
3524   else if (!TARGET_REALLY_IWMMXT)
3525     FAIL;
3526   "
3527 )
3528
3529 (define_insn "arm_ashrdi3_1bit"
3530   [(set (match_operand:DI              0 "s_register_operand" "=r,&r")
3531         (ashiftrt:DI (match_operand:DI 1 "s_register_operand" "0,r")
3532                      (const_int 1)))
3533    (clobber (reg:CC CC_REGNUM))]
3534   "TARGET_32BIT"
3535   "movs\\t%R0, %R1, asr #1\;mov\\t%Q0, %Q1, rrx"
3536   [(set_attr "conds" "clob")
3537    (set_attr "insn" "mov")
3538    (set_attr "length" "8")]
3539 )
3540
3541 (define_expand "ashrsi3"
3542   [(set (match_operand:SI              0 "s_register_operand" "")
3543         (ashiftrt:SI (match_operand:SI 1 "s_register_operand" "")
3544                      (match_operand:SI 2 "arm_rhs_operand" "")))]
3545   "TARGET_EITHER"
3546   "
3547   if (GET_CODE (operands[2]) == CONST_INT
3548       && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) > 31)
3549     operands[2] = GEN_INT (31);
3550   "
3551 )
3552
3553 (define_insn "*thumb1_ashrsi3"
3554   [(set (match_operand:SI              0 "register_operand" "=l,l")
3555         (ashiftrt:SI (match_operand:SI 1 "register_operand" "l,0")
3556                      (match_operand:SI 2 "nonmemory_operand" "N,l")))]
3557   "TARGET_THUMB1"
3558   "asr\\t%0, %1, %2"
3559   [(set_attr "length" "2")
3560    (set_attr "conds" "set")])
3561
3562 (define_expand "lshrdi3"
3563   [(set (match_operand:DI              0 "s_register_operand" "")
3564         (lshiftrt:DI (match_operand:DI 1 "s_register_operand" "")
3565                      (match_operand:SI 2 "reg_or_int_operand" "")))]
3566   "TARGET_32BIT"
3567   "
3568   if (GET_CODE (operands[2]) == CONST_INT)
3569     {
3570       if ((HOST_WIDE_INT) INTVAL (operands[2]) == 1)
3571         {
3572           emit_insn (gen_arm_lshrdi3_1bit (operands[0], operands[1]));
3573           DONE;
3574         }
3575         /* Ideally we shouldn't fail here if we could know that operands[1] 
3576            ends up already living in an iwmmxt register. Otherwise it's
3577            cheaper to have the alternate code being generated than moving
3578            values to iwmmxt regs and back.  */
3579         FAIL;
3580     }
3581   else if (!TARGET_REALLY_IWMMXT)
3582     FAIL;
3583   "
3584 )
3585
3586 (define_insn "arm_lshrdi3_1bit"
3587   [(set (match_operand:DI              0 "s_register_operand" "=r,&r")
3588         (lshiftrt:DI (match_operand:DI 1 "s_register_operand" "0,r")
3589                      (const_int 1)))
3590    (clobber (reg:CC CC_REGNUM))]
3591   "TARGET_32BIT"
3592   "movs\\t%R0, %R1, lsr #1\;mov\\t%Q0, %Q1, rrx"
3593   [(set_attr "conds" "clob")
3594    (set_attr "insn" "mov")
3595    (set_attr "length" "8")]
3596 )
3597
3598 (define_expand "lshrsi3"
3599   [(set (match_operand:SI              0 "s_register_operand" "")
3600         (lshiftrt:SI (match_operand:SI 1 "s_register_operand" "")
3601                      (match_operand:SI 2 "arm_rhs_operand" "")))]
3602   "TARGET_EITHER"
3603   "
3604   if (GET_CODE (operands[2]) == CONST_INT
3605       && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) > 31)
3606     {
3607       emit_insn (gen_movsi (operands[0], const0_rtx));
3608       DONE;
3609     }
3610   "
3611 )
3612
3613 (define_insn "*thumb1_lshrsi3"
3614   [(set (match_operand:SI              0 "register_operand" "=l,l")
3615         (lshiftrt:SI (match_operand:SI 1 "register_operand" "l,0")
3616                      (match_operand:SI 2 "nonmemory_operand" "N,l")))]
3617   "TARGET_THUMB1"
3618   "lsr\\t%0, %1, %2"
3619   [(set_attr "length" "2")
3620    (set_attr "conds" "set")])
3621
3622 (define_expand "rotlsi3"
3623   [(set (match_operand:SI              0 "s_register_operand" "")
3624         (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
3625                      (match_operand:SI 2 "reg_or_int_operand" "")))]
3626   "TARGET_32BIT"
3627   "
3628   if (GET_CODE (operands[2]) == CONST_INT)
3629     operands[2] = GEN_INT ((32 - INTVAL (operands[2])) % 32);
3630   else
3631     {
3632       rtx reg = gen_reg_rtx (SImode);
3633       emit_insn (gen_subsi3 (reg, GEN_INT (32), operands[2]));
3634       operands[2] = reg;
3635     }
3636   "
3637 )
3638
3639 (define_expand "rotrsi3"
3640   [(set (match_operand:SI              0 "s_register_operand" "")
3641         (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
3642                      (match_operand:SI 2 "arm_rhs_operand" "")))]
3643   "TARGET_EITHER"
3644   "
3645   if (TARGET_32BIT)
3646     {
3647       if (GET_CODE (operands[2]) == CONST_INT
3648           && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) > 31)
3649         operands[2] = GEN_INT (INTVAL (operands[2]) % 32);
3650     }
3651   else /* TARGET_THUMB1 */
3652     {
3653       if (GET_CODE (operands [2]) == CONST_INT)
3654         operands [2] = force_reg (SImode, operands[2]);
3655     }
3656   "
3657 )
3658
3659 (define_insn "*thumb1_rotrsi3"
3660   [(set (match_operand:SI              0 "register_operand" "=l")
3661         (rotatert:SI (match_operand:SI 1 "register_operand" "0")
3662                      (match_operand:SI 2 "register_operand" "l")))]
3663   "TARGET_THUMB1"
3664   "ror\\t%0, %0, %2"
3665   [(set_attr "length" "2")]
3666 )
3667
3668 (define_insn "*arm_shiftsi3"
3669   [(set (match_operand:SI   0 "s_register_operand" "=r")
3670         (match_operator:SI  3 "shift_operator"
3671          [(match_operand:SI 1 "s_register_operand"  "r")
3672           (match_operand:SI 2 "reg_or_int_operand" "rM")]))]
3673   "TARGET_32BIT"
3674   "* return arm_output_shift(operands, 0);"
3675   [(set_attr "predicable" "yes")
3676    (set_attr "shift" "1")
3677    (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
3678                       (const_string "alu_shift")
3679                       (const_string "alu_shift_reg")))]
3680 )
3681
3682 (define_insn "*shiftsi3_compare0"
3683   [(set (reg:CC_NOOV CC_REGNUM)
3684         (compare:CC_NOOV (match_operator:SI 3 "shift_operator"
3685                           [(match_operand:SI 1 "s_register_operand" "r")
3686                            (match_operand:SI 2 "arm_rhs_operand" "rM")])
3687                          (const_int 0)))
3688    (set (match_operand:SI 0 "s_register_operand" "=r")
3689         (match_op_dup 3 [(match_dup 1) (match_dup 2)]))]
3690   "TARGET_32BIT"
3691   "* return arm_output_shift(operands, 1);"
3692   [(set_attr "conds" "set")
3693    (set_attr "shift" "1")
3694    (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
3695                       (const_string "alu_shift")
3696                       (const_string "alu_shift_reg")))]
3697 )
3698
3699 (define_insn "*shiftsi3_compare0_scratch"
3700   [(set (reg:CC_NOOV CC_REGNUM)
3701         (compare:CC_NOOV (match_operator:SI 3 "shift_operator"
3702                           [(match_operand:SI 1 "s_register_operand" "r")
3703                            (match_operand:SI 2 "arm_rhs_operand" "rM")])
3704                          (const_int 0)))
3705    (clobber (match_scratch:SI 0 "=r"))]
3706   "TARGET_32BIT"
3707   "* return arm_output_shift(operands, 1);"
3708   [(set_attr "conds" "set")
3709    (set_attr "shift" "1")]
3710 )
3711
3712 (define_insn "*not_shiftsi"
3713   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3714         (not:SI (match_operator:SI 3 "shift_operator"
3715                  [(match_operand:SI 1 "s_register_operand" "r,r")
3716                   (match_operand:SI 2 "shift_amount_operand" "M,rM")])))]
3717   "TARGET_32BIT"
3718   "mvn%?\\t%0, %1%S3"
3719   [(set_attr "predicable" "yes")
3720    (set_attr "shift" "1")
3721    (set_attr "insn" "mvn")
3722    (set_attr "arch" "32,a")
3723    (set_attr "type" "alu_shift,alu_shift_reg")])
3724
3725 (define_insn "*not_shiftsi_compare0"
3726   [(set (reg:CC_NOOV CC_REGNUM)
3727         (compare:CC_NOOV
3728          (not:SI (match_operator:SI 3 "shift_operator"
3729                   [(match_operand:SI 1 "s_register_operand" "r,r")
3730                    (match_operand:SI 2 "shift_amount_operand" "M,rM")]))
3731          (const_int 0)))
3732    (set (match_operand:SI 0 "s_register_operand" "=r,r")
3733         (not:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])))]
3734   "TARGET_32BIT"
3735   "mvn%.\\t%0, %1%S3"
3736   [(set_attr "conds" "set")
3737    (set_attr "shift" "1")
3738    (set_attr "insn" "mvn")
3739    (set_attr "arch" "32,a")
3740    (set_attr "type" "alu_shift,alu_shift_reg")])
3741
3742 (define_insn "*not_shiftsi_compare0_scratch"
3743   [(set (reg:CC_NOOV CC_REGNUM)
3744         (compare:CC_NOOV
3745          (not:SI (match_operator:SI 3 "shift_operator"
3746                   [(match_operand:SI 1 "s_register_operand" "r,r")
3747                    (match_operand:SI 2 "shift_amount_operand" "M,rM")]))
3748          (const_int 0)))
3749    (clobber (match_scratch:SI 0 "=r,r"))]
3750   "TARGET_32BIT"
3751   "mvn%.\\t%0, %1%S3"
3752   [(set_attr "conds" "set")
3753    (set_attr "shift" "1")
3754    (set_attr "insn" "mvn")
3755    (set_attr "arch" "32,a")
3756    (set_attr "type" "alu_shift,alu_shift_reg")])
3757
3758 ;; We don't really have extzv, but defining this using shifts helps
3759 ;; to reduce register pressure later on.
3760
3761 (define_expand "extzv"
3762   [(set (match_operand 0 "s_register_operand" "")
3763         (zero_extract (match_operand 1 "nonimmediate_operand" "")
3764                       (match_operand 2 "const_int_operand" "")
3765                       (match_operand 3 "const_int_operand" "")))]
3766   "TARGET_THUMB1 || arm_arch_thumb2"
3767   "
3768   {
3769     HOST_WIDE_INT lshift = 32 - INTVAL (operands[2]) - INTVAL (operands[3]);
3770     HOST_WIDE_INT rshift = 32 - INTVAL (operands[2]);
3771     
3772     if (arm_arch_thumb2)
3773       {
3774         HOST_WIDE_INT width = INTVAL (operands[2]);
3775         HOST_WIDE_INT bitpos = INTVAL (operands[3]);
3776
3777         if (unaligned_access && MEM_P (operands[1])
3778             && (width == 16 || width == 32) && (bitpos % BITS_PER_UNIT) == 0)
3779           {
3780             rtx base_addr;
3781
3782             if (BYTES_BIG_ENDIAN)
3783               bitpos = GET_MODE_BITSIZE (GET_MODE (operands[0])) - width
3784                        - bitpos;
3785
3786             if (width == 32)
3787               {
3788                 base_addr = adjust_address (operands[1], SImode,
3789                                             bitpos / BITS_PER_UNIT);
3790                 emit_insn (gen_unaligned_loadsi (operands[0], base_addr));
3791               }
3792             else
3793               {
3794                 rtx dest = operands[0];
3795                 rtx tmp = gen_reg_rtx (SImode);
3796
3797                 /* We may get a paradoxical subreg here.  Strip it off.  */
3798                 if (GET_CODE (dest) == SUBREG
3799                     && GET_MODE (dest) == SImode
3800                     && GET_MODE (SUBREG_REG (dest)) == HImode)
3801                   dest = SUBREG_REG (dest);
3802
3803                 if (GET_MODE_BITSIZE (GET_MODE (dest)) != width)
3804                   FAIL;
3805
3806                 base_addr = adjust_address (operands[1], HImode,
3807                                             bitpos / BITS_PER_UNIT);
3808                 emit_insn (gen_unaligned_loadhiu (tmp, base_addr));
3809                 emit_move_insn (gen_lowpart (SImode, dest), tmp);
3810               }
3811             DONE;
3812           }
3813         else if (s_register_operand (operands[1], GET_MODE (operands[1])))
3814           {
3815             emit_insn (gen_extzv_t2 (operands[0], operands[1], operands[2],
3816                                      operands[3]));
3817             DONE;
3818           }
3819         else
3820           FAIL;
3821       }
3822     
3823     if (!s_register_operand (operands[1], GET_MODE (operands[1])))
3824       FAIL;
3825
3826     operands[3] = GEN_INT (rshift);
3827     
3828     if (lshift == 0)
3829       {
3830         emit_insn (gen_lshrsi3 (operands[0], operands[1], operands[3]));
3831         DONE;
3832       }
3833       
3834     emit_insn (gen_extzv_t1 (operands[0], operands[1], GEN_INT (lshift),
3835                              operands[3], gen_reg_rtx (SImode)));
3836     DONE;
3837   }"
3838 )
3839
3840 ;; Helper for extzv, for the Thumb-1 register-shifts case.
3841
3842 (define_expand "extzv_t1"
3843   [(set (match_operand:SI 4 "s_register_operand" "")
3844         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
3845                    (match_operand:SI 2 "const_int_operand" "")))
3846    (set (match_operand:SI 0 "s_register_operand" "")
3847         (lshiftrt:SI (match_dup 4)
3848                      (match_operand:SI 3 "const_int_operand" "")))]
3849   "TARGET_THUMB1"
3850   "")
3851
3852 (define_expand "extv"
3853   [(set (match_operand 0 "s_register_operand" "")
3854         (sign_extract (match_operand 1 "nonimmediate_operand" "")
3855                       (match_operand 2 "const_int_operand" "")
3856                       (match_operand 3 "const_int_operand" "")))]
3857   "arm_arch_thumb2"
3858 {
3859   HOST_WIDE_INT width = INTVAL (operands[2]);
3860   HOST_WIDE_INT bitpos = INTVAL (operands[3]);
3861
3862   if (unaligned_access && MEM_P (operands[1]) && (width == 16 || width == 32)
3863       && (bitpos % BITS_PER_UNIT)  == 0)
3864     {
3865       rtx base_addr;
3866       
3867       if (BYTES_BIG_ENDIAN)
3868         bitpos = GET_MODE_BITSIZE (GET_MODE (operands[0])) - width - bitpos;
3869       
3870       if (width == 32)
3871         {
3872           base_addr = adjust_address (operands[1], SImode,
3873                                       bitpos / BITS_PER_UNIT);
3874           emit_insn (gen_unaligned_loadsi (operands[0], base_addr));
3875         }
3876       else
3877         {
3878           rtx dest = operands[0];
3879           rtx tmp = gen_reg_rtx (SImode);
3880           
3881           /* We may get a paradoxical subreg here.  Strip it off.  */
3882           if (GET_CODE (dest) == SUBREG
3883               && GET_MODE (dest) == SImode
3884               && GET_MODE (SUBREG_REG (dest)) == HImode)
3885             dest = SUBREG_REG (dest);
3886           
3887           if (GET_MODE_BITSIZE (GET_MODE (dest)) != width)
3888             FAIL;
3889<