Fix PR target/63209.
[official-gcc.git] / gcc / config / arm / arm.md
blobe691562ac751f2dbbddd14725125e2a56626b8cd
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,Uh,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 (define_expand "setmemsi"
6720   [(match_operand:BLK 0 "general_operand" "")
6721    (match_operand:SI 1 "const_int_operand" "")
6722    (match_operand:SI 2 "const_int_operand" "")
6723    (match_operand:SI 3 "const_int_operand" "")]
6724   "TARGET_32BIT"
6726   if (arm_gen_setmem (operands))
6727     DONE;
6729   FAIL;
6733 ;; Move a block of memory if it is word aligned and MORE than 2 words long.
6734 ;; We could let this apply for blocks of less than this, but it clobbers so
6735 ;; many registers that there is then probably a better way.
6737 (define_expand "movmemqi"
6738   [(match_operand:BLK 0 "general_operand" "")
6739    (match_operand:BLK 1 "general_operand" "")
6740    (match_operand:SI 2 "const_int_operand" "")
6741    (match_operand:SI 3 "const_int_operand" "")]
6742   ""
6743   "
6744   if (TARGET_32BIT)
6745     {
6746       if (TARGET_LDRD && current_tune->prefer_ldrd_strd
6747           && !optimize_function_for_size_p (cfun))
6748         {
6749           if (gen_movmem_ldrd_strd (operands))
6750             DONE;
6751           FAIL;
6752         }
6754       if (arm_gen_movmemqi (operands))
6755         DONE;
6756       FAIL;
6757     }
6758   else /* TARGET_THUMB1 */
6759     {
6760       if (   INTVAL (operands[3]) != 4
6761           || INTVAL (operands[2]) > 48)
6762         FAIL;
6764       thumb_expand_movmemqi (operands);
6765       DONE;
6766     }
6767   "
6771 ;; Compare & branch insns
6772 ;; The range calculations are based as follows:
6773 ;; For forward branches, the address calculation returns the address of
6774 ;; the next instruction.  This is 2 beyond the branch instruction.
6775 ;; For backward branches, the address calculation returns the address of
6776 ;; the first instruction in this pattern (cmp).  This is 2 before the branch
6777 ;; instruction for the shortest sequence, and 4 before the branch instruction
6778 ;; if we have to jump around an unconditional branch.
6779 ;; To the basic branch range the PC offset must be added (this is +4).
6780 ;; So for forward branches we have 
6781 ;;   (pos_range - pos_base_offs + pc_offs) = (pos_range - 2 + 4).
6782 ;; And for backward branches we have 
6783 ;;   (neg_range - neg_base_offs + pc_offs) = (neg_range - (-2 or -4) + 4).
6785 ;; For a 'b'       pos_range = 2046, neg_range = -2048 giving (-2040->2048).
6786 ;; For a 'b<cond>' pos_range = 254,  neg_range = -256  giving (-250 ->256).
6788 (define_expand "cbranchsi4"
6789   [(set (pc) (if_then_else
6790               (match_operator 0 "expandable_comparison_operator"
6791                [(match_operand:SI 1 "s_register_operand" "")
6792                 (match_operand:SI 2 "nonmemory_operand" "")])
6793               (label_ref (match_operand 3 "" ""))
6794               (pc)))]
6795   "TARGET_EITHER"
6796   "
6797   if (!TARGET_THUMB1)
6798     {
6799       if (!arm_validize_comparison (&operands[0], &operands[1], &operands[2]))
6800         FAIL;
6801       emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
6802                                       operands[3]));
6803       DONE;
6804     }
6805   if (thumb1_cmpneg_operand (operands[2], SImode))
6806     {
6807       emit_jump_insn (gen_cbranchsi4_scratch (NULL, operands[1], operands[2],
6808                                               operands[3], operands[0]));
6809       DONE;
6810     }
6811   if (!thumb1_cmp_operand (operands[2], SImode))
6812     operands[2] = force_reg (SImode, operands[2]);
6813   ")
6815 (define_expand "cbranchsf4"
6816   [(set (pc) (if_then_else
6817               (match_operator 0 "expandable_comparison_operator"
6818                [(match_operand:SF 1 "s_register_operand" "")
6819                 (match_operand:SF 2 "arm_float_compare_operand" "")])
6820               (label_ref (match_operand 3 "" ""))
6821               (pc)))]
6822   "TARGET_32BIT && TARGET_HARD_FLOAT"
6823   "emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
6824                                    operands[3])); DONE;"
6827 (define_expand "cbranchdf4"
6828   [(set (pc) (if_then_else
6829               (match_operator 0 "expandable_comparison_operator"
6830                [(match_operand:DF 1 "s_register_operand" "")
6831                 (match_operand:DF 2 "arm_float_compare_operand" "")])
6832               (label_ref (match_operand 3 "" ""))
6833               (pc)))]
6834   "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
6835   "emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
6836                                    operands[3])); DONE;"
6839 (define_expand "cbranchdi4"
6840   [(set (pc) (if_then_else
6841               (match_operator 0 "expandable_comparison_operator"
6842                [(match_operand:DI 1 "s_register_operand" "")
6843                 (match_operand:DI 2 "cmpdi_operand" "")])
6844               (label_ref (match_operand 3 "" ""))
6845               (pc)))]
6846   "TARGET_32BIT"
6847   "{
6848      if (!arm_validize_comparison (&operands[0], &operands[1], &operands[2]))
6849        FAIL;
6850      emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
6851                                        operands[3]));
6852      DONE;
6853    }"
6856 ;; Comparison and test insns
6858 (define_insn "*arm_cmpsi_insn"
6859   [(set (reg:CC CC_REGNUM)
6860         (compare:CC (match_operand:SI 0 "s_register_operand" "l,r,r,r,r")
6861                     (match_operand:SI 1 "arm_add_operand"    "Py,r,r,I,L")))]
6862   "TARGET_32BIT"
6863   "@
6864    cmp%?\\t%0, %1
6865    cmp%?\\t%0, %1
6866    cmp%?\\t%0, %1
6867    cmp%?\\t%0, %1
6868    cmn%?\\t%0, #%n1"
6869   [(set_attr "conds" "set")
6870    (set_attr "arch" "t2,t2,any,any,any")
6871    (set_attr "length" "2,2,4,4,4")
6872    (set_attr "predicable" "yes")
6873    (set_attr "predicable_short_it" "yes,yes,yes,no,no")
6874    (set_attr "type" "alus_imm,alus_sreg,alus_sreg,alus_imm,alus_imm")]
6877 (define_insn "*cmpsi_shiftsi"
6878   [(set (reg:CC CC_REGNUM)
6879         (compare:CC (match_operand:SI   0 "s_register_operand" "r,r,r")
6880                     (match_operator:SI  3 "shift_operator"
6881                      [(match_operand:SI 1 "s_register_operand" "r,r,r")
6882                       (match_operand:SI 2 "shift_amount_operand" "M,r,M")])))]
6883   "TARGET_32BIT"
6884   "cmp\\t%0, %1%S3"
6885   [(set_attr "conds" "set")
6886    (set_attr "shift" "1")
6887    (set_attr "arch" "32,a,a")
6888    (set_attr "type" "alus_shift_imm,alu_shift_reg,alus_shift_imm")])
6890 (define_insn "*cmpsi_shiftsi_swp"
6891   [(set (reg:CC_SWP CC_REGNUM)
6892         (compare:CC_SWP (match_operator:SI 3 "shift_operator"
6893                          [(match_operand:SI 1 "s_register_operand" "r,r,r")
6894                           (match_operand:SI 2 "shift_amount_operand" "M,r,M")])
6895                         (match_operand:SI 0 "s_register_operand" "r,r,r")))]
6896   "TARGET_32BIT"
6897   "cmp%?\\t%0, %1%S3"
6898   [(set_attr "conds" "set")
6899    (set_attr "shift" "1")
6900    (set_attr "arch" "32,a,a")
6901    (set_attr "type" "alus_shift_imm,alu_shift_reg,alus_shift_imm")])
6903 (define_insn "*arm_cmpsi_negshiftsi_si"
6904   [(set (reg:CC_Z CC_REGNUM)
6905         (compare:CC_Z
6906          (neg:SI (match_operator:SI 1 "shift_operator"
6907                     [(match_operand:SI 2 "s_register_operand" "r")
6908                      (match_operand:SI 3 "reg_or_int_operand" "rM")]))
6909          (match_operand:SI 0 "s_register_operand" "r")))]
6910   "TARGET_ARM"
6911   "cmn%?\\t%0, %2%S1"
6912   [(set_attr "conds" "set")
6913    (set (attr "type") (if_then_else (match_operand 3 "const_int_operand" "")
6914                                     (const_string "alus_shift_imm")
6915                                     (const_string "alus_shift_reg")))
6916    (set_attr "predicable" "yes")]
6919 ;; DImode comparisons.  The generic code generates branches that
6920 ;; if-conversion can not reduce to a conditional compare, so we do
6921 ;; that directly.
6923 (define_insn_and_split "*arm_cmpdi_insn"
6924   [(set (reg:CC_NCV CC_REGNUM)
6925         (compare:CC_NCV (match_operand:DI 0 "s_register_operand" "r")
6926                         (match_operand:DI 1 "arm_di_operand"       "rDi")))
6927    (clobber (match_scratch:SI 2 "=r"))]
6928   "TARGET_32BIT"
6929   "#"   ; "cmp\\t%Q0, %Q1\;sbcs\\t%2, %R0, %R1"
6930   "&& reload_completed"
6931   [(set (reg:CC CC_REGNUM)
6932         (compare:CC (match_dup 0) (match_dup 1)))
6933    (parallel [(set (reg:CC CC_REGNUM)
6934                    (compare:CC (match_dup 3) (match_dup 4)))
6935               (set (match_dup 2)
6936                    (minus:SI (match_dup 5)
6937                             (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))])]
6938   {
6939     operands[3] = gen_highpart (SImode, operands[0]);
6940     operands[0] = gen_lowpart (SImode, operands[0]);
6941     if (CONST_INT_P (operands[1]))
6942       {
6943         operands[4] = GEN_INT (~INTVAL (gen_highpart_mode (SImode,
6944                                                            DImode,
6945                                                            operands[1])));
6946         operands[5] = gen_rtx_PLUS (SImode, operands[3], operands[4]);
6947       }
6948     else
6949       {
6950         operands[4] = gen_highpart (SImode, operands[1]);
6951         operands[5] = gen_rtx_MINUS (SImode, operands[3], operands[4]);
6952       }
6953     operands[1] = gen_lowpart (SImode, operands[1]);
6954     operands[2] = gen_lowpart (SImode, operands[2]);
6955   }
6956   [(set_attr "conds" "set")
6957    (set_attr "length" "8")
6958    (set_attr "type" "multiple")]
6961 (define_insn_and_split "*arm_cmpdi_unsigned"
6962   [(set (reg:CC_CZ CC_REGNUM)
6963         (compare:CC_CZ (match_operand:DI 0 "s_register_operand" "l,r,r,r")
6964                        (match_operand:DI 1 "arm_di_operand"     "Py,r,Di,rDi")))]
6966   "TARGET_32BIT"
6967   "#"   ; "cmp\\t%R0, %R1\;it eq\;cmpeq\\t%Q0, %Q1"
6968   "&& reload_completed"
6969   [(set (reg:CC CC_REGNUM)
6970         (compare:CC (match_dup 2) (match_dup 3)))
6971    (cond_exec (eq:SI (reg:CC CC_REGNUM) (const_int 0))
6972               (set (reg:CC CC_REGNUM)
6973                    (compare:CC (match_dup 0) (match_dup 1))))]
6974   {
6975     operands[2] = gen_highpart (SImode, operands[0]);
6976     operands[0] = gen_lowpart (SImode, operands[0]);
6977     if (CONST_INT_P (operands[1]))
6978       operands[3] = gen_highpart_mode (SImode, DImode, operands[1]);
6979     else
6980       operands[3] = gen_highpart (SImode, operands[1]);
6981     operands[1] = gen_lowpart (SImode, operands[1]);
6982   }
6983   [(set_attr "conds" "set")
6984    (set_attr "enabled_for_depr_it" "yes,yes,no,*")
6985    (set_attr "arch" "t2,t2,t2,a")
6986    (set_attr "length" "6,6,10,8")
6987    (set_attr "type" "multiple")]
6990 (define_insn "*arm_cmpdi_zero"
6991   [(set (reg:CC_Z CC_REGNUM)
6992         (compare:CC_Z (match_operand:DI 0 "s_register_operand" "r")
6993                       (const_int 0)))
6994    (clobber (match_scratch:SI 1 "=r"))]
6995   "TARGET_32BIT"
6996   "orr%.\\t%1, %Q0, %R0"
6997   [(set_attr "conds" "set")
6998    (set_attr "type" "logics_reg")]
7001 ; This insn allows redundant compares to be removed by cse, nothing should
7002 ; ever appear in the output file since (set (reg x) (reg x)) is a no-op that
7003 ; is deleted later on. The match_dup will match the mode here, so that
7004 ; mode changes of the condition codes aren't lost by this even though we don't
7005 ; specify what they are.
7007 (define_insn "*deleted_compare"
7008   [(set (match_operand 0 "cc_register" "") (match_dup 0))]
7009   "TARGET_32BIT"
7010   "\\t%@ deleted compare"
7011   [(set_attr "conds" "set")
7012    (set_attr "length" "0")
7013    (set_attr "type" "no_insn")]
7017 ;; Conditional branch insns
7019 (define_expand "cbranch_cc"
7020   [(set (pc)
7021         (if_then_else (match_operator 0 "" [(match_operand 1 "" "")
7022                                             (match_operand 2 "" "")])
7023                       (label_ref (match_operand 3 "" ""))
7024                       (pc)))]
7025   "TARGET_32BIT"
7026   "operands[1] = arm_gen_compare_reg (GET_CODE (operands[0]),
7027                                       operands[1], operands[2], NULL_RTX);
7028    operands[2] = const0_rtx;"
7032 ;; Patterns to match conditional branch insns.
7035 (define_insn "arm_cond_branch"
7036   [(set (pc)
7037         (if_then_else (match_operator 1 "arm_comparison_operator"
7038                        [(match_operand 2 "cc_register" "") (const_int 0)])
7039                       (label_ref (match_operand 0 "" ""))
7040                       (pc)))]
7041   "TARGET_32BIT"
7042   "*
7043   if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
7044     {
7045       arm_ccfsm_state += 2;
7046       return \"\";
7047     }
7048   return \"b%d1\\t%l0\";
7049   "
7050   [(set_attr "conds" "use")
7051    (set_attr "type" "branch")
7052    (set (attr "length")
7053         (if_then_else
7054            (and (match_test "TARGET_THUMB2")
7055                 (and (ge (minus (match_dup 0) (pc)) (const_int -250))
7056                      (le (minus (match_dup 0) (pc)) (const_int 256))))
7057            (const_int 2)
7058            (const_int 4)))]
7061 (define_insn "*arm_cond_branch_reversed"
7062   [(set (pc)
7063         (if_then_else (match_operator 1 "arm_comparison_operator"
7064                        [(match_operand 2 "cc_register" "") (const_int 0)])
7065                       (pc)
7066                       (label_ref (match_operand 0 "" ""))))]
7067   "TARGET_32BIT"
7068   "*
7069   if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
7070     {
7071       arm_ccfsm_state += 2;
7072       return \"\";
7073     }
7074   return \"b%D1\\t%l0\";
7075   "
7076   [(set_attr "conds" "use")
7077    (set_attr "type" "branch")
7078    (set (attr "length")
7079         (if_then_else
7080            (and (match_test "TARGET_THUMB2")
7081                 (and (ge (minus (match_dup 0) (pc)) (const_int -250))
7082                      (le (minus (match_dup 0) (pc)) (const_int 256))))
7083            (const_int 2)
7084            (const_int 4)))]
7089 ; scc insns
7091 (define_expand "cstore_cc"
7092   [(set (match_operand:SI 0 "s_register_operand" "")
7093         (match_operator:SI 1 "" [(match_operand 2 "" "")
7094                                  (match_operand 3 "" "")]))]
7095   "TARGET_32BIT"
7096   "operands[2] = arm_gen_compare_reg (GET_CODE (operands[1]),
7097                                       operands[2], operands[3], NULL_RTX);
7098    operands[3] = const0_rtx;"
7101 (define_insn_and_split "*mov_scc"
7102   [(set (match_operand:SI 0 "s_register_operand" "=r")
7103         (match_operator:SI 1 "arm_comparison_operator"
7104          [(match_operand 2 "cc_register" "") (const_int 0)]))]
7105   "TARGET_ARM"
7106   "#"   ; "mov%D1\\t%0, #0\;mov%d1\\t%0, #1"
7107   "TARGET_ARM"
7108   [(set (match_dup 0)
7109         (if_then_else:SI (match_dup 1)
7110                          (const_int 1)
7111                          (const_int 0)))]
7112   ""
7113   [(set_attr "conds" "use")
7114    (set_attr "length" "8")
7115    (set_attr "type" "multiple")]
7118 (define_insn_and_split "*mov_negscc"
7119   [(set (match_operand:SI 0 "s_register_operand" "=r")
7120         (neg:SI (match_operator:SI 1 "arm_comparison_operator"
7121                  [(match_operand 2 "cc_register" "") (const_int 0)])))]
7122   "TARGET_ARM"
7123   "#"   ; "mov%D1\\t%0, #0\;mvn%d1\\t%0, #0"
7124   "TARGET_ARM"
7125   [(set (match_dup 0)
7126         (if_then_else:SI (match_dup 1)
7127                          (match_dup 3)
7128                          (const_int 0)))]
7129   {
7130     operands[3] = GEN_INT (~0);
7131   }
7132   [(set_attr "conds" "use")
7133    (set_attr "length" "8")
7134    (set_attr "type" "multiple")]
7137 (define_insn_and_split "*mov_notscc"
7138   [(set (match_operand:SI 0 "s_register_operand" "=r")
7139         (not:SI (match_operator:SI 1 "arm_comparison_operator"
7140                  [(match_operand 2 "cc_register" "") (const_int 0)])))]
7141   "TARGET_ARM"
7142   "#"   ; "mvn%D1\\t%0, #0\;mvn%d1\\t%0, #1"
7143   "TARGET_ARM"
7144   [(set (match_dup 0)
7145         (if_then_else:SI (match_dup 1)
7146                          (match_dup 3)
7147                          (match_dup 4)))]
7148   {
7149     operands[3] = GEN_INT (~1);
7150     operands[4] = GEN_INT (~0);
7151   }
7152   [(set_attr "conds" "use")
7153    (set_attr "length" "8")
7154    (set_attr "type" "multiple")]
7157 (define_expand "cstoresi4"
7158   [(set (match_operand:SI 0 "s_register_operand" "")
7159         (match_operator:SI 1 "expandable_comparison_operator"
7160          [(match_operand:SI 2 "s_register_operand" "")
7161           (match_operand:SI 3 "reg_or_int_operand" "")]))]
7162   "TARGET_32BIT || TARGET_THUMB1"
7163   "{
7164   rtx op3, scratch, scratch2;
7166   if (!TARGET_THUMB1)
7167     {
7168       if (!arm_add_operand (operands[3], SImode))
7169         operands[3] = force_reg (SImode, operands[3]);
7170       emit_insn (gen_cstore_cc (operands[0], operands[1],
7171                                 operands[2], operands[3]));
7172       DONE;
7173     }
7175   if (operands[3] == const0_rtx)
7176     {
7177       switch (GET_CODE (operands[1]))
7178         {
7179         case EQ:
7180           emit_insn (gen_cstoresi_eq0_thumb1 (operands[0], operands[2]));
7181           break;
7183         case NE:
7184           emit_insn (gen_cstoresi_ne0_thumb1 (operands[0], operands[2]));
7185           break;
7187         case LE:
7188           scratch = expand_binop (SImode, add_optab, operands[2], constm1_rtx,
7189                                   NULL_RTX, 0, OPTAB_WIDEN);
7190           scratch = expand_binop (SImode, ior_optab, operands[2], scratch,
7191                                   NULL_RTX, 0, OPTAB_WIDEN);
7192           expand_binop (SImode, lshr_optab, scratch, GEN_INT (31),
7193                         operands[0], 1, OPTAB_WIDEN);
7194           break;
7196         case GE:
7197           scratch = expand_unop (SImode, one_cmpl_optab, operands[2],
7198                                  NULL_RTX, 1);
7199           expand_binop (SImode, lshr_optab, scratch, GEN_INT (31),
7200                         NULL_RTX, 1, OPTAB_WIDEN);
7201           break;
7203         case GT:
7204           scratch = expand_binop (SImode, ashr_optab, operands[2],
7205                                   GEN_INT (31), NULL_RTX, 0, OPTAB_WIDEN);
7206           scratch = expand_binop (SImode, sub_optab, scratch, operands[2],
7207                                   NULL_RTX, 0, OPTAB_WIDEN);
7208           expand_binop (SImode, lshr_optab, scratch, GEN_INT (31), operands[0],
7209                         0, OPTAB_WIDEN);
7210           break;
7212         /* LT is handled by generic code.  No need for unsigned with 0.  */
7213         default:
7214           FAIL;
7215         }
7216       DONE;
7217     }
7219   switch (GET_CODE (operands[1]))
7220     {
7221     case EQ:
7222       scratch = expand_binop (SImode, sub_optab, operands[2], operands[3],
7223                               NULL_RTX, 0, OPTAB_WIDEN);
7224       emit_insn (gen_cstoresi_eq0_thumb1 (operands[0], scratch));
7225       break;
7227     case NE:
7228       scratch = expand_binop (SImode, sub_optab, operands[2], operands[3],
7229                               NULL_RTX, 0, OPTAB_WIDEN);
7230       emit_insn (gen_cstoresi_ne0_thumb1 (operands[0], scratch));
7231       break;
7233     case LE:
7234       op3 = force_reg (SImode, operands[3]);
7236       scratch = expand_binop (SImode, lshr_optab, operands[2], GEN_INT (31),
7237                               NULL_RTX, 1, OPTAB_WIDEN);
7238       scratch2 = expand_binop (SImode, ashr_optab, op3, GEN_INT (31),
7239                               NULL_RTX, 0, OPTAB_WIDEN);
7240       emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch2,
7241                                           op3, operands[2]));
7242       break;
7244     case GE:
7245       op3 = operands[3];
7246       if (!thumb1_cmp_operand (op3, SImode))
7247         op3 = force_reg (SImode, op3);
7248       scratch = expand_binop (SImode, ashr_optab, operands[2], GEN_INT (31),
7249                               NULL_RTX, 0, OPTAB_WIDEN);
7250       scratch2 = expand_binop (SImode, lshr_optab, op3, GEN_INT (31),
7251                                NULL_RTX, 1, OPTAB_WIDEN);
7252       emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch2,
7253                                           operands[2], op3));
7254       break;
7256     case LEU:
7257       op3 = force_reg (SImode, operands[3]);
7258       scratch = force_reg (SImode, const0_rtx);
7259       emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch,
7260                                           op3, operands[2]));
7261       break;
7263     case GEU:
7264       op3 = operands[3];
7265       if (!thumb1_cmp_operand (op3, SImode))
7266         op3 = force_reg (SImode, op3);
7267       scratch = force_reg (SImode, const0_rtx);
7268       emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch,
7269                                           operands[2], op3));
7270       break;
7272     case LTU:
7273       op3 = operands[3];
7274       if (!thumb1_cmp_operand (op3, SImode))
7275         op3 = force_reg (SImode, op3);
7276       scratch = gen_reg_rtx (SImode);
7277       emit_insn (gen_cstoresi_ltu_thumb1 (operands[0], operands[2], op3));
7278       break;
7280     case GTU:
7281       op3 = force_reg (SImode, operands[3]);
7282       scratch = gen_reg_rtx (SImode);
7283       emit_insn (gen_cstoresi_ltu_thumb1 (operands[0], op3, operands[2]));
7284       break;
7286     /* No good sequences for GT, LT.  */
7287     default:
7288       FAIL;
7289     }
7290   DONE;
7293 (define_expand "cstoresf4"
7294   [(set (match_operand:SI 0 "s_register_operand" "")
7295         (match_operator:SI 1 "expandable_comparison_operator"
7296          [(match_operand:SF 2 "s_register_operand" "")
7297           (match_operand:SF 3 "arm_float_compare_operand" "")]))]
7298   "TARGET_32BIT && TARGET_HARD_FLOAT"
7299   "emit_insn (gen_cstore_cc (operands[0], operands[1],
7300                              operands[2], operands[3])); DONE;"
7303 (define_expand "cstoredf4"
7304   [(set (match_operand:SI 0 "s_register_operand" "")
7305         (match_operator:SI 1 "expandable_comparison_operator"
7306          [(match_operand:DF 2 "s_register_operand" "")
7307           (match_operand:DF 3 "arm_float_compare_operand" "")]))]
7308   "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
7309   "emit_insn (gen_cstore_cc (operands[0], operands[1],
7310                              operands[2], operands[3])); DONE;"
7313 (define_expand "cstoredi4"
7314   [(set (match_operand:SI 0 "s_register_operand" "")
7315         (match_operator:SI 1 "expandable_comparison_operator"
7316          [(match_operand:DI 2 "s_register_operand" "")
7317           (match_operand:DI 3 "cmpdi_operand" "")]))]
7318   "TARGET_32BIT"
7319   "{
7320      if (!arm_validize_comparison (&operands[1],
7321                                    &operands[2],
7322                                    &operands[3]))
7323        FAIL;
7324      emit_insn (gen_cstore_cc (operands[0], operands[1], operands[2],
7325                                  operands[3]));
7326      DONE;
7327    }"
7331 ;; Conditional move insns
7333 (define_expand "movsicc"
7334   [(set (match_operand:SI 0 "s_register_operand" "")
7335         (if_then_else:SI (match_operand 1 "expandable_comparison_operator" "")
7336                          (match_operand:SI 2 "arm_not_operand" "")
7337                          (match_operand:SI 3 "arm_not_operand" "")))]
7338   "TARGET_32BIT"
7339   "
7340   {
7341     enum rtx_code code;
7342     rtx ccreg;
7344     if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0), 
7345                                   &XEXP (operands[1], 1)))
7346       FAIL;
7347     
7348     code = GET_CODE (operands[1]);
7349     ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
7350                                  XEXP (operands[1], 1), NULL_RTX);
7351     operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7352   }"
7355 (define_expand "movsfcc"
7356   [(set (match_operand:SF 0 "s_register_operand" "")
7357         (if_then_else:SF (match_operand 1 "arm_cond_move_operator" "")
7358                          (match_operand:SF 2 "s_register_operand" "")
7359                          (match_operand:SF 3 "s_register_operand" "")))]
7360   "TARGET_32BIT && TARGET_HARD_FLOAT"
7361   "
7362   {
7363     enum rtx_code code = GET_CODE (operands[1]);
7364     rtx ccreg;
7366     if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0), 
7367                                   &XEXP (operands[1], 1)))
7368        FAIL;
7370     code = GET_CODE (operands[1]);
7371     ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
7372                                  XEXP (operands[1], 1), NULL_RTX);
7373     operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7374   }"
7377 (define_expand "movdfcc"
7378   [(set (match_operand:DF 0 "s_register_operand" "")
7379         (if_then_else:DF (match_operand 1 "arm_cond_move_operator" "")
7380                          (match_operand:DF 2 "s_register_operand" "")
7381                          (match_operand:DF 3 "s_register_operand" "")))]
7382   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
7383   "
7384   {
7385     enum rtx_code code = GET_CODE (operands[1]);
7386     rtx ccreg;
7388     if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0), 
7389                                   &XEXP (operands[1], 1)))
7390        FAIL;
7391     code = GET_CODE (operands[1]);
7392     ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
7393                                  XEXP (operands[1], 1), NULL_RTX);
7394     operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7395   }"
7398 (define_insn "*cmov<mode>"
7399     [(set (match_operand:SDF 0 "s_register_operand" "=<F_constraint>")
7400         (if_then_else:SDF (match_operator 1 "arm_vsel_comparison_operator"
7401                           [(match_operand 2 "cc_register" "") (const_int 0)])
7402                           (match_operand:SDF 3 "s_register_operand"
7403                                               "<F_constraint>")
7404                           (match_operand:SDF 4 "s_register_operand"
7405                                               "<F_constraint>")))]
7406   "TARGET_HARD_FLOAT && TARGET_FPU_ARMV8 <vfp_double_cond>"
7407   "*
7408   {
7409     enum arm_cond_code code = maybe_get_arm_condition_code (operands[1]);
7410     switch (code)
7411       {
7412       case ARM_GE:
7413       case ARM_GT:
7414       case ARM_EQ:
7415       case ARM_VS:
7416         return \"vsel%d1.<V_if_elem>\\t%<V_reg>0, %<V_reg>3, %<V_reg>4\";
7417       case ARM_LT:
7418       case ARM_LE:
7419       case ARM_NE:
7420       case ARM_VC:
7421         return \"vsel%D1.<V_if_elem>\\t%<V_reg>0, %<V_reg>4, %<V_reg>3\";
7422       default:
7423         gcc_unreachable ();
7424       }
7425     return \"\";
7426   }"
7427   [(set_attr "conds" "use")
7428    (set_attr "type" "fcsel")]
7431 (define_insn_and_split "*movsicc_insn"
7432   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r,r,r,r,r")
7433         (if_then_else:SI
7434          (match_operator 3 "arm_comparison_operator"
7435           [(match_operand 4 "cc_register" "") (const_int 0)])
7436          (match_operand:SI 1 "arm_not_operand" "0,0,rI,K,rI,rI,K,K")
7437          (match_operand:SI 2 "arm_not_operand" "rI,K,0,0,rI,K,rI,K")))]
7438   "TARGET_ARM"
7439   "@
7440    mov%D3\\t%0, %2
7441    mvn%D3\\t%0, #%B2
7442    mov%d3\\t%0, %1
7443    mvn%d3\\t%0, #%B1
7444    #
7445    #
7446    #
7447    #"
7448    ; alt4: mov%d3\\t%0, %1\;mov%D3\\t%0, %2
7449    ; alt5: mov%d3\\t%0, %1\;mvn%D3\\t%0, #%B2
7450    ; alt6: mvn%d3\\t%0, #%B1\;mov%D3\\t%0, %2
7451    ; alt7: mvn%d3\\t%0, #%B1\;mvn%D3\\t%0, #%B2"
7452   "&& reload_completed"
7453   [(const_int 0)]
7454   {
7455     enum rtx_code rev_code;
7456     enum machine_mode mode;
7457     rtx rev_cond;
7459     emit_insn (gen_rtx_COND_EXEC (VOIDmode,
7460                                   operands[3],
7461                                   gen_rtx_SET (VOIDmode,
7462                                                operands[0],
7463                                                operands[1])));
7465     rev_code = GET_CODE (operands[3]);
7466     mode = GET_MODE (operands[4]);
7467     if (mode == CCFPmode || mode == CCFPEmode)
7468       rev_code = reverse_condition_maybe_unordered (rev_code);
7469     else
7470       rev_code = reverse_condition (rev_code);
7472     rev_cond = gen_rtx_fmt_ee (rev_code,
7473                                VOIDmode,
7474                                operands[4],
7475                                const0_rtx);
7476     emit_insn (gen_rtx_COND_EXEC (VOIDmode,
7477                                   rev_cond,
7478                                   gen_rtx_SET (VOIDmode,
7479                                                operands[0],
7480                                                operands[2])));
7481     DONE;
7482   }
7483   [(set_attr "length" "4,4,4,4,8,8,8,8")
7484    (set_attr "conds" "use")
7485    (set_attr_alternative "type"
7486                          [(if_then_else (match_operand 2 "const_int_operand" "")
7487                                         (const_string "mov_imm")
7488                                         (const_string "mov_reg"))
7489                           (const_string "mvn_imm")
7490                           (if_then_else (match_operand 1 "const_int_operand" "")
7491                                         (const_string "mov_imm")
7492                                         (const_string "mov_reg"))
7493                           (const_string "mvn_imm")
7494                           (const_string "mov_reg")
7495                           (const_string "mov_reg")
7496                           (const_string "mov_reg")
7497                           (const_string "mov_reg")])]
7500 (define_insn "*movsfcc_soft_insn"
7501   [(set (match_operand:SF 0 "s_register_operand" "=r,r")
7502         (if_then_else:SF (match_operator 3 "arm_comparison_operator"
7503                           [(match_operand 4 "cc_register" "") (const_int 0)])
7504                          (match_operand:SF 1 "s_register_operand" "0,r")
7505                          (match_operand:SF 2 "s_register_operand" "r,0")))]
7506   "TARGET_ARM && TARGET_SOFT_FLOAT"
7507   "@
7508    mov%D3\\t%0, %2
7509    mov%d3\\t%0, %1"
7510   [(set_attr "conds" "use")
7511    (set_attr "type" "mov_reg")]
7515 ;; Jump and linkage insns
7517 (define_expand "jump"
7518   [(set (pc)
7519         (label_ref (match_operand 0 "" "")))]
7520   "TARGET_EITHER"
7521   ""
7524 (define_insn "*arm_jump"
7525   [(set (pc)
7526         (label_ref (match_operand 0 "" "")))]
7527   "TARGET_32BIT"
7528   "*
7529   {
7530     if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
7531       {
7532         arm_ccfsm_state += 2;
7533         return \"\";
7534       }
7535     return \"b%?\\t%l0\";
7536   }
7537   "
7538   [(set_attr "predicable" "yes")
7539    (set (attr "length")
7540         (if_then_else
7541            (and (match_test "TARGET_THUMB2")
7542                 (and (ge (minus (match_dup 0) (pc)) (const_int -2044))
7543                      (le (minus (match_dup 0) (pc)) (const_int 2048))))
7544            (const_int 2)
7545            (const_int 4)))
7546    (set_attr "type" "branch")]
7549 (define_expand "call"
7550   [(parallel [(call (match_operand 0 "memory_operand" "")
7551                     (match_operand 1 "general_operand" ""))
7552               (use (match_operand 2 "" ""))
7553               (clobber (reg:SI LR_REGNUM))])]
7554   "TARGET_EITHER"
7555   "
7556   {
7557     rtx callee, pat;
7558     
7559     /* In an untyped call, we can get NULL for operand 2.  */
7560     if (operands[2] == NULL_RTX)
7561       operands[2] = const0_rtx;
7562       
7563     /* Decide if we should generate indirect calls by loading the
7564        32-bit address of the callee into a register before performing the
7565        branch and link.  */
7566     callee = XEXP (operands[0], 0);
7567     if (GET_CODE (callee) == SYMBOL_REF
7568         ? arm_is_long_call_p (SYMBOL_REF_DECL (callee))
7569         : !REG_P (callee))
7570       XEXP (operands[0], 0) = force_reg (Pmode, callee);
7572     pat = gen_call_internal (operands[0], operands[1], operands[2]);
7573     arm_emit_call_insn (pat, XEXP (operands[0], 0), false);
7574     DONE;
7575   }"
7578 (define_expand "call_internal"
7579   [(parallel [(call (match_operand 0 "memory_operand" "")
7580                     (match_operand 1 "general_operand" ""))
7581               (use (match_operand 2 "" ""))
7582               (clobber (reg:SI LR_REGNUM))])])
7584 (define_insn "*call_reg_armv5"
7585   [(call (mem:SI (match_operand:SI 0 "s_register_operand" "r"))
7586          (match_operand 1 "" ""))
7587    (use (match_operand 2 "" ""))
7588    (clobber (reg:SI LR_REGNUM))]
7589   "TARGET_ARM && arm_arch5 && !SIBLING_CALL_P (insn)"
7590   "blx%?\\t%0"
7591   [(set_attr "type" "call")]
7594 (define_insn "*call_reg_arm"
7595   [(call (mem:SI (match_operand:SI 0 "s_register_operand" "r"))
7596          (match_operand 1 "" ""))
7597    (use (match_operand 2 "" ""))
7598    (clobber (reg:SI LR_REGNUM))]
7599   "TARGET_ARM && !arm_arch5 && !SIBLING_CALL_P (insn)"
7600   "*
7601   return output_call (operands);
7602   "
7603   ;; length is worst case, normally it is only two
7604   [(set_attr "length" "12")
7605    (set_attr "type" "call")]
7609 ;; Note: not used for armv5+ because the sequence used (ldr pc, ...) is not
7610 ;; considered a function call by the branch predictor of some cores (PR40887).
7611 ;; Falls back to blx rN (*call_reg_armv5).
7613 (define_insn "*call_mem"
7614   [(call (mem:SI (match_operand:SI 0 "call_memory_operand" "m"))
7615          (match_operand 1 "" ""))
7616    (use (match_operand 2 "" ""))
7617    (clobber (reg:SI LR_REGNUM))]
7618   "TARGET_ARM && !arm_arch5 && !SIBLING_CALL_P (insn)"
7619   "*
7620   return output_call_mem (operands);
7621   "
7622   [(set_attr "length" "12")
7623    (set_attr "type" "call")]
7626 (define_expand "call_value"
7627   [(parallel [(set (match_operand       0 "" "")
7628                    (call (match_operand 1 "memory_operand" "")
7629                          (match_operand 2 "general_operand" "")))
7630               (use (match_operand 3 "" ""))
7631               (clobber (reg:SI LR_REGNUM))])]
7632   "TARGET_EITHER"
7633   "
7634   {
7635     rtx pat, callee;
7636     
7637     /* In an untyped call, we can get NULL for operand 2.  */
7638     if (operands[3] == 0)
7639       operands[3] = const0_rtx;
7640       
7641     /* Decide if we should generate indirect calls by loading the
7642        32-bit address of the callee into a register before performing the
7643        branch and link.  */
7644     callee = XEXP (operands[1], 0);
7645     if (GET_CODE (callee) == SYMBOL_REF
7646         ? arm_is_long_call_p (SYMBOL_REF_DECL (callee))
7647         : !REG_P (callee))
7648       XEXP (operands[1], 0) = force_reg (Pmode, callee);
7650     pat = gen_call_value_internal (operands[0], operands[1],
7651                                    operands[2], operands[3]);
7652     arm_emit_call_insn (pat, XEXP (operands[1], 0), false);
7653     DONE;
7654   }"
7657 (define_expand "call_value_internal"
7658   [(parallel [(set (match_operand       0 "" "")
7659                    (call (match_operand 1 "memory_operand" "")
7660                          (match_operand 2 "general_operand" "")))
7661               (use (match_operand 3 "" ""))
7662               (clobber (reg:SI LR_REGNUM))])])
7664 (define_insn "*call_value_reg_armv5"
7665   [(set (match_operand 0 "" "")
7666         (call (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
7667               (match_operand 2 "" "")))
7668    (use (match_operand 3 "" ""))
7669    (clobber (reg:SI LR_REGNUM))]
7670   "TARGET_ARM && arm_arch5 && !SIBLING_CALL_P (insn)"
7671   "blx%?\\t%1"
7672   [(set_attr "type" "call")]
7675 (define_insn "*call_value_reg_arm"
7676   [(set (match_operand 0 "" "")
7677         (call (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
7678               (match_operand 2 "" "")))
7679    (use (match_operand 3 "" ""))
7680    (clobber (reg:SI LR_REGNUM))]
7681   "TARGET_ARM && !arm_arch5 && !SIBLING_CALL_P (insn)"
7682   "*
7683   return output_call (&operands[1]);
7684   "
7685   [(set_attr "length" "12")
7686    (set_attr "type" "call")]
7689 ;; Note: see *call_mem
7691 (define_insn "*call_value_mem"
7692   [(set (match_operand 0 "" "")
7693         (call (mem:SI (match_operand:SI 1 "call_memory_operand" "m"))
7694               (match_operand 2 "" "")))
7695    (use (match_operand 3 "" ""))
7696    (clobber (reg:SI LR_REGNUM))]
7697   "TARGET_ARM && !arm_arch5 && (!CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
7698    && !SIBLING_CALL_P (insn)"
7699   "*
7700   return output_call_mem (&operands[1]);
7701   "
7702   [(set_attr "length" "12")
7703    (set_attr "type" "call")]
7706 ;; Allow calls to SYMBOL_REFs specially as they are not valid general addresses
7707 ;; The 'a' causes the operand to be treated as an address, i.e. no '#' output.
7709 (define_insn "*call_symbol"
7710   [(call (mem:SI (match_operand:SI 0 "" ""))
7711          (match_operand 1 "" ""))
7712    (use (match_operand 2 "" ""))
7713    (clobber (reg:SI LR_REGNUM))]
7714   "TARGET_32BIT
7715    && !SIBLING_CALL_P (insn)
7716    && (GET_CODE (operands[0]) == SYMBOL_REF)
7717    && !arm_is_long_call_p (SYMBOL_REF_DECL (operands[0]))"
7718   "*
7719   {
7720     return NEED_PLT_RELOC ? \"bl%?\\t%a0(PLT)\" : \"bl%?\\t%a0\";
7721   }"
7722   [(set_attr "type" "call")]
7725 (define_insn "*call_value_symbol"
7726   [(set (match_operand 0 "" "")
7727         (call (mem:SI (match_operand:SI 1 "" ""))
7728         (match_operand:SI 2 "" "")))
7729    (use (match_operand 3 "" ""))
7730    (clobber (reg:SI LR_REGNUM))]
7731   "TARGET_32BIT
7732    && !SIBLING_CALL_P (insn)
7733    && (GET_CODE (operands[1]) == SYMBOL_REF)
7734    && !arm_is_long_call_p (SYMBOL_REF_DECL (operands[1]))"
7735   "*
7736   {
7737     return NEED_PLT_RELOC ? \"bl%?\\t%a1(PLT)\" : \"bl%?\\t%a1\";
7738   }"
7739   [(set_attr "type" "call")]
7742 (define_expand "sibcall_internal"
7743   [(parallel [(call (match_operand 0 "memory_operand" "")
7744                     (match_operand 1 "general_operand" ""))
7745               (return)
7746               (use (match_operand 2 "" ""))])])
7748 ;; We may also be able to do sibcalls for Thumb, but it's much harder...
7749 (define_expand "sibcall"
7750   [(parallel [(call (match_operand 0 "memory_operand" "")
7751                     (match_operand 1 "general_operand" ""))
7752               (return)
7753               (use (match_operand 2 "" ""))])]
7754   "TARGET_32BIT"
7755   "
7756   {
7757     rtx pat;
7759     if ((!REG_P (XEXP (operands[0], 0))
7760          && GET_CODE (XEXP (operands[0], 0)) != SYMBOL_REF)
7761         || (GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
7762             && arm_is_long_call_p (SYMBOL_REF_DECL (XEXP (operands[0], 0)))))
7763      XEXP (operands[0], 0) = force_reg (SImode, XEXP (operands[0], 0));
7765     if (operands[2] == NULL_RTX)
7766       operands[2] = const0_rtx;
7768     pat = gen_sibcall_internal (operands[0], operands[1], operands[2]);
7769     arm_emit_call_insn (pat, operands[0], true);
7770     DONE;
7771   }"
7774 (define_expand "sibcall_value_internal"
7775   [(parallel [(set (match_operand 0 "" "")
7776                    (call (match_operand 1 "memory_operand" "")
7777                          (match_operand 2 "general_operand" "")))
7778               (return)
7779               (use (match_operand 3 "" ""))])])
7781 (define_expand "sibcall_value"
7782   [(parallel [(set (match_operand 0 "" "")
7783                    (call (match_operand 1 "memory_operand" "")
7784                          (match_operand 2 "general_operand" "")))
7785               (return)
7786               (use (match_operand 3 "" ""))])]
7787   "TARGET_32BIT"
7788   "
7789   {
7790     rtx pat;
7792     if ((!REG_P (XEXP (operands[1], 0))
7793          && GET_CODE (XEXP (operands[1], 0)) != SYMBOL_REF)
7794         || (GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
7795             && arm_is_long_call_p (SYMBOL_REF_DECL (XEXP (operands[1], 0)))))
7796      XEXP (operands[1], 0) = force_reg (SImode, XEXP (operands[1], 0));
7798     if (operands[3] == NULL_RTX)
7799       operands[3] = const0_rtx;
7801     pat = gen_sibcall_value_internal (operands[0], operands[1],
7802                                       operands[2], operands[3]);
7803     arm_emit_call_insn (pat, operands[1], true);
7804     DONE;
7805   }"
7808 (define_insn "*sibcall_insn"
7809  [(call (mem:SI (match_operand:SI 0 "call_insn_operand" "Cs, US"))
7810         (match_operand 1 "" ""))
7811   (return)
7812   (use (match_operand 2 "" ""))]
7813   "TARGET_32BIT && SIBLING_CALL_P (insn)"
7814   "*
7815   if (which_alternative == 1)
7816     return NEED_PLT_RELOC ? \"b%?\\t%a0(PLT)\" : \"b%?\\t%a0\";
7817   else
7818     {
7819       if (arm_arch5 || arm_arch4t)
7820         return \"bx%?\\t%0\\t%@ indirect register sibling call\";
7821       else
7822         return \"mov%?\\t%|pc, %0\\t%@ indirect register sibling call\";
7823     }
7824   "
7825   [(set_attr "type" "call")]
7828 (define_insn "*sibcall_value_insn"
7829  [(set (match_operand 0 "" "")
7830        (call (mem:SI (match_operand:SI 1 "call_insn_operand" "Cs,US"))
7831              (match_operand 2 "" "")))
7832   (return)
7833   (use (match_operand 3 "" ""))]
7834   "TARGET_32BIT && SIBLING_CALL_P (insn)"
7835   "*
7836   if (which_alternative == 1)
7837    return NEED_PLT_RELOC ? \"b%?\\t%a1(PLT)\" : \"b%?\\t%a1\";
7838   else
7839     {
7840       if (arm_arch5 || arm_arch4t)
7841         return \"bx%?\\t%1\";
7842       else
7843         return \"mov%?\\t%|pc, %1\\t@ indirect sibling call \";
7844     }
7845   "
7846   [(set_attr "type" "call")]
7849 (define_expand "<return_str>return"
7850   [(returns)]
7851   "(TARGET_ARM || (TARGET_THUMB2
7852                    && ARM_FUNC_TYPE (arm_current_func_type ()) == ARM_FT_NORMAL
7853                    && !IS_STACKALIGN (arm_current_func_type ())))
7854     <return_cond_false>"
7855   "
7856   {
7857     if (TARGET_THUMB2)
7858       {
7859         thumb2_expand_return (<return_simple_p>);
7860         DONE;
7861       }
7862   }
7863   "
7866 ;; Often the return insn will be the same as loading from memory, so set attr
7867 (define_insn "*arm_return"
7868   [(return)]
7869   "TARGET_ARM && USE_RETURN_INSN (FALSE)"
7870   "*
7871   {
7872     if (arm_ccfsm_state == 2)
7873       {
7874         arm_ccfsm_state += 2;
7875         return \"\";
7876       }
7877     return output_return_instruction (const_true_rtx, true, false, false);
7878   }"
7879   [(set_attr "type" "load1")
7880    (set_attr "length" "12")
7881    (set_attr "predicable" "yes")]
7884 (define_insn "*cond_<return_str>return"
7885   [(set (pc)
7886         (if_then_else (match_operator 0 "arm_comparison_operator"
7887                        [(match_operand 1 "cc_register" "") (const_int 0)])
7888                       (returns)
7889                       (pc)))]
7890   "TARGET_ARM  <return_cond_true>"
7891   "*
7892   {
7893     if (arm_ccfsm_state == 2)
7894       {
7895         arm_ccfsm_state += 2;
7896         return \"\";
7897       }
7898     return output_return_instruction (operands[0], true, false,
7899                                       <return_simple_p>);
7900   }"
7901   [(set_attr "conds" "use")
7902    (set_attr "length" "12")
7903    (set_attr "type" "load1")]
7906 (define_insn "*cond_<return_str>return_inverted"
7907   [(set (pc)
7908         (if_then_else (match_operator 0 "arm_comparison_operator"
7909                        [(match_operand 1 "cc_register" "") (const_int 0)])
7910                       (pc)
7911                       (returns)))]
7912   "TARGET_ARM <return_cond_true>"
7913   "*
7914   {
7915     if (arm_ccfsm_state == 2)
7916       {
7917         arm_ccfsm_state += 2;
7918         return \"\";
7919       }
7920     return output_return_instruction (operands[0], true, true,
7921                                       <return_simple_p>);
7922   }"
7923   [(set_attr "conds" "use")
7924    (set_attr "length" "12")
7925    (set_attr "type" "load1")]
7928 (define_insn "*arm_simple_return"
7929   [(simple_return)]
7930   "TARGET_ARM"
7931   "*
7932   {
7933     if (arm_ccfsm_state == 2)
7934       {
7935         arm_ccfsm_state += 2;
7936         return \"\";
7937       }
7938     return output_return_instruction (const_true_rtx, true, false, true);
7939   }"
7940   [(set_attr "type" "branch")
7941    (set_attr "length" "4")
7942    (set_attr "predicable" "yes")]
7945 ;; Generate a sequence of instructions to determine if the processor is
7946 ;; in 26-bit or 32-bit mode, and return the appropriate return address
7947 ;; mask.
7949 (define_expand "return_addr_mask"
7950   [(set (match_dup 1)
7951       (compare:CC_NOOV (unspec [(const_int 0)] UNSPEC_CHECK_ARCH)
7952                        (const_int 0)))
7953    (set (match_operand:SI 0 "s_register_operand" "")
7954       (if_then_else:SI (eq (match_dup 1) (const_int 0))
7955                        (const_int -1)
7956                        (const_int 67108860)))] ; 0x03fffffc
7957   "TARGET_ARM"
7958   "
7959   operands[1] = gen_rtx_REG (CC_NOOVmode, CC_REGNUM);
7960   ")
7962 (define_insn "*check_arch2"
7963   [(set (match_operand:CC_NOOV 0 "cc_register" "")
7964       (compare:CC_NOOV (unspec [(const_int 0)] UNSPEC_CHECK_ARCH)
7965                        (const_int 0)))]
7966   "TARGET_ARM"
7967   "teq\\t%|r0, %|r0\;teq\\t%|pc, %|pc"
7968   [(set_attr "length" "8")
7969    (set_attr "conds" "set")
7970    (set_attr "type" "multiple")]
7973 ;; Call subroutine returning any type.
7975 (define_expand "untyped_call"
7976   [(parallel [(call (match_operand 0 "" "")
7977                     (const_int 0))
7978               (match_operand 1 "" "")
7979               (match_operand 2 "" "")])]
7980   "TARGET_EITHER"
7981   "
7982   {
7983     int i;
7984     rtx par = gen_rtx_PARALLEL (VOIDmode,
7985                                 rtvec_alloc (XVECLEN (operands[2], 0)));
7986     rtx addr = gen_reg_rtx (Pmode);
7987     rtx mem;
7988     int size = 0;
7990     emit_move_insn (addr, XEXP (operands[1], 0));
7991     mem = change_address (operands[1], BLKmode, addr);
7993     for (i = 0; i < XVECLEN (operands[2], 0); i++)
7994       {
7995         rtx src = SET_SRC (XVECEXP (operands[2], 0, i));
7997         /* Default code only uses r0 as a return value, but we could
7998            be using anything up to 4 registers.  */
7999         if (REGNO (src) == R0_REGNUM)
8000           src = gen_rtx_REG (TImode, R0_REGNUM);
8002         XVECEXP (par, 0, i) = gen_rtx_EXPR_LIST (VOIDmode, src,
8003                                                  GEN_INT (size));
8004         size += GET_MODE_SIZE (GET_MODE (src));
8005       }
8007     emit_call_insn (GEN_CALL_VALUE (par, operands[0], const0_rtx, NULL,
8008                                     const0_rtx));
8010     size = 0;
8012     for (i = 0; i < XVECLEN (par, 0); i++)
8013       {
8014         HOST_WIDE_INT offset = 0;
8015         rtx reg = XEXP (XVECEXP (par, 0, i), 0);
8017         if (size != 0)
8018           emit_move_insn (addr, plus_constant (Pmode, addr, size));
8020         mem = change_address (mem, GET_MODE (reg), NULL);
8021         if (REGNO (reg) == R0_REGNUM)
8022           {
8023             /* On thumb we have to use a write-back instruction.  */
8024             emit_insn (arm_gen_store_multiple (arm_regs_in_sequence, 4, addr,
8025                        TARGET_THUMB ? TRUE : FALSE, mem, &offset));
8026             size = TARGET_ARM ? 16 : 0;
8027           }
8028         else
8029           {
8030             emit_move_insn (mem, reg);
8031             size = GET_MODE_SIZE (GET_MODE (reg));
8032           }
8033       }
8035     /* The optimizer does not know that the call sets the function value
8036        registers we stored in the result block.  We avoid problems by
8037        claiming that all hard registers are used and clobbered at this
8038        point.  */
8039     emit_insn (gen_blockage ());
8041     DONE;
8042   }"
8045 (define_expand "untyped_return"
8046   [(match_operand:BLK 0 "memory_operand" "")
8047    (match_operand 1 "" "")]
8048   "TARGET_EITHER"
8049   "
8050   {
8051     int i;
8052     rtx addr = gen_reg_rtx (Pmode);
8053     rtx mem;
8054     int size = 0;
8056     emit_move_insn (addr, XEXP (operands[0], 0));
8057     mem = change_address (operands[0], BLKmode, addr);
8059     for (i = 0; i < XVECLEN (operands[1], 0); i++)
8060       {
8061         HOST_WIDE_INT offset = 0;
8062         rtx reg = SET_DEST (XVECEXP (operands[1], 0, i));
8064         if (size != 0)
8065           emit_move_insn (addr, plus_constant (Pmode, addr, size));
8067         mem = change_address (mem, GET_MODE (reg), NULL);
8068         if (REGNO (reg) == R0_REGNUM)
8069           {
8070             /* On thumb we have to use a write-back instruction.  */
8071             emit_insn (arm_gen_load_multiple (arm_regs_in_sequence, 4, addr,
8072                        TARGET_THUMB ? TRUE : FALSE, mem, &offset));
8073             size = TARGET_ARM ? 16 : 0;
8074           }
8075         else
8076           {
8077             emit_move_insn (reg, mem);
8078             size = GET_MODE_SIZE (GET_MODE (reg));
8079           }
8080       }
8082     /* Emit USE insns before the return.  */
8083     for (i = 0; i < XVECLEN (operands[1], 0); i++)
8084       emit_use (SET_DEST (XVECEXP (operands[1], 0, i)));
8086     /* Construct the return.  */
8087     expand_naked_return ();
8089     DONE;
8090   }"
8093 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
8094 ;; all of memory.  This blocks insns from being moved across this point.
8096 (define_insn "blockage"
8097   [(unspec_volatile [(const_int 0)] VUNSPEC_BLOCKAGE)]
8098   "TARGET_EITHER"
8099   ""
8100   [(set_attr "length" "0")
8101    (set_attr "type" "block")]
8104 (define_expand "casesi"
8105   [(match_operand:SI 0 "s_register_operand" "") ; index to jump on
8106    (match_operand:SI 1 "const_int_operand" "")  ; lower bound
8107    (match_operand:SI 2 "const_int_operand" "")  ; total range
8108    (match_operand:SI 3 "" "")                   ; table label
8109    (match_operand:SI 4 "" "")]                  ; Out of range label
8110   "TARGET_32BIT || optimize_size || flag_pic"
8111   "
8112   {
8113     enum insn_code code;
8114     if (operands[1] != const0_rtx)
8115       {
8116         rtx reg = gen_reg_rtx (SImode);
8118         emit_insn (gen_addsi3 (reg, operands[0],
8119                                gen_int_mode (-INTVAL (operands[1]),
8120                                              SImode)));
8121         operands[0] = reg;
8122       }
8124     if (TARGET_ARM)
8125       code = CODE_FOR_arm_casesi_internal;
8126     else if (TARGET_THUMB1)
8127       code = CODE_FOR_thumb1_casesi_internal_pic;
8128     else if (flag_pic)
8129       code = CODE_FOR_thumb2_casesi_internal_pic;
8130     else
8131       code = CODE_FOR_thumb2_casesi_internal;
8133     if (!insn_data[(int) code].operand[1].predicate(operands[2], SImode))
8134       operands[2] = force_reg (SImode, operands[2]);
8136     emit_jump_insn (GEN_FCN ((int) code) (operands[0], operands[2],
8137                                           operands[3], operands[4]));
8138     DONE;
8139   }"
8142 ;; The USE in this pattern is needed to tell flow analysis that this is
8143 ;; a CASESI insn.  It has no other purpose.
8144 (define_insn "arm_casesi_internal"
8145   [(parallel [(set (pc)
8146                (if_then_else
8147                 (leu (match_operand:SI 0 "s_register_operand" "r")
8148                      (match_operand:SI 1 "arm_rhs_operand" "rI"))
8149                 (mem:SI (plus:SI (mult:SI (match_dup 0) (const_int 4))
8150                                  (label_ref (match_operand 2 "" ""))))
8151                 (label_ref (match_operand 3 "" ""))))
8152               (clobber (reg:CC CC_REGNUM))
8153               (use (label_ref (match_dup 2)))])]
8154   "TARGET_ARM"
8155   "*
8156     if (flag_pic)
8157       return \"cmp\\t%0, %1\;addls\\t%|pc, %|pc, %0, asl #2\;b\\t%l3\";
8158     return   \"cmp\\t%0, %1\;ldrls\\t%|pc, [%|pc, %0, asl #2]\;b\\t%l3\";
8159   "
8160   [(set_attr "conds" "clob")
8161    (set_attr "length" "12")
8162    (set_attr "type" "multiple")]
8165 (define_expand "indirect_jump"
8166   [(set (pc)
8167         (match_operand:SI 0 "s_register_operand" ""))]
8168   "TARGET_EITHER"
8169   "
8170   /* Thumb-2 doesn't have mov pc, reg.  Explicitly set the low bit of the
8171      address and use bx.  */
8172   if (TARGET_THUMB2)
8173     {
8174       rtx tmp;
8175       tmp = gen_reg_rtx (SImode);
8176       emit_insn (gen_iorsi3 (tmp, operands[0], GEN_INT(1)));
8177       operands[0] = tmp;
8178     }
8179   "
8182 ;; NB Never uses BX.
8183 (define_insn "*arm_indirect_jump"
8184   [(set (pc)
8185         (match_operand:SI 0 "s_register_operand" "r"))]
8186   "TARGET_ARM"
8187   "mov%?\\t%|pc, %0\\t%@ indirect register jump"
8188   [(set_attr "predicable" "yes")
8189    (set_attr "type" "branch")]
8192 (define_insn "*load_indirect_jump"
8193   [(set (pc)
8194         (match_operand:SI 0 "memory_operand" "m"))]
8195   "TARGET_ARM"
8196   "ldr%?\\t%|pc, %0\\t%@ indirect memory jump"
8197   [(set_attr "type" "load1")
8198    (set_attr "pool_range" "4096")
8199    (set_attr "neg_pool_range" "4084")
8200    (set_attr "predicable" "yes")]
8204 ;; Misc insns
8206 (define_insn "nop"
8207   [(const_int 0)]
8208   "TARGET_EITHER"
8209   "*
8210   if (TARGET_UNIFIED_ASM)
8211     return \"nop\";
8212   if (TARGET_ARM)
8213     return \"mov%?\\t%|r0, %|r0\\t%@ nop\";
8214   return  \"mov\\tr8, r8\";
8215   "
8216   [(set (attr "length")
8217         (if_then_else (eq_attr "is_thumb" "yes")
8218                       (const_int 2)
8219                       (const_int 4)))
8220    (set_attr "type" "mov_reg")]
8223 (define_insn "trap"
8224   [(trap_if (const_int 1) (const_int 0))]
8225   ""
8226   "*
8227   if (TARGET_ARM)
8228     return \".inst\\t0xe7f000f0\";
8229   else
8230     return \".inst\\t0xdeff\";
8231   "
8232   [(set (attr "length")
8233         (if_then_else (eq_attr "is_thumb" "yes")
8234                       (const_int 2)
8235                       (const_int 4)))
8236    (set_attr "type" "trap")
8237    (set_attr "conds" "unconditional")]
8241 ;; Patterns to allow combination of arithmetic, cond code and shifts
8243 (define_insn "*<arith_shift_insn>_multsi"
8244   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8245         (shiftable_ops:SI
8246          (mult:SI (match_operand:SI 2 "s_register_operand" "r,r")
8247                   (match_operand:SI 3 "power_of_two_operand" ""))
8248          (match_operand:SI 1 "s_register_operand" "rk,<t2_binop0>")))]
8249   "TARGET_32BIT"
8250   "<arith_shift_insn>%?\\t%0, %1, %2, lsl %b3"
8251   [(set_attr "predicable" "yes")
8252    (set_attr "predicable_short_it" "no")
8253    (set_attr "shift" "4")
8254    (set_attr "arch" "a,t2")
8255    (set_attr "type" "alu_shift_imm")])
8257 (define_insn "*<arith_shift_insn>_shiftsi"
8258   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
8259         (shiftable_ops:SI
8260          (match_operator:SI 2 "shift_nomul_operator"
8261           [(match_operand:SI 3 "s_register_operand" "r,r,r")
8262            (match_operand:SI 4 "shift_amount_operand" "M,M,r")])
8263          (match_operand:SI 1 "s_register_operand" "rk,<t2_binop0>,rk")))]
8264   "TARGET_32BIT && GET_CODE (operands[3]) != MULT"
8265   "<arith_shift_insn>%?\\t%0, %1, %3%S2"
8266   [(set_attr "predicable" "yes")
8267    (set_attr "predicable_short_it" "no")
8268    (set_attr "shift" "4")
8269    (set_attr "arch" "a,t2,a")
8270    (set_attr "type" "alu_shift_imm,alu_shift_imm,alu_shift_reg")])
8272 (define_split
8273   [(set (match_operand:SI 0 "s_register_operand" "")
8274         (match_operator:SI 1 "shiftable_operator"
8275          [(match_operator:SI 2 "shiftable_operator"
8276            [(match_operator:SI 3 "shift_operator"
8277              [(match_operand:SI 4 "s_register_operand" "")
8278               (match_operand:SI 5 "reg_or_int_operand" "")])
8279             (match_operand:SI 6 "s_register_operand" "")])
8280           (match_operand:SI 7 "arm_rhs_operand" "")]))
8281    (clobber (match_operand:SI 8 "s_register_operand" ""))]
8282   "TARGET_32BIT"
8283   [(set (match_dup 8)
8284         (match_op_dup 2 [(match_op_dup 3 [(match_dup 4) (match_dup 5)])
8285                          (match_dup 6)]))
8286    (set (match_dup 0)
8287         (match_op_dup 1 [(match_dup 8) (match_dup 7)]))]
8288   "")
8290 (define_insn "*arith_shiftsi_compare0"
8291   [(set (reg:CC_NOOV CC_REGNUM)
8292         (compare:CC_NOOV
8293          (match_operator:SI 1 "shiftable_operator"
8294           [(match_operator:SI 3 "shift_operator"
8295             [(match_operand:SI 4 "s_register_operand" "r,r")
8296              (match_operand:SI 5 "shift_amount_operand" "M,r")])
8297            (match_operand:SI 2 "s_register_operand" "r,r")])
8298          (const_int 0)))
8299    (set (match_operand:SI 0 "s_register_operand" "=r,r")
8300         (match_op_dup 1 [(match_op_dup 3 [(match_dup 4) (match_dup 5)])
8301                          (match_dup 2)]))]
8302   "TARGET_32BIT"
8303   "%i1%.\\t%0, %2, %4%S3"
8304   [(set_attr "conds" "set")
8305    (set_attr "shift" "4")
8306    (set_attr "arch" "32,a")
8307    (set_attr "type" "alus_shift_imm,alus_shift_reg")])
8309 (define_insn "*arith_shiftsi_compare0_scratch"
8310   [(set (reg:CC_NOOV CC_REGNUM)
8311         (compare:CC_NOOV
8312          (match_operator:SI 1 "shiftable_operator"
8313           [(match_operator:SI 3 "shift_operator"
8314             [(match_operand:SI 4 "s_register_operand" "r,r")
8315              (match_operand:SI 5 "shift_amount_operand" "M,r")])
8316            (match_operand:SI 2 "s_register_operand" "r,r")])
8317          (const_int 0)))
8318    (clobber (match_scratch:SI 0 "=r,r"))]
8319   "TARGET_32BIT"
8320   "%i1%.\\t%0, %2, %4%S3"
8321   [(set_attr "conds" "set")
8322    (set_attr "shift" "4")
8323    (set_attr "arch" "32,a")
8324    (set_attr "type" "alus_shift_imm,alus_shift_reg")])
8326 (define_insn "*sub_shiftsi"
8327   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8328         (minus:SI (match_operand:SI 1 "s_register_operand" "r,r")
8329                   (match_operator:SI 2 "shift_operator"
8330                    [(match_operand:SI 3 "s_register_operand" "r,r")
8331                     (match_operand:SI 4 "shift_amount_operand" "M,r")])))]
8332   "TARGET_32BIT"
8333   "sub%?\\t%0, %1, %3%S2"
8334   [(set_attr "predicable" "yes")
8335    (set_attr "shift" "3")
8336    (set_attr "arch" "32,a")
8337    (set_attr "type" "alus_shift_imm,alus_shift_reg")])
8339 (define_insn "*sub_shiftsi_compare0"
8340   [(set (reg:CC_NOOV CC_REGNUM)
8341         (compare:CC_NOOV
8342          (minus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
8343                    (match_operator:SI 2 "shift_operator"
8344                     [(match_operand:SI 3 "s_register_operand" "r,r,r")
8345                      (match_operand:SI 4 "shift_amount_operand" "M,r,M")]))
8346          (const_int 0)))
8347    (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
8348         (minus:SI (match_dup 1)
8349                   (match_op_dup 2 [(match_dup 3) (match_dup 4)])))]
8350   "TARGET_32BIT"
8351   "sub%.\\t%0, %1, %3%S2"
8352   [(set_attr "conds" "set")
8353    (set_attr "shift" "3")
8354    (set_attr "arch" "32,a,a")
8355    (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
8357 (define_insn "*sub_shiftsi_compare0_scratch"
8358   [(set (reg:CC_NOOV CC_REGNUM)
8359         (compare:CC_NOOV
8360          (minus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
8361                    (match_operator:SI 2 "shift_operator"
8362                     [(match_operand:SI 3 "s_register_operand" "r,r,r")
8363                      (match_operand:SI 4 "shift_amount_operand" "M,r,M")]))
8364          (const_int 0)))
8365    (clobber (match_scratch:SI 0 "=r,r,r"))]
8366   "TARGET_32BIT"
8367   "sub%.\\t%0, %1, %3%S2"
8368   [(set_attr "conds" "set")
8369    (set_attr "shift" "3")
8370    (set_attr "arch" "32,a,a")
8371    (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
8374 (define_insn_and_split "*and_scc"
8375   [(set (match_operand:SI 0 "s_register_operand" "=r")
8376         (and:SI (match_operator:SI 1 "arm_comparison_operator"
8377                  [(match_operand 2 "cc_register" "") (const_int 0)])
8378                 (match_operand:SI 3 "s_register_operand" "r")))]
8379   "TARGET_ARM"
8380   "#"   ; "mov%D1\\t%0, #0\;and%d1\\t%0, %3, #1"
8381   "&& reload_completed"
8382   [(cond_exec (match_dup 5) (set (match_dup 0) (const_int 0)))
8383    (cond_exec (match_dup 4) (set (match_dup 0)
8384                                  (and:SI (match_dup 3) (const_int 1))))]
8385   {
8386     enum machine_mode mode = GET_MODE (operands[2]);
8387     enum rtx_code rc = GET_CODE (operands[1]);
8389     /* Note that operands[4] is the same as operands[1],
8390        but with VOIDmode as the result. */
8391     operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
8392     if (mode == CCFPmode || mode == CCFPEmode)
8393       rc = reverse_condition_maybe_unordered (rc);
8394     else
8395       rc = reverse_condition (rc);
8396     operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
8397   }
8398   [(set_attr "conds" "use")
8399    (set_attr "type" "multiple")
8400    (set_attr "length" "8")]
8403 (define_insn_and_split "*ior_scc"
8404   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8405         (ior:SI (match_operator:SI 1 "arm_comparison_operator"
8406                  [(match_operand 2 "cc_register" "") (const_int 0)])
8407                 (match_operand:SI 3 "s_register_operand" "0,?r")))]
8408   "TARGET_ARM"
8409   "@
8410    orr%d1\\t%0, %3, #1
8411    #"
8412   "&& reload_completed
8413    && REGNO (operands [0]) != REGNO (operands[3])"
8414   ;; && which_alternative == 1
8415   ; mov%D1\\t%0, %3\;orr%d1\\t%0, %3, #1
8416   [(cond_exec (match_dup 5) (set (match_dup 0) (match_dup 3)))
8417    (cond_exec (match_dup 4) (set (match_dup 0)
8418                                  (ior:SI (match_dup 3) (const_int 1))))]
8419   {
8420     enum machine_mode mode = GET_MODE (operands[2]);
8421     enum rtx_code rc = GET_CODE (operands[1]);
8423     /* Note that operands[4] is the same as operands[1],
8424        but with VOIDmode as the result. */
8425     operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
8426     if (mode == CCFPmode || mode == CCFPEmode)
8427       rc = reverse_condition_maybe_unordered (rc);
8428     else
8429       rc = reverse_condition (rc);
8430     operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
8431   }
8432   [(set_attr "conds" "use")
8433    (set_attr "length" "4,8")
8434    (set_attr "type" "logic_imm,multiple")]
8437 ; A series of splitters for the compare_scc pattern below.  Note that
8438 ; order is important.
8439 (define_split
8440   [(set (match_operand:SI 0 "s_register_operand" "")
8441         (lt:SI (match_operand:SI 1 "s_register_operand" "")
8442                (const_int 0)))
8443    (clobber (reg:CC CC_REGNUM))]
8444   "TARGET_32BIT && reload_completed"
8445   [(set (match_dup 0) (lshiftrt:SI (match_dup 1) (const_int 31)))])
8447 (define_split
8448   [(set (match_operand:SI 0 "s_register_operand" "")
8449         (ge:SI (match_operand:SI 1 "s_register_operand" "")
8450                (const_int 0)))
8451    (clobber (reg:CC CC_REGNUM))]
8452   "TARGET_32BIT && reload_completed"
8453   [(set (match_dup 0) (not:SI (match_dup 1)))
8454    (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 31)))])
8456 (define_split
8457   [(set (match_operand:SI 0 "s_register_operand" "")
8458         (eq:SI (match_operand:SI 1 "s_register_operand" "")
8459                (const_int 0)))
8460    (clobber (reg:CC CC_REGNUM))]
8461   "arm_arch5 && TARGET_32BIT"
8462   [(set (match_dup 0) (clz:SI (match_dup 1)))
8463    (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
8466 (define_split
8467   [(set (match_operand:SI 0 "s_register_operand" "")
8468         (eq:SI (match_operand:SI 1 "s_register_operand" "")
8469                (const_int 0)))
8470    (clobber (reg:CC CC_REGNUM))]
8471   "TARGET_32BIT && reload_completed"
8472   [(parallel
8473     [(set (reg:CC CC_REGNUM)
8474           (compare:CC (const_int 1) (match_dup 1)))
8475      (set (match_dup 0)
8476           (minus:SI (const_int 1) (match_dup 1)))])
8477    (cond_exec (ltu:CC (reg:CC CC_REGNUM) (const_int 0))
8478               (set (match_dup 0) (const_int 0)))])
8480 (define_split
8481   [(set (match_operand:SI 0 "s_register_operand" "")
8482         (ne:SI (match_operand:SI 1 "s_register_operand" "")
8483                (match_operand:SI 2 "const_int_operand" "")))
8484    (clobber (reg:CC CC_REGNUM))]
8485   "TARGET_32BIT && reload_completed"
8486   [(parallel
8487     [(set (reg:CC CC_REGNUM)
8488           (compare:CC (match_dup 1) (match_dup 2)))
8489      (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 3)))])
8490    (cond_exec (ne:CC (reg:CC CC_REGNUM) (const_int 0))
8491               (set (match_dup 0) (const_int 1)))]
8493   operands[3] = GEN_INT (-INTVAL (operands[2]));
8496 (define_split
8497   [(set (match_operand:SI 0 "s_register_operand" "")
8498         (ne:SI (match_operand:SI 1 "s_register_operand" "")
8499                (match_operand:SI 2 "arm_add_operand" "")))
8500    (clobber (reg:CC CC_REGNUM))]
8501   "TARGET_32BIT && reload_completed"
8502   [(parallel
8503     [(set (reg:CC_NOOV CC_REGNUM)
8504           (compare:CC_NOOV (minus:SI (match_dup 1) (match_dup 2))
8505                            (const_int 0)))
8506      (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
8507    (cond_exec (ne:CC_NOOV (reg:CC_NOOV CC_REGNUM) (const_int 0))
8508               (set (match_dup 0) (const_int 1)))])
8510 (define_insn_and_split "*compare_scc"
8511   [(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts")
8512         (match_operator:SI 1 "arm_comparison_operator"
8513          [(match_operand:SI 2 "s_register_operand" "r,r")
8514           (match_operand:SI 3 "arm_add_operand" "rI,L")]))
8515    (clobber (reg:CC CC_REGNUM))]
8516   "TARGET_32BIT"
8517   "#"
8518   "&& reload_completed"
8519   [(set (reg:CC CC_REGNUM) (compare:CC (match_dup 2) (match_dup 3)))
8520    (cond_exec (match_dup 4) (set (match_dup 0) (const_int 0)))
8521    (cond_exec (match_dup 5) (set (match_dup 0) (const_int 1)))]
8523   rtx tmp1;
8524   enum machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
8525                                            operands[2], operands[3]);
8526   enum rtx_code rc = GET_CODE (operands[1]);
8528   tmp1 = gen_rtx_REG (mode, CC_REGNUM);
8530   operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, tmp1, const0_rtx);
8531   if (mode == CCFPmode || mode == CCFPEmode)
8532     rc = reverse_condition_maybe_unordered (rc);
8533   else
8534     rc = reverse_condition (rc);
8535   operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, tmp1, const0_rtx);
8537   [(set_attr "type" "multiple")]
8540 ;; Attempt to improve the sequence generated by the compare_scc splitters
8541 ;; not to use conditional execution.
8543 ;; Rd = (eq (reg1) (const_int0))  // ARMv5
8544 ;;      clz Rd, reg1
8545 ;;      lsr Rd, Rd, #5
8546 (define_peephole2
8547   [(set (reg:CC CC_REGNUM)
8548         (compare:CC (match_operand:SI 1 "register_operand" "")
8549                     (const_int 0)))
8550    (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
8551               (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
8552    (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
8553               (set (match_dup 0) (const_int 1)))]
8554   "arm_arch5 && TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
8555   [(set (match_dup 0) (clz:SI (match_dup 1)))
8556    (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
8559 ;; Rd = (eq (reg1) (const_int0))  // !ARMv5
8560 ;;      negs Rd, reg1
8561 ;;      adc  Rd, Rd, reg1
8562 (define_peephole2
8563   [(set (reg:CC CC_REGNUM)
8564         (compare:CC (match_operand:SI 1 "register_operand" "")
8565                     (const_int 0)))
8566    (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
8567               (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
8568    (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
8569               (set (match_dup 0) (const_int 1)))
8570    (match_scratch:SI 2 "r")]
8571   "TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
8572   [(parallel
8573     [(set (reg:CC CC_REGNUM)
8574           (compare:CC (const_int 0) (match_dup 1)))
8575      (set (match_dup 2) (minus:SI (const_int 0) (match_dup 1)))])
8576    (set (match_dup 0)
8577         (plus:SI (plus:SI (match_dup 1) (match_dup 2))
8578                  (geu:SI (reg:CC CC_REGNUM) (const_int 0))))]
8581 ;; Rd = (eq (reg1) (reg2/imm))  // ARMv5 and optimising for speed.
8582 ;;      sub  Rd, Reg1, reg2
8583 ;;      clz  Rd, Rd
8584 ;;      lsr  Rd, Rd, #5
8585 (define_peephole2
8586   [(set (reg:CC CC_REGNUM)
8587         (compare:CC (match_operand:SI 1 "register_operand" "")
8588                     (match_operand:SI 2 "arm_rhs_operand" "")))
8589    (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
8590               (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
8591    (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
8592               (set (match_dup 0) (const_int 1)))]
8593   "arm_arch5 && TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)
8594   && !(TARGET_THUMB2 && optimize_insn_for_size_p ())"
8595   [(set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))
8596    (set (match_dup 0) (clz:SI (match_dup 0)))
8597    (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
8601 ;; Rd = (eq (reg1) (reg2))      // ! ARMv5 or optimising for size.
8602 ;;      sub  T1, Reg1, reg2
8603 ;;      negs Rd, T1
8604 ;;      adc  Rd, Rd, T1
8605 (define_peephole2
8606   [(set (reg:CC CC_REGNUM)
8607         (compare:CC (match_operand:SI 1 "register_operand" "")
8608                     (match_operand:SI 2 "arm_rhs_operand" "")))
8609    (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
8610               (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
8611    (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
8612               (set (match_dup 0) (const_int 1)))
8613    (match_scratch:SI 3 "r")]
8614   "TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
8615   [(set (match_dup 3) (match_dup 4))
8616    (parallel
8617     [(set (reg:CC CC_REGNUM)
8618           (compare:CC (const_int 0) (match_dup 3)))
8619      (set (match_dup 0) (minus:SI (const_int 0) (match_dup 3)))])
8620    (set (match_dup 0)
8621         (plus:SI (plus:SI (match_dup 0) (match_dup 3))
8622                  (geu:SI (reg:CC CC_REGNUM) (const_int 0))))]
8623   "
8624   if (CONST_INT_P (operands[2]))
8625     operands[4] = plus_constant (SImode, operands[1], -INTVAL (operands[2]));
8626   else
8627     operands[4] = gen_rtx_MINUS (SImode, operands[1], operands[2]);
8628   ")
8630 (define_insn "*cond_move"
8631   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
8632         (if_then_else:SI (match_operator 3 "equality_operator"
8633                           [(match_operator 4 "arm_comparison_operator"
8634                             [(match_operand 5 "cc_register" "") (const_int 0)])
8635                            (const_int 0)])
8636                          (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
8637                          (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))]
8638   "TARGET_ARM"
8639   "*
8640     if (GET_CODE (operands[3]) == NE)
8641       {
8642         if (which_alternative != 1)
8643           output_asm_insn (\"mov%D4\\t%0, %2\", operands);
8644         if (which_alternative != 0)
8645           output_asm_insn (\"mov%d4\\t%0, %1\", operands);
8646         return \"\";
8647       }
8648     if (which_alternative != 0)
8649       output_asm_insn (\"mov%D4\\t%0, %1\", operands);
8650     if (which_alternative != 1)
8651       output_asm_insn (\"mov%d4\\t%0, %2\", operands);
8652     return \"\";
8653   "
8654   [(set_attr "conds" "use")
8655    (set_attr "type" "mov_reg,mov_reg,multiple")
8656    (set_attr "length" "4,4,8")]
8659 (define_insn "*cond_arith"
8660   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8661         (match_operator:SI 5 "shiftable_operator" 
8662          [(match_operator:SI 4 "arm_comparison_operator"
8663            [(match_operand:SI 2 "s_register_operand" "r,r")
8664             (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
8665           (match_operand:SI 1 "s_register_operand" "0,?r")]))
8666    (clobber (reg:CC CC_REGNUM))]
8667   "TARGET_ARM"
8668   "*
8669     if (GET_CODE (operands[4]) == LT && operands[3] == const0_rtx)
8670       return \"%i5\\t%0, %1, %2, lsr #31\";
8672     output_asm_insn (\"cmp\\t%2, %3\", operands);
8673     if (GET_CODE (operands[5]) == AND)
8674       output_asm_insn (\"mov%D4\\t%0, #0\", operands);
8675     else if (GET_CODE (operands[5]) == MINUS)
8676       output_asm_insn (\"rsb%D4\\t%0, %1, #0\", operands);
8677     else if (which_alternative != 0)
8678       output_asm_insn (\"mov%D4\\t%0, %1\", operands);
8679     return \"%i5%d4\\t%0, %1, #1\";
8680   "
8681   [(set_attr "conds" "clob")
8682    (set_attr "length" "12")
8683    (set_attr "type" "multiple")]
8686 (define_insn "*cond_sub"
8687   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8688         (minus:SI (match_operand:SI 1 "s_register_operand" "0,?r")
8689                   (match_operator:SI 4 "arm_comparison_operator"
8690                    [(match_operand:SI 2 "s_register_operand" "r,r")
8691                     (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
8692    (clobber (reg:CC CC_REGNUM))]
8693   "TARGET_ARM"
8694   "*
8695     output_asm_insn (\"cmp\\t%2, %3\", operands);
8696     if (which_alternative != 0)
8697       output_asm_insn (\"mov%D4\\t%0, %1\", operands);
8698     return \"sub%d4\\t%0, %1, #1\";
8699   "
8700   [(set_attr "conds" "clob")
8701    (set_attr "length" "8,12")
8702    (set_attr "type" "multiple")]
8705 (define_insn "*cmp_ite0"
8706   [(set (match_operand 6 "dominant_cc_register" "")
8707         (compare
8708          (if_then_else:SI
8709           (match_operator 4 "arm_comparison_operator"
8710            [(match_operand:SI 0 "s_register_operand"
8711                 "l,l,l,r,r,r,r,r,r")
8712             (match_operand:SI 1 "arm_add_operand"
8713                 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
8714           (match_operator:SI 5 "arm_comparison_operator"
8715            [(match_operand:SI 2 "s_register_operand"
8716                 "l,r,r,l,l,r,r,r,r")
8717             (match_operand:SI 3 "arm_add_operand"
8718                 "lPy,rI,L,lPy,lPy,rI,rI,L,L")])
8719           (const_int 0))
8720          (const_int 0)))]
8721   "TARGET_32BIT"
8722   "*
8723   {
8724     static const char * const cmp1[NUM_OF_COND_CMP][2] =
8725     {
8726       {\"cmp%d5\\t%0, %1\",
8727        \"cmp%d4\\t%2, %3\"},
8728       {\"cmn%d5\\t%0, #%n1\",
8729        \"cmp%d4\\t%2, %3\"},
8730       {\"cmp%d5\\t%0, %1\",
8731        \"cmn%d4\\t%2, #%n3\"},
8732       {\"cmn%d5\\t%0, #%n1\",
8733        \"cmn%d4\\t%2, #%n3\"}
8734     };
8735     static const char * const cmp2[NUM_OF_COND_CMP][2] =
8736     {
8737       {\"cmp\\t%2, %3\",
8738        \"cmp\\t%0, %1\"},
8739       {\"cmp\\t%2, %3\",
8740        \"cmn\\t%0, #%n1\"},
8741       {\"cmn\\t%2, #%n3\",
8742        \"cmp\\t%0, %1\"},
8743       {\"cmn\\t%2, #%n3\",
8744        \"cmn\\t%0, #%n1\"}
8745     };
8746     static const char * const ite[2] =
8747     {
8748       \"it\\t%d5\",
8749       \"it\\t%d4\"
8750     };
8751     static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
8752                                    CMP_CMP, CMN_CMP, CMP_CMP,
8753                                    CMN_CMP, CMP_CMN, CMN_CMN};
8754     int swap =
8755       comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
8757     output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
8758     if (TARGET_THUMB2) {
8759       output_asm_insn (ite[swap], operands);
8760     }
8761     output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
8762     return \"\";
8763   }"
8764   [(set_attr "conds" "set")
8765    (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
8766    (set_attr "type" "multiple")
8767    (set_attr_alternative "length"
8768       [(const_int 6)
8769        (const_int 8)
8770        (const_int 8)
8771        (const_int 8)
8772        (const_int 8)
8773        (if_then_else (eq_attr "is_thumb" "no")
8774            (const_int 8)
8775            (const_int 10))
8776        (if_then_else (eq_attr "is_thumb" "no")
8777            (const_int 8)
8778            (const_int 10))
8779        (if_then_else (eq_attr "is_thumb" "no")
8780            (const_int 8)
8781            (const_int 10))
8782        (if_then_else (eq_attr "is_thumb" "no")
8783            (const_int 8)
8784            (const_int 10))])]
8787 (define_insn "*cmp_ite1"
8788   [(set (match_operand 6 "dominant_cc_register" "")
8789         (compare
8790          (if_then_else:SI
8791           (match_operator 4 "arm_comparison_operator"
8792            [(match_operand:SI 0 "s_register_operand"
8793                 "l,l,l,r,r,r,r,r,r")
8794             (match_operand:SI 1 "arm_add_operand"
8795                 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
8796           (match_operator:SI 5 "arm_comparison_operator"
8797            [(match_operand:SI 2 "s_register_operand"
8798                 "l,r,r,l,l,r,r,r,r")
8799             (match_operand:SI 3 "arm_add_operand"
8800                 "lPy,rI,L,lPy,lPy,rI,rI,L,L")])
8801           (const_int 1))
8802          (const_int 0)))]
8803   "TARGET_32BIT"
8804   "*
8805   {
8806     static const char * const cmp1[NUM_OF_COND_CMP][2] =
8807     {
8808       {\"cmp\\t%0, %1\",
8809        \"cmp\\t%2, %3\"},
8810       {\"cmn\\t%0, #%n1\",
8811        \"cmp\\t%2, %3\"},
8812       {\"cmp\\t%0, %1\",
8813        \"cmn\\t%2, #%n3\"},
8814       {\"cmn\\t%0, #%n1\",
8815        \"cmn\\t%2, #%n3\"}
8816     };
8817     static const char * const cmp2[NUM_OF_COND_CMP][2] =
8818     {
8819       {\"cmp%d4\\t%2, %3\",
8820        \"cmp%D5\\t%0, %1\"},
8821       {\"cmp%d4\\t%2, %3\",
8822        \"cmn%D5\\t%0, #%n1\"},
8823       {\"cmn%d4\\t%2, #%n3\",
8824        \"cmp%D5\\t%0, %1\"},
8825       {\"cmn%d4\\t%2, #%n3\",
8826        \"cmn%D5\\t%0, #%n1\"}
8827     };
8828     static const char * const ite[2] =
8829     {
8830       \"it\\t%d4\",
8831       \"it\\t%D5\"
8832     };
8833     static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
8834                                    CMP_CMP, CMN_CMP, CMP_CMP,
8835                                    CMN_CMP, CMP_CMN, CMN_CMN};
8836     int swap =
8837       comparison_dominates_p (GET_CODE (operands[5]),
8838                               reverse_condition (GET_CODE (operands[4])));
8840     output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
8841     if (TARGET_THUMB2) {
8842       output_asm_insn (ite[swap], operands);
8843     }
8844     output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
8845     return \"\";
8846   }"
8847   [(set_attr "conds" "set")
8848    (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
8849    (set_attr_alternative "length"
8850       [(const_int 6)
8851        (const_int 8)
8852        (const_int 8)
8853        (const_int 8)
8854        (const_int 8)
8855        (if_then_else (eq_attr "is_thumb" "no")
8856            (const_int 8)
8857            (const_int 10))
8858        (if_then_else (eq_attr "is_thumb" "no")
8859            (const_int 8)
8860            (const_int 10))
8861        (if_then_else (eq_attr "is_thumb" "no")
8862            (const_int 8)
8863            (const_int 10))
8864        (if_then_else (eq_attr "is_thumb" "no")
8865            (const_int 8)
8866            (const_int 10))])
8867    (set_attr "type" "multiple")]
8870 (define_insn "*cmp_and"
8871   [(set (match_operand 6 "dominant_cc_register" "")
8872         (compare
8873          (and:SI
8874           (match_operator 4 "arm_comparison_operator"
8875            [(match_operand:SI 0 "s_register_operand" 
8876                 "l,l,l,r,r,r,r,r,r")
8877             (match_operand:SI 1 "arm_add_operand" 
8878                 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
8879           (match_operator:SI 5 "arm_comparison_operator"
8880            [(match_operand:SI 2 "s_register_operand" 
8881                 "l,r,r,l,l,r,r,r,r")
8882             (match_operand:SI 3 "arm_add_operand" 
8883                 "lPy,rI,L,lPy,lPy,rI,rI,L,L")]))
8884          (const_int 0)))]
8885   "TARGET_32BIT"
8886   "*
8887   {
8888     static const char *const cmp1[NUM_OF_COND_CMP][2] =
8889     {
8890       {\"cmp%d5\\t%0, %1\",
8891        \"cmp%d4\\t%2, %3\"},
8892       {\"cmn%d5\\t%0, #%n1\",
8893        \"cmp%d4\\t%2, %3\"},
8894       {\"cmp%d5\\t%0, %1\",
8895        \"cmn%d4\\t%2, #%n3\"},
8896       {\"cmn%d5\\t%0, #%n1\",
8897        \"cmn%d4\\t%2, #%n3\"}
8898     };
8899     static const char *const cmp2[NUM_OF_COND_CMP][2] =
8900     {
8901       {\"cmp\\t%2, %3\",
8902        \"cmp\\t%0, %1\"},
8903       {\"cmp\\t%2, %3\",
8904        \"cmn\\t%0, #%n1\"},
8905       {\"cmn\\t%2, #%n3\",
8906        \"cmp\\t%0, %1\"},
8907       {\"cmn\\t%2, #%n3\",
8908        \"cmn\\t%0, #%n1\"}
8909     };
8910     static const char *const ite[2] =
8911     {
8912       \"it\\t%d5\",
8913       \"it\\t%d4\"
8914     };
8915     static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
8916                                    CMP_CMP, CMN_CMP, CMP_CMP,
8917                                    CMN_CMP, CMP_CMN, CMN_CMN};
8918     int swap =
8919       comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
8921     output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
8922     if (TARGET_THUMB2) {
8923       output_asm_insn (ite[swap], operands);
8924     }
8925     output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
8926     return \"\";
8927   }"
8928   [(set_attr "conds" "set")
8929    (set_attr "predicable" "no")
8930    (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
8931    (set_attr_alternative "length"
8932       [(const_int 6)
8933        (const_int 8)
8934        (const_int 8)
8935        (const_int 8)
8936        (const_int 8)
8937        (if_then_else (eq_attr "is_thumb" "no")
8938            (const_int 8)
8939            (const_int 10))
8940        (if_then_else (eq_attr "is_thumb" "no")
8941            (const_int 8)
8942            (const_int 10))
8943        (if_then_else (eq_attr "is_thumb" "no")
8944            (const_int 8)
8945            (const_int 10))
8946        (if_then_else (eq_attr "is_thumb" "no")
8947            (const_int 8)
8948            (const_int 10))])
8949    (set_attr "type" "multiple")]
8952 (define_insn "*cmp_ior"
8953   [(set (match_operand 6 "dominant_cc_register" "")
8954         (compare
8955          (ior:SI
8956           (match_operator 4 "arm_comparison_operator"
8957            [(match_operand:SI 0 "s_register_operand"
8958                 "l,l,l,r,r,r,r,r,r")
8959             (match_operand:SI 1 "arm_add_operand"
8960                 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
8961           (match_operator:SI 5 "arm_comparison_operator"
8962            [(match_operand:SI 2 "s_register_operand"
8963                 "l,r,r,l,l,r,r,r,r")
8964             (match_operand:SI 3 "arm_add_operand"
8965                 "lPy,rI,L,lPy,lPy,rI,rI,L,L")]))
8966          (const_int 0)))]
8967   "TARGET_32BIT"
8968   "*
8969   {
8970     static const char *const cmp1[NUM_OF_COND_CMP][2] =
8971     {
8972       {\"cmp\\t%0, %1\",
8973        \"cmp\\t%2, %3\"},
8974       {\"cmn\\t%0, #%n1\",
8975        \"cmp\\t%2, %3\"},
8976       {\"cmp\\t%0, %1\",
8977        \"cmn\\t%2, #%n3\"},
8978       {\"cmn\\t%0, #%n1\",
8979        \"cmn\\t%2, #%n3\"}
8980     };
8981     static const char *const cmp2[NUM_OF_COND_CMP][2] =
8982     {
8983       {\"cmp%D4\\t%2, %3\",
8984        \"cmp%D5\\t%0, %1\"},
8985       {\"cmp%D4\\t%2, %3\",
8986        \"cmn%D5\\t%0, #%n1\"},
8987       {\"cmn%D4\\t%2, #%n3\",
8988        \"cmp%D5\\t%0, %1\"},
8989       {\"cmn%D4\\t%2, #%n3\",
8990        \"cmn%D5\\t%0, #%n1\"}
8991     };
8992     static const char *const ite[2] =
8993     {
8994       \"it\\t%D4\",
8995       \"it\\t%D5\"
8996     };
8997     static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
8998                                    CMP_CMP, CMN_CMP, CMP_CMP,
8999                                    CMN_CMP, CMP_CMN, CMN_CMN};
9000     int swap =
9001       comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
9003     output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
9004     if (TARGET_THUMB2) {
9005       output_asm_insn (ite[swap], operands);
9006     }
9007     output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
9008     return \"\";
9009   }
9010   "
9011   [(set_attr "conds" "set")
9012    (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
9013    (set_attr_alternative "length"
9014       [(const_int 6)
9015        (const_int 8)
9016        (const_int 8)
9017        (const_int 8)
9018        (const_int 8)
9019        (if_then_else (eq_attr "is_thumb" "no")
9020            (const_int 8)
9021            (const_int 10))
9022        (if_then_else (eq_attr "is_thumb" "no")
9023            (const_int 8)
9024            (const_int 10))
9025        (if_then_else (eq_attr "is_thumb" "no")
9026            (const_int 8)
9027            (const_int 10))
9028        (if_then_else (eq_attr "is_thumb" "no")
9029            (const_int 8)
9030            (const_int 10))])
9031    (set_attr "type" "multiple")]
9034 (define_insn_and_split "*ior_scc_scc"
9035   [(set (match_operand:SI 0 "s_register_operand" "=Ts")
9036         (ior:SI (match_operator:SI 3 "arm_comparison_operator"
9037                  [(match_operand:SI 1 "s_register_operand" "r")
9038                   (match_operand:SI 2 "arm_add_operand" "rIL")])
9039                 (match_operator:SI 6 "arm_comparison_operator"
9040                  [(match_operand:SI 4 "s_register_operand" "r")
9041                   (match_operand:SI 5 "arm_add_operand" "rIL")])))
9042    (clobber (reg:CC CC_REGNUM))]
9043   "TARGET_32BIT
9044    && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_OR_Y)
9045        != CCmode)"
9046   "#"
9047   "TARGET_32BIT && reload_completed"
9048   [(set (match_dup 7)
9049         (compare
9050          (ior:SI
9051           (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9052           (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9053          (const_int 0)))
9054    (set (match_dup 0) (ne:SI (match_dup 7) (const_int 0)))]
9055   "operands[7]
9056      = gen_rtx_REG (arm_select_dominance_cc_mode (operands[3], operands[6],
9057                                                   DOM_CC_X_OR_Y),
9058                     CC_REGNUM);"
9059   [(set_attr "conds" "clob")
9060    (set_attr "length" "16")
9061    (set_attr "type" "multiple")]
9064 ; If the above pattern is followed by a CMP insn, then the compare is 
9065 ; redundant, since we can rework the conditional instruction that follows.
9066 (define_insn_and_split "*ior_scc_scc_cmp"
9067   [(set (match_operand 0 "dominant_cc_register" "")
9068         (compare (ior:SI (match_operator:SI 3 "arm_comparison_operator"
9069                           [(match_operand:SI 1 "s_register_operand" "r")
9070                            (match_operand:SI 2 "arm_add_operand" "rIL")])
9071                          (match_operator:SI 6 "arm_comparison_operator"
9072                           [(match_operand:SI 4 "s_register_operand" "r")
9073                            (match_operand:SI 5 "arm_add_operand" "rIL")]))
9074                  (const_int 0)))
9075    (set (match_operand:SI 7 "s_register_operand" "=Ts")
9076         (ior:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9077                 (match_op_dup 6 [(match_dup 4) (match_dup 5)])))]
9078   "TARGET_32BIT"
9079   "#"
9080   "TARGET_32BIT && reload_completed"
9081   [(set (match_dup 0)
9082         (compare
9083          (ior:SI
9084           (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9085           (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9086          (const_int 0)))
9087    (set (match_dup 7) (ne:SI (match_dup 0) (const_int 0)))]
9088   ""
9089   [(set_attr "conds" "set")
9090    (set_attr "length" "16")
9091    (set_attr "type" "multiple")]
9094 (define_insn_and_split "*and_scc_scc"
9095   [(set (match_operand:SI 0 "s_register_operand" "=Ts")
9096         (and:SI (match_operator:SI 3 "arm_comparison_operator"
9097                  [(match_operand:SI 1 "s_register_operand" "r")
9098                   (match_operand:SI 2 "arm_add_operand" "rIL")])
9099                 (match_operator:SI 6 "arm_comparison_operator"
9100                  [(match_operand:SI 4 "s_register_operand" "r")
9101                   (match_operand:SI 5 "arm_add_operand" "rIL")])))
9102    (clobber (reg:CC CC_REGNUM))]
9103   "TARGET_32BIT
9104    && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
9105        != CCmode)"
9106   "#"
9107   "TARGET_32BIT && reload_completed
9108    && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
9109        != CCmode)"
9110   [(set (match_dup 7)
9111         (compare
9112          (and:SI
9113           (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9114           (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9115          (const_int 0)))
9116    (set (match_dup 0) (ne:SI (match_dup 7) (const_int 0)))]
9117   "operands[7]
9118      = gen_rtx_REG (arm_select_dominance_cc_mode (operands[3], operands[6],
9119                                                   DOM_CC_X_AND_Y),
9120                     CC_REGNUM);"
9121   [(set_attr "conds" "clob")
9122    (set_attr "length" "16")
9123    (set_attr "type" "multiple")]
9126 ; If the above pattern is followed by a CMP insn, then the compare is 
9127 ; redundant, since we can rework the conditional instruction that follows.
9128 (define_insn_and_split "*and_scc_scc_cmp"
9129   [(set (match_operand 0 "dominant_cc_register" "")
9130         (compare (and:SI (match_operator:SI 3 "arm_comparison_operator"
9131                           [(match_operand:SI 1 "s_register_operand" "r")
9132                            (match_operand:SI 2 "arm_add_operand" "rIL")])
9133                          (match_operator:SI 6 "arm_comparison_operator"
9134                           [(match_operand:SI 4 "s_register_operand" "r")
9135                            (match_operand:SI 5 "arm_add_operand" "rIL")]))
9136                  (const_int 0)))
9137    (set (match_operand:SI 7 "s_register_operand" "=Ts")
9138         (and:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9139                 (match_op_dup 6 [(match_dup 4) (match_dup 5)])))]
9140   "TARGET_32BIT"
9141   "#"
9142   "TARGET_32BIT && reload_completed"
9143   [(set (match_dup 0)
9144         (compare
9145          (and:SI
9146           (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9147           (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9148          (const_int 0)))
9149    (set (match_dup 7) (ne:SI (match_dup 0) (const_int 0)))]
9150   ""
9151   [(set_attr "conds" "set")
9152    (set_attr "length" "16")
9153    (set_attr "type" "multiple")]
9156 ;; If there is no dominance in the comparison, then we can still save an
9157 ;; instruction in the AND case, since we can know that the second compare
9158 ;; need only zero the value if false (if true, then the value is already
9159 ;; correct).
9160 (define_insn_and_split "*and_scc_scc_nodom"
9161   [(set (match_operand:SI 0 "s_register_operand" "=&Ts,&Ts,&Ts")
9162         (and:SI (match_operator:SI 3 "arm_comparison_operator"
9163                  [(match_operand:SI 1 "s_register_operand" "r,r,0")
9164                   (match_operand:SI 2 "arm_add_operand" "rIL,0,rIL")])
9165                 (match_operator:SI 6 "arm_comparison_operator"
9166                  [(match_operand:SI 4 "s_register_operand" "r,r,r")
9167                   (match_operand:SI 5 "arm_add_operand" "rIL,rIL,rIL")])))
9168    (clobber (reg:CC CC_REGNUM))]
9169   "TARGET_32BIT
9170    && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
9171        == CCmode)"
9172   "#"
9173   "TARGET_32BIT && reload_completed"
9174   [(parallel [(set (match_dup 0)
9175                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
9176               (clobber (reg:CC CC_REGNUM))])
9177    (set (match_dup 7) (match_op_dup 8 [(match_dup 4) (match_dup 5)]))
9178    (set (match_dup 0)
9179         (if_then_else:SI (match_op_dup 6 [(match_dup 7) (const_int 0)])
9180                          (match_dup 0)
9181                          (const_int 0)))]
9182   "operands[7] = gen_rtx_REG (SELECT_CC_MODE (GET_CODE (operands[6]),
9183                                               operands[4], operands[5]),
9184                               CC_REGNUM);
9185    operands[8] = gen_rtx_COMPARE (GET_MODE (operands[7]), operands[4],
9186                                   operands[5]);"
9187   [(set_attr "conds" "clob")
9188    (set_attr "length" "20")
9189    (set_attr "type" "multiple")]
9192 (define_split
9193   [(set (reg:CC_NOOV CC_REGNUM)
9194         (compare:CC_NOOV (ior:SI
9195                           (and:SI (match_operand:SI 0 "s_register_operand" "")
9196                                   (const_int 1))
9197                           (match_operator:SI 1 "arm_comparison_operator"
9198                            [(match_operand:SI 2 "s_register_operand" "")
9199                             (match_operand:SI 3 "arm_add_operand" "")]))
9200                          (const_int 0)))
9201    (clobber (match_operand:SI 4 "s_register_operand" ""))]
9202   "TARGET_ARM"
9203   [(set (match_dup 4)
9204         (ior:SI (match_op_dup 1 [(match_dup 2) (match_dup 3)])
9205                 (match_dup 0)))
9206    (set (reg:CC_NOOV CC_REGNUM)
9207         (compare:CC_NOOV (and:SI (match_dup 4) (const_int 1))
9208                          (const_int 0)))]
9209   "")
9211 (define_split
9212   [(set (reg:CC_NOOV CC_REGNUM)
9213         (compare:CC_NOOV (ior:SI
9214                           (match_operator:SI 1 "arm_comparison_operator"
9215                            [(match_operand:SI 2 "s_register_operand" "")
9216                             (match_operand:SI 3 "arm_add_operand" "")])
9217                           (and:SI (match_operand:SI 0 "s_register_operand" "")
9218                                   (const_int 1)))
9219                          (const_int 0)))
9220    (clobber (match_operand:SI 4 "s_register_operand" ""))]
9221   "TARGET_ARM"
9222   [(set (match_dup 4)
9223         (ior:SI (match_op_dup 1 [(match_dup 2) (match_dup 3)])
9224                 (match_dup 0)))
9225    (set (reg:CC_NOOV CC_REGNUM)
9226         (compare:CC_NOOV (and:SI (match_dup 4) (const_int 1))
9227                          (const_int 0)))]
9228   "")
9229 ;; ??? The conditional patterns above need checking for Thumb-2 usefulness
9231 (define_insn_and_split "*negscc"
9232   [(set (match_operand:SI 0 "s_register_operand" "=r")
9233         (neg:SI (match_operator 3 "arm_comparison_operator"
9234                  [(match_operand:SI 1 "s_register_operand" "r")
9235                   (match_operand:SI 2 "arm_rhs_operand" "rI")])))
9236    (clobber (reg:CC CC_REGNUM))]
9237   "TARGET_ARM"
9238   "#"
9239   "&& reload_completed"
9240   [(const_int 0)]
9241   {
9242     rtx cc_reg = gen_rtx_REG (CCmode, CC_REGNUM);
9244     if (GET_CODE (operands[3]) == LT && operands[2] == const0_rtx)
9245        {
9246          /* Emit mov\\t%0, %1, asr #31 */
9247          emit_insn (gen_rtx_SET (VOIDmode,
9248                                  operands[0],
9249                                  gen_rtx_ASHIFTRT (SImode,
9250                                                    operands[1],
9251                                                    GEN_INT (31))));
9252          DONE;
9253        }
9254      else if (GET_CODE (operands[3]) == NE)
9255        {
9256         /* Emit subs\\t%0, %1, %2\;mvnne\\t%0, #0 */
9257         if (CONST_INT_P (operands[2]))
9258           emit_insn (gen_cmpsi2_addneg (operands[0], operands[1], operands[2],
9259                                         GEN_INT (- INTVAL (operands[2]))));
9260         else
9261           emit_insn (gen_subsi3_compare (operands[0], operands[1], operands[2]));
9263         emit_insn (gen_rtx_COND_EXEC (VOIDmode,
9264                                       gen_rtx_NE (SImode,
9265                                                   cc_reg,
9266                                                   const0_rtx),
9267                                       gen_rtx_SET (SImode,
9268                                                    operands[0],
9269                                                    GEN_INT (~0))));
9270         DONE;
9271       }
9272     else
9273       {
9274         /* Emit: cmp\\t%1, %2\;mov%D3\\t%0, #0\;mvn%d3\\t%0, #0 */
9275         emit_insn (gen_rtx_SET (VOIDmode,
9276                                 cc_reg,
9277                                 gen_rtx_COMPARE (CCmode, operands[1], operands[2])));
9278         enum rtx_code rc = GET_CODE (operands[3]);
9280         rc = reverse_condition (rc);
9281         emit_insn (gen_rtx_COND_EXEC (VOIDmode,
9282                                       gen_rtx_fmt_ee (rc,
9283                                                       VOIDmode,
9284                                                       cc_reg,
9285                                                       const0_rtx),
9286                                       gen_rtx_SET (VOIDmode, operands[0], const0_rtx)));
9287         rc = GET_CODE (operands[3]);
9288         emit_insn (gen_rtx_COND_EXEC (VOIDmode,
9289                                       gen_rtx_fmt_ee (rc,
9290                                                       VOIDmode,
9291                                                       cc_reg,
9292                                                       const0_rtx),
9293                                       gen_rtx_SET (VOIDmode,
9294                                                    operands[0],
9295                                                    GEN_INT (~0))));
9296         DONE;
9297       }
9298      FAIL;
9299   }
9300   [(set_attr "conds" "clob")
9301    (set_attr "length" "12")
9302    (set_attr "type" "multiple")]
9305 (define_insn_and_split "movcond_addsi"
9306   [(set (match_operand:SI 0 "s_register_operand" "=r,l,r")
9307         (if_then_else:SI
9308          (match_operator 5 "comparison_operator"
9309           [(plus:SI (match_operand:SI 3 "s_register_operand" "r,r,r")
9310                     (match_operand:SI 4 "arm_add_operand" "rIL,rIL,rIL"))
9311             (const_int 0)])
9312          (match_operand:SI 1 "arm_rhs_operand" "rI,rPy,r")
9313          (match_operand:SI 2 "arm_rhs_operand" "rI,rPy,r")))
9314    (clobber (reg:CC CC_REGNUM))]
9315    "TARGET_32BIT"
9316    "#"
9317    "&& reload_completed"
9318   [(set (reg:CC_NOOV CC_REGNUM)
9319         (compare:CC_NOOV
9320          (plus:SI (match_dup 3)
9321                   (match_dup 4))
9322          (const_int 0)))
9323    (set (match_dup 0) (match_dup 1))
9324    (cond_exec (match_dup 6)
9325               (set (match_dup 0) (match_dup 2)))]
9326   "
9327   {
9328     enum machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[5]),
9329                                              operands[3], operands[4]);
9330     enum rtx_code rc = GET_CODE (operands[5]);
9331     operands[6] = gen_rtx_REG (mode, CC_REGNUM);
9332     gcc_assert (!(mode == CCFPmode || mode == CCFPEmode));
9333     if (REGNO (operands[2]) != REGNO (operands[0]))
9334       rc = reverse_condition (rc);
9335     else 
9336       {
9337         rtx tmp = operands[1];
9338         operands[1] = operands[2];
9339         operands[2] = tmp;
9340       }
9342     operands[6] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
9343   }
9344   "
9345   [(set_attr "conds" "clob")
9346    (set_attr "enabled_for_depr_it" "no,yes,yes")
9347    (set_attr "type" "multiple")]
9350 (define_insn "movcond"
9351   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9352         (if_then_else:SI
9353          (match_operator 5 "arm_comparison_operator"
9354           [(match_operand:SI 3 "s_register_operand" "r,r,r")
9355            (match_operand:SI 4 "arm_add_operand" "rIL,rIL,rIL")])
9356          (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
9357          (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
9358    (clobber (reg:CC CC_REGNUM))]
9359   "TARGET_ARM"
9360   "*
9361   if (GET_CODE (operands[5]) == LT
9362       && (operands[4] == const0_rtx))
9363     {
9364       if (which_alternative != 1 && REG_P (operands[1]))
9365         {
9366           if (operands[2] == const0_rtx)
9367             return \"and\\t%0, %1, %3, asr #31\";
9368           return \"ands\\t%0, %1, %3, asr #32\;movcc\\t%0, %2\";
9369         }
9370       else if (which_alternative != 0 && REG_P (operands[2]))
9371         {
9372           if (operands[1] == const0_rtx)
9373             return \"bic\\t%0, %2, %3, asr #31\";
9374           return \"bics\\t%0, %2, %3, asr #32\;movcs\\t%0, %1\";
9375         }
9376       /* The only case that falls through to here is when both ops 1 & 2
9377          are constants.  */
9378     }
9380   if (GET_CODE (operands[5]) == GE
9381       && (operands[4] == const0_rtx))
9382     {
9383       if (which_alternative != 1 && REG_P (operands[1]))
9384         {
9385           if (operands[2] == const0_rtx)
9386             return \"bic\\t%0, %1, %3, asr #31\";
9387           return \"bics\\t%0, %1, %3, asr #32\;movcs\\t%0, %2\";
9388         }
9389       else if (which_alternative != 0 && REG_P (operands[2]))
9390         {
9391           if (operands[1] == const0_rtx)
9392             return \"and\\t%0, %2, %3, asr #31\";
9393           return \"ands\\t%0, %2, %3, asr #32\;movcc\\t%0, %1\";
9394         }
9395       /* The only case that falls through to here is when both ops 1 & 2
9396          are constants.  */
9397     }
9398   if (CONST_INT_P (operands[4])
9399       && !const_ok_for_arm (INTVAL (operands[4])))
9400     output_asm_insn (\"cmn\\t%3, #%n4\", operands);
9401   else
9402     output_asm_insn (\"cmp\\t%3, %4\", operands);
9403   if (which_alternative != 0)
9404     output_asm_insn (\"mov%d5\\t%0, %1\", operands);
9405   if (which_alternative != 1)
9406     output_asm_insn (\"mov%D5\\t%0, %2\", operands);
9407   return \"\";
9408   "
9409   [(set_attr "conds" "clob")
9410    (set_attr "length" "8,8,12")
9411    (set_attr "type" "multiple")]
9414 ;; ??? The patterns below need checking for Thumb-2 usefulness.
9416 (define_insn "*ifcompare_plus_move"
9417   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9418         (if_then_else:SI (match_operator 6 "arm_comparison_operator"
9419                           [(match_operand:SI 4 "s_register_operand" "r,r")
9420                            (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
9421                          (plus:SI
9422                           (match_operand:SI 2 "s_register_operand" "r,r")
9423                           (match_operand:SI 3 "arm_add_operand" "rIL,rIL"))
9424                          (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))
9425    (clobber (reg:CC CC_REGNUM))]
9426   "TARGET_ARM"
9427   "#"
9428   [(set_attr "conds" "clob")
9429    (set_attr "length" "8,12")
9430    (set_attr "type" "multiple")]
9433 (define_insn "*if_plus_move"
9434   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
9435         (if_then_else:SI
9436          (match_operator 4 "arm_comparison_operator"
9437           [(match_operand 5 "cc_register" "") (const_int 0)])
9438          (plus:SI
9439           (match_operand:SI 2 "s_register_operand" "r,r,r,r")
9440           (match_operand:SI 3 "arm_add_operand" "rI,L,rI,L"))
9441          (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")))]
9442   "TARGET_ARM"
9443   "@
9444    add%d4\\t%0, %2, %3
9445    sub%d4\\t%0, %2, #%n3
9446    add%d4\\t%0, %2, %3\;mov%D4\\t%0, %1
9447    sub%d4\\t%0, %2, #%n3\;mov%D4\\t%0, %1"
9448   [(set_attr "conds" "use")
9449    (set_attr "length" "4,4,8,8")
9450    (set_attr_alternative "type"
9451                          [(if_then_else (match_operand 3 "const_int_operand" "")
9452                                         (const_string "alu_imm" )
9453                                         (const_string "alu_sreg"))
9454                           (const_string "alu_imm")
9455                           (const_string "alu_sreg")
9456                           (const_string "alu_sreg")])]
9459 (define_insn "*ifcompare_move_plus"
9460   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9461         (if_then_else:SI (match_operator 6 "arm_comparison_operator"
9462                           [(match_operand:SI 4 "s_register_operand" "r,r")
9463                            (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
9464                          (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
9465                          (plus:SI
9466                           (match_operand:SI 2 "s_register_operand" "r,r")
9467                           (match_operand:SI 3 "arm_add_operand" "rIL,rIL"))))
9468    (clobber (reg:CC CC_REGNUM))]
9469   "TARGET_ARM"
9470   "#"
9471   [(set_attr "conds" "clob")
9472    (set_attr "length" "8,12")
9473    (set_attr "type" "multiple")]
9476 (define_insn "*if_move_plus"
9477   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
9478         (if_then_else:SI
9479          (match_operator 4 "arm_comparison_operator"
9480           [(match_operand 5 "cc_register" "") (const_int 0)])
9481          (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")
9482          (plus:SI
9483           (match_operand:SI 2 "s_register_operand" "r,r,r,r")
9484           (match_operand:SI 3 "arm_add_operand" "rI,L,rI,L"))))]
9485   "TARGET_ARM"
9486   "@
9487    add%D4\\t%0, %2, %3
9488    sub%D4\\t%0, %2, #%n3
9489    add%D4\\t%0, %2, %3\;mov%d4\\t%0, %1
9490    sub%D4\\t%0, %2, #%n3\;mov%d4\\t%0, %1"
9491   [(set_attr "conds" "use")
9492    (set_attr "length" "4,4,8,8")
9493    (set_attr "type" "alu_sreg,alu_imm,multiple,multiple")]
9496 (define_insn "*ifcompare_arith_arith"
9497   [(set (match_operand:SI 0 "s_register_operand" "=r")
9498         (if_then_else:SI (match_operator 9 "arm_comparison_operator"
9499                           [(match_operand:SI 5 "s_register_operand" "r")
9500                            (match_operand:SI 6 "arm_add_operand" "rIL")])
9501                          (match_operator:SI 8 "shiftable_operator"
9502                           [(match_operand:SI 1 "s_register_operand" "r")
9503                            (match_operand:SI 2 "arm_rhs_operand" "rI")])
9504                          (match_operator:SI 7 "shiftable_operator"
9505                           [(match_operand:SI 3 "s_register_operand" "r")
9506                            (match_operand:SI 4 "arm_rhs_operand" "rI")])))
9507    (clobber (reg:CC CC_REGNUM))]
9508   "TARGET_ARM"
9509   "#"
9510   [(set_attr "conds" "clob")
9511    (set_attr "length" "12")
9512    (set_attr "type" "multiple")]
9515 (define_insn "*if_arith_arith"
9516   [(set (match_operand:SI 0 "s_register_operand" "=r")
9517         (if_then_else:SI (match_operator 5 "arm_comparison_operator"
9518                           [(match_operand 8 "cc_register" "") (const_int 0)])
9519                          (match_operator:SI 6 "shiftable_operator"
9520                           [(match_operand:SI 1 "s_register_operand" "r")
9521                            (match_operand:SI 2 "arm_rhs_operand" "rI")])
9522                          (match_operator:SI 7 "shiftable_operator"
9523                           [(match_operand:SI 3 "s_register_operand" "r")
9524                            (match_operand:SI 4 "arm_rhs_operand" "rI")])))]
9525   "TARGET_ARM"
9526   "%I6%d5\\t%0, %1, %2\;%I7%D5\\t%0, %3, %4"
9527   [(set_attr "conds" "use")
9528    (set_attr "length" "8")
9529    (set_attr "type" "multiple")]
9532 (define_insn "*ifcompare_arith_move"
9533   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9534         (if_then_else:SI (match_operator 6 "arm_comparison_operator"
9535                           [(match_operand:SI 2 "s_register_operand" "r,r")
9536                            (match_operand:SI 3 "arm_add_operand" "rIL,rIL")])
9537                          (match_operator:SI 7 "shiftable_operator"
9538                           [(match_operand:SI 4 "s_register_operand" "r,r")
9539                            (match_operand:SI 5 "arm_rhs_operand" "rI,rI")])
9540                          (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))
9541    (clobber (reg:CC CC_REGNUM))]
9542   "TARGET_ARM"
9543   "*
9544   /* If we have an operation where (op x 0) is the identity operation and
9545      the conditional operator is LT or GE and we are comparing against zero and
9546      everything is in registers then we can do this in two instructions.  */
9547   if (operands[3] == const0_rtx
9548       && GET_CODE (operands[7]) != AND
9549       && REG_P (operands[5])
9550       && REG_P (operands[1])
9551       && REGNO (operands[1]) == REGNO (operands[4])
9552       && REGNO (operands[4]) != REGNO (operands[0]))
9553     {
9554       if (GET_CODE (operands[6]) == LT)
9555         return \"and\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\";
9556       else if (GET_CODE (operands[6]) == GE)
9557         return \"bic\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\";
9558     }
9559   if (CONST_INT_P (operands[3])
9560       && !const_ok_for_arm (INTVAL (operands[3])))
9561     output_asm_insn (\"cmn\\t%2, #%n3\", operands);
9562   else
9563     output_asm_insn (\"cmp\\t%2, %3\", operands);
9564   output_asm_insn (\"%I7%d6\\t%0, %4, %5\", operands);
9565   if (which_alternative != 0)
9566     return \"mov%D6\\t%0, %1\";
9567   return \"\";
9568   "
9569   [(set_attr "conds" "clob")
9570    (set_attr "length" "8,12")
9571    (set_attr "type" "multiple")]
9574 (define_insn "*if_arith_move"
9575   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9576         (if_then_else:SI (match_operator 4 "arm_comparison_operator"
9577                           [(match_operand 6 "cc_register" "") (const_int 0)])
9578                          (match_operator:SI 5 "shiftable_operator"
9579                           [(match_operand:SI 2 "s_register_operand" "r,r")
9580                            (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
9581                          (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))]
9582   "TARGET_ARM"
9583   "@
9584    %I5%d4\\t%0, %2, %3
9585    %I5%d4\\t%0, %2, %3\;mov%D4\\t%0, %1"
9586   [(set_attr "conds" "use")
9587    (set_attr "length" "4,8")
9588    (set_attr "type" "alu_shift_reg,multiple")]
9591 (define_insn "*ifcompare_move_arith"
9592   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9593         (if_then_else:SI (match_operator 6 "arm_comparison_operator"
9594                           [(match_operand:SI 4 "s_register_operand" "r,r")
9595                            (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
9596                          (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
9597                          (match_operator:SI 7 "shiftable_operator"
9598                           [(match_operand:SI 2 "s_register_operand" "r,r")
9599                            (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
9600    (clobber (reg:CC CC_REGNUM))]
9601   "TARGET_ARM"
9602   "*
9603   /* If we have an operation where (op x 0) is the identity operation and
9604      the conditional operator is LT or GE and we are comparing against zero and
9605      everything is in registers then we can do this in two instructions */
9606   if (operands[5] == const0_rtx
9607       && GET_CODE (operands[7]) != AND
9608       && REG_P (operands[3])
9609       && REG_P (operands[1])
9610       && REGNO (operands[1]) == REGNO (operands[2])
9611       && REGNO (operands[2]) != REGNO (operands[0]))
9612     {
9613       if (GET_CODE (operands[6]) == GE)
9614         return \"and\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\";
9615       else if (GET_CODE (operands[6]) == LT)
9616         return \"bic\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\";
9617     }
9619   if (CONST_INT_P (operands[5])
9620       && !const_ok_for_arm (INTVAL (operands[5])))
9621     output_asm_insn (\"cmn\\t%4, #%n5\", operands);
9622   else
9623     output_asm_insn (\"cmp\\t%4, %5\", operands);
9625   if (which_alternative != 0)
9626     output_asm_insn (\"mov%d6\\t%0, %1\", operands);
9627   return \"%I7%D6\\t%0, %2, %3\";
9628   "
9629   [(set_attr "conds" "clob")
9630    (set_attr "length" "8,12")
9631    (set_attr "type" "multiple")]
9634 (define_insn "*if_move_arith"
9635   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9636         (if_then_else:SI
9637          (match_operator 4 "arm_comparison_operator"
9638           [(match_operand 6 "cc_register" "") (const_int 0)])
9639          (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
9640          (match_operator:SI 5 "shiftable_operator"
9641           [(match_operand:SI 2 "s_register_operand" "r,r")
9642            (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))]
9643   "TARGET_ARM"
9644   "@
9645    %I5%D4\\t%0, %2, %3
9646    %I5%D4\\t%0, %2, %3\;mov%d4\\t%0, %1"
9647   [(set_attr "conds" "use")
9648    (set_attr "length" "4,8")
9649    (set_attr "type" "alu_shift_reg,multiple")]
9652 (define_insn "*ifcompare_move_not"
9653   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9654         (if_then_else:SI
9655          (match_operator 5 "arm_comparison_operator"
9656           [(match_operand:SI 3 "s_register_operand" "r,r")
9657            (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
9658          (match_operand:SI 1 "arm_not_operand" "0,?rIK")
9659          (not:SI
9660           (match_operand:SI 2 "s_register_operand" "r,r"))))
9661    (clobber (reg:CC CC_REGNUM))]
9662   "TARGET_ARM"
9663   "#"
9664   [(set_attr "conds" "clob")
9665    (set_attr "length" "8,12")
9666    (set_attr "type" "multiple")]
9669 (define_insn "*if_move_not"
9670   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9671         (if_then_else:SI
9672          (match_operator 4 "arm_comparison_operator"
9673           [(match_operand 3 "cc_register" "") (const_int 0)])
9674          (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
9675          (not:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))))]
9676   "TARGET_ARM"
9677   "@
9678    mvn%D4\\t%0, %2
9679    mov%d4\\t%0, %1\;mvn%D4\\t%0, %2
9680    mvn%d4\\t%0, #%B1\;mvn%D4\\t%0, %2"
9681   [(set_attr "conds" "use")
9682    (set_attr "type" "mvn_reg")
9683    (set_attr "length" "4,8,8")
9684    (set_attr "type" "mvn_reg,multiple,multiple")]
9687 (define_insn "*ifcompare_not_move"
9688   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9689         (if_then_else:SI 
9690          (match_operator 5 "arm_comparison_operator"
9691           [(match_operand:SI 3 "s_register_operand" "r,r")
9692            (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
9693          (not:SI
9694           (match_operand:SI 2 "s_register_operand" "r,r"))
9695          (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
9696    (clobber (reg:CC CC_REGNUM))]
9697   "TARGET_ARM"
9698   "#"
9699   [(set_attr "conds" "clob")
9700    (set_attr "length" "8,12")
9701    (set_attr "type" "multiple")]
9704 (define_insn "*if_not_move"
9705   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9706         (if_then_else:SI
9707          (match_operator 4 "arm_comparison_operator"
9708           [(match_operand 3 "cc_register" "") (const_int 0)])
9709          (not:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))
9710          (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
9711   "TARGET_ARM"
9712   "@
9713    mvn%d4\\t%0, %2
9714    mov%D4\\t%0, %1\;mvn%d4\\t%0, %2
9715    mvn%D4\\t%0, #%B1\;mvn%d4\\t%0, %2"
9716   [(set_attr "conds" "use")
9717    (set_attr "type" "mvn_reg,multiple,multiple")
9718    (set_attr "length" "4,8,8")]
9721 (define_insn "*ifcompare_shift_move"
9722   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9723         (if_then_else:SI
9724          (match_operator 6 "arm_comparison_operator"
9725           [(match_operand:SI 4 "s_register_operand" "r,r")
9726            (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
9727          (match_operator:SI 7 "shift_operator"
9728           [(match_operand:SI 2 "s_register_operand" "r,r")
9729            (match_operand:SI 3 "arm_rhs_operand" "rM,rM")])
9730          (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
9731    (clobber (reg:CC CC_REGNUM))]
9732   "TARGET_ARM"
9733   "#"
9734   [(set_attr "conds" "clob")
9735    (set_attr "length" "8,12")
9736    (set_attr "type" "multiple")]
9739 (define_insn "*if_shift_move"
9740   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9741         (if_then_else:SI
9742          (match_operator 5 "arm_comparison_operator"
9743           [(match_operand 6 "cc_register" "") (const_int 0)])
9744          (match_operator:SI 4 "shift_operator"
9745           [(match_operand:SI 2 "s_register_operand" "r,r,r")
9746            (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM")])
9747          (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
9748   "TARGET_ARM"
9749   "@
9750    mov%d5\\t%0, %2%S4
9751    mov%D5\\t%0, %1\;mov%d5\\t%0, %2%S4
9752    mvn%D5\\t%0, #%B1\;mov%d5\\t%0, %2%S4"
9753   [(set_attr "conds" "use")
9754    (set_attr "shift" "2")
9755    (set_attr "length" "4,8,8")
9756    (set_attr "type" "mov_shift_reg,multiple,multiple")]
9759 (define_insn "*ifcompare_move_shift"
9760   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9761         (if_then_else:SI
9762          (match_operator 6 "arm_comparison_operator"
9763           [(match_operand:SI 4 "s_register_operand" "r,r")
9764            (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
9765          (match_operand:SI 1 "arm_not_operand" "0,?rIK")
9766          (match_operator:SI 7 "shift_operator"
9767           [(match_operand:SI 2 "s_register_operand" "r,r")
9768            (match_operand:SI 3 "arm_rhs_operand" "rM,rM")])))
9769    (clobber (reg:CC CC_REGNUM))]
9770   "TARGET_ARM"
9771   "#"
9772   [(set_attr "conds" "clob")
9773    (set_attr "length" "8,12")
9774    (set_attr "type" "multiple")]
9777 (define_insn "*if_move_shift"
9778   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9779         (if_then_else:SI
9780          (match_operator 5 "arm_comparison_operator"
9781           [(match_operand 6 "cc_register" "") (const_int 0)])
9782          (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
9783          (match_operator:SI 4 "shift_operator"
9784           [(match_operand:SI 2 "s_register_operand" "r,r,r")
9785            (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM")])))]
9786   "TARGET_ARM"
9787   "@
9788    mov%D5\\t%0, %2%S4
9789    mov%d5\\t%0, %1\;mov%D5\\t%0, %2%S4
9790    mvn%d5\\t%0, #%B1\;mov%D5\\t%0, %2%S4"
9791   [(set_attr "conds" "use")
9792    (set_attr "shift" "2")
9793    (set_attr "length" "4,8,8")
9794    (set_attr "type" "mov_shift_reg,multiple,multiple")]
9797 (define_insn "*ifcompare_shift_shift"
9798   [(set (match_operand:SI 0 "s_register_operand" "=r")
9799         (if_then_else:SI
9800          (match_operator 7 "arm_comparison_operator"
9801           [(match_operand:SI 5 "s_register_operand" "r")
9802            (match_operand:SI 6 "arm_add_operand" "rIL")])
9803          (match_operator:SI 8 "shift_operator"
9804           [(match_operand:SI 1 "s_register_operand" "r")
9805            (match_operand:SI 2 "arm_rhs_operand" "rM")])
9806          (match_operator:SI 9 "shift_operator"
9807           [(match_operand:SI 3 "s_register_operand" "r")
9808            (match_operand:SI 4 "arm_rhs_operand" "rM")])))
9809    (clobber (reg:CC CC_REGNUM))]
9810   "TARGET_ARM"
9811   "#"
9812   [(set_attr "conds" "clob")
9813    (set_attr "length" "12")
9814    (set_attr "type" "multiple")]
9817 (define_insn "*if_shift_shift"
9818   [(set (match_operand:SI 0 "s_register_operand" "=r")
9819         (if_then_else:SI
9820          (match_operator 5 "arm_comparison_operator"
9821           [(match_operand 8 "cc_register" "") (const_int 0)])
9822          (match_operator:SI 6 "shift_operator"
9823           [(match_operand:SI 1 "s_register_operand" "r")
9824            (match_operand:SI 2 "arm_rhs_operand" "rM")])
9825          (match_operator:SI 7 "shift_operator"
9826           [(match_operand:SI 3 "s_register_operand" "r")
9827            (match_operand:SI 4 "arm_rhs_operand" "rM")])))]
9828   "TARGET_ARM"
9829   "mov%d5\\t%0, %1%S6\;mov%D5\\t%0, %3%S7"
9830   [(set_attr "conds" "use")
9831    (set_attr "shift" "1")
9832    (set_attr "length" "8")
9833    (set (attr "type") (if_then_else
9834                         (and (match_operand 2 "const_int_operand" "")
9835                              (match_operand 4 "const_int_operand" ""))
9836                       (const_string "mov_shift")
9837                       (const_string "mov_shift_reg")))]
9840 (define_insn "*ifcompare_not_arith"
9841   [(set (match_operand:SI 0 "s_register_operand" "=r")
9842         (if_then_else:SI
9843          (match_operator 6 "arm_comparison_operator"
9844           [(match_operand:SI 4 "s_register_operand" "r")
9845            (match_operand:SI 5 "arm_add_operand" "rIL")])
9846          (not:SI (match_operand:SI 1 "s_register_operand" "r"))
9847          (match_operator:SI 7 "shiftable_operator"
9848           [(match_operand:SI 2 "s_register_operand" "r")
9849            (match_operand:SI 3 "arm_rhs_operand" "rI")])))
9850    (clobber (reg:CC CC_REGNUM))]
9851   "TARGET_ARM"
9852   "#"
9853   [(set_attr "conds" "clob")
9854    (set_attr "length" "12")
9855    (set_attr "type" "multiple")]
9858 (define_insn "*if_not_arith"
9859   [(set (match_operand:SI 0 "s_register_operand" "=r")
9860         (if_then_else:SI
9861          (match_operator 5 "arm_comparison_operator"
9862           [(match_operand 4 "cc_register" "") (const_int 0)])
9863          (not:SI (match_operand:SI 1 "s_register_operand" "r"))
9864          (match_operator:SI 6 "shiftable_operator"
9865           [(match_operand:SI 2 "s_register_operand" "r")
9866            (match_operand:SI 3 "arm_rhs_operand" "rI")])))]
9867   "TARGET_ARM"
9868   "mvn%d5\\t%0, %1\;%I6%D5\\t%0, %2, %3"
9869   [(set_attr "conds" "use")
9870    (set_attr "type" "mvn_reg")
9871    (set_attr "length" "8")]
9874 (define_insn "*ifcompare_arith_not"
9875   [(set (match_operand:SI 0 "s_register_operand" "=r")
9876         (if_then_else:SI
9877          (match_operator 6 "arm_comparison_operator"
9878           [(match_operand:SI 4 "s_register_operand" "r")
9879            (match_operand:SI 5 "arm_add_operand" "rIL")])
9880          (match_operator:SI 7 "shiftable_operator"
9881           [(match_operand:SI 2 "s_register_operand" "r")
9882            (match_operand:SI 3 "arm_rhs_operand" "rI")])
9883          (not:SI (match_operand:SI 1 "s_register_operand" "r"))))
9884    (clobber (reg:CC CC_REGNUM))]
9885   "TARGET_ARM"
9886   "#"
9887   [(set_attr "conds" "clob")
9888    (set_attr "length" "12")
9889    (set_attr "type" "multiple")]
9892 (define_insn "*if_arith_not"
9893   [(set (match_operand:SI 0 "s_register_operand" "=r")
9894         (if_then_else:SI
9895          (match_operator 5 "arm_comparison_operator"
9896           [(match_operand 4 "cc_register" "") (const_int 0)])
9897          (match_operator:SI 6 "shiftable_operator"
9898           [(match_operand:SI 2 "s_register_operand" "r")
9899            (match_operand:SI 3 "arm_rhs_operand" "rI")])
9900          (not:SI (match_operand:SI 1 "s_register_operand" "r"))))]
9901   "TARGET_ARM"
9902   "mvn%D5\\t%0, %1\;%I6%d5\\t%0, %2, %3"
9903   [(set_attr "conds" "use")
9904    (set_attr "type" "multiple")
9905    (set_attr "length" "8")]
9908 (define_insn "*ifcompare_neg_move"
9909   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9910         (if_then_else:SI
9911          (match_operator 5 "arm_comparison_operator"
9912           [(match_operand:SI 3 "s_register_operand" "r,r")
9913            (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
9914          (neg:SI (match_operand:SI 2 "s_register_operand" "r,r"))
9915          (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
9916    (clobber (reg:CC CC_REGNUM))]
9917   "TARGET_ARM"
9918   "#"
9919   [(set_attr "conds" "clob")
9920    (set_attr "length" "8,12")
9921    (set_attr "type" "multiple")]
9924 (define_insn "*if_neg_move"
9925   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9926         (if_then_else:SI
9927          (match_operator 4 "arm_comparison_operator"
9928           [(match_operand 3 "cc_register" "") (const_int 0)])
9929          (neg:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))
9930          (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
9931   "TARGET_ARM"
9932   "@
9933    rsb%d4\\t%0, %2, #0
9934    mov%D4\\t%0, %1\;rsb%d4\\t%0, %2, #0
9935    mvn%D4\\t%0, #%B1\;rsb%d4\\t%0, %2, #0"
9936   [(set_attr "conds" "use")
9937    (set_attr "length" "4,8,8")
9938    (set_attr "type" "logic_shift_imm,multiple,multiple")]
9941 (define_insn "*ifcompare_move_neg"
9942   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9943         (if_then_else:SI
9944          (match_operator 5 "arm_comparison_operator"
9945           [(match_operand:SI 3 "s_register_operand" "r,r")
9946            (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
9947          (match_operand:SI 1 "arm_not_operand" "0,?rIK")
9948          (neg:SI (match_operand:SI 2 "s_register_operand" "r,r"))))
9949    (clobber (reg:CC CC_REGNUM))]
9950   "TARGET_ARM"
9951   "#"
9952   [(set_attr "conds" "clob")
9953    (set_attr "length" "8,12")
9954    (set_attr "type" "multiple")]
9957 (define_insn "*if_move_neg"
9958   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9959         (if_then_else:SI
9960          (match_operator 4 "arm_comparison_operator"
9961           [(match_operand 3 "cc_register" "") (const_int 0)])
9962          (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
9963          (neg:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))))]
9964   "TARGET_ARM"
9965   "@
9966    rsb%D4\\t%0, %2, #0
9967    mov%d4\\t%0, %1\;rsb%D4\\t%0, %2, #0
9968    mvn%d4\\t%0, #%B1\;rsb%D4\\t%0, %2, #0"
9969   [(set_attr "conds" "use")
9970    (set_attr "length" "4,8,8")
9971    (set_attr "type" "logic_shift_imm,multiple,multiple")]
9974 (define_insn "*arith_adjacentmem"
9975   [(set (match_operand:SI 0 "s_register_operand" "=r")
9976         (match_operator:SI 1 "shiftable_operator"
9977          [(match_operand:SI 2 "memory_operand" "m")
9978           (match_operand:SI 3 "memory_operand" "m")]))
9979    (clobber (match_scratch:SI 4 "=r"))]
9980   "TARGET_ARM && adjacent_mem_locations (operands[2], operands[3])"
9981   "*
9982   {
9983     rtx ldm[3];
9984     rtx arith[4];
9985     rtx base_reg;
9986     HOST_WIDE_INT val1 = 0, val2 = 0;
9988     if (REGNO (operands[0]) > REGNO (operands[4]))
9989       {
9990         ldm[1] = operands[4];
9991         ldm[2] = operands[0];
9992       }
9993     else
9994       {
9995         ldm[1] = operands[0];
9996         ldm[2] = operands[4];
9997       }
9999     base_reg = XEXP (operands[2], 0);
10001     if (!REG_P (base_reg))
10002       {
10003         val1 = INTVAL (XEXP (base_reg, 1));
10004         base_reg = XEXP (base_reg, 0);
10005       }
10007     if (!REG_P (XEXP (operands[3], 0)))
10008       val2 = INTVAL (XEXP (XEXP (operands[3], 0), 1));
10010     arith[0] = operands[0];
10011     arith[3] = operands[1];
10013     if (val1 < val2)
10014       {
10015         arith[1] = ldm[1];
10016         arith[2] = ldm[2];
10017       }
10018     else
10019       {
10020         arith[1] = ldm[2];
10021         arith[2] = ldm[1];
10022       }
10024     ldm[0] = base_reg;
10025     if (val1 !=0 && val2 != 0)
10026       {
10027         rtx ops[3];
10029         if (val1 == 4 || val2 == 4)
10030           /* Other val must be 8, since we know they are adjacent and neither
10031              is zero.  */
10032           output_asm_insn (\"ldm%(ib%)\\t%0, {%1, %2}\", ldm);
10033         else if (const_ok_for_arm (val1) || const_ok_for_arm (-val1))
10034           {
10035             ldm[0] = ops[0] = operands[4];
10036             ops[1] = base_reg;
10037             ops[2] = GEN_INT (val1);
10038             output_add_immediate (ops);
10039             if (val1 < val2)
10040               output_asm_insn (\"ldm%(ia%)\\t%0, {%1, %2}\", ldm);
10041             else
10042               output_asm_insn (\"ldm%(da%)\\t%0, {%1, %2}\", ldm);
10043           }
10044         else
10045           {
10046             /* Offset is out of range for a single add, so use two ldr.  */
10047             ops[0] = ldm[1];
10048             ops[1] = base_reg;
10049             ops[2] = GEN_INT (val1);
10050             output_asm_insn (\"ldr%?\\t%0, [%1, %2]\", ops);
10051             ops[0] = ldm[2];
10052             ops[2] = GEN_INT (val2);
10053             output_asm_insn (\"ldr%?\\t%0, [%1, %2]\", ops);
10054           }
10055       }
10056     else if (val1 != 0)
10057       {
10058         if (val1 < val2)
10059           output_asm_insn (\"ldm%(da%)\\t%0, {%1, %2}\", ldm);
10060         else
10061           output_asm_insn (\"ldm%(ia%)\\t%0, {%1, %2}\", ldm);
10062       }
10063     else
10064       {
10065         if (val1 < val2)
10066           output_asm_insn (\"ldm%(ia%)\\t%0, {%1, %2}\", ldm);
10067         else
10068           output_asm_insn (\"ldm%(da%)\\t%0, {%1, %2}\", ldm);
10069       }
10070     output_asm_insn (\"%I3%?\\t%0, %1, %2\", arith);
10071     return \"\";
10072   }"
10073   [(set_attr "length" "12")
10074    (set_attr "predicable" "yes")
10075    (set_attr "type" "load1")]
10078 ; This pattern is never tried by combine, so do it as a peephole
10080 (define_peephole2
10081   [(set (match_operand:SI 0 "arm_general_register_operand" "")
10082         (match_operand:SI 1 "arm_general_register_operand" ""))
10083    (set (reg:CC CC_REGNUM)
10084         (compare:CC (match_dup 1) (const_int 0)))]
10085   "TARGET_ARM"
10086   [(parallel [(set (reg:CC CC_REGNUM) (compare:CC (match_dup 1) (const_int 0)))
10087               (set (match_dup 0) (match_dup 1))])]
10088   ""
10091 (define_split
10092   [(set (match_operand:SI 0 "s_register_operand" "")
10093         (and:SI (ge:SI (match_operand:SI 1 "s_register_operand" "")
10094                        (const_int 0))
10095                 (neg:SI (match_operator:SI 2 "arm_comparison_operator"
10096                          [(match_operand:SI 3 "s_register_operand" "")
10097                           (match_operand:SI 4 "arm_rhs_operand" "")]))))
10098    (clobber (match_operand:SI 5 "s_register_operand" ""))]
10099   "TARGET_ARM"
10100   [(set (match_dup 5) (not:SI (ashiftrt:SI (match_dup 1) (const_int 31))))
10101    (set (match_dup 0) (and:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
10102                               (match_dup 5)))]
10103   ""
10106 ;; This split can be used because CC_Z mode implies that the following
10107 ;; branch will be an equality, or an unsigned inequality, so the sign
10108 ;; extension is not needed.
10110 (define_split
10111   [(set (reg:CC_Z CC_REGNUM)
10112         (compare:CC_Z
10113          (ashift:SI (subreg:SI (match_operand:QI 0 "memory_operand" "") 0)
10114                     (const_int 24))
10115          (match_operand 1 "const_int_operand" "")))
10116    (clobber (match_scratch:SI 2 ""))]
10117   "TARGET_ARM
10118    && (((unsigned HOST_WIDE_INT) INTVAL (operands[1]))
10119        == (((unsigned HOST_WIDE_INT) INTVAL (operands[1])) >> 24) << 24)"
10120   [(set (match_dup 2) (zero_extend:SI (match_dup 0)))
10121    (set (reg:CC CC_REGNUM) (compare:CC (match_dup 2) (match_dup 1)))]
10122   "
10123   operands[1] = GEN_INT (((unsigned long) INTVAL (operands[1])) >> 24);
10124   "
10126 ;; ??? Check the patterns above for Thumb-2 usefulness
10128 (define_expand "prologue"
10129   [(clobber (const_int 0))]
10130   "TARGET_EITHER"
10131   "if (TARGET_32BIT)
10132      arm_expand_prologue ();
10133    else
10134      thumb1_expand_prologue ();
10135   DONE;
10136   "
10139 (define_expand "epilogue"
10140   [(clobber (const_int 0))]
10141   "TARGET_EITHER"
10142   "
10143   if (crtl->calls_eh_return)
10144     emit_insn (gen_force_register_use (gen_rtx_REG (Pmode, 2)));
10145   if (TARGET_THUMB1)
10146    {
10147      thumb1_expand_epilogue ();
10148      emit_jump_insn (gen_rtx_UNSPEC_VOLATILE (VOIDmode,
10149                      gen_rtvec (1, ret_rtx), VUNSPEC_EPILOGUE));
10150    }
10151   else if (HAVE_return)
10152    {
10153      /* HAVE_return is testing for USE_RETURN_INSN (FALSE).  Hence,
10154         no need for explicit testing again.  */
10155      emit_jump_insn (gen_return ());
10156    }
10157   else if (TARGET_32BIT)
10158    {
10159     arm_expand_epilogue (true);
10160    }
10161   DONE;
10162   "
10165 ;; Note - although unspec_volatile's USE all hard registers,
10166 ;; USEs are ignored after relaod has completed.  Thus we need
10167 ;; to add an unspec of the link register to ensure that flow
10168 ;; does not think that it is unused by the sibcall branch that
10169 ;; will replace the standard function epilogue.
10170 (define_expand "sibcall_epilogue"
10171    [(parallel [(unspec:SI [(reg:SI LR_REGNUM)] UNSPEC_REGISTER_USE)
10172                (unspec_volatile [(return)] VUNSPEC_EPILOGUE)])]
10173    "TARGET_32BIT"
10174    "
10175    arm_expand_epilogue (false);
10176    DONE;
10177    "
10180 (define_expand "eh_epilogue"
10181   [(use (match_operand:SI 0 "register_operand" ""))
10182    (use (match_operand:SI 1 "register_operand" ""))
10183    (use (match_operand:SI 2 "register_operand" ""))]
10184   "TARGET_EITHER"
10185   "
10186   {
10187     cfun->machine->eh_epilogue_sp_ofs = operands[1];
10188     if (!REG_P (operands[2]) || REGNO (operands[2]) != 2)
10189       {
10190         rtx ra = gen_rtx_REG (Pmode, 2);
10192         emit_move_insn (ra, operands[2]);
10193         operands[2] = ra;
10194       }
10195     /* This is a hack -- we may have crystalized the function type too
10196        early.  */
10197     cfun->machine->func_type = 0;
10198   }"
10201 ;; This split is only used during output to reduce the number of patterns
10202 ;; that need assembler instructions adding to them.  We allowed the setting
10203 ;; of the conditions to be implicit during rtl generation so that
10204 ;; the conditional compare patterns would work.  However this conflicts to
10205 ;; some extent with the conditional data operations, so we have to split them
10206 ;; up again here.
10208 ;; ??? Need to audit these splitters for Thumb-2.  Why isn't normal
10209 ;; conditional execution sufficient?
10211 (define_split
10212   [(set (match_operand:SI 0 "s_register_operand" "")
10213         (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10214                           [(match_operand 2 "" "") (match_operand 3 "" "")])
10215                          (match_dup 0)
10216                          (match_operand 4 "" "")))
10217    (clobber (reg:CC CC_REGNUM))]
10218   "TARGET_ARM && reload_completed"
10219   [(set (match_dup 5) (match_dup 6))
10220    (cond_exec (match_dup 7)
10221               (set (match_dup 0) (match_dup 4)))]
10222   "
10223   {
10224     enum machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10225                                              operands[2], operands[3]);
10226     enum rtx_code rc = GET_CODE (operands[1]);
10228     operands[5] = gen_rtx_REG (mode, CC_REGNUM);
10229     operands[6] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10230     if (mode == CCFPmode || mode == CCFPEmode)
10231       rc = reverse_condition_maybe_unordered (rc);
10232     else
10233       rc = reverse_condition (rc);
10235     operands[7] = gen_rtx_fmt_ee (rc, VOIDmode, operands[5], const0_rtx);
10236   }"
10239 (define_split
10240   [(set (match_operand:SI 0 "s_register_operand" "")
10241         (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10242                           [(match_operand 2 "" "") (match_operand 3 "" "")])
10243                          (match_operand 4 "" "")
10244                          (match_dup 0)))
10245    (clobber (reg:CC CC_REGNUM))]
10246   "TARGET_ARM && reload_completed"
10247   [(set (match_dup 5) (match_dup 6))
10248    (cond_exec (match_op_dup 1 [(match_dup 5) (const_int 0)])
10249               (set (match_dup 0) (match_dup 4)))]
10250   "
10251   {
10252     enum machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10253                                              operands[2], operands[3]);
10255     operands[5] = gen_rtx_REG (mode, CC_REGNUM);
10256     operands[6] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10257   }"
10260 (define_split
10261   [(set (match_operand:SI 0 "s_register_operand" "")
10262         (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10263                           [(match_operand 2 "" "") (match_operand 3 "" "")])
10264                          (match_operand 4 "" "")
10265                          (match_operand 5 "" "")))
10266    (clobber (reg:CC CC_REGNUM))]
10267   "TARGET_ARM && reload_completed"
10268   [(set (match_dup 6) (match_dup 7))
10269    (cond_exec (match_op_dup 1 [(match_dup 6) (const_int 0)])
10270               (set (match_dup 0) (match_dup 4)))
10271    (cond_exec (match_dup 8)
10272               (set (match_dup 0) (match_dup 5)))]
10273   "
10274   {
10275     enum machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10276                                              operands[2], operands[3]);
10277     enum rtx_code rc = GET_CODE (operands[1]);
10279     operands[6] = gen_rtx_REG (mode, CC_REGNUM);
10280     operands[7] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10281     if (mode == CCFPmode || mode == CCFPEmode)
10282       rc = reverse_condition_maybe_unordered (rc);
10283     else
10284       rc = reverse_condition (rc);
10286     operands[8] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
10287   }"
10290 (define_split
10291   [(set (match_operand:SI 0 "s_register_operand" "")
10292         (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10293                           [(match_operand:SI 2 "s_register_operand" "")
10294                            (match_operand:SI 3 "arm_add_operand" "")])
10295                          (match_operand:SI 4 "arm_rhs_operand" "")
10296                          (not:SI
10297                           (match_operand:SI 5 "s_register_operand" ""))))
10298    (clobber (reg:CC CC_REGNUM))]
10299   "TARGET_ARM && reload_completed"
10300   [(set (match_dup 6) (match_dup 7))
10301    (cond_exec (match_op_dup 1 [(match_dup 6) (const_int 0)])
10302               (set (match_dup 0) (match_dup 4)))
10303    (cond_exec (match_dup 8)
10304               (set (match_dup 0) (not:SI (match_dup 5))))]
10305   "
10306   {
10307     enum machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10308                                              operands[2], operands[3]);
10309     enum rtx_code rc = GET_CODE (operands[1]);
10311     operands[6] = gen_rtx_REG (mode, CC_REGNUM);
10312     operands[7] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10313     if (mode == CCFPmode || mode == CCFPEmode)
10314       rc = reverse_condition_maybe_unordered (rc);
10315     else
10316       rc = reverse_condition (rc);
10318     operands[8] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
10319   }"
10322 (define_insn "*cond_move_not"
10323   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10324         (if_then_else:SI (match_operator 4 "arm_comparison_operator"
10325                           [(match_operand 3 "cc_register" "") (const_int 0)])
10326                          (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
10327                          (not:SI
10328                           (match_operand:SI 2 "s_register_operand" "r,r"))))]
10329   "TARGET_ARM"
10330   "@
10331    mvn%D4\\t%0, %2
10332    mov%d4\\t%0, %1\;mvn%D4\\t%0, %2"
10333   [(set_attr "conds" "use")
10334    (set_attr "type" "mvn_reg,multiple")
10335    (set_attr "length" "4,8")]
10338 ;; The next two patterns occur when an AND operation is followed by a
10339 ;; scc insn sequence 
10341 (define_insn "*sign_extract_onebit"
10342   [(set (match_operand:SI 0 "s_register_operand" "=r")
10343         (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
10344                          (const_int 1)
10345                          (match_operand:SI 2 "const_int_operand" "n")))
10346     (clobber (reg:CC CC_REGNUM))]
10347   "TARGET_ARM"
10348   "*
10349     operands[2] = GEN_INT (1 << INTVAL (operands[2]));
10350     output_asm_insn (\"ands\\t%0, %1, %2\", operands);
10351     return \"mvnne\\t%0, #0\";
10352   "
10353   [(set_attr "conds" "clob")
10354    (set_attr "length" "8")
10355    (set_attr "type" "multiple")]
10358 (define_insn "*not_signextract_onebit"
10359   [(set (match_operand:SI 0 "s_register_operand" "=r")
10360         (not:SI
10361          (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
10362                           (const_int 1)
10363                           (match_operand:SI 2 "const_int_operand" "n"))))
10364    (clobber (reg:CC CC_REGNUM))]
10365   "TARGET_ARM"
10366   "*
10367     operands[2] = GEN_INT (1 << INTVAL (operands[2]));
10368     output_asm_insn (\"tst\\t%1, %2\", operands);
10369     output_asm_insn (\"mvneq\\t%0, #0\", operands);
10370     return \"movne\\t%0, #0\";
10371   "
10372   [(set_attr "conds" "clob")
10373    (set_attr "length" "12")
10374    (set_attr "type" "multiple")]
10376 ;; ??? The above patterns need auditing for Thumb-2
10378 ;; Push multiple registers to the stack.  Registers are in parallel (use ...)
10379 ;; expressions.  For simplicity, the first register is also in the unspec
10380 ;; part.
10381 ;; To avoid the usage of GNU extension, the length attribute is computed
10382 ;; in a C function arm_attr_length_push_multi.
10383 (define_insn "*push_multi"
10384   [(match_parallel 2 "multi_register_push"
10385     [(set (match_operand:BLK 0 "push_mult_memory_operand" "")
10386           (unspec:BLK [(match_operand:SI 1 "s_register_operand" "")]
10387                       UNSPEC_PUSH_MULT))])]
10388   ""
10389   "*
10390   {
10391     int num_saves = XVECLEN (operands[2], 0);
10392      
10393     /* For the StrongARM at least it is faster to
10394        use STR to store only a single register.
10395        In Thumb mode always use push, and the assembler will pick
10396        something appropriate.  */
10397     if (num_saves == 1 && TARGET_ARM)
10398       output_asm_insn (\"str%?\\t%1, [%m0, #-4]!\", operands);
10399     else
10400       {
10401         int i;
10402         char pattern[100];
10404         if (TARGET_ARM)
10405             strcpy (pattern, \"stm%(fd%)\\t%m0!, {%1\");
10406         else if (TARGET_THUMB2)
10407             strcpy (pattern, \"push%?\\t{%1\");
10408         else
10409             strcpy (pattern, \"push\\t{%1\");
10411         for (i = 1; i < num_saves; i++)
10412           {
10413             strcat (pattern, \", %|\");
10414             strcat (pattern,
10415                     reg_names[REGNO (XEXP (XVECEXP (operands[2], 0, i), 0))]);
10416           }
10418         strcat (pattern, \"}\");
10419         output_asm_insn (pattern, operands);
10420       }
10422     return \"\";
10423   }"
10424   [(set_attr "type" "store4")
10425    (set (attr "length")
10426         (symbol_ref "arm_attr_length_push_multi (operands[2], operands[1])"))]
10429 (define_insn "stack_tie"
10430   [(set (mem:BLK (scratch))
10431         (unspec:BLK [(match_operand:SI 0 "s_register_operand" "rk")
10432                      (match_operand:SI 1 "s_register_operand" "rk")]
10433                     UNSPEC_PRLG_STK))]
10434   ""
10435   ""
10436   [(set_attr "length" "0")
10437    (set_attr "type" "block")]
10440 ;; Pop (as used in epilogue RTL)
10442 (define_insn "*load_multiple_with_writeback"
10443   [(match_parallel 0 "load_multiple_operation"
10444     [(set (match_operand:SI 1 "s_register_operand" "+rk")
10445           (plus:SI (match_dup 1)
10446                    (match_operand:SI 2 "const_int_I_operand" "I")))
10447      (set (match_operand:SI 3 "s_register_operand" "=rk")
10448           (mem:SI (match_dup 1)))
10449         ])]
10450   "TARGET_32BIT && (reload_in_progress || reload_completed)"
10451   "*
10452   {
10453     arm_output_multireg_pop (operands, /*return_pc=*/false,
10454                                        /*cond=*/const_true_rtx,
10455                                        /*reverse=*/false,
10456                                        /*update=*/true);
10457     return \"\";
10458   }
10459   "
10460   [(set_attr "type" "load4")
10461    (set_attr "predicable" "yes")]
10464 ;; Pop with return (as used in epilogue RTL)
10466 ;; This instruction is generated when the registers are popped at the end of
10467 ;; epilogue.  Here, instead of popping the value into LR and then generating
10468 ;; jump to LR, value is popped into PC directly.  Hence, the pattern is combined
10469 ;;  with (return).
10470 (define_insn "*pop_multiple_with_writeback_and_return"
10471   [(match_parallel 0 "pop_multiple_return"
10472     [(return)
10473      (set (match_operand:SI 1 "s_register_operand" "+rk")
10474           (plus:SI (match_dup 1)
10475                    (match_operand:SI 2 "const_int_I_operand" "I")))
10476      (set (match_operand:SI 3 "s_register_operand" "=rk")
10477           (mem:SI (match_dup 1)))
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=*/true);
10486     return \"\";
10487   }
10488   "
10489   [(set_attr "type" "load4")
10490    (set_attr "predicable" "yes")]
10493 (define_insn "*pop_multiple_with_return"
10494   [(match_parallel 0 "pop_multiple_return"
10495     [(return)
10496      (set (match_operand:SI 2 "s_register_operand" "=rk")
10497           (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
10498         ])]
10499   "TARGET_32BIT && (reload_in_progress || reload_completed)"
10500   "*
10501   {
10502     arm_output_multireg_pop (operands, /*return_pc=*/true,
10503                                        /*cond=*/const_true_rtx,
10504                                        /*reverse=*/false,
10505                                        /*update=*/false);
10506     return \"\";
10507   }
10508   "
10509   [(set_attr "type" "load4")
10510    (set_attr "predicable" "yes")]
10513 ;; Load into PC and return
10514 (define_insn "*ldr_with_return"
10515   [(return)
10516    (set (reg:SI PC_REGNUM)
10517         (mem:SI (post_inc:SI (match_operand:SI 0 "s_register_operand" "+rk"))))]
10518   "TARGET_32BIT && (reload_in_progress || reload_completed)"
10519   "ldr%?\t%|pc, [%0], #4"
10520   [(set_attr "type" "load1")
10521    (set_attr "predicable" "yes")]
10523 ;; Pop for floating point registers (as used in epilogue RTL)
10524 (define_insn "*vfp_pop_multiple_with_writeback"
10525   [(match_parallel 0 "pop_multiple_fp"
10526     [(set (match_operand:SI 1 "s_register_operand" "+rk")
10527           (plus:SI (match_dup 1)
10528                    (match_operand:SI 2 "const_int_I_operand" "I")))
10529      (set (match_operand:DF 3 "vfp_hard_register_operand" "")
10530           (mem:DF (match_dup 1)))])]
10531   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
10532   "*
10533   {
10534     int num_regs = XVECLEN (operands[0], 0);
10535     char pattern[100];
10536     rtx op_list[2];
10537     strcpy (pattern, \"vldm\\t\");
10538     strcat (pattern, reg_names[REGNO (SET_DEST (XVECEXP (operands[0], 0, 0)))]);
10539     strcat (pattern, \"!, {\");
10540     op_list[0] = XEXP (XVECEXP (operands[0], 0, 1), 0);
10541     strcat (pattern, \"%P0\");
10542     if ((num_regs - 1) > 1)
10543       {
10544         strcat (pattern, \"-%P1\");
10545         op_list [1] = XEXP (XVECEXP (operands[0], 0, num_regs - 1), 0);
10546       }
10548     strcat (pattern, \"}\");
10549     output_asm_insn (pattern, op_list);
10550     return \"\";
10551   }
10552   "
10553   [(set_attr "type" "load4")
10554    (set_attr "conds" "unconditional")
10555    (set_attr "predicable" "no")]
10558 ;; Special patterns for dealing with the constant pool
10560 (define_insn "align_4"
10561   [(unspec_volatile [(const_int 0)] VUNSPEC_ALIGN)]
10562   "TARGET_EITHER"
10563   "*
10564   assemble_align (32);
10565   return \"\";
10566   "
10567   [(set_attr "type" "no_insn")]
10570 (define_insn "align_8"
10571   [(unspec_volatile [(const_int 0)] VUNSPEC_ALIGN8)]
10572   "TARGET_EITHER"
10573   "*
10574   assemble_align (64);
10575   return \"\";
10576   "
10577   [(set_attr "type" "no_insn")]
10580 (define_insn "consttable_end"
10581   [(unspec_volatile [(const_int 0)] VUNSPEC_POOL_END)]
10582   "TARGET_EITHER"
10583   "*
10584   making_const_table = FALSE;
10585   return \"\";
10586   "
10587   [(set_attr "type" "no_insn")]
10590 (define_insn "consttable_4"
10591   [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_4)]
10592   "TARGET_EITHER"
10593   "*
10594   {
10595     rtx x = operands[0];
10596     making_const_table = TRUE;
10597     switch (GET_MODE_CLASS (GET_MODE (x)))
10598       {
10599       case MODE_FLOAT:
10600         if (GET_MODE (x) == HFmode)
10601           arm_emit_fp16_const (x);
10602         else
10603           {
10604             REAL_VALUE_TYPE r;
10605             REAL_VALUE_FROM_CONST_DOUBLE (r, x);
10606             assemble_real (r, GET_MODE (x), BITS_PER_WORD);
10607           }
10608         break;
10609       default:
10610         /* XXX: Sometimes gcc does something really dumb and ends up with
10611            a HIGH in a constant pool entry, usually because it's trying to
10612            load into a VFP register.  We know this will always be used in
10613            combination with a LO_SUM which ignores the high bits, so just
10614            strip off the HIGH.  */
10615         if (GET_CODE (x) == HIGH)
10616           x = XEXP (x, 0);
10617         assemble_integer (x, 4, BITS_PER_WORD, 1);
10618         mark_symbol_refs_as_used (x);
10619         break;
10620       }
10621     return \"\";
10622   }"
10623   [(set_attr "length" "4")
10624    (set_attr "type" "no_insn")]
10627 (define_insn "consttable_8"
10628   [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_8)]
10629   "TARGET_EITHER"
10630   "*
10631   {
10632     making_const_table = TRUE;
10633     switch (GET_MODE_CLASS (GET_MODE (operands[0])))
10634       {
10635        case MODE_FLOAT:
10636         {
10637           REAL_VALUE_TYPE r;
10638           REAL_VALUE_FROM_CONST_DOUBLE (r, operands[0]);
10639           assemble_real (r, GET_MODE (operands[0]), BITS_PER_WORD);
10640           break;
10641         }
10642       default:
10643         assemble_integer (operands[0], 8, BITS_PER_WORD, 1);
10644         break;
10645       }
10646     return \"\";
10647   }"
10648   [(set_attr "length" "8")
10649    (set_attr "type" "no_insn")]
10652 (define_insn "consttable_16"
10653   [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_16)]
10654   "TARGET_EITHER"
10655   "*
10656   {
10657     making_const_table = TRUE;
10658     switch (GET_MODE_CLASS (GET_MODE (operands[0])))
10659       {
10660        case MODE_FLOAT:
10661         {
10662           REAL_VALUE_TYPE r;
10663           REAL_VALUE_FROM_CONST_DOUBLE (r, operands[0]);
10664           assemble_real (r, GET_MODE (operands[0]), BITS_PER_WORD);
10665           break;
10666         }
10667       default:
10668         assemble_integer (operands[0], 16, BITS_PER_WORD, 1);
10669         break;
10670       }
10671     return \"\";
10672   }"
10673   [(set_attr "length" "16")
10674    (set_attr "type" "no_insn")]
10677 ;; V5 Instructions,
10679 (define_insn "clzsi2"
10680   [(set (match_operand:SI 0 "s_register_operand" "=r")
10681         (clz:SI (match_operand:SI 1 "s_register_operand" "r")))]
10682   "TARGET_32BIT && arm_arch5"
10683   "clz%?\\t%0, %1"
10684   [(set_attr "predicable" "yes")
10685    (set_attr "predicable_short_it" "no")
10686    (set_attr "type" "clz")])
10688 (define_insn "rbitsi2"
10689   [(set (match_operand:SI 0 "s_register_operand" "=r")
10690         (unspec:SI [(match_operand:SI 1 "s_register_operand" "r")] UNSPEC_RBIT))]
10691   "TARGET_32BIT && arm_arch_thumb2"
10692   "rbit%?\\t%0, %1"
10693   [(set_attr "predicable" "yes")
10694    (set_attr "predicable_short_it" "no")
10695    (set_attr "type" "clz")])
10697 (define_expand "ctzsi2"
10698  [(set (match_operand:SI           0 "s_register_operand" "")
10699        (ctz:SI (match_operand:SI  1 "s_register_operand" "")))]
10700   "TARGET_32BIT && arm_arch_thumb2"
10701   "
10702    {
10703      rtx tmp = gen_reg_rtx (SImode); 
10704      emit_insn (gen_rbitsi2 (tmp, operands[1]));
10705      emit_insn (gen_clzsi2 (operands[0], tmp));
10706    }
10707    DONE;
10708   "
10711 ;; V5E instructions.
10713 (define_insn "prefetch"
10714   [(prefetch (match_operand:SI 0 "address_operand" "p")
10715              (match_operand:SI 1 "" "")
10716              (match_operand:SI 2 "" ""))]
10717   "TARGET_32BIT && arm_arch5e"
10718   "pld\\t%a0"
10719   [(set_attr "type" "load1")]
10722 ;; General predication pattern
10724 (define_cond_exec
10725   [(match_operator 0 "arm_comparison_operator"
10726     [(match_operand 1 "cc_register" "")
10727      (const_int 0)])]
10728   "TARGET_32BIT"
10729   ""
10730 [(set_attr "predicated" "yes")]
10733 (define_insn "force_register_use"
10734   [(unspec:SI [(match_operand:SI 0 "register_operand" "")] UNSPEC_REGISTER_USE)]
10735   ""
10736   "%@ %0 needed"
10737   [(set_attr "length" "0")
10738    (set_attr "type" "no_insn")]
10742 ;; Patterns for exception handling
10744 (define_expand "eh_return"
10745   [(use (match_operand 0 "general_operand" ""))]
10746   "TARGET_EITHER"
10747   "
10748   {
10749     if (TARGET_32BIT)
10750       emit_insn (gen_arm_eh_return (operands[0]));
10751     else
10752       emit_insn (gen_thumb_eh_return (operands[0]));
10753     DONE;
10754   }"
10756                                    
10757 ;; We can't expand this before we know where the link register is stored.
10758 (define_insn_and_split "arm_eh_return"
10759   [(unspec_volatile [(match_operand:SI 0 "s_register_operand" "r")]
10760                     VUNSPEC_EH_RETURN)
10761    (clobber (match_scratch:SI 1 "=&r"))]
10762   "TARGET_ARM"
10763   "#"
10764   "&& reload_completed"
10765   [(const_int 0)]
10766   "
10767   {
10768     arm_set_return_address (operands[0], operands[1]);
10769     DONE;
10770   }"
10774 ;; TLS support
10776 (define_insn "load_tp_hard"
10777   [(set (match_operand:SI 0 "register_operand" "=r")
10778         (unspec:SI [(const_int 0)] UNSPEC_TLS))]
10779   "TARGET_HARD_TP"
10780   "mrc%?\\tp15, 0, %0, c13, c0, 3\\t@ load_tp_hard"
10781   [(set_attr "predicable" "yes")
10782    (set_attr "type" "mrs")]
10785 ;; Doesn't clobber R1-R3.  Must use r0 for the first operand.
10786 (define_insn "load_tp_soft"
10787   [(set (reg:SI 0) (unspec:SI [(const_int 0)] UNSPEC_TLS))
10788    (clobber (reg:SI LR_REGNUM))
10789    (clobber (reg:SI IP_REGNUM))
10790    (clobber (reg:CC CC_REGNUM))]
10791   "TARGET_SOFT_TP"
10792   "bl\\t__aeabi_read_tp\\t@ load_tp_soft"
10793   [(set_attr "conds" "clob")
10794    (set_attr "type" "branch")]
10797 ;; tls descriptor call
10798 (define_insn "tlscall"
10799   [(set (reg:SI R0_REGNUM)
10800         (unspec:SI [(reg:SI R0_REGNUM)
10801                     (match_operand:SI 0 "" "X")
10802                     (match_operand 1 "" "")] UNSPEC_TLS))
10803    (clobber (reg:SI R1_REGNUM))
10804    (clobber (reg:SI LR_REGNUM))
10805    (clobber (reg:SI CC_REGNUM))]
10806   "TARGET_GNU2_TLS"
10807   {
10808     targetm.asm_out.internal_label (asm_out_file, "LPIC",
10809                                     INTVAL (operands[1]));
10810     return "bl\\t%c0(tlscall)";
10811   }
10812   [(set_attr "conds" "clob")
10813    (set_attr "length" "4")
10814    (set_attr "type" "branch")]
10817 ;; For thread pointer builtin
10818 (define_expand "get_thread_pointersi"
10819   [(match_operand:SI 0 "s_register_operand" "=r")]
10820  ""
10823    arm_load_tp (operands[0]);
10824    DONE;
10825  }")
10829 ;; We only care about the lower 16 bits of the constant 
10830 ;; being inserted into the upper 16 bits of the register.
10831 (define_insn "*arm_movtas_ze" 
10832   [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r")
10833                    (const_int 16)
10834                    (const_int 16))
10835         (match_operand:SI 1 "const_int_operand" ""))]
10836   "arm_arch_thumb2"
10837   "movt%?\t%0, %L1"
10838  [(set_attr "predicable" "yes")
10839   (set_attr "predicable_short_it" "no")
10840   (set_attr "length" "4")
10841   (set_attr "type" "mov_imm")]
10844 (define_insn "*arm_rev"
10845   [(set (match_operand:SI 0 "s_register_operand" "=l,l,r")
10846         (bswap:SI (match_operand:SI 1 "s_register_operand" "l,l,r")))]
10847   "arm_arch6"
10848   "@
10849    rev\t%0, %1
10850    rev%?\t%0, %1
10851    rev%?\t%0, %1"
10852   [(set_attr "arch" "t1,t2,32")
10853    (set_attr "length" "2,2,4")
10854    (set_attr "predicable" "no,yes,yes")
10855    (set_attr "predicable_short_it" "no")
10856    (set_attr "type" "rev")]
10859 (define_expand "arm_legacy_rev"
10860   [(set (match_operand:SI 2 "s_register_operand" "")
10861         (xor:SI (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
10862                              (const_int 16))
10863                 (match_dup 1)))
10864    (set (match_dup 2)
10865         (lshiftrt:SI (match_dup 2)
10866                      (const_int 8)))
10867    (set (match_operand:SI 3 "s_register_operand" "")
10868         (rotatert:SI (match_dup 1)
10869                      (const_int 8)))
10870    (set (match_dup 2)
10871         (and:SI (match_dup 2)
10872                 (const_int -65281)))
10873    (set (match_operand:SI 0 "s_register_operand" "")
10874         (xor:SI (match_dup 3)
10875                 (match_dup 2)))]
10876   "TARGET_32BIT"
10877   ""
10880 ;; Reuse temporaries to keep register pressure down.
10881 (define_expand "thumb_legacy_rev"
10882   [(set (match_operand:SI 2 "s_register_operand" "")
10883      (ashift:SI (match_operand:SI 1 "s_register_operand" "")
10884                 (const_int 24)))
10885    (set (match_operand:SI 3 "s_register_operand" "")
10886      (lshiftrt:SI (match_dup 1)
10887                   (const_int 24)))
10888    (set (match_dup 3)
10889      (ior:SI (match_dup 3)
10890              (match_dup 2)))
10891    (set (match_operand:SI 4 "s_register_operand" "")
10892      (const_int 16))
10893    (set (match_operand:SI 5 "s_register_operand" "")
10894      (rotatert:SI (match_dup 1)
10895                   (match_dup 4)))
10896    (set (match_dup 2)
10897      (ashift:SI (match_dup 5)
10898                 (const_int 24)))
10899    (set (match_dup 5)
10900      (lshiftrt:SI (match_dup 5)
10901                   (const_int 24)))
10902    (set (match_dup 5)
10903      (ior:SI (match_dup 5)
10904              (match_dup 2)))
10905    (set (match_dup 5)
10906      (rotatert:SI (match_dup 5)
10907                   (match_dup 4)))
10908    (set (match_operand:SI 0 "s_register_operand" "")
10909      (ior:SI (match_dup 5)
10910              (match_dup 3)))]
10911   "TARGET_THUMB"
10912   ""
10915 (define_expand "bswapsi2"
10916   [(set (match_operand:SI 0 "s_register_operand" "=r")
10917         (bswap:SI (match_operand:SI 1 "s_register_operand" "r")))]
10918 "TARGET_EITHER && (arm_arch6 || !optimize_size)"
10920     if (!arm_arch6)
10921       {
10922         rtx op2 = gen_reg_rtx (SImode);
10923         rtx op3 = gen_reg_rtx (SImode);
10925         if (TARGET_THUMB)
10926           {
10927             rtx op4 = gen_reg_rtx (SImode);
10928             rtx op5 = gen_reg_rtx (SImode);
10930             emit_insn (gen_thumb_legacy_rev (operands[0], operands[1],
10931                                              op2, op3, op4, op5));
10932           }
10933         else
10934           {
10935             emit_insn (gen_arm_legacy_rev (operands[0], operands[1],
10936                                            op2, op3));
10937           }
10939         DONE;
10940       }
10941   "
10944 ;; bswap16 patterns: use revsh and rev16 instructions for the signed
10945 ;; and unsigned variants, respectively. For rev16, expose
10946 ;; byte-swapping in the lower 16 bits only.
10947 (define_insn "*arm_revsh"
10948   [(set (match_operand:SI 0 "s_register_operand" "=l,l,r")
10949         (sign_extend:SI (bswap:HI (match_operand:HI 1 "s_register_operand" "l,l,r"))))]
10950   "arm_arch6"
10951   "@
10952   revsh\t%0, %1
10953   revsh%?\t%0, %1
10954   revsh%?\t%0, %1"
10955   [(set_attr "arch" "t1,t2,32")
10956    (set_attr "length" "2,2,4")
10957    (set_attr "type" "rev")]
10960 (define_insn "*arm_rev16"
10961   [(set (match_operand:HI 0 "s_register_operand" "=l,l,r")
10962         (bswap:HI (match_operand:HI 1 "s_register_operand" "l,l,r")))]
10963   "arm_arch6"
10964   "@
10965    rev16\t%0, %1
10966    rev16%?\t%0, %1
10967    rev16%?\t%0, %1"
10968   [(set_attr "arch" "t1,t2,32")
10969    (set_attr "length" "2,2,4")
10970    (set_attr "type" "rev")]
10973 ;; There are no canonicalisation rules for the position of the lshiftrt, ashift
10974 ;; operations within an IOR/AND RTX, therefore we have two patterns matching
10975 ;; each valid permutation.
10977 (define_insn "arm_rev16si2"
10978   [(set (match_operand:SI 0 "register_operand" "=l,l,r")
10979         (ior:SI (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "l,l,r")
10980                                    (const_int 8))
10981                         (match_operand:SI 3 "const_int_operand" "n,n,n"))
10982                 (and:SI (lshiftrt:SI (match_dup 1)
10983                                      (const_int 8))
10984                         (match_operand:SI 2 "const_int_operand" "n,n,n"))))]
10985   "arm_arch6
10986    && aarch_rev16_shleft_mask_imm_p (operands[3], SImode)
10987    && aarch_rev16_shright_mask_imm_p (operands[2], SImode)"
10988   "rev16\\t%0, %1"
10989   [(set_attr "arch" "t1,t2,32")
10990    (set_attr "length" "2,2,4")
10991    (set_attr "type" "rev")]
10994 (define_insn "arm_rev16si2_alt"
10995   [(set (match_operand:SI 0 "register_operand" "=l,l,r")
10996         (ior:SI (and:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "l,l,r")
10997                                      (const_int 8))
10998                         (match_operand:SI 2 "const_int_operand" "n,n,n"))
10999                 (and:SI (ashift:SI (match_dup 1)
11000                                    (const_int 8))
11001                         (match_operand:SI 3 "const_int_operand" "n,n,n"))))]
11002   "arm_arch6
11003    && aarch_rev16_shleft_mask_imm_p (operands[3], SImode)
11004    && aarch_rev16_shright_mask_imm_p (operands[2], SImode)"
11005   "rev16\\t%0, %1"
11006   [(set_attr "arch" "t1,t2,32")
11007    (set_attr "length" "2,2,4")
11008    (set_attr "type" "rev")]
11011 (define_expand "bswaphi2"
11012   [(set (match_operand:HI 0 "s_register_operand" "=r")
11013         (bswap:HI (match_operand:HI 1 "s_register_operand" "r")))]
11014 "arm_arch6"
11018 ;; Patterns for LDRD/STRD in Thumb2 mode
11020 (define_insn "*thumb2_ldrd"
11021   [(set (match_operand:SI 0 "s_register_operand" "=r")
11022         (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "rk")
11023                          (match_operand:SI 2 "ldrd_strd_offset_operand" "Do"))))
11024    (set (match_operand:SI 3 "s_register_operand" "=r")
11025         (mem:SI (plus:SI (match_dup 1)
11026                          (match_operand:SI 4 "const_int_operand" ""))))]
11027   "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11028      && current_tune->prefer_ldrd_strd
11029      && ((INTVAL (operands[2]) + 4) == INTVAL (operands[4]))
11030      && (operands_ok_ldrd_strd (operands[0], operands[3],
11031                                   operands[1], INTVAL (operands[2]),
11032                                   false, true))"
11033   "ldrd%?\t%0, %3, [%1, %2]"
11034   [(set_attr "type" "load2")
11035    (set_attr "predicable" "yes")
11036    (set_attr "predicable_short_it" "no")])
11038 (define_insn "*thumb2_ldrd_base"
11039   [(set (match_operand:SI 0 "s_register_operand" "=r")
11040         (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
11041    (set (match_operand:SI 2 "s_register_operand" "=r")
11042         (mem:SI (plus:SI (match_dup 1)
11043                          (const_int 4))))]
11044   "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11045      && current_tune->prefer_ldrd_strd
11046      && (operands_ok_ldrd_strd (operands[0], operands[2],
11047                                   operands[1], 0, false, true))"
11048   "ldrd%?\t%0, %2, [%1]"
11049   [(set_attr "type" "load2")
11050    (set_attr "predicable" "yes")
11051    (set_attr "predicable_short_it" "no")])
11053 (define_insn "*thumb2_ldrd_base_neg"
11054   [(set (match_operand:SI 0 "s_register_operand" "=r")
11055         (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "rk")
11056                          (const_int -4))))
11057    (set (match_operand:SI 2 "s_register_operand" "=r")
11058         (mem:SI (match_dup 1)))]
11059   "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11060      && current_tune->prefer_ldrd_strd
11061      && (operands_ok_ldrd_strd (operands[0], operands[2],
11062                                   operands[1], -4, false, true))"
11063   "ldrd%?\t%0, %2, [%1, #-4]"
11064   [(set_attr "type" "load2")
11065    (set_attr "predicable" "yes")
11066    (set_attr "predicable_short_it" "no")])
11068 (define_insn "*thumb2_strd"
11069   [(set (mem:SI (plus:SI (match_operand:SI 0 "s_register_operand" "rk")
11070                          (match_operand:SI 1 "ldrd_strd_offset_operand" "Do")))
11071         (match_operand:SI 2 "s_register_operand" "r"))
11072    (set (mem:SI (plus:SI (match_dup 0)
11073                          (match_operand:SI 3 "const_int_operand" "")))
11074         (match_operand:SI 4 "s_register_operand" "r"))]
11075   "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11076      && current_tune->prefer_ldrd_strd
11077      && ((INTVAL (operands[1]) + 4) == INTVAL (operands[3]))
11078      && (operands_ok_ldrd_strd (operands[2], operands[4],
11079                                   operands[0], INTVAL (operands[1]),
11080                                   false, false))"
11081   "strd%?\t%2, %4, [%0, %1]"
11082   [(set_attr "type" "store2")
11083    (set_attr "predicable" "yes")
11084    (set_attr "predicable_short_it" "no")])
11086 (define_insn "*thumb2_strd_base"
11087   [(set (mem:SI (match_operand:SI 0 "s_register_operand" "rk"))
11088         (match_operand:SI 1 "s_register_operand" "r"))
11089    (set (mem:SI (plus:SI (match_dup 0)
11090                          (const_int 4)))
11091         (match_operand:SI 2 "s_register_operand" "r"))]
11092   "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11093      && current_tune->prefer_ldrd_strd
11094      && (operands_ok_ldrd_strd (operands[1], operands[2],
11095                                   operands[0], 0, false, false))"
11096   "strd%?\t%1, %2, [%0]"
11097   [(set_attr "type" "store2")
11098    (set_attr "predicable" "yes")
11099    (set_attr "predicable_short_it" "no")])
11101 (define_insn "*thumb2_strd_base_neg"
11102   [(set (mem:SI (plus:SI (match_operand:SI 0 "s_register_operand" "rk")
11103                          (const_int -4)))
11104         (match_operand:SI 1 "s_register_operand" "r"))
11105    (set (mem:SI (match_dup 0))
11106         (match_operand:SI 2 "s_register_operand" "r"))]
11107   "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11108      && current_tune->prefer_ldrd_strd
11109      && (operands_ok_ldrd_strd (operands[1], operands[2],
11110                                   operands[0], -4, false, false))"
11111   "strd%?\t%1, %2, [%0, #-4]"
11112   [(set_attr "type" "store2")
11113    (set_attr "predicable" "yes")
11114    (set_attr "predicable_short_it" "no")])
11116 ;; ARMv8 CRC32 instructions.
11117 (define_insn "<crc_variant>"
11118   [(set (match_operand:SI 0 "s_register_operand" "=r")
11119         (unspec:SI [(match_operand:SI 1 "s_register_operand" "r")
11120                     (match_operand:<crc_mode> 2 "s_register_operand" "r")]
11121          CRC))]
11122   "TARGET_CRC32"
11123   "<crc_variant>\\t%0, %1, %2"
11124   [(set_attr "type" "crc")
11125    (set_attr "conds" "unconditional")]
11128 ;; Load the load/store double peephole optimizations.
11129 (include "ldrdstrd.md")
11131 ;; Load the load/store multiple patterns
11132 (include "ldmstm.md")
11134 ;; Patterns in ldmstm.md don't cover more than 4 registers. This pattern covers
11135 ;; large lists without explicit writeback generated for APCS_FRAME epilogue.
11136 (define_insn "*load_multiple"
11137   [(match_parallel 0 "load_multiple_operation"
11138     [(set (match_operand:SI 2 "s_register_operand" "=rk")
11139           (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
11140         ])]
11141   "TARGET_32BIT"
11142   "*
11143   {
11144     arm_output_multireg_pop (operands, /*return_pc=*/false,
11145                                        /*cond=*/const_true_rtx,
11146                                        /*reverse=*/false,
11147                                        /*update=*/false);
11148     return \"\";
11149   }
11150   "
11151   [(set_attr "predicable" "yes")]
11154 ;; Vector bits common to IWMMXT and Neon
11155 (include "vec-common.md")
11156 ;; Load the Intel Wireless Multimedia Extension patterns
11157 (include "iwmmxt.md")
11158 ;; Load the VFP co-processor patterns
11159 (include "vfp.md")
11160 ;; Thumb-1 patterns
11161 (include "thumb1.md")
11162 ;; Thumb-2 patterns
11163 (include "thumb2.md")
11164 ;; Neon patterns
11165 (include "neon.md")
11166 ;; Crypto patterns
11167 (include "crypto.md")
11168 ;; Synchronization Primitives
11169 (include "sync.md")
11170 ;; Fixed-point patterns
11171 (include "arm-fixed.md")