[ARM][trivial] Use uppercase for code iterator names
[official-gcc.git] / gcc / config / arm / arm.md
blob85d27d93a585673b3d93df637261e6682d9ec4f3
1 ;;- Machine description for ARM for GNU compiler
2 ;;  Copyright (C) 1991-2015 Free Software Foundation, Inc.
3 ;;  Contributed by Pieter `Tiggr' Schoenmakers (rcpieter@win.tue.nl)
4 ;;  and Martin Simmons (@harleqn.co.uk).
5 ;;  More major hacks by Richard Earnshaw (rearnsha@arm.com).
7 ;; This file is part of GCC.
9 ;; GCC is free software; you can redistribute it and/or modify it
10 ;; under the terms of the GNU General Public License as published
11 ;; by the Free Software Foundation; either version 3, or (at your
12 ;; option) any later version.
14 ;; GCC is distributed in the hope that it will be useful, but WITHOUT
15 ;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16 ;; or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
17 ;; License for more details.
19 ;; You should have received a copy of the GNU General Public License
20 ;; along with GCC; see the file COPYING3.  If not see
21 ;; <http://www.gnu.org/licenses/>.
23 ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
26 ;;---------------------------------------------------------------------------
27 ;; Constants
29 ;; Register numbers -- All machine registers should be defined here
30 (define_constants
31   [(R0_REGNUM         0)        ; First CORE register
32    (R1_REGNUM         1)        ; Second CORE register
33    (IP_REGNUM        12)        ; Scratch register
34    (SP_REGNUM        13)        ; Stack pointer
35    (LR_REGNUM        14)        ; Return address register
36    (PC_REGNUM        15)        ; Program counter
37    (LAST_ARM_REGNUM  15)        ;
38    (CC_REGNUM       100)        ; Condition code pseudo register
39    (VFPCC_REGNUM    101)        ; VFP Condition code pseudo register
40   ]
42 ;; 3rd operand to select_dominance_cc_mode
43 (define_constants
44   [(DOM_CC_X_AND_Y  0)
45    (DOM_CC_NX_OR_Y  1)
46    (DOM_CC_X_OR_Y   2)
47   ]
49 ;; conditional compare combination
50 (define_constants
51   [(CMP_CMP 0)
52    (CMN_CMP 1)
53    (CMP_CMN 2)
54    (CMN_CMN 3)
55    (NUM_OF_COND_CMP 4)
56   ]
60 ;;---------------------------------------------------------------------------
61 ;; Attributes
63 ;; Processor type.  This is created automatically from arm-cores.def.
64 (include "arm-tune.md")
66 ;; Instruction classification types
67 (include "types.md")
69 ; IS_THUMB is set to 'yes' when we are generating Thumb code, and 'no' when
70 ; generating ARM code.  This is used to control the length of some insn
71 ; patterns that share the same RTL in both ARM and Thumb code.
72 (define_attr "is_thumb" "no,yes" (const (symbol_ref "thumb_code")))
74 ; IS_ARCH6 is set to 'yes' when we are generating code form ARMv6.
75 (define_attr "is_arch6" "no,yes" (const (symbol_ref "arm_arch6")))
77 ; IS_THUMB1 is set to 'yes' iff we are generating Thumb-1 code.
78 (define_attr "is_thumb1" "no,yes" (const (symbol_ref "thumb1_code")))
80 ; We use this attribute to disable alternatives that can produce 32-bit
81 ; instructions inside an IT-block in Thumb2 state.  ARMv8 deprecates IT blocks
82 ; that contain 32-bit instructions.
83 (define_attr "enabled_for_depr_it" "no,yes" (const_string "yes"))
85 ; This attribute is used to disable a predicated alternative when we have
86 ; arm_restrict_it.
87 (define_attr "predicable_short_it" "no,yes" (const_string "yes"))
89 ;; Operand number of an input operand that is shifted.  Zero if the
90 ;; given instruction does not shift one of its input operands.
91 (define_attr "shift" "" (const_int 0))
93 ;; [For compatibility with AArch64 in pipeline models]
94 ;; Attribute that specifies whether or not the instruction touches fp
95 ;; registers.
96 (define_attr "fp" "no,yes" (const_string "no"))
98 ; Floating Point Unit.  If we only have floating point emulation, then there
99 ; is no point in scheduling the floating point insns.  (Well, for best
100 ; performance we should try and group them together).
101 (define_attr "fpu" "none,vfp"
102   (const (symbol_ref "arm_fpu_attr")))
104 (define_attr "predicated" "yes,no" (const_string "no"))
106 ; LENGTH of an instruction (in bytes)
107 (define_attr "length" ""
108   (const_int 4))
110 ; The architecture which supports the instruction (or alternative).
111 ; This can be "a" for ARM, "t" for either of the Thumbs, "32" for
112 ; TARGET_32BIT, "t1" or "t2" to specify a specific Thumb mode.  "v6"
113 ; for ARM or Thumb-2 with arm_arch6, and nov6 for ARM without
114 ; arm_arch6.  "v6t2" for Thumb-2 with arm_arch6.  This attribute is
115 ; used to compute attribute "enabled", use type "any" to enable an
116 ; alternative in all cases.
117 (define_attr "arch" "any,a,t,32,t1,t2,v6,nov6,v6t2,neon_for_64bits,avoid_neon_for_64bits,iwmmxt,iwmmxt2,armv6_or_vfpv3"
118   (const_string "any"))
120 (define_attr "arch_enabled" "no,yes"
121   (cond [(eq_attr "arch" "any")
122          (const_string "yes")
124          (and (eq_attr "arch" "a")
125               (match_test "TARGET_ARM"))
126          (const_string "yes")
128          (and (eq_attr "arch" "t")
129               (match_test "TARGET_THUMB"))
130          (const_string "yes")
132          (and (eq_attr "arch" "t1")
133               (match_test "TARGET_THUMB1"))
134          (const_string "yes")
136          (and (eq_attr "arch" "t2")
137               (match_test "TARGET_THUMB2"))
138          (const_string "yes")
140          (and (eq_attr "arch" "32")
141               (match_test "TARGET_32BIT"))
142          (const_string "yes")
144          (and (eq_attr "arch" "v6")
145               (match_test "TARGET_32BIT && arm_arch6"))
146          (const_string "yes")
148          (and (eq_attr "arch" "nov6")
149               (match_test "TARGET_32BIT && !arm_arch6"))
150          (const_string "yes")
152          (and (eq_attr "arch" "v6t2")
153               (match_test "TARGET_32BIT && arm_arch6 && arm_arch_thumb2"))
154          (const_string "yes")
156          (and (eq_attr "arch" "avoid_neon_for_64bits")
157               (match_test "TARGET_NEON")
158               (not (match_test "TARGET_PREFER_NEON_64BITS")))
159          (const_string "yes")
161          (and (eq_attr "arch" "neon_for_64bits")
162               (match_test "TARGET_NEON")
163               (match_test "TARGET_PREFER_NEON_64BITS"))
164          (const_string "yes")
166          (and (eq_attr "arch" "iwmmxt2")
167               (match_test "TARGET_REALLY_IWMMXT2"))
168          (const_string "yes")
170          (and (eq_attr "arch" "armv6_or_vfpv3")
171               (match_test "arm_arch6 || TARGET_VFP3"))
172          (const_string "yes")
173         ]
175         (const_string "no")))
177 (define_attr "opt" "any,speed,size"
178   (const_string "any"))
180 (define_attr "opt_enabled" "no,yes"
181   (cond [(eq_attr "opt" "any")
182          (const_string "yes")
184          (and (eq_attr "opt" "speed")
185               (match_test "optimize_function_for_speed_p (cfun)"))
186          (const_string "yes")
188          (and (eq_attr "opt" "size")
189               (match_test "optimize_function_for_size_p (cfun)"))
190          (const_string "yes")]
191         (const_string "no")))
193 (define_attr "use_literal_pool" "no,yes"
194    (cond [(and (eq_attr "type" "f_loads,f_loadd")
195                (match_test "CONSTANT_P (operands[1])"))
196           (const_string "yes")]
197          (const_string "no")))
199 ; Enable all alternatives that are both arch_enabled and insn_enabled.
200 ; FIXME:: opt_enabled has been temporarily removed till the time we have
201 ; an attribute that allows the use of such alternatives.
202 ; This depends on caching of speed_p, size_p on a per
203 ; alternative basis. The problem is that the enabled attribute
204 ; cannot depend on any state that is not cached or is not constant
205 ; for a compilation unit. We probably need a generic "hot/cold"
206 ; alternative which if implemented can help with this. We disable this
207 ; until such a time as this is implemented and / or the improvements or
208 ; regressions with removing this attribute are double checked.
209 ; See ashldi3_neon and <shift>di3_neon in neon.md.
211  (define_attr "enabled" "no,yes"
212    (cond [(and (eq_attr "predicable_short_it" "no")
213                (and (eq_attr "predicated" "yes")
214                     (match_test "arm_restrict_it")))
215           (const_string "no")
217           (and (eq_attr "enabled_for_depr_it" "no")
218                (match_test "arm_restrict_it"))
219           (const_string "no")
221           (and (eq_attr "use_literal_pool" "yes")
222                (match_test "arm_disable_literal_pool"))
223           (const_string "no")
225           (eq_attr "arch_enabled" "no")
226           (const_string "no")]
227          (const_string "yes")))
229 ; POOL_RANGE is how far away from a constant pool entry that this insn
230 ; can be placed.  If the distance is zero, then this insn will never
231 ; reference the pool.
232 ; Note that for Thumb constant pools the PC value is rounded down to the
233 ; nearest multiple of four.  Therefore, THUMB2_POOL_RANGE (and POOL_RANGE for
234 ; Thumb insns) should be set to <max_range> - 2.
235 ; NEG_POOL_RANGE is nonzero for insns that can reference a constant pool entry
236 ; before its address.  It is set to <max_range> - (8 + <data_size>).
237 (define_attr "arm_pool_range" "" (const_int 0))
238 (define_attr "thumb2_pool_range" "" (const_int 0))
239 (define_attr "arm_neg_pool_range" "" (const_int 0))
240 (define_attr "thumb2_neg_pool_range" "" (const_int 0))
242 (define_attr "pool_range" ""
243   (cond [(eq_attr "is_thumb" "yes") (attr "thumb2_pool_range")]
244         (attr "arm_pool_range")))
245 (define_attr "neg_pool_range" ""
246   (cond [(eq_attr "is_thumb" "yes") (attr "thumb2_neg_pool_range")]
247         (attr "arm_neg_pool_range")))
249 ; An assembler sequence may clobber the condition codes without us knowing.
250 ; If such an insn references the pool, then we have no way of knowing how,
251 ; so use the most conservative value for pool_range.
252 (define_asm_attributes
253  [(set_attr "conds" "clob")
254   (set_attr "length" "4")
255   (set_attr "pool_range" "250")])
257 ; Load scheduling, set from the arm_ld_sched variable
258 ; initialized by arm_option_override()
259 (define_attr "ldsched" "no,yes" (const (symbol_ref "arm_ld_sched")))
261 ; condition codes: this one is used by final_prescan_insn to speed up
262 ; conditionalizing instructions.  It saves having to scan the rtl to see if
263 ; it uses or alters the condition codes.
265 ; USE means that the condition codes are used by the insn in the process of
266 ;   outputting code, this means (at present) that we can't use the insn in
267 ;   inlined branches
269 ; SET means that the purpose of the insn is to set the condition codes in a
270 ;   well defined manner.
272 ; CLOB means that the condition codes are altered in an undefined manner, if
273 ;   they are altered at all
275 ; UNCONDITIONAL means the instruction can not be conditionally executed and
276 ;   that the instruction does not use or alter the condition codes.
278 ; NOCOND means that the instruction does not use or alter the condition
279 ;   codes but can be converted into a conditionally exectuted instruction.
281 (define_attr "conds" "use,set,clob,unconditional,nocond"
282         (if_then_else
283          (ior (eq_attr "is_thumb1" "yes")
284               (eq_attr "type" "call"))
285          (const_string "clob")
286          (if_then_else (eq_attr "is_neon_type" "no")
287          (const_string "nocond")
288          (const_string "unconditional"))))
290 ; Predicable means that the insn can be conditionally executed based on
291 ; an automatically added predicate (additional patterns are generated by 
292 ; gen...).  We default to 'no' because no Thumb patterns match this rule
293 ; and not all ARM patterns do.
294 (define_attr "predicable" "no,yes" (const_string "no"))
296 ; Only model the write buffer for ARM6 and ARM7.  Earlier processors don't
297 ; have one.  Later ones, such as StrongARM, have write-back caches, so don't
298 ; suffer blockages enough to warrant modelling this (and it can adversely
299 ; affect the schedule).
300 (define_attr "model_wbuf" "no,yes" (const (symbol_ref "arm_tune_wbuf")))
302 ; WRITE_CONFLICT implies that a read following an unrelated write is likely
303 ; to stall the processor.  Used with model_wbuf above.
304 (define_attr "write_conflict" "no,yes"
305   (if_then_else (eq_attr "type"
306                  "block,call,load1")
307                 (const_string "yes")
308                 (const_string "no")))
310 ; Classify the insns into those that take one cycle and those that take more
311 ; than one on the main cpu execution unit.
312 (define_attr "core_cycles" "single,multi"
313   (if_then_else (eq_attr "type"
314     "adc_imm, adc_reg, adcs_imm, adcs_reg, adr, alu_ext, alu_imm, alu_sreg,\
315     alu_shift_imm, alu_shift_reg, alu_dsp_reg, alus_ext, alus_imm, alus_sreg,\
316     alus_shift_imm, alus_shift_reg, bfm, csel, rev, logic_imm, logic_reg,\
317     logic_shift_imm, logic_shift_reg, logics_imm, logics_reg,\
318     logics_shift_imm, logics_shift_reg, extend, shift_imm, float, fcsel,\
319     wmmx_wor, wmmx_wxor, wmmx_wand, wmmx_wandn, wmmx_wmov, wmmx_tmcrr,\
320     wmmx_tmrrc, wmmx_wldr, wmmx_wstr, wmmx_tmcr, wmmx_tmrc, wmmx_wadd,\
321     wmmx_wsub, wmmx_wmul, wmmx_wmac, wmmx_wavg2, wmmx_tinsr, wmmx_textrm,\
322     wmmx_wshufh, wmmx_wcmpeq, wmmx_wcmpgt, wmmx_wmax, wmmx_wmin, wmmx_wpack,\
323     wmmx_wunpckih, wmmx_wunpckil, wmmx_wunpckeh, wmmx_wunpckel, wmmx_wror,\
324     wmmx_wsra, wmmx_wsrl, wmmx_wsll, wmmx_wmadd, wmmx_tmia, wmmx_tmiaph,\
325     wmmx_tmiaxy, wmmx_tbcst, wmmx_tmovmsk, wmmx_wacc, wmmx_waligni,\
326     wmmx_walignr, wmmx_tandc, wmmx_textrc, wmmx_torc, wmmx_torvsc, wmmx_wsad,\
327     wmmx_wabs, wmmx_wabsdiff, wmmx_waddsubhx, wmmx_wsubaddhx, wmmx_wavg4,\
328     wmmx_wmulw, wmmx_wqmulm, wmmx_wqmulwm, wmmx_waddbhus, wmmx_wqmiaxy,\
329     wmmx_wmiaxy, wmmx_wmiawxy, wmmx_wmerge")
330                 (const_string "single")
331                 (const_string "multi")))
333 ;; FAR_JUMP is "yes" if a BL instruction is used to generate a branch to a
334 ;; distant label.  Only applicable to Thumb code.
335 (define_attr "far_jump" "yes,no" (const_string "no"))
338 ;; The number of machine instructions this pattern expands to.
339 ;; Used for Thumb-2 conditional execution.
340 (define_attr "ce_count" "" (const_int 1))
342 ;;---------------------------------------------------------------------------
343 ;; Unspecs
345 (include "unspecs.md")
347 ;;---------------------------------------------------------------------------
348 ;; Mode iterators
350 (include "iterators.md")
352 ;;---------------------------------------------------------------------------
353 ;; Predicates
355 (include "predicates.md")
356 (include "constraints.md")
358 ;;---------------------------------------------------------------------------
359 ;; Pipeline descriptions
361 (define_attr "tune_cortexr4" "yes,no"
362   (const (if_then_else
363           (eq_attr "tune" "cortexr4,cortexr4f,cortexr5")
364           (const_string "yes")
365           (const_string "no"))))
367 ;; True if the generic scheduling description should be used.
369 (define_attr "generic_sched" "yes,no"
370   (const (if_then_else
371           (ior (eq_attr "tune" "fa526,fa626,fa606te,fa626te,fmp626,fa726te,\
372                                 arm926ejs,arm1020e,arm1026ejs,arm1136js,\
373                                 arm1136jfs,cortexa5,cortexa7,cortexa8,\
374                                 cortexa9,cortexa12,cortexa15,cortexa17,\
375                                 cortexa53,cortexa57,cortexm4,cortexm7,\
376                                 marvell_pj4,xgene1")
377                (eq_attr "tune_cortexr4" "yes"))
378           (const_string "no")
379           (const_string "yes"))))
381 (define_attr "generic_vfp" "yes,no"
382   (const (if_then_else
383           (and (eq_attr "fpu" "vfp")
384                (eq_attr "tune" "!arm1020e,arm1022e,cortexa5,cortexa7,\
385                                 cortexa8,cortexa9,cortexa53,cortexm4,\
386                                 cortexm7,marvell_pj4,xgene1")
387                (eq_attr "tune_cortexr4" "no"))
388           (const_string "yes")
389           (const_string "no"))))
391 (include "marvell-f-iwmmxt.md")
392 (include "arm-generic.md")
393 (include "arm926ejs.md")
394 (include "arm1020e.md")
395 (include "arm1026ejs.md")
396 (include "arm1136jfs.md")
397 (include "fa526.md")
398 (include "fa606te.md")
399 (include "fa626te.md")
400 (include "fmp626.md")
401 (include "fa726te.md")
402 (include "cortex-a5.md")
403 (include "cortex-a7.md")
404 (include "cortex-a8.md")
405 (include "cortex-a9.md")
406 (include "cortex-a15.md")
407 (include "cortex-a17.md")
408 (include "cortex-a53.md")
409 (include "cortex-a57.md")
410 (include "cortex-r4.md")
411 (include "cortex-r4f.md")
412 (include "cortex-m7.md")
413 (include "cortex-m4.md")
414 (include "cortex-m4-fpu.md")
415 (include "vfp11.md")
416 (include "marvell-pj4.md")
417 (include "xgene1.md")
420 ;;---------------------------------------------------------------------------
421 ;; Insn patterns
423 ;; Addition insns.
425 ;; Note: For DImode insns, there is normally no reason why operands should
426 ;; not be in the same register, what we don't want is for something being
427 ;; written to partially overlap something that is an input.
429 (define_expand "adddi3"
430  [(parallel
431    [(set (match_operand:DI           0 "s_register_operand" "")
432           (plus:DI (match_operand:DI 1 "s_register_operand" "")
433                    (match_operand:DI 2 "arm_adddi_operand"  "")))
434     (clobber (reg:CC CC_REGNUM))])]
435   "TARGET_EITHER"
436   "
437   if (TARGET_THUMB1)
438     {
439       if (!REG_P (operands[1]))
440         operands[1] = force_reg (DImode, operands[1]);
441       if (!REG_P (operands[2]))
442         operands[2] = force_reg (DImode, operands[2]);
443      }
444   "
447 (define_insn_and_split "*arm_adddi3"
448   [(set (match_operand:DI          0 "s_register_operand" "=&r,&r,&r,&r,&r")
449         (plus:DI (match_operand:DI 1 "s_register_operand" "%0, 0, r, 0, r")
450                  (match_operand:DI 2 "arm_adddi_operand"  "r,  0, r, Dd, Dd")))
451    (clobber (reg:CC CC_REGNUM))]
452   "TARGET_32BIT && !TARGET_NEON"
453   "#"
454   "TARGET_32BIT && reload_completed
455    && ! (TARGET_NEON && IS_VFP_REGNUM (REGNO (operands[0])))"
456   [(parallel [(set (reg:CC_C CC_REGNUM)
457                    (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
458                                  (match_dup 1)))
459               (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
460    (set (match_dup 3) (plus:SI (plus:SI (match_dup 4) (match_dup 5))
461                                (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
462   "
463   {
464     operands[3] = gen_highpart (SImode, operands[0]);
465     operands[0] = gen_lowpart (SImode, operands[0]);
466     operands[4] = gen_highpart (SImode, operands[1]);
467     operands[1] = gen_lowpart (SImode, operands[1]);
468     operands[5] = gen_highpart_mode (SImode, DImode, operands[2]);
469     operands[2] = gen_lowpart (SImode, operands[2]);
470   }"
471   [(set_attr "conds" "clob")
472    (set_attr "length" "8")
473    (set_attr "type" "multiple")]
476 (define_insn_and_split "*adddi_sesidi_di"
477   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
478         (plus:DI (sign_extend:DI
479                   (match_operand:SI 2 "s_register_operand" "r,r"))
480                  (match_operand:DI 1 "s_register_operand" "0,r")))
481    (clobber (reg:CC CC_REGNUM))]
482   "TARGET_32BIT"
483   "#"
484   "TARGET_32BIT && reload_completed"
485   [(parallel [(set (reg:CC_C CC_REGNUM)
486                    (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
487                                  (match_dup 1)))
488               (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
489    (set (match_dup 3) (plus:SI (plus:SI (ashiftrt:SI (match_dup 2)
490                                                      (const_int 31))
491                                         (match_dup 4))
492                                (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
493   "
494   {
495     operands[3] = gen_highpart (SImode, operands[0]);
496     operands[0] = gen_lowpart (SImode, operands[0]);
497     operands[4] = gen_highpart (SImode, operands[1]);
498     operands[1] = gen_lowpart (SImode, operands[1]);
499     operands[2] = gen_lowpart (SImode, operands[2]);
500   }"
501   [(set_attr "conds" "clob")
502    (set_attr "length" "8")
503    (set_attr "type" "multiple")]
506 (define_insn_and_split "*adddi_zesidi_di"
507   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
508         (plus:DI (zero_extend:DI
509                   (match_operand:SI 2 "s_register_operand" "r,r"))
510                  (match_operand:DI 1 "s_register_operand" "0,r")))
511    (clobber (reg:CC CC_REGNUM))]
512   "TARGET_32BIT"
513   "#"
514   "TARGET_32BIT && reload_completed"
515   [(parallel [(set (reg:CC_C CC_REGNUM)
516                    (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
517                                  (match_dup 1)))
518               (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
519    (set (match_dup 3) (plus:SI (plus:SI (match_dup 4) (const_int 0))
520                                (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
521   "
522   {
523     operands[3] = gen_highpart (SImode, operands[0]);
524     operands[0] = gen_lowpart (SImode, operands[0]);
525     operands[4] = gen_highpart (SImode, operands[1]);
526     operands[1] = gen_lowpart (SImode, operands[1]);
527     operands[2] = gen_lowpart (SImode, operands[2]);
528   }"
529   [(set_attr "conds" "clob")
530    (set_attr "length" "8")
531    (set_attr "type" "multiple")]
534 (define_expand "addsi3"
535   [(set (match_operand:SI          0 "s_register_operand" "")
536         (plus:SI (match_operand:SI 1 "s_register_operand" "")
537                  (match_operand:SI 2 "reg_or_int_operand" "")))]
538   "TARGET_EITHER"
539   "
540   if (TARGET_32BIT && CONST_INT_P (operands[2]))
541     {
542       arm_split_constant (PLUS, SImode, NULL_RTX,
543                           INTVAL (operands[2]), operands[0], operands[1],
544                           optimize && can_create_pseudo_p ());
545       DONE;
546     }
547   "
550 ; If there is a scratch available, this will be faster than synthesizing the
551 ; addition.
552 (define_peephole2
553   [(match_scratch:SI 3 "r")
554    (set (match_operand:SI          0 "arm_general_register_operand" "")
555         (plus:SI (match_operand:SI 1 "arm_general_register_operand" "")
556                  (match_operand:SI 2 "const_int_operand"  "")))]
557   "TARGET_32BIT &&
558    !(const_ok_for_arm (INTVAL (operands[2]))
559      || const_ok_for_arm (-INTVAL (operands[2])))
560     && const_ok_for_arm (~INTVAL (operands[2]))"
561   [(set (match_dup 3) (match_dup 2))
562    (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 3)))]
563   ""
566 ;; The r/r/k alternative is required when reloading the address
567 ;;  (plus (reg rN) (reg sp)) into (reg rN).  In this case reload will
568 ;; put the duplicated register first, and not try the commutative version.
569 (define_insn_and_split "*arm_addsi3"
570   [(set (match_operand:SI          0 "s_register_operand" "=rk,l,l ,l ,r ,k ,r,r ,k ,r ,k,k,r ,k ,r")
571         (plus:SI (match_operand:SI 1 "s_register_operand" "%0 ,l,0 ,l ,rk,k ,r,rk,k ,rk,k,r,rk,k ,rk")
572                  (match_operand:SI 2 "reg_or_int_operand" "rk ,l,Py,Pd,rI,rI,k,Pj,Pj,L ,L,L,PJ,PJ,?n")))]
573   "TARGET_32BIT"
574   "@
575    add%?\\t%0, %0, %2
576    add%?\\t%0, %1, %2
577    add%?\\t%0, %1, %2
578    add%?\\t%0, %1, %2
579    add%?\\t%0, %1, %2
580    add%?\\t%0, %1, %2
581    add%?\\t%0, %2, %1
582    addw%?\\t%0, %1, %2
583    addw%?\\t%0, %1, %2
584    sub%?\\t%0, %1, #%n2
585    sub%?\\t%0, %1, #%n2
586    sub%?\\t%0, %1, #%n2
587    subw%?\\t%0, %1, #%n2
588    subw%?\\t%0, %1, #%n2
589    #"
590   "TARGET_32BIT
591    && CONST_INT_P (operands[2])
592    && !const_ok_for_op (INTVAL (operands[2]), PLUS)
593    && (reload_completed || !arm_eliminable_register (operands[1]))"
594   [(clobber (const_int 0))]
595   "
596   arm_split_constant (PLUS, SImode, curr_insn,
597                       INTVAL (operands[2]), operands[0],
598                       operands[1], 0);
599   DONE;
600   "
601   [(set_attr "length" "2,4,4,4,4,4,4,4,4,4,4,4,4,4,16")
602    (set_attr "predicable" "yes")
603    (set_attr "predicable_short_it" "yes,yes,yes,yes,no,no,no,no,no,no,no,no,no,no,no")
604    (set_attr "arch" "t2,t2,t2,t2,*,*,*,t2,t2,*,*,a,t2,t2,*")
605    (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
606                       (const_string "alu_imm")
607                       (const_string "alu_sreg")))
611 (define_insn "addsi3_compare0"
612   [(set (reg:CC_NOOV CC_REGNUM)
613         (compare:CC_NOOV
614          (plus:SI (match_operand:SI 1 "s_register_operand" "r, r,r")
615                   (match_operand:SI 2 "arm_add_operand"    "I,L,r"))
616          (const_int 0)))
617    (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
618         (plus:SI (match_dup 1) (match_dup 2)))]
619   "TARGET_ARM"
620   "@
621    add%.\\t%0, %1, %2
622    sub%.\\t%0, %1, #%n2
623    add%.\\t%0, %1, %2"
624   [(set_attr "conds" "set")
625    (set_attr "type" "alus_imm,alus_imm,alus_sreg")]
628 (define_insn "*addsi3_compare0_scratch"
629   [(set (reg:CC_NOOV CC_REGNUM)
630         (compare:CC_NOOV
631          (plus:SI (match_operand:SI 0 "s_register_operand" "r, r, r")
632                   (match_operand:SI 1 "arm_add_operand"    "I,L, r"))
633          (const_int 0)))]
634   "TARGET_ARM"
635   "@
636    cmn%?\\t%0, %1
637    cmp%?\\t%0, #%n1
638    cmn%?\\t%0, %1"
639   [(set_attr "conds" "set")
640    (set_attr "predicable" "yes")
641    (set_attr "type" "alus_imm,alus_imm,alus_sreg")]
644 (define_insn "*compare_negsi_si"
645   [(set (reg:CC_Z CC_REGNUM)
646         (compare:CC_Z
647          (neg:SI (match_operand:SI 0 "s_register_operand" "l,r"))
648          (match_operand:SI 1 "s_register_operand" "l,r")))]
649   "TARGET_32BIT"
650   "cmn%?\\t%1, %0"
651   [(set_attr "conds" "set")
652    (set_attr "predicable" "yes")
653    (set_attr "arch" "t2,*")
654    (set_attr "length" "2,4")
655    (set_attr "predicable_short_it" "yes,no")
656    (set_attr "type" "alus_sreg")]
659 ;; This is the canonicalization of addsi3_compare0_for_combiner when the
660 ;; addend is a constant.
661 (define_insn "cmpsi2_addneg"
662   [(set (reg:CC CC_REGNUM)
663         (compare:CC
664          (match_operand:SI 1 "s_register_operand" "r,r")
665          (match_operand:SI 2 "arm_addimm_operand" "L,I")))
666    (set (match_operand:SI 0 "s_register_operand" "=r,r")
667         (plus:SI (match_dup 1)
668                  (match_operand:SI 3 "arm_addimm_operand" "I,L")))]
669   "TARGET_32BIT && INTVAL (operands[2]) == -INTVAL (operands[3])"
670   "@
671    add%.\\t%0, %1, %3
672    sub%.\\t%0, %1, #%n3"
673   [(set_attr "conds" "set")
674    (set_attr "type" "alus_sreg")]
677 ;; Convert the sequence
678 ;;  sub  rd, rn, #1
679 ;;  cmn  rd, #1 (equivalent to cmp rd, #-1)
680 ;;  bne  dest
681 ;; into
682 ;;  subs rd, rn, #1
683 ;;  bcs  dest   ((unsigned)rn >= 1)
684 ;; similarly for the beq variant using bcc.
685 ;; This is a common looping idiom (while (n--))
686 (define_peephole2
687   [(set (match_operand:SI 0 "arm_general_register_operand" "")
688         (plus:SI (match_operand:SI 1 "arm_general_register_operand" "")
689                  (const_int -1)))
690    (set (match_operand 2 "cc_register" "")
691         (compare (match_dup 0) (const_int -1)))
692    (set (pc)
693         (if_then_else (match_operator 3 "equality_operator"
694                        [(match_dup 2) (const_int 0)])
695                       (match_operand 4 "" "")
696                       (match_operand 5 "" "")))]
697   "TARGET_32BIT && peep2_reg_dead_p (3, operands[2])"
698   [(parallel[
699     (set (match_dup 2)
700          (compare:CC
701           (match_dup 1) (const_int 1)))
702     (set (match_dup 0) (plus:SI (match_dup 1) (const_int -1)))])
703    (set (pc)
704         (if_then_else (match_op_dup 3 [(match_dup 2) (const_int 0)])
705                       (match_dup 4)
706                       (match_dup 5)))]
707   "operands[2] = gen_rtx_REG (CCmode, CC_REGNUM);
708    operands[3] = gen_rtx_fmt_ee ((GET_CODE (operands[3]) == NE
709                                   ? GEU : LTU),
710                                  VOIDmode, 
711                                  operands[2], const0_rtx);"
714 ;; The next four insns work because they compare the result with one of
715 ;; the operands, and we know that the use of the condition code is
716 ;; either GEU or LTU, so we can use the carry flag from the addition
717 ;; instead of doing the compare a second time.
718 (define_insn "*addsi3_compare_op1"
719   [(set (reg:CC_C CC_REGNUM)
720         (compare:CC_C
721          (plus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
722                   (match_operand:SI 2 "arm_add_operand" "I,L,r"))
723          (match_dup 1)))
724    (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
725         (plus:SI (match_dup 1) (match_dup 2)))]
726   "TARGET_32BIT"
727   "@
728    add%.\\t%0, %1, %2
729    sub%.\\t%0, %1, #%n2
730    add%.\\t%0, %1, %2"
731   [(set_attr "conds" "set")
732    (set_attr "type"  "alus_imm,alus_imm,alus_sreg")]
735 (define_insn "*addsi3_compare_op2"
736   [(set (reg:CC_C CC_REGNUM)
737         (compare:CC_C
738          (plus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
739                   (match_operand:SI 2 "arm_add_operand" "I,L,r"))
740          (match_dup 2)))
741    (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
742         (plus:SI (match_dup 1) (match_dup 2)))]
743   "TARGET_32BIT"
744   "@
745    add%.\\t%0, %1, %2
746    add%.\\t%0, %1, %2
747    sub%.\\t%0, %1, #%n2"
748   [(set_attr "conds" "set")
749    (set_attr "type" "alus_imm,alus_imm,alus_sreg")]
752 (define_insn "*compare_addsi2_op0"
753   [(set (reg:CC_C CC_REGNUM)
754         (compare:CC_C
755           (plus:SI (match_operand:SI 0 "s_register_operand" "l,l,r,r,r")
756                    (match_operand:SI 1 "arm_add_operand" "Pv,l,I,L,r"))
757           (match_dup 0)))]
758   "TARGET_32BIT"
759   "@
760    cmp%?\\t%0, #%n1
761    cmn%?\\t%0, %1
762    cmn%?\\t%0, %1
763    cmp%?\\t%0, #%n1
764    cmn%?\\t%0, %1"
765   [(set_attr "conds" "set")
766    (set_attr "predicable" "yes")
767    (set_attr "arch" "t2,t2,*,*,*")
768    (set_attr "predicable_short_it" "yes,yes,no,no,no")
769    (set_attr "length" "2,2,4,4,4")
770    (set_attr "type" "alus_imm,alus_sreg,alus_imm,alus_imm,alus_sreg")]
773 (define_insn "*compare_addsi2_op1"
774   [(set (reg:CC_C CC_REGNUM)
775         (compare:CC_C
776           (plus:SI (match_operand:SI 0 "s_register_operand" "l,l,r,r,r")
777                    (match_operand:SI 1 "arm_add_operand" "Pv,l,I,L,r"))
778           (match_dup 1)))]
779   "TARGET_32BIT"
780   "@
781    cmp%?\\t%0, #%n1
782    cmn%?\\t%0, %1
783    cmn%?\\t%0, %1
784    cmp%?\\t%0, #%n1
785    cmn%?\\t%0, %1"
786   [(set_attr "conds" "set")
787    (set_attr "predicable" "yes")
788    (set_attr "arch" "t2,t2,*,*,*")
789    (set_attr "predicable_short_it" "yes,yes,no,no,no")
790    (set_attr "length" "2,2,4,4,4")
791    (set_attr "type" "alus_imm,alus_sreg,alus_imm,alus_imm,alus_sreg")]
794 (define_insn "*addsi3_carryin_<optab>"
795   [(set (match_operand:SI 0 "s_register_operand" "=l,r,r")
796         (plus:SI (plus:SI (match_operand:SI 1 "s_register_operand" "%l,r,r")
797                           (match_operand:SI 2 "arm_not_operand" "0,rI,K"))
798                  (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))))]
799   "TARGET_32BIT"
800   "@
801    adc%?\\t%0, %1, %2
802    adc%?\\t%0, %1, %2
803    sbc%?\\t%0, %1, #%B2"
804   [(set_attr "conds" "use")
805    (set_attr "predicable" "yes")
806    (set_attr "arch" "t2,*,*")
807    (set_attr "length" "4")
808    (set_attr "predicable_short_it" "yes,no,no")
809    (set_attr "type" "adc_reg,adc_reg,adc_imm")]
812 (define_insn "*addsi3_carryin_alt2_<optab>"
813   [(set (match_operand:SI 0 "s_register_operand" "=l,r,r")
814         (plus:SI (plus:SI (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))
815                           (match_operand:SI 1 "s_register_operand" "%l,r,r"))
816                  (match_operand:SI 2 "arm_rhs_operand" "l,rI,K")))]
817   "TARGET_32BIT"
818   "@
819    adc%?\\t%0, %1, %2
820    adc%?\\t%0, %1, %2
821    sbc%?\\t%0, %1, #%B2"
822   [(set_attr "conds" "use")
823    (set_attr "predicable" "yes")
824    (set_attr "arch" "t2,*,*")
825    (set_attr "length" "4")
826    (set_attr "predicable_short_it" "yes,no,no")
827    (set_attr "type" "adc_reg,adc_reg,adc_imm")]
830 (define_insn "*addsi3_carryin_shift_<optab>"
831   [(set (match_operand:SI 0 "s_register_operand" "=r")
832         (plus:SI (plus:SI
833                   (match_operator:SI 2 "shift_operator"
834                     [(match_operand:SI 3 "s_register_operand" "r")
835                      (match_operand:SI 4 "reg_or_int_operand" "rM")])
836                   (match_operand:SI 1 "s_register_operand" "r"))
837                  (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))))]
838   "TARGET_32BIT"
839   "adc%?\\t%0, %1, %3%S2"
840   [(set_attr "conds" "use")
841    (set_attr "predicable" "yes")
842    (set_attr "predicable_short_it" "no")
843    (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
844                       (const_string "alu_shift_imm")
845                       (const_string "alu_shift_reg")))]
848 (define_insn "*addsi3_carryin_clobercc_<optab>"
849   [(set (match_operand:SI 0 "s_register_operand" "=r")
850         (plus:SI (plus:SI (match_operand:SI 1 "s_register_operand" "%r")
851                           (match_operand:SI 2 "arm_rhs_operand" "rI"))
852                  (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))))
853    (clobber (reg:CC CC_REGNUM))]
854    "TARGET_32BIT"
855    "adc%.\\t%0, %1, %2"
856    [(set_attr "conds" "set")
857     (set_attr "type" "adcs_reg")]
860 (define_insn "*subsi3_carryin"
861   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
862         (minus:SI (minus:SI (match_operand:SI 1 "reg_or_int_operand" "r,I")
863                             (match_operand:SI 2 "s_register_operand" "r,r"))
864                   (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
865   "TARGET_32BIT"
866   "@
867    sbc%?\\t%0, %1, %2
868    rsc%?\\t%0, %2, %1"
869   [(set_attr "conds" "use")
870    (set_attr "arch" "*,a")
871    (set_attr "predicable" "yes")
872    (set_attr "predicable_short_it" "no")
873    (set_attr "type" "adc_reg,adc_imm")]
876 (define_insn "*subsi3_carryin_const"
877   [(set (match_operand:SI 0 "s_register_operand" "=r")
878         (minus:SI (plus:SI (match_operand:SI 1 "reg_or_int_operand" "r")
879                            (match_operand:SI 2 "arm_not_operand" "K"))
880                   (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
881   "TARGET_32BIT"
882   "sbc\\t%0, %1, #%B2"
883   [(set_attr "conds" "use")
884    (set_attr "type" "adc_imm")]
887 (define_insn "*subsi3_carryin_compare"
888   [(set (reg:CC CC_REGNUM)
889         (compare:CC (match_operand:SI 1 "s_register_operand" "r")
890                     (match_operand:SI 2 "s_register_operand" "r")))
891    (set (match_operand:SI 0 "s_register_operand" "=r")
892         (minus:SI (minus:SI (match_dup 1)
893                             (match_dup 2))
894                   (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
895   "TARGET_32BIT"
896   "sbcs\\t%0, %1, %2"
897   [(set_attr "conds" "set")
898    (set_attr "type" "adcs_reg")]
901 (define_insn "*subsi3_carryin_compare_const"
902   [(set (reg:CC CC_REGNUM)
903         (compare:CC (match_operand:SI 1 "reg_or_int_operand" "r")
904                     (match_operand:SI 2 "arm_not_operand" "K")))
905    (set (match_operand:SI 0 "s_register_operand" "=r")
906         (minus:SI (plus:SI (match_dup 1)
907                            (match_dup 2))
908                   (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
909   "TARGET_32BIT"
910   "sbcs\\t%0, %1, #%B2"
911   [(set_attr "conds" "set")
912    (set_attr "type" "adcs_imm")]
915 (define_insn "*subsi3_carryin_shift"
916   [(set (match_operand:SI 0 "s_register_operand" "=r")
917         (minus:SI (minus:SI
918                   (match_operand:SI 1 "s_register_operand" "r")
919                   (match_operator:SI 2 "shift_operator"
920                    [(match_operand:SI 3 "s_register_operand" "r")
921                     (match_operand:SI 4 "reg_or_int_operand" "rM")]))
922                  (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
923   "TARGET_32BIT"
924   "sbc%?\\t%0, %1, %3%S2"
925   [(set_attr "conds" "use")
926    (set_attr "predicable" "yes")
927    (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
928                       (const_string "alu_shift_imm")
929                      (const_string "alu_shift_reg")))]
932 (define_insn "*rsbsi3_carryin_shift"
933   [(set (match_operand:SI 0 "s_register_operand" "=r")
934         (minus:SI (minus:SI
935                   (match_operator:SI 2 "shift_operator"
936                    [(match_operand:SI 3 "s_register_operand" "r")
937                     (match_operand:SI 4 "reg_or_int_operand" "rM")])
938                    (match_operand:SI 1 "s_register_operand" "r"))
939                  (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
940   "TARGET_ARM"
941   "rsc%?\\t%0, %1, %3%S2"
942   [(set_attr "conds" "use")
943    (set_attr "predicable" "yes")
944    (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
945                       (const_string "alu_shift_imm")
946                       (const_string "alu_shift_reg")))]
949 ; transform ((x << y) - 1) to ~(~(x-1) << y)  Where X is a constant.
950 (define_split
951   [(set (match_operand:SI 0 "s_register_operand" "")
952         (plus:SI (ashift:SI (match_operand:SI 1 "const_int_operand" "")
953                             (match_operand:SI 2 "s_register_operand" ""))
954                  (const_int -1)))
955    (clobber (match_operand:SI 3 "s_register_operand" ""))]
956   "TARGET_32BIT"
957   [(set (match_dup 3) (match_dup 1))
958    (set (match_dup 0) (not:SI (ashift:SI (match_dup 3) (match_dup 2))))]
959   "
960   operands[1] = GEN_INT (~(INTVAL (operands[1]) - 1));
963 (define_expand "addsf3"
964   [(set (match_operand:SF          0 "s_register_operand" "")
965         (plus:SF (match_operand:SF 1 "s_register_operand" "")
966                  (match_operand:SF 2 "s_register_operand" "")))]
967   "TARGET_32BIT && TARGET_HARD_FLOAT"
968   "
971 (define_expand "adddf3"
972   [(set (match_operand:DF          0 "s_register_operand" "")
973         (plus:DF (match_operand:DF 1 "s_register_operand" "")
974                  (match_operand:DF 2 "s_register_operand" "")))]
975   "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
976   "
979 (define_expand "subdi3"
980  [(parallel
981    [(set (match_operand:DI            0 "s_register_operand" "")
982           (minus:DI (match_operand:DI 1 "s_register_operand" "")
983                     (match_operand:DI 2 "s_register_operand" "")))
984     (clobber (reg:CC CC_REGNUM))])]
985   "TARGET_EITHER"
986   "
987   if (TARGET_THUMB1)
988     {
989       if (!REG_P (operands[1]))
990         operands[1] = force_reg (DImode, operands[1]);
991       if (!REG_P (operands[2]))
992         operands[2] = force_reg (DImode, operands[2]);
993      }  
994   "
997 (define_insn_and_split "*arm_subdi3"
998   [(set (match_operand:DI           0 "s_register_operand" "=&r,&r,&r")
999         (minus:DI (match_operand:DI 1 "s_register_operand" "0,r,0")
1000                   (match_operand:DI 2 "s_register_operand" "r,0,0")))
1001    (clobber (reg:CC CC_REGNUM))]
1002   "TARGET_32BIT && !TARGET_NEON"
1003   "#"  ; "subs\\t%Q0, %Q1, %Q2\;sbc\\t%R0, %R1, %R2"
1004   "&& reload_completed"
1005   [(parallel [(set (reg:CC CC_REGNUM)
1006                    (compare:CC (match_dup 1) (match_dup 2)))
1007               (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1008    (set (match_dup 3) (minus:SI (minus:SI (match_dup 4) (match_dup 5))
1009                                (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1010   {
1011     operands[3] = gen_highpart (SImode, operands[0]);
1012     operands[0] = gen_lowpart (SImode, operands[0]);
1013     operands[4] = gen_highpart (SImode, operands[1]);
1014     operands[1] = gen_lowpart (SImode, operands[1]);
1015     operands[5] = gen_highpart (SImode, operands[2]);
1016     operands[2] = gen_lowpart (SImode, operands[2]);
1017    }
1018   [(set_attr "conds" "clob")
1019    (set_attr "length" "8")
1020    (set_attr "type" "multiple")]
1023 (define_insn_and_split "*subdi_di_zesidi"
1024   [(set (match_operand:DI           0 "s_register_operand" "=&r,&r")
1025         (minus:DI (match_operand:DI 1 "s_register_operand"  "0,r")
1026                   (zero_extend:DI
1027                    (match_operand:SI 2 "s_register_operand"  "r,r"))))
1028    (clobber (reg:CC CC_REGNUM))]
1029   "TARGET_32BIT"
1030   "#"   ; "subs\\t%Q0, %Q1, %2\;sbc\\t%R0, %R1, #0"
1031   "&& reload_completed"
1032   [(parallel [(set (reg:CC CC_REGNUM)
1033                    (compare:CC (match_dup 1) (match_dup 2)))
1034               (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1035    (set (match_dup 3) (minus:SI (plus:SI (match_dup 4) (match_dup 5))
1036                                 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1037   {
1038     operands[3] = gen_highpart (SImode, operands[0]);
1039     operands[0] = gen_lowpart (SImode, operands[0]);
1040     operands[4] = gen_highpart (SImode, operands[1]);
1041     operands[1] = gen_lowpart (SImode, operands[1]);
1042     operands[5] = GEN_INT (~0);
1043    }
1044   [(set_attr "conds" "clob")
1045    (set_attr "length" "8")
1046    (set_attr "type" "multiple")]
1049 (define_insn_and_split "*subdi_di_sesidi"
1050   [(set (match_operand:DI            0 "s_register_operand" "=&r,&r")
1051         (minus:DI (match_operand:DI  1 "s_register_operand"  "0,r")
1052                   (sign_extend:DI
1053                    (match_operand:SI 2 "s_register_operand"  "r,r"))))
1054    (clobber (reg:CC CC_REGNUM))]
1055   "TARGET_32BIT"
1056   "#"   ; "subs\\t%Q0, %Q1, %2\;sbc\\t%R0, %R1, %2, asr #31"
1057   "&& reload_completed"
1058   [(parallel [(set (reg:CC CC_REGNUM)
1059                    (compare:CC (match_dup 1) (match_dup 2)))
1060               (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1061    (set (match_dup 3) (minus:SI (minus:SI (match_dup 4)
1062                                          (ashiftrt:SI (match_dup 2)
1063                                                       (const_int 31)))
1064                                 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1065   {
1066     operands[3] = gen_highpart (SImode, operands[0]);
1067     operands[0] = gen_lowpart (SImode, operands[0]);
1068     operands[4] = gen_highpart (SImode, operands[1]);
1069     operands[1] = gen_lowpart (SImode, operands[1]);
1070   }
1071   [(set_attr "conds" "clob")
1072    (set_attr "length" "8")
1073    (set_attr "type" "multiple")]
1076 (define_insn_and_split "*subdi_zesidi_di"
1077   [(set (match_operand:DI            0 "s_register_operand" "=&r,&r")
1078         (minus:DI (zero_extend:DI
1079                    (match_operand:SI 2 "s_register_operand"  "r,r"))
1080                   (match_operand:DI  1 "s_register_operand" "0,r")))
1081    (clobber (reg:CC CC_REGNUM))]
1082   "TARGET_ARM"
1083   "#"   ; "rsbs\\t%Q0, %Q1, %2\;rsc\\t%R0, %R1, #0"
1084         ; is equivalent to:
1085         ; "subs\\t%Q0, %2, %Q1\;rsc\\t%R0, %R1, #0"
1086   "&& reload_completed"
1087   [(parallel [(set (reg:CC CC_REGNUM)
1088                    (compare:CC (match_dup 2) (match_dup 1)))
1089               (set (match_dup 0) (minus:SI (match_dup 2) (match_dup 1)))])
1090    (set (match_dup 3) (minus:SI (minus:SI (const_int 0) (match_dup 4))
1091                                (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1092   {
1093     operands[3] = gen_highpart (SImode, operands[0]);
1094     operands[0] = gen_lowpart (SImode, operands[0]);
1095     operands[4] = gen_highpart (SImode, operands[1]);
1096     operands[1] = gen_lowpart (SImode, operands[1]);
1097   }
1098   [(set_attr "conds" "clob")
1099    (set_attr "length" "8")
1100    (set_attr "type" "multiple")]
1103 (define_insn_and_split "*subdi_sesidi_di"
1104   [(set (match_operand:DI            0 "s_register_operand" "=&r,&r")
1105         (minus:DI (sign_extend:DI
1106                    (match_operand:SI 2 "s_register_operand"   "r,r"))
1107                   (match_operand:DI  1 "s_register_operand"  "0,r")))
1108    (clobber (reg:CC CC_REGNUM))]
1109   "TARGET_ARM"
1110   "#"   ; "rsbs\\t%Q0, %Q1, %2\;rsc\\t%R0, %R1, %2, asr #31"
1111         ; is equivalent to:
1112         ; "subs\\t%Q0, %2, %Q1\;rsc\\t%R0, %R1, %2, asr #31"
1113   "&& reload_completed"
1114   [(parallel [(set (reg:CC CC_REGNUM)
1115                    (compare:CC (match_dup 2) (match_dup 1)))
1116               (set (match_dup 0) (minus:SI (match_dup 2) (match_dup 1)))])
1117    (set (match_dup 3) (minus:SI (minus:SI
1118                                 (ashiftrt:SI (match_dup 2)
1119                                              (const_int 31))
1120                                 (match_dup 4))
1121                                (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1122   {
1123     operands[3] = gen_highpart (SImode, operands[0]);
1124     operands[0] = gen_lowpart (SImode, operands[0]);
1125     operands[4] = gen_highpart (SImode, operands[1]);
1126     operands[1] = gen_lowpart (SImode, operands[1]);
1127   }
1128   [(set_attr "conds" "clob")
1129    (set_attr "length" "8")
1130    (set_attr "type" "multiple")]
1133 (define_insn_and_split "*subdi_zesidi_zesidi"
1134   [(set (match_operand:DI            0 "s_register_operand" "=r")
1135         (minus:DI (zero_extend:DI
1136                    (match_operand:SI 1 "s_register_operand"  "r"))
1137                   (zero_extend:DI
1138                    (match_operand:SI 2 "s_register_operand"  "r"))))
1139    (clobber (reg:CC CC_REGNUM))]
1140   "TARGET_32BIT"
1141   "#"   ; "subs\\t%Q0, %1, %2\;sbc\\t%R0, %1, %1"
1142   "&& reload_completed"
1143   [(parallel [(set (reg:CC CC_REGNUM)
1144                    (compare:CC (match_dup 1) (match_dup 2)))
1145               (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1146    (set (match_dup 3) (minus:SI (minus:SI (match_dup 1) (match_dup 1))
1147                                (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1148   {
1149        operands[3] = gen_highpart (SImode, operands[0]);
1150        operands[0] = gen_lowpart (SImode, operands[0]);
1151   }
1152   [(set_attr "conds" "clob")
1153    (set_attr "length" "8")
1154    (set_attr "type" "multiple")]
1157 (define_expand "subsi3"
1158   [(set (match_operand:SI           0 "s_register_operand" "")
1159         (minus:SI (match_operand:SI 1 "reg_or_int_operand" "")
1160                   (match_operand:SI 2 "s_register_operand" "")))]
1161   "TARGET_EITHER"
1162   "
1163   if (CONST_INT_P (operands[1]))
1164     {
1165       if (TARGET_32BIT)
1166         {
1167           arm_split_constant (MINUS, SImode, NULL_RTX,
1168                               INTVAL (operands[1]), operands[0],
1169                               operands[2], optimize && can_create_pseudo_p ());
1170           DONE;
1171         }
1172       else /* TARGET_THUMB1 */
1173         operands[1] = force_reg (SImode, operands[1]);
1174     }
1175   "
1178 ; ??? Check Thumb-2 split length
1179 (define_insn_and_split "*arm_subsi3_insn"
1180   [(set (match_operand:SI           0 "s_register_operand" "=l,l ,l ,l ,r ,r,r,rk,r")
1181         (minus:SI (match_operand:SI 1 "reg_or_int_operand" "l ,0 ,l ,Pz,rI,r,r,k ,?n")
1182                   (match_operand:SI 2 "reg_or_int_operand" "l ,Py,Pd,l ,r ,I,r,r ,r")))]
1183   "TARGET_32BIT"
1184   "@
1185    sub%?\\t%0, %1, %2
1186    sub%?\\t%0, %2
1187    sub%?\\t%0, %1, %2
1188    rsb%?\\t%0, %2, %1
1189    rsb%?\\t%0, %2, %1
1190    sub%?\\t%0, %1, %2
1191    sub%?\\t%0, %1, %2
1192    sub%?\\t%0, %1, %2
1193    #"
1194   "&& (CONST_INT_P (operands[1])
1195        && !const_ok_for_arm (INTVAL (operands[1])))"
1196   [(clobber (const_int 0))]
1197   "
1198   arm_split_constant (MINUS, SImode, curr_insn,
1199                       INTVAL (operands[1]), operands[0], operands[2], 0);
1200   DONE;
1201   "
1202   [(set_attr "length" "4,4,4,4,4,4,4,4,16")
1203    (set_attr "arch" "t2,t2,t2,t2,*,*,*,*,*")
1204    (set_attr "predicable" "yes")
1205    (set_attr "predicable_short_it" "yes,yes,yes,yes,no,no,no,no,no")
1206    (set_attr "type" "alu_sreg,alu_sreg,alu_sreg,alu_sreg,alu_imm,alu_imm,alu_sreg,alu_sreg,multiple")]
1209 (define_peephole2
1210   [(match_scratch:SI 3 "r")
1211    (set (match_operand:SI 0 "arm_general_register_operand" "")
1212         (minus:SI (match_operand:SI 1 "const_int_operand" "")
1213                   (match_operand:SI 2 "arm_general_register_operand" "")))]
1214   "TARGET_32BIT
1215    && !const_ok_for_arm (INTVAL (operands[1]))
1216    && const_ok_for_arm (~INTVAL (operands[1]))"
1217   [(set (match_dup 3) (match_dup 1))
1218    (set (match_dup 0) (minus:SI (match_dup 3) (match_dup 2)))]
1219   ""
1222 (define_insn "*subsi3_compare0"
1223   [(set (reg:CC_NOOV CC_REGNUM)
1224         (compare:CC_NOOV
1225          (minus:SI (match_operand:SI 1 "arm_rhs_operand" "r,r,I")
1226                    (match_operand:SI 2 "arm_rhs_operand" "I,r,r"))
1227          (const_int 0)))
1228    (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
1229         (minus:SI (match_dup 1) (match_dup 2)))]
1230   "TARGET_32BIT"
1231   "@
1232    sub%.\\t%0, %1, %2
1233    sub%.\\t%0, %1, %2
1234    rsb%.\\t%0, %2, %1"
1235   [(set_attr "conds" "set")
1236    (set_attr "type"  "alus_imm,alus_sreg,alus_sreg")]
1239 (define_insn "subsi3_compare"
1240   [(set (reg:CC CC_REGNUM)
1241         (compare:CC (match_operand:SI 1 "arm_rhs_operand" "r,r,I")
1242                     (match_operand:SI 2 "arm_rhs_operand" "I,r,r")))
1243    (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
1244         (minus:SI (match_dup 1) (match_dup 2)))]
1245   "TARGET_32BIT"
1246   "@
1247    sub%.\\t%0, %1, %2
1248    sub%.\\t%0, %1, %2
1249    rsb%.\\t%0, %2, %1"
1250   [(set_attr "conds" "set")
1251    (set_attr "type" "alus_imm,alus_sreg,alus_sreg")]
1254 (define_expand "subsf3"
1255   [(set (match_operand:SF           0 "s_register_operand" "")
1256         (minus:SF (match_operand:SF 1 "s_register_operand" "")
1257                   (match_operand:SF 2 "s_register_operand" "")))]
1258   "TARGET_32BIT && TARGET_HARD_FLOAT"
1259   "
1262 (define_expand "subdf3"
1263   [(set (match_operand:DF           0 "s_register_operand" "")
1264         (minus:DF (match_operand:DF 1 "s_register_operand" "")
1265                   (match_operand:DF 2 "s_register_operand" "")))]
1266   "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
1267   "
1271 ;; Multiplication insns
1273 (define_expand "mulhi3"
1274   [(set (match_operand:HI 0 "s_register_operand" "")
1275         (mult:HI (match_operand:HI 1 "s_register_operand" "")
1276                  (match_operand:HI 2 "s_register_operand" "")))]
1277   "TARGET_DSP_MULTIPLY"
1278   "
1279   {
1280     rtx result = gen_reg_rtx (SImode);
1281     emit_insn (gen_mulhisi3 (result, operands[1], operands[2]));
1282     emit_move_insn (operands[0], gen_lowpart (HImode, result));
1283     DONE;
1284   }"
1287 (define_expand "mulsi3"
1288   [(set (match_operand:SI          0 "s_register_operand" "")
1289         (mult:SI (match_operand:SI 2 "s_register_operand" "")
1290                  (match_operand:SI 1 "s_register_operand" "")))]
1291   "TARGET_EITHER"
1292   ""
1295 ;; Use `&' and then `0' to prevent the operands 0 and 1 being the same
1296 (define_insn "*arm_mulsi3"
1297   [(set (match_operand:SI          0 "s_register_operand" "=&r,&r")
1298         (mult:SI (match_operand:SI 2 "s_register_operand" "r,r")
1299                  (match_operand:SI 1 "s_register_operand" "%0,r")))]
1300   "TARGET_32BIT && !arm_arch6"
1301   "mul%?\\t%0, %2, %1"
1302   [(set_attr "type" "mul")
1303    (set_attr "predicable" "yes")]
1306 (define_insn "*arm_mulsi3_v6"
1307   [(set (match_operand:SI          0 "s_register_operand" "=l,l,r")
1308         (mult:SI (match_operand:SI 1 "s_register_operand" "0,l,r")
1309                  (match_operand:SI 2 "s_register_operand" "l,0,r")))]
1310   "TARGET_32BIT && arm_arch6"
1311   "mul%?\\t%0, %1, %2"
1312   [(set_attr "type" "mul")
1313    (set_attr "predicable" "yes")
1314    (set_attr "arch" "t2,t2,*")
1315    (set_attr "length" "4")
1316    (set_attr "predicable_short_it" "yes,yes,no")]
1319 (define_insn "*mulsi3_compare0"
1320   [(set (reg:CC_NOOV CC_REGNUM)
1321         (compare:CC_NOOV (mult:SI
1322                           (match_operand:SI 2 "s_register_operand" "r,r")
1323                           (match_operand:SI 1 "s_register_operand" "%0,r"))
1324                          (const_int 0)))
1325    (set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1326         (mult:SI (match_dup 2) (match_dup 1)))]
1327   "TARGET_ARM && !arm_arch6"
1328   "mul%.\\t%0, %2, %1"
1329   [(set_attr "conds" "set")
1330    (set_attr "type" "muls")]
1333 (define_insn "*mulsi3_compare0_v6"
1334   [(set (reg:CC_NOOV CC_REGNUM)
1335         (compare:CC_NOOV (mult:SI
1336                           (match_operand:SI 2 "s_register_operand" "r")
1337                           (match_operand:SI 1 "s_register_operand" "r"))
1338                          (const_int 0)))
1339    (set (match_operand:SI 0 "s_register_operand" "=r")
1340         (mult:SI (match_dup 2) (match_dup 1)))]
1341   "TARGET_ARM && arm_arch6 && optimize_size"
1342   "mul%.\\t%0, %2, %1"
1343   [(set_attr "conds" "set")
1344    (set_attr "type" "muls")]
1347 (define_insn "*mulsi_compare0_scratch"
1348   [(set (reg:CC_NOOV CC_REGNUM)
1349         (compare:CC_NOOV (mult:SI
1350                           (match_operand:SI 2 "s_register_operand" "r,r")
1351                           (match_operand:SI 1 "s_register_operand" "%0,r"))
1352                          (const_int 0)))
1353    (clobber (match_scratch:SI 0 "=&r,&r"))]
1354   "TARGET_ARM && !arm_arch6"
1355   "mul%.\\t%0, %2, %1"
1356   [(set_attr "conds" "set")
1357    (set_attr "type" "muls")]
1360 (define_insn "*mulsi_compare0_scratch_v6"
1361   [(set (reg:CC_NOOV CC_REGNUM)
1362         (compare:CC_NOOV (mult:SI
1363                           (match_operand:SI 2 "s_register_operand" "r")
1364                           (match_operand:SI 1 "s_register_operand" "r"))
1365                          (const_int 0)))
1366    (clobber (match_scratch:SI 0 "=r"))]
1367   "TARGET_ARM && arm_arch6 && optimize_size"
1368   "mul%.\\t%0, %2, %1"
1369   [(set_attr "conds" "set")
1370    (set_attr "type" "muls")]
1373 ;; Unnamed templates to match MLA instruction.
1375 (define_insn "*mulsi3addsi"
1376   [(set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r,&r")
1377         (plus:SI
1378           (mult:SI (match_operand:SI 2 "s_register_operand" "r,r,r,r")
1379                    (match_operand:SI 1 "s_register_operand" "%0,r,0,r"))
1380           (match_operand:SI 3 "s_register_operand" "r,r,0,0")))]
1381   "TARGET_32BIT && !arm_arch6"
1382   "mla%?\\t%0, %2, %1, %3"
1383   [(set_attr "type" "mla")
1384    (set_attr "predicable" "yes")]
1387 (define_insn "*mulsi3addsi_v6"
1388   [(set (match_operand:SI 0 "s_register_operand" "=r")
1389         (plus:SI
1390           (mult:SI (match_operand:SI 2 "s_register_operand" "r")
1391                    (match_operand:SI 1 "s_register_operand" "r"))
1392           (match_operand:SI 3 "s_register_operand" "r")))]
1393   "TARGET_32BIT && arm_arch6"
1394   "mla%?\\t%0, %2, %1, %3"
1395   [(set_attr "type" "mla")
1396    (set_attr "predicable" "yes")
1397    (set_attr "predicable_short_it" "no")]
1400 (define_insn "*mulsi3addsi_compare0"
1401   [(set (reg:CC_NOOV CC_REGNUM)
1402         (compare:CC_NOOV
1403          (plus:SI (mult:SI
1404                    (match_operand:SI 2 "s_register_operand" "r,r,r,r")
1405                    (match_operand:SI 1 "s_register_operand" "%0,r,0,r"))
1406                   (match_operand:SI 3 "s_register_operand" "r,r,0,0"))
1407          (const_int 0)))
1408    (set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r,&r")
1409         (plus:SI (mult:SI (match_dup 2) (match_dup 1))
1410                  (match_dup 3)))]
1411   "TARGET_ARM && arm_arch6"
1412   "mla%.\\t%0, %2, %1, %3"
1413   [(set_attr "conds" "set")
1414    (set_attr "type" "mlas")]
1417 (define_insn "*mulsi3addsi_compare0_v6"
1418   [(set (reg:CC_NOOV CC_REGNUM)
1419         (compare:CC_NOOV
1420          (plus:SI (mult:SI
1421                    (match_operand:SI 2 "s_register_operand" "r")
1422                    (match_operand:SI 1 "s_register_operand" "r"))
1423                   (match_operand:SI 3 "s_register_operand" "r"))
1424          (const_int 0)))
1425    (set (match_operand:SI 0 "s_register_operand" "=r")
1426         (plus:SI (mult:SI (match_dup 2) (match_dup 1))
1427                  (match_dup 3)))]
1428   "TARGET_ARM && arm_arch6 && optimize_size"
1429   "mla%.\\t%0, %2, %1, %3"
1430   [(set_attr "conds" "set")
1431    (set_attr "type" "mlas")]
1434 (define_insn "*mulsi3addsi_compare0_scratch"
1435   [(set (reg:CC_NOOV CC_REGNUM)
1436         (compare:CC_NOOV
1437          (plus:SI (mult:SI
1438                    (match_operand:SI 2 "s_register_operand" "r,r,r,r")
1439                    (match_operand:SI 1 "s_register_operand" "%0,r,0,r"))
1440                   (match_operand:SI 3 "s_register_operand" "?r,r,0,0"))
1441          (const_int 0)))
1442    (clobber (match_scratch:SI 0 "=&r,&r,&r,&r"))]
1443   "TARGET_ARM && !arm_arch6"
1444   "mla%.\\t%0, %2, %1, %3"
1445   [(set_attr "conds" "set")
1446    (set_attr "type" "mlas")]
1449 (define_insn "*mulsi3addsi_compare0_scratch_v6"
1450   [(set (reg:CC_NOOV CC_REGNUM)
1451         (compare:CC_NOOV
1452          (plus:SI (mult:SI
1453                    (match_operand:SI 2 "s_register_operand" "r")
1454                    (match_operand:SI 1 "s_register_operand" "r"))
1455                   (match_operand:SI 3 "s_register_operand" "r"))
1456          (const_int 0)))
1457    (clobber (match_scratch:SI 0 "=r"))]
1458   "TARGET_ARM && arm_arch6 && optimize_size"
1459   "mla%.\\t%0, %2, %1, %3"
1460   [(set_attr "conds" "set")
1461    (set_attr "type" "mlas")]
1464 (define_insn "*mulsi3subsi"
1465   [(set (match_operand:SI 0 "s_register_operand" "=r")
1466         (minus:SI
1467           (match_operand:SI 3 "s_register_operand" "r")
1468           (mult:SI (match_operand:SI 2 "s_register_operand" "r")
1469                    (match_operand:SI 1 "s_register_operand" "r"))))]
1470   "TARGET_32BIT && arm_arch_thumb2"
1471   "mls%?\\t%0, %2, %1, %3"
1472   [(set_attr "type" "mla")
1473    (set_attr "predicable" "yes")
1474    (set_attr "predicable_short_it" "no")]
1477 (define_expand "maddsidi4"
1478   [(set (match_operand:DI 0 "s_register_operand" "")
1479         (plus:DI
1480          (mult:DI
1481           (sign_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1482           (sign_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1483          (match_operand:DI 3 "s_register_operand" "")))]
1484   "TARGET_32BIT && arm_arch3m"
1485   "")
1487 (define_insn "*mulsidi3adddi"
1488   [(set (match_operand:DI 0 "s_register_operand" "=&r")
1489         (plus:DI
1490          (mult:DI
1491           (sign_extend:DI (match_operand:SI 2 "s_register_operand" "%r"))
1492           (sign_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1493          (match_operand:DI 1 "s_register_operand" "0")))]
1494   "TARGET_32BIT && arm_arch3m && !arm_arch6"
1495   "smlal%?\\t%Q0, %R0, %3, %2"
1496   [(set_attr "type" "smlal")
1497    (set_attr "predicable" "yes")]
1500 (define_insn "*mulsidi3adddi_v6"
1501   [(set (match_operand:DI 0 "s_register_operand" "=r")
1502         (plus:DI
1503          (mult:DI
1504           (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r"))
1505           (sign_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1506          (match_operand:DI 1 "s_register_operand" "0")))]
1507   "TARGET_32BIT && arm_arch6"
1508   "smlal%?\\t%Q0, %R0, %3, %2"
1509   [(set_attr "type" "smlal")
1510    (set_attr "predicable" "yes")
1511    (set_attr "predicable_short_it" "no")]
1514 ;; 32x32->64 widening multiply.
1515 ;; As with mulsi3, the only difference between the v3-5 and v6+
1516 ;; versions of these patterns is the requirement that the output not
1517 ;; overlap the inputs, but that still means we have to have a named
1518 ;; expander and two different starred insns.
1520 (define_expand "mulsidi3"
1521   [(set (match_operand:DI 0 "s_register_operand" "")
1522         (mult:DI
1523          (sign_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1524          (sign_extend:DI (match_operand:SI 2 "s_register_operand" ""))))]
1525   "TARGET_32BIT && arm_arch3m"
1526   ""
1529 (define_insn "*mulsidi3_nov6"
1530   [(set (match_operand:DI 0 "s_register_operand" "=&r")
1531         (mult:DI
1532          (sign_extend:DI (match_operand:SI 1 "s_register_operand" "%r"))
1533          (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1534   "TARGET_32BIT && arm_arch3m && !arm_arch6"
1535   "smull%?\\t%Q0, %R0, %1, %2"
1536   [(set_attr "type" "smull")
1537    (set_attr "predicable" "yes")]
1540 (define_insn "*mulsidi3_v6"
1541   [(set (match_operand:DI 0 "s_register_operand" "=r")
1542         (mult:DI
1543          (sign_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1544          (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1545   "TARGET_32BIT && arm_arch6"
1546   "smull%?\\t%Q0, %R0, %1, %2"
1547   [(set_attr "type" "smull")
1548    (set_attr "predicable" "yes")
1549    (set_attr "predicable_short_it" "no")]
1552 (define_expand "umulsidi3"
1553   [(set (match_operand:DI 0 "s_register_operand" "")
1554         (mult:DI
1555          (zero_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1556          (zero_extend:DI (match_operand:SI 2 "s_register_operand" ""))))]
1557   "TARGET_32BIT && arm_arch3m"
1558   ""
1561 (define_insn "*umulsidi3_nov6"
1562   [(set (match_operand:DI 0 "s_register_operand" "=&r")
1563         (mult:DI
1564          (zero_extend:DI (match_operand:SI 1 "s_register_operand" "%r"))
1565          (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1566   "TARGET_32BIT && arm_arch3m && !arm_arch6"
1567   "umull%?\\t%Q0, %R0, %1, %2"
1568   [(set_attr "type" "umull")
1569    (set_attr "predicable" "yes")]
1572 (define_insn "*umulsidi3_v6"
1573   [(set (match_operand:DI 0 "s_register_operand" "=r")
1574         (mult:DI
1575          (zero_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1576          (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1577   "TARGET_32BIT && arm_arch6"
1578   "umull%?\\t%Q0, %R0, %1, %2"
1579   [(set_attr "type" "umull")
1580    (set_attr "predicable" "yes")
1581    (set_attr "predicable_short_it" "no")]
1584 (define_expand "umaddsidi4"
1585   [(set (match_operand:DI 0 "s_register_operand" "")
1586         (plus:DI
1587          (mult:DI
1588           (zero_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1589           (zero_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1590          (match_operand:DI 3 "s_register_operand" "")))]
1591   "TARGET_32BIT && arm_arch3m"
1592   "")
1594 (define_insn "*umulsidi3adddi"
1595   [(set (match_operand:DI 0 "s_register_operand" "=&r")
1596         (plus:DI
1597          (mult:DI
1598           (zero_extend:DI (match_operand:SI 2 "s_register_operand" "%r"))
1599           (zero_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1600          (match_operand:DI 1 "s_register_operand" "0")))]
1601   "TARGET_32BIT && arm_arch3m && !arm_arch6"
1602   "umlal%?\\t%Q0, %R0, %3, %2"
1603   [(set_attr "type" "umlal")
1604    (set_attr "predicable" "yes")]
1607 (define_insn "*umulsidi3adddi_v6"
1608   [(set (match_operand:DI 0 "s_register_operand" "=r")
1609         (plus:DI
1610          (mult:DI
1611           (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r"))
1612           (zero_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1613          (match_operand:DI 1 "s_register_operand" "0")))]
1614   "TARGET_32BIT && arm_arch6"
1615   "umlal%?\\t%Q0, %R0, %3, %2"
1616   [(set_attr "type" "umlal")
1617    (set_attr "predicable" "yes")
1618    (set_attr "predicable_short_it" "no")]
1621 (define_expand "smulsi3_highpart"
1622   [(parallel
1623     [(set (match_operand:SI 0 "s_register_operand" "")
1624           (truncate:SI
1625            (lshiftrt:DI
1626             (mult:DI
1627              (sign_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1628              (sign_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1629             (const_int 32))))
1630      (clobber (match_scratch:SI 3 ""))])]
1631   "TARGET_32BIT && arm_arch3m"
1632   ""
1635 (define_insn "*smulsi3_highpart_nov6"
1636   [(set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1637         (truncate:SI
1638          (lshiftrt:DI
1639           (mult:DI
1640            (sign_extend:DI (match_operand:SI 1 "s_register_operand" "%0,r"))
1641            (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r,r")))
1642           (const_int 32))))
1643    (clobber (match_scratch:SI 3 "=&r,&r"))]
1644   "TARGET_32BIT && arm_arch3m && !arm_arch6"
1645   "smull%?\\t%3, %0, %2, %1"
1646   [(set_attr "type" "smull")
1647    (set_attr "predicable" "yes")]
1650 (define_insn "*smulsi3_highpart_v6"
1651   [(set (match_operand:SI 0 "s_register_operand" "=r")
1652         (truncate:SI
1653          (lshiftrt:DI
1654           (mult:DI
1655            (sign_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1656            (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r")))
1657           (const_int 32))))
1658    (clobber (match_scratch:SI 3 "=r"))]
1659   "TARGET_32BIT && arm_arch6"
1660   "smull%?\\t%3, %0, %2, %1"
1661   [(set_attr "type" "smull")
1662    (set_attr "predicable" "yes")
1663    (set_attr "predicable_short_it" "no")]
1666 (define_expand "umulsi3_highpart"
1667   [(parallel
1668     [(set (match_operand:SI 0 "s_register_operand" "")
1669           (truncate:SI
1670            (lshiftrt:DI
1671             (mult:DI
1672              (zero_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1673               (zero_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1674             (const_int 32))))
1675      (clobber (match_scratch:SI 3 ""))])]
1676   "TARGET_32BIT && arm_arch3m"
1677   ""
1680 (define_insn "*umulsi3_highpart_nov6"
1681   [(set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1682         (truncate:SI
1683          (lshiftrt:DI
1684           (mult:DI
1685            (zero_extend:DI (match_operand:SI 1 "s_register_operand" "%0,r"))
1686            (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r,r")))
1687           (const_int 32))))
1688    (clobber (match_scratch:SI 3 "=&r,&r"))]
1689   "TARGET_32BIT && arm_arch3m && !arm_arch6"
1690   "umull%?\\t%3, %0, %2, %1"
1691   [(set_attr "type" "umull")
1692    (set_attr "predicable" "yes")]
1695 (define_insn "*umulsi3_highpart_v6"
1696   [(set (match_operand:SI 0 "s_register_operand" "=r")
1697         (truncate:SI
1698          (lshiftrt:DI
1699           (mult:DI
1700            (zero_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1701            (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r")))
1702           (const_int 32))))
1703    (clobber (match_scratch:SI 3 "=r"))]
1704   "TARGET_32BIT && arm_arch6"
1705   "umull%?\\t%3, %0, %2, %1"
1706   [(set_attr "type" "umull")
1707    (set_attr "predicable" "yes")
1708    (set_attr "predicable_short_it" "no")]
1711 (define_insn "mulhisi3"
1712   [(set (match_operand:SI 0 "s_register_operand" "=r")
1713         (mult:SI (sign_extend:SI
1714                   (match_operand:HI 1 "s_register_operand" "%r"))
1715                  (sign_extend:SI
1716                   (match_operand:HI 2 "s_register_operand" "r"))))]
1717   "TARGET_DSP_MULTIPLY"
1718   "smulbb%?\\t%0, %1, %2"
1719   [(set_attr "type" "smulxy")
1720    (set_attr "predicable" "yes")]
1723 (define_insn "*mulhisi3tb"
1724   [(set (match_operand:SI 0 "s_register_operand" "=r")
1725         (mult:SI (ashiftrt:SI
1726                   (match_operand:SI 1 "s_register_operand" "r")
1727                   (const_int 16))
1728                  (sign_extend:SI
1729                   (match_operand:HI 2 "s_register_operand" "r"))))]
1730   "TARGET_DSP_MULTIPLY"
1731   "smultb%?\\t%0, %1, %2"
1732   [(set_attr "type" "smulxy")
1733    (set_attr "predicable" "yes")
1734    (set_attr "predicable_short_it" "no")]
1737 (define_insn "*mulhisi3bt"
1738   [(set (match_operand:SI 0 "s_register_operand" "=r")
1739         (mult:SI (sign_extend:SI
1740                   (match_operand:HI 1 "s_register_operand" "r"))
1741                  (ashiftrt:SI
1742                   (match_operand:SI 2 "s_register_operand" "r")
1743                   (const_int 16))))]
1744   "TARGET_DSP_MULTIPLY"
1745   "smulbt%?\\t%0, %1, %2"
1746   [(set_attr "type" "smulxy")
1747    (set_attr "predicable" "yes")
1748    (set_attr "predicable_short_it" "no")]
1751 (define_insn "*mulhisi3tt"
1752   [(set (match_operand:SI 0 "s_register_operand" "=r")
1753         (mult:SI (ashiftrt:SI
1754                   (match_operand:SI 1 "s_register_operand" "r")
1755                   (const_int 16))
1756                  (ashiftrt:SI
1757                   (match_operand:SI 2 "s_register_operand" "r")
1758                   (const_int 16))))]
1759   "TARGET_DSP_MULTIPLY"
1760   "smultt%?\\t%0, %1, %2"
1761   [(set_attr "type" "smulxy")
1762    (set_attr "predicable" "yes")
1763    (set_attr "predicable_short_it" "no")]
1766 (define_insn "maddhisi4"
1767   [(set (match_operand:SI 0 "s_register_operand" "=r")
1768         (plus:SI (mult:SI (sign_extend:SI
1769                            (match_operand:HI 1 "s_register_operand" "r"))
1770                           (sign_extend:SI
1771                            (match_operand:HI 2 "s_register_operand" "r")))
1772                  (match_operand:SI 3 "s_register_operand" "r")))]
1773   "TARGET_DSP_MULTIPLY"
1774   "smlabb%?\\t%0, %1, %2, %3"
1775   [(set_attr "type" "smlaxy")
1776    (set_attr "predicable" "yes")
1777    (set_attr "predicable_short_it" "no")]
1780 ;; Note: there is no maddhisi4ibt because this one is canonical form
1781 (define_insn "*maddhisi4tb"
1782   [(set (match_operand:SI 0 "s_register_operand" "=r")
1783         (plus:SI (mult:SI (ashiftrt:SI
1784                            (match_operand:SI 1 "s_register_operand" "r")
1785                            (const_int 16))
1786                           (sign_extend:SI
1787                            (match_operand:HI 2 "s_register_operand" "r")))
1788                  (match_operand:SI 3 "s_register_operand" "r")))]
1789   "TARGET_DSP_MULTIPLY"
1790   "smlatb%?\\t%0, %1, %2, %3"
1791   [(set_attr "type" "smlaxy")
1792    (set_attr "predicable" "yes")
1793    (set_attr "predicable_short_it" "no")]
1796 (define_insn "*maddhisi4tt"
1797   [(set (match_operand:SI 0 "s_register_operand" "=r")
1798         (plus:SI (mult:SI (ashiftrt:SI
1799                            (match_operand:SI 1 "s_register_operand" "r")
1800                            (const_int 16))
1801                           (ashiftrt:SI
1802                            (match_operand:SI 2 "s_register_operand" "r")
1803                            (const_int 16)))
1804                  (match_operand:SI 3 "s_register_operand" "r")))]
1805   "TARGET_DSP_MULTIPLY"
1806   "smlatt%?\\t%0, %1, %2, %3"
1807   [(set_attr "type" "smlaxy")
1808    (set_attr "predicable" "yes")
1809    (set_attr "predicable_short_it" "no")]
1812 (define_insn "maddhidi4"
1813   [(set (match_operand:DI 0 "s_register_operand" "=r")
1814         (plus:DI
1815           (mult:DI (sign_extend:DI
1816                     (match_operand:HI 1 "s_register_operand" "r"))
1817                    (sign_extend:DI
1818                     (match_operand:HI 2 "s_register_operand" "r")))
1819           (match_operand:DI 3 "s_register_operand" "0")))]
1820   "TARGET_DSP_MULTIPLY"
1821   "smlalbb%?\\t%Q0, %R0, %1, %2"
1822   [(set_attr "type" "smlalxy")
1823    (set_attr "predicable" "yes")
1824    (set_attr "predicable_short_it" "no")])
1826 ;; Note: there is no maddhidi4ibt because this one is canonical form
1827 (define_insn "*maddhidi4tb"
1828   [(set (match_operand:DI 0 "s_register_operand" "=r")
1829         (plus:DI
1830           (mult:DI (sign_extend:DI
1831                     (ashiftrt:SI
1832                      (match_operand:SI 1 "s_register_operand" "r")
1833                      (const_int 16)))
1834                    (sign_extend:DI
1835                     (match_operand:HI 2 "s_register_operand" "r")))
1836           (match_operand:DI 3 "s_register_operand" "0")))]
1837   "TARGET_DSP_MULTIPLY"
1838   "smlaltb%?\\t%Q0, %R0, %1, %2"
1839   [(set_attr "type" "smlalxy")
1840    (set_attr "predicable" "yes")
1841    (set_attr "predicable_short_it" "no")])
1843 (define_insn "*maddhidi4tt"
1844   [(set (match_operand:DI 0 "s_register_operand" "=r")
1845         (plus:DI
1846           (mult:DI (sign_extend:DI
1847                     (ashiftrt:SI
1848                      (match_operand:SI 1 "s_register_operand" "r")
1849                      (const_int 16)))
1850                    (sign_extend:DI
1851                     (ashiftrt:SI
1852                      (match_operand:SI 2 "s_register_operand" "r")
1853                      (const_int 16))))
1854           (match_operand:DI 3 "s_register_operand" "0")))]
1855   "TARGET_DSP_MULTIPLY"
1856   "smlaltt%?\\t%Q0, %R0, %1, %2"
1857   [(set_attr "type" "smlalxy")
1858    (set_attr "predicable" "yes")
1859    (set_attr "predicable_short_it" "no")])
1861 (define_expand "mulsf3"
1862   [(set (match_operand:SF          0 "s_register_operand" "")
1863         (mult:SF (match_operand:SF 1 "s_register_operand" "")
1864                  (match_operand:SF 2 "s_register_operand" "")))]
1865   "TARGET_32BIT && TARGET_HARD_FLOAT"
1866   "
1869 (define_expand "muldf3"
1870   [(set (match_operand:DF          0 "s_register_operand" "")
1871         (mult:DF (match_operand:DF 1 "s_register_operand" "")
1872                  (match_operand:DF 2 "s_register_operand" "")))]
1873   "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
1874   "
1877 ;; Division insns
1879 (define_expand "divsf3"
1880   [(set (match_operand:SF 0 "s_register_operand" "")
1881         (div:SF (match_operand:SF 1 "s_register_operand" "")
1882                 (match_operand:SF 2 "s_register_operand" "")))]
1883   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
1884   "")
1886 (define_expand "divdf3"
1887   [(set (match_operand:DF 0 "s_register_operand" "")
1888         (div:DF (match_operand:DF 1 "s_register_operand" "")
1889                 (match_operand:DF 2 "s_register_operand" "")))]
1890   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
1891   "")
1893 ;; Boolean and,ior,xor insns
1895 ;; Split up double word logical operations
1897 ;; Split up simple DImode logical operations.  Simply perform the logical
1898 ;; operation on the upper and lower halves of the registers.
1899 (define_split
1900   [(set (match_operand:DI 0 "s_register_operand" "")
1901         (match_operator:DI 6 "logical_binary_operator"
1902           [(match_operand:DI 1 "s_register_operand" "")
1903            (match_operand:DI 2 "s_register_operand" "")]))]
1904   "TARGET_32BIT && reload_completed
1905    && ! (TARGET_NEON && IS_VFP_REGNUM (REGNO (operands[0])))
1906    && ! IS_IWMMXT_REGNUM (REGNO (operands[0]))"
1907   [(set (match_dup 0) (match_op_dup:SI 6 [(match_dup 1) (match_dup 2)]))
1908    (set (match_dup 3) (match_op_dup:SI 6 [(match_dup 4) (match_dup 5)]))]
1909   "
1910   {
1911     operands[3] = gen_highpart (SImode, operands[0]);
1912     operands[0] = gen_lowpart (SImode, operands[0]);
1913     operands[4] = gen_highpart (SImode, operands[1]);
1914     operands[1] = gen_lowpart (SImode, operands[1]);
1915     operands[5] = gen_highpart (SImode, operands[2]);
1916     operands[2] = gen_lowpart (SImode, operands[2]);
1917   }"
1920 (define_split
1921   [(set (match_operand:DI 0 "s_register_operand" "")
1922         (match_operator:DI 6 "logical_binary_operator"
1923           [(sign_extend:DI (match_operand:SI 2 "s_register_operand" ""))
1924            (match_operand:DI 1 "s_register_operand" "")]))]
1925   "TARGET_32BIT && reload_completed"
1926   [(set (match_dup 0) (match_op_dup:SI 6 [(match_dup 1) (match_dup 2)]))
1927    (set (match_dup 3) (match_op_dup:SI 6
1928                         [(ashiftrt:SI (match_dup 2) (const_int 31))
1929                          (match_dup 4)]))]
1930   "
1931   {
1932     operands[3] = gen_highpart (SImode, operands[0]);
1933     operands[0] = gen_lowpart (SImode, operands[0]);
1934     operands[4] = gen_highpart (SImode, operands[1]);
1935     operands[1] = gen_lowpart (SImode, operands[1]);
1936     operands[5] = gen_highpart (SImode, operands[2]);
1937     operands[2] = gen_lowpart (SImode, operands[2]);
1938   }"
1941 ;; The zero extend of operand 2 means we can just copy the high part of
1942 ;; operand1 into operand0.
1943 (define_split
1944   [(set (match_operand:DI 0 "s_register_operand" "")
1945         (ior:DI
1946           (zero_extend:DI (match_operand:SI 2 "s_register_operand" ""))
1947           (match_operand:DI 1 "s_register_operand" "")))]
1948   "TARGET_32BIT && operands[0] != operands[1] && reload_completed"
1949   [(set (match_dup 0) (ior:SI (match_dup 1) (match_dup 2)))
1950    (set (match_dup 3) (match_dup 4))]
1951   "
1952   {
1953     operands[4] = gen_highpart (SImode, operands[1]);
1954     operands[3] = gen_highpart (SImode, operands[0]);
1955     operands[0] = gen_lowpart (SImode, operands[0]);
1956     operands[1] = gen_lowpart (SImode, operands[1]);
1957   }"
1960 ;; The zero extend of operand 2 means we can just copy the high part of
1961 ;; operand1 into operand0.
1962 (define_split
1963   [(set (match_operand:DI 0 "s_register_operand" "")
1964         (xor:DI
1965           (zero_extend:DI (match_operand:SI 2 "s_register_operand" ""))
1966           (match_operand:DI 1 "s_register_operand" "")))]
1967   "TARGET_32BIT && operands[0] != operands[1] && reload_completed"
1968   [(set (match_dup 0) (xor:SI (match_dup 1) (match_dup 2)))
1969    (set (match_dup 3) (match_dup 4))]
1970   "
1971   {
1972     operands[4] = gen_highpart (SImode, operands[1]);
1973     operands[3] = gen_highpart (SImode, operands[0]);
1974     operands[0] = gen_lowpart (SImode, operands[0]);
1975     operands[1] = gen_lowpart (SImode, operands[1]);
1976   }"
1979 (define_expand "anddi3"
1980   [(set (match_operand:DI         0 "s_register_operand" "")
1981         (and:DI (match_operand:DI 1 "s_register_operand" "")
1982                 (match_operand:DI 2 "neon_inv_logic_op2" "")))]
1983   "TARGET_32BIT"
1984   ""
1987 (define_insn_and_split "*anddi3_insn"
1988   [(set (match_operand:DI         0 "s_register_operand"     "=w,w ,&r,&r,&r,&r,?w,?w")
1989         (and:DI (match_operand:DI 1 "s_register_operand"     "%w,0 ,0 ,r ,0 ,r ,w ,0")
1990                 (match_operand:DI 2 "arm_anddi_operand_neon" "w ,DL,r ,r ,De,De,w ,DL")))]
1991   "TARGET_32BIT && !TARGET_IWMMXT"
1993   switch (which_alternative)
1994     {
1995     case 0: /* fall through */
1996     case 6: return "vand\t%P0, %P1, %P2";
1997     case 1: /* fall through */
1998     case 7: return neon_output_logic_immediate ("vand", &operands[2],
1999                     DImode, 1, VALID_NEON_QREG_MODE (DImode));
2000     case 2:
2001     case 3:
2002     case 4:
2003     case 5: /* fall through */
2004       return "#";
2005     default: gcc_unreachable ();
2006     }
2008   "TARGET_32BIT && !TARGET_IWMMXT && reload_completed
2009    && !(IS_VFP_REGNUM (REGNO (operands[0])))"
2010   [(set (match_dup 3) (match_dup 4))
2011    (set (match_dup 5) (match_dup 6))]
2012   "
2013   {
2014     operands[3] = gen_lowpart (SImode, operands[0]);
2015     operands[5] = gen_highpart (SImode, operands[0]);
2017     operands[4] = simplify_gen_binary (AND, SImode,
2018                                            gen_lowpart (SImode, operands[1]),
2019                                            gen_lowpart (SImode, operands[2]));
2020     operands[6] = simplify_gen_binary (AND, SImode,
2021                                            gen_highpart (SImode, operands[1]),
2022                                            gen_highpart_mode (SImode, DImode, operands[2]));
2024   }"
2025   [(set_attr "type" "neon_logic,neon_logic,multiple,multiple,\
2026                      multiple,multiple,neon_logic,neon_logic")
2027    (set_attr "arch" "neon_for_64bits,neon_for_64bits,*,*,*,*,
2028                      avoid_neon_for_64bits,avoid_neon_for_64bits")
2029    (set_attr "length" "*,*,8,8,8,8,*,*")
2030   ]
2033 (define_insn_and_split "*anddi_zesidi_di"
2034   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2035         (and:DI (zero_extend:DI
2036                  (match_operand:SI 2 "s_register_operand" "r,r"))
2037                 (match_operand:DI 1 "s_register_operand" "0,r")))]
2038   "TARGET_32BIT"
2039   "#"
2040   "TARGET_32BIT && reload_completed"
2041   ; The zero extend of operand 2 clears the high word of the output
2042   ; operand.
2043   [(set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))
2044    (set (match_dup 3) (const_int 0))]
2045   "
2046   {
2047     operands[3] = gen_highpart (SImode, operands[0]);
2048     operands[0] = gen_lowpart (SImode, operands[0]);
2049     operands[1] = gen_lowpart (SImode, operands[1]);
2050   }"
2051   [(set_attr "length" "8")
2052    (set_attr "type" "multiple")]
2055 (define_insn "*anddi_sesdi_di"
2056   [(set (match_operand:DI          0 "s_register_operand" "=&r,&r")
2057         (and:DI (sign_extend:DI
2058                  (match_operand:SI 2 "s_register_operand" "r,r"))
2059                 (match_operand:DI  1 "s_register_operand" "0,r")))]
2060   "TARGET_32BIT"
2061   "#"
2062   [(set_attr "length" "8")
2063    (set_attr "type" "multiple")]
2066 (define_expand "andsi3"
2067   [(set (match_operand:SI         0 "s_register_operand" "")
2068         (and:SI (match_operand:SI 1 "s_register_operand" "")
2069                 (match_operand:SI 2 "reg_or_int_operand" "")))]
2070   "TARGET_EITHER"
2071   "
2072   if (TARGET_32BIT)
2073     {
2074       if (CONST_INT_P (operands[2]))
2075         {
2076           if (INTVAL (operands[2]) == 255 && arm_arch6)
2077             {
2078               operands[1] = convert_to_mode (QImode, operands[1], 1);
2079               emit_insn (gen_thumb2_zero_extendqisi2_v6 (operands[0],
2080                                                          operands[1]));
2081             }
2082           else
2083             arm_split_constant (AND, SImode, NULL_RTX,
2084                                 INTVAL (operands[2]), operands[0],
2085                                 operands[1],
2086                                 optimize && can_create_pseudo_p ());
2088           DONE;
2089         }
2090     }
2091   else /* TARGET_THUMB1 */
2092     {
2093       if (!CONST_INT_P (operands[2]))
2094         {
2095           rtx tmp = force_reg (SImode, operands[2]);
2096           if (rtx_equal_p (operands[0], operands[1]))
2097             operands[2] = tmp;
2098           else
2099             {
2100               operands[2] = operands[1];
2101               operands[1] = tmp;
2102             }
2103         }
2104       else
2105         {
2106           int i;
2107           
2108           if (((unsigned HOST_WIDE_INT) ~INTVAL (operands[2])) < 256)
2109             {
2110               operands[2] = force_reg (SImode,
2111                                        GEN_INT (~INTVAL (operands[2])));
2112               
2113               emit_insn (gen_thumb1_bicsi3 (operands[0], operands[2], operands[1]));
2114               
2115               DONE;
2116             }
2118           for (i = 9; i <= 31; i++)
2119             {
2120               if ((((HOST_WIDE_INT) 1) << i) - 1 == INTVAL (operands[2]))
2121                 {
2122                   emit_insn (gen_extzv (operands[0], operands[1], GEN_INT (i),
2123                                         const0_rtx));
2124                   DONE;
2125                 }
2126               else if ((((HOST_WIDE_INT) 1) << i) - 1
2127                        == ~INTVAL (operands[2]))
2128                 {
2129                   rtx shift = GEN_INT (i);
2130                   rtx reg = gen_reg_rtx (SImode);
2131                 
2132                   emit_insn (gen_lshrsi3 (reg, operands[1], shift));
2133                   emit_insn (gen_ashlsi3 (operands[0], reg, shift));
2134                   
2135                   DONE;
2136                 }
2137             }
2139           operands[2] = force_reg (SImode, operands[2]);
2140         }
2141     }
2142   "
2145 ; ??? Check split length for Thumb-2
2146 (define_insn_and_split "*arm_andsi3_insn"
2147   [(set (match_operand:SI         0 "s_register_operand" "=r,l,r,r,r")
2148         (and:SI (match_operand:SI 1 "s_register_operand" "%r,0,r,r,r")
2149                 (match_operand:SI 2 "reg_or_int_operand" "I,l,K,r,?n")))]
2150   "TARGET_32BIT"
2151   "@
2152    and%?\\t%0, %1, %2
2153    and%?\\t%0, %1, %2
2154    bic%?\\t%0, %1, #%B2
2155    and%?\\t%0, %1, %2
2156    #"
2157   "TARGET_32BIT
2158    && CONST_INT_P (operands[2])
2159    && !(const_ok_for_arm (INTVAL (operands[2]))
2160         || const_ok_for_arm (~INTVAL (operands[2])))"
2161   [(clobber (const_int 0))]
2162   "
2163   arm_split_constant  (AND, SImode, curr_insn, 
2164                        INTVAL (operands[2]), operands[0], operands[1], 0);
2165   DONE;
2166   "
2167   [(set_attr "length" "4,4,4,4,16")
2168    (set_attr "predicable" "yes")
2169    (set_attr "predicable_short_it" "no,yes,no,no,no")
2170    (set_attr "type" "logic_imm,logic_imm,logic_reg,logic_reg,logic_imm")]
2173 (define_insn "*andsi3_compare0"
2174   [(set (reg:CC_NOOV CC_REGNUM)
2175         (compare:CC_NOOV
2176          (and:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
2177                  (match_operand:SI 2 "arm_not_operand" "I,K,r"))
2178          (const_int 0)))
2179    (set (match_operand:SI          0 "s_register_operand" "=r,r,r")
2180         (and:SI (match_dup 1) (match_dup 2)))]
2181   "TARGET_32BIT"
2182   "@
2183    and%.\\t%0, %1, %2
2184    bic%.\\t%0, %1, #%B2
2185    and%.\\t%0, %1, %2"
2186   [(set_attr "conds" "set")
2187    (set_attr "type" "logics_imm,logics_imm,logics_reg")]
2190 (define_insn "*andsi3_compare0_scratch"
2191   [(set (reg:CC_NOOV CC_REGNUM)
2192         (compare:CC_NOOV
2193          (and:SI (match_operand:SI 0 "s_register_operand" "r,r,r")
2194                  (match_operand:SI 1 "arm_not_operand" "I,K,r"))
2195          (const_int 0)))
2196    (clobber (match_scratch:SI 2 "=X,r,X"))]
2197   "TARGET_32BIT"
2198   "@
2199    tst%?\\t%0, %1
2200    bic%.\\t%2, %0, #%B1
2201    tst%?\\t%0, %1"
2202   [(set_attr "conds" "set")
2203    (set_attr "type"  "logics_imm,logics_imm,logics_reg")]
2206 (define_insn "*zeroextractsi_compare0_scratch"
2207   [(set (reg:CC_NOOV CC_REGNUM)
2208         (compare:CC_NOOV (zero_extract:SI
2209                           (match_operand:SI 0 "s_register_operand" "r")
2210                           (match_operand 1 "const_int_operand" "n")
2211                           (match_operand 2 "const_int_operand" "n"))
2212                          (const_int 0)))]
2213   "TARGET_32BIT
2214   && (INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) < 32
2215       && INTVAL (operands[1]) > 0 
2216       && INTVAL (operands[1]) + (INTVAL (operands[2]) & 1) <= 8
2217       && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32)"
2218   "*
2219   operands[1] = GEN_INT (((1 << INTVAL (operands[1])) - 1)
2220                          << INTVAL (operands[2]));
2221   output_asm_insn (\"tst%?\\t%0, %1\", operands);
2222   return \"\";
2223   "
2224   [(set_attr "conds" "set")
2225    (set_attr "predicable" "yes")
2226    (set_attr "predicable_short_it" "no")
2227    (set_attr "type" "logics_imm")]
2230 (define_insn_and_split "*ne_zeroextractsi"
2231   [(set (match_operand:SI 0 "s_register_operand" "=r")
2232         (ne:SI (zero_extract:SI
2233                 (match_operand:SI 1 "s_register_operand" "r")
2234                 (match_operand:SI 2 "const_int_operand" "n")
2235                 (match_operand:SI 3 "const_int_operand" "n"))
2236                (const_int 0)))
2237    (clobber (reg:CC CC_REGNUM))]
2238   "TARGET_32BIT
2239    && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2240        && INTVAL (operands[2]) > 0 
2241        && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2242        && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)"
2243   "#"
2244   "TARGET_32BIT
2245    && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2246        && INTVAL (operands[2]) > 0 
2247        && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2248        && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)"
2249   [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2250                    (compare:CC_NOOV (and:SI (match_dup 1) (match_dup 2))
2251                                     (const_int 0)))
2252               (set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))])
2253    (set (match_dup 0)
2254         (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2255                          (match_dup 0) (const_int 1)))]
2256   "
2257   operands[2] = GEN_INT (((1 << INTVAL (operands[2])) - 1)
2258                          << INTVAL (operands[3])); 
2259   "
2260   [(set_attr "conds" "clob")
2261    (set (attr "length")
2262         (if_then_else (eq_attr "is_thumb" "yes")
2263                       (const_int 12)
2264                       (const_int 8)))
2265    (set_attr "type" "multiple")]
2268 (define_insn_and_split "*ne_zeroextractsi_shifted"
2269   [(set (match_operand:SI 0 "s_register_operand" "=r")
2270         (ne:SI (zero_extract:SI
2271                 (match_operand:SI 1 "s_register_operand" "r")
2272                 (match_operand:SI 2 "const_int_operand" "n")
2273                 (const_int 0))
2274                (const_int 0)))
2275    (clobber (reg:CC CC_REGNUM))]
2276   "TARGET_ARM"
2277   "#"
2278   "TARGET_ARM"
2279   [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2280                    (compare:CC_NOOV (ashift:SI (match_dup 1) (match_dup 2))
2281                                     (const_int 0)))
2282               (set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))])
2283    (set (match_dup 0)
2284         (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2285                          (match_dup 0) (const_int 1)))]
2286   "
2287   operands[2] = GEN_INT (32 - INTVAL (operands[2]));
2288   "
2289   [(set_attr "conds" "clob")
2290    (set_attr "length" "8")
2291    (set_attr "type" "multiple")]
2294 (define_insn_and_split "*ite_ne_zeroextractsi"
2295   [(set (match_operand:SI 0 "s_register_operand" "=r")
2296         (if_then_else:SI (ne (zero_extract:SI
2297                               (match_operand:SI 1 "s_register_operand" "r")
2298                               (match_operand:SI 2 "const_int_operand" "n")
2299                               (match_operand:SI 3 "const_int_operand" "n"))
2300                              (const_int 0))
2301                          (match_operand:SI 4 "arm_not_operand" "rIK")
2302                          (const_int 0)))
2303    (clobber (reg:CC CC_REGNUM))]
2304   "TARGET_ARM
2305    && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2306        && INTVAL (operands[2]) > 0 
2307        && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2308        && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)
2309    && !reg_overlap_mentioned_p (operands[0], operands[4])"
2310   "#"
2311   "TARGET_ARM
2312    && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2313        && INTVAL (operands[2]) > 0 
2314        && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2315        && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)
2316    && !reg_overlap_mentioned_p (operands[0], operands[4])"
2317   [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2318                    (compare:CC_NOOV (and:SI (match_dup 1) (match_dup 2))
2319                                     (const_int 0)))
2320               (set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))])
2321    (set (match_dup 0)
2322         (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2323                          (match_dup 0) (match_dup 4)))]
2324   "
2325   operands[2] = GEN_INT (((1 << INTVAL (operands[2])) - 1)
2326                          << INTVAL (operands[3])); 
2327   "
2328   [(set_attr "conds" "clob")
2329    (set_attr "length" "8")
2330    (set_attr "type" "multiple")]
2333 (define_insn_and_split "*ite_ne_zeroextractsi_shifted"
2334   [(set (match_operand:SI 0 "s_register_operand" "=r")
2335         (if_then_else:SI (ne (zero_extract:SI
2336                               (match_operand:SI 1 "s_register_operand" "r")
2337                               (match_operand:SI 2 "const_int_operand" "n")
2338                               (const_int 0))
2339                              (const_int 0))
2340                          (match_operand:SI 3 "arm_not_operand" "rIK")
2341                          (const_int 0)))
2342    (clobber (reg:CC CC_REGNUM))]
2343   "TARGET_ARM && !reg_overlap_mentioned_p (operands[0], operands[3])"
2344   "#"
2345   "TARGET_ARM && !reg_overlap_mentioned_p (operands[0], operands[3])"
2346   [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2347                    (compare:CC_NOOV (ashift:SI (match_dup 1) (match_dup 2))
2348                                     (const_int 0)))
2349               (set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))])
2350    (set (match_dup 0)
2351         (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2352                          (match_dup 0) (match_dup 3)))]
2353   "
2354   operands[2] = GEN_INT (32 - INTVAL (operands[2]));
2355   "
2356   [(set_attr "conds" "clob")
2357    (set_attr "length" "8")
2358    (set_attr "type" "multiple")]
2361 ;; ??? Use Thumb-2 has bitfield insert/extract instructions.
2362 (define_split
2363   [(set (match_operand:SI 0 "s_register_operand" "")
2364         (match_operator:SI 1 "shiftable_operator"
2365          [(zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
2366                            (match_operand:SI 3 "const_int_operand" "")
2367                            (match_operand:SI 4 "const_int_operand" ""))
2368           (match_operand:SI 5 "s_register_operand" "")]))
2369    (clobber (match_operand:SI 6 "s_register_operand" ""))]
2370   "TARGET_ARM"
2371   [(set (match_dup 6) (ashift:SI (match_dup 2) (match_dup 3)))
2372    (set (match_dup 0)
2373         (match_op_dup 1
2374          [(lshiftrt:SI (match_dup 6) (match_dup 4))
2375           (match_dup 5)]))]
2376   "{
2377      HOST_WIDE_INT temp = INTVAL (operands[3]);
2379      operands[3] = GEN_INT (32 - temp - INTVAL (operands[4]));
2380      operands[4] = GEN_INT (32 - temp);
2381    }"
2383   
2384 (define_split
2385   [(set (match_operand:SI 0 "s_register_operand" "")
2386         (match_operator:SI 1 "shiftable_operator"
2387          [(sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
2388                            (match_operand:SI 3 "const_int_operand" "")
2389                            (match_operand:SI 4 "const_int_operand" ""))
2390           (match_operand:SI 5 "s_register_operand" "")]))
2391    (clobber (match_operand:SI 6 "s_register_operand" ""))]
2392   "TARGET_ARM"
2393   [(set (match_dup 6) (ashift:SI (match_dup 2) (match_dup 3)))
2394    (set (match_dup 0)
2395         (match_op_dup 1
2396          [(ashiftrt:SI (match_dup 6) (match_dup 4))
2397           (match_dup 5)]))]
2398   "{
2399      HOST_WIDE_INT temp = INTVAL (operands[3]);
2401      operands[3] = GEN_INT (32 - temp - INTVAL (operands[4]));
2402      operands[4] = GEN_INT (32 - temp);
2403    }"
2405   
2406 ;;; ??? This pattern is bogus.  If operand3 has bits outside the range
2407 ;;; represented by the bitfield, then this will produce incorrect results.
2408 ;;; Somewhere, the value needs to be truncated.  On targets like the m68k,
2409 ;;; which have a real bit-field insert instruction, the truncation happens
2410 ;;; in the bit-field insert instruction itself.  Since arm does not have a
2411 ;;; bit-field insert instruction, we would have to emit code here to truncate
2412 ;;; the value before we insert.  This loses some of the advantage of having
2413 ;;; this insv pattern, so this pattern needs to be reevalutated.
2415 (define_expand "insv"
2416   [(set (zero_extract (match_operand 0 "nonimmediate_operand" "")
2417                       (match_operand 1 "general_operand" "")
2418                       (match_operand 2 "general_operand" ""))
2419         (match_operand 3 "reg_or_int_operand" ""))]
2420   "TARGET_ARM || arm_arch_thumb2"
2421   "
2422   {
2423     int start_bit = INTVAL (operands[2]);
2424     int width = INTVAL (operands[1]);
2425     HOST_WIDE_INT mask = (((HOST_WIDE_INT)1) << width) - 1;
2426     rtx target, subtarget;
2428     if (arm_arch_thumb2)
2429       {
2430         if (unaligned_access && MEM_P (operands[0])
2431             && s_register_operand (operands[3], GET_MODE (operands[3]))
2432             && (width == 16 || width == 32) && (start_bit % BITS_PER_UNIT) == 0)
2433           {
2434             rtx base_addr;
2436             if (BYTES_BIG_ENDIAN)
2437               start_bit = GET_MODE_BITSIZE (GET_MODE (operands[3])) - width
2438                           - start_bit;
2440             if (width == 32)
2441               {
2442                 base_addr = adjust_address (operands[0], SImode,
2443                                             start_bit / BITS_PER_UNIT);
2444                 emit_insn (gen_unaligned_storesi (base_addr, operands[3]));
2445               }
2446             else
2447               {
2448                 rtx tmp = gen_reg_rtx (HImode);
2450                 base_addr = adjust_address (operands[0], HImode,
2451                                             start_bit / BITS_PER_UNIT);
2452                 emit_move_insn (tmp, gen_lowpart (HImode, operands[3]));
2453                 emit_insn (gen_unaligned_storehi (base_addr, tmp));
2454               }
2455             DONE;
2456           }
2457         else if (s_register_operand (operands[0], GET_MODE (operands[0])))
2458           {
2459             bool use_bfi = TRUE;
2461             if (CONST_INT_P (operands[3]))
2462               {
2463                 HOST_WIDE_INT val = INTVAL (operands[3]) & mask;
2465                 if (val == 0)
2466                   {
2467                     emit_insn (gen_insv_zero (operands[0], operands[1],
2468                                               operands[2]));
2469                     DONE;
2470                   }
2472                 /* See if the set can be done with a single orr instruction.  */
2473                 if (val == mask && const_ok_for_arm (val << start_bit))
2474                   use_bfi = FALSE;
2475               }
2477             if (use_bfi)
2478               {
2479                 if (!REG_P (operands[3]))
2480                   operands[3] = force_reg (SImode, operands[3]);
2482                 emit_insn (gen_insv_t2 (operands[0], operands[1], operands[2],
2483                                         operands[3]));
2484                 DONE;
2485               }
2486           }
2487         else
2488           FAIL;
2489       }
2491     if (!s_register_operand (operands[0], GET_MODE (operands[0])))
2492       FAIL;
2494     target = copy_rtx (operands[0]);
2495     /* Avoid using a subreg as a subtarget, and avoid writing a paradoxical 
2496        subreg as the final target.  */
2497     if (GET_CODE (target) == SUBREG)
2498       {
2499         subtarget = gen_reg_rtx (SImode);
2500         if (GET_MODE_SIZE (GET_MODE (SUBREG_REG (target)))
2501             < GET_MODE_SIZE (SImode))
2502           target = SUBREG_REG (target);
2503       }
2504     else
2505       subtarget = target;    
2507     if (CONST_INT_P (operands[3]))
2508       {
2509         /* Since we are inserting a known constant, we may be able to
2510            reduce the number of bits that we have to clear so that
2511            the mask becomes simple.  */
2512         /* ??? This code does not check to see if the new mask is actually
2513            simpler.  It may not be.  */
2514         rtx op1 = gen_reg_rtx (SImode);
2515         /* ??? Truncate operand3 to fit in the bitfield.  See comment before
2516            start of this pattern.  */
2517         HOST_WIDE_INT op3_value = mask & INTVAL (operands[3]);
2518         HOST_WIDE_INT mask2 = ((mask & ~op3_value) << start_bit);
2520         emit_insn (gen_andsi3 (op1, operands[0],
2521                                gen_int_mode (~mask2, SImode)));
2522         emit_insn (gen_iorsi3 (subtarget, op1,
2523                                gen_int_mode (op3_value << start_bit, SImode)));
2524       }
2525     else if (start_bit == 0
2526              && !(const_ok_for_arm (mask)
2527                   || const_ok_for_arm (~mask)))
2528       {
2529         /* A Trick, since we are setting the bottom bits in the word,
2530            we can shift operand[3] up, operand[0] down, OR them together
2531            and rotate the result back again.  This takes 3 insns, and
2532            the third might be mergeable into another op.  */
2533         /* The shift up copes with the possibility that operand[3] is
2534            wider than the bitfield.  */
2535         rtx op0 = gen_reg_rtx (SImode);
2536         rtx op1 = gen_reg_rtx (SImode);
2538         emit_insn (gen_ashlsi3 (op0, operands[3], GEN_INT (32 - width)));
2539         emit_insn (gen_lshrsi3 (op1, operands[0], operands[1]));
2540         emit_insn (gen_iorsi3  (op1, op1, op0));
2541         emit_insn (gen_rotlsi3 (subtarget, op1, operands[1]));
2542       }
2543     else if ((width + start_bit == 32)
2544              && !(const_ok_for_arm (mask)
2545                   || const_ok_for_arm (~mask)))
2546       {
2547         /* Similar trick, but slightly less efficient.  */
2549         rtx op0 = gen_reg_rtx (SImode);
2550         rtx op1 = gen_reg_rtx (SImode);
2552         emit_insn (gen_ashlsi3 (op0, operands[3], GEN_INT (32 - width)));
2553         emit_insn (gen_ashlsi3 (op1, operands[0], operands[1]));
2554         emit_insn (gen_lshrsi3 (op1, op1, operands[1]));
2555         emit_insn (gen_iorsi3 (subtarget, op1, op0));
2556       }
2557     else
2558       {
2559         rtx op0 = gen_int_mode (mask, SImode);
2560         rtx op1 = gen_reg_rtx (SImode);
2561         rtx op2 = gen_reg_rtx (SImode);
2563         if (!(const_ok_for_arm (mask) || const_ok_for_arm (~mask)))
2564           {
2565             rtx tmp = gen_reg_rtx (SImode);
2567             emit_insn (gen_movsi (tmp, op0));
2568             op0 = tmp;
2569           }
2571         /* Mask out any bits in operand[3] that are not needed.  */
2572            emit_insn (gen_andsi3 (op1, operands[3], op0));
2574         if (CONST_INT_P (op0)
2575             && (const_ok_for_arm (mask << start_bit)
2576                 || const_ok_for_arm (~(mask << start_bit))))
2577           {
2578             op0 = gen_int_mode (~(mask << start_bit), SImode);
2579             emit_insn (gen_andsi3 (op2, operands[0], op0));
2580           }
2581         else
2582           {
2583             if (CONST_INT_P (op0))
2584               {
2585                 rtx tmp = gen_reg_rtx (SImode);
2587                 emit_insn (gen_movsi (tmp, op0));
2588                 op0 = tmp;
2589               }
2591             if (start_bit != 0)
2592               emit_insn (gen_ashlsi3 (op0, op0, operands[2]));
2593             
2594             emit_insn (gen_andsi_notsi_si (op2, operands[0], op0));
2595           }
2597         if (start_bit != 0)
2598           emit_insn (gen_ashlsi3 (op1, op1, operands[2]));
2600         emit_insn (gen_iorsi3 (subtarget, op1, op2));
2601       }
2603     if (subtarget != target)
2604       {
2605         /* If TARGET is still a SUBREG, then it must be wider than a word,
2606            so we must be careful only to set the subword we were asked to.  */
2607         if (GET_CODE (target) == SUBREG)
2608           emit_move_insn (target, subtarget);
2609         else
2610           emit_move_insn (target, gen_lowpart (GET_MODE (target), subtarget));
2611       }
2613     DONE;
2614   }"
2617 (define_insn "insv_zero"
2618   [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r")
2619                          (match_operand:SI 1 "const_int_M_operand" "M")
2620                          (match_operand:SI 2 "const_int_M_operand" "M"))
2621         (const_int 0))]
2622   "arm_arch_thumb2"
2623   "bfc%?\t%0, %2, %1"
2624   [(set_attr "length" "4")
2625    (set_attr "predicable" "yes")
2626    (set_attr "predicable_short_it" "no")
2627    (set_attr "type" "bfm")]
2630 (define_insn "insv_t2"
2631   [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r")
2632                          (match_operand:SI 1 "const_int_M_operand" "M")
2633                          (match_operand:SI 2 "const_int_M_operand" "M"))
2634         (match_operand:SI 3 "s_register_operand" "r"))]
2635   "arm_arch_thumb2"
2636   "bfi%?\t%0, %3, %2, %1"
2637   [(set_attr "length" "4")
2638    (set_attr "predicable" "yes")
2639    (set_attr "predicable_short_it" "no")
2640    (set_attr "type" "bfm")]
2643 ; constants for op 2 will never be given to these patterns.
2644 (define_insn_and_split "*anddi_notdi_di"
2645   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2646         (and:DI (not:DI (match_operand:DI 1 "s_register_operand" "0,r"))
2647                 (match_operand:DI 2 "s_register_operand" "r,0")))]
2648   "TARGET_32BIT"
2649   "#"
2650   "TARGET_32BIT && reload_completed
2651    && ! (TARGET_NEON && IS_VFP_REGNUM (REGNO (operands[0])))
2652    && ! IS_IWMMXT_REGNUM (REGNO (operands[0]))"
2653   [(set (match_dup 0) (and:SI (not:SI (match_dup 1)) (match_dup 2)))
2654    (set (match_dup 3) (and:SI (not:SI (match_dup 4)) (match_dup 5)))]
2655   "
2656   {
2657     operands[3] = gen_highpart (SImode, operands[0]);
2658     operands[0] = gen_lowpart (SImode, operands[0]);
2659     operands[4] = gen_highpart (SImode, operands[1]);
2660     operands[1] = gen_lowpart (SImode, operands[1]);
2661     operands[5] = gen_highpart (SImode, operands[2]);
2662     operands[2] = gen_lowpart (SImode, operands[2]);
2663   }"
2664   [(set_attr "length" "8")
2665    (set_attr "predicable" "yes")
2666    (set_attr "type" "multiple")]
2669 (define_insn_and_split "*anddi_notzesidi_di"
2670   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2671         (and:DI (not:DI (zero_extend:DI
2672                          (match_operand:SI 2 "s_register_operand" "r,r")))
2673                 (match_operand:DI 1 "s_register_operand" "0,?r")))]
2674   "TARGET_32BIT"
2675   "@
2676    bic%?\\t%Q0, %Q1, %2
2677    #"
2678   ; (not (zero_extend ...)) allows us to just copy the high word from
2679   ; operand1 to operand0.
2680   "TARGET_32BIT
2681    && reload_completed
2682    && operands[0] != operands[1]"
2683   [(set (match_dup 0) (and:SI (not:SI (match_dup 2)) (match_dup 1)))
2684    (set (match_dup 3) (match_dup 4))]
2685   "
2686   {
2687     operands[3] = gen_highpart (SImode, operands[0]);
2688     operands[0] = gen_lowpart (SImode, operands[0]);
2689     operands[4] = gen_highpart (SImode, operands[1]);
2690     operands[1] = gen_lowpart (SImode, operands[1]);
2691   }"
2692   [(set_attr "length" "4,8")
2693    (set_attr "predicable" "yes")
2694    (set_attr "predicable_short_it" "no")
2695    (set_attr "type" "multiple")]
2698 (define_insn_and_split "*anddi_notdi_zesidi"
2699   [(set (match_operand:DI 0 "s_register_operand" "=r")
2700         (and:DI (not:DI (match_operand:DI 2 "s_register_operand" "r"))
2701                 (zero_extend:DI
2702                  (match_operand:SI 1 "s_register_operand" "r"))))]
2703   "TARGET_32BIT"
2704   "#"
2705   "TARGET_32BIT && reload_completed"
2706   [(set (match_dup 0) (and:SI (not:SI (match_dup 2)) (match_dup 1)))
2707    (set (match_dup 3) (const_int 0))]
2708   "
2709   {
2710     operands[3] = gen_highpart (SImode, operands[0]);
2711     operands[0] = gen_lowpart (SImode, operands[0]);
2712     operands[2] = gen_lowpart (SImode, operands[2]);
2713   }"
2714   [(set_attr "length" "8")
2715    (set_attr "predicable" "yes")
2716    (set_attr "predicable_short_it" "no")
2717    (set_attr "type" "multiple")]
2720 (define_insn_and_split "*anddi_notsesidi_di"
2721   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2722         (and:DI (not:DI (sign_extend:DI
2723                          (match_operand:SI 2 "s_register_operand" "r,r")))
2724                 (match_operand:DI 1 "s_register_operand" "0,r")))]
2725   "TARGET_32BIT"
2726   "#"
2727   "TARGET_32BIT && reload_completed"
2728   [(set (match_dup 0) (and:SI (not:SI (match_dup 2)) (match_dup 1)))
2729    (set (match_dup 3) (and:SI (not:SI
2730                                 (ashiftrt:SI (match_dup 2) (const_int 31)))
2731                                (match_dup 4)))]
2732   "
2733   {
2734     operands[3] = gen_highpart (SImode, operands[0]);
2735     operands[0] = gen_lowpart (SImode, operands[0]);
2736     operands[4] = gen_highpart (SImode, operands[1]);
2737     operands[1] = gen_lowpart (SImode, operands[1]);
2738   }"
2739   [(set_attr "length" "8")
2740    (set_attr "predicable" "yes")
2741    (set_attr "predicable_short_it" "no")
2742    (set_attr "type" "multiple")]
2745 (define_insn "andsi_notsi_si"
2746   [(set (match_operand:SI 0 "s_register_operand" "=r")
2747         (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
2748                 (match_operand:SI 1 "s_register_operand" "r")))]
2749   "TARGET_32BIT"
2750   "bic%?\\t%0, %1, %2"
2751   [(set_attr "predicable" "yes")
2752    (set_attr "predicable_short_it" "no")
2753    (set_attr "type" "logic_reg")]
2756 (define_insn "andsi_not_shiftsi_si"
2757   [(set (match_operand:SI 0 "s_register_operand" "=r")
2758         (and:SI (not:SI (match_operator:SI 4 "shift_operator"
2759                          [(match_operand:SI 2 "s_register_operand" "r")
2760                           (match_operand:SI 3 "arm_rhs_operand" "rM")]))
2761                 (match_operand:SI 1 "s_register_operand" "r")))]
2762   "TARGET_ARM"
2763   "bic%?\\t%0, %1, %2%S4"
2764   [(set_attr "predicable" "yes")
2765    (set_attr "shift" "2")
2766    (set (attr "type") (if_then_else (match_operand 3 "const_int_operand" "")
2767                       (const_string "logic_shift_imm")
2768                       (const_string "logic_shift_reg")))]
2771 (define_insn "*andsi_notsi_si_compare0"
2772   [(set (reg:CC_NOOV CC_REGNUM)
2773         (compare:CC_NOOV
2774          (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
2775                  (match_operand:SI 1 "s_register_operand" "r"))
2776          (const_int 0)))
2777    (set (match_operand:SI 0 "s_register_operand" "=r")
2778         (and:SI (not:SI (match_dup 2)) (match_dup 1)))]
2779   "TARGET_32BIT"
2780   "bic%.\\t%0, %1, %2"
2781   [(set_attr "conds" "set")
2782    (set_attr "type" "logics_shift_reg")]
2785 (define_insn "*andsi_notsi_si_compare0_scratch"
2786   [(set (reg:CC_NOOV CC_REGNUM)
2787         (compare:CC_NOOV
2788          (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
2789                  (match_operand:SI 1 "s_register_operand" "r"))
2790          (const_int 0)))
2791    (clobber (match_scratch:SI 0 "=r"))]
2792   "TARGET_32BIT"
2793   "bic%.\\t%0, %1, %2"
2794   [(set_attr "conds" "set")
2795    (set_attr "type" "logics_shift_reg")]
2798 (define_expand "iordi3"
2799   [(set (match_operand:DI         0 "s_register_operand" "")
2800         (ior:DI (match_operand:DI 1 "s_register_operand" "")
2801                 (match_operand:DI 2 "neon_logic_op2" "")))]
2802   "TARGET_32BIT"
2803   ""
2806 (define_insn_and_split "*iordi3_insn"
2807   [(set (match_operand:DI         0 "s_register_operand"     "=w,w ,&r,&r,&r,&r,?w,?w")
2808         (ior:DI (match_operand:DI 1 "s_register_operand"     "%w,0 ,0 ,r ,0 ,r ,w ,0")
2809                 (match_operand:DI 2 "arm_iordi_operand_neon" "w ,Dl,r ,r ,Df,Df,w ,Dl")))]
2810   "TARGET_32BIT && !TARGET_IWMMXT"
2811   {
2812   switch (which_alternative)
2813     {
2814     case 0: /* fall through */
2815     case 6: return "vorr\t%P0, %P1, %P2";
2816     case 1: /* fall through */
2817     case 7: return neon_output_logic_immediate ("vorr", &operands[2],
2818                      DImode, 0, VALID_NEON_QREG_MODE (DImode));
2819     case 2:
2820     case 3:
2821     case 4:
2822     case 5:
2823       return "#";
2824     default: gcc_unreachable ();
2825     }
2826   }
2827   "TARGET_32BIT && !TARGET_IWMMXT && reload_completed
2828    && !(IS_VFP_REGNUM (REGNO (operands[0])))"
2829   [(set (match_dup 3) (match_dup 4))
2830    (set (match_dup 5) (match_dup 6))]
2831   "
2832   {
2833     operands[3] = gen_lowpart (SImode, operands[0]);
2834     operands[5] = gen_highpart (SImode, operands[0]);
2836     operands[4] = simplify_gen_binary (IOR, SImode,
2837                                            gen_lowpart (SImode, operands[1]),
2838                                            gen_lowpart (SImode, operands[2]));
2839     operands[6] = simplify_gen_binary (IOR, SImode,
2840                                            gen_highpart (SImode, operands[1]),
2841                                            gen_highpart_mode (SImode, DImode, operands[2]));
2843   }"
2844   [(set_attr "type" "neon_logic,neon_logic,multiple,multiple,multiple,\
2845                      multiple,neon_logic,neon_logic")
2846    (set_attr "length" "*,*,8,8,8,8,*,*")
2847    (set_attr "arch" "neon_for_64bits,neon_for_64bits,*,*,*,*,avoid_neon_for_64bits,avoid_neon_for_64bits")]
2850 (define_insn "*iordi_zesidi_di"
2851   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2852         (ior:DI (zero_extend:DI
2853                  (match_operand:SI 2 "s_register_operand" "r,r"))
2854                 (match_operand:DI 1 "s_register_operand" "0,?r")))]
2855   "TARGET_32BIT"
2856   "@
2857    orr%?\\t%Q0, %Q1, %2
2858    #"
2859   [(set_attr "length" "4,8")
2860    (set_attr "predicable" "yes")
2861    (set_attr "predicable_short_it" "no")
2862    (set_attr "type" "logic_reg,multiple")]
2865 (define_insn "*iordi_sesidi_di"
2866   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2867         (ior:DI (sign_extend:DI
2868                  (match_operand:SI 2 "s_register_operand" "r,r"))
2869                 (match_operand:DI 1 "s_register_operand" "0,r")))]
2870   "TARGET_32BIT"
2871   "#"
2872   [(set_attr "length" "8")
2873    (set_attr "predicable" "yes")
2874    (set_attr "type" "multiple")]
2877 (define_expand "iorsi3"
2878   [(set (match_operand:SI         0 "s_register_operand" "")
2879         (ior:SI (match_operand:SI 1 "s_register_operand" "")
2880                 (match_operand:SI 2 "reg_or_int_operand" "")))]
2881   "TARGET_EITHER"
2882   "
2883   if (CONST_INT_P (operands[2]))
2884     {
2885       if (TARGET_32BIT)
2886         {
2887           arm_split_constant (IOR, SImode, NULL_RTX,
2888                               INTVAL (operands[2]), operands[0], operands[1],
2889                               optimize && can_create_pseudo_p ());
2890           DONE;
2891         }
2892       else /* TARGET_THUMB1 */
2893         {
2894           rtx tmp = force_reg (SImode, operands[2]);
2895           if (rtx_equal_p (operands[0], operands[1]))
2896             operands[2] = tmp;
2897           else
2898             {
2899               operands[2] = operands[1];
2900               operands[1] = tmp;
2901             }
2902         }
2903     }
2904   "
2907 (define_insn_and_split "*iorsi3_insn"
2908   [(set (match_operand:SI 0 "s_register_operand" "=r,l,r,r,r")
2909         (ior:SI (match_operand:SI 1 "s_register_operand" "%r,0,r,r,r")
2910                 (match_operand:SI 2 "reg_or_int_operand" "I,l,K,r,?n")))]
2911   "TARGET_32BIT"
2912   "@
2913    orr%?\\t%0, %1, %2
2914    orr%?\\t%0, %1, %2
2915    orn%?\\t%0, %1, #%B2
2916    orr%?\\t%0, %1, %2
2917    #"
2918   "TARGET_32BIT
2919    && CONST_INT_P (operands[2])
2920    && !(const_ok_for_arm (INTVAL (operands[2]))
2921         || (TARGET_THUMB2 && const_ok_for_arm (~INTVAL (operands[2]))))"
2922   [(clobber (const_int 0))]
2924   arm_split_constant (IOR, SImode, curr_insn,
2925                       INTVAL (operands[2]), operands[0], operands[1], 0);
2926   DONE;
2928   [(set_attr "length" "4,4,4,4,16")
2929    (set_attr "arch" "32,t2,t2,32,32")
2930    (set_attr "predicable" "yes")
2931    (set_attr "predicable_short_it" "no,yes,no,no,no")
2932    (set_attr "type" "logic_imm,logic_reg,logic_imm,logic_reg,logic_reg")]
2935 (define_peephole2
2936   [(match_scratch:SI 3 "r")
2937    (set (match_operand:SI 0 "arm_general_register_operand" "")
2938         (ior:SI (match_operand:SI 1 "arm_general_register_operand" "")
2939                 (match_operand:SI 2 "const_int_operand" "")))]
2940   "TARGET_ARM
2941    && !const_ok_for_arm (INTVAL (operands[2]))
2942    && const_ok_for_arm (~INTVAL (operands[2]))"
2943   [(set (match_dup 3) (match_dup 2))
2944    (set (match_dup 0) (ior:SI (match_dup 1) (match_dup 3)))]
2945   ""
2948 (define_insn "*iorsi3_compare0"
2949   [(set (reg:CC_NOOV CC_REGNUM)
2950         (compare:CC_NOOV (ior:SI (match_operand:SI 1 "s_register_operand" "%r,r")
2951                                  (match_operand:SI 2 "arm_rhs_operand" "I,r"))
2952                          (const_int 0)))
2953    (set (match_operand:SI 0 "s_register_operand" "=r,r")
2954         (ior:SI (match_dup 1) (match_dup 2)))]
2955   "TARGET_32BIT"
2956   "orr%.\\t%0, %1, %2"
2957   [(set_attr "conds" "set")
2958    (set_attr "type" "logics_imm,logics_reg")]
2961 (define_insn "*iorsi3_compare0_scratch"
2962   [(set (reg:CC_NOOV CC_REGNUM)
2963         (compare:CC_NOOV (ior:SI (match_operand:SI 1 "s_register_operand" "%r,r")
2964                                  (match_operand:SI 2 "arm_rhs_operand" "I,r"))
2965                          (const_int 0)))
2966    (clobber (match_scratch:SI 0 "=r,r"))]
2967   "TARGET_32BIT"
2968   "orr%.\\t%0, %1, %2"
2969   [(set_attr "conds" "set")
2970    (set_attr "type" "logics_imm,logics_reg")]
2973 (define_expand "xordi3"
2974   [(set (match_operand:DI         0 "s_register_operand" "")
2975         (xor:DI (match_operand:DI 1 "s_register_operand" "")
2976                 (match_operand:DI 2 "arm_xordi_operand" "")))]
2977   "TARGET_32BIT"
2978   ""
2981 (define_insn_and_split "*xordi3_insn"
2982   [(set (match_operand:DI         0 "s_register_operand" "=w,&r,&r,&r,&r,?w")
2983         (xor:DI (match_operand:DI 1 "s_register_operand" "%w ,0,r ,0 ,r ,w")
2984                 (match_operand:DI 2 "arm_xordi_operand"  "w ,r ,r ,Dg,Dg,w")))]
2985   "TARGET_32BIT && !TARGET_IWMMXT"
2987   switch (which_alternative)
2988     {
2989     case 1:
2990     case 2:
2991     case 3:
2992     case 4:  /* fall through */
2993       return "#";
2994     case 0: /* fall through */
2995     case 5: return "veor\t%P0, %P1, %P2";
2996     default: gcc_unreachable ();
2997     }
2999   "TARGET_32BIT && !TARGET_IWMMXT && reload_completed
3000    && !(IS_VFP_REGNUM (REGNO (operands[0])))"
3001   [(set (match_dup 3) (match_dup 4))
3002    (set (match_dup 5) (match_dup 6))]
3003   "
3004   {
3005     operands[3] = gen_lowpart (SImode, operands[0]);
3006     operands[5] = gen_highpart (SImode, operands[0]);
3008     operands[4] = simplify_gen_binary (XOR, SImode,
3009                                            gen_lowpart (SImode, operands[1]),
3010                                            gen_lowpart (SImode, operands[2]));
3011     operands[6] = simplify_gen_binary (XOR, SImode,
3012                                            gen_highpart (SImode, operands[1]),
3013                                            gen_highpart_mode (SImode, DImode, operands[2]));
3015   }"
3016   [(set_attr "length" "*,8,8,8,8,*")
3017    (set_attr "type" "neon_logic,multiple,multiple,multiple,multiple,neon_logic")
3018    (set_attr "arch" "neon_for_64bits,*,*,*,*,avoid_neon_for_64bits")]
3021 (define_insn "*xordi_zesidi_di"
3022   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
3023         (xor:DI (zero_extend:DI
3024                  (match_operand:SI 2 "s_register_operand" "r,r"))
3025                 (match_operand:DI 1 "s_register_operand" "0,?r")))]
3026   "TARGET_32BIT"
3027   "@
3028    eor%?\\t%Q0, %Q1, %2
3029    #"
3030   [(set_attr "length" "4,8")
3031    (set_attr "predicable" "yes")
3032    (set_attr "predicable_short_it" "no")
3033    (set_attr "type" "logic_reg")]
3036 (define_insn "*xordi_sesidi_di"
3037   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
3038         (xor:DI (sign_extend:DI
3039                  (match_operand:SI 2 "s_register_operand" "r,r"))
3040                 (match_operand:DI 1 "s_register_operand" "0,r")))]
3041   "TARGET_32BIT"
3042   "#"
3043   [(set_attr "length" "8")
3044    (set_attr "predicable" "yes")
3045    (set_attr "type" "multiple")]
3048 (define_expand "xorsi3"
3049   [(set (match_operand:SI         0 "s_register_operand" "")
3050         (xor:SI (match_operand:SI 1 "s_register_operand" "")
3051                 (match_operand:SI 2 "reg_or_int_operand" "")))]
3052   "TARGET_EITHER"
3053   "if (CONST_INT_P (operands[2]))
3054     {
3055       if (TARGET_32BIT)
3056         {
3057           arm_split_constant (XOR, SImode, NULL_RTX,
3058                               INTVAL (operands[2]), operands[0], operands[1],
3059                               optimize && can_create_pseudo_p ());
3060           DONE;
3061         }
3062       else /* TARGET_THUMB1 */
3063         {
3064           rtx tmp = force_reg (SImode, operands[2]);
3065           if (rtx_equal_p (operands[0], operands[1]))
3066             operands[2] = tmp;
3067           else
3068             {
3069               operands[2] = operands[1];
3070               operands[1] = tmp;
3071             }
3072         }
3073     }"
3076 (define_insn_and_split "*arm_xorsi3"
3077   [(set (match_operand:SI         0 "s_register_operand" "=r,l,r,r")
3078         (xor:SI (match_operand:SI 1 "s_register_operand" "%r,0,r,r")
3079                 (match_operand:SI 2 "reg_or_int_operand" "I,l,r,?n")))]
3080   "TARGET_32BIT"
3081   "@
3082    eor%?\\t%0, %1, %2
3083    eor%?\\t%0, %1, %2
3084    eor%?\\t%0, %1, %2
3085    #"
3086   "TARGET_32BIT
3087    && CONST_INT_P (operands[2])
3088    && !const_ok_for_arm (INTVAL (operands[2]))"
3089   [(clobber (const_int 0))]
3091   arm_split_constant (XOR, SImode, curr_insn,
3092                       INTVAL (operands[2]), operands[0], operands[1], 0);
3093   DONE;
3095   [(set_attr "length" "4,4,4,16")
3096    (set_attr "predicable" "yes")
3097    (set_attr "predicable_short_it" "no,yes,no,no")
3098    (set_attr "type"  "logic_imm,logic_reg,logic_reg,multiple")]
3101 (define_insn "*xorsi3_compare0"
3102   [(set (reg:CC_NOOV CC_REGNUM)
3103         (compare:CC_NOOV (xor:SI (match_operand:SI 1 "s_register_operand" "r,r")
3104                                  (match_operand:SI 2 "arm_rhs_operand" "I,r"))
3105                          (const_int 0)))
3106    (set (match_operand:SI 0 "s_register_operand" "=r,r")
3107         (xor:SI (match_dup 1) (match_dup 2)))]
3108   "TARGET_32BIT"
3109   "eor%.\\t%0, %1, %2"
3110   [(set_attr "conds" "set")
3111    (set_attr "type" "logics_imm,logics_reg")]
3114 (define_insn "*xorsi3_compare0_scratch"
3115   [(set (reg:CC_NOOV CC_REGNUM)
3116         (compare:CC_NOOV (xor:SI (match_operand:SI 0 "s_register_operand" "r,r")
3117                                  (match_operand:SI 1 "arm_rhs_operand" "I,r"))
3118                          (const_int 0)))]
3119   "TARGET_32BIT"
3120   "teq%?\\t%0, %1"
3121   [(set_attr "conds" "set")
3122    (set_attr "type" "logics_imm,logics_reg")]
3125 ; By splitting (IOR (AND (NOT A) (NOT B)) C) as D = AND (IOR A B) (NOT C), 
3126 ; (NOT D) we can sometimes merge the final NOT into one of the following
3127 ; insns.
3129 (define_split
3130   [(set (match_operand:SI 0 "s_register_operand" "")
3131         (ior:SI (and:SI (not:SI (match_operand:SI 1 "s_register_operand" ""))
3132                         (not:SI (match_operand:SI 2 "arm_rhs_operand" "")))
3133                 (match_operand:SI 3 "arm_rhs_operand" "")))
3134    (clobber (match_operand:SI 4 "s_register_operand" ""))]
3135   "TARGET_32BIT"
3136   [(set (match_dup 4) (and:SI (ior:SI (match_dup 1) (match_dup 2))
3137                               (not:SI (match_dup 3))))
3138    (set (match_dup 0) (not:SI (match_dup 4)))]
3139   ""
3142 (define_insn_and_split "*andsi_iorsi3_notsi"
3143   [(set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r")
3144         (and:SI (ior:SI (match_operand:SI 1 "s_register_operand" "%0,r,r")
3145                         (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI"))
3146                 (not:SI (match_operand:SI 3 "arm_rhs_operand" "rI,rI,rI"))))]
3147   "TARGET_32BIT"
3148   "#"   ; "orr%?\\t%0, %1, %2\;bic%?\\t%0, %0, %3"
3149   "&& reload_completed"
3150   [(set (match_dup 0) (ior:SI (match_dup 1) (match_dup 2)))
3151    (set (match_dup 0) (and:SI (not:SI (match_dup 3)) (match_dup 0)))]
3152   ""
3153   [(set_attr "length" "8")
3154    (set_attr "ce_count" "2")
3155    (set_attr "predicable" "yes")
3156    (set_attr "predicable_short_it" "no")
3157    (set_attr "type" "multiple")]
3160 ; ??? Are these four splitters still beneficial when the Thumb-2 bitfield
3161 ; insns are available?
3162 (define_split
3163   [(set (match_operand:SI 0 "s_register_operand" "")
3164         (match_operator:SI 1 "logical_binary_operator"
3165          [(zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
3166                            (match_operand:SI 3 "const_int_operand" "")
3167                            (match_operand:SI 4 "const_int_operand" ""))
3168           (match_operator:SI 9 "logical_binary_operator"
3169            [(lshiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3170                          (match_operand:SI 6 "const_int_operand" ""))
3171             (match_operand:SI 7 "s_register_operand" "")])]))
3172    (clobber (match_operand:SI 8 "s_register_operand" ""))]
3173   "TARGET_32BIT
3174    && GET_CODE (operands[1]) == GET_CODE (operands[9])
3175    && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3176   [(set (match_dup 8)
3177         (match_op_dup 1
3178          [(ashift:SI (match_dup 2) (match_dup 4))
3179           (match_dup 5)]))
3180    (set (match_dup 0)
3181         (match_op_dup 1
3182          [(lshiftrt:SI (match_dup 8) (match_dup 6))
3183           (match_dup 7)]))]
3184   "
3185   operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3188 (define_split
3189   [(set (match_operand:SI 0 "s_register_operand" "")
3190         (match_operator:SI 1 "logical_binary_operator"
3191          [(match_operator:SI 9 "logical_binary_operator"
3192            [(lshiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3193                          (match_operand:SI 6 "const_int_operand" ""))
3194             (match_operand:SI 7 "s_register_operand" "")])
3195           (zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
3196                            (match_operand:SI 3 "const_int_operand" "")
3197                            (match_operand:SI 4 "const_int_operand" ""))]))
3198    (clobber (match_operand:SI 8 "s_register_operand" ""))]
3199   "TARGET_32BIT
3200    && GET_CODE (operands[1]) == GET_CODE (operands[9])
3201    && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3202   [(set (match_dup 8)
3203         (match_op_dup 1
3204          [(ashift:SI (match_dup 2) (match_dup 4))
3205           (match_dup 5)]))
3206    (set (match_dup 0)
3207         (match_op_dup 1
3208          [(lshiftrt:SI (match_dup 8) (match_dup 6))
3209           (match_dup 7)]))]
3210   "
3211   operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3214 (define_split
3215   [(set (match_operand:SI 0 "s_register_operand" "")
3216         (match_operator:SI 1 "logical_binary_operator"
3217          [(sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
3218                            (match_operand:SI 3 "const_int_operand" "")
3219                            (match_operand:SI 4 "const_int_operand" ""))
3220           (match_operator:SI 9 "logical_binary_operator"
3221            [(ashiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3222                          (match_operand:SI 6 "const_int_operand" ""))
3223             (match_operand:SI 7 "s_register_operand" "")])]))
3224    (clobber (match_operand:SI 8 "s_register_operand" ""))]
3225   "TARGET_32BIT
3226    && GET_CODE (operands[1]) == GET_CODE (operands[9])
3227    && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3228   [(set (match_dup 8)
3229         (match_op_dup 1
3230          [(ashift:SI (match_dup 2) (match_dup 4))
3231           (match_dup 5)]))
3232    (set (match_dup 0)
3233         (match_op_dup 1
3234          [(ashiftrt:SI (match_dup 8) (match_dup 6))
3235           (match_dup 7)]))]
3236   "
3237   operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3240 (define_split
3241   [(set (match_operand:SI 0 "s_register_operand" "")
3242         (match_operator:SI 1 "logical_binary_operator"
3243          [(match_operator:SI 9 "logical_binary_operator"
3244            [(ashiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3245                          (match_operand:SI 6 "const_int_operand" ""))
3246             (match_operand:SI 7 "s_register_operand" "")])
3247           (sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
3248                            (match_operand:SI 3 "const_int_operand" "")
3249                            (match_operand:SI 4 "const_int_operand" ""))]))
3250    (clobber (match_operand:SI 8 "s_register_operand" ""))]
3251   "TARGET_32BIT
3252    && GET_CODE (operands[1]) == GET_CODE (operands[9])
3253    && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3254   [(set (match_dup 8)
3255         (match_op_dup 1
3256          [(ashift:SI (match_dup 2) (match_dup 4))
3257           (match_dup 5)]))
3258    (set (match_dup 0)
3259         (match_op_dup 1
3260          [(ashiftrt:SI (match_dup 8) (match_dup 6))
3261           (match_dup 7)]))]
3262   "
3263   operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3267 ;; Minimum and maximum insns
3269 (define_expand "smaxsi3"
3270   [(parallel [
3271     (set (match_operand:SI 0 "s_register_operand" "")
3272          (smax:SI (match_operand:SI 1 "s_register_operand" "")
3273                   (match_operand:SI 2 "arm_rhs_operand" "")))
3274     (clobber (reg:CC CC_REGNUM))])]
3275   "TARGET_32BIT"
3276   "
3277   if (operands[2] == const0_rtx || operands[2] == constm1_rtx)
3278     {
3279       /* No need for a clobber of the condition code register here.  */
3280       emit_insn (gen_rtx_SET (VOIDmode, operands[0],
3281                               gen_rtx_SMAX (SImode, operands[1],
3282                                             operands[2])));
3283       DONE;
3284     }
3287 (define_insn "*smax_0"
3288   [(set (match_operand:SI 0 "s_register_operand" "=r")
3289         (smax:SI (match_operand:SI 1 "s_register_operand" "r")
3290                  (const_int 0)))]
3291   "TARGET_32BIT"
3292   "bic%?\\t%0, %1, %1, asr #31"
3293   [(set_attr "predicable" "yes")
3294    (set_attr "predicable_short_it" "no")
3295    (set_attr "type" "logic_shift_reg")]
3298 (define_insn "*smax_m1"
3299   [(set (match_operand:SI 0 "s_register_operand" "=r")
3300         (smax:SI (match_operand:SI 1 "s_register_operand" "r")
3301                  (const_int -1)))]
3302   "TARGET_32BIT"
3303   "orr%?\\t%0, %1, %1, asr #31"
3304   [(set_attr "predicable" "yes")
3305    (set_attr "predicable_short_it" "no")
3306    (set_attr "type" "logic_shift_reg")]
3309 (define_insn_and_split "*arm_smax_insn"
3310   [(set (match_operand:SI          0 "s_register_operand" "=r,r")
3311         (smax:SI (match_operand:SI 1 "s_register_operand"  "%0,?r")
3312                  (match_operand:SI 2 "arm_rhs_operand"    "rI,rI")))
3313    (clobber (reg:CC CC_REGNUM))]
3314   "TARGET_ARM"
3315   "#"
3316    ; cmp\\t%1, %2\;movlt\\t%0, %2
3317    ; cmp\\t%1, %2\;movge\\t%0, %1\;movlt\\t%0, %2"
3318   "TARGET_ARM"
3319   [(set (reg:CC CC_REGNUM)
3320         (compare:CC (match_dup 1) (match_dup 2)))
3321    (set (match_dup 0)
3322         (if_then_else:SI (ge:SI (reg:CC CC_REGNUM) (const_int 0))
3323                          (match_dup 1)
3324                          (match_dup 2)))]
3325   ""
3326   [(set_attr "conds" "clob")
3327    (set_attr "length" "8,12")
3328    (set_attr "type" "multiple")]
3331 (define_expand "sminsi3"
3332   [(parallel [
3333     (set (match_operand:SI 0 "s_register_operand" "")
3334          (smin:SI (match_operand:SI 1 "s_register_operand" "")
3335                   (match_operand:SI 2 "arm_rhs_operand" "")))
3336     (clobber (reg:CC CC_REGNUM))])]
3337   "TARGET_32BIT"
3338   "
3339   if (operands[2] == const0_rtx)
3340     {
3341       /* No need for a clobber of the condition code register here.  */
3342       emit_insn (gen_rtx_SET (VOIDmode, operands[0],
3343                               gen_rtx_SMIN (SImode, operands[1],
3344                                             operands[2])));
3345       DONE;
3346     }
3349 (define_insn "*smin_0"
3350   [(set (match_operand:SI 0 "s_register_operand" "=r")
3351         (smin:SI (match_operand:SI 1 "s_register_operand" "r")
3352                  (const_int 0)))]
3353   "TARGET_32BIT"
3354   "and%?\\t%0, %1, %1, asr #31"
3355   [(set_attr "predicable" "yes")
3356    (set_attr "predicable_short_it" "no")
3357    (set_attr "type" "logic_shift_reg")]
3360 (define_insn_and_split "*arm_smin_insn"
3361   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3362         (smin:SI (match_operand:SI 1 "s_register_operand" "%0,?r")
3363                  (match_operand:SI 2 "arm_rhs_operand" "rI,rI")))
3364    (clobber (reg:CC CC_REGNUM))]
3365   "TARGET_ARM"
3366   "#"
3367     ; cmp\\t%1, %2\;movge\\t%0, %2
3368     ; cmp\\t%1, %2\;movlt\\t%0, %1\;movge\\t%0, %2"
3369   "TARGET_ARM"
3370   [(set (reg:CC CC_REGNUM)
3371         (compare:CC (match_dup 1) (match_dup 2)))
3372    (set (match_dup 0)
3373         (if_then_else:SI (lt:SI (reg:CC CC_REGNUM) (const_int 0))
3374                          (match_dup 1)
3375                          (match_dup 2)))]
3376   ""
3377   [(set_attr "conds" "clob")
3378    (set_attr "length" "8,12")
3379    (set_attr "type" "multiple,multiple")]
3382 (define_expand "umaxsi3"
3383   [(parallel [
3384     (set (match_operand:SI 0 "s_register_operand" "")
3385          (umax:SI (match_operand:SI 1 "s_register_operand" "")
3386                   (match_operand:SI 2 "arm_rhs_operand" "")))
3387     (clobber (reg:CC CC_REGNUM))])]
3388   "TARGET_32BIT"
3389   ""
3392 (define_insn_and_split "*arm_umaxsi3"
3393   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
3394         (umax:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
3395                  (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
3396    (clobber (reg:CC CC_REGNUM))]
3397   "TARGET_ARM"
3398   "#"
3399     ; cmp\\t%1, %2\;movcc\\t%0, %2
3400     ; cmp\\t%1, %2\;movcs\\t%0, %1
3401     ; cmp\\t%1, %2\;movcs\\t%0, %1\;movcc\\t%0, %2"
3402   "TARGET_ARM"
3403   [(set (reg:CC CC_REGNUM)
3404         (compare:CC (match_dup 1) (match_dup 2)))
3405    (set (match_dup 0)
3406         (if_then_else:SI (geu:SI (reg:CC CC_REGNUM) (const_int 0))
3407                          (match_dup 1)
3408                          (match_dup 2)))]
3409   ""
3410   [(set_attr "conds" "clob")
3411    (set_attr "length" "8,8,12")
3412    (set_attr "type" "store1")]
3415 (define_expand "uminsi3"
3416   [(parallel [
3417     (set (match_operand:SI 0 "s_register_operand" "")
3418          (umin:SI (match_operand:SI 1 "s_register_operand" "")
3419                   (match_operand:SI 2 "arm_rhs_operand" "")))
3420     (clobber (reg:CC CC_REGNUM))])]
3421   "TARGET_32BIT"
3422   ""
3425 (define_insn_and_split "*arm_uminsi3"
3426   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
3427         (umin:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
3428                  (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
3429    (clobber (reg:CC CC_REGNUM))]
3430   "TARGET_ARM"
3431   "#"
3432    ; cmp\\t%1, %2\;movcs\\t%0, %2
3433    ; cmp\\t%1, %2\;movcc\\t%0, %1
3434    ; cmp\\t%1, %2\;movcc\\t%0, %1\;movcs\\t%0, %2"
3435   "TARGET_ARM"
3436   [(set (reg:CC CC_REGNUM)
3437         (compare:CC (match_dup 1) (match_dup 2)))
3438    (set (match_dup 0)
3439         (if_then_else:SI (ltu:SI (reg:CC CC_REGNUM) (const_int 0))
3440                          (match_dup 1)
3441                          (match_dup 2)))]
3442   ""
3443   [(set_attr "conds" "clob")
3444    (set_attr "length" "8,8,12")
3445    (set_attr "type" "store1")]
3448 (define_insn "*store_minmaxsi"
3449   [(set (match_operand:SI 0 "memory_operand" "=m")
3450         (match_operator:SI 3 "minmax_operator"
3451          [(match_operand:SI 1 "s_register_operand" "r")
3452           (match_operand:SI 2 "s_register_operand" "r")]))
3453    (clobber (reg:CC CC_REGNUM))]
3454   "TARGET_32BIT && optimize_function_for_size_p (cfun) && !arm_restrict_it"
3455   "*
3456   operands[3] = gen_rtx_fmt_ee (minmax_code (operands[3]), SImode,
3457                                 operands[1], operands[2]);
3458   output_asm_insn (\"cmp\\t%1, %2\", operands);
3459   if (TARGET_THUMB2)
3460     output_asm_insn (\"ite\t%d3\", operands);
3461   output_asm_insn (\"str%d3\\t%1, %0\", operands);
3462   output_asm_insn (\"str%D3\\t%2, %0\", operands);
3463   return \"\";
3464   "
3465   [(set_attr "conds" "clob")
3466    (set (attr "length")
3467         (if_then_else (eq_attr "is_thumb" "yes")
3468                       (const_int 14)
3469                       (const_int 12)))
3470    (set_attr "type" "store1")]
3473 ; Reject the frame pointer in operand[1], since reloading this after
3474 ; it has been eliminated can cause carnage.
3475 (define_insn "*minmax_arithsi"
3476   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3477         (match_operator:SI 4 "shiftable_operator"
3478          [(match_operator:SI 5 "minmax_operator"
3479            [(match_operand:SI 2 "s_register_operand" "r,r")
3480             (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
3481           (match_operand:SI 1 "s_register_operand" "0,?r")]))
3482    (clobber (reg:CC CC_REGNUM))]
3483   "TARGET_32BIT && !arm_eliminable_register (operands[1]) && !arm_restrict_it"
3484   "*
3485   {
3486     enum rtx_code code = GET_CODE (operands[4]);
3487     bool need_else;
3489     if (which_alternative != 0 || operands[3] != const0_rtx
3490         || (code != PLUS && code != IOR && code != XOR))
3491       need_else = true;
3492     else
3493       need_else = false;
3495     operands[5] = gen_rtx_fmt_ee (minmax_code (operands[5]), SImode,
3496                                   operands[2], operands[3]);
3497     output_asm_insn (\"cmp\\t%2, %3\", operands);
3498     if (TARGET_THUMB2)
3499       {
3500         if (need_else)
3501           output_asm_insn (\"ite\\t%d5\", operands);
3502         else
3503           output_asm_insn (\"it\\t%d5\", operands);
3504       }
3505     output_asm_insn (\"%i4%d5\\t%0, %1, %2\", operands);
3506     if (need_else)
3507       output_asm_insn (\"%i4%D5\\t%0, %1, %3\", operands);
3508     return \"\";
3509   }"
3510   [(set_attr "conds" "clob")
3511    (set (attr "length")
3512         (if_then_else (eq_attr "is_thumb" "yes")
3513                       (const_int 14)
3514                       (const_int 12)))
3515    (set_attr "type" "multiple")]
3518 ; Reject the frame pointer in operand[1], since reloading this after
3519 ; it has been eliminated can cause carnage.
3520 (define_insn_and_split "*minmax_arithsi_non_canon"
3521   [(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts")
3522         (minus:SI
3523          (match_operand:SI 1 "s_register_operand" "0,?Ts")
3524           (match_operator:SI 4 "minmax_operator"
3525            [(match_operand:SI 2 "s_register_operand" "Ts,Ts")
3526             (match_operand:SI 3 "arm_rhs_operand" "TsI,TsI")])))
3527    (clobber (reg:CC CC_REGNUM))]
3528   "TARGET_32BIT && !arm_eliminable_register (operands[1])
3529    && !(arm_restrict_it && CONST_INT_P (operands[3]))"
3530   "#"
3531   "TARGET_32BIT && !arm_eliminable_register (operands[1]) && reload_completed"
3532   [(set (reg:CC CC_REGNUM)
3533         (compare:CC (match_dup 2) (match_dup 3)))
3535    (cond_exec (match_op_dup 4 [(reg:CC CC_REGNUM) (const_int 0)])
3536               (set (match_dup 0)
3537                    (minus:SI (match_dup 1)
3538                              (match_dup 2))))
3539    (cond_exec (match_op_dup 5 [(reg:CC CC_REGNUM) (const_int 0)])
3540               (set (match_dup 0)
3541                    (match_dup 6)))]
3542   {
3543   machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
3544                                            operands[2], operands[3]);
3545   enum rtx_code rc = minmax_code (operands[4]);
3546   operands[4] = gen_rtx_fmt_ee (rc, VOIDmode,
3547                                 operands[2], operands[3]);
3549   if (mode == CCFPmode || mode == CCFPEmode)
3550     rc = reverse_condition_maybe_unordered (rc);
3551   else
3552     rc = reverse_condition (rc);
3553   operands[5] = gen_rtx_fmt_ee (rc, SImode, operands[2], operands[3]);
3554   if (CONST_INT_P (operands[3]))
3555     operands[6] = plus_constant (SImode, operands[1], -INTVAL (operands[3]));
3556   else
3557     operands[6] = gen_rtx_MINUS (SImode, operands[1], operands[3]);
3558   }
3559   [(set_attr "conds" "clob")
3560    (set (attr "length")
3561         (if_then_else (eq_attr "is_thumb" "yes")
3562                       (const_int 14)
3563                       (const_int 12)))
3564    (set_attr "type" "multiple")]
3567 (define_code_iterator SAT [smin smax])
3568 (define_code_iterator SATrev [smin smax])
3569 (define_code_attr SATlo [(smin "1") (smax "2")])
3570 (define_code_attr SAThi [(smin "2") (smax "1")])
3572 (define_insn "*satsi_<SAT:code>"
3573   [(set (match_operand:SI 0 "s_register_operand" "=r")
3574         (SAT:SI (SATrev:SI (match_operand:SI 3 "s_register_operand" "r")
3575                            (match_operand:SI 1 "const_int_operand" "i"))
3576                 (match_operand:SI 2 "const_int_operand" "i")))]
3577   "TARGET_32BIT && arm_arch6 && <SAT:CODE> != <SATrev:CODE>
3578    && arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>], NULL, NULL)"
3580   int mask;
3581   bool signed_sat;
3582   if (!arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>],
3583                                &mask, &signed_sat))
3584     gcc_unreachable ();
3586   operands[1] = GEN_INT (mask);
3587   if (signed_sat)
3588     return "ssat%?\t%0, %1, %3";
3589   else
3590     return "usat%?\t%0, %1, %3";
3592   [(set_attr "predicable" "yes")
3593    (set_attr "predicable_short_it" "no")
3594    (set_attr "type" "alus_imm")]
3597 (define_insn "*satsi_<SAT:code>_shift"
3598   [(set (match_operand:SI 0 "s_register_operand" "=r")
3599         (SAT:SI (SATrev:SI (match_operator:SI 3 "sat_shift_operator"
3600                              [(match_operand:SI 4 "s_register_operand" "r")
3601                               (match_operand:SI 5 "const_int_operand" "i")])
3602                            (match_operand:SI 1 "const_int_operand" "i"))
3603                 (match_operand:SI 2 "const_int_operand" "i")))]
3604   "TARGET_32BIT && arm_arch6 && <SAT:CODE> != <SATrev:CODE>
3605    && arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>], NULL, NULL)"
3607   int mask;
3608   bool signed_sat;
3609   if (!arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>],
3610                                &mask, &signed_sat))
3611     gcc_unreachable ();
3613   operands[1] = GEN_INT (mask);
3614   if (signed_sat)
3615     return "ssat%?\t%0, %1, %4%S3";
3616   else
3617     return "usat%?\t%0, %1, %4%S3";
3619   [(set_attr "predicable" "yes")
3620    (set_attr "predicable_short_it" "no")
3621    (set_attr "shift" "3")
3622    (set_attr "type" "logic_shift_reg")])
3624 ;; Shift and rotation insns
3626 (define_expand "ashldi3"
3627   [(set (match_operand:DI            0 "s_register_operand" "")
3628         (ashift:DI (match_operand:DI 1 "s_register_operand" "")
3629                    (match_operand:SI 2 "general_operand" "")))]
3630   "TARGET_32BIT"
3631   "
3632   if (TARGET_NEON)
3633     {
3634       /* Delay the decision whether to use NEON or core-regs until
3635          register allocation.  */
3636       emit_insn (gen_ashldi3_neon (operands[0], operands[1], operands[2]));
3637       DONE;
3638     }
3639   else
3640     {
3641       /* Only the NEON case can handle in-memory shift counts.  */
3642       if (!reg_or_int_operand (operands[2], SImode))
3643         operands[2] = force_reg (SImode, operands[2]);
3644     }
3646   if (!CONST_INT_P (operands[2]) && TARGET_REALLY_IWMMXT)
3647     ; /* No special preparation statements; expand pattern as above.  */
3648   else
3649     {
3650       rtx scratch1, scratch2;
3652       if (CONST_INT_P (operands[2])
3653           && (HOST_WIDE_INT) INTVAL (operands[2]) == 1)
3654         {
3655           emit_insn (gen_arm_ashldi3_1bit (operands[0], operands[1]));
3656           DONE;
3657         }
3659       /* Ideally we should use iwmmxt here if we could know that operands[1]
3660          ends up already living in an iwmmxt register. Otherwise it's
3661          cheaper to have the alternate code being generated than moving
3662          values to iwmmxt regs and back.  */
3664       /* If we're optimizing for size, we prefer the libgcc calls.  */
3665       if (optimize_function_for_size_p (cfun))
3666         FAIL;
3668       /* Expand operation using core-registers.
3669          'FAIL' would achieve the same thing, but this is a bit smarter.  */
3670       scratch1 = gen_reg_rtx (SImode);
3671       scratch2 = gen_reg_rtx (SImode);
3672       arm_emit_coreregs_64bit_shift (ASHIFT, operands[0], operands[1],
3673                                      operands[2], scratch1, scratch2);
3674       DONE;
3675     }
3676   "
3679 (define_insn "arm_ashldi3_1bit"
3680   [(set (match_operand:DI            0 "s_register_operand" "=r,&r")
3681         (ashift:DI (match_operand:DI 1 "s_register_operand" "0,r")
3682                    (const_int 1)))
3683    (clobber (reg:CC CC_REGNUM))]
3684   "TARGET_32BIT"
3685   "movs\\t%Q0, %Q1, asl #1\;adc\\t%R0, %R1, %R1"
3686   [(set_attr "conds" "clob")
3687    (set_attr "length" "8")
3688    (set_attr "type" "multiple")]
3691 (define_expand "ashlsi3"
3692   [(set (match_operand:SI            0 "s_register_operand" "")
3693         (ashift:SI (match_operand:SI 1 "s_register_operand" "")
3694                    (match_operand:SI 2 "arm_rhs_operand" "")))]
3695   "TARGET_EITHER"
3696   "
3697   if (CONST_INT_P (operands[2])
3698       && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) > 31)
3699     {
3700       emit_insn (gen_movsi (operands[0], const0_rtx));
3701       DONE;
3702     }
3703   "
3706 (define_expand "ashrdi3"
3707   [(set (match_operand:DI              0 "s_register_operand" "")
3708         (ashiftrt:DI (match_operand:DI 1 "s_register_operand" "")
3709                      (match_operand:SI 2 "reg_or_int_operand" "")))]
3710   "TARGET_32BIT"
3711   "
3712   if (TARGET_NEON)
3713     {
3714       /* Delay the decision whether to use NEON or core-regs until
3715          register allocation.  */
3716       emit_insn (gen_ashrdi3_neon (operands[0], operands[1], operands[2]));
3717       DONE;
3718     }
3720   if (!CONST_INT_P (operands[2]) && TARGET_REALLY_IWMMXT)
3721     ; /* No special preparation statements; expand pattern as above.  */
3722   else
3723     {
3724       rtx scratch1, scratch2;
3726       if (CONST_INT_P (operands[2])
3727           && (HOST_WIDE_INT) INTVAL (operands[2]) == 1)
3728         {
3729           emit_insn (gen_arm_ashrdi3_1bit (operands[0], operands[1]));
3730           DONE;
3731         }
3733       /* Ideally we should use iwmmxt here if we could know that operands[1]
3734          ends up already living in an iwmmxt register. Otherwise it's
3735          cheaper to have the alternate code being generated than moving
3736          values to iwmmxt regs and back.  */
3738       /* If we're optimizing for size, we prefer the libgcc calls.  */
3739       if (optimize_function_for_size_p (cfun))
3740         FAIL;
3742       /* Expand operation using core-registers.
3743          'FAIL' would achieve the same thing, but this is a bit smarter.  */
3744       scratch1 = gen_reg_rtx (SImode);
3745       scratch2 = gen_reg_rtx (SImode);
3746       arm_emit_coreregs_64bit_shift (ASHIFTRT, operands[0], operands[1],
3747                                      operands[2], scratch1, scratch2);
3748       DONE;
3749     }
3750   "
3753 (define_insn "arm_ashrdi3_1bit"
3754   [(set (match_operand:DI              0 "s_register_operand" "=r,&r")
3755         (ashiftrt:DI (match_operand:DI 1 "s_register_operand" "0,r")
3756                      (const_int 1)))
3757    (clobber (reg:CC CC_REGNUM))]
3758   "TARGET_32BIT"
3759   "movs\\t%R0, %R1, asr #1\;mov\\t%Q0, %Q1, rrx"
3760   [(set_attr "conds" "clob")
3761    (set_attr "length" "8")
3762    (set_attr "type" "multiple")]
3765 (define_expand "ashrsi3"
3766   [(set (match_operand:SI              0 "s_register_operand" "")
3767         (ashiftrt:SI (match_operand:SI 1 "s_register_operand" "")
3768                      (match_operand:SI 2 "arm_rhs_operand" "")))]
3769   "TARGET_EITHER"
3770   "
3771   if (CONST_INT_P (operands[2])
3772       && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) > 31)
3773     operands[2] = GEN_INT (31);
3774   "
3777 (define_expand "lshrdi3"
3778   [(set (match_operand:DI              0 "s_register_operand" "")
3779         (lshiftrt:DI (match_operand:DI 1 "s_register_operand" "")
3780                      (match_operand:SI 2 "reg_or_int_operand" "")))]
3781   "TARGET_32BIT"
3782   "
3783   if (TARGET_NEON)
3784     {
3785       /* Delay the decision whether to use NEON or core-regs until
3786          register allocation.  */
3787       emit_insn (gen_lshrdi3_neon (operands[0], operands[1], operands[2]));
3788       DONE;
3789     }
3791   if (!CONST_INT_P (operands[2]) && TARGET_REALLY_IWMMXT)
3792     ; /* No special preparation statements; expand pattern as above.  */
3793   else
3794     {
3795       rtx scratch1, scratch2;
3797       if (CONST_INT_P (operands[2])
3798           && (HOST_WIDE_INT) INTVAL (operands[2]) == 1)
3799         {
3800           emit_insn (gen_arm_lshrdi3_1bit (operands[0], operands[1]));
3801           DONE;
3802         }
3804       /* Ideally we should use iwmmxt here if we could know that operands[1]
3805          ends up already living in an iwmmxt register. Otherwise it's
3806          cheaper to have the alternate code being generated than moving
3807          values to iwmmxt regs and back.  */
3809       /* If we're optimizing for size, we prefer the libgcc calls.  */
3810       if (optimize_function_for_size_p (cfun))
3811         FAIL;
3813       /* Expand operation using core-registers.
3814          'FAIL' would achieve the same thing, but this is a bit smarter.  */
3815       scratch1 = gen_reg_rtx (SImode);
3816       scratch2 = gen_reg_rtx (SImode);
3817       arm_emit_coreregs_64bit_shift (LSHIFTRT, operands[0], operands[1],
3818                                      operands[2], scratch1, scratch2);
3819       DONE;
3820     }
3821   "
3824 (define_insn "arm_lshrdi3_1bit"
3825   [(set (match_operand:DI              0 "s_register_operand" "=r,&r")
3826         (lshiftrt:DI (match_operand:DI 1 "s_register_operand" "0,r")
3827                      (const_int 1)))
3828    (clobber (reg:CC CC_REGNUM))]
3829   "TARGET_32BIT"
3830   "movs\\t%R0, %R1, lsr #1\;mov\\t%Q0, %Q1, rrx"
3831   [(set_attr "conds" "clob")
3832    (set_attr "length" "8")
3833    (set_attr "type" "multiple")]
3836 (define_expand "lshrsi3"
3837   [(set (match_operand:SI              0 "s_register_operand" "")
3838         (lshiftrt:SI (match_operand:SI 1 "s_register_operand" "")
3839                      (match_operand:SI 2 "arm_rhs_operand" "")))]
3840   "TARGET_EITHER"
3841   "
3842   if (CONST_INT_P (operands[2])
3843       && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) > 31)
3844     {
3845       emit_insn (gen_movsi (operands[0], const0_rtx));
3846       DONE;
3847     }
3848   "
3851 (define_expand "rotlsi3"
3852   [(set (match_operand:SI              0 "s_register_operand" "")
3853         (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
3854                      (match_operand:SI 2 "reg_or_int_operand" "")))]
3855   "TARGET_32BIT"
3856   "
3857   if (CONST_INT_P (operands[2]))
3858     operands[2] = GEN_INT ((32 - INTVAL (operands[2])) % 32);
3859   else
3860     {
3861       rtx reg = gen_reg_rtx (SImode);
3862       emit_insn (gen_subsi3 (reg, GEN_INT (32), operands[2]));
3863       operands[2] = reg;
3864     }
3865   "
3868 (define_expand "rotrsi3"
3869   [(set (match_operand:SI              0 "s_register_operand" "")
3870         (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
3871                      (match_operand:SI 2 "arm_rhs_operand" "")))]
3872   "TARGET_EITHER"
3873   "
3874   if (TARGET_32BIT)
3875     {
3876       if (CONST_INT_P (operands[2])
3877           && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) > 31)
3878         operands[2] = GEN_INT (INTVAL (operands[2]) % 32);
3879     }
3880   else /* TARGET_THUMB1 */
3881     {
3882       if (CONST_INT_P (operands [2]))
3883         operands [2] = force_reg (SImode, operands[2]);
3884     }
3885   "
3888 (define_insn "*arm_shiftsi3"
3889   [(set (match_operand:SI   0 "s_register_operand" "=l,l,r,r")
3890         (match_operator:SI  3 "shift_operator"
3891          [(match_operand:SI 1 "s_register_operand"  "0,l,r,r")
3892           (match_operand:SI 2 "reg_or_int_operand" "l,M,M,r")]))]
3893   "TARGET_32BIT"
3894   "* return arm_output_shift(operands, 0);"
3895   [(set_attr "predicable" "yes")
3896    (set_attr "arch" "t2,t2,*,*")
3897    (set_attr "predicable_short_it" "yes,yes,no,no")
3898    (set_attr "length" "4")
3899    (set_attr "shift" "1")
3900    (set_attr "type" "alu_shift_reg,alu_shift_imm,alu_shift_imm,alu_shift_reg")]
3903 (define_insn "*shiftsi3_compare0"
3904   [(set (reg:CC_NOOV CC_REGNUM)
3905         (compare:CC_NOOV (match_operator:SI 3 "shift_operator"
3906                           [(match_operand:SI 1 "s_register_operand" "r,r")
3907                            (match_operand:SI 2 "arm_rhs_operand" "M,r")])
3908                          (const_int 0)))
3909    (set (match_operand:SI 0 "s_register_operand" "=r,r")
3910         (match_op_dup 3 [(match_dup 1) (match_dup 2)]))]
3911   "TARGET_32BIT"
3912   "* return arm_output_shift(operands, 1);"
3913   [(set_attr "conds" "set")
3914    (set_attr "shift" "1")
3915    (set_attr "type" "alus_shift_imm,alus_shift_reg")]
3918 (define_insn "*shiftsi3_compare0_scratch"
3919   [(set (reg:CC_NOOV CC_REGNUM)
3920         (compare:CC_NOOV (match_operator:SI 3 "shift_operator"
3921                           [(match_operand:SI 1 "s_register_operand" "r,r")
3922                            (match_operand:SI 2 "arm_rhs_operand" "M,r")])
3923                          (const_int 0)))
3924    (clobber (match_scratch:SI 0 "=r,r"))]
3925   "TARGET_32BIT"
3926   "* return arm_output_shift(operands, 1);"
3927   [(set_attr "conds" "set")
3928    (set_attr "shift" "1")
3929    (set_attr "type" "shift_imm,shift_reg")]
3932 (define_insn "*not_shiftsi"
3933   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3934         (not:SI (match_operator:SI 3 "shift_operator"
3935                  [(match_operand:SI 1 "s_register_operand" "r,r")
3936                   (match_operand:SI 2 "shift_amount_operand" "M,rM")])))]
3937   "TARGET_32BIT"
3938   "mvn%?\\t%0, %1%S3"
3939   [(set_attr "predicable" "yes")
3940    (set_attr "predicable_short_it" "no")
3941    (set_attr "shift" "1")
3942    (set_attr "arch" "32,a")
3943    (set_attr "type" "mvn_shift,mvn_shift_reg")])
3945 (define_insn "*not_shiftsi_compare0"
3946   [(set (reg:CC_NOOV CC_REGNUM)
3947         (compare:CC_NOOV
3948          (not:SI (match_operator:SI 3 "shift_operator"
3949                   [(match_operand:SI 1 "s_register_operand" "r,r")
3950                    (match_operand:SI 2 "shift_amount_operand" "M,rM")]))
3951          (const_int 0)))
3952    (set (match_operand:SI 0 "s_register_operand" "=r,r")
3953         (not:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])))]
3954   "TARGET_32BIT"
3955   "mvn%.\\t%0, %1%S3"
3956   [(set_attr "conds" "set")
3957    (set_attr "shift" "1")
3958    (set_attr "arch" "32,a")
3959    (set_attr "type" "mvn_shift,mvn_shift_reg")])
3961 (define_insn "*not_shiftsi_compare0_scratch"
3962   [(set (reg:CC_NOOV CC_REGNUM)
3963         (compare:CC_NOOV
3964          (not:SI (match_operator:SI 3 "shift_operator"
3965                   [(match_operand:SI 1 "s_register_operand" "r,r")
3966                    (match_operand:SI 2 "shift_amount_operand" "M,rM")]))
3967          (const_int 0)))
3968    (clobber (match_scratch:SI 0 "=r,r"))]
3969   "TARGET_32BIT"
3970   "mvn%.\\t%0, %1%S3"
3971   [(set_attr "conds" "set")
3972    (set_attr "shift" "1")
3973    (set_attr "arch" "32,a")
3974    (set_attr "type" "mvn_shift,mvn_shift_reg")])
3976 ;; We don't really have extzv, but defining this using shifts helps
3977 ;; to reduce register pressure later on.
3979 (define_expand "extzv"
3980   [(set (match_operand 0 "s_register_operand" "")
3981         (zero_extract (match_operand 1 "nonimmediate_operand" "")
3982                       (match_operand 2 "const_int_operand" "")
3983                       (match_operand 3 "const_int_operand" "")))]
3984   "TARGET_THUMB1 || arm_arch_thumb2"
3985   "
3986   {
3987     HOST_WIDE_INT lshift = 32 - INTVAL (operands[2]) - INTVAL (operands[3]);
3988     HOST_WIDE_INT rshift = 32 - INTVAL (operands[2]);
3989     
3990     if (arm_arch_thumb2)
3991       {
3992         HOST_WIDE_INT width = INTVAL (operands[2]);
3993         HOST_WIDE_INT bitpos = INTVAL (operands[3]);
3995         if (unaligned_access && MEM_P (operands[1])
3996             && (width == 16 || width == 32) && (bitpos % BITS_PER_UNIT) == 0)
3997           {
3998             rtx base_addr;
4000             if (BYTES_BIG_ENDIAN)
4001               bitpos = GET_MODE_BITSIZE (GET_MODE (operands[0])) - width
4002                        - bitpos;
4004             if (width == 32)
4005               {
4006                 base_addr = adjust_address (operands[1], SImode,
4007                                             bitpos / BITS_PER_UNIT);
4008                 emit_insn (gen_unaligned_loadsi (operands[0], base_addr));
4009               }
4010             else
4011               {
4012                 rtx dest = operands[0];
4013                 rtx tmp = gen_reg_rtx (SImode);
4015                 /* We may get a paradoxical subreg here.  Strip it off.  */
4016                 if (GET_CODE (dest) == SUBREG
4017                     && GET_MODE (dest) == SImode
4018                     && GET_MODE (SUBREG_REG (dest)) == HImode)
4019                   dest = SUBREG_REG (dest);
4021                 if (GET_MODE_BITSIZE (GET_MODE (dest)) != width)
4022                   FAIL;
4024                 base_addr = adjust_address (operands[1], HImode,
4025                                             bitpos / BITS_PER_UNIT);
4026                 emit_insn (gen_unaligned_loadhiu (tmp, base_addr));
4027                 emit_move_insn (gen_lowpart (SImode, dest), tmp);
4028               }
4029             DONE;
4030           }
4031         else if (s_register_operand (operands[1], GET_MODE (operands[1])))
4032           {
4033             emit_insn (gen_extzv_t2 (operands[0], operands[1], operands[2],
4034                                      operands[3]));
4035             DONE;
4036           }
4037         else
4038           FAIL;
4039       }
4040     
4041     if (!s_register_operand (operands[1], GET_MODE (operands[1])))
4042       FAIL;
4044     operands[3] = GEN_INT (rshift);
4045     
4046     if (lshift == 0)
4047       {
4048         emit_insn (gen_lshrsi3 (operands[0], operands[1], operands[3]));
4049         DONE;
4050       }
4051       
4052     emit_insn (gen_extzv_t1 (operands[0], operands[1], GEN_INT (lshift),
4053                              operands[3], gen_reg_rtx (SImode)));
4054     DONE;
4055   }"
4058 ;; Helper for extzv, for the Thumb-1 register-shifts case.
4060 (define_expand "extzv_t1"
4061   [(set (match_operand:SI 4 "s_register_operand" "")
4062         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
4063                    (match_operand:SI 2 "const_int_operand" "")))
4064    (set (match_operand:SI 0 "s_register_operand" "")
4065         (lshiftrt:SI (match_dup 4)
4066                      (match_operand:SI 3 "const_int_operand" "")))]
4067   "TARGET_THUMB1"
4068   "")
4070 (define_expand "extv"
4071   [(set (match_operand 0 "s_register_operand" "")
4072         (sign_extract (match_operand 1 "nonimmediate_operand" "")
4073                       (match_operand 2 "const_int_operand" "")
4074                       (match_operand 3 "const_int_operand" "")))]
4075   "arm_arch_thumb2"
4077   HOST_WIDE_INT width = INTVAL (operands[2]);
4078   HOST_WIDE_INT bitpos = INTVAL (operands[3]);
4080   if (unaligned_access && MEM_P (operands[1]) && (width == 16 || width == 32)
4081       && (bitpos % BITS_PER_UNIT)  == 0)
4082     {
4083       rtx base_addr;
4084       
4085       if (BYTES_BIG_ENDIAN)
4086         bitpos = GET_MODE_BITSIZE (GET_MODE (operands[0])) - width - bitpos;
4087       
4088       if (width == 32)
4089         {
4090           base_addr = adjust_address (operands[1], SImode,
4091                                       bitpos / BITS_PER_UNIT);
4092           emit_insn (gen_unaligned_loadsi (operands[0], base_addr));
4093         }
4094       else
4095         {
4096           rtx dest = operands[0];
4097           rtx tmp = gen_reg_rtx (SImode);
4098           
4099           /* We may get a paradoxical subreg here.  Strip it off.  */
4100           if (GET_CODE (dest) == SUBREG
4101               && GET_MODE (dest) == SImode
4102               && GET_MODE (SUBREG_REG (dest)) == HImode)
4103             dest = SUBREG_REG (dest);
4104           
4105           if (GET_MODE_BITSIZE (GET_MODE (dest)) != width)
4106             FAIL;
4107           
4108           base_addr = adjust_address (operands[1], HImode,
4109                                       bitpos / BITS_PER_UNIT);
4110           emit_insn (gen_unaligned_loadhis (tmp, base_addr));
4111           emit_move_insn (gen_lowpart (SImode, dest), tmp);
4112         }
4114       DONE;
4115     }
4116   else if (!s_register_operand (operands[1], GET_MODE (operands[1])))
4117     FAIL;
4118   else if (GET_MODE (operands[0]) == SImode
4119            && GET_MODE (operands[1]) == SImode)
4120     {
4121       emit_insn (gen_extv_regsi (operands[0], operands[1], operands[2],
4122                                  operands[3]));
4123       DONE;
4124     }
4126   FAIL;
4129 ; Helper to expand register forms of extv with the proper modes.
4131 (define_expand "extv_regsi"
4132   [(set (match_operand:SI 0 "s_register_operand" "")
4133         (sign_extract:SI (match_operand:SI 1 "s_register_operand" "")
4134                          (match_operand 2 "const_int_operand" "")
4135                          (match_operand 3 "const_int_operand" "")))]
4136   ""
4140 ; ARMv6+ unaligned load/store instructions (used for packed structure accesses).
4142 (define_insn "unaligned_loadsi"
4143   [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4144         (unspec:SI [(match_operand:SI 1 "memory_operand" "Uw,m")]
4145                    UNSPEC_UNALIGNED_LOAD))]
4146   "unaligned_access && TARGET_32BIT"
4147   "ldr%?\t%0, %1\t@ unaligned"
4148   [(set_attr "arch" "t2,any")
4149    (set_attr "length" "2,4")
4150    (set_attr "predicable" "yes")
4151    (set_attr "predicable_short_it" "yes,no")
4152    (set_attr "type" "load1")])
4154 (define_insn "unaligned_loadhis"
4155   [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4156         (sign_extend:SI
4157           (unspec:HI [(match_operand:HI 1 "memory_operand" "Uw,Uh")]
4158                      UNSPEC_UNALIGNED_LOAD)))]
4159   "unaligned_access && TARGET_32BIT"
4160   "ldr%(sh%)\t%0, %1\t@ unaligned"
4161   [(set_attr "arch" "t2,any")
4162    (set_attr "length" "2,4")
4163    (set_attr "predicable" "yes")
4164    (set_attr "predicable_short_it" "yes,no")
4165    (set_attr "type" "load_byte")])
4167 (define_insn "unaligned_loadhiu"
4168   [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4169         (zero_extend:SI
4170           (unspec:HI [(match_operand:HI 1 "memory_operand" "Uw,m")]
4171                      UNSPEC_UNALIGNED_LOAD)))]
4172   "unaligned_access && TARGET_32BIT"
4173   "ldr%(h%)\t%0, %1\t@ unaligned"
4174   [(set_attr "arch" "t2,any")
4175    (set_attr "length" "2,4")
4176    (set_attr "predicable" "yes")
4177    (set_attr "predicable_short_it" "yes,no")
4178    (set_attr "type" "load_byte")])
4180 (define_insn "unaligned_storesi"
4181   [(set (match_operand:SI 0 "memory_operand" "=Uw,m")
4182         (unspec:SI [(match_operand:SI 1 "s_register_operand" "l,r")]
4183                    UNSPEC_UNALIGNED_STORE))]
4184   "unaligned_access && TARGET_32BIT"
4185   "str%?\t%1, %0\t@ unaligned"
4186   [(set_attr "arch" "t2,any")
4187    (set_attr "length" "2,4")
4188    (set_attr "predicable" "yes")
4189    (set_attr "predicable_short_it" "yes,no")
4190    (set_attr "type" "store1")])
4192 (define_insn "unaligned_storehi"
4193   [(set (match_operand:HI 0 "memory_operand" "=Uw,m")
4194         (unspec:HI [(match_operand:HI 1 "s_register_operand" "l,r")]
4195                    UNSPEC_UNALIGNED_STORE))]
4196   "unaligned_access && TARGET_32BIT"
4197   "str%(h%)\t%1, %0\t@ unaligned"
4198   [(set_attr "arch" "t2,any")
4199    (set_attr "length" "2,4")
4200    (set_attr "predicable" "yes")
4201    (set_attr "predicable_short_it" "yes,no")
4202    (set_attr "type" "store1")])
4204 ;; Unaligned double-word load and store.
4205 ;; Split after reload into two unaligned single-word accesses.
4206 ;; It prevents lower_subreg from splitting some other aligned
4207 ;; double-word accesses too early. Used for internal memcpy.
4209 (define_insn_and_split "unaligned_loaddi"
4210   [(set (match_operand:DI 0 "s_register_operand" "=l,r")
4211         (unspec:DI [(match_operand:DI 1 "memory_operand" "o,o")]
4212                    UNSPEC_UNALIGNED_LOAD))]
4213   "unaligned_access && TARGET_32BIT"
4214   "#"
4215   "&& reload_completed"
4216   [(set (match_dup 0) (unspec:SI [(match_dup 1)] UNSPEC_UNALIGNED_LOAD))
4217    (set (match_dup 2) (unspec:SI [(match_dup 3)] UNSPEC_UNALIGNED_LOAD))]
4218   {
4219     operands[2] = gen_highpart (SImode, operands[0]);
4220     operands[0] = gen_lowpart (SImode, operands[0]);
4221     operands[3] = gen_highpart (SImode, operands[1]);
4222     operands[1] = gen_lowpart (SImode, operands[1]);
4224     /* If the first destination register overlaps with the base address,
4225        swap the order in which the loads are emitted.  */
4226     if (reg_overlap_mentioned_p (operands[0], operands[1]))
4227       {
4228         std::swap (operands[1], operands[3]);
4229         std::swap (operands[0], operands[2]);
4230       }
4231   }
4232   [(set_attr "arch" "t2,any")
4233    (set_attr "length" "4,8")
4234    (set_attr "predicable" "yes")
4235    (set_attr "type" "load2")])
4237 (define_insn_and_split "unaligned_storedi"
4238   [(set (match_operand:DI 0 "memory_operand" "=o,o")
4239         (unspec:DI [(match_operand:DI 1 "s_register_operand" "l,r")]
4240                    UNSPEC_UNALIGNED_STORE))]
4241   "unaligned_access && TARGET_32BIT"
4242   "#"
4243   "&& reload_completed"
4244   [(set (match_dup 0) (unspec:SI [(match_dup 1)] UNSPEC_UNALIGNED_STORE))
4245    (set (match_dup 2) (unspec:SI [(match_dup 3)] UNSPEC_UNALIGNED_STORE))]
4246   {
4247     operands[2] = gen_highpart (SImode, operands[0]);
4248     operands[0] = gen_lowpart (SImode, operands[0]);
4249     operands[3] = gen_highpart (SImode, operands[1]);
4250     operands[1] = gen_lowpart (SImode, operands[1]);
4251   }
4252   [(set_attr "arch" "t2,any")
4253    (set_attr "length" "4,8")
4254    (set_attr "predicable" "yes")
4255    (set_attr "type" "store2")])
4258 (define_insn "*extv_reg"
4259   [(set (match_operand:SI 0 "s_register_operand" "=r")
4260         (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
4261                          (match_operand:SI 2 "const_int_M_operand" "M")
4262                          (match_operand:SI 3 "const_int_M_operand" "M")))]
4263   "arm_arch_thumb2"
4264   "sbfx%?\t%0, %1, %3, %2"
4265   [(set_attr "length" "4")
4266    (set_attr "predicable" "yes")
4267    (set_attr "predicable_short_it" "no")
4268    (set_attr "type" "bfm")]
4271 (define_insn "extzv_t2"
4272   [(set (match_operand:SI 0 "s_register_operand" "=r")
4273         (zero_extract:SI (match_operand:SI 1 "s_register_operand" "r")
4274                          (match_operand:SI 2 "const_int_M_operand" "M")
4275                          (match_operand:SI 3 "const_int_M_operand" "M")))]
4276   "arm_arch_thumb2"
4277   "ubfx%?\t%0, %1, %3, %2"
4278   [(set_attr "length" "4")
4279    (set_attr "predicable" "yes")
4280    (set_attr "predicable_short_it" "no")
4281    (set_attr "type" "bfm")]
4285 ;; Division instructions
4286 (define_insn "divsi3"
4287   [(set (match_operand:SI         0 "s_register_operand" "=r")
4288         (div:SI (match_operand:SI 1 "s_register_operand"  "r")
4289                 (match_operand:SI 2 "s_register_operand"  "r")))]
4290   "TARGET_IDIV"
4291   "sdiv%?\t%0, %1, %2"
4292   [(set_attr "predicable" "yes")
4293    (set_attr "predicable_short_it" "no")
4294    (set_attr "type" "sdiv")]
4297 (define_insn "udivsi3"
4298   [(set (match_operand:SI          0 "s_register_operand" "=r")
4299         (udiv:SI (match_operand:SI 1 "s_register_operand"  "r")
4300                  (match_operand:SI 2 "s_register_operand"  "r")))]
4301   "TARGET_IDIV"
4302   "udiv%?\t%0, %1, %2"
4303   [(set_attr "predicable" "yes")
4304    (set_attr "predicable_short_it" "no")
4305    (set_attr "type" "udiv")]
4309 ;; Unary arithmetic insns
4311 (define_expand "negdi2"
4312  [(parallel
4313    [(set (match_operand:DI 0 "s_register_operand" "")
4314          (neg:DI (match_operand:DI 1 "s_register_operand" "")))
4315     (clobber (reg:CC CC_REGNUM))])]
4316   "TARGET_EITHER"
4317   {
4318     if (TARGET_NEON)
4319       {
4320         emit_insn (gen_negdi2_neon (operands[0], operands[1]));
4321         DONE;
4322       }
4323   }
4326 ;; The constraints here are to prevent a *partial* overlap (where %Q0 == %R1).
4327 ;; The first alternative allows the common case of a *full* overlap.
4328 (define_insn_and_split "*arm_negdi2"
4329   [(set (match_operand:DI         0 "s_register_operand" "=r,&r")
4330         (neg:DI (match_operand:DI 1 "s_register_operand"  "0,r")))
4331    (clobber (reg:CC CC_REGNUM))]
4332   "TARGET_ARM"
4333   "#"   ; "rsbs\\t%Q0, %Q1, #0\;rsc\\t%R0, %R1, #0"
4334   "&& reload_completed"
4335   [(parallel [(set (reg:CC CC_REGNUM)
4336                    (compare:CC (const_int 0) (match_dup 1)))
4337               (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1)))])
4338    (set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3))
4339                                 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
4340   {
4341     operands[2] = gen_highpart (SImode, operands[0]);
4342     operands[0] = gen_lowpart (SImode, operands[0]);
4343     operands[3] = gen_highpart (SImode, operands[1]);
4344     operands[1] = gen_lowpart (SImode, operands[1]);
4345   }
4346   [(set_attr "conds" "clob")
4347    (set_attr "length" "8")
4348    (set_attr "type" "multiple")]
4351 (define_expand "negsi2"
4352   [(set (match_operand:SI         0 "s_register_operand" "")
4353         (neg:SI (match_operand:SI 1 "s_register_operand" "")))]
4354   "TARGET_EITHER"
4355   ""
4358 (define_insn "*arm_negsi2"
4359   [(set (match_operand:SI         0 "s_register_operand" "=l,r")
4360         (neg:SI (match_operand:SI 1 "s_register_operand" "l,r")))]
4361   "TARGET_32BIT"
4362   "rsb%?\\t%0, %1, #0"
4363   [(set_attr "predicable" "yes")
4364    (set_attr "predicable_short_it" "yes,no")
4365    (set_attr "arch" "t2,*")
4366    (set_attr "length" "4")
4367    (set_attr "type" "alu_sreg")]
4370 (define_expand "negsf2"
4371   [(set (match_operand:SF         0 "s_register_operand" "")
4372         (neg:SF (match_operand:SF 1 "s_register_operand" "")))]
4373   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
4374   ""
4377 (define_expand "negdf2"
4378   [(set (match_operand:DF         0 "s_register_operand" "")
4379         (neg:DF (match_operand:DF 1 "s_register_operand" "")))]
4380   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
4381   "")
4383 (define_insn_and_split "*zextendsidi_negsi"
4384   [(set (match_operand:DI 0 "s_register_operand" "=r")
4385         (zero_extend:DI (neg:SI (match_operand:SI 1 "s_register_operand" "r"))))]
4386    "TARGET_32BIT"
4387    "#"
4388    ""
4389    [(set (match_dup 2)
4390          (neg:SI (match_dup 1)))
4391     (set (match_dup 3)
4392          (const_int 0))]
4393    {
4394       operands[2] = gen_lowpart (SImode, operands[0]);
4395       operands[3] = gen_highpart (SImode, operands[0]);
4396    }
4397  [(set_attr "length" "8")
4398   (set_attr "type" "multiple")]
4401 ;; Negate an extended 32-bit value.
4402 (define_insn_and_split "*negdi_extendsidi"
4403   [(set (match_operand:DI 0 "s_register_operand" "=l,r")
4404         (neg:DI (sign_extend:DI
4405                  (match_operand:SI 1 "s_register_operand" "l,r"))))
4406    (clobber (reg:CC CC_REGNUM))]
4407   "TARGET_32BIT"
4408   "#"
4409   "&& reload_completed"
4410   [(const_int 0)]
4411   {
4412     rtx low = gen_lowpart (SImode, operands[0]);
4413     rtx high = gen_highpart (SImode, operands[0]);
4415     if (reg_overlap_mentioned_p (low, operands[1]))
4416       {
4417         /* Input overlaps the low word of the output.  Use:
4418                 asr     Rhi, Rin, #31
4419                 rsbs    Rlo, Rin, #0
4420                 rsc     Rhi, Rhi, #0 (thumb2: sbc Rhi, Rhi, Rhi, lsl #1).  */
4421         rtx cc_reg = gen_rtx_REG (CC_Cmode, CC_REGNUM);
4423         emit_insn (gen_rtx_SET (VOIDmode, high,
4424                                 gen_rtx_ASHIFTRT (SImode, operands[1],
4425                                                   GEN_INT (31))));
4427         emit_insn (gen_subsi3_compare (low, const0_rtx, operands[1]));
4428         if (TARGET_ARM)
4429           emit_insn (gen_rtx_SET (VOIDmode, high,
4430                                   gen_rtx_MINUS (SImode,
4431                                                  gen_rtx_MINUS (SImode,
4432                                                                 const0_rtx,
4433                                                                 high),
4434                                                  gen_rtx_LTU (SImode,
4435                                                               cc_reg,
4436                                                               const0_rtx))));
4437         else
4438           {
4439             rtx two_x = gen_rtx_ASHIFT (SImode, high, GEN_INT (1));
4440             emit_insn (gen_rtx_SET (VOIDmode, high,
4441                                     gen_rtx_MINUS (SImode,
4442                                                    gen_rtx_MINUS (SImode,
4443                                                                   high,
4444                                                                   two_x),
4445                                                    gen_rtx_LTU (SImode,
4446                                                                 cc_reg,
4447                                                                 const0_rtx))));
4448           }
4449       }
4450     else
4451       {
4452         /* No overlap, or overlap on high word.  Use:
4453                 rsb     Rlo, Rin, #0
4454                 bic     Rhi, Rlo, Rin
4455                 asr     Rhi, Rhi, #31
4456            Flags not needed for this sequence.  */
4457         emit_insn (gen_rtx_SET (VOIDmode, low,
4458                                 gen_rtx_NEG (SImode, operands[1])));
4459         emit_insn (gen_rtx_SET (VOIDmode, high,
4460                                 gen_rtx_AND (SImode,
4461                                              gen_rtx_NOT (SImode, operands[1]),
4462                                              low)));
4463         emit_insn (gen_rtx_SET (VOIDmode, high,
4464                                 gen_rtx_ASHIFTRT (SImode, high,
4465                                                   GEN_INT (31))));
4466       }
4467     DONE;
4468   }
4469   [(set_attr "length" "12")
4470    (set_attr "arch" "t2,*")
4471    (set_attr "type" "multiple")]
4474 (define_insn_and_split "*negdi_zero_extendsidi"
4475   [(set (match_operand:DI 0 "s_register_operand" "=r,&r")
4476         (neg:DI (zero_extend:DI (match_operand:SI 1 "s_register_operand" "0,r"))))
4477    (clobber (reg:CC CC_REGNUM))]
4478   "TARGET_32BIT"
4479   "#" ; "rsbs\\t%Q0, %1, #0\;sbc\\t%R0,%R0,%R0"
4480       ;; Don't care what register is input to sbc,
4481       ;; since we just just need to propagate the carry.
4482   "&& reload_completed"
4483   [(parallel [(set (reg:CC CC_REGNUM)
4484                    (compare:CC (const_int 0) (match_dup 1)))
4485               (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1)))])
4486    (set (match_dup 2) (minus:SI (minus:SI (match_dup 2) (match_dup 2))
4487                                 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
4488   {
4489     operands[2] = gen_highpart (SImode, operands[0]);
4490     operands[0] = gen_lowpart (SImode, operands[0]);
4491   }
4492   [(set_attr "conds" "clob")
4493    (set_attr "length" "8")
4494    (set_attr "type" "multiple")]   ;; length in thumb is 4
4497 ;; abssi2 doesn't really clobber the condition codes if a different register
4498 ;; is being set.  To keep things simple, assume during rtl manipulations that
4499 ;; it does, but tell the final scan operator the truth.  Similarly for
4500 ;; (neg (abs...))
4502 (define_expand "abssi2"
4503   [(parallel
4504     [(set (match_operand:SI         0 "s_register_operand" "")
4505           (abs:SI (match_operand:SI 1 "s_register_operand" "")))
4506      (clobber (match_dup 2))])]
4507   "TARGET_EITHER"
4508   "
4509   if (TARGET_THUMB1)
4510     operands[2] = gen_rtx_SCRATCH (SImode);
4511   else
4512     operands[2] = gen_rtx_REG (CCmode, CC_REGNUM);
4515 (define_insn_and_split "*arm_abssi2"
4516   [(set (match_operand:SI 0 "s_register_operand" "=r,&r")
4517         (abs:SI (match_operand:SI 1 "s_register_operand" "0,r")))
4518    (clobber (reg:CC CC_REGNUM))]
4519   "TARGET_ARM"
4520   "#"
4521   "&& reload_completed"
4522   [(const_int 0)]
4523   {
4524    /* if (which_alternative == 0) */
4525    if (REGNO(operands[0]) == REGNO(operands[1]))
4526      {
4527       /* Emit the pattern:
4528          cmp\\t%0, #0\;rsblt\\t%0, %0, #0
4529          [(set (reg:CC CC_REGNUM)
4530                (compare:CC (match_dup 0) (const_int 0)))
4531           (cond_exec (lt:CC (reg:CC CC_REGNUM) (const_int 0))
4532                      (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1))))]
4533       */
4534       emit_insn (gen_rtx_SET (VOIDmode,
4535                               gen_rtx_REG (CCmode, CC_REGNUM),
4536                               gen_rtx_COMPARE (CCmode, operands[0], const0_rtx)));
4537       emit_insn (gen_rtx_COND_EXEC (VOIDmode,
4538                                     (gen_rtx_LT (SImode,
4539                                                  gen_rtx_REG (CCmode, CC_REGNUM),
4540                                                  const0_rtx)),
4541                                     (gen_rtx_SET (VOIDmode,
4542                                                   operands[0],
4543                                                   (gen_rtx_MINUS (SImode,
4544                                                                   const0_rtx,
4545                                                                   operands[1]))))));
4546       DONE;
4547      }
4548    else
4549      {
4550       /* Emit the pattern:
4551          alt1: eor%?\\t%0, %1, %1, asr #31\;sub%?\\t%0, %0, %1, asr #31
4552          [(set (match_dup 0)
4553                (xor:SI (match_dup 1)
4554                        (ashiftrt:SI (match_dup 1) (const_int 31))))
4555           (set (match_dup 0)
4556                (minus:SI (match_dup 0)
4557                       (ashiftrt:SI (match_dup 1) (const_int 31))))]
4558       */
4559       emit_insn (gen_rtx_SET (VOIDmode,
4560                               operands[0],
4561                               gen_rtx_XOR (SImode,
4562                                            gen_rtx_ASHIFTRT (SImode,
4563                                                              operands[1],
4564                                                              GEN_INT (31)),
4565                                            operands[1])));
4566       emit_insn (gen_rtx_SET (VOIDmode,
4567                               operands[0],
4568                               gen_rtx_MINUS (SImode,
4569                                              operands[0],
4570                                              gen_rtx_ASHIFTRT (SImode,
4571                                                                operands[1],
4572                                                                GEN_INT (31)))));
4573       DONE;
4574      }
4575   }
4576   [(set_attr "conds" "clob,*")
4577    (set_attr "shift" "1")
4578    (set_attr "predicable" "no, yes")
4579    (set_attr "length" "8")
4580    (set_attr "type" "multiple")]
4583 (define_insn_and_split "*arm_neg_abssi2"
4584   [(set (match_operand:SI 0 "s_register_operand" "=r,&r")
4585         (neg:SI (abs:SI (match_operand:SI 1 "s_register_operand" "0,r"))))
4586    (clobber (reg:CC CC_REGNUM))]
4587   "TARGET_ARM"
4588   "#"
4589   "&& reload_completed"
4590   [(const_int 0)]
4591   {
4592    /* if (which_alternative == 0) */
4593    if (REGNO (operands[0]) == REGNO (operands[1]))
4594      {
4595       /* Emit the pattern:
4596          cmp\\t%0, #0\;rsbgt\\t%0, %0, #0
4597       */
4598       emit_insn (gen_rtx_SET (VOIDmode,
4599                               gen_rtx_REG (CCmode, CC_REGNUM),
4600                               gen_rtx_COMPARE (CCmode, operands[0], const0_rtx)));
4601       emit_insn (gen_rtx_COND_EXEC (VOIDmode,
4602                                     gen_rtx_GT (SImode,
4603                                                 gen_rtx_REG (CCmode, CC_REGNUM),
4604                                                 const0_rtx),
4605                                     gen_rtx_SET (VOIDmode,
4606                                                  operands[0],
4607                                                  (gen_rtx_MINUS (SImode,
4608                                                                  const0_rtx,
4609                                                                  operands[1])))));
4610      }
4611    else
4612      {
4613       /* Emit the pattern:
4614          eor%?\\t%0, %1, %1, asr #31\;rsb%?\\t%0, %0, %1, asr #31
4615       */
4616       emit_insn (gen_rtx_SET (VOIDmode,
4617                               operands[0],
4618                               gen_rtx_XOR (SImode,
4619                                            gen_rtx_ASHIFTRT (SImode,
4620                                                              operands[1],
4621                                                              GEN_INT (31)),
4622                                            operands[1])));
4623       emit_insn (gen_rtx_SET (VOIDmode,
4624                               operands[0],
4625                               gen_rtx_MINUS (SImode,
4626                                              gen_rtx_ASHIFTRT (SImode,
4627                                                                operands[1],
4628                                                                GEN_INT (31)),
4629                                              operands[0])));
4630      }
4631    DONE;
4632   }
4633   [(set_attr "conds" "clob,*")
4634    (set_attr "shift" "1")
4635    (set_attr "predicable" "no, yes")
4636    (set_attr "length" "8")
4637    (set_attr "type" "multiple")]
4640 (define_expand "abssf2"
4641   [(set (match_operand:SF         0 "s_register_operand" "")
4642         (abs:SF (match_operand:SF 1 "s_register_operand" "")))]
4643   "TARGET_32BIT && TARGET_HARD_FLOAT"
4644   "")
4646 (define_expand "absdf2"
4647   [(set (match_operand:DF         0 "s_register_operand" "")
4648         (abs:DF (match_operand:DF 1 "s_register_operand" "")))]
4649   "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
4650   "")
4652 (define_expand "sqrtsf2"
4653   [(set (match_operand:SF 0 "s_register_operand" "")
4654         (sqrt:SF (match_operand:SF 1 "s_register_operand" "")))]
4655   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
4656   "")
4658 (define_expand "sqrtdf2"
4659   [(set (match_operand:DF 0 "s_register_operand" "")
4660         (sqrt:DF (match_operand:DF 1 "s_register_operand" "")))]
4661   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
4662   "")
4664 (define_insn_and_split "one_cmpldi2"
4665   [(set (match_operand:DI 0 "s_register_operand"         "=w,&r,&r,?w")
4666         (not:DI (match_operand:DI 1 "s_register_operand" " w, 0, r, w")))]
4667   "TARGET_32BIT"
4668   "@
4669    vmvn\t%P0, %P1
4670    #
4671    #
4672    vmvn\t%P0, %P1"
4673   "TARGET_32BIT && reload_completed
4674    && arm_general_register_operand (operands[0], DImode)"
4675   [(set (match_dup 0) (not:SI (match_dup 1)))
4676    (set (match_dup 2) (not:SI (match_dup 3)))]
4677   "
4678   {
4679     operands[2] = gen_highpart (SImode, operands[0]);
4680     operands[0] = gen_lowpart (SImode, operands[0]);
4681     operands[3] = gen_highpart (SImode, operands[1]);
4682     operands[1] = gen_lowpart (SImode, operands[1]);
4683   }"
4684   [(set_attr "length" "*,8,8,*")
4685    (set_attr "predicable" "no,yes,yes,no")
4686    (set_attr "type" "neon_move,multiple,multiple,neon_move")
4687    (set_attr "arch" "neon_for_64bits,*,*,avoid_neon_for_64bits")]
4690 (define_expand "one_cmplsi2"
4691   [(set (match_operand:SI         0 "s_register_operand" "")
4692         (not:SI (match_operand:SI 1 "s_register_operand" "")))]
4693   "TARGET_EITHER"
4694   ""
4697 (define_insn "*arm_one_cmplsi2"
4698   [(set (match_operand:SI         0 "s_register_operand" "=l,r")
4699         (not:SI (match_operand:SI 1 "s_register_operand"  "l,r")))]
4700   "TARGET_32BIT"
4701   "mvn%?\\t%0, %1"
4702   [(set_attr "predicable" "yes")
4703    (set_attr "predicable_short_it" "yes,no")
4704    (set_attr "arch" "t2,*")
4705    (set_attr "length" "4")
4706    (set_attr "type" "mvn_reg")]
4709 (define_insn "*notsi_compare0"
4710   [(set (reg:CC_NOOV CC_REGNUM)
4711         (compare:CC_NOOV (not:SI (match_operand:SI 1 "s_register_operand" "r"))
4712                          (const_int 0)))
4713    (set (match_operand:SI 0 "s_register_operand" "=r")
4714         (not:SI (match_dup 1)))]
4715   "TARGET_32BIT"
4716   "mvn%.\\t%0, %1"
4717   [(set_attr "conds" "set")
4718    (set_attr "type" "mvn_reg")]
4721 (define_insn "*notsi_compare0_scratch"
4722   [(set (reg:CC_NOOV CC_REGNUM)
4723         (compare:CC_NOOV (not:SI (match_operand:SI 1 "s_register_operand" "r"))
4724                          (const_int 0)))
4725    (clobber (match_scratch:SI 0 "=r"))]
4726   "TARGET_32BIT"
4727   "mvn%.\\t%0, %1"
4728   [(set_attr "conds" "set")
4729    (set_attr "type" "mvn_reg")]
4732 ;; Fixed <--> Floating conversion insns
4734 (define_expand "floatsihf2"
4735   [(set (match_operand:HF           0 "general_operand" "")
4736         (float:HF (match_operand:SI 1 "general_operand" "")))]
4737   "TARGET_EITHER"
4738   "
4739   {
4740     rtx op1 = gen_reg_rtx (SFmode);
4741     expand_float (op1, operands[1], 0);
4742     op1 = convert_to_mode (HFmode, op1, 0);
4743     emit_move_insn (operands[0], op1);
4744     DONE;
4745   }"
4748 (define_expand "floatdihf2"
4749   [(set (match_operand:HF           0 "general_operand" "")
4750         (float:HF (match_operand:DI 1 "general_operand" "")))]
4751   "TARGET_EITHER"
4752   "
4753   {
4754     rtx op1 = gen_reg_rtx (SFmode);
4755     expand_float (op1, operands[1], 0);
4756     op1 = convert_to_mode (HFmode, op1, 0);
4757     emit_move_insn (operands[0], op1);
4758     DONE;
4759   }"
4762 (define_expand "floatsisf2"
4763   [(set (match_operand:SF           0 "s_register_operand" "")
4764         (float:SF (match_operand:SI 1 "s_register_operand" "")))]
4765   "TARGET_32BIT && TARGET_HARD_FLOAT"
4766   "
4769 (define_expand "floatsidf2"
4770   [(set (match_operand:DF           0 "s_register_operand" "")
4771         (float:DF (match_operand:SI 1 "s_register_operand" "")))]
4772   "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
4773   "
4776 (define_expand "fix_trunchfsi2"
4777   [(set (match_operand:SI         0 "general_operand" "")
4778         (fix:SI (fix:HF (match_operand:HF 1 "general_operand"  ""))))]
4779   "TARGET_EITHER"
4780   "
4781   {
4782     rtx op1 = convert_to_mode (SFmode, operands[1], 0);
4783     expand_fix (operands[0], op1, 0);
4784     DONE;
4785   }"
4788 (define_expand "fix_trunchfdi2"
4789   [(set (match_operand:DI         0 "general_operand" "")
4790         (fix:DI (fix:HF (match_operand:HF 1 "general_operand"  ""))))]
4791   "TARGET_EITHER"
4792   "
4793   {
4794     rtx op1 = convert_to_mode (SFmode, operands[1], 0);
4795     expand_fix (operands[0], op1, 0);
4796     DONE;
4797   }"
4800 (define_expand "fix_truncsfsi2"
4801   [(set (match_operand:SI         0 "s_register_operand" "")
4802         (fix:SI (fix:SF (match_operand:SF 1 "s_register_operand"  ""))))]
4803   "TARGET_32BIT && TARGET_HARD_FLOAT"
4804   "
4807 (define_expand "fix_truncdfsi2"
4808   [(set (match_operand:SI         0 "s_register_operand" "")
4809         (fix:SI (fix:DF (match_operand:DF 1 "s_register_operand"  ""))))]
4810   "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
4811   "
4814 ;; Truncation insns
4816 (define_expand "truncdfsf2"
4817   [(set (match_operand:SF  0 "s_register_operand" "")
4818         (float_truncate:SF
4819          (match_operand:DF 1 "s_register_operand" "")))]
4820   "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
4821   ""
4824 /* DFmode -> HFmode conversions have to go through SFmode.  */
4825 (define_expand "truncdfhf2"
4826   [(set (match_operand:HF  0 "general_operand" "")
4827         (float_truncate:HF
4828          (match_operand:DF 1 "general_operand" "")))]
4829   "TARGET_EITHER"
4830   "
4831   {
4832     rtx op1;
4833     op1 = convert_to_mode (SFmode, operands[1], 0);
4834     op1 = convert_to_mode (HFmode, op1, 0);
4835     emit_move_insn (operands[0], op1);
4836     DONE;
4837   }"
4840 ;; Zero and sign extension instructions.
4842 (define_insn "zero_extend<mode>di2"
4843   [(set (match_operand:DI 0 "s_register_operand" "=w,r,?r,w")
4844         (zero_extend:DI (match_operand:QHSI 1 "<qhs_zextenddi_op>"
4845                                             "<qhs_zextenddi_cstr>")))]
4846   "TARGET_32BIT <qhs_zextenddi_cond>"
4847   "#"
4848   [(set_attr "length" "8,4,8,8")
4849    (set_attr "arch" "neon_for_64bits,*,*,avoid_neon_for_64bits")
4850    (set_attr "ce_count" "2")
4851    (set_attr "predicable" "yes")
4852    (set_attr "type" "multiple,mov_reg,multiple,multiple")]
4855 (define_insn "extend<mode>di2"
4856   [(set (match_operand:DI 0 "s_register_operand" "=w,r,?r,?r,w")
4857         (sign_extend:DI (match_operand:QHSI 1 "<qhs_extenddi_op>"
4858                                             "<qhs_extenddi_cstr>")))]
4859   "TARGET_32BIT <qhs_sextenddi_cond>"
4860   "#"
4861   [(set_attr "length" "8,4,8,8,8")
4862    (set_attr "ce_count" "2")
4863    (set_attr "shift" "1")
4864    (set_attr "predicable" "yes")
4865    (set_attr "arch" "neon_for_64bits,*,a,t,avoid_neon_for_64bits")
4866    (set_attr "type" "multiple,mov_reg,multiple,multiple,multiple")]
4869 ;; Splits for all extensions to DImode
4870 (define_split
4871   [(set (match_operand:DI 0 "s_register_operand" "")
4872         (zero_extend:DI (match_operand 1 "nonimmediate_operand" "")))]
4873   "TARGET_32BIT && reload_completed && !IS_VFP_REGNUM (REGNO (operands[0]))"
4874   [(set (match_dup 0) (match_dup 1))]
4876   rtx lo_part = gen_lowpart (SImode, operands[0]);
4877   machine_mode src_mode = GET_MODE (operands[1]);
4879   if (REG_P (operands[0])
4880       && !reg_overlap_mentioned_p (operands[0], operands[1]))
4881     emit_clobber (operands[0]);
4882   if (!REG_P (lo_part) || src_mode != SImode
4883       || !rtx_equal_p (lo_part, operands[1]))
4884     {
4885       if (src_mode == SImode)
4886         emit_move_insn (lo_part, operands[1]);
4887       else
4888         emit_insn (gen_rtx_SET (VOIDmode, lo_part,
4889                                 gen_rtx_ZERO_EXTEND (SImode, operands[1])));
4890       operands[1] = lo_part;
4891     }
4892   operands[0] = gen_highpart (SImode, operands[0]);
4893   operands[1] = const0_rtx;
4896 (define_split
4897   [(set (match_operand:DI 0 "s_register_operand" "")
4898         (sign_extend:DI (match_operand 1 "nonimmediate_operand" "")))]
4899   "TARGET_32BIT && reload_completed && !IS_VFP_REGNUM (REGNO (operands[0]))"
4900   [(set (match_dup 0) (ashiftrt:SI (match_dup 1) (const_int 31)))]
4902   rtx lo_part = gen_lowpart (SImode, operands[0]);
4903   machine_mode src_mode = GET_MODE (operands[1]);
4905   if (REG_P (operands[0])
4906       && !reg_overlap_mentioned_p (operands[0], operands[1]))
4907     emit_clobber (operands[0]);
4909   if (!REG_P (lo_part) || src_mode != SImode
4910       || !rtx_equal_p (lo_part, operands[1]))
4911     {
4912       if (src_mode == SImode)
4913         emit_move_insn (lo_part, operands[1]);
4914       else
4915         emit_insn (gen_rtx_SET (VOIDmode, lo_part,
4916                                 gen_rtx_SIGN_EXTEND (SImode, operands[1])));
4917       operands[1] = lo_part;
4918     }
4919   operands[0] = gen_highpart (SImode, operands[0]);
4922 (define_expand "zero_extendhisi2"
4923   [(set (match_operand:SI 0 "s_register_operand" "")
4924         (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
4925   "TARGET_EITHER"
4927   if (TARGET_ARM && !arm_arch4 && MEM_P (operands[1]))
4928     {
4929       emit_insn (gen_movhi_bytes (operands[0], operands[1]));
4930       DONE;
4931     }
4932   if (!arm_arch6 && !MEM_P (operands[1]))
4933     {
4934       rtx t = gen_lowpart (SImode, operands[1]);
4935       rtx tmp = gen_reg_rtx (SImode);
4936       emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (16)));
4937       emit_insn (gen_lshrsi3 (operands[0], tmp, GEN_INT (16)));
4938       DONE;
4939     }
4942 (define_split
4943   [(set (match_operand:SI 0 "s_register_operand" "")
4944         (zero_extend:SI (match_operand:HI 1 "s_register_operand" "")))]
4945   "!TARGET_THUMB2 && !arm_arch6"
4946   [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
4947    (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 16)))]
4949   operands[2] = gen_lowpart (SImode, operands[1]);
4952 (define_insn "*arm_zero_extendhisi2"
4953   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4954         (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
4955   "TARGET_ARM && arm_arch4 && !arm_arch6"
4956   "@
4957    #
4958    ldr%(h%)\\t%0, %1"
4959   [(set_attr "type" "alu_shift_reg,load_byte")
4960    (set_attr "predicable" "yes")]
4963 (define_insn "*arm_zero_extendhisi2_v6"
4964   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4965         (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,Uh")))]
4966   "TARGET_ARM && arm_arch6"
4967   "@
4968    uxth%?\\t%0, %1
4969    ldr%(h%)\\t%0, %1"
4970   [(set_attr "predicable" "yes")
4971    (set_attr "type" "extend,load_byte")]
4974 (define_insn "*arm_zero_extendhisi2addsi"
4975   [(set (match_operand:SI 0 "s_register_operand" "=r")
4976         (plus:SI (zero_extend:SI (match_operand:HI 1 "s_register_operand" "r"))
4977                  (match_operand:SI 2 "s_register_operand" "r")))]
4978   "TARGET_INT_SIMD"
4979   "uxtah%?\\t%0, %2, %1"
4980   [(set_attr "type" "alu_shift_reg")
4981    (set_attr "predicable" "yes")
4982    (set_attr "predicable_short_it" "no")]
4985 (define_expand "zero_extendqisi2"
4986   [(set (match_operand:SI 0 "s_register_operand" "")
4987         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))]
4988   "TARGET_EITHER"
4990   if (TARGET_ARM && !arm_arch6 && !MEM_P (operands[1]))
4991     {
4992       emit_insn (gen_andsi3 (operands[0],
4993                              gen_lowpart (SImode, operands[1]),
4994                                           GEN_INT (255)));
4995       DONE;
4996     }
4997   if (!arm_arch6 && !MEM_P (operands[1]))
4998     {
4999       rtx t = gen_lowpart (SImode, operands[1]);
5000       rtx tmp = gen_reg_rtx (SImode);
5001       emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (24)));
5002       emit_insn (gen_lshrsi3 (operands[0], tmp, GEN_INT (24)));
5003       DONE;
5004     }
5007 (define_split
5008   [(set (match_operand:SI 0 "s_register_operand" "")
5009         (zero_extend:SI (match_operand:QI 1 "s_register_operand" "")))]
5010   "!arm_arch6"
5011   [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 24)))
5012    (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 24)))]
5014   operands[2] = simplify_gen_subreg (SImode, operands[1], QImode, 0);
5015   if (TARGET_ARM)
5016     {
5017       emit_insn (gen_andsi3 (operands[0], operands[2], GEN_INT (255)));
5018       DONE;
5019     }
5022 (define_insn "*arm_zero_extendqisi2"
5023   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5024         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
5025   "TARGET_ARM && !arm_arch6"
5026   "@
5027    #
5028    ldr%(b%)\\t%0, %1\\t%@ zero_extendqisi2"
5029   [(set_attr "length" "8,4")
5030    (set_attr "type" "alu_shift_reg,load_byte")
5031    (set_attr "predicable" "yes")]
5034 (define_insn "*arm_zero_extendqisi2_v6"
5035   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5036         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,Uh")))]
5037   "TARGET_ARM && arm_arch6"
5038   "@
5039    uxtb%(%)\\t%0, %1
5040    ldr%(b%)\\t%0, %1\\t%@ zero_extendqisi2"
5041   [(set_attr "type" "extend,load_byte")
5042    (set_attr "predicable" "yes")]
5045 (define_insn "*arm_zero_extendqisi2addsi"
5046   [(set (match_operand:SI 0 "s_register_operand" "=r")
5047         (plus:SI (zero_extend:SI (match_operand:QI 1 "s_register_operand" "r"))
5048                  (match_operand:SI 2 "s_register_operand" "r")))]
5049   "TARGET_INT_SIMD"
5050   "uxtab%?\\t%0, %2, %1"
5051   [(set_attr "predicable" "yes")
5052    (set_attr "predicable_short_it" "no")
5053    (set_attr "type" "alu_shift_reg")]
5056 (define_split
5057   [(set (match_operand:SI 0 "s_register_operand" "")
5058         (zero_extend:SI (subreg:QI (match_operand:SI 1 "" "") 0)))
5059    (clobber (match_operand:SI 2 "s_register_operand" ""))]
5060   "TARGET_32BIT && (!MEM_P (operands[1])) && ! BYTES_BIG_ENDIAN"
5061   [(set (match_dup 2) (match_dup 1))
5062    (set (match_dup 0) (and:SI (match_dup 2) (const_int 255)))]
5063   ""
5066 (define_split
5067   [(set (match_operand:SI 0 "s_register_operand" "")
5068         (zero_extend:SI (subreg:QI (match_operand:SI 1 "" "") 3)))
5069    (clobber (match_operand:SI 2 "s_register_operand" ""))]
5070   "TARGET_32BIT && (!MEM_P (operands[1])) && BYTES_BIG_ENDIAN"
5071   [(set (match_dup 2) (match_dup 1))
5072    (set (match_dup 0) (and:SI (match_dup 2) (const_int 255)))]
5073   ""
5077 (define_split
5078   [(set (match_operand:SI 0 "s_register_operand" "")
5079         (IOR_XOR:SI (and:SI (ashift:SI
5080                              (match_operand:SI 1 "s_register_operand" "")
5081                              (match_operand:SI 2 "const_int_operand" ""))
5082                             (match_operand:SI 3 "const_int_operand" ""))
5083                     (zero_extend:SI
5084                      (match_operator 5 "subreg_lowpart_operator"
5085                       [(match_operand:SI 4 "s_register_operand" "")]))))]
5086   "TARGET_32BIT
5087    && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
5088        == (GET_MODE_MASK (GET_MODE (operands[5]))
5089            & (GET_MODE_MASK (GET_MODE (operands[5]))
5090               << (INTVAL (operands[2])))))"
5091   [(set (match_dup 0) (IOR_XOR:SI (ashift:SI (match_dup 1) (match_dup 2))
5092                                   (match_dup 4)))
5093    (set (match_dup 0) (zero_extend:SI (match_dup 5)))]
5094   "operands[5] = gen_lowpart (GET_MODE (operands[5]), operands[0]);"
5097 (define_insn "*compareqi_eq0"
5098   [(set (reg:CC_Z CC_REGNUM)
5099         (compare:CC_Z (match_operand:QI 0 "s_register_operand" "r")
5100                          (const_int 0)))]
5101   "TARGET_32BIT"
5102   "tst%?\\t%0, #255"
5103   [(set_attr "conds" "set")
5104    (set_attr "predicable" "yes")
5105    (set_attr "predicable_short_it" "no")
5106    (set_attr "type" "logic_imm")]
5109 (define_expand "extendhisi2"
5110   [(set (match_operand:SI 0 "s_register_operand" "")
5111         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
5112   "TARGET_EITHER"
5114   if (TARGET_THUMB1)
5115     {
5116       emit_insn (gen_thumb1_extendhisi2 (operands[0], operands[1]));
5117       DONE;
5118     }
5119   if (MEM_P (operands[1]) && TARGET_ARM && !arm_arch4)
5120     {
5121       emit_insn (gen_extendhisi2_mem (operands[0], operands[1]));
5122       DONE;
5123     }
5125   if (!arm_arch6 && !MEM_P (operands[1]))
5126     {
5127       rtx t = gen_lowpart (SImode, operands[1]);
5128       rtx tmp = gen_reg_rtx (SImode);
5129       emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (16)));
5130       emit_insn (gen_ashrsi3 (operands[0], tmp, GEN_INT (16)));
5131       DONE;
5132     }
5135 (define_split
5136   [(parallel
5137     [(set (match_operand:SI 0 "register_operand" "")
5138           (sign_extend:SI (match_operand:HI 1 "register_operand" "")))
5139      (clobber (match_scratch:SI 2 ""))])]
5140   "!arm_arch6"
5141   [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
5142    (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
5144   operands[2] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
5147 ;; This pattern will only be used when ldsh is not available
5148 (define_expand "extendhisi2_mem"
5149   [(set (match_dup 2) (zero_extend:SI (match_operand:HI 1 "" "")))
5150    (set (match_dup 3)
5151         (zero_extend:SI (match_dup 7)))
5152    (set (match_dup 6) (ashift:SI (match_dup 4) (const_int 24)))
5153    (set (match_operand:SI 0 "" "")
5154         (ior:SI (ashiftrt:SI (match_dup 6) (const_int 16)) (match_dup 5)))]
5155   "TARGET_ARM"
5156   "
5157   {
5158     rtx mem1, mem2;
5159     rtx addr = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
5161     mem1 = change_address (operands[1], QImode, addr);
5162     mem2 = change_address (operands[1], QImode,
5163                            plus_constant (Pmode, addr, 1));
5164     operands[0] = gen_lowpart (SImode, operands[0]);
5165     operands[1] = mem1;
5166     operands[2] = gen_reg_rtx (SImode);
5167     operands[3] = gen_reg_rtx (SImode);
5168     operands[6] = gen_reg_rtx (SImode);
5169     operands[7] = mem2;
5171     if (BYTES_BIG_ENDIAN)
5172       {
5173         operands[4] = operands[2];
5174         operands[5] = operands[3];
5175       }
5176     else
5177       {
5178         operands[4] = operands[3];
5179         operands[5] = operands[2];
5180       }
5181   }"
5184 (define_split
5185   [(set (match_operand:SI 0 "register_operand" "")
5186         (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
5187   "!arm_arch6"
5188   [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
5189    (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
5191   operands[2] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
5194 (define_insn "*arm_extendhisi2"
5195   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5196         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,Uh")))]
5197   "TARGET_ARM && arm_arch4 && !arm_arch6"
5198   "@
5199    #
5200    ldr%(sh%)\\t%0, %1"
5201   [(set_attr "length" "8,4")
5202    (set_attr "type" "alu_shift_reg,load_byte")
5203    (set_attr "predicable" "yes")]
5206 ;; ??? Check Thumb-2 pool range
5207 (define_insn "*arm_extendhisi2_v6"
5208   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5209         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,Uh")))]
5210   "TARGET_32BIT && arm_arch6"
5211   "@
5212    sxth%?\\t%0, %1
5213    ldr%(sh%)\\t%0, %1"
5214   [(set_attr "type" "extend,load_byte")
5215    (set_attr "predicable" "yes")
5216    (set_attr "predicable_short_it" "no")]
5219 (define_insn "*arm_extendhisi2addsi"
5220   [(set (match_operand:SI 0 "s_register_operand" "=r")
5221         (plus:SI (sign_extend:SI (match_operand:HI 1 "s_register_operand" "r"))
5222                  (match_operand:SI 2 "s_register_operand" "r")))]
5223   "TARGET_INT_SIMD"
5224   "sxtah%?\\t%0, %2, %1"
5225   [(set_attr "type" "alu_shift_reg")]
5228 (define_expand "extendqihi2"
5229   [(set (match_dup 2)
5230         (ashift:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "")
5231                    (const_int 24)))
5232    (set (match_operand:HI 0 "s_register_operand" "")
5233         (ashiftrt:SI (match_dup 2)
5234                      (const_int 24)))]
5235   "TARGET_ARM"
5236   "
5237   {
5238     if (arm_arch4 && MEM_P (operands[1]))
5239       {
5240         emit_insn (gen_rtx_SET (VOIDmode,
5241                                 operands[0],
5242                                 gen_rtx_SIGN_EXTEND (HImode, operands[1])));
5243         DONE;
5244       }
5245     if (!s_register_operand (operands[1], QImode))
5246       operands[1] = copy_to_mode_reg (QImode, operands[1]);
5247     operands[0] = gen_lowpart (SImode, operands[0]);
5248     operands[1] = gen_lowpart (SImode, operands[1]);
5249     operands[2] = gen_reg_rtx (SImode);
5250   }"
5253 (define_insn "*arm_extendqihi_insn"
5254   [(set (match_operand:HI 0 "s_register_operand" "=r")
5255         (sign_extend:HI (match_operand:QI 1 "arm_extendqisi_mem_op" "Uq")))]
5256   "TARGET_ARM && arm_arch4"
5257   "ldr%(sb%)\\t%0, %1"
5258   [(set_attr "type" "load_byte")
5259    (set_attr "predicable" "yes")]
5262 (define_expand "extendqisi2"
5263   [(set (match_operand:SI 0 "s_register_operand" "")
5264         (sign_extend:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "")))]
5265   "TARGET_EITHER"
5267   if (!arm_arch4 && MEM_P (operands[1]))
5268     operands[1] = copy_to_mode_reg (QImode, operands[1]);
5270   if (!arm_arch6 && !MEM_P (operands[1]))
5271     {
5272       rtx t = gen_lowpart (SImode, operands[1]);
5273       rtx tmp = gen_reg_rtx (SImode);
5274       emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (24)));
5275       emit_insn (gen_ashrsi3 (operands[0], tmp, GEN_INT (24)));
5276       DONE;
5277     }
5280 (define_split
5281   [(set (match_operand:SI 0 "register_operand" "")
5282         (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
5283   "!arm_arch6"
5284   [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 24)))
5285    (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 24)))]
5287   operands[2] = simplify_gen_subreg (SImode, operands[1], QImode, 0);
5290 (define_insn "*arm_extendqisi"
5291   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5292         (sign_extend:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "r,Uq")))]
5293   "TARGET_ARM && arm_arch4 && !arm_arch6"
5294   "@
5295    #
5296    ldr%(sb%)\\t%0, %1"
5297   [(set_attr "length" "8,4")
5298    (set_attr "type" "alu_shift_reg,load_byte")
5299    (set_attr "predicable" "yes")]
5302 (define_insn "*arm_extendqisi_v6"
5303   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5304         (sign_extend:SI
5305          (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "r,Uq")))]
5306   "TARGET_ARM && arm_arch6"
5307   "@
5308    sxtb%?\\t%0, %1
5309    ldr%(sb%)\\t%0, %1"
5310   [(set_attr "type" "extend,load_byte")
5311    (set_attr "predicable" "yes")]
5314 (define_insn "*arm_extendqisi2addsi"
5315   [(set (match_operand:SI 0 "s_register_operand" "=r")
5316         (plus:SI (sign_extend:SI (match_operand:QI 1 "s_register_operand" "r"))
5317                  (match_operand:SI 2 "s_register_operand" "r")))]
5318   "TARGET_INT_SIMD"
5319   "sxtab%?\\t%0, %2, %1"
5320   [(set_attr "type" "alu_shift_reg")
5321    (set_attr "predicable" "yes")
5322    (set_attr "predicable_short_it" "no")]
5325 (define_expand "extendsfdf2"
5326   [(set (match_operand:DF                  0 "s_register_operand" "")
5327         (float_extend:DF (match_operand:SF 1 "s_register_operand"  "")))]
5328   "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
5329   ""
5332 /* HFmode -> DFmode conversions have to go through SFmode.  */
5333 (define_expand "extendhfdf2"
5334   [(set (match_operand:DF                  0 "general_operand" "")
5335         (float_extend:DF (match_operand:HF 1 "general_operand"  "")))]
5336   "TARGET_EITHER"
5337   "
5338   {
5339     rtx op1;
5340     op1 = convert_to_mode (SFmode, operands[1], 0);
5341     op1 = convert_to_mode (DFmode, op1, 0);
5342     emit_insn (gen_movdf (operands[0], op1));
5343     DONE;
5344   }"
5347 ;; Move insns (including loads and stores)
5349 ;; XXX Just some ideas about movti.
5350 ;; I don't think these are a good idea on the arm, there just aren't enough
5351 ;; registers
5352 ;;(define_expand "loadti"
5353 ;;  [(set (match_operand:TI 0 "s_register_operand" "")
5354 ;;      (mem:TI (match_operand:SI 1 "address_operand" "")))]
5355 ;;  "" "")
5357 ;;(define_expand "storeti"
5358 ;;  [(set (mem:TI (match_operand:TI 0 "address_operand" ""))
5359 ;;      (match_operand:TI 1 "s_register_operand" ""))]
5360 ;;  "" "")
5362 ;;(define_expand "movti"
5363 ;;  [(set (match_operand:TI 0 "general_operand" "")
5364 ;;      (match_operand:TI 1 "general_operand" ""))]
5365 ;;  ""
5366 ;;  "
5368 ;;  rtx insn;
5370 ;;  if (MEM_P (operands[0]) && MEM_P (operands[1]))
5371 ;;    operands[1] = copy_to_reg (operands[1]);
5372 ;;  if (MEM_P (operands[0]))
5373 ;;    insn = gen_storeti (XEXP (operands[0], 0), operands[1]);
5374 ;;  else if (MEM_P (operands[1]))
5375 ;;    insn = gen_loadti (operands[0], XEXP (operands[1], 0));
5376 ;;  else
5377 ;;    FAIL;
5379 ;;  emit_insn (insn);
5380 ;;  DONE;
5381 ;;}")
5383 ;; Recognize garbage generated above.
5385 ;;(define_insn ""
5386 ;;  [(set (match_operand:TI 0 "general_operand" "=r,r,r,<,>,m")
5387 ;;      (match_operand:TI 1 "general_operand" "<,>,m,r,r,r"))]
5388 ;;  ""
5389 ;;  "*
5390 ;;  {
5391 ;;    register mem = (which_alternative < 3);
5392 ;;    register const char *template;
5394 ;;    operands[mem] = XEXP (operands[mem], 0);
5395 ;;    switch (which_alternative)
5396 ;;      {
5397 ;;      case 0: template = \"ldmdb\\t%1!, %M0\"; break;
5398 ;;      case 1: template = \"ldmia\\t%1!, %M0\"; break;
5399 ;;      case 2: template = \"ldmia\\t%1, %M0\"; break;
5400 ;;      case 3: template = \"stmdb\\t%0!, %M1\"; break;
5401 ;;      case 4: template = \"stmia\\t%0!, %M1\"; break;
5402 ;;      case 5: template = \"stmia\\t%0, %M1\"; break;
5403 ;;      }
5404 ;;    output_asm_insn (template, operands);
5405 ;;    return \"\";
5406 ;;  }")
5408 (define_expand "movdi"
5409   [(set (match_operand:DI 0 "general_operand" "")
5410         (match_operand:DI 1 "general_operand" ""))]
5411   "TARGET_EITHER"
5412   "
5413   if (can_create_pseudo_p ())
5414     {
5415       if (!REG_P (operands[0]))
5416         operands[1] = force_reg (DImode, operands[1]);
5417     }
5418   "
5421 (define_insn "*arm_movdi"
5422   [(set (match_operand:DI 0 "nonimmediate_di_operand" "=r, r, r, q, m")
5423         (match_operand:DI 1 "di_operand"              "rDa,Db,Dc,mi,q"))]
5424   "TARGET_32BIT
5425    && !(TARGET_HARD_FLOAT && TARGET_VFP)
5426    && !TARGET_IWMMXT
5427    && (   register_operand (operands[0], DImode)
5428        || register_operand (operands[1], DImode))"
5429   "*
5430   switch (which_alternative)
5431     {
5432     case 0:
5433     case 1:
5434     case 2:
5435       return \"#\";
5436     default:
5437       return output_move_double (operands, true, NULL);
5438     }
5439   "
5440   [(set_attr "length" "8,12,16,8,8")
5441    (set_attr "type" "multiple,multiple,multiple,load2,store2")
5442    (set_attr "arm_pool_range" "*,*,*,1020,*")
5443    (set_attr "arm_neg_pool_range" "*,*,*,1004,*")
5444    (set_attr "thumb2_pool_range" "*,*,*,4094,*")
5445    (set_attr "thumb2_neg_pool_range" "*,*,*,0,*")]
5448 (define_split
5449   [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
5450         (match_operand:ANY64 1 "immediate_operand" ""))]
5451   "TARGET_32BIT
5452    && reload_completed
5453    && (arm_const_double_inline_cost (operands[1])
5454        <= arm_max_const_double_inline_cost ())"
5455   [(const_int 0)]
5456   "
5457   arm_split_constant (SET, SImode, curr_insn,
5458                       INTVAL (gen_lowpart (SImode, operands[1])),
5459                       gen_lowpart (SImode, operands[0]), NULL_RTX, 0);
5460   arm_split_constant (SET, SImode, curr_insn,
5461                       INTVAL (gen_highpart_mode (SImode,
5462                                                  GET_MODE (operands[0]),
5463                                                  operands[1])),
5464                       gen_highpart (SImode, operands[0]), NULL_RTX, 0);
5465   DONE;
5466   "
5469 ; If optimizing for size, or if we have load delay slots, then 
5470 ; we want to split the constant into two separate operations. 
5471 ; In both cases this may split a trivial part into a single data op
5472 ; leaving a single complex constant to load.  We can also get longer
5473 ; offsets in a LDR which means we get better chances of sharing the pool
5474 ; entries.  Finally, we can normally do a better job of scheduling
5475 ; LDR instructions than we can with LDM.
5476 ; This pattern will only match if the one above did not.
5477 (define_split
5478   [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
5479         (match_operand:ANY64 1 "const_double_operand" ""))]
5480   "TARGET_ARM && reload_completed
5481    && arm_const_double_by_parts (operands[1])"
5482   [(set (match_dup 0) (match_dup 1))
5483    (set (match_dup 2) (match_dup 3))]
5484   "
5485   operands[2] = gen_highpart (SImode, operands[0]);
5486   operands[3] = gen_highpart_mode (SImode, GET_MODE (operands[0]),
5487                                    operands[1]);
5488   operands[0] = gen_lowpart (SImode, operands[0]);
5489   operands[1] = gen_lowpart (SImode, operands[1]);
5490   "
5493 (define_split
5494   [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
5495         (match_operand:ANY64 1 "arm_general_register_operand" ""))]
5496   "TARGET_EITHER && reload_completed"
5497   [(set (match_dup 0) (match_dup 1))
5498    (set (match_dup 2) (match_dup 3))]
5499   "
5500   operands[2] = gen_highpart (SImode, operands[0]);
5501   operands[3] = gen_highpart (SImode, operands[1]);
5502   operands[0] = gen_lowpart (SImode, operands[0]);
5503   operands[1] = gen_lowpart (SImode, operands[1]);
5505   /* Handle a partial overlap.  */
5506   if (rtx_equal_p (operands[0], operands[3]))
5507     {
5508       rtx tmp0 = operands[0];
5509       rtx tmp1 = operands[1];
5511       operands[0] = operands[2];
5512       operands[1] = operands[3];
5513       operands[2] = tmp0;
5514       operands[3] = tmp1;
5515     }
5516   "
5519 ;; We can't actually do base+index doubleword loads if the index and
5520 ;; destination overlap.  Split here so that we at least have chance to
5521 ;; schedule.
5522 (define_split
5523   [(set (match_operand:DI 0 "s_register_operand" "")
5524         (mem:DI (plus:SI (match_operand:SI 1 "s_register_operand" "")
5525                          (match_operand:SI 2 "s_register_operand" ""))))]
5526   "TARGET_LDRD
5527   && reg_overlap_mentioned_p (operands[0], operands[1])
5528   && reg_overlap_mentioned_p (operands[0], operands[2])"
5529   [(set (match_dup 4)
5530         (plus:SI (match_dup 1)
5531                  (match_dup 2)))
5532    (set (match_dup 0)
5533         (mem:DI (match_dup 4)))]
5534   "
5535   operands[4] = gen_rtx_REG (SImode, REGNO(operands[0]));
5536   "
5539 (define_expand "movsi"
5540   [(set (match_operand:SI 0 "general_operand" "")
5541         (match_operand:SI 1 "general_operand" ""))]
5542   "TARGET_EITHER"
5543   "
5544   {
5545   rtx base, offset, tmp;
5547   if (TARGET_32BIT)
5548     {
5549       /* Everything except mem = const or mem = mem can be done easily.  */
5550       if (MEM_P (operands[0]))
5551         operands[1] = force_reg (SImode, operands[1]);
5552       if (arm_general_register_operand (operands[0], SImode)
5553           && CONST_INT_P (operands[1])
5554           && !(const_ok_for_arm (INTVAL (operands[1]))
5555                || const_ok_for_arm (~INTVAL (operands[1]))))
5556         {
5557            arm_split_constant (SET, SImode, NULL_RTX,
5558                                INTVAL (operands[1]), operands[0], NULL_RTX,
5559                                optimize && can_create_pseudo_p ());
5560           DONE;
5561         }
5562     }
5563   else /* TARGET_THUMB1...  */
5564     {
5565       if (can_create_pseudo_p ())
5566         {
5567           if (!REG_P (operands[0]))
5568             operands[1] = force_reg (SImode, operands[1]);
5569         }
5570     }
5572   if (ARM_OFFSETS_MUST_BE_WITHIN_SECTIONS_P)
5573     {
5574       split_const (operands[1], &base, &offset);
5575       if (GET_CODE (base) == SYMBOL_REF
5576           && !offset_within_block_p (base, INTVAL (offset)))
5577         {
5578           tmp = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];
5579           emit_move_insn (tmp, base);
5580           emit_insn (gen_addsi3 (operands[0], tmp, offset));
5581           DONE;
5582         }
5583     }
5585   /* Recognize the case where operand[1] is a reference to thread-local
5586      data and load its address to a register.  */
5587   if (arm_tls_referenced_p (operands[1]))
5588     {
5589       rtx tmp = operands[1];
5590       rtx addend = NULL;
5592       if (GET_CODE (tmp) == CONST && GET_CODE (XEXP (tmp, 0)) == PLUS)
5593         {
5594           addend = XEXP (XEXP (tmp, 0), 1);
5595           tmp = XEXP (XEXP (tmp, 0), 0);
5596         }
5598       gcc_assert (GET_CODE (tmp) == SYMBOL_REF);
5599       gcc_assert (SYMBOL_REF_TLS_MODEL (tmp) != 0);
5601       tmp = legitimize_tls_address (tmp,
5602                                     !can_create_pseudo_p () ? operands[0] : 0);
5603       if (addend)
5604         {
5605           tmp = gen_rtx_PLUS (SImode, tmp, addend);
5606           tmp = force_operand (tmp, operands[0]);
5607         }
5608       operands[1] = tmp;
5609     }
5610   else if (flag_pic
5611            && (CONSTANT_P (operands[1])
5612                || symbol_mentioned_p (operands[1])
5613                || label_mentioned_p (operands[1])))
5614       operands[1] = legitimize_pic_address (operands[1], SImode,
5615                                             (!can_create_pseudo_p ()
5616                                              ? operands[0]
5617                                              : 0));
5618   }
5619   "
5622 ;; The ARM LO_SUM and HIGH are backwards - HIGH sets the low bits, and
5623 ;; LO_SUM adds in the high bits.  Fortunately these are opaque operations
5624 ;; so this does not matter.
5625 (define_insn "*arm_movt"
5626   [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
5627         (lo_sum:SI (match_operand:SI 1 "nonimmediate_operand" "0")
5628                    (match_operand:SI 2 "general_operand"      "i")))]
5629   "arm_arch_thumb2"
5630   "movt%?\t%0, #:upper16:%c2"
5631   [(set_attr "predicable" "yes")
5632    (set_attr "predicable_short_it" "no")
5633    (set_attr "length" "4")
5634    (set_attr "type" "mov_imm")]
5637 (define_insn "*arm_movsi_insn"
5638   [(set (match_operand:SI 0 "nonimmediate_operand" "=rk,r,r,r,rk,m")
5639         (match_operand:SI 1 "general_operand"      "rk, I,K,j,mi,rk"))]
5640   "TARGET_ARM && ! TARGET_IWMMXT
5641    && !(TARGET_HARD_FLOAT && TARGET_VFP)
5642    && (   register_operand (operands[0], SImode)
5643        || register_operand (operands[1], SImode))"
5644   "@
5645    mov%?\\t%0, %1
5646    mov%?\\t%0, %1
5647    mvn%?\\t%0, #%B1
5648    movw%?\\t%0, %1
5649    ldr%?\\t%0, %1
5650    str%?\\t%1, %0"
5651   [(set_attr "type" "mov_reg,mov_imm,mvn_imm,mov_imm,load1,store1")
5652    (set_attr "predicable" "yes")
5653    (set_attr "pool_range" "*,*,*,*,4096,*")
5654    (set_attr "neg_pool_range" "*,*,*,*,4084,*")]
5657 (define_split
5658   [(set (match_operand:SI 0 "arm_general_register_operand" "")
5659         (match_operand:SI 1 "const_int_operand" ""))]
5660   "TARGET_32BIT
5661   && (!(const_ok_for_arm (INTVAL (operands[1]))
5662         || const_ok_for_arm (~INTVAL (operands[1]))))"
5663   [(clobber (const_int 0))]
5664   "
5665   arm_split_constant (SET, SImode, NULL_RTX, 
5666                       INTVAL (operands[1]), operands[0], NULL_RTX, 0);
5667   DONE;
5668   "
5671 ;; A normal way to do (symbol + offset) requires three instructions at least
5672 ;; (depends on how big the offset is) as below:
5673 ;; movw r0, #:lower16:g
5674 ;; movw r0, #:upper16:g
5675 ;; adds r0, #4
5677 ;; A better way would be:
5678 ;; movw r0, #:lower16:g+4
5679 ;; movw r0, #:upper16:g+4
5681 ;; The limitation of this way is that the length of offset should be a 16-bit
5682 ;; signed value, because current assembler only supports REL type relocation for
5683 ;; such case.  If the more powerful RELA type is supported in future, we should
5684 ;; update this pattern to go with better way.
5685 (define_split
5686   [(set (match_operand:SI 0 "arm_general_register_operand" "")
5687         (const:SI (plus:SI (match_operand:SI 1 "general_operand" "")
5688                            (match_operand:SI 2 "const_int_operand" ""))))]
5689   "TARGET_THUMB2
5690    && arm_disable_literal_pool
5691    && reload_completed
5692    && GET_CODE (operands[1]) == SYMBOL_REF"
5693   [(clobber (const_int 0))]
5694   "
5695     int offset = INTVAL (operands[2]);
5697     if (offset < -0x8000 || offset > 0x7fff)
5698       {
5699         arm_emit_movpair (operands[0], operands[1]);
5700         emit_insn (gen_rtx_SET (SImode, operands[0],
5701                                 gen_rtx_PLUS (SImode, operands[0], operands[2])));
5702       }
5703     else
5704       {
5705         rtx op = gen_rtx_CONST (SImode,
5706                                 gen_rtx_PLUS (SImode, operands[1], operands[2]));
5707         arm_emit_movpair (operands[0], op);
5708       }
5709   "
5712 ;; Split symbol_refs at the later stage (after cprop), instead of generating
5713 ;; movt/movw pair directly at expand.  Otherwise corresponding high_sum
5714 ;; and lo_sum would be merged back into memory load at cprop.  However,
5715 ;; if the default is to prefer movt/movw rather than a load from the constant
5716 ;; pool, the performance is better.
5717 (define_split
5718   [(set (match_operand:SI 0 "arm_general_register_operand" "")
5719        (match_operand:SI 1 "general_operand" ""))]
5720   "TARGET_32BIT
5721    && TARGET_USE_MOVT && GET_CODE (operands[1]) == SYMBOL_REF
5722    && !flag_pic && !target_word_relocations
5723    && !arm_tls_referenced_p (operands[1])"
5724   [(clobber (const_int 0))]
5726   arm_emit_movpair (operands[0], operands[1]);
5727   DONE;
5730 ;; When generating pic, we need to load the symbol offset into a register.
5731 ;; So that the optimizer does not confuse this with a normal symbol load
5732 ;; we use an unspec.  The offset will be loaded from a constant pool entry,
5733 ;; since that is the only type of relocation we can use.
5735 ;; Wrap calculation of the whole PIC address in a single pattern for the
5736 ;; benefit of optimizers, particularly, PRE and HOIST.  Calculation of
5737 ;; a PIC address involves two loads from memory, so we want to CSE it
5738 ;; as often as possible.
5739 ;; This pattern will be split into one of the pic_load_addr_* patterns
5740 ;; and a move after GCSE optimizations.
5742 ;; Note: Update arm.c: legitimize_pic_address() when changing this pattern.
5743 (define_expand "calculate_pic_address"
5744   [(set (match_operand:SI 0 "register_operand" "")
5745         (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "")
5746                          (unspec:SI [(match_operand:SI 2 "" "")]
5747                                     UNSPEC_PIC_SYM))))]
5748   "flag_pic"
5751 ;; Split calculate_pic_address into pic_load_addr_* and a move.
5752 (define_split
5753   [(set (match_operand:SI 0 "register_operand" "")
5754         (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "")
5755                          (unspec:SI [(match_operand:SI 2 "" "")]
5756                                     UNSPEC_PIC_SYM))))]
5757   "flag_pic"
5758   [(set (match_dup 3) (unspec:SI [(match_dup 2)] UNSPEC_PIC_SYM))
5759    (set (match_dup 0) (mem:SI (plus:SI (match_dup 1) (match_dup 3))))]
5760   "operands[3] = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];"
5763 ;; operand1 is the memory address to go into 
5764 ;; pic_load_addr_32bit.
5765 ;; operand2 is the PIC label to be emitted 
5766 ;; from pic_add_dot_plus_eight.
5767 ;; We do this to allow hoisting of the entire insn.
5768 (define_insn_and_split "pic_load_addr_unified"
5769   [(set (match_operand:SI 0 "s_register_operand" "=r,r,l")
5770         (unspec:SI [(match_operand:SI 1 "" "mX,mX,mX") 
5771                     (match_operand:SI 2 "" "")] 
5772                     UNSPEC_PIC_UNIFIED))]
5773  "flag_pic"
5774  "#"
5775  "&& reload_completed"
5776  [(set (match_dup 0) (unspec:SI [(match_dup 1)] UNSPEC_PIC_SYM))
5777   (set (match_dup 0) (unspec:SI [(match_dup 0) (match_dup 3)
5778                                  (match_dup 2)] UNSPEC_PIC_BASE))]
5779  "operands[3] = TARGET_THUMB ? GEN_INT (4) : GEN_INT (8);"
5780  [(set_attr "type" "load1,load1,load1")
5781   (set_attr "pool_range" "4096,4094,1022")
5782   (set_attr "neg_pool_range" "4084,0,0")
5783   (set_attr "arch"  "a,t2,t1")    
5784   (set_attr "length" "8,6,4")]
5787 ;; The rather odd constraints on the following are to force reload to leave
5788 ;; the insn alone, and to force the minipool generation pass to then move
5789 ;; the GOT symbol to memory.
5791 (define_insn "pic_load_addr_32bit"
5792   [(set (match_operand:SI 0 "s_register_operand" "=r")
5793         (unspec:SI [(match_operand:SI 1 "" "mX")] UNSPEC_PIC_SYM))]
5794   "TARGET_32BIT && flag_pic"
5795   "ldr%?\\t%0, %1"
5796   [(set_attr "type" "load1")
5797    (set (attr "pool_range")
5798         (if_then_else (eq_attr "is_thumb" "no")
5799                       (const_int 4096)
5800                       (const_int 4094)))
5801    (set (attr "neg_pool_range")
5802         (if_then_else (eq_attr "is_thumb" "no")
5803                       (const_int 4084)
5804                       (const_int 0)))]
5807 (define_insn "pic_load_addr_thumb1"
5808   [(set (match_operand:SI 0 "s_register_operand" "=l")
5809         (unspec:SI [(match_operand:SI 1 "" "mX")] UNSPEC_PIC_SYM))]
5810   "TARGET_THUMB1 && flag_pic"
5811   "ldr\\t%0, %1"
5812   [(set_attr "type" "load1")
5813    (set (attr "pool_range") (const_int 1018))]
5816 (define_insn "pic_add_dot_plus_four"
5817   [(set (match_operand:SI 0 "register_operand" "=r")
5818         (unspec:SI [(match_operand:SI 1 "register_operand" "0")
5819                     (const_int 4)
5820                     (match_operand 2 "" "")]
5821                    UNSPEC_PIC_BASE))]
5822   "TARGET_THUMB"
5823   "*
5824   (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
5825                                      INTVAL (operands[2]));
5826   return \"add\\t%0, %|pc\";
5827   "
5828   [(set_attr "length" "2")
5829    (set_attr "type" "alu_sreg")]
5832 (define_insn "pic_add_dot_plus_eight"
5833   [(set (match_operand:SI 0 "register_operand" "=r")
5834         (unspec:SI [(match_operand:SI 1 "register_operand" "r")
5835                     (const_int 8)
5836                     (match_operand 2 "" "")]
5837                    UNSPEC_PIC_BASE))]
5838   "TARGET_ARM"
5839   "*
5840     (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
5841                                        INTVAL (operands[2]));
5842     return \"add%?\\t%0, %|pc, %1\";
5843   "
5844   [(set_attr "predicable" "yes")
5845    (set_attr "type" "alu_sreg")]
5848 (define_insn "tls_load_dot_plus_eight"
5849   [(set (match_operand:SI 0 "register_operand" "=r")
5850         (mem:SI (unspec:SI [(match_operand:SI 1 "register_operand" "r")
5851                             (const_int 8)
5852                             (match_operand 2 "" "")]
5853                            UNSPEC_PIC_BASE)))]
5854   "TARGET_ARM"
5855   "*
5856     (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
5857                                        INTVAL (operands[2]));
5858     return \"ldr%?\\t%0, [%|pc, %1]\t\t@ tls_load_dot_plus_eight\";
5859   "
5860   [(set_attr "predicable" "yes")
5861    (set_attr "type" "load1")]
5864 ;; PIC references to local variables can generate pic_add_dot_plus_eight
5865 ;; followed by a load.  These sequences can be crunched down to
5866 ;; tls_load_dot_plus_eight by a peephole.
5868 (define_peephole2
5869   [(set (match_operand:SI 0 "register_operand" "")
5870         (unspec:SI [(match_operand:SI 3 "register_operand" "")
5871                     (const_int 8)
5872                     (match_operand 1 "" "")]
5873                    UNSPEC_PIC_BASE))
5874    (set (match_operand:SI 2 "arm_general_register_operand" "")
5875         (mem:SI (match_dup 0)))]
5876   "TARGET_ARM && peep2_reg_dead_p (2, operands[0])"
5877   [(set (match_dup 2)
5878         (mem:SI (unspec:SI [(match_dup 3)
5879                             (const_int 8)
5880                             (match_dup 1)]
5881                            UNSPEC_PIC_BASE)))]
5882   ""
5885 (define_insn "pic_offset_arm"
5886   [(set (match_operand:SI 0 "register_operand" "=r")
5887         (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
5888                          (unspec:SI [(match_operand:SI 2 "" "X")]
5889                                     UNSPEC_PIC_OFFSET))))]
5890   "TARGET_VXWORKS_RTP && TARGET_ARM && flag_pic"
5891   "ldr%?\\t%0, [%1,%2]"
5892   [(set_attr "type" "load1")]
5895 (define_expand "builtin_setjmp_receiver"
5896   [(label_ref (match_operand 0 "" ""))]
5897   "flag_pic"
5898   "
5900   /* r3 is clobbered by set/longjmp, so we can use it as a scratch
5901      register.  */
5902   if (arm_pic_register != INVALID_REGNUM)
5903     arm_load_pic_register (1UL << 3);
5904   DONE;
5907 ;; If copying one reg to another we can set the condition codes according to
5908 ;; its value.  Such a move is common after a return from subroutine and the
5909 ;; result is being tested against zero.
5911 (define_insn "*movsi_compare0"
5912   [(set (reg:CC CC_REGNUM)
5913         (compare:CC (match_operand:SI 1 "s_register_operand" "0,r")
5914                     (const_int 0)))
5915    (set (match_operand:SI 0 "s_register_operand" "=r,r")
5916         (match_dup 1))]
5917   "TARGET_32BIT"
5918   "@
5919    cmp%?\\t%0, #0
5920    sub%.\\t%0, %1, #0"
5921   [(set_attr "conds" "set")
5922    (set_attr "type" "alus_imm,alus_imm")]
5925 ;; Subroutine to store a half word from a register into memory.
5926 ;; Operand 0 is the source register (HImode)
5927 ;; Operand 1 is the destination address in a register (SImode)
5929 ;; In both this routine and the next, we must be careful not to spill
5930 ;; a memory address of reg+large_const into a separate PLUS insn, since this
5931 ;; can generate unrecognizable rtl.
5933 (define_expand "storehi"
5934   [;; store the low byte
5935    (set (match_operand 1 "" "") (match_dup 3))
5936    ;; extract the high byte
5937    (set (match_dup 2)
5938         (ashiftrt:SI (match_operand 0 "" "") (const_int 8)))
5939    ;; store the high byte
5940    (set (match_dup 4) (match_dup 5))]
5941   "TARGET_ARM"
5942   "
5943   {
5944     rtx op1 = operands[1];
5945     rtx addr = XEXP (op1, 0);
5946     enum rtx_code code = GET_CODE (addr);
5948     if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1)))
5949         || code == MINUS)
5950       op1 = replace_equiv_address (operands[1], force_reg (SImode, addr));
5952     operands[4] = adjust_address (op1, QImode, 1);
5953     operands[1] = adjust_address (operands[1], QImode, 0);
5954     operands[3] = gen_lowpart (QImode, operands[0]);
5955     operands[0] = gen_lowpart (SImode, operands[0]);
5956     operands[2] = gen_reg_rtx (SImode);
5957     operands[5] = gen_lowpart (QImode, operands[2]);
5958   }"
5961 (define_expand "storehi_bigend"
5962   [(set (match_dup 4) (match_dup 3))
5963    (set (match_dup 2)
5964         (ashiftrt:SI (match_operand 0 "" "") (const_int 8)))
5965    (set (match_operand 1 "" "") (match_dup 5))]
5966   "TARGET_ARM"
5967   "
5968   {
5969     rtx op1 = operands[1];
5970     rtx addr = XEXP (op1, 0);
5971     enum rtx_code code = GET_CODE (addr);
5973     if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1)))
5974         || code == MINUS)
5975       op1 = replace_equiv_address (op1, force_reg (SImode, addr));
5977     operands[4] = adjust_address (op1, QImode, 1);
5978     operands[1] = adjust_address (operands[1], QImode, 0);
5979     operands[3] = gen_lowpart (QImode, operands[0]);
5980     operands[0] = gen_lowpart (SImode, operands[0]);
5981     operands[2] = gen_reg_rtx (SImode);
5982     operands[5] = gen_lowpart (QImode, operands[2]);
5983   }"
5986 ;; Subroutine to store a half word integer constant into memory.
5987 (define_expand "storeinthi"
5988   [(set (match_operand 0 "" "")
5989         (match_operand 1 "" ""))
5990    (set (match_dup 3) (match_dup 2))]
5991   "TARGET_ARM"
5992   "
5993   {
5994     HOST_WIDE_INT value = INTVAL (operands[1]);
5995     rtx addr = XEXP (operands[0], 0);
5996     rtx op0 = operands[0];
5997     enum rtx_code code = GET_CODE (addr);
5999     if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1)))
6000         || code == MINUS)
6001       op0 = replace_equiv_address (op0, force_reg (SImode, addr));
6003     operands[1] = gen_reg_rtx (SImode);
6004     if (BYTES_BIG_ENDIAN)
6005       {
6006         emit_insn (gen_movsi (operands[1], GEN_INT ((value >> 8) & 255)));
6007         if ((value & 255) == ((value >> 8) & 255))
6008           operands[2] = operands[1];
6009         else
6010           {
6011             operands[2] = gen_reg_rtx (SImode);
6012             emit_insn (gen_movsi (operands[2], GEN_INT (value & 255)));
6013           }
6014       }
6015     else
6016       {
6017         emit_insn (gen_movsi (operands[1], GEN_INT (value & 255)));
6018         if ((value & 255) == ((value >> 8) & 255))
6019           operands[2] = operands[1];
6020         else
6021           {
6022             operands[2] = gen_reg_rtx (SImode);
6023             emit_insn (gen_movsi (operands[2], GEN_INT ((value >> 8) & 255)));
6024           }
6025       }
6027     operands[3] = adjust_address (op0, QImode, 1);
6028     operands[0] = adjust_address (operands[0], QImode, 0);
6029     operands[2] = gen_lowpart (QImode, operands[2]);
6030     operands[1] = gen_lowpart (QImode, operands[1]);
6031   }"
6034 (define_expand "storehi_single_op"
6035   [(set (match_operand:HI 0 "memory_operand" "")
6036         (match_operand:HI 1 "general_operand" ""))]
6037   "TARGET_32BIT && arm_arch4"
6038   "
6039   if (!s_register_operand (operands[1], HImode))
6040     operands[1] = copy_to_mode_reg (HImode, operands[1]);
6041   "
6044 (define_expand "movhi"
6045   [(set (match_operand:HI 0 "general_operand" "")
6046         (match_operand:HI 1 "general_operand" ""))]
6047   "TARGET_EITHER"
6048   "
6049   if (TARGET_ARM)
6050     {
6051       if (can_create_pseudo_p ())
6052         {
6053           if (MEM_P (operands[0]))
6054             {
6055               if (arm_arch4)
6056                 {
6057                   emit_insn (gen_storehi_single_op (operands[0], operands[1]));
6058                   DONE;
6059                 }
6060               if (CONST_INT_P (operands[1]))
6061                 emit_insn (gen_storeinthi (operands[0], operands[1]));
6062               else
6063                 {
6064                   if (MEM_P (operands[1]))
6065                     operands[1] = force_reg (HImode, operands[1]);
6066                   if (BYTES_BIG_ENDIAN)
6067                     emit_insn (gen_storehi_bigend (operands[1], operands[0]));
6068                   else
6069                    emit_insn (gen_storehi (operands[1], operands[0]));
6070                 }
6071               DONE;
6072             }
6073           /* Sign extend a constant, and keep it in an SImode reg.  */
6074           else if (CONST_INT_P (operands[1]))
6075             {
6076               rtx reg = gen_reg_rtx (SImode);
6077               HOST_WIDE_INT val = INTVAL (operands[1]) & 0xffff;
6079               /* If the constant is already valid, leave it alone.  */
6080               if (!const_ok_for_arm (val))
6081                 {
6082                   /* If setting all the top bits will make the constant 
6083                      loadable in a single instruction, then set them.  
6084                      Otherwise, sign extend the number.  */
6086                   if (const_ok_for_arm (~(val | ~0xffff)))
6087                     val |= ~0xffff;
6088                   else if (val & 0x8000)
6089                     val |= ~0xffff;
6090                 }
6092               emit_insn (gen_movsi (reg, GEN_INT (val)));
6093               operands[1] = gen_lowpart (HImode, reg);
6094             }
6095           else if (arm_arch4 && optimize && can_create_pseudo_p ()
6096                    && MEM_P (operands[1]))
6097             {
6098               rtx reg = gen_reg_rtx (SImode);
6100               emit_insn (gen_zero_extendhisi2 (reg, operands[1]));
6101               operands[1] = gen_lowpart (HImode, reg);
6102             }
6103           else if (!arm_arch4)
6104             {
6105               if (MEM_P (operands[1]))
6106                 {
6107                   rtx base;
6108                   rtx offset = const0_rtx;
6109                   rtx reg = gen_reg_rtx (SImode);
6111                   if ((REG_P (base = XEXP (operands[1], 0))
6112                        || (GET_CODE (base) == PLUS
6113                            && (CONST_INT_P (offset = XEXP (base, 1)))
6114                            && ((INTVAL(offset) & 1) != 1)
6115                            && REG_P (base = XEXP (base, 0))))
6116                       && REGNO_POINTER_ALIGN (REGNO (base)) >= 32)
6117                     {
6118                       rtx new_rtx;
6120                       new_rtx = widen_memory_access (operands[1], SImode,
6121                                                      ((INTVAL (offset) & ~3)
6122                                                       - INTVAL (offset)));
6123                       emit_insn (gen_movsi (reg, new_rtx));
6124                       if (((INTVAL (offset) & 2) != 0)
6125                           ^ (BYTES_BIG_ENDIAN ? 1 : 0))
6126                         {
6127                           rtx reg2 = gen_reg_rtx (SImode);
6129                           emit_insn (gen_lshrsi3 (reg2, reg, GEN_INT (16)));
6130                           reg = reg2;
6131                         }
6132                     }
6133                   else
6134                     emit_insn (gen_movhi_bytes (reg, operands[1]));
6136                   operands[1] = gen_lowpart (HImode, reg);
6137                }
6138            }
6139         }
6140       /* Handle loading a large integer during reload.  */
6141       else if (CONST_INT_P (operands[1])
6142                && !const_ok_for_arm (INTVAL (operands[1]))
6143                && !const_ok_for_arm (~INTVAL (operands[1])))
6144         {
6145           /* Writing a constant to memory needs a scratch, which should
6146              be handled with SECONDARY_RELOADs.  */
6147           gcc_assert (REG_P (operands[0]));
6149           operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
6150           emit_insn (gen_movsi (operands[0], operands[1]));
6151           DONE;
6152        }
6153     }
6154   else if (TARGET_THUMB2)
6155     {
6156       /* Thumb-2 can do everything except mem=mem and mem=const easily.  */
6157       if (can_create_pseudo_p ())
6158         {
6159           if (!REG_P (operands[0]))
6160             operands[1] = force_reg (HImode, operands[1]);
6161           /* Zero extend a constant, and keep it in an SImode reg.  */
6162           else if (CONST_INT_P (operands[1]))
6163             {
6164               rtx reg = gen_reg_rtx (SImode);
6165               HOST_WIDE_INT val = INTVAL (operands[1]) & 0xffff;
6167               emit_insn (gen_movsi (reg, GEN_INT (val)));
6168               operands[1] = gen_lowpart (HImode, reg);
6169             }
6170         }
6171     }
6172   else /* TARGET_THUMB1 */
6173     {
6174       if (can_create_pseudo_p ())
6175         {
6176           if (CONST_INT_P (operands[1]))
6177             {
6178               rtx reg = gen_reg_rtx (SImode);
6180               emit_insn (gen_movsi (reg, operands[1]));
6181               operands[1] = gen_lowpart (HImode, reg);
6182             }
6184           /* ??? We shouldn't really get invalid addresses here, but this can
6185              happen if we are passed a SP (never OK for HImode/QImode) or 
6186              virtual register (also rejected as illegitimate for HImode/QImode)
6187              relative address.  */
6188           /* ??? This should perhaps be fixed elsewhere, for instance, in
6189              fixup_stack_1, by checking for other kinds of invalid addresses,
6190              e.g. a bare reference to a virtual register.  This may confuse the
6191              alpha though, which must handle this case differently.  */
6192           if (MEM_P (operands[0])
6193               && !memory_address_p (GET_MODE (operands[0]),
6194                                     XEXP (operands[0], 0)))
6195             operands[0]
6196               = replace_equiv_address (operands[0],
6197                                        copy_to_reg (XEXP (operands[0], 0)));
6198    
6199           if (MEM_P (operands[1])
6200               && !memory_address_p (GET_MODE (operands[1]),
6201                                     XEXP (operands[1], 0)))
6202             operands[1]
6203               = replace_equiv_address (operands[1],
6204                                        copy_to_reg (XEXP (operands[1], 0)));
6206           if (MEM_P (operands[1]) && optimize > 0)
6207             {
6208               rtx reg = gen_reg_rtx (SImode);
6210               emit_insn (gen_zero_extendhisi2 (reg, operands[1]));
6211               operands[1] = gen_lowpart (HImode, reg);
6212             }
6214           if (MEM_P (operands[0]))
6215             operands[1] = force_reg (HImode, operands[1]);
6216         }
6217       else if (CONST_INT_P (operands[1])
6218                 && !satisfies_constraint_I (operands[1]))
6219         {
6220           /* Handle loading a large integer during reload.  */
6222           /* Writing a constant to memory needs a scratch, which should
6223              be handled with SECONDARY_RELOADs.  */
6224           gcc_assert (REG_P (operands[0]));
6226           operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
6227           emit_insn (gen_movsi (operands[0], operands[1]));
6228           DONE;
6229         }
6230     }
6231   "
6234 (define_expand "movhi_bytes"
6235   [(set (match_dup 2) (zero_extend:SI (match_operand:HI 1 "" "")))
6236    (set (match_dup 3)
6237         (zero_extend:SI (match_dup 6)))
6238    (set (match_operand:SI 0 "" "")
6239          (ior:SI (ashift:SI (match_dup 4) (const_int 8)) (match_dup 5)))]
6240   "TARGET_ARM"
6241   "
6242   {
6243     rtx mem1, mem2;
6244     rtx addr = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
6246     mem1 = change_address (operands[1], QImode, addr);
6247     mem2 = change_address (operands[1], QImode,
6248                            plus_constant (Pmode, addr, 1));
6249     operands[0] = gen_lowpart (SImode, operands[0]);
6250     operands[1] = mem1;
6251     operands[2] = gen_reg_rtx (SImode);
6252     operands[3] = gen_reg_rtx (SImode);
6253     operands[6] = mem2;
6255     if (BYTES_BIG_ENDIAN)
6256       {
6257         operands[4] = operands[2];
6258         operands[5] = operands[3];
6259       }
6260     else
6261       {
6262         operands[4] = operands[3];
6263         operands[5] = operands[2];
6264       }
6265   }"
6268 (define_expand "movhi_bigend"
6269   [(set (match_dup 2)
6270         (rotate:SI (subreg:SI (match_operand:HI 1 "memory_operand" "") 0)
6271                    (const_int 16)))
6272    (set (match_dup 3)
6273         (ashiftrt:SI (match_dup 2) (const_int 16)))
6274    (set (match_operand:HI 0 "s_register_operand" "")
6275         (match_dup 4))]
6276   "TARGET_ARM"
6277   "
6278   operands[2] = gen_reg_rtx (SImode);
6279   operands[3] = gen_reg_rtx (SImode);
6280   operands[4] = gen_lowpart (HImode, operands[3]);
6281   "
6284 ;; Pattern to recognize insn generated default case above
6285 (define_insn "*movhi_insn_arch4"
6286   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m,r")
6287         (match_operand:HI 1 "general_operand"      "rIk,K,n,r,mi"))]
6288   "TARGET_ARM
6289    && arm_arch4
6290    && (register_operand (operands[0], HImode)
6291        || register_operand (operands[1], HImode))"
6292   "@
6293    mov%?\\t%0, %1\\t%@ movhi
6294    mvn%?\\t%0, #%B1\\t%@ movhi
6295    movw%?\\t%0, %L1\\t%@ movhi
6296    str%(h%)\\t%1, %0\\t%@ movhi
6297    ldr%(h%)\\t%0, %1\\t%@ movhi"
6298   [(set_attr "predicable" "yes")
6299    (set_attr "pool_range" "*,*,*,*,256")
6300    (set_attr "neg_pool_range" "*,*,*,*,244")
6301    (set_attr "arch" "*,*,v6t2,*,*")
6302    (set_attr_alternative "type"
6303                          [(if_then_else (match_operand 1 "const_int_operand" "")
6304                                         (const_string "mov_imm" )
6305                                         (const_string "mov_reg"))
6306                           (const_string "mvn_imm")
6307                           (const_string "mov_imm")
6308                           (const_string "store1")
6309                           (const_string "load1")])]
6312 (define_insn "*movhi_bytes"
6313   [(set (match_operand:HI 0 "s_register_operand" "=r,r,r")
6314         (match_operand:HI 1 "arm_rhs_operand"  "I,rk,K"))]
6315   "TARGET_ARM"
6316   "@
6317    mov%?\\t%0, %1\\t%@ movhi
6318    mov%?\\t%0, %1\\t%@ movhi
6319    mvn%?\\t%0, #%B1\\t%@ movhi"
6320   [(set_attr "predicable" "yes")
6321    (set_attr "type" "mov_imm,mov_reg,mvn_imm")]
6323         
6324 ;; We use a DImode scratch because we may occasionally need an additional
6325 ;; temporary if the address isn't offsettable -- push_reload doesn't seem
6326 ;; to take any notice of the "o" constraints on reload_memory_operand operand.
6327 (define_expand "reload_outhi"
6328   [(parallel [(match_operand:HI 0 "arm_reload_memory_operand" "=o")
6329               (match_operand:HI 1 "s_register_operand"        "r")
6330               (match_operand:DI 2 "s_register_operand"        "=&l")])]
6331   "TARGET_EITHER"
6332   "if (TARGET_ARM)
6333      arm_reload_out_hi (operands);
6334    else
6335      thumb_reload_out_hi (operands);
6336   DONE;
6337   "
6340 (define_expand "reload_inhi"
6341   [(parallel [(match_operand:HI 0 "s_register_operand" "=r")
6342               (match_operand:HI 1 "arm_reload_memory_operand" "o")
6343               (match_operand:DI 2 "s_register_operand" "=&r")])]
6344   "TARGET_EITHER"
6345   "
6346   if (TARGET_ARM)
6347     arm_reload_in_hi (operands);
6348   else
6349     thumb_reload_out_hi (operands);
6350   DONE;
6353 (define_expand "movqi"
6354   [(set (match_operand:QI 0 "general_operand" "")
6355         (match_operand:QI 1 "general_operand" ""))]
6356   "TARGET_EITHER"
6357   "
6358   /* Everything except mem = const or mem = mem can be done easily */
6360   if (can_create_pseudo_p ())
6361     {
6362       if (CONST_INT_P (operands[1]))
6363         {
6364           rtx reg = gen_reg_rtx (SImode);
6366           /* For thumb we want an unsigned immediate, then we are more likely 
6367              to be able to use a movs insn.  */
6368           if (TARGET_THUMB)
6369             operands[1] = GEN_INT (INTVAL (operands[1]) & 255);
6371           emit_insn (gen_movsi (reg, operands[1]));
6372           operands[1] = gen_lowpart (QImode, reg);
6373         }
6375       if (TARGET_THUMB)
6376         {
6377           /* ??? We shouldn't really get invalid addresses here, but this can
6378              happen if we are passed a SP (never OK for HImode/QImode) or
6379              virtual register (also rejected as illegitimate for HImode/QImode)
6380              relative address.  */
6381           /* ??? This should perhaps be fixed elsewhere, for instance, in
6382              fixup_stack_1, by checking for other kinds of invalid addresses,
6383              e.g. a bare reference to a virtual register.  This may confuse the
6384              alpha though, which must handle this case differently.  */
6385           if (MEM_P (operands[0])
6386               && !memory_address_p (GET_MODE (operands[0]),
6387                                      XEXP (operands[0], 0)))
6388             operands[0]
6389               = replace_equiv_address (operands[0],
6390                                        copy_to_reg (XEXP (operands[0], 0)));
6391           if (MEM_P (operands[1])
6392               && !memory_address_p (GET_MODE (operands[1]),
6393                                     XEXP (operands[1], 0)))
6394              operands[1]
6395                = replace_equiv_address (operands[1],
6396                                         copy_to_reg (XEXP (operands[1], 0)));
6397         }
6399       if (MEM_P (operands[1]) && optimize > 0)
6400         {
6401           rtx reg = gen_reg_rtx (SImode);
6403           emit_insn (gen_zero_extendqisi2 (reg, operands[1]));
6404           operands[1] = gen_lowpart (QImode, reg);
6405         }
6407       if (MEM_P (operands[0]))
6408         operands[1] = force_reg (QImode, operands[1]);
6409     }
6410   else if (TARGET_THUMB
6411            && CONST_INT_P (operands[1])
6412            && !satisfies_constraint_I (operands[1]))
6413     {
6414       /* Handle loading a large integer during reload.  */
6416       /* Writing a constant to memory needs a scratch, which should
6417          be handled with SECONDARY_RELOADs.  */
6418       gcc_assert (REG_P (operands[0]));
6420       operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
6421       emit_insn (gen_movsi (operands[0], operands[1]));
6422       DONE;
6423     }
6424   "
6427 (define_insn "*arm_movqi_insn"
6428   [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,r,l,r,l,Uu,r,m")
6429         (match_operand:QI 1 "general_operand" "rk,rk,I,Py,K,Uu,l,Uh,r"))]
6430   "TARGET_32BIT
6431    && (   register_operand (operands[0], QImode)
6432        || register_operand (operands[1], QImode))"
6433   "@
6434    mov%?\\t%0, %1
6435    mov%?\\t%0, %1
6436    mov%?\\t%0, %1
6437    mov%?\\t%0, %1
6438    mvn%?\\t%0, #%B1
6439    ldr%(b%)\\t%0, %1
6440    str%(b%)\\t%1, %0
6441    ldr%(b%)\\t%0, %1
6442    str%(b%)\\t%1, %0"
6443   [(set_attr "type" "mov_reg,mov_reg,mov_imm,mov_imm,mvn_imm,load1,store1,load1,store1")
6444    (set_attr "predicable" "yes")
6445    (set_attr "predicable_short_it" "yes,yes,yes,no,no,no,no,no,no")
6446    (set_attr "arch" "t2,any,any,t2,any,t2,t2,any,any")
6447    (set_attr "length" "2,4,4,2,4,2,2,4,4")]
6450 ;; HFmode moves
6451 (define_expand "movhf"
6452   [(set (match_operand:HF 0 "general_operand" "")
6453         (match_operand:HF 1 "general_operand" ""))]
6454   "TARGET_EITHER"
6455   "
6456   if (TARGET_32BIT)
6457     {
6458       if (MEM_P (operands[0]))
6459         operands[1] = force_reg (HFmode, operands[1]);
6460     }
6461   else /* TARGET_THUMB1 */
6462     {
6463       if (can_create_pseudo_p ())
6464         {
6465            if (!REG_P (operands[0]))
6466              operands[1] = force_reg (HFmode, operands[1]);
6467         }
6468     }
6469   "
6472 (define_insn "*arm32_movhf"
6473   [(set (match_operand:HF 0 "nonimmediate_operand" "=r,m,r,r")
6474         (match_operand:HF 1 "general_operand"      " m,r,r,F"))]
6475   "TARGET_32BIT && !(TARGET_HARD_FLOAT && TARGET_FP16) && !arm_restrict_it
6476    && (   s_register_operand (operands[0], HFmode)
6477        || s_register_operand (operands[1], HFmode))"
6478   "*
6479   switch (which_alternative)
6480     {
6481     case 0:     /* ARM register from memory */
6482       return \"ldr%(h%)\\t%0, %1\\t%@ __fp16\";
6483     case 1:     /* memory from ARM register */
6484       return \"str%(h%)\\t%1, %0\\t%@ __fp16\";
6485     case 2:     /* ARM register from ARM register */
6486       return \"mov%?\\t%0, %1\\t%@ __fp16\";
6487     case 3:     /* ARM register from constant */
6488       {
6489         REAL_VALUE_TYPE r;
6490         long bits;
6491         rtx ops[4];
6493         REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
6494         bits = real_to_target (NULL, &r, HFmode);
6495         ops[0] = operands[0];
6496         ops[1] = GEN_INT (bits);
6497         ops[2] = GEN_INT (bits & 0xff00);
6498         ops[3] = GEN_INT (bits & 0x00ff);
6500         if (arm_arch_thumb2)
6501           output_asm_insn (\"movw%?\\t%0, %1\", ops);
6502         else
6503           output_asm_insn (\"mov%?\\t%0, %2\;orr%?\\t%0, %0, %3\", ops);
6504         return \"\";
6505        }
6506     default:
6507       gcc_unreachable ();
6508     }
6509   "
6510   [(set_attr "conds" "unconditional")
6511    (set_attr "type" "load1,store1,mov_reg,multiple")
6512    (set_attr "length" "4,4,4,8")
6513    (set_attr "predicable" "yes")]
6516 (define_expand "movsf"
6517   [(set (match_operand:SF 0 "general_operand" "")
6518         (match_operand:SF 1 "general_operand" ""))]
6519   "TARGET_EITHER"
6520   "
6521   if (TARGET_32BIT)
6522     {
6523       if (MEM_P (operands[0]))
6524         operands[1] = force_reg (SFmode, operands[1]);
6525     }
6526   else /* TARGET_THUMB1 */
6527     {
6528       if (can_create_pseudo_p ())
6529         {
6530            if (!REG_P (operands[0]))
6531              operands[1] = force_reg (SFmode, operands[1]);
6532         }
6533     }
6534   "
6537 ;; Transform a floating-point move of a constant into a core register into
6538 ;; an SImode operation.
6539 (define_split
6540   [(set (match_operand:SF 0 "arm_general_register_operand" "")
6541         (match_operand:SF 1 "immediate_operand" ""))]
6542   "TARGET_EITHER
6543    && reload_completed
6544    && CONST_DOUBLE_P (operands[1])"
6545   [(set (match_dup 2) (match_dup 3))]
6546   "
6547   operands[2] = gen_lowpart (SImode, operands[0]);
6548   operands[3] = gen_lowpart (SImode, operands[1]);
6549   if (operands[2] == 0 || operands[3] == 0)
6550     FAIL;
6551   "
6554 (define_insn "*arm_movsf_soft_insn"
6555   [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,m")
6556         (match_operand:SF 1 "general_operand"  "r,mE,r"))]
6557   "TARGET_32BIT
6558    && TARGET_SOFT_FLOAT
6559    && (!MEM_P (operands[0])
6560        || register_operand (operands[1], SFmode))"
6561   "@
6562    mov%?\\t%0, %1
6563    ldr%?\\t%0, %1\\t%@ float
6564    str%?\\t%1, %0\\t%@ float"
6565   [(set_attr "predicable" "yes")
6566    (set_attr "predicable_short_it" "no")
6567    (set_attr "type" "mov_reg,load1,store1")
6568    (set_attr "arm_pool_range" "*,4096,*")
6569    (set_attr "thumb2_pool_range" "*,4094,*")
6570    (set_attr "arm_neg_pool_range" "*,4084,*")
6571    (set_attr "thumb2_neg_pool_range" "*,0,*")]
6574 (define_expand "movdf"
6575   [(set (match_operand:DF 0 "general_operand" "")
6576         (match_operand:DF 1 "general_operand" ""))]
6577   "TARGET_EITHER"
6578   "
6579   if (TARGET_32BIT)
6580     {
6581       if (MEM_P (operands[0]))
6582         operands[1] = force_reg (DFmode, operands[1]);
6583     }
6584   else /* TARGET_THUMB */
6585     {
6586       if (can_create_pseudo_p ())
6587         {
6588           if (!REG_P (operands[0]))
6589             operands[1] = force_reg (DFmode, operands[1]);
6590         }
6591     }
6592   "
6595 ;; Reloading a df mode value stored in integer regs to memory can require a
6596 ;; scratch reg.
6597 (define_expand "reload_outdf"
6598   [(match_operand:DF 0 "arm_reload_memory_operand" "=o")
6599    (match_operand:DF 1 "s_register_operand" "r")
6600    (match_operand:SI 2 "s_register_operand" "=&r")]
6601   "TARGET_THUMB2"
6602   "
6603   {
6604     enum rtx_code code = GET_CODE (XEXP (operands[0], 0));
6606     if (code == REG)
6607       operands[2] = XEXP (operands[0], 0);
6608     else if (code == POST_INC || code == PRE_DEC)
6609       {
6610         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
6611         operands[1] = gen_rtx_SUBREG (DImode, operands[1], 0);
6612         emit_insn (gen_movdi (operands[0], operands[1]));
6613         DONE;
6614       }
6615     else if (code == PRE_INC)
6616       {
6617         rtx reg = XEXP (XEXP (operands[0], 0), 0);
6619         emit_insn (gen_addsi3 (reg, reg, GEN_INT (8)));
6620         operands[2] = reg;
6621       }
6622     else if (code == POST_DEC)
6623       operands[2] = XEXP (XEXP (operands[0], 0), 0);
6624     else
6625       emit_insn (gen_addsi3 (operands[2], XEXP (XEXP (operands[0], 0), 0),
6626                              XEXP (XEXP (operands[0], 0), 1)));
6628     emit_insn (gen_rtx_SET (VOIDmode,
6629                             replace_equiv_address (operands[0], operands[2]),
6630                             operands[1]));
6632     if (code == POST_DEC)
6633       emit_insn (gen_addsi3 (operands[2], operands[2], GEN_INT (-8)));
6635     DONE;
6636   }"
6639 (define_insn "*movdf_soft_insn"
6640   [(set (match_operand:DF 0 "nonimmediate_soft_df_operand" "=r,r,r,q,m")
6641         (match_operand:DF 1 "soft_df_operand" "rDa,Db,Dc,mF,q"))]
6642   "TARGET_32BIT && TARGET_SOFT_FLOAT
6643    && (   register_operand (operands[0], DFmode)
6644        || register_operand (operands[1], DFmode))"
6645   "*
6646   switch (which_alternative)
6647     {
6648     case 0:
6649     case 1:
6650     case 2:
6651       return \"#\";
6652     default:
6653       return output_move_double (operands, true, NULL);
6654     }
6655   "
6656   [(set_attr "length" "8,12,16,8,8")
6657    (set_attr "type" "multiple,multiple,multiple,load2,store2")
6658    (set_attr "arm_pool_range" "*,*,*,1020,*")
6659    (set_attr "thumb2_pool_range" "*,*,*,1018,*")
6660    (set_attr "arm_neg_pool_range" "*,*,*,1004,*")
6661    (set_attr "thumb2_neg_pool_range" "*,*,*,0,*")]
6665 ;; load- and store-multiple insns
6666 ;; The arm can load/store any set of registers, provided that they are in
6667 ;; ascending order, but these expanders assume a contiguous set.
6669 (define_expand "load_multiple"
6670   [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
6671                           (match_operand:SI 1 "" ""))
6672                      (use (match_operand:SI 2 "" ""))])]
6673   "TARGET_32BIT"
6675   HOST_WIDE_INT offset = 0;
6677   /* Support only fixed point registers.  */
6678   if (!CONST_INT_P (operands[2])
6679       || INTVAL (operands[2]) > MAX_LDM_STM_OPS
6680       || INTVAL (operands[2]) < 2
6681       || !MEM_P (operands[1])
6682       || !REG_P (operands[0])
6683       || REGNO (operands[0]) > (LAST_ARM_REGNUM - 1)
6684       || REGNO (operands[0]) + INTVAL (operands[2]) > LAST_ARM_REGNUM)
6685     FAIL;
6687   operands[3]
6688     = arm_gen_load_multiple (arm_regs_in_sequence + REGNO (operands[0]),
6689                              INTVAL (operands[2]),
6690                              force_reg (SImode, XEXP (operands[1], 0)),
6691                              FALSE, operands[1], &offset);
6694 (define_expand "store_multiple"
6695   [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
6696                           (match_operand:SI 1 "" ""))
6697                      (use (match_operand:SI 2 "" ""))])]
6698   "TARGET_32BIT"
6700   HOST_WIDE_INT offset = 0;
6702   /* Support only fixed point registers.  */
6703   if (!CONST_INT_P (operands[2])
6704       || INTVAL (operands[2]) > MAX_LDM_STM_OPS
6705       || INTVAL (operands[2]) < 2
6706       || !REG_P (operands[1])
6707       || !MEM_P (operands[0])
6708       || REGNO (operands[1]) > (LAST_ARM_REGNUM - 1)
6709       || REGNO (operands[1]) + INTVAL (operands[2]) > LAST_ARM_REGNUM)
6710     FAIL;
6712   operands[3]
6713     = arm_gen_store_multiple (arm_regs_in_sequence + REGNO (operands[1]),
6714                               INTVAL (operands[2]),
6715                               force_reg (SImode, XEXP (operands[0], 0)),
6716                               FALSE, operands[0], &offset);
6720 (define_expand "setmemsi"
6721   [(match_operand:BLK 0 "general_operand" "")
6722    (match_operand:SI 1 "const_int_operand" "")
6723    (match_operand:SI 2 "const_int_operand" "")
6724    (match_operand:SI 3 "const_int_operand" "")]
6725   "TARGET_32BIT"
6727   if (arm_gen_setmem (operands))
6728     DONE;
6730   FAIL;
6734 ;; Move a block of memory if it is word aligned and MORE than 2 words long.
6735 ;; We could let this apply for blocks of less than this, but it clobbers so
6736 ;; many registers that there is then probably a better way.
6738 (define_expand "movmemqi"
6739   [(match_operand:BLK 0 "general_operand" "")
6740    (match_operand:BLK 1 "general_operand" "")
6741    (match_operand:SI 2 "const_int_operand" "")
6742    (match_operand:SI 3 "const_int_operand" "")]
6743   ""
6744   "
6745   if (TARGET_32BIT)
6746     {
6747       if (TARGET_LDRD && current_tune->prefer_ldrd_strd
6748           && !optimize_function_for_size_p (cfun))
6749         {
6750           if (gen_movmem_ldrd_strd (operands))
6751             DONE;
6752           FAIL;
6753         }
6755       if (arm_gen_movmemqi (operands))
6756         DONE;
6757       FAIL;
6758     }
6759   else /* TARGET_THUMB1 */
6760     {
6761       if (   INTVAL (operands[3]) != 4
6762           || INTVAL (operands[2]) > 48)
6763         FAIL;
6765       thumb_expand_movmemqi (operands);
6766       DONE;
6767     }
6768   "
6772 ;; Compare & branch insns
6773 ;; The range calculations are based as follows:
6774 ;; For forward branches, the address calculation returns the address of
6775 ;; the next instruction.  This is 2 beyond the branch instruction.
6776 ;; For backward branches, the address calculation returns the address of
6777 ;; the first instruction in this pattern (cmp).  This is 2 before the branch
6778 ;; instruction for the shortest sequence, and 4 before the branch instruction
6779 ;; if we have to jump around an unconditional branch.
6780 ;; To the basic branch range the PC offset must be added (this is +4).
6781 ;; So for forward branches we have 
6782 ;;   (pos_range - pos_base_offs + pc_offs) = (pos_range - 2 + 4).
6783 ;; And for backward branches we have 
6784 ;;   (neg_range - neg_base_offs + pc_offs) = (neg_range - (-2 or -4) + 4).
6786 ;; For a 'b'       pos_range = 2046, neg_range = -2048 giving (-2040->2048).
6787 ;; For a 'b<cond>' pos_range = 254,  neg_range = -256  giving (-250 ->256).
6789 (define_expand "cbranchsi4"
6790   [(set (pc) (if_then_else
6791               (match_operator 0 "expandable_comparison_operator"
6792                [(match_operand:SI 1 "s_register_operand" "")
6793                 (match_operand:SI 2 "nonmemory_operand" "")])
6794               (label_ref (match_operand 3 "" ""))
6795               (pc)))]
6796   "TARGET_EITHER"
6797   "
6798   if (!TARGET_THUMB1)
6799     {
6800       if (!arm_validize_comparison (&operands[0], &operands[1], &operands[2]))
6801         FAIL;
6802       emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
6803                                       operands[3]));
6804       DONE;
6805     }
6806   if (thumb1_cmpneg_operand (operands[2], SImode))
6807     {
6808       emit_jump_insn (gen_cbranchsi4_scratch (NULL, operands[1], operands[2],
6809                                               operands[3], operands[0]));
6810       DONE;
6811     }
6812   if (!thumb1_cmp_operand (operands[2], SImode))
6813     operands[2] = force_reg (SImode, operands[2]);
6814   ")
6816 (define_expand "cbranchsf4"
6817   [(set (pc) (if_then_else
6818               (match_operator 0 "expandable_comparison_operator"
6819                [(match_operand:SF 1 "s_register_operand" "")
6820                 (match_operand:SF 2 "arm_float_compare_operand" "")])
6821               (label_ref (match_operand 3 "" ""))
6822               (pc)))]
6823   "TARGET_32BIT && TARGET_HARD_FLOAT"
6824   "emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
6825                                    operands[3])); DONE;"
6828 (define_expand "cbranchdf4"
6829   [(set (pc) (if_then_else
6830               (match_operator 0 "expandable_comparison_operator"
6831                [(match_operand:DF 1 "s_register_operand" "")
6832                 (match_operand:DF 2 "arm_float_compare_operand" "")])
6833               (label_ref (match_operand 3 "" ""))
6834               (pc)))]
6835   "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
6836   "emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
6837                                    operands[3])); DONE;"
6840 (define_expand "cbranchdi4"
6841   [(set (pc) (if_then_else
6842               (match_operator 0 "expandable_comparison_operator"
6843                [(match_operand:DI 1 "s_register_operand" "")
6844                 (match_operand:DI 2 "cmpdi_operand" "")])
6845               (label_ref (match_operand 3 "" ""))
6846               (pc)))]
6847   "TARGET_32BIT"
6848   "{
6849      if (!arm_validize_comparison (&operands[0], &operands[1], &operands[2]))
6850        FAIL;
6851      emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
6852                                        operands[3]));
6853      DONE;
6854    }"
6857 ;; Comparison and test insns
6859 (define_insn "*arm_cmpsi_insn"
6860   [(set (reg:CC CC_REGNUM)
6861         (compare:CC (match_operand:SI 0 "s_register_operand" "l,r,r,r,r")
6862                     (match_operand:SI 1 "arm_add_operand"    "Py,r,r,I,L")))]
6863   "TARGET_32BIT"
6864   "@
6865    cmp%?\\t%0, %1
6866    cmp%?\\t%0, %1
6867    cmp%?\\t%0, %1
6868    cmp%?\\t%0, %1
6869    cmn%?\\t%0, #%n1"
6870   [(set_attr "conds" "set")
6871    (set_attr "arch" "t2,t2,any,any,any")
6872    (set_attr "length" "2,2,4,4,4")
6873    (set_attr "predicable" "yes")
6874    (set_attr "predicable_short_it" "yes,yes,yes,no,no")
6875    (set_attr "type" "alus_imm,alus_sreg,alus_sreg,alus_imm,alus_imm")]
6878 (define_insn "*cmpsi_shiftsi"
6879   [(set (reg:CC CC_REGNUM)
6880         (compare:CC (match_operand:SI   0 "s_register_operand" "r,r,r")
6881                     (match_operator:SI  3 "shift_operator"
6882                      [(match_operand:SI 1 "s_register_operand" "r,r,r")
6883                       (match_operand:SI 2 "shift_amount_operand" "M,r,M")])))]
6884   "TARGET_32BIT"
6885   "cmp\\t%0, %1%S3"
6886   [(set_attr "conds" "set")
6887    (set_attr "shift" "1")
6888    (set_attr "arch" "32,a,a")
6889    (set_attr "type" "alus_shift_imm,alu_shift_reg,alus_shift_imm")])
6891 (define_insn "*cmpsi_shiftsi_swp"
6892   [(set (reg:CC_SWP CC_REGNUM)
6893         (compare:CC_SWP (match_operator:SI 3 "shift_operator"
6894                          [(match_operand:SI 1 "s_register_operand" "r,r,r")
6895                           (match_operand:SI 2 "shift_amount_operand" "M,r,M")])
6896                         (match_operand:SI 0 "s_register_operand" "r,r,r")))]
6897   "TARGET_32BIT"
6898   "cmp%?\\t%0, %1%S3"
6899   [(set_attr "conds" "set")
6900    (set_attr "shift" "1")
6901    (set_attr "arch" "32,a,a")
6902    (set_attr "type" "alus_shift_imm,alu_shift_reg,alus_shift_imm")])
6904 (define_insn "*arm_cmpsi_negshiftsi_si"
6905   [(set (reg:CC_Z CC_REGNUM)
6906         (compare:CC_Z
6907          (neg:SI (match_operator:SI 1 "shift_operator"
6908                     [(match_operand:SI 2 "s_register_operand" "r")
6909                      (match_operand:SI 3 "reg_or_int_operand" "rM")]))
6910          (match_operand:SI 0 "s_register_operand" "r")))]
6911   "TARGET_ARM"
6912   "cmn%?\\t%0, %2%S1"
6913   [(set_attr "conds" "set")
6914    (set (attr "type") (if_then_else (match_operand 3 "const_int_operand" "")
6915                                     (const_string "alus_shift_imm")
6916                                     (const_string "alus_shift_reg")))
6917    (set_attr "predicable" "yes")]
6920 ;; DImode comparisons.  The generic code generates branches that
6921 ;; if-conversion can not reduce to a conditional compare, so we do
6922 ;; that directly.
6924 (define_insn_and_split "*arm_cmpdi_insn"
6925   [(set (reg:CC_NCV CC_REGNUM)
6926         (compare:CC_NCV (match_operand:DI 0 "s_register_operand" "r")
6927                         (match_operand:DI 1 "arm_di_operand"       "rDi")))
6928    (clobber (match_scratch:SI 2 "=r"))]
6929   "TARGET_32BIT"
6930   "#"   ; "cmp\\t%Q0, %Q1\;sbcs\\t%2, %R0, %R1"
6931   "&& reload_completed"
6932   [(set (reg:CC CC_REGNUM)
6933         (compare:CC (match_dup 0) (match_dup 1)))
6934    (parallel [(set (reg:CC CC_REGNUM)
6935                    (compare:CC (match_dup 3) (match_dup 4)))
6936               (set (match_dup 2)
6937                    (minus:SI (match_dup 5)
6938                             (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))])]
6939   {
6940     operands[3] = gen_highpart (SImode, operands[0]);
6941     operands[0] = gen_lowpart (SImode, operands[0]);
6942     if (CONST_INT_P (operands[1]))
6943       {
6944         operands[4] = GEN_INT (~INTVAL (gen_highpart_mode (SImode,
6945                                                            DImode,
6946                                                            operands[1])));
6947         operands[5] = gen_rtx_PLUS (SImode, operands[3], operands[4]);
6948       }
6949     else
6950       {
6951         operands[4] = gen_highpart (SImode, operands[1]);
6952         operands[5] = gen_rtx_MINUS (SImode, operands[3], operands[4]);
6953       }
6954     operands[1] = gen_lowpart (SImode, operands[1]);
6955     operands[2] = gen_lowpart (SImode, operands[2]);
6956   }
6957   [(set_attr "conds" "set")
6958    (set_attr "length" "8")
6959    (set_attr "type" "multiple")]
6962 (define_insn_and_split "*arm_cmpdi_unsigned"
6963   [(set (reg:CC_CZ CC_REGNUM)
6964         (compare:CC_CZ (match_operand:DI 0 "s_register_operand" "l,r,r,r")
6965                        (match_operand:DI 1 "arm_di_operand"     "Py,r,Di,rDi")))]
6967   "TARGET_32BIT"
6968   "#"   ; "cmp\\t%R0, %R1\;it eq\;cmpeq\\t%Q0, %Q1"
6969   "&& reload_completed"
6970   [(set (reg:CC CC_REGNUM)
6971         (compare:CC (match_dup 2) (match_dup 3)))
6972    (cond_exec (eq:SI (reg:CC CC_REGNUM) (const_int 0))
6973               (set (reg:CC CC_REGNUM)
6974                    (compare:CC (match_dup 0) (match_dup 1))))]
6975   {
6976     operands[2] = gen_highpart (SImode, operands[0]);
6977     operands[0] = gen_lowpart (SImode, operands[0]);
6978     if (CONST_INT_P (operands[1]))
6979       operands[3] = gen_highpart_mode (SImode, DImode, operands[1]);
6980     else
6981       operands[3] = gen_highpart (SImode, operands[1]);
6982     operands[1] = gen_lowpart (SImode, operands[1]);
6983   }
6984   [(set_attr "conds" "set")
6985    (set_attr "enabled_for_depr_it" "yes,yes,no,*")
6986    (set_attr "arch" "t2,t2,t2,a")
6987    (set_attr "length" "6,6,10,8")
6988    (set_attr "type" "multiple")]
6991 (define_insn "*arm_cmpdi_zero"
6992   [(set (reg:CC_Z CC_REGNUM)
6993         (compare:CC_Z (match_operand:DI 0 "s_register_operand" "r")
6994                       (const_int 0)))
6995    (clobber (match_scratch:SI 1 "=r"))]
6996   "TARGET_32BIT"
6997   "orr%.\\t%1, %Q0, %R0"
6998   [(set_attr "conds" "set")
6999    (set_attr "type" "logics_reg")]
7002 ; This insn allows redundant compares to be removed by cse, nothing should
7003 ; ever appear in the output file since (set (reg x) (reg x)) is a no-op that
7004 ; is deleted later on. The match_dup will match the mode here, so that
7005 ; mode changes of the condition codes aren't lost by this even though we don't
7006 ; specify what they are.
7008 (define_insn "*deleted_compare"
7009   [(set (match_operand 0 "cc_register" "") (match_dup 0))]
7010   "TARGET_32BIT"
7011   "\\t%@ deleted compare"
7012   [(set_attr "conds" "set")
7013    (set_attr "length" "0")
7014    (set_attr "type" "no_insn")]
7018 ;; Conditional branch insns
7020 (define_expand "cbranch_cc"
7021   [(set (pc)
7022         (if_then_else (match_operator 0 "" [(match_operand 1 "" "")
7023                                             (match_operand 2 "" "")])
7024                       (label_ref (match_operand 3 "" ""))
7025                       (pc)))]
7026   "TARGET_32BIT"
7027   "operands[1] = arm_gen_compare_reg (GET_CODE (operands[0]),
7028                                       operands[1], operands[2], NULL_RTX);
7029    operands[2] = const0_rtx;"
7033 ;; Patterns to match conditional branch insns.
7036 (define_insn "arm_cond_branch"
7037   [(set (pc)
7038         (if_then_else (match_operator 1 "arm_comparison_operator"
7039                        [(match_operand 2 "cc_register" "") (const_int 0)])
7040                       (label_ref (match_operand 0 "" ""))
7041                       (pc)))]
7042   "TARGET_32BIT"
7043   "*
7044   if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
7045     {
7046       arm_ccfsm_state += 2;
7047       return \"\";
7048     }
7049   return \"b%d1\\t%l0\";
7050   "
7051   [(set_attr "conds" "use")
7052    (set_attr "type" "branch")
7053    (set (attr "length")
7054         (if_then_else
7055            (and (match_test "TARGET_THUMB2")
7056                 (and (ge (minus (match_dup 0) (pc)) (const_int -250))
7057                      (le (minus (match_dup 0) (pc)) (const_int 256))))
7058            (const_int 2)
7059            (const_int 4)))]
7062 (define_insn "*arm_cond_branch_reversed"
7063   [(set (pc)
7064         (if_then_else (match_operator 1 "arm_comparison_operator"
7065                        [(match_operand 2 "cc_register" "") (const_int 0)])
7066                       (pc)
7067                       (label_ref (match_operand 0 "" ""))))]
7068   "TARGET_32BIT"
7069   "*
7070   if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
7071     {
7072       arm_ccfsm_state += 2;
7073       return \"\";
7074     }
7075   return \"b%D1\\t%l0\";
7076   "
7077   [(set_attr "conds" "use")
7078    (set_attr "type" "branch")
7079    (set (attr "length")
7080         (if_then_else
7081            (and (match_test "TARGET_THUMB2")
7082                 (and (ge (minus (match_dup 0) (pc)) (const_int -250))
7083                      (le (minus (match_dup 0) (pc)) (const_int 256))))
7084            (const_int 2)
7085            (const_int 4)))]
7090 ; scc insns
7092 (define_expand "cstore_cc"
7093   [(set (match_operand:SI 0 "s_register_operand" "")
7094         (match_operator:SI 1 "" [(match_operand 2 "" "")
7095                                  (match_operand 3 "" "")]))]
7096   "TARGET_32BIT"
7097   "operands[2] = arm_gen_compare_reg (GET_CODE (operands[1]),
7098                                       operands[2], operands[3], NULL_RTX);
7099    operands[3] = const0_rtx;"
7102 (define_insn_and_split "*mov_scc"
7103   [(set (match_operand:SI 0 "s_register_operand" "=r")
7104         (match_operator:SI 1 "arm_comparison_operator"
7105          [(match_operand 2 "cc_register" "") (const_int 0)]))]
7106   "TARGET_ARM"
7107   "#"   ; "mov%D1\\t%0, #0\;mov%d1\\t%0, #1"
7108   "TARGET_ARM"
7109   [(set (match_dup 0)
7110         (if_then_else:SI (match_dup 1)
7111                          (const_int 1)
7112                          (const_int 0)))]
7113   ""
7114   [(set_attr "conds" "use")
7115    (set_attr "length" "8")
7116    (set_attr "type" "multiple")]
7119 (define_insn_and_split "*mov_negscc"
7120   [(set (match_operand:SI 0 "s_register_operand" "=r")
7121         (neg:SI (match_operator:SI 1 "arm_comparison_operator"
7122                  [(match_operand 2 "cc_register" "") (const_int 0)])))]
7123   "TARGET_ARM"
7124   "#"   ; "mov%D1\\t%0, #0\;mvn%d1\\t%0, #0"
7125   "TARGET_ARM"
7126   [(set (match_dup 0)
7127         (if_then_else:SI (match_dup 1)
7128                          (match_dup 3)
7129                          (const_int 0)))]
7130   {
7131     operands[3] = GEN_INT (~0);
7132   }
7133   [(set_attr "conds" "use")
7134    (set_attr "length" "8")
7135    (set_attr "type" "multiple")]
7138 (define_insn_and_split "*mov_notscc"
7139   [(set (match_operand:SI 0 "s_register_operand" "=r")
7140         (not:SI (match_operator:SI 1 "arm_comparison_operator"
7141                  [(match_operand 2 "cc_register" "") (const_int 0)])))]
7142   "TARGET_ARM"
7143   "#"   ; "mvn%D1\\t%0, #0\;mvn%d1\\t%0, #1"
7144   "TARGET_ARM"
7145   [(set (match_dup 0)
7146         (if_then_else:SI (match_dup 1)
7147                          (match_dup 3)
7148                          (match_dup 4)))]
7149   {
7150     operands[3] = GEN_INT (~1);
7151     operands[4] = GEN_INT (~0);
7152   }
7153   [(set_attr "conds" "use")
7154    (set_attr "length" "8")
7155    (set_attr "type" "multiple")]
7158 (define_expand "cstoresi4"
7159   [(set (match_operand:SI 0 "s_register_operand" "")
7160         (match_operator:SI 1 "expandable_comparison_operator"
7161          [(match_operand:SI 2 "s_register_operand" "")
7162           (match_operand:SI 3 "reg_or_int_operand" "")]))]
7163   "TARGET_32BIT || TARGET_THUMB1"
7164   "{
7165   rtx op3, scratch, scratch2;
7167   if (!TARGET_THUMB1)
7168     {
7169       if (!arm_add_operand (operands[3], SImode))
7170         operands[3] = force_reg (SImode, operands[3]);
7171       emit_insn (gen_cstore_cc (operands[0], operands[1],
7172                                 operands[2], operands[3]));
7173       DONE;
7174     }
7176   if (operands[3] == const0_rtx)
7177     {
7178       switch (GET_CODE (operands[1]))
7179         {
7180         case EQ:
7181           emit_insn (gen_cstoresi_eq0_thumb1 (operands[0], operands[2]));
7182           break;
7184         case NE:
7185           emit_insn (gen_cstoresi_ne0_thumb1 (operands[0], operands[2]));
7186           break;
7188         case LE:
7189           scratch = expand_binop (SImode, add_optab, operands[2], constm1_rtx,
7190                                   NULL_RTX, 0, OPTAB_WIDEN);
7191           scratch = expand_binop (SImode, ior_optab, operands[2], scratch,
7192                                   NULL_RTX, 0, OPTAB_WIDEN);
7193           expand_binop (SImode, lshr_optab, scratch, GEN_INT (31),
7194                         operands[0], 1, OPTAB_WIDEN);
7195           break;
7197         case GE:
7198           scratch = expand_unop (SImode, one_cmpl_optab, operands[2],
7199                                  NULL_RTX, 1);
7200           expand_binop (SImode, lshr_optab, scratch, GEN_INT (31),
7201                         NULL_RTX, 1, OPTAB_WIDEN);
7202           break;
7204         case GT:
7205           scratch = expand_binop (SImode, ashr_optab, operands[2],
7206                                   GEN_INT (31), NULL_RTX, 0, OPTAB_WIDEN);
7207           scratch = expand_binop (SImode, sub_optab, scratch, operands[2],
7208                                   NULL_RTX, 0, OPTAB_WIDEN);
7209           expand_binop (SImode, lshr_optab, scratch, GEN_INT (31), operands[0],
7210                         0, OPTAB_WIDEN);
7211           break;
7213         /* LT is handled by generic code.  No need for unsigned with 0.  */
7214         default:
7215           FAIL;
7216         }
7217       DONE;
7218     }
7220   switch (GET_CODE (operands[1]))
7221     {
7222     case EQ:
7223       scratch = expand_binop (SImode, sub_optab, operands[2], operands[3],
7224                               NULL_RTX, 0, OPTAB_WIDEN);
7225       emit_insn (gen_cstoresi_eq0_thumb1 (operands[0], scratch));
7226       break;
7228     case NE:
7229       scratch = expand_binop (SImode, sub_optab, operands[2], operands[3],
7230                               NULL_RTX, 0, OPTAB_WIDEN);
7231       emit_insn (gen_cstoresi_ne0_thumb1 (operands[0], scratch));
7232       break;
7234     case LE:
7235       op3 = force_reg (SImode, operands[3]);
7237       scratch = expand_binop (SImode, lshr_optab, operands[2], GEN_INT (31),
7238                               NULL_RTX, 1, OPTAB_WIDEN);
7239       scratch2 = expand_binop (SImode, ashr_optab, op3, GEN_INT (31),
7240                               NULL_RTX, 0, OPTAB_WIDEN);
7241       emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch2,
7242                                           op3, operands[2]));
7243       break;
7245     case GE:
7246       op3 = operands[3];
7247       if (!thumb1_cmp_operand (op3, SImode))
7248         op3 = force_reg (SImode, op3);
7249       scratch = expand_binop (SImode, ashr_optab, operands[2], GEN_INT (31),
7250                               NULL_RTX, 0, OPTAB_WIDEN);
7251       scratch2 = expand_binop (SImode, lshr_optab, op3, GEN_INT (31),
7252                                NULL_RTX, 1, OPTAB_WIDEN);
7253       emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch2,
7254                                           operands[2], op3));
7255       break;
7257     case LEU:
7258       op3 = force_reg (SImode, operands[3]);
7259       scratch = force_reg (SImode, const0_rtx);
7260       emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch,
7261                                           op3, operands[2]));
7262       break;
7264     case GEU:
7265       op3 = operands[3];
7266       if (!thumb1_cmp_operand (op3, SImode))
7267         op3 = force_reg (SImode, op3);
7268       scratch = force_reg (SImode, const0_rtx);
7269       emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch,
7270                                           operands[2], op3));
7271       break;
7273     case LTU:
7274       op3 = operands[3];
7275       if (!thumb1_cmp_operand (op3, SImode))
7276         op3 = force_reg (SImode, op3);
7277       scratch = gen_reg_rtx (SImode);
7278       emit_insn (gen_cstoresi_ltu_thumb1 (operands[0], operands[2], op3));
7279       break;
7281     case GTU:
7282       op3 = force_reg (SImode, operands[3]);
7283       scratch = gen_reg_rtx (SImode);
7284       emit_insn (gen_cstoresi_ltu_thumb1 (operands[0], op3, operands[2]));
7285       break;
7287     /* No good sequences for GT, LT.  */
7288     default:
7289       FAIL;
7290     }
7291   DONE;
7294 (define_expand "cstoresf4"
7295   [(set (match_operand:SI 0 "s_register_operand" "")
7296         (match_operator:SI 1 "expandable_comparison_operator"
7297          [(match_operand:SF 2 "s_register_operand" "")
7298           (match_operand:SF 3 "arm_float_compare_operand" "")]))]
7299   "TARGET_32BIT && TARGET_HARD_FLOAT"
7300   "emit_insn (gen_cstore_cc (operands[0], operands[1],
7301                              operands[2], operands[3])); DONE;"
7304 (define_expand "cstoredf4"
7305   [(set (match_operand:SI 0 "s_register_operand" "")
7306         (match_operator:SI 1 "expandable_comparison_operator"
7307          [(match_operand:DF 2 "s_register_operand" "")
7308           (match_operand:DF 3 "arm_float_compare_operand" "")]))]
7309   "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
7310   "emit_insn (gen_cstore_cc (operands[0], operands[1],
7311                              operands[2], operands[3])); DONE;"
7314 (define_expand "cstoredi4"
7315   [(set (match_operand:SI 0 "s_register_operand" "")
7316         (match_operator:SI 1 "expandable_comparison_operator"
7317          [(match_operand:DI 2 "s_register_operand" "")
7318           (match_operand:DI 3 "cmpdi_operand" "")]))]
7319   "TARGET_32BIT"
7320   "{
7321      if (!arm_validize_comparison (&operands[1],
7322                                    &operands[2],
7323                                    &operands[3]))
7324        FAIL;
7325      emit_insn (gen_cstore_cc (operands[0], operands[1], operands[2],
7326                                  operands[3]));
7327      DONE;
7328    }"
7332 ;; Conditional move insns
7334 (define_expand "movsicc"
7335   [(set (match_operand:SI 0 "s_register_operand" "")
7336         (if_then_else:SI (match_operand 1 "expandable_comparison_operator" "")
7337                          (match_operand:SI 2 "arm_not_operand" "")
7338                          (match_operand:SI 3 "arm_not_operand" "")))]
7339   "TARGET_32BIT"
7340   "
7341   {
7342     enum rtx_code code;
7343     rtx ccreg;
7345     if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0), 
7346                                   &XEXP (operands[1], 1)))
7347       FAIL;
7348     
7349     code = GET_CODE (operands[1]);
7350     ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
7351                                  XEXP (operands[1], 1), NULL_RTX);
7352     operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7353   }"
7356 (define_expand "movsfcc"
7357   [(set (match_operand:SF 0 "s_register_operand" "")
7358         (if_then_else:SF (match_operand 1 "arm_cond_move_operator" "")
7359                          (match_operand:SF 2 "s_register_operand" "")
7360                          (match_operand:SF 3 "s_register_operand" "")))]
7361   "TARGET_32BIT && TARGET_HARD_FLOAT"
7362   "
7363   {
7364     enum rtx_code code = GET_CODE (operands[1]);
7365     rtx ccreg;
7367     if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0), 
7368                                   &XEXP (operands[1], 1)))
7369        FAIL;
7371     code = GET_CODE (operands[1]);
7372     ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
7373                                  XEXP (operands[1], 1), NULL_RTX);
7374     operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7375   }"
7378 (define_expand "movdfcc"
7379   [(set (match_operand:DF 0 "s_register_operand" "")
7380         (if_then_else:DF (match_operand 1 "arm_cond_move_operator" "")
7381                          (match_operand:DF 2 "s_register_operand" "")
7382                          (match_operand:DF 3 "s_register_operand" "")))]
7383   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
7384   "
7385   {
7386     enum rtx_code code = GET_CODE (operands[1]);
7387     rtx ccreg;
7389     if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0), 
7390                                   &XEXP (operands[1], 1)))
7391        FAIL;
7392     code = GET_CODE (operands[1]);
7393     ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
7394                                  XEXP (operands[1], 1), NULL_RTX);
7395     operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7396   }"
7399 (define_insn "*cmov<mode>"
7400     [(set (match_operand:SDF 0 "s_register_operand" "=<F_constraint>")
7401         (if_then_else:SDF (match_operator 1 "arm_vsel_comparison_operator"
7402                           [(match_operand 2 "cc_register" "") (const_int 0)])
7403                           (match_operand:SDF 3 "s_register_operand"
7404                                               "<F_constraint>")
7405                           (match_operand:SDF 4 "s_register_operand"
7406                                               "<F_constraint>")))]
7407   "TARGET_HARD_FLOAT && TARGET_FPU_ARMV8 <vfp_double_cond>"
7408   "*
7409   {
7410     enum arm_cond_code code = maybe_get_arm_condition_code (operands[1]);
7411     switch (code)
7412       {
7413       case ARM_GE:
7414       case ARM_GT:
7415       case ARM_EQ:
7416       case ARM_VS:
7417         return \"vsel%d1.<V_if_elem>\\t%<V_reg>0, %<V_reg>3, %<V_reg>4\";
7418       case ARM_LT:
7419       case ARM_LE:
7420       case ARM_NE:
7421       case ARM_VC:
7422         return \"vsel%D1.<V_if_elem>\\t%<V_reg>0, %<V_reg>4, %<V_reg>3\";
7423       default:
7424         gcc_unreachable ();
7425       }
7426     return \"\";
7427   }"
7428   [(set_attr "conds" "use")
7429    (set_attr "type" "fcsel")]
7432 (define_insn_and_split "*movsicc_insn"
7433   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r,r,r,r,r")
7434         (if_then_else:SI
7435          (match_operator 3 "arm_comparison_operator"
7436           [(match_operand 4 "cc_register" "") (const_int 0)])
7437          (match_operand:SI 1 "arm_not_operand" "0,0,rI,K,rI,rI,K,K")
7438          (match_operand:SI 2 "arm_not_operand" "rI,K,0,0,rI,K,rI,K")))]
7439   "TARGET_ARM"
7440   "@
7441    mov%D3\\t%0, %2
7442    mvn%D3\\t%0, #%B2
7443    mov%d3\\t%0, %1
7444    mvn%d3\\t%0, #%B1
7445    #
7446    #
7447    #
7448    #"
7449    ; alt4: mov%d3\\t%0, %1\;mov%D3\\t%0, %2
7450    ; alt5: mov%d3\\t%0, %1\;mvn%D3\\t%0, #%B2
7451    ; alt6: mvn%d3\\t%0, #%B1\;mov%D3\\t%0, %2
7452    ; alt7: mvn%d3\\t%0, #%B1\;mvn%D3\\t%0, #%B2"
7453   "&& reload_completed"
7454   [(const_int 0)]
7455   {
7456     enum rtx_code rev_code;
7457     machine_mode mode;
7458     rtx rev_cond;
7460     emit_insn (gen_rtx_COND_EXEC (VOIDmode,
7461                                   operands[3],
7462                                   gen_rtx_SET (VOIDmode,
7463                                                operands[0],
7464                                                operands[1])));
7466     rev_code = GET_CODE (operands[3]);
7467     mode = GET_MODE (operands[4]);
7468     if (mode == CCFPmode || mode == CCFPEmode)
7469       rev_code = reverse_condition_maybe_unordered (rev_code);
7470     else
7471       rev_code = reverse_condition (rev_code);
7473     rev_cond = gen_rtx_fmt_ee (rev_code,
7474                                VOIDmode,
7475                                operands[4],
7476                                const0_rtx);
7477     emit_insn (gen_rtx_COND_EXEC (VOIDmode,
7478                                   rev_cond,
7479                                   gen_rtx_SET (VOIDmode,
7480                                                operands[0],
7481                                                operands[2])));
7482     DONE;
7483   }
7484   [(set_attr "length" "4,4,4,4,8,8,8,8")
7485    (set_attr "conds" "use")
7486    (set_attr_alternative "type"
7487                          [(if_then_else (match_operand 2 "const_int_operand" "")
7488                                         (const_string "mov_imm")
7489                                         (const_string "mov_reg"))
7490                           (const_string "mvn_imm")
7491                           (if_then_else (match_operand 1 "const_int_operand" "")
7492                                         (const_string "mov_imm")
7493                                         (const_string "mov_reg"))
7494                           (const_string "mvn_imm")
7495                           (const_string "mov_reg")
7496                           (const_string "mov_reg")
7497                           (const_string "mov_reg")
7498                           (const_string "mov_reg")])]
7501 (define_insn "*movsfcc_soft_insn"
7502   [(set (match_operand:SF 0 "s_register_operand" "=r,r")
7503         (if_then_else:SF (match_operator 3 "arm_comparison_operator"
7504                           [(match_operand 4 "cc_register" "") (const_int 0)])
7505                          (match_operand:SF 1 "s_register_operand" "0,r")
7506                          (match_operand:SF 2 "s_register_operand" "r,0")))]
7507   "TARGET_ARM && TARGET_SOFT_FLOAT"
7508   "@
7509    mov%D3\\t%0, %2
7510    mov%d3\\t%0, %1"
7511   [(set_attr "conds" "use")
7512    (set_attr "type" "mov_reg")]
7516 ;; Jump and linkage insns
7518 (define_expand "jump"
7519   [(set (pc)
7520         (label_ref (match_operand 0 "" "")))]
7521   "TARGET_EITHER"
7522   ""
7525 (define_insn "*arm_jump"
7526   [(set (pc)
7527         (label_ref (match_operand 0 "" "")))]
7528   "TARGET_32BIT"
7529   "*
7530   {
7531     if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
7532       {
7533         arm_ccfsm_state += 2;
7534         return \"\";
7535       }
7536     return \"b%?\\t%l0\";
7537   }
7538   "
7539   [(set_attr "predicable" "yes")
7540    (set (attr "length")
7541         (if_then_else
7542            (and (match_test "TARGET_THUMB2")
7543                 (and (ge (minus (match_dup 0) (pc)) (const_int -2044))
7544                      (le (minus (match_dup 0) (pc)) (const_int 2048))))
7545            (const_int 2)
7546            (const_int 4)))
7547    (set_attr "type" "branch")]
7550 (define_expand "call"
7551   [(parallel [(call (match_operand 0 "memory_operand" "")
7552                     (match_operand 1 "general_operand" ""))
7553               (use (match_operand 2 "" ""))
7554               (clobber (reg:SI LR_REGNUM))])]
7555   "TARGET_EITHER"
7556   "
7557   {
7558     rtx callee, pat;
7559     
7560     /* In an untyped call, we can get NULL for operand 2.  */
7561     if (operands[2] == NULL_RTX)
7562       operands[2] = const0_rtx;
7563       
7564     /* Decide if we should generate indirect calls by loading the
7565        32-bit address of the callee into a register before performing the
7566        branch and link.  */
7567     callee = XEXP (operands[0], 0);
7568     if (GET_CODE (callee) == SYMBOL_REF
7569         ? arm_is_long_call_p (SYMBOL_REF_DECL (callee))
7570         : !REG_P (callee))
7571       XEXP (operands[0], 0) = force_reg (Pmode, callee);
7573     pat = gen_call_internal (operands[0], operands[1], operands[2]);
7574     arm_emit_call_insn (pat, XEXP (operands[0], 0), false);
7575     DONE;
7576   }"
7579 (define_expand "call_internal"
7580   [(parallel [(call (match_operand 0 "memory_operand" "")
7581                     (match_operand 1 "general_operand" ""))
7582               (use (match_operand 2 "" ""))
7583               (clobber (reg:SI LR_REGNUM))])])
7585 (define_insn "*call_reg_armv5"
7586   [(call (mem:SI (match_operand:SI 0 "s_register_operand" "r"))
7587          (match_operand 1 "" ""))
7588    (use (match_operand 2 "" ""))
7589    (clobber (reg:SI LR_REGNUM))]
7590   "TARGET_ARM && arm_arch5 && !SIBLING_CALL_P (insn)"
7591   "blx%?\\t%0"
7592   [(set_attr "type" "call")]
7595 (define_insn "*call_reg_arm"
7596   [(call (mem:SI (match_operand:SI 0 "s_register_operand" "r"))
7597          (match_operand 1 "" ""))
7598    (use (match_operand 2 "" ""))
7599    (clobber (reg:SI LR_REGNUM))]
7600   "TARGET_ARM && !arm_arch5 && !SIBLING_CALL_P (insn)"
7601   "*
7602   return output_call (operands);
7603   "
7604   ;; length is worst case, normally it is only two
7605   [(set_attr "length" "12")
7606    (set_attr "type" "call")]
7610 ;; Note: not used for armv5+ because the sequence used (ldr pc, ...) is not
7611 ;; considered a function call by the branch predictor of some cores (PR40887).
7612 ;; Falls back to blx rN (*call_reg_armv5).
7614 (define_insn "*call_mem"
7615   [(call (mem:SI (match_operand:SI 0 "call_memory_operand" "m"))
7616          (match_operand 1 "" ""))
7617    (use (match_operand 2 "" ""))
7618    (clobber (reg:SI LR_REGNUM))]
7619   "TARGET_ARM && !arm_arch5 && !SIBLING_CALL_P (insn)"
7620   "*
7621   return output_call_mem (operands);
7622   "
7623   [(set_attr "length" "12")
7624    (set_attr "type" "call")]
7627 (define_expand "call_value"
7628   [(parallel [(set (match_operand       0 "" "")
7629                    (call (match_operand 1 "memory_operand" "")
7630                          (match_operand 2 "general_operand" "")))
7631               (use (match_operand 3 "" ""))
7632               (clobber (reg:SI LR_REGNUM))])]
7633   "TARGET_EITHER"
7634   "
7635   {
7636     rtx pat, callee;
7637     
7638     /* In an untyped call, we can get NULL for operand 2.  */
7639     if (operands[3] == 0)
7640       operands[3] = const0_rtx;
7641       
7642     /* Decide if we should generate indirect calls by loading the
7643        32-bit address of the callee into a register before performing the
7644        branch and link.  */
7645     callee = XEXP (operands[1], 0);
7646     if (GET_CODE (callee) == SYMBOL_REF
7647         ? arm_is_long_call_p (SYMBOL_REF_DECL (callee))
7648         : !REG_P (callee))
7649       XEXP (operands[1], 0) = force_reg (Pmode, callee);
7651     pat = gen_call_value_internal (operands[0], operands[1],
7652                                    operands[2], operands[3]);
7653     arm_emit_call_insn (pat, XEXP (operands[1], 0), false);
7654     DONE;
7655   }"
7658 (define_expand "call_value_internal"
7659   [(parallel [(set (match_operand       0 "" "")
7660                    (call (match_operand 1 "memory_operand" "")
7661                          (match_operand 2 "general_operand" "")))
7662               (use (match_operand 3 "" ""))
7663               (clobber (reg:SI LR_REGNUM))])])
7665 (define_insn "*call_value_reg_armv5"
7666   [(set (match_operand 0 "" "")
7667         (call (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
7668               (match_operand 2 "" "")))
7669    (use (match_operand 3 "" ""))
7670    (clobber (reg:SI LR_REGNUM))]
7671   "TARGET_ARM && arm_arch5 && !SIBLING_CALL_P (insn)"
7672   "blx%?\\t%1"
7673   [(set_attr "type" "call")]
7676 (define_insn "*call_value_reg_arm"
7677   [(set (match_operand 0 "" "")
7678         (call (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
7679               (match_operand 2 "" "")))
7680    (use (match_operand 3 "" ""))
7681    (clobber (reg:SI LR_REGNUM))]
7682   "TARGET_ARM && !arm_arch5 && !SIBLING_CALL_P (insn)"
7683   "*
7684   return output_call (&operands[1]);
7685   "
7686   [(set_attr "length" "12")
7687    (set_attr "type" "call")]
7690 ;; Note: see *call_mem
7692 (define_insn "*call_value_mem"
7693   [(set (match_operand 0 "" "")
7694         (call (mem:SI (match_operand:SI 1 "call_memory_operand" "m"))
7695               (match_operand 2 "" "")))
7696    (use (match_operand 3 "" ""))
7697    (clobber (reg:SI LR_REGNUM))]
7698   "TARGET_ARM && !arm_arch5 && (!CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
7699    && !SIBLING_CALL_P (insn)"
7700   "*
7701   return output_call_mem (&operands[1]);
7702   "
7703   [(set_attr "length" "12")
7704    (set_attr "type" "call")]
7707 ;; Allow calls to SYMBOL_REFs specially as they are not valid general addresses
7708 ;; The 'a' causes the operand to be treated as an address, i.e. no '#' output.
7710 (define_insn "*call_symbol"
7711   [(call (mem:SI (match_operand:SI 0 "" ""))
7712          (match_operand 1 "" ""))
7713    (use (match_operand 2 "" ""))
7714    (clobber (reg:SI LR_REGNUM))]
7715   "TARGET_32BIT
7716    && !SIBLING_CALL_P (insn)
7717    && (GET_CODE (operands[0]) == SYMBOL_REF)
7718    && !arm_is_long_call_p (SYMBOL_REF_DECL (operands[0]))"
7719   "*
7720   {
7721     return NEED_PLT_RELOC ? \"bl%?\\t%a0(PLT)\" : \"bl%?\\t%a0\";
7722   }"
7723   [(set_attr "type" "call")]
7726 (define_insn "*call_value_symbol"
7727   [(set (match_operand 0 "" "")
7728         (call (mem:SI (match_operand:SI 1 "" ""))
7729         (match_operand:SI 2 "" "")))
7730    (use (match_operand 3 "" ""))
7731    (clobber (reg:SI LR_REGNUM))]
7732   "TARGET_32BIT
7733    && !SIBLING_CALL_P (insn)
7734    && (GET_CODE (operands[1]) == SYMBOL_REF)
7735    && !arm_is_long_call_p (SYMBOL_REF_DECL (operands[1]))"
7736   "*
7737   {
7738     return NEED_PLT_RELOC ? \"bl%?\\t%a1(PLT)\" : \"bl%?\\t%a1\";
7739   }"
7740   [(set_attr "type" "call")]
7743 (define_expand "sibcall_internal"
7744   [(parallel [(call (match_operand 0 "memory_operand" "")
7745                     (match_operand 1 "general_operand" ""))
7746               (return)
7747               (use (match_operand 2 "" ""))])])
7749 ;; We may also be able to do sibcalls for Thumb, but it's much harder...
7750 (define_expand "sibcall"
7751   [(parallel [(call (match_operand 0 "memory_operand" "")
7752                     (match_operand 1 "general_operand" ""))
7753               (return)
7754               (use (match_operand 2 "" ""))])]
7755   "TARGET_32BIT"
7756   "
7757   {
7758     rtx pat;
7760     if ((!REG_P (XEXP (operands[0], 0))
7761          && GET_CODE (XEXP (operands[0], 0)) != SYMBOL_REF)
7762         || (GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
7763             && arm_is_long_call_p (SYMBOL_REF_DECL (XEXP (operands[0], 0)))))
7764      XEXP (operands[0], 0) = force_reg (SImode, XEXP (operands[0], 0));
7766     if (operands[2] == NULL_RTX)
7767       operands[2] = const0_rtx;
7769     pat = gen_sibcall_internal (operands[0], operands[1], operands[2]);
7770     arm_emit_call_insn (pat, operands[0], true);
7771     DONE;
7772   }"
7775 (define_expand "sibcall_value_internal"
7776   [(parallel [(set (match_operand 0 "" "")
7777                    (call (match_operand 1 "memory_operand" "")
7778                          (match_operand 2 "general_operand" "")))
7779               (return)
7780               (use (match_operand 3 "" ""))])])
7782 (define_expand "sibcall_value"
7783   [(parallel [(set (match_operand 0 "" "")
7784                    (call (match_operand 1 "memory_operand" "")
7785                          (match_operand 2 "general_operand" "")))
7786               (return)
7787               (use (match_operand 3 "" ""))])]
7788   "TARGET_32BIT"
7789   "
7790   {
7791     rtx pat;
7793     if ((!REG_P (XEXP (operands[1], 0))
7794          && GET_CODE (XEXP (operands[1], 0)) != SYMBOL_REF)
7795         || (GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
7796             && arm_is_long_call_p (SYMBOL_REF_DECL (XEXP (operands[1], 0)))))
7797      XEXP (operands[1], 0) = force_reg (SImode, XEXP (operands[1], 0));
7799     if (operands[3] == NULL_RTX)
7800       operands[3] = const0_rtx;
7802     pat = gen_sibcall_value_internal (operands[0], operands[1],
7803                                       operands[2], operands[3]);
7804     arm_emit_call_insn (pat, operands[1], true);
7805     DONE;
7806   }"
7809 (define_insn "*sibcall_insn"
7810  [(call (mem:SI (match_operand:SI 0 "call_insn_operand" "Cs, US"))
7811         (match_operand 1 "" ""))
7812   (return)
7813   (use (match_operand 2 "" ""))]
7814   "TARGET_32BIT && SIBLING_CALL_P (insn)"
7815   "*
7816   if (which_alternative == 1)
7817     return NEED_PLT_RELOC ? \"b%?\\t%a0(PLT)\" : \"b%?\\t%a0\";
7818   else
7819     {
7820       if (arm_arch5 || arm_arch4t)
7821         return \"bx%?\\t%0\\t%@ indirect register sibling call\";
7822       else
7823         return \"mov%?\\t%|pc, %0\\t%@ indirect register sibling call\";
7824     }
7825   "
7826   [(set_attr "type" "call")]
7829 (define_insn "*sibcall_value_insn"
7830  [(set (match_operand 0 "" "")
7831        (call (mem:SI (match_operand:SI 1 "call_insn_operand" "Cs,US"))
7832              (match_operand 2 "" "")))
7833   (return)
7834   (use (match_operand 3 "" ""))]
7835   "TARGET_32BIT && SIBLING_CALL_P (insn)"
7836   "*
7837   if (which_alternative == 1)
7838    return NEED_PLT_RELOC ? \"b%?\\t%a1(PLT)\" : \"b%?\\t%a1\";
7839   else
7840     {
7841       if (arm_arch5 || arm_arch4t)
7842         return \"bx%?\\t%1\";
7843       else
7844         return \"mov%?\\t%|pc, %1\\t@ indirect sibling call \";
7845     }
7846   "
7847   [(set_attr "type" "call")]
7850 (define_expand "<return_str>return"
7851   [(RETURNS)]
7852   "(TARGET_ARM || (TARGET_THUMB2
7853                    && ARM_FUNC_TYPE (arm_current_func_type ()) == ARM_FT_NORMAL
7854                    && !IS_STACKALIGN (arm_current_func_type ())))
7855     <return_cond_false>"
7856   "
7857   {
7858     if (TARGET_THUMB2)
7859       {
7860         thumb2_expand_return (<return_simple_p>);
7861         DONE;
7862       }
7863   }
7864   "
7867 ;; Often the return insn will be the same as loading from memory, so set attr
7868 (define_insn "*arm_return"
7869   [(return)]
7870   "TARGET_ARM && USE_RETURN_INSN (FALSE)"
7871   "*
7872   {
7873     if (arm_ccfsm_state == 2)
7874       {
7875         arm_ccfsm_state += 2;
7876         return \"\";
7877       }
7878     return output_return_instruction (const_true_rtx, true, false, false);
7879   }"
7880   [(set_attr "type" "load1")
7881    (set_attr "length" "12")
7882    (set_attr "predicable" "yes")]
7885 (define_insn "*cond_<return_str>return"
7886   [(set (pc)
7887         (if_then_else (match_operator 0 "arm_comparison_operator"
7888                        [(match_operand 1 "cc_register" "") (const_int 0)])
7889                       (RETURNS)
7890                       (pc)))]
7891   "TARGET_ARM  <return_cond_true>"
7892   "*
7893   {
7894     if (arm_ccfsm_state == 2)
7895       {
7896         arm_ccfsm_state += 2;
7897         return \"\";
7898       }
7899     return output_return_instruction (operands[0], true, false,
7900                                       <return_simple_p>);
7901   }"
7902   [(set_attr "conds" "use")
7903    (set_attr "length" "12")
7904    (set_attr "type" "load1")]
7907 (define_insn "*cond_<return_str>return_inverted"
7908   [(set (pc)
7909         (if_then_else (match_operator 0 "arm_comparison_operator"
7910                        [(match_operand 1 "cc_register" "") (const_int 0)])
7911                       (pc)
7912                       (RETURNS)))]
7913   "TARGET_ARM <return_cond_true>"
7914   "*
7915   {
7916     if (arm_ccfsm_state == 2)
7917       {
7918         arm_ccfsm_state += 2;
7919         return \"\";
7920       }
7921     return output_return_instruction (operands[0], true, true,
7922                                       <return_simple_p>);
7923   }"
7924   [(set_attr "conds" "use")
7925    (set_attr "length" "12")
7926    (set_attr "type" "load1")]
7929 (define_insn "*arm_simple_return"
7930   [(simple_return)]
7931   "TARGET_ARM"
7932   "*
7933   {
7934     if (arm_ccfsm_state == 2)
7935       {
7936         arm_ccfsm_state += 2;
7937         return \"\";
7938       }
7939     return output_return_instruction (const_true_rtx, true, false, true);
7940   }"
7941   [(set_attr "type" "branch")
7942    (set_attr "length" "4")
7943    (set_attr "predicable" "yes")]
7946 ;; Generate a sequence of instructions to determine if the processor is
7947 ;; in 26-bit or 32-bit mode, and return the appropriate return address
7948 ;; mask.
7950 (define_expand "return_addr_mask"
7951   [(set (match_dup 1)
7952       (compare:CC_NOOV (unspec [(const_int 0)] UNSPEC_CHECK_ARCH)
7953                        (const_int 0)))
7954    (set (match_operand:SI 0 "s_register_operand" "")
7955       (if_then_else:SI (eq (match_dup 1) (const_int 0))
7956                        (const_int -1)
7957                        (const_int 67108860)))] ; 0x03fffffc
7958   "TARGET_ARM"
7959   "
7960   operands[1] = gen_rtx_REG (CC_NOOVmode, CC_REGNUM);
7961   ")
7963 (define_insn "*check_arch2"
7964   [(set (match_operand:CC_NOOV 0 "cc_register" "")
7965       (compare:CC_NOOV (unspec [(const_int 0)] UNSPEC_CHECK_ARCH)
7966                        (const_int 0)))]
7967   "TARGET_ARM"
7968   "teq\\t%|r0, %|r0\;teq\\t%|pc, %|pc"
7969   [(set_attr "length" "8")
7970    (set_attr "conds" "set")
7971    (set_attr "type" "multiple")]
7974 ;; Call subroutine returning any type.
7976 (define_expand "untyped_call"
7977   [(parallel [(call (match_operand 0 "" "")
7978                     (const_int 0))
7979               (match_operand 1 "" "")
7980               (match_operand 2 "" "")])]
7981   "TARGET_EITHER"
7982   "
7983   {
7984     int i;
7985     rtx par = gen_rtx_PARALLEL (VOIDmode,
7986                                 rtvec_alloc (XVECLEN (operands[2], 0)));
7987     rtx addr = gen_reg_rtx (Pmode);
7988     rtx mem;
7989     int size = 0;
7991     emit_move_insn (addr, XEXP (operands[1], 0));
7992     mem = change_address (operands[1], BLKmode, addr);
7994     for (i = 0; i < XVECLEN (operands[2], 0); i++)
7995       {
7996         rtx src = SET_SRC (XVECEXP (operands[2], 0, i));
7998         /* Default code only uses r0 as a return value, but we could
7999            be using anything up to 4 registers.  */
8000         if (REGNO (src) == R0_REGNUM)
8001           src = gen_rtx_REG (TImode, R0_REGNUM);
8003         XVECEXP (par, 0, i) = gen_rtx_EXPR_LIST (VOIDmode, src,
8004                                                  GEN_INT (size));
8005         size += GET_MODE_SIZE (GET_MODE (src));
8006       }
8008     emit_call_insn (GEN_CALL_VALUE (par, operands[0], const0_rtx, NULL,
8009                                     const0_rtx));
8011     size = 0;
8013     for (i = 0; i < XVECLEN (par, 0); i++)
8014       {
8015         HOST_WIDE_INT offset = 0;
8016         rtx reg = XEXP (XVECEXP (par, 0, i), 0);
8018         if (size != 0)
8019           emit_move_insn (addr, plus_constant (Pmode, addr, size));
8021         mem = change_address (mem, GET_MODE (reg), NULL);
8022         if (REGNO (reg) == R0_REGNUM)
8023           {
8024             /* On thumb we have to use a write-back instruction.  */
8025             emit_insn (arm_gen_store_multiple (arm_regs_in_sequence, 4, addr,
8026                        TARGET_THUMB ? TRUE : FALSE, mem, &offset));
8027             size = TARGET_ARM ? 16 : 0;
8028           }
8029         else
8030           {
8031             emit_move_insn (mem, reg);
8032             size = GET_MODE_SIZE (GET_MODE (reg));
8033           }
8034       }
8036     /* The optimizer does not know that the call sets the function value
8037        registers we stored in the result block.  We avoid problems by
8038        claiming that all hard registers are used and clobbered at this
8039        point.  */
8040     emit_insn (gen_blockage ());
8042     DONE;
8043   }"
8046 (define_expand "untyped_return"
8047   [(match_operand:BLK 0 "memory_operand" "")
8048    (match_operand 1 "" "")]
8049   "TARGET_EITHER"
8050   "
8051   {
8052     int i;
8053     rtx addr = gen_reg_rtx (Pmode);
8054     rtx mem;
8055     int size = 0;
8057     emit_move_insn (addr, XEXP (operands[0], 0));
8058     mem = change_address (operands[0], BLKmode, addr);
8060     for (i = 0; i < XVECLEN (operands[1], 0); i++)
8061       {
8062         HOST_WIDE_INT offset = 0;
8063         rtx reg = SET_DEST (XVECEXP (operands[1], 0, i));
8065         if (size != 0)
8066           emit_move_insn (addr, plus_constant (Pmode, addr, size));
8068         mem = change_address (mem, GET_MODE (reg), NULL);
8069         if (REGNO (reg) == R0_REGNUM)
8070           {
8071             /* On thumb we have to use a write-back instruction.  */
8072             emit_insn (arm_gen_load_multiple (arm_regs_in_sequence, 4, addr,
8073                        TARGET_THUMB ? TRUE : FALSE, mem, &offset));
8074             size = TARGET_ARM ? 16 : 0;
8075           }
8076         else
8077           {
8078             emit_move_insn (reg, mem);
8079             size = GET_MODE_SIZE (GET_MODE (reg));
8080           }
8081       }
8083     /* Emit USE insns before the return.  */
8084     for (i = 0; i < XVECLEN (operands[1], 0); i++)
8085       emit_use (SET_DEST (XVECEXP (operands[1], 0, i)));
8087     /* Construct the return.  */
8088     expand_naked_return ();
8090     DONE;
8091   }"
8094 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
8095 ;; all of memory.  This blocks insns from being moved across this point.
8097 (define_insn "blockage"
8098   [(unspec_volatile [(const_int 0)] VUNSPEC_BLOCKAGE)]
8099   "TARGET_EITHER"
8100   ""
8101   [(set_attr "length" "0")
8102    (set_attr "type" "block")]
8105 (define_expand "casesi"
8106   [(match_operand:SI 0 "s_register_operand" "") ; index to jump on
8107    (match_operand:SI 1 "const_int_operand" "")  ; lower bound
8108    (match_operand:SI 2 "const_int_operand" "")  ; total range
8109    (match_operand:SI 3 "" "")                   ; table label
8110    (match_operand:SI 4 "" "")]                  ; Out of range label
8111   "TARGET_32BIT || optimize_size || flag_pic"
8112   "
8113   {
8114     enum insn_code code;
8115     if (operands[1] != const0_rtx)
8116       {
8117         rtx reg = gen_reg_rtx (SImode);
8119         emit_insn (gen_addsi3 (reg, operands[0],
8120                                gen_int_mode (-INTVAL (operands[1]),
8121                                              SImode)));
8122         operands[0] = reg;
8123       }
8125     if (TARGET_ARM)
8126       code = CODE_FOR_arm_casesi_internal;
8127     else if (TARGET_THUMB1)
8128       code = CODE_FOR_thumb1_casesi_internal_pic;
8129     else if (flag_pic)
8130       code = CODE_FOR_thumb2_casesi_internal_pic;
8131     else
8132       code = CODE_FOR_thumb2_casesi_internal;
8134     if (!insn_data[(int) code].operand[1].predicate(operands[2], SImode))
8135       operands[2] = force_reg (SImode, operands[2]);
8137     emit_jump_insn (GEN_FCN ((int) code) (operands[0], operands[2],
8138                                           operands[3], operands[4]));
8139     DONE;
8140   }"
8143 ;; The USE in this pattern is needed to tell flow analysis that this is
8144 ;; a CASESI insn.  It has no other purpose.
8145 (define_insn "arm_casesi_internal"
8146   [(parallel [(set (pc)
8147                (if_then_else
8148                 (leu (match_operand:SI 0 "s_register_operand" "r")
8149                      (match_operand:SI 1 "arm_rhs_operand" "rI"))
8150                 (mem:SI (plus:SI (mult:SI (match_dup 0) (const_int 4))
8151                                  (label_ref (match_operand 2 "" ""))))
8152                 (label_ref (match_operand 3 "" ""))))
8153               (clobber (reg:CC CC_REGNUM))
8154               (use (label_ref (match_dup 2)))])]
8155   "TARGET_ARM"
8156   "*
8157     if (flag_pic)
8158       return \"cmp\\t%0, %1\;addls\\t%|pc, %|pc, %0, asl #2\;b\\t%l3\";
8159     return   \"cmp\\t%0, %1\;ldrls\\t%|pc, [%|pc, %0, asl #2]\;b\\t%l3\";
8160   "
8161   [(set_attr "conds" "clob")
8162    (set_attr "length" "12")
8163    (set_attr "type" "multiple")]
8166 (define_expand "indirect_jump"
8167   [(set (pc)
8168         (match_operand:SI 0 "s_register_operand" ""))]
8169   "TARGET_EITHER"
8170   "
8171   /* Thumb-2 doesn't have mov pc, reg.  Explicitly set the low bit of the
8172      address and use bx.  */
8173   if (TARGET_THUMB2)
8174     {
8175       rtx tmp;
8176       tmp = gen_reg_rtx (SImode);
8177       emit_insn (gen_iorsi3 (tmp, operands[0], GEN_INT(1)));
8178       operands[0] = tmp;
8179     }
8180   "
8183 ;; NB Never uses BX.
8184 (define_insn "*arm_indirect_jump"
8185   [(set (pc)
8186         (match_operand:SI 0 "s_register_operand" "r"))]
8187   "TARGET_ARM"
8188   "mov%?\\t%|pc, %0\\t%@ indirect register jump"
8189   [(set_attr "predicable" "yes")
8190    (set_attr "type" "branch")]
8193 (define_insn "*load_indirect_jump"
8194   [(set (pc)
8195         (match_operand:SI 0 "memory_operand" "m"))]
8196   "TARGET_ARM"
8197   "ldr%?\\t%|pc, %0\\t%@ indirect memory jump"
8198   [(set_attr "type" "load1")
8199    (set_attr "pool_range" "4096")
8200    (set_attr "neg_pool_range" "4084")
8201    (set_attr "predicable" "yes")]
8205 ;; Misc insns
8207 (define_insn "nop"
8208   [(const_int 0)]
8209   "TARGET_EITHER"
8210   "*
8211   if (TARGET_UNIFIED_ASM)
8212     return \"nop\";
8213   if (TARGET_ARM)
8214     return \"mov%?\\t%|r0, %|r0\\t%@ nop\";
8215   return  \"mov\\tr8, r8\";
8216   "
8217   [(set (attr "length")
8218         (if_then_else (eq_attr "is_thumb" "yes")
8219                       (const_int 2)
8220                       (const_int 4)))
8221    (set_attr "type" "mov_reg")]
8224 (define_insn "trap"
8225   [(trap_if (const_int 1) (const_int 0))]
8226   ""
8227   "*
8228   if (TARGET_ARM)
8229     return \".inst\\t0xe7f000f0\";
8230   else
8231     return \".inst\\t0xdeff\";
8232   "
8233   [(set (attr "length")
8234         (if_then_else (eq_attr "is_thumb" "yes")
8235                       (const_int 2)
8236                       (const_int 4)))
8237    (set_attr "type" "trap")
8238    (set_attr "conds" "unconditional")]
8242 ;; Patterns to allow combination of arithmetic, cond code and shifts
8244 (define_insn "*<arith_shift_insn>_multsi"
8245   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8246         (SHIFTABLE_OPS:SI
8247          (mult:SI (match_operand:SI 2 "s_register_operand" "r,r")
8248                   (match_operand:SI 3 "power_of_two_operand" ""))
8249          (match_operand:SI 1 "s_register_operand" "rk,<t2_binop0>")))]
8250   "TARGET_32BIT"
8251   "<arith_shift_insn>%?\\t%0, %1, %2, lsl %b3"
8252   [(set_attr "predicable" "yes")
8253    (set_attr "predicable_short_it" "no")
8254    (set_attr "shift" "2")
8255    (set_attr "arch" "a,t2")
8256    (set_attr "type" "alu_shift_imm")])
8258 (define_insn "*<arith_shift_insn>_shiftsi"
8259   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
8260         (SHIFTABLE_OPS:SI
8261          (match_operator:SI 2 "shift_nomul_operator"
8262           [(match_operand:SI 3 "s_register_operand" "r,r,r")
8263            (match_operand:SI 4 "shift_amount_operand" "M,M,r")])
8264          (match_operand:SI 1 "s_register_operand" "rk,<t2_binop0>,rk")))]
8265   "TARGET_32BIT && GET_CODE (operands[2]) != MULT"
8266   "<arith_shift_insn>%?\\t%0, %1, %3%S2"
8267   [(set_attr "predicable" "yes")
8268    (set_attr "predicable_short_it" "no")
8269    (set_attr "shift" "3")
8270    (set_attr "arch" "a,t2,a")
8271    (set_attr "type" "alu_shift_imm,alu_shift_imm,alu_shift_reg")])
8273 (define_split
8274   [(set (match_operand:SI 0 "s_register_operand" "")
8275         (match_operator:SI 1 "shiftable_operator"
8276          [(match_operator:SI 2 "shiftable_operator"
8277            [(match_operator:SI 3 "shift_operator"
8278              [(match_operand:SI 4 "s_register_operand" "")
8279               (match_operand:SI 5 "reg_or_int_operand" "")])
8280             (match_operand:SI 6 "s_register_operand" "")])
8281           (match_operand:SI 7 "arm_rhs_operand" "")]))
8282    (clobber (match_operand:SI 8 "s_register_operand" ""))]
8283   "TARGET_32BIT"
8284   [(set (match_dup 8)
8285         (match_op_dup 2 [(match_op_dup 3 [(match_dup 4) (match_dup 5)])
8286                          (match_dup 6)]))
8287    (set (match_dup 0)
8288         (match_op_dup 1 [(match_dup 8) (match_dup 7)]))]
8289   "")
8291 (define_insn "*arith_shiftsi_compare0"
8292   [(set (reg:CC_NOOV CC_REGNUM)
8293         (compare:CC_NOOV
8294          (match_operator:SI 1 "shiftable_operator"
8295           [(match_operator:SI 3 "shift_operator"
8296             [(match_operand:SI 4 "s_register_operand" "r,r")
8297              (match_operand:SI 5 "shift_amount_operand" "M,r")])
8298            (match_operand:SI 2 "s_register_operand" "r,r")])
8299          (const_int 0)))
8300    (set (match_operand:SI 0 "s_register_operand" "=r,r")
8301         (match_op_dup 1 [(match_op_dup 3 [(match_dup 4) (match_dup 5)])
8302                          (match_dup 2)]))]
8303   "TARGET_32BIT"
8304   "%i1%.\\t%0, %2, %4%S3"
8305   [(set_attr "conds" "set")
8306    (set_attr "shift" "4")
8307    (set_attr "arch" "32,a")
8308    (set_attr "type" "alus_shift_imm,alus_shift_reg")])
8310 (define_insn "*arith_shiftsi_compare0_scratch"
8311   [(set (reg:CC_NOOV CC_REGNUM)
8312         (compare:CC_NOOV
8313          (match_operator:SI 1 "shiftable_operator"
8314           [(match_operator:SI 3 "shift_operator"
8315             [(match_operand:SI 4 "s_register_operand" "r,r")
8316              (match_operand:SI 5 "shift_amount_operand" "M,r")])
8317            (match_operand:SI 2 "s_register_operand" "r,r")])
8318          (const_int 0)))
8319    (clobber (match_scratch:SI 0 "=r,r"))]
8320   "TARGET_32BIT"
8321   "%i1%.\\t%0, %2, %4%S3"
8322   [(set_attr "conds" "set")
8323    (set_attr "shift" "4")
8324    (set_attr "arch" "32,a")
8325    (set_attr "type" "alus_shift_imm,alus_shift_reg")])
8327 (define_insn "*sub_shiftsi"
8328   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8329         (minus:SI (match_operand:SI 1 "s_register_operand" "r,r")
8330                   (match_operator:SI 2 "shift_operator"
8331                    [(match_operand:SI 3 "s_register_operand" "r,r")
8332                     (match_operand:SI 4 "shift_amount_operand" "M,r")])))]
8333   "TARGET_32BIT"
8334   "sub%?\\t%0, %1, %3%S2"
8335   [(set_attr "predicable" "yes")
8336    (set_attr "shift" "3")
8337    (set_attr "arch" "32,a")
8338    (set_attr "type" "alus_shift_imm,alus_shift_reg")])
8340 (define_insn "*sub_shiftsi_compare0"
8341   [(set (reg:CC_NOOV CC_REGNUM)
8342         (compare:CC_NOOV
8343          (minus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
8344                    (match_operator:SI 2 "shift_operator"
8345                     [(match_operand:SI 3 "s_register_operand" "r,r,r")
8346                      (match_operand:SI 4 "shift_amount_operand" "M,r,M")]))
8347          (const_int 0)))
8348    (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
8349         (minus:SI (match_dup 1)
8350                   (match_op_dup 2 [(match_dup 3) (match_dup 4)])))]
8351   "TARGET_32BIT"
8352   "sub%.\\t%0, %1, %3%S2"
8353   [(set_attr "conds" "set")
8354    (set_attr "shift" "3")
8355    (set_attr "arch" "32,a,a")
8356    (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
8358 (define_insn "*sub_shiftsi_compare0_scratch"
8359   [(set (reg:CC_NOOV CC_REGNUM)
8360         (compare:CC_NOOV
8361          (minus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
8362                    (match_operator:SI 2 "shift_operator"
8363                     [(match_operand:SI 3 "s_register_operand" "r,r,r")
8364                      (match_operand:SI 4 "shift_amount_operand" "M,r,M")]))
8365          (const_int 0)))
8366    (clobber (match_scratch:SI 0 "=r,r,r"))]
8367   "TARGET_32BIT"
8368   "sub%.\\t%0, %1, %3%S2"
8369   [(set_attr "conds" "set")
8370    (set_attr "shift" "3")
8371    (set_attr "arch" "32,a,a")
8372    (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
8375 (define_insn_and_split "*and_scc"
8376   [(set (match_operand:SI 0 "s_register_operand" "=r")
8377         (and:SI (match_operator:SI 1 "arm_comparison_operator"
8378                  [(match_operand 2 "cc_register" "") (const_int 0)])
8379                 (match_operand:SI 3 "s_register_operand" "r")))]
8380   "TARGET_ARM"
8381   "#"   ; "mov%D1\\t%0, #0\;and%d1\\t%0, %3, #1"
8382   "&& reload_completed"
8383   [(cond_exec (match_dup 5) (set (match_dup 0) (const_int 0)))
8384    (cond_exec (match_dup 4) (set (match_dup 0)
8385                                  (and:SI (match_dup 3) (const_int 1))))]
8386   {
8387     machine_mode mode = GET_MODE (operands[2]);
8388     enum rtx_code rc = GET_CODE (operands[1]);
8390     /* Note that operands[4] is the same as operands[1],
8391        but with VOIDmode as the result. */
8392     operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
8393     if (mode == CCFPmode || mode == CCFPEmode)
8394       rc = reverse_condition_maybe_unordered (rc);
8395     else
8396       rc = reverse_condition (rc);
8397     operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
8398   }
8399   [(set_attr "conds" "use")
8400    (set_attr "type" "multiple")
8401    (set_attr "length" "8")]
8404 (define_insn_and_split "*ior_scc"
8405   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8406         (ior:SI (match_operator:SI 1 "arm_comparison_operator"
8407                  [(match_operand 2 "cc_register" "") (const_int 0)])
8408                 (match_operand:SI 3 "s_register_operand" "0,?r")))]
8409   "TARGET_ARM"
8410   "@
8411    orr%d1\\t%0, %3, #1
8412    #"
8413   "&& reload_completed
8414    && REGNO (operands [0]) != REGNO (operands[3])"
8415   ;; && which_alternative == 1
8416   ; mov%D1\\t%0, %3\;orr%d1\\t%0, %3, #1
8417   [(cond_exec (match_dup 5) (set (match_dup 0) (match_dup 3)))
8418    (cond_exec (match_dup 4) (set (match_dup 0)
8419                                  (ior:SI (match_dup 3) (const_int 1))))]
8420   {
8421     machine_mode mode = GET_MODE (operands[2]);
8422     enum rtx_code rc = GET_CODE (operands[1]);
8424     /* Note that operands[4] is the same as operands[1],
8425        but with VOIDmode as the result. */
8426     operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
8427     if (mode == CCFPmode || mode == CCFPEmode)
8428       rc = reverse_condition_maybe_unordered (rc);
8429     else
8430       rc = reverse_condition (rc);
8431     operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
8432   }
8433   [(set_attr "conds" "use")
8434    (set_attr "length" "4,8")
8435    (set_attr "type" "logic_imm,multiple")]
8438 ; A series of splitters for the compare_scc pattern below.  Note that
8439 ; order is important.
8440 (define_split
8441   [(set (match_operand:SI 0 "s_register_operand" "")
8442         (lt:SI (match_operand:SI 1 "s_register_operand" "")
8443                (const_int 0)))
8444    (clobber (reg:CC CC_REGNUM))]
8445   "TARGET_32BIT && reload_completed"
8446   [(set (match_dup 0) (lshiftrt:SI (match_dup 1) (const_int 31)))])
8448 (define_split
8449   [(set (match_operand:SI 0 "s_register_operand" "")
8450         (ge:SI (match_operand:SI 1 "s_register_operand" "")
8451                (const_int 0)))
8452    (clobber (reg:CC CC_REGNUM))]
8453   "TARGET_32BIT && reload_completed"
8454   [(set (match_dup 0) (not:SI (match_dup 1)))
8455    (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 31)))])
8457 (define_split
8458   [(set (match_operand:SI 0 "s_register_operand" "")
8459         (eq:SI (match_operand:SI 1 "s_register_operand" "")
8460                (const_int 0)))
8461    (clobber (reg:CC CC_REGNUM))]
8462   "arm_arch5 && TARGET_32BIT"
8463   [(set (match_dup 0) (clz:SI (match_dup 1)))
8464    (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
8467 (define_split
8468   [(set (match_operand:SI 0 "s_register_operand" "")
8469         (eq:SI (match_operand:SI 1 "s_register_operand" "")
8470                (const_int 0)))
8471    (clobber (reg:CC CC_REGNUM))]
8472   "TARGET_32BIT && reload_completed"
8473   [(parallel
8474     [(set (reg:CC CC_REGNUM)
8475           (compare:CC (const_int 1) (match_dup 1)))
8476      (set (match_dup 0)
8477           (minus:SI (const_int 1) (match_dup 1)))])
8478    (cond_exec (ltu:CC (reg:CC CC_REGNUM) (const_int 0))
8479               (set (match_dup 0) (const_int 0)))])
8481 (define_split
8482   [(set (match_operand:SI 0 "s_register_operand" "")
8483         (ne:SI (match_operand:SI 1 "s_register_operand" "")
8484                (match_operand:SI 2 "const_int_operand" "")))
8485    (clobber (reg:CC CC_REGNUM))]
8486   "TARGET_32BIT && reload_completed"
8487   [(parallel
8488     [(set (reg:CC CC_REGNUM)
8489           (compare:CC (match_dup 1) (match_dup 2)))
8490      (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 3)))])
8491    (cond_exec (ne:CC (reg:CC CC_REGNUM) (const_int 0))
8492               (set (match_dup 0) (const_int 1)))]
8494   operands[3] = GEN_INT (-INTVAL (operands[2]));
8497 (define_split
8498   [(set (match_operand:SI 0 "s_register_operand" "")
8499         (ne:SI (match_operand:SI 1 "s_register_operand" "")
8500                (match_operand:SI 2 "arm_add_operand" "")))
8501    (clobber (reg:CC CC_REGNUM))]
8502   "TARGET_32BIT && reload_completed"
8503   [(parallel
8504     [(set (reg:CC_NOOV CC_REGNUM)
8505           (compare:CC_NOOV (minus:SI (match_dup 1) (match_dup 2))
8506                            (const_int 0)))
8507      (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
8508    (cond_exec (ne:CC_NOOV (reg:CC_NOOV CC_REGNUM) (const_int 0))
8509               (set (match_dup 0) (const_int 1)))])
8511 (define_insn_and_split "*compare_scc"
8512   [(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts")
8513         (match_operator:SI 1 "arm_comparison_operator"
8514          [(match_operand:SI 2 "s_register_operand" "r,r")
8515           (match_operand:SI 3 "arm_add_operand" "rI,L")]))
8516    (clobber (reg:CC CC_REGNUM))]
8517   "TARGET_32BIT"
8518   "#"
8519   "&& reload_completed"
8520   [(set (reg:CC CC_REGNUM) (compare:CC (match_dup 2) (match_dup 3)))
8521    (cond_exec (match_dup 4) (set (match_dup 0) (const_int 0)))
8522    (cond_exec (match_dup 5) (set (match_dup 0) (const_int 1)))]
8524   rtx tmp1;
8525   machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
8526                                            operands[2], operands[3]);
8527   enum rtx_code rc = GET_CODE (operands[1]);
8529   tmp1 = gen_rtx_REG (mode, CC_REGNUM);
8531   operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, tmp1, const0_rtx);
8532   if (mode == CCFPmode || mode == CCFPEmode)
8533     rc = reverse_condition_maybe_unordered (rc);
8534   else
8535     rc = reverse_condition (rc);
8536   operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, tmp1, const0_rtx);
8538   [(set_attr "type" "multiple")]
8541 ;; Attempt to improve the sequence generated by the compare_scc splitters
8542 ;; not to use conditional execution.
8544 ;; Rd = (eq (reg1) (const_int0))  // ARMv5
8545 ;;      clz Rd, reg1
8546 ;;      lsr Rd, Rd, #5
8547 (define_peephole2
8548   [(set (reg:CC CC_REGNUM)
8549         (compare:CC (match_operand:SI 1 "register_operand" "")
8550                     (const_int 0)))
8551    (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
8552               (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
8553    (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
8554               (set (match_dup 0) (const_int 1)))]
8555   "arm_arch5 && TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
8556   [(set (match_dup 0) (clz:SI (match_dup 1)))
8557    (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
8560 ;; Rd = (eq (reg1) (const_int0))  // !ARMv5
8561 ;;      negs Rd, reg1
8562 ;;      adc  Rd, Rd, reg1
8563 (define_peephole2
8564   [(set (reg:CC CC_REGNUM)
8565         (compare:CC (match_operand:SI 1 "register_operand" "")
8566                     (const_int 0)))
8567    (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
8568               (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
8569    (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
8570               (set (match_dup 0) (const_int 1)))
8571    (match_scratch:SI 2 "r")]
8572   "TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
8573   [(parallel
8574     [(set (reg:CC CC_REGNUM)
8575           (compare:CC (const_int 0) (match_dup 1)))
8576      (set (match_dup 2) (minus:SI (const_int 0) (match_dup 1)))])
8577    (set (match_dup 0)
8578         (plus:SI (plus:SI (match_dup 1) (match_dup 2))
8579                  (geu:SI (reg:CC CC_REGNUM) (const_int 0))))]
8582 ;; Rd = (eq (reg1) (reg2/imm))  // ARMv5 and optimising for speed.
8583 ;;      sub  Rd, Reg1, reg2
8584 ;;      clz  Rd, Rd
8585 ;;      lsr  Rd, Rd, #5
8586 (define_peephole2
8587   [(set (reg:CC CC_REGNUM)
8588         (compare:CC (match_operand:SI 1 "register_operand" "")
8589                     (match_operand:SI 2 "arm_rhs_operand" "")))
8590    (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
8591               (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
8592    (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
8593               (set (match_dup 0) (const_int 1)))]
8594   "arm_arch5 && TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)
8595   && !(TARGET_THUMB2 && optimize_insn_for_size_p ())"
8596   [(set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))
8597    (set (match_dup 0) (clz:SI (match_dup 0)))
8598    (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
8602 ;; Rd = (eq (reg1) (reg2))      // ! ARMv5 or optimising for size.
8603 ;;      sub  T1, Reg1, reg2
8604 ;;      negs Rd, T1
8605 ;;      adc  Rd, Rd, T1
8606 (define_peephole2
8607   [(set (reg:CC CC_REGNUM)
8608         (compare:CC (match_operand:SI 1 "register_operand" "")
8609                     (match_operand:SI 2 "arm_rhs_operand" "")))
8610    (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
8611               (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
8612    (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
8613               (set (match_dup 0) (const_int 1)))
8614    (match_scratch:SI 3 "r")]
8615   "TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
8616   [(set (match_dup 3) (match_dup 4))
8617    (parallel
8618     [(set (reg:CC CC_REGNUM)
8619           (compare:CC (const_int 0) (match_dup 3)))
8620      (set (match_dup 0) (minus:SI (const_int 0) (match_dup 3)))])
8621    (set (match_dup 0)
8622         (plus:SI (plus:SI (match_dup 0) (match_dup 3))
8623                  (geu:SI (reg:CC CC_REGNUM) (const_int 0))))]
8624   "
8625   if (CONST_INT_P (operands[2]))
8626     operands[4] = plus_constant (SImode, operands[1], -INTVAL (operands[2]));
8627   else
8628     operands[4] = gen_rtx_MINUS (SImode, operands[1], operands[2]);
8629   ")
8631 (define_insn "*cond_move"
8632   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
8633         (if_then_else:SI (match_operator 3 "equality_operator"
8634                           [(match_operator 4 "arm_comparison_operator"
8635                             [(match_operand 5 "cc_register" "") (const_int 0)])
8636                            (const_int 0)])
8637                          (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
8638                          (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))]
8639   "TARGET_ARM"
8640   "*
8641     if (GET_CODE (operands[3]) == NE)
8642       {
8643         if (which_alternative != 1)
8644           output_asm_insn (\"mov%D4\\t%0, %2\", operands);
8645         if (which_alternative != 0)
8646           output_asm_insn (\"mov%d4\\t%0, %1\", operands);
8647         return \"\";
8648       }
8649     if (which_alternative != 0)
8650       output_asm_insn (\"mov%D4\\t%0, %1\", operands);
8651     if (which_alternative != 1)
8652       output_asm_insn (\"mov%d4\\t%0, %2\", operands);
8653     return \"\";
8654   "
8655   [(set_attr "conds" "use")
8656    (set_attr "type" "mov_reg,mov_reg,multiple")
8657    (set_attr "length" "4,4,8")]
8660 (define_insn "*cond_arith"
8661   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8662         (match_operator:SI 5 "shiftable_operator" 
8663          [(match_operator:SI 4 "arm_comparison_operator"
8664            [(match_operand:SI 2 "s_register_operand" "r,r")
8665             (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
8666           (match_operand:SI 1 "s_register_operand" "0,?r")]))
8667    (clobber (reg:CC CC_REGNUM))]
8668   "TARGET_ARM"
8669   "*
8670     if (GET_CODE (operands[4]) == LT && operands[3] == const0_rtx)
8671       return \"%i5\\t%0, %1, %2, lsr #31\";
8673     output_asm_insn (\"cmp\\t%2, %3\", operands);
8674     if (GET_CODE (operands[5]) == AND)
8675       output_asm_insn (\"mov%D4\\t%0, #0\", operands);
8676     else if (GET_CODE (operands[5]) == MINUS)
8677       output_asm_insn (\"rsb%D4\\t%0, %1, #0\", operands);
8678     else if (which_alternative != 0)
8679       output_asm_insn (\"mov%D4\\t%0, %1\", operands);
8680     return \"%i5%d4\\t%0, %1, #1\";
8681   "
8682   [(set_attr "conds" "clob")
8683    (set_attr "length" "12")
8684    (set_attr "type" "multiple")]
8687 (define_insn "*cond_sub"
8688   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8689         (minus:SI (match_operand:SI 1 "s_register_operand" "0,?r")
8690                   (match_operator:SI 4 "arm_comparison_operator"
8691                    [(match_operand:SI 2 "s_register_operand" "r,r")
8692                     (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
8693    (clobber (reg:CC CC_REGNUM))]
8694   "TARGET_ARM"
8695   "*
8696     output_asm_insn (\"cmp\\t%2, %3\", operands);
8697     if (which_alternative != 0)
8698       output_asm_insn (\"mov%D4\\t%0, %1\", operands);
8699     return \"sub%d4\\t%0, %1, #1\";
8700   "
8701   [(set_attr "conds" "clob")
8702    (set_attr "length" "8,12")
8703    (set_attr "type" "multiple")]
8706 (define_insn "*cmp_ite0"
8707   [(set (match_operand 6 "dominant_cc_register" "")
8708         (compare
8709          (if_then_else:SI
8710           (match_operator 4 "arm_comparison_operator"
8711            [(match_operand:SI 0 "s_register_operand"
8712                 "l,l,l,r,r,r,r,r,r")
8713             (match_operand:SI 1 "arm_add_operand"
8714                 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
8715           (match_operator:SI 5 "arm_comparison_operator"
8716            [(match_operand:SI 2 "s_register_operand"
8717                 "l,r,r,l,l,r,r,r,r")
8718             (match_operand:SI 3 "arm_add_operand"
8719                 "lPy,rI,L,lPy,lPy,rI,rI,L,L")])
8720           (const_int 0))
8721          (const_int 0)))]
8722   "TARGET_32BIT"
8723   "*
8724   {
8725     static const char * const cmp1[NUM_OF_COND_CMP][2] =
8726     {
8727       {\"cmp%d5\\t%0, %1\",
8728        \"cmp%d4\\t%2, %3\"},
8729       {\"cmn%d5\\t%0, #%n1\",
8730        \"cmp%d4\\t%2, %3\"},
8731       {\"cmp%d5\\t%0, %1\",
8732        \"cmn%d4\\t%2, #%n3\"},
8733       {\"cmn%d5\\t%0, #%n1\",
8734        \"cmn%d4\\t%2, #%n3\"}
8735     };
8736     static const char * const cmp2[NUM_OF_COND_CMP][2] =
8737     {
8738       {\"cmp\\t%2, %3\",
8739        \"cmp\\t%0, %1\"},
8740       {\"cmp\\t%2, %3\",
8741        \"cmn\\t%0, #%n1\"},
8742       {\"cmn\\t%2, #%n3\",
8743        \"cmp\\t%0, %1\"},
8744       {\"cmn\\t%2, #%n3\",
8745        \"cmn\\t%0, #%n1\"}
8746     };
8747     static const char * const ite[2] =
8748     {
8749       \"it\\t%d5\",
8750       \"it\\t%d4\"
8751     };
8752     static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
8753                                    CMP_CMP, CMN_CMP, CMP_CMP,
8754                                    CMN_CMP, CMP_CMN, CMN_CMN};
8755     int swap =
8756       comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
8758     output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
8759     if (TARGET_THUMB2) {
8760       output_asm_insn (ite[swap], operands);
8761     }
8762     output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
8763     return \"\";
8764   }"
8765   [(set_attr "conds" "set")
8766    (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
8767    (set_attr "type" "multiple")
8768    (set_attr_alternative "length"
8769       [(const_int 6)
8770        (const_int 8)
8771        (const_int 8)
8772        (const_int 8)
8773        (const_int 8)
8774        (if_then_else (eq_attr "is_thumb" "no")
8775            (const_int 8)
8776            (const_int 10))
8777        (if_then_else (eq_attr "is_thumb" "no")
8778            (const_int 8)
8779            (const_int 10))
8780        (if_then_else (eq_attr "is_thumb" "no")
8781            (const_int 8)
8782            (const_int 10))
8783        (if_then_else (eq_attr "is_thumb" "no")
8784            (const_int 8)
8785            (const_int 10))])]
8788 (define_insn "*cmp_ite1"
8789   [(set (match_operand 6 "dominant_cc_register" "")
8790         (compare
8791          (if_then_else:SI
8792           (match_operator 4 "arm_comparison_operator"
8793            [(match_operand:SI 0 "s_register_operand"
8794                 "l,l,l,r,r,r,r,r,r")
8795             (match_operand:SI 1 "arm_add_operand"
8796                 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
8797           (match_operator:SI 5 "arm_comparison_operator"
8798            [(match_operand:SI 2 "s_register_operand"
8799                 "l,r,r,l,l,r,r,r,r")
8800             (match_operand:SI 3 "arm_add_operand"
8801                 "lPy,rI,L,lPy,lPy,rI,rI,L,L")])
8802           (const_int 1))
8803          (const_int 0)))]
8804   "TARGET_32BIT"
8805   "*
8806   {
8807     static const char * const cmp1[NUM_OF_COND_CMP][2] =
8808     {
8809       {\"cmp\\t%0, %1\",
8810        \"cmp\\t%2, %3\"},
8811       {\"cmn\\t%0, #%n1\",
8812        \"cmp\\t%2, %3\"},
8813       {\"cmp\\t%0, %1\",
8814        \"cmn\\t%2, #%n3\"},
8815       {\"cmn\\t%0, #%n1\",
8816        \"cmn\\t%2, #%n3\"}
8817     };
8818     static const char * const cmp2[NUM_OF_COND_CMP][2] =
8819     {
8820       {\"cmp%d4\\t%2, %3\",
8821        \"cmp%D5\\t%0, %1\"},
8822       {\"cmp%d4\\t%2, %3\",
8823        \"cmn%D5\\t%0, #%n1\"},
8824       {\"cmn%d4\\t%2, #%n3\",
8825        \"cmp%D5\\t%0, %1\"},
8826       {\"cmn%d4\\t%2, #%n3\",
8827        \"cmn%D5\\t%0, #%n1\"}
8828     };
8829     static const char * const ite[2] =
8830     {
8831       \"it\\t%d4\",
8832       \"it\\t%D5\"
8833     };
8834     static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
8835                                    CMP_CMP, CMN_CMP, CMP_CMP,
8836                                    CMN_CMP, CMP_CMN, CMN_CMN};
8837     int swap =
8838       comparison_dominates_p (GET_CODE (operands[5]),
8839                               reverse_condition (GET_CODE (operands[4])));
8841     output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
8842     if (TARGET_THUMB2) {
8843       output_asm_insn (ite[swap], operands);
8844     }
8845     output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
8846     return \"\";
8847   }"
8848   [(set_attr "conds" "set")
8849    (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
8850    (set_attr_alternative "length"
8851       [(const_int 6)
8852        (const_int 8)
8853        (const_int 8)
8854        (const_int 8)
8855        (const_int 8)
8856        (if_then_else (eq_attr "is_thumb" "no")
8857            (const_int 8)
8858            (const_int 10))
8859        (if_then_else (eq_attr "is_thumb" "no")
8860            (const_int 8)
8861            (const_int 10))
8862        (if_then_else (eq_attr "is_thumb" "no")
8863            (const_int 8)
8864            (const_int 10))
8865        (if_then_else (eq_attr "is_thumb" "no")
8866            (const_int 8)
8867            (const_int 10))])
8868    (set_attr "type" "multiple")]
8871 (define_insn "*cmp_and"
8872   [(set (match_operand 6 "dominant_cc_register" "")
8873         (compare
8874          (and:SI
8875           (match_operator 4 "arm_comparison_operator"
8876            [(match_operand:SI 0 "s_register_operand" 
8877                 "l,l,l,r,r,r,r,r,r")
8878             (match_operand:SI 1 "arm_add_operand" 
8879                 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
8880           (match_operator:SI 5 "arm_comparison_operator"
8881            [(match_operand:SI 2 "s_register_operand" 
8882                 "l,r,r,l,l,r,r,r,r")
8883             (match_operand:SI 3 "arm_add_operand" 
8884                 "lPy,rI,L,lPy,lPy,rI,rI,L,L")]))
8885          (const_int 0)))]
8886   "TARGET_32BIT"
8887   "*
8888   {
8889     static const char *const cmp1[NUM_OF_COND_CMP][2] =
8890     {
8891       {\"cmp%d5\\t%0, %1\",
8892        \"cmp%d4\\t%2, %3\"},
8893       {\"cmn%d5\\t%0, #%n1\",
8894        \"cmp%d4\\t%2, %3\"},
8895       {\"cmp%d5\\t%0, %1\",
8896        \"cmn%d4\\t%2, #%n3\"},
8897       {\"cmn%d5\\t%0, #%n1\",
8898        \"cmn%d4\\t%2, #%n3\"}
8899     };
8900     static const char *const cmp2[NUM_OF_COND_CMP][2] =
8901     {
8902       {\"cmp\\t%2, %3\",
8903        \"cmp\\t%0, %1\"},
8904       {\"cmp\\t%2, %3\",
8905        \"cmn\\t%0, #%n1\"},
8906       {\"cmn\\t%2, #%n3\",
8907        \"cmp\\t%0, %1\"},
8908       {\"cmn\\t%2, #%n3\",
8909        \"cmn\\t%0, #%n1\"}
8910     };
8911     static const char *const ite[2] =
8912     {
8913       \"it\\t%d5\",
8914       \"it\\t%d4\"
8915     };
8916     static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
8917                                    CMP_CMP, CMN_CMP, CMP_CMP,
8918                                    CMN_CMP, CMP_CMN, CMN_CMN};
8919     int swap =
8920       comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
8922     output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
8923     if (TARGET_THUMB2) {
8924       output_asm_insn (ite[swap], operands);
8925     }
8926     output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
8927     return \"\";
8928   }"
8929   [(set_attr "conds" "set")
8930    (set_attr "predicable" "no")
8931    (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
8932    (set_attr_alternative "length"
8933       [(const_int 6)
8934        (const_int 8)
8935        (const_int 8)
8936        (const_int 8)
8937        (const_int 8)
8938        (if_then_else (eq_attr "is_thumb" "no")
8939            (const_int 8)
8940            (const_int 10))
8941        (if_then_else (eq_attr "is_thumb" "no")
8942            (const_int 8)
8943            (const_int 10))
8944        (if_then_else (eq_attr "is_thumb" "no")
8945            (const_int 8)
8946            (const_int 10))
8947        (if_then_else (eq_attr "is_thumb" "no")
8948            (const_int 8)
8949            (const_int 10))])
8950    (set_attr "type" "multiple")]
8953 (define_insn "*cmp_ior"
8954   [(set (match_operand 6 "dominant_cc_register" "")
8955         (compare
8956          (ior:SI
8957           (match_operator 4 "arm_comparison_operator"
8958            [(match_operand:SI 0 "s_register_operand"
8959                 "l,l,l,r,r,r,r,r,r")
8960             (match_operand:SI 1 "arm_add_operand"
8961                 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
8962           (match_operator:SI 5 "arm_comparison_operator"
8963            [(match_operand:SI 2 "s_register_operand"
8964                 "l,r,r,l,l,r,r,r,r")
8965             (match_operand:SI 3 "arm_add_operand"
8966                 "lPy,rI,L,lPy,lPy,rI,rI,L,L")]))
8967          (const_int 0)))]
8968   "TARGET_32BIT"
8969   "*
8970   {
8971     static const char *const cmp1[NUM_OF_COND_CMP][2] =
8972     {
8973       {\"cmp\\t%0, %1\",
8974        \"cmp\\t%2, %3\"},
8975       {\"cmn\\t%0, #%n1\",
8976        \"cmp\\t%2, %3\"},
8977       {\"cmp\\t%0, %1\",
8978        \"cmn\\t%2, #%n3\"},
8979       {\"cmn\\t%0, #%n1\",
8980        \"cmn\\t%2, #%n3\"}
8981     };
8982     static const char *const cmp2[NUM_OF_COND_CMP][2] =
8983     {
8984       {\"cmp%D4\\t%2, %3\",
8985        \"cmp%D5\\t%0, %1\"},
8986       {\"cmp%D4\\t%2, %3\",
8987        \"cmn%D5\\t%0, #%n1\"},
8988       {\"cmn%D4\\t%2, #%n3\",
8989        \"cmp%D5\\t%0, %1\"},
8990       {\"cmn%D4\\t%2, #%n3\",
8991        \"cmn%D5\\t%0, #%n1\"}
8992     };
8993     static const char *const ite[2] =
8994     {
8995       \"it\\t%D4\",
8996       \"it\\t%D5\"
8997     };
8998     static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
8999                                    CMP_CMP, CMN_CMP, CMP_CMP,
9000                                    CMN_CMP, CMP_CMN, CMN_CMN};
9001     int swap =
9002       comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
9004     output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
9005     if (TARGET_THUMB2) {
9006       output_asm_insn (ite[swap], operands);
9007     }
9008     output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
9009     return \"\";
9010   }
9011   "
9012   [(set_attr "conds" "set")
9013    (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
9014    (set_attr_alternative "length"
9015       [(const_int 6)
9016        (const_int 8)
9017        (const_int 8)
9018        (const_int 8)
9019        (const_int 8)
9020        (if_then_else (eq_attr "is_thumb" "no")
9021            (const_int 8)
9022            (const_int 10))
9023        (if_then_else (eq_attr "is_thumb" "no")
9024            (const_int 8)
9025            (const_int 10))
9026        (if_then_else (eq_attr "is_thumb" "no")
9027            (const_int 8)
9028            (const_int 10))
9029        (if_then_else (eq_attr "is_thumb" "no")
9030            (const_int 8)
9031            (const_int 10))])
9032    (set_attr "type" "multiple")]
9035 (define_insn_and_split "*ior_scc_scc"
9036   [(set (match_operand:SI 0 "s_register_operand" "=Ts")
9037         (ior:SI (match_operator:SI 3 "arm_comparison_operator"
9038                  [(match_operand:SI 1 "s_register_operand" "r")
9039                   (match_operand:SI 2 "arm_add_operand" "rIL")])
9040                 (match_operator:SI 6 "arm_comparison_operator"
9041                  [(match_operand:SI 4 "s_register_operand" "r")
9042                   (match_operand:SI 5 "arm_add_operand" "rIL")])))
9043    (clobber (reg:CC CC_REGNUM))]
9044   "TARGET_32BIT
9045    && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_OR_Y)
9046        != CCmode)"
9047   "#"
9048   "TARGET_32BIT && reload_completed"
9049   [(set (match_dup 7)
9050         (compare
9051          (ior:SI
9052           (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9053           (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9054          (const_int 0)))
9055    (set (match_dup 0) (ne:SI (match_dup 7) (const_int 0)))]
9056   "operands[7]
9057      = gen_rtx_REG (arm_select_dominance_cc_mode (operands[3], operands[6],
9058                                                   DOM_CC_X_OR_Y),
9059                     CC_REGNUM);"
9060   [(set_attr "conds" "clob")
9061    (set_attr "length" "16")
9062    (set_attr "type" "multiple")]
9065 ; If the above pattern is followed by a CMP insn, then the compare is 
9066 ; redundant, since we can rework the conditional instruction that follows.
9067 (define_insn_and_split "*ior_scc_scc_cmp"
9068   [(set (match_operand 0 "dominant_cc_register" "")
9069         (compare (ior:SI (match_operator:SI 3 "arm_comparison_operator"
9070                           [(match_operand:SI 1 "s_register_operand" "r")
9071                            (match_operand:SI 2 "arm_add_operand" "rIL")])
9072                          (match_operator:SI 6 "arm_comparison_operator"
9073                           [(match_operand:SI 4 "s_register_operand" "r")
9074                            (match_operand:SI 5 "arm_add_operand" "rIL")]))
9075                  (const_int 0)))
9076    (set (match_operand:SI 7 "s_register_operand" "=Ts")
9077         (ior:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9078                 (match_op_dup 6 [(match_dup 4) (match_dup 5)])))]
9079   "TARGET_32BIT"
9080   "#"
9081   "TARGET_32BIT && reload_completed"
9082   [(set (match_dup 0)
9083         (compare
9084          (ior:SI
9085           (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9086           (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9087          (const_int 0)))
9088    (set (match_dup 7) (ne:SI (match_dup 0) (const_int 0)))]
9089   ""
9090   [(set_attr "conds" "set")
9091    (set_attr "length" "16")
9092    (set_attr "type" "multiple")]
9095 (define_insn_and_split "*and_scc_scc"
9096   [(set (match_operand:SI 0 "s_register_operand" "=Ts")
9097         (and:SI (match_operator:SI 3 "arm_comparison_operator"
9098                  [(match_operand:SI 1 "s_register_operand" "r")
9099                   (match_operand:SI 2 "arm_add_operand" "rIL")])
9100                 (match_operator:SI 6 "arm_comparison_operator"
9101                  [(match_operand:SI 4 "s_register_operand" "r")
9102                   (match_operand:SI 5 "arm_add_operand" "rIL")])))
9103    (clobber (reg:CC CC_REGNUM))]
9104   "TARGET_32BIT
9105    && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
9106        != CCmode)"
9107   "#"
9108   "TARGET_32BIT && reload_completed
9109    && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
9110        != CCmode)"
9111   [(set (match_dup 7)
9112         (compare
9113          (and:SI
9114           (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9115           (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9116          (const_int 0)))
9117    (set (match_dup 0) (ne:SI (match_dup 7) (const_int 0)))]
9118   "operands[7]
9119      = gen_rtx_REG (arm_select_dominance_cc_mode (operands[3], operands[6],
9120                                                   DOM_CC_X_AND_Y),
9121                     CC_REGNUM);"
9122   [(set_attr "conds" "clob")
9123    (set_attr "length" "16")
9124    (set_attr "type" "multiple")]
9127 ; If the above pattern is followed by a CMP insn, then the compare is 
9128 ; redundant, since we can rework the conditional instruction that follows.
9129 (define_insn_and_split "*and_scc_scc_cmp"
9130   [(set (match_operand 0 "dominant_cc_register" "")
9131         (compare (and:SI (match_operator:SI 3 "arm_comparison_operator"
9132                           [(match_operand:SI 1 "s_register_operand" "r")
9133                            (match_operand:SI 2 "arm_add_operand" "rIL")])
9134                          (match_operator:SI 6 "arm_comparison_operator"
9135                           [(match_operand:SI 4 "s_register_operand" "r")
9136                            (match_operand:SI 5 "arm_add_operand" "rIL")]))
9137                  (const_int 0)))
9138    (set (match_operand:SI 7 "s_register_operand" "=Ts")
9139         (and:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9140                 (match_op_dup 6 [(match_dup 4) (match_dup 5)])))]
9141   "TARGET_32BIT"
9142   "#"
9143   "TARGET_32BIT && reload_completed"
9144   [(set (match_dup 0)
9145         (compare
9146          (and:SI
9147           (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9148           (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9149          (const_int 0)))
9150    (set (match_dup 7) (ne:SI (match_dup 0) (const_int 0)))]
9151   ""
9152   [(set_attr "conds" "set")
9153    (set_attr "length" "16")
9154    (set_attr "type" "multiple")]
9157 ;; If there is no dominance in the comparison, then we can still save an
9158 ;; instruction in the AND case, since we can know that the second compare
9159 ;; need only zero the value if false (if true, then the value is already
9160 ;; correct).
9161 (define_insn_and_split "*and_scc_scc_nodom"
9162   [(set (match_operand:SI 0 "s_register_operand" "=&Ts,&Ts,&Ts")
9163         (and:SI (match_operator:SI 3 "arm_comparison_operator"
9164                  [(match_operand:SI 1 "s_register_operand" "r,r,0")
9165                   (match_operand:SI 2 "arm_add_operand" "rIL,0,rIL")])
9166                 (match_operator:SI 6 "arm_comparison_operator"
9167                  [(match_operand:SI 4 "s_register_operand" "r,r,r")
9168                   (match_operand:SI 5 "arm_add_operand" "rIL,rIL,rIL")])))
9169    (clobber (reg:CC CC_REGNUM))]
9170   "TARGET_32BIT
9171    && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
9172        == CCmode)"
9173   "#"
9174   "TARGET_32BIT && reload_completed"
9175   [(parallel [(set (match_dup 0)
9176                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
9177               (clobber (reg:CC CC_REGNUM))])
9178    (set (match_dup 7) (match_op_dup 8 [(match_dup 4) (match_dup 5)]))
9179    (set (match_dup 0)
9180         (if_then_else:SI (match_op_dup 6 [(match_dup 7) (const_int 0)])
9181                          (match_dup 0)
9182                          (const_int 0)))]
9183   "operands[7] = gen_rtx_REG (SELECT_CC_MODE (GET_CODE (operands[6]),
9184                                               operands[4], operands[5]),
9185                               CC_REGNUM);
9186    operands[8] = gen_rtx_COMPARE (GET_MODE (operands[7]), operands[4],
9187                                   operands[5]);"
9188   [(set_attr "conds" "clob")
9189    (set_attr "length" "20")
9190    (set_attr "type" "multiple")]
9193 (define_split
9194   [(set (reg:CC_NOOV CC_REGNUM)
9195         (compare:CC_NOOV (ior:SI
9196                           (and:SI (match_operand:SI 0 "s_register_operand" "")
9197                                   (const_int 1))
9198                           (match_operator:SI 1 "arm_comparison_operator"
9199                            [(match_operand:SI 2 "s_register_operand" "")
9200                             (match_operand:SI 3 "arm_add_operand" "")]))
9201                          (const_int 0)))
9202    (clobber (match_operand:SI 4 "s_register_operand" ""))]
9203   "TARGET_ARM"
9204   [(set (match_dup 4)
9205         (ior:SI (match_op_dup 1 [(match_dup 2) (match_dup 3)])
9206                 (match_dup 0)))
9207    (set (reg:CC_NOOV CC_REGNUM)
9208         (compare:CC_NOOV (and:SI (match_dup 4) (const_int 1))
9209                          (const_int 0)))]
9210   "")
9212 (define_split
9213   [(set (reg:CC_NOOV CC_REGNUM)
9214         (compare:CC_NOOV (ior:SI
9215                           (match_operator:SI 1 "arm_comparison_operator"
9216                            [(match_operand:SI 2 "s_register_operand" "")
9217                             (match_operand:SI 3 "arm_add_operand" "")])
9218                           (and:SI (match_operand:SI 0 "s_register_operand" "")
9219                                   (const_int 1)))
9220                          (const_int 0)))
9221    (clobber (match_operand:SI 4 "s_register_operand" ""))]
9222   "TARGET_ARM"
9223   [(set (match_dup 4)
9224         (ior:SI (match_op_dup 1 [(match_dup 2) (match_dup 3)])
9225                 (match_dup 0)))
9226    (set (reg:CC_NOOV CC_REGNUM)
9227         (compare:CC_NOOV (and:SI (match_dup 4) (const_int 1))
9228                          (const_int 0)))]
9229   "")
9230 ;; ??? The conditional patterns above need checking for Thumb-2 usefulness
9232 (define_insn_and_split "*negscc"
9233   [(set (match_operand:SI 0 "s_register_operand" "=r")
9234         (neg:SI (match_operator 3 "arm_comparison_operator"
9235                  [(match_operand:SI 1 "s_register_operand" "r")
9236                   (match_operand:SI 2 "arm_rhs_operand" "rI")])))
9237    (clobber (reg:CC CC_REGNUM))]
9238   "TARGET_ARM"
9239   "#"
9240   "&& reload_completed"
9241   [(const_int 0)]
9242   {
9243     rtx cc_reg = gen_rtx_REG (CCmode, CC_REGNUM);
9245     if (GET_CODE (operands[3]) == LT && operands[2] == const0_rtx)
9246        {
9247          /* Emit mov\\t%0, %1, asr #31 */
9248          emit_insn (gen_rtx_SET (VOIDmode,
9249                                  operands[0],
9250                                  gen_rtx_ASHIFTRT (SImode,
9251                                                    operands[1],
9252                                                    GEN_INT (31))));
9253          DONE;
9254        }
9255      else if (GET_CODE (operands[3]) == NE)
9256        {
9257         /* Emit subs\\t%0, %1, %2\;mvnne\\t%0, #0 */
9258         if (CONST_INT_P (operands[2]))
9259           emit_insn (gen_cmpsi2_addneg (operands[0], operands[1], operands[2],
9260                                         GEN_INT (- INTVAL (operands[2]))));
9261         else
9262           emit_insn (gen_subsi3_compare (operands[0], operands[1], operands[2]));
9264         emit_insn (gen_rtx_COND_EXEC (VOIDmode,
9265                                       gen_rtx_NE (SImode,
9266                                                   cc_reg,
9267                                                   const0_rtx),
9268                                       gen_rtx_SET (SImode,
9269                                                    operands[0],
9270                                                    GEN_INT (~0))));
9271         DONE;
9272       }
9273     else
9274       {
9275         /* Emit: cmp\\t%1, %2\;mov%D3\\t%0, #0\;mvn%d3\\t%0, #0 */
9276         emit_insn (gen_rtx_SET (VOIDmode,
9277                                 cc_reg,
9278                                 gen_rtx_COMPARE (CCmode, operands[1], operands[2])));
9279         enum rtx_code rc = GET_CODE (operands[3]);
9281         rc = reverse_condition (rc);
9282         emit_insn (gen_rtx_COND_EXEC (VOIDmode,
9283                                       gen_rtx_fmt_ee (rc,
9284                                                       VOIDmode,
9285                                                       cc_reg,
9286                                                       const0_rtx),
9287                                       gen_rtx_SET (VOIDmode, operands[0], const0_rtx)));
9288         rc = GET_CODE (operands[3]);
9289         emit_insn (gen_rtx_COND_EXEC (VOIDmode,
9290                                       gen_rtx_fmt_ee (rc,
9291                                                       VOIDmode,
9292                                                       cc_reg,
9293                                                       const0_rtx),
9294                                       gen_rtx_SET (VOIDmode,
9295                                                    operands[0],
9296                                                    GEN_INT (~0))));
9297         DONE;
9298       }
9299      FAIL;
9300   }
9301   [(set_attr "conds" "clob")
9302    (set_attr "length" "12")
9303    (set_attr "type" "multiple")]
9306 (define_insn_and_split "movcond_addsi"
9307   [(set (match_operand:SI 0 "s_register_operand" "=r,l,r")
9308         (if_then_else:SI
9309          (match_operator 5 "comparison_operator"
9310           [(plus:SI (match_operand:SI 3 "s_register_operand" "r,r,r")
9311                     (match_operand:SI 4 "arm_add_operand" "rIL,rIL,rIL"))
9312             (const_int 0)])
9313          (match_operand:SI 1 "arm_rhs_operand" "rI,rPy,r")
9314          (match_operand:SI 2 "arm_rhs_operand" "rI,rPy,r")))
9315    (clobber (reg:CC CC_REGNUM))]
9316    "TARGET_32BIT"
9317    "#"
9318    "&& reload_completed"
9319   [(set (reg:CC_NOOV CC_REGNUM)
9320         (compare:CC_NOOV
9321          (plus:SI (match_dup 3)
9322                   (match_dup 4))
9323          (const_int 0)))
9324    (set (match_dup 0) (match_dup 1))
9325    (cond_exec (match_dup 6)
9326               (set (match_dup 0) (match_dup 2)))]
9327   "
9328   {
9329     machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[5]),
9330                                              operands[3], operands[4]);
9331     enum rtx_code rc = GET_CODE (operands[5]);
9332     operands[6] = gen_rtx_REG (mode, CC_REGNUM);
9333     gcc_assert (!(mode == CCFPmode || mode == CCFPEmode));
9334     if (REGNO (operands[2]) != REGNO (operands[0]))
9335       rc = reverse_condition (rc);
9336     else
9337       std::swap (operands[1], operands[2]);
9339     operands[6] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
9340   }
9341   "
9342   [(set_attr "conds" "clob")
9343    (set_attr "enabled_for_depr_it" "no,yes,yes")
9344    (set_attr "type" "multiple")]
9347 (define_insn "movcond"
9348   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9349         (if_then_else:SI
9350          (match_operator 5 "arm_comparison_operator"
9351           [(match_operand:SI 3 "s_register_operand" "r,r,r")
9352            (match_operand:SI 4 "arm_add_operand" "rIL,rIL,rIL")])
9353          (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
9354          (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
9355    (clobber (reg:CC CC_REGNUM))]
9356   "TARGET_ARM"
9357   "*
9358   if (GET_CODE (operands[5]) == LT
9359       && (operands[4] == const0_rtx))
9360     {
9361       if (which_alternative != 1 && REG_P (operands[1]))
9362         {
9363           if (operands[2] == const0_rtx)
9364             return \"and\\t%0, %1, %3, asr #31\";
9365           return \"ands\\t%0, %1, %3, asr #32\;movcc\\t%0, %2\";
9366         }
9367       else if (which_alternative != 0 && REG_P (operands[2]))
9368         {
9369           if (operands[1] == const0_rtx)
9370             return \"bic\\t%0, %2, %3, asr #31\";
9371           return \"bics\\t%0, %2, %3, asr #32\;movcs\\t%0, %1\";
9372         }
9373       /* The only case that falls through to here is when both ops 1 & 2
9374          are constants.  */
9375     }
9377   if (GET_CODE (operands[5]) == GE
9378       && (operands[4] == const0_rtx))
9379     {
9380       if (which_alternative != 1 && REG_P (operands[1]))
9381         {
9382           if (operands[2] == const0_rtx)
9383             return \"bic\\t%0, %1, %3, asr #31\";
9384           return \"bics\\t%0, %1, %3, asr #32\;movcs\\t%0, %2\";
9385         }
9386       else if (which_alternative != 0 && REG_P (operands[2]))
9387         {
9388           if (operands[1] == const0_rtx)
9389             return \"and\\t%0, %2, %3, asr #31\";
9390           return \"ands\\t%0, %2, %3, asr #32\;movcc\\t%0, %1\";
9391         }
9392       /* The only case that falls through to here is when both ops 1 & 2
9393          are constants.  */
9394     }
9395   if (CONST_INT_P (operands[4])
9396       && !const_ok_for_arm (INTVAL (operands[4])))
9397     output_asm_insn (\"cmn\\t%3, #%n4\", operands);
9398   else
9399     output_asm_insn (\"cmp\\t%3, %4\", operands);
9400   if (which_alternative != 0)
9401     output_asm_insn (\"mov%d5\\t%0, %1\", operands);
9402   if (which_alternative != 1)
9403     output_asm_insn (\"mov%D5\\t%0, %2\", operands);
9404   return \"\";
9405   "
9406   [(set_attr "conds" "clob")
9407    (set_attr "length" "8,8,12")
9408    (set_attr "type" "multiple")]
9411 ;; ??? The patterns below need checking for Thumb-2 usefulness.
9413 (define_insn "*ifcompare_plus_move"
9414   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9415         (if_then_else:SI (match_operator 6 "arm_comparison_operator"
9416                           [(match_operand:SI 4 "s_register_operand" "r,r")
9417                            (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
9418                          (plus:SI
9419                           (match_operand:SI 2 "s_register_operand" "r,r")
9420                           (match_operand:SI 3 "arm_add_operand" "rIL,rIL"))
9421                          (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))
9422    (clobber (reg:CC CC_REGNUM))]
9423   "TARGET_ARM"
9424   "#"
9425   [(set_attr "conds" "clob")
9426    (set_attr "length" "8,12")
9427    (set_attr "type" "multiple")]
9430 (define_insn "*if_plus_move"
9431   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
9432         (if_then_else:SI
9433          (match_operator 4 "arm_comparison_operator"
9434           [(match_operand 5 "cc_register" "") (const_int 0)])
9435          (plus:SI
9436           (match_operand:SI 2 "s_register_operand" "r,r,r,r")
9437           (match_operand:SI 3 "arm_add_operand" "rI,L,rI,L"))
9438          (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")))]
9439   "TARGET_ARM"
9440   "@
9441    add%d4\\t%0, %2, %3
9442    sub%d4\\t%0, %2, #%n3
9443    add%d4\\t%0, %2, %3\;mov%D4\\t%0, %1
9444    sub%d4\\t%0, %2, #%n3\;mov%D4\\t%0, %1"
9445   [(set_attr "conds" "use")
9446    (set_attr "length" "4,4,8,8")
9447    (set_attr_alternative "type"
9448                          [(if_then_else (match_operand 3 "const_int_operand" "")
9449                                         (const_string "alu_imm" )
9450                                         (const_string "alu_sreg"))
9451                           (const_string "alu_imm")
9452                           (const_string "alu_sreg")
9453                           (const_string "alu_sreg")])]
9456 (define_insn "*ifcompare_move_plus"
9457   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9458         (if_then_else:SI (match_operator 6 "arm_comparison_operator"
9459                           [(match_operand:SI 4 "s_register_operand" "r,r")
9460                            (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
9461                          (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
9462                          (plus:SI
9463                           (match_operand:SI 2 "s_register_operand" "r,r")
9464                           (match_operand:SI 3 "arm_add_operand" "rIL,rIL"))))
9465    (clobber (reg:CC CC_REGNUM))]
9466   "TARGET_ARM"
9467   "#"
9468   [(set_attr "conds" "clob")
9469    (set_attr "length" "8,12")
9470    (set_attr "type" "multiple")]
9473 (define_insn "*if_move_plus"
9474   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
9475         (if_then_else:SI
9476          (match_operator 4 "arm_comparison_operator"
9477           [(match_operand 5 "cc_register" "") (const_int 0)])
9478          (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")
9479          (plus:SI
9480           (match_operand:SI 2 "s_register_operand" "r,r,r,r")
9481           (match_operand:SI 3 "arm_add_operand" "rI,L,rI,L"))))]
9482   "TARGET_ARM"
9483   "@
9484    add%D4\\t%0, %2, %3
9485    sub%D4\\t%0, %2, #%n3
9486    add%D4\\t%0, %2, %3\;mov%d4\\t%0, %1
9487    sub%D4\\t%0, %2, #%n3\;mov%d4\\t%0, %1"
9488   [(set_attr "conds" "use")
9489    (set_attr "length" "4,4,8,8")
9490    (set_attr "type" "alu_sreg,alu_imm,multiple,multiple")]
9493 (define_insn "*ifcompare_arith_arith"
9494   [(set (match_operand:SI 0 "s_register_operand" "=r")
9495         (if_then_else:SI (match_operator 9 "arm_comparison_operator"
9496                           [(match_operand:SI 5 "s_register_operand" "r")
9497                            (match_operand:SI 6 "arm_add_operand" "rIL")])
9498                          (match_operator:SI 8 "shiftable_operator"
9499                           [(match_operand:SI 1 "s_register_operand" "r")
9500                            (match_operand:SI 2 "arm_rhs_operand" "rI")])
9501                          (match_operator:SI 7 "shiftable_operator"
9502                           [(match_operand:SI 3 "s_register_operand" "r")
9503                            (match_operand:SI 4 "arm_rhs_operand" "rI")])))
9504    (clobber (reg:CC CC_REGNUM))]
9505   "TARGET_ARM"
9506   "#"
9507   [(set_attr "conds" "clob")
9508    (set_attr "length" "12")
9509    (set_attr "type" "multiple")]
9512 (define_insn "*if_arith_arith"
9513   [(set (match_operand:SI 0 "s_register_operand" "=r")
9514         (if_then_else:SI (match_operator 5 "arm_comparison_operator"
9515                           [(match_operand 8 "cc_register" "") (const_int 0)])
9516                          (match_operator:SI 6 "shiftable_operator"
9517                           [(match_operand:SI 1 "s_register_operand" "r")
9518                            (match_operand:SI 2 "arm_rhs_operand" "rI")])
9519                          (match_operator:SI 7 "shiftable_operator"
9520                           [(match_operand:SI 3 "s_register_operand" "r")
9521                            (match_operand:SI 4 "arm_rhs_operand" "rI")])))]
9522   "TARGET_ARM"
9523   "%I6%d5\\t%0, %1, %2\;%I7%D5\\t%0, %3, %4"
9524   [(set_attr "conds" "use")
9525    (set_attr "length" "8")
9526    (set_attr "type" "multiple")]
9529 (define_insn "*ifcompare_arith_move"
9530   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9531         (if_then_else:SI (match_operator 6 "arm_comparison_operator"
9532                           [(match_operand:SI 2 "s_register_operand" "r,r")
9533                            (match_operand:SI 3 "arm_add_operand" "rIL,rIL")])
9534                          (match_operator:SI 7 "shiftable_operator"
9535                           [(match_operand:SI 4 "s_register_operand" "r,r")
9536                            (match_operand:SI 5 "arm_rhs_operand" "rI,rI")])
9537                          (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))
9538    (clobber (reg:CC CC_REGNUM))]
9539   "TARGET_ARM"
9540   "*
9541   /* If we have an operation where (op x 0) is the identity operation and
9542      the conditional operator is LT or GE and we are comparing against zero and
9543      everything is in registers then we can do this in two instructions.  */
9544   if (operands[3] == const0_rtx
9545       && GET_CODE (operands[7]) != AND
9546       && REG_P (operands[5])
9547       && REG_P (operands[1])
9548       && REGNO (operands[1]) == REGNO (operands[4])
9549       && REGNO (operands[4]) != REGNO (operands[0]))
9550     {
9551       if (GET_CODE (operands[6]) == LT)
9552         return \"and\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\";
9553       else if (GET_CODE (operands[6]) == GE)
9554         return \"bic\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\";
9555     }
9556   if (CONST_INT_P (operands[3])
9557       && !const_ok_for_arm (INTVAL (operands[3])))
9558     output_asm_insn (\"cmn\\t%2, #%n3\", operands);
9559   else
9560     output_asm_insn (\"cmp\\t%2, %3\", operands);
9561   output_asm_insn (\"%I7%d6\\t%0, %4, %5\", operands);
9562   if (which_alternative != 0)
9563     return \"mov%D6\\t%0, %1\";
9564   return \"\";
9565   "
9566   [(set_attr "conds" "clob")
9567    (set_attr "length" "8,12")
9568    (set_attr "type" "multiple")]
9571 (define_insn "*if_arith_move"
9572   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9573         (if_then_else:SI (match_operator 4 "arm_comparison_operator"
9574                           [(match_operand 6 "cc_register" "") (const_int 0)])
9575                          (match_operator:SI 5 "shiftable_operator"
9576                           [(match_operand:SI 2 "s_register_operand" "r,r")
9577                            (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
9578                          (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))]
9579   "TARGET_ARM"
9580   "@
9581    %I5%d4\\t%0, %2, %3
9582    %I5%d4\\t%0, %2, %3\;mov%D4\\t%0, %1"
9583   [(set_attr "conds" "use")
9584    (set_attr "length" "4,8")
9585    (set_attr "type" "alu_shift_reg,multiple")]
9588 (define_insn "*ifcompare_move_arith"
9589   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9590         (if_then_else:SI (match_operator 6 "arm_comparison_operator"
9591                           [(match_operand:SI 4 "s_register_operand" "r,r")
9592                            (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
9593                          (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
9594                          (match_operator:SI 7 "shiftable_operator"
9595                           [(match_operand:SI 2 "s_register_operand" "r,r")
9596                            (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
9597    (clobber (reg:CC CC_REGNUM))]
9598   "TARGET_ARM"
9599   "*
9600   /* If we have an operation where (op x 0) is the identity operation and
9601      the conditional operator is LT or GE and we are comparing against zero and
9602      everything is in registers then we can do this in two instructions */
9603   if (operands[5] == const0_rtx
9604       && GET_CODE (operands[7]) != AND
9605       && REG_P (operands[3])
9606       && REG_P (operands[1])
9607       && REGNO (operands[1]) == REGNO (operands[2])
9608       && REGNO (operands[2]) != REGNO (operands[0]))
9609     {
9610       if (GET_CODE (operands[6]) == GE)
9611         return \"and\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\";
9612       else if (GET_CODE (operands[6]) == LT)
9613         return \"bic\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\";
9614     }
9616   if (CONST_INT_P (operands[5])
9617       && !const_ok_for_arm (INTVAL (operands[5])))
9618     output_asm_insn (\"cmn\\t%4, #%n5\", operands);
9619   else
9620     output_asm_insn (\"cmp\\t%4, %5\", operands);
9622   if (which_alternative != 0)
9623     output_asm_insn (\"mov%d6\\t%0, %1\", operands);
9624   return \"%I7%D6\\t%0, %2, %3\";
9625   "
9626   [(set_attr "conds" "clob")
9627    (set_attr "length" "8,12")
9628    (set_attr "type" "multiple")]
9631 (define_insn "*if_move_arith"
9632   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9633         (if_then_else:SI
9634          (match_operator 4 "arm_comparison_operator"
9635           [(match_operand 6 "cc_register" "") (const_int 0)])
9636          (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
9637          (match_operator:SI 5 "shiftable_operator"
9638           [(match_operand:SI 2 "s_register_operand" "r,r")
9639            (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))]
9640   "TARGET_ARM"
9641   "@
9642    %I5%D4\\t%0, %2, %3
9643    %I5%D4\\t%0, %2, %3\;mov%d4\\t%0, %1"
9644   [(set_attr "conds" "use")
9645    (set_attr "length" "4,8")
9646    (set_attr "type" "alu_shift_reg,multiple")]
9649 (define_insn "*ifcompare_move_not"
9650   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9651         (if_then_else:SI
9652          (match_operator 5 "arm_comparison_operator"
9653           [(match_operand:SI 3 "s_register_operand" "r,r")
9654            (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
9655          (match_operand:SI 1 "arm_not_operand" "0,?rIK")
9656          (not:SI
9657           (match_operand:SI 2 "s_register_operand" "r,r"))))
9658    (clobber (reg:CC CC_REGNUM))]
9659   "TARGET_ARM"
9660   "#"
9661   [(set_attr "conds" "clob")
9662    (set_attr "length" "8,12")
9663    (set_attr "type" "multiple")]
9666 (define_insn "*if_move_not"
9667   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9668         (if_then_else:SI
9669          (match_operator 4 "arm_comparison_operator"
9670           [(match_operand 3 "cc_register" "") (const_int 0)])
9671          (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
9672          (not:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))))]
9673   "TARGET_ARM"
9674   "@
9675    mvn%D4\\t%0, %2
9676    mov%d4\\t%0, %1\;mvn%D4\\t%0, %2
9677    mvn%d4\\t%0, #%B1\;mvn%D4\\t%0, %2"
9678   [(set_attr "conds" "use")
9679    (set_attr "type" "mvn_reg")
9680    (set_attr "length" "4,8,8")
9681    (set_attr "type" "mvn_reg,multiple,multiple")]
9684 (define_insn "*ifcompare_not_move"
9685   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9686         (if_then_else:SI 
9687          (match_operator 5 "arm_comparison_operator"
9688           [(match_operand:SI 3 "s_register_operand" "r,r")
9689            (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
9690          (not:SI
9691           (match_operand:SI 2 "s_register_operand" "r,r"))
9692          (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
9693    (clobber (reg:CC CC_REGNUM))]
9694   "TARGET_ARM"
9695   "#"
9696   [(set_attr "conds" "clob")
9697    (set_attr "length" "8,12")
9698    (set_attr "type" "multiple")]
9701 (define_insn "*if_not_move"
9702   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9703         (if_then_else:SI
9704          (match_operator 4 "arm_comparison_operator"
9705           [(match_operand 3 "cc_register" "") (const_int 0)])
9706          (not:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))
9707          (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
9708   "TARGET_ARM"
9709   "@
9710    mvn%d4\\t%0, %2
9711    mov%D4\\t%0, %1\;mvn%d4\\t%0, %2
9712    mvn%D4\\t%0, #%B1\;mvn%d4\\t%0, %2"
9713   [(set_attr "conds" "use")
9714    (set_attr "type" "mvn_reg,multiple,multiple")
9715    (set_attr "length" "4,8,8")]
9718 (define_insn "*ifcompare_shift_move"
9719   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9720         (if_then_else:SI
9721          (match_operator 6 "arm_comparison_operator"
9722           [(match_operand:SI 4 "s_register_operand" "r,r")
9723            (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
9724          (match_operator:SI 7 "shift_operator"
9725           [(match_operand:SI 2 "s_register_operand" "r,r")
9726            (match_operand:SI 3 "arm_rhs_operand" "rM,rM")])
9727          (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
9728    (clobber (reg:CC CC_REGNUM))]
9729   "TARGET_ARM"
9730   "#"
9731   [(set_attr "conds" "clob")
9732    (set_attr "length" "8,12")
9733    (set_attr "type" "multiple")]
9736 (define_insn "*if_shift_move"
9737   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9738         (if_then_else:SI
9739          (match_operator 5 "arm_comparison_operator"
9740           [(match_operand 6 "cc_register" "") (const_int 0)])
9741          (match_operator:SI 4 "shift_operator"
9742           [(match_operand:SI 2 "s_register_operand" "r,r,r")
9743            (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM")])
9744          (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
9745   "TARGET_ARM"
9746   "@
9747    mov%d5\\t%0, %2%S4
9748    mov%D5\\t%0, %1\;mov%d5\\t%0, %2%S4
9749    mvn%D5\\t%0, #%B1\;mov%d5\\t%0, %2%S4"
9750   [(set_attr "conds" "use")
9751    (set_attr "shift" "2")
9752    (set_attr "length" "4,8,8")
9753    (set_attr "type" "mov_shift_reg,multiple,multiple")]
9756 (define_insn "*ifcompare_move_shift"
9757   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9758         (if_then_else:SI
9759          (match_operator 6 "arm_comparison_operator"
9760           [(match_operand:SI 4 "s_register_operand" "r,r")
9761            (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
9762          (match_operand:SI 1 "arm_not_operand" "0,?rIK")
9763          (match_operator:SI 7 "shift_operator"
9764           [(match_operand:SI 2 "s_register_operand" "r,r")
9765            (match_operand:SI 3 "arm_rhs_operand" "rM,rM")])))
9766    (clobber (reg:CC CC_REGNUM))]
9767   "TARGET_ARM"
9768   "#"
9769   [(set_attr "conds" "clob")
9770    (set_attr "length" "8,12")
9771    (set_attr "type" "multiple")]
9774 (define_insn "*if_move_shift"
9775   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9776         (if_then_else:SI
9777          (match_operator 5 "arm_comparison_operator"
9778           [(match_operand 6 "cc_register" "") (const_int 0)])
9779          (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
9780          (match_operator:SI 4 "shift_operator"
9781           [(match_operand:SI 2 "s_register_operand" "r,r,r")
9782            (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM")])))]
9783   "TARGET_ARM"
9784   "@
9785    mov%D5\\t%0, %2%S4
9786    mov%d5\\t%0, %1\;mov%D5\\t%0, %2%S4
9787    mvn%d5\\t%0, #%B1\;mov%D5\\t%0, %2%S4"
9788   [(set_attr "conds" "use")
9789    (set_attr "shift" "2")
9790    (set_attr "length" "4,8,8")
9791    (set_attr "type" "mov_shift_reg,multiple,multiple")]
9794 (define_insn "*ifcompare_shift_shift"
9795   [(set (match_operand:SI 0 "s_register_operand" "=r")
9796         (if_then_else:SI
9797          (match_operator 7 "arm_comparison_operator"
9798           [(match_operand:SI 5 "s_register_operand" "r")
9799            (match_operand:SI 6 "arm_add_operand" "rIL")])
9800          (match_operator:SI 8 "shift_operator"
9801           [(match_operand:SI 1 "s_register_operand" "r")
9802            (match_operand:SI 2 "arm_rhs_operand" "rM")])
9803          (match_operator:SI 9 "shift_operator"
9804           [(match_operand:SI 3 "s_register_operand" "r")
9805            (match_operand:SI 4 "arm_rhs_operand" "rM")])))
9806    (clobber (reg:CC CC_REGNUM))]
9807   "TARGET_ARM"
9808   "#"
9809   [(set_attr "conds" "clob")
9810    (set_attr "length" "12")
9811    (set_attr "type" "multiple")]
9814 (define_insn "*if_shift_shift"
9815   [(set (match_operand:SI 0 "s_register_operand" "=r")
9816         (if_then_else:SI
9817          (match_operator 5 "arm_comparison_operator"
9818           [(match_operand 8 "cc_register" "") (const_int 0)])
9819          (match_operator:SI 6 "shift_operator"
9820           [(match_operand:SI 1 "s_register_operand" "r")
9821            (match_operand:SI 2 "arm_rhs_operand" "rM")])
9822          (match_operator:SI 7 "shift_operator"
9823           [(match_operand:SI 3 "s_register_operand" "r")
9824            (match_operand:SI 4 "arm_rhs_operand" "rM")])))]
9825   "TARGET_ARM"
9826   "mov%d5\\t%0, %1%S6\;mov%D5\\t%0, %3%S7"
9827   [(set_attr "conds" "use")
9828    (set_attr "shift" "1")
9829    (set_attr "length" "8")
9830    (set (attr "type") (if_then_else
9831                         (and (match_operand 2 "const_int_operand" "")
9832                              (match_operand 4 "const_int_operand" ""))
9833                       (const_string "mov_shift")
9834                       (const_string "mov_shift_reg")))]
9837 (define_insn "*ifcompare_not_arith"
9838   [(set (match_operand:SI 0 "s_register_operand" "=r")
9839         (if_then_else:SI
9840          (match_operator 6 "arm_comparison_operator"
9841           [(match_operand:SI 4 "s_register_operand" "r")
9842            (match_operand:SI 5 "arm_add_operand" "rIL")])
9843          (not:SI (match_operand:SI 1 "s_register_operand" "r"))
9844          (match_operator:SI 7 "shiftable_operator"
9845           [(match_operand:SI 2 "s_register_operand" "r")
9846            (match_operand:SI 3 "arm_rhs_operand" "rI")])))
9847    (clobber (reg:CC CC_REGNUM))]
9848   "TARGET_ARM"
9849   "#"
9850   [(set_attr "conds" "clob")
9851    (set_attr "length" "12")
9852    (set_attr "type" "multiple")]
9855 (define_insn "*if_not_arith"
9856   [(set (match_operand:SI 0 "s_register_operand" "=r")
9857         (if_then_else:SI
9858          (match_operator 5 "arm_comparison_operator"
9859           [(match_operand 4 "cc_register" "") (const_int 0)])
9860          (not:SI (match_operand:SI 1 "s_register_operand" "r"))
9861          (match_operator:SI 6 "shiftable_operator"
9862           [(match_operand:SI 2 "s_register_operand" "r")
9863            (match_operand:SI 3 "arm_rhs_operand" "rI")])))]
9864   "TARGET_ARM"
9865   "mvn%d5\\t%0, %1\;%I6%D5\\t%0, %2, %3"
9866   [(set_attr "conds" "use")
9867    (set_attr "type" "mvn_reg")
9868    (set_attr "length" "8")]
9871 (define_insn "*ifcompare_arith_not"
9872   [(set (match_operand:SI 0 "s_register_operand" "=r")
9873         (if_then_else:SI
9874          (match_operator 6 "arm_comparison_operator"
9875           [(match_operand:SI 4 "s_register_operand" "r")
9876            (match_operand:SI 5 "arm_add_operand" "rIL")])
9877          (match_operator:SI 7 "shiftable_operator"
9878           [(match_operand:SI 2 "s_register_operand" "r")
9879            (match_operand:SI 3 "arm_rhs_operand" "rI")])
9880          (not:SI (match_operand:SI 1 "s_register_operand" "r"))))
9881    (clobber (reg:CC CC_REGNUM))]
9882   "TARGET_ARM"
9883   "#"
9884   [(set_attr "conds" "clob")
9885    (set_attr "length" "12")
9886    (set_attr "type" "multiple")]
9889 (define_insn "*if_arith_not"
9890   [(set (match_operand:SI 0 "s_register_operand" "=r")
9891         (if_then_else:SI
9892          (match_operator 5 "arm_comparison_operator"
9893           [(match_operand 4 "cc_register" "") (const_int 0)])
9894          (match_operator:SI 6 "shiftable_operator"
9895           [(match_operand:SI 2 "s_register_operand" "r")
9896            (match_operand:SI 3 "arm_rhs_operand" "rI")])
9897          (not:SI (match_operand:SI 1 "s_register_operand" "r"))))]
9898   "TARGET_ARM"
9899   "mvn%D5\\t%0, %1\;%I6%d5\\t%0, %2, %3"
9900   [(set_attr "conds" "use")
9901    (set_attr "type" "multiple")
9902    (set_attr "length" "8")]
9905 (define_insn "*ifcompare_neg_move"
9906   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9907         (if_then_else:SI
9908          (match_operator 5 "arm_comparison_operator"
9909           [(match_operand:SI 3 "s_register_operand" "r,r")
9910            (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
9911          (neg:SI (match_operand:SI 2 "s_register_operand" "r,r"))
9912          (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
9913    (clobber (reg:CC CC_REGNUM))]
9914   "TARGET_ARM"
9915   "#"
9916   [(set_attr "conds" "clob")
9917    (set_attr "length" "8,12")
9918    (set_attr "type" "multiple")]
9921 (define_insn "*if_neg_move"
9922   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9923         (if_then_else:SI
9924          (match_operator 4 "arm_comparison_operator"
9925           [(match_operand 3 "cc_register" "") (const_int 0)])
9926          (neg:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))
9927          (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
9928   "TARGET_ARM"
9929   "@
9930    rsb%d4\\t%0, %2, #0
9931    mov%D4\\t%0, %1\;rsb%d4\\t%0, %2, #0
9932    mvn%D4\\t%0, #%B1\;rsb%d4\\t%0, %2, #0"
9933   [(set_attr "conds" "use")
9934    (set_attr "length" "4,8,8")
9935    (set_attr "type" "logic_shift_imm,multiple,multiple")]
9938 (define_insn "*ifcompare_move_neg"
9939   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9940         (if_then_else:SI
9941          (match_operator 5 "arm_comparison_operator"
9942           [(match_operand:SI 3 "s_register_operand" "r,r")
9943            (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
9944          (match_operand:SI 1 "arm_not_operand" "0,?rIK")
9945          (neg:SI (match_operand:SI 2 "s_register_operand" "r,r"))))
9946    (clobber (reg:CC CC_REGNUM))]
9947   "TARGET_ARM"
9948   "#"
9949   [(set_attr "conds" "clob")
9950    (set_attr "length" "8,12")
9951    (set_attr "type" "multiple")]
9954 (define_insn "*if_move_neg"
9955   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9956         (if_then_else:SI
9957          (match_operator 4 "arm_comparison_operator"
9958           [(match_operand 3 "cc_register" "") (const_int 0)])
9959          (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
9960          (neg:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))))]
9961   "TARGET_ARM"
9962   "@
9963    rsb%D4\\t%0, %2, #0
9964    mov%d4\\t%0, %1\;rsb%D4\\t%0, %2, #0
9965    mvn%d4\\t%0, #%B1\;rsb%D4\\t%0, %2, #0"
9966   [(set_attr "conds" "use")
9967    (set_attr "length" "4,8,8")
9968    (set_attr "type" "logic_shift_imm,multiple,multiple")]
9971 (define_insn "*arith_adjacentmem"
9972   [(set (match_operand:SI 0 "s_register_operand" "=r")
9973         (match_operator:SI 1 "shiftable_operator"
9974          [(match_operand:SI 2 "memory_operand" "m")
9975           (match_operand:SI 3 "memory_operand" "m")]))
9976    (clobber (match_scratch:SI 4 "=r"))]
9977   "TARGET_ARM && adjacent_mem_locations (operands[2], operands[3])"
9978   "*
9979   {
9980     rtx ldm[3];
9981     rtx arith[4];
9982     rtx base_reg;
9983     HOST_WIDE_INT val1 = 0, val2 = 0;
9985     if (REGNO (operands[0]) > REGNO (operands[4]))
9986       {
9987         ldm[1] = operands[4];
9988         ldm[2] = operands[0];
9989       }
9990     else
9991       {
9992         ldm[1] = operands[0];
9993         ldm[2] = operands[4];
9994       }
9996     base_reg = XEXP (operands[2], 0);
9998     if (!REG_P (base_reg))
9999       {
10000         val1 = INTVAL (XEXP (base_reg, 1));
10001         base_reg = XEXP (base_reg, 0);
10002       }
10004     if (!REG_P (XEXP (operands[3], 0)))
10005       val2 = INTVAL (XEXP (XEXP (operands[3], 0), 1));
10007     arith[0] = operands[0];
10008     arith[3] = operands[1];
10010     if (val1 < val2)
10011       {
10012         arith[1] = ldm[1];
10013         arith[2] = ldm[2];
10014       }
10015     else
10016       {
10017         arith[1] = ldm[2];
10018         arith[2] = ldm[1];
10019       }
10021     ldm[0] = base_reg;
10022     if (val1 !=0 && val2 != 0)
10023       {
10024         rtx ops[3];
10026         if (val1 == 4 || val2 == 4)
10027           /* Other val must be 8, since we know they are adjacent and neither
10028              is zero.  */
10029           output_asm_insn (\"ldm%(ib%)\\t%0, {%1, %2}\", ldm);
10030         else if (const_ok_for_arm (val1) || const_ok_for_arm (-val1))
10031           {
10032             ldm[0] = ops[0] = operands[4];
10033             ops[1] = base_reg;
10034             ops[2] = GEN_INT (val1);
10035             output_add_immediate (ops);
10036             if (val1 < val2)
10037               output_asm_insn (\"ldm%(ia%)\\t%0, {%1, %2}\", ldm);
10038             else
10039               output_asm_insn (\"ldm%(da%)\\t%0, {%1, %2}\", ldm);
10040           }
10041         else
10042           {
10043             /* Offset is out of range for a single add, so use two ldr.  */
10044             ops[0] = ldm[1];
10045             ops[1] = base_reg;
10046             ops[2] = GEN_INT (val1);
10047             output_asm_insn (\"ldr%?\\t%0, [%1, %2]\", ops);
10048             ops[0] = ldm[2];
10049             ops[2] = GEN_INT (val2);
10050             output_asm_insn (\"ldr%?\\t%0, [%1, %2]\", ops);
10051           }
10052       }
10053     else if (val1 != 0)
10054       {
10055         if (val1 < val2)
10056           output_asm_insn (\"ldm%(da%)\\t%0, {%1, %2}\", ldm);
10057         else
10058           output_asm_insn (\"ldm%(ia%)\\t%0, {%1, %2}\", ldm);
10059       }
10060     else
10061       {
10062         if (val1 < val2)
10063           output_asm_insn (\"ldm%(ia%)\\t%0, {%1, %2}\", ldm);
10064         else
10065           output_asm_insn (\"ldm%(da%)\\t%0, {%1, %2}\", ldm);
10066       }
10067     output_asm_insn (\"%I3%?\\t%0, %1, %2\", arith);
10068     return \"\";
10069   }"
10070   [(set_attr "length" "12")
10071    (set_attr "predicable" "yes")
10072    (set_attr "type" "load1")]
10075 ; This pattern is never tried by combine, so do it as a peephole
10077 (define_peephole2
10078   [(set (match_operand:SI 0 "arm_general_register_operand" "")
10079         (match_operand:SI 1 "arm_general_register_operand" ""))
10080    (set (reg:CC CC_REGNUM)
10081         (compare:CC (match_dup 1) (const_int 0)))]
10082   "TARGET_ARM"
10083   [(parallel [(set (reg:CC CC_REGNUM) (compare:CC (match_dup 1) (const_int 0)))
10084               (set (match_dup 0) (match_dup 1))])]
10085   ""
10088 (define_split
10089   [(set (match_operand:SI 0 "s_register_operand" "")
10090         (and:SI (ge:SI (match_operand:SI 1 "s_register_operand" "")
10091                        (const_int 0))
10092                 (neg:SI (match_operator:SI 2 "arm_comparison_operator"
10093                          [(match_operand:SI 3 "s_register_operand" "")
10094                           (match_operand:SI 4 "arm_rhs_operand" "")]))))
10095    (clobber (match_operand:SI 5 "s_register_operand" ""))]
10096   "TARGET_ARM"
10097   [(set (match_dup 5) (not:SI (ashiftrt:SI (match_dup 1) (const_int 31))))
10098    (set (match_dup 0) (and:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
10099                               (match_dup 5)))]
10100   ""
10103 ;; This split can be used because CC_Z mode implies that the following
10104 ;; branch will be an equality, or an unsigned inequality, so the sign
10105 ;; extension is not needed.
10107 (define_split
10108   [(set (reg:CC_Z CC_REGNUM)
10109         (compare:CC_Z
10110          (ashift:SI (subreg:SI (match_operand:QI 0 "memory_operand" "") 0)
10111                     (const_int 24))
10112          (match_operand 1 "const_int_operand" "")))
10113    (clobber (match_scratch:SI 2 ""))]
10114   "TARGET_ARM
10115    && (((unsigned HOST_WIDE_INT) INTVAL (operands[1]))
10116        == (((unsigned HOST_WIDE_INT) INTVAL (operands[1])) >> 24) << 24)"
10117   [(set (match_dup 2) (zero_extend:SI (match_dup 0)))
10118    (set (reg:CC CC_REGNUM) (compare:CC (match_dup 2) (match_dup 1)))]
10119   "
10120   operands[1] = GEN_INT (((unsigned long) INTVAL (operands[1])) >> 24);
10121   "
10123 ;; ??? Check the patterns above for Thumb-2 usefulness
10125 (define_expand "prologue"
10126   [(clobber (const_int 0))]
10127   "TARGET_EITHER"
10128   "if (TARGET_32BIT)
10129      arm_expand_prologue ();
10130    else
10131      thumb1_expand_prologue ();
10132   DONE;
10133   "
10136 (define_expand "epilogue"
10137   [(clobber (const_int 0))]
10138   "TARGET_EITHER"
10139   "
10140   if (crtl->calls_eh_return)
10141     emit_insn (gen_force_register_use (gen_rtx_REG (Pmode, 2)));
10142   if (TARGET_THUMB1)
10143    {
10144      thumb1_expand_epilogue ();
10145      emit_jump_insn (gen_rtx_UNSPEC_VOLATILE (VOIDmode,
10146                      gen_rtvec (1, ret_rtx), VUNSPEC_EPILOGUE));
10147    }
10148   else if (HAVE_return)
10149    {
10150      /* HAVE_return is testing for USE_RETURN_INSN (FALSE).  Hence,
10151         no need for explicit testing again.  */
10152      emit_jump_insn (gen_return ());
10153    }
10154   else if (TARGET_32BIT)
10155    {
10156     arm_expand_epilogue (true);
10157    }
10158   DONE;
10159   "
10162 ;; Note - although unspec_volatile's USE all hard registers,
10163 ;; USEs are ignored after relaod has completed.  Thus we need
10164 ;; to add an unspec of the link register to ensure that flow
10165 ;; does not think that it is unused by the sibcall branch that
10166 ;; will replace the standard function epilogue.
10167 (define_expand "sibcall_epilogue"
10168    [(parallel [(unspec:SI [(reg:SI LR_REGNUM)] UNSPEC_REGISTER_USE)
10169                (unspec_volatile [(return)] VUNSPEC_EPILOGUE)])]
10170    "TARGET_32BIT"
10171    "
10172    arm_expand_epilogue (false);
10173    DONE;
10174    "
10177 (define_expand "eh_epilogue"
10178   [(use (match_operand:SI 0 "register_operand" ""))
10179    (use (match_operand:SI 1 "register_operand" ""))
10180    (use (match_operand:SI 2 "register_operand" ""))]
10181   "TARGET_EITHER"
10182   "
10183   {
10184     cfun->machine->eh_epilogue_sp_ofs = operands[1];
10185     if (!REG_P (operands[2]) || REGNO (operands[2]) != 2)
10186       {
10187         rtx ra = gen_rtx_REG (Pmode, 2);
10189         emit_move_insn (ra, operands[2]);
10190         operands[2] = ra;
10191       }
10192     /* This is a hack -- we may have crystalized the function type too
10193        early.  */
10194     cfun->machine->func_type = 0;
10195   }"
10198 ;; This split is only used during output to reduce the number of patterns
10199 ;; that need assembler instructions adding to them.  We allowed the setting
10200 ;; of the conditions to be implicit during rtl generation so that
10201 ;; the conditional compare patterns would work.  However this conflicts to
10202 ;; some extent with the conditional data operations, so we have to split them
10203 ;; up again here.
10205 ;; ??? Need to audit these splitters for Thumb-2.  Why isn't normal
10206 ;; conditional execution sufficient?
10208 (define_split
10209   [(set (match_operand:SI 0 "s_register_operand" "")
10210         (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10211                           [(match_operand 2 "" "") (match_operand 3 "" "")])
10212                          (match_dup 0)
10213                          (match_operand 4 "" "")))
10214    (clobber (reg:CC CC_REGNUM))]
10215   "TARGET_ARM && reload_completed"
10216   [(set (match_dup 5) (match_dup 6))
10217    (cond_exec (match_dup 7)
10218               (set (match_dup 0) (match_dup 4)))]
10219   "
10220   {
10221     machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10222                                              operands[2], operands[3]);
10223     enum rtx_code rc = GET_CODE (operands[1]);
10225     operands[5] = gen_rtx_REG (mode, CC_REGNUM);
10226     operands[6] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10227     if (mode == CCFPmode || mode == CCFPEmode)
10228       rc = reverse_condition_maybe_unordered (rc);
10229     else
10230       rc = reverse_condition (rc);
10232     operands[7] = gen_rtx_fmt_ee (rc, VOIDmode, operands[5], const0_rtx);
10233   }"
10236 (define_split
10237   [(set (match_operand:SI 0 "s_register_operand" "")
10238         (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10239                           [(match_operand 2 "" "") (match_operand 3 "" "")])
10240                          (match_operand 4 "" "")
10241                          (match_dup 0)))
10242    (clobber (reg:CC CC_REGNUM))]
10243   "TARGET_ARM && reload_completed"
10244   [(set (match_dup 5) (match_dup 6))
10245    (cond_exec (match_op_dup 1 [(match_dup 5) (const_int 0)])
10246               (set (match_dup 0) (match_dup 4)))]
10247   "
10248   {
10249     machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10250                                              operands[2], operands[3]);
10252     operands[5] = gen_rtx_REG (mode, CC_REGNUM);
10253     operands[6] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10254   }"
10257 (define_split
10258   [(set (match_operand:SI 0 "s_register_operand" "")
10259         (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10260                           [(match_operand 2 "" "") (match_operand 3 "" "")])
10261                          (match_operand 4 "" "")
10262                          (match_operand 5 "" "")))
10263    (clobber (reg:CC CC_REGNUM))]
10264   "TARGET_ARM && reload_completed"
10265   [(set (match_dup 6) (match_dup 7))
10266    (cond_exec (match_op_dup 1 [(match_dup 6) (const_int 0)])
10267               (set (match_dup 0) (match_dup 4)))
10268    (cond_exec (match_dup 8)
10269               (set (match_dup 0) (match_dup 5)))]
10270   "
10271   {
10272     machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10273                                              operands[2], operands[3]);
10274     enum rtx_code rc = GET_CODE (operands[1]);
10276     operands[6] = gen_rtx_REG (mode, CC_REGNUM);
10277     operands[7] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10278     if (mode == CCFPmode || mode == CCFPEmode)
10279       rc = reverse_condition_maybe_unordered (rc);
10280     else
10281       rc = reverse_condition (rc);
10283     operands[8] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
10284   }"
10287 (define_split
10288   [(set (match_operand:SI 0 "s_register_operand" "")
10289         (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10290                           [(match_operand:SI 2 "s_register_operand" "")
10291                            (match_operand:SI 3 "arm_add_operand" "")])
10292                          (match_operand:SI 4 "arm_rhs_operand" "")
10293                          (not:SI
10294                           (match_operand:SI 5 "s_register_operand" ""))))
10295    (clobber (reg:CC CC_REGNUM))]
10296   "TARGET_ARM && reload_completed"
10297   [(set (match_dup 6) (match_dup 7))
10298    (cond_exec (match_op_dup 1 [(match_dup 6) (const_int 0)])
10299               (set (match_dup 0) (match_dup 4)))
10300    (cond_exec (match_dup 8)
10301               (set (match_dup 0) (not:SI (match_dup 5))))]
10302   "
10303   {
10304     machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10305                                              operands[2], operands[3]);
10306     enum rtx_code rc = GET_CODE (operands[1]);
10308     operands[6] = gen_rtx_REG (mode, CC_REGNUM);
10309     operands[7] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10310     if (mode == CCFPmode || mode == CCFPEmode)
10311       rc = reverse_condition_maybe_unordered (rc);
10312     else
10313       rc = reverse_condition (rc);
10315     operands[8] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
10316   }"
10319 (define_insn "*cond_move_not"
10320   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10321         (if_then_else:SI (match_operator 4 "arm_comparison_operator"
10322                           [(match_operand 3 "cc_register" "") (const_int 0)])
10323                          (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
10324                          (not:SI
10325                           (match_operand:SI 2 "s_register_operand" "r,r"))))]
10326   "TARGET_ARM"
10327   "@
10328    mvn%D4\\t%0, %2
10329    mov%d4\\t%0, %1\;mvn%D4\\t%0, %2"
10330   [(set_attr "conds" "use")
10331    (set_attr "type" "mvn_reg,multiple")
10332    (set_attr "length" "4,8")]
10335 ;; The next two patterns occur when an AND operation is followed by a
10336 ;; scc insn sequence 
10338 (define_insn "*sign_extract_onebit"
10339   [(set (match_operand:SI 0 "s_register_operand" "=r")
10340         (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
10341                          (const_int 1)
10342                          (match_operand:SI 2 "const_int_operand" "n")))
10343     (clobber (reg:CC CC_REGNUM))]
10344   "TARGET_ARM"
10345   "*
10346     operands[2] = GEN_INT (1 << INTVAL (operands[2]));
10347     output_asm_insn (\"ands\\t%0, %1, %2\", operands);
10348     return \"mvnne\\t%0, #0\";
10349   "
10350   [(set_attr "conds" "clob")
10351    (set_attr "length" "8")
10352    (set_attr "type" "multiple")]
10355 (define_insn "*not_signextract_onebit"
10356   [(set (match_operand:SI 0 "s_register_operand" "=r")
10357         (not:SI
10358          (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
10359                           (const_int 1)
10360                           (match_operand:SI 2 "const_int_operand" "n"))))
10361    (clobber (reg:CC CC_REGNUM))]
10362   "TARGET_ARM"
10363   "*
10364     operands[2] = GEN_INT (1 << INTVAL (operands[2]));
10365     output_asm_insn (\"tst\\t%1, %2\", operands);
10366     output_asm_insn (\"mvneq\\t%0, #0\", operands);
10367     return \"movne\\t%0, #0\";
10368   "
10369   [(set_attr "conds" "clob")
10370    (set_attr "length" "12")
10371    (set_attr "type" "multiple")]
10373 ;; ??? The above patterns need auditing for Thumb-2
10375 ;; Push multiple registers to the stack.  Registers are in parallel (use ...)
10376 ;; expressions.  For simplicity, the first register is also in the unspec
10377 ;; part.
10378 ;; To avoid the usage of GNU extension, the length attribute is computed
10379 ;; in a C function arm_attr_length_push_multi.
10380 (define_insn "*push_multi"
10381   [(match_parallel 2 "multi_register_push"
10382     [(set (match_operand:BLK 0 "push_mult_memory_operand" "")
10383           (unspec:BLK [(match_operand:SI 1 "s_register_operand" "")]
10384                       UNSPEC_PUSH_MULT))])]
10385   ""
10386   "*
10387   {
10388     int num_saves = XVECLEN (operands[2], 0);
10389      
10390     /* For the StrongARM at least it is faster to
10391        use STR to store only a single register.
10392        In Thumb mode always use push, and the assembler will pick
10393        something appropriate.  */
10394     if (num_saves == 1 && TARGET_ARM)
10395       output_asm_insn (\"str%?\\t%1, [%m0, #-4]!\", operands);
10396     else
10397       {
10398         int i;
10399         char pattern[100];
10401         if (TARGET_ARM)
10402             strcpy (pattern, \"stm%(fd%)\\t%m0!, {%1\");
10403         else if (TARGET_THUMB2)
10404             strcpy (pattern, \"push%?\\t{%1\");
10405         else
10406             strcpy (pattern, \"push\\t{%1\");
10408         for (i = 1; i < num_saves; i++)
10409           {
10410             strcat (pattern, \", %|\");
10411             strcat (pattern,
10412                     reg_names[REGNO (XEXP (XVECEXP (operands[2], 0, i), 0))]);
10413           }
10415         strcat (pattern, \"}\");
10416         output_asm_insn (pattern, operands);
10417       }
10419     return \"\";
10420   }"
10421   [(set_attr "type" "store4")
10422    (set (attr "length")
10423         (symbol_ref "arm_attr_length_push_multi (operands[2], operands[1])"))]
10426 (define_insn "stack_tie"
10427   [(set (mem:BLK (scratch))
10428         (unspec:BLK [(match_operand:SI 0 "s_register_operand" "rk")
10429                      (match_operand:SI 1 "s_register_operand" "rk")]
10430                     UNSPEC_PRLG_STK))]
10431   ""
10432   ""
10433   [(set_attr "length" "0")
10434    (set_attr "type" "block")]
10437 ;; Pop (as used in epilogue RTL)
10439 (define_insn "*load_multiple_with_writeback"
10440   [(match_parallel 0 "load_multiple_operation"
10441     [(set (match_operand:SI 1 "s_register_operand" "+rk")
10442           (plus:SI (match_dup 1)
10443                    (match_operand:SI 2 "const_int_I_operand" "I")))
10444      (set (match_operand:SI 3 "s_register_operand" "=rk")
10445           (mem:SI (match_dup 1)))
10446         ])]
10447   "TARGET_32BIT && (reload_in_progress || reload_completed)"
10448   "*
10449   {
10450     arm_output_multireg_pop (operands, /*return_pc=*/false,
10451                                        /*cond=*/const_true_rtx,
10452                                        /*reverse=*/false,
10453                                        /*update=*/true);
10454     return \"\";
10455   }
10456   "
10457   [(set_attr "type" "load4")
10458    (set_attr "predicable" "yes")]
10461 ;; Pop with return (as used in epilogue RTL)
10463 ;; This instruction is generated when the registers are popped at the end of
10464 ;; epilogue.  Here, instead of popping the value into LR and then generating
10465 ;; jump to LR, value is popped into PC directly.  Hence, the pattern is combined
10466 ;;  with (return).
10467 (define_insn "*pop_multiple_with_writeback_and_return"
10468   [(match_parallel 0 "pop_multiple_return"
10469     [(return)
10470      (set (match_operand:SI 1 "s_register_operand" "+rk")
10471           (plus:SI (match_dup 1)
10472                    (match_operand:SI 2 "const_int_I_operand" "I")))
10473      (set (match_operand:SI 3 "s_register_operand" "=rk")
10474           (mem:SI (match_dup 1)))
10475         ])]
10476   "TARGET_32BIT && (reload_in_progress || reload_completed)"
10477   "*
10478   {
10479     arm_output_multireg_pop (operands, /*return_pc=*/true,
10480                                        /*cond=*/const_true_rtx,
10481                                        /*reverse=*/false,
10482                                        /*update=*/true);
10483     return \"\";
10484   }
10485   "
10486   [(set_attr "type" "load4")
10487    (set_attr "predicable" "yes")]
10490 (define_insn "*pop_multiple_with_return"
10491   [(match_parallel 0 "pop_multiple_return"
10492     [(return)
10493      (set (match_operand:SI 2 "s_register_operand" "=rk")
10494           (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
10495         ])]
10496   "TARGET_32BIT && (reload_in_progress || reload_completed)"
10497   "*
10498   {
10499     arm_output_multireg_pop (operands, /*return_pc=*/true,
10500                                        /*cond=*/const_true_rtx,
10501                                        /*reverse=*/false,
10502                                        /*update=*/false);
10503     return \"\";
10504   }
10505   "
10506   [(set_attr "type" "load4")
10507    (set_attr "predicable" "yes")]
10510 ;; Load into PC and return
10511 (define_insn "*ldr_with_return"
10512   [(return)
10513    (set (reg:SI PC_REGNUM)
10514         (mem:SI (post_inc:SI (match_operand:SI 0 "s_register_operand" "+rk"))))]
10515   "TARGET_32BIT && (reload_in_progress || reload_completed)"
10516   "ldr%?\t%|pc, [%0], #4"
10517   [(set_attr "type" "load1")
10518    (set_attr "predicable" "yes")]
10520 ;; Pop for floating point registers (as used in epilogue RTL)
10521 (define_insn "*vfp_pop_multiple_with_writeback"
10522   [(match_parallel 0 "pop_multiple_fp"
10523     [(set (match_operand:SI 1 "s_register_operand" "+rk")
10524           (plus:SI (match_dup 1)
10525                    (match_operand:SI 2 "const_int_I_operand" "I")))
10526      (set (match_operand:DF 3 "vfp_hard_register_operand" "")
10527           (mem:DF (match_dup 1)))])]
10528   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
10529   "*
10530   {
10531     int num_regs = XVECLEN (operands[0], 0);
10532     char pattern[100];
10533     rtx op_list[2];
10534     strcpy (pattern, \"vldm\\t\");
10535     strcat (pattern, reg_names[REGNO (SET_DEST (XVECEXP (operands[0], 0, 0)))]);
10536     strcat (pattern, \"!, {\");
10537     op_list[0] = XEXP (XVECEXP (operands[0], 0, 1), 0);
10538     strcat (pattern, \"%P0\");
10539     if ((num_regs - 1) > 1)
10540       {
10541         strcat (pattern, \"-%P1\");
10542         op_list [1] = XEXP (XVECEXP (operands[0], 0, num_regs - 1), 0);
10543       }
10545     strcat (pattern, \"}\");
10546     output_asm_insn (pattern, op_list);
10547     return \"\";
10548   }
10549   "
10550   [(set_attr "type" "load4")
10551    (set_attr "conds" "unconditional")
10552    (set_attr "predicable" "no")]
10555 ;; Special patterns for dealing with the constant pool
10557 (define_insn "align_4"
10558   [(unspec_volatile [(const_int 0)] VUNSPEC_ALIGN)]
10559   "TARGET_EITHER"
10560   "*
10561   assemble_align (32);
10562   return \"\";
10563   "
10564   [(set_attr "type" "no_insn")]
10567 (define_insn "align_8"
10568   [(unspec_volatile [(const_int 0)] VUNSPEC_ALIGN8)]
10569   "TARGET_EITHER"
10570   "*
10571   assemble_align (64);
10572   return \"\";
10573   "
10574   [(set_attr "type" "no_insn")]
10577 (define_insn "consttable_end"
10578   [(unspec_volatile [(const_int 0)] VUNSPEC_POOL_END)]
10579   "TARGET_EITHER"
10580   "*
10581   making_const_table = FALSE;
10582   return \"\";
10583   "
10584   [(set_attr "type" "no_insn")]
10587 (define_insn "consttable_1"
10588   [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_1)]
10589   "TARGET_EITHER"
10590   "*
10591   making_const_table = TRUE;
10592   assemble_integer (operands[0], 1, BITS_PER_WORD, 1);
10593   assemble_zeros (3);
10594   return \"\";
10595   "
10596   [(set_attr "length" "4")
10597    (set_attr "type" "no_insn")]
10600 (define_insn "consttable_2"
10601   [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_2)]
10602   "TARGET_EITHER"
10603   "*
10604   {
10605     rtx x = operands[0];
10606     making_const_table = TRUE;
10607     switch (GET_MODE_CLASS (GET_MODE (x)))
10608       {
10609       case MODE_FLOAT:
10610         arm_emit_fp16_const (x);
10611         break;
10612       default:
10613         assemble_integer (operands[0], 2, BITS_PER_WORD, 1);
10614         assemble_zeros (2);
10615         break;
10616       }
10617     return \"\";
10618   }"
10619   [(set_attr "length" "4")
10620    (set_attr "type" "no_insn")]
10623 (define_insn "consttable_4"
10624   [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_4)]
10625   "TARGET_EITHER"
10626   "*
10627   {
10628     rtx x = operands[0];
10629     making_const_table = TRUE;
10630     switch (GET_MODE_CLASS (GET_MODE (x)))
10631       {
10632       case MODE_FLOAT:
10633         {
10634           REAL_VALUE_TYPE r;
10635           REAL_VALUE_FROM_CONST_DOUBLE (r, x);
10636           assemble_real (r, GET_MODE (x), BITS_PER_WORD);
10637           break;
10638         }
10639       default:
10640         /* XXX: Sometimes gcc does something really dumb and ends up with
10641            a HIGH in a constant pool entry, usually because it's trying to
10642            load into a VFP register.  We know this will always be used in
10643            combination with a LO_SUM which ignores the high bits, so just
10644            strip off the HIGH.  */
10645         if (GET_CODE (x) == HIGH)
10646           x = XEXP (x, 0);
10647         assemble_integer (x, 4, BITS_PER_WORD, 1);
10648         mark_symbol_refs_as_used (x);
10649         break;
10650       }
10651     return \"\";
10652   }"
10653   [(set_attr "length" "4")
10654    (set_attr "type" "no_insn")]
10657 (define_insn "consttable_8"
10658   [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_8)]
10659   "TARGET_EITHER"
10660   "*
10661   {
10662     making_const_table = TRUE;
10663     switch (GET_MODE_CLASS (GET_MODE (operands[0])))
10664       {
10665        case MODE_FLOAT:
10666         {
10667           REAL_VALUE_TYPE r;
10668           REAL_VALUE_FROM_CONST_DOUBLE (r, operands[0]);
10669           assemble_real (r, GET_MODE (operands[0]), BITS_PER_WORD);
10670           break;
10671         }
10672       default:
10673         assemble_integer (operands[0], 8, BITS_PER_WORD, 1);
10674         break;
10675       }
10676     return \"\";
10677   }"
10678   [(set_attr "length" "8")
10679    (set_attr "type" "no_insn")]
10682 (define_insn "consttable_16"
10683   [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_16)]
10684   "TARGET_EITHER"
10685   "*
10686   {
10687     making_const_table = TRUE;
10688     switch (GET_MODE_CLASS (GET_MODE (operands[0])))
10689       {
10690        case MODE_FLOAT:
10691         {
10692           REAL_VALUE_TYPE r;
10693           REAL_VALUE_FROM_CONST_DOUBLE (r, operands[0]);
10694           assemble_real (r, GET_MODE (operands[0]), BITS_PER_WORD);
10695           break;
10696         }
10697       default:
10698         assemble_integer (operands[0], 16, BITS_PER_WORD, 1);
10699         break;
10700       }
10701     return \"\";
10702   }"
10703   [(set_attr "length" "16")
10704    (set_attr "type" "no_insn")]
10707 ;; V5 Instructions,
10709 (define_insn "clzsi2"
10710   [(set (match_operand:SI 0 "s_register_operand" "=r")
10711         (clz:SI (match_operand:SI 1 "s_register_operand" "r")))]
10712   "TARGET_32BIT && arm_arch5"
10713   "clz%?\\t%0, %1"
10714   [(set_attr "predicable" "yes")
10715    (set_attr "predicable_short_it" "no")
10716    (set_attr "type" "clz")])
10718 (define_insn "rbitsi2"
10719   [(set (match_operand:SI 0 "s_register_operand" "=r")
10720         (unspec:SI [(match_operand:SI 1 "s_register_operand" "r")] UNSPEC_RBIT))]
10721   "TARGET_32BIT && arm_arch_thumb2"
10722   "rbit%?\\t%0, %1"
10723   [(set_attr "predicable" "yes")
10724    (set_attr "predicable_short_it" "no")
10725    (set_attr "type" "clz")])
10727 (define_expand "ctzsi2"
10728  [(set (match_operand:SI           0 "s_register_operand" "")
10729        (ctz:SI (match_operand:SI  1 "s_register_operand" "")))]
10730   "TARGET_32BIT && arm_arch_thumb2"
10731   "
10732    {
10733      rtx tmp = gen_reg_rtx (SImode); 
10734      emit_insn (gen_rbitsi2 (tmp, operands[1]));
10735      emit_insn (gen_clzsi2 (operands[0], tmp));
10736    }
10737    DONE;
10738   "
10741 ;; V5E instructions.
10743 (define_insn "prefetch"
10744   [(prefetch (match_operand:SI 0 "address_operand" "p")
10745              (match_operand:SI 1 "" "")
10746              (match_operand:SI 2 "" ""))]
10747   "TARGET_32BIT && arm_arch5e"
10748   "pld\\t%a0"
10749   [(set_attr "type" "load1")]
10752 ;; General predication pattern
10754 (define_cond_exec
10755   [(match_operator 0 "arm_comparison_operator"
10756     [(match_operand 1 "cc_register" "")
10757      (const_int 0)])]
10758   "TARGET_32BIT
10759    && (!TARGET_NO_VOLATILE_CE || !volatile_refs_p (PATTERN (insn)))"
10760   ""
10761 [(set_attr "predicated" "yes")]
10764 (define_insn "force_register_use"
10765   [(unspec:SI [(match_operand:SI 0 "register_operand" "")] UNSPEC_REGISTER_USE)]
10766   ""
10767   "%@ %0 needed"
10768   [(set_attr "length" "0")
10769    (set_attr "type" "no_insn")]
10773 ;; Patterns for exception handling
10775 (define_expand "eh_return"
10776   [(use (match_operand 0 "general_operand" ""))]
10777   "TARGET_EITHER"
10778   "
10779   {
10780     if (TARGET_32BIT)
10781       emit_insn (gen_arm_eh_return (operands[0]));
10782     else
10783       emit_insn (gen_thumb_eh_return (operands[0]));
10784     DONE;
10785   }"
10787                                    
10788 ;; We can't expand this before we know where the link register is stored.
10789 (define_insn_and_split "arm_eh_return"
10790   [(unspec_volatile [(match_operand:SI 0 "s_register_operand" "r")]
10791                     VUNSPEC_EH_RETURN)
10792    (clobber (match_scratch:SI 1 "=&r"))]
10793   "TARGET_ARM"
10794   "#"
10795   "&& reload_completed"
10796   [(const_int 0)]
10797   "
10798   {
10799     arm_set_return_address (operands[0], operands[1]);
10800     DONE;
10801   }"
10805 ;; TLS support
10807 (define_insn "load_tp_hard"
10808   [(set (match_operand:SI 0 "register_operand" "=r")
10809         (unspec:SI [(const_int 0)] UNSPEC_TLS))]
10810   "TARGET_HARD_TP"
10811   "mrc%?\\tp15, 0, %0, c13, c0, 3\\t@ load_tp_hard"
10812   [(set_attr "predicable" "yes")
10813    (set_attr "type" "mrs")]
10816 ;; Doesn't clobber R1-R3.  Must use r0 for the first operand.
10817 (define_insn "load_tp_soft"
10818   [(set (reg:SI 0) (unspec:SI [(const_int 0)] UNSPEC_TLS))
10819    (clobber (reg:SI LR_REGNUM))
10820    (clobber (reg:SI IP_REGNUM))
10821    (clobber (reg:CC CC_REGNUM))]
10822   "TARGET_SOFT_TP"
10823   "bl\\t__aeabi_read_tp\\t@ load_tp_soft"
10824   [(set_attr "conds" "clob")
10825    (set_attr "type" "branch")]
10828 ;; tls descriptor call
10829 (define_insn "tlscall"
10830   [(set (reg:SI R0_REGNUM)
10831         (unspec:SI [(reg:SI R0_REGNUM)
10832                     (match_operand:SI 0 "" "X")
10833                     (match_operand 1 "" "")] UNSPEC_TLS))
10834    (clobber (reg:SI R1_REGNUM))
10835    (clobber (reg:SI LR_REGNUM))
10836    (clobber (reg:SI CC_REGNUM))]
10837   "TARGET_GNU2_TLS"
10838   {
10839     targetm.asm_out.internal_label (asm_out_file, "LPIC",
10840                                     INTVAL (operands[1]));
10841     return "bl\\t%c0(tlscall)";
10842   }
10843   [(set_attr "conds" "clob")
10844    (set_attr "length" "4")
10845    (set_attr "type" "branch")]
10848 ;; For thread pointer builtin
10849 (define_expand "get_thread_pointersi"
10850   [(match_operand:SI 0 "s_register_operand" "=r")]
10851  ""
10854    arm_load_tp (operands[0]);
10855    DONE;
10856  }")
10860 ;; We only care about the lower 16 bits of the constant 
10861 ;; being inserted into the upper 16 bits of the register.
10862 (define_insn "*arm_movtas_ze" 
10863   [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r")
10864                    (const_int 16)
10865                    (const_int 16))
10866         (match_operand:SI 1 "const_int_operand" ""))]
10867   "arm_arch_thumb2"
10868   "movt%?\t%0, %L1"
10869  [(set_attr "predicable" "yes")
10870   (set_attr "predicable_short_it" "no")
10871   (set_attr "length" "4")
10872   (set_attr "type" "mov_imm")]
10875 (define_insn "*arm_rev"
10876   [(set (match_operand:SI 0 "s_register_operand" "=l,l,r")
10877         (bswap:SI (match_operand:SI 1 "s_register_operand" "l,l,r")))]
10878   "arm_arch6"
10879   "@
10880    rev\t%0, %1
10881    rev%?\t%0, %1
10882    rev%?\t%0, %1"
10883   [(set_attr "arch" "t1,t2,32")
10884    (set_attr "length" "2,2,4")
10885    (set_attr "predicable" "no,yes,yes")
10886    (set_attr "predicable_short_it" "no")
10887    (set_attr "type" "rev")]
10890 (define_expand "arm_legacy_rev"
10891   [(set (match_operand:SI 2 "s_register_operand" "")
10892         (xor:SI (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
10893                              (const_int 16))
10894                 (match_dup 1)))
10895    (set (match_dup 2)
10896         (lshiftrt:SI (match_dup 2)
10897                      (const_int 8)))
10898    (set (match_operand:SI 3 "s_register_operand" "")
10899         (rotatert:SI (match_dup 1)
10900                      (const_int 8)))
10901    (set (match_dup 2)
10902         (and:SI (match_dup 2)
10903                 (const_int -65281)))
10904    (set (match_operand:SI 0 "s_register_operand" "")
10905         (xor:SI (match_dup 3)
10906                 (match_dup 2)))]
10907   "TARGET_32BIT"
10908   ""
10911 ;; Reuse temporaries to keep register pressure down.
10912 (define_expand "thumb_legacy_rev"
10913   [(set (match_operand:SI 2 "s_register_operand" "")
10914      (ashift:SI (match_operand:SI 1 "s_register_operand" "")
10915                 (const_int 24)))
10916    (set (match_operand:SI 3 "s_register_operand" "")
10917      (lshiftrt:SI (match_dup 1)
10918                   (const_int 24)))
10919    (set (match_dup 3)
10920      (ior:SI (match_dup 3)
10921              (match_dup 2)))
10922    (set (match_operand:SI 4 "s_register_operand" "")
10923      (const_int 16))
10924    (set (match_operand:SI 5 "s_register_operand" "")
10925      (rotatert:SI (match_dup 1)
10926                   (match_dup 4)))
10927    (set (match_dup 2)
10928      (ashift:SI (match_dup 5)
10929                 (const_int 24)))
10930    (set (match_dup 5)
10931      (lshiftrt:SI (match_dup 5)
10932                   (const_int 24)))
10933    (set (match_dup 5)
10934      (ior:SI (match_dup 5)
10935              (match_dup 2)))
10936    (set (match_dup 5)
10937      (rotatert:SI (match_dup 5)
10938                   (match_dup 4)))
10939    (set (match_operand:SI 0 "s_register_operand" "")
10940      (ior:SI (match_dup 5)
10941              (match_dup 3)))]
10942   "TARGET_THUMB"
10943   ""
10946 (define_expand "bswapsi2"
10947   [(set (match_operand:SI 0 "s_register_operand" "=r")
10948         (bswap:SI (match_operand:SI 1 "s_register_operand" "r")))]
10949 "TARGET_EITHER && (arm_arch6 || !optimize_size)"
10951     if (!arm_arch6)
10952       {
10953         rtx op2 = gen_reg_rtx (SImode);
10954         rtx op3 = gen_reg_rtx (SImode);
10956         if (TARGET_THUMB)
10957           {
10958             rtx op4 = gen_reg_rtx (SImode);
10959             rtx op5 = gen_reg_rtx (SImode);
10961             emit_insn (gen_thumb_legacy_rev (operands[0], operands[1],
10962                                              op2, op3, op4, op5));
10963           }
10964         else
10965           {
10966             emit_insn (gen_arm_legacy_rev (operands[0], operands[1],
10967                                            op2, op3));
10968           }
10970         DONE;
10971       }
10972   "
10975 ;; bswap16 patterns: use revsh and rev16 instructions for the signed
10976 ;; and unsigned variants, respectively. For rev16, expose
10977 ;; byte-swapping in the lower 16 bits only.
10978 (define_insn "*arm_revsh"
10979   [(set (match_operand:SI 0 "s_register_operand" "=l,l,r")
10980         (sign_extend:SI (bswap:HI (match_operand:HI 1 "s_register_operand" "l,l,r"))))]
10981   "arm_arch6"
10982   "@
10983   revsh\t%0, %1
10984   revsh%?\t%0, %1
10985   revsh%?\t%0, %1"
10986   [(set_attr "arch" "t1,t2,32")
10987    (set_attr "length" "2,2,4")
10988    (set_attr "type" "rev")]
10991 (define_insn "*arm_rev16"
10992   [(set (match_operand:HI 0 "s_register_operand" "=l,l,r")
10993         (bswap:HI (match_operand:HI 1 "s_register_operand" "l,l,r")))]
10994   "arm_arch6"
10995   "@
10996    rev16\t%0, %1
10997    rev16%?\t%0, %1
10998    rev16%?\t%0, %1"
10999   [(set_attr "arch" "t1,t2,32")
11000    (set_attr "length" "2,2,4")
11001    (set_attr "type" "rev")]
11004 ;; There are no canonicalisation rules for the position of the lshiftrt, ashift
11005 ;; operations within an IOR/AND RTX, therefore we have two patterns matching
11006 ;; each valid permutation.
11008 (define_insn "arm_rev16si2"
11009   [(set (match_operand:SI 0 "register_operand" "=l,l,r")
11010         (ior:SI (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "l,l,r")
11011                                    (const_int 8))
11012                         (match_operand:SI 3 "const_int_operand" "n,n,n"))
11013                 (and:SI (lshiftrt:SI (match_dup 1)
11014                                      (const_int 8))
11015                         (match_operand:SI 2 "const_int_operand" "n,n,n"))))]
11016   "arm_arch6
11017    && aarch_rev16_shleft_mask_imm_p (operands[3], SImode)
11018    && aarch_rev16_shright_mask_imm_p (operands[2], SImode)"
11019   "rev16\\t%0, %1"
11020   [(set_attr "arch" "t1,t2,32")
11021    (set_attr "length" "2,2,4")
11022    (set_attr "type" "rev")]
11025 (define_insn "arm_rev16si2_alt"
11026   [(set (match_operand:SI 0 "register_operand" "=l,l,r")
11027         (ior:SI (and:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "l,l,r")
11028                                      (const_int 8))
11029                         (match_operand:SI 2 "const_int_operand" "n,n,n"))
11030                 (and:SI (ashift:SI (match_dup 1)
11031                                    (const_int 8))
11032                         (match_operand:SI 3 "const_int_operand" "n,n,n"))))]
11033   "arm_arch6
11034    && aarch_rev16_shleft_mask_imm_p (operands[3], SImode)
11035    && aarch_rev16_shright_mask_imm_p (operands[2], SImode)"
11036   "rev16\\t%0, %1"
11037   [(set_attr "arch" "t1,t2,32")
11038    (set_attr "length" "2,2,4")
11039    (set_attr "type" "rev")]
11042 (define_expand "bswaphi2"
11043   [(set (match_operand:HI 0 "s_register_operand" "=r")
11044         (bswap:HI (match_operand:HI 1 "s_register_operand" "r")))]
11045 "arm_arch6"
11049 ;; Patterns for LDRD/STRD in Thumb2 mode
11051 (define_insn "*thumb2_ldrd"
11052   [(set (match_operand:SI 0 "s_register_operand" "=r")
11053         (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "rk")
11054                          (match_operand:SI 2 "ldrd_strd_offset_operand" "Do"))))
11055    (set (match_operand:SI 3 "s_register_operand" "=r")
11056         (mem:SI (plus:SI (match_dup 1)
11057                          (match_operand:SI 4 "const_int_operand" ""))))]
11058   "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11059      && current_tune->prefer_ldrd_strd
11060      && ((INTVAL (operands[2]) + 4) == INTVAL (operands[4]))
11061      && (operands_ok_ldrd_strd (operands[0], operands[3],
11062                                   operands[1], INTVAL (operands[2]),
11063                                   false, true))"
11064   "ldrd%?\t%0, %3, [%1, %2]"
11065   [(set_attr "type" "load2")
11066    (set_attr "predicable" "yes")
11067    (set_attr "predicable_short_it" "no")])
11069 (define_insn "*thumb2_ldrd_base"
11070   [(set (match_operand:SI 0 "s_register_operand" "=r")
11071         (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
11072    (set (match_operand:SI 2 "s_register_operand" "=r")
11073         (mem:SI (plus:SI (match_dup 1)
11074                          (const_int 4))))]
11075   "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11076      && current_tune->prefer_ldrd_strd
11077      && (operands_ok_ldrd_strd (operands[0], operands[2],
11078                                   operands[1], 0, false, true))"
11079   "ldrd%?\t%0, %2, [%1]"
11080   [(set_attr "type" "load2")
11081    (set_attr "predicable" "yes")
11082    (set_attr "predicable_short_it" "no")])
11084 (define_insn "*thumb2_ldrd_base_neg"
11085   [(set (match_operand:SI 0 "s_register_operand" "=r")
11086         (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "rk")
11087                          (const_int -4))))
11088    (set (match_operand:SI 2 "s_register_operand" "=r")
11089         (mem:SI (match_dup 1)))]
11090   "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11091      && current_tune->prefer_ldrd_strd
11092      && (operands_ok_ldrd_strd (operands[0], operands[2],
11093                                   operands[1], -4, false, true))"
11094   "ldrd%?\t%0, %2, [%1, #-4]"
11095   [(set_attr "type" "load2")
11096    (set_attr "predicable" "yes")
11097    (set_attr "predicable_short_it" "no")])
11099 (define_insn "*thumb2_strd"
11100   [(set (mem:SI (plus:SI (match_operand:SI 0 "s_register_operand" "rk")
11101                          (match_operand:SI 1 "ldrd_strd_offset_operand" "Do")))
11102         (match_operand:SI 2 "s_register_operand" "r"))
11103    (set (mem:SI (plus:SI (match_dup 0)
11104                          (match_operand:SI 3 "const_int_operand" "")))
11105         (match_operand:SI 4 "s_register_operand" "r"))]
11106   "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11107      && current_tune->prefer_ldrd_strd
11108      && ((INTVAL (operands[1]) + 4) == INTVAL (operands[3]))
11109      && (operands_ok_ldrd_strd (operands[2], operands[4],
11110                                   operands[0], INTVAL (operands[1]),
11111                                   false, false))"
11112   "strd%?\t%2, %4, [%0, %1]"
11113   [(set_attr "type" "store2")
11114    (set_attr "predicable" "yes")
11115    (set_attr "predicable_short_it" "no")])
11117 (define_insn "*thumb2_strd_base"
11118   [(set (mem:SI (match_operand:SI 0 "s_register_operand" "rk"))
11119         (match_operand:SI 1 "s_register_operand" "r"))
11120    (set (mem:SI (plus:SI (match_dup 0)
11121                          (const_int 4)))
11122         (match_operand:SI 2 "s_register_operand" "r"))]
11123   "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11124      && current_tune->prefer_ldrd_strd
11125      && (operands_ok_ldrd_strd (operands[1], operands[2],
11126                                   operands[0], 0, false, false))"
11127   "strd%?\t%1, %2, [%0]"
11128   [(set_attr "type" "store2")
11129    (set_attr "predicable" "yes")
11130    (set_attr "predicable_short_it" "no")])
11132 (define_insn "*thumb2_strd_base_neg"
11133   [(set (mem:SI (plus:SI (match_operand:SI 0 "s_register_operand" "rk")
11134                          (const_int -4)))
11135         (match_operand:SI 1 "s_register_operand" "r"))
11136    (set (mem:SI (match_dup 0))
11137         (match_operand:SI 2 "s_register_operand" "r"))]
11138   "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11139      && current_tune->prefer_ldrd_strd
11140      && (operands_ok_ldrd_strd (operands[1], operands[2],
11141                                   operands[0], -4, false, false))"
11142   "strd%?\t%1, %2, [%0, #-4]"
11143   [(set_attr "type" "store2")
11144    (set_attr "predicable" "yes")
11145    (set_attr "predicable_short_it" "no")])
11147 ;; ARMv8 CRC32 instructions.
11148 (define_insn "<crc_variant>"
11149   [(set (match_operand:SI 0 "s_register_operand" "=r")
11150         (unspec:SI [(match_operand:SI 1 "s_register_operand" "r")
11151                     (match_operand:<crc_mode> 2 "s_register_operand" "r")]
11152          CRC))]
11153   "TARGET_CRC32"
11154   "<crc_variant>\\t%0, %1, %2"
11155   [(set_attr "type" "crc")
11156    (set_attr "conds" "unconditional")]
11159 ;; Load the load/store double peephole optimizations.
11160 (include "ldrdstrd.md")
11162 ;; Load the load/store multiple patterns
11163 (include "ldmstm.md")
11165 ;; Patterns in ldmstm.md don't cover more than 4 registers. This pattern covers
11166 ;; large lists without explicit writeback generated for APCS_FRAME epilogue.
11167 (define_insn "*load_multiple"
11168   [(match_parallel 0 "load_multiple_operation"
11169     [(set (match_operand:SI 2 "s_register_operand" "=rk")
11170           (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
11171         ])]
11172   "TARGET_32BIT"
11173   "*
11174   {
11175     arm_output_multireg_pop (operands, /*return_pc=*/false,
11176                                        /*cond=*/const_true_rtx,
11177                                        /*reverse=*/false,
11178                                        /*update=*/false);
11179     return \"\";
11180   }
11181   "
11182   [(set_attr "predicable" "yes")]
11185 (define_expand "copysignsf3"
11186   [(match_operand:SF 0 "register_operand")
11187    (match_operand:SF 1 "register_operand")
11188    (match_operand:SF 2 "register_operand")]
11189   "TARGET_SOFT_FLOAT && arm_arch_thumb2"
11190   "{
11191      emit_move_insn (operands[0], operands[2]);
11192      emit_insn (gen_insv_t2 (simplify_gen_subreg (SImode, operands[0], SFmode, 0),
11193                 GEN_INT (31), GEN_INT (0),
11194                 simplify_gen_subreg (SImode, operands[1], SFmode, 0)));
11195      DONE;
11196   }"
11199 (define_expand "copysigndf3"
11200   [(match_operand:DF 0 "register_operand")
11201    (match_operand:DF 1 "register_operand")
11202    (match_operand:DF 2 "register_operand")]
11203   "TARGET_SOFT_FLOAT && arm_arch_thumb2"
11204   "{
11205      rtx op0_low = gen_lowpart (SImode, operands[0]);
11206      rtx op0_high = gen_highpart (SImode, operands[0]);
11207      rtx op1_low = gen_lowpart (SImode, operands[1]);
11208      rtx op1_high = gen_highpart (SImode, operands[1]);
11209      rtx op2_high = gen_highpart (SImode, operands[2]);
11211      rtx scratch1 = gen_reg_rtx (SImode);
11212      rtx scratch2 = gen_reg_rtx (SImode);
11213      emit_move_insn (scratch1, op2_high);
11214      emit_move_insn (scratch2, op1_high);
11216      emit_insn(gen_rtx_SET(SImode, scratch1,
11217                            gen_rtx_LSHIFTRT (SImode, op2_high, GEN_INT(31))));
11218      emit_insn(gen_insv_t2(scratch2, GEN_INT(1), GEN_INT(31), scratch1));
11219      emit_move_insn (op0_low, op1_low);
11220      emit_move_insn (op0_high, scratch2);
11222      DONE;
11223   }"
11226 ;; Vector bits common to IWMMXT and Neon
11227 (include "vec-common.md")
11228 ;; Load the Intel Wireless Multimedia Extension patterns
11229 (include "iwmmxt.md")
11230 ;; Load the VFP co-processor patterns
11231 (include "vfp.md")
11232 ;; Thumb-1 patterns
11233 (include "thumb1.md")
11234 ;; Thumb-2 patterns
11235 (include "thumb2.md")
11236 ;; Neon patterns
11237 (include "neon.md")
11238 ;; Crypto patterns
11239 (include "crypto.md")
11240 ;; Synchronization Primitives
11241 (include "sync.md")
11242 ;; Fixed-point patterns
11243 (include "arm-fixed.md")