2016-10-17 Bernd Edlinger <bernd.edlinger@hotmail.de>
[official-gcc.git] / gcc / config / arm / arm.md
blob8393f65bcf4c9c3e61b91e5adcd5f59ff7c6ec3f
1 ;;- Machine description for ARM for GNU compiler
2 ;;  Copyright (C) 1991-2016 Free Software Foundation, Inc.
3 ;;  Contributed by Pieter `Tiggr' Schoenmakers (rcpieter@win.tue.nl)
4 ;;  and Martin Simmons (@harleqn.co.uk).
5 ;;  More major hacks by Richard Earnshaw (rearnsha@arm.com).
7 ;; This file is part of GCC.
9 ;; GCC is free software; you can redistribute it and/or modify it
10 ;; under the terms of the GNU General Public License as published
11 ;; by the Free Software Foundation; either version 3, or (at your
12 ;; option) any later version.
14 ;; GCC is distributed in the hope that it will be useful, but WITHOUT
15 ;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16 ;; or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
17 ;; License for more details.
19 ;; You should have received a copy of the GNU General Public License
20 ;; along with GCC; see the file COPYING3.  If not see
21 ;; <http://www.gnu.org/licenses/>.
23 ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
26 ;;---------------------------------------------------------------------------
27 ;; Constants
29 ;; Register numbers -- All machine registers should be defined here
30 (define_constants
31   [(R0_REGNUM         0)        ; First CORE register
32    (R1_REGNUM         1)        ; Second CORE register
33    (IP_REGNUM        12)        ; Scratch register
34    (SP_REGNUM        13)        ; Stack pointer
35    (LR_REGNUM        14)        ; Return address register
36    (PC_REGNUM        15)        ; Program counter
37    (LAST_ARM_REGNUM  15)        ;
38    (CC_REGNUM       100)        ; Condition code pseudo register
39    (VFPCC_REGNUM    101)        ; VFP Condition code pseudo register
40   ]
42 ;; 3rd operand to select_dominance_cc_mode
43 (define_constants
44   [(DOM_CC_X_AND_Y  0)
45    (DOM_CC_NX_OR_Y  1)
46    (DOM_CC_X_OR_Y   2)
47   ]
49 ;; conditional compare combination
50 (define_constants
51   [(CMP_CMP 0)
52    (CMN_CMP 1)
53    (CMP_CMN 2)
54    (CMN_CMN 3)
55    (NUM_OF_COND_CMP 4)
56   ]
60 ;;---------------------------------------------------------------------------
61 ;; Attributes
63 ;; Processor type.  This is created automatically from arm-cores.def.
64 (include "arm-tune.md")
66 ;; Instruction classification types
67 (include "types.md")
69 ; IS_THUMB is set to 'yes' when we are generating Thumb code, and 'no' when
70 ; generating ARM code.  This is used to control the length of some insn
71 ; patterns that share the same RTL in both ARM and Thumb code.
72 (define_attr "is_thumb" "yes,no"
73   (const (if_then_else (symbol_ref "TARGET_THUMB")
74                        (const_string "yes") (const_string "no"))))
76 ; IS_ARCH6 is set to 'yes' when we are generating code form ARMv6.
77 (define_attr "is_arch6" "no,yes" (const (symbol_ref "arm_arch6")))
79 ; IS_THUMB1 is set to 'yes' iff we are generating Thumb-1 code.
80 (define_attr "is_thumb1" "yes,no"
81   (const (if_then_else (symbol_ref "TARGET_THUMB1")
82                        (const_string "yes") (const_string "no"))))
84 ; We use this attribute to disable alternatives that can produce 32-bit
85 ; instructions inside an IT-block in Thumb2 state.  ARMv8 deprecates IT blocks
86 ; that contain 32-bit instructions.
87 (define_attr "enabled_for_depr_it" "no,yes" (const_string "yes"))
89 ; This attribute is used to disable a predicated alternative when we have
90 ; arm_restrict_it.
91 (define_attr "predicable_short_it" "no,yes" (const_string "yes"))
93 ;; Operand number of an input operand that is shifted.  Zero if the
94 ;; given instruction does not shift one of its input operands.
95 (define_attr "shift" "" (const_int 0))
97 ;; [For compatibility with AArch64 in pipeline models]
98 ;; Attribute that specifies whether or not the instruction touches fp
99 ;; registers.
100 (define_attr "fp" "no,yes" (const_string "no"))
102 ; Floating Point Unit.  If we only have floating point emulation, then there
103 ; is no point in scheduling the floating point insns.  (Well, for best
104 ; performance we should try and group them together).
105 (define_attr "fpu" "none,vfp"
106   (const (symbol_ref "arm_fpu_attr")))
108 ; Predicated means that the insn form is conditionally executed based on a
109 ; predicate.  We default to 'no' because no Thumb patterns match this rule
110 ; and not all ARM insns do.
111 (define_attr "predicated" "yes,no" (const_string "no"))
113 ; LENGTH of an instruction (in bytes)
114 (define_attr "length" ""
115   (const_int 4))
117 ; The architecture which supports the instruction (or alternative).
118 ; This can be "a" for ARM, "t" for either of the Thumbs, "32" for
119 ; TARGET_32BIT, "t1" or "t2" to specify a specific Thumb mode.  "v6"
120 ; for ARM or Thumb-2 with arm_arch6, and nov6 for ARM without
121 ; arm_arch6.  "v6t2" for Thumb-2 with arm_arch6 and "v8mb" for ARMv8-M
122 ; Baseline.  This attribute is used to compute attribute "enabled",
123 ; use type "any" to enable an alternative in all cases.
124 (define_attr "arch" "any,a,t,32,t1,t2,v6,nov6,v6t2,v8mb,neon_for_64bits,avoid_neon_for_64bits,iwmmxt,iwmmxt2,armv6_or_vfpv3,neon"
125   (const_string "any"))
127 (define_attr "arch_enabled" "no,yes"
128   (cond [(eq_attr "arch" "any")
129          (const_string "yes")
131          (and (eq_attr "arch" "a")
132               (match_test "TARGET_ARM"))
133          (const_string "yes")
135          (and (eq_attr "arch" "t")
136               (match_test "TARGET_THUMB"))
137          (const_string "yes")
139          (and (eq_attr "arch" "t1")
140               (match_test "TARGET_THUMB1"))
141          (const_string "yes")
143          (and (eq_attr "arch" "t2")
144               (match_test "TARGET_THUMB2"))
145          (const_string "yes")
147          (and (eq_attr "arch" "32")
148               (match_test "TARGET_32BIT"))
149          (const_string "yes")
151          (and (eq_attr "arch" "v6")
152               (match_test "TARGET_32BIT && arm_arch6"))
153          (const_string "yes")
155          (and (eq_attr "arch" "nov6")
156               (match_test "TARGET_32BIT && !arm_arch6"))
157          (const_string "yes")
159          (and (eq_attr "arch" "v6t2")
160               (match_test "TARGET_32BIT && arm_arch6 && arm_arch_thumb2"))
161          (const_string "yes")
163          (and (eq_attr "arch" "v8mb")
164               (match_test "TARGET_THUMB1 && arm_arch8"))
165          (const_string "yes")
167          (and (eq_attr "arch" "avoid_neon_for_64bits")
168               (match_test "TARGET_NEON")
169               (not (match_test "TARGET_PREFER_NEON_64BITS")))
170          (const_string "yes")
172          (and (eq_attr "arch" "neon_for_64bits")
173               (match_test "TARGET_NEON")
174               (match_test "TARGET_PREFER_NEON_64BITS"))
175          (const_string "yes")
177          (and (eq_attr "arch" "iwmmxt2")
178               (match_test "TARGET_REALLY_IWMMXT2"))
179          (const_string "yes")
181          (and (eq_attr "arch" "armv6_or_vfpv3")
182               (match_test "arm_arch6 || TARGET_VFP3"))
183          (const_string "yes")
185          (and (eq_attr "arch" "neon")
186               (match_test "TARGET_NEON"))
187          (const_string "yes")
188         ]
190         (const_string "no")))
192 (define_attr "opt" "any,speed,size"
193   (const_string "any"))
195 (define_attr "opt_enabled" "no,yes"
196   (cond [(eq_attr "opt" "any")
197          (const_string "yes")
199          (and (eq_attr "opt" "speed")
200               (match_test "optimize_function_for_speed_p (cfun)"))
201          (const_string "yes")
203          (and (eq_attr "opt" "size")
204               (match_test "optimize_function_for_size_p (cfun)"))
205          (const_string "yes")]
206         (const_string "no")))
208 (define_attr "use_literal_pool" "no,yes"
209    (cond [(and (eq_attr "type" "f_loads,f_loadd")
210                (match_test "CONSTANT_P (operands[1])"))
211           (const_string "yes")]
212          (const_string "no")))
214 ; Enable all alternatives that are both arch_enabled and insn_enabled.
215 ; FIXME:: opt_enabled has been temporarily removed till the time we have
216 ; an attribute that allows the use of such alternatives.
217 ; This depends on caching of speed_p, size_p on a per
218 ; alternative basis. The problem is that the enabled attribute
219 ; cannot depend on any state that is not cached or is not constant
220 ; for a compilation unit. We probably need a generic "hot/cold"
221 ; alternative which if implemented can help with this. We disable this
222 ; until such a time as this is implemented and / or the improvements or
223 ; regressions with removing this attribute are double checked.
224 ; See ashldi3_neon and <shift>di3_neon in neon.md.
226  (define_attr "enabled" "no,yes"
227    (cond [(and (eq_attr "predicable_short_it" "no")
228                (and (eq_attr "predicated" "yes")
229                     (match_test "arm_restrict_it")))
230           (const_string "no")
232           (and (eq_attr "enabled_for_depr_it" "no")
233                (match_test "arm_restrict_it"))
234           (const_string "no")
236           (and (eq_attr "use_literal_pool" "yes")
237                (match_test "arm_disable_literal_pool"))
238           (const_string "no")
240           (eq_attr "arch_enabled" "no")
241           (const_string "no")]
242          (const_string "yes")))
244 ; POOL_RANGE is how far away from a constant pool entry that this insn
245 ; can be placed.  If the distance is zero, then this insn will never
246 ; reference the pool.
247 ; Note that for Thumb constant pools the PC value is rounded down to the
248 ; nearest multiple of four.  Therefore, THUMB2_POOL_RANGE (and POOL_RANGE for
249 ; Thumb insns) should be set to <max_range> - 2.
250 ; NEG_POOL_RANGE is nonzero for insns that can reference a constant pool entry
251 ; before its address.  It is set to <max_range> - (8 + <data_size>).
252 (define_attr "arm_pool_range" "" (const_int 0))
253 (define_attr "thumb2_pool_range" "" (const_int 0))
254 (define_attr "arm_neg_pool_range" "" (const_int 0))
255 (define_attr "thumb2_neg_pool_range" "" (const_int 0))
257 (define_attr "pool_range" ""
258   (cond [(eq_attr "is_thumb" "yes") (attr "thumb2_pool_range")]
259         (attr "arm_pool_range")))
260 (define_attr "neg_pool_range" ""
261   (cond [(eq_attr "is_thumb" "yes") (attr "thumb2_neg_pool_range")]
262         (attr "arm_neg_pool_range")))
264 ; An assembler sequence may clobber the condition codes without us knowing.
265 ; If such an insn references the pool, then we have no way of knowing how,
266 ; so use the most conservative value for pool_range.
267 (define_asm_attributes
268  [(set_attr "conds" "clob")
269   (set_attr "length" "4")
270   (set_attr "pool_range" "250")])
272 ; Load scheduling, set from the arm_ld_sched variable
273 ; initialized by arm_option_override()
274 (define_attr "ldsched" "no,yes" (const (symbol_ref "arm_ld_sched")))
276 ; condition codes: this one is used by final_prescan_insn to speed up
277 ; conditionalizing instructions.  It saves having to scan the rtl to see if
278 ; it uses or alters the condition codes.
280 ; USE means that the condition codes are used by the insn in the process of
281 ;   outputting code, this means (at present) that we can't use the insn in
282 ;   inlined branches
284 ; SET means that the purpose of the insn is to set the condition codes in a
285 ;   well defined manner.
287 ; CLOB means that the condition codes are altered in an undefined manner, if
288 ;   they are altered at all
290 ; UNCONDITIONAL means the instruction can not be conditionally executed and
291 ;   that the instruction does not use or alter the condition codes.
293 ; NOCOND means that the instruction does not use or alter the condition
294 ;   codes but can be converted into a conditionally exectuted instruction.
296 (define_attr "conds" "use,set,clob,unconditional,nocond"
297         (if_then_else
298          (ior (eq_attr "is_thumb1" "yes")
299               (eq_attr "type" "call"))
300          (const_string "clob")
301          (if_then_else (eq_attr "is_neon_type" "no")
302          (const_string "nocond")
303          (const_string "unconditional"))))
305 ; Predicable means that the insn can be conditionally executed based on
306 ; an automatically added predicate (additional patterns are generated by 
307 ; gen...).  We default to 'no' because no Thumb patterns match this rule
308 ; and not all ARM patterns do.
309 (define_attr "predicable" "no,yes" (const_string "no"))
311 ; Only model the write buffer for ARM6 and ARM7.  Earlier processors don't
312 ; have one.  Later ones, such as StrongARM, have write-back caches, so don't
313 ; suffer blockages enough to warrant modelling this (and it can adversely
314 ; affect the schedule).
315 (define_attr "model_wbuf" "no,yes" (const (symbol_ref "arm_tune_wbuf")))
317 ; WRITE_CONFLICT implies that a read following an unrelated write is likely
318 ; to stall the processor.  Used with model_wbuf above.
319 (define_attr "write_conflict" "no,yes"
320   (if_then_else (eq_attr "type"
321                  "block,call,load1")
322                 (const_string "yes")
323                 (const_string "no")))
325 ; Classify the insns into those that take one cycle and those that take more
326 ; than one on the main cpu execution unit.
327 (define_attr "core_cycles" "single,multi"
328   (if_then_else (eq_attr "type"
329     "adc_imm, adc_reg, adcs_imm, adcs_reg, adr, alu_ext, alu_imm, alu_sreg,\
330     alu_shift_imm, alu_shift_reg, alu_dsp_reg, alus_ext, alus_imm, alus_sreg,\
331     alus_shift_imm, alus_shift_reg, bfm, csel, rev, logic_imm, logic_reg,\
332     logic_shift_imm, logic_shift_reg, logics_imm, logics_reg,\
333     logics_shift_imm, logics_shift_reg, extend, shift_imm, float, fcsel,\
334     wmmx_wor, wmmx_wxor, wmmx_wand, wmmx_wandn, wmmx_wmov, wmmx_tmcrr,\
335     wmmx_tmrrc, wmmx_wldr, wmmx_wstr, wmmx_tmcr, wmmx_tmrc, wmmx_wadd,\
336     wmmx_wsub, wmmx_wmul, wmmx_wmac, wmmx_wavg2, wmmx_tinsr, wmmx_textrm,\
337     wmmx_wshufh, wmmx_wcmpeq, wmmx_wcmpgt, wmmx_wmax, wmmx_wmin, wmmx_wpack,\
338     wmmx_wunpckih, wmmx_wunpckil, wmmx_wunpckeh, wmmx_wunpckel, wmmx_wror,\
339     wmmx_wsra, wmmx_wsrl, wmmx_wsll, wmmx_wmadd, wmmx_tmia, wmmx_tmiaph,\
340     wmmx_tmiaxy, wmmx_tbcst, wmmx_tmovmsk, wmmx_wacc, wmmx_waligni,\
341     wmmx_walignr, wmmx_tandc, wmmx_textrc, wmmx_torc, wmmx_torvsc, wmmx_wsad,\
342     wmmx_wabs, wmmx_wabsdiff, wmmx_waddsubhx, wmmx_wsubaddhx, wmmx_wavg4,\
343     wmmx_wmulw, wmmx_wqmulm, wmmx_wqmulwm, wmmx_waddbhus, wmmx_wqmiaxy,\
344     wmmx_wmiaxy, wmmx_wmiawxy, wmmx_wmerge")
345                 (const_string "single")
346                 (const_string "multi")))
348 ;; FAR_JUMP is "yes" if a BL instruction is used to generate a branch to a
349 ;; distant label.  Only applicable to Thumb code.
350 (define_attr "far_jump" "yes,no" (const_string "no"))
353 ;; The number of machine instructions this pattern expands to.
354 ;; Used for Thumb-2 conditional execution.
355 (define_attr "ce_count" "" (const_int 1))
357 ;;---------------------------------------------------------------------------
358 ;; Unspecs
360 (include "unspecs.md")
362 ;;---------------------------------------------------------------------------
363 ;; Mode iterators
365 (include "iterators.md")
367 ;;---------------------------------------------------------------------------
368 ;; Predicates
370 (include "predicates.md")
371 (include "constraints.md")
373 ;;---------------------------------------------------------------------------
374 ;; Pipeline descriptions
376 (define_attr "tune_cortexr4" "yes,no"
377   (const (if_then_else
378           (eq_attr "tune" "cortexr4,cortexr4f,cortexr5")
379           (const_string "yes")
380           (const_string "no"))))
382 ;; True if the generic scheduling description should be used.
384 (define_attr "generic_sched" "yes,no"
385   (const (if_then_else
386           (ior (eq_attr "tune" "fa526,fa626,fa606te,fa626te,fmp626,fa726te,\
387                                 arm926ejs,arm1020e,arm1026ejs,arm1136js,\
388                                 arm1136jfs,cortexa5,cortexa7,cortexa8,\
389                                 cortexa9,cortexa12,cortexa15,cortexa17,\
390                                 cortexa53,cortexa57,cortexm4,cortexm7,\
391                                 exynosm1,marvell_pj4,xgene1")
392                (eq_attr "tune_cortexr4" "yes"))
393           (const_string "no")
394           (const_string "yes"))))
396 (define_attr "generic_vfp" "yes,no"
397   (const (if_then_else
398           (and (eq_attr "fpu" "vfp")
399                (eq_attr "tune" "!arm1020e,arm1022e,cortexa5,cortexa7,\
400                                 cortexa8,cortexa9,cortexa53,cortexm4,\
401                                 cortexm7,marvell_pj4,xgene1")
402                (eq_attr "tune_cortexr4" "no"))
403           (const_string "yes")
404           (const_string "no"))))
406 (include "marvell-f-iwmmxt.md")
407 (include "arm-generic.md")
408 (include "arm926ejs.md")
409 (include "arm1020e.md")
410 (include "arm1026ejs.md")
411 (include "arm1136jfs.md")
412 (include "fa526.md")
413 (include "fa606te.md")
414 (include "fa626te.md")
415 (include "fmp626.md")
416 (include "fa726te.md")
417 (include "cortex-a5.md")
418 (include "cortex-a7.md")
419 (include "cortex-a8.md")
420 (include "cortex-a9.md")
421 (include "cortex-a15.md")
422 (include "cortex-a17.md")
423 (include "cortex-a53.md")
424 (include "cortex-a57.md")
425 (include "cortex-r4.md")
426 (include "cortex-r4f.md")
427 (include "cortex-m7.md")
428 (include "cortex-m4.md")
429 (include "cortex-m4-fpu.md")
430 (include "exynos-m1.md")
431 (include "vfp11.md")
432 (include "marvell-pj4.md")
433 (include "xgene1.md")
436 ;;---------------------------------------------------------------------------
437 ;; Insn patterns
439 ;; Addition insns.
441 ;; Note: For DImode insns, there is normally no reason why operands should
442 ;; not be in the same register, what we don't want is for something being
443 ;; written to partially overlap something that is an input.
445 (define_expand "adddi3"
446  [(parallel
447    [(set (match_operand:DI           0 "s_register_operand" "")
448           (plus:DI (match_operand:DI 1 "s_register_operand" "")
449                    (match_operand:DI 2 "arm_adddi_operand"  "")))
450     (clobber (reg:CC CC_REGNUM))])]
451   "TARGET_EITHER"
452   "
453   if (TARGET_THUMB1)
454     {
455       if (!REG_P (operands[1]))
456         operands[1] = force_reg (DImode, operands[1]);
457       if (!REG_P (operands[2]))
458         operands[2] = force_reg (DImode, operands[2]);
459      }
460   "
463 (define_insn_and_split "*arm_adddi3"
464   [(set (match_operand:DI          0 "s_register_operand" "=&r,&r,&r,&r,&r")
465         (plus:DI (match_operand:DI 1 "s_register_operand" "%0, 0, r, 0, r")
466                  (match_operand:DI 2 "arm_adddi_operand"  "r,  0, r, Dd, Dd")))
467    (clobber (reg:CC CC_REGNUM))]
468   "TARGET_32BIT && !TARGET_NEON"
469   "#"
470   "TARGET_32BIT && reload_completed
471    && ! (TARGET_NEON && IS_VFP_REGNUM (REGNO (operands[0])))"
472   [(parallel [(set (reg:CC_C CC_REGNUM)
473                    (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
474                                  (match_dup 1)))
475               (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
476    (set (match_dup 3) (plus:SI (plus:SI (match_dup 4) (match_dup 5))
477                                (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
478   "
479   {
480     operands[3] = gen_highpart (SImode, operands[0]);
481     operands[0] = gen_lowpart (SImode, operands[0]);
482     operands[4] = gen_highpart (SImode, operands[1]);
483     operands[1] = gen_lowpart (SImode, operands[1]);
484     operands[5] = gen_highpart_mode (SImode, DImode, operands[2]);
485     operands[2] = gen_lowpart (SImode, operands[2]);
486   }"
487   [(set_attr "conds" "clob")
488    (set_attr "length" "8")
489    (set_attr "type" "multiple")]
492 (define_insn_and_split "*adddi_sesidi_di"
493   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
494         (plus:DI (sign_extend:DI
495                   (match_operand:SI 2 "s_register_operand" "r,r"))
496                  (match_operand:DI 1 "s_register_operand" "0,r")))
497    (clobber (reg:CC CC_REGNUM))]
498   "TARGET_32BIT"
499   "#"
500   "TARGET_32BIT && reload_completed"
501   [(parallel [(set (reg:CC_C CC_REGNUM)
502                    (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
503                                  (match_dup 1)))
504               (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
505    (set (match_dup 3) (plus:SI (plus:SI (ashiftrt:SI (match_dup 2)
506                                                      (const_int 31))
507                                         (match_dup 4))
508                                (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
509   "
510   {
511     operands[3] = gen_highpart (SImode, operands[0]);
512     operands[0] = gen_lowpart (SImode, operands[0]);
513     operands[4] = gen_highpart (SImode, operands[1]);
514     operands[1] = gen_lowpart (SImode, operands[1]);
515     operands[2] = gen_lowpart (SImode, operands[2]);
516   }"
517   [(set_attr "conds" "clob")
518    (set_attr "length" "8")
519    (set_attr "type" "multiple")]
522 (define_insn_and_split "*adddi_zesidi_di"
523   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
524         (plus:DI (zero_extend:DI
525                   (match_operand:SI 2 "s_register_operand" "r,r"))
526                  (match_operand:DI 1 "s_register_operand" "0,r")))
527    (clobber (reg:CC CC_REGNUM))]
528   "TARGET_32BIT"
529   "#"
530   "TARGET_32BIT && reload_completed"
531   [(parallel [(set (reg:CC_C CC_REGNUM)
532                    (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
533                                  (match_dup 1)))
534               (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
535    (set (match_dup 3) (plus:SI (plus:SI (match_dup 4) (const_int 0))
536                                (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
537   "
538   {
539     operands[3] = gen_highpart (SImode, operands[0]);
540     operands[0] = gen_lowpart (SImode, operands[0]);
541     operands[4] = gen_highpart (SImode, operands[1]);
542     operands[1] = gen_lowpart (SImode, operands[1]);
543     operands[2] = gen_lowpart (SImode, operands[2]);
544   }"
545   [(set_attr "conds" "clob")
546    (set_attr "length" "8")
547    (set_attr "type" "multiple")]
550 (define_expand "addv<mode>4"
551   [(match_operand:SIDI 0 "register_operand")
552    (match_operand:SIDI 1 "register_operand")
553    (match_operand:SIDI 2 "register_operand")
554    (match_operand 3 "")]
555   "TARGET_32BIT"
557   emit_insn (gen_add<mode>3_compareV (operands[0], operands[1], operands[2]));
558   arm_gen_unlikely_cbranch (NE, CC_Vmode, operands[3]);
560   DONE;
563 (define_expand "uaddv<mode>4"
564   [(match_operand:SIDI 0 "register_operand")
565    (match_operand:SIDI 1 "register_operand")
566    (match_operand:SIDI 2 "register_operand")
567    (match_operand 3 "")]
568   "TARGET_32BIT"
570   emit_insn (gen_add<mode>3_compareC (operands[0], operands[1], operands[2]));
571   arm_gen_unlikely_cbranch (NE, CC_Cmode, operands[3]);
573   DONE;
576 (define_expand "addsi3"
577   [(set (match_operand:SI          0 "s_register_operand" "")
578         (plus:SI (match_operand:SI 1 "s_register_operand" "")
579                  (match_operand:SI 2 "reg_or_int_operand" "")))]
580   "TARGET_EITHER"
581   "
582   if (TARGET_32BIT && CONST_INT_P (operands[2]))
583     {
584       arm_split_constant (PLUS, SImode, NULL_RTX,
585                           INTVAL (operands[2]), operands[0], operands[1],
586                           optimize && can_create_pseudo_p ());
587       DONE;
588     }
589   "
592 ; If there is a scratch available, this will be faster than synthesizing the
593 ; addition.
594 (define_peephole2
595   [(match_scratch:SI 3 "r")
596    (set (match_operand:SI          0 "arm_general_register_operand" "")
597         (plus:SI (match_operand:SI 1 "arm_general_register_operand" "")
598                  (match_operand:SI 2 "const_int_operand"  "")))]
599   "TARGET_32BIT &&
600    !(const_ok_for_arm (INTVAL (operands[2]))
601      || const_ok_for_arm (-INTVAL (operands[2])))
602     && const_ok_for_arm (~INTVAL (operands[2]))"
603   [(set (match_dup 3) (match_dup 2))
604    (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 3)))]
605   ""
608 ;; The r/r/k alternative is required when reloading the address
609 ;;  (plus (reg rN) (reg sp)) into (reg rN).  In this case reload will
610 ;; put the duplicated register first, and not try the commutative version.
611 (define_insn_and_split "*arm_addsi3"
612   [(set (match_operand:SI          0 "s_register_operand" "=rk,l,l ,l ,r ,k ,r,r ,k ,r ,k,k,r ,k ,r")
613         (plus:SI (match_operand:SI 1 "s_register_operand" "%0 ,l,0 ,l ,rk,k ,r,rk,k ,rk,k,r,rk,k ,rk")
614                  (match_operand:SI 2 "reg_or_int_operand" "rk ,l,Py,Pd,rI,rI,k,Pj,Pj,L ,L,L,PJ,PJ,?n")))]
615   "TARGET_32BIT"
616   "@
617    add%?\\t%0, %0, %2
618    add%?\\t%0, %1, %2
619    add%?\\t%0, %1, %2
620    add%?\\t%0, %1, %2
621    add%?\\t%0, %1, %2
622    add%?\\t%0, %1, %2
623    add%?\\t%0, %2, %1
624    addw%?\\t%0, %1, %2
625    addw%?\\t%0, %1, %2
626    sub%?\\t%0, %1, #%n2
627    sub%?\\t%0, %1, #%n2
628    sub%?\\t%0, %1, #%n2
629    subw%?\\t%0, %1, #%n2
630    subw%?\\t%0, %1, #%n2
631    #"
632   "TARGET_32BIT
633    && CONST_INT_P (operands[2])
634    && !const_ok_for_op (INTVAL (operands[2]), PLUS)
635    && (reload_completed || !arm_eliminable_register (operands[1]))"
636   [(clobber (const_int 0))]
637   "
638   arm_split_constant (PLUS, SImode, curr_insn,
639                       INTVAL (operands[2]), operands[0],
640                       operands[1], 0);
641   DONE;
642   "
643   [(set_attr "length" "2,4,4,4,4,4,4,4,4,4,4,4,4,4,16")
644    (set_attr "predicable" "yes")
645    (set_attr "predicable_short_it" "yes,yes,yes,yes,no,no,no,no,no,no,no,no,no,no,no")
646    (set_attr "arch" "t2,t2,t2,t2,*,*,*,t2,t2,*,*,a,t2,t2,*")
647    (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
648                       (const_string "alu_imm")
649                       (const_string "alu_sreg")))
653 (define_insn_and_split "adddi3_compareV"
654   [(set (reg:CC_V CC_REGNUM)
655         (ne:CC_V
656           (plus:TI
657             (sign_extend:TI (match_operand:DI 1 "register_operand" "r"))
658             (sign_extend:TI (match_operand:DI 2 "register_operand" "r")))
659           (sign_extend:TI (plus:DI (match_dup 1) (match_dup 2)))))
660    (set (match_operand:DI 0 "register_operand" "=&r")
661         (plus:DI (match_dup 1) (match_dup 2)))]
662   "TARGET_32BIT"
663   "#"
664   "&& reload_completed"
665   [(parallel [(set (reg:CC_C CC_REGNUM)
666                    (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
667                                  (match_dup 1)))
668               (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
669    (parallel [(set (reg:CC_V CC_REGNUM)
670                    (ne:CC_V
671                     (plus:DI (plus:DI
672                               (sign_extend:DI (match_dup 4))
673                               (sign_extend:DI (match_dup 5)))
674                              (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0)))
675                     (plus:DI (sign_extend:DI
676                               (plus:SI (match_dup 4) (match_dup 5)))
677                              (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0)))))
678              (set (match_dup 3) (plus:SI (plus:SI
679                                           (match_dup 4) (match_dup 5))
680                                          (ltu:SI (reg:CC_C CC_REGNUM)
681                                                  (const_int 0))))])]
682   "
683   {
684     operands[3] = gen_highpart (SImode, operands[0]);
685     operands[0] = gen_lowpart (SImode, operands[0]);
686     operands[4] = gen_highpart (SImode, operands[1]);
687     operands[1] = gen_lowpart (SImode, operands[1]);
688     operands[5] = gen_highpart (SImode, operands[2]);
689     operands[2] = gen_lowpart (SImode, operands[2]);
690   }"
691  [(set_attr "conds" "set")
692    (set_attr "length" "8")
693    (set_attr "type" "multiple")]
696 (define_insn "addsi3_compareV"
697   [(set (reg:CC_V CC_REGNUM)
698         (ne:CC_V
699           (plus:DI
700             (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
701             (sign_extend:DI (match_operand:SI 2 "register_operand" "r")))
702           (sign_extend:DI (plus:SI (match_dup 1) (match_dup 2)))))
703    (set (match_operand:SI 0 "register_operand" "=r")
704         (plus:SI (match_dup 1) (match_dup 2)))]
705   "TARGET_32BIT"
706   "adds%?\\t%0, %1, %2"
707   [(set_attr "conds" "set")
708    (set_attr "type" "alus_sreg")]
711 (define_insn "*addsi3_compareV_upper"
712   [(set (reg:CC_V CC_REGNUM)
713         (ne:CC_V
714           (plus:DI
715            (plus:DI
716             (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
717             (sign_extend:DI (match_operand:SI 2 "register_operand" "r")))
718            (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0)))
719           (plus:DI (sign_extend:DI
720                     (plus:SI (match_dup 1) (match_dup 2)))
721                    (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0)))))
722    (set (match_operand:SI 0 "register_operand" "=r")
723         (plus:SI
724          (plus:SI (match_dup 1) (match_dup 2))
725          (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
726   "TARGET_32BIT"
727   "adcs%?\\t%0, %1, %2"
728   [(set_attr "conds" "set")
729    (set_attr "type" "adcs_reg")]
732 (define_insn_and_split "adddi3_compareC"
733   [(set (reg:CC_C CC_REGNUM)
734         (ne:CC_C
735           (plus:TI
736             (zero_extend:TI (match_operand:DI 1 "register_operand" "r"))
737             (zero_extend:TI (match_operand:DI 2 "register_operand" "r")))
738           (zero_extend:TI (plus:DI (match_dup 1) (match_dup 2)))))
739    (set (match_operand:DI 0 "register_operand" "=&r")
740         (plus:DI (match_dup 1) (match_dup 2)))]
741   "TARGET_32BIT"
742   "#"
743   "&& reload_completed"
744   [(parallel [(set (reg:CC_C CC_REGNUM)
745                    (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
746                                  (match_dup 1)))
747               (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
748    (parallel [(set (reg:CC_C CC_REGNUM)
749                    (ne:CC_C
750                     (plus:DI (plus:DI
751                               (zero_extend:DI (match_dup 4))
752                               (zero_extend:DI (match_dup 5)))
753                              (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0)))
754                     (plus:DI (zero_extend:DI
755                               (plus:SI (match_dup 4) (match_dup 5)))
756                              (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0)))))
757              (set (match_dup 3) (plus:SI
758                                  (plus:SI (match_dup 4) (match_dup 5))
759                                  (ltu:SI (reg:CC_C CC_REGNUM)
760                                          (const_int 0))))])]
761   "
762   {
763     operands[3] = gen_highpart (SImode, operands[0]);
764     operands[0] = gen_lowpart (SImode, operands[0]);
765     operands[4] = gen_highpart (SImode, operands[1]);
766     operands[5] = gen_highpart (SImode, operands[2]);
767     operands[1] = gen_lowpart (SImode, operands[1]);
768     operands[2] = gen_lowpart (SImode, operands[2]);
769   }"
770  [(set_attr "conds" "set")
771    (set_attr "length" "8")
772    (set_attr "type" "multiple")]
775 (define_insn "*addsi3_compareC_upper"
776   [(set (reg:CC_C CC_REGNUM)
777         (ne:CC_C
778           (plus:DI
779            (plus:DI
780             (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
781             (zero_extend:DI (match_operand:SI 2 "register_operand" "r")))
782            (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0)))
783           (plus:DI (zero_extend:DI
784                     (plus:SI (match_dup 1) (match_dup 2)))
785                    (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0)))))
786    (set (match_operand:SI 0 "register_operand" "=r")
787         (plus:SI
788          (plus:SI (match_dup 1) (match_dup 2))
789          (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
790   "TARGET_32BIT"
791   "adcs%?\\t%0, %1, %2"
792   [(set_attr "conds" "set")
793    (set_attr "type" "adcs_reg")]
796 (define_insn "addsi3_compareC"
797    [(set (reg:CC_C CC_REGNUM)
798          (ne:CC_C
799           (plus:DI
800            (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
801            (zero_extend:DI (match_operand:SI 2 "register_operand" "r")))
802           (zero_extend:DI
803            (plus:SI (match_dup 1) (match_dup 2)))))
804     (set (match_operand:SI 0 "register_operand" "=r")
805          (plus:SI (match_dup 1) (match_dup 2)))]
806   "TARGET_32BIT"
807   "adds%?\\t%0, %1, %2"
808   [(set_attr "conds" "set")
809    (set_attr "type" "alus_sreg")]
812 (define_insn "addsi3_compare0"
813   [(set (reg:CC_NOOV CC_REGNUM)
814         (compare:CC_NOOV
815          (plus:SI (match_operand:SI 1 "s_register_operand" "r, r,r")
816                   (match_operand:SI 2 "arm_add_operand"    "I,L,r"))
817          (const_int 0)))
818    (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
819         (plus:SI (match_dup 1) (match_dup 2)))]
820   "TARGET_ARM"
821   "@
822    adds%?\\t%0, %1, %2
823    subs%?\\t%0, %1, #%n2
824    adds%?\\t%0, %1, %2"
825   [(set_attr "conds" "set")
826    (set_attr "type" "alus_imm,alus_imm,alus_sreg")]
829 (define_insn "*addsi3_compare0_scratch"
830   [(set (reg:CC_NOOV CC_REGNUM)
831         (compare:CC_NOOV
832          (plus:SI (match_operand:SI 0 "s_register_operand" "r, r, r")
833                   (match_operand:SI 1 "arm_add_operand"    "I,L, r"))
834          (const_int 0)))]
835   "TARGET_ARM"
836   "@
837    cmn%?\\t%0, %1
838    cmp%?\\t%0, #%n1
839    cmn%?\\t%0, %1"
840   [(set_attr "conds" "set")
841    (set_attr "predicable" "yes")
842    (set_attr "type" "alus_imm,alus_imm,alus_sreg")]
845 (define_insn "*compare_negsi_si"
846   [(set (reg:CC_Z CC_REGNUM)
847         (compare:CC_Z
848          (neg:SI (match_operand:SI 0 "s_register_operand" "l,r"))
849          (match_operand:SI 1 "s_register_operand" "l,r")))]
850   "TARGET_32BIT"
851   "cmn%?\\t%1, %0"
852   [(set_attr "conds" "set")
853    (set_attr "predicable" "yes")
854    (set_attr "arch" "t2,*")
855    (set_attr "length" "2,4")
856    (set_attr "predicable_short_it" "yes,no")
857    (set_attr "type" "alus_sreg")]
860 ;; This is the canonicalization of addsi3_compare0_for_combiner when the
861 ;; addend is a constant.
862 (define_insn "cmpsi2_addneg"
863   [(set (reg:CC CC_REGNUM)
864         (compare:CC
865          (match_operand:SI 1 "s_register_operand" "r,r")
866          (match_operand:SI 2 "arm_addimm_operand" "L,I")))
867    (set (match_operand:SI 0 "s_register_operand" "=r,r")
868         (plus:SI (match_dup 1)
869                  (match_operand:SI 3 "arm_addimm_operand" "I,L")))]
870   "TARGET_32BIT && INTVAL (operands[2]) == -INTVAL (operands[3])"
871   "@
872    adds%?\\t%0, %1, %3
873    subs%?\\t%0, %1, #%n3"
874   [(set_attr "conds" "set")
875    (set_attr "type" "alus_sreg")]
878 ;; Convert the sequence
879 ;;  sub  rd, rn, #1
880 ;;  cmn  rd, #1 (equivalent to cmp rd, #-1)
881 ;;  bne  dest
882 ;; into
883 ;;  subs rd, rn, #1
884 ;;  bcs  dest   ((unsigned)rn >= 1)
885 ;; similarly for the beq variant using bcc.
886 ;; This is a common looping idiom (while (n--))
887 (define_peephole2
888   [(set (match_operand:SI 0 "arm_general_register_operand" "")
889         (plus:SI (match_operand:SI 1 "arm_general_register_operand" "")
890                  (const_int -1)))
891    (set (match_operand 2 "cc_register" "")
892         (compare (match_dup 0) (const_int -1)))
893    (set (pc)
894         (if_then_else (match_operator 3 "equality_operator"
895                        [(match_dup 2) (const_int 0)])
896                       (match_operand 4 "" "")
897                       (match_operand 5 "" "")))]
898   "TARGET_32BIT && peep2_reg_dead_p (3, operands[2])"
899   [(parallel[
900     (set (match_dup 2)
901          (compare:CC
902           (match_dup 1) (const_int 1)))
903     (set (match_dup 0) (plus:SI (match_dup 1) (const_int -1)))])
904    (set (pc)
905         (if_then_else (match_op_dup 3 [(match_dup 2) (const_int 0)])
906                       (match_dup 4)
907                       (match_dup 5)))]
908   "operands[2] = gen_rtx_REG (CCmode, CC_REGNUM);
909    operands[3] = gen_rtx_fmt_ee ((GET_CODE (operands[3]) == NE
910                                   ? GEU : LTU),
911                                  VOIDmode, 
912                                  operands[2], const0_rtx);"
915 ;; The next four insns work because they compare the result with one of
916 ;; the operands, and we know that the use of the condition code is
917 ;; either GEU or LTU, so we can use the carry flag from the addition
918 ;; instead of doing the compare a second time.
919 (define_insn "*addsi3_compare_op1"
920   [(set (reg:CC_C CC_REGNUM)
921         (compare:CC_C
922          (plus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
923                   (match_operand:SI 2 "arm_add_operand" "I,L,r"))
924          (match_dup 1)))
925    (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
926         (plus:SI (match_dup 1) (match_dup 2)))]
927   "TARGET_32BIT"
928   "@
929    adds%?\\t%0, %1, %2
930    subs%?\\t%0, %1, #%n2
931    adds%?\\t%0, %1, %2"
932   [(set_attr "conds" "set")
933    (set_attr "type"  "alus_imm,alus_imm,alus_sreg")]
936 (define_insn "*addsi3_compare_op2"
937   [(set (reg:CC_C CC_REGNUM)
938         (compare:CC_C
939          (plus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
940                   (match_operand:SI 2 "arm_add_operand" "I,L,r"))
941          (match_dup 2)))
942    (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
943         (plus:SI (match_dup 1) (match_dup 2)))]
944   "TARGET_32BIT"
945   "@
946    adds%?\\t%0, %1, %2
947    subs%?\\t%0, %1, #%n2
948    adds%?\\t%0, %1, %2"
949   [(set_attr "conds" "set")
950    (set_attr "type" "alus_imm,alus_imm,alus_sreg")]
953 (define_insn "*compare_addsi2_op0"
954   [(set (reg:CC_C CC_REGNUM)
955         (compare:CC_C
956           (plus:SI (match_operand:SI 0 "s_register_operand" "l,l,r,r,r")
957                    (match_operand:SI 1 "arm_add_operand" "Pv,l,I,L,r"))
958           (match_dup 0)))]
959   "TARGET_32BIT"
960   "@
961    cmp%?\\t%0, #%n1
962    cmn%?\\t%0, %1
963    cmn%?\\t%0, %1
964    cmp%?\\t%0, #%n1
965    cmn%?\\t%0, %1"
966   [(set_attr "conds" "set")
967    (set_attr "predicable" "yes")
968    (set_attr "arch" "t2,t2,*,*,*")
969    (set_attr "predicable_short_it" "yes,yes,no,no,no")
970    (set_attr "length" "2,2,4,4,4")
971    (set_attr "type" "alus_imm,alus_sreg,alus_imm,alus_imm,alus_sreg")]
974 (define_insn "*compare_addsi2_op1"
975   [(set (reg:CC_C CC_REGNUM)
976         (compare:CC_C
977           (plus:SI (match_operand:SI 0 "s_register_operand" "l,l,r,r,r")
978                    (match_operand:SI 1 "arm_add_operand" "Pv,l,I,L,r"))
979           (match_dup 1)))]
980   "TARGET_32BIT"
981   "@
982    cmp%?\\t%0, #%n1
983    cmn%?\\t%0, %1
984    cmn%?\\t%0, %1
985    cmp%?\\t%0, #%n1
986    cmn%?\\t%0, %1"
987   [(set_attr "conds" "set")
988    (set_attr "predicable" "yes")
989    (set_attr "arch" "t2,t2,*,*,*")
990    (set_attr "predicable_short_it" "yes,yes,no,no,no")
991    (set_attr "length" "2,2,4,4,4")
992    (set_attr "type" "alus_imm,alus_sreg,alus_imm,alus_imm,alus_sreg")]
995 (define_insn "*addsi3_carryin_<optab>"
996   [(set (match_operand:SI 0 "s_register_operand" "=l,r,r")
997         (plus:SI (plus:SI (match_operand:SI 1 "s_register_operand" "%l,r,r")
998                           (match_operand:SI 2 "arm_not_operand" "0,rI,K"))
999                  (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))))]
1000   "TARGET_32BIT"
1001   "@
1002    adc%?\\t%0, %1, %2
1003    adc%?\\t%0, %1, %2
1004    sbc%?\\t%0, %1, #%B2"
1005   [(set_attr "conds" "use")
1006    (set_attr "predicable" "yes")
1007    (set_attr "arch" "t2,*,*")
1008    (set_attr "length" "4")
1009    (set_attr "predicable_short_it" "yes,no,no")
1010    (set_attr "type" "adc_reg,adc_reg,adc_imm")]
1013 (define_insn "*addsi3_carryin_alt2_<optab>"
1014   [(set (match_operand:SI 0 "s_register_operand" "=l,r,r")
1015         (plus:SI (plus:SI (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))
1016                           (match_operand:SI 1 "s_register_operand" "%l,r,r"))
1017                  (match_operand:SI 2 "arm_rhs_operand" "l,rI,K")))]
1018   "TARGET_32BIT"
1019   "@
1020    adc%?\\t%0, %1, %2
1021    adc%?\\t%0, %1, %2
1022    sbc%?\\t%0, %1, #%B2"
1023   [(set_attr "conds" "use")
1024    (set_attr "predicable" "yes")
1025    (set_attr "arch" "t2,*,*")
1026    (set_attr "length" "4")
1027    (set_attr "predicable_short_it" "yes,no,no")
1028    (set_attr "type" "adc_reg,adc_reg,adc_imm")]
1031 (define_insn "*addsi3_carryin_shift_<optab>"
1032   [(set (match_operand:SI 0 "s_register_operand" "=r")
1033         (plus:SI (plus:SI
1034                   (match_operator:SI 2 "shift_operator"
1035                     [(match_operand:SI 3 "s_register_operand" "r")
1036                      (match_operand:SI 4 "reg_or_int_operand" "rM")])
1037                   (match_operand:SI 1 "s_register_operand" "r"))
1038                  (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))))]
1039   "TARGET_32BIT"
1040   "adc%?\\t%0, %1, %3%S2"
1041   [(set_attr "conds" "use")
1042    (set_attr "predicable" "yes")
1043    (set_attr "predicable_short_it" "no")
1044    (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
1045                       (const_string "alu_shift_imm")
1046                       (const_string "alu_shift_reg")))]
1049 (define_insn "*addsi3_carryin_clobercc_<optab>"
1050   [(set (match_operand:SI 0 "s_register_operand" "=r")
1051         (plus:SI (plus:SI (match_operand:SI 1 "s_register_operand" "%r")
1052                           (match_operand:SI 2 "arm_rhs_operand" "rI"))
1053                  (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))))
1054    (clobber (reg:CC CC_REGNUM))]
1055    "TARGET_32BIT"
1056    "adcs%?\\t%0, %1, %2"
1057    [(set_attr "conds" "set")
1058     (set_attr "type" "adcs_reg")]
1061 (define_expand "subv<mode>4"
1062   [(match_operand:SIDI 0 "register_operand")
1063    (match_operand:SIDI 1 "register_operand")
1064    (match_operand:SIDI 2 "register_operand")
1065    (match_operand 3 "")]
1066   "TARGET_32BIT"
1068   emit_insn (gen_sub<mode>3_compare1 (operands[0], operands[1], operands[2]));
1069   arm_gen_unlikely_cbranch (NE, CC_Vmode, operands[3]);
1071   DONE;
1074 (define_expand "usubv<mode>4"
1075   [(match_operand:SIDI 0 "register_operand")
1076    (match_operand:SIDI 1 "register_operand")
1077    (match_operand:SIDI 2 "register_operand")
1078    (match_operand 3 "")]
1079   "TARGET_32BIT"
1081   emit_insn (gen_sub<mode>3_compare1 (operands[0], operands[1], operands[2]));
1082   arm_gen_unlikely_cbranch (LTU, CCmode, operands[3]);
1084   DONE;
1087 (define_insn_and_split "subdi3_compare1"
1088   [(set (reg:CC CC_REGNUM)
1089         (compare:CC
1090           (match_operand:DI 1 "register_operand" "r")
1091           (match_operand:DI 2 "register_operand" "r")))
1092    (set (match_operand:DI 0 "register_operand" "=&r")
1093         (minus:DI (match_dup 1) (match_dup 2)))]
1094   "TARGET_32BIT"
1095   "#"
1096   "&& reload_completed"
1097   [(parallel [(set (reg:CC CC_REGNUM)
1098                    (compare:CC (match_dup 1) (match_dup 2)))
1099               (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1100    (parallel [(set (reg:CC CC_REGNUM)
1101                    (compare:CC (match_dup 4) (match_dup 5)))
1102              (set (match_dup 3) (minus:SI (minus:SI (match_dup 4) (match_dup 5))
1103                                (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))])]
1104   {
1105     operands[3] = gen_highpart (SImode, operands[0]);
1106     operands[0] = gen_lowpart (SImode, operands[0]);
1107     operands[4] = gen_highpart (SImode, operands[1]);
1108     operands[1] = gen_lowpart (SImode, operands[1]);
1109     operands[5] = gen_highpart (SImode, operands[2]);
1110     operands[2] = gen_lowpart (SImode, operands[2]);
1111    }
1112   [(set_attr "conds" "set")
1113    (set_attr "length" "8")
1114    (set_attr "type" "multiple")]
1117 (define_insn "subsi3_compare1"
1118   [(set (reg:CC CC_REGNUM)
1119         (compare:CC
1120           (match_operand:SI 1 "register_operand" "r")
1121           (match_operand:SI 2 "register_operand" "r")))
1122    (set (match_operand:SI 0 "register_operand" "=r")
1123         (minus:SI (match_dup 1) (match_dup 2)))]
1124   "TARGET_32BIT"
1125   "subs%?\\t%0, %1, %2"
1126   [(set_attr "conds" "set")
1127    (set_attr "type" "alus_sreg")]
1130 (define_insn "*subsi3_carryin"
1131   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
1132         (minus:SI (minus:SI (match_operand:SI 1 "reg_or_int_operand" "r,I")
1133                             (match_operand:SI 2 "s_register_operand" "r,r"))
1134                   (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1135   "TARGET_32BIT"
1136   "@
1137    sbc%?\\t%0, %1, %2
1138    rsc%?\\t%0, %2, %1"
1139   [(set_attr "conds" "use")
1140    (set_attr "arch" "*,a")
1141    (set_attr "predicable" "yes")
1142    (set_attr "predicable_short_it" "no")
1143    (set_attr "type" "adc_reg,adc_imm")]
1146 (define_insn "*subsi3_carryin_const"
1147   [(set (match_operand:SI 0 "s_register_operand" "=r")
1148         (minus:SI (plus:SI (match_operand:SI 1 "s_register_operand" "r")
1149                            (match_operand:SI 2 "arm_not_immediate_operand" "K"))
1150                   (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1151   "TARGET_32BIT"
1152   "sbc\\t%0, %1, #%B2"
1153   [(set_attr "conds" "use")
1154    (set_attr "type" "adc_imm")]
1157 (define_insn "*subsi3_carryin_compare"
1158   [(set (reg:CC CC_REGNUM)
1159         (compare:CC (match_operand:SI 1 "s_register_operand" "r")
1160                     (match_operand:SI 2 "s_register_operand" "r")))
1161    (set (match_operand:SI 0 "s_register_operand" "=r")
1162         (minus:SI (minus:SI (match_dup 1)
1163                             (match_dup 2))
1164                   (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1165   "TARGET_32BIT"
1166   "sbcs\\t%0, %1, %2"
1167   [(set_attr "conds" "set")
1168    (set_attr "type" "adcs_reg")]
1171 (define_insn "*subsi3_carryin_compare_const"
1172   [(set (reg:CC CC_REGNUM)
1173         (compare:CC (match_operand:SI 1 "reg_or_int_operand" "r")
1174                     (match_operand:SI 2 "arm_not_operand" "K")))
1175    (set (match_operand:SI 0 "s_register_operand" "=r")
1176         (minus:SI (plus:SI (match_dup 1)
1177                            (match_dup 2))
1178                   (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1179   "TARGET_32BIT"
1180   "sbcs\\t%0, %1, #%B2"
1181   [(set_attr "conds" "set")
1182    (set_attr "type" "adcs_imm")]
1185 (define_insn "*subsi3_carryin_shift"
1186   [(set (match_operand:SI 0 "s_register_operand" "=r")
1187         (minus:SI (minus:SI
1188                   (match_operand:SI 1 "s_register_operand" "r")
1189                   (match_operator:SI 2 "shift_operator"
1190                    [(match_operand:SI 3 "s_register_operand" "r")
1191                     (match_operand:SI 4 "reg_or_int_operand" "rM")]))
1192                  (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1193   "TARGET_32BIT"
1194   "sbc%?\\t%0, %1, %3%S2"
1195   [(set_attr "conds" "use")
1196    (set_attr "predicable" "yes")
1197    (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
1198                       (const_string "alu_shift_imm")
1199                      (const_string "alu_shift_reg")))]
1202 (define_insn "*rsbsi3_carryin_shift"
1203   [(set (match_operand:SI 0 "s_register_operand" "=r")
1204         (minus:SI (minus:SI
1205                   (match_operator:SI 2 "shift_operator"
1206                    [(match_operand:SI 3 "s_register_operand" "r")
1207                     (match_operand:SI 4 "reg_or_int_operand" "rM")])
1208                    (match_operand:SI 1 "s_register_operand" "r"))
1209                  (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1210   "TARGET_ARM"
1211   "rsc%?\\t%0, %1, %3%S2"
1212   [(set_attr "conds" "use")
1213    (set_attr "predicable" "yes")
1214    (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
1215                       (const_string "alu_shift_imm")
1216                       (const_string "alu_shift_reg")))]
1219 ; transform ((x << y) - 1) to ~(~(x-1) << y)  Where X is a constant.
1220 (define_split
1221   [(set (match_operand:SI 0 "s_register_operand" "")
1222         (plus:SI (ashift:SI (match_operand:SI 1 "const_int_operand" "")
1223                             (match_operand:SI 2 "s_register_operand" ""))
1224                  (const_int -1)))
1225    (clobber (match_operand:SI 3 "s_register_operand" ""))]
1226   "TARGET_32BIT"
1227   [(set (match_dup 3) (match_dup 1))
1228    (set (match_dup 0) (not:SI (ashift:SI (match_dup 3) (match_dup 2))))]
1229   "
1230   operands[1] = GEN_INT (~(INTVAL (operands[1]) - 1));
1233 (define_expand "addsf3"
1234   [(set (match_operand:SF          0 "s_register_operand" "")
1235         (plus:SF (match_operand:SF 1 "s_register_operand" "")
1236                  (match_operand:SF 2 "s_register_operand" "")))]
1237   "TARGET_32BIT && TARGET_HARD_FLOAT"
1238   "
1241 (define_expand "adddf3"
1242   [(set (match_operand:DF          0 "s_register_operand" "")
1243         (plus:DF (match_operand:DF 1 "s_register_operand" "")
1244                  (match_operand:DF 2 "s_register_operand" "")))]
1245   "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
1246   "
1249 (define_expand "subdi3"
1250  [(parallel
1251    [(set (match_operand:DI            0 "s_register_operand" "")
1252           (minus:DI (match_operand:DI 1 "s_register_operand" "")
1253                     (match_operand:DI 2 "s_register_operand" "")))
1254     (clobber (reg:CC CC_REGNUM))])]
1255   "TARGET_EITHER"
1256   "
1257   if (TARGET_THUMB1)
1258     {
1259       if (!REG_P (operands[1]))
1260         operands[1] = force_reg (DImode, operands[1]);
1261       if (!REG_P (operands[2]))
1262         operands[2] = force_reg (DImode, operands[2]);
1263      }  
1264   "
1267 (define_insn_and_split "*arm_subdi3"
1268   [(set (match_operand:DI           0 "s_register_operand" "=&r,&r,&r")
1269         (minus:DI (match_operand:DI 1 "s_register_operand" "0,r,0")
1270                   (match_operand:DI 2 "s_register_operand" "r,0,0")))
1271    (clobber (reg:CC CC_REGNUM))]
1272   "TARGET_32BIT && !TARGET_NEON"
1273   "#"  ; "subs\\t%Q0, %Q1, %Q2\;sbc\\t%R0, %R1, %R2"
1274   "&& reload_completed"
1275   [(parallel [(set (reg:CC CC_REGNUM)
1276                    (compare:CC (match_dup 1) (match_dup 2)))
1277               (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1278    (set (match_dup 3) (minus:SI (minus:SI (match_dup 4) (match_dup 5))
1279                                (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1280   {
1281     operands[3] = gen_highpart (SImode, operands[0]);
1282     operands[0] = gen_lowpart (SImode, operands[0]);
1283     operands[4] = gen_highpart (SImode, operands[1]);
1284     operands[1] = gen_lowpart (SImode, operands[1]);
1285     operands[5] = gen_highpart (SImode, operands[2]);
1286     operands[2] = gen_lowpart (SImode, operands[2]);
1287    }
1288   [(set_attr "conds" "clob")
1289    (set_attr "length" "8")
1290    (set_attr "type" "multiple")]
1293 (define_insn_and_split "*subdi_di_zesidi"
1294   [(set (match_operand:DI           0 "s_register_operand" "=&r,&r")
1295         (minus:DI (match_operand:DI 1 "s_register_operand"  "0,r")
1296                   (zero_extend:DI
1297                    (match_operand:SI 2 "s_register_operand"  "r,r"))))
1298    (clobber (reg:CC CC_REGNUM))]
1299   "TARGET_32BIT"
1300   "#"   ; "subs\\t%Q0, %Q1, %2\;sbc\\t%R0, %R1, #0"
1301   "&& reload_completed"
1302   [(parallel [(set (reg:CC CC_REGNUM)
1303                    (compare:CC (match_dup 1) (match_dup 2)))
1304               (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1305    (set (match_dup 3) (minus:SI (plus:SI (match_dup 4) (match_dup 5))
1306                                 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1307   {
1308     operands[3] = gen_highpart (SImode, operands[0]);
1309     operands[0] = gen_lowpart (SImode, operands[0]);
1310     operands[4] = gen_highpart (SImode, operands[1]);
1311     operands[1] = gen_lowpart (SImode, operands[1]);
1312     operands[5] = GEN_INT (~0);
1313    }
1314   [(set_attr "conds" "clob")
1315    (set_attr "length" "8")
1316    (set_attr "type" "multiple")]
1319 (define_insn_and_split "*subdi_di_sesidi"
1320   [(set (match_operand:DI            0 "s_register_operand" "=&r,&r")
1321         (minus:DI (match_operand:DI  1 "s_register_operand"  "0,r")
1322                   (sign_extend:DI
1323                    (match_operand:SI 2 "s_register_operand"  "r,r"))))
1324    (clobber (reg:CC CC_REGNUM))]
1325   "TARGET_32BIT"
1326   "#"   ; "subs\\t%Q0, %Q1, %2\;sbc\\t%R0, %R1, %2, asr #31"
1327   "&& reload_completed"
1328   [(parallel [(set (reg:CC CC_REGNUM)
1329                    (compare:CC (match_dup 1) (match_dup 2)))
1330               (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1331    (set (match_dup 3) (minus:SI (minus:SI (match_dup 4)
1332                                          (ashiftrt:SI (match_dup 2)
1333                                                       (const_int 31)))
1334                                 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1335   {
1336     operands[3] = gen_highpart (SImode, operands[0]);
1337     operands[0] = gen_lowpart (SImode, operands[0]);
1338     operands[4] = gen_highpart (SImode, operands[1]);
1339     operands[1] = gen_lowpart (SImode, operands[1]);
1340   }
1341   [(set_attr "conds" "clob")
1342    (set_attr "length" "8")
1343    (set_attr "type" "multiple")]
1346 (define_insn_and_split "*subdi_zesidi_di"
1347   [(set (match_operand:DI            0 "s_register_operand" "=&r,&r")
1348         (minus:DI (zero_extend:DI
1349                    (match_operand:SI 2 "s_register_operand"  "r,r"))
1350                   (match_operand:DI  1 "s_register_operand" "0,r")))
1351    (clobber (reg:CC CC_REGNUM))]
1352   "TARGET_ARM"
1353   "#"   ; "rsbs\\t%Q0, %Q1, %2\;rsc\\t%R0, %R1, #0"
1354         ; is equivalent to:
1355         ; "subs\\t%Q0, %2, %Q1\;rsc\\t%R0, %R1, #0"
1356   "&& reload_completed"
1357   [(parallel [(set (reg:CC CC_REGNUM)
1358                    (compare:CC (match_dup 2) (match_dup 1)))
1359               (set (match_dup 0) (minus:SI (match_dup 2) (match_dup 1)))])
1360    (set (match_dup 3) (minus:SI (minus:SI (const_int 0) (match_dup 4))
1361                                (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1362   {
1363     operands[3] = gen_highpart (SImode, operands[0]);
1364     operands[0] = gen_lowpart (SImode, operands[0]);
1365     operands[4] = gen_highpart (SImode, operands[1]);
1366     operands[1] = gen_lowpart (SImode, operands[1]);
1367   }
1368   [(set_attr "conds" "clob")
1369    (set_attr "length" "8")
1370    (set_attr "type" "multiple")]
1373 (define_insn_and_split "*subdi_sesidi_di"
1374   [(set (match_operand:DI            0 "s_register_operand" "=&r,&r")
1375         (minus:DI (sign_extend:DI
1376                    (match_operand:SI 2 "s_register_operand"   "r,r"))
1377                   (match_operand:DI  1 "s_register_operand"  "0,r")))
1378    (clobber (reg:CC CC_REGNUM))]
1379   "TARGET_ARM"
1380   "#"   ; "rsbs\\t%Q0, %Q1, %2\;rsc\\t%R0, %R1, %2, asr #31"
1381         ; is equivalent to:
1382         ; "subs\\t%Q0, %2, %Q1\;rsc\\t%R0, %R1, %2, asr #31"
1383   "&& reload_completed"
1384   [(parallel [(set (reg:CC CC_REGNUM)
1385                    (compare:CC (match_dup 2) (match_dup 1)))
1386               (set (match_dup 0) (minus:SI (match_dup 2) (match_dup 1)))])
1387    (set (match_dup 3) (minus:SI (minus:SI
1388                                 (ashiftrt:SI (match_dup 2)
1389                                              (const_int 31))
1390                                 (match_dup 4))
1391                                (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1392   {
1393     operands[3] = gen_highpart (SImode, operands[0]);
1394     operands[0] = gen_lowpart (SImode, operands[0]);
1395     operands[4] = gen_highpart (SImode, operands[1]);
1396     operands[1] = gen_lowpart (SImode, operands[1]);
1397   }
1398   [(set_attr "conds" "clob")
1399    (set_attr "length" "8")
1400    (set_attr "type" "multiple")]
1403 (define_insn_and_split "*subdi_zesidi_zesidi"
1404   [(set (match_operand:DI            0 "s_register_operand" "=r")
1405         (minus:DI (zero_extend:DI
1406                    (match_operand:SI 1 "s_register_operand"  "r"))
1407                   (zero_extend:DI
1408                    (match_operand:SI 2 "s_register_operand"  "r"))))
1409    (clobber (reg:CC CC_REGNUM))]
1410   "TARGET_32BIT"
1411   "#"   ; "subs\\t%Q0, %1, %2\;sbc\\t%R0, %1, %1"
1412   "&& reload_completed"
1413   [(parallel [(set (reg:CC CC_REGNUM)
1414                    (compare:CC (match_dup 1) (match_dup 2)))
1415               (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1416    (set (match_dup 3) (minus:SI (minus:SI (match_dup 1) (match_dup 1))
1417                                (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1418   {
1419        operands[3] = gen_highpart (SImode, operands[0]);
1420        operands[0] = gen_lowpart (SImode, operands[0]);
1421   }
1422   [(set_attr "conds" "clob")
1423    (set_attr "length" "8")
1424    (set_attr "type" "multiple")]
1427 (define_expand "subsi3"
1428   [(set (match_operand:SI           0 "s_register_operand" "")
1429         (minus:SI (match_operand:SI 1 "reg_or_int_operand" "")
1430                   (match_operand:SI 2 "s_register_operand" "")))]
1431   "TARGET_EITHER"
1432   "
1433   if (CONST_INT_P (operands[1]))
1434     {
1435       if (TARGET_32BIT)
1436         {
1437           if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[1]), MINUS))
1438             operands[1] = force_reg (SImode, operands[1]);
1439           else
1440             {
1441               arm_split_constant (MINUS, SImode, NULL_RTX,
1442                                   INTVAL (operands[1]), operands[0],
1443                                   operands[2],
1444                                   optimize && can_create_pseudo_p ());
1445               DONE;
1446             }
1447         }
1448       else /* TARGET_THUMB1 */
1449         operands[1] = force_reg (SImode, operands[1]);
1450     }
1451   "
1454 ; ??? Check Thumb-2 split length
1455 (define_insn_and_split "*arm_subsi3_insn"
1456   [(set (match_operand:SI           0 "s_register_operand" "=l,l ,l ,l ,r,r,r,rk,r")
1457         (minus:SI (match_operand:SI 1 "reg_or_int_operand" "l ,0 ,l ,Pz,I,r,r,k ,?n")
1458                   (match_operand:SI 2 "reg_or_int_operand" "l ,Py,Pd,l ,r,I,r,r ,r")))]
1459   "TARGET_32BIT"
1460   "@
1461    sub%?\\t%0, %1, %2
1462    sub%?\\t%0, %2
1463    sub%?\\t%0, %1, %2
1464    rsb%?\\t%0, %2, %1
1465    rsb%?\\t%0, %2, %1
1466    sub%?\\t%0, %1, %2
1467    sub%?\\t%0, %1, %2
1468    sub%?\\t%0, %1, %2
1469    #"
1470   "&& (CONST_INT_P (operands[1])
1471        && !const_ok_for_arm (INTVAL (operands[1])))"
1472   [(clobber (const_int 0))]
1473   "
1474   arm_split_constant (MINUS, SImode, curr_insn,
1475                       INTVAL (operands[1]), operands[0], operands[2], 0);
1476   DONE;
1477   "
1478   [(set_attr "length" "4,4,4,4,4,4,4,4,16")
1479    (set_attr "arch" "t2,t2,t2,t2,*,*,*,*,*")
1480    (set_attr "predicable" "yes")
1481    (set_attr "predicable_short_it" "yes,yes,yes,yes,no,no,no,no,no")
1482    (set_attr "type" "alu_sreg,alu_sreg,alu_sreg,alu_sreg,alu_imm,alu_imm,alu_sreg,alu_sreg,multiple")]
1485 (define_peephole2
1486   [(match_scratch:SI 3 "r")
1487    (set (match_operand:SI 0 "arm_general_register_operand" "")
1488         (minus:SI (match_operand:SI 1 "const_int_operand" "")
1489                   (match_operand:SI 2 "arm_general_register_operand" "")))]
1490   "TARGET_32BIT
1491    && !const_ok_for_arm (INTVAL (operands[1]))
1492    && const_ok_for_arm (~INTVAL (operands[1]))"
1493   [(set (match_dup 3) (match_dup 1))
1494    (set (match_dup 0) (minus:SI (match_dup 3) (match_dup 2)))]
1495   ""
1498 (define_insn "subsi3_compare0"
1499   [(set (reg:CC_NOOV CC_REGNUM)
1500         (compare:CC_NOOV
1501          (minus:SI (match_operand:SI 1 "arm_rhs_operand" "r,r,I")
1502                    (match_operand:SI 2 "arm_rhs_operand" "I,r,r"))
1503          (const_int 0)))
1504    (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
1505         (minus:SI (match_dup 1) (match_dup 2)))]
1506   "TARGET_32BIT"
1507   "@
1508    subs%?\\t%0, %1, %2
1509    subs%?\\t%0, %1, %2
1510    rsbs%?\\t%0, %2, %1"
1511   [(set_attr "conds" "set")
1512    (set_attr "type"  "alus_imm,alus_sreg,alus_sreg")]
1515 (define_insn "subsi3_compare"
1516   [(set (reg:CC CC_REGNUM)
1517         (compare:CC (match_operand:SI 1 "arm_rhs_operand" "r,r,I")
1518                     (match_operand:SI 2 "arm_rhs_operand" "I,r,r")))
1519    (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
1520         (minus:SI (match_dup 1) (match_dup 2)))]
1521   "TARGET_32BIT"
1522   "@
1523    subs%?\\t%0, %1, %2
1524    subs%?\\t%0, %1, %2
1525    rsbs%?\\t%0, %2, %1"
1526   [(set_attr "conds" "set")
1527    (set_attr "type" "alus_imm,alus_sreg,alus_sreg")]
1530 (define_expand "subsf3"
1531   [(set (match_operand:SF           0 "s_register_operand" "")
1532         (minus:SF (match_operand:SF 1 "s_register_operand" "")
1533                   (match_operand:SF 2 "s_register_operand" "")))]
1534   "TARGET_32BIT && TARGET_HARD_FLOAT"
1535   "
1538 (define_expand "subdf3"
1539   [(set (match_operand:DF           0 "s_register_operand" "")
1540         (minus:DF (match_operand:DF 1 "s_register_operand" "")
1541                   (match_operand:DF 2 "s_register_operand" "")))]
1542   "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
1543   "
1547 ;; Multiplication insns
1549 (define_expand "mulhi3"
1550   [(set (match_operand:HI 0 "s_register_operand" "")
1551         (mult:HI (match_operand:HI 1 "s_register_operand" "")
1552                  (match_operand:HI 2 "s_register_operand" "")))]
1553   "TARGET_DSP_MULTIPLY"
1554   "
1555   {
1556     rtx result = gen_reg_rtx (SImode);
1557     emit_insn (gen_mulhisi3 (result, operands[1], operands[2]));
1558     emit_move_insn (operands[0], gen_lowpart (HImode, result));
1559     DONE;
1560   }"
1563 (define_expand "mulsi3"
1564   [(set (match_operand:SI          0 "s_register_operand" "")
1565         (mult:SI (match_operand:SI 2 "s_register_operand" "")
1566                  (match_operand:SI 1 "s_register_operand" "")))]
1567   "TARGET_EITHER"
1568   ""
1571 ;; Use `&' and then `0' to prevent the operands 0 and 1 being the same
1572 (define_insn "*arm_mulsi3"
1573   [(set (match_operand:SI          0 "s_register_operand" "=&r,&r")
1574         (mult:SI (match_operand:SI 2 "s_register_operand" "r,r")
1575                  (match_operand:SI 1 "s_register_operand" "%0,r")))]
1576   "TARGET_32BIT && !arm_arch6"
1577   "mul%?\\t%0, %2, %1"
1578   [(set_attr "type" "mul")
1579    (set_attr "predicable" "yes")]
1582 (define_insn "*arm_mulsi3_v6"
1583   [(set (match_operand:SI          0 "s_register_operand" "=l,l,r")
1584         (mult:SI (match_operand:SI 1 "s_register_operand" "0,l,r")
1585                  (match_operand:SI 2 "s_register_operand" "l,0,r")))]
1586   "TARGET_32BIT && arm_arch6"
1587   "mul%?\\t%0, %1, %2"
1588   [(set_attr "type" "mul")
1589    (set_attr "predicable" "yes")
1590    (set_attr "arch" "t2,t2,*")
1591    (set_attr "length" "4")
1592    (set_attr "predicable_short_it" "yes,yes,no")]
1595 (define_insn "*mulsi3_compare0"
1596   [(set (reg:CC_NOOV CC_REGNUM)
1597         (compare:CC_NOOV (mult:SI
1598                           (match_operand:SI 2 "s_register_operand" "r,r")
1599                           (match_operand:SI 1 "s_register_operand" "%0,r"))
1600                          (const_int 0)))
1601    (set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1602         (mult:SI (match_dup 2) (match_dup 1)))]
1603   "TARGET_ARM && !arm_arch6"
1604   "muls%?\\t%0, %2, %1"
1605   [(set_attr "conds" "set")
1606    (set_attr "type" "muls")]
1609 (define_insn "*mulsi3_compare0_v6"
1610   [(set (reg:CC_NOOV CC_REGNUM)
1611         (compare:CC_NOOV (mult:SI
1612                           (match_operand:SI 2 "s_register_operand" "r")
1613                           (match_operand:SI 1 "s_register_operand" "r"))
1614                          (const_int 0)))
1615    (set (match_operand:SI 0 "s_register_operand" "=r")
1616         (mult:SI (match_dup 2) (match_dup 1)))]
1617   "TARGET_ARM && arm_arch6 && optimize_size"
1618   "muls%?\\t%0, %2, %1"
1619   [(set_attr "conds" "set")
1620    (set_attr "type" "muls")]
1623 (define_insn "*mulsi_compare0_scratch"
1624   [(set (reg:CC_NOOV CC_REGNUM)
1625         (compare:CC_NOOV (mult:SI
1626                           (match_operand:SI 2 "s_register_operand" "r,r")
1627                           (match_operand:SI 1 "s_register_operand" "%0,r"))
1628                          (const_int 0)))
1629    (clobber (match_scratch:SI 0 "=&r,&r"))]
1630   "TARGET_ARM && !arm_arch6"
1631   "muls%?\\t%0, %2, %1"
1632   [(set_attr "conds" "set")
1633    (set_attr "type" "muls")]
1636 (define_insn "*mulsi_compare0_scratch_v6"
1637   [(set (reg:CC_NOOV CC_REGNUM)
1638         (compare:CC_NOOV (mult:SI
1639                           (match_operand:SI 2 "s_register_operand" "r")
1640                           (match_operand:SI 1 "s_register_operand" "r"))
1641                          (const_int 0)))
1642    (clobber (match_scratch:SI 0 "=r"))]
1643   "TARGET_ARM && arm_arch6 && optimize_size"
1644   "muls%?\\t%0, %2, %1"
1645   [(set_attr "conds" "set")
1646    (set_attr "type" "muls")]
1649 ;; Unnamed templates to match MLA instruction.
1651 (define_insn "*mulsi3addsi"
1652   [(set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r,&r")
1653         (plus:SI
1654           (mult:SI (match_operand:SI 2 "s_register_operand" "r,r,r,r")
1655                    (match_operand:SI 1 "s_register_operand" "%0,r,0,r"))
1656           (match_operand:SI 3 "s_register_operand" "r,r,0,0")))]
1657   "TARGET_32BIT && !arm_arch6"
1658   "mla%?\\t%0, %2, %1, %3"
1659   [(set_attr "type" "mla")
1660    (set_attr "predicable" "yes")]
1663 (define_insn "*mulsi3addsi_v6"
1664   [(set (match_operand:SI 0 "s_register_operand" "=r")
1665         (plus:SI
1666           (mult:SI (match_operand:SI 2 "s_register_operand" "r")
1667                    (match_operand:SI 1 "s_register_operand" "r"))
1668           (match_operand:SI 3 "s_register_operand" "r")))]
1669   "TARGET_32BIT && arm_arch6"
1670   "mla%?\\t%0, %2, %1, %3"
1671   [(set_attr "type" "mla")
1672    (set_attr "predicable" "yes")
1673    (set_attr "predicable_short_it" "no")]
1676 (define_insn "*mulsi3addsi_compare0"
1677   [(set (reg:CC_NOOV CC_REGNUM)
1678         (compare:CC_NOOV
1679          (plus:SI (mult:SI
1680                    (match_operand:SI 2 "s_register_operand" "r,r,r,r")
1681                    (match_operand:SI 1 "s_register_operand" "%0,r,0,r"))
1682                   (match_operand:SI 3 "s_register_operand" "r,r,0,0"))
1683          (const_int 0)))
1684    (set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r,&r")
1685         (plus:SI (mult:SI (match_dup 2) (match_dup 1))
1686                  (match_dup 3)))]
1687   "TARGET_ARM && arm_arch6"
1688   "mlas%?\\t%0, %2, %1, %3"
1689   [(set_attr "conds" "set")
1690    (set_attr "type" "mlas")]
1693 (define_insn "*mulsi3addsi_compare0_v6"
1694   [(set (reg:CC_NOOV CC_REGNUM)
1695         (compare:CC_NOOV
1696          (plus:SI (mult:SI
1697                    (match_operand:SI 2 "s_register_operand" "r")
1698                    (match_operand:SI 1 "s_register_operand" "r"))
1699                   (match_operand:SI 3 "s_register_operand" "r"))
1700          (const_int 0)))
1701    (set (match_operand:SI 0 "s_register_operand" "=r")
1702         (plus:SI (mult:SI (match_dup 2) (match_dup 1))
1703                  (match_dup 3)))]
1704   "TARGET_ARM && arm_arch6 && optimize_size"
1705   "mlas%?\\t%0, %2, %1, %3"
1706   [(set_attr "conds" "set")
1707    (set_attr "type" "mlas")]
1710 (define_insn "*mulsi3addsi_compare0_scratch"
1711   [(set (reg:CC_NOOV CC_REGNUM)
1712         (compare:CC_NOOV
1713          (plus:SI (mult:SI
1714                    (match_operand:SI 2 "s_register_operand" "r,r,r,r")
1715                    (match_operand:SI 1 "s_register_operand" "%0,r,0,r"))
1716                   (match_operand:SI 3 "s_register_operand" "?r,r,0,0"))
1717          (const_int 0)))
1718    (clobber (match_scratch:SI 0 "=&r,&r,&r,&r"))]
1719   "TARGET_ARM && !arm_arch6"
1720   "mlas%?\\t%0, %2, %1, %3"
1721   [(set_attr "conds" "set")
1722    (set_attr "type" "mlas")]
1725 (define_insn "*mulsi3addsi_compare0_scratch_v6"
1726   [(set (reg:CC_NOOV CC_REGNUM)
1727         (compare:CC_NOOV
1728          (plus:SI (mult:SI
1729                    (match_operand:SI 2 "s_register_operand" "r")
1730                    (match_operand:SI 1 "s_register_operand" "r"))
1731                   (match_operand:SI 3 "s_register_operand" "r"))
1732          (const_int 0)))
1733    (clobber (match_scratch:SI 0 "=r"))]
1734   "TARGET_ARM && arm_arch6 && optimize_size"
1735   "mlas%?\\t%0, %2, %1, %3"
1736   [(set_attr "conds" "set")
1737    (set_attr "type" "mlas")]
1740 (define_insn "*mulsi3subsi"
1741   [(set (match_operand:SI 0 "s_register_operand" "=r")
1742         (minus:SI
1743           (match_operand:SI 3 "s_register_operand" "r")
1744           (mult:SI (match_operand:SI 2 "s_register_operand" "r")
1745                    (match_operand:SI 1 "s_register_operand" "r"))))]
1746   "TARGET_32BIT && arm_arch_thumb2"
1747   "mls%?\\t%0, %2, %1, %3"
1748   [(set_attr "type" "mla")
1749    (set_attr "predicable" "yes")
1750    (set_attr "predicable_short_it" "no")]
1753 (define_expand "maddsidi4"
1754   [(set (match_operand:DI 0 "s_register_operand" "")
1755         (plus:DI
1756          (mult:DI
1757           (sign_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1758           (sign_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1759          (match_operand:DI 3 "s_register_operand" "")))]
1760   "TARGET_32BIT && arm_arch3m"
1761   "")
1763 (define_insn "*mulsidi3adddi"
1764   [(set (match_operand:DI 0 "s_register_operand" "=&r")
1765         (plus:DI
1766          (mult:DI
1767           (sign_extend:DI (match_operand:SI 2 "s_register_operand" "%r"))
1768           (sign_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1769          (match_operand:DI 1 "s_register_operand" "0")))]
1770   "TARGET_32BIT && arm_arch3m && !arm_arch6"
1771   "smlal%?\\t%Q0, %R0, %3, %2"
1772   [(set_attr "type" "smlal")
1773    (set_attr "predicable" "yes")]
1776 (define_insn "*mulsidi3adddi_v6"
1777   [(set (match_operand:DI 0 "s_register_operand" "=r")
1778         (plus:DI
1779          (mult:DI
1780           (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r"))
1781           (sign_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1782          (match_operand:DI 1 "s_register_operand" "0")))]
1783   "TARGET_32BIT && arm_arch6"
1784   "smlal%?\\t%Q0, %R0, %3, %2"
1785   [(set_attr "type" "smlal")
1786    (set_attr "predicable" "yes")
1787    (set_attr "predicable_short_it" "no")]
1790 ;; 32x32->64 widening multiply.
1791 ;; As with mulsi3, the only difference between the v3-5 and v6+
1792 ;; versions of these patterns is the requirement that the output not
1793 ;; overlap the inputs, but that still means we have to have a named
1794 ;; expander and two different starred insns.
1796 (define_expand "mulsidi3"
1797   [(set (match_operand:DI 0 "s_register_operand" "")
1798         (mult:DI
1799          (sign_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1800          (sign_extend:DI (match_operand:SI 2 "s_register_operand" ""))))]
1801   "TARGET_32BIT && arm_arch3m"
1802   ""
1805 (define_insn "*mulsidi3_nov6"
1806   [(set (match_operand:DI 0 "s_register_operand" "=&r")
1807         (mult:DI
1808          (sign_extend:DI (match_operand:SI 1 "s_register_operand" "%r"))
1809          (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1810   "TARGET_32BIT && arm_arch3m && !arm_arch6"
1811   "smull%?\\t%Q0, %R0, %1, %2"
1812   [(set_attr "type" "smull")
1813    (set_attr "predicable" "yes")]
1816 (define_insn "*mulsidi3_v6"
1817   [(set (match_operand:DI 0 "s_register_operand" "=r")
1818         (mult:DI
1819          (sign_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1820          (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1821   "TARGET_32BIT && arm_arch6"
1822   "smull%?\\t%Q0, %R0, %1, %2"
1823   [(set_attr "type" "smull")
1824    (set_attr "predicable" "yes")
1825    (set_attr "predicable_short_it" "no")]
1828 (define_expand "umulsidi3"
1829   [(set (match_operand:DI 0 "s_register_operand" "")
1830         (mult:DI
1831          (zero_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1832          (zero_extend:DI (match_operand:SI 2 "s_register_operand" ""))))]
1833   "TARGET_32BIT && arm_arch3m"
1834   ""
1837 (define_insn "*umulsidi3_nov6"
1838   [(set (match_operand:DI 0 "s_register_operand" "=&r")
1839         (mult:DI
1840          (zero_extend:DI (match_operand:SI 1 "s_register_operand" "%r"))
1841          (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1842   "TARGET_32BIT && arm_arch3m && !arm_arch6"
1843   "umull%?\\t%Q0, %R0, %1, %2"
1844   [(set_attr "type" "umull")
1845    (set_attr "predicable" "yes")]
1848 (define_insn "*umulsidi3_v6"
1849   [(set (match_operand:DI 0 "s_register_operand" "=r")
1850         (mult:DI
1851          (zero_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1852          (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1853   "TARGET_32BIT && arm_arch6"
1854   "umull%?\\t%Q0, %R0, %1, %2"
1855   [(set_attr "type" "umull")
1856    (set_attr "predicable" "yes")
1857    (set_attr "predicable_short_it" "no")]
1860 (define_expand "umaddsidi4"
1861   [(set (match_operand:DI 0 "s_register_operand" "")
1862         (plus:DI
1863          (mult:DI
1864           (zero_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1865           (zero_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1866          (match_operand:DI 3 "s_register_operand" "")))]
1867   "TARGET_32BIT && arm_arch3m"
1868   "")
1870 (define_insn "*umulsidi3adddi"
1871   [(set (match_operand:DI 0 "s_register_operand" "=&r")
1872         (plus:DI
1873          (mult:DI
1874           (zero_extend:DI (match_operand:SI 2 "s_register_operand" "%r"))
1875           (zero_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1876          (match_operand:DI 1 "s_register_operand" "0")))]
1877   "TARGET_32BIT && arm_arch3m && !arm_arch6"
1878   "umlal%?\\t%Q0, %R0, %3, %2"
1879   [(set_attr "type" "umlal")
1880    (set_attr "predicable" "yes")]
1883 (define_insn "*umulsidi3adddi_v6"
1884   [(set (match_operand:DI 0 "s_register_operand" "=r")
1885         (plus:DI
1886          (mult:DI
1887           (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r"))
1888           (zero_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1889          (match_operand:DI 1 "s_register_operand" "0")))]
1890   "TARGET_32BIT && arm_arch6"
1891   "umlal%?\\t%Q0, %R0, %3, %2"
1892   [(set_attr "type" "umlal")
1893    (set_attr "predicable" "yes")
1894    (set_attr "predicable_short_it" "no")]
1897 (define_expand "smulsi3_highpart"
1898   [(parallel
1899     [(set (match_operand:SI 0 "s_register_operand" "")
1900           (truncate:SI
1901            (lshiftrt:DI
1902             (mult:DI
1903              (sign_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1904              (sign_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1905             (const_int 32))))
1906      (clobber (match_scratch:SI 3 ""))])]
1907   "TARGET_32BIT && arm_arch3m"
1908   ""
1911 (define_insn "*smulsi3_highpart_nov6"
1912   [(set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1913         (truncate:SI
1914          (lshiftrt:DI
1915           (mult:DI
1916            (sign_extend:DI (match_operand:SI 1 "s_register_operand" "%0,r"))
1917            (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r,r")))
1918           (const_int 32))))
1919    (clobber (match_scratch:SI 3 "=&r,&r"))]
1920   "TARGET_32BIT && arm_arch3m && !arm_arch6"
1921   "smull%?\\t%3, %0, %2, %1"
1922   [(set_attr "type" "smull")
1923    (set_attr "predicable" "yes")]
1926 (define_insn "*smulsi3_highpart_v6"
1927   [(set (match_operand:SI 0 "s_register_operand" "=r")
1928         (truncate:SI
1929          (lshiftrt:DI
1930           (mult:DI
1931            (sign_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1932            (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r")))
1933           (const_int 32))))
1934    (clobber (match_scratch:SI 3 "=r"))]
1935   "TARGET_32BIT && arm_arch6"
1936   "smull%?\\t%3, %0, %2, %1"
1937   [(set_attr "type" "smull")
1938    (set_attr "predicable" "yes")
1939    (set_attr "predicable_short_it" "no")]
1942 (define_expand "umulsi3_highpart"
1943   [(parallel
1944     [(set (match_operand:SI 0 "s_register_operand" "")
1945           (truncate:SI
1946            (lshiftrt:DI
1947             (mult:DI
1948              (zero_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1949               (zero_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1950             (const_int 32))))
1951      (clobber (match_scratch:SI 3 ""))])]
1952   "TARGET_32BIT && arm_arch3m"
1953   ""
1956 (define_insn "*umulsi3_highpart_nov6"
1957   [(set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1958         (truncate:SI
1959          (lshiftrt:DI
1960           (mult:DI
1961            (zero_extend:DI (match_operand:SI 1 "s_register_operand" "%0,r"))
1962            (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r,r")))
1963           (const_int 32))))
1964    (clobber (match_scratch:SI 3 "=&r,&r"))]
1965   "TARGET_32BIT && arm_arch3m && !arm_arch6"
1966   "umull%?\\t%3, %0, %2, %1"
1967   [(set_attr "type" "umull")
1968    (set_attr "predicable" "yes")]
1971 (define_insn "*umulsi3_highpart_v6"
1972   [(set (match_operand:SI 0 "s_register_operand" "=r")
1973         (truncate:SI
1974          (lshiftrt:DI
1975           (mult:DI
1976            (zero_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1977            (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r")))
1978           (const_int 32))))
1979    (clobber (match_scratch:SI 3 "=r"))]
1980   "TARGET_32BIT && arm_arch6"
1981   "umull%?\\t%3, %0, %2, %1"
1982   [(set_attr "type" "umull")
1983    (set_attr "predicable" "yes")
1984    (set_attr "predicable_short_it" "no")]
1987 (define_insn "mulhisi3"
1988   [(set (match_operand:SI 0 "s_register_operand" "=r")
1989         (mult:SI (sign_extend:SI
1990                   (match_operand:HI 1 "s_register_operand" "%r"))
1991                  (sign_extend:SI
1992                   (match_operand:HI 2 "s_register_operand" "r"))))]
1993   "TARGET_DSP_MULTIPLY"
1994   "smulbb%?\\t%0, %1, %2"
1995   [(set_attr "type" "smulxy")
1996    (set_attr "predicable" "yes")]
1999 (define_insn "*mulhisi3tb"
2000   [(set (match_operand:SI 0 "s_register_operand" "=r")
2001         (mult:SI (ashiftrt:SI
2002                   (match_operand:SI 1 "s_register_operand" "r")
2003                   (const_int 16))
2004                  (sign_extend:SI
2005                   (match_operand:HI 2 "s_register_operand" "r"))))]
2006   "TARGET_DSP_MULTIPLY"
2007   "smultb%?\\t%0, %1, %2"
2008   [(set_attr "type" "smulxy")
2009    (set_attr "predicable" "yes")
2010    (set_attr "predicable_short_it" "no")]
2013 (define_insn "*mulhisi3bt"
2014   [(set (match_operand:SI 0 "s_register_operand" "=r")
2015         (mult:SI (sign_extend:SI
2016                   (match_operand:HI 1 "s_register_operand" "r"))
2017                  (ashiftrt:SI
2018                   (match_operand:SI 2 "s_register_operand" "r")
2019                   (const_int 16))))]
2020   "TARGET_DSP_MULTIPLY"
2021   "smulbt%?\\t%0, %1, %2"
2022   [(set_attr "type" "smulxy")
2023    (set_attr "predicable" "yes")
2024    (set_attr "predicable_short_it" "no")]
2027 (define_insn "*mulhisi3tt"
2028   [(set (match_operand:SI 0 "s_register_operand" "=r")
2029         (mult:SI (ashiftrt:SI
2030                   (match_operand:SI 1 "s_register_operand" "r")
2031                   (const_int 16))
2032                  (ashiftrt:SI
2033                   (match_operand:SI 2 "s_register_operand" "r")
2034                   (const_int 16))))]
2035   "TARGET_DSP_MULTIPLY"
2036   "smultt%?\\t%0, %1, %2"
2037   [(set_attr "type" "smulxy")
2038    (set_attr "predicable" "yes")
2039    (set_attr "predicable_short_it" "no")]
2042 (define_insn "maddhisi4"
2043   [(set (match_operand:SI 0 "s_register_operand" "=r")
2044         (plus:SI (mult:SI (sign_extend:SI
2045                            (match_operand:HI 1 "s_register_operand" "r"))
2046                           (sign_extend:SI
2047                            (match_operand:HI 2 "s_register_operand" "r")))
2048                  (match_operand:SI 3 "s_register_operand" "r")))]
2049   "TARGET_DSP_MULTIPLY"
2050   "smlabb%?\\t%0, %1, %2, %3"
2051   [(set_attr "type" "smlaxy")
2052    (set_attr "predicable" "yes")
2053    (set_attr "predicable_short_it" "no")]
2056 ;; Note: there is no maddhisi4ibt because this one is canonical form
2057 (define_insn "*maddhisi4tb"
2058   [(set (match_operand:SI 0 "s_register_operand" "=r")
2059         (plus:SI (mult:SI (ashiftrt:SI
2060                            (match_operand:SI 1 "s_register_operand" "r")
2061                            (const_int 16))
2062                           (sign_extend:SI
2063                            (match_operand:HI 2 "s_register_operand" "r")))
2064                  (match_operand:SI 3 "s_register_operand" "r")))]
2065   "TARGET_DSP_MULTIPLY"
2066   "smlatb%?\\t%0, %1, %2, %3"
2067   [(set_attr "type" "smlaxy")
2068    (set_attr "predicable" "yes")
2069    (set_attr "predicable_short_it" "no")]
2072 (define_insn "*maddhisi4tt"
2073   [(set (match_operand:SI 0 "s_register_operand" "=r")
2074         (plus:SI (mult:SI (ashiftrt:SI
2075                            (match_operand:SI 1 "s_register_operand" "r")
2076                            (const_int 16))
2077                           (ashiftrt:SI
2078                            (match_operand:SI 2 "s_register_operand" "r")
2079                            (const_int 16)))
2080                  (match_operand:SI 3 "s_register_operand" "r")))]
2081   "TARGET_DSP_MULTIPLY"
2082   "smlatt%?\\t%0, %1, %2, %3"
2083   [(set_attr "type" "smlaxy")
2084    (set_attr "predicable" "yes")
2085    (set_attr "predicable_short_it" "no")]
2088 (define_insn "maddhidi4"
2089   [(set (match_operand:DI 0 "s_register_operand" "=r")
2090         (plus:DI
2091           (mult:DI (sign_extend:DI
2092                     (match_operand:HI 1 "s_register_operand" "r"))
2093                    (sign_extend:DI
2094                     (match_operand:HI 2 "s_register_operand" "r")))
2095           (match_operand:DI 3 "s_register_operand" "0")))]
2096   "TARGET_DSP_MULTIPLY"
2097   "smlalbb%?\\t%Q0, %R0, %1, %2"
2098   [(set_attr "type" "smlalxy")
2099    (set_attr "predicable" "yes")
2100    (set_attr "predicable_short_it" "no")])
2102 ;; Note: there is no maddhidi4ibt because this one is canonical form
2103 (define_insn "*maddhidi4tb"
2104   [(set (match_operand:DI 0 "s_register_operand" "=r")
2105         (plus:DI
2106           (mult:DI (sign_extend:DI
2107                     (ashiftrt:SI
2108                      (match_operand:SI 1 "s_register_operand" "r")
2109                      (const_int 16)))
2110                    (sign_extend:DI
2111                     (match_operand:HI 2 "s_register_operand" "r")))
2112           (match_operand:DI 3 "s_register_operand" "0")))]
2113   "TARGET_DSP_MULTIPLY"
2114   "smlaltb%?\\t%Q0, %R0, %1, %2"
2115   [(set_attr "type" "smlalxy")
2116    (set_attr "predicable" "yes")
2117    (set_attr "predicable_short_it" "no")])
2119 (define_insn "*maddhidi4tt"
2120   [(set (match_operand:DI 0 "s_register_operand" "=r")
2121         (plus:DI
2122           (mult:DI (sign_extend:DI
2123                     (ashiftrt:SI
2124                      (match_operand:SI 1 "s_register_operand" "r")
2125                      (const_int 16)))
2126                    (sign_extend:DI
2127                     (ashiftrt:SI
2128                      (match_operand:SI 2 "s_register_operand" "r")
2129                      (const_int 16))))
2130           (match_operand:DI 3 "s_register_operand" "0")))]
2131   "TARGET_DSP_MULTIPLY"
2132   "smlaltt%?\\t%Q0, %R0, %1, %2"
2133   [(set_attr "type" "smlalxy")
2134    (set_attr "predicable" "yes")
2135    (set_attr "predicable_short_it" "no")])
2137 (define_expand "mulsf3"
2138   [(set (match_operand:SF          0 "s_register_operand" "")
2139         (mult:SF (match_operand:SF 1 "s_register_operand" "")
2140                  (match_operand:SF 2 "s_register_operand" "")))]
2141   "TARGET_32BIT && TARGET_HARD_FLOAT"
2142   "
2145 (define_expand "muldf3"
2146   [(set (match_operand:DF          0 "s_register_operand" "")
2147         (mult:DF (match_operand:DF 1 "s_register_operand" "")
2148                  (match_operand:DF 2 "s_register_operand" "")))]
2149   "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
2150   "
2153 ;; Division insns
2155 (define_expand "divsf3"
2156   [(set (match_operand:SF 0 "s_register_operand" "")
2157         (div:SF (match_operand:SF 1 "s_register_operand" "")
2158                 (match_operand:SF 2 "s_register_operand" "")))]
2159   "TARGET_32BIT && TARGET_HARD_FLOAT"
2160   "")
2162 (define_expand "divdf3"
2163   [(set (match_operand:DF 0 "s_register_operand" "")
2164         (div:DF (match_operand:DF 1 "s_register_operand" "")
2165                 (match_operand:DF 2 "s_register_operand" "")))]
2166   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
2167   "")
2169 ;; Boolean and,ior,xor insns
2171 ;; Split up double word logical operations
2173 ;; Split up simple DImode logical operations.  Simply perform the logical
2174 ;; operation on the upper and lower halves of the registers.
2175 (define_split
2176   [(set (match_operand:DI 0 "s_register_operand" "")
2177         (match_operator:DI 6 "logical_binary_operator"
2178           [(match_operand:DI 1 "s_register_operand" "")
2179            (match_operand:DI 2 "s_register_operand" "")]))]
2180   "TARGET_32BIT && reload_completed
2181    && ! (TARGET_NEON && IS_VFP_REGNUM (REGNO (operands[0])))
2182    && ! IS_IWMMXT_REGNUM (REGNO (operands[0]))"
2183   [(set (match_dup 0) (match_op_dup:SI 6 [(match_dup 1) (match_dup 2)]))
2184    (set (match_dup 3) (match_op_dup:SI 6 [(match_dup 4) (match_dup 5)]))]
2185   "
2186   {
2187     operands[3] = gen_highpart (SImode, operands[0]);
2188     operands[0] = gen_lowpart (SImode, operands[0]);
2189     operands[4] = gen_highpart (SImode, operands[1]);
2190     operands[1] = gen_lowpart (SImode, operands[1]);
2191     operands[5] = gen_highpart (SImode, operands[2]);
2192     operands[2] = gen_lowpart (SImode, operands[2]);
2193   }"
2196 (define_split
2197   [(set (match_operand:DI 0 "s_register_operand" "")
2198         (match_operator:DI 6 "logical_binary_operator"
2199           [(sign_extend:DI (match_operand:SI 2 "s_register_operand" ""))
2200            (match_operand:DI 1 "s_register_operand" "")]))]
2201   "TARGET_32BIT && reload_completed"
2202   [(set (match_dup 0) (match_op_dup:SI 6 [(match_dup 1) (match_dup 2)]))
2203    (set (match_dup 3) (match_op_dup:SI 6
2204                         [(ashiftrt:SI (match_dup 2) (const_int 31))
2205                          (match_dup 4)]))]
2206   "
2207   {
2208     operands[3] = gen_highpart (SImode, operands[0]);
2209     operands[0] = gen_lowpart (SImode, operands[0]);
2210     operands[4] = gen_highpart (SImode, operands[1]);
2211     operands[1] = gen_lowpart (SImode, operands[1]);
2212     operands[5] = gen_highpart (SImode, operands[2]);
2213     operands[2] = gen_lowpart (SImode, operands[2]);
2214   }"
2217 ;; The zero extend of operand 2 means we can just copy the high part of
2218 ;; operand1 into operand0.
2219 (define_split
2220   [(set (match_operand:DI 0 "s_register_operand" "")
2221         (ior:DI
2222           (zero_extend:DI (match_operand:SI 2 "s_register_operand" ""))
2223           (match_operand:DI 1 "s_register_operand" "")))]
2224   "TARGET_32BIT && operands[0] != operands[1] && reload_completed"
2225   [(set (match_dup 0) (ior:SI (match_dup 1) (match_dup 2)))
2226    (set (match_dup 3) (match_dup 4))]
2227   "
2228   {
2229     operands[4] = gen_highpart (SImode, operands[1]);
2230     operands[3] = gen_highpart (SImode, operands[0]);
2231     operands[0] = gen_lowpart (SImode, operands[0]);
2232     operands[1] = gen_lowpart (SImode, operands[1]);
2233   }"
2236 ;; The zero extend of operand 2 means we can just copy the high part of
2237 ;; operand1 into operand0.
2238 (define_split
2239   [(set (match_operand:DI 0 "s_register_operand" "")
2240         (xor:DI
2241           (zero_extend:DI (match_operand:SI 2 "s_register_operand" ""))
2242           (match_operand:DI 1 "s_register_operand" "")))]
2243   "TARGET_32BIT && operands[0] != operands[1] && reload_completed"
2244   [(set (match_dup 0) (xor:SI (match_dup 1) (match_dup 2)))
2245    (set (match_dup 3) (match_dup 4))]
2246   "
2247   {
2248     operands[4] = gen_highpart (SImode, operands[1]);
2249     operands[3] = gen_highpart (SImode, operands[0]);
2250     operands[0] = gen_lowpart (SImode, operands[0]);
2251     operands[1] = gen_lowpart (SImode, operands[1]);
2252   }"
2255 (define_expand "anddi3"
2256   [(set (match_operand:DI         0 "s_register_operand" "")
2257         (and:DI (match_operand:DI 1 "s_register_operand" "")
2258                 (match_operand:DI 2 "neon_inv_logic_op2" "")))]
2259   "TARGET_32BIT"
2260   ""
2263 (define_insn_and_split "*anddi3_insn"
2264   [(set (match_operand:DI         0 "s_register_operand"     "=w,w ,&r,&r,&r,&r,?w,?w")
2265         (and:DI (match_operand:DI 1 "s_register_operand"     "%w,0 ,0 ,r ,0 ,r ,w ,0")
2266                 (match_operand:DI 2 "arm_anddi_operand_neon" "w ,DL,r ,r ,De,De,w ,DL")))]
2267   "TARGET_32BIT && !TARGET_IWMMXT"
2269   switch (which_alternative)
2270     {
2271     case 0: /* fall through */
2272     case 6: return "vand\t%P0, %P1, %P2";
2273     case 1: /* fall through */
2274     case 7: return neon_output_logic_immediate ("vand", &operands[2],
2275                     DImode, 1, VALID_NEON_QREG_MODE (DImode));
2276     case 2:
2277     case 3:
2278     case 4:
2279     case 5: /* fall through */
2280       return "#";
2281     default: gcc_unreachable ();
2282     }
2284   "TARGET_32BIT && !TARGET_IWMMXT && reload_completed
2285    && !(IS_VFP_REGNUM (REGNO (operands[0])))"
2286   [(set (match_dup 3) (match_dup 4))
2287    (set (match_dup 5) (match_dup 6))]
2288   "
2289   {
2290     operands[3] = gen_lowpart (SImode, operands[0]);
2291     operands[5] = gen_highpart (SImode, operands[0]);
2293     operands[4] = simplify_gen_binary (AND, SImode,
2294                                            gen_lowpart (SImode, operands[1]),
2295                                            gen_lowpart (SImode, operands[2]));
2296     operands[6] = simplify_gen_binary (AND, SImode,
2297                                            gen_highpart (SImode, operands[1]),
2298                                            gen_highpart_mode (SImode, DImode, operands[2]));
2300   }"
2301   [(set_attr "type" "neon_logic,neon_logic,multiple,multiple,\
2302                      multiple,multiple,neon_logic,neon_logic")
2303    (set_attr "arch" "neon_for_64bits,neon_for_64bits,*,*,*,*,
2304                      avoid_neon_for_64bits,avoid_neon_for_64bits")
2305    (set_attr "length" "*,*,8,8,8,8,*,*")
2306   ]
2309 (define_insn_and_split "*anddi_zesidi_di"
2310   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2311         (and:DI (zero_extend:DI
2312                  (match_operand:SI 2 "s_register_operand" "r,r"))
2313                 (match_operand:DI 1 "s_register_operand" "0,r")))]
2314   "TARGET_32BIT"
2315   "#"
2316   "TARGET_32BIT && reload_completed"
2317   ; The zero extend of operand 2 clears the high word of the output
2318   ; operand.
2319   [(set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))
2320    (set (match_dup 3) (const_int 0))]
2321   "
2322   {
2323     operands[3] = gen_highpart (SImode, operands[0]);
2324     operands[0] = gen_lowpart (SImode, operands[0]);
2325     operands[1] = gen_lowpart (SImode, operands[1]);
2326   }"
2327   [(set_attr "length" "8")
2328    (set_attr "type" "multiple")]
2331 (define_insn "*anddi_sesdi_di"
2332   [(set (match_operand:DI          0 "s_register_operand" "=&r,&r")
2333         (and:DI (sign_extend:DI
2334                  (match_operand:SI 2 "s_register_operand" "r,r"))
2335                 (match_operand:DI  1 "s_register_operand" "0,r")))]
2336   "TARGET_32BIT"
2337   "#"
2338   [(set_attr "length" "8")
2339    (set_attr "type" "multiple")]
2342 (define_expand "andsi3"
2343   [(set (match_operand:SI         0 "s_register_operand" "")
2344         (and:SI (match_operand:SI 1 "s_register_operand" "")
2345                 (match_operand:SI 2 "reg_or_int_operand" "")))]
2346   "TARGET_EITHER"
2347   "
2348   if (TARGET_32BIT)
2349     {
2350       if (CONST_INT_P (operands[2]))
2351         {
2352           if (INTVAL (operands[2]) == 255 && arm_arch6)
2353             {
2354               operands[1] = convert_to_mode (QImode, operands[1], 1);
2355               emit_insn (gen_thumb2_zero_extendqisi2_v6 (operands[0],
2356                                                          operands[1]));
2357               DONE;
2358             }
2359           else if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[2]), AND))
2360             operands[2] = force_reg (SImode, operands[2]);
2361           else
2362             {
2363               arm_split_constant (AND, SImode, NULL_RTX,
2364                                   INTVAL (operands[2]), operands[0],
2365                                   operands[1],
2366                                   optimize && can_create_pseudo_p ());
2368               DONE;
2369             }
2370         }
2371     }
2372   else /* TARGET_THUMB1 */
2373     {
2374       if (!CONST_INT_P (operands[2]))
2375         {
2376           rtx tmp = force_reg (SImode, operands[2]);
2377           if (rtx_equal_p (operands[0], operands[1]))
2378             operands[2] = tmp;
2379           else
2380             {
2381               operands[2] = operands[1];
2382               operands[1] = tmp;
2383             }
2384         }
2385       else
2386         {
2387           int i;
2388           
2389           if (((unsigned HOST_WIDE_INT) ~INTVAL (operands[2])) < 256)
2390             {
2391               operands[2] = force_reg (SImode,
2392                                        GEN_INT (~INTVAL (operands[2])));
2393               
2394               emit_insn (gen_thumb1_bicsi3 (operands[0], operands[2], operands[1]));
2395               
2396               DONE;
2397             }
2399           for (i = 9; i <= 31; i++)
2400             {
2401               if ((HOST_WIDE_INT_1 << i) - 1 == INTVAL (operands[2]))
2402                 {
2403                   emit_insn (gen_extzv (operands[0], operands[1], GEN_INT (i),
2404                                         const0_rtx));
2405                   DONE;
2406                 }
2407               else if ((HOST_WIDE_INT_1 << i) - 1
2408                        == ~INTVAL (operands[2]))
2409                 {
2410                   rtx shift = GEN_INT (i);
2411                   rtx reg = gen_reg_rtx (SImode);
2412                 
2413                   emit_insn (gen_lshrsi3 (reg, operands[1], shift));
2414                   emit_insn (gen_ashlsi3 (operands[0], reg, shift));
2415                   
2416                   DONE;
2417                 }
2418             }
2420           operands[2] = force_reg (SImode, operands[2]);
2421         }
2422     }
2423   "
2426 ; ??? Check split length for Thumb-2
2427 (define_insn_and_split "*arm_andsi3_insn"
2428   [(set (match_operand:SI         0 "s_register_operand" "=r,l,r,r,r")
2429         (and:SI (match_operand:SI 1 "s_register_operand" "%r,0,r,r,r")
2430                 (match_operand:SI 2 "reg_or_int_operand" "I,l,K,r,?n")))]
2431   "TARGET_32BIT"
2432   "@
2433    and%?\\t%0, %1, %2
2434    and%?\\t%0, %1, %2
2435    bic%?\\t%0, %1, #%B2
2436    and%?\\t%0, %1, %2
2437    #"
2438   "TARGET_32BIT
2439    && CONST_INT_P (operands[2])
2440    && !(const_ok_for_arm (INTVAL (operands[2]))
2441         || const_ok_for_arm (~INTVAL (operands[2])))"
2442   [(clobber (const_int 0))]
2443   "
2444   arm_split_constant  (AND, SImode, curr_insn, 
2445                        INTVAL (operands[2]), operands[0], operands[1], 0);
2446   DONE;
2447   "
2448   [(set_attr "length" "4,4,4,4,16")
2449    (set_attr "predicable" "yes")
2450    (set_attr "predicable_short_it" "no,yes,no,no,no")
2451    (set_attr "type" "logic_imm,logic_imm,logic_reg,logic_reg,logic_imm")]
2454 (define_insn "*andsi3_compare0"
2455   [(set (reg:CC_NOOV CC_REGNUM)
2456         (compare:CC_NOOV
2457          (and:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
2458                  (match_operand:SI 2 "arm_not_operand" "I,K,r"))
2459          (const_int 0)))
2460    (set (match_operand:SI          0 "s_register_operand" "=r,r,r")
2461         (and:SI (match_dup 1) (match_dup 2)))]
2462   "TARGET_32BIT"
2463   "@
2464    ands%?\\t%0, %1, %2
2465    bics%?\\t%0, %1, #%B2
2466    ands%?\\t%0, %1, %2"
2467   [(set_attr "conds" "set")
2468    (set_attr "type" "logics_imm,logics_imm,logics_reg")]
2471 (define_insn "*andsi3_compare0_scratch"
2472   [(set (reg:CC_NOOV CC_REGNUM)
2473         (compare:CC_NOOV
2474          (and:SI (match_operand:SI 0 "s_register_operand" "r,r,r")
2475                  (match_operand:SI 1 "arm_not_operand" "I,K,r"))
2476          (const_int 0)))
2477    (clobber (match_scratch:SI 2 "=X,r,X"))]
2478   "TARGET_32BIT"
2479   "@
2480    tst%?\\t%0, %1
2481    bics%?\\t%2, %0, #%B1
2482    tst%?\\t%0, %1"
2483   [(set_attr "conds" "set")
2484    (set_attr "type"  "logics_imm,logics_imm,logics_reg")]
2487 (define_insn "*zeroextractsi_compare0_scratch"
2488   [(set (reg:CC_NOOV CC_REGNUM)
2489         (compare:CC_NOOV (zero_extract:SI
2490                           (match_operand:SI 0 "s_register_operand" "r")
2491                           (match_operand 1 "const_int_operand" "n")
2492                           (match_operand 2 "const_int_operand" "n"))
2493                          (const_int 0)))]
2494   "TARGET_32BIT
2495   && (INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) < 32
2496       && INTVAL (operands[1]) > 0 
2497       && INTVAL (operands[1]) + (INTVAL (operands[2]) & 1) <= 8
2498       && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32)"
2499   "*
2500   operands[1] = GEN_INT (((1 << INTVAL (operands[1])) - 1)
2501                          << INTVAL (operands[2]));
2502   output_asm_insn (\"tst%?\\t%0, %1\", operands);
2503   return \"\";
2504   "
2505   [(set_attr "conds" "set")
2506    (set_attr "predicable" "yes")
2507    (set_attr "predicable_short_it" "no")
2508    (set_attr "type" "logics_imm")]
2511 (define_insn_and_split "*ne_zeroextractsi"
2512   [(set (match_operand:SI 0 "s_register_operand" "=r")
2513         (ne:SI (zero_extract:SI
2514                 (match_operand:SI 1 "s_register_operand" "r")
2515                 (match_operand:SI 2 "const_int_operand" "n")
2516                 (match_operand:SI 3 "const_int_operand" "n"))
2517                (const_int 0)))
2518    (clobber (reg:CC CC_REGNUM))]
2519   "TARGET_32BIT
2520    && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2521        && INTVAL (operands[2]) > 0 
2522        && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2523        && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)"
2524   "#"
2525   "TARGET_32BIT
2526    && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2527        && INTVAL (operands[2]) > 0 
2528        && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2529        && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)"
2530   [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2531                    (compare:CC_NOOV (and:SI (match_dup 1) (match_dup 2))
2532                                     (const_int 0)))
2533               (set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))])
2534    (set (match_dup 0)
2535         (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2536                          (match_dup 0) (const_int 1)))]
2537   "
2538   operands[2] = GEN_INT (((1 << INTVAL (operands[2])) - 1)
2539                          << INTVAL (operands[3])); 
2540   "
2541   [(set_attr "conds" "clob")
2542    (set (attr "length")
2543         (if_then_else (eq_attr "is_thumb" "yes")
2544                       (const_int 12)
2545                       (const_int 8)))
2546    (set_attr "type" "multiple")]
2549 (define_insn_and_split "*ne_zeroextractsi_shifted"
2550   [(set (match_operand:SI 0 "s_register_operand" "=r")
2551         (ne:SI (zero_extract:SI
2552                 (match_operand:SI 1 "s_register_operand" "r")
2553                 (match_operand:SI 2 "const_int_operand" "n")
2554                 (const_int 0))
2555                (const_int 0)))
2556    (clobber (reg:CC CC_REGNUM))]
2557   "TARGET_ARM"
2558   "#"
2559   "TARGET_ARM"
2560   [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2561                    (compare:CC_NOOV (ashift:SI (match_dup 1) (match_dup 2))
2562                                     (const_int 0)))
2563               (set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))])
2564    (set (match_dup 0)
2565         (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2566                          (match_dup 0) (const_int 1)))]
2567   "
2568   operands[2] = GEN_INT (32 - INTVAL (operands[2]));
2569   "
2570   [(set_attr "conds" "clob")
2571    (set_attr "length" "8")
2572    (set_attr "type" "multiple")]
2575 (define_insn_and_split "*ite_ne_zeroextractsi"
2576   [(set (match_operand:SI 0 "s_register_operand" "=r")
2577         (if_then_else:SI (ne (zero_extract:SI
2578                               (match_operand:SI 1 "s_register_operand" "r")
2579                               (match_operand:SI 2 "const_int_operand" "n")
2580                               (match_operand:SI 3 "const_int_operand" "n"))
2581                              (const_int 0))
2582                          (match_operand:SI 4 "arm_not_operand" "rIK")
2583                          (const_int 0)))
2584    (clobber (reg:CC CC_REGNUM))]
2585   "TARGET_ARM
2586    && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2587        && INTVAL (operands[2]) > 0 
2588        && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2589        && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)
2590    && !reg_overlap_mentioned_p (operands[0], operands[4])"
2591   "#"
2592   "TARGET_ARM
2593    && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2594        && INTVAL (operands[2]) > 0 
2595        && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2596        && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)
2597    && !reg_overlap_mentioned_p (operands[0], operands[4])"
2598   [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2599                    (compare:CC_NOOV (and:SI (match_dup 1) (match_dup 2))
2600                                     (const_int 0)))
2601               (set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))])
2602    (set (match_dup 0)
2603         (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2604                          (match_dup 0) (match_dup 4)))]
2605   "
2606   operands[2] = GEN_INT (((1 << INTVAL (operands[2])) - 1)
2607                          << INTVAL (operands[3])); 
2608   "
2609   [(set_attr "conds" "clob")
2610    (set_attr "length" "8")
2611    (set_attr "type" "multiple")]
2614 (define_insn_and_split "*ite_ne_zeroextractsi_shifted"
2615   [(set (match_operand:SI 0 "s_register_operand" "=r")
2616         (if_then_else:SI (ne (zero_extract:SI
2617                               (match_operand:SI 1 "s_register_operand" "r")
2618                               (match_operand:SI 2 "const_int_operand" "n")
2619                               (const_int 0))
2620                              (const_int 0))
2621                          (match_operand:SI 3 "arm_not_operand" "rIK")
2622                          (const_int 0)))
2623    (clobber (reg:CC CC_REGNUM))]
2624   "TARGET_ARM && !reg_overlap_mentioned_p (operands[0], operands[3])"
2625   "#"
2626   "TARGET_ARM && !reg_overlap_mentioned_p (operands[0], operands[3])"
2627   [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2628                    (compare:CC_NOOV (ashift:SI (match_dup 1) (match_dup 2))
2629                                     (const_int 0)))
2630               (set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))])
2631    (set (match_dup 0)
2632         (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2633                          (match_dup 0) (match_dup 3)))]
2634   "
2635   operands[2] = GEN_INT (32 - INTVAL (operands[2]));
2636   "
2637   [(set_attr "conds" "clob")
2638    (set_attr "length" "8")
2639    (set_attr "type" "multiple")]
2642 ;; ??? Use Thumb-2 has bitfield insert/extract instructions.
2643 (define_split
2644   [(set (match_operand:SI 0 "s_register_operand" "")
2645         (match_operator:SI 1 "shiftable_operator"
2646          [(zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
2647                            (match_operand:SI 3 "const_int_operand" "")
2648                            (match_operand:SI 4 "const_int_operand" ""))
2649           (match_operand:SI 5 "s_register_operand" "")]))
2650    (clobber (match_operand:SI 6 "s_register_operand" ""))]
2651   "TARGET_ARM"
2652   [(set (match_dup 6) (ashift:SI (match_dup 2) (match_dup 3)))
2653    (set (match_dup 0)
2654         (match_op_dup 1
2655          [(lshiftrt:SI (match_dup 6) (match_dup 4))
2656           (match_dup 5)]))]
2657   "{
2658      HOST_WIDE_INT temp = INTVAL (operands[3]);
2660      operands[3] = GEN_INT (32 - temp - INTVAL (operands[4]));
2661      operands[4] = GEN_INT (32 - temp);
2662    }"
2664   
2665 (define_split
2666   [(set (match_operand:SI 0 "s_register_operand" "")
2667         (match_operator:SI 1 "shiftable_operator"
2668          [(sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
2669                            (match_operand:SI 3 "const_int_operand" "")
2670                            (match_operand:SI 4 "const_int_operand" ""))
2671           (match_operand:SI 5 "s_register_operand" "")]))
2672    (clobber (match_operand:SI 6 "s_register_operand" ""))]
2673   "TARGET_ARM"
2674   [(set (match_dup 6) (ashift:SI (match_dup 2) (match_dup 3)))
2675    (set (match_dup 0)
2676         (match_op_dup 1
2677          [(ashiftrt:SI (match_dup 6) (match_dup 4))
2678           (match_dup 5)]))]
2679   "{
2680      HOST_WIDE_INT temp = INTVAL (operands[3]);
2682      operands[3] = GEN_INT (32 - temp - INTVAL (operands[4]));
2683      operands[4] = GEN_INT (32 - temp);
2684    }"
2686   
2687 ;;; ??? This pattern is bogus.  If operand3 has bits outside the range
2688 ;;; represented by the bitfield, then this will produce incorrect results.
2689 ;;; Somewhere, the value needs to be truncated.  On targets like the m68k,
2690 ;;; which have a real bit-field insert instruction, the truncation happens
2691 ;;; in the bit-field insert instruction itself.  Since arm does not have a
2692 ;;; bit-field insert instruction, we would have to emit code here to truncate
2693 ;;; the value before we insert.  This loses some of the advantage of having
2694 ;;; this insv pattern, so this pattern needs to be reevalutated.
2696 (define_expand "insv"
2697   [(set (zero_extract (match_operand 0 "nonimmediate_operand" "")
2698                       (match_operand 1 "general_operand" "")
2699                       (match_operand 2 "general_operand" ""))
2700         (match_operand 3 "reg_or_int_operand" ""))]
2701   "TARGET_ARM || arm_arch_thumb2"
2702   "
2703   {
2704     int start_bit = INTVAL (operands[2]);
2705     int width = INTVAL (operands[1]);
2706     HOST_WIDE_INT mask = (HOST_WIDE_INT_1 << width) - 1;
2707     rtx target, subtarget;
2709     if (arm_arch_thumb2)
2710       {
2711         if (unaligned_access && MEM_P (operands[0])
2712             && s_register_operand (operands[3], GET_MODE (operands[3]))
2713             && (width == 16 || width == 32) && (start_bit % BITS_PER_UNIT) == 0)
2714           {
2715             rtx base_addr;
2717             if (BYTES_BIG_ENDIAN)
2718               start_bit = GET_MODE_BITSIZE (GET_MODE (operands[3])) - width
2719                           - start_bit;
2721             if (width == 32)
2722               {
2723                 base_addr = adjust_address (operands[0], SImode,
2724                                             start_bit / BITS_PER_UNIT);
2725                 emit_insn (gen_unaligned_storesi (base_addr, operands[3]));
2726               }
2727             else
2728               {
2729                 rtx tmp = gen_reg_rtx (HImode);
2731                 base_addr = adjust_address (operands[0], HImode,
2732                                             start_bit / BITS_PER_UNIT);
2733                 emit_move_insn (tmp, gen_lowpart (HImode, operands[3]));
2734                 emit_insn (gen_unaligned_storehi (base_addr, tmp));
2735               }
2736             DONE;
2737           }
2738         else if (s_register_operand (operands[0], GET_MODE (operands[0])))
2739           {
2740             bool use_bfi = TRUE;
2742             if (CONST_INT_P (operands[3]))
2743               {
2744                 HOST_WIDE_INT val = INTVAL (operands[3]) & mask;
2746                 if (val == 0)
2747                   {
2748                     emit_insn (gen_insv_zero (operands[0], operands[1],
2749                                               operands[2]));
2750                     DONE;
2751                   }
2753                 /* See if the set can be done with a single orr instruction.  */
2754                 if (val == mask && const_ok_for_arm (val << start_bit))
2755                   use_bfi = FALSE;
2756               }
2758             if (use_bfi)
2759               {
2760                 if (!REG_P (operands[3]))
2761                   operands[3] = force_reg (SImode, operands[3]);
2763                 emit_insn (gen_insv_t2 (operands[0], operands[1], operands[2],
2764                                         operands[3]));
2765                 DONE;
2766               }
2767           }
2768         else
2769           FAIL;
2770       }
2772     if (!s_register_operand (operands[0], GET_MODE (operands[0])))
2773       FAIL;
2775     target = copy_rtx (operands[0]);
2776     /* Avoid using a subreg as a subtarget, and avoid writing a paradoxical 
2777        subreg as the final target.  */
2778     if (GET_CODE (target) == SUBREG)
2779       {
2780         subtarget = gen_reg_rtx (SImode);
2781         if (GET_MODE_SIZE (GET_MODE (SUBREG_REG (target)))
2782             < GET_MODE_SIZE (SImode))
2783           target = SUBREG_REG (target);
2784       }
2785     else
2786       subtarget = target;    
2788     if (CONST_INT_P (operands[3]))
2789       {
2790         /* Since we are inserting a known constant, we may be able to
2791            reduce the number of bits that we have to clear so that
2792            the mask becomes simple.  */
2793         /* ??? This code does not check to see if the new mask is actually
2794            simpler.  It may not be.  */
2795         rtx op1 = gen_reg_rtx (SImode);
2796         /* ??? Truncate operand3 to fit in the bitfield.  See comment before
2797            start of this pattern.  */
2798         HOST_WIDE_INT op3_value = mask & INTVAL (operands[3]);
2799         HOST_WIDE_INT mask2 = ((mask & ~op3_value) << start_bit);
2801         emit_insn (gen_andsi3 (op1, operands[0],
2802                                gen_int_mode (~mask2, SImode)));
2803         emit_insn (gen_iorsi3 (subtarget, op1,
2804                                gen_int_mode (op3_value << start_bit, SImode)));
2805       }
2806     else if (start_bit == 0
2807              && !(const_ok_for_arm (mask)
2808                   || const_ok_for_arm (~mask)))
2809       {
2810         /* A Trick, since we are setting the bottom bits in the word,
2811            we can shift operand[3] up, operand[0] down, OR them together
2812            and rotate the result back again.  This takes 3 insns, and
2813            the third might be mergeable into another op.  */
2814         /* The shift up copes with the possibility that operand[3] is
2815            wider than the bitfield.  */
2816         rtx op0 = gen_reg_rtx (SImode);
2817         rtx op1 = gen_reg_rtx (SImode);
2819         emit_insn (gen_ashlsi3 (op0, operands[3], GEN_INT (32 - width)));
2820         emit_insn (gen_lshrsi3 (op1, operands[0], operands[1]));
2821         emit_insn (gen_iorsi3  (op1, op1, op0));
2822         emit_insn (gen_rotlsi3 (subtarget, op1, operands[1]));
2823       }
2824     else if ((width + start_bit == 32)
2825              && !(const_ok_for_arm (mask)
2826                   || const_ok_for_arm (~mask)))
2827       {
2828         /* Similar trick, but slightly less efficient.  */
2830         rtx op0 = gen_reg_rtx (SImode);
2831         rtx op1 = gen_reg_rtx (SImode);
2833         emit_insn (gen_ashlsi3 (op0, operands[3], GEN_INT (32 - width)));
2834         emit_insn (gen_ashlsi3 (op1, operands[0], operands[1]));
2835         emit_insn (gen_lshrsi3 (op1, op1, operands[1]));
2836         emit_insn (gen_iorsi3 (subtarget, op1, op0));
2837       }
2838     else
2839       {
2840         rtx op0 = gen_int_mode (mask, SImode);
2841         rtx op1 = gen_reg_rtx (SImode);
2842         rtx op2 = gen_reg_rtx (SImode);
2844         if (!(const_ok_for_arm (mask) || const_ok_for_arm (~mask)))
2845           {
2846             rtx tmp = gen_reg_rtx (SImode);
2848             emit_insn (gen_movsi (tmp, op0));
2849             op0 = tmp;
2850           }
2852         /* Mask out any bits in operand[3] that are not needed.  */
2853            emit_insn (gen_andsi3 (op1, operands[3], op0));
2855         if (CONST_INT_P (op0)
2856             && (const_ok_for_arm (mask << start_bit)
2857                 || const_ok_for_arm (~(mask << start_bit))))
2858           {
2859             op0 = gen_int_mode (~(mask << start_bit), SImode);
2860             emit_insn (gen_andsi3 (op2, operands[0], op0));
2861           }
2862         else
2863           {
2864             if (CONST_INT_P (op0))
2865               {
2866                 rtx tmp = gen_reg_rtx (SImode);
2868                 emit_insn (gen_movsi (tmp, op0));
2869                 op0 = tmp;
2870               }
2872             if (start_bit != 0)
2873               emit_insn (gen_ashlsi3 (op0, op0, operands[2]));
2874             
2875             emit_insn (gen_andsi_notsi_si (op2, operands[0], op0));
2876           }
2878         if (start_bit != 0)
2879           emit_insn (gen_ashlsi3 (op1, op1, operands[2]));
2881         emit_insn (gen_iorsi3 (subtarget, op1, op2));
2882       }
2884     if (subtarget != target)
2885       {
2886         /* If TARGET is still a SUBREG, then it must be wider than a word,
2887            so we must be careful only to set the subword we were asked to.  */
2888         if (GET_CODE (target) == SUBREG)
2889           emit_move_insn (target, subtarget);
2890         else
2891           emit_move_insn (target, gen_lowpart (GET_MODE (target), subtarget));
2892       }
2894     DONE;
2895   }"
2898 (define_insn "insv_zero"
2899   [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r")
2900                          (match_operand:SI 1 "const_int_M_operand" "M")
2901                          (match_operand:SI 2 "const_int_M_operand" "M"))
2902         (const_int 0))]
2903   "arm_arch_thumb2"
2904   "bfc%?\t%0, %2, %1"
2905   [(set_attr "length" "4")
2906    (set_attr "predicable" "yes")
2907    (set_attr "predicable_short_it" "no")
2908    (set_attr "type" "bfm")]
2911 (define_insn "insv_t2"
2912   [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r")
2913                          (match_operand:SI 1 "const_int_M_operand" "M")
2914                          (match_operand:SI 2 "const_int_M_operand" "M"))
2915         (match_operand:SI 3 "s_register_operand" "r"))]
2916   "arm_arch_thumb2"
2917   "bfi%?\t%0, %3, %2, %1"
2918   [(set_attr "length" "4")
2919    (set_attr "predicable" "yes")
2920    (set_attr "predicable_short_it" "no")
2921    (set_attr "type" "bfm")]
2924 ; constants for op 2 will never be given to these patterns.
2925 (define_insn_and_split "*anddi_notdi_di"
2926   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2927         (and:DI (not:DI (match_operand:DI 1 "s_register_operand" "0,r"))
2928                 (match_operand:DI 2 "s_register_operand" "r,0")))]
2929   "TARGET_32BIT"
2930   "#"
2931   "TARGET_32BIT && reload_completed
2932    && ! (TARGET_NEON && IS_VFP_REGNUM (REGNO (operands[0])))
2933    && ! IS_IWMMXT_REGNUM (REGNO (operands[0]))"
2934   [(set (match_dup 0) (and:SI (not:SI (match_dup 1)) (match_dup 2)))
2935    (set (match_dup 3) (and:SI (not:SI (match_dup 4)) (match_dup 5)))]
2936   "
2937   {
2938     operands[3] = gen_highpart (SImode, operands[0]);
2939     operands[0] = gen_lowpart (SImode, operands[0]);
2940     operands[4] = gen_highpart (SImode, operands[1]);
2941     operands[1] = gen_lowpart (SImode, operands[1]);
2942     operands[5] = gen_highpart (SImode, operands[2]);
2943     operands[2] = gen_lowpart (SImode, operands[2]);
2944   }"
2945   [(set_attr "length" "8")
2946    (set_attr "predicable" "yes")
2947    (set_attr "type" "multiple")]
2950 (define_insn_and_split "*anddi_notzesidi_di"
2951   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2952         (and:DI (not:DI (zero_extend:DI
2953                          (match_operand:SI 2 "s_register_operand" "r,r")))
2954                 (match_operand:DI 1 "s_register_operand" "0,?r")))]
2955   "TARGET_32BIT"
2956   "@
2957    bic%?\\t%Q0, %Q1, %2
2958    #"
2959   ; (not (zero_extend ...)) allows us to just copy the high word from
2960   ; operand1 to operand0.
2961   "TARGET_32BIT
2962    && reload_completed
2963    && operands[0] != operands[1]"
2964   [(set (match_dup 0) (and:SI (not:SI (match_dup 2)) (match_dup 1)))
2965    (set (match_dup 3) (match_dup 4))]
2966   "
2967   {
2968     operands[3] = gen_highpart (SImode, operands[0]);
2969     operands[0] = gen_lowpart (SImode, operands[0]);
2970     operands[4] = gen_highpart (SImode, operands[1]);
2971     operands[1] = gen_lowpart (SImode, operands[1]);
2972   }"
2973   [(set_attr "length" "4,8")
2974    (set_attr "predicable" "yes")
2975    (set_attr "predicable_short_it" "no")
2976    (set_attr "type" "multiple")]
2979 (define_insn_and_split "*anddi_notdi_zesidi"
2980   [(set (match_operand:DI 0 "s_register_operand" "=r")
2981         (and:DI (not:DI (match_operand:DI 2 "s_register_operand" "r"))
2982                 (zero_extend:DI
2983                  (match_operand:SI 1 "s_register_operand" "r"))))]
2984   "TARGET_32BIT"
2985   "#"
2986   "TARGET_32BIT && reload_completed"
2987   [(set (match_dup 0) (and:SI (not:SI (match_dup 2)) (match_dup 1)))
2988    (set (match_dup 3) (const_int 0))]
2989   "
2990   {
2991     operands[3] = gen_highpart (SImode, operands[0]);
2992     operands[0] = gen_lowpart (SImode, operands[0]);
2993     operands[2] = gen_lowpart (SImode, operands[2]);
2994   }"
2995   [(set_attr "length" "8")
2996    (set_attr "predicable" "yes")
2997    (set_attr "predicable_short_it" "no")
2998    (set_attr "type" "multiple")]
3001 (define_insn_and_split "*anddi_notsesidi_di"
3002   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
3003         (and:DI (not:DI (sign_extend:DI
3004                          (match_operand:SI 2 "s_register_operand" "r,r")))
3005                 (match_operand:DI 1 "s_register_operand" "0,r")))]
3006   "TARGET_32BIT"
3007   "#"
3008   "TARGET_32BIT && reload_completed"
3009   [(set (match_dup 0) (and:SI (not:SI (match_dup 2)) (match_dup 1)))
3010    (set (match_dup 3) (and:SI (not:SI
3011                                 (ashiftrt:SI (match_dup 2) (const_int 31)))
3012                                (match_dup 4)))]
3013   "
3014   {
3015     operands[3] = gen_highpart (SImode, operands[0]);
3016     operands[0] = gen_lowpart (SImode, operands[0]);
3017     operands[4] = gen_highpart (SImode, operands[1]);
3018     operands[1] = gen_lowpart (SImode, operands[1]);
3019   }"
3020   [(set_attr "length" "8")
3021    (set_attr "predicable" "yes")
3022    (set_attr "predicable_short_it" "no")
3023    (set_attr "type" "multiple")]
3026 (define_insn "andsi_notsi_si"
3027   [(set (match_operand:SI 0 "s_register_operand" "=r")
3028         (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
3029                 (match_operand:SI 1 "s_register_operand" "r")))]
3030   "TARGET_32BIT"
3031   "bic%?\\t%0, %1, %2"
3032   [(set_attr "predicable" "yes")
3033    (set_attr "predicable_short_it" "no")
3034    (set_attr "type" "logic_reg")]
3037 (define_insn "andsi_not_shiftsi_si"
3038   [(set (match_operand:SI 0 "s_register_operand" "=r")
3039         (and:SI (not:SI (match_operator:SI 4 "shift_operator"
3040                          [(match_operand:SI 2 "s_register_operand" "r")
3041                           (match_operand:SI 3 "arm_rhs_operand" "rM")]))
3042                 (match_operand:SI 1 "s_register_operand" "r")))]
3043   "TARGET_ARM"
3044   "bic%?\\t%0, %1, %2%S4"
3045   [(set_attr "predicable" "yes")
3046    (set_attr "shift" "2")
3047    (set (attr "type") (if_then_else (match_operand 3 "const_int_operand" "")
3048                       (const_string "logic_shift_imm")
3049                       (const_string "logic_shift_reg")))]
3052 ;; Shifted bics pattern used to set up CC status register and not reusing
3053 ;; bics output.  Pattern restricts Thumb2 shift operand as bics for Thumb2
3054 ;; does not support shift by register.
3055 (define_insn "andsi_not_shiftsi_si_scc_no_reuse"
3056   [(set (reg:CC_NOOV CC_REGNUM)
3057         (compare:CC_NOOV
3058                 (and:SI (not:SI (match_operator:SI 0 "shift_operator"
3059                         [(match_operand:SI 1 "s_register_operand" "r")
3060                          (match_operand:SI 2 "arm_rhs_operand" "rM")]))
3061                         (match_operand:SI 3 "s_register_operand" "r"))
3062                 (const_int 0)))
3063    (clobber (match_scratch:SI 4 "=r"))]
3064   "TARGET_ARM || (TARGET_THUMB2 && CONST_INT_P (operands[2]))"
3065   "bics%?\\t%4, %3, %1%S0"
3066   [(set_attr "predicable" "yes")
3067    (set_attr "predicable_short_it" "no")
3068    (set_attr "conds" "set")
3069    (set_attr "shift" "1")
3070    (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
3071                       (const_string "logic_shift_imm")
3072                       (const_string "logic_shift_reg")))]
3075 ;; Same as andsi_not_shiftsi_si_scc_no_reuse, but the bics result is also
3076 ;; getting reused later.
3077 (define_insn "andsi_not_shiftsi_si_scc"
3078   [(parallel [(set (reg:CC_NOOV CC_REGNUM)
3079         (compare:CC_NOOV
3080                 (and:SI (not:SI (match_operator:SI 0 "shift_operator"
3081                         [(match_operand:SI 1 "s_register_operand" "r")
3082                          (match_operand:SI 2 "arm_rhs_operand" "rM")]))
3083                         (match_operand:SI 3 "s_register_operand" "r"))
3084                 (const_int 0)))
3085         (set (match_operand:SI 4 "s_register_operand" "=r")
3086              (and:SI (not:SI (match_op_dup 0
3087                      [(match_dup 1)
3088                       (match_dup 2)]))
3089                      (match_dup 3)))])]
3090   "TARGET_ARM || (TARGET_THUMB2 && CONST_INT_P (operands[2]))"
3091   "bics%?\\t%4, %3, %1%S0"
3092   [(set_attr "predicable" "yes")
3093    (set_attr "predicable_short_it" "no")
3094    (set_attr "conds" "set")
3095    (set_attr "shift" "1")
3096    (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
3097                       (const_string "logic_shift_imm")
3098                       (const_string "logic_shift_reg")))]
3101 (define_insn "*andsi_notsi_si_compare0"
3102   [(set (reg:CC_NOOV CC_REGNUM)
3103         (compare:CC_NOOV
3104          (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
3105                  (match_operand:SI 1 "s_register_operand" "r"))
3106          (const_int 0)))
3107    (set (match_operand:SI 0 "s_register_operand" "=r")
3108         (and:SI (not:SI (match_dup 2)) (match_dup 1)))]
3109   "TARGET_32BIT"
3110   "bics\\t%0, %1, %2"
3111   [(set_attr "conds" "set")
3112    (set_attr "type" "logics_shift_reg")]
3115 (define_insn "*andsi_notsi_si_compare0_scratch"
3116   [(set (reg:CC_NOOV CC_REGNUM)
3117         (compare:CC_NOOV
3118          (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
3119                  (match_operand:SI 1 "s_register_operand" "r"))
3120          (const_int 0)))
3121    (clobber (match_scratch:SI 0 "=r"))]
3122   "TARGET_32BIT"
3123   "bics\\t%0, %1, %2"
3124   [(set_attr "conds" "set")
3125    (set_attr "type" "logics_shift_reg")]
3128 (define_expand "iordi3"
3129   [(set (match_operand:DI         0 "s_register_operand" "")
3130         (ior:DI (match_operand:DI 1 "s_register_operand" "")
3131                 (match_operand:DI 2 "neon_logic_op2" "")))]
3132   "TARGET_32BIT"
3133   ""
3136 (define_insn_and_split "*iordi3_insn"
3137   [(set (match_operand:DI         0 "s_register_operand"     "=w,w ,&r,&r,&r,&r,?w,?w")
3138         (ior:DI (match_operand:DI 1 "s_register_operand"     "%w,0 ,0 ,r ,0 ,r ,w ,0")
3139                 (match_operand:DI 2 "arm_iordi_operand_neon" "w ,Dl,r ,r ,Df,Df,w ,Dl")))]
3140   "TARGET_32BIT && !TARGET_IWMMXT"
3141   {
3142   switch (which_alternative)
3143     {
3144     case 0: /* fall through */
3145     case 6: return "vorr\t%P0, %P1, %P2";
3146     case 1: /* fall through */
3147     case 7: return neon_output_logic_immediate ("vorr", &operands[2],
3148                      DImode, 0, VALID_NEON_QREG_MODE (DImode));
3149     case 2:
3150     case 3:
3151     case 4:
3152     case 5:
3153       return "#";
3154     default: gcc_unreachable ();
3155     }
3156   }
3157   "TARGET_32BIT && !TARGET_IWMMXT && reload_completed
3158    && !(IS_VFP_REGNUM (REGNO (operands[0])))"
3159   [(set (match_dup 3) (match_dup 4))
3160    (set (match_dup 5) (match_dup 6))]
3161   "
3162   {
3163     operands[3] = gen_lowpart (SImode, operands[0]);
3164     operands[5] = gen_highpart (SImode, operands[0]);
3166     operands[4] = simplify_gen_binary (IOR, SImode,
3167                                            gen_lowpart (SImode, operands[1]),
3168                                            gen_lowpart (SImode, operands[2]));
3169     operands[6] = simplify_gen_binary (IOR, SImode,
3170                                            gen_highpart (SImode, operands[1]),
3171                                            gen_highpart_mode (SImode, DImode, operands[2]));
3173   }"
3174   [(set_attr "type" "neon_logic,neon_logic,multiple,multiple,multiple,\
3175                      multiple,neon_logic,neon_logic")
3176    (set_attr "length" "*,*,8,8,8,8,*,*")
3177    (set_attr "arch" "neon_for_64bits,neon_for_64bits,*,*,*,*,avoid_neon_for_64bits,avoid_neon_for_64bits")]
3180 (define_insn "*iordi_zesidi_di"
3181   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
3182         (ior:DI (zero_extend:DI
3183                  (match_operand:SI 2 "s_register_operand" "r,r"))
3184                 (match_operand:DI 1 "s_register_operand" "0,?r")))]
3185   "TARGET_32BIT"
3186   "@
3187    orr%?\\t%Q0, %Q1, %2
3188    #"
3189   [(set_attr "length" "4,8")
3190    (set_attr "predicable" "yes")
3191    (set_attr "predicable_short_it" "no")
3192    (set_attr "type" "logic_reg,multiple")]
3195 (define_insn "*iordi_sesidi_di"
3196   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
3197         (ior:DI (sign_extend:DI
3198                  (match_operand:SI 2 "s_register_operand" "r,r"))
3199                 (match_operand:DI 1 "s_register_operand" "0,r")))]
3200   "TARGET_32BIT"
3201   "#"
3202   [(set_attr "length" "8")
3203    (set_attr "predicable" "yes")
3204    (set_attr "type" "multiple")]
3207 (define_expand "iorsi3"
3208   [(set (match_operand:SI         0 "s_register_operand" "")
3209         (ior:SI (match_operand:SI 1 "s_register_operand" "")
3210                 (match_operand:SI 2 "reg_or_int_operand" "")))]
3211   "TARGET_EITHER"
3212   "
3213   if (CONST_INT_P (operands[2]))
3214     {
3215       if (TARGET_32BIT)
3216         {
3217           if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[2]), IOR))
3218             operands[2] = force_reg (SImode, operands[2]);
3219           else
3220             {
3221               arm_split_constant (IOR, SImode, NULL_RTX,
3222                                   INTVAL (operands[2]), operands[0],
3223                                   operands[1],
3224                                   optimize && can_create_pseudo_p ());
3225               DONE;
3226             }
3227         }
3228       else /* TARGET_THUMB1 */
3229         {
3230           rtx tmp = force_reg (SImode, operands[2]);
3231           if (rtx_equal_p (operands[0], operands[1]))
3232             operands[2] = tmp;
3233           else
3234             {
3235               operands[2] = operands[1];
3236               operands[1] = tmp;
3237             }
3238         }
3239     }
3240   "
3243 (define_insn_and_split "*iorsi3_insn"
3244   [(set (match_operand:SI 0 "s_register_operand" "=r,l,r,r,r")
3245         (ior:SI (match_operand:SI 1 "s_register_operand" "%r,0,r,r,r")
3246                 (match_operand:SI 2 "reg_or_int_operand" "I,l,K,r,?n")))]
3247   "TARGET_32BIT"
3248   "@
3249    orr%?\\t%0, %1, %2
3250    orr%?\\t%0, %1, %2
3251    orn%?\\t%0, %1, #%B2
3252    orr%?\\t%0, %1, %2
3253    #"
3254   "TARGET_32BIT
3255    && CONST_INT_P (operands[2])
3256    && !(const_ok_for_arm (INTVAL (operands[2]))
3257         || (TARGET_THUMB2 && const_ok_for_arm (~INTVAL (operands[2]))))"
3258   [(clobber (const_int 0))]
3260   arm_split_constant (IOR, SImode, curr_insn,
3261                       INTVAL (operands[2]), operands[0], operands[1], 0);
3262   DONE;
3264   [(set_attr "length" "4,4,4,4,16")
3265    (set_attr "arch" "32,t2,t2,32,32")
3266    (set_attr "predicable" "yes")
3267    (set_attr "predicable_short_it" "no,yes,no,no,no")
3268    (set_attr "type" "logic_imm,logic_reg,logic_imm,logic_reg,logic_reg")]
3271 (define_peephole2
3272   [(match_scratch:SI 3 "r")
3273    (set (match_operand:SI 0 "arm_general_register_operand" "")
3274         (ior:SI (match_operand:SI 1 "arm_general_register_operand" "")
3275                 (match_operand:SI 2 "const_int_operand" "")))]
3276   "TARGET_ARM
3277    && !const_ok_for_arm (INTVAL (operands[2]))
3278    && const_ok_for_arm (~INTVAL (operands[2]))"
3279   [(set (match_dup 3) (match_dup 2))
3280    (set (match_dup 0) (ior:SI (match_dup 1) (match_dup 3)))]
3281   ""
3284 (define_insn "*iorsi3_compare0"
3285   [(set (reg:CC_NOOV CC_REGNUM)
3286         (compare:CC_NOOV (ior:SI (match_operand:SI 1 "s_register_operand" "%r,r")
3287                                  (match_operand:SI 2 "arm_rhs_operand" "I,r"))
3288                          (const_int 0)))
3289    (set (match_operand:SI 0 "s_register_operand" "=r,r")
3290         (ior:SI (match_dup 1) (match_dup 2)))]
3291   "TARGET_32BIT"
3292   "orrs%?\\t%0, %1, %2"
3293   [(set_attr "conds" "set")
3294    (set_attr "type" "logics_imm,logics_reg")]
3297 (define_insn "*iorsi3_compare0_scratch"
3298   [(set (reg:CC_NOOV CC_REGNUM)
3299         (compare:CC_NOOV (ior:SI (match_operand:SI 1 "s_register_operand" "%r,r")
3300                                  (match_operand:SI 2 "arm_rhs_operand" "I,r"))
3301                          (const_int 0)))
3302    (clobber (match_scratch:SI 0 "=r,r"))]
3303   "TARGET_32BIT"
3304   "orrs%?\\t%0, %1, %2"
3305   [(set_attr "conds" "set")
3306    (set_attr "type" "logics_imm,logics_reg")]
3309 (define_expand "xordi3"
3310   [(set (match_operand:DI         0 "s_register_operand" "")
3311         (xor:DI (match_operand:DI 1 "s_register_operand" "")
3312                 (match_operand:DI 2 "arm_xordi_operand" "")))]
3313   "TARGET_32BIT"
3314   ""
3317 (define_insn_and_split "*xordi3_insn"
3318   [(set (match_operand:DI         0 "s_register_operand" "=w,&r,&r,&r,&r,?w")
3319         (xor:DI (match_operand:DI 1 "s_register_operand" "%w ,0,r ,0 ,r ,w")
3320                 (match_operand:DI 2 "arm_xordi_operand"  "w ,r ,r ,Dg,Dg,w")))]
3321   "TARGET_32BIT && !TARGET_IWMMXT"
3323   switch (which_alternative)
3324     {
3325     case 1:
3326     case 2:
3327     case 3:
3328     case 4:  /* fall through */
3329       return "#";
3330     case 0: /* fall through */
3331     case 5: return "veor\t%P0, %P1, %P2";
3332     default: gcc_unreachable ();
3333     }
3335   "TARGET_32BIT && !TARGET_IWMMXT && reload_completed
3336    && !(IS_VFP_REGNUM (REGNO (operands[0])))"
3337   [(set (match_dup 3) (match_dup 4))
3338    (set (match_dup 5) (match_dup 6))]
3339   "
3340   {
3341     operands[3] = gen_lowpart (SImode, operands[0]);
3342     operands[5] = gen_highpart (SImode, operands[0]);
3344     operands[4] = simplify_gen_binary (XOR, SImode,
3345                                            gen_lowpart (SImode, operands[1]),
3346                                            gen_lowpart (SImode, operands[2]));
3347     operands[6] = simplify_gen_binary (XOR, SImode,
3348                                            gen_highpart (SImode, operands[1]),
3349                                            gen_highpart_mode (SImode, DImode, operands[2]));
3351   }"
3352   [(set_attr "length" "*,8,8,8,8,*")
3353    (set_attr "type" "neon_logic,multiple,multiple,multiple,multiple,neon_logic")
3354    (set_attr "arch" "neon_for_64bits,*,*,*,*,avoid_neon_for_64bits")]
3357 (define_insn "*xordi_zesidi_di"
3358   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
3359         (xor:DI (zero_extend:DI
3360                  (match_operand:SI 2 "s_register_operand" "r,r"))
3361                 (match_operand:DI 1 "s_register_operand" "0,?r")))]
3362   "TARGET_32BIT"
3363   "@
3364    eor%?\\t%Q0, %Q1, %2
3365    #"
3366   [(set_attr "length" "4,8")
3367    (set_attr "predicable" "yes")
3368    (set_attr "predicable_short_it" "no")
3369    (set_attr "type" "logic_reg")]
3372 (define_insn "*xordi_sesidi_di"
3373   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
3374         (xor:DI (sign_extend:DI
3375                  (match_operand:SI 2 "s_register_operand" "r,r"))
3376                 (match_operand:DI 1 "s_register_operand" "0,r")))]
3377   "TARGET_32BIT"
3378   "#"
3379   [(set_attr "length" "8")
3380    (set_attr "predicable" "yes")
3381    (set_attr "type" "multiple")]
3384 (define_expand "xorsi3"
3385   [(set (match_operand:SI         0 "s_register_operand" "")
3386         (xor:SI (match_operand:SI 1 "s_register_operand" "")
3387                 (match_operand:SI 2 "reg_or_int_operand" "")))]
3388   "TARGET_EITHER"
3389   "if (CONST_INT_P (operands[2]))
3390     {
3391       if (TARGET_32BIT)
3392         {
3393           if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[2]), XOR))
3394             operands[2] = force_reg (SImode, operands[2]);
3395           else
3396             {
3397               arm_split_constant (XOR, SImode, NULL_RTX,
3398                                   INTVAL (operands[2]), operands[0],
3399                                   operands[1],
3400                                   optimize && can_create_pseudo_p ());
3401               DONE;
3402             }
3403         }
3404       else /* TARGET_THUMB1 */
3405         {
3406           rtx tmp = force_reg (SImode, operands[2]);
3407           if (rtx_equal_p (operands[0], operands[1]))
3408             operands[2] = tmp;
3409           else
3410             {
3411               operands[2] = operands[1];
3412               operands[1] = tmp;
3413             }
3414         }
3415     }"
3418 (define_insn_and_split "*arm_xorsi3"
3419   [(set (match_operand:SI         0 "s_register_operand" "=r,l,r,r")
3420         (xor:SI (match_operand:SI 1 "s_register_operand" "%r,0,r,r")
3421                 (match_operand:SI 2 "reg_or_int_operand" "I,l,r,?n")))]
3422   "TARGET_32BIT"
3423   "@
3424    eor%?\\t%0, %1, %2
3425    eor%?\\t%0, %1, %2
3426    eor%?\\t%0, %1, %2
3427    #"
3428   "TARGET_32BIT
3429    && CONST_INT_P (operands[2])
3430    && !const_ok_for_arm (INTVAL (operands[2]))"
3431   [(clobber (const_int 0))]
3433   arm_split_constant (XOR, SImode, curr_insn,
3434                       INTVAL (operands[2]), operands[0], operands[1], 0);
3435   DONE;
3437   [(set_attr "length" "4,4,4,16")
3438    (set_attr "predicable" "yes")
3439    (set_attr "predicable_short_it" "no,yes,no,no")
3440    (set_attr "type"  "logic_imm,logic_reg,logic_reg,multiple")]
3443 (define_insn "*xorsi3_compare0"
3444   [(set (reg:CC_NOOV CC_REGNUM)
3445         (compare:CC_NOOV (xor:SI (match_operand:SI 1 "s_register_operand" "r,r")
3446                                  (match_operand:SI 2 "arm_rhs_operand" "I,r"))
3447                          (const_int 0)))
3448    (set (match_operand:SI 0 "s_register_operand" "=r,r")
3449         (xor:SI (match_dup 1) (match_dup 2)))]
3450   "TARGET_32BIT"
3451   "eors%?\\t%0, %1, %2"
3452   [(set_attr "conds" "set")
3453    (set_attr "type" "logics_imm,logics_reg")]
3456 (define_insn "*xorsi3_compare0_scratch"
3457   [(set (reg:CC_NOOV CC_REGNUM)
3458         (compare:CC_NOOV (xor:SI (match_operand:SI 0 "s_register_operand" "r,r")
3459                                  (match_operand:SI 1 "arm_rhs_operand" "I,r"))
3460                          (const_int 0)))]
3461   "TARGET_32BIT"
3462   "teq%?\\t%0, %1"
3463   [(set_attr "conds" "set")
3464    (set_attr "type" "logics_imm,logics_reg")]
3467 ; By splitting (IOR (AND (NOT A) (NOT B)) C) as D = AND (IOR A B) (NOT C), 
3468 ; (NOT D) we can sometimes merge the final NOT into one of the following
3469 ; insns.
3471 (define_split
3472   [(set (match_operand:SI 0 "s_register_operand" "")
3473         (ior:SI (and:SI (not:SI (match_operand:SI 1 "s_register_operand" ""))
3474                         (not:SI (match_operand:SI 2 "arm_rhs_operand" "")))
3475                 (match_operand:SI 3 "arm_rhs_operand" "")))
3476    (clobber (match_operand:SI 4 "s_register_operand" ""))]
3477   "TARGET_32BIT"
3478   [(set (match_dup 4) (and:SI (ior:SI (match_dup 1) (match_dup 2))
3479                               (not:SI (match_dup 3))))
3480    (set (match_dup 0) (not:SI (match_dup 4)))]
3481   ""
3484 (define_insn_and_split "*andsi_iorsi3_notsi"
3485   [(set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r")
3486         (and:SI (ior:SI (match_operand:SI 1 "s_register_operand" "%0,r,r")
3487                         (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI"))
3488                 (not:SI (match_operand:SI 3 "arm_rhs_operand" "rI,rI,rI"))))]
3489   "TARGET_32BIT"
3490   "#"   ; "orr%?\\t%0, %1, %2\;bic%?\\t%0, %0, %3"
3491   "&& reload_completed"
3492   [(set (match_dup 0) (ior:SI (match_dup 1) (match_dup 2)))
3493    (set (match_dup 0) (and:SI (match_dup 4) (match_dup 5)))]
3494   {
3495      /* If operands[3] is a constant make sure to fold the NOT into it
3496         to avoid creating a NOT of a CONST_INT.  */
3497     rtx not_rtx = simplify_gen_unary (NOT, SImode, operands[3], SImode);
3498     if (CONST_INT_P (not_rtx))
3499       {
3500         operands[4] = operands[0];
3501         operands[5] = not_rtx;
3502       }
3503     else
3504       {
3505         operands[5] = operands[0];
3506         operands[4] = not_rtx;
3507       }
3508   }
3509   [(set_attr "length" "8")
3510    (set_attr "ce_count" "2")
3511    (set_attr "predicable" "yes")
3512    (set_attr "predicable_short_it" "no")
3513    (set_attr "type" "multiple")]
3516 ; ??? Are these four splitters still beneficial when the Thumb-2 bitfield
3517 ; insns are available?
3518 (define_split
3519   [(set (match_operand:SI 0 "s_register_operand" "")
3520         (match_operator:SI 1 "logical_binary_operator"
3521          [(zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
3522                            (match_operand:SI 3 "const_int_operand" "")
3523                            (match_operand:SI 4 "const_int_operand" ""))
3524           (match_operator:SI 9 "logical_binary_operator"
3525            [(lshiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3526                          (match_operand:SI 6 "const_int_operand" ""))
3527             (match_operand:SI 7 "s_register_operand" "")])]))
3528    (clobber (match_operand:SI 8 "s_register_operand" ""))]
3529   "TARGET_32BIT
3530    && GET_CODE (operands[1]) == GET_CODE (operands[9])
3531    && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3532   [(set (match_dup 8)
3533         (match_op_dup 1
3534          [(ashift:SI (match_dup 2) (match_dup 4))
3535           (match_dup 5)]))
3536    (set (match_dup 0)
3537         (match_op_dup 1
3538          [(lshiftrt:SI (match_dup 8) (match_dup 6))
3539           (match_dup 7)]))]
3540   "
3541   operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3544 (define_split
3545   [(set (match_operand:SI 0 "s_register_operand" "")
3546         (match_operator:SI 1 "logical_binary_operator"
3547          [(match_operator:SI 9 "logical_binary_operator"
3548            [(lshiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3549                          (match_operand:SI 6 "const_int_operand" ""))
3550             (match_operand:SI 7 "s_register_operand" "")])
3551           (zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
3552                            (match_operand:SI 3 "const_int_operand" "")
3553                            (match_operand:SI 4 "const_int_operand" ""))]))
3554    (clobber (match_operand:SI 8 "s_register_operand" ""))]
3555   "TARGET_32BIT
3556    && GET_CODE (operands[1]) == GET_CODE (operands[9])
3557    && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3558   [(set (match_dup 8)
3559         (match_op_dup 1
3560          [(ashift:SI (match_dup 2) (match_dup 4))
3561           (match_dup 5)]))
3562    (set (match_dup 0)
3563         (match_op_dup 1
3564          [(lshiftrt:SI (match_dup 8) (match_dup 6))
3565           (match_dup 7)]))]
3566   "
3567   operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3570 (define_split
3571   [(set (match_operand:SI 0 "s_register_operand" "")
3572         (match_operator:SI 1 "logical_binary_operator"
3573          [(sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
3574                            (match_operand:SI 3 "const_int_operand" "")
3575                            (match_operand:SI 4 "const_int_operand" ""))
3576           (match_operator:SI 9 "logical_binary_operator"
3577            [(ashiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3578                          (match_operand:SI 6 "const_int_operand" ""))
3579             (match_operand:SI 7 "s_register_operand" "")])]))
3580    (clobber (match_operand:SI 8 "s_register_operand" ""))]
3581   "TARGET_32BIT
3582    && GET_CODE (operands[1]) == GET_CODE (operands[9])
3583    && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3584   [(set (match_dup 8)
3585         (match_op_dup 1
3586          [(ashift:SI (match_dup 2) (match_dup 4))
3587           (match_dup 5)]))
3588    (set (match_dup 0)
3589         (match_op_dup 1
3590          [(ashiftrt:SI (match_dup 8) (match_dup 6))
3591           (match_dup 7)]))]
3592   "
3593   operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3596 (define_split
3597   [(set (match_operand:SI 0 "s_register_operand" "")
3598         (match_operator:SI 1 "logical_binary_operator"
3599          [(match_operator:SI 9 "logical_binary_operator"
3600            [(ashiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3601                          (match_operand:SI 6 "const_int_operand" ""))
3602             (match_operand:SI 7 "s_register_operand" "")])
3603           (sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
3604                            (match_operand:SI 3 "const_int_operand" "")
3605                            (match_operand:SI 4 "const_int_operand" ""))]))
3606    (clobber (match_operand:SI 8 "s_register_operand" ""))]
3607   "TARGET_32BIT
3608    && GET_CODE (operands[1]) == GET_CODE (operands[9])
3609    && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3610   [(set (match_dup 8)
3611         (match_op_dup 1
3612          [(ashift:SI (match_dup 2) (match_dup 4))
3613           (match_dup 5)]))
3614    (set (match_dup 0)
3615         (match_op_dup 1
3616          [(ashiftrt:SI (match_dup 8) (match_dup 6))
3617           (match_dup 7)]))]
3618   "
3619   operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3623 ;; Minimum and maximum insns
3625 (define_expand "smaxsi3"
3626   [(parallel [
3627     (set (match_operand:SI 0 "s_register_operand" "")
3628          (smax:SI (match_operand:SI 1 "s_register_operand" "")
3629                   (match_operand:SI 2 "arm_rhs_operand" "")))
3630     (clobber (reg:CC CC_REGNUM))])]
3631   "TARGET_32BIT"
3632   "
3633   if (operands[2] == const0_rtx || operands[2] == constm1_rtx)
3634     {
3635       /* No need for a clobber of the condition code register here.  */
3636       emit_insn (gen_rtx_SET (operands[0],
3637                               gen_rtx_SMAX (SImode, operands[1],
3638                                             operands[2])));
3639       DONE;
3640     }
3643 (define_insn "*smax_0"
3644   [(set (match_operand:SI 0 "s_register_operand" "=r")
3645         (smax:SI (match_operand:SI 1 "s_register_operand" "r")
3646                  (const_int 0)))]
3647   "TARGET_32BIT"
3648   "bic%?\\t%0, %1, %1, asr #31"
3649   [(set_attr "predicable" "yes")
3650    (set_attr "predicable_short_it" "no")
3651    (set_attr "type" "logic_shift_reg")]
3654 (define_insn "*smax_m1"
3655   [(set (match_operand:SI 0 "s_register_operand" "=r")
3656         (smax:SI (match_operand:SI 1 "s_register_operand" "r")
3657                  (const_int -1)))]
3658   "TARGET_32BIT"
3659   "orr%?\\t%0, %1, %1, asr #31"
3660   [(set_attr "predicable" "yes")
3661    (set_attr "predicable_short_it" "no")
3662    (set_attr "type" "logic_shift_reg")]
3665 (define_insn_and_split "*arm_smax_insn"
3666   [(set (match_operand:SI          0 "s_register_operand" "=r,r")
3667         (smax:SI (match_operand:SI 1 "s_register_operand"  "%0,?r")
3668                  (match_operand:SI 2 "arm_rhs_operand"    "rI,rI")))
3669    (clobber (reg:CC CC_REGNUM))]
3670   "TARGET_ARM"
3671   "#"
3672    ; cmp\\t%1, %2\;movlt\\t%0, %2
3673    ; cmp\\t%1, %2\;movge\\t%0, %1\;movlt\\t%0, %2"
3674   "TARGET_ARM"
3675   [(set (reg:CC CC_REGNUM)
3676         (compare:CC (match_dup 1) (match_dup 2)))
3677    (set (match_dup 0)
3678         (if_then_else:SI (ge:SI (reg:CC CC_REGNUM) (const_int 0))
3679                          (match_dup 1)
3680                          (match_dup 2)))]
3681   ""
3682   [(set_attr "conds" "clob")
3683    (set_attr "length" "8,12")
3684    (set_attr "type" "multiple")]
3687 (define_expand "sminsi3"
3688   [(parallel [
3689     (set (match_operand:SI 0 "s_register_operand" "")
3690          (smin:SI (match_operand:SI 1 "s_register_operand" "")
3691                   (match_operand:SI 2 "arm_rhs_operand" "")))
3692     (clobber (reg:CC CC_REGNUM))])]
3693   "TARGET_32BIT"
3694   "
3695   if (operands[2] == const0_rtx)
3696     {
3697       /* No need for a clobber of the condition code register here.  */
3698       emit_insn (gen_rtx_SET (operands[0],
3699                               gen_rtx_SMIN (SImode, operands[1],
3700                                             operands[2])));
3701       DONE;
3702     }
3705 (define_insn "*smin_0"
3706   [(set (match_operand:SI 0 "s_register_operand" "=r")
3707         (smin:SI (match_operand:SI 1 "s_register_operand" "r")
3708                  (const_int 0)))]
3709   "TARGET_32BIT"
3710   "and%?\\t%0, %1, %1, asr #31"
3711   [(set_attr "predicable" "yes")
3712    (set_attr "predicable_short_it" "no")
3713    (set_attr "type" "logic_shift_reg")]
3716 (define_insn_and_split "*arm_smin_insn"
3717   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3718         (smin:SI (match_operand:SI 1 "s_register_operand" "%0,?r")
3719                  (match_operand:SI 2 "arm_rhs_operand" "rI,rI")))
3720    (clobber (reg:CC CC_REGNUM))]
3721   "TARGET_ARM"
3722   "#"
3723     ; cmp\\t%1, %2\;movge\\t%0, %2
3724     ; cmp\\t%1, %2\;movlt\\t%0, %1\;movge\\t%0, %2"
3725   "TARGET_ARM"
3726   [(set (reg:CC CC_REGNUM)
3727         (compare:CC (match_dup 1) (match_dup 2)))
3728    (set (match_dup 0)
3729         (if_then_else:SI (lt:SI (reg:CC CC_REGNUM) (const_int 0))
3730                          (match_dup 1)
3731                          (match_dup 2)))]
3732   ""
3733   [(set_attr "conds" "clob")
3734    (set_attr "length" "8,12")
3735    (set_attr "type" "multiple,multiple")]
3738 (define_expand "umaxsi3"
3739   [(parallel [
3740     (set (match_operand:SI 0 "s_register_operand" "")
3741          (umax:SI (match_operand:SI 1 "s_register_operand" "")
3742                   (match_operand:SI 2 "arm_rhs_operand" "")))
3743     (clobber (reg:CC CC_REGNUM))])]
3744   "TARGET_32BIT"
3745   ""
3748 (define_insn_and_split "*arm_umaxsi3"
3749   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
3750         (umax:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
3751                  (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
3752    (clobber (reg:CC CC_REGNUM))]
3753   "TARGET_ARM"
3754   "#"
3755     ; cmp\\t%1, %2\;movcc\\t%0, %2
3756     ; cmp\\t%1, %2\;movcs\\t%0, %1
3757     ; cmp\\t%1, %2\;movcs\\t%0, %1\;movcc\\t%0, %2"
3758   "TARGET_ARM"
3759   [(set (reg:CC CC_REGNUM)
3760         (compare:CC (match_dup 1) (match_dup 2)))
3761    (set (match_dup 0)
3762         (if_then_else:SI (geu:SI (reg:CC CC_REGNUM) (const_int 0))
3763                          (match_dup 1)
3764                          (match_dup 2)))]
3765   ""
3766   [(set_attr "conds" "clob")
3767    (set_attr "length" "8,8,12")
3768    (set_attr "type" "store1")]
3771 (define_expand "uminsi3"
3772   [(parallel [
3773     (set (match_operand:SI 0 "s_register_operand" "")
3774          (umin:SI (match_operand:SI 1 "s_register_operand" "")
3775                   (match_operand:SI 2 "arm_rhs_operand" "")))
3776     (clobber (reg:CC CC_REGNUM))])]
3777   "TARGET_32BIT"
3778   ""
3781 (define_insn_and_split "*arm_uminsi3"
3782   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
3783         (umin:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
3784                  (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
3785    (clobber (reg:CC CC_REGNUM))]
3786   "TARGET_ARM"
3787   "#"
3788    ; cmp\\t%1, %2\;movcs\\t%0, %2
3789    ; cmp\\t%1, %2\;movcc\\t%0, %1
3790    ; cmp\\t%1, %2\;movcc\\t%0, %1\;movcs\\t%0, %2"
3791   "TARGET_ARM"
3792   [(set (reg:CC CC_REGNUM)
3793         (compare:CC (match_dup 1) (match_dup 2)))
3794    (set (match_dup 0)
3795         (if_then_else:SI (ltu:SI (reg:CC CC_REGNUM) (const_int 0))
3796                          (match_dup 1)
3797                          (match_dup 2)))]
3798   ""
3799   [(set_attr "conds" "clob")
3800    (set_attr "length" "8,8,12")
3801    (set_attr "type" "store1")]
3804 (define_insn "*store_minmaxsi"
3805   [(set (match_operand:SI 0 "memory_operand" "=m")
3806         (match_operator:SI 3 "minmax_operator"
3807          [(match_operand:SI 1 "s_register_operand" "r")
3808           (match_operand:SI 2 "s_register_operand" "r")]))
3809    (clobber (reg:CC CC_REGNUM))]
3810   "TARGET_32BIT && optimize_function_for_size_p (cfun) && !arm_restrict_it"
3811   "*
3812   operands[3] = gen_rtx_fmt_ee (minmax_code (operands[3]), SImode,
3813                                 operands[1], operands[2]);
3814   output_asm_insn (\"cmp\\t%1, %2\", operands);
3815   if (TARGET_THUMB2)
3816     output_asm_insn (\"ite\t%d3\", operands);
3817   output_asm_insn (\"str%d3\\t%1, %0\", operands);
3818   output_asm_insn (\"str%D3\\t%2, %0\", operands);
3819   return \"\";
3820   "
3821   [(set_attr "conds" "clob")
3822    (set (attr "length")
3823         (if_then_else (eq_attr "is_thumb" "yes")
3824                       (const_int 14)
3825                       (const_int 12)))
3826    (set_attr "type" "store1")]
3829 ; Reject the frame pointer in operand[1], since reloading this after
3830 ; it has been eliminated can cause carnage.
3831 (define_insn "*minmax_arithsi"
3832   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3833         (match_operator:SI 4 "shiftable_operator"
3834          [(match_operator:SI 5 "minmax_operator"
3835            [(match_operand:SI 2 "s_register_operand" "r,r")
3836             (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
3837           (match_operand:SI 1 "s_register_operand" "0,?r")]))
3838    (clobber (reg:CC CC_REGNUM))]
3839   "TARGET_32BIT && !arm_eliminable_register (operands[1]) && !arm_restrict_it"
3840   "*
3841   {
3842     enum rtx_code code = GET_CODE (operands[4]);
3843     bool need_else;
3845     if (which_alternative != 0 || operands[3] != const0_rtx
3846         || (code != PLUS && code != IOR && code != XOR))
3847       need_else = true;
3848     else
3849       need_else = false;
3851     operands[5] = gen_rtx_fmt_ee (minmax_code (operands[5]), SImode,
3852                                   operands[2], operands[3]);
3853     output_asm_insn (\"cmp\\t%2, %3\", operands);
3854     if (TARGET_THUMB2)
3855       {
3856         if (need_else)
3857           output_asm_insn (\"ite\\t%d5\", operands);
3858         else
3859           output_asm_insn (\"it\\t%d5\", operands);
3860       }
3861     output_asm_insn (\"%i4%d5\\t%0, %1, %2\", operands);
3862     if (need_else)
3863       output_asm_insn (\"%i4%D5\\t%0, %1, %3\", operands);
3864     return \"\";
3865   }"
3866   [(set_attr "conds" "clob")
3867    (set (attr "length")
3868         (if_then_else (eq_attr "is_thumb" "yes")
3869                       (const_int 14)
3870                       (const_int 12)))
3871    (set_attr "type" "multiple")]
3874 ; Reject the frame pointer in operand[1], since reloading this after
3875 ; it has been eliminated can cause carnage.
3876 (define_insn_and_split "*minmax_arithsi_non_canon"
3877   [(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts")
3878         (minus:SI
3879          (match_operand:SI 1 "s_register_operand" "0,?Ts")
3880           (match_operator:SI 4 "minmax_operator"
3881            [(match_operand:SI 2 "s_register_operand" "Ts,Ts")
3882             (match_operand:SI 3 "arm_rhs_operand" "TsI,TsI")])))
3883    (clobber (reg:CC CC_REGNUM))]
3884   "TARGET_32BIT && !arm_eliminable_register (operands[1])
3885    && !(arm_restrict_it && CONST_INT_P (operands[3]))"
3886   "#"
3887   "TARGET_32BIT && !arm_eliminable_register (operands[1]) && reload_completed"
3888   [(set (reg:CC CC_REGNUM)
3889         (compare:CC (match_dup 2) (match_dup 3)))
3891    (cond_exec (match_op_dup 4 [(reg:CC CC_REGNUM) (const_int 0)])
3892               (set (match_dup 0)
3893                    (minus:SI (match_dup 1)
3894                              (match_dup 2))))
3895    (cond_exec (match_op_dup 5 [(reg:CC CC_REGNUM) (const_int 0)])
3896               (set (match_dup 0)
3897                    (match_dup 6)))]
3898   {
3899   machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
3900                                            operands[2], operands[3]);
3901   enum rtx_code rc = minmax_code (operands[4]);
3902   operands[4] = gen_rtx_fmt_ee (rc, VOIDmode,
3903                                 operands[2], operands[3]);
3905   if (mode == CCFPmode || mode == CCFPEmode)
3906     rc = reverse_condition_maybe_unordered (rc);
3907   else
3908     rc = reverse_condition (rc);
3909   operands[5] = gen_rtx_fmt_ee (rc, SImode, operands[2], operands[3]);
3910   if (CONST_INT_P (operands[3]))
3911     operands[6] = plus_constant (SImode, operands[1], -INTVAL (operands[3]));
3912   else
3913     operands[6] = gen_rtx_MINUS (SImode, operands[1], operands[3]);
3914   }
3915   [(set_attr "conds" "clob")
3916    (set (attr "length")
3917         (if_then_else (eq_attr "is_thumb" "yes")
3918                       (const_int 14)
3919                       (const_int 12)))
3920    (set_attr "type" "multiple")]
3923 (define_code_iterator SAT [smin smax])
3924 (define_code_iterator SATrev [smin smax])
3925 (define_code_attr SATlo [(smin "1") (smax "2")])
3926 (define_code_attr SAThi [(smin "2") (smax "1")])
3928 (define_insn "*satsi_<SAT:code>"
3929   [(set (match_operand:SI 0 "s_register_operand" "=r")
3930         (SAT:SI (SATrev:SI (match_operand:SI 3 "s_register_operand" "r")
3931                            (match_operand:SI 1 "const_int_operand" "i"))
3932                 (match_operand:SI 2 "const_int_operand" "i")))]
3933   "TARGET_32BIT && arm_arch6 && <SAT:CODE> != <SATrev:CODE>
3934    && arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>], NULL, NULL)"
3936   int mask;
3937   bool signed_sat;
3938   if (!arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>],
3939                                &mask, &signed_sat))
3940     gcc_unreachable ();
3942   operands[1] = GEN_INT (mask);
3943   if (signed_sat)
3944     return "ssat%?\t%0, %1, %3";
3945   else
3946     return "usat%?\t%0, %1, %3";
3948   [(set_attr "predicable" "yes")
3949    (set_attr "predicable_short_it" "no")
3950    (set_attr "type" "alus_imm")]
3953 (define_insn "*satsi_<SAT:code>_shift"
3954   [(set (match_operand:SI 0 "s_register_operand" "=r")
3955         (SAT:SI (SATrev:SI (match_operator:SI 3 "sat_shift_operator"
3956                              [(match_operand:SI 4 "s_register_operand" "r")
3957                               (match_operand:SI 5 "const_int_operand" "i")])
3958                            (match_operand:SI 1 "const_int_operand" "i"))
3959                 (match_operand:SI 2 "const_int_operand" "i")))]
3960   "TARGET_32BIT && arm_arch6 && <SAT:CODE> != <SATrev:CODE>
3961    && arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>], NULL, NULL)"
3963   int mask;
3964   bool signed_sat;
3965   if (!arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>],
3966                                &mask, &signed_sat))
3967     gcc_unreachable ();
3969   operands[1] = GEN_INT (mask);
3970   if (signed_sat)
3971     return "ssat%?\t%0, %1, %4%S3";
3972   else
3973     return "usat%?\t%0, %1, %4%S3";
3975   [(set_attr "predicable" "yes")
3976    (set_attr "predicable_short_it" "no")
3977    (set_attr "shift" "3")
3978    (set_attr "type" "logic_shift_reg")])
3980 ;; Shift and rotation insns
3982 (define_expand "ashldi3"
3983   [(set (match_operand:DI            0 "s_register_operand" "")
3984         (ashift:DI (match_operand:DI 1 "s_register_operand" "")
3985                    (match_operand:SI 2 "general_operand" "")))]
3986   "TARGET_32BIT"
3987   "
3988   if (TARGET_NEON)
3989     {
3990       /* Delay the decision whether to use NEON or core-regs until
3991          register allocation.  */
3992       emit_insn (gen_ashldi3_neon (operands[0], operands[1], operands[2]));
3993       DONE;
3994     }
3995   else
3996     {
3997       /* Only the NEON case can handle in-memory shift counts.  */
3998       if (!reg_or_int_operand (operands[2], SImode))
3999         operands[2] = force_reg (SImode, operands[2]);
4000     }
4002   if (!CONST_INT_P (operands[2]) && TARGET_REALLY_IWMMXT)
4003     ; /* No special preparation statements; expand pattern as above.  */
4004   else
4005     {
4006       rtx scratch1, scratch2;
4008       if (operands[2] == CONST1_RTX (SImode))
4009         {
4010           emit_insn (gen_arm_ashldi3_1bit (operands[0], operands[1]));
4011           DONE;
4012         }
4014       /* Ideally we should use iwmmxt here if we could know that operands[1]
4015          ends up already living in an iwmmxt register. Otherwise it's
4016          cheaper to have the alternate code being generated than moving
4017          values to iwmmxt regs and back.  */
4019       /* Expand operation using core-registers.
4020          'FAIL' would achieve the same thing, but this is a bit smarter.  */
4021       scratch1 = gen_reg_rtx (SImode);
4022       scratch2 = gen_reg_rtx (SImode);
4023       arm_emit_coreregs_64bit_shift (ASHIFT, operands[0], operands[1],
4024                                      operands[2], scratch1, scratch2);
4025       DONE;
4026     }
4027   "
4030 (define_insn "arm_ashldi3_1bit"
4031   [(set (match_operand:DI            0 "s_register_operand" "=r,&r")
4032         (ashift:DI (match_operand:DI 1 "s_register_operand" "0,r")
4033                    (const_int 1)))
4034    (clobber (reg:CC CC_REGNUM))]
4035   "TARGET_32BIT"
4036   "movs\\t%Q0, %Q1, asl #1\;adc\\t%R0, %R1, %R1"
4037   [(set_attr "conds" "clob")
4038    (set_attr "length" "8")
4039    (set_attr "type" "multiple")]
4042 (define_expand "ashlsi3"
4043   [(set (match_operand:SI            0 "s_register_operand" "")
4044         (ashift:SI (match_operand:SI 1 "s_register_operand" "")
4045                    (match_operand:SI 2 "arm_rhs_operand" "")))]
4046   "TARGET_EITHER"
4047   "
4048   if (CONST_INT_P (operands[2])
4049       && (UINTVAL (operands[2])) > 31)
4050     {
4051       emit_insn (gen_movsi (operands[0], const0_rtx));
4052       DONE;
4053     }
4054   "
4057 (define_expand "ashrdi3"
4058   [(set (match_operand:DI              0 "s_register_operand" "")
4059         (ashiftrt:DI (match_operand:DI 1 "s_register_operand" "")
4060                      (match_operand:SI 2 "reg_or_int_operand" "")))]
4061   "TARGET_32BIT"
4062   "
4063   if (TARGET_NEON)
4064     {
4065       /* Delay the decision whether to use NEON or core-regs until
4066          register allocation.  */
4067       emit_insn (gen_ashrdi3_neon (operands[0], operands[1], operands[2]));
4068       DONE;
4069     }
4071   if (!CONST_INT_P (operands[2]) && TARGET_REALLY_IWMMXT)
4072     ; /* No special preparation statements; expand pattern as above.  */
4073   else
4074     {
4075       rtx scratch1, scratch2;
4077       if (operands[2] == CONST1_RTX (SImode))
4078         {
4079           emit_insn (gen_arm_ashrdi3_1bit (operands[0], operands[1]));
4080           DONE;
4081         }
4083       /* Ideally we should use iwmmxt here if we could know that operands[1]
4084          ends up already living in an iwmmxt register. Otherwise it's
4085          cheaper to have the alternate code being generated than moving
4086          values to iwmmxt regs and back.  */
4088       /* Expand operation using core-registers.
4089          'FAIL' would achieve the same thing, but this is a bit smarter.  */
4090       scratch1 = gen_reg_rtx (SImode);
4091       scratch2 = gen_reg_rtx (SImode);
4092       arm_emit_coreregs_64bit_shift (ASHIFTRT, operands[0], operands[1],
4093                                      operands[2], scratch1, scratch2);
4094       DONE;
4095     }
4096   "
4099 (define_insn "arm_ashrdi3_1bit"
4100   [(set (match_operand:DI              0 "s_register_operand" "=r,&r")
4101         (ashiftrt:DI (match_operand:DI 1 "s_register_operand" "0,r")
4102                      (const_int 1)))
4103    (clobber (reg:CC CC_REGNUM))]
4104   "TARGET_32BIT"
4105   "movs\\t%R0, %R1, asr #1\;mov\\t%Q0, %Q1, rrx"
4106   [(set_attr "conds" "clob")
4107    (set_attr "length" "8")
4108    (set_attr "type" "multiple")]
4111 (define_expand "ashrsi3"
4112   [(set (match_operand:SI              0 "s_register_operand" "")
4113         (ashiftrt:SI (match_operand:SI 1 "s_register_operand" "")
4114                      (match_operand:SI 2 "arm_rhs_operand" "")))]
4115   "TARGET_EITHER"
4116   "
4117   if (CONST_INT_P (operands[2])
4118       && UINTVAL (operands[2]) > 31)
4119     operands[2] = GEN_INT (31);
4120   "
4123 (define_expand "lshrdi3"
4124   [(set (match_operand:DI              0 "s_register_operand" "")
4125         (lshiftrt:DI (match_operand:DI 1 "s_register_operand" "")
4126                      (match_operand:SI 2 "reg_or_int_operand" "")))]
4127   "TARGET_32BIT"
4128   "
4129   if (TARGET_NEON)
4130     {
4131       /* Delay the decision whether to use NEON or core-regs until
4132          register allocation.  */
4133       emit_insn (gen_lshrdi3_neon (operands[0], operands[1], operands[2]));
4134       DONE;
4135     }
4137   if (!CONST_INT_P (operands[2]) && TARGET_REALLY_IWMMXT)
4138     ; /* No special preparation statements; expand pattern as above.  */
4139   else
4140     {
4141       rtx scratch1, scratch2;
4143       if (operands[2] == CONST1_RTX (SImode))
4144         {
4145           emit_insn (gen_arm_lshrdi3_1bit (operands[0], operands[1]));
4146           DONE;
4147         }
4149       /* Ideally we should use iwmmxt here if we could know that operands[1]
4150          ends up already living in an iwmmxt register. Otherwise it's
4151          cheaper to have the alternate code being generated than moving
4152          values to iwmmxt regs and back.  */
4154       /* Expand operation using core-registers.
4155          'FAIL' would achieve the same thing, but this is a bit smarter.  */
4156       scratch1 = gen_reg_rtx (SImode);
4157       scratch2 = gen_reg_rtx (SImode);
4158       arm_emit_coreregs_64bit_shift (LSHIFTRT, operands[0], operands[1],
4159                                      operands[2], scratch1, scratch2);
4160       DONE;
4161     }
4162   "
4165 (define_insn "arm_lshrdi3_1bit"
4166   [(set (match_operand:DI              0 "s_register_operand" "=r,&r")
4167         (lshiftrt:DI (match_operand:DI 1 "s_register_operand" "0,r")
4168                      (const_int 1)))
4169    (clobber (reg:CC CC_REGNUM))]
4170   "TARGET_32BIT"
4171   "movs\\t%R0, %R1, lsr #1\;mov\\t%Q0, %Q1, rrx"
4172   [(set_attr "conds" "clob")
4173    (set_attr "length" "8")
4174    (set_attr "type" "multiple")]
4177 (define_expand "lshrsi3"
4178   [(set (match_operand:SI              0 "s_register_operand" "")
4179         (lshiftrt:SI (match_operand:SI 1 "s_register_operand" "")
4180                      (match_operand:SI 2 "arm_rhs_operand" "")))]
4181   "TARGET_EITHER"
4182   "
4183   if (CONST_INT_P (operands[2])
4184       && (UINTVAL (operands[2])) > 31)
4185     {
4186       emit_insn (gen_movsi (operands[0], const0_rtx));
4187       DONE;
4188     }
4189   "
4192 (define_expand "rotlsi3"
4193   [(set (match_operand:SI              0 "s_register_operand" "")
4194         (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
4195                      (match_operand:SI 2 "reg_or_int_operand" "")))]
4196   "TARGET_32BIT"
4197   "
4198   if (CONST_INT_P (operands[2]))
4199     operands[2] = GEN_INT ((32 - INTVAL (operands[2])) % 32);
4200   else
4201     {
4202       rtx reg = gen_reg_rtx (SImode);
4203       emit_insn (gen_subsi3 (reg, GEN_INT (32), operands[2]));
4204       operands[2] = reg;
4205     }
4206   "
4209 (define_expand "rotrsi3"
4210   [(set (match_operand:SI              0 "s_register_operand" "")
4211         (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
4212                      (match_operand:SI 2 "arm_rhs_operand" "")))]
4213   "TARGET_EITHER"
4214   "
4215   if (TARGET_32BIT)
4216     {
4217       if (CONST_INT_P (operands[2])
4218           && UINTVAL (operands[2]) > 31)
4219         operands[2] = GEN_INT (INTVAL (operands[2]) % 32);
4220     }
4221   else /* TARGET_THUMB1 */
4222     {
4223       if (CONST_INT_P (operands [2]))
4224         operands [2] = force_reg (SImode, operands[2]);
4225     }
4226   "
4229 (define_insn "*arm_shiftsi3"
4230   [(set (match_operand:SI   0 "s_register_operand" "=l,l,r,r")
4231         (match_operator:SI  3 "shift_operator"
4232          [(match_operand:SI 1 "s_register_operand"  "0,l,r,r")
4233           (match_operand:SI 2 "reg_or_int_operand" "l,M,M,r")]))]
4234   "TARGET_32BIT"
4235   "* return arm_output_shift(operands, 0);"
4236   [(set_attr "predicable" "yes")
4237    (set_attr "arch" "t2,t2,*,*")
4238    (set_attr "predicable_short_it" "yes,yes,no,no")
4239    (set_attr "length" "4")
4240    (set_attr "shift" "1")
4241    (set_attr "type" "alu_shift_reg,alu_shift_imm,alu_shift_imm,alu_shift_reg")]
4244 (define_insn "*shiftsi3_compare0"
4245   [(set (reg:CC_NOOV CC_REGNUM)
4246         (compare:CC_NOOV (match_operator:SI 3 "shift_operator"
4247                           [(match_operand:SI 1 "s_register_operand" "r,r")
4248                            (match_operand:SI 2 "arm_rhs_operand" "M,r")])
4249                          (const_int 0)))
4250    (set (match_operand:SI 0 "s_register_operand" "=r,r")
4251         (match_op_dup 3 [(match_dup 1) (match_dup 2)]))]
4252   "TARGET_32BIT"
4253   "* return arm_output_shift(operands, 1);"
4254   [(set_attr "conds" "set")
4255    (set_attr "shift" "1")
4256    (set_attr "type" "alus_shift_imm,alus_shift_reg")]
4259 (define_insn "*shiftsi3_compare0_scratch"
4260   [(set (reg:CC_NOOV CC_REGNUM)
4261         (compare:CC_NOOV (match_operator:SI 3 "shift_operator"
4262                           [(match_operand:SI 1 "s_register_operand" "r,r")
4263                            (match_operand:SI 2 "arm_rhs_operand" "M,r")])
4264                          (const_int 0)))
4265    (clobber (match_scratch:SI 0 "=r,r"))]
4266   "TARGET_32BIT"
4267   "* return arm_output_shift(operands, 1);"
4268   [(set_attr "conds" "set")
4269    (set_attr "shift" "1")
4270    (set_attr "type" "shift_imm,shift_reg")]
4273 (define_insn "*not_shiftsi"
4274   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4275         (not:SI (match_operator:SI 3 "shift_operator"
4276                  [(match_operand:SI 1 "s_register_operand" "r,r")
4277                   (match_operand:SI 2 "shift_amount_operand" "M,rM")])))]
4278   "TARGET_32BIT"
4279   "mvn%?\\t%0, %1%S3"
4280   [(set_attr "predicable" "yes")
4281    (set_attr "predicable_short_it" "no")
4282    (set_attr "shift" "1")
4283    (set_attr "arch" "32,a")
4284    (set_attr "type" "mvn_shift,mvn_shift_reg")])
4286 (define_insn "*not_shiftsi_compare0"
4287   [(set (reg:CC_NOOV CC_REGNUM)
4288         (compare:CC_NOOV
4289          (not:SI (match_operator:SI 3 "shift_operator"
4290                   [(match_operand:SI 1 "s_register_operand" "r,r")
4291                    (match_operand:SI 2 "shift_amount_operand" "M,rM")]))
4292          (const_int 0)))
4293    (set (match_operand:SI 0 "s_register_operand" "=r,r")
4294         (not:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])))]
4295   "TARGET_32BIT"
4296   "mvns%?\\t%0, %1%S3"
4297   [(set_attr "conds" "set")
4298    (set_attr "shift" "1")
4299    (set_attr "arch" "32,a")
4300    (set_attr "type" "mvn_shift,mvn_shift_reg")])
4302 (define_insn "*not_shiftsi_compare0_scratch"
4303   [(set (reg:CC_NOOV CC_REGNUM)
4304         (compare:CC_NOOV
4305          (not:SI (match_operator:SI 3 "shift_operator"
4306                   [(match_operand:SI 1 "s_register_operand" "r,r")
4307                    (match_operand:SI 2 "shift_amount_operand" "M,rM")]))
4308          (const_int 0)))
4309    (clobber (match_scratch:SI 0 "=r,r"))]
4310   "TARGET_32BIT"
4311   "mvns%?\\t%0, %1%S3"
4312   [(set_attr "conds" "set")
4313    (set_attr "shift" "1")
4314    (set_attr "arch" "32,a")
4315    (set_attr "type" "mvn_shift,mvn_shift_reg")])
4317 ;; We don't really have extzv, but defining this using shifts helps
4318 ;; to reduce register pressure later on.
4320 (define_expand "extzv"
4321   [(set (match_operand 0 "s_register_operand" "")
4322         (zero_extract (match_operand 1 "nonimmediate_operand" "")
4323                       (match_operand 2 "const_int_operand" "")
4324                       (match_operand 3 "const_int_operand" "")))]
4325   "TARGET_THUMB1 || arm_arch_thumb2"
4326   "
4327   {
4328     HOST_WIDE_INT lshift = 32 - INTVAL (operands[2]) - INTVAL (operands[3]);
4329     HOST_WIDE_INT rshift = 32 - INTVAL (operands[2]);
4330     
4331     if (arm_arch_thumb2)
4332       {
4333         HOST_WIDE_INT width = INTVAL (operands[2]);
4334         HOST_WIDE_INT bitpos = INTVAL (operands[3]);
4336         if (unaligned_access && MEM_P (operands[1])
4337             && (width == 16 || width == 32) && (bitpos % BITS_PER_UNIT) == 0)
4338           {
4339             rtx base_addr;
4341             if (BYTES_BIG_ENDIAN)
4342               bitpos = GET_MODE_BITSIZE (GET_MODE (operands[0])) - width
4343                        - bitpos;
4345             if (width == 32)
4346               {
4347                 base_addr = adjust_address (operands[1], SImode,
4348                                             bitpos / BITS_PER_UNIT);
4349                 emit_insn (gen_unaligned_loadsi (operands[0], base_addr));
4350               }
4351             else
4352               {
4353                 rtx dest = operands[0];
4354                 rtx tmp = gen_reg_rtx (SImode);
4356                 /* We may get a paradoxical subreg here.  Strip it off.  */
4357                 if (GET_CODE (dest) == SUBREG
4358                     && GET_MODE (dest) == SImode
4359                     && GET_MODE (SUBREG_REG (dest)) == HImode)
4360                   dest = SUBREG_REG (dest);
4362                 if (GET_MODE_BITSIZE (GET_MODE (dest)) != width)
4363                   FAIL;
4365                 base_addr = adjust_address (operands[1], HImode,
4366                                             bitpos / BITS_PER_UNIT);
4367                 emit_insn (gen_unaligned_loadhiu (tmp, base_addr));
4368                 emit_move_insn (gen_lowpart (SImode, dest), tmp);
4369               }
4370             DONE;
4371           }
4372         else if (s_register_operand (operands[1], GET_MODE (operands[1])))
4373           {
4374             emit_insn (gen_extzv_t2 (operands[0], operands[1], operands[2],
4375                                      operands[3]));
4376             DONE;
4377           }
4378         else
4379           FAIL;
4380       }
4381     
4382     if (!s_register_operand (operands[1], GET_MODE (operands[1])))
4383       FAIL;
4385     operands[3] = GEN_INT (rshift);
4386     
4387     if (lshift == 0)
4388       {
4389         emit_insn (gen_lshrsi3 (operands[0], operands[1], operands[3]));
4390         DONE;
4391       }
4392       
4393     emit_insn (gen_extzv_t1 (operands[0], operands[1], GEN_INT (lshift),
4394                              operands[3], gen_reg_rtx (SImode)));
4395     DONE;
4396   }"
4399 ;; Helper for extzv, for the Thumb-1 register-shifts case.
4401 (define_expand "extzv_t1"
4402   [(set (match_operand:SI 4 "s_register_operand" "")
4403         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
4404                    (match_operand:SI 2 "const_int_operand" "")))
4405    (set (match_operand:SI 0 "s_register_operand" "")
4406         (lshiftrt:SI (match_dup 4)
4407                      (match_operand:SI 3 "const_int_operand" "")))]
4408   "TARGET_THUMB1"
4409   "")
4411 (define_expand "extv"
4412   [(set (match_operand 0 "s_register_operand" "")
4413         (sign_extract (match_operand 1 "nonimmediate_operand" "")
4414                       (match_operand 2 "const_int_operand" "")
4415                       (match_operand 3 "const_int_operand" "")))]
4416   "arm_arch_thumb2"
4418   HOST_WIDE_INT width = INTVAL (operands[2]);
4419   HOST_WIDE_INT bitpos = INTVAL (operands[3]);
4421   if (unaligned_access && MEM_P (operands[1]) && (width == 16 || width == 32)
4422       && (bitpos % BITS_PER_UNIT)  == 0)
4423     {
4424       rtx base_addr;
4425       
4426       if (BYTES_BIG_ENDIAN)
4427         bitpos = GET_MODE_BITSIZE (GET_MODE (operands[0])) - width - bitpos;
4428       
4429       if (width == 32)
4430         {
4431           base_addr = adjust_address (operands[1], SImode,
4432                                       bitpos / BITS_PER_UNIT);
4433           emit_insn (gen_unaligned_loadsi (operands[0], base_addr));
4434         }
4435       else
4436         {
4437           rtx dest = operands[0];
4438           rtx tmp = gen_reg_rtx (SImode);
4439           
4440           /* We may get a paradoxical subreg here.  Strip it off.  */
4441           if (GET_CODE (dest) == SUBREG
4442               && GET_MODE (dest) == SImode
4443               && GET_MODE (SUBREG_REG (dest)) == HImode)
4444             dest = SUBREG_REG (dest);
4445           
4446           if (GET_MODE_BITSIZE (GET_MODE (dest)) != width)
4447             FAIL;
4448           
4449           base_addr = adjust_address (operands[1], HImode,
4450                                       bitpos / BITS_PER_UNIT);
4451           emit_insn (gen_unaligned_loadhis (tmp, base_addr));
4452           emit_move_insn (gen_lowpart (SImode, dest), tmp);
4453         }
4455       DONE;
4456     }
4457   else if (!s_register_operand (operands[1], GET_MODE (operands[1])))
4458     FAIL;
4459   else if (GET_MODE (operands[0]) == SImode
4460            && GET_MODE (operands[1]) == SImode)
4461     {
4462       emit_insn (gen_extv_regsi (operands[0], operands[1], operands[2],
4463                                  operands[3]));
4464       DONE;
4465     }
4467   FAIL;
4470 ; Helper to expand register forms of extv with the proper modes.
4472 (define_expand "extv_regsi"
4473   [(set (match_operand:SI 0 "s_register_operand" "")
4474         (sign_extract:SI (match_operand:SI 1 "s_register_operand" "")
4475                          (match_operand 2 "const_int_operand" "")
4476                          (match_operand 3 "const_int_operand" "")))]
4477   ""
4481 ; ARMv6+ unaligned load/store instructions (used for packed structure accesses).
4483 (define_insn "unaligned_loadsi"
4484   [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4485         (unspec:SI [(match_operand:SI 1 "memory_operand" "Uw,m")]
4486                    UNSPEC_UNALIGNED_LOAD))]
4487   "unaligned_access"
4488   "ldr%?\t%0, %1\t@ unaligned"
4489   [(set_attr "arch" "t2,any")
4490    (set_attr "length" "2,4")
4491    (set_attr "predicable" "yes")
4492    (set_attr "predicable_short_it" "yes,no")
4493    (set_attr "type" "load1")])
4495 (define_insn "unaligned_loadhis"
4496   [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4497         (sign_extend:SI
4498           (unspec:HI [(match_operand:HI 1 "memory_operand" "Uw,Uh")]
4499                      UNSPEC_UNALIGNED_LOAD)))]
4500   "unaligned_access"
4501   "ldrsh%?\t%0, %1\t@ unaligned"
4502   [(set_attr "arch" "t2,any")
4503    (set_attr "length" "2,4")
4504    (set_attr "predicable" "yes")
4505    (set_attr "predicable_short_it" "yes,no")
4506    (set_attr "type" "load_byte")])
4508 (define_insn "unaligned_loadhiu"
4509   [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4510         (zero_extend:SI
4511           (unspec:HI [(match_operand:HI 1 "memory_operand" "Uw,m")]
4512                      UNSPEC_UNALIGNED_LOAD)))]
4513   "unaligned_access"
4514   "ldrh%?\t%0, %1\t@ unaligned"
4515   [(set_attr "arch" "t2,any")
4516    (set_attr "length" "2,4")
4517    (set_attr "predicable" "yes")
4518    (set_attr "predicable_short_it" "yes,no")
4519    (set_attr "type" "load_byte")])
4521 (define_insn "unaligned_storesi"
4522   [(set (match_operand:SI 0 "memory_operand" "=Uw,m")
4523         (unspec:SI [(match_operand:SI 1 "s_register_operand" "l,r")]
4524                    UNSPEC_UNALIGNED_STORE))]
4525   "unaligned_access"
4526   "str%?\t%1, %0\t@ unaligned"
4527   [(set_attr "arch" "t2,any")
4528    (set_attr "length" "2,4")
4529    (set_attr "predicable" "yes")
4530    (set_attr "predicable_short_it" "yes,no")
4531    (set_attr "type" "store1")])
4533 (define_insn "unaligned_storehi"
4534   [(set (match_operand:HI 0 "memory_operand" "=Uw,m")
4535         (unspec:HI [(match_operand:HI 1 "s_register_operand" "l,r")]
4536                    UNSPEC_UNALIGNED_STORE))]
4537   "unaligned_access"
4538   "strh%?\t%1, %0\t@ unaligned"
4539   [(set_attr "arch" "t2,any")
4540    (set_attr "length" "2,4")
4541    (set_attr "predicable" "yes")
4542    (set_attr "predicable_short_it" "yes,no")
4543    (set_attr "type" "store1")])
4546 (define_insn "*extv_reg"
4547   [(set (match_operand:SI 0 "s_register_operand" "=r")
4548         (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
4549                          (match_operand:SI 2 "const_int_M_operand" "M")
4550                          (match_operand:SI 3 "const_int_M_operand" "M")))]
4551   "arm_arch_thumb2"
4552   "sbfx%?\t%0, %1, %3, %2"
4553   [(set_attr "length" "4")
4554    (set_attr "predicable" "yes")
4555    (set_attr "predicable_short_it" "no")
4556    (set_attr "type" "bfm")]
4559 (define_insn "extzv_t2"
4560   [(set (match_operand:SI 0 "s_register_operand" "=r")
4561         (zero_extract:SI (match_operand:SI 1 "s_register_operand" "r")
4562                          (match_operand:SI 2 "const_int_M_operand" "M")
4563                          (match_operand:SI 3 "const_int_M_operand" "M")))]
4564   "arm_arch_thumb2"
4565   "ubfx%?\t%0, %1, %3, %2"
4566   [(set_attr "length" "4")
4567    (set_attr "predicable" "yes")
4568    (set_attr "predicable_short_it" "no")
4569    (set_attr "type" "bfm")]
4573 ;; Division instructions
4574 (define_insn "divsi3"
4575   [(set (match_operand:SI         0 "s_register_operand" "=r,r")
4576         (div:SI (match_operand:SI 1 "s_register_operand"  "r,r")
4577                 (match_operand:SI 2 "s_register_operand"  "r,r")))]
4578   "TARGET_IDIV"
4579   "@
4580    sdiv%?\t%0, %1, %2
4581    sdiv\t%0, %1, %2"
4582   [(set_attr "arch" "32,v8mb")
4583    (set_attr "predicable" "yes")
4584    (set_attr "predicable_short_it" "no")
4585    (set_attr "type" "sdiv")]
4588 (define_insn "udivsi3"
4589   [(set (match_operand:SI          0 "s_register_operand" "=r,r")
4590         (udiv:SI (match_operand:SI 1 "s_register_operand"  "r,r")
4591                  (match_operand:SI 2 "s_register_operand"  "r,r")))]
4592   "TARGET_IDIV"
4593   "@
4594    udiv%?\t%0, %1, %2
4595    udiv\t%0, %1, %2"
4596   [(set_attr "arch" "32,v8mb")
4597    (set_attr "predicable" "yes")
4598    (set_attr "predicable_short_it" "no")
4599    (set_attr "type" "udiv")]
4603 ;; Unary arithmetic insns
4605 (define_expand "negvsi3"
4606   [(match_operand:SI 0 "register_operand")
4607    (match_operand:SI 1 "register_operand")
4608    (match_operand 2 "")]
4609   "TARGET_32BIT"
4611   emit_insn (gen_subsi3_compare (operands[0], const0_rtx, operands[1]));
4612   arm_gen_unlikely_cbranch (NE, CC_Vmode, operands[2]);
4614   DONE;
4617 (define_expand "negvdi3"
4618   [(match_operand:DI 0 "register_operand")
4619    (match_operand:DI 1 "register_operand")
4620    (match_operand 2 "")]
4621   "TARGET_ARM"
4623   emit_insn (gen_negdi2_compare (operands[0], operands[1]));
4624   arm_gen_unlikely_cbranch (NE, CC_Vmode, operands[2]);
4626   DONE;
4630 (define_insn_and_split "negdi2_compare"
4631   [(set (reg:CC CC_REGNUM)
4632         (compare:CC
4633           (const_int 0)
4634           (match_operand:DI 1 "register_operand" "0,r")))
4635    (set (match_operand:DI 0 "register_operand" "=r,&r")
4636         (minus:DI (const_int 0) (match_dup 1)))]
4637   "TARGET_ARM"
4638   "#"
4639   "&& reload_completed"
4640   [(parallel [(set (reg:CC CC_REGNUM)
4641                    (compare:CC (const_int 0) (match_dup 1)))
4642               (set (match_dup 0) (minus:SI (const_int 0)
4643                                            (match_dup 1)))])
4644    (parallel [(set (reg:CC CC_REGNUM)
4645                    (compare:CC (const_int 0) (match_dup 3)))
4646              (set (match_dup 2)
4647                   (minus:SI
4648                    (minus:SI (const_int 0) (match_dup 3))
4649                    (ltu:SI (reg:CC_C CC_REGNUM)
4650                            (const_int 0))))])]
4651   {
4652     operands[2] = gen_highpart (SImode, operands[0]);
4653     operands[0] = gen_lowpart (SImode, operands[0]);
4654     operands[3] = gen_highpart (SImode, operands[1]);
4655     operands[1] = gen_lowpart (SImode, operands[1]);
4656   }
4657   [(set_attr "conds" "set")
4658    (set_attr "length" "8")
4659    (set_attr "type" "multiple")]
4662 (define_expand "negdi2"
4663  [(parallel
4664    [(set (match_operand:DI 0 "s_register_operand" "")
4665          (neg:DI (match_operand:DI 1 "s_register_operand" "")))
4666     (clobber (reg:CC CC_REGNUM))])]
4667   "TARGET_EITHER"
4668   {
4669     if (TARGET_NEON)
4670       {
4671         emit_insn (gen_negdi2_neon (operands[0], operands[1]));
4672         DONE;
4673       }
4674   }
4677 ;; The constraints here are to prevent a *partial* overlap (where %Q0 == %R1).
4678 ;; The first alternative allows the common case of a *full* overlap.
4679 (define_insn_and_split "*arm_negdi2"
4680   [(set (match_operand:DI         0 "s_register_operand" "=r,&r")
4681         (neg:DI (match_operand:DI 1 "s_register_operand"  "0,r")))
4682    (clobber (reg:CC CC_REGNUM))]
4683   "TARGET_ARM"
4684   "#"   ; "rsbs\\t%Q0, %Q1, #0\;rsc\\t%R0, %R1, #0"
4685   "&& reload_completed"
4686   [(parallel [(set (reg:CC CC_REGNUM)
4687                    (compare:CC (const_int 0) (match_dup 1)))
4688               (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1)))])
4689    (set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3))
4690                                 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
4691   {
4692     operands[2] = gen_highpart (SImode, operands[0]);
4693     operands[0] = gen_lowpart (SImode, operands[0]);
4694     operands[3] = gen_highpart (SImode, operands[1]);
4695     operands[1] = gen_lowpart (SImode, operands[1]);
4696   }
4697   [(set_attr "conds" "clob")
4698    (set_attr "length" "8")
4699    (set_attr "type" "multiple")]
4702 (define_insn "*negsi2_carryin_compare"
4703   [(set (reg:CC CC_REGNUM)
4704         (compare:CC (const_int 0)
4705                     (match_operand:SI 1 "s_register_operand" "r")))
4706    (set (match_operand:SI 0 "s_register_operand" "=r")
4707         (minus:SI (minus:SI (const_int 0)
4708                             (match_dup 1))
4709                   (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
4710   "TARGET_ARM"
4711   "rscs\\t%0, %1, #0"
4712   [(set_attr "conds" "set")
4713    (set_attr "type" "alus_imm")]
4716 (define_expand "negsi2"
4717   [(set (match_operand:SI         0 "s_register_operand" "")
4718         (neg:SI (match_operand:SI 1 "s_register_operand" "")))]
4719   "TARGET_EITHER"
4720   ""
4723 (define_insn "*arm_negsi2"
4724   [(set (match_operand:SI         0 "s_register_operand" "=l,r")
4725         (neg:SI (match_operand:SI 1 "s_register_operand" "l,r")))]
4726   "TARGET_32BIT"
4727   "rsb%?\\t%0, %1, #0"
4728   [(set_attr "predicable" "yes")
4729    (set_attr "predicable_short_it" "yes,no")
4730    (set_attr "arch" "t2,*")
4731    (set_attr "length" "4")
4732    (set_attr "type" "alu_sreg")]
4735 (define_expand "negsf2"
4736   [(set (match_operand:SF         0 "s_register_operand" "")
4737         (neg:SF (match_operand:SF 1 "s_register_operand" "")))]
4738   "TARGET_32BIT && TARGET_HARD_FLOAT"
4739   ""
4742 (define_expand "negdf2"
4743   [(set (match_operand:DF         0 "s_register_operand" "")
4744         (neg:DF (match_operand:DF 1 "s_register_operand" "")))]
4745   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
4746   "")
4748 (define_insn_and_split "*zextendsidi_negsi"
4749   [(set (match_operand:DI 0 "s_register_operand" "=r")
4750         (zero_extend:DI (neg:SI (match_operand:SI 1 "s_register_operand" "r"))))]
4751    "TARGET_32BIT"
4752    "#"
4753    ""
4754    [(set (match_dup 2)
4755          (neg:SI (match_dup 1)))
4756     (set (match_dup 3)
4757          (const_int 0))]
4758    {
4759       operands[2] = gen_lowpart (SImode, operands[0]);
4760       operands[3] = gen_highpart (SImode, operands[0]);
4761    }
4762  [(set_attr "length" "8")
4763   (set_attr "type" "multiple")]
4766 ;; Negate an extended 32-bit value.
4767 (define_insn_and_split "*negdi_extendsidi"
4768   [(set (match_operand:DI 0 "s_register_operand" "=l,r")
4769         (neg:DI (sign_extend:DI
4770                  (match_operand:SI 1 "s_register_operand" "l,r"))))
4771    (clobber (reg:CC CC_REGNUM))]
4772   "TARGET_32BIT"
4773   "#"
4774   "&& reload_completed"
4775   [(const_int 0)]
4776   {
4777     rtx low = gen_lowpart (SImode, operands[0]);
4778     rtx high = gen_highpart (SImode, operands[0]);
4780     if (reg_overlap_mentioned_p (low, operands[1]))
4781       {
4782         /* Input overlaps the low word of the output.  Use:
4783                 asr     Rhi, Rin, #31
4784                 rsbs    Rlo, Rin, #0
4785                 rsc     Rhi, Rhi, #0 (thumb2: sbc Rhi, Rhi, Rhi, lsl #1).  */
4786         rtx cc_reg = gen_rtx_REG (CC_Cmode, CC_REGNUM);
4788         emit_insn (gen_rtx_SET (high,
4789                                 gen_rtx_ASHIFTRT (SImode, operands[1],
4790                                                   GEN_INT (31))));
4792         emit_insn (gen_subsi3_compare (low, const0_rtx, operands[1]));
4793         if (TARGET_ARM)
4794           emit_insn (gen_rtx_SET (high,
4795                                   gen_rtx_MINUS (SImode,
4796                                                  gen_rtx_MINUS (SImode,
4797                                                                 const0_rtx,
4798                                                                 high),
4799                                                  gen_rtx_LTU (SImode,
4800                                                               cc_reg,
4801                                                               const0_rtx))));
4802         else
4803           {
4804             rtx two_x = gen_rtx_ASHIFT (SImode, high, GEN_INT (1));
4805             emit_insn (gen_rtx_SET (high,
4806                                     gen_rtx_MINUS (SImode,
4807                                                    gen_rtx_MINUS (SImode,
4808                                                                   high,
4809                                                                   two_x),
4810                                                    gen_rtx_LTU (SImode,
4811                                                                 cc_reg,
4812                                                                 const0_rtx))));
4813           }
4814       }
4815     else
4816       {
4817         /* No overlap, or overlap on high word.  Use:
4818                 rsb     Rlo, Rin, #0
4819                 bic     Rhi, Rlo, Rin
4820                 asr     Rhi, Rhi, #31
4821            Flags not needed for this sequence.  */
4822         emit_insn (gen_rtx_SET (low, gen_rtx_NEG (SImode, operands[1])));
4823         emit_insn (gen_rtx_SET (high,
4824                                 gen_rtx_AND (SImode,
4825                                              gen_rtx_NOT (SImode, operands[1]),
4826                                              low)));
4827         emit_insn (gen_rtx_SET (high,
4828                                 gen_rtx_ASHIFTRT (SImode, high,
4829                                                   GEN_INT (31))));
4830       }
4831     DONE;
4832   }
4833   [(set_attr "length" "12")
4834    (set_attr "arch" "t2,*")
4835    (set_attr "type" "multiple")]
4838 (define_insn_and_split "*negdi_zero_extendsidi"
4839   [(set (match_operand:DI 0 "s_register_operand" "=r,&r")
4840         (neg:DI (zero_extend:DI (match_operand:SI 1 "s_register_operand" "0,r"))))
4841    (clobber (reg:CC CC_REGNUM))]
4842   "TARGET_32BIT"
4843   "#" ; "rsbs\\t%Q0, %1, #0\;sbc\\t%R0,%R0,%R0"
4844       ;; Don't care what register is input to sbc,
4845       ;; since we just need to propagate the carry.
4846   "&& reload_completed"
4847   [(parallel [(set (reg:CC CC_REGNUM)
4848                    (compare:CC (const_int 0) (match_dup 1)))
4849               (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1)))])
4850    (set (match_dup 2) (minus:SI (minus:SI (match_dup 2) (match_dup 2))
4851                                 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
4852   {
4853     operands[2] = gen_highpart (SImode, operands[0]);
4854     operands[0] = gen_lowpart (SImode, operands[0]);
4855   }
4856   [(set_attr "conds" "clob")
4857    (set_attr "length" "8")
4858    (set_attr "type" "multiple")]   ;; length in thumb is 4
4861 ;; abssi2 doesn't really clobber the condition codes if a different register
4862 ;; is being set.  To keep things simple, assume during rtl manipulations that
4863 ;; it does, but tell the final scan operator the truth.  Similarly for
4864 ;; (neg (abs...))
4866 (define_expand "abssi2"
4867   [(parallel
4868     [(set (match_operand:SI         0 "s_register_operand" "")
4869           (abs:SI (match_operand:SI 1 "s_register_operand" "")))
4870      (clobber (match_dup 2))])]
4871   "TARGET_EITHER"
4872   "
4873   if (TARGET_THUMB1)
4874     operands[2] = gen_rtx_SCRATCH (SImode);
4875   else
4876     operands[2] = gen_rtx_REG (CCmode, CC_REGNUM);
4879 (define_insn_and_split "*arm_abssi2"
4880   [(set (match_operand:SI 0 "s_register_operand" "=r,&r")
4881         (abs:SI (match_operand:SI 1 "s_register_operand" "0,r")))
4882    (clobber (reg:CC CC_REGNUM))]
4883   "TARGET_ARM"
4884   "#"
4885   "&& reload_completed"
4886   [(const_int 0)]
4887   {
4888    /* if (which_alternative == 0) */
4889    if (REGNO(operands[0]) == REGNO(operands[1]))
4890      {
4891       /* Emit the pattern:
4892          cmp\\t%0, #0\;rsblt\\t%0, %0, #0
4893          [(set (reg:CC CC_REGNUM)
4894                (compare:CC (match_dup 0) (const_int 0)))
4895           (cond_exec (lt:CC (reg:CC CC_REGNUM) (const_int 0))
4896                      (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1))))]
4897       */
4898       emit_insn (gen_rtx_SET (gen_rtx_REG (CCmode, CC_REGNUM),
4899                               gen_rtx_COMPARE (CCmode, operands[0], const0_rtx)));
4900       emit_insn (gen_rtx_COND_EXEC (VOIDmode,
4901                                     (gen_rtx_LT (SImode,
4902                                                  gen_rtx_REG (CCmode, CC_REGNUM),
4903                                                  const0_rtx)),
4904                                     (gen_rtx_SET (operands[0],
4905                                                   (gen_rtx_MINUS (SImode,
4906                                                                   const0_rtx,
4907                                                                   operands[1]))))));
4908       DONE;
4909      }
4910    else
4911      {
4912       /* Emit the pattern:
4913          alt1: eor%?\\t%0, %1, %1, asr #31\;sub%?\\t%0, %0, %1, asr #31
4914          [(set (match_dup 0)
4915                (xor:SI (match_dup 1)
4916                        (ashiftrt:SI (match_dup 1) (const_int 31))))
4917           (set (match_dup 0)
4918                (minus:SI (match_dup 0)
4919                       (ashiftrt:SI (match_dup 1) (const_int 31))))]
4920       */
4921       emit_insn (gen_rtx_SET (operands[0],
4922                               gen_rtx_XOR (SImode,
4923                                            gen_rtx_ASHIFTRT (SImode,
4924                                                              operands[1],
4925                                                              GEN_INT (31)),
4926                                            operands[1])));
4927       emit_insn (gen_rtx_SET (operands[0],
4928                               gen_rtx_MINUS (SImode,
4929                                              operands[0],
4930                                              gen_rtx_ASHIFTRT (SImode,
4931                                                                operands[1],
4932                                                                GEN_INT (31)))));
4933       DONE;
4934      }
4935   }
4936   [(set_attr "conds" "clob,*")
4937    (set_attr "shift" "1")
4938    (set_attr "predicable" "no, yes")
4939    (set_attr "length" "8")
4940    (set_attr "type" "multiple")]
4943 (define_insn_and_split "*arm_neg_abssi2"
4944   [(set (match_operand:SI 0 "s_register_operand" "=r,&r")
4945         (neg:SI (abs:SI (match_operand:SI 1 "s_register_operand" "0,r"))))
4946    (clobber (reg:CC CC_REGNUM))]
4947   "TARGET_ARM"
4948   "#"
4949   "&& reload_completed"
4950   [(const_int 0)]
4951   {
4952    /* if (which_alternative == 0) */
4953    if (REGNO (operands[0]) == REGNO (operands[1]))
4954      {
4955       /* Emit the pattern:
4956          cmp\\t%0, #0\;rsbgt\\t%0, %0, #0
4957       */
4958       emit_insn (gen_rtx_SET (gen_rtx_REG (CCmode, CC_REGNUM),
4959                               gen_rtx_COMPARE (CCmode, operands[0], const0_rtx)));
4960       emit_insn (gen_rtx_COND_EXEC (VOIDmode,
4961                                     gen_rtx_GT (SImode,
4962                                                 gen_rtx_REG (CCmode, CC_REGNUM),
4963                                                 const0_rtx),
4964                                     gen_rtx_SET (operands[0],
4965                                                  (gen_rtx_MINUS (SImode,
4966                                                                  const0_rtx,
4967                                                                  operands[1])))));
4968      }
4969    else
4970      {
4971       /* Emit the pattern:
4972          eor%?\\t%0, %1, %1, asr #31\;rsb%?\\t%0, %0, %1, asr #31
4973       */
4974       emit_insn (gen_rtx_SET (operands[0],
4975                               gen_rtx_XOR (SImode,
4976                                            gen_rtx_ASHIFTRT (SImode,
4977                                                              operands[1],
4978                                                              GEN_INT (31)),
4979                                            operands[1])));
4980       emit_insn (gen_rtx_SET (operands[0],
4981                               gen_rtx_MINUS (SImode,
4982                                              gen_rtx_ASHIFTRT (SImode,
4983                                                                operands[1],
4984                                                                GEN_INT (31)),
4985                                              operands[0])));
4986      }
4987    DONE;
4988   }
4989   [(set_attr "conds" "clob,*")
4990    (set_attr "shift" "1")
4991    (set_attr "predicable" "no, yes")
4992    (set_attr "length" "8")
4993    (set_attr "type" "multiple")]
4996 (define_expand "abssf2"
4997   [(set (match_operand:SF         0 "s_register_operand" "")
4998         (abs:SF (match_operand:SF 1 "s_register_operand" "")))]
4999   "TARGET_32BIT && TARGET_HARD_FLOAT"
5000   "")
5002 (define_expand "absdf2"
5003   [(set (match_operand:DF         0 "s_register_operand" "")
5004         (abs:DF (match_operand:DF 1 "s_register_operand" "")))]
5005   "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
5006   "")
5008 (define_expand "sqrtsf2"
5009   [(set (match_operand:SF 0 "s_register_operand" "")
5010         (sqrt:SF (match_operand:SF 1 "s_register_operand" "")))]
5011   "TARGET_32BIT && TARGET_HARD_FLOAT"
5012   "")
5014 (define_expand "sqrtdf2"
5015   [(set (match_operand:DF 0 "s_register_operand" "")
5016         (sqrt:DF (match_operand:DF 1 "s_register_operand" "")))]
5017   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
5018   "")
5020 (define_insn_and_split "one_cmpldi2"
5021   [(set (match_operand:DI 0 "s_register_operand"         "=w,&r,&r,?w")
5022         (not:DI (match_operand:DI 1 "s_register_operand" " w, 0, r, w")))]
5023   "TARGET_32BIT"
5024   "@
5025    vmvn\t%P0, %P1
5026    #
5027    #
5028    vmvn\t%P0, %P1"
5029   "TARGET_32BIT && reload_completed
5030    && arm_general_register_operand (operands[0], DImode)"
5031   [(set (match_dup 0) (not:SI (match_dup 1)))
5032    (set (match_dup 2) (not:SI (match_dup 3)))]
5033   "
5034   {
5035     operands[2] = gen_highpart (SImode, operands[0]);
5036     operands[0] = gen_lowpart (SImode, operands[0]);
5037     operands[3] = gen_highpart (SImode, operands[1]);
5038     operands[1] = gen_lowpart (SImode, operands[1]);
5039   }"
5040   [(set_attr "length" "*,8,8,*")
5041    (set_attr "predicable" "no,yes,yes,no")
5042    (set_attr "type" "neon_move,multiple,multiple,neon_move")
5043    (set_attr "arch" "neon_for_64bits,*,*,avoid_neon_for_64bits")]
5046 (define_expand "one_cmplsi2"
5047   [(set (match_operand:SI         0 "s_register_operand" "")
5048         (not:SI (match_operand:SI 1 "s_register_operand" "")))]
5049   "TARGET_EITHER"
5050   ""
5053 (define_insn "*arm_one_cmplsi2"
5054   [(set (match_operand:SI         0 "s_register_operand" "=l,r")
5055         (not:SI (match_operand:SI 1 "s_register_operand"  "l,r")))]
5056   "TARGET_32BIT"
5057   "mvn%?\\t%0, %1"
5058   [(set_attr "predicable" "yes")
5059    (set_attr "predicable_short_it" "yes,no")
5060    (set_attr "arch" "t2,*")
5061    (set_attr "length" "4")
5062    (set_attr "type" "mvn_reg")]
5065 (define_insn "*notsi_compare0"
5066   [(set (reg:CC_NOOV CC_REGNUM)
5067         (compare:CC_NOOV (not:SI (match_operand:SI 1 "s_register_operand" "r"))
5068                          (const_int 0)))
5069    (set (match_operand:SI 0 "s_register_operand" "=r")
5070         (not:SI (match_dup 1)))]
5071   "TARGET_32BIT"
5072   "mvns%?\\t%0, %1"
5073   [(set_attr "conds" "set")
5074    (set_attr "type" "mvn_reg")]
5077 (define_insn "*notsi_compare0_scratch"
5078   [(set (reg:CC_NOOV CC_REGNUM)
5079         (compare:CC_NOOV (not:SI (match_operand:SI 1 "s_register_operand" "r"))
5080                          (const_int 0)))
5081    (clobber (match_scratch:SI 0 "=r"))]
5082   "TARGET_32BIT"
5083   "mvns%?\\t%0, %1"
5084   [(set_attr "conds" "set")
5085    (set_attr "type" "mvn_reg")]
5088 ;; Fixed <--> Floating conversion insns
5090 (define_expand "floatsihf2"
5091   [(set (match_operand:HF           0 "general_operand" "")
5092         (float:HF (match_operand:SI 1 "general_operand" "")))]
5093   "TARGET_EITHER"
5094   "
5095   {
5096     rtx op1 = gen_reg_rtx (SFmode);
5097     expand_float (op1, operands[1], 0);
5098     op1 = convert_to_mode (HFmode, op1, 0);
5099     emit_move_insn (operands[0], op1);
5100     DONE;
5101   }"
5104 (define_expand "floatdihf2"
5105   [(set (match_operand:HF           0 "general_operand" "")
5106         (float:HF (match_operand:DI 1 "general_operand" "")))]
5107   "TARGET_EITHER"
5108   "
5109   {
5110     rtx op1 = gen_reg_rtx (SFmode);
5111     expand_float (op1, operands[1], 0);
5112     op1 = convert_to_mode (HFmode, op1, 0);
5113     emit_move_insn (operands[0], op1);
5114     DONE;
5115   }"
5118 (define_expand "floatsisf2"
5119   [(set (match_operand:SF           0 "s_register_operand" "")
5120         (float:SF (match_operand:SI 1 "s_register_operand" "")))]
5121   "TARGET_32BIT && TARGET_HARD_FLOAT"
5122   "
5125 (define_expand "floatsidf2"
5126   [(set (match_operand:DF           0 "s_register_operand" "")
5127         (float:DF (match_operand:SI 1 "s_register_operand" "")))]
5128   "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
5129   "
5132 (define_expand "fix_trunchfsi2"
5133   [(set (match_operand:SI         0 "general_operand" "")
5134         (fix:SI (fix:HF (match_operand:HF 1 "general_operand"  ""))))]
5135   "TARGET_EITHER"
5136   "
5137   {
5138     rtx op1 = convert_to_mode (SFmode, operands[1], 0);
5139     expand_fix (operands[0], op1, 0);
5140     DONE;
5141   }"
5144 (define_expand "fix_trunchfdi2"
5145   [(set (match_operand:DI         0 "general_operand" "")
5146         (fix:DI (fix:HF (match_operand:HF 1 "general_operand"  ""))))]
5147   "TARGET_EITHER"
5148   "
5149   {
5150     rtx op1 = convert_to_mode (SFmode, operands[1], 0);
5151     expand_fix (operands[0], op1, 0);
5152     DONE;
5153   }"
5156 (define_expand "fix_truncsfsi2"
5157   [(set (match_operand:SI         0 "s_register_operand" "")
5158         (fix:SI (fix:SF (match_operand:SF 1 "s_register_operand"  ""))))]
5159   "TARGET_32BIT && TARGET_HARD_FLOAT"
5160   "
5163 (define_expand "fix_truncdfsi2"
5164   [(set (match_operand:SI         0 "s_register_operand" "")
5165         (fix:SI (fix:DF (match_operand:DF 1 "s_register_operand"  ""))))]
5166   "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
5167   "
5170 ;; Truncation insns
5172 (define_expand "truncdfsf2"
5173   [(set (match_operand:SF  0 "s_register_operand" "")
5174         (float_truncate:SF
5175          (match_operand:DF 1 "s_register_operand" "")))]
5176   "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
5177   ""
5180 ;; DFmode to HFmode conversions have to go through SFmode.
5181 (define_expand "truncdfhf2"
5182   [(set (match_operand:HF  0 "general_operand" "")
5183         (float_truncate:HF
5184          (match_operand:DF 1 "general_operand" "")))]
5185   "TARGET_EITHER"
5186   "
5187   {
5188     rtx op1;
5189     op1 = convert_to_mode (SFmode, operands[1], 0);
5190     op1 = convert_to_mode (HFmode, op1, 0);
5191     emit_move_insn (operands[0], op1);
5192     DONE;
5193   }"
5196 ;; Zero and sign extension instructions.
5198 (define_insn "zero_extend<mode>di2"
5199   [(set (match_operand:DI 0 "s_register_operand" "=w,r,?r,w")
5200         (zero_extend:DI (match_operand:QHSI 1 "<qhs_zextenddi_op>"
5201                                             "<qhs_zextenddi_cstr>")))]
5202   "TARGET_32BIT <qhs_zextenddi_cond>"
5203   "#"
5204   [(set_attr "length" "8,4,8,8")
5205    (set_attr "arch" "neon_for_64bits,*,*,avoid_neon_for_64bits")
5206    (set_attr "ce_count" "2")
5207    (set_attr "predicable" "yes")
5208    (set_attr "type" "multiple,mov_reg,multiple,multiple")]
5211 (define_insn "extend<mode>di2"
5212   [(set (match_operand:DI 0 "s_register_operand" "=w,r,?r,?r,w")
5213         (sign_extend:DI (match_operand:QHSI 1 "<qhs_extenddi_op>"
5214                                             "<qhs_extenddi_cstr>")))]
5215   "TARGET_32BIT <qhs_sextenddi_cond>"
5216   "#"
5217   [(set_attr "length" "8,4,8,8,8")
5218    (set_attr "ce_count" "2")
5219    (set_attr "shift" "1")
5220    (set_attr "predicable" "yes")
5221    (set_attr "arch" "neon_for_64bits,*,a,t,avoid_neon_for_64bits")
5222    (set_attr "type" "multiple,mov_reg,multiple,multiple,multiple")]
5225 ;; Splits for all extensions to DImode
5226 (define_split
5227   [(set (match_operand:DI 0 "s_register_operand" "")
5228         (zero_extend:DI (match_operand 1 "nonimmediate_operand" "")))]
5229   "TARGET_32BIT && reload_completed && !IS_VFP_REGNUM (REGNO (operands[0]))"
5230   [(set (match_dup 0) (match_dup 1))]
5232   rtx lo_part = gen_lowpart (SImode, operands[0]);
5233   machine_mode src_mode = GET_MODE (operands[1]);
5235   if (REG_P (operands[0])
5236       && !reg_overlap_mentioned_p (operands[0], operands[1]))
5237     emit_clobber (operands[0]);
5238   if (!REG_P (lo_part) || src_mode != SImode
5239       || !rtx_equal_p (lo_part, operands[1]))
5240     {
5241       if (src_mode == SImode)
5242         emit_move_insn (lo_part, operands[1]);
5243       else
5244         emit_insn (gen_rtx_SET (lo_part,
5245                                 gen_rtx_ZERO_EXTEND (SImode, operands[1])));
5246       operands[1] = lo_part;
5247     }
5248   operands[0] = gen_highpart (SImode, operands[0]);
5249   operands[1] = const0_rtx;
5252 (define_split
5253   [(set (match_operand:DI 0 "s_register_operand" "")
5254         (sign_extend:DI (match_operand 1 "nonimmediate_operand" "")))]
5255   "TARGET_32BIT && reload_completed && !IS_VFP_REGNUM (REGNO (operands[0]))"
5256   [(set (match_dup 0) (ashiftrt:SI (match_dup 1) (const_int 31)))]
5258   rtx lo_part = gen_lowpart (SImode, operands[0]);
5259   machine_mode src_mode = GET_MODE (operands[1]);
5261   if (REG_P (operands[0])
5262       && !reg_overlap_mentioned_p (operands[0], operands[1]))
5263     emit_clobber (operands[0]);
5265   if (!REG_P (lo_part) || src_mode != SImode
5266       || !rtx_equal_p (lo_part, operands[1]))
5267     {
5268       if (src_mode == SImode)
5269         emit_move_insn (lo_part, operands[1]);
5270       else
5271         emit_insn (gen_rtx_SET (lo_part,
5272                                 gen_rtx_SIGN_EXTEND (SImode, operands[1])));
5273       operands[1] = lo_part;
5274     }
5275   operands[0] = gen_highpart (SImode, operands[0]);
5278 (define_expand "zero_extendhisi2"
5279   [(set (match_operand:SI 0 "s_register_operand" "")
5280         (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
5281   "TARGET_EITHER"
5283   if (TARGET_ARM && !arm_arch4 && MEM_P (operands[1]))
5284     {
5285       emit_insn (gen_movhi_bytes (operands[0], operands[1]));
5286       DONE;
5287     }
5288   if (!arm_arch6 && !MEM_P (operands[1]))
5289     {
5290       rtx t = gen_lowpart (SImode, operands[1]);
5291       rtx tmp = gen_reg_rtx (SImode);
5292       emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (16)));
5293       emit_insn (gen_lshrsi3 (operands[0], tmp, GEN_INT (16)));
5294       DONE;
5295     }
5298 (define_split
5299   [(set (match_operand:SI 0 "s_register_operand" "")
5300         (zero_extend:SI (match_operand:HI 1 "s_register_operand" "")))]
5301   "!TARGET_THUMB2 && !arm_arch6"
5302   [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
5303    (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 16)))]
5305   operands[2] = gen_lowpart (SImode, operands[1]);
5308 (define_insn "*arm_zero_extendhisi2"
5309   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5310         (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
5311   "TARGET_ARM && arm_arch4 && !arm_arch6"
5312   "@
5313    #
5314    ldrh%?\\t%0, %1"
5315   [(set_attr "type" "alu_shift_reg,load_byte")
5316    (set_attr "predicable" "yes")]
5319 (define_insn "*arm_zero_extendhisi2_v6"
5320   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5321         (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,Uh")))]
5322   "TARGET_ARM && arm_arch6"
5323   "@
5324    uxth%?\\t%0, %1
5325    ldrh%?\\t%0, %1"
5326   [(set_attr "predicable" "yes")
5327    (set_attr "type" "extend,load_byte")]
5330 (define_insn "*arm_zero_extendhisi2addsi"
5331   [(set (match_operand:SI 0 "s_register_operand" "=r")
5332         (plus:SI (zero_extend:SI (match_operand:HI 1 "s_register_operand" "r"))
5333                  (match_operand:SI 2 "s_register_operand" "r")))]
5334   "TARGET_INT_SIMD"
5335   "uxtah%?\\t%0, %2, %1"
5336   [(set_attr "type" "alu_shift_reg")
5337    (set_attr "predicable" "yes")
5338    (set_attr "predicable_short_it" "no")]
5341 (define_expand "zero_extendqisi2"
5342   [(set (match_operand:SI 0 "s_register_operand" "")
5343         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))]
5344   "TARGET_EITHER"
5346   if (TARGET_ARM && !arm_arch6 && !MEM_P (operands[1]))
5347     {
5348       emit_insn (gen_andsi3 (operands[0],
5349                              gen_lowpart (SImode, operands[1]),
5350                                           GEN_INT (255)));
5351       DONE;
5352     }
5353   if (!arm_arch6 && !MEM_P (operands[1]))
5354     {
5355       rtx t = gen_lowpart (SImode, operands[1]);
5356       rtx tmp = gen_reg_rtx (SImode);
5357       emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (24)));
5358       emit_insn (gen_lshrsi3 (operands[0], tmp, GEN_INT (24)));
5359       DONE;
5360     }
5363 (define_split
5364   [(set (match_operand:SI 0 "s_register_operand" "")
5365         (zero_extend:SI (match_operand:QI 1 "s_register_operand" "")))]
5366   "!arm_arch6"
5367   [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 24)))
5368    (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 24)))]
5370   operands[2] = simplify_gen_subreg (SImode, operands[1], QImode, 0);
5371   if (TARGET_ARM)
5372     {
5373       emit_insn (gen_andsi3 (operands[0], operands[2], GEN_INT (255)));
5374       DONE;
5375     }
5378 (define_insn "*arm_zero_extendqisi2"
5379   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5380         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
5381   "TARGET_ARM && !arm_arch6"
5382   "@
5383    #
5384    ldrb%?\\t%0, %1\\t%@ zero_extendqisi2"
5385   [(set_attr "length" "8,4")
5386    (set_attr "type" "alu_shift_reg,load_byte")
5387    (set_attr "predicable" "yes")]
5390 (define_insn "*arm_zero_extendqisi2_v6"
5391   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5392         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,Uh")))]
5393   "TARGET_ARM && arm_arch6"
5394   "@
5395    uxtb%?\\t%0, %1
5396    ldrb%?\\t%0, %1\\t%@ zero_extendqisi2"
5397   [(set_attr "type" "extend,load_byte")
5398    (set_attr "predicable" "yes")]
5401 (define_insn "*arm_zero_extendqisi2addsi"
5402   [(set (match_operand:SI 0 "s_register_operand" "=r")
5403         (plus:SI (zero_extend:SI (match_operand:QI 1 "s_register_operand" "r"))
5404                  (match_operand:SI 2 "s_register_operand" "r")))]
5405   "TARGET_INT_SIMD"
5406   "uxtab%?\\t%0, %2, %1"
5407   [(set_attr "predicable" "yes")
5408    (set_attr "predicable_short_it" "no")
5409    (set_attr "type" "alu_shift_reg")]
5412 (define_split
5413   [(set (match_operand:SI 0 "s_register_operand" "")
5414         (zero_extend:SI (subreg:QI (match_operand:SI 1 "" "") 0)))
5415    (clobber (match_operand:SI 2 "s_register_operand" ""))]
5416   "TARGET_32BIT && (!MEM_P (operands[1])) && ! BYTES_BIG_ENDIAN"
5417   [(set (match_dup 2) (match_dup 1))
5418    (set (match_dup 0) (and:SI (match_dup 2) (const_int 255)))]
5419   ""
5422 (define_split
5423   [(set (match_operand:SI 0 "s_register_operand" "")
5424         (zero_extend:SI (subreg:QI (match_operand:SI 1 "" "") 3)))
5425    (clobber (match_operand:SI 2 "s_register_operand" ""))]
5426   "TARGET_32BIT && (!MEM_P (operands[1])) && BYTES_BIG_ENDIAN"
5427   [(set (match_dup 2) (match_dup 1))
5428    (set (match_dup 0) (and:SI (match_dup 2) (const_int 255)))]
5429   ""
5433 (define_split
5434   [(set (match_operand:SI 0 "s_register_operand" "")
5435         (IOR_XOR:SI (and:SI (ashift:SI
5436                              (match_operand:SI 1 "s_register_operand" "")
5437                              (match_operand:SI 2 "const_int_operand" ""))
5438                             (match_operand:SI 3 "const_int_operand" ""))
5439                     (zero_extend:SI
5440                      (match_operator 5 "subreg_lowpart_operator"
5441                       [(match_operand:SI 4 "s_register_operand" "")]))))]
5442   "TARGET_32BIT
5443    && (UINTVAL (operands[3])
5444        == (GET_MODE_MASK (GET_MODE (operands[5]))
5445            & (GET_MODE_MASK (GET_MODE (operands[5]))
5446               << (INTVAL (operands[2])))))"
5447   [(set (match_dup 0) (IOR_XOR:SI (ashift:SI (match_dup 1) (match_dup 2))
5448                                   (match_dup 4)))
5449    (set (match_dup 0) (zero_extend:SI (match_dup 5)))]
5450   "operands[5] = gen_lowpart (GET_MODE (operands[5]), operands[0]);"
5453 (define_insn "*compareqi_eq0"
5454   [(set (reg:CC_Z CC_REGNUM)
5455         (compare:CC_Z (match_operand:QI 0 "s_register_operand" "r")
5456                          (const_int 0)))]
5457   "TARGET_32BIT"
5458   "tst%?\\t%0, #255"
5459   [(set_attr "conds" "set")
5460    (set_attr "predicable" "yes")
5461    (set_attr "predicable_short_it" "no")
5462    (set_attr "type" "logic_imm")]
5465 (define_expand "extendhisi2"
5466   [(set (match_operand:SI 0 "s_register_operand" "")
5467         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
5468   "TARGET_EITHER"
5470   if (TARGET_THUMB1)
5471     {
5472       emit_insn (gen_thumb1_extendhisi2 (operands[0], operands[1]));
5473       DONE;
5474     }
5475   if (MEM_P (operands[1]) && TARGET_ARM && !arm_arch4)
5476     {
5477       emit_insn (gen_extendhisi2_mem (operands[0], operands[1]));
5478       DONE;
5479     }
5481   if (!arm_arch6 && !MEM_P (operands[1]))
5482     {
5483       rtx t = gen_lowpart (SImode, operands[1]);
5484       rtx tmp = gen_reg_rtx (SImode);
5485       emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (16)));
5486       emit_insn (gen_ashrsi3 (operands[0], tmp, GEN_INT (16)));
5487       DONE;
5488     }
5491 (define_split
5492   [(parallel
5493     [(set (match_operand:SI 0 "register_operand" "")
5494           (sign_extend:SI (match_operand:HI 1 "register_operand" "")))
5495      (clobber (match_scratch:SI 2 ""))])]
5496   "!arm_arch6"
5497   [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
5498    (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
5500   operands[2] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
5503 ;; This pattern will only be used when ldsh is not available
5504 (define_expand "extendhisi2_mem"
5505   [(set (match_dup 2) (zero_extend:SI (match_operand:HI 1 "" "")))
5506    (set (match_dup 3)
5507         (zero_extend:SI (match_dup 7)))
5508    (set (match_dup 6) (ashift:SI (match_dup 4) (const_int 24)))
5509    (set (match_operand:SI 0 "" "")
5510         (ior:SI (ashiftrt:SI (match_dup 6) (const_int 16)) (match_dup 5)))]
5511   "TARGET_ARM"
5512   "
5513   {
5514     rtx mem1, mem2;
5515     rtx addr = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
5517     mem1 = change_address (operands[1], QImode, addr);
5518     mem2 = change_address (operands[1], QImode,
5519                            plus_constant (Pmode, addr, 1));
5520     operands[0] = gen_lowpart (SImode, operands[0]);
5521     operands[1] = mem1;
5522     operands[2] = gen_reg_rtx (SImode);
5523     operands[3] = gen_reg_rtx (SImode);
5524     operands[6] = gen_reg_rtx (SImode);
5525     operands[7] = mem2;
5527     if (BYTES_BIG_ENDIAN)
5528       {
5529         operands[4] = operands[2];
5530         operands[5] = operands[3];
5531       }
5532     else
5533       {
5534         operands[4] = operands[3];
5535         operands[5] = operands[2];
5536       }
5537   }"
5540 (define_split
5541   [(set (match_operand:SI 0 "register_operand" "")
5542         (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
5543   "!arm_arch6"
5544   [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
5545    (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
5547   operands[2] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
5550 (define_insn "*arm_extendhisi2"
5551   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5552         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,Uh")))]
5553   "TARGET_ARM && arm_arch4 && !arm_arch6"
5554   "@
5555    #
5556    ldrsh%?\\t%0, %1"
5557   [(set_attr "length" "8,4")
5558    (set_attr "type" "alu_shift_reg,load_byte")
5559    (set_attr "predicable" "yes")]
5562 ;; ??? Check Thumb-2 pool range
5563 (define_insn "*arm_extendhisi2_v6"
5564   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5565         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,Uh")))]
5566   "TARGET_32BIT && arm_arch6"
5567   "@
5568    sxth%?\\t%0, %1
5569    ldrsh%?\\t%0, %1"
5570   [(set_attr "type" "extend,load_byte")
5571    (set_attr "predicable" "yes")
5572    (set_attr "predicable_short_it" "no")]
5575 (define_insn "*arm_extendhisi2addsi"
5576   [(set (match_operand:SI 0 "s_register_operand" "=r")
5577         (plus:SI (sign_extend:SI (match_operand:HI 1 "s_register_operand" "r"))
5578                  (match_operand:SI 2 "s_register_operand" "r")))]
5579   "TARGET_INT_SIMD"
5580   "sxtah%?\\t%0, %2, %1"
5581   [(set_attr "type" "alu_shift_reg")]
5584 (define_expand "extendqihi2"
5585   [(set (match_dup 2)
5586         (ashift:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "")
5587                    (const_int 24)))
5588    (set (match_operand:HI 0 "s_register_operand" "")
5589         (ashiftrt:SI (match_dup 2)
5590                      (const_int 24)))]
5591   "TARGET_ARM"
5592   "
5593   {
5594     if (arm_arch4 && MEM_P (operands[1]))
5595       {
5596         emit_insn (gen_rtx_SET (operands[0],
5597                                 gen_rtx_SIGN_EXTEND (HImode, operands[1])));
5598         DONE;
5599       }
5600     if (!s_register_operand (operands[1], QImode))
5601       operands[1] = copy_to_mode_reg (QImode, operands[1]);
5602     operands[0] = gen_lowpart (SImode, operands[0]);
5603     operands[1] = gen_lowpart (SImode, operands[1]);
5604     operands[2] = gen_reg_rtx (SImode);
5605   }"
5608 (define_insn "*arm_extendqihi_insn"
5609   [(set (match_operand:HI 0 "s_register_operand" "=r")
5610         (sign_extend:HI (match_operand:QI 1 "arm_extendqisi_mem_op" "Uq")))]
5611   "TARGET_ARM && arm_arch4"
5612   "ldrsb%?\\t%0, %1"
5613   [(set_attr "type" "load_byte")
5614    (set_attr "predicable" "yes")]
5617 (define_expand "extendqisi2"
5618   [(set (match_operand:SI 0 "s_register_operand" "")
5619         (sign_extend:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "")))]
5620   "TARGET_EITHER"
5622   if (!arm_arch4 && MEM_P (operands[1]))
5623     operands[1] = copy_to_mode_reg (QImode, operands[1]);
5625   if (!arm_arch6 && !MEM_P (operands[1]))
5626     {
5627       rtx t = gen_lowpart (SImode, operands[1]);
5628       rtx tmp = gen_reg_rtx (SImode);
5629       emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (24)));
5630       emit_insn (gen_ashrsi3 (operands[0], tmp, GEN_INT (24)));
5631       DONE;
5632     }
5635 (define_split
5636   [(set (match_operand:SI 0 "register_operand" "")
5637         (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
5638   "!arm_arch6"
5639   [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 24)))
5640    (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 24)))]
5642   operands[2] = simplify_gen_subreg (SImode, operands[1], QImode, 0);
5645 (define_insn "*arm_extendqisi"
5646   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5647         (sign_extend:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "r,Uq")))]
5648   "TARGET_ARM && arm_arch4 && !arm_arch6"
5649   "@
5650    #
5651    ldrsb%?\\t%0, %1"
5652   [(set_attr "length" "8,4")
5653    (set_attr "type" "alu_shift_reg,load_byte")
5654    (set_attr "predicable" "yes")]
5657 (define_insn "*arm_extendqisi_v6"
5658   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5659         (sign_extend:SI
5660          (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "r,Uq")))]
5661   "TARGET_ARM && arm_arch6"
5662   "@
5663    sxtb%?\\t%0, %1
5664    ldrsb%?\\t%0, %1"
5665   [(set_attr "type" "extend,load_byte")
5666    (set_attr "predicable" "yes")]
5669 (define_insn "*arm_extendqisi2addsi"
5670   [(set (match_operand:SI 0 "s_register_operand" "=r")
5671         (plus:SI (sign_extend:SI (match_operand:QI 1 "s_register_operand" "r"))
5672                  (match_operand:SI 2 "s_register_operand" "r")))]
5673   "TARGET_INT_SIMD"
5674   "sxtab%?\\t%0, %2, %1"
5675   [(set_attr "type" "alu_shift_reg")
5676    (set_attr "predicable" "yes")
5677    (set_attr "predicable_short_it" "no")]
5680 (define_expand "extendsfdf2"
5681   [(set (match_operand:DF                  0 "s_register_operand" "")
5682         (float_extend:DF (match_operand:SF 1 "s_register_operand"  "")))]
5683   "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
5684   ""
5687 ;; HFmode -> DFmode conversions have to go through SFmode.
5688 (define_expand "extendhfdf2"
5689   [(set (match_operand:DF                  0 "general_operand" "")
5690         (float_extend:DF (match_operand:HF 1 "general_operand"  "")))]
5691   "TARGET_EITHER"
5692   "
5693   {
5694     rtx op1;
5695     op1 = convert_to_mode (SFmode, operands[1], 0);
5696     op1 = convert_to_mode (DFmode, op1, 0);
5697     emit_insn (gen_movdf (operands[0], op1));
5698     DONE;
5699   }"
5702 ;; Move insns (including loads and stores)
5704 ;; XXX Just some ideas about movti.
5705 ;; I don't think these are a good idea on the arm, there just aren't enough
5706 ;; registers
5707 ;;(define_expand "loadti"
5708 ;;  [(set (match_operand:TI 0 "s_register_operand" "")
5709 ;;      (mem:TI (match_operand:SI 1 "address_operand" "")))]
5710 ;;  "" "")
5712 ;;(define_expand "storeti"
5713 ;;  [(set (mem:TI (match_operand:TI 0 "address_operand" ""))
5714 ;;      (match_operand:TI 1 "s_register_operand" ""))]
5715 ;;  "" "")
5717 ;;(define_expand "movti"
5718 ;;  [(set (match_operand:TI 0 "general_operand" "")
5719 ;;      (match_operand:TI 1 "general_operand" ""))]
5720 ;;  ""
5721 ;;  "
5723 ;;  rtx insn;
5725 ;;  if (MEM_P (operands[0]) && MEM_P (operands[1]))
5726 ;;    operands[1] = copy_to_reg (operands[1]);
5727 ;;  if (MEM_P (operands[0]))
5728 ;;    insn = gen_storeti (XEXP (operands[0], 0), operands[1]);
5729 ;;  else if (MEM_P (operands[1]))
5730 ;;    insn = gen_loadti (operands[0], XEXP (operands[1], 0));
5731 ;;  else
5732 ;;    FAIL;
5734 ;;  emit_insn (insn);
5735 ;;  DONE;
5736 ;;}")
5738 ;; Recognize garbage generated above.
5740 ;;(define_insn ""
5741 ;;  [(set (match_operand:TI 0 "general_operand" "=r,r,r,<,>,m")
5742 ;;      (match_operand:TI 1 "general_operand" "<,>,m,r,r,r"))]
5743 ;;  ""
5744 ;;  "*
5745 ;;  {
5746 ;;    register mem = (which_alternative < 3);
5747 ;;    register const char *template;
5749 ;;    operands[mem] = XEXP (operands[mem], 0);
5750 ;;    switch (which_alternative)
5751 ;;      {
5752 ;;      case 0: template = \"ldmdb\\t%1!, %M0\"; break;
5753 ;;      case 1: template = \"ldmia\\t%1!, %M0\"; break;
5754 ;;      case 2: template = \"ldmia\\t%1, %M0\"; break;
5755 ;;      case 3: template = \"stmdb\\t%0!, %M1\"; break;
5756 ;;      case 4: template = \"stmia\\t%0!, %M1\"; break;
5757 ;;      case 5: template = \"stmia\\t%0, %M1\"; break;
5758 ;;      }
5759 ;;    output_asm_insn (template, operands);
5760 ;;    return \"\";
5761 ;;  }")
5763 (define_expand "movdi"
5764   [(set (match_operand:DI 0 "general_operand" "")
5765         (match_operand:DI 1 "general_operand" ""))]
5766   "TARGET_EITHER"
5767   "
5768   if (can_create_pseudo_p ())
5769     {
5770       if (!REG_P (operands[0]))
5771         operands[1] = force_reg (DImode, operands[1]);
5772     }
5773   if (REG_P (operands[0]) && REGNO (operands[0]) <= LAST_ARM_REGNUM
5774       && !HARD_REGNO_MODE_OK (REGNO (operands[0]), DImode))
5775     {
5776       /* Avoid LDRD's into an odd-numbered register pair in ARM state
5777          when expanding function calls.  */
5778       gcc_assert (can_create_pseudo_p ());
5779       if (MEM_P (operands[1]) && MEM_VOLATILE_P (operands[1]))
5780         {
5781           /* Perform load into legal reg pair first, then move.  */
5782           rtx reg = gen_reg_rtx (DImode);
5783           emit_insn (gen_movdi (reg, operands[1]));
5784           operands[1] = reg;
5785         }
5786       emit_move_insn (gen_lowpart (SImode, operands[0]),
5787                       gen_lowpart (SImode, operands[1]));
5788       emit_move_insn (gen_highpart (SImode, operands[0]),
5789                       gen_highpart (SImode, operands[1]));
5790       DONE;
5791     }
5792   else if (REG_P (operands[1]) && REGNO (operands[1]) <= LAST_ARM_REGNUM
5793            && !HARD_REGNO_MODE_OK (REGNO (operands[1]), DImode))
5794     {
5795       /* Avoid STRD's from an odd-numbered register pair in ARM state
5796          when expanding function prologue.  */
5797       gcc_assert (can_create_pseudo_p ());
5798       rtx split_dest = (MEM_P (operands[0]) && MEM_VOLATILE_P (operands[0]))
5799                        ? gen_reg_rtx (DImode)
5800                        : operands[0];
5801       emit_move_insn (gen_lowpart (SImode, split_dest),
5802                       gen_lowpart (SImode, operands[1]));
5803       emit_move_insn (gen_highpart (SImode, split_dest),
5804                       gen_highpart (SImode, operands[1]));
5805       if (split_dest != operands[0])
5806         emit_insn (gen_movdi (operands[0], split_dest));
5807       DONE;
5808     }
5809   "
5812 (define_insn "*arm_movdi"
5813   [(set (match_operand:DI 0 "nonimmediate_di_operand" "=r, r, r, q, m")
5814         (match_operand:DI 1 "di_operand"              "rDa,Db,Dc,mi,q"))]
5815   "TARGET_32BIT
5816    && !(TARGET_HARD_FLOAT)
5817    && !TARGET_IWMMXT
5818    && (   register_operand (operands[0], DImode)
5819        || register_operand (operands[1], DImode))"
5820   "*
5821   switch (which_alternative)
5822     {
5823     case 0:
5824     case 1:
5825     case 2:
5826       return \"#\";
5827     default:
5828       return output_move_double (operands, true, NULL);
5829     }
5830   "
5831   [(set_attr "length" "8,12,16,8,8")
5832    (set_attr "type" "multiple,multiple,multiple,load2,store2")
5833    (set_attr "arm_pool_range" "*,*,*,1020,*")
5834    (set_attr "arm_neg_pool_range" "*,*,*,1004,*")
5835    (set_attr "thumb2_pool_range" "*,*,*,4094,*")
5836    (set_attr "thumb2_neg_pool_range" "*,*,*,0,*")]
5839 (define_split
5840   [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
5841         (match_operand:ANY64 1 "immediate_operand" ""))]
5842   "TARGET_32BIT
5843    && reload_completed
5844    && (arm_const_double_inline_cost (operands[1])
5845        <= arm_max_const_double_inline_cost ())"
5846   [(const_int 0)]
5847   "
5848   arm_split_constant (SET, SImode, curr_insn,
5849                       INTVAL (gen_lowpart (SImode, operands[1])),
5850                       gen_lowpart (SImode, operands[0]), NULL_RTX, 0);
5851   arm_split_constant (SET, SImode, curr_insn,
5852                       INTVAL (gen_highpart_mode (SImode,
5853                                                  GET_MODE (operands[0]),
5854                                                  operands[1])),
5855                       gen_highpart (SImode, operands[0]), NULL_RTX, 0);
5856   DONE;
5857   "
5860 ; If optimizing for size, or if we have load delay slots, then 
5861 ; we want to split the constant into two separate operations. 
5862 ; In both cases this may split a trivial part into a single data op
5863 ; leaving a single complex constant to load.  We can also get longer
5864 ; offsets in a LDR which means we get better chances of sharing the pool
5865 ; entries.  Finally, we can normally do a better job of scheduling
5866 ; LDR instructions than we can with LDM.
5867 ; This pattern will only match if the one above did not.
5868 (define_split
5869   [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
5870         (match_operand:ANY64 1 "const_double_operand" ""))]
5871   "TARGET_ARM && reload_completed
5872    && arm_const_double_by_parts (operands[1])"
5873   [(set (match_dup 0) (match_dup 1))
5874    (set (match_dup 2) (match_dup 3))]
5875   "
5876   operands[2] = gen_highpart (SImode, operands[0]);
5877   operands[3] = gen_highpart_mode (SImode, GET_MODE (operands[0]),
5878                                    operands[1]);
5879   operands[0] = gen_lowpart (SImode, operands[0]);
5880   operands[1] = gen_lowpart (SImode, operands[1]);
5881   "
5884 (define_split
5885   [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
5886         (match_operand:ANY64 1 "arm_general_register_operand" ""))]
5887   "TARGET_EITHER && reload_completed"
5888   [(set (match_dup 0) (match_dup 1))
5889    (set (match_dup 2) (match_dup 3))]
5890   "
5891   operands[2] = gen_highpart (SImode, operands[0]);
5892   operands[3] = gen_highpart (SImode, operands[1]);
5893   operands[0] = gen_lowpart (SImode, operands[0]);
5894   operands[1] = gen_lowpart (SImode, operands[1]);
5896   /* Handle a partial overlap.  */
5897   if (rtx_equal_p (operands[0], operands[3]))
5898     {
5899       rtx tmp0 = operands[0];
5900       rtx tmp1 = operands[1];
5902       operands[0] = operands[2];
5903       operands[1] = operands[3];
5904       operands[2] = tmp0;
5905       operands[3] = tmp1;
5906     }
5907   "
5910 ;; We can't actually do base+index doubleword loads if the index and
5911 ;; destination overlap.  Split here so that we at least have chance to
5912 ;; schedule.
5913 (define_split
5914   [(set (match_operand:DI 0 "s_register_operand" "")
5915         (mem:DI (plus:SI (match_operand:SI 1 "s_register_operand" "")
5916                          (match_operand:SI 2 "s_register_operand" ""))))]
5917   "TARGET_LDRD
5918   && reg_overlap_mentioned_p (operands[0], operands[1])
5919   && reg_overlap_mentioned_p (operands[0], operands[2])"
5920   [(set (match_dup 4)
5921         (plus:SI (match_dup 1)
5922                  (match_dup 2)))
5923    (set (match_dup 0)
5924         (mem:DI (match_dup 4)))]
5925   "
5926   operands[4] = gen_rtx_REG (SImode, REGNO(operands[0]));
5927   "
5930 (define_expand "movsi"
5931   [(set (match_operand:SI 0 "general_operand" "")
5932         (match_operand:SI 1 "general_operand" ""))]
5933   "TARGET_EITHER"
5934   "
5935   {
5936   rtx base, offset, tmp;
5938   if (TARGET_32BIT)
5939     {
5940       /* Everything except mem = const or mem = mem can be done easily.  */
5941       if (MEM_P (operands[0]))
5942         operands[1] = force_reg (SImode, operands[1]);
5943       if (arm_general_register_operand (operands[0], SImode)
5944           && CONST_INT_P (operands[1])
5945           && !(const_ok_for_arm (INTVAL (operands[1]))
5946                || const_ok_for_arm (~INTVAL (operands[1]))))
5947         {
5948            if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[1]), SET))
5949              {
5950                 emit_insn (gen_rtx_SET (operands[0], operands[1]));
5951                 DONE;
5952              }
5953           else
5954              {
5955                 arm_split_constant (SET, SImode, NULL_RTX,
5956                                     INTVAL (operands[1]), operands[0], NULL_RTX,
5957                                     optimize && can_create_pseudo_p ());
5958                 DONE;
5959              }
5960         }
5961     }
5962   else /* TARGET_THUMB1...  */
5963     {
5964       if (can_create_pseudo_p ())
5965         {
5966           if (!REG_P (operands[0]))
5967             operands[1] = force_reg (SImode, operands[1]);
5968         }
5969     }
5971   if (ARM_OFFSETS_MUST_BE_WITHIN_SECTIONS_P)
5972     {
5973       split_const (operands[1], &base, &offset);
5974       if (GET_CODE (base) == SYMBOL_REF
5975           && !offset_within_block_p (base, INTVAL (offset)))
5976         {
5977           tmp = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];
5978           emit_move_insn (tmp, base);
5979           emit_insn (gen_addsi3 (operands[0], tmp, offset));
5980           DONE;
5981         }
5982     }
5984   /* Recognize the case where operand[1] is a reference to thread-local
5985      data and load its address to a register.  */
5986   if (arm_tls_referenced_p (operands[1]))
5987     {
5988       rtx tmp = operands[1];
5989       rtx addend = NULL;
5991       if (GET_CODE (tmp) == CONST && GET_CODE (XEXP (tmp, 0)) == PLUS)
5992         {
5993           addend = XEXP (XEXP (tmp, 0), 1);
5994           tmp = XEXP (XEXP (tmp, 0), 0);
5995         }
5997       gcc_assert (GET_CODE (tmp) == SYMBOL_REF);
5998       gcc_assert (SYMBOL_REF_TLS_MODEL (tmp) != 0);
6000       tmp = legitimize_tls_address (tmp,
6001                                     !can_create_pseudo_p () ? operands[0] : 0);
6002       if (addend)
6003         {
6004           tmp = gen_rtx_PLUS (SImode, tmp, addend);
6005           tmp = force_operand (tmp, operands[0]);
6006         }
6007       operands[1] = tmp;
6008     }
6009   else if (flag_pic
6010            && (CONSTANT_P (operands[1])
6011                || symbol_mentioned_p (operands[1])
6012                || label_mentioned_p (operands[1])))
6013       operands[1] = legitimize_pic_address (operands[1], SImode,
6014                                             (!can_create_pseudo_p ()
6015                                              ? operands[0]
6016                                              : 0));
6017   }
6018   "
6021 ;; The ARM LO_SUM and HIGH are backwards - HIGH sets the low bits, and
6022 ;; LO_SUM adds in the high bits.  Fortunately these are opaque operations
6023 ;; so this does not matter.
6024 (define_insn "*arm_movt"
6025   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r")
6026         (lo_sum:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6027                    (match_operand:SI 2 "general_operand"      "i,i")))]
6028   "TARGET_HAVE_MOVT && arm_valid_symbolic_address_p (operands[2])"
6029   "@
6030    movt%?\t%0, #:upper16:%c2
6031    movt\t%0, #:upper16:%c2"
6032   [(set_attr "arch"  "32,v8mb")
6033    (set_attr "predicable" "yes")
6034    (set_attr "predicable_short_it" "no")
6035    (set_attr "length" "4")
6036    (set_attr "type" "alu_sreg")]
6039 (define_insn "*arm_movsi_insn"
6040   [(set (match_operand:SI 0 "nonimmediate_operand" "=rk,r,r,r,rk,m")
6041         (match_operand:SI 1 "general_operand"      "rk, I,K,j,mi,rk"))]
6042   "TARGET_ARM && !TARGET_IWMMXT && !TARGET_HARD_FLOAT
6043    && (   register_operand (operands[0], SImode)
6044        || register_operand (operands[1], SImode))"
6045   "@
6046    mov%?\\t%0, %1
6047    mov%?\\t%0, %1
6048    mvn%?\\t%0, #%B1
6049    movw%?\\t%0, %1
6050    ldr%?\\t%0, %1
6051    str%?\\t%1, %0"
6052   [(set_attr "type" "mov_reg,mov_imm,mvn_imm,mov_imm,load1,store1")
6053    (set_attr "predicable" "yes")
6054    (set_attr "arch" "*,*,*,v6t2,*,*")
6055    (set_attr "pool_range" "*,*,*,*,4096,*")
6056    (set_attr "neg_pool_range" "*,*,*,*,4084,*")]
6059 (define_split
6060   [(set (match_operand:SI 0 "arm_general_register_operand" "")
6061         (match_operand:SI 1 "const_int_operand" ""))]
6062   "TARGET_32BIT
6063   && (!(const_ok_for_arm (INTVAL (operands[1]))
6064         || const_ok_for_arm (~INTVAL (operands[1]))))"
6065   [(clobber (const_int 0))]
6066   "
6067   arm_split_constant (SET, SImode, NULL_RTX, 
6068                       INTVAL (operands[1]), operands[0], NULL_RTX, 0);
6069   DONE;
6070   "
6073 ;; A normal way to do (symbol + offset) requires three instructions at least
6074 ;; (depends on how big the offset is) as below:
6075 ;; movw r0, #:lower16:g
6076 ;; movw r0, #:upper16:g
6077 ;; adds r0, #4
6079 ;; A better way would be:
6080 ;; movw r0, #:lower16:g+4
6081 ;; movw r0, #:upper16:g+4
6083 ;; The limitation of this way is that the length of offset should be a 16-bit
6084 ;; signed value, because current assembler only supports REL type relocation for
6085 ;; such case.  If the more powerful RELA type is supported in future, we should
6086 ;; update this pattern to go with better way.
6087 (define_split
6088   [(set (match_operand:SI 0 "arm_general_register_operand" "")
6089         (const:SI (plus:SI (match_operand:SI 1 "general_operand" "")
6090                            (match_operand:SI 2 "const_int_operand" ""))))]
6091   "TARGET_THUMB
6092    && TARGET_HAVE_MOVT
6093    && arm_disable_literal_pool
6094    && reload_completed
6095    && GET_CODE (operands[1]) == SYMBOL_REF"
6096   [(clobber (const_int 0))]
6097   "
6098     int offset = INTVAL (operands[2]);
6100     if (offset < -0x8000 || offset > 0x7fff)
6101       {
6102         arm_emit_movpair (operands[0], operands[1]);
6103         emit_insn (gen_rtx_SET (operands[0],
6104                                 gen_rtx_PLUS (SImode, operands[0], operands[2])));
6105       }
6106     else
6107       {
6108         rtx op = gen_rtx_CONST (SImode,
6109                                 gen_rtx_PLUS (SImode, operands[1], operands[2]));
6110         arm_emit_movpair (operands[0], op);
6111       }
6112   "
6115 ;; Split symbol_refs at the later stage (after cprop), instead of generating
6116 ;; movt/movw pair directly at expand.  Otherwise corresponding high_sum
6117 ;; and lo_sum would be merged back into memory load at cprop.  However,
6118 ;; if the default is to prefer movt/movw rather than a load from the constant
6119 ;; pool, the performance is better.
6120 (define_split
6121   [(set (match_operand:SI 0 "arm_general_register_operand" "")
6122        (match_operand:SI 1 "general_operand" ""))]
6123   "TARGET_USE_MOVT && GET_CODE (operands[1]) == SYMBOL_REF
6124    && !flag_pic && !target_word_relocations
6125    && !arm_tls_referenced_p (operands[1])"
6126   [(clobber (const_int 0))]
6128   arm_emit_movpair (operands[0], operands[1]);
6129   DONE;
6132 ;; When generating pic, we need to load the symbol offset into a register.
6133 ;; So that the optimizer does not confuse this with a normal symbol load
6134 ;; we use an unspec.  The offset will be loaded from a constant pool entry,
6135 ;; since that is the only type of relocation we can use.
6137 ;; Wrap calculation of the whole PIC address in a single pattern for the
6138 ;; benefit of optimizers, particularly, PRE and HOIST.  Calculation of
6139 ;; a PIC address involves two loads from memory, so we want to CSE it
6140 ;; as often as possible.
6141 ;; This pattern will be split into one of the pic_load_addr_* patterns
6142 ;; and a move after GCSE optimizations.
6144 ;; Note: Update arm.c: legitimize_pic_address() when changing this pattern.
6145 (define_expand "calculate_pic_address"
6146   [(set (match_operand:SI 0 "register_operand" "")
6147         (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "")
6148                          (unspec:SI [(match_operand:SI 2 "" "")]
6149                                     UNSPEC_PIC_SYM))))]
6150   "flag_pic"
6153 ;; Split calculate_pic_address into pic_load_addr_* and a move.
6154 (define_split
6155   [(set (match_operand:SI 0 "register_operand" "")
6156         (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "")
6157                          (unspec:SI [(match_operand:SI 2 "" "")]
6158                                     UNSPEC_PIC_SYM))))]
6159   "flag_pic"
6160   [(set (match_dup 3) (unspec:SI [(match_dup 2)] UNSPEC_PIC_SYM))
6161    (set (match_dup 0) (mem:SI (plus:SI (match_dup 1) (match_dup 3))))]
6162   "operands[3] = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];"
6165 ;; operand1 is the memory address to go into 
6166 ;; pic_load_addr_32bit.
6167 ;; operand2 is the PIC label to be emitted 
6168 ;; from pic_add_dot_plus_eight.
6169 ;; We do this to allow hoisting of the entire insn.
6170 (define_insn_and_split "pic_load_addr_unified"
6171   [(set (match_operand:SI 0 "s_register_operand" "=r,r,l")
6172         (unspec:SI [(match_operand:SI 1 "" "mX,mX,mX") 
6173                     (match_operand:SI 2 "" "")] 
6174                     UNSPEC_PIC_UNIFIED))]
6175  "flag_pic"
6176  "#"
6177  "&& reload_completed"
6178  [(set (match_dup 0) (unspec:SI [(match_dup 1)] UNSPEC_PIC_SYM))
6179   (set (match_dup 0) (unspec:SI [(match_dup 0) (match_dup 3)
6180                                  (match_dup 2)] UNSPEC_PIC_BASE))]
6181  "operands[3] = TARGET_THUMB ? GEN_INT (4) : GEN_INT (8);"
6182  [(set_attr "type" "load1,load1,load1")
6183   (set_attr "pool_range" "4096,4094,1022")
6184   (set_attr "neg_pool_range" "4084,0,0")
6185   (set_attr "arch"  "a,t2,t1")    
6186   (set_attr "length" "8,6,4")]
6189 ;; The rather odd constraints on the following are to force reload to leave
6190 ;; the insn alone, and to force the minipool generation pass to then move
6191 ;; the GOT symbol to memory.
6193 (define_insn "pic_load_addr_32bit"
6194   [(set (match_operand:SI 0 "s_register_operand" "=r")
6195         (unspec:SI [(match_operand:SI 1 "" "mX")] UNSPEC_PIC_SYM))]
6196   "TARGET_32BIT && flag_pic"
6197   "ldr%?\\t%0, %1"
6198   [(set_attr "type" "load1")
6199    (set (attr "pool_range")
6200         (if_then_else (eq_attr "is_thumb" "no")
6201                       (const_int 4096)
6202                       (const_int 4094)))
6203    (set (attr "neg_pool_range")
6204         (if_then_else (eq_attr "is_thumb" "no")
6205                       (const_int 4084)
6206                       (const_int 0)))]
6209 (define_insn "pic_load_addr_thumb1"
6210   [(set (match_operand:SI 0 "s_register_operand" "=l")
6211         (unspec:SI [(match_operand:SI 1 "" "mX")] UNSPEC_PIC_SYM))]
6212   "TARGET_THUMB1 && flag_pic"
6213   "ldr\\t%0, %1"
6214   [(set_attr "type" "load1")
6215    (set (attr "pool_range") (const_int 1018))]
6218 (define_insn "pic_add_dot_plus_four"
6219   [(set (match_operand:SI 0 "register_operand" "=r")
6220         (unspec:SI [(match_operand:SI 1 "register_operand" "0")
6221                     (const_int 4)
6222                     (match_operand 2 "" "")]
6223                    UNSPEC_PIC_BASE))]
6224   "TARGET_THUMB"
6225   "*
6226   (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
6227                                      INTVAL (operands[2]));
6228   return \"add\\t%0, %|pc\";
6229   "
6230   [(set_attr "length" "2")
6231    (set_attr "type" "alu_sreg")]
6234 (define_insn "pic_add_dot_plus_eight"
6235   [(set (match_operand:SI 0 "register_operand" "=r")
6236         (unspec:SI [(match_operand:SI 1 "register_operand" "r")
6237                     (const_int 8)
6238                     (match_operand 2 "" "")]
6239                    UNSPEC_PIC_BASE))]
6240   "TARGET_ARM"
6241   "*
6242     (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
6243                                        INTVAL (operands[2]));
6244     return \"add%?\\t%0, %|pc, %1\";
6245   "
6246   [(set_attr "predicable" "yes")
6247    (set_attr "type" "alu_sreg")]
6250 (define_insn "tls_load_dot_plus_eight"
6251   [(set (match_operand:SI 0 "register_operand" "=r")
6252         (mem:SI (unspec:SI [(match_operand:SI 1 "register_operand" "r")
6253                             (const_int 8)
6254                             (match_operand 2 "" "")]
6255                            UNSPEC_PIC_BASE)))]
6256   "TARGET_ARM"
6257   "*
6258     (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
6259                                        INTVAL (operands[2]));
6260     return \"ldr%?\\t%0, [%|pc, %1]\t\t@ tls_load_dot_plus_eight\";
6261   "
6262   [(set_attr "predicable" "yes")
6263    (set_attr "type" "load1")]
6266 ;; PIC references to local variables can generate pic_add_dot_plus_eight
6267 ;; followed by a load.  These sequences can be crunched down to
6268 ;; tls_load_dot_plus_eight by a peephole.
6270 (define_peephole2
6271   [(set (match_operand:SI 0 "register_operand" "")
6272         (unspec:SI [(match_operand:SI 3 "register_operand" "")
6273                     (const_int 8)
6274                     (match_operand 1 "" "")]
6275                    UNSPEC_PIC_BASE))
6276    (set (match_operand:SI 2 "arm_general_register_operand" "")
6277         (mem:SI (match_dup 0)))]
6278   "TARGET_ARM && peep2_reg_dead_p (2, operands[0])"
6279   [(set (match_dup 2)
6280         (mem:SI (unspec:SI [(match_dup 3)
6281                             (const_int 8)
6282                             (match_dup 1)]
6283                            UNSPEC_PIC_BASE)))]
6284   ""
6287 (define_insn "pic_offset_arm"
6288   [(set (match_operand:SI 0 "register_operand" "=r")
6289         (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
6290                          (unspec:SI [(match_operand:SI 2 "" "X")]
6291                                     UNSPEC_PIC_OFFSET))))]
6292   "TARGET_VXWORKS_RTP && TARGET_ARM && flag_pic"
6293   "ldr%?\\t%0, [%1,%2]"
6294   [(set_attr "type" "load1")]
6297 (define_expand "builtin_setjmp_receiver"
6298   [(label_ref (match_operand 0 "" ""))]
6299   "flag_pic"
6300   "
6302   /* r3 is clobbered by set/longjmp, so we can use it as a scratch
6303      register.  */
6304   if (arm_pic_register != INVALID_REGNUM)
6305     arm_load_pic_register (1UL << 3);
6306   DONE;
6309 ;; If copying one reg to another we can set the condition codes according to
6310 ;; its value.  Such a move is common after a return from subroutine and the
6311 ;; result is being tested against zero.
6313 (define_insn "*movsi_compare0"
6314   [(set (reg:CC CC_REGNUM)
6315         (compare:CC (match_operand:SI 1 "s_register_operand" "0,r")
6316                     (const_int 0)))
6317    (set (match_operand:SI 0 "s_register_operand" "=r,r")
6318         (match_dup 1))]
6319   "TARGET_32BIT"
6320   "@
6321    cmp%?\\t%0, #0
6322    subs%?\\t%0, %1, #0"
6323   [(set_attr "conds" "set")
6324    (set_attr "type" "alus_imm,alus_imm")]
6327 ;; Subroutine to store a half word from a register into memory.
6328 ;; Operand 0 is the source register (HImode)
6329 ;; Operand 1 is the destination address in a register (SImode)
6331 ;; In both this routine and the next, we must be careful not to spill
6332 ;; a memory address of reg+large_const into a separate PLUS insn, since this
6333 ;; can generate unrecognizable rtl.
6335 (define_expand "storehi"
6336   [;; store the low byte
6337    (set (match_operand 1 "" "") (match_dup 3))
6338    ;; extract the high byte
6339    (set (match_dup 2)
6340         (ashiftrt:SI (match_operand 0 "" "") (const_int 8)))
6341    ;; store the high byte
6342    (set (match_dup 4) (match_dup 5))]
6343   "TARGET_ARM"
6344   "
6345   {
6346     rtx op1 = operands[1];
6347     rtx addr = XEXP (op1, 0);
6348     enum rtx_code code = GET_CODE (addr);
6350     if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1)))
6351         || code == MINUS)
6352       op1 = replace_equiv_address (operands[1], force_reg (SImode, addr));
6354     operands[4] = adjust_address (op1, QImode, 1);
6355     operands[1] = adjust_address (operands[1], QImode, 0);
6356     operands[3] = gen_lowpart (QImode, operands[0]);
6357     operands[0] = gen_lowpart (SImode, operands[0]);
6358     operands[2] = gen_reg_rtx (SImode);
6359     operands[5] = gen_lowpart (QImode, operands[2]);
6360   }"
6363 (define_expand "storehi_bigend"
6364   [(set (match_dup 4) (match_dup 3))
6365    (set (match_dup 2)
6366         (ashiftrt:SI (match_operand 0 "" "") (const_int 8)))
6367    (set (match_operand 1 "" "") (match_dup 5))]
6368   "TARGET_ARM"
6369   "
6370   {
6371     rtx op1 = operands[1];
6372     rtx addr = XEXP (op1, 0);
6373     enum rtx_code code = GET_CODE (addr);
6375     if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1)))
6376         || code == MINUS)
6377       op1 = replace_equiv_address (op1, force_reg (SImode, addr));
6379     operands[4] = adjust_address (op1, QImode, 1);
6380     operands[1] = adjust_address (operands[1], QImode, 0);
6381     operands[3] = gen_lowpart (QImode, operands[0]);
6382     operands[0] = gen_lowpart (SImode, operands[0]);
6383     operands[2] = gen_reg_rtx (SImode);
6384     operands[5] = gen_lowpart (QImode, operands[2]);
6385   }"
6388 ;; Subroutine to store a half word integer constant into memory.
6389 (define_expand "storeinthi"
6390   [(set (match_operand 0 "" "")
6391         (match_operand 1 "" ""))
6392    (set (match_dup 3) (match_dup 2))]
6393   "TARGET_ARM"
6394   "
6395   {
6396     HOST_WIDE_INT value = INTVAL (operands[1]);
6397     rtx addr = XEXP (operands[0], 0);
6398     rtx op0 = operands[0];
6399     enum rtx_code code = GET_CODE (addr);
6401     if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1)))
6402         || code == MINUS)
6403       op0 = replace_equiv_address (op0, force_reg (SImode, addr));
6405     operands[1] = gen_reg_rtx (SImode);
6406     if (BYTES_BIG_ENDIAN)
6407       {
6408         emit_insn (gen_movsi (operands[1], GEN_INT ((value >> 8) & 255)));
6409         if ((value & 255) == ((value >> 8) & 255))
6410           operands[2] = operands[1];
6411         else
6412           {
6413             operands[2] = gen_reg_rtx (SImode);
6414             emit_insn (gen_movsi (operands[2], GEN_INT (value & 255)));
6415           }
6416       }
6417     else
6418       {
6419         emit_insn (gen_movsi (operands[1], GEN_INT (value & 255)));
6420         if ((value & 255) == ((value >> 8) & 255))
6421           operands[2] = operands[1];
6422         else
6423           {
6424             operands[2] = gen_reg_rtx (SImode);
6425             emit_insn (gen_movsi (operands[2], GEN_INT ((value >> 8) & 255)));
6426           }
6427       }
6429     operands[3] = adjust_address (op0, QImode, 1);
6430     operands[0] = adjust_address (operands[0], QImode, 0);
6431     operands[2] = gen_lowpart (QImode, operands[2]);
6432     operands[1] = gen_lowpart (QImode, operands[1]);
6433   }"
6436 (define_expand "storehi_single_op"
6437   [(set (match_operand:HI 0 "memory_operand" "")
6438         (match_operand:HI 1 "general_operand" ""))]
6439   "TARGET_32BIT && arm_arch4"
6440   "
6441   if (!s_register_operand (operands[1], HImode))
6442     operands[1] = copy_to_mode_reg (HImode, operands[1]);
6443   "
6446 (define_expand "movhi"
6447   [(set (match_operand:HI 0 "general_operand" "")
6448         (match_operand:HI 1 "general_operand" ""))]
6449   "TARGET_EITHER"
6450   "
6451   if (TARGET_ARM)
6452     {
6453       if (can_create_pseudo_p ())
6454         {
6455           if (MEM_P (operands[0]))
6456             {
6457               if (arm_arch4)
6458                 {
6459                   emit_insn (gen_storehi_single_op (operands[0], operands[1]));
6460                   DONE;
6461                 }
6462               if (CONST_INT_P (operands[1]))
6463                 emit_insn (gen_storeinthi (operands[0], operands[1]));
6464               else
6465                 {
6466                   if (MEM_P (operands[1]))
6467                     operands[1] = force_reg (HImode, operands[1]);
6468                   if (BYTES_BIG_ENDIAN)
6469                     emit_insn (gen_storehi_bigend (operands[1], operands[0]));
6470                   else
6471                    emit_insn (gen_storehi (operands[1], operands[0]));
6472                 }
6473               DONE;
6474             }
6475           /* Sign extend a constant, and keep it in an SImode reg.  */
6476           else if (CONST_INT_P (operands[1]))
6477             {
6478               rtx reg = gen_reg_rtx (SImode);
6479               HOST_WIDE_INT val = INTVAL (operands[1]) & 0xffff;
6481               /* If the constant is already valid, leave it alone.  */
6482               if (!const_ok_for_arm (val))
6483                 {
6484                   /* If setting all the top bits will make the constant 
6485                      loadable in a single instruction, then set them.  
6486                      Otherwise, sign extend the number.  */
6488                   if (const_ok_for_arm (~(val | ~0xffff)))
6489                     val |= ~0xffff;
6490                   else if (val & 0x8000)
6491                     val |= ~0xffff;
6492                 }
6494               emit_insn (gen_movsi (reg, GEN_INT (val)));
6495               operands[1] = gen_lowpart (HImode, reg);
6496             }
6497           else if (arm_arch4 && optimize && can_create_pseudo_p ()
6498                    && MEM_P (operands[1]))
6499             {
6500               rtx reg = gen_reg_rtx (SImode);
6502               emit_insn (gen_zero_extendhisi2 (reg, operands[1]));
6503               operands[1] = gen_lowpart (HImode, reg);
6504             }
6505           else if (!arm_arch4)
6506             {
6507               if (MEM_P (operands[1]))
6508                 {
6509                   rtx base;
6510                   rtx offset = const0_rtx;
6511                   rtx reg = gen_reg_rtx (SImode);
6513                   if ((REG_P (base = XEXP (operands[1], 0))
6514                        || (GET_CODE (base) == PLUS
6515                            && (CONST_INT_P (offset = XEXP (base, 1)))
6516                            && ((INTVAL(offset) & 1) != 1)
6517                            && REG_P (base = XEXP (base, 0))))
6518                       && REGNO_POINTER_ALIGN (REGNO (base)) >= 32)
6519                     {
6520                       rtx new_rtx;
6522                       new_rtx = widen_memory_access (operands[1], SImode,
6523                                                      ((INTVAL (offset) & ~3)
6524                                                       - INTVAL (offset)));
6525                       emit_insn (gen_movsi (reg, new_rtx));
6526                       if (((INTVAL (offset) & 2) != 0)
6527                           ^ (BYTES_BIG_ENDIAN ? 1 : 0))
6528                         {
6529                           rtx reg2 = gen_reg_rtx (SImode);
6531                           emit_insn (gen_lshrsi3 (reg2, reg, GEN_INT (16)));
6532                           reg = reg2;
6533                         }
6534                     }
6535                   else
6536                     emit_insn (gen_movhi_bytes (reg, operands[1]));
6538                   operands[1] = gen_lowpart (HImode, reg);
6539                }
6540            }
6541         }
6542       /* Handle loading a large integer during reload.  */
6543       else if (CONST_INT_P (operands[1])
6544                && !const_ok_for_arm (INTVAL (operands[1]))
6545                && !const_ok_for_arm (~INTVAL (operands[1])))
6546         {
6547           /* Writing a constant to memory needs a scratch, which should
6548              be handled with SECONDARY_RELOADs.  */
6549           gcc_assert (REG_P (operands[0]));
6551           operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
6552           emit_insn (gen_movsi (operands[0], operands[1]));
6553           DONE;
6554        }
6555     }
6556   else if (TARGET_THUMB2)
6557     {
6558       /* Thumb-2 can do everything except mem=mem and mem=const easily.  */
6559       if (can_create_pseudo_p ())
6560         {
6561           if (!REG_P (operands[0]))
6562             operands[1] = force_reg (HImode, operands[1]);
6563           /* Zero extend a constant, and keep it in an SImode reg.  */
6564           else if (CONST_INT_P (operands[1]))
6565             {
6566               rtx reg = gen_reg_rtx (SImode);
6567               HOST_WIDE_INT val = INTVAL (operands[1]) & 0xffff;
6569               emit_insn (gen_movsi (reg, GEN_INT (val)));
6570               operands[1] = gen_lowpart (HImode, reg);
6571             }
6572         }
6573     }
6574   else /* TARGET_THUMB1 */
6575     {
6576       if (can_create_pseudo_p ())
6577         {
6578           if (CONST_INT_P (operands[1]))
6579             {
6580               rtx reg = gen_reg_rtx (SImode);
6582               emit_insn (gen_movsi (reg, operands[1]));
6583               operands[1] = gen_lowpart (HImode, reg);
6584             }
6586           /* ??? We shouldn't really get invalid addresses here, but this can
6587              happen if we are passed a SP (never OK for HImode/QImode) or 
6588              virtual register (also rejected as illegitimate for HImode/QImode)
6589              relative address.  */
6590           /* ??? This should perhaps be fixed elsewhere, for instance, in
6591              fixup_stack_1, by checking for other kinds of invalid addresses,
6592              e.g. a bare reference to a virtual register.  This may confuse the
6593              alpha though, which must handle this case differently.  */
6594           if (MEM_P (operands[0])
6595               && !memory_address_p (GET_MODE (operands[0]),
6596                                     XEXP (operands[0], 0)))
6597             operands[0]
6598               = replace_equiv_address (operands[0],
6599                                        copy_to_reg (XEXP (operands[0], 0)));
6600    
6601           if (MEM_P (operands[1])
6602               && !memory_address_p (GET_MODE (operands[1]),
6603                                     XEXP (operands[1], 0)))
6604             operands[1]
6605               = replace_equiv_address (operands[1],
6606                                        copy_to_reg (XEXP (operands[1], 0)));
6608           if (MEM_P (operands[1]) && optimize > 0)
6609             {
6610               rtx reg = gen_reg_rtx (SImode);
6612               emit_insn (gen_zero_extendhisi2 (reg, operands[1]));
6613               operands[1] = gen_lowpart (HImode, reg);
6614             }
6616           if (MEM_P (operands[0]))
6617             operands[1] = force_reg (HImode, operands[1]);
6618         }
6619       else if (CONST_INT_P (operands[1])
6620                 && !satisfies_constraint_I (operands[1]))
6621         {
6622           /* Handle loading a large integer during reload.  */
6624           /* Writing a constant to memory needs a scratch, which should
6625              be handled with SECONDARY_RELOADs.  */
6626           gcc_assert (REG_P (operands[0]));
6628           operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
6629           emit_insn (gen_movsi (operands[0], operands[1]));
6630           DONE;
6631         }
6632     }
6633   "
6636 (define_expand "movhi_bytes"
6637   [(set (match_dup 2) (zero_extend:SI (match_operand:HI 1 "" "")))
6638    (set (match_dup 3)
6639         (zero_extend:SI (match_dup 6)))
6640    (set (match_operand:SI 0 "" "")
6641          (ior:SI (ashift:SI (match_dup 4) (const_int 8)) (match_dup 5)))]
6642   "TARGET_ARM"
6643   "
6644   {
6645     rtx mem1, mem2;
6646     rtx addr = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
6648     mem1 = change_address (operands[1], QImode, addr);
6649     mem2 = change_address (operands[1], QImode,
6650                            plus_constant (Pmode, addr, 1));
6651     operands[0] = gen_lowpart (SImode, operands[0]);
6652     operands[1] = mem1;
6653     operands[2] = gen_reg_rtx (SImode);
6654     operands[3] = gen_reg_rtx (SImode);
6655     operands[6] = mem2;
6657     if (BYTES_BIG_ENDIAN)
6658       {
6659         operands[4] = operands[2];
6660         operands[5] = operands[3];
6661       }
6662     else
6663       {
6664         operands[4] = operands[3];
6665         operands[5] = operands[2];
6666       }
6667   }"
6670 (define_expand "movhi_bigend"
6671   [(set (match_dup 2)
6672         (rotate:SI (subreg:SI (match_operand:HI 1 "memory_operand" "") 0)
6673                    (const_int 16)))
6674    (set (match_dup 3)
6675         (ashiftrt:SI (match_dup 2) (const_int 16)))
6676    (set (match_operand:HI 0 "s_register_operand" "")
6677         (match_dup 4))]
6678   "TARGET_ARM"
6679   "
6680   operands[2] = gen_reg_rtx (SImode);
6681   operands[3] = gen_reg_rtx (SImode);
6682   operands[4] = gen_lowpart (HImode, operands[3]);
6683   "
6686 ;; Pattern to recognize insn generated default case above
6687 (define_insn "*movhi_insn_arch4"
6688   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m,r")
6689         (match_operand:HI 1 "general_operand"      "rIk,K,n,r,mi"))]
6690   "TARGET_ARM
6691    && arm_arch4 && !TARGET_HARD_FLOAT
6692    && (register_operand (operands[0], HImode)
6693        || register_operand (operands[1], HImode))"
6694   "@
6695    mov%?\\t%0, %1\\t%@ movhi
6696    mvn%?\\t%0, #%B1\\t%@ movhi
6697    movw%?\\t%0, %L1\\t%@ movhi
6698    strh%?\\t%1, %0\\t%@ movhi
6699    ldrh%?\\t%0, %1\\t%@ movhi"
6700   [(set_attr "predicable" "yes")
6701    (set_attr "pool_range" "*,*,*,*,256")
6702    (set_attr "neg_pool_range" "*,*,*,*,244")
6703    (set_attr "arch" "*,*,v6t2,*,*")
6704    (set_attr_alternative "type"
6705                          [(if_then_else (match_operand 1 "const_int_operand" "")
6706                                         (const_string "mov_imm" )
6707                                         (const_string "mov_reg"))
6708                           (const_string "mvn_imm")
6709                           (const_string "mov_imm")
6710                           (const_string "store1")
6711                           (const_string "load1")])]
6714 (define_insn "*movhi_bytes"
6715   [(set (match_operand:HI 0 "s_register_operand" "=r,r,r")
6716         (match_operand:HI 1 "arm_rhs_operand"  "I,rk,K"))]
6717   "TARGET_ARM && !TARGET_HARD_FLOAT"
6718   "@
6719    mov%?\\t%0, %1\\t%@ movhi
6720    mov%?\\t%0, %1\\t%@ movhi
6721    mvn%?\\t%0, #%B1\\t%@ movhi"
6722   [(set_attr "predicable" "yes")
6723    (set_attr "type" "mov_imm,mov_reg,mvn_imm")]
6726 ;; We use a DImode scratch because we may occasionally need an additional
6727 ;; temporary if the address isn't offsettable -- push_reload doesn't seem
6728 ;; to take any notice of the "o" constraints on reload_memory_operand operand.
6729 (define_expand "reload_outhi"
6730   [(parallel [(match_operand:HI 0 "arm_reload_memory_operand" "=o")
6731               (match_operand:HI 1 "s_register_operand"        "r")
6732               (match_operand:DI 2 "s_register_operand"        "=&l")])]
6733   "TARGET_EITHER"
6734   "if (TARGET_ARM)
6735      arm_reload_out_hi (operands);
6736    else
6737      thumb_reload_out_hi (operands);
6738   DONE;
6739   "
6742 (define_expand "reload_inhi"
6743   [(parallel [(match_operand:HI 0 "s_register_operand" "=r")
6744               (match_operand:HI 1 "arm_reload_memory_operand" "o")
6745               (match_operand:DI 2 "s_register_operand" "=&r")])]
6746   "TARGET_EITHER"
6747   "
6748   if (TARGET_ARM)
6749     arm_reload_in_hi (operands);
6750   else
6751     thumb_reload_out_hi (operands);
6752   DONE;
6755 (define_expand "movqi"
6756   [(set (match_operand:QI 0 "general_operand" "")
6757         (match_operand:QI 1 "general_operand" ""))]
6758   "TARGET_EITHER"
6759   "
6760   /* Everything except mem = const or mem = mem can be done easily */
6762   if (can_create_pseudo_p ())
6763     {
6764       if (CONST_INT_P (operands[1]))
6765         {
6766           rtx reg = gen_reg_rtx (SImode);
6768           /* For thumb we want an unsigned immediate, then we are more likely 
6769              to be able to use a movs insn.  */
6770           if (TARGET_THUMB)
6771             operands[1] = GEN_INT (INTVAL (operands[1]) & 255);
6773           emit_insn (gen_movsi (reg, operands[1]));
6774           operands[1] = gen_lowpart (QImode, reg);
6775         }
6777       if (TARGET_THUMB)
6778         {
6779           /* ??? We shouldn't really get invalid addresses here, but this can
6780              happen if we are passed a SP (never OK for HImode/QImode) or
6781              virtual register (also rejected as illegitimate for HImode/QImode)
6782              relative address.  */
6783           /* ??? This should perhaps be fixed elsewhere, for instance, in
6784              fixup_stack_1, by checking for other kinds of invalid addresses,
6785              e.g. a bare reference to a virtual register.  This may confuse the
6786              alpha though, which must handle this case differently.  */
6787           if (MEM_P (operands[0])
6788               && !memory_address_p (GET_MODE (operands[0]),
6789                                      XEXP (operands[0], 0)))
6790             operands[0]
6791               = replace_equiv_address (operands[0],
6792                                        copy_to_reg (XEXP (operands[0], 0)));
6793           if (MEM_P (operands[1])
6794               && !memory_address_p (GET_MODE (operands[1]),
6795                                     XEXP (operands[1], 0)))
6796              operands[1]
6797                = replace_equiv_address (operands[1],
6798                                         copy_to_reg (XEXP (operands[1], 0)));
6799         }
6801       if (MEM_P (operands[1]) && optimize > 0)
6802         {
6803           rtx reg = gen_reg_rtx (SImode);
6805           emit_insn (gen_zero_extendqisi2 (reg, operands[1]));
6806           operands[1] = gen_lowpart (QImode, reg);
6807         }
6809       if (MEM_P (operands[0]))
6810         operands[1] = force_reg (QImode, operands[1]);
6811     }
6812   else if (TARGET_THUMB
6813            && CONST_INT_P (operands[1])
6814            && !satisfies_constraint_I (operands[1]))
6815     {
6816       /* Handle loading a large integer during reload.  */
6818       /* Writing a constant to memory needs a scratch, which should
6819          be handled with SECONDARY_RELOADs.  */
6820       gcc_assert (REG_P (operands[0]));
6822       operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
6823       emit_insn (gen_movsi (operands[0], operands[1]));
6824       DONE;
6825     }
6826   "
6829 (define_insn "*arm_movqi_insn"
6830   [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,r,l,r,l,Uu,r,m")
6831         (match_operand:QI 1 "general_operand" "rk,rk,I,Py,K,Uu,l,Uh,r"))]
6832   "TARGET_32BIT
6833    && (   register_operand (operands[0], QImode)
6834        || register_operand (operands[1], QImode))"
6835   "@
6836    mov%?\\t%0, %1
6837    mov%?\\t%0, %1
6838    mov%?\\t%0, %1
6839    mov%?\\t%0, %1
6840    mvn%?\\t%0, #%B1
6841    ldrb%?\\t%0, %1
6842    strb%?\\t%1, %0
6843    ldrb%?\\t%0, %1
6844    strb%?\\t%1, %0"
6845   [(set_attr "type" "mov_reg,mov_reg,mov_imm,mov_imm,mvn_imm,load1,store1,load1,store1")
6846    (set_attr "predicable" "yes")
6847    (set_attr "predicable_short_it" "yes,yes,no,yes,no,no,no,no,no")
6848    (set_attr "arch" "t2,any,any,t2,any,t2,t2,any,any")
6849    (set_attr "length" "2,4,4,2,4,2,2,4,4")]
6852 ;; HFmode moves
6853 (define_expand "movhf"
6854   [(set (match_operand:HF 0 "general_operand" "")
6855         (match_operand:HF 1 "general_operand" ""))]
6856   "TARGET_EITHER"
6857   "
6858   if (TARGET_32BIT)
6859     {
6860       if (MEM_P (operands[0]))
6861         operands[1] = force_reg (HFmode, operands[1]);
6862     }
6863   else /* TARGET_THUMB1 */
6864     {
6865       if (can_create_pseudo_p ())
6866         {
6867            if (!REG_P (operands[0]))
6868              operands[1] = force_reg (HFmode, operands[1]);
6869         }
6870     }
6871   "
6874 (define_insn "*arm32_movhf"
6875   [(set (match_operand:HF 0 "nonimmediate_operand" "=r,m,r,r")
6876         (match_operand:HF 1 "general_operand"      " m,r,r,F"))]
6877   "TARGET_32BIT && !TARGET_HARD_FLOAT
6878    && (   s_register_operand (operands[0], HFmode)
6879        || s_register_operand (operands[1], HFmode))"
6880   "*
6881   switch (which_alternative)
6882     {
6883     case 0:     /* ARM register from memory */
6884       return \"ldrh%?\\t%0, %1\\t%@ __fp16\";
6885     case 1:     /* memory from ARM register */
6886       return \"strh%?\\t%1, %0\\t%@ __fp16\";
6887     case 2:     /* ARM register from ARM register */
6888       return \"mov%?\\t%0, %1\\t%@ __fp16\";
6889     case 3:     /* ARM register from constant */
6890       {
6891         long bits;
6892         rtx ops[4];
6894         bits = real_to_target (NULL, CONST_DOUBLE_REAL_VALUE (operands[1]),
6895                                HFmode);
6896         ops[0] = operands[0];
6897         ops[1] = GEN_INT (bits);
6898         ops[2] = GEN_INT (bits & 0xff00);
6899         ops[3] = GEN_INT (bits & 0x00ff);
6901         if (arm_arch_thumb2)
6902           output_asm_insn (\"movw%?\\t%0, %1\", ops);
6903         else
6904           output_asm_insn (\"mov%?\\t%0, %2\;orr%?\\t%0, %0, %3\", ops);
6905         return \"\";
6906        }
6907     default:
6908       gcc_unreachable ();
6909     }
6910   "
6911   [(set_attr "conds" "unconditional")
6912    (set_attr "type" "load1,store1,mov_reg,multiple")
6913    (set_attr "length" "4,4,4,8")
6914    (set_attr "predicable" "yes")
6915    (set_attr "predicable_short_it" "no")]
6918 (define_expand "movsf"
6919   [(set (match_operand:SF 0 "general_operand" "")
6920         (match_operand:SF 1 "general_operand" ""))]
6921   "TARGET_EITHER"
6922   "
6923   if (TARGET_32BIT)
6924     {
6925       if (MEM_P (operands[0]))
6926         operands[1] = force_reg (SFmode, operands[1]);
6927     }
6928   else /* TARGET_THUMB1 */
6929     {
6930       if (can_create_pseudo_p ())
6931         {
6932            if (!REG_P (operands[0]))
6933              operands[1] = force_reg (SFmode, operands[1]);
6934         }
6935     }
6936   "
6939 ;; Transform a floating-point move of a constant into a core register into
6940 ;; an SImode operation.
6941 (define_split
6942   [(set (match_operand:SF 0 "arm_general_register_operand" "")
6943         (match_operand:SF 1 "immediate_operand" ""))]
6944   "TARGET_EITHER
6945    && reload_completed
6946    && CONST_DOUBLE_P (operands[1])"
6947   [(set (match_dup 2) (match_dup 3))]
6948   "
6949   operands[2] = gen_lowpart (SImode, operands[0]);
6950   operands[3] = gen_lowpart (SImode, operands[1]);
6951   if (operands[2] == 0 || operands[3] == 0)
6952     FAIL;
6953   "
6956 (define_insn "*arm_movsf_soft_insn"
6957   [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,m")
6958         (match_operand:SF 1 "general_operand"  "r,mE,r"))]
6959   "TARGET_32BIT
6960    && TARGET_SOFT_FLOAT
6961    && (!MEM_P (operands[0])
6962        || register_operand (operands[1], SFmode))"
6963   "@
6964    mov%?\\t%0, %1
6965    ldr%?\\t%0, %1\\t%@ float
6966    str%?\\t%1, %0\\t%@ float"
6967   [(set_attr "predicable" "yes")
6968    (set_attr "predicable_short_it" "no")
6969    (set_attr "type" "mov_reg,load1,store1")
6970    (set_attr "arm_pool_range" "*,4096,*")
6971    (set_attr "thumb2_pool_range" "*,4094,*")
6972    (set_attr "arm_neg_pool_range" "*,4084,*")
6973    (set_attr "thumb2_neg_pool_range" "*,0,*")]
6976 (define_expand "movdf"
6977   [(set (match_operand:DF 0 "general_operand" "")
6978         (match_operand:DF 1 "general_operand" ""))]
6979   "TARGET_EITHER"
6980   "
6981   if (TARGET_32BIT)
6982     {
6983       if (MEM_P (operands[0]))
6984         operands[1] = force_reg (DFmode, operands[1]);
6985     }
6986   else /* TARGET_THUMB */
6987     {
6988       if (can_create_pseudo_p ())
6989         {
6990           if (!REG_P (operands[0]))
6991             operands[1] = force_reg (DFmode, operands[1]);
6992         }
6993     }
6994   "
6997 ;; Reloading a df mode value stored in integer regs to memory can require a
6998 ;; scratch reg.
6999 (define_expand "reload_outdf"
7000   [(match_operand:DF 0 "arm_reload_memory_operand" "=o")
7001    (match_operand:DF 1 "s_register_operand" "r")
7002    (match_operand:SI 2 "s_register_operand" "=&r")]
7003   "TARGET_THUMB2"
7004   "
7005   {
7006     enum rtx_code code = GET_CODE (XEXP (operands[0], 0));
7008     if (code == REG)
7009       operands[2] = XEXP (operands[0], 0);
7010     else if (code == POST_INC || code == PRE_DEC)
7011       {
7012         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7013         operands[1] = gen_rtx_SUBREG (DImode, operands[1], 0);
7014         emit_insn (gen_movdi (operands[0], operands[1]));
7015         DONE;
7016       }
7017     else if (code == PRE_INC)
7018       {
7019         rtx reg = XEXP (XEXP (operands[0], 0), 0);
7021         emit_insn (gen_addsi3 (reg, reg, GEN_INT (8)));
7022         operands[2] = reg;
7023       }
7024     else if (code == POST_DEC)
7025       operands[2] = XEXP (XEXP (operands[0], 0), 0);
7026     else
7027       emit_insn (gen_addsi3 (operands[2], XEXP (XEXP (operands[0], 0), 0),
7028                              XEXP (XEXP (operands[0], 0), 1)));
7030     emit_insn (gen_rtx_SET (replace_equiv_address (operands[0], operands[2]),
7031                             operands[1]));
7033     if (code == POST_DEC)
7034       emit_insn (gen_addsi3 (operands[2], operands[2], GEN_INT (-8)));
7036     DONE;
7037   }"
7040 (define_insn "*movdf_soft_insn"
7041   [(set (match_operand:DF 0 "nonimmediate_soft_df_operand" "=r,r,r,q,m")
7042         (match_operand:DF 1 "soft_df_operand" "rDa,Db,Dc,mF,q"))]
7043   "TARGET_32BIT && TARGET_SOFT_FLOAT
7044    && (   register_operand (operands[0], DFmode)
7045        || register_operand (operands[1], DFmode))"
7046   "*
7047   switch (which_alternative)
7048     {
7049     case 0:
7050     case 1:
7051     case 2:
7052       return \"#\";
7053     default:
7054       return output_move_double (operands, true, NULL);
7055     }
7056   "
7057   [(set_attr "length" "8,12,16,8,8")
7058    (set_attr "type" "multiple,multiple,multiple,load2,store2")
7059    (set_attr "arm_pool_range" "*,*,*,1020,*")
7060    (set_attr "thumb2_pool_range" "*,*,*,1018,*")
7061    (set_attr "arm_neg_pool_range" "*,*,*,1004,*")
7062    (set_attr "thumb2_neg_pool_range" "*,*,*,0,*")]
7066 ;; load- and store-multiple insns
7067 ;; The arm can load/store any set of registers, provided that they are in
7068 ;; ascending order, but these expanders assume a contiguous set.
7070 (define_expand "load_multiple"
7071   [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
7072                           (match_operand:SI 1 "" ""))
7073                      (use (match_operand:SI 2 "" ""))])]
7074   "TARGET_32BIT"
7076   HOST_WIDE_INT offset = 0;
7078   /* Support only fixed point registers.  */
7079   if (!CONST_INT_P (operands[2])
7080       || INTVAL (operands[2]) > MAX_LDM_STM_OPS
7081       || INTVAL (operands[2]) < 2
7082       || !MEM_P (operands[1])
7083       || !REG_P (operands[0])
7084       || REGNO (operands[0]) > (LAST_ARM_REGNUM - 1)
7085       || REGNO (operands[0]) + INTVAL (operands[2]) > LAST_ARM_REGNUM)
7086     FAIL;
7088   operands[3]
7089     = arm_gen_load_multiple (arm_regs_in_sequence + REGNO (operands[0]),
7090                              INTVAL (operands[2]),
7091                              force_reg (SImode, XEXP (operands[1], 0)),
7092                              FALSE, operands[1], &offset);
7095 (define_expand "store_multiple"
7096   [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
7097                           (match_operand:SI 1 "" ""))
7098                      (use (match_operand:SI 2 "" ""))])]
7099   "TARGET_32BIT"
7101   HOST_WIDE_INT offset = 0;
7103   /* Support only fixed point registers.  */
7104   if (!CONST_INT_P (operands[2])
7105       || INTVAL (operands[2]) > MAX_LDM_STM_OPS
7106       || INTVAL (operands[2]) < 2
7107       || !REG_P (operands[1])
7108       || !MEM_P (operands[0])
7109       || REGNO (operands[1]) > (LAST_ARM_REGNUM - 1)
7110       || REGNO (operands[1]) + INTVAL (operands[2]) > LAST_ARM_REGNUM)
7111     FAIL;
7113   operands[3]
7114     = arm_gen_store_multiple (arm_regs_in_sequence + REGNO (operands[1]),
7115                               INTVAL (operands[2]),
7116                               force_reg (SImode, XEXP (operands[0], 0)),
7117                               FALSE, operands[0], &offset);
7121 (define_expand "setmemsi"
7122   [(match_operand:BLK 0 "general_operand" "")
7123    (match_operand:SI 1 "const_int_operand" "")
7124    (match_operand:SI 2 "const_int_operand" "")
7125    (match_operand:SI 3 "const_int_operand" "")]
7126   "TARGET_32BIT"
7128   if (arm_gen_setmem (operands))
7129     DONE;
7131   FAIL;
7135 ;; Move a block of memory if it is word aligned and MORE than 2 words long.
7136 ;; We could let this apply for blocks of less than this, but it clobbers so
7137 ;; many registers that there is then probably a better way.
7139 (define_expand "movmemqi"
7140   [(match_operand:BLK 0 "general_operand" "")
7141    (match_operand:BLK 1 "general_operand" "")
7142    (match_operand:SI 2 "const_int_operand" "")
7143    (match_operand:SI 3 "const_int_operand" "")]
7144   ""
7145   "
7146   if (TARGET_32BIT)
7147     {
7148       if (TARGET_LDRD && current_tune->prefer_ldrd_strd
7149           && !optimize_function_for_size_p (cfun))
7150         {
7151           if (gen_movmem_ldrd_strd (operands))
7152             DONE;
7153           FAIL;
7154         }
7156       if (arm_gen_movmemqi (operands))
7157         DONE;
7158       FAIL;
7159     }
7160   else /* TARGET_THUMB1 */
7161     {
7162       if (   INTVAL (operands[3]) != 4
7163           || INTVAL (operands[2]) > 48)
7164         FAIL;
7166       thumb_expand_movmemqi (operands);
7167       DONE;
7168     }
7169   "
7173 ;; Compare & branch insns
7174 ;; The range calculations are based as follows:
7175 ;; For forward branches, the address calculation returns the address of
7176 ;; the next instruction.  This is 2 beyond the branch instruction.
7177 ;; For backward branches, the address calculation returns the address of
7178 ;; the first instruction in this pattern (cmp).  This is 2 before the branch
7179 ;; instruction for the shortest sequence, and 4 before the branch instruction
7180 ;; if we have to jump around an unconditional branch.
7181 ;; To the basic branch range the PC offset must be added (this is +4).
7182 ;; So for forward branches we have 
7183 ;;   (pos_range - pos_base_offs + pc_offs) = (pos_range - 2 + 4).
7184 ;; And for backward branches we have 
7185 ;;   (neg_range - neg_base_offs + pc_offs) = (neg_range - (-2 or -4) + 4).
7187 ;; For a 'b'       pos_range = 2046, neg_range = -2048 giving (-2040->2048).
7188 ;; For a 'b<cond>' pos_range = 254,  neg_range = -256  giving (-250 ->256).
7190 (define_expand "cbranchsi4"
7191   [(set (pc) (if_then_else
7192               (match_operator 0 "expandable_comparison_operator"
7193                [(match_operand:SI 1 "s_register_operand" "")
7194                 (match_operand:SI 2 "nonmemory_operand" "")])
7195               (label_ref (match_operand 3 "" ""))
7196               (pc)))]
7197   "TARGET_EITHER"
7198   "
7199   if (!TARGET_THUMB1)
7200     {
7201       if (!arm_validize_comparison (&operands[0], &operands[1], &operands[2]))
7202         FAIL;
7203       emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
7204                                       operands[3]));
7205       DONE;
7206     }
7207   if (thumb1_cmpneg_operand (operands[2], SImode))
7208     {
7209       emit_jump_insn (gen_cbranchsi4_scratch (NULL, operands[1], operands[2],
7210                                               operands[3], operands[0]));
7211       DONE;
7212     }
7213   if (!thumb1_cmp_operand (operands[2], SImode))
7214     operands[2] = force_reg (SImode, operands[2]);
7215   ")
7217 (define_expand "cbranchsf4"
7218   [(set (pc) (if_then_else
7219               (match_operator 0 "expandable_comparison_operator"
7220                [(match_operand:SF 1 "s_register_operand" "")
7221                 (match_operand:SF 2 "vfp_compare_operand" "")])
7222               (label_ref (match_operand 3 "" ""))
7223               (pc)))]
7224   "TARGET_32BIT && TARGET_HARD_FLOAT"
7225   "emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
7226                                    operands[3])); DONE;"
7229 (define_expand "cbranchdf4"
7230   [(set (pc) (if_then_else
7231               (match_operator 0 "expandable_comparison_operator"
7232                [(match_operand:DF 1 "s_register_operand" "")
7233                 (match_operand:DF 2 "vfp_compare_operand" "")])
7234               (label_ref (match_operand 3 "" ""))
7235               (pc)))]
7236   "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
7237   "emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
7238                                    operands[3])); DONE;"
7241 (define_expand "cbranchdi4"
7242   [(set (pc) (if_then_else
7243               (match_operator 0 "expandable_comparison_operator"
7244                [(match_operand:DI 1 "s_register_operand" "")
7245                 (match_operand:DI 2 "cmpdi_operand" "")])
7246               (label_ref (match_operand 3 "" ""))
7247               (pc)))]
7248   "TARGET_32BIT"
7249   "{
7250      if (!arm_validize_comparison (&operands[0], &operands[1], &operands[2]))
7251        FAIL;
7252      emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
7253                                        operands[3]));
7254      DONE;
7255    }"
7258 ;; Comparison and test insns
7260 (define_insn "*arm_cmpsi_insn"
7261   [(set (reg:CC CC_REGNUM)
7262         (compare:CC (match_operand:SI 0 "s_register_operand" "l,r,r,r,r")
7263                     (match_operand:SI 1 "arm_add_operand"    "Py,r,r,I,L")))]
7264   "TARGET_32BIT"
7265   "@
7266    cmp%?\\t%0, %1
7267    cmp%?\\t%0, %1
7268    cmp%?\\t%0, %1
7269    cmp%?\\t%0, %1
7270    cmn%?\\t%0, #%n1"
7271   [(set_attr "conds" "set")
7272    (set_attr "arch" "t2,t2,any,any,any")
7273    (set_attr "length" "2,2,4,4,4")
7274    (set_attr "predicable" "yes")
7275    (set_attr "predicable_short_it" "yes,yes,yes,no,no")
7276    (set_attr "type" "alus_imm,alus_sreg,alus_sreg,alus_imm,alus_imm")]
7279 (define_insn "*cmpsi_shiftsi"
7280   [(set (reg:CC CC_REGNUM)
7281         (compare:CC (match_operand:SI   0 "s_register_operand" "r,r,r")
7282                     (match_operator:SI  3 "shift_operator"
7283                      [(match_operand:SI 1 "s_register_operand" "r,r,r")
7284                       (match_operand:SI 2 "shift_amount_operand" "M,r,M")])))]
7285   "TARGET_32BIT"
7286   "cmp\\t%0, %1%S3"
7287   [(set_attr "conds" "set")
7288    (set_attr "shift" "1")
7289    (set_attr "arch" "32,a,a")
7290    (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
7292 (define_insn "*cmpsi_shiftsi_swp"
7293   [(set (reg:CC_SWP CC_REGNUM)
7294         (compare:CC_SWP (match_operator:SI 3 "shift_operator"
7295                          [(match_operand:SI 1 "s_register_operand" "r,r,r")
7296                           (match_operand:SI 2 "shift_amount_operand" "M,r,M")])
7297                         (match_operand:SI 0 "s_register_operand" "r,r,r")))]
7298   "TARGET_32BIT"
7299   "cmp%?\\t%0, %1%S3"
7300   [(set_attr "conds" "set")
7301    (set_attr "shift" "1")
7302    (set_attr "arch" "32,a,a")
7303    (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
7305 (define_insn "*arm_cmpsi_negshiftsi_si"
7306   [(set (reg:CC_Z CC_REGNUM)
7307         (compare:CC_Z
7308          (neg:SI (match_operator:SI 1 "shift_operator"
7309                     [(match_operand:SI 2 "s_register_operand" "r")
7310                      (match_operand:SI 3 "reg_or_int_operand" "rM")]))
7311          (match_operand:SI 0 "s_register_operand" "r")))]
7312   "TARGET_ARM"
7313   "cmn%?\\t%0, %2%S1"
7314   [(set_attr "conds" "set")
7315    (set (attr "type") (if_then_else (match_operand 3 "const_int_operand" "")
7316                                     (const_string "alus_shift_imm")
7317                                     (const_string "alus_shift_reg")))
7318    (set_attr "predicable" "yes")]
7321 ;; DImode comparisons.  The generic code generates branches that
7322 ;; if-conversion can not reduce to a conditional compare, so we do
7323 ;; that directly.
7325 (define_insn_and_split "*arm_cmpdi_insn"
7326   [(set (reg:CC_NCV CC_REGNUM)
7327         (compare:CC_NCV (match_operand:DI 0 "s_register_operand" "r")
7328                         (match_operand:DI 1 "arm_di_operand"       "rDi")))
7329    (clobber (match_scratch:SI 2 "=r"))]
7330   "TARGET_32BIT"
7331   "#"   ; "cmp\\t%Q0, %Q1\;sbcs\\t%2, %R0, %R1"
7332   "&& reload_completed"
7333   [(set (reg:CC CC_REGNUM)
7334         (compare:CC (match_dup 0) (match_dup 1)))
7335    (parallel [(set (reg:CC CC_REGNUM)
7336                    (compare:CC (match_dup 3) (match_dup 4)))
7337               (set (match_dup 2)
7338                    (minus:SI (match_dup 5)
7339                             (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))])]
7340   {
7341     operands[3] = gen_highpart (SImode, operands[0]);
7342     operands[0] = gen_lowpart (SImode, operands[0]);
7343     if (CONST_INT_P (operands[1]))
7344       {
7345         operands[4] = GEN_INT (~INTVAL (gen_highpart_mode (SImode,
7346                                                            DImode,
7347                                                            operands[1])));
7348         operands[5] = gen_rtx_PLUS (SImode, operands[3], operands[4]);
7349       }
7350     else
7351       {
7352         operands[4] = gen_highpart (SImode, operands[1]);
7353         operands[5] = gen_rtx_MINUS (SImode, operands[3], operands[4]);
7354       }
7355     operands[1] = gen_lowpart (SImode, operands[1]);
7356     operands[2] = gen_lowpart (SImode, operands[2]);
7357   }
7358   [(set_attr "conds" "set")
7359    (set_attr "length" "8")
7360    (set_attr "type" "multiple")]
7363 (define_insn_and_split "*arm_cmpdi_unsigned"
7364   [(set (reg:CC_CZ CC_REGNUM)
7365         (compare:CC_CZ (match_operand:DI 0 "s_register_operand" "l,r,r,r")
7366                        (match_operand:DI 1 "arm_di_operand"     "Py,r,Di,rDi")))]
7368   "TARGET_32BIT"
7369   "#"   ; "cmp\\t%R0, %R1\;it eq\;cmpeq\\t%Q0, %Q1"
7370   "&& reload_completed"
7371   [(set (reg:CC CC_REGNUM)
7372         (compare:CC (match_dup 2) (match_dup 3)))
7373    (cond_exec (eq:SI (reg:CC CC_REGNUM) (const_int 0))
7374               (set (reg:CC CC_REGNUM)
7375                    (compare:CC (match_dup 0) (match_dup 1))))]
7376   {
7377     operands[2] = gen_highpart (SImode, operands[0]);
7378     operands[0] = gen_lowpart (SImode, operands[0]);
7379     if (CONST_INT_P (operands[1]))
7380       operands[3] = gen_highpart_mode (SImode, DImode, operands[1]);
7381     else
7382       operands[3] = gen_highpart (SImode, operands[1]);
7383     operands[1] = gen_lowpart (SImode, operands[1]);
7384   }
7385   [(set_attr "conds" "set")
7386    (set_attr "enabled_for_depr_it" "yes,yes,no,*")
7387    (set_attr "arch" "t2,t2,t2,a")
7388    (set_attr "length" "6,6,10,8")
7389    (set_attr "type" "multiple")]
7392 (define_insn "*arm_cmpdi_zero"
7393   [(set (reg:CC_Z CC_REGNUM)
7394         (compare:CC_Z (match_operand:DI 0 "s_register_operand" "r")
7395                       (const_int 0)))
7396    (clobber (match_scratch:SI 1 "=r"))]
7397   "TARGET_32BIT"
7398   "orrs%?\\t%1, %Q0, %R0"
7399   [(set_attr "conds" "set")
7400    (set_attr "type" "logics_reg")]
7403 ; This insn allows redundant compares to be removed by cse, nothing should
7404 ; ever appear in the output file since (set (reg x) (reg x)) is a no-op that
7405 ; is deleted later on. The match_dup will match the mode here, so that
7406 ; mode changes of the condition codes aren't lost by this even though we don't
7407 ; specify what they are.
7409 (define_insn "*deleted_compare"
7410   [(set (match_operand 0 "cc_register" "") (match_dup 0))]
7411   "TARGET_32BIT"
7412   "\\t%@ deleted compare"
7413   [(set_attr "conds" "set")
7414    (set_attr "length" "0")
7415    (set_attr "type" "no_insn")]
7419 ;; Conditional branch insns
7421 (define_expand "cbranch_cc"
7422   [(set (pc)
7423         (if_then_else (match_operator 0 "" [(match_operand 1 "" "")
7424                                             (match_operand 2 "" "")])
7425                       (label_ref (match_operand 3 "" ""))
7426                       (pc)))]
7427   "TARGET_32BIT"
7428   "operands[1] = arm_gen_compare_reg (GET_CODE (operands[0]),
7429                                       operands[1], operands[2], NULL_RTX);
7430    operands[2] = const0_rtx;"
7434 ;; Patterns to match conditional branch insns.
7437 (define_insn "arm_cond_branch"
7438   [(set (pc)
7439         (if_then_else (match_operator 1 "arm_comparison_operator"
7440                        [(match_operand 2 "cc_register" "") (const_int 0)])
7441                       (label_ref (match_operand 0 "" ""))
7442                       (pc)))]
7443   "TARGET_32BIT"
7444   "*
7445   if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
7446     {
7447       arm_ccfsm_state += 2;
7448       return \"\";
7449     }
7450   return \"b%d1\\t%l0\";
7451   "
7452   [(set_attr "conds" "use")
7453    (set_attr "type" "branch")
7454    (set (attr "length")
7455         (if_then_else
7456            (and (match_test "TARGET_THUMB2")
7457                 (and (ge (minus (match_dup 0) (pc)) (const_int -250))
7458                      (le (minus (match_dup 0) (pc)) (const_int 256))))
7459            (const_int 2)
7460            (const_int 4)))]
7463 (define_insn "*arm_cond_branch_reversed"
7464   [(set (pc)
7465         (if_then_else (match_operator 1 "arm_comparison_operator"
7466                        [(match_operand 2 "cc_register" "") (const_int 0)])
7467                       (pc)
7468                       (label_ref (match_operand 0 "" ""))))]
7469   "TARGET_32BIT"
7470   "*
7471   if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
7472     {
7473       arm_ccfsm_state += 2;
7474       return \"\";
7475     }
7476   return \"b%D1\\t%l0\";
7477   "
7478   [(set_attr "conds" "use")
7479    (set_attr "type" "branch")
7480    (set (attr "length")
7481         (if_then_else
7482            (and (match_test "TARGET_THUMB2")
7483                 (and (ge (minus (match_dup 0) (pc)) (const_int -250))
7484                      (le (minus (match_dup 0) (pc)) (const_int 256))))
7485            (const_int 2)
7486            (const_int 4)))]
7491 ; scc insns
7493 (define_expand "cstore_cc"
7494   [(set (match_operand:SI 0 "s_register_operand" "")
7495         (match_operator:SI 1 "" [(match_operand 2 "" "")
7496                                  (match_operand 3 "" "")]))]
7497   "TARGET_32BIT"
7498   "operands[2] = arm_gen_compare_reg (GET_CODE (operands[1]),
7499                                       operands[2], operands[3], NULL_RTX);
7500    operands[3] = const0_rtx;"
7503 (define_insn_and_split "*mov_scc"
7504   [(set (match_operand:SI 0 "s_register_operand" "=r")
7505         (match_operator:SI 1 "arm_comparison_operator_mode"
7506          [(match_operand 2 "cc_register" "") (const_int 0)]))]
7507   "TARGET_ARM"
7508   "#"   ; "mov%D1\\t%0, #0\;mov%d1\\t%0, #1"
7509   "TARGET_ARM"
7510   [(set (match_dup 0)
7511         (if_then_else:SI (match_dup 1)
7512                          (const_int 1)
7513                          (const_int 0)))]
7514   ""
7515   [(set_attr "conds" "use")
7516    (set_attr "length" "8")
7517    (set_attr "type" "multiple")]
7520 (define_insn_and_split "*mov_negscc"
7521   [(set (match_operand:SI 0 "s_register_operand" "=r")
7522         (neg:SI (match_operator:SI 1 "arm_comparison_operator_mode"
7523                  [(match_operand 2 "cc_register" "") (const_int 0)])))]
7524   "TARGET_ARM"
7525   "#"   ; "mov%D1\\t%0, #0\;mvn%d1\\t%0, #0"
7526   "TARGET_ARM"
7527   [(set (match_dup 0)
7528         (if_then_else:SI (match_dup 1)
7529                          (match_dup 3)
7530                          (const_int 0)))]
7531   {
7532     operands[3] = GEN_INT (~0);
7533   }
7534   [(set_attr "conds" "use")
7535    (set_attr "length" "8")
7536    (set_attr "type" "multiple")]
7539 (define_insn_and_split "*mov_notscc"
7540   [(set (match_operand:SI 0 "s_register_operand" "=r")
7541         (not:SI (match_operator:SI 1 "arm_comparison_operator"
7542                  [(match_operand 2 "cc_register" "") (const_int 0)])))]
7543   "TARGET_ARM"
7544   "#"   ; "mvn%D1\\t%0, #0\;mvn%d1\\t%0, #1"
7545   "TARGET_ARM"
7546   [(set (match_dup 0)
7547         (if_then_else:SI (match_dup 1)
7548                          (match_dup 3)
7549                          (match_dup 4)))]
7550   {
7551     operands[3] = GEN_INT (~1);
7552     operands[4] = GEN_INT (~0);
7553   }
7554   [(set_attr "conds" "use")
7555    (set_attr "length" "8")
7556    (set_attr "type" "multiple")]
7559 (define_expand "cstoresi4"
7560   [(set (match_operand:SI 0 "s_register_operand" "")
7561         (match_operator:SI 1 "expandable_comparison_operator"
7562          [(match_operand:SI 2 "s_register_operand" "")
7563           (match_operand:SI 3 "reg_or_int_operand" "")]))]
7564   "TARGET_32BIT || TARGET_THUMB1"
7565   "{
7566   rtx op3, scratch, scratch2;
7568   if (!TARGET_THUMB1)
7569     {
7570       if (!arm_add_operand (operands[3], SImode))
7571         operands[3] = force_reg (SImode, operands[3]);
7572       emit_insn (gen_cstore_cc (operands[0], operands[1],
7573                                 operands[2], operands[3]));
7574       DONE;
7575     }
7577   if (operands[3] == const0_rtx)
7578     {
7579       switch (GET_CODE (operands[1]))
7580         {
7581         case EQ:
7582           emit_insn (gen_cstoresi_eq0_thumb1 (operands[0], operands[2]));
7583           break;
7585         case NE:
7586           emit_insn (gen_cstoresi_ne0_thumb1 (operands[0], operands[2]));
7587           break;
7589         case LE:
7590           scratch = expand_binop (SImode, add_optab, operands[2], constm1_rtx,
7591                                   NULL_RTX, 0, OPTAB_WIDEN);
7592           scratch = expand_binop (SImode, ior_optab, operands[2], scratch,
7593                                   NULL_RTX, 0, OPTAB_WIDEN);
7594           expand_binop (SImode, lshr_optab, scratch, GEN_INT (31),
7595                         operands[0], 1, OPTAB_WIDEN);
7596           break;
7598         case GE:
7599           scratch = expand_unop (SImode, one_cmpl_optab, operands[2],
7600                                  NULL_RTX, 1);
7601           expand_binop (SImode, lshr_optab, scratch, GEN_INT (31),
7602                         NULL_RTX, 1, OPTAB_WIDEN);
7603           break;
7605         case GT:
7606           scratch = expand_binop (SImode, ashr_optab, operands[2],
7607                                   GEN_INT (31), NULL_RTX, 0, OPTAB_WIDEN);
7608           scratch = expand_binop (SImode, sub_optab, scratch, operands[2],
7609                                   NULL_RTX, 0, OPTAB_WIDEN);
7610           expand_binop (SImode, lshr_optab, scratch, GEN_INT (31), operands[0],
7611                         0, OPTAB_WIDEN);
7612           break;
7614         /* LT is handled by generic code.  No need for unsigned with 0.  */
7615         default:
7616           FAIL;
7617         }
7618       DONE;
7619     }
7621   switch (GET_CODE (operands[1]))
7622     {
7623     case EQ:
7624       scratch = expand_binop (SImode, sub_optab, operands[2], operands[3],
7625                               NULL_RTX, 0, OPTAB_WIDEN);
7626       emit_insn (gen_cstoresi_eq0_thumb1 (operands[0], scratch));
7627       break;
7629     case NE:
7630       scratch = expand_binop (SImode, sub_optab, operands[2], operands[3],
7631                               NULL_RTX, 0, OPTAB_WIDEN);
7632       emit_insn (gen_cstoresi_ne0_thumb1 (operands[0], scratch));
7633       break;
7635     case LE:
7636       op3 = force_reg (SImode, operands[3]);
7638       scratch = expand_binop (SImode, lshr_optab, operands[2], GEN_INT (31),
7639                               NULL_RTX, 1, OPTAB_WIDEN);
7640       scratch2 = expand_binop (SImode, ashr_optab, op3, GEN_INT (31),
7641                               NULL_RTX, 0, OPTAB_WIDEN);
7642       emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch2,
7643                                           op3, operands[2]));
7644       break;
7646     case GE:
7647       op3 = operands[3];
7648       if (!thumb1_cmp_operand (op3, SImode))
7649         op3 = force_reg (SImode, op3);
7650       scratch = expand_binop (SImode, ashr_optab, operands[2], GEN_INT (31),
7651                               NULL_RTX, 0, OPTAB_WIDEN);
7652       scratch2 = expand_binop (SImode, lshr_optab, op3, GEN_INT (31),
7653                                NULL_RTX, 1, OPTAB_WIDEN);
7654       emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch2,
7655                                           operands[2], op3));
7656       break;
7658     case LEU:
7659       op3 = force_reg (SImode, operands[3]);
7660       scratch = force_reg (SImode, const0_rtx);
7661       emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch,
7662                                           op3, operands[2]));
7663       break;
7665     case GEU:
7666       op3 = operands[3];
7667       if (!thumb1_cmp_operand (op3, SImode))
7668         op3 = force_reg (SImode, op3);
7669       scratch = force_reg (SImode, const0_rtx);
7670       emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch,
7671                                           operands[2], op3));
7672       break;
7674     case LTU:
7675       op3 = operands[3];
7676       if (!thumb1_cmp_operand (op3, SImode))
7677         op3 = force_reg (SImode, op3);
7678       scratch = gen_reg_rtx (SImode);
7679       emit_insn (gen_cstoresi_ltu_thumb1 (operands[0], operands[2], op3));
7680       break;
7682     case GTU:
7683       op3 = force_reg (SImode, operands[3]);
7684       scratch = gen_reg_rtx (SImode);
7685       emit_insn (gen_cstoresi_ltu_thumb1 (operands[0], op3, operands[2]));
7686       break;
7688     /* No good sequences for GT, LT.  */
7689     default:
7690       FAIL;
7691     }
7692   DONE;
7695 (define_expand "cstorehf4"
7696   [(set (match_operand:SI 0 "s_register_operand")
7697         (match_operator:SI 1 "expandable_comparison_operator"
7698          [(match_operand:HF 2 "s_register_operand")
7699           (match_operand:HF 3 "vfp_compare_operand")]))]
7700   "TARGET_VFP_FP16INST"
7701   {
7702     if (!arm_validize_comparison (&operands[1],
7703                                   &operands[2],
7704                                   &operands[3]))
7705        FAIL;
7707     emit_insn (gen_cstore_cc (operands[0], operands[1],
7708                               operands[2], operands[3]));
7709     DONE;
7710   }
7713 (define_expand "cstoresf4"
7714   [(set (match_operand:SI 0 "s_register_operand" "")
7715         (match_operator:SI 1 "expandable_comparison_operator"
7716          [(match_operand:SF 2 "s_register_operand" "")
7717           (match_operand:SF 3 "vfp_compare_operand" "")]))]
7718   "TARGET_32BIT && TARGET_HARD_FLOAT"
7719   "emit_insn (gen_cstore_cc (operands[0], operands[1],
7720                              operands[2], operands[3])); DONE;"
7723 (define_expand "cstoredf4"
7724   [(set (match_operand:SI 0 "s_register_operand" "")
7725         (match_operator:SI 1 "expandable_comparison_operator"
7726          [(match_operand:DF 2 "s_register_operand" "")
7727           (match_operand:DF 3 "vfp_compare_operand" "")]))]
7728   "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
7729   "emit_insn (gen_cstore_cc (operands[0], operands[1],
7730                              operands[2], operands[3])); DONE;"
7733 (define_expand "cstoredi4"
7734   [(set (match_operand:SI 0 "s_register_operand" "")
7735         (match_operator:SI 1 "expandable_comparison_operator"
7736          [(match_operand:DI 2 "s_register_operand" "")
7737           (match_operand:DI 3 "cmpdi_operand" "")]))]
7738   "TARGET_32BIT"
7739   "{
7740      if (!arm_validize_comparison (&operands[1],
7741                                    &operands[2],
7742                                    &operands[3]))
7743        FAIL;
7744      emit_insn (gen_cstore_cc (operands[0], operands[1], operands[2],
7745                                  operands[3]));
7746      DONE;
7747    }"
7751 ;; Conditional move insns
7753 (define_expand "movsicc"
7754   [(set (match_operand:SI 0 "s_register_operand" "")
7755         (if_then_else:SI (match_operand 1 "expandable_comparison_operator" "")
7756                          (match_operand:SI 2 "arm_not_operand" "")
7757                          (match_operand:SI 3 "arm_not_operand" "")))]
7758   "TARGET_32BIT"
7759   "
7760   {
7761     enum rtx_code code;
7762     rtx ccreg;
7764     if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0), 
7765                                   &XEXP (operands[1], 1)))
7766       FAIL;
7768     code = GET_CODE (operands[1]);
7769     ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
7770                                  XEXP (operands[1], 1), NULL_RTX);
7771     operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7772   }"
7775 (define_expand "movhfcc"
7776   [(set (match_operand:HF 0 "s_register_operand")
7777         (if_then_else:HF (match_operand 1 "arm_cond_move_operator")
7778                          (match_operand:HF 2 "s_register_operand")
7779                          (match_operand:HF 3 "s_register_operand")))]
7780   "TARGET_VFP_FP16INST"
7781   "
7782   {
7783     enum rtx_code code = GET_CODE (operands[1]);
7784     rtx ccreg;
7786     if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
7787                                   &XEXP (operands[1], 1)))
7788       FAIL;
7790     code = GET_CODE (operands[1]);
7791     ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
7792                                  XEXP (operands[1], 1), NULL_RTX);
7793     operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7794   }"
7797 (define_expand "movsfcc"
7798   [(set (match_operand:SF 0 "s_register_operand" "")
7799         (if_then_else:SF (match_operand 1 "arm_cond_move_operator" "")
7800                          (match_operand:SF 2 "s_register_operand" "")
7801                          (match_operand:SF 3 "s_register_operand" "")))]
7802   "TARGET_32BIT && TARGET_HARD_FLOAT"
7803   "
7804   {
7805     enum rtx_code code = GET_CODE (operands[1]);
7806     rtx ccreg;
7808     if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
7809                                   &XEXP (operands[1], 1)))
7810        FAIL;
7812     code = GET_CODE (operands[1]);
7813     ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
7814                                  XEXP (operands[1], 1), NULL_RTX);
7815     operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7816   }"
7819 (define_expand "movdfcc"
7820   [(set (match_operand:DF 0 "s_register_operand" "")
7821         (if_then_else:DF (match_operand 1 "arm_cond_move_operator" "")
7822                          (match_operand:DF 2 "s_register_operand" "")
7823                          (match_operand:DF 3 "s_register_operand" "")))]
7824   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
7825   "
7826   {
7827     enum rtx_code code = GET_CODE (operands[1]);
7828     rtx ccreg;
7830     if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0), 
7831                                   &XEXP (operands[1], 1)))
7832        FAIL;
7833     code = GET_CODE (operands[1]);
7834     ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
7835                                  XEXP (operands[1], 1), NULL_RTX);
7836     operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7837   }"
7840 (define_insn "*cmov<mode>"
7841     [(set (match_operand:SDF 0 "s_register_operand" "=<F_constraint>")
7842         (if_then_else:SDF (match_operator 1 "arm_vsel_comparison_operator"
7843                           [(match_operand 2 "cc_register" "") (const_int 0)])
7844                           (match_operand:SDF 3 "s_register_operand"
7845                                               "<F_constraint>")
7846                           (match_operand:SDF 4 "s_register_operand"
7847                                               "<F_constraint>")))]
7848   "TARGET_HARD_FLOAT && TARGET_FPU_ARMV8 <vfp_double_cond>"
7849   "*
7850   {
7851     enum arm_cond_code code = maybe_get_arm_condition_code (operands[1]);
7852     switch (code)
7853       {
7854       case ARM_GE:
7855       case ARM_GT:
7856       case ARM_EQ:
7857       case ARM_VS:
7858         return \"vsel%d1.<V_if_elem>\\t%<V_reg>0, %<V_reg>3, %<V_reg>4\";
7859       case ARM_LT:
7860       case ARM_LE:
7861       case ARM_NE:
7862       case ARM_VC:
7863         return \"vsel%D1.<V_if_elem>\\t%<V_reg>0, %<V_reg>4, %<V_reg>3\";
7864       default:
7865         gcc_unreachable ();
7866       }
7867     return \"\";
7868   }"
7869   [(set_attr "conds" "use")
7870    (set_attr "type" "fcsel")]
7873 (define_insn "*cmovhf"
7874     [(set (match_operand:HF 0 "s_register_operand" "=t")
7875         (if_then_else:HF (match_operator 1 "arm_vsel_comparison_operator"
7876                          [(match_operand 2 "cc_register" "") (const_int 0)])
7877                           (match_operand:HF 3 "s_register_operand" "t")
7878                           (match_operand:HF 4 "s_register_operand" "t")))]
7879   "TARGET_VFP_FP16INST"
7880   "*
7881   {
7882     enum arm_cond_code code = maybe_get_arm_condition_code (operands[1]);
7883     switch (code)
7884       {
7885       case ARM_GE:
7886       case ARM_GT:
7887       case ARM_EQ:
7888       case ARM_VS:
7889         return \"vsel%d1.f16\\t%0, %3, %4\";
7890       case ARM_LT:
7891       case ARM_LE:
7892       case ARM_NE:
7893       case ARM_VC:
7894         return \"vsel%D1.f16\\t%0, %4, %3\";
7895       default:
7896         gcc_unreachable ();
7897       }
7898     return \"\";
7899   }"
7900   [(set_attr "conds" "use")
7901    (set_attr "type" "fcsel")]
7904 (define_insn_and_split "*movsicc_insn"
7905   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r,r,r,r,r")
7906         (if_then_else:SI
7907          (match_operator 3 "arm_comparison_operator"
7908           [(match_operand 4 "cc_register" "") (const_int 0)])
7909          (match_operand:SI 1 "arm_not_operand" "0,0,rI,K,rI,rI,K,K")
7910          (match_operand:SI 2 "arm_not_operand" "rI,K,0,0,rI,K,rI,K")))]
7911   "TARGET_ARM"
7912   "@
7913    mov%D3\\t%0, %2
7914    mvn%D3\\t%0, #%B2
7915    mov%d3\\t%0, %1
7916    mvn%d3\\t%0, #%B1
7917    #
7918    #
7919    #
7920    #"
7921    ; alt4: mov%d3\\t%0, %1\;mov%D3\\t%0, %2
7922    ; alt5: mov%d3\\t%0, %1\;mvn%D3\\t%0, #%B2
7923    ; alt6: mvn%d3\\t%0, #%B1\;mov%D3\\t%0, %2
7924    ; alt7: mvn%d3\\t%0, #%B1\;mvn%D3\\t%0, #%B2"
7925   "&& reload_completed"
7926   [(const_int 0)]
7927   {
7928     enum rtx_code rev_code;
7929     machine_mode mode;
7930     rtx rev_cond;
7932     emit_insn (gen_rtx_COND_EXEC (VOIDmode,
7933                                   operands[3],
7934                                   gen_rtx_SET (operands[0], operands[1])));
7936     rev_code = GET_CODE (operands[3]);
7937     mode = GET_MODE (operands[4]);
7938     if (mode == CCFPmode || mode == CCFPEmode)
7939       rev_code = reverse_condition_maybe_unordered (rev_code);
7940     else
7941       rev_code = reverse_condition (rev_code);
7943     rev_cond = gen_rtx_fmt_ee (rev_code,
7944                                VOIDmode,
7945                                operands[4],
7946                                const0_rtx);
7947     emit_insn (gen_rtx_COND_EXEC (VOIDmode,
7948                                   rev_cond,
7949                                   gen_rtx_SET (operands[0], operands[2])));
7950     DONE;
7951   }
7952   [(set_attr "length" "4,4,4,4,8,8,8,8")
7953    (set_attr "conds" "use")
7954    (set_attr_alternative "type"
7955                          [(if_then_else (match_operand 2 "const_int_operand" "")
7956                                         (const_string "mov_imm")
7957                                         (const_string "mov_reg"))
7958                           (const_string "mvn_imm")
7959                           (if_then_else (match_operand 1 "const_int_operand" "")
7960                                         (const_string "mov_imm")
7961                                         (const_string "mov_reg"))
7962                           (const_string "mvn_imm")
7963                           (const_string "multiple")
7964                           (const_string "multiple")
7965                           (const_string "multiple")
7966                           (const_string "multiple")])]
7969 (define_insn "*movsfcc_soft_insn"
7970   [(set (match_operand:SF 0 "s_register_operand" "=r,r")
7971         (if_then_else:SF (match_operator 3 "arm_comparison_operator"
7972                           [(match_operand 4 "cc_register" "") (const_int 0)])
7973                          (match_operand:SF 1 "s_register_operand" "0,r")
7974                          (match_operand:SF 2 "s_register_operand" "r,0")))]
7975   "TARGET_ARM && TARGET_SOFT_FLOAT"
7976   "@
7977    mov%D3\\t%0, %2
7978    mov%d3\\t%0, %1"
7979   [(set_attr "conds" "use")
7980    (set_attr "type" "mov_reg")]
7984 ;; Jump and linkage insns
7986 (define_expand "jump"
7987   [(set (pc)
7988         (label_ref (match_operand 0 "" "")))]
7989   "TARGET_EITHER"
7990   ""
7993 (define_insn "*arm_jump"
7994   [(set (pc)
7995         (label_ref (match_operand 0 "" "")))]
7996   "TARGET_32BIT"
7997   "*
7998   {
7999     if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
8000       {
8001         arm_ccfsm_state += 2;
8002         return \"\";
8003       }
8004     return \"b%?\\t%l0\";
8005   }
8006   "
8007   [(set_attr "predicable" "yes")
8008    (set (attr "length")
8009         (if_then_else
8010            (and (match_test "TARGET_THUMB2")
8011                 (and (ge (minus (match_dup 0) (pc)) (const_int -2044))
8012                      (le (minus (match_dup 0) (pc)) (const_int 2048))))
8013            (const_int 2)
8014            (const_int 4)))
8015    (set_attr "type" "branch")]
8018 (define_expand "call"
8019   [(parallel [(call (match_operand 0 "memory_operand" "")
8020                     (match_operand 1 "general_operand" ""))
8021               (use (match_operand 2 "" ""))
8022               (clobber (reg:SI LR_REGNUM))])]
8023   "TARGET_EITHER"
8024   "
8025   {
8026     rtx callee, pat;
8027     
8028     /* In an untyped call, we can get NULL for operand 2.  */
8029     if (operands[2] == NULL_RTX)
8030       operands[2] = const0_rtx;
8031       
8032     /* Decide if we should generate indirect calls by loading the
8033        32-bit address of the callee into a register before performing the
8034        branch and link.  */
8035     callee = XEXP (operands[0], 0);
8036     if (GET_CODE (callee) == SYMBOL_REF
8037         ? arm_is_long_call_p (SYMBOL_REF_DECL (callee))
8038         : !REG_P (callee))
8039       XEXP (operands[0], 0) = force_reg (Pmode, callee);
8041     pat = gen_call_internal (operands[0], operands[1], operands[2]);
8042     arm_emit_call_insn (pat, XEXP (operands[0], 0), false);
8043     DONE;
8044   }"
8047 (define_expand "call_internal"
8048   [(parallel [(call (match_operand 0 "memory_operand" "")
8049                     (match_operand 1 "general_operand" ""))
8050               (use (match_operand 2 "" ""))
8051               (clobber (reg:SI LR_REGNUM))])])
8053 (define_insn "*call_reg_armv5"
8054   [(call (mem:SI (match_operand:SI 0 "s_register_operand" "r"))
8055          (match_operand 1 "" ""))
8056    (use (match_operand 2 "" ""))
8057    (clobber (reg:SI LR_REGNUM))]
8058   "TARGET_ARM && arm_arch5 && !SIBLING_CALL_P (insn)"
8059   "blx%?\\t%0"
8060   [(set_attr "type" "call")]
8063 (define_insn "*call_reg_arm"
8064   [(call (mem:SI (match_operand:SI 0 "s_register_operand" "r"))
8065          (match_operand 1 "" ""))
8066    (use (match_operand 2 "" ""))
8067    (clobber (reg:SI LR_REGNUM))]
8068   "TARGET_ARM && !arm_arch5 && !SIBLING_CALL_P (insn)"
8069   "*
8070   return output_call (operands);
8071   "
8072   ;; length is worst case, normally it is only two
8073   [(set_attr "length" "12")
8074    (set_attr "type" "call")]
8078 (define_expand "call_value"
8079   [(parallel [(set (match_operand       0 "" "")
8080                    (call (match_operand 1 "memory_operand" "")
8081                          (match_operand 2 "general_operand" "")))
8082               (use (match_operand 3 "" ""))
8083               (clobber (reg:SI LR_REGNUM))])]
8084   "TARGET_EITHER"
8085   "
8086   {
8087     rtx pat, callee;
8088     
8089     /* In an untyped call, we can get NULL for operand 2.  */
8090     if (operands[3] == 0)
8091       operands[3] = const0_rtx;
8092       
8093     /* Decide if we should generate indirect calls by loading the
8094        32-bit address of the callee into a register before performing the
8095        branch and link.  */
8096     callee = XEXP (operands[1], 0);
8097     if (GET_CODE (callee) == SYMBOL_REF
8098         ? arm_is_long_call_p (SYMBOL_REF_DECL (callee))
8099         : !REG_P (callee))
8100       XEXP (operands[1], 0) = force_reg (Pmode, callee);
8102     pat = gen_call_value_internal (operands[0], operands[1],
8103                                    operands[2], operands[3]);
8104     arm_emit_call_insn (pat, XEXP (operands[1], 0), false);
8105     DONE;
8106   }"
8109 (define_expand "call_value_internal"
8110   [(parallel [(set (match_operand       0 "" "")
8111                    (call (match_operand 1 "memory_operand" "")
8112                          (match_operand 2 "general_operand" "")))
8113               (use (match_operand 3 "" ""))
8114               (clobber (reg:SI LR_REGNUM))])])
8116 (define_insn "*call_value_reg_armv5"
8117   [(set (match_operand 0 "" "")
8118         (call (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
8119               (match_operand 2 "" "")))
8120    (use (match_operand 3 "" ""))
8121    (clobber (reg:SI LR_REGNUM))]
8122   "TARGET_ARM && arm_arch5 && !SIBLING_CALL_P (insn)"
8123   "blx%?\\t%1"
8124   [(set_attr "type" "call")]
8127 (define_insn "*call_value_reg_arm"
8128   [(set (match_operand 0 "" "")
8129         (call (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
8130               (match_operand 2 "" "")))
8131    (use (match_operand 3 "" ""))
8132    (clobber (reg:SI LR_REGNUM))]
8133   "TARGET_ARM && !arm_arch5 && !SIBLING_CALL_P (insn)"
8134   "*
8135   return output_call (&operands[1]);
8136   "
8137   [(set_attr "length" "12")
8138    (set_attr "type" "call")]
8141 ;; Allow calls to SYMBOL_REFs specially as they are not valid general addresses
8142 ;; The 'a' causes the operand to be treated as an address, i.e. no '#' output.
8144 (define_insn "*call_symbol"
8145   [(call (mem:SI (match_operand:SI 0 "" ""))
8146          (match_operand 1 "" ""))
8147    (use (match_operand 2 "" ""))
8148    (clobber (reg:SI LR_REGNUM))]
8149   "TARGET_32BIT
8150    && !SIBLING_CALL_P (insn)
8151    && (GET_CODE (operands[0]) == SYMBOL_REF)
8152    && !arm_is_long_call_p (SYMBOL_REF_DECL (operands[0]))"
8153   "*
8154   {
8155    rtx op = operands[0];
8157    /* Switch mode now when possible.  */
8158    if (SYMBOL_REF_DECL (op) && !TREE_PUBLIC (SYMBOL_REF_DECL (op))
8159         && arm_arch5 && arm_change_mode_p (SYMBOL_REF_DECL (op)))
8160       return NEED_PLT_RELOC ? \"blx%?\\t%a0(PLT)\" : \"blx%?\\t(%a0)\";
8162     return NEED_PLT_RELOC ? \"bl%?\\t%a0(PLT)\" : \"bl%?\\t%a0\";
8163   }"
8164   [(set_attr "type" "call")]
8167 (define_insn "*call_value_symbol"
8168   [(set (match_operand 0 "" "")
8169         (call (mem:SI (match_operand:SI 1 "" ""))
8170         (match_operand:SI 2 "" "")))
8171    (use (match_operand 3 "" ""))
8172    (clobber (reg:SI LR_REGNUM))]
8173   "TARGET_32BIT
8174    && !SIBLING_CALL_P (insn)
8175    && (GET_CODE (operands[1]) == SYMBOL_REF)
8176    && !arm_is_long_call_p (SYMBOL_REF_DECL (operands[1]))"
8177   "*
8178   {
8179    rtx op = operands[1];
8181    /* Switch mode now when possible.  */
8182    if (SYMBOL_REF_DECL (op) && !TREE_PUBLIC (SYMBOL_REF_DECL (op))
8183         && arm_arch5 && arm_change_mode_p (SYMBOL_REF_DECL (op)))
8184       return NEED_PLT_RELOC ? \"blx%?\\t%a1(PLT)\" : \"blx%?\\t(%a1)\";
8186     return NEED_PLT_RELOC ? \"bl%?\\t%a1(PLT)\" : \"bl%?\\t%a1\";
8187   }"
8188   [(set_attr "type" "call")]
8191 (define_expand "sibcall_internal"
8192   [(parallel [(call (match_operand 0 "memory_operand" "")
8193                     (match_operand 1 "general_operand" ""))
8194               (return)
8195               (use (match_operand 2 "" ""))])])
8197 ;; We may also be able to do sibcalls for Thumb, but it's much harder...
8198 (define_expand "sibcall"
8199   [(parallel [(call (match_operand 0 "memory_operand" "")
8200                     (match_operand 1 "general_operand" ""))
8201               (return)
8202               (use (match_operand 2 "" ""))])]
8203   "TARGET_32BIT"
8204   "
8205   {
8206     rtx pat;
8208     if ((!REG_P (XEXP (operands[0], 0))
8209          && GET_CODE (XEXP (operands[0], 0)) != SYMBOL_REF)
8210         || (GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
8211             && arm_is_long_call_p (SYMBOL_REF_DECL (XEXP (operands[0], 0)))))
8212      XEXP (operands[0], 0) = force_reg (SImode, XEXP (operands[0], 0));
8214     if (operands[2] == NULL_RTX)
8215       operands[2] = const0_rtx;
8217     pat = gen_sibcall_internal (operands[0], operands[1], operands[2]);
8218     arm_emit_call_insn (pat, operands[0], true);
8219     DONE;
8220   }"
8223 (define_expand "sibcall_value_internal"
8224   [(parallel [(set (match_operand 0 "" "")
8225                    (call (match_operand 1 "memory_operand" "")
8226                          (match_operand 2 "general_operand" "")))
8227               (return)
8228               (use (match_operand 3 "" ""))])])
8230 (define_expand "sibcall_value"
8231   [(parallel [(set (match_operand 0 "" "")
8232                    (call (match_operand 1 "memory_operand" "")
8233                          (match_operand 2 "general_operand" "")))
8234               (return)
8235               (use (match_operand 3 "" ""))])]
8236   "TARGET_32BIT"
8237   "
8238   {
8239     rtx pat;
8241     if ((!REG_P (XEXP (operands[1], 0))
8242          && GET_CODE (XEXP (operands[1], 0)) != SYMBOL_REF)
8243         || (GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
8244             && arm_is_long_call_p (SYMBOL_REF_DECL (XEXP (operands[1], 0)))))
8245      XEXP (operands[1], 0) = force_reg (SImode, XEXP (operands[1], 0));
8247     if (operands[3] == NULL_RTX)
8248       operands[3] = const0_rtx;
8250     pat = gen_sibcall_value_internal (operands[0], operands[1],
8251                                       operands[2], operands[3]);
8252     arm_emit_call_insn (pat, operands[1], true);
8253     DONE;
8254   }"
8257 (define_insn "*sibcall_insn"
8258  [(call (mem:SI (match_operand:SI 0 "call_insn_operand" "Cs, US"))
8259         (match_operand 1 "" ""))
8260   (return)
8261   (use (match_operand 2 "" ""))]
8262   "TARGET_32BIT && SIBLING_CALL_P (insn)"
8263   "*
8264   if (which_alternative == 1)
8265     return NEED_PLT_RELOC ? \"b%?\\t%a0(PLT)\" : \"b%?\\t%a0\";
8266   else
8267     {
8268       if (arm_arch5 || arm_arch4t)
8269         return \"bx%?\\t%0\\t%@ indirect register sibling call\";
8270       else
8271         return \"mov%?\\t%|pc, %0\\t%@ indirect register sibling call\";
8272     }
8273   "
8274   [(set_attr "type" "call")]
8277 (define_insn "*sibcall_value_insn"
8278  [(set (match_operand 0 "" "")
8279        (call (mem:SI (match_operand:SI 1 "call_insn_operand" "Cs,US"))
8280              (match_operand 2 "" "")))
8281   (return)
8282   (use (match_operand 3 "" ""))]
8283   "TARGET_32BIT && SIBLING_CALL_P (insn)"
8284   "*
8285   if (which_alternative == 1)
8286    return NEED_PLT_RELOC ? \"b%?\\t%a1(PLT)\" : \"b%?\\t%a1\";
8287   else
8288     {
8289       if (arm_arch5 || arm_arch4t)
8290         return \"bx%?\\t%1\";
8291       else
8292         return \"mov%?\\t%|pc, %1\\t@ indirect sibling call \";
8293     }
8294   "
8295   [(set_attr "type" "call")]
8298 (define_expand "<return_str>return"
8299   [(RETURNS)]
8300   "(TARGET_ARM || (TARGET_THUMB2
8301                    && ARM_FUNC_TYPE (arm_current_func_type ()) == ARM_FT_NORMAL
8302                    && !IS_STACKALIGN (arm_current_func_type ())))
8303     <return_cond_false>"
8304   "
8305   {
8306     if (TARGET_THUMB2)
8307       {
8308         thumb2_expand_return (<return_simple_p>);
8309         DONE;
8310       }
8311   }
8312   "
8315 ;; Often the return insn will be the same as loading from memory, so set attr
8316 (define_insn "*arm_return"
8317   [(return)]
8318   "TARGET_ARM && USE_RETURN_INSN (FALSE)"
8319   "*
8320   {
8321     if (arm_ccfsm_state == 2)
8322       {
8323         arm_ccfsm_state += 2;
8324         return \"\";
8325       }
8326     return output_return_instruction (const_true_rtx, true, false, false);
8327   }"
8328   [(set_attr "type" "load1")
8329    (set_attr "length" "12")
8330    (set_attr "predicable" "yes")]
8333 (define_insn "*cond_<return_str>return"
8334   [(set (pc)
8335         (if_then_else (match_operator 0 "arm_comparison_operator"
8336                        [(match_operand 1 "cc_register" "") (const_int 0)])
8337                       (RETURNS)
8338                       (pc)))]
8339   "TARGET_ARM  <return_cond_true>"
8340   "*
8341   {
8342     if (arm_ccfsm_state == 2)
8343       {
8344         arm_ccfsm_state += 2;
8345         return \"\";
8346       }
8347     return output_return_instruction (operands[0], true, false,
8348                                       <return_simple_p>);
8349   }"
8350   [(set_attr "conds" "use")
8351    (set_attr "length" "12")
8352    (set_attr "type" "load1")]
8355 (define_insn "*cond_<return_str>return_inverted"
8356   [(set (pc)
8357         (if_then_else (match_operator 0 "arm_comparison_operator"
8358                        [(match_operand 1 "cc_register" "") (const_int 0)])
8359                       (pc)
8360                       (RETURNS)))]
8361   "TARGET_ARM <return_cond_true>"
8362   "*
8363   {
8364     if (arm_ccfsm_state == 2)
8365       {
8366         arm_ccfsm_state += 2;
8367         return \"\";
8368       }
8369     return output_return_instruction (operands[0], true, true,
8370                                       <return_simple_p>);
8371   }"
8372   [(set_attr "conds" "use")
8373    (set_attr "length" "12")
8374    (set_attr "type" "load1")]
8377 (define_insn "*arm_simple_return"
8378   [(simple_return)]
8379   "TARGET_ARM"
8380   "*
8381   {
8382     if (arm_ccfsm_state == 2)
8383       {
8384         arm_ccfsm_state += 2;
8385         return \"\";
8386       }
8387     return output_return_instruction (const_true_rtx, true, false, true);
8388   }"
8389   [(set_attr "type" "branch")
8390    (set_attr "length" "4")
8391    (set_attr "predicable" "yes")]
8394 ;; Generate a sequence of instructions to determine if the processor is
8395 ;; in 26-bit or 32-bit mode, and return the appropriate return address
8396 ;; mask.
8398 (define_expand "return_addr_mask"
8399   [(set (match_dup 1)
8400       (compare:CC_NOOV (unspec [(const_int 0)] UNSPEC_CHECK_ARCH)
8401                        (const_int 0)))
8402    (set (match_operand:SI 0 "s_register_operand" "")
8403       (if_then_else:SI (eq (match_dup 1) (const_int 0))
8404                        (const_int -1)
8405                        (const_int 67108860)))] ; 0x03fffffc
8406   "TARGET_ARM"
8407   "
8408   operands[1] = gen_rtx_REG (CC_NOOVmode, CC_REGNUM);
8409   ")
8411 (define_insn "*check_arch2"
8412   [(set (match_operand:CC_NOOV 0 "cc_register" "")
8413       (compare:CC_NOOV (unspec [(const_int 0)] UNSPEC_CHECK_ARCH)
8414                        (const_int 0)))]
8415   "TARGET_ARM"
8416   "teq\\t%|r0, %|r0\;teq\\t%|pc, %|pc"
8417   [(set_attr "length" "8")
8418    (set_attr "conds" "set")
8419    (set_attr "type" "multiple")]
8422 ;; Call subroutine returning any type.
8424 (define_expand "untyped_call"
8425   [(parallel [(call (match_operand 0 "" "")
8426                     (const_int 0))
8427               (match_operand 1 "" "")
8428               (match_operand 2 "" "")])]
8429   "TARGET_EITHER"
8430   "
8431   {
8432     int i;
8433     rtx par = gen_rtx_PARALLEL (VOIDmode,
8434                                 rtvec_alloc (XVECLEN (operands[2], 0)));
8435     rtx addr = gen_reg_rtx (Pmode);
8436     rtx mem;
8437     int size = 0;
8439     emit_move_insn (addr, XEXP (operands[1], 0));
8440     mem = change_address (operands[1], BLKmode, addr);
8442     for (i = 0; i < XVECLEN (operands[2], 0); i++)
8443       {
8444         rtx src = SET_SRC (XVECEXP (operands[2], 0, i));
8446         /* Default code only uses r0 as a return value, but we could
8447            be using anything up to 4 registers.  */
8448         if (REGNO (src) == R0_REGNUM)
8449           src = gen_rtx_REG (TImode, R0_REGNUM);
8451         XVECEXP (par, 0, i) = gen_rtx_EXPR_LIST (VOIDmode, src,
8452                                                  GEN_INT (size));
8453         size += GET_MODE_SIZE (GET_MODE (src));
8454       }
8456     emit_call_insn (gen_call_value (par, operands[0], const0_rtx, NULL));
8458     size = 0;
8460     for (i = 0; i < XVECLEN (par, 0); i++)
8461       {
8462         HOST_WIDE_INT offset = 0;
8463         rtx reg = XEXP (XVECEXP (par, 0, i), 0);
8465         if (size != 0)
8466           emit_move_insn (addr, plus_constant (Pmode, addr, size));
8468         mem = change_address (mem, GET_MODE (reg), NULL);
8469         if (REGNO (reg) == R0_REGNUM)
8470           {
8471             /* On thumb we have to use a write-back instruction.  */
8472             emit_insn (arm_gen_store_multiple (arm_regs_in_sequence, 4, addr,
8473                        TARGET_THUMB ? TRUE : FALSE, mem, &offset));
8474             size = TARGET_ARM ? 16 : 0;
8475           }
8476         else
8477           {
8478             emit_move_insn (mem, reg);
8479             size = GET_MODE_SIZE (GET_MODE (reg));
8480           }
8481       }
8483     /* The optimizer does not know that the call sets the function value
8484        registers we stored in the result block.  We avoid problems by
8485        claiming that all hard registers are used and clobbered at this
8486        point.  */
8487     emit_insn (gen_blockage ());
8489     DONE;
8490   }"
8493 (define_expand "untyped_return"
8494   [(match_operand:BLK 0 "memory_operand" "")
8495    (match_operand 1 "" "")]
8496   "TARGET_EITHER"
8497   "
8498   {
8499     int i;
8500     rtx addr = gen_reg_rtx (Pmode);
8501     rtx mem;
8502     int size = 0;
8504     emit_move_insn (addr, XEXP (operands[0], 0));
8505     mem = change_address (operands[0], BLKmode, addr);
8507     for (i = 0; i < XVECLEN (operands[1], 0); i++)
8508       {
8509         HOST_WIDE_INT offset = 0;
8510         rtx reg = SET_DEST (XVECEXP (operands[1], 0, i));
8512         if (size != 0)
8513           emit_move_insn (addr, plus_constant (Pmode, addr, size));
8515         mem = change_address (mem, GET_MODE (reg), NULL);
8516         if (REGNO (reg) == R0_REGNUM)
8517           {
8518             /* On thumb we have to use a write-back instruction.  */
8519             emit_insn (arm_gen_load_multiple (arm_regs_in_sequence, 4, addr,
8520                        TARGET_THUMB ? TRUE : FALSE, mem, &offset));
8521             size = TARGET_ARM ? 16 : 0;
8522           }
8523         else
8524           {
8525             emit_move_insn (reg, mem);
8526             size = GET_MODE_SIZE (GET_MODE (reg));
8527           }
8528       }
8530     /* Emit USE insns before the return.  */
8531     for (i = 0; i < XVECLEN (operands[1], 0); i++)
8532       emit_use (SET_DEST (XVECEXP (operands[1], 0, i)));
8534     /* Construct the return.  */
8535     expand_naked_return ();
8537     DONE;
8538   }"
8541 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
8542 ;; all of memory.  This blocks insns from being moved across this point.
8544 (define_insn "blockage"
8545   [(unspec_volatile [(const_int 0)] VUNSPEC_BLOCKAGE)]
8546   "TARGET_EITHER"
8547   ""
8548   [(set_attr "length" "0")
8549    (set_attr "type" "block")]
8552 (define_insn "probe_stack"
8553   [(set (match_operand:SI 0 "memory_operand" "=m")
8554         (unspec:SI [(const_int 0)] UNSPEC_PROBE_STACK))]
8555   "TARGET_32BIT"
8556   "str%?\\tr0, %0"
8557   [(set_attr "type" "store1")
8558    (set_attr "predicable" "yes")]
8561 (define_insn "probe_stack_range"
8562   [(set (match_operand:SI 0 "register_operand" "=r")
8563         (unspec_volatile:SI [(match_operand:SI 1 "register_operand" "0")
8564                              (match_operand:SI 2 "register_operand" "r")]
8565                              VUNSPEC_PROBE_STACK_RANGE))]
8566   "TARGET_32BIT"
8568   return output_probe_stack_range (operands[0], operands[2]);
8570   [(set_attr "type" "multiple")
8571    (set_attr "conds" "clob")]
8574 (define_expand "casesi"
8575   [(match_operand:SI 0 "s_register_operand" "") ; index to jump on
8576    (match_operand:SI 1 "const_int_operand" "")  ; lower bound
8577    (match_operand:SI 2 "const_int_operand" "")  ; total range
8578    (match_operand:SI 3 "" "")                   ; table label
8579    (match_operand:SI 4 "" "")]                  ; Out of range label
8580   "(TARGET_32BIT || optimize_size || flag_pic) && !target_pure_code"
8581   "
8582   {
8583     enum insn_code code;
8584     if (operands[1] != const0_rtx)
8585       {
8586         rtx reg = gen_reg_rtx (SImode);
8588         emit_insn (gen_addsi3 (reg, operands[0],
8589                                gen_int_mode (-INTVAL (operands[1]),
8590                                              SImode)));
8591         operands[0] = reg;
8592       }
8594     if (TARGET_ARM)
8595       code = CODE_FOR_arm_casesi_internal;
8596     else if (TARGET_THUMB1)
8597       code = CODE_FOR_thumb1_casesi_internal_pic;
8598     else if (flag_pic)
8599       code = CODE_FOR_thumb2_casesi_internal_pic;
8600     else
8601       code = CODE_FOR_thumb2_casesi_internal;
8603     if (!insn_data[(int) code].operand[1].predicate(operands[2], SImode))
8604       operands[2] = force_reg (SImode, operands[2]);
8606     emit_jump_insn (GEN_FCN ((int) code) (operands[0], operands[2],
8607                                           operands[3], operands[4]));
8608     DONE;
8609   }"
8612 ;; The USE in this pattern is needed to tell flow analysis that this is
8613 ;; a CASESI insn.  It has no other purpose.
8614 (define_insn "arm_casesi_internal"
8615   [(parallel [(set (pc)
8616                (if_then_else
8617                 (leu (match_operand:SI 0 "s_register_operand" "r")
8618                      (match_operand:SI 1 "arm_rhs_operand" "rI"))
8619                 (mem:SI (plus:SI (mult:SI (match_dup 0) (const_int 4))
8620                                  (label_ref (match_operand 2 "" ""))))
8621                 (label_ref (match_operand 3 "" ""))))
8622               (clobber (reg:CC CC_REGNUM))
8623               (use (label_ref (match_dup 2)))])]
8624   "TARGET_ARM"
8625   "*
8626     if (flag_pic)
8627       return \"cmp\\t%0, %1\;addls\\t%|pc, %|pc, %0, asl #2\;b\\t%l3\";
8628     return   \"cmp\\t%0, %1\;ldrls\\t%|pc, [%|pc, %0, asl #2]\;b\\t%l3\";
8629   "
8630   [(set_attr "conds" "clob")
8631    (set_attr "length" "12")
8632    (set_attr "type" "multiple")]
8635 (define_expand "indirect_jump"
8636   [(set (pc)
8637         (match_operand:SI 0 "s_register_operand" ""))]
8638   "TARGET_EITHER"
8639   "
8640   /* Thumb-2 doesn't have mov pc, reg.  Explicitly set the low bit of the
8641      address and use bx.  */
8642   if (TARGET_THUMB2)
8643     {
8644       rtx tmp;
8645       tmp = gen_reg_rtx (SImode);
8646       emit_insn (gen_iorsi3 (tmp, operands[0], GEN_INT(1)));
8647       operands[0] = tmp;
8648     }
8649   "
8652 ;; NB Never uses BX.
8653 (define_insn "*arm_indirect_jump"
8654   [(set (pc)
8655         (match_operand:SI 0 "s_register_operand" "r"))]
8656   "TARGET_ARM"
8657   "mov%?\\t%|pc, %0\\t%@ indirect register jump"
8658   [(set_attr "predicable" "yes")
8659    (set_attr "type" "branch")]
8662 (define_insn "*load_indirect_jump"
8663   [(set (pc)
8664         (match_operand:SI 0 "memory_operand" "m"))]
8665   "TARGET_ARM"
8666   "ldr%?\\t%|pc, %0\\t%@ indirect memory jump"
8667   [(set_attr "type" "load1")
8668    (set_attr "pool_range" "4096")
8669    (set_attr "neg_pool_range" "4084")
8670    (set_attr "predicable" "yes")]
8674 ;; Misc insns
8676 (define_insn "nop"
8677   [(const_int 0)]
8678   "TARGET_EITHER"
8679   "nop"
8680   [(set (attr "length")
8681         (if_then_else (eq_attr "is_thumb" "yes")
8682                       (const_int 2)
8683                       (const_int 4)))
8684    (set_attr "type" "mov_reg")]
8687 (define_insn "trap"
8688   [(trap_if (const_int 1) (const_int 0))]
8689   ""
8690   "*
8691   if (TARGET_ARM)
8692     return \".inst\\t0xe7f000f0\";
8693   else
8694     return \".inst\\t0xdeff\";
8695   "
8696   [(set (attr "length")
8697         (if_then_else (eq_attr "is_thumb" "yes")
8698                       (const_int 2)
8699                       (const_int 4)))
8700    (set_attr "type" "trap")
8701    (set_attr "conds" "unconditional")]
8705 ;; Patterns to allow combination of arithmetic, cond code and shifts
8707 (define_insn "*<arith_shift_insn>_multsi"
8708   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8709         (SHIFTABLE_OPS:SI
8710          (mult:SI (match_operand:SI 2 "s_register_operand" "r,r")
8711                   (match_operand:SI 3 "power_of_two_operand" ""))
8712          (match_operand:SI 1 "s_register_operand" "rk,<t2_binop0>")))]
8713   "TARGET_32BIT"
8714   "<arith_shift_insn>%?\\t%0, %1, %2, lsl %b3"
8715   [(set_attr "predicable" "yes")
8716    (set_attr "predicable_short_it" "no")
8717    (set_attr "shift" "2")
8718    (set_attr "arch" "a,t2")
8719    (set_attr "type" "alu_shift_imm")])
8721 (define_insn "*<arith_shift_insn>_shiftsi"
8722   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
8723         (SHIFTABLE_OPS:SI
8724          (match_operator:SI 2 "shift_nomul_operator"
8725           [(match_operand:SI 3 "s_register_operand" "r,r,r")
8726            (match_operand:SI 4 "shift_amount_operand" "M,M,r")])
8727          (match_operand:SI 1 "s_register_operand" "rk,<t2_binop0>,rk")))]
8728   "TARGET_32BIT && GET_CODE (operands[2]) != MULT"
8729   "<arith_shift_insn>%?\\t%0, %1, %3%S2"
8730   [(set_attr "predicable" "yes")
8731    (set_attr "predicable_short_it" "no")
8732    (set_attr "shift" "3")
8733    (set_attr "arch" "a,t2,a")
8734    (set_attr "type" "alu_shift_imm,alu_shift_imm,alu_shift_reg")])
8736 (define_split
8737   [(set (match_operand:SI 0 "s_register_operand" "")
8738         (match_operator:SI 1 "shiftable_operator"
8739          [(match_operator:SI 2 "shiftable_operator"
8740            [(match_operator:SI 3 "shift_operator"
8741              [(match_operand:SI 4 "s_register_operand" "")
8742               (match_operand:SI 5 "reg_or_int_operand" "")])
8743             (match_operand:SI 6 "s_register_operand" "")])
8744           (match_operand:SI 7 "arm_rhs_operand" "")]))
8745    (clobber (match_operand:SI 8 "s_register_operand" ""))]
8746   "TARGET_32BIT"
8747   [(set (match_dup 8)
8748         (match_op_dup 2 [(match_op_dup 3 [(match_dup 4) (match_dup 5)])
8749                          (match_dup 6)]))
8750    (set (match_dup 0)
8751         (match_op_dup 1 [(match_dup 8) (match_dup 7)]))]
8752   "")
8754 (define_insn "*arith_shiftsi_compare0"
8755   [(set (reg:CC_NOOV CC_REGNUM)
8756         (compare:CC_NOOV
8757          (match_operator:SI 1 "shiftable_operator"
8758           [(match_operator:SI 3 "shift_operator"
8759             [(match_operand:SI 4 "s_register_operand" "r,r")
8760              (match_operand:SI 5 "shift_amount_operand" "M,r")])
8761            (match_operand:SI 2 "s_register_operand" "r,r")])
8762          (const_int 0)))
8763    (set (match_operand:SI 0 "s_register_operand" "=r,r")
8764         (match_op_dup 1 [(match_op_dup 3 [(match_dup 4) (match_dup 5)])
8765                          (match_dup 2)]))]
8766   "TARGET_32BIT"
8767   "%i1s%?\\t%0, %2, %4%S3"
8768   [(set_attr "conds" "set")
8769    (set_attr "shift" "4")
8770    (set_attr "arch" "32,a")
8771    (set_attr "type" "alus_shift_imm,alus_shift_reg")])
8773 (define_insn "*arith_shiftsi_compare0_scratch"
8774   [(set (reg:CC_NOOV CC_REGNUM)
8775         (compare:CC_NOOV
8776          (match_operator:SI 1 "shiftable_operator"
8777           [(match_operator:SI 3 "shift_operator"
8778             [(match_operand:SI 4 "s_register_operand" "r,r")
8779              (match_operand:SI 5 "shift_amount_operand" "M,r")])
8780            (match_operand:SI 2 "s_register_operand" "r,r")])
8781          (const_int 0)))
8782    (clobber (match_scratch:SI 0 "=r,r"))]
8783   "TARGET_32BIT"
8784   "%i1s%?\\t%0, %2, %4%S3"
8785   [(set_attr "conds" "set")
8786    (set_attr "shift" "4")
8787    (set_attr "arch" "32,a")
8788    (set_attr "type" "alus_shift_imm,alus_shift_reg")])
8790 (define_insn "*sub_shiftsi"
8791   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8792         (minus:SI (match_operand:SI 1 "s_register_operand" "r,r")
8793                   (match_operator:SI 2 "shift_operator"
8794                    [(match_operand:SI 3 "s_register_operand" "r,r")
8795                     (match_operand:SI 4 "shift_amount_operand" "M,r")])))]
8796   "TARGET_32BIT"
8797   "sub%?\\t%0, %1, %3%S2"
8798   [(set_attr "predicable" "yes")
8799    (set_attr "shift" "3")
8800    (set_attr "arch" "32,a")
8801    (set_attr "type" "alus_shift_imm,alus_shift_reg")])
8803 (define_insn "*sub_shiftsi_compare0"
8804   [(set (reg:CC_NOOV CC_REGNUM)
8805         (compare:CC_NOOV
8806          (minus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
8807                    (match_operator:SI 2 "shift_operator"
8808                     [(match_operand:SI 3 "s_register_operand" "r,r,r")
8809                      (match_operand:SI 4 "shift_amount_operand" "M,r,M")]))
8810          (const_int 0)))
8811    (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
8812         (minus:SI (match_dup 1)
8813                   (match_op_dup 2 [(match_dup 3) (match_dup 4)])))]
8814   "TARGET_32BIT"
8815   "subs%?\\t%0, %1, %3%S2"
8816   [(set_attr "conds" "set")
8817    (set_attr "shift" "3")
8818    (set_attr "arch" "32,a,a")
8819    (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
8821 (define_insn "*sub_shiftsi_compare0_scratch"
8822   [(set (reg:CC_NOOV CC_REGNUM)
8823         (compare:CC_NOOV
8824          (minus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
8825                    (match_operator:SI 2 "shift_operator"
8826                     [(match_operand:SI 3 "s_register_operand" "r,r,r")
8827                      (match_operand:SI 4 "shift_amount_operand" "M,r,M")]))
8828          (const_int 0)))
8829    (clobber (match_scratch:SI 0 "=r,r,r"))]
8830   "TARGET_32BIT"
8831   "subs%?\\t%0, %1, %3%S2"
8832   [(set_attr "conds" "set")
8833    (set_attr "shift" "3")
8834    (set_attr "arch" "32,a,a")
8835    (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
8838 (define_insn_and_split "*and_scc"
8839   [(set (match_operand:SI 0 "s_register_operand" "=r")
8840         (and:SI (match_operator:SI 1 "arm_comparison_operator"
8841                  [(match_operand 2 "cc_register" "") (const_int 0)])
8842                 (match_operand:SI 3 "s_register_operand" "r")))]
8843   "TARGET_ARM"
8844   "#"   ; "mov%D1\\t%0, #0\;and%d1\\t%0, %3, #1"
8845   "&& reload_completed"
8846   [(cond_exec (match_dup 5) (set (match_dup 0) (const_int 0)))
8847    (cond_exec (match_dup 4) (set (match_dup 0)
8848                                  (and:SI (match_dup 3) (const_int 1))))]
8849   {
8850     machine_mode mode = GET_MODE (operands[2]);
8851     enum rtx_code rc = GET_CODE (operands[1]);
8853     /* Note that operands[4] is the same as operands[1],
8854        but with VOIDmode as the result. */
8855     operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
8856     if (mode == CCFPmode || mode == CCFPEmode)
8857       rc = reverse_condition_maybe_unordered (rc);
8858     else
8859       rc = reverse_condition (rc);
8860     operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
8861   }
8862   [(set_attr "conds" "use")
8863    (set_attr "type" "multiple")
8864    (set_attr "length" "8")]
8867 (define_insn_and_split "*ior_scc"
8868   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8869         (ior:SI (match_operator:SI 1 "arm_comparison_operator"
8870                  [(match_operand 2 "cc_register" "") (const_int 0)])
8871                 (match_operand:SI 3 "s_register_operand" "0,?r")))]
8872   "TARGET_ARM"
8873   "@
8874    orr%d1\\t%0, %3, #1
8875    #"
8876   "&& reload_completed
8877    && REGNO (operands [0]) != REGNO (operands[3])"
8878   ;; && which_alternative == 1
8879   ; mov%D1\\t%0, %3\;orr%d1\\t%0, %3, #1
8880   [(cond_exec (match_dup 5) (set (match_dup 0) (match_dup 3)))
8881    (cond_exec (match_dup 4) (set (match_dup 0)
8882                                  (ior:SI (match_dup 3) (const_int 1))))]
8883   {
8884     machine_mode mode = GET_MODE (operands[2]);
8885     enum rtx_code rc = GET_CODE (operands[1]);
8887     /* Note that operands[4] is the same as operands[1],
8888        but with VOIDmode as the result. */
8889     operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
8890     if (mode == CCFPmode || mode == CCFPEmode)
8891       rc = reverse_condition_maybe_unordered (rc);
8892     else
8893       rc = reverse_condition (rc);
8894     operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
8895   }
8896   [(set_attr "conds" "use")
8897    (set_attr "length" "4,8")
8898    (set_attr "type" "logic_imm,multiple")]
8901 ; A series of splitters for the compare_scc pattern below.  Note that
8902 ; order is important.
8903 (define_split
8904   [(set (match_operand:SI 0 "s_register_operand" "")
8905         (lt:SI (match_operand:SI 1 "s_register_operand" "")
8906                (const_int 0)))
8907    (clobber (reg:CC CC_REGNUM))]
8908   "TARGET_32BIT && reload_completed"
8909   [(set (match_dup 0) (lshiftrt:SI (match_dup 1) (const_int 31)))])
8911 (define_split
8912   [(set (match_operand:SI 0 "s_register_operand" "")
8913         (ge:SI (match_operand:SI 1 "s_register_operand" "")
8914                (const_int 0)))
8915    (clobber (reg:CC CC_REGNUM))]
8916   "TARGET_32BIT && reload_completed"
8917   [(set (match_dup 0) (not:SI (match_dup 1)))
8918    (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 31)))])
8920 (define_split
8921   [(set (match_operand:SI 0 "s_register_operand" "")
8922         (eq:SI (match_operand:SI 1 "s_register_operand" "")
8923                (const_int 0)))
8924    (clobber (reg:CC CC_REGNUM))]
8925   "arm_arch5 && TARGET_32BIT"
8926   [(set (match_dup 0) (clz:SI (match_dup 1)))
8927    (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
8930 (define_split
8931   [(set (match_operand:SI 0 "s_register_operand" "")
8932         (eq:SI (match_operand:SI 1 "s_register_operand" "")
8933                (const_int 0)))
8934    (clobber (reg:CC CC_REGNUM))]
8935   "TARGET_32BIT && reload_completed"
8936   [(parallel
8937     [(set (reg:CC CC_REGNUM)
8938           (compare:CC (const_int 1) (match_dup 1)))
8939      (set (match_dup 0)
8940           (minus:SI (const_int 1) (match_dup 1)))])
8941    (cond_exec (ltu:CC (reg:CC CC_REGNUM) (const_int 0))
8942               (set (match_dup 0) (const_int 0)))])
8944 (define_split
8945   [(set (match_operand:SI 0 "s_register_operand" "")
8946         (ne:SI (match_operand:SI 1 "s_register_operand" "")
8947                (match_operand:SI 2 "const_int_operand" "")))
8948    (clobber (reg:CC CC_REGNUM))]
8949   "TARGET_32BIT && reload_completed"
8950   [(parallel
8951     [(set (reg:CC CC_REGNUM)
8952           (compare:CC (match_dup 1) (match_dup 2)))
8953      (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 3)))])
8954    (cond_exec (ne:CC (reg:CC CC_REGNUM) (const_int 0))
8955               (set (match_dup 0) (const_int 1)))]
8957   operands[3] = GEN_INT (-INTVAL (operands[2]));
8960 (define_split
8961   [(set (match_operand:SI 0 "s_register_operand" "")
8962         (ne:SI (match_operand:SI 1 "s_register_operand" "")
8963                (match_operand:SI 2 "arm_add_operand" "")))
8964    (clobber (reg:CC CC_REGNUM))]
8965   "TARGET_32BIT && reload_completed"
8966   [(parallel
8967     [(set (reg:CC_NOOV CC_REGNUM)
8968           (compare:CC_NOOV (minus:SI (match_dup 1) (match_dup 2))
8969                            (const_int 0)))
8970      (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
8971    (cond_exec (ne:CC_NOOV (reg:CC_NOOV CC_REGNUM) (const_int 0))
8972               (set (match_dup 0) (const_int 1)))])
8974 (define_insn_and_split "*compare_scc"
8975   [(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts")
8976         (match_operator:SI 1 "arm_comparison_operator"
8977          [(match_operand:SI 2 "s_register_operand" "r,r")
8978           (match_operand:SI 3 "arm_add_operand" "rI,L")]))
8979    (clobber (reg:CC CC_REGNUM))]
8980   "TARGET_32BIT"
8981   "#"
8982   "&& reload_completed"
8983   [(set (reg:CC CC_REGNUM) (compare:CC (match_dup 2) (match_dup 3)))
8984    (cond_exec (match_dup 4) (set (match_dup 0) (const_int 0)))
8985    (cond_exec (match_dup 5) (set (match_dup 0) (const_int 1)))]
8987   rtx tmp1;
8988   machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
8989                                            operands[2], operands[3]);
8990   enum rtx_code rc = GET_CODE (operands[1]);
8992   tmp1 = gen_rtx_REG (mode, CC_REGNUM);
8994   operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, tmp1, const0_rtx);
8995   if (mode == CCFPmode || mode == CCFPEmode)
8996     rc = reverse_condition_maybe_unordered (rc);
8997   else
8998     rc = reverse_condition (rc);
8999   operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, tmp1, const0_rtx);
9001   [(set_attr "type" "multiple")]
9004 ;; Attempt to improve the sequence generated by the compare_scc splitters
9005 ;; not to use conditional execution.
9007 ;; Rd = (eq (reg1) (const_int0))  // ARMv5
9008 ;;      clz Rd, reg1
9009 ;;      lsr Rd, Rd, #5
9010 (define_peephole2
9011   [(set (reg:CC CC_REGNUM)
9012         (compare:CC (match_operand:SI 1 "register_operand" "")
9013                     (const_int 0)))
9014    (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
9015               (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
9016    (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
9017               (set (match_dup 0) (const_int 1)))]
9018   "arm_arch5 && TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
9019   [(set (match_dup 0) (clz:SI (match_dup 1)))
9020    (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
9023 ;; Rd = (eq (reg1) (const_int0))  // !ARMv5
9024 ;;      negs Rd, reg1
9025 ;;      adc  Rd, Rd, reg1
9026 (define_peephole2
9027   [(set (reg:CC CC_REGNUM)
9028         (compare:CC (match_operand:SI 1 "register_operand" "")
9029                     (const_int 0)))
9030    (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
9031               (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
9032    (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
9033               (set (match_dup 0) (const_int 1)))
9034    (match_scratch:SI 2 "r")]
9035   "TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
9036   [(parallel
9037     [(set (reg:CC CC_REGNUM)
9038           (compare:CC (const_int 0) (match_dup 1)))
9039      (set (match_dup 2) (minus:SI (const_int 0) (match_dup 1)))])
9040    (set (match_dup 0)
9041         (plus:SI (plus:SI (match_dup 1) (match_dup 2))
9042                  (geu:SI (reg:CC CC_REGNUM) (const_int 0))))]
9045 ;; Rd = (eq (reg1) (reg2/imm))  // ARMv5 and optimising for speed.
9046 ;;      sub  Rd, Reg1, reg2
9047 ;;      clz  Rd, Rd
9048 ;;      lsr  Rd, Rd, #5
9049 (define_peephole2
9050   [(set (reg:CC CC_REGNUM)
9051         (compare:CC (match_operand:SI 1 "register_operand" "")
9052                     (match_operand:SI 2 "arm_rhs_operand" "")))
9053    (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
9054               (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
9055    (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
9056               (set (match_dup 0) (const_int 1)))]
9057   "arm_arch5 && TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)
9058   && !(TARGET_THUMB2 && optimize_insn_for_size_p ())"
9059   [(set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))
9060    (set (match_dup 0) (clz:SI (match_dup 0)))
9061    (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
9065 ;; Rd = (eq (reg1) (reg2))      // ! ARMv5 or optimising for size.
9066 ;;      sub  T1, Reg1, reg2
9067 ;;      negs Rd, T1
9068 ;;      adc  Rd, Rd, T1
9069 (define_peephole2
9070   [(set (reg:CC CC_REGNUM)
9071         (compare:CC (match_operand:SI 1 "register_operand" "")
9072                     (match_operand:SI 2 "arm_rhs_operand" "")))
9073    (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
9074               (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
9075    (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
9076               (set (match_dup 0) (const_int 1)))
9077    (match_scratch:SI 3 "r")]
9078   "TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
9079   [(set (match_dup 3) (match_dup 4))
9080    (parallel
9081     [(set (reg:CC CC_REGNUM)
9082           (compare:CC (const_int 0) (match_dup 3)))
9083      (set (match_dup 0) (minus:SI (const_int 0) (match_dup 3)))])
9084    (set (match_dup 0)
9085         (plus:SI (plus:SI (match_dup 0) (match_dup 3))
9086                  (geu:SI (reg:CC CC_REGNUM) (const_int 0))))]
9087   "
9088   if (CONST_INT_P (operands[2]))
9089     operands[4] = plus_constant (SImode, operands[1], -INTVAL (operands[2]));
9090   else
9091     operands[4] = gen_rtx_MINUS (SImode, operands[1], operands[2]);
9092   ")
9094 (define_insn "*cond_move"
9095   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9096         (if_then_else:SI (match_operator 3 "equality_operator"
9097                           [(match_operator 4 "arm_comparison_operator"
9098                             [(match_operand 5 "cc_register" "") (const_int 0)])
9099                            (const_int 0)])
9100                          (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
9101                          (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))]
9102   "TARGET_ARM"
9103   "*
9104     if (GET_CODE (operands[3]) == NE)
9105       {
9106         if (which_alternative != 1)
9107           output_asm_insn (\"mov%D4\\t%0, %2\", operands);
9108         if (which_alternative != 0)
9109           output_asm_insn (\"mov%d4\\t%0, %1\", operands);
9110         return \"\";
9111       }
9112     if (which_alternative != 0)
9113       output_asm_insn (\"mov%D4\\t%0, %1\", operands);
9114     if (which_alternative != 1)
9115       output_asm_insn (\"mov%d4\\t%0, %2\", operands);
9116     return \"\";
9117   "
9118   [(set_attr "conds" "use")
9119    (set_attr_alternative "type"
9120                          [(if_then_else (match_operand 2 "const_int_operand" "")
9121                                         (const_string "mov_imm")
9122                                         (const_string "mov_reg"))
9123                           (if_then_else (match_operand 1 "const_int_operand" "")
9124                                         (const_string "mov_imm")
9125                                         (const_string "mov_reg"))
9126                           (const_string "multiple")])
9127    (set_attr "length" "4,4,8")]
9130 (define_insn "*cond_arith"
9131   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9132         (match_operator:SI 5 "shiftable_operator" 
9133          [(match_operator:SI 4 "arm_comparison_operator"
9134            [(match_operand:SI 2 "s_register_operand" "r,r")
9135             (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
9136           (match_operand:SI 1 "s_register_operand" "0,?r")]))
9137    (clobber (reg:CC CC_REGNUM))]
9138   "TARGET_ARM"
9139   "*
9140     if (GET_CODE (operands[4]) == LT && operands[3] == const0_rtx)
9141       return \"%i5\\t%0, %1, %2, lsr #31\";
9143     output_asm_insn (\"cmp\\t%2, %3\", operands);
9144     if (GET_CODE (operands[5]) == AND)
9145       output_asm_insn (\"mov%D4\\t%0, #0\", operands);
9146     else if (GET_CODE (operands[5]) == MINUS)
9147       output_asm_insn (\"rsb%D4\\t%0, %1, #0\", operands);
9148     else if (which_alternative != 0)
9149       output_asm_insn (\"mov%D4\\t%0, %1\", operands);
9150     return \"%i5%d4\\t%0, %1, #1\";
9151   "
9152   [(set_attr "conds" "clob")
9153    (set_attr "length" "12")
9154    (set_attr "type" "multiple")]
9157 (define_insn "*cond_sub"
9158   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9159         (minus:SI (match_operand:SI 1 "s_register_operand" "0,?r")
9160                   (match_operator:SI 4 "arm_comparison_operator"
9161                    [(match_operand:SI 2 "s_register_operand" "r,r")
9162                     (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
9163    (clobber (reg:CC CC_REGNUM))]
9164   "TARGET_ARM"
9165   "*
9166     output_asm_insn (\"cmp\\t%2, %3\", operands);
9167     if (which_alternative != 0)
9168       output_asm_insn (\"mov%D4\\t%0, %1\", operands);
9169     return \"sub%d4\\t%0, %1, #1\";
9170   "
9171   [(set_attr "conds" "clob")
9172    (set_attr "length" "8,12")
9173    (set_attr "type" "multiple")]
9176 (define_insn "*cmp_ite0"
9177   [(set (match_operand 6 "dominant_cc_register" "")
9178         (compare
9179          (if_then_else:SI
9180           (match_operator 4 "arm_comparison_operator"
9181            [(match_operand:SI 0 "s_register_operand"
9182                 "l,l,l,r,r,r,r,r,r")
9183             (match_operand:SI 1 "arm_add_operand"
9184                 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
9185           (match_operator:SI 5 "arm_comparison_operator"
9186            [(match_operand:SI 2 "s_register_operand"
9187                 "l,r,r,l,l,r,r,r,r")
9188             (match_operand:SI 3 "arm_add_operand"
9189                 "lPy,rI,L,lPy,lPy,rI,rI,L,L")])
9190           (const_int 0))
9191          (const_int 0)))]
9192   "TARGET_32BIT"
9193   "*
9194   {
9195     static const char * const cmp1[NUM_OF_COND_CMP][2] =
9196     {
9197       {\"cmp%d5\\t%0, %1\",
9198        \"cmp%d4\\t%2, %3\"},
9199       {\"cmn%d5\\t%0, #%n1\",
9200        \"cmp%d4\\t%2, %3\"},
9201       {\"cmp%d5\\t%0, %1\",
9202        \"cmn%d4\\t%2, #%n3\"},
9203       {\"cmn%d5\\t%0, #%n1\",
9204        \"cmn%d4\\t%2, #%n3\"}
9205     };
9206     static const char * const cmp2[NUM_OF_COND_CMP][2] =
9207     {
9208       {\"cmp\\t%2, %3\",
9209        \"cmp\\t%0, %1\"},
9210       {\"cmp\\t%2, %3\",
9211        \"cmn\\t%0, #%n1\"},
9212       {\"cmn\\t%2, #%n3\",
9213        \"cmp\\t%0, %1\"},
9214       {\"cmn\\t%2, #%n3\",
9215        \"cmn\\t%0, #%n1\"}
9216     };
9217     static const char * const ite[2] =
9218     {
9219       \"it\\t%d5\",
9220       \"it\\t%d4\"
9221     };
9222     static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
9223                                    CMP_CMP, CMN_CMP, CMP_CMP,
9224                                    CMN_CMP, CMP_CMN, CMN_CMN};
9225     int swap =
9226       comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
9228     output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
9229     if (TARGET_THUMB2) {
9230       output_asm_insn (ite[swap], operands);
9231     }
9232     output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
9233     return \"\";
9234   }"
9235   [(set_attr "conds" "set")
9236    (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
9237    (set_attr "type" "multiple")
9238    (set_attr_alternative "length"
9239       [(const_int 6)
9240        (const_int 8)
9241        (const_int 8)
9242        (const_int 8)
9243        (const_int 8)
9244        (if_then_else (eq_attr "is_thumb" "no")
9245            (const_int 8)
9246            (const_int 10))
9247        (if_then_else (eq_attr "is_thumb" "no")
9248            (const_int 8)
9249            (const_int 10))
9250        (if_then_else (eq_attr "is_thumb" "no")
9251            (const_int 8)
9252            (const_int 10))
9253        (if_then_else (eq_attr "is_thumb" "no")
9254            (const_int 8)
9255            (const_int 10))])]
9258 (define_insn "*cmp_ite1"
9259   [(set (match_operand 6 "dominant_cc_register" "")
9260         (compare
9261          (if_then_else:SI
9262           (match_operator 4 "arm_comparison_operator"
9263            [(match_operand:SI 0 "s_register_operand"
9264                 "l,l,l,r,r,r,r,r,r")
9265             (match_operand:SI 1 "arm_add_operand"
9266                 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
9267           (match_operator:SI 5 "arm_comparison_operator"
9268            [(match_operand:SI 2 "s_register_operand"
9269                 "l,r,r,l,l,r,r,r,r")
9270             (match_operand:SI 3 "arm_add_operand"
9271                 "lPy,rI,L,lPy,lPy,rI,rI,L,L")])
9272           (const_int 1))
9273          (const_int 0)))]
9274   "TARGET_32BIT"
9275   "*
9276   {
9277     static const char * const cmp1[NUM_OF_COND_CMP][2] =
9278     {
9279       {\"cmp\\t%0, %1\",
9280        \"cmp\\t%2, %3\"},
9281       {\"cmn\\t%0, #%n1\",
9282        \"cmp\\t%2, %3\"},
9283       {\"cmp\\t%0, %1\",
9284        \"cmn\\t%2, #%n3\"},
9285       {\"cmn\\t%0, #%n1\",
9286        \"cmn\\t%2, #%n3\"}
9287     };
9288     static const char * const cmp2[NUM_OF_COND_CMP][2] =
9289     {
9290       {\"cmp%d4\\t%2, %3\",
9291        \"cmp%D5\\t%0, %1\"},
9292       {\"cmp%d4\\t%2, %3\",
9293        \"cmn%D5\\t%0, #%n1\"},
9294       {\"cmn%d4\\t%2, #%n3\",
9295        \"cmp%D5\\t%0, %1\"},
9296       {\"cmn%d4\\t%2, #%n3\",
9297        \"cmn%D5\\t%0, #%n1\"}
9298     };
9299     static const char * const ite[2] =
9300     {
9301       \"it\\t%d4\",
9302       \"it\\t%D5\"
9303     };
9304     static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
9305                                    CMP_CMP, CMN_CMP, CMP_CMP,
9306                                    CMN_CMP, CMP_CMN, CMN_CMN};
9307     int swap =
9308       comparison_dominates_p (GET_CODE (operands[5]),
9309                               reverse_condition (GET_CODE (operands[4])));
9311     output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
9312     if (TARGET_THUMB2) {
9313       output_asm_insn (ite[swap], operands);
9314     }
9315     output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
9316     return \"\";
9317   }"
9318   [(set_attr "conds" "set")
9319    (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
9320    (set_attr_alternative "length"
9321       [(const_int 6)
9322        (const_int 8)
9323        (const_int 8)
9324        (const_int 8)
9325        (const_int 8)
9326        (if_then_else (eq_attr "is_thumb" "no")
9327            (const_int 8)
9328            (const_int 10))
9329        (if_then_else (eq_attr "is_thumb" "no")
9330            (const_int 8)
9331            (const_int 10))
9332        (if_then_else (eq_attr "is_thumb" "no")
9333            (const_int 8)
9334            (const_int 10))
9335        (if_then_else (eq_attr "is_thumb" "no")
9336            (const_int 8)
9337            (const_int 10))])
9338    (set_attr "type" "multiple")]
9341 (define_insn "*cmp_and"
9342   [(set (match_operand 6 "dominant_cc_register" "")
9343         (compare
9344          (and:SI
9345           (match_operator 4 "arm_comparison_operator"
9346            [(match_operand:SI 0 "s_register_operand" 
9347                 "l,l,l,r,r,r,r,r,r")
9348             (match_operand:SI 1 "arm_add_operand" 
9349                 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
9350           (match_operator:SI 5 "arm_comparison_operator"
9351            [(match_operand:SI 2 "s_register_operand" 
9352                 "l,r,r,l,l,r,r,r,r")
9353             (match_operand:SI 3 "arm_add_operand" 
9354                 "lPy,rI,L,lPy,lPy,rI,rI,L,L")]))
9355          (const_int 0)))]
9356   "TARGET_32BIT"
9357   "*
9358   {
9359     static const char *const cmp1[NUM_OF_COND_CMP][2] =
9360     {
9361       {\"cmp%d5\\t%0, %1\",
9362        \"cmp%d4\\t%2, %3\"},
9363       {\"cmn%d5\\t%0, #%n1\",
9364        \"cmp%d4\\t%2, %3\"},
9365       {\"cmp%d5\\t%0, %1\",
9366        \"cmn%d4\\t%2, #%n3\"},
9367       {\"cmn%d5\\t%0, #%n1\",
9368        \"cmn%d4\\t%2, #%n3\"}
9369     };
9370     static const char *const cmp2[NUM_OF_COND_CMP][2] =
9371     {
9372       {\"cmp\\t%2, %3\",
9373        \"cmp\\t%0, %1\"},
9374       {\"cmp\\t%2, %3\",
9375        \"cmn\\t%0, #%n1\"},
9376       {\"cmn\\t%2, #%n3\",
9377        \"cmp\\t%0, %1\"},
9378       {\"cmn\\t%2, #%n3\",
9379        \"cmn\\t%0, #%n1\"}
9380     };
9381     static const char *const ite[2] =
9382     {
9383       \"it\\t%d5\",
9384       \"it\\t%d4\"
9385     };
9386     static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
9387                                    CMP_CMP, CMN_CMP, CMP_CMP,
9388                                    CMN_CMP, CMP_CMN, CMN_CMN};
9389     int swap =
9390       comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
9392     output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
9393     if (TARGET_THUMB2) {
9394       output_asm_insn (ite[swap], operands);
9395     }
9396     output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
9397     return \"\";
9398   }"
9399   [(set_attr "conds" "set")
9400    (set_attr "predicable" "no")
9401    (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
9402    (set_attr_alternative "length"
9403       [(const_int 6)
9404        (const_int 8)
9405        (const_int 8)
9406        (const_int 8)
9407        (const_int 8)
9408        (if_then_else (eq_attr "is_thumb" "no")
9409            (const_int 8)
9410            (const_int 10))
9411        (if_then_else (eq_attr "is_thumb" "no")
9412            (const_int 8)
9413            (const_int 10))
9414        (if_then_else (eq_attr "is_thumb" "no")
9415            (const_int 8)
9416            (const_int 10))
9417        (if_then_else (eq_attr "is_thumb" "no")
9418            (const_int 8)
9419            (const_int 10))])
9420    (set_attr "type" "multiple")]
9423 (define_insn "*cmp_ior"
9424   [(set (match_operand 6 "dominant_cc_register" "")
9425         (compare
9426          (ior:SI
9427           (match_operator 4 "arm_comparison_operator"
9428            [(match_operand:SI 0 "s_register_operand"
9429                 "l,l,l,r,r,r,r,r,r")
9430             (match_operand:SI 1 "arm_add_operand"
9431                 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
9432           (match_operator:SI 5 "arm_comparison_operator"
9433            [(match_operand:SI 2 "s_register_operand"
9434                 "l,r,r,l,l,r,r,r,r")
9435             (match_operand:SI 3 "arm_add_operand"
9436                 "lPy,rI,L,lPy,lPy,rI,rI,L,L")]))
9437          (const_int 0)))]
9438   "TARGET_32BIT"
9439   "*
9440   {
9441     static const char *const cmp1[NUM_OF_COND_CMP][2] =
9442     {
9443       {\"cmp\\t%0, %1\",
9444        \"cmp\\t%2, %3\"},
9445       {\"cmn\\t%0, #%n1\",
9446        \"cmp\\t%2, %3\"},
9447       {\"cmp\\t%0, %1\",
9448        \"cmn\\t%2, #%n3\"},
9449       {\"cmn\\t%0, #%n1\",
9450        \"cmn\\t%2, #%n3\"}
9451     };
9452     static const char *const cmp2[NUM_OF_COND_CMP][2] =
9453     {
9454       {\"cmp%D4\\t%2, %3\",
9455        \"cmp%D5\\t%0, %1\"},
9456       {\"cmp%D4\\t%2, %3\",
9457        \"cmn%D5\\t%0, #%n1\"},
9458       {\"cmn%D4\\t%2, #%n3\",
9459        \"cmp%D5\\t%0, %1\"},
9460       {\"cmn%D4\\t%2, #%n3\",
9461        \"cmn%D5\\t%0, #%n1\"}
9462     };
9463     static const char *const ite[2] =
9464     {
9465       \"it\\t%D4\",
9466       \"it\\t%D5\"
9467     };
9468     static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
9469                                    CMP_CMP, CMN_CMP, CMP_CMP,
9470                                    CMN_CMP, CMP_CMN, CMN_CMN};
9471     int swap =
9472       comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
9474     output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
9475     if (TARGET_THUMB2) {
9476       output_asm_insn (ite[swap], operands);
9477     }
9478     output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
9479     return \"\";
9480   }
9481   "
9482   [(set_attr "conds" "set")
9483    (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
9484    (set_attr_alternative "length"
9485       [(const_int 6)
9486        (const_int 8)
9487        (const_int 8)
9488        (const_int 8)
9489        (const_int 8)
9490        (if_then_else (eq_attr "is_thumb" "no")
9491            (const_int 8)
9492            (const_int 10))
9493        (if_then_else (eq_attr "is_thumb" "no")
9494            (const_int 8)
9495            (const_int 10))
9496        (if_then_else (eq_attr "is_thumb" "no")
9497            (const_int 8)
9498            (const_int 10))
9499        (if_then_else (eq_attr "is_thumb" "no")
9500            (const_int 8)
9501            (const_int 10))])
9502    (set_attr "type" "multiple")]
9505 (define_insn_and_split "*ior_scc_scc"
9506   [(set (match_operand:SI 0 "s_register_operand" "=Ts")
9507         (ior:SI (match_operator:SI 3 "arm_comparison_operator"
9508                  [(match_operand:SI 1 "s_register_operand" "r")
9509                   (match_operand:SI 2 "arm_add_operand" "rIL")])
9510                 (match_operator:SI 6 "arm_comparison_operator"
9511                  [(match_operand:SI 4 "s_register_operand" "r")
9512                   (match_operand:SI 5 "arm_add_operand" "rIL")])))
9513    (clobber (reg:CC CC_REGNUM))]
9514   "TARGET_32BIT
9515    && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_OR_Y)
9516        != CCmode)"
9517   "#"
9518   "TARGET_32BIT && reload_completed"
9519   [(set (match_dup 7)
9520         (compare
9521          (ior:SI
9522           (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9523           (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9524          (const_int 0)))
9525    (set (match_dup 0) (ne:SI (match_dup 7) (const_int 0)))]
9526   "operands[7]
9527      = gen_rtx_REG (arm_select_dominance_cc_mode (operands[3], operands[6],
9528                                                   DOM_CC_X_OR_Y),
9529                     CC_REGNUM);"
9530   [(set_attr "conds" "clob")
9531    (set_attr "length" "16")
9532    (set_attr "type" "multiple")]
9535 ; If the above pattern is followed by a CMP insn, then the compare is 
9536 ; redundant, since we can rework the conditional instruction that follows.
9537 (define_insn_and_split "*ior_scc_scc_cmp"
9538   [(set (match_operand 0 "dominant_cc_register" "")
9539         (compare (ior:SI (match_operator:SI 3 "arm_comparison_operator"
9540                           [(match_operand:SI 1 "s_register_operand" "r")
9541                            (match_operand:SI 2 "arm_add_operand" "rIL")])
9542                          (match_operator:SI 6 "arm_comparison_operator"
9543                           [(match_operand:SI 4 "s_register_operand" "r")
9544                            (match_operand:SI 5 "arm_add_operand" "rIL")]))
9545                  (const_int 0)))
9546    (set (match_operand:SI 7 "s_register_operand" "=Ts")
9547         (ior:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9548                 (match_op_dup 6 [(match_dup 4) (match_dup 5)])))]
9549   "TARGET_32BIT"
9550   "#"
9551   "TARGET_32BIT && reload_completed"
9552   [(set (match_dup 0)
9553         (compare
9554          (ior:SI
9555           (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9556           (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9557          (const_int 0)))
9558    (set (match_dup 7) (ne:SI (match_dup 0) (const_int 0)))]
9559   ""
9560   [(set_attr "conds" "set")
9561    (set_attr "length" "16")
9562    (set_attr "type" "multiple")]
9565 (define_insn_and_split "*and_scc_scc"
9566   [(set (match_operand:SI 0 "s_register_operand" "=Ts")
9567         (and:SI (match_operator:SI 3 "arm_comparison_operator"
9568                  [(match_operand:SI 1 "s_register_operand" "r")
9569                   (match_operand:SI 2 "arm_add_operand" "rIL")])
9570                 (match_operator:SI 6 "arm_comparison_operator"
9571                  [(match_operand:SI 4 "s_register_operand" "r")
9572                   (match_operand:SI 5 "arm_add_operand" "rIL")])))
9573    (clobber (reg:CC CC_REGNUM))]
9574   "TARGET_32BIT
9575    && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
9576        != CCmode)"
9577   "#"
9578   "TARGET_32BIT && reload_completed
9579    && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
9580        != CCmode)"
9581   [(set (match_dup 7)
9582         (compare
9583          (and:SI
9584           (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9585           (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9586          (const_int 0)))
9587    (set (match_dup 0) (ne:SI (match_dup 7) (const_int 0)))]
9588   "operands[7]
9589      = gen_rtx_REG (arm_select_dominance_cc_mode (operands[3], operands[6],
9590                                                   DOM_CC_X_AND_Y),
9591                     CC_REGNUM);"
9592   [(set_attr "conds" "clob")
9593    (set_attr "length" "16")
9594    (set_attr "type" "multiple")]
9597 ; If the above pattern is followed by a CMP insn, then the compare is 
9598 ; redundant, since we can rework the conditional instruction that follows.
9599 (define_insn_and_split "*and_scc_scc_cmp"
9600   [(set (match_operand 0 "dominant_cc_register" "")
9601         (compare (and:SI (match_operator:SI 3 "arm_comparison_operator"
9602                           [(match_operand:SI 1 "s_register_operand" "r")
9603                            (match_operand:SI 2 "arm_add_operand" "rIL")])
9604                          (match_operator:SI 6 "arm_comparison_operator"
9605                           [(match_operand:SI 4 "s_register_operand" "r")
9606                            (match_operand:SI 5 "arm_add_operand" "rIL")]))
9607                  (const_int 0)))
9608    (set (match_operand:SI 7 "s_register_operand" "=Ts")
9609         (and:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9610                 (match_op_dup 6 [(match_dup 4) (match_dup 5)])))]
9611   "TARGET_32BIT"
9612   "#"
9613   "TARGET_32BIT && reload_completed"
9614   [(set (match_dup 0)
9615         (compare
9616          (and:SI
9617           (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9618           (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9619          (const_int 0)))
9620    (set (match_dup 7) (ne:SI (match_dup 0) (const_int 0)))]
9621   ""
9622   [(set_attr "conds" "set")
9623    (set_attr "length" "16")
9624    (set_attr "type" "multiple")]
9627 ;; If there is no dominance in the comparison, then we can still save an
9628 ;; instruction in the AND case, since we can know that the second compare
9629 ;; need only zero the value if false (if true, then the value is already
9630 ;; correct).
9631 (define_insn_and_split "*and_scc_scc_nodom"
9632   [(set (match_operand:SI 0 "s_register_operand" "=&Ts,&Ts,&Ts")
9633         (and:SI (match_operator:SI 3 "arm_comparison_operator"
9634                  [(match_operand:SI 1 "s_register_operand" "r,r,0")
9635                   (match_operand:SI 2 "arm_add_operand" "rIL,0,rIL")])
9636                 (match_operator:SI 6 "arm_comparison_operator"
9637                  [(match_operand:SI 4 "s_register_operand" "r,r,r")
9638                   (match_operand:SI 5 "arm_add_operand" "rIL,rIL,rIL")])))
9639    (clobber (reg:CC CC_REGNUM))]
9640   "TARGET_32BIT
9641    && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
9642        == CCmode)"
9643   "#"
9644   "TARGET_32BIT && reload_completed"
9645   [(parallel [(set (match_dup 0)
9646                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
9647               (clobber (reg:CC CC_REGNUM))])
9648    (set (match_dup 7) (match_op_dup 8 [(match_dup 4) (match_dup 5)]))
9649    (set (match_dup 0)
9650         (if_then_else:SI (match_op_dup 6 [(match_dup 7) (const_int 0)])
9651                          (match_dup 0)
9652                          (const_int 0)))]
9653   "operands[7] = gen_rtx_REG (SELECT_CC_MODE (GET_CODE (operands[6]),
9654                                               operands[4], operands[5]),
9655                               CC_REGNUM);
9656    operands[8] = gen_rtx_COMPARE (GET_MODE (operands[7]), operands[4],
9657                                   operands[5]);"
9658   [(set_attr "conds" "clob")
9659    (set_attr "length" "20")
9660    (set_attr "type" "multiple")]
9663 (define_split
9664   [(set (reg:CC_NOOV CC_REGNUM)
9665         (compare:CC_NOOV (ior:SI
9666                           (and:SI (match_operand:SI 0 "s_register_operand" "")
9667                                   (const_int 1))
9668                           (match_operator:SI 1 "arm_comparison_operator"
9669                            [(match_operand:SI 2 "s_register_operand" "")
9670                             (match_operand:SI 3 "arm_add_operand" "")]))
9671                          (const_int 0)))
9672    (clobber (match_operand:SI 4 "s_register_operand" ""))]
9673   "TARGET_ARM"
9674   [(set (match_dup 4)
9675         (ior:SI (match_op_dup 1 [(match_dup 2) (match_dup 3)])
9676                 (match_dup 0)))
9677    (set (reg:CC_NOOV CC_REGNUM)
9678         (compare:CC_NOOV (and:SI (match_dup 4) (const_int 1))
9679                          (const_int 0)))]
9680   "")
9682 (define_split
9683   [(set (reg:CC_NOOV CC_REGNUM)
9684         (compare:CC_NOOV (ior:SI
9685                           (match_operator:SI 1 "arm_comparison_operator"
9686                            [(match_operand:SI 2 "s_register_operand" "")
9687                             (match_operand:SI 3 "arm_add_operand" "")])
9688                           (and:SI (match_operand:SI 0 "s_register_operand" "")
9689                                   (const_int 1)))
9690                          (const_int 0)))
9691    (clobber (match_operand:SI 4 "s_register_operand" ""))]
9692   "TARGET_ARM"
9693   [(set (match_dup 4)
9694         (ior:SI (match_op_dup 1 [(match_dup 2) (match_dup 3)])
9695                 (match_dup 0)))
9696    (set (reg:CC_NOOV CC_REGNUM)
9697         (compare:CC_NOOV (and:SI (match_dup 4) (const_int 1))
9698                          (const_int 0)))]
9699   "")
9700 ;; ??? The conditional patterns above need checking for Thumb-2 usefulness
9702 (define_insn_and_split "*negscc"
9703   [(set (match_operand:SI 0 "s_register_operand" "=r")
9704         (neg:SI (match_operator 3 "arm_comparison_operator"
9705                  [(match_operand:SI 1 "s_register_operand" "r")
9706                   (match_operand:SI 2 "arm_rhs_operand" "rI")])))
9707    (clobber (reg:CC CC_REGNUM))]
9708   "TARGET_ARM"
9709   "#"
9710   "&& reload_completed"
9711   [(const_int 0)]
9712   {
9713     rtx cc_reg = gen_rtx_REG (CCmode, CC_REGNUM);
9715     if (GET_CODE (operands[3]) == LT && operands[2] == const0_rtx)
9716        {
9717          /* Emit mov\\t%0, %1, asr #31 */
9718          emit_insn (gen_rtx_SET (operands[0],
9719                                  gen_rtx_ASHIFTRT (SImode,
9720                                                    operands[1],
9721                                                    GEN_INT (31))));
9722          DONE;
9723        }
9724      else if (GET_CODE (operands[3]) == NE)
9725        {
9726         /* Emit subs\\t%0, %1, %2\;mvnne\\t%0, #0 */
9727         if (CONST_INT_P (operands[2]))
9728           emit_insn (gen_cmpsi2_addneg (operands[0], operands[1], operands[2],
9729                                         GEN_INT (- INTVAL (operands[2]))));
9730         else
9731           emit_insn (gen_subsi3_compare (operands[0], operands[1], operands[2]));
9733         emit_insn (gen_rtx_COND_EXEC (VOIDmode,
9734                                       gen_rtx_NE (SImode,
9735                                                   cc_reg,
9736                                                   const0_rtx),
9737                                       gen_rtx_SET (operands[0],
9738                                                    GEN_INT (~0))));
9739         DONE;
9740       }
9741     else
9742       {
9743         /* Emit: cmp\\t%1, %2\;mov%D3\\t%0, #0\;mvn%d3\\t%0, #0 */
9744         emit_insn (gen_rtx_SET (cc_reg,
9745                                 gen_rtx_COMPARE (CCmode, operands[1], operands[2])));
9746         enum rtx_code rc = GET_CODE (operands[3]);
9748         rc = reverse_condition (rc);
9749         emit_insn (gen_rtx_COND_EXEC (VOIDmode,
9750                                       gen_rtx_fmt_ee (rc,
9751                                                       VOIDmode,
9752                                                       cc_reg,
9753                                                       const0_rtx),
9754                                       gen_rtx_SET (operands[0], const0_rtx)));
9755         rc = GET_CODE (operands[3]);
9756         emit_insn (gen_rtx_COND_EXEC (VOIDmode,
9757                                       gen_rtx_fmt_ee (rc,
9758                                                       VOIDmode,
9759                                                       cc_reg,
9760                                                       const0_rtx),
9761                                       gen_rtx_SET (operands[0],
9762                                                    GEN_INT (~0))));
9763         DONE;
9764       }
9765      FAIL;
9766   }
9767   [(set_attr "conds" "clob")
9768    (set_attr "length" "12")
9769    (set_attr "type" "multiple")]
9772 (define_insn_and_split "movcond_addsi"
9773   [(set (match_operand:SI 0 "s_register_operand" "=r,l,r")
9774         (if_then_else:SI
9775          (match_operator 5 "comparison_operator"
9776           [(plus:SI (match_operand:SI 3 "s_register_operand" "r,r,r")
9777                     (match_operand:SI 4 "arm_add_operand" "rIL,rIL,rIL"))
9778             (const_int 0)])
9779          (match_operand:SI 1 "arm_rhs_operand" "rI,rPy,r")
9780          (match_operand:SI 2 "arm_rhs_operand" "rI,rPy,r")))
9781    (clobber (reg:CC CC_REGNUM))]
9782    "TARGET_32BIT"
9783    "#"
9784    "&& reload_completed"
9785   [(set (reg:CC_NOOV CC_REGNUM)
9786         (compare:CC_NOOV
9787          (plus:SI (match_dup 3)
9788                   (match_dup 4))
9789          (const_int 0)))
9790    (set (match_dup 0) (match_dup 1))
9791    (cond_exec (match_dup 6)
9792               (set (match_dup 0) (match_dup 2)))]
9793   "
9794   {
9795     machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[5]),
9796                                              operands[3], operands[4]);
9797     enum rtx_code rc = GET_CODE (operands[5]);
9798     operands[6] = gen_rtx_REG (mode, CC_REGNUM);
9799     gcc_assert (!(mode == CCFPmode || mode == CCFPEmode));
9800     if (!REG_P (operands[2]) || REGNO (operands[2]) != REGNO (operands[0]))
9801       rc = reverse_condition (rc);
9802     else
9803       std::swap (operands[1], operands[2]);
9805     operands[6] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
9806   }
9807   "
9808   [(set_attr "conds" "clob")
9809    (set_attr "enabled_for_depr_it" "no,yes,yes")
9810    (set_attr "type" "multiple")]
9813 (define_insn "movcond"
9814   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9815         (if_then_else:SI
9816          (match_operator 5 "arm_comparison_operator"
9817           [(match_operand:SI 3 "s_register_operand" "r,r,r")
9818            (match_operand:SI 4 "arm_add_operand" "rIL,rIL,rIL")])
9819          (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
9820          (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
9821    (clobber (reg:CC CC_REGNUM))]
9822   "TARGET_ARM"
9823   "*
9824   if (GET_CODE (operands[5]) == LT
9825       && (operands[4] == const0_rtx))
9826     {
9827       if (which_alternative != 1 && REG_P (operands[1]))
9828         {
9829           if (operands[2] == const0_rtx)
9830             return \"and\\t%0, %1, %3, asr #31\";
9831           return \"ands\\t%0, %1, %3, asr #32\;movcc\\t%0, %2\";
9832         }
9833       else if (which_alternative != 0 && REG_P (operands[2]))
9834         {
9835           if (operands[1] == const0_rtx)
9836             return \"bic\\t%0, %2, %3, asr #31\";
9837           return \"bics\\t%0, %2, %3, asr #32\;movcs\\t%0, %1\";
9838         }
9839       /* The only case that falls through to here is when both ops 1 & 2
9840          are constants.  */
9841     }
9843   if (GET_CODE (operands[5]) == GE
9844       && (operands[4] == const0_rtx))
9845     {
9846       if (which_alternative != 1 && REG_P (operands[1]))
9847         {
9848           if (operands[2] == const0_rtx)
9849             return \"bic\\t%0, %1, %3, asr #31\";
9850           return \"bics\\t%0, %1, %3, asr #32\;movcs\\t%0, %2\";
9851         }
9852       else if (which_alternative != 0 && REG_P (operands[2]))
9853         {
9854           if (operands[1] == const0_rtx)
9855             return \"and\\t%0, %2, %3, asr #31\";
9856           return \"ands\\t%0, %2, %3, asr #32\;movcc\\t%0, %1\";
9857         }
9858       /* The only case that falls through to here is when both ops 1 & 2
9859          are constants.  */
9860     }
9861   if (CONST_INT_P (operands[4])
9862       && !const_ok_for_arm (INTVAL (operands[4])))
9863     output_asm_insn (\"cmn\\t%3, #%n4\", operands);
9864   else
9865     output_asm_insn (\"cmp\\t%3, %4\", operands);
9866   if (which_alternative != 0)
9867     output_asm_insn (\"mov%d5\\t%0, %1\", operands);
9868   if (which_alternative != 1)
9869     output_asm_insn (\"mov%D5\\t%0, %2\", operands);
9870   return \"\";
9871   "
9872   [(set_attr "conds" "clob")
9873    (set_attr "length" "8,8,12")
9874    (set_attr "type" "multiple")]
9877 ;; ??? The patterns below need checking for Thumb-2 usefulness.
9879 (define_insn "*ifcompare_plus_move"
9880   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9881         (if_then_else:SI (match_operator 6 "arm_comparison_operator"
9882                           [(match_operand:SI 4 "s_register_operand" "r,r")
9883                            (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
9884                          (plus:SI
9885                           (match_operand:SI 2 "s_register_operand" "r,r")
9886                           (match_operand:SI 3 "arm_add_operand" "rIL,rIL"))
9887                          (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))
9888    (clobber (reg:CC CC_REGNUM))]
9889   "TARGET_ARM"
9890   "#"
9891   [(set_attr "conds" "clob")
9892    (set_attr "length" "8,12")
9893    (set_attr "type" "multiple")]
9896 (define_insn "*if_plus_move"
9897   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
9898         (if_then_else:SI
9899          (match_operator 4 "arm_comparison_operator"
9900           [(match_operand 5 "cc_register" "") (const_int 0)])
9901          (plus:SI
9902           (match_operand:SI 2 "s_register_operand" "r,r,r,r")
9903           (match_operand:SI 3 "arm_add_operand" "rI,L,rI,L"))
9904          (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")))]
9905   "TARGET_ARM"
9906   "@
9907    add%d4\\t%0, %2, %3
9908    sub%d4\\t%0, %2, #%n3
9909    add%d4\\t%0, %2, %3\;mov%D4\\t%0, %1
9910    sub%d4\\t%0, %2, #%n3\;mov%D4\\t%0, %1"
9911   [(set_attr "conds" "use")
9912    (set_attr "length" "4,4,8,8")
9913    (set_attr_alternative "type"
9914                          [(if_then_else (match_operand 3 "const_int_operand" "")
9915                                         (const_string "alu_imm" )
9916                                         (const_string "alu_sreg"))
9917                           (const_string "alu_imm")
9918                           (const_string "multiple")
9919                           (const_string "multiple")])]
9922 (define_insn "*ifcompare_move_plus"
9923   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9924         (if_then_else:SI (match_operator 6 "arm_comparison_operator"
9925                           [(match_operand:SI 4 "s_register_operand" "r,r")
9926                            (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
9927                          (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
9928                          (plus:SI
9929                           (match_operand:SI 2 "s_register_operand" "r,r")
9930                           (match_operand:SI 3 "arm_add_operand" "rIL,rIL"))))
9931    (clobber (reg:CC CC_REGNUM))]
9932   "TARGET_ARM"
9933   "#"
9934   [(set_attr "conds" "clob")
9935    (set_attr "length" "8,12")
9936    (set_attr "type" "multiple")]
9939 (define_insn "*if_move_plus"
9940   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
9941         (if_then_else:SI
9942          (match_operator 4 "arm_comparison_operator"
9943           [(match_operand 5 "cc_register" "") (const_int 0)])
9944          (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")
9945          (plus:SI
9946           (match_operand:SI 2 "s_register_operand" "r,r,r,r")
9947           (match_operand:SI 3 "arm_add_operand" "rI,L,rI,L"))))]
9948   "TARGET_ARM"
9949   "@
9950    add%D4\\t%0, %2, %3
9951    sub%D4\\t%0, %2, #%n3
9952    add%D4\\t%0, %2, %3\;mov%d4\\t%0, %1
9953    sub%D4\\t%0, %2, #%n3\;mov%d4\\t%0, %1"
9954   [(set_attr "conds" "use")
9955    (set_attr "length" "4,4,8,8")
9956    (set_attr_alternative "type"
9957                          [(if_then_else (match_operand 3 "const_int_operand" "")
9958                                         (const_string "alu_imm" )
9959                                         (const_string "alu_sreg"))
9960                           (const_string "alu_imm")
9961                           (const_string "multiple")
9962                           (const_string "multiple")])]
9965 (define_insn "*ifcompare_arith_arith"
9966   [(set (match_operand:SI 0 "s_register_operand" "=r")
9967         (if_then_else:SI (match_operator 9 "arm_comparison_operator"
9968                           [(match_operand:SI 5 "s_register_operand" "r")
9969                            (match_operand:SI 6 "arm_add_operand" "rIL")])
9970                          (match_operator:SI 8 "shiftable_operator"
9971                           [(match_operand:SI 1 "s_register_operand" "r")
9972                            (match_operand:SI 2 "arm_rhs_operand" "rI")])
9973                          (match_operator:SI 7 "shiftable_operator"
9974                           [(match_operand:SI 3 "s_register_operand" "r")
9975                            (match_operand:SI 4 "arm_rhs_operand" "rI")])))
9976    (clobber (reg:CC CC_REGNUM))]
9977   "TARGET_ARM"
9978   "#"
9979   [(set_attr "conds" "clob")
9980    (set_attr "length" "12")
9981    (set_attr "type" "multiple")]
9984 (define_insn "*if_arith_arith"
9985   [(set (match_operand:SI 0 "s_register_operand" "=r")
9986         (if_then_else:SI (match_operator 5 "arm_comparison_operator"
9987                           [(match_operand 8 "cc_register" "") (const_int 0)])
9988                          (match_operator:SI 6 "shiftable_operator"
9989                           [(match_operand:SI 1 "s_register_operand" "r")
9990                            (match_operand:SI 2 "arm_rhs_operand" "rI")])
9991                          (match_operator:SI 7 "shiftable_operator"
9992                           [(match_operand:SI 3 "s_register_operand" "r")
9993                            (match_operand:SI 4 "arm_rhs_operand" "rI")])))]
9994   "TARGET_ARM"
9995   "%I6%d5\\t%0, %1, %2\;%I7%D5\\t%0, %3, %4"
9996   [(set_attr "conds" "use")
9997    (set_attr "length" "8")
9998    (set_attr "type" "multiple")]
10001 (define_insn "*ifcompare_arith_move"
10002   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10003         (if_then_else:SI (match_operator 6 "arm_comparison_operator"
10004                           [(match_operand:SI 2 "s_register_operand" "r,r")
10005                            (match_operand:SI 3 "arm_add_operand" "rIL,rIL")])
10006                          (match_operator:SI 7 "shiftable_operator"
10007                           [(match_operand:SI 4 "s_register_operand" "r,r")
10008                            (match_operand:SI 5 "arm_rhs_operand" "rI,rI")])
10009                          (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))
10010    (clobber (reg:CC CC_REGNUM))]
10011   "TARGET_ARM"
10012   "*
10013   /* If we have an operation where (op x 0) is the identity operation and
10014      the conditional operator is LT or GE and we are comparing against zero and
10015      everything is in registers then we can do this in two instructions.  */
10016   if (operands[3] == const0_rtx
10017       && GET_CODE (operands[7]) != AND
10018       && REG_P (operands[5])
10019       && REG_P (operands[1])
10020       && REGNO (operands[1]) == REGNO (operands[4])
10021       && REGNO (operands[4]) != REGNO (operands[0]))
10022     {
10023       if (GET_CODE (operands[6]) == LT)
10024         return \"and\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\";
10025       else if (GET_CODE (operands[6]) == GE)
10026         return \"bic\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\";
10027     }
10028   if (CONST_INT_P (operands[3])
10029       && !const_ok_for_arm (INTVAL (operands[3])))
10030     output_asm_insn (\"cmn\\t%2, #%n3\", operands);
10031   else
10032     output_asm_insn (\"cmp\\t%2, %3\", operands);
10033   output_asm_insn (\"%I7%d6\\t%0, %4, %5\", operands);
10034   if (which_alternative != 0)
10035     return \"mov%D6\\t%0, %1\";
10036   return \"\";
10037   "
10038   [(set_attr "conds" "clob")
10039    (set_attr "length" "8,12")
10040    (set_attr "type" "multiple")]
10043 (define_insn "*if_arith_move"
10044   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10045         (if_then_else:SI (match_operator 4 "arm_comparison_operator"
10046                           [(match_operand 6 "cc_register" "") (const_int 0)])
10047                          (match_operator:SI 5 "shiftable_operator"
10048                           [(match_operand:SI 2 "s_register_operand" "r,r")
10049                            (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
10050                          (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))]
10051   "TARGET_ARM"
10052   "@
10053    %I5%d4\\t%0, %2, %3
10054    %I5%d4\\t%0, %2, %3\;mov%D4\\t%0, %1"
10055   [(set_attr "conds" "use")
10056    (set_attr "length" "4,8")
10057    (set_attr_alternative "type"
10058                          [(if_then_else (match_operand 3 "const_int_operand" "")
10059                                         (const_string "alu_shift_imm" )
10060                                         (const_string "alu_shift_reg"))
10061                           (const_string "multiple")])]
10064 (define_insn "*ifcompare_move_arith"
10065   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10066         (if_then_else:SI (match_operator 6 "arm_comparison_operator"
10067                           [(match_operand:SI 4 "s_register_operand" "r,r")
10068                            (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
10069                          (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
10070                          (match_operator:SI 7 "shiftable_operator"
10071                           [(match_operand:SI 2 "s_register_operand" "r,r")
10072                            (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
10073    (clobber (reg:CC CC_REGNUM))]
10074   "TARGET_ARM"
10075   "*
10076   /* If we have an operation where (op x 0) is the identity operation and
10077      the conditional operator is LT or GE and we are comparing against zero and
10078      everything is in registers then we can do this in two instructions */
10079   if (operands[5] == const0_rtx
10080       && GET_CODE (operands[7]) != AND
10081       && REG_P (operands[3])
10082       && REG_P (operands[1])
10083       && REGNO (operands[1]) == REGNO (operands[2])
10084       && REGNO (operands[2]) != REGNO (operands[0]))
10085     {
10086       if (GET_CODE (operands[6]) == GE)
10087         return \"and\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\";
10088       else if (GET_CODE (operands[6]) == LT)
10089         return \"bic\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\";
10090     }
10092   if (CONST_INT_P (operands[5])
10093       && !const_ok_for_arm (INTVAL (operands[5])))
10094     output_asm_insn (\"cmn\\t%4, #%n5\", operands);
10095   else
10096     output_asm_insn (\"cmp\\t%4, %5\", operands);
10098   if (which_alternative != 0)
10099     output_asm_insn (\"mov%d6\\t%0, %1\", operands);
10100   return \"%I7%D6\\t%0, %2, %3\";
10101   "
10102   [(set_attr "conds" "clob")
10103    (set_attr "length" "8,12")
10104    (set_attr "type" "multiple")]
10107 (define_insn "*if_move_arith"
10108   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10109         (if_then_else:SI
10110          (match_operator 4 "arm_comparison_operator"
10111           [(match_operand 6 "cc_register" "") (const_int 0)])
10112          (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
10113          (match_operator:SI 5 "shiftable_operator"
10114           [(match_operand:SI 2 "s_register_operand" "r,r")
10115            (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))]
10116   "TARGET_ARM"
10117   "@
10118    %I5%D4\\t%0, %2, %3
10119    %I5%D4\\t%0, %2, %3\;mov%d4\\t%0, %1"
10120   [(set_attr "conds" "use")
10121    (set_attr "length" "4,8")
10122    (set_attr_alternative "type"
10123                          [(if_then_else (match_operand 3 "const_int_operand" "")
10124                                         (const_string "alu_shift_imm" )
10125                                         (const_string "alu_shift_reg"))
10126                           (const_string "multiple")])]
10129 (define_insn "*ifcompare_move_not"
10130   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10131         (if_then_else:SI
10132          (match_operator 5 "arm_comparison_operator"
10133           [(match_operand:SI 3 "s_register_operand" "r,r")
10134            (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
10135          (match_operand:SI 1 "arm_not_operand" "0,?rIK")
10136          (not:SI
10137           (match_operand:SI 2 "s_register_operand" "r,r"))))
10138    (clobber (reg:CC CC_REGNUM))]
10139   "TARGET_ARM"
10140   "#"
10141   [(set_attr "conds" "clob")
10142    (set_attr "length" "8,12")
10143    (set_attr "type" "multiple")]
10146 (define_insn "*if_move_not"
10147   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
10148         (if_then_else:SI
10149          (match_operator 4 "arm_comparison_operator"
10150           [(match_operand 3 "cc_register" "") (const_int 0)])
10151          (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
10152          (not:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))))]
10153   "TARGET_ARM"
10154   "@
10155    mvn%D4\\t%0, %2
10156    mov%d4\\t%0, %1\;mvn%D4\\t%0, %2
10157    mvn%d4\\t%0, #%B1\;mvn%D4\\t%0, %2"
10158   [(set_attr "conds" "use")
10159    (set_attr "type" "mvn_reg")
10160    (set_attr "length" "4,8,8")
10161    (set_attr "type" "mvn_reg,multiple,multiple")]
10164 (define_insn "*ifcompare_not_move"
10165   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10166         (if_then_else:SI 
10167          (match_operator 5 "arm_comparison_operator"
10168           [(match_operand:SI 3 "s_register_operand" "r,r")
10169            (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
10170          (not:SI
10171           (match_operand:SI 2 "s_register_operand" "r,r"))
10172          (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
10173    (clobber (reg:CC CC_REGNUM))]
10174   "TARGET_ARM"
10175   "#"
10176   [(set_attr "conds" "clob")
10177    (set_attr "length" "8,12")
10178    (set_attr "type" "multiple")]
10181 (define_insn "*if_not_move"
10182   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
10183         (if_then_else:SI
10184          (match_operator 4 "arm_comparison_operator"
10185           [(match_operand 3 "cc_register" "") (const_int 0)])
10186          (not:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))
10187          (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
10188   "TARGET_ARM"
10189   "@
10190    mvn%d4\\t%0, %2
10191    mov%D4\\t%0, %1\;mvn%d4\\t%0, %2
10192    mvn%D4\\t%0, #%B1\;mvn%d4\\t%0, %2"
10193   [(set_attr "conds" "use")
10194    (set_attr "type" "mvn_reg,multiple,multiple")
10195    (set_attr "length" "4,8,8")]
10198 (define_insn "*ifcompare_shift_move"
10199   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10200         (if_then_else:SI
10201          (match_operator 6 "arm_comparison_operator"
10202           [(match_operand:SI 4 "s_register_operand" "r,r")
10203            (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
10204          (match_operator:SI 7 "shift_operator"
10205           [(match_operand:SI 2 "s_register_operand" "r,r")
10206            (match_operand:SI 3 "arm_rhs_operand" "rM,rM")])
10207          (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
10208    (clobber (reg:CC CC_REGNUM))]
10209   "TARGET_ARM"
10210   "#"
10211   [(set_attr "conds" "clob")
10212    (set_attr "length" "8,12")
10213    (set_attr "type" "multiple")]
10216 (define_insn "*if_shift_move"
10217   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
10218         (if_then_else:SI
10219          (match_operator 5 "arm_comparison_operator"
10220           [(match_operand 6 "cc_register" "") (const_int 0)])
10221          (match_operator:SI 4 "shift_operator"
10222           [(match_operand:SI 2 "s_register_operand" "r,r,r")
10223            (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM")])
10224          (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
10225   "TARGET_ARM"
10226   "@
10227    mov%d5\\t%0, %2%S4
10228    mov%D5\\t%0, %1\;mov%d5\\t%0, %2%S4
10229    mvn%D5\\t%0, #%B1\;mov%d5\\t%0, %2%S4"
10230   [(set_attr "conds" "use")
10231    (set_attr "shift" "2")
10232    (set_attr "length" "4,8,8")
10233    (set_attr_alternative "type"
10234                          [(if_then_else (match_operand 3 "const_int_operand" "")
10235                                         (const_string "mov_shift" )
10236                                         (const_string "mov_shift_reg"))
10237                           (const_string "multiple")
10238                           (const_string "multiple")])]
10241 (define_insn "*ifcompare_move_shift"
10242   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10243         (if_then_else:SI
10244          (match_operator 6 "arm_comparison_operator"
10245           [(match_operand:SI 4 "s_register_operand" "r,r")
10246            (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
10247          (match_operand:SI 1 "arm_not_operand" "0,?rIK")
10248          (match_operator:SI 7 "shift_operator"
10249           [(match_operand:SI 2 "s_register_operand" "r,r")
10250            (match_operand:SI 3 "arm_rhs_operand" "rM,rM")])))
10251    (clobber (reg:CC CC_REGNUM))]
10252   "TARGET_ARM"
10253   "#"
10254   [(set_attr "conds" "clob")
10255    (set_attr "length" "8,12")
10256    (set_attr "type" "multiple")]
10259 (define_insn "*if_move_shift"
10260   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
10261         (if_then_else:SI
10262          (match_operator 5 "arm_comparison_operator"
10263           [(match_operand 6 "cc_register" "") (const_int 0)])
10264          (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
10265          (match_operator:SI 4 "shift_operator"
10266           [(match_operand:SI 2 "s_register_operand" "r,r,r")
10267            (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM")])))]
10268   "TARGET_ARM"
10269   "@
10270    mov%D5\\t%0, %2%S4
10271    mov%d5\\t%0, %1\;mov%D5\\t%0, %2%S4
10272    mvn%d5\\t%0, #%B1\;mov%D5\\t%0, %2%S4"
10273   [(set_attr "conds" "use")
10274    (set_attr "shift" "2")
10275    (set_attr "length" "4,8,8")
10276    (set_attr_alternative "type"
10277                          [(if_then_else (match_operand 3 "const_int_operand" "")
10278                                         (const_string "mov_shift" )
10279                                         (const_string "mov_shift_reg"))
10280                           (const_string "multiple")
10281                           (const_string "multiple")])]
10284 (define_insn "*ifcompare_shift_shift"
10285   [(set (match_operand:SI 0 "s_register_operand" "=r")
10286         (if_then_else:SI
10287          (match_operator 7 "arm_comparison_operator"
10288           [(match_operand:SI 5 "s_register_operand" "r")
10289            (match_operand:SI 6 "arm_add_operand" "rIL")])
10290          (match_operator:SI 8 "shift_operator"
10291           [(match_operand:SI 1 "s_register_operand" "r")
10292            (match_operand:SI 2 "arm_rhs_operand" "rM")])
10293          (match_operator:SI 9 "shift_operator"
10294           [(match_operand:SI 3 "s_register_operand" "r")
10295            (match_operand:SI 4 "arm_rhs_operand" "rM")])))
10296    (clobber (reg:CC CC_REGNUM))]
10297   "TARGET_ARM"
10298   "#"
10299   [(set_attr "conds" "clob")
10300    (set_attr "length" "12")
10301    (set_attr "type" "multiple")]
10304 (define_insn "*if_shift_shift"
10305   [(set (match_operand:SI 0 "s_register_operand" "=r")
10306         (if_then_else:SI
10307          (match_operator 5 "arm_comparison_operator"
10308           [(match_operand 8 "cc_register" "") (const_int 0)])
10309          (match_operator:SI 6 "shift_operator"
10310           [(match_operand:SI 1 "s_register_operand" "r")
10311            (match_operand:SI 2 "arm_rhs_operand" "rM")])
10312          (match_operator:SI 7 "shift_operator"
10313           [(match_operand:SI 3 "s_register_operand" "r")
10314            (match_operand:SI 4 "arm_rhs_operand" "rM")])))]
10315   "TARGET_ARM"
10316   "mov%d5\\t%0, %1%S6\;mov%D5\\t%0, %3%S7"
10317   [(set_attr "conds" "use")
10318    (set_attr "shift" "1")
10319    (set_attr "length" "8")
10320    (set (attr "type") (if_then_else
10321                         (and (match_operand 2 "const_int_operand" "")
10322                              (match_operand 4 "const_int_operand" ""))
10323                       (const_string "mov_shift")
10324                       (const_string "mov_shift_reg")))]
10327 (define_insn "*ifcompare_not_arith"
10328   [(set (match_operand:SI 0 "s_register_operand" "=r")
10329         (if_then_else:SI
10330          (match_operator 6 "arm_comparison_operator"
10331           [(match_operand:SI 4 "s_register_operand" "r")
10332            (match_operand:SI 5 "arm_add_operand" "rIL")])
10333          (not:SI (match_operand:SI 1 "s_register_operand" "r"))
10334          (match_operator:SI 7 "shiftable_operator"
10335           [(match_operand:SI 2 "s_register_operand" "r")
10336            (match_operand:SI 3 "arm_rhs_operand" "rI")])))
10337    (clobber (reg:CC CC_REGNUM))]
10338   "TARGET_ARM"
10339   "#"
10340   [(set_attr "conds" "clob")
10341    (set_attr "length" "12")
10342    (set_attr "type" "multiple")]
10345 (define_insn "*if_not_arith"
10346   [(set (match_operand:SI 0 "s_register_operand" "=r")
10347         (if_then_else:SI
10348          (match_operator 5 "arm_comparison_operator"
10349           [(match_operand 4 "cc_register" "") (const_int 0)])
10350          (not:SI (match_operand:SI 1 "s_register_operand" "r"))
10351          (match_operator:SI 6 "shiftable_operator"
10352           [(match_operand:SI 2 "s_register_operand" "r")
10353            (match_operand:SI 3 "arm_rhs_operand" "rI")])))]
10354   "TARGET_ARM"
10355   "mvn%d5\\t%0, %1\;%I6%D5\\t%0, %2, %3"
10356   [(set_attr "conds" "use")
10357    (set_attr "type" "mvn_reg")
10358    (set_attr "length" "8")]
10361 (define_insn "*ifcompare_arith_not"
10362   [(set (match_operand:SI 0 "s_register_operand" "=r")
10363         (if_then_else:SI
10364          (match_operator 6 "arm_comparison_operator"
10365           [(match_operand:SI 4 "s_register_operand" "r")
10366            (match_operand:SI 5 "arm_add_operand" "rIL")])
10367          (match_operator:SI 7 "shiftable_operator"
10368           [(match_operand:SI 2 "s_register_operand" "r")
10369            (match_operand:SI 3 "arm_rhs_operand" "rI")])
10370          (not:SI (match_operand:SI 1 "s_register_operand" "r"))))
10371    (clobber (reg:CC CC_REGNUM))]
10372   "TARGET_ARM"
10373   "#"
10374   [(set_attr "conds" "clob")
10375    (set_attr "length" "12")
10376    (set_attr "type" "multiple")]
10379 (define_insn "*if_arith_not"
10380   [(set (match_operand:SI 0 "s_register_operand" "=r")
10381         (if_then_else:SI
10382          (match_operator 5 "arm_comparison_operator"
10383           [(match_operand 4 "cc_register" "") (const_int 0)])
10384          (match_operator:SI 6 "shiftable_operator"
10385           [(match_operand:SI 2 "s_register_operand" "r")
10386            (match_operand:SI 3 "arm_rhs_operand" "rI")])
10387          (not:SI (match_operand:SI 1 "s_register_operand" "r"))))]
10388   "TARGET_ARM"
10389   "mvn%D5\\t%0, %1\;%I6%d5\\t%0, %2, %3"
10390   [(set_attr "conds" "use")
10391    (set_attr "type" "multiple")
10392    (set_attr "length" "8")]
10395 (define_insn "*ifcompare_neg_move"
10396   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10397         (if_then_else:SI
10398          (match_operator 5 "arm_comparison_operator"
10399           [(match_operand:SI 3 "s_register_operand" "r,r")
10400            (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
10401          (neg:SI (match_operand:SI 2 "s_register_operand" "r,r"))
10402          (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
10403    (clobber (reg:CC CC_REGNUM))]
10404   "TARGET_ARM"
10405   "#"
10406   [(set_attr "conds" "clob")
10407    (set_attr "length" "8,12")
10408    (set_attr "type" "multiple")]
10411 (define_insn_and_split "*if_neg_move"
10412   [(set (match_operand:SI 0 "s_register_operand" "=l,r")
10413         (if_then_else:SI
10414          (match_operator 4 "arm_comparison_operator"
10415           [(match_operand 3 "cc_register" "") (const_int 0)])
10416          (neg:SI (match_operand:SI 2 "s_register_operand" "l,r"))
10417          (match_operand:SI 1 "s_register_operand" "0,0")))]
10418   "TARGET_32BIT"
10419   "#"
10420   "&& reload_completed"
10421   [(cond_exec (match_op_dup 4 [(match_dup 3) (const_int 0)])
10422               (set (match_dup 0) (neg:SI (match_dup 2))))]
10423   ""
10424   [(set_attr "conds" "use")
10425    (set_attr "length" "4")
10426    (set_attr "arch" "t2,32")
10427    (set_attr "enabled_for_depr_it" "yes,no")
10428    (set_attr "type" "logic_shift_imm")]
10431 (define_insn "*ifcompare_move_neg"
10432   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10433         (if_then_else:SI
10434          (match_operator 5 "arm_comparison_operator"
10435           [(match_operand:SI 3 "s_register_operand" "r,r")
10436            (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
10437          (match_operand:SI 1 "arm_not_operand" "0,?rIK")
10438          (neg:SI (match_operand:SI 2 "s_register_operand" "r,r"))))
10439    (clobber (reg:CC CC_REGNUM))]
10440   "TARGET_ARM"
10441   "#"
10442   [(set_attr "conds" "clob")
10443    (set_attr "length" "8,12")
10444    (set_attr "type" "multiple")]
10447 (define_insn_and_split "*if_move_neg"
10448   [(set (match_operand:SI 0 "s_register_operand" "=l,r")
10449         (if_then_else:SI
10450          (match_operator 4 "arm_comparison_operator"
10451           [(match_operand 3 "cc_register" "") (const_int 0)])
10452          (match_operand:SI 1 "s_register_operand" "0,0")
10453          (neg:SI (match_operand:SI 2 "s_register_operand" "l,r"))))]
10454   "TARGET_32BIT"
10455   "#"
10456   "&& reload_completed"
10457   [(cond_exec (match_dup 5)
10458               (set (match_dup 0) (neg:SI (match_dup 2))))]
10459   {
10460     machine_mode mode = GET_MODE (operands[3]);
10461     rtx_code rc = GET_CODE (operands[4]);
10463     if (mode == CCFPmode || mode == CCFPEmode)
10464       rc = reverse_condition_maybe_unordered (rc);
10465     else
10466       rc = reverse_condition (rc);
10468     operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[3], const0_rtx);
10469   }
10470   [(set_attr "conds" "use")
10471    (set_attr "length" "4")
10472    (set_attr "arch" "t2,32")
10473    (set_attr "enabled_for_depr_it" "yes,no")
10474    (set_attr "type" "logic_shift_imm")]
10477 (define_insn "*arith_adjacentmem"
10478   [(set (match_operand:SI 0 "s_register_operand" "=r")
10479         (match_operator:SI 1 "shiftable_operator"
10480          [(match_operand:SI 2 "memory_operand" "m")
10481           (match_operand:SI 3 "memory_operand" "m")]))
10482    (clobber (match_scratch:SI 4 "=r"))]
10483   "TARGET_ARM && adjacent_mem_locations (operands[2], operands[3])"
10484   "*
10485   {
10486     rtx ldm[3];
10487     rtx arith[4];
10488     rtx base_reg;
10489     HOST_WIDE_INT val1 = 0, val2 = 0;
10491     if (REGNO (operands[0]) > REGNO (operands[4]))
10492       {
10493         ldm[1] = operands[4];
10494         ldm[2] = operands[0];
10495       }
10496     else
10497       {
10498         ldm[1] = operands[0];
10499         ldm[2] = operands[4];
10500       }
10502     base_reg = XEXP (operands[2], 0);
10504     if (!REG_P (base_reg))
10505       {
10506         val1 = INTVAL (XEXP (base_reg, 1));
10507         base_reg = XEXP (base_reg, 0);
10508       }
10510     if (!REG_P (XEXP (operands[3], 0)))
10511       val2 = INTVAL (XEXP (XEXP (operands[3], 0), 1));
10513     arith[0] = operands[0];
10514     arith[3] = operands[1];
10516     if (val1 < val2)
10517       {
10518         arith[1] = ldm[1];
10519         arith[2] = ldm[2];
10520       }
10521     else
10522       {
10523         arith[1] = ldm[2];
10524         arith[2] = ldm[1];
10525       }
10527     ldm[0] = base_reg;
10528     if (val1 !=0 && val2 != 0)
10529       {
10530         rtx ops[3];
10532         if (val1 == 4 || val2 == 4)
10533           /* Other val must be 8, since we know they are adjacent and neither
10534              is zero.  */
10535           output_asm_insn (\"ldmib%?\\t%0, {%1, %2}\", ldm);
10536         else if (const_ok_for_arm (val1) || const_ok_for_arm (-val1))
10537           {
10538             ldm[0] = ops[0] = operands[4];
10539             ops[1] = base_reg;
10540             ops[2] = GEN_INT (val1);
10541             output_add_immediate (ops);
10542             if (val1 < val2)
10543               output_asm_insn (\"ldmia%?\\t%0, {%1, %2}\", ldm);
10544             else
10545               output_asm_insn (\"ldmda%?\\t%0, {%1, %2}\", ldm);
10546           }
10547         else
10548           {
10549             /* Offset is out of range for a single add, so use two ldr.  */
10550             ops[0] = ldm[1];
10551             ops[1] = base_reg;
10552             ops[2] = GEN_INT (val1);
10553             output_asm_insn (\"ldr%?\\t%0, [%1, %2]\", ops);
10554             ops[0] = ldm[2];
10555             ops[2] = GEN_INT (val2);
10556             output_asm_insn (\"ldr%?\\t%0, [%1, %2]\", ops);
10557           }
10558       }
10559     else if (val1 != 0)
10560       {
10561         if (val1 < val2)
10562           output_asm_insn (\"ldmda%?\\t%0, {%1, %2}\", ldm);
10563         else
10564           output_asm_insn (\"ldmia%?\\t%0, {%1, %2}\", ldm);
10565       }
10566     else
10567       {
10568         if (val1 < val2)
10569           output_asm_insn (\"ldmia%?\\t%0, {%1, %2}\", ldm);
10570         else
10571           output_asm_insn (\"ldmda%?\\t%0, {%1, %2}\", ldm);
10572       }
10573     output_asm_insn (\"%I3%?\\t%0, %1, %2\", arith);
10574     return \"\";
10575   }"
10576   [(set_attr "length" "12")
10577    (set_attr "predicable" "yes")
10578    (set_attr "type" "load1")]
10581 ; This pattern is never tried by combine, so do it as a peephole
10583 (define_peephole2
10584   [(set (match_operand:SI 0 "arm_general_register_operand" "")
10585         (match_operand:SI 1 "arm_general_register_operand" ""))
10586    (set (reg:CC CC_REGNUM)
10587         (compare:CC (match_dup 1) (const_int 0)))]
10588   "TARGET_ARM"
10589   [(parallel [(set (reg:CC CC_REGNUM) (compare:CC (match_dup 1) (const_int 0)))
10590               (set (match_dup 0) (match_dup 1))])]
10591   ""
10594 (define_split
10595   [(set (match_operand:SI 0 "s_register_operand" "")
10596         (and:SI (ge:SI (match_operand:SI 1 "s_register_operand" "")
10597                        (const_int 0))
10598                 (neg:SI (match_operator:SI 2 "arm_comparison_operator"
10599                          [(match_operand:SI 3 "s_register_operand" "")
10600                           (match_operand:SI 4 "arm_rhs_operand" "")]))))
10601    (clobber (match_operand:SI 5 "s_register_operand" ""))]
10602   "TARGET_ARM"
10603   [(set (match_dup 5) (not:SI (ashiftrt:SI (match_dup 1) (const_int 31))))
10604    (set (match_dup 0) (and:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
10605                               (match_dup 5)))]
10606   ""
10609 ;; This split can be used because CC_Z mode implies that the following
10610 ;; branch will be an equality, or an unsigned inequality, so the sign
10611 ;; extension is not needed.
10613 (define_split
10614   [(set (reg:CC_Z CC_REGNUM)
10615         (compare:CC_Z
10616          (ashift:SI (subreg:SI (match_operand:QI 0 "memory_operand" "") 0)
10617                     (const_int 24))
10618          (match_operand 1 "const_int_operand" "")))
10619    (clobber (match_scratch:SI 2 ""))]
10620   "TARGET_ARM
10621    && ((UINTVAL (operands[1]))
10622        == ((UINTVAL (operands[1])) >> 24) << 24)"
10623   [(set (match_dup 2) (zero_extend:SI (match_dup 0)))
10624    (set (reg:CC CC_REGNUM) (compare:CC (match_dup 2) (match_dup 1)))]
10625   "
10626   operands[1] = GEN_INT (((unsigned long) INTVAL (operands[1])) >> 24);
10627   "
10629 ;; ??? Check the patterns above for Thumb-2 usefulness
10631 (define_expand "prologue"
10632   [(clobber (const_int 0))]
10633   "TARGET_EITHER"
10634   "if (TARGET_32BIT)
10635      arm_expand_prologue ();
10636    else
10637      thumb1_expand_prologue ();
10638   DONE;
10639   "
10642 (define_expand "epilogue"
10643   [(clobber (const_int 0))]
10644   "TARGET_EITHER"
10645   "
10646   if (crtl->calls_eh_return)
10647     emit_insn (gen_force_register_use (gen_rtx_REG (Pmode, 2)));
10648   if (TARGET_THUMB1)
10649    {
10650      thumb1_expand_epilogue ();
10651      emit_jump_insn (gen_rtx_UNSPEC_VOLATILE (VOIDmode,
10652                      gen_rtvec (1, ret_rtx), VUNSPEC_EPILOGUE));
10653    }
10654   else if (HAVE_return)
10655    {
10656      /* HAVE_return is testing for USE_RETURN_INSN (FALSE).  Hence,
10657         no need for explicit testing again.  */
10658      emit_jump_insn (gen_return ());
10659    }
10660   else if (TARGET_32BIT)
10661    {
10662     arm_expand_epilogue (true);
10663    }
10664   DONE;
10665   "
10668 ;; Note - although unspec_volatile's USE all hard registers,
10669 ;; USEs are ignored after relaod has completed.  Thus we need
10670 ;; to add an unspec of the link register to ensure that flow
10671 ;; does not think that it is unused by the sibcall branch that
10672 ;; will replace the standard function epilogue.
10673 (define_expand "sibcall_epilogue"
10674    [(parallel [(unspec:SI [(reg:SI LR_REGNUM)] UNSPEC_REGISTER_USE)
10675                (unspec_volatile [(return)] VUNSPEC_EPILOGUE)])]
10676    "TARGET_32BIT"
10677    "
10678    arm_expand_epilogue (false);
10679    DONE;
10680    "
10683 (define_expand "eh_epilogue"
10684   [(use (match_operand:SI 0 "register_operand" ""))
10685    (use (match_operand:SI 1 "register_operand" ""))
10686    (use (match_operand:SI 2 "register_operand" ""))]
10687   "TARGET_EITHER"
10688   "
10689   {
10690     cfun->machine->eh_epilogue_sp_ofs = operands[1];
10691     if (!REG_P (operands[2]) || REGNO (operands[2]) != 2)
10692       {
10693         rtx ra = gen_rtx_REG (Pmode, 2);
10695         emit_move_insn (ra, operands[2]);
10696         operands[2] = ra;
10697       }
10698     /* This is a hack -- we may have crystalized the function type too
10699        early.  */
10700     cfun->machine->func_type = 0;
10701   }"
10704 ;; This split is only used during output to reduce the number of patterns
10705 ;; that need assembler instructions adding to them.  We allowed the setting
10706 ;; of the conditions to be implicit during rtl generation so that
10707 ;; the conditional compare patterns would work.  However this conflicts to
10708 ;; some extent with the conditional data operations, so we have to split them
10709 ;; up again here.
10711 ;; ??? Need to audit these splitters for Thumb-2.  Why isn't normal
10712 ;; conditional execution sufficient?
10714 (define_split
10715   [(set (match_operand:SI 0 "s_register_operand" "")
10716         (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10717                           [(match_operand 2 "" "") (match_operand 3 "" "")])
10718                          (match_dup 0)
10719                          (match_operand 4 "" "")))
10720    (clobber (reg:CC CC_REGNUM))]
10721   "TARGET_ARM && reload_completed"
10722   [(set (match_dup 5) (match_dup 6))
10723    (cond_exec (match_dup 7)
10724               (set (match_dup 0) (match_dup 4)))]
10725   "
10726   {
10727     machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10728                                              operands[2], operands[3]);
10729     enum rtx_code rc = GET_CODE (operands[1]);
10731     operands[5] = gen_rtx_REG (mode, CC_REGNUM);
10732     operands[6] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10733     if (mode == CCFPmode || mode == CCFPEmode)
10734       rc = reverse_condition_maybe_unordered (rc);
10735     else
10736       rc = reverse_condition (rc);
10738     operands[7] = gen_rtx_fmt_ee (rc, VOIDmode, operands[5], const0_rtx);
10739   }"
10742 (define_split
10743   [(set (match_operand:SI 0 "s_register_operand" "")
10744         (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10745                           [(match_operand 2 "" "") (match_operand 3 "" "")])
10746                          (match_operand 4 "" "")
10747                          (match_dup 0)))
10748    (clobber (reg:CC CC_REGNUM))]
10749   "TARGET_ARM && reload_completed"
10750   [(set (match_dup 5) (match_dup 6))
10751    (cond_exec (match_op_dup 1 [(match_dup 5) (const_int 0)])
10752               (set (match_dup 0) (match_dup 4)))]
10753   "
10754   {
10755     machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10756                                              operands[2], operands[3]);
10758     operands[5] = gen_rtx_REG (mode, CC_REGNUM);
10759     operands[6] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10760   }"
10763 (define_split
10764   [(set (match_operand:SI 0 "s_register_operand" "")
10765         (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10766                           [(match_operand 2 "" "") (match_operand 3 "" "")])
10767                          (match_operand 4 "" "")
10768                          (match_operand 5 "" "")))
10769    (clobber (reg:CC CC_REGNUM))]
10770   "TARGET_ARM && reload_completed"
10771   [(set (match_dup 6) (match_dup 7))
10772    (cond_exec (match_op_dup 1 [(match_dup 6) (const_int 0)])
10773               (set (match_dup 0) (match_dup 4)))
10774    (cond_exec (match_dup 8)
10775               (set (match_dup 0) (match_dup 5)))]
10776   "
10777   {
10778     machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10779                                              operands[2], operands[3]);
10780     enum rtx_code rc = GET_CODE (operands[1]);
10782     operands[6] = gen_rtx_REG (mode, CC_REGNUM);
10783     operands[7] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10784     if (mode == CCFPmode || mode == CCFPEmode)
10785       rc = reverse_condition_maybe_unordered (rc);
10786     else
10787       rc = reverse_condition (rc);
10789     operands[8] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
10790   }"
10793 (define_split
10794   [(set (match_operand:SI 0 "s_register_operand" "")
10795         (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10796                           [(match_operand:SI 2 "s_register_operand" "")
10797                            (match_operand:SI 3 "arm_add_operand" "")])
10798                          (match_operand:SI 4 "arm_rhs_operand" "")
10799                          (not:SI
10800                           (match_operand:SI 5 "s_register_operand" ""))))
10801    (clobber (reg:CC CC_REGNUM))]
10802   "TARGET_ARM && reload_completed"
10803   [(set (match_dup 6) (match_dup 7))
10804    (cond_exec (match_op_dup 1 [(match_dup 6) (const_int 0)])
10805               (set (match_dup 0) (match_dup 4)))
10806    (cond_exec (match_dup 8)
10807               (set (match_dup 0) (not:SI (match_dup 5))))]
10808   "
10809   {
10810     machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10811                                              operands[2], operands[3]);
10812     enum rtx_code rc = GET_CODE (operands[1]);
10814     operands[6] = gen_rtx_REG (mode, CC_REGNUM);
10815     operands[7] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10816     if (mode == CCFPmode || mode == CCFPEmode)
10817       rc = reverse_condition_maybe_unordered (rc);
10818     else
10819       rc = reverse_condition (rc);
10821     operands[8] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
10822   }"
10825 (define_insn "*cond_move_not"
10826   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10827         (if_then_else:SI (match_operator 4 "arm_comparison_operator"
10828                           [(match_operand 3 "cc_register" "") (const_int 0)])
10829                          (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
10830                          (not:SI
10831                           (match_operand:SI 2 "s_register_operand" "r,r"))))]
10832   "TARGET_ARM"
10833   "@
10834    mvn%D4\\t%0, %2
10835    mov%d4\\t%0, %1\;mvn%D4\\t%0, %2"
10836   [(set_attr "conds" "use")
10837    (set_attr "type" "mvn_reg,multiple")
10838    (set_attr "length" "4,8")]
10841 ;; The next two patterns occur when an AND operation is followed by a
10842 ;; scc insn sequence 
10844 (define_insn "*sign_extract_onebit"
10845   [(set (match_operand:SI 0 "s_register_operand" "=r")
10846         (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
10847                          (const_int 1)
10848                          (match_operand:SI 2 "const_int_operand" "n")))
10849     (clobber (reg:CC CC_REGNUM))]
10850   "TARGET_ARM"
10851   "*
10852     operands[2] = GEN_INT (1 << INTVAL (operands[2]));
10853     output_asm_insn (\"ands\\t%0, %1, %2\", operands);
10854     return \"mvnne\\t%0, #0\";
10855   "
10856   [(set_attr "conds" "clob")
10857    (set_attr "length" "8")
10858    (set_attr "type" "multiple")]
10861 (define_insn "*not_signextract_onebit"
10862   [(set (match_operand:SI 0 "s_register_operand" "=r")
10863         (not:SI
10864          (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
10865                           (const_int 1)
10866                           (match_operand:SI 2 "const_int_operand" "n"))))
10867    (clobber (reg:CC CC_REGNUM))]
10868   "TARGET_ARM"
10869   "*
10870     operands[2] = GEN_INT (1 << INTVAL (operands[2]));
10871     output_asm_insn (\"tst\\t%1, %2\", operands);
10872     output_asm_insn (\"mvneq\\t%0, #0\", operands);
10873     return \"movne\\t%0, #0\";
10874   "
10875   [(set_attr "conds" "clob")
10876    (set_attr "length" "12")
10877    (set_attr "type" "multiple")]
10879 ;; ??? The above patterns need auditing for Thumb-2
10881 ;; Push multiple registers to the stack.  Registers are in parallel (use ...)
10882 ;; expressions.  For simplicity, the first register is also in the unspec
10883 ;; part.
10884 ;; To avoid the usage of GNU extension, the length attribute is computed
10885 ;; in a C function arm_attr_length_push_multi.
10886 (define_insn "*push_multi"
10887   [(match_parallel 2 "multi_register_push"
10888     [(set (match_operand:BLK 0 "push_mult_memory_operand" "")
10889           (unspec:BLK [(match_operand:SI 1 "s_register_operand" "")]
10890                       UNSPEC_PUSH_MULT))])]
10891   ""
10892   "*
10893   {
10894     int num_saves = XVECLEN (operands[2], 0);
10895      
10896     /* For the StrongARM at least it is faster to
10897        use STR to store only a single register.
10898        In Thumb mode always use push, and the assembler will pick
10899        something appropriate.  */
10900     if (num_saves == 1 && TARGET_ARM)
10901       output_asm_insn (\"str%?\\t%1, [%m0, #-4]!\", operands);
10902     else
10903       {
10904         int i;
10905         char pattern[100];
10907         if (TARGET_32BIT)
10908             strcpy (pattern, \"push%?\\t{%1\");
10909         else
10910             strcpy (pattern, \"push\\t{%1\");
10912         for (i = 1; i < num_saves; i++)
10913           {
10914             strcat (pattern, \", %|\");
10915             strcat (pattern,
10916                     reg_names[REGNO (XEXP (XVECEXP (operands[2], 0, i), 0))]);
10917           }
10919         strcat (pattern, \"}\");
10920         output_asm_insn (pattern, operands);
10921       }
10923     return \"\";
10924   }"
10925   [(set_attr "type" "store4")
10926    (set (attr "length")
10927         (symbol_ref "arm_attr_length_push_multi (operands[2], operands[1])"))]
10930 (define_insn "stack_tie"
10931   [(set (mem:BLK (scratch))
10932         (unspec:BLK [(match_operand:SI 0 "s_register_operand" "rk")
10933                      (match_operand:SI 1 "s_register_operand" "rk")]
10934                     UNSPEC_PRLG_STK))]
10935   ""
10936   ""
10937   [(set_attr "length" "0")
10938    (set_attr "type" "block")]
10941 ;; Pop (as used in epilogue RTL)
10943 (define_insn "*load_multiple_with_writeback"
10944   [(match_parallel 0 "load_multiple_operation"
10945     [(set (match_operand:SI 1 "s_register_operand" "+rk")
10946           (plus:SI (match_dup 1)
10947                    (match_operand:SI 2 "const_int_I_operand" "I")))
10948      (set (match_operand:SI 3 "s_register_operand" "=rk")
10949           (mem:SI (match_dup 1)))
10950         ])]
10951   "TARGET_32BIT && (reload_in_progress || reload_completed)"
10952   "*
10953   {
10954     arm_output_multireg_pop (operands, /*return_pc=*/false,
10955                                        /*cond=*/const_true_rtx,
10956                                        /*reverse=*/false,
10957                                        /*update=*/true);
10958     return \"\";
10959   }
10960   "
10961   [(set_attr "type" "load4")
10962    (set_attr "predicable" "yes")
10963    (set (attr "length")
10964         (symbol_ref "arm_attr_length_pop_multi (operands,
10965                                                 /*return_pc=*/false,
10966                                                 /*write_back_p=*/true)"))]
10969 ;; Pop with return (as used in epilogue RTL)
10971 ;; This instruction is generated when the registers are popped at the end of
10972 ;; epilogue.  Here, instead of popping the value into LR and then generating
10973 ;; jump to LR, value is popped into PC directly.  Hence, the pattern is combined
10974 ;;  with (return).
10975 (define_insn "*pop_multiple_with_writeback_and_return"
10976   [(match_parallel 0 "pop_multiple_return"
10977     [(return)
10978      (set (match_operand:SI 1 "s_register_operand" "+rk")
10979           (plus:SI (match_dup 1)
10980                    (match_operand:SI 2 "const_int_I_operand" "I")))
10981      (set (match_operand:SI 3 "s_register_operand" "=rk")
10982           (mem:SI (match_dup 1)))
10983         ])]
10984   "TARGET_32BIT && (reload_in_progress || reload_completed)"
10985   "*
10986   {
10987     arm_output_multireg_pop (operands, /*return_pc=*/true,
10988                                        /*cond=*/const_true_rtx,
10989                                        /*reverse=*/false,
10990                                        /*update=*/true);
10991     return \"\";
10992   }
10993   "
10994   [(set_attr "type" "load4")
10995    (set_attr "predicable" "yes")
10996    (set (attr "length")
10997         (symbol_ref "arm_attr_length_pop_multi (operands, /*return_pc=*/true,
10998                                                 /*write_back_p=*/true)"))]
11001 (define_insn "*pop_multiple_with_return"
11002   [(match_parallel 0 "pop_multiple_return"
11003     [(return)
11004      (set (match_operand:SI 2 "s_register_operand" "=rk")
11005           (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
11006         ])]
11007   "TARGET_32BIT && (reload_in_progress || reload_completed)"
11008   "*
11009   {
11010     arm_output_multireg_pop (operands, /*return_pc=*/true,
11011                                        /*cond=*/const_true_rtx,
11012                                        /*reverse=*/false,
11013                                        /*update=*/false);
11014     return \"\";
11015   }
11016   "
11017   [(set_attr "type" "load4")
11018    (set_attr "predicable" "yes")
11019    (set (attr "length")
11020         (symbol_ref "arm_attr_length_pop_multi (operands, /*return_pc=*/true,
11021                                                 /*write_back_p=*/false)"))]
11024 ;; Load into PC and return
11025 (define_insn "*ldr_with_return"
11026   [(return)
11027    (set (reg:SI PC_REGNUM)
11028         (mem:SI (post_inc:SI (match_operand:SI 0 "s_register_operand" "+rk"))))]
11029   "TARGET_32BIT && (reload_in_progress || reload_completed)"
11030   "ldr%?\t%|pc, [%0], #4"
11031   [(set_attr "type" "load1")
11032    (set_attr "predicable" "yes")]
11034 ;; Pop for floating point registers (as used in epilogue RTL)
11035 (define_insn "*vfp_pop_multiple_with_writeback"
11036   [(match_parallel 0 "pop_multiple_fp"
11037     [(set (match_operand:SI 1 "s_register_operand" "+rk")
11038           (plus:SI (match_dup 1)
11039                    (match_operand:SI 2 "const_int_I_operand" "I")))
11040      (set (match_operand:DF 3 "vfp_hard_register_operand" "")
11041           (mem:DF (match_dup 1)))])]
11042   "TARGET_32BIT && TARGET_HARD_FLOAT"
11043   "*
11044   {
11045     int num_regs = XVECLEN (operands[0], 0);
11046     char pattern[100];
11047     rtx op_list[2];
11048     strcpy (pattern, \"vldm\\t\");
11049     strcat (pattern, reg_names[REGNO (SET_DEST (XVECEXP (operands[0], 0, 0)))]);
11050     strcat (pattern, \"!, {\");
11051     op_list[0] = XEXP (XVECEXP (operands[0], 0, 1), 0);
11052     strcat (pattern, \"%P0\");
11053     if ((num_regs - 1) > 1)
11054       {
11055         strcat (pattern, \"-%P1\");
11056         op_list [1] = XEXP (XVECEXP (operands[0], 0, num_regs - 1), 0);
11057       }
11059     strcat (pattern, \"}\");
11060     output_asm_insn (pattern, op_list);
11061     return \"\";
11062   }
11063   "
11064   [(set_attr "type" "load4")
11065    (set_attr "conds" "unconditional")
11066    (set_attr "predicable" "no")]
11069 ;; Special patterns for dealing with the constant pool
11071 (define_insn "align_4"
11072   [(unspec_volatile [(const_int 0)] VUNSPEC_ALIGN)]
11073   "TARGET_EITHER"
11074   "*
11075   assemble_align (32);
11076   return \"\";
11077   "
11078   [(set_attr "type" "no_insn")]
11081 (define_insn "align_8"
11082   [(unspec_volatile [(const_int 0)] VUNSPEC_ALIGN8)]
11083   "TARGET_EITHER"
11084   "*
11085   assemble_align (64);
11086   return \"\";
11087   "
11088   [(set_attr "type" "no_insn")]
11091 (define_insn "consttable_end"
11092   [(unspec_volatile [(const_int 0)] VUNSPEC_POOL_END)]
11093   "TARGET_EITHER"
11094   "*
11095   making_const_table = FALSE;
11096   return \"\";
11097   "
11098   [(set_attr "type" "no_insn")]
11101 (define_insn "consttable_1"
11102   [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_1)]
11103   "TARGET_EITHER"
11104   "*
11105   making_const_table = TRUE;
11106   assemble_integer (operands[0], 1, BITS_PER_WORD, 1);
11107   assemble_zeros (3);
11108   return \"\";
11109   "
11110   [(set_attr "length" "4")
11111    (set_attr "type" "no_insn")]
11114 (define_insn "consttable_2"
11115   [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_2)]
11116   "TARGET_EITHER"
11117   "*
11118   {
11119     rtx x = operands[0];
11120     making_const_table = TRUE;
11121     switch (GET_MODE_CLASS (GET_MODE (x)))
11122       {
11123       case MODE_FLOAT:
11124         arm_emit_fp16_const (x);
11125         break;
11126       default:
11127         assemble_integer (operands[0], 2, BITS_PER_WORD, 1);
11128         assemble_zeros (2);
11129         break;
11130       }
11131     return \"\";
11132   }"
11133   [(set_attr "length" "4")
11134    (set_attr "type" "no_insn")]
11137 (define_insn "consttable_4"
11138   [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_4)]
11139   "TARGET_EITHER"
11140   "*
11141   {
11142     rtx x = operands[0];
11143     making_const_table = TRUE;
11144     switch (GET_MODE_CLASS (GET_MODE (x)))
11145       {
11146       case MODE_FLOAT:
11147         assemble_real (*CONST_DOUBLE_REAL_VALUE (x), GET_MODE (x),
11148                        BITS_PER_WORD);
11149         break;
11150       default:
11151         /* XXX: Sometimes gcc does something really dumb and ends up with
11152            a HIGH in a constant pool entry, usually because it's trying to
11153            load into a VFP register.  We know this will always be used in
11154            combination with a LO_SUM which ignores the high bits, so just
11155            strip off the HIGH.  */
11156         if (GET_CODE (x) == HIGH)
11157           x = XEXP (x, 0);
11158         assemble_integer (x, 4, BITS_PER_WORD, 1);
11159         mark_symbol_refs_as_used (x);
11160         break;
11161       }
11162     return \"\";
11163   }"
11164   [(set_attr "length" "4")
11165    (set_attr "type" "no_insn")]
11168 (define_insn "consttable_8"
11169   [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_8)]
11170   "TARGET_EITHER"
11171   "*
11172   {
11173     making_const_table = TRUE;
11174     switch (GET_MODE_CLASS (GET_MODE (operands[0])))
11175       {
11176       case MODE_FLOAT:
11177         assemble_real (*CONST_DOUBLE_REAL_VALUE (operands[0]),
11178                        GET_MODE (operands[0]), BITS_PER_WORD);
11179         break;
11180       default:
11181         assemble_integer (operands[0], 8, BITS_PER_WORD, 1);
11182         break;
11183       }
11184     return \"\";
11185   }"
11186   [(set_attr "length" "8")
11187    (set_attr "type" "no_insn")]
11190 (define_insn "consttable_16"
11191   [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_16)]
11192   "TARGET_EITHER"
11193   "*
11194   {
11195     making_const_table = TRUE;
11196     switch (GET_MODE_CLASS (GET_MODE (operands[0])))
11197       {
11198       case MODE_FLOAT:
11199         assemble_real (*CONST_DOUBLE_REAL_VALUE (operands[0]),
11200                        GET_MODE (operands[0]), BITS_PER_WORD);
11201         break;
11202       default:
11203         assemble_integer (operands[0], 16, BITS_PER_WORD, 1);
11204         break;
11205       }
11206     return \"\";
11207   }"
11208   [(set_attr "length" "16")
11209    (set_attr "type" "no_insn")]
11212 ;; V5 Instructions,
11214 (define_insn "clzsi2"
11215   [(set (match_operand:SI 0 "s_register_operand" "=r")
11216         (clz:SI (match_operand:SI 1 "s_register_operand" "r")))]
11217   "TARGET_32BIT && arm_arch5"
11218   "clz%?\\t%0, %1"
11219   [(set_attr "predicable" "yes")
11220    (set_attr "predicable_short_it" "no")
11221    (set_attr "type" "clz")])
11223 (define_insn "rbitsi2"
11224   [(set (match_operand:SI 0 "s_register_operand" "=r")
11225         (unspec:SI [(match_operand:SI 1 "s_register_operand" "r")] UNSPEC_RBIT))]
11226   "TARGET_32BIT && arm_arch_thumb2"
11227   "rbit%?\\t%0, %1"
11228   [(set_attr "predicable" "yes")
11229    (set_attr "predicable_short_it" "no")
11230    (set_attr "type" "clz")])
11232 ;; Keep this as a CTZ expression until after reload and then split
11233 ;; into RBIT + CLZ.  Since RBIT is represented as an UNSPEC it is unlikely
11234 ;; to fold with any other expression.
11236 (define_insn_and_split "ctzsi2"
11237  [(set (match_operand:SI           0 "s_register_operand" "=r")
11238        (ctz:SI (match_operand:SI  1 "s_register_operand" "r")))]
11239   "TARGET_32BIT && arm_arch_thumb2"
11240   "#"
11241   "&& reload_completed"
11242   [(const_int 0)]
11243   "
11244   emit_insn (gen_rbitsi2 (operands[0], operands[1]));
11245   emit_insn (gen_clzsi2 (operands[0], operands[0]));
11246   DONE;
11249 ;; V5E instructions.
11251 (define_insn "prefetch"
11252   [(prefetch (match_operand:SI 0 "address_operand" "p")
11253              (match_operand:SI 1 "" "")
11254              (match_operand:SI 2 "" ""))]
11255   "TARGET_32BIT && arm_arch5e"
11256   "pld\\t%a0"
11257   [(set_attr "type" "load1")]
11260 ;; General predication pattern
11262 (define_cond_exec
11263   [(match_operator 0 "arm_comparison_operator"
11264     [(match_operand 1 "cc_register" "")
11265      (const_int 0)])]
11266   "TARGET_32BIT
11267    && (!TARGET_NO_VOLATILE_CE || !volatile_refs_p (PATTERN (insn)))"
11268   ""
11269 [(set_attr "predicated" "yes")]
11272 (define_insn "force_register_use"
11273   [(unspec:SI [(match_operand:SI 0 "register_operand" "")] UNSPEC_REGISTER_USE)]
11274   ""
11275   "%@ %0 needed"
11276   [(set_attr "length" "0")
11277    (set_attr "type" "no_insn")]
11281 ;; Patterns for exception handling
11283 (define_expand "eh_return"
11284   [(use (match_operand 0 "general_operand" ""))]
11285   "TARGET_EITHER"
11286   "
11287   {
11288     if (TARGET_32BIT)
11289       emit_insn (gen_arm_eh_return (operands[0]));
11290     else
11291       emit_insn (gen_thumb_eh_return (operands[0]));
11292     DONE;
11293   }"
11295                                    
11296 ;; We can't expand this before we know where the link register is stored.
11297 (define_insn_and_split "arm_eh_return"
11298   [(unspec_volatile [(match_operand:SI 0 "s_register_operand" "r")]
11299                     VUNSPEC_EH_RETURN)
11300    (clobber (match_scratch:SI 1 "=&r"))]
11301   "TARGET_ARM"
11302   "#"
11303   "&& reload_completed"
11304   [(const_int 0)]
11305   "
11306   {
11307     arm_set_return_address (operands[0], operands[1]);
11308     DONE;
11309   }"
11313 ;; TLS support
11315 (define_insn "load_tp_hard"
11316   [(set (match_operand:SI 0 "register_operand" "=r")
11317         (unspec:SI [(const_int 0)] UNSPEC_TLS))]
11318   "TARGET_HARD_TP"
11319   "mrc%?\\tp15, 0, %0, c13, c0, 3\\t@ load_tp_hard"
11320   [(set_attr "predicable" "yes")
11321    (set_attr "type" "mrs")]
11324 ;; Doesn't clobber R1-R3.  Must use r0 for the first operand.
11325 (define_insn "load_tp_soft"
11326   [(set (reg:SI 0) (unspec:SI [(const_int 0)] UNSPEC_TLS))
11327    (clobber (reg:SI LR_REGNUM))
11328    (clobber (reg:SI IP_REGNUM))
11329    (clobber (reg:CC CC_REGNUM))]
11330   "TARGET_SOFT_TP"
11331   "bl\\t__aeabi_read_tp\\t@ load_tp_soft"
11332   [(set_attr "conds" "clob")
11333    (set_attr "type" "branch")]
11336 ;; tls descriptor call
11337 (define_insn "tlscall"
11338   [(set (reg:SI R0_REGNUM)
11339         (unspec:SI [(reg:SI R0_REGNUM)
11340                     (match_operand:SI 0 "" "X")
11341                     (match_operand 1 "" "")] UNSPEC_TLS))
11342    (clobber (reg:SI R1_REGNUM))
11343    (clobber (reg:SI LR_REGNUM))
11344    (clobber (reg:SI CC_REGNUM))]
11345   "TARGET_GNU2_TLS"
11346   {
11347     targetm.asm_out.internal_label (asm_out_file, "LPIC",
11348                                     INTVAL (operands[1]));
11349     return "bl\\t%c0(tlscall)";
11350   }
11351   [(set_attr "conds" "clob")
11352    (set_attr "length" "4")
11353    (set_attr "type" "branch")]
11356 ;; For thread pointer builtin
11357 (define_expand "get_thread_pointersi"
11358   [(match_operand:SI 0 "s_register_operand" "=r")]
11359  ""
11362    arm_load_tp (operands[0]);
11363    DONE;
11364  }")
11368 ;; We only care about the lower 16 bits of the constant 
11369 ;; being inserted into the upper 16 bits of the register.
11370 (define_insn "*arm_movtas_ze" 
11371   [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r,r")
11372                    (const_int 16)
11373                    (const_int 16))
11374         (match_operand:SI 1 "const_int_operand" ""))]
11375   "TARGET_HAVE_MOVT"
11376   "@
11377    movt%?\t%0, %L1
11378    movt\t%0, %L1"
11379  [(set_attr "arch" "32,v8mb")
11380   (set_attr "predicable" "yes")
11381   (set_attr "predicable_short_it" "no")
11382   (set_attr "length" "4")
11383   (set_attr "type" "alu_sreg")]
11386 (define_insn "*arm_rev"
11387   [(set (match_operand:SI 0 "s_register_operand" "=l,l,r")
11388         (bswap:SI (match_operand:SI 1 "s_register_operand" "l,l,r")))]
11389   "arm_arch6"
11390   "@
11391    rev\t%0, %1
11392    rev%?\t%0, %1
11393    rev%?\t%0, %1"
11394   [(set_attr "arch" "t1,t2,32")
11395    (set_attr "length" "2,2,4")
11396    (set_attr "predicable" "no,yes,yes")
11397    (set_attr "predicable_short_it" "no")
11398    (set_attr "type" "rev")]
11401 (define_expand "arm_legacy_rev"
11402   [(set (match_operand:SI 2 "s_register_operand" "")
11403         (xor:SI (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
11404                              (const_int 16))
11405                 (match_dup 1)))
11406    (set (match_dup 2)
11407         (lshiftrt:SI (match_dup 2)
11408                      (const_int 8)))
11409    (set (match_operand:SI 3 "s_register_operand" "")
11410         (rotatert:SI (match_dup 1)
11411                      (const_int 8)))
11412    (set (match_dup 2)
11413         (and:SI (match_dup 2)
11414                 (const_int -65281)))
11415    (set (match_operand:SI 0 "s_register_operand" "")
11416         (xor:SI (match_dup 3)
11417                 (match_dup 2)))]
11418   "TARGET_32BIT"
11419   ""
11422 ;; Reuse temporaries to keep register pressure down.
11423 (define_expand "thumb_legacy_rev"
11424   [(set (match_operand:SI 2 "s_register_operand" "")
11425      (ashift:SI (match_operand:SI 1 "s_register_operand" "")
11426                 (const_int 24)))
11427    (set (match_operand:SI 3 "s_register_operand" "")
11428      (lshiftrt:SI (match_dup 1)
11429                   (const_int 24)))
11430    (set (match_dup 3)
11431      (ior:SI (match_dup 3)
11432              (match_dup 2)))
11433    (set (match_operand:SI 4 "s_register_operand" "")
11434      (const_int 16))
11435    (set (match_operand:SI 5 "s_register_operand" "")
11436      (rotatert:SI (match_dup 1)
11437                   (match_dup 4)))
11438    (set (match_dup 2)
11439      (ashift:SI (match_dup 5)
11440                 (const_int 24)))
11441    (set (match_dup 5)
11442      (lshiftrt:SI (match_dup 5)
11443                   (const_int 24)))
11444    (set (match_dup 5)
11445      (ior:SI (match_dup 5)
11446              (match_dup 2)))
11447    (set (match_dup 5)
11448      (rotatert:SI (match_dup 5)
11449                   (match_dup 4)))
11450    (set (match_operand:SI 0 "s_register_operand" "")
11451      (ior:SI (match_dup 5)
11452              (match_dup 3)))]
11453   "TARGET_THUMB"
11454   ""
11457 ;; ARM-specific expansion of signed mod by power of 2
11458 ;; using conditional negate.
11459 ;; For r0 % n where n is a power of 2 produce:
11460 ;; rsbs    r1, r0, #0
11461 ;; and     r0, r0, #(n - 1)
11462 ;; and     r1, r1, #(n - 1)
11463 ;; rsbpl   r0, r1, #0
11465 (define_expand "modsi3"
11466   [(match_operand:SI 0 "register_operand" "")
11467    (match_operand:SI 1 "register_operand" "")
11468    (match_operand:SI 2 "const_int_operand" "")]
11469   "TARGET_32BIT"
11470   {
11471     HOST_WIDE_INT val = INTVAL (operands[2]);
11473     if (val <= 0
11474        || exact_log2 (val) <= 0)
11475       FAIL;
11477     rtx mask = GEN_INT (val - 1);
11479     /* In the special case of x0 % 2 we can do the even shorter:
11480         cmp     r0, #0
11481         and     r0, r0, #1
11482         rsblt   r0, r0, #0.  */
11484     if (val == 2)
11485       {
11486         rtx cc_reg = arm_gen_compare_reg (LT,
11487                                           operands[1], const0_rtx, NULL_RTX);
11488         rtx cond = gen_rtx_LT (SImode, cc_reg, const0_rtx);
11489         rtx masked = gen_reg_rtx (SImode);
11491         emit_insn (gen_andsi3 (masked, operands[1], mask));
11492         emit_move_insn (operands[0],
11493                         gen_rtx_IF_THEN_ELSE (SImode, cond,
11494                                               gen_rtx_NEG (SImode,
11495                                                            masked),
11496                                               masked));
11497         DONE;
11498       }
11500     rtx neg_op = gen_reg_rtx (SImode);
11501     rtx_insn *insn = emit_insn (gen_subsi3_compare0 (neg_op, const0_rtx,
11502                                                       operands[1]));
11504     /* Extract the condition register and mode.  */
11505     rtx cmp = XVECEXP (PATTERN (insn), 0, 0);
11506     rtx cc_reg = SET_DEST (cmp);
11507     rtx cond = gen_rtx_GE (SImode, cc_reg, const0_rtx);
11509     emit_insn (gen_andsi3 (operands[0], operands[1], mask));
11511     rtx masked_neg = gen_reg_rtx (SImode);
11512     emit_insn (gen_andsi3 (masked_neg, neg_op, mask));
11514     /* We want a conditional negate here, but emitting COND_EXEC rtxes
11515        during expand does not always work.  Do an IF_THEN_ELSE instead.  */
11516     emit_move_insn (operands[0],
11517                     gen_rtx_IF_THEN_ELSE (SImode, cond,
11518                                           gen_rtx_NEG (SImode, masked_neg),
11519                                           operands[0]));
11522     DONE;
11523   }
11526 (define_expand "bswapsi2"
11527   [(set (match_operand:SI 0 "s_register_operand" "=r")
11528         (bswap:SI (match_operand:SI 1 "s_register_operand" "r")))]
11529 "TARGET_EITHER && (arm_arch6 || !optimize_size)"
11531     if (!arm_arch6)
11532       {
11533         rtx op2 = gen_reg_rtx (SImode);
11534         rtx op3 = gen_reg_rtx (SImode);
11536         if (TARGET_THUMB)
11537           {
11538             rtx op4 = gen_reg_rtx (SImode);
11539             rtx op5 = gen_reg_rtx (SImode);
11541             emit_insn (gen_thumb_legacy_rev (operands[0], operands[1],
11542                                              op2, op3, op4, op5));
11543           }
11544         else
11545           {
11546             emit_insn (gen_arm_legacy_rev (operands[0], operands[1],
11547                                            op2, op3));
11548           }
11550         DONE;
11551       }
11552   "
11555 ;; bswap16 patterns: use revsh and rev16 instructions for the signed
11556 ;; and unsigned variants, respectively. For rev16, expose
11557 ;; byte-swapping in the lower 16 bits only.
11558 (define_insn "*arm_revsh"
11559   [(set (match_operand:SI 0 "s_register_operand" "=l,l,r")
11560         (sign_extend:SI (bswap:HI (match_operand:HI 1 "s_register_operand" "l,l,r"))))]
11561   "arm_arch6"
11562   "@
11563   revsh\t%0, %1
11564   revsh%?\t%0, %1
11565   revsh%?\t%0, %1"
11566   [(set_attr "arch" "t1,t2,32")
11567    (set_attr "length" "2,2,4")
11568    (set_attr "type" "rev")]
11571 (define_insn "*arm_rev16"
11572   [(set (match_operand:HI 0 "s_register_operand" "=l,l,r")
11573         (bswap:HI (match_operand:HI 1 "s_register_operand" "l,l,r")))]
11574   "arm_arch6"
11575   "@
11576    rev16\t%0, %1
11577    rev16%?\t%0, %1
11578    rev16%?\t%0, %1"
11579   [(set_attr "arch" "t1,t2,32")
11580    (set_attr "length" "2,2,4")
11581    (set_attr "type" "rev")]
11584 ;; There are no canonicalisation rules for the position of the lshiftrt, ashift
11585 ;; operations within an IOR/AND RTX, therefore we have two patterns matching
11586 ;; each valid permutation.
11588 (define_insn "arm_rev16si2"
11589   [(set (match_operand:SI 0 "register_operand" "=l,l,r")
11590         (ior:SI (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "l,l,r")
11591                                    (const_int 8))
11592                         (match_operand:SI 3 "const_int_operand" "n,n,n"))
11593                 (and:SI (lshiftrt:SI (match_dup 1)
11594                                      (const_int 8))
11595                         (match_operand:SI 2 "const_int_operand" "n,n,n"))))]
11596   "arm_arch6
11597    && aarch_rev16_shleft_mask_imm_p (operands[3], SImode)
11598    && aarch_rev16_shright_mask_imm_p (operands[2], SImode)"
11599   "rev16\\t%0, %1"
11600   [(set_attr "arch" "t1,t2,32")
11601    (set_attr "length" "2,2,4")
11602    (set_attr "type" "rev")]
11605 (define_insn "arm_rev16si2_alt"
11606   [(set (match_operand:SI 0 "register_operand" "=l,l,r")
11607         (ior:SI (and:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "l,l,r")
11608                                      (const_int 8))
11609                         (match_operand:SI 2 "const_int_operand" "n,n,n"))
11610                 (and:SI (ashift:SI (match_dup 1)
11611                                    (const_int 8))
11612                         (match_operand:SI 3 "const_int_operand" "n,n,n"))))]
11613   "arm_arch6
11614    && aarch_rev16_shleft_mask_imm_p (operands[3], SImode)
11615    && aarch_rev16_shright_mask_imm_p (operands[2], SImode)"
11616   "rev16\\t%0, %1"
11617   [(set_attr "arch" "t1,t2,32")
11618    (set_attr "length" "2,2,4")
11619    (set_attr "type" "rev")]
11622 (define_expand "bswaphi2"
11623   [(set (match_operand:HI 0 "s_register_operand" "=r")
11624         (bswap:HI (match_operand:HI 1 "s_register_operand" "r")))]
11625 "arm_arch6"
11629 ;; Patterns for LDRD/STRD in Thumb2 mode
11631 (define_insn "*thumb2_ldrd"
11632   [(set (match_operand:SI 0 "s_register_operand" "=r")
11633         (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "rk")
11634                          (match_operand:SI 2 "ldrd_strd_offset_operand" "Do"))))
11635    (set (match_operand:SI 3 "s_register_operand" "=r")
11636         (mem:SI (plus:SI (match_dup 1)
11637                          (match_operand:SI 4 "const_int_operand" ""))))]
11638   "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11639      && current_tune->prefer_ldrd_strd
11640      && ((INTVAL (operands[2]) + 4) == INTVAL (operands[4]))
11641      && (operands_ok_ldrd_strd (operands[0], operands[3],
11642                                   operands[1], INTVAL (operands[2]),
11643                                   false, true))"
11644   "ldrd%?\t%0, %3, [%1, %2]"
11645   [(set_attr "type" "load2")
11646    (set_attr "predicable" "yes")
11647    (set_attr "predicable_short_it" "no")])
11649 (define_insn "*thumb2_ldrd_base"
11650   [(set (match_operand:SI 0 "s_register_operand" "=r")
11651         (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
11652    (set (match_operand:SI 2 "s_register_operand" "=r")
11653         (mem:SI (plus:SI (match_dup 1)
11654                          (const_int 4))))]
11655   "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11656      && current_tune->prefer_ldrd_strd
11657      && (operands_ok_ldrd_strd (operands[0], operands[2],
11658                                   operands[1], 0, false, true))"
11659   "ldrd%?\t%0, %2, [%1]"
11660   [(set_attr "type" "load2")
11661    (set_attr "predicable" "yes")
11662    (set_attr "predicable_short_it" "no")])
11664 (define_insn "*thumb2_ldrd_base_neg"
11665   [(set (match_operand:SI 0 "s_register_operand" "=r")
11666         (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "rk")
11667                          (const_int -4))))
11668    (set (match_operand:SI 2 "s_register_operand" "=r")
11669         (mem:SI (match_dup 1)))]
11670   "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11671      && current_tune->prefer_ldrd_strd
11672      && (operands_ok_ldrd_strd (operands[0], operands[2],
11673                                   operands[1], -4, false, true))"
11674   "ldrd%?\t%0, %2, [%1, #-4]"
11675   [(set_attr "type" "load2")
11676    (set_attr "predicable" "yes")
11677    (set_attr "predicable_short_it" "no")])
11679 (define_insn "*thumb2_strd"
11680   [(set (mem:SI (plus:SI (match_operand:SI 0 "s_register_operand" "rk")
11681                          (match_operand:SI 1 "ldrd_strd_offset_operand" "Do")))
11682         (match_operand:SI 2 "s_register_operand" "r"))
11683    (set (mem:SI (plus:SI (match_dup 0)
11684                          (match_operand:SI 3 "const_int_operand" "")))
11685         (match_operand:SI 4 "s_register_operand" "r"))]
11686   "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11687      && current_tune->prefer_ldrd_strd
11688      && ((INTVAL (operands[1]) + 4) == INTVAL (operands[3]))
11689      && (operands_ok_ldrd_strd (operands[2], operands[4],
11690                                   operands[0], INTVAL (operands[1]),
11691                                   false, false))"
11692   "strd%?\t%2, %4, [%0, %1]"
11693   [(set_attr "type" "store2")
11694    (set_attr "predicable" "yes")
11695    (set_attr "predicable_short_it" "no")])
11697 (define_insn "*thumb2_strd_base"
11698   [(set (mem:SI (match_operand:SI 0 "s_register_operand" "rk"))
11699         (match_operand:SI 1 "s_register_operand" "r"))
11700    (set (mem:SI (plus:SI (match_dup 0)
11701                          (const_int 4)))
11702         (match_operand:SI 2 "s_register_operand" "r"))]
11703   "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11704      && current_tune->prefer_ldrd_strd
11705      && (operands_ok_ldrd_strd (operands[1], operands[2],
11706                                   operands[0], 0, false, false))"
11707   "strd%?\t%1, %2, [%0]"
11708   [(set_attr "type" "store2")
11709    (set_attr "predicable" "yes")
11710    (set_attr "predicable_short_it" "no")])
11712 (define_insn "*thumb2_strd_base_neg"
11713   [(set (mem:SI (plus:SI (match_operand:SI 0 "s_register_operand" "rk")
11714                          (const_int -4)))
11715         (match_operand:SI 1 "s_register_operand" "r"))
11716    (set (mem:SI (match_dup 0))
11717         (match_operand:SI 2 "s_register_operand" "r"))]
11718   "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11719      && current_tune->prefer_ldrd_strd
11720      && (operands_ok_ldrd_strd (operands[1], operands[2],
11721                                   operands[0], -4, false, false))"
11722   "strd%?\t%1, %2, [%0, #-4]"
11723   [(set_attr "type" "store2")
11724    (set_attr "predicable" "yes")
11725    (set_attr "predicable_short_it" "no")])
11727 ;; ARMv8 CRC32 instructions.
11728 (define_insn "<crc_variant>"
11729   [(set (match_operand:SI 0 "s_register_operand" "=r")
11730         (unspec:SI [(match_operand:SI 1 "s_register_operand" "r")
11731                     (match_operand:<crc_mode> 2 "s_register_operand" "r")]
11732          CRC))]
11733   "TARGET_CRC32"
11734   "<crc_variant>\\t%0, %1, %2"
11735   [(set_attr "type" "crc")
11736    (set_attr "conds" "unconditional")]
11739 ;; Load the load/store double peephole optimizations.
11740 (include "ldrdstrd.md")
11742 ;; Load the load/store multiple patterns
11743 (include "ldmstm.md")
11745 ;; Patterns in ldmstm.md don't cover more than 4 registers. This pattern covers
11746 ;; large lists without explicit writeback generated for APCS_FRAME epilogue.
11747 (define_insn "*load_multiple"
11748   [(match_parallel 0 "load_multiple_operation"
11749     [(set (match_operand:SI 2 "s_register_operand" "=rk")
11750           (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
11751         ])]
11752   "TARGET_32BIT"
11753   "*
11754   {
11755     arm_output_multireg_pop (operands, /*return_pc=*/false,
11756                                        /*cond=*/const_true_rtx,
11757                                        /*reverse=*/false,
11758                                        /*update=*/false);
11759     return \"\";
11760   }
11761   "
11762   [(set_attr "predicable" "yes")]
11765 (define_expand "copysignsf3"
11766   [(match_operand:SF 0 "register_operand")
11767    (match_operand:SF 1 "register_operand")
11768    (match_operand:SF 2 "register_operand")]
11769   "TARGET_SOFT_FLOAT && arm_arch_thumb2"
11770   "{
11771      emit_move_insn (operands[0], operands[2]);
11772      emit_insn (gen_insv_t2 (simplify_gen_subreg (SImode, operands[0], SFmode, 0),
11773                 GEN_INT (31), GEN_INT (0),
11774                 simplify_gen_subreg (SImode, operands[1], SFmode, 0)));
11775      DONE;
11776   }"
11779 (define_expand "copysigndf3"
11780   [(match_operand:DF 0 "register_operand")
11781    (match_operand:DF 1 "register_operand")
11782    (match_operand:DF 2 "register_operand")]
11783   "TARGET_SOFT_FLOAT && arm_arch_thumb2"
11784   "{
11785      rtx op0_low = gen_lowpart (SImode, operands[0]);
11786      rtx op0_high = gen_highpart (SImode, operands[0]);
11787      rtx op1_low = gen_lowpart (SImode, operands[1]);
11788      rtx op1_high = gen_highpart (SImode, operands[1]);
11789      rtx op2_high = gen_highpart (SImode, operands[2]);
11791      rtx scratch1 = gen_reg_rtx (SImode);
11792      rtx scratch2 = gen_reg_rtx (SImode);
11793      emit_move_insn (scratch1, op2_high);
11794      emit_move_insn (scratch2, op1_high);
11796      emit_insn(gen_rtx_SET(scratch1,
11797                            gen_rtx_LSHIFTRT (SImode, op2_high, GEN_INT(31))));
11798      emit_insn(gen_insv_t2(scratch2, GEN_INT(1), GEN_INT(31), scratch1));
11799      emit_move_insn (op0_low, op1_low);
11800      emit_move_insn (op0_high, scratch2);
11802      DONE;
11803   }"
11806 ;; movmisalign patterns for HImode and SImode.
11807 (define_expand "movmisalign<mode>"
11808   [(match_operand:HSI 0 "general_operand")
11809    (match_operand:HSI 1 "general_operand")]
11810   "unaligned_access"
11812   /* This pattern is not permitted to fail during expansion: if both arguments
11813      are non-registers (e.g. memory := constant), force operand 1 into a
11814      register.  */
11815   rtx (* gen_unaligned_load)(rtx, rtx);
11816   rtx tmp_dest = operands[0];
11817   if (!s_register_operand (operands[0], <MODE>mode)
11818       && !s_register_operand (operands[1], <MODE>mode))
11819     operands[1] = force_reg (<MODE>mode, operands[1]);
11821   if (<MODE>mode == HImode)
11822    {
11823     gen_unaligned_load = gen_unaligned_loadhiu;
11824     tmp_dest = gen_reg_rtx (SImode);
11825    }
11826   else
11827     gen_unaligned_load = gen_unaligned_loadsi;
11829   if (MEM_P (operands[1]))
11830    {
11831     emit_insn (gen_unaligned_load (tmp_dest, operands[1]));
11832     if (<MODE>mode == HImode)
11833       emit_move_insn (operands[0], gen_lowpart (HImode, tmp_dest));
11834    }
11835   else
11836     emit_insn (gen_unaligned_store<mode> (operands[0], operands[1]));
11838   DONE;
11841 ;; Vector bits common to IWMMXT and Neon
11842 (include "vec-common.md")
11843 ;; Load the Intel Wireless Multimedia Extension patterns
11844 (include "iwmmxt.md")
11845 ;; Load the VFP co-processor patterns
11846 (include "vfp.md")
11847 ;; Thumb-1 patterns
11848 (include "thumb1.md")
11849 ;; Thumb-2 patterns
11850 (include "thumb2.md")
11851 ;; Neon patterns
11852 (include "neon.md")
11853 ;; Crypto patterns
11854 (include "crypto.md")
11855 ;; Synchronization Primitives
11856 (include "sync.md")
11857 ;; Fixed-point patterns
11858 (include "arm-fixed.md")