Rebase.
[official-gcc.git] / gcc / config / arm / arm.md
blob7a50993ca8363eba00286a2ea543164a3c5117c2
1 ;;- Machine description for ARM for GNU compiler
2 ;;  Copyright (C) 1991-2014 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.
25 ;; Beware of splitting Thumb1 patterns that output multiple
26 ;; assembly instructions, in particular instruction such as SBC and
27 ;; ADC which consume flags.  For example, in the pattern thumb_subdi3
28 ;; below, the output SUB implicitly sets the flags (assembled to SUBS)
29 ;; and then the Carry flag is used by SBC to compute the correct
30 ;; result.  If we split thumb_subdi3 pattern into two separate RTL
31 ;; insns (using define_insn_and_split), the scheduler might place
32 ;; other RTL insns between SUB and SBC, possibly modifying the Carry
33 ;; flag used by SBC.  This might happen because most Thumb1 patterns
34 ;; for flag-setting instructions do not have explicit RTL for setting
35 ;; or clobbering the flags.  Instead, they have the attribute "conds"
36 ;; with value "set" or "clob".  However, this attribute is not used to
37 ;; identify dependencies and therefore the scheduler might reorder
38 ;; these instruction.  Currenly, this problem cannot happen because
39 ;; there are no separate Thumb1 patterns for individual instruction
40 ;; that consume flags (except conditional execution, which is treated
41 ;; differently).  In particular there is no Thumb1 armv6-m pattern for
42 ;; sbc or adc.
45 ;;---------------------------------------------------------------------------
46 ;; Constants
48 ;; Register numbers -- All machine registers should be defined here
49 (define_constants
50   [(R0_REGNUM         0)        ; First CORE register
51    (R1_REGNUM         1)        ; Second CORE register
52    (IP_REGNUM        12)        ; Scratch register
53    (SP_REGNUM        13)        ; Stack pointer
54    (LR_REGNUM        14)        ; Return address register
55    (PC_REGNUM        15)        ; Program counter
56    (LAST_ARM_REGNUM  15)        ;
57    (CC_REGNUM       100)        ; Condition code pseudo register
58    (VFPCC_REGNUM    101)        ; VFP Condition code pseudo register
59   ]
61 ;; 3rd operand to select_dominance_cc_mode
62 (define_constants
63   [(DOM_CC_X_AND_Y  0)
64    (DOM_CC_NX_OR_Y  1)
65    (DOM_CC_X_OR_Y   2)
66   ]
68 ;; conditional compare combination
69 (define_constants
70   [(CMP_CMP 0)
71    (CMN_CMP 1)
72    (CMP_CMN 2)
73    (CMN_CMN 3)
74    (NUM_OF_COND_CMP 4)
75   ]
79 ;;---------------------------------------------------------------------------
80 ;; Attributes
82 ;; Processor type.  This is created automatically from arm-cores.def.
83 (include "arm-tune.md")
85 ;; Instruction classification types
86 (include "types.md")
88 ; IS_THUMB is set to 'yes' when we are generating Thumb code, and 'no' when
89 ; generating ARM code.  This is used to control the length of some insn
90 ; patterns that share the same RTL in both ARM and Thumb code.
91 (define_attr "is_thumb" "no,yes" (const (symbol_ref "thumb_code")))
93 ; IS_ARCH6 is set to 'yes' when we are generating code form ARMv6.
94 (define_attr "is_arch6" "no,yes" (const (symbol_ref "arm_arch6")))
96 ; IS_THUMB1 is set to 'yes' iff we are generating Thumb-1 code.
97 (define_attr "is_thumb1" "no,yes" (const (symbol_ref "thumb1_code")))
99 ; We use this attribute to disable alternatives that can produce 32-bit
100 ; instructions inside an IT-block in Thumb2 state.  ARMv8 deprecates IT blocks
101 ; that contain 32-bit instructions.
102 (define_attr "enabled_for_depr_it" "no,yes" (const_string "yes"))
104 ; This attribute is used to disable a predicated alternative when we have
105 ; arm_restrict_it.
106 (define_attr "predicable_short_it" "no,yes" (const_string "yes"))
108 ;; Operand number of an input operand that is shifted.  Zero if the
109 ;; given instruction does not shift one of its input operands.
110 (define_attr "shift" "" (const_int 0))
112 ; Floating Point Unit.  If we only have floating point emulation, then there
113 ; is no point in scheduling the floating point insns.  (Well, for best
114 ; performance we should try and group them together).
115 (define_attr "fpu" "none,vfp"
116   (const (symbol_ref "arm_fpu_attr")))
118 (define_attr "predicated" "yes,no" (const_string "no"))
120 ; LENGTH of an instruction (in bytes)
121 (define_attr "length" ""
122   (const_int 4))
124 ; The architecture which supports the instruction (or alternative).
125 ; This can be "a" for ARM, "t" for either of the Thumbs, "32" for
126 ; TARGET_32BIT, "t1" or "t2" to specify a specific Thumb mode.  "v6"
127 ; for ARM or Thumb-2 with arm_arch6, and nov6 for ARM without
128 ; arm_arch6.  This attribute is used to compute attribute "enabled",
129 ; use type "any" to enable an alternative in all cases.
130 (define_attr "arch" "any,a,t,32,t1,t2,v6,nov6,neon_for_64bits,avoid_neon_for_64bits,iwmmxt,iwmmxt2,armv6_or_vfpv3"
131   (const_string "any"))
133 (define_attr "arch_enabled" "no,yes"
134   (cond [(eq_attr "arch" "any")
135          (const_string "yes")
137          (and (eq_attr "arch" "a")
138               (match_test "TARGET_ARM"))
139          (const_string "yes")
141          (and (eq_attr "arch" "t")
142               (match_test "TARGET_THUMB"))
143          (const_string "yes")
145          (and (eq_attr "arch" "t1")
146               (match_test "TARGET_THUMB1"))
147          (const_string "yes")
149          (and (eq_attr "arch" "t2")
150               (match_test "TARGET_THUMB2"))
151          (const_string "yes")
153          (and (eq_attr "arch" "32")
154               (match_test "TARGET_32BIT"))
155          (const_string "yes")
157          (and (eq_attr "arch" "v6")
158               (match_test "TARGET_32BIT && arm_arch6"))
159          (const_string "yes")
161          (and (eq_attr "arch" "nov6")
162               (match_test "TARGET_32BIT && !arm_arch6"))
163          (const_string "yes")
165          (and (eq_attr "arch" "avoid_neon_for_64bits")
166               (match_test "TARGET_NEON")
167               (not (match_test "TARGET_PREFER_NEON_64BITS")))
168          (const_string "yes")
170          (and (eq_attr "arch" "neon_for_64bits")
171               (match_test "TARGET_NEON")
172               (match_test "TARGET_PREFER_NEON_64BITS"))
173          (const_string "yes")
175          (and (eq_attr "arch" "iwmmxt2")
176               (match_test "TARGET_REALLY_IWMMXT2"))
177          (const_string "yes")
179          (and (eq_attr "arch" "armv6_or_vfpv3")
180               (match_test "arm_arch6 || TARGET_VFP3"))
181          (const_string "yes")
182         ]
184         (const_string "no")))
186 (define_attr "opt" "any,speed,size"
187   (const_string "any"))
189 (define_attr "opt_enabled" "no,yes"
190   (cond [(eq_attr "opt" "any")
191          (const_string "yes")
193          (and (eq_attr "opt" "speed")
194               (match_test "optimize_function_for_speed_p (cfun)"))
195          (const_string "yes")
197          (and (eq_attr "opt" "size")
198               (match_test "optimize_function_for_size_p (cfun)"))
199          (const_string "yes")]
200         (const_string "no")))
202 (define_attr "use_literal_pool" "no,yes"
203    (cond [(and (eq_attr "type" "f_loads,f_loadd")
204                (match_test "CONSTANT_P (operands[1])"))
205           (const_string "yes")]
206          (const_string "no")))
208 ; Enable all alternatives that are both arch_enabled and insn_enabled.
209 ; FIXME:: opt_enabled has been temporarily removed till the time we have
210 ; an attribute that allows the use of such alternatives.
211 ; This depends on caching of speed_p, size_p on a per
212 ; alternative basis. The problem is that the enabled attribute
213 ; cannot depend on any state that is not cached or is not constant
214 ; for a compilation unit. We probably need a generic "hot/cold"
215 ; alternative which if implemented can help with this. We disable this
216 ; until such a time as this is implemented and / or the improvements or
217 ; regressions with removing this attribute are double checked.
218 ; See ashldi3_neon and <shift>di3_neon in neon.md.
220  (define_attr "enabled" "no,yes"
221    (cond [(and (eq_attr "predicable_short_it" "no")
222                (and (eq_attr "predicated" "yes")
223                     (match_test "arm_restrict_it")))
224           (const_string "no")
226           (and (eq_attr "enabled_for_depr_it" "no")
227                (match_test "arm_restrict_it"))
228           (const_string "no")
230           (and (eq_attr "use_literal_pool" "yes")
231                (match_test "arm_disable_literal_pool"))
232           (const_string "no")
234           (eq_attr "arch_enabled" "no")
235           (const_string "no")]
236          (const_string "yes")))
238 ; POOL_RANGE is how far away from a constant pool entry that this insn
239 ; can be placed.  If the distance is zero, then this insn will never
240 ; reference the pool.
241 ; Note that for Thumb constant pools the PC value is rounded down to the
242 ; nearest multiple of four.  Therefore, THUMB2_POOL_RANGE (and POOL_RANGE for
243 ; Thumb insns) should be set to <max_range> - 2.
244 ; NEG_POOL_RANGE is nonzero for insns that can reference a constant pool entry
245 ; before its address.  It is set to <max_range> - (8 + <data_size>).
246 (define_attr "arm_pool_range" "" (const_int 0))
247 (define_attr "thumb2_pool_range" "" (const_int 0))
248 (define_attr "arm_neg_pool_range" "" (const_int 0))
249 (define_attr "thumb2_neg_pool_range" "" (const_int 0))
251 (define_attr "pool_range" ""
252   (cond [(eq_attr "is_thumb" "yes") (attr "thumb2_pool_range")]
253         (attr "arm_pool_range")))
254 (define_attr "neg_pool_range" ""
255   (cond [(eq_attr "is_thumb" "yes") (attr "thumb2_neg_pool_range")]
256         (attr "arm_neg_pool_range")))
258 ; An assembler sequence may clobber the condition codes without us knowing.
259 ; If such an insn references the pool, then we have no way of knowing how,
260 ; so use the most conservative value for pool_range.
261 (define_asm_attributes
262  [(set_attr "conds" "clob")
263   (set_attr "length" "4")
264   (set_attr "pool_range" "250")])
266 ; Load scheduling, set from the arm_ld_sched variable
267 ; initialized by arm_option_override()
268 (define_attr "ldsched" "no,yes" (const (symbol_ref "arm_ld_sched")))
270 ; condition codes: this one is used by final_prescan_insn to speed up
271 ; conditionalizing instructions.  It saves having to scan the rtl to see if
272 ; it uses or alters the condition codes.
274 ; USE means that the condition codes are used by the insn in the process of
275 ;   outputting code, this means (at present) that we can't use the insn in
276 ;   inlined branches
278 ; SET means that the purpose of the insn is to set the condition codes in a
279 ;   well defined manner.
281 ; CLOB means that the condition codes are altered in an undefined manner, if
282 ;   they are altered at all
284 ; UNCONDITIONAL means the instruction can not be conditionally executed and
285 ;   that the instruction does not use or alter the condition codes.
287 ; NOCOND means that the instruction does not use or alter the condition
288 ;   codes but can be converted into a conditionally exectuted instruction.
290 (define_attr "conds" "use,set,clob,unconditional,nocond"
291         (if_then_else
292          (ior (eq_attr "is_thumb1" "yes")
293               (eq_attr "type" "call"))
294          (const_string "clob")
295          (if_then_else (eq_attr "is_neon_type" "no")
296          (const_string "nocond")
297          (const_string "unconditional"))))
299 ; Predicable means that the insn can be conditionally executed based on
300 ; an automatically added predicate (additional patterns are generated by 
301 ; gen...).  We default to 'no' because no Thumb patterns match this rule
302 ; and not all ARM patterns do.
303 (define_attr "predicable" "no,yes" (const_string "no"))
305 ; Only model the write buffer for ARM6 and ARM7.  Earlier processors don't
306 ; have one.  Later ones, such as StrongARM, have write-back caches, so don't
307 ; suffer blockages enough to warrant modelling this (and it can adversely
308 ; affect the schedule).
309 (define_attr "model_wbuf" "no,yes" (const (symbol_ref "arm_tune_wbuf")))
311 ; WRITE_CONFLICT implies that a read following an unrelated write is likely
312 ; to stall the processor.  Used with model_wbuf above.
313 (define_attr "write_conflict" "no,yes"
314   (if_then_else (eq_attr "type"
315                  "block,call,load1")
316                 (const_string "yes")
317                 (const_string "no")))
319 ; Classify the insns into those that take one cycle and those that take more
320 ; than one on the main cpu execution unit.
321 (define_attr "core_cycles" "single,multi"
322   (if_then_else (eq_attr "type"
323     "adc_imm, adc_reg, adcs_imm, adcs_reg, adr, alu_ext, alu_imm, alu_sreg,\
324     alu_shift_imm, alu_shift_reg, alu_dsp_reg, alus_ext, alus_imm, alus_sreg,\
325     alus_shift_imm, alus_shift_reg, bfm, csel, rev, logic_imm, logic_reg,\
326     logic_shift_imm, logic_shift_reg, logics_imm, logics_reg,\
327     logics_shift_imm, logics_shift_reg, extend, shift_imm, float, fcsel,\
328     wmmx_wor, wmmx_wxor, wmmx_wand, wmmx_wandn, wmmx_wmov, wmmx_tmcrr,\
329     wmmx_tmrrc, wmmx_wldr, wmmx_wstr, wmmx_tmcr, wmmx_tmrc, wmmx_wadd,\
330     wmmx_wsub, wmmx_wmul, wmmx_wmac, wmmx_wavg2, wmmx_tinsr, wmmx_textrm,\
331     wmmx_wshufh, wmmx_wcmpeq, wmmx_wcmpgt, wmmx_wmax, wmmx_wmin, wmmx_wpack,\
332     wmmx_wunpckih, wmmx_wunpckil, wmmx_wunpckeh, wmmx_wunpckel, wmmx_wror,\
333     wmmx_wsra, wmmx_wsrl, wmmx_wsll, wmmx_wmadd, wmmx_tmia, wmmx_tmiaph,\
334     wmmx_tmiaxy, wmmx_tbcst, wmmx_tmovmsk, wmmx_wacc, wmmx_waligni,\
335     wmmx_walignr, wmmx_tandc, wmmx_textrc, wmmx_torc, wmmx_torvsc, wmmx_wsad,\
336     wmmx_wabs, wmmx_wabsdiff, wmmx_waddsubhx, wmmx_wsubaddhx, wmmx_wavg4,\
337     wmmx_wmulw, wmmx_wqmulm, wmmx_wqmulwm, wmmx_waddbhus, wmmx_wqmiaxy,\
338     wmmx_wmiaxy, wmmx_wmiawxy, wmmx_wmerge")
339                 (const_string "single")
340                 (const_string "multi")))
342 ;; FAR_JUMP is "yes" if a BL instruction is used to generate a branch to a
343 ;; distant label.  Only applicable to Thumb code.
344 (define_attr "far_jump" "yes,no" (const_string "no"))
347 ;; The number of machine instructions this pattern expands to.
348 ;; Used for Thumb-2 conditional execution.
349 (define_attr "ce_count" "" (const_int 1))
351 ;;---------------------------------------------------------------------------
352 ;; Unspecs
354 (include "unspecs.md")
356 ;;---------------------------------------------------------------------------
357 ;; Mode iterators
359 (include "iterators.md")
361 ;;---------------------------------------------------------------------------
362 ;; Predicates
364 (include "predicates.md")
365 (include "constraints.md")
367 ;;---------------------------------------------------------------------------
368 ;; Pipeline descriptions
370 (define_attr "tune_cortexr4" "yes,no"
371   (const (if_then_else
372           (eq_attr "tune" "cortexr4,cortexr4f,cortexr5")
373           (const_string "yes")
374           (const_string "no"))))
376 ;; True if the generic scheduling description should be used.
378 (define_attr "generic_sched" "yes,no"
379   (const (if_then_else
380           (ior (eq_attr "tune" "fa526,fa626,fa606te,fa626te,fmp626,fa726te,arm926ejs,arm1020e,arm1026ejs,arm1136js,arm1136jfs,cortexa5,cortexa7,cortexa8,cortexa9,cortexa12,cortexa15,cortexa53,cortexm4,marvell_pj4")
381                (eq_attr "tune_cortexr4" "yes"))
382           (const_string "no")
383           (const_string "yes"))))
385 (define_attr "generic_vfp" "yes,no"
386   (const (if_then_else
387           (and (eq_attr "fpu" "vfp")
388                (eq_attr "tune" "!arm1020e,arm1022e,cortexa5,cortexa7,cortexa8,cortexa9,cortexa53,cortexm4,marvell_pj4")
389                (eq_attr "tune_cortexr4" "no"))
390           (const_string "yes")
391           (const_string "no"))))
393 (include "marvell-f-iwmmxt.md")
394 (include "arm-generic.md")
395 (include "arm926ejs.md")
396 (include "arm1020e.md")
397 (include "arm1026ejs.md")
398 (include "arm1136jfs.md")
399 (include "fa526.md")
400 (include "fa606te.md")
401 (include "fa626te.md")
402 (include "fmp626.md")
403 (include "fa726te.md")
404 (include "cortex-a5.md")
405 (include "cortex-a7.md")
406 (include "cortex-a8.md")
407 (include "cortex-a9.md")
408 (include "cortex-a15.md")
409 (include "cortex-a53.md")
410 (include "cortex-r4.md")
411 (include "cortex-r4f.md")
412 (include "cortex-m4.md")
413 (include "cortex-m4-fpu.md")
414 (include "vfp11.md")
415 (include "marvell-pj4.md")
418 ;;---------------------------------------------------------------------------
419 ;; Insn patterns
421 ;; Addition insns.
423 ;; Note: For DImode insns, there is normally no reason why operands should
424 ;; not be in the same register, what we don't want is for something being
425 ;; written to partially overlap something that is an input.
427 (define_expand "adddi3"
428  [(parallel
429    [(set (match_operand:DI           0 "s_register_operand" "")
430           (plus:DI (match_operand:DI 1 "s_register_operand" "")
431                    (match_operand:DI 2 "arm_adddi_operand"  "")))
432     (clobber (reg:CC CC_REGNUM))])]
433   "TARGET_EITHER"
434   "
435   if (TARGET_THUMB1)
436     {
437       if (!REG_P (operands[1]))
438         operands[1] = force_reg (DImode, operands[1]);
439       if (!REG_P (operands[2]))
440         operands[2] = force_reg (DImode, operands[2]);
441      }
442   "
445 (define_insn_and_split "*arm_adddi3"
446   [(set (match_operand:DI          0 "s_register_operand" "=&r,&r,&r,&r,&r")
447         (plus:DI (match_operand:DI 1 "s_register_operand" "%0, 0, r, 0, r")
448                  (match_operand:DI 2 "arm_adddi_operand"  "r,  0, r, Dd, Dd")))
449    (clobber (reg:CC CC_REGNUM))]
450   "TARGET_32BIT && !TARGET_NEON"
451   "#"
452   "TARGET_32BIT && reload_completed
453    && ! (TARGET_NEON && IS_VFP_REGNUM (REGNO (operands[0])))"
454   [(parallel [(set (reg:CC_C CC_REGNUM)
455                    (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
456                                  (match_dup 1)))
457               (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
458    (set (match_dup 3) (plus:SI (plus:SI (match_dup 4) (match_dup 5))
459                                (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
460   "
461   {
462     operands[3] = gen_highpart (SImode, operands[0]);
463     operands[0] = gen_lowpart (SImode, operands[0]);
464     operands[4] = gen_highpart (SImode, operands[1]);
465     operands[1] = gen_lowpart (SImode, operands[1]);
466     operands[5] = gen_highpart_mode (SImode, DImode, operands[2]);
467     operands[2] = gen_lowpart (SImode, operands[2]);
468   }"
469   [(set_attr "conds" "clob")
470    (set_attr "length" "8")
471    (set_attr "type" "multiple")]
474 (define_insn_and_split "*adddi_sesidi_di"
475   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
476         (plus:DI (sign_extend:DI
477                   (match_operand:SI 2 "s_register_operand" "r,r"))
478                  (match_operand:DI 1 "s_register_operand" "0,r")))
479    (clobber (reg:CC CC_REGNUM))]
480   "TARGET_32BIT"
481   "#"
482   "TARGET_32BIT && reload_completed"
483   [(parallel [(set (reg:CC_C CC_REGNUM)
484                    (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
485                                  (match_dup 1)))
486               (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
487    (set (match_dup 3) (plus:SI (plus:SI (ashiftrt:SI (match_dup 2)
488                                                      (const_int 31))
489                                         (match_dup 4))
490                                (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
491   "
492   {
493     operands[3] = gen_highpart (SImode, operands[0]);
494     operands[0] = gen_lowpart (SImode, operands[0]);
495     operands[4] = gen_highpart (SImode, operands[1]);
496     operands[1] = gen_lowpart (SImode, operands[1]);
497     operands[2] = gen_lowpart (SImode, operands[2]);
498   }"
499   [(set_attr "conds" "clob")
500    (set_attr "length" "8")
501    (set_attr "type" "multiple")]
504 (define_insn_and_split "*adddi_zesidi_di"
505   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
506         (plus:DI (zero_extend:DI
507                   (match_operand:SI 2 "s_register_operand" "r,r"))
508                  (match_operand:DI 1 "s_register_operand" "0,r")))
509    (clobber (reg:CC CC_REGNUM))]
510   "TARGET_32BIT"
511   "#"
512   "TARGET_32BIT && reload_completed"
513   [(parallel [(set (reg:CC_C CC_REGNUM)
514                    (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
515                                  (match_dup 1)))
516               (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
517    (set (match_dup 3) (plus:SI (plus:SI (match_dup 4) (const_int 0))
518                                (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
519   "
520   {
521     operands[3] = gen_highpart (SImode, operands[0]);
522     operands[0] = gen_lowpart (SImode, operands[0]);
523     operands[4] = gen_highpart (SImode, operands[1]);
524     operands[1] = gen_lowpart (SImode, operands[1]);
525     operands[2] = gen_lowpart (SImode, operands[2]);
526   }"
527   [(set_attr "conds" "clob")
528    (set_attr "length" "8")
529    (set_attr "type" "multiple")]
532 (define_expand "addsi3"
533   [(set (match_operand:SI          0 "s_register_operand" "")
534         (plus:SI (match_operand:SI 1 "s_register_operand" "")
535                  (match_operand:SI 2 "reg_or_int_operand" "")))]
536   "TARGET_EITHER"
537   "
538   if (TARGET_32BIT && CONST_INT_P (operands[2]))
539     {
540       arm_split_constant (PLUS, SImode, NULL_RTX,
541                           INTVAL (operands[2]), operands[0], operands[1],
542                           optimize && can_create_pseudo_p ());
543       DONE;
544     }
545   "
548 ; If there is a scratch available, this will be faster than synthesizing the
549 ; addition.
550 (define_peephole2
551   [(match_scratch:SI 3 "r")
552    (set (match_operand:SI          0 "arm_general_register_operand" "")
553         (plus:SI (match_operand:SI 1 "arm_general_register_operand" "")
554                  (match_operand:SI 2 "const_int_operand"  "")))]
555   "TARGET_32BIT &&
556    !(const_ok_for_arm (INTVAL (operands[2]))
557      || const_ok_for_arm (-INTVAL (operands[2])))
558     && const_ok_for_arm (~INTVAL (operands[2]))"
559   [(set (match_dup 3) (match_dup 2))
560    (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 3)))]
561   ""
564 ;; The r/r/k alternative is required when reloading the address
565 ;;  (plus (reg rN) (reg sp)) into (reg rN).  In this case reload will
566 ;; put the duplicated register first, and not try the commutative version.
567 (define_insn_and_split "*arm_addsi3"
568   [(set (match_operand:SI          0 "s_register_operand" "=rk,l,l ,l ,r ,k ,r,r ,k ,r ,k,k,r ,k ,r")
569         (plus:SI (match_operand:SI 1 "s_register_operand" "%0 ,l,0 ,l ,rk,k ,r,rk,k ,rk,k,r,rk,k ,rk")
570                  (match_operand:SI 2 "reg_or_int_operand" "rk ,l,Py,Pd,rI,rI,k,Pj,Pj,L ,L,L,PJ,PJ,?n")))]
571   "TARGET_32BIT"
572   "@
573    add%?\\t%0, %0, %2
574    add%?\\t%0, %1, %2
575    add%?\\t%0, %1, %2
576    add%?\\t%0, %1, %2
577    add%?\\t%0, %1, %2
578    add%?\\t%0, %1, %2
579    add%?\\t%0, %2, %1
580    addw%?\\t%0, %1, %2
581    addw%?\\t%0, %1, %2
582    sub%?\\t%0, %1, #%n2
583    sub%?\\t%0, %1, #%n2
584    sub%?\\t%0, %1, #%n2
585    subw%?\\t%0, %1, #%n2
586    subw%?\\t%0, %1, #%n2
587    #"
588   "TARGET_32BIT
589    && CONST_INT_P (operands[2])
590    && !const_ok_for_op (INTVAL (operands[2]), PLUS)
591    && (reload_completed || !arm_eliminable_register (operands[1]))"
592   [(clobber (const_int 0))]
593   "
594   arm_split_constant (PLUS, SImode, curr_insn,
595                       INTVAL (operands[2]), operands[0],
596                       operands[1], 0);
597   DONE;
598   "
599   [(set_attr "length" "2,4,4,4,4,4,4,4,4,4,4,4,4,4,16")
600    (set_attr "predicable" "yes")
601    (set_attr "predicable_short_it" "yes,yes,yes,yes,no,no,no,no,no,no,no,no,no,no,no")
602    (set_attr "arch" "t2,t2,t2,t2,*,*,*,t2,t2,*,*,a,t2,t2,*")
603    (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
604                       (const_string "alu_imm")
605                       (const_string "alu_sreg")))
609 (define_insn "addsi3_compare0"
610   [(set (reg:CC_NOOV CC_REGNUM)
611         (compare:CC_NOOV
612          (plus:SI (match_operand:SI 1 "s_register_operand" "r, r,r")
613                   (match_operand:SI 2 "arm_add_operand"    "I,L,r"))
614          (const_int 0)))
615    (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
616         (plus:SI (match_dup 1) (match_dup 2)))]
617   "TARGET_ARM"
618   "@
619    add%.\\t%0, %1, %2
620    sub%.\\t%0, %1, #%n2
621    add%.\\t%0, %1, %2"
622   [(set_attr "conds" "set")
623    (set_attr "type" "alus_imm,alus_imm,alus_sreg")]
626 (define_insn "*addsi3_compare0_scratch"
627   [(set (reg:CC_NOOV CC_REGNUM)
628         (compare:CC_NOOV
629          (plus:SI (match_operand:SI 0 "s_register_operand" "r, r, r")
630                   (match_operand:SI 1 "arm_add_operand"    "I,L, r"))
631          (const_int 0)))]
632   "TARGET_ARM"
633   "@
634    cmn%?\\t%0, %1
635    cmp%?\\t%0, #%n1
636    cmn%?\\t%0, %1"
637   [(set_attr "conds" "set")
638    (set_attr "predicable" "yes")
639    (set_attr "type" "alus_imm,alus_imm,alus_sreg")]
642 (define_insn "*compare_negsi_si"
643   [(set (reg:CC_Z CC_REGNUM)
644         (compare:CC_Z
645          (neg:SI (match_operand:SI 0 "s_register_operand" "l,r"))
646          (match_operand:SI 1 "s_register_operand" "l,r")))]
647   "TARGET_32BIT"
648   "cmn%?\\t%1, %0"
649   [(set_attr "conds" "set")
650    (set_attr "predicable" "yes")
651    (set_attr "arch" "t2,*")
652    (set_attr "length" "2,4")
653    (set_attr "predicable_short_it" "yes,no")
654    (set_attr "type" "alus_sreg")]
657 ;; This is the canonicalization of addsi3_compare0_for_combiner when the
658 ;; addend is a constant.
659 (define_insn "cmpsi2_addneg"
660   [(set (reg:CC CC_REGNUM)
661         (compare:CC
662          (match_operand:SI 1 "s_register_operand" "r,r")
663          (match_operand:SI 2 "arm_addimm_operand" "L,I")))
664    (set (match_operand:SI 0 "s_register_operand" "=r,r")
665         (plus:SI (match_dup 1)
666                  (match_operand:SI 3 "arm_addimm_operand" "I,L")))]
667   "TARGET_32BIT && INTVAL (operands[2]) == -INTVAL (operands[3])"
668   "@
669    add%.\\t%0, %1, %3
670    sub%.\\t%0, %1, #%n3"
671   [(set_attr "conds" "set")
672    (set_attr "type" "alus_sreg")]
675 ;; Convert the sequence
676 ;;  sub  rd, rn, #1
677 ;;  cmn  rd, #1 (equivalent to cmp rd, #-1)
678 ;;  bne  dest
679 ;; into
680 ;;  subs rd, rn, #1
681 ;;  bcs  dest   ((unsigned)rn >= 1)
682 ;; similarly for the beq variant using bcc.
683 ;; This is a common looping idiom (while (n--))
684 (define_peephole2
685   [(set (match_operand:SI 0 "arm_general_register_operand" "")
686         (plus:SI (match_operand:SI 1 "arm_general_register_operand" "")
687                  (const_int -1)))
688    (set (match_operand 2 "cc_register" "")
689         (compare (match_dup 0) (const_int -1)))
690    (set (pc)
691         (if_then_else (match_operator 3 "equality_operator"
692                        [(match_dup 2) (const_int 0)])
693                       (match_operand 4 "" "")
694                       (match_operand 5 "" "")))]
695   "TARGET_32BIT && peep2_reg_dead_p (3, operands[2])"
696   [(parallel[
697     (set (match_dup 2)
698          (compare:CC
699           (match_dup 1) (const_int 1)))
700     (set (match_dup 0) (plus:SI (match_dup 1) (const_int -1)))])
701    (set (pc)
702         (if_then_else (match_op_dup 3 [(match_dup 2) (const_int 0)])
703                       (match_dup 4)
704                       (match_dup 5)))]
705   "operands[2] = gen_rtx_REG (CCmode, CC_REGNUM);
706    operands[3] = gen_rtx_fmt_ee ((GET_CODE (operands[3]) == NE
707                                   ? GEU : LTU),
708                                  VOIDmode, 
709                                  operands[2], const0_rtx);"
712 ;; The next four insns work because they compare the result with one of
713 ;; the operands, and we know that the use of the condition code is
714 ;; either GEU or LTU, so we can use the carry flag from the addition
715 ;; instead of doing the compare a second time.
716 (define_insn "*addsi3_compare_op1"
717   [(set (reg:CC_C CC_REGNUM)
718         (compare:CC_C
719          (plus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
720                   (match_operand:SI 2 "arm_add_operand" "I,L,r"))
721          (match_dup 1)))
722    (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
723         (plus:SI (match_dup 1) (match_dup 2)))]
724   "TARGET_32BIT"
725   "@
726    add%.\\t%0, %1, %2
727    sub%.\\t%0, %1, #%n2
728    add%.\\t%0, %1, %2"
729   [(set_attr "conds" "set")
730    (set_attr "type"  "alus_imm,alus_imm,alus_sreg")]
733 (define_insn "*addsi3_compare_op2"
734   [(set (reg:CC_C CC_REGNUM)
735         (compare:CC_C
736          (plus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
737                   (match_operand:SI 2 "arm_add_operand" "I,L,r"))
738          (match_dup 2)))
739    (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
740         (plus:SI (match_dup 1) (match_dup 2)))]
741   "TARGET_32BIT"
742   "@
743    add%.\\t%0, %1, %2
744    add%.\\t%0, %1, %2
745    sub%.\\t%0, %1, #%n2"
746   [(set_attr "conds" "set")
747    (set_attr "type" "alus_imm,alus_imm,alus_sreg")]
750 (define_insn "*compare_addsi2_op0"
751   [(set (reg:CC_C CC_REGNUM)
752         (compare:CC_C
753           (plus:SI (match_operand:SI 0 "s_register_operand" "l,l,r,r,r")
754                    (match_operand:SI 1 "arm_add_operand" "Pv,l,I,L,r"))
755           (match_dup 0)))]
756   "TARGET_32BIT"
757   "@
758    cmp%?\\t%0, #%n1
759    cmn%?\\t%0, %1
760    cmn%?\\t%0, %1
761    cmp%?\\t%0, #%n1
762    cmn%?\\t%0, %1"
763   [(set_attr "conds" "set")
764    (set_attr "predicable" "yes")
765    (set_attr "arch" "t2,t2,*,*,*")
766    (set_attr "predicable_short_it" "yes,yes,no,no,no")
767    (set_attr "length" "2,2,4,4,4")
768    (set_attr "type" "alus_imm,alus_sreg,alus_imm,alus_imm,alus_sreg")]
771 (define_insn "*compare_addsi2_op1"
772   [(set (reg:CC_C CC_REGNUM)
773         (compare:CC_C
774           (plus:SI (match_operand:SI 0 "s_register_operand" "l,l,r,r,r")
775                    (match_operand:SI 1 "arm_add_operand" "Pv,l,I,L,r"))
776           (match_dup 1)))]
777   "TARGET_32BIT"
778   "@
779    cmp%?\\t%0, #%n1
780    cmn%?\\t%0, %1
781    cmn%?\\t%0, %1
782    cmp%?\\t%0, #%n1
783    cmn%?\\t%0, %1"
784   [(set_attr "conds" "set")
785    (set_attr "predicable" "yes")
786    (set_attr "arch" "t2,t2,*,*,*")
787    (set_attr "predicable_short_it" "yes,yes,no,no,no")
788    (set_attr "length" "2,2,4,4,4")
789    (set_attr "type" "alus_imm,alus_sreg,alus_imm,alus_imm,alus_sreg")]
792 (define_insn "*addsi3_carryin_<optab>"
793   [(set (match_operand:SI 0 "s_register_operand" "=l,r,r")
794         (plus:SI (plus:SI (match_operand:SI 1 "s_register_operand" "%l,r,r")
795                           (match_operand:SI 2 "arm_not_operand" "0,rI,K"))
796                  (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))))]
797   "TARGET_32BIT"
798   "@
799    adc%?\\t%0, %1, %2
800    adc%?\\t%0, %1, %2
801    sbc%?\\t%0, %1, #%B2"
802   [(set_attr "conds" "use")
803    (set_attr "predicable" "yes")
804    (set_attr "arch" "t2,*,*")
805    (set_attr "length" "4")
806    (set_attr "predicable_short_it" "yes,no,no")
807    (set_attr "type" "adc_reg,adc_reg,adc_imm")]
810 (define_insn "*addsi3_carryin_alt2_<optab>"
811   [(set (match_operand:SI 0 "s_register_operand" "=l,r,r")
812         (plus:SI (plus:SI (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))
813                           (match_operand:SI 1 "s_register_operand" "%l,r,r"))
814                  (match_operand:SI 2 "arm_rhs_operand" "l,rI,K")))]
815   "TARGET_32BIT"
816   "@
817    adc%?\\t%0, %1, %2
818    adc%?\\t%0, %1, %2
819    sbc%?\\t%0, %1, #%B2"
820   [(set_attr "conds" "use")
821    (set_attr "predicable" "yes")
822    (set_attr "arch" "t2,*,*")
823    (set_attr "length" "4")
824    (set_attr "predicable_short_it" "yes,no,no")
825    (set_attr "type" "adc_reg,adc_reg,adc_imm")]
828 (define_insn "*addsi3_carryin_shift_<optab>"
829   [(set (match_operand:SI 0 "s_register_operand" "=r")
830         (plus:SI (plus:SI
831                   (match_operator:SI 2 "shift_operator"
832                     [(match_operand:SI 3 "s_register_operand" "r")
833                      (match_operand:SI 4 "reg_or_int_operand" "rM")])
834                   (match_operand:SI 1 "s_register_operand" "r"))
835                  (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))))]
836   "TARGET_32BIT"
837   "adc%?\\t%0, %1, %3%S2"
838   [(set_attr "conds" "use")
839    (set_attr "predicable" "yes")
840    (set_attr "predicable_short_it" "no")
841    (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
842                       (const_string "alu_shift_imm")
843                       (const_string "alu_shift_reg")))]
846 (define_insn "*addsi3_carryin_clobercc_<optab>"
847   [(set (match_operand:SI 0 "s_register_operand" "=r")
848         (plus:SI (plus:SI (match_operand:SI 1 "s_register_operand" "%r")
849                           (match_operand:SI 2 "arm_rhs_operand" "rI"))
850                  (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))))
851    (clobber (reg:CC CC_REGNUM))]
852    "TARGET_32BIT"
853    "adc%.\\t%0, %1, %2"
854    [(set_attr "conds" "set")
855     (set_attr "type" "adcs_reg")]
858 (define_insn "*subsi3_carryin"
859   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
860         (minus:SI (minus:SI (match_operand:SI 1 "reg_or_int_operand" "r,I")
861                             (match_operand:SI 2 "s_register_operand" "r,r"))
862                   (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
863   "TARGET_32BIT"
864   "@
865    sbc%?\\t%0, %1, %2
866    rsc%?\\t%0, %2, %1"
867   [(set_attr "conds" "use")
868    (set_attr "arch" "*,a")
869    (set_attr "predicable" "yes")
870    (set_attr "predicable_short_it" "no")
871    (set_attr "type" "adc_reg,adc_imm")]
874 (define_insn "*subsi3_carryin_const"
875   [(set (match_operand:SI 0 "s_register_operand" "=r")
876         (minus:SI (plus:SI (match_operand:SI 1 "reg_or_int_operand" "r")
877                            (match_operand:SI 2 "arm_not_operand" "K"))
878                   (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
879   "TARGET_32BIT"
880   "sbc\\t%0, %1, #%B2"
881   [(set_attr "conds" "use")
882    (set_attr "type" "adc_imm")]
885 (define_insn "*subsi3_carryin_compare"
886   [(set (reg:CC CC_REGNUM)
887         (compare:CC (match_operand:SI 1 "s_register_operand" "r")
888                     (match_operand:SI 2 "s_register_operand" "r")))
889    (set (match_operand:SI 0 "s_register_operand" "=r")
890         (minus:SI (minus:SI (match_dup 1)
891                             (match_dup 2))
892                   (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
893   "TARGET_32BIT"
894   "sbcs\\t%0, %1, %2"
895   [(set_attr "conds" "set")
896    (set_attr "type" "adcs_reg")]
899 (define_insn "*subsi3_carryin_compare_const"
900   [(set (reg:CC CC_REGNUM)
901         (compare:CC (match_operand:SI 1 "reg_or_int_operand" "r")
902                     (match_operand:SI 2 "arm_not_operand" "K")))
903    (set (match_operand:SI 0 "s_register_operand" "=r")
904         (minus:SI (plus:SI (match_dup 1)
905                            (match_dup 2))
906                   (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
907   "TARGET_32BIT"
908   "sbcs\\t%0, %1, #%B2"
909   [(set_attr "conds" "set")
910    (set_attr "type" "adcs_imm")]
913 (define_insn "*subsi3_carryin_shift"
914   [(set (match_operand:SI 0 "s_register_operand" "=r")
915         (minus:SI (minus:SI
916                   (match_operand:SI 1 "s_register_operand" "r")
917                   (match_operator:SI 2 "shift_operator"
918                    [(match_operand:SI 3 "s_register_operand" "r")
919                     (match_operand:SI 4 "reg_or_int_operand" "rM")]))
920                  (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
921   "TARGET_32BIT"
922   "sbc%?\\t%0, %1, %3%S2"
923   [(set_attr "conds" "use")
924    (set_attr "predicable" "yes")
925    (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
926                       (const_string "alu_shift_imm")
927                      (const_string "alu_shift_reg")))]
930 (define_insn "*rsbsi3_carryin_shift"
931   [(set (match_operand:SI 0 "s_register_operand" "=r")
932         (minus:SI (minus:SI
933                   (match_operator:SI 2 "shift_operator"
934                    [(match_operand:SI 3 "s_register_operand" "r")
935                     (match_operand:SI 4 "reg_or_int_operand" "rM")])
936                    (match_operand:SI 1 "s_register_operand" "r"))
937                  (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
938   "TARGET_ARM"
939   "rsc%?\\t%0, %1, %3%S2"
940   [(set_attr "conds" "use")
941    (set_attr "predicable" "yes")
942    (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
943                       (const_string "alu_shift_imm")
944                       (const_string "alu_shift_reg")))]
947 ; transform ((x << y) - 1) to ~(~(x-1) << y)  Where X is a constant.
948 (define_split
949   [(set (match_operand:SI 0 "s_register_operand" "")
950         (plus:SI (ashift:SI (match_operand:SI 1 "const_int_operand" "")
951                             (match_operand:SI 2 "s_register_operand" ""))
952                  (const_int -1)))
953    (clobber (match_operand:SI 3 "s_register_operand" ""))]
954   "TARGET_32BIT"
955   [(set (match_dup 3) (match_dup 1))
956    (set (match_dup 0) (not:SI (ashift:SI (match_dup 3) (match_dup 2))))]
957   "
958   operands[1] = GEN_INT (~(INTVAL (operands[1]) - 1));
961 (define_expand "addsf3"
962   [(set (match_operand:SF          0 "s_register_operand" "")
963         (plus:SF (match_operand:SF 1 "s_register_operand" "")
964                  (match_operand:SF 2 "s_register_operand" "")))]
965   "TARGET_32BIT && TARGET_HARD_FLOAT"
966   "
969 (define_expand "adddf3"
970   [(set (match_operand:DF          0 "s_register_operand" "")
971         (plus:DF (match_operand:DF 1 "s_register_operand" "")
972                  (match_operand:DF 2 "s_register_operand" "")))]
973   "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
974   "
977 (define_expand "subdi3"
978  [(parallel
979    [(set (match_operand:DI            0 "s_register_operand" "")
980           (minus:DI (match_operand:DI 1 "s_register_operand" "")
981                     (match_operand:DI 2 "s_register_operand" "")))
982     (clobber (reg:CC CC_REGNUM))])]
983   "TARGET_EITHER"
984   "
985   if (TARGET_THUMB1)
986     {
987       if (!REG_P (operands[1]))
988         operands[1] = force_reg (DImode, operands[1]);
989       if (!REG_P (operands[2]))
990         operands[2] = force_reg (DImode, operands[2]);
991      }  
992   "
995 (define_insn_and_split "*arm_subdi3"
996   [(set (match_operand:DI           0 "s_register_operand" "=&r,&r,&r")
997         (minus:DI (match_operand:DI 1 "s_register_operand" "0,r,0")
998                   (match_operand:DI 2 "s_register_operand" "r,0,0")))
999    (clobber (reg:CC CC_REGNUM))]
1000   "TARGET_32BIT && !TARGET_NEON"
1001   "#"  ; "subs\\t%Q0, %Q1, %Q2\;sbc\\t%R0, %R1, %R2"
1002   "&& reload_completed"
1003   [(parallel [(set (reg:CC CC_REGNUM)
1004                    (compare:CC (match_dup 1) (match_dup 2)))
1005               (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1006    (set (match_dup 3) (minus:SI (minus:SI (match_dup 4) (match_dup 5))
1007                                (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1008   {
1009     operands[3] = gen_highpart (SImode, operands[0]);
1010     operands[0] = gen_lowpart (SImode, operands[0]);
1011     operands[4] = gen_highpart (SImode, operands[1]);
1012     operands[1] = gen_lowpart (SImode, operands[1]);
1013     operands[5] = gen_highpart (SImode, operands[2]);
1014     operands[2] = gen_lowpart (SImode, operands[2]);
1015    }
1016   [(set_attr "conds" "clob")
1017    (set_attr "length" "8")
1018    (set_attr "type" "multiple")]
1021 (define_insn_and_split "*subdi_di_zesidi"
1022   [(set (match_operand:DI           0 "s_register_operand" "=&r,&r")
1023         (minus:DI (match_operand:DI 1 "s_register_operand"  "0,r")
1024                   (zero_extend:DI
1025                    (match_operand:SI 2 "s_register_operand"  "r,r"))))
1026    (clobber (reg:CC CC_REGNUM))]
1027   "TARGET_32BIT"
1028   "#"   ; "subs\\t%Q0, %Q1, %2\;sbc\\t%R0, %R1, #0"
1029   "&& reload_completed"
1030   [(parallel [(set (reg:CC CC_REGNUM)
1031                    (compare:CC (match_dup 1) (match_dup 2)))
1032               (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1033    (set (match_dup 3) (minus:SI (plus:SI (match_dup 4) (match_dup 5))
1034                                 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1035   {
1036     operands[3] = gen_highpart (SImode, operands[0]);
1037     operands[0] = gen_lowpart (SImode, operands[0]);
1038     operands[4] = gen_highpart (SImode, operands[1]);
1039     operands[1] = gen_lowpart (SImode, operands[1]);
1040     operands[5] = GEN_INT (~0);
1041    }
1042   [(set_attr "conds" "clob")
1043    (set_attr "length" "8")
1044    (set_attr "type" "multiple")]
1047 (define_insn_and_split "*subdi_di_sesidi"
1048   [(set (match_operand:DI            0 "s_register_operand" "=&r,&r")
1049         (minus:DI (match_operand:DI  1 "s_register_operand"  "0,r")
1050                   (sign_extend:DI
1051                    (match_operand:SI 2 "s_register_operand"  "r,r"))))
1052    (clobber (reg:CC CC_REGNUM))]
1053   "TARGET_32BIT"
1054   "#"   ; "subs\\t%Q0, %Q1, %2\;sbc\\t%R0, %R1, %2, asr #31"
1055   "&& reload_completed"
1056   [(parallel [(set (reg:CC CC_REGNUM)
1057                    (compare:CC (match_dup 1) (match_dup 2)))
1058               (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1059    (set (match_dup 3) (minus:SI (minus:SI (match_dup 4)
1060                                          (ashiftrt:SI (match_dup 2)
1061                                                       (const_int 31)))
1062                                 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1063   {
1064     operands[3] = gen_highpart (SImode, operands[0]);
1065     operands[0] = gen_lowpart (SImode, operands[0]);
1066     operands[4] = gen_highpart (SImode, operands[1]);
1067     operands[1] = gen_lowpart (SImode, operands[1]);
1068   }
1069   [(set_attr "conds" "clob")
1070    (set_attr "length" "8")
1071    (set_attr "type" "multiple")]
1074 (define_insn_and_split "*subdi_zesidi_di"
1075   [(set (match_operand:DI            0 "s_register_operand" "=&r,&r")
1076         (minus:DI (zero_extend:DI
1077                    (match_operand:SI 2 "s_register_operand"  "r,r"))
1078                   (match_operand:DI  1 "s_register_operand" "0,r")))
1079    (clobber (reg:CC CC_REGNUM))]
1080   "TARGET_ARM"
1081   "#"   ; "rsbs\\t%Q0, %Q1, %2\;rsc\\t%R0, %R1, #0"
1082         ; is equivalent to:
1083         ; "subs\\t%Q0, %2, %Q1\;rsc\\t%R0, %R1, #0"
1084   "&& reload_completed"
1085   [(parallel [(set (reg:CC CC_REGNUM)
1086                    (compare:CC (match_dup 2) (match_dup 1)))
1087               (set (match_dup 0) (minus:SI (match_dup 2) (match_dup 1)))])
1088    (set (match_dup 3) (minus:SI (minus:SI (const_int 0) (match_dup 4))
1089                                (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1090   {
1091     operands[3] = gen_highpart (SImode, operands[0]);
1092     operands[0] = gen_lowpart (SImode, operands[0]);
1093     operands[4] = gen_highpart (SImode, operands[1]);
1094     operands[1] = gen_lowpart (SImode, operands[1]);
1095   }
1096   [(set_attr "conds" "clob")
1097    (set_attr "length" "8")
1098    (set_attr "type" "multiple")]
1101 (define_insn_and_split "*subdi_sesidi_di"
1102   [(set (match_operand:DI            0 "s_register_operand" "=&r,&r")
1103         (minus:DI (sign_extend:DI
1104                    (match_operand:SI 2 "s_register_operand"   "r,r"))
1105                   (match_operand:DI  1 "s_register_operand"  "0,r")))
1106    (clobber (reg:CC CC_REGNUM))]
1107   "TARGET_ARM"
1108   "#"   ; "rsbs\\t%Q0, %Q1, %2\;rsc\\t%R0, %R1, %2, asr #31"
1109         ; is equivalent to:
1110         ; "subs\\t%Q0, %2, %Q1\;rsc\\t%R0, %R1, %2, asr #31"
1111   "&& reload_completed"
1112   [(parallel [(set (reg:CC CC_REGNUM)
1113                    (compare:CC (match_dup 2) (match_dup 1)))
1114               (set (match_dup 0) (minus:SI (match_dup 2) (match_dup 1)))])
1115    (set (match_dup 3) (minus:SI (minus:SI
1116                                 (ashiftrt:SI (match_dup 2)
1117                                              (const_int 31))
1118                                 (match_dup 4))
1119                                (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1120   {
1121     operands[3] = gen_highpart (SImode, operands[0]);
1122     operands[0] = gen_lowpart (SImode, operands[0]);
1123     operands[4] = gen_highpart (SImode, operands[1]);
1124     operands[1] = gen_lowpart (SImode, operands[1]);
1125   }
1126   [(set_attr "conds" "clob")
1127    (set_attr "length" "8")
1128    (set_attr "type" "multiple")]
1131 (define_insn_and_split "*subdi_zesidi_zesidi"
1132   [(set (match_operand:DI            0 "s_register_operand" "=r")
1133         (minus:DI (zero_extend:DI
1134                    (match_operand:SI 1 "s_register_operand"  "r"))
1135                   (zero_extend:DI
1136                    (match_operand:SI 2 "s_register_operand"  "r"))))
1137    (clobber (reg:CC CC_REGNUM))]
1138   "TARGET_32BIT"
1139   "#"   ; "subs\\t%Q0, %1, %2\;sbc\\t%R0, %1, %1"
1140   "&& reload_completed"
1141   [(parallel [(set (reg:CC CC_REGNUM)
1142                    (compare:CC (match_dup 1) (match_dup 2)))
1143               (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1144    (set (match_dup 3) (minus:SI (minus:SI (match_dup 1) (match_dup 1))
1145                                (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1146   {
1147        operands[3] = gen_highpart (SImode, operands[0]);
1148        operands[0] = gen_lowpart (SImode, operands[0]);
1149   }
1150   [(set_attr "conds" "clob")
1151    (set_attr "length" "8")
1152    (set_attr "type" "multiple")]
1155 (define_expand "subsi3"
1156   [(set (match_operand:SI           0 "s_register_operand" "")
1157         (minus:SI (match_operand:SI 1 "reg_or_int_operand" "")
1158                   (match_operand:SI 2 "s_register_operand" "")))]
1159   "TARGET_EITHER"
1160   "
1161   if (CONST_INT_P (operands[1]))
1162     {
1163       if (TARGET_32BIT)
1164         {
1165           arm_split_constant (MINUS, SImode, NULL_RTX,
1166                               INTVAL (operands[1]), operands[0],
1167                               operands[2], optimize && can_create_pseudo_p ());
1168           DONE;
1169         }
1170       else /* TARGET_THUMB1 */
1171         operands[1] = force_reg (SImode, operands[1]);
1172     }
1173   "
1176 ; ??? Check Thumb-2 split length
1177 (define_insn_and_split "*arm_subsi3_insn"
1178   [(set (match_operand:SI           0 "s_register_operand" "=l,l ,l ,l ,r ,r,r,rk,r")
1179         (minus:SI (match_operand:SI 1 "reg_or_int_operand" "l ,0 ,l ,Pz,rI,r,r,k ,?n")
1180                   (match_operand:SI 2 "reg_or_int_operand" "l ,Py,Pd,l ,r ,I,r,r ,r")))]
1181   "TARGET_32BIT"
1182   "@
1183    sub%?\\t%0, %1, %2
1184    sub%?\\t%0, %2
1185    sub%?\\t%0, %1, %2
1186    rsb%?\\t%0, %2, %1
1187    rsb%?\\t%0, %2, %1
1188    sub%?\\t%0, %1, %2
1189    sub%?\\t%0, %1, %2
1190    sub%?\\t%0, %1, %2
1191    #"
1192   "&& (CONST_INT_P (operands[1])
1193        && !const_ok_for_arm (INTVAL (operands[1])))"
1194   [(clobber (const_int 0))]
1195   "
1196   arm_split_constant (MINUS, SImode, curr_insn,
1197                       INTVAL (operands[1]), operands[0], operands[2], 0);
1198   DONE;
1199   "
1200   [(set_attr "length" "4,4,4,4,4,4,4,4,16")
1201    (set_attr "arch" "t2,t2,t2,t2,*,*,*,*,*")
1202    (set_attr "predicable" "yes")
1203    (set_attr "predicable_short_it" "yes,yes,yes,yes,no,no,no,no,no")
1204    (set_attr "type" "alu_sreg,alu_sreg,alu_sreg,alu_sreg,alu_imm,alu_imm,alu_sreg,alu_sreg,multiple")]
1207 (define_peephole2
1208   [(match_scratch:SI 3 "r")
1209    (set (match_operand:SI 0 "arm_general_register_operand" "")
1210         (minus:SI (match_operand:SI 1 "const_int_operand" "")
1211                   (match_operand:SI 2 "arm_general_register_operand" "")))]
1212   "TARGET_32BIT
1213    && !const_ok_for_arm (INTVAL (operands[1]))
1214    && const_ok_for_arm (~INTVAL (operands[1]))"
1215   [(set (match_dup 3) (match_dup 1))
1216    (set (match_dup 0) (minus:SI (match_dup 3) (match_dup 2)))]
1217   ""
1220 (define_insn "*subsi3_compare0"
1221   [(set (reg:CC_NOOV CC_REGNUM)
1222         (compare:CC_NOOV
1223          (minus:SI (match_operand:SI 1 "arm_rhs_operand" "r,r,I")
1224                    (match_operand:SI 2 "arm_rhs_operand" "I,r,r"))
1225          (const_int 0)))
1226    (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
1227         (minus:SI (match_dup 1) (match_dup 2)))]
1228   "TARGET_32BIT"
1229   "@
1230    sub%.\\t%0, %1, %2
1231    sub%.\\t%0, %1, %2
1232    rsb%.\\t%0, %2, %1"
1233   [(set_attr "conds" "set")
1234    (set_attr "type"  "alus_imm,alus_sreg,alus_sreg")]
1237 (define_insn "subsi3_compare"
1238   [(set (reg:CC CC_REGNUM)
1239         (compare:CC (match_operand:SI 1 "arm_rhs_operand" "r,r,I")
1240                     (match_operand:SI 2 "arm_rhs_operand" "I,r,r")))
1241    (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
1242         (minus:SI (match_dup 1) (match_dup 2)))]
1243   "TARGET_32BIT"
1244   "@
1245    sub%.\\t%0, %1, %2
1246    sub%.\\t%0, %1, %2
1247    rsb%.\\t%0, %2, %1"
1248   [(set_attr "conds" "set")
1249    (set_attr "type" "alus_imm,alus_sreg,alus_sreg")]
1252 (define_expand "subsf3"
1253   [(set (match_operand:SF           0 "s_register_operand" "")
1254         (minus:SF (match_operand:SF 1 "s_register_operand" "")
1255                   (match_operand:SF 2 "s_register_operand" "")))]
1256   "TARGET_32BIT && TARGET_HARD_FLOAT"
1257   "
1260 (define_expand "subdf3"
1261   [(set (match_operand:DF           0 "s_register_operand" "")
1262         (minus:DF (match_operand:DF 1 "s_register_operand" "")
1263                   (match_operand:DF 2 "s_register_operand" "")))]
1264   "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
1265   "
1269 ;; Multiplication insns
1271 (define_expand "mulhi3"
1272   [(set (match_operand:HI 0 "s_register_operand" "")
1273         (mult:HI (match_operand:HI 1 "s_register_operand" "")
1274                  (match_operand:HI 2 "s_register_operand" "")))]
1275   "TARGET_DSP_MULTIPLY"
1276   "
1277   {
1278     rtx result = gen_reg_rtx (SImode);
1279     emit_insn (gen_mulhisi3 (result, operands[1], operands[2]));
1280     emit_move_insn (operands[0], gen_lowpart (HImode, result));
1281     DONE;
1282   }"
1285 (define_expand "mulsi3"
1286   [(set (match_operand:SI          0 "s_register_operand" "")
1287         (mult:SI (match_operand:SI 2 "s_register_operand" "")
1288                  (match_operand:SI 1 "s_register_operand" "")))]
1289   "TARGET_EITHER"
1290   ""
1293 ;; Use `&' and then `0' to prevent the operands 0 and 1 being the same
1294 (define_insn "*arm_mulsi3"
1295   [(set (match_operand:SI          0 "s_register_operand" "=&r,&r")
1296         (mult:SI (match_operand:SI 2 "s_register_operand" "r,r")
1297                  (match_operand:SI 1 "s_register_operand" "%0,r")))]
1298   "TARGET_32BIT && !arm_arch6"
1299   "mul%?\\t%0, %2, %1"
1300   [(set_attr "type" "mul")
1301    (set_attr "predicable" "yes")]
1304 (define_insn "*arm_mulsi3_v6"
1305   [(set (match_operand:SI          0 "s_register_operand" "=l,l,r")
1306         (mult:SI (match_operand:SI 1 "s_register_operand" "0,l,r")
1307                  (match_operand:SI 2 "s_register_operand" "l,0,r")))]
1308   "TARGET_32BIT && arm_arch6"
1309   "mul%?\\t%0, %1, %2"
1310   [(set_attr "type" "mul")
1311    (set_attr "predicable" "yes")
1312    (set_attr "arch" "t2,t2,*")
1313    (set_attr "length" "4")
1314    (set_attr "predicable_short_it" "yes,yes,no")]
1317 (define_insn "*mulsi3_compare0"
1318   [(set (reg:CC_NOOV CC_REGNUM)
1319         (compare:CC_NOOV (mult:SI
1320                           (match_operand:SI 2 "s_register_operand" "r,r")
1321                           (match_operand:SI 1 "s_register_operand" "%0,r"))
1322                          (const_int 0)))
1323    (set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1324         (mult:SI (match_dup 2) (match_dup 1)))]
1325   "TARGET_ARM && !arm_arch6"
1326   "mul%.\\t%0, %2, %1"
1327   [(set_attr "conds" "set")
1328    (set_attr "type" "muls")]
1331 (define_insn "*mulsi3_compare0_v6"
1332   [(set (reg:CC_NOOV CC_REGNUM)
1333         (compare:CC_NOOV (mult:SI
1334                           (match_operand:SI 2 "s_register_operand" "r")
1335                           (match_operand:SI 1 "s_register_operand" "r"))
1336                          (const_int 0)))
1337    (set (match_operand:SI 0 "s_register_operand" "=r")
1338         (mult:SI (match_dup 2) (match_dup 1)))]
1339   "TARGET_ARM && arm_arch6 && optimize_size"
1340   "mul%.\\t%0, %2, %1"
1341   [(set_attr "conds" "set")
1342    (set_attr "type" "muls")]
1345 (define_insn "*mulsi_compare0_scratch"
1346   [(set (reg:CC_NOOV CC_REGNUM)
1347         (compare:CC_NOOV (mult:SI
1348                           (match_operand:SI 2 "s_register_operand" "r,r")
1349                           (match_operand:SI 1 "s_register_operand" "%0,r"))
1350                          (const_int 0)))
1351    (clobber (match_scratch:SI 0 "=&r,&r"))]
1352   "TARGET_ARM && !arm_arch6"
1353   "mul%.\\t%0, %2, %1"
1354   [(set_attr "conds" "set")
1355    (set_attr "type" "muls")]
1358 (define_insn "*mulsi_compare0_scratch_v6"
1359   [(set (reg:CC_NOOV CC_REGNUM)
1360         (compare:CC_NOOV (mult:SI
1361                           (match_operand:SI 2 "s_register_operand" "r")
1362                           (match_operand:SI 1 "s_register_operand" "r"))
1363                          (const_int 0)))
1364    (clobber (match_scratch:SI 0 "=r"))]
1365   "TARGET_ARM && arm_arch6 && optimize_size"
1366   "mul%.\\t%0, %2, %1"
1367   [(set_attr "conds" "set")
1368    (set_attr "type" "muls")]
1371 ;; Unnamed templates to match MLA instruction.
1373 (define_insn "*mulsi3addsi"
1374   [(set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r,&r")
1375         (plus:SI
1376           (mult:SI (match_operand:SI 2 "s_register_operand" "r,r,r,r")
1377                    (match_operand:SI 1 "s_register_operand" "%0,r,0,r"))
1378           (match_operand:SI 3 "s_register_operand" "r,r,0,0")))]
1379   "TARGET_32BIT && !arm_arch6"
1380   "mla%?\\t%0, %2, %1, %3"
1381   [(set_attr "type" "mla")
1382    (set_attr "predicable" "yes")]
1385 (define_insn "*mulsi3addsi_v6"
1386   [(set (match_operand:SI 0 "s_register_operand" "=r")
1387         (plus:SI
1388           (mult:SI (match_operand:SI 2 "s_register_operand" "r")
1389                    (match_operand:SI 1 "s_register_operand" "r"))
1390           (match_operand:SI 3 "s_register_operand" "r")))]
1391   "TARGET_32BIT && arm_arch6"
1392   "mla%?\\t%0, %2, %1, %3"
1393   [(set_attr "type" "mla")
1394    (set_attr "predicable" "yes")
1395    (set_attr "predicable_short_it" "no")]
1398 (define_insn "*mulsi3addsi_compare0"
1399   [(set (reg:CC_NOOV CC_REGNUM)
1400         (compare:CC_NOOV
1401          (plus:SI (mult:SI
1402                    (match_operand:SI 2 "s_register_operand" "r,r,r,r")
1403                    (match_operand:SI 1 "s_register_operand" "%0,r,0,r"))
1404                   (match_operand:SI 3 "s_register_operand" "r,r,0,0"))
1405          (const_int 0)))
1406    (set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r,&r")
1407         (plus:SI (mult:SI (match_dup 2) (match_dup 1))
1408                  (match_dup 3)))]
1409   "TARGET_ARM && arm_arch6"
1410   "mla%.\\t%0, %2, %1, %3"
1411   [(set_attr "conds" "set")
1412    (set_attr "type" "mlas")]
1415 (define_insn "*mulsi3addsi_compare0_v6"
1416   [(set (reg:CC_NOOV CC_REGNUM)
1417         (compare:CC_NOOV
1418          (plus:SI (mult:SI
1419                    (match_operand:SI 2 "s_register_operand" "r")
1420                    (match_operand:SI 1 "s_register_operand" "r"))
1421                   (match_operand:SI 3 "s_register_operand" "r"))
1422          (const_int 0)))
1423    (set (match_operand:SI 0 "s_register_operand" "=r")
1424         (plus:SI (mult:SI (match_dup 2) (match_dup 1))
1425                  (match_dup 3)))]
1426   "TARGET_ARM && arm_arch6 && optimize_size"
1427   "mla%.\\t%0, %2, %1, %3"
1428   [(set_attr "conds" "set")
1429    (set_attr "type" "mlas")]
1432 (define_insn "*mulsi3addsi_compare0_scratch"
1433   [(set (reg:CC_NOOV CC_REGNUM)
1434         (compare:CC_NOOV
1435          (plus:SI (mult:SI
1436                    (match_operand:SI 2 "s_register_operand" "r,r,r,r")
1437                    (match_operand:SI 1 "s_register_operand" "%0,r,0,r"))
1438                   (match_operand:SI 3 "s_register_operand" "?r,r,0,0"))
1439          (const_int 0)))
1440    (clobber (match_scratch:SI 0 "=&r,&r,&r,&r"))]
1441   "TARGET_ARM && !arm_arch6"
1442   "mla%.\\t%0, %2, %1, %3"
1443   [(set_attr "conds" "set")
1444    (set_attr "type" "mlas")]
1447 (define_insn "*mulsi3addsi_compare0_scratch_v6"
1448   [(set (reg:CC_NOOV CC_REGNUM)
1449         (compare:CC_NOOV
1450          (plus:SI (mult:SI
1451                    (match_operand:SI 2 "s_register_operand" "r")
1452                    (match_operand:SI 1 "s_register_operand" "r"))
1453                   (match_operand:SI 3 "s_register_operand" "r"))
1454          (const_int 0)))
1455    (clobber (match_scratch:SI 0 "=r"))]
1456   "TARGET_ARM && arm_arch6 && optimize_size"
1457   "mla%.\\t%0, %2, %1, %3"
1458   [(set_attr "conds" "set")
1459    (set_attr "type" "mlas")]
1462 (define_insn "*mulsi3subsi"
1463   [(set (match_operand:SI 0 "s_register_operand" "=r")
1464         (minus:SI
1465           (match_operand:SI 3 "s_register_operand" "r")
1466           (mult:SI (match_operand:SI 2 "s_register_operand" "r")
1467                    (match_operand:SI 1 "s_register_operand" "r"))))]
1468   "TARGET_32BIT && arm_arch_thumb2"
1469   "mls%?\\t%0, %2, %1, %3"
1470   [(set_attr "type" "mla")
1471    (set_attr "predicable" "yes")
1472    (set_attr "predicable_short_it" "no")]
1475 (define_expand "maddsidi4"
1476   [(set (match_operand:DI 0 "s_register_operand" "")
1477         (plus:DI
1478          (mult:DI
1479           (sign_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1480           (sign_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1481          (match_operand:DI 3 "s_register_operand" "")))]
1482   "TARGET_32BIT && arm_arch3m"
1483   "")
1485 (define_insn "*mulsidi3adddi"
1486   [(set (match_operand:DI 0 "s_register_operand" "=&r")
1487         (plus:DI
1488          (mult:DI
1489           (sign_extend:DI (match_operand:SI 2 "s_register_operand" "%r"))
1490           (sign_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1491          (match_operand:DI 1 "s_register_operand" "0")))]
1492   "TARGET_32BIT && arm_arch3m && !arm_arch6"
1493   "smlal%?\\t%Q0, %R0, %3, %2"
1494   [(set_attr "type" "smlal")
1495    (set_attr "predicable" "yes")]
1498 (define_insn "*mulsidi3adddi_v6"
1499   [(set (match_operand:DI 0 "s_register_operand" "=r")
1500         (plus:DI
1501          (mult:DI
1502           (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r"))
1503           (sign_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1504          (match_operand:DI 1 "s_register_operand" "0")))]
1505   "TARGET_32BIT && arm_arch6"
1506   "smlal%?\\t%Q0, %R0, %3, %2"
1507   [(set_attr "type" "smlal")
1508    (set_attr "predicable" "yes")
1509    (set_attr "predicable_short_it" "no")]
1512 ;; 32x32->64 widening multiply.
1513 ;; As with mulsi3, the only difference between the v3-5 and v6+
1514 ;; versions of these patterns is the requirement that the output not
1515 ;; overlap the inputs, but that still means we have to have a named
1516 ;; expander and two different starred insns.
1518 (define_expand "mulsidi3"
1519   [(set (match_operand:DI 0 "s_register_operand" "")
1520         (mult:DI
1521          (sign_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1522          (sign_extend:DI (match_operand:SI 2 "s_register_operand" ""))))]
1523   "TARGET_32BIT && arm_arch3m"
1524   ""
1527 (define_insn "*mulsidi3_nov6"
1528   [(set (match_operand:DI 0 "s_register_operand" "=&r")
1529         (mult:DI
1530          (sign_extend:DI (match_operand:SI 1 "s_register_operand" "%r"))
1531          (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1532   "TARGET_32BIT && arm_arch3m && !arm_arch6"
1533   "smull%?\\t%Q0, %R0, %1, %2"
1534   [(set_attr "type" "smull")
1535    (set_attr "predicable" "yes")]
1538 (define_insn "*mulsidi3_v6"
1539   [(set (match_operand:DI 0 "s_register_operand" "=r")
1540         (mult:DI
1541          (sign_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1542          (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1543   "TARGET_32BIT && arm_arch6"
1544   "smull%?\\t%Q0, %R0, %1, %2"
1545   [(set_attr "type" "smull")
1546    (set_attr "predicable" "yes")
1547    (set_attr "predicable_short_it" "no")]
1550 (define_expand "umulsidi3"
1551   [(set (match_operand:DI 0 "s_register_operand" "")
1552         (mult:DI
1553          (zero_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1554          (zero_extend:DI (match_operand:SI 2 "s_register_operand" ""))))]
1555   "TARGET_32BIT && arm_arch3m"
1556   ""
1559 (define_insn "*umulsidi3_nov6"
1560   [(set (match_operand:DI 0 "s_register_operand" "=&r")
1561         (mult:DI
1562          (zero_extend:DI (match_operand:SI 1 "s_register_operand" "%r"))
1563          (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1564   "TARGET_32BIT && arm_arch3m && !arm_arch6"
1565   "umull%?\\t%Q0, %R0, %1, %2"
1566   [(set_attr "type" "umull")
1567    (set_attr "predicable" "yes")]
1570 (define_insn "*umulsidi3_v6"
1571   [(set (match_operand:DI 0 "s_register_operand" "=r")
1572         (mult:DI
1573          (zero_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1574          (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1575   "TARGET_32BIT && arm_arch6"
1576   "umull%?\\t%Q0, %R0, %1, %2"
1577   [(set_attr "type" "umull")
1578    (set_attr "predicable" "yes")
1579    (set_attr "predicable_short_it" "no")]
1582 (define_expand "umaddsidi4"
1583   [(set (match_operand:DI 0 "s_register_operand" "")
1584         (plus:DI
1585          (mult:DI
1586           (zero_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1587           (zero_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1588          (match_operand:DI 3 "s_register_operand" "")))]
1589   "TARGET_32BIT && arm_arch3m"
1590   "")
1592 (define_insn "*umulsidi3adddi"
1593   [(set (match_operand:DI 0 "s_register_operand" "=&r")
1594         (plus:DI
1595          (mult:DI
1596           (zero_extend:DI (match_operand:SI 2 "s_register_operand" "%r"))
1597           (zero_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1598          (match_operand:DI 1 "s_register_operand" "0")))]
1599   "TARGET_32BIT && arm_arch3m && !arm_arch6"
1600   "umlal%?\\t%Q0, %R0, %3, %2"
1601   [(set_attr "type" "umlal")
1602    (set_attr "predicable" "yes")]
1605 (define_insn "*umulsidi3adddi_v6"
1606   [(set (match_operand:DI 0 "s_register_operand" "=r")
1607         (plus:DI
1608          (mult:DI
1609           (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r"))
1610           (zero_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1611          (match_operand:DI 1 "s_register_operand" "0")))]
1612   "TARGET_32BIT && arm_arch6"
1613   "umlal%?\\t%Q0, %R0, %3, %2"
1614   [(set_attr "type" "umlal")
1615    (set_attr "predicable" "yes")
1616    (set_attr "predicable_short_it" "no")]
1619 (define_expand "smulsi3_highpart"
1620   [(parallel
1621     [(set (match_operand:SI 0 "s_register_operand" "")
1622           (truncate:SI
1623            (lshiftrt:DI
1624             (mult:DI
1625              (sign_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1626              (sign_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1627             (const_int 32))))
1628      (clobber (match_scratch:SI 3 ""))])]
1629   "TARGET_32BIT && arm_arch3m"
1630   ""
1633 (define_insn "*smulsi3_highpart_nov6"
1634   [(set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1635         (truncate:SI
1636          (lshiftrt:DI
1637           (mult:DI
1638            (sign_extend:DI (match_operand:SI 1 "s_register_operand" "%0,r"))
1639            (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r,r")))
1640           (const_int 32))))
1641    (clobber (match_scratch:SI 3 "=&r,&r"))]
1642   "TARGET_32BIT && arm_arch3m && !arm_arch6"
1643   "smull%?\\t%3, %0, %2, %1"
1644   [(set_attr "type" "smull")
1645    (set_attr "predicable" "yes")]
1648 (define_insn "*smulsi3_highpart_v6"
1649   [(set (match_operand:SI 0 "s_register_operand" "=r")
1650         (truncate:SI
1651          (lshiftrt:DI
1652           (mult:DI
1653            (sign_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1654            (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r")))
1655           (const_int 32))))
1656    (clobber (match_scratch:SI 3 "=r"))]
1657   "TARGET_32BIT && arm_arch6"
1658   "smull%?\\t%3, %0, %2, %1"
1659   [(set_attr "type" "smull")
1660    (set_attr "predicable" "yes")
1661    (set_attr "predicable_short_it" "no")]
1664 (define_expand "umulsi3_highpart"
1665   [(parallel
1666     [(set (match_operand:SI 0 "s_register_operand" "")
1667           (truncate:SI
1668            (lshiftrt:DI
1669             (mult:DI
1670              (zero_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1671               (zero_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1672             (const_int 32))))
1673      (clobber (match_scratch:SI 3 ""))])]
1674   "TARGET_32BIT && arm_arch3m"
1675   ""
1678 (define_insn "*umulsi3_highpart_nov6"
1679   [(set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1680         (truncate:SI
1681          (lshiftrt:DI
1682           (mult:DI
1683            (zero_extend:DI (match_operand:SI 1 "s_register_operand" "%0,r"))
1684            (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r,r")))
1685           (const_int 32))))
1686    (clobber (match_scratch:SI 3 "=&r,&r"))]
1687   "TARGET_32BIT && arm_arch3m && !arm_arch6"
1688   "umull%?\\t%3, %0, %2, %1"
1689   [(set_attr "type" "umull")
1690    (set_attr "predicable" "yes")]
1693 (define_insn "*umulsi3_highpart_v6"
1694   [(set (match_operand:SI 0 "s_register_operand" "=r")
1695         (truncate:SI
1696          (lshiftrt:DI
1697           (mult:DI
1698            (zero_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1699            (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r")))
1700           (const_int 32))))
1701    (clobber (match_scratch:SI 3 "=r"))]
1702   "TARGET_32BIT && arm_arch6"
1703   "umull%?\\t%3, %0, %2, %1"
1704   [(set_attr "type" "umull")
1705    (set_attr "predicable" "yes")
1706    (set_attr "predicable_short_it" "no")]
1709 (define_insn "mulhisi3"
1710   [(set (match_operand:SI 0 "s_register_operand" "=r")
1711         (mult:SI (sign_extend:SI
1712                   (match_operand:HI 1 "s_register_operand" "%r"))
1713                  (sign_extend:SI
1714                   (match_operand:HI 2 "s_register_operand" "r"))))]
1715   "TARGET_DSP_MULTIPLY"
1716   "smulbb%?\\t%0, %1, %2"
1717   [(set_attr "type" "smulxy")
1718    (set_attr "predicable" "yes")]
1721 (define_insn "*mulhisi3tb"
1722   [(set (match_operand:SI 0 "s_register_operand" "=r")
1723         (mult:SI (ashiftrt:SI
1724                   (match_operand:SI 1 "s_register_operand" "r")
1725                   (const_int 16))
1726                  (sign_extend:SI
1727                   (match_operand:HI 2 "s_register_operand" "r"))))]
1728   "TARGET_DSP_MULTIPLY"
1729   "smultb%?\\t%0, %1, %2"
1730   [(set_attr "type" "smulxy")
1731    (set_attr "predicable" "yes")
1732    (set_attr "predicable_short_it" "no")]
1735 (define_insn "*mulhisi3bt"
1736   [(set (match_operand:SI 0 "s_register_operand" "=r")
1737         (mult:SI (sign_extend:SI
1738                   (match_operand:HI 1 "s_register_operand" "r"))
1739                  (ashiftrt:SI
1740                   (match_operand:SI 2 "s_register_operand" "r")
1741                   (const_int 16))))]
1742   "TARGET_DSP_MULTIPLY"
1743   "smulbt%?\\t%0, %1, %2"
1744   [(set_attr "type" "smulxy")
1745    (set_attr "predicable" "yes")
1746    (set_attr "predicable_short_it" "no")]
1749 (define_insn "*mulhisi3tt"
1750   [(set (match_operand:SI 0 "s_register_operand" "=r")
1751         (mult:SI (ashiftrt:SI
1752                   (match_operand:SI 1 "s_register_operand" "r")
1753                   (const_int 16))
1754                  (ashiftrt:SI
1755                   (match_operand:SI 2 "s_register_operand" "r")
1756                   (const_int 16))))]
1757   "TARGET_DSP_MULTIPLY"
1758   "smultt%?\\t%0, %1, %2"
1759   [(set_attr "type" "smulxy")
1760    (set_attr "predicable" "yes")
1761    (set_attr "predicable_short_it" "no")]
1764 (define_insn "maddhisi4"
1765   [(set (match_operand:SI 0 "s_register_operand" "=r")
1766         (plus:SI (mult:SI (sign_extend:SI
1767                            (match_operand:HI 1 "s_register_operand" "r"))
1768                           (sign_extend:SI
1769                            (match_operand:HI 2 "s_register_operand" "r")))
1770                  (match_operand:SI 3 "s_register_operand" "r")))]
1771   "TARGET_DSP_MULTIPLY"
1772   "smlabb%?\\t%0, %1, %2, %3"
1773   [(set_attr "type" "smlaxy")
1774    (set_attr "predicable" "yes")
1775    (set_attr "predicable_short_it" "no")]
1778 ;; Note: there is no maddhisi4ibt because this one is canonical form
1779 (define_insn "*maddhisi4tb"
1780   [(set (match_operand:SI 0 "s_register_operand" "=r")
1781         (plus:SI (mult:SI (ashiftrt:SI
1782                            (match_operand:SI 1 "s_register_operand" "r")
1783                            (const_int 16))
1784                           (sign_extend:SI
1785                            (match_operand:HI 2 "s_register_operand" "r")))
1786                  (match_operand:SI 3 "s_register_operand" "r")))]
1787   "TARGET_DSP_MULTIPLY"
1788   "smlatb%?\\t%0, %1, %2, %3"
1789   [(set_attr "type" "smlaxy")
1790    (set_attr "predicable" "yes")
1791    (set_attr "predicable_short_it" "no")]
1794 (define_insn "*maddhisi4tt"
1795   [(set (match_operand:SI 0 "s_register_operand" "=r")
1796         (plus:SI (mult:SI (ashiftrt:SI
1797                            (match_operand:SI 1 "s_register_operand" "r")
1798                            (const_int 16))
1799                           (ashiftrt:SI
1800                            (match_operand:SI 2 "s_register_operand" "r")
1801                            (const_int 16)))
1802                  (match_operand:SI 3 "s_register_operand" "r")))]
1803   "TARGET_DSP_MULTIPLY"
1804   "smlatt%?\\t%0, %1, %2, %3"
1805   [(set_attr "type" "smlaxy")
1806    (set_attr "predicable" "yes")
1807    (set_attr "predicable_short_it" "no")]
1810 (define_insn "maddhidi4"
1811   [(set (match_operand:DI 0 "s_register_operand" "=r")
1812         (plus:DI
1813           (mult:DI (sign_extend:DI
1814                     (match_operand:HI 1 "s_register_operand" "r"))
1815                    (sign_extend:DI
1816                     (match_operand:HI 2 "s_register_operand" "r")))
1817           (match_operand:DI 3 "s_register_operand" "0")))]
1818   "TARGET_DSP_MULTIPLY"
1819   "smlalbb%?\\t%Q0, %R0, %1, %2"
1820   [(set_attr "type" "smlalxy")
1821    (set_attr "predicable" "yes")
1822    (set_attr "predicable_short_it" "no")])
1824 ;; Note: there is no maddhidi4ibt because this one is canonical form
1825 (define_insn "*maddhidi4tb"
1826   [(set (match_operand:DI 0 "s_register_operand" "=r")
1827         (plus:DI
1828           (mult:DI (sign_extend:DI
1829                     (ashiftrt:SI
1830                      (match_operand:SI 1 "s_register_operand" "r")
1831                      (const_int 16)))
1832                    (sign_extend:DI
1833                     (match_operand:HI 2 "s_register_operand" "r")))
1834           (match_operand:DI 3 "s_register_operand" "0")))]
1835   "TARGET_DSP_MULTIPLY"
1836   "smlaltb%?\\t%Q0, %R0, %1, %2"
1837   [(set_attr "type" "smlalxy")
1838    (set_attr "predicable" "yes")
1839    (set_attr "predicable_short_it" "no")])
1841 (define_insn "*maddhidi4tt"
1842   [(set (match_operand:DI 0 "s_register_operand" "=r")
1843         (plus:DI
1844           (mult:DI (sign_extend:DI
1845                     (ashiftrt:SI
1846                      (match_operand:SI 1 "s_register_operand" "r")
1847                      (const_int 16)))
1848                    (sign_extend:DI
1849                     (ashiftrt:SI
1850                      (match_operand:SI 2 "s_register_operand" "r")
1851                      (const_int 16))))
1852           (match_operand:DI 3 "s_register_operand" "0")))]
1853   "TARGET_DSP_MULTIPLY"
1854   "smlaltt%?\\t%Q0, %R0, %1, %2"
1855   [(set_attr "type" "smlalxy")
1856    (set_attr "predicable" "yes")
1857    (set_attr "predicable_short_it" "no")])
1859 (define_expand "mulsf3"
1860   [(set (match_operand:SF          0 "s_register_operand" "")
1861         (mult:SF (match_operand:SF 1 "s_register_operand" "")
1862                  (match_operand:SF 2 "s_register_operand" "")))]
1863   "TARGET_32BIT && TARGET_HARD_FLOAT"
1864   "
1867 (define_expand "muldf3"
1868   [(set (match_operand:DF          0 "s_register_operand" "")
1869         (mult:DF (match_operand:DF 1 "s_register_operand" "")
1870                  (match_operand:DF 2 "s_register_operand" "")))]
1871   "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
1872   "
1875 ;; Division insns
1877 (define_expand "divsf3"
1878   [(set (match_operand:SF 0 "s_register_operand" "")
1879         (div:SF (match_operand:SF 1 "s_register_operand" "")
1880                 (match_operand:SF 2 "s_register_operand" "")))]
1881   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
1882   "")
1884 (define_expand "divdf3"
1885   [(set (match_operand:DF 0 "s_register_operand" "")
1886         (div:DF (match_operand:DF 1 "s_register_operand" "")
1887                 (match_operand:DF 2 "s_register_operand" "")))]
1888   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
1889   "")
1891 ;; Boolean and,ior,xor insns
1893 ;; Split up double word logical operations
1895 ;; Split up simple DImode logical operations.  Simply perform the logical
1896 ;; operation on the upper and lower halves of the registers.
1897 (define_split
1898   [(set (match_operand:DI 0 "s_register_operand" "")
1899         (match_operator:DI 6 "logical_binary_operator"
1900           [(match_operand:DI 1 "s_register_operand" "")
1901            (match_operand:DI 2 "s_register_operand" "")]))]
1902   "TARGET_32BIT && reload_completed
1903    && ! (TARGET_NEON && IS_VFP_REGNUM (REGNO (operands[0])))
1904    && ! IS_IWMMXT_REGNUM (REGNO (operands[0]))"
1905   [(set (match_dup 0) (match_op_dup:SI 6 [(match_dup 1) (match_dup 2)]))
1906    (set (match_dup 3) (match_op_dup:SI 6 [(match_dup 4) (match_dup 5)]))]
1907   "
1908   {
1909     operands[3] = gen_highpart (SImode, operands[0]);
1910     operands[0] = gen_lowpart (SImode, operands[0]);
1911     operands[4] = gen_highpart (SImode, operands[1]);
1912     operands[1] = gen_lowpart (SImode, operands[1]);
1913     operands[5] = gen_highpart (SImode, operands[2]);
1914     operands[2] = gen_lowpart (SImode, operands[2]);
1915   }"
1918 (define_split
1919   [(set (match_operand:DI 0 "s_register_operand" "")
1920         (match_operator:DI 6 "logical_binary_operator"
1921           [(sign_extend:DI (match_operand:SI 2 "s_register_operand" ""))
1922            (match_operand:DI 1 "s_register_operand" "")]))]
1923   "TARGET_32BIT && reload_completed"
1924   [(set (match_dup 0) (match_op_dup:SI 6 [(match_dup 1) (match_dup 2)]))
1925    (set (match_dup 3) (match_op_dup:SI 6
1926                         [(ashiftrt:SI (match_dup 2) (const_int 31))
1927                          (match_dup 4)]))]
1928   "
1929   {
1930     operands[3] = gen_highpart (SImode, operands[0]);
1931     operands[0] = gen_lowpart (SImode, operands[0]);
1932     operands[4] = gen_highpart (SImode, operands[1]);
1933     operands[1] = gen_lowpart (SImode, operands[1]);
1934     operands[5] = gen_highpart (SImode, operands[2]);
1935     operands[2] = gen_lowpart (SImode, operands[2]);
1936   }"
1939 ;; The zero extend of operand 2 means we can just copy the high part of
1940 ;; operand1 into operand0.
1941 (define_split
1942   [(set (match_operand:DI 0 "s_register_operand" "")
1943         (ior:DI
1944           (zero_extend:DI (match_operand:SI 2 "s_register_operand" ""))
1945           (match_operand:DI 1 "s_register_operand" "")))]
1946   "TARGET_32BIT && operands[0] != operands[1] && reload_completed"
1947   [(set (match_dup 0) (ior:SI (match_dup 1) (match_dup 2)))
1948    (set (match_dup 3) (match_dup 4))]
1949   "
1950   {
1951     operands[4] = gen_highpart (SImode, operands[1]);
1952     operands[3] = gen_highpart (SImode, operands[0]);
1953     operands[0] = gen_lowpart (SImode, operands[0]);
1954     operands[1] = gen_lowpart (SImode, operands[1]);
1955   }"
1958 ;; The zero extend of operand 2 means we can just copy the high part of
1959 ;; operand1 into operand0.
1960 (define_split
1961   [(set (match_operand:DI 0 "s_register_operand" "")
1962         (xor:DI
1963           (zero_extend:DI (match_operand:SI 2 "s_register_operand" ""))
1964           (match_operand:DI 1 "s_register_operand" "")))]
1965   "TARGET_32BIT && operands[0] != operands[1] && reload_completed"
1966   [(set (match_dup 0) (xor:SI (match_dup 1) (match_dup 2)))
1967    (set (match_dup 3) (match_dup 4))]
1968   "
1969   {
1970     operands[4] = gen_highpart (SImode, operands[1]);
1971     operands[3] = gen_highpart (SImode, operands[0]);
1972     operands[0] = gen_lowpart (SImode, operands[0]);
1973     operands[1] = gen_lowpart (SImode, operands[1]);
1974   }"
1977 (define_expand "anddi3"
1978   [(set (match_operand:DI         0 "s_register_operand" "")
1979         (and:DI (match_operand:DI 1 "s_register_operand" "")
1980                 (match_operand:DI 2 "neon_inv_logic_op2" "")))]
1981   "TARGET_32BIT"
1982   ""
1985 (define_insn_and_split "*anddi3_insn"
1986   [(set (match_operand:DI         0 "s_register_operand"     "=w,w ,&r,&r,&r,&r,?w,?w")
1987         (and:DI (match_operand:DI 1 "s_register_operand"     "%w,0 ,0 ,r ,0 ,r ,w ,0")
1988                 (match_operand:DI 2 "arm_anddi_operand_neon" "w ,DL,r ,r ,De,De,w ,DL")))]
1989   "TARGET_32BIT && !TARGET_IWMMXT"
1991   switch (which_alternative)
1992     {
1993     case 0: /* fall through */
1994     case 6: return "vand\t%P0, %P1, %P2";
1995     case 1: /* fall through */
1996     case 7: return neon_output_logic_immediate ("vand", &operands[2],
1997                     DImode, 1, VALID_NEON_QREG_MODE (DImode));
1998     case 2:
1999     case 3:
2000     case 4:
2001     case 5: /* fall through */
2002       return "#";
2003     default: gcc_unreachable ();
2004     }
2006   "TARGET_32BIT && !TARGET_IWMMXT && reload_completed
2007    && !(IS_VFP_REGNUM (REGNO (operands[0])))"
2008   [(set (match_dup 3) (match_dup 4))
2009    (set (match_dup 5) (match_dup 6))]
2010   "
2011   {
2012     operands[3] = gen_lowpart (SImode, operands[0]);
2013     operands[5] = gen_highpart (SImode, operands[0]);
2015     operands[4] = simplify_gen_binary (AND, SImode,
2016                                            gen_lowpart (SImode, operands[1]),
2017                                            gen_lowpart (SImode, operands[2]));
2018     operands[6] = simplify_gen_binary (AND, SImode,
2019                                            gen_highpart (SImode, operands[1]),
2020                                            gen_highpart_mode (SImode, DImode, operands[2]));
2022   }"
2023   [(set_attr "type" "neon_logic,neon_logic,multiple,multiple,\
2024                      multiple,multiple,neon_logic,neon_logic")
2025    (set_attr "arch" "neon_for_64bits,neon_for_64bits,*,*,*,*,
2026                      avoid_neon_for_64bits,avoid_neon_for_64bits")
2027    (set_attr "length" "*,*,8,8,8,8,*,*")
2028   ]
2031 (define_insn_and_split "*anddi_zesidi_di"
2032   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2033         (and:DI (zero_extend:DI
2034                  (match_operand:SI 2 "s_register_operand" "r,r"))
2035                 (match_operand:DI 1 "s_register_operand" "0,r")))]
2036   "TARGET_32BIT"
2037   "#"
2038   "TARGET_32BIT && reload_completed"
2039   ; The zero extend of operand 2 clears the high word of the output
2040   ; operand.
2041   [(set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))
2042    (set (match_dup 3) (const_int 0))]
2043   "
2044   {
2045     operands[3] = gen_highpart (SImode, operands[0]);
2046     operands[0] = gen_lowpart (SImode, operands[0]);
2047     operands[1] = gen_lowpart (SImode, operands[1]);
2048   }"
2049   [(set_attr "length" "8")
2050    (set_attr "type" "multiple")]
2053 (define_insn "*anddi_sesdi_di"
2054   [(set (match_operand:DI          0 "s_register_operand" "=&r,&r")
2055         (and:DI (sign_extend:DI
2056                  (match_operand:SI 2 "s_register_operand" "r,r"))
2057                 (match_operand:DI  1 "s_register_operand" "0,r")))]
2058   "TARGET_32BIT"
2059   "#"
2060   [(set_attr "length" "8")
2061    (set_attr "type" "multiple")]
2064 (define_expand "andsi3"
2065   [(set (match_operand:SI         0 "s_register_operand" "")
2066         (and:SI (match_operand:SI 1 "s_register_operand" "")
2067                 (match_operand:SI 2 "reg_or_int_operand" "")))]
2068   "TARGET_EITHER"
2069   "
2070   if (TARGET_32BIT)
2071     {
2072       if (CONST_INT_P (operands[2]))
2073         {
2074           if (INTVAL (operands[2]) == 255 && arm_arch6)
2075             {
2076               operands[1] = convert_to_mode (QImode, operands[1], 1);
2077               emit_insn (gen_thumb2_zero_extendqisi2_v6 (operands[0],
2078                                                          operands[1]));
2079             }
2080           else
2081             arm_split_constant (AND, SImode, NULL_RTX,
2082                                 INTVAL (operands[2]), operands[0],
2083                                 operands[1],
2084                                 optimize && can_create_pseudo_p ());
2086           DONE;
2087         }
2088     }
2089   else /* TARGET_THUMB1 */
2090     {
2091       if (!CONST_INT_P (operands[2]))
2092         {
2093           rtx tmp = force_reg (SImode, operands[2]);
2094           if (rtx_equal_p (operands[0], operands[1]))
2095             operands[2] = tmp;
2096           else
2097             {
2098               operands[2] = operands[1];
2099               operands[1] = tmp;
2100             }
2101         }
2102       else
2103         {
2104           int i;
2105           
2106           if (((unsigned HOST_WIDE_INT) ~INTVAL (operands[2])) < 256)
2107             {
2108               operands[2] = force_reg (SImode,
2109                                        GEN_INT (~INTVAL (operands[2])));
2110               
2111               emit_insn (gen_thumb1_bicsi3 (operands[0], operands[2], operands[1]));
2112               
2113               DONE;
2114             }
2116           for (i = 9; i <= 31; i++)
2117             {
2118               if ((((HOST_WIDE_INT) 1) << i) - 1 == INTVAL (operands[2]))
2119                 {
2120                   emit_insn (gen_extzv (operands[0], operands[1], GEN_INT (i),
2121                                         const0_rtx));
2122                   DONE;
2123                 }
2124               else if ((((HOST_WIDE_INT) 1) << i) - 1
2125                        == ~INTVAL (operands[2]))
2126                 {
2127                   rtx shift = GEN_INT (i);
2128                   rtx reg = gen_reg_rtx (SImode);
2129                 
2130                   emit_insn (gen_lshrsi3 (reg, operands[1], shift));
2131                   emit_insn (gen_ashlsi3 (operands[0], reg, shift));
2132                   
2133                   DONE;
2134                 }
2135             }
2137           operands[2] = force_reg (SImode, operands[2]);
2138         }
2139     }
2140   "
2143 ; ??? Check split length for Thumb-2
2144 (define_insn_and_split "*arm_andsi3_insn"
2145   [(set (match_operand:SI         0 "s_register_operand" "=r,l,r,r,r")
2146         (and:SI (match_operand:SI 1 "s_register_operand" "%r,0,r,r,r")
2147                 (match_operand:SI 2 "reg_or_int_operand" "I,l,K,r,?n")))]
2148   "TARGET_32BIT"
2149   "@
2150    and%?\\t%0, %1, %2
2151    and%?\\t%0, %1, %2
2152    bic%?\\t%0, %1, #%B2
2153    and%?\\t%0, %1, %2
2154    #"
2155   "TARGET_32BIT
2156    && CONST_INT_P (operands[2])
2157    && !(const_ok_for_arm (INTVAL (operands[2]))
2158         || const_ok_for_arm (~INTVAL (operands[2])))"
2159   [(clobber (const_int 0))]
2160   "
2161   arm_split_constant  (AND, SImode, curr_insn, 
2162                        INTVAL (operands[2]), operands[0], operands[1], 0);
2163   DONE;
2164   "
2165   [(set_attr "length" "4,4,4,4,16")
2166    (set_attr "predicable" "yes")
2167    (set_attr "predicable_short_it" "no,yes,no,no,no")
2168    (set_attr "type" "logic_imm,logic_imm,logic_reg,logic_reg,logic_imm")]
2171 (define_insn "*andsi3_compare0"
2172   [(set (reg:CC_NOOV CC_REGNUM)
2173         (compare:CC_NOOV
2174          (and:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
2175                  (match_operand:SI 2 "arm_not_operand" "I,K,r"))
2176          (const_int 0)))
2177    (set (match_operand:SI          0 "s_register_operand" "=r,r,r")
2178         (and:SI (match_dup 1) (match_dup 2)))]
2179   "TARGET_32BIT"
2180   "@
2181    and%.\\t%0, %1, %2
2182    bic%.\\t%0, %1, #%B2
2183    and%.\\t%0, %1, %2"
2184   [(set_attr "conds" "set")
2185    (set_attr "type" "logics_imm,logics_imm,logics_reg")]
2188 (define_insn "*andsi3_compare0_scratch"
2189   [(set (reg:CC_NOOV CC_REGNUM)
2190         (compare:CC_NOOV
2191          (and:SI (match_operand:SI 0 "s_register_operand" "r,r,r")
2192                  (match_operand:SI 1 "arm_not_operand" "I,K,r"))
2193          (const_int 0)))
2194    (clobber (match_scratch:SI 2 "=X,r,X"))]
2195   "TARGET_32BIT"
2196   "@
2197    tst%?\\t%0, %1
2198    bic%.\\t%2, %0, #%B1
2199    tst%?\\t%0, %1"
2200   [(set_attr "conds" "set")
2201    (set_attr "type"  "logics_imm,logics_imm,logics_reg")]
2204 (define_insn "*zeroextractsi_compare0_scratch"
2205   [(set (reg:CC_NOOV CC_REGNUM)
2206         (compare:CC_NOOV (zero_extract:SI
2207                           (match_operand:SI 0 "s_register_operand" "r")
2208                           (match_operand 1 "const_int_operand" "n")
2209                           (match_operand 2 "const_int_operand" "n"))
2210                          (const_int 0)))]
2211   "TARGET_32BIT
2212   && (INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) < 32
2213       && INTVAL (operands[1]) > 0 
2214       && INTVAL (operands[1]) + (INTVAL (operands[2]) & 1) <= 8
2215       && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32)"
2216   "*
2217   operands[1] = GEN_INT (((1 << INTVAL (operands[1])) - 1)
2218                          << INTVAL (operands[2]));
2219   output_asm_insn (\"tst%?\\t%0, %1\", operands);
2220   return \"\";
2221   "
2222   [(set_attr "conds" "set")
2223    (set_attr "predicable" "yes")
2224    (set_attr "predicable_short_it" "no")
2225    (set_attr "type" "logics_imm")]
2228 (define_insn_and_split "*ne_zeroextractsi"
2229   [(set (match_operand:SI 0 "s_register_operand" "=r")
2230         (ne:SI (zero_extract:SI
2231                 (match_operand:SI 1 "s_register_operand" "r")
2232                 (match_operand:SI 2 "const_int_operand" "n")
2233                 (match_operand:SI 3 "const_int_operand" "n"))
2234                (const_int 0)))
2235    (clobber (reg:CC CC_REGNUM))]
2236   "TARGET_32BIT
2237    && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2238        && INTVAL (operands[2]) > 0 
2239        && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2240        && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)"
2241   "#"
2242   "TARGET_32BIT
2243    && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2244        && INTVAL (operands[2]) > 0 
2245        && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2246        && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)"
2247   [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2248                    (compare:CC_NOOV (and:SI (match_dup 1) (match_dup 2))
2249                                     (const_int 0)))
2250               (set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))])
2251    (set (match_dup 0)
2252         (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2253                          (match_dup 0) (const_int 1)))]
2254   "
2255   operands[2] = GEN_INT (((1 << INTVAL (operands[2])) - 1)
2256                          << INTVAL (operands[3])); 
2257   "
2258   [(set_attr "conds" "clob")
2259    (set (attr "length")
2260         (if_then_else (eq_attr "is_thumb" "yes")
2261                       (const_int 12)
2262                       (const_int 8)))
2263    (set_attr "type" "multiple")]
2266 (define_insn_and_split "*ne_zeroextractsi_shifted"
2267   [(set (match_operand:SI 0 "s_register_operand" "=r")
2268         (ne:SI (zero_extract:SI
2269                 (match_operand:SI 1 "s_register_operand" "r")
2270                 (match_operand:SI 2 "const_int_operand" "n")
2271                 (const_int 0))
2272                (const_int 0)))
2273    (clobber (reg:CC CC_REGNUM))]
2274   "TARGET_ARM"
2275   "#"
2276   "TARGET_ARM"
2277   [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2278                    (compare:CC_NOOV (ashift:SI (match_dup 1) (match_dup 2))
2279                                     (const_int 0)))
2280               (set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))])
2281    (set (match_dup 0)
2282         (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2283                          (match_dup 0) (const_int 1)))]
2284   "
2285   operands[2] = GEN_INT (32 - INTVAL (operands[2]));
2286   "
2287   [(set_attr "conds" "clob")
2288    (set_attr "length" "8")
2289    (set_attr "type" "multiple")]
2292 (define_insn_and_split "*ite_ne_zeroextractsi"
2293   [(set (match_operand:SI 0 "s_register_operand" "=r")
2294         (if_then_else:SI (ne (zero_extract:SI
2295                               (match_operand:SI 1 "s_register_operand" "r")
2296                               (match_operand:SI 2 "const_int_operand" "n")
2297                               (match_operand:SI 3 "const_int_operand" "n"))
2298                              (const_int 0))
2299                          (match_operand:SI 4 "arm_not_operand" "rIK")
2300                          (const_int 0)))
2301    (clobber (reg:CC CC_REGNUM))]
2302   "TARGET_ARM
2303    && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2304        && INTVAL (operands[2]) > 0 
2305        && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2306        && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)
2307    && !reg_overlap_mentioned_p (operands[0], operands[4])"
2308   "#"
2309   "TARGET_ARM
2310    && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2311        && INTVAL (operands[2]) > 0 
2312        && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2313        && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)
2314    && !reg_overlap_mentioned_p (operands[0], operands[4])"
2315   [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2316                    (compare:CC_NOOV (and:SI (match_dup 1) (match_dup 2))
2317                                     (const_int 0)))
2318               (set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))])
2319    (set (match_dup 0)
2320         (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2321                          (match_dup 0) (match_dup 4)))]
2322   "
2323   operands[2] = GEN_INT (((1 << INTVAL (operands[2])) - 1)
2324                          << INTVAL (operands[3])); 
2325   "
2326   [(set_attr "conds" "clob")
2327    (set_attr "length" "8")
2328    (set_attr "type" "multiple")]
2331 (define_insn_and_split "*ite_ne_zeroextractsi_shifted"
2332   [(set (match_operand:SI 0 "s_register_operand" "=r")
2333         (if_then_else:SI (ne (zero_extract:SI
2334                               (match_operand:SI 1 "s_register_operand" "r")
2335                               (match_operand:SI 2 "const_int_operand" "n")
2336                               (const_int 0))
2337                              (const_int 0))
2338                          (match_operand:SI 3 "arm_not_operand" "rIK")
2339                          (const_int 0)))
2340    (clobber (reg:CC CC_REGNUM))]
2341   "TARGET_ARM && !reg_overlap_mentioned_p (operands[0], operands[3])"
2342   "#"
2343   "TARGET_ARM && !reg_overlap_mentioned_p (operands[0], operands[3])"
2344   [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2345                    (compare:CC_NOOV (ashift:SI (match_dup 1) (match_dup 2))
2346                                     (const_int 0)))
2347               (set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))])
2348    (set (match_dup 0)
2349         (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2350                          (match_dup 0) (match_dup 3)))]
2351   "
2352   operands[2] = GEN_INT (32 - INTVAL (operands[2]));
2353   "
2354   [(set_attr "conds" "clob")
2355    (set_attr "length" "8")
2356    (set_attr "type" "multiple")]
2359 ;; ??? Use Thumb-2 has bitfield insert/extract instructions.
2360 (define_split
2361   [(set (match_operand:SI 0 "s_register_operand" "")
2362         (match_operator:SI 1 "shiftable_operator"
2363          [(zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
2364                            (match_operand:SI 3 "const_int_operand" "")
2365                            (match_operand:SI 4 "const_int_operand" ""))
2366           (match_operand:SI 5 "s_register_operand" "")]))
2367    (clobber (match_operand:SI 6 "s_register_operand" ""))]
2368   "TARGET_ARM"
2369   [(set (match_dup 6) (ashift:SI (match_dup 2) (match_dup 3)))
2370    (set (match_dup 0)
2371         (match_op_dup 1
2372          [(lshiftrt:SI (match_dup 6) (match_dup 4))
2373           (match_dup 5)]))]
2374   "{
2375      HOST_WIDE_INT temp = INTVAL (operands[3]);
2377      operands[3] = GEN_INT (32 - temp - INTVAL (operands[4]));
2378      operands[4] = GEN_INT (32 - temp);
2379    }"
2381   
2382 (define_split
2383   [(set (match_operand:SI 0 "s_register_operand" "")
2384         (match_operator:SI 1 "shiftable_operator"
2385          [(sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
2386                            (match_operand:SI 3 "const_int_operand" "")
2387                            (match_operand:SI 4 "const_int_operand" ""))
2388           (match_operand:SI 5 "s_register_operand" "")]))
2389    (clobber (match_operand:SI 6 "s_register_operand" ""))]
2390   "TARGET_ARM"
2391   [(set (match_dup 6) (ashift:SI (match_dup 2) (match_dup 3)))
2392    (set (match_dup 0)
2393         (match_op_dup 1
2394          [(ashiftrt:SI (match_dup 6) (match_dup 4))
2395           (match_dup 5)]))]
2396   "{
2397      HOST_WIDE_INT temp = INTVAL (operands[3]);
2399      operands[3] = GEN_INT (32 - temp - INTVAL (operands[4]));
2400      operands[4] = GEN_INT (32 - temp);
2401    }"
2403   
2404 ;;; ??? This pattern is bogus.  If operand3 has bits outside the range
2405 ;;; represented by the bitfield, then this will produce incorrect results.
2406 ;;; Somewhere, the value needs to be truncated.  On targets like the m68k,
2407 ;;; which have a real bit-field insert instruction, the truncation happens
2408 ;;; in the bit-field insert instruction itself.  Since arm does not have a
2409 ;;; bit-field insert instruction, we would have to emit code here to truncate
2410 ;;; the value before we insert.  This loses some of the advantage of having
2411 ;;; this insv pattern, so this pattern needs to be reevalutated.
2413 (define_expand "insv"
2414   [(set (zero_extract (match_operand 0 "nonimmediate_operand" "")
2415                       (match_operand 1 "general_operand" "")
2416                       (match_operand 2 "general_operand" ""))
2417         (match_operand 3 "reg_or_int_operand" ""))]
2418   "TARGET_ARM || arm_arch_thumb2"
2419   "
2420   {
2421     int start_bit = INTVAL (operands[2]);
2422     int width = INTVAL (operands[1]);
2423     HOST_WIDE_INT mask = (((HOST_WIDE_INT)1) << width) - 1;
2424     rtx target, subtarget;
2426     if (arm_arch_thumb2)
2427       {
2428         if (unaligned_access && MEM_P (operands[0])
2429             && s_register_operand (operands[3], GET_MODE (operands[3]))
2430             && (width == 16 || width == 32) && (start_bit % BITS_PER_UNIT) == 0)
2431           {
2432             rtx base_addr;
2434             if (BYTES_BIG_ENDIAN)
2435               start_bit = GET_MODE_BITSIZE (GET_MODE (operands[3])) - width
2436                           - start_bit;
2438             if (width == 32)
2439               {
2440                 base_addr = adjust_address (operands[0], SImode,
2441                                             start_bit / BITS_PER_UNIT);
2442                 emit_insn (gen_unaligned_storesi (base_addr, operands[3]));
2443               }
2444             else
2445               {
2446                 rtx tmp = gen_reg_rtx (HImode);
2448                 base_addr = adjust_address (operands[0], HImode,
2449                                             start_bit / BITS_PER_UNIT);
2450                 emit_move_insn (tmp, gen_lowpart (HImode, operands[3]));
2451                 emit_insn (gen_unaligned_storehi (base_addr, tmp));
2452               }
2453             DONE;
2454           }
2455         else if (s_register_operand (operands[0], GET_MODE (operands[0])))
2456           {
2457             bool use_bfi = TRUE;
2459             if (CONST_INT_P (operands[3]))
2460               {
2461                 HOST_WIDE_INT val = INTVAL (operands[3]) & mask;
2463                 if (val == 0)
2464                   {
2465                     emit_insn (gen_insv_zero (operands[0], operands[1],
2466                                               operands[2]));
2467                     DONE;
2468                   }
2470                 /* See if the set can be done with a single orr instruction.  */
2471                 if (val == mask && const_ok_for_arm (val << start_bit))
2472                   use_bfi = FALSE;
2473               }
2475             if (use_bfi)
2476               {
2477                 if (!REG_P (operands[3]))
2478                   operands[3] = force_reg (SImode, operands[3]);
2480                 emit_insn (gen_insv_t2 (operands[0], operands[1], operands[2],
2481                                         operands[3]));
2482                 DONE;
2483               }
2484           }
2485         else
2486           FAIL;
2487       }
2489     if (!s_register_operand (operands[0], GET_MODE (operands[0])))
2490       FAIL;
2492     target = copy_rtx (operands[0]);
2493     /* Avoid using a subreg as a subtarget, and avoid writing a paradoxical 
2494        subreg as the final target.  */
2495     if (GET_CODE (target) == SUBREG)
2496       {
2497         subtarget = gen_reg_rtx (SImode);
2498         if (GET_MODE_SIZE (GET_MODE (SUBREG_REG (target)))
2499             < GET_MODE_SIZE (SImode))
2500           target = SUBREG_REG (target);
2501       }
2502     else
2503       subtarget = target;    
2505     if (CONST_INT_P (operands[3]))
2506       {
2507         /* Since we are inserting a known constant, we may be able to
2508            reduce the number of bits that we have to clear so that
2509            the mask becomes simple.  */
2510         /* ??? This code does not check to see if the new mask is actually
2511            simpler.  It may not be.  */
2512         rtx op1 = gen_reg_rtx (SImode);
2513         /* ??? Truncate operand3 to fit in the bitfield.  See comment before
2514            start of this pattern.  */
2515         HOST_WIDE_INT op3_value = mask & INTVAL (operands[3]);
2516         HOST_WIDE_INT mask2 = ((mask & ~op3_value) << start_bit);
2518         emit_insn (gen_andsi3 (op1, operands[0],
2519                                gen_int_mode (~mask2, SImode)));
2520         emit_insn (gen_iorsi3 (subtarget, op1,
2521                                gen_int_mode (op3_value << start_bit, SImode)));
2522       }
2523     else if (start_bit == 0
2524              && !(const_ok_for_arm (mask)
2525                   || const_ok_for_arm (~mask)))
2526       {
2527         /* A Trick, since we are setting the bottom bits in the word,
2528            we can shift operand[3] up, operand[0] down, OR them together
2529            and rotate the result back again.  This takes 3 insns, and
2530            the third might be mergeable into another op.  */
2531         /* The shift up copes with the possibility that operand[3] is
2532            wider than the bitfield.  */
2533         rtx op0 = gen_reg_rtx (SImode);
2534         rtx op1 = gen_reg_rtx (SImode);
2536         emit_insn (gen_ashlsi3 (op0, operands[3], GEN_INT (32 - width)));
2537         emit_insn (gen_lshrsi3 (op1, operands[0], operands[1]));
2538         emit_insn (gen_iorsi3  (op1, op1, op0));
2539         emit_insn (gen_rotlsi3 (subtarget, op1, operands[1]));
2540       }
2541     else if ((width + start_bit == 32)
2542              && !(const_ok_for_arm (mask)
2543                   || const_ok_for_arm (~mask)))
2544       {
2545         /* Similar trick, but slightly less efficient.  */
2547         rtx op0 = gen_reg_rtx (SImode);
2548         rtx op1 = gen_reg_rtx (SImode);
2550         emit_insn (gen_ashlsi3 (op0, operands[3], GEN_INT (32 - width)));
2551         emit_insn (gen_ashlsi3 (op1, operands[0], operands[1]));
2552         emit_insn (gen_lshrsi3 (op1, op1, operands[1]));
2553         emit_insn (gen_iorsi3 (subtarget, op1, op0));
2554       }
2555     else
2556       {
2557         rtx op0 = gen_int_mode (mask, SImode);
2558         rtx op1 = gen_reg_rtx (SImode);
2559         rtx op2 = gen_reg_rtx (SImode);
2561         if (!(const_ok_for_arm (mask) || const_ok_for_arm (~mask)))
2562           {
2563             rtx tmp = gen_reg_rtx (SImode);
2565             emit_insn (gen_movsi (tmp, op0));
2566             op0 = tmp;
2567           }
2569         /* Mask out any bits in operand[3] that are not needed.  */
2570            emit_insn (gen_andsi3 (op1, operands[3], op0));
2572         if (CONST_INT_P (op0)
2573             && (const_ok_for_arm (mask << start_bit)
2574                 || const_ok_for_arm (~(mask << start_bit))))
2575           {
2576             op0 = gen_int_mode (~(mask << start_bit), SImode);
2577             emit_insn (gen_andsi3 (op2, operands[0], op0));
2578           }
2579         else
2580           {
2581             if (CONST_INT_P (op0))
2582               {
2583                 rtx tmp = gen_reg_rtx (SImode);
2585                 emit_insn (gen_movsi (tmp, op0));
2586                 op0 = tmp;
2587               }
2589             if (start_bit != 0)
2590               emit_insn (gen_ashlsi3 (op0, op0, operands[2]));
2591             
2592             emit_insn (gen_andsi_notsi_si (op2, operands[0], op0));
2593           }
2595         if (start_bit != 0)
2596           emit_insn (gen_ashlsi3 (op1, op1, operands[2]));
2598         emit_insn (gen_iorsi3 (subtarget, op1, op2));
2599       }
2601     if (subtarget != target)
2602       {
2603         /* If TARGET is still a SUBREG, then it must be wider than a word,
2604            so we must be careful only to set the subword we were asked to.  */
2605         if (GET_CODE (target) == SUBREG)
2606           emit_move_insn (target, subtarget);
2607         else
2608           emit_move_insn (target, gen_lowpart (GET_MODE (target), subtarget));
2609       }
2611     DONE;
2612   }"
2615 (define_insn "insv_zero"
2616   [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r")
2617                          (match_operand:SI 1 "const_int_M_operand" "M")
2618                          (match_operand:SI 2 "const_int_M_operand" "M"))
2619         (const_int 0))]
2620   "arm_arch_thumb2"
2621   "bfc%?\t%0, %2, %1"
2622   [(set_attr "length" "4")
2623    (set_attr "predicable" "yes")
2624    (set_attr "predicable_short_it" "no")
2625    (set_attr "type" "bfm")]
2628 (define_insn "insv_t2"
2629   [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r")
2630                          (match_operand:SI 1 "const_int_M_operand" "M")
2631                          (match_operand:SI 2 "const_int_M_operand" "M"))
2632         (match_operand:SI 3 "s_register_operand" "r"))]
2633   "arm_arch_thumb2"
2634   "bfi%?\t%0, %3, %2, %1"
2635   [(set_attr "length" "4")
2636    (set_attr "predicable" "yes")
2637    (set_attr "predicable_short_it" "no")
2638    (set_attr "type" "bfm")]
2641 ; constants for op 2 will never be given to these patterns.
2642 (define_insn_and_split "*anddi_notdi_di"
2643   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2644         (and:DI (not:DI (match_operand:DI 1 "s_register_operand" "0,r"))
2645                 (match_operand:DI 2 "s_register_operand" "r,0")))]
2646   "TARGET_32BIT"
2647   "#"
2648   "TARGET_32BIT && reload_completed
2649    && ! (TARGET_NEON && IS_VFP_REGNUM (REGNO (operands[0])))
2650    && ! IS_IWMMXT_REGNUM (REGNO (operands[0]))"
2651   [(set (match_dup 0) (and:SI (not:SI (match_dup 1)) (match_dup 2)))
2652    (set (match_dup 3) (and:SI (not:SI (match_dup 4)) (match_dup 5)))]
2653   "
2654   {
2655     operands[3] = gen_highpart (SImode, operands[0]);
2656     operands[0] = gen_lowpart (SImode, operands[0]);
2657     operands[4] = gen_highpart (SImode, operands[1]);
2658     operands[1] = gen_lowpart (SImode, operands[1]);
2659     operands[5] = gen_highpart (SImode, operands[2]);
2660     operands[2] = gen_lowpart (SImode, operands[2]);
2661   }"
2662   [(set_attr "length" "8")
2663    (set_attr "predicable" "yes")
2664    (set_attr "type" "multiple")]
2667 (define_insn_and_split "*anddi_notzesidi_di"
2668   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2669         (and:DI (not:DI (zero_extend:DI
2670                          (match_operand:SI 2 "s_register_operand" "r,r")))
2671                 (match_operand:DI 1 "s_register_operand" "0,?r")))]
2672   "TARGET_32BIT"
2673   "@
2674    bic%?\\t%Q0, %Q1, %2
2675    #"
2676   ; (not (zero_extend ...)) allows us to just copy the high word from
2677   ; operand1 to operand0.
2678   "TARGET_32BIT
2679    && reload_completed
2680    && operands[0] != operands[1]"
2681   [(set (match_dup 0) (and:SI (not:SI (match_dup 2)) (match_dup 1)))
2682    (set (match_dup 3) (match_dup 4))]
2683   "
2684   {
2685     operands[3] = gen_highpart (SImode, operands[0]);
2686     operands[0] = gen_lowpart (SImode, operands[0]);
2687     operands[4] = gen_highpart (SImode, operands[1]);
2688     operands[1] = gen_lowpart (SImode, operands[1]);
2689   }"
2690   [(set_attr "length" "4,8")
2691    (set_attr "predicable" "yes")
2692    (set_attr "predicable_short_it" "no")
2693    (set_attr "type" "multiple")]
2696 (define_insn_and_split "*anddi_notdi_zesidi"
2697   [(set (match_operand:DI 0 "s_register_operand" "=r")
2698         (and:DI (not:DI (match_operand:DI 2 "s_register_operand" "r"))
2699                 (zero_extend:DI
2700                  (match_operand:SI 1 "s_register_operand" "r"))))]
2701   "TARGET_32BIT"
2702   "#"
2703   "TARGET_32BIT && reload_completed"
2704   [(set (match_dup 0) (and:SI (not:SI (match_dup 2)) (match_dup 1)))
2705    (set (match_dup 3) (const_int 0))]
2706   "
2707   {
2708     operands[3] = gen_highpart (SImode, operands[0]);
2709     operands[0] = gen_lowpart (SImode, operands[0]);
2710     operands[2] = gen_lowpart (SImode, operands[2]);
2711   }"
2712   [(set_attr "length" "8")
2713    (set_attr "predicable" "yes")
2714    (set_attr "predicable_short_it" "no")
2715    (set_attr "type" "multiple")]
2718 (define_insn_and_split "*anddi_notsesidi_di"
2719   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2720         (and:DI (not:DI (sign_extend:DI
2721                          (match_operand:SI 2 "s_register_operand" "r,r")))
2722                 (match_operand:DI 1 "s_register_operand" "0,r")))]
2723   "TARGET_32BIT"
2724   "#"
2725   "TARGET_32BIT && reload_completed"
2726   [(set (match_dup 0) (and:SI (not:SI (match_dup 2)) (match_dup 1)))
2727    (set (match_dup 3) (and:SI (not:SI
2728                                 (ashiftrt:SI (match_dup 2) (const_int 31)))
2729                                (match_dup 4)))]
2730   "
2731   {
2732     operands[3] = gen_highpart (SImode, operands[0]);
2733     operands[0] = gen_lowpart (SImode, operands[0]);
2734     operands[4] = gen_highpart (SImode, operands[1]);
2735     operands[1] = gen_lowpart (SImode, operands[1]);
2736   }"
2737   [(set_attr "length" "8")
2738    (set_attr "predicable" "yes")
2739    (set_attr "predicable_short_it" "no")
2740    (set_attr "type" "multiple")]
2743 (define_insn "andsi_notsi_si"
2744   [(set (match_operand:SI 0 "s_register_operand" "=r")
2745         (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
2746                 (match_operand:SI 1 "s_register_operand" "r")))]
2747   "TARGET_32BIT"
2748   "bic%?\\t%0, %1, %2"
2749   [(set_attr "predicable" "yes")
2750    (set_attr "predicable_short_it" "no")
2751    (set_attr "type" "logic_reg")]
2754 (define_insn "andsi_not_shiftsi_si"
2755   [(set (match_operand:SI 0 "s_register_operand" "=r")
2756         (and:SI (not:SI (match_operator:SI 4 "shift_operator"
2757                          [(match_operand:SI 2 "s_register_operand" "r")
2758                           (match_operand:SI 3 "arm_rhs_operand" "rM")]))
2759                 (match_operand:SI 1 "s_register_operand" "r")))]
2760   "TARGET_ARM"
2761   "bic%?\\t%0, %1, %2%S4"
2762   [(set_attr "predicable" "yes")
2763    (set_attr "shift" "2")
2764    (set (attr "type") (if_then_else (match_operand 3 "const_int_operand" "")
2765                       (const_string "logic_shift_imm")
2766                       (const_string "logic_shift_reg")))]
2769 (define_insn "*andsi_notsi_si_compare0"
2770   [(set (reg:CC_NOOV CC_REGNUM)
2771         (compare:CC_NOOV
2772          (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
2773                  (match_operand:SI 1 "s_register_operand" "r"))
2774          (const_int 0)))
2775    (set (match_operand:SI 0 "s_register_operand" "=r")
2776         (and:SI (not:SI (match_dup 2)) (match_dup 1)))]
2777   "TARGET_32BIT"
2778   "bic%.\\t%0, %1, %2"
2779   [(set_attr "conds" "set")
2780    (set_attr "type" "logics_shift_reg")]
2783 (define_insn "*andsi_notsi_si_compare0_scratch"
2784   [(set (reg:CC_NOOV CC_REGNUM)
2785         (compare:CC_NOOV
2786          (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
2787                  (match_operand:SI 1 "s_register_operand" "r"))
2788          (const_int 0)))
2789    (clobber (match_scratch:SI 0 "=r"))]
2790   "TARGET_32BIT"
2791   "bic%.\\t%0, %1, %2"
2792   [(set_attr "conds" "set")
2793    (set_attr "type" "logics_shift_reg")]
2796 (define_expand "iordi3"
2797   [(set (match_operand:DI         0 "s_register_operand" "")
2798         (ior:DI (match_operand:DI 1 "s_register_operand" "")
2799                 (match_operand:DI 2 "neon_logic_op2" "")))]
2800   "TARGET_32BIT"
2801   ""
2804 (define_insn_and_split "*iordi3_insn"
2805   [(set (match_operand:DI         0 "s_register_operand"     "=w,w ,&r,&r,&r,&r,?w,?w")
2806         (ior:DI (match_operand:DI 1 "s_register_operand"     "%w,0 ,0 ,r ,0 ,r ,w ,0")
2807                 (match_operand:DI 2 "arm_iordi_operand_neon" "w ,Dl,r ,r ,Df,Df,w ,Dl")))]
2808   "TARGET_32BIT && !TARGET_IWMMXT"
2809   {
2810   switch (which_alternative)
2811     {
2812     case 0: /* fall through */
2813     case 6: return "vorr\t%P0, %P1, %P2";
2814     case 1: /* fall through */
2815     case 7: return neon_output_logic_immediate ("vorr", &operands[2],
2816                      DImode, 0, VALID_NEON_QREG_MODE (DImode));
2817     case 2:
2818     case 3:
2819     case 4:
2820     case 5:
2821       return "#";
2822     default: gcc_unreachable ();
2823     }
2824   }
2825   "TARGET_32BIT && !TARGET_IWMMXT && reload_completed
2826    && !(IS_VFP_REGNUM (REGNO (operands[0])))"
2827   [(set (match_dup 3) (match_dup 4))
2828    (set (match_dup 5) (match_dup 6))]
2829   "
2830   {
2831     operands[3] = gen_lowpart (SImode, operands[0]);
2832     operands[5] = gen_highpart (SImode, operands[0]);
2834     operands[4] = simplify_gen_binary (IOR, SImode,
2835                                            gen_lowpart (SImode, operands[1]),
2836                                            gen_lowpart (SImode, operands[2]));
2837     operands[6] = simplify_gen_binary (IOR, SImode,
2838                                            gen_highpart (SImode, operands[1]),
2839                                            gen_highpart_mode (SImode, DImode, operands[2]));
2841   }"
2842   [(set_attr "type" "neon_logic,neon_logic,multiple,multiple,multiple,\
2843                      multiple,neon_logic,neon_logic")
2844    (set_attr "length" "*,*,8,8,8,8,*,*")
2845    (set_attr "arch" "neon_for_64bits,neon_for_64bits,*,*,*,*,avoid_neon_for_64bits,avoid_neon_for_64bits")]
2848 (define_insn "*iordi_zesidi_di"
2849   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2850         (ior:DI (zero_extend:DI
2851                  (match_operand:SI 2 "s_register_operand" "r,r"))
2852                 (match_operand:DI 1 "s_register_operand" "0,?r")))]
2853   "TARGET_32BIT"
2854   "@
2855    orr%?\\t%Q0, %Q1, %2
2856    #"
2857   [(set_attr "length" "4,8")
2858    (set_attr "predicable" "yes")
2859    (set_attr "predicable_short_it" "no")
2860    (set_attr "type" "logic_reg,multiple")]
2863 (define_insn "*iordi_sesidi_di"
2864   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2865         (ior:DI (sign_extend:DI
2866                  (match_operand:SI 2 "s_register_operand" "r,r"))
2867                 (match_operand:DI 1 "s_register_operand" "0,r")))]
2868   "TARGET_32BIT"
2869   "#"
2870   [(set_attr "length" "8")
2871    (set_attr "predicable" "yes")
2872    (set_attr "type" "multiple")]
2875 (define_expand "iorsi3"
2876   [(set (match_operand:SI         0 "s_register_operand" "")
2877         (ior:SI (match_operand:SI 1 "s_register_operand" "")
2878                 (match_operand:SI 2 "reg_or_int_operand" "")))]
2879   "TARGET_EITHER"
2880   "
2881   if (CONST_INT_P (operands[2]))
2882     {
2883       if (TARGET_32BIT)
2884         {
2885           arm_split_constant (IOR, SImode, NULL_RTX,
2886                               INTVAL (operands[2]), operands[0], operands[1],
2887                               optimize && can_create_pseudo_p ());
2888           DONE;
2889         }
2890       else /* TARGET_THUMB1 */
2891         {
2892           rtx tmp = force_reg (SImode, operands[2]);
2893           if (rtx_equal_p (operands[0], operands[1]))
2894             operands[2] = tmp;
2895           else
2896             {
2897               operands[2] = operands[1];
2898               operands[1] = tmp;
2899             }
2900         }
2901     }
2902   "
2905 (define_insn_and_split "*iorsi3_insn"
2906   [(set (match_operand:SI 0 "s_register_operand" "=r,l,r,r,r")
2907         (ior:SI (match_operand:SI 1 "s_register_operand" "%r,0,r,r,r")
2908                 (match_operand:SI 2 "reg_or_int_operand" "I,l,K,r,?n")))]
2909   "TARGET_32BIT"
2910   "@
2911    orr%?\\t%0, %1, %2
2912    orr%?\\t%0, %1, %2
2913    orn%?\\t%0, %1, #%B2
2914    orr%?\\t%0, %1, %2
2915    #"
2916   "TARGET_32BIT
2917    && CONST_INT_P (operands[2])
2918    && !(const_ok_for_arm (INTVAL (operands[2]))
2919         || (TARGET_THUMB2 && const_ok_for_arm (~INTVAL (operands[2]))))"
2920   [(clobber (const_int 0))]
2922   arm_split_constant (IOR, SImode, curr_insn,
2923                       INTVAL (operands[2]), operands[0], operands[1], 0);
2924   DONE;
2926   [(set_attr "length" "4,4,4,4,16")
2927    (set_attr "arch" "32,t2,t2,32,32")
2928    (set_attr "predicable" "yes")
2929    (set_attr "predicable_short_it" "no,yes,no,no,no")
2930    (set_attr "type" "logic_imm,logic_reg,logic_imm,logic_reg,logic_reg")]
2933 (define_peephole2
2934   [(match_scratch:SI 3 "r")
2935    (set (match_operand:SI 0 "arm_general_register_operand" "")
2936         (ior:SI (match_operand:SI 1 "arm_general_register_operand" "")
2937                 (match_operand:SI 2 "const_int_operand" "")))]
2938   "TARGET_ARM
2939    && !const_ok_for_arm (INTVAL (operands[2]))
2940    && const_ok_for_arm (~INTVAL (operands[2]))"
2941   [(set (match_dup 3) (match_dup 2))
2942    (set (match_dup 0) (ior:SI (match_dup 1) (match_dup 3)))]
2943   ""
2946 (define_insn "*iorsi3_compare0"
2947   [(set (reg:CC_NOOV CC_REGNUM)
2948         (compare:CC_NOOV (ior:SI (match_operand:SI 1 "s_register_operand" "%r,r")
2949                                  (match_operand:SI 2 "arm_rhs_operand" "I,r"))
2950                          (const_int 0)))
2951    (set (match_operand:SI 0 "s_register_operand" "=r,r")
2952         (ior:SI (match_dup 1) (match_dup 2)))]
2953   "TARGET_32BIT"
2954   "orr%.\\t%0, %1, %2"
2955   [(set_attr "conds" "set")
2956    (set_attr "type" "logics_imm,logics_reg")]
2959 (define_insn "*iorsi3_compare0_scratch"
2960   [(set (reg:CC_NOOV CC_REGNUM)
2961         (compare:CC_NOOV (ior:SI (match_operand:SI 1 "s_register_operand" "%r,r")
2962                                  (match_operand:SI 2 "arm_rhs_operand" "I,r"))
2963                          (const_int 0)))
2964    (clobber (match_scratch:SI 0 "=r,r"))]
2965   "TARGET_32BIT"
2966   "orr%.\\t%0, %1, %2"
2967   [(set_attr "conds" "set")
2968    (set_attr "type" "logics_imm,logics_reg")]
2971 (define_expand "xordi3"
2972   [(set (match_operand:DI         0 "s_register_operand" "")
2973         (xor:DI (match_operand:DI 1 "s_register_operand" "")
2974                 (match_operand:DI 2 "arm_xordi_operand" "")))]
2975   "TARGET_32BIT"
2976   ""
2979 (define_insn_and_split "*xordi3_insn"
2980   [(set (match_operand:DI         0 "s_register_operand" "=w,&r,&r,&r,&r,?w")
2981         (xor:DI (match_operand:DI 1 "s_register_operand" "%w ,0,r ,0 ,r ,w")
2982                 (match_operand:DI 2 "arm_xordi_operand"  "w ,r ,r ,Dg,Dg,w")))]
2983   "TARGET_32BIT && !TARGET_IWMMXT"
2985   switch (which_alternative)
2986     {
2987     case 1:
2988     case 2:
2989     case 3:
2990     case 4:  /* fall through */
2991       return "#";
2992     case 0: /* fall through */
2993     case 5: return "veor\t%P0, %P1, %P2";
2994     default: gcc_unreachable ();
2995     }
2997   "TARGET_32BIT && !TARGET_IWMMXT && reload_completed
2998    && !(IS_VFP_REGNUM (REGNO (operands[0])))"
2999   [(set (match_dup 3) (match_dup 4))
3000    (set (match_dup 5) (match_dup 6))]
3001   "
3002   {
3003     operands[3] = gen_lowpart (SImode, operands[0]);
3004     operands[5] = gen_highpart (SImode, operands[0]);
3006     operands[4] = simplify_gen_binary (XOR, SImode,
3007                                            gen_lowpart (SImode, operands[1]),
3008                                            gen_lowpart (SImode, operands[2]));
3009     operands[6] = simplify_gen_binary (XOR, SImode,
3010                                            gen_highpart (SImode, operands[1]),
3011                                            gen_highpart_mode (SImode, DImode, operands[2]));
3013   }"
3014   [(set_attr "length" "*,8,8,8,8,*")
3015    (set_attr "type" "neon_logic,multiple,multiple,multiple,multiple,neon_logic")
3016    (set_attr "arch" "neon_for_64bits,*,*,*,*,avoid_neon_for_64bits")]
3019 (define_insn "*xordi_zesidi_di"
3020   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
3021         (xor:DI (zero_extend:DI
3022                  (match_operand:SI 2 "s_register_operand" "r,r"))
3023                 (match_operand:DI 1 "s_register_operand" "0,?r")))]
3024   "TARGET_32BIT"
3025   "@
3026    eor%?\\t%Q0, %Q1, %2
3027    #"
3028   [(set_attr "length" "4,8")
3029    (set_attr "predicable" "yes")
3030    (set_attr "predicable_short_it" "no")
3031    (set_attr "type" "logic_reg")]
3034 (define_insn "*xordi_sesidi_di"
3035   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
3036         (xor:DI (sign_extend:DI
3037                  (match_operand:SI 2 "s_register_operand" "r,r"))
3038                 (match_operand:DI 1 "s_register_operand" "0,r")))]
3039   "TARGET_32BIT"
3040   "#"
3041   [(set_attr "length" "8")
3042    (set_attr "predicable" "yes")
3043    (set_attr "type" "multiple")]
3046 (define_expand "xorsi3"
3047   [(set (match_operand:SI         0 "s_register_operand" "")
3048         (xor:SI (match_operand:SI 1 "s_register_operand" "")
3049                 (match_operand:SI 2 "reg_or_int_operand" "")))]
3050   "TARGET_EITHER"
3051   "if (CONST_INT_P (operands[2]))
3052     {
3053       if (TARGET_32BIT)
3054         {
3055           arm_split_constant (XOR, SImode, NULL_RTX,
3056                               INTVAL (operands[2]), operands[0], operands[1],
3057                               optimize && can_create_pseudo_p ());
3058           DONE;
3059         }
3060       else /* TARGET_THUMB1 */
3061         {
3062           rtx tmp = force_reg (SImode, operands[2]);
3063           if (rtx_equal_p (operands[0], operands[1]))
3064             operands[2] = tmp;
3065           else
3066             {
3067               operands[2] = operands[1];
3068               operands[1] = tmp;
3069             }
3070         }
3071     }"
3074 (define_insn_and_split "*arm_xorsi3"
3075   [(set (match_operand:SI         0 "s_register_operand" "=r,l,r,r")
3076         (xor:SI (match_operand:SI 1 "s_register_operand" "%r,0,r,r")
3077                 (match_operand:SI 2 "reg_or_int_operand" "I,l,r,?n")))]
3078   "TARGET_32BIT"
3079   "@
3080    eor%?\\t%0, %1, %2
3081    eor%?\\t%0, %1, %2
3082    eor%?\\t%0, %1, %2
3083    #"
3084   "TARGET_32BIT
3085    && CONST_INT_P (operands[2])
3086    && !const_ok_for_arm (INTVAL (operands[2]))"
3087   [(clobber (const_int 0))]
3089   arm_split_constant (XOR, SImode, curr_insn,
3090                       INTVAL (operands[2]), operands[0], operands[1], 0);
3091   DONE;
3093   [(set_attr "length" "4,4,4,16")
3094    (set_attr "predicable" "yes")
3095    (set_attr "predicable_short_it" "no,yes,no,no")
3096    (set_attr "type"  "logic_imm,logic_reg,logic_reg,multiple")]
3099 (define_insn "*xorsi3_compare0"
3100   [(set (reg:CC_NOOV CC_REGNUM)
3101         (compare:CC_NOOV (xor:SI (match_operand:SI 1 "s_register_operand" "r,r")
3102                                  (match_operand:SI 2 "arm_rhs_operand" "I,r"))
3103                          (const_int 0)))
3104    (set (match_operand:SI 0 "s_register_operand" "=r,r")
3105         (xor:SI (match_dup 1) (match_dup 2)))]
3106   "TARGET_32BIT"
3107   "eor%.\\t%0, %1, %2"
3108   [(set_attr "conds" "set")
3109    (set_attr "type" "logics_imm,logics_reg")]
3112 (define_insn "*xorsi3_compare0_scratch"
3113   [(set (reg:CC_NOOV CC_REGNUM)
3114         (compare:CC_NOOV (xor:SI (match_operand:SI 0 "s_register_operand" "r,r")
3115                                  (match_operand:SI 1 "arm_rhs_operand" "I,r"))
3116                          (const_int 0)))]
3117   "TARGET_32BIT"
3118   "teq%?\\t%0, %1"
3119   [(set_attr "conds" "set")
3120    (set_attr "type" "logics_imm,logics_reg")]
3123 ; By splitting (IOR (AND (NOT A) (NOT B)) C) as D = AND (IOR A B) (NOT C), 
3124 ; (NOT D) we can sometimes merge the final NOT into one of the following
3125 ; insns.
3127 (define_split
3128   [(set (match_operand:SI 0 "s_register_operand" "")
3129         (ior:SI (and:SI (not:SI (match_operand:SI 1 "s_register_operand" ""))
3130                         (not:SI (match_operand:SI 2 "arm_rhs_operand" "")))
3131                 (match_operand:SI 3 "arm_rhs_operand" "")))
3132    (clobber (match_operand:SI 4 "s_register_operand" ""))]
3133   "TARGET_32BIT"
3134   [(set (match_dup 4) (and:SI (ior:SI (match_dup 1) (match_dup 2))
3135                               (not:SI (match_dup 3))))
3136    (set (match_dup 0) (not:SI (match_dup 4)))]
3137   ""
3140 (define_insn_and_split "*andsi_iorsi3_notsi"
3141   [(set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r")
3142         (and:SI (ior:SI (match_operand:SI 1 "s_register_operand" "%0,r,r")
3143                         (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI"))
3144                 (not:SI (match_operand:SI 3 "arm_rhs_operand" "rI,rI,rI"))))]
3145   "TARGET_32BIT"
3146   "#"   ; "orr%?\\t%0, %1, %2\;bic%?\\t%0, %0, %3"
3147   "&& reload_completed"
3148   [(set (match_dup 0) (ior:SI (match_dup 1) (match_dup 2)))
3149    (set (match_dup 0) (and:SI (not:SI (match_dup 3)) (match_dup 0)))]
3150   ""
3151   [(set_attr "length" "8")
3152    (set_attr "ce_count" "2")
3153    (set_attr "predicable" "yes")
3154    (set_attr "predicable_short_it" "no")
3155    (set_attr "type" "multiple")]
3158 ; ??? Are these four splitters still beneficial when the Thumb-2 bitfield
3159 ; insns are available?
3160 (define_split
3161   [(set (match_operand:SI 0 "s_register_operand" "")
3162         (match_operator:SI 1 "logical_binary_operator"
3163          [(zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
3164                            (match_operand:SI 3 "const_int_operand" "")
3165                            (match_operand:SI 4 "const_int_operand" ""))
3166           (match_operator:SI 9 "logical_binary_operator"
3167            [(lshiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3168                          (match_operand:SI 6 "const_int_operand" ""))
3169             (match_operand:SI 7 "s_register_operand" "")])]))
3170    (clobber (match_operand:SI 8 "s_register_operand" ""))]
3171   "TARGET_32BIT
3172    && GET_CODE (operands[1]) == GET_CODE (operands[9])
3173    && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3174   [(set (match_dup 8)
3175         (match_op_dup 1
3176          [(ashift:SI (match_dup 2) (match_dup 4))
3177           (match_dup 5)]))
3178    (set (match_dup 0)
3179         (match_op_dup 1
3180          [(lshiftrt:SI (match_dup 8) (match_dup 6))
3181           (match_dup 7)]))]
3182   "
3183   operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3186 (define_split
3187   [(set (match_operand:SI 0 "s_register_operand" "")
3188         (match_operator:SI 1 "logical_binary_operator"
3189          [(match_operator:SI 9 "logical_binary_operator"
3190            [(lshiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3191                          (match_operand:SI 6 "const_int_operand" ""))
3192             (match_operand:SI 7 "s_register_operand" "")])
3193           (zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
3194                            (match_operand:SI 3 "const_int_operand" "")
3195                            (match_operand:SI 4 "const_int_operand" ""))]))
3196    (clobber (match_operand:SI 8 "s_register_operand" ""))]
3197   "TARGET_32BIT
3198    && GET_CODE (operands[1]) == GET_CODE (operands[9])
3199    && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3200   [(set (match_dup 8)
3201         (match_op_dup 1
3202          [(ashift:SI (match_dup 2) (match_dup 4))
3203           (match_dup 5)]))
3204    (set (match_dup 0)
3205         (match_op_dup 1
3206          [(lshiftrt:SI (match_dup 8) (match_dup 6))
3207           (match_dup 7)]))]
3208   "
3209   operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3212 (define_split
3213   [(set (match_operand:SI 0 "s_register_operand" "")
3214         (match_operator:SI 1 "logical_binary_operator"
3215          [(sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
3216                            (match_operand:SI 3 "const_int_operand" "")
3217                            (match_operand:SI 4 "const_int_operand" ""))
3218           (match_operator:SI 9 "logical_binary_operator"
3219            [(ashiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3220                          (match_operand:SI 6 "const_int_operand" ""))
3221             (match_operand:SI 7 "s_register_operand" "")])]))
3222    (clobber (match_operand:SI 8 "s_register_operand" ""))]
3223   "TARGET_32BIT
3224    && GET_CODE (operands[1]) == GET_CODE (operands[9])
3225    && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3226   [(set (match_dup 8)
3227         (match_op_dup 1
3228          [(ashift:SI (match_dup 2) (match_dup 4))
3229           (match_dup 5)]))
3230    (set (match_dup 0)
3231         (match_op_dup 1
3232          [(ashiftrt:SI (match_dup 8) (match_dup 6))
3233           (match_dup 7)]))]
3234   "
3235   operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3238 (define_split
3239   [(set (match_operand:SI 0 "s_register_operand" "")
3240         (match_operator:SI 1 "logical_binary_operator"
3241          [(match_operator:SI 9 "logical_binary_operator"
3242            [(ashiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3243                          (match_operand:SI 6 "const_int_operand" ""))
3244             (match_operand:SI 7 "s_register_operand" "")])
3245           (sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
3246                            (match_operand:SI 3 "const_int_operand" "")
3247                            (match_operand:SI 4 "const_int_operand" ""))]))
3248    (clobber (match_operand:SI 8 "s_register_operand" ""))]
3249   "TARGET_32BIT
3250    && GET_CODE (operands[1]) == GET_CODE (operands[9])
3251    && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3252   [(set (match_dup 8)
3253         (match_op_dup 1
3254          [(ashift:SI (match_dup 2) (match_dup 4))
3255           (match_dup 5)]))
3256    (set (match_dup 0)
3257         (match_op_dup 1
3258          [(ashiftrt:SI (match_dup 8) (match_dup 6))
3259           (match_dup 7)]))]
3260   "
3261   operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3265 ;; Minimum and maximum insns
3267 (define_expand "smaxsi3"
3268   [(parallel [
3269     (set (match_operand:SI 0 "s_register_operand" "")
3270          (smax:SI (match_operand:SI 1 "s_register_operand" "")
3271                   (match_operand:SI 2 "arm_rhs_operand" "")))
3272     (clobber (reg:CC CC_REGNUM))])]
3273   "TARGET_32BIT"
3274   "
3275   if (operands[2] == const0_rtx || operands[2] == constm1_rtx)
3276     {
3277       /* No need for a clobber of the condition code register here.  */
3278       emit_insn (gen_rtx_SET (VOIDmode, operands[0],
3279                               gen_rtx_SMAX (SImode, operands[1],
3280                                             operands[2])));
3281       DONE;
3282     }
3285 (define_insn "*smax_0"
3286   [(set (match_operand:SI 0 "s_register_operand" "=r")
3287         (smax:SI (match_operand:SI 1 "s_register_operand" "r")
3288                  (const_int 0)))]
3289   "TARGET_32BIT"
3290   "bic%?\\t%0, %1, %1, asr #31"
3291   [(set_attr "predicable" "yes")
3292    (set_attr "predicable_short_it" "no")
3293    (set_attr "type" "logic_shift_reg")]
3296 (define_insn "*smax_m1"
3297   [(set (match_operand:SI 0 "s_register_operand" "=r")
3298         (smax:SI (match_operand:SI 1 "s_register_operand" "r")
3299                  (const_int -1)))]
3300   "TARGET_32BIT"
3301   "orr%?\\t%0, %1, %1, asr #31"
3302   [(set_attr "predicable" "yes")
3303    (set_attr "predicable_short_it" "no")
3304    (set_attr "type" "logic_shift_reg")]
3307 (define_insn_and_split "*arm_smax_insn"
3308   [(set (match_operand:SI          0 "s_register_operand" "=r,r")
3309         (smax:SI (match_operand:SI 1 "s_register_operand"  "%0,?r")
3310                  (match_operand:SI 2 "arm_rhs_operand"    "rI,rI")))
3311    (clobber (reg:CC CC_REGNUM))]
3312   "TARGET_ARM"
3313   "#"
3314    ; cmp\\t%1, %2\;movlt\\t%0, %2
3315    ; cmp\\t%1, %2\;movge\\t%0, %1\;movlt\\t%0, %2"
3316   "TARGET_ARM"
3317   [(set (reg:CC CC_REGNUM)
3318         (compare:CC (match_dup 1) (match_dup 2)))
3319    (set (match_dup 0)
3320         (if_then_else:SI (ge:SI (reg:CC CC_REGNUM) (const_int 0))
3321                          (match_dup 1)
3322                          (match_dup 2)))]
3323   ""
3324   [(set_attr "conds" "clob")
3325    (set_attr "length" "8,12")
3326    (set_attr "type" "multiple")]
3329 (define_expand "sminsi3"
3330   [(parallel [
3331     (set (match_operand:SI 0 "s_register_operand" "")
3332          (smin:SI (match_operand:SI 1 "s_register_operand" "")
3333                   (match_operand:SI 2 "arm_rhs_operand" "")))
3334     (clobber (reg:CC CC_REGNUM))])]
3335   "TARGET_32BIT"
3336   "
3337   if (operands[2] == const0_rtx)
3338     {
3339       /* No need for a clobber of the condition code register here.  */
3340       emit_insn (gen_rtx_SET (VOIDmode, operands[0],
3341                               gen_rtx_SMIN (SImode, operands[1],
3342                                             operands[2])));
3343       DONE;
3344     }
3347 (define_insn "*smin_0"
3348   [(set (match_operand:SI 0 "s_register_operand" "=r")
3349         (smin:SI (match_operand:SI 1 "s_register_operand" "r")
3350                  (const_int 0)))]
3351   "TARGET_32BIT"
3352   "and%?\\t%0, %1, %1, asr #31"
3353   [(set_attr "predicable" "yes")
3354    (set_attr "predicable_short_it" "no")
3355    (set_attr "type" "logic_shift_reg")]
3358 (define_insn_and_split "*arm_smin_insn"
3359   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3360         (smin:SI (match_operand:SI 1 "s_register_operand" "%0,?r")
3361                  (match_operand:SI 2 "arm_rhs_operand" "rI,rI")))
3362    (clobber (reg:CC CC_REGNUM))]
3363   "TARGET_ARM"
3364   "#"
3365     ; cmp\\t%1, %2\;movge\\t%0, %2
3366     ; cmp\\t%1, %2\;movlt\\t%0, %1\;movge\\t%0, %2"
3367   "TARGET_ARM"
3368   [(set (reg:CC CC_REGNUM)
3369         (compare:CC (match_dup 1) (match_dup 2)))
3370    (set (match_dup 0)
3371         (if_then_else:SI (lt:SI (reg:CC CC_REGNUM) (const_int 0))
3372                          (match_dup 1)
3373                          (match_dup 2)))]
3374   ""
3375   [(set_attr "conds" "clob")
3376    (set_attr "length" "8,12")
3377    (set_attr "type" "multiple,multiple")]
3380 (define_expand "umaxsi3"
3381   [(parallel [
3382     (set (match_operand:SI 0 "s_register_operand" "")
3383          (umax:SI (match_operand:SI 1 "s_register_operand" "")
3384                   (match_operand:SI 2 "arm_rhs_operand" "")))
3385     (clobber (reg:CC CC_REGNUM))])]
3386   "TARGET_32BIT"
3387   ""
3390 (define_insn_and_split "*arm_umaxsi3"
3391   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
3392         (umax:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
3393                  (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
3394    (clobber (reg:CC CC_REGNUM))]
3395   "TARGET_ARM"
3396   "#"
3397     ; cmp\\t%1, %2\;movcc\\t%0, %2
3398     ; cmp\\t%1, %2\;movcs\\t%0, %1
3399     ; cmp\\t%1, %2\;movcs\\t%0, %1\;movcc\\t%0, %2"
3400   "TARGET_ARM"
3401   [(set (reg:CC CC_REGNUM)
3402         (compare:CC (match_dup 1) (match_dup 2)))
3403    (set (match_dup 0)
3404         (if_then_else:SI (geu:SI (reg:CC CC_REGNUM) (const_int 0))
3405                          (match_dup 1)
3406                          (match_dup 2)))]
3407   ""
3408   [(set_attr "conds" "clob")
3409    (set_attr "length" "8,8,12")
3410    (set_attr "type" "store1")]
3413 (define_expand "uminsi3"
3414   [(parallel [
3415     (set (match_operand:SI 0 "s_register_operand" "")
3416          (umin:SI (match_operand:SI 1 "s_register_operand" "")
3417                   (match_operand:SI 2 "arm_rhs_operand" "")))
3418     (clobber (reg:CC CC_REGNUM))])]
3419   "TARGET_32BIT"
3420   ""
3423 (define_insn_and_split "*arm_uminsi3"
3424   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
3425         (umin:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
3426                  (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
3427    (clobber (reg:CC CC_REGNUM))]
3428   "TARGET_ARM"
3429   "#"
3430    ; cmp\\t%1, %2\;movcs\\t%0, %2
3431    ; cmp\\t%1, %2\;movcc\\t%0, %1
3432    ; cmp\\t%1, %2\;movcc\\t%0, %1\;movcs\\t%0, %2"
3433   "TARGET_ARM"
3434   [(set (reg:CC CC_REGNUM)
3435         (compare:CC (match_dup 1) (match_dup 2)))
3436    (set (match_dup 0)
3437         (if_then_else:SI (ltu:SI (reg:CC CC_REGNUM) (const_int 0))
3438                          (match_dup 1)
3439                          (match_dup 2)))]
3440   ""
3441   [(set_attr "conds" "clob")
3442    (set_attr "length" "8,8,12")
3443    (set_attr "type" "store1")]
3446 (define_insn "*store_minmaxsi"
3447   [(set (match_operand:SI 0 "memory_operand" "=m")
3448         (match_operator:SI 3 "minmax_operator"
3449          [(match_operand:SI 1 "s_register_operand" "r")
3450           (match_operand:SI 2 "s_register_operand" "r")]))
3451    (clobber (reg:CC CC_REGNUM))]
3452   "TARGET_32BIT && optimize_function_for_size_p (cfun)"
3453   "*
3454   operands[3] = gen_rtx_fmt_ee (minmax_code (operands[3]), SImode,
3455                                 operands[1], operands[2]);
3456   output_asm_insn (\"cmp\\t%1, %2\", operands);
3457   if (TARGET_THUMB2)
3458     output_asm_insn (\"ite\t%d3\", operands);
3459   output_asm_insn (\"str%d3\\t%1, %0\", operands);
3460   output_asm_insn (\"str%D3\\t%2, %0\", operands);
3461   return \"\";
3462   "
3463   [(set_attr "conds" "clob")
3464    (set (attr "length")
3465         (if_then_else (eq_attr "is_thumb" "yes")
3466                       (const_int 14)
3467                       (const_int 12)))
3468    (set_attr "type" "store1")]
3471 ; Reject the frame pointer in operand[1], since reloading this after
3472 ; it has been eliminated can cause carnage.
3473 (define_insn "*minmax_arithsi"
3474   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3475         (match_operator:SI 4 "shiftable_operator"
3476          [(match_operator:SI 5 "minmax_operator"
3477            [(match_operand:SI 2 "s_register_operand" "r,r")
3478             (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
3479           (match_operand:SI 1 "s_register_operand" "0,?r")]))
3480    (clobber (reg:CC CC_REGNUM))]
3481   "TARGET_32BIT && !arm_eliminable_register (operands[1]) && !arm_restrict_it"
3482   "*
3483   {
3484     enum rtx_code code = GET_CODE (operands[4]);
3485     bool need_else;
3487     if (which_alternative != 0 || operands[3] != const0_rtx
3488         || (code != PLUS && code != IOR && code != XOR))
3489       need_else = true;
3490     else
3491       need_else = false;
3493     operands[5] = gen_rtx_fmt_ee (minmax_code (operands[5]), SImode,
3494                                   operands[2], operands[3]);
3495     output_asm_insn (\"cmp\\t%2, %3\", operands);
3496     if (TARGET_THUMB2)
3497       {
3498         if (need_else)
3499           output_asm_insn (\"ite\\t%d5\", operands);
3500         else
3501           output_asm_insn (\"it\\t%d5\", operands);
3502       }
3503     output_asm_insn (\"%i4%d5\\t%0, %1, %2\", operands);
3504     if (need_else)
3505       output_asm_insn (\"%i4%D5\\t%0, %1, %3\", operands);
3506     return \"\";
3507   }"
3508   [(set_attr "conds" "clob")
3509    (set (attr "length")
3510         (if_then_else (eq_attr "is_thumb" "yes")
3511                       (const_int 14)
3512                       (const_int 12)))
3513    (set_attr "type" "multiple")]
3516 ; Reject the frame pointer in operand[1], since reloading this after
3517 ; it has been eliminated can cause carnage.
3518 (define_insn_and_split "*minmax_arithsi_non_canon"
3519   [(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts")
3520         (minus:SI
3521          (match_operand:SI 1 "s_register_operand" "0,?Ts")
3522           (match_operator:SI 4 "minmax_operator"
3523            [(match_operand:SI 2 "s_register_operand" "Ts,Ts")
3524             (match_operand:SI 3 "arm_rhs_operand" "TsI,TsI")])))
3525    (clobber (reg:CC CC_REGNUM))]
3526   "TARGET_32BIT && !arm_eliminable_register (operands[1])
3527    && !(arm_restrict_it && CONST_INT_P (operands[3]))"
3528   "#"
3529   "TARGET_32BIT && !arm_eliminable_register (operands[1]) && reload_completed"
3530   [(set (reg:CC CC_REGNUM)
3531         (compare:CC (match_dup 2) (match_dup 3)))
3533    (cond_exec (match_op_dup 4 [(reg:CC CC_REGNUM) (const_int 0)])
3534               (set (match_dup 0)
3535                    (minus:SI (match_dup 1)
3536                              (match_dup 2))))
3537    (cond_exec (match_op_dup 5 [(reg:CC CC_REGNUM) (const_int 0)])
3538               (set (match_dup 0)
3539                    (match_dup 6)))]
3540   {
3541   enum machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
3542                                            operands[2], operands[3]);
3543   enum rtx_code rc = minmax_code (operands[4]);
3544   operands[4] = gen_rtx_fmt_ee (rc, VOIDmode,
3545                                 operands[2], operands[3]);
3547   if (mode == CCFPmode || mode == CCFPEmode)
3548     rc = reverse_condition_maybe_unordered (rc);
3549   else
3550     rc = reverse_condition (rc);
3551   operands[5] = gen_rtx_fmt_ee (rc, SImode, operands[2], operands[3]);
3552   if (CONST_INT_P (operands[3]))
3553     operands[6] = plus_constant (SImode, operands[1], -INTVAL (operands[3]));
3554   else
3555     operands[6] = gen_rtx_MINUS (SImode, operands[1], operands[3]);
3556   }
3557   [(set_attr "conds" "clob")
3558    (set (attr "length")
3559         (if_then_else (eq_attr "is_thumb" "yes")
3560                       (const_int 14)
3561                       (const_int 12)))
3562    (set_attr "type" "multiple")]
3565 (define_code_iterator SAT [smin smax])
3566 (define_code_iterator SATrev [smin smax])
3567 (define_code_attr SATlo [(smin "1") (smax "2")])
3568 (define_code_attr SAThi [(smin "2") (smax "1")])
3570 (define_insn "*satsi_<SAT:code>"
3571   [(set (match_operand:SI 0 "s_register_operand" "=r")
3572         (SAT:SI (SATrev:SI (match_operand:SI 3 "s_register_operand" "r")
3573                            (match_operand:SI 1 "const_int_operand" "i"))
3574                 (match_operand:SI 2 "const_int_operand" "i")))]
3575   "TARGET_32BIT && arm_arch6 && <SAT:CODE> != <SATrev:CODE>
3576    && arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>], NULL, NULL)"
3578   int mask;
3579   bool signed_sat;
3580   if (!arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>],
3581                                &mask, &signed_sat))
3582     gcc_unreachable ();
3584   operands[1] = GEN_INT (mask);
3585   if (signed_sat)
3586     return "ssat%?\t%0, %1, %3";
3587   else
3588     return "usat%?\t%0, %1, %3";
3590   [(set_attr "predicable" "yes")
3591    (set_attr "predicable_short_it" "no")
3592    (set_attr "type" "alus_imm")]
3595 (define_insn "*satsi_<SAT:code>_shift"
3596   [(set (match_operand:SI 0 "s_register_operand" "=r")
3597         (SAT:SI (SATrev:SI (match_operator:SI 3 "sat_shift_operator"
3598                              [(match_operand:SI 4 "s_register_operand" "r")
3599                               (match_operand:SI 5 "const_int_operand" "i")])
3600                            (match_operand:SI 1 "const_int_operand" "i"))
3601                 (match_operand:SI 2 "const_int_operand" "i")))]
3602   "TARGET_32BIT && arm_arch6 && <SAT:CODE> != <SATrev:CODE>
3603    && arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>], NULL, NULL)"
3605   int mask;
3606   bool signed_sat;
3607   if (!arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>],
3608                                &mask, &signed_sat))
3609     gcc_unreachable ();
3611   operands[1] = GEN_INT (mask);
3612   if (signed_sat)
3613     return "ssat%?\t%0, %1, %4%S3";
3614   else
3615     return "usat%?\t%0, %1, %4%S3";
3617   [(set_attr "predicable" "yes")
3618    (set_attr "predicable_short_it" "no")
3619    (set_attr "shift" "3")
3620    (set_attr "type" "logic_shift_reg")])
3622 ;; Shift and rotation insns
3624 (define_expand "ashldi3"
3625   [(set (match_operand:DI            0 "s_register_operand" "")
3626         (ashift:DI (match_operand:DI 1 "s_register_operand" "")
3627                    (match_operand:SI 2 "general_operand" "")))]
3628   "TARGET_32BIT"
3629   "
3630   if (TARGET_NEON)
3631     {
3632       /* Delay the decision whether to use NEON or core-regs until
3633          register allocation.  */
3634       emit_insn (gen_ashldi3_neon (operands[0], operands[1], operands[2]));
3635       DONE;
3636     }
3637   else
3638     {
3639       /* Only the NEON case can handle in-memory shift counts.  */
3640       if (!reg_or_int_operand (operands[2], SImode))
3641         operands[2] = force_reg (SImode, operands[2]);
3642     }
3644   if (!CONST_INT_P (operands[2]) && TARGET_REALLY_IWMMXT)
3645     ; /* No special preparation statements; expand pattern as above.  */
3646   else
3647     {
3648       rtx scratch1, scratch2;
3650       if (CONST_INT_P (operands[2])
3651           && (HOST_WIDE_INT) INTVAL (operands[2]) == 1)
3652         {
3653           emit_insn (gen_arm_ashldi3_1bit (operands[0], operands[1]));
3654           DONE;
3655         }
3657       /* Ideally we should use iwmmxt here if we could know that operands[1]
3658          ends up already living in an iwmmxt register. Otherwise it's
3659          cheaper to have the alternate code being generated than moving
3660          values to iwmmxt regs and back.  */
3662       /* If we're optimizing for size, we prefer the libgcc calls.  */
3663       if (optimize_function_for_size_p (cfun))
3664         FAIL;
3666       /* Expand operation using core-registers.
3667          'FAIL' would achieve the same thing, but this is a bit smarter.  */
3668       scratch1 = gen_reg_rtx (SImode);
3669       scratch2 = gen_reg_rtx (SImode);
3670       arm_emit_coreregs_64bit_shift (ASHIFT, operands[0], operands[1],
3671                                      operands[2], scratch1, scratch2);
3672       DONE;
3673     }
3674   "
3677 (define_insn "arm_ashldi3_1bit"
3678   [(set (match_operand:DI            0 "s_register_operand" "=r,&r")
3679         (ashift:DI (match_operand:DI 1 "s_register_operand" "0,r")
3680                    (const_int 1)))
3681    (clobber (reg:CC CC_REGNUM))]
3682   "TARGET_32BIT"
3683   "movs\\t%Q0, %Q1, asl #1\;adc\\t%R0, %R1, %R1"
3684   [(set_attr "conds" "clob")
3685    (set_attr "length" "8")
3686    (set_attr "type" "multiple")]
3689 (define_expand "ashlsi3"
3690   [(set (match_operand:SI            0 "s_register_operand" "")
3691         (ashift:SI (match_operand:SI 1 "s_register_operand" "")
3692                    (match_operand:SI 2 "arm_rhs_operand" "")))]
3693   "TARGET_EITHER"
3694   "
3695   if (CONST_INT_P (operands[2])
3696       && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) > 31)
3697     {
3698       emit_insn (gen_movsi (operands[0], const0_rtx));
3699       DONE;
3700     }
3701   "
3704 (define_expand "ashrdi3"
3705   [(set (match_operand:DI              0 "s_register_operand" "")
3706         (ashiftrt:DI (match_operand:DI 1 "s_register_operand" "")
3707                      (match_operand:SI 2 "reg_or_int_operand" "")))]
3708   "TARGET_32BIT"
3709   "
3710   if (TARGET_NEON)
3711     {
3712       /* Delay the decision whether to use NEON or core-regs until
3713          register allocation.  */
3714       emit_insn (gen_ashrdi3_neon (operands[0], operands[1], operands[2]));
3715       DONE;
3716     }
3718   if (!CONST_INT_P (operands[2]) && TARGET_REALLY_IWMMXT)
3719     ; /* No special preparation statements; expand pattern as above.  */
3720   else
3721     {
3722       rtx scratch1, scratch2;
3724       if (CONST_INT_P (operands[2])
3725           && (HOST_WIDE_INT) INTVAL (operands[2]) == 1)
3726         {
3727           emit_insn (gen_arm_ashrdi3_1bit (operands[0], operands[1]));
3728           DONE;
3729         }
3731       /* Ideally we should use iwmmxt here if we could know that operands[1]
3732          ends up already living in an iwmmxt register. Otherwise it's
3733          cheaper to have the alternate code being generated than moving
3734          values to iwmmxt regs and back.  */
3736       /* If we're optimizing for size, we prefer the libgcc calls.  */
3737       if (optimize_function_for_size_p (cfun))
3738         FAIL;
3740       /* Expand operation using core-registers.
3741          'FAIL' would achieve the same thing, but this is a bit smarter.  */
3742       scratch1 = gen_reg_rtx (SImode);
3743       scratch2 = gen_reg_rtx (SImode);
3744       arm_emit_coreregs_64bit_shift (ASHIFTRT, operands[0], operands[1],
3745                                      operands[2], scratch1, scratch2);
3746       DONE;
3747     }
3748   "
3751 (define_insn "arm_ashrdi3_1bit"
3752   [(set (match_operand:DI              0 "s_register_operand" "=r,&r")
3753         (ashiftrt:DI (match_operand:DI 1 "s_register_operand" "0,r")
3754                      (const_int 1)))
3755    (clobber (reg:CC CC_REGNUM))]
3756   "TARGET_32BIT"
3757   "movs\\t%R0, %R1, asr #1\;mov\\t%Q0, %Q1, rrx"
3758   [(set_attr "conds" "clob")
3759    (set_attr "length" "8")
3760    (set_attr "type" "multiple")]
3763 (define_expand "ashrsi3"
3764   [(set (match_operand:SI              0 "s_register_operand" "")
3765         (ashiftrt:SI (match_operand:SI 1 "s_register_operand" "")
3766                      (match_operand:SI 2 "arm_rhs_operand" "")))]
3767   "TARGET_EITHER"
3768   "
3769   if (CONST_INT_P (operands[2])
3770       && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) > 31)
3771     operands[2] = GEN_INT (31);
3772   "
3775 (define_expand "lshrdi3"
3776   [(set (match_operand:DI              0 "s_register_operand" "")
3777         (lshiftrt:DI (match_operand:DI 1 "s_register_operand" "")
3778                      (match_operand:SI 2 "reg_or_int_operand" "")))]
3779   "TARGET_32BIT"
3780   "
3781   if (TARGET_NEON)
3782     {
3783       /* Delay the decision whether to use NEON or core-regs until
3784          register allocation.  */
3785       emit_insn (gen_lshrdi3_neon (operands[0], operands[1], operands[2]));
3786       DONE;
3787     }
3789   if (!CONST_INT_P (operands[2]) && TARGET_REALLY_IWMMXT)
3790     ; /* No special preparation statements; expand pattern as above.  */
3791   else
3792     {
3793       rtx scratch1, scratch2;
3795       if (CONST_INT_P (operands[2])
3796           && (HOST_WIDE_INT) INTVAL (operands[2]) == 1)
3797         {
3798           emit_insn (gen_arm_lshrdi3_1bit (operands[0], operands[1]));
3799           DONE;
3800         }
3802       /* Ideally we should use iwmmxt here if we could know that operands[1]
3803          ends up already living in an iwmmxt register. Otherwise it's
3804          cheaper to have the alternate code being generated than moving
3805          values to iwmmxt regs and back.  */
3807       /* If we're optimizing for size, we prefer the libgcc calls.  */
3808       if (optimize_function_for_size_p (cfun))
3809         FAIL;
3811       /* Expand operation using core-registers.
3812          'FAIL' would achieve the same thing, but this is a bit smarter.  */
3813       scratch1 = gen_reg_rtx (SImode);
3814       scratch2 = gen_reg_rtx (SImode);
3815       arm_emit_coreregs_64bit_shift (LSHIFTRT, operands[0], operands[1],
3816                                      operands[2], scratch1, scratch2);
3817       DONE;
3818     }
3819   "
3822 (define_insn "arm_lshrdi3_1bit"
3823   [(set (match_operand:DI              0 "s_register_operand" "=r,&r")
3824         (lshiftrt:DI (match_operand:DI 1 "s_register_operand" "0,r")
3825                      (const_int 1)))
3826    (clobber (reg:CC CC_REGNUM))]
3827   "TARGET_32BIT"
3828   "movs\\t%R0, %R1, lsr #1\;mov\\t%Q0, %Q1, rrx"
3829   [(set_attr "conds" "clob")
3830    (set_attr "length" "8")
3831    (set_attr "type" "multiple")]
3834 (define_expand "lshrsi3"
3835   [(set (match_operand:SI              0 "s_register_operand" "")
3836         (lshiftrt:SI (match_operand:SI 1 "s_register_operand" "")
3837                      (match_operand:SI 2 "arm_rhs_operand" "")))]
3838   "TARGET_EITHER"
3839   "
3840   if (CONST_INT_P (operands[2])
3841       && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) > 31)
3842     {
3843       emit_insn (gen_movsi (operands[0], const0_rtx));
3844       DONE;
3845     }
3846   "
3849 (define_expand "rotlsi3"
3850   [(set (match_operand:SI              0 "s_register_operand" "")
3851         (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
3852                      (match_operand:SI 2 "reg_or_int_operand" "")))]
3853   "TARGET_32BIT"
3854   "
3855   if (CONST_INT_P (operands[2]))
3856     operands[2] = GEN_INT ((32 - INTVAL (operands[2])) % 32);
3857   else
3858     {
3859       rtx reg = gen_reg_rtx (SImode);
3860       emit_insn (gen_subsi3 (reg, GEN_INT (32), operands[2]));
3861       operands[2] = reg;
3862     }
3863   "
3866 (define_expand "rotrsi3"
3867   [(set (match_operand:SI              0 "s_register_operand" "")
3868         (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
3869                      (match_operand:SI 2 "arm_rhs_operand" "")))]
3870   "TARGET_EITHER"
3871   "
3872   if (TARGET_32BIT)
3873     {
3874       if (CONST_INT_P (operands[2])
3875           && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) > 31)
3876         operands[2] = GEN_INT (INTVAL (operands[2]) % 32);
3877     }
3878   else /* TARGET_THUMB1 */
3879     {
3880       if (CONST_INT_P (operands [2]))
3881         operands [2] = force_reg (SImode, operands[2]);
3882     }
3883   "
3886 (define_insn "*arm_shiftsi3"
3887   [(set (match_operand:SI   0 "s_register_operand" "=l,l,r,r")
3888         (match_operator:SI  3 "shift_operator"
3889          [(match_operand:SI 1 "s_register_operand"  "0,l,r,r")
3890           (match_operand:SI 2 "reg_or_int_operand" "l,M,M,r")]))]
3891   "TARGET_32BIT"
3892   "* return arm_output_shift(operands, 0);"
3893   [(set_attr "predicable" "yes")
3894    (set_attr "arch" "t2,t2,*,*")
3895    (set_attr "predicable_short_it" "yes,yes,no,no")
3896    (set_attr "length" "4")
3897    (set_attr "shift" "1")
3898    (set_attr "type" "alu_shift_reg,alu_shift_imm,alu_shift_imm,alu_shift_reg")]
3901 (define_insn "*shiftsi3_compare0"
3902   [(set (reg:CC_NOOV CC_REGNUM)
3903         (compare:CC_NOOV (match_operator:SI 3 "shift_operator"
3904                           [(match_operand:SI 1 "s_register_operand" "r,r")
3905                            (match_operand:SI 2 "arm_rhs_operand" "M,r")])
3906                          (const_int 0)))
3907    (set (match_operand:SI 0 "s_register_operand" "=r,r")
3908         (match_op_dup 3 [(match_dup 1) (match_dup 2)]))]
3909   "TARGET_32BIT"
3910   "* return arm_output_shift(operands, 1);"
3911   [(set_attr "conds" "set")
3912    (set_attr "shift" "1")
3913    (set_attr "type" "alus_shift_imm,alus_shift_reg")]
3916 (define_insn "*shiftsi3_compare0_scratch"
3917   [(set (reg:CC_NOOV CC_REGNUM)
3918         (compare:CC_NOOV (match_operator:SI 3 "shift_operator"
3919                           [(match_operand:SI 1 "s_register_operand" "r,r")
3920                            (match_operand:SI 2 "arm_rhs_operand" "M,r")])
3921                          (const_int 0)))
3922    (clobber (match_scratch:SI 0 "=r,r"))]
3923   "TARGET_32BIT"
3924   "* return arm_output_shift(operands, 1);"
3925   [(set_attr "conds" "set")
3926    (set_attr "shift" "1")
3927    (set_attr "type" "shift_imm,shift_reg")]
3930 (define_insn "*not_shiftsi"
3931   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3932         (not:SI (match_operator:SI 3 "shift_operator"
3933                  [(match_operand:SI 1 "s_register_operand" "r,r")
3934                   (match_operand:SI 2 "shift_amount_operand" "M,rM")])))]
3935   "TARGET_32BIT"
3936   "mvn%?\\t%0, %1%S3"
3937   [(set_attr "predicable" "yes")
3938    (set_attr "predicable_short_it" "no")
3939    (set_attr "shift" "1")
3940    (set_attr "arch" "32,a")
3941    (set_attr "type" "mvn_shift,mvn_shift_reg")])
3943 (define_insn "*not_shiftsi_compare0"
3944   [(set (reg:CC_NOOV CC_REGNUM)
3945         (compare:CC_NOOV
3946          (not:SI (match_operator:SI 3 "shift_operator"
3947                   [(match_operand:SI 1 "s_register_operand" "r,r")
3948                    (match_operand:SI 2 "shift_amount_operand" "M,rM")]))
3949          (const_int 0)))
3950    (set (match_operand:SI 0 "s_register_operand" "=r,r")
3951         (not:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])))]
3952   "TARGET_32BIT"
3953   "mvn%.\\t%0, %1%S3"
3954   [(set_attr "conds" "set")
3955    (set_attr "shift" "1")
3956    (set_attr "arch" "32,a")
3957    (set_attr "type" "mvn_shift,mvn_shift_reg")])
3959 (define_insn "*not_shiftsi_compare0_scratch"
3960   [(set (reg:CC_NOOV CC_REGNUM)
3961         (compare:CC_NOOV
3962          (not:SI (match_operator:SI 3 "shift_operator"
3963                   [(match_operand:SI 1 "s_register_operand" "r,r")
3964                    (match_operand:SI 2 "shift_amount_operand" "M,rM")]))
3965          (const_int 0)))
3966    (clobber (match_scratch:SI 0 "=r,r"))]
3967   "TARGET_32BIT"
3968   "mvn%.\\t%0, %1%S3"
3969   [(set_attr "conds" "set")
3970    (set_attr "shift" "1")
3971    (set_attr "arch" "32,a")
3972    (set_attr "type" "mvn_shift,mvn_shift_reg")])
3974 ;; We don't really have extzv, but defining this using shifts helps
3975 ;; to reduce register pressure later on.
3977 (define_expand "extzv"
3978   [(set (match_operand 0 "s_register_operand" "")
3979         (zero_extract (match_operand 1 "nonimmediate_operand" "")
3980                       (match_operand 2 "const_int_operand" "")
3981                       (match_operand 3 "const_int_operand" "")))]
3982   "TARGET_THUMB1 || arm_arch_thumb2"
3983   "
3984   {
3985     HOST_WIDE_INT lshift = 32 - INTVAL (operands[2]) - INTVAL (operands[3]);
3986     HOST_WIDE_INT rshift = 32 - INTVAL (operands[2]);
3987     
3988     if (arm_arch_thumb2)
3989       {
3990         HOST_WIDE_INT width = INTVAL (operands[2]);
3991         HOST_WIDE_INT bitpos = INTVAL (operands[3]);
3993         if (unaligned_access && MEM_P (operands[1])
3994             && (width == 16 || width == 32) && (bitpos % BITS_PER_UNIT) == 0)
3995           {
3996             rtx base_addr;
3998             if (BYTES_BIG_ENDIAN)
3999               bitpos = GET_MODE_BITSIZE (GET_MODE (operands[0])) - width
4000                        - bitpos;
4002             if (width == 32)
4003               {
4004                 base_addr = adjust_address (operands[1], SImode,
4005                                             bitpos / BITS_PER_UNIT);
4006                 emit_insn (gen_unaligned_loadsi (operands[0], base_addr));
4007               }
4008             else
4009               {
4010                 rtx dest = operands[0];
4011                 rtx tmp = gen_reg_rtx (SImode);
4013                 /* We may get a paradoxical subreg here.  Strip it off.  */
4014                 if (GET_CODE (dest) == SUBREG
4015                     && GET_MODE (dest) == SImode
4016                     && GET_MODE (SUBREG_REG (dest)) == HImode)
4017                   dest = SUBREG_REG (dest);
4019                 if (GET_MODE_BITSIZE (GET_MODE (dest)) != width)
4020                   FAIL;
4022                 base_addr = adjust_address (operands[1], HImode,
4023                                             bitpos / BITS_PER_UNIT);
4024                 emit_insn (gen_unaligned_loadhiu (tmp, base_addr));
4025                 emit_move_insn (gen_lowpart (SImode, dest), tmp);
4026               }
4027             DONE;
4028           }
4029         else if (s_register_operand (operands[1], GET_MODE (operands[1])))
4030           {
4031             emit_insn (gen_extzv_t2 (operands[0], operands[1], operands[2],
4032                                      operands[3]));
4033             DONE;
4034           }
4035         else
4036           FAIL;
4037       }
4038     
4039     if (!s_register_operand (operands[1], GET_MODE (operands[1])))
4040       FAIL;
4042     operands[3] = GEN_INT (rshift);
4043     
4044     if (lshift == 0)
4045       {
4046         emit_insn (gen_lshrsi3 (operands[0], operands[1], operands[3]));
4047         DONE;
4048       }
4049       
4050     emit_insn (gen_extzv_t1 (operands[0], operands[1], GEN_INT (lshift),
4051                              operands[3], gen_reg_rtx (SImode)));
4052     DONE;
4053   }"
4056 ;; Helper for extzv, for the Thumb-1 register-shifts case.
4058 (define_expand "extzv_t1"
4059   [(set (match_operand:SI 4 "s_register_operand" "")
4060         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
4061                    (match_operand:SI 2 "const_int_operand" "")))
4062    (set (match_operand:SI 0 "s_register_operand" "")
4063         (lshiftrt:SI (match_dup 4)
4064                      (match_operand:SI 3 "const_int_operand" "")))]
4065   "TARGET_THUMB1"
4066   "")
4068 (define_expand "extv"
4069   [(set (match_operand 0 "s_register_operand" "")
4070         (sign_extract (match_operand 1 "nonimmediate_operand" "")
4071                       (match_operand 2 "const_int_operand" "")
4072                       (match_operand 3 "const_int_operand" "")))]
4073   "arm_arch_thumb2"
4075   HOST_WIDE_INT width = INTVAL (operands[2]);
4076   HOST_WIDE_INT bitpos = INTVAL (operands[3]);
4078   if (unaligned_access && MEM_P (operands[1]) && (width == 16 || width == 32)
4079       && (bitpos % BITS_PER_UNIT)  == 0)
4080     {
4081       rtx base_addr;
4082       
4083       if (BYTES_BIG_ENDIAN)
4084         bitpos = GET_MODE_BITSIZE (GET_MODE (operands[0])) - width - bitpos;
4085       
4086       if (width == 32)
4087         {
4088           base_addr = adjust_address (operands[1], SImode,
4089                                       bitpos / BITS_PER_UNIT);
4090           emit_insn (gen_unaligned_loadsi (operands[0], base_addr));
4091         }
4092       else
4093         {
4094           rtx dest = operands[0];
4095           rtx tmp = gen_reg_rtx (SImode);
4096           
4097           /* We may get a paradoxical subreg here.  Strip it off.  */
4098           if (GET_CODE (dest) == SUBREG
4099               && GET_MODE (dest) == SImode
4100               && GET_MODE (SUBREG_REG (dest)) == HImode)
4101             dest = SUBREG_REG (dest);
4102           
4103           if (GET_MODE_BITSIZE (GET_MODE (dest)) != width)
4104             FAIL;
4105           
4106           base_addr = adjust_address (operands[1], HImode,
4107                                       bitpos / BITS_PER_UNIT);
4108           emit_insn (gen_unaligned_loadhis (tmp, base_addr));
4109           emit_move_insn (gen_lowpart (SImode, dest), tmp);
4110         }
4112       DONE;
4113     }
4114   else if (!s_register_operand (operands[1], GET_MODE (operands[1])))
4115     FAIL;
4116   else if (GET_MODE (operands[0]) == SImode
4117            && GET_MODE (operands[1]) == SImode)
4118     {
4119       emit_insn (gen_extv_regsi (operands[0], operands[1], operands[2],
4120                                  operands[3]));
4121       DONE;
4122     }
4124   FAIL;
4127 ; Helper to expand register forms of extv with the proper modes.
4129 (define_expand "extv_regsi"
4130   [(set (match_operand:SI 0 "s_register_operand" "")
4131         (sign_extract:SI (match_operand:SI 1 "s_register_operand" "")
4132                          (match_operand 2 "const_int_operand" "")
4133                          (match_operand 3 "const_int_operand" "")))]
4134   ""
4138 ; ARMv6+ unaligned load/store instructions (used for packed structure accesses).
4140 (define_insn "unaligned_loadsi"
4141   [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4142         (unspec:SI [(match_operand:SI 1 "memory_operand" "Uw,m")]
4143                    UNSPEC_UNALIGNED_LOAD))]
4144   "unaligned_access && TARGET_32BIT"
4145   "ldr%?\t%0, %1\t@ unaligned"
4146   [(set_attr "arch" "t2,any")
4147    (set_attr "length" "2,4")
4148    (set_attr "predicable" "yes")
4149    (set_attr "predicable_short_it" "yes,no")
4150    (set_attr "type" "load1")])
4152 (define_insn "unaligned_loadhis"
4153   [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4154         (sign_extend:SI
4155           (unspec:HI [(match_operand:HI 1 "memory_operand" "Uw,Uh")]
4156                      UNSPEC_UNALIGNED_LOAD)))]
4157   "unaligned_access && TARGET_32BIT"
4158   "ldr%(sh%)\t%0, %1\t@ unaligned"
4159   [(set_attr "arch" "t2,any")
4160    (set_attr "length" "2,4")
4161    (set_attr "predicable" "yes")
4162    (set_attr "predicable_short_it" "yes,no")
4163    (set_attr "type" "load_byte")])
4165 (define_insn "unaligned_loadhiu"
4166   [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4167         (zero_extend:SI
4168           (unspec:HI [(match_operand:HI 1 "memory_operand" "Uw,m")]
4169                      UNSPEC_UNALIGNED_LOAD)))]
4170   "unaligned_access && TARGET_32BIT"
4171   "ldr%(h%)\t%0, %1\t@ unaligned"
4172   [(set_attr "arch" "t2,any")
4173    (set_attr "length" "2,4")
4174    (set_attr "predicable" "yes")
4175    (set_attr "predicable_short_it" "yes,no")
4176    (set_attr "type" "load_byte")])
4178 (define_insn "unaligned_storesi"
4179   [(set (match_operand:SI 0 "memory_operand" "=Uw,m")
4180         (unspec:SI [(match_operand:SI 1 "s_register_operand" "l,r")]
4181                    UNSPEC_UNALIGNED_STORE))]
4182   "unaligned_access && TARGET_32BIT"
4183   "str%?\t%1, %0\t@ unaligned"
4184   [(set_attr "arch" "t2,any")
4185    (set_attr "length" "2,4")
4186    (set_attr "predicable" "yes")
4187    (set_attr "predicable_short_it" "yes,no")
4188    (set_attr "type" "store1")])
4190 (define_insn "unaligned_storehi"
4191   [(set (match_operand:HI 0 "memory_operand" "=Uw,m")
4192         (unspec:HI [(match_operand:HI 1 "s_register_operand" "l,r")]
4193                    UNSPEC_UNALIGNED_STORE))]
4194   "unaligned_access && TARGET_32BIT"
4195   "str%(h%)\t%1, %0\t@ unaligned"
4196   [(set_attr "arch" "t2,any")
4197    (set_attr "length" "2,4")
4198    (set_attr "predicable" "yes")
4199    (set_attr "predicable_short_it" "yes,no")
4200    (set_attr "type" "store1")])
4202 ;; Unaligned double-word load and store.
4203 ;; Split after reload into two unaligned single-word accesses.
4204 ;; It prevents lower_subreg from splitting some other aligned
4205 ;; double-word accesses too early. Used for internal memcpy.
4207 (define_insn_and_split "unaligned_loaddi"
4208   [(set (match_operand:DI 0 "s_register_operand" "=l,r")
4209         (unspec:DI [(match_operand:DI 1 "memory_operand" "o,o")]
4210                    UNSPEC_UNALIGNED_LOAD))]
4211   "unaligned_access && TARGET_32BIT"
4212   "#"
4213   "&& reload_completed"
4214   [(set (match_dup 0) (unspec:SI [(match_dup 1)] UNSPEC_UNALIGNED_LOAD))
4215    (set (match_dup 2) (unspec:SI [(match_dup 3)] UNSPEC_UNALIGNED_LOAD))]
4216   {
4217     operands[2] = gen_highpart (SImode, operands[0]);
4218     operands[0] = gen_lowpart (SImode, operands[0]);
4219     operands[3] = gen_highpart (SImode, operands[1]);
4220     operands[1] = gen_lowpart (SImode, operands[1]);
4222     /* If the first destination register overlaps with the base address,
4223        swap the order in which the loads are emitted.  */
4224     if (reg_overlap_mentioned_p (operands[0], operands[1]))
4225       {
4226         rtx tmp = operands[1];
4227         operands[1] = operands[3];
4228         operands[3] = tmp;
4229         tmp = operands[0];
4230         operands[0] = operands[2];
4231         operands[2] = tmp;
4232       }
4233   }
4234   [(set_attr "arch" "t2,any")
4235    (set_attr "length" "4,8")
4236    (set_attr "predicable" "yes")
4237    (set_attr "type" "load2")])
4239 (define_insn_and_split "unaligned_storedi"
4240   [(set (match_operand:DI 0 "memory_operand" "=o,o")
4241         (unspec:DI [(match_operand:DI 1 "s_register_operand" "l,r")]
4242                    UNSPEC_UNALIGNED_STORE))]
4243   "unaligned_access && TARGET_32BIT"
4244   "#"
4245   "&& reload_completed"
4246   [(set (match_dup 0) (unspec:SI [(match_dup 1)] UNSPEC_UNALIGNED_STORE))
4247    (set (match_dup 2) (unspec:SI [(match_dup 3)] UNSPEC_UNALIGNED_STORE))]
4248   {
4249     operands[2] = gen_highpart (SImode, operands[0]);
4250     operands[0] = gen_lowpart (SImode, operands[0]);
4251     operands[3] = gen_highpart (SImode, operands[1]);
4252     operands[1] = gen_lowpart (SImode, operands[1]);
4253   }
4254   [(set_attr "arch" "t2,any")
4255    (set_attr "length" "4,8")
4256    (set_attr "predicable" "yes")
4257    (set_attr "type" "store2")])
4260 (define_insn "*extv_reg"
4261   [(set (match_operand:SI 0 "s_register_operand" "=r")
4262         (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
4263                          (match_operand:SI 2 "const_int_M_operand" "M")
4264                          (match_operand:SI 3 "const_int_M_operand" "M")))]
4265   "arm_arch_thumb2"
4266   "sbfx%?\t%0, %1, %3, %2"
4267   [(set_attr "length" "4")
4268    (set_attr "predicable" "yes")
4269    (set_attr "predicable_short_it" "no")
4270    (set_attr "type" "bfm")]
4273 (define_insn "extzv_t2"
4274   [(set (match_operand:SI 0 "s_register_operand" "=r")
4275         (zero_extract:SI (match_operand:SI 1 "s_register_operand" "r")
4276                          (match_operand:SI 2 "const_int_M_operand" "M")
4277                          (match_operand:SI 3 "const_int_M_operand" "M")))]
4278   "arm_arch_thumb2"
4279   "ubfx%?\t%0, %1, %3, %2"
4280   [(set_attr "length" "4")
4281    (set_attr "predicable" "yes")
4282    (set_attr "predicable_short_it" "no")
4283    (set_attr "type" "bfm")]
4287 ;; Division instructions
4288 (define_insn "divsi3"
4289   [(set (match_operand:SI         0 "s_register_operand" "=r")
4290         (div:SI (match_operand:SI 1 "s_register_operand"  "r")
4291                 (match_operand:SI 2 "s_register_operand"  "r")))]
4292   "TARGET_IDIV"
4293   "sdiv%?\t%0, %1, %2"
4294   [(set_attr "predicable" "yes")
4295    (set_attr "predicable_short_it" "no")
4296    (set_attr "type" "sdiv")]
4299 (define_insn "udivsi3"
4300   [(set (match_operand:SI          0 "s_register_operand" "=r")
4301         (udiv:SI (match_operand:SI 1 "s_register_operand"  "r")
4302                  (match_operand:SI 2 "s_register_operand"  "r")))]
4303   "TARGET_IDIV"
4304   "udiv%?\t%0, %1, %2"
4305   [(set_attr "predicable" "yes")
4306    (set_attr "predicable_short_it" "no")
4307    (set_attr "type" "udiv")]
4311 ;; Unary arithmetic insns
4313 (define_expand "negdi2"
4314  [(parallel
4315    [(set (match_operand:DI 0 "s_register_operand" "")
4316          (neg:DI (match_operand:DI 1 "s_register_operand" "")))
4317     (clobber (reg:CC CC_REGNUM))])]
4318   "TARGET_EITHER"
4319   {
4320     if (TARGET_NEON)
4321       {
4322         emit_insn (gen_negdi2_neon (operands[0], operands[1]));
4323         DONE;
4324       }
4325   }
4328 ;; The constraints here are to prevent a *partial* overlap (where %Q0 == %R1).
4329 ;; The first alternative allows the common case of a *full* overlap.
4330 (define_insn_and_split "*arm_negdi2"
4331   [(set (match_operand:DI         0 "s_register_operand" "=r,&r")
4332         (neg:DI (match_operand:DI 1 "s_register_operand"  "0,r")))
4333    (clobber (reg:CC CC_REGNUM))]
4334   "TARGET_ARM"
4335   "#"   ; "rsbs\\t%Q0, %Q1, #0\;rsc\\t%R0, %R1, #0"
4336   "&& reload_completed"
4337   [(parallel [(set (reg:CC CC_REGNUM)
4338                    (compare:CC (const_int 0) (match_dup 1)))
4339               (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1)))])
4340    (set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3))
4341                                 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
4342   {
4343     operands[2] = gen_highpart (SImode, operands[0]);
4344     operands[0] = gen_lowpart (SImode, operands[0]);
4345     operands[3] = gen_highpart (SImode, operands[1]);
4346     operands[1] = gen_lowpart (SImode, operands[1]);
4347   }
4348   [(set_attr "conds" "clob")
4349    (set_attr "length" "8")
4350    (set_attr "type" "multiple")]
4353 (define_expand "negsi2"
4354   [(set (match_operand:SI         0 "s_register_operand" "")
4355         (neg:SI (match_operand:SI 1 "s_register_operand" "")))]
4356   "TARGET_EITHER"
4357   ""
4360 (define_insn "*arm_negsi2"
4361   [(set (match_operand:SI         0 "s_register_operand" "=l,r")
4362         (neg:SI (match_operand:SI 1 "s_register_operand" "l,r")))]
4363   "TARGET_32BIT"
4364   "rsb%?\\t%0, %1, #0"
4365   [(set_attr "predicable" "yes")
4366    (set_attr "predicable_short_it" "yes,no")
4367    (set_attr "arch" "t2,*")
4368    (set_attr "length" "4")
4369    (set_attr "type" "alu_sreg")]
4372 (define_expand "negsf2"
4373   [(set (match_operand:SF         0 "s_register_operand" "")
4374         (neg:SF (match_operand:SF 1 "s_register_operand" "")))]
4375   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
4376   ""
4379 (define_expand "negdf2"
4380   [(set (match_operand:DF         0 "s_register_operand" "")
4381         (neg:DF (match_operand:DF 1 "s_register_operand" "")))]
4382   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
4383   "")
4385 (define_insn_and_split "*zextendsidi_negsi"
4386   [(set (match_operand:DI 0 "s_register_operand" "=r")
4387         (zero_extend:DI (neg:SI (match_operand:SI 1 "s_register_operand" "r"))))]
4388    "TARGET_32BIT"
4389    "#"
4390    ""
4391    [(set (match_dup 2)
4392          (neg:SI (match_dup 1)))
4393     (set (match_dup 3)
4394          (const_int 0))]
4395    {
4396       operands[2] = gen_lowpart (SImode, operands[0]);
4397       operands[3] = gen_highpart (SImode, operands[0]);
4398    }
4399  [(set_attr "length" "8")
4400   (set_attr "type" "multiple")]
4403 ;; Negate an extended 32-bit value.
4404 (define_insn_and_split "*negdi_extendsidi"
4405   [(set (match_operand:DI 0 "s_register_operand" "=l,r")
4406         (neg:DI (sign_extend:DI
4407                  (match_operand:SI 1 "s_register_operand" "l,r"))))
4408    (clobber (reg:CC CC_REGNUM))]
4409   "TARGET_32BIT"
4410   "#"
4411   "&& reload_completed"
4412   [(const_int 0)]
4413   {
4414     rtx low = gen_lowpart (SImode, operands[0]);
4415     rtx high = gen_highpart (SImode, operands[0]);
4417     if (reg_overlap_mentioned_p (low, operands[1]))
4418       {
4419         /* Input overlaps the low word of the output.  Use:
4420                 asr     Rhi, Rin, #31
4421                 rsbs    Rlo, Rin, #0
4422                 rsc     Rhi, Rhi, #0 (thumb2: sbc Rhi, Rhi, Rhi, lsl #1).  */
4423         rtx cc_reg = gen_rtx_REG (CC_Cmode, CC_REGNUM);
4425         emit_insn (gen_rtx_SET (VOIDmode, high,
4426                                 gen_rtx_ASHIFTRT (SImode, operands[1],
4427                                                   GEN_INT (31))));
4429         emit_insn (gen_subsi3_compare (low, const0_rtx, operands[1]));
4430         if (TARGET_ARM)
4431           emit_insn (gen_rtx_SET (VOIDmode, high,
4432                                   gen_rtx_MINUS (SImode,
4433                                                  gen_rtx_MINUS (SImode,
4434                                                                 const0_rtx,
4435                                                                 high),
4436                                                  gen_rtx_LTU (SImode,
4437                                                               cc_reg,
4438                                                               const0_rtx))));
4439         else
4440           {
4441             rtx two_x = gen_rtx_ASHIFT (SImode, high, GEN_INT (1));
4442             emit_insn (gen_rtx_SET (VOIDmode, high,
4443                                     gen_rtx_MINUS (SImode,
4444                                                    gen_rtx_MINUS (SImode,
4445                                                                   high,
4446                                                                   two_x),
4447                                                    gen_rtx_LTU (SImode,
4448                                                                 cc_reg,
4449                                                                 const0_rtx))));
4450           }
4451       }
4452     else
4453       {
4454         /* No overlap, or overlap on high word.  Use:
4455                 rsb     Rlo, Rin, #0
4456                 bic     Rhi, Rlo, Rin
4457                 asr     Rhi, Rhi, #31
4458            Flags not needed for this sequence.  */
4459         emit_insn (gen_rtx_SET (VOIDmode, low,
4460                                 gen_rtx_NEG (SImode, operands[1])));
4461         emit_insn (gen_rtx_SET (VOIDmode, high,
4462                                 gen_rtx_AND (SImode,
4463                                              gen_rtx_NOT (SImode, operands[1]),
4464                                              low)));
4465         emit_insn (gen_rtx_SET (VOIDmode, high,
4466                                 gen_rtx_ASHIFTRT (SImode, high,
4467                                                   GEN_INT (31))));
4468       }
4469     DONE;
4470   }
4471   [(set_attr "length" "12")
4472    (set_attr "arch" "t2,*")
4473    (set_attr "type" "multiple")]
4476 (define_insn_and_split "*negdi_zero_extendsidi"
4477   [(set (match_operand:DI 0 "s_register_operand" "=r,&r")
4478         (neg:DI (zero_extend:DI (match_operand:SI 1 "s_register_operand" "0,r"))))
4479    (clobber (reg:CC CC_REGNUM))]
4480   "TARGET_32BIT"
4481   "#" ; "rsbs\\t%Q0, %1, #0\;sbc\\t%R0,%R0,%R0"
4482       ;; Don't care what register is input to sbc,
4483       ;; since we just just need to propagate the carry.
4484   "&& reload_completed"
4485   [(parallel [(set (reg:CC CC_REGNUM)
4486                    (compare:CC (const_int 0) (match_dup 1)))
4487               (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1)))])
4488    (set (match_dup 2) (minus:SI (minus:SI (match_dup 2) (match_dup 2))
4489                                 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
4490   {
4491     operands[2] = gen_highpart (SImode, operands[0]);
4492     operands[0] = gen_lowpart (SImode, operands[0]);
4493   }
4494   [(set_attr "conds" "clob")
4495    (set_attr "length" "8")
4496    (set_attr "type" "multiple")]   ;; length in thumb is 4
4499 ;; abssi2 doesn't really clobber the condition codes if a different register
4500 ;; is being set.  To keep things simple, assume during rtl manipulations that
4501 ;; it does, but tell the final scan operator the truth.  Similarly for
4502 ;; (neg (abs...))
4504 (define_expand "abssi2"
4505   [(parallel
4506     [(set (match_operand:SI         0 "s_register_operand" "")
4507           (abs:SI (match_operand:SI 1 "s_register_operand" "")))
4508      (clobber (match_dup 2))])]
4509   "TARGET_EITHER"
4510   "
4511   if (TARGET_THUMB1)
4512     operands[2] = gen_rtx_SCRATCH (SImode);
4513   else
4514     operands[2] = gen_rtx_REG (CCmode, CC_REGNUM);
4517 (define_insn_and_split "*arm_abssi2"
4518   [(set (match_operand:SI 0 "s_register_operand" "=r,&r")
4519         (abs:SI (match_operand:SI 1 "s_register_operand" "0,r")))
4520    (clobber (reg:CC CC_REGNUM))]
4521   "TARGET_ARM"
4522   "#"
4523   "&& reload_completed"
4524   [(const_int 0)]
4525   {
4526    /* if (which_alternative == 0) */
4527    if (REGNO(operands[0]) == REGNO(operands[1]))
4528      {
4529       /* Emit the pattern:
4530          cmp\\t%0, #0\;rsblt\\t%0, %0, #0
4531          [(set (reg:CC CC_REGNUM)
4532                (compare:CC (match_dup 0) (const_int 0)))
4533           (cond_exec (lt:CC (reg:CC CC_REGNUM) (const_int 0))
4534                      (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1))))]
4535       */
4536       emit_insn (gen_rtx_SET (VOIDmode,
4537                               gen_rtx_REG (CCmode, CC_REGNUM),
4538                               gen_rtx_COMPARE (CCmode, operands[0], const0_rtx)));
4539       emit_insn (gen_rtx_COND_EXEC (VOIDmode,
4540                                     (gen_rtx_LT (SImode,
4541                                                  gen_rtx_REG (CCmode, CC_REGNUM),
4542                                                  const0_rtx)),
4543                                     (gen_rtx_SET (VOIDmode,
4544                                                   operands[0],
4545                                                   (gen_rtx_MINUS (SImode,
4546                                                                   const0_rtx,
4547                                                                   operands[1]))))));
4548       DONE;
4549      }
4550    else
4551      {
4552       /* Emit the pattern:
4553          alt1: eor%?\\t%0, %1, %1, asr #31\;sub%?\\t%0, %0, %1, asr #31
4554          [(set (match_dup 0)
4555                (xor:SI (match_dup 1)
4556                        (ashiftrt:SI (match_dup 1) (const_int 31))))
4557           (set (match_dup 0)
4558                (minus:SI (match_dup 0)
4559                       (ashiftrt:SI (match_dup 1) (const_int 31))))]
4560       */
4561       emit_insn (gen_rtx_SET (VOIDmode,
4562                               operands[0],
4563                               gen_rtx_XOR (SImode,
4564                                            gen_rtx_ASHIFTRT (SImode,
4565                                                              operands[1],
4566                                                              GEN_INT (31)),
4567                                            operands[1])));
4568       emit_insn (gen_rtx_SET (VOIDmode,
4569                               operands[0],
4570                               gen_rtx_MINUS (SImode,
4571                                              operands[0],
4572                                              gen_rtx_ASHIFTRT (SImode,
4573                                                                operands[1],
4574                                                                GEN_INT (31)))));
4575       DONE;
4576      }
4577   }
4578   [(set_attr "conds" "clob,*")
4579    (set_attr "shift" "1")
4580    (set_attr "predicable" "no, yes")
4581    (set_attr "length" "8")
4582    (set_attr "type" "multiple")]
4585 (define_insn_and_split "*arm_neg_abssi2"
4586   [(set (match_operand:SI 0 "s_register_operand" "=r,&r")
4587         (neg:SI (abs:SI (match_operand:SI 1 "s_register_operand" "0,r"))))
4588    (clobber (reg:CC CC_REGNUM))]
4589   "TARGET_ARM"
4590   "#"
4591   "&& reload_completed"
4592   [(const_int 0)]
4593   {
4594    /* if (which_alternative == 0) */
4595    if (REGNO (operands[0]) == REGNO (operands[1]))
4596      {
4597       /* Emit the pattern:
4598          cmp\\t%0, #0\;rsbgt\\t%0, %0, #0
4599       */
4600       emit_insn (gen_rtx_SET (VOIDmode,
4601                               gen_rtx_REG (CCmode, CC_REGNUM),
4602                               gen_rtx_COMPARE (CCmode, operands[0], const0_rtx)));
4603       emit_insn (gen_rtx_COND_EXEC (VOIDmode,
4604                                     gen_rtx_GT (SImode,
4605                                                 gen_rtx_REG (CCmode, CC_REGNUM),
4606                                                 const0_rtx),
4607                                     gen_rtx_SET (VOIDmode,
4608                                                  operands[0],
4609                                                  (gen_rtx_MINUS (SImode,
4610                                                                  const0_rtx,
4611                                                                  operands[1])))));
4612      }
4613    else
4614      {
4615       /* Emit the pattern:
4616          eor%?\\t%0, %1, %1, asr #31\;rsb%?\\t%0, %0, %1, asr #31
4617       */
4618       emit_insn (gen_rtx_SET (VOIDmode,
4619                               operands[0],
4620                               gen_rtx_XOR (SImode,
4621                                            gen_rtx_ASHIFTRT (SImode,
4622                                                              operands[1],
4623                                                              GEN_INT (31)),
4624                                            operands[1])));
4625       emit_insn (gen_rtx_SET (VOIDmode,
4626                               operands[0],
4627                               gen_rtx_MINUS (SImode,
4628                                              gen_rtx_ASHIFTRT (SImode,
4629                                                                operands[1],
4630                                                                GEN_INT (31)),
4631                                              operands[0])));
4632      }
4633    DONE;
4634   }
4635   [(set_attr "conds" "clob,*")
4636    (set_attr "shift" "1")
4637    (set_attr "predicable" "no, yes")
4638    (set_attr "length" "8")
4639    (set_attr "type" "multiple")]
4642 (define_expand "abssf2"
4643   [(set (match_operand:SF         0 "s_register_operand" "")
4644         (abs:SF (match_operand:SF 1 "s_register_operand" "")))]
4645   "TARGET_32BIT && TARGET_HARD_FLOAT"
4646   "")
4648 (define_expand "absdf2"
4649   [(set (match_operand:DF         0 "s_register_operand" "")
4650         (abs:DF (match_operand:DF 1 "s_register_operand" "")))]
4651   "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
4652   "")
4654 (define_expand "sqrtsf2"
4655   [(set (match_operand:SF 0 "s_register_operand" "")
4656         (sqrt:SF (match_operand:SF 1 "s_register_operand" "")))]
4657   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
4658   "")
4660 (define_expand "sqrtdf2"
4661   [(set (match_operand:DF 0 "s_register_operand" "")
4662         (sqrt:DF (match_operand:DF 1 "s_register_operand" "")))]
4663   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
4664   "")
4666 (define_insn_and_split "one_cmpldi2"
4667   [(set (match_operand:DI 0 "s_register_operand"         "=w,&r,&r,?w")
4668         (not:DI (match_operand:DI 1 "s_register_operand" " w, 0, r, w")))]
4669   "TARGET_32BIT"
4670   "@
4671    vmvn\t%P0, %P1
4672    #
4673    #
4674    vmvn\t%P0, %P1"
4675   "TARGET_32BIT && reload_completed
4676    && arm_general_register_operand (operands[0], DImode)"
4677   [(set (match_dup 0) (not:SI (match_dup 1)))
4678    (set (match_dup 2) (not:SI (match_dup 3)))]
4679   "
4680   {
4681     operands[2] = gen_highpart (SImode, operands[0]);
4682     operands[0] = gen_lowpart (SImode, operands[0]);
4683     operands[3] = gen_highpart (SImode, operands[1]);
4684     operands[1] = gen_lowpart (SImode, operands[1]);
4685   }"
4686   [(set_attr "length" "*,8,8,*")
4687    (set_attr "predicable" "no,yes,yes,no")
4688    (set_attr "type" "neon_move,multiple,multiple,neon_move")
4689    (set_attr "arch" "neon_for_64bits,*,*,avoid_neon_for_64bits")]
4692 (define_expand "one_cmplsi2"
4693   [(set (match_operand:SI         0 "s_register_operand" "")
4694         (not:SI (match_operand:SI 1 "s_register_operand" "")))]
4695   "TARGET_EITHER"
4696   ""
4699 (define_insn "*arm_one_cmplsi2"
4700   [(set (match_operand:SI         0 "s_register_operand" "=l,r")
4701         (not:SI (match_operand:SI 1 "s_register_operand"  "l,r")))]
4702   "TARGET_32BIT"
4703   "mvn%?\\t%0, %1"
4704   [(set_attr "predicable" "yes")
4705    (set_attr "predicable_short_it" "yes,no")
4706    (set_attr "arch" "t2,*")
4707    (set_attr "length" "4")
4708    (set_attr "type" "mvn_reg")]
4711 (define_insn "*notsi_compare0"
4712   [(set (reg:CC_NOOV CC_REGNUM)
4713         (compare:CC_NOOV (not:SI (match_operand:SI 1 "s_register_operand" "r"))
4714                          (const_int 0)))
4715    (set (match_operand:SI 0 "s_register_operand" "=r")
4716         (not:SI (match_dup 1)))]
4717   "TARGET_32BIT"
4718   "mvn%.\\t%0, %1"
4719   [(set_attr "conds" "set")
4720    (set_attr "type" "mvn_reg")]
4723 (define_insn "*notsi_compare0_scratch"
4724   [(set (reg:CC_NOOV CC_REGNUM)
4725         (compare:CC_NOOV (not:SI (match_operand:SI 1 "s_register_operand" "r"))
4726                          (const_int 0)))
4727    (clobber (match_scratch:SI 0 "=r"))]
4728   "TARGET_32BIT"
4729   "mvn%.\\t%0, %1"
4730   [(set_attr "conds" "set")
4731    (set_attr "type" "mvn_reg")]
4734 ;; Fixed <--> Floating conversion insns
4736 (define_expand "floatsihf2"
4737   [(set (match_operand:HF           0 "general_operand" "")
4738         (float:HF (match_operand:SI 1 "general_operand" "")))]
4739   "TARGET_EITHER"
4740   "
4741   {
4742     rtx op1 = gen_reg_rtx (SFmode);
4743     expand_float (op1, operands[1], 0);
4744     op1 = convert_to_mode (HFmode, op1, 0);
4745     emit_move_insn (operands[0], op1);
4746     DONE;
4747   }"
4750 (define_expand "floatdihf2"
4751   [(set (match_operand:HF           0 "general_operand" "")
4752         (float:HF (match_operand:DI 1 "general_operand" "")))]
4753   "TARGET_EITHER"
4754   "
4755   {
4756     rtx op1 = gen_reg_rtx (SFmode);
4757     expand_float (op1, operands[1], 0);
4758     op1 = convert_to_mode (HFmode, op1, 0);
4759     emit_move_insn (operands[0], op1);
4760     DONE;
4761   }"
4764 (define_expand "floatsisf2"
4765   [(set (match_operand:SF           0 "s_register_operand" "")
4766         (float:SF (match_operand:SI 1 "s_register_operand" "")))]
4767   "TARGET_32BIT && TARGET_HARD_FLOAT"
4768   "
4771 (define_expand "floatsidf2"
4772   [(set (match_operand:DF           0 "s_register_operand" "")
4773         (float:DF (match_operand:SI 1 "s_register_operand" "")))]
4774   "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
4775   "
4778 (define_expand "fix_trunchfsi2"
4779   [(set (match_operand:SI         0 "general_operand" "")
4780         (fix:SI (fix:HF (match_operand:HF 1 "general_operand"  ""))))]
4781   "TARGET_EITHER"
4782   "
4783   {
4784     rtx op1 = convert_to_mode (SFmode, operands[1], 0);
4785     expand_fix (operands[0], op1, 0);
4786     DONE;
4787   }"
4790 (define_expand "fix_trunchfdi2"
4791   [(set (match_operand:DI         0 "general_operand" "")
4792         (fix:DI (fix:HF (match_operand:HF 1 "general_operand"  ""))))]
4793   "TARGET_EITHER"
4794   "
4795   {
4796     rtx op1 = convert_to_mode (SFmode, operands[1], 0);
4797     expand_fix (operands[0], op1, 0);
4798     DONE;
4799   }"
4802 (define_expand "fix_truncsfsi2"
4803   [(set (match_operand:SI         0 "s_register_operand" "")
4804         (fix:SI (fix:SF (match_operand:SF 1 "s_register_operand"  ""))))]
4805   "TARGET_32BIT && TARGET_HARD_FLOAT"
4806   "
4809 (define_expand "fix_truncdfsi2"
4810   [(set (match_operand:SI         0 "s_register_operand" "")
4811         (fix:SI (fix:DF (match_operand:DF 1 "s_register_operand"  ""))))]
4812   "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
4813   "
4816 ;; Truncation insns
4818 (define_expand "truncdfsf2"
4819   [(set (match_operand:SF  0 "s_register_operand" "")
4820         (float_truncate:SF
4821          (match_operand:DF 1 "s_register_operand" "")))]
4822   "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
4823   ""
4826 /* DFmode -> HFmode conversions have to go through SFmode.  */
4827 (define_expand "truncdfhf2"
4828   [(set (match_operand:HF  0 "general_operand" "")
4829         (float_truncate:HF
4830          (match_operand:DF 1 "general_operand" "")))]
4831   "TARGET_EITHER"
4832   "
4833   {
4834     rtx op1;
4835     op1 = convert_to_mode (SFmode, operands[1], 0);
4836     op1 = convert_to_mode (HFmode, op1, 0);
4837     emit_move_insn (operands[0], op1);
4838     DONE;
4839   }"
4842 ;; Zero and sign extension instructions.
4844 (define_insn "zero_extend<mode>di2"
4845   [(set (match_operand:DI 0 "s_register_operand" "=w,r,?r,w")
4846         (zero_extend:DI (match_operand:QHSI 1 "<qhs_zextenddi_op>"
4847                                             "<qhs_zextenddi_cstr>")))]
4848   "TARGET_32BIT <qhs_zextenddi_cond>"
4849   "#"
4850   [(set_attr "length" "8,4,8,8")
4851    (set_attr "arch" "neon_for_64bits,*,*,avoid_neon_for_64bits")
4852    (set_attr "ce_count" "2")
4853    (set_attr "predicable" "yes")
4854    (set_attr "type" "multiple,mov_reg,multiple,multiple")]
4857 (define_insn "extend<mode>di2"
4858   [(set (match_operand:DI 0 "s_register_operand" "=w,r,?r,?r,w")
4859         (sign_extend:DI (match_operand:QHSI 1 "<qhs_extenddi_op>"
4860                                             "<qhs_extenddi_cstr>")))]
4861   "TARGET_32BIT <qhs_sextenddi_cond>"
4862   "#"
4863   [(set_attr "length" "8,4,8,8,8")
4864    (set_attr "ce_count" "2")
4865    (set_attr "shift" "1")
4866    (set_attr "predicable" "yes")
4867    (set_attr "arch" "neon_for_64bits,*,a,t,avoid_neon_for_64bits")
4868    (set_attr "type" "multiple,mov_reg,multiple,multiple,multiple")]
4871 ;; Splits for all extensions to DImode
4872 (define_split
4873   [(set (match_operand:DI 0 "s_register_operand" "")
4874         (zero_extend:DI (match_operand 1 "nonimmediate_operand" "")))]
4875   "TARGET_32BIT && reload_completed && !IS_VFP_REGNUM (REGNO (operands[0]))"
4876   [(set (match_dup 0) (match_dup 1))]
4878   rtx lo_part = gen_lowpart (SImode, operands[0]);
4879   enum machine_mode src_mode = GET_MODE (operands[1]);
4881   if (REG_P (operands[0])
4882       && !reg_overlap_mentioned_p (operands[0], operands[1]))
4883     emit_clobber (operands[0]);
4884   if (!REG_P (lo_part) || src_mode != SImode
4885       || !rtx_equal_p (lo_part, operands[1]))
4886     {
4887       if (src_mode == SImode)
4888         emit_move_insn (lo_part, operands[1]);
4889       else
4890         emit_insn (gen_rtx_SET (VOIDmode, lo_part,
4891                                 gen_rtx_ZERO_EXTEND (SImode, operands[1])));
4892       operands[1] = lo_part;
4893     }
4894   operands[0] = gen_highpart (SImode, operands[0]);
4895   operands[1] = const0_rtx;
4898 (define_split
4899   [(set (match_operand:DI 0 "s_register_operand" "")
4900         (sign_extend:DI (match_operand 1 "nonimmediate_operand" "")))]
4901   "TARGET_32BIT && reload_completed && !IS_VFP_REGNUM (REGNO (operands[0]))"
4902   [(set (match_dup 0) (ashiftrt:SI (match_dup 1) (const_int 31)))]
4904   rtx lo_part = gen_lowpart (SImode, operands[0]);
4905   enum machine_mode src_mode = GET_MODE (operands[1]);
4907   if (REG_P (operands[0])
4908       && !reg_overlap_mentioned_p (operands[0], operands[1]))
4909     emit_clobber (operands[0]);
4911   if (!REG_P (lo_part) || src_mode != SImode
4912       || !rtx_equal_p (lo_part, operands[1]))
4913     {
4914       if (src_mode == SImode)
4915         emit_move_insn (lo_part, operands[1]);
4916       else
4917         emit_insn (gen_rtx_SET (VOIDmode, lo_part,
4918                                 gen_rtx_SIGN_EXTEND (SImode, operands[1])));
4919       operands[1] = lo_part;
4920     }
4921   operands[0] = gen_highpart (SImode, operands[0]);
4924 (define_expand "zero_extendhisi2"
4925   [(set (match_operand:SI 0 "s_register_operand" "")
4926         (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
4927   "TARGET_EITHER"
4929   if (TARGET_ARM && !arm_arch4 && MEM_P (operands[1]))
4930     {
4931       emit_insn (gen_movhi_bytes (operands[0], operands[1]));
4932       DONE;
4933     }
4934   if (!arm_arch6 && !MEM_P (operands[1]))
4935     {
4936       rtx t = gen_lowpart (SImode, operands[1]);
4937       rtx tmp = gen_reg_rtx (SImode);
4938       emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (16)));
4939       emit_insn (gen_lshrsi3 (operands[0], tmp, GEN_INT (16)));
4940       DONE;
4941     }
4944 (define_split
4945   [(set (match_operand:SI 0 "s_register_operand" "")
4946         (zero_extend:SI (match_operand:HI 1 "s_register_operand" "")))]
4947   "!TARGET_THUMB2 && !arm_arch6"
4948   [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
4949    (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 16)))]
4951   operands[2] = gen_lowpart (SImode, operands[1]);
4954 (define_insn "*arm_zero_extendhisi2"
4955   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4956         (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
4957   "TARGET_ARM && arm_arch4 && !arm_arch6"
4958   "@
4959    #
4960    ldr%(h%)\\t%0, %1"
4961   [(set_attr "type" "alu_shift_reg,load_byte")
4962    (set_attr "predicable" "yes")]
4965 (define_insn "*arm_zero_extendhisi2_v6"
4966   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4967         (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,Uh")))]
4968   "TARGET_ARM && arm_arch6"
4969   "@
4970    uxth%?\\t%0, %1
4971    ldr%(h%)\\t%0, %1"
4972   [(set_attr "predicable" "yes")
4973    (set_attr "type" "extend,load_byte")]
4976 (define_insn "*arm_zero_extendhisi2addsi"
4977   [(set (match_operand:SI 0 "s_register_operand" "=r")
4978         (plus:SI (zero_extend:SI (match_operand:HI 1 "s_register_operand" "r"))
4979                  (match_operand:SI 2 "s_register_operand" "r")))]
4980   "TARGET_INT_SIMD"
4981   "uxtah%?\\t%0, %2, %1"
4982   [(set_attr "type" "alu_shift_reg")
4983    (set_attr "predicable" "yes")
4984    (set_attr "predicable_short_it" "no")]
4987 (define_expand "zero_extendqisi2"
4988   [(set (match_operand:SI 0 "s_register_operand" "")
4989         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))]
4990   "TARGET_EITHER"
4992   if (TARGET_ARM && !arm_arch6 && !MEM_P (operands[1]))
4993     {
4994       emit_insn (gen_andsi3 (operands[0],
4995                              gen_lowpart (SImode, operands[1]),
4996                                           GEN_INT (255)));
4997       DONE;
4998     }
4999   if (!arm_arch6 && !MEM_P (operands[1]))
5000     {
5001       rtx t = gen_lowpart (SImode, operands[1]);
5002       rtx tmp = gen_reg_rtx (SImode);
5003       emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (24)));
5004       emit_insn (gen_lshrsi3 (operands[0], tmp, GEN_INT (24)));
5005       DONE;
5006     }
5009 (define_split
5010   [(set (match_operand:SI 0 "s_register_operand" "")
5011         (zero_extend:SI (match_operand:QI 1 "s_register_operand" "")))]
5012   "!arm_arch6"
5013   [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 24)))
5014    (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 24)))]
5016   operands[2] = simplify_gen_subreg (SImode, operands[1], QImode, 0);
5017   if (TARGET_ARM)
5018     {
5019       emit_insn (gen_andsi3 (operands[0], operands[2], GEN_INT (255)));
5020       DONE;
5021     }
5024 (define_insn "*arm_zero_extendqisi2"
5025   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5026         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
5027   "TARGET_ARM && !arm_arch6"
5028   "@
5029    #
5030    ldr%(b%)\\t%0, %1\\t%@ zero_extendqisi2"
5031   [(set_attr "length" "8,4")
5032    (set_attr "type" "alu_shift_reg,load_byte")
5033    (set_attr "predicable" "yes")]
5036 (define_insn "*arm_zero_extendqisi2_v6"
5037   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5038         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,Uh")))]
5039   "TARGET_ARM && arm_arch6"
5040   "@
5041    uxtb%(%)\\t%0, %1
5042    ldr%(b%)\\t%0, %1\\t%@ zero_extendqisi2"
5043   [(set_attr "type" "extend,load_byte")
5044    (set_attr "predicable" "yes")]
5047 (define_insn "*arm_zero_extendqisi2addsi"
5048   [(set (match_operand:SI 0 "s_register_operand" "=r")
5049         (plus:SI (zero_extend:SI (match_operand:QI 1 "s_register_operand" "r"))
5050                  (match_operand:SI 2 "s_register_operand" "r")))]
5051   "TARGET_INT_SIMD"
5052   "uxtab%?\\t%0, %2, %1"
5053   [(set_attr "predicable" "yes")
5054    (set_attr "predicable_short_it" "no")
5055    (set_attr "type" "alu_shift_reg")]
5058 (define_split
5059   [(set (match_operand:SI 0 "s_register_operand" "")
5060         (zero_extend:SI (subreg:QI (match_operand:SI 1 "" "") 0)))
5061    (clobber (match_operand:SI 2 "s_register_operand" ""))]
5062   "TARGET_32BIT && (!MEM_P (operands[1])) && ! BYTES_BIG_ENDIAN"
5063   [(set (match_dup 2) (match_dup 1))
5064    (set (match_dup 0) (and:SI (match_dup 2) (const_int 255)))]
5065   ""
5068 (define_split
5069   [(set (match_operand:SI 0 "s_register_operand" "")
5070         (zero_extend:SI (subreg:QI (match_operand:SI 1 "" "") 3)))
5071    (clobber (match_operand:SI 2 "s_register_operand" ""))]
5072   "TARGET_32BIT && (!MEM_P (operands[1])) && BYTES_BIG_ENDIAN"
5073   [(set (match_dup 2) (match_dup 1))
5074    (set (match_dup 0) (and:SI (match_dup 2) (const_int 255)))]
5075   ""
5079 (define_split
5080   [(set (match_operand:SI 0 "s_register_operand" "")
5081         (ior_xor:SI (and:SI (ashift:SI
5082                              (match_operand:SI 1 "s_register_operand" "")
5083                              (match_operand:SI 2 "const_int_operand" ""))
5084                             (match_operand:SI 3 "const_int_operand" ""))
5085                     (zero_extend:SI
5086                      (match_operator 5 "subreg_lowpart_operator"
5087                       [(match_operand:SI 4 "s_register_operand" "")]))))]
5088   "TARGET_32BIT
5089    && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
5090        == (GET_MODE_MASK (GET_MODE (operands[5]))
5091            & (GET_MODE_MASK (GET_MODE (operands[5]))
5092               << (INTVAL (operands[2])))))"
5093   [(set (match_dup 0) (ior_xor:SI (ashift:SI (match_dup 1) (match_dup 2))
5094                                   (match_dup 4)))
5095    (set (match_dup 0) (zero_extend:SI (match_dup 5)))]
5096   "operands[5] = gen_lowpart (GET_MODE (operands[5]), operands[0]);"
5099 (define_insn "*compareqi_eq0"
5100   [(set (reg:CC_Z CC_REGNUM)
5101         (compare:CC_Z (match_operand:QI 0 "s_register_operand" "r")
5102                          (const_int 0)))]
5103   "TARGET_32BIT"
5104   "tst%?\\t%0, #255"
5105   [(set_attr "conds" "set")
5106    (set_attr "predicable" "yes")
5107    (set_attr "predicable_short_it" "no")
5108    (set_attr "type" "logic_imm")]
5111 (define_expand "extendhisi2"
5112   [(set (match_operand:SI 0 "s_register_operand" "")
5113         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
5114   "TARGET_EITHER"
5116   if (TARGET_THUMB1)
5117     {
5118       emit_insn (gen_thumb1_extendhisi2 (operands[0], operands[1]));
5119       DONE;
5120     }
5121   if (MEM_P (operands[1]) && TARGET_ARM && !arm_arch4)
5122     {
5123       emit_insn (gen_extendhisi2_mem (operands[0], operands[1]));
5124       DONE;
5125     }
5127   if (!arm_arch6 && !MEM_P (operands[1]))
5128     {
5129       rtx t = gen_lowpart (SImode, operands[1]);
5130       rtx tmp = gen_reg_rtx (SImode);
5131       emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (16)));
5132       emit_insn (gen_ashrsi3 (operands[0], tmp, GEN_INT (16)));
5133       DONE;
5134     }
5137 (define_split
5138   [(parallel
5139     [(set (match_operand:SI 0 "register_operand" "")
5140           (sign_extend:SI (match_operand:HI 1 "register_operand" "")))
5141      (clobber (match_scratch:SI 2 ""))])]
5142   "!arm_arch6"
5143   [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
5144    (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
5146   operands[2] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
5149 ;; This pattern will only be used when ldsh is not available
5150 (define_expand "extendhisi2_mem"
5151   [(set (match_dup 2) (zero_extend:SI (match_operand:HI 1 "" "")))
5152    (set (match_dup 3)
5153         (zero_extend:SI (match_dup 7)))
5154    (set (match_dup 6) (ashift:SI (match_dup 4) (const_int 24)))
5155    (set (match_operand:SI 0 "" "")
5156         (ior:SI (ashiftrt:SI (match_dup 6) (const_int 16)) (match_dup 5)))]
5157   "TARGET_ARM"
5158   "
5159   {
5160     rtx mem1, mem2;
5161     rtx addr = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
5163     mem1 = change_address (operands[1], QImode, addr);
5164     mem2 = change_address (operands[1], QImode,
5165                            plus_constant (Pmode, addr, 1));
5166     operands[0] = gen_lowpart (SImode, operands[0]);
5167     operands[1] = mem1;
5168     operands[2] = gen_reg_rtx (SImode);
5169     operands[3] = gen_reg_rtx (SImode);
5170     operands[6] = gen_reg_rtx (SImode);
5171     operands[7] = mem2;
5173     if (BYTES_BIG_ENDIAN)
5174       {
5175         operands[4] = operands[2];
5176         operands[5] = operands[3];
5177       }
5178     else
5179       {
5180         operands[4] = operands[3];
5181         operands[5] = operands[2];
5182       }
5183   }"
5186 (define_split
5187   [(set (match_operand:SI 0 "register_operand" "")
5188         (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
5189   "!arm_arch6"
5190   [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
5191    (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
5193   operands[2] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
5196 (define_insn "*arm_extendhisi2"
5197   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5198         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,Uh")))]
5199   "TARGET_ARM && arm_arch4 && !arm_arch6"
5200   "@
5201    #
5202    ldr%(sh%)\\t%0, %1"
5203   [(set_attr "length" "8,4")
5204    (set_attr "type" "alu_shift_reg,load_byte")
5205    (set_attr "predicable" "yes")]
5208 ;; ??? Check Thumb-2 pool range
5209 (define_insn "*arm_extendhisi2_v6"
5210   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5211         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,Uh")))]
5212   "TARGET_32BIT && arm_arch6"
5213   "@
5214    sxth%?\\t%0, %1
5215    ldr%(sh%)\\t%0, %1"
5216   [(set_attr "type" "extend,load_byte")
5217    (set_attr "predicable" "yes")
5218    (set_attr "predicable_short_it" "no")]
5221 (define_insn "*arm_extendhisi2addsi"
5222   [(set (match_operand:SI 0 "s_register_operand" "=r")
5223         (plus:SI (sign_extend:SI (match_operand:HI 1 "s_register_operand" "r"))
5224                  (match_operand:SI 2 "s_register_operand" "r")))]
5225   "TARGET_INT_SIMD"
5226   "sxtah%?\\t%0, %2, %1"
5227   [(set_attr "type" "alu_shift_reg")]
5230 (define_expand "extendqihi2"
5231   [(set (match_dup 2)
5232         (ashift:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "")
5233                    (const_int 24)))
5234    (set (match_operand:HI 0 "s_register_operand" "")
5235         (ashiftrt:SI (match_dup 2)
5236                      (const_int 24)))]
5237   "TARGET_ARM"
5238   "
5239   {
5240     if (arm_arch4 && MEM_P (operands[1]))
5241       {
5242         emit_insn (gen_rtx_SET (VOIDmode,
5243                                 operands[0],
5244                                 gen_rtx_SIGN_EXTEND (HImode, operands[1])));
5245         DONE;
5246       }
5247     if (!s_register_operand (operands[1], QImode))
5248       operands[1] = copy_to_mode_reg (QImode, operands[1]);
5249     operands[0] = gen_lowpart (SImode, operands[0]);
5250     operands[1] = gen_lowpart (SImode, operands[1]);
5251     operands[2] = gen_reg_rtx (SImode);
5252   }"
5255 (define_insn "*arm_extendqihi_insn"
5256   [(set (match_operand:HI 0 "s_register_operand" "=r")
5257         (sign_extend:HI (match_operand:QI 1 "arm_extendqisi_mem_op" "Uq")))]
5258   "TARGET_ARM && arm_arch4"
5259   "ldr%(sb%)\\t%0, %1"
5260   [(set_attr "type" "load_byte")
5261    (set_attr "predicable" "yes")]
5264 (define_expand "extendqisi2"
5265   [(set (match_operand:SI 0 "s_register_operand" "")
5266         (sign_extend:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "")))]
5267   "TARGET_EITHER"
5269   if (!arm_arch4 && MEM_P (operands[1]))
5270     operands[1] = copy_to_mode_reg (QImode, operands[1]);
5272   if (!arm_arch6 && !MEM_P (operands[1]))
5273     {
5274       rtx t = gen_lowpart (SImode, operands[1]);
5275       rtx tmp = gen_reg_rtx (SImode);
5276       emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (24)));
5277       emit_insn (gen_ashrsi3 (operands[0], tmp, GEN_INT (24)));
5278       DONE;
5279     }
5282 (define_split
5283   [(set (match_operand:SI 0 "register_operand" "")
5284         (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
5285   "!arm_arch6"
5286   [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 24)))
5287    (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 24)))]
5289   operands[2] = simplify_gen_subreg (SImode, operands[1], QImode, 0);
5292 (define_insn "*arm_extendqisi"
5293   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5294         (sign_extend:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "r,Uq")))]
5295   "TARGET_ARM && arm_arch4 && !arm_arch6"
5296   "@
5297    #
5298    ldr%(sb%)\\t%0, %1"
5299   [(set_attr "length" "8,4")
5300    (set_attr "type" "alu_shift_reg,load_byte")
5301    (set_attr "predicable" "yes")]
5304 (define_insn "*arm_extendqisi_v6"
5305   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5306         (sign_extend:SI
5307          (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "r,Uq")))]
5308   "TARGET_ARM && arm_arch6"
5309   "@
5310    sxtb%?\\t%0, %1
5311    ldr%(sb%)\\t%0, %1"
5312   [(set_attr "type" "extend,load_byte")
5313    (set_attr "predicable" "yes")]
5316 (define_insn "*arm_extendqisi2addsi"
5317   [(set (match_operand:SI 0 "s_register_operand" "=r")
5318         (plus:SI (sign_extend:SI (match_operand:QI 1 "s_register_operand" "r"))
5319                  (match_operand:SI 2 "s_register_operand" "r")))]
5320   "TARGET_INT_SIMD"
5321   "sxtab%?\\t%0, %2, %1"
5322   [(set_attr "type" "alu_shift_reg")
5323    (set_attr "predicable" "yes")
5324    (set_attr "predicable_short_it" "no")]
5327 (define_expand "extendsfdf2"
5328   [(set (match_operand:DF                  0 "s_register_operand" "")
5329         (float_extend:DF (match_operand:SF 1 "s_register_operand"  "")))]
5330   "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
5331   ""
5334 /* HFmode -> DFmode conversions have to go through SFmode.  */
5335 (define_expand "extendhfdf2"
5336   [(set (match_operand:DF                  0 "general_operand" "")
5337         (float_extend:DF (match_operand:HF 1 "general_operand"  "")))]
5338   "TARGET_EITHER"
5339   "
5340   {
5341     rtx op1;
5342     op1 = convert_to_mode (SFmode, operands[1], 0);
5343     op1 = convert_to_mode (DFmode, op1, 0);
5344     emit_insn (gen_movdf (operands[0], op1));
5345     DONE;
5346   }"
5349 ;; Move insns (including loads and stores)
5351 ;; XXX Just some ideas about movti.
5352 ;; I don't think these are a good idea on the arm, there just aren't enough
5353 ;; registers
5354 ;;(define_expand "loadti"
5355 ;;  [(set (match_operand:TI 0 "s_register_operand" "")
5356 ;;      (mem:TI (match_operand:SI 1 "address_operand" "")))]
5357 ;;  "" "")
5359 ;;(define_expand "storeti"
5360 ;;  [(set (mem:TI (match_operand:TI 0 "address_operand" ""))
5361 ;;      (match_operand:TI 1 "s_register_operand" ""))]
5362 ;;  "" "")
5364 ;;(define_expand "movti"
5365 ;;  [(set (match_operand:TI 0 "general_operand" "")
5366 ;;      (match_operand:TI 1 "general_operand" ""))]
5367 ;;  ""
5368 ;;  "
5370 ;;  rtx insn;
5372 ;;  if (MEM_P (operands[0]) && MEM_P (operands[1]))
5373 ;;    operands[1] = copy_to_reg (operands[1]);
5374 ;;  if (MEM_P (operands[0]))
5375 ;;    insn = gen_storeti (XEXP (operands[0], 0), operands[1]);
5376 ;;  else if (MEM_P (operands[1]))
5377 ;;    insn = gen_loadti (operands[0], XEXP (operands[1], 0));
5378 ;;  else
5379 ;;    FAIL;
5381 ;;  emit_insn (insn);
5382 ;;  DONE;
5383 ;;}")
5385 ;; Recognize garbage generated above.
5387 ;;(define_insn ""
5388 ;;  [(set (match_operand:TI 0 "general_operand" "=r,r,r,<,>,m")
5389 ;;      (match_operand:TI 1 "general_operand" "<,>,m,r,r,r"))]
5390 ;;  ""
5391 ;;  "*
5392 ;;  {
5393 ;;    register mem = (which_alternative < 3);
5394 ;;    register const char *template;
5396 ;;    operands[mem] = XEXP (operands[mem], 0);
5397 ;;    switch (which_alternative)
5398 ;;      {
5399 ;;      case 0: template = \"ldmdb\\t%1!, %M0\"; break;
5400 ;;      case 1: template = \"ldmia\\t%1!, %M0\"; break;
5401 ;;      case 2: template = \"ldmia\\t%1, %M0\"; break;
5402 ;;      case 3: template = \"stmdb\\t%0!, %M1\"; break;
5403 ;;      case 4: template = \"stmia\\t%0!, %M1\"; break;
5404 ;;      case 5: template = \"stmia\\t%0, %M1\"; break;
5405 ;;      }
5406 ;;    output_asm_insn (template, operands);
5407 ;;    return \"\";
5408 ;;  }")
5410 (define_expand "movdi"
5411   [(set (match_operand:DI 0 "general_operand" "")
5412         (match_operand:DI 1 "general_operand" ""))]
5413   "TARGET_EITHER"
5414   "
5415   if (can_create_pseudo_p ())
5416     {
5417       if (!REG_P (operands[0]))
5418         operands[1] = force_reg (DImode, operands[1]);
5419     }
5420   "
5423 (define_insn "*arm_movdi"
5424   [(set (match_operand:DI 0 "nonimmediate_di_operand" "=r, r, r, q, m")
5425         (match_operand:DI 1 "di_operand"              "rDa,Db,Dc,mi,q"))]
5426   "TARGET_32BIT
5427    && !(TARGET_HARD_FLOAT && TARGET_VFP)
5428    && !TARGET_IWMMXT
5429    && (   register_operand (operands[0], DImode)
5430        || register_operand (operands[1], DImode))"
5431   "*
5432   switch (which_alternative)
5433     {
5434     case 0:
5435     case 1:
5436     case 2:
5437       return \"#\";
5438     default:
5439       return output_move_double (operands, true, NULL);
5440     }
5441   "
5442   [(set_attr "length" "8,12,16,8,8")
5443    (set_attr "type" "multiple,multiple,multiple,load2,store2")
5444    (set_attr "arm_pool_range" "*,*,*,1020,*")
5445    (set_attr "arm_neg_pool_range" "*,*,*,1004,*")
5446    (set_attr "thumb2_pool_range" "*,*,*,4094,*")
5447    (set_attr "thumb2_neg_pool_range" "*,*,*,0,*")]
5450 (define_split
5451   [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
5452         (match_operand:ANY64 1 "immediate_operand" ""))]
5453   "TARGET_32BIT
5454    && reload_completed
5455    && (arm_const_double_inline_cost (operands[1])
5456        <= arm_max_const_double_inline_cost ())"
5457   [(const_int 0)]
5458   "
5459   arm_split_constant (SET, SImode, curr_insn,
5460                       INTVAL (gen_lowpart (SImode, operands[1])),
5461                       gen_lowpart (SImode, operands[0]), NULL_RTX, 0);
5462   arm_split_constant (SET, SImode, curr_insn,
5463                       INTVAL (gen_highpart_mode (SImode,
5464                                                  GET_MODE (operands[0]),
5465                                                  operands[1])),
5466                       gen_highpart (SImode, operands[0]), NULL_RTX, 0);
5467   DONE;
5468   "
5471 ; If optimizing for size, or if we have load delay slots, then 
5472 ; we want to split the constant into two separate operations. 
5473 ; In both cases this may split a trivial part into a single data op
5474 ; leaving a single complex constant to load.  We can also get longer
5475 ; offsets in a LDR which means we get better chances of sharing the pool
5476 ; entries.  Finally, we can normally do a better job of scheduling
5477 ; LDR instructions than we can with LDM.
5478 ; This pattern will only match if the one above did not.
5479 (define_split
5480   [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
5481         (match_operand:ANY64 1 "const_double_operand" ""))]
5482   "TARGET_ARM && reload_completed
5483    && arm_const_double_by_parts (operands[1])"
5484   [(set (match_dup 0) (match_dup 1))
5485    (set (match_dup 2) (match_dup 3))]
5486   "
5487   operands[2] = gen_highpart (SImode, operands[0]);
5488   operands[3] = gen_highpart_mode (SImode, GET_MODE (operands[0]),
5489                                    operands[1]);
5490   operands[0] = gen_lowpart (SImode, operands[0]);
5491   operands[1] = gen_lowpart (SImode, operands[1]);
5492   "
5495 (define_split
5496   [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
5497         (match_operand:ANY64 1 "arm_general_register_operand" ""))]
5498   "TARGET_EITHER && reload_completed"
5499   [(set (match_dup 0) (match_dup 1))
5500    (set (match_dup 2) (match_dup 3))]
5501   "
5502   operands[2] = gen_highpart (SImode, operands[0]);
5503   operands[3] = gen_highpart (SImode, operands[1]);
5504   operands[0] = gen_lowpart (SImode, operands[0]);
5505   operands[1] = gen_lowpart (SImode, operands[1]);
5507   /* Handle a partial overlap.  */
5508   if (rtx_equal_p (operands[0], operands[3]))
5509     {
5510       rtx tmp0 = operands[0];
5511       rtx tmp1 = operands[1];
5513       operands[0] = operands[2];
5514       operands[1] = operands[3];
5515       operands[2] = tmp0;
5516       operands[3] = tmp1;
5517     }
5518   "
5521 ;; We can't actually do base+index doubleword loads if the index and
5522 ;; destination overlap.  Split here so that we at least have chance to
5523 ;; schedule.
5524 (define_split
5525   [(set (match_operand:DI 0 "s_register_operand" "")
5526         (mem:DI (plus:SI (match_operand:SI 1 "s_register_operand" "")
5527                          (match_operand:SI 2 "s_register_operand" ""))))]
5528   "TARGET_LDRD
5529   && reg_overlap_mentioned_p (operands[0], operands[1])
5530   && reg_overlap_mentioned_p (operands[0], operands[2])"
5531   [(set (match_dup 4)
5532         (plus:SI (match_dup 1)
5533                  (match_dup 2)))
5534    (set (match_dup 0)
5535         (mem:DI (match_dup 4)))]
5536   "
5537   operands[4] = gen_rtx_REG (SImode, REGNO(operands[0]));
5538   "
5541 (define_expand "movsi"
5542   [(set (match_operand:SI 0 "general_operand" "")
5543         (match_operand:SI 1 "general_operand" ""))]
5544   "TARGET_EITHER"
5545   "
5546   {
5547   rtx base, offset, tmp;
5549   if (TARGET_32BIT)
5550     {
5551       /* Everything except mem = const or mem = mem can be done easily.  */
5552       if (MEM_P (operands[0]))
5553         operands[1] = force_reg (SImode, operands[1]);
5554       if (arm_general_register_operand (operands[0], SImode)
5555           && CONST_INT_P (operands[1])
5556           && !(const_ok_for_arm (INTVAL (operands[1]))
5557                || const_ok_for_arm (~INTVAL (operands[1]))))
5558         {
5559            arm_split_constant (SET, SImode, NULL_RTX,
5560                                INTVAL (operands[1]), operands[0], NULL_RTX,
5561                                optimize && can_create_pseudo_p ());
5562           DONE;
5563         }
5564     }
5565   else /* TARGET_THUMB1...  */
5566     {
5567       if (can_create_pseudo_p ())
5568         {
5569           if (!REG_P (operands[0]))
5570             operands[1] = force_reg (SImode, operands[1]);
5571         }
5572     }
5574   if (ARM_OFFSETS_MUST_BE_WITHIN_SECTIONS_P)
5575     {
5576       split_const (operands[1], &base, &offset);
5577       if (GET_CODE (base) == SYMBOL_REF
5578           && !offset_within_block_p (base, INTVAL (offset)))
5579         {
5580           tmp = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];
5581           emit_move_insn (tmp, base);
5582           emit_insn (gen_addsi3 (operands[0], tmp, offset));
5583           DONE;
5584         }
5585     }
5587   /* Recognize the case where operand[1] is a reference to thread-local
5588      data and load its address to a register.  */
5589   if (arm_tls_referenced_p (operands[1]))
5590     {
5591       rtx tmp = operands[1];
5592       rtx addend = NULL;
5594       if (GET_CODE (tmp) == CONST && GET_CODE (XEXP (tmp, 0)) == PLUS)
5595         {
5596           addend = XEXP (XEXP (tmp, 0), 1);
5597           tmp = XEXP (XEXP (tmp, 0), 0);
5598         }
5600       gcc_assert (GET_CODE (tmp) == SYMBOL_REF);
5601       gcc_assert (SYMBOL_REF_TLS_MODEL (tmp) != 0);
5603       tmp = legitimize_tls_address (tmp,
5604                                     !can_create_pseudo_p () ? operands[0] : 0);
5605       if (addend)
5606         {
5607           tmp = gen_rtx_PLUS (SImode, tmp, addend);
5608           tmp = force_operand (tmp, operands[0]);
5609         }
5610       operands[1] = tmp;
5611     }
5612   else if (flag_pic
5613            && (CONSTANT_P (operands[1])
5614                || symbol_mentioned_p (operands[1])
5615                || label_mentioned_p (operands[1])))
5616       operands[1] = legitimize_pic_address (operands[1], SImode,
5617                                             (!can_create_pseudo_p ()
5618                                              ? operands[0]
5619                                              : 0));
5620   }
5621   "
5624 ;; The ARM LO_SUM and HIGH are backwards - HIGH sets the low bits, and
5625 ;; LO_SUM adds in the high bits.  Fortunately these are opaque operations
5626 ;; so this does not matter.
5627 (define_insn "*arm_movt"
5628   [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
5629         (lo_sum:SI (match_operand:SI 1 "nonimmediate_operand" "0")
5630                    (match_operand:SI 2 "general_operand"      "i")))]
5631   "arm_arch_thumb2"
5632   "movt%?\t%0, #:upper16:%c2"
5633   [(set_attr "predicable" "yes")
5634    (set_attr "predicable_short_it" "no")
5635    (set_attr "length" "4")
5636    (set_attr "type" "mov_imm")]
5639 (define_insn "*arm_movsi_insn"
5640   [(set (match_operand:SI 0 "nonimmediate_operand" "=rk,r,r,r,rk,m")
5641         (match_operand:SI 1 "general_operand"      "rk, I,K,j,mi,rk"))]
5642   "TARGET_ARM && ! TARGET_IWMMXT
5643    && !(TARGET_HARD_FLOAT && TARGET_VFP)
5644    && (   register_operand (operands[0], SImode)
5645        || register_operand (operands[1], SImode))"
5646   "@
5647    mov%?\\t%0, %1
5648    mov%?\\t%0, %1
5649    mvn%?\\t%0, #%B1
5650    movw%?\\t%0, %1
5651    ldr%?\\t%0, %1
5652    str%?\\t%1, %0"
5653   [(set_attr "type" "mov_reg,mov_imm,mvn_imm,mov_imm,load1,store1")
5654    (set_attr "predicable" "yes")
5655    (set_attr "pool_range" "*,*,*,*,4096,*")
5656    (set_attr "neg_pool_range" "*,*,*,*,4084,*")]
5659 (define_split
5660   [(set (match_operand:SI 0 "arm_general_register_operand" "")
5661         (match_operand:SI 1 "const_int_operand" ""))]
5662   "TARGET_32BIT
5663   && (!(const_ok_for_arm (INTVAL (operands[1]))
5664         || const_ok_for_arm (~INTVAL (operands[1]))))"
5665   [(clobber (const_int 0))]
5666   "
5667   arm_split_constant (SET, SImode, NULL_RTX, 
5668                       INTVAL (operands[1]), operands[0], NULL_RTX, 0);
5669   DONE;
5670   "
5673 ;; A normal way to do (symbol + offset) requires three instructions at least
5674 ;; (depends on how big the offset is) as below:
5675 ;; movw r0, #:lower16:g
5676 ;; movw r0, #:upper16:g
5677 ;; adds r0, #4
5679 ;; A better way would be:
5680 ;; movw r0, #:lower16:g+4
5681 ;; movw r0, #:upper16:g+4
5683 ;; The limitation of this way is that the length of offset should be a 16-bit
5684 ;; signed value, because current assembler only supports REL type relocation for
5685 ;; such case.  If the more powerful RELA type is supported in future, we should
5686 ;; update this pattern to go with better way.
5687 (define_split
5688   [(set (match_operand:SI 0 "arm_general_register_operand" "")
5689         (const:SI (plus:SI (match_operand:SI 1 "general_operand" "")
5690                            (match_operand:SI 2 "const_int_operand" ""))))]
5691   "TARGET_THUMB2
5692    && arm_disable_literal_pool
5693    && reload_completed
5694    && GET_CODE (operands[1]) == SYMBOL_REF"
5695   [(clobber (const_int 0))]
5696   "
5697     int offset = INTVAL (operands[2]);
5699     if (offset < -0x8000 || offset > 0x7fff)
5700       {
5701         arm_emit_movpair (operands[0], operands[1]);
5702         emit_insn (gen_rtx_SET (SImode, operands[0],
5703                                 gen_rtx_PLUS (SImode, operands[0], operands[2])));
5704       }
5705     else
5706       {
5707         rtx op = gen_rtx_CONST (SImode,
5708                                 gen_rtx_PLUS (SImode, operands[1], operands[2]));
5709         arm_emit_movpair (operands[0], op);
5710       }
5711   "
5714 ;; Split symbol_refs at the later stage (after cprop), instead of generating
5715 ;; movt/movw pair directly at expand.  Otherwise corresponding high_sum
5716 ;; and lo_sum would be merged back into memory load at cprop.  However,
5717 ;; if the default is to prefer movt/movw rather than a load from the constant
5718 ;; pool, the performance is better.
5719 (define_split
5720   [(set (match_operand:SI 0 "arm_general_register_operand" "")
5721        (match_operand:SI 1 "general_operand" ""))]
5722   "TARGET_32BIT
5723    && TARGET_USE_MOVT && GET_CODE (operands[1]) == SYMBOL_REF
5724    && !flag_pic && !target_word_relocations
5725    && !arm_tls_referenced_p (operands[1])"
5726   [(clobber (const_int 0))]
5728   arm_emit_movpair (operands[0], operands[1]);
5729   DONE;
5732 ;; When generating pic, we need to load the symbol offset into a register.
5733 ;; So that the optimizer does not confuse this with a normal symbol load
5734 ;; we use an unspec.  The offset will be loaded from a constant pool entry,
5735 ;; since that is the only type of relocation we can use.
5737 ;; Wrap calculation of the whole PIC address in a single pattern for the
5738 ;; benefit of optimizers, particularly, PRE and HOIST.  Calculation of
5739 ;; a PIC address involves two loads from memory, so we want to CSE it
5740 ;; as often as possible.
5741 ;; This pattern will be split into one of the pic_load_addr_* patterns
5742 ;; and a move after GCSE optimizations.
5744 ;; Note: Update arm.c: legitimize_pic_address() when changing this pattern.
5745 (define_expand "calculate_pic_address"
5746   [(set (match_operand:SI 0 "register_operand" "")
5747         (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "")
5748                          (unspec:SI [(match_operand:SI 2 "" "")]
5749                                     UNSPEC_PIC_SYM))))]
5750   "flag_pic"
5753 ;; Split calculate_pic_address into pic_load_addr_* and a move.
5754 (define_split
5755   [(set (match_operand:SI 0 "register_operand" "")
5756         (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "")
5757                          (unspec:SI [(match_operand:SI 2 "" "")]
5758                                     UNSPEC_PIC_SYM))))]
5759   "flag_pic"
5760   [(set (match_dup 3) (unspec:SI [(match_dup 2)] UNSPEC_PIC_SYM))
5761    (set (match_dup 0) (mem:SI (plus:SI (match_dup 1) (match_dup 3))))]
5762   "operands[3] = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];"
5765 ;; operand1 is the memory address to go into 
5766 ;; pic_load_addr_32bit.
5767 ;; operand2 is the PIC label to be emitted 
5768 ;; from pic_add_dot_plus_eight.
5769 ;; We do this to allow hoisting of the entire insn.
5770 (define_insn_and_split "pic_load_addr_unified"
5771   [(set (match_operand:SI 0 "s_register_operand" "=r,r,l")
5772         (unspec:SI [(match_operand:SI 1 "" "mX,mX,mX") 
5773                     (match_operand:SI 2 "" "")] 
5774                     UNSPEC_PIC_UNIFIED))]
5775  "flag_pic"
5776  "#"
5777  "&& reload_completed"
5778  [(set (match_dup 0) (unspec:SI [(match_dup 1)] UNSPEC_PIC_SYM))
5779   (set (match_dup 0) (unspec:SI [(match_dup 0) (match_dup 3)
5780                                  (match_dup 2)] UNSPEC_PIC_BASE))]
5781  "operands[3] = TARGET_THUMB ? GEN_INT (4) : GEN_INT (8);"
5782  [(set_attr "type" "load1,load1,load1")
5783   (set_attr "pool_range" "4096,4094,1022")
5784   (set_attr "neg_pool_range" "4084,0,0")
5785   (set_attr "arch"  "a,t2,t1")    
5786   (set_attr "length" "8,6,4")]
5789 ;; The rather odd constraints on the following are to force reload to leave
5790 ;; the insn alone, and to force the minipool generation pass to then move
5791 ;; the GOT symbol to memory.
5793 (define_insn "pic_load_addr_32bit"
5794   [(set (match_operand:SI 0 "s_register_operand" "=r")
5795         (unspec:SI [(match_operand:SI 1 "" "mX")] UNSPEC_PIC_SYM))]
5796   "TARGET_32BIT && flag_pic"
5797   "ldr%?\\t%0, %1"
5798   [(set_attr "type" "load1")
5799    (set (attr "pool_range")
5800         (if_then_else (eq_attr "is_thumb" "no")
5801                       (const_int 4096)
5802                       (const_int 4094)))
5803    (set (attr "neg_pool_range")
5804         (if_then_else (eq_attr "is_thumb" "no")
5805                       (const_int 4084)
5806                       (const_int 0)))]
5809 (define_insn "pic_load_addr_thumb1"
5810   [(set (match_operand:SI 0 "s_register_operand" "=l")
5811         (unspec:SI [(match_operand:SI 1 "" "mX")] UNSPEC_PIC_SYM))]
5812   "TARGET_THUMB1 && flag_pic"
5813   "ldr\\t%0, %1"
5814   [(set_attr "type" "load1")
5815    (set (attr "pool_range") (const_int 1018))]
5818 (define_insn "pic_add_dot_plus_four"
5819   [(set (match_operand:SI 0 "register_operand" "=r")
5820         (unspec:SI [(match_operand:SI 1 "register_operand" "0")
5821                     (const_int 4)
5822                     (match_operand 2 "" "")]
5823                    UNSPEC_PIC_BASE))]
5824   "TARGET_THUMB"
5825   "*
5826   (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
5827                                      INTVAL (operands[2]));
5828   return \"add\\t%0, %|pc\";
5829   "
5830   [(set_attr "length" "2")
5831    (set_attr "type" "alu_sreg")]
5834 (define_insn "pic_add_dot_plus_eight"
5835   [(set (match_operand:SI 0 "register_operand" "=r")
5836         (unspec:SI [(match_operand:SI 1 "register_operand" "r")
5837                     (const_int 8)
5838                     (match_operand 2 "" "")]
5839                    UNSPEC_PIC_BASE))]
5840   "TARGET_ARM"
5841   "*
5842     (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
5843                                        INTVAL (operands[2]));
5844     return \"add%?\\t%0, %|pc, %1\";
5845   "
5846   [(set_attr "predicable" "yes")
5847    (set_attr "type" "alu_sreg")]
5850 (define_insn "tls_load_dot_plus_eight"
5851   [(set (match_operand:SI 0 "register_operand" "=r")
5852         (mem:SI (unspec:SI [(match_operand:SI 1 "register_operand" "r")
5853                             (const_int 8)
5854                             (match_operand 2 "" "")]
5855                            UNSPEC_PIC_BASE)))]
5856   "TARGET_ARM"
5857   "*
5858     (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
5859                                        INTVAL (operands[2]));
5860     return \"ldr%?\\t%0, [%|pc, %1]\t\t@ tls_load_dot_plus_eight\";
5861   "
5862   [(set_attr "predicable" "yes")
5863    (set_attr "type" "load1")]
5866 ;; PIC references to local variables can generate pic_add_dot_plus_eight
5867 ;; followed by a load.  These sequences can be crunched down to
5868 ;; tls_load_dot_plus_eight by a peephole.
5870 (define_peephole2
5871   [(set (match_operand:SI 0 "register_operand" "")
5872         (unspec:SI [(match_operand:SI 3 "register_operand" "")
5873                     (const_int 8)
5874                     (match_operand 1 "" "")]
5875                    UNSPEC_PIC_BASE))
5876    (set (match_operand:SI 2 "arm_general_register_operand" "")
5877         (mem:SI (match_dup 0)))]
5878   "TARGET_ARM && peep2_reg_dead_p (2, operands[0])"
5879   [(set (match_dup 2)
5880         (mem:SI (unspec:SI [(match_dup 3)
5881                             (const_int 8)
5882                             (match_dup 1)]
5883                            UNSPEC_PIC_BASE)))]
5884   ""
5887 (define_insn "pic_offset_arm"
5888   [(set (match_operand:SI 0 "register_operand" "=r")
5889         (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
5890                          (unspec:SI [(match_operand:SI 2 "" "X")]
5891                                     UNSPEC_PIC_OFFSET))))]
5892   "TARGET_VXWORKS_RTP && TARGET_ARM && flag_pic"
5893   "ldr%?\\t%0, [%1,%2]"
5894   [(set_attr "type" "load1")]
5897 (define_expand "builtin_setjmp_receiver"
5898   [(label_ref (match_operand 0 "" ""))]
5899   "flag_pic"
5900   "
5902   /* r3 is clobbered by set/longjmp, so we can use it as a scratch
5903      register.  */
5904   if (arm_pic_register != INVALID_REGNUM)
5905     arm_load_pic_register (1UL << 3);
5906   DONE;
5909 ;; If copying one reg to another we can set the condition codes according to
5910 ;; its value.  Such a move is common after a return from subroutine and the
5911 ;; result is being tested against zero.
5913 (define_insn "*movsi_compare0"
5914   [(set (reg:CC CC_REGNUM)
5915         (compare:CC (match_operand:SI 1 "s_register_operand" "0,r")
5916                     (const_int 0)))
5917    (set (match_operand:SI 0 "s_register_operand" "=r,r")
5918         (match_dup 1))]
5919   "TARGET_32BIT"
5920   "@
5921    cmp%?\\t%0, #0
5922    sub%.\\t%0, %1, #0"
5923   [(set_attr "conds" "set")
5924    (set_attr "type" "alus_imm,alus_imm")]
5927 ;; Subroutine to store a half word from a register into memory.
5928 ;; Operand 0 is the source register (HImode)
5929 ;; Operand 1 is the destination address in a register (SImode)
5931 ;; In both this routine and the next, we must be careful not to spill
5932 ;; a memory address of reg+large_const into a separate PLUS insn, since this
5933 ;; can generate unrecognizable rtl.
5935 (define_expand "storehi"
5936   [;; store the low byte
5937    (set (match_operand 1 "" "") (match_dup 3))
5938    ;; extract the high byte
5939    (set (match_dup 2)
5940         (ashiftrt:SI (match_operand 0 "" "") (const_int 8)))
5941    ;; store the high byte
5942    (set (match_dup 4) (match_dup 5))]
5943   "TARGET_ARM"
5944   "
5945   {
5946     rtx op1 = operands[1];
5947     rtx addr = XEXP (op1, 0);
5948     enum rtx_code code = GET_CODE (addr);
5950     if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1)))
5951         || code == MINUS)
5952       op1 = replace_equiv_address (operands[1], force_reg (SImode, addr));
5954     operands[4] = adjust_address (op1, QImode, 1);
5955     operands[1] = adjust_address (operands[1], QImode, 0);
5956     operands[3] = gen_lowpart (QImode, operands[0]);
5957     operands[0] = gen_lowpart (SImode, operands[0]);
5958     operands[2] = gen_reg_rtx (SImode);
5959     operands[5] = gen_lowpart (QImode, operands[2]);
5960   }"
5963 (define_expand "storehi_bigend"
5964   [(set (match_dup 4) (match_dup 3))
5965    (set (match_dup 2)
5966         (ashiftrt:SI (match_operand 0 "" "") (const_int 8)))
5967    (set (match_operand 1 "" "") (match_dup 5))]
5968   "TARGET_ARM"
5969   "
5970   {
5971     rtx op1 = operands[1];
5972     rtx addr = XEXP (op1, 0);
5973     enum rtx_code code = GET_CODE (addr);
5975     if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1)))
5976         || code == MINUS)
5977       op1 = replace_equiv_address (op1, force_reg (SImode, addr));
5979     operands[4] = adjust_address (op1, QImode, 1);
5980     operands[1] = adjust_address (operands[1], QImode, 0);
5981     operands[3] = gen_lowpart (QImode, operands[0]);
5982     operands[0] = gen_lowpart (SImode, operands[0]);
5983     operands[2] = gen_reg_rtx (SImode);
5984     operands[5] = gen_lowpart (QImode, operands[2]);
5985   }"
5988 ;; Subroutine to store a half word integer constant into memory.
5989 (define_expand "storeinthi"
5990   [(set (match_operand 0 "" "")
5991         (match_operand 1 "" ""))
5992    (set (match_dup 3) (match_dup 2))]
5993   "TARGET_ARM"
5994   "
5995   {
5996     HOST_WIDE_INT value = INTVAL (operands[1]);
5997     rtx addr = XEXP (operands[0], 0);
5998     rtx op0 = operands[0];
5999     enum rtx_code code = GET_CODE (addr);
6001     if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1)))
6002         || code == MINUS)
6003       op0 = replace_equiv_address (op0, force_reg (SImode, addr));
6005     operands[1] = gen_reg_rtx (SImode);
6006     if (BYTES_BIG_ENDIAN)
6007       {
6008         emit_insn (gen_movsi (operands[1], GEN_INT ((value >> 8) & 255)));
6009         if ((value & 255) == ((value >> 8) & 255))
6010           operands[2] = operands[1];
6011         else
6012           {
6013             operands[2] = gen_reg_rtx (SImode);
6014             emit_insn (gen_movsi (operands[2], GEN_INT (value & 255)));
6015           }
6016       }
6017     else
6018       {
6019         emit_insn (gen_movsi (operands[1], GEN_INT (value & 255)));
6020         if ((value & 255) == ((value >> 8) & 255))
6021           operands[2] = operands[1];
6022         else
6023           {
6024             operands[2] = gen_reg_rtx (SImode);
6025             emit_insn (gen_movsi (operands[2], GEN_INT ((value >> 8) & 255)));
6026           }
6027       }
6029     operands[3] = adjust_address (op0, QImode, 1);
6030     operands[0] = adjust_address (operands[0], QImode, 0);
6031     operands[2] = gen_lowpart (QImode, operands[2]);
6032     operands[1] = gen_lowpart (QImode, operands[1]);
6033   }"
6036 (define_expand "storehi_single_op"
6037   [(set (match_operand:HI 0 "memory_operand" "")
6038         (match_operand:HI 1 "general_operand" ""))]
6039   "TARGET_32BIT && arm_arch4"
6040   "
6041   if (!s_register_operand (operands[1], HImode))
6042     operands[1] = copy_to_mode_reg (HImode, operands[1]);
6043   "
6046 (define_expand "movhi"
6047   [(set (match_operand:HI 0 "general_operand" "")
6048         (match_operand:HI 1 "general_operand" ""))]
6049   "TARGET_EITHER"
6050   "
6051   if (TARGET_ARM)
6052     {
6053       if (can_create_pseudo_p ())
6054         {
6055           if (MEM_P (operands[0]))
6056             {
6057               if (arm_arch4)
6058                 {
6059                   emit_insn (gen_storehi_single_op (operands[0], operands[1]));
6060                   DONE;
6061                 }
6062               if (CONST_INT_P (operands[1]))
6063                 emit_insn (gen_storeinthi (operands[0], operands[1]));
6064               else
6065                 {
6066                   if (MEM_P (operands[1]))
6067                     operands[1] = force_reg (HImode, operands[1]);
6068                   if (BYTES_BIG_ENDIAN)
6069                     emit_insn (gen_storehi_bigend (operands[1], operands[0]));
6070                   else
6071                    emit_insn (gen_storehi (operands[1], operands[0]));
6072                 }
6073               DONE;
6074             }
6075           /* Sign extend a constant, and keep it in an SImode reg.  */
6076           else if (CONST_INT_P (operands[1]))
6077             {
6078               rtx reg = gen_reg_rtx (SImode);
6079               HOST_WIDE_INT val = INTVAL (operands[1]) & 0xffff;
6081               /* If the constant is already valid, leave it alone.  */
6082               if (!const_ok_for_arm (val))
6083                 {
6084                   /* If setting all the top bits will make the constant 
6085                      loadable in a single instruction, then set them.  
6086                      Otherwise, sign extend the number.  */
6088                   if (const_ok_for_arm (~(val | ~0xffff)))
6089                     val |= ~0xffff;
6090                   else if (val & 0x8000)
6091                     val |= ~0xffff;
6092                 }
6094               emit_insn (gen_movsi (reg, GEN_INT (val)));
6095               operands[1] = gen_lowpart (HImode, reg);
6096             }
6097           else if (arm_arch4 && optimize && can_create_pseudo_p ()
6098                    && MEM_P (operands[1]))
6099             {
6100               rtx reg = gen_reg_rtx (SImode);
6102               emit_insn (gen_zero_extendhisi2 (reg, operands[1]));
6103               operands[1] = gen_lowpart (HImode, reg);
6104             }
6105           else if (!arm_arch4)
6106             {
6107               if (MEM_P (operands[1]))
6108                 {
6109                   rtx base;
6110                   rtx offset = const0_rtx;
6111                   rtx reg = gen_reg_rtx (SImode);
6113                   if ((REG_P (base = XEXP (operands[1], 0))
6114                        || (GET_CODE (base) == PLUS
6115                            && (CONST_INT_P (offset = XEXP (base, 1)))
6116                            && ((INTVAL(offset) & 1) != 1)
6117                            && REG_P (base = XEXP (base, 0))))
6118                       && REGNO_POINTER_ALIGN (REGNO (base)) >= 32)
6119                     {
6120                       rtx new_rtx;
6122                       new_rtx = widen_memory_access (operands[1], SImode,
6123                                                      ((INTVAL (offset) & ~3)
6124                                                       - INTVAL (offset)));
6125                       emit_insn (gen_movsi (reg, new_rtx));
6126                       if (((INTVAL (offset) & 2) != 0)
6127                           ^ (BYTES_BIG_ENDIAN ? 1 : 0))
6128                         {
6129                           rtx reg2 = gen_reg_rtx (SImode);
6131                           emit_insn (gen_lshrsi3 (reg2, reg, GEN_INT (16)));
6132                           reg = reg2;
6133                         }
6134                     }
6135                   else
6136                     emit_insn (gen_movhi_bytes (reg, operands[1]));
6138                   operands[1] = gen_lowpart (HImode, reg);
6139                }
6140            }
6141         }
6142       /* Handle loading a large integer during reload.  */
6143       else if (CONST_INT_P (operands[1])
6144                && !const_ok_for_arm (INTVAL (operands[1]))
6145                && !const_ok_for_arm (~INTVAL (operands[1])))
6146         {
6147           /* Writing a constant to memory needs a scratch, which should
6148              be handled with SECONDARY_RELOADs.  */
6149           gcc_assert (REG_P (operands[0]));
6151           operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
6152           emit_insn (gen_movsi (operands[0], operands[1]));
6153           DONE;
6154        }
6155     }
6156   else if (TARGET_THUMB2)
6157     {
6158       /* Thumb-2 can do everything except mem=mem and mem=const easily.  */
6159       if (can_create_pseudo_p ())
6160         {
6161           if (!REG_P (operands[0]))
6162             operands[1] = force_reg (HImode, operands[1]);
6163           /* Zero extend a constant, and keep it in an SImode reg.  */
6164           else if (CONST_INT_P (operands[1]))
6165             {
6166               rtx reg = gen_reg_rtx (SImode);
6167               HOST_WIDE_INT val = INTVAL (operands[1]) & 0xffff;
6169               emit_insn (gen_movsi (reg, GEN_INT (val)));
6170               operands[1] = gen_lowpart (HImode, reg);
6171             }
6172         }
6173     }
6174   else /* TARGET_THUMB1 */
6175     {
6176       if (can_create_pseudo_p ())
6177         {
6178           if (CONST_INT_P (operands[1]))
6179             {
6180               rtx reg = gen_reg_rtx (SImode);
6182               emit_insn (gen_movsi (reg, operands[1]));
6183               operands[1] = gen_lowpart (HImode, reg);
6184             }
6186           /* ??? We shouldn't really get invalid addresses here, but this can
6187              happen if we are passed a SP (never OK for HImode/QImode) or 
6188              virtual register (also rejected as illegitimate for HImode/QImode)
6189              relative address.  */
6190           /* ??? This should perhaps be fixed elsewhere, for instance, in
6191              fixup_stack_1, by checking for other kinds of invalid addresses,
6192              e.g. a bare reference to a virtual register.  This may confuse the
6193              alpha though, which must handle this case differently.  */
6194           if (MEM_P (operands[0])
6195               && !memory_address_p (GET_MODE (operands[0]),
6196                                     XEXP (operands[0], 0)))
6197             operands[0]
6198               = replace_equiv_address (operands[0],
6199                                        copy_to_reg (XEXP (operands[0], 0)));
6200    
6201           if (MEM_P (operands[1])
6202               && !memory_address_p (GET_MODE (operands[1]),
6203                                     XEXP (operands[1], 0)))
6204             operands[1]
6205               = replace_equiv_address (operands[1],
6206                                        copy_to_reg (XEXP (operands[1], 0)));
6208           if (MEM_P (operands[1]) && optimize > 0)
6209             {
6210               rtx reg = gen_reg_rtx (SImode);
6212               emit_insn (gen_zero_extendhisi2 (reg, operands[1]));
6213               operands[1] = gen_lowpart (HImode, reg);
6214             }
6216           if (MEM_P (operands[0]))
6217             operands[1] = force_reg (HImode, operands[1]);
6218         }
6219       else if (CONST_INT_P (operands[1])
6220                 && !satisfies_constraint_I (operands[1]))
6221         {
6222           /* Handle loading a large integer during reload.  */
6224           /* Writing a constant to memory needs a scratch, which should
6225              be handled with SECONDARY_RELOADs.  */
6226           gcc_assert (REG_P (operands[0]));
6228           operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
6229           emit_insn (gen_movsi (operands[0], operands[1]));
6230           DONE;
6231         }
6232     }
6233   "
6236 (define_expand "movhi_bytes"
6237   [(set (match_dup 2) (zero_extend:SI (match_operand:HI 1 "" "")))
6238    (set (match_dup 3)
6239         (zero_extend:SI (match_dup 6)))
6240    (set (match_operand:SI 0 "" "")
6241          (ior:SI (ashift:SI (match_dup 4) (const_int 8)) (match_dup 5)))]
6242   "TARGET_ARM"
6243   "
6244   {
6245     rtx mem1, mem2;
6246     rtx addr = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
6248     mem1 = change_address (operands[1], QImode, addr);
6249     mem2 = change_address (operands[1], QImode,
6250                            plus_constant (Pmode, addr, 1));
6251     operands[0] = gen_lowpart (SImode, operands[0]);
6252     operands[1] = mem1;
6253     operands[2] = gen_reg_rtx (SImode);
6254     operands[3] = gen_reg_rtx (SImode);
6255     operands[6] = mem2;
6257     if (BYTES_BIG_ENDIAN)
6258       {
6259         operands[4] = operands[2];
6260         operands[5] = operands[3];
6261       }
6262     else
6263       {
6264         operands[4] = operands[3];
6265         operands[5] = operands[2];
6266       }
6267   }"
6270 (define_expand "movhi_bigend"
6271   [(set (match_dup 2)
6272         (rotate:SI (subreg:SI (match_operand:HI 1 "memory_operand" "") 0)
6273                    (const_int 16)))
6274    (set (match_dup 3)
6275         (ashiftrt:SI (match_dup 2) (const_int 16)))
6276    (set (match_operand:HI 0 "s_register_operand" "")
6277         (match_dup 4))]
6278   "TARGET_ARM"
6279   "
6280   operands[2] = gen_reg_rtx (SImode);
6281   operands[3] = gen_reg_rtx (SImode);
6282   operands[4] = gen_lowpart (HImode, operands[3]);
6283   "
6286 ;; Pattern to recognize insn generated default case above
6287 (define_insn "*movhi_insn_arch4"
6288   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,m,r")
6289         (match_operand:HI 1 "general_operand"      "rIk,K,r,mi"))]
6290   "TARGET_ARM
6291    && arm_arch4
6292    && (register_operand (operands[0], HImode)
6293        || register_operand (operands[1], HImode))"
6294   "@
6295    mov%?\\t%0, %1\\t%@ movhi
6296    mvn%?\\t%0, #%B1\\t%@ movhi
6297    str%(h%)\\t%1, %0\\t%@ movhi
6298    ldr%(h%)\\t%0, %1\\t%@ movhi"
6299   [(set_attr "predicable" "yes")
6300    (set_attr "pool_range" "*,*,*,256")
6301    (set_attr "neg_pool_range" "*,*,*,244")
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 "store1")
6308                           (const_string "load1")])]
6311 (define_insn "*movhi_bytes"
6312   [(set (match_operand:HI 0 "s_register_operand" "=r,r,r")
6313         (match_operand:HI 1 "arm_rhs_operand"  "I,rk,K"))]
6314   "TARGET_ARM"
6315   "@
6316    mov%?\\t%0, %1\\t%@ movhi
6317    mov%?\\t%0, %1\\t%@ movhi
6318    mvn%?\\t%0, #%B1\\t%@ movhi"
6319   [(set_attr "predicable" "yes")
6320    (set_attr "type" "mov_imm,mov_reg,mvn_imm")]
6322         
6323 ;; We use a DImode scratch because we may occasionally need an additional
6324 ;; temporary if the address isn't offsettable -- push_reload doesn't seem
6325 ;; to take any notice of the "o" constraints on reload_memory_operand operand.
6326 (define_expand "reload_outhi"
6327   [(parallel [(match_operand:HI 0 "arm_reload_memory_operand" "=o")
6328               (match_operand:HI 1 "s_register_operand"        "r")
6329               (match_operand:DI 2 "s_register_operand"        "=&l")])]
6330   "TARGET_EITHER"
6331   "if (TARGET_ARM)
6332      arm_reload_out_hi (operands);
6333    else
6334      thumb_reload_out_hi (operands);
6335   DONE;
6336   "
6339 (define_expand "reload_inhi"
6340   [(parallel [(match_operand:HI 0 "s_register_operand" "=r")
6341               (match_operand:HI 1 "arm_reload_memory_operand" "o")
6342               (match_operand:DI 2 "s_register_operand" "=&r")])]
6343   "TARGET_EITHER"
6344   "
6345   if (TARGET_ARM)
6346     arm_reload_in_hi (operands);
6347   else
6348     thumb_reload_out_hi (operands);
6349   DONE;
6352 (define_expand "movqi"
6353   [(set (match_operand:QI 0 "general_operand" "")
6354         (match_operand:QI 1 "general_operand" ""))]
6355   "TARGET_EITHER"
6356   "
6357   /* Everything except mem = const or mem = mem can be done easily */
6359   if (can_create_pseudo_p ())
6360     {
6361       if (CONST_INT_P (operands[1]))
6362         {
6363           rtx reg = gen_reg_rtx (SImode);
6365           /* For thumb we want an unsigned immediate, then we are more likely 
6366              to be able to use a movs insn.  */
6367           if (TARGET_THUMB)
6368             operands[1] = GEN_INT (INTVAL (operands[1]) & 255);
6370           emit_insn (gen_movsi (reg, operands[1]));
6371           operands[1] = gen_lowpart (QImode, reg);
6372         }
6374       if (TARGET_THUMB)
6375         {
6376           /* ??? We shouldn't really get invalid addresses here, but this can
6377              happen if we are passed a SP (never OK for HImode/QImode) or
6378              virtual register (also rejected as illegitimate for HImode/QImode)
6379              relative address.  */
6380           /* ??? This should perhaps be fixed elsewhere, for instance, in
6381              fixup_stack_1, by checking for other kinds of invalid addresses,
6382              e.g. a bare reference to a virtual register.  This may confuse the
6383              alpha though, which must handle this case differently.  */
6384           if (MEM_P (operands[0])
6385               && !memory_address_p (GET_MODE (operands[0]),
6386                                      XEXP (operands[0], 0)))
6387             operands[0]
6388               = replace_equiv_address (operands[0],
6389                                        copy_to_reg (XEXP (operands[0], 0)));
6390           if (MEM_P (operands[1])
6391               && !memory_address_p (GET_MODE (operands[1]),
6392                                     XEXP (operands[1], 0)))
6393              operands[1]
6394                = replace_equiv_address (operands[1],
6395                                         copy_to_reg (XEXP (operands[1], 0)));
6396         }
6398       if (MEM_P (operands[1]) && optimize > 0)
6399         {
6400           rtx reg = gen_reg_rtx (SImode);
6402           emit_insn (gen_zero_extendqisi2 (reg, operands[1]));
6403           operands[1] = gen_lowpart (QImode, reg);
6404         }
6406       if (MEM_P (operands[0]))
6407         operands[1] = force_reg (QImode, operands[1]);
6408     }
6409   else if (TARGET_THUMB
6410            && CONST_INT_P (operands[1])
6411            && !satisfies_constraint_I (operands[1]))
6412     {
6413       /* Handle loading a large integer during reload.  */
6415       /* Writing a constant to memory needs a scratch, which should
6416          be handled with SECONDARY_RELOADs.  */
6417       gcc_assert (REG_P (operands[0]));
6419       operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
6420       emit_insn (gen_movsi (operands[0], operands[1]));
6421       DONE;
6422     }
6423   "
6426 (define_insn "*arm_movqi_insn"
6427   [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,r,l,r,l,Uu,r,m")
6428         (match_operand:QI 1 "general_operand" "rk,rk,I,Py,K,Uu,l,m,r"))]
6429   "TARGET_32BIT
6430    && (   register_operand (operands[0], QImode)
6431        || register_operand (operands[1], QImode))"
6432   "@
6433    mov%?\\t%0, %1
6434    mov%?\\t%0, %1
6435    mov%?\\t%0, %1
6436    mov%?\\t%0, %1
6437    mvn%?\\t%0, #%B1
6438    ldr%(b%)\\t%0, %1
6439    str%(b%)\\t%1, %0
6440    ldr%(b%)\\t%0, %1
6441    str%(b%)\\t%1, %0"
6442   [(set_attr "type" "mov_reg,mov_reg,mov_imm,mov_imm,mvn_imm,load1,store1,load1,store1")
6443    (set_attr "predicable" "yes")
6444    (set_attr "predicable_short_it" "yes,yes,yes,no,no,no,no,no,no")
6445    (set_attr "arch" "t2,any,any,t2,any,t2,t2,any,any")
6446    (set_attr "length" "2,4,4,2,4,2,2,4,4")]
6449 ;; HFmode moves
6450 (define_expand "movhf"
6451   [(set (match_operand:HF 0 "general_operand" "")
6452         (match_operand:HF 1 "general_operand" ""))]
6453   "TARGET_EITHER"
6454   "
6455   if (TARGET_32BIT)
6456     {
6457       if (MEM_P (operands[0]))
6458         operands[1] = force_reg (HFmode, operands[1]);
6459     }
6460   else /* TARGET_THUMB1 */
6461     {
6462       if (can_create_pseudo_p ())
6463         {
6464            if (!REG_P (operands[0]))
6465              operands[1] = force_reg (HFmode, operands[1]);
6466         }
6467     }
6468   "
6471 (define_insn "*arm32_movhf"
6472   [(set (match_operand:HF 0 "nonimmediate_operand" "=r,m,r,r")
6473         (match_operand:HF 1 "general_operand"      " m,r,r,F"))]
6474   "TARGET_32BIT && !(TARGET_HARD_FLOAT && TARGET_FP16) && !arm_restrict_it
6475    && (   s_register_operand (operands[0], HFmode)
6476        || s_register_operand (operands[1], HFmode))"
6477   "*
6478   switch (which_alternative)
6479     {
6480     case 0:     /* ARM register from memory */
6481       return \"ldr%(h%)\\t%0, %1\\t%@ __fp16\";
6482     case 1:     /* memory from ARM register */
6483       return \"str%(h%)\\t%1, %0\\t%@ __fp16\";
6484     case 2:     /* ARM register from ARM register */
6485       return \"mov%?\\t%0, %1\\t%@ __fp16\";
6486     case 3:     /* ARM register from constant */
6487       {
6488         REAL_VALUE_TYPE r;
6489         long bits;
6490         rtx ops[4];
6492         REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
6493         bits = real_to_target (NULL, &r, HFmode);
6494         ops[0] = operands[0];
6495         ops[1] = GEN_INT (bits);
6496         ops[2] = GEN_INT (bits & 0xff00);
6497         ops[3] = GEN_INT (bits & 0x00ff);
6499         if (arm_arch_thumb2)
6500           output_asm_insn (\"movw%?\\t%0, %1\", ops);
6501         else
6502           output_asm_insn (\"mov%?\\t%0, %2\;orr%?\\t%0, %0, %3\", ops);
6503         return \"\";
6504        }
6505     default:
6506       gcc_unreachable ();
6507     }
6508   "
6509   [(set_attr "conds" "unconditional")
6510    (set_attr "type" "load1,store1,mov_reg,multiple")
6511    (set_attr "length" "4,4,4,8")
6512    (set_attr "predicable" "yes")]
6515 (define_expand "movsf"
6516   [(set (match_operand:SF 0 "general_operand" "")
6517         (match_operand:SF 1 "general_operand" ""))]
6518   "TARGET_EITHER"
6519   "
6520   if (TARGET_32BIT)
6521     {
6522       if (MEM_P (operands[0]))
6523         operands[1] = force_reg (SFmode, operands[1]);
6524     }
6525   else /* TARGET_THUMB1 */
6526     {
6527       if (can_create_pseudo_p ())
6528         {
6529            if (!REG_P (operands[0]))
6530              operands[1] = force_reg (SFmode, operands[1]);
6531         }
6532     }
6533   "
6536 ;; Transform a floating-point move of a constant into a core register into
6537 ;; an SImode operation.
6538 (define_split
6539   [(set (match_operand:SF 0 "arm_general_register_operand" "")
6540         (match_operand:SF 1 "immediate_operand" ""))]
6541   "TARGET_EITHER
6542    && reload_completed
6543    && CONST_DOUBLE_P (operands[1])"
6544   [(set (match_dup 2) (match_dup 3))]
6545   "
6546   operands[2] = gen_lowpart (SImode, operands[0]);
6547   operands[3] = gen_lowpart (SImode, operands[1]);
6548   if (operands[2] == 0 || operands[3] == 0)
6549     FAIL;
6550   "
6553 (define_insn "*arm_movsf_soft_insn"
6554   [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,m")
6555         (match_operand:SF 1 "general_operand"  "r,mE,r"))]
6556   "TARGET_32BIT
6557    && TARGET_SOFT_FLOAT
6558    && (!MEM_P (operands[0])
6559        || register_operand (operands[1], SFmode))"
6560   "@
6561    mov%?\\t%0, %1
6562    ldr%?\\t%0, %1\\t%@ float
6563    str%?\\t%1, %0\\t%@ float"
6564   [(set_attr "predicable" "yes")
6565    (set_attr "predicable_short_it" "no")
6566    (set_attr "type" "mov_reg,load1,store1")
6567    (set_attr "arm_pool_range" "*,4096,*")
6568    (set_attr "thumb2_pool_range" "*,4094,*")
6569    (set_attr "arm_neg_pool_range" "*,4084,*")
6570    (set_attr "thumb2_neg_pool_range" "*,0,*")]
6573 (define_expand "movdf"
6574   [(set (match_operand:DF 0 "general_operand" "")
6575         (match_operand:DF 1 "general_operand" ""))]
6576   "TARGET_EITHER"
6577   "
6578   if (TARGET_32BIT)
6579     {
6580       if (MEM_P (operands[0]))
6581         operands[1] = force_reg (DFmode, operands[1]);
6582     }
6583   else /* TARGET_THUMB */
6584     {
6585       if (can_create_pseudo_p ())
6586         {
6587           if (!REG_P (operands[0]))
6588             operands[1] = force_reg (DFmode, operands[1]);
6589         }
6590     }
6591   "
6594 ;; Reloading a df mode value stored in integer regs to memory can require a
6595 ;; scratch reg.
6596 (define_expand "reload_outdf"
6597   [(match_operand:DF 0 "arm_reload_memory_operand" "=o")
6598    (match_operand:DF 1 "s_register_operand" "r")
6599    (match_operand:SI 2 "s_register_operand" "=&r")]
6600   "TARGET_THUMB2"
6601   "
6602   {
6603     enum rtx_code code = GET_CODE (XEXP (operands[0], 0));
6605     if (code == REG)
6606       operands[2] = XEXP (operands[0], 0);
6607     else if (code == POST_INC || code == PRE_DEC)
6608       {
6609         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
6610         operands[1] = gen_rtx_SUBREG (DImode, operands[1], 0);
6611         emit_insn (gen_movdi (operands[0], operands[1]));
6612         DONE;
6613       }
6614     else if (code == PRE_INC)
6615       {
6616         rtx reg = XEXP (XEXP (operands[0], 0), 0);
6618         emit_insn (gen_addsi3 (reg, reg, GEN_INT (8)));
6619         operands[2] = reg;
6620       }
6621     else if (code == POST_DEC)
6622       operands[2] = XEXP (XEXP (operands[0], 0), 0);
6623     else
6624       emit_insn (gen_addsi3 (operands[2], XEXP (XEXP (operands[0], 0), 0),
6625                              XEXP (XEXP (operands[0], 0), 1)));
6627     emit_insn (gen_rtx_SET (VOIDmode,
6628                             replace_equiv_address (operands[0], operands[2]),
6629                             operands[1]));
6631     if (code == POST_DEC)
6632       emit_insn (gen_addsi3 (operands[2], operands[2], GEN_INT (-8)));
6634     DONE;
6635   }"
6638 (define_insn "*movdf_soft_insn"
6639   [(set (match_operand:DF 0 "nonimmediate_soft_df_operand" "=r,r,r,q,m")
6640         (match_operand:DF 1 "soft_df_operand" "rDa,Db,Dc,mF,q"))]
6641   "TARGET_32BIT && TARGET_SOFT_FLOAT
6642    && (   register_operand (operands[0], DFmode)
6643        || register_operand (operands[1], DFmode))"
6644   "*
6645   switch (which_alternative)
6646     {
6647     case 0:
6648     case 1:
6649     case 2:
6650       return \"#\";
6651     default:
6652       return output_move_double (operands, true, NULL);
6653     }
6654   "
6655   [(set_attr "length" "8,12,16,8,8")
6656    (set_attr "type" "multiple,multiple,multiple,load2,store2")
6657    (set_attr "arm_pool_range" "*,*,*,1020,*")
6658    (set_attr "thumb2_pool_range" "*,*,*,1018,*")
6659    (set_attr "arm_neg_pool_range" "*,*,*,1004,*")
6660    (set_attr "thumb2_neg_pool_range" "*,*,*,0,*")]
6664 ;; load- and store-multiple insns
6665 ;; The arm can load/store any set of registers, provided that they are in
6666 ;; ascending order, but these expanders assume a contiguous set.
6668 (define_expand "load_multiple"
6669   [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
6670                           (match_operand:SI 1 "" ""))
6671                      (use (match_operand:SI 2 "" ""))])]
6672   "TARGET_32BIT"
6674   HOST_WIDE_INT offset = 0;
6676   /* Support only fixed point registers.  */
6677   if (!CONST_INT_P (operands[2])
6678       || INTVAL (operands[2]) > 14
6679       || INTVAL (operands[2]) < 2
6680       || !MEM_P (operands[1])
6681       || !REG_P (operands[0])
6682       || REGNO (operands[0]) > (LAST_ARM_REGNUM - 1)
6683       || REGNO (operands[0]) + INTVAL (operands[2]) > LAST_ARM_REGNUM)
6684     FAIL;
6686   operands[3]
6687     = arm_gen_load_multiple (arm_regs_in_sequence + REGNO (operands[0]),
6688                              INTVAL (operands[2]),
6689                              force_reg (SImode, XEXP (operands[1], 0)),
6690                              FALSE, operands[1], &offset);
6693 (define_expand "store_multiple"
6694   [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
6695                           (match_operand:SI 1 "" ""))
6696                      (use (match_operand:SI 2 "" ""))])]
6697   "TARGET_32BIT"
6699   HOST_WIDE_INT offset = 0;
6701   /* Support only fixed point registers.  */
6702   if (!CONST_INT_P (operands[2])
6703       || INTVAL (operands[2]) > 14
6704       || INTVAL (operands[2]) < 2
6705       || !REG_P (operands[1])
6706       || !MEM_P (operands[0])
6707       || REGNO (operands[1]) > (LAST_ARM_REGNUM - 1)
6708       || REGNO (operands[1]) + INTVAL (operands[2]) > LAST_ARM_REGNUM)
6709     FAIL;
6711   operands[3]
6712     = arm_gen_store_multiple (arm_regs_in_sequence + REGNO (operands[1]),
6713                               INTVAL (operands[2]),
6714                               force_reg (SImode, XEXP (operands[0], 0)),
6715                               FALSE, operands[0], &offset);
6719 ;; Move a block of memory if it is word aligned and MORE than 2 words long.
6720 ;; We could let this apply for blocks of less than this, but it clobbers so
6721 ;; many registers that there is then probably a better way.
6723 (define_expand "movmemqi"
6724   [(match_operand:BLK 0 "general_operand" "")
6725    (match_operand:BLK 1 "general_operand" "")
6726    (match_operand:SI 2 "const_int_operand" "")
6727    (match_operand:SI 3 "const_int_operand" "")]
6728   ""
6729   "
6730   if (TARGET_32BIT)
6731     {
6732       if (TARGET_LDRD && current_tune->prefer_ldrd_strd
6733           && !optimize_function_for_size_p (cfun))
6734         {
6735           if (gen_movmem_ldrd_strd (operands))
6736             DONE;
6737           FAIL;
6738         }
6740       if (arm_gen_movmemqi (operands))
6741         DONE;
6742       FAIL;
6743     }
6744   else /* TARGET_THUMB1 */
6745     {
6746       if (   INTVAL (operands[3]) != 4
6747           || INTVAL (operands[2]) > 48)
6748         FAIL;
6750       thumb_expand_movmemqi (operands);
6751       DONE;
6752     }
6753   "
6757 ;; Compare & branch insns
6758 ;; The range calculations are based as follows:
6759 ;; For forward branches, the address calculation returns the address of
6760 ;; the next instruction.  This is 2 beyond the branch instruction.
6761 ;; For backward branches, the address calculation returns the address of
6762 ;; the first instruction in this pattern (cmp).  This is 2 before the branch
6763 ;; instruction for the shortest sequence, and 4 before the branch instruction
6764 ;; if we have to jump around an unconditional branch.
6765 ;; To the basic branch range the PC offset must be added (this is +4).
6766 ;; So for forward branches we have 
6767 ;;   (pos_range - pos_base_offs + pc_offs) = (pos_range - 2 + 4).
6768 ;; And for backward branches we have 
6769 ;;   (neg_range - neg_base_offs + pc_offs) = (neg_range - (-2 or -4) + 4).
6771 ;; For a 'b'       pos_range = 2046, neg_range = -2048 giving (-2040->2048).
6772 ;; For a 'b<cond>' pos_range = 254,  neg_range = -256  giving (-250 ->256).
6774 (define_expand "cbranchsi4"
6775   [(set (pc) (if_then_else
6776               (match_operator 0 "expandable_comparison_operator"
6777                [(match_operand:SI 1 "s_register_operand" "")
6778                 (match_operand:SI 2 "nonmemory_operand" "")])
6779               (label_ref (match_operand 3 "" ""))
6780               (pc)))]
6781   "TARGET_EITHER"
6782   "
6783   if (!TARGET_THUMB1)
6784     {
6785       if (!arm_validize_comparison (&operands[0], &operands[1], &operands[2]))
6786         FAIL;
6787       emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
6788                                       operands[3]));
6789       DONE;
6790     }
6791   if (thumb1_cmpneg_operand (operands[2], SImode))
6792     {
6793       emit_jump_insn (gen_cbranchsi4_scratch (NULL, operands[1], operands[2],
6794                                               operands[3], operands[0]));
6795       DONE;
6796     }
6797   if (!thumb1_cmp_operand (operands[2], SImode))
6798     operands[2] = force_reg (SImode, operands[2]);
6799   ")
6801 (define_expand "cbranchsf4"
6802   [(set (pc) (if_then_else
6803               (match_operator 0 "expandable_comparison_operator"
6804                [(match_operand:SF 1 "s_register_operand" "")
6805                 (match_operand:SF 2 "arm_float_compare_operand" "")])
6806               (label_ref (match_operand 3 "" ""))
6807               (pc)))]
6808   "TARGET_32BIT && TARGET_HARD_FLOAT"
6809   "emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
6810                                    operands[3])); DONE;"
6813 (define_expand "cbranchdf4"
6814   [(set (pc) (if_then_else
6815               (match_operator 0 "expandable_comparison_operator"
6816                [(match_operand:DF 1 "s_register_operand" "")
6817                 (match_operand:DF 2 "arm_float_compare_operand" "")])
6818               (label_ref (match_operand 3 "" ""))
6819               (pc)))]
6820   "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
6821   "emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
6822                                    operands[3])); DONE;"
6825 (define_expand "cbranchdi4"
6826   [(set (pc) (if_then_else
6827               (match_operator 0 "expandable_comparison_operator"
6828                [(match_operand:DI 1 "s_register_operand" "")
6829                 (match_operand:DI 2 "cmpdi_operand" "")])
6830               (label_ref (match_operand 3 "" ""))
6831               (pc)))]
6832   "TARGET_32BIT"
6833   "{
6834      if (!arm_validize_comparison (&operands[0], &operands[1], &operands[2]))
6835        FAIL;
6836      emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
6837                                        operands[3]));
6838      DONE;
6839    }"
6842 ;; Comparison and test insns
6844 (define_insn "*arm_cmpsi_insn"
6845   [(set (reg:CC CC_REGNUM)
6846         (compare:CC (match_operand:SI 0 "s_register_operand" "l,r,r,r,r")
6847                     (match_operand:SI 1 "arm_add_operand"    "Py,r,r,I,L")))]
6848   "TARGET_32BIT"
6849   "@
6850    cmp%?\\t%0, %1
6851    cmp%?\\t%0, %1
6852    cmp%?\\t%0, %1
6853    cmp%?\\t%0, %1
6854    cmn%?\\t%0, #%n1"
6855   [(set_attr "conds" "set")
6856    (set_attr "arch" "t2,t2,any,any,any")
6857    (set_attr "length" "2,2,4,4,4")
6858    (set_attr "predicable" "yes")
6859    (set_attr "predicable_short_it" "yes,yes,yes,no,no")
6860    (set_attr "type" "alus_imm,alus_sreg,alus_sreg,alus_imm,alus_imm")]
6863 (define_insn "*cmpsi_shiftsi"
6864   [(set (reg:CC CC_REGNUM)
6865         (compare:CC (match_operand:SI   0 "s_register_operand" "r,r,r")
6866                     (match_operator:SI  3 "shift_operator"
6867                      [(match_operand:SI 1 "s_register_operand" "r,r,r")
6868                       (match_operand:SI 2 "shift_amount_operand" "M,r,M")])))]
6869   "TARGET_32BIT"
6870   "cmp\\t%0, %1%S3"
6871   [(set_attr "conds" "set")
6872    (set_attr "shift" "1")
6873    (set_attr "arch" "32,a,a")
6874    (set_attr "type" "alus_shift_imm,alu_shift_reg,alus_shift_imm")])
6876 (define_insn "*cmpsi_shiftsi_swp"
6877   [(set (reg:CC_SWP CC_REGNUM)
6878         (compare:CC_SWP (match_operator:SI 3 "shift_operator"
6879                          [(match_operand:SI 1 "s_register_operand" "r,r,r")
6880                           (match_operand:SI 2 "shift_amount_operand" "M,r,M")])
6881                         (match_operand:SI 0 "s_register_operand" "r,r,r")))]
6882   "TARGET_32BIT"
6883   "cmp%?\\t%0, %1%S3"
6884   [(set_attr "conds" "set")
6885    (set_attr "shift" "1")
6886    (set_attr "arch" "32,a,a")
6887    (set_attr "type" "alus_shift_imm,alu_shift_reg,alus_shift_imm")])
6889 (define_insn "*arm_cmpsi_negshiftsi_si"
6890   [(set (reg:CC_Z CC_REGNUM)
6891         (compare:CC_Z
6892          (neg:SI (match_operator:SI 1 "shift_operator"
6893                     [(match_operand:SI 2 "s_register_operand" "r")
6894                      (match_operand:SI 3 "reg_or_int_operand" "rM")]))
6895          (match_operand:SI 0 "s_register_operand" "r")))]
6896   "TARGET_ARM"
6897   "cmn%?\\t%0, %2%S1"
6898   [(set_attr "conds" "set")
6899    (set (attr "type") (if_then_else (match_operand 3 "const_int_operand" "")
6900                                     (const_string "alus_shift_imm")
6901                                     (const_string "alus_shift_reg")))
6902    (set_attr "predicable" "yes")]
6905 ;; DImode comparisons.  The generic code generates branches that
6906 ;; if-conversion can not reduce to a conditional compare, so we do
6907 ;; that directly.
6909 (define_insn_and_split "*arm_cmpdi_insn"
6910   [(set (reg:CC_NCV CC_REGNUM)
6911         (compare:CC_NCV (match_operand:DI 0 "s_register_operand" "r")
6912                         (match_operand:DI 1 "arm_di_operand"       "rDi")))
6913    (clobber (match_scratch:SI 2 "=r"))]
6914   "TARGET_32BIT"
6915   "#"   ; "cmp\\t%Q0, %Q1\;sbcs\\t%2, %R0, %R1"
6916   "&& reload_completed"
6917   [(set (reg:CC CC_REGNUM)
6918         (compare:CC (match_dup 0) (match_dup 1)))
6919    (parallel [(set (reg:CC CC_REGNUM)
6920                    (compare:CC (match_dup 3) (match_dup 4)))
6921               (set (match_dup 2)
6922                    (minus:SI (match_dup 5)
6923                             (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))])]
6924   {
6925     operands[3] = gen_highpart (SImode, operands[0]);
6926     operands[0] = gen_lowpart (SImode, operands[0]);
6927     if (CONST_INT_P (operands[1]))
6928       {
6929         operands[4] = GEN_INT (~INTVAL (gen_highpart_mode (SImode,
6930                                                            DImode,
6931                                                            operands[1])));
6932         operands[5] = gen_rtx_PLUS (SImode, operands[3], operands[4]);
6933       }
6934     else
6935       {
6936         operands[4] = gen_highpart (SImode, operands[1]);
6937         operands[5] = gen_rtx_MINUS (SImode, operands[3], operands[4]);
6938       }
6939     operands[1] = gen_lowpart (SImode, operands[1]);
6940     operands[2] = gen_lowpart (SImode, operands[2]);
6941   }
6942   [(set_attr "conds" "set")
6943    (set_attr "length" "8")
6944    (set_attr "type" "multiple")]
6947 (define_insn_and_split "*arm_cmpdi_unsigned"
6948   [(set (reg:CC_CZ CC_REGNUM)
6949         (compare:CC_CZ (match_operand:DI 0 "s_register_operand" "l,r,r,r")
6950                        (match_operand:DI 1 "arm_di_operand"     "Py,r,Di,rDi")))]
6952   "TARGET_32BIT"
6953   "#"   ; "cmp\\t%R0, %R1\;it eq\;cmpeq\\t%Q0, %Q1"
6954   "&& reload_completed"
6955   [(set (reg:CC CC_REGNUM)
6956         (compare:CC (match_dup 2) (match_dup 3)))
6957    (cond_exec (eq:SI (reg:CC CC_REGNUM) (const_int 0))
6958               (set (reg:CC CC_REGNUM)
6959                    (compare:CC (match_dup 0) (match_dup 1))))]
6960   {
6961     operands[2] = gen_highpart (SImode, operands[0]);
6962     operands[0] = gen_lowpart (SImode, operands[0]);
6963     if (CONST_INT_P (operands[1]))
6964       operands[3] = gen_highpart_mode (SImode, DImode, operands[1]);
6965     else
6966       operands[3] = gen_highpart (SImode, operands[1]);
6967     operands[1] = gen_lowpart (SImode, operands[1]);
6968   }
6969   [(set_attr "conds" "set")
6970    (set_attr "enabled_for_depr_it" "yes,yes,no,*")
6971    (set_attr "arch" "t2,t2,t2,a")
6972    (set_attr "length" "6,6,10,8")
6973    (set_attr "type" "multiple")]
6976 (define_insn "*arm_cmpdi_zero"
6977   [(set (reg:CC_Z CC_REGNUM)
6978         (compare:CC_Z (match_operand:DI 0 "s_register_operand" "r")
6979                       (const_int 0)))
6980    (clobber (match_scratch:SI 1 "=r"))]
6981   "TARGET_32BIT"
6982   "orr%.\\t%1, %Q0, %R0"
6983   [(set_attr "conds" "set")
6984    (set_attr "type" "logics_reg")]
6987 ; This insn allows redundant compares to be removed by cse, nothing should
6988 ; ever appear in the output file since (set (reg x) (reg x)) is a no-op that
6989 ; is deleted later on. The match_dup will match the mode here, so that
6990 ; mode changes of the condition codes aren't lost by this even though we don't
6991 ; specify what they are.
6993 (define_insn "*deleted_compare"
6994   [(set (match_operand 0 "cc_register" "") (match_dup 0))]
6995   "TARGET_32BIT"
6996   "\\t%@ deleted compare"
6997   [(set_attr "conds" "set")
6998    (set_attr "length" "0")
6999    (set_attr "type" "no_insn")]
7003 ;; Conditional branch insns
7005 (define_expand "cbranch_cc"
7006   [(set (pc)
7007         (if_then_else (match_operator 0 "" [(match_operand 1 "" "")
7008                                             (match_operand 2 "" "")])
7009                       (label_ref (match_operand 3 "" ""))
7010                       (pc)))]
7011   "TARGET_32BIT"
7012   "operands[1] = arm_gen_compare_reg (GET_CODE (operands[0]),
7013                                       operands[1], operands[2], NULL_RTX);
7014    operands[2] = const0_rtx;"
7018 ;; Patterns to match conditional branch insns.
7021 (define_insn "arm_cond_branch"
7022   [(set (pc)
7023         (if_then_else (match_operator 1 "arm_comparison_operator"
7024                        [(match_operand 2 "cc_register" "") (const_int 0)])
7025                       (label_ref (match_operand 0 "" ""))
7026                       (pc)))]
7027   "TARGET_32BIT"
7028   "*
7029   if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
7030     {
7031       arm_ccfsm_state += 2;
7032       return \"\";
7033     }
7034   return \"b%d1\\t%l0\";
7035   "
7036   [(set_attr "conds" "use")
7037    (set_attr "type" "branch")
7038    (set (attr "length")
7039         (if_then_else
7040            (and (match_test "TARGET_THUMB2")
7041                 (and (ge (minus (match_dup 0) (pc)) (const_int -250))
7042                      (le (minus (match_dup 0) (pc)) (const_int 256))))
7043            (const_int 2)
7044            (const_int 4)))]
7047 (define_insn "*arm_cond_branch_reversed"
7048   [(set (pc)
7049         (if_then_else (match_operator 1 "arm_comparison_operator"
7050                        [(match_operand 2 "cc_register" "") (const_int 0)])
7051                       (pc)
7052                       (label_ref (match_operand 0 "" ""))))]
7053   "TARGET_32BIT"
7054   "*
7055   if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
7056     {
7057       arm_ccfsm_state += 2;
7058       return \"\";
7059     }
7060   return \"b%D1\\t%l0\";
7061   "
7062   [(set_attr "conds" "use")
7063    (set_attr "type" "branch")
7064    (set (attr "length")
7065         (if_then_else
7066            (and (match_test "TARGET_THUMB2")
7067                 (and (ge (minus (match_dup 0) (pc)) (const_int -250))
7068                      (le (minus (match_dup 0) (pc)) (const_int 256))))
7069            (const_int 2)
7070            (const_int 4)))]
7075 ; scc insns
7077 (define_expand "cstore_cc"
7078   [(set (match_operand:SI 0 "s_register_operand" "")
7079         (match_operator:SI 1 "" [(match_operand 2 "" "")
7080                                  (match_operand 3 "" "")]))]
7081   "TARGET_32BIT"
7082   "operands[2] = arm_gen_compare_reg (GET_CODE (operands[1]),
7083                                       operands[2], operands[3], NULL_RTX);
7084    operands[3] = const0_rtx;"
7087 (define_insn_and_split "*mov_scc"
7088   [(set (match_operand:SI 0 "s_register_operand" "=r")
7089         (match_operator:SI 1 "arm_comparison_operator"
7090          [(match_operand 2 "cc_register" "") (const_int 0)]))]
7091   "TARGET_ARM"
7092   "#"   ; "mov%D1\\t%0, #0\;mov%d1\\t%0, #1"
7093   "TARGET_ARM"
7094   [(set (match_dup 0)
7095         (if_then_else:SI (match_dup 1)
7096                          (const_int 1)
7097                          (const_int 0)))]
7098   ""
7099   [(set_attr "conds" "use")
7100    (set_attr "length" "8")
7101    (set_attr "type" "multiple")]
7104 (define_insn_and_split "*mov_negscc"
7105   [(set (match_operand:SI 0 "s_register_operand" "=r")
7106         (neg:SI (match_operator:SI 1 "arm_comparison_operator"
7107                  [(match_operand 2 "cc_register" "") (const_int 0)])))]
7108   "TARGET_ARM"
7109   "#"   ; "mov%D1\\t%0, #0\;mvn%d1\\t%0, #0"
7110   "TARGET_ARM"
7111   [(set (match_dup 0)
7112         (if_then_else:SI (match_dup 1)
7113                          (match_dup 3)
7114                          (const_int 0)))]
7115   {
7116     operands[3] = GEN_INT (~0);
7117   }
7118   [(set_attr "conds" "use")
7119    (set_attr "length" "8")
7120    (set_attr "type" "multiple")]
7123 (define_insn_and_split "*mov_notscc"
7124   [(set (match_operand:SI 0 "s_register_operand" "=r")
7125         (not:SI (match_operator:SI 1 "arm_comparison_operator"
7126                  [(match_operand 2 "cc_register" "") (const_int 0)])))]
7127   "TARGET_ARM"
7128   "#"   ; "mvn%D1\\t%0, #0\;mvn%d1\\t%0, #1"
7129   "TARGET_ARM"
7130   [(set (match_dup 0)
7131         (if_then_else:SI (match_dup 1)
7132                          (match_dup 3)
7133                          (match_dup 4)))]
7134   {
7135     operands[3] = GEN_INT (~1);
7136     operands[4] = GEN_INT (~0);
7137   }
7138   [(set_attr "conds" "use")
7139    (set_attr "length" "8")
7140    (set_attr "type" "multiple")]
7143 (define_expand "cstoresi4"
7144   [(set (match_operand:SI 0 "s_register_operand" "")
7145         (match_operator:SI 1 "expandable_comparison_operator"
7146          [(match_operand:SI 2 "s_register_operand" "")
7147           (match_operand:SI 3 "reg_or_int_operand" "")]))]
7148   "TARGET_32BIT || TARGET_THUMB1"
7149   "{
7150   rtx op3, scratch, scratch2;
7152   if (!TARGET_THUMB1)
7153     {
7154       if (!arm_add_operand (operands[3], SImode))
7155         operands[3] = force_reg (SImode, operands[3]);
7156       emit_insn (gen_cstore_cc (operands[0], operands[1],
7157                                 operands[2], operands[3]));
7158       DONE;
7159     }
7161   if (operands[3] == const0_rtx)
7162     {
7163       switch (GET_CODE (operands[1]))
7164         {
7165         case EQ:
7166           emit_insn (gen_cstoresi_eq0_thumb1 (operands[0], operands[2]));
7167           break;
7169         case NE:
7170           emit_insn (gen_cstoresi_ne0_thumb1 (operands[0], operands[2]));
7171           break;
7173         case LE:
7174           scratch = expand_binop (SImode, add_optab, operands[2], constm1_rtx,
7175                                   NULL_RTX, 0, OPTAB_WIDEN);
7176           scratch = expand_binop (SImode, ior_optab, operands[2], scratch,
7177                                   NULL_RTX, 0, OPTAB_WIDEN);
7178           expand_binop (SImode, lshr_optab, scratch, GEN_INT (31),
7179                         operands[0], 1, OPTAB_WIDEN);
7180           break;
7182         case GE:
7183           scratch = expand_unop (SImode, one_cmpl_optab, operands[2],
7184                                  NULL_RTX, 1);
7185           expand_binop (SImode, lshr_optab, scratch, GEN_INT (31),
7186                         NULL_RTX, 1, OPTAB_WIDEN);
7187           break;
7189         case GT:
7190           scratch = expand_binop (SImode, ashr_optab, operands[2],
7191                                   GEN_INT (31), NULL_RTX, 0, OPTAB_WIDEN);
7192           scratch = expand_binop (SImode, sub_optab, scratch, operands[2],
7193                                   NULL_RTX, 0, OPTAB_WIDEN);
7194           expand_binop (SImode, lshr_optab, scratch, GEN_INT (31), operands[0],
7195                         0, OPTAB_WIDEN);
7196           break;
7198         /* LT is handled by generic code.  No need for unsigned with 0.  */
7199         default:
7200           FAIL;
7201         }
7202       DONE;
7203     }
7205   switch (GET_CODE (operands[1]))
7206     {
7207     case EQ:
7208       scratch = expand_binop (SImode, sub_optab, operands[2], operands[3],
7209                               NULL_RTX, 0, OPTAB_WIDEN);
7210       emit_insn (gen_cstoresi_eq0_thumb1 (operands[0], scratch));
7211       break;
7213     case NE:
7214       scratch = expand_binop (SImode, sub_optab, operands[2], operands[3],
7215                               NULL_RTX, 0, OPTAB_WIDEN);
7216       emit_insn (gen_cstoresi_ne0_thumb1 (operands[0], scratch));
7217       break;
7219     case LE:
7220       op3 = force_reg (SImode, operands[3]);
7222       scratch = expand_binop (SImode, lshr_optab, operands[2], GEN_INT (31),
7223                               NULL_RTX, 1, OPTAB_WIDEN);
7224       scratch2 = expand_binop (SImode, ashr_optab, op3, GEN_INT (31),
7225                               NULL_RTX, 0, OPTAB_WIDEN);
7226       emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch2,
7227                                           op3, operands[2]));
7228       break;
7230     case GE:
7231       op3 = operands[3];
7232       if (!thumb1_cmp_operand (op3, SImode))
7233         op3 = force_reg (SImode, op3);
7234       scratch = expand_binop (SImode, ashr_optab, operands[2], GEN_INT (31),
7235                               NULL_RTX, 0, OPTAB_WIDEN);
7236       scratch2 = expand_binop (SImode, lshr_optab, op3, GEN_INT (31),
7237                                NULL_RTX, 1, OPTAB_WIDEN);
7238       emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch2,
7239                                           operands[2], op3));
7240       break;
7242     case LEU:
7243       op3 = force_reg (SImode, operands[3]);
7244       scratch = force_reg (SImode, const0_rtx);
7245       emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch,
7246                                           op3, operands[2]));
7247       break;
7249     case GEU:
7250       op3 = operands[3];
7251       if (!thumb1_cmp_operand (op3, SImode))
7252         op3 = force_reg (SImode, op3);
7253       scratch = force_reg (SImode, const0_rtx);
7254       emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch,
7255                                           operands[2], op3));
7256       break;
7258     case LTU:
7259       op3 = operands[3];
7260       if (!thumb1_cmp_operand (op3, SImode))
7261         op3 = force_reg (SImode, op3);
7262       scratch = gen_reg_rtx (SImode);
7263       emit_insn (gen_cstoresi_ltu_thumb1 (operands[0], operands[2], op3));
7264       break;
7266     case GTU:
7267       op3 = force_reg (SImode, operands[3]);
7268       scratch = gen_reg_rtx (SImode);
7269       emit_insn (gen_cstoresi_ltu_thumb1 (operands[0], op3, operands[2]));
7270       break;
7272     /* No good sequences for GT, LT.  */
7273     default:
7274       FAIL;
7275     }
7276   DONE;
7279 (define_expand "cstoresf4"
7280   [(set (match_operand:SI 0 "s_register_operand" "")
7281         (match_operator:SI 1 "expandable_comparison_operator"
7282          [(match_operand:SF 2 "s_register_operand" "")
7283           (match_operand:SF 3 "arm_float_compare_operand" "")]))]
7284   "TARGET_32BIT && TARGET_HARD_FLOAT"
7285   "emit_insn (gen_cstore_cc (operands[0], operands[1],
7286                              operands[2], operands[3])); DONE;"
7289 (define_expand "cstoredf4"
7290   [(set (match_operand:SI 0 "s_register_operand" "")
7291         (match_operator:SI 1 "expandable_comparison_operator"
7292          [(match_operand:DF 2 "s_register_operand" "")
7293           (match_operand:DF 3 "arm_float_compare_operand" "")]))]
7294   "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
7295   "emit_insn (gen_cstore_cc (operands[0], operands[1],
7296                              operands[2], operands[3])); DONE;"
7299 (define_expand "cstoredi4"
7300   [(set (match_operand:SI 0 "s_register_operand" "")
7301         (match_operator:SI 1 "expandable_comparison_operator"
7302          [(match_operand:DI 2 "s_register_operand" "")
7303           (match_operand:DI 3 "cmpdi_operand" "")]))]
7304   "TARGET_32BIT"
7305   "{
7306      if (!arm_validize_comparison (&operands[1],
7307                                    &operands[2],
7308                                    &operands[3]))
7309        FAIL;
7310      emit_insn (gen_cstore_cc (operands[0], operands[1], operands[2],
7311                                  operands[3]));
7312      DONE;
7313    }"
7317 ;; Conditional move insns
7319 (define_expand "movsicc"
7320   [(set (match_operand:SI 0 "s_register_operand" "")
7321         (if_then_else:SI (match_operand 1 "expandable_comparison_operator" "")
7322                          (match_operand:SI 2 "arm_not_operand" "")
7323                          (match_operand:SI 3 "arm_not_operand" "")))]
7324   "TARGET_32BIT"
7325   "
7326   {
7327     enum rtx_code code;
7328     rtx ccreg;
7330     if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0), 
7331                                   &XEXP (operands[1], 1)))
7332       FAIL;
7333     
7334     code = GET_CODE (operands[1]);
7335     ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
7336                                  XEXP (operands[1], 1), NULL_RTX);
7337     operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7338   }"
7341 (define_expand "movsfcc"
7342   [(set (match_operand:SF 0 "s_register_operand" "")
7343         (if_then_else:SF (match_operand 1 "arm_cond_move_operator" "")
7344                          (match_operand:SF 2 "s_register_operand" "")
7345                          (match_operand:SF 3 "s_register_operand" "")))]
7346   "TARGET_32BIT && TARGET_HARD_FLOAT"
7347   "
7348   {
7349     enum rtx_code code = GET_CODE (operands[1]);
7350     rtx ccreg;
7352     if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0), 
7353                                   &XEXP (operands[1], 1)))
7354        FAIL;
7356     code = GET_CODE (operands[1]);
7357     ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
7358                                  XEXP (operands[1], 1), NULL_RTX);
7359     operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7360   }"
7363 (define_expand "movdfcc"
7364   [(set (match_operand:DF 0 "s_register_operand" "")
7365         (if_then_else:DF (match_operand 1 "arm_cond_move_operator" "")
7366                          (match_operand:DF 2 "s_register_operand" "")
7367                          (match_operand:DF 3 "s_register_operand" "")))]
7368   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
7369   "
7370   {
7371     enum rtx_code code = GET_CODE (operands[1]);
7372     rtx ccreg;
7374     if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0), 
7375                                   &XEXP (operands[1], 1)))
7376        FAIL;
7377     code = GET_CODE (operands[1]);
7378     ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
7379                                  XEXP (operands[1], 1), NULL_RTX);
7380     operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7381   }"
7384 (define_insn "*cmov<mode>"
7385     [(set (match_operand:SDF 0 "s_register_operand" "=<F_constraint>")
7386         (if_then_else:SDF (match_operator 1 "arm_vsel_comparison_operator"
7387                           [(match_operand 2 "cc_register" "") (const_int 0)])
7388                           (match_operand:SDF 3 "s_register_operand"
7389                                               "<F_constraint>")
7390                           (match_operand:SDF 4 "s_register_operand"
7391                                               "<F_constraint>")))]
7392   "TARGET_HARD_FLOAT && TARGET_FPU_ARMV8 <vfp_double_cond>"
7393   "*
7394   {
7395     enum arm_cond_code code = maybe_get_arm_condition_code (operands[1]);
7396     switch (code)
7397       {
7398       case ARM_GE:
7399       case ARM_GT:
7400       case ARM_EQ:
7401       case ARM_VS:
7402         return \"vsel%d1.<V_if_elem>\\t%<V_reg>0, %<V_reg>3, %<V_reg>4\";
7403       case ARM_LT:
7404       case ARM_LE:
7405       case ARM_NE:
7406       case ARM_VC:
7407         return \"vsel%D1.<V_if_elem>\\t%<V_reg>0, %<V_reg>4, %<V_reg>3\";
7408       default:
7409         gcc_unreachable ();
7410       }
7411     return \"\";
7412   }"
7413   [(set_attr "conds" "use")
7414    (set_attr "type" "f_sel<vfp_type>")]
7417 (define_insn_and_split "*movsicc_insn"
7418   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r,r,r,r,r")
7419         (if_then_else:SI
7420          (match_operator 3 "arm_comparison_operator"
7421           [(match_operand 4 "cc_register" "") (const_int 0)])
7422          (match_operand:SI 1 "arm_not_operand" "0,0,rI,K,rI,rI,K,K")
7423          (match_operand:SI 2 "arm_not_operand" "rI,K,0,0,rI,K,rI,K")))]
7424   "TARGET_ARM"
7425   "@
7426    mov%D3\\t%0, %2
7427    mvn%D3\\t%0, #%B2
7428    mov%d3\\t%0, %1
7429    mvn%d3\\t%0, #%B1
7430    #
7431    #
7432    #
7433    #"
7434    ; alt4: mov%d3\\t%0, %1\;mov%D3\\t%0, %2
7435    ; alt5: mov%d3\\t%0, %1\;mvn%D3\\t%0, #%B2
7436    ; alt6: mvn%d3\\t%0, #%B1\;mov%D3\\t%0, %2
7437    ; alt7: mvn%d3\\t%0, #%B1\;mvn%D3\\t%0, #%B2"
7438   "&& reload_completed"
7439   [(const_int 0)]
7440   {
7441     enum rtx_code rev_code;
7442     enum machine_mode mode;
7443     rtx rev_cond;
7445     emit_insn (gen_rtx_COND_EXEC (VOIDmode,
7446                                   operands[3],
7447                                   gen_rtx_SET (VOIDmode,
7448                                                operands[0],
7449                                                operands[1])));
7451     rev_code = GET_CODE (operands[3]);
7452     mode = GET_MODE (operands[4]);
7453     if (mode == CCFPmode || mode == CCFPEmode)
7454       rev_code = reverse_condition_maybe_unordered (rev_code);
7455     else
7456       rev_code = reverse_condition (rev_code);
7458     rev_cond = gen_rtx_fmt_ee (rev_code,
7459                                VOIDmode,
7460                                operands[4],
7461                                const0_rtx);
7462     emit_insn (gen_rtx_COND_EXEC (VOIDmode,
7463                                   rev_cond,
7464                                   gen_rtx_SET (VOIDmode,
7465                                                operands[0],
7466                                                operands[2])));
7467     DONE;
7468   }
7469   [(set_attr "length" "4,4,4,4,8,8,8,8")
7470    (set_attr "conds" "use")
7471    (set_attr_alternative "type"
7472                          [(if_then_else (match_operand 2 "const_int_operand" "")
7473                                         (const_string "mov_imm")
7474                                         (const_string "mov_reg"))
7475                           (const_string "mvn_imm")
7476                           (if_then_else (match_operand 1 "const_int_operand" "")
7477                                         (const_string "mov_imm")
7478                                         (const_string "mov_reg"))
7479                           (const_string "mvn_imm")
7480                           (const_string "mov_reg")
7481                           (const_string "mov_reg")
7482                           (const_string "mov_reg")
7483                           (const_string "mov_reg")])]
7486 (define_insn "*movsfcc_soft_insn"
7487   [(set (match_operand:SF 0 "s_register_operand" "=r,r")
7488         (if_then_else:SF (match_operator 3 "arm_comparison_operator"
7489                           [(match_operand 4 "cc_register" "") (const_int 0)])
7490                          (match_operand:SF 1 "s_register_operand" "0,r")
7491                          (match_operand:SF 2 "s_register_operand" "r,0")))]
7492   "TARGET_ARM && TARGET_SOFT_FLOAT"
7493   "@
7494    mov%D3\\t%0, %2
7495    mov%d3\\t%0, %1"
7496   [(set_attr "conds" "use")
7497    (set_attr "type" "mov_reg")]
7501 ;; Jump and linkage insns
7503 (define_expand "jump"
7504   [(set (pc)
7505         (label_ref (match_operand 0 "" "")))]
7506   "TARGET_EITHER"
7507   ""
7510 (define_insn "*arm_jump"
7511   [(set (pc)
7512         (label_ref (match_operand 0 "" "")))]
7513   "TARGET_32BIT"
7514   "*
7515   {
7516     if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
7517       {
7518         arm_ccfsm_state += 2;
7519         return \"\";
7520       }
7521     return \"b%?\\t%l0\";
7522   }
7523   "
7524   [(set_attr "predicable" "yes")
7525    (set (attr "length")
7526         (if_then_else
7527            (and (match_test "TARGET_THUMB2")
7528                 (and (ge (minus (match_dup 0) (pc)) (const_int -2044))
7529                      (le (minus (match_dup 0) (pc)) (const_int 2048))))
7530            (const_int 2)
7531            (const_int 4)))
7532    (set_attr "type" "branch")]
7535 (define_expand "call"
7536   [(parallel [(call (match_operand 0 "memory_operand" "")
7537                     (match_operand 1 "general_operand" ""))
7538               (use (match_operand 2 "" ""))
7539               (clobber (reg:SI LR_REGNUM))])]
7540   "TARGET_EITHER"
7541   "
7542   {
7543     rtx callee, pat;
7544     
7545     /* In an untyped call, we can get NULL for operand 2.  */
7546     if (operands[2] == NULL_RTX)
7547       operands[2] = const0_rtx;
7548       
7549     /* Decide if we should generate indirect calls by loading the
7550        32-bit address of the callee into a register before performing the
7551        branch and link.  */
7552     callee = XEXP (operands[0], 0);
7553     if (GET_CODE (callee) == SYMBOL_REF
7554         ? arm_is_long_call_p (SYMBOL_REF_DECL (callee))
7555         : !REG_P (callee))
7556       XEXP (operands[0], 0) = force_reg (Pmode, callee);
7558     pat = gen_call_internal (operands[0], operands[1], operands[2]);
7559     arm_emit_call_insn (pat, XEXP (operands[0], 0), false);
7560     DONE;
7561   }"
7564 (define_expand "call_internal"
7565   [(parallel [(call (match_operand 0 "memory_operand" "")
7566                     (match_operand 1 "general_operand" ""))
7567               (use (match_operand 2 "" ""))
7568               (clobber (reg:SI LR_REGNUM))])])
7570 (define_insn "*call_reg_armv5"
7571   [(call (mem:SI (match_operand:SI 0 "s_register_operand" "r"))
7572          (match_operand 1 "" ""))
7573    (use (match_operand 2 "" ""))
7574    (clobber (reg:SI LR_REGNUM))]
7575   "TARGET_ARM && arm_arch5 && !SIBLING_CALL_P (insn)"
7576   "blx%?\\t%0"
7577   [(set_attr "type" "call")]
7580 (define_insn "*call_reg_arm"
7581   [(call (mem:SI (match_operand:SI 0 "s_register_operand" "r"))
7582          (match_operand 1 "" ""))
7583    (use (match_operand 2 "" ""))
7584    (clobber (reg:SI LR_REGNUM))]
7585   "TARGET_ARM && !arm_arch5 && !SIBLING_CALL_P (insn)"
7586   "*
7587   return output_call (operands);
7588   "
7589   ;; length is worst case, normally it is only two
7590   [(set_attr "length" "12")
7591    (set_attr "type" "call")]
7595 ;; Note: not used for armv5+ because the sequence used (ldr pc, ...) is not
7596 ;; considered a function call by the branch predictor of some cores (PR40887).
7597 ;; Falls back to blx rN (*call_reg_armv5).
7599 (define_insn "*call_mem"
7600   [(call (mem:SI (match_operand:SI 0 "call_memory_operand" "m"))
7601          (match_operand 1 "" ""))
7602    (use (match_operand 2 "" ""))
7603    (clobber (reg:SI LR_REGNUM))]
7604   "TARGET_ARM && !arm_arch5 && !SIBLING_CALL_P (insn)"
7605   "*
7606   return output_call_mem (operands);
7607   "
7608   [(set_attr "length" "12")
7609    (set_attr "type" "call")]
7612 (define_expand "call_value"
7613   [(parallel [(set (match_operand       0 "" "")
7614                    (call (match_operand 1 "memory_operand" "")
7615                          (match_operand 2 "general_operand" "")))
7616               (use (match_operand 3 "" ""))
7617               (clobber (reg:SI LR_REGNUM))])]
7618   "TARGET_EITHER"
7619   "
7620   {
7621     rtx pat, callee;
7622     
7623     /* In an untyped call, we can get NULL for operand 2.  */
7624     if (operands[3] == 0)
7625       operands[3] = const0_rtx;
7626       
7627     /* Decide if we should generate indirect calls by loading the
7628        32-bit address of the callee into a register before performing the
7629        branch and link.  */
7630     callee = XEXP (operands[1], 0);
7631     if (GET_CODE (callee) == SYMBOL_REF
7632         ? arm_is_long_call_p (SYMBOL_REF_DECL (callee))
7633         : !REG_P (callee))
7634       XEXP (operands[1], 0) = force_reg (Pmode, callee);
7636     pat = gen_call_value_internal (operands[0], operands[1],
7637                                    operands[2], operands[3]);
7638     arm_emit_call_insn (pat, XEXP (operands[1], 0), false);
7639     DONE;
7640   }"
7643 (define_expand "call_value_internal"
7644   [(parallel [(set (match_operand       0 "" "")
7645                    (call (match_operand 1 "memory_operand" "")
7646                          (match_operand 2 "general_operand" "")))
7647               (use (match_operand 3 "" ""))
7648               (clobber (reg:SI LR_REGNUM))])])
7650 (define_insn "*call_value_reg_armv5"
7651   [(set (match_operand 0 "" "")
7652         (call (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
7653               (match_operand 2 "" "")))
7654    (use (match_operand 3 "" ""))
7655    (clobber (reg:SI LR_REGNUM))]
7656   "TARGET_ARM && arm_arch5 && !SIBLING_CALL_P (insn)"
7657   "blx%?\\t%1"
7658   [(set_attr "type" "call")]
7661 (define_insn "*call_value_reg_arm"
7662   [(set (match_operand 0 "" "")
7663         (call (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
7664               (match_operand 2 "" "")))
7665    (use (match_operand 3 "" ""))
7666    (clobber (reg:SI LR_REGNUM))]
7667   "TARGET_ARM && !arm_arch5 && !SIBLING_CALL_P (insn)"
7668   "*
7669   return output_call (&operands[1]);
7670   "
7671   [(set_attr "length" "12")
7672    (set_attr "type" "call")]
7675 ;; Note: see *call_mem
7677 (define_insn "*call_value_mem"
7678   [(set (match_operand 0 "" "")
7679         (call (mem:SI (match_operand:SI 1 "call_memory_operand" "m"))
7680               (match_operand 2 "" "")))
7681    (use (match_operand 3 "" ""))
7682    (clobber (reg:SI LR_REGNUM))]
7683   "TARGET_ARM && !arm_arch5 && (!CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
7684    && !SIBLING_CALL_P (insn)"
7685   "*
7686   return output_call_mem (&operands[1]);
7687   "
7688   [(set_attr "length" "12")
7689    (set_attr "type" "call")]
7692 ;; Allow calls to SYMBOL_REFs specially as they are not valid general addresses
7693 ;; The 'a' causes the operand to be treated as an address, i.e. no '#' output.
7695 (define_insn "*call_symbol"
7696   [(call (mem:SI (match_operand:SI 0 "" ""))
7697          (match_operand 1 "" ""))
7698    (use (match_operand 2 "" ""))
7699    (clobber (reg:SI LR_REGNUM))]
7700   "TARGET_32BIT
7701    && !SIBLING_CALL_P (insn)
7702    && (GET_CODE (operands[0]) == SYMBOL_REF)
7703    && !arm_is_long_call_p (SYMBOL_REF_DECL (operands[0]))"
7704   "*
7705   {
7706     return NEED_PLT_RELOC ? \"bl%?\\t%a0(PLT)\" : \"bl%?\\t%a0\";
7707   }"
7708   [(set_attr "type" "call")]
7711 (define_insn "*call_value_symbol"
7712   [(set (match_operand 0 "" "")
7713         (call (mem:SI (match_operand:SI 1 "" ""))
7714         (match_operand:SI 2 "" "")))
7715    (use (match_operand 3 "" ""))
7716    (clobber (reg:SI LR_REGNUM))]
7717   "TARGET_32BIT
7718    && !SIBLING_CALL_P (insn)
7719    && (GET_CODE (operands[1]) == SYMBOL_REF)
7720    && !arm_is_long_call_p (SYMBOL_REF_DECL (operands[1]))"
7721   "*
7722   {
7723     return NEED_PLT_RELOC ? \"bl%?\\t%a1(PLT)\" : \"bl%?\\t%a1\";
7724   }"
7725   [(set_attr "type" "call")]
7728 (define_expand "sibcall_internal"
7729   [(parallel [(call (match_operand 0 "memory_operand" "")
7730                     (match_operand 1 "general_operand" ""))
7731               (return)
7732               (use (match_operand 2 "" ""))])])
7734 ;; We may also be able to do sibcalls for Thumb, but it's much harder...
7735 (define_expand "sibcall"
7736   [(parallel [(call (match_operand 0 "memory_operand" "")
7737                     (match_operand 1 "general_operand" ""))
7738               (return)
7739               (use (match_operand 2 "" ""))])]
7740   "TARGET_32BIT"
7741   "
7742   {
7743     rtx pat;
7745     if ((!REG_P (XEXP (operands[0], 0))
7746          && GET_CODE (XEXP (operands[0], 0)) != SYMBOL_REF)
7747         || (GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
7748             && arm_is_long_call_p (SYMBOL_REF_DECL (XEXP (operands[0], 0)))))
7749      XEXP (operands[0], 0) = force_reg (SImode, XEXP (operands[0], 0));
7751     if (operands[2] == NULL_RTX)
7752       operands[2] = const0_rtx;
7754     pat = gen_sibcall_internal (operands[0], operands[1], operands[2]);
7755     arm_emit_call_insn (pat, operands[0], true);
7756     DONE;
7757   }"
7760 (define_expand "sibcall_value_internal"
7761   [(parallel [(set (match_operand 0 "" "")
7762                    (call (match_operand 1 "memory_operand" "")
7763                          (match_operand 2 "general_operand" "")))
7764               (return)
7765               (use (match_operand 3 "" ""))])])
7767 (define_expand "sibcall_value"
7768   [(parallel [(set (match_operand 0 "" "")
7769                    (call (match_operand 1 "memory_operand" "")
7770                          (match_operand 2 "general_operand" "")))
7771               (return)
7772               (use (match_operand 3 "" ""))])]
7773   "TARGET_32BIT"
7774   "
7775   {
7776     rtx pat;
7778     if ((!REG_P (XEXP (operands[1], 0))
7779          && GET_CODE (XEXP (operands[1], 0)) != SYMBOL_REF)
7780         || (GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
7781             && arm_is_long_call_p (SYMBOL_REF_DECL (XEXP (operands[1], 0)))))
7782      XEXP (operands[1], 0) = force_reg (SImode, XEXP (operands[1], 0));
7784     if (operands[3] == NULL_RTX)
7785       operands[3] = const0_rtx;
7787     pat = gen_sibcall_value_internal (operands[0], operands[1],
7788                                       operands[2], operands[3]);
7789     arm_emit_call_insn (pat, operands[1], true);
7790     DONE;
7791   }"
7794 (define_insn "*sibcall_insn"
7795  [(call (mem:SI (match_operand:SI 0 "call_insn_operand" "Cs, US"))
7796         (match_operand 1 "" ""))
7797   (return)
7798   (use (match_operand 2 "" ""))]
7799   "TARGET_32BIT && SIBLING_CALL_P (insn)"
7800   "*
7801   if (which_alternative == 1)
7802     return NEED_PLT_RELOC ? \"b%?\\t%a0(PLT)\" : \"b%?\\t%a0\";
7803   else
7804     {
7805       if (arm_arch5 || arm_arch4t)
7806         return \"bx%?\\t%0\\t%@ indirect register sibling call\";
7807       else
7808         return \"mov%?\\t%|pc, %0\\t%@ indirect register sibling call\";
7809     }
7810   "
7811   [(set_attr "type" "call")]
7814 (define_insn "*sibcall_value_insn"
7815  [(set (match_operand 0 "" "")
7816        (call (mem:SI (match_operand:SI 1 "call_insn_operand" "Cs,US"))
7817              (match_operand 2 "" "")))
7818   (return)
7819   (use (match_operand 3 "" ""))]
7820   "TARGET_32BIT && SIBLING_CALL_P (insn)"
7821   "*
7822   if (which_alternative == 1)
7823    return NEED_PLT_RELOC ? \"b%?\\t%a1(PLT)\" : \"b%?\\t%a1\";
7824   else
7825     {
7826       if (arm_arch5 || arm_arch4t)
7827         return \"bx%?\\t%1\";
7828       else
7829         return \"mov%?\\t%|pc, %1\\t@ indirect sibling call \";
7830     }
7831   "
7832   [(set_attr "type" "call")]
7835 (define_expand "<return_str>return"
7836   [(returns)]
7837   "(TARGET_ARM || (TARGET_THUMB2
7838                    && ARM_FUNC_TYPE (arm_current_func_type ()) == ARM_FT_NORMAL
7839                    && !IS_STACKALIGN (arm_current_func_type ())))
7840     <return_cond_false>"
7841   "
7842   {
7843     if (TARGET_THUMB2)
7844       {
7845         thumb2_expand_return (<return_simple_p>);
7846         DONE;
7847       }
7848   }
7849   "
7852 ;; Often the return insn will be the same as loading from memory, so set attr
7853 (define_insn "*arm_return"
7854   [(return)]
7855   "TARGET_ARM && USE_RETURN_INSN (FALSE)"
7856   "*
7857   {
7858     if (arm_ccfsm_state == 2)
7859       {
7860         arm_ccfsm_state += 2;
7861         return \"\";
7862       }
7863     return output_return_instruction (const_true_rtx, true, false, false);
7864   }"
7865   [(set_attr "type" "load1")
7866    (set_attr "length" "12")
7867    (set_attr "predicable" "yes")]
7870 (define_insn "*cond_<return_str>return"
7871   [(set (pc)
7872         (if_then_else (match_operator 0 "arm_comparison_operator"
7873                        [(match_operand 1 "cc_register" "") (const_int 0)])
7874                       (returns)
7875                       (pc)))]
7876   "TARGET_ARM  <return_cond_true>"
7877   "*
7878   {
7879     if (arm_ccfsm_state == 2)
7880       {
7881         arm_ccfsm_state += 2;
7882         return \"\";
7883       }
7884     return output_return_instruction (operands[0], true, false,
7885                                       <return_simple_p>);
7886   }"
7887   [(set_attr "conds" "use")
7888    (set_attr "length" "12")
7889    (set_attr "type" "load1")]
7892 (define_insn "*cond_<return_str>return_inverted"
7893   [(set (pc)
7894         (if_then_else (match_operator 0 "arm_comparison_operator"
7895                        [(match_operand 1 "cc_register" "") (const_int 0)])
7896                       (pc)
7897                       (returns)))]
7898   "TARGET_ARM <return_cond_true>"
7899   "*
7900   {
7901     if (arm_ccfsm_state == 2)
7902       {
7903         arm_ccfsm_state += 2;
7904         return \"\";
7905       }
7906     return output_return_instruction (operands[0], true, true,
7907                                       <return_simple_p>);
7908   }"
7909   [(set_attr "conds" "use")
7910    (set_attr "length" "12")
7911    (set_attr "type" "load1")]
7914 (define_insn "*arm_simple_return"
7915   [(simple_return)]
7916   "TARGET_ARM"
7917   "*
7918   {
7919     if (arm_ccfsm_state == 2)
7920       {
7921         arm_ccfsm_state += 2;
7922         return \"\";
7923       }
7924     return output_return_instruction (const_true_rtx, true, false, true);
7925   }"
7926   [(set_attr "type" "branch")
7927    (set_attr "length" "4")
7928    (set_attr "predicable" "yes")]
7931 ;; Generate a sequence of instructions to determine if the processor is
7932 ;; in 26-bit or 32-bit mode, and return the appropriate return address
7933 ;; mask.
7935 (define_expand "return_addr_mask"
7936   [(set (match_dup 1)
7937       (compare:CC_NOOV (unspec [(const_int 0)] UNSPEC_CHECK_ARCH)
7938                        (const_int 0)))
7939    (set (match_operand:SI 0 "s_register_operand" "")
7940       (if_then_else:SI (eq (match_dup 1) (const_int 0))
7941                        (const_int -1)
7942                        (const_int 67108860)))] ; 0x03fffffc
7943   "TARGET_ARM"
7944   "
7945   operands[1] = gen_rtx_REG (CC_NOOVmode, CC_REGNUM);
7946   ")
7948 (define_insn "*check_arch2"
7949   [(set (match_operand:CC_NOOV 0 "cc_register" "")
7950       (compare:CC_NOOV (unspec [(const_int 0)] UNSPEC_CHECK_ARCH)
7951                        (const_int 0)))]
7952   "TARGET_ARM"
7953   "teq\\t%|r0, %|r0\;teq\\t%|pc, %|pc"
7954   [(set_attr "length" "8")
7955    (set_attr "conds" "set")
7956    (set_attr "type" "multiple")]
7959 ;; Call subroutine returning any type.
7961 (define_expand "untyped_call"
7962   [(parallel [(call (match_operand 0 "" "")
7963                     (const_int 0))
7964               (match_operand 1 "" "")
7965               (match_operand 2 "" "")])]
7966   "TARGET_EITHER"
7967   "
7968   {
7969     int i;
7970     rtx par = gen_rtx_PARALLEL (VOIDmode,
7971                                 rtvec_alloc (XVECLEN (operands[2], 0)));
7972     rtx addr = gen_reg_rtx (Pmode);
7973     rtx mem;
7974     int size = 0;
7976     emit_move_insn (addr, XEXP (operands[1], 0));
7977     mem = change_address (operands[1], BLKmode, addr);
7979     for (i = 0; i < XVECLEN (operands[2], 0); i++)
7980       {
7981         rtx src = SET_SRC (XVECEXP (operands[2], 0, i));
7983         /* Default code only uses r0 as a return value, but we could
7984            be using anything up to 4 registers.  */
7985         if (REGNO (src) == R0_REGNUM)
7986           src = gen_rtx_REG (TImode, R0_REGNUM);
7988         XVECEXP (par, 0, i) = gen_rtx_EXPR_LIST (VOIDmode, src,
7989                                                  GEN_INT (size));
7990         size += GET_MODE_SIZE (GET_MODE (src));
7991       }
7993     emit_call_insn (GEN_CALL_VALUE (par, operands[0], const0_rtx, NULL,
7994                                     const0_rtx));
7996     size = 0;
7998     for (i = 0; i < XVECLEN (par, 0); i++)
7999       {
8000         HOST_WIDE_INT offset = 0;
8001         rtx reg = XEXP (XVECEXP (par, 0, i), 0);
8003         if (size != 0)
8004           emit_move_insn (addr, plus_constant (Pmode, addr, size));
8006         mem = change_address (mem, GET_MODE (reg), NULL);
8007         if (REGNO (reg) == R0_REGNUM)
8008           {
8009             /* On thumb we have to use a write-back instruction.  */
8010             emit_insn (arm_gen_store_multiple (arm_regs_in_sequence, 4, addr,
8011                        TARGET_THUMB ? TRUE : FALSE, mem, &offset));
8012             size = TARGET_ARM ? 16 : 0;
8013           }
8014         else
8015           {
8016             emit_move_insn (mem, reg);
8017             size = GET_MODE_SIZE (GET_MODE (reg));
8018           }
8019       }
8021     /* The optimizer does not know that the call sets the function value
8022        registers we stored in the result block.  We avoid problems by
8023        claiming that all hard registers are used and clobbered at this
8024        point.  */
8025     emit_insn (gen_blockage ());
8027     DONE;
8028   }"
8031 (define_expand "untyped_return"
8032   [(match_operand:BLK 0 "memory_operand" "")
8033    (match_operand 1 "" "")]
8034   "TARGET_EITHER"
8035   "
8036   {
8037     int i;
8038     rtx addr = gen_reg_rtx (Pmode);
8039     rtx mem;
8040     int size = 0;
8042     emit_move_insn (addr, XEXP (operands[0], 0));
8043     mem = change_address (operands[0], BLKmode, addr);
8045     for (i = 0; i < XVECLEN (operands[1], 0); i++)
8046       {
8047         HOST_WIDE_INT offset = 0;
8048         rtx reg = SET_DEST (XVECEXP (operands[1], 0, i));
8050         if (size != 0)
8051           emit_move_insn (addr, plus_constant (Pmode, addr, size));
8053         mem = change_address (mem, GET_MODE (reg), NULL);
8054         if (REGNO (reg) == R0_REGNUM)
8055           {
8056             /* On thumb we have to use a write-back instruction.  */
8057             emit_insn (arm_gen_load_multiple (arm_regs_in_sequence, 4, addr,
8058                        TARGET_THUMB ? TRUE : FALSE, mem, &offset));
8059             size = TARGET_ARM ? 16 : 0;
8060           }
8061         else
8062           {
8063             emit_move_insn (reg, mem);
8064             size = GET_MODE_SIZE (GET_MODE (reg));
8065           }
8066       }
8068     /* Emit USE insns before the return.  */
8069     for (i = 0; i < XVECLEN (operands[1], 0); i++)
8070       emit_use (SET_DEST (XVECEXP (operands[1], 0, i)));
8072     /* Construct the return.  */
8073     expand_naked_return ();
8075     DONE;
8076   }"
8079 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
8080 ;; all of memory.  This blocks insns from being moved across this point.
8082 (define_insn "blockage"
8083   [(unspec_volatile [(const_int 0)] VUNSPEC_BLOCKAGE)]
8084   "TARGET_EITHER"
8085   ""
8086   [(set_attr "length" "0")
8087    (set_attr "type" "block")]
8090 (define_expand "casesi"
8091   [(match_operand:SI 0 "s_register_operand" "") ; index to jump on
8092    (match_operand:SI 1 "const_int_operand" "")  ; lower bound
8093    (match_operand:SI 2 "const_int_operand" "")  ; total range
8094    (match_operand:SI 3 "" "")                   ; table label
8095    (match_operand:SI 4 "" "")]                  ; Out of range label
8096   "TARGET_32BIT || optimize_size || flag_pic"
8097   "
8098   {
8099     enum insn_code code;
8100     if (operands[1] != const0_rtx)
8101       {
8102         rtx reg = gen_reg_rtx (SImode);
8104         emit_insn (gen_addsi3 (reg, operands[0],
8105                                gen_int_mode (-INTVAL (operands[1]),
8106                                              SImode)));
8107         operands[0] = reg;
8108       }
8110     if (TARGET_ARM)
8111       code = CODE_FOR_arm_casesi_internal;
8112     else if (TARGET_THUMB1)
8113       code = CODE_FOR_thumb1_casesi_internal_pic;
8114     else if (flag_pic)
8115       code = CODE_FOR_thumb2_casesi_internal_pic;
8116     else
8117       code = CODE_FOR_thumb2_casesi_internal;
8119     if (!insn_data[(int) code].operand[1].predicate(operands[2], SImode))
8120       operands[2] = force_reg (SImode, operands[2]);
8122     emit_jump_insn (GEN_FCN ((int) code) (operands[0], operands[2],
8123                                           operands[3], operands[4]));
8124     DONE;
8125   }"
8128 ;; The USE in this pattern is needed to tell flow analysis that this is
8129 ;; a CASESI insn.  It has no other purpose.
8130 (define_insn "arm_casesi_internal"
8131   [(parallel [(set (pc)
8132                (if_then_else
8133                 (leu (match_operand:SI 0 "s_register_operand" "r")
8134                      (match_operand:SI 1 "arm_rhs_operand" "rI"))
8135                 (mem:SI (plus:SI (mult:SI (match_dup 0) (const_int 4))
8136                                  (label_ref (match_operand 2 "" ""))))
8137                 (label_ref (match_operand 3 "" ""))))
8138               (clobber (reg:CC CC_REGNUM))
8139               (use (label_ref (match_dup 2)))])]
8140   "TARGET_ARM"
8141   "*
8142     if (flag_pic)
8143       return \"cmp\\t%0, %1\;addls\\t%|pc, %|pc, %0, asl #2\;b\\t%l3\";
8144     return   \"cmp\\t%0, %1\;ldrls\\t%|pc, [%|pc, %0, asl #2]\;b\\t%l3\";
8145   "
8146   [(set_attr "conds" "clob")
8147    (set_attr "length" "12")
8148    (set_attr "type" "multiple")]
8151 (define_expand "indirect_jump"
8152   [(set (pc)
8153         (match_operand:SI 0 "s_register_operand" ""))]
8154   "TARGET_EITHER"
8155   "
8156   /* Thumb-2 doesn't have mov pc, reg.  Explicitly set the low bit of the
8157      address and use bx.  */
8158   if (TARGET_THUMB2)
8159     {
8160       rtx tmp;
8161       tmp = gen_reg_rtx (SImode);
8162       emit_insn (gen_iorsi3 (tmp, operands[0], GEN_INT(1)));
8163       operands[0] = tmp;
8164     }
8165   "
8168 ;; NB Never uses BX.
8169 (define_insn "*arm_indirect_jump"
8170   [(set (pc)
8171         (match_operand:SI 0 "s_register_operand" "r"))]
8172   "TARGET_ARM"
8173   "mov%?\\t%|pc, %0\\t%@ indirect register jump"
8174   [(set_attr "predicable" "yes")
8175    (set_attr "type" "branch")]
8178 (define_insn "*load_indirect_jump"
8179   [(set (pc)
8180         (match_operand:SI 0 "memory_operand" "m"))]
8181   "TARGET_ARM"
8182   "ldr%?\\t%|pc, %0\\t%@ indirect memory jump"
8183   [(set_attr "type" "load1")
8184    (set_attr "pool_range" "4096")
8185    (set_attr "neg_pool_range" "4084")
8186    (set_attr "predicable" "yes")]
8190 ;; Misc insns
8192 (define_insn "nop"
8193   [(const_int 0)]
8194   "TARGET_EITHER"
8195   "*
8196   if (TARGET_UNIFIED_ASM)
8197     return \"nop\";
8198   if (TARGET_ARM)
8199     return \"mov%?\\t%|r0, %|r0\\t%@ nop\";
8200   return  \"mov\\tr8, r8\";
8201   "
8202   [(set (attr "length")
8203         (if_then_else (eq_attr "is_thumb" "yes")
8204                       (const_int 2)
8205                       (const_int 4)))
8206    (set_attr "type" "mov_reg")]
8209 (define_insn "trap"
8210   [(trap_if (const_int 1) (const_int 0))]
8211   ""
8212   "*
8213   if (TARGET_ARM)
8214     return \".inst\\t0xe7f000f0\";
8215   else
8216     return \".inst\\t0xdeff\";
8217   "
8218   [(set (attr "length")
8219         (if_then_else (eq_attr "is_thumb" "yes")
8220                       (const_int 2)
8221                       (const_int 4)))
8222    (set_attr "type" "trap")
8223    (set_attr "conds" "unconditional")]
8227 ;; Patterns to allow combination of arithmetic, cond code and shifts
8229 (define_insn "*<arith_shift_insn>_multsi"
8230   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8231         (shiftable_ops:SI
8232          (mult:SI (match_operand:SI 2 "s_register_operand" "r,r")
8233                   (match_operand:SI 3 "power_of_two_operand" ""))
8234          (match_operand:SI 1 "s_register_operand" "rk,<t2_binop0>")))]
8235   "TARGET_32BIT"
8236   "<arith_shift_insn>%?\\t%0, %1, %2, lsl %b3"
8237   [(set_attr "predicable" "yes")
8238    (set_attr "predicable_short_it" "no")
8239    (set_attr "shift" "4")
8240    (set_attr "arch" "a,t2")
8241    (set_attr "type" "alu_shift_imm")])
8243 (define_insn "*<arith_shift_insn>_shiftsi"
8244   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
8245         (shiftable_ops:SI
8246          (match_operator:SI 2 "shift_nomul_operator"
8247           [(match_operand:SI 3 "s_register_operand" "r,r,r")
8248            (match_operand:SI 4 "shift_amount_operand" "M,M,r")])
8249          (match_operand:SI 1 "s_register_operand" "rk,<t2_binop0>,rk")))]
8250   "TARGET_32BIT && GET_CODE (operands[3]) != MULT"
8251   "<arith_shift_insn>%?\\t%0, %1, %3%S2"
8252   [(set_attr "predicable" "yes")
8253    (set_attr "predicable_short_it" "no")
8254    (set_attr "shift" "4")
8255    (set_attr "arch" "a,t2,a")
8256    (set_attr "type" "alu_shift_imm,alu_shift_imm,alu_shift_reg")])
8258 (define_split
8259   [(set (match_operand:SI 0 "s_register_operand" "")
8260         (match_operator:SI 1 "shiftable_operator"
8261          [(match_operator:SI 2 "shiftable_operator"
8262            [(match_operator:SI 3 "shift_operator"
8263              [(match_operand:SI 4 "s_register_operand" "")
8264               (match_operand:SI 5 "reg_or_int_operand" "")])
8265             (match_operand:SI 6 "s_register_operand" "")])
8266           (match_operand:SI 7 "arm_rhs_operand" "")]))
8267    (clobber (match_operand:SI 8 "s_register_operand" ""))]
8268   "TARGET_32BIT"
8269   [(set (match_dup 8)
8270         (match_op_dup 2 [(match_op_dup 3 [(match_dup 4) (match_dup 5)])
8271                          (match_dup 6)]))
8272    (set (match_dup 0)
8273         (match_op_dup 1 [(match_dup 8) (match_dup 7)]))]
8274   "")
8276 (define_insn "*arith_shiftsi_compare0"
8277   [(set (reg:CC_NOOV CC_REGNUM)
8278         (compare:CC_NOOV
8279          (match_operator:SI 1 "shiftable_operator"
8280           [(match_operator:SI 3 "shift_operator"
8281             [(match_operand:SI 4 "s_register_operand" "r,r")
8282              (match_operand:SI 5 "shift_amount_operand" "M,r")])
8283            (match_operand:SI 2 "s_register_operand" "r,r")])
8284          (const_int 0)))
8285    (set (match_operand:SI 0 "s_register_operand" "=r,r")
8286         (match_op_dup 1 [(match_op_dup 3 [(match_dup 4) (match_dup 5)])
8287                          (match_dup 2)]))]
8288   "TARGET_32BIT"
8289   "%i1%.\\t%0, %2, %4%S3"
8290   [(set_attr "conds" "set")
8291    (set_attr "shift" "4")
8292    (set_attr "arch" "32,a")
8293    (set_attr "type" "alus_shift_imm,alus_shift_reg")])
8295 (define_insn "*arith_shiftsi_compare0_scratch"
8296   [(set (reg:CC_NOOV CC_REGNUM)
8297         (compare:CC_NOOV
8298          (match_operator:SI 1 "shiftable_operator"
8299           [(match_operator:SI 3 "shift_operator"
8300             [(match_operand:SI 4 "s_register_operand" "r,r")
8301              (match_operand:SI 5 "shift_amount_operand" "M,r")])
8302            (match_operand:SI 2 "s_register_operand" "r,r")])
8303          (const_int 0)))
8304    (clobber (match_scratch:SI 0 "=r,r"))]
8305   "TARGET_32BIT"
8306   "%i1%.\\t%0, %2, %4%S3"
8307   [(set_attr "conds" "set")
8308    (set_attr "shift" "4")
8309    (set_attr "arch" "32,a")
8310    (set_attr "type" "alus_shift_imm,alus_shift_reg")])
8312 (define_insn "*sub_shiftsi"
8313   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8314         (minus:SI (match_operand:SI 1 "s_register_operand" "r,r")
8315                   (match_operator:SI 2 "shift_operator"
8316                    [(match_operand:SI 3 "s_register_operand" "r,r")
8317                     (match_operand:SI 4 "shift_amount_operand" "M,r")])))]
8318   "TARGET_32BIT"
8319   "sub%?\\t%0, %1, %3%S2"
8320   [(set_attr "predicable" "yes")
8321    (set_attr "shift" "3")
8322    (set_attr "arch" "32,a")
8323    (set_attr "type" "alus_shift_imm,alus_shift_reg")])
8325 (define_insn "*sub_shiftsi_compare0"
8326   [(set (reg:CC_NOOV CC_REGNUM)
8327         (compare:CC_NOOV
8328          (minus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
8329                    (match_operator:SI 2 "shift_operator"
8330                     [(match_operand:SI 3 "s_register_operand" "r,r,r")
8331                      (match_operand:SI 4 "shift_amount_operand" "M,r,M")]))
8332          (const_int 0)))
8333    (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
8334         (minus:SI (match_dup 1)
8335                   (match_op_dup 2 [(match_dup 3) (match_dup 4)])))]
8336   "TARGET_32BIT"
8337   "sub%.\\t%0, %1, %3%S2"
8338   [(set_attr "conds" "set")
8339    (set_attr "shift" "3")
8340    (set_attr "arch" "32,a,a")
8341    (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
8343 (define_insn "*sub_shiftsi_compare0_scratch"
8344   [(set (reg:CC_NOOV CC_REGNUM)
8345         (compare:CC_NOOV
8346          (minus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
8347                    (match_operator:SI 2 "shift_operator"
8348                     [(match_operand:SI 3 "s_register_operand" "r,r,r")
8349                      (match_operand:SI 4 "shift_amount_operand" "M,r,M")]))
8350          (const_int 0)))
8351    (clobber (match_scratch:SI 0 "=r,r,r"))]
8352   "TARGET_32BIT"
8353   "sub%.\\t%0, %1, %3%S2"
8354   [(set_attr "conds" "set")
8355    (set_attr "shift" "3")
8356    (set_attr "arch" "32,a,a")
8357    (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
8360 (define_insn_and_split "*and_scc"
8361   [(set (match_operand:SI 0 "s_register_operand" "=r")
8362         (and:SI (match_operator:SI 1 "arm_comparison_operator"
8363                  [(match_operand 2 "cc_register" "") (const_int 0)])
8364                 (match_operand:SI 3 "s_register_operand" "r")))]
8365   "TARGET_ARM"
8366   "#"   ; "mov%D1\\t%0, #0\;and%d1\\t%0, %3, #1"
8367   "&& reload_completed"
8368   [(cond_exec (match_dup 5) (set (match_dup 0) (const_int 0)))
8369    (cond_exec (match_dup 4) (set (match_dup 0)
8370                                  (and:SI (match_dup 3) (const_int 1))))]
8371   {
8372     enum machine_mode mode = GET_MODE (operands[2]);
8373     enum rtx_code rc = GET_CODE (operands[1]);
8375     /* Note that operands[4] is the same as operands[1],
8376        but with VOIDmode as the result. */
8377     operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
8378     if (mode == CCFPmode || mode == CCFPEmode)
8379       rc = reverse_condition_maybe_unordered (rc);
8380     else
8381       rc = reverse_condition (rc);
8382     operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
8383   }
8384   [(set_attr "conds" "use")
8385    (set_attr "type" "multiple")
8386    (set_attr "length" "8")]
8389 (define_insn_and_split "*ior_scc"
8390   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8391         (ior:SI (match_operator:SI 1 "arm_comparison_operator"
8392                  [(match_operand 2 "cc_register" "") (const_int 0)])
8393                 (match_operand:SI 3 "s_register_operand" "0,?r")))]
8394   "TARGET_ARM"
8395   "@
8396    orr%d1\\t%0, %3, #1
8397    #"
8398   "&& reload_completed
8399    && REGNO (operands [0]) != REGNO (operands[3])"
8400   ;; && which_alternative == 1
8401   ; mov%D1\\t%0, %3\;orr%d1\\t%0, %3, #1
8402   [(cond_exec (match_dup 5) (set (match_dup 0) (match_dup 3)))
8403    (cond_exec (match_dup 4) (set (match_dup 0)
8404                                  (ior:SI (match_dup 3) (const_int 1))))]
8405   {
8406     enum machine_mode mode = GET_MODE (operands[2]);
8407     enum rtx_code rc = GET_CODE (operands[1]);
8409     /* Note that operands[4] is the same as operands[1],
8410        but with VOIDmode as the result. */
8411     operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
8412     if (mode == CCFPmode || mode == CCFPEmode)
8413       rc = reverse_condition_maybe_unordered (rc);
8414     else
8415       rc = reverse_condition (rc);
8416     operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
8417   }
8418   [(set_attr "conds" "use")
8419    (set_attr "length" "4,8")
8420    (set_attr "type" "logic_imm,multiple")]
8423 ; A series of splitters for the compare_scc pattern below.  Note that
8424 ; order is important.
8425 (define_split
8426   [(set (match_operand:SI 0 "s_register_operand" "")
8427         (lt:SI (match_operand:SI 1 "s_register_operand" "")
8428                (const_int 0)))
8429    (clobber (reg:CC CC_REGNUM))]
8430   "TARGET_32BIT && reload_completed"
8431   [(set (match_dup 0) (lshiftrt:SI (match_dup 1) (const_int 31)))])
8433 (define_split
8434   [(set (match_operand:SI 0 "s_register_operand" "")
8435         (ge:SI (match_operand:SI 1 "s_register_operand" "")
8436                (const_int 0)))
8437    (clobber (reg:CC CC_REGNUM))]
8438   "TARGET_32BIT && reload_completed"
8439   [(set (match_dup 0) (not:SI (match_dup 1)))
8440    (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 31)))])
8442 (define_split
8443   [(set (match_operand:SI 0 "s_register_operand" "")
8444         (eq:SI (match_operand:SI 1 "s_register_operand" "")
8445                (const_int 0)))
8446    (clobber (reg:CC CC_REGNUM))]
8447   "arm_arch5 && TARGET_32BIT"
8448   [(set (match_dup 0) (clz:SI (match_dup 1)))
8449    (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
8452 (define_split
8453   [(set (match_operand:SI 0 "s_register_operand" "")
8454         (eq:SI (match_operand:SI 1 "s_register_operand" "")
8455                (const_int 0)))
8456    (clobber (reg:CC CC_REGNUM))]
8457   "TARGET_32BIT && reload_completed"
8458   [(parallel
8459     [(set (reg:CC CC_REGNUM)
8460           (compare:CC (const_int 1) (match_dup 1)))
8461      (set (match_dup 0)
8462           (minus:SI (const_int 1) (match_dup 1)))])
8463    (cond_exec (ltu:CC (reg:CC CC_REGNUM) (const_int 0))
8464               (set (match_dup 0) (const_int 0)))])
8466 (define_split
8467   [(set (match_operand:SI 0 "s_register_operand" "")
8468         (ne:SI (match_operand:SI 1 "s_register_operand" "")
8469                (match_operand:SI 2 "const_int_operand" "")))
8470    (clobber (reg:CC CC_REGNUM))]
8471   "TARGET_32BIT && reload_completed"
8472   [(parallel
8473     [(set (reg:CC CC_REGNUM)
8474           (compare:CC (match_dup 1) (match_dup 2)))
8475      (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 3)))])
8476    (cond_exec (ne:CC (reg:CC CC_REGNUM) (const_int 0))
8477               (set (match_dup 0) (const_int 1)))]
8479   operands[3] = GEN_INT (-INTVAL (operands[2]));
8482 (define_split
8483   [(set (match_operand:SI 0 "s_register_operand" "")
8484         (ne:SI (match_operand:SI 1 "s_register_operand" "")
8485                (match_operand:SI 2 "arm_add_operand" "")))
8486    (clobber (reg:CC CC_REGNUM))]
8487   "TARGET_32BIT && reload_completed"
8488   [(parallel
8489     [(set (reg:CC_NOOV CC_REGNUM)
8490           (compare:CC_NOOV (minus:SI (match_dup 1) (match_dup 2))
8491                            (const_int 0)))
8492      (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
8493    (cond_exec (ne:CC_NOOV (reg:CC_NOOV CC_REGNUM) (const_int 0))
8494               (set (match_dup 0) (const_int 1)))])
8496 (define_insn_and_split "*compare_scc"
8497   [(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts")
8498         (match_operator:SI 1 "arm_comparison_operator"
8499          [(match_operand:SI 2 "s_register_operand" "r,r")
8500           (match_operand:SI 3 "arm_add_operand" "rI,L")]))
8501    (clobber (reg:CC CC_REGNUM))]
8502   "TARGET_32BIT"
8503   "#"
8504   "&& reload_completed"
8505   [(set (reg:CC CC_REGNUM) (compare:CC (match_dup 2) (match_dup 3)))
8506    (cond_exec (match_dup 4) (set (match_dup 0) (const_int 0)))
8507    (cond_exec (match_dup 5) (set (match_dup 0) (const_int 1)))]
8509   rtx tmp1;
8510   enum machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
8511                                            operands[2], operands[3]);
8512   enum rtx_code rc = GET_CODE (operands[1]);
8514   tmp1 = gen_rtx_REG (mode, CC_REGNUM);
8516   operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, tmp1, const0_rtx);
8517   if (mode == CCFPmode || mode == CCFPEmode)
8518     rc = reverse_condition_maybe_unordered (rc);
8519   else
8520     rc = reverse_condition (rc);
8521   operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, tmp1, const0_rtx);
8523   [(set_attr "type" "multiple")]
8526 ;; Attempt to improve the sequence generated by the compare_scc splitters
8527 ;; not to use conditional execution.
8529 ;; Rd = (eq (reg1) (const_int0))  // ARMv5
8530 ;;      clz Rd, reg1
8531 ;;      lsr Rd, Rd, #5
8532 (define_peephole2
8533   [(set (reg:CC CC_REGNUM)
8534         (compare:CC (match_operand:SI 1 "register_operand" "")
8535                     (const_int 0)))
8536    (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
8537               (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
8538    (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
8539               (set (match_dup 0) (const_int 1)))]
8540   "arm_arch5 && TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
8541   [(set (match_dup 0) (clz:SI (match_dup 1)))
8542    (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
8545 ;; Rd = (eq (reg1) (const_int0))  // !ARMv5
8546 ;;      negs Rd, reg1
8547 ;;      adc  Rd, Rd, reg1
8548 (define_peephole2
8549   [(set (reg:CC CC_REGNUM)
8550         (compare:CC (match_operand:SI 1 "register_operand" "")
8551                     (const_int 0)))
8552    (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
8553               (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
8554    (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
8555               (set (match_dup 0) (const_int 1)))
8556    (match_scratch:SI 2 "r")]
8557   "TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
8558   [(parallel
8559     [(set (reg:CC CC_REGNUM)
8560           (compare:CC (const_int 0) (match_dup 1)))
8561      (set (match_dup 2) (minus:SI (const_int 0) (match_dup 1)))])
8562    (set (match_dup 0)
8563         (plus:SI (plus:SI (match_dup 1) (match_dup 2))
8564                  (geu:SI (reg:CC CC_REGNUM) (const_int 0))))]
8567 ;; Rd = (eq (reg1) (reg2/imm))  // ARMv5 and optimising for speed.
8568 ;;      sub  Rd, Reg1, reg2
8569 ;;      clz  Rd, Rd
8570 ;;      lsr  Rd, Rd, #5
8571 (define_peephole2
8572   [(set (reg:CC CC_REGNUM)
8573         (compare:CC (match_operand:SI 1 "register_operand" "")
8574                     (match_operand:SI 2 "arm_rhs_operand" "")))
8575    (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
8576               (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
8577    (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
8578               (set (match_dup 0) (const_int 1)))]
8579   "arm_arch5 && TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)
8580   && !(TARGET_THUMB2 && optimize_insn_for_size_p ())"
8581   [(set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))
8582    (set (match_dup 0) (clz:SI (match_dup 0)))
8583    (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
8587 ;; Rd = (eq (reg1) (reg2))      // ! ARMv5 or optimising for size.
8588 ;;      sub  T1, Reg1, reg2
8589 ;;      negs Rd, T1
8590 ;;      adc  Rd, Rd, T1
8591 (define_peephole2
8592   [(set (reg:CC CC_REGNUM)
8593         (compare:CC (match_operand:SI 1 "register_operand" "")
8594                     (match_operand:SI 2 "arm_rhs_operand" "")))
8595    (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
8596               (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
8597    (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
8598               (set (match_dup 0) (const_int 1)))
8599    (match_scratch:SI 3 "r")]
8600   "TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
8601   [(set (match_dup 3) (match_dup 4))
8602    (parallel
8603     [(set (reg:CC CC_REGNUM)
8604           (compare:CC (const_int 0) (match_dup 3)))
8605      (set (match_dup 0) (minus:SI (const_int 0) (match_dup 3)))])
8606    (set (match_dup 0)
8607         (plus:SI (plus:SI (match_dup 0) (match_dup 3))
8608                  (geu:SI (reg:CC CC_REGNUM) (const_int 0))))]
8609   "
8610   if (CONST_INT_P (operands[2]))
8611     operands[4] = plus_constant (SImode, operands[1], -INTVAL (operands[2]));
8612   else
8613     operands[4] = gen_rtx_MINUS (SImode, operands[1], operands[2]);
8614   ")
8616 (define_insn "*cond_move"
8617   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
8618         (if_then_else:SI (match_operator 3 "equality_operator"
8619                           [(match_operator 4 "arm_comparison_operator"
8620                             [(match_operand 5 "cc_register" "") (const_int 0)])
8621                            (const_int 0)])
8622                          (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
8623                          (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))]
8624   "TARGET_ARM"
8625   "*
8626     if (GET_CODE (operands[3]) == NE)
8627       {
8628         if (which_alternative != 1)
8629           output_asm_insn (\"mov%D4\\t%0, %2\", operands);
8630         if (which_alternative != 0)
8631           output_asm_insn (\"mov%d4\\t%0, %1\", operands);
8632         return \"\";
8633       }
8634     if (which_alternative != 0)
8635       output_asm_insn (\"mov%D4\\t%0, %1\", operands);
8636     if (which_alternative != 1)
8637       output_asm_insn (\"mov%d4\\t%0, %2\", operands);
8638     return \"\";
8639   "
8640   [(set_attr "conds" "use")
8641    (set_attr "type" "mov_reg,mov_reg,multiple")
8642    (set_attr "length" "4,4,8")]
8645 (define_insn "*cond_arith"
8646   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8647         (match_operator:SI 5 "shiftable_operator" 
8648          [(match_operator:SI 4 "arm_comparison_operator"
8649            [(match_operand:SI 2 "s_register_operand" "r,r")
8650             (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
8651           (match_operand:SI 1 "s_register_operand" "0,?r")]))
8652    (clobber (reg:CC CC_REGNUM))]
8653   "TARGET_ARM"
8654   "*
8655     if (GET_CODE (operands[4]) == LT && operands[3] == const0_rtx)
8656       return \"%i5\\t%0, %1, %2, lsr #31\";
8658     output_asm_insn (\"cmp\\t%2, %3\", operands);
8659     if (GET_CODE (operands[5]) == AND)
8660       output_asm_insn (\"mov%D4\\t%0, #0\", operands);
8661     else if (GET_CODE (operands[5]) == MINUS)
8662       output_asm_insn (\"rsb%D4\\t%0, %1, #0\", operands);
8663     else if (which_alternative != 0)
8664       output_asm_insn (\"mov%D4\\t%0, %1\", operands);
8665     return \"%i5%d4\\t%0, %1, #1\";
8666   "
8667   [(set_attr "conds" "clob")
8668    (set_attr "length" "12")
8669    (set_attr "type" "multiple")]
8672 (define_insn "*cond_sub"
8673   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8674         (minus:SI (match_operand:SI 1 "s_register_operand" "0,?r")
8675                   (match_operator:SI 4 "arm_comparison_operator"
8676                    [(match_operand:SI 2 "s_register_operand" "r,r")
8677                     (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
8678    (clobber (reg:CC CC_REGNUM))]
8679   "TARGET_ARM"
8680   "*
8681     output_asm_insn (\"cmp\\t%2, %3\", operands);
8682     if (which_alternative != 0)
8683       output_asm_insn (\"mov%D4\\t%0, %1\", operands);
8684     return \"sub%d4\\t%0, %1, #1\";
8685   "
8686   [(set_attr "conds" "clob")
8687    (set_attr "length" "8,12")
8688    (set_attr "type" "multiple")]
8691 (define_insn "*cmp_ite0"
8692   [(set (match_operand 6 "dominant_cc_register" "")
8693         (compare
8694          (if_then_else:SI
8695           (match_operator 4 "arm_comparison_operator"
8696            [(match_operand:SI 0 "s_register_operand"
8697                 "l,l,l,r,r,r,r,r,r")
8698             (match_operand:SI 1 "arm_add_operand"
8699                 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
8700           (match_operator:SI 5 "arm_comparison_operator"
8701            [(match_operand:SI 2 "s_register_operand"
8702                 "l,r,r,l,l,r,r,r,r")
8703             (match_operand:SI 3 "arm_add_operand"
8704                 "lPy,rI,L,lPy,lPy,rI,rI,L,L")])
8705           (const_int 0))
8706          (const_int 0)))]
8707   "TARGET_32BIT"
8708   "*
8709   {
8710     static const char * const cmp1[NUM_OF_COND_CMP][2] =
8711     {
8712       {\"cmp%d5\\t%0, %1\",
8713        \"cmp%d4\\t%2, %3\"},
8714       {\"cmn%d5\\t%0, #%n1\",
8715        \"cmp%d4\\t%2, %3\"},
8716       {\"cmp%d5\\t%0, %1\",
8717        \"cmn%d4\\t%2, #%n3\"},
8718       {\"cmn%d5\\t%0, #%n1\",
8719        \"cmn%d4\\t%2, #%n3\"}
8720     };
8721     static const char * const cmp2[NUM_OF_COND_CMP][2] =
8722     {
8723       {\"cmp\\t%2, %3\",
8724        \"cmp\\t%0, %1\"},
8725       {\"cmp\\t%2, %3\",
8726        \"cmn\\t%0, #%n1\"},
8727       {\"cmn\\t%2, #%n3\",
8728        \"cmp\\t%0, %1\"},
8729       {\"cmn\\t%2, #%n3\",
8730        \"cmn\\t%0, #%n1\"}
8731     };
8732     static const char * const ite[2] =
8733     {
8734       \"it\\t%d5\",
8735       \"it\\t%d4\"
8736     };
8737     static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
8738                                    CMP_CMP, CMN_CMP, CMP_CMP,
8739                                    CMN_CMP, CMP_CMN, CMN_CMN};
8740     int swap =
8741       comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
8743     output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
8744     if (TARGET_THUMB2) {
8745       output_asm_insn (ite[swap], operands);
8746     }
8747     output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
8748     return \"\";
8749   }"
8750   [(set_attr "conds" "set")
8751    (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
8752    (set_attr "type" "multiple")
8753    (set_attr_alternative "length"
8754       [(const_int 6)
8755        (const_int 8)
8756        (const_int 8)
8757        (const_int 8)
8758        (const_int 8)
8759        (if_then_else (eq_attr "is_thumb" "no")
8760            (const_int 8)
8761            (const_int 10))
8762        (if_then_else (eq_attr "is_thumb" "no")
8763            (const_int 8)
8764            (const_int 10))
8765        (if_then_else (eq_attr "is_thumb" "no")
8766            (const_int 8)
8767            (const_int 10))
8768        (if_then_else (eq_attr "is_thumb" "no")
8769            (const_int 8)
8770            (const_int 10))])]
8773 (define_insn "*cmp_ite1"
8774   [(set (match_operand 6 "dominant_cc_register" "")
8775         (compare
8776          (if_then_else:SI
8777           (match_operator 4 "arm_comparison_operator"
8778            [(match_operand:SI 0 "s_register_operand"
8779                 "l,l,l,r,r,r,r,r,r")
8780             (match_operand:SI 1 "arm_add_operand"
8781                 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
8782           (match_operator:SI 5 "arm_comparison_operator"
8783            [(match_operand:SI 2 "s_register_operand"
8784                 "l,r,r,l,l,r,r,r,r")
8785             (match_operand:SI 3 "arm_add_operand"
8786                 "lPy,rI,L,lPy,lPy,rI,rI,L,L")])
8787           (const_int 1))
8788          (const_int 0)))]
8789   "TARGET_32BIT"
8790   "*
8791   {
8792     static const char * const cmp1[NUM_OF_COND_CMP][2] =
8793     {
8794       {\"cmp\\t%0, %1\",
8795        \"cmp\\t%2, %3\"},
8796       {\"cmn\\t%0, #%n1\",
8797        \"cmp\\t%2, %3\"},
8798       {\"cmp\\t%0, %1\",
8799        \"cmn\\t%2, #%n3\"},
8800       {\"cmn\\t%0, #%n1\",
8801        \"cmn\\t%2, #%n3\"}
8802     };
8803     static const char * const cmp2[NUM_OF_COND_CMP][2] =
8804     {
8805       {\"cmp%d4\\t%2, %3\",
8806        \"cmp%D5\\t%0, %1\"},
8807       {\"cmp%d4\\t%2, %3\",
8808        \"cmn%D5\\t%0, #%n1\"},
8809       {\"cmn%d4\\t%2, #%n3\",
8810        \"cmp%D5\\t%0, %1\"},
8811       {\"cmn%d4\\t%2, #%n3\",
8812        \"cmn%D5\\t%0, #%n1\"}
8813     };
8814     static const char * const ite[2] =
8815     {
8816       \"it\\t%d4\",
8817       \"it\\t%D5\"
8818     };
8819     static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
8820                                    CMP_CMP, CMN_CMP, CMP_CMP,
8821                                    CMN_CMP, CMP_CMN, CMN_CMN};
8822     int swap =
8823       comparison_dominates_p (GET_CODE (operands[5]),
8824                               reverse_condition (GET_CODE (operands[4])));
8826     output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
8827     if (TARGET_THUMB2) {
8828       output_asm_insn (ite[swap], operands);
8829     }
8830     output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
8831     return \"\";
8832   }"
8833   [(set_attr "conds" "set")
8834    (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
8835    (set_attr_alternative "length"
8836       [(const_int 6)
8837        (const_int 8)
8838        (const_int 8)
8839        (const_int 8)
8840        (const_int 8)
8841        (if_then_else (eq_attr "is_thumb" "no")
8842            (const_int 8)
8843            (const_int 10))
8844        (if_then_else (eq_attr "is_thumb" "no")
8845            (const_int 8)
8846            (const_int 10))
8847        (if_then_else (eq_attr "is_thumb" "no")
8848            (const_int 8)
8849            (const_int 10))
8850        (if_then_else (eq_attr "is_thumb" "no")
8851            (const_int 8)
8852            (const_int 10))])
8853    (set_attr "type" "multiple")]
8856 (define_insn "*cmp_and"
8857   [(set (match_operand 6 "dominant_cc_register" "")
8858         (compare
8859          (and:SI
8860           (match_operator 4 "arm_comparison_operator"
8861            [(match_operand:SI 0 "s_register_operand" 
8862                 "l,l,l,r,r,r,r,r,r")
8863             (match_operand:SI 1 "arm_add_operand" 
8864                 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
8865           (match_operator:SI 5 "arm_comparison_operator"
8866            [(match_operand:SI 2 "s_register_operand" 
8867                 "l,r,r,l,l,r,r,r,r")
8868             (match_operand:SI 3 "arm_add_operand" 
8869                 "lPy,rI,L,lPy,lPy,rI,rI,L,L")]))
8870          (const_int 0)))]
8871   "TARGET_32BIT"
8872   "*
8873   {
8874     static const char *const cmp1[NUM_OF_COND_CMP][2] =
8875     {
8876       {\"cmp%d5\\t%0, %1\",
8877        \"cmp%d4\\t%2, %3\"},
8878       {\"cmn%d5\\t%0, #%n1\",
8879        \"cmp%d4\\t%2, %3\"},
8880       {\"cmp%d5\\t%0, %1\",
8881        \"cmn%d4\\t%2, #%n3\"},
8882       {\"cmn%d5\\t%0, #%n1\",
8883        \"cmn%d4\\t%2, #%n3\"}
8884     };
8885     static const char *const cmp2[NUM_OF_COND_CMP][2] =
8886     {
8887       {\"cmp\\t%2, %3\",
8888        \"cmp\\t%0, %1\"},
8889       {\"cmp\\t%2, %3\",
8890        \"cmn\\t%0, #%n1\"},
8891       {\"cmn\\t%2, #%n3\",
8892        \"cmp\\t%0, %1\"},
8893       {\"cmn\\t%2, #%n3\",
8894        \"cmn\\t%0, #%n1\"}
8895     };
8896     static const char *const ite[2] =
8897     {
8898       \"it\\t%d5\",
8899       \"it\\t%d4\"
8900     };
8901     static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
8902                                    CMP_CMP, CMN_CMP, CMP_CMP,
8903                                    CMN_CMP, CMP_CMN, CMN_CMN};
8904     int swap =
8905       comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
8907     output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
8908     if (TARGET_THUMB2) {
8909       output_asm_insn (ite[swap], operands);
8910     }
8911     output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
8912     return \"\";
8913   }"
8914   [(set_attr "conds" "set")
8915    (set_attr "predicable" "no")
8916    (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
8917    (set_attr_alternative "length"
8918       [(const_int 6)
8919        (const_int 8)
8920        (const_int 8)
8921        (const_int 8)
8922        (const_int 8)
8923        (if_then_else (eq_attr "is_thumb" "no")
8924            (const_int 8)
8925            (const_int 10))
8926        (if_then_else (eq_attr "is_thumb" "no")
8927            (const_int 8)
8928            (const_int 10))
8929        (if_then_else (eq_attr "is_thumb" "no")
8930            (const_int 8)
8931            (const_int 10))
8932        (if_then_else (eq_attr "is_thumb" "no")
8933            (const_int 8)
8934            (const_int 10))])
8935    (set_attr "type" "multiple")]
8938 (define_insn "*cmp_ior"
8939   [(set (match_operand 6 "dominant_cc_register" "")
8940         (compare
8941          (ior:SI
8942           (match_operator 4 "arm_comparison_operator"
8943            [(match_operand:SI 0 "s_register_operand"
8944                 "l,l,l,r,r,r,r,r,r")
8945             (match_operand:SI 1 "arm_add_operand"
8946                 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
8947           (match_operator:SI 5 "arm_comparison_operator"
8948            [(match_operand:SI 2 "s_register_operand"
8949                 "l,r,r,l,l,r,r,r,r")
8950             (match_operand:SI 3 "arm_add_operand"
8951                 "lPy,rI,L,lPy,lPy,rI,rI,L,L")]))
8952          (const_int 0)))]
8953   "TARGET_32BIT"
8954   "*
8955   {
8956     static const char *const cmp1[NUM_OF_COND_CMP][2] =
8957     {
8958       {\"cmp\\t%0, %1\",
8959        \"cmp\\t%2, %3\"},
8960       {\"cmn\\t%0, #%n1\",
8961        \"cmp\\t%2, %3\"},
8962       {\"cmp\\t%0, %1\",
8963        \"cmn\\t%2, #%n3\"},
8964       {\"cmn\\t%0, #%n1\",
8965        \"cmn\\t%2, #%n3\"}
8966     };
8967     static const char *const cmp2[NUM_OF_COND_CMP][2] =
8968     {
8969       {\"cmp%D4\\t%2, %3\",
8970        \"cmp%D5\\t%0, %1\"},
8971       {\"cmp%D4\\t%2, %3\",
8972        \"cmn%D5\\t%0, #%n1\"},
8973       {\"cmn%D4\\t%2, #%n3\",
8974        \"cmp%D5\\t%0, %1\"},
8975       {\"cmn%D4\\t%2, #%n3\",
8976        \"cmn%D5\\t%0, #%n1\"}
8977     };
8978     static const char *const ite[2] =
8979     {
8980       \"it\\t%D4\",
8981       \"it\\t%D5\"
8982     };
8983     static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
8984                                    CMP_CMP, CMN_CMP, CMP_CMP,
8985                                    CMN_CMP, CMP_CMN, CMN_CMN};
8986     int swap =
8987       comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
8989     output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
8990     if (TARGET_THUMB2) {
8991       output_asm_insn (ite[swap], operands);
8992     }
8993     output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
8994     return \"\";
8995   }
8996   "
8997   [(set_attr "conds" "set")
8998    (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
8999    (set_attr_alternative "length"
9000       [(const_int 6)
9001        (const_int 8)
9002        (const_int 8)
9003        (const_int 8)
9004        (const_int 8)
9005        (if_then_else (eq_attr "is_thumb" "no")
9006            (const_int 8)
9007            (const_int 10))
9008        (if_then_else (eq_attr "is_thumb" "no")
9009            (const_int 8)
9010            (const_int 10))
9011        (if_then_else (eq_attr "is_thumb" "no")
9012            (const_int 8)
9013            (const_int 10))
9014        (if_then_else (eq_attr "is_thumb" "no")
9015            (const_int 8)
9016            (const_int 10))])
9017    (set_attr "type" "multiple")]
9020 (define_insn_and_split "*ior_scc_scc"
9021   [(set (match_operand:SI 0 "s_register_operand" "=Ts")
9022         (ior:SI (match_operator:SI 3 "arm_comparison_operator"
9023                  [(match_operand:SI 1 "s_register_operand" "r")
9024                   (match_operand:SI 2 "arm_add_operand" "rIL")])
9025                 (match_operator:SI 6 "arm_comparison_operator"
9026                  [(match_operand:SI 4 "s_register_operand" "r")
9027                   (match_operand:SI 5 "arm_add_operand" "rIL")])))
9028    (clobber (reg:CC CC_REGNUM))]
9029   "TARGET_32BIT
9030    && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_OR_Y)
9031        != CCmode)"
9032   "#"
9033   "TARGET_32BIT && reload_completed"
9034   [(set (match_dup 7)
9035         (compare
9036          (ior:SI
9037           (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9038           (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9039          (const_int 0)))
9040    (set (match_dup 0) (ne:SI (match_dup 7) (const_int 0)))]
9041   "operands[7]
9042      = gen_rtx_REG (arm_select_dominance_cc_mode (operands[3], operands[6],
9043                                                   DOM_CC_X_OR_Y),
9044                     CC_REGNUM);"
9045   [(set_attr "conds" "clob")
9046    (set_attr "length" "16")
9047    (set_attr "type" "multiple")]
9050 ; If the above pattern is followed by a CMP insn, then the compare is 
9051 ; redundant, since we can rework the conditional instruction that follows.
9052 (define_insn_and_split "*ior_scc_scc_cmp"
9053   [(set (match_operand 0 "dominant_cc_register" "")
9054         (compare (ior:SI (match_operator:SI 3 "arm_comparison_operator"
9055                           [(match_operand:SI 1 "s_register_operand" "r")
9056                            (match_operand:SI 2 "arm_add_operand" "rIL")])
9057                          (match_operator:SI 6 "arm_comparison_operator"
9058                           [(match_operand:SI 4 "s_register_operand" "r")
9059                            (match_operand:SI 5 "arm_add_operand" "rIL")]))
9060                  (const_int 0)))
9061    (set (match_operand:SI 7 "s_register_operand" "=Ts")
9062         (ior:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9063                 (match_op_dup 6 [(match_dup 4) (match_dup 5)])))]
9064   "TARGET_32BIT"
9065   "#"
9066   "TARGET_32BIT && reload_completed"
9067   [(set (match_dup 0)
9068         (compare
9069          (ior:SI
9070           (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9071           (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9072          (const_int 0)))
9073    (set (match_dup 7) (ne:SI (match_dup 0) (const_int 0)))]
9074   ""
9075   [(set_attr "conds" "set")
9076    (set_attr "length" "16")
9077    (set_attr "type" "multiple")]
9080 (define_insn_and_split "*and_scc_scc"
9081   [(set (match_operand:SI 0 "s_register_operand" "=Ts")
9082         (and:SI (match_operator:SI 3 "arm_comparison_operator"
9083                  [(match_operand:SI 1 "s_register_operand" "r")
9084                   (match_operand:SI 2 "arm_add_operand" "rIL")])
9085                 (match_operator:SI 6 "arm_comparison_operator"
9086                  [(match_operand:SI 4 "s_register_operand" "r")
9087                   (match_operand:SI 5 "arm_add_operand" "rIL")])))
9088    (clobber (reg:CC CC_REGNUM))]
9089   "TARGET_32BIT
9090    && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
9091        != CCmode)"
9092   "#"
9093   "TARGET_32BIT && reload_completed
9094    && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
9095        != CCmode)"
9096   [(set (match_dup 7)
9097         (compare
9098          (and:SI
9099           (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9100           (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9101          (const_int 0)))
9102    (set (match_dup 0) (ne:SI (match_dup 7) (const_int 0)))]
9103   "operands[7]
9104      = gen_rtx_REG (arm_select_dominance_cc_mode (operands[3], operands[6],
9105                                                   DOM_CC_X_AND_Y),
9106                     CC_REGNUM);"
9107   [(set_attr "conds" "clob")
9108    (set_attr "length" "16")
9109    (set_attr "type" "multiple")]
9112 ; If the above pattern is followed by a CMP insn, then the compare is 
9113 ; redundant, since we can rework the conditional instruction that follows.
9114 (define_insn_and_split "*and_scc_scc_cmp"
9115   [(set (match_operand 0 "dominant_cc_register" "")
9116         (compare (and:SI (match_operator:SI 3 "arm_comparison_operator"
9117                           [(match_operand:SI 1 "s_register_operand" "r")
9118                            (match_operand:SI 2 "arm_add_operand" "rIL")])
9119                          (match_operator:SI 6 "arm_comparison_operator"
9120                           [(match_operand:SI 4 "s_register_operand" "r")
9121                            (match_operand:SI 5 "arm_add_operand" "rIL")]))
9122                  (const_int 0)))
9123    (set (match_operand:SI 7 "s_register_operand" "=Ts")
9124         (and:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9125                 (match_op_dup 6 [(match_dup 4) (match_dup 5)])))]
9126   "TARGET_32BIT"
9127   "#"
9128   "TARGET_32BIT && reload_completed"
9129   [(set (match_dup 0)
9130         (compare
9131          (and:SI
9132           (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9133           (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9134          (const_int 0)))
9135    (set (match_dup 7) (ne:SI (match_dup 0) (const_int 0)))]
9136   ""
9137   [(set_attr "conds" "set")
9138    (set_attr "length" "16")
9139    (set_attr "type" "multiple")]
9142 ;; If there is no dominance in the comparison, then we can still save an
9143 ;; instruction in the AND case, since we can know that the second compare
9144 ;; need only zero the value if false (if true, then the value is already
9145 ;; correct).
9146 (define_insn_and_split "*and_scc_scc_nodom"
9147   [(set (match_operand:SI 0 "s_register_operand" "=&Ts,&Ts,&Ts")
9148         (and:SI (match_operator:SI 3 "arm_comparison_operator"
9149                  [(match_operand:SI 1 "s_register_operand" "r,r,0")
9150                   (match_operand:SI 2 "arm_add_operand" "rIL,0,rIL")])
9151                 (match_operator:SI 6 "arm_comparison_operator"
9152                  [(match_operand:SI 4 "s_register_operand" "r,r,r")
9153                   (match_operand:SI 5 "arm_add_operand" "rIL,rIL,rIL")])))
9154    (clobber (reg:CC CC_REGNUM))]
9155   "TARGET_32BIT
9156    && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
9157        == CCmode)"
9158   "#"
9159   "TARGET_32BIT && reload_completed"
9160   [(parallel [(set (match_dup 0)
9161                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
9162               (clobber (reg:CC CC_REGNUM))])
9163    (set (match_dup 7) (match_op_dup 8 [(match_dup 4) (match_dup 5)]))
9164    (set (match_dup 0)
9165         (if_then_else:SI (match_op_dup 6 [(match_dup 7) (const_int 0)])
9166                          (match_dup 0)
9167                          (const_int 0)))]
9168   "operands[7] = gen_rtx_REG (SELECT_CC_MODE (GET_CODE (operands[6]),
9169                                               operands[4], operands[5]),
9170                               CC_REGNUM);
9171    operands[8] = gen_rtx_COMPARE (GET_MODE (operands[7]), operands[4],
9172                                   operands[5]);"
9173   [(set_attr "conds" "clob")
9174    (set_attr "length" "20")
9175    (set_attr "type" "multiple")]
9178 (define_split
9179   [(set (reg:CC_NOOV CC_REGNUM)
9180         (compare:CC_NOOV (ior:SI
9181                           (and:SI (match_operand:SI 0 "s_register_operand" "")
9182                                   (const_int 1))
9183                           (match_operator:SI 1 "arm_comparison_operator"
9184                            [(match_operand:SI 2 "s_register_operand" "")
9185                             (match_operand:SI 3 "arm_add_operand" "")]))
9186                          (const_int 0)))
9187    (clobber (match_operand:SI 4 "s_register_operand" ""))]
9188   "TARGET_ARM"
9189   [(set (match_dup 4)
9190         (ior:SI (match_op_dup 1 [(match_dup 2) (match_dup 3)])
9191                 (match_dup 0)))
9192    (set (reg:CC_NOOV CC_REGNUM)
9193         (compare:CC_NOOV (and:SI (match_dup 4) (const_int 1))
9194                          (const_int 0)))]
9195   "")
9197 (define_split
9198   [(set (reg:CC_NOOV CC_REGNUM)
9199         (compare:CC_NOOV (ior:SI
9200                           (match_operator:SI 1 "arm_comparison_operator"
9201                            [(match_operand:SI 2 "s_register_operand" "")
9202                             (match_operand:SI 3 "arm_add_operand" "")])
9203                           (and:SI (match_operand:SI 0 "s_register_operand" "")
9204                                   (const_int 1)))
9205                          (const_int 0)))
9206    (clobber (match_operand:SI 4 "s_register_operand" ""))]
9207   "TARGET_ARM"
9208   [(set (match_dup 4)
9209         (ior:SI (match_op_dup 1 [(match_dup 2) (match_dup 3)])
9210                 (match_dup 0)))
9211    (set (reg:CC_NOOV CC_REGNUM)
9212         (compare:CC_NOOV (and:SI (match_dup 4) (const_int 1))
9213                          (const_int 0)))]
9214   "")
9215 ;; ??? The conditional patterns above need checking for Thumb-2 usefulness
9217 (define_insn_and_split "*negscc"
9218   [(set (match_operand:SI 0 "s_register_operand" "=r")
9219         (neg:SI (match_operator 3 "arm_comparison_operator"
9220                  [(match_operand:SI 1 "s_register_operand" "r")
9221                   (match_operand:SI 2 "arm_rhs_operand" "rI")])))
9222    (clobber (reg:CC CC_REGNUM))]
9223   "TARGET_ARM"
9224   "#"
9225   "&& reload_completed"
9226   [(const_int 0)]
9227   {
9228     rtx cc_reg = gen_rtx_REG (CCmode, CC_REGNUM);
9230     if (GET_CODE (operands[3]) == LT && operands[2] == const0_rtx)
9231        {
9232          /* Emit mov\\t%0, %1, asr #31 */
9233          emit_insn (gen_rtx_SET (VOIDmode,
9234                                  operands[0],
9235                                  gen_rtx_ASHIFTRT (SImode,
9236                                                    operands[1],
9237                                                    GEN_INT (31))));
9238          DONE;
9239        }
9240      else if (GET_CODE (operands[3]) == NE)
9241        {
9242         /* Emit subs\\t%0, %1, %2\;mvnne\\t%0, #0 */
9243         if (CONST_INT_P (operands[2]))
9244           emit_insn (gen_cmpsi2_addneg (operands[0], operands[1], operands[2],
9245                                         GEN_INT (- INTVAL (operands[2]))));
9246         else
9247           emit_insn (gen_subsi3_compare (operands[0], operands[1], operands[2]));
9249         emit_insn (gen_rtx_COND_EXEC (VOIDmode,
9250                                       gen_rtx_NE (SImode,
9251                                                   cc_reg,
9252                                                   const0_rtx),
9253                                       gen_rtx_SET (SImode,
9254                                                    operands[0],
9255                                                    GEN_INT (~0))));
9256         DONE;
9257       }
9258     else
9259       {
9260         /* Emit: cmp\\t%1, %2\;mov%D3\\t%0, #0\;mvn%d3\\t%0, #0 */
9261         emit_insn (gen_rtx_SET (VOIDmode,
9262                                 cc_reg,
9263                                 gen_rtx_COMPARE (CCmode, operands[1], operands[2])));
9264         enum rtx_code rc = GET_CODE (operands[3]);
9266         rc = reverse_condition (rc);
9267         emit_insn (gen_rtx_COND_EXEC (VOIDmode,
9268                                       gen_rtx_fmt_ee (rc,
9269                                                       VOIDmode,
9270                                                       cc_reg,
9271                                                       const0_rtx),
9272                                       gen_rtx_SET (VOIDmode, operands[0], const0_rtx)));
9273         rc = GET_CODE (operands[3]);
9274         emit_insn (gen_rtx_COND_EXEC (VOIDmode,
9275                                       gen_rtx_fmt_ee (rc,
9276                                                       VOIDmode,
9277                                                       cc_reg,
9278                                                       const0_rtx),
9279                                       gen_rtx_SET (VOIDmode,
9280                                                    operands[0],
9281                                                    GEN_INT (~0))));
9282         DONE;
9283       }
9284      FAIL;
9285   }
9286   [(set_attr "conds" "clob")
9287    (set_attr "length" "12")
9288    (set_attr "type" "multiple")]
9291 (define_insn_and_split "movcond_addsi"
9292   [(set (match_operand:SI 0 "s_register_operand" "=r,l,r")
9293         (if_then_else:SI
9294          (match_operator 5 "comparison_operator"
9295           [(plus:SI (match_operand:SI 3 "s_register_operand" "r,r,r")
9296                     (match_operand:SI 4 "arm_add_operand" "rIL,rIL,rIL"))
9297             (const_int 0)])
9298          (match_operand:SI 1 "arm_rhs_operand" "rI,rPy,r")
9299          (match_operand:SI 2 "arm_rhs_operand" "rI,rPy,r")))
9300    (clobber (reg:CC CC_REGNUM))]
9301    "TARGET_32BIT"
9302    "#"
9303    "&& reload_completed"
9304   [(set (reg:CC_NOOV CC_REGNUM)
9305         (compare:CC_NOOV
9306          (plus:SI (match_dup 3)
9307                   (match_dup 4))
9308          (const_int 0)))
9309    (set (match_dup 0) (match_dup 1))
9310    (cond_exec (match_dup 6)
9311               (set (match_dup 0) (match_dup 2)))]
9312   "
9313   {
9314     enum machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[5]),
9315                                              operands[3], operands[4]);
9316     enum rtx_code rc = GET_CODE (operands[5]);
9318     operands[6] = gen_rtx_REG (mode, CC_REGNUM);
9319     gcc_assert (!(mode == CCFPmode || mode == CCFPEmode));
9320     rc = reverse_condition (rc);
9322     operands[6] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
9323   }
9324   "
9325   [(set_attr "conds" "clob")
9326    (set_attr "enabled_for_depr_it" "no,yes,yes")
9327    (set_attr "type" "multiple")]
9330 (define_insn "movcond"
9331   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9332         (if_then_else:SI
9333          (match_operator 5 "arm_comparison_operator"
9334           [(match_operand:SI 3 "s_register_operand" "r,r,r")
9335            (match_operand:SI 4 "arm_add_operand" "rIL,rIL,rIL")])
9336          (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
9337          (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
9338    (clobber (reg:CC CC_REGNUM))]
9339   "TARGET_ARM"
9340   "*
9341   if (GET_CODE (operands[5]) == LT
9342       && (operands[4] == const0_rtx))
9343     {
9344       if (which_alternative != 1 && REG_P (operands[1]))
9345         {
9346           if (operands[2] == const0_rtx)
9347             return \"and\\t%0, %1, %3, asr #31\";
9348           return \"ands\\t%0, %1, %3, asr #32\;movcc\\t%0, %2\";
9349         }
9350       else if (which_alternative != 0 && REG_P (operands[2]))
9351         {
9352           if (operands[1] == const0_rtx)
9353             return \"bic\\t%0, %2, %3, asr #31\";
9354           return \"bics\\t%0, %2, %3, asr #32\;movcs\\t%0, %1\";
9355         }
9356       /* The only case that falls through to here is when both ops 1 & 2
9357          are constants.  */
9358     }
9360   if (GET_CODE (operands[5]) == GE
9361       && (operands[4] == const0_rtx))
9362     {
9363       if (which_alternative != 1 && REG_P (operands[1]))
9364         {
9365           if (operands[2] == const0_rtx)
9366             return \"bic\\t%0, %1, %3, asr #31\";
9367           return \"bics\\t%0, %1, %3, asr #32\;movcs\\t%0, %2\";
9368         }
9369       else if (which_alternative != 0 && REG_P (operands[2]))
9370         {
9371           if (operands[1] == const0_rtx)
9372             return \"and\\t%0, %2, %3, asr #31\";
9373           return \"ands\\t%0, %2, %3, asr #32\;movcc\\t%0, %1\";
9374         }
9375       /* The only case that falls through to here is when both ops 1 & 2
9376          are constants.  */
9377     }
9378   if (CONST_INT_P (operands[4])
9379       && !const_ok_for_arm (INTVAL (operands[4])))
9380     output_asm_insn (\"cmn\\t%3, #%n4\", operands);
9381   else
9382     output_asm_insn (\"cmp\\t%3, %4\", operands);
9383   if (which_alternative != 0)
9384     output_asm_insn (\"mov%d5\\t%0, %1\", operands);
9385   if (which_alternative != 1)
9386     output_asm_insn (\"mov%D5\\t%0, %2\", operands);
9387   return \"\";
9388   "
9389   [(set_attr "conds" "clob")
9390    (set_attr "length" "8,8,12")
9391    (set_attr "type" "multiple")]
9394 ;; ??? The patterns below need checking for Thumb-2 usefulness.
9396 (define_insn "*ifcompare_plus_move"
9397   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9398         (if_then_else:SI (match_operator 6 "arm_comparison_operator"
9399                           [(match_operand:SI 4 "s_register_operand" "r,r")
9400                            (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
9401                          (plus:SI
9402                           (match_operand:SI 2 "s_register_operand" "r,r")
9403                           (match_operand:SI 3 "arm_add_operand" "rIL,rIL"))
9404                          (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))
9405    (clobber (reg:CC CC_REGNUM))]
9406   "TARGET_ARM"
9407   "#"
9408   [(set_attr "conds" "clob")
9409    (set_attr "length" "8,12")
9410    (set_attr "type" "multiple")]
9413 (define_insn "*if_plus_move"
9414   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
9415         (if_then_else:SI
9416          (match_operator 4 "arm_comparison_operator"
9417           [(match_operand 5 "cc_register" "") (const_int 0)])
9418          (plus:SI
9419           (match_operand:SI 2 "s_register_operand" "r,r,r,r")
9420           (match_operand:SI 3 "arm_add_operand" "rI,L,rI,L"))
9421          (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")))]
9422   "TARGET_ARM"
9423   "@
9424    add%d4\\t%0, %2, %3
9425    sub%d4\\t%0, %2, #%n3
9426    add%d4\\t%0, %2, %3\;mov%D4\\t%0, %1
9427    sub%d4\\t%0, %2, #%n3\;mov%D4\\t%0, %1"
9428   [(set_attr "conds" "use")
9429    (set_attr "length" "4,4,8,8")
9430    (set_attr_alternative "type"
9431                          [(if_then_else (match_operand 3 "const_int_operand" "")
9432                                         (const_string "alu_imm" )
9433                                         (const_string "alu_sreg"))
9434                           (const_string "alu_imm")
9435                           (const_string "alu_sreg")
9436                           (const_string "alu_sreg")])]
9439 (define_insn "*ifcompare_move_plus"
9440   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9441         (if_then_else:SI (match_operator 6 "arm_comparison_operator"
9442                           [(match_operand:SI 4 "s_register_operand" "r,r")
9443                            (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
9444                          (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
9445                          (plus:SI
9446                           (match_operand:SI 2 "s_register_operand" "r,r")
9447                           (match_operand:SI 3 "arm_add_operand" "rIL,rIL"))))
9448    (clobber (reg:CC CC_REGNUM))]
9449   "TARGET_ARM"
9450   "#"
9451   [(set_attr "conds" "clob")
9452    (set_attr "length" "8,12")
9453    (set_attr "type" "multiple")]
9456 (define_insn "*if_move_plus"
9457   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
9458         (if_then_else:SI
9459          (match_operator 4 "arm_comparison_operator"
9460           [(match_operand 5 "cc_register" "") (const_int 0)])
9461          (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")
9462          (plus:SI
9463           (match_operand:SI 2 "s_register_operand" "r,r,r,r")
9464           (match_operand:SI 3 "arm_add_operand" "rI,L,rI,L"))))]
9465   "TARGET_ARM"
9466   "@
9467    add%D4\\t%0, %2, %3
9468    sub%D4\\t%0, %2, #%n3
9469    add%D4\\t%0, %2, %3\;mov%d4\\t%0, %1
9470    sub%D4\\t%0, %2, #%n3\;mov%d4\\t%0, %1"
9471   [(set_attr "conds" "use")
9472    (set_attr "length" "4,4,8,8")
9473    (set_attr "type" "alu_sreg,alu_imm,multiple,multiple")]
9476 (define_insn "*ifcompare_arith_arith"
9477   [(set (match_operand:SI 0 "s_register_operand" "=r")
9478         (if_then_else:SI (match_operator 9 "arm_comparison_operator"
9479                           [(match_operand:SI 5 "s_register_operand" "r")
9480                            (match_operand:SI 6 "arm_add_operand" "rIL")])
9481                          (match_operator:SI 8 "shiftable_operator"
9482                           [(match_operand:SI 1 "s_register_operand" "r")
9483                            (match_operand:SI 2 "arm_rhs_operand" "rI")])
9484                          (match_operator:SI 7 "shiftable_operator"
9485                           [(match_operand:SI 3 "s_register_operand" "r")
9486                            (match_operand:SI 4 "arm_rhs_operand" "rI")])))
9487    (clobber (reg:CC CC_REGNUM))]
9488   "TARGET_ARM"
9489   "#"
9490   [(set_attr "conds" "clob")
9491    (set_attr "length" "12")
9492    (set_attr "type" "multiple")]
9495 (define_insn "*if_arith_arith"
9496   [(set (match_operand:SI 0 "s_register_operand" "=r")
9497         (if_then_else:SI (match_operator 5 "arm_comparison_operator"
9498                           [(match_operand 8 "cc_register" "") (const_int 0)])
9499                          (match_operator:SI 6 "shiftable_operator"
9500                           [(match_operand:SI 1 "s_register_operand" "r")
9501                            (match_operand:SI 2 "arm_rhs_operand" "rI")])
9502                          (match_operator:SI 7 "shiftable_operator"
9503                           [(match_operand:SI 3 "s_register_operand" "r")
9504                            (match_operand:SI 4 "arm_rhs_operand" "rI")])))]
9505   "TARGET_ARM"
9506   "%I6%d5\\t%0, %1, %2\;%I7%D5\\t%0, %3, %4"
9507   [(set_attr "conds" "use")
9508    (set_attr "length" "8")
9509    (set_attr "type" "multiple")]
9512 (define_insn "*ifcompare_arith_move"
9513   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9514         (if_then_else:SI (match_operator 6 "arm_comparison_operator"
9515                           [(match_operand:SI 2 "s_register_operand" "r,r")
9516                            (match_operand:SI 3 "arm_add_operand" "rIL,rIL")])
9517                          (match_operator:SI 7 "shiftable_operator"
9518                           [(match_operand:SI 4 "s_register_operand" "r,r")
9519                            (match_operand:SI 5 "arm_rhs_operand" "rI,rI")])
9520                          (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))
9521    (clobber (reg:CC CC_REGNUM))]
9522   "TARGET_ARM"
9523   "*
9524   /* If we have an operation where (op x 0) is the identity operation and
9525      the conditional operator is LT or GE and we are comparing against zero and
9526      everything is in registers then we can do this in two instructions.  */
9527   if (operands[3] == const0_rtx
9528       && GET_CODE (operands[7]) != AND
9529       && REG_P (operands[5])
9530       && REG_P (operands[1])
9531       && REGNO (operands[1]) == REGNO (operands[4])
9532       && REGNO (operands[4]) != REGNO (operands[0]))
9533     {
9534       if (GET_CODE (operands[6]) == LT)
9535         return \"and\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\";
9536       else if (GET_CODE (operands[6]) == GE)
9537         return \"bic\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\";
9538     }
9539   if (CONST_INT_P (operands[3])
9540       && !const_ok_for_arm (INTVAL (operands[3])))
9541     output_asm_insn (\"cmn\\t%2, #%n3\", operands);
9542   else
9543     output_asm_insn (\"cmp\\t%2, %3\", operands);
9544   output_asm_insn (\"%I7%d6\\t%0, %4, %5\", operands);
9545   if (which_alternative != 0)
9546     return \"mov%D6\\t%0, %1\";
9547   return \"\";
9548   "
9549   [(set_attr "conds" "clob")
9550    (set_attr "length" "8,12")
9551    (set_attr "type" "multiple")]
9554 (define_insn "*if_arith_move"
9555   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9556         (if_then_else:SI (match_operator 4 "arm_comparison_operator"
9557                           [(match_operand 6 "cc_register" "") (const_int 0)])
9558                          (match_operator:SI 5 "shiftable_operator"
9559                           [(match_operand:SI 2 "s_register_operand" "r,r")
9560                            (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
9561                          (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))]
9562   "TARGET_ARM"
9563   "@
9564    %I5%d4\\t%0, %2, %3
9565    %I5%d4\\t%0, %2, %3\;mov%D4\\t%0, %1"
9566   [(set_attr "conds" "use")
9567    (set_attr "length" "4,8")
9568    (set_attr "type" "alu_shift_reg,multiple")]
9571 (define_insn "*ifcompare_move_arith"
9572   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9573         (if_then_else:SI (match_operator 6 "arm_comparison_operator"
9574                           [(match_operand:SI 4 "s_register_operand" "r,r")
9575                            (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
9576                          (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
9577                          (match_operator:SI 7 "shiftable_operator"
9578                           [(match_operand:SI 2 "s_register_operand" "r,r")
9579                            (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
9580    (clobber (reg:CC CC_REGNUM))]
9581   "TARGET_ARM"
9582   "*
9583   /* If we have an operation where (op x 0) is the identity operation and
9584      the conditional operator is LT or GE and we are comparing against zero and
9585      everything is in registers then we can do this in two instructions */
9586   if (operands[5] == const0_rtx
9587       && GET_CODE (operands[7]) != AND
9588       && REG_P (operands[3])
9589       && REG_P (operands[1])
9590       && REGNO (operands[1]) == REGNO (operands[2])
9591       && REGNO (operands[2]) != REGNO (operands[0]))
9592     {
9593       if (GET_CODE (operands[6]) == GE)
9594         return \"and\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\";
9595       else if (GET_CODE (operands[6]) == LT)
9596         return \"bic\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\";
9597     }
9599   if (CONST_INT_P (operands[5])
9600       && !const_ok_for_arm (INTVAL (operands[5])))
9601     output_asm_insn (\"cmn\\t%4, #%n5\", operands);
9602   else
9603     output_asm_insn (\"cmp\\t%4, %5\", operands);
9605   if (which_alternative != 0)
9606     output_asm_insn (\"mov%d6\\t%0, %1\", operands);
9607   return \"%I7%D6\\t%0, %2, %3\";
9608   "
9609   [(set_attr "conds" "clob")
9610    (set_attr "length" "8,12")
9611    (set_attr "type" "multiple")]
9614 (define_insn "*if_move_arith"
9615   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9616         (if_then_else:SI
9617          (match_operator 4 "arm_comparison_operator"
9618           [(match_operand 6 "cc_register" "") (const_int 0)])
9619          (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
9620          (match_operator:SI 5 "shiftable_operator"
9621           [(match_operand:SI 2 "s_register_operand" "r,r")
9622            (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))]
9623   "TARGET_ARM"
9624   "@
9625    %I5%D4\\t%0, %2, %3
9626    %I5%D4\\t%0, %2, %3\;mov%d4\\t%0, %1"
9627   [(set_attr "conds" "use")
9628    (set_attr "length" "4,8")
9629    (set_attr "type" "alu_shift_reg,multiple")]
9632 (define_insn "*ifcompare_move_not"
9633   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9634         (if_then_else:SI
9635          (match_operator 5 "arm_comparison_operator"
9636           [(match_operand:SI 3 "s_register_operand" "r,r")
9637            (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
9638          (match_operand:SI 1 "arm_not_operand" "0,?rIK")
9639          (not:SI
9640           (match_operand:SI 2 "s_register_operand" "r,r"))))
9641    (clobber (reg:CC CC_REGNUM))]
9642   "TARGET_ARM"
9643   "#"
9644   [(set_attr "conds" "clob")
9645    (set_attr "length" "8,12")
9646    (set_attr "type" "multiple")]
9649 (define_insn "*if_move_not"
9650   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9651         (if_then_else:SI
9652          (match_operator 4 "arm_comparison_operator"
9653           [(match_operand 3 "cc_register" "") (const_int 0)])
9654          (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
9655          (not:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))))]
9656   "TARGET_ARM"
9657   "@
9658    mvn%D4\\t%0, %2
9659    mov%d4\\t%0, %1\;mvn%D4\\t%0, %2
9660    mvn%d4\\t%0, #%B1\;mvn%D4\\t%0, %2"
9661   [(set_attr "conds" "use")
9662    (set_attr "type" "mvn_reg")
9663    (set_attr "length" "4,8,8")
9664    (set_attr "type" "mvn_reg,multiple,multiple")]
9667 (define_insn "*ifcompare_not_move"
9668   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9669         (if_then_else:SI 
9670          (match_operator 5 "arm_comparison_operator"
9671           [(match_operand:SI 3 "s_register_operand" "r,r")
9672            (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
9673          (not:SI
9674           (match_operand:SI 2 "s_register_operand" "r,r"))
9675          (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
9676    (clobber (reg:CC CC_REGNUM))]
9677   "TARGET_ARM"
9678   "#"
9679   [(set_attr "conds" "clob")
9680    (set_attr "length" "8,12")
9681    (set_attr "type" "multiple")]
9684 (define_insn "*if_not_move"
9685   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9686         (if_then_else:SI
9687          (match_operator 4 "arm_comparison_operator"
9688           [(match_operand 3 "cc_register" "") (const_int 0)])
9689          (not:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))
9690          (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
9691   "TARGET_ARM"
9692   "@
9693    mvn%d4\\t%0, %2
9694    mov%D4\\t%0, %1\;mvn%d4\\t%0, %2
9695    mvn%D4\\t%0, #%B1\;mvn%d4\\t%0, %2"
9696   [(set_attr "conds" "use")
9697    (set_attr "type" "mvn_reg,multiple,multiple")
9698    (set_attr "length" "4,8,8")]
9701 (define_insn "*ifcompare_shift_move"
9702   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9703         (if_then_else:SI
9704          (match_operator 6 "arm_comparison_operator"
9705           [(match_operand:SI 4 "s_register_operand" "r,r")
9706            (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
9707          (match_operator:SI 7 "shift_operator"
9708           [(match_operand:SI 2 "s_register_operand" "r,r")
9709            (match_operand:SI 3 "arm_rhs_operand" "rM,rM")])
9710          (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
9711    (clobber (reg:CC CC_REGNUM))]
9712   "TARGET_ARM"
9713   "#"
9714   [(set_attr "conds" "clob")
9715    (set_attr "length" "8,12")
9716    (set_attr "type" "multiple")]
9719 (define_insn "*if_shift_move"
9720   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9721         (if_then_else:SI
9722          (match_operator 5 "arm_comparison_operator"
9723           [(match_operand 6 "cc_register" "") (const_int 0)])
9724          (match_operator:SI 4 "shift_operator"
9725           [(match_operand:SI 2 "s_register_operand" "r,r,r")
9726            (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM")])
9727          (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
9728   "TARGET_ARM"
9729   "@
9730    mov%d5\\t%0, %2%S4
9731    mov%D5\\t%0, %1\;mov%d5\\t%0, %2%S4
9732    mvn%D5\\t%0, #%B1\;mov%d5\\t%0, %2%S4"
9733   [(set_attr "conds" "use")
9734    (set_attr "shift" "2")
9735    (set_attr "length" "4,8,8")
9736    (set_attr "type" "mov_shift_reg,multiple,multiple")]
9739 (define_insn "*ifcompare_move_shift"
9740   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9741         (if_then_else:SI
9742          (match_operator 6 "arm_comparison_operator"
9743           [(match_operand:SI 4 "s_register_operand" "r,r")
9744            (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
9745          (match_operand:SI 1 "arm_not_operand" "0,?rIK")
9746          (match_operator:SI 7 "shift_operator"
9747           [(match_operand:SI 2 "s_register_operand" "r,r")
9748            (match_operand:SI 3 "arm_rhs_operand" "rM,rM")])))
9749    (clobber (reg:CC CC_REGNUM))]
9750   "TARGET_ARM"
9751   "#"
9752   [(set_attr "conds" "clob")
9753    (set_attr "length" "8,12")
9754    (set_attr "type" "multiple")]
9757 (define_insn "*if_move_shift"
9758   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9759         (if_then_else:SI
9760          (match_operator 5 "arm_comparison_operator"
9761           [(match_operand 6 "cc_register" "") (const_int 0)])
9762          (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
9763          (match_operator:SI 4 "shift_operator"
9764           [(match_operand:SI 2 "s_register_operand" "r,r,r")
9765            (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM")])))]
9766   "TARGET_ARM"
9767   "@
9768    mov%D5\\t%0, %2%S4
9769    mov%d5\\t%0, %1\;mov%D5\\t%0, %2%S4
9770    mvn%d5\\t%0, #%B1\;mov%D5\\t%0, %2%S4"
9771   [(set_attr "conds" "use")
9772    (set_attr "shift" "2")
9773    (set_attr "length" "4,8,8")
9774    (set_attr "type" "mov_shift_reg,multiple,multiple")]
9777 (define_insn "*ifcompare_shift_shift"
9778   [(set (match_operand:SI 0 "s_register_operand" "=r")
9779         (if_then_else:SI
9780          (match_operator 7 "arm_comparison_operator"
9781           [(match_operand:SI 5 "s_register_operand" "r")
9782            (match_operand:SI 6 "arm_add_operand" "rIL")])
9783          (match_operator:SI 8 "shift_operator"
9784           [(match_operand:SI 1 "s_register_operand" "r")
9785            (match_operand:SI 2 "arm_rhs_operand" "rM")])
9786          (match_operator:SI 9 "shift_operator"
9787           [(match_operand:SI 3 "s_register_operand" "r")
9788            (match_operand:SI 4 "arm_rhs_operand" "rM")])))
9789    (clobber (reg:CC CC_REGNUM))]
9790   "TARGET_ARM"
9791   "#"
9792   [(set_attr "conds" "clob")
9793    (set_attr "length" "12")
9794    (set_attr "type" "multiple")]
9797 (define_insn "*if_shift_shift"
9798   [(set (match_operand:SI 0 "s_register_operand" "=r")
9799         (if_then_else:SI
9800          (match_operator 5 "arm_comparison_operator"
9801           [(match_operand 8 "cc_register" "") (const_int 0)])
9802          (match_operator:SI 6 "shift_operator"
9803           [(match_operand:SI 1 "s_register_operand" "r")
9804            (match_operand:SI 2 "arm_rhs_operand" "rM")])
9805          (match_operator:SI 7 "shift_operator"
9806           [(match_operand:SI 3 "s_register_operand" "r")
9807            (match_operand:SI 4 "arm_rhs_operand" "rM")])))]
9808   "TARGET_ARM"
9809   "mov%d5\\t%0, %1%S6\;mov%D5\\t%0, %3%S7"
9810   [(set_attr "conds" "use")
9811    (set_attr "shift" "1")
9812    (set_attr "length" "8")
9813    (set (attr "type") (if_then_else
9814                         (and (match_operand 2 "const_int_operand" "")
9815                              (match_operand 4 "const_int_operand" ""))
9816                       (const_string "mov_shift")
9817                       (const_string "mov_shift_reg")))]
9820 (define_insn "*ifcompare_not_arith"
9821   [(set (match_operand:SI 0 "s_register_operand" "=r")
9822         (if_then_else:SI
9823          (match_operator 6 "arm_comparison_operator"
9824           [(match_operand:SI 4 "s_register_operand" "r")
9825            (match_operand:SI 5 "arm_add_operand" "rIL")])
9826          (not:SI (match_operand:SI 1 "s_register_operand" "r"))
9827          (match_operator:SI 7 "shiftable_operator"
9828           [(match_operand:SI 2 "s_register_operand" "r")
9829            (match_operand:SI 3 "arm_rhs_operand" "rI")])))
9830    (clobber (reg:CC CC_REGNUM))]
9831   "TARGET_ARM"
9832   "#"
9833   [(set_attr "conds" "clob")
9834    (set_attr "length" "12")
9835    (set_attr "type" "multiple")]
9838 (define_insn "*if_not_arith"
9839   [(set (match_operand:SI 0 "s_register_operand" "=r")
9840         (if_then_else:SI
9841          (match_operator 5 "arm_comparison_operator"
9842           [(match_operand 4 "cc_register" "") (const_int 0)])
9843          (not:SI (match_operand:SI 1 "s_register_operand" "r"))
9844          (match_operator:SI 6 "shiftable_operator"
9845           [(match_operand:SI 2 "s_register_operand" "r")
9846            (match_operand:SI 3 "arm_rhs_operand" "rI")])))]
9847   "TARGET_ARM"
9848   "mvn%d5\\t%0, %1\;%I6%D5\\t%0, %2, %3"
9849   [(set_attr "conds" "use")
9850    (set_attr "type" "mvn_reg")
9851    (set_attr "length" "8")]
9854 (define_insn "*ifcompare_arith_not"
9855   [(set (match_operand:SI 0 "s_register_operand" "=r")
9856         (if_then_else:SI
9857          (match_operator 6 "arm_comparison_operator"
9858           [(match_operand:SI 4 "s_register_operand" "r")
9859            (match_operand:SI 5 "arm_add_operand" "rIL")])
9860          (match_operator:SI 7 "shiftable_operator"
9861           [(match_operand:SI 2 "s_register_operand" "r")
9862            (match_operand:SI 3 "arm_rhs_operand" "rI")])
9863          (not:SI (match_operand:SI 1 "s_register_operand" "r"))))
9864    (clobber (reg:CC CC_REGNUM))]
9865   "TARGET_ARM"
9866   "#"
9867   [(set_attr "conds" "clob")
9868    (set_attr "length" "12")
9869    (set_attr "type" "multiple")]
9872 (define_insn "*if_arith_not"
9873   [(set (match_operand:SI 0 "s_register_operand" "=r")
9874         (if_then_else:SI
9875          (match_operator 5 "arm_comparison_operator"
9876           [(match_operand 4 "cc_register" "") (const_int 0)])
9877          (match_operator:SI 6 "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   "TARGET_ARM"
9882   "mvn%D5\\t%0, %1\;%I6%d5\\t%0, %2, %3"
9883   [(set_attr "conds" "use")
9884    (set_attr "type" "multiple")
9885    (set_attr "length" "8")]
9888 (define_insn "*ifcompare_neg_move"
9889   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9890         (if_then_else:SI
9891          (match_operator 5 "arm_comparison_operator"
9892           [(match_operand:SI 3 "s_register_operand" "r,r")
9893            (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
9894          (neg:SI (match_operand:SI 2 "s_register_operand" "r,r"))
9895          (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
9896    (clobber (reg:CC CC_REGNUM))]
9897   "TARGET_ARM"
9898   "#"
9899   [(set_attr "conds" "clob")
9900    (set_attr "length" "8,12")
9901    (set_attr "type" "multiple")]
9904 (define_insn "*if_neg_move"
9905   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9906         (if_then_else:SI
9907          (match_operator 4 "arm_comparison_operator"
9908           [(match_operand 3 "cc_register" "") (const_int 0)])
9909          (neg:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))
9910          (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
9911   "TARGET_ARM"
9912   "@
9913    rsb%d4\\t%0, %2, #0
9914    mov%D4\\t%0, %1\;rsb%d4\\t%0, %2, #0
9915    mvn%D4\\t%0, #%B1\;rsb%d4\\t%0, %2, #0"
9916   [(set_attr "conds" "use")
9917    (set_attr "length" "4,8,8")
9918    (set_attr "type" "logic_shift_imm,multiple,multiple")]
9921 (define_insn "*ifcompare_move_neg"
9922   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9923         (if_then_else:SI
9924          (match_operator 5 "arm_comparison_operator"
9925           [(match_operand:SI 3 "s_register_operand" "r,r")
9926            (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
9927          (match_operand:SI 1 "arm_not_operand" "0,?rIK")
9928          (neg:SI (match_operand:SI 2 "s_register_operand" "r,r"))))
9929    (clobber (reg:CC CC_REGNUM))]
9930   "TARGET_ARM"
9931   "#"
9932   [(set_attr "conds" "clob")
9933    (set_attr "length" "8,12")
9934    (set_attr "type" "multiple")]
9937 (define_insn "*if_move_neg"
9938   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9939         (if_then_else:SI
9940          (match_operator 4 "arm_comparison_operator"
9941           [(match_operand 3 "cc_register" "") (const_int 0)])
9942          (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
9943          (neg:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))))]
9944   "TARGET_ARM"
9945   "@
9946    rsb%D4\\t%0, %2, #0
9947    mov%d4\\t%0, %1\;rsb%D4\\t%0, %2, #0
9948    mvn%d4\\t%0, #%B1\;rsb%D4\\t%0, %2, #0"
9949   [(set_attr "conds" "use")
9950    (set_attr "length" "4,8,8")
9951    (set_attr "type" "logic_shift_imm,multiple,multiple")]
9954 (define_insn "*arith_adjacentmem"
9955   [(set (match_operand:SI 0 "s_register_operand" "=r")
9956         (match_operator:SI 1 "shiftable_operator"
9957          [(match_operand:SI 2 "memory_operand" "m")
9958           (match_operand:SI 3 "memory_operand" "m")]))
9959    (clobber (match_scratch:SI 4 "=r"))]
9960   "TARGET_ARM && adjacent_mem_locations (operands[2], operands[3])"
9961   "*
9962   {
9963     rtx ldm[3];
9964     rtx arith[4];
9965     rtx base_reg;
9966     HOST_WIDE_INT val1 = 0, val2 = 0;
9968     if (REGNO (operands[0]) > REGNO (operands[4]))
9969       {
9970         ldm[1] = operands[4];
9971         ldm[2] = operands[0];
9972       }
9973     else
9974       {
9975         ldm[1] = operands[0];
9976         ldm[2] = operands[4];
9977       }
9979     base_reg = XEXP (operands[2], 0);
9981     if (!REG_P (base_reg))
9982       {
9983         val1 = INTVAL (XEXP (base_reg, 1));
9984         base_reg = XEXP (base_reg, 0);
9985       }
9987     if (!REG_P (XEXP (operands[3], 0)))
9988       val2 = INTVAL (XEXP (XEXP (operands[3], 0), 1));
9990     arith[0] = operands[0];
9991     arith[3] = operands[1];
9993     if (val1 < val2)
9994       {
9995         arith[1] = ldm[1];
9996         arith[2] = ldm[2];
9997       }
9998     else
9999       {
10000         arith[1] = ldm[2];
10001         arith[2] = ldm[1];
10002       }
10004     ldm[0] = base_reg;
10005     if (val1 !=0 && val2 != 0)
10006       {
10007         rtx ops[3];
10009         if (val1 == 4 || val2 == 4)
10010           /* Other val must be 8, since we know they are adjacent and neither
10011              is zero.  */
10012           output_asm_insn (\"ldm%(ib%)\\t%0, {%1, %2}\", ldm);
10013         else if (const_ok_for_arm (val1) || const_ok_for_arm (-val1))
10014           {
10015             ldm[0] = ops[0] = operands[4];
10016             ops[1] = base_reg;
10017             ops[2] = GEN_INT (val1);
10018             output_add_immediate (ops);
10019             if (val1 < val2)
10020               output_asm_insn (\"ldm%(ia%)\\t%0, {%1, %2}\", ldm);
10021             else
10022               output_asm_insn (\"ldm%(da%)\\t%0, {%1, %2}\", ldm);
10023           }
10024         else
10025           {
10026             /* Offset is out of range for a single add, so use two ldr.  */
10027             ops[0] = ldm[1];
10028             ops[1] = base_reg;
10029             ops[2] = GEN_INT (val1);
10030             output_asm_insn (\"ldr%?\\t%0, [%1, %2]\", ops);
10031             ops[0] = ldm[2];
10032             ops[2] = GEN_INT (val2);
10033             output_asm_insn (\"ldr%?\\t%0, [%1, %2]\", ops);
10034           }
10035       }
10036     else if (val1 != 0)
10037       {
10038         if (val1 < val2)
10039           output_asm_insn (\"ldm%(da%)\\t%0, {%1, %2}\", ldm);
10040         else
10041           output_asm_insn (\"ldm%(ia%)\\t%0, {%1, %2}\", ldm);
10042       }
10043     else
10044       {
10045         if (val1 < val2)
10046           output_asm_insn (\"ldm%(ia%)\\t%0, {%1, %2}\", ldm);
10047         else
10048           output_asm_insn (\"ldm%(da%)\\t%0, {%1, %2}\", ldm);
10049       }
10050     output_asm_insn (\"%I3%?\\t%0, %1, %2\", arith);
10051     return \"\";
10052   }"
10053   [(set_attr "length" "12")
10054    (set_attr "predicable" "yes")
10055    (set_attr "type" "load1")]
10058 ; This pattern is never tried by combine, so do it as a peephole
10060 (define_peephole2
10061   [(set (match_operand:SI 0 "arm_general_register_operand" "")
10062         (match_operand:SI 1 "arm_general_register_operand" ""))
10063    (set (reg:CC CC_REGNUM)
10064         (compare:CC (match_dup 1) (const_int 0)))]
10065   "TARGET_ARM"
10066   [(parallel [(set (reg:CC CC_REGNUM) (compare:CC (match_dup 1) (const_int 0)))
10067               (set (match_dup 0) (match_dup 1))])]
10068   ""
10071 (define_split
10072   [(set (match_operand:SI 0 "s_register_operand" "")
10073         (and:SI (ge:SI (match_operand:SI 1 "s_register_operand" "")
10074                        (const_int 0))
10075                 (neg:SI (match_operator:SI 2 "arm_comparison_operator"
10076                          [(match_operand:SI 3 "s_register_operand" "")
10077                           (match_operand:SI 4 "arm_rhs_operand" "")]))))
10078    (clobber (match_operand:SI 5 "s_register_operand" ""))]
10079   "TARGET_ARM"
10080   [(set (match_dup 5) (not:SI (ashiftrt:SI (match_dup 1) (const_int 31))))
10081    (set (match_dup 0) (and:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
10082                               (match_dup 5)))]
10083   ""
10086 ;; This split can be used because CC_Z mode implies that the following
10087 ;; branch will be an equality, or an unsigned inequality, so the sign
10088 ;; extension is not needed.
10090 (define_split
10091   [(set (reg:CC_Z CC_REGNUM)
10092         (compare:CC_Z
10093          (ashift:SI (subreg:SI (match_operand:QI 0 "memory_operand" "") 0)
10094                     (const_int 24))
10095          (match_operand 1 "const_int_operand" "")))
10096    (clobber (match_scratch:SI 2 ""))]
10097   "TARGET_ARM
10098    && (((unsigned HOST_WIDE_INT) INTVAL (operands[1]))
10099        == (((unsigned HOST_WIDE_INT) INTVAL (operands[1])) >> 24) << 24)"
10100   [(set (match_dup 2) (zero_extend:SI (match_dup 0)))
10101    (set (reg:CC CC_REGNUM) (compare:CC (match_dup 2) (match_dup 1)))]
10102   "
10103   operands[1] = GEN_INT (((unsigned long) INTVAL (operands[1])) >> 24);
10104   "
10106 ;; ??? Check the patterns above for Thumb-2 usefulness
10108 (define_expand "prologue"
10109   [(clobber (const_int 0))]
10110   "TARGET_EITHER"
10111   "if (TARGET_32BIT)
10112      arm_expand_prologue ();
10113    else
10114      thumb1_expand_prologue ();
10115   DONE;
10116   "
10119 (define_expand "epilogue"
10120   [(clobber (const_int 0))]
10121   "TARGET_EITHER"
10122   "
10123   if (crtl->calls_eh_return)
10124     emit_insn (gen_force_register_use (gen_rtx_REG (Pmode, 2)));
10125   if (TARGET_THUMB1)
10126    {
10127      thumb1_expand_epilogue ();
10128      emit_jump_insn (gen_rtx_UNSPEC_VOLATILE (VOIDmode,
10129                      gen_rtvec (1, ret_rtx), VUNSPEC_EPILOGUE));
10130    }
10131   else if (HAVE_return)
10132    {
10133      /* HAVE_return is testing for USE_RETURN_INSN (FALSE).  Hence,
10134         no need for explicit testing again.  */
10135      emit_jump_insn (gen_return ());
10136    }
10137   else if (TARGET_32BIT)
10138    {
10139     arm_expand_epilogue (true);
10140    }
10141   DONE;
10142   "
10145 ;; Note - although unspec_volatile's USE all hard registers,
10146 ;; USEs are ignored after relaod has completed.  Thus we need
10147 ;; to add an unspec of the link register to ensure that flow
10148 ;; does not think that it is unused by the sibcall branch that
10149 ;; will replace the standard function epilogue.
10150 (define_expand "sibcall_epilogue"
10151    [(parallel [(unspec:SI [(reg:SI LR_REGNUM)] UNSPEC_REGISTER_USE)
10152                (unspec_volatile [(return)] VUNSPEC_EPILOGUE)])]
10153    "TARGET_32BIT"
10154    "
10155    arm_expand_epilogue (false);
10156    DONE;
10157    "
10160 (define_expand "eh_epilogue"
10161   [(use (match_operand:SI 0 "register_operand" ""))
10162    (use (match_operand:SI 1 "register_operand" ""))
10163    (use (match_operand:SI 2 "register_operand" ""))]
10164   "TARGET_EITHER"
10165   "
10166   {
10167     cfun->machine->eh_epilogue_sp_ofs = operands[1];
10168     if (!REG_P (operands[2]) || REGNO (operands[2]) != 2)
10169       {
10170         rtx ra = gen_rtx_REG (Pmode, 2);
10172         emit_move_insn (ra, operands[2]);
10173         operands[2] = ra;
10174       }
10175     /* This is a hack -- we may have crystalized the function type too
10176        early.  */
10177     cfun->machine->func_type = 0;
10178   }"
10181 ;; This split is only used during output to reduce the number of patterns
10182 ;; that need assembler instructions adding to them.  We allowed the setting
10183 ;; of the conditions to be implicit during rtl generation so that
10184 ;; the conditional compare patterns would work.  However this conflicts to
10185 ;; some extent with the conditional data operations, so we have to split them
10186 ;; up again here.
10188 ;; ??? Need to audit these splitters for Thumb-2.  Why isn't normal
10189 ;; conditional execution sufficient?
10191 (define_split
10192   [(set (match_operand:SI 0 "s_register_operand" "")
10193         (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10194                           [(match_operand 2 "" "") (match_operand 3 "" "")])
10195                          (match_dup 0)
10196                          (match_operand 4 "" "")))
10197    (clobber (reg:CC CC_REGNUM))]
10198   "TARGET_ARM && reload_completed"
10199   [(set (match_dup 5) (match_dup 6))
10200    (cond_exec (match_dup 7)
10201               (set (match_dup 0) (match_dup 4)))]
10202   "
10203   {
10204     enum machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10205                                              operands[2], operands[3]);
10206     enum rtx_code rc = GET_CODE (operands[1]);
10208     operands[5] = gen_rtx_REG (mode, CC_REGNUM);
10209     operands[6] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10210     if (mode == CCFPmode || mode == CCFPEmode)
10211       rc = reverse_condition_maybe_unordered (rc);
10212     else
10213       rc = reverse_condition (rc);
10215     operands[7] = gen_rtx_fmt_ee (rc, VOIDmode, operands[5], const0_rtx);
10216   }"
10219 (define_split
10220   [(set (match_operand:SI 0 "s_register_operand" "")
10221         (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10222                           [(match_operand 2 "" "") (match_operand 3 "" "")])
10223                          (match_operand 4 "" "")
10224                          (match_dup 0)))
10225    (clobber (reg:CC CC_REGNUM))]
10226   "TARGET_ARM && reload_completed"
10227   [(set (match_dup 5) (match_dup 6))
10228    (cond_exec (match_op_dup 1 [(match_dup 5) (const_int 0)])
10229               (set (match_dup 0) (match_dup 4)))]
10230   "
10231   {
10232     enum machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10233                                              operands[2], operands[3]);
10235     operands[5] = gen_rtx_REG (mode, CC_REGNUM);
10236     operands[6] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10237   }"
10240 (define_split
10241   [(set (match_operand:SI 0 "s_register_operand" "")
10242         (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10243                           [(match_operand 2 "" "") (match_operand 3 "" "")])
10244                          (match_operand 4 "" "")
10245                          (match_operand 5 "" "")))
10246    (clobber (reg:CC CC_REGNUM))]
10247   "TARGET_ARM && reload_completed"
10248   [(set (match_dup 6) (match_dup 7))
10249    (cond_exec (match_op_dup 1 [(match_dup 6) (const_int 0)])
10250               (set (match_dup 0) (match_dup 4)))
10251    (cond_exec (match_dup 8)
10252               (set (match_dup 0) (match_dup 5)))]
10253   "
10254   {
10255     enum machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10256                                              operands[2], operands[3]);
10257     enum rtx_code rc = GET_CODE (operands[1]);
10259     operands[6] = gen_rtx_REG (mode, CC_REGNUM);
10260     operands[7] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10261     if (mode == CCFPmode || mode == CCFPEmode)
10262       rc = reverse_condition_maybe_unordered (rc);
10263     else
10264       rc = reverse_condition (rc);
10266     operands[8] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
10267   }"
10270 (define_split
10271   [(set (match_operand:SI 0 "s_register_operand" "")
10272         (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10273                           [(match_operand:SI 2 "s_register_operand" "")
10274                            (match_operand:SI 3 "arm_add_operand" "")])
10275                          (match_operand:SI 4 "arm_rhs_operand" "")
10276                          (not:SI
10277                           (match_operand:SI 5 "s_register_operand" ""))))
10278    (clobber (reg:CC CC_REGNUM))]
10279   "TARGET_ARM && reload_completed"
10280   [(set (match_dup 6) (match_dup 7))
10281    (cond_exec (match_op_dup 1 [(match_dup 6) (const_int 0)])
10282               (set (match_dup 0) (match_dup 4)))
10283    (cond_exec (match_dup 8)
10284               (set (match_dup 0) (not:SI (match_dup 5))))]
10285   "
10286   {
10287     enum machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10288                                              operands[2], operands[3]);
10289     enum rtx_code rc = GET_CODE (operands[1]);
10291     operands[6] = gen_rtx_REG (mode, CC_REGNUM);
10292     operands[7] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10293     if (mode == CCFPmode || mode == CCFPEmode)
10294       rc = reverse_condition_maybe_unordered (rc);
10295     else
10296       rc = reverse_condition (rc);
10298     operands[8] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
10299   }"
10302 (define_insn "*cond_move_not"
10303   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10304         (if_then_else:SI (match_operator 4 "arm_comparison_operator"
10305                           [(match_operand 3 "cc_register" "") (const_int 0)])
10306                          (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
10307                          (not:SI
10308                           (match_operand:SI 2 "s_register_operand" "r,r"))))]
10309   "TARGET_ARM"
10310   "@
10311    mvn%D4\\t%0, %2
10312    mov%d4\\t%0, %1\;mvn%D4\\t%0, %2"
10313   [(set_attr "conds" "use")
10314    (set_attr "type" "mvn_reg,multiple")
10315    (set_attr "length" "4,8")]
10318 ;; The next two patterns occur when an AND operation is followed by a
10319 ;; scc insn sequence 
10321 (define_insn "*sign_extract_onebit"
10322   [(set (match_operand:SI 0 "s_register_operand" "=r")
10323         (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
10324                          (const_int 1)
10325                          (match_operand:SI 2 "const_int_operand" "n")))
10326     (clobber (reg:CC CC_REGNUM))]
10327   "TARGET_ARM"
10328   "*
10329     operands[2] = GEN_INT (1 << INTVAL (operands[2]));
10330     output_asm_insn (\"ands\\t%0, %1, %2\", operands);
10331     return \"mvnne\\t%0, #0\";
10332   "
10333   [(set_attr "conds" "clob")
10334    (set_attr "length" "8")
10335    (set_attr "type" "multiple")]
10338 (define_insn "*not_signextract_onebit"
10339   [(set (match_operand:SI 0 "s_register_operand" "=r")
10340         (not:SI
10341          (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
10342                           (const_int 1)
10343                           (match_operand:SI 2 "const_int_operand" "n"))))
10344    (clobber (reg:CC CC_REGNUM))]
10345   "TARGET_ARM"
10346   "*
10347     operands[2] = GEN_INT (1 << INTVAL (operands[2]));
10348     output_asm_insn (\"tst\\t%1, %2\", operands);
10349     output_asm_insn (\"mvneq\\t%0, #0\", operands);
10350     return \"movne\\t%0, #0\";
10351   "
10352   [(set_attr "conds" "clob")
10353    (set_attr "length" "12")
10354    (set_attr "type" "multiple")]
10356 ;; ??? The above patterns need auditing for Thumb-2
10358 ;; Push multiple registers to the stack.  Registers are in parallel (use ...)
10359 ;; expressions.  For simplicity, the first register is also in the unspec
10360 ;; part.
10361 ;; To avoid the usage of GNU extension, the length attribute is computed
10362 ;; in a C function arm_attr_length_push_multi.
10363 (define_insn "*push_multi"
10364   [(match_parallel 2 "multi_register_push"
10365     [(set (match_operand:BLK 0 "push_mult_memory_operand" "")
10366           (unspec:BLK [(match_operand:SI 1 "s_register_operand" "")]
10367                       UNSPEC_PUSH_MULT))])]
10368   ""
10369   "*
10370   {
10371     int num_saves = XVECLEN (operands[2], 0);
10372      
10373     /* For the StrongARM at least it is faster to
10374        use STR to store only a single register.
10375        In Thumb mode always use push, and the assembler will pick
10376        something appropriate.  */
10377     if (num_saves == 1 && TARGET_ARM)
10378       output_asm_insn (\"str%?\\t%1, [%m0, #-4]!\", operands);
10379     else
10380       {
10381         int i;
10382         char pattern[100];
10384         if (TARGET_ARM)
10385             strcpy (pattern, \"stm%(fd%)\\t%m0!, {%1\");
10386         else if (TARGET_THUMB2)
10387             strcpy (pattern, \"push%?\\t{%1\");
10388         else
10389             strcpy (pattern, \"push\\t{%1\");
10391         for (i = 1; i < num_saves; i++)
10392           {
10393             strcat (pattern, \", %|\");
10394             strcat (pattern,
10395                     reg_names[REGNO (XEXP (XVECEXP (operands[2], 0, i), 0))]);
10396           }
10398         strcat (pattern, \"}\");
10399         output_asm_insn (pattern, operands);
10400       }
10402     return \"\";
10403   }"
10404   [(set_attr "type" "store4")
10405    (set (attr "length")
10406         (symbol_ref "arm_attr_length_push_multi (operands[2], operands[1])"))]
10409 (define_insn "stack_tie"
10410   [(set (mem:BLK (scratch))
10411         (unspec:BLK [(match_operand:SI 0 "s_register_operand" "rk")
10412                      (match_operand:SI 1 "s_register_operand" "rk")]
10413                     UNSPEC_PRLG_STK))]
10414   ""
10415   ""
10416   [(set_attr "length" "0")
10417    (set_attr "type" "block")]
10420 ;; Pop (as used in epilogue RTL)
10422 (define_insn "*load_multiple_with_writeback"
10423   [(match_parallel 0 "load_multiple_operation"
10424     [(set (match_operand:SI 1 "s_register_operand" "+rk")
10425           (plus:SI (match_dup 1)
10426                    (match_operand:SI 2 "const_int_I_operand" "I")))
10427      (set (match_operand:SI 3 "s_register_operand" "=rk")
10428           (mem:SI (match_dup 1)))
10429         ])]
10430   "TARGET_32BIT && (reload_in_progress || reload_completed)"
10431   "*
10432   {
10433     arm_output_multireg_pop (operands, /*return_pc=*/false,
10434                                        /*cond=*/const_true_rtx,
10435                                        /*reverse=*/false,
10436                                        /*update=*/true);
10437     return \"\";
10438   }
10439   "
10440   [(set_attr "type" "load4")
10441    (set_attr "predicable" "yes")]
10444 ;; Pop with return (as used in epilogue RTL)
10446 ;; This instruction is generated when the registers are popped at the end of
10447 ;; epilogue.  Here, instead of popping the value into LR and then generating
10448 ;; jump to LR, value is popped into PC directly.  Hence, the pattern is combined
10449 ;;  with (return).
10450 (define_insn "*pop_multiple_with_writeback_and_return"
10451   [(match_parallel 0 "pop_multiple_return"
10452     [(return)
10453      (set (match_operand:SI 1 "s_register_operand" "+rk")
10454           (plus:SI (match_dup 1)
10455                    (match_operand:SI 2 "const_int_I_operand" "I")))
10456      (set (match_operand:SI 3 "s_register_operand" "=rk")
10457           (mem:SI (match_dup 1)))
10458         ])]
10459   "TARGET_32BIT && (reload_in_progress || reload_completed)"
10460   "*
10461   {
10462     arm_output_multireg_pop (operands, /*return_pc=*/true,
10463                                        /*cond=*/const_true_rtx,
10464                                        /*reverse=*/false,
10465                                        /*update=*/true);
10466     return \"\";
10467   }
10468   "
10469   [(set_attr "type" "load4")
10470    (set_attr "predicable" "yes")]
10473 (define_insn "*pop_multiple_with_return"
10474   [(match_parallel 0 "pop_multiple_return"
10475     [(return)
10476      (set (match_operand:SI 2 "s_register_operand" "=rk")
10477           (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
10478         ])]
10479   "TARGET_32BIT && (reload_in_progress || reload_completed)"
10480   "*
10481   {
10482     arm_output_multireg_pop (operands, /*return_pc=*/true,
10483                                        /*cond=*/const_true_rtx,
10484                                        /*reverse=*/false,
10485                                        /*update=*/false);
10486     return \"\";
10487   }
10488   "
10489   [(set_attr "type" "load4")
10490    (set_attr "predicable" "yes")]
10493 ;; Load into PC and return
10494 (define_insn "*ldr_with_return"
10495   [(return)
10496    (set (reg:SI PC_REGNUM)
10497         (mem:SI (post_inc:SI (match_operand:SI 0 "s_register_operand" "+rk"))))]
10498   "TARGET_32BIT && (reload_in_progress || reload_completed)"
10499   "ldr%?\t%|pc, [%0], #4"
10500   [(set_attr "type" "load1")
10501    (set_attr "predicable" "yes")]
10503 ;; Pop for floating point registers (as used in epilogue RTL)
10504 (define_insn "*vfp_pop_multiple_with_writeback"
10505   [(match_parallel 0 "pop_multiple_fp"
10506     [(set (match_operand:SI 1 "s_register_operand" "+rk")
10507           (plus:SI (match_dup 1)
10508                    (match_operand:SI 2 "const_int_I_operand" "I")))
10509      (set (match_operand:DF 3 "vfp_hard_register_operand" "")
10510           (mem:DF (match_dup 1)))])]
10511   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
10512   "*
10513   {
10514     int num_regs = XVECLEN (operands[0], 0);
10515     char pattern[100];
10516     rtx op_list[2];
10517     strcpy (pattern, \"fldmfdd\\t\");
10518     strcat (pattern, reg_names[REGNO (SET_DEST (XVECEXP (operands[0], 0, 0)))]);
10519     strcat (pattern, \"!, {\");
10520     op_list[0] = XEXP (XVECEXP (operands[0], 0, 1), 0);
10521     strcat (pattern, \"%P0\");
10522     if ((num_regs - 1) > 1)
10523       {
10524         strcat (pattern, \"-%P1\");
10525         op_list [1] = XEXP (XVECEXP (operands[0], 0, num_regs - 1), 0);
10526       }
10528     strcat (pattern, \"}\");
10529     output_asm_insn (pattern, op_list);
10530     return \"\";
10531   }
10532   "
10533   [(set_attr "type" "load4")
10534    (set_attr "conds" "unconditional")
10535    (set_attr "predicable" "no")]
10538 ;; Special patterns for dealing with the constant pool
10540 (define_insn "align_4"
10541   [(unspec_volatile [(const_int 0)] VUNSPEC_ALIGN)]
10542   "TARGET_EITHER"
10543   "*
10544   assemble_align (32);
10545   return \"\";
10546   "
10547   [(set_attr "type" "no_insn")]
10550 (define_insn "align_8"
10551   [(unspec_volatile [(const_int 0)] VUNSPEC_ALIGN8)]
10552   "TARGET_EITHER"
10553   "*
10554   assemble_align (64);
10555   return \"\";
10556   "
10557   [(set_attr "type" "no_insn")]
10560 (define_insn "consttable_end"
10561   [(unspec_volatile [(const_int 0)] VUNSPEC_POOL_END)]
10562   "TARGET_EITHER"
10563   "*
10564   making_const_table = FALSE;
10565   return \"\";
10566   "
10567   [(set_attr "type" "no_insn")]
10570 (define_insn "consttable_4"
10571   [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_4)]
10572   "TARGET_EITHER"
10573   "*
10574   {
10575     rtx x = operands[0];
10576     making_const_table = TRUE;
10577     switch (GET_MODE_CLASS (GET_MODE (x)))
10578       {
10579       case MODE_FLOAT:
10580         if (GET_MODE (x) == HFmode)
10581           arm_emit_fp16_const (x);
10582         else
10583           {
10584             REAL_VALUE_TYPE r;
10585             REAL_VALUE_FROM_CONST_DOUBLE (r, x);
10586             assemble_real (r, GET_MODE (x), BITS_PER_WORD);
10587           }
10588         break;
10589       default:
10590         /* XXX: Sometimes gcc does something really dumb and ends up with
10591            a HIGH in a constant pool entry, usually because it's trying to
10592            load into a VFP register.  We know this will always be used in
10593            combination with a LO_SUM which ignores the high bits, so just
10594            strip off the HIGH.  */
10595         if (GET_CODE (x) == HIGH)
10596           x = XEXP (x, 0);
10597         assemble_integer (x, 4, BITS_PER_WORD, 1);
10598         mark_symbol_refs_as_used (x);
10599         break;
10600       }
10601     return \"\";
10602   }"
10603   [(set_attr "length" "4")
10604    (set_attr "type" "no_insn")]
10607 (define_insn "consttable_8"
10608   [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_8)]
10609   "TARGET_EITHER"
10610   "*
10611   {
10612     making_const_table = TRUE;
10613     switch (GET_MODE_CLASS (GET_MODE (operands[0])))
10614       {
10615        case MODE_FLOAT:
10616         {
10617           REAL_VALUE_TYPE r;
10618           REAL_VALUE_FROM_CONST_DOUBLE (r, operands[0]);
10619           assemble_real (r, GET_MODE (operands[0]), BITS_PER_WORD);
10620           break;
10621         }
10622       default:
10623         assemble_integer (operands[0], 8, BITS_PER_WORD, 1);
10624         break;
10625       }
10626     return \"\";
10627   }"
10628   [(set_attr "length" "8")
10629    (set_attr "type" "no_insn")]
10632 (define_insn "consttable_16"
10633   [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_16)]
10634   "TARGET_EITHER"
10635   "*
10636   {
10637     making_const_table = TRUE;
10638     switch (GET_MODE_CLASS (GET_MODE (operands[0])))
10639       {
10640        case MODE_FLOAT:
10641         {
10642           REAL_VALUE_TYPE r;
10643           REAL_VALUE_FROM_CONST_DOUBLE (r, operands[0]);
10644           assemble_real (r, GET_MODE (operands[0]), BITS_PER_WORD);
10645           break;
10646         }
10647       default:
10648         assemble_integer (operands[0], 16, BITS_PER_WORD, 1);
10649         break;
10650       }
10651     return \"\";
10652   }"
10653   [(set_attr "length" "16")
10654    (set_attr "type" "no_insn")]
10657 ;; V5 Instructions,
10659 (define_insn "clzsi2"
10660   [(set (match_operand:SI 0 "s_register_operand" "=r")
10661         (clz:SI (match_operand:SI 1 "s_register_operand" "r")))]
10662   "TARGET_32BIT && arm_arch5"
10663   "clz%?\\t%0, %1"
10664   [(set_attr "predicable" "yes")
10665    (set_attr "predicable_short_it" "no")
10666    (set_attr "type" "clz")])
10668 (define_insn "rbitsi2"
10669   [(set (match_operand:SI 0 "s_register_operand" "=r")
10670         (unspec:SI [(match_operand:SI 1 "s_register_operand" "r")] UNSPEC_RBIT))]
10671   "TARGET_32BIT && arm_arch_thumb2"
10672   "rbit%?\\t%0, %1"
10673   [(set_attr "predicable" "yes")
10674    (set_attr "predicable_short_it" "no")
10675    (set_attr "type" "clz")])
10677 (define_expand "ctzsi2"
10678  [(set (match_operand:SI           0 "s_register_operand" "")
10679        (ctz:SI (match_operand:SI  1 "s_register_operand" "")))]
10680   "TARGET_32BIT && arm_arch_thumb2"
10681   "
10682    {
10683      rtx tmp = gen_reg_rtx (SImode); 
10684      emit_insn (gen_rbitsi2 (tmp, operands[1]));
10685      emit_insn (gen_clzsi2 (operands[0], tmp));
10686    }
10687    DONE;
10688   "
10691 ;; V5E instructions.
10693 (define_insn "prefetch"
10694   [(prefetch (match_operand:SI 0 "address_operand" "p")
10695              (match_operand:SI 1 "" "")
10696              (match_operand:SI 2 "" ""))]
10697   "TARGET_32BIT && arm_arch5e"
10698   "pld\\t%a0"
10699   [(set_attr "type" "load1")]
10702 ;; General predication pattern
10704 (define_cond_exec
10705   [(match_operator 0 "arm_comparison_operator"
10706     [(match_operand 1 "cc_register" "")
10707      (const_int 0)])]
10708   "TARGET_32BIT"
10709   ""
10710 [(set_attr "predicated" "yes")]
10713 (define_insn "force_register_use"
10714   [(unspec:SI [(match_operand:SI 0 "register_operand" "")] UNSPEC_REGISTER_USE)]
10715   ""
10716   "%@ %0 needed"
10717   [(set_attr "length" "0")
10718    (set_attr "type" "no_insn")]
10722 ;; Patterns for exception handling
10724 (define_expand "eh_return"
10725   [(use (match_operand 0 "general_operand" ""))]
10726   "TARGET_EITHER"
10727   "
10728   {
10729     if (TARGET_32BIT)
10730       emit_insn (gen_arm_eh_return (operands[0]));
10731     else
10732       emit_insn (gen_thumb_eh_return (operands[0]));
10733     DONE;
10734   }"
10736                                    
10737 ;; We can't expand this before we know where the link register is stored.
10738 (define_insn_and_split "arm_eh_return"
10739   [(unspec_volatile [(match_operand:SI 0 "s_register_operand" "r")]
10740                     VUNSPEC_EH_RETURN)
10741    (clobber (match_scratch:SI 1 "=&r"))]
10742   "TARGET_ARM"
10743   "#"
10744   "&& reload_completed"
10745   [(const_int 0)]
10746   "
10747   {
10748     arm_set_return_address (operands[0], operands[1]);
10749     DONE;
10750   }"
10754 ;; TLS support
10756 (define_insn "load_tp_hard"
10757   [(set (match_operand:SI 0 "register_operand" "=r")
10758         (unspec:SI [(const_int 0)] UNSPEC_TLS))]
10759   "TARGET_HARD_TP"
10760   "mrc%?\\tp15, 0, %0, c13, c0, 3\\t@ load_tp_hard"
10761   [(set_attr "predicable" "yes")
10762    (set_attr "type" "mrs")]
10765 ;; Doesn't clobber R1-R3.  Must use r0 for the first operand.
10766 (define_insn "load_tp_soft"
10767   [(set (reg:SI 0) (unspec:SI [(const_int 0)] UNSPEC_TLS))
10768    (clobber (reg:SI LR_REGNUM))
10769    (clobber (reg:SI IP_REGNUM))
10770    (clobber (reg:CC CC_REGNUM))]
10771   "TARGET_SOFT_TP"
10772   "bl\\t__aeabi_read_tp\\t@ load_tp_soft"
10773   [(set_attr "conds" "clob")
10774    (set_attr "type" "branch")]
10777 ;; tls descriptor call
10778 (define_insn "tlscall"
10779   [(set (reg:SI R0_REGNUM)
10780         (unspec:SI [(reg:SI R0_REGNUM)
10781                     (match_operand:SI 0 "" "X")
10782                     (match_operand 1 "" "")] UNSPEC_TLS))
10783    (clobber (reg:SI R1_REGNUM))
10784    (clobber (reg:SI LR_REGNUM))
10785    (clobber (reg:SI CC_REGNUM))]
10786   "TARGET_GNU2_TLS"
10787   {
10788     targetm.asm_out.internal_label (asm_out_file, "LPIC",
10789                                     INTVAL (operands[1]));
10790     return "bl\\t%c0(tlscall)";
10791   }
10792   [(set_attr "conds" "clob")
10793    (set_attr "length" "4")
10794    (set_attr "type" "branch")]
10797 ;; For thread pointer builtin
10798 (define_expand "get_thread_pointersi"
10799   [(match_operand:SI 0 "s_register_operand" "=r")]
10800  ""
10803    arm_load_tp (operands[0]);
10804    DONE;
10805  }")
10809 ;; We only care about the lower 16 bits of the constant 
10810 ;; being inserted into the upper 16 bits of the register.
10811 (define_insn "*arm_movtas_ze" 
10812   [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r")
10813                    (const_int 16)
10814                    (const_int 16))
10815         (match_operand:SI 1 "const_int_operand" ""))]
10816   "arm_arch_thumb2"
10817   "movt%?\t%0, %L1"
10818  [(set_attr "predicable" "yes")
10819   (set_attr "predicable_short_it" "no")
10820   (set_attr "length" "4")
10821   (set_attr "type" "mov_imm")]
10824 (define_insn "*arm_rev"
10825   [(set (match_operand:SI 0 "s_register_operand" "=l,l,r")
10826         (bswap:SI (match_operand:SI 1 "s_register_operand" "l,l,r")))]
10827   "arm_arch6"
10828   "@
10829    rev\t%0, %1
10830    rev%?\t%0, %1
10831    rev%?\t%0, %1"
10832   [(set_attr "arch" "t1,t2,32")
10833    (set_attr "length" "2,2,4")
10834    (set_attr "predicable" "no,yes,yes")
10835    (set_attr "predicable_short_it" "no")
10836    (set_attr "type" "rev")]
10839 (define_expand "arm_legacy_rev"
10840   [(set (match_operand:SI 2 "s_register_operand" "")
10841         (xor:SI (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
10842                              (const_int 16))
10843                 (match_dup 1)))
10844    (set (match_dup 2)
10845         (lshiftrt:SI (match_dup 2)
10846                      (const_int 8)))
10847    (set (match_operand:SI 3 "s_register_operand" "")
10848         (rotatert:SI (match_dup 1)
10849                      (const_int 8)))
10850    (set (match_dup 2)
10851         (and:SI (match_dup 2)
10852                 (const_int -65281)))
10853    (set (match_operand:SI 0 "s_register_operand" "")
10854         (xor:SI (match_dup 3)
10855                 (match_dup 2)))]
10856   "TARGET_32BIT"
10857   ""
10860 ;; Reuse temporaries to keep register pressure down.
10861 (define_expand "thumb_legacy_rev"
10862   [(set (match_operand:SI 2 "s_register_operand" "")
10863      (ashift:SI (match_operand:SI 1 "s_register_operand" "")
10864                 (const_int 24)))
10865    (set (match_operand:SI 3 "s_register_operand" "")
10866      (lshiftrt:SI (match_dup 1)
10867                   (const_int 24)))
10868    (set (match_dup 3)
10869      (ior:SI (match_dup 3)
10870              (match_dup 2)))
10871    (set (match_operand:SI 4 "s_register_operand" "")
10872      (const_int 16))
10873    (set (match_operand:SI 5 "s_register_operand" "")
10874      (rotatert:SI (match_dup 1)
10875                   (match_dup 4)))
10876    (set (match_dup 2)
10877      (ashift:SI (match_dup 5)
10878                 (const_int 24)))
10879    (set (match_dup 5)
10880      (lshiftrt:SI (match_dup 5)
10881                   (const_int 24)))
10882    (set (match_dup 5)
10883      (ior:SI (match_dup 5)
10884              (match_dup 2)))
10885    (set (match_dup 5)
10886      (rotatert:SI (match_dup 5)
10887                   (match_dup 4)))
10888    (set (match_operand:SI 0 "s_register_operand" "")
10889      (ior:SI (match_dup 5)
10890              (match_dup 3)))]
10891   "TARGET_THUMB"
10892   ""
10895 (define_expand "bswapsi2"
10896   [(set (match_operand:SI 0 "s_register_operand" "=r")
10897         (bswap:SI (match_operand:SI 1 "s_register_operand" "r")))]
10898 "TARGET_EITHER && (arm_arch6 || !optimize_size)"
10900     if (!arm_arch6)
10901       {
10902         rtx op2 = gen_reg_rtx (SImode);
10903         rtx op3 = gen_reg_rtx (SImode);
10905         if (TARGET_THUMB)
10906           {
10907             rtx op4 = gen_reg_rtx (SImode);
10908             rtx op5 = gen_reg_rtx (SImode);
10910             emit_insn (gen_thumb_legacy_rev (operands[0], operands[1],
10911                                              op2, op3, op4, op5));
10912           }
10913         else
10914           {
10915             emit_insn (gen_arm_legacy_rev (operands[0], operands[1],
10916                                            op2, op3));
10917           }
10919         DONE;
10920       }
10921   "
10924 ;; bswap16 patterns: use revsh and rev16 instructions for the signed
10925 ;; and unsigned variants, respectively. For rev16, expose
10926 ;; byte-swapping in the lower 16 bits only.
10927 (define_insn "*arm_revsh"
10928   [(set (match_operand:SI 0 "s_register_operand" "=l,l,r")
10929         (sign_extend:SI (bswap:HI (match_operand:HI 1 "s_register_operand" "l,l,r"))))]
10930   "arm_arch6"
10931   "@
10932   revsh\t%0, %1
10933   revsh%?\t%0, %1
10934   revsh%?\t%0, %1"
10935   [(set_attr "arch" "t1,t2,32")
10936    (set_attr "length" "2,2,4")
10937    (set_attr "type" "rev")]
10940 (define_insn "*arm_rev16"
10941   [(set (match_operand:HI 0 "s_register_operand" "=l,l,r")
10942         (bswap:HI (match_operand:HI 1 "s_register_operand" "l,l,r")))]
10943   "arm_arch6"
10944   "@
10945    rev16\t%0, %1
10946    rev16%?\t%0, %1
10947    rev16%?\t%0, %1"
10948   [(set_attr "arch" "t1,t2,32")
10949    (set_attr "length" "2,2,4")
10950    (set_attr "type" "rev")]
10953 ;; There are no canonicalisation rules for the position of the lshiftrt, ashift
10954 ;; operations within an IOR/AND RTX, therefore we have two patterns matching
10955 ;; each valid permutation.
10957 (define_insn "arm_rev16si2"
10958   [(set (match_operand:SI 0 "register_operand" "=l,l,r")
10959         (ior:SI (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "l,l,r")
10960                                    (const_int 8))
10961                         (match_operand:SI 3 "const_int_operand" "n,n,n"))
10962                 (and:SI (lshiftrt:SI (match_dup 1)
10963                                      (const_int 8))
10964                         (match_operand:SI 2 "const_int_operand" "n,n,n"))))]
10965   "arm_arch6
10966    && aarch_rev16_shleft_mask_imm_p (operands[3], SImode)
10967    && aarch_rev16_shright_mask_imm_p (operands[2], SImode)"
10968   "rev16\\t%0, %1"
10969   [(set_attr "arch" "t1,t2,32")
10970    (set_attr "length" "2,2,4")
10971    (set_attr "type" "rev")]
10974 (define_insn "arm_rev16si2_alt"
10975   [(set (match_operand:SI 0 "register_operand" "=l,l,r")
10976         (ior:SI (and:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "l,l,r")
10977                                      (const_int 8))
10978                         (match_operand:SI 2 "const_int_operand" "n,n,n"))
10979                 (and:SI (ashift:SI (match_dup 1)
10980                                    (const_int 8))
10981                         (match_operand:SI 3 "const_int_operand" "n,n,n"))))]
10982   "arm_arch6
10983    && aarch_rev16_shleft_mask_imm_p (operands[3], SImode)
10984    && aarch_rev16_shright_mask_imm_p (operands[2], SImode)"
10985   "rev16\\t%0, %1"
10986   [(set_attr "arch" "t1,t2,32")
10987    (set_attr "length" "2,2,4")
10988    (set_attr "type" "rev")]
10991 (define_expand "bswaphi2"
10992   [(set (match_operand:HI 0 "s_register_operand" "=r")
10993         (bswap:HI (match_operand:HI 1 "s_register_operand" "r")))]
10994 "arm_arch6"
10998 ;; Patterns for LDRD/STRD in Thumb2 mode
11000 (define_insn "*thumb2_ldrd"
11001   [(set (match_operand:SI 0 "s_register_operand" "=r")
11002         (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "rk")
11003                          (match_operand:SI 2 "ldrd_strd_offset_operand" "Do"))))
11004    (set (match_operand:SI 3 "s_register_operand" "=r")
11005         (mem:SI (plus:SI (match_dup 1)
11006                          (match_operand:SI 4 "const_int_operand" ""))))]
11007   "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11008      && current_tune->prefer_ldrd_strd
11009      && ((INTVAL (operands[2]) + 4) == INTVAL (operands[4]))
11010      && (operands_ok_ldrd_strd (operands[0], operands[3],
11011                                   operands[1], INTVAL (operands[2]),
11012                                   false, true))"
11013   "ldrd%?\t%0, %3, [%1, %2]"
11014   [(set_attr "type" "load2")
11015    (set_attr "predicable" "yes")
11016    (set_attr "predicable_short_it" "no")])
11018 (define_insn "*thumb2_ldrd_base"
11019   [(set (match_operand:SI 0 "s_register_operand" "=r")
11020         (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
11021    (set (match_operand:SI 2 "s_register_operand" "=r")
11022         (mem:SI (plus:SI (match_dup 1)
11023                          (const_int 4))))]
11024   "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11025      && current_tune->prefer_ldrd_strd
11026      && (operands_ok_ldrd_strd (operands[0], operands[2],
11027                                   operands[1], 0, false, true))"
11028   "ldrd%?\t%0, %2, [%1]"
11029   [(set_attr "type" "load2")
11030    (set_attr "predicable" "yes")
11031    (set_attr "predicable_short_it" "no")])
11033 (define_insn "*thumb2_ldrd_base_neg"
11034   [(set (match_operand:SI 0 "s_register_operand" "=r")
11035         (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "rk")
11036                          (const_int -4))))
11037    (set (match_operand:SI 2 "s_register_operand" "=r")
11038         (mem:SI (match_dup 1)))]
11039   "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11040      && current_tune->prefer_ldrd_strd
11041      && (operands_ok_ldrd_strd (operands[0], operands[2],
11042                                   operands[1], -4, false, true))"
11043   "ldrd%?\t%0, %2, [%1, #-4]"
11044   [(set_attr "type" "load2")
11045    (set_attr "predicable" "yes")
11046    (set_attr "predicable_short_it" "no")])
11048 (define_insn "*thumb2_strd"
11049   [(set (mem:SI (plus:SI (match_operand:SI 0 "s_register_operand" "rk")
11050                          (match_operand:SI 1 "ldrd_strd_offset_operand" "Do")))
11051         (match_operand:SI 2 "s_register_operand" "r"))
11052    (set (mem:SI (plus:SI (match_dup 0)
11053                          (match_operand:SI 3 "const_int_operand" "")))
11054         (match_operand:SI 4 "s_register_operand" "r"))]
11055   "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11056      && current_tune->prefer_ldrd_strd
11057      && ((INTVAL (operands[1]) + 4) == INTVAL (operands[3]))
11058      && (operands_ok_ldrd_strd (operands[2], operands[4],
11059                                   operands[0], INTVAL (operands[1]),
11060                                   false, false))"
11061   "strd%?\t%2, %4, [%0, %1]"
11062   [(set_attr "type" "store2")
11063    (set_attr "predicable" "yes")
11064    (set_attr "predicable_short_it" "no")])
11066 (define_insn "*thumb2_strd_base"
11067   [(set (mem:SI (match_operand:SI 0 "s_register_operand" "rk"))
11068         (match_operand:SI 1 "s_register_operand" "r"))
11069    (set (mem:SI (plus:SI (match_dup 0)
11070                          (const_int 4)))
11071         (match_operand:SI 2 "s_register_operand" "r"))]
11072   "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11073      && current_tune->prefer_ldrd_strd
11074      && (operands_ok_ldrd_strd (operands[1], operands[2],
11075                                   operands[0], 0, false, false))"
11076   "strd%?\t%1, %2, [%0]"
11077   [(set_attr "type" "store2")
11078    (set_attr "predicable" "yes")
11079    (set_attr "predicable_short_it" "no")])
11081 (define_insn "*thumb2_strd_base_neg"
11082   [(set (mem:SI (plus:SI (match_operand:SI 0 "s_register_operand" "rk")
11083                          (const_int -4)))
11084         (match_operand:SI 1 "s_register_operand" "r"))
11085    (set (mem:SI (match_dup 0))
11086         (match_operand:SI 2 "s_register_operand" "r"))]
11087   "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11088      && current_tune->prefer_ldrd_strd
11089      && (operands_ok_ldrd_strd (operands[1], operands[2],
11090                                   operands[0], -4, false, false))"
11091   "strd%?\t%1, %2, [%0, #-4]"
11092   [(set_attr "type" "store2")
11093    (set_attr "predicable" "yes")
11094    (set_attr "predicable_short_it" "no")])
11096 ;; ARMv8 CRC32 instructions.
11097 (define_insn "<crc_variant>"
11098   [(set (match_operand:SI 0 "s_register_operand" "=r")
11099         (unspec:SI [(match_operand:SI 1 "s_register_operand" "r")
11100                     (match_operand:<crc_mode> 2 "s_register_operand" "r")]
11101          CRC))]
11102   "TARGET_CRC32"
11103   "<crc_variant>\\t%0, %1, %2"
11104   [(set_attr "type" "crc")
11105    (set_attr "conds" "unconditional")]
11108 ;; Load the load/store double peephole optimizations.
11109 (include "ldrdstrd.md")
11111 ;; Load the load/store multiple patterns
11112 (include "ldmstm.md")
11114 ;; Patterns in ldmstm.md don't cover more than 4 registers. This pattern covers
11115 ;; large lists without explicit writeback generated for APCS_FRAME epilogue.
11116 (define_insn "*load_multiple"
11117   [(match_parallel 0 "load_multiple_operation"
11118     [(set (match_operand:SI 2 "s_register_operand" "=rk")
11119           (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
11120         ])]
11121   "TARGET_32BIT"
11122   "*
11123   {
11124     arm_output_multireg_pop (operands, /*return_pc=*/false,
11125                                        /*cond=*/const_true_rtx,
11126                                        /*reverse=*/false,
11127                                        /*update=*/false);
11128     return \"\";
11129   }
11130   "
11131   [(set_attr "predicable" "yes")]
11134 ;; Vector bits common to IWMMXT and Neon
11135 (include "vec-common.md")
11136 ;; Load the Intel Wireless Multimedia Extension patterns
11137 (include "iwmmxt.md")
11138 ;; Load the VFP co-processor patterns
11139 (include "vfp.md")
11140 ;; Thumb-1 patterns
11141 (include "thumb1.md")
11142 ;; Thumb-2 patterns
11143 (include "thumb2.md")
11144 ;; Neon patterns
11145 (include "neon.md")
11146 ;; Crypto patterns
11147 (include "crypto.md")
11148 ;; Synchronization Primitives
11149 (include "sync.md")
11150 ;; Fixed-point patterns
11151 (include "arm-fixed.md")