2016-08-24 Michael Collison <michael.collison@linaro.org>
[official-gcc.git] / gcc / config / arm / arm.md
blob318db75ece9615412b48943ba197aae364a78a54
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 && TARGET_VFP"
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       /* If we're optimizing for size, we prefer the libgcc calls.  */
4020       if (optimize_function_for_size_p (cfun))
4021         FAIL;
4023       /* Expand operation using core-registers.
4024          'FAIL' would achieve the same thing, but this is a bit smarter.  */
4025       scratch1 = gen_reg_rtx (SImode);
4026       scratch2 = gen_reg_rtx (SImode);
4027       arm_emit_coreregs_64bit_shift (ASHIFT, operands[0], operands[1],
4028                                      operands[2], scratch1, scratch2);
4029       DONE;
4030     }
4031   "
4034 (define_insn "arm_ashldi3_1bit"
4035   [(set (match_operand:DI            0 "s_register_operand" "=r,&r")
4036         (ashift:DI (match_operand:DI 1 "s_register_operand" "0,r")
4037                    (const_int 1)))
4038    (clobber (reg:CC CC_REGNUM))]
4039   "TARGET_32BIT"
4040   "movs\\t%Q0, %Q1, asl #1\;adc\\t%R0, %R1, %R1"
4041   [(set_attr "conds" "clob")
4042    (set_attr "length" "8")
4043    (set_attr "type" "multiple")]
4046 (define_expand "ashlsi3"
4047   [(set (match_operand:SI            0 "s_register_operand" "")
4048         (ashift:SI (match_operand:SI 1 "s_register_operand" "")
4049                    (match_operand:SI 2 "arm_rhs_operand" "")))]
4050   "TARGET_EITHER"
4051   "
4052   if (CONST_INT_P (operands[2])
4053       && (UINTVAL (operands[2])) > 31)
4054     {
4055       emit_insn (gen_movsi (operands[0], const0_rtx));
4056       DONE;
4057     }
4058   "
4061 (define_expand "ashrdi3"
4062   [(set (match_operand:DI              0 "s_register_operand" "")
4063         (ashiftrt:DI (match_operand:DI 1 "s_register_operand" "")
4064                      (match_operand:SI 2 "reg_or_int_operand" "")))]
4065   "TARGET_32BIT"
4066   "
4067   if (TARGET_NEON)
4068     {
4069       /* Delay the decision whether to use NEON or core-regs until
4070          register allocation.  */
4071       emit_insn (gen_ashrdi3_neon (operands[0], operands[1], operands[2]));
4072       DONE;
4073     }
4075   if (!CONST_INT_P (operands[2]) && TARGET_REALLY_IWMMXT)
4076     ; /* No special preparation statements; expand pattern as above.  */
4077   else
4078     {
4079       rtx scratch1, scratch2;
4081       if (operands[2] == CONST1_RTX (SImode))
4082         {
4083           emit_insn (gen_arm_ashrdi3_1bit (operands[0], operands[1]));
4084           DONE;
4085         }
4087       /* Ideally we should use iwmmxt here if we could know that operands[1]
4088          ends up already living in an iwmmxt register. Otherwise it's
4089          cheaper to have the alternate code being generated than moving
4090          values to iwmmxt regs and back.  */
4092       /* If we're optimizing for size, we prefer the libgcc calls.  */
4093       if (optimize_function_for_size_p (cfun))
4094         FAIL;
4096       /* Expand operation using core-registers.
4097          'FAIL' would achieve the same thing, but this is a bit smarter.  */
4098       scratch1 = gen_reg_rtx (SImode);
4099       scratch2 = gen_reg_rtx (SImode);
4100       arm_emit_coreregs_64bit_shift (ASHIFTRT, operands[0], operands[1],
4101                                      operands[2], scratch1, scratch2);
4102       DONE;
4103     }
4104   "
4107 (define_insn "arm_ashrdi3_1bit"
4108   [(set (match_operand:DI              0 "s_register_operand" "=r,&r")
4109         (ashiftrt:DI (match_operand:DI 1 "s_register_operand" "0,r")
4110                      (const_int 1)))
4111    (clobber (reg:CC CC_REGNUM))]
4112   "TARGET_32BIT"
4113   "movs\\t%R0, %R1, asr #1\;mov\\t%Q0, %Q1, rrx"
4114   [(set_attr "conds" "clob")
4115    (set_attr "length" "8")
4116    (set_attr "type" "multiple")]
4119 (define_expand "ashrsi3"
4120   [(set (match_operand:SI              0 "s_register_operand" "")
4121         (ashiftrt:SI (match_operand:SI 1 "s_register_operand" "")
4122                      (match_operand:SI 2 "arm_rhs_operand" "")))]
4123   "TARGET_EITHER"
4124   "
4125   if (CONST_INT_P (operands[2])
4126       && UINTVAL (operands[2]) > 31)
4127     operands[2] = GEN_INT (31);
4128   "
4131 (define_expand "lshrdi3"
4132   [(set (match_operand:DI              0 "s_register_operand" "")
4133         (lshiftrt:DI (match_operand:DI 1 "s_register_operand" "")
4134                      (match_operand:SI 2 "reg_or_int_operand" "")))]
4135   "TARGET_32BIT"
4136   "
4137   if (TARGET_NEON)
4138     {
4139       /* Delay the decision whether to use NEON or core-regs until
4140          register allocation.  */
4141       emit_insn (gen_lshrdi3_neon (operands[0], operands[1], operands[2]));
4142       DONE;
4143     }
4145   if (!CONST_INT_P (operands[2]) && TARGET_REALLY_IWMMXT)
4146     ; /* No special preparation statements; expand pattern as above.  */
4147   else
4148     {
4149       rtx scratch1, scratch2;
4151       if (operands[2] == CONST1_RTX (SImode))
4152         {
4153           emit_insn (gen_arm_lshrdi3_1bit (operands[0], operands[1]));
4154           DONE;
4155         }
4157       /* Ideally we should use iwmmxt here if we could know that operands[1]
4158          ends up already living in an iwmmxt register. Otherwise it's
4159          cheaper to have the alternate code being generated than moving
4160          values to iwmmxt regs and back.  */
4162       /* If we're optimizing for size, we prefer the libgcc calls.  */
4163       if (optimize_function_for_size_p (cfun))
4164         FAIL;
4166       /* Expand operation using core-registers.
4167          'FAIL' would achieve the same thing, but this is a bit smarter.  */
4168       scratch1 = gen_reg_rtx (SImode);
4169       scratch2 = gen_reg_rtx (SImode);
4170       arm_emit_coreregs_64bit_shift (LSHIFTRT, operands[0], operands[1],
4171                                      operands[2], scratch1, scratch2);
4172       DONE;
4173     }
4174   "
4177 (define_insn "arm_lshrdi3_1bit"
4178   [(set (match_operand:DI              0 "s_register_operand" "=r,&r")
4179         (lshiftrt:DI (match_operand:DI 1 "s_register_operand" "0,r")
4180                      (const_int 1)))
4181    (clobber (reg:CC CC_REGNUM))]
4182   "TARGET_32BIT"
4183   "movs\\t%R0, %R1, lsr #1\;mov\\t%Q0, %Q1, rrx"
4184   [(set_attr "conds" "clob")
4185    (set_attr "length" "8")
4186    (set_attr "type" "multiple")]
4189 (define_expand "lshrsi3"
4190   [(set (match_operand:SI              0 "s_register_operand" "")
4191         (lshiftrt:SI (match_operand:SI 1 "s_register_operand" "")
4192                      (match_operand:SI 2 "arm_rhs_operand" "")))]
4193   "TARGET_EITHER"
4194   "
4195   if (CONST_INT_P (operands[2])
4196       && (UINTVAL (operands[2])) > 31)
4197     {
4198       emit_insn (gen_movsi (operands[0], const0_rtx));
4199       DONE;
4200     }
4201   "
4204 (define_expand "rotlsi3"
4205   [(set (match_operand:SI              0 "s_register_operand" "")
4206         (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
4207                      (match_operand:SI 2 "reg_or_int_operand" "")))]
4208   "TARGET_32BIT"
4209   "
4210   if (CONST_INT_P (operands[2]))
4211     operands[2] = GEN_INT ((32 - INTVAL (operands[2])) % 32);
4212   else
4213     {
4214       rtx reg = gen_reg_rtx (SImode);
4215       emit_insn (gen_subsi3 (reg, GEN_INT (32), operands[2]));
4216       operands[2] = reg;
4217     }
4218   "
4221 (define_expand "rotrsi3"
4222   [(set (match_operand:SI              0 "s_register_operand" "")
4223         (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
4224                      (match_operand:SI 2 "arm_rhs_operand" "")))]
4225   "TARGET_EITHER"
4226   "
4227   if (TARGET_32BIT)
4228     {
4229       if (CONST_INT_P (operands[2])
4230           && UINTVAL (operands[2]) > 31)
4231         operands[2] = GEN_INT (INTVAL (operands[2]) % 32);
4232     }
4233   else /* TARGET_THUMB1 */
4234     {
4235       if (CONST_INT_P (operands [2]))
4236         operands [2] = force_reg (SImode, operands[2]);
4237     }
4238   "
4241 (define_insn "*arm_shiftsi3"
4242   [(set (match_operand:SI   0 "s_register_operand" "=l,l,r,r")
4243         (match_operator:SI  3 "shift_operator"
4244          [(match_operand:SI 1 "s_register_operand"  "0,l,r,r")
4245           (match_operand:SI 2 "reg_or_int_operand" "l,M,M,r")]))]
4246   "TARGET_32BIT"
4247   "* return arm_output_shift(operands, 0);"
4248   [(set_attr "predicable" "yes")
4249    (set_attr "arch" "t2,t2,*,*")
4250    (set_attr "predicable_short_it" "yes,yes,no,no")
4251    (set_attr "length" "4")
4252    (set_attr "shift" "1")
4253    (set_attr "type" "alu_shift_reg,alu_shift_imm,alu_shift_imm,alu_shift_reg")]
4256 (define_insn "*shiftsi3_compare0"
4257   [(set (reg:CC_NOOV CC_REGNUM)
4258         (compare:CC_NOOV (match_operator:SI 3 "shift_operator"
4259                           [(match_operand:SI 1 "s_register_operand" "r,r")
4260                            (match_operand:SI 2 "arm_rhs_operand" "M,r")])
4261                          (const_int 0)))
4262    (set (match_operand:SI 0 "s_register_operand" "=r,r")
4263         (match_op_dup 3 [(match_dup 1) (match_dup 2)]))]
4264   "TARGET_32BIT"
4265   "* return arm_output_shift(operands, 1);"
4266   [(set_attr "conds" "set")
4267    (set_attr "shift" "1")
4268    (set_attr "type" "alus_shift_imm,alus_shift_reg")]
4271 (define_insn "*shiftsi3_compare0_scratch"
4272   [(set (reg:CC_NOOV CC_REGNUM)
4273         (compare:CC_NOOV (match_operator:SI 3 "shift_operator"
4274                           [(match_operand:SI 1 "s_register_operand" "r,r")
4275                            (match_operand:SI 2 "arm_rhs_operand" "M,r")])
4276                          (const_int 0)))
4277    (clobber (match_scratch:SI 0 "=r,r"))]
4278   "TARGET_32BIT"
4279   "* return arm_output_shift(operands, 1);"
4280   [(set_attr "conds" "set")
4281    (set_attr "shift" "1")
4282    (set_attr "type" "shift_imm,shift_reg")]
4285 (define_insn "*not_shiftsi"
4286   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4287         (not:SI (match_operator:SI 3 "shift_operator"
4288                  [(match_operand:SI 1 "s_register_operand" "r,r")
4289                   (match_operand:SI 2 "shift_amount_operand" "M,rM")])))]
4290   "TARGET_32BIT"
4291   "mvn%?\\t%0, %1%S3"
4292   [(set_attr "predicable" "yes")
4293    (set_attr "predicable_short_it" "no")
4294    (set_attr "shift" "1")
4295    (set_attr "arch" "32,a")
4296    (set_attr "type" "mvn_shift,mvn_shift_reg")])
4298 (define_insn "*not_shiftsi_compare0"
4299   [(set (reg:CC_NOOV CC_REGNUM)
4300         (compare:CC_NOOV
4301          (not:SI (match_operator:SI 3 "shift_operator"
4302                   [(match_operand:SI 1 "s_register_operand" "r,r")
4303                    (match_operand:SI 2 "shift_amount_operand" "M,rM")]))
4304          (const_int 0)))
4305    (set (match_operand:SI 0 "s_register_operand" "=r,r")
4306         (not:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])))]
4307   "TARGET_32BIT"
4308   "mvns%?\\t%0, %1%S3"
4309   [(set_attr "conds" "set")
4310    (set_attr "shift" "1")
4311    (set_attr "arch" "32,a")
4312    (set_attr "type" "mvn_shift,mvn_shift_reg")])
4314 (define_insn "*not_shiftsi_compare0_scratch"
4315   [(set (reg:CC_NOOV CC_REGNUM)
4316         (compare:CC_NOOV
4317          (not:SI (match_operator:SI 3 "shift_operator"
4318                   [(match_operand:SI 1 "s_register_operand" "r,r")
4319                    (match_operand:SI 2 "shift_amount_operand" "M,rM")]))
4320          (const_int 0)))
4321    (clobber (match_scratch:SI 0 "=r,r"))]
4322   "TARGET_32BIT"
4323   "mvns%?\\t%0, %1%S3"
4324   [(set_attr "conds" "set")
4325    (set_attr "shift" "1")
4326    (set_attr "arch" "32,a")
4327    (set_attr "type" "mvn_shift,mvn_shift_reg")])
4329 ;; We don't really have extzv, but defining this using shifts helps
4330 ;; to reduce register pressure later on.
4332 (define_expand "extzv"
4333   [(set (match_operand 0 "s_register_operand" "")
4334         (zero_extract (match_operand 1 "nonimmediate_operand" "")
4335                       (match_operand 2 "const_int_operand" "")
4336                       (match_operand 3 "const_int_operand" "")))]
4337   "TARGET_THUMB1 || arm_arch_thumb2"
4338   "
4339   {
4340     HOST_WIDE_INT lshift = 32 - INTVAL (operands[2]) - INTVAL (operands[3]);
4341     HOST_WIDE_INT rshift = 32 - INTVAL (operands[2]);
4342     
4343     if (arm_arch_thumb2)
4344       {
4345         HOST_WIDE_INT width = INTVAL (operands[2]);
4346         HOST_WIDE_INT bitpos = INTVAL (operands[3]);
4348         if (unaligned_access && MEM_P (operands[1])
4349             && (width == 16 || width == 32) && (bitpos % BITS_PER_UNIT) == 0)
4350           {
4351             rtx base_addr;
4353             if (BYTES_BIG_ENDIAN)
4354               bitpos = GET_MODE_BITSIZE (GET_MODE (operands[0])) - width
4355                        - bitpos;
4357             if (width == 32)
4358               {
4359                 base_addr = adjust_address (operands[1], SImode,
4360                                             bitpos / BITS_PER_UNIT);
4361                 emit_insn (gen_unaligned_loadsi (operands[0], base_addr));
4362               }
4363             else
4364               {
4365                 rtx dest = operands[0];
4366                 rtx tmp = gen_reg_rtx (SImode);
4368                 /* We may get a paradoxical subreg here.  Strip it off.  */
4369                 if (GET_CODE (dest) == SUBREG
4370                     && GET_MODE (dest) == SImode
4371                     && GET_MODE (SUBREG_REG (dest)) == HImode)
4372                   dest = SUBREG_REG (dest);
4374                 if (GET_MODE_BITSIZE (GET_MODE (dest)) != width)
4375                   FAIL;
4377                 base_addr = adjust_address (operands[1], HImode,
4378                                             bitpos / BITS_PER_UNIT);
4379                 emit_insn (gen_unaligned_loadhiu (tmp, base_addr));
4380                 emit_move_insn (gen_lowpart (SImode, dest), tmp);
4381               }
4382             DONE;
4383           }
4384         else if (s_register_operand (operands[1], GET_MODE (operands[1])))
4385           {
4386             emit_insn (gen_extzv_t2 (operands[0], operands[1], operands[2],
4387                                      operands[3]));
4388             DONE;
4389           }
4390         else
4391           FAIL;
4392       }
4393     
4394     if (!s_register_operand (operands[1], GET_MODE (operands[1])))
4395       FAIL;
4397     operands[3] = GEN_INT (rshift);
4398     
4399     if (lshift == 0)
4400       {
4401         emit_insn (gen_lshrsi3 (operands[0], operands[1], operands[3]));
4402         DONE;
4403       }
4404       
4405     emit_insn (gen_extzv_t1 (operands[0], operands[1], GEN_INT (lshift),
4406                              operands[3], gen_reg_rtx (SImode)));
4407     DONE;
4408   }"
4411 ;; Helper for extzv, for the Thumb-1 register-shifts case.
4413 (define_expand "extzv_t1"
4414   [(set (match_operand:SI 4 "s_register_operand" "")
4415         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
4416                    (match_operand:SI 2 "const_int_operand" "")))
4417    (set (match_operand:SI 0 "s_register_operand" "")
4418         (lshiftrt:SI (match_dup 4)
4419                      (match_operand:SI 3 "const_int_operand" "")))]
4420   "TARGET_THUMB1"
4421   "")
4423 (define_expand "extv"
4424   [(set (match_operand 0 "s_register_operand" "")
4425         (sign_extract (match_operand 1 "nonimmediate_operand" "")
4426                       (match_operand 2 "const_int_operand" "")
4427                       (match_operand 3 "const_int_operand" "")))]
4428   "arm_arch_thumb2"
4430   HOST_WIDE_INT width = INTVAL (operands[2]);
4431   HOST_WIDE_INT bitpos = INTVAL (operands[3]);
4433   if (unaligned_access && MEM_P (operands[1]) && (width == 16 || width == 32)
4434       && (bitpos % BITS_PER_UNIT)  == 0)
4435     {
4436       rtx base_addr;
4437       
4438       if (BYTES_BIG_ENDIAN)
4439         bitpos = GET_MODE_BITSIZE (GET_MODE (operands[0])) - width - bitpos;
4440       
4441       if (width == 32)
4442         {
4443           base_addr = adjust_address (operands[1], SImode,
4444                                       bitpos / BITS_PER_UNIT);
4445           emit_insn (gen_unaligned_loadsi (operands[0], base_addr));
4446         }
4447       else
4448         {
4449           rtx dest = operands[0];
4450           rtx tmp = gen_reg_rtx (SImode);
4451           
4452           /* We may get a paradoxical subreg here.  Strip it off.  */
4453           if (GET_CODE (dest) == SUBREG
4454               && GET_MODE (dest) == SImode
4455               && GET_MODE (SUBREG_REG (dest)) == HImode)
4456             dest = SUBREG_REG (dest);
4457           
4458           if (GET_MODE_BITSIZE (GET_MODE (dest)) != width)
4459             FAIL;
4460           
4461           base_addr = adjust_address (operands[1], HImode,
4462                                       bitpos / BITS_PER_UNIT);
4463           emit_insn (gen_unaligned_loadhis (tmp, base_addr));
4464           emit_move_insn (gen_lowpart (SImode, dest), tmp);
4465         }
4467       DONE;
4468     }
4469   else if (!s_register_operand (operands[1], GET_MODE (operands[1])))
4470     FAIL;
4471   else if (GET_MODE (operands[0]) == SImode
4472            && GET_MODE (operands[1]) == SImode)
4473     {
4474       emit_insn (gen_extv_regsi (operands[0], operands[1], operands[2],
4475                                  operands[3]));
4476       DONE;
4477     }
4479   FAIL;
4482 ; Helper to expand register forms of extv with the proper modes.
4484 (define_expand "extv_regsi"
4485   [(set (match_operand:SI 0 "s_register_operand" "")
4486         (sign_extract:SI (match_operand:SI 1 "s_register_operand" "")
4487                          (match_operand 2 "const_int_operand" "")
4488                          (match_operand 3 "const_int_operand" "")))]
4489   ""
4493 ; ARMv6+ unaligned load/store instructions (used for packed structure accesses).
4495 (define_insn "unaligned_loadsi"
4496   [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4497         (unspec:SI [(match_operand:SI 1 "memory_operand" "Uw,m")]
4498                    UNSPEC_UNALIGNED_LOAD))]
4499   "unaligned_access"
4500   "ldr%?\t%0, %1\t@ unaligned"
4501   [(set_attr "arch" "t2,any")
4502    (set_attr "length" "2,4")
4503    (set_attr "predicable" "yes")
4504    (set_attr "predicable_short_it" "yes,no")
4505    (set_attr "type" "load1")])
4507 (define_insn "unaligned_loadhis"
4508   [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4509         (sign_extend:SI
4510           (unspec:HI [(match_operand:HI 1 "memory_operand" "Uw,Uh")]
4511                      UNSPEC_UNALIGNED_LOAD)))]
4512   "unaligned_access"
4513   "ldrsh%?\t%0, %1\t@ unaligned"
4514   [(set_attr "arch" "t2,any")
4515    (set_attr "length" "2,4")
4516    (set_attr "predicable" "yes")
4517    (set_attr "predicable_short_it" "yes,no")
4518    (set_attr "type" "load_byte")])
4520 (define_insn "unaligned_loadhiu"
4521   [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4522         (zero_extend:SI
4523           (unspec:HI [(match_operand:HI 1 "memory_operand" "Uw,m")]
4524                      UNSPEC_UNALIGNED_LOAD)))]
4525   "unaligned_access"
4526   "ldrh%?\t%0, %1\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" "load_byte")])
4533 (define_insn "unaligned_storesi"
4534   [(set (match_operand:SI 0 "memory_operand" "=Uw,m")
4535         (unspec:SI [(match_operand:SI 1 "s_register_operand" "l,r")]
4536                    UNSPEC_UNALIGNED_STORE))]
4537   "unaligned_access"
4538   "str%?\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")])
4545 (define_insn "unaligned_storehi"
4546   [(set (match_operand:HI 0 "memory_operand" "=Uw,m")
4547         (unspec:HI [(match_operand:HI 1 "s_register_operand" "l,r")]
4548                    UNSPEC_UNALIGNED_STORE))]
4549   "unaligned_access"
4550   "strh%?\t%1, %0\t@ unaligned"
4551   [(set_attr "arch" "t2,any")
4552    (set_attr "length" "2,4")
4553    (set_attr "predicable" "yes")
4554    (set_attr "predicable_short_it" "yes,no")
4555    (set_attr "type" "store1")])
4558 (define_insn "*extv_reg"
4559   [(set (match_operand:SI 0 "s_register_operand" "=r")
4560         (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
4561                          (match_operand:SI 2 "const_int_M_operand" "M")
4562                          (match_operand:SI 3 "const_int_M_operand" "M")))]
4563   "arm_arch_thumb2"
4564   "sbfx%?\t%0, %1, %3, %2"
4565   [(set_attr "length" "4")
4566    (set_attr "predicable" "yes")
4567    (set_attr "predicable_short_it" "no")
4568    (set_attr "type" "bfm")]
4571 (define_insn "extzv_t2"
4572   [(set (match_operand:SI 0 "s_register_operand" "=r")
4573         (zero_extract:SI (match_operand:SI 1 "s_register_operand" "r")
4574                          (match_operand:SI 2 "const_int_M_operand" "M")
4575                          (match_operand:SI 3 "const_int_M_operand" "M")))]
4576   "arm_arch_thumb2"
4577   "ubfx%?\t%0, %1, %3, %2"
4578   [(set_attr "length" "4")
4579    (set_attr "predicable" "yes")
4580    (set_attr "predicable_short_it" "no")
4581    (set_attr "type" "bfm")]
4585 ;; Division instructions
4586 (define_insn "divsi3"
4587   [(set (match_operand:SI         0 "s_register_operand" "=r,r")
4588         (div:SI (match_operand:SI 1 "s_register_operand"  "r,r")
4589                 (match_operand:SI 2 "s_register_operand"  "r,r")))]
4590   "TARGET_IDIV"
4591   "@
4592    sdiv%?\t%0, %1, %2
4593    sdiv\t%0, %1, %2"
4594   [(set_attr "arch" "32,v8mb")
4595    (set_attr "predicable" "yes")
4596    (set_attr "predicable_short_it" "no")
4597    (set_attr "type" "sdiv")]
4600 (define_insn "udivsi3"
4601   [(set (match_operand:SI          0 "s_register_operand" "=r,r")
4602         (udiv:SI (match_operand:SI 1 "s_register_operand"  "r,r")
4603                  (match_operand:SI 2 "s_register_operand"  "r,r")))]
4604   "TARGET_IDIV"
4605   "@
4606    udiv%?\t%0, %1, %2
4607    udiv\t%0, %1, %2"
4608   [(set_attr "arch" "32,v8mb")
4609    (set_attr "predicable" "yes")
4610    (set_attr "predicable_short_it" "no")
4611    (set_attr "type" "udiv")]
4615 ;; Unary arithmetic insns
4617 (define_expand "negvsi3"
4618   [(match_operand:SI 0 "register_operand")
4619    (match_operand:SI 1 "register_operand")
4620    (match_operand 2 "")]
4621   "TARGET_32BIT"
4623   emit_insn (gen_subsi3_compare (operands[0], const0_rtx, operands[1]));
4624   arm_gen_unlikely_cbranch (NE, CC_Vmode, operands[2]);
4626   DONE;
4629 (define_expand "negvdi3"
4630   [(match_operand:DI 0 "register_operand")
4631    (match_operand:DI 1 "register_operand")
4632    (match_operand 2 "")]
4633   "TARGET_ARM"
4635   emit_insn (gen_negdi2_compare (operands[0], operands[1]));
4636   arm_gen_unlikely_cbranch (NE, CC_Vmode, operands[2]);
4638   DONE;
4642 (define_insn_and_split "negdi2_compare"
4643   [(set (reg:CC CC_REGNUM)
4644         (compare:CC
4645           (const_int 0)
4646           (match_operand:DI 1 "register_operand" "0,r")))
4647    (set (match_operand:DI 0 "register_operand" "=r,&r")
4648         (minus:DI (const_int 0) (match_dup 1)))]
4649   "TARGET_ARM"
4650   "#"
4651   "&& reload_completed"
4652   [(parallel [(set (reg:CC CC_REGNUM)
4653                    (compare:CC (const_int 0) (match_dup 1)))
4654               (set (match_dup 0) (minus:SI (const_int 0)
4655                                            (match_dup 1)))])
4656    (parallel [(set (reg:CC CC_REGNUM)
4657                    (compare:CC (const_int 0) (match_dup 3)))
4658              (set (match_dup 2)
4659                   (minus:SI
4660                    (minus:SI (const_int 0) (match_dup 3))
4661                    (ltu:SI (reg:CC_C CC_REGNUM)
4662                            (const_int 0))))])]
4663   {
4664     operands[2] = gen_highpart (SImode, operands[0]);
4665     operands[0] = gen_lowpart (SImode, operands[0]);
4666     operands[3] = gen_highpart (SImode, operands[1]);
4667     operands[1] = gen_lowpart (SImode, operands[1]);
4668   }
4669   [(set_attr "conds" "set")
4670    (set_attr "length" "8")
4671    (set_attr "type" "multiple")]
4674 (define_expand "negdi2"
4675  [(parallel
4676    [(set (match_operand:DI 0 "s_register_operand" "")
4677          (neg:DI (match_operand:DI 1 "s_register_operand" "")))
4678     (clobber (reg:CC CC_REGNUM))])]
4679   "TARGET_EITHER"
4680   {
4681     if (TARGET_NEON)
4682       {
4683         emit_insn (gen_negdi2_neon (operands[0], operands[1]));
4684         DONE;
4685       }
4686   }
4689 ;; The constraints here are to prevent a *partial* overlap (where %Q0 == %R1).
4690 ;; The first alternative allows the common case of a *full* overlap.
4691 (define_insn_and_split "*arm_negdi2"
4692   [(set (match_operand:DI         0 "s_register_operand" "=r,&r")
4693         (neg:DI (match_operand:DI 1 "s_register_operand"  "0,r")))
4694    (clobber (reg:CC CC_REGNUM))]
4695   "TARGET_ARM"
4696   "#"   ; "rsbs\\t%Q0, %Q1, #0\;rsc\\t%R0, %R1, #0"
4697   "&& reload_completed"
4698   [(parallel [(set (reg:CC CC_REGNUM)
4699                    (compare:CC (const_int 0) (match_dup 1)))
4700               (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1)))])
4701    (set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3))
4702                                 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
4703   {
4704     operands[2] = gen_highpart (SImode, operands[0]);
4705     operands[0] = gen_lowpart (SImode, operands[0]);
4706     operands[3] = gen_highpart (SImode, operands[1]);
4707     operands[1] = gen_lowpart (SImode, operands[1]);
4708   }
4709   [(set_attr "conds" "clob")
4710    (set_attr "length" "8")
4711    (set_attr "type" "multiple")]
4714 (define_insn "*negsi2_carryin_compare"
4715   [(set (reg:CC CC_REGNUM)
4716         (compare:CC (const_int 0)
4717                     (match_operand:SI 1 "s_register_operand" "r")))
4718    (set (match_operand:SI 0 "s_register_operand" "=r")
4719         (minus:SI (minus:SI (const_int 0)
4720                             (match_dup 1))
4721                   (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
4722   "TARGET_ARM"
4723   "rscs\\t%0, %1, #0"
4724   [(set_attr "conds" "set")
4725    (set_attr "type" "alus_imm")]
4728 (define_expand "negsi2"
4729   [(set (match_operand:SI         0 "s_register_operand" "")
4730         (neg:SI (match_operand:SI 1 "s_register_operand" "")))]
4731   "TARGET_EITHER"
4732   ""
4735 (define_insn "*arm_negsi2"
4736   [(set (match_operand:SI         0 "s_register_operand" "=l,r")
4737         (neg:SI (match_operand:SI 1 "s_register_operand" "l,r")))]
4738   "TARGET_32BIT"
4739   "rsb%?\\t%0, %1, #0"
4740   [(set_attr "predicable" "yes")
4741    (set_attr "predicable_short_it" "yes,no")
4742    (set_attr "arch" "t2,*")
4743    (set_attr "length" "4")
4744    (set_attr "type" "alu_sreg")]
4747 (define_expand "negsf2"
4748   [(set (match_operand:SF         0 "s_register_operand" "")
4749         (neg:SF (match_operand:SF 1 "s_register_operand" "")))]
4750   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
4751   ""
4754 (define_expand "negdf2"
4755   [(set (match_operand:DF         0 "s_register_operand" "")
4756         (neg:DF (match_operand:DF 1 "s_register_operand" "")))]
4757   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
4758   "")
4760 (define_insn_and_split "*zextendsidi_negsi"
4761   [(set (match_operand:DI 0 "s_register_operand" "=r")
4762         (zero_extend:DI (neg:SI (match_operand:SI 1 "s_register_operand" "r"))))]
4763    "TARGET_32BIT"
4764    "#"
4765    ""
4766    [(set (match_dup 2)
4767          (neg:SI (match_dup 1)))
4768     (set (match_dup 3)
4769          (const_int 0))]
4770    {
4771       operands[2] = gen_lowpart (SImode, operands[0]);
4772       operands[3] = gen_highpart (SImode, operands[0]);
4773    }
4774  [(set_attr "length" "8")
4775   (set_attr "type" "multiple")]
4778 ;; Negate an extended 32-bit value.
4779 (define_insn_and_split "*negdi_extendsidi"
4780   [(set (match_operand:DI 0 "s_register_operand" "=l,r")
4781         (neg:DI (sign_extend:DI
4782                  (match_operand:SI 1 "s_register_operand" "l,r"))))
4783    (clobber (reg:CC CC_REGNUM))]
4784   "TARGET_32BIT"
4785   "#"
4786   "&& reload_completed"
4787   [(const_int 0)]
4788   {
4789     rtx low = gen_lowpart (SImode, operands[0]);
4790     rtx high = gen_highpart (SImode, operands[0]);
4792     if (reg_overlap_mentioned_p (low, operands[1]))
4793       {
4794         /* Input overlaps the low word of the output.  Use:
4795                 asr     Rhi, Rin, #31
4796                 rsbs    Rlo, Rin, #0
4797                 rsc     Rhi, Rhi, #0 (thumb2: sbc Rhi, Rhi, Rhi, lsl #1).  */
4798         rtx cc_reg = gen_rtx_REG (CC_Cmode, CC_REGNUM);
4800         emit_insn (gen_rtx_SET (high,
4801                                 gen_rtx_ASHIFTRT (SImode, operands[1],
4802                                                   GEN_INT (31))));
4804         emit_insn (gen_subsi3_compare (low, const0_rtx, operands[1]));
4805         if (TARGET_ARM)
4806           emit_insn (gen_rtx_SET (high,
4807                                   gen_rtx_MINUS (SImode,
4808                                                  gen_rtx_MINUS (SImode,
4809                                                                 const0_rtx,
4810                                                                 high),
4811                                                  gen_rtx_LTU (SImode,
4812                                                               cc_reg,
4813                                                               const0_rtx))));
4814         else
4815           {
4816             rtx two_x = gen_rtx_ASHIFT (SImode, high, GEN_INT (1));
4817             emit_insn (gen_rtx_SET (high,
4818                                     gen_rtx_MINUS (SImode,
4819                                                    gen_rtx_MINUS (SImode,
4820                                                                   high,
4821                                                                   two_x),
4822                                                    gen_rtx_LTU (SImode,
4823                                                                 cc_reg,
4824                                                                 const0_rtx))));
4825           }
4826       }
4827     else
4828       {
4829         /* No overlap, or overlap on high word.  Use:
4830                 rsb     Rlo, Rin, #0
4831                 bic     Rhi, Rlo, Rin
4832                 asr     Rhi, Rhi, #31
4833            Flags not needed for this sequence.  */
4834         emit_insn (gen_rtx_SET (low, gen_rtx_NEG (SImode, operands[1])));
4835         emit_insn (gen_rtx_SET (high,
4836                                 gen_rtx_AND (SImode,
4837                                              gen_rtx_NOT (SImode, operands[1]),
4838                                              low)));
4839         emit_insn (gen_rtx_SET (high,
4840                                 gen_rtx_ASHIFTRT (SImode, high,
4841                                                   GEN_INT (31))));
4842       }
4843     DONE;
4844   }
4845   [(set_attr "length" "12")
4846    (set_attr "arch" "t2,*")
4847    (set_attr "type" "multiple")]
4850 (define_insn_and_split "*negdi_zero_extendsidi"
4851   [(set (match_operand:DI 0 "s_register_operand" "=r,&r")
4852         (neg:DI (zero_extend:DI (match_operand:SI 1 "s_register_operand" "0,r"))))
4853    (clobber (reg:CC CC_REGNUM))]
4854   "TARGET_32BIT"
4855   "#" ; "rsbs\\t%Q0, %1, #0\;sbc\\t%R0,%R0,%R0"
4856       ;; Don't care what register is input to sbc,
4857       ;; since we just need to propagate the carry.
4858   "&& reload_completed"
4859   [(parallel [(set (reg:CC CC_REGNUM)
4860                    (compare:CC (const_int 0) (match_dup 1)))
4861               (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1)))])
4862    (set (match_dup 2) (minus:SI (minus:SI (match_dup 2) (match_dup 2))
4863                                 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
4864   {
4865     operands[2] = gen_highpart (SImode, operands[0]);
4866     operands[0] = gen_lowpart (SImode, operands[0]);
4867   }
4868   [(set_attr "conds" "clob")
4869    (set_attr "length" "8")
4870    (set_attr "type" "multiple")]   ;; length in thumb is 4
4873 ;; abssi2 doesn't really clobber the condition codes if a different register
4874 ;; is being set.  To keep things simple, assume during rtl manipulations that
4875 ;; it does, but tell the final scan operator the truth.  Similarly for
4876 ;; (neg (abs...))
4878 (define_expand "abssi2"
4879   [(parallel
4880     [(set (match_operand:SI         0 "s_register_operand" "")
4881           (abs:SI (match_operand:SI 1 "s_register_operand" "")))
4882      (clobber (match_dup 2))])]
4883   "TARGET_EITHER"
4884   "
4885   if (TARGET_THUMB1)
4886     operands[2] = gen_rtx_SCRATCH (SImode);
4887   else
4888     operands[2] = gen_rtx_REG (CCmode, CC_REGNUM);
4891 (define_insn_and_split "*arm_abssi2"
4892   [(set (match_operand:SI 0 "s_register_operand" "=r,&r")
4893         (abs:SI (match_operand:SI 1 "s_register_operand" "0,r")))
4894    (clobber (reg:CC CC_REGNUM))]
4895   "TARGET_ARM"
4896   "#"
4897   "&& reload_completed"
4898   [(const_int 0)]
4899   {
4900    /* if (which_alternative == 0) */
4901    if (REGNO(operands[0]) == REGNO(operands[1]))
4902      {
4903       /* Emit the pattern:
4904          cmp\\t%0, #0\;rsblt\\t%0, %0, #0
4905          [(set (reg:CC CC_REGNUM)
4906                (compare:CC (match_dup 0) (const_int 0)))
4907           (cond_exec (lt:CC (reg:CC CC_REGNUM) (const_int 0))
4908                      (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1))))]
4909       */
4910       emit_insn (gen_rtx_SET (gen_rtx_REG (CCmode, CC_REGNUM),
4911                               gen_rtx_COMPARE (CCmode, operands[0], const0_rtx)));
4912       emit_insn (gen_rtx_COND_EXEC (VOIDmode,
4913                                     (gen_rtx_LT (SImode,
4914                                                  gen_rtx_REG (CCmode, CC_REGNUM),
4915                                                  const0_rtx)),
4916                                     (gen_rtx_SET (operands[0],
4917                                                   (gen_rtx_MINUS (SImode,
4918                                                                   const0_rtx,
4919                                                                   operands[1]))))));
4920       DONE;
4921      }
4922    else
4923      {
4924       /* Emit the pattern:
4925          alt1: eor%?\\t%0, %1, %1, asr #31\;sub%?\\t%0, %0, %1, asr #31
4926          [(set (match_dup 0)
4927                (xor:SI (match_dup 1)
4928                        (ashiftrt:SI (match_dup 1) (const_int 31))))
4929           (set (match_dup 0)
4930                (minus:SI (match_dup 0)
4931                       (ashiftrt:SI (match_dup 1) (const_int 31))))]
4932       */
4933       emit_insn (gen_rtx_SET (operands[0],
4934                               gen_rtx_XOR (SImode,
4935                                            gen_rtx_ASHIFTRT (SImode,
4936                                                              operands[1],
4937                                                              GEN_INT (31)),
4938                                            operands[1])));
4939       emit_insn (gen_rtx_SET (operands[0],
4940                               gen_rtx_MINUS (SImode,
4941                                              operands[0],
4942                                              gen_rtx_ASHIFTRT (SImode,
4943                                                                operands[1],
4944                                                                GEN_INT (31)))));
4945       DONE;
4946      }
4947   }
4948   [(set_attr "conds" "clob,*")
4949    (set_attr "shift" "1")
4950    (set_attr "predicable" "no, yes")
4951    (set_attr "length" "8")
4952    (set_attr "type" "multiple")]
4955 (define_insn_and_split "*arm_neg_abssi2"
4956   [(set (match_operand:SI 0 "s_register_operand" "=r,&r")
4957         (neg:SI (abs:SI (match_operand:SI 1 "s_register_operand" "0,r"))))
4958    (clobber (reg:CC CC_REGNUM))]
4959   "TARGET_ARM"
4960   "#"
4961   "&& reload_completed"
4962   [(const_int 0)]
4963   {
4964    /* if (which_alternative == 0) */
4965    if (REGNO (operands[0]) == REGNO (operands[1]))
4966      {
4967       /* Emit the pattern:
4968          cmp\\t%0, #0\;rsbgt\\t%0, %0, #0
4969       */
4970       emit_insn (gen_rtx_SET (gen_rtx_REG (CCmode, CC_REGNUM),
4971                               gen_rtx_COMPARE (CCmode, operands[0], const0_rtx)));
4972       emit_insn (gen_rtx_COND_EXEC (VOIDmode,
4973                                     gen_rtx_GT (SImode,
4974                                                 gen_rtx_REG (CCmode, CC_REGNUM),
4975                                                 const0_rtx),
4976                                     gen_rtx_SET (operands[0],
4977                                                  (gen_rtx_MINUS (SImode,
4978                                                                  const0_rtx,
4979                                                                  operands[1])))));
4980      }
4981    else
4982      {
4983       /* Emit the pattern:
4984          eor%?\\t%0, %1, %1, asr #31\;rsb%?\\t%0, %0, %1, asr #31
4985       */
4986       emit_insn (gen_rtx_SET (operands[0],
4987                               gen_rtx_XOR (SImode,
4988                                            gen_rtx_ASHIFTRT (SImode,
4989                                                              operands[1],
4990                                                              GEN_INT (31)),
4991                                            operands[1])));
4992       emit_insn (gen_rtx_SET (operands[0],
4993                               gen_rtx_MINUS (SImode,
4994                                              gen_rtx_ASHIFTRT (SImode,
4995                                                                operands[1],
4996                                                                GEN_INT (31)),
4997                                              operands[0])));
4998      }
4999    DONE;
5000   }
5001   [(set_attr "conds" "clob,*")
5002    (set_attr "shift" "1")
5003    (set_attr "predicable" "no, yes")
5004    (set_attr "length" "8")
5005    (set_attr "type" "multiple")]
5008 (define_expand "abssf2"
5009   [(set (match_operand:SF         0 "s_register_operand" "")
5010         (abs:SF (match_operand:SF 1 "s_register_operand" "")))]
5011   "TARGET_32BIT && TARGET_HARD_FLOAT"
5012   "")
5014 (define_expand "absdf2"
5015   [(set (match_operand:DF         0 "s_register_operand" "")
5016         (abs:DF (match_operand:DF 1 "s_register_operand" "")))]
5017   "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
5018   "")
5020 (define_expand "sqrtsf2"
5021   [(set (match_operand:SF 0 "s_register_operand" "")
5022         (sqrt:SF (match_operand:SF 1 "s_register_operand" "")))]
5023   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
5024   "")
5026 (define_expand "sqrtdf2"
5027   [(set (match_operand:DF 0 "s_register_operand" "")
5028         (sqrt:DF (match_operand:DF 1 "s_register_operand" "")))]
5029   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
5030   "")
5032 (define_insn_and_split "one_cmpldi2"
5033   [(set (match_operand:DI 0 "s_register_operand"         "=w,&r,&r,?w")
5034         (not:DI (match_operand:DI 1 "s_register_operand" " w, 0, r, w")))]
5035   "TARGET_32BIT"
5036   "@
5037    vmvn\t%P0, %P1
5038    #
5039    #
5040    vmvn\t%P0, %P1"
5041   "TARGET_32BIT && reload_completed
5042    && arm_general_register_operand (operands[0], DImode)"
5043   [(set (match_dup 0) (not:SI (match_dup 1)))
5044    (set (match_dup 2) (not:SI (match_dup 3)))]
5045   "
5046   {
5047     operands[2] = gen_highpart (SImode, operands[0]);
5048     operands[0] = gen_lowpart (SImode, operands[0]);
5049     operands[3] = gen_highpart (SImode, operands[1]);
5050     operands[1] = gen_lowpart (SImode, operands[1]);
5051   }"
5052   [(set_attr "length" "*,8,8,*")
5053    (set_attr "predicable" "no,yes,yes,no")
5054    (set_attr "type" "neon_move,multiple,multiple,neon_move")
5055    (set_attr "arch" "neon_for_64bits,*,*,avoid_neon_for_64bits")]
5058 (define_expand "one_cmplsi2"
5059   [(set (match_operand:SI         0 "s_register_operand" "")
5060         (not:SI (match_operand:SI 1 "s_register_operand" "")))]
5061   "TARGET_EITHER"
5062   ""
5065 (define_insn "*arm_one_cmplsi2"
5066   [(set (match_operand:SI         0 "s_register_operand" "=l,r")
5067         (not:SI (match_operand:SI 1 "s_register_operand"  "l,r")))]
5068   "TARGET_32BIT"
5069   "mvn%?\\t%0, %1"
5070   [(set_attr "predicable" "yes")
5071    (set_attr "predicable_short_it" "yes,no")
5072    (set_attr "arch" "t2,*")
5073    (set_attr "length" "4")
5074    (set_attr "type" "mvn_reg")]
5077 (define_insn "*notsi_compare0"
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    (set (match_operand:SI 0 "s_register_operand" "=r")
5082         (not:SI (match_dup 1)))]
5083   "TARGET_32BIT"
5084   "mvns%?\\t%0, %1"
5085   [(set_attr "conds" "set")
5086    (set_attr "type" "mvn_reg")]
5089 (define_insn "*notsi_compare0_scratch"
5090   [(set (reg:CC_NOOV CC_REGNUM)
5091         (compare:CC_NOOV (not:SI (match_operand:SI 1 "s_register_operand" "r"))
5092                          (const_int 0)))
5093    (clobber (match_scratch:SI 0 "=r"))]
5094   "TARGET_32BIT"
5095   "mvns%?\\t%0, %1"
5096   [(set_attr "conds" "set")
5097    (set_attr "type" "mvn_reg")]
5100 ;; Fixed <--> Floating conversion insns
5102 (define_expand "floatsihf2"
5103   [(set (match_operand:HF           0 "general_operand" "")
5104         (float:HF (match_operand:SI 1 "general_operand" "")))]
5105   "TARGET_EITHER"
5106   "
5107   {
5108     rtx op1 = gen_reg_rtx (SFmode);
5109     expand_float (op1, operands[1], 0);
5110     op1 = convert_to_mode (HFmode, op1, 0);
5111     emit_move_insn (operands[0], op1);
5112     DONE;
5113   }"
5116 (define_expand "floatdihf2"
5117   [(set (match_operand:HF           0 "general_operand" "")
5118         (float:HF (match_operand:DI 1 "general_operand" "")))]
5119   "TARGET_EITHER"
5120   "
5121   {
5122     rtx op1 = gen_reg_rtx (SFmode);
5123     expand_float (op1, operands[1], 0);
5124     op1 = convert_to_mode (HFmode, op1, 0);
5125     emit_move_insn (operands[0], op1);
5126     DONE;
5127   }"
5130 (define_expand "floatsisf2"
5131   [(set (match_operand:SF           0 "s_register_operand" "")
5132         (float:SF (match_operand:SI 1 "s_register_operand" "")))]
5133   "TARGET_32BIT && TARGET_HARD_FLOAT"
5134   "
5137 (define_expand "floatsidf2"
5138   [(set (match_operand:DF           0 "s_register_operand" "")
5139         (float:DF (match_operand:SI 1 "s_register_operand" "")))]
5140   "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
5141   "
5144 (define_expand "fix_trunchfsi2"
5145   [(set (match_operand:SI         0 "general_operand" "")
5146         (fix:SI (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_trunchfdi2"
5157   [(set (match_operand:DI         0 "general_operand" "")
5158         (fix:DI (fix:HF (match_operand:HF 1 "general_operand"  ""))))]
5159   "TARGET_EITHER"
5160   "
5161   {
5162     rtx op1 = convert_to_mode (SFmode, operands[1], 0);
5163     expand_fix (operands[0], op1, 0);
5164     DONE;
5165   }"
5168 (define_expand "fix_truncsfsi2"
5169   [(set (match_operand:SI         0 "s_register_operand" "")
5170         (fix:SI (fix:SF (match_operand:SF 1 "s_register_operand"  ""))))]
5171   "TARGET_32BIT && TARGET_HARD_FLOAT"
5172   "
5175 (define_expand "fix_truncdfsi2"
5176   [(set (match_operand:SI         0 "s_register_operand" "")
5177         (fix:SI (fix:DF (match_operand:DF 1 "s_register_operand"  ""))))]
5178   "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
5179   "
5182 ;; Truncation insns
5184 (define_expand "truncdfsf2"
5185   [(set (match_operand:SF  0 "s_register_operand" "")
5186         (float_truncate:SF
5187          (match_operand:DF 1 "s_register_operand" "")))]
5188   "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
5189   ""
5192 /* DFmode -> HFmode conversions have to go through SFmode.  */
5193 (define_expand "truncdfhf2"
5194   [(set (match_operand:HF  0 "general_operand" "")
5195         (float_truncate:HF
5196          (match_operand:DF 1 "general_operand" "")))]
5197   "TARGET_EITHER"
5198   "
5199   {
5200     rtx op1;
5201     op1 = convert_to_mode (SFmode, operands[1], 0);
5202     op1 = convert_to_mode (HFmode, op1, 0);
5203     emit_move_insn (operands[0], op1);
5204     DONE;
5205   }"
5208 ;; Zero and sign extension instructions.
5210 (define_insn "zero_extend<mode>di2"
5211   [(set (match_operand:DI 0 "s_register_operand" "=w,r,?r,w")
5212         (zero_extend:DI (match_operand:QHSI 1 "<qhs_zextenddi_op>"
5213                                             "<qhs_zextenddi_cstr>")))]
5214   "TARGET_32BIT <qhs_zextenddi_cond>"
5215   "#"
5216   [(set_attr "length" "8,4,8,8")
5217    (set_attr "arch" "neon_for_64bits,*,*,avoid_neon_for_64bits")
5218    (set_attr "ce_count" "2")
5219    (set_attr "predicable" "yes")
5220    (set_attr "type" "multiple,mov_reg,multiple,multiple")]
5223 (define_insn "extend<mode>di2"
5224   [(set (match_operand:DI 0 "s_register_operand" "=w,r,?r,?r,w")
5225         (sign_extend:DI (match_operand:QHSI 1 "<qhs_extenddi_op>"
5226                                             "<qhs_extenddi_cstr>")))]
5227   "TARGET_32BIT <qhs_sextenddi_cond>"
5228   "#"
5229   [(set_attr "length" "8,4,8,8,8")
5230    (set_attr "ce_count" "2")
5231    (set_attr "shift" "1")
5232    (set_attr "predicable" "yes")
5233    (set_attr "arch" "neon_for_64bits,*,a,t,avoid_neon_for_64bits")
5234    (set_attr "type" "multiple,mov_reg,multiple,multiple,multiple")]
5237 ;; Splits for all extensions to DImode
5238 (define_split
5239   [(set (match_operand:DI 0 "s_register_operand" "")
5240         (zero_extend:DI (match_operand 1 "nonimmediate_operand" "")))]
5241   "TARGET_32BIT && reload_completed && !IS_VFP_REGNUM (REGNO (operands[0]))"
5242   [(set (match_dup 0) (match_dup 1))]
5244   rtx lo_part = gen_lowpart (SImode, operands[0]);
5245   machine_mode src_mode = GET_MODE (operands[1]);
5247   if (REG_P (operands[0])
5248       && !reg_overlap_mentioned_p (operands[0], operands[1]))
5249     emit_clobber (operands[0]);
5250   if (!REG_P (lo_part) || src_mode != SImode
5251       || !rtx_equal_p (lo_part, operands[1]))
5252     {
5253       if (src_mode == SImode)
5254         emit_move_insn (lo_part, operands[1]);
5255       else
5256         emit_insn (gen_rtx_SET (lo_part,
5257                                 gen_rtx_ZERO_EXTEND (SImode, operands[1])));
5258       operands[1] = lo_part;
5259     }
5260   operands[0] = gen_highpart (SImode, operands[0]);
5261   operands[1] = const0_rtx;
5264 (define_split
5265   [(set (match_operand:DI 0 "s_register_operand" "")
5266         (sign_extend:DI (match_operand 1 "nonimmediate_operand" "")))]
5267   "TARGET_32BIT && reload_completed && !IS_VFP_REGNUM (REGNO (operands[0]))"
5268   [(set (match_dup 0) (ashiftrt:SI (match_dup 1) (const_int 31)))]
5270   rtx lo_part = gen_lowpart (SImode, operands[0]);
5271   machine_mode src_mode = GET_MODE (operands[1]);
5273   if (REG_P (operands[0])
5274       && !reg_overlap_mentioned_p (operands[0], operands[1]))
5275     emit_clobber (operands[0]);
5277   if (!REG_P (lo_part) || src_mode != SImode
5278       || !rtx_equal_p (lo_part, operands[1]))
5279     {
5280       if (src_mode == SImode)
5281         emit_move_insn (lo_part, operands[1]);
5282       else
5283         emit_insn (gen_rtx_SET (lo_part,
5284                                 gen_rtx_SIGN_EXTEND (SImode, operands[1])));
5285       operands[1] = lo_part;
5286     }
5287   operands[0] = gen_highpart (SImode, operands[0]);
5290 (define_expand "zero_extendhisi2"
5291   [(set (match_operand:SI 0 "s_register_operand" "")
5292         (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
5293   "TARGET_EITHER"
5295   if (TARGET_ARM && !arm_arch4 && MEM_P (operands[1]))
5296     {
5297       emit_insn (gen_movhi_bytes (operands[0], operands[1]));
5298       DONE;
5299     }
5300   if (!arm_arch6 && !MEM_P (operands[1]))
5301     {
5302       rtx t = gen_lowpart (SImode, operands[1]);
5303       rtx tmp = gen_reg_rtx (SImode);
5304       emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (16)));
5305       emit_insn (gen_lshrsi3 (operands[0], tmp, GEN_INT (16)));
5306       DONE;
5307     }
5310 (define_split
5311   [(set (match_operand:SI 0 "s_register_operand" "")
5312         (zero_extend:SI (match_operand:HI 1 "s_register_operand" "")))]
5313   "!TARGET_THUMB2 && !arm_arch6"
5314   [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
5315    (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 16)))]
5317   operands[2] = gen_lowpart (SImode, operands[1]);
5320 (define_insn "*arm_zero_extendhisi2"
5321   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5322         (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
5323   "TARGET_ARM && arm_arch4 && !arm_arch6"
5324   "@
5325    #
5326    ldrh%?\\t%0, %1"
5327   [(set_attr "type" "alu_shift_reg,load_byte")
5328    (set_attr "predicable" "yes")]
5331 (define_insn "*arm_zero_extendhisi2_v6"
5332   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5333         (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,Uh")))]
5334   "TARGET_ARM && arm_arch6"
5335   "@
5336    uxth%?\\t%0, %1
5337    ldrh%?\\t%0, %1"
5338   [(set_attr "predicable" "yes")
5339    (set_attr "type" "extend,load_byte")]
5342 (define_insn "*arm_zero_extendhisi2addsi"
5343   [(set (match_operand:SI 0 "s_register_operand" "=r")
5344         (plus:SI (zero_extend:SI (match_operand:HI 1 "s_register_operand" "r"))
5345                  (match_operand:SI 2 "s_register_operand" "r")))]
5346   "TARGET_INT_SIMD"
5347   "uxtah%?\\t%0, %2, %1"
5348   [(set_attr "type" "alu_shift_reg")
5349    (set_attr "predicable" "yes")
5350    (set_attr "predicable_short_it" "no")]
5353 (define_expand "zero_extendqisi2"
5354   [(set (match_operand:SI 0 "s_register_operand" "")
5355         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))]
5356   "TARGET_EITHER"
5358   if (TARGET_ARM && !arm_arch6 && !MEM_P (operands[1]))
5359     {
5360       emit_insn (gen_andsi3 (operands[0],
5361                              gen_lowpart (SImode, operands[1]),
5362                                           GEN_INT (255)));
5363       DONE;
5364     }
5365   if (!arm_arch6 && !MEM_P (operands[1]))
5366     {
5367       rtx t = gen_lowpart (SImode, operands[1]);
5368       rtx tmp = gen_reg_rtx (SImode);
5369       emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (24)));
5370       emit_insn (gen_lshrsi3 (operands[0], tmp, GEN_INT (24)));
5371       DONE;
5372     }
5375 (define_split
5376   [(set (match_operand:SI 0 "s_register_operand" "")
5377         (zero_extend:SI (match_operand:QI 1 "s_register_operand" "")))]
5378   "!arm_arch6"
5379   [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 24)))
5380    (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 24)))]
5382   operands[2] = simplify_gen_subreg (SImode, operands[1], QImode, 0);
5383   if (TARGET_ARM)
5384     {
5385       emit_insn (gen_andsi3 (operands[0], operands[2], GEN_INT (255)));
5386       DONE;
5387     }
5390 (define_insn "*arm_zero_extendqisi2"
5391   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5392         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
5393   "TARGET_ARM && !arm_arch6"
5394   "@
5395    #
5396    ldrb%?\\t%0, %1\\t%@ zero_extendqisi2"
5397   [(set_attr "length" "8,4")
5398    (set_attr "type" "alu_shift_reg,load_byte")
5399    (set_attr "predicable" "yes")]
5402 (define_insn "*arm_zero_extendqisi2_v6"
5403   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5404         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,Uh")))]
5405   "TARGET_ARM && arm_arch6"
5406   "@
5407    uxtb%?\\t%0, %1
5408    ldrb%?\\t%0, %1\\t%@ zero_extendqisi2"
5409   [(set_attr "type" "extend,load_byte")
5410    (set_attr "predicable" "yes")]
5413 (define_insn "*arm_zero_extendqisi2addsi"
5414   [(set (match_operand:SI 0 "s_register_operand" "=r")
5415         (plus:SI (zero_extend:SI (match_operand:QI 1 "s_register_operand" "r"))
5416                  (match_operand:SI 2 "s_register_operand" "r")))]
5417   "TARGET_INT_SIMD"
5418   "uxtab%?\\t%0, %2, %1"
5419   [(set_attr "predicable" "yes")
5420    (set_attr "predicable_short_it" "no")
5421    (set_attr "type" "alu_shift_reg")]
5424 (define_split
5425   [(set (match_operand:SI 0 "s_register_operand" "")
5426         (zero_extend:SI (subreg:QI (match_operand:SI 1 "" "") 0)))
5427    (clobber (match_operand:SI 2 "s_register_operand" ""))]
5428   "TARGET_32BIT && (!MEM_P (operands[1])) && ! BYTES_BIG_ENDIAN"
5429   [(set (match_dup 2) (match_dup 1))
5430    (set (match_dup 0) (and:SI (match_dup 2) (const_int 255)))]
5431   ""
5434 (define_split
5435   [(set (match_operand:SI 0 "s_register_operand" "")
5436         (zero_extend:SI (subreg:QI (match_operand:SI 1 "" "") 3)))
5437    (clobber (match_operand:SI 2 "s_register_operand" ""))]
5438   "TARGET_32BIT && (!MEM_P (operands[1])) && BYTES_BIG_ENDIAN"
5439   [(set (match_dup 2) (match_dup 1))
5440    (set (match_dup 0) (and:SI (match_dup 2) (const_int 255)))]
5441   ""
5445 (define_split
5446   [(set (match_operand:SI 0 "s_register_operand" "")
5447         (IOR_XOR:SI (and:SI (ashift:SI
5448                              (match_operand:SI 1 "s_register_operand" "")
5449                              (match_operand:SI 2 "const_int_operand" ""))
5450                             (match_operand:SI 3 "const_int_operand" ""))
5451                     (zero_extend:SI
5452                      (match_operator 5 "subreg_lowpart_operator"
5453                       [(match_operand:SI 4 "s_register_operand" "")]))))]
5454   "TARGET_32BIT
5455    && (UINTVAL (operands[3])
5456        == (GET_MODE_MASK (GET_MODE (operands[5]))
5457            & (GET_MODE_MASK (GET_MODE (operands[5]))
5458               << (INTVAL (operands[2])))))"
5459   [(set (match_dup 0) (IOR_XOR:SI (ashift:SI (match_dup 1) (match_dup 2))
5460                                   (match_dup 4)))
5461    (set (match_dup 0) (zero_extend:SI (match_dup 5)))]
5462   "operands[5] = gen_lowpart (GET_MODE (operands[5]), operands[0]);"
5465 (define_insn "*compareqi_eq0"
5466   [(set (reg:CC_Z CC_REGNUM)
5467         (compare:CC_Z (match_operand:QI 0 "s_register_operand" "r")
5468                          (const_int 0)))]
5469   "TARGET_32BIT"
5470   "tst%?\\t%0, #255"
5471   [(set_attr "conds" "set")
5472    (set_attr "predicable" "yes")
5473    (set_attr "predicable_short_it" "no")
5474    (set_attr "type" "logic_imm")]
5477 (define_expand "extendhisi2"
5478   [(set (match_operand:SI 0 "s_register_operand" "")
5479         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
5480   "TARGET_EITHER"
5482   if (TARGET_THUMB1)
5483     {
5484       emit_insn (gen_thumb1_extendhisi2 (operands[0], operands[1]));
5485       DONE;
5486     }
5487   if (MEM_P (operands[1]) && TARGET_ARM && !arm_arch4)
5488     {
5489       emit_insn (gen_extendhisi2_mem (operands[0], operands[1]));
5490       DONE;
5491     }
5493   if (!arm_arch6 && !MEM_P (operands[1]))
5494     {
5495       rtx t = gen_lowpart (SImode, operands[1]);
5496       rtx tmp = gen_reg_rtx (SImode);
5497       emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (16)));
5498       emit_insn (gen_ashrsi3 (operands[0], tmp, GEN_INT (16)));
5499       DONE;
5500     }
5503 (define_split
5504   [(parallel
5505     [(set (match_operand:SI 0 "register_operand" "")
5506           (sign_extend:SI (match_operand:HI 1 "register_operand" "")))
5507      (clobber (match_scratch:SI 2 ""))])]
5508   "!arm_arch6"
5509   [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
5510    (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
5512   operands[2] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
5515 ;; This pattern will only be used when ldsh is not available
5516 (define_expand "extendhisi2_mem"
5517   [(set (match_dup 2) (zero_extend:SI (match_operand:HI 1 "" "")))
5518    (set (match_dup 3)
5519         (zero_extend:SI (match_dup 7)))
5520    (set (match_dup 6) (ashift:SI (match_dup 4) (const_int 24)))
5521    (set (match_operand:SI 0 "" "")
5522         (ior:SI (ashiftrt:SI (match_dup 6) (const_int 16)) (match_dup 5)))]
5523   "TARGET_ARM"
5524   "
5525   {
5526     rtx mem1, mem2;
5527     rtx addr = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
5529     mem1 = change_address (operands[1], QImode, addr);
5530     mem2 = change_address (operands[1], QImode,
5531                            plus_constant (Pmode, addr, 1));
5532     operands[0] = gen_lowpart (SImode, operands[0]);
5533     operands[1] = mem1;
5534     operands[2] = gen_reg_rtx (SImode);
5535     operands[3] = gen_reg_rtx (SImode);
5536     operands[6] = gen_reg_rtx (SImode);
5537     operands[7] = mem2;
5539     if (BYTES_BIG_ENDIAN)
5540       {
5541         operands[4] = operands[2];
5542         operands[5] = operands[3];
5543       }
5544     else
5545       {
5546         operands[4] = operands[3];
5547         operands[5] = operands[2];
5548       }
5549   }"
5552 (define_split
5553   [(set (match_operand:SI 0 "register_operand" "")
5554         (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
5555   "!arm_arch6"
5556   [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
5557    (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
5559   operands[2] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
5562 (define_insn "*arm_extendhisi2"
5563   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5564         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,Uh")))]
5565   "TARGET_ARM && arm_arch4 && !arm_arch6"
5566   "@
5567    #
5568    ldrsh%?\\t%0, %1"
5569   [(set_attr "length" "8,4")
5570    (set_attr "type" "alu_shift_reg,load_byte")
5571    (set_attr "predicable" "yes")]
5574 ;; ??? Check Thumb-2 pool range
5575 (define_insn "*arm_extendhisi2_v6"
5576   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5577         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,Uh")))]
5578   "TARGET_32BIT && arm_arch6"
5579   "@
5580    sxth%?\\t%0, %1
5581    ldrsh%?\\t%0, %1"
5582   [(set_attr "type" "extend,load_byte")
5583    (set_attr "predicable" "yes")
5584    (set_attr "predicable_short_it" "no")]
5587 (define_insn "*arm_extendhisi2addsi"
5588   [(set (match_operand:SI 0 "s_register_operand" "=r")
5589         (plus:SI (sign_extend:SI (match_operand:HI 1 "s_register_operand" "r"))
5590                  (match_operand:SI 2 "s_register_operand" "r")))]
5591   "TARGET_INT_SIMD"
5592   "sxtah%?\\t%0, %2, %1"
5593   [(set_attr "type" "alu_shift_reg")]
5596 (define_expand "extendqihi2"
5597   [(set (match_dup 2)
5598         (ashift:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "")
5599                    (const_int 24)))
5600    (set (match_operand:HI 0 "s_register_operand" "")
5601         (ashiftrt:SI (match_dup 2)
5602                      (const_int 24)))]
5603   "TARGET_ARM"
5604   "
5605   {
5606     if (arm_arch4 && MEM_P (operands[1]))
5607       {
5608         emit_insn (gen_rtx_SET (operands[0],
5609                                 gen_rtx_SIGN_EXTEND (HImode, operands[1])));
5610         DONE;
5611       }
5612     if (!s_register_operand (operands[1], QImode))
5613       operands[1] = copy_to_mode_reg (QImode, operands[1]);
5614     operands[0] = gen_lowpart (SImode, operands[0]);
5615     operands[1] = gen_lowpart (SImode, operands[1]);
5616     operands[2] = gen_reg_rtx (SImode);
5617   }"
5620 (define_insn "*arm_extendqihi_insn"
5621   [(set (match_operand:HI 0 "s_register_operand" "=r")
5622         (sign_extend:HI (match_operand:QI 1 "arm_extendqisi_mem_op" "Uq")))]
5623   "TARGET_ARM && arm_arch4"
5624   "ldrsb%?\\t%0, %1"
5625   [(set_attr "type" "load_byte")
5626    (set_attr "predicable" "yes")]
5629 (define_expand "extendqisi2"
5630   [(set (match_operand:SI 0 "s_register_operand" "")
5631         (sign_extend:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "")))]
5632   "TARGET_EITHER"
5634   if (!arm_arch4 && MEM_P (operands[1]))
5635     operands[1] = copy_to_mode_reg (QImode, operands[1]);
5637   if (!arm_arch6 && !MEM_P (operands[1]))
5638     {
5639       rtx t = gen_lowpart (SImode, operands[1]);
5640       rtx tmp = gen_reg_rtx (SImode);
5641       emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (24)));
5642       emit_insn (gen_ashrsi3 (operands[0], tmp, GEN_INT (24)));
5643       DONE;
5644     }
5647 (define_split
5648   [(set (match_operand:SI 0 "register_operand" "")
5649         (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
5650   "!arm_arch6"
5651   [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 24)))
5652    (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 24)))]
5654   operands[2] = simplify_gen_subreg (SImode, operands[1], QImode, 0);
5657 (define_insn "*arm_extendqisi"
5658   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5659         (sign_extend:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "r,Uq")))]
5660   "TARGET_ARM && arm_arch4 && !arm_arch6"
5661   "@
5662    #
5663    ldrsb%?\\t%0, %1"
5664   [(set_attr "length" "8,4")
5665    (set_attr "type" "alu_shift_reg,load_byte")
5666    (set_attr "predicable" "yes")]
5669 (define_insn "*arm_extendqisi_v6"
5670   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5671         (sign_extend:SI
5672          (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "r,Uq")))]
5673   "TARGET_ARM && arm_arch6"
5674   "@
5675    sxtb%?\\t%0, %1
5676    ldrsb%?\\t%0, %1"
5677   [(set_attr "type" "extend,load_byte")
5678    (set_attr "predicable" "yes")]
5681 (define_insn "*arm_extendqisi2addsi"
5682   [(set (match_operand:SI 0 "s_register_operand" "=r")
5683         (plus:SI (sign_extend:SI (match_operand:QI 1 "s_register_operand" "r"))
5684                  (match_operand:SI 2 "s_register_operand" "r")))]
5685   "TARGET_INT_SIMD"
5686   "sxtab%?\\t%0, %2, %1"
5687   [(set_attr "type" "alu_shift_reg")
5688    (set_attr "predicable" "yes")
5689    (set_attr "predicable_short_it" "no")]
5692 (define_expand "extendsfdf2"
5693   [(set (match_operand:DF                  0 "s_register_operand" "")
5694         (float_extend:DF (match_operand:SF 1 "s_register_operand"  "")))]
5695   "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
5696   ""
5699 /* HFmode -> DFmode conversions have to go through SFmode.  */
5700 (define_expand "extendhfdf2"
5701   [(set (match_operand:DF                  0 "general_operand" "")
5702         (float_extend:DF (match_operand:HF 1 "general_operand"  "")))]
5703   "TARGET_EITHER"
5704   "
5705   {
5706     rtx op1;
5707     op1 = convert_to_mode (SFmode, operands[1], 0);
5708     op1 = convert_to_mode (DFmode, op1, 0);
5709     emit_insn (gen_movdf (operands[0], op1));
5710     DONE;
5711   }"
5714 ;; Move insns (including loads and stores)
5716 ;; XXX Just some ideas about movti.
5717 ;; I don't think these are a good idea on the arm, there just aren't enough
5718 ;; registers
5719 ;;(define_expand "loadti"
5720 ;;  [(set (match_operand:TI 0 "s_register_operand" "")
5721 ;;      (mem:TI (match_operand:SI 1 "address_operand" "")))]
5722 ;;  "" "")
5724 ;;(define_expand "storeti"
5725 ;;  [(set (mem:TI (match_operand:TI 0 "address_operand" ""))
5726 ;;      (match_operand:TI 1 "s_register_operand" ""))]
5727 ;;  "" "")
5729 ;;(define_expand "movti"
5730 ;;  [(set (match_operand:TI 0 "general_operand" "")
5731 ;;      (match_operand:TI 1 "general_operand" ""))]
5732 ;;  ""
5733 ;;  "
5735 ;;  rtx insn;
5737 ;;  if (MEM_P (operands[0]) && MEM_P (operands[1]))
5738 ;;    operands[1] = copy_to_reg (operands[1]);
5739 ;;  if (MEM_P (operands[0]))
5740 ;;    insn = gen_storeti (XEXP (operands[0], 0), operands[1]);
5741 ;;  else if (MEM_P (operands[1]))
5742 ;;    insn = gen_loadti (operands[0], XEXP (operands[1], 0));
5743 ;;  else
5744 ;;    FAIL;
5746 ;;  emit_insn (insn);
5747 ;;  DONE;
5748 ;;}")
5750 ;; Recognize garbage generated above.
5752 ;;(define_insn ""
5753 ;;  [(set (match_operand:TI 0 "general_operand" "=r,r,r,<,>,m")
5754 ;;      (match_operand:TI 1 "general_operand" "<,>,m,r,r,r"))]
5755 ;;  ""
5756 ;;  "*
5757 ;;  {
5758 ;;    register mem = (which_alternative < 3);
5759 ;;    register const char *template;
5761 ;;    operands[mem] = XEXP (operands[mem], 0);
5762 ;;    switch (which_alternative)
5763 ;;      {
5764 ;;      case 0: template = \"ldmdb\\t%1!, %M0\"; break;
5765 ;;      case 1: template = \"ldmia\\t%1!, %M0\"; break;
5766 ;;      case 2: template = \"ldmia\\t%1, %M0\"; break;
5767 ;;      case 3: template = \"stmdb\\t%0!, %M1\"; break;
5768 ;;      case 4: template = \"stmia\\t%0!, %M1\"; break;
5769 ;;      case 5: template = \"stmia\\t%0, %M1\"; break;
5770 ;;      }
5771 ;;    output_asm_insn (template, operands);
5772 ;;    return \"\";
5773 ;;  }")
5775 (define_expand "movdi"
5776   [(set (match_operand:DI 0 "general_operand" "")
5777         (match_operand:DI 1 "general_operand" ""))]
5778   "TARGET_EITHER"
5779   "
5780   if (can_create_pseudo_p ())
5781     {
5782       if (!REG_P (operands[0]))
5783         operands[1] = force_reg (DImode, operands[1]);
5784     }
5785   if (REG_P (operands[0]) && REGNO (operands[0]) <= LAST_ARM_REGNUM
5786       && !HARD_REGNO_MODE_OK (REGNO (operands[0]), DImode))
5787     {
5788       /* Avoid LDRD's into an odd-numbered register pair in ARM state
5789          when expanding function calls.  */
5790       gcc_assert (can_create_pseudo_p ());
5791       if (MEM_P (operands[1]) && MEM_VOLATILE_P (operands[1]))
5792         {
5793           /* Perform load into legal reg pair first, then move.  */
5794           rtx reg = gen_reg_rtx (DImode);
5795           emit_insn (gen_movdi (reg, operands[1]));
5796           operands[1] = reg;
5797         }
5798       emit_move_insn (gen_lowpart (SImode, operands[0]),
5799                       gen_lowpart (SImode, operands[1]));
5800       emit_move_insn (gen_highpart (SImode, operands[0]),
5801                       gen_highpart (SImode, operands[1]));
5802       DONE;
5803     }
5804   else if (REG_P (operands[1]) && REGNO (operands[1]) <= LAST_ARM_REGNUM
5805            && !HARD_REGNO_MODE_OK (REGNO (operands[1]), DImode))
5806     {
5807       /* Avoid STRD's from an odd-numbered register pair in ARM state
5808          when expanding function prologue.  */
5809       gcc_assert (can_create_pseudo_p ());
5810       rtx split_dest = (MEM_P (operands[0]) && MEM_VOLATILE_P (operands[0]))
5811                        ? gen_reg_rtx (DImode)
5812                        : operands[0];
5813       emit_move_insn (gen_lowpart (SImode, split_dest),
5814                       gen_lowpart (SImode, operands[1]));
5815       emit_move_insn (gen_highpart (SImode, split_dest),
5816                       gen_highpart (SImode, operands[1]));
5817       if (split_dest != operands[0])
5818         emit_insn (gen_movdi (operands[0], split_dest));
5819       DONE;
5820     }
5821   "
5824 (define_insn "*arm_movdi"
5825   [(set (match_operand:DI 0 "nonimmediate_di_operand" "=r, r, r, q, m")
5826         (match_operand:DI 1 "di_operand"              "rDa,Db,Dc,mi,q"))]
5827   "TARGET_32BIT
5828    && !(TARGET_HARD_FLOAT && TARGET_VFP)
5829    && !TARGET_IWMMXT
5830    && (   register_operand (operands[0], DImode)
5831        || register_operand (operands[1], DImode))"
5832   "*
5833   switch (which_alternative)
5834     {
5835     case 0:
5836     case 1:
5837     case 2:
5838       return \"#\";
5839     default:
5840       return output_move_double (operands, true, NULL);
5841     }
5842   "
5843   [(set_attr "length" "8,12,16,8,8")
5844    (set_attr "type" "multiple,multiple,multiple,load2,store2")
5845    (set_attr "arm_pool_range" "*,*,*,1020,*")
5846    (set_attr "arm_neg_pool_range" "*,*,*,1004,*")
5847    (set_attr "thumb2_pool_range" "*,*,*,4094,*")
5848    (set_attr "thumb2_neg_pool_range" "*,*,*,0,*")]
5851 (define_split
5852   [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
5853         (match_operand:ANY64 1 "immediate_operand" ""))]
5854   "TARGET_32BIT
5855    && reload_completed
5856    && (arm_const_double_inline_cost (operands[1])
5857        <= arm_max_const_double_inline_cost ())"
5858   [(const_int 0)]
5859   "
5860   arm_split_constant (SET, SImode, curr_insn,
5861                       INTVAL (gen_lowpart (SImode, operands[1])),
5862                       gen_lowpart (SImode, operands[0]), NULL_RTX, 0);
5863   arm_split_constant (SET, SImode, curr_insn,
5864                       INTVAL (gen_highpart_mode (SImode,
5865                                                  GET_MODE (operands[0]),
5866                                                  operands[1])),
5867                       gen_highpart (SImode, operands[0]), NULL_RTX, 0);
5868   DONE;
5869   "
5872 ; If optimizing for size, or if we have load delay slots, then 
5873 ; we want to split the constant into two separate operations. 
5874 ; In both cases this may split a trivial part into a single data op
5875 ; leaving a single complex constant to load.  We can also get longer
5876 ; offsets in a LDR which means we get better chances of sharing the pool
5877 ; entries.  Finally, we can normally do a better job of scheduling
5878 ; LDR instructions than we can with LDM.
5879 ; This pattern will only match if the one above did not.
5880 (define_split
5881   [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
5882         (match_operand:ANY64 1 "const_double_operand" ""))]
5883   "TARGET_ARM && reload_completed
5884    && arm_const_double_by_parts (operands[1])"
5885   [(set (match_dup 0) (match_dup 1))
5886    (set (match_dup 2) (match_dup 3))]
5887   "
5888   operands[2] = gen_highpart (SImode, operands[0]);
5889   operands[3] = gen_highpart_mode (SImode, GET_MODE (operands[0]),
5890                                    operands[1]);
5891   operands[0] = gen_lowpart (SImode, operands[0]);
5892   operands[1] = gen_lowpart (SImode, operands[1]);
5893   "
5896 (define_split
5897   [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
5898         (match_operand:ANY64 1 "arm_general_register_operand" ""))]
5899   "TARGET_EITHER && reload_completed"
5900   [(set (match_dup 0) (match_dup 1))
5901    (set (match_dup 2) (match_dup 3))]
5902   "
5903   operands[2] = gen_highpart (SImode, operands[0]);
5904   operands[3] = gen_highpart (SImode, operands[1]);
5905   operands[0] = gen_lowpart (SImode, operands[0]);
5906   operands[1] = gen_lowpart (SImode, operands[1]);
5908   /* Handle a partial overlap.  */
5909   if (rtx_equal_p (operands[0], operands[3]))
5910     {
5911       rtx tmp0 = operands[0];
5912       rtx tmp1 = operands[1];
5914       operands[0] = operands[2];
5915       operands[1] = operands[3];
5916       operands[2] = tmp0;
5917       operands[3] = tmp1;
5918     }
5919   "
5922 ;; We can't actually do base+index doubleword loads if the index and
5923 ;; destination overlap.  Split here so that we at least have chance to
5924 ;; schedule.
5925 (define_split
5926   [(set (match_operand:DI 0 "s_register_operand" "")
5927         (mem:DI (plus:SI (match_operand:SI 1 "s_register_operand" "")
5928                          (match_operand:SI 2 "s_register_operand" ""))))]
5929   "TARGET_LDRD
5930   && reg_overlap_mentioned_p (operands[0], operands[1])
5931   && reg_overlap_mentioned_p (operands[0], operands[2])"
5932   [(set (match_dup 4)
5933         (plus:SI (match_dup 1)
5934                  (match_dup 2)))
5935    (set (match_dup 0)
5936         (mem:DI (match_dup 4)))]
5937   "
5938   operands[4] = gen_rtx_REG (SImode, REGNO(operands[0]));
5939   "
5942 (define_expand "movsi"
5943   [(set (match_operand:SI 0 "general_operand" "")
5944         (match_operand:SI 1 "general_operand" ""))]
5945   "TARGET_EITHER"
5946   "
5947   {
5948   rtx base, offset, tmp;
5950   if (TARGET_32BIT)
5951     {
5952       /* Everything except mem = const or mem = mem can be done easily.  */
5953       if (MEM_P (operands[0]))
5954         operands[1] = force_reg (SImode, operands[1]);
5955       if (arm_general_register_operand (operands[0], SImode)
5956           && CONST_INT_P (operands[1])
5957           && !(const_ok_for_arm (INTVAL (operands[1]))
5958                || const_ok_for_arm (~INTVAL (operands[1]))))
5959         {
5960            if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[1]), SET))
5961              {
5962                 emit_insn (gen_rtx_SET (operands[0], operands[1]));
5963                 DONE;
5964              }
5965           else
5966              {
5967                 arm_split_constant (SET, SImode, NULL_RTX,
5968                                     INTVAL (operands[1]), operands[0], NULL_RTX,
5969                                     optimize && can_create_pseudo_p ());
5970                 DONE;
5971              }
5972         }
5973     }
5974   else /* TARGET_THUMB1...  */
5975     {
5976       if (can_create_pseudo_p ())
5977         {
5978           if (!REG_P (operands[0]))
5979             operands[1] = force_reg (SImode, operands[1]);
5980         }
5981     }
5983   if (ARM_OFFSETS_MUST_BE_WITHIN_SECTIONS_P)
5984     {
5985       split_const (operands[1], &base, &offset);
5986       if (GET_CODE (base) == SYMBOL_REF
5987           && !offset_within_block_p (base, INTVAL (offset)))
5988         {
5989           tmp = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];
5990           emit_move_insn (tmp, base);
5991           emit_insn (gen_addsi3 (operands[0], tmp, offset));
5992           DONE;
5993         }
5994     }
5996   /* Recognize the case where operand[1] is a reference to thread-local
5997      data and load its address to a register.  */
5998   if (arm_tls_referenced_p (operands[1]))
5999     {
6000       rtx tmp = operands[1];
6001       rtx addend = NULL;
6003       if (GET_CODE (tmp) == CONST && GET_CODE (XEXP (tmp, 0)) == PLUS)
6004         {
6005           addend = XEXP (XEXP (tmp, 0), 1);
6006           tmp = XEXP (XEXP (tmp, 0), 0);
6007         }
6009       gcc_assert (GET_CODE (tmp) == SYMBOL_REF);
6010       gcc_assert (SYMBOL_REF_TLS_MODEL (tmp) != 0);
6012       tmp = legitimize_tls_address (tmp,
6013                                     !can_create_pseudo_p () ? operands[0] : 0);
6014       if (addend)
6015         {
6016           tmp = gen_rtx_PLUS (SImode, tmp, addend);
6017           tmp = force_operand (tmp, operands[0]);
6018         }
6019       operands[1] = tmp;
6020     }
6021   else if (flag_pic
6022            && (CONSTANT_P (operands[1])
6023                || symbol_mentioned_p (operands[1])
6024                || label_mentioned_p (operands[1])))
6025       operands[1] = legitimize_pic_address (operands[1], SImode,
6026                                             (!can_create_pseudo_p ()
6027                                              ? operands[0]
6028                                              : 0));
6029   }
6030   "
6033 ;; The ARM LO_SUM and HIGH are backwards - HIGH sets the low bits, and
6034 ;; LO_SUM adds in the high bits.  Fortunately these are opaque operations
6035 ;; so this does not matter.
6036 (define_insn "*arm_movt"
6037   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r")
6038         (lo_sum:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6039                    (match_operand:SI 2 "general_operand"      "i,i")))]
6040   "TARGET_HAVE_MOVT && arm_valid_symbolic_address_p (operands[2])"
6041   "@
6042    movt%?\t%0, #:upper16:%c2
6043    movt\t%0, #:upper16:%c2"
6044   [(set_attr "arch"  "32,v8mb")
6045    (set_attr "predicable" "yes")
6046    (set_attr "predicable_short_it" "no")
6047    (set_attr "length" "4")
6048    (set_attr "type" "alu_sreg")]
6051 (define_insn "*arm_movsi_insn"
6052   [(set (match_operand:SI 0 "nonimmediate_operand" "=rk,r,r,r,rk,m")
6053         (match_operand:SI 1 "general_operand"      "rk, I,K,j,mi,rk"))]
6054   "TARGET_ARM && ! TARGET_IWMMXT
6055    && !(TARGET_HARD_FLOAT && TARGET_VFP)
6056    && (   register_operand (operands[0], SImode)
6057        || register_operand (operands[1], SImode))"
6058   "@
6059    mov%?\\t%0, %1
6060    mov%?\\t%0, %1
6061    mvn%?\\t%0, #%B1
6062    movw%?\\t%0, %1
6063    ldr%?\\t%0, %1
6064    str%?\\t%1, %0"
6065   [(set_attr "type" "mov_reg,mov_imm,mvn_imm,mov_imm,load1,store1")
6066    (set_attr "predicable" "yes")
6067    (set_attr "pool_range" "*,*,*,*,4096,*")
6068    (set_attr "neg_pool_range" "*,*,*,*,4084,*")]
6071 (define_split
6072   [(set (match_operand:SI 0 "arm_general_register_operand" "")
6073         (match_operand:SI 1 "const_int_operand" ""))]
6074   "TARGET_32BIT
6075   && (!(const_ok_for_arm (INTVAL (operands[1]))
6076         || const_ok_for_arm (~INTVAL (operands[1]))))"
6077   [(clobber (const_int 0))]
6078   "
6079   arm_split_constant (SET, SImode, NULL_RTX, 
6080                       INTVAL (operands[1]), operands[0], NULL_RTX, 0);
6081   DONE;
6082   "
6085 ;; A normal way to do (symbol + offset) requires three instructions at least
6086 ;; (depends on how big the offset is) as below:
6087 ;; movw r0, #:lower16:g
6088 ;; movw r0, #:upper16:g
6089 ;; adds r0, #4
6091 ;; A better way would be:
6092 ;; movw r0, #:lower16:g+4
6093 ;; movw r0, #:upper16:g+4
6095 ;; The limitation of this way is that the length of offset should be a 16-bit
6096 ;; signed value, because current assembler only supports REL type relocation for
6097 ;; such case.  If the more powerful RELA type is supported in future, we should
6098 ;; update this pattern to go with better way.
6099 (define_split
6100   [(set (match_operand:SI 0 "arm_general_register_operand" "")
6101         (const:SI (plus:SI (match_operand:SI 1 "general_operand" "")
6102                            (match_operand:SI 2 "const_int_operand" ""))))]
6103   "TARGET_THUMB
6104    && TARGET_HAVE_MOVT
6105    && arm_disable_literal_pool
6106    && reload_completed
6107    && GET_CODE (operands[1]) == SYMBOL_REF"
6108   [(clobber (const_int 0))]
6109   "
6110     int offset = INTVAL (operands[2]);
6112     if (offset < -0x8000 || offset > 0x7fff)
6113       {
6114         arm_emit_movpair (operands[0], operands[1]);
6115         emit_insn (gen_rtx_SET (operands[0],
6116                                 gen_rtx_PLUS (SImode, operands[0], operands[2])));
6117       }
6118     else
6119       {
6120         rtx op = gen_rtx_CONST (SImode,
6121                                 gen_rtx_PLUS (SImode, operands[1], operands[2]));
6122         arm_emit_movpair (operands[0], op);
6123       }
6124   "
6127 ;; Split symbol_refs at the later stage (after cprop), instead of generating
6128 ;; movt/movw pair directly at expand.  Otherwise corresponding high_sum
6129 ;; and lo_sum would be merged back into memory load at cprop.  However,
6130 ;; if the default is to prefer movt/movw rather than a load from the constant
6131 ;; pool, the performance is better.
6132 (define_split
6133   [(set (match_operand:SI 0 "arm_general_register_operand" "")
6134        (match_operand:SI 1 "general_operand" ""))]
6135   "TARGET_USE_MOVT && GET_CODE (operands[1]) == SYMBOL_REF
6136    && !flag_pic && !target_word_relocations
6137    && !arm_tls_referenced_p (operands[1])"
6138   [(clobber (const_int 0))]
6140   arm_emit_movpair (operands[0], operands[1]);
6141   DONE;
6144 ;; When generating pic, we need to load the symbol offset into a register.
6145 ;; So that the optimizer does not confuse this with a normal symbol load
6146 ;; we use an unspec.  The offset will be loaded from a constant pool entry,
6147 ;; since that is the only type of relocation we can use.
6149 ;; Wrap calculation of the whole PIC address in a single pattern for the
6150 ;; benefit of optimizers, particularly, PRE and HOIST.  Calculation of
6151 ;; a PIC address involves two loads from memory, so we want to CSE it
6152 ;; as often as possible.
6153 ;; This pattern will be split into one of the pic_load_addr_* patterns
6154 ;; and a move after GCSE optimizations.
6156 ;; Note: Update arm.c: legitimize_pic_address() when changing this pattern.
6157 (define_expand "calculate_pic_address"
6158   [(set (match_operand:SI 0 "register_operand" "")
6159         (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "")
6160                          (unspec:SI [(match_operand:SI 2 "" "")]
6161                                     UNSPEC_PIC_SYM))))]
6162   "flag_pic"
6165 ;; Split calculate_pic_address into pic_load_addr_* and a move.
6166 (define_split
6167   [(set (match_operand:SI 0 "register_operand" "")
6168         (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "")
6169                          (unspec:SI [(match_operand:SI 2 "" "")]
6170                                     UNSPEC_PIC_SYM))))]
6171   "flag_pic"
6172   [(set (match_dup 3) (unspec:SI [(match_dup 2)] UNSPEC_PIC_SYM))
6173    (set (match_dup 0) (mem:SI (plus:SI (match_dup 1) (match_dup 3))))]
6174   "operands[3] = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];"
6177 ;; operand1 is the memory address to go into 
6178 ;; pic_load_addr_32bit.
6179 ;; operand2 is the PIC label to be emitted 
6180 ;; from pic_add_dot_plus_eight.
6181 ;; We do this to allow hoisting of the entire insn.
6182 (define_insn_and_split "pic_load_addr_unified"
6183   [(set (match_operand:SI 0 "s_register_operand" "=r,r,l")
6184         (unspec:SI [(match_operand:SI 1 "" "mX,mX,mX") 
6185                     (match_operand:SI 2 "" "")] 
6186                     UNSPEC_PIC_UNIFIED))]
6187  "flag_pic"
6188  "#"
6189  "&& reload_completed"
6190  [(set (match_dup 0) (unspec:SI [(match_dup 1)] UNSPEC_PIC_SYM))
6191   (set (match_dup 0) (unspec:SI [(match_dup 0) (match_dup 3)
6192                                  (match_dup 2)] UNSPEC_PIC_BASE))]
6193  "operands[3] = TARGET_THUMB ? GEN_INT (4) : GEN_INT (8);"
6194  [(set_attr "type" "load1,load1,load1")
6195   (set_attr "pool_range" "4096,4094,1022")
6196   (set_attr "neg_pool_range" "4084,0,0")
6197   (set_attr "arch"  "a,t2,t1")    
6198   (set_attr "length" "8,6,4")]
6201 ;; The rather odd constraints on the following are to force reload to leave
6202 ;; the insn alone, and to force the minipool generation pass to then move
6203 ;; the GOT symbol to memory.
6205 (define_insn "pic_load_addr_32bit"
6206   [(set (match_operand:SI 0 "s_register_operand" "=r")
6207         (unspec:SI [(match_operand:SI 1 "" "mX")] UNSPEC_PIC_SYM))]
6208   "TARGET_32BIT && flag_pic"
6209   "ldr%?\\t%0, %1"
6210   [(set_attr "type" "load1")
6211    (set (attr "pool_range")
6212         (if_then_else (eq_attr "is_thumb" "no")
6213                       (const_int 4096)
6214                       (const_int 4094)))
6215    (set (attr "neg_pool_range")
6216         (if_then_else (eq_attr "is_thumb" "no")
6217                       (const_int 4084)
6218                       (const_int 0)))]
6221 (define_insn "pic_load_addr_thumb1"
6222   [(set (match_operand:SI 0 "s_register_operand" "=l")
6223         (unspec:SI [(match_operand:SI 1 "" "mX")] UNSPEC_PIC_SYM))]
6224   "TARGET_THUMB1 && flag_pic"
6225   "ldr\\t%0, %1"
6226   [(set_attr "type" "load1")
6227    (set (attr "pool_range") (const_int 1018))]
6230 (define_insn "pic_add_dot_plus_four"
6231   [(set (match_operand:SI 0 "register_operand" "=r")
6232         (unspec:SI [(match_operand:SI 1 "register_operand" "0")
6233                     (const_int 4)
6234                     (match_operand 2 "" "")]
6235                    UNSPEC_PIC_BASE))]
6236   "TARGET_THUMB"
6237   "*
6238   (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
6239                                      INTVAL (operands[2]));
6240   return \"add\\t%0, %|pc\";
6241   "
6242   [(set_attr "length" "2")
6243    (set_attr "type" "alu_sreg")]
6246 (define_insn "pic_add_dot_plus_eight"
6247   [(set (match_operand:SI 0 "register_operand" "=r")
6248         (unspec:SI [(match_operand:SI 1 "register_operand" "r")
6249                     (const_int 8)
6250                     (match_operand 2 "" "")]
6251                    UNSPEC_PIC_BASE))]
6252   "TARGET_ARM"
6253   "*
6254     (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
6255                                        INTVAL (operands[2]));
6256     return \"add%?\\t%0, %|pc, %1\";
6257   "
6258   [(set_attr "predicable" "yes")
6259    (set_attr "type" "alu_sreg")]
6262 (define_insn "tls_load_dot_plus_eight"
6263   [(set (match_operand:SI 0 "register_operand" "=r")
6264         (mem:SI (unspec:SI [(match_operand:SI 1 "register_operand" "r")
6265                             (const_int 8)
6266                             (match_operand 2 "" "")]
6267                            UNSPEC_PIC_BASE)))]
6268   "TARGET_ARM"
6269   "*
6270     (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
6271                                        INTVAL (operands[2]));
6272     return \"ldr%?\\t%0, [%|pc, %1]\t\t@ tls_load_dot_plus_eight\";
6273   "
6274   [(set_attr "predicable" "yes")
6275    (set_attr "type" "load1")]
6278 ;; PIC references to local variables can generate pic_add_dot_plus_eight
6279 ;; followed by a load.  These sequences can be crunched down to
6280 ;; tls_load_dot_plus_eight by a peephole.
6282 (define_peephole2
6283   [(set (match_operand:SI 0 "register_operand" "")
6284         (unspec:SI [(match_operand:SI 3 "register_operand" "")
6285                     (const_int 8)
6286                     (match_operand 1 "" "")]
6287                    UNSPEC_PIC_BASE))
6288    (set (match_operand:SI 2 "arm_general_register_operand" "")
6289         (mem:SI (match_dup 0)))]
6290   "TARGET_ARM && peep2_reg_dead_p (2, operands[0])"
6291   [(set (match_dup 2)
6292         (mem:SI (unspec:SI [(match_dup 3)
6293                             (const_int 8)
6294                             (match_dup 1)]
6295                            UNSPEC_PIC_BASE)))]
6296   ""
6299 (define_insn "pic_offset_arm"
6300   [(set (match_operand:SI 0 "register_operand" "=r")
6301         (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
6302                          (unspec:SI [(match_operand:SI 2 "" "X")]
6303                                     UNSPEC_PIC_OFFSET))))]
6304   "TARGET_VXWORKS_RTP && TARGET_ARM && flag_pic"
6305   "ldr%?\\t%0, [%1,%2]"
6306   [(set_attr "type" "load1")]
6309 (define_expand "builtin_setjmp_receiver"
6310   [(label_ref (match_operand 0 "" ""))]
6311   "flag_pic"
6312   "
6314   /* r3 is clobbered by set/longjmp, so we can use it as a scratch
6315      register.  */
6316   if (arm_pic_register != INVALID_REGNUM)
6317     arm_load_pic_register (1UL << 3);
6318   DONE;
6321 ;; If copying one reg to another we can set the condition codes according to
6322 ;; its value.  Such a move is common after a return from subroutine and the
6323 ;; result is being tested against zero.
6325 (define_insn "*movsi_compare0"
6326   [(set (reg:CC CC_REGNUM)
6327         (compare:CC (match_operand:SI 1 "s_register_operand" "0,r")
6328                     (const_int 0)))
6329    (set (match_operand:SI 0 "s_register_operand" "=r,r")
6330         (match_dup 1))]
6331   "TARGET_32BIT"
6332   "@
6333    cmp%?\\t%0, #0
6334    subs%?\\t%0, %1, #0"
6335   [(set_attr "conds" "set")
6336    (set_attr "type" "alus_imm,alus_imm")]
6339 ;; Subroutine to store a half word from a register into memory.
6340 ;; Operand 0 is the source register (HImode)
6341 ;; Operand 1 is the destination address in a register (SImode)
6343 ;; In both this routine and the next, we must be careful not to spill
6344 ;; a memory address of reg+large_const into a separate PLUS insn, since this
6345 ;; can generate unrecognizable rtl.
6347 (define_expand "storehi"
6348   [;; store the low byte
6349    (set (match_operand 1 "" "") (match_dup 3))
6350    ;; extract the high byte
6351    (set (match_dup 2)
6352         (ashiftrt:SI (match_operand 0 "" "") (const_int 8)))
6353    ;; store the high byte
6354    (set (match_dup 4) (match_dup 5))]
6355   "TARGET_ARM"
6356   "
6357   {
6358     rtx op1 = operands[1];
6359     rtx addr = XEXP (op1, 0);
6360     enum rtx_code code = GET_CODE (addr);
6362     if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1)))
6363         || code == MINUS)
6364       op1 = replace_equiv_address (operands[1], force_reg (SImode, addr));
6366     operands[4] = adjust_address (op1, QImode, 1);
6367     operands[1] = adjust_address (operands[1], QImode, 0);
6368     operands[3] = gen_lowpart (QImode, operands[0]);
6369     operands[0] = gen_lowpart (SImode, operands[0]);
6370     operands[2] = gen_reg_rtx (SImode);
6371     operands[5] = gen_lowpart (QImode, operands[2]);
6372   }"
6375 (define_expand "storehi_bigend"
6376   [(set (match_dup 4) (match_dup 3))
6377    (set (match_dup 2)
6378         (ashiftrt:SI (match_operand 0 "" "") (const_int 8)))
6379    (set (match_operand 1 "" "") (match_dup 5))]
6380   "TARGET_ARM"
6381   "
6382   {
6383     rtx op1 = operands[1];
6384     rtx addr = XEXP (op1, 0);
6385     enum rtx_code code = GET_CODE (addr);
6387     if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1)))
6388         || code == MINUS)
6389       op1 = replace_equiv_address (op1, force_reg (SImode, addr));
6391     operands[4] = adjust_address (op1, QImode, 1);
6392     operands[1] = adjust_address (operands[1], QImode, 0);
6393     operands[3] = gen_lowpart (QImode, operands[0]);
6394     operands[0] = gen_lowpart (SImode, operands[0]);
6395     operands[2] = gen_reg_rtx (SImode);
6396     operands[5] = gen_lowpart (QImode, operands[2]);
6397   }"
6400 ;; Subroutine to store a half word integer constant into memory.
6401 (define_expand "storeinthi"
6402   [(set (match_operand 0 "" "")
6403         (match_operand 1 "" ""))
6404    (set (match_dup 3) (match_dup 2))]
6405   "TARGET_ARM"
6406   "
6407   {
6408     HOST_WIDE_INT value = INTVAL (operands[1]);
6409     rtx addr = XEXP (operands[0], 0);
6410     rtx op0 = operands[0];
6411     enum rtx_code code = GET_CODE (addr);
6413     if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1)))
6414         || code == MINUS)
6415       op0 = replace_equiv_address (op0, force_reg (SImode, addr));
6417     operands[1] = gen_reg_rtx (SImode);
6418     if (BYTES_BIG_ENDIAN)
6419       {
6420         emit_insn (gen_movsi (operands[1], GEN_INT ((value >> 8) & 255)));
6421         if ((value & 255) == ((value >> 8) & 255))
6422           operands[2] = operands[1];
6423         else
6424           {
6425             operands[2] = gen_reg_rtx (SImode);
6426             emit_insn (gen_movsi (operands[2], GEN_INT (value & 255)));
6427           }
6428       }
6429     else
6430       {
6431         emit_insn (gen_movsi (operands[1], GEN_INT (value & 255)));
6432         if ((value & 255) == ((value >> 8) & 255))
6433           operands[2] = operands[1];
6434         else
6435           {
6436             operands[2] = gen_reg_rtx (SImode);
6437             emit_insn (gen_movsi (operands[2], GEN_INT ((value >> 8) & 255)));
6438           }
6439       }
6441     operands[3] = adjust_address (op0, QImode, 1);
6442     operands[0] = adjust_address (operands[0], QImode, 0);
6443     operands[2] = gen_lowpart (QImode, operands[2]);
6444     operands[1] = gen_lowpart (QImode, operands[1]);
6445   }"
6448 (define_expand "storehi_single_op"
6449   [(set (match_operand:HI 0 "memory_operand" "")
6450         (match_operand:HI 1 "general_operand" ""))]
6451   "TARGET_32BIT && arm_arch4"
6452   "
6453   if (!s_register_operand (operands[1], HImode))
6454     operands[1] = copy_to_mode_reg (HImode, operands[1]);
6455   "
6458 (define_expand "movhi"
6459   [(set (match_operand:HI 0 "general_operand" "")
6460         (match_operand:HI 1 "general_operand" ""))]
6461   "TARGET_EITHER"
6462   "
6463   if (TARGET_ARM)
6464     {
6465       if (can_create_pseudo_p ())
6466         {
6467           if (MEM_P (operands[0]))
6468             {
6469               if (arm_arch4)
6470                 {
6471                   emit_insn (gen_storehi_single_op (operands[0], operands[1]));
6472                   DONE;
6473                 }
6474               if (CONST_INT_P (operands[1]))
6475                 emit_insn (gen_storeinthi (operands[0], operands[1]));
6476               else
6477                 {
6478                   if (MEM_P (operands[1]))
6479                     operands[1] = force_reg (HImode, operands[1]);
6480                   if (BYTES_BIG_ENDIAN)
6481                     emit_insn (gen_storehi_bigend (operands[1], operands[0]));
6482                   else
6483                    emit_insn (gen_storehi (operands[1], operands[0]));
6484                 }
6485               DONE;
6486             }
6487           /* Sign extend a constant, and keep it in an SImode reg.  */
6488           else if (CONST_INT_P (operands[1]))
6489             {
6490               rtx reg = gen_reg_rtx (SImode);
6491               HOST_WIDE_INT val = INTVAL (operands[1]) & 0xffff;
6493               /* If the constant is already valid, leave it alone.  */
6494               if (!const_ok_for_arm (val))
6495                 {
6496                   /* If setting all the top bits will make the constant 
6497                      loadable in a single instruction, then set them.  
6498                      Otherwise, sign extend the number.  */
6500                   if (const_ok_for_arm (~(val | ~0xffff)))
6501                     val |= ~0xffff;
6502                   else if (val & 0x8000)
6503                     val |= ~0xffff;
6504                 }
6506               emit_insn (gen_movsi (reg, GEN_INT (val)));
6507               operands[1] = gen_lowpart (HImode, reg);
6508             }
6509           else if (arm_arch4 && optimize && can_create_pseudo_p ()
6510                    && MEM_P (operands[1]))
6511             {
6512               rtx reg = gen_reg_rtx (SImode);
6514               emit_insn (gen_zero_extendhisi2 (reg, operands[1]));
6515               operands[1] = gen_lowpart (HImode, reg);
6516             }
6517           else if (!arm_arch4)
6518             {
6519               if (MEM_P (operands[1]))
6520                 {
6521                   rtx base;
6522                   rtx offset = const0_rtx;
6523                   rtx reg = gen_reg_rtx (SImode);
6525                   if ((REG_P (base = XEXP (operands[1], 0))
6526                        || (GET_CODE (base) == PLUS
6527                            && (CONST_INT_P (offset = XEXP (base, 1)))
6528                            && ((INTVAL(offset) & 1) != 1)
6529                            && REG_P (base = XEXP (base, 0))))
6530                       && REGNO_POINTER_ALIGN (REGNO (base)) >= 32)
6531                     {
6532                       rtx new_rtx;
6534                       new_rtx = widen_memory_access (operands[1], SImode,
6535                                                      ((INTVAL (offset) & ~3)
6536                                                       - INTVAL (offset)));
6537                       emit_insn (gen_movsi (reg, new_rtx));
6538                       if (((INTVAL (offset) & 2) != 0)
6539                           ^ (BYTES_BIG_ENDIAN ? 1 : 0))
6540                         {
6541                           rtx reg2 = gen_reg_rtx (SImode);
6543                           emit_insn (gen_lshrsi3 (reg2, reg, GEN_INT (16)));
6544                           reg = reg2;
6545                         }
6546                     }
6547                   else
6548                     emit_insn (gen_movhi_bytes (reg, operands[1]));
6550                   operands[1] = gen_lowpart (HImode, reg);
6551                }
6552            }
6553         }
6554       /* Handle loading a large integer during reload.  */
6555       else if (CONST_INT_P (operands[1])
6556                && !const_ok_for_arm (INTVAL (operands[1]))
6557                && !const_ok_for_arm (~INTVAL (operands[1])))
6558         {
6559           /* Writing a constant to memory needs a scratch, which should
6560              be handled with SECONDARY_RELOADs.  */
6561           gcc_assert (REG_P (operands[0]));
6563           operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
6564           emit_insn (gen_movsi (operands[0], operands[1]));
6565           DONE;
6566        }
6567     }
6568   else if (TARGET_THUMB2)
6569     {
6570       /* Thumb-2 can do everything except mem=mem and mem=const easily.  */
6571       if (can_create_pseudo_p ())
6572         {
6573           if (!REG_P (operands[0]))
6574             operands[1] = force_reg (HImode, operands[1]);
6575           /* Zero extend a constant, and keep it in an SImode reg.  */
6576           else if (CONST_INT_P (operands[1]))
6577             {
6578               rtx reg = gen_reg_rtx (SImode);
6579               HOST_WIDE_INT val = INTVAL (operands[1]) & 0xffff;
6581               emit_insn (gen_movsi (reg, GEN_INT (val)));
6582               operands[1] = gen_lowpart (HImode, reg);
6583             }
6584         }
6585     }
6586   else /* TARGET_THUMB1 */
6587     {
6588       if (can_create_pseudo_p ())
6589         {
6590           if (CONST_INT_P (operands[1]))
6591             {
6592               rtx reg = gen_reg_rtx (SImode);
6594               emit_insn (gen_movsi (reg, operands[1]));
6595               operands[1] = gen_lowpart (HImode, reg);
6596             }
6598           /* ??? We shouldn't really get invalid addresses here, but this can
6599              happen if we are passed a SP (never OK for HImode/QImode) or 
6600              virtual register (also rejected as illegitimate for HImode/QImode)
6601              relative address.  */
6602           /* ??? This should perhaps be fixed elsewhere, for instance, in
6603              fixup_stack_1, by checking for other kinds of invalid addresses,
6604              e.g. a bare reference to a virtual register.  This may confuse the
6605              alpha though, which must handle this case differently.  */
6606           if (MEM_P (operands[0])
6607               && !memory_address_p (GET_MODE (operands[0]),
6608                                     XEXP (operands[0], 0)))
6609             operands[0]
6610               = replace_equiv_address (operands[0],
6611                                        copy_to_reg (XEXP (operands[0], 0)));
6612    
6613           if (MEM_P (operands[1])
6614               && !memory_address_p (GET_MODE (operands[1]),
6615                                     XEXP (operands[1], 0)))
6616             operands[1]
6617               = replace_equiv_address (operands[1],
6618                                        copy_to_reg (XEXP (operands[1], 0)));
6620           if (MEM_P (operands[1]) && optimize > 0)
6621             {
6622               rtx reg = gen_reg_rtx (SImode);
6624               emit_insn (gen_zero_extendhisi2 (reg, operands[1]));
6625               operands[1] = gen_lowpart (HImode, reg);
6626             }
6628           if (MEM_P (operands[0]))
6629             operands[1] = force_reg (HImode, operands[1]);
6630         }
6631       else if (CONST_INT_P (operands[1])
6632                 && !satisfies_constraint_I (operands[1]))
6633         {
6634           /* Handle loading a large integer during reload.  */
6636           /* Writing a constant to memory needs a scratch, which should
6637              be handled with SECONDARY_RELOADs.  */
6638           gcc_assert (REG_P (operands[0]));
6640           operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
6641           emit_insn (gen_movsi (operands[0], operands[1]));
6642           DONE;
6643         }
6644     }
6645   "
6648 (define_expand "movhi_bytes"
6649   [(set (match_dup 2) (zero_extend:SI (match_operand:HI 1 "" "")))
6650    (set (match_dup 3)
6651         (zero_extend:SI (match_dup 6)))
6652    (set (match_operand:SI 0 "" "")
6653          (ior:SI (ashift:SI (match_dup 4) (const_int 8)) (match_dup 5)))]
6654   "TARGET_ARM"
6655   "
6656   {
6657     rtx mem1, mem2;
6658     rtx addr = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
6660     mem1 = change_address (operands[1], QImode, addr);
6661     mem2 = change_address (operands[1], QImode,
6662                            plus_constant (Pmode, addr, 1));
6663     operands[0] = gen_lowpart (SImode, operands[0]);
6664     operands[1] = mem1;
6665     operands[2] = gen_reg_rtx (SImode);
6666     operands[3] = gen_reg_rtx (SImode);
6667     operands[6] = mem2;
6669     if (BYTES_BIG_ENDIAN)
6670       {
6671         operands[4] = operands[2];
6672         operands[5] = operands[3];
6673       }
6674     else
6675       {
6676         operands[4] = operands[3];
6677         operands[5] = operands[2];
6678       }
6679   }"
6682 (define_expand "movhi_bigend"
6683   [(set (match_dup 2)
6684         (rotate:SI (subreg:SI (match_operand:HI 1 "memory_operand" "") 0)
6685                    (const_int 16)))
6686    (set (match_dup 3)
6687         (ashiftrt:SI (match_dup 2) (const_int 16)))
6688    (set (match_operand:HI 0 "s_register_operand" "")
6689         (match_dup 4))]
6690   "TARGET_ARM"
6691   "
6692   operands[2] = gen_reg_rtx (SImode);
6693   operands[3] = gen_reg_rtx (SImode);
6694   operands[4] = gen_lowpart (HImode, operands[3]);
6695   "
6698 ;; Pattern to recognize insn generated default case above
6699 (define_insn "*movhi_insn_arch4"
6700   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m,r")
6701         (match_operand:HI 1 "general_operand"      "rIk,K,n,r,mi"))]
6702   "TARGET_ARM
6703    && arm_arch4
6704    && (register_operand (operands[0], HImode)
6705        || register_operand (operands[1], HImode))"
6706   "@
6707    mov%?\\t%0, %1\\t%@ movhi
6708    mvn%?\\t%0, #%B1\\t%@ movhi
6709    movw%?\\t%0, %L1\\t%@ movhi
6710    strh%?\\t%1, %0\\t%@ movhi
6711    ldrh%?\\t%0, %1\\t%@ movhi"
6712   [(set_attr "predicable" "yes")
6713    (set_attr "pool_range" "*,*,*,*,256")
6714    (set_attr "neg_pool_range" "*,*,*,*,244")
6715    (set_attr "arch" "*,*,v6t2,*,*")
6716    (set_attr_alternative "type"
6717                          [(if_then_else (match_operand 1 "const_int_operand" "")
6718                                         (const_string "mov_imm" )
6719                                         (const_string "mov_reg"))
6720                           (const_string "mvn_imm")
6721                           (const_string "mov_imm")
6722                           (const_string "store1")
6723                           (const_string "load1")])]
6726 (define_insn "*movhi_bytes"
6727   [(set (match_operand:HI 0 "s_register_operand" "=r,r,r")
6728         (match_operand:HI 1 "arm_rhs_operand"  "I,rk,K"))]
6729   "TARGET_ARM"
6730   "@
6731    mov%?\\t%0, %1\\t%@ movhi
6732    mov%?\\t%0, %1\\t%@ movhi
6733    mvn%?\\t%0, #%B1\\t%@ movhi"
6734   [(set_attr "predicable" "yes")
6735    (set_attr "type" "mov_imm,mov_reg,mvn_imm")]
6737         
6738 ;; We use a DImode scratch because we may occasionally need an additional
6739 ;; temporary if the address isn't offsettable -- push_reload doesn't seem
6740 ;; to take any notice of the "o" constraints on reload_memory_operand operand.
6741 (define_expand "reload_outhi"
6742   [(parallel [(match_operand:HI 0 "arm_reload_memory_operand" "=o")
6743               (match_operand:HI 1 "s_register_operand"        "r")
6744               (match_operand:DI 2 "s_register_operand"        "=&l")])]
6745   "TARGET_EITHER"
6746   "if (TARGET_ARM)
6747      arm_reload_out_hi (operands);
6748    else
6749      thumb_reload_out_hi (operands);
6750   DONE;
6751   "
6754 (define_expand "reload_inhi"
6755   [(parallel [(match_operand:HI 0 "s_register_operand" "=r")
6756               (match_operand:HI 1 "arm_reload_memory_operand" "o")
6757               (match_operand:DI 2 "s_register_operand" "=&r")])]
6758   "TARGET_EITHER"
6759   "
6760   if (TARGET_ARM)
6761     arm_reload_in_hi (operands);
6762   else
6763     thumb_reload_out_hi (operands);
6764   DONE;
6767 (define_expand "movqi"
6768   [(set (match_operand:QI 0 "general_operand" "")
6769         (match_operand:QI 1 "general_operand" ""))]
6770   "TARGET_EITHER"
6771   "
6772   /* Everything except mem = const or mem = mem can be done easily */
6774   if (can_create_pseudo_p ())
6775     {
6776       if (CONST_INT_P (operands[1]))
6777         {
6778           rtx reg = gen_reg_rtx (SImode);
6780           /* For thumb we want an unsigned immediate, then we are more likely 
6781              to be able to use a movs insn.  */
6782           if (TARGET_THUMB)
6783             operands[1] = GEN_INT (INTVAL (operands[1]) & 255);
6785           emit_insn (gen_movsi (reg, operands[1]));
6786           operands[1] = gen_lowpart (QImode, reg);
6787         }
6789       if (TARGET_THUMB)
6790         {
6791           /* ??? We shouldn't really get invalid addresses here, but this can
6792              happen if we are passed a SP (never OK for HImode/QImode) or
6793              virtual register (also rejected as illegitimate for HImode/QImode)
6794              relative address.  */
6795           /* ??? This should perhaps be fixed elsewhere, for instance, in
6796              fixup_stack_1, by checking for other kinds of invalid addresses,
6797              e.g. a bare reference to a virtual register.  This may confuse the
6798              alpha though, which must handle this case differently.  */
6799           if (MEM_P (operands[0])
6800               && !memory_address_p (GET_MODE (operands[0]),
6801                                      XEXP (operands[0], 0)))
6802             operands[0]
6803               = replace_equiv_address (operands[0],
6804                                        copy_to_reg (XEXP (operands[0], 0)));
6805           if (MEM_P (operands[1])
6806               && !memory_address_p (GET_MODE (operands[1]),
6807                                     XEXP (operands[1], 0)))
6808              operands[1]
6809                = replace_equiv_address (operands[1],
6810                                         copy_to_reg (XEXP (operands[1], 0)));
6811         }
6813       if (MEM_P (operands[1]) && optimize > 0)
6814         {
6815           rtx reg = gen_reg_rtx (SImode);
6817           emit_insn (gen_zero_extendqisi2 (reg, operands[1]));
6818           operands[1] = gen_lowpart (QImode, reg);
6819         }
6821       if (MEM_P (operands[0]))
6822         operands[1] = force_reg (QImode, operands[1]);
6823     }
6824   else if (TARGET_THUMB
6825            && CONST_INT_P (operands[1])
6826            && !satisfies_constraint_I (operands[1]))
6827     {
6828       /* Handle loading a large integer during reload.  */
6830       /* Writing a constant to memory needs a scratch, which should
6831          be handled with SECONDARY_RELOADs.  */
6832       gcc_assert (REG_P (operands[0]));
6834       operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
6835       emit_insn (gen_movsi (operands[0], operands[1]));
6836       DONE;
6837     }
6838   "
6841 (define_insn "*arm_movqi_insn"
6842   [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,r,l,r,l,Uu,r,m")
6843         (match_operand:QI 1 "general_operand" "rk,rk,I,Py,K,Uu,l,Uh,r"))]
6844   "TARGET_32BIT
6845    && (   register_operand (operands[0], QImode)
6846        || register_operand (operands[1], QImode))"
6847   "@
6848    mov%?\\t%0, %1
6849    mov%?\\t%0, %1
6850    mov%?\\t%0, %1
6851    mov%?\\t%0, %1
6852    mvn%?\\t%0, #%B1
6853    ldrb%?\\t%0, %1
6854    strb%?\\t%1, %0
6855    ldrb%?\\t%0, %1
6856    strb%?\\t%1, %0"
6857   [(set_attr "type" "mov_reg,mov_reg,mov_imm,mov_imm,mvn_imm,load1,store1,load1,store1")
6858    (set_attr "predicable" "yes")
6859    (set_attr "predicable_short_it" "yes,yes,no,yes,no,no,no,no,no")
6860    (set_attr "arch" "t2,any,any,t2,any,t2,t2,any,any")
6861    (set_attr "length" "2,4,4,2,4,2,2,4,4")]
6864 ;; HFmode moves
6865 (define_expand "movhf"
6866   [(set (match_operand:HF 0 "general_operand" "")
6867         (match_operand:HF 1 "general_operand" ""))]
6868   "TARGET_EITHER"
6869   "
6870   if (TARGET_32BIT)
6871     {
6872       if (MEM_P (operands[0]))
6873         operands[1] = force_reg (HFmode, operands[1]);
6874     }
6875   else /* TARGET_THUMB1 */
6876     {
6877       if (can_create_pseudo_p ())
6878         {
6879            if (!REG_P (operands[0]))
6880              operands[1] = force_reg (HFmode, operands[1]);
6881         }
6882     }
6883   "
6886 (define_insn "*arm32_movhf"
6887   [(set (match_operand:HF 0 "nonimmediate_operand" "=r,m,r,r")
6888         (match_operand:HF 1 "general_operand"      " m,r,r,F"))]
6889   "TARGET_32BIT && !(TARGET_HARD_FLOAT && TARGET_VFP)
6890    && (   s_register_operand (operands[0], HFmode)
6891        || s_register_operand (operands[1], HFmode))"
6892   "*
6893   switch (which_alternative)
6894     {
6895     case 0:     /* ARM register from memory */
6896       return \"ldrh%?\\t%0, %1\\t%@ __fp16\";
6897     case 1:     /* memory from ARM register */
6898       return \"strh%?\\t%1, %0\\t%@ __fp16\";
6899     case 2:     /* ARM register from ARM register */
6900       return \"mov%?\\t%0, %1\\t%@ __fp16\";
6901     case 3:     /* ARM register from constant */
6902       {
6903         long bits;
6904         rtx ops[4];
6906         bits = real_to_target (NULL, CONST_DOUBLE_REAL_VALUE (operands[1]),
6907                                HFmode);
6908         ops[0] = operands[0];
6909         ops[1] = GEN_INT (bits);
6910         ops[2] = GEN_INT (bits & 0xff00);
6911         ops[3] = GEN_INT (bits & 0x00ff);
6913         if (arm_arch_thumb2)
6914           output_asm_insn (\"movw%?\\t%0, %1\", ops);
6915         else
6916           output_asm_insn (\"mov%?\\t%0, %2\;orr%?\\t%0, %0, %3\", ops);
6917         return \"\";
6918        }
6919     default:
6920       gcc_unreachable ();
6921     }
6922   "
6923   [(set_attr "conds" "unconditional")
6924    (set_attr "type" "load1,store1,mov_reg,multiple")
6925    (set_attr "length" "4,4,4,8")
6926    (set_attr "predicable" "yes")
6927    (set_attr "predicable_short_it" "no")]
6930 (define_expand "movsf"
6931   [(set (match_operand:SF 0 "general_operand" "")
6932         (match_operand:SF 1 "general_operand" ""))]
6933   "TARGET_EITHER"
6934   "
6935   if (TARGET_32BIT)
6936     {
6937       if (MEM_P (operands[0]))
6938         operands[1] = force_reg (SFmode, operands[1]);
6939     }
6940   else /* TARGET_THUMB1 */
6941     {
6942       if (can_create_pseudo_p ())
6943         {
6944            if (!REG_P (operands[0]))
6945              operands[1] = force_reg (SFmode, operands[1]);
6946         }
6947     }
6948   "
6951 ;; Transform a floating-point move of a constant into a core register into
6952 ;; an SImode operation.
6953 (define_split
6954   [(set (match_operand:SF 0 "arm_general_register_operand" "")
6955         (match_operand:SF 1 "immediate_operand" ""))]
6956   "TARGET_EITHER
6957    && reload_completed
6958    && CONST_DOUBLE_P (operands[1])"
6959   [(set (match_dup 2) (match_dup 3))]
6960   "
6961   operands[2] = gen_lowpart (SImode, operands[0]);
6962   operands[3] = gen_lowpart (SImode, operands[1]);
6963   if (operands[2] == 0 || operands[3] == 0)
6964     FAIL;
6965   "
6968 (define_insn "*arm_movsf_soft_insn"
6969   [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,m")
6970         (match_operand:SF 1 "general_operand"  "r,mE,r"))]
6971   "TARGET_32BIT
6972    && TARGET_SOFT_FLOAT
6973    && (!MEM_P (operands[0])
6974        || register_operand (operands[1], SFmode))"
6975   "@
6976    mov%?\\t%0, %1
6977    ldr%?\\t%0, %1\\t%@ float
6978    str%?\\t%1, %0\\t%@ float"
6979   [(set_attr "predicable" "yes")
6980    (set_attr "predicable_short_it" "no")
6981    (set_attr "type" "mov_reg,load1,store1")
6982    (set_attr "arm_pool_range" "*,4096,*")
6983    (set_attr "thumb2_pool_range" "*,4094,*")
6984    (set_attr "arm_neg_pool_range" "*,4084,*")
6985    (set_attr "thumb2_neg_pool_range" "*,0,*")]
6988 (define_expand "movdf"
6989   [(set (match_operand:DF 0 "general_operand" "")
6990         (match_operand:DF 1 "general_operand" ""))]
6991   "TARGET_EITHER"
6992   "
6993   if (TARGET_32BIT)
6994     {
6995       if (MEM_P (operands[0]))
6996         operands[1] = force_reg (DFmode, operands[1]);
6997     }
6998   else /* TARGET_THUMB */
6999     {
7000       if (can_create_pseudo_p ())
7001         {
7002           if (!REG_P (operands[0]))
7003             operands[1] = force_reg (DFmode, operands[1]);
7004         }
7005     }
7006   "
7009 ;; Reloading a df mode value stored in integer regs to memory can require a
7010 ;; scratch reg.
7011 (define_expand "reload_outdf"
7012   [(match_operand:DF 0 "arm_reload_memory_operand" "=o")
7013    (match_operand:DF 1 "s_register_operand" "r")
7014    (match_operand:SI 2 "s_register_operand" "=&r")]
7015   "TARGET_THUMB2"
7016   "
7017   {
7018     enum rtx_code code = GET_CODE (XEXP (operands[0], 0));
7020     if (code == REG)
7021       operands[2] = XEXP (operands[0], 0);
7022     else if (code == POST_INC || code == PRE_DEC)
7023       {
7024         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7025         operands[1] = gen_rtx_SUBREG (DImode, operands[1], 0);
7026         emit_insn (gen_movdi (operands[0], operands[1]));
7027         DONE;
7028       }
7029     else if (code == PRE_INC)
7030       {
7031         rtx reg = XEXP (XEXP (operands[0], 0), 0);
7033         emit_insn (gen_addsi3 (reg, reg, GEN_INT (8)));
7034         operands[2] = reg;
7035       }
7036     else if (code == POST_DEC)
7037       operands[2] = XEXP (XEXP (operands[0], 0), 0);
7038     else
7039       emit_insn (gen_addsi3 (operands[2], XEXP (XEXP (operands[0], 0), 0),
7040                              XEXP (XEXP (operands[0], 0), 1)));
7042     emit_insn (gen_rtx_SET (replace_equiv_address (operands[0], operands[2]),
7043                             operands[1]));
7045     if (code == POST_DEC)
7046       emit_insn (gen_addsi3 (operands[2], operands[2], GEN_INT (-8)));
7048     DONE;
7049   }"
7052 (define_insn "*movdf_soft_insn"
7053   [(set (match_operand:DF 0 "nonimmediate_soft_df_operand" "=r,r,r,q,m")
7054         (match_operand:DF 1 "soft_df_operand" "rDa,Db,Dc,mF,q"))]
7055   "TARGET_32BIT && TARGET_SOFT_FLOAT
7056    && (   register_operand (operands[0], DFmode)
7057        || register_operand (operands[1], DFmode))"
7058   "*
7059   switch (which_alternative)
7060     {
7061     case 0:
7062     case 1:
7063     case 2:
7064       return \"#\";
7065     default:
7066       return output_move_double (operands, true, NULL);
7067     }
7068   "
7069   [(set_attr "length" "8,12,16,8,8")
7070    (set_attr "type" "multiple,multiple,multiple,load2,store2")
7071    (set_attr "arm_pool_range" "*,*,*,1020,*")
7072    (set_attr "thumb2_pool_range" "*,*,*,1018,*")
7073    (set_attr "arm_neg_pool_range" "*,*,*,1004,*")
7074    (set_attr "thumb2_neg_pool_range" "*,*,*,0,*")]
7078 ;; load- and store-multiple insns
7079 ;; The arm can load/store any set of registers, provided that they are in
7080 ;; ascending order, but these expanders assume a contiguous set.
7082 (define_expand "load_multiple"
7083   [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
7084                           (match_operand:SI 1 "" ""))
7085                      (use (match_operand:SI 2 "" ""))])]
7086   "TARGET_32BIT"
7088   HOST_WIDE_INT offset = 0;
7090   /* Support only fixed point registers.  */
7091   if (!CONST_INT_P (operands[2])
7092       || INTVAL (operands[2]) > MAX_LDM_STM_OPS
7093       || INTVAL (operands[2]) < 2
7094       || !MEM_P (operands[1])
7095       || !REG_P (operands[0])
7096       || REGNO (operands[0]) > (LAST_ARM_REGNUM - 1)
7097       || REGNO (operands[0]) + INTVAL (operands[2]) > LAST_ARM_REGNUM)
7098     FAIL;
7100   operands[3]
7101     = arm_gen_load_multiple (arm_regs_in_sequence + REGNO (operands[0]),
7102                              INTVAL (operands[2]),
7103                              force_reg (SImode, XEXP (operands[1], 0)),
7104                              FALSE, operands[1], &offset);
7107 (define_expand "store_multiple"
7108   [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
7109                           (match_operand:SI 1 "" ""))
7110                      (use (match_operand:SI 2 "" ""))])]
7111   "TARGET_32BIT"
7113   HOST_WIDE_INT offset = 0;
7115   /* Support only fixed point registers.  */
7116   if (!CONST_INT_P (operands[2])
7117       || INTVAL (operands[2]) > MAX_LDM_STM_OPS
7118       || INTVAL (operands[2]) < 2
7119       || !REG_P (operands[1])
7120       || !MEM_P (operands[0])
7121       || REGNO (operands[1]) > (LAST_ARM_REGNUM - 1)
7122       || REGNO (operands[1]) + INTVAL (operands[2]) > LAST_ARM_REGNUM)
7123     FAIL;
7125   operands[3]
7126     = arm_gen_store_multiple (arm_regs_in_sequence + REGNO (operands[1]),
7127                               INTVAL (operands[2]),
7128                               force_reg (SImode, XEXP (operands[0], 0)),
7129                               FALSE, operands[0], &offset);
7133 (define_expand "setmemsi"
7134   [(match_operand:BLK 0 "general_operand" "")
7135    (match_operand:SI 1 "const_int_operand" "")
7136    (match_operand:SI 2 "const_int_operand" "")
7137    (match_operand:SI 3 "const_int_operand" "")]
7138   "TARGET_32BIT"
7140   if (arm_gen_setmem (operands))
7141     DONE;
7143   FAIL;
7147 ;; Move a block of memory if it is word aligned and MORE than 2 words long.
7148 ;; We could let this apply for blocks of less than this, but it clobbers so
7149 ;; many registers that there is then probably a better way.
7151 (define_expand "movmemqi"
7152   [(match_operand:BLK 0 "general_operand" "")
7153    (match_operand:BLK 1 "general_operand" "")
7154    (match_operand:SI 2 "const_int_operand" "")
7155    (match_operand:SI 3 "const_int_operand" "")]
7156   ""
7157   "
7158   if (TARGET_32BIT)
7159     {
7160       if (TARGET_LDRD && current_tune->prefer_ldrd_strd
7161           && !optimize_function_for_size_p (cfun))
7162         {
7163           if (gen_movmem_ldrd_strd (operands))
7164             DONE;
7165           FAIL;
7166         }
7168       if (arm_gen_movmemqi (operands))
7169         DONE;
7170       FAIL;
7171     }
7172   else /* TARGET_THUMB1 */
7173     {
7174       if (   INTVAL (operands[3]) != 4
7175           || INTVAL (operands[2]) > 48)
7176         FAIL;
7178       thumb_expand_movmemqi (operands);
7179       DONE;
7180     }
7181   "
7185 ;; Compare & branch insns
7186 ;; The range calculations are based as follows:
7187 ;; For forward branches, the address calculation returns the address of
7188 ;; the next instruction.  This is 2 beyond the branch instruction.
7189 ;; For backward branches, the address calculation returns the address of
7190 ;; the first instruction in this pattern (cmp).  This is 2 before the branch
7191 ;; instruction for the shortest sequence, and 4 before the branch instruction
7192 ;; if we have to jump around an unconditional branch.
7193 ;; To the basic branch range the PC offset must be added (this is +4).
7194 ;; So for forward branches we have 
7195 ;;   (pos_range - pos_base_offs + pc_offs) = (pos_range - 2 + 4).
7196 ;; And for backward branches we have 
7197 ;;   (neg_range - neg_base_offs + pc_offs) = (neg_range - (-2 or -4) + 4).
7199 ;; For a 'b'       pos_range = 2046, neg_range = -2048 giving (-2040->2048).
7200 ;; For a 'b<cond>' pos_range = 254,  neg_range = -256  giving (-250 ->256).
7202 (define_expand "cbranchsi4"
7203   [(set (pc) (if_then_else
7204               (match_operator 0 "expandable_comparison_operator"
7205                [(match_operand:SI 1 "s_register_operand" "")
7206                 (match_operand:SI 2 "nonmemory_operand" "")])
7207               (label_ref (match_operand 3 "" ""))
7208               (pc)))]
7209   "TARGET_EITHER"
7210   "
7211   if (!TARGET_THUMB1)
7212     {
7213       if (!arm_validize_comparison (&operands[0], &operands[1], &operands[2]))
7214         FAIL;
7215       emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
7216                                       operands[3]));
7217       DONE;
7218     }
7219   if (thumb1_cmpneg_operand (operands[2], SImode))
7220     {
7221       emit_jump_insn (gen_cbranchsi4_scratch (NULL, operands[1], operands[2],
7222                                               operands[3], operands[0]));
7223       DONE;
7224     }
7225   if (!thumb1_cmp_operand (operands[2], SImode))
7226     operands[2] = force_reg (SImode, operands[2]);
7227   ")
7229 (define_expand "cbranchsf4"
7230   [(set (pc) (if_then_else
7231               (match_operator 0 "expandable_comparison_operator"
7232                [(match_operand:SF 1 "s_register_operand" "")
7233                 (match_operand:SF 2 "arm_float_compare_operand" "")])
7234               (label_ref (match_operand 3 "" ""))
7235               (pc)))]
7236   "TARGET_32BIT && TARGET_HARD_FLOAT"
7237   "emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
7238                                    operands[3])); DONE;"
7241 (define_expand "cbranchdf4"
7242   [(set (pc) (if_then_else
7243               (match_operator 0 "expandable_comparison_operator"
7244                [(match_operand:DF 1 "s_register_operand" "")
7245                 (match_operand:DF 2 "arm_float_compare_operand" "")])
7246               (label_ref (match_operand 3 "" ""))
7247               (pc)))]
7248   "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
7249   "emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
7250                                    operands[3])); DONE;"
7253 (define_expand "cbranchdi4"
7254   [(set (pc) (if_then_else
7255               (match_operator 0 "expandable_comparison_operator"
7256                [(match_operand:DI 1 "s_register_operand" "")
7257                 (match_operand:DI 2 "cmpdi_operand" "")])
7258               (label_ref (match_operand 3 "" ""))
7259               (pc)))]
7260   "TARGET_32BIT"
7261   "{
7262      if (!arm_validize_comparison (&operands[0], &operands[1], &operands[2]))
7263        FAIL;
7264      emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
7265                                        operands[3]));
7266      DONE;
7267    }"
7270 ;; Comparison and test insns
7272 (define_insn "*arm_cmpsi_insn"
7273   [(set (reg:CC CC_REGNUM)
7274         (compare:CC (match_operand:SI 0 "s_register_operand" "l,r,r,r,r")
7275                     (match_operand:SI 1 "arm_add_operand"    "Py,r,r,I,L")))]
7276   "TARGET_32BIT"
7277   "@
7278    cmp%?\\t%0, %1
7279    cmp%?\\t%0, %1
7280    cmp%?\\t%0, %1
7281    cmp%?\\t%0, %1
7282    cmn%?\\t%0, #%n1"
7283   [(set_attr "conds" "set")
7284    (set_attr "arch" "t2,t2,any,any,any")
7285    (set_attr "length" "2,2,4,4,4")
7286    (set_attr "predicable" "yes")
7287    (set_attr "predicable_short_it" "yes,yes,yes,no,no")
7288    (set_attr "type" "alus_imm,alus_sreg,alus_sreg,alus_imm,alus_imm")]
7291 (define_insn "*cmpsi_shiftsi"
7292   [(set (reg:CC CC_REGNUM)
7293         (compare:CC (match_operand:SI   0 "s_register_operand" "r,r,r")
7294                     (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   "TARGET_32BIT"
7298   "cmp\\t%0, %1%S3"
7299   [(set_attr "conds" "set")
7300    (set_attr "shift" "1")
7301    (set_attr "arch" "32,a,a")
7302    (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
7304 (define_insn "*cmpsi_shiftsi_swp"
7305   [(set (reg:CC_SWP CC_REGNUM)
7306         (compare:CC_SWP (match_operator:SI 3 "shift_operator"
7307                          [(match_operand:SI 1 "s_register_operand" "r,r,r")
7308                           (match_operand:SI 2 "shift_amount_operand" "M,r,M")])
7309                         (match_operand:SI 0 "s_register_operand" "r,r,r")))]
7310   "TARGET_32BIT"
7311   "cmp%?\\t%0, %1%S3"
7312   [(set_attr "conds" "set")
7313    (set_attr "shift" "1")
7314    (set_attr "arch" "32,a,a")
7315    (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
7317 (define_insn "*arm_cmpsi_negshiftsi_si"
7318   [(set (reg:CC_Z CC_REGNUM)
7319         (compare:CC_Z
7320          (neg:SI (match_operator:SI 1 "shift_operator"
7321                     [(match_operand:SI 2 "s_register_operand" "r")
7322                      (match_operand:SI 3 "reg_or_int_operand" "rM")]))
7323          (match_operand:SI 0 "s_register_operand" "r")))]
7324   "TARGET_ARM"
7325   "cmn%?\\t%0, %2%S1"
7326   [(set_attr "conds" "set")
7327    (set (attr "type") (if_then_else (match_operand 3 "const_int_operand" "")
7328                                     (const_string "alus_shift_imm")
7329                                     (const_string "alus_shift_reg")))
7330    (set_attr "predicable" "yes")]
7333 ;; DImode comparisons.  The generic code generates branches that
7334 ;; if-conversion can not reduce to a conditional compare, so we do
7335 ;; that directly.
7337 (define_insn_and_split "*arm_cmpdi_insn"
7338   [(set (reg:CC_NCV CC_REGNUM)
7339         (compare:CC_NCV (match_operand:DI 0 "s_register_operand" "r")
7340                         (match_operand:DI 1 "arm_di_operand"       "rDi")))
7341    (clobber (match_scratch:SI 2 "=r"))]
7342   "TARGET_32BIT"
7343   "#"   ; "cmp\\t%Q0, %Q1\;sbcs\\t%2, %R0, %R1"
7344   "&& reload_completed"
7345   [(set (reg:CC CC_REGNUM)
7346         (compare:CC (match_dup 0) (match_dup 1)))
7347    (parallel [(set (reg:CC CC_REGNUM)
7348                    (compare:CC (match_dup 3) (match_dup 4)))
7349               (set (match_dup 2)
7350                    (minus:SI (match_dup 5)
7351                             (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))])]
7352   {
7353     operands[3] = gen_highpart (SImode, operands[0]);
7354     operands[0] = gen_lowpart (SImode, operands[0]);
7355     if (CONST_INT_P (operands[1]))
7356       {
7357         operands[4] = GEN_INT (~INTVAL (gen_highpart_mode (SImode,
7358                                                            DImode,
7359                                                            operands[1])));
7360         operands[5] = gen_rtx_PLUS (SImode, operands[3], operands[4]);
7361       }
7362     else
7363       {
7364         operands[4] = gen_highpart (SImode, operands[1]);
7365         operands[5] = gen_rtx_MINUS (SImode, operands[3], operands[4]);
7366       }
7367     operands[1] = gen_lowpart (SImode, operands[1]);
7368     operands[2] = gen_lowpart (SImode, operands[2]);
7369   }
7370   [(set_attr "conds" "set")
7371    (set_attr "length" "8")
7372    (set_attr "type" "multiple")]
7375 (define_insn_and_split "*arm_cmpdi_unsigned"
7376   [(set (reg:CC_CZ CC_REGNUM)
7377         (compare:CC_CZ (match_operand:DI 0 "s_register_operand" "l,r,r,r")
7378                        (match_operand:DI 1 "arm_di_operand"     "Py,r,Di,rDi")))]
7380   "TARGET_32BIT"
7381   "#"   ; "cmp\\t%R0, %R1\;it eq\;cmpeq\\t%Q0, %Q1"
7382   "&& reload_completed"
7383   [(set (reg:CC CC_REGNUM)
7384         (compare:CC (match_dup 2) (match_dup 3)))
7385    (cond_exec (eq:SI (reg:CC CC_REGNUM) (const_int 0))
7386               (set (reg:CC CC_REGNUM)
7387                    (compare:CC (match_dup 0) (match_dup 1))))]
7388   {
7389     operands[2] = gen_highpart (SImode, operands[0]);
7390     operands[0] = gen_lowpart (SImode, operands[0]);
7391     if (CONST_INT_P (operands[1]))
7392       operands[3] = gen_highpart_mode (SImode, DImode, operands[1]);
7393     else
7394       operands[3] = gen_highpart (SImode, operands[1]);
7395     operands[1] = gen_lowpart (SImode, operands[1]);
7396   }
7397   [(set_attr "conds" "set")
7398    (set_attr "enabled_for_depr_it" "yes,yes,no,*")
7399    (set_attr "arch" "t2,t2,t2,a")
7400    (set_attr "length" "6,6,10,8")
7401    (set_attr "type" "multiple")]
7404 (define_insn "*arm_cmpdi_zero"
7405   [(set (reg:CC_Z CC_REGNUM)
7406         (compare:CC_Z (match_operand:DI 0 "s_register_operand" "r")
7407                       (const_int 0)))
7408    (clobber (match_scratch:SI 1 "=r"))]
7409   "TARGET_32BIT"
7410   "orrs%?\\t%1, %Q0, %R0"
7411   [(set_attr "conds" "set")
7412    (set_attr "type" "logics_reg")]
7415 ; This insn allows redundant compares to be removed by cse, nothing should
7416 ; ever appear in the output file since (set (reg x) (reg x)) is a no-op that
7417 ; is deleted later on. The match_dup will match the mode here, so that
7418 ; mode changes of the condition codes aren't lost by this even though we don't
7419 ; specify what they are.
7421 (define_insn "*deleted_compare"
7422   [(set (match_operand 0 "cc_register" "") (match_dup 0))]
7423   "TARGET_32BIT"
7424   "\\t%@ deleted compare"
7425   [(set_attr "conds" "set")
7426    (set_attr "length" "0")
7427    (set_attr "type" "no_insn")]
7431 ;; Conditional branch insns
7433 (define_expand "cbranch_cc"
7434   [(set (pc)
7435         (if_then_else (match_operator 0 "" [(match_operand 1 "" "")
7436                                             (match_operand 2 "" "")])
7437                       (label_ref (match_operand 3 "" ""))
7438                       (pc)))]
7439   "TARGET_32BIT"
7440   "operands[1] = arm_gen_compare_reg (GET_CODE (operands[0]),
7441                                       operands[1], operands[2], NULL_RTX);
7442    operands[2] = const0_rtx;"
7446 ;; Patterns to match conditional branch insns.
7449 (define_insn "arm_cond_branch"
7450   [(set (pc)
7451         (if_then_else (match_operator 1 "arm_comparison_operator"
7452                        [(match_operand 2 "cc_register" "") (const_int 0)])
7453                       (label_ref (match_operand 0 "" ""))
7454                       (pc)))]
7455   "TARGET_32BIT"
7456   "*
7457   if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
7458     {
7459       arm_ccfsm_state += 2;
7460       return \"\";
7461     }
7462   return \"b%d1\\t%l0\";
7463   "
7464   [(set_attr "conds" "use")
7465    (set_attr "type" "branch")
7466    (set (attr "length")
7467         (if_then_else
7468            (and (match_test "TARGET_THUMB2")
7469                 (and (ge (minus (match_dup 0) (pc)) (const_int -250))
7470                      (le (minus (match_dup 0) (pc)) (const_int 256))))
7471            (const_int 2)
7472            (const_int 4)))]
7475 (define_insn "*arm_cond_branch_reversed"
7476   [(set (pc)
7477         (if_then_else (match_operator 1 "arm_comparison_operator"
7478                        [(match_operand 2 "cc_register" "") (const_int 0)])
7479                       (pc)
7480                       (label_ref (match_operand 0 "" ""))))]
7481   "TARGET_32BIT"
7482   "*
7483   if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
7484     {
7485       arm_ccfsm_state += 2;
7486       return \"\";
7487     }
7488   return \"b%D1\\t%l0\";
7489   "
7490   [(set_attr "conds" "use")
7491    (set_attr "type" "branch")
7492    (set (attr "length")
7493         (if_then_else
7494            (and (match_test "TARGET_THUMB2")
7495                 (and (ge (minus (match_dup 0) (pc)) (const_int -250))
7496                      (le (minus (match_dup 0) (pc)) (const_int 256))))
7497            (const_int 2)
7498            (const_int 4)))]
7503 ; scc insns
7505 (define_expand "cstore_cc"
7506   [(set (match_operand:SI 0 "s_register_operand" "")
7507         (match_operator:SI 1 "" [(match_operand 2 "" "")
7508                                  (match_operand 3 "" "")]))]
7509   "TARGET_32BIT"
7510   "operands[2] = arm_gen_compare_reg (GET_CODE (operands[1]),
7511                                       operands[2], operands[3], NULL_RTX);
7512    operands[3] = const0_rtx;"
7515 (define_insn_and_split "*mov_scc"
7516   [(set (match_operand:SI 0 "s_register_operand" "=r")
7517         (match_operator:SI 1 "arm_comparison_operator_mode"
7518          [(match_operand 2 "cc_register" "") (const_int 0)]))]
7519   "TARGET_ARM"
7520   "#"   ; "mov%D1\\t%0, #0\;mov%d1\\t%0, #1"
7521   "TARGET_ARM"
7522   [(set (match_dup 0)
7523         (if_then_else:SI (match_dup 1)
7524                          (const_int 1)
7525                          (const_int 0)))]
7526   ""
7527   [(set_attr "conds" "use")
7528    (set_attr "length" "8")
7529    (set_attr "type" "multiple")]
7532 (define_insn_and_split "*mov_negscc"
7533   [(set (match_operand:SI 0 "s_register_operand" "=r")
7534         (neg:SI (match_operator:SI 1 "arm_comparison_operator_mode"
7535                  [(match_operand 2 "cc_register" "") (const_int 0)])))]
7536   "TARGET_ARM"
7537   "#"   ; "mov%D1\\t%0, #0\;mvn%d1\\t%0, #0"
7538   "TARGET_ARM"
7539   [(set (match_dup 0)
7540         (if_then_else:SI (match_dup 1)
7541                          (match_dup 3)
7542                          (const_int 0)))]
7543   {
7544     operands[3] = GEN_INT (~0);
7545   }
7546   [(set_attr "conds" "use")
7547    (set_attr "length" "8")
7548    (set_attr "type" "multiple")]
7551 (define_insn_and_split "*mov_notscc"
7552   [(set (match_operand:SI 0 "s_register_operand" "=r")
7553         (not:SI (match_operator:SI 1 "arm_comparison_operator"
7554                  [(match_operand 2 "cc_register" "") (const_int 0)])))]
7555   "TARGET_ARM"
7556   "#"   ; "mvn%D1\\t%0, #0\;mvn%d1\\t%0, #1"
7557   "TARGET_ARM"
7558   [(set (match_dup 0)
7559         (if_then_else:SI (match_dup 1)
7560                          (match_dup 3)
7561                          (match_dup 4)))]
7562   {
7563     operands[3] = GEN_INT (~1);
7564     operands[4] = GEN_INT (~0);
7565   }
7566   [(set_attr "conds" "use")
7567    (set_attr "length" "8")
7568    (set_attr "type" "multiple")]
7571 (define_expand "cstoresi4"
7572   [(set (match_operand:SI 0 "s_register_operand" "")
7573         (match_operator:SI 1 "expandable_comparison_operator"
7574          [(match_operand:SI 2 "s_register_operand" "")
7575           (match_operand:SI 3 "reg_or_int_operand" "")]))]
7576   "TARGET_32BIT || TARGET_THUMB1"
7577   "{
7578   rtx op3, scratch, scratch2;
7580   if (!TARGET_THUMB1)
7581     {
7582       if (!arm_add_operand (operands[3], SImode))
7583         operands[3] = force_reg (SImode, operands[3]);
7584       emit_insn (gen_cstore_cc (operands[0], operands[1],
7585                                 operands[2], operands[3]));
7586       DONE;
7587     }
7589   if (operands[3] == const0_rtx)
7590     {
7591       switch (GET_CODE (operands[1]))
7592         {
7593         case EQ:
7594           emit_insn (gen_cstoresi_eq0_thumb1 (operands[0], operands[2]));
7595           break;
7597         case NE:
7598           emit_insn (gen_cstoresi_ne0_thumb1 (operands[0], operands[2]));
7599           break;
7601         case LE:
7602           scratch = expand_binop (SImode, add_optab, operands[2], constm1_rtx,
7603                                   NULL_RTX, 0, OPTAB_WIDEN);
7604           scratch = expand_binop (SImode, ior_optab, operands[2], scratch,
7605                                   NULL_RTX, 0, OPTAB_WIDEN);
7606           expand_binop (SImode, lshr_optab, scratch, GEN_INT (31),
7607                         operands[0], 1, OPTAB_WIDEN);
7608           break;
7610         case GE:
7611           scratch = expand_unop (SImode, one_cmpl_optab, operands[2],
7612                                  NULL_RTX, 1);
7613           expand_binop (SImode, lshr_optab, scratch, GEN_INT (31),
7614                         NULL_RTX, 1, OPTAB_WIDEN);
7615           break;
7617         case GT:
7618           scratch = expand_binop (SImode, ashr_optab, operands[2],
7619                                   GEN_INT (31), NULL_RTX, 0, OPTAB_WIDEN);
7620           scratch = expand_binop (SImode, sub_optab, scratch, operands[2],
7621                                   NULL_RTX, 0, OPTAB_WIDEN);
7622           expand_binop (SImode, lshr_optab, scratch, GEN_INT (31), operands[0],
7623                         0, OPTAB_WIDEN);
7624           break;
7626         /* LT is handled by generic code.  No need for unsigned with 0.  */
7627         default:
7628           FAIL;
7629         }
7630       DONE;
7631     }
7633   switch (GET_CODE (operands[1]))
7634     {
7635     case EQ:
7636       scratch = expand_binop (SImode, sub_optab, operands[2], operands[3],
7637                               NULL_RTX, 0, OPTAB_WIDEN);
7638       emit_insn (gen_cstoresi_eq0_thumb1 (operands[0], scratch));
7639       break;
7641     case NE:
7642       scratch = expand_binop (SImode, sub_optab, operands[2], operands[3],
7643                               NULL_RTX, 0, OPTAB_WIDEN);
7644       emit_insn (gen_cstoresi_ne0_thumb1 (operands[0], scratch));
7645       break;
7647     case LE:
7648       op3 = force_reg (SImode, operands[3]);
7650       scratch = expand_binop (SImode, lshr_optab, operands[2], GEN_INT (31),
7651                               NULL_RTX, 1, OPTAB_WIDEN);
7652       scratch2 = expand_binop (SImode, ashr_optab, op3, GEN_INT (31),
7653                               NULL_RTX, 0, OPTAB_WIDEN);
7654       emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch2,
7655                                           op3, operands[2]));
7656       break;
7658     case GE:
7659       op3 = operands[3];
7660       if (!thumb1_cmp_operand (op3, SImode))
7661         op3 = force_reg (SImode, op3);
7662       scratch = expand_binop (SImode, ashr_optab, operands[2], GEN_INT (31),
7663                               NULL_RTX, 0, OPTAB_WIDEN);
7664       scratch2 = expand_binop (SImode, lshr_optab, op3, GEN_INT (31),
7665                                NULL_RTX, 1, OPTAB_WIDEN);
7666       emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch2,
7667                                           operands[2], op3));
7668       break;
7670     case LEU:
7671       op3 = force_reg (SImode, operands[3]);
7672       scratch = force_reg (SImode, const0_rtx);
7673       emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch,
7674                                           op3, operands[2]));
7675       break;
7677     case GEU:
7678       op3 = operands[3];
7679       if (!thumb1_cmp_operand (op3, SImode))
7680         op3 = force_reg (SImode, op3);
7681       scratch = force_reg (SImode, const0_rtx);
7682       emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch,
7683                                           operands[2], op3));
7684       break;
7686     case LTU:
7687       op3 = operands[3];
7688       if (!thumb1_cmp_operand (op3, SImode))
7689         op3 = force_reg (SImode, op3);
7690       scratch = gen_reg_rtx (SImode);
7691       emit_insn (gen_cstoresi_ltu_thumb1 (operands[0], operands[2], op3));
7692       break;
7694     case GTU:
7695       op3 = force_reg (SImode, operands[3]);
7696       scratch = gen_reg_rtx (SImode);
7697       emit_insn (gen_cstoresi_ltu_thumb1 (operands[0], op3, operands[2]));
7698       break;
7700     /* No good sequences for GT, LT.  */
7701     default:
7702       FAIL;
7703     }
7704   DONE;
7707 (define_expand "cstoresf4"
7708   [(set (match_operand:SI 0 "s_register_operand" "")
7709         (match_operator:SI 1 "expandable_comparison_operator"
7710          [(match_operand:SF 2 "s_register_operand" "")
7711           (match_operand:SF 3 "arm_float_compare_operand" "")]))]
7712   "TARGET_32BIT && TARGET_HARD_FLOAT"
7713   "emit_insn (gen_cstore_cc (operands[0], operands[1],
7714                              operands[2], operands[3])); DONE;"
7717 (define_expand "cstoredf4"
7718   [(set (match_operand:SI 0 "s_register_operand" "")
7719         (match_operator:SI 1 "expandable_comparison_operator"
7720          [(match_operand:DF 2 "s_register_operand" "")
7721           (match_operand:DF 3 "arm_float_compare_operand" "")]))]
7722   "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
7723   "emit_insn (gen_cstore_cc (operands[0], operands[1],
7724                              operands[2], operands[3])); DONE;"
7727 (define_expand "cstoredi4"
7728   [(set (match_operand:SI 0 "s_register_operand" "")
7729         (match_operator:SI 1 "expandable_comparison_operator"
7730          [(match_operand:DI 2 "s_register_operand" "")
7731           (match_operand:DI 3 "cmpdi_operand" "")]))]
7732   "TARGET_32BIT"
7733   "{
7734      if (!arm_validize_comparison (&operands[1],
7735                                    &operands[2],
7736                                    &operands[3]))
7737        FAIL;
7738      emit_insn (gen_cstore_cc (operands[0], operands[1], operands[2],
7739                                  operands[3]));
7740      DONE;
7741    }"
7745 ;; Conditional move insns
7747 (define_expand "movsicc"
7748   [(set (match_operand:SI 0 "s_register_operand" "")
7749         (if_then_else:SI (match_operand 1 "expandable_comparison_operator" "")
7750                          (match_operand:SI 2 "arm_not_operand" "")
7751                          (match_operand:SI 3 "arm_not_operand" "")))]
7752   "TARGET_32BIT"
7753   "
7754   {
7755     enum rtx_code code;
7756     rtx ccreg;
7758     if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0), 
7759                                   &XEXP (operands[1], 1)))
7760       FAIL;
7761     
7762     code = GET_CODE (operands[1]);
7763     ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
7764                                  XEXP (operands[1], 1), NULL_RTX);
7765     operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7766   }"
7769 (define_expand "movsfcc"
7770   [(set (match_operand:SF 0 "s_register_operand" "")
7771         (if_then_else:SF (match_operand 1 "arm_cond_move_operator" "")
7772                          (match_operand:SF 2 "s_register_operand" "")
7773                          (match_operand:SF 3 "s_register_operand" "")))]
7774   "TARGET_32BIT && TARGET_HARD_FLOAT"
7775   "
7776   {
7777     enum rtx_code code = GET_CODE (operands[1]);
7778     rtx ccreg;
7780     if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0), 
7781                                   &XEXP (operands[1], 1)))
7782        FAIL;
7784     code = GET_CODE (operands[1]);
7785     ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
7786                                  XEXP (operands[1], 1), NULL_RTX);
7787     operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7788   }"
7791 (define_expand "movdfcc"
7792   [(set (match_operand:DF 0 "s_register_operand" "")
7793         (if_then_else:DF (match_operand 1 "arm_cond_move_operator" "")
7794                          (match_operand:DF 2 "s_register_operand" "")
7795                          (match_operand:DF 3 "s_register_operand" "")))]
7796   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
7797   "
7798   {
7799     enum rtx_code code = GET_CODE (operands[1]);
7800     rtx ccreg;
7802     if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0), 
7803                                   &XEXP (operands[1], 1)))
7804        FAIL;
7805     code = GET_CODE (operands[1]);
7806     ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
7807                                  XEXP (operands[1], 1), NULL_RTX);
7808     operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7809   }"
7812 (define_insn "*cmov<mode>"
7813     [(set (match_operand:SDF 0 "s_register_operand" "=<F_constraint>")
7814         (if_then_else:SDF (match_operator 1 "arm_vsel_comparison_operator"
7815                           [(match_operand 2 "cc_register" "") (const_int 0)])
7816                           (match_operand:SDF 3 "s_register_operand"
7817                                               "<F_constraint>")
7818                           (match_operand:SDF 4 "s_register_operand"
7819                                               "<F_constraint>")))]
7820   "TARGET_HARD_FLOAT && TARGET_FPU_ARMV8 <vfp_double_cond>"
7821   "*
7822   {
7823     enum arm_cond_code code = maybe_get_arm_condition_code (operands[1]);
7824     switch (code)
7825       {
7826       case ARM_GE:
7827       case ARM_GT:
7828       case ARM_EQ:
7829       case ARM_VS:
7830         return \"vsel%d1.<V_if_elem>\\t%<V_reg>0, %<V_reg>3, %<V_reg>4\";
7831       case ARM_LT:
7832       case ARM_LE:
7833       case ARM_NE:
7834       case ARM_VC:
7835         return \"vsel%D1.<V_if_elem>\\t%<V_reg>0, %<V_reg>4, %<V_reg>3\";
7836       default:
7837         gcc_unreachable ();
7838       }
7839     return \"\";
7840   }"
7841   [(set_attr "conds" "use")
7842    (set_attr "type" "fcsel")]
7845 (define_insn_and_split "*movsicc_insn"
7846   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r,r,r,r,r")
7847         (if_then_else:SI
7848          (match_operator 3 "arm_comparison_operator"
7849           [(match_operand 4 "cc_register" "") (const_int 0)])
7850          (match_operand:SI 1 "arm_not_operand" "0,0,rI,K,rI,rI,K,K")
7851          (match_operand:SI 2 "arm_not_operand" "rI,K,0,0,rI,K,rI,K")))]
7852   "TARGET_ARM"
7853   "@
7854    mov%D3\\t%0, %2
7855    mvn%D3\\t%0, #%B2
7856    mov%d3\\t%0, %1
7857    mvn%d3\\t%0, #%B1
7858    #
7859    #
7860    #
7861    #"
7862    ; alt4: mov%d3\\t%0, %1\;mov%D3\\t%0, %2
7863    ; alt5: mov%d3\\t%0, %1\;mvn%D3\\t%0, #%B2
7864    ; alt6: mvn%d3\\t%0, #%B1\;mov%D3\\t%0, %2
7865    ; alt7: mvn%d3\\t%0, #%B1\;mvn%D3\\t%0, #%B2"
7866   "&& reload_completed"
7867   [(const_int 0)]
7868   {
7869     enum rtx_code rev_code;
7870     machine_mode mode;
7871     rtx rev_cond;
7873     emit_insn (gen_rtx_COND_EXEC (VOIDmode,
7874                                   operands[3],
7875                                   gen_rtx_SET (operands[0], operands[1])));
7877     rev_code = GET_CODE (operands[3]);
7878     mode = GET_MODE (operands[4]);
7879     if (mode == CCFPmode || mode == CCFPEmode)
7880       rev_code = reverse_condition_maybe_unordered (rev_code);
7881     else
7882       rev_code = reverse_condition (rev_code);
7884     rev_cond = gen_rtx_fmt_ee (rev_code,
7885                                VOIDmode,
7886                                operands[4],
7887                                const0_rtx);
7888     emit_insn (gen_rtx_COND_EXEC (VOIDmode,
7889                                   rev_cond,
7890                                   gen_rtx_SET (operands[0], operands[2])));
7891     DONE;
7892   }
7893   [(set_attr "length" "4,4,4,4,8,8,8,8")
7894    (set_attr "conds" "use")
7895    (set_attr_alternative "type"
7896                          [(if_then_else (match_operand 2 "const_int_operand" "")
7897                                         (const_string "mov_imm")
7898                                         (const_string "mov_reg"))
7899                           (const_string "mvn_imm")
7900                           (if_then_else (match_operand 1 "const_int_operand" "")
7901                                         (const_string "mov_imm")
7902                                         (const_string "mov_reg"))
7903                           (const_string "mvn_imm")
7904                           (const_string "multiple")
7905                           (const_string "multiple")
7906                           (const_string "multiple")
7907                           (const_string "multiple")])]
7910 (define_insn "*movsfcc_soft_insn"
7911   [(set (match_operand:SF 0 "s_register_operand" "=r,r")
7912         (if_then_else:SF (match_operator 3 "arm_comparison_operator"
7913                           [(match_operand 4 "cc_register" "") (const_int 0)])
7914                          (match_operand:SF 1 "s_register_operand" "0,r")
7915                          (match_operand:SF 2 "s_register_operand" "r,0")))]
7916   "TARGET_ARM && TARGET_SOFT_FLOAT"
7917   "@
7918    mov%D3\\t%0, %2
7919    mov%d3\\t%0, %1"
7920   [(set_attr "conds" "use")
7921    (set_attr "type" "mov_reg")]
7925 ;; Jump and linkage insns
7927 (define_expand "jump"
7928   [(set (pc)
7929         (label_ref (match_operand 0 "" "")))]
7930   "TARGET_EITHER"
7931   ""
7934 (define_insn "*arm_jump"
7935   [(set (pc)
7936         (label_ref (match_operand 0 "" "")))]
7937   "TARGET_32BIT"
7938   "*
7939   {
7940     if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
7941       {
7942         arm_ccfsm_state += 2;
7943         return \"\";
7944       }
7945     return \"b%?\\t%l0\";
7946   }
7947   "
7948   [(set_attr "predicable" "yes")
7949    (set (attr "length")
7950         (if_then_else
7951            (and (match_test "TARGET_THUMB2")
7952                 (and (ge (minus (match_dup 0) (pc)) (const_int -2044))
7953                      (le (minus (match_dup 0) (pc)) (const_int 2048))))
7954            (const_int 2)
7955            (const_int 4)))
7956    (set_attr "type" "branch")]
7959 (define_expand "call"
7960   [(parallel [(call (match_operand 0 "memory_operand" "")
7961                     (match_operand 1 "general_operand" ""))
7962               (use (match_operand 2 "" ""))
7963               (clobber (reg:SI LR_REGNUM))])]
7964   "TARGET_EITHER"
7965   "
7966   {
7967     rtx callee, pat;
7968     
7969     /* In an untyped call, we can get NULL for operand 2.  */
7970     if (operands[2] == NULL_RTX)
7971       operands[2] = const0_rtx;
7972       
7973     /* Decide if we should generate indirect calls by loading the
7974        32-bit address of the callee into a register before performing the
7975        branch and link.  */
7976     callee = XEXP (operands[0], 0);
7977     if (GET_CODE (callee) == SYMBOL_REF
7978         ? arm_is_long_call_p (SYMBOL_REF_DECL (callee))
7979         : !REG_P (callee))
7980       XEXP (operands[0], 0) = force_reg (Pmode, callee);
7982     pat = gen_call_internal (operands[0], operands[1], operands[2]);
7983     arm_emit_call_insn (pat, XEXP (operands[0], 0), false);
7984     DONE;
7985   }"
7988 (define_expand "call_internal"
7989   [(parallel [(call (match_operand 0 "memory_operand" "")
7990                     (match_operand 1 "general_operand" ""))
7991               (use (match_operand 2 "" ""))
7992               (clobber (reg:SI LR_REGNUM))])])
7994 (define_insn "*call_reg_armv5"
7995   [(call (mem:SI (match_operand:SI 0 "s_register_operand" "r"))
7996          (match_operand 1 "" ""))
7997    (use (match_operand 2 "" ""))
7998    (clobber (reg:SI LR_REGNUM))]
7999   "TARGET_ARM && arm_arch5 && !SIBLING_CALL_P (insn)"
8000   "blx%?\\t%0"
8001   [(set_attr "type" "call")]
8004 (define_insn "*call_reg_arm"
8005   [(call (mem:SI (match_operand:SI 0 "s_register_operand" "r"))
8006          (match_operand 1 "" ""))
8007    (use (match_operand 2 "" ""))
8008    (clobber (reg:SI LR_REGNUM))]
8009   "TARGET_ARM && !arm_arch5 && !SIBLING_CALL_P (insn)"
8010   "*
8011   return output_call (operands);
8012   "
8013   ;; length is worst case, normally it is only two
8014   [(set_attr "length" "12")
8015    (set_attr "type" "call")]
8019 (define_expand "call_value"
8020   [(parallel [(set (match_operand       0 "" "")
8021                    (call (match_operand 1 "memory_operand" "")
8022                          (match_operand 2 "general_operand" "")))
8023               (use (match_operand 3 "" ""))
8024               (clobber (reg:SI LR_REGNUM))])]
8025   "TARGET_EITHER"
8026   "
8027   {
8028     rtx pat, callee;
8029     
8030     /* In an untyped call, we can get NULL for operand 2.  */
8031     if (operands[3] == 0)
8032       operands[3] = const0_rtx;
8033       
8034     /* Decide if we should generate indirect calls by loading the
8035        32-bit address of the callee into a register before performing the
8036        branch and link.  */
8037     callee = XEXP (operands[1], 0);
8038     if (GET_CODE (callee) == SYMBOL_REF
8039         ? arm_is_long_call_p (SYMBOL_REF_DECL (callee))
8040         : !REG_P (callee))
8041       XEXP (operands[1], 0) = force_reg (Pmode, callee);
8043     pat = gen_call_value_internal (operands[0], operands[1],
8044                                    operands[2], operands[3]);
8045     arm_emit_call_insn (pat, XEXP (operands[1], 0), false);
8046     DONE;
8047   }"
8050 (define_expand "call_value_internal"
8051   [(parallel [(set (match_operand       0 "" "")
8052                    (call (match_operand 1 "memory_operand" "")
8053                          (match_operand 2 "general_operand" "")))
8054               (use (match_operand 3 "" ""))
8055               (clobber (reg:SI LR_REGNUM))])])
8057 (define_insn "*call_value_reg_armv5"
8058   [(set (match_operand 0 "" "")
8059         (call (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
8060               (match_operand 2 "" "")))
8061    (use (match_operand 3 "" ""))
8062    (clobber (reg:SI LR_REGNUM))]
8063   "TARGET_ARM && arm_arch5 && !SIBLING_CALL_P (insn)"
8064   "blx%?\\t%1"
8065   [(set_attr "type" "call")]
8068 (define_insn "*call_value_reg_arm"
8069   [(set (match_operand 0 "" "")
8070         (call (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
8071               (match_operand 2 "" "")))
8072    (use (match_operand 3 "" ""))
8073    (clobber (reg:SI LR_REGNUM))]
8074   "TARGET_ARM && !arm_arch5 && !SIBLING_CALL_P (insn)"
8075   "*
8076   return output_call (&operands[1]);
8077   "
8078   [(set_attr "length" "12")
8079    (set_attr "type" "call")]
8082 ;; Allow calls to SYMBOL_REFs specially as they are not valid general addresses
8083 ;; The 'a' causes the operand to be treated as an address, i.e. no '#' output.
8085 (define_insn "*call_symbol"
8086   [(call (mem:SI (match_operand:SI 0 "" ""))
8087          (match_operand 1 "" ""))
8088    (use (match_operand 2 "" ""))
8089    (clobber (reg:SI LR_REGNUM))]
8090   "TARGET_32BIT
8091    && !SIBLING_CALL_P (insn)
8092    && (GET_CODE (operands[0]) == SYMBOL_REF)
8093    && !arm_is_long_call_p (SYMBOL_REF_DECL (operands[0]))"
8094   "*
8095   {
8096    rtx op = operands[0];
8098    /* Switch mode now when possible.  */
8099    if (SYMBOL_REF_DECL (op) && !TREE_PUBLIC (SYMBOL_REF_DECL (op))
8100         && arm_arch5 && arm_change_mode_p (SYMBOL_REF_DECL (op)))
8101       return NEED_PLT_RELOC ? \"blx%?\\t%a0(PLT)\" : \"blx%?\\t(%a0)\";
8103     return NEED_PLT_RELOC ? \"bl%?\\t%a0(PLT)\" : \"bl%?\\t%a0\";
8104   }"
8105   [(set_attr "type" "call")]
8108 (define_insn "*call_value_symbol"
8109   [(set (match_operand 0 "" "")
8110         (call (mem:SI (match_operand:SI 1 "" ""))
8111         (match_operand:SI 2 "" "")))
8112    (use (match_operand 3 "" ""))
8113    (clobber (reg:SI LR_REGNUM))]
8114   "TARGET_32BIT
8115    && !SIBLING_CALL_P (insn)
8116    && (GET_CODE (operands[1]) == SYMBOL_REF)
8117    && !arm_is_long_call_p (SYMBOL_REF_DECL (operands[1]))"
8118   "*
8119   {
8120    rtx op = operands[1];
8122    /* Switch mode now when possible.  */
8123    if (SYMBOL_REF_DECL (op) && !TREE_PUBLIC (SYMBOL_REF_DECL (op))
8124         && arm_arch5 && arm_change_mode_p (SYMBOL_REF_DECL (op)))
8125       return NEED_PLT_RELOC ? \"blx%?\\t%a1(PLT)\" : \"blx%?\\t(%a1)\";
8127     return NEED_PLT_RELOC ? \"bl%?\\t%a1(PLT)\" : \"bl%?\\t%a1\";
8128   }"
8129   [(set_attr "type" "call")]
8132 (define_expand "sibcall_internal"
8133   [(parallel [(call (match_operand 0 "memory_operand" "")
8134                     (match_operand 1 "general_operand" ""))
8135               (return)
8136               (use (match_operand 2 "" ""))])])
8138 ;; We may also be able to do sibcalls for Thumb, but it's much harder...
8139 (define_expand "sibcall"
8140   [(parallel [(call (match_operand 0 "memory_operand" "")
8141                     (match_operand 1 "general_operand" ""))
8142               (return)
8143               (use (match_operand 2 "" ""))])]
8144   "TARGET_32BIT"
8145   "
8146   {
8147     rtx pat;
8149     if ((!REG_P (XEXP (operands[0], 0))
8150          && GET_CODE (XEXP (operands[0], 0)) != SYMBOL_REF)
8151         || (GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
8152             && arm_is_long_call_p (SYMBOL_REF_DECL (XEXP (operands[0], 0)))))
8153      XEXP (operands[0], 0) = force_reg (SImode, XEXP (operands[0], 0));
8155     if (operands[2] == NULL_RTX)
8156       operands[2] = const0_rtx;
8158     pat = gen_sibcall_internal (operands[0], operands[1], operands[2]);
8159     arm_emit_call_insn (pat, operands[0], true);
8160     DONE;
8161   }"
8164 (define_expand "sibcall_value_internal"
8165   [(parallel [(set (match_operand 0 "" "")
8166                    (call (match_operand 1 "memory_operand" "")
8167                          (match_operand 2 "general_operand" "")))
8168               (return)
8169               (use (match_operand 3 "" ""))])])
8171 (define_expand "sibcall_value"
8172   [(parallel [(set (match_operand 0 "" "")
8173                    (call (match_operand 1 "memory_operand" "")
8174                          (match_operand 2 "general_operand" "")))
8175               (return)
8176               (use (match_operand 3 "" ""))])]
8177   "TARGET_32BIT"
8178   "
8179   {
8180     rtx pat;
8182     if ((!REG_P (XEXP (operands[1], 0))
8183          && GET_CODE (XEXP (operands[1], 0)) != SYMBOL_REF)
8184         || (GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
8185             && arm_is_long_call_p (SYMBOL_REF_DECL (XEXP (operands[1], 0)))))
8186      XEXP (operands[1], 0) = force_reg (SImode, XEXP (operands[1], 0));
8188     if (operands[3] == NULL_RTX)
8189       operands[3] = const0_rtx;
8191     pat = gen_sibcall_value_internal (operands[0], operands[1],
8192                                       operands[2], operands[3]);
8193     arm_emit_call_insn (pat, operands[1], true);
8194     DONE;
8195   }"
8198 (define_insn "*sibcall_insn"
8199  [(call (mem:SI (match_operand:SI 0 "call_insn_operand" "Cs, US"))
8200         (match_operand 1 "" ""))
8201   (return)
8202   (use (match_operand 2 "" ""))]
8203   "TARGET_32BIT && SIBLING_CALL_P (insn)"
8204   "*
8205   if (which_alternative == 1)
8206     return NEED_PLT_RELOC ? \"b%?\\t%a0(PLT)\" : \"b%?\\t%a0\";
8207   else
8208     {
8209       if (arm_arch5 || arm_arch4t)
8210         return \"bx%?\\t%0\\t%@ indirect register sibling call\";
8211       else
8212         return \"mov%?\\t%|pc, %0\\t%@ indirect register sibling call\";
8213     }
8214   "
8215   [(set_attr "type" "call")]
8218 (define_insn "*sibcall_value_insn"
8219  [(set (match_operand 0 "" "")
8220        (call (mem:SI (match_operand:SI 1 "call_insn_operand" "Cs,US"))
8221              (match_operand 2 "" "")))
8222   (return)
8223   (use (match_operand 3 "" ""))]
8224   "TARGET_32BIT && SIBLING_CALL_P (insn)"
8225   "*
8226   if (which_alternative == 1)
8227    return NEED_PLT_RELOC ? \"b%?\\t%a1(PLT)\" : \"b%?\\t%a1\";
8228   else
8229     {
8230       if (arm_arch5 || arm_arch4t)
8231         return \"bx%?\\t%1\";
8232       else
8233         return \"mov%?\\t%|pc, %1\\t@ indirect sibling call \";
8234     }
8235   "
8236   [(set_attr "type" "call")]
8239 (define_expand "<return_str>return"
8240   [(RETURNS)]
8241   "(TARGET_ARM || (TARGET_THUMB2
8242                    && ARM_FUNC_TYPE (arm_current_func_type ()) == ARM_FT_NORMAL
8243                    && !IS_STACKALIGN (arm_current_func_type ())))
8244     <return_cond_false>"
8245   "
8246   {
8247     if (TARGET_THUMB2)
8248       {
8249         thumb2_expand_return (<return_simple_p>);
8250         DONE;
8251       }
8252   }
8253   "
8256 ;; Often the return insn will be the same as loading from memory, so set attr
8257 (define_insn "*arm_return"
8258   [(return)]
8259   "TARGET_ARM && USE_RETURN_INSN (FALSE)"
8260   "*
8261   {
8262     if (arm_ccfsm_state == 2)
8263       {
8264         arm_ccfsm_state += 2;
8265         return \"\";
8266       }
8267     return output_return_instruction (const_true_rtx, true, false, false);
8268   }"
8269   [(set_attr "type" "load1")
8270    (set_attr "length" "12")
8271    (set_attr "predicable" "yes")]
8274 (define_insn "*cond_<return_str>return"
8275   [(set (pc)
8276         (if_then_else (match_operator 0 "arm_comparison_operator"
8277                        [(match_operand 1 "cc_register" "") (const_int 0)])
8278                       (RETURNS)
8279                       (pc)))]
8280   "TARGET_ARM  <return_cond_true>"
8281   "*
8282   {
8283     if (arm_ccfsm_state == 2)
8284       {
8285         arm_ccfsm_state += 2;
8286         return \"\";
8287       }
8288     return output_return_instruction (operands[0], true, false,
8289                                       <return_simple_p>);
8290   }"
8291   [(set_attr "conds" "use")
8292    (set_attr "length" "12")
8293    (set_attr "type" "load1")]
8296 (define_insn "*cond_<return_str>return_inverted"
8297   [(set (pc)
8298         (if_then_else (match_operator 0 "arm_comparison_operator"
8299                        [(match_operand 1 "cc_register" "") (const_int 0)])
8300                       (pc)
8301                       (RETURNS)))]
8302   "TARGET_ARM <return_cond_true>"
8303   "*
8304   {
8305     if (arm_ccfsm_state == 2)
8306       {
8307         arm_ccfsm_state += 2;
8308         return \"\";
8309       }
8310     return output_return_instruction (operands[0], true, true,
8311                                       <return_simple_p>);
8312   }"
8313   [(set_attr "conds" "use")
8314    (set_attr "length" "12")
8315    (set_attr "type" "load1")]
8318 (define_insn "*arm_simple_return"
8319   [(simple_return)]
8320   "TARGET_ARM"
8321   "*
8322   {
8323     if (arm_ccfsm_state == 2)
8324       {
8325         arm_ccfsm_state += 2;
8326         return \"\";
8327       }
8328     return output_return_instruction (const_true_rtx, true, false, true);
8329   }"
8330   [(set_attr "type" "branch")
8331    (set_attr "length" "4")
8332    (set_attr "predicable" "yes")]
8335 ;; Generate a sequence of instructions to determine if the processor is
8336 ;; in 26-bit or 32-bit mode, and return the appropriate return address
8337 ;; mask.
8339 (define_expand "return_addr_mask"
8340   [(set (match_dup 1)
8341       (compare:CC_NOOV (unspec [(const_int 0)] UNSPEC_CHECK_ARCH)
8342                        (const_int 0)))
8343    (set (match_operand:SI 0 "s_register_operand" "")
8344       (if_then_else:SI (eq (match_dup 1) (const_int 0))
8345                        (const_int -1)
8346                        (const_int 67108860)))] ; 0x03fffffc
8347   "TARGET_ARM"
8348   "
8349   operands[1] = gen_rtx_REG (CC_NOOVmode, CC_REGNUM);
8350   ")
8352 (define_insn "*check_arch2"
8353   [(set (match_operand:CC_NOOV 0 "cc_register" "")
8354       (compare:CC_NOOV (unspec [(const_int 0)] UNSPEC_CHECK_ARCH)
8355                        (const_int 0)))]
8356   "TARGET_ARM"
8357   "teq\\t%|r0, %|r0\;teq\\t%|pc, %|pc"
8358   [(set_attr "length" "8")
8359    (set_attr "conds" "set")
8360    (set_attr "type" "multiple")]
8363 ;; Call subroutine returning any type.
8365 (define_expand "untyped_call"
8366   [(parallel [(call (match_operand 0 "" "")
8367                     (const_int 0))
8368               (match_operand 1 "" "")
8369               (match_operand 2 "" "")])]
8370   "TARGET_EITHER"
8371   "
8372   {
8373     int i;
8374     rtx par = gen_rtx_PARALLEL (VOIDmode,
8375                                 rtvec_alloc (XVECLEN (operands[2], 0)));
8376     rtx addr = gen_reg_rtx (Pmode);
8377     rtx mem;
8378     int size = 0;
8380     emit_move_insn (addr, XEXP (operands[1], 0));
8381     mem = change_address (operands[1], BLKmode, addr);
8383     for (i = 0; i < XVECLEN (operands[2], 0); i++)
8384       {
8385         rtx src = SET_SRC (XVECEXP (operands[2], 0, i));
8387         /* Default code only uses r0 as a return value, but we could
8388            be using anything up to 4 registers.  */
8389         if (REGNO (src) == R0_REGNUM)
8390           src = gen_rtx_REG (TImode, R0_REGNUM);
8392         XVECEXP (par, 0, i) = gen_rtx_EXPR_LIST (VOIDmode, src,
8393                                                  GEN_INT (size));
8394         size += GET_MODE_SIZE (GET_MODE (src));
8395       }
8397     emit_call_insn (gen_call_value (par, operands[0], const0_rtx, NULL));
8399     size = 0;
8401     for (i = 0; i < XVECLEN (par, 0); i++)
8402       {
8403         HOST_WIDE_INT offset = 0;
8404         rtx reg = XEXP (XVECEXP (par, 0, i), 0);
8406         if (size != 0)
8407           emit_move_insn (addr, plus_constant (Pmode, addr, size));
8409         mem = change_address (mem, GET_MODE (reg), NULL);
8410         if (REGNO (reg) == R0_REGNUM)
8411           {
8412             /* On thumb we have to use a write-back instruction.  */
8413             emit_insn (arm_gen_store_multiple (arm_regs_in_sequence, 4, addr,
8414                        TARGET_THUMB ? TRUE : FALSE, mem, &offset));
8415             size = TARGET_ARM ? 16 : 0;
8416           }
8417         else
8418           {
8419             emit_move_insn (mem, reg);
8420             size = GET_MODE_SIZE (GET_MODE (reg));
8421           }
8422       }
8424     /* The optimizer does not know that the call sets the function value
8425        registers we stored in the result block.  We avoid problems by
8426        claiming that all hard registers are used and clobbered at this
8427        point.  */
8428     emit_insn (gen_blockage ());
8430     DONE;
8431   }"
8434 (define_expand "untyped_return"
8435   [(match_operand:BLK 0 "memory_operand" "")
8436    (match_operand 1 "" "")]
8437   "TARGET_EITHER"
8438   "
8439   {
8440     int i;
8441     rtx addr = gen_reg_rtx (Pmode);
8442     rtx mem;
8443     int size = 0;
8445     emit_move_insn (addr, XEXP (operands[0], 0));
8446     mem = change_address (operands[0], BLKmode, addr);
8448     for (i = 0; i < XVECLEN (operands[1], 0); i++)
8449       {
8450         HOST_WIDE_INT offset = 0;
8451         rtx reg = SET_DEST (XVECEXP (operands[1], 0, i));
8453         if (size != 0)
8454           emit_move_insn (addr, plus_constant (Pmode, addr, size));
8456         mem = change_address (mem, GET_MODE (reg), NULL);
8457         if (REGNO (reg) == R0_REGNUM)
8458           {
8459             /* On thumb we have to use a write-back instruction.  */
8460             emit_insn (arm_gen_load_multiple (arm_regs_in_sequence, 4, addr,
8461                        TARGET_THUMB ? TRUE : FALSE, mem, &offset));
8462             size = TARGET_ARM ? 16 : 0;
8463           }
8464         else
8465           {
8466             emit_move_insn (reg, mem);
8467             size = GET_MODE_SIZE (GET_MODE (reg));
8468           }
8469       }
8471     /* Emit USE insns before the return.  */
8472     for (i = 0; i < XVECLEN (operands[1], 0); i++)
8473       emit_use (SET_DEST (XVECEXP (operands[1], 0, i)));
8475     /* Construct the return.  */
8476     expand_naked_return ();
8478     DONE;
8479   }"
8482 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
8483 ;; all of memory.  This blocks insns from being moved across this point.
8485 (define_insn "blockage"
8486   [(unspec_volatile [(const_int 0)] VUNSPEC_BLOCKAGE)]
8487   "TARGET_EITHER"
8488   ""
8489   [(set_attr "length" "0")
8490    (set_attr "type" "block")]
8493 (define_insn "probe_stack"
8494   [(set (match_operand:SI 0 "memory_operand" "=m")
8495         (unspec:SI [(const_int 0)] UNSPEC_PROBE_STACK))]
8496   "TARGET_32BIT"
8497   "str%?\\tr0, %0"
8498   [(set_attr "type" "store1")
8499    (set_attr "predicable" "yes")]
8502 (define_insn "probe_stack_range"
8503   [(set (match_operand:SI 0 "register_operand" "=r")
8504         (unspec_volatile:SI [(match_operand:SI 1 "register_operand" "0")
8505                              (match_operand:SI 2 "register_operand" "r")]
8506                              VUNSPEC_PROBE_STACK_RANGE))]
8507   "TARGET_32BIT"
8509   return output_probe_stack_range (operands[0], operands[2]);
8511   [(set_attr "type" "multiple")
8512    (set_attr "conds" "clob")]
8515 (define_expand "casesi"
8516   [(match_operand:SI 0 "s_register_operand" "") ; index to jump on
8517    (match_operand:SI 1 "const_int_operand" "")  ; lower bound
8518    (match_operand:SI 2 "const_int_operand" "")  ; total range
8519    (match_operand:SI 3 "" "")                   ; table label
8520    (match_operand:SI 4 "" "")]                  ; Out of range label
8521   "TARGET_32BIT || optimize_size || flag_pic"
8522   "
8523   {
8524     enum insn_code code;
8525     if (operands[1] != const0_rtx)
8526       {
8527         rtx reg = gen_reg_rtx (SImode);
8529         emit_insn (gen_addsi3 (reg, operands[0],
8530                                gen_int_mode (-INTVAL (operands[1]),
8531                                              SImode)));
8532         operands[0] = reg;
8533       }
8535     if (TARGET_ARM)
8536       code = CODE_FOR_arm_casesi_internal;
8537     else if (TARGET_THUMB1)
8538       code = CODE_FOR_thumb1_casesi_internal_pic;
8539     else if (flag_pic)
8540       code = CODE_FOR_thumb2_casesi_internal_pic;
8541     else
8542       code = CODE_FOR_thumb2_casesi_internal;
8544     if (!insn_data[(int) code].operand[1].predicate(operands[2], SImode))
8545       operands[2] = force_reg (SImode, operands[2]);
8547     emit_jump_insn (GEN_FCN ((int) code) (operands[0], operands[2],
8548                                           operands[3], operands[4]));
8549     DONE;
8550   }"
8553 ;; The USE in this pattern is needed to tell flow analysis that this is
8554 ;; a CASESI insn.  It has no other purpose.
8555 (define_insn "arm_casesi_internal"
8556   [(parallel [(set (pc)
8557                (if_then_else
8558                 (leu (match_operand:SI 0 "s_register_operand" "r")
8559                      (match_operand:SI 1 "arm_rhs_operand" "rI"))
8560                 (mem:SI (plus:SI (mult:SI (match_dup 0) (const_int 4))
8561                                  (label_ref (match_operand 2 "" ""))))
8562                 (label_ref (match_operand 3 "" ""))))
8563               (clobber (reg:CC CC_REGNUM))
8564               (use (label_ref (match_dup 2)))])]
8565   "TARGET_ARM"
8566   "*
8567     if (flag_pic)
8568       return \"cmp\\t%0, %1\;addls\\t%|pc, %|pc, %0, asl #2\;b\\t%l3\";
8569     return   \"cmp\\t%0, %1\;ldrls\\t%|pc, [%|pc, %0, asl #2]\;b\\t%l3\";
8570   "
8571   [(set_attr "conds" "clob")
8572    (set_attr "length" "12")
8573    (set_attr "type" "multiple")]
8576 (define_expand "indirect_jump"
8577   [(set (pc)
8578         (match_operand:SI 0 "s_register_operand" ""))]
8579   "TARGET_EITHER"
8580   "
8581   /* Thumb-2 doesn't have mov pc, reg.  Explicitly set the low bit of the
8582      address and use bx.  */
8583   if (TARGET_THUMB2)
8584     {
8585       rtx tmp;
8586       tmp = gen_reg_rtx (SImode);
8587       emit_insn (gen_iorsi3 (tmp, operands[0], GEN_INT(1)));
8588       operands[0] = tmp;
8589     }
8590   "
8593 ;; NB Never uses BX.
8594 (define_insn "*arm_indirect_jump"
8595   [(set (pc)
8596         (match_operand:SI 0 "s_register_operand" "r"))]
8597   "TARGET_ARM"
8598   "mov%?\\t%|pc, %0\\t%@ indirect register jump"
8599   [(set_attr "predicable" "yes")
8600    (set_attr "type" "branch")]
8603 (define_insn "*load_indirect_jump"
8604   [(set (pc)
8605         (match_operand:SI 0 "memory_operand" "m"))]
8606   "TARGET_ARM"
8607   "ldr%?\\t%|pc, %0\\t%@ indirect memory jump"
8608   [(set_attr "type" "load1")
8609    (set_attr "pool_range" "4096")
8610    (set_attr "neg_pool_range" "4084")
8611    (set_attr "predicable" "yes")]
8615 ;; Misc insns
8617 (define_insn "nop"
8618   [(const_int 0)]
8619   "TARGET_EITHER"
8620   "nop"
8621   [(set (attr "length")
8622         (if_then_else (eq_attr "is_thumb" "yes")
8623                       (const_int 2)
8624                       (const_int 4)))
8625    (set_attr "type" "mov_reg")]
8628 (define_insn "trap"
8629   [(trap_if (const_int 1) (const_int 0))]
8630   ""
8631   "*
8632   if (TARGET_ARM)
8633     return \".inst\\t0xe7f000f0\";
8634   else
8635     return \".inst\\t0xdeff\";
8636   "
8637   [(set (attr "length")
8638         (if_then_else (eq_attr "is_thumb" "yes")
8639                       (const_int 2)
8640                       (const_int 4)))
8641    (set_attr "type" "trap")
8642    (set_attr "conds" "unconditional")]
8646 ;; Patterns to allow combination of arithmetic, cond code and shifts
8648 (define_insn "*<arith_shift_insn>_multsi"
8649   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8650         (SHIFTABLE_OPS:SI
8651          (mult:SI (match_operand:SI 2 "s_register_operand" "r,r")
8652                   (match_operand:SI 3 "power_of_two_operand" ""))
8653          (match_operand:SI 1 "s_register_operand" "rk,<t2_binop0>")))]
8654   "TARGET_32BIT"
8655   "<arith_shift_insn>%?\\t%0, %1, %2, lsl %b3"
8656   [(set_attr "predicable" "yes")
8657    (set_attr "predicable_short_it" "no")
8658    (set_attr "shift" "2")
8659    (set_attr "arch" "a,t2")
8660    (set_attr "type" "alu_shift_imm")])
8662 (define_insn "*<arith_shift_insn>_shiftsi"
8663   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
8664         (SHIFTABLE_OPS:SI
8665          (match_operator:SI 2 "shift_nomul_operator"
8666           [(match_operand:SI 3 "s_register_operand" "r,r,r")
8667            (match_operand:SI 4 "shift_amount_operand" "M,M,r")])
8668          (match_operand:SI 1 "s_register_operand" "rk,<t2_binop0>,rk")))]
8669   "TARGET_32BIT && GET_CODE (operands[2]) != MULT"
8670   "<arith_shift_insn>%?\\t%0, %1, %3%S2"
8671   [(set_attr "predicable" "yes")
8672    (set_attr "predicable_short_it" "no")
8673    (set_attr "shift" "3")
8674    (set_attr "arch" "a,t2,a")
8675    (set_attr "type" "alu_shift_imm,alu_shift_imm,alu_shift_reg")])
8677 (define_split
8678   [(set (match_operand:SI 0 "s_register_operand" "")
8679         (match_operator:SI 1 "shiftable_operator"
8680          [(match_operator:SI 2 "shiftable_operator"
8681            [(match_operator:SI 3 "shift_operator"
8682              [(match_operand:SI 4 "s_register_operand" "")
8683               (match_operand:SI 5 "reg_or_int_operand" "")])
8684             (match_operand:SI 6 "s_register_operand" "")])
8685           (match_operand:SI 7 "arm_rhs_operand" "")]))
8686    (clobber (match_operand:SI 8 "s_register_operand" ""))]
8687   "TARGET_32BIT"
8688   [(set (match_dup 8)
8689         (match_op_dup 2 [(match_op_dup 3 [(match_dup 4) (match_dup 5)])
8690                          (match_dup 6)]))
8691    (set (match_dup 0)
8692         (match_op_dup 1 [(match_dup 8) (match_dup 7)]))]
8693   "")
8695 (define_insn "*arith_shiftsi_compare0"
8696   [(set (reg:CC_NOOV CC_REGNUM)
8697         (compare:CC_NOOV
8698          (match_operator:SI 1 "shiftable_operator"
8699           [(match_operator:SI 3 "shift_operator"
8700             [(match_operand:SI 4 "s_register_operand" "r,r")
8701              (match_operand:SI 5 "shift_amount_operand" "M,r")])
8702            (match_operand:SI 2 "s_register_operand" "r,r")])
8703          (const_int 0)))
8704    (set (match_operand:SI 0 "s_register_operand" "=r,r")
8705         (match_op_dup 1 [(match_op_dup 3 [(match_dup 4) (match_dup 5)])
8706                          (match_dup 2)]))]
8707   "TARGET_32BIT"
8708   "%i1s%?\\t%0, %2, %4%S3"
8709   [(set_attr "conds" "set")
8710    (set_attr "shift" "4")
8711    (set_attr "arch" "32,a")
8712    (set_attr "type" "alus_shift_imm,alus_shift_reg")])
8714 (define_insn "*arith_shiftsi_compare0_scratch"
8715   [(set (reg:CC_NOOV CC_REGNUM)
8716         (compare:CC_NOOV
8717          (match_operator:SI 1 "shiftable_operator"
8718           [(match_operator:SI 3 "shift_operator"
8719             [(match_operand:SI 4 "s_register_operand" "r,r")
8720              (match_operand:SI 5 "shift_amount_operand" "M,r")])
8721            (match_operand:SI 2 "s_register_operand" "r,r")])
8722          (const_int 0)))
8723    (clobber (match_scratch:SI 0 "=r,r"))]
8724   "TARGET_32BIT"
8725   "%i1s%?\\t%0, %2, %4%S3"
8726   [(set_attr "conds" "set")
8727    (set_attr "shift" "4")
8728    (set_attr "arch" "32,a")
8729    (set_attr "type" "alus_shift_imm,alus_shift_reg")])
8731 (define_insn "*sub_shiftsi"
8732   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8733         (minus:SI (match_operand:SI 1 "s_register_operand" "r,r")
8734                   (match_operator:SI 2 "shift_operator"
8735                    [(match_operand:SI 3 "s_register_operand" "r,r")
8736                     (match_operand:SI 4 "shift_amount_operand" "M,r")])))]
8737   "TARGET_32BIT"
8738   "sub%?\\t%0, %1, %3%S2"
8739   [(set_attr "predicable" "yes")
8740    (set_attr "shift" "3")
8741    (set_attr "arch" "32,a")
8742    (set_attr "type" "alus_shift_imm,alus_shift_reg")])
8744 (define_insn "*sub_shiftsi_compare0"
8745   [(set (reg:CC_NOOV CC_REGNUM)
8746         (compare:CC_NOOV
8747          (minus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
8748                    (match_operator:SI 2 "shift_operator"
8749                     [(match_operand:SI 3 "s_register_operand" "r,r,r")
8750                      (match_operand:SI 4 "shift_amount_operand" "M,r,M")]))
8751          (const_int 0)))
8752    (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
8753         (minus:SI (match_dup 1)
8754                   (match_op_dup 2 [(match_dup 3) (match_dup 4)])))]
8755   "TARGET_32BIT"
8756   "subs%?\\t%0, %1, %3%S2"
8757   [(set_attr "conds" "set")
8758    (set_attr "shift" "3")
8759    (set_attr "arch" "32,a,a")
8760    (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
8762 (define_insn "*sub_shiftsi_compare0_scratch"
8763   [(set (reg:CC_NOOV CC_REGNUM)
8764         (compare:CC_NOOV
8765          (minus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
8766                    (match_operator:SI 2 "shift_operator"
8767                     [(match_operand:SI 3 "s_register_operand" "r,r,r")
8768                      (match_operand:SI 4 "shift_amount_operand" "M,r,M")]))
8769          (const_int 0)))
8770    (clobber (match_scratch:SI 0 "=r,r,r"))]
8771   "TARGET_32BIT"
8772   "subs%?\\t%0, %1, %3%S2"
8773   [(set_attr "conds" "set")
8774    (set_attr "shift" "3")
8775    (set_attr "arch" "32,a,a")
8776    (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
8779 (define_insn_and_split "*and_scc"
8780   [(set (match_operand:SI 0 "s_register_operand" "=r")
8781         (and:SI (match_operator:SI 1 "arm_comparison_operator"
8782                  [(match_operand 2 "cc_register" "") (const_int 0)])
8783                 (match_operand:SI 3 "s_register_operand" "r")))]
8784   "TARGET_ARM"
8785   "#"   ; "mov%D1\\t%0, #0\;and%d1\\t%0, %3, #1"
8786   "&& reload_completed"
8787   [(cond_exec (match_dup 5) (set (match_dup 0) (const_int 0)))
8788    (cond_exec (match_dup 4) (set (match_dup 0)
8789                                  (and:SI (match_dup 3) (const_int 1))))]
8790   {
8791     machine_mode mode = GET_MODE (operands[2]);
8792     enum rtx_code rc = GET_CODE (operands[1]);
8794     /* Note that operands[4] is the same as operands[1],
8795        but with VOIDmode as the result. */
8796     operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
8797     if (mode == CCFPmode || mode == CCFPEmode)
8798       rc = reverse_condition_maybe_unordered (rc);
8799     else
8800       rc = reverse_condition (rc);
8801     operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
8802   }
8803   [(set_attr "conds" "use")
8804    (set_attr "type" "multiple")
8805    (set_attr "length" "8")]
8808 (define_insn_and_split "*ior_scc"
8809   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8810         (ior:SI (match_operator:SI 1 "arm_comparison_operator"
8811                  [(match_operand 2 "cc_register" "") (const_int 0)])
8812                 (match_operand:SI 3 "s_register_operand" "0,?r")))]
8813   "TARGET_ARM"
8814   "@
8815    orr%d1\\t%0, %3, #1
8816    #"
8817   "&& reload_completed
8818    && REGNO (operands [0]) != REGNO (operands[3])"
8819   ;; && which_alternative == 1
8820   ; mov%D1\\t%0, %3\;orr%d1\\t%0, %3, #1
8821   [(cond_exec (match_dup 5) (set (match_dup 0) (match_dup 3)))
8822    (cond_exec (match_dup 4) (set (match_dup 0)
8823                                  (ior:SI (match_dup 3) (const_int 1))))]
8824   {
8825     machine_mode mode = GET_MODE (operands[2]);
8826     enum rtx_code rc = GET_CODE (operands[1]);
8828     /* Note that operands[4] is the same as operands[1],
8829        but with VOIDmode as the result. */
8830     operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
8831     if (mode == CCFPmode || mode == CCFPEmode)
8832       rc = reverse_condition_maybe_unordered (rc);
8833     else
8834       rc = reverse_condition (rc);
8835     operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
8836   }
8837   [(set_attr "conds" "use")
8838    (set_attr "length" "4,8")
8839    (set_attr "type" "logic_imm,multiple")]
8842 ; A series of splitters for the compare_scc pattern below.  Note that
8843 ; order is important.
8844 (define_split
8845   [(set (match_operand:SI 0 "s_register_operand" "")
8846         (lt:SI (match_operand:SI 1 "s_register_operand" "")
8847                (const_int 0)))
8848    (clobber (reg:CC CC_REGNUM))]
8849   "TARGET_32BIT && reload_completed"
8850   [(set (match_dup 0) (lshiftrt:SI (match_dup 1) (const_int 31)))])
8852 (define_split
8853   [(set (match_operand:SI 0 "s_register_operand" "")
8854         (ge:SI (match_operand:SI 1 "s_register_operand" "")
8855                (const_int 0)))
8856    (clobber (reg:CC CC_REGNUM))]
8857   "TARGET_32BIT && reload_completed"
8858   [(set (match_dup 0) (not:SI (match_dup 1)))
8859    (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 31)))])
8861 (define_split
8862   [(set (match_operand:SI 0 "s_register_operand" "")
8863         (eq:SI (match_operand:SI 1 "s_register_operand" "")
8864                (const_int 0)))
8865    (clobber (reg:CC CC_REGNUM))]
8866   "arm_arch5 && TARGET_32BIT"
8867   [(set (match_dup 0) (clz:SI (match_dup 1)))
8868    (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
8871 (define_split
8872   [(set (match_operand:SI 0 "s_register_operand" "")
8873         (eq:SI (match_operand:SI 1 "s_register_operand" "")
8874                (const_int 0)))
8875    (clobber (reg:CC CC_REGNUM))]
8876   "TARGET_32BIT && reload_completed"
8877   [(parallel
8878     [(set (reg:CC CC_REGNUM)
8879           (compare:CC (const_int 1) (match_dup 1)))
8880      (set (match_dup 0)
8881           (minus:SI (const_int 1) (match_dup 1)))])
8882    (cond_exec (ltu:CC (reg:CC CC_REGNUM) (const_int 0))
8883               (set (match_dup 0) (const_int 0)))])
8885 (define_split
8886   [(set (match_operand:SI 0 "s_register_operand" "")
8887         (ne:SI (match_operand:SI 1 "s_register_operand" "")
8888                (match_operand:SI 2 "const_int_operand" "")))
8889    (clobber (reg:CC CC_REGNUM))]
8890   "TARGET_32BIT && reload_completed"
8891   [(parallel
8892     [(set (reg:CC CC_REGNUM)
8893           (compare:CC (match_dup 1) (match_dup 2)))
8894      (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 3)))])
8895    (cond_exec (ne:CC (reg:CC CC_REGNUM) (const_int 0))
8896               (set (match_dup 0) (const_int 1)))]
8898   operands[3] = GEN_INT (-INTVAL (operands[2]));
8901 (define_split
8902   [(set (match_operand:SI 0 "s_register_operand" "")
8903         (ne:SI (match_operand:SI 1 "s_register_operand" "")
8904                (match_operand:SI 2 "arm_add_operand" "")))
8905    (clobber (reg:CC CC_REGNUM))]
8906   "TARGET_32BIT && reload_completed"
8907   [(parallel
8908     [(set (reg:CC_NOOV CC_REGNUM)
8909           (compare:CC_NOOV (minus:SI (match_dup 1) (match_dup 2))
8910                            (const_int 0)))
8911      (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
8912    (cond_exec (ne:CC_NOOV (reg:CC_NOOV CC_REGNUM) (const_int 0))
8913               (set (match_dup 0) (const_int 1)))])
8915 (define_insn_and_split "*compare_scc"
8916   [(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts")
8917         (match_operator:SI 1 "arm_comparison_operator"
8918          [(match_operand:SI 2 "s_register_operand" "r,r")
8919           (match_operand:SI 3 "arm_add_operand" "rI,L")]))
8920    (clobber (reg:CC CC_REGNUM))]
8921   "TARGET_32BIT"
8922   "#"
8923   "&& reload_completed"
8924   [(set (reg:CC CC_REGNUM) (compare:CC (match_dup 2) (match_dup 3)))
8925    (cond_exec (match_dup 4) (set (match_dup 0) (const_int 0)))
8926    (cond_exec (match_dup 5) (set (match_dup 0) (const_int 1)))]
8928   rtx tmp1;
8929   machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
8930                                            operands[2], operands[3]);
8931   enum rtx_code rc = GET_CODE (operands[1]);
8933   tmp1 = gen_rtx_REG (mode, CC_REGNUM);
8935   operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, tmp1, const0_rtx);
8936   if (mode == CCFPmode || mode == CCFPEmode)
8937     rc = reverse_condition_maybe_unordered (rc);
8938   else
8939     rc = reverse_condition (rc);
8940   operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, tmp1, const0_rtx);
8942   [(set_attr "type" "multiple")]
8945 ;; Attempt to improve the sequence generated by the compare_scc splitters
8946 ;; not to use conditional execution.
8948 ;; Rd = (eq (reg1) (const_int0))  // ARMv5
8949 ;;      clz Rd, reg1
8950 ;;      lsr Rd, Rd, #5
8951 (define_peephole2
8952   [(set (reg:CC CC_REGNUM)
8953         (compare:CC (match_operand:SI 1 "register_operand" "")
8954                     (const_int 0)))
8955    (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
8956               (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
8957    (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
8958               (set (match_dup 0) (const_int 1)))]
8959   "arm_arch5 && TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
8960   [(set (match_dup 0) (clz:SI (match_dup 1)))
8961    (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
8964 ;; Rd = (eq (reg1) (const_int0))  // !ARMv5
8965 ;;      negs Rd, reg1
8966 ;;      adc  Rd, Rd, reg1
8967 (define_peephole2
8968   [(set (reg:CC CC_REGNUM)
8969         (compare:CC (match_operand:SI 1 "register_operand" "")
8970                     (const_int 0)))
8971    (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
8972               (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
8973    (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
8974               (set (match_dup 0) (const_int 1)))
8975    (match_scratch:SI 2 "r")]
8976   "TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
8977   [(parallel
8978     [(set (reg:CC CC_REGNUM)
8979           (compare:CC (const_int 0) (match_dup 1)))
8980      (set (match_dup 2) (minus:SI (const_int 0) (match_dup 1)))])
8981    (set (match_dup 0)
8982         (plus:SI (plus:SI (match_dup 1) (match_dup 2))
8983                  (geu:SI (reg:CC CC_REGNUM) (const_int 0))))]
8986 ;; Rd = (eq (reg1) (reg2/imm))  // ARMv5 and optimising for speed.
8987 ;;      sub  Rd, Reg1, reg2
8988 ;;      clz  Rd, Rd
8989 ;;      lsr  Rd, Rd, #5
8990 (define_peephole2
8991   [(set (reg:CC CC_REGNUM)
8992         (compare:CC (match_operand:SI 1 "register_operand" "")
8993                     (match_operand:SI 2 "arm_rhs_operand" "")))
8994    (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
8995               (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
8996    (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
8997               (set (match_dup 0) (const_int 1)))]
8998   "arm_arch5 && TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)
8999   && !(TARGET_THUMB2 && optimize_insn_for_size_p ())"
9000   [(set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))
9001    (set (match_dup 0) (clz:SI (match_dup 0)))
9002    (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
9006 ;; Rd = (eq (reg1) (reg2))      // ! ARMv5 or optimising for size.
9007 ;;      sub  T1, Reg1, reg2
9008 ;;      negs Rd, T1
9009 ;;      adc  Rd, Rd, T1
9010 (define_peephole2
9011   [(set (reg:CC CC_REGNUM)
9012         (compare:CC (match_operand:SI 1 "register_operand" "")
9013                     (match_operand:SI 2 "arm_rhs_operand" "")))
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    (match_scratch:SI 3 "r")]
9019   "TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
9020   [(set (match_dup 3) (match_dup 4))
9021    (parallel
9022     [(set (reg:CC CC_REGNUM)
9023           (compare:CC (const_int 0) (match_dup 3)))
9024      (set (match_dup 0) (minus:SI (const_int 0) (match_dup 3)))])
9025    (set (match_dup 0)
9026         (plus:SI (plus:SI (match_dup 0) (match_dup 3))
9027                  (geu:SI (reg:CC CC_REGNUM) (const_int 0))))]
9028   "
9029   if (CONST_INT_P (operands[2]))
9030     operands[4] = plus_constant (SImode, operands[1], -INTVAL (operands[2]));
9031   else
9032     operands[4] = gen_rtx_MINUS (SImode, operands[1], operands[2]);
9033   ")
9035 (define_insn "*cond_move"
9036   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9037         (if_then_else:SI (match_operator 3 "equality_operator"
9038                           [(match_operator 4 "arm_comparison_operator"
9039                             [(match_operand 5 "cc_register" "") (const_int 0)])
9040                            (const_int 0)])
9041                          (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
9042                          (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))]
9043   "TARGET_ARM"
9044   "*
9045     if (GET_CODE (operands[3]) == NE)
9046       {
9047         if (which_alternative != 1)
9048           output_asm_insn (\"mov%D4\\t%0, %2\", operands);
9049         if (which_alternative != 0)
9050           output_asm_insn (\"mov%d4\\t%0, %1\", operands);
9051         return \"\";
9052       }
9053     if (which_alternative != 0)
9054       output_asm_insn (\"mov%D4\\t%0, %1\", operands);
9055     if (which_alternative != 1)
9056       output_asm_insn (\"mov%d4\\t%0, %2\", operands);
9057     return \"\";
9058   "
9059   [(set_attr "conds" "use")
9060    (set_attr_alternative "type"
9061                          [(if_then_else (match_operand 2 "const_int_operand" "")
9062                                         (const_string "mov_imm")
9063                                         (const_string "mov_reg"))
9064                           (if_then_else (match_operand 1 "const_int_operand" "")
9065                                         (const_string "mov_imm")
9066                                         (const_string "mov_reg"))
9067                           (const_string "multiple")])
9068    (set_attr "length" "4,4,8")]
9071 (define_insn "*cond_arith"
9072   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9073         (match_operator:SI 5 "shiftable_operator" 
9074          [(match_operator:SI 4 "arm_comparison_operator"
9075            [(match_operand:SI 2 "s_register_operand" "r,r")
9076             (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
9077           (match_operand:SI 1 "s_register_operand" "0,?r")]))
9078    (clobber (reg:CC CC_REGNUM))]
9079   "TARGET_ARM"
9080   "*
9081     if (GET_CODE (operands[4]) == LT && operands[3] == const0_rtx)
9082       return \"%i5\\t%0, %1, %2, lsr #31\";
9084     output_asm_insn (\"cmp\\t%2, %3\", operands);
9085     if (GET_CODE (operands[5]) == AND)
9086       output_asm_insn (\"mov%D4\\t%0, #0\", operands);
9087     else if (GET_CODE (operands[5]) == MINUS)
9088       output_asm_insn (\"rsb%D4\\t%0, %1, #0\", operands);
9089     else if (which_alternative != 0)
9090       output_asm_insn (\"mov%D4\\t%0, %1\", operands);
9091     return \"%i5%d4\\t%0, %1, #1\";
9092   "
9093   [(set_attr "conds" "clob")
9094    (set_attr "length" "12")
9095    (set_attr "type" "multiple")]
9098 (define_insn "*cond_sub"
9099   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9100         (minus:SI (match_operand:SI 1 "s_register_operand" "0,?r")
9101                   (match_operator:SI 4 "arm_comparison_operator"
9102                    [(match_operand:SI 2 "s_register_operand" "r,r")
9103                     (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
9104    (clobber (reg:CC CC_REGNUM))]
9105   "TARGET_ARM"
9106   "*
9107     output_asm_insn (\"cmp\\t%2, %3\", operands);
9108     if (which_alternative != 0)
9109       output_asm_insn (\"mov%D4\\t%0, %1\", operands);
9110     return \"sub%d4\\t%0, %1, #1\";
9111   "
9112   [(set_attr "conds" "clob")
9113    (set_attr "length" "8,12")
9114    (set_attr "type" "multiple")]
9117 (define_insn "*cmp_ite0"
9118   [(set (match_operand 6 "dominant_cc_register" "")
9119         (compare
9120          (if_then_else:SI
9121           (match_operator 4 "arm_comparison_operator"
9122            [(match_operand:SI 0 "s_register_operand"
9123                 "l,l,l,r,r,r,r,r,r")
9124             (match_operand:SI 1 "arm_add_operand"
9125                 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
9126           (match_operator:SI 5 "arm_comparison_operator"
9127            [(match_operand:SI 2 "s_register_operand"
9128                 "l,r,r,l,l,r,r,r,r")
9129             (match_operand:SI 3 "arm_add_operand"
9130                 "lPy,rI,L,lPy,lPy,rI,rI,L,L")])
9131           (const_int 0))
9132          (const_int 0)))]
9133   "TARGET_32BIT"
9134   "*
9135   {
9136     static const char * const cmp1[NUM_OF_COND_CMP][2] =
9137     {
9138       {\"cmp%d5\\t%0, %1\",
9139        \"cmp%d4\\t%2, %3\"},
9140       {\"cmn%d5\\t%0, #%n1\",
9141        \"cmp%d4\\t%2, %3\"},
9142       {\"cmp%d5\\t%0, %1\",
9143        \"cmn%d4\\t%2, #%n3\"},
9144       {\"cmn%d5\\t%0, #%n1\",
9145        \"cmn%d4\\t%2, #%n3\"}
9146     };
9147     static const char * const cmp2[NUM_OF_COND_CMP][2] =
9148     {
9149       {\"cmp\\t%2, %3\",
9150        \"cmp\\t%0, %1\"},
9151       {\"cmp\\t%2, %3\",
9152        \"cmn\\t%0, #%n1\"},
9153       {\"cmn\\t%2, #%n3\",
9154        \"cmp\\t%0, %1\"},
9155       {\"cmn\\t%2, #%n3\",
9156        \"cmn\\t%0, #%n1\"}
9157     };
9158     static const char * const ite[2] =
9159     {
9160       \"it\\t%d5\",
9161       \"it\\t%d4\"
9162     };
9163     static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
9164                                    CMP_CMP, CMN_CMP, CMP_CMP,
9165                                    CMN_CMP, CMP_CMN, CMN_CMN};
9166     int swap =
9167       comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
9169     output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
9170     if (TARGET_THUMB2) {
9171       output_asm_insn (ite[swap], operands);
9172     }
9173     output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
9174     return \"\";
9175   }"
9176   [(set_attr "conds" "set")
9177    (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
9178    (set_attr "type" "multiple")
9179    (set_attr_alternative "length"
9180       [(const_int 6)
9181        (const_int 8)
9182        (const_int 8)
9183        (const_int 8)
9184        (const_int 8)
9185        (if_then_else (eq_attr "is_thumb" "no")
9186            (const_int 8)
9187            (const_int 10))
9188        (if_then_else (eq_attr "is_thumb" "no")
9189            (const_int 8)
9190            (const_int 10))
9191        (if_then_else (eq_attr "is_thumb" "no")
9192            (const_int 8)
9193            (const_int 10))
9194        (if_then_else (eq_attr "is_thumb" "no")
9195            (const_int 8)
9196            (const_int 10))])]
9199 (define_insn "*cmp_ite1"
9200   [(set (match_operand 6 "dominant_cc_register" "")
9201         (compare
9202          (if_then_else:SI
9203           (match_operator 4 "arm_comparison_operator"
9204            [(match_operand:SI 0 "s_register_operand"
9205                 "l,l,l,r,r,r,r,r,r")
9206             (match_operand:SI 1 "arm_add_operand"
9207                 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
9208           (match_operator:SI 5 "arm_comparison_operator"
9209            [(match_operand:SI 2 "s_register_operand"
9210                 "l,r,r,l,l,r,r,r,r")
9211             (match_operand:SI 3 "arm_add_operand"
9212                 "lPy,rI,L,lPy,lPy,rI,rI,L,L")])
9213           (const_int 1))
9214          (const_int 0)))]
9215   "TARGET_32BIT"
9216   "*
9217   {
9218     static const char * const cmp1[NUM_OF_COND_CMP][2] =
9219     {
9220       {\"cmp\\t%0, %1\",
9221        \"cmp\\t%2, %3\"},
9222       {\"cmn\\t%0, #%n1\",
9223        \"cmp\\t%2, %3\"},
9224       {\"cmp\\t%0, %1\",
9225        \"cmn\\t%2, #%n3\"},
9226       {\"cmn\\t%0, #%n1\",
9227        \"cmn\\t%2, #%n3\"}
9228     };
9229     static const char * const cmp2[NUM_OF_COND_CMP][2] =
9230     {
9231       {\"cmp%d4\\t%2, %3\",
9232        \"cmp%D5\\t%0, %1\"},
9233       {\"cmp%d4\\t%2, %3\",
9234        \"cmn%D5\\t%0, #%n1\"},
9235       {\"cmn%d4\\t%2, #%n3\",
9236        \"cmp%D5\\t%0, %1\"},
9237       {\"cmn%d4\\t%2, #%n3\",
9238        \"cmn%D5\\t%0, #%n1\"}
9239     };
9240     static const char * const ite[2] =
9241     {
9242       \"it\\t%d4\",
9243       \"it\\t%D5\"
9244     };
9245     static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
9246                                    CMP_CMP, CMN_CMP, CMP_CMP,
9247                                    CMN_CMP, CMP_CMN, CMN_CMN};
9248     int swap =
9249       comparison_dominates_p (GET_CODE (operands[5]),
9250                               reverse_condition (GET_CODE (operands[4])));
9252     output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
9253     if (TARGET_THUMB2) {
9254       output_asm_insn (ite[swap], operands);
9255     }
9256     output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
9257     return \"\";
9258   }"
9259   [(set_attr "conds" "set")
9260    (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
9261    (set_attr_alternative "length"
9262       [(const_int 6)
9263        (const_int 8)
9264        (const_int 8)
9265        (const_int 8)
9266        (const_int 8)
9267        (if_then_else (eq_attr "is_thumb" "no")
9268            (const_int 8)
9269            (const_int 10))
9270        (if_then_else (eq_attr "is_thumb" "no")
9271            (const_int 8)
9272            (const_int 10))
9273        (if_then_else (eq_attr "is_thumb" "no")
9274            (const_int 8)
9275            (const_int 10))
9276        (if_then_else (eq_attr "is_thumb" "no")
9277            (const_int 8)
9278            (const_int 10))])
9279    (set_attr "type" "multiple")]
9282 (define_insn "*cmp_and"
9283   [(set (match_operand 6 "dominant_cc_register" "")
9284         (compare
9285          (and:SI
9286           (match_operator 4 "arm_comparison_operator"
9287            [(match_operand:SI 0 "s_register_operand" 
9288                 "l,l,l,r,r,r,r,r,r")
9289             (match_operand:SI 1 "arm_add_operand" 
9290                 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
9291           (match_operator:SI 5 "arm_comparison_operator"
9292            [(match_operand:SI 2 "s_register_operand" 
9293                 "l,r,r,l,l,r,r,r,r")
9294             (match_operand:SI 3 "arm_add_operand" 
9295                 "lPy,rI,L,lPy,lPy,rI,rI,L,L")]))
9296          (const_int 0)))]
9297   "TARGET_32BIT"
9298   "*
9299   {
9300     static const char *const cmp1[NUM_OF_COND_CMP][2] =
9301     {
9302       {\"cmp%d5\\t%0, %1\",
9303        \"cmp%d4\\t%2, %3\"},
9304       {\"cmn%d5\\t%0, #%n1\",
9305        \"cmp%d4\\t%2, %3\"},
9306       {\"cmp%d5\\t%0, %1\",
9307        \"cmn%d4\\t%2, #%n3\"},
9308       {\"cmn%d5\\t%0, #%n1\",
9309        \"cmn%d4\\t%2, #%n3\"}
9310     };
9311     static const char *const cmp2[NUM_OF_COND_CMP][2] =
9312     {
9313       {\"cmp\\t%2, %3\",
9314        \"cmp\\t%0, %1\"},
9315       {\"cmp\\t%2, %3\",
9316        \"cmn\\t%0, #%n1\"},
9317       {\"cmn\\t%2, #%n3\",
9318        \"cmp\\t%0, %1\"},
9319       {\"cmn\\t%2, #%n3\",
9320        \"cmn\\t%0, #%n1\"}
9321     };
9322     static const char *const ite[2] =
9323     {
9324       \"it\\t%d5\",
9325       \"it\\t%d4\"
9326     };
9327     static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
9328                                    CMP_CMP, CMN_CMP, CMP_CMP,
9329                                    CMN_CMP, CMP_CMN, CMN_CMN};
9330     int swap =
9331       comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
9333     output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
9334     if (TARGET_THUMB2) {
9335       output_asm_insn (ite[swap], operands);
9336     }
9337     output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
9338     return \"\";
9339   }"
9340   [(set_attr "conds" "set")
9341    (set_attr "predicable" "no")
9342    (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
9343    (set_attr_alternative "length"
9344       [(const_int 6)
9345        (const_int 8)
9346        (const_int 8)
9347        (const_int 8)
9348        (const_int 8)
9349        (if_then_else (eq_attr "is_thumb" "no")
9350            (const_int 8)
9351            (const_int 10))
9352        (if_then_else (eq_attr "is_thumb" "no")
9353            (const_int 8)
9354            (const_int 10))
9355        (if_then_else (eq_attr "is_thumb" "no")
9356            (const_int 8)
9357            (const_int 10))
9358        (if_then_else (eq_attr "is_thumb" "no")
9359            (const_int 8)
9360            (const_int 10))])
9361    (set_attr "type" "multiple")]
9364 (define_insn "*cmp_ior"
9365   [(set (match_operand 6 "dominant_cc_register" "")
9366         (compare
9367          (ior:SI
9368           (match_operator 4 "arm_comparison_operator"
9369            [(match_operand:SI 0 "s_register_operand"
9370                 "l,l,l,r,r,r,r,r,r")
9371             (match_operand:SI 1 "arm_add_operand"
9372                 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
9373           (match_operator:SI 5 "arm_comparison_operator"
9374            [(match_operand:SI 2 "s_register_operand"
9375                 "l,r,r,l,l,r,r,r,r")
9376             (match_operand:SI 3 "arm_add_operand"
9377                 "lPy,rI,L,lPy,lPy,rI,rI,L,L")]))
9378          (const_int 0)))]
9379   "TARGET_32BIT"
9380   "*
9381   {
9382     static const char *const cmp1[NUM_OF_COND_CMP][2] =
9383     {
9384       {\"cmp\\t%0, %1\",
9385        \"cmp\\t%2, %3\"},
9386       {\"cmn\\t%0, #%n1\",
9387        \"cmp\\t%2, %3\"},
9388       {\"cmp\\t%0, %1\",
9389        \"cmn\\t%2, #%n3\"},
9390       {\"cmn\\t%0, #%n1\",
9391        \"cmn\\t%2, #%n3\"}
9392     };
9393     static const char *const cmp2[NUM_OF_COND_CMP][2] =
9394     {
9395       {\"cmp%D4\\t%2, %3\",
9396        \"cmp%D5\\t%0, %1\"},
9397       {\"cmp%D4\\t%2, %3\",
9398        \"cmn%D5\\t%0, #%n1\"},
9399       {\"cmn%D4\\t%2, #%n3\",
9400        \"cmp%D5\\t%0, %1\"},
9401       {\"cmn%D4\\t%2, #%n3\",
9402        \"cmn%D5\\t%0, #%n1\"}
9403     };
9404     static const char *const ite[2] =
9405     {
9406       \"it\\t%D4\",
9407       \"it\\t%D5\"
9408     };
9409     static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
9410                                    CMP_CMP, CMN_CMP, CMP_CMP,
9411                                    CMN_CMP, CMP_CMN, CMN_CMN};
9412     int swap =
9413       comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
9415     output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
9416     if (TARGET_THUMB2) {
9417       output_asm_insn (ite[swap], operands);
9418     }
9419     output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
9420     return \"\";
9421   }
9422   "
9423   [(set_attr "conds" "set")
9424    (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
9425    (set_attr_alternative "length"
9426       [(const_int 6)
9427        (const_int 8)
9428        (const_int 8)
9429        (const_int 8)
9430        (const_int 8)
9431        (if_then_else (eq_attr "is_thumb" "no")
9432            (const_int 8)
9433            (const_int 10))
9434        (if_then_else (eq_attr "is_thumb" "no")
9435            (const_int 8)
9436            (const_int 10))
9437        (if_then_else (eq_attr "is_thumb" "no")
9438            (const_int 8)
9439            (const_int 10))
9440        (if_then_else (eq_attr "is_thumb" "no")
9441            (const_int 8)
9442            (const_int 10))])
9443    (set_attr "type" "multiple")]
9446 (define_insn_and_split "*ior_scc_scc"
9447   [(set (match_operand:SI 0 "s_register_operand" "=Ts")
9448         (ior:SI (match_operator:SI 3 "arm_comparison_operator"
9449                  [(match_operand:SI 1 "s_register_operand" "r")
9450                   (match_operand:SI 2 "arm_add_operand" "rIL")])
9451                 (match_operator:SI 6 "arm_comparison_operator"
9452                  [(match_operand:SI 4 "s_register_operand" "r")
9453                   (match_operand:SI 5 "arm_add_operand" "rIL")])))
9454    (clobber (reg:CC CC_REGNUM))]
9455   "TARGET_32BIT
9456    && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_OR_Y)
9457        != CCmode)"
9458   "#"
9459   "TARGET_32BIT && reload_completed"
9460   [(set (match_dup 7)
9461         (compare
9462          (ior:SI
9463           (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9464           (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9465          (const_int 0)))
9466    (set (match_dup 0) (ne:SI (match_dup 7) (const_int 0)))]
9467   "operands[7]
9468      = gen_rtx_REG (arm_select_dominance_cc_mode (operands[3], operands[6],
9469                                                   DOM_CC_X_OR_Y),
9470                     CC_REGNUM);"
9471   [(set_attr "conds" "clob")
9472    (set_attr "length" "16")
9473    (set_attr "type" "multiple")]
9476 ; If the above pattern is followed by a CMP insn, then the compare is 
9477 ; redundant, since we can rework the conditional instruction that follows.
9478 (define_insn_and_split "*ior_scc_scc_cmp"
9479   [(set (match_operand 0 "dominant_cc_register" "")
9480         (compare (ior:SI (match_operator:SI 3 "arm_comparison_operator"
9481                           [(match_operand:SI 1 "s_register_operand" "r")
9482                            (match_operand:SI 2 "arm_add_operand" "rIL")])
9483                          (match_operator:SI 6 "arm_comparison_operator"
9484                           [(match_operand:SI 4 "s_register_operand" "r")
9485                            (match_operand:SI 5 "arm_add_operand" "rIL")]))
9486                  (const_int 0)))
9487    (set (match_operand:SI 7 "s_register_operand" "=Ts")
9488         (ior:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9489                 (match_op_dup 6 [(match_dup 4) (match_dup 5)])))]
9490   "TARGET_32BIT"
9491   "#"
9492   "TARGET_32BIT && reload_completed"
9493   [(set (match_dup 0)
9494         (compare
9495          (ior:SI
9496           (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9497           (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9498          (const_int 0)))
9499    (set (match_dup 7) (ne:SI (match_dup 0) (const_int 0)))]
9500   ""
9501   [(set_attr "conds" "set")
9502    (set_attr "length" "16")
9503    (set_attr "type" "multiple")]
9506 (define_insn_and_split "*and_scc_scc"
9507   [(set (match_operand:SI 0 "s_register_operand" "=Ts")
9508         (and:SI (match_operator:SI 3 "arm_comparison_operator"
9509                  [(match_operand:SI 1 "s_register_operand" "r")
9510                   (match_operand:SI 2 "arm_add_operand" "rIL")])
9511                 (match_operator:SI 6 "arm_comparison_operator"
9512                  [(match_operand:SI 4 "s_register_operand" "r")
9513                   (match_operand:SI 5 "arm_add_operand" "rIL")])))
9514    (clobber (reg:CC CC_REGNUM))]
9515   "TARGET_32BIT
9516    && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
9517        != CCmode)"
9518   "#"
9519   "TARGET_32BIT && reload_completed
9520    && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
9521        != CCmode)"
9522   [(set (match_dup 7)
9523         (compare
9524          (and:SI
9525           (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9526           (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9527          (const_int 0)))
9528    (set (match_dup 0) (ne:SI (match_dup 7) (const_int 0)))]
9529   "operands[7]
9530      = gen_rtx_REG (arm_select_dominance_cc_mode (operands[3], operands[6],
9531                                                   DOM_CC_X_AND_Y),
9532                     CC_REGNUM);"
9533   [(set_attr "conds" "clob")
9534    (set_attr "length" "16")
9535    (set_attr "type" "multiple")]
9538 ; If the above pattern is followed by a CMP insn, then the compare is 
9539 ; redundant, since we can rework the conditional instruction that follows.
9540 (define_insn_and_split "*and_scc_scc_cmp"
9541   [(set (match_operand 0 "dominant_cc_register" "")
9542         (compare (and:SI (match_operator:SI 3 "arm_comparison_operator"
9543                           [(match_operand:SI 1 "s_register_operand" "r")
9544                            (match_operand:SI 2 "arm_add_operand" "rIL")])
9545                          (match_operator:SI 6 "arm_comparison_operator"
9546                           [(match_operand:SI 4 "s_register_operand" "r")
9547                            (match_operand:SI 5 "arm_add_operand" "rIL")]))
9548                  (const_int 0)))
9549    (set (match_operand:SI 7 "s_register_operand" "=Ts")
9550         (and:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9551                 (match_op_dup 6 [(match_dup 4) (match_dup 5)])))]
9552   "TARGET_32BIT"
9553   "#"
9554   "TARGET_32BIT && reload_completed"
9555   [(set (match_dup 0)
9556         (compare
9557          (and:SI
9558           (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9559           (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9560          (const_int 0)))
9561    (set (match_dup 7) (ne:SI (match_dup 0) (const_int 0)))]
9562   ""
9563   [(set_attr "conds" "set")
9564    (set_attr "length" "16")
9565    (set_attr "type" "multiple")]
9568 ;; If there is no dominance in the comparison, then we can still save an
9569 ;; instruction in the AND case, since we can know that the second compare
9570 ;; need only zero the value if false (if true, then the value is already
9571 ;; correct).
9572 (define_insn_and_split "*and_scc_scc_nodom"
9573   [(set (match_operand:SI 0 "s_register_operand" "=&Ts,&Ts,&Ts")
9574         (and:SI (match_operator:SI 3 "arm_comparison_operator"
9575                  [(match_operand:SI 1 "s_register_operand" "r,r,0")
9576                   (match_operand:SI 2 "arm_add_operand" "rIL,0,rIL")])
9577                 (match_operator:SI 6 "arm_comparison_operator"
9578                  [(match_operand:SI 4 "s_register_operand" "r,r,r")
9579                   (match_operand:SI 5 "arm_add_operand" "rIL,rIL,rIL")])))
9580    (clobber (reg:CC CC_REGNUM))]
9581   "TARGET_32BIT
9582    && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
9583        == CCmode)"
9584   "#"
9585   "TARGET_32BIT && reload_completed"
9586   [(parallel [(set (match_dup 0)
9587                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
9588               (clobber (reg:CC CC_REGNUM))])
9589    (set (match_dup 7) (match_op_dup 8 [(match_dup 4) (match_dup 5)]))
9590    (set (match_dup 0)
9591         (if_then_else:SI (match_op_dup 6 [(match_dup 7) (const_int 0)])
9592                          (match_dup 0)
9593                          (const_int 0)))]
9594   "operands[7] = gen_rtx_REG (SELECT_CC_MODE (GET_CODE (operands[6]),
9595                                               operands[4], operands[5]),
9596                               CC_REGNUM);
9597    operands[8] = gen_rtx_COMPARE (GET_MODE (operands[7]), operands[4],
9598                                   operands[5]);"
9599   [(set_attr "conds" "clob")
9600    (set_attr "length" "20")
9601    (set_attr "type" "multiple")]
9604 (define_split
9605   [(set (reg:CC_NOOV CC_REGNUM)
9606         (compare:CC_NOOV (ior:SI
9607                           (and:SI (match_operand:SI 0 "s_register_operand" "")
9608                                   (const_int 1))
9609                           (match_operator:SI 1 "arm_comparison_operator"
9610                            [(match_operand:SI 2 "s_register_operand" "")
9611                             (match_operand:SI 3 "arm_add_operand" "")]))
9612                          (const_int 0)))
9613    (clobber (match_operand:SI 4 "s_register_operand" ""))]
9614   "TARGET_ARM"
9615   [(set (match_dup 4)
9616         (ior:SI (match_op_dup 1 [(match_dup 2) (match_dup 3)])
9617                 (match_dup 0)))
9618    (set (reg:CC_NOOV CC_REGNUM)
9619         (compare:CC_NOOV (and:SI (match_dup 4) (const_int 1))
9620                          (const_int 0)))]
9621   "")
9623 (define_split
9624   [(set (reg:CC_NOOV CC_REGNUM)
9625         (compare:CC_NOOV (ior:SI
9626                           (match_operator:SI 1 "arm_comparison_operator"
9627                            [(match_operand:SI 2 "s_register_operand" "")
9628                             (match_operand:SI 3 "arm_add_operand" "")])
9629                           (and:SI (match_operand:SI 0 "s_register_operand" "")
9630                                   (const_int 1)))
9631                          (const_int 0)))
9632    (clobber (match_operand:SI 4 "s_register_operand" ""))]
9633   "TARGET_ARM"
9634   [(set (match_dup 4)
9635         (ior:SI (match_op_dup 1 [(match_dup 2) (match_dup 3)])
9636                 (match_dup 0)))
9637    (set (reg:CC_NOOV CC_REGNUM)
9638         (compare:CC_NOOV (and:SI (match_dup 4) (const_int 1))
9639                          (const_int 0)))]
9640   "")
9641 ;; ??? The conditional patterns above need checking for Thumb-2 usefulness
9643 (define_insn_and_split "*negscc"
9644   [(set (match_operand:SI 0 "s_register_operand" "=r")
9645         (neg:SI (match_operator 3 "arm_comparison_operator"
9646                  [(match_operand:SI 1 "s_register_operand" "r")
9647                   (match_operand:SI 2 "arm_rhs_operand" "rI")])))
9648    (clobber (reg:CC CC_REGNUM))]
9649   "TARGET_ARM"
9650   "#"
9651   "&& reload_completed"
9652   [(const_int 0)]
9653   {
9654     rtx cc_reg = gen_rtx_REG (CCmode, CC_REGNUM);
9656     if (GET_CODE (operands[3]) == LT && operands[2] == const0_rtx)
9657        {
9658          /* Emit mov\\t%0, %1, asr #31 */
9659          emit_insn (gen_rtx_SET (operands[0],
9660                                  gen_rtx_ASHIFTRT (SImode,
9661                                                    operands[1],
9662                                                    GEN_INT (31))));
9663          DONE;
9664        }
9665      else if (GET_CODE (operands[3]) == NE)
9666        {
9667         /* Emit subs\\t%0, %1, %2\;mvnne\\t%0, #0 */
9668         if (CONST_INT_P (operands[2]))
9669           emit_insn (gen_cmpsi2_addneg (operands[0], operands[1], operands[2],
9670                                         GEN_INT (- INTVAL (operands[2]))));
9671         else
9672           emit_insn (gen_subsi3_compare (operands[0], operands[1], operands[2]));
9674         emit_insn (gen_rtx_COND_EXEC (VOIDmode,
9675                                       gen_rtx_NE (SImode,
9676                                                   cc_reg,
9677                                                   const0_rtx),
9678                                       gen_rtx_SET (operands[0],
9679                                                    GEN_INT (~0))));
9680         DONE;
9681       }
9682     else
9683       {
9684         /* Emit: cmp\\t%1, %2\;mov%D3\\t%0, #0\;mvn%d3\\t%0, #0 */
9685         emit_insn (gen_rtx_SET (cc_reg,
9686                                 gen_rtx_COMPARE (CCmode, operands[1], operands[2])));
9687         enum rtx_code rc = GET_CODE (operands[3]);
9689         rc = reverse_condition (rc);
9690         emit_insn (gen_rtx_COND_EXEC (VOIDmode,
9691                                       gen_rtx_fmt_ee (rc,
9692                                                       VOIDmode,
9693                                                       cc_reg,
9694                                                       const0_rtx),
9695                                       gen_rtx_SET (operands[0], const0_rtx)));
9696         rc = GET_CODE (operands[3]);
9697         emit_insn (gen_rtx_COND_EXEC (VOIDmode,
9698                                       gen_rtx_fmt_ee (rc,
9699                                                       VOIDmode,
9700                                                       cc_reg,
9701                                                       const0_rtx),
9702                                       gen_rtx_SET (operands[0],
9703                                                    GEN_INT (~0))));
9704         DONE;
9705       }
9706      FAIL;
9707   }
9708   [(set_attr "conds" "clob")
9709    (set_attr "length" "12")
9710    (set_attr "type" "multiple")]
9713 (define_insn_and_split "movcond_addsi"
9714   [(set (match_operand:SI 0 "s_register_operand" "=r,l,r")
9715         (if_then_else:SI
9716          (match_operator 5 "comparison_operator"
9717           [(plus:SI (match_operand:SI 3 "s_register_operand" "r,r,r")
9718                     (match_operand:SI 4 "arm_add_operand" "rIL,rIL,rIL"))
9719             (const_int 0)])
9720          (match_operand:SI 1 "arm_rhs_operand" "rI,rPy,r")
9721          (match_operand:SI 2 "arm_rhs_operand" "rI,rPy,r")))
9722    (clobber (reg:CC CC_REGNUM))]
9723    "TARGET_32BIT"
9724    "#"
9725    "&& reload_completed"
9726   [(set (reg:CC_NOOV CC_REGNUM)
9727         (compare:CC_NOOV
9728          (plus:SI (match_dup 3)
9729                   (match_dup 4))
9730          (const_int 0)))
9731    (set (match_dup 0) (match_dup 1))
9732    (cond_exec (match_dup 6)
9733               (set (match_dup 0) (match_dup 2)))]
9734   "
9735   {
9736     machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[5]),
9737                                              operands[3], operands[4]);
9738     enum rtx_code rc = GET_CODE (operands[5]);
9739     operands[6] = gen_rtx_REG (mode, CC_REGNUM);
9740     gcc_assert (!(mode == CCFPmode || mode == CCFPEmode));
9741     if (!REG_P (operands[2]) || REGNO (operands[2]) != REGNO (operands[0]))
9742       rc = reverse_condition (rc);
9743     else
9744       std::swap (operands[1], operands[2]);
9746     operands[6] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
9747   }
9748   "
9749   [(set_attr "conds" "clob")
9750    (set_attr "enabled_for_depr_it" "no,yes,yes")
9751    (set_attr "type" "multiple")]
9754 (define_insn "movcond"
9755   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9756         (if_then_else:SI
9757          (match_operator 5 "arm_comparison_operator"
9758           [(match_operand:SI 3 "s_register_operand" "r,r,r")
9759            (match_operand:SI 4 "arm_add_operand" "rIL,rIL,rIL")])
9760          (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
9761          (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
9762    (clobber (reg:CC CC_REGNUM))]
9763   "TARGET_ARM"
9764   "*
9765   if (GET_CODE (operands[5]) == LT
9766       && (operands[4] == const0_rtx))
9767     {
9768       if (which_alternative != 1 && REG_P (operands[1]))
9769         {
9770           if (operands[2] == const0_rtx)
9771             return \"and\\t%0, %1, %3, asr #31\";
9772           return \"ands\\t%0, %1, %3, asr #32\;movcc\\t%0, %2\";
9773         }
9774       else if (which_alternative != 0 && REG_P (operands[2]))
9775         {
9776           if (operands[1] == const0_rtx)
9777             return \"bic\\t%0, %2, %3, asr #31\";
9778           return \"bics\\t%0, %2, %3, asr #32\;movcs\\t%0, %1\";
9779         }
9780       /* The only case that falls through to here is when both ops 1 & 2
9781          are constants.  */
9782     }
9784   if (GET_CODE (operands[5]) == GE
9785       && (operands[4] == const0_rtx))
9786     {
9787       if (which_alternative != 1 && REG_P (operands[1]))
9788         {
9789           if (operands[2] == const0_rtx)
9790             return \"bic\\t%0, %1, %3, asr #31\";
9791           return \"bics\\t%0, %1, %3, asr #32\;movcs\\t%0, %2\";
9792         }
9793       else if (which_alternative != 0 && REG_P (operands[2]))
9794         {
9795           if (operands[1] == const0_rtx)
9796             return \"and\\t%0, %2, %3, asr #31\";
9797           return \"ands\\t%0, %2, %3, asr #32\;movcc\\t%0, %1\";
9798         }
9799       /* The only case that falls through to here is when both ops 1 & 2
9800          are constants.  */
9801     }
9802   if (CONST_INT_P (operands[4])
9803       && !const_ok_for_arm (INTVAL (operands[4])))
9804     output_asm_insn (\"cmn\\t%3, #%n4\", operands);
9805   else
9806     output_asm_insn (\"cmp\\t%3, %4\", operands);
9807   if (which_alternative != 0)
9808     output_asm_insn (\"mov%d5\\t%0, %1\", operands);
9809   if (which_alternative != 1)
9810     output_asm_insn (\"mov%D5\\t%0, %2\", operands);
9811   return \"\";
9812   "
9813   [(set_attr "conds" "clob")
9814    (set_attr "length" "8,8,12")
9815    (set_attr "type" "multiple")]
9818 ;; ??? The patterns below need checking for Thumb-2 usefulness.
9820 (define_insn "*ifcompare_plus_move"
9821   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9822         (if_then_else:SI (match_operator 6 "arm_comparison_operator"
9823                           [(match_operand:SI 4 "s_register_operand" "r,r")
9824                            (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
9825                          (plus:SI
9826                           (match_operand:SI 2 "s_register_operand" "r,r")
9827                           (match_operand:SI 3 "arm_add_operand" "rIL,rIL"))
9828                          (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))
9829    (clobber (reg:CC CC_REGNUM))]
9830   "TARGET_ARM"
9831   "#"
9832   [(set_attr "conds" "clob")
9833    (set_attr "length" "8,12")
9834    (set_attr "type" "multiple")]
9837 (define_insn "*if_plus_move"
9838   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
9839         (if_then_else:SI
9840          (match_operator 4 "arm_comparison_operator"
9841           [(match_operand 5 "cc_register" "") (const_int 0)])
9842          (plus:SI
9843           (match_operand:SI 2 "s_register_operand" "r,r,r,r")
9844           (match_operand:SI 3 "arm_add_operand" "rI,L,rI,L"))
9845          (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")))]
9846   "TARGET_ARM"
9847   "@
9848    add%d4\\t%0, %2, %3
9849    sub%d4\\t%0, %2, #%n3
9850    add%d4\\t%0, %2, %3\;mov%D4\\t%0, %1
9851    sub%d4\\t%0, %2, #%n3\;mov%D4\\t%0, %1"
9852   [(set_attr "conds" "use")
9853    (set_attr "length" "4,4,8,8")
9854    (set_attr_alternative "type"
9855                          [(if_then_else (match_operand 3 "const_int_operand" "")
9856                                         (const_string "alu_imm" )
9857                                         (const_string "alu_sreg"))
9858                           (const_string "alu_imm")
9859                           (const_string "multiple")
9860                           (const_string "multiple")])]
9863 (define_insn "*ifcompare_move_plus"
9864   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9865         (if_then_else:SI (match_operator 6 "arm_comparison_operator"
9866                           [(match_operand:SI 4 "s_register_operand" "r,r")
9867                            (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
9868                          (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
9869                          (plus:SI
9870                           (match_operand:SI 2 "s_register_operand" "r,r")
9871                           (match_operand:SI 3 "arm_add_operand" "rIL,rIL"))))
9872    (clobber (reg:CC CC_REGNUM))]
9873   "TARGET_ARM"
9874   "#"
9875   [(set_attr "conds" "clob")
9876    (set_attr "length" "8,12")
9877    (set_attr "type" "multiple")]
9880 (define_insn "*if_move_plus"
9881   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
9882         (if_then_else:SI
9883          (match_operator 4 "arm_comparison_operator"
9884           [(match_operand 5 "cc_register" "") (const_int 0)])
9885          (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")
9886          (plus:SI
9887           (match_operand:SI 2 "s_register_operand" "r,r,r,r")
9888           (match_operand:SI 3 "arm_add_operand" "rI,L,rI,L"))))]
9889   "TARGET_ARM"
9890   "@
9891    add%D4\\t%0, %2, %3
9892    sub%D4\\t%0, %2, #%n3
9893    add%D4\\t%0, %2, %3\;mov%d4\\t%0, %1
9894    sub%D4\\t%0, %2, #%n3\;mov%d4\\t%0, %1"
9895   [(set_attr "conds" "use")
9896    (set_attr "length" "4,4,8,8")
9897    (set_attr_alternative "type"
9898                          [(if_then_else (match_operand 3 "const_int_operand" "")
9899                                         (const_string "alu_imm" )
9900                                         (const_string "alu_sreg"))
9901                           (const_string "alu_imm")
9902                           (const_string "multiple")
9903                           (const_string "multiple")])]
9906 (define_insn "*ifcompare_arith_arith"
9907   [(set (match_operand:SI 0 "s_register_operand" "=r")
9908         (if_then_else:SI (match_operator 9 "arm_comparison_operator"
9909                           [(match_operand:SI 5 "s_register_operand" "r")
9910                            (match_operand:SI 6 "arm_add_operand" "rIL")])
9911                          (match_operator:SI 8 "shiftable_operator"
9912                           [(match_operand:SI 1 "s_register_operand" "r")
9913                            (match_operand:SI 2 "arm_rhs_operand" "rI")])
9914                          (match_operator:SI 7 "shiftable_operator"
9915                           [(match_operand:SI 3 "s_register_operand" "r")
9916                            (match_operand:SI 4 "arm_rhs_operand" "rI")])))
9917    (clobber (reg:CC CC_REGNUM))]
9918   "TARGET_ARM"
9919   "#"
9920   [(set_attr "conds" "clob")
9921    (set_attr "length" "12")
9922    (set_attr "type" "multiple")]
9925 (define_insn "*if_arith_arith"
9926   [(set (match_operand:SI 0 "s_register_operand" "=r")
9927         (if_then_else:SI (match_operator 5 "arm_comparison_operator"
9928                           [(match_operand 8 "cc_register" "") (const_int 0)])
9929                          (match_operator:SI 6 "shiftable_operator"
9930                           [(match_operand:SI 1 "s_register_operand" "r")
9931                            (match_operand:SI 2 "arm_rhs_operand" "rI")])
9932                          (match_operator:SI 7 "shiftable_operator"
9933                           [(match_operand:SI 3 "s_register_operand" "r")
9934                            (match_operand:SI 4 "arm_rhs_operand" "rI")])))]
9935   "TARGET_ARM"
9936   "%I6%d5\\t%0, %1, %2\;%I7%D5\\t%0, %3, %4"
9937   [(set_attr "conds" "use")
9938    (set_attr "length" "8")
9939    (set_attr "type" "multiple")]
9942 (define_insn "*ifcompare_arith_move"
9943   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9944         (if_then_else:SI (match_operator 6 "arm_comparison_operator"
9945                           [(match_operand:SI 2 "s_register_operand" "r,r")
9946                            (match_operand:SI 3 "arm_add_operand" "rIL,rIL")])
9947                          (match_operator:SI 7 "shiftable_operator"
9948                           [(match_operand:SI 4 "s_register_operand" "r,r")
9949                            (match_operand:SI 5 "arm_rhs_operand" "rI,rI")])
9950                          (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))
9951    (clobber (reg:CC CC_REGNUM))]
9952   "TARGET_ARM"
9953   "*
9954   /* If we have an operation where (op x 0) is the identity operation and
9955      the conditional operator is LT or GE and we are comparing against zero and
9956      everything is in registers then we can do this in two instructions.  */
9957   if (operands[3] == const0_rtx
9958       && GET_CODE (operands[7]) != AND
9959       && REG_P (operands[5])
9960       && REG_P (operands[1])
9961       && REGNO (operands[1]) == REGNO (operands[4])
9962       && REGNO (operands[4]) != REGNO (operands[0]))
9963     {
9964       if (GET_CODE (operands[6]) == LT)
9965         return \"and\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\";
9966       else if (GET_CODE (operands[6]) == GE)
9967         return \"bic\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\";
9968     }
9969   if (CONST_INT_P (operands[3])
9970       && !const_ok_for_arm (INTVAL (operands[3])))
9971     output_asm_insn (\"cmn\\t%2, #%n3\", operands);
9972   else
9973     output_asm_insn (\"cmp\\t%2, %3\", operands);
9974   output_asm_insn (\"%I7%d6\\t%0, %4, %5\", operands);
9975   if (which_alternative != 0)
9976     return \"mov%D6\\t%0, %1\";
9977   return \"\";
9978   "
9979   [(set_attr "conds" "clob")
9980    (set_attr "length" "8,12")
9981    (set_attr "type" "multiple")]
9984 (define_insn "*if_arith_move"
9985   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9986         (if_then_else:SI (match_operator 4 "arm_comparison_operator"
9987                           [(match_operand 6 "cc_register" "") (const_int 0)])
9988                          (match_operator:SI 5 "shiftable_operator"
9989                           [(match_operand:SI 2 "s_register_operand" "r,r")
9990                            (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
9991                          (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))]
9992   "TARGET_ARM"
9993   "@
9994    %I5%d4\\t%0, %2, %3
9995    %I5%d4\\t%0, %2, %3\;mov%D4\\t%0, %1"
9996   [(set_attr "conds" "use")
9997    (set_attr "length" "4,8")
9998    (set_attr_alternative "type"
9999                          [(if_then_else (match_operand 3 "const_int_operand" "")
10000                                         (const_string "alu_shift_imm" )
10001                                         (const_string "alu_shift_reg"))
10002                           (const_string "multiple")])]
10005 (define_insn "*ifcompare_move_arith"
10006   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10007         (if_then_else:SI (match_operator 6 "arm_comparison_operator"
10008                           [(match_operand:SI 4 "s_register_operand" "r,r")
10009                            (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
10010                          (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
10011                          (match_operator:SI 7 "shiftable_operator"
10012                           [(match_operand:SI 2 "s_register_operand" "r,r")
10013                            (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
10014    (clobber (reg:CC CC_REGNUM))]
10015   "TARGET_ARM"
10016   "*
10017   /* If we have an operation where (op x 0) is the identity operation and
10018      the conditional operator is LT or GE and we are comparing against zero and
10019      everything is in registers then we can do this in two instructions */
10020   if (operands[5] == const0_rtx
10021       && GET_CODE (operands[7]) != AND
10022       && REG_P (operands[3])
10023       && REG_P (operands[1])
10024       && REGNO (operands[1]) == REGNO (operands[2])
10025       && REGNO (operands[2]) != REGNO (operands[0]))
10026     {
10027       if (GET_CODE (operands[6]) == GE)
10028         return \"and\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\";
10029       else if (GET_CODE (operands[6]) == LT)
10030         return \"bic\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\";
10031     }
10033   if (CONST_INT_P (operands[5])
10034       && !const_ok_for_arm (INTVAL (operands[5])))
10035     output_asm_insn (\"cmn\\t%4, #%n5\", operands);
10036   else
10037     output_asm_insn (\"cmp\\t%4, %5\", operands);
10039   if (which_alternative != 0)
10040     output_asm_insn (\"mov%d6\\t%0, %1\", operands);
10041   return \"%I7%D6\\t%0, %2, %3\";
10042   "
10043   [(set_attr "conds" "clob")
10044    (set_attr "length" "8,12")
10045    (set_attr "type" "multiple")]
10048 (define_insn "*if_move_arith"
10049   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10050         (if_then_else:SI
10051          (match_operator 4 "arm_comparison_operator"
10052           [(match_operand 6 "cc_register" "") (const_int 0)])
10053          (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
10054          (match_operator:SI 5 "shiftable_operator"
10055           [(match_operand:SI 2 "s_register_operand" "r,r")
10056            (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))]
10057   "TARGET_ARM"
10058   "@
10059    %I5%D4\\t%0, %2, %3
10060    %I5%D4\\t%0, %2, %3\;mov%d4\\t%0, %1"
10061   [(set_attr "conds" "use")
10062    (set_attr "length" "4,8")
10063    (set_attr_alternative "type"
10064                          [(if_then_else (match_operand 3 "const_int_operand" "")
10065                                         (const_string "alu_shift_imm" )
10066                                         (const_string "alu_shift_reg"))
10067                           (const_string "multiple")])]
10070 (define_insn "*ifcompare_move_not"
10071   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10072         (if_then_else:SI
10073          (match_operator 5 "arm_comparison_operator"
10074           [(match_operand:SI 3 "s_register_operand" "r,r")
10075            (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
10076          (match_operand:SI 1 "arm_not_operand" "0,?rIK")
10077          (not:SI
10078           (match_operand:SI 2 "s_register_operand" "r,r"))))
10079    (clobber (reg:CC CC_REGNUM))]
10080   "TARGET_ARM"
10081   "#"
10082   [(set_attr "conds" "clob")
10083    (set_attr "length" "8,12")
10084    (set_attr "type" "multiple")]
10087 (define_insn "*if_move_not"
10088   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
10089         (if_then_else:SI
10090          (match_operator 4 "arm_comparison_operator"
10091           [(match_operand 3 "cc_register" "") (const_int 0)])
10092          (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
10093          (not:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))))]
10094   "TARGET_ARM"
10095   "@
10096    mvn%D4\\t%0, %2
10097    mov%d4\\t%0, %1\;mvn%D4\\t%0, %2
10098    mvn%d4\\t%0, #%B1\;mvn%D4\\t%0, %2"
10099   [(set_attr "conds" "use")
10100    (set_attr "type" "mvn_reg")
10101    (set_attr "length" "4,8,8")
10102    (set_attr "type" "mvn_reg,multiple,multiple")]
10105 (define_insn "*ifcompare_not_move"
10106   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10107         (if_then_else:SI 
10108          (match_operator 5 "arm_comparison_operator"
10109           [(match_operand:SI 3 "s_register_operand" "r,r")
10110            (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
10111          (not:SI
10112           (match_operand:SI 2 "s_register_operand" "r,r"))
10113          (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
10114    (clobber (reg:CC CC_REGNUM))]
10115   "TARGET_ARM"
10116   "#"
10117   [(set_attr "conds" "clob")
10118    (set_attr "length" "8,12")
10119    (set_attr "type" "multiple")]
10122 (define_insn "*if_not_move"
10123   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
10124         (if_then_else:SI
10125          (match_operator 4 "arm_comparison_operator"
10126           [(match_operand 3 "cc_register" "") (const_int 0)])
10127          (not:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))
10128          (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
10129   "TARGET_ARM"
10130   "@
10131    mvn%d4\\t%0, %2
10132    mov%D4\\t%0, %1\;mvn%d4\\t%0, %2
10133    mvn%D4\\t%0, #%B1\;mvn%d4\\t%0, %2"
10134   [(set_attr "conds" "use")
10135    (set_attr "type" "mvn_reg,multiple,multiple")
10136    (set_attr "length" "4,8,8")]
10139 (define_insn "*ifcompare_shift_move"
10140   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10141         (if_then_else:SI
10142          (match_operator 6 "arm_comparison_operator"
10143           [(match_operand:SI 4 "s_register_operand" "r,r")
10144            (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
10145          (match_operator:SI 7 "shift_operator"
10146           [(match_operand:SI 2 "s_register_operand" "r,r")
10147            (match_operand:SI 3 "arm_rhs_operand" "rM,rM")])
10148          (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
10149    (clobber (reg:CC CC_REGNUM))]
10150   "TARGET_ARM"
10151   "#"
10152   [(set_attr "conds" "clob")
10153    (set_attr "length" "8,12")
10154    (set_attr "type" "multiple")]
10157 (define_insn "*if_shift_move"
10158   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
10159         (if_then_else:SI
10160          (match_operator 5 "arm_comparison_operator"
10161           [(match_operand 6 "cc_register" "") (const_int 0)])
10162          (match_operator:SI 4 "shift_operator"
10163           [(match_operand:SI 2 "s_register_operand" "r,r,r")
10164            (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM")])
10165          (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
10166   "TARGET_ARM"
10167   "@
10168    mov%d5\\t%0, %2%S4
10169    mov%D5\\t%0, %1\;mov%d5\\t%0, %2%S4
10170    mvn%D5\\t%0, #%B1\;mov%d5\\t%0, %2%S4"
10171   [(set_attr "conds" "use")
10172    (set_attr "shift" "2")
10173    (set_attr "length" "4,8,8")
10174    (set_attr_alternative "type"
10175                          [(if_then_else (match_operand 3 "const_int_operand" "")
10176                                         (const_string "mov_shift" )
10177                                         (const_string "mov_shift_reg"))
10178                           (const_string "multiple")
10179                           (const_string "multiple")])]
10182 (define_insn "*ifcompare_move_shift"
10183   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10184         (if_then_else:SI
10185          (match_operator 6 "arm_comparison_operator"
10186           [(match_operand:SI 4 "s_register_operand" "r,r")
10187            (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
10188          (match_operand:SI 1 "arm_not_operand" "0,?rIK")
10189          (match_operator:SI 7 "shift_operator"
10190           [(match_operand:SI 2 "s_register_operand" "r,r")
10191            (match_operand:SI 3 "arm_rhs_operand" "rM,rM")])))
10192    (clobber (reg:CC CC_REGNUM))]
10193   "TARGET_ARM"
10194   "#"
10195   [(set_attr "conds" "clob")
10196    (set_attr "length" "8,12")
10197    (set_attr "type" "multiple")]
10200 (define_insn "*if_move_shift"
10201   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
10202         (if_then_else:SI
10203          (match_operator 5 "arm_comparison_operator"
10204           [(match_operand 6 "cc_register" "") (const_int 0)])
10205          (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
10206          (match_operator:SI 4 "shift_operator"
10207           [(match_operand:SI 2 "s_register_operand" "r,r,r")
10208            (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM")])))]
10209   "TARGET_ARM"
10210   "@
10211    mov%D5\\t%0, %2%S4
10212    mov%d5\\t%0, %1\;mov%D5\\t%0, %2%S4
10213    mvn%d5\\t%0, #%B1\;mov%D5\\t%0, %2%S4"
10214   [(set_attr "conds" "use")
10215    (set_attr "shift" "2")
10216    (set_attr "length" "4,8,8")
10217    (set_attr_alternative "type"
10218                          [(if_then_else (match_operand 3 "const_int_operand" "")
10219                                         (const_string "mov_shift" )
10220                                         (const_string "mov_shift_reg"))
10221                           (const_string "multiple")
10222                           (const_string "multiple")])]
10225 (define_insn "*ifcompare_shift_shift"
10226   [(set (match_operand:SI 0 "s_register_operand" "=r")
10227         (if_then_else:SI
10228          (match_operator 7 "arm_comparison_operator"
10229           [(match_operand:SI 5 "s_register_operand" "r")
10230            (match_operand:SI 6 "arm_add_operand" "rIL")])
10231          (match_operator:SI 8 "shift_operator"
10232           [(match_operand:SI 1 "s_register_operand" "r")
10233            (match_operand:SI 2 "arm_rhs_operand" "rM")])
10234          (match_operator:SI 9 "shift_operator"
10235           [(match_operand:SI 3 "s_register_operand" "r")
10236            (match_operand:SI 4 "arm_rhs_operand" "rM")])))
10237    (clobber (reg:CC CC_REGNUM))]
10238   "TARGET_ARM"
10239   "#"
10240   [(set_attr "conds" "clob")
10241    (set_attr "length" "12")
10242    (set_attr "type" "multiple")]
10245 (define_insn "*if_shift_shift"
10246   [(set (match_operand:SI 0 "s_register_operand" "=r")
10247         (if_then_else:SI
10248          (match_operator 5 "arm_comparison_operator"
10249           [(match_operand 8 "cc_register" "") (const_int 0)])
10250          (match_operator:SI 6 "shift_operator"
10251           [(match_operand:SI 1 "s_register_operand" "r")
10252            (match_operand:SI 2 "arm_rhs_operand" "rM")])
10253          (match_operator:SI 7 "shift_operator"
10254           [(match_operand:SI 3 "s_register_operand" "r")
10255            (match_operand:SI 4 "arm_rhs_operand" "rM")])))]
10256   "TARGET_ARM"
10257   "mov%d5\\t%0, %1%S6\;mov%D5\\t%0, %3%S7"
10258   [(set_attr "conds" "use")
10259    (set_attr "shift" "1")
10260    (set_attr "length" "8")
10261    (set (attr "type") (if_then_else
10262                         (and (match_operand 2 "const_int_operand" "")
10263                              (match_operand 4 "const_int_operand" ""))
10264                       (const_string "mov_shift")
10265                       (const_string "mov_shift_reg")))]
10268 (define_insn "*ifcompare_not_arith"
10269   [(set (match_operand:SI 0 "s_register_operand" "=r")
10270         (if_then_else:SI
10271          (match_operator 6 "arm_comparison_operator"
10272           [(match_operand:SI 4 "s_register_operand" "r")
10273            (match_operand:SI 5 "arm_add_operand" "rIL")])
10274          (not:SI (match_operand:SI 1 "s_register_operand" "r"))
10275          (match_operator:SI 7 "shiftable_operator"
10276           [(match_operand:SI 2 "s_register_operand" "r")
10277            (match_operand:SI 3 "arm_rhs_operand" "rI")])))
10278    (clobber (reg:CC CC_REGNUM))]
10279   "TARGET_ARM"
10280   "#"
10281   [(set_attr "conds" "clob")
10282    (set_attr "length" "12")
10283    (set_attr "type" "multiple")]
10286 (define_insn "*if_not_arith"
10287   [(set (match_operand:SI 0 "s_register_operand" "=r")
10288         (if_then_else:SI
10289          (match_operator 5 "arm_comparison_operator"
10290           [(match_operand 4 "cc_register" "") (const_int 0)])
10291          (not:SI (match_operand:SI 1 "s_register_operand" "r"))
10292          (match_operator:SI 6 "shiftable_operator"
10293           [(match_operand:SI 2 "s_register_operand" "r")
10294            (match_operand:SI 3 "arm_rhs_operand" "rI")])))]
10295   "TARGET_ARM"
10296   "mvn%d5\\t%0, %1\;%I6%D5\\t%0, %2, %3"
10297   [(set_attr "conds" "use")
10298    (set_attr "type" "mvn_reg")
10299    (set_attr "length" "8")]
10302 (define_insn "*ifcompare_arith_not"
10303   [(set (match_operand:SI 0 "s_register_operand" "=r")
10304         (if_then_else:SI
10305          (match_operator 6 "arm_comparison_operator"
10306           [(match_operand:SI 4 "s_register_operand" "r")
10307            (match_operand:SI 5 "arm_add_operand" "rIL")])
10308          (match_operator:SI 7 "shiftable_operator"
10309           [(match_operand:SI 2 "s_register_operand" "r")
10310            (match_operand:SI 3 "arm_rhs_operand" "rI")])
10311          (not:SI (match_operand:SI 1 "s_register_operand" "r"))))
10312    (clobber (reg:CC CC_REGNUM))]
10313   "TARGET_ARM"
10314   "#"
10315   [(set_attr "conds" "clob")
10316    (set_attr "length" "12")
10317    (set_attr "type" "multiple")]
10320 (define_insn "*if_arith_not"
10321   [(set (match_operand:SI 0 "s_register_operand" "=r")
10322         (if_then_else:SI
10323          (match_operator 5 "arm_comparison_operator"
10324           [(match_operand 4 "cc_register" "") (const_int 0)])
10325          (match_operator:SI 6 "shiftable_operator"
10326           [(match_operand:SI 2 "s_register_operand" "r")
10327            (match_operand:SI 3 "arm_rhs_operand" "rI")])
10328          (not:SI (match_operand:SI 1 "s_register_operand" "r"))))]
10329   "TARGET_ARM"
10330   "mvn%D5\\t%0, %1\;%I6%d5\\t%0, %2, %3"
10331   [(set_attr "conds" "use")
10332    (set_attr "type" "multiple")
10333    (set_attr "length" "8")]
10336 (define_insn "*ifcompare_neg_move"
10337   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10338         (if_then_else:SI
10339          (match_operator 5 "arm_comparison_operator"
10340           [(match_operand:SI 3 "s_register_operand" "r,r")
10341            (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
10342          (neg:SI (match_operand:SI 2 "s_register_operand" "r,r"))
10343          (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
10344    (clobber (reg:CC CC_REGNUM))]
10345   "TARGET_ARM"
10346   "#"
10347   [(set_attr "conds" "clob")
10348    (set_attr "length" "8,12")
10349    (set_attr "type" "multiple")]
10352 (define_insn_and_split "*if_neg_move"
10353   [(set (match_operand:SI 0 "s_register_operand" "=l,r")
10354         (if_then_else:SI
10355          (match_operator 4 "arm_comparison_operator"
10356           [(match_operand 3 "cc_register" "") (const_int 0)])
10357          (neg:SI (match_operand:SI 2 "s_register_operand" "l,r"))
10358          (match_operand:SI 1 "s_register_operand" "0,0")))]
10359   "TARGET_32BIT"
10360   "#"
10361   "&& reload_completed"
10362   [(cond_exec (match_op_dup 4 [(match_dup 3) (const_int 0)])
10363               (set (match_dup 0) (neg:SI (match_dup 2))))]
10364   ""
10365   [(set_attr "conds" "use")
10366    (set_attr "length" "4")
10367    (set_attr "arch" "t2,32")
10368    (set_attr "enabled_for_depr_it" "yes,no")
10369    (set_attr "type" "logic_shift_imm")]
10372 (define_insn "*ifcompare_move_neg"
10373   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10374         (if_then_else:SI
10375          (match_operator 5 "arm_comparison_operator"
10376           [(match_operand:SI 3 "s_register_operand" "r,r")
10377            (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
10378          (match_operand:SI 1 "arm_not_operand" "0,?rIK")
10379          (neg:SI (match_operand:SI 2 "s_register_operand" "r,r"))))
10380    (clobber (reg:CC CC_REGNUM))]
10381   "TARGET_ARM"
10382   "#"
10383   [(set_attr "conds" "clob")
10384    (set_attr "length" "8,12")
10385    (set_attr "type" "multiple")]
10388 (define_insn_and_split "*if_move_neg"
10389   [(set (match_operand:SI 0 "s_register_operand" "=l,r")
10390         (if_then_else:SI
10391          (match_operator 4 "arm_comparison_operator"
10392           [(match_operand 3 "cc_register" "") (const_int 0)])
10393          (match_operand:SI 1 "s_register_operand" "0,0")
10394          (neg:SI (match_operand:SI 2 "s_register_operand" "l,r"))))]
10395   "TARGET_32BIT"
10396   "#"
10397   "&& reload_completed"
10398   [(cond_exec (match_dup 5)
10399               (set (match_dup 0) (neg:SI (match_dup 2))))]
10400   {
10401     machine_mode mode = GET_MODE (operands[3]);
10402     rtx_code rc = GET_CODE (operands[4]);
10404     if (mode == CCFPmode || mode == CCFPEmode)
10405       rc = reverse_condition_maybe_unordered (rc);
10406     else
10407       rc = reverse_condition (rc);
10409     operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[3], const0_rtx);
10410   }
10411   [(set_attr "conds" "use")
10412    (set_attr "length" "4")
10413    (set_attr "arch" "t2,32")
10414    (set_attr "enabled_for_depr_it" "yes,no")
10415    (set_attr "type" "logic_shift_imm")]
10418 (define_insn "*arith_adjacentmem"
10419   [(set (match_operand:SI 0 "s_register_operand" "=r")
10420         (match_operator:SI 1 "shiftable_operator"
10421          [(match_operand:SI 2 "memory_operand" "m")
10422           (match_operand:SI 3 "memory_operand" "m")]))
10423    (clobber (match_scratch:SI 4 "=r"))]
10424   "TARGET_ARM && adjacent_mem_locations (operands[2], operands[3])"
10425   "*
10426   {
10427     rtx ldm[3];
10428     rtx arith[4];
10429     rtx base_reg;
10430     HOST_WIDE_INT val1 = 0, val2 = 0;
10432     if (REGNO (operands[0]) > REGNO (operands[4]))
10433       {
10434         ldm[1] = operands[4];
10435         ldm[2] = operands[0];
10436       }
10437     else
10438       {
10439         ldm[1] = operands[0];
10440         ldm[2] = operands[4];
10441       }
10443     base_reg = XEXP (operands[2], 0);
10445     if (!REG_P (base_reg))
10446       {
10447         val1 = INTVAL (XEXP (base_reg, 1));
10448         base_reg = XEXP (base_reg, 0);
10449       }
10451     if (!REG_P (XEXP (operands[3], 0)))
10452       val2 = INTVAL (XEXP (XEXP (operands[3], 0), 1));
10454     arith[0] = operands[0];
10455     arith[3] = operands[1];
10457     if (val1 < val2)
10458       {
10459         arith[1] = ldm[1];
10460         arith[2] = ldm[2];
10461       }
10462     else
10463       {
10464         arith[1] = ldm[2];
10465         arith[2] = ldm[1];
10466       }
10468     ldm[0] = base_reg;
10469     if (val1 !=0 && val2 != 0)
10470       {
10471         rtx ops[3];
10473         if (val1 == 4 || val2 == 4)
10474           /* Other val must be 8, since we know they are adjacent and neither
10475              is zero.  */
10476           output_asm_insn (\"ldmib%?\\t%0, {%1, %2}\", ldm);
10477         else if (const_ok_for_arm (val1) || const_ok_for_arm (-val1))
10478           {
10479             ldm[0] = ops[0] = operands[4];
10480             ops[1] = base_reg;
10481             ops[2] = GEN_INT (val1);
10482             output_add_immediate (ops);
10483             if (val1 < val2)
10484               output_asm_insn (\"ldmia%?\\t%0, {%1, %2}\", ldm);
10485             else
10486               output_asm_insn (\"ldmda%?\\t%0, {%1, %2}\", ldm);
10487           }
10488         else
10489           {
10490             /* Offset is out of range for a single add, so use two ldr.  */
10491             ops[0] = ldm[1];
10492             ops[1] = base_reg;
10493             ops[2] = GEN_INT (val1);
10494             output_asm_insn (\"ldr%?\\t%0, [%1, %2]\", ops);
10495             ops[0] = ldm[2];
10496             ops[2] = GEN_INT (val2);
10497             output_asm_insn (\"ldr%?\\t%0, [%1, %2]\", ops);
10498           }
10499       }
10500     else if (val1 != 0)
10501       {
10502         if (val1 < val2)
10503           output_asm_insn (\"ldmda%?\\t%0, {%1, %2}\", ldm);
10504         else
10505           output_asm_insn (\"ldmia%?\\t%0, {%1, %2}\", ldm);
10506       }
10507     else
10508       {
10509         if (val1 < val2)
10510           output_asm_insn (\"ldmia%?\\t%0, {%1, %2}\", ldm);
10511         else
10512           output_asm_insn (\"ldmda%?\\t%0, {%1, %2}\", ldm);
10513       }
10514     output_asm_insn (\"%I3%?\\t%0, %1, %2\", arith);
10515     return \"\";
10516   }"
10517   [(set_attr "length" "12")
10518    (set_attr "predicable" "yes")
10519    (set_attr "type" "load1")]
10522 ; This pattern is never tried by combine, so do it as a peephole
10524 (define_peephole2
10525   [(set (match_operand:SI 0 "arm_general_register_operand" "")
10526         (match_operand:SI 1 "arm_general_register_operand" ""))
10527    (set (reg:CC CC_REGNUM)
10528         (compare:CC (match_dup 1) (const_int 0)))]
10529   "TARGET_ARM"
10530   [(parallel [(set (reg:CC CC_REGNUM) (compare:CC (match_dup 1) (const_int 0)))
10531               (set (match_dup 0) (match_dup 1))])]
10532   ""
10535 (define_split
10536   [(set (match_operand:SI 0 "s_register_operand" "")
10537         (and:SI (ge:SI (match_operand:SI 1 "s_register_operand" "")
10538                        (const_int 0))
10539                 (neg:SI (match_operator:SI 2 "arm_comparison_operator"
10540                          [(match_operand:SI 3 "s_register_operand" "")
10541                           (match_operand:SI 4 "arm_rhs_operand" "")]))))
10542    (clobber (match_operand:SI 5 "s_register_operand" ""))]
10543   "TARGET_ARM"
10544   [(set (match_dup 5) (not:SI (ashiftrt:SI (match_dup 1) (const_int 31))))
10545    (set (match_dup 0) (and:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
10546                               (match_dup 5)))]
10547   ""
10550 ;; This split can be used because CC_Z mode implies that the following
10551 ;; branch will be an equality, or an unsigned inequality, so the sign
10552 ;; extension is not needed.
10554 (define_split
10555   [(set (reg:CC_Z CC_REGNUM)
10556         (compare:CC_Z
10557          (ashift:SI (subreg:SI (match_operand:QI 0 "memory_operand" "") 0)
10558                     (const_int 24))
10559          (match_operand 1 "const_int_operand" "")))
10560    (clobber (match_scratch:SI 2 ""))]
10561   "TARGET_ARM
10562    && ((UINTVAL (operands[1]))
10563        == ((UINTVAL (operands[1])) >> 24) << 24)"
10564   [(set (match_dup 2) (zero_extend:SI (match_dup 0)))
10565    (set (reg:CC CC_REGNUM) (compare:CC (match_dup 2) (match_dup 1)))]
10566   "
10567   operands[1] = GEN_INT (((unsigned long) INTVAL (operands[1])) >> 24);
10568   "
10570 ;; ??? Check the patterns above for Thumb-2 usefulness
10572 (define_expand "prologue"
10573   [(clobber (const_int 0))]
10574   "TARGET_EITHER"
10575   "if (TARGET_32BIT)
10576      arm_expand_prologue ();
10577    else
10578      thumb1_expand_prologue ();
10579   DONE;
10580   "
10583 (define_expand "epilogue"
10584   [(clobber (const_int 0))]
10585   "TARGET_EITHER"
10586   "
10587   if (crtl->calls_eh_return)
10588     emit_insn (gen_force_register_use (gen_rtx_REG (Pmode, 2)));
10589   if (TARGET_THUMB1)
10590    {
10591      thumb1_expand_epilogue ();
10592      emit_jump_insn (gen_rtx_UNSPEC_VOLATILE (VOIDmode,
10593                      gen_rtvec (1, ret_rtx), VUNSPEC_EPILOGUE));
10594    }
10595   else if (HAVE_return)
10596    {
10597      /* HAVE_return is testing for USE_RETURN_INSN (FALSE).  Hence,
10598         no need for explicit testing again.  */
10599      emit_jump_insn (gen_return ());
10600    }
10601   else if (TARGET_32BIT)
10602    {
10603     arm_expand_epilogue (true);
10604    }
10605   DONE;
10606   "
10609 ;; Note - although unspec_volatile's USE all hard registers,
10610 ;; USEs are ignored after relaod has completed.  Thus we need
10611 ;; to add an unspec of the link register to ensure that flow
10612 ;; does not think that it is unused by the sibcall branch that
10613 ;; will replace the standard function epilogue.
10614 (define_expand "sibcall_epilogue"
10615    [(parallel [(unspec:SI [(reg:SI LR_REGNUM)] UNSPEC_REGISTER_USE)
10616                (unspec_volatile [(return)] VUNSPEC_EPILOGUE)])]
10617    "TARGET_32BIT"
10618    "
10619    arm_expand_epilogue (false);
10620    DONE;
10621    "
10624 (define_expand "eh_epilogue"
10625   [(use (match_operand:SI 0 "register_operand" ""))
10626    (use (match_operand:SI 1 "register_operand" ""))
10627    (use (match_operand:SI 2 "register_operand" ""))]
10628   "TARGET_EITHER"
10629   "
10630   {
10631     cfun->machine->eh_epilogue_sp_ofs = operands[1];
10632     if (!REG_P (operands[2]) || REGNO (operands[2]) != 2)
10633       {
10634         rtx ra = gen_rtx_REG (Pmode, 2);
10636         emit_move_insn (ra, operands[2]);
10637         operands[2] = ra;
10638       }
10639     /* This is a hack -- we may have crystalized the function type too
10640        early.  */
10641     cfun->machine->func_type = 0;
10642   }"
10645 ;; This split is only used during output to reduce the number of patterns
10646 ;; that need assembler instructions adding to them.  We allowed the setting
10647 ;; of the conditions to be implicit during rtl generation so that
10648 ;; the conditional compare patterns would work.  However this conflicts to
10649 ;; some extent with the conditional data operations, so we have to split them
10650 ;; up again here.
10652 ;; ??? Need to audit these splitters for Thumb-2.  Why isn't normal
10653 ;; conditional execution sufficient?
10655 (define_split
10656   [(set (match_operand:SI 0 "s_register_operand" "")
10657         (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10658                           [(match_operand 2 "" "") (match_operand 3 "" "")])
10659                          (match_dup 0)
10660                          (match_operand 4 "" "")))
10661    (clobber (reg:CC CC_REGNUM))]
10662   "TARGET_ARM && reload_completed"
10663   [(set (match_dup 5) (match_dup 6))
10664    (cond_exec (match_dup 7)
10665               (set (match_dup 0) (match_dup 4)))]
10666   "
10667   {
10668     machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10669                                              operands[2], operands[3]);
10670     enum rtx_code rc = GET_CODE (operands[1]);
10672     operands[5] = gen_rtx_REG (mode, CC_REGNUM);
10673     operands[6] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10674     if (mode == CCFPmode || mode == CCFPEmode)
10675       rc = reverse_condition_maybe_unordered (rc);
10676     else
10677       rc = reverse_condition (rc);
10679     operands[7] = gen_rtx_fmt_ee (rc, VOIDmode, operands[5], const0_rtx);
10680   }"
10683 (define_split
10684   [(set (match_operand:SI 0 "s_register_operand" "")
10685         (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10686                           [(match_operand 2 "" "") (match_operand 3 "" "")])
10687                          (match_operand 4 "" "")
10688                          (match_dup 0)))
10689    (clobber (reg:CC CC_REGNUM))]
10690   "TARGET_ARM && reload_completed"
10691   [(set (match_dup 5) (match_dup 6))
10692    (cond_exec (match_op_dup 1 [(match_dup 5) (const_int 0)])
10693               (set (match_dup 0) (match_dup 4)))]
10694   "
10695   {
10696     machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10697                                              operands[2], operands[3]);
10699     operands[5] = gen_rtx_REG (mode, CC_REGNUM);
10700     operands[6] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10701   }"
10704 (define_split
10705   [(set (match_operand:SI 0 "s_register_operand" "")
10706         (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10707                           [(match_operand 2 "" "") (match_operand 3 "" "")])
10708                          (match_operand 4 "" "")
10709                          (match_operand 5 "" "")))
10710    (clobber (reg:CC CC_REGNUM))]
10711   "TARGET_ARM && reload_completed"
10712   [(set (match_dup 6) (match_dup 7))
10713    (cond_exec (match_op_dup 1 [(match_dup 6) (const_int 0)])
10714               (set (match_dup 0) (match_dup 4)))
10715    (cond_exec (match_dup 8)
10716               (set (match_dup 0) (match_dup 5)))]
10717   "
10718   {
10719     machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10720                                              operands[2], operands[3]);
10721     enum rtx_code rc = GET_CODE (operands[1]);
10723     operands[6] = gen_rtx_REG (mode, CC_REGNUM);
10724     operands[7] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10725     if (mode == CCFPmode || mode == CCFPEmode)
10726       rc = reverse_condition_maybe_unordered (rc);
10727     else
10728       rc = reverse_condition (rc);
10730     operands[8] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
10731   }"
10734 (define_split
10735   [(set (match_operand:SI 0 "s_register_operand" "")
10736         (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10737                           [(match_operand:SI 2 "s_register_operand" "")
10738                            (match_operand:SI 3 "arm_add_operand" "")])
10739                          (match_operand:SI 4 "arm_rhs_operand" "")
10740                          (not:SI
10741                           (match_operand:SI 5 "s_register_operand" ""))))
10742    (clobber (reg:CC CC_REGNUM))]
10743   "TARGET_ARM && reload_completed"
10744   [(set (match_dup 6) (match_dup 7))
10745    (cond_exec (match_op_dup 1 [(match_dup 6) (const_int 0)])
10746               (set (match_dup 0) (match_dup 4)))
10747    (cond_exec (match_dup 8)
10748               (set (match_dup 0) (not:SI (match_dup 5))))]
10749   "
10750   {
10751     machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10752                                              operands[2], operands[3]);
10753     enum rtx_code rc = GET_CODE (operands[1]);
10755     operands[6] = gen_rtx_REG (mode, CC_REGNUM);
10756     operands[7] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10757     if (mode == CCFPmode || mode == CCFPEmode)
10758       rc = reverse_condition_maybe_unordered (rc);
10759     else
10760       rc = reverse_condition (rc);
10762     operands[8] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
10763   }"
10766 (define_insn "*cond_move_not"
10767   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10768         (if_then_else:SI (match_operator 4 "arm_comparison_operator"
10769                           [(match_operand 3 "cc_register" "") (const_int 0)])
10770                          (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
10771                          (not:SI
10772                           (match_operand:SI 2 "s_register_operand" "r,r"))))]
10773   "TARGET_ARM"
10774   "@
10775    mvn%D4\\t%0, %2
10776    mov%d4\\t%0, %1\;mvn%D4\\t%0, %2"
10777   [(set_attr "conds" "use")
10778    (set_attr "type" "mvn_reg,multiple")
10779    (set_attr "length" "4,8")]
10782 ;; The next two patterns occur when an AND operation is followed by a
10783 ;; scc insn sequence 
10785 (define_insn "*sign_extract_onebit"
10786   [(set (match_operand:SI 0 "s_register_operand" "=r")
10787         (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
10788                          (const_int 1)
10789                          (match_operand:SI 2 "const_int_operand" "n")))
10790     (clobber (reg:CC CC_REGNUM))]
10791   "TARGET_ARM"
10792   "*
10793     operands[2] = GEN_INT (1 << INTVAL (operands[2]));
10794     output_asm_insn (\"ands\\t%0, %1, %2\", operands);
10795     return \"mvnne\\t%0, #0\";
10796   "
10797   [(set_attr "conds" "clob")
10798    (set_attr "length" "8")
10799    (set_attr "type" "multiple")]
10802 (define_insn "*not_signextract_onebit"
10803   [(set (match_operand:SI 0 "s_register_operand" "=r")
10804         (not:SI
10805          (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
10806                           (const_int 1)
10807                           (match_operand:SI 2 "const_int_operand" "n"))))
10808    (clobber (reg:CC CC_REGNUM))]
10809   "TARGET_ARM"
10810   "*
10811     operands[2] = GEN_INT (1 << INTVAL (operands[2]));
10812     output_asm_insn (\"tst\\t%1, %2\", operands);
10813     output_asm_insn (\"mvneq\\t%0, #0\", operands);
10814     return \"movne\\t%0, #0\";
10815   "
10816   [(set_attr "conds" "clob")
10817    (set_attr "length" "12")
10818    (set_attr "type" "multiple")]
10820 ;; ??? The above patterns need auditing for Thumb-2
10822 ;; Push multiple registers to the stack.  Registers are in parallel (use ...)
10823 ;; expressions.  For simplicity, the first register is also in the unspec
10824 ;; part.
10825 ;; To avoid the usage of GNU extension, the length attribute is computed
10826 ;; in a C function arm_attr_length_push_multi.
10827 (define_insn "*push_multi"
10828   [(match_parallel 2 "multi_register_push"
10829     [(set (match_operand:BLK 0 "push_mult_memory_operand" "")
10830           (unspec:BLK [(match_operand:SI 1 "s_register_operand" "")]
10831                       UNSPEC_PUSH_MULT))])]
10832   ""
10833   "*
10834   {
10835     int num_saves = XVECLEN (operands[2], 0);
10836      
10837     /* For the StrongARM at least it is faster to
10838        use STR to store only a single register.
10839        In Thumb mode always use push, and the assembler will pick
10840        something appropriate.  */
10841     if (num_saves == 1 && TARGET_ARM)
10842       output_asm_insn (\"str%?\\t%1, [%m0, #-4]!\", operands);
10843     else
10844       {
10845         int i;
10846         char pattern[100];
10848         if (TARGET_32BIT)
10849             strcpy (pattern, \"push%?\\t{%1\");
10850         else
10851             strcpy (pattern, \"push\\t{%1\");
10853         for (i = 1; i < num_saves; i++)
10854           {
10855             strcat (pattern, \", %|\");
10856             strcat (pattern,
10857                     reg_names[REGNO (XEXP (XVECEXP (operands[2], 0, i), 0))]);
10858           }
10860         strcat (pattern, \"}\");
10861         output_asm_insn (pattern, operands);
10862       }
10864     return \"\";
10865   }"
10866   [(set_attr "type" "store4")
10867    (set (attr "length")
10868         (symbol_ref "arm_attr_length_push_multi (operands[2], operands[1])"))]
10871 (define_insn "stack_tie"
10872   [(set (mem:BLK (scratch))
10873         (unspec:BLK [(match_operand:SI 0 "s_register_operand" "rk")
10874                      (match_operand:SI 1 "s_register_operand" "rk")]
10875                     UNSPEC_PRLG_STK))]
10876   ""
10877   ""
10878   [(set_attr "length" "0")
10879    (set_attr "type" "block")]
10882 ;; Pop (as used in epilogue RTL)
10884 (define_insn "*load_multiple_with_writeback"
10885   [(match_parallel 0 "load_multiple_operation"
10886     [(set (match_operand:SI 1 "s_register_operand" "+rk")
10887           (plus:SI (match_dup 1)
10888                    (match_operand:SI 2 "const_int_I_operand" "I")))
10889      (set (match_operand:SI 3 "s_register_operand" "=rk")
10890           (mem:SI (match_dup 1)))
10891         ])]
10892   "TARGET_32BIT && (reload_in_progress || reload_completed)"
10893   "*
10894   {
10895     arm_output_multireg_pop (operands, /*return_pc=*/false,
10896                                        /*cond=*/const_true_rtx,
10897                                        /*reverse=*/false,
10898                                        /*update=*/true);
10899     return \"\";
10900   }
10901   "
10902   [(set_attr "type" "load4")
10903    (set_attr "predicable" "yes")
10904    (set (attr "length")
10905         (symbol_ref "arm_attr_length_pop_multi (operands,
10906                                                 /*return_pc=*/false,
10907                                                 /*write_back_p=*/true)"))]
10910 ;; Pop with return (as used in epilogue RTL)
10912 ;; This instruction is generated when the registers are popped at the end of
10913 ;; epilogue.  Here, instead of popping the value into LR and then generating
10914 ;; jump to LR, value is popped into PC directly.  Hence, the pattern is combined
10915 ;;  with (return).
10916 (define_insn "*pop_multiple_with_writeback_and_return"
10917   [(match_parallel 0 "pop_multiple_return"
10918     [(return)
10919      (set (match_operand:SI 1 "s_register_operand" "+rk")
10920           (plus:SI (match_dup 1)
10921                    (match_operand:SI 2 "const_int_I_operand" "I")))
10922      (set (match_operand:SI 3 "s_register_operand" "=rk")
10923           (mem:SI (match_dup 1)))
10924         ])]
10925   "TARGET_32BIT && (reload_in_progress || reload_completed)"
10926   "*
10927   {
10928     arm_output_multireg_pop (operands, /*return_pc=*/true,
10929                                        /*cond=*/const_true_rtx,
10930                                        /*reverse=*/false,
10931                                        /*update=*/true);
10932     return \"\";
10933   }
10934   "
10935   [(set_attr "type" "load4")
10936    (set_attr "predicable" "yes")
10937    (set (attr "length")
10938         (symbol_ref "arm_attr_length_pop_multi (operands, /*return_pc=*/true,
10939                                                 /*write_back_p=*/true)"))]
10942 (define_insn "*pop_multiple_with_return"
10943   [(match_parallel 0 "pop_multiple_return"
10944     [(return)
10945      (set (match_operand:SI 2 "s_register_operand" "=rk")
10946           (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
10947         ])]
10948   "TARGET_32BIT && (reload_in_progress || reload_completed)"
10949   "*
10950   {
10951     arm_output_multireg_pop (operands, /*return_pc=*/true,
10952                                        /*cond=*/const_true_rtx,
10953                                        /*reverse=*/false,
10954                                        /*update=*/false);
10955     return \"\";
10956   }
10957   "
10958   [(set_attr "type" "load4")
10959    (set_attr "predicable" "yes")
10960    (set (attr "length")
10961         (symbol_ref "arm_attr_length_pop_multi (operands, /*return_pc=*/true,
10962                                                 /*write_back_p=*/false)"))]
10965 ;; Load into PC and return
10966 (define_insn "*ldr_with_return"
10967   [(return)
10968    (set (reg:SI PC_REGNUM)
10969         (mem:SI (post_inc:SI (match_operand:SI 0 "s_register_operand" "+rk"))))]
10970   "TARGET_32BIT && (reload_in_progress || reload_completed)"
10971   "ldr%?\t%|pc, [%0], #4"
10972   [(set_attr "type" "load1")
10973    (set_attr "predicable" "yes")]
10975 ;; Pop for floating point registers (as used in epilogue RTL)
10976 (define_insn "*vfp_pop_multiple_with_writeback"
10977   [(match_parallel 0 "pop_multiple_fp"
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:DF 3 "vfp_hard_register_operand" "")
10982           (mem:DF (match_dup 1)))])]
10983   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
10984   "*
10985   {
10986     int num_regs = XVECLEN (operands[0], 0);
10987     char pattern[100];
10988     rtx op_list[2];
10989     strcpy (pattern, \"vldm\\t\");
10990     strcat (pattern, reg_names[REGNO (SET_DEST (XVECEXP (operands[0], 0, 0)))]);
10991     strcat (pattern, \"!, {\");
10992     op_list[0] = XEXP (XVECEXP (operands[0], 0, 1), 0);
10993     strcat (pattern, \"%P0\");
10994     if ((num_regs - 1) > 1)
10995       {
10996         strcat (pattern, \"-%P1\");
10997         op_list [1] = XEXP (XVECEXP (operands[0], 0, num_regs - 1), 0);
10998       }
11000     strcat (pattern, \"}\");
11001     output_asm_insn (pattern, op_list);
11002     return \"\";
11003   }
11004   "
11005   [(set_attr "type" "load4")
11006    (set_attr "conds" "unconditional")
11007    (set_attr "predicable" "no")]
11010 ;; Special patterns for dealing with the constant pool
11012 (define_insn "align_4"
11013   [(unspec_volatile [(const_int 0)] VUNSPEC_ALIGN)]
11014   "TARGET_EITHER"
11015   "*
11016   assemble_align (32);
11017   return \"\";
11018   "
11019   [(set_attr "type" "no_insn")]
11022 (define_insn "align_8"
11023   [(unspec_volatile [(const_int 0)] VUNSPEC_ALIGN8)]
11024   "TARGET_EITHER"
11025   "*
11026   assemble_align (64);
11027   return \"\";
11028   "
11029   [(set_attr "type" "no_insn")]
11032 (define_insn "consttable_end"
11033   [(unspec_volatile [(const_int 0)] VUNSPEC_POOL_END)]
11034   "TARGET_EITHER"
11035   "*
11036   making_const_table = FALSE;
11037   return \"\";
11038   "
11039   [(set_attr "type" "no_insn")]
11042 (define_insn "consttable_1"
11043   [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_1)]
11044   "TARGET_EITHER"
11045   "*
11046   making_const_table = TRUE;
11047   assemble_integer (operands[0], 1, BITS_PER_WORD, 1);
11048   assemble_zeros (3);
11049   return \"\";
11050   "
11051   [(set_attr "length" "4")
11052    (set_attr "type" "no_insn")]
11055 (define_insn "consttable_2"
11056   [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_2)]
11057   "TARGET_EITHER"
11058   "*
11059   {
11060     rtx x = operands[0];
11061     making_const_table = TRUE;
11062     switch (GET_MODE_CLASS (GET_MODE (x)))
11063       {
11064       case MODE_FLOAT:
11065         arm_emit_fp16_const (x);
11066         break;
11067       default:
11068         assemble_integer (operands[0], 2, BITS_PER_WORD, 1);
11069         assemble_zeros (2);
11070         break;
11071       }
11072     return \"\";
11073   }"
11074   [(set_attr "length" "4")
11075    (set_attr "type" "no_insn")]
11078 (define_insn "consttable_4"
11079   [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_4)]
11080   "TARGET_EITHER"
11081   "*
11082   {
11083     rtx x = operands[0];
11084     making_const_table = TRUE;
11085     switch (GET_MODE_CLASS (GET_MODE (x)))
11086       {
11087       case MODE_FLOAT:
11088         assemble_real (*CONST_DOUBLE_REAL_VALUE (x), GET_MODE (x),
11089                        BITS_PER_WORD);
11090         break;
11091       default:
11092         /* XXX: Sometimes gcc does something really dumb and ends up with
11093            a HIGH in a constant pool entry, usually because it's trying to
11094            load into a VFP register.  We know this will always be used in
11095            combination with a LO_SUM which ignores the high bits, so just
11096            strip off the HIGH.  */
11097         if (GET_CODE (x) == HIGH)
11098           x = XEXP (x, 0);
11099         assemble_integer (x, 4, BITS_PER_WORD, 1);
11100         mark_symbol_refs_as_used (x);
11101         break;
11102       }
11103     return \"\";
11104   }"
11105   [(set_attr "length" "4")
11106    (set_attr "type" "no_insn")]
11109 (define_insn "consttable_8"
11110   [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_8)]
11111   "TARGET_EITHER"
11112   "*
11113   {
11114     making_const_table = TRUE;
11115     switch (GET_MODE_CLASS (GET_MODE (operands[0])))
11116       {
11117       case MODE_FLOAT:
11118         assemble_real (*CONST_DOUBLE_REAL_VALUE (operands[0]),
11119                        GET_MODE (operands[0]), BITS_PER_WORD);
11120         break;
11121       default:
11122         assemble_integer (operands[0], 8, BITS_PER_WORD, 1);
11123         break;
11124       }
11125     return \"\";
11126   }"
11127   [(set_attr "length" "8")
11128    (set_attr "type" "no_insn")]
11131 (define_insn "consttable_16"
11132   [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_16)]
11133   "TARGET_EITHER"
11134   "*
11135   {
11136     making_const_table = TRUE;
11137     switch (GET_MODE_CLASS (GET_MODE (operands[0])))
11138       {
11139       case MODE_FLOAT:
11140         assemble_real (*CONST_DOUBLE_REAL_VALUE (operands[0]),
11141                        GET_MODE (operands[0]), BITS_PER_WORD);
11142         break;
11143       default:
11144         assemble_integer (operands[0], 16, BITS_PER_WORD, 1);
11145         break;
11146       }
11147     return \"\";
11148   }"
11149   [(set_attr "length" "16")
11150    (set_attr "type" "no_insn")]
11153 ;; V5 Instructions,
11155 (define_insn "clzsi2"
11156   [(set (match_operand:SI 0 "s_register_operand" "=r")
11157         (clz:SI (match_operand:SI 1 "s_register_operand" "r")))]
11158   "TARGET_32BIT && arm_arch5"
11159   "clz%?\\t%0, %1"
11160   [(set_attr "predicable" "yes")
11161    (set_attr "predicable_short_it" "no")
11162    (set_attr "type" "clz")])
11164 (define_insn "rbitsi2"
11165   [(set (match_operand:SI 0 "s_register_operand" "=r")
11166         (unspec:SI [(match_operand:SI 1 "s_register_operand" "r")] UNSPEC_RBIT))]
11167   "TARGET_32BIT && arm_arch_thumb2"
11168   "rbit%?\\t%0, %1"
11169   [(set_attr "predicable" "yes")
11170    (set_attr "predicable_short_it" "no")
11171    (set_attr "type" "clz")])
11173 ;; Keep this as a CTZ expression until after reload and then split
11174 ;; into RBIT + CLZ.  Since RBIT is represented as an UNSPEC it is unlikely
11175 ;; to fold with any other expression.
11177 (define_insn_and_split "ctzsi2"
11178  [(set (match_operand:SI           0 "s_register_operand" "=r")
11179        (ctz:SI (match_operand:SI  1 "s_register_operand" "r")))]
11180   "TARGET_32BIT && arm_arch_thumb2"
11181   "#"
11182   "&& reload_completed"
11183   [(const_int 0)]
11184   "
11185   emit_insn (gen_rbitsi2 (operands[0], operands[1]));
11186   emit_insn (gen_clzsi2 (operands[0], operands[0]));
11187   DONE;
11190 ;; V5E instructions.
11192 (define_insn "prefetch"
11193   [(prefetch (match_operand:SI 0 "address_operand" "p")
11194              (match_operand:SI 1 "" "")
11195              (match_operand:SI 2 "" ""))]
11196   "TARGET_32BIT && arm_arch5e"
11197   "pld\\t%a0"
11198   [(set_attr "type" "load1")]
11201 ;; General predication pattern
11203 (define_cond_exec
11204   [(match_operator 0 "arm_comparison_operator"
11205     [(match_operand 1 "cc_register" "")
11206      (const_int 0)])]
11207   "TARGET_32BIT
11208    && (!TARGET_NO_VOLATILE_CE || !volatile_refs_p (PATTERN (insn)))"
11209   ""
11210 [(set_attr "predicated" "yes")]
11213 (define_insn "force_register_use"
11214   [(unspec:SI [(match_operand:SI 0 "register_operand" "")] UNSPEC_REGISTER_USE)]
11215   ""
11216   "%@ %0 needed"
11217   [(set_attr "length" "0")
11218    (set_attr "type" "no_insn")]
11222 ;; Patterns for exception handling
11224 (define_expand "eh_return"
11225   [(use (match_operand 0 "general_operand" ""))]
11226   "TARGET_EITHER"
11227   "
11228   {
11229     if (TARGET_32BIT)
11230       emit_insn (gen_arm_eh_return (operands[0]));
11231     else
11232       emit_insn (gen_thumb_eh_return (operands[0]));
11233     DONE;
11234   }"
11236                                    
11237 ;; We can't expand this before we know where the link register is stored.
11238 (define_insn_and_split "arm_eh_return"
11239   [(unspec_volatile [(match_operand:SI 0 "s_register_operand" "r")]
11240                     VUNSPEC_EH_RETURN)
11241    (clobber (match_scratch:SI 1 "=&r"))]
11242   "TARGET_ARM"
11243   "#"
11244   "&& reload_completed"
11245   [(const_int 0)]
11246   "
11247   {
11248     arm_set_return_address (operands[0], operands[1]);
11249     DONE;
11250   }"
11254 ;; TLS support
11256 (define_insn "load_tp_hard"
11257   [(set (match_operand:SI 0 "register_operand" "=r")
11258         (unspec:SI [(const_int 0)] UNSPEC_TLS))]
11259   "TARGET_HARD_TP"
11260   "mrc%?\\tp15, 0, %0, c13, c0, 3\\t@ load_tp_hard"
11261   [(set_attr "predicable" "yes")
11262    (set_attr "type" "mrs")]
11265 ;; Doesn't clobber R1-R3.  Must use r0 for the first operand.
11266 (define_insn "load_tp_soft"
11267   [(set (reg:SI 0) (unspec:SI [(const_int 0)] UNSPEC_TLS))
11268    (clobber (reg:SI LR_REGNUM))
11269    (clobber (reg:SI IP_REGNUM))
11270    (clobber (reg:CC CC_REGNUM))]
11271   "TARGET_SOFT_TP"
11272   "bl\\t__aeabi_read_tp\\t@ load_tp_soft"
11273   [(set_attr "conds" "clob")
11274    (set_attr "type" "branch")]
11277 ;; tls descriptor call
11278 (define_insn "tlscall"
11279   [(set (reg:SI R0_REGNUM)
11280         (unspec:SI [(reg:SI R0_REGNUM)
11281                     (match_operand:SI 0 "" "X")
11282                     (match_operand 1 "" "")] UNSPEC_TLS))
11283    (clobber (reg:SI R1_REGNUM))
11284    (clobber (reg:SI LR_REGNUM))
11285    (clobber (reg:SI CC_REGNUM))]
11286   "TARGET_GNU2_TLS"
11287   {
11288     targetm.asm_out.internal_label (asm_out_file, "LPIC",
11289                                     INTVAL (operands[1]));
11290     return "bl\\t%c0(tlscall)";
11291   }
11292   [(set_attr "conds" "clob")
11293    (set_attr "length" "4")
11294    (set_attr "type" "branch")]
11297 ;; For thread pointer builtin
11298 (define_expand "get_thread_pointersi"
11299   [(match_operand:SI 0 "s_register_operand" "=r")]
11300  ""
11303    arm_load_tp (operands[0]);
11304    DONE;
11305  }")
11309 ;; We only care about the lower 16 bits of the constant 
11310 ;; being inserted into the upper 16 bits of the register.
11311 (define_insn "*arm_movtas_ze" 
11312   [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r,r")
11313                    (const_int 16)
11314                    (const_int 16))
11315         (match_operand:SI 1 "const_int_operand" ""))]
11316   "TARGET_HAVE_MOVT"
11317   "@
11318    movt%?\t%0, %L1
11319    movt\t%0, %L1"
11320  [(set_attr "arch" "32,v8mb")
11321   (set_attr "predicable" "yes")
11322   (set_attr "predicable_short_it" "no")
11323   (set_attr "length" "4")
11324   (set_attr "type" "alu_sreg")]
11327 (define_insn "*arm_rev"
11328   [(set (match_operand:SI 0 "s_register_operand" "=l,l,r")
11329         (bswap:SI (match_operand:SI 1 "s_register_operand" "l,l,r")))]
11330   "arm_arch6"
11331   "@
11332    rev\t%0, %1
11333    rev%?\t%0, %1
11334    rev%?\t%0, %1"
11335   [(set_attr "arch" "t1,t2,32")
11336    (set_attr "length" "2,2,4")
11337    (set_attr "predicable" "no,yes,yes")
11338    (set_attr "predicable_short_it" "no")
11339    (set_attr "type" "rev")]
11342 (define_expand "arm_legacy_rev"
11343   [(set (match_operand:SI 2 "s_register_operand" "")
11344         (xor:SI (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
11345                              (const_int 16))
11346                 (match_dup 1)))
11347    (set (match_dup 2)
11348         (lshiftrt:SI (match_dup 2)
11349                      (const_int 8)))
11350    (set (match_operand:SI 3 "s_register_operand" "")
11351         (rotatert:SI (match_dup 1)
11352                      (const_int 8)))
11353    (set (match_dup 2)
11354         (and:SI (match_dup 2)
11355                 (const_int -65281)))
11356    (set (match_operand:SI 0 "s_register_operand" "")
11357         (xor:SI (match_dup 3)
11358                 (match_dup 2)))]
11359   "TARGET_32BIT"
11360   ""
11363 ;; Reuse temporaries to keep register pressure down.
11364 (define_expand "thumb_legacy_rev"
11365   [(set (match_operand:SI 2 "s_register_operand" "")
11366      (ashift:SI (match_operand:SI 1 "s_register_operand" "")
11367                 (const_int 24)))
11368    (set (match_operand:SI 3 "s_register_operand" "")
11369      (lshiftrt:SI (match_dup 1)
11370                   (const_int 24)))
11371    (set (match_dup 3)
11372      (ior:SI (match_dup 3)
11373              (match_dup 2)))
11374    (set (match_operand:SI 4 "s_register_operand" "")
11375      (const_int 16))
11376    (set (match_operand:SI 5 "s_register_operand" "")
11377      (rotatert:SI (match_dup 1)
11378                   (match_dup 4)))
11379    (set (match_dup 2)
11380      (ashift:SI (match_dup 5)
11381                 (const_int 24)))
11382    (set (match_dup 5)
11383      (lshiftrt:SI (match_dup 5)
11384                   (const_int 24)))
11385    (set (match_dup 5)
11386      (ior:SI (match_dup 5)
11387              (match_dup 2)))
11388    (set (match_dup 5)
11389      (rotatert:SI (match_dup 5)
11390                   (match_dup 4)))
11391    (set (match_operand:SI 0 "s_register_operand" "")
11392      (ior:SI (match_dup 5)
11393              (match_dup 3)))]
11394   "TARGET_THUMB"
11395   ""
11398 ;; ARM-specific expansion of signed mod by power of 2
11399 ;; using conditional negate.
11400 ;; For r0 % n where n is a power of 2 produce:
11401 ;; rsbs    r1, r0, #0
11402 ;; and     r0, r0, #(n - 1)
11403 ;; and     r1, r1, #(n - 1)
11404 ;; rsbpl   r0, r1, #0
11406 (define_expand "modsi3"
11407   [(match_operand:SI 0 "register_operand" "")
11408    (match_operand:SI 1 "register_operand" "")
11409    (match_operand:SI 2 "const_int_operand" "")]
11410   "TARGET_32BIT"
11411   {
11412     HOST_WIDE_INT val = INTVAL (operands[2]);
11414     if (val <= 0
11415        || exact_log2 (val) <= 0)
11416       FAIL;
11418     rtx mask = GEN_INT (val - 1);
11420     /* In the special case of x0 % 2 we can do the even shorter:
11421         cmp     r0, #0
11422         and     r0, r0, #1
11423         rsblt   r0, r0, #0.  */
11425     if (val == 2)
11426       {
11427         rtx cc_reg = arm_gen_compare_reg (LT,
11428                                           operands[1], const0_rtx, NULL_RTX);
11429         rtx cond = gen_rtx_LT (SImode, cc_reg, const0_rtx);
11430         rtx masked = gen_reg_rtx (SImode);
11432         emit_insn (gen_andsi3 (masked, operands[1], mask));
11433         emit_move_insn (operands[0],
11434                         gen_rtx_IF_THEN_ELSE (SImode, cond,
11435                                               gen_rtx_NEG (SImode,
11436                                                            masked),
11437                                               masked));
11438         DONE;
11439       }
11441     rtx neg_op = gen_reg_rtx (SImode);
11442     rtx_insn *insn = emit_insn (gen_subsi3_compare0 (neg_op, const0_rtx,
11443                                                       operands[1]));
11445     /* Extract the condition register and mode.  */
11446     rtx cmp = XVECEXP (PATTERN (insn), 0, 0);
11447     rtx cc_reg = SET_DEST (cmp);
11448     rtx cond = gen_rtx_GE (SImode, cc_reg, const0_rtx);
11450     emit_insn (gen_andsi3 (operands[0], operands[1], mask));
11452     rtx masked_neg = gen_reg_rtx (SImode);
11453     emit_insn (gen_andsi3 (masked_neg, neg_op, mask));
11455     /* We want a conditional negate here, but emitting COND_EXEC rtxes
11456        during expand does not always work.  Do an IF_THEN_ELSE instead.  */
11457     emit_move_insn (operands[0],
11458                     gen_rtx_IF_THEN_ELSE (SImode, cond,
11459                                           gen_rtx_NEG (SImode, masked_neg),
11460                                           operands[0]));
11463     DONE;
11464   }
11467 (define_expand "bswapsi2"
11468   [(set (match_operand:SI 0 "s_register_operand" "=r")
11469         (bswap:SI (match_operand:SI 1 "s_register_operand" "r")))]
11470 "TARGET_EITHER && (arm_arch6 || !optimize_size)"
11472     if (!arm_arch6)
11473       {
11474         rtx op2 = gen_reg_rtx (SImode);
11475         rtx op3 = gen_reg_rtx (SImode);
11477         if (TARGET_THUMB)
11478           {
11479             rtx op4 = gen_reg_rtx (SImode);
11480             rtx op5 = gen_reg_rtx (SImode);
11482             emit_insn (gen_thumb_legacy_rev (operands[0], operands[1],
11483                                              op2, op3, op4, op5));
11484           }
11485         else
11486           {
11487             emit_insn (gen_arm_legacy_rev (operands[0], operands[1],
11488                                            op2, op3));
11489           }
11491         DONE;
11492       }
11493   "
11496 ;; bswap16 patterns: use revsh and rev16 instructions for the signed
11497 ;; and unsigned variants, respectively. For rev16, expose
11498 ;; byte-swapping in the lower 16 bits only.
11499 (define_insn "*arm_revsh"
11500   [(set (match_operand:SI 0 "s_register_operand" "=l,l,r")
11501         (sign_extend:SI (bswap:HI (match_operand:HI 1 "s_register_operand" "l,l,r"))))]
11502   "arm_arch6"
11503   "@
11504   revsh\t%0, %1
11505   revsh%?\t%0, %1
11506   revsh%?\t%0, %1"
11507   [(set_attr "arch" "t1,t2,32")
11508    (set_attr "length" "2,2,4")
11509    (set_attr "type" "rev")]
11512 (define_insn "*arm_rev16"
11513   [(set (match_operand:HI 0 "s_register_operand" "=l,l,r")
11514         (bswap:HI (match_operand:HI 1 "s_register_operand" "l,l,r")))]
11515   "arm_arch6"
11516   "@
11517    rev16\t%0, %1
11518    rev16%?\t%0, %1
11519    rev16%?\t%0, %1"
11520   [(set_attr "arch" "t1,t2,32")
11521    (set_attr "length" "2,2,4")
11522    (set_attr "type" "rev")]
11525 ;; There are no canonicalisation rules for the position of the lshiftrt, ashift
11526 ;; operations within an IOR/AND RTX, therefore we have two patterns matching
11527 ;; each valid permutation.
11529 (define_insn "arm_rev16si2"
11530   [(set (match_operand:SI 0 "register_operand" "=l,l,r")
11531         (ior:SI (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "l,l,r")
11532                                    (const_int 8))
11533                         (match_operand:SI 3 "const_int_operand" "n,n,n"))
11534                 (and:SI (lshiftrt:SI (match_dup 1)
11535                                      (const_int 8))
11536                         (match_operand:SI 2 "const_int_operand" "n,n,n"))))]
11537   "arm_arch6
11538    && aarch_rev16_shleft_mask_imm_p (operands[3], SImode)
11539    && aarch_rev16_shright_mask_imm_p (operands[2], SImode)"
11540   "rev16\\t%0, %1"
11541   [(set_attr "arch" "t1,t2,32")
11542    (set_attr "length" "2,2,4")
11543    (set_attr "type" "rev")]
11546 (define_insn "arm_rev16si2_alt"
11547   [(set (match_operand:SI 0 "register_operand" "=l,l,r")
11548         (ior:SI (and:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "l,l,r")
11549                                      (const_int 8))
11550                         (match_operand:SI 2 "const_int_operand" "n,n,n"))
11551                 (and:SI (ashift:SI (match_dup 1)
11552                                    (const_int 8))
11553                         (match_operand:SI 3 "const_int_operand" "n,n,n"))))]
11554   "arm_arch6
11555    && aarch_rev16_shleft_mask_imm_p (operands[3], SImode)
11556    && aarch_rev16_shright_mask_imm_p (operands[2], SImode)"
11557   "rev16\\t%0, %1"
11558   [(set_attr "arch" "t1,t2,32")
11559    (set_attr "length" "2,2,4")
11560    (set_attr "type" "rev")]
11563 (define_expand "bswaphi2"
11564   [(set (match_operand:HI 0 "s_register_operand" "=r")
11565         (bswap:HI (match_operand:HI 1 "s_register_operand" "r")))]
11566 "arm_arch6"
11570 ;; Patterns for LDRD/STRD in Thumb2 mode
11572 (define_insn "*thumb2_ldrd"
11573   [(set (match_operand:SI 0 "s_register_operand" "=r")
11574         (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "rk")
11575                          (match_operand:SI 2 "ldrd_strd_offset_operand" "Do"))))
11576    (set (match_operand:SI 3 "s_register_operand" "=r")
11577         (mem:SI (plus:SI (match_dup 1)
11578                          (match_operand:SI 4 "const_int_operand" ""))))]
11579   "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11580      && current_tune->prefer_ldrd_strd
11581      && ((INTVAL (operands[2]) + 4) == INTVAL (operands[4]))
11582      && (operands_ok_ldrd_strd (operands[0], operands[3],
11583                                   operands[1], INTVAL (operands[2]),
11584                                   false, true))"
11585   "ldrd%?\t%0, %3, [%1, %2]"
11586   [(set_attr "type" "load2")
11587    (set_attr "predicable" "yes")
11588    (set_attr "predicable_short_it" "no")])
11590 (define_insn "*thumb2_ldrd_base"
11591   [(set (match_operand:SI 0 "s_register_operand" "=r")
11592         (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
11593    (set (match_operand:SI 2 "s_register_operand" "=r")
11594         (mem:SI (plus:SI (match_dup 1)
11595                          (const_int 4))))]
11596   "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11597      && current_tune->prefer_ldrd_strd
11598      && (operands_ok_ldrd_strd (operands[0], operands[2],
11599                                   operands[1], 0, false, true))"
11600   "ldrd%?\t%0, %2, [%1]"
11601   [(set_attr "type" "load2")
11602    (set_attr "predicable" "yes")
11603    (set_attr "predicable_short_it" "no")])
11605 (define_insn "*thumb2_ldrd_base_neg"
11606   [(set (match_operand:SI 0 "s_register_operand" "=r")
11607         (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "rk")
11608                          (const_int -4))))
11609    (set (match_operand:SI 2 "s_register_operand" "=r")
11610         (mem:SI (match_dup 1)))]
11611   "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11612      && current_tune->prefer_ldrd_strd
11613      && (operands_ok_ldrd_strd (operands[0], operands[2],
11614                                   operands[1], -4, false, true))"
11615   "ldrd%?\t%0, %2, [%1, #-4]"
11616   [(set_attr "type" "load2")
11617    (set_attr "predicable" "yes")
11618    (set_attr "predicable_short_it" "no")])
11620 (define_insn "*thumb2_strd"
11621   [(set (mem:SI (plus:SI (match_operand:SI 0 "s_register_operand" "rk")
11622                          (match_operand:SI 1 "ldrd_strd_offset_operand" "Do")))
11623         (match_operand:SI 2 "s_register_operand" "r"))
11624    (set (mem:SI (plus:SI (match_dup 0)
11625                          (match_operand:SI 3 "const_int_operand" "")))
11626         (match_operand:SI 4 "s_register_operand" "r"))]
11627   "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11628      && current_tune->prefer_ldrd_strd
11629      && ((INTVAL (operands[1]) + 4) == INTVAL (operands[3]))
11630      && (operands_ok_ldrd_strd (operands[2], operands[4],
11631                                   operands[0], INTVAL (operands[1]),
11632                                   false, false))"
11633   "strd%?\t%2, %4, [%0, %1]"
11634   [(set_attr "type" "store2")
11635    (set_attr "predicable" "yes")
11636    (set_attr "predicable_short_it" "no")])
11638 (define_insn "*thumb2_strd_base"
11639   [(set (mem:SI (match_operand:SI 0 "s_register_operand" "rk"))
11640         (match_operand:SI 1 "s_register_operand" "r"))
11641    (set (mem:SI (plus:SI (match_dup 0)
11642                          (const_int 4)))
11643         (match_operand:SI 2 "s_register_operand" "r"))]
11644   "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11645      && current_tune->prefer_ldrd_strd
11646      && (operands_ok_ldrd_strd (operands[1], operands[2],
11647                                   operands[0], 0, false, false))"
11648   "strd%?\t%1, %2, [%0]"
11649   [(set_attr "type" "store2")
11650    (set_attr "predicable" "yes")
11651    (set_attr "predicable_short_it" "no")])
11653 (define_insn "*thumb2_strd_base_neg"
11654   [(set (mem:SI (plus:SI (match_operand:SI 0 "s_register_operand" "rk")
11655                          (const_int -4)))
11656         (match_operand:SI 1 "s_register_operand" "r"))
11657    (set (mem:SI (match_dup 0))
11658         (match_operand:SI 2 "s_register_operand" "r"))]
11659   "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11660      && current_tune->prefer_ldrd_strd
11661      && (operands_ok_ldrd_strd (operands[1], operands[2],
11662                                   operands[0], -4, false, false))"
11663   "strd%?\t%1, %2, [%0, #-4]"
11664   [(set_attr "type" "store2")
11665    (set_attr "predicable" "yes")
11666    (set_attr "predicable_short_it" "no")])
11668 ;; ARMv8 CRC32 instructions.
11669 (define_insn "<crc_variant>"
11670   [(set (match_operand:SI 0 "s_register_operand" "=r")
11671         (unspec:SI [(match_operand:SI 1 "s_register_operand" "r")
11672                     (match_operand:<crc_mode> 2 "s_register_operand" "r")]
11673          CRC))]
11674   "TARGET_CRC32"
11675   "<crc_variant>\\t%0, %1, %2"
11676   [(set_attr "type" "crc")
11677    (set_attr "conds" "unconditional")]
11680 ;; Load the load/store double peephole optimizations.
11681 (include "ldrdstrd.md")
11683 ;; Load the load/store multiple patterns
11684 (include "ldmstm.md")
11686 ;; Patterns in ldmstm.md don't cover more than 4 registers. This pattern covers
11687 ;; large lists without explicit writeback generated for APCS_FRAME epilogue.
11688 (define_insn "*load_multiple"
11689   [(match_parallel 0 "load_multiple_operation"
11690     [(set (match_operand:SI 2 "s_register_operand" "=rk")
11691           (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
11692         ])]
11693   "TARGET_32BIT"
11694   "*
11695   {
11696     arm_output_multireg_pop (operands, /*return_pc=*/false,
11697                                        /*cond=*/const_true_rtx,
11698                                        /*reverse=*/false,
11699                                        /*update=*/false);
11700     return \"\";
11701   }
11702   "
11703   [(set_attr "predicable" "yes")]
11706 (define_expand "copysignsf3"
11707   [(match_operand:SF 0 "register_operand")
11708    (match_operand:SF 1 "register_operand")
11709    (match_operand:SF 2 "register_operand")]
11710   "TARGET_SOFT_FLOAT && arm_arch_thumb2"
11711   "{
11712      emit_move_insn (operands[0], operands[2]);
11713      emit_insn (gen_insv_t2 (simplify_gen_subreg (SImode, operands[0], SFmode, 0),
11714                 GEN_INT (31), GEN_INT (0),
11715                 simplify_gen_subreg (SImode, operands[1], SFmode, 0)));
11716      DONE;
11717   }"
11720 (define_expand "copysigndf3"
11721   [(match_operand:DF 0 "register_operand")
11722    (match_operand:DF 1 "register_operand")
11723    (match_operand:DF 2 "register_operand")]
11724   "TARGET_SOFT_FLOAT && arm_arch_thumb2"
11725   "{
11726      rtx op0_low = gen_lowpart (SImode, operands[0]);
11727      rtx op0_high = gen_highpart (SImode, operands[0]);
11728      rtx op1_low = gen_lowpart (SImode, operands[1]);
11729      rtx op1_high = gen_highpart (SImode, operands[1]);
11730      rtx op2_high = gen_highpart (SImode, operands[2]);
11732      rtx scratch1 = gen_reg_rtx (SImode);
11733      rtx scratch2 = gen_reg_rtx (SImode);
11734      emit_move_insn (scratch1, op2_high);
11735      emit_move_insn (scratch2, op1_high);
11737      emit_insn(gen_rtx_SET(scratch1,
11738                            gen_rtx_LSHIFTRT (SImode, op2_high, GEN_INT(31))));
11739      emit_insn(gen_insv_t2(scratch2, GEN_INT(1), GEN_INT(31), scratch1));
11740      emit_move_insn (op0_low, op1_low);
11741      emit_move_insn (op0_high, scratch2);
11743      DONE;
11744   }"
11747 ;; movmisalign patterns for HImode and SImode.
11748 (define_expand "movmisalign<mode>"
11749   [(match_operand:HSI 0 "general_operand")
11750    (match_operand:HSI 1 "general_operand")]
11751   "unaligned_access"
11753   /* This pattern is not permitted to fail during expansion: if both arguments
11754      are non-registers (e.g. memory := constant), force operand 1 into a
11755      register.  */
11756   rtx (* gen_unaligned_load)(rtx, rtx);
11757   rtx tmp_dest = operands[0];
11758   if (!s_register_operand (operands[0], <MODE>mode)
11759       && !s_register_operand (operands[1], <MODE>mode))
11760     operands[1] = force_reg (<MODE>mode, operands[1]);
11762   if (<MODE>mode == HImode)
11763    {
11764     gen_unaligned_load = gen_unaligned_loadhiu;
11765     tmp_dest = gen_reg_rtx (SImode);
11766    }
11767   else
11768     gen_unaligned_load = gen_unaligned_loadsi;
11770   if (MEM_P (operands[1]))
11771    {
11772     emit_insn (gen_unaligned_load (tmp_dest, operands[1]));
11773     if (<MODE>mode == HImode)
11774       emit_move_insn (operands[0], gen_lowpart (HImode, tmp_dest));
11775    }
11776   else
11777     emit_insn (gen_unaligned_store<mode> (operands[0], operands[1]));
11779   DONE;
11782 ;; Vector bits common to IWMMXT and Neon
11783 (include "vec-common.md")
11784 ;; Load the Intel Wireless Multimedia Extension patterns
11785 (include "iwmmxt.md")
11786 ;; Load the VFP co-processor patterns
11787 (include "vfp.md")
11788 ;; Thumb-1 patterns
11789 (include "thumb1.md")
11790 ;; Thumb-2 patterns
11791 (include "thumb2.md")
11792 ;; Neon patterns
11793 (include "neon.md")
11794 ;; Crypto patterns
11795 (include "crypto.md")
11796 ;; Synchronization Primitives
11797 (include "sync.md")
11798 ;; Fixed-point patterns
11799 (include "arm-fixed.md")