OSDN Git Service

Latest updates from FSF 4.7 branch
[pf3gnuchains/gcc-fork.git] / gcc / config / arm / arm.md
1 ;;- Machine description for ARM for GNU compiler
2 ;;  Copyright 1991, 1993, 1994, 1995, 1996, 1996, 1997, 1998, 1999, 2000,
3 ;;  2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012
4 ;;  Free Software Foundation, Inc.
5 ;;  Contributed by Pieter `Tiggr' Schoenmakers (rcpieter@win.tue.nl)
6 ;;  and Martin Simmons (@harleqn.co.uk).
7 ;;  More major hacks by Richard Earnshaw (rearnsha@arm.com).
8
9 ;; This file is part of GCC.
10
11 ;; GCC is free software; you can redistribute it and/or modify it
12 ;; under the terms of the GNU General Public License as published
13 ;; by the Free Software Foundation; either version 3, or (at your
14 ;; option) any later version.
15
16 ;; GCC is distributed in the hope that it will be useful, but WITHOUT
17 ;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
18 ;; or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
19 ;; License for more details.
20
21 ;; You should have received a copy of the GNU General Public License
22 ;; along with GCC; see the file COPYING3.  If not see
23 ;; <http://www.gnu.org/licenses/>.
24
25 ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
26
27 \f
28 ;;---------------------------------------------------------------------------
29 ;; Constants
30
31 ;; Register numbers
32 (define_constants
33   [(R0_REGNUM        0)         ; First CORE register
34    (R1_REGNUM        1)         ; Second CORE register
35    (IP_REGNUM       12)         ; Scratch register
36    (SP_REGNUM       13)         ; Stack pointer
37    (LR_REGNUM       14)         ; Return address register
38    (PC_REGNUM       15)         ; Program counter
39    (CC_REGNUM       24)         ; Condition code pseudo register
40    (LAST_ARM_REGNUM 15)         ;
41    (FPA_F0_REGNUM   16)         ; FIRST_FPA_REGNUM
42    (FPA_F7_REGNUM   23)         ; LAST_FPA_REGNUM
43   ]
44 )
45 ;; 3rd operand to select_dominance_cc_mode
46 (define_constants
47   [(DOM_CC_X_AND_Y  0)
48    (DOM_CC_NX_OR_Y  1)
49    (DOM_CC_X_OR_Y   2)
50   ]
51 )
52 ;; conditional compare combination
53 (define_constants
54   [(CMP_CMP 0)
55    (CMN_CMP 1)
56    (CMP_CMN 2)
57    (CMN_CMN 3)
58    (NUM_OF_COND_CMP 4)
59   ]
60 )
61
62 ;; UNSPEC Usage:
63 ;; Note: sin and cos are no-longer used.
64 ;; Unspec enumerators for Neon are defined in neon.md.
65
66 (define_constants
67   [(UNSPEC_SIN       0) ; `sin' operation (MODE_FLOAT):
68                         ;   operand 0 is the result,
69                         ;   operand 1 the parameter.
70    (UNPSEC_COS       1) ; `cos' operation (MODE_FLOAT):
71                         ;   operand 0 is the result,
72                         ;   operand 1 the parameter.
73    (UNSPEC_PUSH_MULT 2) ; `push multiple' operation:
74                         ;   operand 0 is the first register,
75                         ;   subsequent registers are in parallel (use ...)
76                         ;   expressions.
77    (UNSPEC_PIC_SYM   3) ; 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  4) ; 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  5) ; A special barrier that prevents frame accesses 
84                         ;   being scheduled before the stack adjustment insn.
85    (UNSPEC_PROLOGUE_USE 6) ; 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 7); Set CCs to indicate 26-bit or 32-bit mode.
91    (UNSPEC_WSHUFH    8) ; Used by the intrinsic form of the iWMMXt WSHUFH instruction.
92    (UNSPEC_WACC      9) ; Used by the intrinsic form of the iWMMXt WACC instruction.
93    (UNSPEC_TMOVMSK  10) ; Used by the intrinsic form of the iWMMXt TMOVMSK instruction.
94    (UNSPEC_WSAD     11) ; Used by the intrinsic form of the iWMMXt WSAD instruction.
95    (UNSPEC_WSADZ    12) ; Used by the intrinsic form of the iWMMXt WSADZ instruction.
96    (UNSPEC_WMACS    13) ; Used by the intrinsic form of the iWMMXt WMACS instruction.
97    (UNSPEC_WMACU    14) ; Used by the intrinsic form of the iWMMXt WMACU instruction.
98    (UNSPEC_WMACSZ   15) ; Used by the intrinsic form of the iWMMXt WMACSZ instruction.
99    (UNSPEC_WMACUZ   16) ; Used by the intrinsic form of the iWMMXt WMACUZ instruction.
100    (UNSPEC_CLRDI    17) ; Used by the intrinsic form of the iWMMXt CLRDI instruction.
101    (UNSPEC_WMADDS   18) ; Used by the intrinsic form of the iWMMXt WMADDS instruction.
102    (UNSPEC_WMADDU   19) ; Used by the intrinsic form of the iWMMXt WMADDU instruction.
103    (UNSPEC_TLS      20) ; A symbol that has been treated properly for TLS usage.
104    (UNSPEC_PIC_LABEL 21) ; A label used for PIC access that does not appear in the
105                          ; instruction stream.
106    (UNSPEC_STACK_ALIGN 22) ; Doubleword aligned stack pointer.  Used to
107                            ; generate correct unwind information.
108    (UNSPEC_PIC_OFFSET 23) ; A symbolic 12-bit OFFSET that has been treated
109                           ; correctly for PIC usage.
110    (UNSPEC_GOTSYM_OFF 24) ; The offset of the start of the the GOT from a
111                           ; a given symbolic address.
112    (UNSPEC_THUMB1_CASESI 25) ; A Thumb1 compressed dispatch-table call.
113    (UNSPEC_RBIT 26)       ; rbit operation.
114    (UNSPEC_SYMBOL_OFFSET 27) ; The offset of the start of the symbol from
115                              ; another symbolic address.
116    (UNSPEC_MEMORY_BARRIER 28) ; Represent a memory barrier.
117    (UNSPEC_PIC_UNIFIED 29)  ; Create a common pic addressing form.
118    (UNSPEC_UNALIGNED_LOAD 30)
119    (UNSPEC_UNALIGNED_STORE 31)
120   ]
121 )
122
123 ;; UNSPEC_VOLATILE Usage:
124
125 (define_c_enum "unspecv" [
126   VUNSPEC_BLOCKAGE      ; `blockage' insn to prevent scheduling across an
127                         ;   insn in the code.
128   VUNSPEC_EPILOGUE      ; `epilogue' insn, used to represent any part of the
129                         ;   instruction epilogue sequence that isn't expanded
130                         ;   into normal RTL.  Used for both normal and sibcall
131                         ;   epilogues.
132   VUNSPEC_THUMB1_INTERWORK ; `prologue_thumb1_interwork' insn, used to swap
133                         ;   modes from arm to thumb.
134   VUNSPEC_ALIGN         ; `align' insn.  Used at the head of a minipool table
135                         ;   for inlined constants.
136   VUNSPEC_POOL_END      ; `end-of-table'.  Used to mark the end of a minipool
137                         ;   table.
138   VUNSPEC_POOL_1        ; `pool-entry(1)'.  An entry in the constant pool for
139                         ;   an 8-bit object.
140   VUNSPEC_POOL_2        ; `pool-entry(2)'.  An entry in the constant pool for
141                         ;   a 16-bit object.
142   VUNSPEC_POOL_4        ; `pool-entry(4)'.  An entry in the constant pool for
143                         ;   a 32-bit object.
144   VUNSPEC_POOL_8        ; `pool-entry(8)'.  An entry in the constant pool for
145                         ;   a 64-bit object.
146   VUNSPEC_POOL_16       ; `pool-entry(16)'.  An entry in the constant pool for
147                         ;   a 128-bit object.
148   VUNSPEC_TMRC          ; Used by the iWMMXt TMRC instruction.
149   VUNSPEC_TMCR          ; Used by the iWMMXt TMCR instruction.
150   VUNSPEC_ALIGN8        ; 8-byte alignment version of VUNSPEC_ALIGN
151   VUNSPEC_WCMP_EQ       ; Used by the iWMMXt WCMPEQ instructions
152   VUNSPEC_WCMP_GTU      ; Used by the iWMMXt WCMPGTU instructions
153   VUNSPEC_WCMP_GT       ; Used by the iwMMXT WCMPGT instructions
154   VUNSPEC_EH_RETURN     ; Use to override the return address for exception
155                         ; handling.
156   VUNSPEC_ATOMIC_CAS    ; Represent an atomic compare swap.
157   VUNSPEC_ATOMIC_XCHG   ; Represent an atomic exchange.
158   VUNSPEC_ATOMIC_OP     ; Represent an atomic operation.
159   VUNSPEC_LL            ; Represent a load-register-exclusive.
160   VUNSPEC_SC            ; Represent a store-register-exclusive.
161 ])
162 \f
163 ;;---------------------------------------------------------------------------
164 ;; Attributes
165
166 ;; Processor type.  This is created automatically from arm-cores.def.
167 (include "arm-tune.md")
168
169 ; IS_THUMB is set to 'yes' when we are generating Thumb code, and 'no' when
170 ; generating ARM code.  This is used to control the length of some insn
171 ; patterns that share the same RTL in both ARM and Thumb code.
172 (define_attr "is_thumb" "no,yes" (const (symbol_ref "thumb_code")))
173
174 ; IS_ARCH6 is set to 'yes' when we are generating code form ARMv6.
175 (define_attr "is_arch6" "no,yes" (const (symbol_ref "arm_arch6")))
176
177 ; IS_THUMB1 is set to 'yes' iff we are generating Thumb-1 code.
178 (define_attr "is_thumb1" "no,yes" (const (symbol_ref "thumb1_code")))
179
180 ;; Operand number of an input operand that is shifted.  Zero if the
181 ;; given instruction does not shift one of its input operands.
182 (define_attr "shift" "" (const_int 0))
183
184 ; Floating Point Unit.  If we only have floating point emulation, then there
185 ; is no point in scheduling the floating point insns.  (Well, for best
186 ; performance we should try and group them together).
187 (define_attr "fpu" "none,fpa,fpe2,fpe3,maverick,vfp"
188   (const (symbol_ref "arm_fpu_attr")))
189
190 ; LENGTH of an instruction (in bytes)
191 (define_attr "length" ""
192   (const_int 4))
193
194 ; The architecture which supports the instruction (or alternative).
195 ; This can be "a" for ARM, "t" for either of the Thumbs, "32" for
196 ; TARGET_32BIT, "t1" or "t2" to specify a specific Thumb mode.  "v6"
197 ; for ARM or Thumb-2 with arm_arch6, and nov6 for ARM without
198 ; arm_arch6.  This attribute is used to compute attribute "enabled",
199 ; use type "any" to enable an alternative in all cases.
200 (define_attr "arch" "any,a,t,32,t1,t2,v6,nov6,onlya8,nota8"
201   (const_string "any"))
202
203 (define_attr "arch_enabled" "no,yes"
204   (cond [(eq_attr "arch" "any")
205          (const_string "yes")
206
207          (and (eq_attr "arch" "a")
208               (match_test "TARGET_ARM"))
209          (const_string "yes")
210
211          (and (eq_attr "arch" "t")
212               (match_test "TARGET_THUMB"))
213          (const_string "yes")
214
215          (and (eq_attr "arch" "t1")
216               (match_test "TARGET_THUMB1"))
217          (const_string "yes")
218
219          (and (eq_attr "arch" "t2")
220               (match_test "TARGET_THUMB2"))
221          (const_string "yes")
222
223          (and (eq_attr "arch" "32")
224               (match_test "TARGET_32BIT"))
225          (const_string "yes")
226
227          (and (eq_attr "arch" "v6")
228               (match_test "TARGET_32BIT && arm_arch6"))
229          (const_string "yes")
230
231          (and (eq_attr "arch" "nov6")
232               (match_test "TARGET_32BIT && !arm_arch6"))
233          (const_string "yes")
234
235          (and (eq_attr "arch" "onlya8")
236               (eq_attr "tune" "cortexa8"))
237          (const_string "yes")
238
239          (and (eq_attr "arch" "nota8")
240               (not (eq_attr "tune" "cortexa8")))
241          (const_string "yes")]
242         (const_string "no")))
243
244 ; Allows an insn to disable certain alternatives for reasons other than
245 ; arch support.
246 (define_attr "insn_enabled" "no,yes"
247   (const_string "yes"))
248
249 ; Enable all alternatives that are both arch_enabled and insn_enabled.
250  (define_attr "enabled" "no,yes"
251    (if_then_else (eq_attr "insn_enabled" "yes")
252                (if_then_else (eq_attr "arch_enabled" "yes")
253                              (const_string "yes")
254                              (const_string "no"))
255                 (const_string "no")))
256
257 ; POOL_RANGE is how far away from a constant pool entry that this insn
258 ; can be placed.  If the distance is zero, then this insn will never
259 ; reference the pool.
260 ; NEG_POOL_RANGE is nonzero for insns that can reference a constant pool entry
261 ; before its address.  It is set to <max_range> - (8 + <data_size>).
262 (define_attr "arm_pool_range" "" (const_int 0))
263 (define_attr "thumb2_pool_range" "" (const_int 0))
264 (define_attr "arm_neg_pool_range" "" (const_int 0))
265 (define_attr "thumb2_neg_pool_range" "" (const_int 0))
266
267 (define_attr "pool_range" ""
268   (cond [(eq_attr "is_thumb" "yes") (attr "thumb2_pool_range")]
269         (attr "arm_pool_range")))
270 (define_attr "neg_pool_range" ""
271   (cond [(eq_attr "is_thumb" "yes") (attr "thumb2_neg_pool_range")]
272         (attr "arm_neg_pool_range")))
273
274 ; An assembler sequence may clobber the condition codes without us knowing.
275 ; If such an insn references the pool, then we have no way of knowing how,
276 ; so use the most conservative value for pool_range.
277 (define_asm_attributes
278  [(set_attr "conds" "clob")
279   (set_attr "length" "4")
280   (set_attr "pool_range" "250")])
281
282 ;; The instruction used to implement a particular pattern.  This
283 ;; information is used by pipeline descriptions to provide accurate
284 ;; scheduling information.
285
286 (define_attr "insn"
287         "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"
288         (const_string "other"))
289
290 ; TYPE attribute is used to detect floating point instructions which, if
291 ; running on a co-processor can run in parallel with other, basic instructions
292 ; If write-buffer scheduling is enabled then it can also be used in the
293 ; scheduling of writes.
294
295 ; Classification of each insn
296 ; Note: vfp.md has different meanings for some of these, and some further
297 ; types as well.  See that file for details.
298 ; alu           any alu  instruction that doesn't hit memory or fp
299 ;               regs or have a shifted source operand
300 ; alu_shift     any data instruction that doesn't hit memory or fp
301 ;               regs, but has a source operand shifted by a constant
302 ; alu_shift_reg any data instruction that doesn't hit memory or fp
303 ;               regs, but has a source operand shifted by a register value
304 ; mult          a multiply instruction
305 ; block         blockage insn, this blocks all functional units
306 ; float         a floating point arithmetic operation (subject to expansion)
307 ; fdivd         DFmode floating point division
308 ; fdivs         SFmode floating point division
309 ; fmul          Floating point multiply
310 ; ffmul         Fast floating point multiply
311 ; farith        Floating point arithmetic (4 cycle)
312 ; ffarith       Fast floating point arithmetic (2 cycle)
313 ; float_em      a floating point arithmetic operation that is normally emulated
314 ;               even on a machine with an fpa.
315 ; f_fpa_load    a floating point load from memory. Only for the FPA.
316 ; f_fpa_store   a floating point store to memory. Only for the FPA.
317 ; f_load[sd]    A single/double load from memory. Used for VFP unit.
318 ; f_store[sd]   A single/double store to memory. Used for VFP unit.
319 ; f_flag        a transfer of co-processor flags to the CPSR
320 ; f_mem_r       a transfer of a floating point register to a real reg via mem
321 ; r_mem_f       the reverse of f_mem_r
322 ; f_2_r         fast transfer float to arm (no memory needed)
323 ; r_2_f         fast transfer arm to float
324 ; f_cvt         convert floating<->integral
325 ; branch        a branch
326 ; call          a subroutine call
327 ; load_byte     load byte(s) from memory to arm registers
328 ; load1         load 1 word from memory to arm registers
329 ; load2         load 2 words from memory to arm registers
330 ; load3         load 3 words from memory to arm registers
331 ; load4         load 4 words from memory to arm registers
332 ; store         store 1 word to memory from arm registers
333 ; store2        store 2 words
334 ; store3        store 3 words
335 ; store4        store 4 (or more) words
336 ;  Additions for Cirrus Maverick co-processor:
337 ; mav_farith    Floating point arithmetic (4 cycle)
338 ; mav_dmult     Double multiplies (7 cycle)
339 ;
340
341 (define_attr "type"
342         "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"
343         (if_then_else 
344          (eq_attr "insn" "smulxy,smlaxy,smlalxy,smulwy,smlawx,mul,muls,mla,mlas,umull,umulls,umlal,umlals,smull,smulls,smlal,smlals")
345          (const_string "mult")
346          (const_string "alu")))
347
348 ; Is this an (integer side) multiply with a 64-bit result?
349 (define_attr "mul64" "no,yes"
350              (if_then_else
351                (eq_attr "insn" "smlalxy,umull,umulls,umlal,umlals,smull,smulls,smlal,smlals")
352                (const_string "yes")
353                (const_string "no")))
354
355 ; Load scheduling, set from the arm_ld_sched variable
356 ; initialized by arm_option_override()
357 (define_attr "ldsched" "no,yes" (const (symbol_ref "arm_ld_sched")))
358
359 ;; Classification of NEON instructions for scheduling purposes.
360 ;; Do not set this attribute and the "type" attribute together in
361 ;; any one instruction pattern.
362 (define_attr "neon_type"
363    "neon_int_1,\
364    neon_int_2,\
365    neon_int_3,\
366    neon_int_4,\
367    neon_int_5,\
368    neon_vqneg_vqabs,\
369    neon_vmov,\
370    neon_vaba,\
371    neon_vsma,\
372    neon_vaba_qqq,\
373    neon_mul_ddd_8_16_qdd_16_8_long_32_16_long,\
374    neon_mul_qqq_8_16_32_ddd_32,\
375    neon_mul_qdd_64_32_long_qqd_16_ddd_32_scalar_64_32_long_scalar,\
376    neon_mla_ddd_8_16_qdd_16_8_long_32_16_long,\
377    neon_mla_qqq_8_16,\
378    neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long,\
379    neon_mla_qqq_32_qqd_32_scalar,\
380    neon_mul_ddd_16_scalar_32_16_long_scalar,\
381    neon_mul_qqd_32_scalar,\
382    neon_mla_ddd_16_scalar_qdd_32_16_long_scalar,\
383    neon_shift_1,\
384    neon_shift_2,\
385    neon_shift_3,\
386    neon_vshl_ddd,\
387    neon_vqshl_vrshl_vqrshl_qqq,\
388    neon_vsra_vrsra,\
389    neon_fp_vadd_ddd_vabs_dd,\
390    neon_fp_vadd_qqq_vabs_qq,\
391    neon_fp_vsum,\
392    neon_fp_vmul_ddd,\
393    neon_fp_vmul_qqd,\
394    neon_fp_vmla_ddd,\
395    neon_fp_vmla_qqq,\
396    neon_fp_vmla_ddd_scalar,\
397    neon_fp_vmla_qqq_scalar,\
398    neon_fp_vrecps_vrsqrts_ddd,\
399    neon_fp_vrecps_vrsqrts_qqq,\
400    neon_bp_simple,\
401    neon_bp_2cycle,\
402    neon_bp_3cycle,\
403    neon_ldr,\
404    neon_str,\
405    neon_vld1_1_2_regs,\
406    neon_vld1_3_4_regs,\
407    neon_vld2_2_regs_vld1_vld2_all_lanes,\
408    neon_vld2_4_regs,\
409    neon_vld3_vld4,\
410    neon_vst1_1_2_regs_vst2_2_regs,\
411    neon_vst1_3_4_regs,\
412    neon_vst2_4_regs_vst3_vst4,\
413    neon_vst3_vst4,\
414    neon_vld1_vld2_lane,\
415    neon_vld3_vld4_lane,\
416    neon_vst1_vst2_lane,\
417    neon_vst3_vst4_lane,\
418    neon_vld3_vld4_all_lanes,\
419    neon_mcr,\
420    neon_mcr_2_mcrr,\
421    neon_mrc,\
422    neon_mrrc,\
423    neon_ldm_2,\
424    neon_stm_2,\
425    none"
426  (const_string "none"))
427
428 ; condition codes: this one is used by final_prescan_insn to speed up
429 ; conditionalizing instructions.  It saves having to scan the rtl to see if
430 ; it uses or alters the condition codes.
431
432 ; USE means that the condition codes are used by the insn in the process of
433 ;   outputting code, this means (at present) that we can't use the insn in
434 ;   inlined branches
435 ;
436 ; SET means that the purpose of the insn is to set the condition codes in a
437 ;   well defined manner.
438 ;
439 ; CLOB means that the condition codes are altered in an undefined manner, if
440 ;   they are altered at all
441 ;
442 ; UNCONDITIONAL means the instruction can not be conditionally executed and
443 ;   that the instruction does not use or alter the condition codes.
444 ;
445 ; NOCOND means that the instruction does not use or alter the condition
446 ;   codes but can be converted into a conditionally exectuted instruction.
447
448 (define_attr "conds" "use,set,clob,unconditional,nocond"
449         (if_then_else
450          (ior (eq_attr "is_thumb1" "yes")
451               (eq_attr "type" "call"))
452          (const_string "clob")
453          (if_then_else (eq_attr "neon_type" "none")
454           (const_string "nocond")
455           (const_string "unconditional"))))
456
457 ; Predicable means that the insn can be conditionally executed based on
458 ; an automatically added predicate (additional patterns are generated by 
459 ; gen...).  We default to 'no' because no Thumb patterns match this rule
460 ; and not all ARM patterns do.
461 (define_attr "predicable" "no,yes" (const_string "no"))
462
463 ; Only model the write buffer for ARM6 and ARM7.  Earlier processors don't
464 ; have one.  Later ones, such as StrongARM, have write-back caches, so don't
465 ; suffer blockages enough to warrant modelling this (and it can adversely
466 ; affect the schedule).
467 (define_attr "model_wbuf" "no,yes" (const (symbol_ref "arm_tune_wbuf")))
468
469 ; WRITE_CONFLICT implies that a read following an unrelated write is likely
470 ; to stall the processor.  Used with model_wbuf above.
471 (define_attr "write_conflict" "no,yes"
472   (if_then_else (eq_attr "type"
473                  "block,float_em,f_fpa_load,f_fpa_store,f_mem_r,r_mem_f,call,load1")
474                 (const_string "yes")
475                 (const_string "no")))
476
477 ; Classify the insns into those that take one cycle and those that take more
478 ; than one on the main cpu execution unit.
479 (define_attr "core_cycles" "single,multi"
480   (if_then_else (eq_attr "type"
481                  "alu,alu_shift,float,fdivx,fdivd,fdivs,fmul,ffmul,farith,ffarith")
482                 (const_string "single")
483                 (const_string "multi")))
484
485 ;; FAR_JUMP is "yes" if a BL instruction is used to generate a branch to a
486 ;; distant label.  Only applicable to Thumb code.
487 (define_attr "far_jump" "yes,no" (const_string "no"))
488
489
490 ;; The number of machine instructions this pattern expands to.
491 ;; Used for Thumb-2 conditional execution.
492 (define_attr "ce_count" "" (const_int 1))
493
494 ;;---------------------------------------------------------------------------
495 ;; Mode iterators
496
497 (include "iterators.md")
498
499 ;;---------------------------------------------------------------------------
500 ;; Predicates
501
502 (include "predicates.md")
503 (include "constraints.md")
504
505 ;;---------------------------------------------------------------------------
506 ;; Pipeline descriptions
507
508 (define_attr "tune_cortexr4" "yes,no"
509   (const (if_then_else
510           (eq_attr "tune" "cortexr4,cortexr4f,cortexr5")
511           (const_string "yes")
512           (const_string "no"))))
513
514 ;; True if the generic scheduling description should be used.
515
516 (define_attr "generic_sched" "yes,no"
517   (const (if_then_else
518           (ior (eq_attr "tune" "fa526,fa626,fa606te,fa626te,fmp626,fa726te,arm926ejs,arm1020e,arm1026ejs,arm1136js,arm1136jfs,cortexa5,cortexa8,cortexa9,cortexa15,cortexm4")
519                (eq_attr "tune_cortexr4" "yes"))
520           (const_string "no")
521           (const_string "yes"))))
522
523 (define_attr "generic_vfp" "yes,no"
524   (const (if_then_else
525           (and (eq_attr "fpu" "vfp")
526                (eq_attr "tune" "!arm1020e,arm1022e,cortexa5,cortexa8,cortexa9,cortexm4")
527                (eq_attr "tune_cortexr4" "no"))
528           (const_string "yes")
529           (const_string "no"))))
530
531 (include "arm-generic.md")
532 (include "arm926ejs.md")
533 (include "arm1020e.md")
534 (include "arm1026ejs.md")
535 (include "arm1136jfs.md")
536 (include "fa526.md")
537 (include "fa606te.md")
538 (include "fa626te.md")
539 (include "fmp626.md")
540 (include "fa726te.md")
541 (include "cortex-a5.md")
542 (include "cortex-a8.md")
543 (include "cortex-a9.md")
544 (include "cortex-a15.md")
545 (include "cortex-r4.md")
546 (include "cortex-r4f.md")
547 (include "cortex-m4.md")
548 (include "cortex-m4-fpu.md")
549 (include "vfp11.md")
550
551 \f
552 ;;---------------------------------------------------------------------------
553 ;; Insn patterns
554 ;;
555 ;; Addition insns.
556
557 ;; Note: For DImode insns, there is normally no reason why operands should
558 ;; not be in the same register, what we don't want is for something being
559 ;; written to partially overlap something that is an input.
560 ;; Cirrus 64bit additions should not be split because we have a native
561 ;; 64bit addition instructions.
562
563 (define_expand "adddi3"
564  [(parallel
565    [(set (match_operand:DI           0 "s_register_operand" "")
566           (plus:DI (match_operand:DI 1 "s_register_operand" "")
567                    (match_operand:DI 2 "s_register_operand" "")))
568     (clobber (reg:CC CC_REGNUM))])]
569   "TARGET_EITHER"
570   "
571   if (TARGET_HARD_FLOAT && TARGET_MAVERICK)
572     {
573       if (!cirrus_fp_register (operands[0], DImode))
574         operands[0] = force_reg (DImode, operands[0]);
575       if (!cirrus_fp_register (operands[1], DImode))
576         operands[1] = force_reg (DImode, operands[1]);
577       emit_insn (gen_cirrus_adddi3 (operands[0], operands[1], operands[2]));
578       DONE;
579     }
580
581   if (TARGET_THUMB1)
582     {
583       if (GET_CODE (operands[1]) != REG)
584         operands[1] = force_reg (DImode, operands[1]);
585       if (GET_CODE (operands[2]) != REG)
586         operands[2] = force_reg (DImode, operands[2]);
587      }
588   "
589 )
590
591 (define_insn "*thumb1_adddi3"
592   [(set (match_operand:DI          0 "register_operand" "=l")
593         (plus:DI (match_operand:DI 1 "register_operand" "%0")
594                  (match_operand:DI 2 "register_operand" "l")))
595    (clobber (reg:CC CC_REGNUM))
596   ]
597   "TARGET_THUMB1"
598   "add\\t%Q0, %Q0, %Q2\;adc\\t%R0, %R0, %R2"
599   [(set_attr "length" "4")]
600 )
601
602 (define_insn_and_split "*arm_adddi3"
603   [(set (match_operand:DI          0 "s_register_operand" "=&r,&r")
604         (plus:DI (match_operand:DI 1 "s_register_operand" "%0, 0")
605                  (match_operand:DI 2 "s_register_operand" "r,  0")))
606    (clobber (reg:CC CC_REGNUM))]
607   "TARGET_32BIT && !(TARGET_HARD_FLOAT && TARGET_MAVERICK) && !TARGET_NEON"
608   "#"
609   "TARGET_32BIT && reload_completed
610    && ! (TARGET_NEON && IS_VFP_REGNUM (REGNO (operands[0])))"
611   [(parallel [(set (reg:CC_C CC_REGNUM)
612                    (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
613                                  (match_dup 1)))
614               (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
615    (set (match_dup 3) (plus:SI (plus:SI (match_dup 4) (match_dup 5))
616                                (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
617   "
618   {
619     operands[3] = gen_highpart (SImode, operands[0]);
620     operands[0] = gen_lowpart (SImode, operands[0]);
621     operands[4] = gen_highpart (SImode, operands[1]);
622     operands[1] = gen_lowpart (SImode, operands[1]);
623     operands[5] = gen_highpart (SImode, operands[2]);
624     operands[2] = gen_lowpart (SImode, operands[2]);
625   }"
626   [(set_attr "conds" "clob")
627    (set_attr "length" "8")]
628 )
629
630 (define_insn_and_split "*adddi_sesidi_di"
631   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
632         (plus:DI (sign_extend:DI
633                   (match_operand:SI 2 "s_register_operand" "r,r"))
634                  (match_operand:DI 1 "s_register_operand" "0,r")))
635    (clobber (reg:CC CC_REGNUM))]
636   "TARGET_32BIT && !(TARGET_HARD_FLOAT && TARGET_MAVERICK)"
637   "#"
638   "TARGET_32BIT && reload_completed"
639   [(parallel [(set (reg:CC_C CC_REGNUM)
640                    (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
641                                  (match_dup 1)))
642               (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
643    (set (match_dup 3) (plus:SI (plus:SI (ashiftrt:SI (match_dup 2)
644                                                      (const_int 31))
645                                         (match_dup 4))
646                                (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
647   "
648   {
649     operands[3] = gen_highpart (SImode, operands[0]);
650     operands[0] = gen_lowpart (SImode, operands[0]);
651     operands[4] = gen_highpart (SImode, operands[1]);
652     operands[1] = gen_lowpart (SImode, operands[1]);
653     operands[2] = gen_lowpart (SImode, operands[2]);
654   }"
655   [(set_attr "conds" "clob")
656    (set_attr "length" "8")]
657 )
658
659 (define_insn_and_split "*adddi_zesidi_di"
660   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
661         (plus:DI (zero_extend:DI
662                   (match_operand:SI 2 "s_register_operand" "r,r"))
663                  (match_operand:DI 1 "s_register_operand" "0,r")))
664    (clobber (reg:CC CC_REGNUM))]
665   "TARGET_32BIT && !(TARGET_HARD_FLOAT && TARGET_MAVERICK)"
666   "#"
667   "TARGET_32BIT && reload_completed"
668   [(parallel [(set (reg:CC_C CC_REGNUM)
669                    (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
670                                  (match_dup 1)))
671               (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
672    (set (match_dup 3) (plus:SI (plus:SI (match_dup 4) (const_int 0))
673                                (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
674   "
675   {
676     operands[3] = gen_highpart (SImode, operands[0]);
677     operands[0] = gen_lowpart (SImode, operands[0]);
678     operands[4] = gen_highpart (SImode, operands[1]);
679     operands[1] = gen_lowpart (SImode, operands[1]);
680     operands[2] = gen_lowpart (SImode, operands[2]);
681   }"
682   [(set_attr "conds" "clob")
683    (set_attr "length" "8")]
684 )
685
686 (define_expand "addsi3"
687   [(set (match_operand:SI          0 "s_register_operand" "")
688         (plus:SI (match_operand:SI 1 "s_register_operand" "")
689                  (match_operand:SI 2 "reg_or_int_operand" "")))]
690   "TARGET_EITHER"
691   "
692   if (TARGET_32BIT && GET_CODE (operands[2]) == CONST_INT)
693     {
694       arm_split_constant (PLUS, SImode, NULL_RTX,
695                           INTVAL (operands[2]), operands[0], operands[1],
696                           optimize && can_create_pseudo_p ());
697       DONE;
698     }
699   "
700 )
701
702 ; If there is a scratch available, this will be faster than synthesizing the
703 ; addition.
704 (define_peephole2
705   [(match_scratch:SI 3 "r")
706    (set (match_operand:SI          0 "arm_general_register_operand" "")
707         (plus:SI (match_operand:SI 1 "arm_general_register_operand" "")
708                  (match_operand:SI 2 "const_int_operand"  "")))]
709   "TARGET_32BIT &&
710    !(const_ok_for_arm (INTVAL (operands[2]))
711      || const_ok_for_arm (-INTVAL (operands[2])))
712     && const_ok_for_arm (~INTVAL (operands[2]))"
713   [(set (match_dup 3) (match_dup 2))
714    (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 3)))]
715   ""
716 )
717
718 ;; The r/r/k alternative is required when reloading the address
719 ;;  (plus (reg rN) (reg sp)) into (reg rN).  In this case reload will
720 ;; put the duplicated register first, and not try the commutative version.
721 (define_insn_and_split "*arm_addsi3"
722   [(set (match_operand:SI          0 "s_register_operand" "=r, k,r,r, k, r, k,r, k, r")
723         (plus:SI (match_operand:SI 1 "s_register_operand" "%rk,k,r,rk,k, rk,k,rk,k, rk")
724                  (match_operand:SI 2 "reg_or_int_operand" "rI,rI,k,Pj,Pj,L, L,PJ,PJ,?n")))]
725   "TARGET_32BIT"
726   "@
727    add%?\\t%0, %1, %2
728    add%?\\t%0, %1, %2
729    add%?\\t%0, %2, %1
730    addw%?\\t%0, %1, %2
731    addw%?\\t%0, %1, %2
732    sub%?\\t%0, %1, #%n2
733    sub%?\\t%0, %1, #%n2
734    subw%?\\t%0, %1, #%n2
735    subw%?\\t%0, %1, #%n2
736    #"
737   "TARGET_32BIT
738    && GET_CODE (operands[2]) == CONST_INT
739    && !const_ok_for_op (INTVAL (operands[2]), PLUS)
740    && (reload_completed || !arm_eliminable_register (operands[1]))"
741   [(clobber (const_int 0))]
742   "
743   arm_split_constant (PLUS, SImode, curr_insn,
744                       INTVAL (operands[2]), operands[0],
745                       operands[1], 0);
746   DONE;
747   "
748   [(set_attr "length" "4,4,4,4,4,4,4,4,4,16")
749    (set_attr "predicable" "yes")
750    (set_attr "arch" "*,*,*,t2,t2,*,*,t2,t2,*")]
751 )
752
753 (define_insn_and_split "*thumb1_addsi3"
754   [(set (match_operand:SI          0 "register_operand" "=l,l,l,*rk,*hk,l,k,l,l,l")
755         (plus:SI (match_operand:SI 1 "register_operand" "%0,0,l,*0,*0,k,k,0,l,k")
756                  (match_operand:SI 2 "nonmemory_operand" "I,J,lL,*hk,*rk,M,O,Pa,Pb,Pc")))]
757   "TARGET_THUMB1"
758   "*
759    static const char * const asms[] = 
760    {
761      \"add\\t%0, %0, %2\",
762      \"sub\\t%0, %0, #%n2\",
763      \"add\\t%0, %1, %2\",
764      \"add\\t%0, %0, %2\",
765      \"add\\t%0, %0, %2\",
766      \"add\\t%0, %1, %2\",
767      \"add\\t%0, %1, %2\",
768      \"#\",
769      \"#\",
770      \"#\"
771    };
772    if ((which_alternative == 2 || which_alternative == 6)
773        && GET_CODE (operands[2]) == CONST_INT
774        && INTVAL (operands[2]) < 0)
775      return \"sub\\t%0, %1, #%n2\";
776    return asms[which_alternative];
777   "
778   "&& reload_completed && CONST_INT_P (operands[2])
779    && ((operands[1] != stack_pointer_rtx
780         && (INTVAL (operands[2]) > 255 || INTVAL (operands[2]) < -255))
781        || (operands[1] == stack_pointer_rtx
782            && INTVAL (operands[2]) > 1020))"
783   [(set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))
784    (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 3)))]
785   {
786     HOST_WIDE_INT offset = INTVAL (operands[2]);
787     if (operands[1] == stack_pointer_rtx)
788       offset -= 1020;
789     else
790       {
791         if (offset > 255)
792           offset = 255;
793         else if (offset < -255)
794           offset = -255;
795       }
796     operands[3] = GEN_INT (offset);
797     operands[2] = GEN_INT (INTVAL (operands[2]) - offset);
798   }
799   [(set_attr "length" "2,2,2,2,2,2,2,4,4,4")]
800 )
801
802 ;; Reloading and elimination of the frame pointer can
803 ;; sometimes cause this optimization to be missed.
804 (define_peephole2
805   [(set (match_operand:SI 0 "arm_general_register_operand" "")
806         (match_operand:SI 1 "const_int_operand" ""))
807    (set (match_dup 0)
808         (plus:SI (match_dup 0) (reg:SI SP_REGNUM)))]
809   "TARGET_THUMB1
810    && (unsigned HOST_WIDE_INT) (INTVAL (operands[1])) < 1024
811    && (INTVAL (operands[1]) & 3) == 0"
812   [(set (match_dup 0) (plus:SI (reg:SI SP_REGNUM) (match_dup 1)))]
813   ""
814 )
815
816 (define_insn "addsi3_compare0"
817   [(set (reg:CC_NOOV CC_REGNUM)
818         (compare:CC_NOOV
819          (plus:SI (match_operand:SI 1 "s_register_operand" "r, r")
820                   (match_operand:SI 2 "arm_add_operand"    "rI,L"))
821          (const_int 0)))
822    (set (match_operand:SI 0 "s_register_operand" "=r,r")
823         (plus:SI (match_dup 1) (match_dup 2)))]
824   "TARGET_ARM"
825   "@
826    add%.\\t%0, %1, %2
827    sub%.\\t%0, %1, #%n2"
828   [(set_attr "conds" "set")]
829 )
830
831 (define_insn "*addsi3_compare0_scratch"
832   [(set (reg:CC_NOOV CC_REGNUM)
833         (compare:CC_NOOV
834          (plus:SI (match_operand:SI 0 "s_register_operand" "r, r")
835                   (match_operand:SI 1 "arm_add_operand"    "rI,L"))
836          (const_int 0)))]
837   "TARGET_ARM"
838   "@
839    cmn%?\\t%0, %1
840    cmp%?\\t%0, #%n1"
841   [(set_attr "conds" "set")
842    (set_attr "predicable" "yes")]
843 )
844
845 (define_insn "*compare_negsi_si"
846   [(set (reg:CC_Z CC_REGNUM)
847         (compare:CC_Z
848          (neg:SI (match_operand:SI 0 "s_register_operand" "r"))
849          (match_operand:SI 1 "s_register_operand" "r")))]
850   "TARGET_32BIT"
851   "cmn%?\\t%1, %0"
852   [(set_attr "conds" "set")
853    (set_attr "predicable" "yes")]
854 )
855
856 ;; This is the canonicalization of addsi3_compare0_for_combiner when the
857 ;; addend is a constant.
858 (define_insn "*cmpsi2_addneg"
859   [(set (reg:CC CC_REGNUM)
860         (compare:CC
861          (match_operand:SI 1 "s_register_operand" "r,r")
862          (match_operand:SI 2 "arm_addimm_operand" "L,I")))
863    (set (match_operand:SI 0 "s_register_operand" "=r,r")
864         (plus:SI (match_dup 1)
865                  (match_operand:SI 3 "arm_addimm_operand" "I,L")))]
866   "TARGET_32BIT && INTVAL (operands[2]) == -INTVAL (operands[3])"
867   "@
868    add%.\\t%0, %1, %3
869    sub%.\\t%0, %1, #%n3"
870   [(set_attr "conds" "set")]
871 )
872
873 ;; Convert the sequence
874 ;;  sub  rd, rn, #1
875 ;;  cmn  rd, #1 (equivalent to cmp rd, #-1)
876 ;;  bne  dest
877 ;; into
878 ;;  subs rd, rn, #1
879 ;;  bcs  dest   ((unsigned)rn >= 1)
880 ;; similarly for the beq variant using bcc.
881 ;; This is a common looping idiom (while (n--))
882 (define_peephole2
883   [(set (match_operand:SI 0 "arm_general_register_operand" "")
884         (plus:SI (match_operand:SI 1 "arm_general_register_operand" "")
885                  (const_int -1)))
886    (set (match_operand 2 "cc_register" "")
887         (compare (match_dup 0) (const_int -1)))
888    (set (pc)
889         (if_then_else (match_operator 3 "equality_operator"
890                        [(match_dup 2) (const_int 0)])
891                       (match_operand 4 "" "")
892                       (match_operand 5 "" "")))]
893   "TARGET_32BIT && peep2_reg_dead_p (3, operands[2])"
894   [(parallel[
895     (set (match_dup 2)
896          (compare:CC
897           (match_dup 1) (const_int 1)))
898     (set (match_dup 0) (plus:SI (match_dup 1) (const_int -1)))])
899    (set (pc)
900         (if_then_else (match_op_dup 3 [(match_dup 2) (const_int 0)])
901                       (match_dup 4)
902                       (match_dup 5)))]
903   "operands[2] = gen_rtx_REG (CCmode, CC_REGNUM);
904    operands[3] = gen_rtx_fmt_ee ((GET_CODE (operands[3]) == NE
905                                   ? GEU : LTU),
906                                  VOIDmode, 
907                                  operands[2], const0_rtx);"
908 )
909
910 ;; The next four insns work because they compare the result with one of
911 ;; the operands, and we know that the use of the condition code is
912 ;; either GEU or LTU, so we can use the carry flag from the addition
913 ;; instead of doing the compare a second time.
914 (define_insn "*addsi3_compare_op1"
915   [(set (reg:CC_C CC_REGNUM)
916         (compare:CC_C
917          (plus:SI (match_operand:SI 1 "s_register_operand" "r,r")
918                   (match_operand:SI 2 "arm_add_operand" "rI,L"))
919          (match_dup 1)))
920    (set (match_operand:SI 0 "s_register_operand" "=r,r")
921         (plus:SI (match_dup 1) (match_dup 2)))]
922   "TARGET_32BIT"
923   "@
924    add%.\\t%0, %1, %2
925    sub%.\\t%0, %1, #%n2"
926   [(set_attr "conds" "set")]
927 )
928
929 (define_insn "*addsi3_compare_op2"
930   [(set (reg:CC_C CC_REGNUM)
931         (compare:CC_C
932          (plus:SI (match_operand:SI 1 "s_register_operand" "r,r")
933                   (match_operand:SI 2 "arm_add_operand" "rI,L"))
934          (match_dup 2)))
935    (set (match_operand:SI 0 "s_register_operand" "=r,r")
936         (plus:SI (match_dup 1) (match_dup 2)))]
937   "TARGET_32BIT"
938   "@
939    add%.\\t%0, %1, %2
940    sub%.\\t%0, %1, #%n2"
941   [(set_attr "conds" "set")]
942 )
943
944 (define_insn "*compare_addsi2_op0"
945   [(set (reg:CC_C CC_REGNUM)
946         (compare:CC_C
947          (plus:SI (match_operand:SI 0 "s_register_operand" "r,r")
948                   (match_operand:SI 1 "arm_add_operand" "rI,L"))
949          (match_dup 0)))]
950   "TARGET_32BIT"
951   "@
952    cmn%?\\t%0, %1
953    cmp%?\\t%0, #%n1"
954   [(set_attr "conds" "set")
955    (set_attr "predicable" "yes")]
956 )
957
958 (define_insn "*compare_addsi2_op1"
959   [(set (reg:CC_C CC_REGNUM)
960         (compare:CC_C
961          (plus:SI (match_operand:SI 0 "s_register_operand" "r,r")
962                   (match_operand:SI 1 "arm_add_operand" "rI,L"))
963          (match_dup 1)))]
964   "TARGET_32BIT"
965   "@
966    cmn%?\\t%0, %1
967    cmp%?\\t%0, #%n1"
968   [(set_attr "conds" "set")
969    (set_attr "predicable" "yes")]
970 )
971
972 (define_insn "*addsi3_carryin_<optab>"
973   [(set (match_operand:SI 0 "s_register_operand" "=r")
974         (plus:SI (plus:SI (match_operand:SI 1 "s_register_operand" "%r")
975                           (match_operand:SI 2 "arm_rhs_operand" "rI"))
976                  (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))))]
977   "TARGET_32BIT"
978   "adc%?\\t%0, %1, %2"
979   [(set_attr "conds" "use")]
980 )
981
982 (define_insn "*addsi3_carryin_alt2_<optab>"
983   [(set (match_operand:SI 0 "s_register_operand" "=r")
984         (plus:SI (plus:SI (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))
985                           (match_operand:SI 1 "s_register_operand" "%r"))
986                  (match_operand:SI 2 "arm_rhs_operand" "rI")))]
987   "TARGET_32BIT"
988   "adc%?\\t%0, %1, %2"
989   [(set_attr "conds" "use")]
990 )
991
992 (define_insn "*addsi3_carryin_shift_<optab>"
993   [(set (match_operand:SI 0 "s_register_operand" "=r")
994         (plus:SI (plus:SI
995                   (match_operator:SI 2 "shift_operator"
996                     [(match_operand:SI 3 "s_register_operand" "r")
997                      (match_operand:SI 4 "reg_or_int_operand" "rM")])
998                   (match_operand:SI 1 "s_register_operand" "r"))
999                  (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))))]
1000   "TARGET_32BIT"
1001   "adc%?\\t%0, %1, %3%S2"
1002   [(set_attr "conds" "use")
1003    (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
1004                       (const_string "alu_shift")
1005                       (const_string "alu_shift_reg")))]
1006 )
1007
1008 (define_insn "*addsi3_carryin_clobercc_<optab>"
1009   [(set (match_operand:SI 0 "s_register_operand" "=r")
1010         (plus:SI (plus:SI (match_operand:SI 1 "s_register_operand" "%r")
1011                           (match_operand:SI 2 "arm_rhs_operand" "rI"))
1012                  (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))))
1013    (clobber (reg:CC CC_REGNUM))]
1014    "TARGET_32BIT"
1015    "adc%.\\t%0, %1, %2"
1016    [(set_attr "conds" "set")]
1017 )
1018
1019 (define_expand "incscc"
1020   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
1021         (plus:SI (match_operator:SI 2 "arm_comparison_operator"
1022                     [(match_operand:CC 3 "cc_register" "") (const_int 0)])
1023                  (match_operand:SI 1 "s_register_operand" "0,?r")))]
1024   "TARGET_32BIT"
1025   ""
1026 )
1027
1028 (define_insn "*arm_incscc"
1029   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
1030         (plus:SI (match_operator:SI 2 "arm_comparison_operator"
1031                     [(match_operand:CC 3 "cc_register" "") (const_int 0)])
1032                  (match_operand:SI 1 "s_register_operand" "0,?r")))]
1033   "TARGET_ARM"
1034   "@
1035   add%d2\\t%0, %1, #1
1036   mov%D2\\t%0, %1\;add%d2\\t%0, %1, #1"
1037   [(set_attr "conds" "use")
1038    (set_attr "length" "4,8")]
1039 )
1040
1041 ; transform ((x << y) - 1) to ~(~(x-1) << y)  Where X is a constant.
1042 (define_split
1043   [(set (match_operand:SI 0 "s_register_operand" "")
1044         (plus:SI (ashift:SI (match_operand:SI 1 "const_int_operand" "")
1045                             (match_operand:SI 2 "s_register_operand" ""))
1046                  (const_int -1)))
1047    (clobber (match_operand:SI 3 "s_register_operand" ""))]
1048   "TARGET_32BIT"
1049   [(set (match_dup 3) (match_dup 1))
1050    (set (match_dup 0) (not:SI (ashift:SI (match_dup 3) (match_dup 2))))]
1051   "
1052   operands[1] = GEN_INT (~(INTVAL (operands[1]) - 1));
1053 ")
1054
1055 (define_expand "addsf3"
1056   [(set (match_operand:SF          0 "s_register_operand" "")
1057         (plus:SF (match_operand:SF 1 "s_register_operand" "")
1058                  (match_operand:SF 2 "arm_float_add_operand" "")))]
1059   "TARGET_32BIT && TARGET_HARD_FLOAT"
1060   "
1061   if (TARGET_MAVERICK
1062       && !cirrus_fp_register (operands[2], SFmode))
1063     operands[2] = force_reg (SFmode, operands[2]);
1064 ")
1065
1066 (define_expand "adddf3"
1067   [(set (match_operand:DF          0 "s_register_operand" "")
1068         (plus:DF (match_operand:DF 1 "s_register_operand" "")
1069                  (match_operand:DF 2 "arm_float_add_operand" "")))]
1070   "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
1071   "
1072   if (TARGET_MAVERICK
1073       && !cirrus_fp_register (operands[2], DFmode))
1074     operands[2] = force_reg (DFmode, operands[2]);
1075 ")
1076
1077 (define_expand "subdi3"
1078  [(parallel
1079    [(set (match_operand:DI            0 "s_register_operand" "")
1080           (minus:DI (match_operand:DI 1 "s_register_operand" "")
1081                     (match_operand:DI 2 "s_register_operand" "")))
1082     (clobber (reg:CC CC_REGNUM))])]
1083   "TARGET_EITHER"
1084   "
1085   if (TARGET_HARD_FLOAT && TARGET_MAVERICK
1086       && TARGET_32BIT
1087       && cirrus_fp_register (operands[0], DImode)
1088       && cirrus_fp_register (operands[1], DImode))
1089     {
1090       emit_insn (gen_cirrus_subdi3 (operands[0], operands[1], operands[2]));
1091       DONE;
1092     }
1093
1094   if (TARGET_THUMB1)
1095     {
1096       if (GET_CODE (operands[1]) != REG)
1097         operands[1] = force_reg (DImode, operands[1]);
1098       if (GET_CODE (operands[2]) != REG)
1099         operands[2] = force_reg (DImode, operands[2]);
1100      }  
1101   "
1102 )
1103
1104 (define_insn "*arm_subdi3"
1105   [(set (match_operand:DI           0 "s_register_operand" "=&r,&r,&r")
1106         (minus:DI (match_operand:DI 1 "s_register_operand" "0,r,0")
1107                   (match_operand:DI 2 "s_register_operand" "r,0,0")))
1108    (clobber (reg:CC CC_REGNUM))]
1109   "TARGET_32BIT && !TARGET_NEON"
1110   "subs\\t%Q0, %Q1, %Q2\;sbc\\t%R0, %R1, %R2"
1111   [(set_attr "conds" "clob")
1112    (set_attr "length" "8")]
1113 )
1114
1115 (define_insn "*thumb_subdi3"
1116   [(set (match_operand:DI           0 "register_operand" "=l")
1117         (minus:DI (match_operand:DI 1 "register_operand"  "0")
1118                   (match_operand:DI 2 "register_operand"  "l")))
1119    (clobber (reg:CC CC_REGNUM))]
1120   "TARGET_THUMB1"
1121   "sub\\t%Q0, %Q0, %Q2\;sbc\\t%R0, %R0, %R2"
1122   [(set_attr "length" "4")]
1123 )
1124
1125 (define_insn "*subdi_di_zesidi"
1126   [(set (match_operand:DI           0 "s_register_operand" "=&r,&r")
1127         (minus:DI (match_operand:DI 1 "s_register_operand"  "0,r")
1128                   (zero_extend:DI
1129                    (match_operand:SI 2 "s_register_operand"  "r,r"))))
1130    (clobber (reg:CC CC_REGNUM))]
1131   "TARGET_32BIT"
1132   "subs\\t%Q0, %Q1, %2\;sbc\\t%R0, %R1, #0"
1133   [(set_attr "conds" "clob")
1134    (set_attr "length" "8")]
1135 )
1136
1137 (define_insn "*subdi_di_sesidi"
1138   [(set (match_operand:DI            0 "s_register_operand" "=&r,&r")
1139         (minus:DI (match_operand:DI  1 "s_register_operand"  "0,r")
1140                   (sign_extend:DI
1141                    (match_operand:SI 2 "s_register_operand"  "r,r"))))
1142    (clobber (reg:CC CC_REGNUM))]
1143   "TARGET_32BIT"
1144   "subs\\t%Q0, %Q1, %2\;sbc\\t%R0, %R1, %2, asr #31"
1145   [(set_attr "conds" "clob")
1146    (set_attr "length" "8")]
1147 )
1148
1149 (define_insn "*subdi_zesidi_di"
1150   [(set (match_operand:DI            0 "s_register_operand" "=&r,&r")
1151         (minus:DI (zero_extend:DI
1152                    (match_operand:SI 2 "s_register_operand"  "r,r"))
1153                   (match_operand:DI  1 "s_register_operand" "0,r")))
1154    (clobber (reg:CC CC_REGNUM))]
1155   "TARGET_ARM"
1156   "rsbs\\t%Q0, %Q1, %2\;rsc\\t%R0, %R1, #0"
1157   [(set_attr "conds" "clob")
1158    (set_attr "length" "8")]
1159 )
1160
1161 (define_insn "*subdi_sesidi_di"
1162   [(set (match_operand:DI            0 "s_register_operand" "=&r,&r")
1163         (minus:DI (sign_extend:DI
1164                    (match_operand:SI 2 "s_register_operand"   "r,r"))
1165                   (match_operand:DI  1 "s_register_operand"  "0,r")))
1166    (clobber (reg:CC CC_REGNUM))]
1167   "TARGET_ARM"
1168   "rsbs\\t%Q0, %Q1, %2\;rsc\\t%R0, %R1, %2, asr #31"
1169   [(set_attr "conds" "clob")
1170    (set_attr "length" "8")]
1171 )
1172
1173 (define_insn "*subdi_zesidi_zesidi"
1174   [(set (match_operand:DI            0 "s_register_operand" "=r")
1175         (minus:DI (zero_extend:DI
1176                    (match_operand:SI 1 "s_register_operand"  "r"))
1177                   (zero_extend:DI
1178                    (match_operand:SI 2 "s_register_operand"  "r"))))
1179    (clobber (reg:CC CC_REGNUM))]
1180   "TARGET_32BIT"
1181   "subs\\t%Q0, %1, %2\;sbc\\t%R0, %1, %1"
1182   [(set_attr "conds" "clob")
1183    (set_attr "length" "8")]
1184 )
1185
1186 (define_expand "subsi3"
1187   [(set (match_operand:SI           0 "s_register_operand" "")
1188         (minus:SI (match_operand:SI 1 "reg_or_int_operand" "")
1189                   (match_operand:SI 2 "s_register_operand" "")))]
1190   "TARGET_EITHER"
1191   "
1192   if (GET_CODE (operands[1]) == CONST_INT)
1193     {
1194       if (TARGET_32BIT)
1195         {
1196           arm_split_constant (MINUS, SImode, NULL_RTX,
1197                               INTVAL (operands[1]), operands[0],
1198                               operands[2], optimize && can_create_pseudo_p ());
1199           DONE;
1200         }
1201       else /* TARGET_THUMB1 */
1202         operands[1] = force_reg (SImode, operands[1]);
1203     }
1204   "
1205 )
1206
1207 (define_insn "thumb1_subsi3_insn"
1208   [(set (match_operand:SI           0 "register_operand" "=l")
1209         (minus:SI (match_operand:SI 1 "register_operand" "l")
1210                   (match_operand:SI 2 "reg_or_int_operand" "lPd")))]
1211   "TARGET_THUMB1"
1212   "sub\\t%0, %1, %2"
1213   [(set_attr "length" "2")
1214    (set_attr "conds" "set")])
1215
1216 ; ??? Check Thumb-2 split length
1217 (define_insn_and_split "*arm_subsi3_insn"
1218   [(set (match_operand:SI           0 "s_register_operand" "=r,r,rk,r")
1219         (minus:SI (match_operand:SI 1 "reg_or_int_operand" "rI,r,k,?n")
1220                   (match_operand:SI 2 "reg_or_int_operand" "r,rI,r, r")))]
1221   "TARGET_32BIT"
1222   "@
1223    rsb%?\\t%0, %2, %1
1224    sub%?\\t%0, %1, %2
1225    sub%?\\t%0, %1, %2
1226    #"
1227   "&& (GET_CODE (operands[1]) == CONST_INT
1228        && !const_ok_for_arm (INTVAL (operands[1])))"
1229   [(clobber (const_int 0))]
1230   "
1231   arm_split_constant (MINUS, SImode, curr_insn,
1232                       INTVAL (operands[1]), operands[0], operands[2], 0);
1233   DONE;
1234   "
1235   [(set_attr "length" "4,4,4,16")
1236    (set_attr "predicable" "yes")]
1237 )
1238
1239 (define_peephole2
1240   [(match_scratch:SI 3 "r")
1241    (set (match_operand:SI 0 "arm_general_register_operand" "")
1242         (minus:SI (match_operand:SI 1 "const_int_operand" "")
1243                   (match_operand:SI 2 "arm_general_register_operand" "")))]
1244   "TARGET_32BIT
1245    && !const_ok_for_arm (INTVAL (operands[1]))
1246    && const_ok_for_arm (~INTVAL (operands[1]))"
1247   [(set (match_dup 3) (match_dup 1))
1248    (set (match_dup 0) (minus:SI (match_dup 3) (match_dup 2)))]
1249   ""
1250 )
1251
1252 (define_insn "*subsi3_compare0"
1253   [(set (reg:CC_NOOV CC_REGNUM)
1254         (compare:CC_NOOV
1255          (minus:SI (match_operand:SI 1 "arm_rhs_operand" "r,I")
1256                    (match_operand:SI 2 "arm_rhs_operand" "rI,r"))
1257          (const_int 0)))
1258    (set (match_operand:SI 0 "s_register_operand" "=r,r")
1259         (minus:SI (match_dup 1) (match_dup 2)))]
1260   "TARGET_32BIT"
1261   "@
1262    sub%.\\t%0, %1, %2
1263    rsb%.\\t%0, %2, %1"
1264   [(set_attr "conds" "set")]
1265 )
1266
1267 (define_insn "*subsi3_compare"
1268   [(set (reg:CC CC_REGNUM)
1269         (compare:CC (match_operand:SI 1 "arm_rhs_operand" "r,I")
1270                     (match_operand:SI 2 "arm_rhs_operand" "rI,r")))
1271    (set (match_operand:SI 0 "s_register_operand" "=r,r")
1272         (minus:SI (match_dup 1) (match_dup 2)))]
1273   "TARGET_32BIT"
1274   "@
1275    sub%.\\t%0, %1, %2
1276    rsb%.\\t%0, %2, %1"
1277   [(set_attr "conds" "set")]
1278 )
1279
1280 (define_expand "decscc"
1281   [(set (match_operand:SI            0 "s_register_operand" "=r,r")
1282         (minus:SI (match_operand:SI  1 "s_register_operand" "0,?r")
1283                   (match_operator:SI 2 "arm_comparison_operator"
1284                    [(match_operand   3 "cc_register" "") (const_int 0)])))]
1285   "TARGET_32BIT"
1286   ""
1287 )
1288
1289 (define_insn "*arm_decscc"
1290   [(set (match_operand:SI            0 "s_register_operand" "=r,r")
1291         (minus:SI (match_operand:SI  1 "s_register_operand" "0,?r")
1292                   (match_operator:SI 2 "arm_comparison_operator"
1293                    [(match_operand   3 "cc_register" "") (const_int 0)])))]
1294   "TARGET_ARM"
1295   "@
1296    sub%d2\\t%0, %1, #1
1297    mov%D2\\t%0, %1\;sub%d2\\t%0, %1, #1"
1298   [(set_attr "conds" "use")
1299    (set_attr "length" "*,8")]
1300 )
1301
1302 (define_expand "subsf3"
1303   [(set (match_operand:SF           0 "s_register_operand" "")
1304         (minus:SF (match_operand:SF 1 "arm_float_rhs_operand" "")
1305                   (match_operand:SF 2 "arm_float_rhs_operand" "")))]
1306   "TARGET_32BIT && TARGET_HARD_FLOAT"
1307   "
1308   if (TARGET_MAVERICK)
1309     {
1310       if (!cirrus_fp_register (operands[1], SFmode))
1311         operands[1] = force_reg (SFmode, operands[1]);
1312       if (!cirrus_fp_register (operands[2], SFmode))
1313         operands[2] = force_reg (SFmode, operands[2]);
1314     }
1315 ")
1316
1317 (define_expand "subdf3"
1318   [(set (match_operand:DF           0 "s_register_operand" "")
1319         (minus:DF (match_operand:DF 1 "arm_float_rhs_operand" "")
1320                   (match_operand:DF 2 "arm_float_rhs_operand" "")))]
1321   "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
1322   "
1323   if (TARGET_MAVERICK)
1324     {
1325        if (!cirrus_fp_register (operands[1], DFmode))
1326          operands[1] = force_reg (DFmode, operands[1]);
1327        if (!cirrus_fp_register (operands[2], DFmode))
1328          operands[2] = force_reg (DFmode, operands[2]);
1329     }
1330 ")
1331
1332 \f
1333 ;; Multiplication insns
1334
1335 (define_expand "mulsi3"
1336   [(set (match_operand:SI          0 "s_register_operand" "")
1337         (mult:SI (match_operand:SI 2 "s_register_operand" "")
1338                  (match_operand:SI 1 "s_register_operand" "")))]
1339   "TARGET_EITHER"
1340   ""
1341 )
1342
1343 ;; Use `&' and then `0' to prevent the operands 0 and 1 being the same
1344 (define_insn "*arm_mulsi3"
1345   [(set (match_operand:SI          0 "s_register_operand" "=&r,&r")
1346         (mult:SI (match_operand:SI 2 "s_register_operand" "r,r")
1347                  (match_operand:SI 1 "s_register_operand" "%0,r")))]
1348   "TARGET_32BIT && !arm_arch6"
1349   "mul%?\\t%0, %2, %1"
1350   [(set_attr "insn" "mul")
1351    (set_attr "predicable" "yes")]
1352 )
1353
1354 (define_insn "*arm_mulsi3_v6"
1355   [(set (match_operand:SI          0 "s_register_operand" "=r")
1356         (mult:SI (match_operand:SI 1 "s_register_operand" "r")
1357                  (match_operand:SI 2 "s_register_operand" "r")))]
1358   "TARGET_32BIT && arm_arch6"
1359   "mul%?\\t%0, %1, %2"
1360   [(set_attr "insn" "mul")
1361    (set_attr "predicable" "yes")]
1362 )
1363
1364 ; Unfortunately with the Thumb the '&'/'0' trick can fails when operands 
1365 ; 1 and 2; are the same, because reload will make operand 0 match 
1366 ; operand 1 without realizing that this conflicts with operand 2.  We fix 
1367 ; this by adding another alternative to match this case, and then `reload' 
1368 ; it ourselves.  This alternative must come first.
1369 (define_insn "*thumb_mulsi3"
1370   [(set (match_operand:SI          0 "register_operand" "=&l,&l,&l")
1371         (mult:SI (match_operand:SI 1 "register_operand" "%l,*h,0")
1372                  (match_operand:SI 2 "register_operand" "l,l,l")))]
1373   "TARGET_THUMB1 && !arm_arch6"
1374   "*
1375   if (which_alternative < 2)
1376     return \"mov\\t%0, %1\;mul\\t%0, %2\";
1377   else
1378     return \"mul\\t%0, %2\";
1379   "
1380   [(set_attr "length" "4,4,2")
1381    (set_attr "insn" "mul")]
1382 )
1383
1384 (define_insn "*thumb_mulsi3_v6"
1385   [(set (match_operand:SI          0 "register_operand" "=l,l,l")
1386         (mult:SI (match_operand:SI 1 "register_operand" "0,l,0")
1387                  (match_operand:SI 2 "register_operand" "l,0,0")))]
1388   "TARGET_THUMB1 && arm_arch6"
1389   "@
1390    mul\\t%0, %2
1391    mul\\t%0, %1
1392    mul\\t%0, %1"
1393   [(set_attr "length" "2")
1394    (set_attr "insn" "mul")]
1395 )
1396
1397 (define_insn "*mulsi3_compare0"
1398   [(set (reg:CC_NOOV CC_REGNUM)
1399         (compare:CC_NOOV (mult:SI
1400                           (match_operand:SI 2 "s_register_operand" "r,r")
1401                           (match_operand:SI 1 "s_register_operand" "%0,r"))
1402                          (const_int 0)))
1403    (set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1404         (mult:SI (match_dup 2) (match_dup 1)))]
1405   "TARGET_ARM && !arm_arch6"
1406   "mul%.\\t%0, %2, %1"
1407   [(set_attr "conds" "set")
1408    (set_attr "insn" "muls")]
1409 )
1410
1411 (define_insn "*mulsi3_compare0_v6"
1412   [(set (reg:CC_NOOV CC_REGNUM)
1413         (compare:CC_NOOV (mult:SI
1414                           (match_operand:SI 2 "s_register_operand" "r")
1415                           (match_operand:SI 1 "s_register_operand" "r"))
1416                          (const_int 0)))
1417    (set (match_operand:SI 0 "s_register_operand" "=r")
1418         (mult:SI (match_dup 2) (match_dup 1)))]
1419   "TARGET_ARM && arm_arch6 && optimize_size"
1420   "mul%.\\t%0, %2, %1"
1421   [(set_attr "conds" "set")
1422    (set_attr "insn" "muls")]
1423 )
1424
1425 (define_insn "*mulsi_compare0_scratch"
1426   [(set (reg:CC_NOOV CC_REGNUM)
1427         (compare:CC_NOOV (mult:SI
1428                           (match_operand:SI 2 "s_register_operand" "r,r")
1429                           (match_operand:SI 1 "s_register_operand" "%0,r"))
1430                          (const_int 0)))
1431    (clobber (match_scratch:SI 0 "=&r,&r"))]
1432   "TARGET_ARM && !arm_arch6"
1433   "mul%.\\t%0, %2, %1"
1434   [(set_attr "conds" "set")
1435    (set_attr "insn" "muls")]
1436 )
1437
1438 (define_insn "*mulsi_compare0_scratch_v6"
1439   [(set (reg:CC_NOOV CC_REGNUM)
1440         (compare:CC_NOOV (mult:SI
1441                           (match_operand:SI 2 "s_register_operand" "r")
1442                           (match_operand:SI 1 "s_register_operand" "r"))
1443                          (const_int 0)))
1444    (clobber (match_scratch:SI 0 "=r"))]
1445   "TARGET_ARM && arm_arch6 && optimize_size"
1446   "mul%.\\t%0, %2, %1"
1447   [(set_attr "conds" "set")
1448    (set_attr "insn" "muls")]
1449 )
1450
1451 ;; Unnamed templates to match MLA instruction.
1452
1453 (define_insn "*mulsi3addsi"
1454   [(set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r,&r")
1455         (plus:SI
1456           (mult:SI (match_operand:SI 2 "s_register_operand" "r,r,r,r")
1457                    (match_operand:SI 1 "s_register_operand" "%0,r,0,r"))
1458           (match_operand:SI 3 "s_register_operand" "r,r,0,0")))]
1459   "TARGET_32BIT && !arm_arch6"
1460   "mla%?\\t%0, %2, %1, %3"
1461   [(set_attr "insn" "mla")
1462    (set_attr "predicable" "yes")]
1463 )
1464
1465 (define_insn "*mulsi3addsi_v6"
1466   [(set (match_operand:SI 0 "s_register_operand" "=r")
1467         (plus:SI
1468           (mult:SI (match_operand:SI 2 "s_register_operand" "r")
1469                    (match_operand:SI 1 "s_register_operand" "r"))
1470           (match_operand:SI 3 "s_register_operand" "r")))]
1471   "TARGET_32BIT && arm_arch6"
1472   "mla%?\\t%0, %2, %1, %3"
1473   [(set_attr "insn" "mla")
1474    (set_attr "predicable" "yes")]
1475 )
1476
1477 (define_insn "*mulsi3addsi_compare0"
1478   [(set (reg:CC_NOOV CC_REGNUM)
1479         (compare:CC_NOOV
1480          (plus:SI (mult:SI
1481                    (match_operand:SI 2 "s_register_operand" "r,r,r,r")
1482                    (match_operand:SI 1 "s_register_operand" "%0,r,0,r"))
1483                   (match_operand:SI 3 "s_register_operand" "r,r,0,0"))
1484          (const_int 0)))
1485    (set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r,&r")
1486         (plus:SI (mult:SI (match_dup 2) (match_dup 1))
1487                  (match_dup 3)))]
1488   "TARGET_ARM && arm_arch6"
1489   "mla%.\\t%0, %2, %1, %3"
1490   [(set_attr "conds" "set")
1491    (set_attr "insn" "mlas")]
1492 )
1493
1494 (define_insn "*mulsi3addsi_compare0_v6"
1495   [(set (reg:CC_NOOV CC_REGNUM)
1496         (compare:CC_NOOV
1497          (plus:SI (mult:SI
1498                    (match_operand:SI 2 "s_register_operand" "r")
1499                    (match_operand:SI 1 "s_register_operand" "r"))
1500                   (match_operand:SI 3 "s_register_operand" "r"))
1501          (const_int 0)))
1502    (set (match_operand:SI 0 "s_register_operand" "=r")
1503         (plus:SI (mult:SI (match_dup 2) (match_dup 1))
1504                  (match_dup 3)))]
1505   "TARGET_ARM && arm_arch6 && optimize_size"
1506   "mla%.\\t%0, %2, %1, %3"
1507   [(set_attr "conds" "set")
1508    (set_attr "insn" "mlas")]
1509 )
1510
1511 (define_insn "*mulsi3addsi_compare0_scratch"
1512   [(set (reg:CC_NOOV CC_REGNUM)
1513         (compare:CC_NOOV
1514          (plus:SI (mult:SI
1515                    (match_operand:SI 2 "s_register_operand" "r,r,r,r")
1516                    (match_operand:SI 1 "s_register_operand" "%0,r,0,r"))
1517                   (match_operand:SI 3 "s_register_operand" "?r,r,0,0"))
1518          (const_int 0)))
1519    (clobber (match_scratch:SI 0 "=&r,&r,&r,&r"))]
1520   "TARGET_ARM && !arm_arch6"
1521   "mla%.\\t%0, %2, %1, %3"
1522   [(set_attr "conds" "set")
1523    (set_attr "insn" "mlas")]
1524 )
1525
1526 (define_insn "*mulsi3addsi_compare0_scratch_v6"
1527   [(set (reg:CC_NOOV CC_REGNUM)
1528         (compare:CC_NOOV
1529          (plus:SI (mult:SI
1530                    (match_operand:SI 2 "s_register_operand" "r")
1531                    (match_operand:SI 1 "s_register_operand" "r"))
1532                   (match_operand:SI 3 "s_register_operand" "r"))
1533          (const_int 0)))
1534    (clobber (match_scratch:SI 0 "=r"))]
1535   "TARGET_ARM && arm_arch6 && optimize_size"
1536   "mla%.\\t%0, %2, %1, %3"
1537   [(set_attr "conds" "set")
1538    (set_attr "insn" "mlas")]
1539 )
1540
1541 (define_insn "*mulsi3subsi"
1542   [(set (match_operand:SI 0 "s_register_operand" "=r")
1543         (minus:SI
1544           (match_operand:SI 3 "s_register_operand" "r")
1545           (mult:SI (match_operand:SI 2 "s_register_operand" "r")
1546                    (match_operand:SI 1 "s_register_operand" "r"))))]
1547   "TARGET_32BIT && arm_arch_thumb2"
1548   "mls%?\\t%0, %2, %1, %3"
1549   [(set_attr "insn" "mla")
1550    (set_attr "predicable" "yes")]
1551 )
1552
1553 (define_expand "maddsidi4"
1554   [(set (match_operand:DI 0 "s_register_operand" "")
1555         (plus:DI
1556          (mult:DI
1557           (sign_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1558           (sign_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1559          (match_operand:DI 3 "s_register_operand" "")))]
1560   "TARGET_32BIT && arm_arch3m"
1561   "")
1562
1563 (define_insn "*mulsidi3adddi"
1564   [(set (match_operand:DI 0 "s_register_operand" "=&r")
1565         (plus:DI
1566          (mult:DI
1567           (sign_extend:DI (match_operand:SI 2 "s_register_operand" "%r"))
1568           (sign_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1569          (match_operand:DI 1 "s_register_operand" "0")))]
1570   "TARGET_32BIT && arm_arch3m && !arm_arch6"
1571   "smlal%?\\t%Q0, %R0, %3, %2"
1572   [(set_attr "insn" "smlal")
1573    (set_attr "predicable" "yes")]
1574 )
1575
1576 (define_insn "*mulsidi3adddi_v6"
1577   [(set (match_operand:DI 0 "s_register_operand" "=r")
1578         (plus:DI
1579          (mult:DI
1580           (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r"))
1581           (sign_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1582          (match_operand:DI 1 "s_register_operand" "0")))]
1583   "TARGET_32BIT && arm_arch6"
1584   "smlal%?\\t%Q0, %R0, %3, %2"
1585   [(set_attr "insn" "smlal")
1586    (set_attr "predicable" "yes")]
1587 )
1588
1589 ;; 32x32->64 widening multiply.
1590 ;; As with mulsi3, the only difference between the v3-5 and v6+
1591 ;; versions of these patterns is the requirement that the output not
1592 ;; overlap the inputs, but that still means we have to have a named
1593 ;; expander and two different starred insns.
1594
1595 (define_expand "mulsidi3"
1596   [(set (match_operand:DI 0 "s_register_operand" "")
1597         (mult:DI
1598          (sign_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1599          (sign_extend:DI (match_operand:SI 2 "s_register_operand" ""))))]
1600   "TARGET_32BIT && arm_arch3m"
1601   ""
1602 )
1603
1604 (define_insn "*mulsidi3_nov6"
1605   [(set (match_operand:DI 0 "s_register_operand" "=&r")
1606         (mult:DI
1607          (sign_extend:DI (match_operand:SI 1 "s_register_operand" "%r"))
1608          (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1609   "TARGET_32BIT && arm_arch3m && !arm_arch6"
1610   "smull%?\\t%Q0, %R0, %1, %2"
1611   [(set_attr "insn" "smull")
1612    (set_attr "predicable" "yes")]
1613 )
1614
1615 (define_insn "*mulsidi3_v6"
1616   [(set (match_operand:DI 0 "s_register_operand" "=r")
1617         (mult:DI
1618          (sign_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1619          (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1620   "TARGET_32BIT && arm_arch6"
1621   "smull%?\\t%Q0, %R0, %1, %2"
1622   [(set_attr "insn" "smull")
1623    (set_attr "predicable" "yes")]
1624 )
1625
1626 (define_expand "umulsidi3"
1627   [(set (match_operand:DI 0 "s_register_operand" "")
1628         (mult:DI
1629          (zero_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1630          (zero_extend:DI (match_operand:SI 2 "s_register_operand" ""))))]
1631   "TARGET_32BIT && arm_arch3m"
1632   ""
1633 )
1634
1635 (define_insn "*umulsidi3_nov6"
1636   [(set (match_operand:DI 0 "s_register_operand" "=&r")
1637         (mult:DI
1638          (zero_extend:DI (match_operand:SI 1 "s_register_operand" "%r"))
1639          (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1640   "TARGET_32BIT && arm_arch3m && !arm_arch6"
1641   "umull%?\\t%Q0, %R0, %1, %2"
1642   [(set_attr "insn" "umull")
1643    (set_attr "predicable" "yes")]
1644 )
1645
1646 (define_insn "*umulsidi3_v6"
1647   [(set (match_operand:DI 0 "s_register_operand" "=r")
1648         (mult:DI
1649          (zero_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1650          (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1651   "TARGET_32BIT && arm_arch6"
1652   "umull%?\\t%Q0, %R0, %1, %2"
1653   [(set_attr "insn" "umull")
1654    (set_attr "predicable" "yes")]
1655 )
1656
1657 (define_expand "umaddsidi4"
1658   [(set (match_operand:DI 0 "s_register_operand" "")
1659         (plus:DI
1660          (mult:DI
1661           (zero_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1662           (zero_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1663          (match_operand:DI 3 "s_register_operand" "")))]
1664   "TARGET_32BIT && arm_arch3m"
1665   "")
1666
1667 (define_insn "*umulsidi3adddi"
1668   [(set (match_operand:DI 0 "s_register_operand" "=&r")
1669         (plus:DI
1670          (mult:DI
1671           (zero_extend:DI (match_operand:SI 2 "s_register_operand" "%r"))
1672           (zero_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1673          (match_operand:DI 1 "s_register_operand" "0")))]
1674   "TARGET_32BIT && arm_arch3m && !arm_arch6"
1675   "umlal%?\\t%Q0, %R0, %3, %2"
1676   [(set_attr "insn" "umlal")
1677    (set_attr "predicable" "yes")]
1678 )
1679
1680 (define_insn "*umulsidi3adddi_v6"
1681   [(set (match_operand:DI 0 "s_register_operand" "=r")
1682         (plus:DI
1683          (mult:DI
1684           (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r"))
1685           (zero_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1686          (match_operand:DI 1 "s_register_operand" "0")))]
1687   "TARGET_32BIT && arm_arch6"
1688   "umlal%?\\t%Q0, %R0, %3, %2"
1689   [(set_attr "insn" "umlal")
1690    (set_attr "predicable" "yes")]
1691 )
1692
1693 (define_expand "smulsi3_highpart"
1694   [(parallel
1695     [(set (match_operand:SI 0 "s_register_operand" "")
1696           (truncate:SI
1697            (lshiftrt:DI
1698             (mult:DI
1699              (sign_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1700              (sign_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1701             (const_int 32))))
1702      (clobber (match_scratch:SI 3 ""))])]
1703   "TARGET_32BIT && arm_arch3m"
1704   ""
1705 )
1706
1707 (define_insn "*smulsi3_highpart_nov6"
1708   [(set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1709         (truncate:SI
1710          (lshiftrt:DI
1711           (mult:DI
1712            (sign_extend:DI (match_operand:SI 1 "s_register_operand" "%0,r"))
1713            (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r,r")))
1714           (const_int 32))))
1715    (clobber (match_scratch:SI 3 "=&r,&r"))]
1716   "TARGET_32BIT && arm_arch3m && !arm_arch6"
1717   "smull%?\\t%3, %0, %2, %1"
1718   [(set_attr "insn" "smull")
1719    (set_attr "predicable" "yes")]
1720 )
1721
1722 (define_insn "*smulsi3_highpart_v6"
1723   [(set (match_operand:SI 0 "s_register_operand" "=r")
1724         (truncate:SI
1725          (lshiftrt:DI
1726           (mult:DI
1727            (sign_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1728            (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r")))
1729           (const_int 32))))
1730    (clobber (match_scratch:SI 3 "=r"))]
1731   "TARGET_32BIT && arm_arch6"
1732   "smull%?\\t%3, %0, %2, %1"
1733   [(set_attr "insn" "smull")
1734    (set_attr "predicable" "yes")]
1735 )
1736
1737 (define_expand "umulsi3_highpart"
1738   [(parallel
1739     [(set (match_operand:SI 0 "s_register_operand" "")
1740           (truncate:SI
1741            (lshiftrt:DI
1742             (mult:DI
1743              (zero_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1744               (zero_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1745             (const_int 32))))
1746      (clobber (match_scratch:SI 3 ""))])]
1747   "TARGET_32BIT && arm_arch3m"
1748   ""
1749 )
1750
1751 (define_insn "*umulsi3_highpart_nov6"
1752   [(set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1753         (truncate:SI
1754          (lshiftrt:DI
1755           (mult:DI
1756            (zero_extend:DI (match_operand:SI 1 "s_register_operand" "%0,r"))
1757            (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r,r")))
1758           (const_int 32))))
1759    (clobber (match_scratch:SI 3 "=&r,&r"))]
1760   "TARGET_32BIT && arm_arch3m && !arm_arch6"
1761   "umull%?\\t%3, %0, %2, %1"
1762   [(set_attr "insn" "umull")
1763    (set_attr "predicable" "yes")]
1764 )
1765
1766 (define_insn "*umulsi3_highpart_v6"
1767   [(set (match_operand:SI 0 "s_register_operand" "=r")
1768         (truncate:SI
1769          (lshiftrt:DI
1770           (mult:DI
1771            (zero_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1772            (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r")))
1773           (const_int 32))))
1774    (clobber (match_scratch:SI 3 "=r"))]
1775   "TARGET_32BIT && arm_arch6"
1776   "umull%?\\t%3, %0, %2, %1"
1777   [(set_attr "insn" "umull")
1778    (set_attr "predicable" "yes")]
1779 )
1780
1781 (define_insn "mulhisi3"
1782   [(set (match_operand:SI 0 "s_register_operand" "=r")
1783         (mult:SI (sign_extend:SI
1784                   (match_operand:HI 1 "s_register_operand" "%r"))
1785                  (sign_extend:SI
1786                   (match_operand:HI 2 "s_register_operand" "r"))))]
1787   "TARGET_DSP_MULTIPLY"
1788   "smulbb%?\\t%0, %1, %2"
1789   [(set_attr "insn" "smulxy")
1790    (set_attr "predicable" "yes")]
1791 )
1792
1793 (define_insn "*mulhisi3tb"
1794   [(set (match_operand:SI 0 "s_register_operand" "=r")
1795         (mult:SI (ashiftrt:SI
1796                   (match_operand:SI 1 "s_register_operand" "r")
1797                   (const_int 16))
1798                  (sign_extend:SI
1799                   (match_operand:HI 2 "s_register_operand" "r"))))]
1800   "TARGET_DSP_MULTIPLY"
1801   "smultb%?\\t%0, %1, %2"
1802   [(set_attr "insn" "smulxy")
1803    (set_attr "predicable" "yes")]
1804 )
1805
1806 (define_insn "*mulhisi3bt"
1807   [(set (match_operand:SI 0 "s_register_operand" "=r")
1808         (mult:SI (sign_extend:SI
1809                   (match_operand:HI 1 "s_register_operand" "r"))
1810                  (ashiftrt:SI
1811                   (match_operand:SI 2 "s_register_operand" "r")
1812                   (const_int 16))))]
1813   "TARGET_DSP_MULTIPLY"
1814   "smulbt%?\\t%0, %1, %2"
1815   [(set_attr "insn" "smulxy")
1816    (set_attr "predicable" "yes")]
1817 )
1818
1819 (define_insn "*mulhisi3tt"
1820   [(set (match_operand:SI 0 "s_register_operand" "=r")
1821         (mult:SI (ashiftrt:SI
1822                   (match_operand:SI 1 "s_register_operand" "r")
1823                   (const_int 16))
1824                  (ashiftrt:SI
1825                   (match_operand:SI 2 "s_register_operand" "r")
1826                   (const_int 16))))]
1827   "TARGET_DSP_MULTIPLY"
1828   "smultt%?\\t%0, %1, %2"
1829   [(set_attr "insn" "smulxy")
1830    (set_attr "predicable" "yes")]
1831 )
1832
1833 (define_insn "maddhisi4"
1834   [(set (match_operand:SI 0 "s_register_operand" "=r")
1835         (plus:SI (mult:SI (sign_extend:SI
1836                            (match_operand:HI 1 "s_register_operand" "r"))
1837                           (sign_extend:SI
1838                            (match_operand:HI 2 "s_register_operand" "r")))
1839                  (match_operand:SI 3 "s_register_operand" "r")))]
1840   "TARGET_DSP_MULTIPLY"
1841   "smlabb%?\\t%0, %1, %2, %3"
1842   [(set_attr "insn" "smlaxy")
1843    (set_attr "predicable" "yes")]
1844 )
1845
1846 ;; Note: there is no maddhisi4ibt because this one is canonical form
1847 (define_insn "*maddhisi4tb"
1848   [(set (match_operand:SI 0 "s_register_operand" "=r")
1849         (plus:SI (mult:SI (ashiftrt:SI
1850                            (match_operand:SI 1 "s_register_operand" "r")
1851                            (const_int 16))
1852                           (sign_extend:SI
1853                            (match_operand:HI 2 "s_register_operand" "r")))
1854                  (match_operand:SI 3 "s_register_operand" "r")))]
1855   "TARGET_DSP_MULTIPLY"
1856   "smlatb%?\\t%0, %1, %2, %3"
1857   [(set_attr "insn" "smlaxy")
1858    (set_attr "predicable" "yes")]
1859 )
1860
1861 (define_insn "*maddhisi4tt"
1862   [(set (match_operand:SI 0 "s_register_operand" "=r")
1863         (plus:SI (mult:SI (ashiftrt:SI
1864                            (match_operand:SI 1 "s_register_operand" "r")
1865                            (const_int 16))
1866                           (ashiftrt:SI
1867                            (match_operand:SI 2 "s_register_operand" "r")
1868                            (const_int 16)))
1869                  (match_operand:SI 3 "s_register_operand" "r")))]
1870   "TARGET_DSP_MULTIPLY"
1871   "smlatt%?\\t%0, %1, %2, %3"
1872   [(set_attr "insn" "smlaxy")
1873    (set_attr "predicable" "yes")]
1874 )
1875
1876 (define_insn "maddhidi4"
1877   [(set (match_operand:DI 0 "s_register_operand" "=r")
1878         (plus:DI
1879           (mult:DI (sign_extend:DI
1880                     (match_operand:HI 1 "s_register_operand" "r"))
1881                    (sign_extend:DI
1882                     (match_operand:HI 2 "s_register_operand" "r")))
1883           (match_operand:DI 3 "s_register_operand" "0")))]
1884   "TARGET_DSP_MULTIPLY"
1885   "smlalbb%?\\t%Q0, %R0, %1, %2"
1886   [(set_attr "insn" "smlalxy")
1887    (set_attr "predicable" "yes")])
1888
1889 ;; Note: there is no maddhidi4ibt because this one is canonical form
1890 (define_insn "*maddhidi4tb"
1891   [(set (match_operand:DI 0 "s_register_operand" "=r")
1892         (plus:DI
1893           (mult:DI (sign_extend:DI
1894                     (ashiftrt:SI
1895                      (match_operand:SI 1 "s_register_operand" "r")
1896                      (const_int 16)))
1897                    (sign_extend:DI
1898                     (match_operand:HI 2 "s_register_operand" "r")))
1899           (match_operand:DI 3 "s_register_operand" "0")))]
1900   "TARGET_DSP_MULTIPLY"
1901   "smlaltb%?\\t%Q0, %R0, %1, %2"
1902   [(set_attr "insn" "smlalxy")
1903    (set_attr "predicable" "yes")])
1904
1905 (define_insn "*maddhidi4tt"
1906   [(set (match_operand:DI 0 "s_register_operand" "=r")
1907         (plus:DI
1908           (mult:DI (sign_extend:DI
1909                     (ashiftrt:SI
1910                      (match_operand:SI 1 "s_register_operand" "r")
1911                      (const_int 16)))
1912                    (sign_extend:DI
1913                     (ashiftrt:SI
1914                      (match_operand:SI 2 "s_register_operand" "r")
1915                      (const_int 16))))
1916           (match_operand:DI 3 "s_register_operand" "0")))]
1917   "TARGET_DSP_MULTIPLY"
1918   "smlaltt%?\\t%Q0, %R0, %1, %2"
1919   [(set_attr "insn" "smlalxy")
1920    (set_attr "predicable" "yes")])
1921
1922 (define_expand "mulsf3"
1923   [(set (match_operand:SF          0 "s_register_operand" "")
1924         (mult:SF (match_operand:SF 1 "s_register_operand" "")
1925                  (match_operand:SF 2 "arm_float_rhs_operand" "")))]
1926   "TARGET_32BIT && TARGET_HARD_FLOAT"
1927   "
1928   if (TARGET_MAVERICK
1929       && !cirrus_fp_register (operands[2], SFmode))
1930     operands[2] = force_reg (SFmode, operands[2]);
1931 ")
1932
1933 (define_expand "muldf3"
1934   [(set (match_operand:DF          0 "s_register_operand" "")
1935         (mult:DF (match_operand:DF 1 "s_register_operand" "")
1936                  (match_operand:DF 2 "arm_float_rhs_operand" "")))]
1937   "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
1938   "
1939   if (TARGET_MAVERICK
1940       && !cirrus_fp_register (operands[2], DFmode))
1941     operands[2] = force_reg (DFmode, operands[2]);
1942 ")
1943 \f
1944 ;; Division insns
1945
1946 (define_expand "divsf3"
1947   [(set (match_operand:SF 0 "s_register_operand" "")
1948         (div:SF (match_operand:SF 1 "arm_float_rhs_operand" "")
1949                 (match_operand:SF 2 "arm_float_rhs_operand" "")))]
1950   "TARGET_32BIT && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP)"
1951   "")
1952
1953 (define_expand "divdf3"
1954   [(set (match_operand:DF 0 "s_register_operand" "")
1955         (div:DF (match_operand:DF 1 "arm_float_rhs_operand" "")
1956                 (match_operand:DF 2 "arm_float_rhs_operand" "")))]
1957   "TARGET_32BIT && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP_DOUBLE)"
1958   "")
1959 \f
1960 ;; Modulo insns
1961
1962 (define_expand "modsf3"
1963   [(set (match_operand:SF 0 "s_register_operand" "")
1964         (mod:SF (match_operand:SF 1 "s_register_operand" "")
1965                 (match_operand:SF 2 "arm_float_rhs_operand" "")))]
1966   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_FPA"
1967   "")
1968
1969 (define_expand "moddf3"
1970   [(set (match_operand:DF 0 "s_register_operand" "")
1971         (mod:DF (match_operand:DF 1 "s_register_operand" "")
1972                 (match_operand:DF 2 "arm_float_rhs_operand" "")))]
1973   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_FPA"
1974   "")
1975 \f
1976 ;; Boolean and,ior,xor insns
1977
1978 ;; Split up double word logical operations
1979
1980 ;; Split up simple DImode logical operations.  Simply perform the logical
1981 ;; operation on the upper and lower halves of the registers.
1982 (define_split
1983   [(set (match_operand:DI 0 "s_register_operand" "")
1984         (match_operator:DI 6 "logical_binary_operator"
1985           [(match_operand:DI 1 "s_register_operand" "")
1986            (match_operand:DI 2 "s_register_operand" "")]))]
1987   "TARGET_32BIT && reload_completed
1988    && ! (TARGET_NEON && IS_VFP_REGNUM (REGNO (operands[0])))
1989    && ! IS_IWMMXT_REGNUM (REGNO (operands[0]))"
1990   [(set (match_dup 0) (match_op_dup:SI 6 [(match_dup 1) (match_dup 2)]))
1991    (set (match_dup 3) (match_op_dup:SI 6 [(match_dup 4) (match_dup 5)]))]
1992   "
1993   {
1994     operands[3] = gen_highpart (SImode, operands[0]);
1995     operands[0] = gen_lowpart (SImode, operands[0]);
1996     operands[4] = gen_highpart (SImode, operands[1]);
1997     operands[1] = gen_lowpart (SImode, operands[1]);
1998     operands[5] = gen_highpart (SImode, operands[2]);
1999     operands[2] = gen_lowpart (SImode, operands[2]);
2000   }"
2001 )
2002
2003 (define_split
2004   [(set (match_operand:DI 0 "s_register_operand" "")
2005         (match_operator:DI 6 "logical_binary_operator"
2006           [(sign_extend:DI (match_operand:SI 2 "s_register_operand" ""))
2007            (match_operand:DI 1 "s_register_operand" "")]))]
2008   "TARGET_32BIT && reload_completed"
2009   [(set (match_dup 0) (match_op_dup:SI 6 [(match_dup 1) (match_dup 2)]))
2010    (set (match_dup 3) (match_op_dup:SI 6
2011                         [(ashiftrt:SI (match_dup 2) (const_int 31))
2012                          (match_dup 4)]))]
2013   "
2014   {
2015     operands[3] = gen_highpart (SImode, operands[0]);
2016     operands[0] = gen_lowpart (SImode, operands[0]);
2017     operands[4] = gen_highpart (SImode, operands[1]);
2018     operands[1] = gen_lowpart (SImode, operands[1]);
2019     operands[5] = gen_highpart (SImode, operands[2]);
2020     operands[2] = gen_lowpart (SImode, operands[2]);
2021   }"
2022 )
2023
2024 ;; The zero extend of operand 2 means we can just copy the high part of
2025 ;; operand1 into operand0.
2026 (define_split
2027   [(set (match_operand:DI 0 "s_register_operand" "")
2028         (ior:DI
2029           (zero_extend:DI (match_operand:SI 2 "s_register_operand" ""))
2030           (match_operand:DI 1 "s_register_operand" "")))]
2031   "TARGET_32BIT && operands[0] != operands[1] && reload_completed"
2032   [(set (match_dup 0) (ior:SI (match_dup 1) (match_dup 2)))
2033    (set (match_dup 3) (match_dup 4))]
2034   "
2035   {
2036     operands[4] = gen_highpart (SImode, operands[1]);
2037     operands[3] = gen_highpart (SImode, operands[0]);
2038     operands[0] = gen_lowpart (SImode, operands[0]);
2039     operands[1] = gen_lowpart (SImode, operands[1]);
2040   }"
2041 )
2042
2043 ;; The zero extend of operand 2 means we can just copy the high part of
2044 ;; operand1 into operand0.
2045 (define_split
2046   [(set (match_operand:DI 0 "s_register_operand" "")
2047         (xor:DI
2048           (zero_extend:DI (match_operand:SI 2 "s_register_operand" ""))
2049           (match_operand:DI 1 "s_register_operand" "")))]
2050   "TARGET_32BIT && operands[0] != operands[1] && reload_completed"
2051   [(set (match_dup 0) (xor:SI (match_dup 1) (match_dup 2)))
2052    (set (match_dup 3) (match_dup 4))]
2053   "
2054   {
2055     operands[4] = gen_highpart (SImode, operands[1]);
2056     operands[3] = gen_highpart (SImode, operands[0]);
2057     operands[0] = gen_lowpart (SImode, operands[0]);
2058     operands[1] = gen_lowpart (SImode, operands[1]);
2059   }"
2060 )
2061
2062 (define_expand "anddi3"
2063   [(set (match_operand:DI         0 "s_register_operand" "")
2064         (and:DI (match_operand:DI 1 "s_register_operand" "")
2065                 (match_operand:DI 2 "neon_inv_logic_op2" "")))]
2066   "TARGET_32BIT"
2067   ""
2068 )
2069
2070 (define_insn "*anddi3_insn"
2071   [(set (match_operand:DI         0 "s_register_operand" "=&r,&r")
2072         (and:DI (match_operand:DI 1 "s_register_operand"  "%0,r")
2073                 (match_operand:DI 2 "s_register_operand"   "r,r")))]
2074   "TARGET_32BIT && !TARGET_IWMMXT && !TARGET_NEON"
2075   "#"
2076   [(set_attr "length" "8")]
2077 )
2078
2079 (define_insn_and_split "*anddi_zesidi_di"
2080   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2081         (and:DI (zero_extend:DI
2082                  (match_operand:SI 2 "s_register_operand" "r,r"))
2083                 (match_operand:DI 1 "s_register_operand" "0,r")))]
2084   "TARGET_32BIT"
2085   "#"
2086   "TARGET_32BIT && reload_completed"
2087   ; The zero extend of operand 2 clears the high word of the output
2088   ; operand.
2089   [(set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))
2090    (set (match_dup 3) (const_int 0))]
2091   "
2092   {
2093     operands[3] = gen_highpart (SImode, operands[0]);
2094     operands[0] = gen_lowpart (SImode, operands[0]);
2095     operands[1] = gen_lowpart (SImode, operands[1]);
2096   }"
2097   [(set_attr "length" "8")]
2098 )
2099
2100 (define_insn "*anddi_sesdi_di"
2101   [(set (match_operand:DI          0 "s_register_operand" "=&r,&r")
2102         (and:DI (sign_extend:DI
2103                  (match_operand:SI 2 "s_register_operand" "r,r"))
2104                 (match_operand:DI  1 "s_register_operand" "0,r")))]
2105   "TARGET_32BIT"
2106   "#"
2107   [(set_attr "length" "8")]
2108 )
2109
2110 (define_expand "andsi3"
2111   [(set (match_operand:SI         0 "s_register_operand" "")
2112         (and:SI (match_operand:SI 1 "s_register_operand" "")
2113                 (match_operand:SI 2 "reg_or_int_operand" "")))]
2114   "TARGET_EITHER"
2115   "
2116   if (TARGET_32BIT)
2117     {
2118       if (GET_CODE (operands[2]) == CONST_INT)
2119         {
2120           if (INTVAL (operands[2]) == 255 && arm_arch6)
2121             {
2122               operands[1] = convert_to_mode (QImode, operands[1], 1);
2123               emit_insn (gen_thumb2_zero_extendqisi2_v6 (operands[0],
2124                                                          operands[1]));
2125             }
2126           else
2127             arm_split_constant (AND, SImode, NULL_RTX,
2128                                 INTVAL (operands[2]), operands[0],
2129                                 operands[1],
2130                                 optimize && can_create_pseudo_p ());
2131
2132           DONE;
2133         }
2134     }
2135   else /* TARGET_THUMB1 */
2136     {
2137       if (GET_CODE (operands[2]) != CONST_INT)
2138         {
2139           rtx tmp = force_reg (SImode, operands[2]);
2140           if (rtx_equal_p (operands[0], operands[1]))
2141             operands[2] = tmp;
2142           else
2143             {
2144               operands[2] = operands[1];
2145               operands[1] = tmp;
2146             }
2147         }
2148       else
2149         {
2150           int i;
2151           
2152           if (((unsigned HOST_WIDE_INT) ~INTVAL (operands[2])) < 256)
2153             {
2154               operands[2] = force_reg (SImode,
2155                                        GEN_INT (~INTVAL (operands[2])));
2156               
2157               emit_insn (gen_thumb1_bicsi3 (operands[0], operands[2], operands[1]));
2158               
2159               DONE;
2160             }
2161
2162           for (i = 9; i <= 31; i++)
2163             {
2164               if ((((HOST_WIDE_INT) 1) << i) - 1 == INTVAL (operands[2]))
2165                 {
2166                   emit_insn (gen_extzv (operands[0], operands[1], GEN_INT (i),
2167                                         const0_rtx));
2168                   DONE;
2169                 }
2170               else if ((((HOST_WIDE_INT) 1) << i) - 1
2171                        == ~INTVAL (operands[2]))
2172                 {
2173                   rtx shift = GEN_INT (i);
2174                   rtx reg = gen_reg_rtx (SImode);
2175                 
2176                   emit_insn (gen_lshrsi3 (reg, operands[1], shift));
2177                   emit_insn (gen_ashlsi3 (operands[0], reg, shift));
2178                   
2179                   DONE;
2180                 }
2181             }
2182
2183           operands[2] = force_reg (SImode, operands[2]);
2184         }
2185     }
2186   "
2187 )
2188
2189 ; ??? Check split length for Thumb-2
2190 (define_insn_and_split "*arm_andsi3_insn"
2191   [(set (match_operand:SI         0 "s_register_operand" "=r,r,r")
2192         (and:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
2193                 (match_operand:SI 2 "reg_or_int_operand" "rI,K,?n")))]
2194   "TARGET_32BIT"
2195   "@
2196    and%?\\t%0, %1, %2
2197    bic%?\\t%0, %1, #%B2
2198    #"
2199   "TARGET_32BIT
2200    && GET_CODE (operands[2]) == CONST_INT
2201    && !(const_ok_for_arm (INTVAL (operands[2]))
2202         || const_ok_for_arm (~INTVAL (operands[2])))"
2203   [(clobber (const_int 0))]
2204   "
2205   arm_split_constant  (AND, SImode, curr_insn, 
2206                        INTVAL (operands[2]), operands[0], operands[1], 0);
2207   DONE;
2208   "
2209   [(set_attr "length" "4,4,16")
2210    (set_attr "predicable" "yes")]
2211 )
2212
2213 (define_insn "*thumb1_andsi3_insn"
2214   [(set (match_operand:SI         0 "register_operand" "=l")
2215         (and:SI (match_operand:SI 1 "register_operand" "%0")
2216                 (match_operand:SI 2 "register_operand" "l")))]
2217   "TARGET_THUMB1"
2218   "and\\t%0, %2"
2219   [(set_attr "length" "2")
2220    (set_attr "conds" "set")])
2221
2222 (define_insn "*andsi3_compare0"
2223   [(set (reg:CC_NOOV CC_REGNUM)
2224         (compare:CC_NOOV
2225          (and:SI (match_operand:SI 1 "s_register_operand" "r,r")
2226                  (match_operand:SI 2 "arm_not_operand" "rI,K"))
2227          (const_int 0)))
2228    (set (match_operand:SI          0 "s_register_operand" "=r,r")
2229         (and:SI (match_dup 1) (match_dup 2)))]
2230   "TARGET_32BIT"
2231   "@
2232    and%.\\t%0, %1, %2
2233    bic%.\\t%0, %1, #%B2"
2234   [(set_attr "conds" "set")]
2235 )
2236
2237 (define_insn "*andsi3_compare0_scratch"
2238   [(set (reg:CC_NOOV CC_REGNUM)
2239         (compare:CC_NOOV
2240          (and:SI (match_operand:SI 0 "s_register_operand" "r,r")
2241                  (match_operand:SI 1 "arm_not_operand" "rI,K"))
2242          (const_int 0)))
2243    (clobber (match_scratch:SI 2 "=X,r"))]
2244   "TARGET_32BIT"
2245   "@
2246    tst%?\\t%0, %1
2247    bic%.\\t%2, %0, #%B1"
2248   [(set_attr "conds" "set")]
2249 )
2250
2251 (define_insn "*zeroextractsi_compare0_scratch"
2252   [(set (reg:CC_NOOV CC_REGNUM)
2253         (compare:CC_NOOV (zero_extract:SI
2254                           (match_operand:SI 0 "s_register_operand" "r")
2255                           (match_operand 1 "const_int_operand" "n")
2256                           (match_operand 2 "const_int_operand" "n"))
2257                          (const_int 0)))]
2258   "TARGET_32BIT
2259   && (INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) < 32
2260       && INTVAL (operands[1]) > 0 
2261       && INTVAL (operands[1]) + (INTVAL (operands[2]) & 1) <= 8
2262       && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32)"
2263   "*
2264   operands[1] = GEN_INT (((1 << INTVAL (operands[1])) - 1)
2265                          << INTVAL (operands[2]));
2266   output_asm_insn (\"tst%?\\t%0, %1\", operands);
2267   return \"\";
2268   "
2269   [(set_attr "conds" "set")
2270    (set_attr "predicable" "yes")]
2271 )
2272
2273 (define_insn_and_split "*ne_zeroextractsi"
2274   [(set (match_operand:SI 0 "s_register_operand" "=r")
2275         (ne:SI (zero_extract:SI
2276                 (match_operand:SI 1 "s_register_operand" "r")
2277                 (match_operand:SI 2 "const_int_operand" "n")
2278                 (match_operand:SI 3 "const_int_operand" "n"))
2279                (const_int 0)))
2280    (clobber (reg:CC CC_REGNUM))]
2281   "TARGET_32BIT
2282    && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2283        && INTVAL (operands[2]) > 0 
2284        && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2285        && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)"
2286   "#"
2287   "TARGET_32BIT
2288    && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2289        && INTVAL (operands[2]) > 0 
2290        && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2291        && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)"
2292   [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2293                    (compare:CC_NOOV (and:SI (match_dup 1) (match_dup 2))
2294                                     (const_int 0)))
2295               (set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))])
2296    (set (match_dup 0)
2297         (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2298                          (match_dup 0) (const_int 1)))]
2299   "
2300   operands[2] = GEN_INT (((1 << INTVAL (operands[2])) - 1)
2301                          << INTVAL (operands[3])); 
2302   "
2303   [(set_attr "conds" "clob")
2304    (set (attr "length")
2305         (if_then_else (eq_attr "is_thumb" "yes")
2306                       (const_int 12)
2307                       (const_int 8)))]
2308 )
2309
2310 (define_insn_and_split "*ne_zeroextractsi_shifted"
2311   [(set (match_operand:SI 0 "s_register_operand" "=r")
2312         (ne:SI (zero_extract:SI
2313                 (match_operand:SI 1 "s_register_operand" "r")
2314                 (match_operand:SI 2 "const_int_operand" "n")
2315                 (const_int 0))
2316                (const_int 0)))
2317    (clobber (reg:CC CC_REGNUM))]
2318   "TARGET_ARM"
2319   "#"
2320   "TARGET_ARM"
2321   [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2322                    (compare:CC_NOOV (ashift:SI (match_dup 1) (match_dup 2))
2323                                     (const_int 0)))
2324               (set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))])
2325    (set (match_dup 0)
2326         (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2327                          (match_dup 0) (const_int 1)))]
2328   "
2329   operands[2] = GEN_INT (32 - INTVAL (operands[2]));
2330   "
2331   [(set_attr "conds" "clob")
2332    (set_attr "length" "8")]
2333 )
2334
2335 (define_insn_and_split "*ite_ne_zeroextractsi"
2336   [(set (match_operand:SI 0 "s_register_operand" "=r")
2337         (if_then_else:SI (ne (zero_extract:SI
2338                               (match_operand:SI 1 "s_register_operand" "r")
2339                               (match_operand:SI 2 "const_int_operand" "n")
2340                               (match_operand:SI 3 "const_int_operand" "n"))
2341                              (const_int 0))
2342                          (match_operand:SI 4 "arm_not_operand" "rIK")
2343                          (const_int 0)))
2344    (clobber (reg:CC CC_REGNUM))]
2345   "TARGET_ARM
2346    && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2347        && INTVAL (operands[2]) > 0 
2348        && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2349        && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)
2350    && !reg_overlap_mentioned_p (operands[0], operands[4])"
2351   "#"
2352   "TARGET_ARM
2353    && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2354        && INTVAL (operands[2]) > 0 
2355        && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2356        && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)
2357    && !reg_overlap_mentioned_p (operands[0], operands[4])"
2358   [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2359                    (compare:CC_NOOV (and:SI (match_dup 1) (match_dup 2))
2360                                     (const_int 0)))
2361               (set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))])
2362    (set (match_dup 0)
2363         (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2364                          (match_dup 0) (match_dup 4)))]
2365   "
2366   operands[2] = GEN_INT (((1 << INTVAL (operands[2])) - 1)
2367                          << INTVAL (operands[3])); 
2368   "
2369   [(set_attr "conds" "clob")
2370    (set_attr "length" "8")]
2371 )
2372
2373 (define_insn_and_split "*ite_ne_zeroextractsi_shifted"
2374   [(set (match_operand:SI 0 "s_register_operand" "=r")
2375         (if_then_else:SI (ne (zero_extract:SI
2376                               (match_operand:SI 1 "s_register_operand" "r")
2377                               (match_operand:SI 2 "const_int_operand" "n")
2378                               (const_int 0))
2379                              (const_int 0))
2380                          (match_operand:SI 3 "arm_not_operand" "rIK")
2381                          (const_int 0)))
2382    (clobber (reg:CC CC_REGNUM))]
2383   "TARGET_ARM && !reg_overlap_mentioned_p (operands[0], operands[3])"
2384   "#"
2385   "TARGET_ARM && !reg_overlap_mentioned_p (operands[0], operands[3])"
2386   [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2387                    (compare:CC_NOOV (ashift:SI (match_dup 1) (match_dup 2))
2388                                     (const_int 0)))
2389               (set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))])
2390    (set (match_dup 0)
2391         (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2392                          (match_dup 0) (match_dup 3)))]
2393   "
2394   operands[2] = GEN_INT (32 - INTVAL (operands[2]));
2395   "
2396   [(set_attr "conds" "clob")
2397    (set_attr "length" "8")]
2398 )
2399
2400 (define_split
2401   [(set (match_operand:SI 0 "s_register_operand" "")
2402         (zero_extract:SI (match_operand:SI 1 "s_register_operand" "")
2403                          (match_operand:SI 2 "const_int_operand" "")
2404                          (match_operand:SI 3 "const_int_operand" "")))
2405    (clobber (match_operand:SI 4 "s_register_operand" ""))]
2406   "TARGET_THUMB1"
2407   [(set (match_dup 4) (ashift:SI (match_dup 1) (match_dup 2)))
2408    (set (match_dup 0) (lshiftrt:SI (match_dup 4) (match_dup 3)))]
2409   "{
2410      HOST_WIDE_INT temp = INTVAL (operands[2]);
2411
2412      operands[2] = GEN_INT (32 - temp - INTVAL (operands[3]));
2413      operands[3] = GEN_INT (32 - temp);
2414    }"
2415 )
2416
2417 ;; ??? Use Thumb-2 has bitfield insert/extract instructions.
2418 (define_split
2419   [(set (match_operand:SI 0 "s_register_operand" "")
2420         (match_operator:SI 1 "shiftable_operator"
2421          [(zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
2422                            (match_operand:SI 3 "const_int_operand" "")
2423                            (match_operand:SI 4 "const_int_operand" ""))
2424           (match_operand:SI 5 "s_register_operand" "")]))
2425    (clobber (match_operand:SI 6 "s_register_operand" ""))]
2426   "TARGET_ARM"
2427   [(set (match_dup 6) (ashift:SI (match_dup 2) (match_dup 3)))
2428    (set (match_dup 0)
2429         (match_op_dup 1
2430          [(lshiftrt:SI (match_dup 6) (match_dup 4))
2431           (match_dup 5)]))]
2432   "{
2433      HOST_WIDE_INT temp = INTVAL (operands[3]);
2434
2435      operands[3] = GEN_INT (32 - temp - INTVAL (operands[4]));
2436      operands[4] = GEN_INT (32 - temp);
2437    }"
2438 )
2439   
2440 (define_split
2441   [(set (match_operand:SI 0 "s_register_operand" "")
2442         (sign_extract:SI (match_operand:SI 1 "s_register_operand" "")
2443                          (match_operand:SI 2 "const_int_operand" "")
2444                          (match_operand:SI 3 "const_int_operand" "")))]
2445   "TARGET_THUMB1"
2446   [(set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))
2447    (set (match_dup 0) (ashiftrt:SI (match_dup 0) (match_dup 3)))]
2448   "{
2449      HOST_WIDE_INT temp = INTVAL (operands[2]);
2450
2451      operands[2] = GEN_INT (32 - temp - INTVAL (operands[3]));
2452      operands[3] = GEN_INT (32 - temp);
2453    }"
2454 )
2455
2456 (define_split
2457   [(set (match_operand:SI 0 "s_register_operand" "")
2458         (match_operator:SI 1 "shiftable_operator"
2459          [(sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
2460                            (match_operand:SI 3 "const_int_operand" "")
2461                            (match_operand:SI 4 "const_int_operand" ""))
2462           (match_operand:SI 5 "s_register_operand" "")]))
2463    (clobber (match_operand:SI 6 "s_register_operand" ""))]
2464   "TARGET_ARM"
2465   [(set (match_dup 6) (ashift:SI (match_dup 2) (match_dup 3)))
2466    (set (match_dup 0)
2467         (match_op_dup 1
2468          [(ashiftrt:SI (match_dup 6) (match_dup 4))
2469           (match_dup 5)]))]
2470   "{
2471      HOST_WIDE_INT temp = INTVAL (operands[3]);
2472
2473      operands[3] = GEN_INT (32 - temp - INTVAL (operands[4]));
2474      operands[4] = GEN_INT (32 - temp);
2475    }"
2476 )
2477   
2478 ;;; ??? This pattern is bogus.  If operand3 has bits outside the range
2479 ;;; represented by the bitfield, then this will produce incorrect results.
2480 ;;; Somewhere, the value needs to be truncated.  On targets like the m68k,
2481 ;;; which have a real bit-field insert instruction, the truncation happens
2482 ;;; in the bit-field insert instruction itself.  Since arm does not have a
2483 ;;; bit-field insert instruction, we would have to emit code here to truncate
2484 ;;; the value before we insert.  This loses some of the advantage of having
2485 ;;; this insv pattern, so this pattern needs to be reevalutated.
2486
2487 (define_expand "insv"
2488   [(set (zero_extract (match_operand 0 "nonimmediate_operand" "")
2489                       (match_operand 1 "general_operand" "")
2490                       (match_operand 2 "general_operand" ""))
2491         (match_operand 3 "reg_or_int_operand" ""))]
2492   "TARGET_ARM || arm_arch_thumb2"
2493   "
2494   {
2495     int start_bit = INTVAL (operands[2]);
2496     int width = INTVAL (operands[1]);
2497     HOST_WIDE_INT mask = (((HOST_WIDE_INT)1) << width) - 1;
2498     rtx target, subtarget;
2499
2500     if (arm_arch_thumb2)
2501       {
2502         if (unaligned_access && MEM_P (operands[0])
2503             && s_register_operand (operands[3], GET_MODE (operands[3]))
2504             && (width == 16 || width == 32) && (start_bit % BITS_PER_UNIT) == 0)
2505           {
2506             rtx base_addr;
2507
2508             if (BYTES_BIG_ENDIAN)
2509               start_bit = GET_MODE_BITSIZE (GET_MODE (operands[3])) - width
2510                           - start_bit;
2511
2512             if (width == 32)
2513               {
2514                 base_addr = adjust_address (operands[0], SImode,
2515                                             start_bit / BITS_PER_UNIT);
2516                 emit_insn (gen_unaligned_storesi (base_addr, operands[3]));
2517               }
2518             else
2519               {
2520                 rtx tmp = gen_reg_rtx (HImode);
2521
2522                 base_addr = adjust_address (operands[0], HImode,
2523                                             start_bit / BITS_PER_UNIT);
2524                 emit_move_insn (tmp, gen_lowpart (HImode, operands[3]));
2525                 emit_insn (gen_unaligned_storehi (base_addr, tmp));
2526               }
2527             DONE;
2528           }
2529         else if (s_register_operand (operands[0], GET_MODE (operands[0])))
2530           {
2531             bool use_bfi = TRUE;
2532
2533             if (GET_CODE (operands[3]) == CONST_INT)
2534               {
2535                 HOST_WIDE_INT val = INTVAL (operands[3]) & mask;
2536
2537                 if (val == 0)
2538                   {
2539                     emit_insn (gen_insv_zero (operands[0], operands[1],
2540                                               operands[2]));
2541                     DONE;
2542                   }
2543
2544                 /* See if the set can be done with a single orr instruction.  */
2545                 if (val == mask && const_ok_for_arm (val << start_bit))
2546                   use_bfi = FALSE;
2547               }
2548
2549             if (use_bfi)
2550               {
2551                 if (GET_CODE (operands[3]) != REG)
2552                   operands[3] = force_reg (SImode, operands[3]);
2553
2554                 emit_insn (gen_insv_t2 (operands[0], operands[1], operands[2],
2555                                         operands[3]));
2556                 DONE;
2557               }
2558           }
2559         else
2560           FAIL;
2561       }
2562
2563     if (!s_register_operand (operands[0], GET_MODE (operands[0])))
2564       FAIL;
2565
2566     target = copy_rtx (operands[0]);
2567     /* Avoid using a subreg as a subtarget, and avoid writing a paradoxical 
2568        subreg as the final target.  */
2569     if (GET_CODE (target) == SUBREG)
2570       {
2571         subtarget = gen_reg_rtx (SImode);
2572         if (GET_MODE_SIZE (GET_MODE (SUBREG_REG (target)))
2573             < GET_MODE_SIZE (SImode))
2574           target = SUBREG_REG (target);
2575       }
2576     else
2577       subtarget = target;    
2578
2579     if (GET_CODE (operands[3]) == CONST_INT)
2580       {
2581         /* Since we are inserting a known constant, we may be able to
2582            reduce the number of bits that we have to clear so that
2583            the mask becomes simple.  */
2584         /* ??? This code does not check to see if the new mask is actually
2585            simpler.  It may not be.  */
2586         rtx op1 = gen_reg_rtx (SImode);
2587         /* ??? Truncate operand3 to fit in the bitfield.  See comment before
2588            start of this pattern.  */
2589         HOST_WIDE_INT op3_value = mask & INTVAL (operands[3]);
2590         HOST_WIDE_INT mask2 = ((mask & ~op3_value) << start_bit);
2591
2592         emit_insn (gen_andsi3 (op1, operands[0],
2593                                gen_int_mode (~mask2, SImode)));
2594         emit_insn (gen_iorsi3 (subtarget, op1,
2595                                gen_int_mode (op3_value << start_bit, SImode)));
2596       }
2597     else if (start_bit == 0
2598              && !(const_ok_for_arm (mask)
2599                   || const_ok_for_arm (~mask)))
2600       {
2601         /* A Trick, since we are setting the bottom bits in the word,
2602            we can shift operand[3] up, operand[0] down, OR them together
2603            and rotate the result back again.  This takes 3 insns, and
2604            the third might be mergeable into another op.  */
2605         /* The shift up copes with the possibility that operand[3] is
2606            wider than the bitfield.  */
2607         rtx op0 = gen_reg_rtx (SImode);
2608         rtx op1 = gen_reg_rtx (SImode);
2609
2610         emit_insn (gen_ashlsi3 (op0, operands[3], GEN_INT (32 - width)));
2611         emit_insn (gen_lshrsi3 (op1, operands[0], operands[1]));
2612         emit_insn (gen_iorsi3  (op1, op1, op0));
2613         emit_insn (gen_rotlsi3 (subtarget, op1, operands[1]));
2614       }
2615     else if ((width + start_bit == 32)
2616              && !(const_ok_for_arm (mask)
2617                   || const_ok_for_arm (~mask)))
2618       {
2619         /* Similar trick, but slightly less efficient.  */
2620
2621         rtx op0 = gen_reg_rtx (SImode);
2622         rtx op1 = gen_reg_rtx (SImode);
2623
2624         emit_insn (gen_ashlsi3 (op0, operands[3], GEN_INT (32 - width)));
2625         emit_insn (gen_ashlsi3 (op1, operands[0], operands[1]));
2626         emit_insn (gen_lshrsi3 (op1, op1, operands[1]));
2627         emit_insn (gen_iorsi3 (subtarget, op1, op0));
2628       }
2629     else
2630       {
2631         rtx op0 = gen_int_mode (mask, SImode);
2632         rtx op1 = gen_reg_rtx (SImode);
2633         rtx op2 = gen_reg_rtx (SImode);
2634
2635         if (!(const_ok_for_arm (mask) || const_ok_for_arm (~mask)))
2636           {
2637             rtx tmp = gen_reg_rtx (SImode);
2638
2639             emit_insn (gen_movsi (tmp, op0));
2640             op0 = tmp;
2641           }
2642
2643         /* Mask out any bits in operand[3] that are not needed.  */
2644            emit_insn (gen_andsi3 (op1, operands[3], op0));
2645
2646         if (GET_CODE (op0) == CONST_INT
2647             && (const_ok_for_arm (mask << start_bit)
2648                 || const_ok_for_arm (~(mask << start_bit))))
2649           {
2650             op0 = gen_int_mode (~(mask << start_bit), SImode);
2651             emit_insn (gen_andsi3 (op2, operands[0], op0));
2652           }
2653         else
2654           {
2655             if (GET_CODE (op0) == CONST_INT)
2656               {
2657                 rtx tmp = gen_reg_rtx (SImode);
2658
2659                 emit_insn (gen_movsi (tmp, op0));
2660                 op0 = tmp;
2661               }
2662
2663             if (start_bit != 0)
2664               emit_insn (gen_ashlsi3 (op0, op0, operands[2]));
2665             
2666             emit_insn (gen_andsi_notsi_si (op2, operands[0], op0));
2667           }
2668
2669         if (start_bit != 0)
2670           emit_insn (gen_ashlsi3 (op1, op1, operands[2]));
2671
2672         emit_insn (gen_iorsi3 (subtarget, op1, op2));
2673       }
2674
2675     if (subtarget != target)
2676       {
2677         /* If TARGET is still a SUBREG, then it must be wider than a word,
2678            so we must be careful only to set the subword we were asked to.  */
2679         if (GET_CODE (target) == SUBREG)
2680           emit_move_insn (target, subtarget);
2681         else
2682           emit_move_insn (target, gen_lowpart (GET_MODE (target), subtarget));
2683       }
2684
2685     DONE;
2686   }"
2687 )
2688
2689 (define_insn "insv_zero"
2690   [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r")
2691                          (match_operand:SI 1 "const_int_operand" "M")
2692                          (match_operand:SI 2 "const_int_operand" "M"))
2693         (const_int 0))]
2694   "arm_arch_thumb2"
2695   "bfc%?\t%0, %2, %1"
2696   [(set_attr "length" "4")
2697    (set_attr "predicable" "yes")]
2698 )
2699
2700 (define_insn "insv_t2"
2701   [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r")
2702                          (match_operand:SI 1 "const_int_operand" "M")
2703                          (match_operand:SI 2 "const_int_operand" "M"))
2704         (match_operand:SI 3 "s_register_operand" "r"))]
2705   "arm_arch_thumb2"
2706   "bfi%?\t%0, %3, %2, %1"
2707   [(set_attr "length" "4")
2708    (set_attr "predicable" "yes")]
2709 )
2710
2711 ; constants for op 2 will never be given to these patterns.
2712 (define_insn_and_split "*anddi_notdi_di"
2713   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2714         (and:DI (not:DI (match_operand:DI 1 "s_register_operand" "0,r"))
2715                 (match_operand:DI 2 "s_register_operand" "r,0")))]
2716   "TARGET_32BIT"
2717   "#"
2718   "TARGET_32BIT && reload_completed
2719    && ! (TARGET_NEON && IS_VFP_REGNUM (REGNO (operands[0])))
2720    && ! IS_IWMMXT_REGNUM (REGNO (operands[0]))"
2721   [(set (match_dup 0) (and:SI (not:SI (match_dup 1)) (match_dup 2)))
2722    (set (match_dup 3) (and:SI (not:SI (match_dup 4)) (match_dup 5)))]
2723   "
2724   {
2725     operands[3] = gen_highpart (SImode, operands[0]);
2726     operands[0] = gen_lowpart (SImode, operands[0]);
2727     operands[4] = gen_highpart (SImode, operands[1]);
2728     operands[1] = gen_lowpart (SImode, operands[1]);
2729     operands[5] = gen_highpart (SImode, operands[2]);
2730     operands[2] = gen_lowpart (SImode, operands[2]);
2731   }"
2732   [(set_attr "length" "8")
2733    (set_attr "predicable" "yes")]
2734 )
2735   
2736 (define_insn_and_split "*anddi_notzesidi_di"
2737   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2738         (and:DI (not:DI (zero_extend:DI
2739                          (match_operand:SI 2 "s_register_operand" "r,r")))
2740                 (match_operand:DI 1 "s_register_operand" "0,?r")))]
2741   "TARGET_32BIT"
2742   "@
2743    bic%?\\t%Q0, %Q1, %2
2744    #"
2745   ; (not (zero_extend ...)) allows us to just copy the high word from
2746   ; operand1 to operand0.
2747   "TARGET_32BIT
2748    && reload_completed
2749    && operands[0] != operands[1]"
2750   [(set (match_dup 0) (and:SI (not:SI (match_dup 2)) (match_dup 1)))
2751    (set (match_dup 3) (match_dup 4))]
2752   "
2753   {
2754     operands[3] = gen_highpart (SImode, operands[0]);
2755     operands[0] = gen_lowpart (SImode, operands[0]);
2756     operands[4] = gen_highpart (SImode, operands[1]);
2757     operands[1] = gen_lowpart (SImode, operands[1]);
2758   }"
2759   [(set_attr "length" "4,8")
2760    (set_attr "predicable" "yes")]
2761 )
2762   
2763 (define_insn_and_split "*anddi_notsesidi_di"
2764   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2765         (and:DI (not:DI (sign_extend:DI
2766                          (match_operand:SI 2 "s_register_operand" "r,r")))
2767                 (match_operand:DI 1 "s_register_operand" "0,r")))]
2768   "TARGET_32BIT"
2769   "#"
2770   "TARGET_32BIT && reload_completed"
2771   [(set (match_dup 0) (and:SI (not:SI (match_dup 2)) (match_dup 1)))
2772    (set (match_dup 3) (and:SI (not:SI
2773                                 (ashiftrt:SI (match_dup 2) (const_int 31)))
2774                                (match_dup 4)))]
2775   "
2776   {
2777     operands[3] = gen_highpart (SImode, operands[0]);
2778     operands[0] = gen_lowpart (SImode, operands[0]);
2779     operands[4] = gen_highpart (SImode, operands[1]);
2780     operands[1] = gen_lowpart (SImode, operands[1]);
2781   }"
2782   [(set_attr "length" "8")
2783    (set_attr "predicable" "yes")]
2784 )
2785   
2786 (define_insn "andsi_notsi_si"
2787   [(set (match_operand:SI 0 "s_register_operand" "=r")
2788         (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
2789                 (match_operand:SI 1 "s_register_operand" "r")))]
2790   "TARGET_32BIT"
2791   "bic%?\\t%0, %1, %2"
2792   [(set_attr "predicable" "yes")]
2793 )
2794
2795 (define_insn "thumb1_bicsi3"
2796   [(set (match_operand:SI                 0 "register_operand" "=l")
2797         (and:SI (not:SI (match_operand:SI 1 "register_operand" "l"))
2798                 (match_operand:SI         2 "register_operand" "0")))]
2799   "TARGET_THUMB1"
2800   "bic\\t%0, %1"
2801   [(set_attr "length" "2")
2802    (set_attr "conds" "set")])
2803
2804 (define_insn "andsi_not_shiftsi_si"
2805   [(set (match_operand:SI 0 "s_register_operand" "=r")
2806         (and:SI (not:SI (match_operator:SI 4 "shift_operator"
2807                          [(match_operand:SI 2 "s_register_operand" "r")
2808                           (match_operand:SI 3 "arm_rhs_operand" "rM")]))
2809                 (match_operand:SI 1 "s_register_operand" "r")))]
2810   "TARGET_ARM"
2811   "bic%?\\t%0, %1, %2%S4"
2812   [(set_attr "predicable" "yes")
2813    (set_attr "shift" "2")
2814    (set (attr "type") (if_then_else (match_operand 3 "const_int_operand" "")
2815                       (const_string "alu_shift")
2816                       (const_string "alu_shift_reg")))]
2817 )
2818
2819 (define_insn "*andsi_notsi_si_compare0"
2820   [(set (reg:CC_NOOV CC_REGNUM)
2821         (compare:CC_NOOV
2822          (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
2823                  (match_operand:SI 1 "s_register_operand" "r"))
2824          (const_int 0)))
2825    (set (match_operand:SI 0 "s_register_operand" "=r")
2826         (and:SI (not:SI (match_dup 2)) (match_dup 1)))]
2827   "TARGET_32BIT"
2828   "bic%.\\t%0, %1, %2"
2829   [(set_attr "conds" "set")]
2830 )
2831
2832 (define_insn "*andsi_notsi_si_compare0_scratch"
2833   [(set (reg:CC_NOOV CC_REGNUM)
2834         (compare:CC_NOOV
2835          (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
2836                  (match_operand:SI 1 "s_register_operand" "r"))
2837          (const_int 0)))
2838    (clobber (match_scratch:SI 0 "=r"))]
2839   "TARGET_32BIT"
2840   "bic%.\\t%0, %1, %2"
2841   [(set_attr "conds" "set")]
2842 )
2843
2844 (define_expand "iordi3"
2845   [(set (match_operand:DI         0 "s_register_operand" "")
2846         (ior:DI (match_operand:DI 1 "s_register_operand" "")
2847                 (match_operand:DI 2 "neon_logic_op2" "")))]
2848   "TARGET_32BIT"
2849   ""
2850 )
2851
2852 (define_insn "*iordi3_insn"
2853   [(set (match_operand:DI         0 "s_register_operand" "=&r,&r")
2854         (ior:DI (match_operand:DI 1 "s_register_operand"  "%0,r")
2855                 (match_operand:DI 2 "s_register_operand"   "r,r")))]
2856   "TARGET_32BIT && !TARGET_IWMMXT && !TARGET_NEON"
2857   "#"
2858   [(set_attr "length" "8")
2859    (set_attr "predicable" "yes")]
2860 )
2861
2862 (define_insn "*iordi_zesidi_di"
2863   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2864         (ior:DI (zero_extend:DI
2865                  (match_operand:SI 2 "s_register_operand" "r,r"))
2866                 (match_operand:DI 1 "s_register_operand" "0,?r")))]
2867   "TARGET_32BIT"
2868   "@
2869    orr%?\\t%Q0, %Q1, %2
2870    #"
2871   [(set_attr "length" "4,8")
2872    (set_attr "predicable" "yes")]
2873 )
2874
2875 (define_insn "*iordi_sesidi_di"
2876   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2877         (ior:DI (sign_extend:DI
2878                  (match_operand:SI 2 "s_register_operand" "r,r"))
2879                 (match_operand:DI 1 "s_register_operand" "0,r")))]
2880   "TARGET_32BIT"
2881   "#"
2882   [(set_attr "length" "8")
2883    (set_attr "predicable" "yes")]
2884 )
2885
2886 (define_expand "iorsi3"
2887   [(set (match_operand:SI         0 "s_register_operand" "")
2888         (ior:SI (match_operand:SI 1 "s_register_operand" "")
2889                 (match_operand:SI 2 "reg_or_int_operand" "")))]
2890   "TARGET_EITHER"
2891   "
2892   if (GET_CODE (operands[2]) == CONST_INT)
2893     {
2894       if (TARGET_32BIT)
2895         {
2896           arm_split_constant (IOR, SImode, NULL_RTX,
2897                               INTVAL (operands[2]), operands[0], operands[1],
2898                               optimize && can_create_pseudo_p ());
2899           DONE;
2900         }
2901       else /* TARGET_THUMB1 */
2902         {
2903           rtx tmp = force_reg (SImode, operands[2]);
2904           if (rtx_equal_p (operands[0], operands[1]))
2905             operands[2] = tmp;
2906           else
2907             {
2908               operands[2] = operands[1];
2909               operands[1] = tmp;
2910             }
2911         }
2912     }
2913   "
2914 )
2915
2916 (define_insn_and_split "*iorsi3_insn"
2917   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
2918         (ior:SI (match_operand:SI 1 "s_register_operand" "%r,r,r")
2919                 (match_operand:SI 2 "reg_or_int_operand" "rI,K,?n")))]
2920   "TARGET_32BIT"
2921   "@
2922    orr%?\\t%0, %1, %2
2923    orn%?\\t%0, %1, #%B2
2924    #"
2925   "TARGET_32BIT
2926    && GET_CODE (operands[2]) == CONST_INT
2927    && !(const_ok_for_arm (INTVAL (operands[2]))
2928         || (TARGET_THUMB2 && const_ok_for_arm (~INTVAL (operands[2]))))"
2929   [(clobber (const_int 0))]
2930 {
2931   arm_split_constant (IOR, SImode, curr_insn, 
2932                       INTVAL (operands[2]), operands[0], operands[1], 0);
2933   DONE;
2934 }
2935   [(set_attr "length" "4,4,16")
2936    (set_attr "arch" "32,t2,32")
2937    (set_attr "predicable" "yes")])
2938
2939 (define_insn "*thumb1_iorsi3_insn"
2940   [(set (match_operand:SI         0 "register_operand" "=l")
2941         (ior:SI (match_operand:SI 1 "register_operand" "%0")
2942                 (match_operand:SI 2 "register_operand" "l")))]
2943   "TARGET_THUMB1"
2944   "orr\\t%0, %2"
2945   [(set_attr "length" "2")
2946    (set_attr "conds" "set")])
2947
2948 (define_peephole2
2949   [(match_scratch:SI 3 "r")
2950    (set (match_operand:SI 0 "arm_general_register_operand" "")
2951         (ior:SI (match_operand:SI 1 "arm_general_register_operand" "")
2952                 (match_operand:SI 2 "const_int_operand" "")))]
2953   "TARGET_ARM
2954    && !const_ok_for_arm (INTVAL (operands[2]))
2955    && const_ok_for_arm (~INTVAL (operands[2]))"
2956   [(set (match_dup 3) (match_dup 2))
2957    (set (match_dup 0) (ior:SI (match_dup 1) (match_dup 3)))]
2958   ""
2959 )
2960
2961 (define_insn "*iorsi3_compare0"
2962   [(set (reg:CC_NOOV CC_REGNUM)
2963         (compare:CC_NOOV (ior:SI (match_operand:SI 1 "s_register_operand" "%r")
2964                                  (match_operand:SI 2 "arm_rhs_operand" "rI"))
2965                          (const_int 0)))
2966    (set (match_operand:SI 0 "s_register_operand" "=r")
2967         (ior:SI (match_dup 1) (match_dup 2)))]
2968   "TARGET_32BIT"
2969   "orr%.\\t%0, %1, %2"
2970   [(set_attr "conds" "set")]
2971 )
2972
2973 (define_insn "*iorsi3_compare0_scratch"
2974   [(set (reg:CC_NOOV CC_REGNUM)
2975         (compare:CC_NOOV (ior:SI (match_operand:SI 1 "s_register_operand" "%r")
2976                                  (match_operand:SI 2 "arm_rhs_operand" "rI"))
2977                          (const_int 0)))
2978    (clobber (match_scratch:SI 0 "=r"))]
2979   "TARGET_32BIT"
2980   "orr%.\\t%0, %1, %2"
2981   [(set_attr "conds" "set")]
2982 )
2983
2984 (define_expand "xordi3"
2985   [(set (match_operand:DI         0 "s_register_operand" "")
2986         (xor:DI (match_operand:DI 1 "s_register_operand" "")
2987                 (match_operand:DI 2 "s_register_operand" "")))]
2988   "TARGET_32BIT"
2989   ""
2990 )
2991
2992 (define_insn "*xordi3_insn"
2993   [(set (match_operand:DI         0 "s_register_operand" "=&r,&r")
2994         (xor:DI (match_operand:DI 1 "s_register_operand"  "%0,r")
2995                 (match_operand:DI 2 "s_register_operand"   "r,r")))]
2996   "TARGET_32BIT && !TARGET_IWMMXT && !TARGET_NEON"
2997   "#"
2998   [(set_attr "length" "8")
2999    (set_attr "predicable" "yes")]
3000 )
3001
3002 (define_insn "*xordi_zesidi_di"
3003   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
3004         (xor:DI (zero_extend:DI
3005                  (match_operand:SI 2 "s_register_operand" "r,r"))
3006                 (match_operand:DI 1 "s_register_operand" "0,?r")))]
3007   "TARGET_32BIT"
3008   "@
3009    eor%?\\t%Q0, %Q1, %2
3010    #"
3011   [(set_attr "length" "4,8")
3012    (set_attr "predicable" "yes")]
3013 )
3014
3015 (define_insn "*xordi_sesidi_di"
3016   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
3017         (xor:DI (sign_extend:DI
3018                  (match_operand:SI 2 "s_register_operand" "r,r"))
3019                 (match_operand:DI 1 "s_register_operand" "0,r")))]
3020   "TARGET_32BIT"
3021   "#"
3022   [(set_attr "length" "8")
3023    (set_attr "predicable" "yes")]
3024 )
3025
3026 (define_expand "xorsi3"
3027   [(set (match_operand:SI         0 "s_register_operand" "")
3028         (xor:SI (match_operand:SI 1 "s_register_operand" "")
3029                 (match_operand:SI 2 "reg_or_int_operand" "")))]
3030   "TARGET_EITHER"
3031   "if (GET_CODE (operands[2]) == CONST_INT)
3032     {
3033       if (TARGET_32BIT)
3034         {
3035           arm_split_constant (XOR, SImode, NULL_RTX,
3036                               INTVAL (operands[2]), operands[0], operands[1],
3037                               optimize && can_create_pseudo_p ());
3038           DONE;
3039         }
3040       else /* TARGET_THUMB1 */
3041         {
3042           rtx tmp = force_reg (SImode, operands[2]);
3043           if (rtx_equal_p (operands[0], operands[1]))
3044             operands[2] = tmp;
3045           else
3046             {
3047               operands[2] = operands[1];
3048               operands[1] = tmp;
3049             }
3050         }
3051     }"
3052 )
3053
3054 (define_insn_and_split "*arm_xorsi3"
3055   [(set (match_operand:SI         0 "s_register_operand" "=r,r")
3056         (xor:SI (match_operand:SI 1 "s_register_operand" "%r,r")
3057                 (match_operand:SI 2 "reg_or_int_operand" "rI,?n")))]
3058   "TARGET_32BIT"
3059   "@
3060    eor%?\\t%0, %1, %2
3061    #"
3062   "TARGET_32BIT
3063    && GET_CODE (operands[2]) == CONST_INT
3064    && !const_ok_for_arm (INTVAL (operands[2]))"
3065   [(clobber (const_int 0))]
3066 {
3067   arm_split_constant (XOR, SImode, curr_insn,
3068                       INTVAL (operands[2]), operands[0], operands[1], 0);
3069   DONE;
3070 }
3071   [(set_attr "length" "4,16")
3072    (set_attr "predicable" "yes")]
3073 )
3074
3075 (define_insn "*thumb1_xorsi3_insn"
3076   [(set (match_operand:SI         0 "register_operand" "=l")
3077         (xor:SI (match_operand:SI 1 "register_operand" "%0")
3078                 (match_operand:SI 2 "register_operand" "l")))]
3079   "TARGET_THUMB1"
3080   "eor\\t%0, %2"
3081   [(set_attr "length" "2")
3082    (set_attr "conds" "set")])
3083
3084 (define_insn "*xorsi3_compare0"
3085   [(set (reg:CC_NOOV CC_REGNUM)
3086         (compare:CC_NOOV (xor:SI (match_operand:SI 1 "s_register_operand" "r")
3087                                  (match_operand:SI 2 "arm_rhs_operand" "rI"))
3088                          (const_int 0)))
3089    (set (match_operand:SI 0 "s_register_operand" "=r")
3090         (xor:SI (match_dup 1) (match_dup 2)))]
3091   "TARGET_32BIT"
3092   "eor%.\\t%0, %1, %2"
3093   [(set_attr "conds" "set")]
3094 )
3095
3096 (define_insn "*xorsi3_compare0_scratch"
3097   [(set (reg:CC_NOOV CC_REGNUM)
3098         (compare:CC_NOOV (xor:SI (match_operand:SI 0 "s_register_operand" "r")
3099                                  (match_operand:SI 1 "arm_rhs_operand" "rI"))
3100                          (const_int 0)))]
3101   "TARGET_32BIT"
3102   "teq%?\\t%0, %1"
3103   [(set_attr "conds" "set")]
3104 )
3105
3106 ; By splitting (IOR (AND (NOT A) (NOT B)) C) as D = AND (IOR A B) (NOT C), 
3107 ; (NOT D) we can sometimes merge the final NOT into one of the following
3108 ; insns.
3109
3110 (define_split
3111   [(set (match_operand:SI 0 "s_register_operand" "")
3112         (ior:SI (and:SI (not:SI (match_operand:SI 1 "s_register_operand" ""))
3113                         (not:SI (match_operand:SI 2 "arm_rhs_operand" "")))
3114                 (match_operand:SI 3 "arm_rhs_operand" "")))
3115    (clobber (match_operand:SI 4 "s_register_operand" ""))]
3116   "TARGET_32BIT"
3117   [(set (match_dup 4) (and:SI (ior:SI (match_dup 1) (match_dup 2))
3118                               (not:SI (match_dup 3))))
3119    (set (match_dup 0) (not:SI (match_dup 4)))]
3120   ""
3121 )
3122
3123 (define_insn "*andsi_iorsi3_notsi"
3124   [(set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r")
3125         (and:SI (ior:SI (match_operand:SI 1 "s_register_operand" "%0,r,r")
3126                         (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI"))
3127                 (not:SI (match_operand:SI 3 "arm_rhs_operand" "rI,rI,rI"))))]
3128   "TARGET_32BIT"
3129   "orr%?\\t%0, %1, %2\;bic%?\\t%0, %0, %3"
3130   [(set_attr "length" "8")
3131    (set_attr "ce_count" "2")
3132    (set_attr "predicable" "yes")]
3133 )
3134
3135 ; ??? Are these four splitters still beneficial when the Thumb-2 bitfield
3136 ; insns are available?
3137 (define_split
3138   [(set (match_operand:SI 0 "s_register_operand" "")
3139         (match_operator:SI 1 "logical_binary_operator"
3140          [(zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
3141                            (match_operand:SI 3 "const_int_operand" "")
3142                            (match_operand:SI 4 "const_int_operand" ""))
3143           (match_operator:SI 9 "logical_binary_operator"
3144            [(lshiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3145                          (match_operand:SI 6 "const_int_operand" ""))
3146             (match_operand:SI 7 "s_register_operand" "")])]))
3147    (clobber (match_operand:SI 8 "s_register_operand" ""))]
3148   "TARGET_32BIT
3149    && GET_CODE (operands[1]) == GET_CODE (operands[9])
3150    && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3151   [(set (match_dup 8)
3152         (match_op_dup 1
3153          [(ashift:SI (match_dup 2) (match_dup 4))
3154           (match_dup 5)]))
3155    (set (match_dup 0)
3156         (match_op_dup 1
3157          [(lshiftrt:SI (match_dup 8) (match_dup 6))
3158           (match_dup 7)]))]
3159   "
3160   operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3161 ")
3162
3163 (define_split
3164   [(set (match_operand:SI 0 "s_register_operand" "")
3165         (match_operator:SI 1 "logical_binary_operator"
3166          [(match_operator:SI 9 "logical_binary_operator"
3167            [(lshiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3168                          (match_operand:SI 6 "const_int_operand" ""))
3169             (match_operand:SI 7 "s_register_operand" "")])
3170           (zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
3171                            (match_operand:SI 3 "const_int_operand" "")
3172                            (match_operand:SI 4 "const_int_operand" ""))]))
3173    (clobber (match_operand:SI 8 "s_register_operand" ""))]
3174   "TARGET_32BIT
3175    && GET_CODE (operands[1]) == GET_CODE (operands[9])
3176    && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3177   [(set (match_dup 8)
3178         (match_op_dup 1
3179          [(ashift:SI (match_dup 2) (match_dup 4))
3180           (match_dup 5)]))
3181    (set (match_dup 0)
3182         (match_op_dup 1
3183          [(lshiftrt:SI (match_dup 8) (match_dup 6))
3184           (match_dup 7)]))]
3185   "
3186   operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3187 ")
3188
3189 (define_split
3190   [(set (match_operand:SI 0 "s_register_operand" "")
3191         (match_operator:SI 1 "logical_binary_operator"
3192          [(sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
3193                            (match_operand:SI 3 "const_int_operand" "")
3194                            (match_operand:SI 4 "const_int_operand" ""))
3195           (match_operator:SI 9 "logical_binary_operator"
3196            [(ashiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3197                          (match_operand:SI 6 "const_int_operand" ""))
3198             (match_operand:SI 7 "s_register_operand" "")])]))
3199    (clobber (match_operand:SI 8 "s_register_operand" ""))]
3200   "TARGET_32BIT
3201    && GET_CODE (operands[1]) == GET_CODE (operands[9])
3202    && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3203   [(set (match_dup 8)
3204         (match_op_dup 1
3205          [(ashift:SI (match_dup 2) (match_dup 4))
3206           (match_dup 5)]))
3207    (set (match_dup 0)
3208         (match_op_dup 1
3209          [(ashiftrt:SI (match_dup 8) (match_dup 6))
3210           (match_dup 7)]))]
3211   "
3212   operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3213 ")
3214
3215 (define_split
3216   [(set (match_operand:SI 0 "s_register_operand" "")
3217         (match_operator:SI 1 "logical_binary_operator"
3218          [(match_operator:SI 9 "logical_binary_operator"
3219            [(ashiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3220                          (match_operand:SI 6 "const_int_operand" ""))
3221             (match_operand:SI 7 "s_register_operand" "")])
3222           (sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
3223                            (match_operand:SI 3 "const_int_operand" "")
3224                            (match_operand:SI 4 "const_int_operand" ""))]))
3225    (clobber (match_operand:SI 8 "s_register_operand" ""))]
3226   "TARGET_32BIT
3227    && GET_CODE (operands[1]) == GET_CODE (operands[9])
3228    && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3229   [(set (match_dup 8)
3230         (match_op_dup 1
3231          [(ashift:SI (match_dup 2) (match_dup 4))
3232           (match_dup 5)]))
3233    (set (match_dup 0)
3234         (match_op_dup 1
3235          [(ashiftrt:SI (match_dup 8) (match_dup 6))
3236           (match_dup 7)]))]
3237   "
3238   operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3239 ")
3240 \f
3241
3242 ;; Minimum and maximum insns
3243
3244 (define_expand "smaxsi3"
3245   [(parallel [
3246     (set (match_operand:SI 0 "s_register_operand" "")
3247          (smax:SI (match_operand:SI 1 "s_register_operand" "")
3248                   (match_operand:SI 2 "arm_rhs_operand" "")))
3249     (clobber (reg:CC CC_REGNUM))])]
3250   "TARGET_32BIT"
3251   "
3252   if (operands[2] == const0_rtx || operands[2] == constm1_rtx)
3253     {
3254       /* No need for a clobber of the condition code register here.  */
3255       emit_insn (gen_rtx_SET (VOIDmode, operands[0],
3256                               gen_rtx_SMAX (SImode, operands[1],
3257                                             operands[2])));
3258       DONE;
3259     }
3260 ")
3261
3262 (define_insn "*smax_0"
3263   [(set (match_operand:SI 0 "s_register_operand" "=r")
3264         (smax:SI (match_operand:SI 1 "s_register_operand" "r")
3265                  (const_int 0)))]
3266   "TARGET_32BIT"
3267   "bic%?\\t%0, %1, %1, asr #31"
3268   [(set_attr "predicable" "yes")]
3269 )
3270
3271 (define_insn "*smax_m1"
3272   [(set (match_operand:SI 0 "s_register_operand" "=r")
3273         (smax:SI (match_operand:SI 1 "s_register_operand" "r")
3274                  (const_int -1)))]
3275   "TARGET_32BIT"
3276   "orr%?\\t%0, %1, %1, asr #31"
3277   [(set_attr "predicable" "yes")]
3278 )
3279
3280 (define_insn "*arm_smax_insn"
3281   [(set (match_operand:SI          0 "s_register_operand" "=r,r")
3282         (smax:SI (match_operand:SI 1 "s_register_operand"  "%0,?r")
3283                  (match_operand:SI 2 "arm_rhs_operand"    "rI,rI")))
3284    (clobber (reg:CC CC_REGNUM))]
3285   "TARGET_ARM"
3286   "@
3287    cmp\\t%1, %2\;movlt\\t%0, %2
3288    cmp\\t%1, %2\;movge\\t%0, %1\;movlt\\t%0, %2"
3289   [(set_attr "conds" "clob")
3290    (set_attr "length" "8,12")]
3291 )
3292
3293 (define_expand "sminsi3"
3294   [(parallel [
3295     (set (match_operand:SI 0 "s_register_operand" "")
3296          (smin:SI (match_operand:SI 1 "s_register_operand" "")
3297                   (match_operand:SI 2 "arm_rhs_operand" "")))
3298     (clobber (reg:CC CC_REGNUM))])]
3299   "TARGET_32BIT"
3300   "
3301   if (operands[2] == const0_rtx)
3302     {
3303       /* No need for a clobber of the condition code register here.  */
3304       emit_insn (gen_rtx_SET (VOIDmode, operands[0],
3305                               gen_rtx_SMIN (SImode, operands[1],
3306                                             operands[2])));
3307       DONE;
3308     }
3309 ")
3310
3311 (define_insn "*smin_0"
3312   [(set (match_operand:SI 0 "s_register_operand" "=r")
3313         (smin:SI (match_operand:SI 1 "s_register_operand" "r")
3314                  (const_int 0)))]
3315   "TARGET_32BIT"
3316   "and%?\\t%0, %1, %1, asr #31"
3317   [(set_attr "predicable" "yes")]
3318 )
3319
3320 (define_insn "*arm_smin_insn"
3321   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3322         (smin:SI (match_operand:SI 1 "s_register_operand" "%0,?r")
3323                  (match_operand:SI 2 "arm_rhs_operand" "rI,rI")))
3324    (clobber (reg:CC CC_REGNUM))]
3325   "TARGET_ARM"
3326   "@
3327    cmp\\t%1, %2\;movge\\t%0, %2
3328    cmp\\t%1, %2\;movlt\\t%0, %1\;movge\\t%0, %2"
3329   [(set_attr "conds" "clob")
3330    (set_attr "length" "8,12")]
3331 )
3332
3333 (define_expand "umaxsi3"
3334   [(parallel [
3335     (set (match_operand:SI 0 "s_register_operand" "")
3336          (umax:SI (match_operand:SI 1 "s_register_operand" "")
3337                   (match_operand:SI 2 "arm_rhs_operand" "")))
3338     (clobber (reg:CC CC_REGNUM))])]
3339   "TARGET_32BIT"
3340   ""
3341 )
3342
3343 (define_insn "*arm_umaxsi3"
3344   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
3345         (umax:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
3346                  (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
3347    (clobber (reg:CC CC_REGNUM))]
3348   "TARGET_ARM"
3349   "@
3350    cmp\\t%1, %2\;movcc\\t%0, %2
3351    cmp\\t%1, %2\;movcs\\t%0, %1
3352    cmp\\t%1, %2\;movcs\\t%0, %1\;movcc\\t%0, %2"
3353   [(set_attr "conds" "clob")
3354    (set_attr "length" "8,8,12")]
3355 )
3356
3357 (define_expand "uminsi3"
3358   [(parallel [
3359     (set (match_operand:SI 0 "s_register_operand" "")
3360          (umin:SI (match_operand:SI 1 "s_register_operand" "")
3361                   (match_operand:SI 2 "arm_rhs_operand" "")))
3362     (clobber (reg:CC CC_REGNUM))])]
3363   "TARGET_32BIT"
3364   ""
3365 )
3366
3367 (define_insn "*arm_uminsi3"
3368   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
3369         (umin:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
3370                  (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
3371    (clobber (reg:CC CC_REGNUM))]
3372   "TARGET_ARM"
3373   "@
3374    cmp\\t%1, %2\;movcs\\t%0, %2
3375    cmp\\t%1, %2\;movcc\\t%0, %1
3376    cmp\\t%1, %2\;movcc\\t%0, %1\;movcs\\t%0, %2"
3377   [(set_attr "conds" "clob")
3378    (set_attr "length" "8,8,12")]
3379 )
3380
3381 (define_insn "*store_minmaxsi"
3382   [(set (match_operand:SI 0 "memory_operand" "=m")
3383         (match_operator:SI 3 "minmax_operator"
3384          [(match_operand:SI 1 "s_register_operand" "r")
3385           (match_operand:SI 2 "s_register_operand" "r")]))
3386    (clobber (reg:CC CC_REGNUM))]
3387   "TARGET_32BIT"
3388   "*
3389   operands[3] = gen_rtx_fmt_ee (minmax_code (operands[3]), SImode,
3390                                 operands[1], operands[2]);
3391   output_asm_insn (\"cmp\\t%1, %2\", operands);
3392   if (TARGET_THUMB2)
3393     output_asm_insn (\"ite\t%d3\", operands);
3394   output_asm_insn (\"str%d3\\t%1, %0\", operands);
3395   output_asm_insn (\"str%D3\\t%2, %0\", operands);
3396   return \"\";
3397   "
3398   [(set_attr "conds" "clob")
3399    (set (attr "length")
3400         (if_then_else (eq_attr "is_thumb" "yes")
3401                       (const_int 14)
3402                       (const_int 12)))
3403    (set_attr "type" "store1")]
3404 )
3405
3406 ; Reject the frame pointer in operand[1], since reloading this after
3407 ; it has been eliminated can cause carnage.
3408 (define_insn "*minmax_arithsi"
3409   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3410         (match_operator:SI 4 "shiftable_operator"
3411          [(match_operator:SI 5 "minmax_operator"
3412            [(match_operand:SI 2 "s_register_operand" "r,r")
3413             (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
3414           (match_operand:SI 1 "s_register_operand" "0,?r")]))
3415    (clobber (reg:CC CC_REGNUM))]
3416   "TARGET_32BIT && !arm_eliminable_register (operands[1])"
3417   "*
3418   {
3419     enum rtx_code code = GET_CODE (operands[4]);
3420     bool need_else;
3421
3422     if (which_alternative != 0 || operands[3] != const0_rtx
3423         || (code != PLUS && code != IOR && code != XOR))
3424       need_else = true;
3425     else
3426       need_else = false;
3427
3428     operands[5] = gen_rtx_fmt_ee (minmax_code (operands[5]), SImode,
3429                                   operands[2], operands[3]);
3430     output_asm_insn (\"cmp\\t%2, %3\", operands);
3431     if (TARGET_THUMB2)
3432       {
3433         if (need_else)
3434           output_asm_insn (\"ite\\t%d5\", operands);
3435         else
3436           output_asm_insn (\"it\\t%d5\", operands);
3437       }
3438     output_asm_insn (\"%i4%d5\\t%0, %1, %2\", operands);
3439     if (need_else)
3440       output_asm_insn (\"%i4%D5\\t%0, %1, %3\", operands);
3441     return \"\";
3442   }"
3443   [(set_attr "conds" "clob")
3444    (set (attr "length")
3445         (if_then_else (eq_attr "is_thumb" "yes")
3446                       (const_int 14)
3447                       (const_int 12)))]
3448 )
3449
3450 \f
3451 ;; Shift and rotation insns
3452
3453 (define_expand "ashldi3"
3454   [(set (match_operand:DI            0 "s_register_operand" "")
3455         (ashift:DI (match_operand:DI 1 "s_register_operand" "")
3456                    (match_operand:SI 2 "reg_or_int_operand" "")))]
3457   "TARGET_32BIT"
3458   "
3459   if (GET_CODE (operands[2]) == CONST_INT)
3460     {
3461       if ((HOST_WIDE_INT) INTVAL (operands[2]) == 1)
3462         {
3463           emit_insn (gen_arm_ashldi3_1bit (operands[0], operands[1]));
3464           DONE;
3465         }
3466         /* Ideally we shouldn't fail here if we could know that operands[1] 
3467            ends up already living in an iwmmxt register. Otherwise it's
3468            cheaper to have the alternate code being generated than moving
3469            values to iwmmxt regs and back.  */
3470         FAIL;
3471     }
3472   else if (!TARGET_REALLY_IWMMXT && !(TARGET_HARD_FLOAT && TARGET_MAVERICK))
3473     FAIL;
3474   "
3475 )
3476
3477 (define_insn "arm_ashldi3_1bit"
3478   [(set (match_operand:DI            0 "s_register_operand" "=r,&r")
3479         (ashift:DI (match_operand:DI 1 "s_register_operand" "0,r")
3480                    (const_int 1)))
3481    (clobber (reg:CC CC_REGNUM))]
3482   "TARGET_32BIT"
3483   "movs\\t%Q0, %Q1, asl #1\;adc\\t%R0, %R1, %R1"
3484   [(set_attr "conds" "clob")
3485    (set_attr "length" "8")]
3486 )
3487
3488 (define_expand "ashlsi3"
3489   [(set (match_operand:SI            0 "s_register_operand" "")
3490         (ashift:SI (match_operand:SI 1 "s_register_operand" "")
3491                    (match_operand:SI 2 "arm_rhs_operand" "")))]
3492   "TARGET_EITHER"
3493   "
3494   if (GET_CODE (operands[2]) == CONST_INT
3495       && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) > 31)
3496     {
3497       emit_insn (gen_movsi (operands[0], const0_rtx));
3498       DONE;
3499     }
3500   "
3501 )
3502
3503 (define_insn "*thumb1_ashlsi3"
3504   [(set (match_operand:SI            0 "register_operand" "=l,l")
3505         (ashift:SI (match_operand:SI 1 "register_operand" "l,0")
3506                    (match_operand:SI 2 "nonmemory_operand" "N,l")))]
3507   "TARGET_THUMB1"
3508   "lsl\\t%0, %1, %2"
3509   [(set_attr "length" "2")
3510    (set_attr "conds" "set")])
3511
3512 (define_expand "ashrdi3"
3513   [(set (match_operand:DI              0 "s_register_operand" "")
3514         (ashiftrt:DI (match_operand:DI 1 "s_register_operand" "")
3515                      (match_operand:SI 2 "reg_or_int_operand" "")))]
3516   "TARGET_32BIT"
3517   "
3518   if (GET_CODE (operands[2]) == CONST_INT)
3519     {
3520       if ((HOST_WIDE_INT) INTVAL (operands[2]) == 1)
3521         {
3522           emit_insn (gen_arm_ashrdi3_1bit (operands[0], operands[1]));
3523           DONE;
3524         }
3525         /* Ideally we shouldn't fail here if we could know that operands[1] 
3526            ends up already living in an iwmmxt register. Otherwise it's
3527            cheaper to have the alternate code being generated than moving
3528            values to iwmmxt regs and back.  */
3529         FAIL;
3530     }
3531   else if (!TARGET_REALLY_IWMMXT)
3532     FAIL;
3533   "
3534 )
3535
3536 (define_insn "arm_ashrdi3_1bit"
3537   [(set (match_operand:DI              0 "s_register_operand" "=r,&r")
3538         (ashiftrt:DI (match_operand:DI 1 "s_register_operand" "0,r")
3539                      (const_int 1)))
3540    (clobber (reg:CC CC_REGNUM))]
3541   "TARGET_32BIT"
3542   "movs\\t%R0, %R1, asr #1\;mov\\t%Q0, %Q1, rrx"
3543   [(set_attr "conds" "clob")
3544    (set_attr "insn" "mov")
3545    (set_attr "length" "8")]
3546 )
3547
3548 (define_expand "ashrsi3"
3549   [(set (match_operand:SI              0 "s_register_operand" "")
3550         (ashiftrt:SI (match_operand:SI 1 "s_register_operand" "")
3551                      (match_operand:SI 2 "arm_rhs_operand" "")))]
3552   "TARGET_EITHER"
3553   "
3554   if (GET_CODE (operands[2]) == CONST_INT
3555       && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) > 31)
3556     operands[2] = GEN_INT (31);
3557   "
3558 )
3559
3560 (define_insn "*thumb1_ashrsi3"
3561   [(set (match_operand:SI              0 "register_operand" "=l,l")
3562         (ashiftrt:SI (match_operand:SI 1 "register_operand" "l,0")
3563                      (match_operand:SI 2 "nonmemory_operand" "N,l")))]
3564   "TARGET_THUMB1"
3565   "asr\\t%0, %1, %2"
3566   [(set_attr "length" "2")
3567    (set_attr "conds" "set")])
3568
3569 (define_expand "lshrdi3"
3570   [(set (match_operand:DI              0 "s_register_operand" "")
3571         (lshiftrt:DI (match_operand:DI 1 "s_register_operand" "")
3572                      (match_operand:SI 2 "reg_or_int_operand" "")))]
3573   "TARGET_32BIT"
3574   "
3575   if (GET_CODE (operands[2]) == CONST_INT)
3576     {
3577       if ((HOST_WIDE_INT) INTVAL (operands[2]) == 1)
3578         {
3579           emit_insn (gen_arm_lshrdi3_1bit (operands[0], operands[1]));
3580           DONE;
3581         }
3582         /* Ideally we shouldn't fail here if we could know that operands[1] 
3583            ends up already living in an iwmmxt register. Otherwise it's
3584            cheaper to have the alternate code being generated than moving
3585            values to iwmmxt regs and back.  */
3586         FAIL;
3587     }
3588   else if (!TARGET_REALLY_IWMMXT)
3589     FAIL;
3590   "
3591 )
3592
3593 (define_insn "arm_lshrdi3_1bit"
3594   [(set (match_operand:DI              0 "s_register_operand" "=r,&r")
3595         (lshiftrt:DI (match_operand:DI 1 "s_register_operand" "0,r")
3596                      (const_int 1)))
3597    (clobber (reg:CC CC_REGNUM))]
3598   "TARGET_32BIT"
3599   "movs\\t%R0, %R1, lsr #1\;mov\\t%Q0, %Q1, rrx"
3600   [(set_attr "conds" "clob")
3601    (set_attr "insn" "mov")
3602    (set_attr "length" "8")]
3603 )
3604
3605 (define_expand "lshrsi3"
3606   [(set (match_operand:SI              0 "s_register_operand" "")
3607         (lshiftrt:SI (match_operand:SI 1 "s_register_operand" "")
3608                      (match_operand:SI 2 "arm_rhs_operand" "")))]
3609   "TARGET_EITHER"
3610   "
3611   if (GET_CODE (operands[2]) == CONST_INT
3612       && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) > 31)
3613     {
3614       emit_insn (gen_movsi (operands[0], const0_rtx));
3615       DONE;
3616     }
3617   "
3618 )
3619
3620 (define_insn "*thumb1_lshrsi3"
3621   [(set (match_operand:SI              0 "register_operand" "=l,l")
3622         (lshiftrt:SI (match_operand:SI 1 "register_operand" "l,0")
3623                      (match_operand:SI 2 "nonmemory_operand" "N,l")))]
3624   "TARGET_THUMB1"
3625   "lsr\\t%0, %1, %2"
3626   [(set_attr "length" "2")
3627    (set_attr "conds" "set")])
3628
3629 (define_expand "rotlsi3"
3630   [(set (match_operand:SI              0 "s_register_operand" "")
3631         (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
3632                      (match_operand:SI 2 "reg_or_int_operand" "")))]
3633   "TARGET_32BIT"
3634   "
3635   if (GET_CODE (operands[2]) == CONST_INT)
3636     operands[2] = GEN_INT ((32 - INTVAL (operands[2])) % 32);
3637   else
3638     {
3639       rtx reg = gen_reg_rtx (SImode);
3640       emit_insn (gen_subsi3 (reg, GEN_INT (32), operands[2]));
3641       operands[2] = reg;
3642     }
3643   "
3644 )
3645
3646 (define_expand "rotrsi3"
3647   [(set (match_operand:SI              0 "s_register_operand" "")
3648         (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
3649                      (match_operand:SI 2 "arm_rhs_operand" "")))]
3650   "TARGET_EITHER"
3651   "
3652   if (TARGET_32BIT)
3653     {
3654       if (GET_CODE (operands[2]) == CONST_INT
3655           && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) > 31)
3656         operands[2] = GEN_INT (INTVAL (operands[2]) % 32);
3657     }
3658   else /* TARGET_THUMB1 */
3659     {
3660       if (GET_CODE (operands [2]) == CONST_INT)
3661         operands [2] = force_reg (SImode, operands[2]);
3662     }
3663   "
3664 )
3665
3666 (define_insn "*thumb1_rotrsi3"
3667   [(set (match_operand:SI              0 "register_operand" "=l")
3668         (rotatert:SI (match_operand:SI 1 "register_operand" "0")
3669                      (match_operand:SI 2 "register_operand" "l")))]
3670   "TARGET_THUMB1"
3671   "ror\\t%0, %0, %2"
3672   [(set_attr "length" "2")]
3673 )
3674
3675 (define_insn "*arm_shiftsi3"
3676   [(set (match_operand:SI   0 "s_register_operand" "=r")
3677         (match_operator:SI  3 "shift_operator"
3678          [(match_operand:SI 1 "s_register_operand"  "r")
3679           (match_operand:SI 2 "reg_or_int_operand" "rM")]))]
3680   "TARGET_32BIT"
3681   "* return arm_output_shift(operands, 0);"
3682   [(set_attr "predicable" "yes")
3683    (set_attr "shift" "1")
3684    (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
3685                       (const_string "alu_shift")
3686                       (const_string "alu_shift_reg")))]
3687 )
3688
3689 (define_insn "*shiftsi3_compare0"
3690   [(set (reg:CC_NOOV CC_REGNUM)
3691         (compare:CC_NOOV (match_operator:SI 3 "shift_operator"
3692                           [(match_operand:SI 1 "s_register_operand" "r")
3693                            (match_operand:SI 2 "arm_rhs_operand" "rM")])
3694                          (const_int 0)))
3695    (set (match_operand:SI 0 "s_register_operand" "=r")
3696         (match_op_dup 3 [(match_dup 1) (match_dup 2)]))]
3697   "TARGET_32BIT"
3698   "* return arm_output_shift(operands, 1);"
3699   [(set_attr "conds" "set")
3700    (set_attr "shift" "1")
3701    (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
3702                       (const_string "alu_shift")
3703                       (const_string "alu_shift_reg")))]
3704 )
3705
3706 (define_insn "*shiftsi3_compare0_scratch"
3707   [(set (reg:CC_NOOV CC_REGNUM)
3708         (compare:CC_NOOV (match_operator:SI 3 "shift_operator"
3709                           [(match_operand:SI 1 "s_register_operand" "r")
3710                            (match_operand:SI 2 "arm_rhs_operand" "rM")])
3711                          (const_int 0)))
3712    (clobber (match_scratch:SI 0 "=r"))]
3713   "TARGET_32BIT"
3714   "* return arm_output_shift(operands, 1);"
3715   [(set_attr "conds" "set")
3716    (set_attr "shift" "1")]
3717 )
3718
3719 (define_insn "*not_shiftsi"
3720   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3721         (not:SI (match_operator:SI 3 "shift_operator"
3722                  [(match_operand:SI 1 "s_register_operand" "r,r")
3723                   (match_operand:SI 2 "shift_amount_operand" "M,rM")])))]
3724   "TARGET_32BIT"
3725   "mvn%?\\t%0, %1%S3"
3726   [(set_attr "predicable" "yes")
3727    (set_attr "shift" "1")
3728    (set_attr "insn" "mvn")
3729    (set_attr "arch" "32,a")
3730    (set_attr "type" "alu_shift,alu_shift_reg")])
3731
3732 (define_insn "*not_shiftsi_compare0"
3733   [(set (reg:CC_NOOV CC_REGNUM)
3734         (compare:CC_NOOV
3735          (not:SI (match_operator:SI 3 "shift_operator"
3736                   [(match_operand:SI 1 "s_register_operand" "r,r")
3737                    (match_operand:SI 2 "shift_amount_operand" "M,rM")]))
3738          (const_int 0)))
3739    (set (match_operand:SI 0 "s_register_operand" "=r,r")
3740         (not:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])))]
3741   "TARGET_32BIT"
3742   "mvn%.\\t%0, %1%S3"
3743   [(set_attr "conds" "set")
3744    (set_attr "shift" "1")
3745    (set_attr "insn" "mvn")
3746    (set_attr "arch" "32,a")
3747    (set_attr "type" "alu_shift,alu_shift_reg")])
3748
3749 (define_insn "*not_shiftsi_compare0_scratch"
3750   [(set (reg:CC_NOOV CC_REGNUM)
3751         (compare:CC_NOOV
3752          (not:SI (match_operator:SI 3 "shift_operator"
3753                   [(match_operand:SI 1 "s_register_operand" "r,r")
3754                    (match_operand:SI 2 "shift_amount_operand" "M,rM")]))
3755          (const_int 0)))
3756    (clobber (match_scratch:SI 0 "=r,r"))]
3757   "TARGET_32BIT"
3758   "mvn%.\\t%0, %1%S3"
3759   [(set_attr "conds" "set")
3760    (set_attr "shift" "1")
3761    (set_attr "insn" "mvn")
3762    (set_attr "arch" "32,a")
3763    (set_attr "type" "alu_shift,alu_shift_reg")])
3764
3765 ;; We don't really have extzv, but defining this using shifts helps
3766 ;; to reduce register pressure later on.
3767
3768 (define_expand "extzv"
3769   [(set (match_operand 0 "s_register_operand" "")
3770         (zero_extract (match_operand 1 "nonimmediate_operand" "")
3771                       (match_operand 2 "const_int_operand" "")
3772                       (match_operand 3 "const_int_operand" "")))]
3773   "TARGET_THUMB1 || arm_arch_thumb2"
3774   "
3775   {
3776     HOST_WIDE_INT lshift = 32 - INTVAL (operands[2]) - INTVAL (operands[3]);
3777     HOST_WIDE_INT rshift = 32 - INTVAL (operands[2]);
3778     
3779     if (arm_arch_thumb2)
3780       {
3781         HOST_WIDE_INT width = INTVAL (operands[2]);
3782         HOST_WIDE_INT bitpos = INTVAL (operands[3]);
3783
3784         if (unaligned_access && MEM_P (operands[1])
3785             && (width == 16 || width == 32) && (bitpos % BITS_PER_UNIT) == 0)
3786           {
3787             rtx base_addr;
3788
3789             if (BYTES_BIG_ENDIAN)
3790               bitpos = GET_MODE_BITSIZE (GET_MODE (operands[0])) - width
3791                        - bitpos;
3792
3793             if (width == 32)
3794               {
3795                 base_addr = adjust_address (operands[1], SImode,
3796                                             bitpos / BITS_PER_UNIT);
3797                 emit_insn (gen_unaligned_loadsi (operands[0], base_addr));
3798               }
3799             else
3800               {
3801                 rtx dest = operands[0];
3802                 rtx tmp = gen_reg_rtx (SImode);
3803
3804                 /* We may get a paradoxical subreg here.  Strip it off.  */
3805                 if (GET_CODE (dest) == SUBREG
3806                     && GET_MODE (dest) == SImode
3807                     && GET_MODE (SUBREG_REG (dest)) == HImode)
3808                   dest = SUBREG_REG (dest);
3809
3810                 if (GET_MODE_BITSIZE (GET_MODE (dest)) != width)
3811                   FAIL;
3812
3813                 base_addr = adjust_address (operands[1], HImode,
3814                                             bitpos / BITS_PER_UNIT);
3815                 emit_insn (gen_unaligned_loadhiu (tmp, base_addr));
3816                 emit_move_insn (gen_lowpart (SImode, dest), tmp);
3817               }
3818             DONE;
3819           }
3820         else if (s_register_operand (operands[1], GET_MODE (operands[1])))
3821           {
3822             emit_insn (gen_extzv_t2 (operands[0], operands[1], operands[2],
3823                                      operands[3]));
3824             DONE;
3825           }
3826         else
3827           FAIL;
3828       }
3829     
3830     if (!s_register_operand (operands[1], GET_MODE (operands[1])))
3831       FAIL;
3832
3833     operands[3] = GEN_INT (rshift);
3834     
3835     if (lshift == 0)
3836       {
3837         emit_insn (gen_lshrsi3 (operands[0], operands[1], operands[3]));
3838         DONE;
3839       }
3840       
3841     emit_insn (gen_extzv_t1 (operands[0], operands[1], GEN_INT (lshift),
3842                              operands[3], gen_reg_rtx (SImode)));
3843     DONE;
3844   }"
3845 )
3846
3847 ;; Helper for extzv, for the Thumb-1 register-shifts case.
3848
3849 (define_expand "extzv_t1"
3850   [(set (match_operand:SI 4 "s_register_operand" "")
3851         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
3852                    (match_operand:SI 2 "const_int_operand" "")))
3853    (set (match_operand:SI 0 "s_register_operand" "")
3854         (lshiftrt:SI (match_dup 4)
3855                      (match_operand:SI 3 "const_int_operand" "")))]
3856   "TARGET_THUMB1"
3857   "")
3858
3859 (define_expand "extv"
3860   [(set (match_operand 0 "s_register_operand" "")
3861         (sign_extract (match_operand 1 "nonimmediate_operand" "")
3862                       (match_operand 2 "const_int_operand" "")
3863                       (match_operand 3 "const_int_operand" "")))]
3864   "arm_arch_thumb2"
3865 {
3866   HOST_WIDE_INT width = INTVAL (operands[2]);
3867   HOST_WIDE_INT bitpos = INTVAL (operands[3]);
3868
3869   if (unaligned_access && MEM_P (operands[1]) && (width == 16 || width == 32)
3870       && (bitpos % BITS_PER_UNIT)  == 0)
3871     {
3872       rtx base_addr;
3873       
3874       if (BYTES_BIG_ENDIAN)
3875         bitpos = GET_MODE_BITSIZE (GET_MODE (operands[0])) - width - bitpos;
3876       
3877       if (width == 32)
3878         {
3879           base_addr = adjust_address (operands[1], SImode,
3880                                       bitpos / BITS_PER_UNIT);
3881           emit_insn (gen_unaligned_loadsi (operands[0], base_addr));
3882         }
3883       else
3884         {
3885           rtx dest = operands[0];
3886           rtx tmp = gen_reg_rtx (SImode);
3887           
3888           /* We may get a paradoxical subreg here.  Strip it off.  */
3889           if (GET_CODE (dest) == SUBREG
3890               && GET_MODE (dest) == SImode
3891               && GET_MODE (SUBREG_REG (dest)) == HImode)
3892             dest = SUBREG_REG (dest);
3893           
3894           if (GET_MODE_BITSIZE (GET_MODE (dest)) != width)
3895             FAIL;
3896           
3897           base_addr = adjust_address (operands[1], HImode,
3898                                       bitpos / BITS_PER_UNIT);
3899           emit_insn (gen_unaligned_loadhis (tmp, base_addr));
3900           emit_move_insn (gen_lowpart (SImode, dest), tmp);
3901         }
3902
3903       DONE;
3904     }
3905   else if (!s_register_operand (operands[1], GET_MODE (operands[1])))
3906     FAIL;
3907   else if (GET_MODE (operands[0]) == SImode
3908            && GET_MODE (operands[1]) == SImode)
3909     {
3910       emit_insn (gen_extv_regsi (operands[0], operands[1], operands[2],
3911                                  operands[3]));
3912       DONE;
3913     }
3914
3915   FAIL;
3916 })
3917
3918 ; Helper to expand register forms of extv with the proper modes.
3919
3920 (define_expand "extv_regsi"
3921   [(set (match_operand:SI 0 "s_register_operand" "")
3922         (sign_extract:SI (match_operand:SI 1 "s_register_operand" "")
3923                          (match_operand 2 "const_int_operand" "")
3924                          (match_operand 3 "const_int_operand" "")))]
3925   ""
3926 {
3927 })
3928
3929 ; ARMv6+ unaligned load/store instructions (used for packed structure accesses).
3930
3931 (define_insn "unaligned_loadsi"
3932   [(set (match_operand:SI 0 "s_register_operand" "=l,r")
3933         (unspec:SI [(match_operand:SI 1 "memory_operand" "Uw,m")]
3934                    UNSPEC_UNALIGNED_LOAD))]
3935   "unaligned_access && TARGET_32BIT"
3936   "ldr%?\t%0, %1\t@ unaligned"
3937   [(set_attr "arch" "t2,any")
3938    (set_attr "length" "2,4")
3939    (set_attr "predicable" "yes")
3940    (set_attr "type" "load1")])
3941
3942 (define_insn "unaligned_loadhis"
3943   [(set (match_operand:SI 0 "s_register_operand" "=l,r")
3944         (sign_extend:SI
3945           (unspec:HI [(match_operand:HI 1 "memory_operand" "Uw,m")]
3946                      UNSPEC_UNALIGNED_LOAD)))]
3947   "unaligned_access && TARGET_32BIT"
3948   "ldr%(sh%)\t%0, %1\t@ unaligned"
3949   [(set_attr "arch" "t2,any")
3950    (set_attr "length" "2,4")
3951    (set_attr "predicable" "yes")
3952    (set_attr "type" "load_byte")])
3953
3954 (define_insn "unaligned_loadhiu"
3955   [(set (match_operand:SI 0 "s_register_operand" "=l,r")
3956         (zero_extend:SI
3957           (unspec:HI [(match_operand:HI 1 "memory_operand" "Uw,m")]
3958                      UNSPEC_UNALIGNED_LOAD)))]
3959   "unaligned_access && TARGET_32BIT"
3960   "ldr%(h%)\t%0, %1\t@ unaligned"
3961   [(set_attr "arch" "t2,any")
3962    (set_attr "length" "2,4")
3963    (set_attr "predicable" "yes")
3964    (set_attr "type" "load_byte")])
3965
3966 (define_insn "unaligned_storesi"
3967   [(set (match_operand:SI 0 "memory_operand" "=Uw,m")
3968         (unspec:SI [(match_operand:SI 1 "s_register_operand" "l,r")]
3969                    UNSPEC_UNALIGNED_STORE))]
3970   "unaligned_access && TARGET_32BIT"
3971   "str%?\t%1, %0\t@ unaligned"
3972   [(set_attr "arch" "t2,any")
3973    (set_attr "length" "2,4")
3974    (set_attr "predicable" "yes")
3975    (set_attr "type" "store1")])
3976
3977 (define_insn "unaligned_storehi"
3978   [(set (match_operand:HI 0 "memory_operand" "=Uw,m")
3979         (unspec:HI [(match_operand:HI 1 "s_register_operand" "l,r")]
3980                    UNSPEC_UNALIGNED_STORE))]
3981   "unaligned_access && TARGET_32BIT"
3982   "str%(h%)\t%1, %0\t@ unaligned"
3983   [(set_attr "arch" "t2,any")
3984    (set_attr "length" "2,4")
3985    (set_attr "predicable" "yes")
3986    (set_attr "type" "store1")])
3987
3988 (define_insn "*extv_reg"
3989   [(set (match_operand:SI 0 "s_register_operand" "=r")
3990         (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
3991                          (match_operand:SI 2 "const_int_operand" "M")
3992                          (match_operand:SI 3 "const_int_operand" "M")))]
3993   "arm_arch_thumb2"
3994   "sbfx%?\t%0, %1, %3, %2"
3995   [(set_attr "length" "4")
3996    (set_attr "predicable" "yes")]
3997 )
3998
3999 (define_insn "extzv_t2"
4000   [(set (match_operand:SI 0 "s_register_operand" "=r")
4001         (zero_extract:SI (match_operand:SI 1 "s_register_operand" "r")
4002                          (match_operand:SI 2 "const_int_operand" "M")
4003                          (match_operand:SI 3 "const_int_operand" "M")))]
4004   "arm_arch_thumb2"
4005   "ubfx%?\t%0, %1, %3, %2"
4006   [(set_attr "length" "4")
4007    (set_attr "predicable" "yes")]
4008 )
4009
4010
4011 ;; Division instructions
4012 (define_insn "divsi3"
4013   [(set (match_operand:SI         0 "s_register_operand" "=r")
4014         (div:SI (match_operand:SI 1 "s_register_operand"  "r")
4015                 (match_operand:SI 2 "s_register_operand"  "r")))]
4016   "TARGET_IDIV"
4017   "sdiv%?\t%0, %1, %2"
4018   [(set_attr "predicable" "yes")
4019    (set_attr "insn" "sdiv")]
4020 )
4021
4022 (define_insn "udivsi3"
4023   [(set (match_operand:SI          0 "s_register_operand" "=r")
4024         (udiv:SI (match_operand:SI 1 "s_register_operand"  "r")
4025                  (match_operand:SI 2 "s_register_operand"  "r")))]
4026   "TARGET_IDIV"
4027   "udiv%?\t%0, %1, %2"
4028   [(set_attr "predicable" "yes")
4029    (set_attr "insn" "udiv")]
4030 )
4031
4032 \f
4033 ;; Unary arithmetic insns
4034
4035 (define_expand "negdi2"
4036  [(parallel
4037    [(set (match_operand:DI 0 "s_register_operand" "")
4038          (neg:DI (match_operand:DI 1 "s_register_operand" "")))
4039     (clobber (reg:CC CC_REGNUM))])]
4040   "TARGET_EITHER"
4041   ""
4042 )
4043
4044 ;; The constraints here are to prevent a *partial* overlap (where %Q0 == %R1).
4045 ;; The first alternative allows the common case of a *full* overlap.
4046 (define_insn "*arm_negdi2"
4047   [(set (match_operand:DI         0 "s_register_operand" "=r,&r")
4048         (neg:DI (match_operand:DI 1 "s_register_operand"  "0,r")))
4049    (clobber (reg:CC CC_REGNUM))]
4050   "TARGET_ARM"
4051   "rsbs\\t%Q0, %Q1, #0\;rsc\\t%R0, %R1, #0"
4052   [(set_attr "conds" "clob")
4053    (set_attr "length" "8")]
4054 )
4055
4056 (define_insn "*thumb1_negdi2"
4057   [(set (match_operand:DI 0 "register_operand" "=&l")
4058         (neg:DI (match_operand:DI 1 "register_operand" "l")))
4059    (clobber (reg:CC CC_REGNUM))]
4060   "TARGET_THUMB1"
4061   "mov\\t%R0, #0\;neg\\t%Q0, %Q1\;sbc\\t%R0, %R1"
4062   [(set_attr "length" "6")]
4063 )
4064
4065 (define_expand "negsi2"
4066   [(set (match_operand:SI         0 "s_register_operand" "")
4067         (neg:SI (match_operand:SI 1 "s_register_operand" "")))]
4068   "TARGET_EITHER"
4069   ""
4070 )
4071
4072 (define_insn "*arm_negsi2"
4073   [(set (match_operand:SI         0 "s_register_operand" "=r")
4074         (neg:SI (match_operand:SI 1 "s_register_operand" "r")))]
4075   "TARGET_32BIT"
4076   "rsb%?\\t%0, %1, #0"
4077   [(set_attr "predicable" "yes")]
4078 )
4079
4080 (define_insn "*thumb1_negsi2"
4081   [(set (match_operand:SI         0 "register_operand" "=l")
4082         (neg:SI (match_operand:SI 1 "register_operand" "l")))]
4083   "TARGET_THUMB1"
4084   "neg\\t%0, %1"
4085   [(set_attr "length" "2")]
4086 )
4087
4088 (define_expand "negsf2"
4089   [(set (match_operand:SF         0 "s_register_operand" "")
4090         (neg:SF (match_operand:SF 1 "s_register_operand" "")))]
4091   "TARGET_32BIT && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP)"
4092   ""
4093 )
4094
4095 (define_expand "negdf2"
4096   [(set (match_operand:DF         0 "s_register_operand" "")
4097         (neg:DF (match_operand:DF 1 "s_register_operand" "")))]
4098   "TARGET_32BIT && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP_DOUBLE)"
4099   "")
4100
4101 ;; abssi2 doesn't really clobber the condition codes if a different register
4102 ;; is being set.  To keep things simple, assume during rtl manipulations that
4103 ;; it does, but tell the final scan operator the truth.  Similarly for
4104 ;; (neg (abs...))
4105
4106 (define_expand "abssi2"
4107   [(parallel
4108     [(set (match_operand:SI         0 "s_register_operand" "")
4109           (abs:SI (match_operand:SI 1 "s_register_operand" "")))
4110      (clobber (match_dup 2))])]
4111   "TARGET_EITHER"
4112   "
4113   if (TARGET_THUMB1)
4114     operands[2] = gen_rtx_SCRATCH (SImode);
4115   else
4116     operands[2] = gen_rtx_REG (CCmode, CC_REGNUM);
4117 ")
4118
4119 (define_insn "*arm_abssi2"
4120   [(set (match_operand:SI 0 "s_register_operand" "=r,&r")
4121         (abs:SI (match_operand:SI 1 "s_register_operand" "0,r")))
4122    (clobber (reg:CC CC_REGNUM))]
4123   "TARGET_ARM"
4124   "@
4125    cmp\\t%0, #0\;rsblt\\t%0, %0, #0
4126    eor%?\\t%0, %1, %1, asr #31\;sub%?\\t%0, %0, %1, asr #31"
4127   [(set_attr "conds" "clob,*")
4128    (set_attr "shift" "1")
4129    ;; predicable can't be set based on the variant, so left as no
4130    (set_attr "length" "8")]
4131 )
4132
4133 (define_insn_and_split "*thumb1_abssi2"
4134   [(set (match_operand:SI 0 "s_register_operand" "=l")
4135         (abs:SI (match_operand:SI 1 "s_register_operand" "l")))
4136    (clobber (match_scratch:SI 2 "=&l"))]
4137   "TARGET_THUMB1"
4138   "#"
4139   "TARGET_THUMB1 && reload_completed"
4140   [(set (match_dup 2) (ashiftrt:SI (match_dup 1) (const_int 31)))
4141    (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))
4142    (set (match_dup 0) (xor:SI (match_dup 0) (match_dup 2)))]
4143   ""
4144   [(set_attr "length" "6")]
4145 )
4146
4147 (define_insn "*arm_neg_abssi2"
4148   [(set (match_operand:SI 0 "s_register_operand" "=r,&r")
4149         (neg:SI (abs:SI (match_operand:SI 1 "s_register_operand" "0,r"))))
4150    (clobber (reg:CC CC_REGNUM))]
4151   "TARGET_ARM"
4152   "@
4153    cmp\\t%0, #0\;rsbgt\\t%0, %0, #0
4154    eor%?\\t%0, %1, %1, asr #31\;rsb%?\\t%0, %0, %1, asr #31"
4155   [(set_attr "conds" "clob,*")
4156    (set_attr "shift" "1")
4157    ;; predicable can't be set based on the variant, so left as no
4158    (set_attr "length" "8")]
4159 )
4160
4161 (define_insn_and_split "*thumb1_neg_abssi2"
4162   [(set (match_operand:SI 0 "s_register_operand" "=l")
4163         (neg:SI (abs:SI (match_operand:SI 1 "s_register_operand" "l"))))
4164    (clobber (match_scratch:SI 2 "=&l"))]
4165   "TARGET_THUMB1"
4166   "#"
4167   "TARGET_THUMB1 && reload_completed"
4168   [(set (match_dup 2) (ashiftrt:SI (match_dup 1) (const_int 31)))
4169    (set (match_dup 0) (minus:SI (match_dup 2) (match_dup 1)))
4170    (set (match_dup 0) (xor:SI (match_dup 0) (match_dup 2)))]
4171   ""
4172   [(set_attr "length" "6")]
4173 )
4174
4175 (define_expand "abssf2"
4176   [(set (match_operand:SF         0 "s_register_operand" "")
4177         (abs:SF (match_operand:SF 1 "s_register_operand" "")))]
4178   "TARGET_32BIT && TARGET_HARD_FLOAT"
4179   "")
4180
4181 (define_expand "absdf2"
4182   [(set (match_operand:DF         0 "s_register_operand" "")
4183         (abs:DF (match_operand:DF 1 "s_register_operand" "")))]
4184   "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
4185   "")
4186
4187 (define_expand "sqrtsf2"
4188   [(set (match_operand:SF 0 "s_register_operand" "")
4189         (sqrt:SF (match_operand:SF 1 "s_register_operand" "")))]
4190   "TARGET_32BIT && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP)"
4191   "")
4192
4193 (define_expand "sqrtdf2"
4194   [(set (match_operand:DF 0 "s_register_operand" "")
4195         (sqrt:DF (match_operand:DF 1 "s_register_operand" "")))]
4196   "TARGET_32BIT && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP_DOUBLE)"
4197   "")
4198
4199 (define_insn_and_split "one_cmpldi2"
4200   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
4201         (not:DI (match_operand:DI 1 "s_register_operand" "0,r")))]
4202   "TARGET_32BIT"
4203   "#"
4204   "TARGET_32BIT && reload_completed"
4205   [(set (match_dup 0) (not:SI (match_dup 1)))
4206    (set (match_dup 2) (not:SI (match_dup 3)))]
4207   "
4208   {
4209     operands[2] = gen_highpart (SImode, operands[0]);
4210     operands[0] = gen_lowpart (SImode, operands[0]);
4211     operands[3] = gen_highpart (SImode, operands[1]);
4212     operands[1] = gen_lowpart (SImode, operands[1]);
4213   }"
4214   [(set_attr "length" "8")
4215    (set_attr "predicable" "yes")]
4216 )
4217
4218 (define_expand "one_cmplsi2"
4219   [(set (match_operand:SI         0 "s_register_operand" "")
4220         (not:SI (match_operand:SI 1 "s_register_operand" "")))]
4221   "TARGET_EITHER"
4222   ""
4223 )
4224
4225 (define_insn "*arm_one_cmplsi2"
4226   [(set (match_operand:SI         0 "s_register_operand" "=r")
4227         (not:SI (match_operand:SI 1 "s_register_operand"  "r")))]
4228   "TARGET_32BIT"
4229   "mvn%?\\t%0, %1"
4230   [(set_attr "predicable" "yes")
4231    (set_attr "insn" "mvn")]
4232 )
4233
4234 (define_insn "*thumb1_one_cmplsi2"
4235   [(set (match_operand:SI         0 "register_operand" "=l")
4236         (not:SI (match_operand:SI 1 "register_operand"  "l")))]
4237   "TARGET_THUMB1"
4238   "mvn\\t%0, %1"
4239   [(set_attr "length" "2")
4240    (set_attr "insn" "mvn")]
4241 )
4242
4243 (define_insn "*notsi_compare0"
4244   [(set (reg:CC_NOOV CC_REGNUM)
4245         (compare:CC_NOOV (not:SI (match_operand:SI 1 "s_register_operand" "r"))
4246                          (const_int 0)))
4247    (set (match_operand:SI 0 "s_register_operand" "=r")
4248         (not:SI (match_dup 1)))]
4249   "TARGET_32BIT"
4250   "mvn%.\\t%0, %1"
4251   [(set_attr "conds" "set")
4252    (set_attr "insn" "mvn")]
4253 )
4254
4255 (define_insn "*notsi_compare0_scratch"
4256   [(set (reg:CC_NOOV CC_REGNUM)
4257         (compare:CC_NOOV (not:SI (match_operand:SI 1 "s_register_operand" "r"))
4258                          (const_int 0)))
4259    (clobber (match_scratch:SI 0 "=r"))]
4260   "TARGET_32BIT"
4261   "mvn%.\\t%0, %1"
4262   [(set_attr "conds" "set")
4263    (set_attr "insn" "mvn")]
4264 )
4265 \f
4266 ;; Fixed <--> Floating conversion insns
4267
4268 (define_expand "floatsihf2"
4269   [(set (match_operand:HF           0 "general_operand" "")
4270         (float:HF (match_operand:SI 1 "general_operand" "")))]
4271   "TARGET_EITHER"
4272   "
4273   {
4274     rtx op1 = gen_reg_rtx (SFmode);
4275     expand_float (op1, operands[1], 0);
4276     op1 = convert_to_mode (HFmode, op1, 0);
4277     emit_move_insn (operands[0], op1);
4278     DONE;
4279   }"
4280 )
4281
4282 (define_expand "floatdihf2"
4283   [(set (match_operand:HF           0 "general_operand" "")
4284         (float:HF (match_operand:DI 1 "general_operand" "")))]
4285   "TARGET_EITHER"
4286   "
4287   {
4288     rtx op1 = gen_reg_rtx (SFmode);
4289     expand_float (op1, operands[1], 0);
4290     op1 = convert_to_mode (HFmode, op1, 0);
4291     emit_move_insn (operands[0], op1);
4292     DONE;
4293   }"
4294 )
4295
4296 (define_expand "floatsisf2"
4297   [(set (match_operand:SF           0 "s_register_operand" "")
4298         (float:SF (match_operand:SI 1 "s_register_operand" "")))]
4299   "TARGET_32BIT && TARGET_HARD_FLOAT"
4300   "
4301   if (TARGET_MAVERICK)
4302     {
4303       emit_insn (gen_cirrus_floatsisf2 (operands[0], operands[1]));
4304       DONE;
4305     }
4306 ")
4307
4308 (define_expand "floatsidf2"
4309   [(set (match_operand:DF           0 "s_register_operand" "")
4310         (float:DF (match_operand:SI 1 "s_register_operand" "")))]
4311   "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
4312   "
4313   if (TARGET_MAVERICK)
4314     {
4315       emit_insn (gen_cirrus_floatsidf2 (operands[0], operands[1]));
4316       DONE;
4317     }
4318 ")
4319
4320 (define_expand "fix_trunchfsi2"
4321   [(set (match_operand:SI         0 "general_operand" "")
4322         (fix:SI (fix:HF (match_operand:HF 1 "general_operand"  ""))))]
4323   "TARGET_EITHER"
4324   "
4325   {
4326     rtx op1 = convert_to_mode (SFmode, operands[1], 0);
4327     expand_fix (operands[0], op1, 0);
4328     DONE;
4329   }"
4330 )
4331
4332 (define_expand "fix_trunchfdi2"
4333   [(set (match_operand:DI         0 "general_operand" "")
4334         (fix:DI (fix:HF (match_operand:HF 1 "general_operand"  ""))))]
4335   "TARGET_EITHER"
4336   "
4337   {
4338     rtx op1 = convert_to_mode (SFmode, operands[1], 0);
4339     expand_fix (operands[0], op1, 0);
4340     DONE;
4341   }"
4342 )
4343
4344 (define_expand "fix_truncsfsi2"
4345   [(set (match_operand:SI         0 "s_register_operand" "")
4346         (fix:SI (fix:SF (match_operand:SF 1 "s_register_operand"  ""))))]
4347   "TARGET_32BIT && TARGET_HARD_FLOAT"
4348   "
4349   if (TARGET_MAVERICK)
4350     {
4351       if (!cirrus_fp_register (operands[0], SImode))
4352         operands[0] = force_reg (SImode, operands[0]);
4353       if (!cirrus_fp_register (operands[1], SFmode))
4354         operands[1] = force_reg (SFmode, operands[0]);
4355       emit_insn (gen_cirrus_truncsfsi2 (operands[0], operands[1]));
4356       DONE;
4357     }
4358 ")
4359
4360 (define_expand "fix_truncdfsi2"
4361   [(set (match_operand:SI         0 "s_register_operand" "")
4362         (fix:SI (fix:DF (match_operand:DF 1 "s_register_operand"  ""))))]
4363   "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
4364   "
4365   if (TARGET_MAVERICK)
4366     {
4367       if (!cirrus_fp_register (operands[1], DFmode))
4368         operands[1] = force_reg (DFmode, operands[0]);
4369       emit_insn (gen_cirrus_truncdfsi2 (operands[0], operands[1]));
4370       DONE;
4371     }
4372 ")
4373
4374 ;; Truncation insns
4375
4376 (define_expand "truncdfsf2"
4377   [(set (match_operand:SF  0 "s_register_operand" "")
4378         (float_truncate:SF
4379          (match_operand:DF 1 "s_register_operand" "")))]
4380   "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
4381   ""
4382 )
4383
4384 /* DFmode -> HFmode conversions have to go through SFmode.  */
4385 (define_expand "truncdfhf2"
4386   [(set (match_operand:HF  0 "general_operand" "")
4387         (float_truncate:HF
4388          (match_operand:DF 1 "general_operand" "")))]
4389   "TARGET_EITHER"
4390   "
4391   {
4392     rtx op1;
4393     op1 = convert_to_mode (SFmode, operands[1], 0);
4394     op1 = convert_to_mode (HFmode, op1, 0);
4395     emit_move_insn (operands[0], op1);
4396     DONE;
4397   }"
4398 )
4399 \f
4400 ;; Zero and sign extension instructions.
4401
4402 (define_insn "zero_extend<mode>di2"
4403   [(set (match_operand:DI 0 "s_register_operand" "=r")
4404         (zero_extend:DI (match_operand:QHSI 1 "<qhs_zextenddi_op>"
4405                                             "<qhs_zextenddi_cstr>")))]
4406   "TARGET_32BIT <qhs_zextenddi_cond>"
4407   "#"
4408   [(set_attr "length" "8")
4409    (set_attr "ce_count" "2")
4410    (set_attr "predicable" "yes")]
4411 )
4412
4413 (define_insn "extend<mode>di2"
4414   [(set (match_operand:DI 0 "s_register_operand" "=r")
4415         (sign_extend:DI (match_operand:QHSI 1 "<qhs_extenddi_op>"
4416                                             "<qhs_extenddi_cstr>")))]
4417   "TARGET_32BIT <qhs_sextenddi_cond>"
4418   "#"
4419   [(set_attr "length" "8")
4420    (set_attr "ce_count" "2")
4421    (set_attr "shift" "1")
4422    (set_attr "predicable" "yes")]
4423 )
4424
4425 ;; Splits for all extensions to DImode
4426 (define_split
4427   [(set (match_operand:DI 0 "s_register_operand" "")
4428         (zero_extend:DI (match_operand 1 "nonimmediate_operand" "")))]
4429   "TARGET_32BIT"
4430   [(set (match_dup 0) (match_dup 1))]
4431 {
4432   rtx lo_part = gen_lowpart (SImode, operands[0]);
4433   enum machine_mode src_mode = GET_MODE (operands[1]);
4434
4435   if (REG_P (operands[0])
4436       && !reg_overlap_mentioned_p (operands[0], operands[1]))
4437     emit_clobber (operands[0]);
4438   if (!REG_P (lo_part) || src_mode != SImode
4439       || !rtx_equal_p (lo_part, operands[1]))
4440     {
4441       if (src_mode == SImode)
4442         emit_move_insn (lo_part, operands[1]);
4443       else
4444         emit_insn (gen_rtx_SET (VOIDmode, lo_part,
4445                                 gen_rtx_ZERO_EXTEND (SImode, operands[1])));
4446       operands[1] = lo_part;
4447     }
4448   operands[0] = gen_highpart (SImode, operands[0]);
4449   operands[1] = const0_rtx;
4450 })
4451
4452 (define_split
4453   [(set (match_operand:DI 0 "s_register_operand" "")
4454         (sign_extend:DI (match_operand 1 "nonimmediate_operand" "")))]
4455   "TARGET_32BIT"
4456   [(set (match_dup 0) (ashiftrt:SI (match_dup 1) (const_int 31)))]
4457 {
4458   rtx lo_part = gen_lowpart (SImode, operands[0]);
4459   enum machine_mode src_mode = GET_MODE (operands[1]);
4460
4461   if (REG_P (operands[0])
4462       && !reg_overlap_mentioned_p (operands[0], operands[1]))
4463     emit_clobber (operands[0]);
4464
4465   if (!REG_P (lo_part) || src_mode != SImode
4466       || !rtx_equal_p (lo_part, operands[1]))
4467     {
4468       if (src_mode == SImode)
4469         emit_move_insn (lo_part, operands[1]);
4470       else
4471         emit_insn (gen_rtx_SET (VOIDmode, lo_part,
4472                                 gen_rtx_SIGN_EXTEND (SImode, operands[1])));
4473       operands[1] = lo_part;
4474     }
4475   operands[0] = gen_highpart (SImode, operands[0]);
4476 })
4477
4478 (define_expand "zero_extendhisi2"
4479   [(set (match_operand:SI 0 "s_register_operand" "")
4480         (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
4481   "TARGET_EITHER"
4482 {
4483   if (TARGET_ARM && !arm_arch4 && MEM_P (operands[1]))
4484     {
4485       emit_insn (gen_movhi_bytes (operands[0], operands[1]));
4486       DONE;
4487     }
4488   if (!arm_arch6 && !MEM_P (operands[1]))
4489     {
4490       rtx t = gen_lowpart (SImode, operands[1]);
4491       rtx tmp = gen_reg_rtx (SImode);
4492       emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (16)));
4493       emit_insn (gen_lshrsi3 (operands[0], tmp, GEN_INT (16)));
4494       DONE;
4495     }
4496 })
4497
4498 (define_split
4499   [(set (match_operand:SI 0 "s_register_operand" "")
4500         (zero_extend:SI (match_operand:HI 1 "s_register_operand" "")))]
4501   "!TARGET_THUMB2 && !arm_arch6"
4502   [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
4503    (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 16)))]
4504 {
4505   operands[2] = gen_lowpart (SImode, operands[1]);
4506 })
4507
4508 (define_insn "*thumb1_zero_extendhisi2"
4509   [(set (match_operand:SI 0 "register_operand" "=l,l")
4510         (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "l,m")))]
4511   "TARGET_THUMB1"
4512 {
4513   rtx mem;
4514
4515   if (which_alternative == 0 && arm_arch6)
4516     return "uxth\t%0, %1";
4517   if (which_alternative == 0)
4518     return "#";
4519
4520   mem = XEXP (operands[1], 0);
4521
4522   if (GET_CODE (mem) == CONST)
4523     mem = XEXP (mem, 0);
4524     
4525   if (GET_CODE (mem) == PLUS)
4526     {
4527       rtx a = XEXP (mem, 0);
4528
4529       /* This can happen due to bugs in reload.  */
4530       if (GET_CODE (a) == REG && REGNO (a) == SP_REGNUM)
4531         {
4532           rtx ops[2];
4533           ops[0] = operands[0];
4534           ops[1] = a;
4535       
4536           output_asm_insn ("mov\t%0, %1", ops);
4537
4538           XEXP (mem, 0) = operands[0];
4539        }
4540     }
4541     
4542   return "ldrh\t%0, %1";
4543 }
4544   [(set_attr_alternative "length"
4545                          [(if_then_else (eq_attr "is_arch6" "yes")
4546                                        (const_int 2) (const_int 4))
4547                          (const_int 4)])
4548    (set_attr "type" "alu_shift,load_byte")]
4549 )
4550
4551 (define_insn "*arm_zero_extendhisi2"
4552   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4553         (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
4554   "TARGET_ARM && arm_arch4 && !arm_arch6"
4555   "@
4556    #
4557    ldr%(h%)\\t%0, %1"
4558   [(set_attr "type" "alu_shift,load_byte")
4559    (set_attr "predicable" "yes")]
4560 )
4561
4562 (define_insn "*arm_zero_extendhisi2_v6"
4563   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4564         (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
4565   "TARGET_ARM && arm_arch6"
4566   "@
4567    uxth%?\\t%0, %1
4568    ldr%(h%)\\t%0, %1"
4569   [(set_attr "type" "alu_shift,load_byte")
4570    (set_attr "predicable" "yes")]
4571 )
4572
4573 (define_insn "*arm_zero_extendhisi2addsi"
4574   [(set (match_operand:SI 0 "s_register_operand" "=r")
4575         (plus:SI (zero_extend:SI (match_operand:HI 1 "s_register_operand" "r"))
4576                  (match_operand:SI 2 "s_register_operand" "r")))]
4577   "TARGET_INT_SIMD"
4578   "uxtah%?\\t%0, %2, %1"
4579   [(set_attr "type" "alu_shift")
4580    (set_attr "predicable" "yes")]
4581 )
4582
4583 (define_expand "zero_extendqisi2"
4584   [(set (match_operand:SI 0 "s_register_operand" "")
4585         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))]
4586   "TARGET_EITHER"
4587 {
4588   if (TARGET_ARM && !arm_arch6 && GET_CODE (operands[1]) != MEM)
4589     {
4590       emit_insn (gen_andsi3 (operands[0],
4591                              gen_lowpart (SImode, operands[1]),
4592                                           GEN_INT (255)));
4593       DONE;
4594     }
4595   if (!arm_arch6 && !MEM_P (operands[1]))
4596     {
4597       rtx t = gen_lowpart (SImode, operands[1]);
4598       rtx tmp = gen_reg_rtx (SImode);
4599       emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (24)));
4600       emit_insn (gen_lshrsi3 (operands[0], tmp, GEN_INT (24)));
4601       DONE;
4602     }
4603 })
4604
4605 (define_split
4606   [(set (match_operand:SI 0 "s_register_operand" "")
4607         (zero_extend:SI (match_operand:QI 1 "s_register_operand" "")))]
4608   "!arm_arch6"
4609   [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 24)))
4610    (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 24)))]
4611 {
4612   operands[2] = simplify_gen_subreg (SImode, operands[1], QImode, 0);
4613   if (TARGET_ARM)
4614     {
4615       emit_insn (gen_andsi3 (operands[0], operands[2], GEN_INT (255)));
4616       DONE;
4617     }
4618 })
4619
4620 (define_insn "*thumb1_zero_extendqisi2"
4621   [(set (match_operand:SI 0 "register_operand" "=l,l")
4622         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "l,m")))]
4623   "TARGET_THUMB1 && !arm_arch6"
4624   "@
4625    #
4626    ldrb\\t%0, %1"
4627   [(set_attr "length" "4,2")
4628    (set_attr "type" "alu_shift,load_byte")
4629    (set_attr "pool_range" "*,32")]
4630 )
4631
4632 (define_insn "*thumb1_zero_extendqisi2_v6"
4633   [(set (match_operand:SI 0 "register_operand" "=l,l")
4634         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "l,m")))]
4635   "TARGET_THUMB1 && arm_arch6"
4636   "@
4637    uxtb\\t%0, %1
4638    ldrb\\t%0, %1"
4639   [(set_attr "length" "2")
4640    (set_attr "type" "alu_shift,load_byte")]
4641 )
4642
4643 (define_insn "*arm_zero_extendqisi2"
4644   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4645         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
4646   "TARGET_ARM && !arm_arch6"
4647   "@
4648    #
4649    ldr%(b%)\\t%0, %1\\t%@ zero_extendqisi2"
4650   [(set_attr "length" "8,4")
4651    (set_attr "type" "alu_shift,load_byte")
4652    (set_attr "predicable" "yes")]
4653 )
4654
4655 (define_insn "*arm_zero_extendqisi2_v6"
4656   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4657         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
4658   "TARGET_ARM && arm_arch6"
4659   "@
4660    uxtb%(%)\\t%0, %1
4661    ldr%(b%)\\t%0, %1\\t%@ zero_extendqisi2"
4662   [(set_attr "type" "alu_shift,load_byte")
4663    (set_attr "predicable" "yes")]
4664 )
4665
4666 (define_insn "*arm_zero_extendqisi2addsi"
4667   [(set (match_operand:SI 0 "s_register_operand" "=r")
4668         (plus:SI (zero_extend:SI (match_operand:QI 1 "s_register_operand" "r"))
4669                  (match_operand:SI 2 "s_register_operand" "r")))]
4670   "TARGET_INT_SIMD"
4671   "uxtab%?\\t%0, %2, %1"
4672   [(set_attr "predicable" "yes")
4673    (set_attr "insn" "xtab")
4674    (set_attr "type" "alu_shift")]
4675 )
4676
4677 (define_split
4678   [(set (match_operand:SI 0 "s_register_operand" "")
4679         (zero_extend:SI (subreg:QI (match_operand:SI 1 "" "") 0)))
4680    (clobber (match_operand:SI 2 "s_register_operand" ""))]
4681   "TARGET_32BIT && (GET_CODE (operands[1]) != MEM) && ! BYTES_BIG_ENDIAN"
4682   [(set (match_dup 2) (match_dup 1))
4683    (set (match_dup 0) (and:SI (match_dup 2) (const_int 255)))]
4684   ""
4685 )
4686
4687 (define_split
4688   [(set (match_operand:SI 0 "s_register_operand" "")
4689         (zero_extend:SI (subreg:QI (match_operand:SI 1 "" "") 3)))
4690    (clobber (match_operand:SI 2 "s_register_operand" ""))]
4691   "TARGET_32BIT && (GET_CODE (operands[1]) != MEM) && BYTES_BIG_ENDIAN"
4692   [(set (match_dup 2) (match_dup 1))
4693    (set (match_dup 0) (and:SI (match_dup 2) (const_int 255)))]
4694   ""
4695 )
4696
4697
4698 (define_split
4699   [(set (match_operand:SI 0 "s_register_operand" "")
4700         (ior_xor:SI (and:SI (ashift:SI
4701                              (match_operand:SI 1 "s_register_operand" "")
4702                              (match_operand:SI 2 "const_int_operand" ""))
4703                             (match_operand:SI 3 "const_int_operand" ""))
4704                     (zero_extend:SI
4705                      (match_operator 5 "subreg_lowpart_operator"
4706                       [(match_operand:SI 4 "s_register_operand" "")]))))]
4707   "TARGET_32BIT
4708    && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
4709        == (GET_MODE_MASK (GET_MODE (operands[5]))
4710            & (GET_MODE_MASK (GET_MODE (operands[5]))
4711               << (INTVAL (operands[2])))))"
4712   [(set (match_dup 0) (ior_xor:SI (ashift:SI (match_dup 1) (match_dup 2))
4713                                   (match_dup 4)))
4714    (set (match_dup 0) (zero_extend:SI (match_dup 5)))]
4715   "operands[5] = gen_lowpart (GET_MODE (operands[5]), operands[0]);"
4716 )
4717
4718 (define_insn "*compareqi_eq0"
4719   [(set (reg:CC_Z CC_REGNUM)
4720         (compare:CC_Z (match_operand:QI 0 "s_register_operand" "r")
4721                          (const_int 0)))]
4722   "TARGET_32BIT"
4723   "tst%?\\t%0, #255"
4724   [(set_attr "conds" "set")
4725    (set_attr "predicable" "yes")]
4726 )
4727
4728 (define_expand "extendhisi2"
4729   [(set (match_operand:SI 0 "s_register_operand" "")
4730         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
4731   "TARGET_EITHER"
4732 {
4733   if (TARGET_THUMB1)
4734     {
4735       emit_insn (gen_thumb1_extendhisi2 (operands[0], operands[1]));
4736       DONE;
4737     }
4738   if (MEM_P (operands[1]) && TARGET_ARM && !arm_arch4)
4739     {
4740       emit_insn (gen_extendhisi2_mem (operands[0], operands[1]));
4741       DONE;
4742     }
4743
4744   if (!arm_arch6 && !MEM_P (operands[1]))
4745     {
4746       rtx t = gen_lowpart (SImode, operands[1]);
4747       rtx tmp = gen_reg_rtx (SImode);
4748       emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (16)));
4749       emit_insn (gen_ashrsi3 (operands[0], tmp, GEN_INT (16)));
4750       DONE;
4751     }
4752 })
4753
4754 (define_split
4755   [(parallel
4756     [(set (match_operand:SI 0 "register_operand" "")
4757           (sign_extend:SI (match_operand:HI 1 "register_operand" "")))
4758      (clobber (match_scratch:SI 2 ""))])]
4759   "!arm_arch6"
4760   [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
4761    (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
4762 {
4763   operands[2] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
4764 })
4765
4766 ;; We used to have an early-clobber on the scratch register here.
4767 ;; However, there's a bug somewhere in reload which means that this
4768 ;; can be partially ignored during spill allocation if the memory
4769 ;; address also needs reloading; this causes us to die later on when
4770 ;; we try to verify the operands.  Fortunately, we don't really need
4771 ;; the early-clobber: we can always use operand 0 if operand 2
4772 ;; overlaps the address.
4773 (define_insn "thumb1_extendhisi2"
4774   [(set (match_operand:SI 0 "register_operand" "=l,l")
4775         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "l,m")))
4776    (clobber (match_scratch:SI 2 "=X,l"))]
4777   "TARGET_THUMB1"
4778   "*
4779   {
4780     rtx ops[4];
4781     rtx mem;
4782
4783     if (which_alternative == 0 && !arm_arch6)
4784       return \"#\";
4785     if (which_alternative == 0)
4786       return \"sxth\\t%0, %1\";
4787
4788     mem = XEXP (operands[1], 0);
4789
4790     /* This code used to try to use 'V', and fix the address only if it was
4791        offsettable, but this fails for e.g. REG+48 because 48 is outside the
4792        range of QImode offsets, and offsettable_address_p does a QImode
4793        address check.  */
4794        
4795     if (GET_CODE (mem) == CONST)
4796       mem = XEXP (mem, 0);
4797     
4798     if (GET_CODE (mem) == LABEL_REF)
4799       return \"ldr\\t%0, %1\";
4800     
4801     if (GET_CODE (mem) == PLUS)
4802       {
4803         rtx a = XEXP (mem, 0);
4804         rtx b = XEXP (mem, 1);
4805
4806         if (GET_CODE (a) == LABEL_REF
4807             && GET_CODE (b) == CONST_INT)
4808           return \"ldr\\t%0, %1\";
4809
4810         if (GET_CODE (b) == REG)
4811           return \"ldrsh\\t%0, %1\";
4812           
4813         ops[1] = a;
4814         ops[2] = b;
4815       }
4816     else
4817       {
4818         ops[1] = mem;
4819         ops[2] = const0_rtx;
4820       }
4821       
4822     gcc_assert (GET_CODE (ops[1]) == REG);
4823
4824     ops[0] = operands[0];
4825     if (reg_mentioned_p (operands[2], ops[1]))
4826       ops[3] = ops[0];
4827     else
4828       ops[3] = operands[2];
4829     output_asm_insn (\"mov\\t%3, %2\;ldrsh\\t%0, [%1, %3]\", ops);
4830     return \"\";
4831   }"
4832   [(set_attr_alternative "length"
4833                          [(if_then_else (eq_attr "is_arch6" "yes")
4834                                         (const_int 2) (const_int 4))
4835                           (const_int 4)])
4836    (set_attr "type" "alu_shift,load_byte")
4837    (set_attr "pool_range" "*,1020")]
4838 )
4839
4840 ;; This pattern will only be used when ldsh is not available
4841 (define_expand "extendhisi2_mem"
4842   [(set (match_dup 2) (zero_extend:SI (match_operand:HI 1 "" "")))
4843    (set (match_dup 3)
4844         (zero_extend:SI (match_dup 7)))
4845    (set (match_dup 6) (ashift:SI (match_dup 4) (const_int 24)))
4846    (set (match_operand:SI 0 "" "")
4847         (ior:SI (ashiftrt:SI (match_dup 6) (const_int 16)) (match_dup 5)))]
4848   "TARGET_ARM"
4849   "
4850   {
4851     rtx mem1, mem2;
4852     rtx addr = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
4853
4854     mem1 = change_address (operands[1], QImode, addr);
4855     mem2 = change_address (operands[1], QImode, plus_constant (addr, 1));
4856     operands[0] = gen_lowpart (SImode, operands[0]);
4857     operands[1] = mem1;
4858     operands[2] = gen_reg_rtx (SImode);
4859     operands[3] = gen_reg_rtx (SImode);
4860     operands[6] = gen_reg_rtx (SImode);
4861     operands[7] = mem2;
4862
4863     if (BYTES_BIG_ENDIAN)
4864       {
4865         operands[4] = operands[2];
4866         operands[5] = operands[3];
4867       }
4868     else
4869       {
4870         operands[4] = operands[3];
4871         operands[5] = operands[2];
4872       }
4873   }"
4874 )
4875
4876 (define_split
4877   [(set (match_operand:SI 0 "register_operand" "")
4878         (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
4879   "!arm_arch6"
4880   [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
4881    (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
4882 {
4883   operands[2] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
4884 })
4885
4886 (define_insn "*arm_extendhisi2"
4887   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4888         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
4889   "TARGET_ARM && arm_arch4 && !arm_arch6"
4890   "@
4891    #
4892    ldr%(sh%)\\t%0, %1"
4893   [(set_attr "length" "8,4")
4894    (set_attr "type" "alu_shift,load_byte")
4895    (set_attr "predicable" "yes")
4896    (set_attr "pool_range" "*,256")
4897    (set_attr "neg_pool_range" "*,244")]
4898 )
4899
4900 ;; ??? Check Thumb-2 pool range
4901 (define_insn "*arm_extendhisi2_v6"
4902   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4903         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
4904   "TARGET_32BIT && arm_arch6"
4905   "@
4906    sxth%?\\t%0, %1
4907    ldr%(sh%)\\t%0, %1"
4908   [(set_attr "type" "alu_shift,load_byte")
4909    (set_attr "predicable" "yes")
4910    (set_attr "pool_range" "*,256")
4911    (set_attr "neg_pool_range" "*,244")]
4912 )
4913
4914 (define_insn "*arm_extendhisi2addsi"
4915   [(set (match_operand:SI 0 "s_register_operand" "=r")
4916         (plus:SI (sign_extend:SI (match_operand:HI 1 "s_register_operand" "r"))
4917                  (match_operand:SI 2 "s_register_operand" "r")))]
4918   "TARGET_INT_SIMD"
4919   "sxtah%?\\t%0, %2, %1"
4920 )
4921
4922 (define_expand "extendqihi2"
4923   [(set (match_dup 2)
4924         (ashift:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "")
4925                    (const_int 24)))
4926    (set (match_operand:HI 0 "s_register_operand" "")
4927         (ashiftrt:SI (match_dup 2)
4928                      (const_int 24)))]
4929   "TARGET_ARM"
4930   "
4931   {
4932     if (arm_arch4 && GET_CODE (operands[1]) == MEM)
4933       {
4934         emit_insn (gen_rtx_SET (VOIDmode,
4935                                 operands[0],
4936                                 gen_rtx_SIGN_EXTEND (HImode, operands[1])));
4937         DONE;
4938       }
4939     if (!s_register_operand (operands[1], QImode))
4940       operands[1] = copy_to_mode_reg (QImode, operands[1]);
4941     operands[0] = gen_lowpart (SImode, operands[0]);
4942     operands[1] = gen_lowpart (SImode, operands[1]);
4943     operands[2] = gen_reg_rtx (SImode);
4944   }"
4945 )
4946
4947 (define_insn "*arm_extendqihi_insn"
4948   [(set (match_operand:HI 0 "s_register_operand" "=r")
4949         (sign_extend:HI (match_operand:QI 1 "arm_extendqisi_mem_op" "Uq")))]
4950   "TARGET_ARM && arm_arch4"
4951   "ldr%(sb%)\\t%0, %1"
4952   [(set_attr "type" "load_byte")
4953    (set_attr "predicable" "yes")
4954    (set_attr "pool_range" "256")
4955    (set_attr "neg_pool_range" "244")]
4956 )
4957
4958 (define_expand "extendqisi2"
4959   [(set (match_operand:SI 0 "s_register_operand" "")
4960         (sign_extend:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "")))]
4961   "TARGET_EITHER"
4962 {
4963   if (!arm_arch4 && MEM_P (operands[1]))
4964     operands[1] = copy_to_mode_reg (QImode, operands[1]);
4965
4966   if (!arm_arch6 && !MEM_P (operands[1]))
4967     {
4968       rtx t = gen_lowpart (SImode, operands[1]);
4969       rtx tmp = gen_reg_rtx (SImode);
4970       emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (24)));
4971       emit_insn (gen_ashrsi3 (operands[0], tmp, GEN_INT (24)));
4972       DONE;
4973     }
4974 })
4975
4976 (define_split
4977   [(set (match_operand:SI 0 "register_operand" "")
4978         (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
4979   "!arm_arch6"
4980   [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 24)))
4981    (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 24)))]
4982 {
4983   operands[2] = simplify_gen_subreg (SImode, operands[1], QImode, 0);
4984 })
4985
4986 (define_insn "*arm_extendqisi"
4987   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4988         (sign_extend:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "r,Uq")))]
4989   "TARGET_ARM && arm_arch4 && !arm_arch6"
4990   "@
4991    #
4992    ldr%(sb%)\\t%0, %1"
4993   [(set_attr "length" "8,4")
4994    (set_attr "type" "alu_shift,load_byte")
4995    (set_attr "predicable" "yes")
4996    (set_attr "pool_range" "*,256")
4997    (set_attr "neg_pool_range" "*,244")]
4998 )
4999
5000 (define_insn "*arm_extendqisi_v6"
5001   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5002         (sign_extend:SI
5003          (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "r,Uq")))]
5004   "TARGET_ARM && arm_arch6"
5005   "@
5006    sxtb%?\\t%0, %1
5007    ldr%(sb%)\\t%0, %1"
5008   [(set_attr "type" "alu_shift,load_byte")
5009    (set_attr "predicable" "yes")
5010    (set_attr "pool_range" "*,256")
5011    (set_attr "neg_pool_range" "*,244")]
5012 )
5013
5014 (define_insn "*arm_extendqisi2addsi"
5015   [(set (match_operand:SI 0 "s_register_operand" "=r")
5016         (plus:SI (sign_extend:SI (match_operand:QI 1 "s_register_operand" "r"))
5017                  (match_operand:SI 2 "s_register_operand" "r")))]
5018   "TARGET_INT_SIMD"
5019   "sxtab%?\\t%0, %2, %1"
5020   [(set_attr "type" "alu_shift")
5021    (set_attr "insn" "xtab")
5022    (set_attr "predicable" "yes")]
5023 )
5024
5025 (define_split
5026   [(set (match_operand:SI 0 "register_operand" "")
5027         (sign_extend:SI (match_operand:QI 1 "memory_operand" "")))]
5028   "TARGET_THUMB1 && reload_completed"
5029   [(set (match_dup 0) (match_dup 2))
5030    (set (match_dup 0) (sign_extend:SI (match_dup 3)))]
5031 {
5032   rtx addr = XEXP (operands[1], 0);
5033
5034   if (GET_CODE (addr) == CONST)
5035     addr = XEXP (addr, 0);
5036
5037   if (GET_CODE (addr) == PLUS
5038       && REG_P (XEXP (addr, 0)) && REG_P (XEXP (addr, 1)))
5039     /* No split necessary.  */
5040     FAIL;
5041
5042   if (GET_CODE (addr) == PLUS
5043       && !REG_P (XEXP (addr, 0)) && !REG_P (XEXP (addr, 1)))
5044     FAIL;
5045
5046   if (reg_overlap_mentioned_p (operands[0], addr))
5047     {
5048       rtx t = gen_lowpart (QImode, operands[0]);
5049       emit_move_insn (t, operands[1]);
5050       emit_insn (gen_thumb1_extendqisi2 (operands[0], t));
5051       DONE;
5052     }
5053
5054   if (REG_P (addr))
5055     {
5056       addr = gen_rtx_PLUS (Pmode, addr, operands[0]);
5057       operands[2] = const0_rtx;
5058     }
5059   else if (GET_CODE (addr) != PLUS)
5060     FAIL;
5061   else if (REG_P (XEXP (addr, 0)))
5062     {
5063       operands[2] = XEXP (addr, 1);
5064       addr = gen_rtx_PLUS (Pmode, XEXP (addr, 0), operands[0]);
5065     }
5066   else
5067     {
5068       operands[2] = XEXP (addr, 0);
5069       addr = gen_rtx_PLUS (Pmode, XEXP (addr, 1), operands[0]);
5070     }
5071
5072   operands[3] = change_address (operands[1], QImode, addr);
5073 })
5074
5075 (define_peephole2
5076   [(set (match_operand:SI 0 "register_operand" "")
5077         (plus:SI (match_dup 0) (match_operand 1 "const_int_operand")))
5078    (set (match_operand:SI 2 "register_operand" "") (const_int 0))
5079    (set (match_operand:SI 3 "register_operand" "")
5080         (sign_extend:SI (match_operand:QI 4 "memory_operand" "")))]
5081   "TARGET_THUMB1
5082    && GET_CODE (XEXP (operands[4], 0)) == PLUS
5083    && rtx_equal_p (operands[0], XEXP (XEXP (operands[4], 0), 0))
5084    && rtx_equal_p (operands[2], XEXP (XEXP (operands[4], 0), 1))
5085    && (peep2_reg_dead_p (3, operands[0])
5086        || rtx_equal_p (operands[0], operands[3]))
5087    && (peep2_reg_dead_p (3, operands[2])
5088        || rtx_equal_p (operands[2], operands[3]))"
5089   [(set (match_dup 2) (match_dup 1))
5090    (set (match_dup 3) (sign_extend:SI (match_dup 4)))]
5091 {
5092   rtx addr = gen_rtx_PLUS (Pmode, operands[0], operands[2]);
5093   operands[4] = change_address (operands[4], QImode, addr);
5094 })
5095
5096 (define_insn "thumb1_extendqisi2"
5097   [(set (match_operand:SI 0 "register_operand" "=l,l,l")
5098         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "l,V,m")))]
5099   "TARGET_THUMB1"
5100 {
5101   rtx addr;
5102
5103   if (which_alternative == 0 && arm_arch6)
5104     return "sxtb\\t%0, %1";
5105   if (which_alternative == 0)
5106     return "#";
5107
5108   addr = XEXP (operands[1], 0);
5109   if (GET_CODE (addr) == PLUS
5110       && REG_P (XEXP (addr, 0)) && REG_P (XEXP (addr, 1)))
5111     return "ldrsb\\t%0, %1";
5112       
5113   return "#";
5114 }
5115   [(set_attr_alternative "length"
5116                          [(if_then_else (eq_attr "is_arch6" "yes")
5117                                         (const_int 2) (const_int 4))
5118                           (const_int 2)
5119                           (if_then_else (eq_attr "is_arch6" "yes")
5120                                         (const_int 4) (const_int 6))])
5121    (set_attr "type" "alu_shift,load_byte,load_byte")]
5122 )
5123
5124 (define_expand "extendsfdf2"
5125   [(set (match_operand:DF                  0 "s_register_operand" "")
5126         (float_extend:DF (match_operand:SF 1 "s_register_operand"  "")))]
5127   "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
5128   ""
5129 )
5130
5131 /* HFmode -> DFmode conversions have to go through SFmode.  */
5132 (define_expand "extendhfdf2"
5133   [(set (match_operand:DF                  0 "general_operand" "")
5134         (float_extend:DF (match_operand:HF 1 "general_operand"  "")))]
5135   "TARGET_EITHER"
5136   "
5137   {
5138     rtx op1;
5139     op1 = convert_to_mode (SFmode, operands[1], 0);
5140     op1 = convert_to_mode (DFmode, op1, 0);
5141     emit_insn (gen_movdf (operands[0], op1));
5142     DONE;
5143   }"
5144 )
5145 \f
5146 ;; Move insns (including loads and stores)
5147
5148 ;; XXX Just some ideas about movti.
5149 ;; I don't think these are a good idea on the arm, there just aren't enough
5150 ;; registers
5151 ;;(define_expand "loadti"
5152 ;;  [(set (match_operand:TI 0 "s_register_operand" "")
5153 ;;      (mem:TI (match_operand:SI 1 "address_operand" "")))]
5154 ;;  "" "")
5155
5156 ;;(define_expand "storeti"
5157 ;;  [(set (mem:TI (match_operand:TI 0 "address_operand" ""))
5158 ;;      (match_operand:TI 1 "s_register_operand" ""))]
5159 ;;  "" "")
5160
5161 ;;(define_expand "movti"
5162 ;;  [(set (match_operand:TI 0 "general_operand" "")
5163 ;;      (match_operand:TI 1 "general_operand" ""))]
5164 ;;  ""
5165 ;;  "
5166 ;;{
5167 ;;  rtx insn;
5168 ;;
5169 ;;  if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
5170 ;;    operands[1] = copy_to_reg (operands[1]);
5171 ;;  if (GET_CODE (operands[0]) == MEM)
5172 ;;    insn = gen_storeti (XEXP (operands[0], 0), operands[1]);
5173 ;;  else if (GET_CODE (operands[1]) == MEM)
5174 ;;    insn = gen_loadti (operands[0], XEXP (operands[1], 0));
5175 ;;  else
5176 ;;    FAIL;
5177 ;;
5178 ;;  emit_insn (insn);
5179 ;;  DONE;
5180 ;;}")
5181
5182 ;; Recognize garbage generated above.
5183
5184 ;;(define_insn ""
5185 ;;  [(set (match_operand:TI 0 "general_operand" "=r,r,r,<,>,m")
5186 ;;      (match_operand:TI 1 "general_operand" "<,>,m,r,r,r"))]
5187 ;;  ""
5188 ;;  "*
5189 ;;  {
5190 ;;    register mem = (which_alternative < 3);
5191 ;;    register const char *template;
5192 ;;
5193 ;;    operands[mem] = XEXP (operands[mem], 0);
5194 ;;    switch (which_alternative)
5195 ;;      {
5196 ;;      case 0: template = \"ldmdb\\t%1!, %M0\"; break;
5197 ;;      case 1: template = \"ldmia\\t%1!, %M0\"; break;
5198 ;;      case 2: template = \"ldmia\\t%1, %M0\"; break;
5199 ;;      case 3: template = \"stmdb\\t%0!, %M1\"; break;
5200 ;;      case 4: template = \"stmia\\t%0!, %M1\"; break;
5201 ;;      case 5: template = \"stmia\\t%0, %M1\"; break;
5202 ;;      }
5203 ;;    output_asm_insn (template, operands);
5204 ;;    return \"\";
5205 ;;  }")
5206
5207 (define_expand "movdi"
5208   [(set (match_operand:DI 0 "general_operand" "")
5209         (match_operand:DI 1 "general_operand" ""))]
5210   "TARGET_EITHER"
5211   "
5212   if (can_create_pseudo_p ())
5213     {
5214       if (GET_CODE (operands[0]) != REG)
5215         operands[1] = force_reg (DImode, operands[1]);
5216     }
5217   "
5218 )
5219
5220 (define_insn "*arm_movdi"
5221   [(set (match_operand:DI 0 "nonimmediate_di_operand" "=r, r, r, r, m")
5222         (match_operand:DI 1 "di_operand"              "rDa,Db,Dc,mi,r"))]
5223   "TARGET_32BIT
5224    && !(TARGET_HARD_FLOAT && (TARGET_MAVERICK || TARGET_VFP))
5225    && !TARGET_IWMMXT
5226    && (   register_operand (operands[0], DImode)
5227        || register_operand (operands[1], DImode))"
5228   "*
5229   switch (which_alternative)
5230     {
5231     case 0:
5232     case 1:
5233     case 2:
5234       return \"#\";
5235     default:
5236       return output_move_double (operands, true, NULL);
5237     }
5238   "
5239   [(set_attr "length" "8,12,16,8,8")
5240    (set_attr "type" "*,*,*,load2,store2")
5241    (set_attr "arm_pool_range" "*,*,*,1020,*")
5242    (set_attr "arm_neg_pool_range" "*,*,*,1004,*")
5243    (set_attr "thumb2_pool_range" "*,*,*,4096,*")
5244    (set_attr "thumb2_neg_pool_range" "*,*,*,0,*")]
5245 )
5246
5247 (define_split
5248   [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
5249         (match_operand:ANY64 1 "const_double_operand" ""))]
5250   "TARGET_32BIT
5251    && reload_completed
5252    && (arm_const_double_inline_cost (operands[1])
5253        <= ((optimize_size || arm_ld_sched) ? 3 : 4))"
5254   [(const_int 0)]
5255   "
5256   arm_split_constant (SET, SImode, curr_insn,
5257                       INTVAL (gen_lowpart (SImode, operands[1])),
5258                       gen_lowpart (SImode, operands[0]), NULL_RTX, 0);
5259   arm_split_constant (SET, SImode, curr_insn,
5260                       INTVAL (gen_highpart_mode (SImode,
5261                                                  GET_MODE (operands[0]),
5262                                                  operands[1])),
5263                       gen_highpart (SImode, operands[0]), NULL_RTX, 0);
5264   DONE;
5265   "
5266 )
5267
5268 ; If optimizing for size, or if we have load delay slots, then 
5269 ; we want to split the constant into two separate operations. 
5270 ; In both cases this may split a trivial part into a single data op
5271 ; leaving a single complex constant to load.  We can also get longer
5272 ; offsets in a LDR which means we get better chances of sharing the pool
5273 ; entries.  Finally, we can normally do a better job of scheduling
5274 ; LDR instructions than we can with LDM.
5275 ; This pattern will only match if the one above did not.
5276 (define_split
5277   [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
5278         (match_operand:ANY64 1 "const_double_operand" ""))]
5279   "TARGET_ARM && reload_completed
5280    && arm_const_double_by_parts (operands[1])"
5281   [(set (match_dup 0) (match_dup 1))
5282    (set (match_dup 2) (match_dup 3))]
5283   "
5284   operands[2] = gen_highpart (SImode, operands[0]);
5285   operands[3] = gen_highpart_mode (SImode, GET_MODE (operands[0]),
5286                                    operands[1]);
5287   operands[0] = gen_lowpart (SImode, operands[0]);
5288   operands[1] = gen_lowpart (SImode, operands[1]);
5289   "
5290 )
5291
5292 (define_split
5293   [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
5294         (match_operand:ANY64 1 "arm_general_register_operand" ""))]
5295   "TARGET_EITHER && reload_completed"
5296   [(set (match_dup 0) (match_dup 1))
5297    (set (match_dup 2) (match_dup 3))]
5298   "
5299   operands[2] = gen_highpart (SImode, operands[0]);
5300   operands[3] = gen_highpart (SImode, operands[1]);
5301   operands[0] = gen_lowpart (SImode, operands[0]);
5302   operands[1] = gen_lowpart (SImode, operands[1]);
5303
5304   /* Handle a partial overlap.  */
5305   if (rtx_equal_p (operands[0], operands[3]))
5306     {
5307       rtx tmp0 = operands[0];
5308       rtx tmp1 = operands[1];
5309
5310       operands[0] = operands[2];
5311       operands[1] = operands[3];
5312       operands[2] = tmp0;
5313       operands[3] = tmp1;
5314     }
5315   "
5316 )
5317
5318 ;; We can't actually do base+index doubleword loads if the index and
5319 ;; destination overlap.  Split here so that we at least have chance to
5320 ;; schedule.
5321 (define_split
5322   [(set (match_operand:DI 0 "s_register_operand" "")
5323         (mem:DI (plus:SI (match_operand:SI 1 "s_register_operand" "")
5324                          (match_operand:SI 2 "s_register_operand" ""))))]
5325   "TARGET_LDRD
5326   && reg_overlap_mentioned_p (operands[0], operands[1])
5327   && reg_overlap_mentioned_p (operands[0], operands[2])"
5328   [(set (match_dup 4)
5329         (plus:SI (match_dup 1)
5330                  (match_dup 2)))
5331    (set (match_dup 0)
5332         (mem:DI (match_dup 4)))]
5333   "
5334   operands[4] = gen_rtx_REG (SImode, REGNO(operands[0]));
5335   "
5336 )
5337
5338 ;;; ??? This should have alternatives for constants.
5339 ;;; ??? This was originally identical to the movdf_insn pattern.
5340 ;;; ??? The 'i' constraint looks funny, but it should always be replaced by
5341 ;;; thumb_reorg with a memory reference.
5342 (define_insn "*thumb1_movdi_insn"
5343   [(set (match_operand:DI 0 "nonimmediate_operand" "=l,l,l,l,>,l, m,*r")
5344         (match_operand:DI 1 "general_operand"      "l, I,J,>,l,mi,l,*r"))]
5345   "TARGET_THUMB1
5346    && !(TARGET_HARD_FLOAT && TARGET_MAVERICK)
5347    && (   register_operand (operands[0], DImode)
5348        || register_operand (operands[1], DImode))"
5349   "*
5350   {
5351   switch (which_alternative)
5352     {
5353     default:
5354     case 0:
5355       if (REGNO (operands[1]) == REGNO (operands[0]) + 1)
5356         return \"add\\t%0,  %1,  #0\;add\\t%H0, %H1, #0\";
5357       return   \"add\\t%H0, %H1, #0\;add\\t%0,  %1,  #0\";
5358     case 1:
5359       return \"mov\\t%Q0, %1\;mov\\t%R0, #0\";
5360     case 2:
5361       operands[1] = GEN_INT (- INTVAL (operands[1]));
5362       return \"mov\\t%Q0, %1\;neg\\t%Q0, %Q0\;asr\\t%R0, %Q0, #31\";
5363     case 3:
5364       return \"ldmia\\t%1, {%0, %H0}\";
5365     case 4:
5366       return \"stmia\\t%0, {%1, %H1}\";
5367     case 5:
5368       return thumb_load_double_from_address (operands);
5369     case 6:
5370       operands[2] = gen_rtx_MEM (SImode,
5371                              plus_constant (XEXP (operands[0], 0), 4));
5372       output_asm_insn (\"str\\t%1, %0\;str\\t%H1, %2\", operands);
5373       return \"\";
5374     case 7:
5375       if (REGNO (operands[1]) == REGNO (operands[0]) + 1)
5376         return \"mov\\t%0, %1\;mov\\t%H0, %H1\";
5377       return \"mov\\t%H0, %H1\;mov\\t%0, %1\";
5378     }
5379   }"
5380   [(set_attr "length" "4,4,6,2,2,6,4,4")
5381    (set_attr "type" "*,*,*,load2,store2,load2,store2,*")
5382    (set_attr "insn" "*,mov,*,*,*,*,*,mov")
5383    (set_attr "pool_range" "*,*,*,*,*,1020,*,*")]
5384 )
5385
5386 (define_expand "movsi"
5387   [(set (match_operand:SI 0 "general_operand" "")
5388         (match_operand:SI 1 "general_operand" ""))]
5389   "TARGET_EITHER"
5390   "
5391   {
5392   rtx base, offset, tmp;
5393
5394   if (TARGET_32BIT)
5395     {
5396       /* Everything except mem = const or mem = mem can be done easily.  */
5397       if (GET_CODE (operands[0]) == MEM)
5398         operands[1] = force_reg (SImode, operands[1]);
5399       if (arm_general_register_operand (operands[0], SImode)
5400           && GET_CODE (operands[1]) == CONST_INT
5401           && !(const_ok_for_arm (INTVAL (operands[1]))
5402                || const_ok_for_arm (~INTVAL (operands[1]))))
5403         {
5404            arm_split_constant (SET, SImode, NULL_RTX,
5405                                INTVAL (operands[1]), operands[0], NULL_RTX,
5406                                optimize && can_create_pseudo_p ());
5407           DONE;
5408         }
5409
5410       if (TARGET_USE_MOVT && !target_word_relocations
5411           && GET_CODE (operands[1]) == SYMBOL_REF
5412           && !flag_pic && !arm_tls_referenced_p (operands[1]))
5413         {
5414           arm_emit_movpair (operands[0], operands[1]);
5415           DONE;
5416         }
5417     }
5418   else /* TARGET_THUMB1...  */
5419     {
5420       if (can_create_pseudo_p ())
5421         {
5422           if (GET_CODE (operands[0]) != REG)
5423             operands[1] = force_reg (SImode, operands[1]);
5424         }
5425     }
5426
5427   if (ARM_OFFSETS_MUST_BE_WITHIN_SECTIONS_P)
5428     {
5429       split_const (operands[1], &base, &offset);
5430       if (GET_CODE (base) == SYMBOL_REF
5431           && !offset_within_block_p (base, INTVAL (offset)))
5432         {
5433           tmp = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];
5434           emit_move_insn (tmp, base);
5435           emit_insn (gen_addsi3 (operands[0], tmp, offset));
5436           DONE;
5437         }
5438     }
5439
5440   /* Recognize the case where operand[1] is a reference to thread-local
5441      data and load its address to a register.  */
5442   if (arm_tls_referenced_p (operands[1]))
5443     {
5444       rtx tmp = operands[1];
5445       rtx addend = NULL;
5446
5447       if (GET_CODE (tmp) == CONST && GET_CODE (XEXP (tmp, 0)) == PLUS)
5448         {
5449           addend = XEXP (XEXP (tmp, 0), 1);
5450           tmp = XEXP (XEXP (tmp, 0), 0);
5451         }
5452
5453       gcc_assert (GET_CODE (tmp) == SYMBOL_REF);
5454       gcc_assert (SYMBOL_REF_TLS_MODEL (tmp) != 0);
5455
5456       tmp = legitimize_tls_address (tmp,
5457                                     !can_create_pseudo_p () ? operands[0] : 0);
5458       if (addend)
5459         {
5460           tmp = gen_rtx_PLUS (SImode, tmp, addend);
5461           tmp = force_operand (tmp, operands[0]);
5462         }
5463       operands[1] = tmp;
5464     }
5465   else if (flag_pic
5466            && (CONSTANT_P (operands[1])
5467                || symbol_mentioned_p (operands[1])
5468                || label_mentioned_p (operands[1])))
5469       operands[1] = legitimize_pic_address (operands[1], SImode,
5470                                             (!can_create_pseudo_p ()
5471                                              ? operands[0]
5472                                              : 0));
5473   }
5474   "
5475 )
5476
5477 ;; The ARM LO_SUM and HIGH are backwards - HIGH sets the low bits, and
5478 ;; LO_SUM adds in the high bits.  Fortunately these are opaque operations
5479 ;; so this does not matter.
5480 (define_insn "*arm_movt"
5481   [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
5482         (lo_sum:SI (match_operand:SI 1 "nonimmediate_operand" "0")
5483                    (match_operand:SI 2 "general_operand"      "i")))]
5484   "arm_arch_thumb2"
5485   "movt%?\t%0, #:upper16:%c2"
5486   [(set_attr "predicable" "yes")
5487    (set_attr "length" "4")]
5488 )
5489
5490 (define_insn "*arm_movsi_insn"
5491   [(set (match_operand:SI 0 "nonimmediate_operand" "=rk,r,r,r,rk,m")
5492         (match_operand:SI 1 "general_operand"      "rk, I,K,j,mi,rk"))]
5493   "TARGET_ARM && ! TARGET_IWMMXT
5494    && !(TARGET_HARD_FLOAT && TARGET_VFP)
5495    && (   register_operand (operands[0], SImode)
5496        || register_operand (operands[1], SImode))"
5497   "@
5498    mov%?\\t%0, %1
5499    mov%?\\t%0, %1
5500    mvn%?\\t%0, #%B1
5501    movw%?\\t%0, %1
5502    ldr%?\\t%0, %1
5503    str%?\\t%1, %0"
5504   [(set_attr "type" "*,*,*,*,load1,store1")
5505    (set_attr "insn" "mov,mov,mvn,mov,*,*")
5506    (set_attr "predicable" "yes")
5507    (set_attr "pool_range" "*,*,*,*,4096,*")
5508    (set_attr "neg_pool_range" "*,*,*,*,4084,*")]
5509 )
5510
5511 (define_split
5512   [(set (match_operand:SI 0 "arm_general_register_operand" "")
5513         (match_operand:SI 1 "const_int_operand" ""))]
5514   "TARGET_32BIT
5515   && (!(const_ok_for_arm (INTVAL (operands[1]))
5516         || const_ok_for_arm (~INTVAL (operands[1]))))"
5517   [(clobber (const_int 0))]
5518   "
5519   arm_split_constant (SET, SImode, NULL_RTX, 
5520                       INTVAL (operands[1]), operands[0], NULL_RTX, 0);
5521   DONE;
5522   "
5523 )
5524
5525 (define_insn "*thumb1_movsi_insn"
5526   [(set (match_operand:SI 0 "nonimmediate_operand" "=l,l,l,l,l,>,l, m,*l*h*k")
5527         (match_operand:SI 1 "general_operand"      "l, I,J,K,>,l,mi,l,*l*h*k"))]
5528   "TARGET_THUMB1
5529    && (   register_operand (operands[0], SImode) 
5530        || register_operand (operands[1], SImode))"
5531   "@
5532    mov  %0, %1
5533    mov  %0, %1
5534    #
5535    #
5536    ldmia\\t%1, {%0}
5537    stmia\\t%0, {%1}
5538    ldr\\t%0, %1
5539    str\\t%1, %0
5540    mov\\t%0, %1"
5541   [(set_attr "length" "2,2,4,4,2,2,2,2,2")
5542    (set_attr "type" "*,*,*,*,load1,store1,load1,store1,*")
5543    (set_attr "pool_range" "*,*,*,*,*,*,1020,*,*")
5544    (set_attr "conds" "set,clob,*,*,nocond,nocond,nocond,nocond,nocond")])
5545
5546 (define_split 
5547   [(set (match_operand:SI 0 "register_operand" "")
5548         (match_operand:SI 1 "const_int_operand" ""))]
5549   "TARGET_THUMB1 && satisfies_constraint_J (operands[1])"
5550   [(set (match_dup 2) (match_dup 1))
5551    (set (match_dup 0) (neg:SI (match_dup 2)))]
5552   "
5553   {
5554     operands[1] = GEN_INT (- INTVAL (operands[1]));
5555     operands[2] = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];
5556   }"
5557 )
5558
5559 (define_split 
5560   [(set (match_operand:SI 0 "register_operand" "")
5561         (match_operand:SI 1 "const_int_operand" ""))]
5562   "TARGET_THUMB1 && satisfies_constraint_K (operands[1])"
5563   [(set (match_dup 2) (match_dup 1))
5564    (set (match_dup 0) (ashift:SI (match_dup 2) (match_dup 3)))]
5565   "
5566   {
5567     unsigned HOST_WIDE_INT val = INTVAL (operands[1]) & 0xffffffffu;
5568     unsigned HOST_WIDE_INT mask = 0xff;
5569     int i;
5570     
5571     for (i = 0; i < 25; i++)
5572       if ((val & (mask << i)) == val)
5573         break;
5574
5575     /* Don't split if the shift is zero.  */
5576     if (i == 0)
5577       FAIL;
5578
5579     operands[1] = GEN_INT (val >> i);
5580     operands[2] = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];
5581     operands[3] = GEN_INT (i);
5582   }"
5583 )
5584
5585 ;; When generating pic, we need to load the symbol offset into a register.
5586 ;; So that the optimizer does not confuse this with a normal symbol load
5587 ;; we use an unspec.  The offset will be loaded from a constant pool entry,
5588 ;; since that is the only type of relocation we can use.
5589
5590 ;; Wrap calculation of the whole PIC address in a single pattern for the
5591 ;; benefit of optimizers, particularly, PRE and HOIST.  Calculation of
5592 ;; a PIC address involves two loads from memory, so we want to CSE it
5593 ;; as often as possible.
5594 ;; This pattern will be split into one of the pic_load_addr_* patterns
5595 ;; and a move after GCSE optimizations.
5596 ;;
5597 ;; Note: Update arm.c: legitimize_pic_address() when changing this pattern.
5598 (define_expand "calculate_pic_address"
5599   [(set (match_operand:SI 0 "register_operand" "")
5600         (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "")
5601                          (unspec:SI [(match_operand:SI 2 "" "")]
5602                                     UNSPEC_PIC_SYM))))]
5603   "flag_pic"
5604 )
5605
5606 ;; Split calculate_pic_address into pic_load_addr_* and a move.
5607 (define_split
5608   [(set (match_operand:SI 0 "register_operand" "")
5609         (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "")
5610                          (unspec:SI [(match_operand:SI 2 "" "")]
5611                                     UNSPEC_PIC_SYM))))]
5612   "flag_pic"
5613   [(set (match_dup 3) (unspec:SI [(match_dup 2)] UNSPEC_PIC_SYM))
5614    (set (match_dup 0) (mem:SI (plus:SI (match_dup 1) (match_dup 3))))]
5615   "operands[3] = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];"
5616 )
5617
5618 ;; operand1 is the memory address to go into 
5619 ;; pic_load_addr_32bit.
5620 ;; operand2 is the PIC label to be emitted 
5621 ;; from pic_add_dot_plus_eight.
5622 ;; We do this to allow hoisting of the entire insn.
5623 (define_insn_and_split "pic_load_addr_unified"
5624   [(set (match_operand:SI 0 "s_register_operand" "=r,r,l")
5625         (unspec:SI [(match_operand:SI 1 "" "mX,mX,mX") 
5626                     (match_operand:SI 2 "" "")] 
5627                     UNSPEC_PIC_UNIFIED))]
5628  "flag_pic"
5629  "#"
5630  "&& reload_completed"
5631  [(set (match_dup 0) (unspec:SI [(match_dup 1)] UNSPEC_PIC_SYM))
5632   (set (match_dup 0) (unspec:SI [(match_dup 0) (match_dup 3)
5633                                  (match_dup 2)] UNSPEC_PIC_BASE))]
5634  "operands[3] = TARGET_THUMB ? GEN_INT (4) : GEN_INT (8);"
5635  [(set_attr "type" "load1,load1,load1")
5636   (set_attr "pool_range" "4096,4096,1024")
5637   (set_attr "neg_pool_range" "4084,0,0")
5638   (set_attr "arch"  "a,t2,t1")    
5639   (set_attr "length" "8,6,4")]
5640 )
5641
5642 ;; The rather odd constraints on the following are to force reload to leave
5643 ;; the insn alone, and to force the minipool generation pass to then move
5644 ;; the GOT symbol to memory.
5645
5646 (define_insn "pic_load_addr_32bit"
5647   [(set (match_operand:SI 0 "s_register_operand" "=r")
5648         (unspec:SI [(match_operand:SI 1 "" "mX")] UNSPEC_PIC_SYM))]
5649   "TARGET_32BIT && flag_pic"
5650   "ldr%?\\t%0, %1"
5651   [(set_attr "type" "load1")
5652    (set_attr "pool_range" "4096")
5653    (set (attr "neg_pool_range")
5654         (if_then_else (eq_attr "is_thumb" "no")
5655                       (const_int 4084)
5656                       (const_int 0)))]
5657 )
5658
5659 (define_insn "pic_load_addr_thumb1"
5660   [(set (match_operand:SI 0 "s_register_operand" "=l")
5661         (unspec:SI [(match_operand:SI 1 "" "mX")] UNSPEC_PIC_SYM))]
5662   "TARGET_THUMB1 && flag_pic"
5663   "ldr\\t%0, %1"
5664   [(set_attr "type" "load1")
5665    (set (attr "pool_range") (const_int 1024))]
5666 )
5667
5668 (define_insn "pic_add_dot_plus_four"
5669   [(set (match_operand:SI 0 "register_operand" "=r")
5670         (unspec:SI [(match_operand:SI 1 "register_operand" "0")
5671                     (const_int 4)
5672                     (match_operand 2 "" "")]
5673                    UNSPEC_PIC_BASE))]
5674   "TARGET_THUMB"
5675   "*
5676   (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
5677                                      INTVAL (operands[2]));
5678   return \"add\\t%0, %|pc\";
5679   "
5680   [(set_attr "length" "2")]
5681 )
5682
5683 (define_insn "pic_add_dot_plus_eight"
5684   [(set (match_operand:SI 0 "register_operand" "=r")
5685         (unspec:SI [(match_operand:SI 1 "register_operand" "r")
5686                     (const_int 8)
5687                     (match_operand 2 "" "")]
5688                    UNSPEC_PIC_BASE))]
5689   "TARGET_ARM"
5690   "*
5691     (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
5692                                        INTVAL (operands[2]));
5693     return \"add%?\\t%0, %|pc, %1\";
5694   "
5695   [(set_attr "predicable" "yes")]
5696 )
5697
5698 (define_insn "tls_load_dot_plus_eight"
5699   [(set (match_operand:SI 0 "register_operand" "=r")
5700         (mem:SI (unspec:SI [(match_operand:SI 1 "register_operand" "r")
5701                             (const_int 8)
5702                             (match_operand 2 "" "")]
5703                            UNSPEC_PIC_BASE)))]
5704   "TARGET_ARM"
5705   "*
5706     (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
5707                                        INTVAL (operands[2]));
5708     return \"ldr%?\\t%0, [%|pc, %1]\t\t@ tls_load_dot_plus_eight\";
5709   "
5710   [(set_attr "predicable" "yes")]
5711 )
5712
5713 ;; PIC references to local variables can generate pic_add_dot_plus_eight
5714 ;; followed by a load.  These sequences can be crunched down to
5715 ;; tls_load_dot_plus_eight by a peephole.
5716
5717 (define_peephole2
5718   [(set (match_operand:SI 0 "register_operand" "")
5719         (unspec:SI [(match_operand:SI 3 "register_operand" "")
5720                     (const_int 8)
5721                     (match_operand 1 "" "")]
5722                    UNSPEC_PIC_BASE))
5723    (set (match_operand:SI 2 "arm_general_register_operand" "")
5724         (mem:SI (match_dup 0)))]
5725   "TARGET_ARM && peep2_reg_dead_p (2, operands[0])"
5726   [(set (match_dup 2)
5727         (mem:SI (unspec:SI [(match_dup 3)
5728                             (const_int 8)
5729                             (match_dup 1)]
5730                            UNSPEC_PIC_BASE)))]
5731   ""
5732 )
5733
5734 (define_insn "pic_offset_arm"
5735   [(set (match_operand:SI 0 "register_operand" "=r")
5736         (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
5737                          (unspec:SI [(match_operand:SI 2 "" "X")]
5738                                     UNSPEC_PIC_OFFSET))))]
5739   "TARGET_VXWORKS_RTP && TARGET_ARM && flag_pic"
5740   "ldr%?\\t%0, [%1,%2]"
5741   [(set_attr "type" "load1")]
5742 )
5743
5744 (define_expand "builtin_setjmp_receiver"
5745   [(label_ref (match_operand 0 "" ""))]
5746   "flag_pic"
5747   "
5748 {
5749   /* r3 is clobbered by set/longjmp, so we can use it as a scratch
5750      register.  */
5751   if (arm_pic_register != INVALID_REGNUM)
5752     arm_load_pic_register (1UL << 3);
5753   DONE;
5754 }")
5755
5756 ;; If copying one reg to another we can set the condition codes according to
5757 ;; its value.  Such a move is common after a return from subroutine and the
5758 ;; result is being tested against zero.
5759
5760 (define_insn "*movsi_compare0"
5761   [(set (reg:CC CC_REGNUM)
5762         (compare:CC (match_operand:SI 1 "s_register_operand" "0,r")
5763                     (const_int 0)))
5764    (set (match_operand:SI 0 "s_register_operand" "=r,r")
5765         (match_dup 1))]
5766   "TARGET_32BIT"
5767   "@
5768    cmp%?\\t%0, #0
5769    sub%.\\t%0, %1, #0"
5770   [(set_attr "conds" "set")]
5771 )
5772
5773 ;; Subroutine to store a half word from a register into memory.
5774 ;; Operand 0 is the source register (HImode)
5775 ;; Operand 1 is the destination address in a register (SImode)
5776
5777 ;; In both this routine and the next, we must be careful not to spill
5778 ;; a memory address of reg+large_const into a separate PLUS insn, since this
5779 ;; can generate unrecognizable rtl.
5780
5781 (define_expand "storehi"
5782   [;; store the low byte
5783    (set (match_operand 1 "" "") (match_dup 3))
5784    ;; extract the high byte
5785    (set (match_dup 2)
5786         (ashiftrt:SI (match_operand 0 "" "") (const_int 8)))
5787    ;; store the high byte
5788    (set (match_dup 4) (match_dup 5))]
5789   "TARGET_ARM"
5790   "
5791   {
5792     rtx op1 = operands[1];
5793     rtx addr = XEXP (op1, 0);
5794     enum rtx_code code = GET_CODE (addr);
5795
5796     if ((code == PLUS && GET_CODE (XEXP (addr, 1)) != CONST_INT)
5797         || code == MINUS)
5798       op1 = replace_equiv_address (operands[1], force_reg (SImode, addr));
5799
5800     operands[4] = adjust_address (op1, QImode, 1);
5801     operands[1] = adjust_address (operands[1], QImode, 0);
5802     operands[3] = gen_lowpart (QImode, operands[0]);
5803     operands[0] = gen_lowpart (SImode, operands[0]);
5804     operands[2] = gen_reg_rtx (SImode);
5805     operands[5] = gen_lowpart (QImode, operands[2]);
5806   }"
5807 )
5808
5809 (define_expand "storehi_bigend"
5810   [(set (match_dup 4) (match_dup 3))
5811    (set (match_dup 2)
5812         (ashiftrt:SI (match_operand 0 "" "") (const_int 8)))
5813    (set (match_operand 1 "" "") (match_dup 5))]
5814   "TARGET_ARM"
5815   "
5816   {
5817     rtx op1 = operands[1];
5818     rtx addr = XEXP (op1, 0);
5819     enum rtx_code code = GET_CODE (addr);
5820
5821     if ((code == PLUS && GET_CODE (XEXP (addr, 1)) != CONST_INT)
5822         || code == MINUS)
5823       op1 = replace_equiv_address (op1, force_reg (SImode, addr));
5824
5825     operands[4] = adjust_address (op1, QImode, 1);
5826     operands[1] = adjust_address (operands[1], QImode, 0);
5827     operands[3] = gen_lowpart (QImode, operands[0]);
5828     operands[0] = gen_lowpart (SImode, operands[0]);
5829     operands[2] = gen_reg_rtx (SImode);
5830     operands[5] = gen_lowpart (QImode, operands[2]);
5831   }"
5832 )
5833
5834 ;; Subroutine to store a half word integer constant into memory.
5835 (define_expand "storeinthi"
5836   [(set (match_operand 0 "" "")
5837         (match_operand 1 "" ""))
5838    (set (match_dup 3) (match_dup 2))]
5839   "TARGET_ARM"
5840   "
5841   {
5842     HOST_WIDE_INT value = INTVAL (operands[1]);
5843     rtx addr = XEXP (operands[0], 0);
5844     rtx op0 = operands[0];
5845     enum rtx_code code = GET_CODE (addr);
5846
5847     if ((code == PLUS && GET_CODE (XEXP (addr, 1)) != CONST_INT)
5848         || code == MINUS)
5849       op0 = replace_equiv_address (op0, force_reg (SImode, addr));
5850
5851     operands[1] = gen_reg_rtx (SImode);
5852     if (BYTES_BIG_ENDIAN)
5853       {
5854         emit_insn (gen_movsi (operands[1], GEN_INT ((value >> 8) & 255)));
5855         if ((value & 255) == ((value >> 8) & 255))
5856           operands[2] = operands[1];
5857         else
5858           {
5859             operands[2] = gen_reg_rtx (SImode);
5860             emit_insn (gen_movsi (operands[2], GEN_INT (value & 255)));
5861           }
5862       }
5863     else
5864       {
5865         emit_insn (gen_movsi (operands[1], GEN_INT (value & 255)));
5866         if ((value & 255) == ((value >> 8) & 255))
5867           operands[2] = operands[1];
5868         else
5869           {
5870             operands[2] = gen_reg_rtx (SImode);
5871             emit_insn (gen_movsi (operands[2], GEN_INT ((value >> 8) & 255)));
5872           }
5873       }
5874
5875     operands[3] = adjust_address (op0, QImode, 1);
5876     operands[0] = adjust_address (operands[0], QImode, 0);
5877     operands[2] = gen_lowpart (QImode, operands[2]);
5878     operands[1] = gen_lowpart (QImode, operands[1]);
5879   }"
5880 )
5881
5882 (define_expand "storehi_single_op"
5883   [(set (match_operand:HI 0 "memory_operand" "")
5884         (match_operand:HI 1 "general_operand" ""))]
5885   "TARGET_32BIT && arm_arch4"
5886   "
5887   if (!s_register_operand (operands[1], HImode))
5888     operands[1] = copy_to_mode_reg (HImode, operands[1]);
5889   "
5890 )
5891
5892 (define_expand "movhi"
5893   [(set (match_operand:HI 0 "general_operand" "")
5894         (match_operand:HI 1 "general_operand" ""))]
5895   "TARGET_EITHER"
5896   "
5897   if (TARGET_ARM)
5898     {
5899       if (can_create_pseudo_p ())
5900         {
5901           if (GET_CODE (operands[0]) == MEM)
5902             {
5903               if (arm_arch4)
5904                 {
5905                   emit_insn (gen_storehi_single_op (operands[0], operands[1]));
5906                   DONE;
5907                 }
5908               if (GET_CODE (operands[1]) == CONST_INT)
5909                 emit_insn (gen_storeinthi (operands[0], operands[1]));
5910               else
5911                 {
5912                   if (GET_CODE (operands[1]) == MEM)
5913                     operands[1] = force_reg (HImode, operands[1]);
5914                   if (BYTES_BIG_ENDIAN)
5915                     emit_insn (gen_storehi_bigend (operands[1], operands[0]));
5916                   else
5917                    emit_insn (gen_storehi (operands[1], operands[0]));
5918                 }
5919               DONE;
5920             }
5921           /* Sign extend a constant, and keep it in an SImode reg.  */
5922           else if (GET_CODE (operands[1]) == CONST_INT)
5923             {
5924               rtx reg = gen_reg_rtx (SImode);
5925               HOST_WIDE_INT val = INTVAL (operands[1]) & 0xffff;
5926
5927               /* If the constant is already valid, leave it alone.  */
5928               if (!const_ok_for_arm (val))
5929                 {
5930                   /* If setting all the top bits will make the constant 
5931                      loadable in a single instruction, then set them.  
5932                      Otherwise, sign extend the number.  */
5933
5934                   if (const_ok_for_arm (~(val | ~0xffff)))
5935                     val |= ~0xffff;
5936                   else if (val & 0x8000)
5937                     val |= ~0xffff;
5938                 }
5939
5940               emit_insn (gen_movsi (reg, GEN_INT (val)));
5941               operands[1] = gen_lowpart (HImode, reg);
5942             }
5943           else if (arm_arch4 && optimize && can_create_pseudo_p ()
5944                    && GET_CODE (operands[1]) == MEM)
5945             {
5946               rtx reg = gen_reg_rtx (SImode);
5947
5948               emit_insn (gen_zero_extendhisi2 (reg, operands[1]));
5949               operands[1] = gen_lowpart (HImode, reg);
5950             }
5951           else if (!arm_arch4)
5952             {
5953               if (GET_CODE (operands[1]) == MEM)
5954                 {
5955                   rtx base;
5956                   rtx offset = const0_rtx;
5957                   rtx reg = gen_reg_rtx (SImode);
5958
5959                   if ((GET_CODE (base = XEXP (operands[1], 0)) == REG
5960                        || (GET_CODE (base) == PLUS
5961                            && (GET_CODE (offset = XEXP (base, 1))
5962                                == CONST_INT)
5963                            && ((INTVAL(offset) & 1) != 1)
5964                            && GET_CODE (base = XEXP (base, 0)) == REG))
5965                       && REGNO_POINTER_ALIGN (REGNO (base)) >= 32)
5966                     {
5967                       rtx new_rtx;
5968
5969                       new_rtx = widen_memory_access (operands[1], SImode,
5970                                                      ((INTVAL (offset) & ~3)
5971                                                       - INTVAL (offset)));
5972                       emit_insn (gen_movsi (reg, new_rtx));
5973                       if (((INTVAL (offset) & 2) != 0)
5974                           ^ (BYTES_BIG_ENDIAN ? 1 : 0))
5975                         {
5976                           rtx reg2 = gen_reg_rtx (SImode);
5977
5978                           emit_insn (gen_lshrsi3 (reg2, reg, GEN_INT (16)));
5979                           reg = reg2;
5980                         }
5981                     }
5982                   else
5983                     emit_insn (gen_movhi_bytes (reg, operands[1]));
5984
5985                   operands[1] = gen_lowpart (HImode, reg);
5986                }
5987            }
5988         }
5989       /* Handle loading a large integer during reload.  */
5990       else if (GET_CODE (operands[1]) == CONST_INT
5991                && !const_ok_for_arm (INTVAL (operands[1]))
5992                && !const_ok_for_arm (~INTVAL (operands[1])))
5993         {
5994           /* Writing a constant to memory needs a scratch, which should
5995              be handled with SECONDARY_RELOADs.  */
5996           gcc_assert (GET_CODE (operands[0]) == REG);
5997
5998           operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
5999           emit_insn (gen_movsi (operands[0], operands[1]));
6000           DONE;
6001        }
6002     }
6003   else if (TARGET_THUMB2)
6004     {
6005       /* Thumb-2 can do everything except mem=mem and mem=const easily.  */
6006       if (can_create_pseudo_p ())
6007         {
6008           if (GET_CODE (operands[0]) != REG)
6009             operands[1] = force_reg (HImode, operands[1]);
6010           /* Zero extend a constant, and keep it in an SImode reg.  */
6011           else if (GET_CODE (operands[1]) == CONST_INT)
6012             {
6013               rtx reg = gen_reg_rtx (SImode);
6014               HOST_WIDE_INT val = INTVAL (operands[1]) & 0xffff;
6015
6016               emit_insn (gen_movsi (reg, GEN_INT (val)));
6017               operands[1] = gen_lowpart (HImode, reg);
6018             }
6019         }
6020     }
6021   else /* TARGET_THUMB1 */
6022     {
6023       if (can_create_pseudo_p ())
6024         {
6025           if (GET_CODE (operands[1]) == CONST_INT)
6026             {
6027               rtx reg = gen_reg_rtx (SImode);
6028
6029               emit_insn (gen_movsi (reg, operands[1]));
6030               operands[1] = gen_lowpart (HImode, reg);
6031             }
6032
6033           /* ??? We shouldn't really get invalid addresses here, but this can
6034              happen if we are passed a SP (never OK for HImode/QImode) or 
6035              virtual register (also rejected as illegitimate for HImode/QImode)
6036              relative address.  */
6037           /* ??? This should perhaps be fixed elsewhere, for instance, in
6038              fixup_stack_1, by checking for other kinds of invalid addresses,
6039              e.g. a bare reference to a virtual register.  This may confuse the
6040              alpha though, which must handle this case differently.  */
6041           if (GET_CODE (operands[0]) == MEM
6042               && !memory_address_p (GET_MODE (operands[0]),
6043                                     XEXP (operands[0], 0)))
6044             operands[0]
6045               = replace_equiv_address (operands[0],
6046                                        copy_to_reg (XEXP (operands[0], 0)));
6047    
6048           if (GET_CODE (operands[1]) == MEM
6049               && !memory_address_p (GET_MODE (operands[1]),
6050                                     XEXP (operands[1], 0)))
6051             operands[1]
6052               = replace_equiv_address (operands[1],
6053                                        copy_to_reg (XEXP (operands[1], 0)));
6054
6055           if (GET_CODE (operands[1]) == MEM && optimize > 0)
6056             {
6057               rtx reg = gen_reg_rtx (SImode);
6058
6059               emit_insn (gen_zero_extendhisi2 (reg, operands[1]));
6060               operands[1] = gen_lowpart (HImode, reg);
6061             }
6062
6063           if (GET_CODE (operands[0]) == MEM)
6064             operands[1] = force_reg (HImode, operands[1]);
6065         }
6066       else if (GET_CODE (operands[1]) == CONST_INT
6067                 && !satisfies_constraint_I (operands[1]))
6068         {
6069           /* Handle loading a large integer during reload.  */
6070
6071           /* Writing a constant to memory needs a scratch, which should
6072              be handled with SECONDARY_RELOADs.  */
6073           gcc_assert (GET_CODE (operands[0]) == REG);
6074
6075           operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
6076           emit_insn (gen_movsi (operands[0], operands[1]));
6077           DONE;
6078         }
6079     }
6080   "
6081 )
6082
6083 (define_insn "*thumb1_movhi_insn"
6084   [(set (match_operand:HI 0 "nonimmediate_operand" "=l,l,m,*r,*h,l")
6085         (match_operand:HI 1 "general_operand"       "l,m,l,*h,*r,I"))]
6086   "TARGET_THUMB1
6087    && (   register_operand (operands[0], HImode)
6088        || register_operand (operands[1], HImode))"
6089   "*
6090   switch (which_alternative)
6091     {
6092     case 0: return \"add        %0, %1, #0\";
6093     case 2: return \"strh       %1, %0\";
6094     case 3: return \"mov        %0, %1\";
6095     case 4: return \"mov        %0, %1\";
6096     case 5: return \"mov        %0, %1\";
6097     default: gcc_unreachable ();
6098     case 1:
6099       /* The stack pointer can end up being taken as an index register.
6100           Catch this case here and deal with it.  */
6101       if (GET_CODE (XEXP (operands[1], 0)) == PLUS
6102           && GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == REG
6103           && REGNO    (XEXP (XEXP (operands[1], 0), 0)) == SP_REGNUM)
6104         {
6105           rtx ops[2];
6106           ops[0] = operands[0];
6107           ops[1] = XEXP (XEXP (operands[1], 0), 0);
6108       
6109           output_asm_insn (\"mov        %0, %1\", ops);
6110
6111           XEXP (XEXP (operands[1], 0), 0) = operands[0];
6112     
6113         }
6114       return \"ldrh     %0, %1\";
6115     }"
6116   [(set_attr "length" "2,4,2,2,2,2")
6117    (set_attr "type" "*,load1,store1,*,*,*")
6118    (set_attr "conds" "clob,nocond,nocond,nocond,nocond,clob")])
6119
6120
6121 (define_expand "movhi_bytes"
6122   [(set (match_dup 2) (zero_extend:SI (match_operand:HI 1 "" "")))
6123    (set (match_dup 3)
6124         (zero_extend:SI (match_dup 6)))
6125    (set (match_operand:SI 0 "" "")
6126          (ior:SI (ashift:SI (match_dup 4) (const_int 8)) (match_dup 5)))]
6127   "TARGET_ARM"
6128   "
6129   {
6130     rtx mem1, mem2;
6131     rtx addr = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
6132
6133     mem1 = change_address (operands[1], QImode, addr);
6134     mem2 = change_address (operands[1], QImode, plus_constant (addr, 1));
6135     operands[0] = gen_lowpart (SImode, operands[0]);
6136     operands[1] = mem1;
6137     operands[2] = gen_reg_rtx (SImode);
6138     operands[3] = gen_reg_rtx (SImode);
6139     operands[6] = mem2;
6140
6141     if (BYTES_BIG_ENDIAN)
6142       {
6143         operands[4] = operands[2];
6144         operands[5] = operands[3];
6145       }
6146     else
6147       {
6148         operands[4] = operands[3];
6149         operands[5] = operands[2];
6150       }
6151   }"
6152 )
6153
6154 (define_expand "movhi_bigend"
6155   [(set (match_dup 2)
6156         (rotate:SI (subreg:SI (match_operand:HI 1 "memory_operand" "") 0)
6157                    (const_int 16)))
6158    (set (match_dup 3)
6159         (ashiftrt:SI (match_dup 2) (const_int 16)))
6160    (set (match_operand:HI 0 "s_register_operand" "")
6161         (match_dup 4))]
6162   "TARGET_ARM"
6163   "
6164   operands[2] = gen_reg_rtx (SImode);
6165   operands[3] = gen_reg_rtx (SImode);
6166   operands[4] = gen_lowpart (HImode, operands[3]);
6167   "
6168 )
6169
6170 ;; Pattern to recognize insn generated default case above
6171 (define_insn "*movhi_insn_arch4"
6172   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,m,r")
6173         (match_operand:HI 1 "general_operand"      "rI,K,r,mi"))]
6174   "TARGET_ARM
6175    && arm_arch4
6176    && (register_operand (operands[0], HImode)
6177        || register_operand (operands[1], HImode))"
6178   "@
6179    mov%?\\t%0, %1\\t%@ movhi
6180    mvn%?\\t%0, #%B1\\t%@ movhi
6181    str%(h%)\\t%1, %0\\t%@ movhi
6182    ldr%(h%)\\t%0, %1\\t%@ movhi"
6183   [(set_attr "type" "*,*,store1,load1")
6184    (set_attr "predicable" "yes")
6185    (set_attr "insn" "mov,mvn,*,*")
6186    (set_attr "pool_range" "*,*,*,256")
6187    (set_attr "neg_pool_range" "*,*,*,244")]
6188 )
6189
6190 (define_insn "*movhi_bytes"
6191   [(set (match_operand:HI 0 "s_register_operand" "=r,r")
6192         (match_operand:HI 1 "arm_rhs_operand"  "rI,K"))]
6193   "TARGET_ARM"
6194   "@
6195    mov%?\\t%0, %1\\t%@ movhi
6196    mvn%?\\t%0, #%B1\\t%@ movhi"
6197   [(set_attr "predicable" "yes")
6198    (set_attr "insn" "mov,mvn")]
6199 )
6200
6201 (define_expand "thumb_movhi_clobber"
6202   [(set (match_operand:HI     0 "memory_operand"   "")
6203         (match_operand:HI     1 "register_operand" ""))
6204    (clobber (match_operand:DI 2 "register_operand" ""))]
6205   "TARGET_THUMB1"
6206   "
6207   if (strict_memory_address_p (HImode, XEXP (operands[0], 0))
6208       && REGNO (operands[1]) <= LAST_LO_REGNUM)
6209     {
6210       emit_insn (gen_movhi (operands[0], operands[1]));
6211       DONE;
6212     }
6213   /* XXX Fixme, need to handle other cases here as well.  */
6214   gcc_unreachable ();
6215   "
6216 )
6217         
6218 ;; We use a DImode scratch because we may occasionally need an additional
6219 ;; temporary if the address isn't offsettable -- push_reload doesn't seem
6220 ;; to take any notice of the "o" constraints on reload_memory_operand operand.
6221 (define_expand "reload_outhi"
6222   [(parallel [(match_operand:HI 0 "arm_reload_memory_operand" "=o")
6223               (match_operand:HI 1 "s_register_operand"        "r")
6224               (match_operand:DI 2 "s_register_operand"        "=&l")])]
6225   "TARGET_EITHER"
6226   "if (TARGET_ARM)
6227      arm_reload_out_hi (operands);
6228    else
6229      thumb_reload_out_hi (operands);
6230   DONE;
6231   "
6232 )
6233
6234 (define_expand "reload_inhi"
6235   [(parallel [(match_operand:HI 0 "s_register_operand" "=r")
6236               (match_operand:HI 1 "arm_reload_memory_operand" "o")
6237               (match_operand:DI 2 "s_register_operand" "=&r")])]
6238   "TARGET_EITHER"
6239   "
6240   if (TARGET_ARM)
6241     arm_reload_in_hi (operands);
6242   else
6243     thumb_reload_out_hi (operands);
6244   DONE;
6245 ")
6246
6247 (define_expand "movqi"
6248   [(set (match_operand:QI 0 "general_operand" "")
6249         (match_operand:QI 1 "general_operand" ""))]
6250   "TARGET_EITHER"
6251   "
6252   /* Everything except mem = const or mem = mem can be done easily */
6253
6254   if (can_create_pseudo_p ())
6255     {
6256       if (GET_CODE (operands[1]) == CONST_INT)
6257         {
6258           rtx reg = gen_reg_rtx (SImode);
6259
6260           /* For thumb we want an unsigned immediate, then we are more likely 
6261              to be able to use a movs insn.  */
6262           if (TARGET_THUMB)
6263             operands[1] = GEN_INT (INTVAL (operands[1]) & 255);
6264
6265           emit_insn (gen_movsi (reg, operands[1]));
6266           operands[1] = gen_lowpart (QImode, reg);
6267         }
6268
6269       if (TARGET_THUMB)
6270         {
6271           /* ??? We shouldn't really get invalid addresses here, but this can
6272              happen if we are passed a SP (never OK for HImode/QImode) or
6273              virtual register (also rejected as illegitimate for HImode/QImode)
6274              relative address.  */
6275           /* ??? This should perhaps be fixed elsewhere, for instance, in
6276              fixup_stack_1, by checking for other kinds of invalid addresses,
6277              e.g. a bare reference to a virtual register.  This may confuse the
6278              alpha though, which must handle this case differently.  */
6279           if (GET_CODE (operands[0]) == MEM
6280               && !memory_address_p (GET_MODE (operands[0]),
6281                                      XEXP (operands[0], 0)))
6282             operands[0]
6283               = replace_equiv_address (operands[0],
6284                                        copy_to_reg (XEXP (operands[0], 0)));
6285           if (GET_CODE (operands[1]) == MEM
6286               && !memory_address_p (GET_MODE (operands[1]),
6287                                     XEXP (operands[1], 0)))
6288              operands[1]
6289                = replace_equiv_address (operands[1],
6290                                         copy_to_reg (XEXP (operands[1], 0)));
6291         }
6292
6293       if (GET_CODE (operands[1]) == MEM && optimize > 0)
6294         {
6295           rtx reg = gen_reg_rtx (SImode);
6296
6297           emit_insn (gen_zero_extendqisi2 (reg, operands[1]));
6298           operands[1] = gen_lowpart (QImode, reg);
6299         }
6300
6301       if (GET_CODE (operands[0]) == MEM)
6302         operands[1] = force_reg (QImode, operands[1]);
6303     }
6304   else if (TARGET_THUMB
6305            && GET_CODE (operands[1]) == CONST_INT
6306            && !satisfies_constraint_I (operands[1]))
6307     {
6308       /* Handle loading a large integer during reload.  */
6309
6310       /* Writing a constant to memory needs a scratch, which should
6311          be handled with SECONDARY_RELOADs.  */
6312       gcc_assert (GET_CODE (operands[0]) == REG);
6313
6314       operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
6315       emit_insn (gen_movsi (operands[0], operands[1]));
6316       DONE;
6317     }
6318   "
6319 )
6320
6321
6322 (define_insn "*arm_movqi_insn"
6323   [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,l,Uu,r,m")
6324         (match_operand:QI 1 "general_operand" "rI,K,Uu,l,m,r"))]
6325   "TARGET_32BIT
6326    && (   register_operand (operands[0], QImode)
6327        || register_operand (operands[1], QImode))"
6328   "@
6329    mov%?\\t%0, %1
6330    mvn%?\\t%0, #%B1
6331    ldr%(b%)\\t%0, %1
6332    str%(b%)\\t%1, %0
6333    ldr%(b%)\\t%0, %1
6334    str%(b%)\\t%1, %0"
6335   [(set_attr "type" "*,*,load1,store1,load1,store1")
6336    (set_attr "insn" "mov,mvn,*,*,*,*")
6337    (set_attr "predicable" "yes")
6338    (set_attr "arch" "any,any,t2,t2,any,any")
6339    (set_attr "length" "4,4,2,2,4,4")]
6340 )
6341
6342 (define_insn "*thumb1_movqi_insn"
6343   [(set (match_operand:QI 0 "nonimmediate_operand" "=l,l,m,*r,*h,l")
6344         (match_operand:QI 1 "general_operand"      "l, m,l,*h,*r,I"))]
6345   "TARGET_THUMB1
6346    && (   register_operand (operands[0], QImode)
6347        || register_operand (operands[1], QImode))"
6348   "@
6349    add\\t%0, %1, #0
6350    ldrb\\t%0, %1
6351    strb\\t%1, %0
6352    mov\\t%0, %1
6353    mov\\t%0, %1
6354    mov\\t%0, %1"
6355   [(set_attr "length" "2")
6356    (set_attr "type" "*,load1,store1,*,*,*")
6357    (set_attr "insn" "*,*,*,mov,mov,mov")
6358    (set_attr "pool_range" "*,32,*,*,*,*")
6359    (set_attr "conds" "clob,nocond,nocond,nocond,nocond,clob")])
6360
6361 ;; HFmode moves
6362 (define_expand "movhf"
6363   [(set (match_operand:HF 0 "general_operand" "")
6364         (match_operand:HF 1 "general_operand" ""))]
6365   "TARGET_EITHER"
6366   "
6367   if (TARGET_32BIT)
6368     {
6369       if (GET_CODE (operands[0]) == MEM)
6370         operands[1] = force_reg (HFmode, operands[1]);
6371     }
6372   else /* TARGET_THUMB1 */
6373     {
6374       if (can_create_pseudo_p ())
6375         {
6376            if (GET_CODE (operands[0]) != REG)
6377              operands[1] = force_reg (HFmode, operands[1]);
6378         }
6379     }
6380   "
6381 )
6382
6383 (define_insn "*arm32_movhf"
6384   [(set (match_operand:HF 0 "nonimmediate_operand" "=r,m,r,r")
6385         (match_operand:HF 1 "general_operand"      " m,r,r,F"))]
6386   "TARGET_32BIT && !(TARGET_HARD_FLOAT && TARGET_FP16)
6387    && (   s_register_operand (operands[0], HFmode)
6388        || s_register_operand (operands[1], HFmode))"
6389   "*
6390   switch (which_alternative)
6391     {
6392     case 0:     /* ARM register from memory */
6393       return \"ldr%(h%)\\t%0, %1\\t%@ __fp16\";
6394     case 1:     /* memory from ARM register */
6395       return \"str%(h%)\\t%1, %0\\t%@ __fp16\";
6396     case 2:     /* ARM register from ARM register */
6397       return \"mov%?\\t%0, %1\\t%@ __fp16\";
6398     case 3:     /* ARM register from constant */
6399       {
6400         REAL_VALUE_TYPE r;
6401         long bits;
6402         rtx ops[4];
6403
6404         REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
6405         bits = real_to_target (NULL, &r, HFmode);
6406         ops[0] = operands[0];
6407         ops[1] = GEN_INT (bits);
6408         ops[2] = GEN_INT (bits & 0xff00);
6409         ops[3] = GEN_INT (bits & 0x00ff);
6410
6411         if (arm_arch_thumb2)
6412           output_asm_insn (\"movw%?\\t%0, %1\", ops);
6413         else
6414           output_asm_insn (\"mov%?\\t%0, %2\;orr%?\\t%0, %0, %3\", ops);
6415         return \"\";
6416        }
6417     default:
6418       gcc_unreachable ();
6419     }
6420   "
6421   [(set_attr "conds" "unconditional")
6422    (set_attr "type" "load1,store1,*,*")
6423    (set_attr "insn" "*,*,mov,mov")
6424    (set_attr "length" "4,4,4,8")
6425    (set_attr "predicable" "yes")]
6426 )
6427
6428 (define_insn "*thumb1_movhf"
6429   [(set (match_operand:HF     0 "nonimmediate_operand" "=l,l,m,*r,*h")
6430         (match_operand:HF     1 "general_operand"      "l,mF,l,*h,*r"))]
6431   "TARGET_THUMB1
6432    && (   s_register_operand (operands[0], HFmode) 
6433        || s_register_operand (operands[1], HFmode))"
6434   "*
6435   switch (which_alternative)
6436     {
6437     case 1:
6438       {
6439         rtx addr;
6440         gcc_assert (GET_CODE(operands[1]) == MEM);
6441         addr = XEXP (operands[1], 0);
6442         if (GET_CODE (addr) == LABEL_REF
6443             || (GET_CODE (addr) == CONST
6444                 && GET_CODE (XEXP (addr, 0)) == PLUS
6445                 && GET_CODE (XEXP (XEXP (addr, 0), 0)) == LABEL_REF
6446                 && GET_CODE (XEXP (XEXP (addr, 0), 1)) == CONST_INT))
6447           {
6448             /* Constant pool entry.  */
6449             return \"ldr\\t%0, %1\";
6450           }
6451         return \"ldrh\\t%0, %1\";
6452       }
6453     case 2: return \"strh\\t%1, %0\";
6454     default: return \"mov\\t%0, %1\";
6455     }
6456   "
6457   [(set_attr "length" "2")
6458    (set_attr "type" "*,load1,store1,*,*")
6459    (set_attr "insn" "mov,*,*,mov,mov")
6460    (set_attr "pool_range" "*,1020,*,*,*")
6461    (set_attr "conds" "clob,nocond,nocond,nocond,nocond")])
6462
6463 (define_expand "movsf"
6464   [(set (match_operand:SF 0 "general_operand" "")
6465         (match_operand:SF 1 "general_operand" ""))]
6466   "TARGET_EITHER"
6467   "
6468   if (TARGET_32BIT)
6469     {
6470       if (GET_CODE (operands[0]) == MEM)
6471         operands[1] = force_reg (SFmode, operands[1]);
6472     }
6473   else /* TARGET_THUMB1 */
6474     {
6475       if (can_create_pseudo_p ())
6476         {
6477            if (GET_CODE (operands[0]) != REG)
6478              operands[1] = force_reg (SFmode, operands[1]);
6479         }
6480     }
6481   "
6482 )
6483
6484 ;; Transform a floating-point move of a constant into a core register into
6485 ;; an SImode operation.
6486 (define_split
6487   [(set (match_operand:SF 0 "arm_general_register_operand" "")
6488         (match_operand:SF 1 "immediate_operand" ""))]
6489   "TARGET_EITHER
6490    && reload_completed
6491    && GET_CODE (operands[1]) == CONST_DOUBLE"
6492   [(set (match_dup 2) (match_dup 3))]
6493   "
6494   operands[2] = gen_lowpart (SImode, operands[0]);
6495   operands[3] = gen_lowpart (SImode, operands[1]);
6496   if (operands[2] == 0 || operands[3] == 0)
6497     FAIL;
6498   "
6499 )
6500
6501 (define_insn "*arm_movsf_soft_insn"
6502   [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,m")
6503         (match_operand:SF 1 "general_operand"  "r,mE,r"))]
6504   "TARGET_32BIT
6505    && TARGET_SOFT_FLOAT
6506    && (GET_CODE (operands[0]) != MEM
6507        || register_operand (operands[1], SFmode))"
6508   "@
6509    mov%?\\t%0, %1
6510    ldr%?\\t%0, %1\\t%@ float
6511    str%?\\t%1, %0\\t%@ float"
6512   [(set_attr "predicable" "yes")
6513    (set_attr "type" "*,load1,store1")
6514    (set_attr "insn" "mov,*,*")
6515    (set_attr "pool_range" "*,4096,*")
6516    (set_attr "arm_neg_pool_range" "*,4084,*")
6517    (set_attr "thumb2_neg_pool_range" "*,0,*")]
6518 )
6519
6520 ;;; ??? This should have alternatives for constants.
6521 (define_insn "*thumb1_movsf_insn"
6522   [(set (match_operand:SF     0 "nonimmediate_operand" "=l,l,>,l, m,*r,*h")
6523         (match_operand:SF     1 "general_operand"      "l, >,l,mF,l,*h,*r"))]
6524   "TARGET_THUMB1
6525    && (   register_operand (operands[0], SFmode) 
6526        || register_operand (operands[1], SFmode))"
6527   "@
6528    add\\t%0, %1, #0
6529    ldmia\\t%1, {%0}
6530    stmia\\t%0, {%1}
6531    ldr\\t%0, %1
6532    str\\t%1, %0
6533    mov\\t%0, %1
6534    mov\\t%0, %1"
6535   [(set_attr "length" "2")
6536    (set_attr "type" "*,load1,store1,load1,store1,*,*")
6537    (set_attr "pool_range" "*,*,*,1020,*,*,*")
6538    (set_attr "insn" "*,*,*,*,*,mov,mov")
6539    (set_attr "conds" "clob,nocond,nocond,nocond,nocond,nocond,nocond")]
6540 )
6541
6542 (define_expand "movdf"
6543   [(set (match_operand:DF 0 "general_operand" "")
6544         (match_operand:DF 1 "general_operand" ""))]
6545   "TARGET_EITHER"
6546   "
6547   if (TARGET_32BIT)
6548     {
6549       if (GET_CODE (operands[0]) == MEM)
6550         operands[1] = force_reg (DFmode, operands[1]);
6551     }
6552   else /* TARGET_THUMB */
6553     {
6554       if (can_create_pseudo_p ())
6555         {
6556           if (GET_CODE (operands[0]) != REG)
6557             operands[1] = force_reg (DFmode, operands[1]);
6558         }
6559     }
6560   "
6561 )
6562
6563 ;; Reloading a df mode value stored in integer regs to memory can require a
6564 ;; scratch reg.
6565 (define_expand "reload_outdf"
6566   [(match_operand:DF 0 "arm_reload_memory_operand" "=o")
6567    (match_operand:DF 1 "s_register_operand" "r")
6568    (match_operand:SI 2 "s_register_operand" "=&r")]
6569   "TARGET_THUMB2"
6570   "
6571   {
6572     enum rtx_code code = GET_CODE (XEXP (operands[0], 0));
6573
6574     if (code == REG)
6575       operands[2] = XEXP (operands[0], 0);
6576     else if (code == POST_INC || code == PRE_DEC)
6577       {
6578         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
6579         operands[1] = gen_rtx_SUBREG (DImode, operands[1], 0);
6580         emit_insn (gen_movdi (operands[0], operands[1]));
6581         DONE;
6582       }
6583     else if (code == PRE_INC)
6584       {
6585         rtx reg = XEXP (XEXP (operands[0], 0), 0);
6586
6587         emit_insn (gen_addsi3 (reg, reg, GEN_INT (8)));
6588         operands[2] = reg;
6589       }
6590     else if (code == POST_DEC)
6591       operands[2] = XEXP (XEXP (operands[0], 0), 0);
6592     else
6593       emit_insn (gen_addsi3 (operands[2], XEXP (XEXP (operands[0], 0), 0),
6594                              XEXP (XEXP (operands[0], 0), 1)));
6595
6596     emit_insn (gen_rtx_SET (VOIDmode,
6597                             replace_equiv_address (operands[0], operands[2]),
6598                             operands[1]));
6599
6600     if (code == POST_DEC)
6601       emit_insn (gen_addsi3 (operands[2], operands[2], GEN_INT (-8)));
6602
6603     DONE;
6604   }"
6605 )
6606
6607 (define_insn "*movdf_soft_insn"
6608   [(set (match_operand:DF 0 "nonimmediate_soft_df_operand" "=r,r,r,r,m")
6609         (match_operand:DF 1 "soft_df_operand" "rDa,Db,Dc,mF,r"))]
6610   "TARGET_32BIT && TARGET_SOFT_FLOAT
6611    && (   register_operand (operands[0], DFmode)
6612        || register_operand (operands[1], DFmode))"
6613   "*
6614   switch (which_alternative)
6615     {
6616     case 0:
6617     case 1:
6618     case 2:
6619       return \"#\";
6620     default:
6621       return output_move_double (operands, true, NULL);
6622     }
6623   "
6624   [(set_attr "length" "8,12,16,8,8")
6625    (set_attr "type" "*,*,*,load2,store2")
6626    (set_attr "pool_range" "*,*,*,1020,*")
6627    (set_attr "arm_neg_pool_range" "*,*,*,1004,*")
6628    (set_attr "thumb2_neg_pool_range" "*,*,*,0,*")]
6629 )
6630
6631 ;;; ??? This should have alternatives for constants.
6632 ;;; ??? This was originally identical to the movdi_insn pattern.
6633 ;;; ??? The 'F' constraint looks funny, but it should always be replaced by
6634 ;;; thumb_reorg with a memory reference.
6635 (define_insn "*thumb_movdf_insn"
6636   [(set (match_operand:DF 0 "nonimmediate_operand" "=l,l,>,l, m,*r")
6637         (match_operand:DF 1 "general_operand"      "l, >,l,mF,l,*r"))]
6638   "TARGET_THUMB1
6639    && (   register_operand (operands[0], DFmode)
6640        || register_operand (operands[1], DFmode))"
6641   "*
6642   switch (which_alternative)
6643     {
6644     default:
6645     case 0:
6646       if (REGNO (operands[1]) == REGNO (operands[0]) + 1)
6647         return \"add\\t%0, %1, #0\;add\\t%H0, %H1, #0\";
6648       return \"add\\t%H0, %H1, #0\;add\\t%0, %1, #0\";
6649     case 1:
6650       return \"ldmia\\t%1, {%0, %H0}\";
6651     case 2:
6652       return \"stmia\\t%0, {%1, %H1}\";
6653     case 3:
6654       return thumb_load_double_from_address (operands);
6655     case 4:
6656       operands[2] = gen_rtx_MEM (SImode,
6657                                  plus_constant (XEXP (operands[0], 0), 4));
6658       output_asm_insn (\"str\\t%1, %0\;str\\t%H1, %2\", operands);
6659       return \"\";
6660     case 5:
6661       if (REGNO (operands[1]) == REGNO (operands[0]) + 1)
6662         return \"mov\\t%0, %1\;mov\\t%H0, %H1\";
6663       return \"mov\\t%H0, %H1\;mov\\t%0, %1\";
6664     }
6665   "
6666   [(set_attr "length" "4,2,2,6,4,4")
6667    (set_attr "type" "*,load2,store2,load2,store2,*")
6668    (set_attr "insn" "*,*,*,*,*,mov")
6669    (set_attr "pool_range" "*,*,*,1020,*,*")]
6670 )
6671
6672 (define_expand "movxf"
6673   [(set (match_operand:XF 0 "general_operand" "")
6674         (match_operand:XF 1 "general_operand" ""))]
6675   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_FPA"
6676   "
6677   if (GET_CODE (operands[0]) == MEM)
6678     operands[1] = force_reg (XFmode, operands[1]);
6679   "
6680 )
6681
6682 \f
6683
6684 ;; load- and store-multiple insns
6685 ;; The arm can load/store any set of registers, provided that they are in
6686 ;; ascending order, but these expanders assume a contiguous set.
6687
6688 (define_expand "load_multiple"
6689   [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
6690                           (match_operand:SI 1 "" ""))
6691                      (use (match_operand:SI 2 "" ""))])]
6692   "TARGET_32BIT"
6693 {
6694   HOST_WIDE_INT offset = 0;
6695
6696   /* Support only fixed point registers.  */
6697   if (GET_CODE (operands[2]) != CONST_INT
6698       || INTVAL (operands[2]) > 14
6699       || INTVAL (operands[2]) < 2
6700       || GET_CODE (operands[1]) != MEM
6701       || GET_CODE (operands[0]) != REG
6702       || REGNO (operands[0]) > (LAST_ARM_REGNUM - 1)
6703       || REGNO (operands[0]) + INTVAL (operands[2]) > LAST_ARM_REGNUM)
6704     FAIL;
6705
6706   operands[3]
6707     = arm_gen_load_multiple (arm_regs_in_sequence + REGNO (operands[0]),
6708                              INTVAL (operands[2]),
6709                              force_reg (SImode, XEXP (operands[1], 0)),
6710                              FALSE, operands[1], &offset);
6711 })
6712
6713 (define_expand "store_multiple"
6714   [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
6715                           (match_operand:SI 1 "" ""))
6716                      (use (match_operand:SI 2 "" ""))])]
6717   "TARGET_32BIT"
6718 {
6719   HOST_WIDE_INT offset = 0;
6720
6721   /* Support only fixed point registers.  */
6722   if (GET_CODE (operands[2]) != CONST_INT
6723       || INTVAL (operands[2]) > 14
6724       || INTVAL (operands[2]) < 2
6725       || GET_CODE (operands[1]) != REG
6726       || GET_CODE (operands[0]) != MEM
6727       || REGNO (operands[1]) > (LAST_ARM_REGNUM - 1)
6728       || REGNO (operands[1]) + INTVAL (operands[2]) > LAST_ARM_REGNUM)
6729     FAIL;
6730
6731   operands[3]
6732     = arm_gen_store_multiple (arm_regs_in_sequence + REGNO (operands[1]),
6733                               INTVAL (operands[2]),
6734                               force_reg (SImode, XEXP (operands[0], 0)),
6735                               FALSE, operands[0], &offset);
6736 })
6737
6738
6739 ;; Move a block of memory if it is word aligned and MORE than 2 words long.
6740 ;; We could let this apply for blocks of less than this, but it clobbers so
6741 ;; many registers that there is then probably a better way.
6742
6743 (define_expand "movmemqi"
6744   [(match_operand:BLK 0 "general_operand" "")
6745    (match_operand:BLK 1 "general_operand" "")
6746    (match_operand:SI 2 "const_int_operand" "")
6747    (match_operand:SI 3 "const_int_operand" "")]
6748   "TARGET_EITHER"
6749   "
6750   if (TARGET_32BIT)
6751     {
6752       if (arm_gen_movmemqi (operands))
6753         DONE;
6754       FAIL;
6755     }
6756   else /* TARGET_THUMB1 */
6757     {
6758       if (   INTVAL (operands[3]) != 4
6759           || INTVAL (operands[2]) > 48)
6760         FAIL;
6761
6762       thumb_expand_movmemqi (operands);
6763       DONE;
6764     }
6765   "
6766 )
6767
6768 ;; Thumb block-move insns
6769
6770 (define_insn "movmem12b"
6771   [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
6772         (mem:SI (match_operand:SI 3 "register_operand" "1")))
6773    (set (mem:SI (plus:SI (match_dup 2) (const_int 4)))
6774         (mem:SI (plus:SI (match_dup 3) (const_int 4))))
6775    (set (mem:SI (plus:SI (match_dup 2) (const_int 8)))
6776         (mem:SI (plus:SI (match_dup 3) (const_int 8))))
6777    (set (match_operand:SI 0 "register_operand" "=l")
6778         (plus:SI (match_dup 2) (const_int 12)))
6779    (set (match_operand:SI 1 "register_operand" "=l")
6780         (plus:SI (match_dup 3) (const_int 12)))
6781    (clobber (match_scratch:SI 4 "=&l"))
6782    (clobber (match_scratch:SI 5 "=&l"))
6783    (clobber (match_scratch:SI 6 "=&l"))]
6784   "TARGET_THUMB1"
6785   "* return thumb_output_move_mem_multiple (3, operands);"
6786   [(set_attr "length" "4")
6787    ; This isn't entirely accurate...  It loads as well, but in terms of
6788    ; scheduling the following insn it is better to consider it as a store
6789    (set_attr "type" "store3")]
6790 )
6791
6792 (define_insn "movmem8b"
6793   [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
6794         (mem:SI (match_operand:SI 3 "register_operand" "1")))
6795    (set (mem:SI (plus:SI (match_dup 2) (const_int 4)))
6796         (mem:SI (plus:SI (match_dup 3) (const_int 4))))
6797    (set (match_operand:SI 0 "register_operand" "=l")
6798         (plus:SI (match_dup 2) (const_int 8)))
6799    (set (match_operand:SI 1 "register_operand" "=l")
6800         (plus:SI (match_dup 3) (const_int 8)))
6801    (clobber (match_scratch:SI 4 "=&l"))
6802    (clobber (match_scratch:SI 5 "=&l"))]
6803   "TARGET_THUMB1"
6804   "* return thumb_output_move_mem_multiple (2, operands);"
6805   [(set_attr "length" "4")
6806    ; This isn't entirely accurate...  It loads as well, but in terms of
6807    ; scheduling the following insn it is better to consider it as a store
6808    (set_attr "type" "store2")]
6809 )
6810
6811 \f
6812
6813 ;; Compare & branch insns
6814 ;; The range calculations are based as follows:
6815 ;; For forward branches, the address calculation returns the address of
6816 ;; the next instruction.  This is 2 beyond the branch instruction.
6817 ;; For backward branches, the address calculation returns the address of
6818 ;; the first instruction in this pattern (cmp).  This is 2 before the branch
6819 ;; instruction for the shortest sequence, and 4 before the branch instruction
6820 ;; if we have to jump around an unconditional branch.
6821 ;; To the basic branch range the PC offset must be added (this is +4).
6822 ;; So for forward branches we have 
6823 ;;   (pos_range - pos_base_offs + pc_offs) = (pos_range - 2 + 4).
6824 ;; And for backward branches we have 
6825 ;;   (neg_range - neg_base_offs + pc_offs) = (neg_range - (-2 or -4) + 4).
6826 ;;
6827 ;; For a 'b'       pos_range = 2046, neg_range = -2048 giving (-2040->2048).
6828 ;; For a 'b<cond>' pos_range = 254,  neg_range = -256  giving (-250 ->256).
6829
6830 (define_expand "cbranchsi4"
6831   [(set (pc) (if_then_else
6832               (match_operator 0 "expandable_comparison_operator"
6833                [(match_operand:SI 1 "s_register_operand" "")
6834                 (match_operand:SI 2 "nonmemory_operand" "")])
6835               (label_ref (match_operand 3 "" ""))
6836               (pc)))]
6837   "TARGET_THUMB1 || TARGET_32BIT"
6838   "
6839   if (!TARGET_THUMB1)
6840     {
6841       if (!arm_add_operand (operands[2], SImode))
6842         operands[2] = force_reg (SImode, operands[2]);
6843       emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
6844                                       operands[3]));
6845       DONE;
6846     }
6847   if (thumb1_cmpneg_operand (operands[2], SImode))
6848     {
6849       emit_jump_insn (gen_cbranchsi4_scratch (NULL, operands[1], operands[2],
6850                                               operands[3], operands[0]));
6851       DONE;
6852     }
6853   if (!thumb1_cmp_operand (operands[2], SImode))
6854     operands[2] = force_reg (SImode, operands[2]);
6855   ")
6856
6857 ;; A pattern to recognize a special situation and optimize for it.
6858 ;; On the thumb, zero-extension from memory is preferrable to sign-extension
6859 ;; due to the available addressing modes.  Hence, convert a signed comparison
6860 ;; with zero into an unsigned comparison with 127 if possible.
6861 (define_expand "cbranchqi4"
6862   [(set (pc) (if_then_else
6863               (match_operator 0 "lt_ge_comparison_operator"
6864                [(match_operand:QI 1 "memory_operand" "")
6865                 (match_operand:QI 2 "const0_operand" "")])
6866               (label_ref (match_operand 3 "" ""))
6867               (pc)))]
6868   "TARGET_THUMB1"
6869 {
6870   rtx xops[4];
6871   xops[1] = gen_reg_rtx (SImode);
6872   emit_insn (gen_zero_extendqisi2 (xops[1], operands[1]));
6873   xops[2] = GEN_INT (127);
6874   xops[0] = gen_rtx_fmt_ee (GET_CODE (operands[0]) == GE ? LEU : GTU,
6875                             VOIDmode, xops[1], xops[2]);
6876   xops[3] = operands[3];
6877   emit_insn (gen_cbranchsi4 (xops[0], xops[1], xops[2], xops[3]));
6878   DONE;
6879 })
6880
6881 (define_expand "cbranchsf4"
6882   [(set (pc) (if_then_else
6883               (match_operator 0 "expandable_comparison_operator"
6884                [(match_operand:SF 1 "s_register_operand" "")
6885                 (match_operand:SF 2 "arm_float_compare_operand" "")])
6886               (label_ref (match_operand 3 "" ""))
6887               (pc)))]
6888   "TARGET_32BIT && TARGET_HARD_FLOAT"
6889   "emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
6890                                    operands[3])); DONE;"
6891 )
6892
6893 (define_expand "cbranchdf4"
6894   [(set (pc) (if_then_else
6895               (match_operator 0 "expandable_comparison_operator"
6896                [(match_operand:DF 1 "s_register_operand" "")
6897                 (match_operand:DF 2 "arm_float_compare_operand" "")])
6898               (label_ref (match_operand 3 "" ""))
6899               (pc)))]
6900   "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
6901   "emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
6902                                    operands[3])); DONE;"
6903 )
6904
6905 (define_expand "cbranchdi4"
6906   [(set (pc) (if_then_else
6907               (match_operator 0 "expandable_comparison_operator"
6908                [(match_operand:DI 1 "cmpdi_operand" "")
6909                 (match_operand:DI 2 "cmpdi_operand" "")])
6910               (label_ref (match_operand 3 "" ""))
6911               (pc)))]
6912   "TARGET_32BIT"
6913   "{
6914      rtx swap = NULL_RTX;
6915      enum rtx_code code = GET_CODE (operands[0]);
6916
6917      /* We should not have two constants.  */
6918      gcc_assert (GET_MODE (operands[1]) == DImode
6919                  || GET_MODE (operands[2]) == DImode);
6920
6921     /* Flip unimplemented DImode comparisons to a form that
6922        arm_gen_compare_reg can handle.  */
6923      switch (code)
6924      {
6925      case GT:
6926        swap = gen_rtx_LT (VOIDmode, operands[2], operands[1]); break;
6927      case LE:
6928        swap = gen_rtx_GE (VOIDmode, operands[2], operands[1]); break;
6929      case GTU:
6930        swap = gen_rtx_LTU (VOIDmode, operands[2], operands[1]); break;
6931      case LEU:
6932        swap = gen_rtx_GEU (VOIDmode, operands[2], operands[1]); break;
6933      default:
6934        break;
6935      }
6936      if (swap)
6937        emit_jump_insn (gen_cbranch_cc (swap, operands[2], operands[1],
6938                                        operands[3]));
6939      else
6940        emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
6941                                        operands[3]));
6942      DONE;
6943    }"
6944 )
6945
6946 (define_insn "cbranchsi4_insn"
6947   [(set (pc) (if_then_else
6948               (match_operator 0 "arm_comparison_operator"
6949                [(match_operand:SI 1 "s_register_operand" "l,l*h")
6950                 (match_operand:SI 2 "thumb1_cmp_operand" "lI*h,*r")])
6951               (label_ref (match_operand 3 "" ""))
6952               (pc)))]
6953   "TARGET_THUMB1"
6954 {
6955   rtx t = cfun->machine->thumb1_cc_insn;
6956   if (t != NULL_RTX)
6957     {
6958       if (!rtx_equal_p (cfun->machine->thumb1_cc_op0, operands[1])
6959           || !rtx_equal_p (cfun->machine->thumb1_cc_op1, operands[2]))
6960         t = NULL_RTX;
6961       if (cfun->machine->thumb1_cc_mode == CC_NOOVmode)
6962         {
6963           if (!noov_comparison_operator (operands[0], VOIDmode))
6964             t = NULL_RTX;
6965         }
6966       else if (cfun->machine->thumb1_cc_mode != CCmode)
6967         t = NULL_RTX;
6968     }
6969   if (t == NULL_RTX)
6970     {
6971       output_asm_insn ("cmp\t%1, %2", operands);
6972       cfun->machine->thumb1_cc_insn = insn;
6973       cfun->machine->thumb1_cc_op0 = operands[1];
6974       cfun->machine->thumb1_cc_op1 = operands[2];
6975       cfun->machine->thumb1_cc_mode = CCmode;
6976     }
6977   else
6978     /* Ensure we emit the right type of condition code on the jump.  */
6979     XEXP (operands[0], 0) = gen_rtx_REG (cfun->machine->thumb1_cc_mode,
6980                                          CC_REGNUM);
6981
6982   switch (get_attr_length (insn))
6983     {
6984     case 4:  return \"b%d0\\t%l3\";
6985     case 6:  return \"b%D0\\t.LCB%=\;b\\t%l3\\t%@long jump\\n.LCB%=:\";
6986     default: return \"b%D0\\t.LCB%=\;bl\\t%l3\\t%@far jump\\n.LCB%=:\";
6987     }
6988 }
6989   [(set (attr "far_jump")
6990         (if_then_else
6991             (eq_attr "length" "8")
6992             (const_string "yes")
6993             (const_string "no")))
6994    (set (attr "length") 
6995         (if_then_else
6996             (and (ge (minus (match_dup 3) (pc)) (const_int -250))
6997                  (le (minus (match_dup 3) (pc)) (const_int 256)))
6998             (const_int 4)
6999             (if_then_else
7000                 (and (ge (minus (match_dup 3) (pc)) (const_int -2040))
7001                      (le (minus (match_dup 3) (pc)) (const_int 2048)))
7002                 (const_int 6)
7003                 (const_int 8))))]
7004 )
7005
7006 (define_insn "cbranchsi4_scratch"
7007   [(set (pc) (if_then_else
7008               (match_operator 4 "arm_comparison_operator"
7009                [(match_operand:SI 1 "s_register_operand" "l,0")
7010                 (match_operand:SI 2 "thumb1_cmpneg_operand" "L,J")])
7011               (label_ref (match_operand 3 "" ""))
7012               (pc)))
7013    (clobber (match_scratch:SI 0 "=l,l"))]
7014   "TARGET_THUMB1"
7015   "*
7016   output_asm_insn (\"add\\t%0, %1, #%n2\", operands);
7017
7018   switch (get_attr_length (insn))
7019     {
7020     case 4:  return \"b%d4\\t%l3\";
7021     case 6:  return \"b%D4\\t.LCB%=\;b\\t%l3\\t%@long jump\\n.LCB%=:\";
7022     default: return \"b%D4\\t.LCB%=\;bl\\t%l3\\t%@far jump\\n.LCB%=:\";
7023     }
7024   "
7025   [(set (attr "far_jump")
7026         (if_then_else
7027             (eq_attr "length" "8")
7028             (const_string "yes")
7029             (const_string "no")))
7030    (set (attr "length") 
7031         (if_then_else
7032             (and (ge (minus (match_dup 3) (pc)) (const_int -250))
7033                  (le (minus (match_dup 3) (pc)) (const_int 256)))
7034             (const_int 4)
7035             (if_then_else
7036                 (and (ge (minus (match_dup 3) (pc)) (const_int -2040))
7037                      (le (minus (match_dup 3) (pc)) (const_int 2048)))
7038                 (const_int 6)
7039                 (const_int 8))))]
7040 )
7041
7042 ;; Two peepholes to generate subtract of 0 instead of a move if the
7043 ;; condition codes will be useful.
7044 (define_peephole2
7045   [(set (match_operand:SI 0 "low_register_operand" "")
7046         (match_operand:SI 1 "low_register_operand" ""))
7047    (set (pc)
7048         (if_then_else (match_operator 2 "arm_comparison_operator"
7049                        [(match_dup 1) (const_int 0)])
7050                       (label_ref (match_operand 3 "" ""))
7051                       (pc)))]
7052   "TARGET_THUMB1"
7053   [(set (match_dup 0) (minus:SI (match_dup 1) (const_int 0)))
7054    (set (pc)
7055         (if_then_else (match_op_dup 2 [(match_dup 0) (const_int 0)])
7056                       (label_ref (match_dup 3))
7057                       (pc)))]
7058   "")
7059
7060 ;; Sigh!  This variant shouldn't be needed, but combine often fails to
7061 ;; merge cases like this because the op1 is a hard register in
7062 ;; arm_class_likely_spilled_p.
7063 (define_peephole2
7064   [(set (match_operand:SI 0 "low_register_operand" "")
7065         (match_operand:SI 1 "low_register_operand" ""))
7066    (set (pc)
7067         (if_then_else (match_operator 2 "arm_comparison_operator"
7068                        [(match_dup 0) (const_int 0)])
7069                       (label_ref (match_operand 3 "" ""))
7070                       (pc)))]
7071   "TARGET_THUMB1"
7072   [(set (match_dup 0) (minus:SI (match_dup 1) (const_int 0)))
7073    (set (pc)
7074         (if_then_else (match_op_dup 2 [(match_dup 0) (const_int 0)])
7075                       (label_ref (match_dup 3))
7076                       (pc)))]
7077   "")
7078
7079 (define_insn "*negated_cbranchsi4"
7080   [(set (pc)
7081         (if_then_else
7082          (match_operator 0 "equality_operator"
7083           [(match_operand:SI 1 "s_register_operand" "l")
7084            (neg:SI (match_operand:SI 2 "s_register_operand" "l"))])
7085          (label_ref (match_operand 3 "" ""))
7086          (pc)))]
7087   "TARGET_THUMB1"
7088   "*
7089   output_asm_insn (\"cmn\\t%1, %2\", operands);
7090   switch (get_attr_length (insn))
7091     {
7092     case 4:  return \"b%d0\\t%l3\";
7093     case 6:  return \"b%D0\\t.LCB%=\;b\\t%l3\\t%@long jump\\n.LCB%=:\";
7094     default: return \"b%D0\\t.LCB%=\;bl\\t%l3\\t%@far jump\\n.LCB%=:\";
7095     }
7096   "
7097   [(set (attr "far_jump")
7098         (if_then_else
7099             (eq_attr "length" "8")
7100             (const_string "yes")
7101             (const_string "no")))
7102    (set (attr "length") 
7103         (if_then_else
7104             (and (ge (minus (match_dup 3) (pc)) (const_int -250))
7105                  (le (minus (match_dup 3) (pc)) (const_int 256)))
7106             (const_int 4)
7107             (if_then_else
7108                 (and (ge (minus (match_dup 3) (pc)) (const_int -2040))
7109                      (le (minus (match_dup 3) (pc)) (const_int 2048)))
7110                 (const_int 6)
7111                 (const_int 8))))]
7112 )
7113
7114 (define_insn "*tbit_cbranch"
7115   [(set (pc)
7116         (if_then_else
7117          (match_operator 0 "equality_operator"
7118           [(zero_extract:SI (match_operand:SI 1 "s_register_operand" "l")
7119                             (const_int 1)
7120                             (match_operand:SI 2 "const_int_operand" "i"))
7121            (const_int 0)])
7122          (label_ref (match_operand 3 "" ""))
7123          (pc)))
7124    (clobber (match_scratch:SI 4 "=l"))]
7125   "TARGET_THUMB1"
7126   "*
7127   {
7128   rtx op[3];
7129   op[0] = operands[4];
7130   op[1] = operands[1];
7131   op[2] = GEN_INT (32 - 1 - INTVAL (operands[2]));
7132
7133   output_asm_insn (\"lsl\\t%0, %1, %2\", op);
7134   switch (get_attr_length (insn))
7135     {
7136     case 4:  return \"b%d0\\t%l3\";
7137     case 6:  return \"b%D0\\t.LCB%=\;b\\t%l3\\t%@long jump\\n.LCB%=:\";
7138     default: return \"b%D0\\t.LCB%=\;bl\\t%l3\\t%@far jump\\n.LCB%=:\";
7139     }
7140   }"
7141   [(set (attr "far_jump")
7142         (if_then_else
7143             (eq_attr "length" "8")
7144             (const_string "yes")
7145             (const_string "no")))
7146    (set (attr "length") 
7147         (if_then_else
7148             (and (ge (minus (match_dup 3) (pc)) (const_int -250))
7149                  (le (minus (match_dup 3) (pc)) (const_int 256)))
7150             (const_int 4)
7151             (if_then_else
7152                 (and (ge (minus (match_dup 3) (pc)) (const_int -2040))
7153                      (le (minus (match_dup 3) (pc)) (const_int 2048)))
7154                 (const_int 6)
7155                 (const_int 8))))]
7156 )
7157   
7158 (define_insn "*tlobits_cbranch"
7159   [(set (pc)
7160         (if_then_else
7161          (match_operator 0 "equality_operator"
7162           [(zero_extract:SI (match_operand:SI 1 "s_register_operand" "l")
7163                             (match_operand:SI 2 "const_int_operand" "i")
7164                             (const_int 0))
7165            (const_int 0)])
7166          (label_ref (match_operand 3 "" ""))
7167          (pc)))
7168    (clobber (match_scratch:SI 4 "=l"))]
7169   "TARGET_THUMB1"
7170   "*
7171   {
7172   rtx op[3];
7173   op[0] = operands[4];
7174   op[1] = operands[1];
7175   op[2] = GEN_INT (32 - INTVAL (operands[2]));
7176
7177   output_asm_insn (\"lsl\\t%0, %1, %2\", op);
7178   switch (get_attr_length (insn))
7179     {
7180     case 4:  return \"b%d0\\t%l3\";
7181     case 6:  return \"b%D0\\t.LCB%=\;b\\t%l3\\t%@long jump\\n.LCB%=:\";
7182     default: return \"b%D0\\t.LCB%=\;bl\\t%l3\\t%@far jump\\n.LCB%=:\";
7183     }
7184   }"
7185   [(set (attr "far_jump")
7186         (if_then_else
7187             (eq_attr "length" "8")
7188             (const_string "yes")
7189             (const_string "no")))
7190    (set (attr "length") 
7191         (if_then_else
7192             (and (ge (minus (match_dup 3) (pc)) (const_int -250))
7193                  (le (minus (match_dup 3) (pc)) (const_int 256)))
7194             (const_int 4)
7195             (if_then_else
7196                 (and (ge (minus (match_dup 3) (pc)) (const_int -2040))
7197                      (le (minus (match_dup 3) (pc)) (const_int 2048)))
7198                 (const_int 6)
7199                 (const_int 8))))]
7200 )
7201
7202 (define_insn "*tstsi3_cbranch"
7203   [(set (pc)
7204         (if_then_else
7205          (match_operator 3 "equality_operator"
7206           [(and:SI (match_operand:SI 0 "s_register_operand" "%l")
7207                    (match_operand:SI 1 "s_register_operand" "l"))
7208            (const_int 0)])
7209          (label_ref (match_operand 2 "" ""))
7210          (pc)))]
7211   "TARGET_THUMB1"
7212   "*
7213   {
7214   output_asm_insn (\"tst\\t%0, %1\", operands);
7215   switch (get_attr_length (insn))
7216     {
7217     case 4:  return \"b%d3\\t%l2\";
7218     case 6:  return \"b%D3\\t.LCB%=\;b\\t%l2\\t%@long jump\\n.LCB%=:\";
7219     default: return \"b%D3\\t.LCB%=\;bl\\t%l2\\t%@far jump\\n.LCB%=:\";
7220     }
7221   }"
7222   [(set (attr "far_jump")
7223         (if_then_else
7224             (eq_attr "length" "8")
7225             (const_string "yes")
7226             (const_string "no")))
7227    (set (attr "length") 
7228         (if_then_else
7229             (and (ge (minus (match_dup 2) (pc)) (const_int -250))
7230                  (le (minus (match_dup 2) (pc)) (const_int 256)))
7231             (const_int 4)
7232             (if_then_else
7233                 (and (ge (minus (match_dup 2) (pc)) (const_int -2040))
7234                      (le (minus (match_dup 2) (pc)) (const_int 2048)))
7235                 (const_int 6)
7236                 (const_int 8))))]
7237 )
7238   
7239 (define_insn "*cbranchne_decr1"
7240   [(set (pc)
7241         (if_then_else (match_operator 3 "equality_operator"
7242                        [(match_operand:SI 2 "s_register_operand" "l,l,1,l")
7243                         (const_int 0)])
7244                       (label_ref (match_operand 4 "" ""))
7245                       (pc)))
7246    (set (match_operand:SI 0 "thumb_cbrch_target_operand" "=l,*?h,*?m,*?m")
7247         (plus:SI (match_dup 2) (const_int -1)))
7248    (clobber (match_scratch:SI 1 "=X,l,&l,&l"))]
7249   "TARGET_THUMB1"
7250   "*
7251    {
7252      rtx cond[2];
7253      cond[0] = gen_rtx_fmt_ee ((GET_CODE (operands[3]) == NE
7254                                 ? GEU : LTU),
7255                                VOIDmode, operands[2], const1_rtx);
7256      cond[1] = operands[4];
7257
7258      if (which_alternative == 0)
7259        output_asm_insn (\"sub\\t%0, %2, #1\", operands);
7260      else if (which_alternative == 1)
7261        {
7262          /* We must provide an alternative for a hi reg because reload 
7263             cannot handle output reloads on a jump instruction, but we
7264             can't subtract into that.  Fortunately a mov from lo to hi
7265             does not clobber the condition codes.  */
7266          output_asm_insn (\"sub\\t%1, %2, #1\", operands);
7267          output_asm_insn (\"mov\\t%0, %1\", operands);
7268        }
7269      else
7270        {
7271          /* Similarly, but the target is memory.  */
7272          output_asm_insn (\"sub\\t%1, %2, #1\", operands);
7273          output_asm_insn (\"str\\t%1, %0\", operands);
7274        }
7275
7276      switch (get_attr_length (insn) - (which_alternative ? 2 : 0))
7277        {
7278          case 4:
7279            output_asm_insn (\"b%d0\\t%l1\", cond);
7280            return \"\";
7281          case 6:
7282            output_asm_insn (\"b%D0\\t.LCB%=\", cond);
7283            return \"b\\t%l4\\t%@long jump\\n.LCB%=:\";
7284          default:
7285            output_asm_insn (\"b%D0\\t.LCB%=\", cond);
7286            return \"bl\\t%l4\\t%@far jump\\n.LCB%=:\";
7287        }
7288    }
7289   "
7290   [(set (attr "far_jump")
7291         (if_then_else
7292             (ior (and (eq (symbol_ref ("which_alternative"))
7293                           (const_int 0))
7294                       (eq_attr "length" "8"))
7295                  (eq_attr "length" "10"))
7296             (const_string "yes")
7297             (const_string "no")))
7298    (set_attr_alternative "length"
7299       [
7300        ;; Alternative 0
7301        (if_then_else
7302          (and (ge (minus (match_dup 4) (pc)) (const_int -250))
7303               (le (minus (match_dup 4) (pc)) (const_int 256)))
7304          (const_int 4)
7305          (if_then_else
7306            (and (ge (minus (match_dup 4) (pc)) (const_int -2040))
7307                 (le (minus (match_dup 4) (pc)) (const_int 2048)))
7308            (const_int 6)
7309            (const_int 8)))
7310        ;; Alternative 1
7311        (if_then_else
7312          (and (ge (minus (match_dup 4) (pc)) (const_int -248))
7313               (le (minus (match_dup 4) (pc)) (const_int 256)))
7314          (const_int 6)
7315          (if_then_else
7316            (and (ge (minus (match_dup 4) (pc)) (const_int -2038))
7317                 (le (minus (match_dup 4) (pc)) (const_int 2048)))
7318            (const_int 8)
7319            (const_int 10)))
7320        ;; Alternative 2
7321        (if_then_else
7322          (and (ge (minus (match_dup 4) (pc)) (const_int -248))
7323               (le (minus (match_dup 4) (pc)) (const_int 256)))
7324          (const_int 6)
7325          (if_then_else
7326            (and (ge (minus (match_dup 4) (pc)) (const_int -2038))
7327                 (le (minus (match_dup 4) (pc)) (const_int 2048)))
7328            (const_int 8)
7329            (const_int 10)))
7330        ;; Alternative 3
7331        (if_then_else
7332          (and (ge (minus (match_dup 4) (pc)) (const_int -248))
7333               (le (minus (match_dup 4) (pc)) (const_int 256)))
7334          (const_int 6)
7335          (if_then_else
7336            (and (ge (minus (match_dup 4) (pc)) (const_int -2038))
7337                 (le (minus (match_dup 4) (pc)) (const_int 2048)))
7338            (const_int 8)
7339            (const_int 10)))])]
7340 )
7341
7342 (define_insn "*addsi3_cbranch"
7343   [(set (pc)
7344         (if_then_else
7345          (match_operator 4 "arm_comparison_operator"
7346           [(plus:SI
7347             (match_operand:SI 2 "s_register_operand" "%0,l,*l,1,1,1")
7348             (match_operand:SI 3 "reg_or_int_operand" "IJ,lL,*l,lIJ,lIJ,lIJ"))
7349            (const_int 0)])
7350          (label_ref (match_operand 5 "" ""))
7351          (pc)))
7352    (set
7353     (match_operand:SI 0 "thumb_cbrch_target_operand" "=l,l,*!h,*?h,*?m,*?m")
7354     (plus:SI (match_dup 2) (match_dup 3)))
7355    (clobber (match_scratch:SI 1 "=X,X,l,l,&l,&l"))]
7356   "TARGET_THUMB1
7357    && (GET_CODE (operands[4]) == EQ
7358        || GET_CODE (operands[4]) == NE
7359        || GET_CODE (operands[4]) == GE
7360        || GET_CODE (operands[4]) == LT)"
7361   "*
7362    {
7363      rtx cond[3];
7364
7365      cond[0] = (which_alternative < 2) ? operands[0] : operands[1];
7366      cond[1] = operands[2];
7367      cond[2] = operands[3];
7368
7369      if (GET_CODE (cond[2]) == CONST_INT && INTVAL (cond[2]) < 0)
7370        output_asm_insn (\"sub\\t%0, %1, #%n2\", cond);
7371      else
7372        output_asm_insn (\"add\\t%0, %1, %2\", cond);
7373
7374      if (which_alternative >= 2
7375          && which_alternative < 4)
7376        output_asm_insn (\"mov\\t%0, %1\", operands);
7377      else if (which_alternative >= 4)
7378        output_asm_insn (\"str\\t%1, %0\", operands);
7379
7380      switch (get_attr_length (insn) - ((which_alternative >= 2) ? 2 : 0))
7381        {
7382          case 4:
7383            return \"b%d4\\t%l5\";
7384          case 6:
7385            return \"b%D4\\t.LCB%=\;b\\t%l5\\t%@long jump\\n.LCB%=:\";
7386          default:
7387            return \"b%D4\\t.LCB%=\;bl\\t%l5\\t%@far jump\\n.LCB%=:\";
7388        }
7389    }
7390   "
7391   [(set (attr "far_jump")
7392         (if_then_else
7393             (ior (and (lt (symbol_ref ("which_alternative"))
7394                           (const_int 2))
7395                       (eq_attr "length" "8"))
7396                  (eq_attr "length" "10"))
7397             (const_string "yes")
7398             (const_string "no")))
7399    (set (attr "length")
7400      (if_then_else
7401        (lt (symbol_ref ("which_alternative"))
7402                        (const_int 2))
7403        (if_then_else
7404          (and (ge (minus (match_dup 5) (pc)) (const_int -250))
7405               (le (minus (match_dup 5) (pc)) (const_int 256)))
7406          (const_int 4)
7407          (if_then_else
7408            (and (ge (minus (match_dup 5) (pc)) (const_int -2040))
7409                 (le (minus (match_dup 5) (pc)) (const_int 2048)))
7410            (const_int 6)
7411            (const_int 8)))
7412        (if_then_else
7413          (and (ge (minus (match_dup 5) (pc)) (const_int -248))
7414               (le (minus (match_dup 5) (pc)) (const_int 256)))
7415          (const_int 6)
7416          (if_then_else
7417            (and (ge (minus (match_dup 5) (pc)) (const_int -2038))
7418                 (le (minus (match_dup 5) (pc)) (const_int 2048)))
7419            (const_int 8)
7420            (const_int 10)))))]
7421 )
7422
7423 (define_insn "*addsi3_cbranch_scratch"
7424   [(set (pc)
7425         (if_then_else
7426          (match_operator 3 "arm_comparison_operator"
7427           [(plus:SI
7428             (match_operand:SI 1 "s_register_operand" "%l,l,l,0")
7429             (match_operand:SI 2 "reg_or_int_operand" "J,l,L,IJ"))
7430            (const_int 0)])
7431          (label_ref (match_operand 4 "" ""))
7432          (pc)))
7433    (clobber (match_scratch:SI 0 "=X,X,l,l"))]
7434   "TARGET_THUMB1
7435    && (GET_CODE (operands[3]) == EQ
7436        || GET_CODE (operands[3]) == NE
7437        || GET_CODE (operands[3]) == GE
7438        || GET_CODE (operands[3]) == LT)"
7439   "*
7440    {
7441      switch (which_alternative)
7442        {
7443        case 0:
7444          output_asm_insn (\"cmp\t%1, #%n2\", operands);
7445          break;
7446        case 1:
7447          output_asm_insn (\"cmn\t%1, %2\", operands);
7448          break;
7449        case 2:
7450          if (INTVAL (operands[2]) < 0)
7451            output_asm_insn (\"sub\t%0, %1, %2\", operands);
7452          else
7453            output_asm_insn (\"add\t%0, %1, %2\", operands);
7454          break;
7455        case 3:
7456          if (INTVAL (operands[2]) < 0)
7457            output_asm_insn (\"sub\t%0, %0, %2\", operands);
7458          else
7459            output_asm_insn (\"add\t%0, %0, %2\", operands);
7460          break;
7461        }
7462
7463      switch (get_attr_length (insn))
7464        {
7465          case 4:
7466            return \"b%d3\\t%l4\";
7467          case 6:
7468            return \"b%D3\\t.LCB%=\;b\\t%l4\\t%@long jump\\n.LCB%=:\";
7469          default:
7470            return \"b%D3\\t.LCB%=\;bl\\t%l4\\t%@far jump\\n.LCB%=:\";
7471        }
7472    }
7473   "
7474   [(set (attr "far_jump")
7475         (if_then_else
7476             (eq_attr "length" "8")
7477             (const_string "yes")
7478             (const_string "no")))
7479    (set (attr "length")
7480        (if_then_else
7481          (and (ge (minus (match_dup 4) (pc)) (const_int -250))
7482               (le (minus (match_dup 4) (pc)) (const_int 256)))
7483          (const_int 4)
7484          (if_then_else
7485            (and (ge (minus (match_dup 4) (pc)) (const_int -2040))
7486                 (le (minus (match_dup 4) (pc)) (const_int 2048)))
7487            (const_int 6)
7488            (const_int 8))))]
7489 )
7490
7491
7492 ;; Comparison and test insns
7493
7494 (define_insn "*arm_cmpsi_insn"
7495   [(set (reg:CC CC_REGNUM)
7496         (compare:CC (match_operand:SI 0 "s_register_operand" "l,r,r,r")
7497                     (match_operand:SI 1 "arm_add_operand"    "Py,r,rI,L")))]
7498   "TARGET_32BIT"
7499   "@
7500    cmp%?\\t%0, %1
7501    cmp%?\\t%0, %1
7502    cmp%?\\t%0, %1
7503    cmn%?\\t%0, #%n1"
7504   [(set_attr "conds" "set")
7505    (set_attr "arch" "t2,t2,any,any")
7506    (set_attr "length" "2,2,4,4")
7507    (set_attr "predicable" "yes")]
7508 )
7509
7510 (define_insn "*cmpsi_shiftsi"
7511   [(set (reg:CC CC_REGNUM)
7512         (compare:CC (match_operand:SI   0 "s_register_operand" "r,r")
7513                     (match_operator:SI  3 "shift_operator"
7514                      [(match_operand:SI 1 "s_register_operand" "r,r")
7515                       (match_operand:SI 2 "shift_amount_operand" "M,rM")])))]
7516   "TARGET_32BIT"
7517   "cmp%?\\t%0, %1%S3"
7518   [(set_attr "conds" "set")
7519    (set_attr "shift" "1")
7520    (set_attr "arch" "32,a")
7521    (set_attr "type" "alu_shift,alu_shift_reg")])
7522
7523 (define_insn "*cmpsi_shiftsi_swp"
7524   [(set (reg:CC_SWP CC_REGNUM)
7525         (compare:CC_SWP (match_operator:SI 3 "shift_operator"
7526                          [(match_operand:SI 1 "s_register_operand" "r,r")
7527                           (match_operand:SI 2 "shift_amount_operand" "M,rM")])
7528                         (match_operand:SI 0 "s_register_operand" "r,r")))]
7529   "TARGET_32BIT"
7530   "cmp%?\\t%0, %1%S3"
7531   [(set_attr "conds" "set")
7532    (set_attr "shift" "1")
7533    (set_attr "arch" "32,a")
7534    (set_attr "type" "alu_shift,alu_shift_reg")])
7535
7536 (define_insn "*arm_cmpsi_negshiftsi_si"
7537   [(set (reg:CC_Z CC_REGNUM)
7538         (compare:CC_Z
7539          (neg:SI (match_operator:SI 1 "shift_operator"
7540                     [(match_operand:SI 2 "s_register_operand" "r")
7541                      (match_operand:SI 3 "reg_or_int_operand" "rM")]))
7542          (match_operand:SI 0 "s_register_operand" "r")))]
7543   "TARGET_ARM"
7544   "cmn%?\\t%0, %2%S1"
7545   [(set_attr "conds" "set")
7546    (set (attr "type") (if_then_else (match_operand 3 "const_int_operand" "")
7547                                     (const_string "alu_shift")
7548                                     (const_string "alu_shift_reg")))
7549    (set_attr "predicable" "yes")]
7550 )
7551
7552 ;; DImode comparisons.  The generic code generates branches that
7553 ;; if-conversion can not reduce to a conditional compare, so we do
7554 ;; that directly.
7555
7556 (define_insn "*arm_cmpdi_insn"
7557   [(set (reg:CC_NCV CC_REGNUM)
7558         (compare:CC_NCV (match_operand:DI 0 "s_register_operand" "r")
7559                         (match_operand:DI 1 "arm_di_operand"       "rDi")))
7560    (clobber (match_scratch:SI 2 "=r"))]
7561   "TARGET_32BIT && !(TARGET_HARD_FLOAT && TARGET_MAVERICK)"
7562   "cmp\\t%Q0, %Q1\;sbcs\\t%2, %R0, %R1"
7563   [(set_attr "conds" "set")
7564    (set_attr "length" "8")]
7565 )
7566
7567 (define_insn "*arm_cmpdi_unsigned"
7568   [(set (reg:CC_CZ CC_REGNUM)
7569         (compare:CC_CZ (match_operand:DI 0 "s_register_operand" "r")
7570                        (match_operand:DI 1 "arm_di_operand"     "rDi")))]
7571   "TARGET_32BIT"
7572   "cmp\\t%R0, %R1\;it eq\;cmpeq\\t%Q0, %Q1"
7573   [(set_attr "conds" "set")
7574    (set_attr "length" "8")]
7575 )
7576
7577 (define_insn "*arm_cmpdi_zero"
7578   [(set (reg:CC_Z CC_REGNUM)
7579         (compare:CC_Z (match_operand:DI 0 "s_register_operand" "r")
7580                       (const_int 0)))
7581    (clobber (match_scratch:SI 1 "=r"))]
7582   "TARGET_32BIT"
7583   "orr%.\\t%1, %Q0, %R0"
7584   [(set_attr "conds" "set")]
7585 )
7586
7587 (define_insn "*thumb_cmpdi_zero"
7588   [(set (reg:CC_Z CC_REGNUM)
7589         (compare:CC_Z (match_operand:DI 0 "s_register_operand" "l")
7590                       (const_int 0)))
7591    (clobber (match_scratch:SI 1 "=l"))]
7592   "TARGET_THUMB1"
7593   "orr\\t%1, %Q0, %R0"
7594   [(set_attr "conds" "set")
7595    (set_attr "length" "2")]
7596 )
7597
7598 ;; Cirrus SF compare instruction
7599 (define_insn "*cirrus_cmpsf"
7600   [(set (reg:CCFP CC_REGNUM)
7601         (compare:CCFP (match_operand:SF 0 "cirrus_fp_register" "v")
7602                       (match_operand:SF 1 "cirrus_fp_register" "v")))]
7603   "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_MAVERICK"
7604   "cfcmps%?\\tr15, %V0, %V1"
7605   [(set_attr "type"   "mav_farith")
7606    (set_attr "cirrus" "compare")]
7607 )
7608
7609 ;; Cirrus DF compare instruction
7610 (define_insn "*cirrus_cmpdf"
7611   [(set (reg:CCFP CC_REGNUM)
7612         (compare:CCFP (match_operand:DF 0 "cirrus_fp_register" "v")
7613                       (match_operand:DF 1 "cirrus_fp_register" "v")))]
7614   "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_MAVERICK"
7615   "cfcmpd%?\\tr15, %V0, %V1"
7616   [(set_attr "type"   "mav_farith")
7617    (set_attr "cirrus" "compare")]
7618 )
7619
7620 (define_insn "*cirrus_cmpdi"
7621   [(set (reg:CC CC_REGNUM)
7622         (compare:CC (match_operand:DI 0 "cirrus_fp_register" "v")
7623                     (match_operand:DI 1 "cirrus_fp_register" "v")))]
7624   "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_MAVERICK"
7625   "cfcmp64%?\\tr15, %V0, %V1"
7626   [(set_attr "type"   "mav_farith")
7627    (set_attr "cirrus" "compare")]
7628 )
7629
7630 ; This insn allows redundant compares to be removed by cse, nothing should
7631 ; ever appear in the output file since (set (reg x) (reg x)) is a no-op that
7632 ; is deleted later on. The match_dup will match the mode here, so that
7633 ; mode changes of the condition codes aren't lost by this even though we don't
7634 ; specify what they are.
7635
7636 (define_insn "*deleted_compare"
7637   [(set (match_operand 0 "cc_register" "") (match_dup 0))]
7638   "TARGET_32BIT"
7639   "\\t%@ deleted compare"
7640   [(set_attr "conds" "set")
7641    (set_attr "length" "0")]
7642 )
7643
7644 \f
7645 ;; Conditional branch insns
7646
7647 (define_expand "cbranch_cc"
7648   [(set (pc)
7649         (if_then_else (match_operator 0 "" [(match_operand 1 "" "")
7650                                             (match_operand 2 "" "")])
7651                       (label_ref (match_operand 3 "" ""))
7652                       (pc)))]
7653   "TARGET_32BIT"
7654   "operands[1] = arm_gen_compare_reg (GET_CODE (operands[0]),
7655                                       operands[1], operands[2], NULL_RTX);
7656    operands[2] = const0_rtx;"
7657 )
7658
7659 ;;
7660 ;; Patterns to match conditional branch insns.
7661 ;;
7662
7663 (define_insn "*arm_cond_branch"
7664   [(set (pc)
7665         (if_then_else (match_operator 1 "arm_comparison_operator"
7666                        [(match_operand 2 "cc_register" "") (const_int 0)])
7667                       (label_ref (match_operand 0 "" ""))
7668                       (pc)))]
7669   "TARGET_32BIT"
7670   "*
7671   if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
7672     {
7673       arm_ccfsm_state += 2;
7674       return \"\";
7675     }
7676   return \"b%d1\\t%l0\";
7677   "
7678   [(set_attr "conds" "use")
7679    (set_attr "type" "branch")
7680    (set (attr "length")
7681         (if_then_else
7682            (and (match_test "TARGET_THUMB2")
7683                 (and (ge (minus (match_dup 0) (pc)) (const_int -250))
7684                      (le (minus (match_dup 0) (pc)) (const_int 256))))
7685            (const_int 2)
7686            (const_int 4)))]
7687 )
7688
7689 (define_insn "*arm_cond_branch_reversed"
7690   [(set (pc)
7691         (if_then_else (match_operator 1 "arm_comparison_operator"
7692                        [(match_operand 2 "cc_register" "") (const_int 0)])
7693                       (pc)
7694                       (label_ref (match_operand 0 "" ""))))]
7695   "TARGET_32BIT"
7696   "*
7697   if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
7698     {
7699       arm_ccfsm_state += 2;
7700       return \"\";
7701     }
7702   return \"b%D1\\t%l0\";
7703   "
7704   [(set_attr "conds" "use")
7705    (set_attr "type" "branch")
7706    (set (attr "length")
7707         (if_then_else
7708            (and (match_test "TARGET_THUMB2")
7709                 (and (ge (minus (match_dup 0) (pc)) (const_int -250))
7710                      (le (minus (match_dup 0) (pc)) (const_int 256))))
7711            (const_int 2)
7712            (const_int 4)))]
7713 )
7714
7715 \f
7716
7717 ; scc insns
7718
7719 (define_expand "cstore_cc"
7720   [(set (match_operand:SI 0 "s_register_operand" "")
7721         (match_operator:SI 1 "" [(match_operand 2 "" "")
7722                                  (match_operand 3 "" "")]))]
7723   "TARGET_32BIT"
7724   "operands[2] = arm_gen_compare_reg (GET_CODE (operands[1]),
7725                                       operands[2], operands[3], NULL_RTX);
7726    operands[3] = const0_rtx;"
7727 )
7728
7729 (define_insn "*mov_scc"
7730   [(set (match_operand:SI 0 "s_register_operand" "=r")
7731         (match_operator:SI 1 "arm_comparison_operator"
7732          [(match_operand 2 "cc_register" "") (const_int 0)]))]
7733   "TARGET_ARM"
7734   "mov%D1\\t%0, #0\;mov%d1\\t%0, #1"
7735   [(set_attr "conds" "use")
7736    (set_attr "insn" "mov")
7737    (set_attr "length" "8")]
7738 )
7739
7740 (define_insn "*mov_negscc"
7741   [(set (match_operand:SI 0 "s_register_operand" "=r")
7742         (neg:SI (match_operator:SI 1 "arm_comparison_operator"
7743                  [(match_operand 2 "cc_register" "") (const_int 0)])))]
7744   "TARGET_ARM"
7745   "mov%D1\\t%0, #0\;mvn%d1\\t%0, #0"
7746   [(set_attr "conds" "use")
7747    (set_attr "insn" "mov")
7748    (set_attr "length" "8")]
7749 )
7750
7751 (define_insn "*mov_notscc"
7752   [(set (match_operand:SI 0 "s_register_operand" "=r")
7753         (not:SI (match_operator:SI 1 "arm_comparison_operator"
7754                  [(match_operand 2 "cc_register" "") (const_int 0)])))]
7755   "TARGET_ARM"
7756   "mvn%D1\\t%0, #0\;mvn%d1\\t%0, #1"
7757   [(set_attr "conds" "use")
7758    (set_attr "insn" "mov")
7759    (set_attr "length" "8")]
7760 )
7761
7762 (define_expand "cstoresi4"
7763   [(set (match_operand:SI 0 "s_register_operand" "")
7764         (match_operator:SI 1 "expandable_comparison_operator"
7765          [(match_operand:SI 2 "s_register_operand" "")
7766           (match_operand:SI 3 "reg_or_int_operand" "")]))]
7767   "TARGET_32BIT || TARGET_THUMB1"
7768   "{
7769   rtx op3, scratch, scratch2;
7770
7771   if (!TARGET_THUMB1)
7772     {
7773       if (!arm_add_operand (operands[3], SImode))
7774         operands[3] = force_reg (SImode, operands[3]);
7775       emit_insn (gen_cstore_cc (operands[0], operands[1],
7776                                 operands[2], operands[3]));
7777       DONE;
7778     }
7779
7780   if (operands[3] == const0_rtx)
7781     {
7782       switch (GET_CODE (operands[1]))
7783         {
7784         case EQ:
7785           emit_insn (gen_cstoresi_eq0_thumb1 (operands[0], operands[2]));
7786           break;
7787
7788         case NE:
7789           emit_insn (gen_cstoresi_ne0_thumb1 (operands[0], operands[2]));
7790           break;
7791
7792         case LE:
7793           scratch = expand_binop (SImode, add_optab, operands[2], constm1_rtx,
7794                                   NULL_RTX, 0, OPTAB_WIDEN);
7795           scratch = expand_binop (SImode, ior_optab, operands[2], scratch,
7796                                   NULL_RTX, 0, OPTAB_WIDEN);
7797           expand_binop (SImode, lshr_optab, scratch, GEN_INT (31),
7798                         operands[0], 1, OPTAB_WIDEN);
7799           break;
7800
7801         case GE:
7802           scratch = expand_unop (SImode, one_cmpl_optab, operands[2],
7803                                  NULL_RTX, 1);
7804           expand_binop (SImode, lshr_optab, scratch, GEN_INT (31),
7805                         NULL_RTX, 1, OPTAB_WIDEN);
7806           break;
7807
7808         case GT:
7809           scratch = expand_binop (SImode, ashr_optab, operands[2],
7810                                   GEN_INT (31), NULL_RTX, 0, OPTAB_WIDEN);
7811           scratch = expand_binop (SImode, sub_optab, scratch, operands[2],
7812                                   NULL_RTX, 0, OPTAB_WIDEN);
7813           expand_binop (SImode, lshr_optab, scratch, GEN_INT (31), operands[0],
7814                         0, OPTAB_WIDEN);
7815           break;
7816
7817         /* LT is handled by generic code.  No need for unsigned with 0.  */
7818         default:
7819           FAIL;
7820         }
7821       DONE;
7822     }
7823
7824   switch (GET_CODE (operands[1]))
7825     {
7826     case EQ:
7827       scratch = expand_binop (SImode, sub_optab, operands[2], operands[3],
7828                               NULL_RTX, 0, OPTAB_WIDEN);
7829       emit_insn (gen_cstoresi_eq0_thumb1 (operands[0], scratch));
7830       break;
7831
7832     case NE:
7833       scratch = expand_binop (SImode, sub_optab, operands[2], operands[3],
7834                               NULL_RTX, 0, OPTAB_WIDEN);
7835       emit_insn (gen_cstoresi_ne0_thumb1 (operands[0], scratch));
7836       break;
7837
7838     case LE:
7839       op3 = force_reg (SImode, operands[3]);
7840
7841       scratch = expand_binop (SImode, lshr_optab, operands[2], GEN_INT (31),
7842                               NULL_RTX, 1, OPTAB_WIDEN);
7843       scratch2 = expand_binop (SImode, ashr_optab, op3, GEN_INT (31),
7844                               NULL_RTX, 0, OPTAB_WIDEN);
7845       emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch2,
7846                                           op3, operands[2]));
7847       break;
7848
7849     case GE:
7850       op3 = operands[3];
7851       if (!thumb1_cmp_operand (op3, SImode))
7852         op3 = force_reg (SImode, op3);
7853       scratch = expand_binop (SImode, ashr_optab, operands[2], GEN_INT (31),
7854                               NULL_RTX, 0, OPTAB_WIDEN);
7855       scratch2 = expand_binop (SImode, lshr_optab, op3, GEN_INT (31),
7856                                NULL_RTX, 1, OPTAB_WIDEN);
7857       emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch2,
7858                                           operands[2], op3));
7859       break;
7860
7861     case LEU:
7862       op3 = force_reg (SImode, operands[3]);
7863       scratch = force_reg (SImode, const0_rtx);
7864       emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch,
7865                                           op3, operands[2]));
7866       break;
7867
7868     case GEU:
7869       op3 = operands[3];
7870       if (!thumb1_cmp_operand (op3, SImode))
7871         op3 = force_reg (SImode, op3);
7872       scratch = force_reg (SImode, const0_rtx);
7873       emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch,
7874                                           operands[2], op3));
7875       break;
7876
7877     case LTU:
7878       op3 = operands[3];
7879       if (!thumb1_cmp_operand (op3, SImode))
7880         op3 = force_reg (SImode, op3);
7881       scratch = gen_reg_rtx (SImode);
7882       emit_insn (gen_cstoresi_ltu_thumb1 (operands[0], operands[2], op3));
7883       break;
7884
7885     case GTU:
7886       op3 = force_reg (SImode, operands[3]);
7887       scratch = gen_reg_rtx (SImode);
7888       emit_insn (gen_cstoresi_ltu_thumb1 (operands[0], op3, operands[2]));
7889       break;
7890
7891     /* No good sequences for GT, LT.  */
7892     default:
7893       FAIL;
7894     }
7895   DONE;
7896 }")
7897
7898 (define_expand "cstoresf4"
7899   [(set (match_operand:SI 0 "s_register_operand" "")
7900         (match_operator:SI 1 "expandable_comparison_operator"
7901          [(match_operand:SF 2 "s_register_operand" "")
7902           (match_operand:SF 3 "arm_float_compare_operand" "")]))]
7903   "TARGET_32BIT && TARGET_HARD_FLOAT"
7904   "emit_insn (gen_cstore_cc (operands[0], operands[1],
7905                              operands[2], operands[3])); DONE;"
7906 )
7907
7908 (define_expand "cstoredf4"
7909   [(set (match_operand:SI 0 "s_register_operand" "")
7910         (match_operator:SI 1 "expandable_comparison_operator"
7911          [(match_operand:DF 2 "s_register_operand" "")
7912           (match_operand:DF 3 "arm_float_compare_operand" "")]))]
7913   "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
7914   "emit_insn (gen_cstore_cc (operands[0], operands[1],
7915                              operands[2], operands[3])); DONE;"
7916 )
7917
7918 (define_expand "cstoredi4"
7919   [(set (match_operand:SI 0 "s_register_operand" "")
7920         (match_operator:SI 1 "expandable_comparison_operator"
7921          [(match_operand:DI 2 "cmpdi_operand" "")
7922           (match_operand:DI 3 "cmpdi_operand" "")]))]
7923   "TARGET_32BIT"
7924   "{
7925      rtx swap = NULL_RTX;
7926      enum rtx_code code = GET_CODE (operands[1]);
7927
7928      /* We should not have two constants.  */
7929      gcc_assert (GET_MODE (operands[2]) == DImode
7930                  || GET_MODE (operands[3]) == DImode);
7931
7932     /* Flip unimplemented DImode comparisons to a form that
7933        arm_gen_compare_reg can handle.  */
7934      switch (code)
7935      {
7936      case GT:
7937        swap = gen_rtx_LT (VOIDmode, operands[3], operands[2]); break;
7938      case LE:
7939        swap = gen_rtx_GE (VOIDmode, operands[3], operands[2]); break;
7940      case GTU:
7941        swap = gen_rtx_LTU (VOIDmode, operands[3], operands[2]); break;
7942      case LEU:
7943        swap = gen_rtx_GEU (VOIDmode, operands[3], operands[2]); break;
7944      default:
7945        break;
7946      }
7947      if (swap)
7948        emit_insn (gen_cstore_cc (operands[0], swap, operands[3],
7949                                  operands[2]));
7950      else
7951        emit_insn (gen_cstore_cc (operands[0], operands[1], operands[2],
7952                                  operands[3]));
7953      DONE;
7954    }"
7955 )
7956
7957 (define_expand "cstoresi_eq0_thumb1"
7958   [(parallel
7959     [(set (match_operand:SI 0 "s_register_operand" "")
7960           (eq:SI (match_operand:SI 1 "s_register_operand" "")
7961                  (const_int 0)))
7962      (clobber (match_dup:SI 2))])]
7963   "TARGET_THUMB1"
7964   "operands[2] = gen_reg_rtx (SImode);"
7965 )
7966
7967 (define_expand "cstoresi_ne0_thumb1"
7968   [(parallel
7969     [(set (match_operand:SI 0 "s_register_operand" "")
7970           (ne:SI (match_operand:SI 1 "s_register_operand" "")
7971                  (const_int 0)))
7972      (clobber (match_dup:SI 2))])]
7973   "TARGET_THUMB1"
7974   "operands[2] = gen_reg_rtx (SImode);"
7975 )
7976
7977 (define_insn "*cstoresi_eq0_thumb1_insn"
7978   [(set (match_operand:SI 0 "s_register_operand" "=&l,l")
7979         (eq:SI (match_operand:SI 1 "s_register_operand" "l,0")
7980                (const_int 0)))
7981    (clobber (match_operand:SI 2 "s_register_operand" "=X,l"))]
7982   "TARGET_THUMB1"
7983   "@
7984    neg\\t%0, %1\;adc\\t%0, %0, %1
7985    neg\\t%2, %1\;adc\\t%0, %1, %2"
7986   [(set_attr "length" "4")]
7987 )
7988
7989 (define_insn "*cstoresi_ne0_thumb1_insn"
7990   [(set (match_operand:SI 0 "s_register_operand" "=l")
7991         (ne:SI (match_operand:SI 1 "s_register_operand" "0")
7992                (const_int 0)))
7993    (clobber (match_operand:SI 2 "s_register_operand" "=l"))]
7994   "TARGET_THUMB1"
7995   "sub\\t%2, %1, #1\;sbc\\t%0, %1, %2"
7996   [(set_attr "length" "4")]
7997 )
7998
7999 ;; Used as part of the expansion of thumb ltu and gtu sequences
8000 (define_insn "cstoresi_nltu_thumb1"
8001   [(set (match_operand:SI 0 "s_register_operand" "=l,l")
8002         (neg:SI (ltu:SI (match_operand:SI 1 "s_register_operand" "l,*h")
8003                         (match_operand:SI 2 "thumb1_cmp_operand" "lI*h,*r"))))]
8004   "TARGET_THUMB1"
8005   "cmp\\t%1, %2\;sbc\\t%0, %0, %0"
8006   [(set_attr "length" "4")]
8007 )
8008
8009 (define_insn_and_split "cstoresi_ltu_thumb1"
8010   [(set (match_operand:SI 0 "s_register_operand" "=l,l")
8011         (ltu:SI (match_operand:SI 1 "s_register_operand" "l,*h")
8012                 (match_operand:SI 2 "thumb1_cmp_operand" "lI*h,*r")))]
8013   "TARGET_THUMB1"
8014   "#"
8015   "TARGET_THUMB1"
8016   [(set (match_dup 3)
8017         (neg:SI (ltu:SI (match_dup 1) (match_dup 2))))
8018    (set (match_dup 0) (neg:SI (match_dup 3)))]
8019   "operands[3] = gen_reg_rtx (SImode);"
8020   [(set_attr "length" "4")]
8021 )
8022
8023 ;; Used as part of the expansion of thumb les sequence.
8024 (define_insn "thumb1_addsi3_addgeu"
8025   [(set (match_operand:SI 0 "s_register_operand" "=l")
8026         (plus:SI (plus:SI (match_operand:SI 1 "s_register_operand" "%0")
8027                           (match_operand:SI 2 "s_register_operand" "l"))
8028                  (geu:SI (match_operand:SI 3 "s_register_operand" "l")
8029                          (match_operand:SI 4 "thumb1_cmp_operand" "lI"))))]
8030   "TARGET_THUMB1"
8031   "cmp\\t%3, %4\;adc\\t%0, %1, %2"
8032   [(set_attr "length" "4")]
8033 )
8034
8035 \f
8036 ;; Conditional move insns
8037
8038 (define_expand "movsicc"
8039   [(set (match_operand:SI 0 "s_register_operand" "")
8040         (if_then_else:SI (match_operand 1 "expandable_comparison_operator" "")
8041                          (match_operand:SI 2 "arm_not_operand" "")
8042                          (match_operand:SI 3 "arm_not_operand" "")))]
8043   "TARGET_32BIT"
8044   "
8045   {
8046     enum rtx_code code = GET_CODE (operands[1]);
8047     rtx ccreg;
8048
8049     if (code == UNEQ || code == LTGT)
8050       FAIL;
8051
8052     ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
8053                                  XEXP (operands[1], 1), NULL_RTX);
8054     operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
8055   }"
8056 )
8057
8058 (define_expand "movsfcc"
8059   [(set (match_operand:SF 0 "s_register_operand" "")
8060         (if_then_else:SF (match_operand 1 "expandable_comparison_operator" "")
8061                          (match_operand:SF 2 "s_register_operand" "")
8062                          (match_operand:SF 3 "nonmemory_operand" "")))]
8063   "TARGET_32BIT && TARGET_HARD_FLOAT"
8064   "
8065   {
8066     enum rtx_code code = GET_CODE (operands[1]);
8067     rtx ccreg;
8068
8069     if (code == UNEQ || code == LTGT)
8070       FAIL;
8071
8072     /* When compiling for SOFT_FLOAT, ensure both arms are in registers. 
8073        Otherwise, ensure it is a valid FP add operand */
8074     if ((!(TARGET_HARD_FLOAT && TARGET_FPA))
8075         || (!arm_float_add_operand (operands[3], SFmode)))
8076       operands[3] = force_reg (SFmode, operands[3]);
8077
8078     ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
8079                                  XEXP (operands[1], 1), NULL_RTX);
8080     operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
8081   }"
8082 )
8083
8084 (define_expand "movdfcc"
8085   [(set (match_operand:DF 0 "s_register_operand" "")
8086         (if_then_else:DF (match_operand 1 "expandable_comparison_operator" "")
8087                          (match_operand:DF 2 "s_register_operand" "")
8088                          (match_operand:DF 3 "arm_float_add_operand" "")))]
8089   "TARGET_32BIT && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP_DOUBLE)"
8090   "
8091   {
8092     enum rtx_code code = GET_CODE (operands[1]);
8093     rtx ccreg;
8094
8095     if (code == UNEQ || code == LTGT)
8096       FAIL;
8097
8098     ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
8099                                  XEXP (operands[1], 1), NULL_RTX);
8100     operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
8101   }"
8102 )
8103
8104 (define_insn "*movsicc_insn"
8105   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r,r,r,r,r")
8106         (if_then_else:SI
8107          (match_operator 3 "arm_comparison_operator"
8108           [(match_operand 4 "cc_register" "") (const_int 0)])
8109          (match_operand:SI 1 "arm_not_operand" "0,0,rI,K,rI,rI,K,K")
8110          (match_operand:SI 2 "arm_not_operand" "rI,K,0,0,rI,K,rI,K")))]
8111   "TARGET_ARM"
8112   "@
8113    mov%D3\\t%0, %2
8114    mvn%D3\\t%0, #%B2
8115    mov%d3\\t%0, %1
8116    mvn%d3\\t%0, #%B1
8117    mov%d3\\t%0, %1\;mov%D3\\t%0, %2
8118    mov%d3\\t%0, %1\;mvn%D3\\t%0, #%B2
8119    mvn%d3\\t%0, #%B1\;mov%D3\\t%0, %2
8120    mvn%d3\\t%0, #%B1\;mvn%D3\\t%0, #%B2"
8121   [(set_attr "length" "4,4,4,4,8,8,8,8")
8122    (set_attr "conds" "use")
8123    (set_attr "insn" "mov,mvn,mov,mvn,mov,mov,mvn,mvn")]
8124 )
8125
8126 (define_insn "*movsfcc_soft_insn"
8127   [(set (match_operand:SF 0 "s_register_operand" "=r,r")
8128         (if_then_else:SF (match_operator 3 "arm_comparison_operator"
8129                           [(match_operand 4 "cc_register" "") (const_int 0)])
8130                          (match_operand:SF 1 "s_register_operand" "0,r")
8131                          (match_operand:SF 2 "s_register_operand" "r,0")))]
8132   "TARGET_ARM && TARGET_SOFT_FLOAT"
8133   "@
8134    mov%D3\\t%0, %2
8135    mov%d3\\t%0, %1"
8136   [(set_attr "conds" "use")
8137    (set_attr "insn" "mov")]
8138 )
8139
8140 \f
8141 ;; Jump and linkage insns
8142
8143 (define_expand "jump"
8144   [(set (pc)
8145         (label_ref (match_operand 0 "" "")))]
8146   "TARGET_EITHER"
8147   ""
8148 )
8149
8150 (define_insn "*arm_jump"
8151   [(set (pc)
8152         (label_ref (match_operand 0 "" "")))]
8153   "TARGET_32BIT"
8154   "*
8155   {
8156     if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
8157       {
8158         arm_ccfsm_state += 2;
8159         return \"\";
8160       }
8161     return \"b%?\\t%l0\";
8162   }
8163   "
8164   [(set_attr "predicable" "yes")
8165    (set (attr "length")
8166         (if_then_else
8167            (and (match_test "TARGET_THUMB2")
8168                 (and (ge (minus (match_dup 0) (pc)) (const_int -2044))
8169                      (le (minus (match_dup 0) (pc)) (const_int 2048))))
8170            (const_int 2)
8171            (const_int 4)))]
8172 )
8173
8174 (define_insn "*thumb_jump"
8175   [(set (pc)
8176         (label_ref (match_operand 0 "" "")))]
8177   "TARGET_THUMB1"
8178   "*
8179   if (get_attr_length (insn) == 2)
8180     return \"b\\t%l0\";
8181   return \"bl\\t%l0\\t%@ far jump\";
8182   "
8183   [(set (attr "far_jump")
8184         (if_then_else
8185             (eq_attr "length" "4")
8186             (const_string "yes")
8187             (const_string "no")))
8188    (set (attr "length") 
8189         (if_then_else
8190             (and (ge (minus (match_dup 0) (pc)) (const_int -2044))
8191                  (le (minus (match_dup 0) (pc)) (const_int 2048)))
8192             (const_int 2)
8193             (const_int 4)))]
8194 )
8195
8196 (define_expand "call"
8197   [(parallel [(call (match_operand 0 "memory_operand" "")
8198                     (match_operand 1 "general_operand" ""))
8199               (use (match_operand 2 "" ""))
8200               (clobber (reg:SI LR_REGNUM))])]
8201   "TARGET_EITHER"
8202   "
8203   {
8204     rtx callee, pat;
8205     
8206     /* In an untyped call, we can get NULL for operand 2.  */
8207     if (operands[2] == NULL_RTX)
8208       operands[2] = const0_rtx;
8209       
8210     /* Decide if we should generate indirect calls by loading the
8211        32-bit address of the callee into a register before performing the
8212        branch and link.  */
8213     callee = XEXP (operands[0], 0);
8214     if (GET_CODE (callee) == SYMBOL_REF
8215         ? arm_is_long_call_p (SYMBOL_REF_DECL (callee))
8216         : !REG_P (callee))
8217       XEXP (operands[0], 0) = force_reg (Pmode, callee);
8218
8219     pat = gen_call_internal (operands[0], operands[1], operands[2]);
8220     arm_emit_call_insn (pat, XEXP (operands[0], 0));
8221     DONE;
8222   }"
8223 )
8224
8225 (define_expand "call_internal"
8226   [(parallel [(call (match_operand 0 "memory_operand" "")
8227                     (match_operand 1 "general_operand" ""))
8228               (use (match_operand 2 "" ""))
8229               (clobber (reg:SI LR_REGNUM))])])
8230
8231 (define_insn "*call_reg_armv5"
8232   [(call (mem:SI (match_operand:SI 0 "s_register_operand" "r"))
8233          (match_operand 1 "" ""))
8234    (use (match_operand 2 "" ""))
8235    (clobber (reg:SI LR_REGNUM))]
8236   "TARGET_ARM && arm_arch5"
8237   "blx%?\\t%0"
8238   [(set_attr "type" "call")]
8239 )
8240
8241 (define_insn "*call_reg_arm"
8242   [(call (mem:SI (match_operand:SI 0 "s_register_operand" "r"))
8243          (match_operand 1 "" ""))
8244    (use (match_operand 2 "" ""))
8245    (clobber (reg:SI LR_REGNUM))]
8246   "TARGET_ARM && !arm_arch5"
8247   "*
8248   return output_call (operands);
8249   "
8250   ;; length is worst case, normally it is only two
8251   [(set_attr "length" "12")
8252    (set_attr "type" "call")]
8253 )
8254
8255
8256 ;; Note: not used for armv5+ because the sequence used (ldr pc, ...) is not
8257 ;; considered a function call by the branch predictor of some cores (PR40887).
8258 ;; Falls back to blx rN (*call_reg_armv5).
8259
8260 (define_insn "*call_mem"
8261   [(call (mem:SI (match_operand:SI 0 "call_memory_operand" "m"))
8262          (match_operand 1 "" ""))
8263    (use (match_operand 2 "" ""))
8264    (clobber (reg:SI LR_REGNUM))]
8265   "TARGET_ARM && !arm_arch5"
8266   "*
8267   return output_call_mem (operands);
8268   "
8269   [(set_attr "length" "12")
8270    (set_attr "type" "call")]
8271 )
8272
8273 (define_insn "*call_reg_thumb1_v5"
8274   [(call (mem:SI (match_operand:SI 0 "register_operand" "l*r"))
8275          (match_operand 1 "" ""))
8276    (use (match_operand 2 "" ""))
8277    (clobber (reg:SI LR_REGNUM))]
8278   "TARGET_THUMB1 && arm_arch5"
8279   "blx\\t%0"
8280   [(set_attr "length" "2")
8281    (set_attr "type" "call")]
8282 )
8283
8284 (define_insn "*call_reg_thumb1"
8285   [(call (mem:SI (match_operand:SI 0 "register_operand" "l*r"))
8286          (match_operand 1 "" ""))
8287    (use (match_operand 2 "" ""))
8288    (clobber (reg:SI LR_REGNUM))]
8289   "TARGET_THUMB1 && !arm_arch5"
8290   "*
8291   {
8292     if (!TARGET_CALLER_INTERWORKING)
8293       return thumb_call_via_reg (operands[0]);
8294     else if (operands[1] == const0_rtx)
8295       return \"bl\\t%__interwork_call_via_%0\";
8296     else if (frame_pointer_needed)
8297       return \"bl\\t%__interwork_r7_call_via_%0\";
8298     else
8299       return \"bl\\t%__interwork_r11_call_via_%0\";
8300   }"
8301   [(set_attr "type" "call")]
8302 )
8303
8304 (define_expand "call_value"
8305   [(parallel [(set (match_operand       0 "" "")
8306                    (call (match_operand 1 "memory_operand" "")
8307                          (match_operand 2 "general_operand" "")))
8308               (use (match_operand 3 "" ""))
8309               (clobber (reg:SI LR_REGNUM))])]
8310   "TARGET_EITHER"
8311   "
8312   {
8313     rtx pat, callee;
8314     
8315     /* In an untyped call, we can get NULL for operand 2.  */
8316     if (operands[3] == 0)
8317       operands[3] = const0_rtx;
8318       
8319     /* Decide if we should generate indirect calls by loading the
8320        32-bit address of the callee into a register before performing the
8321        branch and link.  */
8322     callee = XEXP (operands[1], 0);
8323     if (GET_CODE (callee) == SYMBOL_REF
8324         ? arm_is_long_call_p (SYMBOL_REF_DECL (callee))
8325         : !REG_P (callee))
8326       XEXP (operands[1], 0) = force_reg (Pmode, callee);
8327
8328     pat = gen_call_value_internal (operands[0], operands[1],
8329                                    operands[2], operands[3]);
8330     arm_emit_call_insn (pat, XEXP (operands[1], 0));
8331     DONE;
8332   }"
8333 )
8334
8335 (define_expand "call_value_internal"
8336   [(parallel [(set (match_operand       0 "" "")
8337                    (call (match_operand 1 "memory_operand" "")
8338                          (match_operand 2 "general_operand" "")))
8339               (use (match_operand 3 "" ""))
8340               (clobber (reg:SI LR_REGNUM))])])
8341
8342 (define_insn "*call_value_reg_armv5"
8343   [(set (match_operand 0 "" "")
8344         (call (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
8345               (match_operand 2 "" "")))
8346    (use (match_operand 3 "" ""))
8347    (clobber (reg:SI LR_REGNUM))]
8348   "TARGET_ARM && arm_arch5"
8349   "blx%?\\t%1"
8350   [(set_attr "type" "call")]
8351 )
8352
8353 (define_insn "*call_value_reg_arm"
8354   [(set (match_operand 0 "" "")
8355         (call (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
8356               (match_operand 2 "" "")))
8357    (use (match_operand 3 "" ""))
8358    (clobber (reg:SI LR_REGNUM))]
8359   "TARGET_ARM && !arm_arch5"
8360   "*
8361   return output_call (&operands[1]);
8362   "
8363   [(set_attr "length" "12")
8364    (set_attr "type" "call")]
8365 )
8366
8367 ;; Note: see *call_mem
8368
8369 (define_insn "*call_value_mem"
8370   [(set (match_operand 0 "" "")
8371         (call (mem:SI (match_operand:SI 1 "call_memory_operand" "m"))
8372               (match_operand 2 "" "")))
8373    (use (match_operand 3 "" ""))
8374    (clobber (reg:SI LR_REGNUM))]
8375   "TARGET_ARM && !arm_arch5 && (!CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))"
8376   "*
8377   return output_call_mem (&operands[1]);
8378   "
8379   [(set_attr "length" "12")
8380    (set_attr "type" "call")]
8381 )
8382
8383 (define_insn "*call_value_reg_thumb1_v5"
8384   [(set (match_operand 0 "" "")
8385         (call (mem:SI (match_operand:SI 1 "register_operand" "l*r"))
8386               (match_operand 2 "" "")))
8387    (use (match_operand 3 "" ""))
8388    (clobber (reg:SI LR_REGNUM))]
8389   "TARGET_THUMB1 && arm_arch5"
8390   "blx\\t%1"
8391   [(set_attr "length" "2")
8392    (set_attr "type" "call")]
8393 )
8394
8395 (define_insn "*call_value_reg_thumb1"
8396   [(set (match_operand 0 "" "")
8397         (call (mem:SI (match_operand:SI 1 "register_operand" "l*r"))
8398               (match_operand 2 "" "")))
8399    (use (match_operand 3 "" ""))
8400    (clobber (reg:SI LR_REGNUM))]
8401   "TARGET_THUMB1 && !arm_arch5"
8402   "*
8403   {
8404     if (!TARGET_CALLER_INTERWORKING)
8405       return thumb_call_via_reg (operands[1]);
8406     else if (operands[2] == const0_rtx)
8407       return \"bl\\t%__interwork_call_via_%1\";
8408     else if (frame_pointer_needed)
8409       return \"bl\\t%__interwork_r7_call_via_%1\";
8410     else
8411       return \"bl\\t%__interwork_r11_call_via_%1\";
8412   }"
8413   [(set_attr "type" "call")]
8414 )
8415
8416 ;; Allow calls to SYMBOL_REFs specially as they are not valid general addresses
8417 ;; The 'a' causes the operand to be treated as an address, i.e. no '#' output.
8418
8419 (define_insn "*call_symbol"
8420   [(call (mem:SI (match_operand:SI 0 "" ""))
8421          (match_operand 1 "" ""))
8422    (use (match_operand 2 "" ""))
8423    (clobber (reg:SI LR_REGNUM))]
8424   "TARGET_32BIT
8425    && (GET_CODE (operands[0]) == SYMBOL_REF)
8426    && !arm_is_long_call_p (SYMBOL_REF_DECL (operands[0]))"
8427   "*
8428   {
8429     return NEED_PLT_RELOC ? \"bl%?\\t%a0(PLT)\" : \"bl%?\\t%a0\";
8430   }"
8431   [(set_attr "type" "call")]
8432 )
8433
8434 (define_insn "*call_value_symbol"
8435   [(set (match_operand 0 "" "")
8436         (call (mem:SI (match_operand:SI 1 "" ""))
8437         (match_operand:SI 2 "" "")))
8438    (use (match_operand 3 "" ""))
8439    (clobber (reg:SI LR_REGNUM))]
8440   "TARGET_32BIT
8441    && (GET_CODE (operands[1]) == SYMBOL_REF)
8442    && !arm_is_long_call_p (SYMBOL_REF_DECL (operands[1]))"
8443   "*
8444   {
8445     return NEED_PLT_RELOC ? \"bl%?\\t%a1(PLT)\" : \"bl%?\\t%a1\";
8446   }"
8447   [(set_attr "type" "call")]
8448 )
8449
8450 (define_insn "*call_insn"
8451   [(call (mem:SI (match_operand:SI 0 "" ""))
8452          (match_operand:SI 1 "" ""))
8453    (use (match_operand 2 "" ""))
8454    (clobber (reg:SI LR_REGNUM))]
8455   "TARGET_THUMB1
8456    && GET_CODE (operands[0]) == SYMBOL_REF
8457    && !arm_is_long_call_p (SYMBOL_REF_DECL (operands[0]))"
8458   "bl\\t%a0"
8459   [(set_attr "length" "4")
8460    (set_attr "type" "call")]
8461 )
8462
8463 (define_insn "*call_value_insn"
8464   [(set (match_operand 0 "" "")
8465         (call (mem:SI (match_operand 1 "" ""))
8466               (match_operand 2 "" "")))
8467    (use (match_operand 3 "" ""))
8468    (clobber (reg:SI LR_REGNUM))]
8469   "TARGET_THUMB1
8470    && GET_CODE (operands[1]) == SYMBOL_REF
8471    && !arm_is_long_call_p (SYMBOL_REF_DECL (operands[1]))"
8472   "bl\\t%a1"
8473   [(set_attr "length" "4")
8474    (set_attr "type" "call")]
8475 )
8476
8477 ;; We may also be able to do sibcalls for Thumb, but it's much harder...
8478 (define_expand "sibcall"
8479   [(parallel [(call (match_operand 0 "memory_operand" "")
8480                     (match_operand 1 "general_operand" ""))
8481               (return)
8482               (use (match_operand 2 "" ""))])]
8483   "TARGET_32BIT"
8484   "
8485   {
8486     if (operands[2] == NULL_RTX)
8487       operands[2] = const0_rtx;
8488   }"
8489 )
8490
8491 (define_expand "sibcall_value"
8492   [(parallel [(set (match_operand 0 "" "")
8493                    (call (match_operand 1 "memory_operand" "")
8494                          (match_operand 2 "general_operand" "")))
8495               (return)
8496               (use (match_operand 3 "" ""))])]
8497   "TARGET_32BIT"
8498   "
8499   {
8500     if (operands[3] == NULL_RTX)
8501       operands[3] = const0_rtx;
8502   }"
8503 )
8504
8505 (define_insn "*sibcall_insn"
8506  [(call (mem:SI (match_operand:SI 0 "" "X"))
8507         (match_operand 1 "" ""))
8508   (return)
8509   (use (match_operand 2 "" ""))]
8510   "TARGET_32BIT && GET_CODE (operands[0]) == SYMBOL_REF"
8511   "*
8512   return NEED_PLT_RELOC ? \"b%?\\t%a0(PLT)\" : \"b%?\\t%a0\";
8513   "
8514   [(set_attr "type" "call")]
8515 )
8516
8517 (define_insn "*sibcall_value_insn"
8518  [(set (match_operand 0 "" "")
8519        (call (mem:SI (match_operand:SI 1 "" "X"))
8520              (match_operand 2 "" "")))
8521   (return)
8522   (use (match_operand 3 "" ""))]
8523   "TARGET_32BIT && GET_CODE (operands[1]) == SYMBOL_REF"
8524   "*
8525   return NEED_PLT_RELOC ? \"b%?\\t%a1(PLT)\" : \"b%?\\t%a1\";
8526   "
8527   [(set_attr "type" "call")]
8528 )
8529
8530 (define_expand "return"
8531   [(return)]
8532   "TARGET_32BIT && USE_RETURN_INSN (FALSE)"
8533   "")
8534
8535 ;; Often the return insn will be the same as loading from memory, so set attr
8536 (define_insn "*arm_return"
8537   [(return)]
8538   "TARGET_ARM && USE_RETURN_INSN (FALSE)"
8539   "*
8540   {
8541     if (arm_ccfsm_state == 2)
8542       {
8543         arm_ccfsm_state += 2;
8544         return \"\";
8545       }
8546     return output_return_instruction (const_true_rtx, TRUE, FALSE);
8547   }"
8548   [(set_attr "type" "load1")
8549    (set_attr "length" "12")
8550    (set_attr "predicable" "yes")]
8551 )
8552
8553 (define_insn "*cond_return"
8554   [(set (pc)
8555         (if_then_else (match_operator 0 "arm_comparison_operator"
8556                        [(match_operand 1 "cc_register" "") (const_int 0)])
8557                       (return)
8558                       (pc)))]
8559   "TARGET_ARM && USE_RETURN_INSN (TRUE)"
8560   "*
8561   {
8562     if (arm_ccfsm_state == 2)
8563       {
8564         arm_ccfsm_state += 2;
8565         return \"\";
8566       }
8567     return output_return_instruction (operands[0], TRUE, FALSE);
8568   }"
8569   [(set_attr "conds" "use")
8570    (set_attr "length" "12")
8571    (set_attr "type" "load1")]
8572 )
8573
8574 (define_insn "*cond_return_inverted"
8575   [(set (pc)
8576         (if_then_else (match_operator 0 "arm_comparison_operator"
8577                        [(match_operand 1 "cc_register" "") (const_int 0)])
8578                       (pc)
8579                       (return)))]
8580   "TARGET_ARM && USE_RETURN_INSN (TRUE)"
8581   "*
8582   {
8583     if (arm_ccfsm_state == 2)
8584       {
8585         arm_ccfsm_state += 2;
8586         return \"\";
8587       }
8588     return output_return_instruction (operands[0], TRUE, TRUE);
8589   }"
8590   [(set_attr "conds" "use")
8591    (set_attr "length" "12")
8592    (set_attr "type" "load1")]
8593 )
8594
8595 ;; Generate a sequence of instructions to determine if the processor is
8596 ;; in 26-bit or 32-bit mode, and return the appropriate return address
8597 ;; mask.
8598
8599 (define_expand "return_addr_mask"
8600   [(set (match_dup 1)
8601       (compare:CC_NOOV (unspec [(const_int 0)] UNSPEC_CHECK_ARCH)
8602                        (const_int 0)))
8603    (set (match_operand:SI 0 "s_register_operand" "")
8604       (if_then_else:SI (eq (match_dup 1) (const_int 0))
8605                        (const_int -1)
8606                        (const_int 67108860)))] ; 0x03fffffc
8607   "TARGET_ARM"
8608   "
8609   operands[1] = gen_rtx_REG (CC_NOOVmode, CC_REGNUM);
8610   ")
8611
8612 (define_insn "*check_arch2"
8613   [(set (match_operand:CC_NOOV 0 "cc_register" "")
8614       (compare:CC_NOOV (unspec [(const_int 0)] UNSPEC_CHECK_ARCH)
8615                        (const_int 0)))]
8616   "TARGET_ARM"
8617   "teq\\t%|r0, %|r0\;teq\\t%|pc, %|pc"
8618   [(set_attr "length" "8")
8619    (set_attr "conds" "set")]
8620 )
8621
8622 ;; Call subroutine returning any type.
8623
8624 (define_expand "untyped_call"
8625   [(parallel [(call (match_operand 0 "" "")
8626                     (const_int 0))
8627               (match_operand 1 "" "")
8628               (match_operand 2 "" "")])]
8629   "TARGET_EITHER"
8630   "
8631   {
8632     int i;
8633     rtx par = gen_rtx_PARALLEL (VOIDmode,
8634                                 rtvec_alloc (XVECLEN (operands[2], 0)));
8635     rtx addr = gen_reg_rtx (Pmode);
8636     rtx mem;
8637     int size = 0;
8638
8639     emit_move_insn (addr, XEXP (operands[1], 0));
8640     mem = change_address (operands[1], BLKmode, addr);
8641
8642     for (i = 0; i < XVECLEN (operands[2], 0); i++)
8643       {
8644         rtx src = SET_SRC (XVECEXP (operands[2], 0, i));
8645
8646         /* Default code only uses r0 as a return value, but we could
8647            be using anything up to 4 registers.  */
8648         if (REGNO (src) == R0_REGNUM)
8649           src = gen_rtx_REG (TImode, R0_REGNUM);
8650
8651         XVECEXP (par, 0, i) = gen_rtx_EXPR_LIST (VOIDmode, src,
8652                                                  GEN_INT (size));
8653         size += GET_MODE_SIZE (GET_MODE (src));
8654       }
8655
8656     emit_call_insn (GEN_CALL_VALUE (par, operands[0], const0_rtx, NULL,
8657                                     const0_rtx));
8658
8659     size = 0;
8660
8661     for (i = 0; i < XVECLEN (par, 0); i++)
8662       {
8663         HOST_WIDE_INT offset = 0;
8664         rtx reg = XEXP (XVECEXP (par, 0, i), 0);
8665
8666         if (size != 0)
8667           emit_move_insn (addr, plus_constant (addr, size));
8668
8669         mem = change_address (mem, GET_MODE (reg), NULL);
8670         if (REGNO (reg) == R0_REGNUM)
8671           {
8672             /* On thumb we have to use a write-back instruction.  */
8673             emit_insn (arm_gen_store_multiple (arm_regs_in_sequence, 4, addr,
8674                        TARGET_THUMB ? TRUE : FALSE, mem, &offset));
8675             size = TARGET_ARM ? 16 : 0;
8676           }
8677         else
8678           {
8679             emit_move_insn (mem, reg);
8680             size = GET_MODE_SIZE (GET_MODE (reg));
8681           }
8682       }
8683
8684     /* The optimizer does not know that the call sets the function value
8685        registers we stored in the result block.  We avoid problems by
8686        claiming that all hard registers are used and clobbered at this
8687        point.  */
8688     emit_insn (gen_blockage ());
8689
8690     DONE;
8691   }"
8692 )
8693
8694 (define_expand "untyped_return"
8695   [(match_operand:BLK 0 "memory_operand" "")
8696    (match_operand 1 "" "")]
8697   "TARGET_EITHER"
8698   "
8699   {
8700     int i;
8701     rtx addr = gen_reg_rtx (Pmode);
8702     rtx mem;
8703     int size = 0;
8704
8705     emit_move_insn (addr, XEXP (operands[0], 0));
8706     mem = change_address (operands[0], BLKmode, addr);
8707
8708     for (i = 0; i < XVECLEN (operands[1], 0); i++)
8709       {
8710         HOST_WIDE_INT offset = 0;
8711         rtx reg = SET_DEST (XVECEXP (operands[1], 0, i));
8712
8713         if (size != 0)
8714           emit_move_insn (addr, plus_constant (addr, size));
8715
8716         mem = change_address (mem, GET_MODE (reg), NULL);
8717         if (REGNO (reg) == R0_REGNUM)
8718           {
8719             /* On thumb we have to use a write-back instruction.  */
8720             emit_insn (arm_gen_load_multiple (arm_regs_in_sequence, 4, addr,
8721                        TARGET_THUMB ? TRUE : FALSE, mem, &offset));
8722             size = TARGET_ARM ? 16 : 0;
8723           }
8724         else
8725           {
8726             emit_move_insn (reg, mem);
8727             size = GET_MODE_SIZE (GET_MODE (reg));
8728           }
8729       }
8730
8731     /* Emit USE insns before the return.  */
8732     for (i = 0; i < XVECLEN (operands[1], 0); i++)
8733       emit_use (SET_DEST (XVECEXP (operands[1], 0, i)));
8734
8735     /* Construct the return.  */
8736     expand_naked_return ();
8737
8738     DONE;
8739   }"
8740 )
8741
8742 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
8743 ;; all of memory.  This blocks insns from being moved across this point.
8744
8745 (define_insn "blockage"
8746   [(unspec_volatile [(const_int 0)] VUNSPEC_BLOCKAGE)]
8747   "TARGET_EITHER"
8748   ""
8749   [(set_attr "length" "0")
8750    (set_attr "type" "block")]
8751 )
8752
8753 (define_expand "casesi"
8754   [(match_operand:SI 0 "s_register_operand" "") ; index to jump on
8755    (match_operand:SI 1 "const_int_operand" "")  ; lower bound
8756    (match_operand:SI 2 "const_int_operand" "")  ; total range
8757    (match_operand:SI 3 "" "")                   ; table label
8758    (match_operand:SI 4 "" "")]                  ; Out of range label
8759   "TARGET_32BIT || optimize_size || flag_pic"
8760   "
8761   {
8762     enum insn_code code;
8763     if (operands[1] != const0_rtx)
8764       {
8765         rtx reg = gen_reg_rtx (SImode);
8766
8767         emit_insn (gen_addsi3 (reg, operands[0],
8768                                gen_int_mode (-INTVAL (operands[1]),
8769                                              SImode)));
8770         operands[0] = reg;
8771       }
8772
8773     if (TARGET_ARM)
8774       code = CODE_FOR_arm_casesi_internal;
8775     else if (TARGET_THUMB1)
8776       code = CODE_FOR_thumb1_casesi_internal_pic;
8777     else if (flag_pic)
8778       code = CODE_FOR_thumb2_casesi_internal_pic;
8779     else
8780       code = CODE_FOR_thumb2_casesi_internal;
8781
8782     if (!insn_data[(int) code].operand[1].predicate(operands[2], SImode))
8783       operands[2] = force_reg (SImode, operands[2]);
8784
8785     emit_jump_insn (GEN_FCN ((int) code) (operands[0], operands[2],
8786                                           operands[3], operands[4]));
8787     DONE;
8788   }"
8789 )
8790
8791 ;; The USE in this pattern is needed to tell flow analysis that this is
8792 ;; a CASESI insn.  It has no other purpose.
8793 (define_insn "arm_casesi_internal"
8794   [(parallel [(set (pc)
8795                (if_then_else
8796                 (leu (match_operand:SI 0 "s_register_operand" "r")
8797                      (match_operand:SI 1 "arm_rhs_operand" "rI"))
8798                 (mem:SI (plus:SI (mult:SI (match_dup 0) (const_int 4))
8799                                  (label_ref (match_operand 2 "" ""))))
8800                 (label_ref (match_operand 3 "" ""))))
8801               (clobber (reg:CC CC_REGNUM))
8802               (use (label_ref (match_dup 2)))])]
8803   "TARGET_ARM"
8804   "*
8805     if (flag_pic)
8806       return \"cmp\\t%0, %1\;addls\\t%|pc, %|pc, %0, asl #2\;b\\t%l3\";
8807     return   \"cmp\\t%0, %1\;ldrls\\t%|pc, [%|pc, %0, asl #2]\;b\\t%l3\";
8808   "
8809   [(set_attr "conds" "clob")
8810    (set_attr "length" "12")]
8811 )
8812
8813 (define_expand "thumb1_casesi_internal_pic"
8814   [(match_operand:SI 0 "s_register_operand" "")
8815    (match_operand:SI 1 "thumb1_cmp_operand" "")
8816    (match_operand 2 "" "")
8817    (match_operand 3 "" "")]
8818   "TARGET_THUMB1"
8819   {
8820     rtx reg0;
8821     rtx test = gen_rtx_GTU (VOIDmode, operands[0], operands[1]);
8822     emit_jump_insn (gen_cbranchsi4 (test, operands[0], operands[1],
8823                                     operands[3]));
8824     reg0 = gen_rtx_REG (SImode, 0);
8825     emit_move_insn (reg0, operands[0]);
8826     emit_jump_insn (gen_thumb1_casesi_dispatch (operands[2]/*, operands[3]*/));
8827     DONE;
8828   }
8829 )
8830
8831 (define_insn "thumb1_casesi_dispatch"
8832   [(parallel [(set (pc) (unspec [(reg:SI 0)
8833                                  (label_ref (match_operand 0 "" ""))
8834 ;;                               (label_ref (match_operand 1 "" ""))
8835 ]
8836                          UNSPEC_THUMB1_CASESI))
8837               (clobber (reg:SI IP_REGNUM))
8838               (clobber (reg:SI LR_REGNUM))])]
8839   "TARGET_THUMB1"
8840   "* return thumb1_output_casesi(operands);"
8841   [(set_attr "length" "4")]
8842 )
8843
8844 (define_expand "indirect_jump"
8845   [(set (pc)
8846         (match_operand:SI 0 "s_register_operand" ""))]
8847   "TARGET_EITHER"
8848   "
8849   /* Thumb-2 doesn't have mov pc, reg.  Explicitly set the low bit of the
8850      address and use bx.  */
8851   if (TARGET_THUMB2)
8852     {
8853       rtx tmp;
8854       tmp = gen_reg_rtx (SImode);
8855       emit_insn (gen_iorsi3 (tmp, operands[0], GEN_INT(1)));
8856       operands[0] = tmp;
8857     }
8858   "
8859 )
8860
8861 ;; NB Never uses BX.
8862 (define_insn "*arm_indirect_jump"
8863   [(set (pc)
8864         (match_operand:SI 0 "s_register_operand" "r"))]
8865   "TARGET_ARM"
8866   "mov%?\\t%|pc, %0\\t%@ indirect register jump"
8867   [(set_attr "predicable" "yes")]
8868 )
8869
8870 (define_insn "*load_indirect_jump"
8871   [(set (pc)
8872         (match_operand:SI 0 "memory_operand" "m"))]
8873   "TARGET_ARM"
8874   "ldr%?\\t%|pc, %0\\t%@ indirect memory jump"
8875   [(set_attr "type" "load1")
8876    (set_attr "pool_range" "4096")
8877    (set_attr "neg_pool_range" "4084")
8878    (set_attr "predicable" "yes")]
8879 )
8880
8881 ;; NB Never uses BX.
8882 (define_insn "*thumb1_indirect_jump"
8883   [(set (pc)
8884         (match_operand:SI 0 "register_operand" "l*r"))]
8885   "TARGET_THUMB1"
8886   "mov\\tpc, %0"
8887   [(set_attr "conds" "clob")
8888    (set_attr "length" "2")]
8889 )
8890
8891 \f
8892 ;; Misc insns
8893
8894 (define_insn "nop"
8895   [(const_int 0)]
8896   "TARGET_EITHER"
8897   "*
8898   if (TARGET_UNIFIED_ASM)
8899     return \"nop\";
8900   if (TARGET_ARM)
8901     return \"mov%?\\t%|r0, %|r0\\t%@ nop\";
8902   return  \"mov\\tr8, r8\";
8903   "
8904   [(set (attr "length")
8905         (if_then_else (eq_attr "is_thumb" "yes")
8906                       (const_int 2)
8907                       (const_int 4)))]
8908 )
8909
8910 \f
8911 ;; Patterns to allow combination of arithmetic, cond code and shifts
8912
8913 (define_insn "*arith_shiftsi"
8914   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
8915         (match_operator:SI 1 "shiftable_operator"
8916           [(match_operator:SI 3 "shift_operator"
8917              [(match_operand:SI 4 "s_register_operand" "r,r,r,r")
8918               (match_operand:SI 5 "shift_amount_operand" "M,M,M,r")])
8919            (match_operand:SI 2 "s_register_operand" "rk,rk,r,rk")]))]
8920   "TARGET_32BIT"
8921   "%i1%?\\t%0, %2, %4%S3"
8922   [(set_attr "predicable" "yes")
8923    (set_attr "shift" "4")
8924    (set_attr "arch" "a,t2,t2,a")
8925    ;; Thumb2 doesn't allow the stack pointer to be used for 
8926    ;; operand1 for all operations other than add and sub. In this case 
8927    ;; the minus operation is a candidate for an rsub and hence needs
8928    ;; to be disabled.
8929    ;; We have to make sure to disable the fourth alternative if
8930    ;; the shift_operator is MULT, since otherwise the insn will
8931    ;; also match a multiply_accumulate pattern and validate_change
8932    ;; will allow a replacement of the constant with a register
8933    ;; despite the checks done in shift_operator.
8934    (set_attr_alternative "insn_enabled"
8935                          [(const_string "yes")
8936                           (if_then_else
8937                            (match_operand:SI 1 "add_operator" "")
8938                            (const_string "yes") (const_string "no"))
8939                           (const_string "yes")
8940                           (if_then_else
8941                            (match_operand:SI 3 "mult_operator" "")
8942                            (const_string "no") (const_string "yes"))])
8943    (set_attr "type" "alu_shift,alu_shift,alu_shift,alu_shift_reg")])
8944
8945 (define_split
8946   [(set (match_operand:SI 0 "s_register_operand" "")
8947         (match_operator:SI 1 "shiftable_operator"
8948          [(match_operator:SI 2 "shiftable_operator"
8949            [(match_operator:SI 3 "shift_operator"
8950              [(match_operand:SI 4 "s_register_operand" "")
8951               (match_operand:SI 5 "reg_or_int_operand" "")])
8952             (match_operand:SI 6 "s_register_operand" "")])
8953           (match_operand:SI 7 "arm_rhs_operand" "")]))
8954    (clobber (match_operand:SI 8 "s_register_operand" ""))]
8955   "TARGET_32BIT"
8956   [(set (match_dup 8)
8957         (match_op_dup 2 [(match_op_dup 3 [(match_dup 4) (match_dup 5)])
8958                          (match_dup 6)]))
8959    (set (match_dup 0)
8960         (match_op_dup 1 [(match_dup 8) (match_dup 7)]))]
8961   "")
8962
8963 (define_insn "*arith_shiftsi_compare0"
8964   [(set (reg:CC_NOOV CC_REGNUM)
8965         (compare:CC_NOOV
8966          (match_operator:SI 1 "shiftable_operator"
8967           [(match_operator:SI 3 "shift_operator"
8968             [(match_operand:SI 4 "s_register_operand" "r,r")
8969              (match_operand:SI 5 "shift_amount_operand" "M,r")])
8970            (match_operand:SI 2 "s_register_operand" "r,r")])
8971          (const_int 0)))
8972    (set (match_operand:SI 0 "s_register_operand" "=r,r")
8973         (match_op_dup 1 [(match_op_dup 3 [(match_dup 4) (match_dup 5)])
8974                          (match_dup 2)]))]
8975   "TARGET_32BIT"
8976   "%i1%.\\t%0, %2, %4%S3"
8977   [(set_attr "conds" "set")
8978    (set_attr "shift" "4")
8979    (set_attr "arch" "32,a")
8980    (set_attr "type" "alu_shift,alu_shift_reg")])
8981
8982 (define_insn "*arith_shiftsi_compare0_scratch"
8983   [(set (reg:CC_NOOV CC_REGNUM)
8984         (compare:CC_NOOV
8985          (match_operator:SI 1 "shiftable_operator"
8986           [(match_operator:SI 3 "shift_operator"
8987             [(match_operand:SI 4 "s_register_operand" "r,r")
8988              (match_operand:SI 5 "shift_amount_operand" "M,r")])
8989            (match_operand:SI 2 "s_register_operand" "r,r")])
8990          (const_int 0)))
8991    (clobber (match_scratch:SI 0 "=r,r"))]
8992   "TARGET_32BIT"
8993   "%i1%.\\t%0, %2, %4%S3"
8994   [(set_attr "conds" "set")
8995    (set_attr "shift" "4")
8996    (set_attr "arch" "32,a")
8997    (set_attr "type" "alu_shift,alu_shift_reg")])
8998
8999 (define_insn "*sub_shiftsi"
9000   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9001         (minus:SI (match_operand:SI 1 "s_register_operand" "r,r")
9002                   (match_operator:SI 2 "shift_operator"
9003                    [(match_operand:SI 3 "s_register_operand" "r,r")
9004                     (match_operand:SI 4 "shift_amount_operand" "M,r")])))]
9005   "TARGET_32BIT"
9006   "sub%?\\t%0, %1, %3%S2"
9007   [(set_attr "predicable" "yes")
9008    (set_attr "shift" "3")
9009    (set_attr "arch" "32,a")
9010    (set_attr "type" "alu_shift,alu_shift_reg")])
9011
9012 (define_insn "*sub_shiftsi_compare0"
9013   [(set (reg:CC_NOOV CC_REGNUM)
9014         (compare:CC_NOOV
9015          (minus:SI (match_operand:SI 1 "s_register_operand" "r,r")
9016                    (match_operator:SI 2 "shift_operator"
9017                     [(match_operand:SI 3 "s_register_operand" "r,r")
9018                      (match_operand:SI 4 "shift_amount_operand" "M,rM")]))
9019          (const_int 0)))
9020    (set (match_operand:SI 0 "s_register_operand" "=r,r")
9021         (minus:SI (match_dup 1)
9022                   (match_op_dup 2 [(match_dup 3) (match_dup 4)])))]
9023   "TARGET_32BIT"
9024   "sub%.\\t%0, %1, %3%S2"
9025   [(set_attr "conds" "set")
9026    (set_attr "shift" "3")
9027    (set_attr "arch" "32,a")
9028    (set_attr "type" "alu_shift,alu_shift_reg")])
9029
9030 (define_insn "*sub_shiftsi_compare0_scratch"
9031   [(set (reg:CC_NOOV CC_REGNUM)
9032         (compare:CC_NOOV
9033          (minus:SI (match_operand:SI 1 "s_register_operand" "r,r")
9034                    (match_operator:SI 2 "shift_operator"
9035                     [(match_operand:SI 3 "s_register_operand" "r,r")
9036                      (match_operand:SI 4 "shift_amount_operand" "M,rM")]))
9037          (const_int 0)))
9038    (clobber (match_scratch:SI 0 "=r,r"))]
9039   "TARGET_32BIT"
9040   "sub%.\\t%0, %1, %3%S2"
9041   [(set_attr "conds" "set")
9042    (set_attr "shift" "3")
9043    (set_attr "arch" "32,a")
9044    (set_attr "type" "alu_shift,alu_shift_reg")])
9045 \f
9046
9047 (define_insn "*and_scc"
9048   [(set (match_operand:SI 0 "s_register_operand" "=r")
9049         (and:SI (match_operator:SI 1 "arm_comparison_operator"
9050                  [(match_operand 3 "cc_register" "") (const_int 0)])
9051                 (match_operand:SI 2 "s_register_operand" "r")))]
9052   "TARGET_ARM"
9053   "mov%D1\\t%0, #0\;and%d1\\t%0, %2, #1"
9054   [(set_attr "conds" "use")
9055    (set_attr "insn" "mov")
9056    (set_attr "length" "8")]
9057 )
9058
9059 (define_insn "*ior_scc"
9060   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9061         (ior:SI (match_operator:SI 2 "arm_comparison_operator"
9062                  [(match_operand 3 "cc_register" "") (const_int 0)])
9063                 (match_operand:SI 1 "s_register_operand" "0,?r")))]
9064   "TARGET_ARM"
9065   "@
9066    orr%d2\\t%0, %1, #1
9067    mov%D2\\t%0, %1\;orr%d2\\t%0, %1, #1"
9068   [(set_attr "conds" "use")
9069    (set_attr "length" "4,8")]
9070 )
9071
9072 ; A series of splitters for the compare_scc pattern below.  Note that
9073 ; order is important.
9074 (define_split
9075   [(set (match_operand:SI 0 "s_register_operand" "")
9076         (lt:SI (match_operand:SI 1 "s_register_operand" "")
9077                (const_int 0)))
9078    (clobber (reg:CC CC_REGNUM))]
9079   "TARGET_32BIT && reload_completed"
9080   [(set (match_dup 0) (lshiftrt:SI (match_dup 1) (const_int 31)))])
9081
9082 (define_split
9083   [(set (match_operand:SI 0 "s_register_operand" "")
9084         (ge:SI (match_operand:SI 1 "s_register_operand" "")
9085                (const_int 0)))
9086    (clobber (reg:CC CC_REGNUM))]
9087   "TARGET_32BIT && reload_completed"
9088   [(set (match_dup 0) (not:SI (match_dup 1)))
9089    (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 31)))])
9090
9091 (define_split
9092   [(set (match_operand:SI 0 "s_register_operand" "")
9093         (eq:SI (match_operand:SI 1 "s_register_operand" "")
9094                (const_int 0)))
9095    (clobber (reg:CC CC_REGNUM))]
9096   "TARGET_32BIT && reload_completed"
9097   [(parallel
9098     [(set (reg:CC CC_REGNUM)
9099           (compare:CC (const_int 1) (match_dup 1)))
9100      (set (match_dup 0)
9101           (minus:SI (const_int 1) (match_dup 1)))])
9102    (cond_exec (ltu:CC (reg:CC CC_REGNUM) (const_int 0))
9103               (set (match_dup 0) (const_int 0)))])
9104
9105 (define_split
9106   [(set (match_operand:SI 0 "s_register_operand" "")
9107         (ne:SI (match_operand:SI 1 "s_register_operand" "")
9108                (match_operand:SI 2 "const_int_operand" "")))
9109    (clobber (reg:CC CC_REGNUM))]
9110   "TARGET_32BIT && reload_completed"
9111   [(parallel
9112     [(set (reg:CC CC_REGNUM)
9113           (compare:CC (match_dup 1) (match_dup 2)))
9114      (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 3)))])
9115    (cond_exec (ne:CC (reg:CC CC_REGNUM) (const_int 0))
9116               (set (match_dup 0) (const_int 1)))]
9117 {
9118   operands[3] = GEN_INT (-INTVAL (operands[2]));
9119 })
9120
9121 (define_split
9122   [(set (match_operand:SI 0 "s_register_operand" "")
9123         (ne:SI (match_operand:SI 1 "s_register_operand" "")
9124                (match_operand:SI 2 "arm_add_operand" "")))
9125    (clobber (reg:CC CC_REGNUM))]
9126   "TARGET_32BIT && reload_completed"
9127   [(parallel
9128     [(set (reg:CC_NOOV CC_REGNUM)
9129           (compare:CC_NOOV (minus:SI (match_dup 1) (match_dup 2))
9130                            (const_int 0)))
9131      (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
9132    (cond_exec (ne:CC_NOOV (reg:CC_NOOV CC_REGNUM) (const_int 0))
9133               (set (match_dup 0) (const_int 1)))])
9134
9135 (define_insn_and_split "*compare_scc"
9136   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9137         (match_operator:SI 1 "arm_comparison_operator"
9138          [(match_operand:SI 2 "s_register_operand" "r,r")
9139           (match_operand:SI 3 "arm_add_operand" "rI,L")]))
9140    (clobber (reg:CC CC_REGNUM))]
9141   "TARGET_32BIT"
9142   "#"
9143   "&& reload_completed"
9144   [(set (reg:CC CC_REGNUM) (compare:CC (match_dup 2) (match_dup 3)))
9145    (cond_exec (match_dup 4) (set (match_dup 0) (const_int 0)))
9146    (cond_exec (match_dup 5) (set (match_dup 0) (const_int 1)))]
9147 {
9148   rtx tmp1;
9149   enum machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
9150                                            operands[2], operands[3]);
9151   enum rtx_code rc = GET_CODE (operands[1]);
9152
9153   tmp1 = gen_rtx_REG (mode, CC_REGNUM);
9154
9155   operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, tmp1, const0_rtx);
9156   if (mode == CCFPmode || mode == CCFPEmode)
9157     rc = reverse_condition_maybe_unordered (rc);
9158   else
9159     rc = reverse_condition (rc);
9160   operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, tmp1, const0_rtx);
9161 })
9162
9163 ;; Attempt to improve the sequence generated by the compare_scc splitters
9164 ;; not to use conditional execution.
9165 (define_peephole2
9166   [(set (reg:CC CC_REGNUM)
9167         (compare:CC (match_operand:SI 1 "register_operand" "")
9168                     (match_operand:SI 2 "arm_rhs_operand" "")))
9169    (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
9170               (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
9171    (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
9172               (set (match_dup 0) (const_int 1)))
9173    (match_scratch:SI 3 "r")]
9174   "TARGET_32BIT"
9175   [(parallel
9176     [(set (reg:CC CC_REGNUM)
9177           (compare:CC (match_dup 1) (match_dup 2)))
9178      (set (match_dup 3) (minus:SI (match_dup 1) (match_dup 2)))])
9179    (parallel
9180     [(set (reg:CC CC_REGNUM)
9181           (compare:CC (const_int 0) (match_dup 3)))
9182      (set (match_dup 0) (minus:SI (const_int 0) (match_dup 3)))])
9183    (parallel
9184     [(set (match_dup 0)
9185           (plus:SI (plus:SI (match_dup 0) (match_dup 3))
9186                    (geu:SI (reg:CC CC_REGNUM) (const_int 0))))
9187      (clobber (reg:CC CC_REGNUM))])])
9188
9189 (define_insn "*cond_move"
9190   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9191         (if_then_else:SI (match_operator 3 "equality_operator"
9192                           [(match_operator 4 "arm_comparison_operator"
9193                             [(match_operand 5 "cc_register" "") (const_int 0)])
9194                            (const_int 0)])
9195                          (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
9196                          (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))]
9197   "TARGET_ARM"
9198   "*
9199     if (GET_CODE (operands[3]) == NE)
9200       {
9201         if (which_alternative != 1)
9202           output_asm_insn (\"mov%D4\\t%0, %2\", operands);
9203         if (which_alternative != 0)
9204           output_asm_insn (\"mov%d4\\t%0, %1\", operands);
9205         return \"\";
9206       }
9207     if (which_alternative != 0)
9208       output_asm_insn (\"mov%D4\\t%0, %1\", operands);
9209     if (which_alternative != 1)
9210       output_asm_insn (\"mov%d4\\t%0, %2\", operands);
9211     return \"\";
9212   "
9213   [(set_attr "conds" "use")
9214    (set_attr "insn" "mov")
9215    (set_attr "length" "4,4,8")]
9216 )
9217
9218 (define_insn "*cond_arith"
9219   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9220         (match_operator:SI 5 "shiftable_operator" 
9221          [(match_operator:SI 4 "arm_comparison_operator"
9222            [(match_operand:SI 2 "s_register_operand" "r,r")
9223             (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
9224           (match_operand:SI 1 "s_register_operand" "0,?r")]))
9225    (clobber (reg:CC CC_REGNUM))]
9226   "TARGET_ARM"
9227   "*
9228     if (GET_CODE (operands[4]) == LT && operands[3] == const0_rtx)
9229       return \"%i5\\t%0, %1, %2, lsr #31\";
9230
9231     output_asm_insn (\"cmp\\t%2, %3\", operands);
9232     if (GET_CODE (operands[5]) == AND)
9233       output_asm_insn (\"mov%D4\\t%0, #0\", operands);
9234     else if (GET_CODE (operands[5]) == MINUS)
9235       output_asm_insn (\"rsb%D4\\t%0, %1, #0\", operands);
9236     else if (which_alternative != 0)
9237       output_asm_insn (\"mov%D4\\t%0, %1\", operands);
9238     return \"%i5%d4\\t%0, %1, #1\";
9239   "
9240   [(set_attr "conds" "clob")
9241    (set_attr "length" "12")]
9242 )
9243
9244 (define_insn "*cond_sub"
9245   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9246         (minus:SI (match_operand:SI 1 "s_register_operand" "0,?r")
9247                   (match_operator:SI 4 "arm_comparison_operator"
9248                    [(match_operand:SI 2 "s_register_operand" "r,r")
9249                     (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
9250    (clobber (reg:CC CC_REGNUM))]
9251   "TARGET_ARM"
9252   "*
9253     output_asm_insn (\"cmp\\t%2, %3\", operands);
9254     if (which_alternative != 0)
9255       output_asm_insn (\"mov%D4\\t%0, %1\", operands);
9256     return \"sub%d4\\t%0, %1, #1\";
9257   "
9258   [(set_attr "conds" "clob")
9259    (set_attr "length" "8,12")]
9260 )
9261
9262 (define_insn "*cmp_ite0"
9263   [(set (match_operand 6 "dominant_cc_register" "")
9264         (compare
9265          (if_then_else:SI
9266           (match_operator 4 "arm_comparison_operator"
9267            [(match_operand:SI 0 "s_register_operand"
9268                 "l,l,l,r,r,r,r,r,r")
9269             (match_operand:SI 1 "arm_add_operand"
9270                 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
9271           (match_operator:SI 5 "arm_comparison_operator"
9272            [(match_operand:SI 2 "s_register_operand"
9273                 "l,r,r,l,l,r,r,r,r")
9274             (match_operand:SI 3 "arm_add_operand"
9275                 "lPy,rI,L,lPy,lPy,rI,rI,L,L")])
9276           (const_int 0))
9277          (const_int 0)))]
9278   "TARGET_32BIT"
9279   "*
9280   {
9281     static const char * const cmp1[NUM_OF_COND_CMP][2] =
9282     {
9283       {\"cmp%d5\\t%0, %1\",
9284        \"cmp%d4\\t%2, %3\"},
9285       {\"cmn%d5\\t%0, #%n1\",
9286        \"cmp%d4\\t%2, %3\"},
9287       {\"cmp%d5\\t%0, %1\",
9288        \"cmn%d4\\t%2, #%n3\"},
9289       {\"cmn%d5\\t%0, #%n1\",
9290        \"cmn%d4\\t%2, #%n3\"}
9291     };
9292     static const char * const cmp2[NUM_OF_COND_CMP][2] =
9293     {
9294       {\"cmp\\t%2, %3\",
9295        \"cmp\\t%0, %1\"},
9296       {\"cmp\\t%2, %3\",
9297        \"cmn\\t%0, #%n1\"},
9298       {\"cmn\\t%2, #%n3\",
9299        \"cmp\\t%0, %1\"},
9300       {\"cmn\\t%2, #%n3\",
9301        \"cmn\\t%0, #%n1\"}
9302     };
9303     static const char * const ite[2] =
9304     {
9305       \"it\\t%d5\",
9306       \"it\\t%d4\"
9307     };
9308     static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
9309                                    CMP_CMP, CMN_CMP, CMP_CMP,
9310                                    CMN_CMP, CMP_CMN, CMN_CMN};
9311     int swap =
9312       comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
9313
9314     output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
9315     if (TARGET_THUMB2) {
9316       output_asm_insn (ite[swap], operands);
9317     }
9318     output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
9319     return \"\";
9320   }"
9321   [(set_attr "conds" "set")
9322    (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
9323    (set_attr_alternative "length"
9324       [(const_int 6)
9325        (const_int 8)
9326        (const_int 8)
9327        (const_int 8)
9328        (const_int 8)
9329        (if_then_else (eq_attr "is_thumb" "no")
9330            (const_int 8)
9331            (const_int 10))
9332        (if_then_else (eq_attr "is_thumb" "no")
9333            (const_int 8)
9334            (const_int 10))
9335        (if_then_else (eq_attr "is_thumb" "no")
9336            (const_int 8)
9337            (const_int 10))
9338        (if_then_else (eq_attr "is_thumb" "no")
9339            (const_int 8)
9340            (const_int 10))])]
9341 )
9342
9343 (define_insn "*cmp_ite1"
9344   [(set (match_operand 6 "dominant_cc_register" "")
9345         (compare
9346          (if_then_else:SI
9347           (match_operator 4 "arm_comparison_operator"
9348            [(match_operand:SI 0 "s_register_operand"
9349                 "l,l,l,r,r,r,r,r,r")
9350             (match_operand:SI 1 "arm_add_operand"
9351                 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
9352           (match_operator:SI 5 "arm_comparison_operator"
9353            [(match_operand:SI 2 "s_register_operand"
9354                 "l,r,r,l,l,r,r,r,r")
9355             (match_operand:SI 3 "arm_add_operand"
9356                 "lPy,rI,L,lPy,lPy,rI,rI,L,L")])
9357           (const_int 1))
9358          (const_int 0)))]
9359   "TARGET_32BIT"
9360   "*
9361   {
9362     static const char * const cmp1[NUM_OF_COND_CMP][2] =
9363     {
9364       {\"cmp\\t%0, %1\",
9365        \"cmp\\t%2, %3\"},
9366       {\"cmn\\t%0, #%n1\",
9367        \"cmp\\t%2, %3\"},
9368       {\"cmp\\t%0, %1\",
9369        \"cmn\\t%2, #%n3\"},
9370       {\"cmn\\t%0, #%n1\",
9371        \"cmn\\t%2, #%n3\"}
9372     };
9373     static const char * const cmp2[NUM_OF_COND_CMP][2] =
9374     {
9375       {\"cmp%d4\\t%2, %3\",
9376        \"cmp%D5\\t%0, %1\"},
9377       {\"cmp%d4\\t%2, %3\",
9378        \"cmn%D5\\t%0, #%n1\"},
9379       {\"cmn%d4\\t%2, #%n3\",
9380        \"cmp%D5\\t%0, %1\"},
9381       {\"cmn%d4\\t%2, #%n3\",
9382        \"cmn%D5\\t%0, #%n1\"}
9383     };
9384     static const char * const ite[2] =
9385     {
9386       \"it\\t%d4\",
9387       \"it\\t%D5\"
9388     };
9389     static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
9390                                    CMP_CMP, CMN_CMP, CMP_CMP,
9391                                    CMN_CMP, CMP_CMN, CMN_CMN};
9392     int swap =
9393       comparison_dominates_p (GET_CODE (operands[5]),
9394                               reverse_condition (GET_CODE (operands[4])));
9395
9396     output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
9397     if (TARGET_THUMB2) {
9398       output_asm_insn (ite[swap], operands);
9399     }
9400     output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
9401     return \"\";
9402   }"
9403   [(set_attr "conds" "set")
9404    (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
9405    (set_attr_alternative "length"
9406       [(const_int 6)
9407        (const_int 8)
9408        (const_int 8)
9409        (const_int 8)
9410        (const_int 8)
9411        (if_then_else (eq_attr "is_thumb" "no")
9412            (const_int 8)
9413            (const_int 10))
9414        (if_then_else (eq_attr "is_thumb" "no")
9415            (const_int 8)
9416            (const_int 10))
9417        (if_then_else (eq_attr "is_thumb" "no")
9418            (const_int 8)
9419            (const_int 10))
9420        (if_then_else (eq_attr "is_thumb" "no")
9421            (const_int 8)
9422            (const_int 10))])]
9423 )
9424
9425 (define_insn "*cmp_and"
9426   [(set (match_operand 6 "dominant_cc_register" "")
9427         (compare
9428          (and:SI
9429           (match_operator 4 "arm_comparison_operator"
9430            [(match_operand:SI 0 "s_register_operand" 
9431                 "l,l,l,r,r,r,r,r,r")
9432             (match_operand:SI 1 "arm_add_operand" 
9433                 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
9434           (match_operator:SI 5 "arm_comparison_operator"
9435            [(match_operand:SI 2 "s_register_operand" 
9436                 "l,r,r,l,l,r,r,r,r")
9437             (match_operand:SI 3 "arm_add_operand" 
9438                 "lPy,rI,L,lPy,lPy,rI,rI,L,L")]))
9439          (const_int 0)))]
9440   "TARGET_32BIT"
9441   "*
9442   {
9443     static const char *const cmp1[NUM_OF_COND_CMP][2] =
9444     {
9445       {\"cmp%d5\\t%0, %1\",
9446        \"cmp%d4\\t%2, %3\"},
9447       {\"cmn%d5\\t%0, #%n1\",
9448        \"cmp%d4\\t%2, %3\"},
9449       {\"cmp%d5\\t%0, %1\",
9450        \"cmn%d4\\t%2, #%n3\"},
9451       {\"cmn%d5\\t%0, #%n1\",
9452        \"cmn%d4\\t%2, #%n3\"}
9453     };
9454     static const char *const cmp2[NUM_OF_COND_CMP][2] =
9455     {
9456       {\"cmp\\t%2, %3\",
9457        \"cmp\\t%0, %1\"},
9458       {\"cmp\\t%2, %3\",
9459        \"cmn\\t%0, #%n1\"},
9460       {\"cmn\\t%2, #%n3\",
9461        \"cmp\\t%0, %1\"},
9462       {\"cmn\\t%2, #%n3\",
9463        \"cmn\\t%0, #%n1\"}
9464     };
9465     static const char *const ite[2] =
9466     {
9467       \"it\\t%d5\",
9468       \"it\\t%d4\"
9469     };
9470     static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
9471                                    CMP_CMP, CMN_CMP, CMP_CMP,
9472                                    CMN_CMP, CMP_CMN, CMN_CMN};
9473     int swap =
9474       comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
9475
9476     output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
9477     if (TARGET_THUMB2) {
9478       output_asm_insn (ite[swap], operands);
9479     }
9480     output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
9481     return \"\";
9482   }"
9483   [(set_attr "conds" "set")
9484    (set_attr "predicable" "no")
9485    (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
9486    (set_attr_alternative "length"
9487       [(const_int 6)
9488        (const_int 8)
9489        (const_int 8)
9490        (const_int 8)
9491        (const_int 8)
9492        (if_then_else (eq_attr "is_thumb" "no")
9493            (const_int 8)
9494            (const_int 10))
9495        (if_then_else (eq_attr "is_thumb" "no")
9496            (const_int 8)
9497            (const_int 10))
9498        (if_then_else (eq_attr "is_thumb" "no")
9499            (const_int 8)
9500            (const_int 10))
9501        (if_then_else (eq_attr "is_thumb" "no")
9502            (const_int 8)
9503            (const_int 10))])]
9504 )
9505
9506 (define_insn "*cmp_ior"
9507   [(set (match_operand 6 "dominant_cc_register" "")
9508         (compare
9509          (ior:SI
9510           (match_operator 4 "arm_comparison_operator"
9511            [(match_operand:SI 0 "s_register_operand"
9512                 "l,l,l,r,r,r,r,r,r")
9513             (match_operand:SI 1 "arm_add_operand"
9514                 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
9515           (match_operator:SI 5 "arm_comparison_operator"
9516            [(match_operand:SI 2 "s_register_operand"
9517                 "l,r,r,l,l,r,r,r,r")
9518             (match_operand:SI 3 "arm_add_operand"
9519                 "lPy,rI,L,lPy,lPy,rI,rI,L,L")]))
9520          (const_int 0)))]
9521   "TARGET_32BIT"
9522   "*
9523   {
9524     static const char *const cmp1[NUM_OF_COND_CMP][2] =
9525     {
9526       {\"cmp\\t%0, %1\",
9527        \"cmp\\t%2, %3\"},
9528       {\"cmn\\t%0, #%n1\",
9529        \"cmp\\t%2, %3\"},
9530       {\"cmp\\t%0, %1\",
9531        \"cmn\\t%2, #%n3\"},
9532       {\"cmn\\t%0, #%n1\",
9533        \"cmn\\t%2, #%n3\"}
9534     };
9535     static const char *const cmp2[NUM_OF_COND_CMP][2] =
9536     {
9537       {\"cmp%D4\\t%2, %3\",
9538        \"cmp%D5\\t%0, %1\"},
9539       {\"cmp%D4\\t%2, %3\",
9540        \"cmn%D5\\t%0, #%n1\"},
9541       {\"cmn%D4\\t%2, #%n3\",
9542        \"cmp%D5\\t%0, %1\"},
9543       {\"cmn%D4\\t%2, #%n3\",
9544        \"cmn%D5\\t%0, #%n1\"}
9545     };
9546     static const char *const ite[2] =
9547     {
9548       \"it\\t%D4\",
9549       \"it\\t%D5\"
9550     };
9551     static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
9552                                    CMP_CMP, CMN_CMP, CMP_CMP,
9553                                    CMN_CMP, CMP_CMN, CMN_CMN};
9554     int swap =
9555       comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
9556
9557     output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
9558     if (TARGET_THUMB2) {
9559       output_asm_insn (ite[swap], operands);
9560     }
9561     output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
9562     return \"\";
9563   }
9564   "
9565   [(set_attr "conds" "set")
9566    (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
9567    (set_attr_alternative "length"
9568       [(const_int 6)
9569        (const_int 8)
9570        (const_int 8)
9571        (const_int 8)
9572        (const_int 8)
9573        (if_then_else (eq_attr "is_thumb" "no")
9574            (const_int 8)
9575            (const_int 10))
9576        (if_then_else (eq_attr "is_thumb" "no")
9577            (const_int 8)
9578            (const_int 10))
9579        (if_then_else (eq_attr "is_thumb" "no")
9580            (const_int 8)
9581            (const_int 10))
9582        (if_then_else (eq_attr "is_thumb" "no")
9583            (const_int 8)
9584            (const_int 10))])]
9585 )
9586
9587 (define_insn_and_split "*ior_scc_scc"
9588   [(set (match_operand:SI 0 "s_register_operand" "=r")
9589         (ior:SI (match_operator:SI 3 "arm_comparison_operator"
9590                  [(match_operand:SI 1 "s_register_operand" "r")
9591                   (match_operand:SI 2 "arm_add_operand" "rIL")])
9592                 (match_operator:SI 6 "arm_comparison_operator"
9593                  [(match_operand:SI 4 "s_register_operand" "r")
9594                   (match_operand:SI 5 "arm_add_operand" "rIL")])))
9595    (clobber (reg:CC CC_REGNUM))]
9596   "TARGET_32BIT
9597    && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_OR_Y)
9598        != CCmode)"
9599   "#"
9600   "TARGET_32BIT && reload_completed"
9601   [(set (match_dup 7)
9602         (compare
9603          (ior:SI
9604           (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9605           (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9606          (const_int 0)))
9607    (set (match_dup 0) (ne:SI (match_dup 7) (const_int 0)))]
9608   "operands[7]
9609      = gen_rtx_REG (arm_select_dominance_cc_mode (operands[3], operands[6],
9610                                                   DOM_CC_X_OR_Y),
9611                     CC_REGNUM);"
9612   [(set_attr "conds" "clob")
9613    (set_attr "length" "16")])
9614
9615 ; If the above pattern is followed by a CMP insn, then the compare is 
9616 ; redundant, since we can rework the conditional instruction that follows.
9617 (define_insn_and_split "*ior_scc_scc_cmp"
9618   [(set (match_operand 0 "dominant_cc_register" "")
9619         (compare (ior:SI (match_operator:SI 3 "arm_comparison_operator"
9620                           [(match_operand:SI 1 "s_register_operand" "r")
9621                            (match_operand:SI 2 "arm_add_operand" "rIL")])
9622                          (match_operator:SI 6 "arm_comparison_operator"
9623                           [(match_operand:SI 4 "s_register_operand" "r")
9624                            (match_operand:SI 5 "arm_add_operand" "rIL")]))
9625                  (const_int 0)))
9626    (set (match_operand:SI 7 "s_register_operand" "=r")
9627         (ior:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9628                 (match_op_dup 6 [(match_dup 4) (match_dup 5)])))]
9629   "TARGET_32BIT"
9630   "#"
9631   "TARGET_32BIT && reload_completed"
9632   [(set (match_dup 0)
9633         (compare
9634          (ior:SI
9635           (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9636           (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9637          (const_int 0)))
9638    (set (match_dup 7) (ne:SI (match_dup 0) (const_int 0)))]
9639   ""
9640   [(set_attr "conds" "set")
9641    (set_attr "length" "16")])
9642
9643 (define_insn_and_split "*and_scc_scc"
9644   [(set (match_operand:SI 0 "s_register_operand" "=r")
9645         (and:SI (match_operator:SI 3 "arm_comparison_operator"
9646                  [(match_operand:SI 1 "s_register_operand" "r")
9647                   (match_operand:SI 2 "arm_add_operand" "rIL")])
9648                 (match_operator:SI 6 "arm_comparison_operator"
9649                  [(match_operand:SI 4 "s_register_operand" "r")
9650                   (match_operand:SI 5 "arm_add_operand" "rIL")])))
9651    (clobber (reg:CC CC_REGNUM))]
9652   "TARGET_32BIT
9653    && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
9654        != CCmode)"
9655   "#"
9656   "TARGET_32BIT && reload_completed
9657    && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
9658        != CCmode)"
9659   [(set (match_dup 7)
9660         (compare
9661          (and:SI
9662           (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9663           (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9664          (const_int 0)))
9665    (set (match_dup 0) (ne:SI (match_dup 7) (const_int 0)))]
9666   "operands[7]
9667      = gen_rtx_REG (arm_select_dominance_cc_mode (operands[3], operands[6],
9668                                                   DOM_CC_X_AND_Y),
9669                     CC_REGNUM);"
9670   [(set_attr "conds" "clob")
9671    (set_attr "length" "16")])
9672
9673 ; If the above pattern is followed by a CMP insn, then the compare is 
9674 ; redundant, since we can rework the conditional instruction that follows.
9675 (define_insn_and_split "*and_scc_scc_cmp"
9676   [(set (match_operand 0 "dominant_cc_register" "")
9677         (compare (and:SI (match_operator:SI 3 "arm_comparison_operator"
9678                           [(match_operand:SI 1 "s_register_operand" "r")
9679                            (match_operand:SI 2 "arm_add_operand" "rIL")])
9680                          (match_operator:SI 6 "arm_comparison_operator"
9681                           [(match_operand:SI 4 "s_register_operand" "r")
9682                            (match_operand:SI 5 "arm_add_operand" "rIL")]))
9683                  (const_int 0)))
9684    (set (match_operand:SI 7 "s_register_operand" "=r")
9685         (and:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9686                 (match_op_dup 6 [(match_dup 4) (match_dup 5)])))]
9687   "TARGET_32BIT"
9688   "#"
9689   "TARGET_32BIT && reload_completed"
9690   [(set (match_dup 0)
9691         (compare
9692          (and:SI
9693           (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9694           (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9695          (const_int 0)))
9696    (set (match_dup 7) (ne:SI (match_dup 0) (const_int 0)))]
9697   ""
9698   [(set_attr "conds" "set")
9699    (set_attr "length" "16")])
9700
9701 ;; If there is no dominance in the comparison, then we can still save an
9702 ;; instruction in the AND case, since we can know that the second compare
9703 ;; need only zero the value if false (if true, then the value is already
9704 ;; correct).
9705 (define_insn_and_split "*and_scc_scc_nodom"
9706   [(set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r")
9707         (and:SI (match_operator:SI 3 "arm_comparison_operator"
9708                  [(match_operand:SI 1 "s_register_operand" "r,r,0")
9709                   (match_operand:SI 2 "arm_add_operand" "rIL,0,rIL")])
9710                 (match_operator:SI 6 "arm_comparison_operator"
9711                  [(match_operand:SI 4 "s_register_operand" "r,r,r")
9712                   (match_operand:SI 5 "arm_add_operand" "rIL,rIL,rIL")])))
9713    (clobber (reg:CC CC_REGNUM))]
9714   "TARGET_32BIT
9715    && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
9716        == CCmode)"
9717   "#"
9718   "TARGET_32BIT && reload_completed"
9719   [(parallel [(set (match_dup 0)
9720                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
9721               (clobber (reg:CC CC_REGNUM))])
9722    (set (match_dup 7) (match_op_dup 8 [(match_dup 4) (match_dup 5)]))
9723    (set (match_dup 0)
9724         (if_then_else:SI (match_op_dup 6 [(match_dup 7) (const_int 0)])
9725                          (match_dup 0)
9726                          (const_int 0)))]
9727   "operands[7] = gen_rtx_REG (SELECT_CC_MODE (GET_CODE (operands[6]),
9728                                               operands[4], operands[5]),
9729                               CC_REGNUM);
9730    operands[8] = gen_rtx_COMPARE (GET_MODE (operands[7]), operands[4],
9731                                   operands[5]);"
9732   [(set_attr "conds" "clob")
9733    (set_attr "length" "20")])
9734
9735 (define_split
9736   [(set (reg:CC_NOOV CC_REGNUM)
9737         (compare:CC_NOOV (ior:SI
9738                           (and:SI (match_operand:SI 0 "s_register_operand" "")
9739                                   (const_int 1))
9740                           (match_operator:SI 1 "arm_comparison_operator"
9741                            [(match_operand:SI 2 "s_register_operand" "")
9742                             (match_operand:SI 3 "arm_add_operand" "")]))
9743                          (const_int 0)))
9744    (clobber (match_operand:SI 4 "s_register_operand" ""))]
9745   "TARGET_ARM"
9746   [(set (match_dup 4)
9747         (ior:SI (match_op_dup 1 [(match_dup 2) (match_dup 3)])
9748                 (match_dup 0)))
9749    (set (reg:CC_NOOV CC_REGNUM)
9750         (compare:CC_NOOV (and:SI (match_dup 4) (const_int 1))
9751                          (const_int 0)))]
9752   "")
9753
9754 (define_split
9755   [(set (reg:CC_NOOV CC_REGNUM)
9756         (compare:CC_NOOV (ior:SI
9757                           (match_operator:SI 1 "arm_comparison_operator"
9758                            [(match_operand:SI 2 "s_register_operand" "")
9759                             (match_operand:SI 3 "arm_add_operand" "")])
9760                           (and:SI (match_operand:SI 0 "s_register_operand" "")
9761                                   (const_int 1)))
9762                          (const_int 0)))
9763    (clobber (match_operand:SI 4 "s_register_operand" ""))]
9764   "TARGET_ARM"
9765   [(set (match_dup 4)
9766         (ior:SI (match_op_dup 1 [(match_dup 2) (match_dup 3)])
9767                 (match_dup 0)))
9768    (set (reg:CC_NOOV CC_REGNUM)
9769         (compare:CC_NOOV (and:SI (match_dup 4) (const_int 1))
9770                          (const_int 0)))]
9771   "")
9772 ;; ??? The conditional patterns above need checking for Thumb-2 usefulness
9773
9774 (define_insn "*negscc"
9775   [(set (match_operand:SI 0 "s_register_operand" "=r")
9776         (neg:SI (match_operator 3 "arm_comparison_operator"
9777                  [(match_operand:SI 1 "s_register_operand" "r")
9778                   (match_operand:SI 2 "arm_rhs_operand" "rI")])))
9779    (clobber (reg:CC CC_REGNUM))]
9780   "TARGET_ARM"
9781   "*
9782   if (GET_CODE (operands[3]) == LT && operands[2] == const0_rtx)
9783     return \"mov\\t%0, %1, asr #31\";
9784
9785   if (GET_CODE (operands[3]) == NE)
9786     return \"subs\\t%0, %1, %2\;mvnne\\t%0, #0\";
9787
9788   output_asm_insn (\"cmp\\t%1, %2\", operands);
9789   output_asm_insn (\"mov%D3\\t%0, #0\", operands);
9790   return \"mvn%d3\\t%0, #0\";
9791   "
9792   [(set_attr "conds" "clob")
9793    (set_attr "length" "12")]
9794 )
9795
9796 (define_insn "movcond"
9797   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9798         (if_then_else:SI
9799          (match_operator 5 "arm_comparison_operator"
9800           [(match_operand:SI 3 "s_register_operand" "r,r,r")
9801            (match_operand:SI 4 "arm_add_operand" "rIL,rIL,rIL")])
9802          (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
9803          (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
9804    (clobber (reg:CC CC_REGNUM))]
9805   "TARGET_ARM"
9806   "*
9807   if (GET_CODE (operands[5]) == LT
9808       && (operands[4] == const0_rtx))
9809     {
9810       if (which_alternative != 1 && GET_CODE (operands[1]) == REG)
9811         {
9812           if (operands[2] == const0_rtx)
9813             return \"and\\t%0, %1, %3, asr #31\";
9814           return \"ands\\t%0, %1, %3, asr #32\;movcc\\t%0, %2\";
9815         }
9816       else if (which_alternative != 0 && GET_CODE (operands[2]) == REG)
9817         {
9818           if (operands[1] == const0_rtx)
9819             return \"bic\\t%0, %2, %3, asr #31\";
9820           return \"bics\\t%0, %2, %3, asr #32\;movcs\\t%0, %1\";
9821         }
9822       /* The only case that falls through to here is when both ops 1 & 2
9823          are constants.  */
9824     }
9825
9826   if (GET_CODE (operands[5]) == GE
9827       && (operands[4] == const0_rtx))
9828     {
9829       if (which_alternative != 1 && GET_CODE (operands[1]) == REG)
9830         {
9831           if (operands[2] == const0_rtx)
9832             return \"bic\\t%0, %1, %3, asr #31\";
9833           return \"bics\\t%0, %1, %3, asr #32\;movcs\\t%0, %2\";
9834         }
9835       else if (which_alternative != 0 && GET_CODE (operands[2]) == REG)
9836         {
9837           if (operands[1] == const0_rtx)
9838             return \"and\\t%0, %2, %3, asr #31\";
9839           return \"ands\\t%0, %2, %3, asr #32\;movcc\\t%0, %1\";
9840         }
9841       /* The only case that falls through to here is when both ops 1 & 2
9842          are constants.  */
9843     }
9844   if (GET_CODE (operands[4]) == CONST_INT
9845       && !const_ok_for_arm (INTVAL (operands[4])))
9846     output_asm_insn (\"cmn\\t%3, #%n4\", operands);
9847   else
9848     output_asm_insn (\"cmp\\t%3, %4\", operands);
9849   if (which_alternative != 0)
9850     output_asm_insn (\"mov%d5\\t%0, %1\", operands);
9851   if (which_alternative != 1)
9852     output_asm_insn (\"mov%D5\\t%0, %2\", operands);
9853   return \"\";
9854   "
9855   [(set_attr "conds" "clob")
9856    (set_attr "length" "8,8,12")]
9857 )
9858
9859 ;; ??? The patterns below need checking for Thumb-2 usefulness.
9860
9861 (define_insn "*ifcompare_plus_move"
9862   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9863         (if_then_else:SI (match_operator 6 "arm_comparison_operator"
9864                           [(match_operand:SI 4 "s_register_operand" "r,r")
9865                            (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
9866                          (plus:SI
9867                           (match_operand:SI 2 "s_register_operand" "r,r")
9868                           (match_operand:SI 3 "arm_add_operand" "rIL,rIL"))
9869                          (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))
9870    (clobber (reg:CC CC_REGNUM))]
9871   "TARGET_ARM"
9872   "#"
9873   [(set_attr "conds" "clob")
9874    (set_attr "length" "8,12")]
9875 )
9876
9877 (define_insn "*if_plus_move"
9878   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
9879         (if_then_else:SI
9880          (match_operator 4 "arm_comparison_operator"
9881           [(match_operand 5 "cc_register" "") (const_int 0)])
9882          (plus:SI
9883           (match_operand:SI 2 "s_register_operand" "r,r,r,r")
9884           (match_operand:SI 3 "arm_add_operand" "rI,L,rI,L"))
9885          (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")))]
9886   "TARGET_ARM"
9887   "@
9888    add%d4\\t%0, %2, %3
9889    sub%d4\\t%0, %2, #%n3
9890    add%d4\\t%0, %2, %3\;mov%D4\\t%0, %1
9891    sub%d4\\t%0, %2, #%n3\;mov%D4\\t%0, %1"
9892   [(set_attr "conds" "use")
9893    (set_attr "length" "4,4,8,8")
9894    (set_attr "type" "*,*,*,*")]
9895 )
9896
9897 (define_insn "*ifcompare_move_plus"
9898   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9899         (if_then_else:SI (match_operator 6 "arm_comparison_operator"
9900                           [(match_operand:SI 4 "s_register_operand" "r,r")
9901                            (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
9902                          (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
9903                          (plus:SI
9904                           (match_operand:SI 2 "s_register_operand" "r,r")
9905                           (match_operand:SI 3 "arm_add_operand" "rIL,rIL"))))
9906    (clobber (reg:CC CC_REGNUM))]
9907   "TARGET_ARM"
9908   "#"
9909   [(set_attr "conds" "clob")
9910    (set_attr "length" "8,12")]
9911 )
9912
9913 (define_insn "*if_move_plus"
9914   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
9915         (if_then_else:SI
9916          (match_operator 4 "arm_comparison_operator"
9917           [(match_operand 5 "cc_register" "") (const_int 0)])
9918          (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")
9919          (plus:SI
9920           (match_operand:SI 2 "s_register_operand" "r,r,r,r")
9921           (match_operand:SI 3 "arm_add_operand" "rI,L,rI,L"))))]
9922   "TARGET_ARM"
9923   "@
9924    add%D4\\t%0, %2, %3
9925    sub%D4\\t%0, %2, #%n3
9926    add%D4\\t%0, %2, %3\;mov%d4\\t%0, %1
9927    sub%D4\\t%0, %2, #%n3\;mov%d4\\t%0, %1"
9928   [(set_attr "conds" "use")
9929    (set_attr "length" "4,4,8,8")
9930    (set_attr "type" "*,*,*,*")]
9931 )
9932
9933 (define_insn "*ifcompare_arith_arith"
9934   [(set (match_operand:SI 0 "s_register_operand" "=r")
9935         (if_then_else:SI (match_operator 9 "arm_comparison_operator"
9936                           [(match_operand:SI 5 "s_register_operand" "r")
9937                            (match_operand:SI 6 "arm_add_operand" "rIL")])
9938                          (match_operator:SI 8 "shiftable_operator"
9939                           [(match_operand:SI 1 "s_register_operand" "r")
9940                            (match_operand:SI 2 "arm_rhs_operand" "rI")])
9941                          (match_operator:SI 7 "shiftable_operator"
9942                           [(match_operand:SI 3 "s_register_operand" "r")
9943                            (match_operand:SI 4 "arm_rhs_operand" "rI")])))
9944    (clobber (reg:CC CC_REGNUM))]
9945   "TARGET_ARM"
9946   "#"
9947   [(set_attr "conds" "clob")
9948    (set_attr "length" "12")]
9949 )
9950
9951 (define_insn "*if_arith_arith"
9952   [(set (match_operand:SI 0 "s_register_operand" "=r")
9953         (if_then_else:SI (match_operator 5 "arm_comparison_operator"
9954                           [(match_operand 8 "cc_register" "") (const_int 0)])
9955                          (match_operator:SI 6 "shiftable_operator"
9956                           [(match_operand:SI 1 "s_register_operand" "r")
9957                            (match_operand:SI 2 "arm_rhs_operand" "rI")])
9958                          (match_operator:SI 7 "shiftable_operator"
9959                           [(match_operand:SI 3 "s_register_operand" "r")
9960                            (match_operand:SI 4 "arm_rhs_operand" "rI")])))]
9961   "TARGET_ARM"
9962   "%I6%d5\\t%0, %1, %2\;%I7%D5\\t%0, %3, %4"
9963   [(set_attr "conds" "use")
9964    (set_attr "length" "8")]
9965 )
9966
9967 (define_insn "*ifcompare_arith_move"
9968   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9969         (if_then_else:SI (match_operator 6 "arm_comparison_operator"
9970                           [(match_operand:SI 2 "s_register_operand" "r,r")
9971                            (match_operand:SI 3 "arm_add_operand" "rIL,rIL")])
9972                          (match_operator:SI 7 "shiftable_operator"
9973                           [(match_operand:SI 4 "s_register_operand" "r,r")
9974                            (match_operand:SI 5 "arm_rhs_operand" "rI,rI")])
9975                          (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))
9976    (clobber (reg:CC CC_REGNUM))]
9977   "TARGET_ARM"
9978   "*
9979   /* If we have an operation where (op x 0) is the identity operation and
9980      the conditional operator is LT or GE and we are comparing against zero and
9981      everything is in registers then we can do this in two instructions.  */
9982   if (operands[3] == const0_rtx
9983       && GET_CODE (operands[7]) != AND
9984       && GET_CODE (operands[5]) == REG
9985       && GET_CODE (operands[1]) == REG 
9986       && REGNO (operands[1]) == REGNO (operands[4])
9987       && REGNO (operands[4]) != REGNO (operands[0]))
9988     {
9989       if (GET_CODE (operands[6]) == LT)
9990         return \"and\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\";
9991       else if (GET_CODE (operands[6]) == GE)
9992         return \"bic\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\";
9993     }
9994   if (GET_CODE (operands[3]) == CONST_INT
9995       && !const_ok_for_arm (INTVAL (operands[3])))
9996     output_asm_insn (\"cmn\\t%2, #%n3\", operands);
9997   else
9998     output_asm_insn (\"cmp\\t%2, %3\", operands);
9999   output_asm_insn (\"%I7%d6\\t%0, %4, %5\", operands);
10000   if (which_alternative != 0)
10001     return \"mov%D6\\t%0, %1\";
10002   return \"\";
10003   "
10004   [(set_attr "conds" "clob")
10005    (set_attr "length" "8,12")]
10006 )
10007
10008 (define_insn "*if_arith_move"
10009   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10010         (if_then_else:SI (match_operator 4 "arm_comparison_operator"
10011                           [(match_operand 6 "cc_register" "") (const_int 0)])
10012                          (match_operator:SI 5 "shiftable_operator"
10013                           [(match_operand:SI 2 "s_register_operand" "r,r")
10014                            (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
10015                          (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))]
10016   "TARGET_ARM"
10017   "@
10018    %I5%d4\\t%0, %2, %3
10019    %I5%d4\\t%0, %2, %3\;mov%D4\\t%0, %1"
10020   [(set_attr "conds" "use")
10021    (set_attr "length" "4,8")
10022    (set_attr "type" "*,*")]
10023 )
10024
10025 (define_insn "*ifcompare_move_arith"
10026   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10027         (if_then_else:SI (match_operator 6 "arm_comparison_operator"
10028                           [(match_operand:SI 4 "s_register_operand" "r,r")
10029                            (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
10030                          (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
10031                          (match_operator:SI 7 "shiftable_operator"
10032                           [(match_operand:SI 2 "s_register_operand" "r,r")
10033                            (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
10034    (clobber (reg:CC CC_REGNUM))]
10035   "TARGET_ARM"
10036   "*
10037   /* If we have an operation where (op x 0) is the identity operation and
10038      the conditional operator is LT or GE and we are comparing against zero and
10039      everything is in registers then we can do this in two instructions */
10040   if (operands[5] == const0_rtx
10041       && GET_CODE (operands[7]) != AND
10042       && GET_CODE (operands[3]) == REG
10043       && GET_CODE (operands[1]) == REG 
10044       && REGNO (operands[1]) == REGNO (operands[2])
10045       && REGNO (operands[2]) != REGNO (operands[0]))
10046     {
10047       if (GET_CODE (operands[6]) == GE)
10048         return \"and\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\";
10049       else if (GET_CODE (operands[6]) == LT)
10050         return \"bic\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\";
10051     }
10052
10053   if (GET_CODE (operands[5]) == CONST_INT
10054       && !const_ok_for_arm (INTVAL (operands[5])))
10055     output_asm_insn (\"cmn\\t%4, #%n5\", operands);
10056   else
10057     output_asm_insn (\"cmp\\t%4, %5\", operands);
10058
10059   if (which_alternative != 0)
10060     output_asm_insn (\"mov%d6\\t%0, %1\", operands);
10061   return \"%I7%D6\\t%0, %2, %3\";
10062   "
10063   [(set_attr "conds" "clob")
10064    (set_attr "length" "8,12")]
10065 )
10066
10067 (define_insn "*if_move_arith"
10068   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10069         (if_then_else:SI
10070          (match_operator 4 "arm_comparison_operator"
10071           [(match_operand 6 "cc_register" "") (const_int 0)])
10072          (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
10073          (match_operator:SI 5 "shiftable_operator"
10074           [(match_operand:SI 2 "s_register_operand" "r,r")
10075            (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))]
10076   "TARGET_ARM"
10077   "@
10078    %I5%D4\\t%0, %2, %3
10079    %I5%D4\\t%0, %2, %3\;mov%d4\\t%0, %1"
10080   [(set_attr "conds" "use")
10081    (set_attr "length" "4,8")
10082    (set_attr "type" "*,*")]
10083 )
10084
10085 (define_insn "*ifcompare_move_not"
10086   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10087         (if_then_else:SI
10088          (match_operator 5 "arm_comparison_operator"
10089           [(match_operand:SI 3 "s_register_operand" "r,r")
10090            (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
10091          (match_operand:SI 1 "arm_not_operand" "0,?rIK")
10092          (not:SI
10093           (match_operand:SI 2 "s_register_operand" "r,r"))))
10094    (clobber (reg:CC CC_REGNUM))]
10095   "TARGET_ARM"
10096   "#"
10097   [(set_attr "conds" "clob")
10098    (set_attr "length" "8,12")]
10099 )
10100
10101 (define_insn "*if_move_not"
10102   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
10103         (if_then_else:SI
10104          (match_operator 4 "arm_comparison_operator"
10105           [(match_operand 3 "cc_register" "") (const_int 0)])
10106          (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
10107          (not:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))))]
10108   "TARGET_ARM"
10109   "@
10110    mvn%D4\\t%0, %2
10111    mov%d4\\t%0, %1\;mvn%D4\\t%0, %2
10112    mvn%d4\\t%0, #%B1\;mvn%D4\\t%0, %2"
10113   [(set_attr "conds" "use")
10114    (set_attr "insn" "mvn")
10115    (set_attr "length" "4,8,8")]
10116 )
10117
10118 (define_insn "*ifcompare_not_move"
10119   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10120         (if_then_else:SI 
10121          (match_operator 5 "arm_comparison_operator"
10122           [(match_operand:SI 3 "s_register_operand" "r,r")
10123            (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
10124          (not:SI
10125           (match_operand:SI 2 "s_register_operand" "r,r"))
10126          (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
10127    (clobber (reg:CC CC_REGNUM))]
10128   "TARGET_ARM"
10129   "#"
10130   [(set_attr "conds" "clob")
10131    (set_attr "length" "8,12")]
10132 )
10133
10134 (define_insn "*if_not_move"
10135   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
10136         (if_then_else:SI
10137          (match_operator 4 "arm_comparison_operator"
10138           [(match_operand 3 "cc_register" "") (const_int 0)])
10139          (not:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))
10140          (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
10141   "TARGET_ARM"
10142   "@
10143    mvn%d4\\t%0, %2
10144    mov%D4\\t%0, %1\;mvn%d4\\t%0, %2
10145    mvn%D4\\t%0, #%B1\;mvn%d4\\t%0, %2"
10146   [(set_attr "conds" "use")
10147    (set_attr "insn" "mvn")
10148    (set_attr "length" "4,8,8")]
10149 )
10150
10151 (define_insn "*ifcompare_shift_move"
10152   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10153         (if_then_else:SI
10154          (match_operator 6 "arm_comparison_operator"
10155           [(match_operand:SI 4 "s_register_operand" "r,r")
10156            (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
10157          (match_operator:SI 7 "shift_operator"
10158           [(match_operand:SI 2 "s_register_operand" "r,r")
10159            (match_operand:SI 3 "arm_rhs_operand" "rM,rM")])
10160          (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
10161    (clobber (reg:CC CC_REGNUM))]
10162   "TARGET_ARM"
10163   "#"
10164   [(set_attr "conds" "clob")
10165    (set_attr "length" "8,12")]
10166 )
10167
10168 (define_insn "*if_shift_move"
10169   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
10170         (if_then_else:SI
10171          (match_operator 5 "arm_comparison_operator"
10172           [(match_operand 6 "cc_register" "") (const_int 0)])
10173          (match_operator:SI 4 "shift_operator"
10174           [(match_operand:SI 2 "s_register_operand" "r,r,r")
10175            (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM")])
10176          (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
10177   "TARGET_ARM"
10178   "@
10179    mov%d5\\t%0, %2%S4
10180    mov%D5\\t%0, %1\;mov%d5\\t%0, %2%S4
10181    mvn%D5\\t%0, #%B1\;mov%d5\\t%0, %2%S4"
10182   [(set_attr "conds" "use")
10183    (set_attr "shift" "2")
10184    (set_attr "length" "4,8,8")
10185    (set_attr "insn" "mov")
10186    (set (attr "type") (if_then_else (match_operand 3 "const_int_operand" "")
10187                       (const_string "alu_shift")
10188                       (const_string "alu_shift_reg")))]
10189 )
10190
10191 (define_insn "*ifcompare_move_shift"
10192   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10193         (if_then_else:SI
10194          (match_operator 6 "arm_comparison_operator"
10195           [(match_operand:SI 4 "s_register_operand" "r,r")
10196            (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
10197          (match_operand:SI 1 "arm_not_operand" "0,?rIK")
10198          (match_operator:SI 7 "shift_operator"
10199           [(match_operand:SI 2 "s_register_operand" "r,r")
10200            (match_operand:SI 3 "arm_rhs_operand" "rM,rM")])))
10201    (clobber (reg:CC CC_REGNUM))]
10202   "TARGET_ARM"
10203   "#"
10204   [(set_attr "conds" "clob")
10205    (set_attr "length" "8,12")]
10206 )
10207
10208 (define_insn "*if_move_shift"
10209   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
10210         (if_then_else:SI
10211          (match_operator 5 "arm_comparison_operator"
10212           [(match_operand 6 "cc_register" "") (const_int 0)])
10213          (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
10214          (match_operator:SI 4 "shift_operator"
10215           [(match_operand:SI 2 "s_register_operand" "r,r,r")
10216            (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM")])))]
10217   "TARGET_ARM"
10218   "@
10219    mov%D5\\t%0, %2%S4
10220    mov%d5\\t%0, %1\;mov%D5\\t%0, %2%S4
10221    mvn%d5\\t%0, #%B1\;mov%D5\\t%0, %2%S4"
10222   [(set_attr "conds" "use")
10223    (set_attr "shift" "2")
10224    (set_attr "length" "4,8,8")
10225    (set_attr "insn" "mov")
10226    (set (attr "type") (if_then_else (match_operand 3 "const_int_operand" "")
10227                       (const_string "alu_shift")
10228                       (const_string "alu_shift_reg")))]
10229 )
10230
10231 (define_insn "*ifcompare_shift_shift"
10232   [(set (match_operand:SI 0 "s_register_operand" "=r")
10233         (if_then_else:SI
10234          (match_operator 7 "arm_comparison_operator"
10235           [(match_operand:SI 5 "s_register_operand" "r")
10236            (match_operand:SI 6 "arm_add_operand" "rIL")])
10237          (match_operator:SI 8 "shift_operator"
10238           [(match_operand:SI 1 "s_register_operand" "r")
10239            (match_operand:SI 2 "arm_rhs_operand" "rM")])
10240          (match_operator:SI 9 "shift_operator"
10241           [(match_operand:SI 3 "s_register_operand" "r")
10242            (match_operand:SI 4 "arm_rhs_operand" "rM")])))
10243    (clobber (reg:CC CC_REGNUM))]
10244   "TARGET_ARM"
10245   "#"
10246   [(set_attr "conds" "clob")
10247    (set_attr "length" "12")]
10248 )
10249
10250 (define_insn "*if_shift_shift"
10251   [(set (match_operand:SI 0 "s_register_operand" "=r")
10252         (if_then_else:SI
10253          (match_operator 5 "arm_comparison_operator"
10254           [(match_operand 8 "cc_register" "") (const_int 0)])
10255          (match_operator:SI 6 "shift_operator"
10256           [(match_operand:SI 1 "s_register_operand" "r")
10257            (match_operand:SI 2 "arm_rhs_operand" "rM")])
10258          (match_operator:SI 7 "shift_operator"
10259           [(match_operand:SI 3 "s_register_operand" "r")
10260            (match_operand:SI 4 "arm_rhs_operand" "rM")])))]
10261   "TARGET_ARM"
10262   "mov%d5\\t%0, %1%S6\;mov%D5\\t%0, %3%S7"
10263   [(set_attr "conds" "use")
10264    (set_attr "shift" "1")
10265    (set_attr "length" "8")
10266    (set_attr "insn" "mov")
10267    (set (attr "type") (if_then_else
10268                         (and (match_operand 2 "const_int_operand" "")
10269                              (match_operand 4 "const_int_operand" ""))
10270                       (const_string "alu_shift")
10271                       (const_string "alu_shift_reg")))]
10272 )
10273
10274 (define_insn "*ifcompare_not_arith"
10275   [(set (match_operand:SI 0 "s_register_operand" "=r")
10276         (if_then_else:SI
10277          (match_operator 6 "arm_comparison_operator"
10278           [(match_operand:SI 4 "s_register_operand" "r")
10279            (match_operand:SI 5 "arm_add_operand" "rIL")])
10280          (not:SI (match_operand:SI 1 "s_register_operand" "r"))
10281          (match_operator:SI 7 "shiftable_operator"
10282           [(match_operand:SI 2 "s_register_operand" "r")
10283            (match_operand:SI 3 "arm_rhs_operand" "rI")])))
10284    (clobber (reg:CC CC_REGNUM))]
10285   "TARGET_ARM"
10286   "#"
10287   [(set_attr "conds" "clob")
10288    (set_attr "length" "12")]
10289 )
10290
10291 (define_insn "*if_not_arith"
10292   [(set (match_operand:SI 0 "s_register_operand" "=r")
10293         (if_then_else:SI
10294          (match_operator 5 "arm_comparison_operator"
10295           [(match_operand 4 "cc_register" "") (const_int 0)])
10296          (not:SI (match_operand:SI 1 "s_register_operand" "r"))
10297          (match_operator:SI 6 "shiftable_operator"
10298           [(match_operand:SI 2 "s_register_operand" "r")
10299            (match_operand:SI 3 "arm_rhs_operand" "rI")])))]
10300   "TARGET_ARM"
10301   "mvn%d5\\t%0, %1\;%I6%D5\\t%0, %2, %3"
10302   [(set_attr "conds" "use")
10303    (set_attr "insn" "mvn")
10304    (set_attr "length" "8")]
10305 )
10306
10307 (define_insn "*ifcompare_arith_not"
10308   [(set (match_operand:SI 0 "s_register_operand" "=r")
10309         (if_then_else:SI
10310          (match_operator 6 "arm_comparison_operator"
10311           [(match_operand:SI 4 "s_register_operand" "r")
10312            (match_operand:SI 5 "arm_add_operand" "rIL")])
10313          (match_operator:SI 7 "shiftable_operator"
10314           [(match_operand:SI 2 "s_register_operand" "r")
10315            (match_operand:SI 3 "arm_rhs_operand" "rI")])
10316          (not:SI (match_operand:SI 1 "s_register_operand" "r"))))
10317    (clobber (reg:CC CC_REGNUM))]
10318   "TARGET_ARM"
10319   "#"
10320   [(set_attr "conds" "clob")
10321    (set_attr "length" "12")]
10322 )
10323
10324 (define_insn "*if_arith_not"
10325   [(set (match_operand:SI 0 "s_register_operand" "=r")
10326         (if_then_else:SI
10327          (match_operator 5 "arm_comparison_operator"
10328           [(match_operand 4 "cc_register" "") (const_int 0)])
10329          (match_operator:SI 6 "shiftable_operator"
10330           [(match_operand:SI 2 "s_register_operand" "r")
10331            (match_operand:SI 3 "arm_rhs_operand" "rI")])
10332          (not:SI (match_operand:SI 1 "s_register_operand" "r"))))]
10333   "TARGET_ARM"
10334   "mvn%D5\\t%0, %1\;%I6%d5\\t%0, %2, %3"
10335   [(set_attr "conds" "use")
10336    (set_attr "insn" "mvn")
10337    (set_attr "length" "8")]
10338 )
10339
10340 (define_insn "*ifcompare_neg_move"
10341   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10342         (if_then_else:SI
10343          (match_operator 5 "arm_comparison_operator"
10344           [(match_operand:SI 3 "s_register_operand" "r,r")
10345            (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
10346          (neg:SI (match_operand:SI 2 "s_register_operand" "r,r"))
10347          (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
10348    (clobber (reg:CC CC_REGNUM))]
10349   "TARGET_ARM"
10350   "#"
10351   [(set_attr "conds" "clob")
10352    (set_attr "length" "8,12")]
10353 )
10354
10355 (define_insn "*if_neg_move"
10356   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
10357         (if_then_else:SI
10358          (match_operator 4 "arm_comparison_operator"
10359           [(match_operand 3 "cc_register" "") (const_int 0)])
10360          (neg:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))
10361          (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
10362   "TARGET_ARM"
10363   "@
10364    rsb%d4\\t%0, %2, #0
10365    mov%D4\\t%0, %1\;rsb%d4\\t%0, %2, #0
10366    mvn%D4\\t%0, #%B1\;rsb%d4\\t%0, %2, #0"
10367   [(set_attr "conds" "use")
10368    (set_attr "length" "4,8,8")]
10369 )
10370
10371 (define_insn "*ifcompare_move_neg"
10372   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10373         (if_then_else:SI
10374          (match_operator 5 "arm_comparison_operator"
10375           [(match_operand:SI 3 "s_register_operand" "r,r")
10376            (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
10377          (match_operand:SI 1 "arm_not_operand" "0,?rIK")
10378          (neg:SI (match_operand:SI 2 "s_register_operand" "r,r"))))
10379    (clobber (reg:CC CC_REGNUM))]
10380   "TARGET_ARM"
10381   "#"
10382   [(set_attr "conds" "clob")
10383    (set_attr "length" "8,12")]
10384 )
10385
10386 (define_insn "*if_move_neg"
10387   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
10388         (if_then_else:SI
10389          (match_operator 4 "arm_comparison_operator"
10390           [(match_operand 3 "cc_register" "") (const_int 0)])
10391          (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
10392          (neg:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))))]
10393   "TARGET_ARM"
10394   "@
10395    rsb%D4\\t%0, %2, #0
10396    mov%d4\\t%0, %1\;rsb%D4\\t%0, %2, #0
10397    mvn%d4\\t%0, #%B1\;rsb%D4\\t%0, %2, #0"
10398   [(set_attr "conds" "use")
10399    (set_attr "length" "4,8,8")]
10400 )
10401
10402 (define_insn "*arith_adjacentmem"
10403   [(set (match_operand:SI 0 "s_register_operand" "=r")
10404         (match_operator:SI 1 "shiftable_operator"
10405          [(match_operand:SI 2 "memory_operand" "m")
10406           (match_operand:SI 3 "memory_operand" "m")]))
10407    (clobber (match_scratch:SI 4 "=r"))]
10408   "TARGET_ARM && adjacent_mem_locations (operands[2], operands[3])"
10409   "*
10410   {
10411     rtx ldm[3];
10412     rtx arith[4];
10413     rtx base_reg;
10414     HOST_WIDE_INT val1 = 0, val2 = 0;
10415
10416     if (REGNO (operands[0]) > REGNO (operands[4]))
10417       {
10418         ldm[1] = operands[4];
10419         ldm[2] = operands[0];
10420       }
10421     else
10422       {
10423         ldm[1] = operands[0];
10424         ldm[2] = operands[4];
10425       }
10426
10427     base_reg = XEXP (operands[2], 0);
10428
10429     if (!REG_P (base_reg))
10430       {
10431         val1 = INTVAL (XEXP (base_reg, 1));
10432         base_reg = XEXP (base_reg, 0);
10433       }
10434
10435     if (!REG_P (XEXP (operands[3], 0)))
10436       val2 = INTVAL (XEXP (XEXP (operands[3], 0), 1));
10437
10438     arith[0] = operands[0];
10439     arith[3] = operands[1];
10440
10441     if (val1 < val2)
10442       {
10443         arith[1] = ldm[1];
10444         arith[2] = ldm[2];
10445       }
10446     else
10447       {
10448         arith[1] = ldm[2];
10449         arith[2] = ldm[1];
10450       }
10451
10452     ldm[0] = base_reg;
10453     if (val1 !=0 && val2 != 0)
10454       {
10455         rtx ops[3];
10456
10457         if (val1 == 4 || val2 == 4)
10458           /* Other val must be 8, since we know they are adjacent and neither
10459              is zero.  */
10460           output_asm_insn (\"ldm%(ib%)\\t%0, {%1, %2}\", ldm);
10461         else if (const_ok_for_arm (val1) || const_ok_for_arm (-val1))
10462           {
10463             ldm[0] = ops[0] = operands[4];
10464             ops[1] = base_reg;
10465             ops[2] = GEN_INT (val1);
10466             output_add_immediate (ops);
10467             if (val1 < val2)
10468               output_asm_insn (\"ldm%(ia%)\\t%0, {%1, %2}\", ldm);
10469             else
10470               output_asm_insn (\"ldm%(da%)\\t%0, {%1, %2}\", ldm);
10471           }
10472         else
10473           {
10474             /* Offset is out of range for a single add, so use two ldr.  */
10475             ops[0] = ldm[1];
10476             ops[1] = base_reg;
10477             ops[2] = GEN_INT (val1);
10478             output_asm_insn (\"ldr%?\\t%0, [%1, %2]\", ops);
10479             ops[0] = ldm[2];
10480             ops[2] = GEN_INT (val2);
10481             output_asm_insn (\"ldr%?\\t%0, [%1, %2]\", ops);
10482           }
10483       }
10484     else if (val1 != 0)
10485       {
10486         if (val1 < val2)
10487           output_asm_insn (\"ldm%(da%)\\t%0, {%1, %2}\", ldm);
10488         else
10489           output_asm_insn (\"ldm%(ia%)\\t%0, {%1, %2}\", ldm);
10490       }
10491     else
10492       {
10493         if (val1 < val2)
10494           output_asm_insn (\"ldm%(ia%)\\t%0, {%1, %2}\", ldm);
10495         else
10496           output_asm_insn (\"ldm%(da%)\\t%0, {%1, %2}\", ldm);
10497       }
10498     output_asm_insn (\"%I3%?\\t%0, %1, %2\", arith);
10499     return \"\";
10500   }"
10501   [(set_attr "length" "12")
10502    (set_attr "predicable" "yes")
10503    (set_attr "type" "load1")]
10504 )
10505
10506 ; This pattern is never tried by combine, so do it as a peephole
10507
10508 (define_peephole2
10509   [(set (match_operand:SI 0 "arm_general_register_operand" "")
10510         (match_operand:SI 1 "arm_general_register_operand" ""))
10511    (set (reg:CC CC_REGNUM)
10512         (compare:CC (match_dup 1) (const_int 0)))]
10513   "TARGET_ARM"
10514   [(parallel [(set (reg:CC CC_REGNUM) (compare:CC (match_dup 1) (const_int 0)))
10515               (set (match_dup 0) (match_dup 1))])]
10516   ""
10517 )
10518
10519 (define_split
10520   [(set (match_operand:SI 0 "s_register_operand" "")
10521         (and:SI (ge:SI (match_operand:SI 1 "s_register_operand" "")
10522                        (const_int 0))
10523                 (neg:SI (match_operator:SI 2 "arm_comparison_operator"
10524                          [(match_operand:SI 3 "s_register_operand" "")
10525                           (match_operand:SI 4 "arm_rhs_operand" "")]))))
10526    (clobber (match_operand:SI 5 "s_register_operand" ""))]
10527   "TARGET_ARM"
10528   [(set (match_dup 5) (not:SI (ashiftrt:SI (match_dup 1) (const_int 31))))
10529    (set (match_dup 0) (and:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
10530                               (match_dup 5)))]
10531   ""
10532 )
10533
10534 ;; This split can be used because CC_Z mode implies that the following
10535 ;; branch will be an equality, or an unsigned inequality, so the sign
10536 ;; extension is not needed.
10537
10538 (define_split
10539   [(set (reg:CC_Z CC_REGNUM)
10540         (compare:CC_Z
10541          (ashift:SI (subreg:SI (match_operand:QI 0 "memory_operand" "") 0)
10542                     (const_int 24))
10543          (match_operand 1 "const_int_operand" "")))
10544    (clobber (match_scratch:SI 2 ""))]
10545   "TARGET_ARM
10546    && (((unsigned HOST_WIDE_INT) INTVAL (operands[1]))
10547        == (((unsigned HOST_WIDE_INT) INTVAL (operands[1])) >> 24) << 24)"
10548   [(set (match_dup 2) (zero_extend:SI (match_dup 0)))
10549    (set (reg:CC CC_REGNUM) (compare:CC (match_dup 2) (match_dup 1)))]
10550   "
10551   operands[1] = GEN_INT (((unsigned long) INTVAL (operands[1])) >> 24);
10552   "
10553 )
10554 ;; ??? Check the patterns above for Thumb-2 usefulness
10555
10556 (define_expand "prologue"
10557   [(clobber (const_int 0))]
10558   "TARGET_EITHER"
10559   "if (TARGET_32BIT)
10560      arm_expand_prologue ();
10561    else
10562      thumb1_expand_prologue ();
10563   DONE;
10564   "
10565 )
10566
10567 (define_expand "epilogue"
10568   [(clobber (const_int 0))]
10569   "TARGET_EITHER"
10570   "
10571   if (crtl->calls_eh_return)
10572     emit_insn (gen_prologue_use (gen_rtx_REG (Pmode, 2)));
10573   if (TARGET_THUMB1)
10574     thumb1_expand_epilogue ();
10575   else if (USE_RETURN_INSN (FALSE))
10576     {
10577       emit_jump_insn (gen_return ());
10578       DONE;
10579     }
10580   emit_jump_insn (gen_rtx_UNSPEC_VOLATILE (VOIDmode,
10581         gen_rtvec (1, ret_rtx), VUNSPEC_EPILOGUE));
10582   DONE;
10583   "
10584 )
10585
10586 (define_insn "prologue_thumb1_interwork"
10587   [(unspec_volatile [(const_int 0)] VUNSPEC_THUMB1_INTERWORK)]
10588   "TARGET_THUMB1"
10589   "* return thumb1_output_interwork ();"
10590   [(set_attr "length" "8")]
10591 )
10592
10593 ;; Note - although unspec_volatile's USE all hard registers,
10594 ;; USEs are ignored after relaod has completed.  Thus we need
10595 ;; to add an unspec of the link register to ensure that flow
10596 ;; does not think that it is unused by the sibcall branch that
10597 ;; will replace the standard function epilogue.
10598 (define_insn "sibcall_epilogue"
10599   [(parallel [(unspec:SI [(reg:SI LR_REGNUM)] UNSPEC_PROLOGUE_USE)
10600               (unspec_volatile [(return)] VUNSPEC_EPILOGUE)])]
10601   "TARGET_32BIT"
10602   "*
10603   if (use_return_insn (FALSE, next_nonnote_insn (insn)))
10604     return output_return_instruction (const_true_rtx, FALSE, FALSE);
10605   return arm_output_epilogue (next_nonnote_insn (insn));
10606   "
10607 ;; Length is absolute worst case
10608   [(set_attr "length" "44")
10609    (set_attr "type" "block")
10610    ;; We don't clobber the conditions, but the potential length of this
10611    ;; operation is sufficient to make conditionalizing the sequence 
10612    ;; unlikely to be profitable.
10613    (set_attr "conds" "clob")]
10614 )
10615
10616 (define_insn "*epilogue_insns"
10617   [(unspec_volatile [(return)] VUNSPEC_EPILOGUE)]
10618   "TARGET_EITHER"
10619   "*
10620   if (TARGET_32BIT)
10621     return arm_output_epilogue (NULL);
10622   else /* TARGET_THUMB1 */
10623     return thumb_unexpanded_epilogue ();
10624   "
10625   ; Length is absolute worst case
10626   [(set_attr "length" "44")
10627    (set_attr "type" "block")
10628    ;; We don't clobber the conditions, but the potential length of this
10629    ;; operation is sufficient to make conditionalizing the sequence 
10630    ;; unlikely to be profitable.
10631    (set_attr "conds" "clob")]
10632 )
10633
10634 (define_expand "eh_epilogue"
10635   [(use (match_operand:SI 0 "register_operand" ""))
10636    (use (match_operand:SI 1 "register_operand" ""))
10637    (use (match_operand:SI 2 "register_operand" ""))]
10638   "TARGET_EITHER"
10639   "
10640   {
10641     cfun->machine->eh_epilogue_sp_ofs = operands[1];
10642     if (GET_CODE (operands[2]) != REG || REGNO (operands[2]) != 2)
10643       {
10644         rtx ra = gen_rtx_REG (Pmode, 2);
10645
10646         emit_move_insn (ra, operands[2]);
10647         operands[2] = ra;
10648       }
10649     /* This is a hack -- we may have crystalized the function type too
10650        early.  */
10651     cfun->machine->func_type = 0;
10652   }"
10653 )
10654
10655 ;; This split is only used during output to reduce the number of patterns
10656 ;; that need assembler instructions adding to them.  We allowed the setting
10657 ;; of the conditions to be implicit during rtl generation so that
10658 ;; the conditional compare patterns would work.  However this conflicts to
10659 ;; some extent with the conditional data operations, so we have to split them
10660 ;; up again here.
10661
10662 ;; ??? Need to audit these splitters for Thumb-2.  Why isn't normal
10663 ;; conditional execution sufficient?
10664
10665 (define_split
10666   [(set (match_operand:SI 0 "s_register_operand" "")
10667         (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10668                           [(match_operand 2 "" "") (match_operand 3 "" "")])
10669                          (match_dup 0)
10670                          (match_operand 4 "" "")))
10671    (clobber (reg:CC CC_REGNUM))]
10672   "TARGET_ARM && reload_completed"
10673   [(set (match_dup 5) (match_dup 6))
10674    (cond_exec (match_dup 7)
10675               (set (match_dup 0) (match_dup 4)))]
10676   "
10677   {
10678     enum machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10679                                              operands[2], operands[3]);
10680     enum rtx_code rc = GET_CODE (operands[1]);
10681
10682     operands[5] = gen_rtx_REG (mode, CC_REGNUM);
10683     operands[6] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10684     if (mode == CCFPmode || mode == CCFPEmode)
10685       rc = reverse_condition_maybe_unordered (rc);
10686     else
10687       rc = reverse_condition (rc);
10688
10689     operands[7] = gen_rtx_fmt_ee (rc, VOIDmode, operands[5], const0_rtx);
10690   }"
10691 )
10692
10693 (define_split
10694   [(set (match_operand:SI 0 "s_register_operand" "")
10695         (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10696                           [(match_operand 2 "" "") (match_operand 3 "" "")])
10697                          (match_operand 4 "" "")
10698                          (match_dup 0)))
10699    (clobber (reg:CC CC_REGNUM))]
10700   "TARGET_ARM && reload_completed"
10701   [(set (match_dup 5) (match_dup 6))
10702    (cond_exec (match_op_dup 1 [(match_dup 5) (const_int 0)])
10703               (set (match_dup 0) (match_dup 4)))]
10704   "
10705   {
10706     enum machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10707                                              operands[2], operands[3]);
10708
10709     operands[5] = gen_rtx_REG (mode, CC_REGNUM);
10710     operands[6] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10711   }"
10712 )
10713
10714 (define_split
10715   [(set (match_operand:SI 0 "s_register_operand" "")
10716         (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10717                           [(match_operand 2 "" "") (match_operand 3 "" "")])
10718                          (match_operand 4 "" "")
10719                          (match_operand 5 "" "")))
10720    (clobber (reg:CC CC_REGNUM))]
10721   "TARGET_ARM && reload_completed"
10722   [(set (match_dup 6) (match_dup 7))
10723    (cond_exec (match_op_dup 1 [(match_dup 6) (const_int 0)])
10724               (set (match_dup 0) (match_dup 4)))
10725    (cond_exec (match_dup 8)
10726               (set (match_dup 0) (match_dup 5)))]
10727   "
10728   {
10729     enum machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10730                                              operands[2], operands[3]);
10731     enum rtx_code rc = GET_CODE (operands[1]);
10732
10733     operands[6] = gen_rtx_REG (mode, CC_REGNUM);
10734     operands[7] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10735     if (mode == CCFPmode || mode == CCFPEmode)
10736       rc = reverse_condition_maybe_unordered (rc);
10737     else
10738       rc = reverse_condition (rc);
10739
10740     operands[8] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
10741   }"
10742 )
10743
10744 (define_split
10745   [(set (match_operand:SI 0 "s_register_operand" "")
10746         (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10747                           [(match_operand:SI 2 "s_register_operand" "")
10748                            (match_operand:SI 3 "arm_add_operand" "")])
10749                          (match_operand:SI 4 "arm_rhs_operand" "")
10750                          (not:SI
10751                           (match_operand:SI 5 "s_register_operand" ""))))
10752    (clobber (reg:CC CC_REGNUM))]
10753   "TARGET_ARM && reload_completed"
10754   [(set (match_dup 6) (match_dup 7))
10755    (cond_exec (match_op_dup 1 [(match_dup 6) (const_int 0)])
10756               (set (match_dup 0) (match_dup 4)))
10757    (cond_exec (match_dup 8)
10758               (set (match_dup 0) (not:SI (match_dup 5))))]
10759   "
10760   {
10761     enum machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10762                                              operands[2], operands[3]);
10763     enum rtx_code rc = GET_CODE (operands[1]);
10764
10765     operands[6] = gen_rtx_REG (mode, CC_REGNUM);
10766     operands[7] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10767     if (mode == CCFPmode || mode == CCFPEmode)
10768       rc = reverse_condition_maybe_unordered (rc);
10769     else
10770       rc = reverse_condition (rc);
10771
10772     operands[8] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
10773   }"
10774 )
10775
10776 (define_insn "*cond_move_not"
10777   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10778         (if_then_else:SI (match_operator 4 "arm_comparison_operator"
10779                           [(match_operand 3 "cc_register" "") (const_int 0)])
10780                          (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
10781                          (not:SI
10782                           (match_operand:SI 2 "s_register_operand" "r,r"))))]
10783   "TARGET_ARM"
10784   "@
10785    mvn%D4\\t%0, %2
10786    mov%d4\\t%0, %1\;mvn%D4\\t%0, %2"
10787   [(set_attr "conds" "use")
10788    (set_attr "insn" "mvn")
10789    (set_attr "length" "4,8")]
10790 )
10791
10792 ;; The next two patterns occur when an AND operation is followed by a
10793 ;; scc insn sequence 
10794
10795 (define_insn "*sign_extract_onebit"
10796   [(set (match_operand:SI 0 "s_register_operand" "=r")
10797         (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
10798                          (const_int 1)
10799                          (match_operand:SI 2 "const_int_operand" "n")))
10800     (clobber (reg:CC CC_REGNUM))]
10801   "TARGET_ARM"
10802   "*
10803     operands[2] = GEN_INT (1 << INTVAL (operands[2]));
10804     output_asm_insn (\"ands\\t%0, %1, %2\", operands);
10805     return \"mvnne\\t%0, #0\";
10806   "
10807   [(set_attr "conds" "clob")
10808    (set_attr "length" "8")]
10809 )
10810
10811 (define_insn "*not_signextract_onebit"
10812   [(set (match_operand:SI 0 "s_register_operand" "=r")
10813         (not:SI
10814          (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
10815                           (const_int 1)
10816                           (match_operand:SI 2 "const_int_operand" "n"))))
10817    (clobber (reg:CC CC_REGNUM))]
10818   "TARGET_ARM"
10819   "*
10820     operands[2] = GEN_INT (1 << INTVAL (operands[2]));
10821     output_asm_insn (\"tst\\t%1, %2\", operands);
10822     output_asm_insn (\"mvneq\\t%0, #0\", operands);
10823     return \"movne\\t%0, #0\";
10824   "
10825   [(set_attr "conds" "clob")
10826    (set_attr "length" "12")]
10827 )
10828 ;; ??? The above patterns need auditing for Thumb-2
10829
10830 ;; Push multiple registers to the stack.  Registers are in parallel (use ...)
10831 ;; expressions.  For simplicity, the first register is also in the unspec
10832 ;; part.
10833 ;; To avoid the usage of GNU extension, the length attribute is computed
10834 ;; in a C function arm_attr_length_push_multi.
10835 (define_insn "*push_multi"
10836   [(match_parallel 2 "multi_register_push"
10837     [(set (match_operand:BLK 0 "push_mult_memory_operand" "")
10838           (unspec:BLK [(match_operand:SI 1 "s_register_operand" "")]
10839                       UNSPEC_PUSH_MULT))])]
10840   ""
10841   "*
10842   {
10843     int num_saves = XVECLEN (operands[2], 0);
10844      
10845     /* For the StrongARM at least it is faster to
10846        use STR to store only a single register.
10847        In Thumb mode always use push, and the assembler will pick
10848        something appropriate.  */
10849     if (num_saves == 1 && TARGET_ARM)
10850       output_asm_insn (\"str%?\\t%1, [%m0, #-4]!\", operands);
10851     else
10852       {
10853         int i;
10854         char pattern[100];
10855
10856         if (TARGET_ARM)
10857             strcpy (pattern, \"stm%(fd%)\\t%m0!, {%1\");
10858         else if (TARGET_THUMB2)
10859             strcpy (pattern, \"push%?\\t{%1\");
10860         else
10861             strcpy (pattern, \"push\\t{%1\");
10862
10863         for (i = 1; i < num_saves; i++)
10864           {
10865             strcat (pattern, \", %|\");
10866             strcat (pattern,
10867                     reg_names[REGNO (XEXP (XVECEXP (operands[2], 0, i), 0))]);
10868           }
10869
10870         strcat (pattern, \"}\");
10871         output_asm_insn (pattern, operands);
10872       }
10873
10874     return \"\";
10875   }"
10876   [(set_attr "type" "store4")
10877    (set (attr "length")
10878         (symbol_ref "arm_attr_length_push_multi (operands[2], operands[1])"))]
10879 )
10880
10881 (define_insn "stack_tie"
10882   [(set (mem:BLK (scratch))
10883         (unspec:BLK [(match_operand:SI 0 "s_register_operand" "rk")
10884                      (match_operand:SI 1 "s_register_operand" "rk")]
10885                     UNSPEC_PRLG_STK))]
10886   ""
10887   ""
10888   [(set_attr "length" "0")]
10889 )
10890
10891 ;; Similarly for the floating point registers
10892 (define_insn "*push_fp_multi"
10893   [(match_parallel 2 "multi_register_push"
10894     [(set (match_operand:BLK 0 "memory_operand" "=m")
10895           (unspec:BLK [(match_operand:XF 1 "f_register_operand" "")]
10896                       UNSPEC_PUSH_MULT))])]
10897   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_FPA"
10898   "*
10899   {
10900     char pattern[100];
10901
10902     sprintf (pattern, \"sfm%%(fd%%)\\t%%1, %d, [%%m0]!\", XVECLEN (operands[2], 0));
10903     output_asm_insn (pattern, operands);
10904     return \"\";
10905   }"
10906   [(set_attr "type" "f_fpa_store")]
10907 )
10908
10909 ;; Special patterns for dealing with the constant pool
10910
10911 (define_insn "align_4"
10912   [(unspec_volatile [(const_int 0)] VUNSPEC_ALIGN)]
10913   "TARGET_EITHER"
10914   "*
10915   assemble_align (32);
10916   return \"\";
10917   "
10918 )
10919
10920 (define_insn "align_8"
10921   [(unspec_volatile [(const_int 0)] VUNSPEC_ALIGN8)]
10922   "TARGET_EITHER"
10923   "*
10924   assemble_align (64);
10925   return \"\";
10926   "
10927 )
10928
10929 (define_insn "consttable_end"
10930   [(unspec_volatile [(const_int 0)] VUNSPEC_POOL_END)]
10931   "TARGET_EITHER"
10932   "*
10933   making_const_table = FALSE;
10934   return \"\";
10935   "
10936 )
10937
10938 (define_insn "consttable_1"
10939   [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_1)]
10940   "TARGET_THUMB1"
10941   "*
10942   making_const_table = TRUE;
10943   assemble_integer (operands[0], 1, BITS_PER_WORD, 1);
10944   assemble_zeros (3);
10945   return \"\";
10946   "
10947   [(set_attr "length" "4")]
10948 )
10949
10950 (define_insn "consttable_2"
10951   [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_2)]
10952   "TARGET_THUMB1"
10953   "*
10954   making_const_table = TRUE;
10955   gcc_assert (GET_MODE_CLASS (GET_MODE (operands[0])) != MODE_FLOAT);
10956   assemble_integer (operands[0], 2, BITS_PER_WORD, 1);
10957   assemble_zeros (2);
10958   return \"\";
10959   "
10960   [(set_attr "length" "4")]
10961 )
10962
10963 (define_insn "consttable_4"
10964   [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_4)]
10965   "TARGET_EITHER"
10966   "*
10967   {
10968     rtx x = operands[0];
10969     making_const_table = TRUE;
10970     switch (GET_MODE_CLASS (GET_MODE (x)))
10971       {
10972       case MODE_FLOAT:
10973         if (GET_MODE (x) == HFmode)
10974           arm_emit_fp16_const (x);
10975         else
10976           {
10977             REAL_VALUE_TYPE r;
10978             REAL_VALUE_FROM_CONST_DOUBLE (r, x);
10979             assemble_real (r, GET_MODE (x), BITS_PER_WORD);
10980           }
10981         break;
10982       default:
10983         /* XXX: Sometimes gcc does something really dumb and ends up with
10984            a HIGH in a constant pool entry, usually because it's trying to
10985            load into a VFP register.  We know this will always be used in
10986            combination with a LO_SUM which ignores the high bits, so just
10987            strip off the HIGH.  */
10988         if (GET_CODE (x) == HIGH)
10989           x = XEXP (x, 0);
10990         assemble_integer (x, 4, BITS_PER_WORD, 1);
10991         mark_symbol_refs_as_used (x);
10992         break;
10993       }
10994     return \"\";
10995   }"
10996   [(set_attr "length" "4")]
10997 )
10998
10999 (define_insn "consttable_8"
11000   [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_8)]
11001   "TARGET_EITHER"
11002   "*
11003   {
11004     making_const_table = TRUE;
11005     switch (GET_MODE_CLASS (GET_MODE (operands[0])))
11006       {
11007        case MODE_FLOAT:
11008         {
11009           REAL_VALUE_TYPE r;
11010           REAL_VALUE_FROM_CONST_DOUBLE (r, operands[0]);
11011           assemble_real (r, GET_MODE (operands[0]), BITS_PER_WORD);
11012           break;
11013         }
11014       default:
11015         assemble_integer (operands[0], 8, BITS_PER_WORD, 1);
11016         break;
11017       }
11018     return \"\";
11019   }"
11020   [(set_attr "length" "8")]
11021 )
11022
11023 (define_insn "consttable_16"
11024   [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_16)]
11025   "TARGET_EITHER"
11026   "*
11027   {
11028     making_const_table = TRUE;
11029     switch (GET_MODE_CLASS (GET_MODE (operands[0])))
11030       {
11031        case MODE_FLOAT:
11032         {
11033           REAL_VALUE_TYPE r;
11034           REAL_VALUE_FROM_CONST_DOUBLE (r, operands[0]);
11035           assemble_real (r, GET_MODE (operands[0]), BITS_PER_WORD);
11036           break;
11037         }
11038       default:
11039         assemble_integer (operands[0], 16, BITS_PER_WORD, 1);
11040         break;
11041       }
11042     return \"\";
11043   }"
11044   [(set_attr "length" "16")]
11045 )
11046
11047 ;; Miscellaneous Thumb patterns
11048
11049 (define_expand "tablejump"
11050   [(parallel [(set (pc) (match_operand:SI 0 "register_operand" ""))
11051               (use (label_ref (match_operand 1 "" "")))])]
11052   "TARGET_THUMB1"
11053   "
11054   if (flag_pic)
11055     {
11056       /* Hopefully, CSE will eliminate this copy.  */
11057       rtx reg1 = copy_addr_to_reg (gen_rtx_LABEL_REF (Pmode, operands[1]));
11058       rtx reg2 = gen_reg_rtx (SImode);
11059
11060       emit_insn (gen_addsi3 (reg2, operands[0], reg1));
11061       operands[0] = reg2;
11062     }
11063   "
11064 )
11065
11066 ;; NB never uses BX.
11067 (define_insn "*thumb1_tablejump"
11068   [(set (pc) (match_operand:SI 0 "register_operand" "l*r"))
11069    (use (label_ref (match_operand 1 "" "")))]
11070   "TARGET_THUMB1"
11071   "mov\\t%|pc, %0"
11072   [(set_attr "length" "2")]
11073 )
11074
11075 ;; V5 Instructions,
11076
11077 (define_insn "clzsi2"
11078   [(set (match_operand:SI 0 "s_register_operand" "=r")
11079         (clz:SI (match_operand:SI 1 "s_register_operand" "r")))]
11080   "TARGET_32BIT && arm_arch5"
11081   "clz%?\\t%0, %1"
11082   [(set_attr "predicable" "yes")
11083    (set_attr "insn" "clz")])
11084
11085 (define_insn "rbitsi2"
11086   [(set (match_operand:SI 0 "s_register_operand" "=r")
11087         (unspec:SI [(match_operand:SI 1 "s_register_operand" "r")] UNSPEC_RBIT))]
11088   "TARGET_32BIT && arm_arch_thumb2"
11089   "rbit%?\\t%0, %1"
11090   [(set_attr "predicable" "yes")
11091    (set_attr "insn" "clz")])
11092
11093 (define_expand "ctzsi2"
11094  [(set (match_operand:SI           0 "s_register_operand" "")
11095        (ctz:SI (match_operand:SI  1 "s_register_operand" "")))]
11096   "TARGET_32BIT && arm_arch_thumb2"
11097   "
11098    {
11099      rtx tmp = gen_reg_rtx (SImode); 
11100      emit_insn (gen_rbitsi2 (tmp, operands[1]));
11101      emit_insn (gen_clzsi2 (operands[0], tmp));
11102    }
11103    DONE;
11104   "
11105 )
11106
11107 ;; V5E instructions.
11108
11109 (define_insn "prefetch"
11110   [(prefetch (match_operand:SI 0 "address_operand" "p")
11111              (match_operand:SI 1 "" "")
11112              (match_operand:SI 2 "" ""))]
11113   "TARGET_32BIT && arm_arch5e"
11114   "pld\\t%a0")
11115
11116 ;; General predication pattern
11117
11118 (define_cond_exec
11119   [(match_operator 0 "arm_comparison_operator"
11120     [(match_operand 1 "cc_register" "")
11121      (const_int 0)])]
11122   "TARGET_32BIT"
11123   ""
11124 )
11125
11126 (define_insn "prologue_use"
11127   [(unspec:SI [(match_operand:SI 0 "register_operand" "")] UNSPEC_PROLOGUE_USE)]
11128   ""
11129   "%@ %0 needed for prologue"
11130   [(set_attr "length" "0")]
11131 )
11132
11133
11134 ;; Patterns for exception handling
11135
11136 (define_expand "eh_return"
11137   [(use (match_operand 0 "general_operand" ""))]
11138   "TARGET_EITHER"
11139   "
11140   {
11141     if (TARGET_32BIT)
11142       emit_insn (gen_arm_eh_return (operands[0]));
11143     else
11144       emit_insn (gen_thumb_eh_return (operands[0]));
11145     DONE;
11146   }"
11147 )
11148                                    
11149 ;; We can't expand this before we know where the link register is stored.
11150 (define_insn_and_split "arm_eh_return"
11151   [(unspec_volatile [(match_operand:SI 0 "s_register_operand" "r")]
11152                     VUNSPEC_EH_RETURN)
11153    (clobber (match_scratch:SI 1 "=&r"))]
11154   "TARGET_ARM"
11155   "#"
11156   "&& reload_completed"
11157   [(const_int 0)]
11158   "
11159   {
11160     arm_set_return_address (operands[0], operands[1]);
11161     DONE;
11162   }"
11163 )
11164
11165 (define_insn_and_split "thumb_eh_return"
11166   [(unspec_volatile [(match_operand:SI 0 "s_register_operand" "l")]
11167                     VUNSPEC_EH_RETURN)
11168    (clobber (match_scratch:SI 1 "=&l"))]
11169   "TARGET_THUMB1"
11170   "#"
11171   "&& reload_completed"
11172   [(const_int 0)]
11173   "
11174   {
11175     thumb_set_return_address (operands[0], operands[1]);
11176     DONE;
11177   }"
11178 )
11179
11180 \f
11181 ;; TLS support
11182
11183 (define_insn "load_tp_hard"
11184   [(set (match_operand:SI 0 "register_operand" "=r")
11185         (unspec:SI [(const_int 0)] UNSPEC_TLS))]
11186   "TARGET_HARD_TP"
11187   "mrc%?\\tp15, 0, %0, c13, c0, 3\\t@ load_tp_hard"
11188   [(set_attr "predicable" "yes")]
11189 )
11190
11191 ;; Doesn't clobber R1-R3.  Must use r0 for the first operand.
11192 (define_insn "load_tp_soft"
11193   [(set (reg:SI 0) (unspec:SI [(const_int 0)] UNSPEC_TLS))
11194    (clobber (reg:SI LR_REGNUM))
11195    (clobber (reg:SI IP_REGNUM))
11196    (clobber (reg:CC CC_REGNUM))]
11197   "TARGET_SOFT_TP"
11198   "bl\\t__aeabi_read_tp\\t@ load_tp_soft"
11199   [(set_attr "conds" "clob")]
11200 )
11201
11202 ;; tls descriptor call
11203 (define_insn "tlscall"
11204   [(set (reg:SI R0_REGNUM)
11205         (unspec:SI [(reg:SI R0_REGNUM)
11206                     (match_operand:SI 0 "" "X")
11207                     (match_operand 1 "" "")] UNSPEC_TLS))
11208    (clobber (reg:SI R1_REGNUM))
11209    (clobber (reg:SI LR_REGNUM))
11210    (clobber (reg:SI CC_REGNUM))]
11211   "TARGET_GNU2_TLS"
11212   {
11213     targetm.asm_out.internal_label (asm_out_file, "LPIC",
11214                                     INTVAL (operands[1]));
11215     return "bl\\t%c0(tlscall)";
11216   }
11217   [(set_attr "conds" "clob")
11218    (set_attr "length" "4")]
11219 )
11220
11221 ;;
11222
11223 ;; We only care about the lower 16 bits of the constant 
11224 ;; being inserted into the upper 16 bits of the register.
11225 (define_insn "*arm_movtas_ze" 
11226   [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r")
11227                    (const_int 16)
11228                    (const_int 16))
11229         (match_operand:SI 1 "const_int_operand" ""))]
11230   "arm_arch_thumb2"
11231   "movt%?\t%0, %L1"
11232  [(set_attr "predicable" "yes")
11233    (set_attr "length" "4")]
11234 )
11235
11236 (define_insn "*arm_rev"
11237   [(set (match_operand:SI 0 "s_register_operand" "=r")
11238         (bswap:SI (match_operand:SI 1 "s_register_operand" "r")))]
11239   "TARGET_32BIT && arm_arch6"
11240   "rev%?\t%0, %1"
11241   [(set_attr "predicable" "yes")
11242    (set_attr "length" "4")]
11243 )
11244
11245 (define_insn "*thumb1_rev"
11246   [(set (match_operand:SI 0 "s_register_operand" "=l")
11247         (bswap:SI (match_operand:SI 1 "s_register_operand" "l")))]
11248   "TARGET_THUMB1 && arm_arch6"
11249    "rev\t%0, %1"
11250   [(set_attr "length" "2")]
11251 )
11252
11253 (define_expand "arm_legacy_rev"
11254   [(set (match_operand:SI 2 "s_register_operand" "")
11255         (xor:SI (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
11256                              (const_int 16))
11257                 (match_dup 1)))
11258    (set (match_dup 2)
11259         (lshiftrt:SI (match_dup 2)
11260                      (const_int 8)))
11261    (set (match_operand:SI 3 "s_register_operand" "")
11262         (rotatert:SI (match_dup 1)
11263                      (const_int 8)))
11264    (set (match_dup 2)
11265         (and:SI (match_dup 2)
11266                 (const_int -65281)))
11267    (set (match_operand:SI 0 "s_register_operand" "")
11268         (xor:SI (match_dup 3)
11269                 (match_dup 2)))]
11270   "TARGET_32BIT"
11271   ""
11272 )
11273
11274 ;; Reuse temporaries to keep register pressure down.
11275 (define_expand "thumb_legacy_rev"
11276   [(set (match_operand:SI 2 "s_register_operand" "")
11277      (ashift:SI (match_operand:SI 1 "s_register_operand" "")
11278                 (const_int 24)))
11279    (set (match_operand:SI 3 "s_register_operand" "")
11280      (lshiftrt:SI (match_dup 1)
11281                   (const_int 24)))
11282    (set (match_dup 3)
11283      (ior:SI (match_dup 3)
11284              (match_dup 2)))
11285    (set (match_operand:SI 4 "s_register_operand" "")
11286      (const_int 16))
11287    (set (match_operand:SI 5 "s_register_operand" "")
11288      (rotatert:SI (match_dup 1)
11289                   (match_dup 4)))
11290    (set (match_dup 2)
11291      (ashift:SI (match_dup 5)
11292                 (const_int 24)))
11293    (set (match_dup 5)
11294      (lshiftrt:SI (match_dup 5)
11295                   (const_int 24)))
11296    (set (match_dup 5)
11297      (ior:SI (match_dup 5)
11298              (match_dup 2)))
11299    (set (match_dup 5)
11300      (rotatert:SI (match_dup 5)
11301                   (match_dup 4)))
11302    (set (match_operand:SI 0 "s_register_operand" "")
11303      (ior:SI (match_dup 5)
11304              (match_dup 3)))]
11305   "TARGET_THUMB"
11306   ""
11307 )
11308
11309 (define_expand "bswapsi2"
11310   [(set (match_operand:SI 0 "s_register_operand" "=r")
11311         (bswap:SI (match_operand:SI 1 "s_register_operand" "r")))]
11312 "TARGET_EITHER && (arm_arch6 || !optimize_size)"
11313 "
11314     if (!arm_arch6)
11315       {
11316         rtx op2 = gen_reg_rtx (SImode);
11317         rtx op3 = gen_reg_rtx (SImode);
11318
11319         if (TARGET_THUMB)
11320           {
11321             rtx op4 = gen_reg_rtx (SImode);
11322             rtx op5 = gen_reg_rtx (SImode);
11323
11324             emit_insn (gen_thumb_legacy_rev (operands[0], operands[1],
11325                                              op2, op3, op4, op5));
11326           }
11327         else
11328           {
11329             emit_insn (gen_arm_legacy_rev (operands[0], operands[1],
11330                                            op2, op3));
11331           }
11332
11333         DONE;
11334       }
11335   "
11336 )
11337
11338 ;; Load the load/store multiple patterns
11339 (include "ldmstm.md")
11340 ;; Load the FPA co-processor patterns
11341 (include "fpa.md")
11342 ;; Load the Maverick co-processor patterns
11343 (include "cirrus.md")
11344 ;; Vector bits common to IWMMXT and Neon
11345 (include "vec-common.md")
11346 ;; Load the Intel Wireless Multimedia Extension patterns
11347 (include "iwmmxt.md")
11348 ;; Load the VFP co-processor patterns
11349 (include "vfp.md")
11350 ;; Thumb-2 patterns
11351 (include "thumb2.md")
11352 ;; Neon patterns
11353 (include "neon.md")
11354 ;; Synchronization Primitives
11355 (include "sync.md")
11356 ;; Fixed-point patterns
11357 (include "arm-fixed.md")