[ARM] PR 67591 ARM v8 Thumb IT blocks are deprecated part 2
[official-gcc.git] / gcc / config / arm / arm.md
blob7f6f0d24de9187a376a0d199036bdeb9386cb86b
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,load_4")
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" "store_4")]
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" "store_4")]
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" "store_4")]
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       /* Ideally we should use iwmmxt here if we could know that operands[1]
4063          ends up already living in an iwmmxt register. Otherwise it's
4064          cheaper to have the alternate code being generated than moving
4065          values to iwmmxt regs and back.  */
4067       /* Expand operation using core-registers.
4068          'FAIL' would achieve the same thing, but this is a bit smarter.  */
4069       scratch1 = gen_reg_rtx (SImode);
4070       scratch2 = gen_reg_rtx (SImode);
4071       arm_emit_coreregs_64bit_shift (ASHIFT, operands[0], operands[1],
4072                                      operands[2], scratch1, scratch2);
4073       DONE;
4074     }
4075   "
4078 (define_expand "ashlsi3"
4079   [(set (match_operand:SI            0 "s_register_operand" "")
4080         (ashift:SI (match_operand:SI 1 "s_register_operand" "")
4081                    (match_operand:SI 2 "arm_rhs_operand" "")))]
4082   "TARGET_EITHER"
4083   "
4084   if (CONST_INT_P (operands[2])
4085       && (UINTVAL (operands[2])) > 31)
4086     {
4087       emit_insn (gen_movsi (operands[0], const0_rtx));
4088       DONE;
4089     }
4090   "
4093 (define_expand "ashrdi3"
4094   [(set (match_operand:DI              0 "s_register_operand" "")
4095         (ashiftrt:DI (match_operand:DI 1 "s_register_operand" "")
4096                      (match_operand:SI 2 "reg_or_int_operand" "")))]
4097   "TARGET_32BIT"
4098   "
4099   if (TARGET_NEON)
4100     {
4101       /* Delay the decision whether to use NEON or core-regs until
4102          register allocation.  */
4103       emit_insn (gen_ashrdi3_neon (operands[0], operands[1], operands[2]));
4104       DONE;
4105     }
4107   if (!CONST_INT_P (operands[2]) && TARGET_REALLY_IWMMXT)
4108     ; /* No special preparation statements; expand pattern as above.  */
4109   else
4110     {
4111       rtx scratch1, scratch2;
4113       /* Ideally we should use iwmmxt here if we could know that operands[1]
4114          ends up already living in an iwmmxt register. Otherwise it's
4115          cheaper to have the alternate code being generated than moving
4116          values to iwmmxt regs and back.  */
4118       /* Expand operation using core-registers.
4119          'FAIL' would achieve the same thing, but this is a bit smarter.  */
4120       scratch1 = gen_reg_rtx (SImode);
4121       scratch2 = gen_reg_rtx (SImode);
4122       arm_emit_coreregs_64bit_shift (ASHIFTRT, operands[0], operands[1],
4123                                      operands[2], scratch1, scratch2);
4124       DONE;
4125     }
4126   "
4129 (define_expand "ashrsi3"
4130   [(set (match_operand:SI              0 "s_register_operand" "")
4131         (ashiftrt:SI (match_operand:SI 1 "s_register_operand" "")
4132                      (match_operand:SI 2 "arm_rhs_operand" "")))]
4133   "TARGET_EITHER"
4134   "
4135   if (CONST_INT_P (operands[2])
4136       && UINTVAL (operands[2]) > 31)
4137     operands[2] = GEN_INT (31);
4138   "
4141 (define_expand "lshrdi3"
4142   [(set (match_operand:DI              0 "s_register_operand" "")
4143         (lshiftrt:DI (match_operand:DI 1 "s_register_operand" "")
4144                      (match_operand:SI 2 "reg_or_int_operand" "")))]
4145   "TARGET_32BIT"
4146   "
4147   if (TARGET_NEON)
4148     {
4149       /* Delay the decision whether to use NEON or core-regs until
4150          register allocation.  */
4151       emit_insn (gen_lshrdi3_neon (operands[0], operands[1], operands[2]));
4152       DONE;
4153     }
4155   if (!CONST_INT_P (operands[2]) && TARGET_REALLY_IWMMXT)
4156     ; /* No special preparation statements; expand pattern as above.  */
4157   else
4158     {
4159       rtx scratch1, scratch2;
4161       /* Ideally we should use iwmmxt here if we could know that operands[1]
4162          ends up already living in an iwmmxt register. Otherwise it's
4163          cheaper to have the alternate code being generated than moving
4164          values to iwmmxt regs and back.  */
4166       /* Expand operation using core-registers.
4167          'FAIL' would achieve the same thing, but this is a bit smarter.  */
4168       scratch1 = gen_reg_rtx (SImode);
4169       scratch2 = gen_reg_rtx (SImode);
4170       arm_emit_coreregs_64bit_shift (LSHIFTRT, operands[0], operands[1],
4171                                      operands[2], scratch1, scratch2);
4172       DONE;
4173     }
4174   "
4177 (define_expand "lshrsi3"
4178   [(set (match_operand:SI              0 "s_register_operand" "")
4179         (lshiftrt:SI (match_operand:SI 1 "s_register_operand" "")
4180                      (match_operand:SI 2 "arm_rhs_operand" "")))]
4181   "TARGET_EITHER"
4182   "
4183   if (CONST_INT_P (operands[2])
4184       && (UINTVAL (operands[2])) > 31)
4185     {
4186       emit_insn (gen_movsi (operands[0], const0_rtx));
4187       DONE;
4188     }
4189   "
4192 (define_expand "rotlsi3"
4193   [(set (match_operand:SI              0 "s_register_operand" "")
4194         (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
4195                      (match_operand:SI 2 "reg_or_int_operand" "")))]
4196   "TARGET_32BIT"
4197   "
4198   if (CONST_INT_P (operands[2]))
4199     operands[2] = GEN_INT ((32 - INTVAL (operands[2])) % 32);
4200   else
4201     {
4202       rtx reg = gen_reg_rtx (SImode);
4203       emit_insn (gen_subsi3 (reg, GEN_INT (32), operands[2]));
4204       operands[2] = reg;
4205     }
4206   "
4209 (define_expand "rotrsi3"
4210   [(set (match_operand:SI              0 "s_register_operand" "")
4211         (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
4212                      (match_operand:SI 2 "arm_rhs_operand" "")))]
4213   "TARGET_EITHER"
4214   "
4215   if (TARGET_32BIT)
4216     {
4217       if (CONST_INT_P (operands[2])
4218           && UINTVAL (operands[2]) > 31)
4219         operands[2] = GEN_INT (INTVAL (operands[2]) % 32);
4220     }
4221   else /* TARGET_THUMB1 */
4222     {
4223       if (CONST_INT_P (operands [2]))
4224         operands [2] = force_reg (SImode, operands[2]);
4225     }
4226   "
4229 (define_insn "*arm_shiftsi3"
4230   [(set (match_operand:SI   0 "s_register_operand" "=l,l,r,r")
4231         (match_operator:SI  3 "shift_operator"
4232          [(match_operand:SI 1 "s_register_operand"  "0,l,r,r")
4233           (match_operand:SI 2 "reg_or_int_operand" "l,M,M,r")]))]
4234   "TARGET_32BIT"
4235   "* return arm_output_shift(operands, 0);"
4236   [(set_attr "predicable" "yes")
4237    (set_attr "arch" "t2,t2,*,*")
4238    (set_attr "predicable_short_it" "yes,yes,no,no")
4239    (set_attr "length" "4")
4240    (set_attr "shift" "1")
4241    (set_attr "type" "alu_shift_reg,alu_shift_imm,alu_shift_imm,alu_shift_reg")]
4244 (define_insn "*shiftsi3_compare0"
4245   [(set (reg:CC_NOOV CC_REGNUM)
4246         (compare:CC_NOOV (match_operator:SI 3 "shift_operator"
4247                           [(match_operand:SI 1 "s_register_operand" "r,r")
4248                            (match_operand:SI 2 "arm_rhs_operand" "M,r")])
4249                          (const_int 0)))
4250    (set (match_operand:SI 0 "s_register_operand" "=r,r")
4251         (match_op_dup 3 [(match_dup 1) (match_dup 2)]))]
4252   "TARGET_32BIT"
4253   "* return arm_output_shift(operands, 1);"
4254   [(set_attr "conds" "set")
4255    (set_attr "shift" "1")
4256    (set_attr "type" "alus_shift_imm,alus_shift_reg")]
4259 (define_insn "*shiftsi3_compare0_scratch"
4260   [(set (reg:CC_NOOV CC_REGNUM)
4261         (compare:CC_NOOV (match_operator:SI 3 "shift_operator"
4262                           [(match_operand:SI 1 "s_register_operand" "r,r")
4263                            (match_operand:SI 2 "arm_rhs_operand" "M,r")])
4264                          (const_int 0)))
4265    (clobber (match_scratch:SI 0 "=r,r"))]
4266   "TARGET_32BIT"
4267   "* return arm_output_shift(operands, 1);"
4268   [(set_attr "conds" "set")
4269    (set_attr "shift" "1")
4270    (set_attr "type" "shift_imm,shift_reg")]
4273 (define_insn "*not_shiftsi"
4274   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4275         (not:SI (match_operator:SI 3 "shift_operator"
4276                  [(match_operand:SI 1 "s_register_operand" "r,r")
4277                   (match_operand:SI 2 "shift_amount_operand" "M,rM")])))]
4278   "TARGET_32BIT"
4279   "mvn%?\\t%0, %1%S3"
4280   [(set_attr "predicable" "yes")
4281    (set_attr "predicable_short_it" "no")
4282    (set_attr "shift" "1")
4283    (set_attr "arch" "32,a")
4284    (set_attr "type" "mvn_shift,mvn_shift_reg")])
4286 (define_insn "*not_shiftsi_compare0"
4287   [(set (reg:CC_NOOV CC_REGNUM)
4288         (compare:CC_NOOV
4289          (not:SI (match_operator:SI 3 "shift_operator"
4290                   [(match_operand:SI 1 "s_register_operand" "r,r")
4291                    (match_operand:SI 2 "shift_amount_operand" "M,rM")]))
4292          (const_int 0)))
4293    (set (match_operand:SI 0 "s_register_operand" "=r,r")
4294         (not:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])))]
4295   "TARGET_32BIT"
4296   "mvns%?\\t%0, %1%S3"
4297   [(set_attr "conds" "set")
4298    (set_attr "shift" "1")
4299    (set_attr "arch" "32,a")
4300    (set_attr "type" "mvn_shift,mvn_shift_reg")])
4302 (define_insn "*not_shiftsi_compare0_scratch"
4303   [(set (reg:CC_NOOV CC_REGNUM)
4304         (compare:CC_NOOV
4305          (not:SI (match_operator:SI 3 "shift_operator"
4306                   [(match_operand:SI 1 "s_register_operand" "r,r")
4307                    (match_operand:SI 2 "shift_amount_operand" "M,rM")]))
4308          (const_int 0)))
4309    (clobber (match_scratch:SI 0 "=r,r"))]
4310   "TARGET_32BIT"
4311   "mvns%?\\t%0, %1%S3"
4312   [(set_attr "conds" "set")
4313    (set_attr "shift" "1")
4314    (set_attr "arch" "32,a")
4315    (set_attr "type" "mvn_shift,mvn_shift_reg")])
4317 ;; We don't really have extzv, but defining this using shifts helps
4318 ;; to reduce register pressure later on.
4320 (define_expand "extzv"
4321   [(set (match_operand 0 "s_register_operand" "")
4322         (zero_extract (match_operand 1 "nonimmediate_operand" "")
4323                       (match_operand 2 "const_int_operand" "")
4324                       (match_operand 3 "const_int_operand" "")))]
4325   "TARGET_THUMB1 || arm_arch_thumb2"
4326   "
4327   {
4328     HOST_WIDE_INT lshift = 32 - INTVAL (operands[2]) - INTVAL (operands[3]);
4329     HOST_WIDE_INT rshift = 32 - INTVAL (operands[2]);
4330     
4331     if (arm_arch_thumb2)
4332       {
4333         HOST_WIDE_INT width = INTVAL (operands[2]);
4334         HOST_WIDE_INT bitpos = INTVAL (operands[3]);
4336         if (unaligned_access && MEM_P (operands[1])
4337             && (width == 16 || width == 32) && (bitpos % BITS_PER_UNIT) == 0)
4338           {
4339             rtx base_addr;
4341             if (BYTES_BIG_ENDIAN)
4342               bitpos = GET_MODE_BITSIZE (GET_MODE (operands[0])) - width
4343                        - bitpos;
4345             if (width == 32)
4346               {
4347                 base_addr = adjust_address (operands[1], SImode,
4348                                             bitpos / BITS_PER_UNIT);
4349                 emit_insn (gen_unaligned_loadsi (operands[0], base_addr));
4350               }
4351             else
4352               {
4353                 rtx dest = operands[0];
4354                 rtx tmp = gen_reg_rtx (SImode);
4356                 /* We may get a paradoxical subreg here.  Strip it off.  */
4357                 if (GET_CODE (dest) == SUBREG
4358                     && GET_MODE (dest) == SImode
4359                     && GET_MODE (SUBREG_REG (dest)) == HImode)
4360                   dest = SUBREG_REG (dest);
4362                 if (GET_MODE_BITSIZE (GET_MODE (dest)) != width)
4363                   FAIL;
4365                 base_addr = adjust_address (operands[1], HImode,
4366                                             bitpos / BITS_PER_UNIT);
4367                 emit_insn (gen_unaligned_loadhiu (tmp, base_addr));
4368                 emit_move_insn (gen_lowpart (SImode, dest), tmp);
4369               }
4370             DONE;
4371           }
4372         else if (s_register_operand (operands[1], GET_MODE (operands[1])))
4373           {
4374             emit_insn (gen_extzv_t2 (operands[0], operands[1], operands[2],
4375                                      operands[3]));
4376             DONE;
4377           }
4378         else
4379           FAIL;
4380       }
4381     
4382     if (!s_register_operand (operands[1], GET_MODE (operands[1])))
4383       FAIL;
4385     operands[3] = GEN_INT (rshift);
4386     
4387     if (lshift == 0)
4388       {
4389         emit_insn (gen_lshrsi3 (operands[0], operands[1], operands[3]));
4390         DONE;
4391       }
4392       
4393     emit_insn (gen_extzv_t1 (operands[0], operands[1], GEN_INT (lshift),
4394                              operands[3], gen_reg_rtx (SImode)));
4395     DONE;
4396   }"
4399 ;; Helper for extzv, for the Thumb-1 register-shifts case.
4401 (define_expand "extzv_t1"
4402   [(set (match_operand:SI 4 "s_register_operand" "")
4403         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
4404                    (match_operand:SI 2 "const_int_operand" "")))
4405    (set (match_operand:SI 0 "s_register_operand" "")
4406         (lshiftrt:SI (match_dup 4)
4407                      (match_operand:SI 3 "const_int_operand" "")))]
4408   "TARGET_THUMB1"
4409   "")
4411 (define_expand "extv"
4412   [(set (match_operand 0 "s_register_operand" "")
4413         (sign_extract (match_operand 1 "nonimmediate_operand" "")
4414                       (match_operand 2 "const_int_operand" "")
4415                       (match_operand 3 "const_int_operand" "")))]
4416   "arm_arch_thumb2"
4418   HOST_WIDE_INT width = INTVAL (operands[2]);
4419   HOST_WIDE_INT bitpos = INTVAL (operands[3]);
4421   if (unaligned_access && MEM_P (operands[1]) && (width == 16 || width == 32)
4422       && (bitpos % BITS_PER_UNIT)  == 0)
4423     {
4424       rtx base_addr;
4425       
4426       if (BYTES_BIG_ENDIAN)
4427         bitpos = GET_MODE_BITSIZE (GET_MODE (operands[0])) - width - bitpos;
4428       
4429       if (width == 32)
4430         {
4431           base_addr = adjust_address (operands[1], SImode,
4432                                       bitpos / BITS_PER_UNIT);
4433           emit_insn (gen_unaligned_loadsi (operands[0], base_addr));
4434         }
4435       else
4436         {
4437           rtx dest = operands[0];
4438           rtx tmp = gen_reg_rtx (SImode);
4439           
4440           /* We may get a paradoxical subreg here.  Strip it off.  */
4441           if (GET_CODE (dest) == SUBREG
4442               && GET_MODE (dest) == SImode
4443               && GET_MODE (SUBREG_REG (dest)) == HImode)
4444             dest = SUBREG_REG (dest);
4445           
4446           if (GET_MODE_BITSIZE (GET_MODE (dest)) != width)
4447             FAIL;
4448           
4449           base_addr = adjust_address (operands[1], HImode,
4450                                       bitpos / BITS_PER_UNIT);
4451           emit_insn (gen_unaligned_loadhis (tmp, base_addr));
4452           emit_move_insn (gen_lowpart (SImode, dest), tmp);
4453         }
4455       DONE;
4456     }
4457   else if (!s_register_operand (operands[1], GET_MODE (operands[1])))
4458     FAIL;
4459   else if (GET_MODE (operands[0]) == SImode
4460            && GET_MODE (operands[1]) == SImode)
4461     {
4462       emit_insn (gen_extv_regsi (operands[0], operands[1], operands[2],
4463                                  operands[3]));
4464       DONE;
4465     }
4467   FAIL;
4470 ; Helper to expand register forms of extv with the proper modes.
4472 (define_expand "extv_regsi"
4473   [(set (match_operand:SI 0 "s_register_operand" "")
4474         (sign_extract:SI (match_operand:SI 1 "s_register_operand" "")
4475                          (match_operand 2 "const_int_operand" "")
4476                          (match_operand 3 "const_int_operand" "")))]
4477   ""
4481 ; ARMv6+ unaligned load/store instructions (used for packed structure accesses).
4483 (define_insn "unaligned_loadsi"
4484   [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4485         (unspec:SI [(match_operand:SI 1 "memory_operand" "Uw,m")]
4486                    UNSPEC_UNALIGNED_LOAD))]
4487   "unaligned_access"
4488   "ldr%?\t%0, %1\t@ unaligned"
4489   [(set_attr "arch" "t2,any")
4490    (set_attr "length" "2,4")
4491    (set_attr "predicable" "yes")
4492    (set_attr "predicable_short_it" "yes,no")
4493    (set_attr "type" "load_4")])
4495 (define_insn "unaligned_loadhis"
4496   [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4497         (sign_extend:SI
4498           (unspec:HI [(match_operand:HI 1 "memory_operand" "Uw,Uh")]
4499                      UNSPEC_UNALIGNED_LOAD)))]
4500   "unaligned_access"
4501   "ldrsh%?\t%0, %1\t@ unaligned"
4502   [(set_attr "arch" "t2,any")
4503    (set_attr "length" "2,4")
4504    (set_attr "predicable" "yes")
4505    (set_attr "predicable_short_it" "yes,no")
4506    (set_attr "type" "load_byte")])
4508 (define_insn "unaligned_loadhiu"
4509   [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4510         (zero_extend:SI
4511           (unspec:HI [(match_operand:HI 1 "memory_operand" "Uw,m")]
4512                      UNSPEC_UNALIGNED_LOAD)))]
4513   "unaligned_access"
4514   "ldrh%?\t%0, %1\t@ unaligned"
4515   [(set_attr "arch" "t2,any")
4516    (set_attr "length" "2,4")
4517    (set_attr "predicable" "yes")
4518    (set_attr "predicable_short_it" "yes,no")
4519    (set_attr "type" "load_byte")])
4521 (define_insn "unaligned_storesi"
4522   [(set (match_operand:SI 0 "memory_operand" "=Uw,m")
4523         (unspec:SI [(match_operand:SI 1 "s_register_operand" "l,r")]
4524                    UNSPEC_UNALIGNED_STORE))]
4525   "unaligned_access"
4526   "str%?\t%1, %0\t@ unaligned"
4527   [(set_attr "arch" "t2,any")
4528    (set_attr "length" "2,4")
4529    (set_attr "predicable" "yes")
4530    (set_attr "predicable_short_it" "yes,no")
4531    (set_attr "type" "store_4")])
4533 (define_insn "unaligned_storehi"
4534   [(set (match_operand:HI 0 "memory_operand" "=Uw,m")
4535         (unspec:HI [(match_operand:HI 1 "s_register_operand" "l,r")]
4536                    UNSPEC_UNALIGNED_STORE))]
4537   "unaligned_access"
4538   "strh%?\t%1, %0\t@ unaligned"
4539   [(set_attr "arch" "t2,any")
4540    (set_attr "length" "2,4")
4541    (set_attr "predicable" "yes")
4542    (set_attr "predicable_short_it" "yes,no")
4543    (set_attr "type" "store_4")])
4546 (define_insn "*extv_reg"
4547   [(set (match_operand:SI 0 "s_register_operand" "=r")
4548         (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
4549                           (match_operand:SI 2 "const_int_operand" "n")
4550                           (match_operand:SI 3 "const_int_operand" "n")))]
4551   "arm_arch_thumb2
4552    && IN_RANGE (INTVAL (operands[3]), 0, 31)
4553    && IN_RANGE (INTVAL (operands[2]), 1, 32 - INTVAL (operands[3]))"
4554   "sbfx%?\t%0, %1, %3, %2"
4555   [(set_attr "length" "4")
4556    (set_attr "predicable" "yes")
4557    (set_attr "predicable_short_it" "no")
4558    (set_attr "type" "bfm")]
4561 (define_insn "extzv_t2"
4562   [(set (match_operand:SI 0 "s_register_operand" "=r")
4563         (zero_extract:SI (match_operand:SI 1 "s_register_operand" "r")
4564                           (match_operand:SI 2 "const_int_operand" "n")
4565                           (match_operand:SI 3 "const_int_operand" "n")))]
4566   "arm_arch_thumb2
4567    && IN_RANGE (INTVAL (operands[3]), 0, 31)
4568    && IN_RANGE (INTVAL (operands[2]), 1, 32 - INTVAL (operands[3]))"
4569   "ubfx%?\t%0, %1, %3, %2"
4570   [(set_attr "length" "4")
4571    (set_attr "predicable" "yes")
4572    (set_attr "predicable_short_it" "no")
4573    (set_attr "type" "bfm")]
4577 ;; Division instructions
4578 (define_insn "divsi3"
4579   [(set (match_operand:SI         0 "s_register_operand" "=r,r")
4580         (div:SI (match_operand:SI 1 "s_register_operand"  "r,r")
4581                 (match_operand:SI 2 "s_register_operand"  "r,r")))]
4582   "TARGET_IDIV"
4583   "@
4584    sdiv%?\t%0, %1, %2
4585    sdiv\t%0, %1, %2"
4586   [(set_attr "arch" "32,v8mb")
4587    (set_attr "predicable" "yes")
4588    (set_attr "predicable_short_it" "no")
4589    (set_attr "type" "sdiv")]
4592 (define_insn "udivsi3"
4593   [(set (match_operand:SI          0 "s_register_operand" "=r,r")
4594         (udiv:SI (match_operand:SI 1 "s_register_operand"  "r,r")
4595                  (match_operand:SI 2 "s_register_operand"  "r,r")))]
4596   "TARGET_IDIV"
4597   "@
4598    udiv%?\t%0, %1, %2
4599    udiv\t%0, %1, %2"
4600   [(set_attr "arch" "32,v8mb")
4601    (set_attr "predicable" "yes")
4602    (set_attr "predicable_short_it" "no")
4603    (set_attr "type" "udiv")]
4607 ;; Unary arithmetic insns
4609 (define_expand "negvsi3"
4610   [(match_operand:SI 0 "register_operand")
4611    (match_operand:SI 1 "register_operand")
4612    (match_operand 2 "")]
4613   "TARGET_32BIT"
4615   emit_insn (gen_subsi3_compare (operands[0], const0_rtx, operands[1]));
4616   arm_gen_unlikely_cbranch (NE, CC_Vmode, operands[2]);
4618   DONE;
4621 (define_expand "negvdi3"
4622   [(match_operand:DI 0 "register_operand")
4623    (match_operand:DI 1 "register_operand")
4624    (match_operand 2 "")]
4625   "TARGET_ARM"
4627   emit_insn (gen_negdi2_compare (operands[0], operands[1]));
4628   arm_gen_unlikely_cbranch (NE, CC_Vmode, operands[2]);
4630   DONE;
4634 (define_insn_and_split "negdi2_compare"
4635   [(set (reg:CC CC_REGNUM)
4636         (compare:CC
4637           (const_int 0)
4638           (match_operand:DI 1 "register_operand" "0,r")))
4639    (set (match_operand:DI 0 "register_operand" "=r,&r")
4640         (minus:DI (const_int 0) (match_dup 1)))]
4641   "TARGET_ARM"
4642   "#"
4643   "&& reload_completed"
4644   [(parallel [(set (reg:CC CC_REGNUM)
4645                    (compare:CC (const_int 0) (match_dup 1)))
4646               (set (match_dup 0) (minus:SI (const_int 0)
4647                                            (match_dup 1)))])
4648    (parallel [(set (reg:CC CC_REGNUM)
4649                    (compare:CC (const_int 0) (match_dup 3)))
4650              (set (match_dup 2)
4651                   (minus:SI
4652                    (minus:SI (const_int 0) (match_dup 3))
4653                    (ltu:SI (reg:CC_C CC_REGNUM)
4654                            (const_int 0))))])]
4655   {
4656     operands[2] = gen_highpart (SImode, operands[0]);
4657     operands[0] = gen_lowpart (SImode, operands[0]);
4658     operands[3] = gen_highpart (SImode, operands[1]);
4659     operands[1] = gen_lowpart (SImode, operands[1]);
4660   }
4661   [(set_attr "conds" "set")
4662    (set_attr "length" "8")
4663    (set_attr "type" "multiple")]
4666 (define_expand "negdi2"
4667  [(parallel
4668    [(set (match_operand:DI 0 "s_register_operand" "")
4669          (neg:DI (match_operand:DI 1 "s_register_operand" "")))
4670     (clobber (reg:CC CC_REGNUM))])]
4671   "TARGET_EITHER"
4672   {
4673     if (TARGET_NEON)
4674       {
4675         emit_insn (gen_negdi2_neon (operands[0], operands[1]));
4676         DONE;
4677       }
4678   }
4681 ;; The constraints here are to prevent a *partial* overlap (where %Q0 == %R1).
4682 ;; The first alternative allows the common case of a *full* overlap.
4683 (define_insn_and_split "*negdi2_insn"
4684   [(set (match_operand:DI         0 "s_register_operand" "=r,&r")
4685         (neg:DI (match_operand:DI 1 "s_register_operand"  "0,r")))
4686    (clobber (reg:CC CC_REGNUM))]
4687   "TARGET_32BIT"
4688   "#"   ; rsbs %Q0, %Q1, #0; rsc %R0, %R1, #0          (ARM)
4689         ; negs %Q0, %Q1    ; sbc %R0, %R1, %R1, lsl #1 (Thumb-2)
4690   "&& reload_completed"
4691   [(parallel [(set (reg:CC CC_REGNUM)
4692                    (compare:CC (const_int 0) (match_dup 1)))
4693               (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1)))])
4694    (set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3))
4695                                 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
4696   {
4697     operands[2] = gen_highpart (SImode, operands[0]);
4698     operands[0] = gen_lowpart (SImode, operands[0]);
4699     operands[3] = gen_highpart (SImode, operands[1]);
4700     operands[1] = gen_lowpart (SImode, operands[1]);
4701   }
4702   [(set_attr "conds" "clob")
4703    (set_attr "length" "8")
4704    (set_attr "type" "multiple")]
4707 (define_insn "*negsi2_carryin_compare"
4708   [(set (reg:CC CC_REGNUM)
4709         (compare:CC (const_int 0)
4710                     (match_operand:SI 1 "s_register_operand" "r")))
4711    (set (match_operand:SI 0 "s_register_operand" "=r")
4712         (minus:SI (minus:SI (const_int 0)
4713                             (match_dup 1))
4714                   (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
4715   "TARGET_ARM"
4716   "rscs\\t%0, %1, #0"
4717   [(set_attr "conds" "set")
4718    (set_attr "type" "alus_imm")]
4721 (define_expand "negsi2"
4722   [(set (match_operand:SI         0 "s_register_operand" "")
4723         (neg:SI (match_operand:SI 1 "s_register_operand" "")))]
4724   "TARGET_EITHER"
4725   ""
4728 (define_insn "*arm_negsi2"
4729   [(set (match_operand:SI         0 "s_register_operand" "=l,r")
4730         (neg:SI (match_operand:SI 1 "s_register_operand" "l,r")))]
4731   "TARGET_32BIT"
4732   "rsb%?\\t%0, %1, #0"
4733   [(set_attr "predicable" "yes")
4734    (set_attr "predicable_short_it" "yes,no")
4735    (set_attr "arch" "t2,*")
4736    (set_attr "length" "4")
4737    (set_attr "type" "alu_sreg")]
4740 (define_expand "negsf2"
4741   [(set (match_operand:SF         0 "s_register_operand" "")
4742         (neg:SF (match_operand:SF 1 "s_register_operand" "")))]
4743   "TARGET_32BIT && TARGET_HARD_FLOAT"
4744   ""
4747 (define_expand "negdf2"
4748   [(set (match_operand:DF         0 "s_register_operand" "")
4749         (neg:DF (match_operand:DF 1 "s_register_operand" "")))]
4750   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
4751   "")
4753 (define_insn_and_split "*zextendsidi_negsi"
4754   [(set (match_operand:DI 0 "s_register_operand" "=r")
4755         (zero_extend:DI (neg:SI (match_operand:SI 1 "s_register_operand" "r"))))]
4756    "TARGET_32BIT"
4757    "#"
4758    ""
4759    [(set (match_dup 2)
4760          (neg:SI (match_dup 1)))
4761     (set (match_dup 3)
4762          (const_int 0))]
4763    {
4764       operands[2] = gen_lowpart (SImode, operands[0]);
4765       operands[3] = gen_highpart (SImode, operands[0]);
4766    }
4767  [(set_attr "length" "8")
4768   (set_attr "type" "multiple")]
4771 ;; Negate an extended 32-bit value.
4772 (define_insn_and_split "*negdi_extendsidi"
4773   [(set (match_operand:DI 0 "s_register_operand" "=l,r")
4774         (neg:DI (sign_extend:DI
4775                  (match_operand:SI 1 "s_register_operand" "l,r"))))
4776    (clobber (reg:CC CC_REGNUM))]
4777   "TARGET_32BIT"
4778   "#"
4779   "&& reload_completed"
4780   [(const_int 0)]
4781   {
4782     rtx low = gen_lowpart (SImode, operands[0]);
4783     rtx high = gen_highpart (SImode, operands[0]);
4785     if (reg_overlap_mentioned_p (low, operands[1]))
4786       {
4787         /* Input overlaps the low word of the output.  Use:
4788                 asr     Rhi, Rin, #31
4789                 rsbs    Rlo, Rin, #0
4790                 rsc     Rhi, Rhi, #0 (thumb2: sbc Rhi, Rhi, Rhi, lsl #1).  */
4791         rtx cc_reg = gen_rtx_REG (CC_Cmode, CC_REGNUM);
4793         emit_insn (gen_rtx_SET (high,
4794                                 gen_rtx_ASHIFTRT (SImode, operands[1],
4795                                                   GEN_INT (31))));
4797         emit_insn (gen_subsi3_compare (low, const0_rtx, operands[1]));
4798         if (TARGET_ARM)
4799           emit_insn (gen_rtx_SET (high,
4800                                   gen_rtx_MINUS (SImode,
4801                                                  gen_rtx_MINUS (SImode,
4802                                                                 const0_rtx,
4803                                                                 high),
4804                                                  gen_rtx_LTU (SImode,
4805                                                               cc_reg,
4806                                                               const0_rtx))));
4807         else
4808           {
4809             rtx two_x = gen_rtx_ASHIFT (SImode, high, GEN_INT (1));
4810             emit_insn (gen_rtx_SET (high,
4811                                     gen_rtx_MINUS (SImode,
4812                                                    gen_rtx_MINUS (SImode,
4813                                                                   high,
4814                                                                   two_x),
4815                                                    gen_rtx_LTU (SImode,
4816                                                                 cc_reg,
4817                                                                 const0_rtx))));
4818           }
4819       }
4820     else
4821       {
4822         /* No overlap, or overlap on high word.  Use:
4823                 rsb     Rlo, Rin, #0
4824                 bic     Rhi, Rlo, Rin
4825                 asr     Rhi, Rhi, #31
4826            Flags not needed for this sequence.  */
4827         emit_insn (gen_rtx_SET (low, gen_rtx_NEG (SImode, operands[1])));
4828         emit_insn (gen_rtx_SET (high,
4829                                 gen_rtx_AND (SImode,
4830                                              gen_rtx_NOT (SImode, operands[1]),
4831                                              low)));
4832         emit_insn (gen_rtx_SET (high,
4833                                 gen_rtx_ASHIFTRT (SImode, high,
4834                                                   GEN_INT (31))));
4835       }
4836     DONE;
4837   }
4838   [(set_attr "length" "12")
4839    (set_attr "arch" "t2,*")
4840    (set_attr "type" "multiple")]
4843 (define_insn_and_split "*negdi_zero_extendsidi"
4844   [(set (match_operand:DI 0 "s_register_operand" "=r,&r")
4845         (neg:DI (zero_extend:DI (match_operand:SI 1 "s_register_operand" "0,r"))))
4846    (clobber (reg:CC CC_REGNUM))]
4847   "TARGET_32BIT"
4848   "#" ; "rsbs\\t%Q0, %1, #0\;sbc\\t%R0,%R0,%R0"
4849       ;; Don't care what register is input to sbc,
4850       ;; since we just need to propagate the carry.
4851   "&& reload_completed"
4852   [(parallel [(set (reg:CC CC_REGNUM)
4853                    (compare:CC (const_int 0) (match_dup 1)))
4854               (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1)))])
4855    (set (match_dup 2) (minus:SI (minus:SI (match_dup 2) (match_dup 2))
4856                                 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
4857   {
4858     operands[2] = gen_highpart (SImode, operands[0]);
4859     operands[0] = gen_lowpart (SImode, operands[0]);
4860   }
4861   [(set_attr "conds" "clob")
4862    (set_attr "length" "8")
4863    (set_attr "type" "multiple")]   ;; length in thumb is 4
4866 ;; abssi2 doesn't really clobber the condition codes if a different register
4867 ;; is being set.  To keep things simple, assume during rtl manipulations that
4868 ;; it does, but tell the final scan operator the truth.  Similarly for
4869 ;; (neg (abs...))
4871 (define_expand "abssi2"
4872   [(parallel
4873     [(set (match_operand:SI         0 "s_register_operand" "")
4874           (abs:SI (match_operand:SI 1 "s_register_operand" "")))
4875      (clobber (match_dup 2))])]
4876   "TARGET_EITHER"
4877   "
4878   if (TARGET_THUMB1)
4879     operands[2] = gen_rtx_SCRATCH (SImode);
4880   else
4881     operands[2] = gen_rtx_REG (CCmode, CC_REGNUM);
4884 (define_insn_and_split "*arm_abssi2"
4885   [(set (match_operand:SI 0 "s_register_operand" "=r,&r")
4886         (abs:SI (match_operand:SI 1 "s_register_operand" "0,r")))
4887    (clobber (reg:CC CC_REGNUM))]
4888   "TARGET_ARM"
4889   "#"
4890   "&& reload_completed"
4891   [(const_int 0)]
4892   {
4893    /* if (which_alternative == 0) */
4894    if (REGNO(operands[0]) == REGNO(operands[1]))
4895      {
4896       /* Emit the pattern:
4897          cmp\\t%0, #0\;rsblt\\t%0, %0, #0
4898          [(set (reg:CC CC_REGNUM)
4899                (compare:CC (match_dup 0) (const_int 0)))
4900           (cond_exec (lt:CC (reg:CC CC_REGNUM) (const_int 0))
4901                      (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1))))]
4902       */
4903       emit_insn (gen_rtx_SET (gen_rtx_REG (CCmode, CC_REGNUM),
4904                               gen_rtx_COMPARE (CCmode, operands[0], const0_rtx)));
4905       emit_insn (gen_rtx_COND_EXEC (VOIDmode,
4906                                     (gen_rtx_LT (SImode,
4907                                                  gen_rtx_REG (CCmode, CC_REGNUM),
4908                                                  const0_rtx)),
4909                                     (gen_rtx_SET (operands[0],
4910                                                   (gen_rtx_MINUS (SImode,
4911                                                                   const0_rtx,
4912                                                                   operands[1]))))));
4913       DONE;
4914      }
4915    else
4916      {
4917       /* Emit the pattern:
4918          alt1: eor%?\\t%0, %1, %1, asr #31\;sub%?\\t%0, %0, %1, asr #31
4919          [(set (match_dup 0)
4920                (xor:SI (match_dup 1)
4921                        (ashiftrt:SI (match_dup 1) (const_int 31))))
4922           (set (match_dup 0)
4923                (minus:SI (match_dup 0)
4924                       (ashiftrt:SI (match_dup 1) (const_int 31))))]
4925       */
4926       emit_insn (gen_rtx_SET (operands[0],
4927                               gen_rtx_XOR (SImode,
4928                                            gen_rtx_ASHIFTRT (SImode,
4929                                                              operands[1],
4930                                                              GEN_INT (31)),
4931                                            operands[1])));
4932       emit_insn (gen_rtx_SET (operands[0],
4933                               gen_rtx_MINUS (SImode,
4934                                              operands[0],
4935                                              gen_rtx_ASHIFTRT (SImode,
4936                                                                operands[1],
4937                                                                GEN_INT (31)))));
4938       DONE;
4939      }
4940   }
4941   [(set_attr "conds" "clob,*")
4942    (set_attr "shift" "1")
4943    (set_attr "predicable" "no, yes")
4944    (set_attr "length" "8")
4945    (set_attr "type" "multiple")]
4948 (define_insn_and_split "*arm_neg_abssi2"
4949   [(set (match_operand:SI 0 "s_register_operand" "=r,&r")
4950         (neg:SI (abs:SI (match_operand:SI 1 "s_register_operand" "0,r"))))
4951    (clobber (reg:CC CC_REGNUM))]
4952   "TARGET_ARM"
4953   "#"
4954   "&& reload_completed"
4955   [(const_int 0)]
4956   {
4957    /* if (which_alternative == 0) */
4958    if (REGNO (operands[0]) == REGNO (operands[1]))
4959      {
4960       /* Emit the pattern:
4961          cmp\\t%0, #0\;rsbgt\\t%0, %0, #0
4962       */
4963       emit_insn (gen_rtx_SET (gen_rtx_REG (CCmode, CC_REGNUM),
4964                               gen_rtx_COMPARE (CCmode, operands[0], const0_rtx)));
4965       emit_insn (gen_rtx_COND_EXEC (VOIDmode,
4966                                     gen_rtx_GT (SImode,
4967                                                 gen_rtx_REG (CCmode, CC_REGNUM),
4968                                                 const0_rtx),
4969                                     gen_rtx_SET (operands[0],
4970                                                  (gen_rtx_MINUS (SImode,
4971                                                                  const0_rtx,
4972                                                                  operands[1])))));
4973      }
4974    else
4975      {
4976       /* Emit the pattern:
4977          eor%?\\t%0, %1, %1, asr #31\;rsb%?\\t%0, %0, %1, asr #31
4978       */
4979       emit_insn (gen_rtx_SET (operands[0],
4980                               gen_rtx_XOR (SImode,
4981                                            gen_rtx_ASHIFTRT (SImode,
4982                                                              operands[1],
4983                                                              GEN_INT (31)),
4984                                            operands[1])));
4985       emit_insn (gen_rtx_SET (operands[0],
4986                               gen_rtx_MINUS (SImode,
4987                                              gen_rtx_ASHIFTRT (SImode,
4988                                                                operands[1],
4989                                                                GEN_INT (31)),
4990                                              operands[0])));
4991      }
4992    DONE;
4993   }
4994   [(set_attr "conds" "clob,*")
4995    (set_attr "shift" "1")
4996    (set_attr "predicable" "no, yes")
4997    (set_attr "length" "8")
4998    (set_attr "type" "multiple")]
5001 (define_expand "abssf2"
5002   [(set (match_operand:SF         0 "s_register_operand" "")
5003         (abs:SF (match_operand:SF 1 "s_register_operand" "")))]
5004   "TARGET_32BIT && TARGET_HARD_FLOAT"
5005   "")
5007 (define_expand "absdf2"
5008   [(set (match_operand:DF         0 "s_register_operand" "")
5009         (abs:DF (match_operand:DF 1 "s_register_operand" "")))]
5010   "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
5011   "")
5013 (define_expand "sqrtsf2"
5014   [(set (match_operand:SF 0 "s_register_operand" "")
5015         (sqrt:SF (match_operand:SF 1 "s_register_operand" "")))]
5016   "TARGET_32BIT && TARGET_HARD_FLOAT"
5017   "")
5019 (define_expand "sqrtdf2"
5020   [(set (match_operand:DF 0 "s_register_operand" "")
5021         (sqrt:DF (match_operand:DF 1 "s_register_operand" "")))]
5022   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
5023   "")
5025 (define_expand "one_cmpldi2"
5026   [(set (match_operand:DI 0 "s_register_operand" "")
5027         (not:DI (match_operand:DI 1 "s_register_operand" "")))]
5028   "TARGET_32BIT"
5029   "
5030   if (!TARGET_NEON && !TARGET_IWMMXT)
5031     {
5032       rtx low  = simplify_gen_unary (NOT, SImode,
5033                                      gen_lowpart (SImode, operands[1]),
5034                                      SImode);
5035       rtx high = simplify_gen_unary (NOT, SImode,
5036                                      gen_highpart_mode (SImode, DImode,
5037                                                         operands[1]),
5038                                      SImode);
5040       emit_insn (gen_rtx_SET (gen_lowpart (SImode, operands[0]), low));
5041       emit_insn (gen_rtx_SET (gen_highpart (SImode, operands[0]), high));
5043       DONE;
5044     }
5045   /* Otherwise expand pattern as above.  */
5046   "
5049 (define_insn_and_split "*one_cmpldi2_insn"
5050   [(set (match_operand:DI 0 "s_register_operand"         "=w,&r,&r,?w")
5051         (not:DI (match_operand:DI 1 "s_register_operand" " w, 0, r, w")))]
5052   "TARGET_32BIT"
5053   "@
5054    vmvn\t%P0, %P1
5055    #
5056    #
5057    vmvn\t%P0, %P1"
5058   "TARGET_32BIT && reload_completed
5059    && arm_general_register_operand (operands[0], DImode)"
5060   [(set (match_dup 0) (not:SI (match_dup 1)))
5061    (set (match_dup 2) (not:SI (match_dup 3)))]
5062   "
5063   {
5064     operands[2] = gen_highpart (SImode, operands[0]);
5065     operands[0] = gen_lowpart (SImode, operands[0]);
5066     operands[3] = gen_highpart (SImode, operands[1]);
5067     operands[1] = gen_lowpart (SImode, operands[1]);
5068   }"
5069   [(set_attr "length" "*,8,8,*")
5070    (set_attr "predicable" "no,yes,yes,no")
5071    (set_attr "type" "neon_move,multiple,multiple,neon_move")
5072    (set_attr "arch" "neon_for_64bits,*,*,avoid_neon_for_64bits")]
5075 (define_expand "one_cmplsi2"
5076   [(set (match_operand:SI         0 "s_register_operand" "")
5077         (not:SI (match_operand:SI 1 "s_register_operand" "")))]
5078   "TARGET_EITHER"
5079   ""
5082 (define_insn "*arm_one_cmplsi2"
5083   [(set (match_operand:SI         0 "s_register_operand" "=l,r")
5084         (not:SI (match_operand:SI 1 "s_register_operand"  "l,r")))]
5085   "TARGET_32BIT"
5086   "mvn%?\\t%0, %1"
5087   [(set_attr "predicable" "yes")
5088    (set_attr "predicable_short_it" "yes,no")
5089    (set_attr "arch" "t2,*")
5090    (set_attr "length" "4")
5091    (set_attr "type" "mvn_reg")]
5094 (define_insn "*notsi_compare0"
5095   [(set (reg:CC_NOOV CC_REGNUM)
5096         (compare:CC_NOOV (not:SI (match_operand:SI 1 "s_register_operand" "r"))
5097                          (const_int 0)))
5098    (set (match_operand:SI 0 "s_register_operand" "=r")
5099         (not:SI (match_dup 1)))]
5100   "TARGET_32BIT"
5101   "mvns%?\\t%0, %1"
5102   [(set_attr "conds" "set")
5103    (set_attr "type" "mvn_reg")]
5106 (define_insn "*notsi_compare0_scratch"
5107   [(set (reg:CC_NOOV CC_REGNUM)
5108         (compare:CC_NOOV (not:SI (match_operand:SI 1 "s_register_operand" "r"))
5109                          (const_int 0)))
5110    (clobber (match_scratch:SI 0 "=r"))]
5111   "TARGET_32BIT"
5112   "mvns%?\\t%0, %1"
5113   [(set_attr "conds" "set")
5114    (set_attr "type" "mvn_reg")]
5117 ;; Fixed <--> Floating conversion insns
5119 (define_expand "floatsihf2"
5120   [(set (match_operand:HF           0 "general_operand" "")
5121         (float:HF (match_operand:SI 1 "general_operand" "")))]
5122   "TARGET_EITHER"
5123   "
5124   {
5125     rtx op1 = gen_reg_rtx (SFmode);
5126     expand_float (op1, operands[1], 0);
5127     op1 = convert_to_mode (HFmode, op1, 0);
5128     emit_move_insn (operands[0], op1);
5129     DONE;
5130   }"
5133 (define_expand "floatdihf2"
5134   [(set (match_operand:HF           0 "general_operand" "")
5135         (float:HF (match_operand:DI 1 "general_operand" "")))]
5136   "TARGET_EITHER"
5137   "
5138   {
5139     rtx op1 = gen_reg_rtx (SFmode);
5140     expand_float (op1, operands[1], 0);
5141     op1 = convert_to_mode (HFmode, op1, 0);
5142     emit_move_insn (operands[0], op1);
5143     DONE;
5144   }"
5147 (define_expand "floatsisf2"
5148   [(set (match_operand:SF           0 "s_register_operand" "")
5149         (float:SF (match_operand:SI 1 "s_register_operand" "")))]
5150   "TARGET_32BIT && TARGET_HARD_FLOAT"
5151   "
5154 (define_expand "floatsidf2"
5155   [(set (match_operand:DF           0 "s_register_operand" "")
5156         (float:DF (match_operand:SI 1 "s_register_operand" "")))]
5157   "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
5158   "
5161 (define_expand "fix_trunchfsi2"
5162   [(set (match_operand:SI         0 "general_operand" "")
5163         (fix:SI (fix:HF (match_operand:HF 1 "general_operand"  ""))))]
5164   "TARGET_EITHER"
5165   "
5166   {
5167     rtx op1 = convert_to_mode (SFmode, operands[1], 0);
5168     expand_fix (operands[0], op1, 0);
5169     DONE;
5170   }"
5173 (define_expand "fix_trunchfdi2"
5174   [(set (match_operand:DI         0 "general_operand" "")
5175         (fix:DI (fix:HF (match_operand:HF 1 "general_operand"  ""))))]
5176   "TARGET_EITHER"
5177   "
5178   {
5179     rtx op1 = convert_to_mode (SFmode, operands[1], 0);
5180     expand_fix (operands[0], op1, 0);
5181     DONE;
5182   }"
5185 (define_expand "fix_truncsfsi2"
5186   [(set (match_operand:SI         0 "s_register_operand" "")
5187         (fix:SI (fix:SF (match_operand:SF 1 "s_register_operand"  ""))))]
5188   "TARGET_32BIT && TARGET_HARD_FLOAT"
5189   "
5192 (define_expand "fix_truncdfsi2"
5193   [(set (match_operand:SI         0 "s_register_operand" "")
5194         (fix:SI (fix:DF (match_operand:DF 1 "s_register_operand"  ""))))]
5195   "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
5196   "
5199 ;; Truncation insns
5201 (define_expand "truncdfsf2"
5202   [(set (match_operand:SF  0 "s_register_operand" "")
5203         (float_truncate:SF
5204          (match_operand:DF 1 "s_register_operand" "")))]
5205   "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
5206   ""
5209 ;; DFmode to HFmode conversions on targets without a single-step hardware
5210 ;; instruction for it would have to go through SFmode.  This is dangerous
5211 ;; as it introduces double rounding.
5213 ;; Disable this pattern unless we are in an unsafe math mode, or we have
5214 ;; a single-step instruction.
5216 (define_expand "truncdfhf2"
5217   [(set (match_operand:HF  0 "s_register_operand" "")
5218         (float_truncate:HF
5219          (match_operand:DF 1 "s_register_operand" "")))]
5220   "(TARGET_EITHER && flag_unsafe_math_optimizations)
5221    || (TARGET_32BIT && TARGET_FP16_TO_DOUBLE)"
5223   /* We don't have a direct instruction for this, so we must be in
5224      an unsafe math mode, and going via SFmode.  */
5226   if (!(TARGET_32BIT && TARGET_FP16_TO_DOUBLE))
5227     {
5228       rtx op1;
5229       op1 = convert_to_mode (SFmode, operands[1], 0);
5230       op1 = convert_to_mode (HFmode, op1, 0);
5231       emit_move_insn (operands[0], op1);
5232       DONE;
5233     }
5234   /* Otherwise, we will pick this up as a single instruction with
5235      no intermediary rounding.  */
5239 ;; Zero and sign extension instructions.
5241 (define_insn "zero_extend<mode>di2"
5242   [(set (match_operand:DI 0 "s_register_operand" "=w,r,?r,w")
5243         (zero_extend:DI (match_operand:QHSI 1 "<qhs_zextenddi_op>"
5244                                             "<qhs_zextenddi_cstr>")))]
5245   "TARGET_32BIT <qhs_zextenddi_cond>"
5246   "#"
5247   [(set_attr "length" "8,4,8,8")
5248    (set_attr "arch" "neon_for_64bits,*,*,avoid_neon_for_64bits")
5249    (set_attr "ce_count" "2")
5250    (set_attr "predicable" "yes")
5251    (set_attr "type" "multiple,mov_reg,multiple,multiple")]
5254 (define_insn "extend<mode>di2"
5255   [(set (match_operand:DI 0 "s_register_operand" "=w,r,?r,?r,w")
5256         (sign_extend:DI (match_operand:QHSI 1 "<qhs_extenddi_op>"
5257                                             "<qhs_extenddi_cstr>")))]
5258   "TARGET_32BIT <qhs_sextenddi_cond>"
5259   "#"
5260   [(set_attr "length" "8,4,8,8,8")
5261    (set_attr "ce_count" "2")
5262    (set_attr "shift" "1")
5263    (set_attr "predicable" "yes")
5264    (set_attr "arch" "neon_for_64bits,*,a,t,avoid_neon_for_64bits")
5265    (set_attr "type" "multiple,mov_reg,multiple,multiple,multiple")]
5268 ;; Splits for all extensions to DImode
5269 (define_split
5270   [(set (match_operand:DI 0 "s_register_operand" "")
5271         (zero_extend:DI (match_operand 1 "nonimmediate_operand" "")))]
5272   "TARGET_32BIT && reload_completed && !IS_VFP_REGNUM (REGNO (operands[0]))"
5273   [(set (match_dup 0) (match_dup 1))]
5275   rtx lo_part = gen_lowpart (SImode, operands[0]);
5276   machine_mode src_mode = GET_MODE (operands[1]);
5278   if (REG_P (operands[0])
5279       && !reg_overlap_mentioned_p (operands[0], operands[1]))
5280     emit_clobber (operands[0]);
5281   if (!REG_P (lo_part) || src_mode != SImode
5282       || !rtx_equal_p (lo_part, operands[1]))
5283     {
5284       if (src_mode == SImode)
5285         emit_move_insn (lo_part, operands[1]);
5286       else
5287         emit_insn (gen_rtx_SET (lo_part,
5288                                 gen_rtx_ZERO_EXTEND (SImode, operands[1])));
5289       operands[1] = lo_part;
5290     }
5291   operands[0] = gen_highpart (SImode, operands[0]);
5292   operands[1] = const0_rtx;
5295 (define_split
5296   [(set (match_operand:DI 0 "s_register_operand" "")
5297         (sign_extend:DI (match_operand 1 "nonimmediate_operand" "")))]
5298   "TARGET_32BIT && reload_completed && !IS_VFP_REGNUM (REGNO (operands[0]))"
5299   [(set (match_dup 0) (ashiftrt:SI (match_dup 1) (const_int 31)))]
5301   rtx lo_part = gen_lowpart (SImode, operands[0]);
5302   machine_mode src_mode = GET_MODE (operands[1]);
5304   if (REG_P (operands[0])
5305       && !reg_overlap_mentioned_p (operands[0], operands[1]))
5306     emit_clobber (operands[0]);
5308   if (!REG_P (lo_part) || src_mode != SImode
5309       || !rtx_equal_p (lo_part, operands[1]))
5310     {
5311       if (src_mode == SImode)
5312         emit_move_insn (lo_part, operands[1]);
5313       else
5314         emit_insn (gen_rtx_SET (lo_part,
5315                                 gen_rtx_SIGN_EXTEND (SImode, operands[1])));
5316       operands[1] = lo_part;
5317     }
5318   operands[0] = gen_highpart (SImode, operands[0]);
5321 (define_expand "zero_extendhisi2"
5322   [(set (match_operand:SI 0 "s_register_operand" "")
5323         (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
5324   "TARGET_EITHER"
5326   if (TARGET_ARM && !arm_arch4 && MEM_P (operands[1]))
5327     {
5328       emit_insn (gen_movhi_bytes (operands[0], operands[1]));
5329       DONE;
5330     }
5331   if (!arm_arch6 && !MEM_P (operands[1]))
5332     {
5333       rtx t = gen_lowpart (SImode, operands[1]);
5334       rtx tmp = gen_reg_rtx (SImode);
5335       emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (16)));
5336       emit_insn (gen_lshrsi3 (operands[0], tmp, GEN_INT (16)));
5337       DONE;
5338     }
5341 (define_split
5342   [(set (match_operand:SI 0 "s_register_operand" "")
5343         (zero_extend:SI (match_operand:HI 1 "s_register_operand" "")))]
5344   "!TARGET_THUMB2 && !arm_arch6"
5345   [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
5346    (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 16)))]
5348   operands[2] = gen_lowpart (SImode, operands[1]);
5351 (define_insn "*arm_zero_extendhisi2"
5352   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5353         (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
5354   "TARGET_ARM && arm_arch4 && !arm_arch6"
5355   "@
5356    #
5357    ldrh%?\\t%0, %1"
5358   [(set_attr "type" "alu_shift_reg,load_byte")
5359    (set_attr "predicable" "yes")]
5362 (define_insn "*arm_zero_extendhisi2_v6"
5363   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5364         (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,Uh")))]
5365   "TARGET_ARM && arm_arch6"
5366   "@
5367    uxth%?\\t%0, %1
5368    ldrh%?\\t%0, %1"
5369   [(set_attr "predicable" "yes")
5370    (set_attr "type" "extend,load_byte")]
5373 (define_insn "*arm_zero_extendhisi2addsi"
5374   [(set (match_operand:SI 0 "s_register_operand" "=r")
5375         (plus:SI (zero_extend:SI (match_operand:HI 1 "s_register_operand" "r"))
5376                  (match_operand:SI 2 "s_register_operand" "r")))]
5377   "TARGET_INT_SIMD"
5378   "uxtah%?\\t%0, %2, %1"
5379   [(set_attr "type" "alu_shift_reg")
5380    (set_attr "predicable" "yes")
5381    (set_attr "predicable_short_it" "no")]
5384 (define_expand "zero_extendqisi2"
5385   [(set (match_operand:SI 0 "s_register_operand" "")
5386         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))]
5387   "TARGET_EITHER"
5389   if (TARGET_ARM && !arm_arch6 && !MEM_P (operands[1]))
5390     {
5391       emit_insn (gen_andsi3 (operands[0],
5392                              gen_lowpart (SImode, operands[1]),
5393                                           GEN_INT (255)));
5394       DONE;
5395     }
5396   if (!arm_arch6 && !MEM_P (operands[1]))
5397     {
5398       rtx t = gen_lowpart (SImode, operands[1]);
5399       rtx tmp = gen_reg_rtx (SImode);
5400       emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (24)));
5401       emit_insn (gen_lshrsi3 (operands[0], tmp, GEN_INT (24)));
5402       DONE;
5403     }
5406 (define_split
5407   [(set (match_operand:SI 0 "s_register_operand" "")
5408         (zero_extend:SI (match_operand:QI 1 "s_register_operand" "")))]
5409   "!arm_arch6"
5410   [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 24)))
5411    (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 24)))]
5413   operands[2] = simplify_gen_subreg (SImode, operands[1], QImode, 0);
5414   if (TARGET_ARM)
5415     {
5416       emit_insn (gen_andsi3 (operands[0], operands[2], GEN_INT (255)));
5417       DONE;
5418     }
5421 (define_insn "*arm_zero_extendqisi2"
5422   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5423         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
5424   "TARGET_ARM && !arm_arch6"
5425   "@
5426    #
5427    ldrb%?\\t%0, %1\\t%@ zero_extendqisi2"
5428   [(set_attr "length" "8,4")
5429    (set_attr "type" "alu_shift_reg,load_byte")
5430    (set_attr "predicable" "yes")]
5433 (define_insn "*arm_zero_extendqisi2_v6"
5434   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5435         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,Uh")))]
5436   "TARGET_ARM && arm_arch6"
5437   "@
5438    uxtb%?\\t%0, %1
5439    ldrb%?\\t%0, %1\\t%@ zero_extendqisi2"
5440   [(set_attr "type" "extend,load_byte")
5441    (set_attr "predicable" "yes")]
5444 (define_insn "*arm_zero_extendqisi2addsi"
5445   [(set (match_operand:SI 0 "s_register_operand" "=r")
5446         (plus:SI (zero_extend:SI (match_operand:QI 1 "s_register_operand" "r"))
5447                  (match_operand:SI 2 "s_register_operand" "r")))]
5448   "TARGET_INT_SIMD"
5449   "uxtab%?\\t%0, %2, %1"
5450   [(set_attr "predicable" "yes")
5451    (set_attr "predicable_short_it" "no")
5452    (set_attr "type" "alu_shift_reg")]
5455 (define_split
5456   [(set (match_operand:SI 0 "s_register_operand" "")
5457         (zero_extend:SI (subreg:QI (match_operand:SI 1 "" "") 0)))
5458    (clobber (match_operand:SI 2 "s_register_operand" ""))]
5459   "TARGET_32BIT && (!MEM_P (operands[1])) && ! BYTES_BIG_ENDIAN"
5460   [(set (match_dup 2) (match_dup 1))
5461    (set (match_dup 0) (and:SI (match_dup 2) (const_int 255)))]
5462   ""
5465 (define_split
5466   [(set (match_operand:SI 0 "s_register_operand" "")
5467         (zero_extend:SI (subreg:QI (match_operand:SI 1 "" "") 3)))
5468    (clobber (match_operand:SI 2 "s_register_operand" ""))]
5469   "TARGET_32BIT && (!MEM_P (operands[1])) && BYTES_BIG_ENDIAN"
5470   [(set (match_dup 2) (match_dup 1))
5471    (set (match_dup 0) (and:SI (match_dup 2) (const_int 255)))]
5472   ""
5476 (define_split
5477   [(set (match_operand:SI 0 "s_register_operand" "")
5478         (IOR_XOR:SI (and:SI (ashift:SI
5479                              (match_operand:SI 1 "s_register_operand" "")
5480                              (match_operand:SI 2 "const_int_operand" ""))
5481                             (match_operand:SI 3 "const_int_operand" ""))
5482                     (zero_extend:SI
5483                      (match_operator 5 "subreg_lowpart_operator"
5484                       [(match_operand:SI 4 "s_register_operand" "")]))))]
5485   "TARGET_32BIT
5486    && (UINTVAL (operands[3])
5487        == (GET_MODE_MASK (GET_MODE (operands[5]))
5488            & (GET_MODE_MASK (GET_MODE (operands[5]))
5489               << (INTVAL (operands[2])))))"
5490   [(set (match_dup 0) (IOR_XOR:SI (ashift:SI (match_dup 1) (match_dup 2))
5491                                   (match_dup 4)))
5492    (set (match_dup 0) (zero_extend:SI (match_dup 5)))]
5493   "operands[5] = gen_lowpart (GET_MODE (operands[5]), operands[0]);"
5496 (define_insn "*compareqi_eq0"
5497   [(set (reg:CC_Z CC_REGNUM)
5498         (compare:CC_Z (match_operand:QI 0 "s_register_operand" "r")
5499                          (const_int 0)))]
5500   "TARGET_32BIT"
5501   "tst%?\\t%0, #255"
5502   [(set_attr "conds" "set")
5503    (set_attr "predicable" "yes")
5504    (set_attr "predicable_short_it" "no")
5505    (set_attr "type" "logic_imm")]
5508 (define_expand "extendhisi2"
5509   [(set (match_operand:SI 0 "s_register_operand" "")
5510         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
5511   "TARGET_EITHER"
5513   if (TARGET_THUMB1)
5514     {
5515       emit_insn (gen_thumb1_extendhisi2 (operands[0], operands[1]));
5516       DONE;
5517     }
5518   if (MEM_P (operands[1]) && TARGET_ARM && !arm_arch4)
5519     {
5520       emit_insn (gen_extendhisi2_mem (operands[0], operands[1]));
5521       DONE;
5522     }
5524   if (!arm_arch6 && !MEM_P (operands[1]))
5525     {
5526       rtx t = gen_lowpart (SImode, operands[1]);
5527       rtx tmp = gen_reg_rtx (SImode);
5528       emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (16)));
5529       emit_insn (gen_ashrsi3 (operands[0], tmp, GEN_INT (16)));
5530       DONE;
5531     }
5534 (define_split
5535   [(parallel
5536     [(set (match_operand:SI 0 "register_operand" "")
5537           (sign_extend:SI (match_operand:HI 1 "register_operand" "")))
5538      (clobber (match_scratch:SI 2 ""))])]
5539   "!arm_arch6"
5540   [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
5541    (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
5543   operands[2] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
5546 ;; This pattern will only be used when ldsh is not available
5547 (define_expand "extendhisi2_mem"
5548   [(set (match_dup 2) (zero_extend:SI (match_operand:HI 1 "" "")))
5549    (set (match_dup 3)
5550         (zero_extend:SI (match_dup 7)))
5551    (set (match_dup 6) (ashift:SI (match_dup 4) (const_int 24)))
5552    (set (match_operand:SI 0 "" "")
5553         (ior:SI (ashiftrt:SI (match_dup 6) (const_int 16)) (match_dup 5)))]
5554   "TARGET_ARM"
5555   "
5556   {
5557     rtx mem1, mem2;
5558     rtx addr = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
5560     mem1 = change_address (operands[1], QImode, addr);
5561     mem2 = change_address (operands[1], QImode,
5562                            plus_constant (Pmode, addr, 1));
5563     operands[0] = gen_lowpart (SImode, operands[0]);
5564     operands[1] = mem1;
5565     operands[2] = gen_reg_rtx (SImode);
5566     operands[3] = gen_reg_rtx (SImode);
5567     operands[6] = gen_reg_rtx (SImode);
5568     operands[7] = mem2;
5570     if (BYTES_BIG_ENDIAN)
5571       {
5572         operands[4] = operands[2];
5573         operands[5] = operands[3];
5574       }
5575     else
5576       {
5577         operands[4] = operands[3];
5578         operands[5] = operands[2];
5579       }
5580   }"
5583 (define_split
5584   [(set (match_operand:SI 0 "register_operand" "")
5585         (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
5586   "!arm_arch6"
5587   [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
5588    (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
5590   operands[2] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
5593 (define_insn "*arm_extendhisi2"
5594   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5595         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,Uh")))]
5596   "TARGET_ARM && arm_arch4 && !arm_arch6"
5597   "@
5598    #
5599    ldrsh%?\\t%0, %1"
5600   [(set_attr "length" "8,4")
5601    (set_attr "type" "alu_shift_reg,load_byte")
5602    (set_attr "predicable" "yes")]
5605 ;; ??? Check Thumb-2 pool range
5606 (define_insn "*arm_extendhisi2_v6"
5607   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5608         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,Uh")))]
5609   "TARGET_32BIT && arm_arch6"
5610   "@
5611    sxth%?\\t%0, %1
5612    ldrsh%?\\t%0, %1"
5613   [(set_attr "type" "extend,load_byte")
5614    (set_attr "predicable" "yes")
5615    (set_attr "predicable_short_it" "no")]
5618 (define_insn "*arm_extendhisi2addsi"
5619   [(set (match_operand:SI 0 "s_register_operand" "=r")
5620         (plus:SI (sign_extend:SI (match_operand:HI 1 "s_register_operand" "r"))
5621                  (match_operand:SI 2 "s_register_operand" "r")))]
5622   "TARGET_INT_SIMD"
5623   "sxtah%?\\t%0, %2, %1"
5624   [(set_attr "type" "alu_shift_reg")]
5627 (define_expand "extendqihi2"
5628   [(set (match_dup 2)
5629         (ashift:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "")
5630                    (const_int 24)))
5631    (set (match_operand:HI 0 "s_register_operand" "")
5632         (ashiftrt:SI (match_dup 2)
5633                      (const_int 24)))]
5634   "TARGET_ARM"
5635   "
5636   {
5637     if (arm_arch4 && MEM_P (operands[1]))
5638       {
5639         emit_insn (gen_rtx_SET (operands[0],
5640                                 gen_rtx_SIGN_EXTEND (HImode, operands[1])));
5641         DONE;
5642       }
5643     if (!s_register_operand (operands[1], QImode))
5644       operands[1] = copy_to_mode_reg (QImode, operands[1]);
5645     operands[0] = gen_lowpart (SImode, operands[0]);
5646     operands[1] = gen_lowpart (SImode, operands[1]);
5647     operands[2] = gen_reg_rtx (SImode);
5648   }"
5651 (define_insn "*arm_extendqihi_insn"
5652   [(set (match_operand:HI 0 "s_register_operand" "=r")
5653         (sign_extend:HI (match_operand:QI 1 "arm_extendqisi_mem_op" "Uq")))]
5654   "TARGET_ARM && arm_arch4"
5655   "ldrsb%?\\t%0, %1"
5656   [(set_attr "type" "load_byte")
5657    (set_attr "predicable" "yes")]
5660 (define_expand "extendqisi2"
5661   [(set (match_operand:SI 0 "s_register_operand" "")
5662         (sign_extend:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "")))]
5663   "TARGET_EITHER"
5665   if (!arm_arch4 && MEM_P (operands[1]))
5666     operands[1] = copy_to_mode_reg (QImode, operands[1]);
5668   if (!arm_arch6 && !MEM_P (operands[1]))
5669     {
5670       rtx t = gen_lowpart (SImode, operands[1]);
5671       rtx tmp = gen_reg_rtx (SImode);
5672       emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (24)));
5673       emit_insn (gen_ashrsi3 (operands[0], tmp, GEN_INT (24)));
5674       DONE;
5675     }
5678 (define_split
5679   [(set (match_operand:SI 0 "register_operand" "")
5680         (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
5681   "!arm_arch6"
5682   [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 24)))
5683    (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 24)))]
5685   operands[2] = simplify_gen_subreg (SImode, operands[1], QImode, 0);
5688 (define_insn "*arm_extendqisi"
5689   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5690         (sign_extend:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "r,Uq")))]
5691   "TARGET_ARM && arm_arch4 && !arm_arch6"
5692   "@
5693    #
5694    ldrsb%?\\t%0, %1"
5695   [(set_attr "length" "8,4")
5696    (set_attr "type" "alu_shift_reg,load_byte")
5697    (set_attr "predicable" "yes")]
5700 (define_insn "*arm_extendqisi_v6"
5701   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5702         (sign_extend:SI
5703          (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "r,Uq")))]
5704   "TARGET_ARM && arm_arch6"
5705   "@
5706    sxtb%?\\t%0, %1
5707    ldrsb%?\\t%0, %1"
5708   [(set_attr "type" "extend,load_byte")
5709    (set_attr "predicable" "yes")]
5712 (define_insn "*arm_extendqisi2addsi"
5713   [(set (match_operand:SI 0 "s_register_operand" "=r")
5714         (plus:SI (sign_extend:SI (match_operand:QI 1 "s_register_operand" "r"))
5715                  (match_operand:SI 2 "s_register_operand" "r")))]
5716   "TARGET_INT_SIMD"
5717   "sxtab%?\\t%0, %2, %1"
5718   [(set_attr "type" "alu_shift_reg")
5719    (set_attr "predicable" "yes")
5720    (set_attr "predicable_short_it" "no")]
5723 (define_expand "extendsfdf2"
5724   [(set (match_operand:DF                  0 "s_register_operand" "")
5725         (float_extend:DF (match_operand:SF 1 "s_register_operand"  "")))]
5726   "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
5727   ""
5730 ;; HFmode -> DFmode conversions where we don't have an instruction for it
5731 ;; must go through SFmode.
5733 ;; This is always safe for an extend.
5735 (define_expand "extendhfdf2"
5736   [(set (match_operand:DF                  0 "s_register_operand" "")
5737         (float_extend:DF (match_operand:HF 1 "s_register_operand" "")))]
5738   "TARGET_EITHER"
5740   /* We don't have a direct instruction for this, so go via SFmode.  */
5741   if (!(TARGET_32BIT && TARGET_FP16_TO_DOUBLE))
5742     {
5743       rtx op1;
5744       op1 = convert_to_mode (SFmode, operands[1], 0);
5745       op1 = convert_to_mode (DFmode, op1, 0);
5746       emit_insn (gen_movdf (operands[0], op1));
5747       DONE;
5748     }
5749   /* Otherwise, we're done producing RTL and will pick up the correct
5750      pattern to do this with one rounding-step in a single instruction.  */
5754 ;; Move insns (including loads and stores)
5756 ;; XXX Just some ideas about movti.
5757 ;; I don't think these are a good idea on the arm, there just aren't enough
5758 ;; registers
5759 ;;(define_expand "loadti"
5760 ;;  [(set (match_operand:TI 0 "s_register_operand" "")
5761 ;;      (mem:TI (match_operand:SI 1 "address_operand" "")))]
5762 ;;  "" "")
5764 ;;(define_expand "storeti"
5765 ;;  [(set (mem:TI (match_operand:TI 0 "address_operand" ""))
5766 ;;      (match_operand:TI 1 "s_register_operand" ""))]
5767 ;;  "" "")
5769 ;;(define_expand "movti"
5770 ;;  [(set (match_operand:TI 0 "general_operand" "")
5771 ;;      (match_operand:TI 1 "general_operand" ""))]
5772 ;;  ""
5773 ;;  "
5775 ;;  rtx insn;
5777 ;;  if (MEM_P (operands[0]) && MEM_P (operands[1]))
5778 ;;    operands[1] = copy_to_reg (operands[1]);
5779 ;;  if (MEM_P (operands[0]))
5780 ;;    insn = gen_storeti (XEXP (operands[0], 0), operands[1]);
5781 ;;  else if (MEM_P (operands[1]))
5782 ;;    insn = gen_loadti (operands[0], XEXP (operands[1], 0));
5783 ;;  else
5784 ;;    FAIL;
5786 ;;  emit_insn (insn);
5787 ;;  DONE;
5788 ;;}")
5790 ;; Recognize garbage generated above.
5792 ;;(define_insn ""
5793 ;;  [(set (match_operand:TI 0 "general_operand" "=r,r,r,<,>,m")
5794 ;;      (match_operand:TI 1 "general_operand" "<,>,m,r,r,r"))]
5795 ;;  ""
5796 ;;  "*
5797 ;;  {
5798 ;;    register mem = (which_alternative < 3);
5799 ;;    register const char *template;
5801 ;;    operands[mem] = XEXP (operands[mem], 0);
5802 ;;    switch (which_alternative)
5803 ;;      {
5804 ;;      case 0: template = \"ldmdb\\t%1!, %M0\"; break;
5805 ;;      case 1: template = \"ldmia\\t%1!, %M0\"; break;
5806 ;;      case 2: template = \"ldmia\\t%1, %M0\"; break;
5807 ;;      case 3: template = \"stmdb\\t%0!, %M1\"; break;
5808 ;;      case 4: template = \"stmia\\t%0!, %M1\"; break;
5809 ;;      case 5: template = \"stmia\\t%0, %M1\"; break;
5810 ;;      }
5811 ;;    output_asm_insn (template, operands);
5812 ;;    return \"\";
5813 ;;  }")
5815 (define_expand "movdi"
5816   [(set (match_operand:DI 0 "general_operand" "")
5817         (match_operand:DI 1 "general_operand" ""))]
5818   "TARGET_EITHER"
5819   "
5820   if (can_create_pseudo_p ())
5821     {
5822       if (!REG_P (operands[0]))
5823         operands[1] = force_reg (DImode, operands[1]);
5824     }
5825   if (REG_P (operands[0]) && REGNO (operands[0]) <= LAST_ARM_REGNUM
5826       && !targetm.hard_regno_mode_ok (REGNO (operands[0]), DImode))
5827     {
5828       /* Avoid LDRD's into an odd-numbered register pair in ARM state
5829          when expanding function calls.  */
5830       gcc_assert (can_create_pseudo_p ());
5831       if (MEM_P (operands[1]) && MEM_VOLATILE_P (operands[1]))
5832         {
5833           /* Perform load into legal reg pair first, then move.  */
5834           rtx reg = gen_reg_rtx (DImode);
5835           emit_insn (gen_movdi (reg, operands[1]));
5836           operands[1] = reg;
5837         }
5838       emit_move_insn (gen_lowpart (SImode, operands[0]),
5839                       gen_lowpart (SImode, operands[1]));
5840       emit_move_insn (gen_highpart (SImode, operands[0]),
5841                       gen_highpart (SImode, operands[1]));
5842       DONE;
5843     }
5844   else if (REG_P (operands[1]) && REGNO (operands[1]) <= LAST_ARM_REGNUM
5845            && !targetm.hard_regno_mode_ok (REGNO (operands[1]), DImode))
5846     {
5847       /* Avoid STRD's from an odd-numbered register pair in ARM state
5848          when expanding function prologue.  */
5849       gcc_assert (can_create_pseudo_p ());
5850       rtx split_dest = (MEM_P (operands[0]) && MEM_VOLATILE_P (operands[0]))
5851                        ? gen_reg_rtx (DImode)
5852                        : operands[0];
5853       emit_move_insn (gen_lowpart (SImode, split_dest),
5854                       gen_lowpart (SImode, operands[1]));
5855       emit_move_insn (gen_highpart (SImode, split_dest),
5856                       gen_highpart (SImode, operands[1]));
5857       if (split_dest != operands[0])
5858         emit_insn (gen_movdi (operands[0], split_dest));
5859       DONE;
5860     }
5861   "
5864 (define_insn "*arm_movdi"
5865   [(set (match_operand:DI 0 "nonimmediate_di_operand" "=r, r, r, q, m")
5866         (match_operand:DI 1 "di_operand"              "rDa,Db,Dc,mi,q"))]
5867   "TARGET_32BIT
5868    && !(TARGET_HARD_FLOAT)
5869    && !TARGET_IWMMXT
5870    && (   register_operand (operands[0], DImode)
5871        || register_operand (operands[1], DImode))"
5872   "*
5873   switch (which_alternative)
5874     {
5875     case 0:
5876     case 1:
5877     case 2:
5878       return \"#\";
5879     default:
5880       return output_move_double (operands, true, NULL);
5881     }
5882   "
5883   [(set_attr "length" "8,12,16,8,8")
5884    (set_attr "type" "multiple,multiple,multiple,load_8,store_8")
5885    (set_attr "arm_pool_range" "*,*,*,1020,*")
5886    (set_attr "arm_neg_pool_range" "*,*,*,1004,*")
5887    (set_attr "thumb2_pool_range" "*,*,*,4094,*")
5888    (set_attr "thumb2_neg_pool_range" "*,*,*,0,*")]
5891 (define_split
5892   [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
5893         (match_operand:ANY64 1 "immediate_operand" ""))]
5894   "TARGET_32BIT
5895    && reload_completed
5896    && (arm_disable_literal_pool
5897        || (arm_const_double_inline_cost (operands[1])
5898            <= arm_max_const_double_inline_cost ()))"
5899   [(const_int 0)]
5900   "
5901   arm_split_constant (SET, SImode, curr_insn,
5902                       INTVAL (gen_lowpart (SImode, operands[1])),
5903                       gen_lowpart (SImode, operands[0]), NULL_RTX, 0);
5904   arm_split_constant (SET, SImode, curr_insn,
5905                       INTVAL (gen_highpart_mode (SImode,
5906                                                  GET_MODE (operands[0]),
5907                                                  operands[1])),
5908                       gen_highpart (SImode, operands[0]), NULL_RTX, 0);
5909   DONE;
5910   "
5913 ; If optimizing for size, or if we have load delay slots, then 
5914 ; we want to split the constant into two separate operations. 
5915 ; In both cases this may split a trivial part into a single data op
5916 ; leaving a single complex constant to load.  We can also get longer
5917 ; offsets in a LDR which means we get better chances of sharing the pool
5918 ; entries.  Finally, we can normally do a better job of scheduling
5919 ; LDR instructions than we can with LDM.
5920 ; This pattern will only match if the one above did not.
5921 (define_split
5922   [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
5923         (match_operand:ANY64 1 "const_double_operand" ""))]
5924   "TARGET_ARM && reload_completed
5925    && arm_const_double_by_parts (operands[1])"
5926   [(set (match_dup 0) (match_dup 1))
5927    (set (match_dup 2) (match_dup 3))]
5928   "
5929   operands[2] = gen_highpart (SImode, operands[0]);
5930   operands[3] = gen_highpart_mode (SImode, GET_MODE (operands[0]),
5931                                    operands[1]);
5932   operands[0] = gen_lowpart (SImode, operands[0]);
5933   operands[1] = gen_lowpart (SImode, operands[1]);
5934   "
5937 (define_split
5938   [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
5939         (match_operand:ANY64 1 "arm_general_register_operand" ""))]
5940   "TARGET_EITHER && reload_completed"
5941   [(set (match_dup 0) (match_dup 1))
5942    (set (match_dup 2) (match_dup 3))]
5943   "
5944   operands[2] = gen_highpart (SImode, operands[0]);
5945   operands[3] = gen_highpart (SImode, operands[1]);
5946   operands[0] = gen_lowpart (SImode, operands[0]);
5947   operands[1] = gen_lowpart (SImode, operands[1]);
5949   /* Handle a partial overlap.  */
5950   if (rtx_equal_p (operands[0], operands[3]))
5951     {
5952       rtx tmp0 = operands[0];
5953       rtx tmp1 = operands[1];
5955       operands[0] = operands[2];
5956       operands[1] = operands[3];
5957       operands[2] = tmp0;
5958       operands[3] = tmp1;
5959     }
5960   "
5963 ;; We can't actually do base+index doubleword loads if the index and
5964 ;; destination overlap.  Split here so that we at least have chance to
5965 ;; schedule.
5966 (define_split
5967   [(set (match_operand:DI 0 "s_register_operand" "")
5968         (mem:DI (plus:SI (match_operand:SI 1 "s_register_operand" "")
5969                          (match_operand:SI 2 "s_register_operand" ""))))]
5970   "TARGET_LDRD
5971   && reg_overlap_mentioned_p (operands[0], operands[1])
5972   && reg_overlap_mentioned_p (operands[0], operands[2])"
5973   [(set (match_dup 4)
5974         (plus:SI (match_dup 1)
5975                  (match_dup 2)))
5976    (set (match_dup 0)
5977         (mem:DI (match_dup 4)))]
5978   "
5979   operands[4] = gen_rtx_REG (SImode, REGNO(operands[0]));
5980   "
5983 (define_expand "movsi"
5984   [(set (match_operand:SI 0 "general_operand" "")
5985         (match_operand:SI 1 "general_operand" ""))]
5986   "TARGET_EITHER"
5987   "
5988   {
5989   rtx base, offset, tmp;
5991   if (TARGET_32BIT || TARGET_HAVE_MOVT)
5992     {
5993       /* Everything except mem = const or mem = mem can be done easily.  */
5994       if (MEM_P (operands[0]))
5995         operands[1] = force_reg (SImode, operands[1]);
5996       if (arm_general_register_operand (operands[0], SImode)
5997           && CONST_INT_P (operands[1])
5998           && !(const_ok_for_arm (INTVAL (operands[1]))
5999                || const_ok_for_arm (~INTVAL (operands[1]))))
6000         {
6001            if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[1]), SET))
6002              {
6003                 emit_insn (gen_rtx_SET (operands[0], operands[1]));
6004                 DONE;
6005              }
6006           else
6007              {
6008                 arm_split_constant (SET, SImode, NULL_RTX,
6009                                     INTVAL (operands[1]), operands[0], NULL_RTX,
6010                                     optimize && can_create_pseudo_p ());
6011                 DONE;
6012              }
6013         }
6014     }
6015   else /* Target doesn't have MOVT...  */
6016     {
6017       if (can_create_pseudo_p ())
6018         {
6019           if (!REG_P (operands[0]))
6020             operands[1] = force_reg (SImode, operands[1]);
6021         }
6022     }
6024   if (ARM_OFFSETS_MUST_BE_WITHIN_SECTIONS_P)
6025     {
6026       split_const (operands[1], &base, &offset);
6027       if (GET_CODE (base) == SYMBOL_REF
6028           && !offset_within_block_p (base, INTVAL (offset)))
6029         {
6030           tmp = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];
6031           emit_move_insn (tmp, base);
6032           emit_insn (gen_addsi3 (operands[0], tmp, offset));
6033           DONE;
6034         }
6035     }
6037   /* Recognize the case where operand[1] is a reference to thread-local
6038      data and load its address to a register.  */
6039   if (arm_tls_referenced_p (operands[1]))
6040     {
6041       rtx tmp = operands[1];
6042       rtx addend = NULL;
6044       if (GET_CODE (tmp) == CONST && GET_CODE (XEXP (tmp, 0)) == PLUS)
6045         {
6046           addend = XEXP (XEXP (tmp, 0), 1);
6047           tmp = XEXP (XEXP (tmp, 0), 0);
6048         }
6050       gcc_assert (GET_CODE (tmp) == SYMBOL_REF);
6051       gcc_assert (SYMBOL_REF_TLS_MODEL (tmp) != 0);
6053       tmp = legitimize_tls_address (tmp,
6054                                     !can_create_pseudo_p () ? operands[0] : 0);
6055       if (addend)
6056         {
6057           tmp = gen_rtx_PLUS (SImode, tmp, addend);
6058           tmp = force_operand (tmp, operands[0]);
6059         }
6060       operands[1] = tmp;
6061     }
6062   else if (flag_pic
6063            && (CONSTANT_P (operands[1])
6064                || symbol_mentioned_p (operands[1])
6065                || label_mentioned_p (operands[1])))
6066       operands[1] = legitimize_pic_address (operands[1], SImode,
6067                                             (!can_create_pseudo_p ()
6068                                              ? operands[0]
6069                                              : 0));
6070   }
6071   "
6074 ;; The ARM LO_SUM and HIGH are backwards - HIGH sets the low bits, and
6075 ;; LO_SUM adds in the high bits.  Fortunately these are opaque operations
6076 ;; so this does not matter.
6077 (define_insn "*arm_movt"
6078   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r")
6079         (lo_sum:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6080                    (match_operand:SI 2 "general_operand"      "i,i")))]
6081   "TARGET_HAVE_MOVT && arm_valid_symbolic_address_p (operands[2])"
6082   "@
6083    movt%?\t%0, #:upper16:%c2
6084    movt\t%0, #:upper16:%c2"
6085   [(set_attr "arch"  "32,v8mb")
6086    (set_attr "predicable" "yes")
6087    (set_attr "predicable_short_it" "no")
6088    (set_attr "length" "4")
6089    (set_attr "type" "alu_sreg")]
6092 (define_insn "*arm_movsi_insn"
6093   [(set (match_operand:SI 0 "nonimmediate_operand" "=rk,r,r,r,rk,m")
6094         (match_operand:SI 1 "general_operand"      "rk, I,K,j,mi,rk"))]
6095   "TARGET_ARM && !TARGET_IWMMXT && !TARGET_HARD_FLOAT
6096    && (   register_operand (operands[0], SImode)
6097        || register_operand (operands[1], SImode))"
6098   "@
6099    mov%?\\t%0, %1
6100    mov%?\\t%0, %1
6101    mvn%?\\t%0, #%B1
6102    movw%?\\t%0, %1
6103    ldr%?\\t%0, %1
6104    str%?\\t%1, %0"
6105   [(set_attr "type" "mov_reg,mov_imm,mvn_imm,mov_imm,load_4,store_4")
6106    (set_attr "predicable" "yes")
6107    (set_attr "arch" "*,*,*,v6t2,*,*")
6108    (set_attr "pool_range" "*,*,*,*,4096,*")
6109    (set_attr "neg_pool_range" "*,*,*,*,4084,*")]
6112 (define_split
6113   [(set (match_operand:SI 0 "arm_general_register_operand" "")
6114         (match_operand:SI 1 "const_int_operand" ""))]
6115   "(TARGET_32BIT || TARGET_HAVE_MOVT)
6116   && (!(const_ok_for_arm (INTVAL (operands[1]))
6117         || const_ok_for_arm (~INTVAL (operands[1]))))"
6118   [(clobber (const_int 0))]
6119   "
6120   arm_split_constant (SET, SImode, NULL_RTX, 
6121                       INTVAL (operands[1]), operands[0], NULL_RTX, 0);
6122   DONE;
6123   "
6126 ;; A normal way to do (symbol + offset) requires three instructions at least
6127 ;; (depends on how big the offset is) as below:
6128 ;; movw r0, #:lower16:g
6129 ;; movw r0, #:upper16:g
6130 ;; adds r0, #4
6132 ;; A better way would be:
6133 ;; movw r0, #:lower16:g+4
6134 ;; movw r0, #:upper16:g+4
6136 ;; The limitation of this way is that the length of offset should be a 16-bit
6137 ;; signed value, because current assembler only supports REL type relocation for
6138 ;; such case.  If the more powerful RELA type is supported in future, we should
6139 ;; update this pattern to go with better way.
6140 (define_split
6141   [(set (match_operand:SI 0 "arm_general_register_operand" "")
6142         (const:SI (plus:SI (match_operand:SI 1 "general_operand" "")
6143                            (match_operand:SI 2 "const_int_operand" ""))))]
6144   "TARGET_THUMB
6145    && TARGET_HAVE_MOVT
6146    && arm_disable_literal_pool
6147    && reload_completed
6148    && GET_CODE (operands[1]) == SYMBOL_REF"
6149   [(clobber (const_int 0))]
6150   "
6151     int offset = INTVAL (operands[2]);
6153     if (offset < -0x8000 || offset > 0x7fff)
6154       {
6155         arm_emit_movpair (operands[0], operands[1]);
6156         emit_insn (gen_rtx_SET (operands[0],
6157                                 gen_rtx_PLUS (SImode, operands[0], operands[2])));
6158       }
6159     else
6160       {
6161         rtx op = gen_rtx_CONST (SImode,
6162                                 gen_rtx_PLUS (SImode, operands[1], operands[2]));
6163         arm_emit_movpair (operands[0], op);
6164       }
6165   "
6168 ;; Split symbol_refs at the later stage (after cprop), instead of generating
6169 ;; movt/movw pair directly at expand.  Otherwise corresponding high_sum
6170 ;; and lo_sum would be merged back into memory load at cprop.  However,
6171 ;; if the default is to prefer movt/movw rather than a load from the constant
6172 ;; pool, the performance is better.
6173 (define_split
6174   [(set (match_operand:SI 0 "arm_general_register_operand" "")
6175        (match_operand:SI 1 "general_operand" ""))]
6176   "TARGET_USE_MOVT && GET_CODE (operands[1]) == SYMBOL_REF
6177    && !flag_pic && !target_word_relocations
6178    && !arm_tls_referenced_p (operands[1])"
6179   [(clobber (const_int 0))]
6181   arm_emit_movpair (operands[0], operands[1]);
6182   DONE;
6185 ;; When generating pic, we need to load the symbol offset into a register.
6186 ;; So that the optimizer does not confuse this with a normal symbol load
6187 ;; we use an unspec.  The offset will be loaded from a constant pool entry,
6188 ;; since that is the only type of relocation we can use.
6190 ;; Wrap calculation of the whole PIC address in a single pattern for the
6191 ;; benefit of optimizers, particularly, PRE and HOIST.  Calculation of
6192 ;; a PIC address involves two loads from memory, so we want to CSE it
6193 ;; as often as possible.
6194 ;; This pattern will be split into one of the pic_load_addr_* patterns
6195 ;; and a move after GCSE optimizations.
6197 ;; Note: Update arm.c: legitimize_pic_address() when changing this pattern.
6198 (define_expand "calculate_pic_address"
6199   [(set (match_operand:SI 0 "register_operand" "")
6200         (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "")
6201                          (unspec:SI [(match_operand:SI 2 "" "")]
6202                                     UNSPEC_PIC_SYM))))]
6203   "flag_pic"
6206 ;; Split calculate_pic_address into pic_load_addr_* and a move.
6207 (define_split
6208   [(set (match_operand:SI 0 "register_operand" "")
6209         (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "")
6210                          (unspec:SI [(match_operand:SI 2 "" "")]
6211                                     UNSPEC_PIC_SYM))))]
6212   "flag_pic"
6213   [(set (match_dup 3) (unspec:SI [(match_dup 2)] UNSPEC_PIC_SYM))
6214    (set (match_dup 0) (mem:SI (plus:SI (match_dup 1) (match_dup 3))))]
6215   "operands[3] = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];"
6218 ;; operand1 is the memory address to go into 
6219 ;; pic_load_addr_32bit.
6220 ;; operand2 is the PIC label to be emitted 
6221 ;; from pic_add_dot_plus_eight.
6222 ;; We do this to allow hoisting of the entire insn.
6223 (define_insn_and_split "pic_load_addr_unified"
6224   [(set (match_operand:SI 0 "s_register_operand" "=r,r,l")
6225         (unspec:SI [(match_operand:SI 1 "" "mX,mX,mX") 
6226                     (match_operand:SI 2 "" "")] 
6227                     UNSPEC_PIC_UNIFIED))]
6228  "flag_pic"
6229  "#"
6230  "&& reload_completed"
6231  [(set (match_dup 0) (unspec:SI [(match_dup 1)] UNSPEC_PIC_SYM))
6232   (set (match_dup 0) (unspec:SI [(match_dup 0) (match_dup 3)
6233                                  (match_dup 2)] UNSPEC_PIC_BASE))]
6234  "operands[3] = TARGET_THUMB ? GEN_INT (4) : GEN_INT (8);"
6235  [(set_attr "type" "load_4,load_4,load_4")
6236   (set_attr "pool_range" "4096,4094,1022")
6237   (set_attr "neg_pool_range" "4084,0,0")
6238   (set_attr "arch"  "a,t2,t1")    
6239   (set_attr "length" "8,6,4")]
6242 ;; The rather odd constraints on the following are to force reload to leave
6243 ;; the insn alone, and to force the minipool generation pass to then move
6244 ;; the GOT symbol to memory.
6246 (define_insn "pic_load_addr_32bit"
6247   [(set (match_operand:SI 0 "s_register_operand" "=r")
6248         (unspec:SI [(match_operand:SI 1 "" "mX")] UNSPEC_PIC_SYM))]
6249   "TARGET_32BIT && flag_pic"
6250   "ldr%?\\t%0, %1"
6251   [(set_attr "type" "load_4")
6252    (set (attr "pool_range")
6253         (if_then_else (eq_attr "is_thumb" "no")
6254                       (const_int 4096)
6255                       (const_int 4094)))
6256    (set (attr "neg_pool_range")
6257         (if_then_else (eq_attr "is_thumb" "no")
6258                       (const_int 4084)
6259                       (const_int 0)))]
6262 (define_insn "pic_load_addr_thumb1"
6263   [(set (match_operand:SI 0 "s_register_operand" "=l")
6264         (unspec:SI [(match_operand:SI 1 "" "mX")] UNSPEC_PIC_SYM))]
6265   "TARGET_THUMB1 && flag_pic"
6266   "ldr\\t%0, %1"
6267   [(set_attr "type" "load_4")
6268    (set (attr "pool_range") (const_int 1018))]
6271 (define_insn "pic_add_dot_plus_four"
6272   [(set (match_operand:SI 0 "register_operand" "=r")
6273         (unspec:SI [(match_operand:SI 1 "register_operand" "0")
6274                     (const_int 4)
6275                     (match_operand 2 "" "")]
6276                    UNSPEC_PIC_BASE))]
6277   "TARGET_THUMB"
6278   "*
6279   (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
6280                                      INTVAL (operands[2]));
6281   return \"add\\t%0, %|pc\";
6282   "
6283   [(set_attr "length" "2")
6284    (set_attr "type" "alu_sreg")]
6287 (define_insn "pic_add_dot_plus_eight"
6288   [(set (match_operand:SI 0 "register_operand" "=r")
6289         (unspec:SI [(match_operand:SI 1 "register_operand" "r")
6290                     (const_int 8)
6291                     (match_operand 2 "" "")]
6292                    UNSPEC_PIC_BASE))]
6293   "TARGET_ARM"
6294   "*
6295     (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
6296                                        INTVAL (operands[2]));
6297     return \"add%?\\t%0, %|pc, %1\";
6298   "
6299   [(set_attr "predicable" "yes")
6300    (set_attr "type" "alu_sreg")]
6303 (define_insn "tls_load_dot_plus_eight"
6304   [(set (match_operand:SI 0 "register_operand" "=r")
6305         (mem:SI (unspec:SI [(match_operand:SI 1 "register_operand" "r")
6306                             (const_int 8)
6307                             (match_operand 2 "" "")]
6308                            UNSPEC_PIC_BASE)))]
6309   "TARGET_ARM"
6310   "*
6311     (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
6312                                        INTVAL (operands[2]));
6313     return \"ldr%?\\t%0, [%|pc, %1]\t\t@ tls_load_dot_plus_eight\";
6314   "
6315   [(set_attr "predicable" "yes")
6316    (set_attr "type" "load_4")]
6319 ;; PIC references to local variables can generate pic_add_dot_plus_eight
6320 ;; followed by a load.  These sequences can be crunched down to
6321 ;; tls_load_dot_plus_eight by a peephole.
6323 (define_peephole2
6324   [(set (match_operand:SI 0 "register_operand" "")
6325         (unspec:SI [(match_operand:SI 3 "register_operand" "")
6326                     (const_int 8)
6327                     (match_operand 1 "" "")]
6328                    UNSPEC_PIC_BASE))
6329    (set (match_operand:SI 2 "arm_general_register_operand" "")
6330         (mem:SI (match_dup 0)))]
6331   "TARGET_ARM && peep2_reg_dead_p (2, operands[0])"
6332   [(set (match_dup 2)
6333         (mem:SI (unspec:SI [(match_dup 3)
6334                             (const_int 8)
6335                             (match_dup 1)]
6336                            UNSPEC_PIC_BASE)))]
6337   ""
6340 (define_insn "pic_offset_arm"
6341   [(set (match_operand:SI 0 "register_operand" "=r")
6342         (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
6343                          (unspec:SI [(match_operand:SI 2 "" "X")]
6344                                     UNSPEC_PIC_OFFSET))))]
6345   "TARGET_VXWORKS_RTP && TARGET_ARM && flag_pic"
6346   "ldr%?\\t%0, [%1,%2]"
6347   [(set_attr "type" "load_4")]
6350 (define_expand "builtin_setjmp_receiver"
6351   [(label_ref (match_operand 0 "" ""))]
6352   "flag_pic"
6353   "
6355   /* r3 is clobbered by set/longjmp, so we can use it as a scratch
6356      register.  */
6357   if (arm_pic_register != INVALID_REGNUM)
6358     arm_load_pic_register (1UL << 3);
6359   DONE;
6362 ;; If copying one reg to another we can set the condition codes according to
6363 ;; its value.  Such a move is common after a return from subroutine and the
6364 ;; result is being tested against zero.
6366 (define_insn "*movsi_compare0"
6367   [(set (reg:CC CC_REGNUM)
6368         (compare:CC (match_operand:SI 1 "s_register_operand" "0,r")
6369                     (const_int 0)))
6370    (set (match_operand:SI 0 "s_register_operand" "=r,r")
6371         (match_dup 1))]
6372   "TARGET_32BIT"
6373   "@
6374    cmp%?\\t%0, #0
6375    subs%?\\t%0, %1, #0"
6376   [(set_attr "conds" "set")
6377    (set_attr "type" "alus_imm,alus_imm")]
6380 ;; Subroutine to store a half word from a register into memory.
6381 ;; Operand 0 is the source register (HImode)
6382 ;; Operand 1 is the destination address in a register (SImode)
6384 ;; In both this routine and the next, we must be careful not to spill
6385 ;; a memory address of reg+large_const into a separate PLUS insn, since this
6386 ;; can generate unrecognizable rtl.
6388 (define_expand "storehi"
6389   [;; store the low byte
6390    (set (match_operand 1 "" "") (match_dup 3))
6391    ;; extract the high byte
6392    (set (match_dup 2)
6393         (ashiftrt:SI (match_operand 0 "" "") (const_int 8)))
6394    ;; store the high byte
6395    (set (match_dup 4) (match_dup 5))]
6396   "TARGET_ARM"
6397   "
6398   {
6399     rtx op1 = operands[1];
6400     rtx addr = XEXP (op1, 0);
6401     enum rtx_code code = GET_CODE (addr);
6403     if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1)))
6404         || code == MINUS)
6405       op1 = replace_equiv_address (operands[1], force_reg (SImode, addr));
6407     operands[4] = adjust_address (op1, QImode, 1);
6408     operands[1] = adjust_address (operands[1], QImode, 0);
6409     operands[3] = gen_lowpart (QImode, operands[0]);
6410     operands[0] = gen_lowpart (SImode, operands[0]);
6411     operands[2] = gen_reg_rtx (SImode);
6412     operands[5] = gen_lowpart (QImode, operands[2]);
6413   }"
6416 (define_expand "storehi_bigend"
6417   [(set (match_dup 4) (match_dup 3))
6418    (set (match_dup 2)
6419         (ashiftrt:SI (match_operand 0 "" "") (const_int 8)))
6420    (set (match_operand 1 "" "") (match_dup 5))]
6421   "TARGET_ARM"
6422   "
6423   {
6424     rtx op1 = operands[1];
6425     rtx addr = XEXP (op1, 0);
6426     enum rtx_code code = GET_CODE (addr);
6428     if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1)))
6429         || code == MINUS)
6430       op1 = replace_equiv_address (op1, force_reg (SImode, addr));
6432     operands[4] = adjust_address (op1, QImode, 1);
6433     operands[1] = adjust_address (operands[1], QImode, 0);
6434     operands[3] = gen_lowpart (QImode, operands[0]);
6435     operands[0] = gen_lowpart (SImode, operands[0]);
6436     operands[2] = gen_reg_rtx (SImode);
6437     operands[5] = gen_lowpart (QImode, operands[2]);
6438   }"
6441 ;; Subroutine to store a half word integer constant into memory.
6442 (define_expand "storeinthi"
6443   [(set (match_operand 0 "" "")
6444         (match_operand 1 "" ""))
6445    (set (match_dup 3) (match_dup 2))]
6446   "TARGET_ARM"
6447   "
6448   {
6449     HOST_WIDE_INT value = INTVAL (operands[1]);
6450     rtx addr = XEXP (operands[0], 0);
6451     rtx op0 = operands[0];
6452     enum rtx_code code = GET_CODE (addr);
6454     if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1)))
6455         || code == MINUS)
6456       op0 = replace_equiv_address (op0, force_reg (SImode, addr));
6458     operands[1] = gen_reg_rtx (SImode);
6459     if (BYTES_BIG_ENDIAN)
6460       {
6461         emit_insn (gen_movsi (operands[1], GEN_INT ((value >> 8) & 255)));
6462         if ((value & 255) == ((value >> 8) & 255))
6463           operands[2] = operands[1];
6464         else
6465           {
6466             operands[2] = gen_reg_rtx (SImode);
6467             emit_insn (gen_movsi (operands[2], GEN_INT (value & 255)));
6468           }
6469       }
6470     else
6471       {
6472         emit_insn (gen_movsi (operands[1], GEN_INT (value & 255)));
6473         if ((value & 255) == ((value >> 8) & 255))
6474           operands[2] = operands[1];
6475         else
6476           {
6477             operands[2] = gen_reg_rtx (SImode);
6478             emit_insn (gen_movsi (operands[2], GEN_INT ((value >> 8) & 255)));
6479           }
6480       }
6482     operands[3] = adjust_address (op0, QImode, 1);
6483     operands[0] = adjust_address (operands[0], QImode, 0);
6484     operands[2] = gen_lowpart (QImode, operands[2]);
6485     operands[1] = gen_lowpart (QImode, operands[1]);
6486   }"
6489 (define_expand "storehi_single_op"
6490   [(set (match_operand:HI 0 "memory_operand" "")
6491         (match_operand:HI 1 "general_operand" ""))]
6492   "TARGET_32BIT && arm_arch4"
6493   "
6494   if (!s_register_operand (operands[1], HImode))
6495     operands[1] = copy_to_mode_reg (HImode, operands[1]);
6496   "
6499 (define_expand "movhi"
6500   [(set (match_operand:HI 0 "general_operand" "")
6501         (match_operand:HI 1 "general_operand" ""))]
6502   "TARGET_EITHER"
6503   "
6504   if (TARGET_ARM)
6505     {
6506       if (can_create_pseudo_p ())
6507         {
6508           if (MEM_P (operands[0]))
6509             {
6510               if (arm_arch4)
6511                 {
6512                   emit_insn (gen_storehi_single_op (operands[0], operands[1]));
6513                   DONE;
6514                 }
6515               if (CONST_INT_P (operands[1]))
6516                 emit_insn (gen_storeinthi (operands[0], operands[1]));
6517               else
6518                 {
6519                   if (MEM_P (operands[1]))
6520                     operands[1] = force_reg (HImode, operands[1]);
6521                   if (BYTES_BIG_ENDIAN)
6522                     emit_insn (gen_storehi_bigend (operands[1], operands[0]));
6523                   else
6524                    emit_insn (gen_storehi (operands[1], operands[0]));
6525                 }
6526               DONE;
6527             }
6528           /* Sign extend a constant, and keep it in an SImode reg.  */
6529           else if (CONST_INT_P (operands[1]))
6530             {
6531               rtx reg = gen_reg_rtx (SImode);
6532               HOST_WIDE_INT val = INTVAL (operands[1]) & 0xffff;
6534               /* If the constant is already valid, leave it alone.  */
6535               if (!const_ok_for_arm (val))
6536                 {
6537                   /* If setting all the top bits will make the constant 
6538                      loadable in a single instruction, then set them.  
6539                      Otherwise, sign extend the number.  */
6541                   if (const_ok_for_arm (~(val | ~0xffff)))
6542                     val |= ~0xffff;
6543                   else if (val & 0x8000)
6544                     val |= ~0xffff;
6545                 }
6547               emit_insn (gen_movsi (reg, GEN_INT (val)));
6548               operands[1] = gen_lowpart (HImode, reg);
6549             }
6550           else if (arm_arch4 && optimize && can_create_pseudo_p ()
6551                    && MEM_P (operands[1]))
6552             {
6553               rtx reg = gen_reg_rtx (SImode);
6555               emit_insn (gen_zero_extendhisi2 (reg, operands[1]));
6556               operands[1] = gen_lowpart (HImode, reg);
6557             }
6558           else if (!arm_arch4)
6559             {
6560               if (MEM_P (operands[1]))
6561                 {
6562                   rtx base;
6563                   rtx offset = const0_rtx;
6564                   rtx reg = gen_reg_rtx (SImode);
6566                   if ((REG_P (base = XEXP (operands[1], 0))
6567                        || (GET_CODE (base) == PLUS
6568                            && (CONST_INT_P (offset = XEXP (base, 1)))
6569                            && ((INTVAL(offset) & 1) != 1)
6570                            && REG_P (base = XEXP (base, 0))))
6571                       && REGNO_POINTER_ALIGN (REGNO (base)) >= 32)
6572                     {
6573                       rtx new_rtx;
6575                       new_rtx = widen_memory_access (operands[1], SImode,
6576                                                      ((INTVAL (offset) & ~3)
6577                                                       - INTVAL (offset)));
6578                       emit_insn (gen_movsi (reg, new_rtx));
6579                       if (((INTVAL (offset) & 2) != 0)
6580                           ^ (BYTES_BIG_ENDIAN ? 1 : 0))
6581                         {
6582                           rtx reg2 = gen_reg_rtx (SImode);
6584                           emit_insn (gen_lshrsi3 (reg2, reg, GEN_INT (16)));
6585                           reg = reg2;
6586                         }
6587                     }
6588                   else
6589                     emit_insn (gen_movhi_bytes (reg, operands[1]));
6591                   operands[1] = gen_lowpart (HImode, reg);
6592                }
6593            }
6594         }
6595       /* Handle loading a large integer during reload.  */
6596       else if (CONST_INT_P (operands[1])
6597                && !const_ok_for_arm (INTVAL (operands[1]))
6598                && !const_ok_for_arm (~INTVAL (operands[1])))
6599         {
6600           /* Writing a constant to memory needs a scratch, which should
6601              be handled with SECONDARY_RELOADs.  */
6602           gcc_assert (REG_P (operands[0]));
6604           operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
6605           emit_insn (gen_movsi (operands[0], operands[1]));
6606           DONE;
6607        }
6608     }
6609   else if (TARGET_THUMB2)
6610     {
6611       /* Thumb-2 can do everything except mem=mem and mem=const easily.  */
6612       if (can_create_pseudo_p ())
6613         {
6614           if (!REG_P (operands[0]))
6615             operands[1] = force_reg (HImode, operands[1]);
6616           /* Zero extend a constant, and keep it in an SImode reg.  */
6617           else if (CONST_INT_P (operands[1]))
6618             {
6619               rtx reg = gen_reg_rtx (SImode);
6620               HOST_WIDE_INT val = INTVAL (operands[1]) & 0xffff;
6622               emit_insn (gen_movsi (reg, GEN_INT (val)));
6623               operands[1] = gen_lowpart (HImode, reg);
6624             }
6625         }
6626     }
6627   else /* TARGET_THUMB1 */
6628     {
6629       if (can_create_pseudo_p ())
6630         {
6631           if (CONST_INT_P (operands[1]))
6632             {
6633               rtx reg = gen_reg_rtx (SImode);
6635               emit_insn (gen_movsi (reg, operands[1]));
6636               operands[1] = gen_lowpart (HImode, reg);
6637             }
6639           /* ??? We shouldn't really get invalid addresses here, but this can
6640              happen if we are passed a SP (never OK for HImode/QImode) or 
6641              virtual register (also rejected as illegitimate for HImode/QImode)
6642              relative address.  */
6643           /* ??? This should perhaps be fixed elsewhere, for instance, in
6644              fixup_stack_1, by checking for other kinds of invalid addresses,
6645              e.g. a bare reference to a virtual register.  This may confuse the
6646              alpha though, which must handle this case differently.  */
6647           if (MEM_P (operands[0])
6648               && !memory_address_p (GET_MODE (operands[0]),
6649                                     XEXP (operands[0], 0)))
6650             operands[0]
6651               = replace_equiv_address (operands[0],
6652                                        copy_to_reg (XEXP (operands[0], 0)));
6653    
6654           if (MEM_P (operands[1])
6655               && !memory_address_p (GET_MODE (operands[1]),
6656                                     XEXP (operands[1], 0)))
6657             operands[1]
6658               = replace_equiv_address (operands[1],
6659                                        copy_to_reg (XEXP (operands[1], 0)));
6661           if (MEM_P (operands[1]) && optimize > 0)
6662             {
6663               rtx reg = gen_reg_rtx (SImode);
6665               emit_insn (gen_zero_extendhisi2 (reg, operands[1]));
6666               operands[1] = gen_lowpart (HImode, reg);
6667             }
6669           if (MEM_P (operands[0]))
6670             operands[1] = force_reg (HImode, operands[1]);
6671         }
6672       else if (CONST_INT_P (operands[1])
6673                 && !satisfies_constraint_I (operands[1]))
6674         {
6675           /* Handle loading a large integer during reload.  */
6677           /* Writing a constant to memory needs a scratch, which should
6678              be handled with SECONDARY_RELOADs.  */
6679           gcc_assert (REG_P (operands[0]));
6681           operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
6682           emit_insn (gen_movsi (operands[0], operands[1]));
6683           DONE;
6684         }
6685     }
6686   "
6689 (define_expand "movhi_bytes"
6690   [(set (match_dup 2) (zero_extend:SI (match_operand:HI 1 "" "")))
6691    (set (match_dup 3)
6692         (zero_extend:SI (match_dup 6)))
6693    (set (match_operand:SI 0 "" "")
6694          (ior:SI (ashift:SI (match_dup 4) (const_int 8)) (match_dup 5)))]
6695   "TARGET_ARM"
6696   "
6697   {
6698     rtx mem1, mem2;
6699     rtx addr = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
6701     mem1 = change_address (operands[1], QImode, addr);
6702     mem2 = change_address (operands[1], QImode,
6703                            plus_constant (Pmode, addr, 1));
6704     operands[0] = gen_lowpart (SImode, operands[0]);
6705     operands[1] = mem1;
6706     operands[2] = gen_reg_rtx (SImode);
6707     operands[3] = gen_reg_rtx (SImode);
6708     operands[6] = mem2;
6710     if (BYTES_BIG_ENDIAN)
6711       {
6712         operands[4] = operands[2];
6713         operands[5] = operands[3];
6714       }
6715     else
6716       {
6717         operands[4] = operands[3];
6718         operands[5] = operands[2];
6719       }
6720   }"
6723 (define_expand "movhi_bigend"
6724   [(set (match_dup 2)
6725         (rotate:SI (subreg:SI (match_operand:HI 1 "memory_operand" "") 0)
6726                    (const_int 16)))
6727    (set (match_dup 3)
6728         (ashiftrt:SI (match_dup 2) (const_int 16)))
6729    (set (match_operand:HI 0 "s_register_operand" "")
6730         (match_dup 4))]
6731   "TARGET_ARM"
6732   "
6733   operands[2] = gen_reg_rtx (SImode);
6734   operands[3] = gen_reg_rtx (SImode);
6735   operands[4] = gen_lowpart (HImode, operands[3]);
6736   "
6739 ;; Pattern to recognize insn generated default case above
6740 (define_insn "*movhi_insn_arch4"
6741   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m,r")
6742         (match_operand:HI 1 "general_operand"      "rIk,K,n,r,mi"))]
6743   "TARGET_ARM
6744    && arm_arch4 && !TARGET_HARD_FLOAT
6745    && (register_operand (operands[0], HImode)
6746        || register_operand (operands[1], HImode))"
6747   "@
6748    mov%?\\t%0, %1\\t%@ movhi
6749    mvn%?\\t%0, #%B1\\t%@ movhi
6750    movw%?\\t%0, %L1\\t%@ movhi
6751    strh%?\\t%1, %0\\t%@ movhi
6752    ldrh%?\\t%0, %1\\t%@ movhi"
6753   [(set_attr "predicable" "yes")
6754    (set_attr "pool_range" "*,*,*,*,256")
6755    (set_attr "neg_pool_range" "*,*,*,*,244")
6756    (set_attr "arch" "*,*,v6t2,*,*")
6757    (set_attr_alternative "type"
6758                          [(if_then_else (match_operand 1 "const_int_operand" "")
6759                                         (const_string "mov_imm" )
6760                                         (const_string "mov_reg"))
6761                           (const_string "mvn_imm")
6762                           (const_string "mov_imm")
6763                           (const_string "store_4")
6764                           (const_string "load_4")])]
6767 (define_insn "*movhi_bytes"
6768   [(set (match_operand:HI 0 "s_register_operand" "=r,r,r")
6769         (match_operand:HI 1 "arm_rhs_operand"  "I,rk,K"))]
6770   "TARGET_ARM && !TARGET_HARD_FLOAT"
6771   "@
6772    mov%?\\t%0, %1\\t%@ movhi
6773    mov%?\\t%0, %1\\t%@ movhi
6774    mvn%?\\t%0, #%B1\\t%@ movhi"
6775   [(set_attr "predicable" "yes")
6776    (set_attr "type" "mov_imm,mov_reg,mvn_imm")]
6779 ;; We use a DImode scratch because we may occasionally need an additional
6780 ;; temporary if the address isn't offsettable -- push_reload doesn't seem
6781 ;; to take any notice of the "o" constraints on reload_memory_operand operand.
6782 (define_expand "reload_outhi"
6783   [(parallel [(match_operand:HI 0 "arm_reload_memory_operand" "=o")
6784               (match_operand:HI 1 "s_register_operand"        "r")
6785               (match_operand:DI 2 "s_register_operand"        "=&l")])]
6786   "TARGET_EITHER"
6787   "if (TARGET_ARM)
6788      arm_reload_out_hi (operands);
6789    else
6790      thumb_reload_out_hi (operands);
6791   DONE;
6792   "
6795 (define_expand "reload_inhi"
6796   [(parallel [(match_operand:HI 0 "s_register_operand" "=r")
6797               (match_operand:HI 1 "arm_reload_memory_operand" "o")
6798               (match_operand:DI 2 "s_register_operand" "=&r")])]
6799   "TARGET_EITHER"
6800   "
6801   if (TARGET_ARM)
6802     arm_reload_in_hi (operands);
6803   else
6804     thumb_reload_out_hi (operands);
6805   DONE;
6808 (define_expand "movqi"
6809   [(set (match_operand:QI 0 "general_operand" "")
6810         (match_operand:QI 1 "general_operand" ""))]
6811   "TARGET_EITHER"
6812   "
6813   /* Everything except mem = const or mem = mem can be done easily */
6815   if (can_create_pseudo_p ())
6816     {
6817       if (CONST_INT_P (operands[1]))
6818         {
6819           rtx reg = gen_reg_rtx (SImode);
6821           /* For thumb we want an unsigned immediate, then we are more likely 
6822              to be able to use a movs insn.  */
6823           if (TARGET_THUMB)
6824             operands[1] = GEN_INT (INTVAL (operands[1]) & 255);
6826           emit_insn (gen_movsi (reg, operands[1]));
6827           operands[1] = gen_lowpart (QImode, reg);
6828         }
6830       if (TARGET_THUMB)
6831         {
6832           /* ??? We shouldn't really get invalid addresses here, but this can
6833              happen if we are passed a SP (never OK for HImode/QImode) or
6834              virtual register (also rejected as illegitimate for HImode/QImode)
6835              relative address.  */
6836           /* ??? This should perhaps be fixed elsewhere, for instance, in
6837              fixup_stack_1, by checking for other kinds of invalid addresses,
6838              e.g. a bare reference to a virtual register.  This may confuse the
6839              alpha though, which must handle this case differently.  */
6840           if (MEM_P (operands[0])
6841               && !memory_address_p (GET_MODE (operands[0]),
6842                                      XEXP (operands[0], 0)))
6843             operands[0]
6844               = replace_equiv_address (operands[0],
6845                                        copy_to_reg (XEXP (operands[0], 0)));
6846           if (MEM_P (operands[1])
6847               && !memory_address_p (GET_MODE (operands[1]),
6848                                     XEXP (operands[1], 0)))
6849              operands[1]
6850                = replace_equiv_address (operands[1],
6851                                         copy_to_reg (XEXP (operands[1], 0)));
6852         }
6854       if (MEM_P (operands[1]) && optimize > 0)
6855         {
6856           rtx reg = gen_reg_rtx (SImode);
6858           emit_insn (gen_zero_extendqisi2 (reg, operands[1]));
6859           operands[1] = gen_lowpart (QImode, reg);
6860         }
6862       if (MEM_P (operands[0]))
6863         operands[1] = force_reg (QImode, operands[1]);
6864     }
6865   else if (TARGET_THUMB
6866            && CONST_INT_P (operands[1])
6867            && !satisfies_constraint_I (operands[1]))
6868     {
6869       /* Handle loading a large integer during reload.  */
6871       /* Writing a constant to memory needs a scratch, which should
6872          be handled with SECONDARY_RELOADs.  */
6873       gcc_assert (REG_P (operands[0]));
6875       operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
6876       emit_insn (gen_movsi (operands[0], operands[1]));
6877       DONE;
6878     }
6879   "
6882 (define_insn "*arm_movqi_insn"
6883   [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,r,l,r,l,Uu,r,m")
6884         (match_operand:QI 1 "general_operand" "rk,rk,I,Py,K,Uu,l,Uh,r"))]
6885   "TARGET_32BIT
6886    && (   register_operand (operands[0], QImode)
6887        || register_operand (operands[1], QImode))"
6888   "@
6889    mov%?\\t%0, %1
6890    mov%?\\t%0, %1
6891    mov%?\\t%0, %1
6892    mov%?\\t%0, %1
6893    mvn%?\\t%0, #%B1
6894    ldrb%?\\t%0, %1
6895    strb%?\\t%1, %0
6896    ldrb%?\\t%0, %1
6897    strb%?\\t%1, %0"
6898   [(set_attr "type" "mov_reg,mov_reg,mov_imm,mov_imm,mvn_imm,load_4,store_4,load_4,store_4")
6899    (set_attr "predicable" "yes")
6900    (set_attr "predicable_short_it" "yes,yes,no,yes,no,no,no,no,no")
6901    (set_attr "arch" "t2,any,any,t2,any,t2,t2,any,any")
6902    (set_attr "length" "2,4,4,2,4,2,2,4,4")]
6905 ;; HFmode moves
6906 (define_expand "movhf"
6907   [(set (match_operand:HF 0 "general_operand" "")
6908         (match_operand:HF 1 "general_operand" ""))]
6909   "TARGET_EITHER"
6910   "
6911   if (TARGET_32BIT)
6912     {
6913       if (MEM_P (operands[0]))
6914         operands[1] = force_reg (HFmode, operands[1]);
6915     }
6916   else /* TARGET_THUMB1 */
6917     {
6918       if (can_create_pseudo_p ())
6919         {
6920            if (!REG_P (operands[0]))
6921              operands[1] = force_reg (HFmode, operands[1]);
6922         }
6923     }
6924   "
6927 (define_insn "*arm32_movhf"
6928   [(set (match_operand:HF 0 "nonimmediate_operand" "=r,m,r,r")
6929         (match_operand:HF 1 "general_operand"      " m,r,r,F"))]
6930   "TARGET_32BIT && !TARGET_HARD_FLOAT
6931    && (   s_register_operand (operands[0], HFmode)
6932        || s_register_operand (operands[1], HFmode))"
6933   "*
6934   switch (which_alternative)
6935     {
6936     case 0:     /* ARM register from memory */
6937       return \"ldrh%?\\t%0, %1\\t%@ __fp16\";
6938     case 1:     /* memory from ARM register */
6939       return \"strh%?\\t%1, %0\\t%@ __fp16\";
6940     case 2:     /* ARM register from ARM register */
6941       return \"mov%?\\t%0, %1\\t%@ __fp16\";
6942     case 3:     /* ARM register from constant */
6943       {
6944         long bits;
6945         rtx ops[4];
6947         bits = real_to_target (NULL, CONST_DOUBLE_REAL_VALUE (operands[1]),
6948                                HFmode);
6949         ops[0] = operands[0];
6950         ops[1] = GEN_INT (bits);
6951         ops[2] = GEN_INT (bits & 0xff00);
6952         ops[3] = GEN_INT (bits & 0x00ff);
6954         if (arm_arch_thumb2)
6955           output_asm_insn (\"movw%?\\t%0, %1\", ops);
6956         else
6957           output_asm_insn (\"mov%?\\t%0, %2\;orr%?\\t%0, %0, %3\", ops);
6958         return \"\";
6959        }
6960     default:
6961       gcc_unreachable ();
6962     }
6963   "
6964   [(set_attr "conds" "unconditional")
6965    (set_attr "type" "load_4,store_4,mov_reg,multiple")
6966    (set_attr "length" "4,4,4,8")
6967    (set_attr "predicable" "yes")
6968    (set_attr "predicable_short_it" "no")]
6971 (define_expand "movsf"
6972   [(set (match_operand:SF 0 "general_operand" "")
6973         (match_operand:SF 1 "general_operand" ""))]
6974   "TARGET_EITHER"
6975   "
6976   if (TARGET_32BIT)
6977     {
6978       if (MEM_P (operands[0]))
6979         operands[1] = force_reg (SFmode, operands[1]);
6980     }
6981   else /* TARGET_THUMB1 */
6982     {
6983       if (can_create_pseudo_p ())
6984         {
6985            if (!REG_P (operands[0]))
6986              operands[1] = force_reg (SFmode, operands[1]);
6987         }
6988     }
6989   "
6992 ;; Transform a floating-point move of a constant into a core register into
6993 ;; an SImode operation.
6994 (define_split
6995   [(set (match_operand:SF 0 "arm_general_register_operand" "")
6996         (match_operand:SF 1 "immediate_operand" ""))]
6997   "TARGET_EITHER
6998    && reload_completed
6999    && CONST_DOUBLE_P (operands[1])"
7000   [(set (match_dup 2) (match_dup 3))]
7001   "
7002   operands[2] = gen_lowpart (SImode, operands[0]);
7003   operands[3] = gen_lowpart (SImode, operands[1]);
7004   if (operands[2] == 0 || operands[3] == 0)
7005     FAIL;
7006   "
7009 (define_insn "*arm_movsf_soft_insn"
7010   [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,m")
7011         (match_operand:SF 1 "general_operand"  "r,mE,r"))]
7012   "TARGET_32BIT
7013    && TARGET_SOFT_FLOAT
7014    && (!MEM_P (operands[0])
7015        || register_operand (operands[1], SFmode))"
7016   "@
7017    mov%?\\t%0, %1
7018    ldr%?\\t%0, %1\\t%@ float
7019    str%?\\t%1, %0\\t%@ float"
7020   [(set_attr "predicable" "yes")
7021    (set_attr "predicable_short_it" "no")
7022    (set_attr "type" "mov_reg,load_4,store_4")
7023    (set_attr "arm_pool_range" "*,4096,*")
7024    (set_attr "thumb2_pool_range" "*,4094,*")
7025    (set_attr "arm_neg_pool_range" "*,4084,*")
7026    (set_attr "thumb2_neg_pool_range" "*,0,*")]
7029 (define_expand "movdf"
7030   [(set (match_operand:DF 0 "general_operand" "")
7031         (match_operand:DF 1 "general_operand" ""))]
7032   "TARGET_EITHER"
7033   "
7034   if (TARGET_32BIT)
7035     {
7036       if (MEM_P (operands[0]))
7037         operands[1] = force_reg (DFmode, operands[1]);
7038     }
7039   else /* TARGET_THUMB */
7040     {
7041       if (can_create_pseudo_p ())
7042         {
7043           if (!REG_P (operands[0]))
7044             operands[1] = force_reg (DFmode, operands[1]);
7045         }
7046     }
7047   "
7050 ;; Reloading a df mode value stored in integer regs to memory can require a
7051 ;; scratch reg.
7052 (define_expand "reload_outdf"
7053   [(match_operand:DF 0 "arm_reload_memory_operand" "=o")
7054    (match_operand:DF 1 "s_register_operand" "r")
7055    (match_operand:SI 2 "s_register_operand" "=&r")]
7056   "TARGET_THUMB2"
7057   "
7058   {
7059     enum rtx_code code = GET_CODE (XEXP (operands[0], 0));
7061     if (code == REG)
7062       operands[2] = XEXP (operands[0], 0);
7063     else if (code == POST_INC || code == PRE_DEC)
7064       {
7065         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7066         operands[1] = gen_rtx_SUBREG (DImode, operands[1], 0);
7067         emit_insn (gen_movdi (operands[0], operands[1]));
7068         DONE;
7069       }
7070     else if (code == PRE_INC)
7071       {
7072         rtx reg = XEXP (XEXP (operands[0], 0), 0);
7074         emit_insn (gen_addsi3 (reg, reg, GEN_INT (8)));
7075         operands[2] = reg;
7076       }
7077     else if (code == POST_DEC)
7078       operands[2] = XEXP (XEXP (operands[0], 0), 0);
7079     else
7080       emit_insn (gen_addsi3 (operands[2], XEXP (XEXP (operands[0], 0), 0),
7081                              XEXP (XEXP (operands[0], 0), 1)));
7083     emit_insn (gen_rtx_SET (replace_equiv_address (operands[0], operands[2]),
7084                             operands[1]));
7086     if (code == POST_DEC)
7087       emit_insn (gen_addsi3 (operands[2], operands[2], GEN_INT (-8)));
7089     DONE;
7090   }"
7093 (define_insn "*movdf_soft_insn"
7094   [(set (match_operand:DF 0 "nonimmediate_soft_df_operand" "=r,r,r,q,m")
7095         (match_operand:DF 1 "soft_df_operand" "rDa,Db,Dc,mF,q"))]
7096   "TARGET_32BIT && TARGET_SOFT_FLOAT
7097    && (   register_operand (operands[0], DFmode)
7098        || register_operand (operands[1], DFmode))"
7099   "*
7100   switch (which_alternative)
7101     {
7102     case 0:
7103     case 1:
7104     case 2:
7105       return \"#\";
7106     default:
7107       return output_move_double (operands, true, NULL);
7108     }
7109   "
7110   [(set_attr "length" "8,12,16,8,8")
7111    (set_attr "type" "multiple,multiple,multiple,load_8,store_8")
7112    (set_attr "arm_pool_range" "*,*,*,1020,*")
7113    (set_attr "thumb2_pool_range" "*,*,*,1018,*")
7114    (set_attr "arm_neg_pool_range" "*,*,*,1004,*")
7115    (set_attr "thumb2_neg_pool_range" "*,*,*,0,*")]
7119 ;; load- and store-multiple insns
7120 ;; The arm can load/store any set of registers, provided that they are in
7121 ;; ascending order, but these expanders assume a contiguous set.
7123 (define_expand "load_multiple"
7124   [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
7125                           (match_operand:SI 1 "" ""))
7126                      (use (match_operand:SI 2 "" ""))])]
7127   "TARGET_32BIT"
7129   HOST_WIDE_INT offset = 0;
7131   /* Support only fixed point registers.  */
7132   if (!CONST_INT_P (operands[2])
7133       || INTVAL (operands[2]) > MAX_LDM_STM_OPS
7134       || INTVAL (operands[2]) < 2
7135       || !MEM_P (operands[1])
7136       || !REG_P (operands[0])
7137       || REGNO (operands[0]) > (LAST_ARM_REGNUM - 1)
7138       || REGNO (operands[0]) + INTVAL (operands[2]) > LAST_ARM_REGNUM)
7139     FAIL;
7141   operands[3]
7142     = arm_gen_load_multiple (arm_regs_in_sequence + REGNO (operands[0]),
7143                              INTVAL (operands[2]),
7144                              force_reg (SImode, XEXP (operands[1], 0)),
7145                              FALSE, operands[1], &offset);
7148 (define_expand "store_multiple"
7149   [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
7150                           (match_operand:SI 1 "" ""))
7151                      (use (match_operand:SI 2 "" ""))])]
7152   "TARGET_32BIT"
7154   HOST_WIDE_INT offset = 0;
7156   /* Support only fixed point registers.  */
7157   if (!CONST_INT_P (operands[2])
7158       || INTVAL (operands[2]) > MAX_LDM_STM_OPS
7159       || INTVAL (operands[2]) < 2
7160       || !REG_P (operands[1])
7161       || !MEM_P (operands[0])
7162       || REGNO (operands[1]) > (LAST_ARM_REGNUM - 1)
7163       || REGNO (operands[1]) + INTVAL (operands[2]) > LAST_ARM_REGNUM)
7164     FAIL;
7166   operands[3]
7167     = arm_gen_store_multiple (arm_regs_in_sequence + REGNO (operands[1]),
7168                               INTVAL (operands[2]),
7169                               force_reg (SImode, XEXP (operands[0], 0)),
7170                               FALSE, operands[0], &offset);
7174 (define_expand "setmemsi"
7175   [(match_operand:BLK 0 "general_operand" "")
7176    (match_operand:SI 1 "const_int_operand" "")
7177    (match_operand:SI 2 "const_int_operand" "")
7178    (match_operand:SI 3 "const_int_operand" "")]
7179   "TARGET_32BIT"
7181   if (arm_gen_setmem (operands))
7182     DONE;
7184   FAIL;
7188 ;; Move a block of memory if it is word aligned and MORE than 2 words long.
7189 ;; We could let this apply for blocks of less than this, but it clobbers so
7190 ;; many registers that there is then probably a better way.
7192 (define_expand "movmemqi"
7193   [(match_operand:BLK 0 "general_operand" "")
7194    (match_operand:BLK 1 "general_operand" "")
7195    (match_operand:SI 2 "const_int_operand" "")
7196    (match_operand:SI 3 "const_int_operand" "")]
7197   ""
7198   "
7199   if (TARGET_32BIT)
7200     {
7201       if (TARGET_LDRD && current_tune->prefer_ldrd_strd
7202           && !optimize_function_for_size_p (cfun))
7203         {
7204           if (gen_movmem_ldrd_strd (operands))
7205             DONE;
7206           FAIL;
7207         }
7209       if (arm_gen_movmemqi (operands))
7210         DONE;
7211       FAIL;
7212     }
7213   else /* TARGET_THUMB1 */
7214     {
7215       if (   INTVAL (operands[3]) != 4
7216           || INTVAL (operands[2]) > 48)
7217         FAIL;
7219       thumb_expand_movmemqi (operands);
7220       DONE;
7221     }
7222   "
7226 ;; Compare & branch insns
7227 ;; The range calculations are based as follows:
7228 ;; For forward branches, the address calculation returns the address of
7229 ;; the next instruction.  This is 2 beyond the branch instruction.
7230 ;; For backward branches, the address calculation returns the address of
7231 ;; the first instruction in this pattern (cmp).  This is 2 before the branch
7232 ;; instruction for the shortest sequence, and 4 before the branch instruction
7233 ;; if we have to jump around an unconditional branch.
7234 ;; To the basic branch range the PC offset must be added (this is +4).
7235 ;; So for forward branches we have 
7236 ;;   (pos_range - pos_base_offs + pc_offs) = (pos_range - 2 + 4).
7237 ;; And for backward branches we have 
7238 ;;   (neg_range - neg_base_offs + pc_offs) = (neg_range - (-2 or -4) + 4).
7240 ;; For a 'b'       pos_range = 2046, neg_range = -2048 giving (-2040->2048).
7241 ;; For a 'b<cond>' pos_range = 254,  neg_range = -256  giving (-250 ->256).
7243 (define_expand "cbranchsi4"
7244   [(set (pc) (if_then_else
7245               (match_operator 0 "expandable_comparison_operator"
7246                [(match_operand:SI 1 "s_register_operand" "")
7247                 (match_operand:SI 2 "nonmemory_operand" "")])
7248               (label_ref (match_operand 3 "" ""))
7249               (pc)))]
7250   "TARGET_EITHER"
7251   "
7252   if (!TARGET_THUMB1)
7253     {
7254       if (!arm_validize_comparison (&operands[0], &operands[1], &operands[2]))
7255         FAIL;
7256       emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
7257                                       operands[3]));
7258       DONE;
7259     }
7260   if (thumb1_cmpneg_operand (operands[2], SImode))
7261     {
7262       emit_jump_insn (gen_cbranchsi4_scratch (NULL, operands[1], operands[2],
7263                                               operands[3], operands[0]));
7264       DONE;
7265     }
7266   if (!thumb1_cmp_operand (operands[2], SImode))
7267     operands[2] = force_reg (SImode, operands[2]);
7268   ")
7270 (define_expand "cbranchsf4"
7271   [(set (pc) (if_then_else
7272               (match_operator 0 "expandable_comparison_operator"
7273                [(match_operand:SF 1 "s_register_operand" "")
7274                 (match_operand:SF 2 "vfp_compare_operand" "")])
7275               (label_ref (match_operand 3 "" ""))
7276               (pc)))]
7277   "TARGET_32BIT && TARGET_HARD_FLOAT"
7278   "emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
7279                                    operands[3])); DONE;"
7282 (define_expand "cbranchdf4"
7283   [(set (pc) (if_then_else
7284               (match_operator 0 "expandable_comparison_operator"
7285                [(match_operand:DF 1 "s_register_operand" "")
7286                 (match_operand:DF 2 "vfp_compare_operand" "")])
7287               (label_ref (match_operand 3 "" ""))
7288               (pc)))]
7289   "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
7290   "emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
7291                                    operands[3])); DONE;"
7294 (define_expand "cbranchdi4"
7295   [(set (pc) (if_then_else
7296               (match_operator 0 "expandable_comparison_operator"
7297                [(match_operand:DI 1 "s_register_operand" "")
7298                 (match_operand:DI 2 "cmpdi_operand" "")])
7299               (label_ref (match_operand 3 "" ""))
7300               (pc)))]
7301   "TARGET_32BIT"
7302   "{
7303      if (!arm_validize_comparison (&operands[0], &operands[1], &operands[2]))
7304        FAIL;
7305      emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
7306                                        operands[3]));
7307      DONE;
7308    }"
7311 ;; Comparison and test insns
7313 (define_insn "*arm_cmpsi_insn"
7314   [(set (reg:CC CC_REGNUM)
7315         (compare:CC (match_operand:SI 0 "s_register_operand" "l,r,r,r,r")
7316                     (match_operand:SI 1 "arm_add_operand"    "Py,r,r,I,L")))]
7317   "TARGET_32BIT"
7318   "@
7319    cmp%?\\t%0, %1
7320    cmp%?\\t%0, %1
7321    cmp%?\\t%0, %1
7322    cmp%?\\t%0, %1
7323    cmn%?\\t%0, #%n1"
7324   [(set_attr "conds" "set")
7325    (set_attr "arch" "t2,t2,any,any,any")
7326    (set_attr "length" "2,2,4,4,4")
7327    (set_attr "predicable" "yes")
7328    (set_attr "predicable_short_it" "yes,yes,yes,no,no")
7329    (set_attr "type" "alus_imm,alus_sreg,alus_sreg,alus_imm,alus_imm")]
7332 (define_insn "*cmpsi_shiftsi"
7333   [(set (reg:CC CC_REGNUM)
7334         (compare:CC (match_operand:SI   0 "s_register_operand" "r,r,r")
7335                     (match_operator:SI  3 "shift_operator"
7336                      [(match_operand:SI 1 "s_register_operand" "r,r,r")
7337                       (match_operand:SI 2 "shift_amount_operand" "M,r,M")])))]
7338   "TARGET_32BIT"
7339   "cmp\\t%0, %1%S3"
7340   [(set_attr "conds" "set")
7341    (set_attr "shift" "1")
7342    (set_attr "arch" "32,a,a")
7343    (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
7345 (define_insn "*cmpsi_shiftsi_swp"
7346   [(set (reg:CC_SWP CC_REGNUM)
7347         (compare:CC_SWP (match_operator:SI 3 "shift_operator"
7348                          [(match_operand:SI 1 "s_register_operand" "r,r,r")
7349                           (match_operand:SI 2 "shift_amount_operand" "M,r,M")])
7350                         (match_operand:SI 0 "s_register_operand" "r,r,r")))]
7351   "TARGET_32BIT"
7352   "cmp%?\\t%0, %1%S3"
7353   [(set_attr "conds" "set")
7354    (set_attr "shift" "1")
7355    (set_attr "arch" "32,a,a")
7356    (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
7358 (define_insn "*arm_cmpsi_negshiftsi_si"
7359   [(set (reg:CC_Z CC_REGNUM)
7360         (compare:CC_Z
7361          (neg:SI (match_operator:SI 1 "shift_operator"
7362                     [(match_operand:SI 2 "s_register_operand" "r")
7363                      (match_operand:SI 3 "reg_or_int_operand" "rM")]))
7364          (match_operand:SI 0 "s_register_operand" "r")))]
7365   "TARGET_ARM"
7366   "cmn%?\\t%0, %2%S1"
7367   [(set_attr "conds" "set")
7368    (set (attr "type") (if_then_else (match_operand 3 "const_int_operand" "")
7369                                     (const_string "alus_shift_imm")
7370                                     (const_string "alus_shift_reg")))
7371    (set_attr "predicable" "yes")]
7374 ;; DImode comparisons.  The generic code generates branches that
7375 ;; if-conversion can not reduce to a conditional compare, so we do
7376 ;; that directly.
7378 (define_insn_and_split "*arm_cmpdi_insn"
7379   [(set (reg:CC_NCV CC_REGNUM)
7380         (compare:CC_NCV (match_operand:DI 0 "s_register_operand" "r")
7381                         (match_operand:DI 1 "arm_di_operand"       "rDi")))
7382    (clobber (match_scratch:SI 2 "=r"))]
7383   "TARGET_32BIT"
7384   "#"   ; "cmp\\t%Q0, %Q1\;sbcs\\t%2, %R0, %R1"
7385   "&& reload_completed"
7386   [(set (reg:CC CC_REGNUM)
7387         (compare:CC (match_dup 0) (match_dup 1)))
7388    (parallel [(set (reg:CC CC_REGNUM)
7389                    (compare:CC (match_dup 3) (match_dup 4)))
7390               (set (match_dup 2)
7391                    (minus:SI (match_dup 5)
7392                             (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))])]
7393   {
7394     operands[3] = gen_highpart (SImode, operands[0]);
7395     operands[0] = gen_lowpart (SImode, operands[0]);
7396     if (CONST_INT_P (operands[1]))
7397       {
7398         operands[4] = GEN_INT (~INTVAL (gen_highpart_mode (SImode,
7399                                                            DImode,
7400                                                            operands[1])));
7401         operands[5] = gen_rtx_PLUS (SImode, operands[3], operands[4]);
7402       }
7403     else
7404       {
7405         operands[4] = gen_highpart (SImode, operands[1]);
7406         operands[5] = gen_rtx_MINUS (SImode, operands[3], operands[4]);
7407       }
7408     operands[1] = gen_lowpart (SImode, operands[1]);
7409     operands[2] = gen_lowpart (SImode, operands[2]);
7410   }
7411   [(set_attr "conds" "set")
7412    (set_attr "length" "8")
7413    (set_attr "type" "multiple")]
7416 (define_insn_and_split "*arm_cmpdi_unsigned"
7417   [(set (reg:CC_CZ CC_REGNUM)
7418         (compare:CC_CZ (match_operand:DI 0 "s_register_operand" "l,r,r,r")
7419                        (match_operand:DI 1 "arm_di_operand"     "Py,r,Di,rDi")))]
7421   "TARGET_32BIT"
7422   "#"   ; "cmp\\t%R0, %R1\;it eq\;cmpeq\\t%Q0, %Q1"
7423   "&& reload_completed"
7424   [(set (reg:CC CC_REGNUM)
7425         (compare:CC (match_dup 2) (match_dup 3)))
7426    (cond_exec (eq:SI (reg:CC CC_REGNUM) (const_int 0))
7427               (set (reg:CC CC_REGNUM)
7428                    (compare:CC (match_dup 0) (match_dup 1))))]
7429   {
7430     operands[2] = gen_highpart (SImode, operands[0]);
7431     operands[0] = gen_lowpart (SImode, operands[0]);
7432     if (CONST_INT_P (operands[1]))
7433       operands[3] = gen_highpart_mode (SImode, DImode, operands[1]);
7434     else
7435       operands[3] = gen_highpart (SImode, operands[1]);
7436     operands[1] = gen_lowpart (SImode, operands[1]);
7437   }
7438   [(set_attr "conds" "set")
7439    (set_attr "enabled_for_depr_it" "yes,yes,no,*")
7440    (set_attr "arch" "t2,t2,t2,a")
7441    (set_attr "length" "6,6,10,8")
7442    (set_attr "type" "multiple")]
7445 (define_insn "*arm_cmpdi_zero"
7446   [(set (reg:CC_Z CC_REGNUM)
7447         (compare:CC_Z (match_operand:DI 0 "s_register_operand" "r")
7448                       (const_int 0)))
7449    (clobber (match_scratch:SI 1 "=r"))]
7450   "TARGET_32BIT"
7451   "orrs%?\\t%1, %Q0, %R0"
7452   [(set_attr "conds" "set")
7453    (set_attr "type" "logics_reg")]
7456 ; This insn allows redundant compares to be removed by cse, nothing should
7457 ; ever appear in the output file since (set (reg x) (reg x)) is a no-op that
7458 ; is deleted later on. The match_dup will match the mode here, so that
7459 ; mode changes of the condition codes aren't lost by this even though we don't
7460 ; specify what they are.
7462 (define_insn "*deleted_compare"
7463   [(set (match_operand 0 "cc_register" "") (match_dup 0))]
7464   "TARGET_32BIT"
7465   "\\t%@ deleted compare"
7466   [(set_attr "conds" "set")
7467    (set_attr "length" "0")
7468    (set_attr "type" "no_insn")]
7472 ;; Conditional branch insns
7474 (define_expand "cbranch_cc"
7475   [(set (pc)
7476         (if_then_else (match_operator 0 "" [(match_operand 1 "" "")
7477                                             (match_operand 2 "" "")])
7478                       (label_ref (match_operand 3 "" ""))
7479                       (pc)))]
7480   "TARGET_32BIT"
7481   "operands[1] = arm_gen_compare_reg (GET_CODE (operands[0]),
7482                                       operands[1], operands[2], NULL_RTX);
7483    operands[2] = const0_rtx;"
7487 ;; Patterns to match conditional branch insns.
7490 (define_insn "arm_cond_branch"
7491   [(set (pc)
7492         (if_then_else (match_operator 1 "arm_comparison_operator"
7493                        [(match_operand 2 "cc_register" "") (const_int 0)])
7494                       (label_ref (match_operand 0 "" ""))
7495                       (pc)))]
7496   "TARGET_32BIT"
7497   "*
7498   if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
7499     {
7500       arm_ccfsm_state += 2;
7501       return \"\";
7502     }
7503   return \"b%d1\\t%l0\";
7504   "
7505   [(set_attr "conds" "use")
7506    (set_attr "type" "branch")
7507    (set (attr "length")
7508         (if_then_else
7509            (and (match_test "TARGET_THUMB2")
7510                 (and (ge (minus (match_dup 0) (pc)) (const_int -250))
7511                      (le (minus (match_dup 0) (pc)) (const_int 256))))
7512            (const_int 2)
7513            (const_int 4)))]
7516 (define_insn "*arm_cond_branch_reversed"
7517   [(set (pc)
7518         (if_then_else (match_operator 1 "arm_comparison_operator"
7519                        [(match_operand 2 "cc_register" "") (const_int 0)])
7520                       (pc)
7521                       (label_ref (match_operand 0 "" ""))))]
7522   "TARGET_32BIT"
7523   "*
7524   if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
7525     {
7526       arm_ccfsm_state += 2;
7527       return \"\";
7528     }
7529   return \"b%D1\\t%l0\";
7530   "
7531   [(set_attr "conds" "use")
7532    (set_attr "type" "branch")
7533    (set (attr "length")
7534         (if_then_else
7535            (and (match_test "TARGET_THUMB2")
7536                 (and (ge (minus (match_dup 0) (pc)) (const_int -250))
7537                      (le (minus (match_dup 0) (pc)) (const_int 256))))
7538            (const_int 2)
7539            (const_int 4)))]
7544 ; scc insns
7546 (define_expand "cstore_cc"
7547   [(set (match_operand:SI 0 "s_register_operand" "")
7548         (match_operator:SI 1 "" [(match_operand 2 "" "")
7549                                  (match_operand 3 "" "")]))]
7550   "TARGET_32BIT"
7551   "operands[2] = arm_gen_compare_reg (GET_CODE (operands[1]),
7552                                       operands[2], operands[3], NULL_RTX);
7553    operands[3] = const0_rtx;"
7556 (define_insn_and_split "*mov_scc"
7557   [(set (match_operand:SI 0 "s_register_operand" "=r")
7558         (match_operator:SI 1 "arm_comparison_operator_mode"
7559          [(match_operand 2 "cc_register" "") (const_int 0)]))]
7560   "TARGET_ARM"
7561   "#"   ; "mov%D1\\t%0, #0\;mov%d1\\t%0, #1"
7562   "TARGET_ARM"
7563   [(set (match_dup 0)
7564         (if_then_else:SI (match_dup 1)
7565                          (const_int 1)
7566                          (const_int 0)))]
7567   ""
7568   [(set_attr "conds" "use")
7569    (set_attr "length" "8")
7570    (set_attr "type" "multiple")]
7573 (define_insn_and_split "*mov_negscc"
7574   [(set (match_operand:SI 0 "s_register_operand" "=r")
7575         (neg:SI (match_operator:SI 1 "arm_comparison_operator_mode"
7576                  [(match_operand 2 "cc_register" "") (const_int 0)])))]
7577   "TARGET_ARM"
7578   "#"   ; "mov%D1\\t%0, #0\;mvn%d1\\t%0, #0"
7579   "TARGET_ARM"
7580   [(set (match_dup 0)
7581         (if_then_else:SI (match_dup 1)
7582                          (match_dup 3)
7583                          (const_int 0)))]
7584   {
7585     operands[3] = GEN_INT (~0);
7586   }
7587   [(set_attr "conds" "use")
7588    (set_attr "length" "8")
7589    (set_attr "type" "multiple")]
7592 (define_insn_and_split "*mov_notscc"
7593   [(set (match_operand:SI 0 "s_register_operand" "=r")
7594         (not:SI (match_operator:SI 1 "arm_comparison_operator"
7595                  [(match_operand 2 "cc_register" "") (const_int 0)])))]
7596   "TARGET_ARM"
7597   "#"   ; "mvn%D1\\t%0, #0\;mvn%d1\\t%0, #1"
7598   "TARGET_ARM"
7599   [(set (match_dup 0)
7600         (if_then_else:SI (match_dup 1)
7601                          (match_dup 3)
7602                          (match_dup 4)))]
7603   {
7604     operands[3] = GEN_INT (~1);
7605     operands[4] = GEN_INT (~0);
7606   }
7607   [(set_attr "conds" "use")
7608    (set_attr "length" "8")
7609    (set_attr "type" "multiple")]
7612 (define_expand "cstoresi4"
7613   [(set (match_operand:SI 0 "s_register_operand" "")
7614         (match_operator:SI 1 "expandable_comparison_operator"
7615          [(match_operand:SI 2 "s_register_operand" "")
7616           (match_operand:SI 3 "reg_or_int_operand" "")]))]
7617   "TARGET_32BIT || TARGET_THUMB1"
7618   "{
7619   rtx op3, scratch, scratch2;
7621   if (!TARGET_THUMB1)
7622     {
7623       if (!arm_add_operand (operands[3], SImode))
7624         operands[3] = force_reg (SImode, operands[3]);
7625       emit_insn (gen_cstore_cc (operands[0], operands[1],
7626                                 operands[2], operands[3]));
7627       DONE;
7628     }
7630   if (operands[3] == const0_rtx)
7631     {
7632       switch (GET_CODE (operands[1]))
7633         {
7634         case EQ:
7635           emit_insn (gen_cstoresi_eq0_thumb1 (operands[0], operands[2]));
7636           break;
7638         case NE:
7639           emit_insn (gen_cstoresi_ne0_thumb1 (operands[0], operands[2]));
7640           break;
7642         case LE:
7643           scratch = expand_binop (SImode, add_optab, operands[2], constm1_rtx,
7644                                   NULL_RTX, 0, OPTAB_WIDEN);
7645           scratch = expand_binop (SImode, ior_optab, operands[2], scratch,
7646                                   NULL_RTX, 0, OPTAB_WIDEN);
7647           expand_binop (SImode, lshr_optab, scratch, GEN_INT (31),
7648                         operands[0], 1, OPTAB_WIDEN);
7649           break;
7651         case GE:
7652           scratch = expand_unop (SImode, one_cmpl_optab, operands[2],
7653                                  NULL_RTX, 1);
7654           expand_binop (SImode, lshr_optab, scratch, GEN_INT (31),
7655                         NULL_RTX, 1, OPTAB_WIDEN);
7656           break;
7658         case GT:
7659           scratch = expand_binop (SImode, ashr_optab, operands[2],
7660                                   GEN_INT (31), NULL_RTX, 0, OPTAB_WIDEN);
7661           scratch = expand_binop (SImode, sub_optab, scratch, operands[2],
7662                                   NULL_RTX, 0, OPTAB_WIDEN);
7663           expand_binop (SImode, lshr_optab, scratch, GEN_INT (31), operands[0],
7664                         0, OPTAB_WIDEN);
7665           break;
7667         /* LT is handled by generic code.  No need for unsigned with 0.  */
7668         default:
7669           FAIL;
7670         }
7671       DONE;
7672     }
7674   switch (GET_CODE (operands[1]))
7675     {
7676     case EQ:
7677       scratch = expand_binop (SImode, sub_optab, operands[2], operands[3],
7678                               NULL_RTX, 0, OPTAB_WIDEN);
7679       emit_insn (gen_cstoresi_eq0_thumb1 (operands[0], scratch));
7680       break;
7682     case NE:
7683       scratch = expand_binop (SImode, sub_optab, operands[2], operands[3],
7684                               NULL_RTX, 0, OPTAB_WIDEN);
7685       emit_insn (gen_cstoresi_ne0_thumb1 (operands[0], scratch));
7686       break;
7688     case LE:
7689       op3 = force_reg (SImode, operands[3]);
7691       scratch = expand_binop (SImode, lshr_optab, operands[2], GEN_INT (31),
7692                               NULL_RTX, 1, OPTAB_WIDEN);
7693       scratch2 = expand_binop (SImode, ashr_optab, op3, GEN_INT (31),
7694                               NULL_RTX, 0, OPTAB_WIDEN);
7695       emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch2,
7696                                           op3, operands[2]));
7697       break;
7699     case GE:
7700       op3 = operands[3];
7701       if (!thumb1_cmp_operand (op3, SImode))
7702         op3 = force_reg (SImode, op3);
7703       scratch = expand_binop (SImode, ashr_optab, operands[2], GEN_INT (31),
7704                               NULL_RTX, 0, OPTAB_WIDEN);
7705       scratch2 = expand_binop (SImode, lshr_optab, op3, GEN_INT (31),
7706                                NULL_RTX, 1, OPTAB_WIDEN);
7707       emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch2,
7708                                           operands[2], op3));
7709       break;
7711     case LEU:
7712       op3 = force_reg (SImode, operands[3]);
7713       scratch = force_reg (SImode, const0_rtx);
7714       emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch,
7715                                           op3, operands[2]));
7716       break;
7718     case GEU:
7719       op3 = operands[3];
7720       if (!thumb1_cmp_operand (op3, SImode))
7721         op3 = force_reg (SImode, op3);
7722       scratch = force_reg (SImode, const0_rtx);
7723       emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch,
7724                                           operands[2], op3));
7725       break;
7727     case LTU:
7728       op3 = operands[3];
7729       if (!thumb1_cmp_operand (op3, SImode))
7730         op3 = force_reg (SImode, op3);
7731       scratch = gen_reg_rtx (SImode);
7732       emit_insn (gen_cstoresi_ltu_thumb1 (operands[0], operands[2], op3));
7733       break;
7735     case GTU:
7736       op3 = force_reg (SImode, operands[3]);
7737       scratch = gen_reg_rtx (SImode);
7738       emit_insn (gen_cstoresi_ltu_thumb1 (operands[0], op3, operands[2]));
7739       break;
7741     /* No good sequences for GT, LT.  */
7742     default:
7743       FAIL;
7744     }
7745   DONE;
7748 (define_expand "cstorehf4"
7749   [(set (match_operand:SI 0 "s_register_operand")
7750         (match_operator:SI 1 "expandable_comparison_operator"
7751          [(match_operand:HF 2 "s_register_operand")
7752           (match_operand:HF 3 "vfp_compare_operand")]))]
7753   "TARGET_VFP_FP16INST"
7754   {
7755     if (!arm_validize_comparison (&operands[1],
7756                                   &operands[2],
7757                                   &operands[3]))
7758        FAIL;
7760     emit_insn (gen_cstore_cc (operands[0], operands[1],
7761                               operands[2], operands[3]));
7762     DONE;
7763   }
7766 (define_expand "cstoresf4"
7767   [(set (match_operand:SI 0 "s_register_operand" "")
7768         (match_operator:SI 1 "expandable_comparison_operator"
7769          [(match_operand:SF 2 "s_register_operand" "")
7770           (match_operand:SF 3 "vfp_compare_operand" "")]))]
7771   "TARGET_32BIT && TARGET_HARD_FLOAT"
7772   "emit_insn (gen_cstore_cc (operands[0], operands[1],
7773                              operands[2], operands[3])); DONE;"
7776 (define_expand "cstoredf4"
7777   [(set (match_operand:SI 0 "s_register_operand" "")
7778         (match_operator:SI 1 "expandable_comparison_operator"
7779          [(match_operand:DF 2 "s_register_operand" "")
7780           (match_operand:DF 3 "vfp_compare_operand" "")]))]
7781   "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
7782   "emit_insn (gen_cstore_cc (operands[0], operands[1],
7783                              operands[2], operands[3])); DONE;"
7786 (define_expand "cstoredi4"
7787   [(set (match_operand:SI 0 "s_register_operand" "")
7788         (match_operator:SI 1 "expandable_comparison_operator"
7789          [(match_operand:DI 2 "s_register_operand" "")
7790           (match_operand:DI 3 "cmpdi_operand" "")]))]
7791   "TARGET_32BIT"
7792   "{
7793      if (!arm_validize_comparison (&operands[1],
7794                                    &operands[2],
7795                                    &operands[3]))
7796        FAIL;
7797      emit_insn (gen_cstore_cc (operands[0], operands[1], operands[2],
7798                                  operands[3]));
7799      DONE;
7800    }"
7804 ;; Conditional move insns
7806 (define_expand "movsicc"
7807   [(set (match_operand:SI 0 "s_register_operand" "")
7808         (if_then_else:SI (match_operand 1 "expandable_comparison_operator" "")
7809                          (match_operand:SI 2 "arm_not_operand" "")
7810                          (match_operand:SI 3 "arm_not_operand" "")))]
7811   "TARGET_32BIT"
7812   "
7813   {
7814     enum rtx_code code;
7815     rtx ccreg;
7817     if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0), 
7818                                   &XEXP (operands[1], 1)))
7819       FAIL;
7821     code = GET_CODE (operands[1]);
7822     ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
7823                                  XEXP (operands[1], 1), NULL_RTX);
7824     operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7825   }"
7828 (define_expand "movhfcc"
7829   [(set (match_operand:HF 0 "s_register_operand")
7830         (if_then_else:HF (match_operand 1 "arm_cond_move_operator")
7831                          (match_operand:HF 2 "s_register_operand")
7832                          (match_operand:HF 3 "s_register_operand")))]
7833   "TARGET_VFP_FP16INST"
7834   "
7835   {
7836     enum rtx_code code = GET_CODE (operands[1]);
7837     rtx ccreg;
7839     if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
7840                                   &XEXP (operands[1], 1)))
7841       FAIL;
7843     code = GET_CODE (operands[1]);
7844     ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
7845                                  XEXP (operands[1], 1), NULL_RTX);
7846     operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7847   }"
7850 (define_expand "movsfcc"
7851   [(set (match_operand:SF 0 "s_register_operand" "")
7852         (if_then_else:SF (match_operand 1 "arm_cond_move_operator" "")
7853                          (match_operand:SF 2 "s_register_operand" "")
7854                          (match_operand:SF 3 "s_register_operand" "")))]
7855   "TARGET_32BIT && TARGET_HARD_FLOAT"
7856   "
7857   {
7858     enum rtx_code code = GET_CODE (operands[1]);
7859     rtx ccreg;
7861     if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
7862                                   &XEXP (operands[1], 1)))
7863        FAIL;
7865     code = GET_CODE (operands[1]);
7866     ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
7867                                  XEXP (operands[1], 1), NULL_RTX);
7868     operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7869   }"
7872 (define_expand "movdfcc"
7873   [(set (match_operand:DF 0 "s_register_operand" "")
7874         (if_then_else:DF (match_operand 1 "arm_cond_move_operator" "")
7875                          (match_operand:DF 2 "s_register_operand" "")
7876                          (match_operand:DF 3 "s_register_operand" "")))]
7877   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
7878   "
7879   {
7880     enum rtx_code code = GET_CODE (operands[1]);
7881     rtx ccreg;
7883     if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0), 
7884                                   &XEXP (operands[1], 1)))
7885        FAIL;
7886     code = GET_CODE (operands[1]);
7887     ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
7888                                  XEXP (operands[1], 1), NULL_RTX);
7889     operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7890   }"
7893 (define_insn "*cmov<mode>"
7894     [(set (match_operand:SDF 0 "s_register_operand" "=<F_constraint>")
7895         (if_then_else:SDF (match_operator 1 "arm_vsel_comparison_operator"
7896                           [(match_operand 2 "cc_register" "") (const_int 0)])
7897                           (match_operand:SDF 3 "s_register_operand"
7898                                               "<F_constraint>")
7899                           (match_operand:SDF 4 "s_register_operand"
7900                                               "<F_constraint>")))]
7901   "TARGET_HARD_FLOAT && TARGET_VFP5 <vfp_double_cond>"
7902   "*
7903   {
7904     enum arm_cond_code code = maybe_get_arm_condition_code (operands[1]);
7905     switch (code)
7906       {
7907       case ARM_GE:
7908       case ARM_GT:
7909       case ARM_EQ:
7910       case ARM_VS:
7911         return \"vsel%d1.<V_if_elem>\\t%<V_reg>0, %<V_reg>3, %<V_reg>4\";
7912       case ARM_LT:
7913       case ARM_LE:
7914       case ARM_NE:
7915       case ARM_VC:
7916         return \"vsel%D1.<V_if_elem>\\t%<V_reg>0, %<V_reg>4, %<V_reg>3\";
7917       default:
7918         gcc_unreachable ();
7919       }
7920     return \"\";
7921   }"
7922   [(set_attr "conds" "use")
7923    (set_attr "type" "fcsel")]
7926 (define_insn "*cmovhf"
7927     [(set (match_operand:HF 0 "s_register_operand" "=t")
7928         (if_then_else:HF (match_operator 1 "arm_vsel_comparison_operator"
7929                          [(match_operand 2 "cc_register" "") (const_int 0)])
7930                           (match_operand:HF 3 "s_register_operand" "t")
7931                           (match_operand:HF 4 "s_register_operand" "t")))]
7932   "TARGET_VFP_FP16INST"
7933   "*
7934   {
7935     enum arm_cond_code code = maybe_get_arm_condition_code (operands[1]);
7936     switch (code)
7937       {
7938       case ARM_GE:
7939       case ARM_GT:
7940       case ARM_EQ:
7941       case ARM_VS:
7942         return \"vsel%d1.f16\\t%0, %3, %4\";
7943       case ARM_LT:
7944       case ARM_LE:
7945       case ARM_NE:
7946       case ARM_VC:
7947         return \"vsel%D1.f16\\t%0, %4, %3\";
7948       default:
7949         gcc_unreachable ();
7950       }
7951     return \"\";
7952   }"
7953   [(set_attr "conds" "use")
7954    (set_attr "type" "fcsel")]
7957 (define_insn_and_split "*movsicc_insn"
7958   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r,r,r,r,r")
7959         (if_then_else:SI
7960          (match_operator 3 "arm_comparison_operator"
7961           [(match_operand 4 "cc_register" "") (const_int 0)])
7962          (match_operand:SI 1 "arm_not_operand" "0,0,rI,K,rI,rI,K,K")
7963          (match_operand:SI 2 "arm_not_operand" "rI,K,0,0,rI,K,rI,K")))]
7964   "TARGET_ARM"
7965   "@
7966    mov%D3\\t%0, %2
7967    mvn%D3\\t%0, #%B2
7968    mov%d3\\t%0, %1
7969    mvn%d3\\t%0, #%B1
7970    #
7971    #
7972    #
7973    #"
7974    ; alt4: mov%d3\\t%0, %1\;mov%D3\\t%0, %2
7975    ; alt5: mov%d3\\t%0, %1\;mvn%D3\\t%0, #%B2
7976    ; alt6: mvn%d3\\t%0, #%B1\;mov%D3\\t%0, %2
7977    ; alt7: mvn%d3\\t%0, #%B1\;mvn%D3\\t%0, #%B2"
7978   "&& reload_completed"
7979   [(const_int 0)]
7980   {
7981     enum rtx_code rev_code;
7982     machine_mode mode;
7983     rtx rev_cond;
7985     emit_insn (gen_rtx_COND_EXEC (VOIDmode,
7986                                   operands[3],
7987                                   gen_rtx_SET (operands[0], operands[1])));
7989     rev_code = GET_CODE (operands[3]);
7990     mode = GET_MODE (operands[4]);
7991     if (mode == CCFPmode || mode == CCFPEmode)
7992       rev_code = reverse_condition_maybe_unordered (rev_code);
7993     else
7994       rev_code = reverse_condition (rev_code);
7996     rev_cond = gen_rtx_fmt_ee (rev_code,
7997                                VOIDmode,
7998                                operands[4],
7999                                const0_rtx);
8000     emit_insn (gen_rtx_COND_EXEC (VOIDmode,
8001                                   rev_cond,
8002                                   gen_rtx_SET (operands[0], operands[2])));
8003     DONE;
8004   }
8005   [(set_attr "length" "4,4,4,4,8,8,8,8")
8006    (set_attr "conds" "use")
8007    (set_attr_alternative "type"
8008                          [(if_then_else (match_operand 2 "const_int_operand" "")
8009                                         (const_string "mov_imm")
8010                                         (const_string "mov_reg"))
8011                           (const_string "mvn_imm")
8012                           (if_then_else (match_operand 1 "const_int_operand" "")
8013                                         (const_string "mov_imm")
8014                                         (const_string "mov_reg"))
8015                           (const_string "mvn_imm")
8016                           (const_string "multiple")
8017                           (const_string "multiple")
8018                           (const_string "multiple")
8019                           (const_string "multiple")])]
8022 (define_insn "*movsfcc_soft_insn"
8023   [(set (match_operand:SF 0 "s_register_operand" "=r,r")
8024         (if_then_else:SF (match_operator 3 "arm_comparison_operator"
8025                           [(match_operand 4 "cc_register" "") (const_int 0)])
8026                          (match_operand:SF 1 "s_register_operand" "0,r")
8027                          (match_operand:SF 2 "s_register_operand" "r,0")))]
8028   "TARGET_ARM && TARGET_SOFT_FLOAT"
8029   "@
8030    mov%D3\\t%0, %2
8031    mov%d3\\t%0, %1"
8032   [(set_attr "conds" "use")
8033    (set_attr "type" "mov_reg")]
8037 ;; Jump and linkage insns
8039 (define_expand "jump"
8040   [(set (pc)
8041         (label_ref (match_operand 0 "" "")))]
8042   "TARGET_EITHER"
8043   ""
8046 (define_insn "*arm_jump"
8047   [(set (pc)
8048         (label_ref (match_operand 0 "" "")))]
8049   "TARGET_32BIT"
8050   "*
8051   {
8052     if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
8053       {
8054         arm_ccfsm_state += 2;
8055         return \"\";
8056       }
8057     return \"b%?\\t%l0\";
8058   }
8059   "
8060   [(set_attr "predicable" "yes")
8061    (set (attr "length")
8062         (if_then_else
8063            (and (match_test "TARGET_THUMB2")
8064                 (and (ge (minus (match_dup 0) (pc)) (const_int -2044))
8065                      (le (minus (match_dup 0) (pc)) (const_int 2048))))
8066            (const_int 2)
8067            (const_int 4)))
8068    (set_attr "type" "branch")]
8071 (define_expand "call"
8072   [(parallel [(call (match_operand 0 "memory_operand" "")
8073                     (match_operand 1 "general_operand" ""))
8074               (use (match_operand 2 "" ""))
8075               (clobber (reg:SI LR_REGNUM))])]
8076   "TARGET_EITHER"
8077   "
8078   {
8079     rtx callee, pat;
8080     tree addr = MEM_EXPR (operands[0]);
8081     
8082     /* In an untyped call, we can get NULL for operand 2.  */
8083     if (operands[2] == NULL_RTX)
8084       operands[2] = const0_rtx;
8085       
8086     /* Decide if we should generate indirect calls by loading the
8087        32-bit address of the callee into a register before performing the
8088        branch and link.  */
8089     callee = XEXP (operands[0], 0);
8090     if (GET_CODE (callee) == SYMBOL_REF
8091         ? arm_is_long_call_p (SYMBOL_REF_DECL (callee))
8092         : !REG_P (callee))
8093       XEXP (operands[0], 0) = force_reg (Pmode, callee);
8095     if (detect_cmse_nonsecure_call (addr))
8096       {
8097         pat = gen_nonsecure_call_internal (operands[0], operands[1],
8098                                            operands[2]);
8099         emit_call_insn (pat);
8100       }
8101     else
8102       {
8103         pat = gen_call_internal (operands[0], operands[1], operands[2]);
8104         arm_emit_call_insn (pat, XEXP (operands[0], 0), false);
8105       }
8106     DONE;
8107   }"
8110 (define_expand "call_internal"
8111   [(parallel [(call (match_operand 0 "memory_operand" "")
8112                     (match_operand 1 "general_operand" ""))
8113               (use (match_operand 2 "" ""))
8114               (clobber (reg:SI LR_REGNUM))])])
8116 (define_expand "nonsecure_call_internal"
8117   [(parallel [(call (unspec:SI [(match_operand 0 "memory_operand" "")]
8118                                UNSPEC_NONSECURE_MEM)
8119                     (match_operand 1 "general_operand" ""))
8120               (use (match_operand 2 "" ""))
8121               (clobber (reg:SI LR_REGNUM))
8122               (clobber (reg:SI 4))])]
8123   "use_cmse"
8124   "
8125   {
8126     rtx tmp;
8127     tmp = copy_to_suggested_reg (XEXP (operands[0], 0),
8128                                  gen_rtx_REG (SImode, 4),
8129                                  SImode);
8131     operands[0] = replace_equiv_address (operands[0], tmp);
8132   }")
8134 (define_insn "*call_reg_armv5"
8135   [(call (mem:SI (match_operand:SI 0 "s_register_operand" "r"))
8136          (match_operand 1 "" ""))
8137    (use (match_operand 2 "" ""))
8138    (clobber (reg:SI LR_REGNUM))]
8139   "TARGET_ARM && arm_arch5 && !SIBLING_CALL_P (insn)"
8140   "blx%?\\t%0"
8141   [(set_attr "type" "call")]
8144 (define_insn "*call_reg_arm"
8145   [(call (mem:SI (match_operand:SI 0 "s_register_operand" "r"))
8146          (match_operand 1 "" ""))
8147    (use (match_operand 2 "" ""))
8148    (clobber (reg:SI LR_REGNUM))]
8149   "TARGET_ARM && !arm_arch5 && !SIBLING_CALL_P (insn)"
8150   "*
8151   return output_call (operands);
8152   "
8153   ;; length is worst case, normally it is only two
8154   [(set_attr "length" "12")
8155    (set_attr "type" "call")]
8159 (define_expand "call_value"
8160   [(parallel [(set (match_operand       0 "" "")
8161                    (call (match_operand 1 "memory_operand" "")
8162                          (match_operand 2 "general_operand" "")))
8163               (use (match_operand 3 "" ""))
8164               (clobber (reg:SI LR_REGNUM))])]
8165   "TARGET_EITHER"
8166   "
8167   {
8168     rtx pat, callee;
8169     tree addr = MEM_EXPR (operands[1]);
8170     
8171     /* In an untyped call, we can get NULL for operand 2.  */
8172     if (operands[3] == 0)
8173       operands[3] = const0_rtx;
8174       
8175     /* Decide if we should generate indirect calls by loading the
8176        32-bit address of the callee into a register before performing the
8177        branch and link.  */
8178     callee = XEXP (operands[1], 0);
8179     if (GET_CODE (callee) == SYMBOL_REF
8180         ? arm_is_long_call_p (SYMBOL_REF_DECL (callee))
8181         : !REG_P (callee))
8182       XEXP (operands[1], 0) = force_reg (Pmode, callee);
8184     if (detect_cmse_nonsecure_call (addr))
8185       {
8186         pat = gen_nonsecure_call_value_internal (operands[0], operands[1],
8187                                                  operands[2], operands[3]);
8188         emit_call_insn (pat);
8189       }
8190     else
8191       {
8192         pat = gen_call_value_internal (operands[0], operands[1],
8193                                        operands[2], operands[3]);
8194         arm_emit_call_insn (pat, XEXP (operands[1], 0), false);
8195       }
8196     DONE;
8197   }"
8200 (define_expand "call_value_internal"
8201   [(parallel [(set (match_operand       0 "" "")
8202                    (call (match_operand 1 "memory_operand" "")
8203                          (match_operand 2 "general_operand" "")))
8204               (use (match_operand 3 "" ""))
8205               (clobber (reg:SI LR_REGNUM))])])
8207 (define_expand "nonsecure_call_value_internal"
8208   [(parallel [(set (match_operand       0 "" "")
8209                    (call (unspec:SI [(match_operand 1 "memory_operand" "")]
8210                                     UNSPEC_NONSECURE_MEM)
8211                          (match_operand 2 "general_operand" "")))
8212               (use (match_operand 3 "" ""))
8213               (clobber (reg:SI LR_REGNUM))
8214               (clobber (reg:SI 4))])]
8215   "use_cmse"
8216   "
8217   {
8218     rtx tmp;
8219     tmp = copy_to_suggested_reg (XEXP (operands[1], 0),
8220                                  gen_rtx_REG (SImode, 4),
8221                                  SImode);
8223     operands[1] = replace_equiv_address (operands[1], tmp);
8224   }")
8226 (define_insn "*call_value_reg_armv5"
8227   [(set (match_operand 0 "" "")
8228         (call (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
8229               (match_operand 2 "" "")))
8230    (use (match_operand 3 "" ""))
8231    (clobber (reg:SI LR_REGNUM))]
8232   "TARGET_ARM && arm_arch5 && !SIBLING_CALL_P (insn)"
8233   "blx%?\\t%1"
8234   [(set_attr "type" "call")]
8237 (define_insn "*call_value_reg_arm"
8238   [(set (match_operand 0 "" "")
8239         (call (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
8240               (match_operand 2 "" "")))
8241    (use (match_operand 3 "" ""))
8242    (clobber (reg:SI LR_REGNUM))]
8243   "TARGET_ARM && !arm_arch5 && !SIBLING_CALL_P (insn)"
8244   "*
8245   return output_call (&operands[1]);
8246   "
8247   [(set_attr "length" "12")
8248    (set_attr "type" "call")]
8251 ;; Allow calls to SYMBOL_REFs specially as they are not valid general addresses
8252 ;; The 'a' causes the operand to be treated as an address, i.e. no '#' output.
8254 (define_insn "*call_symbol"
8255   [(call (mem:SI (match_operand:SI 0 "" ""))
8256          (match_operand 1 "" ""))
8257    (use (match_operand 2 "" ""))
8258    (clobber (reg:SI LR_REGNUM))]
8259   "TARGET_32BIT
8260    && !SIBLING_CALL_P (insn)
8261    && (GET_CODE (operands[0]) == SYMBOL_REF)
8262    && !arm_is_long_call_p (SYMBOL_REF_DECL (operands[0]))"
8263   "*
8264   {
8265    rtx op = operands[0];
8267    /* Switch mode now when possible.  */
8268    if (SYMBOL_REF_DECL (op) && !TREE_PUBLIC (SYMBOL_REF_DECL (op))
8269         && arm_arch5 && arm_change_mode_p (SYMBOL_REF_DECL (op)))
8270       return NEED_PLT_RELOC ? \"blx%?\\t%a0(PLT)\" : \"blx%?\\t(%a0)\";
8272     return NEED_PLT_RELOC ? \"bl%?\\t%a0(PLT)\" : \"bl%?\\t%a0\";
8273   }"
8274   [(set_attr "type" "call")]
8277 (define_insn "*call_value_symbol"
8278   [(set (match_operand 0 "" "")
8279         (call (mem:SI (match_operand:SI 1 "" ""))
8280         (match_operand:SI 2 "" "")))
8281    (use (match_operand 3 "" ""))
8282    (clobber (reg:SI LR_REGNUM))]
8283   "TARGET_32BIT
8284    && !SIBLING_CALL_P (insn)
8285    && (GET_CODE (operands[1]) == SYMBOL_REF)
8286    && !arm_is_long_call_p (SYMBOL_REF_DECL (operands[1]))"
8287   "*
8288   {
8289    rtx op = operands[1];
8291    /* Switch mode now when possible.  */
8292    if (SYMBOL_REF_DECL (op) && !TREE_PUBLIC (SYMBOL_REF_DECL (op))
8293         && arm_arch5 && arm_change_mode_p (SYMBOL_REF_DECL (op)))
8294       return NEED_PLT_RELOC ? \"blx%?\\t%a1(PLT)\" : \"blx%?\\t(%a1)\";
8296     return NEED_PLT_RELOC ? \"bl%?\\t%a1(PLT)\" : \"bl%?\\t%a1\";
8297   }"
8298   [(set_attr "type" "call")]
8301 (define_expand "sibcall_internal"
8302   [(parallel [(call (match_operand 0 "memory_operand" "")
8303                     (match_operand 1 "general_operand" ""))
8304               (return)
8305               (use (match_operand 2 "" ""))])])
8307 ;; We may also be able to do sibcalls for Thumb, but it's much harder...
8308 (define_expand "sibcall"
8309   [(parallel [(call (match_operand 0 "memory_operand" "")
8310                     (match_operand 1 "general_operand" ""))
8311               (return)
8312               (use (match_operand 2 "" ""))])]
8313   "TARGET_32BIT"
8314   "
8315   {
8316     rtx pat;
8318     if ((!REG_P (XEXP (operands[0], 0))
8319          && GET_CODE (XEXP (operands[0], 0)) != SYMBOL_REF)
8320         || (GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
8321             && arm_is_long_call_p (SYMBOL_REF_DECL (XEXP (operands[0], 0)))))
8322      XEXP (operands[0], 0) = force_reg (SImode, XEXP (operands[0], 0));
8324     if (operands[2] == NULL_RTX)
8325       operands[2] = const0_rtx;
8327     pat = gen_sibcall_internal (operands[0], operands[1], operands[2]);
8328     arm_emit_call_insn (pat, operands[0], true);
8329     DONE;
8330   }"
8333 (define_expand "sibcall_value_internal"
8334   [(parallel [(set (match_operand 0 "" "")
8335                    (call (match_operand 1 "memory_operand" "")
8336                          (match_operand 2 "general_operand" "")))
8337               (return)
8338               (use (match_operand 3 "" ""))])])
8340 (define_expand "sibcall_value"
8341   [(parallel [(set (match_operand 0 "" "")
8342                    (call (match_operand 1 "memory_operand" "")
8343                          (match_operand 2 "general_operand" "")))
8344               (return)
8345               (use (match_operand 3 "" ""))])]
8346   "TARGET_32BIT"
8347   "
8348   {
8349     rtx pat;
8351     if ((!REG_P (XEXP (operands[1], 0))
8352          && GET_CODE (XEXP (operands[1], 0)) != SYMBOL_REF)
8353         || (GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
8354             && arm_is_long_call_p (SYMBOL_REF_DECL (XEXP (operands[1], 0)))))
8355      XEXP (operands[1], 0) = force_reg (SImode, XEXP (operands[1], 0));
8357     if (operands[3] == NULL_RTX)
8358       operands[3] = const0_rtx;
8360     pat = gen_sibcall_value_internal (operands[0], operands[1],
8361                                       operands[2], operands[3]);
8362     arm_emit_call_insn (pat, operands[1], true);
8363     DONE;
8364   }"
8367 (define_insn "*sibcall_insn"
8368  [(call (mem:SI (match_operand:SI 0 "call_insn_operand" "Cs, US"))
8369         (match_operand 1 "" ""))
8370   (return)
8371   (use (match_operand 2 "" ""))]
8372   "TARGET_32BIT && SIBLING_CALL_P (insn)"
8373   "*
8374   if (which_alternative == 1)
8375     return NEED_PLT_RELOC ? \"b%?\\t%a0(PLT)\" : \"b%?\\t%a0\";
8376   else
8377     {
8378       if (arm_arch5 || arm_arch4t)
8379         return \"bx%?\\t%0\\t%@ indirect register sibling call\";
8380       else
8381         return \"mov%?\\t%|pc, %0\\t%@ indirect register sibling call\";
8382     }
8383   "
8384   [(set_attr "type" "call")]
8387 (define_insn "*sibcall_value_insn"
8388  [(set (match_operand 0 "" "")
8389        (call (mem:SI (match_operand:SI 1 "call_insn_operand" "Cs,US"))
8390              (match_operand 2 "" "")))
8391   (return)
8392   (use (match_operand 3 "" ""))]
8393   "TARGET_32BIT && SIBLING_CALL_P (insn)"
8394   "*
8395   if (which_alternative == 1)
8396    return NEED_PLT_RELOC ? \"b%?\\t%a1(PLT)\" : \"b%?\\t%a1\";
8397   else
8398     {
8399       if (arm_arch5 || arm_arch4t)
8400         return \"bx%?\\t%1\";
8401       else
8402         return \"mov%?\\t%|pc, %1\\t@ indirect sibling call \";
8403     }
8404   "
8405   [(set_attr "type" "call")]
8408 (define_expand "<return_str>return"
8409   [(RETURNS)]
8410   "(TARGET_ARM || (TARGET_THUMB2
8411                    && ARM_FUNC_TYPE (arm_current_func_type ()) == ARM_FT_NORMAL
8412                    && !IS_STACKALIGN (arm_current_func_type ())))
8413     <return_cond_false>"
8414   "
8415   {
8416     if (TARGET_THUMB2)
8417       {
8418         thumb2_expand_return (<return_simple_p>);
8419         DONE;
8420       }
8421   }
8422   "
8425 ;; Often the return insn will be the same as loading from memory, so set attr
8426 (define_insn "*arm_return"
8427   [(return)]
8428   "TARGET_ARM && USE_RETURN_INSN (FALSE)"
8429   "*
8430   {
8431     if (arm_ccfsm_state == 2)
8432       {
8433         arm_ccfsm_state += 2;
8434         return \"\";
8435       }
8436     return output_return_instruction (const_true_rtx, true, false, false);
8437   }"
8438   [(set_attr "type" "load_4")
8439    (set_attr "length" "12")
8440    (set_attr "predicable" "yes")]
8443 (define_insn "*cond_<return_str>return"
8444   [(set (pc)
8445         (if_then_else (match_operator 0 "arm_comparison_operator"
8446                        [(match_operand 1 "cc_register" "") (const_int 0)])
8447                       (RETURNS)
8448                       (pc)))]
8449   "TARGET_ARM  <return_cond_true>"
8450   "*
8451   {
8452     if (arm_ccfsm_state == 2)
8453       {
8454         arm_ccfsm_state += 2;
8455         return \"\";
8456       }
8457     return output_return_instruction (operands[0], true, false,
8458                                       <return_simple_p>);
8459   }"
8460   [(set_attr "conds" "use")
8461    (set_attr "length" "12")
8462    (set_attr "type" "load_4")]
8465 (define_insn "*cond_<return_str>return_inverted"
8466   [(set (pc)
8467         (if_then_else (match_operator 0 "arm_comparison_operator"
8468                        [(match_operand 1 "cc_register" "") (const_int 0)])
8469                       (pc)
8470                       (RETURNS)))]
8471   "TARGET_ARM <return_cond_true>"
8472   "*
8473   {
8474     if (arm_ccfsm_state == 2)
8475       {
8476         arm_ccfsm_state += 2;
8477         return \"\";
8478       }
8479     return output_return_instruction (operands[0], true, true,
8480                                       <return_simple_p>);
8481   }"
8482   [(set_attr "conds" "use")
8483    (set_attr "length" "12")
8484    (set_attr "type" "load_4")]
8487 (define_insn "*arm_simple_return"
8488   [(simple_return)]
8489   "TARGET_ARM"
8490   "*
8491   {
8492     if (arm_ccfsm_state == 2)
8493       {
8494         arm_ccfsm_state += 2;
8495         return \"\";
8496       }
8497     return output_return_instruction (const_true_rtx, true, false, true);
8498   }"
8499   [(set_attr "type" "branch")
8500    (set_attr "length" "4")
8501    (set_attr "predicable" "yes")]
8504 ;; Generate a sequence of instructions to determine if the processor is
8505 ;; in 26-bit or 32-bit mode, and return the appropriate return address
8506 ;; mask.
8508 (define_expand "return_addr_mask"
8509   [(set (match_dup 1)
8510       (compare:CC_NOOV (unspec [(const_int 0)] UNSPEC_CHECK_ARCH)
8511                        (const_int 0)))
8512    (set (match_operand:SI 0 "s_register_operand" "")
8513       (if_then_else:SI (eq (match_dup 1) (const_int 0))
8514                        (const_int -1)
8515                        (const_int 67108860)))] ; 0x03fffffc
8516   "TARGET_ARM"
8517   "
8518   operands[1] = gen_rtx_REG (CC_NOOVmode, CC_REGNUM);
8519   ")
8521 (define_insn "*check_arch2"
8522   [(set (match_operand:CC_NOOV 0 "cc_register" "")
8523       (compare:CC_NOOV (unspec [(const_int 0)] UNSPEC_CHECK_ARCH)
8524                        (const_int 0)))]
8525   "TARGET_ARM"
8526   "teq\\t%|r0, %|r0\;teq\\t%|pc, %|pc"
8527   [(set_attr "length" "8")
8528    (set_attr "conds" "set")
8529    (set_attr "type" "multiple")]
8532 ;; Call subroutine returning any type.
8534 (define_expand "untyped_call"
8535   [(parallel [(call (match_operand 0 "" "")
8536                     (const_int 0))
8537               (match_operand 1 "" "")
8538               (match_operand 2 "" "")])]
8539   "TARGET_EITHER"
8540   "
8541   {
8542     int i;
8543     rtx par = gen_rtx_PARALLEL (VOIDmode,
8544                                 rtvec_alloc (XVECLEN (operands[2], 0)));
8545     rtx addr = gen_reg_rtx (Pmode);
8546     rtx mem;
8547     int size = 0;
8549     emit_move_insn (addr, XEXP (operands[1], 0));
8550     mem = change_address (operands[1], BLKmode, addr);
8552     for (i = 0; i < XVECLEN (operands[2], 0); i++)
8553       {
8554         rtx src = SET_SRC (XVECEXP (operands[2], 0, i));
8556         /* Default code only uses r0 as a return value, but we could
8557            be using anything up to 4 registers.  */
8558         if (REGNO (src) == R0_REGNUM)
8559           src = gen_rtx_REG (TImode, R0_REGNUM);
8561         XVECEXP (par, 0, i) = gen_rtx_EXPR_LIST (VOIDmode, src,
8562                                                  GEN_INT (size));
8563         size += GET_MODE_SIZE (GET_MODE (src));
8564       }
8566     emit_call_insn (gen_call_value (par, operands[0], const0_rtx, NULL));
8568     size = 0;
8570     for (i = 0; i < XVECLEN (par, 0); i++)
8571       {
8572         HOST_WIDE_INT offset = 0;
8573         rtx reg = XEXP (XVECEXP (par, 0, i), 0);
8575         if (size != 0)
8576           emit_move_insn (addr, plus_constant (Pmode, addr, size));
8578         mem = change_address (mem, GET_MODE (reg), NULL);
8579         if (REGNO (reg) == R0_REGNUM)
8580           {
8581             /* On thumb we have to use a write-back instruction.  */
8582             emit_insn (arm_gen_store_multiple (arm_regs_in_sequence, 4, addr,
8583                        TARGET_THUMB ? TRUE : FALSE, mem, &offset));
8584             size = TARGET_ARM ? 16 : 0;
8585           }
8586         else
8587           {
8588             emit_move_insn (mem, reg);
8589             size = GET_MODE_SIZE (GET_MODE (reg));
8590           }
8591       }
8593     /* The optimizer does not know that the call sets the function value
8594        registers we stored in the result block.  We avoid problems by
8595        claiming that all hard registers are used and clobbered at this
8596        point.  */
8597     emit_insn (gen_blockage ());
8599     DONE;
8600   }"
8603 (define_expand "untyped_return"
8604   [(match_operand:BLK 0 "memory_operand" "")
8605    (match_operand 1 "" "")]
8606   "TARGET_EITHER"
8607   "
8608   {
8609     int i;
8610     rtx addr = gen_reg_rtx (Pmode);
8611     rtx mem;
8612     int size = 0;
8614     emit_move_insn (addr, XEXP (operands[0], 0));
8615     mem = change_address (operands[0], BLKmode, addr);
8617     for (i = 0; i < XVECLEN (operands[1], 0); i++)
8618       {
8619         HOST_WIDE_INT offset = 0;
8620         rtx reg = SET_DEST (XVECEXP (operands[1], 0, i));
8622         if (size != 0)
8623           emit_move_insn (addr, plus_constant (Pmode, addr, size));
8625         mem = change_address (mem, GET_MODE (reg), NULL);
8626         if (REGNO (reg) == R0_REGNUM)
8627           {
8628             /* On thumb we have to use a write-back instruction.  */
8629             emit_insn (arm_gen_load_multiple (arm_regs_in_sequence, 4, addr,
8630                        TARGET_THUMB ? TRUE : FALSE, mem, &offset));
8631             size = TARGET_ARM ? 16 : 0;
8632           }
8633         else
8634           {
8635             emit_move_insn (reg, mem);
8636             size = GET_MODE_SIZE (GET_MODE (reg));
8637           }
8638       }
8640     /* Emit USE insns before the return.  */
8641     for (i = 0; i < XVECLEN (operands[1], 0); i++)
8642       emit_use (SET_DEST (XVECEXP (operands[1], 0, i)));
8644     /* Construct the return.  */
8645     expand_naked_return ();
8647     DONE;
8648   }"
8651 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
8652 ;; all of memory.  This blocks insns from being moved across this point.
8654 (define_insn "blockage"
8655   [(unspec_volatile [(const_int 0)] VUNSPEC_BLOCKAGE)]
8656   "TARGET_EITHER"
8657   ""
8658   [(set_attr "length" "0")
8659    (set_attr "type" "block")]
8662 (define_insn "probe_stack"
8663   [(set (match_operand:SI 0 "memory_operand" "=m")
8664         (unspec:SI [(const_int 0)] UNSPEC_PROBE_STACK))]
8665   "TARGET_32BIT"
8666   "str%?\\tr0, %0"
8667   [(set_attr "type" "store_4")
8668    (set_attr "predicable" "yes")]
8671 (define_insn "probe_stack_range"
8672   [(set (match_operand:SI 0 "register_operand" "=r")
8673         (unspec_volatile:SI [(match_operand:SI 1 "register_operand" "0")
8674                              (match_operand:SI 2 "register_operand" "r")]
8675                              VUNSPEC_PROBE_STACK_RANGE))]
8676   "TARGET_32BIT"
8678   return output_probe_stack_range (operands[0], operands[2]);
8680   [(set_attr "type" "multiple")
8681    (set_attr "conds" "clob")]
8684 (define_expand "casesi"
8685   [(match_operand:SI 0 "s_register_operand" "") ; index to jump on
8686    (match_operand:SI 1 "const_int_operand" "")  ; lower bound
8687    (match_operand:SI 2 "const_int_operand" "")  ; total range
8688    (match_operand:SI 3 "" "")                   ; table label
8689    (match_operand:SI 4 "" "")]                  ; Out of range label
8690   "(TARGET_32BIT || optimize_size || flag_pic) && !target_pure_code"
8691   "
8692   {
8693     enum insn_code code;
8694     if (operands[1] != const0_rtx)
8695       {
8696         rtx reg = gen_reg_rtx (SImode);
8698         emit_insn (gen_addsi3 (reg, operands[0],
8699                                gen_int_mode (-INTVAL (operands[1]),
8700                                              SImode)));
8701         operands[0] = reg;
8702       }
8704     if (TARGET_ARM)
8705       code = CODE_FOR_arm_casesi_internal;
8706     else if (TARGET_THUMB1)
8707       code = CODE_FOR_thumb1_casesi_internal_pic;
8708     else if (flag_pic)
8709       code = CODE_FOR_thumb2_casesi_internal_pic;
8710     else
8711       code = CODE_FOR_thumb2_casesi_internal;
8713     if (!insn_data[(int) code].operand[1].predicate(operands[2], SImode))
8714       operands[2] = force_reg (SImode, operands[2]);
8716     emit_jump_insn (GEN_FCN ((int) code) (operands[0], operands[2],
8717                                           operands[3], operands[4]));
8718     DONE;
8719   }"
8722 ;; The USE in this pattern is needed to tell flow analysis that this is
8723 ;; a CASESI insn.  It has no other purpose.
8724 (define_insn "arm_casesi_internal"
8725   [(parallel [(set (pc)
8726                (if_then_else
8727                 (leu (match_operand:SI 0 "s_register_operand" "r")
8728                      (match_operand:SI 1 "arm_rhs_operand" "rI"))
8729                 (mem:SI (plus:SI (mult:SI (match_dup 0) (const_int 4))
8730                                  (label_ref (match_operand 2 "" ""))))
8731                 (label_ref (match_operand 3 "" ""))))
8732               (clobber (reg:CC CC_REGNUM))
8733               (use (label_ref (match_dup 2)))])]
8734   "TARGET_ARM"
8735   "*
8736     if (flag_pic)
8737       return \"cmp\\t%0, %1\;addls\\t%|pc, %|pc, %0, asl #2\;b\\t%l3\";
8738     return   \"cmp\\t%0, %1\;ldrls\\t%|pc, [%|pc, %0, asl #2]\;b\\t%l3\";
8739   "
8740   [(set_attr "conds" "clob")
8741    (set_attr "length" "12")
8742    (set_attr "type" "multiple")]
8745 (define_expand "indirect_jump"
8746   [(set (pc)
8747         (match_operand:SI 0 "s_register_operand" ""))]
8748   "TARGET_EITHER"
8749   "
8750   /* Thumb-2 doesn't have mov pc, reg.  Explicitly set the low bit of the
8751      address and use bx.  */
8752   if (TARGET_THUMB2)
8753     {
8754       rtx tmp;
8755       tmp = gen_reg_rtx (SImode);
8756       emit_insn (gen_iorsi3 (tmp, operands[0], GEN_INT(1)));
8757       operands[0] = tmp;
8758     }
8759   "
8762 ;; NB Never uses BX.
8763 (define_insn "*arm_indirect_jump"
8764   [(set (pc)
8765         (match_operand:SI 0 "s_register_operand" "r"))]
8766   "TARGET_ARM"
8767   "mov%?\\t%|pc, %0\\t%@ indirect register jump"
8768   [(set_attr "predicable" "yes")
8769    (set_attr "type" "branch")]
8772 (define_insn "*load_indirect_jump"
8773   [(set (pc)
8774         (match_operand:SI 0 "memory_operand" "m"))]
8775   "TARGET_ARM"
8776   "ldr%?\\t%|pc, %0\\t%@ indirect memory jump"
8777   [(set_attr "type" "load_4")
8778    (set_attr "pool_range" "4096")
8779    (set_attr "neg_pool_range" "4084")
8780    (set_attr "predicable" "yes")]
8784 ;; Misc insns
8786 (define_insn "nop"
8787   [(const_int 0)]
8788   "TARGET_EITHER"
8789   "nop"
8790   [(set (attr "length")
8791         (if_then_else (eq_attr "is_thumb" "yes")
8792                       (const_int 2)
8793                       (const_int 4)))
8794    (set_attr "type" "mov_reg")]
8797 (define_insn "trap"
8798   [(trap_if (const_int 1) (const_int 0))]
8799   ""
8800   "*
8801   if (TARGET_ARM)
8802     return \".inst\\t0xe7f000f0\";
8803   else
8804     return \".inst\\t0xdeff\";
8805   "
8806   [(set (attr "length")
8807         (if_then_else (eq_attr "is_thumb" "yes")
8808                       (const_int 2)
8809                       (const_int 4)))
8810    (set_attr "type" "trap")
8811    (set_attr "conds" "unconditional")]
8815 ;; Patterns to allow combination of arithmetic, cond code and shifts
8817 (define_insn "*<arith_shift_insn>_multsi"
8818   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8819         (SHIFTABLE_OPS:SI
8820          (mult:SI (match_operand:SI 2 "s_register_operand" "r,r")
8821                   (match_operand:SI 3 "power_of_two_operand" ""))
8822          (match_operand:SI 1 "s_register_operand" "rk,<t2_binop0>")))]
8823   "TARGET_32BIT"
8824   "<arith_shift_insn>%?\\t%0, %1, %2, lsl %b3"
8825   [(set_attr "predicable" "yes")
8826    (set_attr "predicable_short_it" "no")
8827    (set_attr "shift" "2")
8828    (set_attr "arch" "a,t2")
8829    (set_attr "type" "alu_shift_imm")])
8831 (define_insn "*<arith_shift_insn>_shiftsi"
8832   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
8833         (SHIFTABLE_OPS:SI
8834          (match_operator:SI 2 "shift_nomul_operator"
8835           [(match_operand:SI 3 "s_register_operand" "r,r,r")
8836            (match_operand:SI 4 "shift_amount_operand" "M,M,r")])
8837          (match_operand:SI 1 "s_register_operand" "rk,<t2_binop0>,rk")))]
8838   "TARGET_32BIT && GET_CODE (operands[2]) != MULT"
8839   "<arith_shift_insn>%?\\t%0, %1, %3%S2"
8840   [(set_attr "predicable" "yes")
8841    (set_attr "predicable_short_it" "no")
8842    (set_attr "shift" "3")
8843    (set_attr "arch" "a,t2,a")
8844    (set_attr "type" "alu_shift_imm,alu_shift_imm,alu_shift_reg")])
8846 (define_split
8847   [(set (match_operand:SI 0 "s_register_operand" "")
8848         (match_operator:SI 1 "shiftable_operator"
8849          [(match_operator:SI 2 "shiftable_operator"
8850            [(match_operator:SI 3 "shift_operator"
8851              [(match_operand:SI 4 "s_register_operand" "")
8852               (match_operand:SI 5 "reg_or_int_operand" "")])
8853             (match_operand:SI 6 "s_register_operand" "")])
8854           (match_operand:SI 7 "arm_rhs_operand" "")]))
8855    (clobber (match_operand:SI 8 "s_register_operand" ""))]
8856   "TARGET_32BIT"
8857   [(set (match_dup 8)
8858         (match_op_dup 2 [(match_op_dup 3 [(match_dup 4) (match_dup 5)])
8859                          (match_dup 6)]))
8860    (set (match_dup 0)
8861         (match_op_dup 1 [(match_dup 8) (match_dup 7)]))]
8862   "")
8864 (define_insn "*arith_shiftsi_compare0"
8865   [(set (reg:CC_NOOV CC_REGNUM)
8866         (compare:CC_NOOV
8867          (match_operator:SI 1 "shiftable_operator"
8868           [(match_operator:SI 3 "shift_operator"
8869             [(match_operand:SI 4 "s_register_operand" "r,r")
8870              (match_operand:SI 5 "shift_amount_operand" "M,r")])
8871            (match_operand:SI 2 "s_register_operand" "r,r")])
8872          (const_int 0)))
8873    (set (match_operand:SI 0 "s_register_operand" "=r,r")
8874         (match_op_dup 1 [(match_op_dup 3 [(match_dup 4) (match_dup 5)])
8875                          (match_dup 2)]))]
8876   "TARGET_32BIT"
8877   "%i1s%?\\t%0, %2, %4%S3"
8878   [(set_attr "conds" "set")
8879    (set_attr "shift" "4")
8880    (set_attr "arch" "32,a")
8881    (set_attr "type" "alus_shift_imm,alus_shift_reg")])
8883 (define_insn "*arith_shiftsi_compare0_scratch"
8884   [(set (reg:CC_NOOV CC_REGNUM)
8885         (compare:CC_NOOV
8886          (match_operator:SI 1 "shiftable_operator"
8887           [(match_operator:SI 3 "shift_operator"
8888             [(match_operand:SI 4 "s_register_operand" "r,r")
8889              (match_operand:SI 5 "shift_amount_operand" "M,r")])
8890            (match_operand:SI 2 "s_register_operand" "r,r")])
8891          (const_int 0)))
8892    (clobber (match_scratch:SI 0 "=r,r"))]
8893   "TARGET_32BIT"
8894   "%i1s%?\\t%0, %2, %4%S3"
8895   [(set_attr "conds" "set")
8896    (set_attr "shift" "4")
8897    (set_attr "arch" "32,a")
8898    (set_attr "type" "alus_shift_imm,alus_shift_reg")])
8900 (define_insn "*sub_shiftsi"
8901   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8902         (minus:SI (match_operand:SI 1 "s_register_operand" "r,r")
8903                   (match_operator:SI 2 "shift_operator"
8904                    [(match_operand:SI 3 "s_register_operand" "r,r")
8905                     (match_operand:SI 4 "shift_amount_operand" "M,r")])))]
8906   "TARGET_32BIT"
8907   "sub%?\\t%0, %1, %3%S2"
8908   [(set_attr "predicable" "yes")
8909    (set_attr "predicable_short_it" "no")
8910    (set_attr "shift" "3")
8911    (set_attr "arch" "32,a")
8912    (set_attr "type" "alus_shift_imm,alus_shift_reg")])
8914 (define_insn "*sub_shiftsi_compare0"
8915   [(set (reg:CC_NOOV CC_REGNUM)
8916         (compare:CC_NOOV
8917          (minus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
8918                    (match_operator:SI 2 "shift_operator"
8919                     [(match_operand:SI 3 "s_register_operand" "r,r,r")
8920                      (match_operand:SI 4 "shift_amount_operand" "M,r,M")]))
8921          (const_int 0)))
8922    (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
8923         (minus:SI (match_dup 1)
8924                   (match_op_dup 2 [(match_dup 3) (match_dup 4)])))]
8925   "TARGET_32BIT"
8926   "subs%?\\t%0, %1, %3%S2"
8927   [(set_attr "conds" "set")
8928    (set_attr "shift" "3")
8929    (set_attr "arch" "32,a,a")
8930    (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
8932 (define_insn "*sub_shiftsi_compare0_scratch"
8933   [(set (reg:CC_NOOV CC_REGNUM)
8934         (compare:CC_NOOV
8935          (minus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
8936                    (match_operator:SI 2 "shift_operator"
8937                     [(match_operand:SI 3 "s_register_operand" "r,r,r")
8938                      (match_operand:SI 4 "shift_amount_operand" "M,r,M")]))
8939          (const_int 0)))
8940    (clobber (match_scratch:SI 0 "=r,r,r"))]
8941   "TARGET_32BIT"
8942   "subs%?\\t%0, %1, %3%S2"
8943   [(set_attr "conds" "set")
8944    (set_attr "shift" "3")
8945    (set_attr "arch" "32,a,a")
8946    (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
8949 (define_insn_and_split "*and_scc"
8950   [(set (match_operand:SI 0 "s_register_operand" "=r")
8951         (and:SI (match_operator:SI 1 "arm_comparison_operator"
8952                  [(match_operand 2 "cc_register" "") (const_int 0)])
8953                 (match_operand:SI 3 "s_register_operand" "r")))]
8954   "TARGET_ARM"
8955   "#"   ; "mov%D1\\t%0, #0\;and%d1\\t%0, %3, #1"
8956   "&& reload_completed"
8957   [(cond_exec (match_dup 5) (set (match_dup 0) (const_int 0)))
8958    (cond_exec (match_dup 4) (set (match_dup 0)
8959                                  (and:SI (match_dup 3) (const_int 1))))]
8960   {
8961     machine_mode mode = GET_MODE (operands[2]);
8962     enum rtx_code rc = GET_CODE (operands[1]);
8964     /* Note that operands[4] is the same as operands[1],
8965        but with VOIDmode as the result. */
8966     operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
8967     if (mode == CCFPmode || mode == CCFPEmode)
8968       rc = reverse_condition_maybe_unordered (rc);
8969     else
8970       rc = reverse_condition (rc);
8971     operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
8972   }
8973   [(set_attr "conds" "use")
8974    (set_attr "type" "multiple")
8975    (set_attr "length" "8")]
8978 (define_insn_and_split "*ior_scc"
8979   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8980         (ior:SI (match_operator:SI 1 "arm_comparison_operator"
8981                  [(match_operand 2 "cc_register" "") (const_int 0)])
8982                 (match_operand:SI 3 "s_register_operand" "0,?r")))]
8983   "TARGET_ARM"
8984   "@
8985    orr%d1\\t%0, %3, #1
8986    #"
8987   "&& reload_completed
8988    && REGNO (operands [0]) != REGNO (operands[3])"
8989   ;; && which_alternative == 1
8990   ; mov%D1\\t%0, %3\;orr%d1\\t%0, %3, #1
8991   [(cond_exec (match_dup 5) (set (match_dup 0) (match_dup 3)))
8992    (cond_exec (match_dup 4) (set (match_dup 0)
8993                                  (ior:SI (match_dup 3) (const_int 1))))]
8994   {
8995     machine_mode mode = GET_MODE (operands[2]);
8996     enum rtx_code rc = GET_CODE (operands[1]);
8998     /* Note that operands[4] is the same as operands[1],
8999        but with VOIDmode as the result. */
9000     operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
9001     if (mode == CCFPmode || mode == CCFPEmode)
9002       rc = reverse_condition_maybe_unordered (rc);
9003     else
9004       rc = reverse_condition (rc);
9005     operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
9006   }
9007   [(set_attr "conds" "use")
9008    (set_attr "length" "4,8")
9009    (set_attr "type" "logic_imm,multiple")]
9012 ; A series of splitters for the compare_scc pattern below.  Note that
9013 ; order is important.
9014 (define_split
9015   [(set (match_operand:SI 0 "s_register_operand" "")
9016         (lt:SI (match_operand:SI 1 "s_register_operand" "")
9017                (const_int 0)))
9018    (clobber (reg:CC CC_REGNUM))]
9019   "TARGET_32BIT && reload_completed"
9020   [(set (match_dup 0) (lshiftrt:SI (match_dup 1) (const_int 31)))])
9022 (define_split
9023   [(set (match_operand:SI 0 "s_register_operand" "")
9024         (ge:SI (match_operand:SI 1 "s_register_operand" "")
9025                (const_int 0)))
9026    (clobber (reg:CC CC_REGNUM))]
9027   "TARGET_32BIT && reload_completed"
9028   [(set (match_dup 0) (not:SI (match_dup 1)))
9029    (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 31)))])
9031 (define_split
9032   [(set (match_operand:SI 0 "s_register_operand" "")
9033         (eq:SI (match_operand:SI 1 "s_register_operand" "")
9034                (const_int 0)))
9035    (clobber (reg:CC CC_REGNUM))]
9036   "arm_arch5 && TARGET_32BIT"
9037   [(set (match_dup 0) (clz:SI (match_dup 1)))
9038    (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
9041 (define_split
9042   [(set (match_operand:SI 0 "s_register_operand" "")
9043         (eq:SI (match_operand:SI 1 "s_register_operand" "")
9044                (const_int 0)))
9045    (clobber (reg:CC CC_REGNUM))]
9046   "TARGET_32BIT && reload_completed"
9047   [(parallel
9048     [(set (reg:CC CC_REGNUM)
9049           (compare:CC (const_int 1) (match_dup 1)))
9050      (set (match_dup 0)
9051           (minus:SI (const_int 1) (match_dup 1)))])
9052    (cond_exec (ltu:CC (reg:CC CC_REGNUM) (const_int 0))
9053               (set (match_dup 0) (const_int 0)))])
9055 (define_split
9056   [(set (match_operand:SI 0 "s_register_operand" "")
9057         (ne:SI (match_operand:SI 1 "s_register_operand" "")
9058                (match_operand:SI 2 "const_int_operand" "")))
9059    (clobber (reg:CC CC_REGNUM))]
9060   "TARGET_32BIT && reload_completed"
9061   [(parallel
9062     [(set (reg:CC CC_REGNUM)
9063           (compare:CC (match_dup 1) (match_dup 2)))
9064      (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 3)))])
9065    (cond_exec (ne:CC (reg:CC CC_REGNUM) (const_int 0))
9066               (set (match_dup 0) (const_int 1)))]
9068   operands[3] = GEN_INT (-INTVAL (operands[2]));
9071 (define_split
9072   [(set (match_operand:SI 0 "s_register_operand" "")
9073         (ne:SI (match_operand:SI 1 "s_register_operand" "")
9074                (match_operand:SI 2 "arm_add_operand" "")))
9075    (clobber (reg:CC CC_REGNUM))]
9076   "TARGET_32BIT && reload_completed"
9077   [(parallel
9078     [(set (reg:CC_NOOV CC_REGNUM)
9079           (compare:CC_NOOV (minus:SI (match_dup 1) (match_dup 2))
9080                            (const_int 0)))
9081      (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
9082    (cond_exec (ne:CC_NOOV (reg:CC_NOOV CC_REGNUM) (const_int 0))
9083               (set (match_dup 0) (const_int 1)))])
9085 (define_insn_and_split "*compare_scc"
9086   [(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts")
9087         (match_operator:SI 1 "arm_comparison_operator"
9088          [(match_operand:SI 2 "s_register_operand" "r,r")
9089           (match_operand:SI 3 "arm_add_operand" "rI,L")]))
9090    (clobber (reg:CC CC_REGNUM))]
9091   "TARGET_32BIT"
9092   "#"
9093   "&& reload_completed"
9094   [(set (reg:CC CC_REGNUM) (compare:CC (match_dup 2) (match_dup 3)))
9095    (cond_exec (match_dup 4) (set (match_dup 0) (const_int 0)))
9096    (cond_exec (match_dup 5) (set (match_dup 0) (const_int 1)))]
9098   rtx tmp1;
9099   machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
9100                                            operands[2], operands[3]);
9101   enum rtx_code rc = GET_CODE (operands[1]);
9103   tmp1 = gen_rtx_REG (mode, CC_REGNUM);
9105   operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, tmp1, const0_rtx);
9106   if (mode == CCFPmode || mode == CCFPEmode)
9107     rc = reverse_condition_maybe_unordered (rc);
9108   else
9109     rc = reverse_condition (rc);
9110   operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, tmp1, const0_rtx);
9112   [(set_attr "type" "multiple")]
9115 ;; Attempt to improve the sequence generated by the compare_scc splitters
9116 ;; not to use conditional execution.
9118 ;; Rd = (eq (reg1) (const_int0))  // ARMv5
9119 ;;      clz Rd, reg1
9120 ;;      lsr Rd, Rd, #5
9121 (define_peephole2
9122   [(set (reg:CC CC_REGNUM)
9123         (compare:CC (match_operand:SI 1 "register_operand" "")
9124                     (const_int 0)))
9125    (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
9126               (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
9127    (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
9128               (set (match_dup 0) (const_int 1)))]
9129   "arm_arch5 && TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
9130   [(set (match_dup 0) (clz:SI (match_dup 1)))
9131    (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
9134 ;; Rd = (eq (reg1) (const_int0))  // !ARMv5
9135 ;;      negs Rd, reg1
9136 ;;      adc  Rd, Rd, reg1
9137 (define_peephole2
9138   [(set (reg:CC CC_REGNUM)
9139         (compare:CC (match_operand:SI 1 "register_operand" "")
9140                     (const_int 0)))
9141    (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
9142               (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
9143    (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
9144               (set (match_dup 0) (const_int 1)))
9145    (match_scratch:SI 2 "r")]
9146   "TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
9147   [(parallel
9148     [(set (reg:CC CC_REGNUM)
9149           (compare:CC (const_int 0) (match_dup 1)))
9150      (set (match_dup 2) (minus:SI (const_int 0) (match_dup 1)))])
9151    (set (match_dup 0)
9152         (plus:SI (plus:SI (match_dup 1) (match_dup 2))
9153                  (geu:SI (reg:CC CC_REGNUM) (const_int 0))))]
9156 ;; Rd = (eq (reg1) (reg2/imm))  // ARMv5 and optimising for speed.
9157 ;;      sub  Rd, Reg1, reg2
9158 ;;      clz  Rd, Rd
9159 ;;      lsr  Rd, Rd, #5
9160 (define_peephole2
9161   [(set (reg:CC CC_REGNUM)
9162         (compare:CC (match_operand:SI 1 "register_operand" "")
9163                     (match_operand:SI 2 "arm_rhs_operand" "")))
9164    (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
9165               (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
9166    (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
9167               (set (match_dup 0) (const_int 1)))]
9168   "arm_arch5 && TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)
9169   && !(TARGET_THUMB2 && optimize_insn_for_size_p ())"
9170   [(set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))
9171    (set (match_dup 0) (clz:SI (match_dup 0)))
9172    (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
9176 ;; Rd = (eq (reg1) (reg2))      // ! ARMv5 or optimising for size.
9177 ;;      sub  T1, Reg1, reg2
9178 ;;      negs Rd, T1
9179 ;;      adc  Rd, Rd, T1
9180 (define_peephole2
9181   [(set (reg:CC CC_REGNUM)
9182         (compare:CC (match_operand:SI 1 "register_operand" "")
9183                     (match_operand:SI 2 "arm_rhs_operand" "")))
9184    (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
9185               (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
9186    (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
9187               (set (match_dup 0) (const_int 1)))
9188    (match_scratch:SI 3 "r")]
9189   "TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
9190   [(set (match_dup 3) (match_dup 4))
9191    (parallel
9192     [(set (reg:CC CC_REGNUM)
9193           (compare:CC (const_int 0) (match_dup 3)))
9194      (set (match_dup 0) (minus:SI (const_int 0) (match_dup 3)))])
9195    (set (match_dup 0)
9196         (plus:SI (plus:SI (match_dup 0) (match_dup 3))
9197                  (geu:SI (reg:CC CC_REGNUM) (const_int 0))))]
9198   "
9199   if (CONST_INT_P (operands[2]))
9200     operands[4] = plus_constant (SImode, operands[1], -INTVAL (operands[2]));
9201   else
9202     operands[4] = gen_rtx_MINUS (SImode, operands[1], operands[2]);
9203   ")
9205 (define_insn "*cond_move"
9206   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9207         (if_then_else:SI (match_operator 3 "equality_operator"
9208                           [(match_operator 4 "arm_comparison_operator"
9209                             [(match_operand 5 "cc_register" "") (const_int 0)])
9210                            (const_int 0)])
9211                          (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
9212                          (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))]
9213   "TARGET_ARM"
9214   "*
9215     if (GET_CODE (operands[3]) == NE)
9216       {
9217         if (which_alternative != 1)
9218           output_asm_insn (\"mov%D4\\t%0, %2\", operands);
9219         if (which_alternative != 0)
9220           output_asm_insn (\"mov%d4\\t%0, %1\", operands);
9221         return \"\";
9222       }
9223     if (which_alternative != 0)
9224       output_asm_insn (\"mov%D4\\t%0, %1\", operands);
9225     if (which_alternative != 1)
9226       output_asm_insn (\"mov%d4\\t%0, %2\", operands);
9227     return \"\";
9228   "
9229   [(set_attr "conds" "use")
9230    (set_attr_alternative "type"
9231                          [(if_then_else (match_operand 2 "const_int_operand" "")
9232                                         (const_string "mov_imm")
9233                                         (const_string "mov_reg"))
9234                           (if_then_else (match_operand 1 "const_int_operand" "")
9235                                         (const_string "mov_imm")
9236                                         (const_string "mov_reg"))
9237                           (const_string "multiple")])
9238    (set_attr "length" "4,4,8")]
9241 (define_insn "*cond_arith"
9242   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9243         (match_operator:SI 5 "shiftable_operator" 
9244          [(match_operator:SI 4 "arm_comparison_operator"
9245            [(match_operand:SI 2 "s_register_operand" "r,r")
9246             (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
9247           (match_operand:SI 1 "s_register_operand" "0,?r")]))
9248    (clobber (reg:CC CC_REGNUM))]
9249   "TARGET_ARM"
9250   "*
9251     if (GET_CODE (operands[4]) == LT && operands[3] == const0_rtx)
9252       return \"%i5\\t%0, %1, %2, lsr #31\";
9254     output_asm_insn (\"cmp\\t%2, %3\", operands);
9255     if (GET_CODE (operands[5]) == AND)
9256       output_asm_insn (\"mov%D4\\t%0, #0\", operands);
9257     else if (GET_CODE (operands[5]) == MINUS)
9258       output_asm_insn (\"rsb%D4\\t%0, %1, #0\", operands);
9259     else if (which_alternative != 0)
9260       output_asm_insn (\"mov%D4\\t%0, %1\", operands);
9261     return \"%i5%d4\\t%0, %1, #1\";
9262   "
9263   [(set_attr "conds" "clob")
9264    (set_attr "length" "12")
9265    (set_attr "type" "multiple")]
9268 (define_insn "*cond_sub"
9269   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9270         (minus:SI (match_operand:SI 1 "s_register_operand" "0,?r")
9271                   (match_operator:SI 4 "arm_comparison_operator"
9272                    [(match_operand:SI 2 "s_register_operand" "r,r")
9273                     (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
9274    (clobber (reg:CC CC_REGNUM))]
9275   "TARGET_ARM"
9276   "*
9277     output_asm_insn (\"cmp\\t%2, %3\", operands);
9278     if (which_alternative != 0)
9279       output_asm_insn (\"mov%D4\\t%0, %1\", operands);
9280     return \"sub%d4\\t%0, %1, #1\";
9281   "
9282   [(set_attr "conds" "clob")
9283    (set_attr "length" "8,12")
9284    (set_attr "type" "multiple")]
9287 (define_insn "*cmp_ite0"
9288   [(set (match_operand 6 "dominant_cc_register" "")
9289         (compare
9290          (if_then_else:SI
9291           (match_operator 4 "arm_comparison_operator"
9292            [(match_operand:SI 0 "s_register_operand"
9293                 "l,l,l,r,r,r,r,r,r")
9294             (match_operand:SI 1 "arm_add_operand"
9295                 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
9296           (match_operator:SI 5 "arm_comparison_operator"
9297            [(match_operand:SI 2 "s_register_operand"
9298                 "l,r,r,l,l,r,r,r,r")
9299             (match_operand:SI 3 "arm_add_operand"
9300                 "lPy,rI,L,lPy,lPy,rI,rI,L,L")])
9301           (const_int 0))
9302          (const_int 0)))]
9303   "TARGET_32BIT"
9304   "*
9305   {
9306     static const char * const cmp1[NUM_OF_COND_CMP][2] =
9307     {
9308       {\"cmp%d5\\t%0, %1\",
9309        \"cmp%d4\\t%2, %3\"},
9310       {\"cmn%d5\\t%0, #%n1\",
9311        \"cmp%d4\\t%2, %3\"},
9312       {\"cmp%d5\\t%0, %1\",
9313        \"cmn%d4\\t%2, #%n3\"},
9314       {\"cmn%d5\\t%0, #%n1\",
9315        \"cmn%d4\\t%2, #%n3\"}
9316     };
9317     static const char * const cmp2[NUM_OF_COND_CMP][2] =
9318     {
9319       {\"cmp\\t%2, %3\",
9320        \"cmp\\t%0, %1\"},
9321       {\"cmp\\t%2, %3\",
9322        \"cmn\\t%0, #%n1\"},
9323       {\"cmn\\t%2, #%n3\",
9324        \"cmp\\t%0, %1\"},
9325       {\"cmn\\t%2, #%n3\",
9326        \"cmn\\t%0, #%n1\"}
9327     };
9328     static const char * const ite[2] =
9329     {
9330       \"it\\t%d5\",
9331       \"it\\t%d4\"
9332     };
9333     static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
9334                                    CMP_CMP, CMN_CMP, CMP_CMP,
9335                                    CMN_CMP, CMP_CMN, CMN_CMN};
9336     int swap =
9337       comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
9339     output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
9340     if (TARGET_THUMB2) {
9341       output_asm_insn (ite[swap], operands);
9342     }
9343     output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
9344     return \"\";
9345   }"
9346   [(set_attr "conds" "set")
9347    (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
9348    (set_attr "enabled_for_depr_it" "yes,no,no,no,no,no,no,no,no")
9349    (set_attr "type" "multiple")
9350    (set_attr_alternative "length"
9351       [(const_int 6)
9352        (const_int 8)
9353        (const_int 8)
9354        (const_int 8)
9355        (const_int 8)
9356        (if_then_else (eq_attr "is_thumb" "no")
9357            (const_int 8)
9358            (const_int 10))
9359        (if_then_else (eq_attr "is_thumb" "no")
9360            (const_int 8)
9361            (const_int 10))
9362        (if_then_else (eq_attr "is_thumb" "no")
9363            (const_int 8)
9364            (const_int 10))
9365        (if_then_else (eq_attr "is_thumb" "no")
9366            (const_int 8)
9367            (const_int 10))])]
9370 (define_insn "*cmp_ite1"
9371   [(set (match_operand 6 "dominant_cc_register" "")
9372         (compare
9373          (if_then_else:SI
9374           (match_operator 4 "arm_comparison_operator"
9375            [(match_operand:SI 0 "s_register_operand"
9376                 "l,l,l,r,r,r,r,r,r")
9377             (match_operand:SI 1 "arm_add_operand"
9378                 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
9379           (match_operator:SI 5 "arm_comparison_operator"
9380            [(match_operand:SI 2 "s_register_operand"
9381                 "l,r,r,l,l,r,r,r,r")
9382             (match_operand:SI 3 "arm_add_operand"
9383                 "lPy,rI,L,lPy,lPy,rI,rI,L,L")])
9384           (const_int 1))
9385          (const_int 0)))]
9386   "TARGET_32BIT"
9387   "*
9388   {
9389     static const char * const cmp1[NUM_OF_COND_CMP][2] =
9390     {
9391       {\"cmp\\t%0, %1\",
9392        \"cmp\\t%2, %3\"},
9393       {\"cmn\\t%0, #%n1\",
9394        \"cmp\\t%2, %3\"},
9395       {\"cmp\\t%0, %1\",
9396        \"cmn\\t%2, #%n3\"},
9397       {\"cmn\\t%0, #%n1\",
9398        \"cmn\\t%2, #%n3\"}
9399     };
9400     static const char * const cmp2[NUM_OF_COND_CMP][2] =
9401     {
9402       {\"cmp%d4\\t%2, %3\",
9403        \"cmp%D5\\t%0, %1\"},
9404       {\"cmp%d4\\t%2, %3\",
9405        \"cmn%D5\\t%0, #%n1\"},
9406       {\"cmn%d4\\t%2, #%n3\",
9407        \"cmp%D5\\t%0, %1\"},
9408       {\"cmn%d4\\t%2, #%n3\",
9409        \"cmn%D5\\t%0, #%n1\"}
9410     };
9411     static const char * const ite[2] =
9412     {
9413       \"it\\t%d4\",
9414       \"it\\t%D5\"
9415     };
9416     static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
9417                                    CMP_CMP, CMN_CMP, CMP_CMP,
9418                                    CMN_CMP, CMP_CMN, CMN_CMN};
9419     int swap =
9420       comparison_dominates_p (GET_CODE (operands[5]),
9421                               reverse_condition (GET_CODE (operands[4])));
9423     output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
9424     if (TARGET_THUMB2) {
9425       output_asm_insn (ite[swap], operands);
9426     }
9427     output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
9428     return \"\";
9429   }"
9430   [(set_attr "conds" "set")
9431    (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
9432    (set_attr "enabled_for_depr_it" "yes,no,no,no,no,no,no,no,no")
9433    (set_attr_alternative "length"
9434       [(const_int 6)
9435        (const_int 8)
9436        (const_int 8)
9437        (const_int 8)
9438        (const_int 8)
9439        (if_then_else (eq_attr "is_thumb" "no")
9440            (const_int 8)
9441            (const_int 10))
9442        (if_then_else (eq_attr "is_thumb" "no")
9443            (const_int 8)
9444            (const_int 10))
9445        (if_then_else (eq_attr "is_thumb" "no")
9446            (const_int 8)
9447            (const_int 10))
9448        (if_then_else (eq_attr "is_thumb" "no")
9449            (const_int 8)
9450            (const_int 10))])
9451    (set_attr "type" "multiple")]
9454 (define_insn "*cmp_and"
9455   [(set (match_operand 6 "dominant_cc_register" "")
9456         (compare
9457          (and:SI
9458           (match_operator 4 "arm_comparison_operator"
9459            [(match_operand:SI 0 "s_register_operand" 
9460                 "l,l,l,r,r,r,r,r,r")
9461             (match_operand:SI 1 "arm_add_operand" 
9462                 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
9463           (match_operator:SI 5 "arm_comparison_operator"
9464            [(match_operand:SI 2 "s_register_operand" 
9465                 "l,r,r,l,l,r,r,r,r")
9466             (match_operand:SI 3 "arm_add_operand" 
9467                 "lPy,rI,L,lPy,lPy,rI,rI,L,L")]))
9468          (const_int 0)))]
9469   "TARGET_32BIT"
9470   "*
9471   {
9472     static const char *const cmp1[NUM_OF_COND_CMP][2] =
9473     {
9474       {\"cmp%d5\\t%0, %1\",
9475        \"cmp%d4\\t%2, %3\"},
9476       {\"cmn%d5\\t%0, #%n1\",
9477        \"cmp%d4\\t%2, %3\"},
9478       {\"cmp%d5\\t%0, %1\",
9479        \"cmn%d4\\t%2, #%n3\"},
9480       {\"cmn%d5\\t%0, #%n1\",
9481        \"cmn%d4\\t%2, #%n3\"}
9482     };
9483     static const char *const cmp2[NUM_OF_COND_CMP][2] =
9484     {
9485       {\"cmp\\t%2, %3\",
9486        \"cmp\\t%0, %1\"},
9487       {\"cmp\\t%2, %3\",
9488        \"cmn\\t%0, #%n1\"},
9489       {\"cmn\\t%2, #%n3\",
9490        \"cmp\\t%0, %1\"},
9491       {\"cmn\\t%2, #%n3\",
9492        \"cmn\\t%0, #%n1\"}
9493     };
9494     static const char *const ite[2] =
9495     {
9496       \"it\\t%d5\",
9497       \"it\\t%d4\"
9498     };
9499     static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
9500                                    CMP_CMP, CMN_CMP, CMP_CMP,
9501                                    CMN_CMP, CMP_CMN, CMN_CMN};
9502     int swap =
9503       comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
9505     output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
9506     if (TARGET_THUMB2) {
9507       output_asm_insn (ite[swap], operands);
9508     }
9509     output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
9510     return \"\";
9511   }"
9512   [(set_attr "conds" "set")
9513    (set_attr "predicable" "no")
9514    (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
9515    (set_attr "enabled_for_depr_it" "yes,no,no,no,no,no,no,no,no")
9516    (set_attr_alternative "length"
9517       [(const_int 6)
9518        (const_int 8)
9519        (const_int 8)
9520        (const_int 8)
9521        (const_int 8)
9522        (if_then_else (eq_attr "is_thumb" "no")
9523            (const_int 8)
9524            (const_int 10))
9525        (if_then_else (eq_attr "is_thumb" "no")
9526            (const_int 8)
9527            (const_int 10))
9528        (if_then_else (eq_attr "is_thumb" "no")
9529            (const_int 8)
9530            (const_int 10))
9531        (if_then_else (eq_attr "is_thumb" "no")
9532            (const_int 8)
9533            (const_int 10))])
9534    (set_attr "type" "multiple")]
9537 (define_insn "*cmp_ior"
9538   [(set (match_operand 6 "dominant_cc_register" "")
9539         (compare
9540          (ior:SI
9541           (match_operator 4 "arm_comparison_operator"
9542            [(match_operand:SI 0 "s_register_operand"
9543                 "l,l,l,r,r,r,r,r,r")
9544             (match_operand:SI 1 "arm_add_operand"
9545                 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
9546           (match_operator:SI 5 "arm_comparison_operator"
9547            [(match_operand:SI 2 "s_register_operand"
9548                 "l,r,r,l,l,r,r,r,r")
9549             (match_operand:SI 3 "arm_add_operand"
9550                 "lPy,rI,L,lPy,lPy,rI,rI,L,L")]))
9551          (const_int 0)))]
9552   "TARGET_32BIT"
9553   "*
9554   {
9555     static const char *const cmp1[NUM_OF_COND_CMP][2] =
9556     {
9557       {\"cmp\\t%0, %1\",
9558        \"cmp\\t%2, %3\"},
9559       {\"cmn\\t%0, #%n1\",
9560        \"cmp\\t%2, %3\"},
9561       {\"cmp\\t%0, %1\",
9562        \"cmn\\t%2, #%n3\"},
9563       {\"cmn\\t%0, #%n1\",
9564        \"cmn\\t%2, #%n3\"}
9565     };
9566     static const char *const cmp2[NUM_OF_COND_CMP][2] =
9567     {
9568       {\"cmp%D4\\t%2, %3\",
9569        \"cmp%D5\\t%0, %1\"},
9570       {\"cmp%D4\\t%2, %3\",
9571        \"cmn%D5\\t%0, #%n1\"},
9572       {\"cmn%D4\\t%2, #%n3\",
9573        \"cmp%D5\\t%0, %1\"},
9574       {\"cmn%D4\\t%2, #%n3\",
9575        \"cmn%D5\\t%0, #%n1\"}
9576     };
9577     static const char *const ite[2] =
9578     {
9579       \"it\\t%D4\",
9580       \"it\\t%D5\"
9581     };
9582     static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
9583                                    CMP_CMP, CMN_CMP, CMP_CMP,
9584                                    CMN_CMP, CMP_CMN, CMN_CMN};
9585     int swap =
9586       comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
9588     output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
9589     if (TARGET_THUMB2) {
9590       output_asm_insn (ite[swap], operands);
9591     }
9592     output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
9593     return \"\";
9594   }
9595   "
9596   [(set_attr "conds" "set")
9597    (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
9598    (set_attr "enabled_for_depr_it" "yes,no,no,no,no,no,no,no,no")
9599    (set_attr_alternative "length"
9600       [(const_int 6)
9601        (const_int 8)
9602        (const_int 8)
9603        (const_int 8)
9604        (const_int 8)
9605        (if_then_else (eq_attr "is_thumb" "no")
9606            (const_int 8)
9607            (const_int 10))
9608        (if_then_else (eq_attr "is_thumb" "no")
9609            (const_int 8)
9610            (const_int 10))
9611        (if_then_else (eq_attr "is_thumb" "no")
9612            (const_int 8)
9613            (const_int 10))
9614        (if_then_else (eq_attr "is_thumb" "no")
9615            (const_int 8)
9616            (const_int 10))])
9617    (set_attr "type" "multiple")]
9620 (define_insn_and_split "*ior_scc_scc"
9621   [(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts")
9622         (ior:SI (match_operator:SI 3 "arm_comparison_operator"
9623                  [(match_operand:SI 1 "s_register_operand" "l,r")
9624                   (match_operand:SI 2 "arm_add_operand" "lPy,rIL")])
9625                 (match_operator:SI 6 "arm_comparison_operator"
9626                  [(match_operand:SI 4 "s_register_operand" "l,r")
9627                   (match_operand:SI 5 "arm_add_operand" "lPy,rIL")])))
9628    (clobber (reg:CC CC_REGNUM))]
9629   "TARGET_32BIT
9630    && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_OR_Y)
9631        != CCmode)"
9632   "#"
9633   "TARGET_32BIT && reload_completed"
9634   [(set (match_dup 7)
9635         (compare
9636          (ior:SI
9637           (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9638           (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9639          (const_int 0)))
9640    (set (match_dup 0) (ne:SI (match_dup 7) (const_int 0)))]
9641   "operands[7]
9642      = gen_rtx_REG (arm_select_dominance_cc_mode (operands[3], operands[6],
9643                                                   DOM_CC_X_OR_Y),
9644                     CC_REGNUM);"
9645   [(set_attr "conds" "clob")
9646    (set_attr "enabled_for_depr_it" "yes,no")
9647    (set_attr "length" "16")
9648    (set_attr "type" "multiple")]
9651 ; If the above pattern is followed by a CMP insn, then the compare is 
9652 ; redundant, since we can rework the conditional instruction that follows.
9653 (define_insn_and_split "*ior_scc_scc_cmp"
9654   [(set (match_operand 0 "dominant_cc_register" "")
9655         (compare (ior:SI (match_operator:SI 3 "arm_comparison_operator"
9656                           [(match_operand:SI 1 "s_register_operand" "l,r")
9657                            (match_operand:SI 2 "arm_add_operand" "lPy,rIL")])
9658                          (match_operator:SI 6 "arm_comparison_operator"
9659                           [(match_operand:SI 4 "s_register_operand" "l,r")
9660                            (match_operand:SI 5 "arm_add_operand" "lPy,rIL")]))
9661                  (const_int 0)))
9662    (set (match_operand:SI 7 "s_register_operand" "=Ts,Ts")
9663         (ior:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9664                 (match_op_dup 6 [(match_dup 4) (match_dup 5)])))]
9665   "TARGET_32BIT"
9666   "#"
9667   "TARGET_32BIT && reload_completed"
9668   [(set (match_dup 0)
9669         (compare
9670          (ior:SI
9671           (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9672           (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9673          (const_int 0)))
9674    (set (match_dup 7) (ne:SI (match_dup 0) (const_int 0)))]
9675   ""
9676   [(set_attr "conds" "set")
9677    (set_attr "enabled_for_depr_it" "yes,no")
9678    (set_attr "length" "16")
9679    (set_attr "type" "multiple")]
9682 (define_insn_and_split "*and_scc_scc"
9683   [(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts")
9684         (and:SI (match_operator:SI 3 "arm_comparison_operator"
9685                  [(match_operand:SI 1 "s_register_operand" "l,r")
9686                   (match_operand:SI 2 "arm_add_operand" "lPy,rIL")])
9687                 (match_operator:SI 6 "arm_comparison_operator"
9688                  [(match_operand:SI 4 "s_register_operand" "l,r")
9689                   (match_operand:SI 5 "arm_add_operand" "lPy,rIL")])))
9690    (clobber (reg:CC CC_REGNUM))]
9691   "TARGET_32BIT
9692    && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
9693        != CCmode)"
9694   "#"
9695   "TARGET_32BIT && reload_completed
9696    && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
9697        != CCmode)"
9698   [(set (match_dup 7)
9699         (compare
9700          (and:SI
9701           (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9702           (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9703          (const_int 0)))
9704    (set (match_dup 0) (ne:SI (match_dup 7) (const_int 0)))]
9705   "operands[7]
9706      = gen_rtx_REG (arm_select_dominance_cc_mode (operands[3], operands[6],
9707                                                   DOM_CC_X_AND_Y),
9708                     CC_REGNUM);"
9709   [(set_attr "conds" "clob")
9710    (set_attr "enabled_for_depr_it" "yes,no")
9711    (set_attr "length" "16")
9712    (set_attr "type" "multiple")]
9715 ; If the above pattern is followed by a CMP insn, then the compare is 
9716 ; redundant, since we can rework the conditional instruction that follows.
9717 (define_insn_and_split "*and_scc_scc_cmp"
9718   [(set (match_operand 0 "dominant_cc_register" "")
9719         (compare (and:SI (match_operator:SI 3 "arm_comparison_operator"
9720                           [(match_operand:SI 1 "s_register_operand" "l,r")
9721                            (match_operand:SI 2 "arm_add_operand" "lPy,rIL")])
9722                          (match_operator:SI 6 "arm_comparison_operator"
9723                           [(match_operand:SI 4 "s_register_operand" "l,r")
9724                            (match_operand:SI 5 "arm_add_operand" "lPy,rIL")]))
9725                  (const_int 0)))
9726    (set (match_operand:SI 7 "s_register_operand" "=Ts,Ts")
9727         (and:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9728                 (match_op_dup 6 [(match_dup 4) (match_dup 5)])))]
9729   "TARGET_32BIT"
9730   "#"
9731   "TARGET_32BIT && reload_completed"
9732   [(set (match_dup 0)
9733         (compare
9734          (and:SI
9735           (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9736           (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9737          (const_int 0)))
9738    (set (match_dup 7) (ne:SI (match_dup 0) (const_int 0)))]
9739   ""
9740   [(set_attr "conds" "set")
9741    (set_attr "enabled_for_depr_it" "yes,no")
9742    (set_attr "length" "16")
9743    (set_attr "type" "multiple")]
9746 ;; If there is no dominance in the comparison, then we can still save an
9747 ;; instruction in the AND case, since we can know that the second compare
9748 ;; need only zero the value if false (if true, then the value is already
9749 ;; correct).
9750 (define_insn_and_split "*and_scc_scc_nodom"
9751   [(set (match_operand:SI 0 "s_register_operand" "=&Ts,&Ts,&Ts")
9752         (and:SI (match_operator:SI 3 "arm_comparison_operator"
9753                  [(match_operand:SI 1 "s_register_operand" "r,r,0")
9754                   (match_operand:SI 2 "arm_add_operand" "rIL,0,rIL")])
9755                 (match_operator:SI 6 "arm_comparison_operator"
9756                  [(match_operand:SI 4 "s_register_operand" "r,r,r")
9757                   (match_operand:SI 5 "arm_add_operand" "rIL,rIL,rIL")])))
9758    (clobber (reg:CC CC_REGNUM))]
9759   "TARGET_32BIT
9760    && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
9761        == CCmode)"
9762   "#"
9763   "TARGET_32BIT && reload_completed"
9764   [(parallel [(set (match_dup 0)
9765                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
9766               (clobber (reg:CC CC_REGNUM))])
9767    (set (match_dup 7) (match_op_dup 8 [(match_dup 4) (match_dup 5)]))
9768    (set (match_dup 0)
9769         (if_then_else:SI (match_op_dup 6 [(match_dup 7) (const_int 0)])
9770                          (match_dup 0)
9771                          (const_int 0)))]
9772   "operands[7] = gen_rtx_REG (SELECT_CC_MODE (GET_CODE (operands[6]),
9773                                               operands[4], operands[5]),
9774                               CC_REGNUM);
9775    operands[8] = gen_rtx_COMPARE (GET_MODE (operands[7]), operands[4],
9776                                   operands[5]);"
9777   [(set_attr "conds" "clob")
9778    (set_attr "length" "20")
9779    (set_attr "type" "multiple")]
9782 (define_split
9783   [(set (reg:CC_NOOV CC_REGNUM)
9784         (compare:CC_NOOV (ior:SI
9785                           (and:SI (match_operand:SI 0 "s_register_operand" "")
9786                                   (const_int 1))
9787                           (match_operator:SI 1 "arm_comparison_operator"
9788                            [(match_operand:SI 2 "s_register_operand" "")
9789                             (match_operand:SI 3 "arm_add_operand" "")]))
9790                          (const_int 0)))
9791    (clobber (match_operand:SI 4 "s_register_operand" ""))]
9792   "TARGET_ARM"
9793   [(set (match_dup 4)
9794         (ior:SI (match_op_dup 1 [(match_dup 2) (match_dup 3)])
9795                 (match_dup 0)))
9796    (set (reg:CC_NOOV CC_REGNUM)
9797         (compare:CC_NOOV (and:SI (match_dup 4) (const_int 1))
9798                          (const_int 0)))]
9799   "")
9801 (define_split
9802   [(set (reg:CC_NOOV CC_REGNUM)
9803         (compare:CC_NOOV (ior:SI
9804                           (match_operator:SI 1 "arm_comparison_operator"
9805                            [(match_operand:SI 2 "s_register_operand" "")
9806                             (match_operand:SI 3 "arm_add_operand" "")])
9807                           (and:SI (match_operand:SI 0 "s_register_operand" "")
9808                                   (const_int 1)))
9809                          (const_int 0)))
9810    (clobber (match_operand:SI 4 "s_register_operand" ""))]
9811   "TARGET_ARM"
9812   [(set (match_dup 4)
9813         (ior:SI (match_op_dup 1 [(match_dup 2) (match_dup 3)])
9814                 (match_dup 0)))
9815    (set (reg:CC_NOOV CC_REGNUM)
9816         (compare:CC_NOOV (and:SI (match_dup 4) (const_int 1))
9817                          (const_int 0)))]
9818   "")
9819 ;; ??? The conditional patterns above need checking for Thumb-2 usefulness
9821 (define_insn_and_split "*negscc"
9822   [(set (match_operand:SI 0 "s_register_operand" "=r")
9823         (neg:SI (match_operator 3 "arm_comparison_operator"
9824                  [(match_operand:SI 1 "s_register_operand" "r")
9825                   (match_operand:SI 2 "arm_rhs_operand" "rI")])))
9826    (clobber (reg:CC CC_REGNUM))]
9827   "TARGET_ARM"
9828   "#"
9829   "&& reload_completed"
9830   [(const_int 0)]
9831   {
9832     rtx cc_reg = gen_rtx_REG (CCmode, CC_REGNUM);
9834     if (GET_CODE (operands[3]) == LT && operands[2] == const0_rtx)
9835        {
9836          /* Emit mov\\t%0, %1, asr #31 */
9837          emit_insn (gen_rtx_SET (operands[0],
9838                                  gen_rtx_ASHIFTRT (SImode,
9839                                                    operands[1],
9840                                                    GEN_INT (31))));
9841          DONE;
9842        }
9843      else if (GET_CODE (operands[3]) == NE)
9844        {
9845         /* Emit subs\\t%0, %1, %2\;mvnne\\t%0, #0 */
9846         if (CONST_INT_P (operands[2]))
9847           emit_insn (gen_cmpsi2_addneg (operands[0], operands[1], operands[2],
9848                                         GEN_INT (- INTVAL (operands[2]))));
9849         else
9850           emit_insn (gen_subsi3_compare (operands[0], operands[1], operands[2]));
9852         emit_insn (gen_rtx_COND_EXEC (VOIDmode,
9853                                       gen_rtx_NE (SImode,
9854                                                   cc_reg,
9855                                                   const0_rtx),
9856                                       gen_rtx_SET (operands[0],
9857                                                    GEN_INT (~0))));
9858         DONE;
9859       }
9860     else
9861       {
9862         /* Emit: cmp\\t%1, %2\;mov%D3\\t%0, #0\;mvn%d3\\t%0, #0 */
9863         emit_insn (gen_rtx_SET (cc_reg,
9864                                 gen_rtx_COMPARE (CCmode, operands[1], operands[2])));
9865         enum rtx_code rc = GET_CODE (operands[3]);
9867         rc = reverse_condition (rc);
9868         emit_insn (gen_rtx_COND_EXEC (VOIDmode,
9869                                       gen_rtx_fmt_ee (rc,
9870                                                       VOIDmode,
9871                                                       cc_reg,
9872                                                       const0_rtx),
9873                                       gen_rtx_SET (operands[0], const0_rtx)));
9874         rc = GET_CODE (operands[3]);
9875         emit_insn (gen_rtx_COND_EXEC (VOIDmode,
9876                                       gen_rtx_fmt_ee (rc,
9877                                                       VOIDmode,
9878                                                       cc_reg,
9879                                                       const0_rtx),
9880                                       gen_rtx_SET (operands[0],
9881                                                    GEN_INT (~0))));
9882         DONE;
9883       }
9884      FAIL;
9885   }
9886   [(set_attr "conds" "clob")
9887    (set_attr "length" "12")
9888    (set_attr "type" "multiple")]
9891 (define_insn_and_split "movcond_addsi"
9892   [(set (match_operand:SI 0 "s_register_operand" "=r,l,r")
9893         (if_then_else:SI
9894          (match_operator 5 "comparison_operator"
9895           [(plus:SI (match_operand:SI 3 "s_register_operand" "r,r,r")
9896                     (match_operand:SI 4 "arm_add_operand" "rIL,rIL,rIL"))
9897             (const_int 0)])
9898          (match_operand:SI 1 "arm_rhs_operand" "rI,rPy,r")
9899          (match_operand:SI 2 "arm_rhs_operand" "rI,rPy,r")))
9900    (clobber (reg:CC CC_REGNUM))]
9901    "TARGET_32BIT"
9902    "#"
9903    "&& reload_completed"
9904   [(set (reg:CC_NOOV CC_REGNUM)
9905         (compare:CC_NOOV
9906          (plus:SI (match_dup 3)
9907                   (match_dup 4))
9908          (const_int 0)))
9909    (set (match_dup 0) (match_dup 1))
9910    (cond_exec (match_dup 6)
9911               (set (match_dup 0) (match_dup 2)))]
9912   "
9913   {
9914     machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[5]),
9915                                              operands[3], operands[4]);
9916     enum rtx_code rc = GET_CODE (operands[5]);
9917     operands[6] = gen_rtx_REG (mode, CC_REGNUM);
9918     gcc_assert (!(mode == CCFPmode || mode == CCFPEmode));
9919     if (!REG_P (operands[2]) || REGNO (operands[2]) != REGNO (operands[0]))
9920       rc = reverse_condition (rc);
9921     else
9922       std::swap (operands[1], operands[2]);
9924     operands[6] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
9925   }
9926   "
9927   [(set_attr "conds" "clob")
9928    (set_attr "enabled_for_depr_it" "no,yes,yes")
9929    (set_attr "type" "multiple")]
9932 (define_insn "movcond"
9933   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9934         (if_then_else:SI
9935          (match_operator 5 "arm_comparison_operator"
9936           [(match_operand:SI 3 "s_register_operand" "r,r,r")
9937            (match_operand:SI 4 "arm_add_operand" "rIL,rIL,rIL")])
9938          (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
9939          (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
9940    (clobber (reg:CC CC_REGNUM))]
9941   "TARGET_ARM"
9942   "*
9943   if (GET_CODE (operands[5]) == LT
9944       && (operands[4] == const0_rtx))
9945     {
9946       if (which_alternative != 1 && REG_P (operands[1]))
9947         {
9948           if (operands[2] == const0_rtx)
9949             return \"and\\t%0, %1, %3, asr #31\";
9950           return \"ands\\t%0, %1, %3, asr #32\;movcc\\t%0, %2\";
9951         }
9952       else if (which_alternative != 0 && REG_P (operands[2]))
9953         {
9954           if (operands[1] == const0_rtx)
9955             return \"bic\\t%0, %2, %3, asr #31\";
9956           return \"bics\\t%0, %2, %3, asr #32\;movcs\\t%0, %1\";
9957         }
9958       /* The only case that falls through to here is when both ops 1 & 2
9959          are constants.  */
9960     }
9962   if (GET_CODE (operands[5]) == GE
9963       && (operands[4] == const0_rtx))
9964     {
9965       if (which_alternative != 1 && REG_P (operands[1]))
9966         {
9967           if (operands[2] == const0_rtx)
9968             return \"bic\\t%0, %1, %3, asr #31\";
9969           return \"bics\\t%0, %1, %3, asr #32\;movcs\\t%0, %2\";
9970         }
9971       else if (which_alternative != 0 && REG_P (operands[2]))
9972         {
9973           if (operands[1] == const0_rtx)
9974             return \"and\\t%0, %2, %3, asr #31\";
9975           return \"ands\\t%0, %2, %3, asr #32\;movcc\\t%0, %1\";
9976         }
9977       /* The only case that falls through to here is when both ops 1 & 2
9978          are constants.  */
9979     }
9980   if (CONST_INT_P (operands[4])
9981       && !const_ok_for_arm (INTVAL (operands[4])))
9982     output_asm_insn (\"cmn\\t%3, #%n4\", operands);
9983   else
9984     output_asm_insn (\"cmp\\t%3, %4\", operands);
9985   if (which_alternative != 0)
9986     output_asm_insn (\"mov%d5\\t%0, %1\", operands);
9987   if (which_alternative != 1)
9988     output_asm_insn (\"mov%D5\\t%0, %2\", operands);
9989   return \"\";
9990   "
9991   [(set_attr "conds" "clob")
9992    (set_attr "length" "8,8,12")
9993    (set_attr "type" "multiple")]
9996 ;; ??? The patterns below need checking for Thumb-2 usefulness.
9998 (define_insn "*ifcompare_plus_move"
9999   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10000         (if_then_else:SI (match_operator 6 "arm_comparison_operator"
10001                           [(match_operand:SI 4 "s_register_operand" "r,r")
10002                            (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
10003                          (plus:SI
10004                           (match_operand:SI 2 "s_register_operand" "r,r")
10005                           (match_operand:SI 3 "arm_add_operand" "rIL,rIL"))
10006                          (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))
10007    (clobber (reg:CC CC_REGNUM))]
10008   "TARGET_ARM"
10009   "#"
10010   [(set_attr "conds" "clob")
10011    (set_attr "length" "8,12")
10012    (set_attr "type" "multiple")]
10015 (define_insn "*if_plus_move"
10016   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
10017         (if_then_else:SI
10018          (match_operator 4 "arm_comparison_operator"
10019           [(match_operand 5 "cc_register" "") (const_int 0)])
10020          (plus:SI
10021           (match_operand:SI 2 "s_register_operand" "r,r,r,r")
10022           (match_operand:SI 3 "arm_add_operand" "rI,L,rI,L"))
10023          (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")))]
10024   "TARGET_ARM"
10025   "@
10026    add%d4\\t%0, %2, %3
10027    sub%d4\\t%0, %2, #%n3
10028    add%d4\\t%0, %2, %3\;mov%D4\\t%0, %1
10029    sub%d4\\t%0, %2, #%n3\;mov%D4\\t%0, %1"
10030   [(set_attr "conds" "use")
10031    (set_attr "length" "4,4,8,8")
10032    (set_attr_alternative "type"
10033                          [(if_then_else (match_operand 3 "const_int_operand" "")
10034                                         (const_string "alu_imm" )
10035                                         (const_string "alu_sreg"))
10036                           (const_string "alu_imm")
10037                           (const_string "multiple")
10038                           (const_string "multiple")])]
10041 (define_insn "*ifcompare_move_plus"
10042   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10043         (if_then_else:SI (match_operator 6 "arm_comparison_operator"
10044                           [(match_operand:SI 4 "s_register_operand" "r,r")
10045                            (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
10046                          (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
10047                          (plus:SI
10048                           (match_operand:SI 2 "s_register_operand" "r,r")
10049                           (match_operand:SI 3 "arm_add_operand" "rIL,rIL"))))
10050    (clobber (reg:CC CC_REGNUM))]
10051   "TARGET_ARM"
10052   "#"
10053   [(set_attr "conds" "clob")
10054    (set_attr "length" "8,12")
10055    (set_attr "type" "multiple")]
10058 (define_insn "*if_move_plus"
10059   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
10060         (if_then_else:SI
10061          (match_operator 4 "arm_comparison_operator"
10062           [(match_operand 5 "cc_register" "") (const_int 0)])
10063          (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")
10064          (plus:SI
10065           (match_operand:SI 2 "s_register_operand" "r,r,r,r")
10066           (match_operand:SI 3 "arm_add_operand" "rI,L,rI,L"))))]
10067   "TARGET_ARM"
10068   "@
10069    add%D4\\t%0, %2, %3
10070    sub%D4\\t%0, %2, #%n3
10071    add%D4\\t%0, %2, %3\;mov%d4\\t%0, %1
10072    sub%D4\\t%0, %2, #%n3\;mov%d4\\t%0, %1"
10073   [(set_attr "conds" "use")
10074    (set_attr "length" "4,4,8,8")
10075    (set_attr_alternative "type"
10076                          [(if_then_else (match_operand 3 "const_int_operand" "")
10077                                         (const_string "alu_imm" )
10078                                         (const_string "alu_sreg"))
10079                           (const_string "alu_imm")
10080                           (const_string "multiple")
10081                           (const_string "multiple")])]
10084 (define_insn "*ifcompare_arith_arith"
10085   [(set (match_operand:SI 0 "s_register_operand" "=r")
10086         (if_then_else:SI (match_operator 9 "arm_comparison_operator"
10087                           [(match_operand:SI 5 "s_register_operand" "r")
10088                            (match_operand:SI 6 "arm_add_operand" "rIL")])
10089                          (match_operator:SI 8 "shiftable_operator"
10090                           [(match_operand:SI 1 "s_register_operand" "r")
10091                            (match_operand:SI 2 "arm_rhs_operand" "rI")])
10092                          (match_operator:SI 7 "shiftable_operator"
10093                           [(match_operand:SI 3 "s_register_operand" "r")
10094                            (match_operand:SI 4 "arm_rhs_operand" "rI")])))
10095    (clobber (reg:CC CC_REGNUM))]
10096   "TARGET_ARM"
10097   "#"
10098   [(set_attr "conds" "clob")
10099    (set_attr "length" "12")
10100    (set_attr "type" "multiple")]
10103 (define_insn "*if_arith_arith"
10104   [(set (match_operand:SI 0 "s_register_operand" "=r")
10105         (if_then_else:SI (match_operator 5 "arm_comparison_operator"
10106                           [(match_operand 8 "cc_register" "") (const_int 0)])
10107                          (match_operator:SI 6 "shiftable_operator"
10108                           [(match_operand:SI 1 "s_register_operand" "r")
10109                            (match_operand:SI 2 "arm_rhs_operand" "rI")])
10110                          (match_operator:SI 7 "shiftable_operator"
10111                           [(match_operand:SI 3 "s_register_operand" "r")
10112                            (match_operand:SI 4 "arm_rhs_operand" "rI")])))]
10113   "TARGET_ARM"
10114   "%I6%d5\\t%0, %1, %2\;%I7%D5\\t%0, %3, %4"
10115   [(set_attr "conds" "use")
10116    (set_attr "length" "8")
10117    (set_attr "type" "multiple")]
10120 (define_insn "*ifcompare_arith_move"
10121   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10122         (if_then_else:SI (match_operator 6 "arm_comparison_operator"
10123                           [(match_operand:SI 2 "s_register_operand" "r,r")
10124                            (match_operand:SI 3 "arm_add_operand" "rIL,rIL")])
10125                          (match_operator:SI 7 "shiftable_operator"
10126                           [(match_operand:SI 4 "s_register_operand" "r,r")
10127                            (match_operand:SI 5 "arm_rhs_operand" "rI,rI")])
10128                          (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))
10129    (clobber (reg:CC CC_REGNUM))]
10130   "TARGET_ARM"
10131   "*
10132   /* If we have an operation where (op x 0) is the identity operation and
10133      the conditional operator is LT or GE and we are comparing against zero and
10134      everything is in registers then we can do this in two instructions.  */
10135   if (operands[3] == const0_rtx
10136       && GET_CODE (operands[7]) != AND
10137       && REG_P (operands[5])
10138       && REG_P (operands[1])
10139       && REGNO (operands[1]) == REGNO (operands[4])
10140       && REGNO (operands[4]) != REGNO (operands[0]))
10141     {
10142       if (GET_CODE (operands[6]) == LT)
10143         return \"and\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\";
10144       else if (GET_CODE (operands[6]) == GE)
10145         return \"bic\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\";
10146     }
10147   if (CONST_INT_P (operands[3])
10148       && !const_ok_for_arm (INTVAL (operands[3])))
10149     output_asm_insn (\"cmn\\t%2, #%n3\", operands);
10150   else
10151     output_asm_insn (\"cmp\\t%2, %3\", operands);
10152   output_asm_insn (\"%I7%d6\\t%0, %4, %5\", operands);
10153   if (which_alternative != 0)
10154     return \"mov%D6\\t%0, %1\";
10155   return \"\";
10156   "
10157   [(set_attr "conds" "clob")
10158    (set_attr "length" "8,12")
10159    (set_attr "type" "multiple")]
10162 (define_insn "*if_arith_move"
10163   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10164         (if_then_else:SI (match_operator 4 "arm_comparison_operator"
10165                           [(match_operand 6 "cc_register" "") (const_int 0)])
10166                          (match_operator:SI 5 "shiftable_operator"
10167                           [(match_operand:SI 2 "s_register_operand" "r,r")
10168                            (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
10169                          (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))]
10170   "TARGET_ARM"
10171   "@
10172    %I5%d4\\t%0, %2, %3
10173    %I5%d4\\t%0, %2, %3\;mov%D4\\t%0, %1"
10174   [(set_attr "conds" "use")
10175    (set_attr "length" "4,8")
10176    (set_attr_alternative "type"
10177                          [(if_then_else (match_operand 3 "const_int_operand" "")
10178                                         (const_string "alu_shift_imm" )
10179                                         (const_string "alu_shift_reg"))
10180                           (const_string "multiple")])]
10183 (define_insn "*ifcompare_move_arith"
10184   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10185         (if_then_else:SI (match_operator 6 "arm_comparison_operator"
10186                           [(match_operand:SI 4 "s_register_operand" "r,r")
10187                            (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
10188                          (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
10189                          (match_operator:SI 7 "shiftable_operator"
10190                           [(match_operand:SI 2 "s_register_operand" "r,r")
10191                            (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
10192    (clobber (reg:CC CC_REGNUM))]
10193   "TARGET_ARM"
10194   "*
10195   /* If we have an operation where (op x 0) is the identity operation and
10196      the conditional operator is LT or GE and we are comparing against zero and
10197      everything is in registers then we can do this in two instructions */
10198   if (operands[5] == const0_rtx
10199       && GET_CODE (operands[7]) != AND
10200       && REG_P (operands[3])
10201       && REG_P (operands[1])
10202       && REGNO (operands[1]) == REGNO (operands[2])
10203       && REGNO (operands[2]) != REGNO (operands[0]))
10204     {
10205       if (GET_CODE (operands[6]) == GE)
10206         return \"and\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\";
10207       else if (GET_CODE (operands[6]) == LT)
10208         return \"bic\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\";
10209     }
10211   if (CONST_INT_P (operands[5])
10212       && !const_ok_for_arm (INTVAL (operands[5])))
10213     output_asm_insn (\"cmn\\t%4, #%n5\", operands);
10214   else
10215     output_asm_insn (\"cmp\\t%4, %5\", operands);
10217   if (which_alternative != 0)
10218     output_asm_insn (\"mov%d6\\t%0, %1\", operands);
10219   return \"%I7%D6\\t%0, %2, %3\";
10220   "
10221   [(set_attr "conds" "clob")
10222    (set_attr "length" "8,12")
10223    (set_attr "type" "multiple")]
10226 (define_insn "*if_move_arith"
10227   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10228         (if_then_else:SI
10229          (match_operator 4 "arm_comparison_operator"
10230           [(match_operand 6 "cc_register" "") (const_int 0)])
10231          (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
10232          (match_operator:SI 5 "shiftable_operator"
10233           [(match_operand:SI 2 "s_register_operand" "r,r")
10234            (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))]
10235   "TARGET_ARM"
10236   "@
10237    %I5%D4\\t%0, %2, %3
10238    %I5%D4\\t%0, %2, %3\;mov%d4\\t%0, %1"
10239   [(set_attr "conds" "use")
10240    (set_attr "length" "4,8")
10241    (set_attr_alternative "type"
10242                          [(if_then_else (match_operand 3 "const_int_operand" "")
10243                                         (const_string "alu_shift_imm" )
10244                                         (const_string "alu_shift_reg"))
10245                           (const_string "multiple")])]
10248 (define_insn "*ifcompare_move_not"
10249   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10250         (if_then_else:SI
10251          (match_operator 5 "arm_comparison_operator"
10252           [(match_operand:SI 3 "s_register_operand" "r,r")
10253            (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
10254          (match_operand:SI 1 "arm_not_operand" "0,?rIK")
10255          (not:SI
10256           (match_operand:SI 2 "s_register_operand" "r,r"))))
10257    (clobber (reg:CC CC_REGNUM))]
10258   "TARGET_ARM"
10259   "#"
10260   [(set_attr "conds" "clob")
10261    (set_attr "length" "8,12")
10262    (set_attr "type" "multiple")]
10265 (define_insn "*if_move_not"
10266   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
10267         (if_then_else:SI
10268          (match_operator 4 "arm_comparison_operator"
10269           [(match_operand 3 "cc_register" "") (const_int 0)])
10270          (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
10271          (not:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))))]
10272   "TARGET_ARM"
10273   "@
10274    mvn%D4\\t%0, %2
10275    mov%d4\\t%0, %1\;mvn%D4\\t%0, %2
10276    mvn%d4\\t%0, #%B1\;mvn%D4\\t%0, %2"
10277   [(set_attr "conds" "use")
10278    (set_attr "type" "mvn_reg")
10279    (set_attr "length" "4,8,8")
10280    (set_attr "type" "mvn_reg,multiple,multiple")]
10283 (define_insn "*ifcompare_not_move"
10284   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10285         (if_then_else:SI 
10286          (match_operator 5 "arm_comparison_operator"
10287           [(match_operand:SI 3 "s_register_operand" "r,r")
10288            (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
10289          (not:SI
10290           (match_operand:SI 2 "s_register_operand" "r,r"))
10291          (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
10292    (clobber (reg:CC CC_REGNUM))]
10293   "TARGET_ARM"
10294   "#"
10295   [(set_attr "conds" "clob")
10296    (set_attr "length" "8,12")
10297    (set_attr "type" "multiple")]
10300 (define_insn "*if_not_move"
10301   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
10302         (if_then_else:SI
10303          (match_operator 4 "arm_comparison_operator"
10304           [(match_operand 3 "cc_register" "") (const_int 0)])
10305          (not:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))
10306          (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
10307   "TARGET_ARM"
10308   "@
10309    mvn%d4\\t%0, %2
10310    mov%D4\\t%0, %1\;mvn%d4\\t%0, %2
10311    mvn%D4\\t%0, #%B1\;mvn%d4\\t%0, %2"
10312   [(set_attr "conds" "use")
10313    (set_attr "type" "mvn_reg,multiple,multiple")
10314    (set_attr "length" "4,8,8")]
10317 (define_insn "*ifcompare_shift_move"
10318   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10319         (if_then_else:SI
10320          (match_operator 6 "arm_comparison_operator"
10321           [(match_operand:SI 4 "s_register_operand" "r,r")
10322            (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
10323          (match_operator:SI 7 "shift_operator"
10324           [(match_operand:SI 2 "s_register_operand" "r,r")
10325            (match_operand:SI 3 "arm_rhs_operand" "rM,rM")])
10326          (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
10327    (clobber (reg:CC CC_REGNUM))]
10328   "TARGET_ARM"
10329   "#"
10330   [(set_attr "conds" "clob")
10331    (set_attr "length" "8,12")
10332    (set_attr "type" "multiple")]
10335 (define_insn "*if_shift_move"
10336   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
10337         (if_then_else:SI
10338          (match_operator 5 "arm_comparison_operator"
10339           [(match_operand 6 "cc_register" "") (const_int 0)])
10340          (match_operator:SI 4 "shift_operator"
10341           [(match_operand:SI 2 "s_register_operand" "r,r,r")
10342            (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM")])
10343          (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
10344   "TARGET_ARM"
10345   "@
10346    mov%d5\\t%0, %2%S4
10347    mov%D5\\t%0, %1\;mov%d5\\t%0, %2%S4
10348    mvn%D5\\t%0, #%B1\;mov%d5\\t%0, %2%S4"
10349   [(set_attr "conds" "use")
10350    (set_attr "shift" "2")
10351    (set_attr "length" "4,8,8")
10352    (set_attr_alternative "type"
10353                          [(if_then_else (match_operand 3 "const_int_operand" "")
10354                                         (const_string "mov_shift" )
10355                                         (const_string "mov_shift_reg"))
10356                           (const_string "multiple")
10357                           (const_string "multiple")])]
10360 (define_insn "*ifcompare_move_shift"
10361   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10362         (if_then_else:SI
10363          (match_operator 6 "arm_comparison_operator"
10364           [(match_operand:SI 4 "s_register_operand" "r,r")
10365            (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
10366          (match_operand:SI 1 "arm_not_operand" "0,?rIK")
10367          (match_operator:SI 7 "shift_operator"
10368           [(match_operand:SI 2 "s_register_operand" "r,r")
10369            (match_operand:SI 3 "arm_rhs_operand" "rM,rM")])))
10370    (clobber (reg:CC CC_REGNUM))]
10371   "TARGET_ARM"
10372   "#"
10373   [(set_attr "conds" "clob")
10374    (set_attr "length" "8,12")
10375    (set_attr "type" "multiple")]
10378 (define_insn "*if_move_shift"
10379   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
10380         (if_then_else:SI
10381          (match_operator 5 "arm_comparison_operator"
10382           [(match_operand 6 "cc_register" "") (const_int 0)])
10383          (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
10384          (match_operator:SI 4 "shift_operator"
10385           [(match_operand:SI 2 "s_register_operand" "r,r,r")
10386            (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM")])))]
10387   "TARGET_ARM"
10388   "@
10389    mov%D5\\t%0, %2%S4
10390    mov%d5\\t%0, %1\;mov%D5\\t%0, %2%S4
10391    mvn%d5\\t%0, #%B1\;mov%D5\\t%0, %2%S4"
10392   [(set_attr "conds" "use")
10393    (set_attr "shift" "2")
10394    (set_attr "length" "4,8,8")
10395    (set_attr_alternative "type"
10396                          [(if_then_else (match_operand 3 "const_int_operand" "")
10397                                         (const_string "mov_shift" )
10398                                         (const_string "mov_shift_reg"))
10399                           (const_string "multiple")
10400                           (const_string "multiple")])]
10403 (define_insn "*ifcompare_shift_shift"
10404   [(set (match_operand:SI 0 "s_register_operand" "=r")
10405         (if_then_else:SI
10406          (match_operator 7 "arm_comparison_operator"
10407           [(match_operand:SI 5 "s_register_operand" "r")
10408            (match_operand:SI 6 "arm_add_operand" "rIL")])
10409          (match_operator:SI 8 "shift_operator"
10410           [(match_operand:SI 1 "s_register_operand" "r")
10411            (match_operand:SI 2 "arm_rhs_operand" "rM")])
10412          (match_operator:SI 9 "shift_operator"
10413           [(match_operand:SI 3 "s_register_operand" "r")
10414            (match_operand:SI 4 "arm_rhs_operand" "rM")])))
10415    (clobber (reg:CC CC_REGNUM))]
10416   "TARGET_ARM"
10417   "#"
10418   [(set_attr "conds" "clob")
10419    (set_attr "length" "12")
10420    (set_attr "type" "multiple")]
10423 (define_insn "*if_shift_shift"
10424   [(set (match_operand:SI 0 "s_register_operand" "=r")
10425         (if_then_else:SI
10426          (match_operator 5 "arm_comparison_operator"
10427           [(match_operand 8 "cc_register" "") (const_int 0)])
10428          (match_operator:SI 6 "shift_operator"
10429           [(match_operand:SI 1 "s_register_operand" "r")
10430            (match_operand:SI 2 "arm_rhs_operand" "rM")])
10431          (match_operator:SI 7 "shift_operator"
10432           [(match_operand:SI 3 "s_register_operand" "r")
10433            (match_operand:SI 4 "arm_rhs_operand" "rM")])))]
10434   "TARGET_ARM"
10435   "mov%d5\\t%0, %1%S6\;mov%D5\\t%0, %3%S7"
10436   [(set_attr "conds" "use")
10437    (set_attr "shift" "1")
10438    (set_attr "length" "8")
10439    (set (attr "type") (if_then_else
10440                         (and (match_operand 2 "const_int_operand" "")
10441                              (match_operand 4 "const_int_operand" ""))
10442                       (const_string "mov_shift")
10443                       (const_string "mov_shift_reg")))]
10446 (define_insn "*ifcompare_not_arith"
10447   [(set (match_operand:SI 0 "s_register_operand" "=r")
10448         (if_then_else:SI
10449          (match_operator 6 "arm_comparison_operator"
10450           [(match_operand:SI 4 "s_register_operand" "r")
10451            (match_operand:SI 5 "arm_add_operand" "rIL")])
10452          (not:SI (match_operand:SI 1 "s_register_operand" "r"))
10453          (match_operator:SI 7 "shiftable_operator"
10454           [(match_operand:SI 2 "s_register_operand" "r")
10455            (match_operand:SI 3 "arm_rhs_operand" "rI")])))
10456    (clobber (reg:CC CC_REGNUM))]
10457   "TARGET_ARM"
10458   "#"
10459   [(set_attr "conds" "clob")
10460    (set_attr "length" "12")
10461    (set_attr "type" "multiple")]
10464 (define_insn "*if_not_arith"
10465   [(set (match_operand:SI 0 "s_register_operand" "=r")
10466         (if_then_else:SI
10467          (match_operator 5 "arm_comparison_operator"
10468           [(match_operand 4 "cc_register" "") (const_int 0)])
10469          (not:SI (match_operand:SI 1 "s_register_operand" "r"))
10470          (match_operator:SI 6 "shiftable_operator"
10471           [(match_operand:SI 2 "s_register_operand" "r")
10472            (match_operand:SI 3 "arm_rhs_operand" "rI")])))]
10473   "TARGET_ARM"
10474   "mvn%d5\\t%0, %1\;%I6%D5\\t%0, %2, %3"
10475   [(set_attr "conds" "use")
10476    (set_attr "type" "mvn_reg")
10477    (set_attr "length" "8")]
10480 (define_insn "*ifcompare_arith_not"
10481   [(set (match_operand:SI 0 "s_register_operand" "=r")
10482         (if_then_else:SI
10483          (match_operator 6 "arm_comparison_operator"
10484           [(match_operand:SI 4 "s_register_operand" "r")
10485            (match_operand:SI 5 "arm_add_operand" "rIL")])
10486          (match_operator:SI 7 "shiftable_operator"
10487           [(match_operand:SI 2 "s_register_operand" "r")
10488            (match_operand:SI 3 "arm_rhs_operand" "rI")])
10489          (not:SI (match_operand:SI 1 "s_register_operand" "r"))))
10490    (clobber (reg:CC CC_REGNUM))]
10491   "TARGET_ARM"
10492   "#"
10493   [(set_attr "conds" "clob")
10494    (set_attr "length" "12")
10495    (set_attr "type" "multiple")]
10498 (define_insn "*if_arith_not"
10499   [(set (match_operand:SI 0 "s_register_operand" "=r")
10500         (if_then_else:SI
10501          (match_operator 5 "arm_comparison_operator"
10502           [(match_operand 4 "cc_register" "") (const_int 0)])
10503          (match_operator:SI 6 "shiftable_operator"
10504           [(match_operand:SI 2 "s_register_operand" "r")
10505            (match_operand:SI 3 "arm_rhs_operand" "rI")])
10506          (not:SI (match_operand:SI 1 "s_register_operand" "r"))))]
10507   "TARGET_ARM"
10508   "mvn%D5\\t%0, %1\;%I6%d5\\t%0, %2, %3"
10509   [(set_attr "conds" "use")
10510    (set_attr "type" "multiple")
10511    (set_attr "length" "8")]
10514 (define_insn "*ifcompare_neg_move"
10515   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10516         (if_then_else:SI
10517          (match_operator 5 "arm_comparison_operator"
10518           [(match_operand:SI 3 "s_register_operand" "r,r")
10519            (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
10520          (neg:SI (match_operand:SI 2 "s_register_operand" "r,r"))
10521          (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
10522    (clobber (reg:CC CC_REGNUM))]
10523   "TARGET_ARM"
10524   "#"
10525   [(set_attr "conds" "clob")
10526    (set_attr "length" "8,12")
10527    (set_attr "type" "multiple")]
10530 (define_insn_and_split "*if_neg_move"
10531   [(set (match_operand:SI 0 "s_register_operand" "=l,r")
10532         (if_then_else:SI
10533          (match_operator 4 "arm_comparison_operator"
10534           [(match_operand 3 "cc_register" "") (const_int 0)])
10535          (neg:SI (match_operand:SI 2 "s_register_operand" "l,r"))
10536          (match_operand:SI 1 "s_register_operand" "0,0")))]
10537   "TARGET_32BIT"
10538   "#"
10539   "&& reload_completed"
10540   [(cond_exec (match_op_dup 4 [(match_dup 3) (const_int 0)])
10541               (set (match_dup 0) (neg:SI (match_dup 2))))]
10542   ""
10543   [(set_attr "conds" "use")
10544    (set_attr "length" "4")
10545    (set_attr "arch" "t2,32")
10546    (set_attr "enabled_for_depr_it" "yes,no")
10547    (set_attr "type" "logic_shift_imm")]
10550 (define_insn "*ifcompare_move_neg"
10551   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10552         (if_then_else:SI
10553          (match_operator 5 "arm_comparison_operator"
10554           [(match_operand:SI 3 "s_register_operand" "r,r")
10555            (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
10556          (match_operand:SI 1 "arm_not_operand" "0,?rIK")
10557          (neg:SI (match_operand:SI 2 "s_register_operand" "r,r"))))
10558    (clobber (reg:CC CC_REGNUM))]
10559   "TARGET_ARM"
10560   "#"
10561   [(set_attr "conds" "clob")
10562    (set_attr "length" "8,12")
10563    (set_attr "type" "multiple")]
10566 (define_insn_and_split "*if_move_neg"
10567   [(set (match_operand:SI 0 "s_register_operand" "=l,r")
10568         (if_then_else:SI
10569          (match_operator 4 "arm_comparison_operator"
10570           [(match_operand 3 "cc_register" "") (const_int 0)])
10571          (match_operand:SI 1 "s_register_operand" "0,0")
10572          (neg:SI (match_operand:SI 2 "s_register_operand" "l,r"))))]
10573   "TARGET_32BIT"
10574   "#"
10575   "&& reload_completed"
10576   [(cond_exec (match_dup 5)
10577               (set (match_dup 0) (neg:SI (match_dup 2))))]
10578   {
10579     machine_mode mode = GET_MODE (operands[3]);
10580     rtx_code rc = GET_CODE (operands[4]);
10582     if (mode == CCFPmode || mode == CCFPEmode)
10583       rc = reverse_condition_maybe_unordered (rc);
10584     else
10585       rc = reverse_condition (rc);
10587     operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[3], const0_rtx);
10588   }
10589   [(set_attr "conds" "use")
10590    (set_attr "length" "4")
10591    (set_attr "arch" "t2,32")
10592    (set_attr "enabled_for_depr_it" "yes,no")
10593    (set_attr "type" "logic_shift_imm")]
10596 (define_insn "*arith_adjacentmem"
10597   [(set (match_operand:SI 0 "s_register_operand" "=r")
10598         (match_operator:SI 1 "shiftable_operator"
10599          [(match_operand:SI 2 "memory_operand" "m")
10600           (match_operand:SI 3 "memory_operand" "m")]))
10601    (clobber (match_scratch:SI 4 "=r"))]
10602   "TARGET_ARM && adjacent_mem_locations (operands[2], operands[3])"
10603   "*
10604   {
10605     rtx ldm[3];
10606     rtx arith[4];
10607     rtx base_reg;
10608     HOST_WIDE_INT val1 = 0, val2 = 0;
10610     if (REGNO (operands[0]) > REGNO (operands[4]))
10611       {
10612         ldm[1] = operands[4];
10613         ldm[2] = operands[0];
10614       }
10615     else
10616       {
10617         ldm[1] = operands[0];
10618         ldm[2] = operands[4];
10619       }
10621     base_reg = XEXP (operands[2], 0);
10623     if (!REG_P (base_reg))
10624       {
10625         val1 = INTVAL (XEXP (base_reg, 1));
10626         base_reg = XEXP (base_reg, 0);
10627       }
10629     if (!REG_P (XEXP (operands[3], 0)))
10630       val2 = INTVAL (XEXP (XEXP (operands[3], 0), 1));
10632     arith[0] = operands[0];
10633     arith[3] = operands[1];
10635     if (val1 < val2)
10636       {
10637         arith[1] = ldm[1];
10638         arith[2] = ldm[2];
10639       }
10640     else
10641       {
10642         arith[1] = ldm[2];
10643         arith[2] = ldm[1];
10644       }
10646     ldm[0] = base_reg;
10647     if (val1 !=0 && val2 != 0)
10648       {
10649         rtx ops[3];
10651         if (val1 == 4 || val2 == 4)
10652           /* Other val must be 8, since we know they are adjacent and neither
10653              is zero.  */
10654           output_asm_insn (\"ldmib%?\\t%0, {%1, %2}\", ldm);
10655         else if (const_ok_for_arm (val1) || const_ok_for_arm (-val1))
10656           {
10657             ldm[0] = ops[0] = operands[4];
10658             ops[1] = base_reg;
10659             ops[2] = GEN_INT (val1);
10660             output_add_immediate (ops);
10661             if (val1 < val2)
10662               output_asm_insn (\"ldmia%?\\t%0, {%1, %2}\", ldm);
10663             else
10664               output_asm_insn (\"ldmda%?\\t%0, {%1, %2}\", ldm);
10665           }
10666         else
10667           {
10668             /* Offset is out of range for a single add, so use two ldr.  */
10669             ops[0] = ldm[1];
10670             ops[1] = base_reg;
10671             ops[2] = GEN_INT (val1);
10672             output_asm_insn (\"ldr%?\\t%0, [%1, %2]\", ops);
10673             ops[0] = ldm[2];
10674             ops[2] = GEN_INT (val2);
10675             output_asm_insn (\"ldr%?\\t%0, [%1, %2]\", ops);
10676           }
10677       }
10678     else if (val1 != 0)
10679       {
10680         if (val1 < val2)
10681           output_asm_insn (\"ldmda%?\\t%0, {%1, %2}\", ldm);
10682         else
10683           output_asm_insn (\"ldmia%?\\t%0, {%1, %2}\", ldm);
10684       }
10685     else
10686       {
10687         if (val1 < val2)
10688           output_asm_insn (\"ldmia%?\\t%0, {%1, %2}\", ldm);
10689         else
10690           output_asm_insn (\"ldmda%?\\t%0, {%1, %2}\", ldm);
10691       }
10692     output_asm_insn (\"%I3%?\\t%0, %1, %2\", arith);
10693     return \"\";
10694   }"
10695   [(set_attr "length" "12")
10696    (set_attr "predicable" "yes")
10697    (set_attr "type" "load_4")]
10700 ; This pattern is never tried by combine, so do it as a peephole
10702 (define_peephole2
10703   [(set (match_operand:SI 0 "arm_general_register_operand" "")
10704         (match_operand:SI 1 "arm_general_register_operand" ""))
10705    (set (reg:CC CC_REGNUM)
10706         (compare:CC (match_dup 1) (const_int 0)))]
10707   "TARGET_ARM"
10708   [(parallel [(set (reg:CC CC_REGNUM) (compare:CC (match_dup 1) (const_int 0)))
10709               (set (match_dup 0) (match_dup 1))])]
10710   ""
10713 (define_split
10714   [(set (match_operand:SI 0 "s_register_operand" "")
10715         (and:SI (ge:SI (match_operand:SI 1 "s_register_operand" "")
10716                        (const_int 0))
10717                 (neg:SI (match_operator:SI 2 "arm_comparison_operator"
10718                          [(match_operand:SI 3 "s_register_operand" "")
10719                           (match_operand:SI 4 "arm_rhs_operand" "")]))))
10720    (clobber (match_operand:SI 5 "s_register_operand" ""))]
10721   "TARGET_ARM"
10722   [(set (match_dup 5) (not:SI (ashiftrt:SI (match_dup 1) (const_int 31))))
10723    (set (match_dup 0) (and:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
10724                               (match_dup 5)))]
10725   ""
10728 ;; This split can be used because CC_Z mode implies that the following
10729 ;; branch will be an equality, or an unsigned inequality, so the sign
10730 ;; extension is not needed.
10732 (define_split
10733   [(set (reg:CC_Z CC_REGNUM)
10734         (compare:CC_Z
10735          (ashift:SI (subreg:SI (match_operand:QI 0 "memory_operand" "") 0)
10736                     (const_int 24))
10737          (match_operand 1 "const_int_operand" "")))
10738    (clobber (match_scratch:SI 2 ""))]
10739   "TARGET_ARM
10740    && ((UINTVAL (operands[1]))
10741        == ((UINTVAL (operands[1])) >> 24) << 24)"
10742   [(set (match_dup 2) (zero_extend:SI (match_dup 0)))
10743    (set (reg:CC CC_REGNUM) (compare:CC (match_dup 2) (match_dup 1)))]
10744   "
10745   operands[1] = GEN_INT (((unsigned long) INTVAL (operands[1])) >> 24);
10746   "
10748 ;; ??? Check the patterns above for Thumb-2 usefulness
10750 (define_expand "prologue"
10751   [(clobber (const_int 0))]
10752   "TARGET_EITHER"
10753   "if (TARGET_32BIT)
10754      arm_expand_prologue ();
10755    else
10756      thumb1_expand_prologue ();
10757   DONE;
10758   "
10761 (define_expand "epilogue"
10762   [(clobber (const_int 0))]
10763   "TARGET_EITHER"
10764   "
10765   if (crtl->calls_eh_return)
10766     emit_insn (gen_force_register_use (gen_rtx_REG (Pmode, 2)));
10767   if (TARGET_THUMB1)
10768    {
10769      thumb1_expand_epilogue ();
10770      emit_jump_insn (gen_rtx_UNSPEC_VOLATILE (VOIDmode,
10771                      gen_rtvec (1, ret_rtx), VUNSPEC_EPILOGUE));
10772    }
10773   else if (HAVE_return)
10774    {
10775      /* HAVE_return is testing for USE_RETURN_INSN (FALSE).  Hence,
10776         no need for explicit testing again.  */
10777      emit_jump_insn (gen_return ());
10778    }
10779   else if (TARGET_32BIT)
10780    {
10781     arm_expand_epilogue (true);
10782    }
10783   DONE;
10784   "
10787 ;; Note - although unspec_volatile's USE all hard registers,
10788 ;; USEs are ignored after relaod has completed.  Thus we need
10789 ;; to add an unspec of the link register to ensure that flow
10790 ;; does not think that it is unused by the sibcall branch that
10791 ;; will replace the standard function epilogue.
10792 (define_expand "sibcall_epilogue"
10793    [(parallel [(unspec:SI [(reg:SI LR_REGNUM)] UNSPEC_REGISTER_USE)
10794                (unspec_volatile [(return)] VUNSPEC_EPILOGUE)])]
10795    "TARGET_32BIT"
10796    "
10797    arm_expand_epilogue (false);
10798    DONE;
10799    "
10802 (define_expand "eh_epilogue"
10803   [(use (match_operand:SI 0 "register_operand" ""))
10804    (use (match_operand:SI 1 "register_operand" ""))
10805    (use (match_operand:SI 2 "register_operand" ""))]
10806   "TARGET_EITHER"
10807   "
10808   {
10809     cfun->machine->eh_epilogue_sp_ofs = operands[1];
10810     if (!REG_P (operands[2]) || REGNO (operands[2]) != 2)
10811       {
10812         rtx ra = gen_rtx_REG (Pmode, 2);
10814         emit_move_insn (ra, operands[2]);
10815         operands[2] = ra;
10816       }
10817     /* This is a hack -- we may have crystalized the function type too
10818        early.  */
10819     cfun->machine->func_type = 0;
10820   }"
10823 ;; This split is only used during output to reduce the number of patterns
10824 ;; that need assembler instructions adding to them.  We allowed the setting
10825 ;; of the conditions to be implicit during rtl generation so that
10826 ;; the conditional compare patterns would work.  However this conflicts to
10827 ;; some extent with the conditional data operations, so we have to split them
10828 ;; up again here.
10830 ;; ??? Need to audit these splitters for Thumb-2.  Why isn't normal
10831 ;; conditional execution sufficient?
10833 (define_split
10834   [(set (match_operand:SI 0 "s_register_operand" "")
10835         (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10836                           [(match_operand 2 "" "") (match_operand 3 "" "")])
10837                          (match_dup 0)
10838                          (match_operand 4 "" "")))
10839    (clobber (reg:CC CC_REGNUM))]
10840   "TARGET_ARM && reload_completed"
10841   [(set (match_dup 5) (match_dup 6))
10842    (cond_exec (match_dup 7)
10843               (set (match_dup 0) (match_dup 4)))]
10844   "
10845   {
10846     machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10847                                              operands[2], operands[3]);
10848     enum rtx_code rc = GET_CODE (operands[1]);
10850     operands[5] = gen_rtx_REG (mode, CC_REGNUM);
10851     operands[6] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10852     if (mode == CCFPmode || mode == CCFPEmode)
10853       rc = reverse_condition_maybe_unordered (rc);
10854     else
10855       rc = reverse_condition (rc);
10857     operands[7] = gen_rtx_fmt_ee (rc, VOIDmode, operands[5], const0_rtx);
10858   }"
10861 (define_split
10862   [(set (match_operand:SI 0 "s_register_operand" "")
10863         (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10864                           [(match_operand 2 "" "") (match_operand 3 "" "")])
10865                          (match_operand 4 "" "")
10866                          (match_dup 0)))
10867    (clobber (reg:CC CC_REGNUM))]
10868   "TARGET_ARM && reload_completed"
10869   [(set (match_dup 5) (match_dup 6))
10870    (cond_exec (match_op_dup 1 [(match_dup 5) (const_int 0)])
10871               (set (match_dup 0) (match_dup 4)))]
10872   "
10873   {
10874     machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10875                                              operands[2], operands[3]);
10877     operands[5] = gen_rtx_REG (mode, CC_REGNUM);
10878     operands[6] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10879   }"
10882 (define_split
10883   [(set (match_operand:SI 0 "s_register_operand" "")
10884         (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10885                           [(match_operand 2 "" "") (match_operand 3 "" "")])
10886                          (match_operand 4 "" "")
10887                          (match_operand 5 "" "")))
10888    (clobber (reg:CC CC_REGNUM))]
10889   "TARGET_ARM && reload_completed"
10890   [(set (match_dup 6) (match_dup 7))
10891    (cond_exec (match_op_dup 1 [(match_dup 6) (const_int 0)])
10892               (set (match_dup 0) (match_dup 4)))
10893    (cond_exec (match_dup 8)
10894               (set (match_dup 0) (match_dup 5)))]
10895   "
10896   {
10897     machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10898                                              operands[2], operands[3]);
10899     enum rtx_code rc = GET_CODE (operands[1]);
10901     operands[6] = gen_rtx_REG (mode, CC_REGNUM);
10902     operands[7] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10903     if (mode == CCFPmode || mode == CCFPEmode)
10904       rc = reverse_condition_maybe_unordered (rc);
10905     else
10906       rc = reverse_condition (rc);
10908     operands[8] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
10909   }"
10912 (define_split
10913   [(set (match_operand:SI 0 "s_register_operand" "")
10914         (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10915                           [(match_operand:SI 2 "s_register_operand" "")
10916                            (match_operand:SI 3 "arm_add_operand" "")])
10917                          (match_operand:SI 4 "arm_rhs_operand" "")
10918                          (not:SI
10919                           (match_operand:SI 5 "s_register_operand" ""))))
10920    (clobber (reg:CC CC_REGNUM))]
10921   "TARGET_ARM && reload_completed"
10922   [(set (match_dup 6) (match_dup 7))
10923    (cond_exec (match_op_dup 1 [(match_dup 6) (const_int 0)])
10924               (set (match_dup 0) (match_dup 4)))
10925    (cond_exec (match_dup 8)
10926               (set (match_dup 0) (not:SI (match_dup 5))))]
10927   "
10928   {
10929     machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10930                                              operands[2], operands[3]);
10931     enum rtx_code rc = GET_CODE (operands[1]);
10933     operands[6] = gen_rtx_REG (mode, CC_REGNUM);
10934     operands[7] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10935     if (mode == CCFPmode || mode == CCFPEmode)
10936       rc = reverse_condition_maybe_unordered (rc);
10937     else
10938       rc = reverse_condition (rc);
10940     operands[8] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
10941   }"
10944 (define_insn "*cond_move_not"
10945   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10946         (if_then_else:SI (match_operator 4 "arm_comparison_operator"
10947                           [(match_operand 3 "cc_register" "") (const_int 0)])
10948                          (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
10949                          (not:SI
10950                           (match_operand:SI 2 "s_register_operand" "r,r"))))]
10951   "TARGET_ARM"
10952   "@
10953    mvn%D4\\t%0, %2
10954    mov%d4\\t%0, %1\;mvn%D4\\t%0, %2"
10955   [(set_attr "conds" "use")
10956    (set_attr "type" "mvn_reg,multiple")
10957    (set_attr "length" "4,8")]
10960 ;; The next two patterns occur when an AND operation is followed by a
10961 ;; scc insn sequence 
10963 (define_insn "*sign_extract_onebit"
10964   [(set (match_operand:SI 0 "s_register_operand" "=r")
10965         (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
10966                          (const_int 1)
10967                          (match_operand:SI 2 "const_int_operand" "n")))
10968     (clobber (reg:CC CC_REGNUM))]
10969   "TARGET_ARM"
10970   "*
10971     operands[2] = GEN_INT (1 << INTVAL (operands[2]));
10972     output_asm_insn (\"ands\\t%0, %1, %2\", operands);
10973     return \"mvnne\\t%0, #0\";
10974   "
10975   [(set_attr "conds" "clob")
10976    (set_attr "length" "8")
10977    (set_attr "type" "multiple")]
10980 (define_insn "*not_signextract_onebit"
10981   [(set (match_operand:SI 0 "s_register_operand" "=r")
10982         (not:SI
10983          (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
10984                           (const_int 1)
10985                           (match_operand:SI 2 "const_int_operand" "n"))))
10986    (clobber (reg:CC CC_REGNUM))]
10987   "TARGET_ARM"
10988   "*
10989     operands[2] = GEN_INT (1 << INTVAL (operands[2]));
10990     output_asm_insn (\"tst\\t%1, %2\", operands);
10991     output_asm_insn (\"mvneq\\t%0, #0\", operands);
10992     return \"movne\\t%0, #0\";
10993   "
10994   [(set_attr "conds" "clob")
10995    (set_attr "length" "12")
10996    (set_attr "type" "multiple")]
10998 ;; ??? The above patterns need auditing for Thumb-2
11000 ;; Push multiple registers to the stack.  Registers are in parallel (use ...)
11001 ;; expressions.  For simplicity, the first register is also in the unspec
11002 ;; part.
11003 ;; To avoid the usage of GNU extension, the length attribute is computed
11004 ;; in a C function arm_attr_length_push_multi.
11005 (define_insn "*push_multi"
11006   [(match_parallel 2 "multi_register_push"
11007     [(set (match_operand:BLK 0 "push_mult_memory_operand" "")
11008           (unspec:BLK [(match_operand:SI 1 "s_register_operand" "")]
11009                       UNSPEC_PUSH_MULT))])]
11010   ""
11011   "*
11012   {
11013     int num_saves = XVECLEN (operands[2], 0);
11014      
11015     /* For the StrongARM at least it is faster to
11016        use STR to store only a single register.
11017        In Thumb mode always use push, and the assembler will pick
11018        something appropriate.  */
11019     if (num_saves == 1 && TARGET_ARM)
11020       output_asm_insn (\"str%?\\t%1, [%m0, #-4]!\", operands);
11021     else
11022       {
11023         int i;
11024         char pattern[100];
11026         if (TARGET_32BIT)
11027             strcpy (pattern, \"push%?\\t{%1\");
11028         else
11029             strcpy (pattern, \"push\\t{%1\");
11031         for (i = 1; i < num_saves; i++)
11032           {
11033             strcat (pattern, \", %|\");
11034             strcat (pattern,
11035                     reg_names[REGNO (XEXP (XVECEXP (operands[2], 0, i), 0))]);
11036           }
11038         strcat (pattern, \"}\");
11039         output_asm_insn (pattern, operands);
11040       }
11042     return \"\";
11043   }"
11044   [(set_attr "type" "store_16")
11045    (set (attr "length")
11046         (symbol_ref "arm_attr_length_push_multi (operands[2], operands[1])"))]
11049 (define_insn "stack_tie"
11050   [(set (mem:BLK (scratch))
11051         (unspec:BLK [(match_operand:SI 0 "s_register_operand" "rk")
11052                      (match_operand:SI 1 "s_register_operand" "rk")]
11053                     UNSPEC_PRLG_STK))]
11054   ""
11055   ""
11056   [(set_attr "length" "0")
11057    (set_attr "type" "block")]
11060 ;; Pop (as used in epilogue RTL)
11062 (define_insn "*load_multiple_with_writeback"
11063   [(match_parallel 0 "load_multiple_operation"
11064     [(set (match_operand:SI 1 "s_register_operand" "+rk")
11065           (plus:SI (match_dup 1)
11066                    (match_operand:SI 2 "const_int_I_operand" "I")))
11067      (set (match_operand:SI 3 "s_register_operand" "=rk")
11068           (mem:SI (match_dup 1)))
11069         ])]
11070   "TARGET_32BIT && (reload_in_progress || reload_completed)"
11071   "*
11072   {
11073     arm_output_multireg_pop (operands, /*return_pc=*/false,
11074                                        /*cond=*/const_true_rtx,
11075                                        /*reverse=*/false,
11076                                        /*update=*/true);
11077     return \"\";
11078   }
11079   "
11080   [(set_attr "type" "load_16")
11081    (set_attr "predicable" "yes")
11082    (set (attr "length")
11083         (symbol_ref "arm_attr_length_pop_multi (operands,
11084                                                 /*return_pc=*/false,
11085                                                 /*write_back_p=*/true)"))]
11088 ;; Pop with return (as used in epilogue RTL)
11090 ;; This instruction is generated when the registers are popped at the end of
11091 ;; epilogue.  Here, instead of popping the value into LR and then generating
11092 ;; jump to LR, value is popped into PC directly.  Hence, the pattern is combined
11093 ;;  with (return).
11094 (define_insn "*pop_multiple_with_writeback_and_return"
11095   [(match_parallel 0 "pop_multiple_return"
11096     [(return)
11097      (set (match_operand:SI 1 "s_register_operand" "+rk")
11098           (plus:SI (match_dup 1)
11099                    (match_operand:SI 2 "const_int_I_operand" "I")))
11100      (set (match_operand:SI 3 "s_register_operand" "=rk")
11101           (mem:SI (match_dup 1)))
11102         ])]
11103   "TARGET_32BIT && (reload_in_progress || reload_completed)"
11104   "*
11105   {
11106     arm_output_multireg_pop (operands, /*return_pc=*/true,
11107                                        /*cond=*/const_true_rtx,
11108                                        /*reverse=*/false,
11109                                        /*update=*/true);
11110     return \"\";
11111   }
11112   "
11113   [(set_attr "type" "load_16")
11114    (set_attr "predicable" "yes")
11115    (set (attr "length")
11116         (symbol_ref "arm_attr_length_pop_multi (operands, /*return_pc=*/true,
11117                                                 /*write_back_p=*/true)"))]
11120 (define_insn "*pop_multiple_with_return"
11121   [(match_parallel 0 "pop_multiple_return"
11122     [(return)
11123      (set (match_operand:SI 2 "s_register_operand" "=rk")
11124           (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
11125         ])]
11126   "TARGET_32BIT && (reload_in_progress || reload_completed)"
11127   "*
11128   {
11129     arm_output_multireg_pop (operands, /*return_pc=*/true,
11130                                        /*cond=*/const_true_rtx,
11131                                        /*reverse=*/false,
11132                                        /*update=*/false);
11133     return \"\";
11134   }
11135   "
11136   [(set_attr "type" "load_16")
11137    (set_attr "predicable" "yes")
11138    (set (attr "length")
11139         (symbol_ref "arm_attr_length_pop_multi (operands, /*return_pc=*/true,
11140                                                 /*write_back_p=*/false)"))]
11143 ;; Load into PC and return
11144 (define_insn "*ldr_with_return"
11145   [(return)
11146    (set (reg:SI PC_REGNUM)
11147         (mem:SI (post_inc:SI (match_operand:SI 0 "s_register_operand" "+rk"))))]
11148   "TARGET_32BIT && (reload_in_progress || reload_completed)"
11149   "ldr%?\t%|pc, [%0], #4"
11150   [(set_attr "type" "load_4")
11151    (set_attr "predicable" "yes")]
11153 ;; Pop for floating point registers (as used in epilogue RTL)
11154 (define_insn "*vfp_pop_multiple_with_writeback"
11155   [(match_parallel 0 "pop_multiple_fp"
11156     [(set (match_operand:SI 1 "s_register_operand" "+rk")
11157           (plus:SI (match_dup 1)
11158                    (match_operand:SI 2 "const_int_I_operand" "I")))
11159      (set (match_operand:DF 3 "vfp_hard_register_operand" "")
11160           (mem:DF (match_dup 1)))])]
11161   "TARGET_32BIT && TARGET_HARD_FLOAT"
11162   "*
11163   {
11164     int num_regs = XVECLEN (operands[0], 0);
11165     char pattern[100];
11166     rtx op_list[2];
11167     strcpy (pattern, \"vldm\\t\");
11168     strcat (pattern, reg_names[REGNO (SET_DEST (XVECEXP (operands[0], 0, 0)))]);
11169     strcat (pattern, \"!, {\");
11170     op_list[0] = XEXP (XVECEXP (operands[0], 0, 1), 0);
11171     strcat (pattern, \"%P0\");
11172     if ((num_regs - 1) > 1)
11173       {
11174         strcat (pattern, \"-%P1\");
11175         op_list [1] = XEXP (XVECEXP (operands[0], 0, num_regs - 1), 0);
11176       }
11178     strcat (pattern, \"}\");
11179     output_asm_insn (pattern, op_list);
11180     return \"\";
11181   }
11182   "
11183   [(set_attr "type" "load_16")
11184    (set_attr "conds" "unconditional")
11185    (set_attr "predicable" "no")]
11188 ;; Special patterns for dealing with the constant pool
11190 (define_insn "align_4"
11191   [(unspec_volatile [(const_int 0)] VUNSPEC_ALIGN)]
11192   "TARGET_EITHER"
11193   "*
11194   assemble_align (32);
11195   return \"\";
11196   "
11197   [(set_attr "type" "no_insn")]
11200 (define_insn "align_8"
11201   [(unspec_volatile [(const_int 0)] VUNSPEC_ALIGN8)]
11202   "TARGET_EITHER"
11203   "*
11204   assemble_align (64);
11205   return \"\";
11206   "
11207   [(set_attr "type" "no_insn")]
11210 (define_insn "consttable_end"
11211   [(unspec_volatile [(const_int 0)] VUNSPEC_POOL_END)]
11212   "TARGET_EITHER"
11213   "*
11214   making_const_table = FALSE;
11215   return \"\";
11216   "
11217   [(set_attr "type" "no_insn")]
11220 (define_insn "consttable_1"
11221   [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_1)]
11222   "TARGET_EITHER"
11223   "*
11224   making_const_table = TRUE;
11225   assemble_integer (operands[0], 1, BITS_PER_WORD, 1);
11226   assemble_zeros (3);
11227   return \"\";
11228   "
11229   [(set_attr "length" "4")
11230    (set_attr "type" "no_insn")]
11233 (define_insn "consttable_2"
11234   [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_2)]
11235   "TARGET_EITHER"
11236   "*
11237   {
11238     rtx x = operands[0];
11239     making_const_table = TRUE;
11240     switch (GET_MODE_CLASS (GET_MODE (x)))
11241       {
11242       case MODE_FLOAT:
11243         arm_emit_fp16_const (x);
11244         break;
11245       default:
11246         assemble_integer (operands[0], 2, BITS_PER_WORD, 1);
11247         assemble_zeros (2);
11248         break;
11249       }
11250     return \"\";
11251   }"
11252   [(set_attr "length" "4")
11253    (set_attr "type" "no_insn")]
11256 (define_insn "consttable_4"
11257   [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_4)]
11258   "TARGET_EITHER"
11259   "*
11260   {
11261     rtx x = operands[0];
11262     making_const_table = TRUE;
11263     scalar_float_mode float_mode;
11264     if (is_a <scalar_float_mode> (GET_MODE (x), &float_mode))
11265       assemble_real (*CONST_DOUBLE_REAL_VALUE (x), float_mode, BITS_PER_WORD);
11266     else
11267       {
11268         /* XXX: Sometimes gcc does something really dumb and ends up with
11269            a HIGH in a constant pool entry, usually because it's trying to
11270            load into a VFP register.  We know this will always be used in
11271            combination with a LO_SUM which ignores the high bits, so just
11272            strip off the HIGH.  */
11273         if (GET_CODE (x) == HIGH)
11274           x = XEXP (x, 0);
11275         assemble_integer (x, 4, BITS_PER_WORD, 1);
11276         mark_symbol_refs_as_used (x);
11277       }
11278     return \"\";
11279   }"
11280   [(set_attr "length" "4")
11281    (set_attr "type" "no_insn")]
11284 (define_insn "consttable_8"
11285   [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_8)]
11286   "TARGET_EITHER"
11287   "*
11288   {
11289     making_const_table = TRUE;
11290     scalar_float_mode float_mode;
11291     if (is_a <scalar_float_mode> (GET_MODE (operands[0]), &float_mode))
11292       assemble_real (*CONST_DOUBLE_REAL_VALUE (operands[0]),
11293                      float_mode, BITS_PER_WORD);
11294     else
11295       assemble_integer (operands[0], 8, BITS_PER_WORD, 1);
11296     return \"\";
11297   }"
11298   [(set_attr "length" "8")
11299    (set_attr "type" "no_insn")]
11302 (define_insn "consttable_16"
11303   [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_16)]
11304   "TARGET_EITHER"
11305   "*
11306   {
11307     making_const_table = TRUE;
11308     scalar_float_mode float_mode;
11309     if (is_a <scalar_float_mode> (GET_MODE (operands[0]), &float_mode))
11310       assemble_real (*CONST_DOUBLE_REAL_VALUE (operands[0]),
11311                      float_mode, BITS_PER_WORD);
11312     else
11313       assemble_integer (operands[0], 16, BITS_PER_WORD, 1);
11314     return \"\";
11315   }"
11316   [(set_attr "length" "16")
11317    (set_attr "type" "no_insn")]
11320 ;; V5 Instructions,
11322 (define_insn "clzsi2"
11323   [(set (match_operand:SI 0 "s_register_operand" "=r")
11324         (clz:SI (match_operand:SI 1 "s_register_operand" "r")))]
11325   "TARGET_32BIT && arm_arch5"
11326   "clz%?\\t%0, %1"
11327   [(set_attr "predicable" "yes")
11328    (set_attr "predicable_short_it" "no")
11329    (set_attr "type" "clz")])
11331 (define_insn "rbitsi2"
11332   [(set (match_operand:SI 0 "s_register_operand" "=r")
11333         (unspec:SI [(match_operand:SI 1 "s_register_operand" "r")] UNSPEC_RBIT))]
11334   "TARGET_32BIT && arm_arch_thumb2"
11335   "rbit%?\\t%0, %1"
11336   [(set_attr "predicable" "yes")
11337    (set_attr "predicable_short_it" "no")
11338    (set_attr "type" "clz")])
11340 ;; Keep this as a CTZ expression until after reload and then split
11341 ;; into RBIT + CLZ.  Since RBIT is represented as an UNSPEC it is unlikely
11342 ;; to fold with any other expression.
11344 (define_insn_and_split "ctzsi2"
11345  [(set (match_operand:SI           0 "s_register_operand" "=r")
11346        (ctz:SI (match_operand:SI  1 "s_register_operand" "r")))]
11347   "TARGET_32BIT && arm_arch_thumb2"
11348   "#"
11349   "&& reload_completed"
11350   [(const_int 0)]
11351   "
11352   emit_insn (gen_rbitsi2 (operands[0], operands[1]));
11353   emit_insn (gen_clzsi2 (operands[0], operands[0]));
11354   DONE;
11357 ;; V5E instructions.
11359 (define_insn "prefetch"
11360   [(prefetch (match_operand:SI 0 "address_operand" "p")
11361              (match_operand:SI 1 "" "")
11362              (match_operand:SI 2 "" ""))]
11363   "TARGET_32BIT && arm_arch5e"
11364   "pld\\t%a0"
11365   [(set_attr "type" "load_4")]
11368 ;; General predication pattern
11370 (define_cond_exec
11371   [(match_operator 0 "arm_comparison_operator"
11372     [(match_operand 1 "cc_register" "")
11373      (const_int 0)])]
11374   "TARGET_32BIT
11375    && (!TARGET_NO_VOLATILE_CE || !volatile_refs_p (PATTERN (insn)))"
11376   ""
11377 [(set_attr "predicated" "yes")]
11380 (define_insn "force_register_use"
11381   [(unspec:SI [(match_operand:SI 0 "register_operand" "")] UNSPEC_REGISTER_USE)]
11382   ""
11383   "%@ %0 needed"
11384   [(set_attr "length" "0")
11385    (set_attr "type" "no_insn")]
11389 ;; Patterns for exception handling
11391 (define_expand "eh_return"
11392   [(use (match_operand 0 "general_operand" ""))]
11393   "TARGET_EITHER"
11394   "
11395   {
11396     if (TARGET_32BIT)
11397       emit_insn (gen_arm_eh_return (operands[0]));
11398     else
11399       emit_insn (gen_thumb_eh_return (operands[0]));
11400     DONE;
11401   }"
11403                                    
11404 ;; We can't expand this before we know where the link register is stored.
11405 (define_insn_and_split "arm_eh_return"
11406   [(unspec_volatile [(match_operand:SI 0 "s_register_operand" "r")]
11407                     VUNSPEC_EH_RETURN)
11408    (clobber (match_scratch:SI 1 "=&r"))]
11409   "TARGET_ARM"
11410   "#"
11411   "&& reload_completed"
11412   [(const_int 0)]
11413   "
11414   {
11415     arm_set_return_address (operands[0], operands[1]);
11416     DONE;
11417   }"
11421 ;; TLS support
11423 (define_insn "load_tp_hard"
11424   [(set (match_operand:SI 0 "register_operand" "=r")
11425         (unspec:SI [(const_int 0)] UNSPEC_TLS))]
11426   "TARGET_HARD_TP"
11427   "mrc%?\\tp15, 0, %0, c13, c0, 3\\t@ load_tp_hard"
11428   [(set_attr "predicable" "yes")
11429    (set_attr "type" "mrs")]
11432 ;; Doesn't clobber R1-R3.  Must use r0 for the first operand.
11433 (define_insn "load_tp_soft"
11434   [(set (reg:SI 0) (unspec:SI [(const_int 0)] UNSPEC_TLS))
11435    (clobber (reg:SI LR_REGNUM))
11436    (clobber (reg:SI IP_REGNUM))
11437    (clobber (reg:CC CC_REGNUM))]
11438   "TARGET_SOFT_TP"
11439   "bl\\t__aeabi_read_tp\\t@ load_tp_soft"
11440   [(set_attr "conds" "clob")
11441    (set_attr "type" "branch")]
11444 ;; tls descriptor call
11445 (define_insn "tlscall"
11446   [(set (reg:SI R0_REGNUM)
11447         (unspec:SI [(reg:SI R0_REGNUM)
11448                     (match_operand:SI 0 "" "X")
11449                     (match_operand 1 "" "")] UNSPEC_TLS))
11450    (clobber (reg:SI R1_REGNUM))
11451    (clobber (reg:SI LR_REGNUM))
11452    (clobber (reg:SI CC_REGNUM))]
11453   "TARGET_GNU2_TLS"
11454   {
11455     targetm.asm_out.internal_label (asm_out_file, "LPIC",
11456                                     INTVAL (operands[1]));
11457     return "bl\\t%c0(tlscall)";
11458   }
11459   [(set_attr "conds" "clob")
11460    (set_attr "length" "4")
11461    (set_attr "type" "branch")]
11464 ;; For thread pointer builtin
11465 (define_expand "get_thread_pointersi"
11466   [(match_operand:SI 0 "s_register_operand" "=r")]
11467  ""
11470    arm_load_tp (operands[0]);
11471    DONE;
11472  }")
11476 ;; We only care about the lower 16 bits of the constant 
11477 ;; being inserted into the upper 16 bits of the register.
11478 (define_insn "*arm_movtas_ze" 
11479   [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r,r")
11480                    (const_int 16)
11481                    (const_int 16))
11482         (match_operand:SI 1 "const_int_operand" ""))]
11483   "TARGET_HAVE_MOVT"
11484   "@
11485    movt%?\t%0, %L1
11486    movt\t%0, %L1"
11487  [(set_attr "arch" "32,v8mb")
11488   (set_attr "predicable" "yes")
11489   (set_attr "predicable_short_it" "no")
11490   (set_attr "length" "4")
11491   (set_attr "type" "alu_sreg")]
11494 (define_insn "*arm_rev"
11495   [(set (match_operand:SI 0 "s_register_operand" "=l,l,r")
11496         (bswap:SI (match_operand:SI 1 "s_register_operand" "l,l,r")))]
11497   "arm_arch6"
11498   "@
11499    rev\t%0, %1
11500    rev%?\t%0, %1
11501    rev%?\t%0, %1"
11502   [(set_attr "arch" "t1,t2,32")
11503    (set_attr "length" "2,2,4")
11504    (set_attr "predicable" "no,yes,yes")
11505    (set_attr "predicable_short_it" "no")
11506    (set_attr "type" "rev")]
11509 (define_expand "arm_legacy_rev"
11510   [(set (match_operand:SI 2 "s_register_operand" "")
11511         (xor:SI (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
11512                              (const_int 16))
11513                 (match_dup 1)))
11514    (set (match_dup 2)
11515         (lshiftrt:SI (match_dup 2)
11516                      (const_int 8)))
11517    (set (match_operand:SI 3 "s_register_operand" "")
11518         (rotatert:SI (match_dup 1)
11519                      (const_int 8)))
11520    (set (match_dup 2)
11521         (and:SI (match_dup 2)
11522                 (const_int -65281)))
11523    (set (match_operand:SI 0 "s_register_operand" "")
11524         (xor:SI (match_dup 3)
11525                 (match_dup 2)))]
11526   "TARGET_32BIT"
11527   ""
11530 ;; Reuse temporaries to keep register pressure down.
11531 (define_expand "thumb_legacy_rev"
11532   [(set (match_operand:SI 2 "s_register_operand" "")
11533      (ashift:SI (match_operand:SI 1 "s_register_operand" "")
11534                 (const_int 24)))
11535    (set (match_operand:SI 3 "s_register_operand" "")
11536      (lshiftrt:SI (match_dup 1)
11537                   (const_int 24)))
11538    (set (match_dup 3)
11539      (ior:SI (match_dup 3)
11540              (match_dup 2)))
11541    (set (match_operand:SI 4 "s_register_operand" "")
11542      (const_int 16))
11543    (set (match_operand:SI 5 "s_register_operand" "")
11544      (rotatert:SI (match_dup 1)
11545                   (match_dup 4)))
11546    (set (match_dup 2)
11547      (ashift:SI (match_dup 5)
11548                 (const_int 24)))
11549    (set (match_dup 5)
11550      (lshiftrt:SI (match_dup 5)
11551                   (const_int 24)))
11552    (set (match_dup 5)
11553      (ior:SI (match_dup 5)
11554              (match_dup 2)))
11555    (set (match_dup 5)
11556      (rotatert:SI (match_dup 5)
11557                   (match_dup 4)))
11558    (set (match_operand:SI 0 "s_register_operand" "")
11559      (ior:SI (match_dup 5)
11560              (match_dup 3)))]
11561   "TARGET_THUMB"
11562   ""
11565 ;; ARM-specific expansion of signed mod by power of 2
11566 ;; using conditional negate.
11567 ;; For r0 % n where n is a power of 2 produce:
11568 ;; rsbs    r1, r0, #0
11569 ;; and     r0, r0, #(n - 1)
11570 ;; and     r1, r1, #(n - 1)
11571 ;; rsbpl   r0, r1, #0
11573 (define_expand "modsi3"
11574   [(match_operand:SI 0 "register_operand" "")
11575    (match_operand:SI 1 "register_operand" "")
11576    (match_operand:SI 2 "const_int_operand" "")]
11577   "TARGET_32BIT"
11578   {
11579     HOST_WIDE_INT val = INTVAL (operands[2]);
11581     if (val <= 0
11582        || exact_log2 (val) <= 0)
11583       FAIL;
11585     rtx mask = GEN_INT (val - 1);
11587     /* In the special case of x0 % 2 we can do the even shorter:
11588         cmp     r0, #0
11589         and     r0, r0, #1
11590         rsblt   r0, r0, #0.  */
11592     if (val == 2)
11593       {
11594         rtx cc_reg = arm_gen_compare_reg (LT,
11595                                           operands[1], const0_rtx, NULL_RTX);
11596         rtx cond = gen_rtx_LT (SImode, cc_reg, const0_rtx);
11597         rtx masked = gen_reg_rtx (SImode);
11599         emit_insn (gen_andsi3 (masked, operands[1], mask));
11600         emit_move_insn (operands[0],
11601                         gen_rtx_IF_THEN_ELSE (SImode, cond,
11602                                               gen_rtx_NEG (SImode,
11603                                                            masked),
11604                                               masked));
11605         DONE;
11606       }
11608     rtx neg_op = gen_reg_rtx (SImode);
11609     rtx_insn *insn = emit_insn (gen_subsi3_compare0 (neg_op, const0_rtx,
11610                                                       operands[1]));
11612     /* Extract the condition register and mode.  */
11613     rtx cmp = XVECEXP (PATTERN (insn), 0, 0);
11614     rtx cc_reg = SET_DEST (cmp);
11615     rtx cond = gen_rtx_GE (SImode, cc_reg, const0_rtx);
11617     emit_insn (gen_andsi3 (operands[0], operands[1], mask));
11619     rtx masked_neg = gen_reg_rtx (SImode);
11620     emit_insn (gen_andsi3 (masked_neg, neg_op, mask));
11622     /* We want a conditional negate here, but emitting COND_EXEC rtxes
11623        during expand does not always work.  Do an IF_THEN_ELSE instead.  */
11624     emit_move_insn (operands[0],
11625                     gen_rtx_IF_THEN_ELSE (SImode, cond,
11626                                           gen_rtx_NEG (SImode, masked_neg),
11627                                           operands[0]));
11630     DONE;
11631   }
11634 (define_expand "bswapsi2"
11635   [(set (match_operand:SI 0 "s_register_operand" "=r")
11636         (bswap:SI (match_operand:SI 1 "s_register_operand" "r")))]
11637 "TARGET_EITHER && (arm_arch6 || !optimize_size)"
11639     if (!arm_arch6)
11640       {
11641         rtx op2 = gen_reg_rtx (SImode);
11642         rtx op3 = gen_reg_rtx (SImode);
11644         if (TARGET_THUMB)
11645           {
11646             rtx op4 = gen_reg_rtx (SImode);
11647             rtx op5 = gen_reg_rtx (SImode);
11649             emit_insn (gen_thumb_legacy_rev (operands[0], operands[1],
11650                                              op2, op3, op4, op5));
11651           }
11652         else
11653           {
11654             emit_insn (gen_arm_legacy_rev (operands[0], operands[1],
11655                                            op2, op3));
11656           }
11658         DONE;
11659       }
11660   "
11663 ;; bswap16 patterns: use revsh and rev16 instructions for the signed
11664 ;; and unsigned variants, respectively. For rev16, expose
11665 ;; byte-swapping in the lower 16 bits only.
11666 (define_insn "*arm_revsh"
11667   [(set (match_operand:SI 0 "s_register_operand" "=l,l,r")
11668         (sign_extend:SI (bswap:HI (match_operand:HI 1 "s_register_operand" "l,l,r"))))]
11669   "arm_arch6"
11670   "@
11671   revsh\t%0, %1
11672   revsh%?\t%0, %1
11673   revsh%?\t%0, %1"
11674   [(set_attr "arch" "t1,t2,32")
11675    (set_attr "length" "2,2,4")
11676    (set_attr "type" "rev")]
11679 (define_insn "*arm_rev16"
11680   [(set (match_operand:HI 0 "s_register_operand" "=l,l,r")
11681         (bswap:HI (match_operand:HI 1 "s_register_operand" "l,l,r")))]
11682   "arm_arch6"
11683   "@
11684    rev16\t%0, %1
11685    rev16%?\t%0, %1
11686    rev16%?\t%0, %1"
11687   [(set_attr "arch" "t1,t2,32")
11688    (set_attr "length" "2,2,4")
11689    (set_attr "type" "rev")]
11692 ;; There are no canonicalisation rules for the position of the lshiftrt, ashift
11693 ;; operations within an IOR/AND RTX, therefore we have two patterns matching
11694 ;; each valid permutation.
11696 (define_insn "arm_rev16si2"
11697   [(set (match_operand:SI 0 "register_operand" "=l,l,r")
11698         (ior:SI (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "l,l,r")
11699                                    (const_int 8))
11700                         (match_operand:SI 3 "const_int_operand" "n,n,n"))
11701                 (and:SI (lshiftrt:SI (match_dup 1)
11702                                      (const_int 8))
11703                         (match_operand:SI 2 "const_int_operand" "n,n,n"))))]
11704   "arm_arch6
11705    && aarch_rev16_shleft_mask_imm_p (operands[3], SImode)
11706    && aarch_rev16_shright_mask_imm_p (operands[2], SImode)"
11707   "rev16\\t%0, %1"
11708   [(set_attr "arch" "t1,t2,32")
11709    (set_attr "length" "2,2,4")
11710    (set_attr "type" "rev")]
11713 (define_insn "arm_rev16si2_alt"
11714   [(set (match_operand:SI 0 "register_operand" "=l,l,r")
11715         (ior:SI (and:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "l,l,r")
11716                                      (const_int 8))
11717                         (match_operand:SI 2 "const_int_operand" "n,n,n"))
11718                 (and:SI (ashift:SI (match_dup 1)
11719                                    (const_int 8))
11720                         (match_operand:SI 3 "const_int_operand" "n,n,n"))))]
11721   "arm_arch6
11722    && aarch_rev16_shleft_mask_imm_p (operands[3], SImode)
11723    && aarch_rev16_shright_mask_imm_p (operands[2], SImode)"
11724   "rev16\\t%0, %1"
11725   [(set_attr "arch" "t1,t2,32")
11726    (set_attr "length" "2,2,4")
11727    (set_attr "type" "rev")]
11730 (define_expand "bswaphi2"
11731   [(set (match_operand:HI 0 "s_register_operand" "=r")
11732         (bswap:HI (match_operand:HI 1 "s_register_operand" "r")))]
11733 "arm_arch6"
11737 ;; Patterns for LDRD/STRD in Thumb2 mode
11739 (define_insn "*thumb2_ldrd"
11740   [(set (match_operand:SI 0 "s_register_operand" "=r")
11741         (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "rk")
11742                          (match_operand:SI 2 "ldrd_strd_offset_operand" "Do"))))
11743    (set (match_operand:SI 3 "s_register_operand" "=r")
11744         (mem:SI (plus:SI (match_dup 1)
11745                          (match_operand:SI 4 "const_int_operand" ""))))]
11746   "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11747      && ((INTVAL (operands[2]) + 4) == INTVAL (operands[4]))
11748      && (operands_ok_ldrd_strd (operands[0], operands[3],
11749                                   operands[1], INTVAL (operands[2]),
11750                                   false, true))"
11751   "ldrd%?\t%0, %3, [%1, %2]"
11752   [(set_attr "type" "load_8")
11753    (set_attr "predicable" "yes")
11754    (set_attr "predicable_short_it" "no")])
11756 (define_insn "*thumb2_ldrd_base"
11757   [(set (match_operand:SI 0 "s_register_operand" "=r")
11758         (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
11759    (set (match_operand:SI 2 "s_register_operand" "=r")
11760         (mem:SI (plus:SI (match_dup 1)
11761                          (const_int 4))))]
11762   "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11763      && (operands_ok_ldrd_strd (operands[0], operands[2],
11764                                   operands[1], 0, false, true))"
11765   "ldrd%?\t%0, %2, [%1]"
11766   [(set_attr "type" "load_8")
11767    (set_attr "predicable" "yes")
11768    (set_attr "predicable_short_it" "no")])
11770 (define_insn "*thumb2_ldrd_base_neg"
11771   [(set (match_operand:SI 0 "s_register_operand" "=r")
11772         (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "rk")
11773                          (const_int -4))))
11774    (set (match_operand:SI 2 "s_register_operand" "=r")
11775         (mem:SI (match_dup 1)))]
11776   "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11777      && (operands_ok_ldrd_strd (operands[0], operands[2],
11778                                   operands[1], -4, false, true))"
11779   "ldrd%?\t%0, %2, [%1, #-4]"
11780   [(set_attr "type" "load_8")
11781    (set_attr "predicable" "yes")
11782    (set_attr "predicable_short_it" "no")])
11784 (define_insn "*thumb2_strd"
11785   [(set (mem:SI (plus:SI (match_operand:SI 0 "s_register_operand" "rk")
11786                          (match_operand:SI 1 "ldrd_strd_offset_operand" "Do")))
11787         (match_operand:SI 2 "s_register_operand" "r"))
11788    (set (mem:SI (plus:SI (match_dup 0)
11789                          (match_operand:SI 3 "const_int_operand" "")))
11790         (match_operand:SI 4 "s_register_operand" "r"))]
11791   "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11792      && ((INTVAL (operands[1]) + 4) == INTVAL (operands[3]))
11793      && (operands_ok_ldrd_strd (operands[2], operands[4],
11794                                   operands[0], INTVAL (operands[1]),
11795                                   false, false))"
11796   "strd%?\t%2, %4, [%0, %1]"
11797   [(set_attr "type" "store_8")
11798    (set_attr "predicable" "yes")
11799    (set_attr "predicable_short_it" "no")])
11801 (define_insn "*thumb2_strd_base"
11802   [(set (mem:SI (match_operand:SI 0 "s_register_operand" "rk"))
11803         (match_operand:SI 1 "s_register_operand" "r"))
11804    (set (mem:SI (plus:SI (match_dup 0)
11805                          (const_int 4)))
11806         (match_operand:SI 2 "s_register_operand" "r"))]
11807   "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11808      && (operands_ok_ldrd_strd (operands[1], operands[2],
11809                                   operands[0], 0, false, false))"
11810   "strd%?\t%1, %2, [%0]"
11811   [(set_attr "type" "store_8")
11812    (set_attr "predicable" "yes")
11813    (set_attr "predicable_short_it" "no")])
11815 (define_insn "*thumb2_strd_base_neg"
11816   [(set (mem:SI (plus:SI (match_operand:SI 0 "s_register_operand" "rk")
11817                          (const_int -4)))
11818         (match_operand:SI 1 "s_register_operand" "r"))
11819    (set (mem:SI (match_dup 0))
11820         (match_operand:SI 2 "s_register_operand" "r"))]
11821   "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11822      && (operands_ok_ldrd_strd (operands[1], operands[2],
11823                                   operands[0], -4, false, false))"
11824   "strd%?\t%1, %2, [%0, #-4]"
11825   [(set_attr "type" "store_8")
11826    (set_attr "predicable" "yes")
11827    (set_attr "predicable_short_it" "no")])
11829 ;; ARMv8 CRC32 instructions.
11830 (define_insn "<crc_variant>"
11831   [(set (match_operand:SI 0 "s_register_operand" "=r")
11832         (unspec:SI [(match_operand:SI 1 "s_register_operand" "r")
11833                     (match_operand:<crc_mode> 2 "s_register_operand" "r")]
11834          CRC))]
11835   "TARGET_CRC32"
11836   "<crc_variant>\\t%0, %1, %2"
11837   [(set_attr "type" "crc")
11838    (set_attr "conds" "unconditional")]
11841 ;; Load the load/store double peephole optimizations.
11842 (include "ldrdstrd.md")
11844 ;; Load the load/store multiple patterns
11845 (include "ldmstm.md")
11847 ;; Patterns in ldmstm.md don't cover more than 4 registers. This pattern covers
11848 ;; large lists without explicit writeback generated for APCS_FRAME epilogue.
11849 ;; The operands are validated through the load_multiple_operation
11850 ;; match_parallel predicate rather than through constraints so enable it only
11851 ;; after reload.
11852 (define_insn "*load_multiple"
11853   [(match_parallel 0 "load_multiple_operation"
11854     [(set (match_operand:SI 2 "s_register_operand" "=rk")
11855           (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
11856         ])]
11857   "TARGET_32BIT && reload_completed"
11858   "*
11859   {
11860     arm_output_multireg_pop (operands, /*return_pc=*/false,
11861                                        /*cond=*/const_true_rtx,
11862                                        /*reverse=*/false,
11863                                        /*update=*/false);
11864     return \"\";
11865   }
11866   "
11867   [(set_attr "predicable" "yes")]
11870 (define_expand "copysignsf3"
11871   [(match_operand:SF 0 "register_operand")
11872    (match_operand:SF 1 "register_operand")
11873    (match_operand:SF 2 "register_operand")]
11874   "TARGET_SOFT_FLOAT && arm_arch_thumb2"
11875   "{
11876      emit_move_insn (operands[0], operands[2]);
11877      emit_insn (gen_insv_t2 (simplify_gen_subreg (SImode, operands[0], SFmode, 0),
11878                 GEN_INT (31), GEN_INT (0),
11879                 simplify_gen_subreg (SImode, operands[1], SFmode, 0)));
11880      DONE;
11881   }"
11884 (define_expand "copysigndf3"
11885   [(match_operand:DF 0 "register_operand")
11886    (match_operand:DF 1 "register_operand")
11887    (match_operand:DF 2 "register_operand")]
11888   "TARGET_SOFT_FLOAT && arm_arch_thumb2"
11889   "{
11890      rtx op0_low = gen_lowpart (SImode, operands[0]);
11891      rtx op0_high = gen_highpart (SImode, operands[0]);
11892      rtx op1_low = gen_lowpart (SImode, operands[1]);
11893      rtx op1_high = gen_highpart (SImode, operands[1]);
11894      rtx op2_high = gen_highpart (SImode, operands[2]);
11896      rtx scratch1 = gen_reg_rtx (SImode);
11897      rtx scratch2 = gen_reg_rtx (SImode);
11898      emit_move_insn (scratch1, op2_high);
11899      emit_move_insn (scratch2, op1_high);
11901      emit_insn(gen_rtx_SET(scratch1,
11902                            gen_rtx_LSHIFTRT (SImode, op2_high, GEN_INT(31))));
11903      emit_insn(gen_insv_t2(scratch2, GEN_INT(1), GEN_INT(31), scratch1));
11904      emit_move_insn (op0_low, op1_low);
11905      emit_move_insn (op0_high, scratch2);
11907      DONE;
11908   }"
11911 ;; movmisalign patterns for HImode and SImode.
11912 (define_expand "movmisalign<mode>"
11913   [(match_operand:HSI 0 "general_operand")
11914    (match_operand:HSI 1 "general_operand")]
11915   "unaligned_access"
11917   /* This pattern is not permitted to fail during expansion: if both arguments
11918      are non-registers (e.g. memory := constant), force operand 1 into a
11919      register.  */
11920   rtx (* gen_unaligned_load)(rtx, rtx);
11921   rtx tmp_dest = operands[0];
11922   if (!s_register_operand (operands[0], <MODE>mode)
11923       && !s_register_operand (operands[1], <MODE>mode))
11924     operands[1] = force_reg (<MODE>mode, operands[1]);
11926   if (<MODE>mode == HImode)
11927    {
11928     gen_unaligned_load = gen_unaligned_loadhiu;
11929     tmp_dest = gen_reg_rtx (SImode);
11930    }
11931   else
11932     gen_unaligned_load = gen_unaligned_loadsi;
11934   if (MEM_P (operands[1]))
11935    {
11936     emit_insn (gen_unaligned_load (tmp_dest, operands[1]));
11937     if (<MODE>mode == HImode)
11938       emit_move_insn (operands[0], gen_lowpart (HImode, tmp_dest));
11939    }
11940   else
11941     emit_insn (gen_unaligned_store<mode> (operands[0], operands[1]));
11943   DONE;
11946 (define_insn "<cdp>"
11947   [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "n")
11948                      (match_operand:SI 1 "immediate_operand" "n")
11949                      (match_operand:SI 2 "immediate_operand" "n")
11950                      (match_operand:SI 3 "immediate_operand" "n")
11951                      (match_operand:SI 4 "immediate_operand" "n")
11952                      (match_operand:SI 5 "immediate_operand" "n")] CDPI)]
11953   "arm_coproc_builtin_available (VUNSPEC_<CDP>)"
11955   arm_const_bounds (operands[0], 0, 16);
11956   arm_const_bounds (operands[1], 0, 16);
11957   arm_const_bounds (operands[2], 0, (1 << 5));
11958   arm_const_bounds (operands[3], 0, (1 << 5));
11959   arm_const_bounds (operands[4], 0, (1 << 5));
11960   arm_const_bounds (operands[5], 0, 8);
11961   return "<cdp>\\tp%c0, %1, CR%c2, CR%c3, CR%c4, %5";
11963   [(set_attr "length" "4")
11964    (set_attr "type" "coproc")])
11966 (define_insn "*ldc"
11967   [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "n")
11968                      (match_operand:SI 1 "immediate_operand" "n")
11969                      (match_operand:SI 2 "memory_operand" "Uz")] LDCI)]
11970   "arm_coproc_builtin_available (VUNSPEC_<LDC>)"
11972   arm_const_bounds (operands[0], 0, 16);
11973   arm_const_bounds (operands[1], 0, (1 << 5));
11974   return "<ldc>\\tp%c0, CR%c1, %2";
11976   [(set_attr "length" "4")
11977    (set_attr "type" "coproc")])
11979 (define_insn "*stc"
11980   [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "n")
11981                      (match_operand:SI 1 "immediate_operand" "n")
11982                      (match_operand:SI 2 "memory_operand" "=Uz")] STCI)]
11983   "arm_coproc_builtin_available (VUNSPEC_<STC>)"
11985   arm_const_bounds (operands[0], 0, 16);
11986   arm_const_bounds (operands[1], 0, (1 << 5));
11987   return "<stc>\\tp%c0, CR%c1, %2";
11989   [(set_attr "length" "4")
11990    (set_attr "type" "coproc")])
11992 (define_expand "<ldc>"
11993   [(unspec_volatile [(match_operand:SI 0 "immediate_operand")
11994                      (match_operand:SI 1 "immediate_operand")
11995                      (mem:SI (match_operand:SI 2 "s_register_operand"))] LDCI)]
11996   "arm_coproc_builtin_available (VUNSPEC_<LDC>)")
11998 (define_expand "<stc>"
11999   [(unspec_volatile [(match_operand:SI 0 "immediate_operand")
12000                      (match_operand:SI 1 "immediate_operand")
12001                      (mem:SI (match_operand:SI 2 "s_register_operand"))] STCI)]
12002   "arm_coproc_builtin_available (VUNSPEC_<STC>)")
12004 (define_insn "<mcr>"
12005   [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "n")
12006                      (match_operand:SI 1 "immediate_operand" "n")
12007                      (match_operand:SI 2 "s_register_operand" "r")
12008                      (match_operand:SI 3 "immediate_operand" "n")
12009                      (match_operand:SI 4 "immediate_operand" "n")
12010                      (match_operand:SI 5 "immediate_operand" "n")] MCRI)
12011    (use (match_dup 2))]
12012   "arm_coproc_builtin_available (VUNSPEC_<MCR>)"
12014   arm_const_bounds (operands[0], 0, 16);
12015   arm_const_bounds (operands[1], 0, 8);
12016   arm_const_bounds (operands[3], 0, (1 << 5));
12017   arm_const_bounds (operands[4], 0, (1 << 5));
12018   arm_const_bounds (operands[5], 0, 8);
12019   return "<mcr>\\tp%c0, %1, %2, CR%c3, CR%c4, %5";
12021   [(set_attr "length" "4")
12022    (set_attr "type" "coproc")])
12024 (define_insn "<mrc>"
12025   [(set (match_operand:SI 0 "s_register_operand" "=r")
12026         (unspec_volatile:SI [(match_operand:SI 1 "immediate_operand" "n")
12027                           (match_operand:SI 2 "immediate_operand" "n")
12028                           (match_operand:SI 3 "immediate_operand" "n")
12029                           (match_operand:SI 4 "immediate_operand" "n")
12030                           (match_operand:SI 5 "immediate_operand" "n")] MRCI))]
12031   "arm_coproc_builtin_available (VUNSPEC_<MRC>)"
12033   arm_const_bounds (operands[1], 0, 16);
12034   arm_const_bounds (operands[2], 0, 8);
12035   arm_const_bounds (operands[3], 0, (1 << 5));
12036   arm_const_bounds (operands[4], 0, (1 << 5));
12037   arm_const_bounds (operands[5], 0, 8);
12038   return "<mrc>\\tp%c1, %2, %0, CR%c3, CR%c4, %5";
12040   [(set_attr "length" "4")
12041    (set_attr "type" "coproc")])
12043 (define_insn "<mcrr>"
12044   [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "n")
12045                      (match_operand:SI 1 "immediate_operand" "n")
12046                      (match_operand:DI 2 "s_register_operand" "r")
12047                      (match_operand:SI 3 "immediate_operand" "n")] MCRRI)
12048    (use (match_dup 2))]
12049   "arm_coproc_builtin_available (VUNSPEC_<MCRR>)"
12051   arm_const_bounds (operands[0], 0, 16);
12052   arm_const_bounds (operands[1], 0, 8);
12053   arm_const_bounds (operands[3], 0, (1 << 5));
12054   return "<mcrr>\\tp%c0, %1, %Q2, %R2, CR%c3";
12056   [(set_attr "length" "4")
12057    (set_attr "type" "coproc")])
12059 (define_insn "<mrrc>"
12060   [(set (match_operand:DI 0 "s_register_operand" "=r")
12061         (unspec_volatile:DI [(match_operand:SI 1 "immediate_operand" "n")
12062                           (match_operand:SI 2 "immediate_operand" "n")
12063                           (match_operand:SI 3 "immediate_operand" "n")] MRRCI))]
12064   "arm_coproc_builtin_available (VUNSPEC_<MRRC>)"
12066   arm_const_bounds (operands[1], 0, 16);
12067   arm_const_bounds (operands[2], 0, 8);
12068   arm_const_bounds (operands[3], 0, (1 << 5));
12069   return "<mrrc>\\tp%c1, %2, %Q0, %R0, CR%c3";
12071   [(set_attr "length" "4")
12072    (set_attr "type" "coproc")])
12074 ;; Vector bits common to IWMMXT and Neon
12075 (include "vec-common.md")
12076 ;; Load the Intel Wireless Multimedia Extension patterns
12077 (include "iwmmxt.md")
12078 ;; Load the VFP co-processor patterns
12079 (include "vfp.md")
12080 ;; Thumb-1 patterns
12081 (include "thumb1.md")
12082 ;; Thumb-2 patterns
12083 (include "thumb2.md")
12084 ;; Neon patterns
12085 (include "neon.md")
12086 ;; Crypto patterns
12087 (include "crypto.md")
12088 ;; Synchronization Primitives
12089 (include "sync.md")
12090 ;; Fixed-point patterns
12091 (include "arm-fixed.md")