Turn SLOW_UNALIGNED_ACCESS into a target hook
[official-gcc.git] / gcc / config / arm / arm.md
blobdf73e73b3a9ff7e89d249348ae1029f5038f7f1d
1 ;;- Machine description for ARM for GNU compiler
2 ;;  Copyright (C) 1991-2017 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           (eq_attr "arch_enabled" "no")
237           (const_string "no")]
238          (const_string "yes")))
240 ; POOL_RANGE is how far away from a constant pool entry that this insn
241 ; can be placed.  If the distance is zero, then this insn will never
242 ; reference the pool.
243 ; Note that for Thumb constant pools the PC value is rounded down to the
244 ; nearest multiple of four.  Therefore, THUMB2_POOL_RANGE (and POOL_RANGE for
245 ; Thumb insns) should be set to <max_range> - 2.
246 ; NEG_POOL_RANGE is nonzero for insns that can reference a constant pool entry
247 ; before its address.  It is set to <max_range> - (8 + <data_size>).
248 (define_attr "arm_pool_range" "" (const_int 0))
249 (define_attr "thumb2_pool_range" "" (const_int 0))
250 (define_attr "arm_neg_pool_range" "" (const_int 0))
251 (define_attr "thumb2_neg_pool_range" "" (const_int 0))
253 (define_attr "pool_range" ""
254   (cond [(eq_attr "is_thumb" "yes") (attr "thumb2_pool_range")]
255         (attr "arm_pool_range")))
256 (define_attr "neg_pool_range" ""
257   (cond [(eq_attr "is_thumb" "yes") (attr "thumb2_neg_pool_range")]
258         (attr "arm_neg_pool_range")))
260 ; An assembler sequence may clobber the condition codes without us knowing.
261 ; If such an insn references the pool, then we have no way of knowing how,
262 ; so use the most conservative value for pool_range.
263 (define_asm_attributes
264  [(set_attr "conds" "clob")
265   (set_attr "length" "4")
266   (set_attr "pool_range" "250")])
268 ; Load scheduling, set from the arm_ld_sched variable
269 ; initialized by arm_option_override()
270 (define_attr "ldsched" "no,yes" (const (symbol_ref "arm_ld_sched")))
272 ; condition codes: this one is used by final_prescan_insn to speed up
273 ; conditionalizing instructions.  It saves having to scan the rtl to see if
274 ; it uses or alters the condition codes.
276 ; USE means that the condition codes are used by the insn in the process of
277 ;   outputting code, this means (at present) that we can't use the insn in
278 ;   inlined branches
280 ; SET means that the purpose of the insn is to set the condition codes in a
281 ;   well defined manner.
283 ; CLOB means that the condition codes are altered in an undefined manner, if
284 ;   they are altered at all
286 ; UNCONDITIONAL means the instruction can not be conditionally executed and
287 ;   that the instruction does not use or alter the condition codes.
289 ; NOCOND means that the instruction does not use or alter the condition
290 ;   codes but can be converted into a conditionally exectuted instruction.
292 (define_attr "conds" "use,set,clob,unconditional,nocond"
293         (if_then_else
294          (ior (eq_attr "is_thumb1" "yes")
295               (eq_attr "type" "call"))
296          (const_string "clob")
297          (if_then_else (eq_attr "is_neon_type" "no")
298          (const_string "nocond")
299          (const_string "unconditional"))))
301 ; Predicable means that the insn can be conditionally executed based on
302 ; an automatically added predicate (additional patterns are generated by 
303 ; gen...).  We default to 'no' because no Thumb patterns match this rule
304 ; and not all ARM patterns do.
305 (define_attr "predicable" "no,yes" (const_string "no"))
307 ; Only model the write buffer for ARM6 and ARM7.  Earlier processors don't
308 ; have one.  Later ones, such as StrongARM, have write-back caches, so don't
309 ; suffer blockages enough to warrant modelling this (and it can adversely
310 ; affect the schedule).
311 (define_attr "model_wbuf" "no,yes" (const (symbol_ref "arm_tune_wbuf")))
313 ; WRITE_CONFLICT implies that a read following an unrelated write is likely
314 ; to stall the processor.  Used with model_wbuf above.
315 (define_attr "write_conflict" "no,yes"
316   (if_then_else (eq_attr "type"
317                  "block,call,load1")
318                 (const_string "yes")
319                 (const_string "no")))
321 ; Classify the insns into those that take one cycle and those that take more
322 ; than one on the main cpu execution unit.
323 (define_attr "core_cycles" "single,multi"
324   (if_then_else (eq_attr "type"
325     "adc_imm, adc_reg, adcs_imm, adcs_reg, adr, alu_ext, alu_imm, alu_sreg,\
326     alu_shift_imm, alu_shift_reg, alu_dsp_reg, alus_ext, alus_imm, alus_sreg,\
327     alus_shift_imm, alus_shift_reg, bfm, csel, rev, logic_imm, logic_reg,\
328     logic_shift_imm, logic_shift_reg, logics_imm, logics_reg,\
329     logics_shift_imm, logics_shift_reg, extend, shift_imm, float, fcsel,\
330     wmmx_wor, wmmx_wxor, wmmx_wand, wmmx_wandn, wmmx_wmov, wmmx_tmcrr,\
331     wmmx_tmrrc, wmmx_wldr, wmmx_wstr, wmmx_tmcr, wmmx_tmrc, wmmx_wadd,\
332     wmmx_wsub, wmmx_wmul, wmmx_wmac, wmmx_wavg2, wmmx_tinsr, wmmx_textrm,\
333     wmmx_wshufh, wmmx_wcmpeq, wmmx_wcmpgt, wmmx_wmax, wmmx_wmin, wmmx_wpack,\
334     wmmx_wunpckih, wmmx_wunpckil, wmmx_wunpckeh, wmmx_wunpckel, wmmx_wror,\
335     wmmx_wsra, wmmx_wsrl, wmmx_wsll, wmmx_wmadd, wmmx_tmia, wmmx_tmiaph,\
336     wmmx_tmiaxy, wmmx_tbcst, wmmx_tmovmsk, wmmx_wacc, wmmx_waligni,\
337     wmmx_walignr, wmmx_tandc, wmmx_textrc, wmmx_torc, wmmx_torvsc, wmmx_wsad,\
338     wmmx_wabs, wmmx_wabsdiff, wmmx_waddsubhx, wmmx_wsubaddhx, wmmx_wavg4,\
339     wmmx_wmulw, wmmx_wqmulm, wmmx_wqmulwm, wmmx_waddbhus, wmmx_wqmiaxy,\
340     wmmx_wmiaxy, wmmx_wmiawxy, wmmx_wmerge")
341                 (const_string "single")
342                 (const_string "multi")))
344 ;; FAR_JUMP is "yes" if a BL instruction is used to generate a branch to a
345 ;; distant label.  Only applicable to Thumb code.
346 (define_attr "far_jump" "yes,no" (const_string "no"))
349 ;; The number of machine instructions this pattern expands to.
350 ;; Used for Thumb-2 conditional execution.
351 (define_attr "ce_count" "" (const_int 1))
353 ;;---------------------------------------------------------------------------
354 ;; Unspecs
356 (include "unspecs.md")
358 ;;---------------------------------------------------------------------------
359 ;; Mode iterators
361 (include "iterators.md")
363 ;;---------------------------------------------------------------------------
364 ;; Predicates
366 (include "predicates.md")
367 (include "constraints.md")
369 ;;---------------------------------------------------------------------------
370 ;; Pipeline descriptions
372 (define_attr "tune_cortexr4" "yes,no"
373   (const (if_then_else
374           (eq_attr "tune" "cortexr4,cortexr4f,cortexr5")
375           (const_string "yes")
376           (const_string "no"))))
378 ;; True if the generic scheduling description should be used.
380 (define_attr "generic_sched" "yes,no"
381   (const (if_then_else
382           (ior (eq_attr "tune" "fa526,fa626,fa606te,fa626te,fmp626,fa726te,\
383                                 arm926ejs,arm1020e,arm1026ejs,arm1136js,\
384                                 arm1136jfs,cortexa5,cortexa7,cortexa8,\
385                                 cortexa9,cortexa12,cortexa15,cortexa17,\
386                                 cortexa53,cortexa57,cortexm4,cortexm7,\
387                                 exynosm1,marvell_pj4,xgene1")
388                (eq_attr "tune_cortexr4" "yes"))
389           (const_string "no")
390           (const_string "yes"))))
392 (define_attr "generic_vfp" "yes,no"
393   (const (if_then_else
394           (and (eq_attr "fpu" "vfp")
395                (eq_attr "tune" "!arm1020e,arm1022e,cortexa5,cortexa7,\
396                                 cortexa8,cortexa9,cortexa53,cortexm4,\
397                                 cortexm7,marvell_pj4,xgene1")
398                (eq_attr "tune_cortexr4" "no"))
399           (const_string "yes")
400           (const_string "no"))))
402 (include "marvell-f-iwmmxt.md")
403 (include "arm-generic.md")
404 (include "arm926ejs.md")
405 (include "arm1020e.md")
406 (include "arm1026ejs.md")
407 (include "arm1136jfs.md")
408 (include "fa526.md")
409 (include "fa606te.md")
410 (include "fa626te.md")
411 (include "fmp626.md")
412 (include "fa726te.md")
413 (include "cortex-a5.md")
414 (include "cortex-a7.md")
415 (include "cortex-a8.md")
416 (include "cortex-a9.md")
417 (include "cortex-a15.md")
418 (include "cortex-a17.md")
419 (include "cortex-a53.md")
420 (include "cortex-a57.md")
421 (include "cortex-r4.md")
422 (include "cortex-r4f.md")
423 (include "cortex-m7.md")
424 (include "cortex-m4.md")
425 (include "cortex-m4-fpu.md")
426 (include "exynos-m1.md")
427 (include "vfp11.md")
428 (include "marvell-pj4.md")
429 (include "xgene1.md")
432 ;;---------------------------------------------------------------------------
433 ;; Insn patterns
435 ;; Addition insns.
437 ;; Note: For DImode insns, there is normally no reason why operands should
438 ;; not be in the same register, what we don't want is for something being
439 ;; written to partially overlap something that is an input.
441 (define_expand "adddi3"
442  [(parallel
443    [(set (match_operand:DI           0 "s_register_operand" "")
444           (plus:DI (match_operand:DI 1 "s_register_operand" "")
445                    (match_operand:DI 2 "arm_adddi_operand"  "")))
446     (clobber (reg:CC CC_REGNUM))])]
447   "TARGET_EITHER"
448   "
449   if (TARGET_THUMB1)
450     {
451       if (!REG_P (operands[1]))
452         operands[1] = force_reg (DImode, operands[1]);
453       if (!REG_P (operands[2]))
454         operands[2] = force_reg (DImode, operands[2]);
455      }
456   "
459 (define_insn_and_split "*arm_adddi3"
460   [(set (match_operand:DI          0 "arm_general_register_operand" "=&r,&r,&r,&r,&r")
461         (plus:DI (match_operand:DI 1 "arm_general_register_operand" "%0, 0, r, 0, r")
462                  (match_operand:DI 2 "arm_general_adddi_operand"    "r,  0, r, Dd, Dd")))
463    (clobber (reg:CC CC_REGNUM))]
464   "TARGET_32BIT && !TARGET_NEON"
465   "#"
466   "TARGET_32BIT && ((!TARGET_NEON && !TARGET_IWMMXT) || reload_completed)"
467   [(parallel [(set (reg:CC_C CC_REGNUM)
468                    (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
469                                  (match_dup 1)))
470               (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
471    (set (match_dup 3) (plus:SI (plus:SI (match_dup 4) (match_dup 5))
472                                (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
473   "
474   {
475     operands[3] = gen_highpart (SImode, operands[0]);
476     operands[0] = gen_lowpart (SImode, operands[0]);
477     operands[4] = gen_highpart (SImode, operands[1]);
478     operands[1] = gen_lowpart (SImode, operands[1]);
479     operands[5] = gen_highpart_mode (SImode, DImode, operands[2]);
480     operands[2] = gen_lowpart (SImode, operands[2]);
481   }"
482   [(set_attr "conds" "clob")
483    (set_attr "length" "8")
484    (set_attr "type" "multiple")]
487 (define_insn_and_split "*adddi_sesidi_di"
488   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
489         (plus:DI (sign_extend:DI
490                   (match_operand:SI 2 "s_register_operand" "r,r"))
491                  (match_operand:DI 1 "s_register_operand" "0,r")))
492    (clobber (reg:CC CC_REGNUM))]
493   "TARGET_32BIT"
494   "#"
495   "TARGET_32BIT && reload_completed"
496   [(parallel [(set (reg:CC_C CC_REGNUM)
497                    (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
498                                  (match_dup 1)))
499               (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
500    (set (match_dup 3) (plus:SI (plus:SI (ashiftrt:SI (match_dup 2)
501                                                      (const_int 31))
502                                         (match_dup 4))
503                                (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
504   "
505   {
506     operands[3] = gen_highpart (SImode, operands[0]);
507     operands[0] = gen_lowpart (SImode, operands[0]);
508     operands[4] = gen_highpart (SImode, operands[1]);
509     operands[1] = gen_lowpart (SImode, operands[1]);
510     operands[2] = gen_lowpart (SImode, operands[2]);
511   }"
512   [(set_attr "conds" "clob")
513    (set_attr "length" "8")
514    (set_attr "type" "multiple")]
517 (define_insn_and_split "*adddi_zesidi_di"
518   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
519         (plus:DI (zero_extend:DI
520                   (match_operand:SI 2 "s_register_operand" "r,r"))
521                  (match_operand:DI 1 "s_register_operand" "0,r")))
522    (clobber (reg:CC CC_REGNUM))]
523   "TARGET_32BIT"
524   "#"
525   "TARGET_32BIT && reload_completed"
526   [(parallel [(set (reg:CC_C CC_REGNUM)
527                    (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
528                                  (match_dup 1)))
529               (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
530    (set (match_dup 3) (plus:SI (plus:SI (match_dup 4) (const_int 0))
531                                (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
532   "
533   {
534     operands[3] = gen_highpart (SImode, operands[0]);
535     operands[0] = gen_lowpart (SImode, operands[0]);
536     operands[4] = gen_highpart (SImode, operands[1]);
537     operands[1] = gen_lowpart (SImode, operands[1]);
538     operands[2] = gen_lowpart (SImode, operands[2]);
539   }"
540   [(set_attr "conds" "clob")
541    (set_attr "length" "8")
542    (set_attr "type" "multiple")]
545 (define_expand "addv<mode>4"
546   [(match_operand:SIDI 0 "register_operand")
547    (match_operand:SIDI 1 "register_operand")
548    (match_operand:SIDI 2 "register_operand")
549    (match_operand 3 "")]
550   "TARGET_32BIT"
552   emit_insn (gen_add<mode>3_compareV (operands[0], operands[1], operands[2]));
553   arm_gen_unlikely_cbranch (NE, CC_Vmode, operands[3]);
555   DONE;
558 (define_expand "uaddv<mode>4"
559   [(match_operand:SIDI 0 "register_operand")
560    (match_operand:SIDI 1 "register_operand")
561    (match_operand:SIDI 2 "register_operand")
562    (match_operand 3 "")]
563   "TARGET_32BIT"
565   emit_insn (gen_add<mode>3_compareC (operands[0], operands[1], operands[2]));
566   arm_gen_unlikely_cbranch (NE, CC_Cmode, operands[3]);
568   DONE;
571 (define_expand "addsi3"
572   [(set (match_operand:SI          0 "s_register_operand" "")
573         (plus:SI (match_operand:SI 1 "s_register_operand" "")
574                  (match_operand:SI 2 "reg_or_int_operand" "")))]
575   "TARGET_EITHER"
576   "
577   if (TARGET_32BIT && CONST_INT_P (operands[2]))
578     {
579       arm_split_constant (PLUS, SImode, NULL_RTX,
580                           INTVAL (operands[2]), operands[0], operands[1],
581                           optimize && can_create_pseudo_p ());
582       DONE;
583     }
584   "
587 ; If there is a scratch available, this will be faster than synthesizing the
588 ; addition.
589 (define_peephole2
590   [(match_scratch:SI 3 "r")
591    (set (match_operand:SI          0 "arm_general_register_operand" "")
592         (plus:SI (match_operand:SI 1 "arm_general_register_operand" "")
593                  (match_operand:SI 2 "const_int_operand"  "")))]
594   "TARGET_32BIT &&
595    !(const_ok_for_arm (INTVAL (operands[2]))
596      || const_ok_for_arm (-INTVAL (operands[2])))
597     && const_ok_for_arm (~INTVAL (operands[2]))"
598   [(set (match_dup 3) (match_dup 2))
599    (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 3)))]
600   ""
603 ;; The r/r/k alternative is required when reloading the address
604 ;;  (plus (reg rN) (reg sp)) into (reg rN).  In this case reload will
605 ;; put the duplicated register first, and not try the commutative version.
606 (define_insn_and_split "*arm_addsi3"
607   [(set (match_operand:SI          0 "s_register_operand" "=rk,l,l ,l ,r ,k ,r,k ,r ,k ,r ,k,k,r ,k ,r")
608         (plus:SI (match_operand:SI 1 "s_register_operand" "%0 ,l,0 ,l ,rk,k ,r,r ,rk,k ,rk,k,r,rk,k ,rk")
609                  (match_operand:SI 2 "reg_or_int_operand" "rk ,l,Py,Pd,rI,rI,k,rI,Pj,Pj,L ,L,L,PJ,PJ,?n")))]
610   "TARGET_32BIT"
611   "@
612    add%?\\t%0, %0, %2
613    add%?\\t%0, %1, %2
614    add%?\\t%0, %1, %2
615    add%?\\t%0, %1, %2
616    add%?\\t%0, %1, %2
617    add%?\\t%0, %1, %2
618    add%?\\t%0, %2, %1
619    add%?\\t%0, %1, %2
620    addw%?\\t%0, %1, %2
621    addw%?\\t%0, %1, %2
622    sub%?\\t%0, %1, #%n2
623    sub%?\\t%0, %1, #%n2
624    sub%?\\t%0, %1, #%n2
625    subw%?\\t%0, %1, #%n2
626    subw%?\\t%0, %1, #%n2
627    #"
628   "TARGET_32BIT
629    && CONST_INT_P (operands[2])
630    && !const_ok_for_op (INTVAL (operands[2]), PLUS)
631    && (reload_completed || !arm_eliminable_register (operands[1]))"
632   [(clobber (const_int 0))]
633   "
634   arm_split_constant (PLUS, SImode, curr_insn,
635                       INTVAL (operands[2]), operands[0],
636                       operands[1], 0);
637   DONE;
638   "
639   [(set_attr "length" "2,4,4,4,4,4,4,4,4,4,4,4,4,4,4,16")
640    (set_attr "predicable" "yes")
641    (set_attr "predicable_short_it" "yes,yes,yes,yes,no,no,no,no,no,no,no,no,no,no,no,no")
642    (set_attr "arch" "t2,t2,t2,t2,*,*,*,a,t2,t2,*,*,a,t2,t2,*")
643    (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
644                       (const_string "alu_imm")
645                       (const_string "alu_sreg")))
649 (define_insn_and_split "adddi3_compareV"
650   [(set (reg:CC_V CC_REGNUM)
651         (ne:CC_V
652           (plus:TI
653             (sign_extend:TI (match_operand:DI 1 "register_operand" "r"))
654             (sign_extend:TI (match_operand:DI 2 "register_operand" "r")))
655           (sign_extend:TI (plus:DI (match_dup 1) (match_dup 2)))))
656    (set (match_operand:DI 0 "register_operand" "=&r")
657         (plus:DI (match_dup 1) (match_dup 2)))]
658   "TARGET_32BIT"
659   "#"
660   "&& reload_completed"
661   [(parallel [(set (reg:CC_C CC_REGNUM)
662                    (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
663                                  (match_dup 1)))
664               (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
665    (parallel [(set (reg:CC_V CC_REGNUM)
666                    (ne:CC_V
667                     (plus:DI (plus:DI
668                               (sign_extend:DI (match_dup 4))
669                               (sign_extend:DI (match_dup 5)))
670                              (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0)))
671                     (plus:DI (sign_extend:DI
672                               (plus:SI (match_dup 4) (match_dup 5)))
673                              (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0)))))
674              (set (match_dup 3) (plus:SI (plus:SI
675                                           (match_dup 4) (match_dup 5))
676                                          (ltu:SI (reg:CC_C CC_REGNUM)
677                                                  (const_int 0))))])]
678   "
679   {
680     operands[3] = gen_highpart (SImode, operands[0]);
681     operands[0] = gen_lowpart (SImode, operands[0]);
682     operands[4] = gen_highpart (SImode, operands[1]);
683     operands[1] = gen_lowpart (SImode, operands[1]);
684     operands[5] = gen_highpart (SImode, operands[2]);
685     operands[2] = gen_lowpart (SImode, operands[2]);
686   }"
687  [(set_attr "conds" "set")
688    (set_attr "length" "8")
689    (set_attr "type" "multiple")]
692 (define_insn "addsi3_compareV"
693   [(set (reg:CC_V CC_REGNUM)
694         (ne:CC_V
695           (plus:DI
696             (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
697             (sign_extend:DI (match_operand:SI 2 "register_operand" "r")))
698           (sign_extend:DI (plus:SI (match_dup 1) (match_dup 2)))))
699    (set (match_operand:SI 0 "register_operand" "=r")
700         (plus:SI (match_dup 1) (match_dup 2)))]
701   "TARGET_32BIT"
702   "adds%?\\t%0, %1, %2"
703   [(set_attr "conds" "set")
704    (set_attr "type" "alus_sreg")]
707 (define_insn "*addsi3_compareV_upper"
708   [(set (reg:CC_V CC_REGNUM)
709         (ne:CC_V
710           (plus:DI
711            (plus:DI
712             (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
713             (sign_extend:DI (match_operand:SI 2 "register_operand" "r")))
714            (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0)))
715           (plus:DI (sign_extend:DI
716                     (plus:SI (match_dup 1) (match_dup 2)))
717                    (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0)))))
718    (set (match_operand:SI 0 "register_operand" "=r")
719         (plus:SI
720          (plus:SI (match_dup 1) (match_dup 2))
721          (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
722   "TARGET_32BIT"
723   "adcs%?\\t%0, %1, %2"
724   [(set_attr "conds" "set")
725    (set_attr "type" "adcs_reg")]
728 (define_insn_and_split "adddi3_compareC"
729   [(set (reg:CC_C CC_REGNUM)
730         (ne:CC_C
731           (plus:TI
732             (zero_extend:TI (match_operand:DI 1 "register_operand" "r"))
733             (zero_extend:TI (match_operand:DI 2 "register_operand" "r")))
734           (zero_extend:TI (plus:DI (match_dup 1) (match_dup 2)))))
735    (set (match_operand:DI 0 "register_operand" "=&r")
736         (plus:DI (match_dup 1) (match_dup 2)))]
737   "TARGET_32BIT"
738   "#"
739   "&& reload_completed"
740   [(parallel [(set (reg:CC_C CC_REGNUM)
741                    (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
742                                  (match_dup 1)))
743               (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
744    (parallel [(set (reg:CC_C CC_REGNUM)
745                    (ne:CC_C
746                     (plus:DI (plus:DI
747                               (zero_extend:DI (match_dup 4))
748                               (zero_extend:DI (match_dup 5)))
749                              (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0)))
750                     (plus:DI (zero_extend:DI
751                               (plus:SI (match_dup 4) (match_dup 5)))
752                              (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0)))))
753              (set (match_dup 3) (plus:SI
754                                  (plus:SI (match_dup 4) (match_dup 5))
755                                  (ltu:SI (reg:CC_C CC_REGNUM)
756                                          (const_int 0))))])]
757   "
758   {
759     operands[3] = gen_highpart (SImode, operands[0]);
760     operands[0] = gen_lowpart (SImode, operands[0]);
761     operands[4] = gen_highpart (SImode, operands[1]);
762     operands[5] = gen_highpart (SImode, operands[2]);
763     operands[1] = gen_lowpart (SImode, operands[1]);
764     operands[2] = gen_lowpart (SImode, operands[2]);
765   }"
766  [(set_attr "conds" "set")
767    (set_attr "length" "8")
768    (set_attr "type" "multiple")]
771 (define_insn "*addsi3_compareC_upper"
772   [(set (reg:CC_C CC_REGNUM)
773         (ne:CC_C
774           (plus:DI
775            (plus:DI
776             (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
777             (zero_extend:DI (match_operand:SI 2 "register_operand" "r")))
778            (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0)))
779           (plus:DI (zero_extend:DI
780                     (plus:SI (match_dup 1) (match_dup 2)))
781                    (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0)))))
782    (set (match_operand:SI 0 "register_operand" "=r")
783         (plus:SI
784          (plus:SI (match_dup 1) (match_dup 2))
785          (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
786   "TARGET_32BIT"
787   "adcs%?\\t%0, %1, %2"
788   [(set_attr "conds" "set")
789    (set_attr "type" "adcs_reg")]
792 (define_insn "addsi3_compareC"
793    [(set (reg:CC_C CC_REGNUM)
794          (ne:CC_C
795           (plus:DI
796            (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
797            (zero_extend:DI (match_operand:SI 2 "register_operand" "r")))
798           (zero_extend:DI
799            (plus:SI (match_dup 1) (match_dup 2)))))
800     (set (match_operand:SI 0 "register_operand" "=r")
801          (plus:SI (match_dup 1) (match_dup 2)))]
802   "TARGET_32BIT"
803   "adds%?\\t%0, %1, %2"
804   [(set_attr "conds" "set")
805    (set_attr "type" "alus_sreg")]
808 (define_insn "addsi3_compare0"
809   [(set (reg:CC_NOOV CC_REGNUM)
810         (compare:CC_NOOV
811          (plus:SI (match_operand:SI 1 "s_register_operand" "r, r,r")
812                   (match_operand:SI 2 "arm_add_operand"    "I,L,r"))
813          (const_int 0)))
814    (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
815         (plus:SI (match_dup 1) (match_dup 2)))]
816   "TARGET_ARM"
817   "@
818    adds%?\\t%0, %1, %2
819    subs%?\\t%0, %1, #%n2
820    adds%?\\t%0, %1, %2"
821   [(set_attr "conds" "set")
822    (set_attr "type" "alus_imm,alus_imm,alus_sreg")]
825 (define_insn "*addsi3_compare0_scratch"
826   [(set (reg:CC_NOOV CC_REGNUM)
827         (compare:CC_NOOV
828          (plus:SI (match_operand:SI 0 "s_register_operand" "r, r, r")
829                   (match_operand:SI 1 "arm_add_operand"    "I,L, r"))
830          (const_int 0)))]
831   "TARGET_ARM"
832   "@
833    cmn%?\\t%0, %1
834    cmp%?\\t%0, #%n1
835    cmn%?\\t%0, %1"
836   [(set_attr "conds" "set")
837    (set_attr "predicable" "yes")
838    (set_attr "type" "alus_imm,alus_imm,alus_sreg")]
841 (define_insn "*compare_negsi_si"
842   [(set (reg:CC_Z CC_REGNUM)
843         (compare:CC_Z
844          (neg:SI (match_operand:SI 0 "s_register_operand" "l,r"))
845          (match_operand:SI 1 "s_register_operand" "l,r")))]
846   "TARGET_32BIT"
847   "cmn%?\\t%1, %0"
848   [(set_attr "conds" "set")
849    (set_attr "predicable" "yes")
850    (set_attr "arch" "t2,*")
851    (set_attr "length" "2,4")
852    (set_attr "predicable_short_it" "yes,no")
853    (set_attr "type" "alus_sreg")]
856 ;; This is the canonicalization of addsi3_compare0_for_combiner when the
857 ;; addend is a constant.
858 (define_insn "cmpsi2_addneg"
859   [(set (reg:CC CC_REGNUM)
860         (compare:CC
861          (match_operand:SI 1 "s_register_operand" "r,r")
862          (match_operand:SI 2 "arm_addimm_operand" "L,I")))
863    (set (match_operand:SI 0 "s_register_operand" "=r,r")
864         (plus:SI (match_dup 1)
865                  (match_operand:SI 3 "arm_addimm_operand" "I,L")))]
866   "TARGET_32BIT && INTVAL (operands[2]) == -INTVAL (operands[3])"
867   "@
868    adds%?\\t%0, %1, %3
869    subs%?\\t%0, %1, #%n3"
870   [(set_attr "conds" "set")
871    (set_attr "type" "alus_sreg")]
874 ;; Convert the sequence
875 ;;  sub  rd, rn, #1
876 ;;  cmn  rd, #1 (equivalent to cmp rd, #-1)
877 ;;  bne  dest
878 ;; into
879 ;;  subs rd, rn, #1
880 ;;  bcs  dest   ((unsigned)rn >= 1)
881 ;; similarly for the beq variant using bcc.
882 ;; This is a common looping idiom (while (n--))
883 (define_peephole2
884   [(set (match_operand:SI 0 "arm_general_register_operand" "")
885         (plus:SI (match_operand:SI 1 "arm_general_register_operand" "")
886                  (const_int -1)))
887    (set (match_operand 2 "cc_register" "")
888         (compare (match_dup 0) (const_int -1)))
889    (set (pc)
890         (if_then_else (match_operator 3 "equality_operator"
891                        [(match_dup 2) (const_int 0)])
892                       (match_operand 4 "" "")
893                       (match_operand 5 "" "")))]
894   "TARGET_32BIT && peep2_reg_dead_p (3, operands[2])"
895   [(parallel[
896     (set (match_dup 2)
897          (compare:CC
898           (match_dup 1) (const_int 1)))
899     (set (match_dup 0) (plus:SI (match_dup 1) (const_int -1)))])
900    (set (pc)
901         (if_then_else (match_op_dup 3 [(match_dup 2) (const_int 0)])
902                       (match_dup 4)
903                       (match_dup 5)))]
904   "operands[2] = gen_rtx_REG (CCmode, CC_REGNUM);
905    operands[3] = gen_rtx_fmt_ee ((GET_CODE (operands[3]) == NE
906                                   ? GEU : LTU),
907                                  VOIDmode, 
908                                  operands[2], const0_rtx);"
911 ;; The next four insns work because they compare the result with one of
912 ;; the operands, and we know that the use of the condition code is
913 ;; either GEU or LTU, so we can use the carry flag from the addition
914 ;; instead of doing the compare a second time.
915 (define_insn "*addsi3_compare_op1"
916   [(set (reg:CC_C CC_REGNUM)
917         (compare:CC_C
918          (plus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
919                   (match_operand:SI 2 "arm_add_operand" "I,L,r"))
920          (match_dup 1)))
921    (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
922         (plus:SI (match_dup 1) (match_dup 2)))]
923   "TARGET_32BIT"
924   "@
925    adds%?\\t%0, %1, %2
926    subs%?\\t%0, %1, #%n2
927    adds%?\\t%0, %1, %2"
928   [(set_attr "conds" "set")
929    (set_attr "type"  "alus_imm,alus_imm,alus_sreg")]
932 (define_insn "*addsi3_compare_op2"
933   [(set (reg:CC_C CC_REGNUM)
934         (compare:CC_C
935          (plus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
936                   (match_operand:SI 2 "arm_add_operand" "I,L,r"))
937          (match_dup 2)))
938    (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
939         (plus:SI (match_dup 1) (match_dup 2)))]
940   "TARGET_32BIT"
941   "@
942    adds%?\\t%0, %1, %2
943    subs%?\\t%0, %1, #%n2
944    adds%?\\t%0, %1, %2"
945   [(set_attr "conds" "set")
946    (set_attr "type" "alus_imm,alus_imm,alus_sreg")]
949 (define_insn "*compare_addsi2_op0"
950   [(set (reg:CC_C CC_REGNUM)
951         (compare:CC_C
952           (plus:SI (match_operand:SI 0 "s_register_operand" "l,l,r,r,r")
953                    (match_operand:SI 1 "arm_add_operand" "Pv,l,I,L,r"))
954           (match_dup 0)))]
955   "TARGET_32BIT"
956   "@
957    cmp%?\\t%0, #%n1
958    cmn%?\\t%0, %1
959    cmn%?\\t%0, %1
960    cmp%?\\t%0, #%n1
961    cmn%?\\t%0, %1"
962   [(set_attr "conds" "set")
963    (set_attr "predicable" "yes")
964    (set_attr "arch" "t2,t2,*,*,*")
965    (set_attr "predicable_short_it" "yes,yes,no,no,no")
966    (set_attr "length" "2,2,4,4,4")
967    (set_attr "type" "alus_imm,alus_sreg,alus_imm,alus_imm,alus_sreg")]
970 (define_insn "*compare_addsi2_op1"
971   [(set (reg:CC_C CC_REGNUM)
972         (compare:CC_C
973           (plus:SI (match_operand:SI 0 "s_register_operand" "l,l,r,r,r")
974                    (match_operand:SI 1 "arm_add_operand" "Pv,l,I,L,r"))
975           (match_dup 1)))]
976   "TARGET_32BIT"
977   "@
978    cmp%?\\t%0, #%n1
979    cmn%?\\t%0, %1
980    cmn%?\\t%0, %1
981    cmp%?\\t%0, #%n1
982    cmn%?\\t%0, %1"
983   [(set_attr "conds" "set")
984    (set_attr "predicable" "yes")
985    (set_attr "arch" "t2,t2,*,*,*")
986    (set_attr "predicable_short_it" "yes,yes,no,no,no")
987    (set_attr "length" "2,2,4,4,4")
988    (set_attr "type" "alus_imm,alus_sreg,alus_imm,alus_imm,alus_sreg")]
991 (define_insn "*addsi3_carryin_<optab>"
992   [(set (match_operand:SI 0 "s_register_operand" "=l,r,r")
993         (plus:SI (plus:SI (match_operand:SI 1 "s_register_operand" "%l,r,r")
994                           (match_operand:SI 2 "arm_not_operand" "0,rI,K"))
995                  (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))))]
996   "TARGET_32BIT"
997   "@
998    adc%?\\t%0, %1, %2
999    adc%?\\t%0, %1, %2
1000    sbc%?\\t%0, %1, #%B2"
1001   [(set_attr "conds" "use")
1002    (set_attr "predicable" "yes")
1003    (set_attr "arch" "t2,*,*")
1004    (set_attr "length" "4")
1005    (set_attr "predicable_short_it" "yes,no,no")
1006    (set_attr "type" "adc_reg,adc_reg,adc_imm")]
1009 (define_insn "*addsi3_carryin_alt2_<optab>"
1010   [(set (match_operand:SI 0 "s_register_operand" "=l,r,r")
1011         (plus:SI (plus:SI (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))
1012                           (match_operand:SI 1 "s_register_operand" "%l,r,r"))
1013                  (match_operand:SI 2 "arm_rhs_operand" "l,rI,K")))]
1014   "TARGET_32BIT"
1015   "@
1016    adc%?\\t%0, %1, %2
1017    adc%?\\t%0, %1, %2
1018    sbc%?\\t%0, %1, #%B2"
1019   [(set_attr "conds" "use")
1020    (set_attr "predicable" "yes")
1021    (set_attr "arch" "t2,*,*")
1022    (set_attr "length" "4")
1023    (set_attr "predicable_short_it" "yes,no,no")
1024    (set_attr "type" "adc_reg,adc_reg,adc_imm")]
1027 (define_insn "*addsi3_carryin_shift_<optab>"
1028   [(set (match_operand:SI 0 "s_register_operand" "=r")
1029         (plus:SI (plus:SI
1030                   (match_operator:SI 2 "shift_operator"
1031                     [(match_operand:SI 3 "s_register_operand" "r")
1032                      (match_operand:SI 4 "reg_or_int_operand" "rM")])
1033                   (match_operand:SI 1 "s_register_operand" "r"))
1034                  (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))))]
1035   "TARGET_32BIT"
1036   "adc%?\\t%0, %1, %3%S2"
1037   [(set_attr "conds" "use")
1038    (set_attr "predicable" "yes")
1039    (set_attr "predicable_short_it" "no")
1040    (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
1041                       (const_string "alu_shift_imm")
1042                       (const_string "alu_shift_reg")))]
1045 (define_insn "*addsi3_carryin_clobercc_<optab>"
1046   [(set (match_operand:SI 0 "s_register_operand" "=r")
1047         (plus:SI (plus:SI (match_operand:SI 1 "s_register_operand" "%r")
1048                           (match_operand:SI 2 "arm_rhs_operand" "rI"))
1049                  (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))))
1050    (clobber (reg:CC CC_REGNUM))]
1051    "TARGET_32BIT"
1052    "adcs%?\\t%0, %1, %2"
1053    [(set_attr "conds" "set")
1054     (set_attr "type" "adcs_reg")]
1057 (define_expand "subv<mode>4"
1058   [(match_operand:SIDI 0 "register_operand")
1059    (match_operand:SIDI 1 "register_operand")
1060    (match_operand:SIDI 2 "register_operand")
1061    (match_operand 3 "")]
1062   "TARGET_32BIT"
1064   emit_insn (gen_sub<mode>3_compare1 (operands[0], operands[1], operands[2]));
1065   arm_gen_unlikely_cbranch (NE, CC_Vmode, operands[3]);
1067   DONE;
1070 (define_expand "usubv<mode>4"
1071   [(match_operand:SIDI 0 "register_operand")
1072    (match_operand:SIDI 1 "register_operand")
1073    (match_operand:SIDI 2 "register_operand")
1074    (match_operand 3 "")]
1075   "TARGET_32BIT"
1077   emit_insn (gen_sub<mode>3_compare1 (operands[0], operands[1], operands[2]));
1078   arm_gen_unlikely_cbranch (LTU, CCmode, operands[3]);
1080   DONE;
1083 (define_insn_and_split "subdi3_compare1"
1084   [(set (reg:CC CC_REGNUM)
1085         (compare:CC
1086           (match_operand:DI 1 "register_operand" "r")
1087           (match_operand:DI 2 "register_operand" "r")))
1088    (set (match_operand:DI 0 "register_operand" "=&r")
1089         (minus:DI (match_dup 1) (match_dup 2)))]
1090   "TARGET_32BIT"
1091   "#"
1092   "&& reload_completed"
1093   [(parallel [(set (reg:CC CC_REGNUM)
1094                    (compare:CC (match_dup 1) (match_dup 2)))
1095               (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1096    (parallel [(set (reg:CC CC_REGNUM)
1097                    (compare:CC (match_dup 4) (match_dup 5)))
1098              (set (match_dup 3) (minus:SI (minus:SI (match_dup 4) (match_dup 5))
1099                                (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))])]
1100   {
1101     operands[3] = gen_highpart (SImode, operands[0]);
1102     operands[0] = gen_lowpart (SImode, operands[0]);
1103     operands[4] = gen_highpart (SImode, operands[1]);
1104     operands[1] = gen_lowpart (SImode, operands[1]);
1105     operands[5] = gen_highpart (SImode, operands[2]);
1106     operands[2] = gen_lowpart (SImode, operands[2]);
1107    }
1108   [(set_attr "conds" "set")
1109    (set_attr "length" "8")
1110    (set_attr "type" "multiple")]
1113 (define_insn "subsi3_compare1"
1114   [(set (reg:CC CC_REGNUM)
1115         (compare:CC
1116           (match_operand:SI 1 "register_operand" "r")
1117           (match_operand:SI 2 "register_operand" "r")))
1118    (set (match_operand:SI 0 "register_operand" "=r")
1119         (minus:SI (match_dup 1) (match_dup 2)))]
1120   "TARGET_32BIT"
1121   "subs%?\\t%0, %1, %2"
1122   [(set_attr "conds" "set")
1123    (set_attr "type" "alus_sreg")]
1126 (define_insn "*subsi3_carryin"
1127   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
1128         (minus:SI (minus:SI (match_operand:SI 1 "reg_or_int_operand" "r,I,Pz")
1129                             (match_operand:SI 2 "s_register_operand" "r,r,r"))
1130                   (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1131   "TARGET_32BIT"
1132   "@
1133    sbc%?\\t%0, %1, %2
1134    rsc%?\\t%0, %2, %1
1135    sbc%?\\t%0, %2, %2, lsl #1"
1136   [(set_attr "conds" "use")
1137    (set_attr "arch" "*,a,t2")
1138    (set_attr "predicable" "yes")
1139    (set_attr "predicable_short_it" "no")
1140    (set_attr "type" "adc_reg,adc_imm,alu_shift_imm")]
1143 (define_insn "*subsi3_carryin_const"
1144   [(set (match_operand:SI 0 "s_register_operand" "=r")
1145         (minus:SI (plus:SI (match_operand:SI 1 "s_register_operand" "r")
1146                            (match_operand:SI 2 "arm_not_immediate_operand" "K"))
1147                   (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1148   "TARGET_32BIT"
1149   "sbc\\t%0, %1, #%B2"
1150   [(set_attr "conds" "use")
1151    (set_attr "type" "adc_imm")]
1154 (define_insn "*subsi3_carryin_compare"
1155   [(set (reg:CC CC_REGNUM)
1156         (compare:CC (match_operand:SI 1 "s_register_operand" "r")
1157                     (match_operand:SI 2 "s_register_operand" "r")))
1158    (set (match_operand:SI 0 "s_register_operand" "=r")
1159         (minus:SI (minus:SI (match_dup 1)
1160                             (match_dup 2))
1161                   (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1162   "TARGET_32BIT"
1163   "sbcs\\t%0, %1, %2"
1164   [(set_attr "conds" "set")
1165    (set_attr "type" "adcs_reg")]
1168 (define_insn "*subsi3_carryin_compare_const"
1169   [(set (reg:CC CC_REGNUM)
1170         (compare:CC (match_operand:SI 1 "reg_or_int_operand" "r")
1171                     (match_operand:SI 2 "arm_not_operand" "K")))
1172    (set (match_operand:SI 0 "s_register_operand" "=r")
1173         (minus:SI (plus:SI (match_dup 1)
1174                            (match_dup 2))
1175                   (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1176   "TARGET_32BIT"
1177   "sbcs\\t%0, %1, #%B2"
1178   [(set_attr "conds" "set")
1179    (set_attr "type" "adcs_imm")]
1182 (define_insn "*subsi3_carryin_shift"
1183   [(set (match_operand:SI 0 "s_register_operand" "=r")
1184         (minus:SI (minus:SI
1185                   (match_operand:SI 1 "s_register_operand" "r")
1186                   (match_operator:SI 2 "shift_operator"
1187                    [(match_operand:SI 3 "s_register_operand" "r")
1188                     (match_operand:SI 4 "reg_or_int_operand" "rM")]))
1189                  (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1190   "TARGET_32BIT"
1191   "sbc%?\\t%0, %1, %3%S2"
1192   [(set_attr "conds" "use")
1193    (set_attr "predicable" "yes")
1194    (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
1195                       (const_string "alu_shift_imm")
1196                      (const_string "alu_shift_reg")))]
1199 (define_insn "*rsbsi3_carryin_shift"
1200   [(set (match_operand:SI 0 "s_register_operand" "=r")
1201         (minus:SI (minus:SI
1202                   (match_operator:SI 2 "shift_operator"
1203                    [(match_operand:SI 3 "s_register_operand" "r")
1204                     (match_operand:SI 4 "reg_or_int_operand" "rM")])
1205                    (match_operand:SI 1 "s_register_operand" "r"))
1206                  (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1207   "TARGET_ARM"
1208   "rsc%?\\t%0, %1, %3%S2"
1209   [(set_attr "conds" "use")
1210    (set_attr "predicable" "yes")
1211    (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
1212                       (const_string "alu_shift_imm")
1213                       (const_string "alu_shift_reg")))]
1216 ; transform ((x << y) - 1) to ~(~(x-1) << y)  Where X is a constant.
1217 (define_split
1218   [(set (match_operand:SI 0 "s_register_operand" "")
1219         (plus:SI (ashift:SI (match_operand:SI 1 "const_int_operand" "")
1220                             (match_operand:SI 2 "s_register_operand" ""))
1221                  (const_int -1)))
1222    (clobber (match_operand:SI 3 "s_register_operand" ""))]
1223   "TARGET_32BIT"
1224   [(set (match_dup 3) (match_dup 1))
1225    (set (match_dup 0) (not:SI (ashift:SI (match_dup 3) (match_dup 2))))]
1226   "
1227   operands[1] = GEN_INT (~(INTVAL (operands[1]) - 1));
1230 (define_expand "addsf3"
1231   [(set (match_operand:SF          0 "s_register_operand" "")
1232         (plus:SF (match_operand:SF 1 "s_register_operand" "")
1233                  (match_operand:SF 2 "s_register_operand" "")))]
1234   "TARGET_32BIT && TARGET_HARD_FLOAT"
1235   "
1238 (define_expand "adddf3"
1239   [(set (match_operand:DF          0 "s_register_operand" "")
1240         (plus:DF (match_operand:DF 1 "s_register_operand" "")
1241                  (match_operand:DF 2 "s_register_operand" "")))]
1242   "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
1243   "
1246 (define_expand "subdi3"
1247  [(parallel
1248    [(set (match_operand:DI            0 "s_register_operand" "")
1249           (minus:DI (match_operand:DI 1 "s_register_operand" "")
1250                     (match_operand:DI 2 "s_register_operand" "")))
1251     (clobber (reg:CC CC_REGNUM))])]
1252   "TARGET_EITHER"
1253   "
1254   if (TARGET_THUMB1)
1255     {
1256       if (!REG_P (operands[1]))
1257         operands[1] = force_reg (DImode, operands[1]);
1258       if (!REG_P (operands[2]))
1259         operands[2] = force_reg (DImode, operands[2]);
1260      }  
1261   "
1264 (define_insn_and_split "*arm_subdi3"
1265   [(set (match_operand:DI           0 "arm_general_register_operand" "=&r,&r,&r")
1266         (minus:DI (match_operand:DI 1 "arm_general_register_operand" "0,r,0")
1267                   (match_operand:DI 2 "arm_general_register_operand" "r,0,0")))
1268    (clobber (reg:CC CC_REGNUM))]
1269   "TARGET_32BIT && !TARGET_NEON"
1270   "#"  ; "subs\\t%Q0, %Q1, %Q2\;sbc\\t%R0, %R1, %R2"
1271   "&& (!TARGET_IWMMXT || reload_completed)"
1272   [(parallel [(set (reg:CC CC_REGNUM)
1273                    (compare:CC (match_dup 1) (match_dup 2)))
1274               (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1275    (set (match_dup 3) (minus:SI (minus:SI (match_dup 4) (match_dup 5))
1276                                (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1277   {
1278     operands[3] = gen_highpart (SImode, operands[0]);
1279     operands[0] = gen_lowpart (SImode, operands[0]);
1280     operands[4] = gen_highpart (SImode, operands[1]);
1281     operands[1] = gen_lowpart (SImode, operands[1]);
1282     operands[5] = gen_highpart (SImode, operands[2]);
1283     operands[2] = gen_lowpart (SImode, operands[2]);
1284    }
1285   [(set_attr "conds" "clob")
1286    (set_attr "length" "8")
1287    (set_attr "type" "multiple")]
1290 (define_insn_and_split "*subdi_di_zesidi"
1291   [(set (match_operand:DI           0 "s_register_operand" "=&r,&r")
1292         (minus:DI (match_operand:DI 1 "s_register_operand"  "0,r")
1293                   (zero_extend:DI
1294                    (match_operand:SI 2 "s_register_operand"  "r,r"))))
1295    (clobber (reg:CC CC_REGNUM))]
1296   "TARGET_32BIT"
1297   "#"   ; "subs\\t%Q0, %Q1, %2\;sbc\\t%R0, %R1, #0"
1298   "&& reload_completed"
1299   [(parallel [(set (reg:CC CC_REGNUM)
1300                    (compare:CC (match_dup 1) (match_dup 2)))
1301               (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1302    (set (match_dup 3) (minus:SI (plus:SI (match_dup 4) (match_dup 5))
1303                                 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1304   {
1305     operands[3] = gen_highpart (SImode, operands[0]);
1306     operands[0] = gen_lowpart (SImode, operands[0]);
1307     operands[4] = gen_highpart (SImode, operands[1]);
1308     operands[1] = gen_lowpart (SImode, operands[1]);
1309     operands[5] = GEN_INT (~0);
1310    }
1311   [(set_attr "conds" "clob")
1312    (set_attr "length" "8")
1313    (set_attr "type" "multiple")]
1316 (define_insn_and_split "*subdi_di_sesidi"
1317   [(set (match_operand:DI            0 "s_register_operand" "=&r,&r")
1318         (minus:DI (match_operand:DI  1 "s_register_operand"  "0,r")
1319                   (sign_extend:DI
1320                    (match_operand:SI 2 "s_register_operand"  "r,r"))))
1321    (clobber (reg:CC CC_REGNUM))]
1322   "TARGET_32BIT"
1323   "#"   ; "subs\\t%Q0, %Q1, %2\;sbc\\t%R0, %R1, %2, asr #31"
1324   "&& reload_completed"
1325   [(parallel [(set (reg:CC CC_REGNUM)
1326                    (compare:CC (match_dup 1) (match_dup 2)))
1327               (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1328    (set (match_dup 3) (minus:SI (minus:SI (match_dup 4)
1329                                          (ashiftrt:SI (match_dup 2)
1330                                                       (const_int 31)))
1331                                 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1332   {
1333     operands[3] = gen_highpart (SImode, operands[0]);
1334     operands[0] = gen_lowpart (SImode, operands[0]);
1335     operands[4] = gen_highpart (SImode, operands[1]);
1336     operands[1] = gen_lowpart (SImode, operands[1]);
1337   }
1338   [(set_attr "conds" "clob")
1339    (set_attr "length" "8")
1340    (set_attr "type" "multiple")]
1343 (define_insn_and_split "*subdi_zesidi_di"
1344   [(set (match_operand:DI            0 "s_register_operand" "=&r,&r")
1345         (minus:DI (zero_extend:DI
1346                    (match_operand:SI 2 "s_register_operand"  "r,r"))
1347                   (match_operand:DI  1 "s_register_operand" "0,r")))
1348    (clobber (reg:CC CC_REGNUM))]
1349   "TARGET_ARM"
1350   "#"   ; "rsbs\\t%Q0, %Q1, %2\;rsc\\t%R0, %R1, #0"
1351         ; is equivalent to:
1352         ; "subs\\t%Q0, %2, %Q1\;rsc\\t%R0, %R1, #0"
1353   "&& reload_completed"
1354   [(parallel [(set (reg:CC CC_REGNUM)
1355                    (compare:CC (match_dup 2) (match_dup 1)))
1356               (set (match_dup 0) (minus:SI (match_dup 2) (match_dup 1)))])
1357    (set (match_dup 3) (minus:SI (minus:SI (const_int 0) (match_dup 4))
1358                                (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1359   {
1360     operands[3] = gen_highpart (SImode, operands[0]);
1361     operands[0] = gen_lowpart (SImode, operands[0]);
1362     operands[4] = gen_highpart (SImode, operands[1]);
1363     operands[1] = gen_lowpart (SImode, operands[1]);
1364   }
1365   [(set_attr "conds" "clob")
1366    (set_attr "length" "8")
1367    (set_attr "type" "multiple")]
1370 (define_insn_and_split "*subdi_sesidi_di"
1371   [(set (match_operand:DI            0 "s_register_operand" "=&r,&r")
1372         (minus:DI (sign_extend:DI
1373                    (match_operand:SI 2 "s_register_operand"   "r,r"))
1374                   (match_operand:DI  1 "s_register_operand"  "0,r")))
1375    (clobber (reg:CC CC_REGNUM))]
1376   "TARGET_ARM"
1377   "#"   ; "rsbs\\t%Q0, %Q1, %2\;rsc\\t%R0, %R1, %2, asr #31"
1378         ; is equivalent to:
1379         ; "subs\\t%Q0, %2, %Q1\;rsc\\t%R0, %R1, %2, asr #31"
1380   "&& reload_completed"
1381   [(parallel [(set (reg:CC CC_REGNUM)
1382                    (compare:CC (match_dup 2) (match_dup 1)))
1383               (set (match_dup 0) (minus:SI (match_dup 2) (match_dup 1)))])
1384    (set (match_dup 3) (minus:SI (minus:SI
1385                                 (ashiftrt:SI (match_dup 2)
1386                                              (const_int 31))
1387                                 (match_dup 4))
1388                                (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1389   {
1390     operands[3] = gen_highpart (SImode, operands[0]);
1391     operands[0] = gen_lowpart (SImode, operands[0]);
1392     operands[4] = gen_highpart (SImode, operands[1]);
1393     operands[1] = gen_lowpart (SImode, operands[1]);
1394   }
1395   [(set_attr "conds" "clob")
1396    (set_attr "length" "8")
1397    (set_attr "type" "multiple")]
1400 (define_insn_and_split "*subdi_zesidi_zesidi"
1401   [(set (match_operand:DI            0 "s_register_operand" "=r")
1402         (minus:DI (zero_extend:DI
1403                    (match_operand:SI 1 "s_register_operand"  "r"))
1404                   (zero_extend:DI
1405                    (match_operand:SI 2 "s_register_operand"  "r"))))
1406    (clobber (reg:CC CC_REGNUM))]
1407   "TARGET_32BIT"
1408   "#"   ; "subs\\t%Q0, %1, %2\;sbc\\t%R0, %1, %1"
1409   "&& reload_completed"
1410   [(parallel [(set (reg:CC CC_REGNUM)
1411                    (compare:CC (match_dup 1) (match_dup 2)))
1412               (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1413    (set (match_dup 3) (minus:SI (minus:SI (match_dup 1) (match_dup 1))
1414                                (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1415   {
1416        operands[3] = gen_highpart (SImode, operands[0]);
1417        operands[0] = gen_lowpart (SImode, operands[0]);
1418   }
1419   [(set_attr "conds" "clob")
1420    (set_attr "length" "8")
1421    (set_attr "type" "multiple")]
1424 (define_expand "subsi3"
1425   [(set (match_operand:SI           0 "s_register_operand" "")
1426         (minus:SI (match_operand:SI 1 "reg_or_int_operand" "")
1427                   (match_operand:SI 2 "s_register_operand" "")))]
1428   "TARGET_EITHER"
1429   "
1430   if (CONST_INT_P (operands[1]))
1431     {
1432       if (TARGET_32BIT)
1433         {
1434           if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[1]), MINUS))
1435             operands[1] = force_reg (SImode, operands[1]);
1436           else
1437             {
1438               arm_split_constant (MINUS, SImode, NULL_RTX,
1439                                   INTVAL (operands[1]), operands[0],
1440                                   operands[2],
1441                                   optimize && can_create_pseudo_p ());
1442               DONE;
1443             }
1444         }
1445       else /* TARGET_THUMB1 */
1446         operands[1] = force_reg (SImode, operands[1]);
1447     }
1448   "
1451 ; ??? Check Thumb-2 split length
1452 (define_insn_and_split "*arm_subsi3_insn"
1453   [(set (match_operand:SI           0 "s_register_operand" "=l,l ,l ,l ,r,r,r,rk,r")
1454         (minus:SI (match_operand:SI 1 "reg_or_int_operand" "l ,0 ,l ,Pz,I,r,r,k ,?n")
1455                   (match_operand:SI 2 "reg_or_int_operand" "l ,Py,Pd,l ,r,I,r,r ,r")))]
1456   "TARGET_32BIT"
1457   "@
1458    sub%?\\t%0, %1, %2
1459    sub%?\\t%0, %2
1460    sub%?\\t%0, %1, %2
1461    rsb%?\\t%0, %2, %1
1462    rsb%?\\t%0, %2, %1
1463    sub%?\\t%0, %1, %2
1464    sub%?\\t%0, %1, %2
1465    sub%?\\t%0, %1, %2
1466    #"
1467   "&& (CONST_INT_P (operands[1])
1468        && !const_ok_for_arm (INTVAL (operands[1])))"
1469   [(clobber (const_int 0))]
1470   "
1471   arm_split_constant (MINUS, SImode, curr_insn,
1472                       INTVAL (operands[1]), operands[0], operands[2], 0);
1473   DONE;
1474   "
1475   [(set_attr "length" "4,4,4,4,4,4,4,4,16")
1476    (set_attr "arch" "t2,t2,t2,t2,*,*,*,*,*")
1477    (set_attr "predicable" "yes")
1478    (set_attr "predicable_short_it" "yes,yes,yes,yes,no,no,no,no,no")
1479    (set_attr "type" "alu_sreg,alu_sreg,alu_sreg,alu_sreg,alu_imm,alu_imm,alu_sreg,alu_sreg,multiple")]
1482 (define_peephole2
1483   [(match_scratch:SI 3 "r")
1484    (set (match_operand:SI 0 "arm_general_register_operand" "")
1485         (minus:SI (match_operand:SI 1 "const_int_operand" "")
1486                   (match_operand:SI 2 "arm_general_register_operand" "")))]
1487   "TARGET_32BIT
1488    && !const_ok_for_arm (INTVAL (operands[1]))
1489    && const_ok_for_arm (~INTVAL (operands[1]))"
1490   [(set (match_dup 3) (match_dup 1))
1491    (set (match_dup 0) (minus:SI (match_dup 3) (match_dup 2)))]
1492   ""
1495 (define_insn "subsi3_compare0"
1496   [(set (reg:CC_NOOV CC_REGNUM)
1497         (compare:CC_NOOV
1498          (minus:SI (match_operand:SI 1 "arm_rhs_operand" "r,r,I")
1499                    (match_operand:SI 2 "arm_rhs_operand" "I,r,r"))
1500          (const_int 0)))
1501    (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
1502         (minus:SI (match_dup 1) (match_dup 2)))]
1503   "TARGET_32BIT"
1504   "@
1505    subs%?\\t%0, %1, %2
1506    subs%?\\t%0, %1, %2
1507    rsbs%?\\t%0, %2, %1"
1508   [(set_attr "conds" "set")
1509    (set_attr "type"  "alus_imm,alus_sreg,alus_sreg")]
1512 (define_insn "subsi3_compare"
1513   [(set (reg:CC CC_REGNUM)
1514         (compare:CC (match_operand:SI 1 "arm_rhs_operand" "r,r,I")
1515                     (match_operand:SI 2 "arm_rhs_operand" "I,r,r")))
1516    (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
1517         (minus:SI (match_dup 1) (match_dup 2)))]
1518   "TARGET_32BIT"
1519   "@
1520    subs%?\\t%0, %1, %2
1521    subs%?\\t%0, %1, %2
1522    rsbs%?\\t%0, %2, %1"
1523   [(set_attr "conds" "set")
1524    (set_attr "type" "alus_imm,alus_sreg,alus_sreg")]
1527 (define_expand "subsf3"
1528   [(set (match_operand:SF           0 "s_register_operand" "")
1529         (minus:SF (match_operand:SF 1 "s_register_operand" "")
1530                   (match_operand:SF 2 "s_register_operand" "")))]
1531   "TARGET_32BIT && TARGET_HARD_FLOAT"
1532   "
1535 (define_expand "subdf3"
1536   [(set (match_operand:DF           0 "s_register_operand" "")
1537         (minus:DF (match_operand:DF 1 "s_register_operand" "")
1538                   (match_operand:DF 2 "s_register_operand" "")))]
1539   "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
1540   "
1544 ;; Multiplication insns
1546 (define_expand "mulhi3"
1547   [(set (match_operand:HI 0 "s_register_operand" "")
1548         (mult:HI (match_operand:HI 1 "s_register_operand" "")
1549                  (match_operand:HI 2 "s_register_operand" "")))]
1550   "TARGET_DSP_MULTIPLY"
1551   "
1552   {
1553     rtx result = gen_reg_rtx (SImode);
1554     emit_insn (gen_mulhisi3 (result, operands[1], operands[2]));
1555     emit_move_insn (operands[0], gen_lowpart (HImode, result));
1556     DONE;
1557   }"
1560 (define_expand "mulsi3"
1561   [(set (match_operand:SI          0 "s_register_operand" "")
1562         (mult:SI (match_operand:SI 2 "s_register_operand" "")
1563                  (match_operand:SI 1 "s_register_operand" "")))]
1564   "TARGET_EITHER"
1565   ""
1568 ;; Use `&' and then `0' to prevent the operands 0 and 1 being the same
1569 (define_insn "*arm_mulsi3"
1570   [(set (match_operand:SI          0 "s_register_operand" "=&r,&r")
1571         (mult:SI (match_operand:SI 2 "s_register_operand" "r,r")
1572                  (match_operand:SI 1 "s_register_operand" "%0,r")))]
1573   "TARGET_32BIT && !arm_arch6"
1574   "mul%?\\t%0, %2, %1"
1575   [(set_attr "type" "mul")
1576    (set_attr "predicable" "yes")]
1579 (define_insn "*arm_mulsi3_v6"
1580   [(set (match_operand:SI          0 "s_register_operand" "=l,l,r")
1581         (mult:SI (match_operand:SI 1 "s_register_operand" "0,l,r")
1582                  (match_operand:SI 2 "s_register_operand" "l,0,r")))]
1583   "TARGET_32BIT && arm_arch6"
1584   "mul%?\\t%0, %1, %2"
1585   [(set_attr "type" "mul")
1586    (set_attr "predicable" "yes")
1587    (set_attr "arch" "t2,t2,*")
1588    (set_attr "length" "4")
1589    (set_attr "predicable_short_it" "yes,yes,no")]
1592 (define_insn "*mulsi3_compare0"
1593   [(set (reg:CC_NOOV CC_REGNUM)
1594         (compare:CC_NOOV (mult:SI
1595                           (match_operand:SI 2 "s_register_operand" "r,r")
1596                           (match_operand:SI 1 "s_register_operand" "%0,r"))
1597                          (const_int 0)))
1598    (set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1599         (mult:SI (match_dup 2) (match_dup 1)))]
1600   "TARGET_ARM && !arm_arch6"
1601   "muls%?\\t%0, %2, %1"
1602   [(set_attr "conds" "set")
1603    (set_attr "type" "muls")]
1606 (define_insn "*mulsi3_compare0_v6"
1607   [(set (reg:CC_NOOV CC_REGNUM)
1608         (compare:CC_NOOV (mult:SI
1609                           (match_operand:SI 2 "s_register_operand" "r")
1610                           (match_operand:SI 1 "s_register_operand" "r"))
1611                          (const_int 0)))
1612    (set (match_operand:SI 0 "s_register_operand" "=r")
1613         (mult:SI (match_dup 2) (match_dup 1)))]
1614   "TARGET_ARM && arm_arch6 && optimize_size"
1615   "muls%?\\t%0, %2, %1"
1616   [(set_attr "conds" "set")
1617    (set_attr "type" "muls")]
1620 (define_insn "*mulsi_compare0_scratch"
1621   [(set (reg:CC_NOOV CC_REGNUM)
1622         (compare:CC_NOOV (mult:SI
1623                           (match_operand:SI 2 "s_register_operand" "r,r")
1624                           (match_operand:SI 1 "s_register_operand" "%0,r"))
1625                          (const_int 0)))
1626    (clobber (match_scratch:SI 0 "=&r,&r"))]
1627   "TARGET_ARM && !arm_arch6"
1628   "muls%?\\t%0, %2, %1"
1629   [(set_attr "conds" "set")
1630    (set_attr "type" "muls")]
1633 (define_insn "*mulsi_compare0_scratch_v6"
1634   [(set (reg:CC_NOOV CC_REGNUM)
1635         (compare:CC_NOOV (mult:SI
1636                           (match_operand:SI 2 "s_register_operand" "r")
1637                           (match_operand:SI 1 "s_register_operand" "r"))
1638                          (const_int 0)))
1639    (clobber (match_scratch:SI 0 "=r"))]
1640   "TARGET_ARM && arm_arch6 && optimize_size"
1641   "muls%?\\t%0, %2, %1"
1642   [(set_attr "conds" "set")
1643    (set_attr "type" "muls")]
1646 ;; Unnamed templates to match MLA instruction.
1648 (define_insn "*mulsi3addsi"
1649   [(set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r,&r")
1650         (plus:SI
1651           (mult:SI (match_operand:SI 2 "s_register_operand" "r,r,r,r")
1652                    (match_operand:SI 1 "s_register_operand" "%0,r,0,r"))
1653           (match_operand:SI 3 "s_register_operand" "r,r,0,0")))]
1654   "TARGET_32BIT && !arm_arch6"
1655   "mla%?\\t%0, %2, %1, %3"
1656   [(set_attr "type" "mla")
1657    (set_attr "predicable" "yes")]
1660 (define_insn "*mulsi3addsi_v6"
1661   [(set (match_operand:SI 0 "s_register_operand" "=r")
1662         (plus:SI
1663           (mult:SI (match_operand:SI 2 "s_register_operand" "r")
1664                    (match_operand:SI 1 "s_register_operand" "r"))
1665           (match_operand:SI 3 "s_register_operand" "r")))]
1666   "TARGET_32BIT && arm_arch6"
1667   "mla%?\\t%0, %2, %1, %3"
1668   [(set_attr "type" "mla")
1669    (set_attr "predicable" "yes")
1670    (set_attr "predicable_short_it" "no")]
1673 (define_insn "*mulsi3addsi_compare0"
1674   [(set (reg:CC_NOOV CC_REGNUM)
1675         (compare:CC_NOOV
1676          (plus:SI (mult:SI
1677                    (match_operand:SI 2 "s_register_operand" "r,r,r,r")
1678                    (match_operand:SI 1 "s_register_operand" "%0,r,0,r"))
1679                   (match_operand:SI 3 "s_register_operand" "r,r,0,0"))
1680          (const_int 0)))
1681    (set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r,&r")
1682         (plus:SI (mult:SI (match_dup 2) (match_dup 1))
1683                  (match_dup 3)))]
1684   "TARGET_ARM && arm_arch6"
1685   "mlas%?\\t%0, %2, %1, %3"
1686   [(set_attr "conds" "set")
1687    (set_attr "type" "mlas")]
1690 (define_insn "*mulsi3addsi_compare0_v6"
1691   [(set (reg:CC_NOOV CC_REGNUM)
1692         (compare:CC_NOOV
1693          (plus:SI (mult:SI
1694                    (match_operand:SI 2 "s_register_operand" "r")
1695                    (match_operand:SI 1 "s_register_operand" "r"))
1696                   (match_operand:SI 3 "s_register_operand" "r"))
1697          (const_int 0)))
1698    (set (match_operand:SI 0 "s_register_operand" "=r")
1699         (plus:SI (mult:SI (match_dup 2) (match_dup 1))
1700                  (match_dup 3)))]
1701   "TARGET_ARM && arm_arch6 && optimize_size"
1702   "mlas%?\\t%0, %2, %1, %3"
1703   [(set_attr "conds" "set")
1704    (set_attr "type" "mlas")]
1707 (define_insn "*mulsi3addsi_compare0_scratch"
1708   [(set (reg:CC_NOOV CC_REGNUM)
1709         (compare:CC_NOOV
1710          (plus:SI (mult:SI
1711                    (match_operand:SI 2 "s_register_operand" "r,r,r,r")
1712                    (match_operand:SI 1 "s_register_operand" "%0,r,0,r"))
1713                   (match_operand:SI 3 "s_register_operand" "?r,r,0,0"))
1714          (const_int 0)))
1715    (clobber (match_scratch:SI 0 "=&r,&r,&r,&r"))]
1716   "TARGET_ARM && !arm_arch6"
1717   "mlas%?\\t%0, %2, %1, %3"
1718   [(set_attr "conds" "set")
1719    (set_attr "type" "mlas")]
1722 (define_insn "*mulsi3addsi_compare0_scratch_v6"
1723   [(set (reg:CC_NOOV CC_REGNUM)
1724         (compare:CC_NOOV
1725          (plus:SI (mult:SI
1726                    (match_operand:SI 2 "s_register_operand" "r")
1727                    (match_operand:SI 1 "s_register_operand" "r"))
1728                   (match_operand:SI 3 "s_register_operand" "r"))
1729          (const_int 0)))
1730    (clobber (match_scratch:SI 0 "=r"))]
1731   "TARGET_ARM && arm_arch6 && optimize_size"
1732   "mlas%?\\t%0, %2, %1, %3"
1733   [(set_attr "conds" "set")
1734    (set_attr "type" "mlas")]
1737 (define_insn "*mulsi3subsi"
1738   [(set (match_operand:SI 0 "s_register_operand" "=r")
1739         (minus:SI
1740           (match_operand:SI 3 "s_register_operand" "r")
1741           (mult:SI (match_operand:SI 2 "s_register_operand" "r")
1742                    (match_operand:SI 1 "s_register_operand" "r"))))]
1743   "TARGET_32BIT && arm_arch_thumb2"
1744   "mls%?\\t%0, %2, %1, %3"
1745   [(set_attr "type" "mla")
1746    (set_attr "predicable" "yes")
1747    (set_attr "predicable_short_it" "no")]
1750 (define_expand "maddsidi4"
1751   [(set (match_operand:DI 0 "s_register_operand" "")
1752         (plus:DI
1753          (mult:DI
1754           (sign_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1755           (sign_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1756          (match_operand:DI 3 "s_register_operand" "")))]
1757   "TARGET_32BIT && arm_arch3m"
1758   "")
1760 (define_insn "*mulsidi3adddi"
1761   [(set (match_operand:DI 0 "s_register_operand" "=&r")
1762         (plus:DI
1763          (mult:DI
1764           (sign_extend:DI (match_operand:SI 2 "s_register_operand" "%r"))
1765           (sign_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1766          (match_operand:DI 1 "s_register_operand" "0")))]
1767   "TARGET_32BIT && arm_arch3m && !arm_arch6"
1768   "smlal%?\\t%Q0, %R0, %3, %2"
1769   [(set_attr "type" "smlal")
1770    (set_attr "predicable" "yes")]
1773 (define_insn "*mulsidi3adddi_v6"
1774   [(set (match_operand:DI 0 "s_register_operand" "=r")
1775         (plus:DI
1776          (mult:DI
1777           (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r"))
1778           (sign_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1779          (match_operand:DI 1 "s_register_operand" "0")))]
1780   "TARGET_32BIT && arm_arch6"
1781   "smlal%?\\t%Q0, %R0, %3, %2"
1782   [(set_attr "type" "smlal")
1783    (set_attr "predicable" "yes")
1784    (set_attr "predicable_short_it" "no")]
1787 ;; 32x32->64 widening multiply.
1788 ;; As with mulsi3, the only difference between the v3-5 and v6+
1789 ;; versions of these patterns is the requirement that the output not
1790 ;; overlap the inputs, but that still means we have to have a named
1791 ;; expander and two different starred insns.
1793 (define_expand "mulsidi3"
1794   [(set (match_operand:DI 0 "s_register_operand" "")
1795         (mult:DI
1796          (sign_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1797          (sign_extend:DI (match_operand:SI 2 "s_register_operand" ""))))]
1798   "TARGET_32BIT && arm_arch3m"
1799   ""
1802 (define_insn "*mulsidi3_nov6"
1803   [(set (match_operand:DI 0 "s_register_operand" "=&r")
1804         (mult:DI
1805          (sign_extend:DI (match_operand:SI 1 "s_register_operand" "%r"))
1806          (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1807   "TARGET_32BIT && arm_arch3m && !arm_arch6"
1808   "smull%?\\t%Q0, %R0, %1, %2"
1809   [(set_attr "type" "smull")
1810    (set_attr "predicable" "yes")]
1813 (define_insn "*mulsidi3_v6"
1814   [(set (match_operand:DI 0 "s_register_operand" "=r")
1815         (mult:DI
1816          (sign_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1817          (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1818   "TARGET_32BIT && arm_arch6"
1819   "smull%?\\t%Q0, %R0, %1, %2"
1820   [(set_attr "type" "smull")
1821    (set_attr "predicable" "yes")
1822    (set_attr "predicable_short_it" "no")]
1825 (define_expand "umulsidi3"
1826   [(set (match_operand:DI 0 "s_register_operand" "")
1827         (mult:DI
1828          (zero_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1829          (zero_extend:DI (match_operand:SI 2 "s_register_operand" ""))))]
1830   "TARGET_32BIT && arm_arch3m"
1831   ""
1834 (define_insn "*umulsidi3_nov6"
1835   [(set (match_operand:DI 0 "s_register_operand" "=&r")
1836         (mult:DI
1837          (zero_extend:DI (match_operand:SI 1 "s_register_operand" "%r"))
1838          (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1839   "TARGET_32BIT && arm_arch3m && !arm_arch6"
1840   "umull%?\\t%Q0, %R0, %1, %2"
1841   [(set_attr "type" "umull")
1842    (set_attr "predicable" "yes")]
1845 (define_insn "*umulsidi3_v6"
1846   [(set (match_operand:DI 0 "s_register_operand" "=r")
1847         (mult:DI
1848          (zero_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1849          (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1850   "TARGET_32BIT && arm_arch6"
1851   "umull%?\\t%Q0, %R0, %1, %2"
1852   [(set_attr "type" "umull")
1853    (set_attr "predicable" "yes")
1854    (set_attr "predicable_short_it" "no")]
1857 (define_expand "umaddsidi4"
1858   [(set (match_operand:DI 0 "s_register_operand" "")
1859         (plus:DI
1860          (mult:DI
1861           (zero_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1862           (zero_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1863          (match_operand:DI 3 "s_register_operand" "")))]
1864   "TARGET_32BIT && arm_arch3m"
1865   "")
1867 (define_insn "*umulsidi3adddi"
1868   [(set (match_operand:DI 0 "s_register_operand" "=&r")
1869         (plus:DI
1870          (mult:DI
1871           (zero_extend:DI (match_operand:SI 2 "s_register_operand" "%r"))
1872           (zero_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1873          (match_operand:DI 1 "s_register_operand" "0")))]
1874   "TARGET_32BIT && arm_arch3m && !arm_arch6"
1875   "umlal%?\\t%Q0, %R0, %3, %2"
1876   [(set_attr "type" "umlal")
1877    (set_attr "predicable" "yes")]
1880 (define_insn "*umulsidi3adddi_v6"
1881   [(set (match_operand:DI 0 "s_register_operand" "=r")
1882         (plus:DI
1883          (mult:DI
1884           (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r"))
1885           (zero_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1886          (match_operand:DI 1 "s_register_operand" "0")))]
1887   "TARGET_32BIT && arm_arch6"
1888   "umlal%?\\t%Q0, %R0, %3, %2"
1889   [(set_attr "type" "umlal")
1890    (set_attr "predicable" "yes")
1891    (set_attr "predicable_short_it" "no")]
1894 (define_expand "smulsi3_highpart"
1895   [(parallel
1896     [(set (match_operand:SI 0 "s_register_operand" "")
1897           (truncate:SI
1898            (lshiftrt:DI
1899             (mult:DI
1900              (sign_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1901              (sign_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1902             (const_int 32))))
1903      (clobber (match_scratch:SI 3 ""))])]
1904   "TARGET_32BIT && arm_arch3m"
1905   ""
1908 (define_insn "*smulsi3_highpart_nov6"
1909   [(set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1910         (truncate:SI
1911          (lshiftrt:DI
1912           (mult:DI
1913            (sign_extend:DI (match_operand:SI 1 "s_register_operand" "%0,r"))
1914            (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r,r")))
1915           (const_int 32))))
1916    (clobber (match_scratch:SI 3 "=&r,&r"))]
1917   "TARGET_32BIT && arm_arch3m && !arm_arch6"
1918   "smull%?\\t%3, %0, %2, %1"
1919   [(set_attr "type" "smull")
1920    (set_attr "predicable" "yes")]
1923 (define_insn "*smulsi3_highpart_v6"
1924   [(set (match_operand:SI 0 "s_register_operand" "=r")
1925         (truncate:SI
1926          (lshiftrt:DI
1927           (mult:DI
1928            (sign_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1929            (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r")))
1930           (const_int 32))))
1931    (clobber (match_scratch:SI 3 "=r"))]
1932   "TARGET_32BIT && arm_arch6"
1933   "smull%?\\t%3, %0, %2, %1"
1934   [(set_attr "type" "smull")
1935    (set_attr "predicable" "yes")
1936    (set_attr "predicable_short_it" "no")]
1939 (define_expand "umulsi3_highpart"
1940   [(parallel
1941     [(set (match_operand:SI 0 "s_register_operand" "")
1942           (truncate:SI
1943            (lshiftrt:DI
1944             (mult:DI
1945              (zero_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1946               (zero_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1947             (const_int 32))))
1948      (clobber (match_scratch:SI 3 ""))])]
1949   "TARGET_32BIT && arm_arch3m"
1950   ""
1953 (define_insn "*umulsi3_highpart_nov6"
1954   [(set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1955         (truncate:SI
1956          (lshiftrt:DI
1957           (mult:DI
1958            (zero_extend:DI (match_operand:SI 1 "s_register_operand" "%0,r"))
1959            (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r,r")))
1960           (const_int 32))))
1961    (clobber (match_scratch:SI 3 "=&r,&r"))]
1962   "TARGET_32BIT && arm_arch3m && !arm_arch6"
1963   "umull%?\\t%3, %0, %2, %1"
1964   [(set_attr "type" "umull")
1965    (set_attr "predicable" "yes")]
1968 (define_insn "*umulsi3_highpart_v6"
1969   [(set (match_operand:SI 0 "s_register_operand" "=r")
1970         (truncate:SI
1971          (lshiftrt:DI
1972           (mult:DI
1973            (zero_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1974            (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r")))
1975           (const_int 32))))
1976    (clobber (match_scratch:SI 3 "=r"))]
1977   "TARGET_32BIT && arm_arch6"
1978   "umull%?\\t%3, %0, %2, %1"
1979   [(set_attr "type" "umull")
1980    (set_attr "predicable" "yes")
1981    (set_attr "predicable_short_it" "no")]
1984 (define_insn "mulhisi3"
1985   [(set (match_operand:SI 0 "s_register_operand" "=r")
1986         (mult:SI (sign_extend:SI
1987                   (match_operand:HI 1 "s_register_operand" "%r"))
1988                  (sign_extend:SI
1989                   (match_operand:HI 2 "s_register_operand" "r"))))]
1990   "TARGET_DSP_MULTIPLY"
1991   "smulbb%?\\t%0, %1, %2"
1992   [(set_attr "type" "smulxy")
1993    (set_attr "predicable" "yes")]
1996 (define_insn "*mulhisi3tb"
1997   [(set (match_operand:SI 0 "s_register_operand" "=r")
1998         (mult:SI (ashiftrt:SI
1999                   (match_operand:SI 1 "s_register_operand" "r")
2000                   (const_int 16))
2001                  (sign_extend:SI
2002                   (match_operand:HI 2 "s_register_operand" "r"))))]
2003   "TARGET_DSP_MULTIPLY"
2004   "smultb%?\\t%0, %1, %2"
2005   [(set_attr "type" "smulxy")
2006    (set_attr "predicable" "yes")
2007    (set_attr "predicable_short_it" "no")]
2010 (define_insn "*mulhisi3bt"
2011   [(set (match_operand:SI 0 "s_register_operand" "=r")
2012         (mult:SI (sign_extend:SI
2013                   (match_operand:HI 1 "s_register_operand" "r"))
2014                  (ashiftrt:SI
2015                   (match_operand:SI 2 "s_register_operand" "r")
2016                   (const_int 16))))]
2017   "TARGET_DSP_MULTIPLY"
2018   "smulbt%?\\t%0, %1, %2"
2019   [(set_attr "type" "smulxy")
2020    (set_attr "predicable" "yes")
2021    (set_attr "predicable_short_it" "no")]
2024 (define_insn "*mulhisi3tt"
2025   [(set (match_operand:SI 0 "s_register_operand" "=r")
2026         (mult:SI (ashiftrt:SI
2027                   (match_operand:SI 1 "s_register_operand" "r")
2028                   (const_int 16))
2029                  (ashiftrt:SI
2030                   (match_operand:SI 2 "s_register_operand" "r")
2031                   (const_int 16))))]
2032   "TARGET_DSP_MULTIPLY"
2033   "smultt%?\\t%0, %1, %2"
2034   [(set_attr "type" "smulxy")
2035    (set_attr "predicable" "yes")
2036    (set_attr "predicable_short_it" "no")]
2039 (define_insn "maddhisi4"
2040   [(set (match_operand:SI 0 "s_register_operand" "=r")
2041         (plus:SI (mult:SI (sign_extend:SI
2042                            (match_operand:HI 1 "s_register_operand" "r"))
2043                           (sign_extend:SI
2044                            (match_operand:HI 2 "s_register_operand" "r")))
2045                  (match_operand:SI 3 "s_register_operand" "r")))]
2046   "TARGET_DSP_MULTIPLY"
2047   "smlabb%?\\t%0, %1, %2, %3"
2048   [(set_attr "type" "smlaxy")
2049    (set_attr "predicable" "yes")
2050    (set_attr "predicable_short_it" "no")]
2053 ;; Note: there is no maddhisi4ibt because this one is canonical form
2054 (define_insn "*maddhisi4tb"
2055   [(set (match_operand:SI 0 "s_register_operand" "=r")
2056         (plus:SI (mult:SI (ashiftrt:SI
2057                            (match_operand:SI 1 "s_register_operand" "r")
2058                            (const_int 16))
2059                           (sign_extend:SI
2060                            (match_operand:HI 2 "s_register_operand" "r")))
2061                  (match_operand:SI 3 "s_register_operand" "r")))]
2062   "TARGET_DSP_MULTIPLY"
2063   "smlatb%?\\t%0, %1, %2, %3"
2064   [(set_attr "type" "smlaxy")
2065    (set_attr "predicable" "yes")
2066    (set_attr "predicable_short_it" "no")]
2069 (define_insn "*maddhisi4tt"
2070   [(set (match_operand:SI 0 "s_register_operand" "=r")
2071         (plus:SI (mult:SI (ashiftrt:SI
2072                            (match_operand:SI 1 "s_register_operand" "r")
2073                            (const_int 16))
2074                           (ashiftrt:SI
2075                            (match_operand:SI 2 "s_register_operand" "r")
2076                            (const_int 16)))
2077                  (match_operand:SI 3 "s_register_operand" "r")))]
2078   "TARGET_DSP_MULTIPLY"
2079   "smlatt%?\\t%0, %1, %2, %3"
2080   [(set_attr "type" "smlaxy")
2081    (set_attr "predicable" "yes")
2082    (set_attr "predicable_short_it" "no")]
2085 (define_insn "maddhidi4"
2086   [(set (match_operand:DI 0 "s_register_operand" "=r")
2087         (plus:DI
2088           (mult:DI (sign_extend:DI
2089                     (match_operand:HI 1 "s_register_operand" "r"))
2090                    (sign_extend:DI
2091                     (match_operand:HI 2 "s_register_operand" "r")))
2092           (match_operand:DI 3 "s_register_operand" "0")))]
2093   "TARGET_DSP_MULTIPLY"
2094   "smlalbb%?\\t%Q0, %R0, %1, %2"
2095   [(set_attr "type" "smlalxy")
2096    (set_attr "predicable" "yes")
2097    (set_attr "predicable_short_it" "no")])
2099 ;; Note: there is no maddhidi4ibt because this one is canonical form
2100 (define_insn "*maddhidi4tb"
2101   [(set (match_operand:DI 0 "s_register_operand" "=r")
2102         (plus:DI
2103           (mult:DI (sign_extend:DI
2104                     (ashiftrt:SI
2105                      (match_operand:SI 1 "s_register_operand" "r")
2106                      (const_int 16)))
2107                    (sign_extend:DI
2108                     (match_operand:HI 2 "s_register_operand" "r")))
2109           (match_operand:DI 3 "s_register_operand" "0")))]
2110   "TARGET_DSP_MULTIPLY"
2111   "smlaltb%?\\t%Q0, %R0, %1, %2"
2112   [(set_attr "type" "smlalxy")
2113    (set_attr "predicable" "yes")
2114    (set_attr "predicable_short_it" "no")])
2116 (define_insn "*maddhidi4tt"
2117   [(set (match_operand:DI 0 "s_register_operand" "=r")
2118         (plus:DI
2119           (mult:DI (sign_extend:DI
2120                     (ashiftrt:SI
2121                      (match_operand:SI 1 "s_register_operand" "r")
2122                      (const_int 16)))
2123                    (sign_extend:DI
2124                     (ashiftrt:SI
2125                      (match_operand:SI 2 "s_register_operand" "r")
2126                      (const_int 16))))
2127           (match_operand:DI 3 "s_register_operand" "0")))]
2128   "TARGET_DSP_MULTIPLY"
2129   "smlaltt%?\\t%Q0, %R0, %1, %2"
2130   [(set_attr "type" "smlalxy")
2131    (set_attr "predicable" "yes")
2132    (set_attr "predicable_short_it" "no")])
2134 (define_expand "mulsf3"
2135   [(set (match_operand:SF          0 "s_register_operand" "")
2136         (mult:SF (match_operand:SF 1 "s_register_operand" "")
2137                  (match_operand:SF 2 "s_register_operand" "")))]
2138   "TARGET_32BIT && TARGET_HARD_FLOAT"
2139   "
2142 (define_expand "muldf3"
2143   [(set (match_operand:DF          0 "s_register_operand" "")
2144         (mult:DF (match_operand:DF 1 "s_register_operand" "")
2145                  (match_operand:DF 2 "s_register_operand" "")))]
2146   "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
2147   "
2150 ;; Division insns
2152 (define_expand "divsf3"
2153   [(set (match_operand:SF 0 "s_register_operand" "")
2154         (div:SF (match_operand:SF 1 "s_register_operand" "")
2155                 (match_operand:SF 2 "s_register_operand" "")))]
2156   "TARGET_32BIT && TARGET_HARD_FLOAT"
2157   "")
2159 (define_expand "divdf3"
2160   [(set (match_operand:DF 0 "s_register_operand" "")
2161         (div:DF (match_operand:DF 1 "s_register_operand" "")
2162                 (match_operand:DF 2 "s_register_operand" "")))]
2163   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
2164   "")
2166 ;; Boolean and,ior,xor insns
2168 ;; Split up double word logical operations
2170 ;; Split up simple DImode logical operations.  Simply perform the logical
2171 ;; operation on the upper and lower halves of the registers.
2172 (define_split
2173   [(set (match_operand:DI 0 "s_register_operand" "")
2174         (match_operator:DI 6 "logical_binary_operator"
2175           [(match_operand:DI 1 "s_register_operand" "")
2176            (match_operand:DI 2 "s_register_operand" "")]))]
2177   "TARGET_32BIT && reload_completed
2178    && ! (TARGET_NEON && IS_VFP_REGNUM (REGNO (operands[0])))
2179    && ! IS_IWMMXT_REGNUM (REGNO (operands[0]))"
2180   [(set (match_dup 0) (match_op_dup:SI 6 [(match_dup 1) (match_dup 2)]))
2181    (set (match_dup 3) (match_op_dup:SI 6 [(match_dup 4) (match_dup 5)]))]
2182   "
2183   {
2184     operands[3] = gen_highpart (SImode, operands[0]);
2185     operands[0] = gen_lowpart (SImode, operands[0]);
2186     operands[4] = gen_highpart (SImode, operands[1]);
2187     operands[1] = gen_lowpart (SImode, operands[1]);
2188     operands[5] = gen_highpart (SImode, operands[2]);
2189     operands[2] = gen_lowpart (SImode, operands[2]);
2190   }"
2193 (define_split
2194   [(set (match_operand:DI 0 "s_register_operand" "")
2195         (match_operator:DI 6 "logical_binary_operator"
2196           [(sign_extend:DI (match_operand:SI 2 "s_register_operand" ""))
2197            (match_operand:DI 1 "s_register_operand" "")]))]
2198   "TARGET_32BIT && reload_completed"
2199   [(set (match_dup 0) (match_op_dup:SI 6 [(match_dup 1) (match_dup 2)]))
2200    (set (match_dup 3) (match_op_dup:SI 6
2201                         [(ashiftrt:SI (match_dup 2) (const_int 31))
2202                          (match_dup 4)]))]
2203   "
2204   {
2205     operands[3] = gen_highpart (SImode, operands[0]);
2206     operands[0] = gen_lowpart (SImode, operands[0]);
2207     operands[4] = gen_highpart (SImode, operands[1]);
2208     operands[1] = gen_lowpart (SImode, operands[1]);
2209     operands[5] = gen_highpart (SImode, operands[2]);
2210     operands[2] = gen_lowpart (SImode, operands[2]);
2211   }"
2214 ;; The zero extend of operand 2 means we can just copy the high part of
2215 ;; operand1 into operand0.
2216 (define_split
2217   [(set (match_operand:DI 0 "s_register_operand" "")
2218         (ior:DI
2219           (zero_extend:DI (match_operand:SI 2 "s_register_operand" ""))
2220           (match_operand:DI 1 "s_register_operand" "")))]
2221   "TARGET_32BIT && operands[0] != operands[1] && reload_completed"
2222   [(set (match_dup 0) (ior:SI (match_dup 1) (match_dup 2)))
2223    (set (match_dup 3) (match_dup 4))]
2224   "
2225   {
2226     operands[4] = gen_highpart (SImode, operands[1]);
2227     operands[3] = gen_highpart (SImode, operands[0]);
2228     operands[0] = gen_lowpart (SImode, operands[0]);
2229     operands[1] = gen_lowpart (SImode, operands[1]);
2230   }"
2233 ;; The zero extend of operand 2 means we can just copy the high part of
2234 ;; operand1 into operand0.
2235 (define_split
2236   [(set (match_operand:DI 0 "s_register_operand" "")
2237         (xor:DI
2238           (zero_extend:DI (match_operand:SI 2 "s_register_operand" ""))
2239           (match_operand:DI 1 "s_register_operand" "")))]
2240   "TARGET_32BIT && operands[0] != operands[1] && reload_completed"
2241   [(set (match_dup 0) (xor:SI (match_dup 1) (match_dup 2)))
2242    (set (match_dup 3) (match_dup 4))]
2243   "
2244   {
2245     operands[4] = gen_highpart (SImode, operands[1]);
2246     operands[3] = gen_highpart (SImode, operands[0]);
2247     operands[0] = gen_lowpart (SImode, operands[0]);
2248     operands[1] = gen_lowpart (SImode, operands[1]);
2249   }"
2252 (define_expand "anddi3"
2253   [(set (match_operand:DI         0 "s_register_operand" "")
2254         (and:DI (match_operand:DI 1 "s_register_operand" "")
2255                 (match_operand:DI 2 "neon_inv_logic_op2" "")))]
2256   "TARGET_32BIT"
2257   "
2258   if (!TARGET_NEON && !TARGET_IWMMXT)
2259     {
2260       rtx low  = simplify_gen_binary (AND, SImode,
2261                                       gen_lowpart (SImode, operands[1]),
2262                                       gen_lowpart (SImode, operands[2]));
2263       rtx high = simplify_gen_binary (AND, SImode,
2264                                       gen_highpart (SImode, operands[1]),
2265                                       gen_highpart_mode (SImode, DImode,
2266                                                          operands[2]));
2268       emit_insn (gen_rtx_SET (gen_lowpart (SImode, operands[0]), low));
2269       emit_insn (gen_rtx_SET (gen_highpart (SImode, operands[0]), high));
2271       DONE;
2272     }
2273   /* Otherwise expand pattern as above.  */
2274   "
2277 (define_insn_and_split "*anddi3_insn"
2278   [(set (match_operand:DI         0 "s_register_operand"     "=w,w ,&r,&r,&r,&r,?w,?w")
2279         (and:DI (match_operand:DI 1 "s_register_operand"     "%w,0 ,0 ,r ,0 ,r ,w ,0")
2280                 (match_operand:DI 2 "arm_anddi_operand_neon" "w ,DL,r ,r ,De,De,w ,DL")))]
2281   "TARGET_32BIT && !TARGET_IWMMXT"
2283   switch (which_alternative)
2284     {
2285     case 0: /* fall through */
2286     case 6: return "vand\t%P0, %P1, %P2";
2287     case 1: /* fall through */
2288     case 7: return neon_output_logic_immediate ("vand", &operands[2],
2289                     DImode, 1, VALID_NEON_QREG_MODE (DImode));
2290     case 2:
2291     case 3:
2292     case 4:
2293     case 5: /* fall through */
2294       return "#";
2295     default: gcc_unreachable ();
2296     }
2298   "TARGET_32BIT && !TARGET_IWMMXT && reload_completed
2299    && !(IS_VFP_REGNUM (REGNO (operands[0])))"
2300   [(set (match_dup 3) (match_dup 4))
2301    (set (match_dup 5) (match_dup 6))]
2302   "
2303   {
2304     operands[3] = gen_lowpart (SImode, operands[0]);
2305     operands[5] = gen_highpart (SImode, operands[0]);
2307     operands[4] = simplify_gen_binary (AND, SImode,
2308                                            gen_lowpart (SImode, operands[1]),
2309                                            gen_lowpart (SImode, operands[2]));
2310     operands[6] = simplify_gen_binary (AND, SImode,
2311                                            gen_highpart (SImode, operands[1]),
2312                                            gen_highpart_mode (SImode, DImode, operands[2]));
2314   }"
2315   [(set_attr "type" "neon_logic,neon_logic,multiple,multiple,\
2316                      multiple,multiple,neon_logic,neon_logic")
2317    (set_attr "arch" "neon_for_64bits,neon_for_64bits,*,*,*,*,
2318                      avoid_neon_for_64bits,avoid_neon_for_64bits")
2319    (set_attr "length" "*,*,8,8,8,8,*,*")
2320   ]
2323 (define_insn_and_split "*anddi_zesidi_di"
2324   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2325         (and:DI (zero_extend:DI
2326                  (match_operand:SI 2 "s_register_operand" "r,r"))
2327                 (match_operand:DI 1 "s_register_operand" "0,r")))]
2328   "TARGET_32BIT"
2329   "#"
2330   "TARGET_32BIT && reload_completed"
2331   ; The zero extend of operand 2 clears the high word of the output
2332   ; operand.
2333   [(set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))
2334    (set (match_dup 3) (const_int 0))]
2335   "
2336   {
2337     operands[3] = gen_highpart (SImode, operands[0]);
2338     operands[0] = gen_lowpart (SImode, operands[0]);
2339     operands[1] = gen_lowpart (SImode, operands[1]);
2340   }"
2341   [(set_attr "length" "8")
2342    (set_attr "type" "multiple")]
2345 (define_insn "*anddi_sesdi_di"
2346   [(set (match_operand:DI          0 "s_register_operand" "=&r,&r")
2347         (and:DI (sign_extend:DI
2348                  (match_operand:SI 2 "s_register_operand" "r,r"))
2349                 (match_operand:DI  1 "s_register_operand" "0,r")))]
2350   "TARGET_32BIT"
2351   "#"
2352   [(set_attr "length" "8")
2353    (set_attr "type" "multiple")]
2356 (define_expand "andsi3"
2357   [(set (match_operand:SI         0 "s_register_operand" "")
2358         (and:SI (match_operand:SI 1 "s_register_operand" "")
2359                 (match_operand:SI 2 "reg_or_int_operand" "")))]
2360   "TARGET_EITHER"
2361   "
2362   if (TARGET_32BIT)
2363     {
2364       if (CONST_INT_P (operands[2]))
2365         {
2366           if (INTVAL (operands[2]) == 255 && arm_arch6)
2367             {
2368               operands[1] = convert_to_mode (QImode, operands[1], 1);
2369               emit_insn (gen_thumb2_zero_extendqisi2_v6 (operands[0],
2370                                                          operands[1]));
2371               DONE;
2372             }
2373           else if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[2]), AND))
2374             operands[2] = force_reg (SImode, operands[2]);
2375           else
2376             {
2377               arm_split_constant (AND, SImode, NULL_RTX,
2378                                   INTVAL (operands[2]), operands[0],
2379                                   operands[1],
2380                                   optimize && can_create_pseudo_p ());
2382               DONE;
2383             }
2384         }
2385     }
2386   else /* TARGET_THUMB1 */
2387     {
2388       if (!CONST_INT_P (operands[2]))
2389         {
2390           rtx tmp = force_reg (SImode, operands[2]);
2391           if (rtx_equal_p (operands[0], operands[1]))
2392             operands[2] = tmp;
2393           else
2394             {
2395               operands[2] = operands[1];
2396               operands[1] = tmp;
2397             }
2398         }
2399       else
2400         {
2401           int i;
2402           
2403           if (((unsigned HOST_WIDE_INT) ~INTVAL (operands[2])) < 256)
2404             {
2405               operands[2] = force_reg (SImode,
2406                                        GEN_INT (~INTVAL (operands[2])));
2407               
2408               emit_insn (gen_thumb1_bicsi3 (operands[0], operands[2], operands[1]));
2409               
2410               DONE;
2411             }
2413           for (i = 9; i <= 31; i++)
2414             {
2415               if ((HOST_WIDE_INT_1 << i) - 1 == INTVAL (operands[2]))
2416                 {
2417                   emit_insn (gen_extzv (operands[0], operands[1], GEN_INT (i),
2418                                         const0_rtx));
2419                   DONE;
2420                 }
2421               else if ((HOST_WIDE_INT_1 << i) - 1
2422                        == ~INTVAL (operands[2]))
2423                 {
2424                   rtx shift = GEN_INT (i);
2425                   rtx reg = gen_reg_rtx (SImode);
2426                 
2427                   emit_insn (gen_lshrsi3 (reg, operands[1], shift));
2428                   emit_insn (gen_ashlsi3 (operands[0], reg, shift));
2429                   
2430                   DONE;
2431                 }
2432             }
2434           operands[2] = force_reg (SImode, operands[2]);
2435         }
2436     }
2437   "
2440 ; ??? Check split length for Thumb-2
2441 (define_insn_and_split "*arm_andsi3_insn"
2442   [(set (match_operand:SI         0 "s_register_operand" "=r,l,r,r,r")
2443         (and:SI (match_operand:SI 1 "s_register_operand" "%r,0,r,r,r")
2444                 (match_operand:SI 2 "reg_or_int_operand" "I,l,K,r,?n")))]
2445   "TARGET_32BIT"
2446   "@
2447    and%?\\t%0, %1, %2
2448    and%?\\t%0, %1, %2
2449    bic%?\\t%0, %1, #%B2
2450    and%?\\t%0, %1, %2
2451    #"
2452   "TARGET_32BIT
2453    && CONST_INT_P (operands[2])
2454    && !(const_ok_for_arm (INTVAL (operands[2]))
2455         || const_ok_for_arm (~INTVAL (operands[2])))"
2456   [(clobber (const_int 0))]
2457   "
2458   arm_split_constant  (AND, SImode, curr_insn, 
2459                        INTVAL (operands[2]), operands[0], operands[1], 0);
2460   DONE;
2461   "
2462   [(set_attr "length" "4,4,4,4,16")
2463    (set_attr "predicable" "yes")
2464    (set_attr "predicable_short_it" "no,yes,no,no,no")
2465    (set_attr "type" "logic_imm,logic_imm,logic_reg,logic_reg,logic_imm")]
2468 (define_insn "*andsi3_compare0"
2469   [(set (reg:CC_NOOV CC_REGNUM)
2470         (compare:CC_NOOV
2471          (and:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
2472                  (match_operand:SI 2 "arm_not_operand" "I,K,r"))
2473          (const_int 0)))
2474    (set (match_operand:SI          0 "s_register_operand" "=r,r,r")
2475         (and:SI (match_dup 1) (match_dup 2)))]
2476   "TARGET_32BIT"
2477   "@
2478    ands%?\\t%0, %1, %2
2479    bics%?\\t%0, %1, #%B2
2480    ands%?\\t%0, %1, %2"
2481   [(set_attr "conds" "set")
2482    (set_attr "type" "logics_imm,logics_imm,logics_reg")]
2485 (define_insn "*andsi3_compare0_scratch"
2486   [(set (reg:CC_NOOV CC_REGNUM)
2487         (compare:CC_NOOV
2488          (and:SI (match_operand:SI 0 "s_register_operand" "r,r,r")
2489                  (match_operand:SI 1 "arm_not_operand" "I,K,r"))
2490          (const_int 0)))
2491    (clobber (match_scratch:SI 2 "=X,r,X"))]
2492   "TARGET_32BIT"
2493   "@
2494    tst%?\\t%0, %1
2495    bics%?\\t%2, %0, #%B1
2496    tst%?\\t%0, %1"
2497   [(set_attr "conds" "set")
2498    (set_attr "type"  "logics_imm,logics_imm,logics_reg")]
2501 (define_insn "*zeroextractsi_compare0_scratch"
2502   [(set (reg:CC_NOOV CC_REGNUM)
2503         (compare:CC_NOOV (zero_extract:SI
2504                           (match_operand:SI 0 "s_register_operand" "r")
2505                           (match_operand 1 "const_int_operand" "n")
2506                           (match_operand 2 "const_int_operand" "n"))
2507                          (const_int 0)))]
2508   "TARGET_32BIT
2509   && (INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) < 32
2510       && INTVAL (operands[1]) > 0 
2511       && INTVAL (operands[1]) + (INTVAL (operands[2]) & 1) <= 8
2512       && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32)"
2513   "*
2514   operands[1] = GEN_INT (((1 << INTVAL (operands[1])) - 1)
2515                          << INTVAL (operands[2]));
2516   output_asm_insn (\"tst%?\\t%0, %1\", operands);
2517   return \"\";
2518   "
2519   [(set_attr "conds" "set")
2520    (set_attr "predicable" "yes")
2521    (set_attr "predicable_short_it" "no")
2522    (set_attr "type" "logics_imm")]
2525 (define_insn_and_split "*ne_zeroextractsi"
2526   [(set (match_operand:SI 0 "s_register_operand" "=r")
2527         (ne:SI (zero_extract:SI
2528                 (match_operand:SI 1 "s_register_operand" "r")
2529                 (match_operand:SI 2 "const_int_operand" "n")
2530                 (match_operand:SI 3 "const_int_operand" "n"))
2531                (const_int 0)))
2532    (clobber (reg:CC CC_REGNUM))]
2533   "TARGET_32BIT
2534    && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2535        && INTVAL (operands[2]) > 0 
2536        && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2537        && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)"
2538   "#"
2539   "TARGET_32BIT
2540    && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2541        && INTVAL (operands[2]) > 0 
2542        && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2543        && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)"
2544   [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2545                    (compare:CC_NOOV (and:SI (match_dup 1) (match_dup 2))
2546                                     (const_int 0)))
2547               (set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))])
2548    (set (match_dup 0)
2549         (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2550                          (match_dup 0) (const_int 1)))]
2551   "
2552   operands[2] = GEN_INT (((1 << INTVAL (operands[2])) - 1)
2553                          << INTVAL (operands[3])); 
2554   "
2555   [(set_attr "conds" "clob")
2556    (set (attr "length")
2557         (if_then_else (eq_attr "is_thumb" "yes")
2558                       (const_int 12)
2559                       (const_int 8)))
2560    (set_attr "type" "multiple")]
2563 (define_insn_and_split "*ne_zeroextractsi_shifted"
2564   [(set (match_operand:SI 0 "s_register_operand" "=r")
2565         (ne:SI (zero_extract:SI
2566                 (match_operand:SI 1 "s_register_operand" "r")
2567                 (match_operand:SI 2 "const_int_operand" "n")
2568                 (const_int 0))
2569                (const_int 0)))
2570    (clobber (reg:CC CC_REGNUM))]
2571   "TARGET_ARM"
2572   "#"
2573   "TARGET_ARM"
2574   [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2575                    (compare:CC_NOOV (ashift:SI (match_dup 1) (match_dup 2))
2576                                     (const_int 0)))
2577               (set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))])
2578    (set (match_dup 0)
2579         (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2580                          (match_dup 0) (const_int 1)))]
2581   "
2582   operands[2] = GEN_INT (32 - INTVAL (operands[2]));
2583   "
2584   [(set_attr "conds" "clob")
2585    (set_attr "length" "8")
2586    (set_attr "type" "multiple")]
2589 (define_insn_and_split "*ite_ne_zeroextractsi"
2590   [(set (match_operand:SI 0 "s_register_operand" "=r")
2591         (if_then_else:SI (ne (zero_extract:SI
2592                               (match_operand:SI 1 "s_register_operand" "r")
2593                               (match_operand:SI 2 "const_int_operand" "n")
2594                               (match_operand:SI 3 "const_int_operand" "n"))
2595                              (const_int 0))
2596                          (match_operand:SI 4 "arm_not_operand" "rIK")
2597                          (const_int 0)))
2598    (clobber (reg:CC CC_REGNUM))]
2599   "TARGET_ARM
2600    && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2601        && INTVAL (operands[2]) > 0 
2602        && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2603        && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)
2604    && !reg_overlap_mentioned_p (operands[0], operands[4])"
2605   "#"
2606   "TARGET_ARM
2607    && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2608        && INTVAL (operands[2]) > 0 
2609        && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2610        && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)
2611    && !reg_overlap_mentioned_p (operands[0], operands[4])"
2612   [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2613                    (compare:CC_NOOV (and:SI (match_dup 1) (match_dup 2))
2614                                     (const_int 0)))
2615               (set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))])
2616    (set (match_dup 0)
2617         (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2618                          (match_dup 0) (match_dup 4)))]
2619   "
2620   operands[2] = GEN_INT (((1 << INTVAL (operands[2])) - 1)
2621                          << INTVAL (operands[3])); 
2622   "
2623   [(set_attr "conds" "clob")
2624    (set_attr "length" "8")
2625    (set_attr "type" "multiple")]
2628 (define_insn_and_split "*ite_ne_zeroextractsi_shifted"
2629   [(set (match_operand:SI 0 "s_register_operand" "=r")
2630         (if_then_else:SI (ne (zero_extract:SI
2631                               (match_operand:SI 1 "s_register_operand" "r")
2632                               (match_operand:SI 2 "const_int_operand" "n")
2633                               (const_int 0))
2634                              (const_int 0))
2635                          (match_operand:SI 3 "arm_not_operand" "rIK")
2636                          (const_int 0)))
2637    (clobber (reg:CC CC_REGNUM))]
2638   "TARGET_ARM && !reg_overlap_mentioned_p (operands[0], operands[3])"
2639   "#"
2640   "TARGET_ARM && !reg_overlap_mentioned_p (operands[0], operands[3])"
2641   [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2642                    (compare:CC_NOOV (ashift:SI (match_dup 1) (match_dup 2))
2643                                     (const_int 0)))
2644               (set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))])
2645    (set (match_dup 0)
2646         (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2647                          (match_dup 0) (match_dup 3)))]
2648   "
2649   operands[2] = GEN_INT (32 - INTVAL (operands[2]));
2650   "
2651   [(set_attr "conds" "clob")
2652    (set_attr "length" "8")
2653    (set_attr "type" "multiple")]
2656 ;; ??? Use Thumb-2 has bitfield insert/extract instructions.
2657 (define_split
2658   [(set (match_operand:SI 0 "s_register_operand" "")
2659         (match_operator:SI 1 "shiftable_operator"
2660          [(zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
2661                            (match_operand:SI 3 "const_int_operand" "")
2662                            (match_operand:SI 4 "const_int_operand" ""))
2663           (match_operand:SI 5 "s_register_operand" "")]))
2664    (clobber (match_operand:SI 6 "s_register_operand" ""))]
2665   "TARGET_ARM"
2666   [(set (match_dup 6) (ashift:SI (match_dup 2) (match_dup 3)))
2667    (set (match_dup 0)
2668         (match_op_dup 1
2669          [(lshiftrt:SI (match_dup 6) (match_dup 4))
2670           (match_dup 5)]))]
2671   "{
2672      HOST_WIDE_INT temp = INTVAL (operands[3]);
2674      operands[3] = GEN_INT (32 - temp - INTVAL (operands[4]));
2675      operands[4] = GEN_INT (32 - temp);
2676    }"
2678   
2679 (define_split
2680   [(set (match_operand:SI 0 "s_register_operand" "")
2681         (match_operator:SI 1 "shiftable_operator"
2682          [(sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
2683                            (match_operand:SI 3 "const_int_operand" "")
2684                            (match_operand:SI 4 "const_int_operand" ""))
2685           (match_operand:SI 5 "s_register_operand" "")]))
2686    (clobber (match_operand:SI 6 "s_register_operand" ""))]
2687   "TARGET_ARM"
2688   [(set (match_dup 6) (ashift:SI (match_dup 2) (match_dup 3)))
2689    (set (match_dup 0)
2690         (match_op_dup 1
2691          [(ashiftrt:SI (match_dup 6) (match_dup 4))
2692           (match_dup 5)]))]
2693   "{
2694      HOST_WIDE_INT temp = INTVAL (operands[3]);
2696      operands[3] = GEN_INT (32 - temp - INTVAL (operands[4]));
2697      operands[4] = GEN_INT (32 - temp);
2698    }"
2700   
2701 ;;; ??? This pattern is bogus.  If operand3 has bits outside the range
2702 ;;; represented by the bitfield, then this will produce incorrect results.
2703 ;;; Somewhere, the value needs to be truncated.  On targets like the m68k,
2704 ;;; which have a real bit-field insert instruction, the truncation happens
2705 ;;; in the bit-field insert instruction itself.  Since arm does not have a
2706 ;;; bit-field insert instruction, we would have to emit code here to truncate
2707 ;;; the value before we insert.  This loses some of the advantage of having
2708 ;;; this insv pattern, so this pattern needs to be reevalutated.
2710 (define_expand "insv"
2711   [(set (zero_extract (match_operand 0 "nonimmediate_operand" "")
2712                       (match_operand 1 "general_operand" "")
2713                       (match_operand 2 "general_operand" ""))
2714         (match_operand 3 "reg_or_int_operand" ""))]
2715   "TARGET_ARM || arm_arch_thumb2"
2716   "
2717   {
2718     int start_bit = INTVAL (operands[2]);
2719     int width = INTVAL (operands[1]);
2720     HOST_WIDE_INT mask = (HOST_WIDE_INT_1 << width) - 1;
2721     rtx target, subtarget;
2723     if (arm_arch_thumb2)
2724       {
2725         if (unaligned_access && MEM_P (operands[0])
2726             && s_register_operand (operands[3], GET_MODE (operands[3]))
2727             && (width == 16 || width == 32) && (start_bit % BITS_PER_UNIT) == 0)
2728           {
2729             rtx base_addr;
2731             if (BYTES_BIG_ENDIAN)
2732               start_bit = GET_MODE_BITSIZE (GET_MODE (operands[3])) - width
2733                           - start_bit;
2735             if (width == 32)
2736               {
2737                 base_addr = adjust_address (operands[0], SImode,
2738                                             start_bit / BITS_PER_UNIT);
2739                 emit_insn (gen_unaligned_storesi (base_addr, operands[3]));
2740               }
2741             else
2742               {
2743                 rtx tmp = gen_reg_rtx (HImode);
2745                 base_addr = adjust_address (operands[0], HImode,
2746                                             start_bit / BITS_PER_UNIT);
2747                 emit_move_insn (tmp, gen_lowpart (HImode, operands[3]));
2748                 emit_insn (gen_unaligned_storehi (base_addr, tmp));
2749               }
2750             DONE;
2751           }
2752         else if (s_register_operand (operands[0], GET_MODE (operands[0])))
2753           {
2754             bool use_bfi = TRUE;
2756             if (CONST_INT_P (operands[3]))
2757               {
2758                 HOST_WIDE_INT val = INTVAL (operands[3]) & mask;
2760                 if (val == 0)
2761                   {
2762                     emit_insn (gen_insv_zero (operands[0], operands[1],
2763                                               operands[2]));
2764                     DONE;
2765                   }
2767                 /* See if the set can be done with a single orr instruction.  */
2768                 if (val == mask && const_ok_for_arm (val << start_bit))
2769                   use_bfi = FALSE;
2770               }
2772             if (use_bfi)
2773               {
2774                 if (!REG_P (operands[3]))
2775                   operands[3] = force_reg (SImode, operands[3]);
2777                 emit_insn (gen_insv_t2 (operands[0], operands[1], operands[2],
2778                                         operands[3]));
2779                 DONE;
2780               }
2781           }
2782         else
2783           FAIL;
2784       }
2786     if (!s_register_operand (operands[0], GET_MODE (operands[0])))
2787       FAIL;
2789     target = copy_rtx (operands[0]);
2790     /* Avoid using a subreg as a subtarget, and avoid writing a paradoxical 
2791        subreg as the final target.  */
2792     if (GET_CODE (target) == SUBREG)
2793       {
2794         subtarget = gen_reg_rtx (SImode);
2795         if (GET_MODE_SIZE (GET_MODE (SUBREG_REG (target)))
2796             < GET_MODE_SIZE (SImode))
2797           target = SUBREG_REG (target);
2798       }
2799     else
2800       subtarget = target;    
2802     if (CONST_INT_P (operands[3]))
2803       {
2804         /* Since we are inserting a known constant, we may be able to
2805            reduce the number of bits that we have to clear so that
2806            the mask becomes simple.  */
2807         /* ??? This code does not check to see if the new mask is actually
2808            simpler.  It may not be.  */
2809         rtx op1 = gen_reg_rtx (SImode);
2810         /* ??? Truncate operand3 to fit in the bitfield.  See comment before
2811            start of this pattern.  */
2812         HOST_WIDE_INT op3_value = mask & INTVAL (operands[3]);
2813         HOST_WIDE_INT mask2 = ((mask & ~op3_value) << start_bit);
2815         emit_insn (gen_andsi3 (op1, operands[0],
2816                                gen_int_mode (~mask2, SImode)));
2817         emit_insn (gen_iorsi3 (subtarget, op1,
2818                                gen_int_mode (op3_value << start_bit, SImode)));
2819       }
2820     else if (start_bit == 0
2821              && !(const_ok_for_arm (mask)
2822                   || const_ok_for_arm (~mask)))
2823       {
2824         /* A Trick, since we are setting the bottom bits in the word,
2825            we can shift operand[3] up, operand[0] down, OR them together
2826            and rotate the result back again.  This takes 3 insns, and
2827            the third might be mergeable into another op.  */
2828         /* The shift up copes with the possibility that operand[3] is
2829            wider than the bitfield.  */
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_lshrsi3 (op1, operands[0], operands[1]));
2835         emit_insn (gen_iorsi3  (op1, op1, op0));
2836         emit_insn (gen_rotlsi3 (subtarget, op1, operands[1]));
2837       }
2838     else if ((width + start_bit == 32)
2839              && !(const_ok_for_arm (mask)
2840                   || const_ok_for_arm (~mask)))
2841       {
2842         /* Similar trick, but slightly less efficient.  */
2844         rtx op0 = gen_reg_rtx (SImode);
2845         rtx op1 = gen_reg_rtx (SImode);
2847         emit_insn (gen_ashlsi3 (op0, operands[3], GEN_INT (32 - width)));
2848         emit_insn (gen_ashlsi3 (op1, operands[0], operands[1]));
2849         emit_insn (gen_lshrsi3 (op1, op1, operands[1]));
2850         emit_insn (gen_iorsi3 (subtarget, op1, op0));
2851       }
2852     else
2853       {
2854         rtx op0 = gen_int_mode (mask, SImode);
2855         rtx op1 = gen_reg_rtx (SImode);
2856         rtx op2 = gen_reg_rtx (SImode);
2858         if (!(const_ok_for_arm (mask) || const_ok_for_arm (~mask)))
2859           {
2860             rtx tmp = gen_reg_rtx (SImode);
2862             emit_insn (gen_movsi (tmp, op0));
2863             op0 = tmp;
2864           }
2866         /* Mask out any bits in operand[3] that are not needed.  */
2867            emit_insn (gen_andsi3 (op1, operands[3], op0));
2869         if (CONST_INT_P (op0)
2870             && (const_ok_for_arm (mask << start_bit)
2871                 || const_ok_for_arm (~(mask << start_bit))))
2872           {
2873             op0 = gen_int_mode (~(mask << start_bit), SImode);
2874             emit_insn (gen_andsi3 (op2, operands[0], op0));
2875           }
2876         else
2877           {
2878             if (CONST_INT_P (op0))
2879               {
2880                 rtx tmp = gen_reg_rtx (SImode);
2882                 emit_insn (gen_movsi (tmp, op0));
2883                 op0 = tmp;
2884               }
2886             if (start_bit != 0)
2887               emit_insn (gen_ashlsi3 (op0, op0, operands[2]));
2888             
2889             emit_insn (gen_andsi_notsi_si (op2, operands[0], op0));
2890           }
2892         if (start_bit != 0)
2893           emit_insn (gen_ashlsi3 (op1, op1, operands[2]));
2895         emit_insn (gen_iorsi3 (subtarget, op1, op2));
2896       }
2898     if (subtarget != target)
2899       {
2900         /* If TARGET is still a SUBREG, then it must be wider than a word,
2901            so we must be careful only to set the subword we were asked to.  */
2902         if (GET_CODE (target) == SUBREG)
2903           emit_move_insn (target, subtarget);
2904         else
2905           emit_move_insn (target, gen_lowpart (GET_MODE (target), subtarget));
2906       }
2908     DONE;
2909   }"
2912 (define_insn "insv_zero"
2913   [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r")
2914                          (match_operand:SI 1 "const_int_M_operand" "M")
2915                          (match_operand:SI 2 "const_int_M_operand" "M"))
2916         (const_int 0))]
2917   "arm_arch_thumb2"
2918   "bfc%?\t%0, %2, %1"
2919   [(set_attr "length" "4")
2920    (set_attr "predicable" "yes")
2921    (set_attr "predicable_short_it" "no")
2922    (set_attr "type" "bfm")]
2925 (define_insn "insv_t2"
2926   [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r")
2927                          (match_operand:SI 1 "const_int_M_operand" "M")
2928                          (match_operand:SI 2 "const_int_M_operand" "M"))
2929         (match_operand:SI 3 "s_register_operand" "r"))]
2930   "arm_arch_thumb2"
2931   "bfi%?\t%0, %3, %2, %1"
2932   [(set_attr "length" "4")
2933    (set_attr "predicable" "yes")
2934    (set_attr "predicable_short_it" "no")
2935    (set_attr "type" "bfm")]
2938 ; constants for op 2 will never be given to these patterns.
2939 (define_insn_and_split "*anddi_notdi_di"
2940   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2941         (and:DI (not:DI (match_operand:DI 1 "s_register_operand" "0,r"))
2942                 (match_operand:DI 2 "s_register_operand" "r,0")))]
2943   "TARGET_32BIT"
2944   "#"
2945   "TARGET_32BIT && reload_completed
2946    && ! (TARGET_NEON && IS_VFP_REGNUM (REGNO (operands[0])))
2947    && ! IS_IWMMXT_REGNUM (REGNO (operands[0]))"
2948   [(set (match_dup 0) (and:SI (not:SI (match_dup 1)) (match_dup 2)))
2949    (set (match_dup 3) (and:SI (not:SI (match_dup 4)) (match_dup 5)))]
2950   "
2951   {
2952     operands[3] = gen_highpart (SImode, operands[0]);
2953     operands[0] = gen_lowpart (SImode, operands[0]);
2954     operands[4] = gen_highpart (SImode, operands[1]);
2955     operands[1] = gen_lowpart (SImode, operands[1]);
2956     operands[5] = gen_highpart (SImode, operands[2]);
2957     operands[2] = gen_lowpart (SImode, operands[2]);
2958   }"
2959   [(set_attr "length" "8")
2960    (set_attr "predicable" "yes")
2961    (set_attr "type" "multiple")]
2964 (define_insn_and_split "*anddi_notzesidi_di"
2965   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2966         (and:DI (not:DI (zero_extend:DI
2967                          (match_operand:SI 2 "s_register_operand" "r,r")))
2968                 (match_operand:DI 1 "s_register_operand" "0,?r")))]
2969   "TARGET_32BIT"
2970   "@
2971    bic%?\\t%Q0, %Q1, %2
2972    #"
2973   ; (not (zero_extend ...)) allows us to just copy the high word from
2974   ; operand1 to operand0.
2975   "TARGET_32BIT
2976    && reload_completed
2977    && operands[0] != operands[1]"
2978   [(set (match_dup 0) (and:SI (not:SI (match_dup 2)) (match_dup 1)))
2979    (set (match_dup 3) (match_dup 4))]
2980   "
2981   {
2982     operands[3] = gen_highpart (SImode, operands[0]);
2983     operands[0] = gen_lowpart (SImode, operands[0]);
2984     operands[4] = gen_highpart (SImode, operands[1]);
2985     operands[1] = gen_lowpart (SImode, operands[1]);
2986   }"
2987   [(set_attr "length" "4,8")
2988    (set_attr "predicable" "yes")
2989    (set_attr "predicable_short_it" "no")
2990    (set_attr "type" "multiple")]
2993 (define_insn_and_split "*anddi_notdi_zesidi"
2994   [(set (match_operand:DI 0 "s_register_operand" "=r")
2995         (and:DI (not:DI (match_operand:DI 2 "s_register_operand" "r"))
2996                 (zero_extend:DI
2997                  (match_operand:SI 1 "s_register_operand" "r"))))]
2998   "TARGET_32BIT"
2999   "#"
3000   "TARGET_32BIT && reload_completed"
3001   [(set (match_dup 0) (and:SI (not:SI (match_dup 2)) (match_dup 1)))
3002    (set (match_dup 3) (const_int 0))]
3003   "
3004   {
3005     operands[3] = gen_highpart (SImode, operands[0]);
3006     operands[0] = gen_lowpart (SImode, operands[0]);
3007     operands[2] = gen_lowpart (SImode, operands[2]);
3008   }"
3009   [(set_attr "length" "8")
3010    (set_attr "predicable" "yes")
3011    (set_attr "predicable_short_it" "no")
3012    (set_attr "type" "multiple")]
3015 (define_insn_and_split "*anddi_notsesidi_di"
3016   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
3017         (and:DI (not:DI (sign_extend:DI
3018                          (match_operand:SI 2 "s_register_operand" "r,r")))
3019                 (match_operand:DI 1 "s_register_operand" "0,r")))]
3020   "TARGET_32BIT"
3021   "#"
3022   "TARGET_32BIT && reload_completed"
3023   [(set (match_dup 0) (and:SI (not:SI (match_dup 2)) (match_dup 1)))
3024    (set (match_dup 3) (and:SI (not:SI
3025                                 (ashiftrt:SI (match_dup 2) (const_int 31)))
3026                                (match_dup 4)))]
3027   "
3028   {
3029     operands[3] = gen_highpart (SImode, operands[0]);
3030     operands[0] = gen_lowpart (SImode, operands[0]);
3031     operands[4] = gen_highpart (SImode, operands[1]);
3032     operands[1] = gen_lowpart (SImode, operands[1]);
3033   }"
3034   [(set_attr "length" "8")
3035    (set_attr "predicable" "yes")
3036    (set_attr "predicable_short_it" "no")
3037    (set_attr "type" "multiple")]
3040 (define_insn "andsi_notsi_si"
3041   [(set (match_operand:SI 0 "s_register_operand" "=r")
3042         (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
3043                 (match_operand:SI 1 "s_register_operand" "r")))]
3044   "TARGET_32BIT"
3045   "bic%?\\t%0, %1, %2"
3046   [(set_attr "predicable" "yes")
3047    (set_attr "predicable_short_it" "no")
3048    (set_attr "type" "logic_reg")]
3051 (define_insn "andsi_not_shiftsi_si"
3052   [(set (match_operand:SI 0 "s_register_operand" "=r")
3053         (and:SI (not:SI (match_operator:SI 4 "shift_operator"
3054                          [(match_operand:SI 2 "s_register_operand" "r")
3055                           (match_operand:SI 3 "arm_rhs_operand" "rM")]))
3056                 (match_operand:SI 1 "s_register_operand" "r")))]
3057   "TARGET_ARM"
3058   "bic%?\\t%0, %1, %2%S4"
3059   [(set_attr "predicable" "yes")
3060    (set_attr "shift" "2")
3061    (set (attr "type") (if_then_else (match_operand 3 "const_int_operand" "")
3062                       (const_string "logic_shift_imm")
3063                       (const_string "logic_shift_reg")))]
3066 ;; Shifted bics pattern used to set up CC status register and not reusing
3067 ;; bics output.  Pattern restricts Thumb2 shift operand as bics for Thumb2
3068 ;; does not support shift by register.
3069 (define_insn "andsi_not_shiftsi_si_scc_no_reuse"
3070   [(set (reg:CC_NOOV CC_REGNUM)
3071         (compare:CC_NOOV
3072                 (and:SI (not:SI (match_operator:SI 0 "shift_operator"
3073                         [(match_operand:SI 1 "s_register_operand" "r")
3074                          (match_operand:SI 2 "arm_rhs_operand" "rM")]))
3075                         (match_operand:SI 3 "s_register_operand" "r"))
3076                 (const_int 0)))
3077    (clobber (match_scratch:SI 4 "=r"))]
3078   "TARGET_ARM || (TARGET_THUMB2 && CONST_INT_P (operands[2]))"
3079   "bics%?\\t%4, %3, %1%S0"
3080   [(set_attr "predicable" "yes")
3081    (set_attr "predicable_short_it" "no")
3082    (set_attr "conds" "set")
3083    (set_attr "shift" "1")
3084    (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
3085                       (const_string "logic_shift_imm")
3086                       (const_string "logic_shift_reg")))]
3089 ;; Same as andsi_not_shiftsi_si_scc_no_reuse, but the bics result is also
3090 ;; getting reused later.
3091 (define_insn "andsi_not_shiftsi_si_scc"
3092   [(parallel [(set (reg:CC_NOOV CC_REGNUM)
3093         (compare:CC_NOOV
3094                 (and:SI (not:SI (match_operator:SI 0 "shift_operator"
3095                         [(match_operand:SI 1 "s_register_operand" "r")
3096                          (match_operand:SI 2 "arm_rhs_operand" "rM")]))
3097                         (match_operand:SI 3 "s_register_operand" "r"))
3098                 (const_int 0)))
3099         (set (match_operand:SI 4 "s_register_operand" "=r")
3100              (and:SI (not:SI (match_op_dup 0
3101                      [(match_dup 1)
3102                       (match_dup 2)]))
3103                      (match_dup 3)))])]
3104   "TARGET_ARM || (TARGET_THUMB2 && CONST_INT_P (operands[2]))"
3105   "bics%?\\t%4, %3, %1%S0"
3106   [(set_attr "predicable" "yes")
3107    (set_attr "predicable_short_it" "no")
3108    (set_attr "conds" "set")
3109    (set_attr "shift" "1")
3110    (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
3111                       (const_string "logic_shift_imm")
3112                       (const_string "logic_shift_reg")))]
3115 (define_insn "*andsi_notsi_si_compare0"
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    (set (match_operand:SI 0 "s_register_operand" "=r")
3122         (and:SI (not:SI (match_dup 2)) (match_dup 1)))]
3123   "TARGET_32BIT"
3124   "bics\\t%0, %1, %2"
3125   [(set_attr "conds" "set")
3126    (set_attr "type" "logics_shift_reg")]
3129 (define_insn "*andsi_notsi_si_compare0_scratch"
3130   [(set (reg:CC_NOOV CC_REGNUM)
3131         (compare:CC_NOOV
3132          (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
3133                  (match_operand:SI 1 "s_register_operand" "r"))
3134          (const_int 0)))
3135    (clobber (match_scratch:SI 0 "=r"))]
3136   "TARGET_32BIT"
3137   "bics\\t%0, %1, %2"
3138   [(set_attr "conds" "set")
3139    (set_attr "type" "logics_shift_reg")]
3142 (define_expand "iordi3"
3143   [(set (match_operand:DI         0 "s_register_operand" "")
3144         (ior:DI (match_operand:DI 1 "s_register_operand" "")
3145                 (match_operand:DI 2 "neon_logic_op2" "")))]
3146   "TARGET_32BIT"
3147   "
3148   if (!TARGET_NEON && !TARGET_IWMMXT)
3149     {
3150       rtx low  = simplify_gen_binary (IOR, SImode,
3151                                       gen_lowpart (SImode, operands[1]),
3152                                       gen_lowpart (SImode, operands[2]));
3153       rtx high = simplify_gen_binary (IOR, SImode,
3154                                       gen_highpart (SImode, operands[1]),
3155                                       gen_highpart_mode (SImode, DImode,
3156                                                          operands[2]));
3158       emit_insn (gen_rtx_SET (gen_lowpart (SImode, operands[0]), low));
3159       emit_insn (gen_rtx_SET (gen_highpart (SImode, operands[0]), high));
3161       DONE;
3162     }
3163   /* Otherwise expand pattern as above.  */
3164   "
3167 (define_insn_and_split "*iordi3_insn"
3168   [(set (match_operand:DI         0 "s_register_operand"     "=w,w ,&r,&r,&r,&r,?w,?w")
3169         (ior:DI (match_operand:DI 1 "s_register_operand"     "%w,0 ,0 ,r ,0 ,r ,w ,0")
3170                 (match_operand:DI 2 "arm_iordi_operand_neon" "w ,Dl,r ,r ,Df,Df,w ,Dl")))]
3171   "TARGET_32BIT && !TARGET_IWMMXT"
3172   {
3173   switch (which_alternative)
3174     {
3175     case 0: /* fall through */
3176     case 6: return "vorr\t%P0, %P1, %P2";
3177     case 1: /* fall through */
3178     case 7: return neon_output_logic_immediate ("vorr", &operands[2],
3179                      DImode, 0, VALID_NEON_QREG_MODE (DImode));
3180     case 2:
3181     case 3:
3182     case 4:
3183     case 5:
3184       return "#";
3185     default: gcc_unreachable ();
3186     }
3187   }
3188   "TARGET_32BIT && !TARGET_IWMMXT && reload_completed
3189    && !(IS_VFP_REGNUM (REGNO (operands[0])))"
3190   [(set (match_dup 3) (match_dup 4))
3191    (set (match_dup 5) (match_dup 6))]
3192   "
3193   {
3194     operands[3] = gen_lowpart (SImode, operands[0]);
3195     operands[5] = gen_highpart (SImode, operands[0]);
3197     operands[4] = simplify_gen_binary (IOR, SImode,
3198                                            gen_lowpart (SImode, operands[1]),
3199                                            gen_lowpart (SImode, operands[2]));
3200     operands[6] = simplify_gen_binary (IOR, SImode,
3201                                            gen_highpart (SImode, operands[1]),
3202                                            gen_highpart_mode (SImode, DImode, operands[2]));
3204   }"
3205   [(set_attr "type" "neon_logic,neon_logic,multiple,multiple,multiple,\
3206                      multiple,neon_logic,neon_logic")
3207    (set_attr "length" "*,*,8,8,8,8,*,*")
3208    (set_attr "arch" "neon_for_64bits,neon_for_64bits,*,*,*,*,avoid_neon_for_64bits,avoid_neon_for_64bits")]
3211 (define_insn "*iordi_zesidi_di"
3212   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
3213         (ior:DI (zero_extend:DI
3214                  (match_operand:SI 2 "s_register_operand" "r,r"))
3215                 (match_operand:DI 1 "s_register_operand" "0,?r")))]
3216   "TARGET_32BIT"
3217   "@
3218    orr%?\\t%Q0, %Q1, %2
3219    #"
3220   [(set_attr "length" "4,8")
3221    (set_attr "predicable" "yes")
3222    (set_attr "predicable_short_it" "no")
3223    (set_attr "type" "logic_reg,multiple")]
3226 (define_insn "*iordi_sesidi_di"
3227   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
3228         (ior:DI (sign_extend:DI
3229                  (match_operand:SI 2 "s_register_operand" "r,r"))
3230                 (match_operand:DI 1 "s_register_operand" "0,r")))]
3231   "TARGET_32BIT"
3232   "#"
3233   [(set_attr "length" "8")
3234    (set_attr "predicable" "yes")
3235    (set_attr "type" "multiple")]
3238 (define_expand "iorsi3"
3239   [(set (match_operand:SI         0 "s_register_operand" "")
3240         (ior:SI (match_operand:SI 1 "s_register_operand" "")
3241                 (match_operand:SI 2 "reg_or_int_operand" "")))]
3242   "TARGET_EITHER"
3243   "
3244   if (CONST_INT_P (operands[2]))
3245     {
3246       if (TARGET_32BIT)
3247         {
3248           if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[2]), IOR))
3249             operands[2] = force_reg (SImode, operands[2]);
3250           else
3251             {
3252               arm_split_constant (IOR, SImode, NULL_RTX,
3253                                   INTVAL (operands[2]), operands[0],
3254                                   operands[1],
3255                                   optimize && can_create_pseudo_p ());
3256               DONE;
3257             }
3258         }
3259       else /* TARGET_THUMB1 */
3260         {
3261           rtx tmp = force_reg (SImode, operands[2]);
3262           if (rtx_equal_p (operands[0], operands[1]))
3263             operands[2] = tmp;
3264           else
3265             {
3266               operands[2] = operands[1];
3267               operands[1] = tmp;
3268             }
3269         }
3270     }
3271   "
3274 (define_insn_and_split "*iorsi3_insn"
3275   [(set (match_operand:SI 0 "s_register_operand" "=r,l,r,r,r")
3276         (ior:SI (match_operand:SI 1 "s_register_operand" "%r,0,r,r,r")
3277                 (match_operand:SI 2 "reg_or_int_operand" "I,l,K,r,?n")))]
3278   "TARGET_32BIT"
3279   "@
3280    orr%?\\t%0, %1, %2
3281    orr%?\\t%0, %1, %2
3282    orn%?\\t%0, %1, #%B2
3283    orr%?\\t%0, %1, %2
3284    #"
3285   "TARGET_32BIT
3286    && CONST_INT_P (operands[2])
3287    && !(const_ok_for_arm (INTVAL (operands[2]))
3288         || (TARGET_THUMB2 && const_ok_for_arm (~INTVAL (operands[2]))))"
3289   [(clobber (const_int 0))]
3291   arm_split_constant (IOR, SImode, curr_insn,
3292                       INTVAL (operands[2]), operands[0], operands[1], 0);
3293   DONE;
3295   [(set_attr "length" "4,4,4,4,16")
3296    (set_attr "arch" "32,t2,t2,32,32")
3297    (set_attr "predicable" "yes")
3298    (set_attr "predicable_short_it" "no,yes,no,no,no")
3299    (set_attr "type" "logic_imm,logic_reg,logic_imm,logic_reg,logic_reg")]
3302 (define_peephole2
3303   [(match_scratch:SI 3 "r")
3304    (set (match_operand:SI 0 "arm_general_register_operand" "")
3305         (ior:SI (match_operand:SI 1 "arm_general_register_operand" "")
3306                 (match_operand:SI 2 "const_int_operand" "")))]
3307   "TARGET_ARM
3308    && !const_ok_for_arm (INTVAL (operands[2]))
3309    && const_ok_for_arm (~INTVAL (operands[2]))"
3310   [(set (match_dup 3) (match_dup 2))
3311    (set (match_dup 0) (ior:SI (match_dup 1) (match_dup 3)))]
3312   ""
3315 (define_insn "*iorsi3_compare0"
3316   [(set (reg:CC_NOOV CC_REGNUM)
3317         (compare:CC_NOOV (ior:SI (match_operand:SI 1 "s_register_operand" "%r,r")
3318                                  (match_operand:SI 2 "arm_rhs_operand" "I,r"))
3319                          (const_int 0)))
3320    (set (match_operand:SI 0 "s_register_operand" "=r,r")
3321         (ior:SI (match_dup 1) (match_dup 2)))]
3322   "TARGET_32BIT"
3323   "orrs%?\\t%0, %1, %2"
3324   [(set_attr "conds" "set")
3325    (set_attr "type" "logics_imm,logics_reg")]
3328 (define_insn "*iorsi3_compare0_scratch"
3329   [(set (reg:CC_NOOV CC_REGNUM)
3330         (compare:CC_NOOV (ior:SI (match_operand:SI 1 "s_register_operand" "%r,r")
3331                                  (match_operand:SI 2 "arm_rhs_operand" "I,r"))
3332                          (const_int 0)))
3333    (clobber (match_scratch:SI 0 "=r,r"))]
3334   "TARGET_32BIT"
3335   "orrs%?\\t%0, %1, %2"
3336   [(set_attr "conds" "set")
3337    (set_attr "type" "logics_imm,logics_reg")]
3340 (define_expand "xordi3"
3341   [(set (match_operand:DI         0 "s_register_operand" "")
3342         (xor:DI (match_operand:DI 1 "s_register_operand" "")
3343                 (match_operand:DI 2 "arm_xordi_operand" "")))]
3344   "TARGET_32BIT"
3345   {
3346     /* The iWMMXt pattern for xordi3 accepts only register operands but we want
3347        to reuse this expander for all TARGET_32BIT targets so just force the
3348        constants into a register.  Unlike for the anddi3 and iordi3 there are
3349        no NEON instructions that take an immediate.  */
3350     if (TARGET_IWMMXT && !REG_P (operands[2]))
3351       operands[2] = force_reg (DImode, operands[2]);
3352     if (!TARGET_NEON && !TARGET_IWMMXT)
3353       {
3354         rtx low  = simplify_gen_binary (XOR, SImode,
3355                                         gen_lowpart (SImode, operands[1]),
3356                                         gen_lowpart (SImode, operands[2]));
3357         rtx high = simplify_gen_binary (XOR, SImode,
3358                                         gen_highpart (SImode, operands[1]),
3359                                         gen_highpart_mode (SImode, DImode,
3360                                                            operands[2]));
3362         emit_insn (gen_rtx_SET (gen_lowpart (SImode, operands[0]), low));
3363         emit_insn (gen_rtx_SET (gen_highpart (SImode, operands[0]), high));
3365         DONE;
3366       }
3367     /* Otherwise expand pattern as above.  */
3368   }
3371 (define_insn_and_split "*xordi3_insn"
3372   [(set (match_operand:DI         0 "s_register_operand" "=w,&r,&r,&r,&r,?w")
3373         (xor:DI (match_operand:DI 1 "s_register_operand" "%w ,0,r ,0 ,r ,w")
3374                 (match_operand:DI 2 "arm_xordi_operand"  "w ,r ,r ,Dg,Dg,w")))]
3375   "TARGET_32BIT && !TARGET_IWMMXT"
3377   switch (which_alternative)
3378     {
3379     case 1:
3380     case 2:
3381     case 3:
3382     case 4:  /* fall through */
3383       return "#";
3384     case 0: /* fall through */
3385     case 5: return "veor\t%P0, %P1, %P2";
3386     default: gcc_unreachable ();
3387     }
3389   "TARGET_32BIT && !TARGET_IWMMXT && reload_completed
3390    && !(IS_VFP_REGNUM (REGNO (operands[0])))"
3391   [(set (match_dup 3) (match_dup 4))
3392    (set (match_dup 5) (match_dup 6))]
3393   "
3394   {
3395     operands[3] = gen_lowpart (SImode, operands[0]);
3396     operands[5] = gen_highpart (SImode, operands[0]);
3398     operands[4] = simplify_gen_binary (XOR, SImode,
3399                                            gen_lowpart (SImode, operands[1]),
3400                                            gen_lowpart (SImode, operands[2]));
3401     operands[6] = simplify_gen_binary (XOR, SImode,
3402                                            gen_highpart (SImode, operands[1]),
3403                                            gen_highpart_mode (SImode, DImode, operands[2]));
3405   }"
3406   [(set_attr "length" "*,8,8,8,8,*")
3407    (set_attr "type" "neon_logic,multiple,multiple,multiple,multiple,neon_logic")
3408    (set_attr "arch" "neon_for_64bits,*,*,*,*,avoid_neon_for_64bits")]
3411 (define_insn "*xordi_zesidi_di"
3412   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
3413         (xor:DI (zero_extend:DI
3414                  (match_operand:SI 2 "s_register_operand" "r,r"))
3415                 (match_operand:DI 1 "s_register_operand" "0,?r")))]
3416   "TARGET_32BIT"
3417   "@
3418    eor%?\\t%Q0, %Q1, %2
3419    #"
3420   [(set_attr "length" "4,8")
3421    (set_attr "predicable" "yes")
3422    (set_attr "predicable_short_it" "no")
3423    (set_attr "type" "logic_reg")]
3426 (define_insn "*xordi_sesidi_di"
3427   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
3428         (xor:DI (sign_extend:DI
3429                  (match_operand:SI 2 "s_register_operand" "r,r"))
3430                 (match_operand:DI 1 "s_register_operand" "0,r")))]
3431   "TARGET_32BIT"
3432   "#"
3433   [(set_attr "length" "8")
3434    (set_attr "predicable" "yes")
3435    (set_attr "type" "multiple")]
3438 (define_expand "xorsi3"
3439   [(set (match_operand:SI         0 "s_register_operand" "")
3440         (xor:SI (match_operand:SI 1 "s_register_operand" "")
3441                 (match_operand:SI 2 "reg_or_int_operand" "")))]
3442   "TARGET_EITHER"
3443   "if (CONST_INT_P (operands[2]))
3444     {
3445       if (TARGET_32BIT)
3446         {
3447           if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[2]), XOR))
3448             operands[2] = force_reg (SImode, operands[2]);
3449           else
3450             {
3451               arm_split_constant (XOR, SImode, NULL_RTX,
3452                                   INTVAL (operands[2]), operands[0],
3453                                   operands[1],
3454                                   optimize && can_create_pseudo_p ());
3455               DONE;
3456             }
3457         }
3458       else /* TARGET_THUMB1 */
3459         {
3460           rtx tmp = force_reg (SImode, operands[2]);
3461           if (rtx_equal_p (operands[0], operands[1]))
3462             operands[2] = tmp;
3463           else
3464             {
3465               operands[2] = operands[1];
3466               operands[1] = tmp;
3467             }
3468         }
3469     }"
3472 (define_insn_and_split "*arm_xorsi3"
3473   [(set (match_operand:SI         0 "s_register_operand" "=r,l,r,r")
3474         (xor:SI (match_operand:SI 1 "s_register_operand" "%r,0,r,r")
3475                 (match_operand:SI 2 "reg_or_int_operand" "I,l,r,?n")))]
3476   "TARGET_32BIT"
3477   "@
3478    eor%?\\t%0, %1, %2
3479    eor%?\\t%0, %1, %2
3480    eor%?\\t%0, %1, %2
3481    #"
3482   "TARGET_32BIT
3483    && CONST_INT_P (operands[2])
3484    && !const_ok_for_arm (INTVAL (operands[2]))"
3485   [(clobber (const_int 0))]
3487   arm_split_constant (XOR, SImode, curr_insn,
3488                       INTVAL (operands[2]), operands[0], operands[1], 0);
3489   DONE;
3491   [(set_attr "length" "4,4,4,16")
3492    (set_attr "predicable" "yes")
3493    (set_attr "predicable_short_it" "no,yes,no,no")
3494    (set_attr "type"  "logic_imm,logic_reg,logic_reg,multiple")]
3497 (define_insn "*xorsi3_compare0"
3498   [(set (reg:CC_NOOV CC_REGNUM)
3499         (compare:CC_NOOV (xor:SI (match_operand:SI 1 "s_register_operand" "r,r")
3500                                  (match_operand:SI 2 "arm_rhs_operand" "I,r"))
3501                          (const_int 0)))
3502    (set (match_operand:SI 0 "s_register_operand" "=r,r")
3503         (xor:SI (match_dup 1) (match_dup 2)))]
3504   "TARGET_32BIT"
3505   "eors%?\\t%0, %1, %2"
3506   [(set_attr "conds" "set")
3507    (set_attr "type" "logics_imm,logics_reg")]
3510 (define_insn "*xorsi3_compare0_scratch"
3511   [(set (reg:CC_NOOV CC_REGNUM)
3512         (compare:CC_NOOV (xor:SI (match_operand:SI 0 "s_register_operand" "r,r")
3513                                  (match_operand:SI 1 "arm_rhs_operand" "I,r"))
3514                          (const_int 0)))]
3515   "TARGET_32BIT"
3516   "teq%?\\t%0, %1"
3517   [(set_attr "conds" "set")
3518    (set_attr "type" "logics_imm,logics_reg")]
3521 ; By splitting (IOR (AND (NOT A) (NOT B)) C) as D = AND (IOR A B) (NOT C), 
3522 ; (NOT D) we can sometimes merge the final NOT into one of the following
3523 ; insns.
3525 (define_split
3526   [(set (match_operand:SI 0 "s_register_operand" "")
3527         (ior:SI (and:SI (not:SI (match_operand:SI 1 "s_register_operand" ""))
3528                         (not:SI (match_operand:SI 2 "arm_rhs_operand" "")))
3529                 (match_operand:SI 3 "arm_rhs_operand" "")))
3530    (clobber (match_operand:SI 4 "s_register_operand" ""))]
3531   "TARGET_32BIT"
3532   [(set (match_dup 4) (and:SI (ior:SI (match_dup 1) (match_dup 2))
3533                               (not:SI (match_dup 3))))
3534    (set (match_dup 0) (not:SI (match_dup 4)))]
3535   ""
3538 (define_insn_and_split "*andsi_iorsi3_notsi"
3539   [(set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r")
3540         (and:SI (ior:SI (match_operand:SI 1 "s_register_operand" "%0,r,r")
3541                         (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI"))
3542                 (not:SI (match_operand:SI 3 "arm_rhs_operand" "rI,rI,rI"))))]
3543   "TARGET_32BIT"
3544   "#"   ; "orr%?\\t%0, %1, %2\;bic%?\\t%0, %0, %3"
3545   "&& reload_completed"
3546   [(set (match_dup 0) (ior:SI (match_dup 1) (match_dup 2)))
3547    (set (match_dup 0) (and:SI (match_dup 4) (match_dup 5)))]
3548   {
3549      /* If operands[3] is a constant make sure to fold the NOT into it
3550         to avoid creating a NOT of a CONST_INT.  */
3551     rtx not_rtx = simplify_gen_unary (NOT, SImode, operands[3], SImode);
3552     if (CONST_INT_P (not_rtx))
3553       {
3554         operands[4] = operands[0];
3555         operands[5] = not_rtx;
3556       }
3557     else
3558       {
3559         operands[5] = operands[0];
3560         operands[4] = not_rtx;
3561       }
3562   }
3563   [(set_attr "length" "8")
3564    (set_attr "ce_count" "2")
3565    (set_attr "predicable" "yes")
3566    (set_attr "predicable_short_it" "no")
3567    (set_attr "type" "multiple")]
3570 ; ??? Are these four splitters still beneficial when the Thumb-2 bitfield
3571 ; insns are available?
3572 (define_split
3573   [(set (match_operand:SI 0 "s_register_operand" "")
3574         (match_operator:SI 1 "logical_binary_operator"
3575          [(zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
3576                            (match_operand:SI 3 "const_int_operand" "")
3577                            (match_operand:SI 4 "const_int_operand" ""))
3578           (match_operator:SI 9 "logical_binary_operator"
3579            [(lshiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3580                          (match_operand:SI 6 "const_int_operand" ""))
3581             (match_operand:SI 7 "s_register_operand" "")])]))
3582    (clobber (match_operand:SI 8 "s_register_operand" ""))]
3583   "TARGET_32BIT
3584    && GET_CODE (operands[1]) == GET_CODE (operands[9])
3585    && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3586   [(set (match_dup 8)
3587         (match_op_dup 1
3588          [(ashift:SI (match_dup 2) (match_dup 4))
3589           (match_dup 5)]))
3590    (set (match_dup 0)
3591         (match_op_dup 1
3592          [(lshiftrt:SI (match_dup 8) (match_dup 6))
3593           (match_dup 7)]))]
3594   "
3595   operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3598 (define_split
3599   [(set (match_operand:SI 0 "s_register_operand" "")
3600         (match_operator:SI 1 "logical_binary_operator"
3601          [(match_operator:SI 9 "logical_binary_operator"
3602            [(lshiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3603                          (match_operand:SI 6 "const_int_operand" ""))
3604             (match_operand:SI 7 "s_register_operand" "")])
3605           (zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
3606                            (match_operand:SI 3 "const_int_operand" "")
3607                            (match_operand:SI 4 "const_int_operand" ""))]))
3608    (clobber (match_operand:SI 8 "s_register_operand" ""))]
3609   "TARGET_32BIT
3610    && GET_CODE (operands[1]) == GET_CODE (operands[9])
3611    && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3612   [(set (match_dup 8)
3613         (match_op_dup 1
3614          [(ashift:SI (match_dup 2) (match_dup 4))
3615           (match_dup 5)]))
3616    (set (match_dup 0)
3617         (match_op_dup 1
3618          [(lshiftrt:SI (match_dup 8) (match_dup 6))
3619           (match_dup 7)]))]
3620   "
3621   operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3624 (define_split
3625   [(set (match_operand:SI 0 "s_register_operand" "")
3626         (match_operator:SI 1 "logical_binary_operator"
3627          [(sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
3628                            (match_operand:SI 3 "const_int_operand" "")
3629                            (match_operand:SI 4 "const_int_operand" ""))
3630           (match_operator:SI 9 "logical_binary_operator"
3631            [(ashiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3632                          (match_operand:SI 6 "const_int_operand" ""))
3633             (match_operand:SI 7 "s_register_operand" "")])]))
3634    (clobber (match_operand:SI 8 "s_register_operand" ""))]
3635   "TARGET_32BIT
3636    && GET_CODE (operands[1]) == GET_CODE (operands[9])
3637    && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3638   [(set (match_dup 8)
3639         (match_op_dup 1
3640          [(ashift:SI (match_dup 2) (match_dup 4))
3641           (match_dup 5)]))
3642    (set (match_dup 0)
3643         (match_op_dup 1
3644          [(ashiftrt:SI (match_dup 8) (match_dup 6))
3645           (match_dup 7)]))]
3646   "
3647   operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3650 (define_split
3651   [(set (match_operand:SI 0 "s_register_operand" "")
3652         (match_operator:SI 1 "logical_binary_operator"
3653          [(match_operator:SI 9 "logical_binary_operator"
3654            [(ashiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3655                          (match_operand:SI 6 "const_int_operand" ""))
3656             (match_operand:SI 7 "s_register_operand" "")])
3657           (sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
3658                            (match_operand:SI 3 "const_int_operand" "")
3659                            (match_operand:SI 4 "const_int_operand" ""))]))
3660    (clobber (match_operand:SI 8 "s_register_operand" ""))]
3661   "TARGET_32BIT
3662    && GET_CODE (operands[1]) == GET_CODE (operands[9])
3663    && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3664   [(set (match_dup 8)
3665         (match_op_dup 1
3666          [(ashift:SI (match_dup 2) (match_dup 4))
3667           (match_dup 5)]))
3668    (set (match_dup 0)
3669         (match_op_dup 1
3670          [(ashiftrt:SI (match_dup 8) (match_dup 6))
3671           (match_dup 7)]))]
3672   "
3673   operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3677 ;; Minimum and maximum insns
3679 (define_expand "smaxsi3"
3680   [(parallel [
3681     (set (match_operand:SI 0 "s_register_operand" "")
3682          (smax:SI (match_operand:SI 1 "s_register_operand" "")
3683                   (match_operand:SI 2 "arm_rhs_operand" "")))
3684     (clobber (reg:CC CC_REGNUM))])]
3685   "TARGET_32BIT"
3686   "
3687   if (operands[2] == const0_rtx || operands[2] == constm1_rtx)
3688     {
3689       /* No need for a clobber of the condition code register here.  */
3690       emit_insn (gen_rtx_SET (operands[0],
3691                               gen_rtx_SMAX (SImode, operands[1],
3692                                             operands[2])));
3693       DONE;
3694     }
3697 (define_insn "*smax_0"
3698   [(set (match_operand:SI 0 "s_register_operand" "=r")
3699         (smax:SI (match_operand:SI 1 "s_register_operand" "r")
3700                  (const_int 0)))]
3701   "TARGET_32BIT"
3702   "bic%?\\t%0, %1, %1, asr #31"
3703   [(set_attr "predicable" "yes")
3704    (set_attr "predicable_short_it" "no")
3705    (set_attr "type" "logic_shift_reg")]
3708 (define_insn "*smax_m1"
3709   [(set (match_operand:SI 0 "s_register_operand" "=r")
3710         (smax:SI (match_operand:SI 1 "s_register_operand" "r")
3711                  (const_int -1)))]
3712   "TARGET_32BIT"
3713   "orr%?\\t%0, %1, %1, asr #31"
3714   [(set_attr "predicable" "yes")
3715    (set_attr "predicable_short_it" "no")
3716    (set_attr "type" "logic_shift_reg")]
3719 (define_insn_and_split "*arm_smax_insn"
3720   [(set (match_operand:SI          0 "s_register_operand" "=r,r")
3721         (smax:SI (match_operand:SI 1 "s_register_operand"  "%0,?r")
3722                  (match_operand:SI 2 "arm_rhs_operand"    "rI,rI")))
3723    (clobber (reg:CC CC_REGNUM))]
3724   "TARGET_ARM"
3725   "#"
3726    ; cmp\\t%1, %2\;movlt\\t%0, %2
3727    ; cmp\\t%1, %2\;movge\\t%0, %1\;movlt\\t%0, %2"
3728   "TARGET_ARM"
3729   [(set (reg:CC CC_REGNUM)
3730         (compare:CC (match_dup 1) (match_dup 2)))
3731    (set (match_dup 0)
3732         (if_then_else:SI (ge:SI (reg:CC CC_REGNUM) (const_int 0))
3733                          (match_dup 1)
3734                          (match_dup 2)))]
3735   ""
3736   [(set_attr "conds" "clob")
3737    (set_attr "length" "8,12")
3738    (set_attr "type" "multiple")]
3741 (define_expand "sminsi3"
3742   [(parallel [
3743     (set (match_operand:SI 0 "s_register_operand" "")
3744          (smin:SI (match_operand:SI 1 "s_register_operand" "")
3745                   (match_operand:SI 2 "arm_rhs_operand" "")))
3746     (clobber (reg:CC CC_REGNUM))])]
3747   "TARGET_32BIT"
3748   "
3749   if (operands[2] == const0_rtx)
3750     {
3751       /* No need for a clobber of the condition code register here.  */
3752       emit_insn (gen_rtx_SET (operands[0],
3753                               gen_rtx_SMIN (SImode, operands[1],
3754                                             operands[2])));
3755       DONE;
3756     }
3759 (define_insn "*smin_0"
3760   [(set (match_operand:SI 0 "s_register_operand" "=r")
3761         (smin:SI (match_operand:SI 1 "s_register_operand" "r")
3762                  (const_int 0)))]
3763   "TARGET_32BIT"
3764   "and%?\\t%0, %1, %1, asr #31"
3765   [(set_attr "predicable" "yes")
3766    (set_attr "predicable_short_it" "no")
3767    (set_attr "type" "logic_shift_reg")]
3770 (define_insn_and_split "*arm_smin_insn"
3771   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3772         (smin:SI (match_operand:SI 1 "s_register_operand" "%0,?r")
3773                  (match_operand:SI 2 "arm_rhs_operand" "rI,rI")))
3774    (clobber (reg:CC CC_REGNUM))]
3775   "TARGET_ARM"
3776   "#"
3777     ; cmp\\t%1, %2\;movge\\t%0, %2
3778     ; cmp\\t%1, %2\;movlt\\t%0, %1\;movge\\t%0, %2"
3779   "TARGET_ARM"
3780   [(set (reg:CC CC_REGNUM)
3781         (compare:CC (match_dup 1) (match_dup 2)))
3782    (set (match_dup 0)
3783         (if_then_else:SI (lt:SI (reg:CC CC_REGNUM) (const_int 0))
3784                          (match_dup 1)
3785                          (match_dup 2)))]
3786   ""
3787   [(set_attr "conds" "clob")
3788    (set_attr "length" "8,12")
3789    (set_attr "type" "multiple,multiple")]
3792 (define_expand "umaxsi3"
3793   [(parallel [
3794     (set (match_operand:SI 0 "s_register_operand" "")
3795          (umax:SI (match_operand:SI 1 "s_register_operand" "")
3796                   (match_operand:SI 2 "arm_rhs_operand" "")))
3797     (clobber (reg:CC CC_REGNUM))])]
3798   "TARGET_32BIT"
3799   ""
3802 (define_insn_and_split "*arm_umaxsi3"
3803   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
3804         (umax:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
3805                  (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
3806    (clobber (reg:CC CC_REGNUM))]
3807   "TARGET_ARM"
3808   "#"
3809     ; cmp\\t%1, %2\;movcc\\t%0, %2
3810     ; cmp\\t%1, %2\;movcs\\t%0, %1
3811     ; cmp\\t%1, %2\;movcs\\t%0, %1\;movcc\\t%0, %2"
3812   "TARGET_ARM"
3813   [(set (reg:CC CC_REGNUM)
3814         (compare:CC (match_dup 1) (match_dup 2)))
3815    (set (match_dup 0)
3816         (if_then_else:SI (geu:SI (reg:CC CC_REGNUM) (const_int 0))
3817                          (match_dup 1)
3818                          (match_dup 2)))]
3819   ""
3820   [(set_attr "conds" "clob")
3821    (set_attr "length" "8,8,12")
3822    (set_attr "type" "store1")]
3825 (define_expand "uminsi3"
3826   [(parallel [
3827     (set (match_operand:SI 0 "s_register_operand" "")
3828          (umin:SI (match_operand:SI 1 "s_register_operand" "")
3829                   (match_operand:SI 2 "arm_rhs_operand" "")))
3830     (clobber (reg:CC CC_REGNUM))])]
3831   "TARGET_32BIT"
3832   ""
3835 (define_insn_and_split "*arm_uminsi3"
3836   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
3837         (umin:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
3838                  (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
3839    (clobber (reg:CC CC_REGNUM))]
3840   "TARGET_ARM"
3841   "#"
3842    ; cmp\\t%1, %2\;movcs\\t%0, %2
3843    ; cmp\\t%1, %2\;movcc\\t%0, %1
3844    ; cmp\\t%1, %2\;movcc\\t%0, %1\;movcs\\t%0, %2"
3845   "TARGET_ARM"
3846   [(set (reg:CC CC_REGNUM)
3847         (compare:CC (match_dup 1) (match_dup 2)))
3848    (set (match_dup 0)
3849         (if_then_else:SI (ltu:SI (reg:CC CC_REGNUM) (const_int 0))
3850                          (match_dup 1)
3851                          (match_dup 2)))]
3852   ""
3853   [(set_attr "conds" "clob")
3854    (set_attr "length" "8,8,12")
3855    (set_attr "type" "store1")]
3858 (define_insn "*store_minmaxsi"
3859   [(set (match_operand:SI 0 "memory_operand" "=m")
3860         (match_operator:SI 3 "minmax_operator"
3861          [(match_operand:SI 1 "s_register_operand" "r")
3862           (match_operand:SI 2 "s_register_operand" "r")]))
3863    (clobber (reg:CC CC_REGNUM))]
3864   "TARGET_32BIT && optimize_function_for_size_p (cfun) && !arm_restrict_it"
3865   "*
3866   operands[3] = gen_rtx_fmt_ee (minmax_code (operands[3]), SImode,
3867                                 operands[1], operands[2]);
3868   output_asm_insn (\"cmp\\t%1, %2\", operands);
3869   if (TARGET_THUMB2)
3870     output_asm_insn (\"ite\t%d3\", operands);
3871   output_asm_insn (\"str%d3\\t%1, %0\", operands);
3872   output_asm_insn (\"str%D3\\t%2, %0\", operands);
3873   return \"\";
3874   "
3875   [(set_attr "conds" "clob")
3876    (set (attr "length")
3877         (if_then_else (eq_attr "is_thumb" "yes")
3878                       (const_int 14)
3879                       (const_int 12)))
3880    (set_attr "type" "store1")]
3883 ; Reject the frame pointer in operand[1], since reloading this after
3884 ; it has been eliminated can cause carnage.
3885 (define_insn "*minmax_arithsi"
3886   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3887         (match_operator:SI 4 "shiftable_operator"
3888          [(match_operator:SI 5 "minmax_operator"
3889            [(match_operand:SI 2 "s_register_operand" "r,r")
3890             (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
3891           (match_operand:SI 1 "s_register_operand" "0,?r")]))
3892    (clobber (reg:CC CC_REGNUM))]
3893   "TARGET_32BIT && !arm_eliminable_register (operands[1]) && !arm_restrict_it"
3894   "*
3895   {
3896     enum rtx_code code = GET_CODE (operands[4]);
3897     bool need_else;
3899     if (which_alternative != 0 || operands[3] != const0_rtx
3900         || (code != PLUS && code != IOR && code != XOR))
3901       need_else = true;
3902     else
3903       need_else = false;
3905     operands[5] = gen_rtx_fmt_ee (minmax_code (operands[5]), SImode,
3906                                   operands[2], operands[3]);
3907     output_asm_insn (\"cmp\\t%2, %3\", operands);
3908     if (TARGET_THUMB2)
3909       {
3910         if (need_else)
3911           output_asm_insn (\"ite\\t%d5\", operands);
3912         else
3913           output_asm_insn (\"it\\t%d5\", operands);
3914       }
3915     output_asm_insn (\"%i4%d5\\t%0, %1, %2\", operands);
3916     if (need_else)
3917       output_asm_insn (\"%i4%D5\\t%0, %1, %3\", operands);
3918     return \"\";
3919   }"
3920   [(set_attr "conds" "clob")
3921    (set (attr "length")
3922         (if_then_else (eq_attr "is_thumb" "yes")
3923                       (const_int 14)
3924                       (const_int 12)))
3925    (set_attr "type" "multiple")]
3928 ; Reject the frame pointer in operand[1], since reloading this after
3929 ; it has been eliminated can cause carnage.
3930 (define_insn_and_split "*minmax_arithsi_non_canon"
3931   [(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts")
3932         (minus:SI
3933          (match_operand:SI 1 "s_register_operand" "0,?Ts")
3934           (match_operator:SI 4 "minmax_operator"
3935            [(match_operand:SI 2 "s_register_operand" "Ts,Ts")
3936             (match_operand:SI 3 "arm_rhs_operand" "TsI,TsI")])))
3937    (clobber (reg:CC CC_REGNUM))]
3938   "TARGET_32BIT && !arm_eliminable_register (operands[1])
3939    && !(arm_restrict_it && CONST_INT_P (operands[3]))"
3940   "#"
3941   "TARGET_32BIT && !arm_eliminable_register (operands[1]) && reload_completed"
3942   [(set (reg:CC CC_REGNUM)
3943         (compare:CC (match_dup 2) (match_dup 3)))
3945    (cond_exec (match_op_dup 4 [(reg:CC CC_REGNUM) (const_int 0)])
3946               (set (match_dup 0)
3947                    (minus:SI (match_dup 1)
3948                              (match_dup 2))))
3949    (cond_exec (match_op_dup 5 [(reg:CC CC_REGNUM) (const_int 0)])
3950               (set (match_dup 0)
3951                    (match_dup 6)))]
3952   {
3953   machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
3954                                            operands[2], operands[3]);
3955   enum rtx_code rc = minmax_code (operands[4]);
3956   operands[4] = gen_rtx_fmt_ee (rc, VOIDmode,
3957                                 operands[2], operands[3]);
3959   if (mode == CCFPmode || mode == CCFPEmode)
3960     rc = reverse_condition_maybe_unordered (rc);
3961   else
3962     rc = reverse_condition (rc);
3963   operands[5] = gen_rtx_fmt_ee (rc, SImode, operands[2], operands[3]);
3964   if (CONST_INT_P (operands[3]))
3965     operands[6] = plus_constant (SImode, operands[1], -INTVAL (operands[3]));
3966   else
3967     operands[6] = gen_rtx_MINUS (SImode, operands[1], operands[3]);
3968   }
3969   [(set_attr "conds" "clob")
3970    (set (attr "length")
3971         (if_then_else (eq_attr "is_thumb" "yes")
3972                       (const_int 14)
3973                       (const_int 12)))
3974    (set_attr "type" "multiple")]
3977 (define_code_iterator SAT [smin smax])
3978 (define_code_iterator SATrev [smin smax])
3979 (define_code_attr SATlo [(smin "1") (smax "2")])
3980 (define_code_attr SAThi [(smin "2") (smax "1")])
3982 (define_insn "*satsi_<SAT:code>"
3983   [(set (match_operand:SI 0 "s_register_operand" "=r")
3984         (SAT:SI (SATrev:SI (match_operand:SI 3 "s_register_operand" "r")
3985                            (match_operand:SI 1 "const_int_operand" "i"))
3986                 (match_operand:SI 2 "const_int_operand" "i")))]
3987   "TARGET_32BIT && arm_arch6 && <SAT:CODE> != <SATrev:CODE>
3988    && arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>], NULL, NULL)"
3990   int mask;
3991   bool signed_sat;
3992   if (!arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>],
3993                                &mask, &signed_sat))
3994     gcc_unreachable ();
3996   operands[1] = GEN_INT (mask);
3997   if (signed_sat)
3998     return "ssat%?\t%0, %1, %3";
3999   else
4000     return "usat%?\t%0, %1, %3";
4002   [(set_attr "predicable" "yes")
4003    (set_attr "predicable_short_it" "no")
4004    (set_attr "type" "alus_imm")]
4007 (define_insn "*satsi_<SAT:code>_shift"
4008   [(set (match_operand:SI 0 "s_register_operand" "=r")
4009         (SAT:SI (SATrev:SI (match_operator:SI 3 "sat_shift_operator"
4010                              [(match_operand:SI 4 "s_register_operand" "r")
4011                               (match_operand:SI 5 "const_int_operand" "i")])
4012                            (match_operand:SI 1 "const_int_operand" "i"))
4013                 (match_operand:SI 2 "const_int_operand" "i")))]
4014   "TARGET_32BIT && arm_arch6 && <SAT:CODE> != <SATrev:CODE>
4015    && arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>], NULL, NULL)"
4017   int mask;
4018   bool signed_sat;
4019   if (!arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>],
4020                                &mask, &signed_sat))
4021     gcc_unreachable ();
4023   operands[1] = GEN_INT (mask);
4024   if (signed_sat)
4025     return "ssat%?\t%0, %1, %4%S3";
4026   else
4027     return "usat%?\t%0, %1, %4%S3";
4029   [(set_attr "predicable" "yes")
4030    (set_attr "predicable_short_it" "no")
4031    (set_attr "shift" "3")
4032    (set_attr "type" "logic_shift_reg")])
4034 ;; Shift and rotation insns
4036 (define_expand "ashldi3"
4037   [(set (match_operand:DI            0 "s_register_operand" "")
4038         (ashift:DI (match_operand:DI 1 "s_register_operand" "")
4039                    (match_operand:SI 2 "general_operand" "")))]
4040   "TARGET_32BIT"
4041   "
4042   if (TARGET_NEON)
4043     {
4044       /* Delay the decision whether to use NEON or core-regs until
4045          register allocation.  */
4046       emit_insn (gen_ashldi3_neon (operands[0], operands[1], operands[2]));
4047       DONE;
4048     }
4049   else
4050     {
4051       /* Only the NEON case can handle in-memory shift counts.  */
4052       if (!reg_or_int_operand (operands[2], SImode))
4053         operands[2] = force_reg (SImode, operands[2]);
4054     }
4056   if (!CONST_INT_P (operands[2]) && TARGET_REALLY_IWMMXT)
4057     ; /* No special preparation statements; expand pattern as above.  */
4058   else
4059     {
4060       rtx scratch1, scratch2;
4062       if (operands[2] == CONST1_RTX (SImode))
4063         {
4064           emit_insn (gen_arm_ashldi3_1bit (operands[0], operands[1]));
4065           DONE;
4066         }
4068       /* Ideally we should use iwmmxt here if we could know that operands[1]
4069          ends up already living in an iwmmxt register. Otherwise it's
4070          cheaper to have the alternate code being generated than moving
4071          values to iwmmxt regs and back.  */
4073       /* Expand operation using core-registers.
4074          'FAIL' would achieve the same thing, but this is a bit smarter.  */
4075       scratch1 = gen_reg_rtx (SImode);
4076       scratch2 = gen_reg_rtx (SImode);
4077       arm_emit_coreregs_64bit_shift (ASHIFT, operands[0], operands[1],
4078                                      operands[2], scratch1, scratch2);
4079       DONE;
4080     }
4081   "
4084 (define_insn "arm_ashldi3_1bit"
4085   [(set (match_operand:DI            0 "s_register_operand" "=r,&r")
4086         (ashift:DI (match_operand:DI 1 "s_register_operand" "0,r")
4087                    (const_int 1)))
4088    (clobber (reg:CC CC_REGNUM))]
4089   "TARGET_32BIT"
4090   "movs\\t%Q0, %Q1, asl #1\;adc\\t%R0, %R1, %R1"
4091   [(set_attr "conds" "clob")
4092    (set_attr "length" "8")
4093    (set_attr "type" "multiple")]
4096 (define_expand "ashlsi3"
4097   [(set (match_operand:SI            0 "s_register_operand" "")
4098         (ashift:SI (match_operand:SI 1 "s_register_operand" "")
4099                    (match_operand:SI 2 "arm_rhs_operand" "")))]
4100   "TARGET_EITHER"
4101   "
4102   if (CONST_INT_P (operands[2])
4103       && (UINTVAL (operands[2])) > 31)
4104     {
4105       emit_insn (gen_movsi (operands[0], const0_rtx));
4106       DONE;
4107     }
4108   "
4111 (define_expand "ashrdi3"
4112   [(set (match_operand:DI              0 "s_register_operand" "")
4113         (ashiftrt:DI (match_operand:DI 1 "s_register_operand" "")
4114                      (match_operand:SI 2 "reg_or_int_operand" "")))]
4115   "TARGET_32BIT"
4116   "
4117   if (TARGET_NEON)
4118     {
4119       /* Delay the decision whether to use NEON or core-regs until
4120          register allocation.  */
4121       emit_insn (gen_ashrdi3_neon (operands[0], operands[1], operands[2]));
4122       DONE;
4123     }
4125   if (!CONST_INT_P (operands[2]) && TARGET_REALLY_IWMMXT)
4126     ; /* No special preparation statements; expand pattern as above.  */
4127   else
4128     {
4129       rtx scratch1, scratch2;
4131       if (operands[2] == CONST1_RTX (SImode))
4132         {
4133           emit_insn (gen_arm_ashrdi3_1bit (operands[0], operands[1]));
4134           DONE;
4135         }
4137       /* Ideally we should use iwmmxt here if we could know that operands[1]
4138          ends up already living in an iwmmxt register. Otherwise it's
4139          cheaper to have the alternate code being generated than moving
4140          values to iwmmxt regs and back.  */
4142       /* Expand operation using core-registers.
4143          'FAIL' would achieve the same thing, but this is a bit smarter.  */
4144       scratch1 = gen_reg_rtx (SImode);
4145       scratch2 = gen_reg_rtx (SImode);
4146       arm_emit_coreregs_64bit_shift (ASHIFTRT, operands[0], operands[1],
4147                                      operands[2], scratch1, scratch2);
4148       DONE;
4149     }
4150   "
4153 (define_insn "arm_ashrdi3_1bit"
4154   [(set (match_operand:DI              0 "s_register_operand" "=r,&r")
4155         (ashiftrt:DI (match_operand:DI 1 "s_register_operand" "0,r")
4156                      (const_int 1)))
4157    (clobber (reg:CC CC_REGNUM))]
4158   "TARGET_32BIT"
4159   "movs\\t%R0, %R1, asr #1\;mov\\t%Q0, %Q1, rrx"
4160   [(set_attr "conds" "clob")
4161    (set_attr "length" "8")
4162    (set_attr "type" "multiple")]
4165 (define_expand "ashrsi3"
4166   [(set (match_operand:SI              0 "s_register_operand" "")
4167         (ashiftrt:SI (match_operand:SI 1 "s_register_operand" "")
4168                      (match_operand:SI 2 "arm_rhs_operand" "")))]
4169   "TARGET_EITHER"
4170   "
4171   if (CONST_INT_P (operands[2])
4172       && UINTVAL (operands[2]) > 31)
4173     operands[2] = GEN_INT (31);
4174   "
4177 (define_expand "lshrdi3"
4178   [(set (match_operand:DI              0 "s_register_operand" "")
4179         (lshiftrt:DI (match_operand:DI 1 "s_register_operand" "")
4180                      (match_operand:SI 2 "reg_or_int_operand" "")))]
4181   "TARGET_32BIT"
4182   "
4183   if (TARGET_NEON)
4184     {
4185       /* Delay the decision whether to use NEON or core-regs until
4186          register allocation.  */
4187       emit_insn (gen_lshrdi3_neon (operands[0], operands[1], operands[2]));
4188       DONE;
4189     }
4191   if (!CONST_INT_P (operands[2]) && TARGET_REALLY_IWMMXT)
4192     ; /* No special preparation statements; expand pattern as above.  */
4193   else
4194     {
4195       rtx scratch1, scratch2;
4197       if (operands[2] == CONST1_RTX (SImode))
4198         {
4199           emit_insn (gen_arm_lshrdi3_1bit (operands[0], operands[1]));
4200           DONE;
4201         }
4203       /* Ideally we should use iwmmxt here if we could know that operands[1]
4204          ends up already living in an iwmmxt register. Otherwise it's
4205          cheaper to have the alternate code being generated than moving
4206          values to iwmmxt regs and back.  */
4208       /* Expand operation using core-registers.
4209          'FAIL' would achieve the same thing, but this is a bit smarter.  */
4210       scratch1 = gen_reg_rtx (SImode);
4211       scratch2 = gen_reg_rtx (SImode);
4212       arm_emit_coreregs_64bit_shift (LSHIFTRT, operands[0], operands[1],
4213                                      operands[2], scratch1, scratch2);
4214       DONE;
4215     }
4216   "
4219 (define_insn "arm_lshrdi3_1bit"
4220   [(set (match_operand:DI              0 "s_register_operand" "=r,&r")
4221         (lshiftrt:DI (match_operand:DI 1 "s_register_operand" "0,r")
4222                      (const_int 1)))
4223    (clobber (reg:CC CC_REGNUM))]
4224   "TARGET_32BIT"
4225   "movs\\t%R0, %R1, lsr #1\;mov\\t%Q0, %Q1, rrx"
4226   [(set_attr "conds" "clob")
4227    (set_attr "length" "8")
4228    (set_attr "type" "multiple")]
4231 (define_expand "lshrsi3"
4232   [(set (match_operand:SI              0 "s_register_operand" "")
4233         (lshiftrt:SI (match_operand:SI 1 "s_register_operand" "")
4234                      (match_operand:SI 2 "arm_rhs_operand" "")))]
4235   "TARGET_EITHER"
4236   "
4237   if (CONST_INT_P (operands[2])
4238       && (UINTVAL (operands[2])) > 31)
4239     {
4240       emit_insn (gen_movsi (operands[0], const0_rtx));
4241       DONE;
4242     }
4243   "
4246 (define_expand "rotlsi3"
4247   [(set (match_operand:SI              0 "s_register_operand" "")
4248         (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
4249                      (match_operand:SI 2 "reg_or_int_operand" "")))]
4250   "TARGET_32BIT"
4251   "
4252   if (CONST_INT_P (operands[2]))
4253     operands[2] = GEN_INT ((32 - INTVAL (operands[2])) % 32);
4254   else
4255     {
4256       rtx reg = gen_reg_rtx (SImode);
4257       emit_insn (gen_subsi3 (reg, GEN_INT (32), operands[2]));
4258       operands[2] = reg;
4259     }
4260   "
4263 (define_expand "rotrsi3"
4264   [(set (match_operand:SI              0 "s_register_operand" "")
4265         (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
4266                      (match_operand:SI 2 "arm_rhs_operand" "")))]
4267   "TARGET_EITHER"
4268   "
4269   if (TARGET_32BIT)
4270     {
4271       if (CONST_INT_P (operands[2])
4272           && UINTVAL (operands[2]) > 31)
4273         operands[2] = GEN_INT (INTVAL (operands[2]) % 32);
4274     }
4275   else /* TARGET_THUMB1 */
4276     {
4277       if (CONST_INT_P (operands [2]))
4278         operands [2] = force_reg (SImode, operands[2]);
4279     }
4280   "
4283 (define_insn "*arm_shiftsi3"
4284   [(set (match_operand:SI   0 "s_register_operand" "=l,l,r,r")
4285         (match_operator:SI  3 "shift_operator"
4286          [(match_operand:SI 1 "s_register_operand"  "0,l,r,r")
4287           (match_operand:SI 2 "reg_or_int_operand" "l,M,M,r")]))]
4288   "TARGET_32BIT"
4289   "* return arm_output_shift(operands, 0);"
4290   [(set_attr "predicable" "yes")
4291    (set_attr "arch" "t2,t2,*,*")
4292    (set_attr "predicable_short_it" "yes,yes,no,no")
4293    (set_attr "length" "4")
4294    (set_attr "shift" "1")
4295    (set_attr "type" "alu_shift_reg,alu_shift_imm,alu_shift_imm,alu_shift_reg")]
4298 (define_insn "*shiftsi3_compare0"
4299   [(set (reg:CC_NOOV CC_REGNUM)
4300         (compare:CC_NOOV (match_operator:SI 3 "shift_operator"
4301                           [(match_operand:SI 1 "s_register_operand" "r,r")
4302                            (match_operand:SI 2 "arm_rhs_operand" "M,r")])
4303                          (const_int 0)))
4304    (set (match_operand:SI 0 "s_register_operand" "=r,r")
4305         (match_op_dup 3 [(match_dup 1) (match_dup 2)]))]
4306   "TARGET_32BIT"
4307   "* return arm_output_shift(operands, 1);"
4308   [(set_attr "conds" "set")
4309    (set_attr "shift" "1")
4310    (set_attr "type" "alus_shift_imm,alus_shift_reg")]
4313 (define_insn "*shiftsi3_compare0_scratch"
4314   [(set (reg:CC_NOOV CC_REGNUM)
4315         (compare:CC_NOOV (match_operator:SI 3 "shift_operator"
4316                           [(match_operand:SI 1 "s_register_operand" "r,r")
4317                            (match_operand:SI 2 "arm_rhs_operand" "M,r")])
4318                          (const_int 0)))
4319    (clobber (match_scratch:SI 0 "=r,r"))]
4320   "TARGET_32BIT"
4321   "* return arm_output_shift(operands, 1);"
4322   [(set_attr "conds" "set")
4323    (set_attr "shift" "1")
4324    (set_attr "type" "shift_imm,shift_reg")]
4327 (define_insn "*not_shiftsi"
4328   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4329         (not:SI (match_operator:SI 3 "shift_operator"
4330                  [(match_operand:SI 1 "s_register_operand" "r,r")
4331                   (match_operand:SI 2 "shift_amount_operand" "M,rM")])))]
4332   "TARGET_32BIT"
4333   "mvn%?\\t%0, %1%S3"
4334   [(set_attr "predicable" "yes")
4335    (set_attr "predicable_short_it" "no")
4336    (set_attr "shift" "1")
4337    (set_attr "arch" "32,a")
4338    (set_attr "type" "mvn_shift,mvn_shift_reg")])
4340 (define_insn "*not_shiftsi_compare0"
4341   [(set (reg:CC_NOOV CC_REGNUM)
4342         (compare:CC_NOOV
4343          (not:SI (match_operator:SI 3 "shift_operator"
4344                   [(match_operand:SI 1 "s_register_operand" "r,r")
4345                    (match_operand:SI 2 "shift_amount_operand" "M,rM")]))
4346          (const_int 0)))
4347    (set (match_operand:SI 0 "s_register_operand" "=r,r")
4348         (not:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])))]
4349   "TARGET_32BIT"
4350   "mvns%?\\t%0, %1%S3"
4351   [(set_attr "conds" "set")
4352    (set_attr "shift" "1")
4353    (set_attr "arch" "32,a")
4354    (set_attr "type" "mvn_shift,mvn_shift_reg")])
4356 (define_insn "*not_shiftsi_compare0_scratch"
4357   [(set (reg:CC_NOOV CC_REGNUM)
4358         (compare:CC_NOOV
4359          (not:SI (match_operator:SI 3 "shift_operator"
4360                   [(match_operand:SI 1 "s_register_operand" "r,r")
4361                    (match_operand:SI 2 "shift_amount_operand" "M,rM")]))
4362          (const_int 0)))
4363    (clobber (match_scratch:SI 0 "=r,r"))]
4364   "TARGET_32BIT"
4365   "mvns%?\\t%0, %1%S3"
4366   [(set_attr "conds" "set")
4367    (set_attr "shift" "1")
4368    (set_attr "arch" "32,a")
4369    (set_attr "type" "mvn_shift,mvn_shift_reg")])
4371 ;; We don't really have extzv, but defining this using shifts helps
4372 ;; to reduce register pressure later on.
4374 (define_expand "extzv"
4375   [(set (match_operand 0 "s_register_operand" "")
4376         (zero_extract (match_operand 1 "nonimmediate_operand" "")
4377                       (match_operand 2 "const_int_operand" "")
4378                       (match_operand 3 "const_int_operand" "")))]
4379   "TARGET_THUMB1 || arm_arch_thumb2"
4380   "
4381   {
4382     HOST_WIDE_INT lshift = 32 - INTVAL (operands[2]) - INTVAL (operands[3]);
4383     HOST_WIDE_INT rshift = 32 - INTVAL (operands[2]);
4384     
4385     if (arm_arch_thumb2)
4386       {
4387         HOST_WIDE_INT width = INTVAL (operands[2]);
4388         HOST_WIDE_INT bitpos = INTVAL (operands[3]);
4390         if (unaligned_access && MEM_P (operands[1])
4391             && (width == 16 || width == 32) && (bitpos % BITS_PER_UNIT) == 0)
4392           {
4393             rtx base_addr;
4395             if (BYTES_BIG_ENDIAN)
4396               bitpos = GET_MODE_BITSIZE (GET_MODE (operands[0])) - width
4397                        - bitpos;
4399             if (width == 32)
4400               {
4401                 base_addr = adjust_address (operands[1], SImode,
4402                                             bitpos / BITS_PER_UNIT);
4403                 emit_insn (gen_unaligned_loadsi (operands[0], base_addr));
4404               }
4405             else
4406               {
4407                 rtx dest = operands[0];
4408                 rtx tmp = gen_reg_rtx (SImode);
4410                 /* We may get a paradoxical subreg here.  Strip it off.  */
4411                 if (GET_CODE (dest) == SUBREG
4412                     && GET_MODE (dest) == SImode
4413                     && GET_MODE (SUBREG_REG (dest)) == HImode)
4414                   dest = SUBREG_REG (dest);
4416                 if (GET_MODE_BITSIZE (GET_MODE (dest)) != width)
4417                   FAIL;
4419                 base_addr = adjust_address (operands[1], HImode,
4420                                             bitpos / BITS_PER_UNIT);
4421                 emit_insn (gen_unaligned_loadhiu (tmp, base_addr));
4422                 emit_move_insn (gen_lowpart (SImode, dest), tmp);
4423               }
4424             DONE;
4425           }
4426         else if (s_register_operand (operands[1], GET_MODE (operands[1])))
4427           {
4428             emit_insn (gen_extzv_t2 (operands[0], operands[1], operands[2],
4429                                      operands[3]));
4430             DONE;
4431           }
4432         else
4433           FAIL;
4434       }
4435     
4436     if (!s_register_operand (operands[1], GET_MODE (operands[1])))
4437       FAIL;
4439     operands[3] = GEN_INT (rshift);
4440     
4441     if (lshift == 0)
4442       {
4443         emit_insn (gen_lshrsi3 (operands[0], operands[1], operands[3]));
4444         DONE;
4445       }
4446       
4447     emit_insn (gen_extzv_t1 (operands[0], operands[1], GEN_INT (lshift),
4448                              operands[3], gen_reg_rtx (SImode)));
4449     DONE;
4450   }"
4453 ;; Helper for extzv, for the Thumb-1 register-shifts case.
4455 (define_expand "extzv_t1"
4456   [(set (match_operand:SI 4 "s_register_operand" "")
4457         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
4458                    (match_operand:SI 2 "const_int_operand" "")))
4459    (set (match_operand:SI 0 "s_register_operand" "")
4460         (lshiftrt:SI (match_dup 4)
4461                      (match_operand:SI 3 "const_int_operand" "")))]
4462   "TARGET_THUMB1"
4463   "")
4465 (define_expand "extv"
4466   [(set (match_operand 0 "s_register_operand" "")
4467         (sign_extract (match_operand 1 "nonimmediate_operand" "")
4468                       (match_operand 2 "const_int_operand" "")
4469                       (match_operand 3 "const_int_operand" "")))]
4470   "arm_arch_thumb2"
4472   HOST_WIDE_INT width = INTVAL (operands[2]);
4473   HOST_WIDE_INT bitpos = INTVAL (operands[3]);
4475   if (unaligned_access && MEM_P (operands[1]) && (width == 16 || width == 32)
4476       && (bitpos % BITS_PER_UNIT)  == 0)
4477     {
4478       rtx base_addr;
4479       
4480       if (BYTES_BIG_ENDIAN)
4481         bitpos = GET_MODE_BITSIZE (GET_MODE (operands[0])) - width - bitpos;
4482       
4483       if (width == 32)
4484         {
4485           base_addr = adjust_address (operands[1], SImode,
4486                                       bitpos / BITS_PER_UNIT);
4487           emit_insn (gen_unaligned_loadsi (operands[0], base_addr));
4488         }
4489       else
4490         {
4491           rtx dest = operands[0];
4492           rtx tmp = gen_reg_rtx (SImode);
4493           
4494           /* We may get a paradoxical subreg here.  Strip it off.  */
4495           if (GET_CODE (dest) == SUBREG
4496               && GET_MODE (dest) == SImode
4497               && GET_MODE (SUBREG_REG (dest)) == HImode)
4498             dest = SUBREG_REG (dest);
4499           
4500           if (GET_MODE_BITSIZE (GET_MODE (dest)) != width)
4501             FAIL;
4502           
4503           base_addr = adjust_address (operands[1], HImode,
4504                                       bitpos / BITS_PER_UNIT);
4505           emit_insn (gen_unaligned_loadhis (tmp, base_addr));
4506           emit_move_insn (gen_lowpart (SImode, dest), tmp);
4507         }
4509       DONE;
4510     }
4511   else if (!s_register_operand (operands[1], GET_MODE (operands[1])))
4512     FAIL;
4513   else if (GET_MODE (operands[0]) == SImode
4514            && GET_MODE (operands[1]) == SImode)
4515     {
4516       emit_insn (gen_extv_regsi (operands[0], operands[1], operands[2],
4517                                  operands[3]));
4518       DONE;
4519     }
4521   FAIL;
4524 ; Helper to expand register forms of extv with the proper modes.
4526 (define_expand "extv_regsi"
4527   [(set (match_operand:SI 0 "s_register_operand" "")
4528         (sign_extract:SI (match_operand:SI 1 "s_register_operand" "")
4529                          (match_operand 2 "const_int_operand" "")
4530                          (match_operand 3 "const_int_operand" "")))]
4531   ""
4535 ; ARMv6+ unaligned load/store instructions (used for packed structure accesses).
4537 (define_insn "unaligned_loadsi"
4538   [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4539         (unspec:SI [(match_operand:SI 1 "memory_operand" "Uw,m")]
4540                    UNSPEC_UNALIGNED_LOAD))]
4541   "unaligned_access"
4542   "ldr%?\t%0, %1\t@ unaligned"
4543   [(set_attr "arch" "t2,any")
4544    (set_attr "length" "2,4")
4545    (set_attr "predicable" "yes")
4546    (set_attr "predicable_short_it" "yes,no")
4547    (set_attr "type" "load1")])
4549 (define_insn "unaligned_loadhis"
4550   [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4551         (sign_extend:SI
4552           (unspec:HI [(match_operand:HI 1 "memory_operand" "Uw,Uh")]
4553                      UNSPEC_UNALIGNED_LOAD)))]
4554   "unaligned_access"
4555   "ldrsh%?\t%0, %1\t@ unaligned"
4556   [(set_attr "arch" "t2,any")
4557    (set_attr "length" "2,4")
4558    (set_attr "predicable" "yes")
4559    (set_attr "predicable_short_it" "yes,no")
4560    (set_attr "type" "load_byte")])
4562 (define_insn "unaligned_loadhiu"
4563   [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4564         (zero_extend:SI
4565           (unspec:HI [(match_operand:HI 1 "memory_operand" "Uw,m")]
4566                      UNSPEC_UNALIGNED_LOAD)))]
4567   "unaligned_access"
4568   "ldrh%?\t%0, %1\t@ unaligned"
4569   [(set_attr "arch" "t2,any")
4570    (set_attr "length" "2,4")
4571    (set_attr "predicable" "yes")
4572    (set_attr "predicable_short_it" "yes,no")
4573    (set_attr "type" "load_byte")])
4575 (define_insn "unaligned_storesi"
4576   [(set (match_operand:SI 0 "memory_operand" "=Uw,m")
4577         (unspec:SI [(match_operand:SI 1 "s_register_operand" "l,r")]
4578                    UNSPEC_UNALIGNED_STORE))]
4579   "unaligned_access"
4580   "str%?\t%1, %0\t@ unaligned"
4581   [(set_attr "arch" "t2,any")
4582    (set_attr "length" "2,4")
4583    (set_attr "predicable" "yes")
4584    (set_attr "predicable_short_it" "yes,no")
4585    (set_attr "type" "store1")])
4587 (define_insn "unaligned_storehi"
4588   [(set (match_operand:HI 0 "memory_operand" "=Uw,m")
4589         (unspec:HI [(match_operand:HI 1 "s_register_operand" "l,r")]
4590                    UNSPEC_UNALIGNED_STORE))]
4591   "unaligned_access"
4592   "strh%?\t%1, %0\t@ unaligned"
4593   [(set_attr "arch" "t2,any")
4594    (set_attr "length" "2,4")
4595    (set_attr "predicable" "yes")
4596    (set_attr "predicable_short_it" "yes,no")
4597    (set_attr "type" "store1")])
4600 (define_insn "*extv_reg"
4601   [(set (match_operand:SI 0 "s_register_operand" "=r")
4602         (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
4603                           (match_operand:SI 2 "const_int_operand" "n")
4604                           (match_operand:SI 3 "const_int_operand" "n")))]
4605   "arm_arch_thumb2
4606    && IN_RANGE (INTVAL (operands[3]), 0, 31)
4607    && IN_RANGE (INTVAL (operands[2]), 1, 32 - INTVAL (operands[3]))"
4608   "sbfx%?\t%0, %1, %3, %2"
4609   [(set_attr "length" "4")
4610    (set_attr "predicable" "yes")
4611    (set_attr "predicable_short_it" "no")
4612    (set_attr "type" "bfm")]
4615 (define_insn "extzv_t2"
4616   [(set (match_operand:SI 0 "s_register_operand" "=r")
4617         (zero_extract:SI (match_operand:SI 1 "s_register_operand" "r")
4618                           (match_operand:SI 2 "const_int_operand" "n")
4619                           (match_operand:SI 3 "const_int_operand" "n")))]
4620   "arm_arch_thumb2
4621    && IN_RANGE (INTVAL (operands[3]), 0, 31)
4622    && IN_RANGE (INTVAL (operands[2]), 1, 32 - INTVAL (operands[3]))"
4623   "ubfx%?\t%0, %1, %3, %2"
4624   [(set_attr "length" "4")
4625    (set_attr "predicable" "yes")
4626    (set_attr "predicable_short_it" "no")
4627    (set_attr "type" "bfm")]
4631 ;; Division instructions
4632 (define_insn "divsi3"
4633   [(set (match_operand:SI         0 "s_register_operand" "=r,r")
4634         (div:SI (match_operand:SI 1 "s_register_operand"  "r,r")
4635                 (match_operand:SI 2 "s_register_operand"  "r,r")))]
4636   "TARGET_IDIV"
4637   "@
4638    sdiv%?\t%0, %1, %2
4639    sdiv\t%0, %1, %2"
4640   [(set_attr "arch" "32,v8mb")
4641    (set_attr "predicable" "yes")
4642    (set_attr "predicable_short_it" "no")
4643    (set_attr "type" "sdiv")]
4646 (define_insn "udivsi3"
4647   [(set (match_operand:SI          0 "s_register_operand" "=r,r")
4648         (udiv:SI (match_operand:SI 1 "s_register_operand"  "r,r")
4649                  (match_operand:SI 2 "s_register_operand"  "r,r")))]
4650   "TARGET_IDIV"
4651   "@
4652    udiv%?\t%0, %1, %2
4653    udiv\t%0, %1, %2"
4654   [(set_attr "arch" "32,v8mb")
4655    (set_attr "predicable" "yes")
4656    (set_attr "predicable_short_it" "no")
4657    (set_attr "type" "udiv")]
4661 ;; Unary arithmetic insns
4663 (define_expand "negvsi3"
4664   [(match_operand:SI 0 "register_operand")
4665    (match_operand:SI 1 "register_operand")
4666    (match_operand 2 "")]
4667   "TARGET_32BIT"
4669   emit_insn (gen_subsi3_compare (operands[0], const0_rtx, operands[1]));
4670   arm_gen_unlikely_cbranch (NE, CC_Vmode, operands[2]);
4672   DONE;
4675 (define_expand "negvdi3"
4676   [(match_operand:DI 0 "register_operand")
4677    (match_operand:DI 1 "register_operand")
4678    (match_operand 2 "")]
4679   "TARGET_ARM"
4681   emit_insn (gen_negdi2_compare (operands[0], operands[1]));
4682   arm_gen_unlikely_cbranch (NE, CC_Vmode, operands[2]);
4684   DONE;
4688 (define_insn_and_split "negdi2_compare"
4689   [(set (reg:CC CC_REGNUM)
4690         (compare:CC
4691           (const_int 0)
4692           (match_operand:DI 1 "register_operand" "0,r")))
4693    (set (match_operand:DI 0 "register_operand" "=r,&r")
4694         (minus:DI (const_int 0) (match_dup 1)))]
4695   "TARGET_ARM"
4696   "#"
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)
4701                                            (match_dup 1)))])
4702    (parallel [(set (reg:CC CC_REGNUM)
4703                    (compare:CC (const_int 0) (match_dup 3)))
4704              (set (match_dup 2)
4705                   (minus:SI
4706                    (minus:SI (const_int 0) (match_dup 3))
4707                    (ltu:SI (reg:CC_C CC_REGNUM)
4708                            (const_int 0))))])]
4709   {
4710     operands[2] = gen_highpart (SImode, operands[0]);
4711     operands[0] = gen_lowpart (SImode, operands[0]);
4712     operands[3] = gen_highpart (SImode, operands[1]);
4713     operands[1] = gen_lowpart (SImode, operands[1]);
4714   }
4715   [(set_attr "conds" "set")
4716    (set_attr "length" "8")
4717    (set_attr "type" "multiple")]
4720 (define_expand "negdi2"
4721  [(parallel
4722    [(set (match_operand:DI 0 "s_register_operand" "")
4723          (neg:DI (match_operand:DI 1 "s_register_operand" "")))
4724     (clobber (reg:CC CC_REGNUM))])]
4725   "TARGET_EITHER"
4726   {
4727     if (TARGET_NEON)
4728       {
4729         emit_insn (gen_negdi2_neon (operands[0], operands[1]));
4730         DONE;
4731       }
4732   }
4735 ;; The constraints here are to prevent a *partial* overlap (where %Q0 == %R1).
4736 ;; The first alternative allows the common case of a *full* overlap.
4737 (define_insn_and_split "*negdi2_insn"
4738   [(set (match_operand:DI         0 "s_register_operand" "=r,&r")
4739         (neg:DI (match_operand:DI 1 "s_register_operand"  "0,r")))
4740    (clobber (reg:CC CC_REGNUM))]
4741   "TARGET_32BIT"
4742   "#"   ; rsbs %Q0, %Q1, #0; rsc %R0, %R1, #0          (ARM)
4743         ; negs %Q0, %Q1    ; sbc %R0, %R1, %R1, lsl #1 (Thumb-2)
4744   "&& reload_completed"
4745   [(parallel [(set (reg:CC CC_REGNUM)
4746                    (compare:CC (const_int 0) (match_dup 1)))
4747               (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1)))])
4748    (set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3))
4749                                 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
4750   {
4751     operands[2] = gen_highpart (SImode, operands[0]);
4752     operands[0] = gen_lowpart (SImode, operands[0]);
4753     operands[3] = gen_highpart (SImode, operands[1]);
4754     operands[1] = gen_lowpart (SImode, operands[1]);
4755   }
4756   [(set_attr "conds" "clob")
4757    (set_attr "length" "8")
4758    (set_attr "type" "multiple")]
4761 (define_insn "*negsi2_carryin_compare"
4762   [(set (reg:CC CC_REGNUM)
4763         (compare:CC (const_int 0)
4764                     (match_operand:SI 1 "s_register_operand" "r")))
4765    (set (match_operand:SI 0 "s_register_operand" "=r")
4766         (minus:SI (minus:SI (const_int 0)
4767                             (match_dup 1))
4768                   (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
4769   "TARGET_ARM"
4770   "rscs\\t%0, %1, #0"
4771   [(set_attr "conds" "set")
4772    (set_attr "type" "alus_imm")]
4775 (define_expand "negsi2"
4776   [(set (match_operand:SI         0 "s_register_operand" "")
4777         (neg:SI (match_operand:SI 1 "s_register_operand" "")))]
4778   "TARGET_EITHER"
4779   ""
4782 (define_insn "*arm_negsi2"
4783   [(set (match_operand:SI         0 "s_register_operand" "=l,r")
4784         (neg:SI (match_operand:SI 1 "s_register_operand" "l,r")))]
4785   "TARGET_32BIT"
4786   "rsb%?\\t%0, %1, #0"
4787   [(set_attr "predicable" "yes")
4788    (set_attr "predicable_short_it" "yes,no")
4789    (set_attr "arch" "t2,*")
4790    (set_attr "length" "4")
4791    (set_attr "type" "alu_sreg")]
4794 (define_expand "negsf2"
4795   [(set (match_operand:SF         0 "s_register_operand" "")
4796         (neg:SF (match_operand:SF 1 "s_register_operand" "")))]
4797   "TARGET_32BIT && TARGET_HARD_FLOAT"
4798   ""
4801 (define_expand "negdf2"
4802   [(set (match_operand:DF         0 "s_register_operand" "")
4803         (neg:DF (match_operand:DF 1 "s_register_operand" "")))]
4804   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
4805   "")
4807 (define_insn_and_split "*zextendsidi_negsi"
4808   [(set (match_operand:DI 0 "s_register_operand" "=r")
4809         (zero_extend:DI (neg:SI (match_operand:SI 1 "s_register_operand" "r"))))]
4810    "TARGET_32BIT"
4811    "#"
4812    ""
4813    [(set (match_dup 2)
4814          (neg:SI (match_dup 1)))
4815     (set (match_dup 3)
4816          (const_int 0))]
4817    {
4818       operands[2] = gen_lowpart (SImode, operands[0]);
4819       operands[3] = gen_highpart (SImode, operands[0]);
4820    }
4821  [(set_attr "length" "8")
4822   (set_attr "type" "multiple")]
4825 ;; Negate an extended 32-bit value.
4826 (define_insn_and_split "*negdi_extendsidi"
4827   [(set (match_operand:DI 0 "s_register_operand" "=l,r")
4828         (neg:DI (sign_extend:DI
4829                  (match_operand:SI 1 "s_register_operand" "l,r"))))
4830    (clobber (reg:CC CC_REGNUM))]
4831   "TARGET_32BIT"
4832   "#"
4833   "&& reload_completed"
4834   [(const_int 0)]
4835   {
4836     rtx low = gen_lowpart (SImode, operands[0]);
4837     rtx high = gen_highpart (SImode, operands[0]);
4839     if (reg_overlap_mentioned_p (low, operands[1]))
4840       {
4841         /* Input overlaps the low word of the output.  Use:
4842                 asr     Rhi, Rin, #31
4843                 rsbs    Rlo, Rin, #0
4844                 rsc     Rhi, Rhi, #0 (thumb2: sbc Rhi, Rhi, Rhi, lsl #1).  */
4845         rtx cc_reg = gen_rtx_REG (CC_Cmode, CC_REGNUM);
4847         emit_insn (gen_rtx_SET (high,
4848                                 gen_rtx_ASHIFTRT (SImode, operands[1],
4849                                                   GEN_INT (31))));
4851         emit_insn (gen_subsi3_compare (low, const0_rtx, operands[1]));
4852         if (TARGET_ARM)
4853           emit_insn (gen_rtx_SET (high,
4854                                   gen_rtx_MINUS (SImode,
4855                                                  gen_rtx_MINUS (SImode,
4856                                                                 const0_rtx,
4857                                                                 high),
4858                                                  gen_rtx_LTU (SImode,
4859                                                               cc_reg,
4860                                                               const0_rtx))));
4861         else
4862           {
4863             rtx two_x = gen_rtx_ASHIFT (SImode, high, GEN_INT (1));
4864             emit_insn (gen_rtx_SET (high,
4865                                     gen_rtx_MINUS (SImode,
4866                                                    gen_rtx_MINUS (SImode,
4867                                                                   high,
4868                                                                   two_x),
4869                                                    gen_rtx_LTU (SImode,
4870                                                                 cc_reg,
4871                                                                 const0_rtx))));
4872           }
4873       }
4874     else
4875       {
4876         /* No overlap, or overlap on high word.  Use:
4877                 rsb     Rlo, Rin, #0
4878                 bic     Rhi, Rlo, Rin
4879                 asr     Rhi, Rhi, #31
4880            Flags not needed for this sequence.  */
4881         emit_insn (gen_rtx_SET (low, gen_rtx_NEG (SImode, operands[1])));
4882         emit_insn (gen_rtx_SET (high,
4883                                 gen_rtx_AND (SImode,
4884                                              gen_rtx_NOT (SImode, operands[1]),
4885                                              low)));
4886         emit_insn (gen_rtx_SET (high,
4887                                 gen_rtx_ASHIFTRT (SImode, high,
4888                                                   GEN_INT (31))));
4889       }
4890     DONE;
4891   }
4892   [(set_attr "length" "12")
4893    (set_attr "arch" "t2,*")
4894    (set_attr "type" "multiple")]
4897 (define_insn_and_split "*negdi_zero_extendsidi"
4898   [(set (match_operand:DI 0 "s_register_operand" "=r,&r")
4899         (neg:DI (zero_extend:DI (match_operand:SI 1 "s_register_operand" "0,r"))))
4900    (clobber (reg:CC CC_REGNUM))]
4901   "TARGET_32BIT"
4902   "#" ; "rsbs\\t%Q0, %1, #0\;sbc\\t%R0,%R0,%R0"
4903       ;; Don't care what register is input to sbc,
4904       ;; since we just need to propagate the carry.
4905   "&& reload_completed"
4906   [(parallel [(set (reg:CC CC_REGNUM)
4907                    (compare:CC (const_int 0) (match_dup 1)))
4908               (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1)))])
4909    (set (match_dup 2) (minus:SI (minus:SI (match_dup 2) (match_dup 2))
4910                                 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
4911   {
4912     operands[2] = gen_highpart (SImode, operands[0]);
4913     operands[0] = gen_lowpart (SImode, operands[0]);
4914   }
4915   [(set_attr "conds" "clob")
4916    (set_attr "length" "8")
4917    (set_attr "type" "multiple")]   ;; length in thumb is 4
4920 ;; abssi2 doesn't really clobber the condition codes if a different register
4921 ;; is being set.  To keep things simple, assume during rtl manipulations that
4922 ;; it does, but tell the final scan operator the truth.  Similarly for
4923 ;; (neg (abs...))
4925 (define_expand "abssi2"
4926   [(parallel
4927     [(set (match_operand:SI         0 "s_register_operand" "")
4928           (abs:SI (match_operand:SI 1 "s_register_operand" "")))
4929      (clobber (match_dup 2))])]
4930   "TARGET_EITHER"
4931   "
4932   if (TARGET_THUMB1)
4933     operands[2] = gen_rtx_SCRATCH (SImode);
4934   else
4935     operands[2] = gen_rtx_REG (CCmode, CC_REGNUM);
4938 (define_insn_and_split "*arm_abssi2"
4939   [(set (match_operand:SI 0 "s_register_operand" "=r,&r")
4940         (abs:SI (match_operand:SI 1 "s_register_operand" "0,r")))
4941    (clobber (reg:CC CC_REGNUM))]
4942   "TARGET_ARM"
4943   "#"
4944   "&& reload_completed"
4945   [(const_int 0)]
4946   {
4947    /* if (which_alternative == 0) */
4948    if (REGNO(operands[0]) == REGNO(operands[1]))
4949      {
4950       /* Emit the pattern:
4951          cmp\\t%0, #0\;rsblt\\t%0, %0, #0
4952          [(set (reg:CC CC_REGNUM)
4953                (compare:CC (match_dup 0) (const_int 0)))
4954           (cond_exec (lt:CC (reg:CC CC_REGNUM) (const_int 0))
4955                      (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1))))]
4956       */
4957       emit_insn (gen_rtx_SET (gen_rtx_REG (CCmode, CC_REGNUM),
4958                               gen_rtx_COMPARE (CCmode, operands[0], const0_rtx)));
4959       emit_insn (gen_rtx_COND_EXEC (VOIDmode,
4960                                     (gen_rtx_LT (SImode,
4961                                                  gen_rtx_REG (CCmode, CC_REGNUM),
4962                                                  const0_rtx)),
4963                                     (gen_rtx_SET (operands[0],
4964                                                   (gen_rtx_MINUS (SImode,
4965                                                                   const0_rtx,
4966                                                                   operands[1]))))));
4967       DONE;
4968      }
4969    else
4970      {
4971       /* Emit the pattern:
4972          alt1: eor%?\\t%0, %1, %1, asr #31\;sub%?\\t%0, %0, %1, asr #31
4973          [(set (match_dup 0)
4974                (xor:SI (match_dup 1)
4975                        (ashiftrt:SI (match_dup 1) (const_int 31))))
4976           (set (match_dup 0)
4977                (minus:SI (match_dup 0)
4978                       (ashiftrt:SI (match_dup 1) (const_int 31))))]
4979       */
4980       emit_insn (gen_rtx_SET (operands[0],
4981                               gen_rtx_XOR (SImode,
4982                                            gen_rtx_ASHIFTRT (SImode,
4983                                                              operands[1],
4984                                                              GEN_INT (31)),
4985                                            operands[1])));
4986       emit_insn (gen_rtx_SET (operands[0],
4987                               gen_rtx_MINUS (SImode,
4988                                              operands[0],
4989                                              gen_rtx_ASHIFTRT (SImode,
4990                                                                operands[1],
4991                                                                GEN_INT (31)))));
4992       DONE;
4993      }
4994   }
4995   [(set_attr "conds" "clob,*")
4996    (set_attr "shift" "1")
4997    (set_attr "predicable" "no, yes")
4998    (set_attr "length" "8")
4999    (set_attr "type" "multiple")]
5002 (define_insn_and_split "*arm_neg_abssi2"
5003   [(set (match_operand:SI 0 "s_register_operand" "=r,&r")
5004         (neg:SI (abs:SI (match_operand:SI 1 "s_register_operand" "0,r"))))
5005    (clobber (reg:CC CC_REGNUM))]
5006   "TARGET_ARM"
5007   "#"
5008   "&& reload_completed"
5009   [(const_int 0)]
5010   {
5011    /* if (which_alternative == 0) */
5012    if (REGNO (operands[0]) == REGNO (operands[1]))
5013      {
5014       /* Emit the pattern:
5015          cmp\\t%0, #0\;rsbgt\\t%0, %0, #0
5016       */
5017       emit_insn (gen_rtx_SET (gen_rtx_REG (CCmode, CC_REGNUM),
5018                               gen_rtx_COMPARE (CCmode, operands[0], const0_rtx)));
5019       emit_insn (gen_rtx_COND_EXEC (VOIDmode,
5020                                     gen_rtx_GT (SImode,
5021                                                 gen_rtx_REG (CCmode, CC_REGNUM),
5022                                                 const0_rtx),
5023                                     gen_rtx_SET (operands[0],
5024                                                  (gen_rtx_MINUS (SImode,
5025                                                                  const0_rtx,
5026                                                                  operands[1])))));
5027      }
5028    else
5029      {
5030       /* Emit the pattern:
5031          eor%?\\t%0, %1, %1, asr #31\;rsb%?\\t%0, %0, %1, asr #31
5032       */
5033       emit_insn (gen_rtx_SET (operands[0],
5034                               gen_rtx_XOR (SImode,
5035                                            gen_rtx_ASHIFTRT (SImode,
5036                                                              operands[1],
5037                                                              GEN_INT (31)),
5038                                            operands[1])));
5039       emit_insn (gen_rtx_SET (operands[0],
5040                               gen_rtx_MINUS (SImode,
5041                                              gen_rtx_ASHIFTRT (SImode,
5042                                                                operands[1],
5043                                                                GEN_INT (31)),
5044                                              operands[0])));
5045      }
5046    DONE;
5047   }
5048   [(set_attr "conds" "clob,*")
5049    (set_attr "shift" "1")
5050    (set_attr "predicable" "no, yes")
5051    (set_attr "length" "8")
5052    (set_attr "type" "multiple")]
5055 (define_expand "abssf2"
5056   [(set (match_operand:SF         0 "s_register_operand" "")
5057         (abs:SF (match_operand:SF 1 "s_register_operand" "")))]
5058   "TARGET_32BIT && TARGET_HARD_FLOAT"
5059   "")
5061 (define_expand "absdf2"
5062   [(set (match_operand:DF         0 "s_register_operand" "")
5063         (abs:DF (match_operand:DF 1 "s_register_operand" "")))]
5064   "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
5065   "")
5067 (define_expand "sqrtsf2"
5068   [(set (match_operand:SF 0 "s_register_operand" "")
5069         (sqrt:SF (match_operand:SF 1 "s_register_operand" "")))]
5070   "TARGET_32BIT && TARGET_HARD_FLOAT"
5071   "")
5073 (define_expand "sqrtdf2"
5074   [(set (match_operand:DF 0 "s_register_operand" "")
5075         (sqrt:DF (match_operand:DF 1 "s_register_operand" "")))]
5076   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
5077   "")
5079 (define_expand "one_cmpldi2"
5080   [(set (match_operand:DI 0 "s_register_operand" "")
5081         (not:DI (match_operand:DI 1 "s_register_operand" "")))]
5082   "TARGET_32BIT"
5083   "
5084   if (!TARGET_NEON && !TARGET_IWMMXT)
5085     {
5086       rtx low  = simplify_gen_unary (NOT, SImode,
5087                                      gen_lowpart (SImode, operands[1]),
5088                                      SImode);
5089       rtx high = simplify_gen_unary (NOT, SImode,
5090                                      gen_highpart_mode (SImode, DImode,
5091                                                         operands[1]),
5092                                      SImode);
5094       emit_insn (gen_rtx_SET (gen_lowpart (SImode, operands[0]), low));
5095       emit_insn (gen_rtx_SET (gen_highpart (SImode, operands[0]), high));
5097       DONE;
5098     }
5099   /* Otherwise expand pattern as above.  */
5100   "
5103 (define_insn_and_split "*one_cmpldi2_insn"
5104   [(set (match_operand:DI 0 "s_register_operand"         "=w,&r,&r,?w")
5105         (not:DI (match_operand:DI 1 "s_register_operand" " w, 0, r, w")))]
5106   "TARGET_32BIT"
5107   "@
5108    vmvn\t%P0, %P1
5109    #
5110    #
5111    vmvn\t%P0, %P1"
5112   "TARGET_32BIT && reload_completed
5113    && arm_general_register_operand (operands[0], DImode)"
5114   [(set (match_dup 0) (not:SI (match_dup 1)))
5115    (set (match_dup 2) (not:SI (match_dup 3)))]
5116   "
5117   {
5118     operands[2] = gen_highpart (SImode, operands[0]);
5119     operands[0] = gen_lowpart (SImode, operands[0]);
5120     operands[3] = gen_highpart (SImode, operands[1]);
5121     operands[1] = gen_lowpart (SImode, operands[1]);
5122   }"
5123   [(set_attr "length" "*,8,8,*")
5124    (set_attr "predicable" "no,yes,yes,no")
5125    (set_attr "type" "neon_move,multiple,multiple,neon_move")
5126    (set_attr "arch" "neon_for_64bits,*,*,avoid_neon_for_64bits")]
5129 (define_expand "one_cmplsi2"
5130   [(set (match_operand:SI         0 "s_register_operand" "")
5131         (not:SI (match_operand:SI 1 "s_register_operand" "")))]
5132   "TARGET_EITHER"
5133   ""
5136 (define_insn "*arm_one_cmplsi2"
5137   [(set (match_operand:SI         0 "s_register_operand" "=l,r")
5138         (not:SI (match_operand:SI 1 "s_register_operand"  "l,r")))]
5139   "TARGET_32BIT"
5140   "mvn%?\\t%0, %1"
5141   [(set_attr "predicable" "yes")
5142    (set_attr "predicable_short_it" "yes,no")
5143    (set_attr "arch" "t2,*")
5144    (set_attr "length" "4")
5145    (set_attr "type" "mvn_reg")]
5148 (define_insn "*notsi_compare0"
5149   [(set (reg:CC_NOOV CC_REGNUM)
5150         (compare:CC_NOOV (not:SI (match_operand:SI 1 "s_register_operand" "r"))
5151                          (const_int 0)))
5152    (set (match_operand:SI 0 "s_register_operand" "=r")
5153         (not:SI (match_dup 1)))]
5154   "TARGET_32BIT"
5155   "mvns%?\\t%0, %1"
5156   [(set_attr "conds" "set")
5157    (set_attr "type" "mvn_reg")]
5160 (define_insn "*notsi_compare0_scratch"
5161   [(set (reg:CC_NOOV CC_REGNUM)
5162         (compare:CC_NOOV (not:SI (match_operand:SI 1 "s_register_operand" "r"))
5163                          (const_int 0)))
5164    (clobber (match_scratch:SI 0 "=r"))]
5165   "TARGET_32BIT"
5166   "mvns%?\\t%0, %1"
5167   [(set_attr "conds" "set")
5168    (set_attr "type" "mvn_reg")]
5171 ;; Fixed <--> Floating conversion insns
5173 (define_expand "floatsihf2"
5174   [(set (match_operand:HF           0 "general_operand" "")
5175         (float:HF (match_operand:SI 1 "general_operand" "")))]
5176   "TARGET_EITHER"
5177   "
5178   {
5179     rtx op1 = gen_reg_rtx (SFmode);
5180     expand_float (op1, operands[1], 0);
5181     op1 = convert_to_mode (HFmode, op1, 0);
5182     emit_move_insn (operands[0], op1);
5183     DONE;
5184   }"
5187 (define_expand "floatdihf2"
5188   [(set (match_operand:HF           0 "general_operand" "")
5189         (float:HF (match_operand:DI 1 "general_operand" "")))]
5190   "TARGET_EITHER"
5191   "
5192   {
5193     rtx op1 = gen_reg_rtx (SFmode);
5194     expand_float (op1, operands[1], 0);
5195     op1 = convert_to_mode (HFmode, op1, 0);
5196     emit_move_insn (operands[0], op1);
5197     DONE;
5198   }"
5201 (define_expand "floatsisf2"
5202   [(set (match_operand:SF           0 "s_register_operand" "")
5203         (float:SF (match_operand:SI 1 "s_register_operand" "")))]
5204   "TARGET_32BIT && TARGET_HARD_FLOAT"
5205   "
5208 (define_expand "floatsidf2"
5209   [(set (match_operand:DF           0 "s_register_operand" "")
5210         (float:DF (match_operand:SI 1 "s_register_operand" "")))]
5211   "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
5212   "
5215 (define_expand "fix_trunchfsi2"
5216   [(set (match_operand:SI         0 "general_operand" "")
5217         (fix:SI (fix:HF (match_operand:HF 1 "general_operand"  ""))))]
5218   "TARGET_EITHER"
5219   "
5220   {
5221     rtx op1 = convert_to_mode (SFmode, operands[1], 0);
5222     expand_fix (operands[0], op1, 0);
5223     DONE;
5224   }"
5227 (define_expand "fix_trunchfdi2"
5228   [(set (match_operand:DI         0 "general_operand" "")
5229         (fix:DI (fix:HF (match_operand:HF 1 "general_operand"  ""))))]
5230   "TARGET_EITHER"
5231   "
5232   {
5233     rtx op1 = convert_to_mode (SFmode, operands[1], 0);
5234     expand_fix (operands[0], op1, 0);
5235     DONE;
5236   }"
5239 (define_expand "fix_truncsfsi2"
5240   [(set (match_operand:SI         0 "s_register_operand" "")
5241         (fix:SI (fix:SF (match_operand:SF 1 "s_register_operand"  ""))))]
5242   "TARGET_32BIT && TARGET_HARD_FLOAT"
5243   "
5246 (define_expand "fix_truncdfsi2"
5247   [(set (match_operand:SI         0 "s_register_operand" "")
5248         (fix:SI (fix:DF (match_operand:DF 1 "s_register_operand"  ""))))]
5249   "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
5250   "
5253 ;; Truncation insns
5255 (define_expand "truncdfsf2"
5256   [(set (match_operand:SF  0 "s_register_operand" "")
5257         (float_truncate:SF
5258          (match_operand:DF 1 "s_register_operand" "")))]
5259   "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
5260   ""
5263 ;; DFmode to HFmode conversions on targets without a single-step hardware
5264 ;; instruction for it would have to go through SFmode.  This is dangerous
5265 ;; as it introduces double rounding.
5267 ;; Disable this pattern unless we are in an unsafe math mode, or we have
5268 ;; a single-step instruction.
5270 (define_expand "truncdfhf2"
5271   [(set (match_operand:HF  0 "s_register_operand" "")
5272         (float_truncate:HF
5273          (match_operand:DF 1 "s_register_operand" "")))]
5274   "(TARGET_EITHER && flag_unsafe_math_optimizations)
5275    || (TARGET_32BIT && TARGET_FP16_TO_DOUBLE)"
5277   /* We don't have a direct instruction for this, so we must be in
5278      an unsafe math mode, and going via SFmode.  */
5280   if (!(TARGET_32BIT && TARGET_FP16_TO_DOUBLE))
5281     {
5282       rtx op1;
5283       op1 = convert_to_mode (SFmode, operands[1], 0);
5284       op1 = convert_to_mode (HFmode, op1, 0);
5285       emit_move_insn (operands[0], op1);
5286       DONE;
5287     }
5288   /* Otherwise, we will pick this up as a single instruction with
5289      no intermediary rounding.  */
5293 ;; Zero and sign extension instructions.
5295 (define_insn "zero_extend<mode>di2"
5296   [(set (match_operand:DI 0 "s_register_operand" "=w,r,?r,w")
5297         (zero_extend:DI (match_operand:QHSI 1 "<qhs_zextenddi_op>"
5298                                             "<qhs_zextenddi_cstr>")))]
5299   "TARGET_32BIT <qhs_zextenddi_cond>"
5300   "#"
5301   [(set_attr "length" "8,4,8,8")
5302    (set_attr "arch" "neon_for_64bits,*,*,avoid_neon_for_64bits")
5303    (set_attr "ce_count" "2")
5304    (set_attr "predicable" "yes")
5305    (set_attr "type" "multiple,mov_reg,multiple,multiple")]
5308 (define_insn "extend<mode>di2"
5309   [(set (match_operand:DI 0 "s_register_operand" "=w,r,?r,?r,w")
5310         (sign_extend:DI (match_operand:QHSI 1 "<qhs_extenddi_op>"
5311                                             "<qhs_extenddi_cstr>")))]
5312   "TARGET_32BIT <qhs_sextenddi_cond>"
5313   "#"
5314   [(set_attr "length" "8,4,8,8,8")
5315    (set_attr "ce_count" "2")
5316    (set_attr "shift" "1")
5317    (set_attr "predicable" "yes")
5318    (set_attr "arch" "neon_for_64bits,*,a,t,avoid_neon_for_64bits")
5319    (set_attr "type" "multiple,mov_reg,multiple,multiple,multiple")]
5322 ;; Splits for all extensions to DImode
5323 (define_split
5324   [(set (match_operand:DI 0 "s_register_operand" "")
5325         (zero_extend:DI (match_operand 1 "nonimmediate_operand" "")))]
5326   "TARGET_32BIT && reload_completed && !IS_VFP_REGNUM (REGNO (operands[0]))"
5327   [(set (match_dup 0) (match_dup 1))]
5329   rtx lo_part = gen_lowpart (SImode, operands[0]);
5330   machine_mode src_mode = GET_MODE (operands[1]);
5332   if (REG_P (operands[0])
5333       && !reg_overlap_mentioned_p (operands[0], operands[1]))
5334     emit_clobber (operands[0]);
5335   if (!REG_P (lo_part) || src_mode != SImode
5336       || !rtx_equal_p (lo_part, operands[1]))
5337     {
5338       if (src_mode == SImode)
5339         emit_move_insn (lo_part, operands[1]);
5340       else
5341         emit_insn (gen_rtx_SET (lo_part,
5342                                 gen_rtx_ZERO_EXTEND (SImode, operands[1])));
5343       operands[1] = lo_part;
5344     }
5345   operands[0] = gen_highpart (SImode, operands[0]);
5346   operands[1] = const0_rtx;
5349 (define_split
5350   [(set (match_operand:DI 0 "s_register_operand" "")
5351         (sign_extend:DI (match_operand 1 "nonimmediate_operand" "")))]
5352   "TARGET_32BIT && reload_completed && !IS_VFP_REGNUM (REGNO (operands[0]))"
5353   [(set (match_dup 0) (ashiftrt:SI (match_dup 1) (const_int 31)))]
5355   rtx lo_part = gen_lowpart (SImode, operands[0]);
5356   machine_mode src_mode = GET_MODE (operands[1]);
5358   if (REG_P (operands[0])
5359       && !reg_overlap_mentioned_p (operands[0], operands[1]))
5360     emit_clobber (operands[0]);
5362   if (!REG_P (lo_part) || src_mode != SImode
5363       || !rtx_equal_p (lo_part, operands[1]))
5364     {
5365       if (src_mode == SImode)
5366         emit_move_insn (lo_part, operands[1]);
5367       else
5368         emit_insn (gen_rtx_SET (lo_part,
5369                                 gen_rtx_SIGN_EXTEND (SImode, operands[1])));
5370       operands[1] = lo_part;
5371     }
5372   operands[0] = gen_highpart (SImode, operands[0]);
5375 (define_expand "zero_extendhisi2"
5376   [(set (match_operand:SI 0 "s_register_operand" "")
5377         (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
5378   "TARGET_EITHER"
5380   if (TARGET_ARM && !arm_arch4 && MEM_P (operands[1]))
5381     {
5382       emit_insn (gen_movhi_bytes (operands[0], operands[1]));
5383       DONE;
5384     }
5385   if (!arm_arch6 && !MEM_P (operands[1]))
5386     {
5387       rtx t = gen_lowpart (SImode, operands[1]);
5388       rtx tmp = gen_reg_rtx (SImode);
5389       emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (16)));
5390       emit_insn (gen_lshrsi3 (operands[0], tmp, GEN_INT (16)));
5391       DONE;
5392     }
5395 (define_split
5396   [(set (match_operand:SI 0 "s_register_operand" "")
5397         (zero_extend:SI (match_operand:HI 1 "s_register_operand" "")))]
5398   "!TARGET_THUMB2 && !arm_arch6"
5399   [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
5400    (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 16)))]
5402   operands[2] = gen_lowpart (SImode, operands[1]);
5405 (define_insn "*arm_zero_extendhisi2"
5406   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5407         (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
5408   "TARGET_ARM && arm_arch4 && !arm_arch6"
5409   "@
5410    #
5411    ldrh%?\\t%0, %1"
5412   [(set_attr "type" "alu_shift_reg,load_byte")
5413    (set_attr "predicable" "yes")]
5416 (define_insn "*arm_zero_extendhisi2_v6"
5417   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5418         (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,Uh")))]
5419   "TARGET_ARM && arm_arch6"
5420   "@
5421    uxth%?\\t%0, %1
5422    ldrh%?\\t%0, %1"
5423   [(set_attr "predicable" "yes")
5424    (set_attr "type" "extend,load_byte")]
5427 (define_insn "*arm_zero_extendhisi2addsi"
5428   [(set (match_operand:SI 0 "s_register_operand" "=r")
5429         (plus:SI (zero_extend:SI (match_operand:HI 1 "s_register_operand" "r"))
5430                  (match_operand:SI 2 "s_register_operand" "r")))]
5431   "TARGET_INT_SIMD"
5432   "uxtah%?\\t%0, %2, %1"
5433   [(set_attr "type" "alu_shift_reg")
5434    (set_attr "predicable" "yes")
5435    (set_attr "predicable_short_it" "no")]
5438 (define_expand "zero_extendqisi2"
5439   [(set (match_operand:SI 0 "s_register_operand" "")
5440         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))]
5441   "TARGET_EITHER"
5443   if (TARGET_ARM && !arm_arch6 && !MEM_P (operands[1]))
5444     {
5445       emit_insn (gen_andsi3 (operands[0],
5446                              gen_lowpart (SImode, operands[1]),
5447                                           GEN_INT (255)));
5448       DONE;
5449     }
5450   if (!arm_arch6 && !MEM_P (operands[1]))
5451     {
5452       rtx t = gen_lowpart (SImode, operands[1]);
5453       rtx tmp = gen_reg_rtx (SImode);
5454       emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (24)));
5455       emit_insn (gen_lshrsi3 (operands[0], tmp, GEN_INT (24)));
5456       DONE;
5457     }
5460 (define_split
5461   [(set (match_operand:SI 0 "s_register_operand" "")
5462         (zero_extend:SI (match_operand:QI 1 "s_register_operand" "")))]
5463   "!arm_arch6"
5464   [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 24)))
5465    (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 24)))]
5467   operands[2] = simplify_gen_subreg (SImode, operands[1], QImode, 0);
5468   if (TARGET_ARM)
5469     {
5470       emit_insn (gen_andsi3 (operands[0], operands[2], GEN_INT (255)));
5471       DONE;
5472     }
5475 (define_insn "*arm_zero_extendqisi2"
5476   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5477         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
5478   "TARGET_ARM && !arm_arch6"
5479   "@
5480    #
5481    ldrb%?\\t%0, %1\\t%@ zero_extendqisi2"
5482   [(set_attr "length" "8,4")
5483    (set_attr "type" "alu_shift_reg,load_byte")
5484    (set_attr "predicable" "yes")]
5487 (define_insn "*arm_zero_extendqisi2_v6"
5488   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5489         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,Uh")))]
5490   "TARGET_ARM && arm_arch6"
5491   "@
5492    uxtb%?\\t%0, %1
5493    ldrb%?\\t%0, %1\\t%@ zero_extendqisi2"
5494   [(set_attr "type" "extend,load_byte")
5495    (set_attr "predicable" "yes")]
5498 (define_insn "*arm_zero_extendqisi2addsi"
5499   [(set (match_operand:SI 0 "s_register_operand" "=r")
5500         (plus:SI (zero_extend:SI (match_operand:QI 1 "s_register_operand" "r"))
5501                  (match_operand:SI 2 "s_register_operand" "r")))]
5502   "TARGET_INT_SIMD"
5503   "uxtab%?\\t%0, %2, %1"
5504   [(set_attr "predicable" "yes")
5505    (set_attr "predicable_short_it" "no")
5506    (set_attr "type" "alu_shift_reg")]
5509 (define_split
5510   [(set (match_operand:SI 0 "s_register_operand" "")
5511         (zero_extend:SI (subreg:QI (match_operand:SI 1 "" "") 0)))
5512    (clobber (match_operand:SI 2 "s_register_operand" ""))]
5513   "TARGET_32BIT && (!MEM_P (operands[1])) && ! BYTES_BIG_ENDIAN"
5514   [(set (match_dup 2) (match_dup 1))
5515    (set (match_dup 0) (and:SI (match_dup 2) (const_int 255)))]
5516   ""
5519 (define_split
5520   [(set (match_operand:SI 0 "s_register_operand" "")
5521         (zero_extend:SI (subreg:QI (match_operand:SI 1 "" "") 3)))
5522    (clobber (match_operand:SI 2 "s_register_operand" ""))]
5523   "TARGET_32BIT && (!MEM_P (operands[1])) && BYTES_BIG_ENDIAN"
5524   [(set (match_dup 2) (match_dup 1))
5525    (set (match_dup 0) (and:SI (match_dup 2) (const_int 255)))]
5526   ""
5530 (define_split
5531   [(set (match_operand:SI 0 "s_register_operand" "")
5532         (IOR_XOR:SI (and:SI (ashift:SI
5533                              (match_operand:SI 1 "s_register_operand" "")
5534                              (match_operand:SI 2 "const_int_operand" ""))
5535                             (match_operand:SI 3 "const_int_operand" ""))
5536                     (zero_extend:SI
5537                      (match_operator 5 "subreg_lowpart_operator"
5538                       [(match_operand:SI 4 "s_register_operand" "")]))))]
5539   "TARGET_32BIT
5540    && (UINTVAL (operands[3])
5541        == (GET_MODE_MASK (GET_MODE (operands[5]))
5542            & (GET_MODE_MASK (GET_MODE (operands[5]))
5543               << (INTVAL (operands[2])))))"
5544   [(set (match_dup 0) (IOR_XOR:SI (ashift:SI (match_dup 1) (match_dup 2))
5545                                   (match_dup 4)))
5546    (set (match_dup 0) (zero_extend:SI (match_dup 5)))]
5547   "operands[5] = gen_lowpart (GET_MODE (operands[5]), operands[0]);"
5550 (define_insn "*compareqi_eq0"
5551   [(set (reg:CC_Z CC_REGNUM)
5552         (compare:CC_Z (match_operand:QI 0 "s_register_operand" "r")
5553                          (const_int 0)))]
5554   "TARGET_32BIT"
5555   "tst%?\\t%0, #255"
5556   [(set_attr "conds" "set")
5557    (set_attr "predicable" "yes")
5558    (set_attr "predicable_short_it" "no")
5559    (set_attr "type" "logic_imm")]
5562 (define_expand "extendhisi2"
5563   [(set (match_operand:SI 0 "s_register_operand" "")
5564         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
5565   "TARGET_EITHER"
5567   if (TARGET_THUMB1)
5568     {
5569       emit_insn (gen_thumb1_extendhisi2 (operands[0], operands[1]));
5570       DONE;
5571     }
5572   if (MEM_P (operands[1]) && TARGET_ARM && !arm_arch4)
5573     {
5574       emit_insn (gen_extendhisi2_mem (operands[0], operands[1]));
5575       DONE;
5576     }
5578   if (!arm_arch6 && !MEM_P (operands[1]))
5579     {
5580       rtx t = gen_lowpart (SImode, operands[1]);
5581       rtx tmp = gen_reg_rtx (SImode);
5582       emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (16)));
5583       emit_insn (gen_ashrsi3 (operands[0], tmp, GEN_INT (16)));
5584       DONE;
5585     }
5588 (define_split
5589   [(parallel
5590     [(set (match_operand:SI 0 "register_operand" "")
5591           (sign_extend:SI (match_operand:HI 1 "register_operand" "")))
5592      (clobber (match_scratch:SI 2 ""))])]
5593   "!arm_arch6"
5594   [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
5595    (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
5597   operands[2] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
5600 ;; This pattern will only be used when ldsh is not available
5601 (define_expand "extendhisi2_mem"
5602   [(set (match_dup 2) (zero_extend:SI (match_operand:HI 1 "" "")))
5603    (set (match_dup 3)
5604         (zero_extend:SI (match_dup 7)))
5605    (set (match_dup 6) (ashift:SI (match_dup 4) (const_int 24)))
5606    (set (match_operand:SI 0 "" "")
5607         (ior:SI (ashiftrt:SI (match_dup 6) (const_int 16)) (match_dup 5)))]
5608   "TARGET_ARM"
5609   "
5610   {
5611     rtx mem1, mem2;
5612     rtx addr = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
5614     mem1 = change_address (operands[1], QImode, addr);
5615     mem2 = change_address (operands[1], QImode,
5616                            plus_constant (Pmode, addr, 1));
5617     operands[0] = gen_lowpart (SImode, operands[0]);
5618     operands[1] = mem1;
5619     operands[2] = gen_reg_rtx (SImode);
5620     operands[3] = gen_reg_rtx (SImode);
5621     operands[6] = gen_reg_rtx (SImode);
5622     operands[7] = mem2;
5624     if (BYTES_BIG_ENDIAN)
5625       {
5626         operands[4] = operands[2];
5627         operands[5] = operands[3];
5628       }
5629     else
5630       {
5631         operands[4] = operands[3];
5632         operands[5] = operands[2];
5633       }
5634   }"
5637 (define_split
5638   [(set (match_operand:SI 0 "register_operand" "")
5639         (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
5640   "!arm_arch6"
5641   [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
5642    (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
5644   operands[2] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
5647 (define_insn "*arm_extendhisi2"
5648   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5649         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,Uh")))]
5650   "TARGET_ARM && arm_arch4 && !arm_arch6"
5651   "@
5652    #
5653    ldrsh%?\\t%0, %1"
5654   [(set_attr "length" "8,4")
5655    (set_attr "type" "alu_shift_reg,load_byte")
5656    (set_attr "predicable" "yes")]
5659 ;; ??? Check Thumb-2 pool range
5660 (define_insn "*arm_extendhisi2_v6"
5661   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5662         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,Uh")))]
5663   "TARGET_32BIT && arm_arch6"
5664   "@
5665    sxth%?\\t%0, %1
5666    ldrsh%?\\t%0, %1"
5667   [(set_attr "type" "extend,load_byte")
5668    (set_attr "predicable" "yes")
5669    (set_attr "predicable_short_it" "no")]
5672 (define_insn "*arm_extendhisi2addsi"
5673   [(set (match_operand:SI 0 "s_register_operand" "=r")
5674         (plus:SI (sign_extend:SI (match_operand:HI 1 "s_register_operand" "r"))
5675                  (match_operand:SI 2 "s_register_operand" "r")))]
5676   "TARGET_INT_SIMD"
5677   "sxtah%?\\t%0, %2, %1"
5678   [(set_attr "type" "alu_shift_reg")]
5681 (define_expand "extendqihi2"
5682   [(set (match_dup 2)
5683         (ashift:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "")
5684                    (const_int 24)))
5685    (set (match_operand:HI 0 "s_register_operand" "")
5686         (ashiftrt:SI (match_dup 2)
5687                      (const_int 24)))]
5688   "TARGET_ARM"
5689   "
5690   {
5691     if (arm_arch4 && MEM_P (operands[1]))
5692       {
5693         emit_insn (gen_rtx_SET (operands[0],
5694                                 gen_rtx_SIGN_EXTEND (HImode, operands[1])));
5695         DONE;
5696       }
5697     if (!s_register_operand (operands[1], QImode))
5698       operands[1] = copy_to_mode_reg (QImode, operands[1]);
5699     operands[0] = gen_lowpart (SImode, operands[0]);
5700     operands[1] = gen_lowpart (SImode, operands[1]);
5701     operands[2] = gen_reg_rtx (SImode);
5702   }"
5705 (define_insn "*arm_extendqihi_insn"
5706   [(set (match_operand:HI 0 "s_register_operand" "=r")
5707         (sign_extend:HI (match_operand:QI 1 "arm_extendqisi_mem_op" "Uq")))]
5708   "TARGET_ARM && arm_arch4"
5709   "ldrsb%?\\t%0, %1"
5710   [(set_attr "type" "load_byte")
5711    (set_attr "predicable" "yes")]
5714 (define_expand "extendqisi2"
5715   [(set (match_operand:SI 0 "s_register_operand" "")
5716         (sign_extend:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "")))]
5717   "TARGET_EITHER"
5719   if (!arm_arch4 && MEM_P (operands[1]))
5720     operands[1] = copy_to_mode_reg (QImode, operands[1]);
5722   if (!arm_arch6 && !MEM_P (operands[1]))
5723     {
5724       rtx t = gen_lowpart (SImode, operands[1]);
5725       rtx tmp = gen_reg_rtx (SImode);
5726       emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (24)));
5727       emit_insn (gen_ashrsi3 (operands[0], tmp, GEN_INT (24)));
5728       DONE;
5729     }
5732 (define_split
5733   [(set (match_operand:SI 0 "register_operand" "")
5734         (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
5735   "!arm_arch6"
5736   [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 24)))
5737    (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 24)))]
5739   operands[2] = simplify_gen_subreg (SImode, operands[1], QImode, 0);
5742 (define_insn "*arm_extendqisi"
5743   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5744         (sign_extend:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "r,Uq")))]
5745   "TARGET_ARM && arm_arch4 && !arm_arch6"
5746   "@
5747    #
5748    ldrsb%?\\t%0, %1"
5749   [(set_attr "length" "8,4")
5750    (set_attr "type" "alu_shift_reg,load_byte")
5751    (set_attr "predicable" "yes")]
5754 (define_insn "*arm_extendqisi_v6"
5755   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5756         (sign_extend:SI
5757          (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "r,Uq")))]
5758   "TARGET_ARM && arm_arch6"
5759   "@
5760    sxtb%?\\t%0, %1
5761    ldrsb%?\\t%0, %1"
5762   [(set_attr "type" "extend,load_byte")
5763    (set_attr "predicable" "yes")]
5766 (define_insn "*arm_extendqisi2addsi"
5767   [(set (match_operand:SI 0 "s_register_operand" "=r")
5768         (plus:SI (sign_extend:SI (match_operand:QI 1 "s_register_operand" "r"))
5769                  (match_operand:SI 2 "s_register_operand" "r")))]
5770   "TARGET_INT_SIMD"
5771   "sxtab%?\\t%0, %2, %1"
5772   [(set_attr "type" "alu_shift_reg")
5773    (set_attr "predicable" "yes")
5774    (set_attr "predicable_short_it" "no")]
5777 (define_expand "extendsfdf2"
5778   [(set (match_operand:DF                  0 "s_register_operand" "")
5779         (float_extend:DF (match_operand:SF 1 "s_register_operand"  "")))]
5780   "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
5781   ""
5784 ;; HFmode -> DFmode conversions where we don't have an instruction for it
5785 ;; must go through SFmode.
5787 ;; This is always safe for an extend.
5789 (define_expand "extendhfdf2"
5790   [(set (match_operand:DF                  0 "s_register_operand" "")
5791         (float_extend:DF (match_operand:HF 1 "s_register_operand" "")))]
5792   "TARGET_EITHER"
5794   /* We don't have a direct instruction for this, so go via SFmode.  */
5795   if (!(TARGET_32BIT && TARGET_FP16_TO_DOUBLE))
5796     {
5797       rtx op1;
5798       op1 = convert_to_mode (SFmode, operands[1], 0);
5799       op1 = convert_to_mode (DFmode, op1, 0);
5800       emit_insn (gen_movdf (operands[0], op1));
5801       DONE;
5802     }
5803   /* Otherwise, we're done producing RTL and will pick up the correct
5804      pattern to do this with one rounding-step in a single instruction.  */
5808 ;; Move insns (including loads and stores)
5810 ;; XXX Just some ideas about movti.
5811 ;; I don't think these are a good idea on the arm, there just aren't enough
5812 ;; registers
5813 ;;(define_expand "loadti"
5814 ;;  [(set (match_operand:TI 0 "s_register_operand" "")
5815 ;;      (mem:TI (match_operand:SI 1 "address_operand" "")))]
5816 ;;  "" "")
5818 ;;(define_expand "storeti"
5819 ;;  [(set (mem:TI (match_operand:TI 0 "address_operand" ""))
5820 ;;      (match_operand:TI 1 "s_register_operand" ""))]
5821 ;;  "" "")
5823 ;;(define_expand "movti"
5824 ;;  [(set (match_operand:TI 0 "general_operand" "")
5825 ;;      (match_operand:TI 1 "general_operand" ""))]
5826 ;;  ""
5827 ;;  "
5829 ;;  rtx insn;
5831 ;;  if (MEM_P (operands[0]) && MEM_P (operands[1]))
5832 ;;    operands[1] = copy_to_reg (operands[1]);
5833 ;;  if (MEM_P (operands[0]))
5834 ;;    insn = gen_storeti (XEXP (operands[0], 0), operands[1]);
5835 ;;  else if (MEM_P (operands[1]))
5836 ;;    insn = gen_loadti (operands[0], XEXP (operands[1], 0));
5837 ;;  else
5838 ;;    FAIL;
5840 ;;  emit_insn (insn);
5841 ;;  DONE;
5842 ;;}")
5844 ;; Recognize garbage generated above.
5846 ;;(define_insn ""
5847 ;;  [(set (match_operand:TI 0 "general_operand" "=r,r,r,<,>,m")
5848 ;;      (match_operand:TI 1 "general_operand" "<,>,m,r,r,r"))]
5849 ;;  ""
5850 ;;  "*
5851 ;;  {
5852 ;;    register mem = (which_alternative < 3);
5853 ;;    register const char *template;
5855 ;;    operands[mem] = XEXP (operands[mem], 0);
5856 ;;    switch (which_alternative)
5857 ;;      {
5858 ;;      case 0: template = \"ldmdb\\t%1!, %M0\"; break;
5859 ;;      case 1: template = \"ldmia\\t%1!, %M0\"; break;
5860 ;;      case 2: template = \"ldmia\\t%1, %M0\"; break;
5861 ;;      case 3: template = \"stmdb\\t%0!, %M1\"; break;
5862 ;;      case 4: template = \"stmia\\t%0!, %M1\"; break;
5863 ;;      case 5: template = \"stmia\\t%0, %M1\"; break;
5864 ;;      }
5865 ;;    output_asm_insn (template, operands);
5866 ;;    return \"\";
5867 ;;  }")
5869 (define_expand "movdi"
5870   [(set (match_operand:DI 0 "general_operand" "")
5871         (match_operand:DI 1 "general_operand" ""))]
5872   "TARGET_EITHER"
5873   "
5874   if (can_create_pseudo_p ())
5875     {
5876       if (!REG_P (operands[0]))
5877         operands[1] = force_reg (DImode, operands[1]);
5878     }
5879   if (REG_P (operands[0]) && REGNO (operands[0]) <= LAST_ARM_REGNUM
5880       && !targetm.hard_regno_mode_ok (REGNO (operands[0]), DImode))
5881     {
5882       /* Avoid LDRD's into an odd-numbered register pair in ARM state
5883          when expanding function calls.  */
5884       gcc_assert (can_create_pseudo_p ());
5885       if (MEM_P (operands[1]) && MEM_VOLATILE_P (operands[1]))
5886         {
5887           /* Perform load into legal reg pair first, then move.  */
5888           rtx reg = gen_reg_rtx (DImode);
5889           emit_insn (gen_movdi (reg, operands[1]));
5890           operands[1] = reg;
5891         }
5892       emit_move_insn (gen_lowpart (SImode, operands[0]),
5893                       gen_lowpart (SImode, operands[1]));
5894       emit_move_insn (gen_highpart (SImode, operands[0]),
5895                       gen_highpart (SImode, operands[1]));
5896       DONE;
5897     }
5898   else if (REG_P (operands[1]) && REGNO (operands[1]) <= LAST_ARM_REGNUM
5899            && !targetm.hard_regno_mode_ok (REGNO (operands[1]), DImode))
5900     {
5901       /* Avoid STRD's from an odd-numbered register pair in ARM state
5902          when expanding function prologue.  */
5903       gcc_assert (can_create_pseudo_p ());
5904       rtx split_dest = (MEM_P (operands[0]) && MEM_VOLATILE_P (operands[0]))
5905                        ? gen_reg_rtx (DImode)
5906                        : operands[0];
5907       emit_move_insn (gen_lowpart (SImode, split_dest),
5908                       gen_lowpart (SImode, operands[1]));
5909       emit_move_insn (gen_highpart (SImode, split_dest),
5910                       gen_highpart (SImode, operands[1]));
5911       if (split_dest != operands[0])
5912         emit_insn (gen_movdi (operands[0], split_dest));
5913       DONE;
5914     }
5915   "
5918 (define_insn "*arm_movdi"
5919   [(set (match_operand:DI 0 "nonimmediate_di_operand" "=r, r, r, q, m")
5920         (match_operand:DI 1 "di_operand"              "rDa,Db,Dc,mi,q"))]
5921   "TARGET_32BIT
5922    && !(TARGET_HARD_FLOAT)
5923    && !TARGET_IWMMXT
5924    && (   register_operand (operands[0], DImode)
5925        || register_operand (operands[1], DImode))"
5926   "*
5927   switch (which_alternative)
5928     {
5929     case 0:
5930     case 1:
5931     case 2:
5932       return \"#\";
5933     default:
5934       return output_move_double (operands, true, NULL);
5935     }
5936   "
5937   [(set_attr "length" "8,12,16,8,8")
5938    (set_attr "type" "multiple,multiple,multiple,load2,store2")
5939    (set_attr "arm_pool_range" "*,*,*,1020,*")
5940    (set_attr "arm_neg_pool_range" "*,*,*,1004,*")
5941    (set_attr "thumb2_pool_range" "*,*,*,4094,*")
5942    (set_attr "thumb2_neg_pool_range" "*,*,*,0,*")]
5945 (define_split
5946   [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
5947         (match_operand:ANY64 1 "immediate_operand" ""))]
5948   "TARGET_32BIT
5949    && reload_completed
5950    && (arm_disable_literal_pool
5951        || (arm_const_double_inline_cost (operands[1])
5952            <= arm_max_const_double_inline_cost ()))"
5953   [(const_int 0)]
5954   "
5955   arm_split_constant (SET, SImode, curr_insn,
5956                       INTVAL (gen_lowpart (SImode, operands[1])),
5957                       gen_lowpart (SImode, operands[0]), NULL_RTX, 0);
5958   arm_split_constant (SET, SImode, curr_insn,
5959                       INTVAL (gen_highpart_mode (SImode,
5960                                                  GET_MODE (operands[0]),
5961                                                  operands[1])),
5962                       gen_highpart (SImode, operands[0]), NULL_RTX, 0);
5963   DONE;
5964   "
5967 ; If optimizing for size, or if we have load delay slots, then 
5968 ; we want to split the constant into two separate operations. 
5969 ; In both cases this may split a trivial part into a single data op
5970 ; leaving a single complex constant to load.  We can also get longer
5971 ; offsets in a LDR which means we get better chances of sharing the pool
5972 ; entries.  Finally, we can normally do a better job of scheduling
5973 ; LDR instructions than we can with LDM.
5974 ; This pattern will only match if the one above did not.
5975 (define_split
5976   [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
5977         (match_operand:ANY64 1 "const_double_operand" ""))]
5978   "TARGET_ARM && reload_completed
5979    && arm_const_double_by_parts (operands[1])"
5980   [(set (match_dup 0) (match_dup 1))
5981    (set (match_dup 2) (match_dup 3))]
5982   "
5983   operands[2] = gen_highpart (SImode, operands[0]);
5984   operands[3] = gen_highpart_mode (SImode, GET_MODE (operands[0]),
5985                                    operands[1]);
5986   operands[0] = gen_lowpart (SImode, operands[0]);
5987   operands[1] = gen_lowpart (SImode, operands[1]);
5988   "
5991 (define_split
5992   [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
5993         (match_operand:ANY64 1 "arm_general_register_operand" ""))]
5994   "TARGET_EITHER && reload_completed"
5995   [(set (match_dup 0) (match_dup 1))
5996    (set (match_dup 2) (match_dup 3))]
5997   "
5998   operands[2] = gen_highpart (SImode, operands[0]);
5999   operands[3] = gen_highpart (SImode, operands[1]);
6000   operands[0] = gen_lowpart (SImode, operands[0]);
6001   operands[1] = gen_lowpart (SImode, operands[1]);
6003   /* Handle a partial overlap.  */
6004   if (rtx_equal_p (operands[0], operands[3]))
6005     {
6006       rtx tmp0 = operands[0];
6007       rtx tmp1 = operands[1];
6009       operands[0] = operands[2];
6010       operands[1] = operands[3];
6011       operands[2] = tmp0;
6012       operands[3] = tmp1;
6013     }
6014   "
6017 ;; We can't actually do base+index doubleword loads if the index and
6018 ;; destination overlap.  Split here so that we at least have chance to
6019 ;; schedule.
6020 (define_split
6021   [(set (match_operand:DI 0 "s_register_operand" "")
6022         (mem:DI (plus:SI (match_operand:SI 1 "s_register_operand" "")
6023                          (match_operand:SI 2 "s_register_operand" ""))))]
6024   "TARGET_LDRD
6025   && reg_overlap_mentioned_p (operands[0], operands[1])
6026   && reg_overlap_mentioned_p (operands[0], operands[2])"
6027   [(set (match_dup 4)
6028         (plus:SI (match_dup 1)
6029                  (match_dup 2)))
6030    (set (match_dup 0)
6031         (mem:DI (match_dup 4)))]
6032   "
6033   operands[4] = gen_rtx_REG (SImode, REGNO(operands[0]));
6034   "
6037 (define_expand "movsi"
6038   [(set (match_operand:SI 0 "general_operand" "")
6039         (match_operand:SI 1 "general_operand" ""))]
6040   "TARGET_EITHER"
6041   "
6042   {
6043   rtx base, offset, tmp;
6045   if (TARGET_32BIT || TARGET_HAVE_MOVT)
6046     {
6047       /* Everything except mem = const or mem = mem can be done easily.  */
6048       if (MEM_P (operands[0]))
6049         operands[1] = force_reg (SImode, operands[1]);
6050       if (arm_general_register_operand (operands[0], SImode)
6051           && CONST_INT_P (operands[1])
6052           && !(const_ok_for_arm (INTVAL (operands[1]))
6053                || const_ok_for_arm (~INTVAL (operands[1]))))
6054         {
6055            if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[1]), SET))
6056              {
6057                 emit_insn (gen_rtx_SET (operands[0], operands[1]));
6058                 DONE;
6059              }
6060           else
6061              {
6062                 arm_split_constant (SET, SImode, NULL_RTX,
6063                                     INTVAL (operands[1]), operands[0], NULL_RTX,
6064                                     optimize && can_create_pseudo_p ());
6065                 DONE;
6066              }
6067         }
6068     }
6069   else /* Target doesn't have MOVT...  */
6070     {
6071       if (can_create_pseudo_p ())
6072         {
6073           if (!REG_P (operands[0]))
6074             operands[1] = force_reg (SImode, operands[1]);
6075         }
6076     }
6078   if (ARM_OFFSETS_MUST_BE_WITHIN_SECTIONS_P)
6079     {
6080       split_const (operands[1], &base, &offset);
6081       if (GET_CODE (base) == SYMBOL_REF
6082           && !offset_within_block_p (base, INTVAL (offset)))
6083         {
6084           tmp = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];
6085           emit_move_insn (tmp, base);
6086           emit_insn (gen_addsi3 (operands[0], tmp, offset));
6087           DONE;
6088         }
6089     }
6091   /* Recognize the case where operand[1] is a reference to thread-local
6092      data and load its address to a register.  */
6093   if (arm_tls_referenced_p (operands[1]))
6094     {
6095       rtx tmp = operands[1];
6096       rtx addend = NULL;
6098       if (GET_CODE (tmp) == CONST && GET_CODE (XEXP (tmp, 0)) == PLUS)
6099         {
6100           addend = XEXP (XEXP (tmp, 0), 1);
6101           tmp = XEXP (XEXP (tmp, 0), 0);
6102         }
6104       gcc_assert (GET_CODE (tmp) == SYMBOL_REF);
6105       gcc_assert (SYMBOL_REF_TLS_MODEL (tmp) != 0);
6107       tmp = legitimize_tls_address (tmp,
6108                                     !can_create_pseudo_p () ? operands[0] : 0);
6109       if (addend)
6110         {
6111           tmp = gen_rtx_PLUS (SImode, tmp, addend);
6112           tmp = force_operand (tmp, operands[0]);
6113         }
6114       operands[1] = tmp;
6115     }
6116   else if (flag_pic
6117            && (CONSTANT_P (operands[1])
6118                || symbol_mentioned_p (operands[1])
6119                || label_mentioned_p (operands[1])))
6120       operands[1] = legitimize_pic_address (operands[1], SImode,
6121                                             (!can_create_pseudo_p ()
6122                                              ? operands[0]
6123                                              : 0));
6124   }
6125   "
6128 ;; The ARM LO_SUM and HIGH are backwards - HIGH sets the low bits, and
6129 ;; LO_SUM adds in the high bits.  Fortunately these are opaque operations
6130 ;; so this does not matter.
6131 (define_insn "*arm_movt"
6132   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r")
6133         (lo_sum:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6134                    (match_operand:SI 2 "general_operand"      "i,i")))]
6135   "TARGET_HAVE_MOVT && arm_valid_symbolic_address_p (operands[2])"
6136   "@
6137    movt%?\t%0, #:upper16:%c2
6138    movt\t%0, #:upper16:%c2"
6139   [(set_attr "arch"  "32,v8mb")
6140    (set_attr "predicable" "yes")
6141    (set_attr "predicable_short_it" "no")
6142    (set_attr "length" "4")
6143    (set_attr "type" "alu_sreg")]
6146 (define_insn "*arm_movsi_insn"
6147   [(set (match_operand:SI 0 "nonimmediate_operand" "=rk,r,r,r,rk,m")
6148         (match_operand:SI 1 "general_operand"      "rk, I,K,j,mi,rk"))]
6149   "TARGET_ARM && !TARGET_IWMMXT && !TARGET_HARD_FLOAT
6150    && (   register_operand (operands[0], SImode)
6151        || register_operand (operands[1], SImode))"
6152   "@
6153    mov%?\\t%0, %1
6154    mov%?\\t%0, %1
6155    mvn%?\\t%0, #%B1
6156    movw%?\\t%0, %1
6157    ldr%?\\t%0, %1
6158    str%?\\t%1, %0"
6159   [(set_attr "type" "mov_reg,mov_imm,mvn_imm,mov_imm,load1,store1")
6160    (set_attr "predicable" "yes")
6161    (set_attr "arch" "*,*,*,v6t2,*,*")
6162    (set_attr "pool_range" "*,*,*,*,4096,*")
6163    (set_attr "neg_pool_range" "*,*,*,*,4084,*")]
6166 (define_split
6167   [(set (match_operand:SI 0 "arm_general_register_operand" "")
6168         (match_operand:SI 1 "const_int_operand" ""))]
6169   "(TARGET_32BIT || TARGET_HAVE_MOVT)
6170   && (!(const_ok_for_arm (INTVAL (operands[1]))
6171         || const_ok_for_arm (~INTVAL (operands[1]))))"
6172   [(clobber (const_int 0))]
6173   "
6174   arm_split_constant (SET, SImode, NULL_RTX, 
6175                       INTVAL (operands[1]), operands[0], NULL_RTX, 0);
6176   DONE;
6177   "
6180 ;; A normal way to do (symbol + offset) requires three instructions at least
6181 ;; (depends on how big the offset is) as below:
6182 ;; movw r0, #:lower16:g
6183 ;; movw r0, #:upper16:g
6184 ;; adds r0, #4
6186 ;; A better way would be:
6187 ;; movw r0, #:lower16:g+4
6188 ;; movw r0, #:upper16:g+4
6190 ;; The limitation of this way is that the length of offset should be a 16-bit
6191 ;; signed value, because current assembler only supports REL type relocation for
6192 ;; such case.  If the more powerful RELA type is supported in future, we should
6193 ;; update this pattern to go with better way.
6194 (define_split
6195   [(set (match_operand:SI 0 "arm_general_register_operand" "")
6196         (const:SI (plus:SI (match_operand:SI 1 "general_operand" "")
6197                            (match_operand:SI 2 "const_int_operand" ""))))]
6198   "TARGET_THUMB
6199    && TARGET_HAVE_MOVT
6200    && arm_disable_literal_pool
6201    && reload_completed
6202    && GET_CODE (operands[1]) == SYMBOL_REF"
6203   [(clobber (const_int 0))]
6204   "
6205     int offset = INTVAL (operands[2]);
6207     if (offset < -0x8000 || offset > 0x7fff)
6208       {
6209         arm_emit_movpair (operands[0], operands[1]);
6210         emit_insn (gen_rtx_SET (operands[0],
6211                                 gen_rtx_PLUS (SImode, operands[0], operands[2])));
6212       }
6213     else
6214       {
6215         rtx op = gen_rtx_CONST (SImode,
6216                                 gen_rtx_PLUS (SImode, operands[1], operands[2]));
6217         arm_emit_movpair (operands[0], op);
6218       }
6219   "
6222 ;; Split symbol_refs at the later stage (after cprop), instead of generating
6223 ;; movt/movw pair directly at expand.  Otherwise corresponding high_sum
6224 ;; and lo_sum would be merged back into memory load at cprop.  However,
6225 ;; if the default is to prefer movt/movw rather than a load from the constant
6226 ;; pool, the performance is better.
6227 (define_split
6228   [(set (match_operand:SI 0 "arm_general_register_operand" "")
6229        (match_operand:SI 1 "general_operand" ""))]
6230   "TARGET_USE_MOVT && GET_CODE (operands[1]) == SYMBOL_REF
6231    && !flag_pic && !target_word_relocations
6232    && !arm_tls_referenced_p (operands[1])"
6233   [(clobber (const_int 0))]
6235   arm_emit_movpair (operands[0], operands[1]);
6236   DONE;
6239 ;; When generating pic, we need to load the symbol offset into a register.
6240 ;; So that the optimizer does not confuse this with a normal symbol load
6241 ;; we use an unspec.  The offset will be loaded from a constant pool entry,
6242 ;; since that is the only type of relocation we can use.
6244 ;; Wrap calculation of the whole PIC address in a single pattern for the
6245 ;; benefit of optimizers, particularly, PRE and HOIST.  Calculation of
6246 ;; a PIC address involves two loads from memory, so we want to CSE it
6247 ;; as often as possible.
6248 ;; This pattern will be split into one of the pic_load_addr_* patterns
6249 ;; and a move after GCSE optimizations.
6251 ;; Note: Update arm.c: legitimize_pic_address() when changing this pattern.
6252 (define_expand "calculate_pic_address"
6253   [(set (match_operand:SI 0 "register_operand" "")
6254         (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "")
6255                          (unspec:SI [(match_operand:SI 2 "" "")]
6256                                     UNSPEC_PIC_SYM))))]
6257   "flag_pic"
6260 ;; Split calculate_pic_address into pic_load_addr_* and a move.
6261 (define_split
6262   [(set (match_operand:SI 0 "register_operand" "")
6263         (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "")
6264                          (unspec:SI [(match_operand:SI 2 "" "")]
6265                                     UNSPEC_PIC_SYM))))]
6266   "flag_pic"
6267   [(set (match_dup 3) (unspec:SI [(match_dup 2)] UNSPEC_PIC_SYM))
6268    (set (match_dup 0) (mem:SI (plus:SI (match_dup 1) (match_dup 3))))]
6269   "operands[3] = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];"
6272 ;; operand1 is the memory address to go into 
6273 ;; pic_load_addr_32bit.
6274 ;; operand2 is the PIC label to be emitted 
6275 ;; from pic_add_dot_plus_eight.
6276 ;; We do this to allow hoisting of the entire insn.
6277 (define_insn_and_split "pic_load_addr_unified"
6278   [(set (match_operand:SI 0 "s_register_operand" "=r,r,l")
6279         (unspec:SI [(match_operand:SI 1 "" "mX,mX,mX") 
6280                     (match_operand:SI 2 "" "")] 
6281                     UNSPEC_PIC_UNIFIED))]
6282  "flag_pic"
6283  "#"
6284  "&& reload_completed"
6285  [(set (match_dup 0) (unspec:SI [(match_dup 1)] UNSPEC_PIC_SYM))
6286   (set (match_dup 0) (unspec:SI [(match_dup 0) (match_dup 3)
6287                                  (match_dup 2)] UNSPEC_PIC_BASE))]
6288  "operands[3] = TARGET_THUMB ? GEN_INT (4) : GEN_INT (8);"
6289  [(set_attr "type" "load1,load1,load1")
6290   (set_attr "pool_range" "4096,4094,1022")
6291   (set_attr "neg_pool_range" "4084,0,0")
6292   (set_attr "arch"  "a,t2,t1")    
6293   (set_attr "length" "8,6,4")]
6296 ;; The rather odd constraints on the following are to force reload to leave
6297 ;; the insn alone, and to force the minipool generation pass to then move
6298 ;; the GOT symbol to memory.
6300 (define_insn "pic_load_addr_32bit"
6301   [(set (match_operand:SI 0 "s_register_operand" "=r")
6302         (unspec:SI [(match_operand:SI 1 "" "mX")] UNSPEC_PIC_SYM))]
6303   "TARGET_32BIT && flag_pic"
6304   "ldr%?\\t%0, %1"
6305   [(set_attr "type" "load1")
6306    (set (attr "pool_range")
6307         (if_then_else (eq_attr "is_thumb" "no")
6308                       (const_int 4096)
6309                       (const_int 4094)))
6310    (set (attr "neg_pool_range")
6311         (if_then_else (eq_attr "is_thumb" "no")
6312                       (const_int 4084)
6313                       (const_int 0)))]
6316 (define_insn "pic_load_addr_thumb1"
6317   [(set (match_operand:SI 0 "s_register_operand" "=l")
6318         (unspec:SI [(match_operand:SI 1 "" "mX")] UNSPEC_PIC_SYM))]
6319   "TARGET_THUMB1 && flag_pic"
6320   "ldr\\t%0, %1"
6321   [(set_attr "type" "load1")
6322    (set (attr "pool_range") (const_int 1018))]
6325 (define_insn "pic_add_dot_plus_four"
6326   [(set (match_operand:SI 0 "register_operand" "=r")
6327         (unspec:SI [(match_operand:SI 1 "register_operand" "0")
6328                     (const_int 4)
6329                     (match_operand 2 "" "")]
6330                    UNSPEC_PIC_BASE))]
6331   "TARGET_THUMB"
6332   "*
6333   (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
6334                                      INTVAL (operands[2]));
6335   return \"add\\t%0, %|pc\";
6336   "
6337   [(set_attr "length" "2")
6338    (set_attr "type" "alu_sreg")]
6341 (define_insn "pic_add_dot_plus_eight"
6342   [(set (match_operand:SI 0 "register_operand" "=r")
6343         (unspec:SI [(match_operand:SI 1 "register_operand" "r")
6344                     (const_int 8)
6345                     (match_operand 2 "" "")]
6346                    UNSPEC_PIC_BASE))]
6347   "TARGET_ARM"
6348   "*
6349     (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
6350                                        INTVAL (operands[2]));
6351     return \"add%?\\t%0, %|pc, %1\";
6352   "
6353   [(set_attr "predicable" "yes")
6354    (set_attr "type" "alu_sreg")]
6357 (define_insn "tls_load_dot_plus_eight"
6358   [(set (match_operand:SI 0 "register_operand" "=r")
6359         (mem:SI (unspec:SI [(match_operand:SI 1 "register_operand" "r")
6360                             (const_int 8)
6361                             (match_operand 2 "" "")]
6362                            UNSPEC_PIC_BASE)))]
6363   "TARGET_ARM"
6364   "*
6365     (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
6366                                        INTVAL (operands[2]));
6367     return \"ldr%?\\t%0, [%|pc, %1]\t\t@ tls_load_dot_plus_eight\";
6368   "
6369   [(set_attr "predicable" "yes")
6370    (set_attr "type" "load1")]
6373 ;; PIC references to local variables can generate pic_add_dot_plus_eight
6374 ;; followed by a load.  These sequences can be crunched down to
6375 ;; tls_load_dot_plus_eight by a peephole.
6377 (define_peephole2
6378   [(set (match_operand:SI 0 "register_operand" "")
6379         (unspec:SI [(match_operand:SI 3 "register_operand" "")
6380                     (const_int 8)
6381                     (match_operand 1 "" "")]
6382                    UNSPEC_PIC_BASE))
6383    (set (match_operand:SI 2 "arm_general_register_operand" "")
6384         (mem:SI (match_dup 0)))]
6385   "TARGET_ARM && peep2_reg_dead_p (2, operands[0])"
6386   [(set (match_dup 2)
6387         (mem:SI (unspec:SI [(match_dup 3)
6388                             (const_int 8)
6389                             (match_dup 1)]
6390                            UNSPEC_PIC_BASE)))]
6391   ""
6394 (define_insn "pic_offset_arm"
6395   [(set (match_operand:SI 0 "register_operand" "=r")
6396         (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
6397                          (unspec:SI [(match_operand:SI 2 "" "X")]
6398                                     UNSPEC_PIC_OFFSET))))]
6399   "TARGET_VXWORKS_RTP && TARGET_ARM && flag_pic"
6400   "ldr%?\\t%0, [%1,%2]"
6401   [(set_attr "type" "load1")]
6404 (define_expand "builtin_setjmp_receiver"
6405   [(label_ref (match_operand 0 "" ""))]
6406   "flag_pic"
6407   "
6409   /* r3 is clobbered by set/longjmp, so we can use it as a scratch
6410      register.  */
6411   if (arm_pic_register != INVALID_REGNUM)
6412     arm_load_pic_register (1UL << 3);
6413   DONE;
6416 ;; If copying one reg to another we can set the condition codes according to
6417 ;; its value.  Such a move is common after a return from subroutine and the
6418 ;; result is being tested against zero.
6420 (define_insn "*movsi_compare0"
6421   [(set (reg:CC CC_REGNUM)
6422         (compare:CC (match_operand:SI 1 "s_register_operand" "0,r")
6423                     (const_int 0)))
6424    (set (match_operand:SI 0 "s_register_operand" "=r,r")
6425         (match_dup 1))]
6426   "TARGET_32BIT"
6427   "@
6428    cmp%?\\t%0, #0
6429    subs%?\\t%0, %1, #0"
6430   [(set_attr "conds" "set")
6431    (set_attr "type" "alus_imm,alus_imm")]
6434 ;; Subroutine to store a half word from a register into memory.
6435 ;; Operand 0 is the source register (HImode)
6436 ;; Operand 1 is the destination address in a register (SImode)
6438 ;; In both this routine and the next, we must be careful not to spill
6439 ;; a memory address of reg+large_const into a separate PLUS insn, since this
6440 ;; can generate unrecognizable rtl.
6442 (define_expand "storehi"
6443   [;; store the low byte
6444    (set (match_operand 1 "" "") (match_dup 3))
6445    ;; extract the high byte
6446    (set (match_dup 2)
6447         (ashiftrt:SI (match_operand 0 "" "") (const_int 8)))
6448    ;; store the high byte
6449    (set (match_dup 4) (match_dup 5))]
6450   "TARGET_ARM"
6451   "
6452   {
6453     rtx op1 = operands[1];
6454     rtx addr = XEXP (op1, 0);
6455     enum rtx_code code = GET_CODE (addr);
6457     if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1)))
6458         || code == MINUS)
6459       op1 = replace_equiv_address (operands[1], force_reg (SImode, addr));
6461     operands[4] = adjust_address (op1, QImode, 1);
6462     operands[1] = adjust_address (operands[1], QImode, 0);
6463     operands[3] = gen_lowpart (QImode, operands[0]);
6464     operands[0] = gen_lowpart (SImode, operands[0]);
6465     operands[2] = gen_reg_rtx (SImode);
6466     operands[5] = gen_lowpart (QImode, operands[2]);
6467   }"
6470 (define_expand "storehi_bigend"
6471   [(set (match_dup 4) (match_dup 3))
6472    (set (match_dup 2)
6473         (ashiftrt:SI (match_operand 0 "" "") (const_int 8)))
6474    (set (match_operand 1 "" "") (match_dup 5))]
6475   "TARGET_ARM"
6476   "
6477   {
6478     rtx op1 = operands[1];
6479     rtx addr = XEXP (op1, 0);
6480     enum rtx_code code = GET_CODE (addr);
6482     if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1)))
6483         || code == MINUS)
6484       op1 = replace_equiv_address (op1, force_reg (SImode, addr));
6486     operands[4] = adjust_address (op1, QImode, 1);
6487     operands[1] = adjust_address (operands[1], QImode, 0);
6488     operands[3] = gen_lowpart (QImode, operands[0]);
6489     operands[0] = gen_lowpart (SImode, operands[0]);
6490     operands[2] = gen_reg_rtx (SImode);
6491     operands[5] = gen_lowpart (QImode, operands[2]);
6492   }"
6495 ;; Subroutine to store a half word integer constant into memory.
6496 (define_expand "storeinthi"
6497   [(set (match_operand 0 "" "")
6498         (match_operand 1 "" ""))
6499    (set (match_dup 3) (match_dup 2))]
6500   "TARGET_ARM"
6501   "
6502   {
6503     HOST_WIDE_INT value = INTVAL (operands[1]);
6504     rtx addr = XEXP (operands[0], 0);
6505     rtx op0 = operands[0];
6506     enum rtx_code code = GET_CODE (addr);
6508     if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1)))
6509         || code == MINUS)
6510       op0 = replace_equiv_address (op0, force_reg (SImode, addr));
6512     operands[1] = gen_reg_rtx (SImode);
6513     if (BYTES_BIG_ENDIAN)
6514       {
6515         emit_insn (gen_movsi (operands[1], GEN_INT ((value >> 8) & 255)));
6516         if ((value & 255) == ((value >> 8) & 255))
6517           operands[2] = operands[1];
6518         else
6519           {
6520             operands[2] = gen_reg_rtx (SImode);
6521             emit_insn (gen_movsi (operands[2], GEN_INT (value & 255)));
6522           }
6523       }
6524     else
6525       {
6526         emit_insn (gen_movsi (operands[1], GEN_INT (value & 255)));
6527         if ((value & 255) == ((value >> 8) & 255))
6528           operands[2] = operands[1];
6529         else
6530           {
6531             operands[2] = gen_reg_rtx (SImode);
6532             emit_insn (gen_movsi (operands[2], GEN_INT ((value >> 8) & 255)));
6533           }
6534       }
6536     operands[3] = adjust_address (op0, QImode, 1);
6537     operands[0] = adjust_address (operands[0], QImode, 0);
6538     operands[2] = gen_lowpart (QImode, operands[2]);
6539     operands[1] = gen_lowpart (QImode, operands[1]);
6540   }"
6543 (define_expand "storehi_single_op"
6544   [(set (match_operand:HI 0 "memory_operand" "")
6545         (match_operand:HI 1 "general_operand" ""))]
6546   "TARGET_32BIT && arm_arch4"
6547   "
6548   if (!s_register_operand (operands[1], HImode))
6549     operands[1] = copy_to_mode_reg (HImode, operands[1]);
6550   "
6553 (define_expand "movhi"
6554   [(set (match_operand:HI 0 "general_operand" "")
6555         (match_operand:HI 1 "general_operand" ""))]
6556   "TARGET_EITHER"
6557   "
6558   if (TARGET_ARM)
6559     {
6560       if (can_create_pseudo_p ())
6561         {
6562           if (MEM_P (operands[0]))
6563             {
6564               if (arm_arch4)
6565                 {
6566                   emit_insn (gen_storehi_single_op (operands[0], operands[1]));
6567                   DONE;
6568                 }
6569               if (CONST_INT_P (operands[1]))
6570                 emit_insn (gen_storeinthi (operands[0], operands[1]));
6571               else
6572                 {
6573                   if (MEM_P (operands[1]))
6574                     operands[1] = force_reg (HImode, operands[1]);
6575                   if (BYTES_BIG_ENDIAN)
6576                     emit_insn (gen_storehi_bigend (operands[1], operands[0]));
6577                   else
6578                    emit_insn (gen_storehi (operands[1], operands[0]));
6579                 }
6580               DONE;
6581             }
6582           /* Sign extend a constant, and keep it in an SImode reg.  */
6583           else if (CONST_INT_P (operands[1]))
6584             {
6585               rtx reg = gen_reg_rtx (SImode);
6586               HOST_WIDE_INT val = INTVAL (operands[1]) & 0xffff;
6588               /* If the constant is already valid, leave it alone.  */
6589               if (!const_ok_for_arm (val))
6590                 {
6591                   /* If setting all the top bits will make the constant 
6592                      loadable in a single instruction, then set them.  
6593                      Otherwise, sign extend the number.  */
6595                   if (const_ok_for_arm (~(val | ~0xffff)))
6596                     val |= ~0xffff;
6597                   else if (val & 0x8000)
6598                     val |= ~0xffff;
6599                 }
6601               emit_insn (gen_movsi (reg, GEN_INT (val)));
6602               operands[1] = gen_lowpart (HImode, reg);
6603             }
6604           else if (arm_arch4 && optimize && can_create_pseudo_p ()
6605                    && MEM_P (operands[1]))
6606             {
6607               rtx reg = gen_reg_rtx (SImode);
6609               emit_insn (gen_zero_extendhisi2 (reg, operands[1]));
6610               operands[1] = gen_lowpart (HImode, reg);
6611             }
6612           else if (!arm_arch4)
6613             {
6614               if (MEM_P (operands[1]))
6615                 {
6616                   rtx base;
6617                   rtx offset = const0_rtx;
6618                   rtx reg = gen_reg_rtx (SImode);
6620                   if ((REG_P (base = XEXP (operands[1], 0))
6621                        || (GET_CODE (base) == PLUS
6622                            && (CONST_INT_P (offset = XEXP (base, 1)))
6623                            && ((INTVAL(offset) & 1) != 1)
6624                            && REG_P (base = XEXP (base, 0))))
6625                       && REGNO_POINTER_ALIGN (REGNO (base)) >= 32)
6626                     {
6627                       rtx new_rtx;
6629                       new_rtx = widen_memory_access (operands[1], SImode,
6630                                                      ((INTVAL (offset) & ~3)
6631                                                       - INTVAL (offset)));
6632                       emit_insn (gen_movsi (reg, new_rtx));
6633                       if (((INTVAL (offset) & 2) != 0)
6634                           ^ (BYTES_BIG_ENDIAN ? 1 : 0))
6635                         {
6636                           rtx reg2 = gen_reg_rtx (SImode);
6638                           emit_insn (gen_lshrsi3 (reg2, reg, GEN_INT (16)));
6639                           reg = reg2;
6640                         }
6641                     }
6642                   else
6643                     emit_insn (gen_movhi_bytes (reg, operands[1]));
6645                   operands[1] = gen_lowpart (HImode, reg);
6646                }
6647            }
6648         }
6649       /* Handle loading a large integer during reload.  */
6650       else if (CONST_INT_P (operands[1])
6651                && !const_ok_for_arm (INTVAL (operands[1]))
6652                && !const_ok_for_arm (~INTVAL (operands[1])))
6653         {
6654           /* Writing a constant to memory needs a scratch, which should
6655              be handled with SECONDARY_RELOADs.  */
6656           gcc_assert (REG_P (operands[0]));
6658           operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
6659           emit_insn (gen_movsi (operands[0], operands[1]));
6660           DONE;
6661        }
6662     }
6663   else if (TARGET_THUMB2)
6664     {
6665       /* Thumb-2 can do everything except mem=mem and mem=const easily.  */
6666       if (can_create_pseudo_p ())
6667         {
6668           if (!REG_P (operands[0]))
6669             operands[1] = force_reg (HImode, operands[1]);
6670           /* Zero extend a constant, and keep it in an SImode reg.  */
6671           else if (CONST_INT_P (operands[1]))
6672             {
6673               rtx reg = gen_reg_rtx (SImode);
6674               HOST_WIDE_INT val = INTVAL (operands[1]) & 0xffff;
6676               emit_insn (gen_movsi (reg, GEN_INT (val)));
6677               operands[1] = gen_lowpart (HImode, reg);
6678             }
6679         }
6680     }
6681   else /* TARGET_THUMB1 */
6682     {
6683       if (can_create_pseudo_p ())
6684         {
6685           if (CONST_INT_P (operands[1]))
6686             {
6687               rtx reg = gen_reg_rtx (SImode);
6689               emit_insn (gen_movsi (reg, operands[1]));
6690               operands[1] = gen_lowpart (HImode, reg);
6691             }
6693           /* ??? We shouldn't really get invalid addresses here, but this can
6694              happen if we are passed a SP (never OK for HImode/QImode) or 
6695              virtual register (also rejected as illegitimate for HImode/QImode)
6696              relative address.  */
6697           /* ??? This should perhaps be fixed elsewhere, for instance, in
6698              fixup_stack_1, by checking for other kinds of invalid addresses,
6699              e.g. a bare reference to a virtual register.  This may confuse the
6700              alpha though, which must handle this case differently.  */
6701           if (MEM_P (operands[0])
6702               && !memory_address_p (GET_MODE (operands[0]),
6703                                     XEXP (operands[0], 0)))
6704             operands[0]
6705               = replace_equiv_address (operands[0],
6706                                        copy_to_reg (XEXP (operands[0], 0)));
6707    
6708           if (MEM_P (operands[1])
6709               && !memory_address_p (GET_MODE (operands[1]),
6710                                     XEXP (operands[1], 0)))
6711             operands[1]
6712               = replace_equiv_address (operands[1],
6713                                        copy_to_reg (XEXP (operands[1], 0)));
6715           if (MEM_P (operands[1]) && optimize > 0)
6716             {
6717               rtx reg = gen_reg_rtx (SImode);
6719               emit_insn (gen_zero_extendhisi2 (reg, operands[1]));
6720               operands[1] = gen_lowpart (HImode, reg);
6721             }
6723           if (MEM_P (operands[0]))
6724             operands[1] = force_reg (HImode, operands[1]);
6725         }
6726       else if (CONST_INT_P (operands[1])
6727                 && !satisfies_constraint_I (operands[1]))
6728         {
6729           /* Handle loading a large integer during reload.  */
6731           /* Writing a constant to memory needs a scratch, which should
6732              be handled with SECONDARY_RELOADs.  */
6733           gcc_assert (REG_P (operands[0]));
6735           operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
6736           emit_insn (gen_movsi (operands[0], operands[1]));
6737           DONE;
6738         }
6739     }
6740   "
6743 (define_expand "movhi_bytes"
6744   [(set (match_dup 2) (zero_extend:SI (match_operand:HI 1 "" "")))
6745    (set (match_dup 3)
6746         (zero_extend:SI (match_dup 6)))
6747    (set (match_operand:SI 0 "" "")
6748          (ior:SI (ashift:SI (match_dup 4) (const_int 8)) (match_dup 5)))]
6749   "TARGET_ARM"
6750   "
6751   {
6752     rtx mem1, mem2;
6753     rtx addr = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
6755     mem1 = change_address (operands[1], QImode, addr);
6756     mem2 = change_address (operands[1], QImode,
6757                            plus_constant (Pmode, addr, 1));
6758     operands[0] = gen_lowpart (SImode, operands[0]);
6759     operands[1] = mem1;
6760     operands[2] = gen_reg_rtx (SImode);
6761     operands[3] = gen_reg_rtx (SImode);
6762     operands[6] = mem2;
6764     if (BYTES_BIG_ENDIAN)
6765       {
6766         operands[4] = operands[2];
6767         operands[5] = operands[3];
6768       }
6769     else
6770       {
6771         operands[4] = operands[3];
6772         operands[5] = operands[2];
6773       }
6774   }"
6777 (define_expand "movhi_bigend"
6778   [(set (match_dup 2)
6779         (rotate:SI (subreg:SI (match_operand:HI 1 "memory_operand" "") 0)
6780                    (const_int 16)))
6781    (set (match_dup 3)
6782         (ashiftrt:SI (match_dup 2) (const_int 16)))
6783    (set (match_operand:HI 0 "s_register_operand" "")
6784         (match_dup 4))]
6785   "TARGET_ARM"
6786   "
6787   operands[2] = gen_reg_rtx (SImode);
6788   operands[3] = gen_reg_rtx (SImode);
6789   operands[4] = gen_lowpart (HImode, operands[3]);
6790   "
6793 ;; Pattern to recognize insn generated default case above
6794 (define_insn "*movhi_insn_arch4"
6795   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m,r")
6796         (match_operand:HI 1 "general_operand"      "rIk,K,n,r,mi"))]
6797   "TARGET_ARM
6798    && arm_arch4 && !TARGET_HARD_FLOAT
6799    && (register_operand (operands[0], HImode)
6800        || register_operand (operands[1], HImode))"
6801   "@
6802    mov%?\\t%0, %1\\t%@ movhi
6803    mvn%?\\t%0, #%B1\\t%@ movhi
6804    movw%?\\t%0, %L1\\t%@ movhi
6805    strh%?\\t%1, %0\\t%@ movhi
6806    ldrh%?\\t%0, %1\\t%@ movhi"
6807   [(set_attr "predicable" "yes")
6808    (set_attr "pool_range" "*,*,*,*,256")
6809    (set_attr "neg_pool_range" "*,*,*,*,244")
6810    (set_attr "arch" "*,*,v6t2,*,*")
6811    (set_attr_alternative "type"
6812                          [(if_then_else (match_operand 1 "const_int_operand" "")
6813                                         (const_string "mov_imm" )
6814                                         (const_string "mov_reg"))
6815                           (const_string "mvn_imm")
6816                           (const_string "mov_imm")
6817                           (const_string "store1")
6818                           (const_string "load1")])]
6821 (define_insn "*movhi_bytes"
6822   [(set (match_operand:HI 0 "s_register_operand" "=r,r,r")
6823         (match_operand:HI 1 "arm_rhs_operand"  "I,rk,K"))]
6824   "TARGET_ARM && !TARGET_HARD_FLOAT"
6825   "@
6826    mov%?\\t%0, %1\\t%@ movhi
6827    mov%?\\t%0, %1\\t%@ movhi
6828    mvn%?\\t%0, #%B1\\t%@ movhi"
6829   [(set_attr "predicable" "yes")
6830    (set_attr "type" "mov_imm,mov_reg,mvn_imm")]
6833 ;; We use a DImode scratch because we may occasionally need an additional
6834 ;; temporary if the address isn't offsettable -- push_reload doesn't seem
6835 ;; to take any notice of the "o" constraints on reload_memory_operand operand.
6836 (define_expand "reload_outhi"
6837   [(parallel [(match_operand:HI 0 "arm_reload_memory_operand" "=o")
6838               (match_operand:HI 1 "s_register_operand"        "r")
6839               (match_operand:DI 2 "s_register_operand"        "=&l")])]
6840   "TARGET_EITHER"
6841   "if (TARGET_ARM)
6842      arm_reload_out_hi (operands);
6843    else
6844      thumb_reload_out_hi (operands);
6845   DONE;
6846   "
6849 (define_expand "reload_inhi"
6850   [(parallel [(match_operand:HI 0 "s_register_operand" "=r")
6851               (match_operand:HI 1 "arm_reload_memory_operand" "o")
6852               (match_operand:DI 2 "s_register_operand" "=&r")])]
6853   "TARGET_EITHER"
6854   "
6855   if (TARGET_ARM)
6856     arm_reload_in_hi (operands);
6857   else
6858     thumb_reload_out_hi (operands);
6859   DONE;
6862 (define_expand "movqi"
6863   [(set (match_operand:QI 0 "general_operand" "")
6864         (match_operand:QI 1 "general_operand" ""))]
6865   "TARGET_EITHER"
6866   "
6867   /* Everything except mem = const or mem = mem can be done easily */
6869   if (can_create_pseudo_p ())
6870     {
6871       if (CONST_INT_P (operands[1]))
6872         {
6873           rtx reg = gen_reg_rtx (SImode);
6875           /* For thumb we want an unsigned immediate, then we are more likely 
6876              to be able to use a movs insn.  */
6877           if (TARGET_THUMB)
6878             operands[1] = GEN_INT (INTVAL (operands[1]) & 255);
6880           emit_insn (gen_movsi (reg, operands[1]));
6881           operands[1] = gen_lowpart (QImode, reg);
6882         }
6884       if (TARGET_THUMB)
6885         {
6886           /* ??? We shouldn't really get invalid addresses here, but this can
6887              happen if we are passed a SP (never OK for HImode/QImode) or
6888              virtual register (also rejected as illegitimate for HImode/QImode)
6889              relative address.  */
6890           /* ??? This should perhaps be fixed elsewhere, for instance, in
6891              fixup_stack_1, by checking for other kinds of invalid addresses,
6892              e.g. a bare reference to a virtual register.  This may confuse the
6893              alpha though, which must handle this case differently.  */
6894           if (MEM_P (operands[0])
6895               && !memory_address_p (GET_MODE (operands[0]),
6896                                      XEXP (operands[0], 0)))
6897             operands[0]
6898               = replace_equiv_address (operands[0],
6899                                        copy_to_reg (XEXP (operands[0], 0)));
6900           if (MEM_P (operands[1])
6901               && !memory_address_p (GET_MODE (operands[1]),
6902                                     XEXP (operands[1], 0)))
6903              operands[1]
6904                = replace_equiv_address (operands[1],
6905                                         copy_to_reg (XEXP (operands[1], 0)));
6906         }
6908       if (MEM_P (operands[1]) && optimize > 0)
6909         {
6910           rtx reg = gen_reg_rtx (SImode);
6912           emit_insn (gen_zero_extendqisi2 (reg, operands[1]));
6913           operands[1] = gen_lowpart (QImode, reg);
6914         }
6916       if (MEM_P (operands[0]))
6917         operands[1] = force_reg (QImode, operands[1]);
6918     }
6919   else if (TARGET_THUMB
6920            && CONST_INT_P (operands[1])
6921            && !satisfies_constraint_I (operands[1]))
6922     {
6923       /* Handle loading a large integer during reload.  */
6925       /* Writing a constant to memory needs a scratch, which should
6926          be handled with SECONDARY_RELOADs.  */
6927       gcc_assert (REG_P (operands[0]));
6929       operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
6930       emit_insn (gen_movsi (operands[0], operands[1]));
6931       DONE;
6932     }
6933   "
6936 (define_insn "*arm_movqi_insn"
6937   [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,r,l,r,l,Uu,r,m")
6938         (match_operand:QI 1 "general_operand" "rk,rk,I,Py,K,Uu,l,Uh,r"))]
6939   "TARGET_32BIT
6940    && (   register_operand (operands[0], QImode)
6941        || register_operand (operands[1], QImode))"
6942   "@
6943    mov%?\\t%0, %1
6944    mov%?\\t%0, %1
6945    mov%?\\t%0, %1
6946    mov%?\\t%0, %1
6947    mvn%?\\t%0, #%B1
6948    ldrb%?\\t%0, %1
6949    strb%?\\t%1, %0
6950    ldrb%?\\t%0, %1
6951    strb%?\\t%1, %0"
6952   [(set_attr "type" "mov_reg,mov_reg,mov_imm,mov_imm,mvn_imm,load1,store1,load1,store1")
6953    (set_attr "predicable" "yes")
6954    (set_attr "predicable_short_it" "yes,yes,no,yes,no,no,no,no,no")
6955    (set_attr "arch" "t2,any,any,t2,any,t2,t2,any,any")
6956    (set_attr "length" "2,4,4,2,4,2,2,4,4")]
6959 ;; HFmode moves
6960 (define_expand "movhf"
6961   [(set (match_operand:HF 0 "general_operand" "")
6962         (match_operand:HF 1 "general_operand" ""))]
6963   "TARGET_EITHER"
6964   "
6965   if (TARGET_32BIT)
6966     {
6967       if (MEM_P (operands[0]))
6968         operands[1] = force_reg (HFmode, operands[1]);
6969     }
6970   else /* TARGET_THUMB1 */
6971     {
6972       if (can_create_pseudo_p ())
6973         {
6974            if (!REG_P (operands[0]))
6975              operands[1] = force_reg (HFmode, operands[1]);
6976         }
6977     }
6978   "
6981 (define_insn "*arm32_movhf"
6982   [(set (match_operand:HF 0 "nonimmediate_operand" "=r,m,r,r")
6983         (match_operand:HF 1 "general_operand"      " m,r,r,F"))]
6984   "TARGET_32BIT && !TARGET_HARD_FLOAT
6985    && (   s_register_operand (operands[0], HFmode)
6986        || s_register_operand (operands[1], HFmode))"
6987   "*
6988   switch (which_alternative)
6989     {
6990     case 0:     /* ARM register from memory */
6991       return \"ldrh%?\\t%0, %1\\t%@ __fp16\";
6992     case 1:     /* memory from ARM register */
6993       return \"strh%?\\t%1, %0\\t%@ __fp16\";
6994     case 2:     /* ARM register from ARM register */
6995       return \"mov%?\\t%0, %1\\t%@ __fp16\";
6996     case 3:     /* ARM register from constant */
6997       {
6998         long bits;
6999         rtx ops[4];
7001         bits = real_to_target (NULL, CONST_DOUBLE_REAL_VALUE (operands[1]),
7002                                HFmode);
7003         ops[0] = operands[0];
7004         ops[1] = GEN_INT (bits);
7005         ops[2] = GEN_INT (bits & 0xff00);
7006         ops[3] = GEN_INT (bits & 0x00ff);
7008         if (arm_arch_thumb2)
7009           output_asm_insn (\"movw%?\\t%0, %1\", ops);
7010         else
7011           output_asm_insn (\"mov%?\\t%0, %2\;orr%?\\t%0, %0, %3\", ops);
7012         return \"\";
7013        }
7014     default:
7015       gcc_unreachable ();
7016     }
7017   "
7018   [(set_attr "conds" "unconditional")
7019    (set_attr "type" "load1,store1,mov_reg,multiple")
7020    (set_attr "length" "4,4,4,8")
7021    (set_attr "predicable" "yes")
7022    (set_attr "predicable_short_it" "no")]
7025 (define_expand "movsf"
7026   [(set (match_operand:SF 0 "general_operand" "")
7027         (match_operand:SF 1 "general_operand" ""))]
7028   "TARGET_EITHER"
7029   "
7030   if (TARGET_32BIT)
7031     {
7032       if (MEM_P (operands[0]))
7033         operands[1] = force_reg (SFmode, operands[1]);
7034     }
7035   else /* TARGET_THUMB1 */
7036     {
7037       if (can_create_pseudo_p ())
7038         {
7039            if (!REG_P (operands[0]))
7040              operands[1] = force_reg (SFmode, operands[1]);
7041         }
7042     }
7043   "
7046 ;; Transform a floating-point move of a constant into a core register into
7047 ;; an SImode operation.
7048 (define_split
7049   [(set (match_operand:SF 0 "arm_general_register_operand" "")
7050         (match_operand:SF 1 "immediate_operand" ""))]
7051   "TARGET_EITHER
7052    && reload_completed
7053    && CONST_DOUBLE_P (operands[1])"
7054   [(set (match_dup 2) (match_dup 3))]
7055   "
7056   operands[2] = gen_lowpart (SImode, operands[0]);
7057   operands[3] = gen_lowpart (SImode, operands[1]);
7058   if (operands[2] == 0 || operands[3] == 0)
7059     FAIL;
7060   "
7063 (define_insn "*arm_movsf_soft_insn"
7064   [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,m")
7065         (match_operand:SF 1 "general_operand"  "r,mE,r"))]
7066   "TARGET_32BIT
7067    && TARGET_SOFT_FLOAT
7068    && (!MEM_P (operands[0])
7069        || register_operand (operands[1], SFmode))"
7070   "@
7071    mov%?\\t%0, %1
7072    ldr%?\\t%0, %1\\t%@ float
7073    str%?\\t%1, %0\\t%@ float"
7074   [(set_attr "predicable" "yes")
7075    (set_attr "predicable_short_it" "no")
7076    (set_attr "type" "mov_reg,load1,store1")
7077    (set_attr "arm_pool_range" "*,4096,*")
7078    (set_attr "thumb2_pool_range" "*,4094,*")
7079    (set_attr "arm_neg_pool_range" "*,4084,*")
7080    (set_attr "thumb2_neg_pool_range" "*,0,*")]
7083 (define_expand "movdf"
7084   [(set (match_operand:DF 0 "general_operand" "")
7085         (match_operand:DF 1 "general_operand" ""))]
7086   "TARGET_EITHER"
7087   "
7088   if (TARGET_32BIT)
7089     {
7090       if (MEM_P (operands[0]))
7091         operands[1] = force_reg (DFmode, operands[1]);
7092     }
7093   else /* TARGET_THUMB */
7094     {
7095       if (can_create_pseudo_p ())
7096         {
7097           if (!REG_P (operands[0]))
7098             operands[1] = force_reg (DFmode, operands[1]);
7099         }
7100     }
7101   "
7104 ;; Reloading a df mode value stored in integer regs to memory can require a
7105 ;; scratch reg.
7106 (define_expand "reload_outdf"
7107   [(match_operand:DF 0 "arm_reload_memory_operand" "=o")
7108    (match_operand:DF 1 "s_register_operand" "r")
7109    (match_operand:SI 2 "s_register_operand" "=&r")]
7110   "TARGET_THUMB2"
7111   "
7112   {
7113     enum rtx_code code = GET_CODE (XEXP (operands[0], 0));
7115     if (code == REG)
7116       operands[2] = XEXP (operands[0], 0);
7117     else if (code == POST_INC || code == PRE_DEC)
7118       {
7119         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7120         operands[1] = gen_rtx_SUBREG (DImode, operands[1], 0);
7121         emit_insn (gen_movdi (operands[0], operands[1]));
7122         DONE;
7123       }
7124     else if (code == PRE_INC)
7125       {
7126         rtx reg = XEXP (XEXP (operands[0], 0), 0);
7128         emit_insn (gen_addsi3 (reg, reg, GEN_INT (8)));
7129         operands[2] = reg;
7130       }
7131     else if (code == POST_DEC)
7132       operands[2] = XEXP (XEXP (operands[0], 0), 0);
7133     else
7134       emit_insn (gen_addsi3 (operands[2], XEXP (XEXP (operands[0], 0), 0),
7135                              XEXP (XEXP (operands[0], 0), 1)));
7137     emit_insn (gen_rtx_SET (replace_equiv_address (operands[0], operands[2]),
7138                             operands[1]));
7140     if (code == POST_DEC)
7141       emit_insn (gen_addsi3 (operands[2], operands[2], GEN_INT (-8)));
7143     DONE;
7144   }"
7147 (define_insn "*movdf_soft_insn"
7148   [(set (match_operand:DF 0 "nonimmediate_soft_df_operand" "=r,r,r,q,m")
7149         (match_operand:DF 1 "soft_df_operand" "rDa,Db,Dc,mF,q"))]
7150   "TARGET_32BIT && TARGET_SOFT_FLOAT
7151    && (   register_operand (operands[0], DFmode)
7152        || register_operand (operands[1], DFmode))"
7153   "*
7154   switch (which_alternative)
7155     {
7156     case 0:
7157     case 1:
7158     case 2:
7159       return \"#\";
7160     default:
7161       return output_move_double (operands, true, NULL);
7162     }
7163   "
7164   [(set_attr "length" "8,12,16,8,8")
7165    (set_attr "type" "multiple,multiple,multiple,load2,store2")
7166    (set_attr "arm_pool_range" "*,*,*,1020,*")
7167    (set_attr "thumb2_pool_range" "*,*,*,1018,*")
7168    (set_attr "arm_neg_pool_range" "*,*,*,1004,*")
7169    (set_attr "thumb2_neg_pool_range" "*,*,*,0,*")]
7173 ;; load- and store-multiple insns
7174 ;; The arm can load/store any set of registers, provided that they are in
7175 ;; ascending order, but these expanders assume a contiguous set.
7177 (define_expand "load_multiple"
7178   [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
7179                           (match_operand:SI 1 "" ""))
7180                      (use (match_operand:SI 2 "" ""))])]
7181   "TARGET_32BIT"
7183   HOST_WIDE_INT offset = 0;
7185   /* Support only fixed point registers.  */
7186   if (!CONST_INT_P (operands[2])
7187       || INTVAL (operands[2]) > MAX_LDM_STM_OPS
7188       || INTVAL (operands[2]) < 2
7189       || !MEM_P (operands[1])
7190       || !REG_P (operands[0])
7191       || REGNO (operands[0]) > (LAST_ARM_REGNUM - 1)
7192       || REGNO (operands[0]) + INTVAL (operands[2]) > LAST_ARM_REGNUM)
7193     FAIL;
7195   operands[3]
7196     = arm_gen_load_multiple (arm_regs_in_sequence + REGNO (operands[0]),
7197                              INTVAL (operands[2]),
7198                              force_reg (SImode, XEXP (operands[1], 0)),
7199                              FALSE, operands[1], &offset);
7202 (define_expand "store_multiple"
7203   [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
7204                           (match_operand:SI 1 "" ""))
7205                      (use (match_operand:SI 2 "" ""))])]
7206   "TARGET_32BIT"
7208   HOST_WIDE_INT offset = 0;
7210   /* Support only fixed point registers.  */
7211   if (!CONST_INT_P (operands[2])
7212       || INTVAL (operands[2]) > MAX_LDM_STM_OPS
7213       || INTVAL (operands[2]) < 2
7214       || !REG_P (operands[1])
7215       || !MEM_P (operands[0])
7216       || REGNO (operands[1]) > (LAST_ARM_REGNUM - 1)
7217       || REGNO (operands[1]) + INTVAL (operands[2]) > LAST_ARM_REGNUM)
7218     FAIL;
7220   operands[3]
7221     = arm_gen_store_multiple (arm_regs_in_sequence + REGNO (operands[1]),
7222                               INTVAL (operands[2]),
7223                               force_reg (SImode, XEXP (operands[0], 0)),
7224                               FALSE, operands[0], &offset);
7228 (define_expand "setmemsi"
7229   [(match_operand:BLK 0 "general_operand" "")
7230    (match_operand:SI 1 "const_int_operand" "")
7231    (match_operand:SI 2 "const_int_operand" "")
7232    (match_operand:SI 3 "const_int_operand" "")]
7233   "TARGET_32BIT"
7235   if (arm_gen_setmem (operands))
7236     DONE;
7238   FAIL;
7242 ;; Move a block of memory if it is word aligned and MORE than 2 words long.
7243 ;; We could let this apply for blocks of less than this, but it clobbers so
7244 ;; many registers that there is then probably a better way.
7246 (define_expand "movmemqi"
7247   [(match_operand:BLK 0 "general_operand" "")
7248    (match_operand:BLK 1 "general_operand" "")
7249    (match_operand:SI 2 "const_int_operand" "")
7250    (match_operand:SI 3 "const_int_operand" "")]
7251   ""
7252   "
7253   if (TARGET_32BIT)
7254     {
7255       if (TARGET_LDRD && current_tune->prefer_ldrd_strd
7256           && !optimize_function_for_size_p (cfun))
7257         {
7258           if (gen_movmem_ldrd_strd (operands))
7259             DONE;
7260           FAIL;
7261         }
7263       if (arm_gen_movmemqi (operands))
7264         DONE;
7265       FAIL;
7266     }
7267   else /* TARGET_THUMB1 */
7268     {
7269       if (   INTVAL (operands[3]) != 4
7270           || INTVAL (operands[2]) > 48)
7271         FAIL;
7273       thumb_expand_movmemqi (operands);
7274       DONE;
7275     }
7276   "
7280 ;; Compare & branch insns
7281 ;; The range calculations are based as follows:
7282 ;; For forward branches, the address calculation returns the address of
7283 ;; the next instruction.  This is 2 beyond the branch instruction.
7284 ;; For backward branches, the address calculation returns the address of
7285 ;; the first instruction in this pattern (cmp).  This is 2 before the branch
7286 ;; instruction for the shortest sequence, and 4 before the branch instruction
7287 ;; if we have to jump around an unconditional branch.
7288 ;; To the basic branch range the PC offset must be added (this is +4).
7289 ;; So for forward branches we have 
7290 ;;   (pos_range - pos_base_offs + pc_offs) = (pos_range - 2 + 4).
7291 ;; And for backward branches we have 
7292 ;;   (neg_range - neg_base_offs + pc_offs) = (neg_range - (-2 or -4) + 4).
7294 ;; For a 'b'       pos_range = 2046, neg_range = -2048 giving (-2040->2048).
7295 ;; For a 'b<cond>' pos_range = 254,  neg_range = -256  giving (-250 ->256).
7297 (define_expand "cbranchsi4"
7298   [(set (pc) (if_then_else
7299               (match_operator 0 "expandable_comparison_operator"
7300                [(match_operand:SI 1 "s_register_operand" "")
7301                 (match_operand:SI 2 "nonmemory_operand" "")])
7302               (label_ref (match_operand 3 "" ""))
7303               (pc)))]
7304   "TARGET_EITHER"
7305   "
7306   if (!TARGET_THUMB1)
7307     {
7308       if (!arm_validize_comparison (&operands[0], &operands[1], &operands[2]))
7309         FAIL;
7310       emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
7311                                       operands[3]));
7312       DONE;
7313     }
7314   if (thumb1_cmpneg_operand (operands[2], SImode))
7315     {
7316       emit_jump_insn (gen_cbranchsi4_scratch (NULL, operands[1], operands[2],
7317                                               operands[3], operands[0]));
7318       DONE;
7319     }
7320   if (!thumb1_cmp_operand (operands[2], SImode))
7321     operands[2] = force_reg (SImode, operands[2]);
7322   ")
7324 (define_expand "cbranchsf4"
7325   [(set (pc) (if_then_else
7326               (match_operator 0 "expandable_comparison_operator"
7327                [(match_operand:SF 1 "s_register_operand" "")
7328                 (match_operand:SF 2 "vfp_compare_operand" "")])
7329               (label_ref (match_operand 3 "" ""))
7330               (pc)))]
7331   "TARGET_32BIT && TARGET_HARD_FLOAT"
7332   "emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
7333                                    operands[3])); DONE;"
7336 (define_expand "cbranchdf4"
7337   [(set (pc) (if_then_else
7338               (match_operator 0 "expandable_comparison_operator"
7339                [(match_operand:DF 1 "s_register_operand" "")
7340                 (match_operand:DF 2 "vfp_compare_operand" "")])
7341               (label_ref (match_operand 3 "" ""))
7342               (pc)))]
7343   "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
7344   "emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
7345                                    operands[3])); DONE;"
7348 (define_expand "cbranchdi4"
7349   [(set (pc) (if_then_else
7350               (match_operator 0 "expandable_comparison_operator"
7351                [(match_operand:DI 1 "s_register_operand" "")
7352                 (match_operand:DI 2 "cmpdi_operand" "")])
7353               (label_ref (match_operand 3 "" ""))
7354               (pc)))]
7355   "TARGET_32BIT"
7356   "{
7357      if (!arm_validize_comparison (&operands[0], &operands[1], &operands[2]))
7358        FAIL;
7359      emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
7360                                        operands[3]));
7361      DONE;
7362    }"
7365 ;; Comparison and test insns
7367 (define_insn "*arm_cmpsi_insn"
7368   [(set (reg:CC CC_REGNUM)
7369         (compare:CC (match_operand:SI 0 "s_register_operand" "l,r,r,r,r")
7370                     (match_operand:SI 1 "arm_add_operand"    "Py,r,r,I,L")))]
7371   "TARGET_32BIT"
7372   "@
7373    cmp%?\\t%0, %1
7374    cmp%?\\t%0, %1
7375    cmp%?\\t%0, %1
7376    cmp%?\\t%0, %1
7377    cmn%?\\t%0, #%n1"
7378   [(set_attr "conds" "set")
7379    (set_attr "arch" "t2,t2,any,any,any")
7380    (set_attr "length" "2,2,4,4,4")
7381    (set_attr "predicable" "yes")
7382    (set_attr "predicable_short_it" "yes,yes,yes,no,no")
7383    (set_attr "type" "alus_imm,alus_sreg,alus_sreg,alus_imm,alus_imm")]
7386 (define_insn "*cmpsi_shiftsi"
7387   [(set (reg:CC CC_REGNUM)
7388         (compare:CC (match_operand:SI   0 "s_register_operand" "r,r,r")
7389                     (match_operator:SI  3 "shift_operator"
7390                      [(match_operand:SI 1 "s_register_operand" "r,r,r")
7391                       (match_operand:SI 2 "shift_amount_operand" "M,r,M")])))]
7392   "TARGET_32BIT"
7393   "cmp\\t%0, %1%S3"
7394   [(set_attr "conds" "set")
7395    (set_attr "shift" "1")
7396    (set_attr "arch" "32,a,a")
7397    (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
7399 (define_insn "*cmpsi_shiftsi_swp"
7400   [(set (reg:CC_SWP CC_REGNUM)
7401         (compare:CC_SWP (match_operator:SI 3 "shift_operator"
7402                          [(match_operand:SI 1 "s_register_operand" "r,r,r")
7403                           (match_operand:SI 2 "shift_amount_operand" "M,r,M")])
7404                         (match_operand:SI 0 "s_register_operand" "r,r,r")))]
7405   "TARGET_32BIT"
7406   "cmp%?\\t%0, %1%S3"
7407   [(set_attr "conds" "set")
7408    (set_attr "shift" "1")
7409    (set_attr "arch" "32,a,a")
7410    (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
7412 (define_insn "*arm_cmpsi_negshiftsi_si"
7413   [(set (reg:CC_Z CC_REGNUM)
7414         (compare:CC_Z
7415          (neg:SI (match_operator:SI 1 "shift_operator"
7416                     [(match_operand:SI 2 "s_register_operand" "r")
7417                      (match_operand:SI 3 "reg_or_int_operand" "rM")]))
7418          (match_operand:SI 0 "s_register_operand" "r")))]
7419   "TARGET_ARM"
7420   "cmn%?\\t%0, %2%S1"
7421   [(set_attr "conds" "set")
7422    (set (attr "type") (if_then_else (match_operand 3 "const_int_operand" "")
7423                                     (const_string "alus_shift_imm")
7424                                     (const_string "alus_shift_reg")))
7425    (set_attr "predicable" "yes")]
7428 ;; DImode comparisons.  The generic code generates branches that
7429 ;; if-conversion can not reduce to a conditional compare, so we do
7430 ;; that directly.
7432 (define_insn_and_split "*arm_cmpdi_insn"
7433   [(set (reg:CC_NCV CC_REGNUM)
7434         (compare:CC_NCV (match_operand:DI 0 "s_register_operand" "r")
7435                         (match_operand:DI 1 "arm_di_operand"       "rDi")))
7436    (clobber (match_scratch:SI 2 "=r"))]
7437   "TARGET_32BIT"
7438   "#"   ; "cmp\\t%Q0, %Q1\;sbcs\\t%2, %R0, %R1"
7439   "&& reload_completed"
7440   [(set (reg:CC CC_REGNUM)
7441         (compare:CC (match_dup 0) (match_dup 1)))
7442    (parallel [(set (reg:CC CC_REGNUM)
7443                    (compare:CC (match_dup 3) (match_dup 4)))
7444               (set (match_dup 2)
7445                    (minus:SI (match_dup 5)
7446                             (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))])]
7447   {
7448     operands[3] = gen_highpart (SImode, operands[0]);
7449     operands[0] = gen_lowpart (SImode, operands[0]);
7450     if (CONST_INT_P (operands[1]))
7451       {
7452         operands[4] = GEN_INT (~INTVAL (gen_highpart_mode (SImode,
7453                                                            DImode,
7454                                                            operands[1])));
7455         operands[5] = gen_rtx_PLUS (SImode, operands[3], operands[4]);
7456       }
7457     else
7458       {
7459         operands[4] = gen_highpart (SImode, operands[1]);
7460         operands[5] = gen_rtx_MINUS (SImode, operands[3], operands[4]);
7461       }
7462     operands[1] = gen_lowpart (SImode, operands[1]);
7463     operands[2] = gen_lowpart (SImode, operands[2]);
7464   }
7465   [(set_attr "conds" "set")
7466    (set_attr "length" "8")
7467    (set_attr "type" "multiple")]
7470 (define_insn_and_split "*arm_cmpdi_unsigned"
7471   [(set (reg:CC_CZ CC_REGNUM)
7472         (compare:CC_CZ (match_operand:DI 0 "s_register_operand" "l,r,r,r")
7473                        (match_operand:DI 1 "arm_di_operand"     "Py,r,Di,rDi")))]
7475   "TARGET_32BIT"
7476   "#"   ; "cmp\\t%R0, %R1\;it eq\;cmpeq\\t%Q0, %Q1"
7477   "&& reload_completed"
7478   [(set (reg:CC CC_REGNUM)
7479         (compare:CC (match_dup 2) (match_dup 3)))
7480    (cond_exec (eq:SI (reg:CC CC_REGNUM) (const_int 0))
7481               (set (reg:CC CC_REGNUM)
7482                    (compare:CC (match_dup 0) (match_dup 1))))]
7483   {
7484     operands[2] = gen_highpart (SImode, operands[0]);
7485     operands[0] = gen_lowpart (SImode, operands[0]);
7486     if (CONST_INT_P (operands[1]))
7487       operands[3] = gen_highpart_mode (SImode, DImode, operands[1]);
7488     else
7489       operands[3] = gen_highpart (SImode, operands[1]);
7490     operands[1] = gen_lowpart (SImode, operands[1]);
7491   }
7492   [(set_attr "conds" "set")
7493    (set_attr "enabled_for_depr_it" "yes,yes,no,*")
7494    (set_attr "arch" "t2,t2,t2,a")
7495    (set_attr "length" "6,6,10,8")
7496    (set_attr "type" "multiple")]
7499 (define_insn "*arm_cmpdi_zero"
7500   [(set (reg:CC_Z CC_REGNUM)
7501         (compare:CC_Z (match_operand:DI 0 "s_register_operand" "r")
7502                       (const_int 0)))
7503    (clobber (match_scratch:SI 1 "=r"))]
7504   "TARGET_32BIT"
7505   "orrs%?\\t%1, %Q0, %R0"
7506   [(set_attr "conds" "set")
7507    (set_attr "type" "logics_reg")]
7510 ; This insn allows redundant compares to be removed by cse, nothing should
7511 ; ever appear in the output file since (set (reg x) (reg x)) is a no-op that
7512 ; is deleted later on. The match_dup will match the mode here, so that
7513 ; mode changes of the condition codes aren't lost by this even though we don't
7514 ; specify what they are.
7516 (define_insn "*deleted_compare"
7517   [(set (match_operand 0 "cc_register" "") (match_dup 0))]
7518   "TARGET_32BIT"
7519   "\\t%@ deleted compare"
7520   [(set_attr "conds" "set")
7521    (set_attr "length" "0")
7522    (set_attr "type" "no_insn")]
7526 ;; Conditional branch insns
7528 (define_expand "cbranch_cc"
7529   [(set (pc)
7530         (if_then_else (match_operator 0 "" [(match_operand 1 "" "")
7531                                             (match_operand 2 "" "")])
7532                       (label_ref (match_operand 3 "" ""))
7533                       (pc)))]
7534   "TARGET_32BIT"
7535   "operands[1] = arm_gen_compare_reg (GET_CODE (operands[0]),
7536                                       operands[1], operands[2], NULL_RTX);
7537    operands[2] = const0_rtx;"
7541 ;; Patterns to match conditional branch insns.
7544 (define_insn "arm_cond_branch"
7545   [(set (pc)
7546         (if_then_else (match_operator 1 "arm_comparison_operator"
7547                        [(match_operand 2 "cc_register" "") (const_int 0)])
7548                       (label_ref (match_operand 0 "" ""))
7549                       (pc)))]
7550   "TARGET_32BIT"
7551   "*
7552   if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
7553     {
7554       arm_ccfsm_state += 2;
7555       return \"\";
7556     }
7557   return \"b%d1\\t%l0\";
7558   "
7559   [(set_attr "conds" "use")
7560    (set_attr "type" "branch")
7561    (set (attr "length")
7562         (if_then_else
7563            (and (match_test "TARGET_THUMB2")
7564                 (and (ge (minus (match_dup 0) (pc)) (const_int -250))
7565                      (le (minus (match_dup 0) (pc)) (const_int 256))))
7566            (const_int 2)
7567            (const_int 4)))]
7570 (define_insn "*arm_cond_branch_reversed"
7571   [(set (pc)
7572         (if_then_else (match_operator 1 "arm_comparison_operator"
7573                        [(match_operand 2 "cc_register" "") (const_int 0)])
7574                       (pc)
7575                       (label_ref (match_operand 0 "" ""))))]
7576   "TARGET_32BIT"
7577   "*
7578   if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
7579     {
7580       arm_ccfsm_state += 2;
7581       return \"\";
7582     }
7583   return \"b%D1\\t%l0\";
7584   "
7585   [(set_attr "conds" "use")
7586    (set_attr "type" "branch")
7587    (set (attr "length")
7588         (if_then_else
7589            (and (match_test "TARGET_THUMB2")
7590                 (and (ge (minus (match_dup 0) (pc)) (const_int -250))
7591                      (le (minus (match_dup 0) (pc)) (const_int 256))))
7592            (const_int 2)
7593            (const_int 4)))]
7598 ; scc insns
7600 (define_expand "cstore_cc"
7601   [(set (match_operand:SI 0 "s_register_operand" "")
7602         (match_operator:SI 1 "" [(match_operand 2 "" "")
7603                                  (match_operand 3 "" "")]))]
7604   "TARGET_32BIT"
7605   "operands[2] = arm_gen_compare_reg (GET_CODE (operands[1]),
7606                                       operands[2], operands[3], NULL_RTX);
7607    operands[3] = const0_rtx;"
7610 (define_insn_and_split "*mov_scc"
7611   [(set (match_operand:SI 0 "s_register_operand" "=r")
7612         (match_operator:SI 1 "arm_comparison_operator_mode"
7613          [(match_operand 2 "cc_register" "") (const_int 0)]))]
7614   "TARGET_ARM"
7615   "#"   ; "mov%D1\\t%0, #0\;mov%d1\\t%0, #1"
7616   "TARGET_ARM"
7617   [(set (match_dup 0)
7618         (if_then_else:SI (match_dup 1)
7619                          (const_int 1)
7620                          (const_int 0)))]
7621   ""
7622   [(set_attr "conds" "use")
7623    (set_attr "length" "8")
7624    (set_attr "type" "multiple")]
7627 (define_insn_and_split "*mov_negscc"
7628   [(set (match_operand:SI 0 "s_register_operand" "=r")
7629         (neg:SI (match_operator:SI 1 "arm_comparison_operator_mode"
7630                  [(match_operand 2 "cc_register" "") (const_int 0)])))]
7631   "TARGET_ARM"
7632   "#"   ; "mov%D1\\t%0, #0\;mvn%d1\\t%0, #0"
7633   "TARGET_ARM"
7634   [(set (match_dup 0)
7635         (if_then_else:SI (match_dup 1)
7636                          (match_dup 3)
7637                          (const_int 0)))]
7638   {
7639     operands[3] = GEN_INT (~0);
7640   }
7641   [(set_attr "conds" "use")
7642    (set_attr "length" "8")
7643    (set_attr "type" "multiple")]
7646 (define_insn_and_split "*mov_notscc"
7647   [(set (match_operand:SI 0 "s_register_operand" "=r")
7648         (not:SI (match_operator:SI 1 "arm_comparison_operator"
7649                  [(match_operand 2 "cc_register" "") (const_int 0)])))]
7650   "TARGET_ARM"
7651   "#"   ; "mvn%D1\\t%0, #0\;mvn%d1\\t%0, #1"
7652   "TARGET_ARM"
7653   [(set (match_dup 0)
7654         (if_then_else:SI (match_dup 1)
7655                          (match_dup 3)
7656                          (match_dup 4)))]
7657   {
7658     operands[3] = GEN_INT (~1);
7659     operands[4] = GEN_INT (~0);
7660   }
7661   [(set_attr "conds" "use")
7662    (set_attr "length" "8")
7663    (set_attr "type" "multiple")]
7666 (define_expand "cstoresi4"
7667   [(set (match_operand:SI 0 "s_register_operand" "")
7668         (match_operator:SI 1 "expandable_comparison_operator"
7669          [(match_operand:SI 2 "s_register_operand" "")
7670           (match_operand:SI 3 "reg_or_int_operand" "")]))]
7671   "TARGET_32BIT || TARGET_THUMB1"
7672   "{
7673   rtx op3, scratch, scratch2;
7675   if (!TARGET_THUMB1)
7676     {
7677       if (!arm_add_operand (operands[3], SImode))
7678         operands[3] = force_reg (SImode, operands[3]);
7679       emit_insn (gen_cstore_cc (operands[0], operands[1],
7680                                 operands[2], operands[3]));
7681       DONE;
7682     }
7684   if (operands[3] == const0_rtx)
7685     {
7686       switch (GET_CODE (operands[1]))
7687         {
7688         case EQ:
7689           emit_insn (gen_cstoresi_eq0_thumb1 (operands[0], operands[2]));
7690           break;
7692         case NE:
7693           emit_insn (gen_cstoresi_ne0_thumb1 (operands[0], operands[2]));
7694           break;
7696         case LE:
7697           scratch = expand_binop (SImode, add_optab, operands[2], constm1_rtx,
7698                                   NULL_RTX, 0, OPTAB_WIDEN);
7699           scratch = expand_binop (SImode, ior_optab, operands[2], scratch,
7700                                   NULL_RTX, 0, OPTAB_WIDEN);
7701           expand_binop (SImode, lshr_optab, scratch, GEN_INT (31),
7702                         operands[0], 1, OPTAB_WIDEN);
7703           break;
7705         case GE:
7706           scratch = expand_unop (SImode, one_cmpl_optab, operands[2],
7707                                  NULL_RTX, 1);
7708           expand_binop (SImode, lshr_optab, scratch, GEN_INT (31),
7709                         NULL_RTX, 1, OPTAB_WIDEN);
7710           break;
7712         case GT:
7713           scratch = expand_binop (SImode, ashr_optab, operands[2],
7714                                   GEN_INT (31), NULL_RTX, 0, OPTAB_WIDEN);
7715           scratch = expand_binop (SImode, sub_optab, scratch, operands[2],
7716                                   NULL_RTX, 0, OPTAB_WIDEN);
7717           expand_binop (SImode, lshr_optab, scratch, GEN_INT (31), operands[0],
7718                         0, OPTAB_WIDEN);
7719           break;
7721         /* LT is handled by generic code.  No need for unsigned with 0.  */
7722         default:
7723           FAIL;
7724         }
7725       DONE;
7726     }
7728   switch (GET_CODE (operands[1]))
7729     {
7730     case EQ:
7731       scratch = expand_binop (SImode, sub_optab, operands[2], operands[3],
7732                               NULL_RTX, 0, OPTAB_WIDEN);
7733       emit_insn (gen_cstoresi_eq0_thumb1 (operands[0], scratch));
7734       break;
7736     case NE:
7737       scratch = expand_binop (SImode, sub_optab, operands[2], operands[3],
7738                               NULL_RTX, 0, OPTAB_WIDEN);
7739       emit_insn (gen_cstoresi_ne0_thumb1 (operands[0], scratch));
7740       break;
7742     case LE:
7743       op3 = force_reg (SImode, operands[3]);
7745       scratch = expand_binop (SImode, lshr_optab, operands[2], GEN_INT (31),
7746                               NULL_RTX, 1, OPTAB_WIDEN);
7747       scratch2 = expand_binop (SImode, ashr_optab, op3, GEN_INT (31),
7748                               NULL_RTX, 0, OPTAB_WIDEN);
7749       emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch2,
7750                                           op3, operands[2]));
7751       break;
7753     case GE:
7754       op3 = operands[3];
7755       if (!thumb1_cmp_operand (op3, SImode))
7756         op3 = force_reg (SImode, op3);
7757       scratch = expand_binop (SImode, ashr_optab, operands[2], GEN_INT (31),
7758                               NULL_RTX, 0, OPTAB_WIDEN);
7759       scratch2 = expand_binop (SImode, lshr_optab, op3, GEN_INT (31),
7760                                NULL_RTX, 1, OPTAB_WIDEN);
7761       emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch2,
7762                                           operands[2], op3));
7763       break;
7765     case LEU:
7766       op3 = force_reg (SImode, operands[3]);
7767       scratch = force_reg (SImode, const0_rtx);
7768       emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch,
7769                                           op3, operands[2]));
7770       break;
7772     case GEU:
7773       op3 = operands[3];
7774       if (!thumb1_cmp_operand (op3, SImode))
7775         op3 = force_reg (SImode, op3);
7776       scratch = force_reg (SImode, const0_rtx);
7777       emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch,
7778                                           operands[2], op3));
7779       break;
7781     case LTU:
7782       op3 = operands[3];
7783       if (!thumb1_cmp_operand (op3, SImode))
7784         op3 = force_reg (SImode, op3);
7785       scratch = gen_reg_rtx (SImode);
7786       emit_insn (gen_cstoresi_ltu_thumb1 (operands[0], operands[2], op3));
7787       break;
7789     case GTU:
7790       op3 = force_reg (SImode, operands[3]);
7791       scratch = gen_reg_rtx (SImode);
7792       emit_insn (gen_cstoresi_ltu_thumb1 (operands[0], op3, operands[2]));
7793       break;
7795     /* No good sequences for GT, LT.  */
7796     default:
7797       FAIL;
7798     }
7799   DONE;
7802 (define_expand "cstorehf4"
7803   [(set (match_operand:SI 0 "s_register_operand")
7804         (match_operator:SI 1 "expandable_comparison_operator"
7805          [(match_operand:HF 2 "s_register_operand")
7806           (match_operand:HF 3 "vfp_compare_operand")]))]
7807   "TARGET_VFP_FP16INST"
7808   {
7809     if (!arm_validize_comparison (&operands[1],
7810                                   &operands[2],
7811                                   &operands[3]))
7812        FAIL;
7814     emit_insn (gen_cstore_cc (operands[0], operands[1],
7815                               operands[2], operands[3]));
7816     DONE;
7817   }
7820 (define_expand "cstoresf4"
7821   [(set (match_operand:SI 0 "s_register_operand" "")
7822         (match_operator:SI 1 "expandable_comparison_operator"
7823          [(match_operand:SF 2 "s_register_operand" "")
7824           (match_operand:SF 3 "vfp_compare_operand" "")]))]
7825   "TARGET_32BIT && TARGET_HARD_FLOAT"
7826   "emit_insn (gen_cstore_cc (operands[0], operands[1],
7827                              operands[2], operands[3])); DONE;"
7830 (define_expand "cstoredf4"
7831   [(set (match_operand:SI 0 "s_register_operand" "")
7832         (match_operator:SI 1 "expandable_comparison_operator"
7833          [(match_operand:DF 2 "s_register_operand" "")
7834           (match_operand:DF 3 "vfp_compare_operand" "")]))]
7835   "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
7836   "emit_insn (gen_cstore_cc (operands[0], operands[1],
7837                              operands[2], operands[3])); DONE;"
7840 (define_expand "cstoredi4"
7841   [(set (match_operand:SI 0 "s_register_operand" "")
7842         (match_operator:SI 1 "expandable_comparison_operator"
7843          [(match_operand:DI 2 "s_register_operand" "")
7844           (match_operand:DI 3 "cmpdi_operand" "")]))]
7845   "TARGET_32BIT"
7846   "{
7847      if (!arm_validize_comparison (&operands[1],
7848                                    &operands[2],
7849                                    &operands[3]))
7850        FAIL;
7851      emit_insn (gen_cstore_cc (operands[0], operands[1], operands[2],
7852                                  operands[3]));
7853      DONE;
7854    }"
7858 ;; Conditional move insns
7860 (define_expand "movsicc"
7861   [(set (match_operand:SI 0 "s_register_operand" "")
7862         (if_then_else:SI (match_operand 1 "expandable_comparison_operator" "")
7863                          (match_operand:SI 2 "arm_not_operand" "")
7864                          (match_operand:SI 3 "arm_not_operand" "")))]
7865   "TARGET_32BIT"
7866   "
7867   {
7868     enum rtx_code code;
7869     rtx ccreg;
7871     if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0), 
7872                                   &XEXP (operands[1], 1)))
7873       FAIL;
7875     code = GET_CODE (operands[1]);
7876     ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
7877                                  XEXP (operands[1], 1), NULL_RTX);
7878     operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7879   }"
7882 (define_expand "movhfcc"
7883   [(set (match_operand:HF 0 "s_register_operand")
7884         (if_then_else:HF (match_operand 1 "arm_cond_move_operator")
7885                          (match_operand:HF 2 "s_register_operand")
7886                          (match_operand:HF 3 "s_register_operand")))]
7887   "TARGET_VFP_FP16INST"
7888   "
7889   {
7890     enum rtx_code code = GET_CODE (operands[1]);
7891     rtx ccreg;
7893     if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
7894                                   &XEXP (operands[1], 1)))
7895       FAIL;
7897     code = GET_CODE (operands[1]);
7898     ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
7899                                  XEXP (operands[1], 1), NULL_RTX);
7900     operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7901   }"
7904 (define_expand "movsfcc"
7905   [(set (match_operand:SF 0 "s_register_operand" "")
7906         (if_then_else:SF (match_operand 1 "arm_cond_move_operator" "")
7907                          (match_operand:SF 2 "s_register_operand" "")
7908                          (match_operand:SF 3 "s_register_operand" "")))]
7909   "TARGET_32BIT && TARGET_HARD_FLOAT"
7910   "
7911   {
7912     enum rtx_code code = GET_CODE (operands[1]);
7913     rtx ccreg;
7915     if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
7916                                   &XEXP (operands[1], 1)))
7917        FAIL;
7919     code = GET_CODE (operands[1]);
7920     ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
7921                                  XEXP (operands[1], 1), NULL_RTX);
7922     operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7923   }"
7926 (define_expand "movdfcc"
7927   [(set (match_operand:DF 0 "s_register_operand" "")
7928         (if_then_else:DF (match_operand 1 "arm_cond_move_operator" "")
7929                          (match_operand:DF 2 "s_register_operand" "")
7930                          (match_operand:DF 3 "s_register_operand" "")))]
7931   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
7932   "
7933   {
7934     enum rtx_code code = GET_CODE (operands[1]);
7935     rtx ccreg;
7937     if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0), 
7938                                   &XEXP (operands[1], 1)))
7939        FAIL;
7940     code = GET_CODE (operands[1]);
7941     ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
7942                                  XEXP (operands[1], 1), NULL_RTX);
7943     operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7944   }"
7947 (define_insn "*cmov<mode>"
7948     [(set (match_operand:SDF 0 "s_register_operand" "=<F_constraint>")
7949         (if_then_else:SDF (match_operator 1 "arm_vsel_comparison_operator"
7950                           [(match_operand 2 "cc_register" "") (const_int 0)])
7951                           (match_operand:SDF 3 "s_register_operand"
7952                                               "<F_constraint>")
7953                           (match_operand:SDF 4 "s_register_operand"
7954                                               "<F_constraint>")))]
7955   "TARGET_HARD_FLOAT && TARGET_VFP5 <vfp_double_cond>"
7956   "*
7957   {
7958     enum arm_cond_code code = maybe_get_arm_condition_code (operands[1]);
7959     switch (code)
7960       {
7961       case ARM_GE:
7962       case ARM_GT:
7963       case ARM_EQ:
7964       case ARM_VS:
7965         return \"vsel%d1.<V_if_elem>\\t%<V_reg>0, %<V_reg>3, %<V_reg>4\";
7966       case ARM_LT:
7967       case ARM_LE:
7968       case ARM_NE:
7969       case ARM_VC:
7970         return \"vsel%D1.<V_if_elem>\\t%<V_reg>0, %<V_reg>4, %<V_reg>3\";
7971       default:
7972         gcc_unreachable ();
7973       }
7974     return \"\";
7975   }"
7976   [(set_attr "conds" "use")
7977    (set_attr "type" "fcsel")]
7980 (define_insn "*cmovhf"
7981     [(set (match_operand:HF 0 "s_register_operand" "=t")
7982         (if_then_else:HF (match_operator 1 "arm_vsel_comparison_operator"
7983                          [(match_operand 2 "cc_register" "") (const_int 0)])
7984                           (match_operand:HF 3 "s_register_operand" "t")
7985                           (match_operand:HF 4 "s_register_operand" "t")))]
7986   "TARGET_VFP_FP16INST"
7987   "*
7988   {
7989     enum arm_cond_code code = maybe_get_arm_condition_code (operands[1]);
7990     switch (code)
7991       {
7992       case ARM_GE:
7993       case ARM_GT:
7994       case ARM_EQ:
7995       case ARM_VS:
7996         return \"vsel%d1.f16\\t%0, %3, %4\";
7997       case ARM_LT:
7998       case ARM_LE:
7999       case ARM_NE:
8000       case ARM_VC:
8001         return \"vsel%D1.f16\\t%0, %4, %3\";
8002       default:
8003         gcc_unreachable ();
8004       }
8005     return \"\";
8006   }"
8007   [(set_attr "conds" "use")
8008    (set_attr "type" "fcsel")]
8011 (define_insn_and_split "*movsicc_insn"
8012   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r,r,r,r,r")
8013         (if_then_else:SI
8014          (match_operator 3 "arm_comparison_operator"
8015           [(match_operand 4 "cc_register" "") (const_int 0)])
8016          (match_operand:SI 1 "arm_not_operand" "0,0,rI,K,rI,rI,K,K")
8017          (match_operand:SI 2 "arm_not_operand" "rI,K,0,0,rI,K,rI,K")))]
8018   "TARGET_ARM"
8019   "@
8020    mov%D3\\t%0, %2
8021    mvn%D3\\t%0, #%B2
8022    mov%d3\\t%0, %1
8023    mvn%d3\\t%0, #%B1
8024    #
8025    #
8026    #
8027    #"
8028    ; alt4: mov%d3\\t%0, %1\;mov%D3\\t%0, %2
8029    ; alt5: mov%d3\\t%0, %1\;mvn%D3\\t%0, #%B2
8030    ; alt6: mvn%d3\\t%0, #%B1\;mov%D3\\t%0, %2
8031    ; alt7: mvn%d3\\t%0, #%B1\;mvn%D3\\t%0, #%B2"
8032   "&& reload_completed"
8033   [(const_int 0)]
8034   {
8035     enum rtx_code rev_code;
8036     machine_mode mode;
8037     rtx rev_cond;
8039     emit_insn (gen_rtx_COND_EXEC (VOIDmode,
8040                                   operands[3],
8041                                   gen_rtx_SET (operands[0], operands[1])));
8043     rev_code = GET_CODE (operands[3]);
8044     mode = GET_MODE (operands[4]);
8045     if (mode == CCFPmode || mode == CCFPEmode)
8046       rev_code = reverse_condition_maybe_unordered (rev_code);
8047     else
8048       rev_code = reverse_condition (rev_code);
8050     rev_cond = gen_rtx_fmt_ee (rev_code,
8051                                VOIDmode,
8052                                operands[4],
8053                                const0_rtx);
8054     emit_insn (gen_rtx_COND_EXEC (VOIDmode,
8055                                   rev_cond,
8056                                   gen_rtx_SET (operands[0], operands[2])));
8057     DONE;
8058   }
8059   [(set_attr "length" "4,4,4,4,8,8,8,8")
8060    (set_attr "conds" "use")
8061    (set_attr_alternative "type"
8062                          [(if_then_else (match_operand 2 "const_int_operand" "")
8063                                         (const_string "mov_imm")
8064                                         (const_string "mov_reg"))
8065                           (const_string "mvn_imm")
8066                           (if_then_else (match_operand 1 "const_int_operand" "")
8067                                         (const_string "mov_imm")
8068                                         (const_string "mov_reg"))
8069                           (const_string "mvn_imm")
8070                           (const_string "multiple")
8071                           (const_string "multiple")
8072                           (const_string "multiple")
8073                           (const_string "multiple")])]
8076 (define_insn "*movsfcc_soft_insn"
8077   [(set (match_operand:SF 0 "s_register_operand" "=r,r")
8078         (if_then_else:SF (match_operator 3 "arm_comparison_operator"
8079                           [(match_operand 4 "cc_register" "") (const_int 0)])
8080                          (match_operand:SF 1 "s_register_operand" "0,r")
8081                          (match_operand:SF 2 "s_register_operand" "r,0")))]
8082   "TARGET_ARM && TARGET_SOFT_FLOAT"
8083   "@
8084    mov%D3\\t%0, %2
8085    mov%d3\\t%0, %1"
8086   [(set_attr "conds" "use")
8087    (set_attr "type" "mov_reg")]
8091 ;; Jump and linkage insns
8093 (define_expand "jump"
8094   [(set (pc)
8095         (label_ref (match_operand 0 "" "")))]
8096   "TARGET_EITHER"
8097   ""
8100 (define_insn "*arm_jump"
8101   [(set (pc)
8102         (label_ref (match_operand 0 "" "")))]
8103   "TARGET_32BIT"
8104   "*
8105   {
8106     if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
8107       {
8108         arm_ccfsm_state += 2;
8109         return \"\";
8110       }
8111     return \"b%?\\t%l0\";
8112   }
8113   "
8114   [(set_attr "predicable" "yes")
8115    (set (attr "length")
8116         (if_then_else
8117            (and (match_test "TARGET_THUMB2")
8118                 (and (ge (minus (match_dup 0) (pc)) (const_int -2044))
8119                      (le (minus (match_dup 0) (pc)) (const_int 2048))))
8120            (const_int 2)
8121            (const_int 4)))
8122    (set_attr "type" "branch")]
8125 (define_expand "call"
8126   [(parallel [(call (match_operand 0 "memory_operand" "")
8127                     (match_operand 1 "general_operand" ""))
8128               (use (match_operand 2 "" ""))
8129               (clobber (reg:SI LR_REGNUM))])]
8130   "TARGET_EITHER"
8131   "
8132   {
8133     rtx callee, pat;
8134     tree addr = MEM_EXPR (operands[0]);
8135     
8136     /* In an untyped call, we can get NULL for operand 2.  */
8137     if (operands[2] == NULL_RTX)
8138       operands[2] = const0_rtx;
8139       
8140     /* Decide if we should generate indirect calls by loading the
8141        32-bit address of the callee into a register before performing the
8142        branch and link.  */
8143     callee = XEXP (operands[0], 0);
8144     if (GET_CODE (callee) == SYMBOL_REF
8145         ? arm_is_long_call_p (SYMBOL_REF_DECL (callee))
8146         : !REG_P (callee))
8147       XEXP (operands[0], 0) = force_reg (Pmode, callee);
8149     if (detect_cmse_nonsecure_call (addr))
8150       {
8151         pat = gen_nonsecure_call_internal (operands[0], operands[1],
8152                                            operands[2]);
8153         emit_call_insn (pat);
8154       }
8155     else
8156       {
8157         pat = gen_call_internal (operands[0], operands[1], operands[2]);
8158         arm_emit_call_insn (pat, XEXP (operands[0], 0), false);
8159       }
8160     DONE;
8161   }"
8164 (define_expand "call_internal"
8165   [(parallel [(call (match_operand 0 "memory_operand" "")
8166                     (match_operand 1 "general_operand" ""))
8167               (use (match_operand 2 "" ""))
8168               (clobber (reg:SI LR_REGNUM))])])
8170 (define_expand "nonsecure_call_internal"
8171   [(parallel [(call (unspec:SI [(match_operand 0 "memory_operand" "")]
8172                                UNSPEC_NONSECURE_MEM)
8173                     (match_operand 1 "general_operand" ""))
8174               (use (match_operand 2 "" ""))
8175               (clobber (reg:SI LR_REGNUM))
8176               (clobber (reg:SI 4))])]
8177   "use_cmse"
8178   "
8179   {
8180     rtx tmp;
8181     tmp = copy_to_suggested_reg (XEXP (operands[0], 0),
8182                                  gen_rtx_REG (SImode, 4),
8183                                  SImode);
8185     operands[0] = replace_equiv_address (operands[0], tmp);
8186   }")
8188 (define_insn "*call_reg_armv5"
8189   [(call (mem:SI (match_operand:SI 0 "s_register_operand" "r"))
8190          (match_operand 1 "" ""))
8191    (use (match_operand 2 "" ""))
8192    (clobber (reg:SI LR_REGNUM))]
8193   "TARGET_ARM && arm_arch5 && !SIBLING_CALL_P (insn)"
8194   "blx%?\\t%0"
8195   [(set_attr "type" "call")]
8198 (define_insn "*call_reg_arm"
8199   [(call (mem:SI (match_operand:SI 0 "s_register_operand" "r"))
8200          (match_operand 1 "" ""))
8201    (use (match_operand 2 "" ""))
8202    (clobber (reg:SI LR_REGNUM))]
8203   "TARGET_ARM && !arm_arch5 && !SIBLING_CALL_P (insn)"
8204   "*
8205   return output_call (operands);
8206   "
8207   ;; length is worst case, normally it is only two
8208   [(set_attr "length" "12")
8209    (set_attr "type" "call")]
8213 (define_expand "call_value"
8214   [(parallel [(set (match_operand       0 "" "")
8215                    (call (match_operand 1 "memory_operand" "")
8216                          (match_operand 2 "general_operand" "")))
8217               (use (match_operand 3 "" ""))
8218               (clobber (reg:SI LR_REGNUM))])]
8219   "TARGET_EITHER"
8220   "
8221   {
8222     rtx pat, callee;
8223     tree addr = MEM_EXPR (operands[1]);
8224     
8225     /* In an untyped call, we can get NULL for operand 2.  */
8226     if (operands[3] == 0)
8227       operands[3] = const0_rtx;
8228       
8229     /* Decide if we should generate indirect calls by loading the
8230        32-bit address of the callee into a register before performing the
8231        branch and link.  */
8232     callee = XEXP (operands[1], 0);
8233     if (GET_CODE (callee) == SYMBOL_REF
8234         ? arm_is_long_call_p (SYMBOL_REF_DECL (callee))
8235         : !REG_P (callee))
8236       XEXP (operands[1], 0) = force_reg (Pmode, callee);
8238     if (detect_cmse_nonsecure_call (addr))
8239       {
8240         pat = gen_nonsecure_call_value_internal (operands[0], operands[1],
8241                                                  operands[2], operands[3]);
8242         emit_call_insn (pat);
8243       }
8244     else
8245       {
8246         pat = gen_call_value_internal (operands[0], operands[1],
8247                                        operands[2], operands[3]);
8248         arm_emit_call_insn (pat, XEXP (operands[1], 0), false);
8249       }
8250     DONE;
8251   }"
8254 (define_expand "call_value_internal"
8255   [(parallel [(set (match_operand       0 "" "")
8256                    (call (match_operand 1 "memory_operand" "")
8257                          (match_operand 2 "general_operand" "")))
8258               (use (match_operand 3 "" ""))
8259               (clobber (reg:SI LR_REGNUM))])])
8261 (define_expand "nonsecure_call_value_internal"
8262   [(parallel [(set (match_operand       0 "" "")
8263                    (call (unspec:SI [(match_operand 1 "memory_operand" "")]
8264                                     UNSPEC_NONSECURE_MEM)
8265                          (match_operand 2 "general_operand" "")))
8266               (use (match_operand 3 "" ""))
8267               (clobber (reg:SI LR_REGNUM))
8268               (clobber (reg:SI 4))])]
8269   "use_cmse"
8270   "
8271   {
8272     rtx tmp;
8273     tmp = copy_to_suggested_reg (XEXP (operands[1], 0),
8274                                  gen_rtx_REG (SImode, 4),
8275                                  SImode);
8277     operands[1] = replace_equiv_address (operands[1], tmp);
8278   }")
8280 (define_insn "*call_value_reg_armv5"
8281   [(set (match_operand 0 "" "")
8282         (call (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
8283               (match_operand 2 "" "")))
8284    (use (match_operand 3 "" ""))
8285    (clobber (reg:SI LR_REGNUM))]
8286   "TARGET_ARM && arm_arch5 && !SIBLING_CALL_P (insn)"
8287   "blx%?\\t%1"
8288   [(set_attr "type" "call")]
8291 (define_insn "*call_value_reg_arm"
8292   [(set (match_operand 0 "" "")
8293         (call (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
8294               (match_operand 2 "" "")))
8295    (use (match_operand 3 "" ""))
8296    (clobber (reg:SI LR_REGNUM))]
8297   "TARGET_ARM && !arm_arch5 && !SIBLING_CALL_P (insn)"
8298   "*
8299   return output_call (&operands[1]);
8300   "
8301   [(set_attr "length" "12")
8302    (set_attr "type" "call")]
8305 ;; Allow calls to SYMBOL_REFs specially as they are not valid general addresses
8306 ;; The 'a' causes the operand to be treated as an address, i.e. no '#' output.
8308 (define_insn "*call_symbol"
8309   [(call (mem:SI (match_operand:SI 0 "" ""))
8310          (match_operand 1 "" ""))
8311    (use (match_operand 2 "" ""))
8312    (clobber (reg:SI LR_REGNUM))]
8313   "TARGET_32BIT
8314    && !SIBLING_CALL_P (insn)
8315    && (GET_CODE (operands[0]) == SYMBOL_REF)
8316    && !arm_is_long_call_p (SYMBOL_REF_DECL (operands[0]))"
8317   "*
8318   {
8319    rtx op = operands[0];
8321    /* Switch mode now when possible.  */
8322    if (SYMBOL_REF_DECL (op) && !TREE_PUBLIC (SYMBOL_REF_DECL (op))
8323         && arm_arch5 && arm_change_mode_p (SYMBOL_REF_DECL (op)))
8324       return NEED_PLT_RELOC ? \"blx%?\\t%a0(PLT)\" : \"blx%?\\t(%a0)\";
8326     return NEED_PLT_RELOC ? \"bl%?\\t%a0(PLT)\" : \"bl%?\\t%a0\";
8327   }"
8328   [(set_attr "type" "call")]
8331 (define_insn "*call_value_symbol"
8332   [(set (match_operand 0 "" "")
8333         (call (mem:SI (match_operand:SI 1 "" ""))
8334         (match_operand:SI 2 "" "")))
8335    (use (match_operand 3 "" ""))
8336    (clobber (reg:SI LR_REGNUM))]
8337   "TARGET_32BIT
8338    && !SIBLING_CALL_P (insn)
8339    && (GET_CODE (operands[1]) == SYMBOL_REF)
8340    && !arm_is_long_call_p (SYMBOL_REF_DECL (operands[1]))"
8341   "*
8342   {
8343    rtx op = operands[1];
8345    /* Switch mode now when possible.  */
8346    if (SYMBOL_REF_DECL (op) && !TREE_PUBLIC (SYMBOL_REF_DECL (op))
8347         && arm_arch5 && arm_change_mode_p (SYMBOL_REF_DECL (op)))
8348       return NEED_PLT_RELOC ? \"blx%?\\t%a1(PLT)\" : \"blx%?\\t(%a1)\";
8350     return NEED_PLT_RELOC ? \"bl%?\\t%a1(PLT)\" : \"bl%?\\t%a1\";
8351   }"
8352   [(set_attr "type" "call")]
8355 (define_expand "sibcall_internal"
8356   [(parallel [(call (match_operand 0 "memory_operand" "")
8357                     (match_operand 1 "general_operand" ""))
8358               (return)
8359               (use (match_operand 2 "" ""))])])
8361 ;; We may also be able to do sibcalls for Thumb, but it's much harder...
8362 (define_expand "sibcall"
8363   [(parallel [(call (match_operand 0 "memory_operand" "")
8364                     (match_operand 1 "general_operand" ""))
8365               (return)
8366               (use (match_operand 2 "" ""))])]
8367   "TARGET_32BIT"
8368   "
8369   {
8370     rtx pat;
8372     if ((!REG_P (XEXP (operands[0], 0))
8373          && GET_CODE (XEXP (operands[0], 0)) != SYMBOL_REF)
8374         || (GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
8375             && arm_is_long_call_p (SYMBOL_REF_DECL (XEXP (operands[0], 0)))))
8376      XEXP (operands[0], 0) = force_reg (SImode, XEXP (operands[0], 0));
8378     if (operands[2] == NULL_RTX)
8379       operands[2] = const0_rtx;
8381     pat = gen_sibcall_internal (operands[0], operands[1], operands[2]);
8382     arm_emit_call_insn (pat, operands[0], true);
8383     DONE;
8384   }"
8387 (define_expand "sibcall_value_internal"
8388   [(parallel [(set (match_operand 0 "" "")
8389                    (call (match_operand 1 "memory_operand" "")
8390                          (match_operand 2 "general_operand" "")))
8391               (return)
8392               (use (match_operand 3 "" ""))])])
8394 (define_expand "sibcall_value"
8395   [(parallel [(set (match_operand 0 "" "")
8396                    (call (match_operand 1 "memory_operand" "")
8397                          (match_operand 2 "general_operand" "")))
8398               (return)
8399               (use (match_operand 3 "" ""))])]
8400   "TARGET_32BIT"
8401   "
8402   {
8403     rtx pat;
8405     if ((!REG_P (XEXP (operands[1], 0))
8406          && GET_CODE (XEXP (operands[1], 0)) != SYMBOL_REF)
8407         || (GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
8408             && arm_is_long_call_p (SYMBOL_REF_DECL (XEXP (operands[1], 0)))))
8409      XEXP (operands[1], 0) = force_reg (SImode, XEXP (operands[1], 0));
8411     if (operands[3] == NULL_RTX)
8412       operands[3] = const0_rtx;
8414     pat = gen_sibcall_value_internal (operands[0], operands[1],
8415                                       operands[2], operands[3]);
8416     arm_emit_call_insn (pat, operands[1], true);
8417     DONE;
8418   }"
8421 (define_insn "*sibcall_insn"
8422  [(call (mem:SI (match_operand:SI 0 "call_insn_operand" "Cs, US"))
8423         (match_operand 1 "" ""))
8424   (return)
8425   (use (match_operand 2 "" ""))]
8426   "TARGET_32BIT && SIBLING_CALL_P (insn)"
8427   "*
8428   if (which_alternative == 1)
8429     return NEED_PLT_RELOC ? \"b%?\\t%a0(PLT)\" : \"b%?\\t%a0\";
8430   else
8431     {
8432       if (arm_arch5 || arm_arch4t)
8433         return \"bx%?\\t%0\\t%@ indirect register sibling call\";
8434       else
8435         return \"mov%?\\t%|pc, %0\\t%@ indirect register sibling call\";
8436     }
8437   "
8438   [(set_attr "type" "call")]
8441 (define_insn "*sibcall_value_insn"
8442  [(set (match_operand 0 "" "")
8443        (call (mem:SI (match_operand:SI 1 "call_insn_operand" "Cs,US"))
8444              (match_operand 2 "" "")))
8445   (return)
8446   (use (match_operand 3 "" ""))]
8447   "TARGET_32BIT && SIBLING_CALL_P (insn)"
8448   "*
8449   if (which_alternative == 1)
8450    return NEED_PLT_RELOC ? \"b%?\\t%a1(PLT)\" : \"b%?\\t%a1\";
8451   else
8452     {
8453       if (arm_arch5 || arm_arch4t)
8454         return \"bx%?\\t%1\";
8455       else
8456         return \"mov%?\\t%|pc, %1\\t@ indirect sibling call \";
8457     }
8458   "
8459   [(set_attr "type" "call")]
8462 (define_expand "<return_str>return"
8463   [(RETURNS)]
8464   "(TARGET_ARM || (TARGET_THUMB2
8465                    && ARM_FUNC_TYPE (arm_current_func_type ()) == ARM_FT_NORMAL
8466                    && !IS_STACKALIGN (arm_current_func_type ())))
8467     <return_cond_false>"
8468   "
8469   {
8470     if (TARGET_THUMB2)
8471       {
8472         thumb2_expand_return (<return_simple_p>);
8473         DONE;
8474       }
8475   }
8476   "
8479 ;; Often the return insn will be the same as loading from memory, so set attr
8480 (define_insn "*arm_return"
8481   [(return)]
8482   "TARGET_ARM && USE_RETURN_INSN (FALSE)"
8483   "*
8484   {
8485     if (arm_ccfsm_state == 2)
8486       {
8487         arm_ccfsm_state += 2;
8488         return \"\";
8489       }
8490     return output_return_instruction (const_true_rtx, true, false, false);
8491   }"
8492   [(set_attr "type" "load1")
8493    (set_attr "length" "12")
8494    (set_attr "predicable" "yes")]
8497 (define_insn "*cond_<return_str>return"
8498   [(set (pc)
8499         (if_then_else (match_operator 0 "arm_comparison_operator"
8500                        [(match_operand 1 "cc_register" "") (const_int 0)])
8501                       (RETURNS)
8502                       (pc)))]
8503   "TARGET_ARM  <return_cond_true>"
8504   "*
8505   {
8506     if (arm_ccfsm_state == 2)
8507       {
8508         arm_ccfsm_state += 2;
8509         return \"\";
8510       }
8511     return output_return_instruction (operands[0], true, false,
8512                                       <return_simple_p>);
8513   }"
8514   [(set_attr "conds" "use")
8515    (set_attr "length" "12")
8516    (set_attr "type" "load1")]
8519 (define_insn "*cond_<return_str>return_inverted"
8520   [(set (pc)
8521         (if_then_else (match_operator 0 "arm_comparison_operator"
8522                        [(match_operand 1 "cc_register" "") (const_int 0)])
8523                       (pc)
8524                       (RETURNS)))]
8525   "TARGET_ARM <return_cond_true>"
8526   "*
8527   {
8528     if (arm_ccfsm_state == 2)
8529       {
8530         arm_ccfsm_state += 2;
8531         return \"\";
8532       }
8533     return output_return_instruction (operands[0], true, true,
8534                                       <return_simple_p>);
8535   }"
8536   [(set_attr "conds" "use")
8537    (set_attr "length" "12")
8538    (set_attr "type" "load1")]
8541 (define_insn "*arm_simple_return"
8542   [(simple_return)]
8543   "TARGET_ARM"
8544   "*
8545   {
8546     if (arm_ccfsm_state == 2)
8547       {
8548         arm_ccfsm_state += 2;
8549         return \"\";
8550       }
8551     return output_return_instruction (const_true_rtx, true, false, true);
8552   }"
8553   [(set_attr "type" "branch")
8554    (set_attr "length" "4")
8555    (set_attr "predicable" "yes")]
8558 ;; Generate a sequence of instructions to determine if the processor is
8559 ;; in 26-bit or 32-bit mode, and return the appropriate return address
8560 ;; mask.
8562 (define_expand "return_addr_mask"
8563   [(set (match_dup 1)
8564       (compare:CC_NOOV (unspec [(const_int 0)] UNSPEC_CHECK_ARCH)
8565                        (const_int 0)))
8566    (set (match_operand:SI 0 "s_register_operand" "")
8567       (if_then_else:SI (eq (match_dup 1) (const_int 0))
8568                        (const_int -1)
8569                        (const_int 67108860)))] ; 0x03fffffc
8570   "TARGET_ARM"
8571   "
8572   operands[1] = gen_rtx_REG (CC_NOOVmode, CC_REGNUM);
8573   ")
8575 (define_insn "*check_arch2"
8576   [(set (match_operand:CC_NOOV 0 "cc_register" "")
8577       (compare:CC_NOOV (unspec [(const_int 0)] UNSPEC_CHECK_ARCH)
8578                        (const_int 0)))]
8579   "TARGET_ARM"
8580   "teq\\t%|r0, %|r0\;teq\\t%|pc, %|pc"
8581   [(set_attr "length" "8")
8582    (set_attr "conds" "set")
8583    (set_attr "type" "multiple")]
8586 ;; Call subroutine returning any type.
8588 (define_expand "untyped_call"
8589   [(parallel [(call (match_operand 0 "" "")
8590                     (const_int 0))
8591               (match_operand 1 "" "")
8592               (match_operand 2 "" "")])]
8593   "TARGET_EITHER"
8594   "
8595   {
8596     int i;
8597     rtx par = gen_rtx_PARALLEL (VOIDmode,
8598                                 rtvec_alloc (XVECLEN (operands[2], 0)));
8599     rtx addr = gen_reg_rtx (Pmode);
8600     rtx mem;
8601     int size = 0;
8603     emit_move_insn (addr, XEXP (operands[1], 0));
8604     mem = change_address (operands[1], BLKmode, addr);
8606     for (i = 0; i < XVECLEN (operands[2], 0); i++)
8607       {
8608         rtx src = SET_SRC (XVECEXP (operands[2], 0, i));
8610         /* Default code only uses r0 as a return value, but we could
8611            be using anything up to 4 registers.  */
8612         if (REGNO (src) == R0_REGNUM)
8613           src = gen_rtx_REG (TImode, R0_REGNUM);
8615         XVECEXP (par, 0, i) = gen_rtx_EXPR_LIST (VOIDmode, src,
8616                                                  GEN_INT (size));
8617         size += GET_MODE_SIZE (GET_MODE (src));
8618       }
8620     emit_call_insn (gen_call_value (par, operands[0], const0_rtx, NULL));
8622     size = 0;
8624     for (i = 0; i < XVECLEN (par, 0); i++)
8625       {
8626         HOST_WIDE_INT offset = 0;
8627         rtx reg = XEXP (XVECEXP (par, 0, i), 0);
8629         if (size != 0)
8630           emit_move_insn (addr, plus_constant (Pmode, addr, size));
8632         mem = change_address (mem, GET_MODE (reg), NULL);
8633         if (REGNO (reg) == R0_REGNUM)
8634           {
8635             /* On thumb we have to use a write-back instruction.  */
8636             emit_insn (arm_gen_store_multiple (arm_regs_in_sequence, 4, addr,
8637                        TARGET_THUMB ? TRUE : FALSE, mem, &offset));
8638             size = TARGET_ARM ? 16 : 0;
8639           }
8640         else
8641           {
8642             emit_move_insn (mem, reg);
8643             size = GET_MODE_SIZE (GET_MODE (reg));
8644           }
8645       }
8647     /* The optimizer does not know that the call sets the function value
8648        registers we stored in the result block.  We avoid problems by
8649        claiming that all hard registers are used and clobbered at this
8650        point.  */
8651     emit_insn (gen_blockage ());
8653     DONE;
8654   }"
8657 (define_expand "untyped_return"
8658   [(match_operand:BLK 0 "memory_operand" "")
8659    (match_operand 1 "" "")]
8660   "TARGET_EITHER"
8661   "
8662   {
8663     int i;
8664     rtx addr = gen_reg_rtx (Pmode);
8665     rtx mem;
8666     int size = 0;
8668     emit_move_insn (addr, XEXP (operands[0], 0));
8669     mem = change_address (operands[0], BLKmode, addr);
8671     for (i = 0; i < XVECLEN (operands[1], 0); i++)
8672       {
8673         HOST_WIDE_INT offset = 0;
8674         rtx reg = SET_DEST (XVECEXP (operands[1], 0, i));
8676         if (size != 0)
8677           emit_move_insn (addr, plus_constant (Pmode, addr, size));
8679         mem = change_address (mem, GET_MODE (reg), NULL);
8680         if (REGNO (reg) == R0_REGNUM)
8681           {
8682             /* On thumb we have to use a write-back instruction.  */
8683             emit_insn (arm_gen_load_multiple (arm_regs_in_sequence, 4, addr,
8684                        TARGET_THUMB ? TRUE : FALSE, mem, &offset));
8685             size = TARGET_ARM ? 16 : 0;
8686           }
8687         else
8688           {
8689             emit_move_insn (reg, mem);
8690             size = GET_MODE_SIZE (GET_MODE (reg));
8691           }
8692       }
8694     /* Emit USE insns before the return.  */
8695     for (i = 0; i < XVECLEN (operands[1], 0); i++)
8696       emit_use (SET_DEST (XVECEXP (operands[1], 0, i)));
8698     /* Construct the return.  */
8699     expand_naked_return ();
8701     DONE;
8702   }"
8705 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
8706 ;; all of memory.  This blocks insns from being moved across this point.
8708 (define_insn "blockage"
8709   [(unspec_volatile [(const_int 0)] VUNSPEC_BLOCKAGE)]
8710   "TARGET_EITHER"
8711   ""
8712   [(set_attr "length" "0")
8713    (set_attr "type" "block")]
8716 (define_insn "probe_stack"
8717   [(set (match_operand:SI 0 "memory_operand" "=m")
8718         (unspec:SI [(const_int 0)] UNSPEC_PROBE_STACK))]
8719   "TARGET_32BIT"
8720   "str%?\\tr0, %0"
8721   [(set_attr "type" "store1")
8722    (set_attr "predicable" "yes")]
8725 (define_insn "probe_stack_range"
8726   [(set (match_operand:SI 0 "register_operand" "=r")
8727         (unspec_volatile:SI [(match_operand:SI 1 "register_operand" "0")
8728                              (match_operand:SI 2 "register_operand" "r")]
8729                              VUNSPEC_PROBE_STACK_RANGE))]
8730   "TARGET_32BIT"
8732   return output_probe_stack_range (operands[0], operands[2]);
8734   [(set_attr "type" "multiple")
8735    (set_attr "conds" "clob")]
8738 (define_expand "casesi"
8739   [(match_operand:SI 0 "s_register_operand" "") ; index to jump on
8740    (match_operand:SI 1 "const_int_operand" "")  ; lower bound
8741    (match_operand:SI 2 "const_int_operand" "")  ; total range
8742    (match_operand:SI 3 "" "")                   ; table label
8743    (match_operand:SI 4 "" "")]                  ; Out of range label
8744   "(TARGET_32BIT || optimize_size || flag_pic) && !target_pure_code"
8745   "
8746   {
8747     enum insn_code code;
8748     if (operands[1] != const0_rtx)
8749       {
8750         rtx reg = gen_reg_rtx (SImode);
8752         emit_insn (gen_addsi3 (reg, operands[0],
8753                                gen_int_mode (-INTVAL (operands[1]),
8754                                              SImode)));
8755         operands[0] = reg;
8756       }
8758     if (TARGET_ARM)
8759       code = CODE_FOR_arm_casesi_internal;
8760     else if (TARGET_THUMB1)
8761       code = CODE_FOR_thumb1_casesi_internal_pic;
8762     else if (flag_pic)
8763       code = CODE_FOR_thumb2_casesi_internal_pic;
8764     else
8765       code = CODE_FOR_thumb2_casesi_internal;
8767     if (!insn_data[(int) code].operand[1].predicate(operands[2], SImode))
8768       operands[2] = force_reg (SImode, operands[2]);
8770     emit_jump_insn (GEN_FCN ((int) code) (operands[0], operands[2],
8771                                           operands[3], operands[4]));
8772     DONE;
8773   }"
8776 ;; The USE in this pattern is needed to tell flow analysis that this is
8777 ;; a CASESI insn.  It has no other purpose.
8778 (define_insn "arm_casesi_internal"
8779   [(parallel [(set (pc)
8780                (if_then_else
8781                 (leu (match_operand:SI 0 "s_register_operand" "r")
8782                      (match_operand:SI 1 "arm_rhs_operand" "rI"))
8783                 (mem:SI (plus:SI (mult:SI (match_dup 0) (const_int 4))
8784                                  (label_ref (match_operand 2 "" ""))))
8785                 (label_ref (match_operand 3 "" ""))))
8786               (clobber (reg:CC CC_REGNUM))
8787               (use (label_ref (match_dup 2)))])]
8788   "TARGET_ARM"
8789   "*
8790     if (flag_pic)
8791       return \"cmp\\t%0, %1\;addls\\t%|pc, %|pc, %0, asl #2\;b\\t%l3\";
8792     return   \"cmp\\t%0, %1\;ldrls\\t%|pc, [%|pc, %0, asl #2]\;b\\t%l3\";
8793   "
8794   [(set_attr "conds" "clob")
8795    (set_attr "length" "12")
8796    (set_attr "type" "multiple")]
8799 (define_expand "indirect_jump"
8800   [(set (pc)
8801         (match_operand:SI 0 "s_register_operand" ""))]
8802   "TARGET_EITHER"
8803   "
8804   /* Thumb-2 doesn't have mov pc, reg.  Explicitly set the low bit of the
8805      address and use bx.  */
8806   if (TARGET_THUMB2)
8807     {
8808       rtx tmp;
8809       tmp = gen_reg_rtx (SImode);
8810       emit_insn (gen_iorsi3 (tmp, operands[0], GEN_INT(1)));
8811       operands[0] = tmp;
8812     }
8813   "
8816 ;; NB Never uses BX.
8817 (define_insn "*arm_indirect_jump"
8818   [(set (pc)
8819         (match_operand:SI 0 "s_register_operand" "r"))]
8820   "TARGET_ARM"
8821   "mov%?\\t%|pc, %0\\t%@ indirect register jump"
8822   [(set_attr "predicable" "yes")
8823    (set_attr "type" "branch")]
8826 (define_insn "*load_indirect_jump"
8827   [(set (pc)
8828         (match_operand:SI 0 "memory_operand" "m"))]
8829   "TARGET_ARM"
8830   "ldr%?\\t%|pc, %0\\t%@ indirect memory jump"
8831   [(set_attr "type" "load1")
8832    (set_attr "pool_range" "4096")
8833    (set_attr "neg_pool_range" "4084")
8834    (set_attr "predicable" "yes")]
8838 ;; Misc insns
8840 (define_insn "nop"
8841   [(const_int 0)]
8842   "TARGET_EITHER"
8843   "nop"
8844   [(set (attr "length")
8845         (if_then_else (eq_attr "is_thumb" "yes")
8846                       (const_int 2)
8847                       (const_int 4)))
8848    (set_attr "type" "mov_reg")]
8851 (define_insn "trap"
8852   [(trap_if (const_int 1) (const_int 0))]
8853   ""
8854   "*
8855   if (TARGET_ARM)
8856     return \".inst\\t0xe7f000f0\";
8857   else
8858     return \".inst\\t0xdeff\";
8859   "
8860   [(set (attr "length")
8861         (if_then_else (eq_attr "is_thumb" "yes")
8862                       (const_int 2)
8863                       (const_int 4)))
8864    (set_attr "type" "trap")
8865    (set_attr "conds" "unconditional")]
8869 ;; Patterns to allow combination of arithmetic, cond code and shifts
8871 (define_insn "*<arith_shift_insn>_multsi"
8872   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8873         (SHIFTABLE_OPS:SI
8874          (mult:SI (match_operand:SI 2 "s_register_operand" "r,r")
8875                   (match_operand:SI 3 "power_of_two_operand" ""))
8876          (match_operand:SI 1 "s_register_operand" "rk,<t2_binop0>")))]
8877   "TARGET_32BIT"
8878   "<arith_shift_insn>%?\\t%0, %1, %2, lsl %b3"
8879   [(set_attr "predicable" "yes")
8880    (set_attr "predicable_short_it" "no")
8881    (set_attr "shift" "2")
8882    (set_attr "arch" "a,t2")
8883    (set_attr "type" "alu_shift_imm")])
8885 (define_insn "*<arith_shift_insn>_shiftsi"
8886   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
8887         (SHIFTABLE_OPS:SI
8888          (match_operator:SI 2 "shift_nomul_operator"
8889           [(match_operand:SI 3 "s_register_operand" "r,r,r")
8890            (match_operand:SI 4 "shift_amount_operand" "M,M,r")])
8891          (match_operand:SI 1 "s_register_operand" "rk,<t2_binop0>,rk")))]
8892   "TARGET_32BIT && GET_CODE (operands[2]) != MULT"
8893   "<arith_shift_insn>%?\\t%0, %1, %3%S2"
8894   [(set_attr "predicable" "yes")
8895    (set_attr "predicable_short_it" "no")
8896    (set_attr "shift" "3")
8897    (set_attr "arch" "a,t2,a")
8898    (set_attr "type" "alu_shift_imm,alu_shift_imm,alu_shift_reg")])
8900 (define_split
8901   [(set (match_operand:SI 0 "s_register_operand" "")
8902         (match_operator:SI 1 "shiftable_operator"
8903          [(match_operator:SI 2 "shiftable_operator"
8904            [(match_operator:SI 3 "shift_operator"
8905              [(match_operand:SI 4 "s_register_operand" "")
8906               (match_operand:SI 5 "reg_or_int_operand" "")])
8907             (match_operand:SI 6 "s_register_operand" "")])
8908           (match_operand:SI 7 "arm_rhs_operand" "")]))
8909    (clobber (match_operand:SI 8 "s_register_operand" ""))]
8910   "TARGET_32BIT"
8911   [(set (match_dup 8)
8912         (match_op_dup 2 [(match_op_dup 3 [(match_dup 4) (match_dup 5)])
8913                          (match_dup 6)]))
8914    (set (match_dup 0)
8915         (match_op_dup 1 [(match_dup 8) (match_dup 7)]))]
8916   "")
8918 (define_insn "*arith_shiftsi_compare0"
8919   [(set (reg:CC_NOOV CC_REGNUM)
8920         (compare:CC_NOOV
8921          (match_operator:SI 1 "shiftable_operator"
8922           [(match_operator:SI 3 "shift_operator"
8923             [(match_operand:SI 4 "s_register_operand" "r,r")
8924              (match_operand:SI 5 "shift_amount_operand" "M,r")])
8925            (match_operand:SI 2 "s_register_operand" "r,r")])
8926          (const_int 0)))
8927    (set (match_operand:SI 0 "s_register_operand" "=r,r")
8928         (match_op_dup 1 [(match_op_dup 3 [(match_dup 4) (match_dup 5)])
8929                          (match_dup 2)]))]
8930   "TARGET_32BIT"
8931   "%i1s%?\\t%0, %2, %4%S3"
8932   [(set_attr "conds" "set")
8933    (set_attr "shift" "4")
8934    (set_attr "arch" "32,a")
8935    (set_attr "type" "alus_shift_imm,alus_shift_reg")])
8937 (define_insn "*arith_shiftsi_compare0_scratch"
8938   [(set (reg:CC_NOOV CC_REGNUM)
8939         (compare:CC_NOOV
8940          (match_operator:SI 1 "shiftable_operator"
8941           [(match_operator:SI 3 "shift_operator"
8942             [(match_operand:SI 4 "s_register_operand" "r,r")
8943              (match_operand:SI 5 "shift_amount_operand" "M,r")])
8944            (match_operand:SI 2 "s_register_operand" "r,r")])
8945          (const_int 0)))
8946    (clobber (match_scratch:SI 0 "=r,r"))]
8947   "TARGET_32BIT"
8948   "%i1s%?\\t%0, %2, %4%S3"
8949   [(set_attr "conds" "set")
8950    (set_attr "shift" "4")
8951    (set_attr "arch" "32,a")
8952    (set_attr "type" "alus_shift_imm,alus_shift_reg")])
8954 (define_insn "*sub_shiftsi"
8955   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8956         (minus:SI (match_operand:SI 1 "s_register_operand" "r,r")
8957                   (match_operator:SI 2 "shift_operator"
8958                    [(match_operand:SI 3 "s_register_operand" "r,r")
8959                     (match_operand:SI 4 "shift_amount_operand" "M,r")])))]
8960   "TARGET_32BIT"
8961   "sub%?\\t%0, %1, %3%S2"
8962   [(set_attr "predicable" "yes")
8963    (set_attr "shift" "3")
8964    (set_attr "arch" "32,a")
8965    (set_attr "type" "alus_shift_imm,alus_shift_reg")])
8967 (define_insn "*sub_shiftsi_compare0"
8968   [(set (reg:CC_NOOV CC_REGNUM)
8969         (compare:CC_NOOV
8970          (minus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
8971                    (match_operator:SI 2 "shift_operator"
8972                     [(match_operand:SI 3 "s_register_operand" "r,r,r")
8973                      (match_operand:SI 4 "shift_amount_operand" "M,r,M")]))
8974          (const_int 0)))
8975    (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
8976         (minus:SI (match_dup 1)
8977                   (match_op_dup 2 [(match_dup 3) (match_dup 4)])))]
8978   "TARGET_32BIT"
8979   "subs%?\\t%0, %1, %3%S2"
8980   [(set_attr "conds" "set")
8981    (set_attr "shift" "3")
8982    (set_attr "arch" "32,a,a")
8983    (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
8985 (define_insn "*sub_shiftsi_compare0_scratch"
8986   [(set (reg:CC_NOOV CC_REGNUM)
8987         (compare:CC_NOOV
8988          (minus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
8989                    (match_operator:SI 2 "shift_operator"
8990                     [(match_operand:SI 3 "s_register_operand" "r,r,r")
8991                      (match_operand:SI 4 "shift_amount_operand" "M,r,M")]))
8992          (const_int 0)))
8993    (clobber (match_scratch:SI 0 "=r,r,r"))]
8994   "TARGET_32BIT"
8995   "subs%?\\t%0, %1, %3%S2"
8996   [(set_attr "conds" "set")
8997    (set_attr "shift" "3")
8998    (set_attr "arch" "32,a,a")
8999    (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
9002 (define_insn_and_split "*and_scc"
9003   [(set (match_operand:SI 0 "s_register_operand" "=r")
9004         (and:SI (match_operator:SI 1 "arm_comparison_operator"
9005                  [(match_operand 2 "cc_register" "") (const_int 0)])
9006                 (match_operand:SI 3 "s_register_operand" "r")))]
9007   "TARGET_ARM"
9008   "#"   ; "mov%D1\\t%0, #0\;and%d1\\t%0, %3, #1"
9009   "&& reload_completed"
9010   [(cond_exec (match_dup 5) (set (match_dup 0) (const_int 0)))
9011    (cond_exec (match_dup 4) (set (match_dup 0)
9012                                  (and:SI (match_dup 3) (const_int 1))))]
9013   {
9014     machine_mode mode = GET_MODE (operands[2]);
9015     enum rtx_code rc = GET_CODE (operands[1]);
9017     /* Note that operands[4] is the same as operands[1],
9018        but with VOIDmode as the result. */
9019     operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
9020     if (mode == CCFPmode || mode == CCFPEmode)
9021       rc = reverse_condition_maybe_unordered (rc);
9022     else
9023       rc = reverse_condition (rc);
9024     operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
9025   }
9026   [(set_attr "conds" "use")
9027    (set_attr "type" "multiple")
9028    (set_attr "length" "8")]
9031 (define_insn_and_split "*ior_scc"
9032   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9033         (ior:SI (match_operator:SI 1 "arm_comparison_operator"
9034                  [(match_operand 2 "cc_register" "") (const_int 0)])
9035                 (match_operand:SI 3 "s_register_operand" "0,?r")))]
9036   "TARGET_ARM"
9037   "@
9038    orr%d1\\t%0, %3, #1
9039    #"
9040   "&& reload_completed
9041    && REGNO (operands [0]) != REGNO (operands[3])"
9042   ;; && which_alternative == 1
9043   ; mov%D1\\t%0, %3\;orr%d1\\t%0, %3, #1
9044   [(cond_exec (match_dup 5) (set (match_dup 0) (match_dup 3)))
9045    (cond_exec (match_dup 4) (set (match_dup 0)
9046                                  (ior:SI (match_dup 3) (const_int 1))))]
9047   {
9048     machine_mode mode = GET_MODE (operands[2]);
9049     enum rtx_code rc = GET_CODE (operands[1]);
9051     /* Note that operands[4] is the same as operands[1],
9052        but with VOIDmode as the result. */
9053     operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
9054     if (mode == CCFPmode || mode == CCFPEmode)
9055       rc = reverse_condition_maybe_unordered (rc);
9056     else
9057       rc = reverse_condition (rc);
9058     operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
9059   }
9060   [(set_attr "conds" "use")
9061    (set_attr "length" "4,8")
9062    (set_attr "type" "logic_imm,multiple")]
9065 ; A series of splitters for the compare_scc pattern below.  Note that
9066 ; order is important.
9067 (define_split
9068   [(set (match_operand:SI 0 "s_register_operand" "")
9069         (lt:SI (match_operand:SI 1 "s_register_operand" "")
9070                (const_int 0)))
9071    (clobber (reg:CC CC_REGNUM))]
9072   "TARGET_32BIT && reload_completed"
9073   [(set (match_dup 0) (lshiftrt:SI (match_dup 1) (const_int 31)))])
9075 (define_split
9076   [(set (match_operand:SI 0 "s_register_operand" "")
9077         (ge:SI (match_operand:SI 1 "s_register_operand" "")
9078                (const_int 0)))
9079    (clobber (reg:CC CC_REGNUM))]
9080   "TARGET_32BIT && reload_completed"
9081   [(set (match_dup 0) (not:SI (match_dup 1)))
9082    (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 31)))])
9084 (define_split
9085   [(set (match_operand:SI 0 "s_register_operand" "")
9086         (eq:SI (match_operand:SI 1 "s_register_operand" "")
9087                (const_int 0)))
9088    (clobber (reg:CC CC_REGNUM))]
9089   "arm_arch5 && TARGET_32BIT"
9090   [(set (match_dup 0) (clz:SI (match_dup 1)))
9091    (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
9094 (define_split
9095   [(set (match_operand:SI 0 "s_register_operand" "")
9096         (eq:SI (match_operand:SI 1 "s_register_operand" "")
9097                (const_int 0)))
9098    (clobber (reg:CC CC_REGNUM))]
9099   "TARGET_32BIT && reload_completed"
9100   [(parallel
9101     [(set (reg:CC CC_REGNUM)
9102           (compare:CC (const_int 1) (match_dup 1)))
9103      (set (match_dup 0)
9104           (minus:SI (const_int 1) (match_dup 1)))])
9105    (cond_exec (ltu:CC (reg:CC CC_REGNUM) (const_int 0))
9106               (set (match_dup 0) (const_int 0)))])
9108 (define_split
9109   [(set (match_operand:SI 0 "s_register_operand" "")
9110         (ne:SI (match_operand:SI 1 "s_register_operand" "")
9111                (match_operand:SI 2 "const_int_operand" "")))
9112    (clobber (reg:CC CC_REGNUM))]
9113   "TARGET_32BIT && reload_completed"
9114   [(parallel
9115     [(set (reg:CC CC_REGNUM)
9116           (compare:CC (match_dup 1) (match_dup 2)))
9117      (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 3)))])
9118    (cond_exec (ne:CC (reg:CC CC_REGNUM) (const_int 0))
9119               (set (match_dup 0) (const_int 1)))]
9121   operands[3] = GEN_INT (-INTVAL (operands[2]));
9124 (define_split
9125   [(set (match_operand:SI 0 "s_register_operand" "")
9126         (ne:SI (match_operand:SI 1 "s_register_operand" "")
9127                (match_operand:SI 2 "arm_add_operand" "")))
9128    (clobber (reg:CC CC_REGNUM))]
9129   "TARGET_32BIT && reload_completed"
9130   [(parallel
9131     [(set (reg:CC_NOOV CC_REGNUM)
9132           (compare:CC_NOOV (minus:SI (match_dup 1) (match_dup 2))
9133                            (const_int 0)))
9134      (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
9135    (cond_exec (ne:CC_NOOV (reg:CC_NOOV CC_REGNUM) (const_int 0))
9136               (set (match_dup 0) (const_int 1)))])
9138 (define_insn_and_split "*compare_scc"
9139   [(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts")
9140         (match_operator:SI 1 "arm_comparison_operator"
9141          [(match_operand:SI 2 "s_register_operand" "r,r")
9142           (match_operand:SI 3 "arm_add_operand" "rI,L")]))
9143    (clobber (reg:CC CC_REGNUM))]
9144   "TARGET_32BIT"
9145   "#"
9146   "&& reload_completed"
9147   [(set (reg:CC CC_REGNUM) (compare:CC (match_dup 2) (match_dup 3)))
9148    (cond_exec (match_dup 4) (set (match_dup 0) (const_int 0)))
9149    (cond_exec (match_dup 5) (set (match_dup 0) (const_int 1)))]
9151   rtx tmp1;
9152   machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
9153                                            operands[2], operands[3]);
9154   enum rtx_code rc = GET_CODE (operands[1]);
9156   tmp1 = gen_rtx_REG (mode, CC_REGNUM);
9158   operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, tmp1, const0_rtx);
9159   if (mode == CCFPmode || mode == CCFPEmode)
9160     rc = reverse_condition_maybe_unordered (rc);
9161   else
9162     rc = reverse_condition (rc);
9163   operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, tmp1, const0_rtx);
9165   [(set_attr "type" "multiple")]
9168 ;; Attempt to improve the sequence generated by the compare_scc splitters
9169 ;; not to use conditional execution.
9171 ;; Rd = (eq (reg1) (const_int0))  // ARMv5
9172 ;;      clz Rd, reg1
9173 ;;      lsr Rd, Rd, #5
9174 (define_peephole2
9175   [(set (reg:CC CC_REGNUM)
9176         (compare:CC (match_operand:SI 1 "register_operand" "")
9177                     (const_int 0)))
9178    (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
9179               (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
9180    (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
9181               (set (match_dup 0) (const_int 1)))]
9182   "arm_arch5 && TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
9183   [(set (match_dup 0) (clz:SI (match_dup 1)))
9184    (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
9187 ;; Rd = (eq (reg1) (const_int0))  // !ARMv5
9188 ;;      negs Rd, reg1
9189 ;;      adc  Rd, Rd, reg1
9190 (define_peephole2
9191   [(set (reg:CC CC_REGNUM)
9192         (compare:CC (match_operand:SI 1 "register_operand" "")
9193                     (const_int 0)))
9194    (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
9195               (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
9196    (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
9197               (set (match_dup 0) (const_int 1)))
9198    (match_scratch:SI 2 "r")]
9199   "TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
9200   [(parallel
9201     [(set (reg:CC CC_REGNUM)
9202           (compare:CC (const_int 0) (match_dup 1)))
9203      (set (match_dup 2) (minus:SI (const_int 0) (match_dup 1)))])
9204    (set (match_dup 0)
9205         (plus:SI (plus:SI (match_dup 1) (match_dup 2))
9206                  (geu:SI (reg:CC CC_REGNUM) (const_int 0))))]
9209 ;; Rd = (eq (reg1) (reg2/imm))  // ARMv5 and optimising for speed.
9210 ;;      sub  Rd, Reg1, reg2
9211 ;;      clz  Rd, Rd
9212 ;;      lsr  Rd, Rd, #5
9213 (define_peephole2
9214   [(set (reg:CC CC_REGNUM)
9215         (compare:CC (match_operand:SI 1 "register_operand" "")
9216                     (match_operand:SI 2 "arm_rhs_operand" "")))
9217    (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
9218               (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
9219    (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
9220               (set (match_dup 0) (const_int 1)))]
9221   "arm_arch5 && TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)
9222   && !(TARGET_THUMB2 && optimize_insn_for_size_p ())"
9223   [(set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))
9224    (set (match_dup 0) (clz:SI (match_dup 0)))
9225    (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
9229 ;; Rd = (eq (reg1) (reg2))      // ! ARMv5 or optimising for size.
9230 ;;      sub  T1, Reg1, reg2
9231 ;;      negs Rd, T1
9232 ;;      adc  Rd, Rd, T1
9233 (define_peephole2
9234   [(set (reg:CC CC_REGNUM)
9235         (compare:CC (match_operand:SI 1 "register_operand" "")
9236                     (match_operand:SI 2 "arm_rhs_operand" "")))
9237    (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
9238               (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
9239    (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
9240               (set (match_dup 0) (const_int 1)))
9241    (match_scratch:SI 3 "r")]
9242   "TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
9243   [(set (match_dup 3) (match_dup 4))
9244    (parallel
9245     [(set (reg:CC CC_REGNUM)
9246           (compare:CC (const_int 0) (match_dup 3)))
9247      (set (match_dup 0) (minus:SI (const_int 0) (match_dup 3)))])
9248    (set (match_dup 0)
9249         (plus:SI (plus:SI (match_dup 0) (match_dup 3))
9250                  (geu:SI (reg:CC CC_REGNUM) (const_int 0))))]
9251   "
9252   if (CONST_INT_P (operands[2]))
9253     operands[4] = plus_constant (SImode, operands[1], -INTVAL (operands[2]));
9254   else
9255     operands[4] = gen_rtx_MINUS (SImode, operands[1], operands[2]);
9256   ")
9258 (define_insn "*cond_move"
9259   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9260         (if_then_else:SI (match_operator 3 "equality_operator"
9261                           [(match_operator 4 "arm_comparison_operator"
9262                             [(match_operand 5 "cc_register" "") (const_int 0)])
9263                            (const_int 0)])
9264                          (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
9265                          (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))]
9266   "TARGET_ARM"
9267   "*
9268     if (GET_CODE (operands[3]) == NE)
9269       {
9270         if (which_alternative != 1)
9271           output_asm_insn (\"mov%D4\\t%0, %2\", operands);
9272         if (which_alternative != 0)
9273           output_asm_insn (\"mov%d4\\t%0, %1\", operands);
9274         return \"\";
9275       }
9276     if (which_alternative != 0)
9277       output_asm_insn (\"mov%D4\\t%0, %1\", operands);
9278     if (which_alternative != 1)
9279       output_asm_insn (\"mov%d4\\t%0, %2\", operands);
9280     return \"\";
9281   "
9282   [(set_attr "conds" "use")
9283    (set_attr_alternative "type"
9284                          [(if_then_else (match_operand 2 "const_int_operand" "")
9285                                         (const_string "mov_imm")
9286                                         (const_string "mov_reg"))
9287                           (if_then_else (match_operand 1 "const_int_operand" "")
9288                                         (const_string "mov_imm")
9289                                         (const_string "mov_reg"))
9290                           (const_string "multiple")])
9291    (set_attr "length" "4,4,8")]
9294 (define_insn "*cond_arith"
9295   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9296         (match_operator:SI 5 "shiftable_operator" 
9297          [(match_operator:SI 4 "arm_comparison_operator"
9298            [(match_operand:SI 2 "s_register_operand" "r,r")
9299             (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
9300           (match_operand:SI 1 "s_register_operand" "0,?r")]))
9301    (clobber (reg:CC CC_REGNUM))]
9302   "TARGET_ARM"
9303   "*
9304     if (GET_CODE (operands[4]) == LT && operands[3] == const0_rtx)
9305       return \"%i5\\t%0, %1, %2, lsr #31\";
9307     output_asm_insn (\"cmp\\t%2, %3\", operands);
9308     if (GET_CODE (operands[5]) == AND)
9309       output_asm_insn (\"mov%D4\\t%0, #0\", operands);
9310     else if (GET_CODE (operands[5]) == MINUS)
9311       output_asm_insn (\"rsb%D4\\t%0, %1, #0\", operands);
9312     else if (which_alternative != 0)
9313       output_asm_insn (\"mov%D4\\t%0, %1\", operands);
9314     return \"%i5%d4\\t%0, %1, #1\";
9315   "
9316   [(set_attr "conds" "clob")
9317    (set_attr "length" "12")
9318    (set_attr "type" "multiple")]
9321 (define_insn "*cond_sub"
9322   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9323         (minus:SI (match_operand:SI 1 "s_register_operand" "0,?r")
9324                   (match_operator:SI 4 "arm_comparison_operator"
9325                    [(match_operand:SI 2 "s_register_operand" "r,r")
9326                     (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
9327    (clobber (reg:CC CC_REGNUM))]
9328   "TARGET_ARM"
9329   "*
9330     output_asm_insn (\"cmp\\t%2, %3\", operands);
9331     if (which_alternative != 0)
9332       output_asm_insn (\"mov%D4\\t%0, %1\", operands);
9333     return \"sub%d4\\t%0, %1, #1\";
9334   "
9335   [(set_attr "conds" "clob")
9336    (set_attr "length" "8,12")
9337    (set_attr "type" "multiple")]
9340 (define_insn "*cmp_ite0"
9341   [(set (match_operand 6 "dominant_cc_register" "")
9342         (compare
9343          (if_then_else:SI
9344           (match_operator 4 "arm_comparison_operator"
9345            [(match_operand:SI 0 "s_register_operand"
9346                 "l,l,l,r,r,r,r,r,r")
9347             (match_operand:SI 1 "arm_add_operand"
9348                 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
9349           (match_operator:SI 5 "arm_comparison_operator"
9350            [(match_operand:SI 2 "s_register_operand"
9351                 "l,r,r,l,l,r,r,r,r")
9352             (match_operand:SI 3 "arm_add_operand"
9353                 "lPy,rI,L,lPy,lPy,rI,rI,L,L")])
9354           (const_int 0))
9355          (const_int 0)))]
9356   "TARGET_32BIT"
9357   "*
9358   {
9359     static const char * const cmp1[NUM_OF_COND_CMP][2] =
9360     {
9361       {\"cmp%d5\\t%0, %1\",
9362        \"cmp%d4\\t%2, %3\"},
9363       {\"cmn%d5\\t%0, #%n1\",
9364        \"cmp%d4\\t%2, %3\"},
9365       {\"cmp%d5\\t%0, %1\",
9366        \"cmn%d4\\t%2, #%n3\"},
9367       {\"cmn%d5\\t%0, #%n1\",
9368        \"cmn%d4\\t%2, #%n3\"}
9369     };
9370     static const char * const cmp2[NUM_OF_COND_CMP][2] =
9371     {
9372       {\"cmp\\t%2, %3\",
9373        \"cmp\\t%0, %1\"},
9374       {\"cmp\\t%2, %3\",
9375        \"cmn\\t%0, #%n1\"},
9376       {\"cmn\\t%2, #%n3\",
9377        \"cmp\\t%0, %1\"},
9378       {\"cmn\\t%2, #%n3\",
9379        \"cmn\\t%0, #%n1\"}
9380     };
9381     static const char * const ite[2] =
9382     {
9383       \"it\\t%d5\",
9384       \"it\\t%d4\"
9385     };
9386     static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
9387                                    CMP_CMP, CMN_CMP, CMP_CMP,
9388                                    CMN_CMP, CMP_CMN, CMN_CMN};
9389     int swap =
9390       comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
9392     output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
9393     if (TARGET_THUMB2) {
9394       output_asm_insn (ite[swap], operands);
9395     }
9396     output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
9397     return \"\";
9398   }"
9399   [(set_attr "conds" "set")
9400    (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
9401    (set_attr "type" "multiple")
9402    (set_attr_alternative "length"
9403       [(const_int 6)
9404        (const_int 8)
9405        (const_int 8)
9406        (const_int 8)
9407        (const_int 8)
9408        (if_then_else (eq_attr "is_thumb" "no")
9409            (const_int 8)
9410            (const_int 10))
9411        (if_then_else (eq_attr "is_thumb" "no")
9412            (const_int 8)
9413            (const_int 10))
9414        (if_then_else (eq_attr "is_thumb" "no")
9415            (const_int 8)
9416            (const_int 10))
9417        (if_then_else (eq_attr "is_thumb" "no")
9418            (const_int 8)
9419            (const_int 10))])]
9422 (define_insn "*cmp_ite1"
9423   [(set (match_operand 6 "dominant_cc_register" "")
9424         (compare
9425          (if_then_else:SI
9426           (match_operator 4 "arm_comparison_operator"
9427            [(match_operand:SI 0 "s_register_operand"
9428                 "l,l,l,r,r,r,r,r,r")
9429             (match_operand:SI 1 "arm_add_operand"
9430                 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
9431           (match_operator:SI 5 "arm_comparison_operator"
9432            [(match_operand:SI 2 "s_register_operand"
9433                 "l,r,r,l,l,r,r,r,r")
9434             (match_operand:SI 3 "arm_add_operand"
9435                 "lPy,rI,L,lPy,lPy,rI,rI,L,L")])
9436           (const_int 1))
9437          (const_int 0)))]
9438   "TARGET_32BIT"
9439   "*
9440   {
9441     static const char * const cmp1[NUM_OF_COND_CMP][2] =
9442     {
9443       {\"cmp\\t%0, %1\",
9444        \"cmp\\t%2, %3\"},
9445       {\"cmn\\t%0, #%n1\",
9446        \"cmp\\t%2, %3\"},
9447       {\"cmp\\t%0, %1\",
9448        \"cmn\\t%2, #%n3\"},
9449       {\"cmn\\t%0, #%n1\",
9450        \"cmn\\t%2, #%n3\"}
9451     };
9452     static const char * const cmp2[NUM_OF_COND_CMP][2] =
9453     {
9454       {\"cmp%d4\\t%2, %3\",
9455        \"cmp%D5\\t%0, %1\"},
9456       {\"cmp%d4\\t%2, %3\",
9457        \"cmn%D5\\t%0, #%n1\"},
9458       {\"cmn%d4\\t%2, #%n3\",
9459        \"cmp%D5\\t%0, %1\"},
9460       {\"cmn%d4\\t%2, #%n3\",
9461        \"cmn%D5\\t%0, #%n1\"}
9462     };
9463     static const char * const ite[2] =
9464     {
9465       \"it\\t%d4\",
9466       \"it\\t%D5\"
9467     };
9468     static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
9469                                    CMP_CMP, CMN_CMP, CMP_CMP,
9470                                    CMN_CMP, CMP_CMN, CMN_CMN};
9471     int swap =
9472       comparison_dominates_p (GET_CODE (operands[5]),
9473                               reverse_condition (GET_CODE (operands[4])));
9475     output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
9476     if (TARGET_THUMB2) {
9477       output_asm_insn (ite[swap], operands);
9478     }
9479     output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
9480     return \"\";
9481   }"
9482   [(set_attr "conds" "set")
9483    (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
9484    (set_attr_alternative "length"
9485       [(const_int 6)
9486        (const_int 8)
9487        (const_int 8)
9488        (const_int 8)
9489        (const_int 8)
9490        (if_then_else (eq_attr "is_thumb" "no")
9491            (const_int 8)
9492            (const_int 10))
9493        (if_then_else (eq_attr "is_thumb" "no")
9494            (const_int 8)
9495            (const_int 10))
9496        (if_then_else (eq_attr "is_thumb" "no")
9497            (const_int 8)
9498            (const_int 10))
9499        (if_then_else (eq_attr "is_thumb" "no")
9500            (const_int 8)
9501            (const_int 10))])
9502    (set_attr "type" "multiple")]
9505 (define_insn "*cmp_and"
9506   [(set (match_operand 6 "dominant_cc_register" "")
9507         (compare
9508          (and:SI
9509           (match_operator 4 "arm_comparison_operator"
9510            [(match_operand:SI 0 "s_register_operand" 
9511                 "l,l,l,r,r,r,r,r,r")
9512             (match_operand:SI 1 "arm_add_operand" 
9513                 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
9514           (match_operator:SI 5 "arm_comparison_operator"
9515            [(match_operand:SI 2 "s_register_operand" 
9516                 "l,r,r,l,l,r,r,r,r")
9517             (match_operand:SI 3 "arm_add_operand" 
9518                 "lPy,rI,L,lPy,lPy,rI,rI,L,L")]))
9519          (const_int 0)))]
9520   "TARGET_32BIT"
9521   "*
9522   {
9523     static const char *const cmp1[NUM_OF_COND_CMP][2] =
9524     {
9525       {\"cmp%d5\\t%0, %1\",
9526        \"cmp%d4\\t%2, %3\"},
9527       {\"cmn%d5\\t%0, #%n1\",
9528        \"cmp%d4\\t%2, %3\"},
9529       {\"cmp%d5\\t%0, %1\",
9530        \"cmn%d4\\t%2, #%n3\"},
9531       {\"cmn%d5\\t%0, #%n1\",
9532        \"cmn%d4\\t%2, #%n3\"}
9533     };
9534     static const char *const cmp2[NUM_OF_COND_CMP][2] =
9535     {
9536       {\"cmp\\t%2, %3\",
9537        \"cmp\\t%0, %1\"},
9538       {\"cmp\\t%2, %3\",
9539        \"cmn\\t%0, #%n1\"},
9540       {\"cmn\\t%2, #%n3\",
9541        \"cmp\\t%0, %1\"},
9542       {\"cmn\\t%2, #%n3\",
9543        \"cmn\\t%0, #%n1\"}
9544     };
9545     static const char *const ite[2] =
9546     {
9547       \"it\\t%d5\",
9548       \"it\\t%d4\"
9549     };
9550     static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
9551                                    CMP_CMP, CMN_CMP, CMP_CMP,
9552                                    CMN_CMP, CMP_CMN, CMN_CMN};
9553     int swap =
9554       comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
9556     output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
9557     if (TARGET_THUMB2) {
9558       output_asm_insn (ite[swap], operands);
9559     }
9560     output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
9561     return \"\";
9562   }"
9563   [(set_attr "conds" "set")
9564    (set_attr "predicable" "no")
9565    (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
9566    (set_attr_alternative "length"
9567       [(const_int 6)
9568        (const_int 8)
9569        (const_int 8)
9570        (const_int 8)
9571        (const_int 8)
9572        (if_then_else (eq_attr "is_thumb" "no")
9573            (const_int 8)
9574            (const_int 10))
9575        (if_then_else (eq_attr "is_thumb" "no")
9576            (const_int 8)
9577            (const_int 10))
9578        (if_then_else (eq_attr "is_thumb" "no")
9579            (const_int 8)
9580            (const_int 10))
9581        (if_then_else (eq_attr "is_thumb" "no")
9582            (const_int 8)
9583            (const_int 10))])
9584    (set_attr "type" "multiple")]
9587 (define_insn "*cmp_ior"
9588   [(set (match_operand 6 "dominant_cc_register" "")
9589         (compare
9590          (ior:SI
9591           (match_operator 4 "arm_comparison_operator"
9592            [(match_operand:SI 0 "s_register_operand"
9593                 "l,l,l,r,r,r,r,r,r")
9594             (match_operand:SI 1 "arm_add_operand"
9595                 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
9596           (match_operator:SI 5 "arm_comparison_operator"
9597            [(match_operand:SI 2 "s_register_operand"
9598                 "l,r,r,l,l,r,r,r,r")
9599             (match_operand:SI 3 "arm_add_operand"
9600                 "lPy,rI,L,lPy,lPy,rI,rI,L,L")]))
9601          (const_int 0)))]
9602   "TARGET_32BIT"
9603   "*
9604   {
9605     static const char *const cmp1[NUM_OF_COND_CMP][2] =
9606     {
9607       {\"cmp\\t%0, %1\",
9608        \"cmp\\t%2, %3\"},
9609       {\"cmn\\t%0, #%n1\",
9610        \"cmp\\t%2, %3\"},
9611       {\"cmp\\t%0, %1\",
9612        \"cmn\\t%2, #%n3\"},
9613       {\"cmn\\t%0, #%n1\",
9614        \"cmn\\t%2, #%n3\"}
9615     };
9616     static const char *const cmp2[NUM_OF_COND_CMP][2] =
9617     {
9618       {\"cmp%D4\\t%2, %3\",
9619        \"cmp%D5\\t%0, %1\"},
9620       {\"cmp%D4\\t%2, %3\",
9621        \"cmn%D5\\t%0, #%n1\"},
9622       {\"cmn%D4\\t%2, #%n3\",
9623        \"cmp%D5\\t%0, %1\"},
9624       {\"cmn%D4\\t%2, #%n3\",
9625        \"cmn%D5\\t%0, #%n1\"}
9626     };
9627     static const char *const ite[2] =
9628     {
9629       \"it\\t%D4\",
9630       \"it\\t%D5\"
9631     };
9632     static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
9633                                    CMP_CMP, CMN_CMP, CMP_CMP,
9634                                    CMN_CMP, CMP_CMN, CMN_CMN};
9635     int swap =
9636       comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
9638     output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
9639     if (TARGET_THUMB2) {
9640       output_asm_insn (ite[swap], operands);
9641     }
9642     output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
9643     return \"\";
9644   }
9645   "
9646   [(set_attr "conds" "set")
9647    (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
9648    (set_attr_alternative "length"
9649       [(const_int 6)
9650        (const_int 8)
9651        (const_int 8)
9652        (const_int 8)
9653        (const_int 8)
9654        (if_then_else (eq_attr "is_thumb" "no")
9655            (const_int 8)
9656            (const_int 10))
9657        (if_then_else (eq_attr "is_thumb" "no")
9658            (const_int 8)
9659            (const_int 10))
9660        (if_then_else (eq_attr "is_thumb" "no")
9661            (const_int 8)
9662            (const_int 10))
9663        (if_then_else (eq_attr "is_thumb" "no")
9664            (const_int 8)
9665            (const_int 10))])
9666    (set_attr "type" "multiple")]
9669 (define_insn_and_split "*ior_scc_scc"
9670   [(set (match_operand:SI 0 "s_register_operand" "=Ts")
9671         (ior:SI (match_operator:SI 3 "arm_comparison_operator"
9672                  [(match_operand:SI 1 "s_register_operand" "r")
9673                   (match_operand:SI 2 "arm_add_operand" "rIL")])
9674                 (match_operator:SI 6 "arm_comparison_operator"
9675                  [(match_operand:SI 4 "s_register_operand" "r")
9676                   (match_operand:SI 5 "arm_add_operand" "rIL")])))
9677    (clobber (reg:CC CC_REGNUM))]
9678   "TARGET_32BIT
9679    && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_OR_Y)
9680        != CCmode)"
9681   "#"
9682   "TARGET_32BIT && reload_completed"
9683   [(set (match_dup 7)
9684         (compare
9685          (ior:SI
9686           (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9687           (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9688          (const_int 0)))
9689    (set (match_dup 0) (ne:SI (match_dup 7) (const_int 0)))]
9690   "operands[7]
9691      = gen_rtx_REG (arm_select_dominance_cc_mode (operands[3], operands[6],
9692                                                   DOM_CC_X_OR_Y),
9693                     CC_REGNUM);"
9694   [(set_attr "conds" "clob")
9695    (set_attr "length" "16")
9696    (set_attr "type" "multiple")]
9699 ; If the above pattern is followed by a CMP insn, then the compare is 
9700 ; redundant, since we can rework the conditional instruction that follows.
9701 (define_insn_and_split "*ior_scc_scc_cmp"
9702   [(set (match_operand 0 "dominant_cc_register" "")
9703         (compare (ior:SI (match_operator:SI 3 "arm_comparison_operator"
9704                           [(match_operand:SI 1 "s_register_operand" "r")
9705                            (match_operand:SI 2 "arm_add_operand" "rIL")])
9706                          (match_operator:SI 6 "arm_comparison_operator"
9707                           [(match_operand:SI 4 "s_register_operand" "r")
9708                            (match_operand:SI 5 "arm_add_operand" "rIL")]))
9709                  (const_int 0)))
9710    (set (match_operand:SI 7 "s_register_operand" "=Ts")
9711         (ior:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9712                 (match_op_dup 6 [(match_dup 4) (match_dup 5)])))]
9713   "TARGET_32BIT"
9714   "#"
9715   "TARGET_32BIT && reload_completed"
9716   [(set (match_dup 0)
9717         (compare
9718          (ior:SI
9719           (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9720           (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9721          (const_int 0)))
9722    (set (match_dup 7) (ne:SI (match_dup 0) (const_int 0)))]
9723   ""
9724   [(set_attr "conds" "set")
9725    (set_attr "length" "16")
9726    (set_attr "type" "multiple")]
9729 (define_insn_and_split "*and_scc_scc"
9730   [(set (match_operand:SI 0 "s_register_operand" "=Ts")
9731         (and:SI (match_operator:SI 3 "arm_comparison_operator"
9732                  [(match_operand:SI 1 "s_register_operand" "r")
9733                   (match_operand:SI 2 "arm_add_operand" "rIL")])
9734                 (match_operator:SI 6 "arm_comparison_operator"
9735                  [(match_operand:SI 4 "s_register_operand" "r")
9736                   (match_operand:SI 5 "arm_add_operand" "rIL")])))
9737    (clobber (reg:CC CC_REGNUM))]
9738   "TARGET_32BIT
9739    && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
9740        != CCmode)"
9741   "#"
9742   "TARGET_32BIT && reload_completed
9743    && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
9744        != CCmode)"
9745   [(set (match_dup 7)
9746         (compare
9747          (and:SI
9748           (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9749           (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9750          (const_int 0)))
9751    (set (match_dup 0) (ne:SI (match_dup 7) (const_int 0)))]
9752   "operands[7]
9753      = gen_rtx_REG (arm_select_dominance_cc_mode (operands[3], operands[6],
9754                                                   DOM_CC_X_AND_Y),
9755                     CC_REGNUM);"
9756   [(set_attr "conds" "clob")
9757    (set_attr "length" "16")
9758    (set_attr "type" "multiple")]
9761 ; If the above pattern is followed by a CMP insn, then the compare is 
9762 ; redundant, since we can rework the conditional instruction that follows.
9763 (define_insn_and_split "*and_scc_scc_cmp"
9764   [(set (match_operand 0 "dominant_cc_register" "")
9765         (compare (and:SI (match_operator:SI 3 "arm_comparison_operator"
9766                           [(match_operand:SI 1 "s_register_operand" "r")
9767                            (match_operand:SI 2 "arm_add_operand" "rIL")])
9768                          (match_operator:SI 6 "arm_comparison_operator"
9769                           [(match_operand:SI 4 "s_register_operand" "r")
9770                            (match_operand:SI 5 "arm_add_operand" "rIL")]))
9771                  (const_int 0)))
9772    (set (match_operand:SI 7 "s_register_operand" "=Ts")
9773         (and:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9774                 (match_op_dup 6 [(match_dup 4) (match_dup 5)])))]
9775   "TARGET_32BIT"
9776   "#"
9777   "TARGET_32BIT && reload_completed"
9778   [(set (match_dup 0)
9779         (compare
9780          (and:SI
9781           (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9782           (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9783          (const_int 0)))
9784    (set (match_dup 7) (ne:SI (match_dup 0) (const_int 0)))]
9785   ""
9786   [(set_attr "conds" "set")
9787    (set_attr "length" "16")
9788    (set_attr "type" "multiple")]
9791 ;; If there is no dominance in the comparison, then we can still save an
9792 ;; instruction in the AND case, since we can know that the second compare
9793 ;; need only zero the value if false (if true, then the value is already
9794 ;; correct).
9795 (define_insn_and_split "*and_scc_scc_nodom"
9796   [(set (match_operand:SI 0 "s_register_operand" "=&Ts,&Ts,&Ts")
9797         (and:SI (match_operator:SI 3 "arm_comparison_operator"
9798                  [(match_operand:SI 1 "s_register_operand" "r,r,0")
9799                   (match_operand:SI 2 "arm_add_operand" "rIL,0,rIL")])
9800                 (match_operator:SI 6 "arm_comparison_operator"
9801                  [(match_operand:SI 4 "s_register_operand" "r,r,r")
9802                   (match_operand:SI 5 "arm_add_operand" "rIL,rIL,rIL")])))
9803    (clobber (reg:CC CC_REGNUM))]
9804   "TARGET_32BIT
9805    && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
9806        == CCmode)"
9807   "#"
9808   "TARGET_32BIT && reload_completed"
9809   [(parallel [(set (match_dup 0)
9810                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
9811               (clobber (reg:CC CC_REGNUM))])
9812    (set (match_dup 7) (match_op_dup 8 [(match_dup 4) (match_dup 5)]))
9813    (set (match_dup 0)
9814         (if_then_else:SI (match_op_dup 6 [(match_dup 7) (const_int 0)])
9815                          (match_dup 0)
9816                          (const_int 0)))]
9817   "operands[7] = gen_rtx_REG (SELECT_CC_MODE (GET_CODE (operands[6]),
9818                                               operands[4], operands[5]),
9819                               CC_REGNUM);
9820    operands[8] = gen_rtx_COMPARE (GET_MODE (operands[7]), operands[4],
9821                                   operands[5]);"
9822   [(set_attr "conds" "clob")
9823    (set_attr "length" "20")
9824    (set_attr "type" "multiple")]
9827 (define_split
9828   [(set (reg:CC_NOOV CC_REGNUM)
9829         (compare:CC_NOOV (ior:SI
9830                           (and:SI (match_operand:SI 0 "s_register_operand" "")
9831                                   (const_int 1))
9832                           (match_operator:SI 1 "arm_comparison_operator"
9833                            [(match_operand:SI 2 "s_register_operand" "")
9834                             (match_operand:SI 3 "arm_add_operand" "")]))
9835                          (const_int 0)))
9836    (clobber (match_operand:SI 4 "s_register_operand" ""))]
9837   "TARGET_ARM"
9838   [(set (match_dup 4)
9839         (ior:SI (match_op_dup 1 [(match_dup 2) (match_dup 3)])
9840                 (match_dup 0)))
9841    (set (reg:CC_NOOV CC_REGNUM)
9842         (compare:CC_NOOV (and:SI (match_dup 4) (const_int 1))
9843                          (const_int 0)))]
9844   "")
9846 (define_split
9847   [(set (reg:CC_NOOV CC_REGNUM)
9848         (compare:CC_NOOV (ior:SI
9849                           (match_operator:SI 1 "arm_comparison_operator"
9850                            [(match_operand:SI 2 "s_register_operand" "")
9851                             (match_operand:SI 3 "arm_add_operand" "")])
9852                           (and:SI (match_operand:SI 0 "s_register_operand" "")
9853                                   (const_int 1)))
9854                          (const_int 0)))
9855    (clobber (match_operand:SI 4 "s_register_operand" ""))]
9856   "TARGET_ARM"
9857   [(set (match_dup 4)
9858         (ior:SI (match_op_dup 1 [(match_dup 2) (match_dup 3)])
9859                 (match_dup 0)))
9860    (set (reg:CC_NOOV CC_REGNUM)
9861         (compare:CC_NOOV (and:SI (match_dup 4) (const_int 1))
9862                          (const_int 0)))]
9863   "")
9864 ;; ??? The conditional patterns above need checking for Thumb-2 usefulness
9866 (define_insn_and_split "*negscc"
9867   [(set (match_operand:SI 0 "s_register_operand" "=r")
9868         (neg:SI (match_operator 3 "arm_comparison_operator"
9869                  [(match_operand:SI 1 "s_register_operand" "r")
9870                   (match_operand:SI 2 "arm_rhs_operand" "rI")])))
9871    (clobber (reg:CC CC_REGNUM))]
9872   "TARGET_ARM"
9873   "#"
9874   "&& reload_completed"
9875   [(const_int 0)]
9876   {
9877     rtx cc_reg = gen_rtx_REG (CCmode, CC_REGNUM);
9879     if (GET_CODE (operands[3]) == LT && operands[2] == const0_rtx)
9880        {
9881          /* Emit mov\\t%0, %1, asr #31 */
9882          emit_insn (gen_rtx_SET (operands[0],
9883                                  gen_rtx_ASHIFTRT (SImode,
9884                                                    operands[1],
9885                                                    GEN_INT (31))));
9886          DONE;
9887        }
9888      else if (GET_CODE (operands[3]) == NE)
9889        {
9890         /* Emit subs\\t%0, %1, %2\;mvnne\\t%0, #0 */
9891         if (CONST_INT_P (operands[2]))
9892           emit_insn (gen_cmpsi2_addneg (operands[0], operands[1], operands[2],
9893                                         GEN_INT (- INTVAL (operands[2]))));
9894         else
9895           emit_insn (gen_subsi3_compare (operands[0], operands[1], operands[2]));
9897         emit_insn (gen_rtx_COND_EXEC (VOIDmode,
9898                                       gen_rtx_NE (SImode,
9899                                                   cc_reg,
9900                                                   const0_rtx),
9901                                       gen_rtx_SET (operands[0],
9902                                                    GEN_INT (~0))));
9903         DONE;
9904       }
9905     else
9906       {
9907         /* Emit: cmp\\t%1, %2\;mov%D3\\t%0, #0\;mvn%d3\\t%0, #0 */
9908         emit_insn (gen_rtx_SET (cc_reg,
9909                                 gen_rtx_COMPARE (CCmode, operands[1], operands[2])));
9910         enum rtx_code rc = GET_CODE (operands[3]);
9912         rc = reverse_condition (rc);
9913         emit_insn (gen_rtx_COND_EXEC (VOIDmode,
9914                                       gen_rtx_fmt_ee (rc,
9915                                                       VOIDmode,
9916                                                       cc_reg,
9917                                                       const0_rtx),
9918                                       gen_rtx_SET (operands[0], const0_rtx)));
9919         rc = GET_CODE (operands[3]);
9920         emit_insn (gen_rtx_COND_EXEC (VOIDmode,
9921                                       gen_rtx_fmt_ee (rc,
9922                                                       VOIDmode,
9923                                                       cc_reg,
9924                                                       const0_rtx),
9925                                       gen_rtx_SET (operands[0],
9926                                                    GEN_INT (~0))));
9927         DONE;
9928       }
9929      FAIL;
9930   }
9931   [(set_attr "conds" "clob")
9932    (set_attr "length" "12")
9933    (set_attr "type" "multiple")]
9936 (define_insn_and_split "movcond_addsi"
9937   [(set (match_operand:SI 0 "s_register_operand" "=r,l,r")
9938         (if_then_else:SI
9939          (match_operator 5 "comparison_operator"
9940           [(plus:SI (match_operand:SI 3 "s_register_operand" "r,r,r")
9941                     (match_operand:SI 4 "arm_add_operand" "rIL,rIL,rIL"))
9942             (const_int 0)])
9943          (match_operand:SI 1 "arm_rhs_operand" "rI,rPy,r")
9944          (match_operand:SI 2 "arm_rhs_operand" "rI,rPy,r")))
9945    (clobber (reg:CC CC_REGNUM))]
9946    "TARGET_32BIT"
9947    "#"
9948    "&& reload_completed"
9949   [(set (reg:CC_NOOV CC_REGNUM)
9950         (compare:CC_NOOV
9951          (plus:SI (match_dup 3)
9952                   (match_dup 4))
9953          (const_int 0)))
9954    (set (match_dup 0) (match_dup 1))
9955    (cond_exec (match_dup 6)
9956               (set (match_dup 0) (match_dup 2)))]
9957   "
9958   {
9959     machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[5]),
9960                                              operands[3], operands[4]);
9961     enum rtx_code rc = GET_CODE (operands[5]);
9962     operands[6] = gen_rtx_REG (mode, CC_REGNUM);
9963     gcc_assert (!(mode == CCFPmode || mode == CCFPEmode));
9964     if (!REG_P (operands[2]) || REGNO (operands[2]) != REGNO (operands[0]))
9965       rc = reverse_condition (rc);
9966     else
9967       std::swap (operands[1], operands[2]);
9969     operands[6] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
9970   }
9971   "
9972   [(set_attr "conds" "clob")
9973    (set_attr "enabled_for_depr_it" "no,yes,yes")
9974    (set_attr "type" "multiple")]
9977 (define_insn "movcond"
9978   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9979         (if_then_else:SI
9980          (match_operator 5 "arm_comparison_operator"
9981           [(match_operand:SI 3 "s_register_operand" "r,r,r")
9982            (match_operand:SI 4 "arm_add_operand" "rIL,rIL,rIL")])
9983          (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
9984          (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
9985    (clobber (reg:CC CC_REGNUM))]
9986   "TARGET_ARM"
9987   "*
9988   if (GET_CODE (operands[5]) == LT
9989       && (operands[4] == const0_rtx))
9990     {
9991       if (which_alternative != 1 && REG_P (operands[1]))
9992         {
9993           if (operands[2] == const0_rtx)
9994             return \"and\\t%0, %1, %3, asr #31\";
9995           return \"ands\\t%0, %1, %3, asr #32\;movcc\\t%0, %2\";
9996         }
9997       else if (which_alternative != 0 && REG_P (operands[2]))
9998         {
9999           if (operands[1] == const0_rtx)
10000             return \"bic\\t%0, %2, %3, asr #31\";
10001           return \"bics\\t%0, %2, %3, asr #32\;movcs\\t%0, %1\";
10002         }
10003       /* The only case that falls through to here is when both ops 1 & 2
10004          are constants.  */
10005     }
10007   if (GET_CODE (operands[5]) == GE
10008       && (operands[4] == const0_rtx))
10009     {
10010       if (which_alternative != 1 && REG_P (operands[1]))
10011         {
10012           if (operands[2] == const0_rtx)
10013             return \"bic\\t%0, %1, %3, asr #31\";
10014           return \"bics\\t%0, %1, %3, asr #32\;movcs\\t%0, %2\";
10015         }
10016       else if (which_alternative != 0 && REG_P (operands[2]))
10017         {
10018           if (operands[1] == const0_rtx)
10019             return \"and\\t%0, %2, %3, asr #31\";
10020           return \"ands\\t%0, %2, %3, asr #32\;movcc\\t%0, %1\";
10021         }
10022       /* The only case that falls through to here is when both ops 1 & 2
10023          are constants.  */
10024     }
10025   if (CONST_INT_P (operands[4])
10026       && !const_ok_for_arm (INTVAL (operands[4])))
10027     output_asm_insn (\"cmn\\t%3, #%n4\", operands);
10028   else
10029     output_asm_insn (\"cmp\\t%3, %4\", operands);
10030   if (which_alternative != 0)
10031     output_asm_insn (\"mov%d5\\t%0, %1\", operands);
10032   if (which_alternative != 1)
10033     output_asm_insn (\"mov%D5\\t%0, %2\", operands);
10034   return \"\";
10035   "
10036   [(set_attr "conds" "clob")
10037    (set_attr "length" "8,8,12")
10038    (set_attr "type" "multiple")]
10041 ;; ??? The patterns below need checking for Thumb-2 usefulness.
10043 (define_insn "*ifcompare_plus_move"
10044   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10045         (if_then_else:SI (match_operator 6 "arm_comparison_operator"
10046                           [(match_operand:SI 4 "s_register_operand" "r,r")
10047                            (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
10048                          (plus:SI
10049                           (match_operand:SI 2 "s_register_operand" "r,r")
10050                           (match_operand:SI 3 "arm_add_operand" "rIL,rIL"))
10051                          (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))
10052    (clobber (reg:CC CC_REGNUM))]
10053   "TARGET_ARM"
10054   "#"
10055   [(set_attr "conds" "clob")
10056    (set_attr "length" "8,12")
10057    (set_attr "type" "multiple")]
10060 (define_insn "*if_plus_move"
10061   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
10062         (if_then_else:SI
10063          (match_operator 4 "arm_comparison_operator"
10064           [(match_operand 5 "cc_register" "") (const_int 0)])
10065          (plus:SI
10066           (match_operand:SI 2 "s_register_operand" "r,r,r,r")
10067           (match_operand:SI 3 "arm_add_operand" "rI,L,rI,L"))
10068          (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")))]
10069   "TARGET_ARM"
10070   "@
10071    add%d4\\t%0, %2, %3
10072    sub%d4\\t%0, %2, #%n3
10073    add%d4\\t%0, %2, %3\;mov%D4\\t%0, %1
10074    sub%d4\\t%0, %2, #%n3\;mov%D4\\t%0, %1"
10075   [(set_attr "conds" "use")
10076    (set_attr "length" "4,4,8,8")
10077    (set_attr_alternative "type"
10078                          [(if_then_else (match_operand 3 "const_int_operand" "")
10079                                         (const_string "alu_imm" )
10080                                         (const_string "alu_sreg"))
10081                           (const_string "alu_imm")
10082                           (const_string "multiple")
10083                           (const_string "multiple")])]
10086 (define_insn "*ifcompare_move_plus"
10087   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10088         (if_then_else:SI (match_operator 6 "arm_comparison_operator"
10089                           [(match_operand:SI 4 "s_register_operand" "r,r")
10090                            (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
10091                          (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
10092                          (plus:SI
10093                           (match_operand:SI 2 "s_register_operand" "r,r")
10094                           (match_operand:SI 3 "arm_add_operand" "rIL,rIL"))))
10095    (clobber (reg:CC CC_REGNUM))]
10096   "TARGET_ARM"
10097   "#"
10098   [(set_attr "conds" "clob")
10099    (set_attr "length" "8,12")
10100    (set_attr "type" "multiple")]
10103 (define_insn "*if_move_plus"
10104   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
10105         (if_then_else:SI
10106          (match_operator 4 "arm_comparison_operator"
10107           [(match_operand 5 "cc_register" "") (const_int 0)])
10108          (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")
10109          (plus:SI
10110           (match_operand:SI 2 "s_register_operand" "r,r,r,r")
10111           (match_operand:SI 3 "arm_add_operand" "rI,L,rI,L"))))]
10112   "TARGET_ARM"
10113   "@
10114    add%D4\\t%0, %2, %3
10115    sub%D4\\t%0, %2, #%n3
10116    add%D4\\t%0, %2, %3\;mov%d4\\t%0, %1
10117    sub%D4\\t%0, %2, #%n3\;mov%d4\\t%0, %1"
10118   [(set_attr "conds" "use")
10119    (set_attr "length" "4,4,8,8")
10120    (set_attr_alternative "type"
10121                          [(if_then_else (match_operand 3 "const_int_operand" "")
10122                                         (const_string "alu_imm" )
10123                                         (const_string "alu_sreg"))
10124                           (const_string "alu_imm")
10125                           (const_string "multiple")
10126                           (const_string "multiple")])]
10129 (define_insn "*ifcompare_arith_arith"
10130   [(set (match_operand:SI 0 "s_register_operand" "=r")
10131         (if_then_else:SI (match_operator 9 "arm_comparison_operator"
10132                           [(match_operand:SI 5 "s_register_operand" "r")
10133                            (match_operand:SI 6 "arm_add_operand" "rIL")])
10134                          (match_operator:SI 8 "shiftable_operator"
10135                           [(match_operand:SI 1 "s_register_operand" "r")
10136                            (match_operand:SI 2 "arm_rhs_operand" "rI")])
10137                          (match_operator:SI 7 "shiftable_operator"
10138                           [(match_operand:SI 3 "s_register_operand" "r")
10139                            (match_operand:SI 4 "arm_rhs_operand" "rI")])))
10140    (clobber (reg:CC CC_REGNUM))]
10141   "TARGET_ARM"
10142   "#"
10143   [(set_attr "conds" "clob")
10144    (set_attr "length" "12")
10145    (set_attr "type" "multiple")]
10148 (define_insn "*if_arith_arith"
10149   [(set (match_operand:SI 0 "s_register_operand" "=r")
10150         (if_then_else:SI (match_operator 5 "arm_comparison_operator"
10151                           [(match_operand 8 "cc_register" "") (const_int 0)])
10152                          (match_operator:SI 6 "shiftable_operator"
10153                           [(match_operand:SI 1 "s_register_operand" "r")
10154                            (match_operand:SI 2 "arm_rhs_operand" "rI")])
10155                          (match_operator:SI 7 "shiftable_operator"
10156                           [(match_operand:SI 3 "s_register_operand" "r")
10157                            (match_operand:SI 4 "arm_rhs_operand" "rI")])))]
10158   "TARGET_ARM"
10159   "%I6%d5\\t%0, %1, %2\;%I7%D5\\t%0, %3, %4"
10160   [(set_attr "conds" "use")
10161    (set_attr "length" "8")
10162    (set_attr "type" "multiple")]
10165 (define_insn "*ifcompare_arith_move"
10166   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10167         (if_then_else:SI (match_operator 6 "arm_comparison_operator"
10168                           [(match_operand:SI 2 "s_register_operand" "r,r")
10169                            (match_operand:SI 3 "arm_add_operand" "rIL,rIL")])
10170                          (match_operator:SI 7 "shiftable_operator"
10171                           [(match_operand:SI 4 "s_register_operand" "r,r")
10172                            (match_operand:SI 5 "arm_rhs_operand" "rI,rI")])
10173                          (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))
10174    (clobber (reg:CC CC_REGNUM))]
10175   "TARGET_ARM"
10176   "*
10177   /* If we have an operation where (op x 0) is the identity operation and
10178      the conditional operator is LT or GE and we are comparing against zero and
10179      everything is in registers then we can do this in two instructions.  */
10180   if (operands[3] == const0_rtx
10181       && GET_CODE (operands[7]) != AND
10182       && REG_P (operands[5])
10183       && REG_P (operands[1])
10184       && REGNO (operands[1]) == REGNO (operands[4])
10185       && REGNO (operands[4]) != REGNO (operands[0]))
10186     {
10187       if (GET_CODE (operands[6]) == LT)
10188         return \"and\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\";
10189       else if (GET_CODE (operands[6]) == GE)
10190         return \"bic\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\";
10191     }
10192   if (CONST_INT_P (operands[3])
10193       && !const_ok_for_arm (INTVAL (operands[3])))
10194     output_asm_insn (\"cmn\\t%2, #%n3\", operands);
10195   else
10196     output_asm_insn (\"cmp\\t%2, %3\", operands);
10197   output_asm_insn (\"%I7%d6\\t%0, %4, %5\", operands);
10198   if (which_alternative != 0)
10199     return \"mov%D6\\t%0, %1\";
10200   return \"\";
10201   "
10202   [(set_attr "conds" "clob")
10203    (set_attr "length" "8,12")
10204    (set_attr "type" "multiple")]
10207 (define_insn "*if_arith_move"
10208   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10209         (if_then_else:SI (match_operator 4 "arm_comparison_operator"
10210                           [(match_operand 6 "cc_register" "") (const_int 0)])
10211                          (match_operator:SI 5 "shiftable_operator"
10212                           [(match_operand:SI 2 "s_register_operand" "r,r")
10213                            (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
10214                          (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))]
10215   "TARGET_ARM"
10216   "@
10217    %I5%d4\\t%0, %2, %3
10218    %I5%d4\\t%0, %2, %3\;mov%D4\\t%0, %1"
10219   [(set_attr "conds" "use")
10220    (set_attr "length" "4,8")
10221    (set_attr_alternative "type"
10222                          [(if_then_else (match_operand 3 "const_int_operand" "")
10223                                         (const_string "alu_shift_imm" )
10224                                         (const_string "alu_shift_reg"))
10225                           (const_string "multiple")])]
10228 (define_insn "*ifcompare_move_arith"
10229   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10230         (if_then_else:SI (match_operator 6 "arm_comparison_operator"
10231                           [(match_operand:SI 4 "s_register_operand" "r,r")
10232                            (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
10233                          (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
10234                          (match_operator:SI 7 "shiftable_operator"
10235                           [(match_operand:SI 2 "s_register_operand" "r,r")
10236                            (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
10237    (clobber (reg:CC CC_REGNUM))]
10238   "TARGET_ARM"
10239   "*
10240   /* If we have an operation where (op x 0) is the identity operation and
10241      the conditional operator is LT or GE and we are comparing against zero and
10242      everything is in registers then we can do this in two instructions */
10243   if (operands[5] == const0_rtx
10244       && GET_CODE (operands[7]) != AND
10245       && REG_P (operands[3])
10246       && REG_P (operands[1])
10247       && REGNO (operands[1]) == REGNO (operands[2])
10248       && REGNO (operands[2]) != REGNO (operands[0]))
10249     {
10250       if (GET_CODE (operands[6]) == GE)
10251         return \"and\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\";
10252       else if (GET_CODE (operands[6]) == LT)
10253         return \"bic\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\";
10254     }
10256   if (CONST_INT_P (operands[5])
10257       && !const_ok_for_arm (INTVAL (operands[5])))
10258     output_asm_insn (\"cmn\\t%4, #%n5\", operands);
10259   else
10260     output_asm_insn (\"cmp\\t%4, %5\", operands);
10262   if (which_alternative != 0)
10263     output_asm_insn (\"mov%d6\\t%0, %1\", operands);
10264   return \"%I7%D6\\t%0, %2, %3\";
10265   "
10266   [(set_attr "conds" "clob")
10267    (set_attr "length" "8,12")
10268    (set_attr "type" "multiple")]
10271 (define_insn "*if_move_arith"
10272   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10273         (if_then_else:SI
10274          (match_operator 4 "arm_comparison_operator"
10275           [(match_operand 6 "cc_register" "") (const_int 0)])
10276          (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
10277          (match_operator:SI 5 "shiftable_operator"
10278           [(match_operand:SI 2 "s_register_operand" "r,r")
10279            (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))]
10280   "TARGET_ARM"
10281   "@
10282    %I5%D4\\t%0, %2, %3
10283    %I5%D4\\t%0, %2, %3\;mov%d4\\t%0, %1"
10284   [(set_attr "conds" "use")
10285    (set_attr "length" "4,8")
10286    (set_attr_alternative "type"
10287                          [(if_then_else (match_operand 3 "const_int_operand" "")
10288                                         (const_string "alu_shift_imm" )
10289                                         (const_string "alu_shift_reg"))
10290                           (const_string "multiple")])]
10293 (define_insn "*ifcompare_move_not"
10294   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10295         (if_then_else:SI
10296          (match_operator 5 "arm_comparison_operator"
10297           [(match_operand:SI 3 "s_register_operand" "r,r")
10298            (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
10299          (match_operand:SI 1 "arm_not_operand" "0,?rIK")
10300          (not:SI
10301           (match_operand:SI 2 "s_register_operand" "r,r"))))
10302    (clobber (reg:CC CC_REGNUM))]
10303   "TARGET_ARM"
10304   "#"
10305   [(set_attr "conds" "clob")
10306    (set_attr "length" "8,12")
10307    (set_attr "type" "multiple")]
10310 (define_insn "*if_move_not"
10311   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
10312         (if_then_else:SI
10313          (match_operator 4 "arm_comparison_operator"
10314           [(match_operand 3 "cc_register" "") (const_int 0)])
10315          (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
10316          (not:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))))]
10317   "TARGET_ARM"
10318   "@
10319    mvn%D4\\t%0, %2
10320    mov%d4\\t%0, %1\;mvn%D4\\t%0, %2
10321    mvn%d4\\t%0, #%B1\;mvn%D4\\t%0, %2"
10322   [(set_attr "conds" "use")
10323    (set_attr "type" "mvn_reg")
10324    (set_attr "length" "4,8,8")
10325    (set_attr "type" "mvn_reg,multiple,multiple")]
10328 (define_insn "*ifcompare_not_move"
10329   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10330         (if_then_else:SI 
10331          (match_operator 5 "arm_comparison_operator"
10332           [(match_operand:SI 3 "s_register_operand" "r,r")
10333            (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
10334          (not:SI
10335           (match_operand:SI 2 "s_register_operand" "r,r"))
10336          (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
10337    (clobber (reg:CC CC_REGNUM))]
10338   "TARGET_ARM"
10339   "#"
10340   [(set_attr "conds" "clob")
10341    (set_attr "length" "8,12")
10342    (set_attr "type" "multiple")]
10345 (define_insn "*if_not_move"
10346   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
10347         (if_then_else:SI
10348          (match_operator 4 "arm_comparison_operator"
10349           [(match_operand 3 "cc_register" "") (const_int 0)])
10350          (not:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))
10351          (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
10352   "TARGET_ARM"
10353   "@
10354    mvn%d4\\t%0, %2
10355    mov%D4\\t%0, %1\;mvn%d4\\t%0, %2
10356    mvn%D4\\t%0, #%B1\;mvn%d4\\t%0, %2"
10357   [(set_attr "conds" "use")
10358    (set_attr "type" "mvn_reg,multiple,multiple")
10359    (set_attr "length" "4,8,8")]
10362 (define_insn "*ifcompare_shift_move"
10363   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10364         (if_then_else:SI
10365          (match_operator 6 "arm_comparison_operator"
10366           [(match_operand:SI 4 "s_register_operand" "r,r")
10367            (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
10368          (match_operator:SI 7 "shift_operator"
10369           [(match_operand:SI 2 "s_register_operand" "r,r")
10370            (match_operand:SI 3 "arm_rhs_operand" "rM,rM")])
10371          (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
10372    (clobber (reg:CC CC_REGNUM))]
10373   "TARGET_ARM"
10374   "#"
10375   [(set_attr "conds" "clob")
10376    (set_attr "length" "8,12")
10377    (set_attr "type" "multiple")]
10380 (define_insn "*if_shift_move"
10381   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
10382         (if_then_else:SI
10383          (match_operator 5 "arm_comparison_operator"
10384           [(match_operand 6 "cc_register" "") (const_int 0)])
10385          (match_operator:SI 4 "shift_operator"
10386           [(match_operand:SI 2 "s_register_operand" "r,r,r")
10387            (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM")])
10388          (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
10389   "TARGET_ARM"
10390   "@
10391    mov%d5\\t%0, %2%S4
10392    mov%D5\\t%0, %1\;mov%d5\\t%0, %2%S4
10393    mvn%D5\\t%0, #%B1\;mov%d5\\t%0, %2%S4"
10394   [(set_attr "conds" "use")
10395    (set_attr "shift" "2")
10396    (set_attr "length" "4,8,8")
10397    (set_attr_alternative "type"
10398                          [(if_then_else (match_operand 3 "const_int_operand" "")
10399                                         (const_string "mov_shift" )
10400                                         (const_string "mov_shift_reg"))
10401                           (const_string "multiple")
10402                           (const_string "multiple")])]
10405 (define_insn "*ifcompare_move_shift"
10406   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10407         (if_then_else:SI
10408          (match_operator 6 "arm_comparison_operator"
10409           [(match_operand:SI 4 "s_register_operand" "r,r")
10410            (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
10411          (match_operand:SI 1 "arm_not_operand" "0,?rIK")
10412          (match_operator:SI 7 "shift_operator"
10413           [(match_operand:SI 2 "s_register_operand" "r,r")
10414            (match_operand:SI 3 "arm_rhs_operand" "rM,rM")])))
10415    (clobber (reg:CC CC_REGNUM))]
10416   "TARGET_ARM"
10417   "#"
10418   [(set_attr "conds" "clob")
10419    (set_attr "length" "8,12")
10420    (set_attr "type" "multiple")]
10423 (define_insn "*if_move_shift"
10424   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
10425         (if_then_else:SI
10426          (match_operator 5 "arm_comparison_operator"
10427           [(match_operand 6 "cc_register" "") (const_int 0)])
10428          (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
10429          (match_operator:SI 4 "shift_operator"
10430           [(match_operand:SI 2 "s_register_operand" "r,r,r")
10431            (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM")])))]
10432   "TARGET_ARM"
10433   "@
10434    mov%D5\\t%0, %2%S4
10435    mov%d5\\t%0, %1\;mov%D5\\t%0, %2%S4
10436    mvn%d5\\t%0, #%B1\;mov%D5\\t%0, %2%S4"
10437   [(set_attr "conds" "use")
10438    (set_attr "shift" "2")
10439    (set_attr "length" "4,8,8")
10440    (set_attr_alternative "type"
10441                          [(if_then_else (match_operand 3 "const_int_operand" "")
10442                                         (const_string "mov_shift" )
10443                                         (const_string "mov_shift_reg"))
10444                           (const_string "multiple")
10445                           (const_string "multiple")])]
10448 (define_insn "*ifcompare_shift_shift"
10449   [(set (match_operand:SI 0 "s_register_operand" "=r")
10450         (if_then_else:SI
10451          (match_operator 7 "arm_comparison_operator"
10452           [(match_operand:SI 5 "s_register_operand" "r")
10453            (match_operand:SI 6 "arm_add_operand" "rIL")])
10454          (match_operator:SI 8 "shift_operator"
10455           [(match_operand:SI 1 "s_register_operand" "r")
10456            (match_operand:SI 2 "arm_rhs_operand" "rM")])
10457          (match_operator:SI 9 "shift_operator"
10458           [(match_operand:SI 3 "s_register_operand" "r")
10459            (match_operand:SI 4 "arm_rhs_operand" "rM")])))
10460    (clobber (reg:CC CC_REGNUM))]
10461   "TARGET_ARM"
10462   "#"
10463   [(set_attr "conds" "clob")
10464    (set_attr "length" "12")
10465    (set_attr "type" "multiple")]
10468 (define_insn "*if_shift_shift"
10469   [(set (match_operand:SI 0 "s_register_operand" "=r")
10470         (if_then_else:SI
10471          (match_operator 5 "arm_comparison_operator"
10472           [(match_operand 8 "cc_register" "") (const_int 0)])
10473          (match_operator:SI 6 "shift_operator"
10474           [(match_operand:SI 1 "s_register_operand" "r")
10475            (match_operand:SI 2 "arm_rhs_operand" "rM")])
10476          (match_operator:SI 7 "shift_operator"
10477           [(match_operand:SI 3 "s_register_operand" "r")
10478            (match_operand:SI 4 "arm_rhs_operand" "rM")])))]
10479   "TARGET_ARM"
10480   "mov%d5\\t%0, %1%S6\;mov%D5\\t%0, %3%S7"
10481   [(set_attr "conds" "use")
10482    (set_attr "shift" "1")
10483    (set_attr "length" "8")
10484    (set (attr "type") (if_then_else
10485                         (and (match_operand 2 "const_int_operand" "")
10486                              (match_operand 4 "const_int_operand" ""))
10487                       (const_string "mov_shift")
10488                       (const_string "mov_shift_reg")))]
10491 (define_insn "*ifcompare_not_arith"
10492   [(set (match_operand:SI 0 "s_register_operand" "=r")
10493         (if_then_else:SI
10494          (match_operator 6 "arm_comparison_operator"
10495           [(match_operand:SI 4 "s_register_operand" "r")
10496            (match_operand:SI 5 "arm_add_operand" "rIL")])
10497          (not:SI (match_operand:SI 1 "s_register_operand" "r"))
10498          (match_operator:SI 7 "shiftable_operator"
10499           [(match_operand:SI 2 "s_register_operand" "r")
10500            (match_operand:SI 3 "arm_rhs_operand" "rI")])))
10501    (clobber (reg:CC CC_REGNUM))]
10502   "TARGET_ARM"
10503   "#"
10504   [(set_attr "conds" "clob")
10505    (set_attr "length" "12")
10506    (set_attr "type" "multiple")]
10509 (define_insn "*if_not_arith"
10510   [(set (match_operand:SI 0 "s_register_operand" "=r")
10511         (if_then_else:SI
10512          (match_operator 5 "arm_comparison_operator"
10513           [(match_operand 4 "cc_register" "") (const_int 0)])
10514          (not:SI (match_operand:SI 1 "s_register_operand" "r"))
10515          (match_operator:SI 6 "shiftable_operator"
10516           [(match_operand:SI 2 "s_register_operand" "r")
10517            (match_operand:SI 3 "arm_rhs_operand" "rI")])))]
10518   "TARGET_ARM"
10519   "mvn%d5\\t%0, %1\;%I6%D5\\t%0, %2, %3"
10520   [(set_attr "conds" "use")
10521    (set_attr "type" "mvn_reg")
10522    (set_attr "length" "8")]
10525 (define_insn "*ifcompare_arith_not"
10526   [(set (match_operand:SI 0 "s_register_operand" "=r")
10527         (if_then_else:SI
10528          (match_operator 6 "arm_comparison_operator"
10529           [(match_operand:SI 4 "s_register_operand" "r")
10530            (match_operand:SI 5 "arm_add_operand" "rIL")])
10531          (match_operator:SI 7 "shiftable_operator"
10532           [(match_operand:SI 2 "s_register_operand" "r")
10533            (match_operand:SI 3 "arm_rhs_operand" "rI")])
10534          (not:SI (match_operand:SI 1 "s_register_operand" "r"))))
10535    (clobber (reg:CC CC_REGNUM))]
10536   "TARGET_ARM"
10537   "#"
10538   [(set_attr "conds" "clob")
10539    (set_attr "length" "12")
10540    (set_attr "type" "multiple")]
10543 (define_insn "*if_arith_not"
10544   [(set (match_operand:SI 0 "s_register_operand" "=r")
10545         (if_then_else:SI
10546          (match_operator 5 "arm_comparison_operator"
10547           [(match_operand 4 "cc_register" "") (const_int 0)])
10548          (match_operator:SI 6 "shiftable_operator"
10549           [(match_operand:SI 2 "s_register_operand" "r")
10550            (match_operand:SI 3 "arm_rhs_operand" "rI")])
10551          (not:SI (match_operand:SI 1 "s_register_operand" "r"))))]
10552   "TARGET_ARM"
10553   "mvn%D5\\t%0, %1\;%I6%d5\\t%0, %2, %3"
10554   [(set_attr "conds" "use")
10555    (set_attr "type" "multiple")
10556    (set_attr "length" "8")]
10559 (define_insn "*ifcompare_neg_move"
10560   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10561         (if_then_else:SI
10562          (match_operator 5 "arm_comparison_operator"
10563           [(match_operand:SI 3 "s_register_operand" "r,r")
10564            (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
10565          (neg:SI (match_operand:SI 2 "s_register_operand" "r,r"))
10566          (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
10567    (clobber (reg:CC CC_REGNUM))]
10568   "TARGET_ARM"
10569   "#"
10570   [(set_attr "conds" "clob")
10571    (set_attr "length" "8,12")
10572    (set_attr "type" "multiple")]
10575 (define_insn_and_split "*if_neg_move"
10576   [(set (match_operand:SI 0 "s_register_operand" "=l,r")
10577         (if_then_else:SI
10578          (match_operator 4 "arm_comparison_operator"
10579           [(match_operand 3 "cc_register" "") (const_int 0)])
10580          (neg:SI (match_operand:SI 2 "s_register_operand" "l,r"))
10581          (match_operand:SI 1 "s_register_operand" "0,0")))]
10582   "TARGET_32BIT"
10583   "#"
10584   "&& reload_completed"
10585   [(cond_exec (match_op_dup 4 [(match_dup 3) (const_int 0)])
10586               (set (match_dup 0) (neg:SI (match_dup 2))))]
10587   ""
10588   [(set_attr "conds" "use")
10589    (set_attr "length" "4")
10590    (set_attr "arch" "t2,32")
10591    (set_attr "enabled_for_depr_it" "yes,no")
10592    (set_attr "type" "logic_shift_imm")]
10595 (define_insn "*ifcompare_move_neg"
10596   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10597         (if_then_else:SI
10598          (match_operator 5 "arm_comparison_operator"
10599           [(match_operand:SI 3 "s_register_operand" "r,r")
10600            (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
10601          (match_operand:SI 1 "arm_not_operand" "0,?rIK")
10602          (neg:SI (match_operand:SI 2 "s_register_operand" "r,r"))))
10603    (clobber (reg:CC CC_REGNUM))]
10604   "TARGET_ARM"
10605   "#"
10606   [(set_attr "conds" "clob")
10607    (set_attr "length" "8,12")
10608    (set_attr "type" "multiple")]
10611 (define_insn_and_split "*if_move_neg"
10612   [(set (match_operand:SI 0 "s_register_operand" "=l,r")
10613         (if_then_else:SI
10614          (match_operator 4 "arm_comparison_operator"
10615           [(match_operand 3 "cc_register" "") (const_int 0)])
10616          (match_operand:SI 1 "s_register_operand" "0,0")
10617          (neg:SI (match_operand:SI 2 "s_register_operand" "l,r"))))]
10618   "TARGET_32BIT"
10619   "#"
10620   "&& reload_completed"
10621   [(cond_exec (match_dup 5)
10622               (set (match_dup 0) (neg:SI (match_dup 2))))]
10623   {
10624     machine_mode mode = GET_MODE (operands[3]);
10625     rtx_code rc = GET_CODE (operands[4]);
10627     if (mode == CCFPmode || mode == CCFPEmode)
10628       rc = reverse_condition_maybe_unordered (rc);
10629     else
10630       rc = reverse_condition (rc);
10632     operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[3], const0_rtx);
10633   }
10634   [(set_attr "conds" "use")
10635    (set_attr "length" "4")
10636    (set_attr "arch" "t2,32")
10637    (set_attr "enabled_for_depr_it" "yes,no")
10638    (set_attr "type" "logic_shift_imm")]
10641 (define_insn "*arith_adjacentmem"
10642   [(set (match_operand:SI 0 "s_register_operand" "=r")
10643         (match_operator:SI 1 "shiftable_operator"
10644          [(match_operand:SI 2 "memory_operand" "m")
10645           (match_operand:SI 3 "memory_operand" "m")]))
10646    (clobber (match_scratch:SI 4 "=r"))]
10647   "TARGET_ARM && adjacent_mem_locations (operands[2], operands[3])"
10648   "*
10649   {
10650     rtx ldm[3];
10651     rtx arith[4];
10652     rtx base_reg;
10653     HOST_WIDE_INT val1 = 0, val2 = 0;
10655     if (REGNO (operands[0]) > REGNO (operands[4]))
10656       {
10657         ldm[1] = operands[4];
10658         ldm[2] = operands[0];
10659       }
10660     else
10661       {
10662         ldm[1] = operands[0];
10663         ldm[2] = operands[4];
10664       }
10666     base_reg = XEXP (operands[2], 0);
10668     if (!REG_P (base_reg))
10669       {
10670         val1 = INTVAL (XEXP (base_reg, 1));
10671         base_reg = XEXP (base_reg, 0);
10672       }
10674     if (!REG_P (XEXP (operands[3], 0)))
10675       val2 = INTVAL (XEXP (XEXP (operands[3], 0), 1));
10677     arith[0] = operands[0];
10678     arith[3] = operands[1];
10680     if (val1 < val2)
10681       {
10682         arith[1] = ldm[1];
10683         arith[2] = ldm[2];
10684       }
10685     else
10686       {
10687         arith[1] = ldm[2];
10688         arith[2] = ldm[1];
10689       }
10691     ldm[0] = base_reg;
10692     if (val1 !=0 && val2 != 0)
10693       {
10694         rtx ops[3];
10696         if (val1 == 4 || val2 == 4)
10697           /* Other val must be 8, since we know they are adjacent and neither
10698              is zero.  */
10699           output_asm_insn (\"ldmib%?\\t%0, {%1, %2}\", ldm);
10700         else if (const_ok_for_arm (val1) || const_ok_for_arm (-val1))
10701           {
10702             ldm[0] = ops[0] = operands[4];
10703             ops[1] = base_reg;
10704             ops[2] = GEN_INT (val1);
10705             output_add_immediate (ops);
10706             if (val1 < val2)
10707               output_asm_insn (\"ldmia%?\\t%0, {%1, %2}\", ldm);
10708             else
10709               output_asm_insn (\"ldmda%?\\t%0, {%1, %2}\", ldm);
10710           }
10711         else
10712           {
10713             /* Offset is out of range for a single add, so use two ldr.  */
10714             ops[0] = ldm[1];
10715             ops[1] = base_reg;
10716             ops[2] = GEN_INT (val1);
10717             output_asm_insn (\"ldr%?\\t%0, [%1, %2]\", ops);
10718             ops[0] = ldm[2];
10719             ops[2] = GEN_INT (val2);
10720             output_asm_insn (\"ldr%?\\t%0, [%1, %2]\", ops);
10721           }
10722       }
10723     else if (val1 != 0)
10724       {
10725         if (val1 < val2)
10726           output_asm_insn (\"ldmda%?\\t%0, {%1, %2}\", ldm);
10727         else
10728           output_asm_insn (\"ldmia%?\\t%0, {%1, %2}\", ldm);
10729       }
10730     else
10731       {
10732         if (val1 < val2)
10733           output_asm_insn (\"ldmia%?\\t%0, {%1, %2}\", ldm);
10734         else
10735           output_asm_insn (\"ldmda%?\\t%0, {%1, %2}\", ldm);
10736       }
10737     output_asm_insn (\"%I3%?\\t%0, %1, %2\", arith);
10738     return \"\";
10739   }"
10740   [(set_attr "length" "12")
10741    (set_attr "predicable" "yes")
10742    (set_attr "type" "load1")]
10745 ; This pattern is never tried by combine, so do it as a peephole
10747 (define_peephole2
10748   [(set (match_operand:SI 0 "arm_general_register_operand" "")
10749         (match_operand:SI 1 "arm_general_register_operand" ""))
10750    (set (reg:CC CC_REGNUM)
10751         (compare:CC (match_dup 1) (const_int 0)))]
10752   "TARGET_ARM"
10753   [(parallel [(set (reg:CC CC_REGNUM) (compare:CC (match_dup 1) (const_int 0)))
10754               (set (match_dup 0) (match_dup 1))])]
10755   ""
10758 (define_split
10759   [(set (match_operand:SI 0 "s_register_operand" "")
10760         (and:SI (ge:SI (match_operand:SI 1 "s_register_operand" "")
10761                        (const_int 0))
10762                 (neg:SI (match_operator:SI 2 "arm_comparison_operator"
10763                          [(match_operand:SI 3 "s_register_operand" "")
10764                           (match_operand:SI 4 "arm_rhs_operand" "")]))))
10765    (clobber (match_operand:SI 5 "s_register_operand" ""))]
10766   "TARGET_ARM"
10767   [(set (match_dup 5) (not:SI (ashiftrt:SI (match_dup 1) (const_int 31))))
10768    (set (match_dup 0) (and:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
10769                               (match_dup 5)))]
10770   ""
10773 ;; This split can be used because CC_Z mode implies that the following
10774 ;; branch will be an equality, or an unsigned inequality, so the sign
10775 ;; extension is not needed.
10777 (define_split
10778   [(set (reg:CC_Z CC_REGNUM)
10779         (compare:CC_Z
10780          (ashift:SI (subreg:SI (match_operand:QI 0 "memory_operand" "") 0)
10781                     (const_int 24))
10782          (match_operand 1 "const_int_operand" "")))
10783    (clobber (match_scratch:SI 2 ""))]
10784   "TARGET_ARM
10785    && ((UINTVAL (operands[1]))
10786        == ((UINTVAL (operands[1])) >> 24) << 24)"
10787   [(set (match_dup 2) (zero_extend:SI (match_dup 0)))
10788    (set (reg:CC CC_REGNUM) (compare:CC (match_dup 2) (match_dup 1)))]
10789   "
10790   operands[1] = GEN_INT (((unsigned long) INTVAL (operands[1])) >> 24);
10791   "
10793 ;; ??? Check the patterns above for Thumb-2 usefulness
10795 (define_expand "prologue"
10796   [(clobber (const_int 0))]
10797   "TARGET_EITHER"
10798   "if (TARGET_32BIT)
10799      arm_expand_prologue ();
10800    else
10801      thumb1_expand_prologue ();
10802   DONE;
10803   "
10806 (define_expand "epilogue"
10807   [(clobber (const_int 0))]
10808   "TARGET_EITHER"
10809   "
10810   if (crtl->calls_eh_return)
10811     emit_insn (gen_force_register_use (gen_rtx_REG (Pmode, 2)));
10812   if (TARGET_THUMB1)
10813    {
10814      thumb1_expand_epilogue ();
10815      emit_jump_insn (gen_rtx_UNSPEC_VOLATILE (VOIDmode,
10816                      gen_rtvec (1, ret_rtx), VUNSPEC_EPILOGUE));
10817    }
10818   else if (HAVE_return)
10819    {
10820      /* HAVE_return is testing for USE_RETURN_INSN (FALSE).  Hence,
10821         no need for explicit testing again.  */
10822      emit_jump_insn (gen_return ());
10823    }
10824   else if (TARGET_32BIT)
10825    {
10826     arm_expand_epilogue (true);
10827    }
10828   DONE;
10829   "
10832 ;; Note - although unspec_volatile's USE all hard registers,
10833 ;; USEs are ignored after relaod has completed.  Thus we need
10834 ;; to add an unspec of the link register to ensure that flow
10835 ;; does not think that it is unused by the sibcall branch that
10836 ;; will replace the standard function epilogue.
10837 (define_expand "sibcall_epilogue"
10838    [(parallel [(unspec:SI [(reg:SI LR_REGNUM)] UNSPEC_REGISTER_USE)
10839                (unspec_volatile [(return)] VUNSPEC_EPILOGUE)])]
10840    "TARGET_32BIT"
10841    "
10842    arm_expand_epilogue (false);
10843    DONE;
10844    "
10847 (define_expand "eh_epilogue"
10848   [(use (match_operand:SI 0 "register_operand" ""))
10849    (use (match_operand:SI 1 "register_operand" ""))
10850    (use (match_operand:SI 2 "register_operand" ""))]
10851   "TARGET_EITHER"
10852   "
10853   {
10854     cfun->machine->eh_epilogue_sp_ofs = operands[1];
10855     if (!REG_P (operands[2]) || REGNO (operands[2]) != 2)
10856       {
10857         rtx ra = gen_rtx_REG (Pmode, 2);
10859         emit_move_insn (ra, operands[2]);
10860         operands[2] = ra;
10861       }
10862     /* This is a hack -- we may have crystalized the function type too
10863        early.  */
10864     cfun->machine->func_type = 0;
10865   }"
10868 ;; This split is only used during output to reduce the number of patterns
10869 ;; that need assembler instructions adding to them.  We allowed the setting
10870 ;; of the conditions to be implicit during rtl generation so that
10871 ;; the conditional compare patterns would work.  However this conflicts to
10872 ;; some extent with the conditional data operations, so we have to split them
10873 ;; up again here.
10875 ;; ??? Need to audit these splitters for Thumb-2.  Why isn't normal
10876 ;; conditional execution sufficient?
10878 (define_split
10879   [(set (match_operand:SI 0 "s_register_operand" "")
10880         (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10881                           [(match_operand 2 "" "") (match_operand 3 "" "")])
10882                          (match_dup 0)
10883                          (match_operand 4 "" "")))
10884    (clobber (reg:CC CC_REGNUM))]
10885   "TARGET_ARM && reload_completed"
10886   [(set (match_dup 5) (match_dup 6))
10887    (cond_exec (match_dup 7)
10888               (set (match_dup 0) (match_dup 4)))]
10889   "
10890   {
10891     machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10892                                              operands[2], operands[3]);
10893     enum rtx_code rc = GET_CODE (operands[1]);
10895     operands[5] = gen_rtx_REG (mode, CC_REGNUM);
10896     operands[6] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10897     if (mode == CCFPmode || mode == CCFPEmode)
10898       rc = reverse_condition_maybe_unordered (rc);
10899     else
10900       rc = reverse_condition (rc);
10902     operands[7] = gen_rtx_fmt_ee (rc, VOIDmode, operands[5], const0_rtx);
10903   }"
10906 (define_split
10907   [(set (match_operand:SI 0 "s_register_operand" "")
10908         (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10909                           [(match_operand 2 "" "") (match_operand 3 "" "")])
10910                          (match_operand 4 "" "")
10911                          (match_dup 0)))
10912    (clobber (reg:CC CC_REGNUM))]
10913   "TARGET_ARM && reload_completed"
10914   [(set (match_dup 5) (match_dup 6))
10915    (cond_exec (match_op_dup 1 [(match_dup 5) (const_int 0)])
10916               (set (match_dup 0) (match_dup 4)))]
10917   "
10918   {
10919     machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10920                                              operands[2], operands[3]);
10922     operands[5] = gen_rtx_REG (mode, CC_REGNUM);
10923     operands[6] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10924   }"
10927 (define_split
10928   [(set (match_operand:SI 0 "s_register_operand" "")
10929         (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10930                           [(match_operand 2 "" "") (match_operand 3 "" "")])
10931                          (match_operand 4 "" "")
10932                          (match_operand 5 "" "")))
10933    (clobber (reg:CC CC_REGNUM))]
10934   "TARGET_ARM && reload_completed"
10935   [(set (match_dup 6) (match_dup 7))
10936    (cond_exec (match_op_dup 1 [(match_dup 6) (const_int 0)])
10937               (set (match_dup 0) (match_dup 4)))
10938    (cond_exec (match_dup 8)
10939               (set (match_dup 0) (match_dup 5)))]
10940   "
10941   {
10942     machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10943                                              operands[2], operands[3]);
10944     enum rtx_code rc = GET_CODE (operands[1]);
10946     operands[6] = gen_rtx_REG (mode, CC_REGNUM);
10947     operands[7] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10948     if (mode == CCFPmode || mode == CCFPEmode)
10949       rc = reverse_condition_maybe_unordered (rc);
10950     else
10951       rc = reverse_condition (rc);
10953     operands[8] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
10954   }"
10957 (define_split
10958   [(set (match_operand:SI 0 "s_register_operand" "")
10959         (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10960                           [(match_operand:SI 2 "s_register_operand" "")
10961                            (match_operand:SI 3 "arm_add_operand" "")])
10962                          (match_operand:SI 4 "arm_rhs_operand" "")
10963                          (not:SI
10964                           (match_operand:SI 5 "s_register_operand" ""))))
10965    (clobber (reg:CC CC_REGNUM))]
10966   "TARGET_ARM && reload_completed"
10967   [(set (match_dup 6) (match_dup 7))
10968    (cond_exec (match_op_dup 1 [(match_dup 6) (const_int 0)])
10969               (set (match_dup 0) (match_dup 4)))
10970    (cond_exec (match_dup 8)
10971               (set (match_dup 0) (not:SI (match_dup 5))))]
10972   "
10973   {
10974     machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10975                                              operands[2], operands[3]);
10976     enum rtx_code rc = GET_CODE (operands[1]);
10978     operands[6] = gen_rtx_REG (mode, CC_REGNUM);
10979     operands[7] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10980     if (mode == CCFPmode || mode == CCFPEmode)
10981       rc = reverse_condition_maybe_unordered (rc);
10982     else
10983       rc = reverse_condition (rc);
10985     operands[8] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
10986   }"
10989 (define_insn "*cond_move_not"
10990   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10991         (if_then_else:SI (match_operator 4 "arm_comparison_operator"
10992                           [(match_operand 3 "cc_register" "") (const_int 0)])
10993                          (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
10994                          (not:SI
10995                           (match_operand:SI 2 "s_register_operand" "r,r"))))]
10996   "TARGET_ARM"
10997   "@
10998    mvn%D4\\t%0, %2
10999    mov%d4\\t%0, %1\;mvn%D4\\t%0, %2"
11000   [(set_attr "conds" "use")
11001    (set_attr "type" "mvn_reg,multiple")
11002    (set_attr "length" "4,8")]
11005 ;; The next two patterns occur when an AND operation is followed by a
11006 ;; scc insn sequence 
11008 (define_insn "*sign_extract_onebit"
11009   [(set (match_operand:SI 0 "s_register_operand" "=r")
11010         (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
11011                          (const_int 1)
11012                          (match_operand:SI 2 "const_int_operand" "n")))
11013     (clobber (reg:CC CC_REGNUM))]
11014   "TARGET_ARM"
11015   "*
11016     operands[2] = GEN_INT (1 << INTVAL (operands[2]));
11017     output_asm_insn (\"ands\\t%0, %1, %2\", operands);
11018     return \"mvnne\\t%0, #0\";
11019   "
11020   [(set_attr "conds" "clob")
11021    (set_attr "length" "8")
11022    (set_attr "type" "multiple")]
11025 (define_insn "*not_signextract_onebit"
11026   [(set (match_operand:SI 0 "s_register_operand" "=r")
11027         (not:SI
11028          (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
11029                           (const_int 1)
11030                           (match_operand:SI 2 "const_int_operand" "n"))))
11031    (clobber (reg:CC CC_REGNUM))]
11032   "TARGET_ARM"
11033   "*
11034     operands[2] = GEN_INT (1 << INTVAL (operands[2]));
11035     output_asm_insn (\"tst\\t%1, %2\", operands);
11036     output_asm_insn (\"mvneq\\t%0, #0\", operands);
11037     return \"movne\\t%0, #0\";
11038   "
11039   [(set_attr "conds" "clob")
11040    (set_attr "length" "12")
11041    (set_attr "type" "multiple")]
11043 ;; ??? The above patterns need auditing for Thumb-2
11045 ;; Push multiple registers to the stack.  Registers are in parallel (use ...)
11046 ;; expressions.  For simplicity, the first register is also in the unspec
11047 ;; part.
11048 ;; To avoid the usage of GNU extension, the length attribute is computed
11049 ;; in a C function arm_attr_length_push_multi.
11050 (define_insn "*push_multi"
11051   [(match_parallel 2 "multi_register_push"
11052     [(set (match_operand:BLK 0 "push_mult_memory_operand" "")
11053           (unspec:BLK [(match_operand:SI 1 "s_register_operand" "")]
11054                       UNSPEC_PUSH_MULT))])]
11055   ""
11056   "*
11057   {
11058     int num_saves = XVECLEN (operands[2], 0);
11059      
11060     /* For the StrongARM at least it is faster to
11061        use STR to store only a single register.
11062        In Thumb mode always use push, and the assembler will pick
11063        something appropriate.  */
11064     if (num_saves == 1 && TARGET_ARM)
11065       output_asm_insn (\"str%?\\t%1, [%m0, #-4]!\", operands);
11066     else
11067       {
11068         int i;
11069         char pattern[100];
11071         if (TARGET_32BIT)
11072             strcpy (pattern, \"push%?\\t{%1\");
11073         else
11074             strcpy (pattern, \"push\\t{%1\");
11076         for (i = 1; i < num_saves; i++)
11077           {
11078             strcat (pattern, \", %|\");
11079             strcat (pattern,
11080                     reg_names[REGNO (XEXP (XVECEXP (operands[2], 0, i), 0))]);
11081           }
11083         strcat (pattern, \"}\");
11084         output_asm_insn (pattern, operands);
11085       }
11087     return \"\";
11088   }"
11089   [(set_attr "type" "store4")
11090    (set (attr "length")
11091         (symbol_ref "arm_attr_length_push_multi (operands[2], operands[1])"))]
11094 (define_insn "stack_tie"
11095   [(set (mem:BLK (scratch))
11096         (unspec:BLK [(match_operand:SI 0 "s_register_operand" "rk")
11097                      (match_operand:SI 1 "s_register_operand" "rk")]
11098                     UNSPEC_PRLG_STK))]
11099   ""
11100   ""
11101   [(set_attr "length" "0")
11102    (set_attr "type" "block")]
11105 ;; Pop (as used in epilogue RTL)
11107 (define_insn "*load_multiple_with_writeback"
11108   [(match_parallel 0 "load_multiple_operation"
11109     [(set (match_operand:SI 1 "s_register_operand" "+rk")
11110           (plus:SI (match_dup 1)
11111                    (match_operand:SI 2 "const_int_I_operand" "I")))
11112      (set (match_operand:SI 3 "s_register_operand" "=rk")
11113           (mem:SI (match_dup 1)))
11114         ])]
11115   "TARGET_32BIT && (reload_in_progress || reload_completed)"
11116   "*
11117   {
11118     arm_output_multireg_pop (operands, /*return_pc=*/false,
11119                                        /*cond=*/const_true_rtx,
11120                                        /*reverse=*/false,
11121                                        /*update=*/true);
11122     return \"\";
11123   }
11124   "
11125   [(set_attr "type" "load4")
11126    (set_attr "predicable" "yes")
11127    (set (attr "length")
11128         (symbol_ref "arm_attr_length_pop_multi (operands,
11129                                                 /*return_pc=*/false,
11130                                                 /*write_back_p=*/true)"))]
11133 ;; Pop with return (as used in epilogue RTL)
11135 ;; This instruction is generated when the registers are popped at the end of
11136 ;; epilogue.  Here, instead of popping the value into LR and then generating
11137 ;; jump to LR, value is popped into PC directly.  Hence, the pattern is combined
11138 ;;  with (return).
11139 (define_insn "*pop_multiple_with_writeback_and_return"
11140   [(match_parallel 0 "pop_multiple_return"
11141     [(return)
11142      (set (match_operand:SI 1 "s_register_operand" "+rk")
11143           (plus:SI (match_dup 1)
11144                    (match_operand:SI 2 "const_int_I_operand" "I")))
11145      (set (match_operand:SI 3 "s_register_operand" "=rk")
11146           (mem:SI (match_dup 1)))
11147         ])]
11148   "TARGET_32BIT && (reload_in_progress || reload_completed)"
11149   "*
11150   {
11151     arm_output_multireg_pop (operands, /*return_pc=*/true,
11152                                        /*cond=*/const_true_rtx,
11153                                        /*reverse=*/false,
11154                                        /*update=*/true);
11155     return \"\";
11156   }
11157   "
11158   [(set_attr "type" "load4")
11159    (set_attr "predicable" "yes")
11160    (set (attr "length")
11161         (symbol_ref "arm_attr_length_pop_multi (operands, /*return_pc=*/true,
11162                                                 /*write_back_p=*/true)"))]
11165 (define_insn "*pop_multiple_with_return"
11166   [(match_parallel 0 "pop_multiple_return"
11167     [(return)
11168      (set (match_operand:SI 2 "s_register_operand" "=rk")
11169           (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
11170         ])]
11171   "TARGET_32BIT && (reload_in_progress || reload_completed)"
11172   "*
11173   {
11174     arm_output_multireg_pop (operands, /*return_pc=*/true,
11175                                        /*cond=*/const_true_rtx,
11176                                        /*reverse=*/false,
11177                                        /*update=*/false);
11178     return \"\";
11179   }
11180   "
11181   [(set_attr "type" "load4")
11182    (set_attr "predicable" "yes")
11183    (set (attr "length")
11184         (symbol_ref "arm_attr_length_pop_multi (operands, /*return_pc=*/true,
11185                                                 /*write_back_p=*/false)"))]
11188 ;; Load into PC and return
11189 (define_insn "*ldr_with_return"
11190   [(return)
11191    (set (reg:SI PC_REGNUM)
11192         (mem:SI (post_inc:SI (match_operand:SI 0 "s_register_operand" "+rk"))))]
11193   "TARGET_32BIT && (reload_in_progress || reload_completed)"
11194   "ldr%?\t%|pc, [%0], #4"
11195   [(set_attr "type" "load1")
11196    (set_attr "predicable" "yes")]
11198 ;; Pop for floating point registers (as used in epilogue RTL)
11199 (define_insn "*vfp_pop_multiple_with_writeback"
11200   [(match_parallel 0 "pop_multiple_fp"
11201     [(set (match_operand:SI 1 "s_register_operand" "+rk")
11202           (plus:SI (match_dup 1)
11203                    (match_operand:SI 2 "const_int_I_operand" "I")))
11204      (set (match_operand:DF 3 "vfp_hard_register_operand" "")
11205           (mem:DF (match_dup 1)))])]
11206   "TARGET_32BIT && TARGET_HARD_FLOAT"
11207   "*
11208   {
11209     int num_regs = XVECLEN (operands[0], 0);
11210     char pattern[100];
11211     rtx op_list[2];
11212     strcpy (pattern, \"vldm\\t\");
11213     strcat (pattern, reg_names[REGNO (SET_DEST (XVECEXP (operands[0], 0, 0)))]);
11214     strcat (pattern, \"!, {\");
11215     op_list[0] = XEXP (XVECEXP (operands[0], 0, 1), 0);
11216     strcat (pattern, \"%P0\");
11217     if ((num_regs - 1) > 1)
11218       {
11219         strcat (pattern, \"-%P1\");
11220         op_list [1] = XEXP (XVECEXP (operands[0], 0, num_regs - 1), 0);
11221       }
11223     strcat (pattern, \"}\");
11224     output_asm_insn (pattern, op_list);
11225     return \"\";
11226   }
11227   "
11228   [(set_attr "type" "load4")
11229    (set_attr "conds" "unconditional")
11230    (set_attr "predicable" "no")]
11233 ;; Special patterns for dealing with the constant pool
11235 (define_insn "align_4"
11236   [(unspec_volatile [(const_int 0)] VUNSPEC_ALIGN)]
11237   "TARGET_EITHER"
11238   "*
11239   assemble_align (32);
11240   return \"\";
11241   "
11242   [(set_attr "type" "no_insn")]
11245 (define_insn "align_8"
11246   [(unspec_volatile [(const_int 0)] VUNSPEC_ALIGN8)]
11247   "TARGET_EITHER"
11248   "*
11249   assemble_align (64);
11250   return \"\";
11251   "
11252   [(set_attr "type" "no_insn")]
11255 (define_insn "consttable_end"
11256   [(unspec_volatile [(const_int 0)] VUNSPEC_POOL_END)]
11257   "TARGET_EITHER"
11258   "*
11259   making_const_table = FALSE;
11260   return \"\";
11261   "
11262   [(set_attr "type" "no_insn")]
11265 (define_insn "consttable_1"
11266   [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_1)]
11267   "TARGET_EITHER"
11268   "*
11269   making_const_table = TRUE;
11270   assemble_integer (operands[0], 1, BITS_PER_WORD, 1);
11271   assemble_zeros (3);
11272   return \"\";
11273   "
11274   [(set_attr "length" "4")
11275    (set_attr "type" "no_insn")]
11278 (define_insn "consttable_2"
11279   [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_2)]
11280   "TARGET_EITHER"
11281   "*
11282   {
11283     rtx x = operands[0];
11284     making_const_table = TRUE;
11285     switch (GET_MODE_CLASS (GET_MODE (x)))
11286       {
11287       case MODE_FLOAT:
11288         arm_emit_fp16_const (x);
11289         break;
11290       default:
11291         assemble_integer (operands[0], 2, BITS_PER_WORD, 1);
11292         assemble_zeros (2);
11293         break;
11294       }
11295     return \"\";
11296   }"
11297   [(set_attr "length" "4")
11298    (set_attr "type" "no_insn")]
11301 (define_insn "consttable_4"
11302   [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_4)]
11303   "TARGET_EITHER"
11304   "*
11305   {
11306     rtx x = operands[0];
11307     making_const_table = TRUE;
11308     scalar_float_mode float_mode;
11309     if (is_a <scalar_float_mode> (GET_MODE (x), &float_mode))
11310       assemble_real (*CONST_DOUBLE_REAL_VALUE (x), float_mode, BITS_PER_WORD);
11311     else
11312       {
11313         /* XXX: Sometimes gcc does something really dumb and ends up with
11314            a HIGH in a constant pool entry, usually because it's trying to
11315            load into a VFP register.  We know this will always be used in
11316            combination with a LO_SUM which ignores the high bits, so just
11317            strip off the HIGH.  */
11318         if (GET_CODE (x) == HIGH)
11319           x = XEXP (x, 0);
11320         assemble_integer (x, 4, BITS_PER_WORD, 1);
11321         mark_symbol_refs_as_used (x);
11322       }
11323     return \"\";
11324   }"
11325   [(set_attr "length" "4")
11326    (set_attr "type" "no_insn")]
11329 (define_insn "consttable_8"
11330   [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_8)]
11331   "TARGET_EITHER"
11332   "*
11333   {
11334     making_const_table = TRUE;
11335     scalar_float_mode float_mode;
11336     if (is_a <scalar_float_mode> (GET_MODE (operands[0]), &float_mode))
11337       assemble_real (*CONST_DOUBLE_REAL_VALUE (operands[0]),
11338                      float_mode, BITS_PER_WORD);
11339     else
11340       assemble_integer (operands[0], 8, BITS_PER_WORD, 1);
11341     return \"\";
11342   }"
11343   [(set_attr "length" "8")
11344    (set_attr "type" "no_insn")]
11347 (define_insn "consttable_16"
11348   [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_16)]
11349   "TARGET_EITHER"
11350   "*
11351   {
11352     making_const_table = TRUE;
11353     scalar_float_mode float_mode;
11354     if (is_a <scalar_float_mode> (GET_MODE (operands[0]), &float_mode))
11355       assemble_real (*CONST_DOUBLE_REAL_VALUE (operands[0]),
11356                      float_mode, BITS_PER_WORD);
11357     else
11358       assemble_integer (operands[0], 16, BITS_PER_WORD, 1);
11359     return \"\";
11360   }"
11361   [(set_attr "length" "16")
11362    (set_attr "type" "no_insn")]
11365 ;; V5 Instructions,
11367 (define_insn "clzsi2"
11368   [(set (match_operand:SI 0 "s_register_operand" "=r")
11369         (clz:SI (match_operand:SI 1 "s_register_operand" "r")))]
11370   "TARGET_32BIT && arm_arch5"
11371   "clz%?\\t%0, %1"
11372   [(set_attr "predicable" "yes")
11373    (set_attr "predicable_short_it" "no")
11374    (set_attr "type" "clz")])
11376 (define_insn "rbitsi2"
11377   [(set (match_operand:SI 0 "s_register_operand" "=r")
11378         (unspec:SI [(match_operand:SI 1 "s_register_operand" "r")] UNSPEC_RBIT))]
11379   "TARGET_32BIT && arm_arch_thumb2"
11380   "rbit%?\\t%0, %1"
11381   [(set_attr "predicable" "yes")
11382    (set_attr "predicable_short_it" "no")
11383    (set_attr "type" "clz")])
11385 ;; Keep this as a CTZ expression until after reload and then split
11386 ;; into RBIT + CLZ.  Since RBIT is represented as an UNSPEC it is unlikely
11387 ;; to fold with any other expression.
11389 (define_insn_and_split "ctzsi2"
11390  [(set (match_operand:SI           0 "s_register_operand" "=r")
11391        (ctz:SI (match_operand:SI  1 "s_register_operand" "r")))]
11392   "TARGET_32BIT && arm_arch_thumb2"
11393   "#"
11394   "&& reload_completed"
11395   [(const_int 0)]
11396   "
11397   emit_insn (gen_rbitsi2 (operands[0], operands[1]));
11398   emit_insn (gen_clzsi2 (operands[0], operands[0]));
11399   DONE;
11402 ;; V5E instructions.
11404 (define_insn "prefetch"
11405   [(prefetch (match_operand:SI 0 "address_operand" "p")
11406              (match_operand:SI 1 "" "")
11407              (match_operand:SI 2 "" ""))]
11408   "TARGET_32BIT && arm_arch5e"
11409   "pld\\t%a0"
11410   [(set_attr "type" "load1")]
11413 ;; General predication pattern
11415 (define_cond_exec
11416   [(match_operator 0 "arm_comparison_operator"
11417     [(match_operand 1 "cc_register" "")
11418      (const_int 0)])]
11419   "TARGET_32BIT
11420    && (!TARGET_NO_VOLATILE_CE || !volatile_refs_p (PATTERN (insn)))"
11421   ""
11422 [(set_attr "predicated" "yes")]
11425 (define_insn "force_register_use"
11426   [(unspec:SI [(match_operand:SI 0 "register_operand" "")] UNSPEC_REGISTER_USE)]
11427   ""
11428   "%@ %0 needed"
11429   [(set_attr "length" "0")
11430    (set_attr "type" "no_insn")]
11434 ;; Patterns for exception handling
11436 (define_expand "eh_return"
11437   [(use (match_operand 0 "general_operand" ""))]
11438   "TARGET_EITHER"
11439   "
11440   {
11441     if (TARGET_32BIT)
11442       emit_insn (gen_arm_eh_return (operands[0]));
11443     else
11444       emit_insn (gen_thumb_eh_return (operands[0]));
11445     DONE;
11446   }"
11448                                    
11449 ;; We can't expand this before we know where the link register is stored.
11450 (define_insn_and_split "arm_eh_return"
11451   [(unspec_volatile [(match_operand:SI 0 "s_register_operand" "r")]
11452                     VUNSPEC_EH_RETURN)
11453    (clobber (match_scratch:SI 1 "=&r"))]
11454   "TARGET_ARM"
11455   "#"
11456   "&& reload_completed"
11457   [(const_int 0)]
11458   "
11459   {
11460     arm_set_return_address (operands[0], operands[1]);
11461     DONE;
11462   }"
11466 ;; TLS support
11468 (define_insn "load_tp_hard"
11469   [(set (match_operand:SI 0 "register_operand" "=r")
11470         (unspec:SI [(const_int 0)] UNSPEC_TLS))]
11471   "TARGET_HARD_TP"
11472   "mrc%?\\tp15, 0, %0, c13, c0, 3\\t@ load_tp_hard"
11473   [(set_attr "predicable" "yes")
11474    (set_attr "type" "mrs")]
11477 ;; Doesn't clobber R1-R3.  Must use r0 for the first operand.
11478 (define_insn "load_tp_soft"
11479   [(set (reg:SI 0) (unspec:SI [(const_int 0)] UNSPEC_TLS))
11480    (clobber (reg:SI LR_REGNUM))
11481    (clobber (reg:SI IP_REGNUM))
11482    (clobber (reg:CC CC_REGNUM))]
11483   "TARGET_SOFT_TP"
11484   "bl\\t__aeabi_read_tp\\t@ load_tp_soft"
11485   [(set_attr "conds" "clob")
11486    (set_attr "type" "branch")]
11489 ;; tls descriptor call
11490 (define_insn "tlscall"
11491   [(set (reg:SI R0_REGNUM)
11492         (unspec:SI [(reg:SI R0_REGNUM)
11493                     (match_operand:SI 0 "" "X")
11494                     (match_operand 1 "" "")] UNSPEC_TLS))
11495    (clobber (reg:SI R1_REGNUM))
11496    (clobber (reg:SI LR_REGNUM))
11497    (clobber (reg:SI CC_REGNUM))]
11498   "TARGET_GNU2_TLS"
11499   {
11500     targetm.asm_out.internal_label (asm_out_file, "LPIC",
11501                                     INTVAL (operands[1]));
11502     return "bl\\t%c0(tlscall)";
11503   }
11504   [(set_attr "conds" "clob")
11505    (set_attr "length" "4")
11506    (set_attr "type" "branch")]
11509 ;; For thread pointer builtin
11510 (define_expand "get_thread_pointersi"
11511   [(match_operand:SI 0 "s_register_operand" "=r")]
11512  ""
11515    arm_load_tp (operands[0]);
11516    DONE;
11517  }")
11521 ;; We only care about the lower 16 bits of the constant 
11522 ;; being inserted into the upper 16 bits of the register.
11523 (define_insn "*arm_movtas_ze" 
11524   [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r,r")
11525                    (const_int 16)
11526                    (const_int 16))
11527         (match_operand:SI 1 "const_int_operand" ""))]
11528   "TARGET_HAVE_MOVT"
11529   "@
11530    movt%?\t%0, %L1
11531    movt\t%0, %L1"
11532  [(set_attr "arch" "32,v8mb")
11533   (set_attr "predicable" "yes")
11534   (set_attr "predicable_short_it" "no")
11535   (set_attr "length" "4")
11536   (set_attr "type" "alu_sreg")]
11539 (define_insn "*arm_rev"
11540   [(set (match_operand:SI 0 "s_register_operand" "=l,l,r")
11541         (bswap:SI (match_operand:SI 1 "s_register_operand" "l,l,r")))]
11542   "arm_arch6"
11543   "@
11544    rev\t%0, %1
11545    rev%?\t%0, %1
11546    rev%?\t%0, %1"
11547   [(set_attr "arch" "t1,t2,32")
11548    (set_attr "length" "2,2,4")
11549    (set_attr "predicable" "no,yes,yes")
11550    (set_attr "predicable_short_it" "no")
11551    (set_attr "type" "rev")]
11554 (define_expand "arm_legacy_rev"
11555   [(set (match_operand:SI 2 "s_register_operand" "")
11556         (xor:SI (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
11557                              (const_int 16))
11558                 (match_dup 1)))
11559    (set (match_dup 2)
11560         (lshiftrt:SI (match_dup 2)
11561                      (const_int 8)))
11562    (set (match_operand:SI 3 "s_register_operand" "")
11563         (rotatert:SI (match_dup 1)
11564                      (const_int 8)))
11565    (set (match_dup 2)
11566         (and:SI (match_dup 2)
11567                 (const_int -65281)))
11568    (set (match_operand:SI 0 "s_register_operand" "")
11569         (xor:SI (match_dup 3)
11570                 (match_dup 2)))]
11571   "TARGET_32BIT"
11572   ""
11575 ;; Reuse temporaries to keep register pressure down.
11576 (define_expand "thumb_legacy_rev"
11577   [(set (match_operand:SI 2 "s_register_operand" "")
11578      (ashift:SI (match_operand:SI 1 "s_register_operand" "")
11579                 (const_int 24)))
11580    (set (match_operand:SI 3 "s_register_operand" "")
11581      (lshiftrt:SI (match_dup 1)
11582                   (const_int 24)))
11583    (set (match_dup 3)
11584      (ior:SI (match_dup 3)
11585              (match_dup 2)))
11586    (set (match_operand:SI 4 "s_register_operand" "")
11587      (const_int 16))
11588    (set (match_operand:SI 5 "s_register_operand" "")
11589      (rotatert:SI (match_dup 1)
11590                   (match_dup 4)))
11591    (set (match_dup 2)
11592      (ashift:SI (match_dup 5)
11593                 (const_int 24)))
11594    (set (match_dup 5)
11595      (lshiftrt:SI (match_dup 5)
11596                   (const_int 24)))
11597    (set (match_dup 5)
11598      (ior:SI (match_dup 5)
11599              (match_dup 2)))
11600    (set (match_dup 5)
11601      (rotatert:SI (match_dup 5)
11602                   (match_dup 4)))
11603    (set (match_operand:SI 0 "s_register_operand" "")
11604      (ior:SI (match_dup 5)
11605              (match_dup 3)))]
11606   "TARGET_THUMB"
11607   ""
11610 ;; ARM-specific expansion of signed mod by power of 2
11611 ;; using conditional negate.
11612 ;; For r0 % n where n is a power of 2 produce:
11613 ;; rsbs    r1, r0, #0
11614 ;; and     r0, r0, #(n - 1)
11615 ;; and     r1, r1, #(n - 1)
11616 ;; rsbpl   r0, r1, #0
11618 (define_expand "modsi3"
11619   [(match_operand:SI 0 "register_operand" "")
11620    (match_operand:SI 1 "register_operand" "")
11621    (match_operand:SI 2 "const_int_operand" "")]
11622   "TARGET_32BIT"
11623   {
11624     HOST_WIDE_INT val = INTVAL (operands[2]);
11626     if (val <= 0
11627        || exact_log2 (val) <= 0)
11628       FAIL;
11630     rtx mask = GEN_INT (val - 1);
11632     /* In the special case of x0 % 2 we can do the even shorter:
11633         cmp     r0, #0
11634         and     r0, r0, #1
11635         rsblt   r0, r0, #0.  */
11637     if (val == 2)
11638       {
11639         rtx cc_reg = arm_gen_compare_reg (LT,
11640                                           operands[1], const0_rtx, NULL_RTX);
11641         rtx cond = gen_rtx_LT (SImode, cc_reg, const0_rtx);
11642         rtx masked = gen_reg_rtx (SImode);
11644         emit_insn (gen_andsi3 (masked, operands[1], mask));
11645         emit_move_insn (operands[0],
11646                         gen_rtx_IF_THEN_ELSE (SImode, cond,
11647                                               gen_rtx_NEG (SImode,
11648                                                            masked),
11649                                               masked));
11650         DONE;
11651       }
11653     rtx neg_op = gen_reg_rtx (SImode);
11654     rtx_insn *insn = emit_insn (gen_subsi3_compare0 (neg_op, const0_rtx,
11655                                                       operands[1]));
11657     /* Extract the condition register and mode.  */
11658     rtx cmp = XVECEXP (PATTERN (insn), 0, 0);
11659     rtx cc_reg = SET_DEST (cmp);
11660     rtx cond = gen_rtx_GE (SImode, cc_reg, const0_rtx);
11662     emit_insn (gen_andsi3 (operands[0], operands[1], mask));
11664     rtx masked_neg = gen_reg_rtx (SImode);
11665     emit_insn (gen_andsi3 (masked_neg, neg_op, mask));
11667     /* We want a conditional negate here, but emitting COND_EXEC rtxes
11668        during expand does not always work.  Do an IF_THEN_ELSE instead.  */
11669     emit_move_insn (operands[0],
11670                     gen_rtx_IF_THEN_ELSE (SImode, cond,
11671                                           gen_rtx_NEG (SImode, masked_neg),
11672                                           operands[0]));
11675     DONE;
11676   }
11679 (define_expand "bswapsi2"
11680   [(set (match_operand:SI 0 "s_register_operand" "=r")
11681         (bswap:SI (match_operand:SI 1 "s_register_operand" "r")))]
11682 "TARGET_EITHER && (arm_arch6 || !optimize_size)"
11684     if (!arm_arch6)
11685       {
11686         rtx op2 = gen_reg_rtx (SImode);
11687         rtx op3 = gen_reg_rtx (SImode);
11689         if (TARGET_THUMB)
11690           {
11691             rtx op4 = gen_reg_rtx (SImode);
11692             rtx op5 = gen_reg_rtx (SImode);
11694             emit_insn (gen_thumb_legacy_rev (operands[0], operands[1],
11695                                              op2, op3, op4, op5));
11696           }
11697         else
11698           {
11699             emit_insn (gen_arm_legacy_rev (operands[0], operands[1],
11700                                            op2, op3));
11701           }
11703         DONE;
11704       }
11705   "
11708 ;; bswap16 patterns: use revsh and rev16 instructions for the signed
11709 ;; and unsigned variants, respectively. For rev16, expose
11710 ;; byte-swapping in the lower 16 bits only.
11711 (define_insn "*arm_revsh"
11712   [(set (match_operand:SI 0 "s_register_operand" "=l,l,r")
11713         (sign_extend:SI (bswap:HI (match_operand:HI 1 "s_register_operand" "l,l,r"))))]
11714   "arm_arch6"
11715   "@
11716   revsh\t%0, %1
11717   revsh%?\t%0, %1
11718   revsh%?\t%0, %1"
11719   [(set_attr "arch" "t1,t2,32")
11720    (set_attr "length" "2,2,4")
11721    (set_attr "type" "rev")]
11724 (define_insn "*arm_rev16"
11725   [(set (match_operand:HI 0 "s_register_operand" "=l,l,r")
11726         (bswap:HI (match_operand:HI 1 "s_register_operand" "l,l,r")))]
11727   "arm_arch6"
11728   "@
11729    rev16\t%0, %1
11730    rev16%?\t%0, %1
11731    rev16%?\t%0, %1"
11732   [(set_attr "arch" "t1,t2,32")
11733    (set_attr "length" "2,2,4")
11734    (set_attr "type" "rev")]
11737 ;; There are no canonicalisation rules for the position of the lshiftrt, ashift
11738 ;; operations within an IOR/AND RTX, therefore we have two patterns matching
11739 ;; each valid permutation.
11741 (define_insn "arm_rev16si2"
11742   [(set (match_operand:SI 0 "register_operand" "=l,l,r")
11743         (ior:SI (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "l,l,r")
11744                                    (const_int 8))
11745                         (match_operand:SI 3 "const_int_operand" "n,n,n"))
11746                 (and:SI (lshiftrt:SI (match_dup 1)
11747                                      (const_int 8))
11748                         (match_operand:SI 2 "const_int_operand" "n,n,n"))))]
11749   "arm_arch6
11750    && aarch_rev16_shleft_mask_imm_p (operands[3], SImode)
11751    && aarch_rev16_shright_mask_imm_p (operands[2], SImode)"
11752   "rev16\\t%0, %1"
11753   [(set_attr "arch" "t1,t2,32")
11754    (set_attr "length" "2,2,4")
11755    (set_attr "type" "rev")]
11758 (define_insn "arm_rev16si2_alt"
11759   [(set (match_operand:SI 0 "register_operand" "=l,l,r")
11760         (ior:SI (and:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "l,l,r")
11761                                      (const_int 8))
11762                         (match_operand:SI 2 "const_int_operand" "n,n,n"))
11763                 (and:SI (ashift:SI (match_dup 1)
11764                                    (const_int 8))
11765                         (match_operand:SI 3 "const_int_operand" "n,n,n"))))]
11766   "arm_arch6
11767    && aarch_rev16_shleft_mask_imm_p (operands[3], SImode)
11768    && aarch_rev16_shright_mask_imm_p (operands[2], SImode)"
11769   "rev16\\t%0, %1"
11770   [(set_attr "arch" "t1,t2,32")
11771    (set_attr "length" "2,2,4")
11772    (set_attr "type" "rev")]
11775 (define_expand "bswaphi2"
11776   [(set (match_operand:HI 0 "s_register_operand" "=r")
11777         (bswap:HI (match_operand:HI 1 "s_register_operand" "r")))]
11778 "arm_arch6"
11782 ;; Patterns for LDRD/STRD in Thumb2 mode
11784 (define_insn "*thumb2_ldrd"
11785   [(set (match_operand:SI 0 "s_register_operand" "=r")
11786         (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "rk")
11787                          (match_operand:SI 2 "ldrd_strd_offset_operand" "Do"))))
11788    (set (match_operand:SI 3 "s_register_operand" "=r")
11789         (mem:SI (plus:SI (match_dup 1)
11790                          (match_operand:SI 4 "const_int_operand" ""))))]
11791   "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11792      && ((INTVAL (operands[2]) + 4) == INTVAL (operands[4]))
11793      && (operands_ok_ldrd_strd (operands[0], operands[3],
11794                                   operands[1], INTVAL (operands[2]),
11795                                   false, true))"
11796   "ldrd%?\t%0, %3, [%1, %2]"
11797   [(set_attr "type" "load2")
11798    (set_attr "predicable" "yes")
11799    (set_attr "predicable_short_it" "no")])
11801 (define_insn "*thumb2_ldrd_base"
11802   [(set (match_operand:SI 0 "s_register_operand" "=r")
11803         (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
11804    (set (match_operand:SI 2 "s_register_operand" "=r")
11805         (mem:SI (plus:SI (match_dup 1)
11806                          (const_int 4))))]
11807   "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11808      && (operands_ok_ldrd_strd (operands[0], operands[2],
11809                                   operands[1], 0, false, true))"
11810   "ldrd%?\t%0, %2, [%1]"
11811   [(set_attr "type" "load2")
11812    (set_attr "predicable" "yes")
11813    (set_attr "predicable_short_it" "no")])
11815 (define_insn "*thumb2_ldrd_base_neg"
11816   [(set (match_operand:SI 0 "s_register_operand" "=r")
11817         (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "rk")
11818                          (const_int -4))))
11819    (set (match_operand:SI 2 "s_register_operand" "=r")
11820         (mem:SI (match_dup 1)))]
11821   "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11822      && (operands_ok_ldrd_strd (operands[0], operands[2],
11823                                   operands[1], -4, false, true))"
11824   "ldrd%?\t%0, %2, [%1, #-4]"
11825   [(set_attr "type" "load2")
11826    (set_attr "predicable" "yes")
11827    (set_attr "predicable_short_it" "no")])
11829 (define_insn "*thumb2_strd"
11830   [(set (mem:SI (plus:SI (match_operand:SI 0 "s_register_operand" "rk")
11831                          (match_operand:SI 1 "ldrd_strd_offset_operand" "Do")))
11832         (match_operand:SI 2 "s_register_operand" "r"))
11833    (set (mem:SI (plus:SI (match_dup 0)
11834                          (match_operand:SI 3 "const_int_operand" "")))
11835         (match_operand:SI 4 "s_register_operand" "r"))]
11836   "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11837      && ((INTVAL (operands[1]) + 4) == INTVAL (operands[3]))
11838      && (operands_ok_ldrd_strd (operands[2], operands[4],
11839                                   operands[0], INTVAL (operands[1]),
11840                                   false, false))"
11841   "strd%?\t%2, %4, [%0, %1]"
11842   [(set_attr "type" "store2")
11843    (set_attr "predicable" "yes")
11844    (set_attr "predicable_short_it" "no")])
11846 (define_insn "*thumb2_strd_base"
11847   [(set (mem:SI (match_operand:SI 0 "s_register_operand" "rk"))
11848         (match_operand:SI 1 "s_register_operand" "r"))
11849    (set (mem:SI (plus:SI (match_dup 0)
11850                          (const_int 4)))
11851         (match_operand:SI 2 "s_register_operand" "r"))]
11852   "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11853      && (operands_ok_ldrd_strd (operands[1], operands[2],
11854                                   operands[0], 0, false, false))"
11855   "strd%?\t%1, %2, [%0]"
11856   [(set_attr "type" "store2")
11857    (set_attr "predicable" "yes")
11858    (set_attr "predicable_short_it" "no")])
11860 (define_insn "*thumb2_strd_base_neg"
11861   [(set (mem:SI (plus:SI (match_operand:SI 0 "s_register_operand" "rk")
11862                          (const_int -4)))
11863         (match_operand:SI 1 "s_register_operand" "r"))
11864    (set (mem:SI (match_dup 0))
11865         (match_operand:SI 2 "s_register_operand" "r"))]
11866   "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11867      && (operands_ok_ldrd_strd (operands[1], operands[2],
11868                                   operands[0], -4, false, false))"
11869   "strd%?\t%1, %2, [%0, #-4]"
11870   [(set_attr "type" "store2")
11871    (set_attr "predicable" "yes")
11872    (set_attr "predicable_short_it" "no")])
11874 ;; ARMv8 CRC32 instructions.
11875 (define_insn "<crc_variant>"
11876   [(set (match_operand:SI 0 "s_register_operand" "=r")
11877         (unspec:SI [(match_operand:SI 1 "s_register_operand" "r")
11878                     (match_operand:<crc_mode> 2 "s_register_operand" "r")]
11879          CRC))]
11880   "TARGET_CRC32"
11881   "<crc_variant>\\t%0, %1, %2"
11882   [(set_attr "type" "crc")
11883    (set_attr "conds" "unconditional")]
11886 ;; Load the load/store double peephole optimizations.
11887 (include "ldrdstrd.md")
11889 ;; Load the load/store multiple patterns
11890 (include "ldmstm.md")
11892 ;; Patterns in ldmstm.md don't cover more than 4 registers. This pattern covers
11893 ;; large lists without explicit writeback generated for APCS_FRAME epilogue.
11894 ;; The operands are validated through the load_multiple_operation
11895 ;; match_parallel predicate rather than through constraints so enable it only
11896 ;; after reload.
11897 (define_insn "*load_multiple"
11898   [(match_parallel 0 "load_multiple_operation"
11899     [(set (match_operand:SI 2 "s_register_operand" "=rk")
11900           (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
11901         ])]
11902   "TARGET_32BIT && reload_completed"
11903   "*
11904   {
11905     arm_output_multireg_pop (operands, /*return_pc=*/false,
11906                                        /*cond=*/const_true_rtx,
11907                                        /*reverse=*/false,
11908                                        /*update=*/false);
11909     return \"\";
11910   }
11911   "
11912   [(set_attr "predicable" "yes")]
11915 (define_expand "copysignsf3"
11916   [(match_operand:SF 0 "register_operand")
11917    (match_operand:SF 1 "register_operand")
11918    (match_operand:SF 2 "register_operand")]
11919   "TARGET_SOFT_FLOAT && arm_arch_thumb2"
11920   "{
11921      emit_move_insn (operands[0], operands[2]);
11922      emit_insn (gen_insv_t2 (simplify_gen_subreg (SImode, operands[0], SFmode, 0),
11923                 GEN_INT (31), GEN_INT (0),
11924                 simplify_gen_subreg (SImode, operands[1], SFmode, 0)));
11925      DONE;
11926   }"
11929 (define_expand "copysigndf3"
11930   [(match_operand:DF 0 "register_operand")
11931    (match_operand:DF 1 "register_operand")
11932    (match_operand:DF 2 "register_operand")]
11933   "TARGET_SOFT_FLOAT && arm_arch_thumb2"
11934   "{
11935      rtx op0_low = gen_lowpart (SImode, operands[0]);
11936      rtx op0_high = gen_highpart (SImode, operands[0]);
11937      rtx op1_low = gen_lowpart (SImode, operands[1]);
11938      rtx op1_high = gen_highpart (SImode, operands[1]);
11939      rtx op2_high = gen_highpart (SImode, operands[2]);
11941      rtx scratch1 = gen_reg_rtx (SImode);
11942      rtx scratch2 = gen_reg_rtx (SImode);
11943      emit_move_insn (scratch1, op2_high);
11944      emit_move_insn (scratch2, op1_high);
11946      emit_insn(gen_rtx_SET(scratch1,
11947                            gen_rtx_LSHIFTRT (SImode, op2_high, GEN_INT(31))));
11948      emit_insn(gen_insv_t2(scratch2, GEN_INT(1), GEN_INT(31), scratch1));
11949      emit_move_insn (op0_low, op1_low);
11950      emit_move_insn (op0_high, scratch2);
11952      DONE;
11953   }"
11956 ;; movmisalign patterns for HImode and SImode.
11957 (define_expand "movmisalign<mode>"
11958   [(match_operand:HSI 0 "general_operand")
11959    (match_operand:HSI 1 "general_operand")]
11960   "unaligned_access"
11962   /* This pattern is not permitted to fail during expansion: if both arguments
11963      are non-registers (e.g. memory := constant), force operand 1 into a
11964      register.  */
11965   rtx (* gen_unaligned_load)(rtx, rtx);
11966   rtx tmp_dest = operands[0];
11967   if (!s_register_operand (operands[0], <MODE>mode)
11968       && !s_register_operand (operands[1], <MODE>mode))
11969     operands[1] = force_reg (<MODE>mode, operands[1]);
11971   if (<MODE>mode == HImode)
11972    {
11973     gen_unaligned_load = gen_unaligned_loadhiu;
11974     tmp_dest = gen_reg_rtx (SImode);
11975    }
11976   else
11977     gen_unaligned_load = gen_unaligned_loadsi;
11979   if (MEM_P (operands[1]))
11980    {
11981     emit_insn (gen_unaligned_load (tmp_dest, operands[1]));
11982     if (<MODE>mode == HImode)
11983       emit_move_insn (operands[0], gen_lowpart (HImode, tmp_dest));
11984    }
11985   else
11986     emit_insn (gen_unaligned_store<mode> (operands[0], operands[1]));
11988   DONE;
11991 (define_insn "<cdp>"
11992   [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "n")
11993                      (match_operand:SI 1 "immediate_operand" "n")
11994                      (match_operand:SI 2 "immediate_operand" "n")
11995                      (match_operand:SI 3 "immediate_operand" "n")
11996                      (match_operand:SI 4 "immediate_operand" "n")
11997                      (match_operand:SI 5 "immediate_operand" "n")] CDPI)]
11998   "arm_coproc_builtin_available (VUNSPEC_<CDP>)"
12000   arm_const_bounds (operands[0], 0, 16);
12001   arm_const_bounds (operands[1], 0, 16);
12002   arm_const_bounds (operands[2], 0, (1 << 5));
12003   arm_const_bounds (operands[3], 0, (1 << 5));
12004   arm_const_bounds (operands[4], 0, (1 << 5));
12005   arm_const_bounds (operands[5], 0, 8);
12006   return "<cdp>\\tp%c0, %1, CR%c2, CR%c3, CR%c4, %5";
12008   [(set_attr "length" "4")
12009    (set_attr "type" "coproc")])
12011 (define_insn "*ldc"
12012   [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "n")
12013                      (match_operand:SI 1 "immediate_operand" "n")
12014                      (match_operand:SI 2 "memory_operand" "Uz")] LDCI)]
12015   "arm_coproc_builtin_available (VUNSPEC_<LDC>)"
12017   arm_const_bounds (operands[0], 0, 16);
12018   arm_const_bounds (operands[1], 0, (1 << 5));
12019   return "<ldc>\\tp%c0, CR%c1, %2";
12021   [(set_attr "length" "4")
12022    (set_attr "type" "coproc")])
12024 (define_insn "*stc"
12025   [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "n")
12026                      (match_operand:SI 1 "immediate_operand" "n")
12027                      (match_operand:SI 2 "memory_operand" "=Uz")] STCI)]
12028   "arm_coproc_builtin_available (VUNSPEC_<STC>)"
12030   arm_const_bounds (operands[0], 0, 16);
12031   arm_const_bounds (operands[1], 0, (1 << 5));
12032   return "<stc>\\tp%c0, CR%c1, %2";
12034   [(set_attr "length" "4")
12035    (set_attr "type" "coproc")])
12037 (define_expand "<ldc>"
12038   [(unspec_volatile [(match_operand:SI 0 "immediate_operand")
12039                      (match_operand:SI 1 "immediate_operand")
12040                      (mem:SI (match_operand:SI 2 "s_register_operand"))] LDCI)]
12041   "arm_coproc_builtin_available (VUNSPEC_<LDC>)")
12043 (define_expand "<stc>"
12044   [(unspec_volatile [(match_operand:SI 0 "immediate_operand")
12045                      (match_operand:SI 1 "immediate_operand")
12046                      (mem:SI (match_operand:SI 2 "s_register_operand"))] STCI)]
12047   "arm_coproc_builtin_available (VUNSPEC_<STC>)")
12049 (define_insn "<mcr>"
12050   [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "n")
12051                      (match_operand:SI 1 "immediate_operand" "n")
12052                      (match_operand:SI 2 "s_register_operand" "r")
12053                      (match_operand:SI 3 "immediate_operand" "n")
12054                      (match_operand:SI 4 "immediate_operand" "n")
12055                      (match_operand:SI 5 "immediate_operand" "n")] MCRI)
12056    (use (match_dup 2))]
12057   "arm_coproc_builtin_available (VUNSPEC_<MCR>)"
12059   arm_const_bounds (operands[0], 0, 16);
12060   arm_const_bounds (operands[1], 0, 8);
12061   arm_const_bounds (operands[3], 0, (1 << 5));
12062   arm_const_bounds (operands[4], 0, (1 << 5));
12063   arm_const_bounds (operands[5], 0, 8);
12064   return "<mcr>\\tp%c0, %1, %2, CR%c3, CR%c4, %5";
12066   [(set_attr "length" "4")
12067    (set_attr "type" "coproc")])
12069 (define_insn "<mrc>"
12070   [(set (match_operand:SI 0 "s_register_operand" "=r")
12071         (unspec_volatile:SI [(match_operand:SI 1 "immediate_operand" "n")
12072                           (match_operand:SI 2 "immediate_operand" "n")
12073                           (match_operand:SI 3 "immediate_operand" "n")
12074                           (match_operand:SI 4 "immediate_operand" "n")
12075                           (match_operand:SI 5 "immediate_operand" "n")] MRCI))]
12076   "arm_coproc_builtin_available (VUNSPEC_<MRC>)"
12078   arm_const_bounds (operands[1], 0, 16);
12079   arm_const_bounds (operands[2], 0, 8);
12080   arm_const_bounds (operands[3], 0, (1 << 5));
12081   arm_const_bounds (operands[4], 0, (1 << 5));
12082   arm_const_bounds (operands[5], 0, 8);
12083   return "<mrc>\\tp%c1, %2, %0, CR%c3, CR%c4, %5";
12085   [(set_attr "length" "4")
12086    (set_attr "type" "coproc")])
12088 (define_insn "<mcrr>"
12089   [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "n")
12090                      (match_operand:SI 1 "immediate_operand" "n")
12091                      (match_operand:DI 2 "s_register_operand" "r")
12092                      (match_operand:SI 3 "immediate_operand" "n")] MCRRI)
12093    (use (match_dup 2))]
12094   "arm_coproc_builtin_available (VUNSPEC_<MCRR>)"
12096   arm_const_bounds (operands[0], 0, 16);
12097   arm_const_bounds (operands[1], 0, 8);
12098   arm_const_bounds (operands[3], 0, (1 << 5));
12099   return "<mcrr>\\tp%c0, %1, %Q2, %R2, CR%c3";
12101   [(set_attr "length" "4")
12102    (set_attr "type" "coproc")])
12104 (define_insn "<mrrc>"
12105   [(set (match_operand:DI 0 "s_register_operand" "=r")
12106         (unspec_volatile:DI [(match_operand:SI 1 "immediate_operand" "n")
12107                           (match_operand:SI 2 "immediate_operand" "n")
12108                           (match_operand:SI 3 "immediate_operand" "n")] MRRCI))]
12109   "arm_coproc_builtin_available (VUNSPEC_<MRRC>)"
12111   arm_const_bounds (operands[1], 0, 16);
12112   arm_const_bounds (operands[2], 0, 8);
12113   arm_const_bounds (operands[3], 0, (1 << 5));
12114   return "<mrrc>\\tp%c1, %2, %Q0, %R0, CR%c3";
12116   [(set_attr "length" "4")
12117    (set_attr "type" "coproc")])
12119 ;; Vector bits common to IWMMXT and Neon
12120 (include "vec-common.md")
12121 ;; Load the Intel Wireless Multimedia Extension patterns
12122 (include "iwmmxt.md")
12123 ;; Load the VFP co-processor patterns
12124 (include "vfp.md")
12125 ;; Thumb-1 patterns
12126 (include "thumb1.md")
12127 ;; Thumb-2 patterns
12128 (include "thumb2.md")
12129 ;; Neon patterns
12130 (include "neon.md")
12131 ;; Crypto patterns
12132 (include "crypto.md")
12133 ;; Synchronization Primitives
12134 (include "sync.md")
12135 ;; Fixed-point patterns
12136 (include "arm-fixed.md")