[ARM] PR71607: Fix ICE when loading constant
[official-gcc.git] / gcc / config / arm / arm.md
blob4a2b623e528256835958a510e2d32628477cb680
1 ;;- Machine description for ARM for GNU compiler
2 ;;  Copyright (C) 1991-2017 Free Software Foundation, Inc.
3 ;;  Contributed by Pieter `Tiggr' Schoenmakers (rcpieter@win.tue.nl)
4 ;;  and Martin Simmons (@harleqn.co.uk).
5 ;;  More major hacks by Richard Earnshaw (rearnsha@arm.com).
7 ;; This file is part of GCC.
9 ;; GCC is free software; you can redistribute it and/or modify it
10 ;; under the terms of the GNU General Public License as published
11 ;; by the Free Software Foundation; either version 3, or (at your
12 ;; option) any later version.
14 ;; GCC is distributed in the hope that it will be useful, but WITHOUT
15 ;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16 ;; or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
17 ;; License for more details.
19 ;; You should have received a copy of the GNU General Public License
20 ;; along with GCC; see the file COPYING3.  If not see
21 ;; <http://www.gnu.org/licenses/>.
23 ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
26 ;;---------------------------------------------------------------------------
27 ;; Constants
29 ;; Register numbers -- All machine registers should be defined here
30 (define_constants
31   [(R0_REGNUM         0)        ; First CORE register
32    (R1_REGNUM         1)        ; Second CORE register
33    (IP_REGNUM        12)        ; Scratch register
34    (SP_REGNUM        13)        ; Stack pointer
35    (LR_REGNUM        14)        ; Return address register
36    (PC_REGNUM        15)        ; Program counter
37    (LAST_ARM_REGNUM  15)        ;
38    (CC_REGNUM       100)        ; Condition code pseudo register
39    (VFPCC_REGNUM    101)        ; VFP Condition code pseudo register
40   ]
42 ;; 3rd operand to select_dominance_cc_mode
43 (define_constants
44   [(DOM_CC_X_AND_Y  0)
45    (DOM_CC_NX_OR_Y  1)
46    (DOM_CC_X_OR_Y   2)
47   ]
49 ;; conditional compare combination
50 (define_constants
51   [(CMP_CMP 0)
52    (CMN_CMP 1)
53    (CMP_CMN 2)
54    (CMN_CMN 3)
55    (NUM_OF_COND_CMP 4)
56   ]
60 ;;---------------------------------------------------------------------------
61 ;; Attributes
63 ;; Processor type.  This is created automatically from arm-cores.def.
64 (include "arm-tune.md")
66 ;; Instruction classification types
67 (include "types.md")
69 ; IS_THUMB is set to 'yes' when we are generating Thumb code, and 'no' when
70 ; generating ARM code.  This is used to control the length of some insn
71 ; patterns that share the same RTL in both ARM and Thumb code.
72 (define_attr "is_thumb" "yes,no"
73   (const (if_then_else (symbol_ref "TARGET_THUMB")
74                        (const_string "yes") (const_string "no"))))
76 ; IS_ARCH6 is set to 'yes' when we are generating code form ARMv6.
77 (define_attr "is_arch6" "no,yes" (const (symbol_ref "arm_arch6")))
79 ; IS_THUMB1 is set to 'yes' iff we are generating Thumb-1 code.
80 (define_attr "is_thumb1" "yes,no"
81   (const (if_then_else (symbol_ref "TARGET_THUMB1")
82                        (const_string "yes") (const_string "no"))))
84 ; We use this attribute to disable alternatives that can produce 32-bit
85 ; instructions inside an IT-block in Thumb2 state.  ARMv8 deprecates IT blocks
86 ; that contain 32-bit instructions.
87 (define_attr "enabled_for_depr_it" "no,yes" (const_string "yes"))
89 ; This attribute is used to disable a predicated alternative when we have
90 ; arm_restrict_it.
91 (define_attr "predicable_short_it" "no,yes" (const_string "yes"))
93 ;; Operand number of an input operand that is shifted.  Zero if the
94 ;; given instruction does not shift one of its input operands.
95 (define_attr "shift" "" (const_int 0))
97 ;; [For compatibility with AArch64 in pipeline models]
98 ;; Attribute that specifies whether or not the instruction touches fp
99 ;; registers.
100 (define_attr "fp" "no,yes" (const_string "no"))
102 ; Floating Point Unit.  If we only have floating point emulation, then there
103 ; is no point in scheduling the floating point insns.  (Well, for best
104 ; performance we should try and group them together).
105 (define_attr "fpu" "none,vfp"
106   (const (symbol_ref "arm_fpu_attr")))
108 ; Predicated means that the insn form is conditionally executed based on a
109 ; predicate.  We default to 'no' because no Thumb patterns match this rule
110 ; and not all ARM insns do.
111 (define_attr "predicated" "yes,no" (const_string "no"))
113 ; LENGTH of an instruction (in bytes)
114 (define_attr "length" ""
115   (const_int 4))
117 ; The architecture which supports the instruction (or alternative).
118 ; This can be "a" for ARM, "t" for either of the Thumbs, "32" for
119 ; TARGET_32BIT, "t1" or "t2" to specify a specific Thumb mode.  "v6"
120 ; for ARM or Thumb-2 with arm_arch6, and nov6 for ARM without
121 ; arm_arch6.  "v6t2" for Thumb-2 with arm_arch6 and "v8mb" for ARMv8-M
122 ; Baseline.  This attribute is used to compute attribute "enabled",
123 ; use type "any" to enable an alternative in all cases.
124 (define_attr "arch" "any,a,t,32,t1,t2,v6,nov6,v6t2,v8mb,neon_for_64bits,avoid_neon_for_64bits,iwmmxt,iwmmxt2,armv6_or_vfpv3,neon"
125   (const_string "any"))
127 (define_attr "arch_enabled" "no,yes"
128   (cond [(eq_attr "arch" "any")
129          (const_string "yes")
131          (and (eq_attr "arch" "a")
132               (match_test "TARGET_ARM"))
133          (const_string "yes")
135          (and (eq_attr "arch" "t")
136               (match_test "TARGET_THUMB"))
137          (const_string "yes")
139          (and (eq_attr "arch" "t1")
140               (match_test "TARGET_THUMB1"))
141          (const_string "yes")
143          (and (eq_attr "arch" "t2")
144               (match_test "TARGET_THUMB2"))
145          (const_string "yes")
147          (and (eq_attr "arch" "32")
148               (match_test "TARGET_32BIT"))
149          (const_string "yes")
151          (and (eq_attr "arch" "v6")
152               (match_test "TARGET_32BIT && arm_arch6"))
153          (const_string "yes")
155          (and (eq_attr "arch" "nov6")
156               (match_test "TARGET_32BIT && !arm_arch6"))
157          (const_string "yes")
159          (and (eq_attr "arch" "v6t2")
160               (match_test "TARGET_32BIT && arm_arch6 && arm_arch_thumb2"))
161          (const_string "yes")
163          (and (eq_attr "arch" "v8mb")
164               (match_test "TARGET_THUMB1 && arm_arch8"))
165          (const_string "yes")
167          (and (eq_attr "arch" "avoid_neon_for_64bits")
168               (match_test "TARGET_NEON")
169               (not (match_test "TARGET_PREFER_NEON_64BITS")))
170          (const_string "yes")
172          (and (eq_attr "arch" "neon_for_64bits")
173               (match_test "TARGET_NEON")
174               (match_test "TARGET_PREFER_NEON_64BITS"))
175          (const_string "yes")
177          (and (eq_attr "arch" "iwmmxt2")
178               (match_test "TARGET_REALLY_IWMMXT2"))
179          (const_string "yes")
181          (and (eq_attr "arch" "armv6_or_vfpv3")
182               (match_test "arm_arch6 || TARGET_VFP3"))
183          (const_string "yes")
185          (and (eq_attr "arch" "neon")
186               (match_test "TARGET_NEON"))
187          (const_string "yes")
188         ]
190         (const_string "no")))
192 (define_attr "opt" "any,speed,size"
193   (const_string "any"))
195 (define_attr "opt_enabled" "no,yes"
196   (cond [(eq_attr "opt" "any")
197          (const_string "yes")
199          (and (eq_attr "opt" "speed")
200               (match_test "optimize_function_for_speed_p (cfun)"))
201          (const_string "yes")
203          (and (eq_attr "opt" "size")
204               (match_test "optimize_function_for_size_p (cfun)"))
205          (const_string "yes")]
206         (const_string "no")))
208 (define_attr "use_literal_pool" "no,yes"
209    (cond [(and (eq_attr "type" "f_loads,f_loadd")
210                (match_test "CONSTANT_P (operands[1])"))
211           (const_string "yes")]
212          (const_string "no")))
214 ; Enable all alternatives that are both arch_enabled and insn_enabled.
215 ; FIXME:: opt_enabled has been temporarily removed till the time we have
216 ; an attribute that allows the use of such alternatives.
217 ; This depends on caching of speed_p, size_p on a per
218 ; alternative basis. The problem is that the enabled attribute
219 ; cannot depend on any state that is not cached or is not constant
220 ; for a compilation unit. We probably need a generic "hot/cold"
221 ; alternative which if implemented can help with this. We disable this
222 ; until such a time as this is implemented and / or the improvements or
223 ; regressions with removing this attribute are double checked.
224 ; See ashldi3_neon and <shift>di3_neon in neon.md.
226  (define_attr "enabled" "no,yes"
227    (cond [(and (eq_attr "predicable_short_it" "no")
228                (and (eq_attr "predicated" "yes")
229                     (match_test "arm_restrict_it")))
230           (const_string "no")
232           (and (eq_attr "enabled_for_depr_it" "no")
233                (match_test "arm_restrict_it"))
234           (const_string "no")
236           (eq_attr "arch_enabled" "no")
237           (const_string "no")]
238          (const_string "yes")))
240 ; POOL_RANGE is how far away from a constant pool entry that this insn
241 ; can be placed.  If the distance is zero, then this insn will never
242 ; reference the pool.
243 ; Note that for Thumb constant pools the PC value is rounded down to the
244 ; nearest multiple of four.  Therefore, THUMB2_POOL_RANGE (and POOL_RANGE for
245 ; Thumb insns) should be set to <max_range> - 2.
246 ; NEG_POOL_RANGE is nonzero for insns that can reference a constant pool entry
247 ; before its address.  It is set to <max_range> - (8 + <data_size>).
248 (define_attr "arm_pool_range" "" (const_int 0))
249 (define_attr "thumb2_pool_range" "" (const_int 0))
250 (define_attr "arm_neg_pool_range" "" (const_int 0))
251 (define_attr "thumb2_neg_pool_range" "" (const_int 0))
253 (define_attr "pool_range" ""
254   (cond [(eq_attr "is_thumb" "yes") (attr "thumb2_pool_range")]
255         (attr "arm_pool_range")))
256 (define_attr "neg_pool_range" ""
257   (cond [(eq_attr "is_thumb" "yes") (attr "thumb2_neg_pool_range")]
258         (attr "arm_neg_pool_range")))
260 ; An assembler sequence may clobber the condition codes without us knowing.
261 ; If such an insn references the pool, then we have no way of knowing how,
262 ; so use the most conservative value for pool_range.
263 (define_asm_attributes
264  [(set_attr "conds" "clob")
265   (set_attr "length" "4")
266   (set_attr "pool_range" "250")])
268 ; Load scheduling, set from the arm_ld_sched variable
269 ; initialized by arm_option_override()
270 (define_attr "ldsched" "no,yes" (const (symbol_ref "arm_ld_sched")))
272 ; condition codes: this one is used by final_prescan_insn to speed up
273 ; conditionalizing instructions.  It saves having to scan the rtl to see if
274 ; it uses or alters the condition codes.
276 ; USE means that the condition codes are used by the insn in the process of
277 ;   outputting code, this means (at present) that we can't use the insn in
278 ;   inlined branches
280 ; SET means that the purpose of the insn is to set the condition codes in a
281 ;   well defined manner.
283 ; CLOB means that the condition codes are altered in an undefined manner, if
284 ;   they are altered at all
286 ; UNCONDITIONAL means the instruction can not be conditionally executed and
287 ;   that the instruction does not use or alter the condition codes.
289 ; NOCOND means that the instruction does not use or alter the condition
290 ;   codes but can be converted into a conditionally exectuted instruction.
292 (define_attr "conds" "use,set,clob,unconditional,nocond"
293         (if_then_else
294          (ior (eq_attr "is_thumb1" "yes")
295               (eq_attr "type" "call"))
296          (const_string "clob")
297          (if_then_else (eq_attr "is_neon_type" "no")
298          (const_string "nocond")
299          (const_string "unconditional"))))
301 ; Predicable means that the insn can be conditionally executed based on
302 ; an automatically added predicate (additional patterns are generated by 
303 ; gen...).  We default to 'no' because no Thumb patterns match this rule
304 ; and not all ARM patterns do.
305 (define_attr "predicable" "no,yes" (const_string "no"))
307 ; Only model the write buffer for ARM6 and ARM7.  Earlier processors don't
308 ; have one.  Later ones, such as StrongARM, have write-back caches, so don't
309 ; suffer blockages enough to warrant modelling this (and it can adversely
310 ; affect the schedule).
311 (define_attr "model_wbuf" "no,yes" (const (symbol_ref "arm_tune_wbuf")))
313 ; WRITE_CONFLICT implies that a read following an unrelated write is likely
314 ; to stall the processor.  Used with model_wbuf above.
315 (define_attr "write_conflict" "no,yes"
316   (if_then_else (eq_attr "type"
317                  "block,call,load1")
318                 (const_string "yes")
319                 (const_string "no")))
321 ; Classify the insns into those that take one cycle and those that take more
322 ; than one on the main cpu execution unit.
323 (define_attr "core_cycles" "single,multi"
324   (if_then_else (eq_attr "type"
325     "adc_imm, adc_reg, adcs_imm, adcs_reg, adr, alu_ext, alu_imm, alu_sreg,\
326     alu_shift_imm, alu_shift_reg, alu_dsp_reg, alus_ext, alus_imm, alus_sreg,\
327     alus_shift_imm, alus_shift_reg, bfm, csel, rev, logic_imm, logic_reg,\
328     logic_shift_imm, logic_shift_reg, logics_imm, logics_reg,\
329     logics_shift_imm, logics_shift_reg, extend, shift_imm, float, fcsel,\
330     wmmx_wor, wmmx_wxor, wmmx_wand, wmmx_wandn, wmmx_wmov, wmmx_tmcrr,\
331     wmmx_tmrrc, wmmx_wldr, wmmx_wstr, wmmx_tmcr, wmmx_tmrc, wmmx_wadd,\
332     wmmx_wsub, wmmx_wmul, wmmx_wmac, wmmx_wavg2, wmmx_tinsr, wmmx_textrm,\
333     wmmx_wshufh, wmmx_wcmpeq, wmmx_wcmpgt, wmmx_wmax, wmmx_wmin, wmmx_wpack,\
334     wmmx_wunpckih, wmmx_wunpckil, wmmx_wunpckeh, wmmx_wunpckel, wmmx_wror,\
335     wmmx_wsra, wmmx_wsrl, wmmx_wsll, wmmx_wmadd, wmmx_tmia, wmmx_tmiaph,\
336     wmmx_tmiaxy, wmmx_tbcst, wmmx_tmovmsk, wmmx_wacc, wmmx_waligni,\
337     wmmx_walignr, wmmx_tandc, wmmx_textrc, wmmx_torc, wmmx_torvsc, wmmx_wsad,\
338     wmmx_wabs, wmmx_wabsdiff, wmmx_waddsubhx, wmmx_wsubaddhx, wmmx_wavg4,\
339     wmmx_wmulw, wmmx_wqmulm, wmmx_wqmulwm, wmmx_waddbhus, wmmx_wqmiaxy,\
340     wmmx_wmiaxy, wmmx_wmiawxy, wmmx_wmerge")
341                 (const_string "single")
342                 (const_string "multi")))
344 ;; FAR_JUMP is "yes" if a BL instruction is used to generate a branch to a
345 ;; distant label.  Only applicable to Thumb code.
346 (define_attr "far_jump" "yes,no" (const_string "no"))
349 ;; The number of machine instructions this pattern expands to.
350 ;; Used for Thumb-2 conditional execution.
351 (define_attr "ce_count" "" (const_int 1))
353 ;;---------------------------------------------------------------------------
354 ;; Unspecs
356 (include "unspecs.md")
358 ;;---------------------------------------------------------------------------
359 ;; Mode iterators
361 (include "iterators.md")
363 ;;---------------------------------------------------------------------------
364 ;; Predicates
366 (include "predicates.md")
367 (include "constraints.md")
369 ;;---------------------------------------------------------------------------
370 ;; Pipeline descriptions
372 (define_attr "tune_cortexr4" "yes,no"
373   (const (if_then_else
374           (eq_attr "tune" "cortexr4,cortexr4f,cortexr5")
375           (const_string "yes")
376           (const_string "no"))))
378 ;; True if the generic scheduling description should be used.
380 (define_attr "generic_sched" "yes,no"
381   (const (if_then_else
382           (ior (eq_attr "tune" "fa526,fa626,fa606te,fa626te,fmp626,fa726te,\
383                                 arm926ejs,arm1020e,arm1026ejs,arm1136js,\
384                                 arm1136jfs,cortexa5,cortexa7,cortexa8,\
385                                 cortexa9,cortexa12,cortexa15,cortexa17,\
386                                 cortexa53,cortexa57,cortexm4,cortexm7,\
387                                 exynosm1,marvell_pj4,xgene1")
388                (eq_attr "tune_cortexr4" "yes"))
389           (const_string "no")
390           (const_string "yes"))))
392 (define_attr "generic_vfp" "yes,no"
393   (const (if_then_else
394           (and (eq_attr "fpu" "vfp")
395                (eq_attr "tune" "!arm1020e,arm1022e,cortexa5,cortexa7,\
396                                 cortexa8,cortexa9,cortexa53,cortexm4,\
397                                 cortexm7,marvell_pj4,xgene1")
398                (eq_attr "tune_cortexr4" "no"))
399           (const_string "yes")
400           (const_string "no"))))
402 (include "marvell-f-iwmmxt.md")
403 (include "arm-generic.md")
404 (include "arm926ejs.md")
405 (include "arm1020e.md")
406 (include "arm1026ejs.md")
407 (include "arm1136jfs.md")
408 (include "fa526.md")
409 (include "fa606te.md")
410 (include "fa626te.md")
411 (include "fmp626.md")
412 (include "fa726te.md")
413 (include "cortex-a5.md")
414 (include "cortex-a7.md")
415 (include "cortex-a8.md")
416 (include "cortex-a9.md")
417 (include "cortex-a15.md")
418 (include "cortex-a17.md")
419 (include "cortex-a53.md")
420 (include "cortex-a57.md")
421 (include "cortex-r4.md")
422 (include "cortex-r4f.md")
423 (include "cortex-m7.md")
424 (include "cortex-m4.md")
425 (include "cortex-m4-fpu.md")
426 (include "exynos-m1.md")
427 (include "vfp11.md")
428 (include "marvell-pj4.md")
429 (include "xgene1.md")
432 ;;---------------------------------------------------------------------------
433 ;; Insn patterns
435 ;; Addition insns.
437 ;; Note: For DImode insns, there is normally no reason why operands should
438 ;; not be in the same register, what we don't want is for something being
439 ;; written to partially overlap something that is an input.
441 (define_expand "adddi3"
442  [(parallel
443    [(set (match_operand:DI           0 "s_register_operand" "")
444           (plus:DI (match_operand:DI 1 "s_register_operand" "")
445                    (match_operand:DI 2 "arm_adddi_operand"  "")))
446     (clobber (reg:CC CC_REGNUM))])]
447   "TARGET_EITHER"
448   "
449   if (TARGET_THUMB1)
450     {
451       if (!REG_P (operands[1]))
452         operands[1] = force_reg (DImode, operands[1]);
453       if (!REG_P (operands[2]))
454         operands[2] = force_reg (DImode, operands[2]);
455      }
456   "
459 (define_insn_and_split "*arm_adddi3"
460   [(set (match_operand:DI          0 "s_register_operand" "=&r,&r,&r,&r,&r")
461         (plus:DI (match_operand:DI 1 "s_register_operand" "%0, 0, r, 0, r")
462                  (match_operand:DI 2 "arm_adddi_operand"  "r,  0, r, Dd, Dd")))
463    (clobber (reg:CC CC_REGNUM))]
464   "TARGET_32BIT && !TARGET_NEON"
465   "#"
466   "TARGET_32BIT && reload_completed
467    && ! (TARGET_NEON && IS_VFP_REGNUM (REGNO (operands[0])))"
468   [(parallel [(set (reg:CC_C CC_REGNUM)
469                    (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
470                                  (match_dup 1)))
471               (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
472    (set (match_dup 3) (plus:SI (plus:SI (match_dup 4) (match_dup 5))
473                                (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
474   "
475   {
476     operands[3] = gen_highpart (SImode, operands[0]);
477     operands[0] = gen_lowpart (SImode, operands[0]);
478     operands[4] = gen_highpart (SImode, operands[1]);
479     operands[1] = gen_lowpart (SImode, operands[1]);
480     operands[5] = gen_highpart_mode (SImode, DImode, operands[2]);
481     operands[2] = gen_lowpart (SImode, operands[2]);
482   }"
483   [(set_attr "conds" "clob")
484    (set_attr "length" "8")
485    (set_attr "type" "multiple")]
488 (define_insn_and_split "*adddi_sesidi_di"
489   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
490         (plus:DI (sign_extend:DI
491                   (match_operand:SI 2 "s_register_operand" "r,r"))
492                  (match_operand:DI 1 "s_register_operand" "0,r")))
493    (clobber (reg:CC CC_REGNUM))]
494   "TARGET_32BIT"
495   "#"
496   "TARGET_32BIT && reload_completed"
497   [(parallel [(set (reg:CC_C CC_REGNUM)
498                    (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
499                                  (match_dup 1)))
500               (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
501    (set (match_dup 3) (plus:SI (plus:SI (ashiftrt:SI (match_dup 2)
502                                                      (const_int 31))
503                                         (match_dup 4))
504                                (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
505   "
506   {
507     operands[3] = gen_highpart (SImode, operands[0]);
508     operands[0] = gen_lowpart (SImode, operands[0]);
509     operands[4] = gen_highpart (SImode, operands[1]);
510     operands[1] = gen_lowpart (SImode, operands[1]);
511     operands[2] = gen_lowpart (SImode, operands[2]);
512   }"
513   [(set_attr "conds" "clob")
514    (set_attr "length" "8")
515    (set_attr "type" "multiple")]
518 (define_insn_and_split "*adddi_zesidi_di"
519   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
520         (plus:DI (zero_extend:DI
521                   (match_operand:SI 2 "s_register_operand" "r,r"))
522                  (match_operand:DI 1 "s_register_operand" "0,r")))
523    (clobber (reg:CC CC_REGNUM))]
524   "TARGET_32BIT"
525   "#"
526   "TARGET_32BIT && reload_completed"
527   [(parallel [(set (reg:CC_C CC_REGNUM)
528                    (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
529                                  (match_dup 1)))
530               (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
531    (set (match_dup 3) (plus:SI (plus:SI (match_dup 4) (const_int 0))
532                                (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
533   "
534   {
535     operands[3] = gen_highpart (SImode, operands[0]);
536     operands[0] = gen_lowpart (SImode, operands[0]);
537     operands[4] = gen_highpart (SImode, operands[1]);
538     operands[1] = gen_lowpart (SImode, operands[1]);
539     operands[2] = gen_lowpart (SImode, operands[2]);
540   }"
541   [(set_attr "conds" "clob")
542    (set_attr "length" "8")
543    (set_attr "type" "multiple")]
546 (define_expand "addv<mode>4"
547   [(match_operand:SIDI 0 "register_operand")
548    (match_operand:SIDI 1 "register_operand")
549    (match_operand:SIDI 2 "register_operand")
550    (match_operand 3 "")]
551   "TARGET_32BIT"
553   emit_insn (gen_add<mode>3_compareV (operands[0], operands[1], operands[2]));
554   arm_gen_unlikely_cbranch (NE, CC_Vmode, operands[3]);
556   DONE;
559 (define_expand "uaddv<mode>4"
560   [(match_operand:SIDI 0 "register_operand")
561    (match_operand:SIDI 1 "register_operand")
562    (match_operand:SIDI 2 "register_operand")
563    (match_operand 3 "")]
564   "TARGET_32BIT"
566   emit_insn (gen_add<mode>3_compareC (operands[0], operands[1], operands[2]));
567   arm_gen_unlikely_cbranch (NE, CC_Cmode, operands[3]);
569   DONE;
572 (define_expand "addsi3"
573   [(set (match_operand:SI          0 "s_register_operand" "")
574         (plus:SI (match_operand:SI 1 "s_register_operand" "")
575                  (match_operand:SI 2 "reg_or_int_operand" "")))]
576   "TARGET_EITHER"
577   "
578   if (TARGET_32BIT && CONST_INT_P (operands[2]))
579     {
580       arm_split_constant (PLUS, SImode, NULL_RTX,
581                           INTVAL (operands[2]), operands[0], operands[1],
582                           optimize && can_create_pseudo_p ());
583       DONE;
584     }
585   "
588 ; If there is a scratch available, this will be faster than synthesizing the
589 ; addition.
590 (define_peephole2
591   [(match_scratch:SI 3 "r")
592    (set (match_operand:SI          0 "arm_general_register_operand" "")
593         (plus:SI (match_operand:SI 1 "arm_general_register_operand" "")
594                  (match_operand:SI 2 "const_int_operand"  "")))]
595   "TARGET_32BIT &&
596    !(const_ok_for_arm (INTVAL (operands[2]))
597      || const_ok_for_arm (-INTVAL (operands[2])))
598     && const_ok_for_arm (~INTVAL (operands[2]))"
599   [(set (match_dup 3) (match_dup 2))
600    (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 3)))]
601   ""
604 ;; The r/r/k alternative is required when reloading the address
605 ;;  (plus (reg rN) (reg sp)) into (reg rN).  In this case reload will
606 ;; put the duplicated register first, and not try the commutative version.
607 (define_insn_and_split "*arm_addsi3"
608   [(set (match_operand:SI          0 "s_register_operand" "=rk,l,l ,l ,r ,k ,r,k ,r ,k ,r ,k,k,r ,k ,r")
609         (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")
610                  (match_operand:SI 2 "reg_or_int_operand" "rk ,l,Py,Pd,rI,rI,k,rI,Pj,Pj,L ,L,L,PJ,PJ,?n")))]
611   "TARGET_32BIT"
612   "@
613    add%?\\t%0, %0, %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, %1, %2
619    add%?\\t%0, %2, %1
620    add%?\\t%0, %1, %2
621    addw%?\\t%0, %1, %2
622    addw%?\\t%0, %1, %2
623    sub%?\\t%0, %1, #%n2
624    sub%?\\t%0, %1, #%n2
625    sub%?\\t%0, %1, #%n2
626    subw%?\\t%0, %1, #%n2
627    subw%?\\t%0, %1, #%n2
628    #"
629   "TARGET_32BIT
630    && CONST_INT_P (operands[2])
631    && !const_ok_for_op (INTVAL (operands[2]), PLUS)
632    && (reload_completed || !arm_eliminable_register (operands[1]))"
633   [(clobber (const_int 0))]
634   "
635   arm_split_constant (PLUS, SImode, curr_insn,
636                       INTVAL (operands[2]), operands[0],
637                       operands[1], 0);
638   DONE;
639   "
640   [(set_attr "length" "2,4,4,4,4,4,4,4,4,4,4,4,4,4,4,16")
641    (set_attr "predicable" "yes")
642    (set_attr "predicable_short_it" "yes,yes,yes,yes,no,no,no,no,no,no,no,no,no,no,no,no")
643    (set_attr "arch" "t2,t2,t2,t2,*,*,*,a,t2,t2,*,*,a,t2,t2,*")
644    (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
645                       (const_string "alu_imm")
646                       (const_string "alu_sreg")))
650 (define_insn_and_split "adddi3_compareV"
651   [(set (reg:CC_V CC_REGNUM)
652         (ne:CC_V
653           (plus:TI
654             (sign_extend:TI (match_operand:DI 1 "register_operand" "r"))
655             (sign_extend:TI (match_operand:DI 2 "register_operand" "r")))
656           (sign_extend:TI (plus:DI (match_dup 1) (match_dup 2)))))
657    (set (match_operand:DI 0 "register_operand" "=&r")
658         (plus:DI (match_dup 1) (match_dup 2)))]
659   "TARGET_32BIT"
660   "#"
661   "&& reload_completed"
662   [(parallel [(set (reg:CC_C CC_REGNUM)
663                    (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
664                                  (match_dup 1)))
665               (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
666    (parallel [(set (reg:CC_V CC_REGNUM)
667                    (ne:CC_V
668                     (plus:DI (plus:DI
669                               (sign_extend:DI (match_dup 4))
670                               (sign_extend:DI (match_dup 5)))
671                              (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0)))
672                     (plus:DI (sign_extend:DI
673                               (plus:SI (match_dup 4) (match_dup 5)))
674                              (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0)))))
675              (set (match_dup 3) (plus:SI (plus:SI
676                                           (match_dup 4) (match_dup 5))
677                                          (ltu:SI (reg:CC_C CC_REGNUM)
678                                                  (const_int 0))))])]
679   "
680   {
681     operands[3] = gen_highpart (SImode, operands[0]);
682     operands[0] = gen_lowpart (SImode, operands[0]);
683     operands[4] = gen_highpart (SImode, operands[1]);
684     operands[1] = gen_lowpart (SImode, operands[1]);
685     operands[5] = gen_highpart (SImode, operands[2]);
686     operands[2] = gen_lowpart (SImode, operands[2]);
687   }"
688  [(set_attr "conds" "set")
689    (set_attr "length" "8")
690    (set_attr "type" "multiple")]
693 (define_insn "addsi3_compareV"
694   [(set (reg:CC_V CC_REGNUM)
695         (ne:CC_V
696           (plus:DI
697             (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
698             (sign_extend:DI (match_operand:SI 2 "register_operand" "r")))
699           (sign_extend:DI (plus:SI (match_dup 1) (match_dup 2)))))
700    (set (match_operand:SI 0 "register_operand" "=r")
701         (plus:SI (match_dup 1) (match_dup 2)))]
702   "TARGET_32BIT"
703   "adds%?\\t%0, %1, %2"
704   [(set_attr "conds" "set")
705    (set_attr "type" "alus_sreg")]
708 (define_insn "*addsi3_compareV_upper"
709   [(set (reg:CC_V CC_REGNUM)
710         (ne:CC_V
711           (plus:DI
712            (plus:DI
713             (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
714             (sign_extend:DI (match_operand:SI 2 "register_operand" "r")))
715            (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0)))
716           (plus:DI (sign_extend:DI
717                     (plus:SI (match_dup 1) (match_dup 2)))
718                    (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0)))))
719    (set (match_operand:SI 0 "register_operand" "=r")
720         (plus:SI
721          (plus:SI (match_dup 1) (match_dup 2))
722          (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
723   "TARGET_32BIT"
724   "adcs%?\\t%0, %1, %2"
725   [(set_attr "conds" "set")
726    (set_attr "type" "adcs_reg")]
729 (define_insn_and_split "adddi3_compareC"
730   [(set (reg:CC_C CC_REGNUM)
731         (ne:CC_C
732           (plus:TI
733             (zero_extend:TI (match_operand:DI 1 "register_operand" "r"))
734             (zero_extend:TI (match_operand:DI 2 "register_operand" "r")))
735           (zero_extend:TI (plus:DI (match_dup 1) (match_dup 2)))))
736    (set (match_operand:DI 0 "register_operand" "=&r")
737         (plus:DI (match_dup 1) (match_dup 2)))]
738   "TARGET_32BIT"
739   "#"
740   "&& reload_completed"
741   [(parallel [(set (reg:CC_C CC_REGNUM)
742                    (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
743                                  (match_dup 1)))
744               (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
745    (parallel [(set (reg:CC_C CC_REGNUM)
746                    (ne:CC_C
747                     (plus:DI (plus:DI
748                               (zero_extend:DI (match_dup 4))
749                               (zero_extend:DI (match_dup 5)))
750                              (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0)))
751                     (plus:DI (zero_extend:DI
752                               (plus:SI (match_dup 4) (match_dup 5)))
753                              (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0)))))
754              (set (match_dup 3) (plus:SI
755                                  (plus:SI (match_dup 4) (match_dup 5))
756                                  (ltu:SI (reg:CC_C CC_REGNUM)
757                                          (const_int 0))))])]
758   "
759   {
760     operands[3] = gen_highpart (SImode, operands[0]);
761     operands[0] = gen_lowpart (SImode, operands[0]);
762     operands[4] = gen_highpart (SImode, operands[1]);
763     operands[5] = gen_highpart (SImode, operands[2]);
764     operands[1] = gen_lowpart (SImode, operands[1]);
765     operands[2] = gen_lowpart (SImode, operands[2]);
766   }"
767  [(set_attr "conds" "set")
768    (set_attr "length" "8")
769    (set_attr "type" "multiple")]
772 (define_insn "*addsi3_compareC_upper"
773   [(set (reg:CC_C CC_REGNUM)
774         (ne:CC_C
775           (plus:DI
776            (plus:DI
777             (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
778             (zero_extend:DI (match_operand:SI 2 "register_operand" "r")))
779            (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0)))
780           (plus:DI (zero_extend:DI
781                     (plus:SI (match_dup 1) (match_dup 2)))
782                    (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0)))))
783    (set (match_operand:SI 0 "register_operand" "=r")
784         (plus:SI
785          (plus:SI (match_dup 1) (match_dup 2))
786          (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
787   "TARGET_32BIT"
788   "adcs%?\\t%0, %1, %2"
789   [(set_attr "conds" "set")
790    (set_attr "type" "adcs_reg")]
793 (define_insn "addsi3_compareC"
794    [(set (reg:CC_C CC_REGNUM)
795          (ne:CC_C
796           (plus:DI
797            (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
798            (zero_extend:DI (match_operand:SI 2 "register_operand" "r")))
799           (zero_extend:DI
800            (plus:SI (match_dup 1) (match_dup 2)))))
801     (set (match_operand:SI 0 "register_operand" "=r")
802          (plus:SI (match_dup 1) (match_dup 2)))]
803   "TARGET_32BIT"
804   "adds%?\\t%0, %1, %2"
805   [(set_attr "conds" "set")
806    (set_attr "type" "alus_sreg")]
809 (define_insn "addsi3_compare0"
810   [(set (reg:CC_NOOV CC_REGNUM)
811         (compare:CC_NOOV
812          (plus:SI (match_operand:SI 1 "s_register_operand" "r, r,r")
813                   (match_operand:SI 2 "arm_add_operand"    "I,L,r"))
814          (const_int 0)))
815    (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
816         (plus:SI (match_dup 1) (match_dup 2)))]
817   "TARGET_ARM"
818   "@
819    adds%?\\t%0, %1, %2
820    subs%?\\t%0, %1, #%n2
821    adds%?\\t%0, %1, %2"
822   [(set_attr "conds" "set")
823    (set_attr "type" "alus_imm,alus_imm,alus_sreg")]
826 (define_insn "*addsi3_compare0_scratch"
827   [(set (reg:CC_NOOV CC_REGNUM)
828         (compare:CC_NOOV
829          (plus:SI (match_operand:SI 0 "s_register_operand" "r, r, r")
830                   (match_operand:SI 1 "arm_add_operand"    "I,L, r"))
831          (const_int 0)))]
832   "TARGET_ARM"
833   "@
834    cmn%?\\t%0, %1
835    cmp%?\\t%0, #%n1
836    cmn%?\\t%0, %1"
837   [(set_attr "conds" "set")
838    (set_attr "predicable" "yes")
839    (set_attr "type" "alus_imm,alus_imm,alus_sreg")]
842 (define_insn "*compare_negsi_si"
843   [(set (reg:CC_Z CC_REGNUM)
844         (compare:CC_Z
845          (neg:SI (match_operand:SI 0 "s_register_operand" "l,r"))
846          (match_operand:SI 1 "s_register_operand" "l,r")))]
847   "TARGET_32BIT"
848   "cmn%?\\t%1, %0"
849   [(set_attr "conds" "set")
850    (set_attr "predicable" "yes")
851    (set_attr "arch" "t2,*")
852    (set_attr "length" "2,4")
853    (set_attr "predicable_short_it" "yes,no")
854    (set_attr "type" "alus_sreg")]
857 ;; This is the canonicalization of addsi3_compare0_for_combiner when the
858 ;; addend is a constant.
859 (define_insn "cmpsi2_addneg"
860   [(set (reg:CC CC_REGNUM)
861         (compare:CC
862          (match_operand:SI 1 "s_register_operand" "r,r")
863          (match_operand:SI 2 "arm_addimm_operand" "L,I")))
864    (set (match_operand:SI 0 "s_register_operand" "=r,r")
865         (plus:SI (match_dup 1)
866                  (match_operand:SI 3 "arm_addimm_operand" "I,L")))]
867   "TARGET_32BIT && INTVAL (operands[2]) == -INTVAL (operands[3])"
868   "@
869    adds%?\\t%0, %1, %3
870    subs%?\\t%0, %1, #%n3"
871   [(set_attr "conds" "set")
872    (set_attr "type" "alus_sreg")]
875 ;; Convert the sequence
876 ;;  sub  rd, rn, #1
877 ;;  cmn  rd, #1 (equivalent to cmp rd, #-1)
878 ;;  bne  dest
879 ;; into
880 ;;  subs rd, rn, #1
881 ;;  bcs  dest   ((unsigned)rn >= 1)
882 ;; similarly for the beq variant using bcc.
883 ;; This is a common looping idiom (while (n--))
884 (define_peephole2
885   [(set (match_operand:SI 0 "arm_general_register_operand" "")
886         (plus:SI (match_operand:SI 1 "arm_general_register_operand" "")
887                  (const_int -1)))
888    (set (match_operand 2 "cc_register" "")
889         (compare (match_dup 0) (const_int -1)))
890    (set (pc)
891         (if_then_else (match_operator 3 "equality_operator"
892                        [(match_dup 2) (const_int 0)])
893                       (match_operand 4 "" "")
894                       (match_operand 5 "" "")))]
895   "TARGET_32BIT && peep2_reg_dead_p (3, operands[2])"
896   [(parallel[
897     (set (match_dup 2)
898          (compare:CC
899           (match_dup 1) (const_int 1)))
900     (set (match_dup 0) (plus:SI (match_dup 1) (const_int -1)))])
901    (set (pc)
902         (if_then_else (match_op_dup 3 [(match_dup 2) (const_int 0)])
903                       (match_dup 4)
904                       (match_dup 5)))]
905   "operands[2] = gen_rtx_REG (CCmode, CC_REGNUM);
906    operands[3] = gen_rtx_fmt_ee ((GET_CODE (operands[3]) == NE
907                                   ? GEU : LTU),
908                                  VOIDmode, 
909                                  operands[2], const0_rtx);"
912 ;; The next four insns work because they compare the result with one of
913 ;; the operands, and we know that the use of the condition code is
914 ;; either GEU or LTU, so we can use the carry flag from the addition
915 ;; instead of doing the compare a second time.
916 (define_insn "*addsi3_compare_op1"
917   [(set (reg:CC_C CC_REGNUM)
918         (compare:CC_C
919          (plus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
920                   (match_operand:SI 2 "arm_add_operand" "I,L,r"))
921          (match_dup 1)))
922    (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
923         (plus:SI (match_dup 1) (match_dup 2)))]
924   "TARGET_32BIT"
925   "@
926    adds%?\\t%0, %1, %2
927    subs%?\\t%0, %1, #%n2
928    adds%?\\t%0, %1, %2"
929   [(set_attr "conds" "set")
930    (set_attr "type"  "alus_imm,alus_imm,alus_sreg")]
933 (define_insn "*addsi3_compare_op2"
934   [(set (reg:CC_C CC_REGNUM)
935         (compare:CC_C
936          (plus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
937                   (match_operand:SI 2 "arm_add_operand" "I,L,r"))
938          (match_dup 2)))
939    (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
940         (plus:SI (match_dup 1) (match_dup 2)))]
941   "TARGET_32BIT"
942   "@
943    adds%?\\t%0, %1, %2
944    subs%?\\t%0, %1, #%n2
945    adds%?\\t%0, %1, %2"
946   [(set_attr "conds" "set")
947    (set_attr "type" "alus_imm,alus_imm,alus_sreg")]
950 (define_insn "*compare_addsi2_op0"
951   [(set (reg:CC_C CC_REGNUM)
952         (compare:CC_C
953           (plus:SI (match_operand:SI 0 "s_register_operand" "l,l,r,r,r")
954                    (match_operand:SI 1 "arm_add_operand" "Pv,l,I,L,r"))
955           (match_dup 0)))]
956   "TARGET_32BIT"
957   "@
958    cmp%?\\t%0, #%n1
959    cmn%?\\t%0, %1
960    cmn%?\\t%0, %1
961    cmp%?\\t%0, #%n1
962    cmn%?\\t%0, %1"
963   [(set_attr "conds" "set")
964    (set_attr "predicable" "yes")
965    (set_attr "arch" "t2,t2,*,*,*")
966    (set_attr "predicable_short_it" "yes,yes,no,no,no")
967    (set_attr "length" "2,2,4,4,4")
968    (set_attr "type" "alus_imm,alus_sreg,alus_imm,alus_imm,alus_sreg")]
971 (define_insn "*compare_addsi2_op1"
972   [(set (reg:CC_C CC_REGNUM)
973         (compare:CC_C
974           (plus:SI (match_operand:SI 0 "s_register_operand" "l,l,r,r,r")
975                    (match_operand:SI 1 "arm_add_operand" "Pv,l,I,L,r"))
976           (match_dup 1)))]
977   "TARGET_32BIT"
978   "@
979    cmp%?\\t%0, #%n1
980    cmn%?\\t%0, %1
981    cmn%?\\t%0, %1
982    cmp%?\\t%0, #%n1
983    cmn%?\\t%0, %1"
984   [(set_attr "conds" "set")
985    (set_attr "predicable" "yes")
986    (set_attr "arch" "t2,t2,*,*,*")
987    (set_attr "predicable_short_it" "yes,yes,no,no,no")
988    (set_attr "length" "2,2,4,4,4")
989    (set_attr "type" "alus_imm,alus_sreg,alus_imm,alus_imm,alus_sreg")]
992 (define_insn "*addsi3_carryin_<optab>"
993   [(set (match_operand:SI 0 "s_register_operand" "=l,r,r")
994         (plus:SI (plus:SI (match_operand:SI 1 "s_register_operand" "%l,r,r")
995                           (match_operand:SI 2 "arm_not_operand" "0,rI,K"))
996                  (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))))]
997   "TARGET_32BIT"
998   "@
999    adc%?\\t%0, %1, %2
1000    adc%?\\t%0, %1, %2
1001    sbc%?\\t%0, %1, #%B2"
1002   [(set_attr "conds" "use")
1003    (set_attr "predicable" "yes")
1004    (set_attr "arch" "t2,*,*")
1005    (set_attr "length" "4")
1006    (set_attr "predicable_short_it" "yes,no,no")
1007    (set_attr "type" "adc_reg,adc_reg,adc_imm")]
1010 (define_insn "*addsi3_carryin_alt2_<optab>"
1011   [(set (match_operand:SI 0 "s_register_operand" "=l,r,r")
1012         (plus:SI (plus:SI (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))
1013                           (match_operand:SI 1 "s_register_operand" "%l,r,r"))
1014                  (match_operand:SI 2 "arm_rhs_operand" "l,rI,K")))]
1015   "TARGET_32BIT"
1016   "@
1017    adc%?\\t%0, %1, %2
1018    adc%?\\t%0, %1, %2
1019    sbc%?\\t%0, %1, #%B2"
1020   [(set_attr "conds" "use")
1021    (set_attr "predicable" "yes")
1022    (set_attr "arch" "t2,*,*")
1023    (set_attr "length" "4")
1024    (set_attr "predicable_short_it" "yes,no,no")
1025    (set_attr "type" "adc_reg,adc_reg,adc_imm")]
1028 (define_insn "*addsi3_carryin_shift_<optab>"
1029   [(set (match_operand:SI 0 "s_register_operand" "=r")
1030         (plus:SI (plus:SI
1031                   (match_operator:SI 2 "shift_operator"
1032                     [(match_operand:SI 3 "s_register_operand" "r")
1033                      (match_operand:SI 4 "reg_or_int_operand" "rM")])
1034                   (match_operand:SI 1 "s_register_operand" "r"))
1035                  (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))))]
1036   "TARGET_32BIT"
1037   "adc%?\\t%0, %1, %3%S2"
1038   [(set_attr "conds" "use")
1039    (set_attr "predicable" "yes")
1040    (set_attr "predicable_short_it" "no")
1041    (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
1042                       (const_string "alu_shift_imm")
1043                       (const_string "alu_shift_reg")))]
1046 (define_insn "*addsi3_carryin_clobercc_<optab>"
1047   [(set (match_operand:SI 0 "s_register_operand" "=r")
1048         (plus:SI (plus:SI (match_operand:SI 1 "s_register_operand" "%r")
1049                           (match_operand:SI 2 "arm_rhs_operand" "rI"))
1050                  (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))))
1051    (clobber (reg:CC CC_REGNUM))]
1052    "TARGET_32BIT"
1053    "adcs%?\\t%0, %1, %2"
1054    [(set_attr "conds" "set")
1055     (set_attr "type" "adcs_reg")]
1058 (define_expand "subv<mode>4"
1059   [(match_operand:SIDI 0 "register_operand")
1060    (match_operand:SIDI 1 "register_operand")
1061    (match_operand:SIDI 2 "register_operand")
1062    (match_operand 3 "")]
1063   "TARGET_32BIT"
1065   emit_insn (gen_sub<mode>3_compare1 (operands[0], operands[1], operands[2]));
1066   arm_gen_unlikely_cbranch (NE, CC_Vmode, operands[3]);
1068   DONE;
1071 (define_expand "usubv<mode>4"
1072   [(match_operand:SIDI 0 "register_operand")
1073    (match_operand:SIDI 1 "register_operand")
1074    (match_operand:SIDI 2 "register_operand")
1075    (match_operand 3 "")]
1076   "TARGET_32BIT"
1078   emit_insn (gen_sub<mode>3_compare1 (operands[0], operands[1], operands[2]));
1079   arm_gen_unlikely_cbranch (LTU, CCmode, operands[3]);
1081   DONE;
1084 (define_insn_and_split "subdi3_compare1"
1085   [(set (reg:CC CC_REGNUM)
1086         (compare:CC
1087           (match_operand:DI 1 "register_operand" "r")
1088           (match_operand:DI 2 "register_operand" "r")))
1089    (set (match_operand:DI 0 "register_operand" "=&r")
1090         (minus:DI (match_dup 1) (match_dup 2)))]
1091   "TARGET_32BIT"
1092   "#"
1093   "&& reload_completed"
1094   [(parallel [(set (reg:CC CC_REGNUM)
1095                    (compare:CC (match_dup 1) (match_dup 2)))
1096               (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1097    (parallel [(set (reg:CC CC_REGNUM)
1098                    (compare:CC (match_dup 4) (match_dup 5)))
1099              (set (match_dup 3) (minus:SI (minus:SI (match_dup 4) (match_dup 5))
1100                                (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))])]
1101   {
1102     operands[3] = gen_highpart (SImode, operands[0]);
1103     operands[0] = gen_lowpart (SImode, operands[0]);
1104     operands[4] = gen_highpart (SImode, operands[1]);
1105     operands[1] = gen_lowpart (SImode, operands[1]);
1106     operands[5] = gen_highpart (SImode, operands[2]);
1107     operands[2] = gen_lowpart (SImode, operands[2]);
1108    }
1109   [(set_attr "conds" "set")
1110    (set_attr "length" "8")
1111    (set_attr "type" "multiple")]
1114 (define_insn "subsi3_compare1"
1115   [(set (reg:CC CC_REGNUM)
1116         (compare:CC
1117           (match_operand:SI 1 "register_operand" "r")
1118           (match_operand:SI 2 "register_operand" "r")))
1119    (set (match_operand:SI 0 "register_operand" "=r")
1120         (minus:SI (match_dup 1) (match_dup 2)))]
1121   "TARGET_32BIT"
1122   "subs%?\\t%0, %1, %2"
1123   [(set_attr "conds" "set")
1124    (set_attr "type" "alus_sreg")]
1127 (define_insn "*subsi3_carryin"
1128   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
1129         (minus:SI (minus:SI (match_operand:SI 1 "reg_or_int_operand" "r,I,Pz")
1130                             (match_operand:SI 2 "s_register_operand" "r,r,r"))
1131                   (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1132   "TARGET_32BIT"
1133   "@
1134    sbc%?\\t%0, %1, %2
1135    rsc%?\\t%0, %2, %1
1136    sbc%?\\t%0, %2, %2, lsl #1"
1137   [(set_attr "conds" "use")
1138    (set_attr "arch" "*,a,t2")
1139    (set_attr "predicable" "yes")
1140    (set_attr "predicable_short_it" "no")
1141    (set_attr "type" "adc_reg,adc_imm,alu_shift_imm")]
1144 (define_insn "*subsi3_carryin_const"
1145   [(set (match_operand:SI 0 "s_register_operand" "=r")
1146         (minus:SI (plus:SI (match_operand:SI 1 "s_register_operand" "r")
1147                            (match_operand:SI 2 "arm_not_immediate_operand" "K"))
1148                   (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1149   "TARGET_32BIT"
1150   "sbc\\t%0, %1, #%B2"
1151   [(set_attr "conds" "use")
1152    (set_attr "type" "adc_imm")]
1155 (define_insn "*subsi3_carryin_compare"
1156   [(set (reg:CC CC_REGNUM)
1157         (compare:CC (match_operand:SI 1 "s_register_operand" "r")
1158                     (match_operand:SI 2 "s_register_operand" "r")))
1159    (set (match_operand:SI 0 "s_register_operand" "=r")
1160         (minus:SI (minus:SI (match_dup 1)
1161                             (match_dup 2))
1162                   (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1163   "TARGET_32BIT"
1164   "sbcs\\t%0, %1, %2"
1165   [(set_attr "conds" "set")
1166    (set_attr "type" "adcs_reg")]
1169 (define_insn "*subsi3_carryin_compare_const"
1170   [(set (reg:CC CC_REGNUM)
1171         (compare:CC (match_operand:SI 1 "reg_or_int_operand" "r")
1172                     (match_operand:SI 2 "arm_not_operand" "K")))
1173    (set (match_operand:SI 0 "s_register_operand" "=r")
1174         (minus:SI (plus:SI (match_dup 1)
1175                            (match_dup 2))
1176                   (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1177   "TARGET_32BIT"
1178   "sbcs\\t%0, %1, #%B2"
1179   [(set_attr "conds" "set")
1180    (set_attr "type" "adcs_imm")]
1183 (define_insn "*subsi3_carryin_shift"
1184   [(set (match_operand:SI 0 "s_register_operand" "=r")
1185         (minus:SI (minus:SI
1186                   (match_operand:SI 1 "s_register_operand" "r")
1187                   (match_operator:SI 2 "shift_operator"
1188                    [(match_operand:SI 3 "s_register_operand" "r")
1189                     (match_operand:SI 4 "reg_or_int_operand" "rM")]))
1190                  (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1191   "TARGET_32BIT"
1192   "sbc%?\\t%0, %1, %3%S2"
1193   [(set_attr "conds" "use")
1194    (set_attr "predicable" "yes")
1195    (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
1196                       (const_string "alu_shift_imm")
1197                      (const_string "alu_shift_reg")))]
1200 (define_insn "*rsbsi3_carryin_shift"
1201   [(set (match_operand:SI 0 "s_register_operand" "=r")
1202         (minus:SI (minus:SI
1203                   (match_operator:SI 2 "shift_operator"
1204                    [(match_operand:SI 3 "s_register_operand" "r")
1205                     (match_operand:SI 4 "reg_or_int_operand" "rM")])
1206                    (match_operand:SI 1 "s_register_operand" "r"))
1207                  (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1208   "TARGET_ARM"
1209   "rsc%?\\t%0, %1, %3%S2"
1210   [(set_attr "conds" "use")
1211    (set_attr "predicable" "yes")
1212    (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
1213                       (const_string "alu_shift_imm")
1214                       (const_string "alu_shift_reg")))]
1217 ; transform ((x << y) - 1) to ~(~(x-1) << y)  Where X is a constant.
1218 (define_split
1219   [(set (match_operand:SI 0 "s_register_operand" "")
1220         (plus:SI (ashift:SI (match_operand:SI 1 "const_int_operand" "")
1221                             (match_operand:SI 2 "s_register_operand" ""))
1222                  (const_int -1)))
1223    (clobber (match_operand:SI 3 "s_register_operand" ""))]
1224   "TARGET_32BIT"
1225   [(set (match_dup 3) (match_dup 1))
1226    (set (match_dup 0) (not:SI (ashift:SI (match_dup 3) (match_dup 2))))]
1227   "
1228   operands[1] = GEN_INT (~(INTVAL (operands[1]) - 1));
1231 (define_expand "addsf3"
1232   [(set (match_operand:SF          0 "s_register_operand" "")
1233         (plus:SF (match_operand:SF 1 "s_register_operand" "")
1234                  (match_operand:SF 2 "s_register_operand" "")))]
1235   "TARGET_32BIT && TARGET_HARD_FLOAT"
1236   "
1239 (define_expand "adddf3"
1240   [(set (match_operand:DF          0 "s_register_operand" "")
1241         (plus:DF (match_operand:DF 1 "s_register_operand" "")
1242                  (match_operand:DF 2 "s_register_operand" "")))]
1243   "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
1244   "
1247 (define_expand "subdi3"
1248  [(parallel
1249    [(set (match_operand:DI            0 "s_register_operand" "")
1250           (minus:DI (match_operand:DI 1 "s_register_operand" "")
1251                     (match_operand:DI 2 "s_register_operand" "")))
1252     (clobber (reg:CC CC_REGNUM))])]
1253   "TARGET_EITHER"
1254   "
1255   if (TARGET_THUMB1)
1256     {
1257       if (!REG_P (operands[1]))
1258         operands[1] = force_reg (DImode, operands[1]);
1259       if (!REG_P (operands[2]))
1260         operands[2] = force_reg (DImode, operands[2]);
1261      }  
1262   "
1265 (define_insn_and_split "*arm_subdi3"
1266   [(set (match_operand:DI           0 "s_register_operand" "=&r,&r,&r")
1267         (minus:DI (match_operand:DI 1 "s_register_operand" "0,r,0")
1268                   (match_operand:DI 2 "s_register_operand" "r,0,0")))
1269    (clobber (reg:CC CC_REGNUM))]
1270   "TARGET_32BIT && !TARGET_NEON"
1271   "#"  ; "subs\\t%Q0, %Q1, %Q2\;sbc\\t%R0, %R1, %R2"
1272   "&& reload_completed"
1273   [(parallel [(set (reg:CC CC_REGNUM)
1274                    (compare:CC (match_dup 1) (match_dup 2)))
1275               (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1276    (set (match_dup 3) (minus:SI (minus:SI (match_dup 4) (match_dup 5))
1277                                (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1278   {
1279     operands[3] = gen_highpart (SImode, operands[0]);
1280     operands[0] = gen_lowpart (SImode, operands[0]);
1281     operands[4] = gen_highpart (SImode, operands[1]);
1282     operands[1] = gen_lowpart (SImode, operands[1]);
1283     operands[5] = gen_highpart (SImode, operands[2]);
1284     operands[2] = gen_lowpart (SImode, operands[2]);
1285    }
1286   [(set_attr "conds" "clob")
1287    (set_attr "length" "8")
1288    (set_attr "type" "multiple")]
1291 (define_insn_and_split "*subdi_di_zesidi"
1292   [(set (match_operand:DI           0 "s_register_operand" "=&r,&r")
1293         (minus:DI (match_operand:DI 1 "s_register_operand"  "0,r")
1294                   (zero_extend:DI
1295                    (match_operand:SI 2 "s_register_operand"  "r,r"))))
1296    (clobber (reg:CC CC_REGNUM))]
1297   "TARGET_32BIT"
1298   "#"   ; "subs\\t%Q0, %Q1, %2\;sbc\\t%R0, %R1, #0"
1299   "&& reload_completed"
1300   [(parallel [(set (reg:CC CC_REGNUM)
1301                    (compare:CC (match_dup 1) (match_dup 2)))
1302               (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1303    (set (match_dup 3) (minus:SI (plus:SI (match_dup 4) (match_dup 5))
1304                                 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1305   {
1306     operands[3] = gen_highpart (SImode, operands[0]);
1307     operands[0] = gen_lowpart (SImode, operands[0]);
1308     operands[4] = gen_highpart (SImode, operands[1]);
1309     operands[1] = gen_lowpart (SImode, operands[1]);
1310     operands[5] = GEN_INT (~0);
1311    }
1312   [(set_attr "conds" "clob")
1313    (set_attr "length" "8")
1314    (set_attr "type" "multiple")]
1317 (define_insn_and_split "*subdi_di_sesidi"
1318   [(set (match_operand:DI            0 "s_register_operand" "=&r,&r")
1319         (minus:DI (match_operand:DI  1 "s_register_operand"  "0,r")
1320                   (sign_extend:DI
1321                    (match_operand:SI 2 "s_register_operand"  "r,r"))))
1322    (clobber (reg:CC CC_REGNUM))]
1323   "TARGET_32BIT"
1324   "#"   ; "subs\\t%Q0, %Q1, %2\;sbc\\t%R0, %R1, %2, asr #31"
1325   "&& reload_completed"
1326   [(parallel [(set (reg:CC CC_REGNUM)
1327                    (compare:CC (match_dup 1) (match_dup 2)))
1328               (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1329    (set (match_dup 3) (minus:SI (minus:SI (match_dup 4)
1330                                          (ashiftrt:SI (match_dup 2)
1331                                                       (const_int 31)))
1332                                 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1333   {
1334     operands[3] = gen_highpart (SImode, operands[0]);
1335     operands[0] = gen_lowpart (SImode, operands[0]);
1336     operands[4] = gen_highpart (SImode, operands[1]);
1337     operands[1] = gen_lowpart (SImode, operands[1]);
1338   }
1339   [(set_attr "conds" "clob")
1340    (set_attr "length" "8")
1341    (set_attr "type" "multiple")]
1344 (define_insn_and_split "*subdi_zesidi_di"
1345   [(set (match_operand:DI            0 "s_register_operand" "=&r,&r")
1346         (minus:DI (zero_extend:DI
1347                    (match_operand:SI 2 "s_register_operand"  "r,r"))
1348                   (match_operand:DI  1 "s_register_operand" "0,r")))
1349    (clobber (reg:CC CC_REGNUM))]
1350   "TARGET_ARM"
1351   "#"   ; "rsbs\\t%Q0, %Q1, %2\;rsc\\t%R0, %R1, #0"
1352         ; is equivalent to:
1353         ; "subs\\t%Q0, %2, %Q1\;rsc\\t%R0, %R1, #0"
1354   "&& reload_completed"
1355   [(parallel [(set (reg:CC CC_REGNUM)
1356                    (compare:CC (match_dup 2) (match_dup 1)))
1357               (set (match_dup 0) (minus:SI (match_dup 2) (match_dup 1)))])
1358    (set (match_dup 3) (minus:SI (minus:SI (const_int 0) (match_dup 4))
1359                                (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1360   {
1361     operands[3] = gen_highpart (SImode, operands[0]);
1362     operands[0] = gen_lowpart (SImode, operands[0]);
1363     operands[4] = gen_highpart (SImode, operands[1]);
1364     operands[1] = gen_lowpart (SImode, operands[1]);
1365   }
1366   [(set_attr "conds" "clob")
1367    (set_attr "length" "8")
1368    (set_attr "type" "multiple")]
1371 (define_insn_and_split "*subdi_sesidi_di"
1372   [(set (match_operand:DI            0 "s_register_operand" "=&r,&r")
1373         (minus:DI (sign_extend:DI
1374                    (match_operand:SI 2 "s_register_operand"   "r,r"))
1375                   (match_operand:DI  1 "s_register_operand"  "0,r")))
1376    (clobber (reg:CC CC_REGNUM))]
1377   "TARGET_ARM"
1378   "#"   ; "rsbs\\t%Q0, %Q1, %2\;rsc\\t%R0, %R1, %2, asr #31"
1379         ; is equivalent to:
1380         ; "subs\\t%Q0, %2, %Q1\;rsc\\t%R0, %R1, %2, asr #31"
1381   "&& reload_completed"
1382   [(parallel [(set (reg:CC CC_REGNUM)
1383                    (compare:CC (match_dup 2) (match_dup 1)))
1384               (set (match_dup 0) (minus:SI (match_dup 2) (match_dup 1)))])
1385    (set (match_dup 3) (minus:SI (minus:SI
1386                                 (ashiftrt:SI (match_dup 2)
1387                                              (const_int 31))
1388                                 (match_dup 4))
1389                                (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1390   {
1391     operands[3] = gen_highpart (SImode, operands[0]);
1392     operands[0] = gen_lowpart (SImode, operands[0]);
1393     operands[4] = gen_highpart (SImode, operands[1]);
1394     operands[1] = gen_lowpart (SImode, operands[1]);
1395   }
1396   [(set_attr "conds" "clob")
1397    (set_attr "length" "8")
1398    (set_attr "type" "multiple")]
1401 (define_insn_and_split "*subdi_zesidi_zesidi"
1402   [(set (match_operand:DI            0 "s_register_operand" "=r")
1403         (minus:DI (zero_extend:DI
1404                    (match_operand:SI 1 "s_register_operand"  "r"))
1405                   (zero_extend:DI
1406                    (match_operand:SI 2 "s_register_operand"  "r"))))
1407    (clobber (reg:CC CC_REGNUM))]
1408   "TARGET_32BIT"
1409   "#"   ; "subs\\t%Q0, %1, %2\;sbc\\t%R0, %1, %1"
1410   "&& reload_completed"
1411   [(parallel [(set (reg:CC CC_REGNUM)
1412                    (compare:CC (match_dup 1) (match_dup 2)))
1413               (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1414    (set (match_dup 3) (minus:SI (minus:SI (match_dup 1) (match_dup 1))
1415                                (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1416   {
1417        operands[3] = gen_highpart (SImode, operands[0]);
1418        operands[0] = gen_lowpart (SImode, operands[0]);
1419   }
1420   [(set_attr "conds" "clob")
1421    (set_attr "length" "8")
1422    (set_attr "type" "multiple")]
1425 (define_expand "subsi3"
1426   [(set (match_operand:SI           0 "s_register_operand" "")
1427         (minus:SI (match_operand:SI 1 "reg_or_int_operand" "")
1428                   (match_operand:SI 2 "s_register_operand" "")))]
1429   "TARGET_EITHER"
1430   "
1431   if (CONST_INT_P (operands[1]))
1432     {
1433       if (TARGET_32BIT)
1434         {
1435           if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[1]), MINUS))
1436             operands[1] = force_reg (SImode, operands[1]);
1437           else
1438             {
1439               arm_split_constant (MINUS, SImode, NULL_RTX,
1440                                   INTVAL (operands[1]), operands[0],
1441                                   operands[2],
1442                                   optimize && can_create_pseudo_p ());
1443               DONE;
1444             }
1445         }
1446       else /* TARGET_THUMB1 */
1447         operands[1] = force_reg (SImode, operands[1]);
1448     }
1449   "
1452 ; ??? Check Thumb-2 split length
1453 (define_insn_and_split "*arm_subsi3_insn"
1454   [(set (match_operand:SI           0 "s_register_operand" "=l,l ,l ,l ,r,r,r,rk,r")
1455         (minus:SI (match_operand:SI 1 "reg_or_int_operand" "l ,0 ,l ,Pz,I,r,r,k ,?n")
1456                   (match_operand:SI 2 "reg_or_int_operand" "l ,Py,Pd,l ,r,I,r,r ,r")))]
1457   "TARGET_32BIT"
1458   "@
1459    sub%?\\t%0, %1, %2
1460    sub%?\\t%0, %2
1461    sub%?\\t%0, %1, %2
1462    rsb%?\\t%0, %2, %1
1463    rsb%?\\t%0, %2, %1
1464    sub%?\\t%0, %1, %2
1465    sub%?\\t%0, %1, %2
1466    sub%?\\t%0, %1, %2
1467    #"
1468   "&& (CONST_INT_P (operands[1])
1469        && !const_ok_for_arm (INTVAL (operands[1])))"
1470   [(clobber (const_int 0))]
1471   "
1472   arm_split_constant (MINUS, SImode, curr_insn,
1473                       INTVAL (operands[1]), operands[0], operands[2], 0);
1474   DONE;
1475   "
1476   [(set_attr "length" "4,4,4,4,4,4,4,4,16")
1477    (set_attr "arch" "t2,t2,t2,t2,*,*,*,*,*")
1478    (set_attr "predicable" "yes")
1479    (set_attr "predicable_short_it" "yes,yes,yes,yes,no,no,no,no,no")
1480    (set_attr "type" "alu_sreg,alu_sreg,alu_sreg,alu_sreg,alu_imm,alu_imm,alu_sreg,alu_sreg,multiple")]
1483 (define_peephole2
1484   [(match_scratch:SI 3 "r")
1485    (set (match_operand:SI 0 "arm_general_register_operand" "")
1486         (minus:SI (match_operand:SI 1 "const_int_operand" "")
1487                   (match_operand:SI 2 "arm_general_register_operand" "")))]
1488   "TARGET_32BIT
1489    && !const_ok_for_arm (INTVAL (operands[1]))
1490    && const_ok_for_arm (~INTVAL (operands[1]))"
1491   [(set (match_dup 3) (match_dup 1))
1492    (set (match_dup 0) (minus:SI (match_dup 3) (match_dup 2)))]
1493   ""
1496 (define_insn "subsi3_compare0"
1497   [(set (reg:CC_NOOV CC_REGNUM)
1498         (compare:CC_NOOV
1499          (minus:SI (match_operand:SI 1 "arm_rhs_operand" "r,r,I")
1500                    (match_operand:SI 2 "arm_rhs_operand" "I,r,r"))
1501          (const_int 0)))
1502    (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
1503         (minus:SI (match_dup 1) (match_dup 2)))]
1504   "TARGET_32BIT"
1505   "@
1506    subs%?\\t%0, %1, %2
1507    subs%?\\t%0, %1, %2
1508    rsbs%?\\t%0, %2, %1"
1509   [(set_attr "conds" "set")
1510    (set_attr "type"  "alus_imm,alus_sreg,alus_sreg")]
1513 (define_insn "subsi3_compare"
1514   [(set (reg:CC CC_REGNUM)
1515         (compare:CC (match_operand:SI 1 "arm_rhs_operand" "r,r,I")
1516                     (match_operand:SI 2 "arm_rhs_operand" "I,r,r")))
1517    (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
1518         (minus:SI (match_dup 1) (match_dup 2)))]
1519   "TARGET_32BIT"
1520   "@
1521    subs%?\\t%0, %1, %2
1522    subs%?\\t%0, %1, %2
1523    rsbs%?\\t%0, %2, %1"
1524   [(set_attr "conds" "set")
1525    (set_attr "type" "alus_imm,alus_sreg,alus_sreg")]
1528 (define_expand "subsf3"
1529   [(set (match_operand:SF           0 "s_register_operand" "")
1530         (minus:SF (match_operand:SF 1 "s_register_operand" "")
1531                   (match_operand:SF 2 "s_register_operand" "")))]
1532   "TARGET_32BIT && TARGET_HARD_FLOAT"
1533   "
1536 (define_expand "subdf3"
1537   [(set (match_operand:DF           0 "s_register_operand" "")
1538         (minus:DF (match_operand:DF 1 "s_register_operand" "")
1539                   (match_operand:DF 2 "s_register_operand" "")))]
1540   "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
1541   "
1545 ;; Multiplication insns
1547 (define_expand "mulhi3"
1548   [(set (match_operand:HI 0 "s_register_operand" "")
1549         (mult:HI (match_operand:HI 1 "s_register_operand" "")
1550                  (match_operand:HI 2 "s_register_operand" "")))]
1551   "TARGET_DSP_MULTIPLY"
1552   "
1553   {
1554     rtx result = gen_reg_rtx (SImode);
1555     emit_insn (gen_mulhisi3 (result, operands[1], operands[2]));
1556     emit_move_insn (operands[0], gen_lowpart (HImode, result));
1557     DONE;
1558   }"
1561 (define_expand "mulsi3"
1562   [(set (match_operand:SI          0 "s_register_operand" "")
1563         (mult:SI (match_operand:SI 2 "s_register_operand" "")
1564                  (match_operand:SI 1 "s_register_operand" "")))]
1565   "TARGET_EITHER"
1566   ""
1569 ;; Use `&' and then `0' to prevent the operands 0 and 1 being the same
1570 (define_insn "*arm_mulsi3"
1571   [(set (match_operand:SI          0 "s_register_operand" "=&r,&r")
1572         (mult:SI (match_operand:SI 2 "s_register_operand" "r,r")
1573                  (match_operand:SI 1 "s_register_operand" "%0,r")))]
1574   "TARGET_32BIT && !arm_arch6"
1575   "mul%?\\t%0, %2, %1"
1576   [(set_attr "type" "mul")
1577    (set_attr "predicable" "yes")]
1580 (define_insn "*arm_mulsi3_v6"
1581   [(set (match_operand:SI          0 "s_register_operand" "=l,l,r")
1582         (mult:SI (match_operand:SI 1 "s_register_operand" "0,l,r")
1583                  (match_operand:SI 2 "s_register_operand" "l,0,r")))]
1584   "TARGET_32BIT && arm_arch6"
1585   "mul%?\\t%0, %1, %2"
1586   [(set_attr "type" "mul")
1587    (set_attr "predicable" "yes")
1588    (set_attr "arch" "t2,t2,*")
1589    (set_attr "length" "4")
1590    (set_attr "predicable_short_it" "yes,yes,no")]
1593 (define_insn "*mulsi3_compare0"
1594   [(set (reg:CC_NOOV CC_REGNUM)
1595         (compare:CC_NOOV (mult:SI
1596                           (match_operand:SI 2 "s_register_operand" "r,r")
1597                           (match_operand:SI 1 "s_register_operand" "%0,r"))
1598                          (const_int 0)))
1599    (set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1600         (mult:SI (match_dup 2) (match_dup 1)))]
1601   "TARGET_ARM && !arm_arch6"
1602   "muls%?\\t%0, %2, %1"
1603   [(set_attr "conds" "set")
1604    (set_attr "type" "muls")]
1607 (define_insn "*mulsi3_compare0_v6"
1608   [(set (reg:CC_NOOV CC_REGNUM)
1609         (compare:CC_NOOV (mult:SI
1610                           (match_operand:SI 2 "s_register_operand" "r")
1611                           (match_operand:SI 1 "s_register_operand" "r"))
1612                          (const_int 0)))
1613    (set (match_operand:SI 0 "s_register_operand" "=r")
1614         (mult:SI (match_dup 2) (match_dup 1)))]
1615   "TARGET_ARM && arm_arch6 && optimize_size"
1616   "muls%?\\t%0, %2, %1"
1617   [(set_attr "conds" "set")
1618    (set_attr "type" "muls")]
1621 (define_insn "*mulsi_compare0_scratch"
1622   [(set (reg:CC_NOOV CC_REGNUM)
1623         (compare:CC_NOOV (mult:SI
1624                           (match_operand:SI 2 "s_register_operand" "r,r")
1625                           (match_operand:SI 1 "s_register_operand" "%0,r"))
1626                          (const_int 0)))
1627    (clobber (match_scratch:SI 0 "=&r,&r"))]
1628   "TARGET_ARM && !arm_arch6"
1629   "muls%?\\t%0, %2, %1"
1630   [(set_attr "conds" "set")
1631    (set_attr "type" "muls")]
1634 (define_insn "*mulsi_compare0_scratch_v6"
1635   [(set (reg:CC_NOOV CC_REGNUM)
1636         (compare:CC_NOOV (mult:SI
1637                           (match_operand:SI 2 "s_register_operand" "r")
1638                           (match_operand:SI 1 "s_register_operand" "r"))
1639                          (const_int 0)))
1640    (clobber (match_scratch:SI 0 "=r"))]
1641   "TARGET_ARM && arm_arch6 && optimize_size"
1642   "muls%?\\t%0, %2, %1"
1643   [(set_attr "conds" "set")
1644    (set_attr "type" "muls")]
1647 ;; Unnamed templates to match MLA instruction.
1649 (define_insn "*mulsi3addsi"
1650   [(set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r,&r")
1651         (plus:SI
1652           (mult:SI (match_operand:SI 2 "s_register_operand" "r,r,r,r")
1653                    (match_operand:SI 1 "s_register_operand" "%0,r,0,r"))
1654           (match_operand:SI 3 "s_register_operand" "r,r,0,0")))]
1655   "TARGET_32BIT && !arm_arch6"
1656   "mla%?\\t%0, %2, %1, %3"
1657   [(set_attr "type" "mla")
1658    (set_attr "predicable" "yes")]
1661 (define_insn "*mulsi3addsi_v6"
1662   [(set (match_operand:SI 0 "s_register_operand" "=r")
1663         (plus:SI
1664           (mult:SI (match_operand:SI 2 "s_register_operand" "r")
1665                    (match_operand:SI 1 "s_register_operand" "r"))
1666           (match_operand:SI 3 "s_register_operand" "r")))]
1667   "TARGET_32BIT && arm_arch6"
1668   "mla%?\\t%0, %2, %1, %3"
1669   [(set_attr "type" "mla")
1670    (set_attr "predicable" "yes")
1671    (set_attr "predicable_short_it" "no")]
1674 (define_insn "*mulsi3addsi_compare0"
1675   [(set (reg:CC_NOOV CC_REGNUM)
1676         (compare:CC_NOOV
1677          (plus:SI (mult:SI
1678                    (match_operand:SI 2 "s_register_operand" "r,r,r,r")
1679                    (match_operand:SI 1 "s_register_operand" "%0,r,0,r"))
1680                   (match_operand:SI 3 "s_register_operand" "r,r,0,0"))
1681          (const_int 0)))
1682    (set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r,&r")
1683         (plus:SI (mult:SI (match_dup 2) (match_dup 1))
1684                  (match_dup 3)))]
1685   "TARGET_ARM && arm_arch6"
1686   "mlas%?\\t%0, %2, %1, %3"
1687   [(set_attr "conds" "set")
1688    (set_attr "type" "mlas")]
1691 (define_insn "*mulsi3addsi_compare0_v6"
1692   [(set (reg:CC_NOOV CC_REGNUM)
1693         (compare:CC_NOOV
1694          (plus:SI (mult:SI
1695                    (match_operand:SI 2 "s_register_operand" "r")
1696                    (match_operand:SI 1 "s_register_operand" "r"))
1697                   (match_operand:SI 3 "s_register_operand" "r"))
1698          (const_int 0)))
1699    (set (match_operand:SI 0 "s_register_operand" "=r")
1700         (plus:SI (mult:SI (match_dup 2) (match_dup 1))
1701                  (match_dup 3)))]
1702   "TARGET_ARM && arm_arch6 && optimize_size"
1703   "mlas%?\\t%0, %2, %1, %3"
1704   [(set_attr "conds" "set")
1705    (set_attr "type" "mlas")]
1708 (define_insn "*mulsi3addsi_compare0_scratch"
1709   [(set (reg:CC_NOOV CC_REGNUM)
1710         (compare:CC_NOOV
1711          (plus:SI (mult:SI
1712                    (match_operand:SI 2 "s_register_operand" "r,r,r,r")
1713                    (match_operand:SI 1 "s_register_operand" "%0,r,0,r"))
1714                   (match_operand:SI 3 "s_register_operand" "?r,r,0,0"))
1715          (const_int 0)))
1716    (clobber (match_scratch:SI 0 "=&r,&r,&r,&r"))]
1717   "TARGET_ARM && !arm_arch6"
1718   "mlas%?\\t%0, %2, %1, %3"
1719   [(set_attr "conds" "set")
1720    (set_attr "type" "mlas")]
1723 (define_insn "*mulsi3addsi_compare0_scratch_v6"
1724   [(set (reg:CC_NOOV CC_REGNUM)
1725         (compare:CC_NOOV
1726          (plus:SI (mult:SI
1727                    (match_operand:SI 2 "s_register_operand" "r")
1728                    (match_operand:SI 1 "s_register_operand" "r"))
1729                   (match_operand:SI 3 "s_register_operand" "r"))
1730          (const_int 0)))
1731    (clobber (match_scratch:SI 0 "=r"))]
1732   "TARGET_ARM && arm_arch6 && optimize_size"
1733   "mlas%?\\t%0, %2, %1, %3"
1734   [(set_attr "conds" "set")
1735    (set_attr "type" "mlas")]
1738 (define_insn "*mulsi3subsi"
1739   [(set (match_operand:SI 0 "s_register_operand" "=r")
1740         (minus:SI
1741           (match_operand:SI 3 "s_register_operand" "r")
1742           (mult:SI (match_operand:SI 2 "s_register_operand" "r")
1743                    (match_operand:SI 1 "s_register_operand" "r"))))]
1744   "TARGET_32BIT && arm_arch_thumb2"
1745   "mls%?\\t%0, %2, %1, %3"
1746   [(set_attr "type" "mla")
1747    (set_attr "predicable" "yes")
1748    (set_attr "predicable_short_it" "no")]
1751 (define_expand "maddsidi4"
1752   [(set (match_operand:DI 0 "s_register_operand" "")
1753         (plus:DI
1754          (mult:DI
1755           (sign_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1756           (sign_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1757          (match_operand:DI 3 "s_register_operand" "")))]
1758   "TARGET_32BIT && arm_arch3m"
1759   "")
1761 (define_insn "*mulsidi3adddi"
1762   [(set (match_operand:DI 0 "s_register_operand" "=&r")
1763         (plus:DI
1764          (mult:DI
1765           (sign_extend:DI (match_operand:SI 2 "s_register_operand" "%r"))
1766           (sign_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1767          (match_operand:DI 1 "s_register_operand" "0")))]
1768   "TARGET_32BIT && arm_arch3m && !arm_arch6"
1769   "smlal%?\\t%Q0, %R0, %3, %2"
1770   [(set_attr "type" "smlal")
1771    (set_attr "predicable" "yes")]
1774 (define_insn "*mulsidi3adddi_v6"
1775   [(set (match_operand:DI 0 "s_register_operand" "=r")
1776         (plus:DI
1777          (mult:DI
1778           (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r"))
1779           (sign_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1780          (match_operand:DI 1 "s_register_operand" "0")))]
1781   "TARGET_32BIT && arm_arch6"
1782   "smlal%?\\t%Q0, %R0, %3, %2"
1783   [(set_attr "type" "smlal")
1784    (set_attr "predicable" "yes")
1785    (set_attr "predicable_short_it" "no")]
1788 ;; 32x32->64 widening multiply.
1789 ;; As with mulsi3, the only difference between the v3-5 and v6+
1790 ;; versions of these patterns is the requirement that the output not
1791 ;; overlap the inputs, but that still means we have to have a named
1792 ;; expander and two different starred insns.
1794 (define_expand "mulsidi3"
1795   [(set (match_operand:DI 0 "s_register_operand" "")
1796         (mult:DI
1797          (sign_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1798          (sign_extend:DI (match_operand:SI 2 "s_register_operand" ""))))]
1799   "TARGET_32BIT && arm_arch3m"
1800   ""
1803 (define_insn "*mulsidi3_nov6"
1804   [(set (match_operand:DI 0 "s_register_operand" "=&r")
1805         (mult:DI
1806          (sign_extend:DI (match_operand:SI 1 "s_register_operand" "%r"))
1807          (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1808   "TARGET_32BIT && arm_arch3m && !arm_arch6"
1809   "smull%?\\t%Q0, %R0, %1, %2"
1810   [(set_attr "type" "smull")
1811    (set_attr "predicable" "yes")]
1814 (define_insn "*mulsidi3_v6"
1815   [(set (match_operand:DI 0 "s_register_operand" "=r")
1816         (mult:DI
1817          (sign_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1818          (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1819   "TARGET_32BIT && arm_arch6"
1820   "smull%?\\t%Q0, %R0, %1, %2"
1821   [(set_attr "type" "smull")
1822    (set_attr "predicable" "yes")
1823    (set_attr "predicable_short_it" "no")]
1826 (define_expand "umulsidi3"
1827   [(set (match_operand:DI 0 "s_register_operand" "")
1828         (mult:DI
1829          (zero_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1830          (zero_extend:DI (match_operand:SI 2 "s_register_operand" ""))))]
1831   "TARGET_32BIT && arm_arch3m"
1832   ""
1835 (define_insn "*umulsidi3_nov6"
1836   [(set (match_operand:DI 0 "s_register_operand" "=&r")
1837         (mult:DI
1838          (zero_extend:DI (match_operand:SI 1 "s_register_operand" "%r"))
1839          (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1840   "TARGET_32BIT && arm_arch3m && !arm_arch6"
1841   "umull%?\\t%Q0, %R0, %1, %2"
1842   [(set_attr "type" "umull")
1843    (set_attr "predicable" "yes")]
1846 (define_insn "*umulsidi3_v6"
1847   [(set (match_operand:DI 0 "s_register_operand" "=r")
1848         (mult:DI
1849          (zero_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1850          (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1851   "TARGET_32BIT && arm_arch6"
1852   "umull%?\\t%Q0, %R0, %1, %2"
1853   [(set_attr "type" "umull")
1854    (set_attr "predicable" "yes")
1855    (set_attr "predicable_short_it" "no")]
1858 (define_expand "umaddsidi4"
1859   [(set (match_operand:DI 0 "s_register_operand" "")
1860         (plus:DI
1861          (mult:DI
1862           (zero_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1863           (zero_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1864          (match_operand:DI 3 "s_register_operand" "")))]
1865   "TARGET_32BIT && arm_arch3m"
1866   "")
1868 (define_insn "*umulsidi3adddi"
1869   [(set (match_operand:DI 0 "s_register_operand" "=&r")
1870         (plus:DI
1871          (mult:DI
1872           (zero_extend:DI (match_operand:SI 2 "s_register_operand" "%r"))
1873           (zero_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1874          (match_operand:DI 1 "s_register_operand" "0")))]
1875   "TARGET_32BIT && arm_arch3m && !arm_arch6"
1876   "umlal%?\\t%Q0, %R0, %3, %2"
1877   [(set_attr "type" "umlal")
1878    (set_attr "predicable" "yes")]
1881 (define_insn "*umulsidi3adddi_v6"
1882   [(set (match_operand:DI 0 "s_register_operand" "=r")
1883         (plus:DI
1884          (mult:DI
1885           (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r"))
1886           (zero_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1887          (match_operand:DI 1 "s_register_operand" "0")))]
1888   "TARGET_32BIT && arm_arch6"
1889   "umlal%?\\t%Q0, %R0, %3, %2"
1890   [(set_attr "type" "umlal")
1891    (set_attr "predicable" "yes")
1892    (set_attr "predicable_short_it" "no")]
1895 (define_expand "smulsi3_highpart"
1896   [(parallel
1897     [(set (match_operand:SI 0 "s_register_operand" "")
1898           (truncate:SI
1899            (lshiftrt:DI
1900             (mult:DI
1901              (sign_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1902              (sign_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1903             (const_int 32))))
1904      (clobber (match_scratch:SI 3 ""))])]
1905   "TARGET_32BIT && arm_arch3m"
1906   ""
1909 (define_insn "*smulsi3_highpart_nov6"
1910   [(set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1911         (truncate:SI
1912          (lshiftrt:DI
1913           (mult:DI
1914            (sign_extend:DI (match_operand:SI 1 "s_register_operand" "%0,r"))
1915            (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r,r")))
1916           (const_int 32))))
1917    (clobber (match_scratch:SI 3 "=&r,&r"))]
1918   "TARGET_32BIT && arm_arch3m && !arm_arch6"
1919   "smull%?\\t%3, %0, %2, %1"
1920   [(set_attr "type" "smull")
1921    (set_attr "predicable" "yes")]
1924 (define_insn "*smulsi3_highpart_v6"
1925   [(set (match_operand:SI 0 "s_register_operand" "=r")
1926         (truncate:SI
1927          (lshiftrt:DI
1928           (mult:DI
1929            (sign_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1930            (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r")))
1931           (const_int 32))))
1932    (clobber (match_scratch:SI 3 "=r"))]
1933   "TARGET_32BIT && arm_arch6"
1934   "smull%?\\t%3, %0, %2, %1"
1935   [(set_attr "type" "smull")
1936    (set_attr "predicable" "yes")
1937    (set_attr "predicable_short_it" "no")]
1940 (define_expand "umulsi3_highpart"
1941   [(parallel
1942     [(set (match_operand:SI 0 "s_register_operand" "")
1943           (truncate:SI
1944            (lshiftrt:DI
1945             (mult:DI
1946              (zero_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1947               (zero_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1948             (const_int 32))))
1949      (clobber (match_scratch:SI 3 ""))])]
1950   "TARGET_32BIT && arm_arch3m"
1951   ""
1954 (define_insn "*umulsi3_highpart_nov6"
1955   [(set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1956         (truncate:SI
1957          (lshiftrt:DI
1958           (mult:DI
1959            (zero_extend:DI (match_operand:SI 1 "s_register_operand" "%0,r"))
1960            (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r,r")))
1961           (const_int 32))))
1962    (clobber (match_scratch:SI 3 "=&r,&r"))]
1963   "TARGET_32BIT && arm_arch3m && !arm_arch6"
1964   "umull%?\\t%3, %0, %2, %1"
1965   [(set_attr "type" "umull")
1966    (set_attr "predicable" "yes")]
1969 (define_insn "*umulsi3_highpart_v6"
1970   [(set (match_operand:SI 0 "s_register_operand" "=r")
1971         (truncate:SI
1972          (lshiftrt:DI
1973           (mult:DI
1974            (zero_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1975            (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r")))
1976           (const_int 32))))
1977    (clobber (match_scratch:SI 3 "=r"))]
1978   "TARGET_32BIT && arm_arch6"
1979   "umull%?\\t%3, %0, %2, %1"
1980   [(set_attr "type" "umull")
1981    (set_attr "predicable" "yes")
1982    (set_attr "predicable_short_it" "no")]
1985 (define_insn "mulhisi3"
1986   [(set (match_operand:SI 0 "s_register_operand" "=r")
1987         (mult:SI (sign_extend:SI
1988                   (match_operand:HI 1 "s_register_operand" "%r"))
1989                  (sign_extend:SI
1990                   (match_operand:HI 2 "s_register_operand" "r"))))]
1991   "TARGET_DSP_MULTIPLY"
1992   "smulbb%?\\t%0, %1, %2"
1993   [(set_attr "type" "smulxy")
1994    (set_attr "predicable" "yes")]
1997 (define_insn "*mulhisi3tb"
1998   [(set (match_operand:SI 0 "s_register_operand" "=r")
1999         (mult:SI (ashiftrt:SI
2000                   (match_operand:SI 1 "s_register_operand" "r")
2001                   (const_int 16))
2002                  (sign_extend:SI
2003                   (match_operand:HI 2 "s_register_operand" "r"))))]
2004   "TARGET_DSP_MULTIPLY"
2005   "smultb%?\\t%0, %1, %2"
2006   [(set_attr "type" "smulxy")
2007    (set_attr "predicable" "yes")
2008    (set_attr "predicable_short_it" "no")]
2011 (define_insn "*mulhisi3bt"
2012   [(set (match_operand:SI 0 "s_register_operand" "=r")
2013         (mult:SI (sign_extend:SI
2014                   (match_operand:HI 1 "s_register_operand" "r"))
2015                  (ashiftrt:SI
2016                   (match_operand:SI 2 "s_register_operand" "r")
2017                   (const_int 16))))]
2018   "TARGET_DSP_MULTIPLY"
2019   "smulbt%?\\t%0, %1, %2"
2020   [(set_attr "type" "smulxy")
2021    (set_attr "predicable" "yes")
2022    (set_attr "predicable_short_it" "no")]
2025 (define_insn "*mulhisi3tt"
2026   [(set (match_operand:SI 0 "s_register_operand" "=r")
2027         (mult:SI (ashiftrt:SI
2028                   (match_operand:SI 1 "s_register_operand" "r")
2029                   (const_int 16))
2030                  (ashiftrt:SI
2031                   (match_operand:SI 2 "s_register_operand" "r")
2032                   (const_int 16))))]
2033   "TARGET_DSP_MULTIPLY"
2034   "smultt%?\\t%0, %1, %2"
2035   [(set_attr "type" "smulxy")
2036    (set_attr "predicable" "yes")
2037    (set_attr "predicable_short_it" "no")]
2040 (define_insn "maddhisi4"
2041   [(set (match_operand:SI 0 "s_register_operand" "=r")
2042         (plus:SI (mult:SI (sign_extend:SI
2043                            (match_operand:HI 1 "s_register_operand" "r"))
2044                           (sign_extend:SI
2045                            (match_operand:HI 2 "s_register_operand" "r")))
2046                  (match_operand:SI 3 "s_register_operand" "r")))]
2047   "TARGET_DSP_MULTIPLY"
2048   "smlabb%?\\t%0, %1, %2, %3"
2049   [(set_attr "type" "smlaxy")
2050    (set_attr "predicable" "yes")
2051    (set_attr "predicable_short_it" "no")]
2054 ;; Note: there is no maddhisi4ibt because this one is canonical form
2055 (define_insn "*maddhisi4tb"
2056   [(set (match_operand:SI 0 "s_register_operand" "=r")
2057         (plus:SI (mult:SI (ashiftrt:SI
2058                            (match_operand:SI 1 "s_register_operand" "r")
2059                            (const_int 16))
2060                           (sign_extend:SI
2061                            (match_operand:HI 2 "s_register_operand" "r")))
2062                  (match_operand:SI 3 "s_register_operand" "r")))]
2063   "TARGET_DSP_MULTIPLY"
2064   "smlatb%?\\t%0, %1, %2, %3"
2065   [(set_attr "type" "smlaxy")
2066    (set_attr "predicable" "yes")
2067    (set_attr "predicable_short_it" "no")]
2070 (define_insn "*maddhisi4tt"
2071   [(set (match_operand:SI 0 "s_register_operand" "=r")
2072         (plus:SI (mult:SI (ashiftrt:SI
2073                            (match_operand:SI 1 "s_register_operand" "r")
2074                            (const_int 16))
2075                           (ashiftrt:SI
2076                            (match_operand:SI 2 "s_register_operand" "r")
2077                            (const_int 16)))
2078                  (match_operand:SI 3 "s_register_operand" "r")))]
2079   "TARGET_DSP_MULTIPLY"
2080   "smlatt%?\\t%0, %1, %2, %3"
2081   [(set_attr "type" "smlaxy")
2082    (set_attr "predicable" "yes")
2083    (set_attr "predicable_short_it" "no")]
2086 (define_insn "maddhidi4"
2087   [(set (match_operand:DI 0 "s_register_operand" "=r")
2088         (plus:DI
2089           (mult:DI (sign_extend:DI
2090                     (match_operand:HI 1 "s_register_operand" "r"))
2091                    (sign_extend:DI
2092                     (match_operand:HI 2 "s_register_operand" "r")))
2093           (match_operand:DI 3 "s_register_operand" "0")))]
2094   "TARGET_DSP_MULTIPLY"
2095   "smlalbb%?\\t%Q0, %R0, %1, %2"
2096   [(set_attr "type" "smlalxy")
2097    (set_attr "predicable" "yes")
2098    (set_attr "predicable_short_it" "no")])
2100 ;; Note: there is no maddhidi4ibt because this one is canonical form
2101 (define_insn "*maddhidi4tb"
2102   [(set (match_operand:DI 0 "s_register_operand" "=r")
2103         (plus:DI
2104           (mult:DI (sign_extend:DI
2105                     (ashiftrt:SI
2106                      (match_operand:SI 1 "s_register_operand" "r")
2107                      (const_int 16)))
2108                    (sign_extend:DI
2109                     (match_operand:HI 2 "s_register_operand" "r")))
2110           (match_operand:DI 3 "s_register_operand" "0")))]
2111   "TARGET_DSP_MULTIPLY"
2112   "smlaltb%?\\t%Q0, %R0, %1, %2"
2113   [(set_attr "type" "smlalxy")
2114    (set_attr "predicable" "yes")
2115    (set_attr "predicable_short_it" "no")])
2117 (define_insn "*maddhidi4tt"
2118   [(set (match_operand:DI 0 "s_register_operand" "=r")
2119         (plus:DI
2120           (mult:DI (sign_extend:DI
2121                     (ashiftrt:SI
2122                      (match_operand:SI 1 "s_register_operand" "r")
2123                      (const_int 16)))
2124                    (sign_extend:DI
2125                     (ashiftrt:SI
2126                      (match_operand:SI 2 "s_register_operand" "r")
2127                      (const_int 16))))
2128           (match_operand:DI 3 "s_register_operand" "0")))]
2129   "TARGET_DSP_MULTIPLY"
2130   "smlaltt%?\\t%Q0, %R0, %1, %2"
2131   [(set_attr "type" "smlalxy")
2132    (set_attr "predicable" "yes")
2133    (set_attr "predicable_short_it" "no")])
2135 (define_expand "mulsf3"
2136   [(set (match_operand:SF          0 "s_register_operand" "")
2137         (mult:SF (match_operand:SF 1 "s_register_operand" "")
2138                  (match_operand:SF 2 "s_register_operand" "")))]
2139   "TARGET_32BIT && TARGET_HARD_FLOAT"
2140   "
2143 (define_expand "muldf3"
2144   [(set (match_operand:DF          0 "s_register_operand" "")
2145         (mult:DF (match_operand:DF 1 "s_register_operand" "")
2146                  (match_operand:DF 2 "s_register_operand" "")))]
2147   "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
2148   "
2151 ;; Division insns
2153 (define_expand "divsf3"
2154   [(set (match_operand:SF 0 "s_register_operand" "")
2155         (div:SF (match_operand:SF 1 "s_register_operand" "")
2156                 (match_operand:SF 2 "s_register_operand" "")))]
2157   "TARGET_32BIT && TARGET_HARD_FLOAT"
2158   "")
2160 (define_expand "divdf3"
2161   [(set (match_operand:DF 0 "s_register_operand" "")
2162         (div:DF (match_operand:DF 1 "s_register_operand" "")
2163                 (match_operand:DF 2 "s_register_operand" "")))]
2164   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
2165   "")
2167 ;; Boolean and,ior,xor insns
2169 ;; Split up double word logical operations
2171 ;; Split up simple DImode logical operations.  Simply perform the logical
2172 ;; operation on the upper and lower halves of the registers.
2173 (define_split
2174   [(set (match_operand:DI 0 "s_register_operand" "")
2175         (match_operator:DI 6 "logical_binary_operator"
2176           [(match_operand:DI 1 "s_register_operand" "")
2177            (match_operand:DI 2 "s_register_operand" "")]))]
2178   "TARGET_32BIT && reload_completed
2179    && ! (TARGET_NEON && IS_VFP_REGNUM (REGNO (operands[0])))
2180    && ! IS_IWMMXT_REGNUM (REGNO (operands[0]))"
2181   [(set (match_dup 0) (match_op_dup:SI 6 [(match_dup 1) (match_dup 2)]))
2182    (set (match_dup 3) (match_op_dup:SI 6 [(match_dup 4) (match_dup 5)]))]
2183   "
2184   {
2185     operands[3] = gen_highpart (SImode, operands[0]);
2186     operands[0] = gen_lowpart (SImode, operands[0]);
2187     operands[4] = gen_highpart (SImode, operands[1]);
2188     operands[1] = gen_lowpart (SImode, operands[1]);
2189     operands[5] = gen_highpart (SImode, operands[2]);
2190     operands[2] = gen_lowpart (SImode, operands[2]);
2191   }"
2194 (define_split
2195   [(set (match_operand:DI 0 "s_register_operand" "")
2196         (match_operator:DI 6 "logical_binary_operator"
2197           [(sign_extend:DI (match_operand:SI 2 "s_register_operand" ""))
2198            (match_operand:DI 1 "s_register_operand" "")]))]
2199   "TARGET_32BIT && reload_completed"
2200   [(set (match_dup 0) (match_op_dup:SI 6 [(match_dup 1) (match_dup 2)]))
2201    (set (match_dup 3) (match_op_dup:SI 6
2202                         [(ashiftrt:SI (match_dup 2) (const_int 31))
2203                          (match_dup 4)]))]
2204   "
2205   {
2206     operands[3] = gen_highpart (SImode, operands[0]);
2207     operands[0] = gen_lowpart (SImode, operands[0]);
2208     operands[4] = gen_highpart (SImode, operands[1]);
2209     operands[1] = gen_lowpart (SImode, operands[1]);
2210     operands[5] = gen_highpart (SImode, operands[2]);
2211     operands[2] = gen_lowpart (SImode, operands[2]);
2212   }"
2215 ;; The zero extend of operand 2 means we can just copy the high part of
2216 ;; operand1 into operand0.
2217 (define_split
2218   [(set (match_operand:DI 0 "s_register_operand" "")
2219         (ior:DI
2220           (zero_extend:DI (match_operand:SI 2 "s_register_operand" ""))
2221           (match_operand:DI 1 "s_register_operand" "")))]
2222   "TARGET_32BIT && operands[0] != operands[1] && reload_completed"
2223   [(set (match_dup 0) (ior:SI (match_dup 1) (match_dup 2)))
2224    (set (match_dup 3) (match_dup 4))]
2225   "
2226   {
2227     operands[4] = gen_highpart (SImode, operands[1]);
2228     operands[3] = gen_highpart (SImode, operands[0]);
2229     operands[0] = gen_lowpart (SImode, operands[0]);
2230     operands[1] = gen_lowpart (SImode, operands[1]);
2231   }"
2234 ;; The zero extend of operand 2 means we can just copy the high part of
2235 ;; operand1 into operand0.
2236 (define_split
2237   [(set (match_operand:DI 0 "s_register_operand" "")
2238         (xor:DI
2239           (zero_extend:DI (match_operand:SI 2 "s_register_operand" ""))
2240           (match_operand:DI 1 "s_register_operand" "")))]
2241   "TARGET_32BIT && operands[0] != operands[1] && reload_completed"
2242   [(set (match_dup 0) (xor:SI (match_dup 1) (match_dup 2)))
2243    (set (match_dup 3) (match_dup 4))]
2244   "
2245   {
2246     operands[4] = gen_highpart (SImode, operands[1]);
2247     operands[3] = gen_highpart (SImode, operands[0]);
2248     operands[0] = gen_lowpart (SImode, operands[0]);
2249     operands[1] = gen_lowpart (SImode, operands[1]);
2250   }"
2253 (define_expand "anddi3"
2254   [(set (match_operand:DI         0 "s_register_operand" "")
2255         (and:DI (match_operand:DI 1 "s_register_operand" "")
2256                 (match_operand:DI 2 "neon_inv_logic_op2" "")))]
2257   "TARGET_32BIT"
2258   ""
2261 (define_insn_and_split "*anddi3_insn"
2262   [(set (match_operand:DI         0 "s_register_operand"     "=w,w ,&r,&r,&r,&r,?w,?w")
2263         (and:DI (match_operand:DI 1 "s_register_operand"     "%w,0 ,0 ,r ,0 ,r ,w ,0")
2264                 (match_operand:DI 2 "arm_anddi_operand_neon" "w ,DL,r ,r ,De,De,w ,DL")))]
2265   "TARGET_32BIT && !TARGET_IWMMXT"
2267   switch (which_alternative)
2268     {
2269     case 0: /* fall through */
2270     case 6: return "vand\t%P0, %P1, %P2";
2271     case 1: /* fall through */
2272     case 7: return neon_output_logic_immediate ("vand", &operands[2],
2273                     DImode, 1, VALID_NEON_QREG_MODE (DImode));
2274     case 2:
2275     case 3:
2276     case 4:
2277     case 5: /* fall through */
2278       return "#";
2279     default: gcc_unreachable ();
2280     }
2282   "TARGET_32BIT && !TARGET_IWMMXT && reload_completed
2283    && !(IS_VFP_REGNUM (REGNO (operands[0])))"
2284   [(set (match_dup 3) (match_dup 4))
2285    (set (match_dup 5) (match_dup 6))]
2286   "
2287   {
2288     operands[3] = gen_lowpart (SImode, operands[0]);
2289     operands[5] = gen_highpart (SImode, operands[0]);
2291     operands[4] = simplify_gen_binary (AND, SImode,
2292                                            gen_lowpart (SImode, operands[1]),
2293                                            gen_lowpart (SImode, operands[2]));
2294     operands[6] = simplify_gen_binary (AND, SImode,
2295                                            gen_highpart (SImode, operands[1]),
2296                                            gen_highpart_mode (SImode, DImode, operands[2]));
2298   }"
2299   [(set_attr "type" "neon_logic,neon_logic,multiple,multiple,\
2300                      multiple,multiple,neon_logic,neon_logic")
2301    (set_attr "arch" "neon_for_64bits,neon_for_64bits,*,*,*,*,
2302                      avoid_neon_for_64bits,avoid_neon_for_64bits")
2303    (set_attr "length" "*,*,8,8,8,8,*,*")
2304   ]
2307 (define_insn_and_split "*anddi_zesidi_di"
2308   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2309         (and:DI (zero_extend:DI
2310                  (match_operand:SI 2 "s_register_operand" "r,r"))
2311                 (match_operand:DI 1 "s_register_operand" "0,r")))]
2312   "TARGET_32BIT"
2313   "#"
2314   "TARGET_32BIT && reload_completed"
2315   ; The zero extend of operand 2 clears the high word of the output
2316   ; operand.
2317   [(set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))
2318    (set (match_dup 3) (const_int 0))]
2319   "
2320   {
2321     operands[3] = gen_highpart (SImode, operands[0]);
2322     operands[0] = gen_lowpart (SImode, operands[0]);
2323     operands[1] = gen_lowpart (SImode, operands[1]);
2324   }"
2325   [(set_attr "length" "8")
2326    (set_attr "type" "multiple")]
2329 (define_insn "*anddi_sesdi_di"
2330   [(set (match_operand:DI          0 "s_register_operand" "=&r,&r")
2331         (and:DI (sign_extend:DI
2332                  (match_operand:SI 2 "s_register_operand" "r,r"))
2333                 (match_operand:DI  1 "s_register_operand" "0,r")))]
2334   "TARGET_32BIT"
2335   "#"
2336   [(set_attr "length" "8")
2337    (set_attr "type" "multiple")]
2340 (define_expand "andsi3"
2341   [(set (match_operand:SI         0 "s_register_operand" "")
2342         (and:SI (match_operand:SI 1 "s_register_operand" "")
2343                 (match_operand:SI 2 "reg_or_int_operand" "")))]
2344   "TARGET_EITHER"
2345   "
2346   if (TARGET_32BIT)
2347     {
2348       if (CONST_INT_P (operands[2]))
2349         {
2350           if (INTVAL (operands[2]) == 255 && arm_arch6)
2351             {
2352               operands[1] = convert_to_mode (QImode, operands[1], 1);
2353               emit_insn (gen_thumb2_zero_extendqisi2_v6 (operands[0],
2354                                                          operands[1]));
2355               DONE;
2356             }
2357           else if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[2]), AND))
2358             operands[2] = force_reg (SImode, operands[2]);
2359           else
2360             {
2361               arm_split_constant (AND, SImode, NULL_RTX,
2362                                   INTVAL (operands[2]), operands[0],
2363                                   operands[1],
2364                                   optimize && can_create_pseudo_p ());
2366               DONE;
2367             }
2368         }
2369     }
2370   else /* TARGET_THUMB1 */
2371     {
2372       if (!CONST_INT_P (operands[2]))
2373         {
2374           rtx tmp = force_reg (SImode, operands[2]);
2375           if (rtx_equal_p (operands[0], operands[1]))
2376             operands[2] = tmp;
2377           else
2378             {
2379               operands[2] = operands[1];
2380               operands[1] = tmp;
2381             }
2382         }
2383       else
2384         {
2385           int i;
2386           
2387           if (((unsigned HOST_WIDE_INT) ~INTVAL (operands[2])) < 256)
2388             {
2389               operands[2] = force_reg (SImode,
2390                                        GEN_INT (~INTVAL (operands[2])));
2391               
2392               emit_insn (gen_thumb1_bicsi3 (operands[0], operands[2], operands[1]));
2393               
2394               DONE;
2395             }
2397           for (i = 9; i <= 31; i++)
2398             {
2399               if ((HOST_WIDE_INT_1 << i) - 1 == INTVAL (operands[2]))
2400                 {
2401                   emit_insn (gen_extzv (operands[0], operands[1], GEN_INT (i),
2402                                         const0_rtx));
2403                   DONE;
2404                 }
2405               else if ((HOST_WIDE_INT_1 << i) - 1
2406                        == ~INTVAL (operands[2]))
2407                 {
2408                   rtx shift = GEN_INT (i);
2409                   rtx reg = gen_reg_rtx (SImode);
2410                 
2411                   emit_insn (gen_lshrsi3 (reg, operands[1], shift));
2412                   emit_insn (gen_ashlsi3 (operands[0], reg, shift));
2413                   
2414                   DONE;
2415                 }
2416             }
2418           operands[2] = force_reg (SImode, operands[2]);
2419         }
2420     }
2421   "
2424 ; ??? Check split length for Thumb-2
2425 (define_insn_and_split "*arm_andsi3_insn"
2426   [(set (match_operand:SI         0 "s_register_operand" "=r,l,r,r,r")
2427         (and:SI (match_operand:SI 1 "s_register_operand" "%r,0,r,r,r")
2428                 (match_operand:SI 2 "reg_or_int_operand" "I,l,K,r,?n")))]
2429   "TARGET_32BIT"
2430   "@
2431    and%?\\t%0, %1, %2
2432    and%?\\t%0, %1, %2
2433    bic%?\\t%0, %1, #%B2
2434    and%?\\t%0, %1, %2
2435    #"
2436   "TARGET_32BIT
2437    && CONST_INT_P (operands[2])
2438    && !(const_ok_for_arm (INTVAL (operands[2]))
2439         || const_ok_for_arm (~INTVAL (operands[2])))"
2440   [(clobber (const_int 0))]
2441   "
2442   arm_split_constant  (AND, SImode, curr_insn, 
2443                        INTVAL (operands[2]), operands[0], operands[1], 0);
2444   DONE;
2445   "
2446   [(set_attr "length" "4,4,4,4,16")
2447    (set_attr "predicable" "yes")
2448    (set_attr "predicable_short_it" "no,yes,no,no,no")
2449    (set_attr "type" "logic_imm,logic_imm,logic_reg,logic_reg,logic_imm")]
2452 (define_insn "*andsi3_compare0"
2453   [(set (reg:CC_NOOV CC_REGNUM)
2454         (compare:CC_NOOV
2455          (and:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
2456                  (match_operand:SI 2 "arm_not_operand" "I,K,r"))
2457          (const_int 0)))
2458    (set (match_operand:SI          0 "s_register_operand" "=r,r,r")
2459         (and:SI (match_dup 1) (match_dup 2)))]
2460   "TARGET_32BIT"
2461   "@
2462    ands%?\\t%0, %1, %2
2463    bics%?\\t%0, %1, #%B2
2464    ands%?\\t%0, %1, %2"
2465   [(set_attr "conds" "set")
2466    (set_attr "type" "logics_imm,logics_imm,logics_reg")]
2469 (define_insn "*andsi3_compare0_scratch"
2470   [(set (reg:CC_NOOV CC_REGNUM)
2471         (compare:CC_NOOV
2472          (and:SI (match_operand:SI 0 "s_register_operand" "r,r,r")
2473                  (match_operand:SI 1 "arm_not_operand" "I,K,r"))
2474          (const_int 0)))
2475    (clobber (match_scratch:SI 2 "=X,r,X"))]
2476   "TARGET_32BIT"
2477   "@
2478    tst%?\\t%0, %1
2479    bics%?\\t%2, %0, #%B1
2480    tst%?\\t%0, %1"
2481   [(set_attr "conds" "set")
2482    (set_attr "type"  "logics_imm,logics_imm,logics_reg")]
2485 (define_insn "*zeroextractsi_compare0_scratch"
2486   [(set (reg:CC_NOOV CC_REGNUM)
2487         (compare:CC_NOOV (zero_extract:SI
2488                           (match_operand:SI 0 "s_register_operand" "r")
2489                           (match_operand 1 "const_int_operand" "n")
2490                           (match_operand 2 "const_int_operand" "n"))
2491                          (const_int 0)))]
2492   "TARGET_32BIT
2493   && (INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) < 32
2494       && INTVAL (operands[1]) > 0 
2495       && INTVAL (operands[1]) + (INTVAL (operands[2]) & 1) <= 8
2496       && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32)"
2497   "*
2498   operands[1] = GEN_INT (((1 << INTVAL (operands[1])) - 1)
2499                          << INTVAL (operands[2]));
2500   output_asm_insn (\"tst%?\\t%0, %1\", operands);
2501   return \"\";
2502   "
2503   [(set_attr "conds" "set")
2504    (set_attr "predicable" "yes")
2505    (set_attr "predicable_short_it" "no")
2506    (set_attr "type" "logics_imm")]
2509 (define_insn_and_split "*ne_zeroextractsi"
2510   [(set (match_operand:SI 0 "s_register_operand" "=r")
2511         (ne:SI (zero_extract:SI
2512                 (match_operand:SI 1 "s_register_operand" "r")
2513                 (match_operand:SI 2 "const_int_operand" "n")
2514                 (match_operand:SI 3 "const_int_operand" "n"))
2515                (const_int 0)))
2516    (clobber (reg:CC CC_REGNUM))]
2517   "TARGET_32BIT
2518    && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2519        && INTVAL (operands[2]) > 0 
2520        && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2521        && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)"
2522   "#"
2523   "TARGET_32BIT
2524    && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2525        && INTVAL (operands[2]) > 0 
2526        && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2527        && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)"
2528   [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2529                    (compare:CC_NOOV (and:SI (match_dup 1) (match_dup 2))
2530                                     (const_int 0)))
2531               (set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))])
2532    (set (match_dup 0)
2533         (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2534                          (match_dup 0) (const_int 1)))]
2535   "
2536   operands[2] = GEN_INT (((1 << INTVAL (operands[2])) - 1)
2537                          << INTVAL (operands[3])); 
2538   "
2539   [(set_attr "conds" "clob")
2540    (set (attr "length")
2541         (if_then_else (eq_attr "is_thumb" "yes")
2542                       (const_int 12)
2543                       (const_int 8)))
2544    (set_attr "type" "multiple")]
2547 (define_insn_and_split "*ne_zeroextractsi_shifted"
2548   [(set (match_operand:SI 0 "s_register_operand" "=r")
2549         (ne:SI (zero_extract:SI
2550                 (match_operand:SI 1 "s_register_operand" "r")
2551                 (match_operand:SI 2 "const_int_operand" "n")
2552                 (const_int 0))
2553                (const_int 0)))
2554    (clobber (reg:CC CC_REGNUM))]
2555   "TARGET_ARM"
2556   "#"
2557   "TARGET_ARM"
2558   [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2559                    (compare:CC_NOOV (ashift:SI (match_dup 1) (match_dup 2))
2560                                     (const_int 0)))
2561               (set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))])
2562    (set (match_dup 0)
2563         (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2564                          (match_dup 0) (const_int 1)))]
2565   "
2566   operands[2] = GEN_INT (32 - INTVAL (operands[2]));
2567   "
2568   [(set_attr "conds" "clob")
2569    (set_attr "length" "8")
2570    (set_attr "type" "multiple")]
2573 (define_insn_and_split "*ite_ne_zeroextractsi"
2574   [(set (match_operand:SI 0 "s_register_operand" "=r")
2575         (if_then_else:SI (ne (zero_extract:SI
2576                               (match_operand:SI 1 "s_register_operand" "r")
2577                               (match_operand:SI 2 "const_int_operand" "n")
2578                               (match_operand:SI 3 "const_int_operand" "n"))
2579                              (const_int 0))
2580                          (match_operand:SI 4 "arm_not_operand" "rIK")
2581                          (const_int 0)))
2582    (clobber (reg:CC CC_REGNUM))]
2583   "TARGET_ARM
2584    && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2585        && INTVAL (operands[2]) > 0 
2586        && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2587        && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)
2588    && !reg_overlap_mentioned_p (operands[0], operands[4])"
2589   "#"
2590   "TARGET_ARM
2591    && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2592        && INTVAL (operands[2]) > 0 
2593        && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2594        && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)
2595    && !reg_overlap_mentioned_p (operands[0], operands[4])"
2596   [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2597                    (compare:CC_NOOV (and:SI (match_dup 1) (match_dup 2))
2598                                     (const_int 0)))
2599               (set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))])
2600    (set (match_dup 0)
2601         (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2602                          (match_dup 0) (match_dup 4)))]
2603   "
2604   operands[2] = GEN_INT (((1 << INTVAL (operands[2])) - 1)
2605                          << INTVAL (operands[3])); 
2606   "
2607   [(set_attr "conds" "clob")
2608    (set_attr "length" "8")
2609    (set_attr "type" "multiple")]
2612 (define_insn_and_split "*ite_ne_zeroextractsi_shifted"
2613   [(set (match_operand:SI 0 "s_register_operand" "=r")
2614         (if_then_else:SI (ne (zero_extract:SI
2615                               (match_operand:SI 1 "s_register_operand" "r")
2616                               (match_operand:SI 2 "const_int_operand" "n")
2617                               (const_int 0))
2618                              (const_int 0))
2619                          (match_operand:SI 3 "arm_not_operand" "rIK")
2620                          (const_int 0)))
2621    (clobber (reg:CC CC_REGNUM))]
2622   "TARGET_ARM && !reg_overlap_mentioned_p (operands[0], operands[3])"
2623   "#"
2624   "TARGET_ARM && !reg_overlap_mentioned_p (operands[0], operands[3])"
2625   [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2626                    (compare:CC_NOOV (ashift:SI (match_dup 1) (match_dup 2))
2627                                     (const_int 0)))
2628               (set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))])
2629    (set (match_dup 0)
2630         (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2631                          (match_dup 0) (match_dup 3)))]
2632   "
2633   operands[2] = GEN_INT (32 - INTVAL (operands[2]));
2634   "
2635   [(set_attr "conds" "clob")
2636    (set_attr "length" "8")
2637    (set_attr "type" "multiple")]
2640 ;; ??? Use Thumb-2 has bitfield insert/extract instructions.
2641 (define_split
2642   [(set (match_operand:SI 0 "s_register_operand" "")
2643         (match_operator:SI 1 "shiftable_operator"
2644          [(zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
2645                            (match_operand:SI 3 "const_int_operand" "")
2646                            (match_operand:SI 4 "const_int_operand" ""))
2647           (match_operand:SI 5 "s_register_operand" "")]))
2648    (clobber (match_operand:SI 6 "s_register_operand" ""))]
2649   "TARGET_ARM"
2650   [(set (match_dup 6) (ashift:SI (match_dup 2) (match_dup 3)))
2651    (set (match_dup 0)
2652         (match_op_dup 1
2653          [(lshiftrt:SI (match_dup 6) (match_dup 4))
2654           (match_dup 5)]))]
2655   "{
2656      HOST_WIDE_INT temp = INTVAL (operands[3]);
2658      operands[3] = GEN_INT (32 - temp - INTVAL (operands[4]));
2659      operands[4] = GEN_INT (32 - temp);
2660    }"
2662   
2663 (define_split
2664   [(set (match_operand:SI 0 "s_register_operand" "")
2665         (match_operator:SI 1 "shiftable_operator"
2666          [(sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
2667                            (match_operand:SI 3 "const_int_operand" "")
2668                            (match_operand:SI 4 "const_int_operand" ""))
2669           (match_operand:SI 5 "s_register_operand" "")]))
2670    (clobber (match_operand:SI 6 "s_register_operand" ""))]
2671   "TARGET_ARM"
2672   [(set (match_dup 6) (ashift:SI (match_dup 2) (match_dup 3)))
2673    (set (match_dup 0)
2674         (match_op_dup 1
2675          [(ashiftrt:SI (match_dup 6) (match_dup 4))
2676           (match_dup 5)]))]
2677   "{
2678      HOST_WIDE_INT temp = INTVAL (operands[3]);
2680      operands[3] = GEN_INT (32 - temp - INTVAL (operands[4]));
2681      operands[4] = GEN_INT (32 - temp);
2682    }"
2684   
2685 ;;; ??? This pattern is bogus.  If operand3 has bits outside the range
2686 ;;; represented by the bitfield, then this will produce incorrect results.
2687 ;;; Somewhere, the value needs to be truncated.  On targets like the m68k,
2688 ;;; which have a real bit-field insert instruction, the truncation happens
2689 ;;; in the bit-field insert instruction itself.  Since arm does not have a
2690 ;;; bit-field insert instruction, we would have to emit code here to truncate
2691 ;;; the value before we insert.  This loses some of the advantage of having
2692 ;;; this insv pattern, so this pattern needs to be reevalutated.
2694 (define_expand "insv"
2695   [(set (zero_extract (match_operand 0 "nonimmediate_operand" "")
2696                       (match_operand 1 "general_operand" "")
2697                       (match_operand 2 "general_operand" ""))
2698         (match_operand 3 "reg_or_int_operand" ""))]
2699   "TARGET_ARM || arm_arch_thumb2"
2700   "
2701   {
2702     int start_bit = INTVAL (operands[2]);
2703     int width = INTVAL (operands[1]);
2704     HOST_WIDE_INT mask = (HOST_WIDE_INT_1 << width) - 1;
2705     rtx target, subtarget;
2707     if (arm_arch_thumb2)
2708       {
2709         if (unaligned_access && MEM_P (operands[0])
2710             && s_register_operand (operands[3], GET_MODE (operands[3]))
2711             && (width == 16 || width == 32) && (start_bit % BITS_PER_UNIT) == 0)
2712           {
2713             rtx base_addr;
2715             if (BYTES_BIG_ENDIAN)
2716               start_bit = GET_MODE_BITSIZE (GET_MODE (operands[3])) - width
2717                           - start_bit;
2719             if (width == 32)
2720               {
2721                 base_addr = adjust_address (operands[0], SImode,
2722                                             start_bit / BITS_PER_UNIT);
2723                 emit_insn (gen_unaligned_storesi (base_addr, operands[3]));
2724               }
2725             else
2726               {
2727                 rtx tmp = gen_reg_rtx (HImode);
2729                 base_addr = adjust_address (operands[0], HImode,
2730                                             start_bit / BITS_PER_UNIT);
2731                 emit_move_insn (tmp, gen_lowpart (HImode, operands[3]));
2732                 emit_insn (gen_unaligned_storehi (base_addr, tmp));
2733               }
2734             DONE;
2735           }
2736         else if (s_register_operand (operands[0], GET_MODE (operands[0])))
2737           {
2738             bool use_bfi = TRUE;
2740             if (CONST_INT_P (operands[3]))
2741               {
2742                 HOST_WIDE_INT val = INTVAL (operands[3]) & mask;
2744                 if (val == 0)
2745                   {
2746                     emit_insn (gen_insv_zero (operands[0], operands[1],
2747                                               operands[2]));
2748                     DONE;
2749                   }
2751                 /* See if the set can be done with a single orr instruction.  */
2752                 if (val == mask && const_ok_for_arm (val << start_bit))
2753                   use_bfi = FALSE;
2754               }
2756             if (use_bfi)
2757               {
2758                 if (!REG_P (operands[3]))
2759                   operands[3] = force_reg (SImode, operands[3]);
2761                 emit_insn (gen_insv_t2 (operands[0], operands[1], operands[2],
2762                                         operands[3]));
2763                 DONE;
2764               }
2765           }
2766         else
2767           FAIL;
2768       }
2770     if (!s_register_operand (operands[0], GET_MODE (operands[0])))
2771       FAIL;
2773     target = copy_rtx (operands[0]);
2774     /* Avoid using a subreg as a subtarget, and avoid writing a paradoxical 
2775        subreg as the final target.  */
2776     if (GET_CODE (target) == SUBREG)
2777       {
2778         subtarget = gen_reg_rtx (SImode);
2779         if (GET_MODE_SIZE (GET_MODE (SUBREG_REG (target)))
2780             < GET_MODE_SIZE (SImode))
2781           target = SUBREG_REG (target);
2782       }
2783     else
2784       subtarget = target;    
2786     if (CONST_INT_P (operands[3]))
2787       {
2788         /* Since we are inserting a known constant, we may be able to
2789            reduce the number of bits that we have to clear so that
2790            the mask becomes simple.  */
2791         /* ??? This code does not check to see if the new mask is actually
2792            simpler.  It may not be.  */
2793         rtx op1 = gen_reg_rtx (SImode);
2794         /* ??? Truncate operand3 to fit in the bitfield.  See comment before
2795            start of this pattern.  */
2796         HOST_WIDE_INT op3_value = mask & INTVAL (operands[3]);
2797         HOST_WIDE_INT mask2 = ((mask & ~op3_value) << start_bit);
2799         emit_insn (gen_andsi3 (op1, operands[0],
2800                                gen_int_mode (~mask2, SImode)));
2801         emit_insn (gen_iorsi3 (subtarget, op1,
2802                                gen_int_mode (op3_value << start_bit, SImode)));
2803       }
2804     else if (start_bit == 0
2805              && !(const_ok_for_arm (mask)
2806                   || const_ok_for_arm (~mask)))
2807       {
2808         /* A Trick, since we are setting the bottom bits in the word,
2809            we can shift operand[3] up, operand[0] down, OR them together
2810            and rotate the result back again.  This takes 3 insns, and
2811            the third might be mergeable into another op.  */
2812         /* The shift up copes with the possibility that operand[3] is
2813            wider than the bitfield.  */
2814         rtx op0 = gen_reg_rtx (SImode);
2815         rtx op1 = gen_reg_rtx (SImode);
2817         emit_insn (gen_ashlsi3 (op0, operands[3], GEN_INT (32 - width)));
2818         emit_insn (gen_lshrsi3 (op1, operands[0], operands[1]));
2819         emit_insn (gen_iorsi3  (op1, op1, op0));
2820         emit_insn (gen_rotlsi3 (subtarget, op1, operands[1]));
2821       }
2822     else if ((width + start_bit == 32)
2823              && !(const_ok_for_arm (mask)
2824                   || const_ok_for_arm (~mask)))
2825       {
2826         /* Similar trick, but slightly less efficient.  */
2828         rtx op0 = gen_reg_rtx (SImode);
2829         rtx op1 = gen_reg_rtx (SImode);
2831         emit_insn (gen_ashlsi3 (op0, operands[3], GEN_INT (32 - width)));
2832         emit_insn (gen_ashlsi3 (op1, operands[0], operands[1]));
2833         emit_insn (gen_lshrsi3 (op1, op1, operands[1]));
2834         emit_insn (gen_iorsi3 (subtarget, op1, op0));
2835       }
2836     else
2837       {
2838         rtx op0 = gen_int_mode (mask, SImode);
2839         rtx op1 = gen_reg_rtx (SImode);
2840         rtx op2 = gen_reg_rtx (SImode);
2842         if (!(const_ok_for_arm (mask) || const_ok_for_arm (~mask)))
2843           {
2844             rtx tmp = gen_reg_rtx (SImode);
2846             emit_insn (gen_movsi (tmp, op0));
2847             op0 = tmp;
2848           }
2850         /* Mask out any bits in operand[3] that are not needed.  */
2851            emit_insn (gen_andsi3 (op1, operands[3], op0));
2853         if (CONST_INT_P (op0)
2854             && (const_ok_for_arm (mask << start_bit)
2855                 || const_ok_for_arm (~(mask << start_bit))))
2856           {
2857             op0 = gen_int_mode (~(mask << start_bit), SImode);
2858             emit_insn (gen_andsi3 (op2, operands[0], op0));
2859           }
2860         else
2861           {
2862             if (CONST_INT_P (op0))
2863               {
2864                 rtx tmp = gen_reg_rtx (SImode);
2866                 emit_insn (gen_movsi (tmp, op0));
2867                 op0 = tmp;
2868               }
2870             if (start_bit != 0)
2871               emit_insn (gen_ashlsi3 (op0, op0, operands[2]));
2872             
2873             emit_insn (gen_andsi_notsi_si (op2, operands[0], op0));
2874           }
2876         if (start_bit != 0)
2877           emit_insn (gen_ashlsi3 (op1, op1, operands[2]));
2879         emit_insn (gen_iorsi3 (subtarget, op1, op2));
2880       }
2882     if (subtarget != target)
2883       {
2884         /* If TARGET is still a SUBREG, then it must be wider than a word,
2885            so we must be careful only to set the subword we were asked to.  */
2886         if (GET_CODE (target) == SUBREG)
2887           emit_move_insn (target, subtarget);
2888         else
2889           emit_move_insn (target, gen_lowpart (GET_MODE (target), subtarget));
2890       }
2892     DONE;
2893   }"
2896 (define_insn "insv_zero"
2897   [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r")
2898                          (match_operand:SI 1 "const_int_M_operand" "M")
2899                          (match_operand:SI 2 "const_int_M_operand" "M"))
2900         (const_int 0))]
2901   "arm_arch_thumb2"
2902   "bfc%?\t%0, %2, %1"
2903   [(set_attr "length" "4")
2904    (set_attr "predicable" "yes")
2905    (set_attr "predicable_short_it" "no")
2906    (set_attr "type" "bfm")]
2909 (define_insn "insv_t2"
2910   [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r")
2911                          (match_operand:SI 1 "const_int_M_operand" "M")
2912                          (match_operand:SI 2 "const_int_M_operand" "M"))
2913         (match_operand:SI 3 "s_register_operand" "r"))]
2914   "arm_arch_thumb2"
2915   "bfi%?\t%0, %3, %2, %1"
2916   [(set_attr "length" "4")
2917    (set_attr "predicable" "yes")
2918    (set_attr "predicable_short_it" "no")
2919    (set_attr "type" "bfm")]
2922 ; constants for op 2 will never be given to these patterns.
2923 (define_insn_and_split "*anddi_notdi_di"
2924   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2925         (and:DI (not:DI (match_operand:DI 1 "s_register_operand" "0,r"))
2926                 (match_operand:DI 2 "s_register_operand" "r,0")))]
2927   "TARGET_32BIT"
2928   "#"
2929   "TARGET_32BIT && reload_completed
2930    && ! (TARGET_NEON && IS_VFP_REGNUM (REGNO (operands[0])))
2931    && ! IS_IWMMXT_REGNUM (REGNO (operands[0]))"
2932   [(set (match_dup 0) (and:SI (not:SI (match_dup 1)) (match_dup 2)))
2933    (set (match_dup 3) (and:SI (not:SI (match_dup 4)) (match_dup 5)))]
2934   "
2935   {
2936     operands[3] = gen_highpart (SImode, operands[0]);
2937     operands[0] = gen_lowpart (SImode, operands[0]);
2938     operands[4] = gen_highpart (SImode, operands[1]);
2939     operands[1] = gen_lowpart (SImode, operands[1]);
2940     operands[5] = gen_highpart (SImode, operands[2]);
2941     operands[2] = gen_lowpart (SImode, operands[2]);
2942   }"
2943   [(set_attr "length" "8")
2944    (set_attr "predicable" "yes")
2945    (set_attr "type" "multiple")]
2948 (define_insn_and_split "*anddi_notzesidi_di"
2949   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2950         (and:DI (not:DI (zero_extend:DI
2951                          (match_operand:SI 2 "s_register_operand" "r,r")))
2952                 (match_operand:DI 1 "s_register_operand" "0,?r")))]
2953   "TARGET_32BIT"
2954   "@
2955    bic%?\\t%Q0, %Q1, %2
2956    #"
2957   ; (not (zero_extend ...)) allows us to just copy the high word from
2958   ; operand1 to operand0.
2959   "TARGET_32BIT
2960    && reload_completed
2961    && operands[0] != operands[1]"
2962   [(set (match_dup 0) (and:SI (not:SI (match_dup 2)) (match_dup 1)))
2963    (set (match_dup 3) (match_dup 4))]
2964   "
2965   {
2966     operands[3] = gen_highpart (SImode, operands[0]);
2967     operands[0] = gen_lowpart (SImode, operands[0]);
2968     operands[4] = gen_highpart (SImode, operands[1]);
2969     operands[1] = gen_lowpart (SImode, operands[1]);
2970   }"
2971   [(set_attr "length" "4,8")
2972    (set_attr "predicable" "yes")
2973    (set_attr "predicable_short_it" "no")
2974    (set_attr "type" "multiple")]
2977 (define_insn_and_split "*anddi_notdi_zesidi"
2978   [(set (match_operand:DI 0 "s_register_operand" "=r")
2979         (and:DI (not:DI (match_operand:DI 2 "s_register_operand" "r"))
2980                 (zero_extend:DI
2981                  (match_operand:SI 1 "s_register_operand" "r"))))]
2982   "TARGET_32BIT"
2983   "#"
2984   "TARGET_32BIT && reload_completed"
2985   [(set (match_dup 0) (and:SI (not:SI (match_dup 2)) (match_dup 1)))
2986    (set (match_dup 3) (const_int 0))]
2987   "
2988   {
2989     operands[3] = gen_highpart (SImode, operands[0]);
2990     operands[0] = gen_lowpart (SImode, operands[0]);
2991     operands[2] = gen_lowpart (SImode, operands[2]);
2992   }"
2993   [(set_attr "length" "8")
2994    (set_attr "predicable" "yes")
2995    (set_attr "predicable_short_it" "no")
2996    (set_attr "type" "multiple")]
2999 (define_insn_and_split "*anddi_notsesidi_di"
3000   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
3001         (and:DI (not:DI (sign_extend:DI
3002                          (match_operand:SI 2 "s_register_operand" "r,r")))
3003                 (match_operand:DI 1 "s_register_operand" "0,r")))]
3004   "TARGET_32BIT"
3005   "#"
3006   "TARGET_32BIT && reload_completed"
3007   [(set (match_dup 0) (and:SI (not:SI (match_dup 2)) (match_dup 1)))
3008    (set (match_dup 3) (and:SI (not:SI
3009                                 (ashiftrt:SI (match_dup 2) (const_int 31)))
3010                                (match_dup 4)))]
3011   "
3012   {
3013     operands[3] = gen_highpart (SImode, operands[0]);
3014     operands[0] = gen_lowpart (SImode, operands[0]);
3015     operands[4] = gen_highpart (SImode, operands[1]);
3016     operands[1] = gen_lowpart (SImode, operands[1]);
3017   }"
3018   [(set_attr "length" "8")
3019    (set_attr "predicable" "yes")
3020    (set_attr "predicable_short_it" "no")
3021    (set_attr "type" "multiple")]
3024 (define_insn "andsi_notsi_si"
3025   [(set (match_operand:SI 0 "s_register_operand" "=r")
3026         (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
3027                 (match_operand:SI 1 "s_register_operand" "r")))]
3028   "TARGET_32BIT"
3029   "bic%?\\t%0, %1, %2"
3030   [(set_attr "predicable" "yes")
3031    (set_attr "predicable_short_it" "no")
3032    (set_attr "type" "logic_reg")]
3035 (define_insn "andsi_not_shiftsi_si"
3036   [(set (match_operand:SI 0 "s_register_operand" "=r")
3037         (and:SI (not:SI (match_operator:SI 4 "shift_operator"
3038                          [(match_operand:SI 2 "s_register_operand" "r")
3039                           (match_operand:SI 3 "arm_rhs_operand" "rM")]))
3040                 (match_operand:SI 1 "s_register_operand" "r")))]
3041   "TARGET_ARM"
3042   "bic%?\\t%0, %1, %2%S4"
3043   [(set_attr "predicable" "yes")
3044    (set_attr "shift" "2")
3045    (set (attr "type") (if_then_else (match_operand 3 "const_int_operand" "")
3046                       (const_string "logic_shift_imm")
3047                       (const_string "logic_shift_reg")))]
3050 ;; Shifted bics pattern used to set up CC status register and not reusing
3051 ;; bics output.  Pattern restricts Thumb2 shift operand as bics for Thumb2
3052 ;; does not support shift by register.
3053 (define_insn "andsi_not_shiftsi_si_scc_no_reuse"
3054   [(set (reg:CC_NOOV CC_REGNUM)
3055         (compare:CC_NOOV
3056                 (and:SI (not:SI (match_operator:SI 0 "shift_operator"
3057                         [(match_operand:SI 1 "s_register_operand" "r")
3058                          (match_operand:SI 2 "arm_rhs_operand" "rM")]))
3059                         (match_operand:SI 3 "s_register_operand" "r"))
3060                 (const_int 0)))
3061    (clobber (match_scratch:SI 4 "=r"))]
3062   "TARGET_ARM || (TARGET_THUMB2 && CONST_INT_P (operands[2]))"
3063   "bics%?\\t%4, %3, %1%S0"
3064   [(set_attr "predicable" "yes")
3065    (set_attr "predicable_short_it" "no")
3066    (set_attr "conds" "set")
3067    (set_attr "shift" "1")
3068    (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
3069                       (const_string "logic_shift_imm")
3070                       (const_string "logic_shift_reg")))]
3073 ;; Same as andsi_not_shiftsi_si_scc_no_reuse, but the bics result is also
3074 ;; getting reused later.
3075 (define_insn "andsi_not_shiftsi_si_scc"
3076   [(parallel [(set (reg:CC_NOOV CC_REGNUM)
3077         (compare:CC_NOOV
3078                 (and:SI (not:SI (match_operator:SI 0 "shift_operator"
3079                         [(match_operand:SI 1 "s_register_operand" "r")
3080                          (match_operand:SI 2 "arm_rhs_operand" "rM")]))
3081                         (match_operand:SI 3 "s_register_operand" "r"))
3082                 (const_int 0)))
3083         (set (match_operand:SI 4 "s_register_operand" "=r")
3084              (and:SI (not:SI (match_op_dup 0
3085                      [(match_dup 1)
3086                       (match_dup 2)]))
3087                      (match_dup 3)))])]
3088   "TARGET_ARM || (TARGET_THUMB2 && CONST_INT_P (operands[2]))"
3089   "bics%?\\t%4, %3, %1%S0"
3090   [(set_attr "predicable" "yes")
3091    (set_attr "predicable_short_it" "no")
3092    (set_attr "conds" "set")
3093    (set_attr "shift" "1")
3094    (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
3095                       (const_string "logic_shift_imm")
3096                       (const_string "logic_shift_reg")))]
3099 (define_insn "*andsi_notsi_si_compare0"
3100   [(set (reg:CC_NOOV CC_REGNUM)
3101         (compare:CC_NOOV
3102          (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
3103                  (match_operand:SI 1 "s_register_operand" "r"))
3104          (const_int 0)))
3105    (set (match_operand:SI 0 "s_register_operand" "=r")
3106         (and:SI (not:SI (match_dup 2)) (match_dup 1)))]
3107   "TARGET_32BIT"
3108   "bics\\t%0, %1, %2"
3109   [(set_attr "conds" "set")
3110    (set_attr "type" "logics_shift_reg")]
3113 (define_insn "*andsi_notsi_si_compare0_scratch"
3114   [(set (reg:CC_NOOV CC_REGNUM)
3115         (compare:CC_NOOV
3116          (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
3117                  (match_operand:SI 1 "s_register_operand" "r"))
3118          (const_int 0)))
3119    (clobber (match_scratch:SI 0 "=r"))]
3120   "TARGET_32BIT"
3121   "bics\\t%0, %1, %2"
3122   [(set_attr "conds" "set")
3123    (set_attr "type" "logics_shift_reg")]
3126 (define_expand "iordi3"
3127   [(set (match_operand:DI         0 "s_register_operand" "")
3128         (ior:DI (match_operand:DI 1 "s_register_operand" "")
3129                 (match_operand:DI 2 "neon_logic_op2" "")))]
3130   "TARGET_32BIT"
3131   ""
3134 (define_insn_and_split "*iordi3_insn"
3135   [(set (match_operand:DI         0 "s_register_operand"     "=w,w ,&r,&r,&r,&r,?w,?w")
3136         (ior:DI (match_operand:DI 1 "s_register_operand"     "%w,0 ,0 ,r ,0 ,r ,w ,0")
3137                 (match_operand:DI 2 "arm_iordi_operand_neon" "w ,Dl,r ,r ,Df,Df,w ,Dl")))]
3138   "TARGET_32BIT && !TARGET_IWMMXT"
3139   {
3140   switch (which_alternative)
3141     {
3142     case 0: /* fall through */
3143     case 6: return "vorr\t%P0, %P1, %P2";
3144     case 1: /* fall through */
3145     case 7: return neon_output_logic_immediate ("vorr", &operands[2],
3146                      DImode, 0, VALID_NEON_QREG_MODE (DImode));
3147     case 2:
3148     case 3:
3149     case 4:
3150     case 5:
3151       return "#";
3152     default: gcc_unreachable ();
3153     }
3154   }
3155   "TARGET_32BIT && !TARGET_IWMMXT && reload_completed
3156    && !(IS_VFP_REGNUM (REGNO (operands[0])))"
3157   [(set (match_dup 3) (match_dup 4))
3158    (set (match_dup 5) (match_dup 6))]
3159   "
3160   {
3161     operands[3] = gen_lowpart (SImode, operands[0]);
3162     operands[5] = gen_highpart (SImode, operands[0]);
3164     operands[4] = simplify_gen_binary (IOR, SImode,
3165                                            gen_lowpart (SImode, operands[1]),
3166                                            gen_lowpart (SImode, operands[2]));
3167     operands[6] = simplify_gen_binary (IOR, SImode,
3168                                            gen_highpart (SImode, operands[1]),
3169                                            gen_highpart_mode (SImode, DImode, operands[2]));
3171   }"
3172   [(set_attr "type" "neon_logic,neon_logic,multiple,multiple,multiple,\
3173                      multiple,neon_logic,neon_logic")
3174    (set_attr "length" "*,*,8,8,8,8,*,*")
3175    (set_attr "arch" "neon_for_64bits,neon_for_64bits,*,*,*,*,avoid_neon_for_64bits,avoid_neon_for_64bits")]
3178 (define_insn "*iordi_zesidi_di"
3179   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
3180         (ior:DI (zero_extend:DI
3181                  (match_operand:SI 2 "s_register_operand" "r,r"))
3182                 (match_operand:DI 1 "s_register_operand" "0,?r")))]
3183   "TARGET_32BIT"
3184   "@
3185    orr%?\\t%Q0, %Q1, %2
3186    #"
3187   [(set_attr "length" "4,8")
3188    (set_attr "predicable" "yes")
3189    (set_attr "predicable_short_it" "no")
3190    (set_attr "type" "logic_reg,multiple")]
3193 (define_insn "*iordi_sesidi_di"
3194   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
3195         (ior:DI (sign_extend:DI
3196                  (match_operand:SI 2 "s_register_operand" "r,r"))
3197                 (match_operand:DI 1 "s_register_operand" "0,r")))]
3198   "TARGET_32BIT"
3199   "#"
3200   [(set_attr "length" "8")
3201    (set_attr "predicable" "yes")
3202    (set_attr "type" "multiple")]
3205 (define_expand "iorsi3"
3206   [(set (match_operand:SI         0 "s_register_operand" "")
3207         (ior:SI (match_operand:SI 1 "s_register_operand" "")
3208                 (match_operand:SI 2 "reg_or_int_operand" "")))]
3209   "TARGET_EITHER"
3210   "
3211   if (CONST_INT_P (operands[2]))
3212     {
3213       if (TARGET_32BIT)
3214         {
3215           if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[2]), IOR))
3216             operands[2] = force_reg (SImode, operands[2]);
3217           else
3218             {
3219               arm_split_constant (IOR, SImode, NULL_RTX,
3220                                   INTVAL (operands[2]), operands[0],
3221                                   operands[1],
3222                                   optimize && can_create_pseudo_p ());
3223               DONE;
3224             }
3225         }
3226       else /* TARGET_THUMB1 */
3227         {
3228           rtx tmp = force_reg (SImode, operands[2]);
3229           if (rtx_equal_p (operands[0], operands[1]))
3230             operands[2] = tmp;
3231           else
3232             {
3233               operands[2] = operands[1];
3234               operands[1] = tmp;
3235             }
3236         }
3237     }
3238   "
3241 (define_insn_and_split "*iorsi3_insn"
3242   [(set (match_operand:SI 0 "s_register_operand" "=r,l,r,r,r")
3243         (ior:SI (match_operand:SI 1 "s_register_operand" "%r,0,r,r,r")
3244                 (match_operand:SI 2 "reg_or_int_operand" "I,l,K,r,?n")))]
3245   "TARGET_32BIT"
3246   "@
3247    orr%?\\t%0, %1, %2
3248    orr%?\\t%0, %1, %2
3249    orn%?\\t%0, %1, #%B2
3250    orr%?\\t%0, %1, %2
3251    #"
3252   "TARGET_32BIT
3253    && CONST_INT_P (operands[2])
3254    && !(const_ok_for_arm (INTVAL (operands[2]))
3255         || (TARGET_THUMB2 && const_ok_for_arm (~INTVAL (operands[2]))))"
3256   [(clobber (const_int 0))]
3258   arm_split_constant (IOR, SImode, curr_insn,
3259                       INTVAL (operands[2]), operands[0], operands[1], 0);
3260   DONE;
3262   [(set_attr "length" "4,4,4,4,16")
3263    (set_attr "arch" "32,t2,t2,32,32")
3264    (set_attr "predicable" "yes")
3265    (set_attr "predicable_short_it" "no,yes,no,no,no")
3266    (set_attr "type" "logic_imm,logic_reg,logic_imm,logic_reg,logic_reg")]
3269 (define_peephole2
3270   [(match_scratch:SI 3 "r")
3271    (set (match_operand:SI 0 "arm_general_register_operand" "")
3272         (ior:SI (match_operand:SI 1 "arm_general_register_operand" "")
3273                 (match_operand:SI 2 "const_int_operand" "")))]
3274   "TARGET_ARM
3275    && !const_ok_for_arm (INTVAL (operands[2]))
3276    && const_ok_for_arm (~INTVAL (operands[2]))"
3277   [(set (match_dup 3) (match_dup 2))
3278    (set (match_dup 0) (ior:SI (match_dup 1) (match_dup 3)))]
3279   ""
3282 (define_insn "*iorsi3_compare0"
3283   [(set (reg:CC_NOOV CC_REGNUM)
3284         (compare:CC_NOOV (ior:SI (match_operand:SI 1 "s_register_operand" "%r,r")
3285                                  (match_operand:SI 2 "arm_rhs_operand" "I,r"))
3286                          (const_int 0)))
3287    (set (match_operand:SI 0 "s_register_operand" "=r,r")
3288         (ior:SI (match_dup 1) (match_dup 2)))]
3289   "TARGET_32BIT"
3290   "orrs%?\\t%0, %1, %2"
3291   [(set_attr "conds" "set")
3292    (set_attr "type" "logics_imm,logics_reg")]
3295 (define_insn "*iorsi3_compare0_scratch"
3296   [(set (reg:CC_NOOV CC_REGNUM)
3297         (compare:CC_NOOV (ior:SI (match_operand:SI 1 "s_register_operand" "%r,r")
3298                                  (match_operand:SI 2 "arm_rhs_operand" "I,r"))
3299                          (const_int 0)))
3300    (clobber (match_scratch:SI 0 "=r,r"))]
3301   "TARGET_32BIT"
3302   "orrs%?\\t%0, %1, %2"
3303   [(set_attr "conds" "set")
3304    (set_attr "type" "logics_imm,logics_reg")]
3307 (define_expand "xordi3"
3308   [(set (match_operand:DI         0 "s_register_operand" "")
3309         (xor:DI (match_operand:DI 1 "s_register_operand" "")
3310                 (match_operand:DI 2 "arm_xordi_operand" "")))]
3311   "TARGET_32BIT"
3312   {
3313     /* The iWMMXt pattern for xordi3 accepts only register operands but we want
3314        to reuse this expander for all TARGET_32BIT targets so just force the
3315        constants into a register.  Unlike for the anddi3 and iordi3 there are
3316        no NEON instructions that take an immediate.  */
3317     if (TARGET_IWMMXT && !REG_P (operands[2]))
3318       operands[2] = force_reg (DImode, operands[2]);
3319   }
3322 (define_insn_and_split "*xordi3_insn"
3323   [(set (match_operand:DI         0 "s_register_operand" "=w,&r,&r,&r,&r,?w")
3324         (xor:DI (match_operand:DI 1 "s_register_operand" "%w ,0,r ,0 ,r ,w")
3325                 (match_operand:DI 2 "arm_xordi_operand"  "w ,r ,r ,Dg,Dg,w")))]
3326   "TARGET_32BIT && !TARGET_IWMMXT"
3328   switch (which_alternative)
3329     {
3330     case 1:
3331     case 2:
3332     case 3:
3333     case 4:  /* fall through */
3334       return "#";
3335     case 0: /* fall through */
3336     case 5: return "veor\t%P0, %P1, %P2";
3337     default: gcc_unreachable ();
3338     }
3340   "TARGET_32BIT && !TARGET_IWMMXT && reload_completed
3341    && !(IS_VFP_REGNUM (REGNO (operands[0])))"
3342   [(set (match_dup 3) (match_dup 4))
3343    (set (match_dup 5) (match_dup 6))]
3344   "
3345   {
3346     operands[3] = gen_lowpart (SImode, operands[0]);
3347     operands[5] = gen_highpart (SImode, operands[0]);
3349     operands[4] = simplify_gen_binary (XOR, SImode,
3350                                            gen_lowpart (SImode, operands[1]),
3351                                            gen_lowpart (SImode, operands[2]));
3352     operands[6] = simplify_gen_binary (XOR, SImode,
3353                                            gen_highpart (SImode, operands[1]),
3354                                            gen_highpart_mode (SImode, DImode, operands[2]));
3356   }"
3357   [(set_attr "length" "*,8,8,8,8,*")
3358    (set_attr "type" "neon_logic,multiple,multiple,multiple,multiple,neon_logic")
3359    (set_attr "arch" "neon_for_64bits,*,*,*,*,avoid_neon_for_64bits")]
3362 (define_insn "*xordi_zesidi_di"
3363   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
3364         (xor:DI (zero_extend:DI
3365                  (match_operand:SI 2 "s_register_operand" "r,r"))
3366                 (match_operand:DI 1 "s_register_operand" "0,?r")))]
3367   "TARGET_32BIT"
3368   "@
3369    eor%?\\t%Q0, %Q1, %2
3370    #"
3371   [(set_attr "length" "4,8")
3372    (set_attr "predicable" "yes")
3373    (set_attr "predicable_short_it" "no")
3374    (set_attr "type" "logic_reg")]
3377 (define_insn "*xordi_sesidi_di"
3378   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
3379         (xor:DI (sign_extend:DI
3380                  (match_operand:SI 2 "s_register_operand" "r,r"))
3381                 (match_operand:DI 1 "s_register_operand" "0,r")))]
3382   "TARGET_32BIT"
3383   "#"
3384   [(set_attr "length" "8")
3385    (set_attr "predicable" "yes")
3386    (set_attr "type" "multiple")]
3389 (define_expand "xorsi3"
3390   [(set (match_operand:SI         0 "s_register_operand" "")
3391         (xor:SI (match_operand:SI 1 "s_register_operand" "")
3392                 (match_operand:SI 2 "reg_or_int_operand" "")))]
3393   "TARGET_EITHER"
3394   "if (CONST_INT_P (operands[2]))
3395     {
3396       if (TARGET_32BIT)
3397         {
3398           if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[2]), XOR))
3399             operands[2] = force_reg (SImode, operands[2]);
3400           else
3401             {
3402               arm_split_constant (XOR, SImode, NULL_RTX,
3403                                   INTVAL (operands[2]), operands[0],
3404                                   operands[1],
3405                                   optimize && can_create_pseudo_p ());
3406               DONE;
3407             }
3408         }
3409       else /* TARGET_THUMB1 */
3410         {
3411           rtx tmp = force_reg (SImode, operands[2]);
3412           if (rtx_equal_p (operands[0], operands[1]))
3413             operands[2] = tmp;
3414           else
3415             {
3416               operands[2] = operands[1];
3417               operands[1] = tmp;
3418             }
3419         }
3420     }"
3423 (define_insn_and_split "*arm_xorsi3"
3424   [(set (match_operand:SI         0 "s_register_operand" "=r,l,r,r")
3425         (xor:SI (match_operand:SI 1 "s_register_operand" "%r,0,r,r")
3426                 (match_operand:SI 2 "reg_or_int_operand" "I,l,r,?n")))]
3427   "TARGET_32BIT"
3428   "@
3429    eor%?\\t%0, %1, %2
3430    eor%?\\t%0, %1, %2
3431    eor%?\\t%0, %1, %2
3432    #"
3433   "TARGET_32BIT
3434    && CONST_INT_P (operands[2])
3435    && !const_ok_for_arm (INTVAL (operands[2]))"
3436   [(clobber (const_int 0))]
3438   arm_split_constant (XOR, SImode, curr_insn,
3439                       INTVAL (operands[2]), operands[0], operands[1], 0);
3440   DONE;
3442   [(set_attr "length" "4,4,4,16")
3443    (set_attr "predicable" "yes")
3444    (set_attr "predicable_short_it" "no,yes,no,no")
3445    (set_attr "type"  "logic_imm,logic_reg,logic_reg,multiple")]
3448 (define_insn "*xorsi3_compare0"
3449   [(set (reg:CC_NOOV CC_REGNUM)
3450         (compare:CC_NOOV (xor:SI (match_operand:SI 1 "s_register_operand" "r,r")
3451                                  (match_operand:SI 2 "arm_rhs_operand" "I,r"))
3452                          (const_int 0)))
3453    (set (match_operand:SI 0 "s_register_operand" "=r,r")
3454         (xor:SI (match_dup 1) (match_dup 2)))]
3455   "TARGET_32BIT"
3456   "eors%?\\t%0, %1, %2"
3457   [(set_attr "conds" "set")
3458    (set_attr "type" "logics_imm,logics_reg")]
3461 (define_insn "*xorsi3_compare0_scratch"
3462   [(set (reg:CC_NOOV CC_REGNUM)
3463         (compare:CC_NOOV (xor:SI (match_operand:SI 0 "s_register_operand" "r,r")
3464                                  (match_operand:SI 1 "arm_rhs_operand" "I,r"))
3465                          (const_int 0)))]
3466   "TARGET_32BIT"
3467   "teq%?\\t%0, %1"
3468   [(set_attr "conds" "set")
3469    (set_attr "type" "logics_imm,logics_reg")]
3472 ; By splitting (IOR (AND (NOT A) (NOT B)) C) as D = AND (IOR A B) (NOT C), 
3473 ; (NOT D) we can sometimes merge the final NOT into one of the following
3474 ; insns.
3476 (define_split
3477   [(set (match_operand:SI 0 "s_register_operand" "")
3478         (ior:SI (and:SI (not:SI (match_operand:SI 1 "s_register_operand" ""))
3479                         (not:SI (match_operand:SI 2 "arm_rhs_operand" "")))
3480                 (match_operand:SI 3 "arm_rhs_operand" "")))
3481    (clobber (match_operand:SI 4 "s_register_operand" ""))]
3482   "TARGET_32BIT"
3483   [(set (match_dup 4) (and:SI (ior:SI (match_dup 1) (match_dup 2))
3484                               (not:SI (match_dup 3))))
3485    (set (match_dup 0) (not:SI (match_dup 4)))]
3486   ""
3489 (define_insn_and_split "*andsi_iorsi3_notsi"
3490   [(set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r")
3491         (and:SI (ior:SI (match_operand:SI 1 "s_register_operand" "%0,r,r")
3492                         (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI"))
3493                 (not:SI (match_operand:SI 3 "arm_rhs_operand" "rI,rI,rI"))))]
3494   "TARGET_32BIT"
3495   "#"   ; "orr%?\\t%0, %1, %2\;bic%?\\t%0, %0, %3"
3496   "&& reload_completed"
3497   [(set (match_dup 0) (ior:SI (match_dup 1) (match_dup 2)))
3498    (set (match_dup 0) (and:SI (match_dup 4) (match_dup 5)))]
3499   {
3500      /* If operands[3] is a constant make sure to fold the NOT into it
3501         to avoid creating a NOT of a CONST_INT.  */
3502     rtx not_rtx = simplify_gen_unary (NOT, SImode, operands[3], SImode);
3503     if (CONST_INT_P (not_rtx))
3504       {
3505         operands[4] = operands[0];
3506         operands[5] = not_rtx;
3507       }
3508     else
3509       {
3510         operands[5] = operands[0];
3511         operands[4] = not_rtx;
3512       }
3513   }
3514   [(set_attr "length" "8")
3515    (set_attr "ce_count" "2")
3516    (set_attr "predicable" "yes")
3517    (set_attr "predicable_short_it" "no")
3518    (set_attr "type" "multiple")]
3521 ; ??? Are these four splitters still beneficial when the Thumb-2 bitfield
3522 ; insns are available?
3523 (define_split
3524   [(set (match_operand:SI 0 "s_register_operand" "")
3525         (match_operator:SI 1 "logical_binary_operator"
3526          [(zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
3527                            (match_operand:SI 3 "const_int_operand" "")
3528                            (match_operand:SI 4 "const_int_operand" ""))
3529           (match_operator:SI 9 "logical_binary_operator"
3530            [(lshiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3531                          (match_operand:SI 6 "const_int_operand" ""))
3532             (match_operand:SI 7 "s_register_operand" "")])]))
3533    (clobber (match_operand:SI 8 "s_register_operand" ""))]
3534   "TARGET_32BIT
3535    && GET_CODE (operands[1]) == GET_CODE (operands[9])
3536    && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3537   [(set (match_dup 8)
3538         (match_op_dup 1
3539          [(ashift:SI (match_dup 2) (match_dup 4))
3540           (match_dup 5)]))
3541    (set (match_dup 0)
3542         (match_op_dup 1
3543          [(lshiftrt:SI (match_dup 8) (match_dup 6))
3544           (match_dup 7)]))]
3545   "
3546   operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3549 (define_split
3550   [(set (match_operand:SI 0 "s_register_operand" "")
3551         (match_operator:SI 1 "logical_binary_operator"
3552          [(match_operator:SI 9 "logical_binary_operator"
3553            [(lshiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3554                          (match_operand:SI 6 "const_int_operand" ""))
3555             (match_operand:SI 7 "s_register_operand" "")])
3556           (zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
3557                            (match_operand:SI 3 "const_int_operand" "")
3558                            (match_operand:SI 4 "const_int_operand" ""))]))
3559    (clobber (match_operand:SI 8 "s_register_operand" ""))]
3560   "TARGET_32BIT
3561    && GET_CODE (operands[1]) == GET_CODE (operands[9])
3562    && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3563   [(set (match_dup 8)
3564         (match_op_dup 1
3565          [(ashift:SI (match_dup 2) (match_dup 4))
3566           (match_dup 5)]))
3567    (set (match_dup 0)
3568         (match_op_dup 1
3569          [(lshiftrt:SI (match_dup 8) (match_dup 6))
3570           (match_dup 7)]))]
3571   "
3572   operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3575 (define_split
3576   [(set (match_operand:SI 0 "s_register_operand" "")
3577         (match_operator:SI 1 "logical_binary_operator"
3578          [(sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
3579                            (match_operand:SI 3 "const_int_operand" "")
3580                            (match_operand:SI 4 "const_int_operand" ""))
3581           (match_operator:SI 9 "logical_binary_operator"
3582            [(ashiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3583                          (match_operand:SI 6 "const_int_operand" ""))
3584             (match_operand:SI 7 "s_register_operand" "")])]))
3585    (clobber (match_operand:SI 8 "s_register_operand" ""))]
3586   "TARGET_32BIT
3587    && GET_CODE (operands[1]) == GET_CODE (operands[9])
3588    && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3589   [(set (match_dup 8)
3590         (match_op_dup 1
3591          [(ashift:SI (match_dup 2) (match_dup 4))
3592           (match_dup 5)]))
3593    (set (match_dup 0)
3594         (match_op_dup 1
3595          [(ashiftrt:SI (match_dup 8) (match_dup 6))
3596           (match_dup 7)]))]
3597   "
3598   operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3601 (define_split
3602   [(set (match_operand:SI 0 "s_register_operand" "")
3603         (match_operator:SI 1 "logical_binary_operator"
3604          [(match_operator:SI 9 "logical_binary_operator"
3605            [(ashiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3606                          (match_operand:SI 6 "const_int_operand" ""))
3607             (match_operand:SI 7 "s_register_operand" "")])
3608           (sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
3609                            (match_operand:SI 3 "const_int_operand" "")
3610                            (match_operand:SI 4 "const_int_operand" ""))]))
3611    (clobber (match_operand:SI 8 "s_register_operand" ""))]
3612   "TARGET_32BIT
3613    && GET_CODE (operands[1]) == GET_CODE (operands[9])
3614    && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3615   [(set (match_dup 8)
3616         (match_op_dup 1
3617          [(ashift:SI (match_dup 2) (match_dup 4))
3618           (match_dup 5)]))
3619    (set (match_dup 0)
3620         (match_op_dup 1
3621          [(ashiftrt:SI (match_dup 8) (match_dup 6))
3622           (match_dup 7)]))]
3623   "
3624   operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3628 ;; Minimum and maximum insns
3630 (define_expand "smaxsi3"
3631   [(parallel [
3632     (set (match_operand:SI 0 "s_register_operand" "")
3633          (smax:SI (match_operand:SI 1 "s_register_operand" "")
3634                   (match_operand:SI 2 "arm_rhs_operand" "")))
3635     (clobber (reg:CC CC_REGNUM))])]
3636   "TARGET_32BIT"
3637   "
3638   if (operands[2] == const0_rtx || operands[2] == constm1_rtx)
3639     {
3640       /* No need for a clobber of the condition code register here.  */
3641       emit_insn (gen_rtx_SET (operands[0],
3642                               gen_rtx_SMAX (SImode, operands[1],
3643                                             operands[2])));
3644       DONE;
3645     }
3648 (define_insn "*smax_0"
3649   [(set (match_operand:SI 0 "s_register_operand" "=r")
3650         (smax:SI (match_operand:SI 1 "s_register_operand" "r")
3651                  (const_int 0)))]
3652   "TARGET_32BIT"
3653   "bic%?\\t%0, %1, %1, asr #31"
3654   [(set_attr "predicable" "yes")
3655    (set_attr "predicable_short_it" "no")
3656    (set_attr "type" "logic_shift_reg")]
3659 (define_insn "*smax_m1"
3660   [(set (match_operand:SI 0 "s_register_operand" "=r")
3661         (smax:SI (match_operand:SI 1 "s_register_operand" "r")
3662                  (const_int -1)))]
3663   "TARGET_32BIT"
3664   "orr%?\\t%0, %1, %1, asr #31"
3665   [(set_attr "predicable" "yes")
3666    (set_attr "predicable_short_it" "no")
3667    (set_attr "type" "logic_shift_reg")]
3670 (define_insn_and_split "*arm_smax_insn"
3671   [(set (match_operand:SI          0 "s_register_operand" "=r,r")
3672         (smax:SI (match_operand:SI 1 "s_register_operand"  "%0,?r")
3673                  (match_operand:SI 2 "arm_rhs_operand"    "rI,rI")))
3674    (clobber (reg:CC CC_REGNUM))]
3675   "TARGET_ARM"
3676   "#"
3677    ; cmp\\t%1, %2\;movlt\\t%0, %2
3678    ; cmp\\t%1, %2\;movge\\t%0, %1\;movlt\\t%0, %2"
3679   "TARGET_ARM"
3680   [(set (reg:CC CC_REGNUM)
3681         (compare:CC (match_dup 1) (match_dup 2)))
3682    (set (match_dup 0)
3683         (if_then_else:SI (ge:SI (reg:CC CC_REGNUM) (const_int 0))
3684                          (match_dup 1)
3685                          (match_dup 2)))]
3686   ""
3687   [(set_attr "conds" "clob")
3688    (set_attr "length" "8,12")
3689    (set_attr "type" "multiple")]
3692 (define_expand "sminsi3"
3693   [(parallel [
3694     (set (match_operand:SI 0 "s_register_operand" "")
3695          (smin:SI (match_operand:SI 1 "s_register_operand" "")
3696                   (match_operand:SI 2 "arm_rhs_operand" "")))
3697     (clobber (reg:CC CC_REGNUM))])]
3698   "TARGET_32BIT"
3699   "
3700   if (operands[2] == const0_rtx)
3701     {
3702       /* No need for a clobber of the condition code register here.  */
3703       emit_insn (gen_rtx_SET (operands[0],
3704                               gen_rtx_SMIN (SImode, operands[1],
3705                                             operands[2])));
3706       DONE;
3707     }
3710 (define_insn "*smin_0"
3711   [(set (match_operand:SI 0 "s_register_operand" "=r")
3712         (smin:SI (match_operand:SI 1 "s_register_operand" "r")
3713                  (const_int 0)))]
3714   "TARGET_32BIT"
3715   "and%?\\t%0, %1, %1, asr #31"
3716   [(set_attr "predicable" "yes")
3717    (set_attr "predicable_short_it" "no")
3718    (set_attr "type" "logic_shift_reg")]
3721 (define_insn_and_split "*arm_smin_insn"
3722   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3723         (smin:SI (match_operand:SI 1 "s_register_operand" "%0,?r")
3724                  (match_operand:SI 2 "arm_rhs_operand" "rI,rI")))
3725    (clobber (reg:CC CC_REGNUM))]
3726   "TARGET_ARM"
3727   "#"
3728     ; cmp\\t%1, %2\;movge\\t%0, %2
3729     ; cmp\\t%1, %2\;movlt\\t%0, %1\;movge\\t%0, %2"
3730   "TARGET_ARM"
3731   [(set (reg:CC CC_REGNUM)
3732         (compare:CC (match_dup 1) (match_dup 2)))
3733    (set (match_dup 0)
3734         (if_then_else:SI (lt:SI (reg:CC CC_REGNUM) (const_int 0))
3735                          (match_dup 1)
3736                          (match_dup 2)))]
3737   ""
3738   [(set_attr "conds" "clob")
3739    (set_attr "length" "8,12")
3740    (set_attr "type" "multiple,multiple")]
3743 (define_expand "umaxsi3"
3744   [(parallel [
3745     (set (match_operand:SI 0 "s_register_operand" "")
3746          (umax:SI (match_operand:SI 1 "s_register_operand" "")
3747                   (match_operand:SI 2 "arm_rhs_operand" "")))
3748     (clobber (reg:CC CC_REGNUM))])]
3749   "TARGET_32BIT"
3750   ""
3753 (define_insn_and_split "*arm_umaxsi3"
3754   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
3755         (umax:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
3756                  (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
3757    (clobber (reg:CC CC_REGNUM))]
3758   "TARGET_ARM"
3759   "#"
3760     ; cmp\\t%1, %2\;movcc\\t%0, %2
3761     ; cmp\\t%1, %2\;movcs\\t%0, %1
3762     ; cmp\\t%1, %2\;movcs\\t%0, %1\;movcc\\t%0, %2"
3763   "TARGET_ARM"
3764   [(set (reg:CC CC_REGNUM)
3765         (compare:CC (match_dup 1) (match_dup 2)))
3766    (set (match_dup 0)
3767         (if_then_else:SI (geu:SI (reg:CC CC_REGNUM) (const_int 0))
3768                          (match_dup 1)
3769                          (match_dup 2)))]
3770   ""
3771   [(set_attr "conds" "clob")
3772    (set_attr "length" "8,8,12")
3773    (set_attr "type" "store1")]
3776 (define_expand "uminsi3"
3777   [(parallel [
3778     (set (match_operand:SI 0 "s_register_operand" "")
3779          (umin:SI (match_operand:SI 1 "s_register_operand" "")
3780                   (match_operand:SI 2 "arm_rhs_operand" "")))
3781     (clobber (reg:CC CC_REGNUM))])]
3782   "TARGET_32BIT"
3783   ""
3786 (define_insn_and_split "*arm_uminsi3"
3787   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
3788         (umin:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
3789                  (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
3790    (clobber (reg:CC CC_REGNUM))]
3791   "TARGET_ARM"
3792   "#"
3793    ; cmp\\t%1, %2\;movcs\\t%0, %2
3794    ; cmp\\t%1, %2\;movcc\\t%0, %1
3795    ; cmp\\t%1, %2\;movcc\\t%0, %1\;movcs\\t%0, %2"
3796   "TARGET_ARM"
3797   [(set (reg:CC CC_REGNUM)
3798         (compare:CC (match_dup 1) (match_dup 2)))
3799    (set (match_dup 0)
3800         (if_then_else:SI (ltu:SI (reg:CC CC_REGNUM) (const_int 0))
3801                          (match_dup 1)
3802                          (match_dup 2)))]
3803   ""
3804   [(set_attr "conds" "clob")
3805    (set_attr "length" "8,8,12")
3806    (set_attr "type" "store1")]
3809 (define_insn "*store_minmaxsi"
3810   [(set (match_operand:SI 0 "memory_operand" "=m")
3811         (match_operator:SI 3 "minmax_operator"
3812          [(match_operand:SI 1 "s_register_operand" "r")
3813           (match_operand:SI 2 "s_register_operand" "r")]))
3814    (clobber (reg:CC CC_REGNUM))]
3815   "TARGET_32BIT && optimize_function_for_size_p (cfun) && !arm_restrict_it"
3816   "*
3817   operands[3] = gen_rtx_fmt_ee (minmax_code (operands[3]), SImode,
3818                                 operands[1], operands[2]);
3819   output_asm_insn (\"cmp\\t%1, %2\", operands);
3820   if (TARGET_THUMB2)
3821     output_asm_insn (\"ite\t%d3\", operands);
3822   output_asm_insn (\"str%d3\\t%1, %0\", operands);
3823   output_asm_insn (\"str%D3\\t%2, %0\", operands);
3824   return \"\";
3825   "
3826   [(set_attr "conds" "clob")
3827    (set (attr "length")
3828         (if_then_else (eq_attr "is_thumb" "yes")
3829                       (const_int 14)
3830                       (const_int 12)))
3831    (set_attr "type" "store1")]
3834 ; Reject the frame pointer in operand[1], since reloading this after
3835 ; it has been eliminated can cause carnage.
3836 (define_insn "*minmax_arithsi"
3837   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3838         (match_operator:SI 4 "shiftable_operator"
3839          [(match_operator:SI 5 "minmax_operator"
3840            [(match_operand:SI 2 "s_register_operand" "r,r")
3841             (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
3842           (match_operand:SI 1 "s_register_operand" "0,?r")]))
3843    (clobber (reg:CC CC_REGNUM))]
3844   "TARGET_32BIT && !arm_eliminable_register (operands[1]) && !arm_restrict_it"
3845   "*
3846   {
3847     enum rtx_code code = GET_CODE (operands[4]);
3848     bool need_else;
3850     if (which_alternative != 0 || operands[3] != const0_rtx
3851         || (code != PLUS && code != IOR && code != XOR))
3852       need_else = true;
3853     else
3854       need_else = false;
3856     operands[5] = gen_rtx_fmt_ee (minmax_code (operands[5]), SImode,
3857                                   operands[2], operands[3]);
3858     output_asm_insn (\"cmp\\t%2, %3\", operands);
3859     if (TARGET_THUMB2)
3860       {
3861         if (need_else)
3862           output_asm_insn (\"ite\\t%d5\", operands);
3863         else
3864           output_asm_insn (\"it\\t%d5\", operands);
3865       }
3866     output_asm_insn (\"%i4%d5\\t%0, %1, %2\", operands);
3867     if (need_else)
3868       output_asm_insn (\"%i4%D5\\t%0, %1, %3\", operands);
3869     return \"\";
3870   }"
3871   [(set_attr "conds" "clob")
3872    (set (attr "length")
3873         (if_then_else (eq_attr "is_thumb" "yes")
3874                       (const_int 14)
3875                       (const_int 12)))
3876    (set_attr "type" "multiple")]
3879 ; Reject the frame pointer in operand[1], since reloading this after
3880 ; it has been eliminated can cause carnage.
3881 (define_insn_and_split "*minmax_arithsi_non_canon"
3882   [(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts")
3883         (minus:SI
3884          (match_operand:SI 1 "s_register_operand" "0,?Ts")
3885           (match_operator:SI 4 "minmax_operator"
3886            [(match_operand:SI 2 "s_register_operand" "Ts,Ts")
3887             (match_operand:SI 3 "arm_rhs_operand" "TsI,TsI")])))
3888    (clobber (reg:CC CC_REGNUM))]
3889   "TARGET_32BIT && !arm_eliminable_register (operands[1])
3890    && !(arm_restrict_it && CONST_INT_P (operands[3]))"
3891   "#"
3892   "TARGET_32BIT && !arm_eliminable_register (operands[1]) && reload_completed"
3893   [(set (reg:CC CC_REGNUM)
3894         (compare:CC (match_dup 2) (match_dup 3)))
3896    (cond_exec (match_op_dup 4 [(reg:CC CC_REGNUM) (const_int 0)])
3897               (set (match_dup 0)
3898                    (minus:SI (match_dup 1)
3899                              (match_dup 2))))
3900    (cond_exec (match_op_dup 5 [(reg:CC CC_REGNUM) (const_int 0)])
3901               (set (match_dup 0)
3902                    (match_dup 6)))]
3903   {
3904   machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
3905                                            operands[2], operands[3]);
3906   enum rtx_code rc = minmax_code (operands[4]);
3907   operands[4] = gen_rtx_fmt_ee (rc, VOIDmode,
3908                                 operands[2], operands[3]);
3910   if (mode == CCFPmode || mode == CCFPEmode)
3911     rc = reverse_condition_maybe_unordered (rc);
3912   else
3913     rc = reverse_condition (rc);
3914   operands[5] = gen_rtx_fmt_ee (rc, SImode, operands[2], operands[3]);
3915   if (CONST_INT_P (operands[3]))
3916     operands[6] = plus_constant (SImode, operands[1], -INTVAL (operands[3]));
3917   else
3918     operands[6] = gen_rtx_MINUS (SImode, operands[1], operands[3]);
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 (define_code_iterator SAT [smin smax])
3929 (define_code_iterator SATrev [smin smax])
3930 (define_code_attr SATlo [(smin "1") (smax "2")])
3931 (define_code_attr SAThi [(smin "2") (smax "1")])
3933 (define_insn "*satsi_<SAT:code>"
3934   [(set (match_operand:SI 0 "s_register_operand" "=r")
3935         (SAT:SI (SATrev:SI (match_operand:SI 3 "s_register_operand" "r")
3936                            (match_operand:SI 1 "const_int_operand" "i"))
3937                 (match_operand:SI 2 "const_int_operand" "i")))]
3938   "TARGET_32BIT && arm_arch6 && <SAT:CODE> != <SATrev:CODE>
3939    && arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>], NULL, NULL)"
3941   int mask;
3942   bool signed_sat;
3943   if (!arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>],
3944                                &mask, &signed_sat))
3945     gcc_unreachable ();
3947   operands[1] = GEN_INT (mask);
3948   if (signed_sat)
3949     return "ssat%?\t%0, %1, %3";
3950   else
3951     return "usat%?\t%0, %1, %3";
3953   [(set_attr "predicable" "yes")
3954    (set_attr "predicable_short_it" "no")
3955    (set_attr "type" "alus_imm")]
3958 (define_insn "*satsi_<SAT:code>_shift"
3959   [(set (match_operand:SI 0 "s_register_operand" "=r")
3960         (SAT:SI (SATrev:SI (match_operator:SI 3 "sat_shift_operator"
3961                              [(match_operand:SI 4 "s_register_operand" "r")
3962                               (match_operand:SI 5 "const_int_operand" "i")])
3963                            (match_operand:SI 1 "const_int_operand" "i"))
3964                 (match_operand:SI 2 "const_int_operand" "i")))]
3965   "TARGET_32BIT && arm_arch6 && <SAT:CODE> != <SATrev:CODE>
3966    && arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>], NULL, NULL)"
3968   int mask;
3969   bool signed_sat;
3970   if (!arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>],
3971                                &mask, &signed_sat))
3972     gcc_unreachable ();
3974   operands[1] = GEN_INT (mask);
3975   if (signed_sat)
3976     return "ssat%?\t%0, %1, %4%S3";
3977   else
3978     return "usat%?\t%0, %1, %4%S3";
3980   [(set_attr "predicable" "yes")
3981    (set_attr "predicable_short_it" "no")
3982    (set_attr "shift" "3")
3983    (set_attr "type" "logic_shift_reg")])
3985 ;; Shift and rotation insns
3987 (define_expand "ashldi3"
3988   [(set (match_operand:DI            0 "s_register_operand" "")
3989         (ashift:DI (match_operand:DI 1 "s_register_operand" "")
3990                    (match_operand:SI 2 "general_operand" "")))]
3991   "TARGET_32BIT"
3992   "
3993   if (TARGET_NEON)
3994     {
3995       /* Delay the decision whether to use NEON or core-regs until
3996          register allocation.  */
3997       emit_insn (gen_ashldi3_neon (operands[0], operands[1], operands[2]));
3998       DONE;
3999     }
4000   else
4001     {
4002       /* Only the NEON case can handle in-memory shift counts.  */
4003       if (!reg_or_int_operand (operands[2], SImode))
4004         operands[2] = force_reg (SImode, operands[2]);
4005     }
4007   if (!CONST_INT_P (operands[2]) && TARGET_REALLY_IWMMXT)
4008     ; /* No special preparation statements; expand pattern as above.  */
4009   else
4010     {
4011       rtx scratch1, scratch2;
4013       if (operands[2] == CONST1_RTX (SImode))
4014         {
4015           emit_insn (gen_arm_ashldi3_1bit (operands[0], operands[1]));
4016           DONE;
4017         }
4019       /* Ideally we should use iwmmxt here if we could know that operands[1]
4020          ends up already living in an iwmmxt register. Otherwise it's
4021          cheaper to have the alternate code being generated than moving
4022          values to iwmmxt regs and back.  */
4024       /* Expand operation using core-registers.
4025          'FAIL' would achieve the same thing, but this is a bit smarter.  */
4026       scratch1 = gen_reg_rtx (SImode);
4027       scratch2 = gen_reg_rtx (SImode);
4028       arm_emit_coreregs_64bit_shift (ASHIFT, operands[0], operands[1],
4029                                      operands[2], scratch1, scratch2);
4030       DONE;
4031     }
4032   "
4035 (define_insn "arm_ashldi3_1bit"
4036   [(set (match_operand:DI            0 "s_register_operand" "=r,&r")
4037         (ashift:DI (match_operand:DI 1 "s_register_operand" "0,r")
4038                    (const_int 1)))
4039    (clobber (reg:CC CC_REGNUM))]
4040   "TARGET_32BIT"
4041   "movs\\t%Q0, %Q1, asl #1\;adc\\t%R0, %R1, %R1"
4042   [(set_attr "conds" "clob")
4043    (set_attr "length" "8")
4044    (set_attr "type" "multiple")]
4047 (define_expand "ashlsi3"
4048   [(set (match_operand:SI            0 "s_register_operand" "")
4049         (ashift:SI (match_operand:SI 1 "s_register_operand" "")
4050                    (match_operand:SI 2 "arm_rhs_operand" "")))]
4051   "TARGET_EITHER"
4052   "
4053   if (CONST_INT_P (operands[2])
4054       && (UINTVAL (operands[2])) > 31)
4055     {
4056       emit_insn (gen_movsi (operands[0], const0_rtx));
4057       DONE;
4058     }
4059   "
4062 (define_expand "ashrdi3"
4063   [(set (match_operand:DI              0 "s_register_operand" "")
4064         (ashiftrt:DI (match_operand:DI 1 "s_register_operand" "")
4065                      (match_operand:SI 2 "reg_or_int_operand" "")))]
4066   "TARGET_32BIT"
4067   "
4068   if (TARGET_NEON)
4069     {
4070       /* Delay the decision whether to use NEON or core-regs until
4071          register allocation.  */
4072       emit_insn (gen_ashrdi3_neon (operands[0], operands[1], operands[2]));
4073       DONE;
4074     }
4076   if (!CONST_INT_P (operands[2]) && TARGET_REALLY_IWMMXT)
4077     ; /* No special preparation statements; expand pattern as above.  */
4078   else
4079     {
4080       rtx scratch1, scratch2;
4082       if (operands[2] == CONST1_RTX (SImode))
4083         {
4084           emit_insn (gen_arm_ashrdi3_1bit (operands[0], operands[1]));
4085           DONE;
4086         }
4088       /* Ideally we should use iwmmxt here if we could know that operands[1]
4089          ends up already living in an iwmmxt register. Otherwise it's
4090          cheaper to have the alternate code being generated than moving
4091          values to iwmmxt regs and back.  */
4093       /* Expand operation using core-registers.
4094          'FAIL' would achieve the same thing, but this is a bit smarter.  */
4095       scratch1 = gen_reg_rtx (SImode);
4096       scratch2 = gen_reg_rtx (SImode);
4097       arm_emit_coreregs_64bit_shift (ASHIFTRT, operands[0], operands[1],
4098                                      operands[2], scratch1, scratch2);
4099       DONE;
4100     }
4101   "
4104 (define_insn "arm_ashrdi3_1bit"
4105   [(set (match_operand:DI              0 "s_register_operand" "=r,&r")
4106         (ashiftrt:DI (match_operand:DI 1 "s_register_operand" "0,r")
4107                      (const_int 1)))
4108    (clobber (reg:CC CC_REGNUM))]
4109   "TARGET_32BIT"
4110   "movs\\t%R0, %R1, asr #1\;mov\\t%Q0, %Q1, rrx"
4111   [(set_attr "conds" "clob")
4112    (set_attr "length" "8")
4113    (set_attr "type" "multiple")]
4116 (define_expand "ashrsi3"
4117   [(set (match_operand:SI              0 "s_register_operand" "")
4118         (ashiftrt:SI (match_operand:SI 1 "s_register_operand" "")
4119                      (match_operand:SI 2 "arm_rhs_operand" "")))]
4120   "TARGET_EITHER"
4121   "
4122   if (CONST_INT_P (operands[2])
4123       && UINTVAL (operands[2]) > 31)
4124     operands[2] = GEN_INT (31);
4125   "
4128 (define_expand "lshrdi3"
4129   [(set (match_operand:DI              0 "s_register_operand" "")
4130         (lshiftrt:DI (match_operand:DI 1 "s_register_operand" "")
4131                      (match_operand:SI 2 "reg_or_int_operand" "")))]
4132   "TARGET_32BIT"
4133   "
4134   if (TARGET_NEON)
4135     {
4136       /* Delay the decision whether to use NEON or core-regs until
4137          register allocation.  */
4138       emit_insn (gen_lshrdi3_neon (operands[0], operands[1], operands[2]));
4139       DONE;
4140     }
4142   if (!CONST_INT_P (operands[2]) && TARGET_REALLY_IWMMXT)
4143     ; /* No special preparation statements; expand pattern as above.  */
4144   else
4145     {
4146       rtx scratch1, scratch2;
4148       if (operands[2] == CONST1_RTX (SImode))
4149         {
4150           emit_insn (gen_arm_lshrdi3_1bit (operands[0], operands[1]));
4151           DONE;
4152         }
4154       /* Ideally we should use iwmmxt here if we could know that operands[1]
4155          ends up already living in an iwmmxt register. Otherwise it's
4156          cheaper to have the alternate code being generated than moving
4157          values to iwmmxt regs and back.  */
4159       /* Expand operation using core-registers.
4160          'FAIL' would achieve the same thing, but this is a bit smarter.  */
4161       scratch1 = gen_reg_rtx (SImode);
4162       scratch2 = gen_reg_rtx (SImode);
4163       arm_emit_coreregs_64bit_shift (LSHIFTRT, operands[0], operands[1],
4164                                      operands[2], scratch1, scratch2);
4165       DONE;
4166     }
4167   "
4170 (define_insn "arm_lshrdi3_1bit"
4171   [(set (match_operand:DI              0 "s_register_operand" "=r,&r")
4172         (lshiftrt:DI (match_operand:DI 1 "s_register_operand" "0,r")
4173                      (const_int 1)))
4174    (clobber (reg:CC CC_REGNUM))]
4175   "TARGET_32BIT"
4176   "movs\\t%R0, %R1, lsr #1\;mov\\t%Q0, %Q1, rrx"
4177   [(set_attr "conds" "clob")
4178    (set_attr "length" "8")
4179    (set_attr "type" "multiple")]
4182 (define_expand "lshrsi3"
4183   [(set (match_operand:SI              0 "s_register_operand" "")
4184         (lshiftrt:SI (match_operand:SI 1 "s_register_operand" "")
4185                      (match_operand:SI 2 "arm_rhs_operand" "")))]
4186   "TARGET_EITHER"
4187   "
4188   if (CONST_INT_P (operands[2])
4189       && (UINTVAL (operands[2])) > 31)
4190     {
4191       emit_insn (gen_movsi (operands[0], const0_rtx));
4192       DONE;
4193     }
4194   "
4197 (define_expand "rotlsi3"
4198   [(set (match_operand:SI              0 "s_register_operand" "")
4199         (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
4200                      (match_operand:SI 2 "reg_or_int_operand" "")))]
4201   "TARGET_32BIT"
4202   "
4203   if (CONST_INT_P (operands[2]))
4204     operands[2] = GEN_INT ((32 - INTVAL (operands[2])) % 32);
4205   else
4206     {
4207       rtx reg = gen_reg_rtx (SImode);
4208       emit_insn (gen_subsi3 (reg, GEN_INT (32), operands[2]));
4209       operands[2] = reg;
4210     }
4211   "
4214 (define_expand "rotrsi3"
4215   [(set (match_operand:SI              0 "s_register_operand" "")
4216         (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
4217                      (match_operand:SI 2 "arm_rhs_operand" "")))]
4218   "TARGET_EITHER"
4219   "
4220   if (TARGET_32BIT)
4221     {
4222       if (CONST_INT_P (operands[2])
4223           && UINTVAL (operands[2]) > 31)
4224         operands[2] = GEN_INT (INTVAL (operands[2]) % 32);
4225     }
4226   else /* TARGET_THUMB1 */
4227     {
4228       if (CONST_INT_P (operands [2]))
4229         operands [2] = force_reg (SImode, operands[2]);
4230     }
4231   "
4234 (define_insn "*arm_shiftsi3"
4235   [(set (match_operand:SI   0 "s_register_operand" "=l,l,r,r")
4236         (match_operator:SI  3 "shift_operator"
4237          [(match_operand:SI 1 "s_register_operand"  "0,l,r,r")
4238           (match_operand:SI 2 "reg_or_int_operand" "l,M,M,r")]))]
4239   "TARGET_32BIT"
4240   "* return arm_output_shift(operands, 0);"
4241   [(set_attr "predicable" "yes")
4242    (set_attr "arch" "t2,t2,*,*")
4243    (set_attr "predicable_short_it" "yes,yes,no,no")
4244    (set_attr "length" "4")
4245    (set_attr "shift" "1")
4246    (set_attr "type" "alu_shift_reg,alu_shift_imm,alu_shift_imm,alu_shift_reg")]
4249 (define_insn "*shiftsi3_compare0"
4250   [(set (reg:CC_NOOV CC_REGNUM)
4251         (compare:CC_NOOV (match_operator:SI 3 "shift_operator"
4252                           [(match_operand:SI 1 "s_register_operand" "r,r")
4253                            (match_operand:SI 2 "arm_rhs_operand" "M,r")])
4254                          (const_int 0)))
4255    (set (match_operand:SI 0 "s_register_operand" "=r,r")
4256         (match_op_dup 3 [(match_dup 1) (match_dup 2)]))]
4257   "TARGET_32BIT"
4258   "* return arm_output_shift(operands, 1);"
4259   [(set_attr "conds" "set")
4260    (set_attr "shift" "1")
4261    (set_attr "type" "alus_shift_imm,alus_shift_reg")]
4264 (define_insn "*shiftsi3_compare0_scratch"
4265   [(set (reg:CC_NOOV CC_REGNUM)
4266         (compare:CC_NOOV (match_operator:SI 3 "shift_operator"
4267                           [(match_operand:SI 1 "s_register_operand" "r,r")
4268                            (match_operand:SI 2 "arm_rhs_operand" "M,r")])
4269                          (const_int 0)))
4270    (clobber (match_scratch:SI 0 "=r,r"))]
4271   "TARGET_32BIT"
4272   "* return arm_output_shift(operands, 1);"
4273   [(set_attr "conds" "set")
4274    (set_attr "shift" "1")
4275    (set_attr "type" "shift_imm,shift_reg")]
4278 (define_insn "*not_shiftsi"
4279   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4280         (not:SI (match_operator:SI 3 "shift_operator"
4281                  [(match_operand:SI 1 "s_register_operand" "r,r")
4282                   (match_operand:SI 2 "shift_amount_operand" "M,rM")])))]
4283   "TARGET_32BIT"
4284   "mvn%?\\t%0, %1%S3"
4285   [(set_attr "predicable" "yes")
4286    (set_attr "predicable_short_it" "no")
4287    (set_attr "shift" "1")
4288    (set_attr "arch" "32,a")
4289    (set_attr "type" "mvn_shift,mvn_shift_reg")])
4291 (define_insn "*not_shiftsi_compare0"
4292   [(set (reg:CC_NOOV CC_REGNUM)
4293         (compare:CC_NOOV
4294          (not:SI (match_operator:SI 3 "shift_operator"
4295                   [(match_operand:SI 1 "s_register_operand" "r,r")
4296                    (match_operand:SI 2 "shift_amount_operand" "M,rM")]))
4297          (const_int 0)))
4298    (set (match_operand:SI 0 "s_register_operand" "=r,r")
4299         (not:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])))]
4300   "TARGET_32BIT"
4301   "mvns%?\\t%0, %1%S3"
4302   [(set_attr "conds" "set")
4303    (set_attr "shift" "1")
4304    (set_attr "arch" "32,a")
4305    (set_attr "type" "mvn_shift,mvn_shift_reg")])
4307 (define_insn "*not_shiftsi_compare0_scratch"
4308   [(set (reg:CC_NOOV CC_REGNUM)
4309         (compare:CC_NOOV
4310          (not:SI (match_operator:SI 3 "shift_operator"
4311                   [(match_operand:SI 1 "s_register_operand" "r,r")
4312                    (match_operand:SI 2 "shift_amount_operand" "M,rM")]))
4313          (const_int 0)))
4314    (clobber (match_scratch:SI 0 "=r,r"))]
4315   "TARGET_32BIT"
4316   "mvns%?\\t%0, %1%S3"
4317   [(set_attr "conds" "set")
4318    (set_attr "shift" "1")
4319    (set_attr "arch" "32,a")
4320    (set_attr "type" "mvn_shift,mvn_shift_reg")])
4322 ;; We don't really have extzv, but defining this using shifts helps
4323 ;; to reduce register pressure later on.
4325 (define_expand "extzv"
4326   [(set (match_operand 0 "s_register_operand" "")
4327         (zero_extract (match_operand 1 "nonimmediate_operand" "")
4328                       (match_operand 2 "const_int_operand" "")
4329                       (match_operand 3 "const_int_operand" "")))]
4330   "TARGET_THUMB1 || arm_arch_thumb2"
4331   "
4332   {
4333     HOST_WIDE_INT lshift = 32 - INTVAL (operands[2]) - INTVAL (operands[3]);
4334     HOST_WIDE_INT rshift = 32 - INTVAL (operands[2]);
4335     
4336     if (arm_arch_thumb2)
4337       {
4338         HOST_WIDE_INT width = INTVAL (operands[2]);
4339         HOST_WIDE_INT bitpos = INTVAL (operands[3]);
4341         if (unaligned_access && MEM_P (operands[1])
4342             && (width == 16 || width == 32) && (bitpos % BITS_PER_UNIT) == 0)
4343           {
4344             rtx base_addr;
4346             if (BYTES_BIG_ENDIAN)
4347               bitpos = GET_MODE_BITSIZE (GET_MODE (operands[0])) - width
4348                        - bitpos;
4350             if (width == 32)
4351               {
4352                 base_addr = adjust_address (operands[1], SImode,
4353                                             bitpos / BITS_PER_UNIT);
4354                 emit_insn (gen_unaligned_loadsi (operands[0], base_addr));
4355               }
4356             else
4357               {
4358                 rtx dest = operands[0];
4359                 rtx tmp = gen_reg_rtx (SImode);
4361                 /* We may get a paradoxical subreg here.  Strip it off.  */
4362                 if (GET_CODE (dest) == SUBREG
4363                     && GET_MODE (dest) == SImode
4364                     && GET_MODE (SUBREG_REG (dest)) == HImode)
4365                   dest = SUBREG_REG (dest);
4367                 if (GET_MODE_BITSIZE (GET_MODE (dest)) != width)
4368                   FAIL;
4370                 base_addr = adjust_address (operands[1], HImode,
4371                                             bitpos / BITS_PER_UNIT);
4372                 emit_insn (gen_unaligned_loadhiu (tmp, base_addr));
4373                 emit_move_insn (gen_lowpart (SImode, dest), tmp);
4374               }
4375             DONE;
4376           }
4377         else if (s_register_operand (operands[1], GET_MODE (operands[1])))
4378           {
4379             emit_insn (gen_extzv_t2 (operands[0], operands[1], operands[2],
4380                                      operands[3]));
4381             DONE;
4382           }
4383         else
4384           FAIL;
4385       }
4386     
4387     if (!s_register_operand (operands[1], GET_MODE (operands[1])))
4388       FAIL;
4390     operands[3] = GEN_INT (rshift);
4391     
4392     if (lshift == 0)
4393       {
4394         emit_insn (gen_lshrsi3 (operands[0], operands[1], operands[3]));
4395         DONE;
4396       }
4397       
4398     emit_insn (gen_extzv_t1 (operands[0], operands[1], GEN_INT (lshift),
4399                              operands[3], gen_reg_rtx (SImode)));
4400     DONE;
4401   }"
4404 ;; Helper for extzv, for the Thumb-1 register-shifts case.
4406 (define_expand "extzv_t1"
4407   [(set (match_operand:SI 4 "s_register_operand" "")
4408         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
4409                    (match_operand:SI 2 "const_int_operand" "")))
4410    (set (match_operand:SI 0 "s_register_operand" "")
4411         (lshiftrt:SI (match_dup 4)
4412                      (match_operand:SI 3 "const_int_operand" "")))]
4413   "TARGET_THUMB1"
4414   "")
4416 (define_expand "extv"
4417   [(set (match_operand 0 "s_register_operand" "")
4418         (sign_extract (match_operand 1 "nonimmediate_operand" "")
4419                       (match_operand 2 "const_int_operand" "")
4420                       (match_operand 3 "const_int_operand" "")))]
4421   "arm_arch_thumb2"
4423   HOST_WIDE_INT width = INTVAL (operands[2]);
4424   HOST_WIDE_INT bitpos = INTVAL (operands[3]);
4426   if (unaligned_access && MEM_P (operands[1]) && (width == 16 || width == 32)
4427       && (bitpos % BITS_PER_UNIT)  == 0)
4428     {
4429       rtx base_addr;
4430       
4431       if (BYTES_BIG_ENDIAN)
4432         bitpos = GET_MODE_BITSIZE (GET_MODE (operands[0])) - width - bitpos;
4433       
4434       if (width == 32)
4435         {
4436           base_addr = adjust_address (operands[1], SImode,
4437                                       bitpos / BITS_PER_UNIT);
4438           emit_insn (gen_unaligned_loadsi (operands[0], base_addr));
4439         }
4440       else
4441         {
4442           rtx dest = operands[0];
4443           rtx tmp = gen_reg_rtx (SImode);
4444           
4445           /* We may get a paradoxical subreg here.  Strip it off.  */
4446           if (GET_CODE (dest) == SUBREG
4447               && GET_MODE (dest) == SImode
4448               && GET_MODE (SUBREG_REG (dest)) == HImode)
4449             dest = SUBREG_REG (dest);
4450           
4451           if (GET_MODE_BITSIZE (GET_MODE (dest)) != width)
4452             FAIL;
4453           
4454           base_addr = adjust_address (operands[1], HImode,
4455                                       bitpos / BITS_PER_UNIT);
4456           emit_insn (gen_unaligned_loadhis (tmp, base_addr));
4457           emit_move_insn (gen_lowpart (SImode, dest), tmp);
4458         }
4460       DONE;
4461     }
4462   else if (!s_register_operand (operands[1], GET_MODE (operands[1])))
4463     FAIL;
4464   else if (GET_MODE (operands[0]) == SImode
4465            && GET_MODE (operands[1]) == SImode)
4466     {
4467       emit_insn (gen_extv_regsi (operands[0], operands[1], operands[2],
4468                                  operands[3]));
4469       DONE;
4470     }
4472   FAIL;
4475 ; Helper to expand register forms of extv with the proper modes.
4477 (define_expand "extv_regsi"
4478   [(set (match_operand:SI 0 "s_register_operand" "")
4479         (sign_extract:SI (match_operand:SI 1 "s_register_operand" "")
4480                          (match_operand 2 "const_int_operand" "")
4481                          (match_operand 3 "const_int_operand" "")))]
4482   ""
4486 ; ARMv6+ unaligned load/store instructions (used for packed structure accesses).
4488 (define_insn "unaligned_loadsi"
4489   [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4490         (unspec:SI [(match_operand:SI 1 "memory_operand" "Uw,m")]
4491                    UNSPEC_UNALIGNED_LOAD))]
4492   "unaligned_access"
4493   "ldr%?\t%0, %1\t@ unaligned"
4494   [(set_attr "arch" "t2,any")
4495    (set_attr "length" "2,4")
4496    (set_attr "predicable" "yes")
4497    (set_attr "predicable_short_it" "yes,no")
4498    (set_attr "type" "load1")])
4500 (define_insn "unaligned_loadhis"
4501   [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4502         (sign_extend:SI
4503           (unspec:HI [(match_operand:HI 1 "memory_operand" "Uw,Uh")]
4504                      UNSPEC_UNALIGNED_LOAD)))]
4505   "unaligned_access"
4506   "ldrsh%?\t%0, %1\t@ unaligned"
4507   [(set_attr "arch" "t2,any")
4508    (set_attr "length" "2,4")
4509    (set_attr "predicable" "yes")
4510    (set_attr "predicable_short_it" "yes,no")
4511    (set_attr "type" "load_byte")])
4513 (define_insn "unaligned_loadhiu"
4514   [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4515         (zero_extend:SI
4516           (unspec:HI [(match_operand:HI 1 "memory_operand" "Uw,m")]
4517                      UNSPEC_UNALIGNED_LOAD)))]
4518   "unaligned_access"
4519   "ldrh%?\t%0, %1\t@ unaligned"
4520   [(set_attr "arch" "t2,any")
4521    (set_attr "length" "2,4")
4522    (set_attr "predicable" "yes")
4523    (set_attr "predicable_short_it" "yes,no")
4524    (set_attr "type" "load_byte")])
4526 (define_insn "unaligned_storesi"
4527   [(set (match_operand:SI 0 "memory_operand" "=Uw,m")
4528         (unspec:SI [(match_operand:SI 1 "s_register_operand" "l,r")]
4529                    UNSPEC_UNALIGNED_STORE))]
4530   "unaligned_access"
4531   "str%?\t%1, %0\t@ unaligned"
4532   [(set_attr "arch" "t2,any")
4533    (set_attr "length" "2,4")
4534    (set_attr "predicable" "yes")
4535    (set_attr "predicable_short_it" "yes,no")
4536    (set_attr "type" "store1")])
4538 (define_insn "unaligned_storehi"
4539   [(set (match_operand:HI 0 "memory_operand" "=Uw,m")
4540         (unspec:HI [(match_operand:HI 1 "s_register_operand" "l,r")]
4541                    UNSPEC_UNALIGNED_STORE))]
4542   "unaligned_access"
4543   "strh%?\t%1, %0\t@ unaligned"
4544   [(set_attr "arch" "t2,any")
4545    (set_attr "length" "2,4")
4546    (set_attr "predicable" "yes")
4547    (set_attr "predicable_short_it" "yes,no")
4548    (set_attr "type" "store1")])
4551 (define_insn "*extv_reg"
4552   [(set (match_operand:SI 0 "s_register_operand" "=r")
4553         (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
4554                           (match_operand:SI 2 "const_int_operand" "n")
4555                           (match_operand:SI 3 "const_int_operand" "n")))]
4556   "arm_arch_thumb2
4557    && IN_RANGE (INTVAL (operands[3]), 0, 31)
4558    && IN_RANGE (INTVAL (operands[2]), 1, 32 - INTVAL (operands[3]))"
4559   "sbfx%?\t%0, %1, %3, %2"
4560   [(set_attr "length" "4")
4561    (set_attr "predicable" "yes")
4562    (set_attr "predicable_short_it" "no")
4563    (set_attr "type" "bfm")]
4566 (define_insn "extzv_t2"
4567   [(set (match_operand:SI 0 "s_register_operand" "=r")
4568         (zero_extract:SI (match_operand:SI 1 "s_register_operand" "r")
4569                           (match_operand:SI 2 "const_int_operand" "n")
4570                           (match_operand:SI 3 "const_int_operand" "n")))]
4571   "arm_arch_thumb2
4572    && IN_RANGE (INTVAL (operands[3]), 0, 31)
4573    && IN_RANGE (INTVAL (operands[2]), 1, 32 - INTVAL (operands[3]))"
4574   "ubfx%?\t%0, %1, %3, %2"
4575   [(set_attr "length" "4")
4576    (set_attr "predicable" "yes")
4577    (set_attr "predicable_short_it" "no")
4578    (set_attr "type" "bfm")]
4582 ;; Division instructions
4583 (define_insn "divsi3"
4584   [(set (match_operand:SI         0 "s_register_operand" "=r,r")
4585         (div:SI (match_operand:SI 1 "s_register_operand"  "r,r")
4586                 (match_operand:SI 2 "s_register_operand"  "r,r")))]
4587   "TARGET_IDIV"
4588   "@
4589    sdiv%?\t%0, %1, %2
4590    sdiv\t%0, %1, %2"
4591   [(set_attr "arch" "32,v8mb")
4592    (set_attr "predicable" "yes")
4593    (set_attr "predicable_short_it" "no")
4594    (set_attr "type" "sdiv")]
4597 (define_insn "udivsi3"
4598   [(set (match_operand:SI          0 "s_register_operand" "=r,r")
4599         (udiv:SI (match_operand:SI 1 "s_register_operand"  "r,r")
4600                  (match_operand:SI 2 "s_register_operand"  "r,r")))]
4601   "TARGET_IDIV"
4602   "@
4603    udiv%?\t%0, %1, %2
4604    udiv\t%0, %1, %2"
4605   [(set_attr "arch" "32,v8mb")
4606    (set_attr "predicable" "yes")
4607    (set_attr "predicable_short_it" "no")
4608    (set_attr "type" "udiv")]
4612 ;; Unary arithmetic insns
4614 (define_expand "negvsi3"
4615   [(match_operand:SI 0 "register_operand")
4616    (match_operand:SI 1 "register_operand")
4617    (match_operand 2 "")]
4618   "TARGET_32BIT"
4620   emit_insn (gen_subsi3_compare (operands[0], const0_rtx, operands[1]));
4621   arm_gen_unlikely_cbranch (NE, CC_Vmode, operands[2]);
4623   DONE;
4626 (define_expand "negvdi3"
4627   [(match_operand:DI 0 "register_operand")
4628    (match_operand:DI 1 "register_operand")
4629    (match_operand 2 "")]
4630   "TARGET_ARM"
4632   emit_insn (gen_negdi2_compare (operands[0], operands[1]));
4633   arm_gen_unlikely_cbranch (NE, CC_Vmode, operands[2]);
4635   DONE;
4639 (define_insn_and_split "negdi2_compare"
4640   [(set (reg:CC CC_REGNUM)
4641         (compare:CC
4642           (const_int 0)
4643           (match_operand:DI 1 "register_operand" "0,r")))
4644    (set (match_operand:DI 0 "register_operand" "=r,&r")
4645         (minus:DI (const_int 0) (match_dup 1)))]
4646   "TARGET_ARM"
4647   "#"
4648   "&& reload_completed"
4649   [(parallel [(set (reg:CC CC_REGNUM)
4650                    (compare:CC (const_int 0) (match_dup 1)))
4651               (set (match_dup 0) (minus:SI (const_int 0)
4652                                            (match_dup 1)))])
4653    (parallel [(set (reg:CC CC_REGNUM)
4654                    (compare:CC (const_int 0) (match_dup 3)))
4655              (set (match_dup 2)
4656                   (minus:SI
4657                    (minus:SI (const_int 0) (match_dup 3))
4658                    (ltu:SI (reg:CC_C CC_REGNUM)
4659                            (const_int 0))))])]
4660   {
4661     operands[2] = gen_highpart (SImode, operands[0]);
4662     operands[0] = gen_lowpart (SImode, operands[0]);
4663     operands[3] = gen_highpart (SImode, operands[1]);
4664     operands[1] = gen_lowpart (SImode, operands[1]);
4665   }
4666   [(set_attr "conds" "set")
4667    (set_attr "length" "8")
4668    (set_attr "type" "multiple")]
4671 (define_expand "negdi2"
4672  [(parallel
4673    [(set (match_operand:DI 0 "s_register_operand" "")
4674          (neg:DI (match_operand:DI 1 "s_register_operand" "")))
4675     (clobber (reg:CC CC_REGNUM))])]
4676   "TARGET_EITHER"
4677   {
4678     if (TARGET_NEON)
4679       {
4680         emit_insn (gen_negdi2_neon (operands[0], operands[1]));
4681         DONE;
4682       }
4683   }
4686 ;; The constraints here are to prevent a *partial* overlap (where %Q0 == %R1).
4687 ;; The first alternative allows the common case of a *full* overlap.
4688 (define_insn_and_split "*negdi2_insn"
4689   [(set (match_operand:DI         0 "s_register_operand" "=r,&r")
4690         (neg:DI (match_operand:DI 1 "s_register_operand"  "0,r")))
4691    (clobber (reg:CC CC_REGNUM))]
4692   "TARGET_32BIT"
4693   "#"   ; rsbs %Q0, %Q1, #0; rsc %R0, %R1, #0          (ARM)
4694         ; negs %Q0, %Q1    ; sbc %R0, %R1, %R1, lsl #1 (Thumb-2)
4695   "&& reload_completed"
4696   [(parallel [(set (reg:CC CC_REGNUM)
4697                    (compare:CC (const_int 0) (match_dup 1)))
4698               (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1)))])
4699    (set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3))
4700                                 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
4701   {
4702     operands[2] = gen_highpart (SImode, operands[0]);
4703     operands[0] = gen_lowpart (SImode, operands[0]);
4704     operands[3] = gen_highpart (SImode, operands[1]);
4705     operands[1] = gen_lowpart (SImode, operands[1]);
4706   }
4707   [(set_attr "conds" "clob")
4708    (set_attr "length" "8")
4709    (set_attr "type" "multiple")]
4712 (define_insn "*negsi2_carryin_compare"
4713   [(set (reg:CC CC_REGNUM)
4714         (compare:CC (const_int 0)
4715                     (match_operand:SI 1 "s_register_operand" "r")))
4716    (set (match_operand:SI 0 "s_register_operand" "=r")
4717         (minus:SI (minus:SI (const_int 0)
4718                             (match_dup 1))
4719                   (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
4720   "TARGET_ARM"
4721   "rscs\\t%0, %1, #0"
4722   [(set_attr "conds" "set")
4723    (set_attr "type" "alus_imm")]
4726 (define_expand "negsi2"
4727   [(set (match_operand:SI         0 "s_register_operand" "")
4728         (neg:SI (match_operand:SI 1 "s_register_operand" "")))]
4729   "TARGET_EITHER"
4730   ""
4733 (define_insn "*arm_negsi2"
4734   [(set (match_operand:SI         0 "s_register_operand" "=l,r")
4735         (neg:SI (match_operand:SI 1 "s_register_operand" "l,r")))]
4736   "TARGET_32BIT"
4737   "rsb%?\\t%0, %1, #0"
4738   [(set_attr "predicable" "yes")
4739    (set_attr "predicable_short_it" "yes,no")
4740    (set_attr "arch" "t2,*")
4741    (set_attr "length" "4")
4742    (set_attr "type" "alu_sreg")]
4745 (define_expand "negsf2"
4746   [(set (match_operand:SF         0 "s_register_operand" "")
4747         (neg:SF (match_operand:SF 1 "s_register_operand" "")))]
4748   "TARGET_32BIT && TARGET_HARD_FLOAT"
4749   ""
4752 (define_expand "negdf2"
4753   [(set (match_operand:DF         0 "s_register_operand" "")
4754         (neg:DF (match_operand:DF 1 "s_register_operand" "")))]
4755   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
4756   "")
4758 (define_insn_and_split "*zextendsidi_negsi"
4759   [(set (match_operand:DI 0 "s_register_operand" "=r")
4760         (zero_extend:DI (neg:SI (match_operand:SI 1 "s_register_operand" "r"))))]
4761    "TARGET_32BIT"
4762    "#"
4763    ""
4764    [(set (match_dup 2)
4765          (neg:SI (match_dup 1)))
4766     (set (match_dup 3)
4767          (const_int 0))]
4768    {
4769       operands[2] = gen_lowpart (SImode, operands[0]);
4770       operands[3] = gen_highpart (SImode, operands[0]);
4771    }
4772  [(set_attr "length" "8")
4773   (set_attr "type" "multiple")]
4776 ;; Negate an extended 32-bit value.
4777 (define_insn_and_split "*negdi_extendsidi"
4778   [(set (match_operand:DI 0 "s_register_operand" "=l,r")
4779         (neg:DI (sign_extend:DI
4780                  (match_operand:SI 1 "s_register_operand" "l,r"))))
4781    (clobber (reg:CC CC_REGNUM))]
4782   "TARGET_32BIT"
4783   "#"
4784   "&& reload_completed"
4785   [(const_int 0)]
4786   {
4787     rtx low = gen_lowpart (SImode, operands[0]);
4788     rtx high = gen_highpart (SImode, operands[0]);
4790     if (reg_overlap_mentioned_p (low, operands[1]))
4791       {
4792         /* Input overlaps the low word of the output.  Use:
4793                 asr     Rhi, Rin, #31
4794                 rsbs    Rlo, Rin, #0
4795                 rsc     Rhi, Rhi, #0 (thumb2: sbc Rhi, Rhi, Rhi, lsl #1).  */
4796         rtx cc_reg = gen_rtx_REG (CC_Cmode, CC_REGNUM);
4798         emit_insn (gen_rtx_SET (high,
4799                                 gen_rtx_ASHIFTRT (SImode, operands[1],
4800                                                   GEN_INT (31))));
4802         emit_insn (gen_subsi3_compare (low, const0_rtx, operands[1]));
4803         if (TARGET_ARM)
4804           emit_insn (gen_rtx_SET (high,
4805                                   gen_rtx_MINUS (SImode,
4806                                                  gen_rtx_MINUS (SImode,
4807                                                                 const0_rtx,
4808                                                                 high),
4809                                                  gen_rtx_LTU (SImode,
4810                                                               cc_reg,
4811                                                               const0_rtx))));
4812         else
4813           {
4814             rtx two_x = gen_rtx_ASHIFT (SImode, high, GEN_INT (1));
4815             emit_insn (gen_rtx_SET (high,
4816                                     gen_rtx_MINUS (SImode,
4817                                                    gen_rtx_MINUS (SImode,
4818                                                                   high,
4819                                                                   two_x),
4820                                                    gen_rtx_LTU (SImode,
4821                                                                 cc_reg,
4822                                                                 const0_rtx))));
4823           }
4824       }
4825     else
4826       {
4827         /* No overlap, or overlap on high word.  Use:
4828                 rsb     Rlo, Rin, #0
4829                 bic     Rhi, Rlo, Rin
4830                 asr     Rhi, Rhi, #31
4831            Flags not needed for this sequence.  */
4832         emit_insn (gen_rtx_SET (low, gen_rtx_NEG (SImode, operands[1])));
4833         emit_insn (gen_rtx_SET (high,
4834                                 gen_rtx_AND (SImode,
4835                                              gen_rtx_NOT (SImode, operands[1]),
4836                                              low)));
4837         emit_insn (gen_rtx_SET (high,
4838                                 gen_rtx_ASHIFTRT (SImode, high,
4839                                                   GEN_INT (31))));
4840       }
4841     DONE;
4842   }
4843   [(set_attr "length" "12")
4844    (set_attr "arch" "t2,*")
4845    (set_attr "type" "multiple")]
4848 (define_insn_and_split "*negdi_zero_extendsidi"
4849   [(set (match_operand:DI 0 "s_register_operand" "=r,&r")
4850         (neg:DI (zero_extend:DI (match_operand:SI 1 "s_register_operand" "0,r"))))
4851    (clobber (reg:CC CC_REGNUM))]
4852   "TARGET_32BIT"
4853   "#" ; "rsbs\\t%Q0, %1, #0\;sbc\\t%R0,%R0,%R0"
4854       ;; Don't care what register is input to sbc,
4855       ;; since we just need to propagate the carry.
4856   "&& reload_completed"
4857   [(parallel [(set (reg:CC CC_REGNUM)
4858                    (compare:CC (const_int 0) (match_dup 1)))
4859               (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1)))])
4860    (set (match_dup 2) (minus:SI (minus:SI (match_dup 2) (match_dup 2))
4861                                 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
4862   {
4863     operands[2] = gen_highpart (SImode, operands[0]);
4864     operands[0] = gen_lowpart (SImode, operands[0]);
4865   }
4866   [(set_attr "conds" "clob")
4867    (set_attr "length" "8")
4868    (set_attr "type" "multiple")]   ;; length in thumb is 4
4871 ;; abssi2 doesn't really clobber the condition codes if a different register
4872 ;; is being set.  To keep things simple, assume during rtl manipulations that
4873 ;; it does, but tell the final scan operator the truth.  Similarly for
4874 ;; (neg (abs...))
4876 (define_expand "abssi2"
4877   [(parallel
4878     [(set (match_operand:SI         0 "s_register_operand" "")
4879           (abs:SI (match_operand:SI 1 "s_register_operand" "")))
4880      (clobber (match_dup 2))])]
4881   "TARGET_EITHER"
4882   "
4883   if (TARGET_THUMB1)
4884     operands[2] = gen_rtx_SCRATCH (SImode);
4885   else
4886     operands[2] = gen_rtx_REG (CCmode, CC_REGNUM);
4889 (define_insn_and_split "*arm_abssi2"
4890   [(set (match_operand:SI 0 "s_register_operand" "=r,&r")
4891         (abs:SI (match_operand:SI 1 "s_register_operand" "0,r")))
4892    (clobber (reg:CC CC_REGNUM))]
4893   "TARGET_ARM"
4894   "#"
4895   "&& reload_completed"
4896   [(const_int 0)]
4897   {
4898    /* if (which_alternative == 0) */
4899    if (REGNO(operands[0]) == REGNO(operands[1]))
4900      {
4901       /* Emit the pattern:
4902          cmp\\t%0, #0\;rsblt\\t%0, %0, #0
4903          [(set (reg:CC CC_REGNUM)
4904                (compare:CC (match_dup 0) (const_int 0)))
4905           (cond_exec (lt:CC (reg:CC CC_REGNUM) (const_int 0))
4906                      (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1))))]
4907       */
4908       emit_insn (gen_rtx_SET (gen_rtx_REG (CCmode, CC_REGNUM),
4909                               gen_rtx_COMPARE (CCmode, operands[0], const0_rtx)));
4910       emit_insn (gen_rtx_COND_EXEC (VOIDmode,
4911                                     (gen_rtx_LT (SImode,
4912                                                  gen_rtx_REG (CCmode, CC_REGNUM),
4913                                                  const0_rtx)),
4914                                     (gen_rtx_SET (operands[0],
4915                                                   (gen_rtx_MINUS (SImode,
4916                                                                   const0_rtx,
4917                                                                   operands[1]))))));
4918       DONE;
4919      }
4920    else
4921      {
4922       /* Emit the pattern:
4923          alt1: eor%?\\t%0, %1, %1, asr #31\;sub%?\\t%0, %0, %1, asr #31
4924          [(set (match_dup 0)
4925                (xor:SI (match_dup 1)
4926                        (ashiftrt:SI (match_dup 1) (const_int 31))))
4927           (set (match_dup 0)
4928                (minus:SI (match_dup 0)
4929                       (ashiftrt:SI (match_dup 1) (const_int 31))))]
4930       */
4931       emit_insn (gen_rtx_SET (operands[0],
4932                               gen_rtx_XOR (SImode,
4933                                            gen_rtx_ASHIFTRT (SImode,
4934                                                              operands[1],
4935                                                              GEN_INT (31)),
4936                                            operands[1])));
4937       emit_insn (gen_rtx_SET (operands[0],
4938                               gen_rtx_MINUS (SImode,
4939                                              operands[0],
4940                                              gen_rtx_ASHIFTRT (SImode,
4941                                                                operands[1],
4942                                                                GEN_INT (31)))));
4943       DONE;
4944      }
4945   }
4946   [(set_attr "conds" "clob,*")
4947    (set_attr "shift" "1")
4948    (set_attr "predicable" "no, yes")
4949    (set_attr "length" "8")
4950    (set_attr "type" "multiple")]
4953 (define_insn_and_split "*arm_neg_abssi2"
4954   [(set (match_operand:SI 0 "s_register_operand" "=r,&r")
4955         (neg:SI (abs:SI (match_operand:SI 1 "s_register_operand" "0,r"))))
4956    (clobber (reg:CC CC_REGNUM))]
4957   "TARGET_ARM"
4958   "#"
4959   "&& reload_completed"
4960   [(const_int 0)]
4961   {
4962    /* if (which_alternative == 0) */
4963    if (REGNO (operands[0]) == REGNO (operands[1]))
4964      {
4965       /* Emit the pattern:
4966          cmp\\t%0, #0\;rsbgt\\t%0, %0, #0
4967       */
4968       emit_insn (gen_rtx_SET (gen_rtx_REG (CCmode, CC_REGNUM),
4969                               gen_rtx_COMPARE (CCmode, operands[0], const0_rtx)));
4970       emit_insn (gen_rtx_COND_EXEC (VOIDmode,
4971                                     gen_rtx_GT (SImode,
4972                                                 gen_rtx_REG (CCmode, CC_REGNUM),
4973                                                 const0_rtx),
4974                                     gen_rtx_SET (operands[0],
4975                                                  (gen_rtx_MINUS (SImode,
4976                                                                  const0_rtx,
4977                                                                  operands[1])))));
4978      }
4979    else
4980      {
4981       /* Emit the pattern:
4982          eor%?\\t%0, %1, %1, asr #31\;rsb%?\\t%0, %0, %1, asr #31
4983       */
4984       emit_insn (gen_rtx_SET (operands[0],
4985                               gen_rtx_XOR (SImode,
4986                                            gen_rtx_ASHIFTRT (SImode,
4987                                                              operands[1],
4988                                                              GEN_INT (31)),
4989                                            operands[1])));
4990       emit_insn (gen_rtx_SET (operands[0],
4991                               gen_rtx_MINUS (SImode,
4992                                              gen_rtx_ASHIFTRT (SImode,
4993                                                                operands[1],
4994                                                                GEN_INT (31)),
4995                                              operands[0])));
4996      }
4997    DONE;
4998   }
4999   [(set_attr "conds" "clob,*")
5000    (set_attr "shift" "1")
5001    (set_attr "predicable" "no, yes")
5002    (set_attr "length" "8")
5003    (set_attr "type" "multiple")]
5006 (define_expand "abssf2"
5007   [(set (match_operand:SF         0 "s_register_operand" "")
5008         (abs:SF (match_operand:SF 1 "s_register_operand" "")))]
5009   "TARGET_32BIT && TARGET_HARD_FLOAT"
5010   "")
5012 (define_expand "absdf2"
5013   [(set (match_operand:DF         0 "s_register_operand" "")
5014         (abs:DF (match_operand:DF 1 "s_register_operand" "")))]
5015   "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
5016   "")
5018 (define_expand "sqrtsf2"
5019   [(set (match_operand:SF 0 "s_register_operand" "")
5020         (sqrt:SF (match_operand:SF 1 "s_register_operand" "")))]
5021   "TARGET_32BIT && TARGET_HARD_FLOAT"
5022   "")
5024 (define_expand "sqrtdf2"
5025   [(set (match_operand:DF 0 "s_register_operand" "")
5026         (sqrt:DF (match_operand:DF 1 "s_register_operand" "")))]
5027   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
5028   "")
5030 (define_insn_and_split "one_cmpldi2"
5031   [(set (match_operand:DI 0 "s_register_operand"         "=w,&r,&r,?w")
5032         (not:DI (match_operand:DI 1 "s_register_operand" " w, 0, r, w")))]
5033   "TARGET_32BIT"
5034   "@
5035    vmvn\t%P0, %P1
5036    #
5037    #
5038    vmvn\t%P0, %P1"
5039   "TARGET_32BIT && reload_completed
5040    && arm_general_register_operand (operands[0], DImode)"
5041   [(set (match_dup 0) (not:SI (match_dup 1)))
5042    (set (match_dup 2) (not:SI (match_dup 3)))]
5043   "
5044   {
5045     operands[2] = gen_highpart (SImode, operands[0]);
5046     operands[0] = gen_lowpart (SImode, operands[0]);
5047     operands[3] = gen_highpart (SImode, operands[1]);
5048     operands[1] = gen_lowpart (SImode, operands[1]);
5049   }"
5050   [(set_attr "length" "*,8,8,*")
5051    (set_attr "predicable" "no,yes,yes,no")
5052    (set_attr "type" "neon_move,multiple,multiple,neon_move")
5053    (set_attr "arch" "neon_for_64bits,*,*,avoid_neon_for_64bits")]
5056 (define_expand "one_cmplsi2"
5057   [(set (match_operand:SI         0 "s_register_operand" "")
5058         (not:SI (match_operand:SI 1 "s_register_operand" "")))]
5059   "TARGET_EITHER"
5060   ""
5063 (define_insn "*arm_one_cmplsi2"
5064   [(set (match_operand:SI         0 "s_register_operand" "=l,r")
5065         (not:SI (match_operand:SI 1 "s_register_operand"  "l,r")))]
5066   "TARGET_32BIT"
5067   "mvn%?\\t%0, %1"
5068   [(set_attr "predicable" "yes")
5069    (set_attr "predicable_short_it" "yes,no")
5070    (set_attr "arch" "t2,*")
5071    (set_attr "length" "4")
5072    (set_attr "type" "mvn_reg")]
5075 (define_insn "*notsi_compare0"
5076   [(set (reg:CC_NOOV CC_REGNUM)
5077         (compare:CC_NOOV (not:SI (match_operand:SI 1 "s_register_operand" "r"))
5078                          (const_int 0)))
5079    (set (match_operand:SI 0 "s_register_operand" "=r")
5080         (not:SI (match_dup 1)))]
5081   "TARGET_32BIT"
5082   "mvns%?\\t%0, %1"
5083   [(set_attr "conds" "set")
5084    (set_attr "type" "mvn_reg")]
5087 (define_insn "*notsi_compare0_scratch"
5088   [(set (reg:CC_NOOV CC_REGNUM)
5089         (compare:CC_NOOV (not:SI (match_operand:SI 1 "s_register_operand" "r"))
5090                          (const_int 0)))
5091    (clobber (match_scratch:SI 0 "=r"))]
5092   "TARGET_32BIT"
5093   "mvns%?\\t%0, %1"
5094   [(set_attr "conds" "set")
5095    (set_attr "type" "mvn_reg")]
5098 ;; Fixed <--> Floating conversion insns
5100 (define_expand "floatsihf2"
5101   [(set (match_operand:HF           0 "general_operand" "")
5102         (float:HF (match_operand:SI 1 "general_operand" "")))]
5103   "TARGET_EITHER"
5104   "
5105   {
5106     rtx op1 = gen_reg_rtx (SFmode);
5107     expand_float (op1, operands[1], 0);
5108     op1 = convert_to_mode (HFmode, op1, 0);
5109     emit_move_insn (operands[0], op1);
5110     DONE;
5111   }"
5114 (define_expand "floatdihf2"
5115   [(set (match_operand:HF           0 "general_operand" "")
5116         (float:HF (match_operand:DI 1 "general_operand" "")))]
5117   "TARGET_EITHER"
5118   "
5119   {
5120     rtx op1 = gen_reg_rtx (SFmode);
5121     expand_float (op1, operands[1], 0);
5122     op1 = convert_to_mode (HFmode, op1, 0);
5123     emit_move_insn (operands[0], op1);
5124     DONE;
5125   }"
5128 (define_expand "floatsisf2"
5129   [(set (match_operand:SF           0 "s_register_operand" "")
5130         (float:SF (match_operand:SI 1 "s_register_operand" "")))]
5131   "TARGET_32BIT && TARGET_HARD_FLOAT"
5132   "
5135 (define_expand "floatsidf2"
5136   [(set (match_operand:DF           0 "s_register_operand" "")
5137         (float:DF (match_operand:SI 1 "s_register_operand" "")))]
5138   "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
5139   "
5142 (define_expand "fix_trunchfsi2"
5143   [(set (match_operand:SI         0 "general_operand" "")
5144         (fix:SI (fix:HF (match_operand:HF 1 "general_operand"  ""))))]
5145   "TARGET_EITHER"
5146   "
5147   {
5148     rtx op1 = convert_to_mode (SFmode, operands[1], 0);
5149     expand_fix (operands[0], op1, 0);
5150     DONE;
5151   }"
5154 (define_expand "fix_trunchfdi2"
5155   [(set (match_operand:DI         0 "general_operand" "")
5156         (fix:DI (fix:HF (match_operand:HF 1 "general_operand"  ""))))]
5157   "TARGET_EITHER"
5158   "
5159   {
5160     rtx op1 = convert_to_mode (SFmode, operands[1], 0);
5161     expand_fix (operands[0], op1, 0);
5162     DONE;
5163   }"
5166 (define_expand "fix_truncsfsi2"
5167   [(set (match_operand:SI         0 "s_register_operand" "")
5168         (fix:SI (fix:SF (match_operand:SF 1 "s_register_operand"  ""))))]
5169   "TARGET_32BIT && TARGET_HARD_FLOAT"
5170   "
5173 (define_expand "fix_truncdfsi2"
5174   [(set (match_operand:SI         0 "s_register_operand" "")
5175         (fix:SI (fix:DF (match_operand:DF 1 "s_register_operand"  ""))))]
5176   "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
5177   "
5180 ;; Truncation insns
5182 (define_expand "truncdfsf2"
5183   [(set (match_operand:SF  0 "s_register_operand" "")
5184         (float_truncate:SF
5185          (match_operand:DF 1 "s_register_operand" "")))]
5186   "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
5187   ""
5190 ;; DFmode to HFmode conversions on targets without a single-step hardware
5191 ;; instruction for it would have to go through SFmode.  This is dangerous
5192 ;; as it introduces double rounding.
5194 ;; Disable this pattern unless we are in an unsafe math mode, or we have
5195 ;; a single-step instruction.
5197 (define_expand "truncdfhf2"
5198   [(set (match_operand:HF  0 "s_register_operand" "")
5199         (float_truncate:HF
5200          (match_operand:DF 1 "s_register_operand" "")))]
5201   "(TARGET_EITHER && flag_unsafe_math_optimizations)
5202    || (TARGET_32BIT && TARGET_FP16_TO_DOUBLE)"
5204   /* We don't have a direct instruction for this, so we must be in
5205      an unsafe math mode, and going via SFmode.  */
5207   if (!(TARGET_32BIT && TARGET_FP16_TO_DOUBLE))
5208     {
5209       rtx op1;
5210       op1 = convert_to_mode (SFmode, operands[1], 0);
5211       op1 = convert_to_mode (HFmode, op1, 0);
5212       emit_move_insn (operands[0], op1);
5213       DONE;
5214     }
5215   /* Otherwise, we will pick this up as a single instruction with
5216      no intermediary rounding.  */
5220 ;; Zero and sign extension instructions.
5222 (define_insn "zero_extend<mode>di2"
5223   [(set (match_operand:DI 0 "s_register_operand" "=w,r,?r,w")
5224         (zero_extend:DI (match_operand:QHSI 1 "<qhs_zextenddi_op>"
5225                                             "<qhs_zextenddi_cstr>")))]
5226   "TARGET_32BIT <qhs_zextenddi_cond>"
5227   "#"
5228   [(set_attr "length" "8,4,8,8")
5229    (set_attr "arch" "neon_for_64bits,*,*,avoid_neon_for_64bits")
5230    (set_attr "ce_count" "2")
5231    (set_attr "predicable" "yes")
5232    (set_attr "type" "multiple,mov_reg,multiple,multiple")]
5235 (define_insn "extend<mode>di2"
5236   [(set (match_operand:DI 0 "s_register_operand" "=w,r,?r,?r,w")
5237         (sign_extend:DI (match_operand:QHSI 1 "<qhs_extenddi_op>"
5238                                             "<qhs_extenddi_cstr>")))]
5239   "TARGET_32BIT <qhs_sextenddi_cond>"
5240   "#"
5241   [(set_attr "length" "8,4,8,8,8")
5242    (set_attr "ce_count" "2")
5243    (set_attr "shift" "1")
5244    (set_attr "predicable" "yes")
5245    (set_attr "arch" "neon_for_64bits,*,a,t,avoid_neon_for_64bits")
5246    (set_attr "type" "multiple,mov_reg,multiple,multiple,multiple")]
5249 ;; Splits for all extensions to DImode
5250 (define_split
5251   [(set (match_operand:DI 0 "s_register_operand" "")
5252         (zero_extend:DI (match_operand 1 "nonimmediate_operand" "")))]
5253   "TARGET_32BIT && reload_completed && !IS_VFP_REGNUM (REGNO (operands[0]))"
5254   [(set (match_dup 0) (match_dup 1))]
5256   rtx lo_part = gen_lowpart (SImode, operands[0]);
5257   machine_mode src_mode = GET_MODE (operands[1]);
5259   if (REG_P (operands[0])
5260       && !reg_overlap_mentioned_p (operands[0], operands[1]))
5261     emit_clobber (operands[0]);
5262   if (!REG_P (lo_part) || src_mode != SImode
5263       || !rtx_equal_p (lo_part, operands[1]))
5264     {
5265       if (src_mode == SImode)
5266         emit_move_insn (lo_part, operands[1]);
5267       else
5268         emit_insn (gen_rtx_SET (lo_part,
5269                                 gen_rtx_ZERO_EXTEND (SImode, operands[1])));
5270       operands[1] = lo_part;
5271     }
5272   operands[0] = gen_highpart (SImode, operands[0]);
5273   operands[1] = const0_rtx;
5276 (define_split
5277   [(set (match_operand:DI 0 "s_register_operand" "")
5278         (sign_extend:DI (match_operand 1 "nonimmediate_operand" "")))]
5279   "TARGET_32BIT && reload_completed && !IS_VFP_REGNUM (REGNO (operands[0]))"
5280   [(set (match_dup 0) (ashiftrt:SI (match_dup 1) (const_int 31)))]
5282   rtx lo_part = gen_lowpart (SImode, operands[0]);
5283   machine_mode src_mode = GET_MODE (operands[1]);
5285   if (REG_P (operands[0])
5286       && !reg_overlap_mentioned_p (operands[0], operands[1]))
5287     emit_clobber (operands[0]);
5289   if (!REG_P (lo_part) || src_mode != SImode
5290       || !rtx_equal_p (lo_part, operands[1]))
5291     {
5292       if (src_mode == SImode)
5293         emit_move_insn (lo_part, operands[1]);
5294       else
5295         emit_insn (gen_rtx_SET (lo_part,
5296                                 gen_rtx_SIGN_EXTEND (SImode, operands[1])));
5297       operands[1] = lo_part;
5298     }
5299   operands[0] = gen_highpart (SImode, operands[0]);
5302 (define_expand "zero_extendhisi2"
5303   [(set (match_operand:SI 0 "s_register_operand" "")
5304         (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
5305   "TARGET_EITHER"
5307   if (TARGET_ARM && !arm_arch4 && MEM_P (operands[1]))
5308     {
5309       emit_insn (gen_movhi_bytes (operands[0], operands[1]));
5310       DONE;
5311     }
5312   if (!arm_arch6 && !MEM_P (operands[1]))
5313     {
5314       rtx t = gen_lowpart (SImode, operands[1]);
5315       rtx tmp = gen_reg_rtx (SImode);
5316       emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (16)));
5317       emit_insn (gen_lshrsi3 (operands[0], tmp, GEN_INT (16)));
5318       DONE;
5319     }
5322 (define_split
5323   [(set (match_operand:SI 0 "s_register_operand" "")
5324         (zero_extend:SI (match_operand:HI 1 "s_register_operand" "")))]
5325   "!TARGET_THUMB2 && !arm_arch6"
5326   [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
5327    (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 16)))]
5329   operands[2] = gen_lowpart (SImode, operands[1]);
5332 (define_insn "*arm_zero_extendhisi2"
5333   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5334         (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
5335   "TARGET_ARM && arm_arch4 && !arm_arch6"
5336   "@
5337    #
5338    ldrh%?\\t%0, %1"
5339   [(set_attr "type" "alu_shift_reg,load_byte")
5340    (set_attr "predicable" "yes")]
5343 (define_insn "*arm_zero_extendhisi2_v6"
5344   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5345         (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,Uh")))]
5346   "TARGET_ARM && arm_arch6"
5347   "@
5348    uxth%?\\t%0, %1
5349    ldrh%?\\t%0, %1"
5350   [(set_attr "predicable" "yes")
5351    (set_attr "type" "extend,load_byte")]
5354 (define_insn "*arm_zero_extendhisi2addsi"
5355   [(set (match_operand:SI 0 "s_register_operand" "=r")
5356         (plus:SI (zero_extend:SI (match_operand:HI 1 "s_register_operand" "r"))
5357                  (match_operand:SI 2 "s_register_operand" "r")))]
5358   "TARGET_INT_SIMD"
5359   "uxtah%?\\t%0, %2, %1"
5360   [(set_attr "type" "alu_shift_reg")
5361    (set_attr "predicable" "yes")
5362    (set_attr "predicable_short_it" "no")]
5365 (define_expand "zero_extendqisi2"
5366   [(set (match_operand:SI 0 "s_register_operand" "")
5367         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))]
5368   "TARGET_EITHER"
5370   if (TARGET_ARM && !arm_arch6 && !MEM_P (operands[1]))
5371     {
5372       emit_insn (gen_andsi3 (operands[0],
5373                              gen_lowpart (SImode, operands[1]),
5374                                           GEN_INT (255)));
5375       DONE;
5376     }
5377   if (!arm_arch6 && !MEM_P (operands[1]))
5378     {
5379       rtx t = gen_lowpart (SImode, operands[1]);
5380       rtx tmp = gen_reg_rtx (SImode);
5381       emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (24)));
5382       emit_insn (gen_lshrsi3 (operands[0], tmp, GEN_INT (24)));
5383       DONE;
5384     }
5387 (define_split
5388   [(set (match_operand:SI 0 "s_register_operand" "")
5389         (zero_extend:SI (match_operand:QI 1 "s_register_operand" "")))]
5390   "!arm_arch6"
5391   [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 24)))
5392    (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 24)))]
5394   operands[2] = simplify_gen_subreg (SImode, operands[1], QImode, 0);
5395   if (TARGET_ARM)
5396     {
5397       emit_insn (gen_andsi3 (operands[0], operands[2], GEN_INT (255)));
5398       DONE;
5399     }
5402 (define_insn "*arm_zero_extendqisi2"
5403   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5404         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
5405   "TARGET_ARM && !arm_arch6"
5406   "@
5407    #
5408    ldrb%?\\t%0, %1\\t%@ zero_extendqisi2"
5409   [(set_attr "length" "8,4")
5410    (set_attr "type" "alu_shift_reg,load_byte")
5411    (set_attr "predicable" "yes")]
5414 (define_insn "*arm_zero_extendqisi2_v6"
5415   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5416         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,Uh")))]
5417   "TARGET_ARM && arm_arch6"
5418   "@
5419    uxtb%?\\t%0, %1
5420    ldrb%?\\t%0, %1\\t%@ zero_extendqisi2"
5421   [(set_attr "type" "extend,load_byte")
5422    (set_attr "predicable" "yes")]
5425 (define_insn "*arm_zero_extendqisi2addsi"
5426   [(set (match_operand:SI 0 "s_register_operand" "=r")
5427         (plus:SI (zero_extend:SI (match_operand:QI 1 "s_register_operand" "r"))
5428                  (match_operand:SI 2 "s_register_operand" "r")))]
5429   "TARGET_INT_SIMD"
5430   "uxtab%?\\t%0, %2, %1"
5431   [(set_attr "predicable" "yes")
5432    (set_attr "predicable_short_it" "no")
5433    (set_attr "type" "alu_shift_reg")]
5436 (define_split
5437   [(set (match_operand:SI 0 "s_register_operand" "")
5438         (zero_extend:SI (subreg:QI (match_operand:SI 1 "" "") 0)))
5439    (clobber (match_operand:SI 2 "s_register_operand" ""))]
5440   "TARGET_32BIT && (!MEM_P (operands[1])) && ! BYTES_BIG_ENDIAN"
5441   [(set (match_dup 2) (match_dup 1))
5442    (set (match_dup 0) (and:SI (match_dup 2) (const_int 255)))]
5443   ""
5446 (define_split
5447   [(set (match_operand:SI 0 "s_register_operand" "")
5448         (zero_extend:SI (subreg:QI (match_operand:SI 1 "" "") 3)))
5449    (clobber (match_operand:SI 2 "s_register_operand" ""))]
5450   "TARGET_32BIT && (!MEM_P (operands[1])) && BYTES_BIG_ENDIAN"
5451   [(set (match_dup 2) (match_dup 1))
5452    (set (match_dup 0) (and:SI (match_dup 2) (const_int 255)))]
5453   ""
5457 (define_split
5458   [(set (match_operand:SI 0 "s_register_operand" "")
5459         (IOR_XOR:SI (and:SI (ashift:SI
5460                              (match_operand:SI 1 "s_register_operand" "")
5461                              (match_operand:SI 2 "const_int_operand" ""))
5462                             (match_operand:SI 3 "const_int_operand" ""))
5463                     (zero_extend:SI
5464                      (match_operator 5 "subreg_lowpart_operator"
5465                       [(match_operand:SI 4 "s_register_operand" "")]))))]
5466   "TARGET_32BIT
5467    && (UINTVAL (operands[3])
5468        == (GET_MODE_MASK (GET_MODE (operands[5]))
5469            & (GET_MODE_MASK (GET_MODE (operands[5]))
5470               << (INTVAL (operands[2])))))"
5471   [(set (match_dup 0) (IOR_XOR:SI (ashift:SI (match_dup 1) (match_dup 2))
5472                                   (match_dup 4)))
5473    (set (match_dup 0) (zero_extend:SI (match_dup 5)))]
5474   "operands[5] = gen_lowpart (GET_MODE (operands[5]), operands[0]);"
5477 (define_insn "*compareqi_eq0"
5478   [(set (reg:CC_Z CC_REGNUM)
5479         (compare:CC_Z (match_operand:QI 0 "s_register_operand" "r")
5480                          (const_int 0)))]
5481   "TARGET_32BIT"
5482   "tst%?\\t%0, #255"
5483   [(set_attr "conds" "set")
5484    (set_attr "predicable" "yes")
5485    (set_attr "predicable_short_it" "no")
5486    (set_attr "type" "logic_imm")]
5489 (define_expand "extendhisi2"
5490   [(set (match_operand:SI 0 "s_register_operand" "")
5491         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
5492   "TARGET_EITHER"
5494   if (TARGET_THUMB1)
5495     {
5496       emit_insn (gen_thumb1_extendhisi2 (operands[0], operands[1]));
5497       DONE;
5498     }
5499   if (MEM_P (operands[1]) && TARGET_ARM && !arm_arch4)
5500     {
5501       emit_insn (gen_extendhisi2_mem (operands[0], operands[1]));
5502       DONE;
5503     }
5505   if (!arm_arch6 && !MEM_P (operands[1]))
5506     {
5507       rtx t = gen_lowpart (SImode, operands[1]);
5508       rtx tmp = gen_reg_rtx (SImode);
5509       emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (16)));
5510       emit_insn (gen_ashrsi3 (operands[0], tmp, GEN_INT (16)));
5511       DONE;
5512     }
5515 (define_split
5516   [(parallel
5517     [(set (match_operand:SI 0 "register_operand" "")
5518           (sign_extend:SI (match_operand:HI 1 "register_operand" "")))
5519      (clobber (match_scratch:SI 2 ""))])]
5520   "!arm_arch6"
5521   [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
5522    (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
5524   operands[2] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
5527 ;; This pattern will only be used when ldsh is not available
5528 (define_expand "extendhisi2_mem"
5529   [(set (match_dup 2) (zero_extend:SI (match_operand:HI 1 "" "")))
5530    (set (match_dup 3)
5531         (zero_extend:SI (match_dup 7)))
5532    (set (match_dup 6) (ashift:SI (match_dup 4) (const_int 24)))
5533    (set (match_operand:SI 0 "" "")
5534         (ior:SI (ashiftrt:SI (match_dup 6) (const_int 16)) (match_dup 5)))]
5535   "TARGET_ARM"
5536   "
5537   {
5538     rtx mem1, mem2;
5539     rtx addr = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
5541     mem1 = change_address (operands[1], QImode, addr);
5542     mem2 = change_address (operands[1], QImode,
5543                            plus_constant (Pmode, addr, 1));
5544     operands[0] = gen_lowpart (SImode, operands[0]);
5545     operands[1] = mem1;
5546     operands[2] = gen_reg_rtx (SImode);
5547     operands[3] = gen_reg_rtx (SImode);
5548     operands[6] = gen_reg_rtx (SImode);
5549     operands[7] = mem2;
5551     if (BYTES_BIG_ENDIAN)
5552       {
5553         operands[4] = operands[2];
5554         operands[5] = operands[3];
5555       }
5556     else
5557       {
5558         operands[4] = operands[3];
5559         operands[5] = operands[2];
5560       }
5561   }"
5564 (define_split
5565   [(set (match_operand:SI 0 "register_operand" "")
5566         (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
5567   "!arm_arch6"
5568   [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
5569    (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
5571   operands[2] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
5574 (define_insn "*arm_extendhisi2"
5575   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5576         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,Uh")))]
5577   "TARGET_ARM && arm_arch4 && !arm_arch6"
5578   "@
5579    #
5580    ldrsh%?\\t%0, %1"
5581   [(set_attr "length" "8,4")
5582    (set_attr "type" "alu_shift_reg,load_byte")
5583    (set_attr "predicable" "yes")]
5586 ;; ??? Check Thumb-2 pool range
5587 (define_insn "*arm_extendhisi2_v6"
5588   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5589         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,Uh")))]
5590   "TARGET_32BIT && arm_arch6"
5591   "@
5592    sxth%?\\t%0, %1
5593    ldrsh%?\\t%0, %1"
5594   [(set_attr "type" "extend,load_byte")
5595    (set_attr "predicable" "yes")
5596    (set_attr "predicable_short_it" "no")]
5599 (define_insn "*arm_extendhisi2addsi"
5600   [(set (match_operand:SI 0 "s_register_operand" "=r")
5601         (plus:SI (sign_extend:SI (match_operand:HI 1 "s_register_operand" "r"))
5602                  (match_operand:SI 2 "s_register_operand" "r")))]
5603   "TARGET_INT_SIMD"
5604   "sxtah%?\\t%0, %2, %1"
5605   [(set_attr "type" "alu_shift_reg")]
5608 (define_expand "extendqihi2"
5609   [(set (match_dup 2)
5610         (ashift:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "")
5611                    (const_int 24)))
5612    (set (match_operand:HI 0 "s_register_operand" "")
5613         (ashiftrt:SI (match_dup 2)
5614                      (const_int 24)))]
5615   "TARGET_ARM"
5616   "
5617   {
5618     if (arm_arch4 && MEM_P (operands[1]))
5619       {
5620         emit_insn (gen_rtx_SET (operands[0],
5621                                 gen_rtx_SIGN_EXTEND (HImode, operands[1])));
5622         DONE;
5623       }
5624     if (!s_register_operand (operands[1], QImode))
5625       operands[1] = copy_to_mode_reg (QImode, operands[1]);
5626     operands[0] = gen_lowpart (SImode, operands[0]);
5627     operands[1] = gen_lowpart (SImode, operands[1]);
5628     operands[2] = gen_reg_rtx (SImode);
5629   }"
5632 (define_insn "*arm_extendqihi_insn"
5633   [(set (match_operand:HI 0 "s_register_operand" "=r")
5634         (sign_extend:HI (match_operand:QI 1 "arm_extendqisi_mem_op" "Uq")))]
5635   "TARGET_ARM && arm_arch4"
5636   "ldrsb%?\\t%0, %1"
5637   [(set_attr "type" "load_byte")
5638    (set_attr "predicable" "yes")]
5641 (define_expand "extendqisi2"
5642   [(set (match_operand:SI 0 "s_register_operand" "")
5643         (sign_extend:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "")))]
5644   "TARGET_EITHER"
5646   if (!arm_arch4 && MEM_P (operands[1]))
5647     operands[1] = copy_to_mode_reg (QImode, operands[1]);
5649   if (!arm_arch6 && !MEM_P (operands[1]))
5650     {
5651       rtx t = gen_lowpart (SImode, operands[1]);
5652       rtx tmp = gen_reg_rtx (SImode);
5653       emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (24)));
5654       emit_insn (gen_ashrsi3 (operands[0], tmp, GEN_INT (24)));
5655       DONE;
5656     }
5659 (define_split
5660   [(set (match_operand:SI 0 "register_operand" "")
5661         (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
5662   "!arm_arch6"
5663   [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 24)))
5664    (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 24)))]
5666   operands[2] = simplify_gen_subreg (SImode, operands[1], QImode, 0);
5669 (define_insn "*arm_extendqisi"
5670   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5671         (sign_extend:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "r,Uq")))]
5672   "TARGET_ARM && arm_arch4 && !arm_arch6"
5673   "@
5674    #
5675    ldrsb%?\\t%0, %1"
5676   [(set_attr "length" "8,4")
5677    (set_attr "type" "alu_shift_reg,load_byte")
5678    (set_attr "predicable" "yes")]
5681 (define_insn "*arm_extendqisi_v6"
5682   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5683         (sign_extend:SI
5684          (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "r,Uq")))]
5685   "TARGET_ARM && arm_arch6"
5686   "@
5687    sxtb%?\\t%0, %1
5688    ldrsb%?\\t%0, %1"
5689   [(set_attr "type" "extend,load_byte")
5690    (set_attr "predicable" "yes")]
5693 (define_insn "*arm_extendqisi2addsi"
5694   [(set (match_operand:SI 0 "s_register_operand" "=r")
5695         (plus:SI (sign_extend:SI (match_operand:QI 1 "s_register_operand" "r"))
5696                  (match_operand:SI 2 "s_register_operand" "r")))]
5697   "TARGET_INT_SIMD"
5698   "sxtab%?\\t%0, %2, %1"
5699   [(set_attr "type" "alu_shift_reg")
5700    (set_attr "predicable" "yes")
5701    (set_attr "predicable_short_it" "no")]
5704 (define_expand "extendsfdf2"
5705   [(set (match_operand:DF                  0 "s_register_operand" "")
5706         (float_extend:DF (match_operand:SF 1 "s_register_operand"  "")))]
5707   "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
5708   ""
5711 ;; HFmode -> DFmode conversions where we don't have an instruction for it
5712 ;; must go through SFmode.
5714 ;; This is always safe for an extend.
5716 (define_expand "extendhfdf2"
5717   [(set (match_operand:DF                  0 "s_register_operand" "")
5718         (float_extend:DF (match_operand:HF 1 "s_register_operand" "")))]
5719   "TARGET_EITHER"
5721   /* We don't have a direct instruction for this, so go via SFmode.  */
5722   if (!(TARGET_32BIT && TARGET_FP16_TO_DOUBLE))
5723     {
5724       rtx op1;
5725       op1 = convert_to_mode (SFmode, operands[1], 0);
5726       op1 = convert_to_mode (DFmode, op1, 0);
5727       emit_insn (gen_movdf (operands[0], op1));
5728       DONE;
5729     }
5730   /* Otherwise, we're done producing RTL and will pick up the correct
5731      pattern to do this with one rounding-step in a single instruction.  */
5735 ;; Move insns (including loads and stores)
5737 ;; XXX Just some ideas about movti.
5738 ;; I don't think these are a good idea on the arm, there just aren't enough
5739 ;; registers
5740 ;;(define_expand "loadti"
5741 ;;  [(set (match_operand:TI 0 "s_register_operand" "")
5742 ;;      (mem:TI (match_operand:SI 1 "address_operand" "")))]
5743 ;;  "" "")
5745 ;;(define_expand "storeti"
5746 ;;  [(set (mem:TI (match_operand:TI 0 "address_operand" ""))
5747 ;;      (match_operand:TI 1 "s_register_operand" ""))]
5748 ;;  "" "")
5750 ;;(define_expand "movti"
5751 ;;  [(set (match_operand:TI 0 "general_operand" "")
5752 ;;      (match_operand:TI 1 "general_operand" ""))]
5753 ;;  ""
5754 ;;  "
5756 ;;  rtx insn;
5758 ;;  if (MEM_P (operands[0]) && MEM_P (operands[1]))
5759 ;;    operands[1] = copy_to_reg (operands[1]);
5760 ;;  if (MEM_P (operands[0]))
5761 ;;    insn = gen_storeti (XEXP (operands[0], 0), operands[1]);
5762 ;;  else if (MEM_P (operands[1]))
5763 ;;    insn = gen_loadti (operands[0], XEXP (operands[1], 0));
5764 ;;  else
5765 ;;    FAIL;
5767 ;;  emit_insn (insn);
5768 ;;  DONE;
5769 ;;}")
5771 ;; Recognize garbage generated above.
5773 ;;(define_insn ""
5774 ;;  [(set (match_operand:TI 0 "general_operand" "=r,r,r,<,>,m")
5775 ;;      (match_operand:TI 1 "general_operand" "<,>,m,r,r,r"))]
5776 ;;  ""
5777 ;;  "*
5778 ;;  {
5779 ;;    register mem = (which_alternative < 3);
5780 ;;    register const char *template;
5782 ;;    operands[mem] = XEXP (operands[mem], 0);
5783 ;;    switch (which_alternative)
5784 ;;      {
5785 ;;      case 0: template = \"ldmdb\\t%1!, %M0\"; break;
5786 ;;      case 1: template = \"ldmia\\t%1!, %M0\"; break;
5787 ;;      case 2: template = \"ldmia\\t%1, %M0\"; break;
5788 ;;      case 3: template = \"stmdb\\t%0!, %M1\"; break;
5789 ;;      case 4: template = \"stmia\\t%0!, %M1\"; break;
5790 ;;      case 5: template = \"stmia\\t%0, %M1\"; break;
5791 ;;      }
5792 ;;    output_asm_insn (template, operands);
5793 ;;    return \"\";
5794 ;;  }")
5796 (define_expand "movdi"
5797   [(set (match_operand:DI 0 "general_operand" "")
5798         (match_operand:DI 1 "general_operand" ""))]
5799   "TARGET_EITHER"
5800   "
5801   if (can_create_pseudo_p ())
5802     {
5803       if (!REG_P (operands[0]))
5804         operands[1] = force_reg (DImode, operands[1]);
5805     }
5806   if (REG_P (operands[0]) && REGNO (operands[0]) <= LAST_ARM_REGNUM
5807       && !HARD_REGNO_MODE_OK (REGNO (operands[0]), DImode))
5808     {
5809       /* Avoid LDRD's into an odd-numbered register pair in ARM state
5810          when expanding function calls.  */
5811       gcc_assert (can_create_pseudo_p ());
5812       if (MEM_P (operands[1]) && MEM_VOLATILE_P (operands[1]))
5813         {
5814           /* Perform load into legal reg pair first, then move.  */
5815           rtx reg = gen_reg_rtx (DImode);
5816           emit_insn (gen_movdi (reg, operands[1]));
5817           operands[1] = reg;
5818         }
5819       emit_move_insn (gen_lowpart (SImode, operands[0]),
5820                       gen_lowpart (SImode, operands[1]));
5821       emit_move_insn (gen_highpart (SImode, operands[0]),
5822                       gen_highpart (SImode, operands[1]));
5823       DONE;
5824     }
5825   else if (REG_P (operands[1]) && REGNO (operands[1]) <= LAST_ARM_REGNUM
5826            && !HARD_REGNO_MODE_OK (REGNO (operands[1]), DImode))
5827     {
5828       /* Avoid STRD's from an odd-numbered register pair in ARM state
5829          when expanding function prologue.  */
5830       gcc_assert (can_create_pseudo_p ());
5831       rtx split_dest = (MEM_P (operands[0]) && MEM_VOLATILE_P (operands[0]))
5832                        ? gen_reg_rtx (DImode)
5833                        : operands[0];
5834       emit_move_insn (gen_lowpart (SImode, split_dest),
5835                       gen_lowpart (SImode, operands[1]));
5836       emit_move_insn (gen_highpart (SImode, split_dest),
5837                       gen_highpart (SImode, operands[1]));
5838       if (split_dest != operands[0])
5839         emit_insn (gen_movdi (operands[0], split_dest));
5840       DONE;
5841     }
5842   "
5845 (define_insn "*arm_movdi"
5846   [(set (match_operand:DI 0 "nonimmediate_di_operand" "=r, r, r, q, m")
5847         (match_operand:DI 1 "di_operand"              "rDa,Db,Dc,mi,q"))]
5848   "TARGET_32BIT
5849    && !(TARGET_HARD_FLOAT)
5850    && !TARGET_IWMMXT
5851    && (   register_operand (operands[0], DImode)
5852        || register_operand (operands[1], DImode))"
5853   "*
5854   switch (which_alternative)
5855     {
5856     case 0:
5857     case 1:
5858     case 2:
5859       return \"#\";
5860     default:
5861       return output_move_double (operands, true, NULL);
5862     }
5863   "
5864   [(set_attr "length" "8,12,16,8,8")
5865    (set_attr "type" "multiple,multiple,multiple,load2,store2")
5866    (set_attr "arm_pool_range" "*,*,*,1020,*")
5867    (set_attr "arm_neg_pool_range" "*,*,*,1004,*")
5868    (set_attr "thumb2_pool_range" "*,*,*,4094,*")
5869    (set_attr "thumb2_neg_pool_range" "*,*,*,0,*")]
5872 (define_split
5873   [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
5874         (match_operand:ANY64 1 "immediate_operand" ""))]
5875   "TARGET_32BIT
5876    && reload_completed
5877    && (arm_disable_literal_pool
5878        || (arm_const_double_inline_cost (operands[1])
5879            <= arm_max_const_double_inline_cost ()))"
5880   [(const_int 0)]
5881   "
5882   arm_split_constant (SET, SImode, curr_insn,
5883                       INTVAL (gen_lowpart (SImode, operands[1])),
5884                       gen_lowpart (SImode, operands[0]), NULL_RTX, 0);
5885   arm_split_constant (SET, SImode, curr_insn,
5886                       INTVAL (gen_highpart_mode (SImode,
5887                                                  GET_MODE (operands[0]),
5888                                                  operands[1])),
5889                       gen_highpart (SImode, operands[0]), NULL_RTX, 0);
5890   DONE;
5891   "
5894 ; If optimizing for size, or if we have load delay slots, then 
5895 ; we want to split the constant into two separate operations. 
5896 ; In both cases this may split a trivial part into a single data op
5897 ; leaving a single complex constant to load.  We can also get longer
5898 ; offsets in a LDR which means we get better chances of sharing the pool
5899 ; entries.  Finally, we can normally do a better job of scheduling
5900 ; LDR instructions than we can with LDM.
5901 ; This pattern will only match if the one above did not.
5902 (define_split
5903   [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
5904         (match_operand:ANY64 1 "const_double_operand" ""))]
5905   "TARGET_ARM && reload_completed
5906    && arm_const_double_by_parts (operands[1])"
5907   [(set (match_dup 0) (match_dup 1))
5908    (set (match_dup 2) (match_dup 3))]
5909   "
5910   operands[2] = gen_highpart (SImode, operands[0]);
5911   operands[3] = gen_highpart_mode (SImode, GET_MODE (operands[0]),
5912                                    operands[1]);
5913   operands[0] = gen_lowpart (SImode, operands[0]);
5914   operands[1] = gen_lowpart (SImode, operands[1]);
5915   "
5918 (define_split
5919   [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
5920         (match_operand:ANY64 1 "arm_general_register_operand" ""))]
5921   "TARGET_EITHER && reload_completed"
5922   [(set (match_dup 0) (match_dup 1))
5923    (set (match_dup 2) (match_dup 3))]
5924   "
5925   operands[2] = gen_highpart (SImode, operands[0]);
5926   operands[3] = gen_highpart (SImode, operands[1]);
5927   operands[0] = gen_lowpart (SImode, operands[0]);
5928   operands[1] = gen_lowpart (SImode, operands[1]);
5930   /* Handle a partial overlap.  */
5931   if (rtx_equal_p (operands[0], operands[3]))
5932     {
5933       rtx tmp0 = operands[0];
5934       rtx tmp1 = operands[1];
5936       operands[0] = operands[2];
5937       operands[1] = operands[3];
5938       operands[2] = tmp0;
5939       operands[3] = tmp1;
5940     }
5941   "
5944 ;; We can't actually do base+index doubleword loads if the index and
5945 ;; destination overlap.  Split here so that we at least have chance to
5946 ;; schedule.
5947 (define_split
5948   [(set (match_operand:DI 0 "s_register_operand" "")
5949         (mem:DI (plus:SI (match_operand:SI 1 "s_register_operand" "")
5950                          (match_operand:SI 2 "s_register_operand" ""))))]
5951   "TARGET_LDRD
5952   && reg_overlap_mentioned_p (operands[0], operands[1])
5953   && reg_overlap_mentioned_p (operands[0], operands[2])"
5954   [(set (match_dup 4)
5955         (plus:SI (match_dup 1)
5956                  (match_dup 2)))
5957    (set (match_dup 0)
5958         (mem:DI (match_dup 4)))]
5959   "
5960   operands[4] = gen_rtx_REG (SImode, REGNO(operands[0]));
5961   "
5964 (define_expand "movsi"
5965   [(set (match_operand:SI 0 "general_operand" "")
5966         (match_operand:SI 1 "general_operand" ""))]
5967   "TARGET_EITHER"
5968   "
5969   {
5970   rtx base, offset, tmp;
5972   if (TARGET_HAVE_MOVT)
5973     {
5974       /* Everything except mem = const or mem = mem can be done easily.  */
5975       if (MEM_P (operands[0]))
5976         operands[1] = force_reg (SImode, operands[1]);
5977       if (arm_general_register_operand (operands[0], SImode)
5978           && CONST_INT_P (operands[1])
5979           && !(const_ok_for_arm (INTVAL (operands[1]))
5980                || const_ok_for_arm (~INTVAL (operands[1]))))
5981         {
5982            if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[1]), SET))
5983              {
5984                 emit_insn (gen_rtx_SET (operands[0], operands[1]));
5985                 DONE;
5986              }
5987           else
5988              {
5989                 arm_split_constant (SET, SImode, NULL_RTX,
5990                                     INTVAL (operands[1]), operands[0], NULL_RTX,
5991                                     optimize && can_create_pseudo_p ());
5992                 DONE;
5993              }
5994         }
5995     }
5996   else /* Target doesn't have MOVT...  */
5997     {
5998       if (can_create_pseudo_p ())
5999         {
6000           if (!REG_P (operands[0]))
6001             operands[1] = force_reg (SImode, operands[1]);
6002         }
6003     }
6005   if (ARM_OFFSETS_MUST_BE_WITHIN_SECTIONS_P)
6006     {
6007       split_const (operands[1], &base, &offset);
6008       if (GET_CODE (base) == SYMBOL_REF
6009           && !offset_within_block_p (base, INTVAL (offset)))
6010         {
6011           tmp = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];
6012           emit_move_insn (tmp, base);
6013           emit_insn (gen_addsi3 (operands[0], tmp, offset));
6014           DONE;
6015         }
6016     }
6018   /* Recognize the case where operand[1] is a reference to thread-local
6019      data and load its address to a register.  */
6020   if (arm_tls_referenced_p (operands[1]))
6021     {
6022       rtx tmp = operands[1];
6023       rtx addend = NULL;
6025       if (GET_CODE (tmp) == CONST && GET_CODE (XEXP (tmp, 0)) == PLUS)
6026         {
6027           addend = XEXP (XEXP (tmp, 0), 1);
6028           tmp = XEXP (XEXP (tmp, 0), 0);
6029         }
6031       gcc_assert (GET_CODE (tmp) == SYMBOL_REF);
6032       gcc_assert (SYMBOL_REF_TLS_MODEL (tmp) != 0);
6034       tmp = legitimize_tls_address (tmp,
6035                                     !can_create_pseudo_p () ? operands[0] : 0);
6036       if (addend)
6037         {
6038           tmp = gen_rtx_PLUS (SImode, tmp, addend);
6039           tmp = force_operand (tmp, operands[0]);
6040         }
6041       operands[1] = tmp;
6042     }
6043   else if (flag_pic
6044            && (CONSTANT_P (operands[1])
6045                || symbol_mentioned_p (operands[1])
6046                || label_mentioned_p (operands[1])))
6047       operands[1] = legitimize_pic_address (operands[1], SImode,
6048                                             (!can_create_pseudo_p ()
6049                                              ? operands[0]
6050                                              : 0));
6051   }
6052   "
6055 ;; The ARM LO_SUM and HIGH are backwards - HIGH sets the low bits, and
6056 ;; LO_SUM adds in the high bits.  Fortunately these are opaque operations
6057 ;; so this does not matter.
6058 (define_insn "*arm_movt"
6059   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r")
6060         (lo_sum:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6061                    (match_operand:SI 2 "general_operand"      "i,i")))]
6062   "TARGET_HAVE_MOVT && arm_valid_symbolic_address_p (operands[2])"
6063   "@
6064    movt%?\t%0, #:upper16:%c2
6065    movt\t%0, #:upper16:%c2"
6066   [(set_attr "arch"  "32,v8mb")
6067    (set_attr "predicable" "yes")
6068    (set_attr "predicable_short_it" "no")
6069    (set_attr "length" "4")
6070    (set_attr "type" "alu_sreg")]
6073 (define_insn "*arm_movsi_insn"
6074   [(set (match_operand:SI 0 "nonimmediate_operand" "=rk,r,r,r,rk,m")
6075         (match_operand:SI 1 "general_operand"      "rk, I,K,j,mi,rk"))]
6076   "TARGET_ARM && !TARGET_IWMMXT && !TARGET_HARD_FLOAT
6077    && (   register_operand (operands[0], SImode)
6078        || register_operand (operands[1], SImode))"
6079   "@
6080    mov%?\\t%0, %1
6081    mov%?\\t%0, %1
6082    mvn%?\\t%0, #%B1
6083    movw%?\\t%0, %1
6084    ldr%?\\t%0, %1
6085    str%?\\t%1, %0"
6086   [(set_attr "type" "mov_reg,mov_imm,mvn_imm,mov_imm,load1,store1")
6087    (set_attr "predicable" "yes")
6088    (set_attr "arch" "*,*,*,v6t2,*,*")
6089    (set_attr "pool_range" "*,*,*,*,4096,*")
6090    (set_attr "neg_pool_range" "*,*,*,*,4084,*")]
6093 (define_split
6094   [(set (match_operand:SI 0 "arm_general_register_operand" "")
6095         (match_operand:SI 1 "const_int_operand" ""))]
6096   "TARGET_HAVE_MOVT
6097   && (!(const_ok_for_arm (INTVAL (operands[1]))
6098         || const_ok_for_arm (~INTVAL (operands[1]))))"
6099   [(clobber (const_int 0))]
6100   "
6101   arm_split_constant (SET, SImode, NULL_RTX, 
6102                       INTVAL (operands[1]), operands[0], NULL_RTX, 0);
6103   DONE;
6104   "
6107 ;; A normal way to do (symbol + offset) requires three instructions at least
6108 ;; (depends on how big the offset is) as below:
6109 ;; movw r0, #:lower16:g
6110 ;; movw r0, #:upper16:g
6111 ;; adds r0, #4
6113 ;; A better way would be:
6114 ;; movw r0, #:lower16:g+4
6115 ;; movw r0, #:upper16:g+4
6117 ;; The limitation of this way is that the length of offset should be a 16-bit
6118 ;; signed value, because current assembler only supports REL type relocation for
6119 ;; such case.  If the more powerful RELA type is supported in future, we should
6120 ;; update this pattern to go with better way.
6121 (define_split
6122   [(set (match_operand:SI 0 "arm_general_register_operand" "")
6123         (const:SI (plus:SI (match_operand:SI 1 "general_operand" "")
6124                            (match_operand:SI 2 "const_int_operand" ""))))]
6125   "TARGET_THUMB
6126    && TARGET_HAVE_MOVT
6127    && arm_disable_literal_pool
6128    && reload_completed
6129    && GET_CODE (operands[1]) == SYMBOL_REF"
6130   [(clobber (const_int 0))]
6131   "
6132     int offset = INTVAL (operands[2]);
6134     if (offset < -0x8000 || offset > 0x7fff)
6135       {
6136         arm_emit_movpair (operands[0], operands[1]);
6137         emit_insn (gen_rtx_SET (operands[0],
6138                                 gen_rtx_PLUS (SImode, operands[0], operands[2])));
6139       }
6140     else
6141       {
6142         rtx op = gen_rtx_CONST (SImode,
6143                                 gen_rtx_PLUS (SImode, operands[1], operands[2]));
6144         arm_emit_movpair (operands[0], op);
6145       }
6146   "
6149 ;; Split symbol_refs at the later stage (after cprop), instead of generating
6150 ;; movt/movw pair directly at expand.  Otherwise corresponding high_sum
6151 ;; and lo_sum would be merged back into memory load at cprop.  However,
6152 ;; if the default is to prefer movt/movw rather than a load from the constant
6153 ;; pool, the performance is better.
6154 (define_split
6155   [(set (match_operand:SI 0 "arm_general_register_operand" "")
6156        (match_operand:SI 1 "general_operand" ""))]
6157   "TARGET_USE_MOVT && GET_CODE (operands[1]) == SYMBOL_REF
6158    && !flag_pic && !target_word_relocations
6159    && !arm_tls_referenced_p (operands[1])"
6160   [(clobber (const_int 0))]
6162   arm_emit_movpair (operands[0], operands[1]);
6163   DONE;
6166 ;; When generating pic, we need to load the symbol offset into a register.
6167 ;; So that the optimizer does not confuse this with a normal symbol load
6168 ;; we use an unspec.  The offset will be loaded from a constant pool entry,
6169 ;; since that is the only type of relocation we can use.
6171 ;; Wrap calculation of the whole PIC address in a single pattern for the
6172 ;; benefit of optimizers, particularly, PRE and HOIST.  Calculation of
6173 ;; a PIC address involves two loads from memory, so we want to CSE it
6174 ;; as often as possible.
6175 ;; This pattern will be split into one of the pic_load_addr_* patterns
6176 ;; and a move after GCSE optimizations.
6178 ;; Note: Update arm.c: legitimize_pic_address() when changing this pattern.
6179 (define_expand "calculate_pic_address"
6180   [(set (match_operand:SI 0 "register_operand" "")
6181         (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "")
6182                          (unspec:SI [(match_operand:SI 2 "" "")]
6183                                     UNSPEC_PIC_SYM))))]
6184   "flag_pic"
6187 ;; Split calculate_pic_address into pic_load_addr_* and a move.
6188 (define_split
6189   [(set (match_operand:SI 0 "register_operand" "")
6190         (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "")
6191                          (unspec:SI [(match_operand:SI 2 "" "")]
6192                                     UNSPEC_PIC_SYM))))]
6193   "flag_pic"
6194   [(set (match_dup 3) (unspec:SI [(match_dup 2)] UNSPEC_PIC_SYM))
6195    (set (match_dup 0) (mem:SI (plus:SI (match_dup 1) (match_dup 3))))]
6196   "operands[3] = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];"
6199 ;; operand1 is the memory address to go into 
6200 ;; pic_load_addr_32bit.
6201 ;; operand2 is the PIC label to be emitted 
6202 ;; from pic_add_dot_plus_eight.
6203 ;; We do this to allow hoisting of the entire insn.
6204 (define_insn_and_split "pic_load_addr_unified"
6205   [(set (match_operand:SI 0 "s_register_operand" "=r,r,l")
6206         (unspec:SI [(match_operand:SI 1 "" "mX,mX,mX") 
6207                     (match_operand:SI 2 "" "")] 
6208                     UNSPEC_PIC_UNIFIED))]
6209  "flag_pic"
6210  "#"
6211  "&& reload_completed"
6212  [(set (match_dup 0) (unspec:SI [(match_dup 1)] UNSPEC_PIC_SYM))
6213   (set (match_dup 0) (unspec:SI [(match_dup 0) (match_dup 3)
6214                                  (match_dup 2)] UNSPEC_PIC_BASE))]
6215  "operands[3] = TARGET_THUMB ? GEN_INT (4) : GEN_INT (8);"
6216  [(set_attr "type" "load1,load1,load1")
6217   (set_attr "pool_range" "4096,4094,1022")
6218   (set_attr "neg_pool_range" "4084,0,0")
6219   (set_attr "arch"  "a,t2,t1")    
6220   (set_attr "length" "8,6,4")]
6223 ;; The rather odd constraints on the following are to force reload to leave
6224 ;; the insn alone, and to force the minipool generation pass to then move
6225 ;; the GOT symbol to memory.
6227 (define_insn "pic_load_addr_32bit"
6228   [(set (match_operand:SI 0 "s_register_operand" "=r")
6229         (unspec:SI [(match_operand:SI 1 "" "mX")] UNSPEC_PIC_SYM))]
6230   "TARGET_32BIT && flag_pic"
6231   "ldr%?\\t%0, %1"
6232   [(set_attr "type" "load1")
6233    (set (attr "pool_range")
6234         (if_then_else (eq_attr "is_thumb" "no")
6235                       (const_int 4096)
6236                       (const_int 4094)))
6237    (set (attr "neg_pool_range")
6238         (if_then_else (eq_attr "is_thumb" "no")
6239                       (const_int 4084)
6240                       (const_int 0)))]
6243 (define_insn "pic_load_addr_thumb1"
6244   [(set (match_operand:SI 0 "s_register_operand" "=l")
6245         (unspec:SI [(match_operand:SI 1 "" "mX")] UNSPEC_PIC_SYM))]
6246   "TARGET_THUMB1 && flag_pic"
6247   "ldr\\t%0, %1"
6248   [(set_attr "type" "load1")
6249    (set (attr "pool_range") (const_int 1018))]
6252 (define_insn "pic_add_dot_plus_four"
6253   [(set (match_operand:SI 0 "register_operand" "=r")
6254         (unspec:SI [(match_operand:SI 1 "register_operand" "0")
6255                     (const_int 4)
6256                     (match_operand 2 "" "")]
6257                    UNSPEC_PIC_BASE))]
6258   "TARGET_THUMB"
6259   "*
6260   (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
6261                                      INTVAL (operands[2]));
6262   return \"add\\t%0, %|pc\";
6263   "
6264   [(set_attr "length" "2")
6265    (set_attr "type" "alu_sreg")]
6268 (define_insn "pic_add_dot_plus_eight"
6269   [(set (match_operand:SI 0 "register_operand" "=r")
6270         (unspec:SI [(match_operand:SI 1 "register_operand" "r")
6271                     (const_int 8)
6272                     (match_operand 2 "" "")]
6273                    UNSPEC_PIC_BASE))]
6274   "TARGET_ARM"
6275   "*
6276     (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
6277                                        INTVAL (operands[2]));
6278     return \"add%?\\t%0, %|pc, %1\";
6279   "
6280   [(set_attr "predicable" "yes")
6281    (set_attr "type" "alu_sreg")]
6284 (define_insn "tls_load_dot_plus_eight"
6285   [(set (match_operand:SI 0 "register_operand" "=r")
6286         (mem:SI (unspec:SI [(match_operand:SI 1 "register_operand" "r")
6287                             (const_int 8)
6288                             (match_operand 2 "" "")]
6289                            UNSPEC_PIC_BASE)))]
6290   "TARGET_ARM"
6291   "*
6292     (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
6293                                        INTVAL (operands[2]));
6294     return \"ldr%?\\t%0, [%|pc, %1]\t\t@ tls_load_dot_plus_eight\";
6295   "
6296   [(set_attr "predicable" "yes")
6297    (set_attr "type" "load1")]
6300 ;; PIC references to local variables can generate pic_add_dot_plus_eight
6301 ;; followed by a load.  These sequences can be crunched down to
6302 ;; tls_load_dot_plus_eight by a peephole.
6304 (define_peephole2
6305   [(set (match_operand:SI 0 "register_operand" "")
6306         (unspec:SI [(match_operand:SI 3 "register_operand" "")
6307                     (const_int 8)
6308                     (match_operand 1 "" "")]
6309                    UNSPEC_PIC_BASE))
6310    (set (match_operand:SI 2 "arm_general_register_operand" "")
6311         (mem:SI (match_dup 0)))]
6312   "TARGET_ARM && peep2_reg_dead_p (2, operands[0])"
6313   [(set (match_dup 2)
6314         (mem:SI (unspec:SI [(match_dup 3)
6315                             (const_int 8)
6316                             (match_dup 1)]
6317                            UNSPEC_PIC_BASE)))]
6318   ""
6321 (define_insn "pic_offset_arm"
6322   [(set (match_operand:SI 0 "register_operand" "=r")
6323         (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
6324                          (unspec:SI [(match_operand:SI 2 "" "X")]
6325                                     UNSPEC_PIC_OFFSET))))]
6326   "TARGET_VXWORKS_RTP && TARGET_ARM && flag_pic"
6327   "ldr%?\\t%0, [%1,%2]"
6328   [(set_attr "type" "load1")]
6331 (define_expand "builtin_setjmp_receiver"
6332   [(label_ref (match_operand 0 "" ""))]
6333   "flag_pic"
6334   "
6336   /* r3 is clobbered by set/longjmp, so we can use it as a scratch
6337      register.  */
6338   if (arm_pic_register != INVALID_REGNUM)
6339     arm_load_pic_register (1UL << 3);
6340   DONE;
6343 ;; If copying one reg to another we can set the condition codes according to
6344 ;; its value.  Such a move is common after a return from subroutine and the
6345 ;; result is being tested against zero.
6347 (define_insn "*movsi_compare0"
6348   [(set (reg:CC CC_REGNUM)
6349         (compare:CC (match_operand:SI 1 "s_register_operand" "0,r")
6350                     (const_int 0)))
6351    (set (match_operand:SI 0 "s_register_operand" "=r,r")
6352         (match_dup 1))]
6353   "TARGET_32BIT"
6354   "@
6355    cmp%?\\t%0, #0
6356    subs%?\\t%0, %1, #0"
6357   [(set_attr "conds" "set")
6358    (set_attr "type" "alus_imm,alus_imm")]
6361 ;; Subroutine to store a half word from a register into memory.
6362 ;; Operand 0 is the source register (HImode)
6363 ;; Operand 1 is the destination address in a register (SImode)
6365 ;; In both this routine and the next, we must be careful not to spill
6366 ;; a memory address of reg+large_const into a separate PLUS insn, since this
6367 ;; can generate unrecognizable rtl.
6369 (define_expand "storehi"
6370   [;; store the low byte
6371    (set (match_operand 1 "" "") (match_dup 3))
6372    ;; extract the high byte
6373    (set (match_dup 2)
6374         (ashiftrt:SI (match_operand 0 "" "") (const_int 8)))
6375    ;; store the high byte
6376    (set (match_dup 4) (match_dup 5))]
6377   "TARGET_ARM"
6378   "
6379   {
6380     rtx op1 = operands[1];
6381     rtx addr = XEXP (op1, 0);
6382     enum rtx_code code = GET_CODE (addr);
6384     if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1)))
6385         || code == MINUS)
6386       op1 = replace_equiv_address (operands[1], force_reg (SImode, addr));
6388     operands[4] = adjust_address (op1, QImode, 1);
6389     operands[1] = adjust_address (operands[1], QImode, 0);
6390     operands[3] = gen_lowpart (QImode, operands[0]);
6391     operands[0] = gen_lowpart (SImode, operands[0]);
6392     operands[2] = gen_reg_rtx (SImode);
6393     operands[5] = gen_lowpart (QImode, operands[2]);
6394   }"
6397 (define_expand "storehi_bigend"
6398   [(set (match_dup 4) (match_dup 3))
6399    (set (match_dup 2)
6400         (ashiftrt:SI (match_operand 0 "" "") (const_int 8)))
6401    (set (match_operand 1 "" "") (match_dup 5))]
6402   "TARGET_ARM"
6403   "
6404   {
6405     rtx op1 = operands[1];
6406     rtx addr = XEXP (op1, 0);
6407     enum rtx_code code = GET_CODE (addr);
6409     if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1)))
6410         || code == MINUS)
6411       op1 = replace_equiv_address (op1, force_reg (SImode, addr));
6413     operands[4] = adjust_address (op1, QImode, 1);
6414     operands[1] = adjust_address (operands[1], QImode, 0);
6415     operands[3] = gen_lowpart (QImode, operands[0]);
6416     operands[0] = gen_lowpart (SImode, operands[0]);
6417     operands[2] = gen_reg_rtx (SImode);
6418     operands[5] = gen_lowpart (QImode, operands[2]);
6419   }"
6422 ;; Subroutine to store a half word integer constant into memory.
6423 (define_expand "storeinthi"
6424   [(set (match_operand 0 "" "")
6425         (match_operand 1 "" ""))
6426    (set (match_dup 3) (match_dup 2))]
6427   "TARGET_ARM"
6428   "
6429   {
6430     HOST_WIDE_INT value = INTVAL (operands[1]);
6431     rtx addr = XEXP (operands[0], 0);
6432     rtx op0 = operands[0];
6433     enum rtx_code code = GET_CODE (addr);
6435     if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1)))
6436         || code == MINUS)
6437       op0 = replace_equiv_address (op0, force_reg (SImode, addr));
6439     operands[1] = gen_reg_rtx (SImode);
6440     if (BYTES_BIG_ENDIAN)
6441       {
6442         emit_insn (gen_movsi (operands[1], GEN_INT ((value >> 8) & 255)));
6443         if ((value & 255) == ((value >> 8) & 255))
6444           operands[2] = operands[1];
6445         else
6446           {
6447             operands[2] = gen_reg_rtx (SImode);
6448             emit_insn (gen_movsi (operands[2], GEN_INT (value & 255)));
6449           }
6450       }
6451     else
6452       {
6453         emit_insn (gen_movsi (operands[1], GEN_INT (value & 255)));
6454         if ((value & 255) == ((value >> 8) & 255))
6455           operands[2] = operands[1];
6456         else
6457           {
6458             operands[2] = gen_reg_rtx (SImode);
6459             emit_insn (gen_movsi (operands[2], GEN_INT ((value >> 8) & 255)));
6460           }
6461       }
6463     operands[3] = adjust_address (op0, QImode, 1);
6464     operands[0] = adjust_address (operands[0], QImode, 0);
6465     operands[2] = gen_lowpart (QImode, operands[2]);
6466     operands[1] = gen_lowpart (QImode, operands[1]);
6467   }"
6470 (define_expand "storehi_single_op"
6471   [(set (match_operand:HI 0 "memory_operand" "")
6472         (match_operand:HI 1 "general_operand" ""))]
6473   "TARGET_32BIT && arm_arch4"
6474   "
6475   if (!s_register_operand (operands[1], HImode))
6476     operands[1] = copy_to_mode_reg (HImode, operands[1]);
6477   "
6480 (define_expand "movhi"
6481   [(set (match_operand:HI 0 "general_operand" "")
6482         (match_operand:HI 1 "general_operand" ""))]
6483   "TARGET_EITHER"
6484   "
6485   if (TARGET_ARM)
6486     {
6487       if (can_create_pseudo_p ())
6488         {
6489           if (MEM_P (operands[0]))
6490             {
6491               if (arm_arch4)
6492                 {
6493                   emit_insn (gen_storehi_single_op (operands[0], operands[1]));
6494                   DONE;
6495                 }
6496               if (CONST_INT_P (operands[1]))
6497                 emit_insn (gen_storeinthi (operands[0], operands[1]));
6498               else
6499                 {
6500                   if (MEM_P (operands[1]))
6501                     operands[1] = force_reg (HImode, operands[1]);
6502                   if (BYTES_BIG_ENDIAN)
6503                     emit_insn (gen_storehi_bigend (operands[1], operands[0]));
6504                   else
6505                    emit_insn (gen_storehi (operands[1], operands[0]));
6506                 }
6507               DONE;
6508             }
6509           /* Sign extend a constant, and keep it in an SImode reg.  */
6510           else if (CONST_INT_P (operands[1]))
6511             {
6512               rtx reg = gen_reg_rtx (SImode);
6513               HOST_WIDE_INT val = INTVAL (operands[1]) & 0xffff;
6515               /* If the constant is already valid, leave it alone.  */
6516               if (!const_ok_for_arm (val))
6517                 {
6518                   /* If setting all the top bits will make the constant 
6519                      loadable in a single instruction, then set them.  
6520                      Otherwise, sign extend the number.  */
6522                   if (const_ok_for_arm (~(val | ~0xffff)))
6523                     val |= ~0xffff;
6524                   else if (val & 0x8000)
6525                     val |= ~0xffff;
6526                 }
6528               emit_insn (gen_movsi (reg, GEN_INT (val)));
6529               operands[1] = gen_lowpart (HImode, reg);
6530             }
6531           else if (arm_arch4 && optimize && can_create_pseudo_p ()
6532                    && MEM_P (operands[1]))
6533             {
6534               rtx reg = gen_reg_rtx (SImode);
6536               emit_insn (gen_zero_extendhisi2 (reg, operands[1]));
6537               operands[1] = gen_lowpart (HImode, reg);
6538             }
6539           else if (!arm_arch4)
6540             {
6541               if (MEM_P (operands[1]))
6542                 {
6543                   rtx base;
6544                   rtx offset = const0_rtx;
6545                   rtx reg = gen_reg_rtx (SImode);
6547                   if ((REG_P (base = XEXP (operands[1], 0))
6548                        || (GET_CODE (base) == PLUS
6549                            && (CONST_INT_P (offset = XEXP (base, 1)))
6550                            && ((INTVAL(offset) & 1) != 1)
6551                            && REG_P (base = XEXP (base, 0))))
6552                       && REGNO_POINTER_ALIGN (REGNO (base)) >= 32)
6553                     {
6554                       rtx new_rtx;
6556                       new_rtx = widen_memory_access (operands[1], SImode,
6557                                                      ((INTVAL (offset) & ~3)
6558                                                       - INTVAL (offset)));
6559                       emit_insn (gen_movsi (reg, new_rtx));
6560                       if (((INTVAL (offset) & 2) != 0)
6561                           ^ (BYTES_BIG_ENDIAN ? 1 : 0))
6562                         {
6563                           rtx reg2 = gen_reg_rtx (SImode);
6565                           emit_insn (gen_lshrsi3 (reg2, reg, GEN_INT (16)));
6566                           reg = reg2;
6567                         }
6568                     }
6569                   else
6570                     emit_insn (gen_movhi_bytes (reg, operands[1]));
6572                   operands[1] = gen_lowpart (HImode, reg);
6573                }
6574            }
6575         }
6576       /* Handle loading a large integer during reload.  */
6577       else if (CONST_INT_P (operands[1])
6578                && !const_ok_for_arm (INTVAL (operands[1]))
6579                && !const_ok_for_arm (~INTVAL (operands[1])))
6580         {
6581           /* Writing a constant to memory needs a scratch, which should
6582              be handled with SECONDARY_RELOADs.  */
6583           gcc_assert (REG_P (operands[0]));
6585           operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
6586           emit_insn (gen_movsi (operands[0], operands[1]));
6587           DONE;
6588        }
6589     }
6590   else if (TARGET_THUMB2)
6591     {
6592       /* Thumb-2 can do everything except mem=mem and mem=const easily.  */
6593       if (can_create_pseudo_p ())
6594         {
6595           if (!REG_P (operands[0]))
6596             operands[1] = force_reg (HImode, operands[1]);
6597           /* Zero extend a constant, and keep it in an SImode reg.  */
6598           else if (CONST_INT_P (operands[1]))
6599             {
6600               rtx reg = gen_reg_rtx (SImode);
6601               HOST_WIDE_INT val = INTVAL (operands[1]) & 0xffff;
6603               emit_insn (gen_movsi (reg, GEN_INT (val)));
6604               operands[1] = gen_lowpart (HImode, reg);
6605             }
6606         }
6607     }
6608   else /* TARGET_THUMB1 */
6609     {
6610       if (can_create_pseudo_p ())
6611         {
6612           if (CONST_INT_P (operands[1]))
6613             {
6614               rtx reg = gen_reg_rtx (SImode);
6616               emit_insn (gen_movsi (reg, operands[1]));
6617               operands[1] = gen_lowpart (HImode, reg);
6618             }
6620           /* ??? We shouldn't really get invalid addresses here, but this can
6621              happen if we are passed a SP (never OK for HImode/QImode) or 
6622              virtual register (also rejected as illegitimate for HImode/QImode)
6623              relative address.  */
6624           /* ??? This should perhaps be fixed elsewhere, for instance, in
6625              fixup_stack_1, by checking for other kinds of invalid addresses,
6626              e.g. a bare reference to a virtual register.  This may confuse the
6627              alpha though, which must handle this case differently.  */
6628           if (MEM_P (operands[0])
6629               && !memory_address_p (GET_MODE (operands[0]),
6630                                     XEXP (operands[0], 0)))
6631             operands[0]
6632               = replace_equiv_address (operands[0],
6633                                        copy_to_reg (XEXP (operands[0], 0)));
6634    
6635           if (MEM_P (operands[1])
6636               && !memory_address_p (GET_MODE (operands[1]),
6637                                     XEXP (operands[1], 0)))
6638             operands[1]
6639               = replace_equiv_address (operands[1],
6640                                        copy_to_reg (XEXP (operands[1], 0)));
6642           if (MEM_P (operands[1]) && optimize > 0)
6643             {
6644               rtx reg = gen_reg_rtx (SImode);
6646               emit_insn (gen_zero_extendhisi2 (reg, operands[1]));
6647               operands[1] = gen_lowpart (HImode, reg);
6648             }
6650           if (MEM_P (operands[0]))
6651             operands[1] = force_reg (HImode, operands[1]);
6652         }
6653       else if (CONST_INT_P (operands[1])
6654                 && !satisfies_constraint_I (operands[1]))
6655         {
6656           /* Handle loading a large integer during reload.  */
6658           /* Writing a constant to memory needs a scratch, which should
6659              be handled with SECONDARY_RELOADs.  */
6660           gcc_assert (REG_P (operands[0]));
6662           operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
6663           emit_insn (gen_movsi (operands[0], operands[1]));
6664           DONE;
6665         }
6666     }
6667   "
6670 (define_expand "movhi_bytes"
6671   [(set (match_dup 2) (zero_extend:SI (match_operand:HI 1 "" "")))
6672    (set (match_dup 3)
6673         (zero_extend:SI (match_dup 6)))
6674    (set (match_operand:SI 0 "" "")
6675          (ior:SI (ashift:SI (match_dup 4) (const_int 8)) (match_dup 5)))]
6676   "TARGET_ARM"
6677   "
6678   {
6679     rtx mem1, mem2;
6680     rtx addr = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
6682     mem1 = change_address (operands[1], QImode, addr);
6683     mem2 = change_address (operands[1], QImode,
6684                            plus_constant (Pmode, addr, 1));
6685     operands[0] = gen_lowpart (SImode, operands[0]);
6686     operands[1] = mem1;
6687     operands[2] = gen_reg_rtx (SImode);
6688     operands[3] = gen_reg_rtx (SImode);
6689     operands[6] = mem2;
6691     if (BYTES_BIG_ENDIAN)
6692       {
6693         operands[4] = operands[2];
6694         operands[5] = operands[3];
6695       }
6696     else
6697       {
6698         operands[4] = operands[3];
6699         operands[5] = operands[2];
6700       }
6701   }"
6704 (define_expand "movhi_bigend"
6705   [(set (match_dup 2)
6706         (rotate:SI (subreg:SI (match_operand:HI 1 "memory_operand" "") 0)
6707                    (const_int 16)))
6708    (set (match_dup 3)
6709         (ashiftrt:SI (match_dup 2) (const_int 16)))
6710    (set (match_operand:HI 0 "s_register_operand" "")
6711         (match_dup 4))]
6712   "TARGET_ARM"
6713   "
6714   operands[2] = gen_reg_rtx (SImode);
6715   operands[3] = gen_reg_rtx (SImode);
6716   operands[4] = gen_lowpart (HImode, operands[3]);
6717   "
6720 ;; Pattern to recognize insn generated default case above
6721 (define_insn "*movhi_insn_arch4"
6722   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m,r")
6723         (match_operand:HI 1 "general_operand"      "rIk,K,n,r,mi"))]
6724   "TARGET_ARM
6725    && arm_arch4 && !TARGET_HARD_FLOAT
6726    && (register_operand (operands[0], HImode)
6727        || register_operand (operands[1], HImode))"
6728   "@
6729    mov%?\\t%0, %1\\t%@ movhi
6730    mvn%?\\t%0, #%B1\\t%@ movhi
6731    movw%?\\t%0, %L1\\t%@ movhi
6732    strh%?\\t%1, %0\\t%@ movhi
6733    ldrh%?\\t%0, %1\\t%@ movhi"
6734   [(set_attr "predicable" "yes")
6735    (set_attr "pool_range" "*,*,*,*,256")
6736    (set_attr "neg_pool_range" "*,*,*,*,244")
6737    (set_attr "arch" "*,*,v6t2,*,*")
6738    (set_attr_alternative "type"
6739                          [(if_then_else (match_operand 1 "const_int_operand" "")
6740                                         (const_string "mov_imm" )
6741                                         (const_string "mov_reg"))
6742                           (const_string "mvn_imm")
6743                           (const_string "mov_imm")
6744                           (const_string "store1")
6745                           (const_string "load1")])]
6748 (define_insn "*movhi_bytes"
6749   [(set (match_operand:HI 0 "s_register_operand" "=r,r,r")
6750         (match_operand:HI 1 "arm_rhs_operand"  "I,rk,K"))]
6751   "TARGET_ARM && !TARGET_HARD_FLOAT"
6752   "@
6753    mov%?\\t%0, %1\\t%@ movhi
6754    mov%?\\t%0, %1\\t%@ movhi
6755    mvn%?\\t%0, #%B1\\t%@ movhi"
6756   [(set_attr "predicable" "yes")
6757    (set_attr "type" "mov_imm,mov_reg,mvn_imm")]
6760 ;; We use a DImode scratch because we may occasionally need an additional
6761 ;; temporary if the address isn't offsettable -- push_reload doesn't seem
6762 ;; to take any notice of the "o" constraints on reload_memory_operand operand.
6763 (define_expand "reload_outhi"
6764   [(parallel [(match_operand:HI 0 "arm_reload_memory_operand" "=o")
6765               (match_operand:HI 1 "s_register_operand"        "r")
6766               (match_operand:DI 2 "s_register_operand"        "=&l")])]
6767   "TARGET_EITHER"
6768   "if (TARGET_ARM)
6769      arm_reload_out_hi (operands);
6770    else
6771      thumb_reload_out_hi (operands);
6772   DONE;
6773   "
6776 (define_expand "reload_inhi"
6777   [(parallel [(match_operand:HI 0 "s_register_operand" "=r")
6778               (match_operand:HI 1 "arm_reload_memory_operand" "o")
6779               (match_operand:DI 2 "s_register_operand" "=&r")])]
6780   "TARGET_EITHER"
6781   "
6782   if (TARGET_ARM)
6783     arm_reload_in_hi (operands);
6784   else
6785     thumb_reload_out_hi (operands);
6786   DONE;
6789 (define_expand "movqi"
6790   [(set (match_operand:QI 0 "general_operand" "")
6791         (match_operand:QI 1 "general_operand" ""))]
6792   "TARGET_EITHER"
6793   "
6794   /* Everything except mem = const or mem = mem can be done easily */
6796   if (can_create_pseudo_p ())
6797     {
6798       if (CONST_INT_P (operands[1]))
6799         {
6800           rtx reg = gen_reg_rtx (SImode);
6802           /* For thumb we want an unsigned immediate, then we are more likely 
6803              to be able to use a movs insn.  */
6804           if (TARGET_THUMB)
6805             operands[1] = GEN_INT (INTVAL (operands[1]) & 255);
6807           emit_insn (gen_movsi (reg, operands[1]));
6808           operands[1] = gen_lowpart (QImode, reg);
6809         }
6811       if (TARGET_THUMB)
6812         {
6813           /* ??? We shouldn't really get invalid addresses here, but this can
6814              happen if we are passed a SP (never OK for HImode/QImode) or
6815              virtual register (also rejected as illegitimate for HImode/QImode)
6816              relative address.  */
6817           /* ??? This should perhaps be fixed elsewhere, for instance, in
6818              fixup_stack_1, by checking for other kinds of invalid addresses,
6819              e.g. a bare reference to a virtual register.  This may confuse the
6820              alpha though, which must handle this case differently.  */
6821           if (MEM_P (operands[0])
6822               && !memory_address_p (GET_MODE (operands[0]),
6823                                      XEXP (operands[0], 0)))
6824             operands[0]
6825               = replace_equiv_address (operands[0],
6826                                        copy_to_reg (XEXP (operands[0], 0)));
6827           if (MEM_P (operands[1])
6828               && !memory_address_p (GET_MODE (operands[1]),
6829                                     XEXP (operands[1], 0)))
6830              operands[1]
6831                = replace_equiv_address (operands[1],
6832                                         copy_to_reg (XEXP (operands[1], 0)));
6833         }
6835       if (MEM_P (operands[1]) && optimize > 0)
6836         {
6837           rtx reg = gen_reg_rtx (SImode);
6839           emit_insn (gen_zero_extendqisi2 (reg, operands[1]));
6840           operands[1] = gen_lowpart (QImode, reg);
6841         }
6843       if (MEM_P (operands[0]))
6844         operands[1] = force_reg (QImode, operands[1]);
6845     }
6846   else if (TARGET_THUMB
6847            && CONST_INT_P (operands[1])
6848            && !satisfies_constraint_I (operands[1]))
6849     {
6850       /* Handle loading a large integer during reload.  */
6852       /* Writing a constant to memory needs a scratch, which should
6853          be handled with SECONDARY_RELOADs.  */
6854       gcc_assert (REG_P (operands[0]));
6856       operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
6857       emit_insn (gen_movsi (operands[0], operands[1]));
6858       DONE;
6859     }
6860   "
6863 (define_insn "*arm_movqi_insn"
6864   [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,r,l,r,l,Uu,r,m")
6865         (match_operand:QI 1 "general_operand" "rk,rk,I,Py,K,Uu,l,Uh,r"))]
6866   "TARGET_32BIT
6867    && (   register_operand (operands[0], QImode)
6868        || register_operand (operands[1], QImode))"
6869   "@
6870    mov%?\\t%0, %1
6871    mov%?\\t%0, %1
6872    mov%?\\t%0, %1
6873    mov%?\\t%0, %1
6874    mvn%?\\t%0, #%B1
6875    ldrb%?\\t%0, %1
6876    strb%?\\t%1, %0
6877    ldrb%?\\t%0, %1
6878    strb%?\\t%1, %0"
6879   [(set_attr "type" "mov_reg,mov_reg,mov_imm,mov_imm,mvn_imm,load1,store1,load1,store1")
6880    (set_attr "predicable" "yes")
6881    (set_attr "predicable_short_it" "yes,yes,no,yes,no,no,no,no,no")
6882    (set_attr "arch" "t2,any,any,t2,any,t2,t2,any,any")
6883    (set_attr "length" "2,4,4,2,4,2,2,4,4")]
6886 ;; HFmode moves
6887 (define_expand "movhf"
6888   [(set (match_operand:HF 0 "general_operand" "")
6889         (match_operand:HF 1 "general_operand" ""))]
6890   "TARGET_EITHER"
6891   "
6892   if (TARGET_32BIT)
6893     {
6894       if (MEM_P (operands[0]))
6895         operands[1] = force_reg (HFmode, operands[1]);
6896     }
6897   else /* TARGET_THUMB1 */
6898     {
6899       if (can_create_pseudo_p ())
6900         {
6901            if (!REG_P (operands[0]))
6902              operands[1] = force_reg (HFmode, operands[1]);
6903         }
6904     }
6905   "
6908 (define_insn "*arm32_movhf"
6909   [(set (match_operand:HF 0 "nonimmediate_operand" "=r,m,r,r")
6910         (match_operand:HF 1 "general_operand"      " m,r,r,F"))]
6911   "TARGET_32BIT && !TARGET_HARD_FLOAT
6912    && (   s_register_operand (operands[0], HFmode)
6913        || s_register_operand (operands[1], HFmode))"
6914   "*
6915   switch (which_alternative)
6916     {
6917     case 0:     /* ARM register from memory */
6918       return \"ldrh%?\\t%0, %1\\t%@ __fp16\";
6919     case 1:     /* memory from ARM register */
6920       return \"strh%?\\t%1, %0\\t%@ __fp16\";
6921     case 2:     /* ARM register from ARM register */
6922       return \"mov%?\\t%0, %1\\t%@ __fp16\";
6923     case 3:     /* ARM register from constant */
6924       {
6925         long bits;
6926         rtx ops[4];
6928         bits = real_to_target (NULL, CONST_DOUBLE_REAL_VALUE (operands[1]),
6929                                HFmode);
6930         ops[0] = operands[0];
6931         ops[1] = GEN_INT (bits);
6932         ops[2] = GEN_INT (bits & 0xff00);
6933         ops[3] = GEN_INT (bits & 0x00ff);
6935         if (arm_arch_thumb2)
6936           output_asm_insn (\"movw%?\\t%0, %1\", ops);
6937         else
6938           output_asm_insn (\"mov%?\\t%0, %2\;orr%?\\t%0, %0, %3\", ops);
6939         return \"\";
6940        }
6941     default:
6942       gcc_unreachable ();
6943     }
6944   "
6945   [(set_attr "conds" "unconditional")
6946    (set_attr "type" "load1,store1,mov_reg,multiple")
6947    (set_attr "length" "4,4,4,8")
6948    (set_attr "predicable" "yes")
6949    (set_attr "predicable_short_it" "no")]
6952 (define_expand "movsf"
6953   [(set (match_operand:SF 0 "general_operand" "")
6954         (match_operand:SF 1 "general_operand" ""))]
6955   "TARGET_EITHER"
6956   "
6957   if (TARGET_32BIT)
6958     {
6959       if (MEM_P (operands[0]))
6960         operands[1] = force_reg (SFmode, operands[1]);
6961     }
6962   else /* TARGET_THUMB1 */
6963     {
6964       if (can_create_pseudo_p ())
6965         {
6966            if (!REG_P (operands[0]))
6967              operands[1] = force_reg (SFmode, operands[1]);
6968         }
6969     }
6970   "
6973 ;; Transform a floating-point move of a constant into a core register into
6974 ;; an SImode operation.
6975 (define_split
6976   [(set (match_operand:SF 0 "arm_general_register_operand" "")
6977         (match_operand:SF 1 "immediate_operand" ""))]
6978   "TARGET_EITHER
6979    && reload_completed
6980    && CONST_DOUBLE_P (operands[1])"
6981   [(set (match_dup 2) (match_dup 3))]
6982   "
6983   operands[2] = gen_lowpart (SImode, operands[0]);
6984   operands[3] = gen_lowpart (SImode, operands[1]);
6985   if (operands[2] == 0 || operands[3] == 0)
6986     FAIL;
6987   "
6990 (define_insn "*arm_movsf_soft_insn"
6991   [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,m")
6992         (match_operand:SF 1 "general_operand"  "r,mE,r"))]
6993   "TARGET_32BIT
6994    && TARGET_SOFT_FLOAT
6995    && (!MEM_P (operands[0])
6996        || register_operand (operands[1], SFmode))"
6997   "@
6998    mov%?\\t%0, %1
6999    ldr%?\\t%0, %1\\t%@ float
7000    str%?\\t%1, %0\\t%@ float"
7001   [(set_attr "predicable" "yes")
7002    (set_attr "predicable_short_it" "no")
7003    (set_attr "type" "mov_reg,load1,store1")
7004    (set_attr "arm_pool_range" "*,4096,*")
7005    (set_attr "thumb2_pool_range" "*,4094,*")
7006    (set_attr "arm_neg_pool_range" "*,4084,*")
7007    (set_attr "thumb2_neg_pool_range" "*,0,*")]
7010 (define_expand "movdf"
7011   [(set (match_operand:DF 0 "general_operand" "")
7012         (match_operand:DF 1 "general_operand" ""))]
7013   "TARGET_EITHER"
7014   "
7015   if (TARGET_32BIT)
7016     {
7017       if (MEM_P (operands[0]))
7018         operands[1] = force_reg (DFmode, operands[1]);
7019     }
7020   else /* TARGET_THUMB */
7021     {
7022       if (can_create_pseudo_p ())
7023         {
7024           if (!REG_P (operands[0]))
7025             operands[1] = force_reg (DFmode, operands[1]);
7026         }
7027     }
7028   "
7031 ;; Reloading a df mode value stored in integer regs to memory can require a
7032 ;; scratch reg.
7033 (define_expand "reload_outdf"
7034   [(match_operand:DF 0 "arm_reload_memory_operand" "=o")
7035    (match_operand:DF 1 "s_register_operand" "r")
7036    (match_operand:SI 2 "s_register_operand" "=&r")]
7037   "TARGET_THUMB2"
7038   "
7039   {
7040     enum rtx_code code = GET_CODE (XEXP (operands[0], 0));
7042     if (code == REG)
7043       operands[2] = XEXP (operands[0], 0);
7044     else if (code == POST_INC || code == PRE_DEC)
7045       {
7046         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7047         operands[1] = gen_rtx_SUBREG (DImode, operands[1], 0);
7048         emit_insn (gen_movdi (operands[0], operands[1]));
7049         DONE;
7050       }
7051     else if (code == PRE_INC)
7052       {
7053         rtx reg = XEXP (XEXP (operands[0], 0), 0);
7055         emit_insn (gen_addsi3 (reg, reg, GEN_INT (8)));
7056         operands[2] = reg;
7057       }
7058     else if (code == POST_DEC)
7059       operands[2] = XEXP (XEXP (operands[0], 0), 0);
7060     else
7061       emit_insn (gen_addsi3 (operands[2], XEXP (XEXP (operands[0], 0), 0),
7062                              XEXP (XEXP (operands[0], 0), 1)));
7064     emit_insn (gen_rtx_SET (replace_equiv_address (operands[0], operands[2]),
7065                             operands[1]));
7067     if (code == POST_DEC)
7068       emit_insn (gen_addsi3 (operands[2], operands[2], GEN_INT (-8)));
7070     DONE;
7071   }"
7074 (define_insn "*movdf_soft_insn"
7075   [(set (match_operand:DF 0 "nonimmediate_soft_df_operand" "=r,r,r,q,m")
7076         (match_operand:DF 1 "soft_df_operand" "rDa,Db,Dc,mF,q"))]
7077   "TARGET_32BIT && TARGET_SOFT_FLOAT
7078    && (   register_operand (operands[0], DFmode)
7079        || register_operand (operands[1], DFmode))"
7080   "*
7081   switch (which_alternative)
7082     {
7083     case 0:
7084     case 1:
7085     case 2:
7086       return \"#\";
7087     default:
7088       return output_move_double (operands, true, NULL);
7089     }
7090   "
7091   [(set_attr "length" "8,12,16,8,8")
7092    (set_attr "type" "multiple,multiple,multiple,load2,store2")
7093    (set_attr "arm_pool_range" "*,*,*,1020,*")
7094    (set_attr "thumb2_pool_range" "*,*,*,1018,*")
7095    (set_attr "arm_neg_pool_range" "*,*,*,1004,*")
7096    (set_attr "thumb2_neg_pool_range" "*,*,*,0,*")]
7100 ;; load- and store-multiple insns
7101 ;; The arm can load/store any set of registers, provided that they are in
7102 ;; ascending order, but these expanders assume a contiguous set.
7104 (define_expand "load_multiple"
7105   [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
7106                           (match_operand:SI 1 "" ""))
7107                      (use (match_operand:SI 2 "" ""))])]
7108   "TARGET_32BIT"
7110   HOST_WIDE_INT offset = 0;
7112   /* Support only fixed point registers.  */
7113   if (!CONST_INT_P (operands[2])
7114       || INTVAL (operands[2]) > MAX_LDM_STM_OPS
7115       || INTVAL (operands[2]) < 2
7116       || !MEM_P (operands[1])
7117       || !REG_P (operands[0])
7118       || REGNO (operands[0]) > (LAST_ARM_REGNUM - 1)
7119       || REGNO (operands[0]) + INTVAL (operands[2]) > LAST_ARM_REGNUM)
7120     FAIL;
7122   operands[3]
7123     = arm_gen_load_multiple (arm_regs_in_sequence + REGNO (operands[0]),
7124                              INTVAL (operands[2]),
7125                              force_reg (SImode, XEXP (operands[1], 0)),
7126                              FALSE, operands[1], &offset);
7129 (define_expand "store_multiple"
7130   [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
7131                           (match_operand:SI 1 "" ""))
7132                      (use (match_operand:SI 2 "" ""))])]
7133   "TARGET_32BIT"
7135   HOST_WIDE_INT offset = 0;
7137   /* Support only fixed point registers.  */
7138   if (!CONST_INT_P (operands[2])
7139       || INTVAL (operands[2]) > MAX_LDM_STM_OPS
7140       || INTVAL (operands[2]) < 2
7141       || !REG_P (operands[1])
7142       || !MEM_P (operands[0])
7143       || REGNO (operands[1]) > (LAST_ARM_REGNUM - 1)
7144       || REGNO (operands[1]) + INTVAL (operands[2]) > LAST_ARM_REGNUM)
7145     FAIL;
7147   operands[3]
7148     = arm_gen_store_multiple (arm_regs_in_sequence + REGNO (operands[1]),
7149                               INTVAL (operands[2]),
7150                               force_reg (SImode, XEXP (operands[0], 0)),
7151                               FALSE, operands[0], &offset);
7155 (define_expand "setmemsi"
7156   [(match_operand:BLK 0 "general_operand" "")
7157    (match_operand:SI 1 "const_int_operand" "")
7158    (match_operand:SI 2 "const_int_operand" "")
7159    (match_operand:SI 3 "const_int_operand" "")]
7160   "TARGET_32BIT"
7162   if (arm_gen_setmem (operands))
7163     DONE;
7165   FAIL;
7169 ;; Move a block of memory if it is word aligned and MORE than 2 words long.
7170 ;; We could let this apply for blocks of less than this, but it clobbers so
7171 ;; many registers that there is then probably a better way.
7173 (define_expand "movmemqi"
7174   [(match_operand:BLK 0 "general_operand" "")
7175    (match_operand:BLK 1 "general_operand" "")
7176    (match_operand:SI 2 "const_int_operand" "")
7177    (match_operand:SI 3 "const_int_operand" "")]
7178   ""
7179   "
7180   if (TARGET_32BIT)
7181     {
7182       if (TARGET_LDRD && current_tune->prefer_ldrd_strd
7183           && !optimize_function_for_size_p (cfun))
7184         {
7185           if (gen_movmem_ldrd_strd (operands))
7186             DONE;
7187           FAIL;
7188         }
7190       if (arm_gen_movmemqi (operands))
7191         DONE;
7192       FAIL;
7193     }
7194   else /* TARGET_THUMB1 */
7195     {
7196       if (   INTVAL (operands[3]) != 4
7197           || INTVAL (operands[2]) > 48)
7198         FAIL;
7200       thumb_expand_movmemqi (operands);
7201       DONE;
7202     }
7203   "
7207 ;; Compare & branch insns
7208 ;; The range calculations are based as follows:
7209 ;; For forward branches, the address calculation returns the address of
7210 ;; the next instruction.  This is 2 beyond the branch instruction.
7211 ;; For backward branches, the address calculation returns the address of
7212 ;; the first instruction in this pattern (cmp).  This is 2 before the branch
7213 ;; instruction for the shortest sequence, and 4 before the branch instruction
7214 ;; if we have to jump around an unconditional branch.
7215 ;; To the basic branch range the PC offset must be added (this is +4).
7216 ;; So for forward branches we have 
7217 ;;   (pos_range - pos_base_offs + pc_offs) = (pos_range - 2 + 4).
7218 ;; And for backward branches we have 
7219 ;;   (neg_range - neg_base_offs + pc_offs) = (neg_range - (-2 or -4) + 4).
7221 ;; For a 'b'       pos_range = 2046, neg_range = -2048 giving (-2040->2048).
7222 ;; For a 'b<cond>' pos_range = 254,  neg_range = -256  giving (-250 ->256).
7224 (define_expand "cbranchsi4"
7225   [(set (pc) (if_then_else
7226               (match_operator 0 "expandable_comparison_operator"
7227                [(match_operand:SI 1 "s_register_operand" "")
7228                 (match_operand:SI 2 "nonmemory_operand" "")])
7229               (label_ref (match_operand 3 "" ""))
7230               (pc)))]
7231   "TARGET_EITHER"
7232   "
7233   if (!TARGET_THUMB1)
7234     {
7235       if (!arm_validize_comparison (&operands[0], &operands[1], &operands[2]))
7236         FAIL;
7237       emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
7238                                       operands[3]));
7239       DONE;
7240     }
7241   if (thumb1_cmpneg_operand (operands[2], SImode))
7242     {
7243       emit_jump_insn (gen_cbranchsi4_scratch (NULL, operands[1], operands[2],
7244                                               operands[3], operands[0]));
7245       DONE;
7246     }
7247   if (!thumb1_cmp_operand (operands[2], SImode))
7248     operands[2] = force_reg (SImode, operands[2]);
7249   ")
7251 (define_expand "cbranchsf4"
7252   [(set (pc) (if_then_else
7253               (match_operator 0 "expandable_comparison_operator"
7254                [(match_operand:SF 1 "s_register_operand" "")
7255                 (match_operand:SF 2 "vfp_compare_operand" "")])
7256               (label_ref (match_operand 3 "" ""))
7257               (pc)))]
7258   "TARGET_32BIT && TARGET_HARD_FLOAT"
7259   "emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
7260                                    operands[3])); DONE;"
7263 (define_expand "cbranchdf4"
7264   [(set (pc) (if_then_else
7265               (match_operator 0 "expandable_comparison_operator"
7266                [(match_operand:DF 1 "s_register_operand" "")
7267                 (match_operand:DF 2 "vfp_compare_operand" "")])
7268               (label_ref (match_operand 3 "" ""))
7269               (pc)))]
7270   "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
7271   "emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
7272                                    operands[3])); DONE;"
7275 (define_expand "cbranchdi4"
7276   [(set (pc) (if_then_else
7277               (match_operator 0 "expandable_comparison_operator"
7278                [(match_operand:DI 1 "s_register_operand" "")
7279                 (match_operand:DI 2 "cmpdi_operand" "")])
7280               (label_ref (match_operand 3 "" ""))
7281               (pc)))]
7282   "TARGET_32BIT"
7283   "{
7284      if (!arm_validize_comparison (&operands[0], &operands[1], &operands[2]))
7285        FAIL;
7286      emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
7287                                        operands[3]));
7288      DONE;
7289    }"
7292 ;; Comparison and test insns
7294 (define_insn "*arm_cmpsi_insn"
7295   [(set (reg:CC CC_REGNUM)
7296         (compare:CC (match_operand:SI 0 "s_register_operand" "l,r,r,r,r")
7297                     (match_operand:SI 1 "arm_add_operand"    "Py,r,r,I,L")))]
7298   "TARGET_32BIT"
7299   "@
7300    cmp%?\\t%0, %1
7301    cmp%?\\t%0, %1
7302    cmp%?\\t%0, %1
7303    cmp%?\\t%0, %1
7304    cmn%?\\t%0, #%n1"
7305   [(set_attr "conds" "set")
7306    (set_attr "arch" "t2,t2,any,any,any")
7307    (set_attr "length" "2,2,4,4,4")
7308    (set_attr "predicable" "yes")
7309    (set_attr "predicable_short_it" "yes,yes,yes,no,no")
7310    (set_attr "type" "alus_imm,alus_sreg,alus_sreg,alus_imm,alus_imm")]
7313 (define_insn "*cmpsi_shiftsi"
7314   [(set (reg:CC CC_REGNUM)
7315         (compare:CC (match_operand:SI   0 "s_register_operand" "r,r,r")
7316                     (match_operator:SI  3 "shift_operator"
7317                      [(match_operand:SI 1 "s_register_operand" "r,r,r")
7318                       (match_operand:SI 2 "shift_amount_operand" "M,r,M")])))]
7319   "TARGET_32BIT"
7320   "cmp\\t%0, %1%S3"
7321   [(set_attr "conds" "set")
7322    (set_attr "shift" "1")
7323    (set_attr "arch" "32,a,a")
7324    (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
7326 (define_insn "*cmpsi_shiftsi_swp"
7327   [(set (reg:CC_SWP CC_REGNUM)
7328         (compare:CC_SWP (match_operator:SI 3 "shift_operator"
7329                          [(match_operand:SI 1 "s_register_operand" "r,r,r")
7330                           (match_operand:SI 2 "shift_amount_operand" "M,r,M")])
7331                         (match_operand:SI 0 "s_register_operand" "r,r,r")))]
7332   "TARGET_32BIT"
7333   "cmp%?\\t%0, %1%S3"
7334   [(set_attr "conds" "set")
7335    (set_attr "shift" "1")
7336    (set_attr "arch" "32,a,a")
7337    (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
7339 (define_insn "*arm_cmpsi_negshiftsi_si"
7340   [(set (reg:CC_Z CC_REGNUM)
7341         (compare:CC_Z
7342          (neg:SI (match_operator:SI 1 "shift_operator"
7343                     [(match_operand:SI 2 "s_register_operand" "r")
7344                      (match_operand:SI 3 "reg_or_int_operand" "rM")]))
7345          (match_operand:SI 0 "s_register_operand" "r")))]
7346   "TARGET_ARM"
7347   "cmn%?\\t%0, %2%S1"
7348   [(set_attr "conds" "set")
7349    (set (attr "type") (if_then_else (match_operand 3 "const_int_operand" "")
7350                                     (const_string "alus_shift_imm")
7351                                     (const_string "alus_shift_reg")))
7352    (set_attr "predicable" "yes")]
7355 ;; DImode comparisons.  The generic code generates branches that
7356 ;; if-conversion can not reduce to a conditional compare, so we do
7357 ;; that directly.
7359 (define_insn_and_split "*arm_cmpdi_insn"
7360   [(set (reg:CC_NCV CC_REGNUM)
7361         (compare:CC_NCV (match_operand:DI 0 "s_register_operand" "r")
7362                         (match_operand:DI 1 "arm_di_operand"       "rDi")))
7363    (clobber (match_scratch:SI 2 "=r"))]
7364   "TARGET_32BIT"
7365   "#"   ; "cmp\\t%Q0, %Q1\;sbcs\\t%2, %R0, %R1"
7366   "&& reload_completed"
7367   [(set (reg:CC CC_REGNUM)
7368         (compare:CC (match_dup 0) (match_dup 1)))
7369    (parallel [(set (reg:CC CC_REGNUM)
7370                    (compare:CC (match_dup 3) (match_dup 4)))
7371               (set (match_dup 2)
7372                    (minus:SI (match_dup 5)
7373                             (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))])]
7374   {
7375     operands[3] = gen_highpart (SImode, operands[0]);
7376     operands[0] = gen_lowpart (SImode, operands[0]);
7377     if (CONST_INT_P (operands[1]))
7378       {
7379         operands[4] = GEN_INT (~INTVAL (gen_highpart_mode (SImode,
7380                                                            DImode,
7381                                                            operands[1])));
7382         operands[5] = gen_rtx_PLUS (SImode, operands[3], operands[4]);
7383       }
7384     else
7385       {
7386         operands[4] = gen_highpart (SImode, operands[1]);
7387         operands[5] = gen_rtx_MINUS (SImode, operands[3], operands[4]);
7388       }
7389     operands[1] = gen_lowpart (SImode, operands[1]);
7390     operands[2] = gen_lowpart (SImode, operands[2]);
7391   }
7392   [(set_attr "conds" "set")
7393    (set_attr "length" "8")
7394    (set_attr "type" "multiple")]
7397 (define_insn_and_split "*arm_cmpdi_unsigned"
7398   [(set (reg:CC_CZ CC_REGNUM)
7399         (compare:CC_CZ (match_operand:DI 0 "s_register_operand" "l,r,r,r")
7400                        (match_operand:DI 1 "arm_di_operand"     "Py,r,Di,rDi")))]
7402   "TARGET_32BIT"
7403   "#"   ; "cmp\\t%R0, %R1\;it eq\;cmpeq\\t%Q0, %Q1"
7404   "&& reload_completed"
7405   [(set (reg:CC CC_REGNUM)
7406         (compare:CC (match_dup 2) (match_dup 3)))
7407    (cond_exec (eq:SI (reg:CC CC_REGNUM) (const_int 0))
7408               (set (reg:CC CC_REGNUM)
7409                    (compare:CC (match_dup 0) (match_dup 1))))]
7410   {
7411     operands[2] = gen_highpart (SImode, operands[0]);
7412     operands[0] = gen_lowpart (SImode, operands[0]);
7413     if (CONST_INT_P (operands[1]))
7414       operands[3] = gen_highpart_mode (SImode, DImode, operands[1]);
7415     else
7416       operands[3] = gen_highpart (SImode, operands[1]);
7417     operands[1] = gen_lowpart (SImode, operands[1]);
7418   }
7419   [(set_attr "conds" "set")
7420    (set_attr "enabled_for_depr_it" "yes,yes,no,*")
7421    (set_attr "arch" "t2,t2,t2,a")
7422    (set_attr "length" "6,6,10,8")
7423    (set_attr "type" "multiple")]
7426 (define_insn "*arm_cmpdi_zero"
7427   [(set (reg:CC_Z CC_REGNUM)
7428         (compare:CC_Z (match_operand:DI 0 "s_register_operand" "r")
7429                       (const_int 0)))
7430    (clobber (match_scratch:SI 1 "=r"))]
7431   "TARGET_32BIT"
7432   "orrs%?\\t%1, %Q0, %R0"
7433   [(set_attr "conds" "set")
7434    (set_attr "type" "logics_reg")]
7437 ; This insn allows redundant compares to be removed by cse, nothing should
7438 ; ever appear in the output file since (set (reg x) (reg x)) is a no-op that
7439 ; is deleted later on. The match_dup will match the mode here, so that
7440 ; mode changes of the condition codes aren't lost by this even though we don't
7441 ; specify what they are.
7443 (define_insn "*deleted_compare"
7444   [(set (match_operand 0 "cc_register" "") (match_dup 0))]
7445   "TARGET_32BIT"
7446   "\\t%@ deleted compare"
7447   [(set_attr "conds" "set")
7448    (set_attr "length" "0")
7449    (set_attr "type" "no_insn")]
7453 ;; Conditional branch insns
7455 (define_expand "cbranch_cc"
7456   [(set (pc)
7457         (if_then_else (match_operator 0 "" [(match_operand 1 "" "")
7458                                             (match_operand 2 "" "")])
7459                       (label_ref (match_operand 3 "" ""))
7460                       (pc)))]
7461   "TARGET_32BIT"
7462   "operands[1] = arm_gen_compare_reg (GET_CODE (operands[0]),
7463                                       operands[1], operands[2], NULL_RTX);
7464    operands[2] = const0_rtx;"
7468 ;; Patterns to match conditional branch insns.
7471 (define_insn "arm_cond_branch"
7472   [(set (pc)
7473         (if_then_else (match_operator 1 "arm_comparison_operator"
7474                        [(match_operand 2 "cc_register" "") (const_int 0)])
7475                       (label_ref (match_operand 0 "" ""))
7476                       (pc)))]
7477   "TARGET_32BIT"
7478   "*
7479   if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
7480     {
7481       arm_ccfsm_state += 2;
7482       return \"\";
7483     }
7484   return \"b%d1\\t%l0\";
7485   "
7486   [(set_attr "conds" "use")
7487    (set_attr "type" "branch")
7488    (set (attr "length")
7489         (if_then_else
7490            (and (match_test "TARGET_THUMB2")
7491                 (and (ge (minus (match_dup 0) (pc)) (const_int -250))
7492                      (le (minus (match_dup 0) (pc)) (const_int 256))))
7493            (const_int 2)
7494            (const_int 4)))]
7497 (define_insn "*arm_cond_branch_reversed"
7498   [(set (pc)
7499         (if_then_else (match_operator 1 "arm_comparison_operator"
7500                        [(match_operand 2 "cc_register" "") (const_int 0)])
7501                       (pc)
7502                       (label_ref (match_operand 0 "" ""))))]
7503   "TARGET_32BIT"
7504   "*
7505   if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
7506     {
7507       arm_ccfsm_state += 2;
7508       return \"\";
7509     }
7510   return \"b%D1\\t%l0\";
7511   "
7512   [(set_attr "conds" "use")
7513    (set_attr "type" "branch")
7514    (set (attr "length")
7515         (if_then_else
7516            (and (match_test "TARGET_THUMB2")
7517                 (and (ge (minus (match_dup 0) (pc)) (const_int -250))
7518                      (le (minus (match_dup 0) (pc)) (const_int 256))))
7519            (const_int 2)
7520            (const_int 4)))]
7525 ; scc insns
7527 (define_expand "cstore_cc"
7528   [(set (match_operand:SI 0 "s_register_operand" "")
7529         (match_operator:SI 1 "" [(match_operand 2 "" "")
7530                                  (match_operand 3 "" "")]))]
7531   "TARGET_32BIT"
7532   "operands[2] = arm_gen_compare_reg (GET_CODE (operands[1]),
7533                                       operands[2], operands[3], NULL_RTX);
7534    operands[3] = const0_rtx;"
7537 (define_insn_and_split "*mov_scc"
7538   [(set (match_operand:SI 0 "s_register_operand" "=r")
7539         (match_operator:SI 1 "arm_comparison_operator_mode"
7540          [(match_operand 2 "cc_register" "") (const_int 0)]))]
7541   "TARGET_ARM"
7542   "#"   ; "mov%D1\\t%0, #0\;mov%d1\\t%0, #1"
7543   "TARGET_ARM"
7544   [(set (match_dup 0)
7545         (if_then_else:SI (match_dup 1)
7546                          (const_int 1)
7547                          (const_int 0)))]
7548   ""
7549   [(set_attr "conds" "use")
7550    (set_attr "length" "8")
7551    (set_attr "type" "multiple")]
7554 (define_insn_and_split "*mov_negscc"
7555   [(set (match_operand:SI 0 "s_register_operand" "=r")
7556         (neg:SI (match_operator:SI 1 "arm_comparison_operator_mode"
7557                  [(match_operand 2 "cc_register" "") (const_int 0)])))]
7558   "TARGET_ARM"
7559   "#"   ; "mov%D1\\t%0, #0\;mvn%d1\\t%0, #0"
7560   "TARGET_ARM"
7561   [(set (match_dup 0)
7562         (if_then_else:SI (match_dup 1)
7563                          (match_dup 3)
7564                          (const_int 0)))]
7565   {
7566     operands[3] = GEN_INT (~0);
7567   }
7568   [(set_attr "conds" "use")
7569    (set_attr "length" "8")
7570    (set_attr "type" "multiple")]
7573 (define_insn_and_split "*mov_notscc"
7574   [(set (match_operand:SI 0 "s_register_operand" "=r")
7575         (not:SI (match_operator:SI 1 "arm_comparison_operator"
7576                  [(match_operand 2 "cc_register" "") (const_int 0)])))]
7577   "TARGET_ARM"
7578   "#"   ; "mvn%D1\\t%0, #0\;mvn%d1\\t%0, #1"
7579   "TARGET_ARM"
7580   [(set (match_dup 0)
7581         (if_then_else:SI (match_dup 1)
7582                          (match_dup 3)
7583                          (match_dup 4)))]
7584   {
7585     operands[3] = GEN_INT (~1);
7586     operands[4] = GEN_INT (~0);
7587   }
7588   [(set_attr "conds" "use")
7589    (set_attr "length" "8")
7590    (set_attr "type" "multiple")]
7593 (define_expand "cstoresi4"
7594   [(set (match_operand:SI 0 "s_register_operand" "")
7595         (match_operator:SI 1 "expandable_comparison_operator"
7596          [(match_operand:SI 2 "s_register_operand" "")
7597           (match_operand:SI 3 "reg_or_int_operand" "")]))]
7598   "TARGET_32BIT || TARGET_THUMB1"
7599   "{
7600   rtx op3, scratch, scratch2;
7602   if (!TARGET_THUMB1)
7603     {
7604       if (!arm_add_operand (operands[3], SImode))
7605         operands[3] = force_reg (SImode, operands[3]);
7606       emit_insn (gen_cstore_cc (operands[0], operands[1],
7607                                 operands[2], operands[3]));
7608       DONE;
7609     }
7611   if (operands[3] == const0_rtx)
7612     {
7613       switch (GET_CODE (operands[1]))
7614         {
7615         case EQ:
7616           emit_insn (gen_cstoresi_eq0_thumb1 (operands[0], operands[2]));
7617           break;
7619         case NE:
7620           emit_insn (gen_cstoresi_ne0_thumb1 (operands[0], operands[2]));
7621           break;
7623         case LE:
7624           scratch = expand_binop (SImode, add_optab, operands[2], constm1_rtx,
7625                                   NULL_RTX, 0, OPTAB_WIDEN);
7626           scratch = expand_binop (SImode, ior_optab, operands[2], scratch,
7627                                   NULL_RTX, 0, OPTAB_WIDEN);
7628           expand_binop (SImode, lshr_optab, scratch, GEN_INT (31),
7629                         operands[0], 1, OPTAB_WIDEN);
7630           break;
7632         case GE:
7633           scratch = expand_unop (SImode, one_cmpl_optab, operands[2],
7634                                  NULL_RTX, 1);
7635           expand_binop (SImode, lshr_optab, scratch, GEN_INT (31),
7636                         NULL_RTX, 1, OPTAB_WIDEN);
7637           break;
7639         case GT:
7640           scratch = expand_binop (SImode, ashr_optab, operands[2],
7641                                   GEN_INT (31), NULL_RTX, 0, OPTAB_WIDEN);
7642           scratch = expand_binop (SImode, sub_optab, scratch, operands[2],
7643                                   NULL_RTX, 0, OPTAB_WIDEN);
7644           expand_binop (SImode, lshr_optab, scratch, GEN_INT (31), operands[0],
7645                         0, OPTAB_WIDEN);
7646           break;
7648         /* LT is handled by generic code.  No need for unsigned with 0.  */
7649         default:
7650           FAIL;
7651         }
7652       DONE;
7653     }
7655   switch (GET_CODE (operands[1]))
7656     {
7657     case EQ:
7658       scratch = expand_binop (SImode, sub_optab, operands[2], operands[3],
7659                               NULL_RTX, 0, OPTAB_WIDEN);
7660       emit_insn (gen_cstoresi_eq0_thumb1 (operands[0], scratch));
7661       break;
7663     case NE:
7664       scratch = expand_binop (SImode, sub_optab, operands[2], operands[3],
7665                               NULL_RTX, 0, OPTAB_WIDEN);
7666       emit_insn (gen_cstoresi_ne0_thumb1 (operands[0], scratch));
7667       break;
7669     case LE:
7670       op3 = force_reg (SImode, operands[3]);
7672       scratch = expand_binop (SImode, lshr_optab, operands[2], GEN_INT (31),
7673                               NULL_RTX, 1, OPTAB_WIDEN);
7674       scratch2 = expand_binop (SImode, ashr_optab, op3, GEN_INT (31),
7675                               NULL_RTX, 0, OPTAB_WIDEN);
7676       emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch2,
7677                                           op3, operands[2]));
7678       break;
7680     case GE:
7681       op3 = operands[3];
7682       if (!thumb1_cmp_operand (op3, SImode))
7683         op3 = force_reg (SImode, op3);
7684       scratch = expand_binop (SImode, ashr_optab, operands[2], GEN_INT (31),
7685                               NULL_RTX, 0, OPTAB_WIDEN);
7686       scratch2 = expand_binop (SImode, lshr_optab, op3, GEN_INT (31),
7687                                NULL_RTX, 1, OPTAB_WIDEN);
7688       emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch2,
7689                                           operands[2], op3));
7690       break;
7692     case LEU:
7693       op3 = force_reg (SImode, operands[3]);
7694       scratch = force_reg (SImode, const0_rtx);
7695       emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch,
7696                                           op3, operands[2]));
7697       break;
7699     case GEU:
7700       op3 = operands[3];
7701       if (!thumb1_cmp_operand (op3, SImode))
7702         op3 = force_reg (SImode, op3);
7703       scratch = force_reg (SImode, const0_rtx);
7704       emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch,
7705                                           operands[2], op3));
7706       break;
7708     case LTU:
7709       op3 = operands[3];
7710       if (!thumb1_cmp_operand (op3, SImode))
7711         op3 = force_reg (SImode, op3);
7712       scratch = gen_reg_rtx (SImode);
7713       emit_insn (gen_cstoresi_ltu_thumb1 (operands[0], operands[2], op3));
7714       break;
7716     case GTU:
7717       op3 = force_reg (SImode, operands[3]);
7718       scratch = gen_reg_rtx (SImode);
7719       emit_insn (gen_cstoresi_ltu_thumb1 (operands[0], op3, operands[2]));
7720       break;
7722     /* No good sequences for GT, LT.  */
7723     default:
7724       FAIL;
7725     }
7726   DONE;
7729 (define_expand "cstorehf4"
7730   [(set (match_operand:SI 0 "s_register_operand")
7731         (match_operator:SI 1 "expandable_comparison_operator"
7732          [(match_operand:HF 2 "s_register_operand")
7733           (match_operand:HF 3 "vfp_compare_operand")]))]
7734   "TARGET_VFP_FP16INST"
7735   {
7736     if (!arm_validize_comparison (&operands[1],
7737                                   &operands[2],
7738                                   &operands[3]))
7739        FAIL;
7741     emit_insn (gen_cstore_cc (operands[0], operands[1],
7742                               operands[2], operands[3]));
7743     DONE;
7744   }
7747 (define_expand "cstoresf4"
7748   [(set (match_operand:SI 0 "s_register_operand" "")
7749         (match_operator:SI 1 "expandable_comparison_operator"
7750          [(match_operand:SF 2 "s_register_operand" "")
7751           (match_operand:SF 3 "vfp_compare_operand" "")]))]
7752   "TARGET_32BIT && TARGET_HARD_FLOAT"
7753   "emit_insn (gen_cstore_cc (operands[0], operands[1],
7754                              operands[2], operands[3])); DONE;"
7757 (define_expand "cstoredf4"
7758   [(set (match_operand:SI 0 "s_register_operand" "")
7759         (match_operator:SI 1 "expandable_comparison_operator"
7760          [(match_operand:DF 2 "s_register_operand" "")
7761           (match_operand:DF 3 "vfp_compare_operand" "")]))]
7762   "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
7763   "emit_insn (gen_cstore_cc (operands[0], operands[1],
7764                              operands[2], operands[3])); DONE;"
7767 (define_expand "cstoredi4"
7768   [(set (match_operand:SI 0 "s_register_operand" "")
7769         (match_operator:SI 1 "expandable_comparison_operator"
7770          [(match_operand:DI 2 "s_register_operand" "")
7771           (match_operand:DI 3 "cmpdi_operand" "")]))]
7772   "TARGET_32BIT"
7773   "{
7774      if (!arm_validize_comparison (&operands[1],
7775                                    &operands[2],
7776                                    &operands[3]))
7777        FAIL;
7778      emit_insn (gen_cstore_cc (operands[0], operands[1], operands[2],
7779                                  operands[3]));
7780      DONE;
7781    }"
7785 ;; Conditional move insns
7787 (define_expand "movsicc"
7788   [(set (match_operand:SI 0 "s_register_operand" "")
7789         (if_then_else:SI (match_operand 1 "expandable_comparison_operator" "")
7790                          (match_operand:SI 2 "arm_not_operand" "")
7791                          (match_operand:SI 3 "arm_not_operand" "")))]
7792   "TARGET_32BIT"
7793   "
7794   {
7795     enum rtx_code code;
7796     rtx ccreg;
7798     if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0), 
7799                                   &XEXP (operands[1], 1)))
7800       FAIL;
7802     code = GET_CODE (operands[1]);
7803     ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
7804                                  XEXP (operands[1], 1), NULL_RTX);
7805     operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7806   }"
7809 (define_expand "movhfcc"
7810   [(set (match_operand:HF 0 "s_register_operand")
7811         (if_then_else:HF (match_operand 1 "arm_cond_move_operator")
7812                          (match_operand:HF 2 "s_register_operand")
7813                          (match_operand:HF 3 "s_register_operand")))]
7814   "TARGET_VFP_FP16INST"
7815   "
7816   {
7817     enum rtx_code code = GET_CODE (operands[1]);
7818     rtx ccreg;
7820     if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
7821                                   &XEXP (operands[1], 1)))
7822       FAIL;
7824     code = GET_CODE (operands[1]);
7825     ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
7826                                  XEXP (operands[1], 1), NULL_RTX);
7827     operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7828   }"
7831 (define_expand "movsfcc"
7832   [(set (match_operand:SF 0 "s_register_operand" "")
7833         (if_then_else:SF (match_operand 1 "arm_cond_move_operator" "")
7834                          (match_operand:SF 2 "s_register_operand" "")
7835                          (match_operand:SF 3 "s_register_operand" "")))]
7836   "TARGET_32BIT && TARGET_HARD_FLOAT"
7837   "
7838   {
7839     enum rtx_code code = GET_CODE (operands[1]);
7840     rtx ccreg;
7842     if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
7843                                   &XEXP (operands[1], 1)))
7844        FAIL;
7846     code = GET_CODE (operands[1]);
7847     ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
7848                                  XEXP (operands[1], 1), NULL_RTX);
7849     operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7850   }"
7853 (define_expand "movdfcc"
7854   [(set (match_operand:DF 0 "s_register_operand" "")
7855         (if_then_else:DF (match_operand 1 "arm_cond_move_operator" "")
7856                          (match_operand:DF 2 "s_register_operand" "")
7857                          (match_operand:DF 3 "s_register_operand" "")))]
7858   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
7859   "
7860   {
7861     enum rtx_code code = GET_CODE (operands[1]);
7862     rtx ccreg;
7864     if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0), 
7865                                   &XEXP (operands[1], 1)))
7866        FAIL;
7867     code = GET_CODE (operands[1]);
7868     ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
7869                                  XEXP (operands[1], 1), NULL_RTX);
7870     operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7871   }"
7874 (define_insn "*cmov<mode>"
7875     [(set (match_operand:SDF 0 "s_register_operand" "=<F_constraint>")
7876         (if_then_else:SDF (match_operator 1 "arm_vsel_comparison_operator"
7877                           [(match_operand 2 "cc_register" "") (const_int 0)])
7878                           (match_operand:SDF 3 "s_register_operand"
7879                                               "<F_constraint>")
7880                           (match_operand:SDF 4 "s_register_operand"
7881                                               "<F_constraint>")))]
7882   "TARGET_HARD_FLOAT && TARGET_FPU_ARMV8 <vfp_double_cond>"
7883   "*
7884   {
7885     enum arm_cond_code code = maybe_get_arm_condition_code (operands[1]);
7886     switch (code)
7887       {
7888       case ARM_GE:
7889       case ARM_GT:
7890       case ARM_EQ:
7891       case ARM_VS:
7892         return \"vsel%d1.<V_if_elem>\\t%<V_reg>0, %<V_reg>3, %<V_reg>4\";
7893       case ARM_LT:
7894       case ARM_LE:
7895       case ARM_NE:
7896       case ARM_VC:
7897         return \"vsel%D1.<V_if_elem>\\t%<V_reg>0, %<V_reg>4, %<V_reg>3\";
7898       default:
7899         gcc_unreachable ();
7900       }
7901     return \"\";
7902   }"
7903   [(set_attr "conds" "use")
7904    (set_attr "type" "fcsel")]
7907 (define_insn "*cmovhf"
7908     [(set (match_operand:HF 0 "s_register_operand" "=t")
7909         (if_then_else:HF (match_operator 1 "arm_vsel_comparison_operator"
7910                          [(match_operand 2 "cc_register" "") (const_int 0)])
7911                           (match_operand:HF 3 "s_register_operand" "t")
7912                           (match_operand:HF 4 "s_register_operand" "t")))]
7913   "TARGET_VFP_FP16INST"
7914   "*
7915   {
7916     enum arm_cond_code code = maybe_get_arm_condition_code (operands[1]);
7917     switch (code)
7918       {
7919       case ARM_GE:
7920       case ARM_GT:
7921       case ARM_EQ:
7922       case ARM_VS:
7923         return \"vsel%d1.f16\\t%0, %3, %4\";
7924       case ARM_LT:
7925       case ARM_LE:
7926       case ARM_NE:
7927       case ARM_VC:
7928         return \"vsel%D1.f16\\t%0, %4, %3\";
7929       default:
7930         gcc_unreachable ();
7931       }
7932     return \"\";
7933   }"
7934   [(set_attr "conds" "use")
7935    (set_attr "type" "fcsel")]
7938 (define_insn_and_split "*movsicc_insn"
7939   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r,r,r,r,r")
7940         (if_then_else:SI
7941          (match_operator 3 "arm_comparison_operator"
7942           [(match_operand 4 "cc_register" "") (const_int 0)])
7943          (match_operand:SI 1 "arm_not_operand" "0,0,rI,K,rI,rI,K,K")
7944          (match_operand:SI 2 "arm_not_operand" "rI,K,0,0,rI,K,rI,K")))]
7945   "TARGET_ARM"
7946   "@
7947    mov%D3\\t%0, %2
7948    mvn%D3\\t%0, #%B2
7949    mov%d3\\t%0, %1
7950    mvn%d3\\t%0, #%B1
7951    #
7952    #
7953    #
7954    #"
7955    ; alt4: mov%d3\\t%0, %1\;mov%D3\\t%0, %2
7956    ; alt5: mov%d3\\t%0, %1\;mvn%D3\\t%0, #%B2
7957    ; alt6: mvn%d3\\t%0, #%B1\;mov%D3\\t%0, %2
7958    ; alt7: mvn%d3\\t%0, #%B1\;mvn%D3\\t%0, #%B2"
7959   "&& reload_completed"
7960   [(const_int 0)]
7961   {
7962     enum rtx_code rev_code;
7963     machine_mode mode;
7964     rtx rev_cond;
7966     emit_insn (gen_rtx_COND_EXEC (VOIDmode,
7967                                   operands[3],
7968                                   gen_rtx_SET (operands[0], operands[1])));
7970     rev_code = GET_CODE (operands[3]);
7971     mode = GET_MODE (operands[4]);
7972     if (mode == CCFPmode || mode == CCFPEmode)
7973       rev_code = reverse_condition_maybe_unordered (rev_code);
7974     else
7975       rev_code = reverse_condition (rev_code);
7977     rev_cond = gen_rtx_fmt_ee (rev_code,
7978                                VOIDmode,
7979                                operands[4],
7980                                const0_rtx);
7981     emit_insn (gen_rtx_COND_EXEC (VOIDmode,
7982                                   rev_cond,
7983                                   gen_rtx_SET (operands[0], operands[2])));
7984     DONE;
7985   }
7986   [(set_attr "length" "4,4,4,4,8,8,8,8")
7987    (set_attr "conds" "use")
7988    (set_attr_alternative "type"
7989                          [(if_then_else (match_operand 2 "const_int_operand" "")
7990                                         (const_string "mov_imm")
7991                                         (const_string "mov_reg"))
7992                           (const_string "mvn_imm")
7993                           (if_then_else (match_operand 1 "const_int_operand" "")
7994                                         (const_string "mov_imm")
7995                                         (const_string "mov_reg"))
7996                           (const_string "mvn_imm")
7997                           (const_string "multiple")
7998                           (const_string "multiple")
7999                           (const_string "multiple")
8000                           (const_string "multiple")])]
8003 (define_insn "*movsfcc_soft_insn"
8004   [(set (match_operand:SF 0 "s_register_operand" "=r,r")
8005         (if_then_else:SF (match_operator 3 "arm_comparison_operator"
8006                           [(match_operand 4 "cc_register" "") (const_int 0)])
8007                          (match_operand:SF 1 "s_register_operand" "0,r")
8008                          (match_operand:SF 2 "s_register_operand" "r,0")))]
8009   "TARGET_ARM && TARGET_SOFT_FLOAT"
8010   "@
8011    mov%D3\\t%0, %2
8012    mov%d3\\t%0, %1"
8013   [(set_attr "conds" "use")
8014    (set_attr "type" "mov_reg")]
8018 ;; Jump and linkage insns
8020 (define_expand "jump"
8021   [(set (pc)
8022         (label_ref (match_operand 0 "" "")))]
8023   "TARGET_EITHER"
8024   ""
8027 (define_insn "*arm_jump"
8028   [(set (pc)
8029         (label_ref (match_operand 0 "" "")))]
8030   "TARGET_32BIT"
8031   "*
8032   {
8033     if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
8034       {
8035         arm_ccfsm_state += 2;
8036         return \"\";
8037       }
8038     return \"b%?\\t%l0\";
8039   }
8040   "
8041   [(set_attr "predicable" "yes")
8042    (set (attr "length")
8043         (if_then_else
8044            (and (match_test "TARGET_THUMB2")
8045                 (and (ge (minus (match_dup 0) (pc)) (const_int -2044))
8046                      (le (minus (match_dup 0) (pc)) (const_int 2048))))
8047            (const_int 2)
8048            (const_int 4)))
8049    (set_attr "type" "branch")]
8052 (define_expand "call"
8053   [(parallel [(call (match_operand 0 "memory_operand" "")
8054                     (match_operand 1 "general_operand" ""))
8055               (use (match_operand 2 "" ""))
8056               (clobber (reg:SI LR_REGNUM))])]
8057   "TARGET_EITHER"
8058   "
8059   {
8060     rtx callee, pat;
8061     tree addr = MEM_EXPR (operands[0]);
8062     
8063     /* In an untyped call, we can get NULL for operand 2.  */
8064     if (operands[2] == NULL_RTX)
8065       operands[2] = const0_rtx;
8066       
8067     /* Decide if we should generate indirect calls by loading the
8068        32-bit address of the callee into a register before performing the
8069        branch and link.  */
8070     callee = XEXP (operands[0], 0);
8071     if (GET_CODE (callee) == SYMBOL_REF
8072         ? arm_is_long_call_p (SYMBOL_REF_DECL (callee))
8073         : !REG_P (callee))
8074       XEXP (operands[0], 0) = force_reg (Pmode, callee);
8076     if (detect_cmse_nonsecure_call (addr))
8077       {
8078         pat = gen_nonsecure_call_internal (operands[0], operands[1],
8079                                            operands[2]);
8080         emit_call_insn (pat);
8081       }
8082     else
8083       {
8084         pat = gen_call_internal (operands[0], operands[1], operands[2]);
8085         arm_emit_call_insn (pat, XEXP (operands[0], 0), false);
8086       }
8087     DONE;
8088   }"
8091 (define_expand "call_internal"
8092   [(parallel [(call (match_operand 0 "memory_operand" "")
8093                     (match_operand 1 "general_operand" ""))
8094               (use (match_operand 2 "" ""))
8095               (clobber (reg:SI LR_REGNUM))])])
8097 (define_expand "nonsecure_call_internal"
8098   [(parallel [(call (unspec:SI [(match_operand 0 "memory_operand" "")]
8099                                UNSPEC_NONSECURE_MEM)
8100                     (match_operand 1 "general_operand" ""))
8101               (use (match_operand 2 "" ""))
8102               (clobber (reg:SI LR_REGNUM))
8103               (clobber (reg:SI 4))])]
8104   "use_cmse"
8105   "
8106   {
8107     rtx tmp;
8108     tmp = copy_to_suggested_reg (XEXP (operands[0], 0),
8109                                  gen_rtx_REG (SImode, 4),
8110                                  SImode);
8112     operands[0] = replace_equiv_address (operands[0], tmp);
8113   }")
8115 (define_insn "*call_reg_armv5"
8116   [(call (mem:SI (match_operand:SI 0 "s_register_operand" "r"))
8117          (match_operand 1 "" ""))
8118    (use (match_operand 2 "" ""))
8119    (clobber (reg:SI LR_REGNUM))]
8120   "TARGET_ARM && arm_arch5 && !SIBLING_CALL_P (insn)"
8121   "blx%?\\t%0"
8122   [(set_attr "type" "call")]
8125 (define_insn "*call_reg_arm"
8126   [(call (mem:SI (match_operand:SI 0 "s_register_operand" "r"))
8127          (match_operand 1 "" ""))
8128    (use (match_operand 2 "" ""))
8129    (clobber (reg:SI LR_REGNUM))]
8130   "TARGET_ARM && !arm_arch5 && !SIBLING_CALL_P (insn)"
8131   "*
8132   return output_call (operands);
8133   "
8134   ;; length is worst case, normally it is only two
8135   [(set_attr "length" "12")
8136    (set_attr "type" "call")]
8140 (define_expand "call_value"
8141   [(parallel [(set (match_operand       0 "" "")
8142                    (call (match_operand 1 "memory_operand" "")
8143                          (match_operand 2 "general_operand" "")))
8144               (use (match_operand 3 "" ""))
8145               (clobber (reg:SI LR_REGNUM))])]
8146   "TARGET_EITHER"
8147   "
8148   {
8149     rtx pat, callee;
8150     tree addr = MEM_EXPR (operands[1]);
8151     
8152     /* In an untyped call, we can get NULL for operand 2.  */
8153     if (operands[3] == 0)
8154       operands[3] = const0_rtx;
8155       
8156     /* Decide if we should generate indirect calls by loading the
8157        32-bit address of the callee into a register before performing the
8158        branch and link.  */
8159     callee = XEXP (operands[1], 0);
8160     if (GET_CODE (callee) == SYMBOL_REF
8161         ? arm_is_long_call_p (SYMBOL_REF_DECL (callee))
8162         : !REG_P (callee))
8163       XEXP (operands[1], 0) = force_reg (Pmode, callee);
8165     if (detect_cmse_nonsecure_call (addr))
8166       {
8167         pat = gen_nonsecure_call_value_internal (operands[0], operands[1],
8168                                                  operands[2], operands[3]);
8169         emit_call_insn (pat);
8170       }
8171     else
8172       {
8173         pat = gen_call_value_internal (operands[0], operands[1],
8174                                        operands[2], operands[3]);
8175         arm_emit_call_insn (pat, XEXP (operands[1], 0), false);
8176       }
8177     DONE;
8178   }"
8181 (define_expand "call_value_internal"
8182   [(parallel [(set (match_operand       0 "" "")
8183                    (call (match_operand 1 "memory_operand" "")
8184                          (match_operand 2 "general_operand" "")))
8185               (use (match_operand 3 "" ""))
8186               (clobber (reg:SI LR_REGNUM))])])
8188 (define_expand "nonsecure_call_value_internal"
8189   [(parallel [(set (match_operand       0 "" "")
8190                    (call (unspec:SI [(match_operand 1 "memory_operand" "")]
8191                                     UNSPEC_NONSECURE_MEM)
8192                          (match_operand 2 "general_operand" "")))
8193               (use (match_operand 3 "" ""))
8194               (clobber (reg:SI LR_REGNUM))
8195               (clobber (reg:SI 4))])]
8196   "use_cmse"
8197   "
8198   {
8199     rtx tmp;
8200     tmp = copy_to_suggested_reg (XEXP (operands[1], 0),
8201                                  gen_rtx_REG (SImode, 4),
8202                                  SImode);
8204     operands[1] = replace_equiv_address (operands[1], tmp);
8205   }")
8207 (define_insn "*call_value_reg_armv5"
8208   [(set (match_operand 0 "" "")
8209         (call (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
8210               (match_operand 2 "" "")))
8211    (use (match_operand 3 "" ""))
8212    (clobber (reg:SI LR_REGNUM))]
8213   "TARGET_ARM && arm_arch5 && !SIBLING_CALL_P (insn)"
8214   "blx%?\\t%1"
8215   [(set_attr "type" "call")]
8218 (define_insn "*call_value_reg_arm"
8219   [(set (match_operand 0 "" "")
8220         (call (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
8221               (match_operand 2 "" "")))
8222    (use (match_operand 3 "" ""))
8223    (clobber (reg:SI LR_REGNUM))]
8224   "TARGET_ARM && !arm_arch5 && !SIBLING_CALL_P (insn)"
8225   "*
8226   return output_call (&operands[1]);
8227   "
8228   [(set_attr "length" "12")
8229    (set_attr "type" "call")]
8232 ;; Allow calls to SYMBOL_REFs specially as they are not valid general addresses
8233 ;; The 'a' causes the operand to be treated as an address, i.e. no '#' output.
8235 (define_insn "*call_symbol"
8236   [(call (mem:SI (match_operand:SI 0 "" ""))
8237          (match_operand 1 "" ""))
8238    (use (match_operand 2 "" ""))
8239    (clobber (reg:SI LR_REGNUM))]
8240   "TARGET_32BIT
8241    && !SIBLING_CALL_P (insn)
8242    && (GET_CODE (operands[0]) == SYMBOL_REF)
8243    && !arm_is_long_call_p (SYMBOL_REF_DECL (operands[0]))"
8244   "*
8245   {
8246    rtx op = operands[0];
8248    /* Switch mode now when possible.  */
8249    if (SYMBOL_REF_DECL (op) && !TREE_PUBLIC (SYMBOL_REF_DECL (op))
8250         && arm_arch5 && arm_change_mode_p (SYMBOL_REF_DECL (op)))
8251       return NEED_PLT_RELOC ? \"blx%?\\t%a0(PLT)\" : \"blx%?\\t(%a0)\";
8253     return NEED_PLT_RELOC ? \"bl%?\\t%a0(PLT)\" : \"bl%?\\t%a0\";
8254   }"
8255   [(set_attr "type" "call")]
8258 (define_insn "*call_value_symbol"
8259   [(set (match_operand 0 "" "")
8260         (call (mem:SI (match_operand:SI 1 "" ""))
8261         (match_operand:SI 2 "" "")))
8262    (use (match_operand 3 "" ""))
8263    (clobber (reg:SI LR_REGNUM))]
8264   "TARGET_32BIT
8265    && !SIBLING_CALL_P (insn)
8266    && (GET_CODE (operands[1]) == SYMBOL_REF)
8267    && !arm_is_long_call_p (SYMBOL_REF_DECL (operands[1]))"
8268   "*
8269   {
8270    rtx op = operands[1];
8272    /* Switch mode now when possible.  */
8273    if (SYMBOL_REF_DECL (op) && !TREE_PUBLIC (SYMBOL_REF_DECL (op))
8274         && arm_arch5 && arm_change_mode_p (SYMBOL_REF_DECL (op)))
8275       return NEED_PLT_RELOC ? \"blx%?\\t%a1(PLT)\" : \"blx%?\\t(%a1)\";
8277     return NEED_PLT_RELOC ? \"bl%?\\t%a1(PLT)\" : \"bl%?\\t%a1\";
8278   }"
8279   [(set_attr "type" "call")]
8282 (define_expand "sibcall_internal"
8283   [(parallel [(call (match_operand 0 "memory_operand" "")
8284                     (match_operand 1 "general_operand" ""))
8285               (return)
8286               (use (match_operand 2 "" ""))])])
8288 ;; We may also be able to do sibcalls for Thumb, but it's much harder...
8289 (define_expand "sibcall"
8290   [(parallel [(call (match_operand 0 "memory_operand" "")
8291                     (match_operand 1 "general_operand" ""))
8292               (return)
8293               (use (match_operand 2 "" ""))])]
8294   "TARGET_32BIT"
8295   "
8296   {
8297     rtx pat;
8299     if ((!REG_P (XEXP (operands[0], 0))
8300          && GET_CODE (XEXP (operands[0], 0)) != SYMBOL_REF)
8301         || (GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
8302             && arm_is_long_call_p (SYMBOL_REF_DECL (XEXP (operands[0], 0)))))
8303      XEXP (operands[0], 0) = force_reg (SImode, XEXP (operands[0], 0));
8305     if (operands[2] == NULL_RTX)
8306       operands[2] = const0_rtx;
8308     pat = gen_sibcall_internal (operands[0], operands[1], operands[2]);
8309     arm_emit_call_insn (pat, operands[0], true);
8310     DONE;
8311   }"
8314 (define_expand "sibcall_value_internal"
8315   [(parallel [(set (match_operand 0 "" "")
8316                    (call (match_operand 1 "memory_operand" "")
8317                          (match_operand 2 "general_operand" "")))
8318               (return)
8319               (use (match_operand 3 "" ""))])])
8321 (define_expand "sibcall_value"
8322   [(parallel [(set (match_operand 0 "" "")
8323                    (call (match_operand 1 "memory_operand" "")
8324                          (match_operand 2 "general_operand" "")))
8325               (return)
8326               (use (match_operand 3 "" ""))])]
8327   "TARGET_32BIT"
8328   "
8329   {
8330     rtx pat;
8332     if ((!REG_P (XEXP (operands[1], 0))
8333          && GET_CODE (XEXP (operands[1], 0)) != SYMBOL_REF)
8334         || (GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
8335             && arm_is_long_call_p (SYMBOL_REF_DECL (XEXP (operands[1], 0)))))
8336      XEXP (operands[1], 0) = force_reg (SImode, XEXP (operands[1], 0));
8338     if (operands[3] == NULL_RTX)
8339       operands[3] = const0_rtx;
8341     pat = gen_sibcall_value_internal (operands[0], operands[1],
8342                                       operands[2], operands[3]);
8343     arm_emit_call_insn (pat, operands[1], true);
8344     DONE;
8345   }"
8348 (define_insn "*sibcall_insn"
8349  [(call (mem:SI (match_operand:SI 0 "call_insn_operand" "Cs, US"))
8350         (match_operand 1 "" ""))
8351   (return)
8352   (use (match_operand 2 "" ""))]
8353   "TARGET_32BIT && SIBLING_CALL_P (insn)"
8354   "*
8355   if (which_alternative == 1)
8356     return NEED_PLT_RELOC ? \"b%?\\t%a0(PLT)\" : \"b%?\\t%a0\";
8357   else
8358     {
8359       if (arm_arch5 || arm_arch4t)
8360         return \"bx%?\\t%0\\t%@ indirect register sibling call\";
8361       else
8362         return \"mov%?\\t%|pc, %0\\t%@ indirect register sibling call\";
8363     }
8364   "
8365   [(set_attr "type" "call")]
8368 (define_insn "*sibcall_value_insn"
8369  [(set (match_operand 0 "" "")
8370        (call (mem:SI (match_operand:SI 1 "call_insn_operand" "Cs,US"))
8371              (match_operand 2 "" "")))
8372   (return)
8373   (use (match_operand 3 "" ""))]
8374   "TARGET_32BIT && SIBLING_CALL_P (insn)"
8375   "*
8376   if (which_alternative == 1)
8377    return NEED_PLT_RELOC ? \"b%?\\t%a1(PLT)\" : \"b%?\\t%a1\";
8378   else
8379     {
8380       if (arm_arch5 || arm_arch4t)
8381         return \"bx%?\\t%1\";
8382       else
8383         return \"mov%?\\t%|pc, %1\\t@ indirect sibling call \";
8384     }
8385   "
8386   [(set_attr "type" "call")]
8389 (define_expand "<return_str>return"
8390   [(RETURNS)]
8391   "(TARGET_ARM || (TARGET_THUMB2
8392                    && ARM_FUNC_TYPE (arm_current_func_type ()) == ARM_FT_NORMAL
8393                    && !IS_STACKALIGN (arm_current_func_type ())))
8394     <return_cond_false>"
8395   "
8396   {
8397     if (TARGET_THUMB2)
8398       {
8399         thumb2_expand_return (<return_simple_p>);
8400         DONE;
8401       }
8402   }
8403   "
8406 ;; Often the return insn will be the same as loading from memory, so set attr
8407 (define_insn "*arm_return"
8408   [(return)]
8409   "TARGET_ARM && USE_RETURN_INSN (FALSE)"
8410   "*
8411   {
8412     if (arm_ccfsm_state == 2)
8413       {
8414         arm_ccfsm_state += 2;
8415         return \"\";
8416       }
8417     return output_return_instruction (const_true_rtx, true, false, false);
8418   }"
8419   [(set_attr "type" "load1")
8420    (set_attr "length" "12")
8421    (set_attr "predicable" "yes")]
8424 (define_insn "*cond_<return_str>return"
8425   [(set (pc)
8426         (if_then_else (match_operator 0 "arm_comparison_operator"
8427                        [(match_operand 1 "cc_register" "") (const_int 0)])
8428                       (RETURNS)
8429                       (pc)))]
8430   "TARGET_ARM  <return_cond_true>"
8431   "*
8432   {
8433     if (arm_ccfsm_state == 2)
8434       {
8435         arm_ccfsm_state += 2;
8436         return \"\";
8437       }
8438     return output_return_instruction (operands[0], true, false,
8439                                       <return_simple_p>);
8440   }"
8441   [(set_attr "conds" "use")
8442    (set_attr "length" "12")
8443    (set_attr "type" "load1")]
8446 (define_insn "*cond_<return_str>return_inverted"
8447   [(set (pc)
8448         (if_then_else (match_operator 0 "arm_comparison_operator"
8449                        [(match_operand 1 "cc_register" "") (const_int 0)])
8450                       (pc)
8451                       (RETURNS)))]
8452   "TARGET_ARM <return_cond_true>"
8453   "*
8454   {
8455     if (arm_ccfsm_state == 2)
8456       {
8457         arm_ccfsm_state += 2;
8458         return \"\";
8459       }
8460     return output_return_instruction (operands[0], true, true,
8461                                       <return_simple_p>);
8462   }"
8463   [(set_attr "conds" "use")
8464    (set_attr "length" "12")
8465    (set_attr "type" "load1")]
8468 (define_insn "*arm_simple_return"
8469   [(simple_return)]
8470   "TARGET_ARM"
8471   "*
8472   {
8473     if (arm_ccfsm_state == 2)
8474       {
8475         arm_ccfsm_state += 2;
8476         return \"\";
8477       }
8478     return output_return_instruction (const_true_rtx, true, false, true);
8479   }"
8480   [(set_attr "type" "branch")
8481    (set_attr "length" "4")
8482    (set_attr "predicable" "yes")]
8485 ;; Generate a sequence of instructions to determine if the processor is
8486 ;; in 26-bit or 32-bit mode, and return the appropriate return address
8487 ;; mask.
8489 (define_expand "return_addr_mask"
8490   [(set (match_dup 1)
8491       (compare:CC_NOOV (unspec [(const_int 0)] UNSPEC_CHECK_ARCH)
8492                        (const_int 0)))
8493    (set (match_operand:SI 0 "s_register_operand" "")
8494       (if_then_else:SI (eq (match_dup 1) (const_int 0))
8495                        (const_int -1)
8496                        (const_int 67108860)))] ; 0x03fffffc
8497   "TARGET_ARM"
8498   "
8499   operands[1] = gen_rtx_REG (CC_NOOVmode, CC_REGNUM);
8500   ")
8502 (define_insn "*check_arch2"
8503   [(set (match_operand:CC_NOOV 0 "cc_register" "")
8504       (compare:CC_NOOV (unspec [(const_int 0)] UNSPEC_CHECK_ARCH)
8505                        (const_int 0)))]
8506   "TARGET_ARM"
8507   "teq\\t%|r0, %|r0\;teq\\t%|pc, %|pc"
8508   [(set_attr "length" "8")
8509    (set_attr "conds" "set")
8510    (set_attr "type" "multiple")]
8513 ;; Call subroutine returning any type.
8515 (define_expand "untyped_call"
8516   [(parallel [(call (match_operand 0 "" "")
8517                     (const_int 0))
8518               (match_operand 1 "" "")
8519               (match_operand 2 "" "")])]
8520   "TARGET_EITHER"
8521   "
8522   {
8523     int i;
8524     rtx par = gen_rtx_PARALLEL (VOIDmode,
8525                                 rtvec_alloc (XVECLEN (operands[2], 0)));
8526     rtx addr = gen_reg_rtx (Pmode);
8527     rtx mem;
8528     int size = 0;
8530     emit_move_insn (addr, XEXP (operands[1], 0));
8531     mem = change_address (operands[1], BLKmode, addr);
8533     for (i = 0; i < XVECLEN (operands[2], 0); i++)
8534       {
8535         rtx src = SET_SRC (XVECEXP (operands[2], 0, i));
8537         /* Default code only uses r0 as a return value, but we could
8538            be using anything up to 4 registers.  */
8539         if (REGNO (src) == R0_REGNUM)
8540           src = gen_rtx_REG (TImode, R0_REGNUM);
8542         XVECEXP (par, 0, i) = gen_rtx_EXPR_LIST (VOIDmode, src,
8543                                                  GEN_INT (size));
8544         size += GET_MODE_SIZE (GET_MODE (src));
8545       }
8547     emit_call_insn (gen_call_value (par, operands[0], const0_rtx, NULL));
8549     size = 0;
8551     for (i = 0; i < XVECLEN (par, 0); i++)
8552       {
8553         HOST_WIDE_INT offset = 0;
8554         rtx reg = XEXP (XVECEXP (par, 0, i), 0);
8556         if (size != 0)
8557           emit_move_insn (addr, plus_constant (Pmode, addr, size));
8559         mem = change_address (mem, GET_MODE (reg), NULL);
8560         if (REGNO (reg) == R0_REGNUM)
8561           {
8562             /* On thumb we have to use a write-back instruction.  */
8563             emit_insn (arm_gen_store_multiple (arm_regs_in_sequence, 4, addr,
8564                        TARGET_THUMB ? TRUE : FALSE, mem, &offset));
8565             size = TARGET_ARM ? 16 : 0;
8566           }
8567         else
8568           {
8569             emit_move_insn (mem, reg);
8570             size = GET_MODE_SIZE (GET_MODE (reg));
8571           }
8572       }
8574     /* The optimizer does not know that the call sets the function value
8575        registers we stored in the result block.  We avoid problems by
8576        claiming that all hard registers are used and clobbered at this
8577        point.  */
8578     emit_insn (gen_blockage ());
8580     DONE;
8581   }"
8584 (define_expand "untyped_return"
8585   [(match_operand:BLK 0 "memory_operand" "")
8586    (match_operand 1 "" "")]
8587   "TARGET_EITHER"
8588   "
8589   {
8590     int i;
8591     rtx addr = gen_reg_rtx (Pmode);
8592     rtx mem;
8593     int size = 0;
8595     emit_move_insn (addr, XEXP (operands[0], 0));
8596     mem = change_address (operands[0], BLKmode, addr);
8598     for (i = 0; i < XVECLEN (operands[1], 0); i++)
8599       {
8600         HOST_WIDE_INT offset = 0;
8601         rtx reg = SET_DEST (XVECEXP (operands[1], 0, i));
8603         if (size != 0)
8604           emit_move_insn (addr, plus_constant (Pmode, addr, size));
8606         mem = change_address (mem, GET_MODE (reg), NULL);
8607         if (REGNO (reg) == R0_REGNUM)
8608           {
8609             /* On thumb we have to use a write-back instruction.  */
8610             emit_insn (arm_gen_load_multiple (arm_regs_in_sequence, 4, addr,
8611                        TARGET_THUMB ? TRUE : FALSE, mem, &offset));
8612             size = TARGET_ARM ? 16 : 0;
8613           }
8614         else
8615           {
8616             emit_move_insn (reg, mem);
8617             size = GET_MODE_SIZE (GET_MODE (reg));
8618           }
8619       }
8621     /* Emit USE insns before the return.  */
8622     for (i = 0; i < XVECLEN (operands[1], 0); i++)
8623       emit_use (SET_DEST (XVECEXP (operands[1], 0, i)));
8625     /* Construct the return.  */
8626     expand_naked_return ();
8628     DONE;
8629   }"
8632 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
8633 ;; all of memory.  This blocks insns from being moved across this point.
8635 (define_insn "blockage"
8636   [(unspec_volatile [(const_int 0)] VUNSPEC_BLOCKAGE)]
8637   "TARGET_EITHER"
8638   ""
8639   [(set_attr "length" "0")
8640    (set_attr "type" "block")]
8643 (define_insn "probe_stack"
8644   [(set (match_operand:SI 0 "memory_operand" "=m")
8645         (unspec:SI [(const_int 0)] UNSPEC_PROBE_STACK))]
8646   "TARGET_32BIT"
8647   "str%?\\tr0, %0"
8648   [(set_attr "type" "store1")
8649    (set_attr "predicable" "yes")]
8652 (define_insn "probe_stack_range"
8653   [(set (match_operand:SI 0 "register_operand" "=r")
8654         (unspec_volatile:SI [(match_operand:SI 1 "register_operand" "0")
8655                              (match_operand:SI 2 "register_operand" "r")]
8656                              VUNSPEC_PROBE_STACK_RANGE))]
8657   "TARGET_32BIT"
8659   return output_probe_stack_range (operands[0], operands[2]);
8661   [(set_attr "type" "multiple")
8662    (set_attr "conds" "clob")]
8665 (define_expand "casesi"
8666   [(match_operand:SI 0 "s_register_operand" "") ; index to jump on
8667    (match_operand:SI 1 "const_int_operand" "")  ; lower bound
8668    (match_operand:SI 2 "const_int_operand" "")  ; total range
8669    (match_operand:SI 3 "" "")                   ; table label
8670    (match_operand:SI 4 "" "")]                  ; Out of range label
8671   "(TARGET_32BIT || optimize_size || flag_pic) && !target_pure_code"
8672   "
8673   {
8674     enum insn_code code;
8675     if (operands[1] != const0_rtx)
8676       {
8677         rtx reg = gen_reg_rtx (SImode);
8679         emit_insn (gen_addsi3 (reg, operands[0],
8680                                gen_int_mode (-INTVAL (operands[1]),
8681                                              SImode)));
8682         operands[0] = reg;
8683       }
8685     if (TARGET_ARM)
8686       code = CODE_FOR_arm_casesi_internal;
8687     else if (TARGET_THUMB1)
8688       code = CODE_FOR_thumb1_casesi_internal_pic;
8689     else if (flag_pic)
8690       code = CODE_FOR_thumb2_casesi_internal_pic;
8691     else
8692       code = CODE_FOR_thumb2_casesi_internal;
8694     if (!insn_data[(int) code].operand[1].predicate(operands[2], SImode))
8695       operands[2] = force_reg (SImode, operands[2]);
8697     emit_jump_insn (GEN_FCN ((int) code) (operands[0], operands[2],
8698                                           operands[3], operands[4]));
8699     DONE;
8700   }"
8703 ;; The USE in this pattern is needed to tell flow analysis that this is
8704 ;; a CASESI insn.  It has no other purpose.
8705 (define_insn "arm_casesi_internal"
8706   [(parallel [(set (pc)
8707                (if_then_else
8708                 (leu (match_operand:SI 0 "s_register_operand" "r")
8709                      (match_operand:SI 1 "arm_rhs_operand" "rI"))
8710                 (mem:SI (plus:SI (mult:SI (match_dup 0) (const_int 4))
8711                                  (label_ref (match_operand 2 "" ""))))
8712                 (label_ref (match_operand 3 "" ""))))
8713               (clobber (reg:CC CC_REGNUM))
8714               (use (label_ref (match_dup 2)))])]
8715   "TARGET_ARM"
8716   "*
8717     if (flag_pic)
8718       return \"cmp\\t%0, %1\;addls\\t%|pc, %|pc, %0, asl #2\;b\\t%l3\";
8719     return   \"cmp\\t%0, %1\;ldrls\\t%|pc, [%|pc, %0, asl #2]\;b\\t%l3\";
8720   "
8721   [(set_attr "conds" "clob")
8722    (set_attr "length" "12")
8723    (set_attr "type" "multiple")]
8726 (define_expand "indirect_jump"
8727   [(set (pc)
8728         (match_operand:SI 0 "s_register_operand" ""))]
8729   "TARGET_EITHER"
8730   "
8731   /* Thumb-2 doesn't have mov pc, reg.  Explicitly set the low bit of the
8732      address and use bx.  */
8733   if (TARGET_THUMB2)
8734     {
8735       rtx tmp;
8736       tmp = gen_reg_rtx (SImode);
8737       emit_insn (gen_iorsi3 (tmp, operands[0], GEN_INT(1)));
8738       operands[0] = tmp;
8739     }
8740   "
8743 ;; NB Never uses BX.
8744 (define_insn "*arm_indirect_jump"
8745   [(set (pc)
8746         (match_operand:SI 0 "s_register_operand" "r"))]
8747   "TARGET_ARM"
8748   "mov%?\\t%|pc, %0\\t%@ indirect register jump"
8749   [(set_attr "predicable" "yes")
8750    (set_attr "type" "branch")]
8753 (define_insn "*load_indirect_jump"
8754   [(set (pc)
8755         (match_operand:SI 0 "memory_operand" "m"))]
8756   "TARGET_ARM"
8757   "ldr%?\\t%|pc, %0\\t%@ indirect memory jump"
8758   [(set_attr "type" "load1")
8759    (set_attr "pool_range" "4096")
8760    (set_attr "neg_pool_range" "4084")
8761    (set_attr "predicable" "yes")]
8765 ;; Misc insns
8767 (define_insn "nop"
8768   [(const_int 0)]
8769   "TARGET_EITHER"
8770   "nop"
8771   [(set (attr "length")
8772         (if_then_else (eq_attr "is_thumb" "yes")
8773                       (const_int 2)
8774                       (const_int 4)))
8775    (set_attr "type" "mov_reg")]
8778 (define_insn "trap"
8779   [(trap_if (const_int 1) (const_int 0))]
8780   ""
8781   "*
8782   if (TARGET_ARM)
8783     return \".inst\\t0xe7f000f0\";
8784   else
8785     return \".inst\\t0xdeff\";
8786   "
8787   [(set (attr "length")
8788         (if_then_else (eq_attr "is_thumb" "yes")
8789                       (const_int 2)
8790                       (const_int 4)))
8791    (set_attr "type" "trap")
8792    (set_attr "conds" "unconditional")]
8796 ;; Patterns to allow combination of arithmetic, cond code and shifts
8798 (define_insn "*<arith_shift_insn>_multsi"
8799   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8800         (SHIFTABLE_OPS:SI
8801          (mult:SI (match_operand:SI 2 "s_register_operand" "r,r")
8802                   (match_operand:SI 3 "power_of_two_operand" ""))
8803          (match_operand:SI 1 "s_register_operand" "rk,<t2_binop0>")))]
8804   "TARGET_32BIT"
8805   "<arith_shift_insn>%?\\t%0, %1, %2, lsl %b3"
8806   [(set_attr "predicable" "yes")
8807    (set_attr "predicable_short_it" "no")
8808    (set_attr "shift" "2")
8809    (set_attr "arch" "a,t2")
8810    (set_attr "type" "alu_shift_imm")])
8812 (define_insn "*<arith_shift_insn>_shiftsi"
8813   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
8814         (SHIFTABLE_OPS:SI
8815          (match_operator:SI 2 "shift_nomul_operator"
8816           [(match_operand:SI 3 "s_register_operand" "r,r,r")
8817            (match_operand:SI 4 "shift_amount_operand" "M,M,r")])
8818          (match_operand:SI 1 "s_register_operand" "rk,<t2_binop0>,rk")))]
8819   "TARGET_32BIT && GET_CODE (operands[2]) != MULT"
8820   "<arith_shift_insn>%?\\t%0, %1, %3%S2"
8821   [(set_attr "predicable" "yes")
8822    (set_attr "predicable_short_it" "no")
8823    (set_attr "shift" "3")
8824    (set_attr "arch" "a,t2,a")
8825    (set_attr "type" "alu_shift_imm,alu_shift_imm,alu_shift_reg")])
8827 (define_split
8828   [(set (match_operand:SI 0 "s_register_operand" "")
8829         (match_operator:SI 1 "shiftable_operator"
8830          [(match_operator:SI 2 "shiftable_operator"
8831            [(match_operator:SI 3 "shift_operator"
8832              [(match_operand:SI 4 "s_register_operand" "")
8833               (match_operand:SI 5 "reg_or_int_operand" "")])
8834             (match_operand:SI 6 "s_register_operand" "")])
8835           (match_operand:SI 7 "arm_rhs_operand" "")]))
8836    (clobber (match_operand:SI 8 "s_register_operand" ""))]
8837   "TARGET_32BIT"
8838   [(set (match_dup 8)
8839         (match_op_dup 2 [(match_op_dup 3 [(match_dup 4) (match_dup 5)])
8840                          (match_dup 6)]))
8841    (set (match_dup 0)
8842         (match_op_dup 1 [(match_dup 8) (match_dup 7)]))]
8843   "")
8845 (define_insn "*arith_shiftsi_compare0"
8846   [(set (reg:CC_NOOV CC_REGNUM)
8847         (compare:CC_NOOV
8848          (match_operator:SI 1 "shiftable_operator"
8849           [(match_operator:SI 3 "shift_operator"
8850             [(match_operand:SI 4 "s_register_operand" "r,r")
8851              (match_operand:SI 5 "shift_amount_operand" "M,r")])
8852            (match_operand:SI 2 "s_register_operand" "r,r")])
8853          (const_int 0)))
8854    (set (match_operand:SI 0 "s_register_operand" "=r,r")
8855         (match_op_dup 1 [(match_op_dup 3 [(match_dup 4) (match_dup 5)])
8856                          (match_dup 2)]))]
8857   "TARGET_32BIT"
8858   "%i1s%?\\t%0, %2, %4%S3"
8859   [(set_attr "conds" "set")
8860    (set_attr "shift" "4")
8861    (set_attr "arch" "32,a")
8862    (set_attr "type" "alus_shift_imm,alus_shift_reg")])
8864 (define_insn "*arith_shiftsi_compare0_scratch"
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    (clobber (match_scratch:SI 0 "=r,r"))]
8874   "TARGET_32BIT"
8875   "%i1s%?\\t%0, %2, %4%S3"
8876   [(set_attr "conds" "set")
8877    (set_attr "shift" "4")
8878    (set_attr "arch" "32,a")
8879    (set_attr "type" "alus_shift_imm,alus_shift_reg")])
8881 (define_insn "*sub_shiftsi"
8882   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8883         (minus:SI (match_operand:SI 1 "s_register_operand" "r,r")
8884                   (match_operator:SI 2 "shift_operator"
8885                    [(match_operand:SI 3 "s_register_operand" "r,r")
8886                     (match_operand:SI 4 "shift_amount_operand" "M,r")])))]
8887   "TARGET_32BIT"
8888   "sub%?\\t%0, %1, %3%S2"
8889   [(set_attr "predicable" "yes")
8890    (set_attr "shift" "3")
8891    (set_attr "arch" "32,a")
8892    (set_attr "type" "alus_shift_imm,alus_shift_reg")])
8894 (define_insn "*sub_shiftsi_compare0"
8895   [(set (reg:CC_NOOV CC_REGNUM)
8896         (compare:CC_NOOV
8897          (minus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
8898                    (match_operator:SI 2 "shift_operator"
8899                     [(match_operand:SI 3 "s_register_operand" "r,r,r")
8900                      (match_operand:SI 4 "shift_amount_operand" "M,r,M")]))
8901          (const_int 0)))
8902    (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
8903         (minus:SI (match_dup 1)
8904                   (match_op_dup 2 [(match_dup 3) (match_dup 4)])))]
8905   "TARGET_32BIT"
8906   "subs%?\\t%0, %1, %3%S2"
8907   [(set_attr "conds" "set")
8908    (set_attr "shift" "3")
8909    (set_attr "arch" "32,a,a")
8910    (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
8912 (define_insn "*sub_shiftsi_compare0_scratch"
8913   [(set (reg:CC_NOOV CC_REGNUM)
8914         (compare:CC_NOOV
8915          (minus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
8916                    (match_operator:SI 2 "shift_operator"
8917                     [(match_operand:SI 3 "s_register_operand" "r,r,r")
8918                      (match_operand:SI 4 "shift_amount_operand" "M,r,M")]))
8919          (const_int 0)))
8920    (clobber (match_scratch:SI 0 "=r,r,r"))]
8921   "TARGET_32BIT"
8922   "subs%?\\t%0, %1, %3%S2"
8923   [(set_attr "conds" "set")
8924    (set_attr "shift" "3")
8925    (set_attr "arch" "32,a,a")
8926    (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
8929 (define_insn_and_split "*and_scc"
8930   [(set (match_operand:SI 0 "s_register_operand" "=r")
8931         (and:SI (match_operator:SI 1 "arm_comparison_operator"
8932                  [(match_operand 2 "cc_register" "") (const_int 0)])
8933                 (match_operand:SI 3 "s_register_operand" "r")))]
8934   "TARGET_ARM"
8935   "#"   ; "mov%D1\\t%0, #0\;and%d1\\t%0, %3, #1"
8936   "&& reload_completed"
8937   [(cond_exec (match_dup 5) (set (match_dup 0) (const_int 0)))
8938    (cond_exec (match_dup 4) (set (match_dup 0)
8939                                  (and:SI (match_dup 3) (const_int 1))))]
8940   {
8941     machine_mode mode = GET_MODE (operands[2]);
8942     enum rtx_code rc = GET_CODE (operands[1]);
8944     /* Note that operands[4] is the same as operands[1],
8945        but with VOIDmode as the result. */
8946     operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
8947     if (mode == CCFPmode || mode == CCFPEmode)
8948       rc = reverse_condition_maybe_unordered (rc);
8949     else
8950       rc = reverse_condition (rc);
8951     operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
8952   }
8953   [(set_attr "conds" "use")
8954    (set_attr "type" "multiple")
8955    (set_attr "length" "8")]
8958 (define_insn_and_split "*ior_scc"
8959   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8960         (ior:SI (match_operator:SI 1 "arm_comparison_operator"
8961                  [(match_operand 2 "cc_register" "") (const_int 0)])
8962                 (match_operand:SI 3 "s_register_operand" "0,?r")))]
8963   "TARGET_ARM"
8964   "@
8965    orr%d1\\t%0, %3, #1
8966    #"
8967   "&& reload_completed
8968    && REGNO (operands [0]) != REGNO (operands[3])"
8969   ;; && which_alternative == 1
8970   ; mov%D1\\t%0, %3\;orr%d1\\t%0, %3, #1
8971   [(cond_exec (match_dup 5) (set (match_dup 0) (match_dup 3)))
8972    (cond_exec (match_dup 4) (set (match_dup 0)
8973                                  (ior:SI (match_dup 3) (const_int 1))))]
8974   {
8975     machine_mode mode = GET_MODE (operands[2]);
8976     enum rtx_code rc = GET_CODE (operands[1]);
8978     /* Note that operands[4] is the same as operands[1],
8979        but with VOIDmode as the result. */
8980     operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
8981     if (mode == CCFPmode || mode == CCFPEmode)
8982       rc = reverse_condition_maybe_unordered (rc);
8983     else
8984       rc = reverse_condition (rc);
8985     operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
8986   }
8987   [(set_attr "conds" "use")
8988    (set_attr "length" "4,8")
8989    (set_attr "type" "logic_imm,multiple")]
8992 ; A series of splitters for the compare_scc pattern below.  Note that
8993 ; order is important.
8994 (define_split
8995   [(set (match_operand:SI 0 "s_register_operand" "")
8996         (lt:SI (match_operand:SI 1 "s_register_operand" "")
8997                (const_int 0)))
8998    (clobber (reg:CC CC_REGNUM))]
8999   "TARGET_32BIT && reload_completed"
9000   [(set (match_dup 0) (lshiftrt:SI (match_dup 1) (const_int 31)))])
9002 (define_split
9003   [(set (match_operand:SI 0 "s_register_operand" "")
9004         (ge:SI (match_operand:SI 1 "s_register_operand" "")
9005                (const_int 0)))
9006    (clobber (reg:CC CC_REGNUM))]
9007   "TARGET_32BIT && reload_completed"
9008   [(set (match_dup 0) (not:SI (match_dup 1)))
9009    (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 31)))])
9011 (define_split
9012   [(set (match_operand:SI 0 "s_register_operand" "")
9013         (eq:SI (match_operand:SI 1 "s_register_operand" "")
9014                (const_int 0)))
9015    (clobber (reg:CC CC_REGNUM))]
9016   "arm_arch5 && TARGET_32BIT"
9017   [(set (match_dup 0) (clz:SI (match_dup 1)))
9018    (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
9021 (define_split
9022   [(set (match_operand:SI 0 "s_register_operand" "")
9023         (eq:SI (match_operand:SI 1 "s_register_operand" "")
9024                (const_int 0)))
9025    (clobber (reg:CC CC_REGNUM))]
9026   "TARGET_32BIT && reload_completed"
9027   [(parallel
9028     [(set (reg:CC CC_REGNUM)
9029           (compare:CC (const_int 1) (match_dup 1)))
9030      (set (match_dup 0)
9031           (minus:SI (const_int 1) (match_dup 1)))])
9032    (cond_exec (ltu:CC (reg:CC CC_REGNUM) (const_int 0))
9033               (set (match_dup 0) (const_int 0)))])
9035 (define_split
9036   [(set (match_operand:SI 0 "s_register_operand" "")
9037         (ne:SI (match_operand:SI 1 "s_register_operand" "")
9038                (match_operand:SI 2 "const_int_operand" "")))
9039    (clobber (reg:CC CC_REGNUM))]
9040   "TARGET_32BIT && reload_completed"
9041   [(parallel
9042     [(set (reg:CC CC_REGNUM)
9043           (compare:CC (match_dup 1) (match_dup 2)))
9044      (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 3)))])
9045    (cond_exec (ne:CC (reg:CC CC_REGNUM) (const_int 0))
9046               (set (match_dup 0) (const_int 1)))]
9048   operands[3] = GEN_INT (-INTVAL (operands[2]));
9051 (define_split
9052   [(set (match_operand:SI 0 "s_register_operand" "")
9053         (ne:SI (match_operand:SI 1 "s_register_operand" "")
9054                (match_operand:SI 2 "arm_add_operand" "")))
9055    (clobber (reg:CC CC_REGNUM))]
9056   "TARGET_32BIT && reload_completed"
9057   [(parallel
9058     [(set (reg:CC_NOOV CC_REGNUM)
9059           (compare:CC_NOOV (minus:SI (match_dup 1) (match_dup 2))
9060                            (const_int 0)))
9061      (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
9062    (cond_exec (ne:CC_NOOV (reg:CC_NOOV CC_REGNUM) (const_int 0))
9063               (set (match_dup 0) (const_int 1)))])
9065 (define_insn_and_split "*compare_scc"
9066   [(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts")
9067         (match_operator:SI 1 "arm_comparison_operator"
9068          [(match_operand:SI 2 "s_register_operand" "r,r")
9069           (match_operand:SI 3 "arm_add_operand" "rI,L")]))
9070    (clobber (reg:CC CC_REGNUM))]
9071   "TARGET_32BIT"
9072   "#"
9073   "&& reload_completed"
9074   [(set (reg:CC CC_REGNUM) (compare:CC (match_dup 2) (match_dup 3)))
9075    (cond_exec (match_dup 4) (set (match_dup 0) (const_int 0)))
9076    (cond_exec (match_dup 5) (set (match_dup 0) (const_int 1)))]
9078   rtx tmp1;
9079   machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
9080                                            operands[2], operands[3]);
9081   enum rtx_code rc = GET_CODE (operands[1]);
9083   tmp1 = gen_rtx_REG (mode, CC_REGNUM);
9085   operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, tmp1, const0_rtx);
9086   if (mode == CCFPmode || mode == CCFPEmode)
9087     rc = reverse_condition_maybe_unordered (rc);
9088   else
9089     rc = reverse_condition (rc);
9090   operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, tmp1, const0_rtx);
9092   [(set_attr "type" "multiple")]
9095 ;; Attempt to improve the sequence generated by the compare_scc splitters
9096 ;; not to use conditional execution.
9098 ;; Rd = (eq (reg1) (const_int0))  // ARMv5
9099 ;;      clz Rd, reg1
9100 ;;      lsr Rd, Rd, #5
9101 (define_peephole2
9102   [(set (reg:CC CC_REGNUM)
9103         (compare:CC (match_operand:SI 1 "register_operand" "")
9104                     (const_int 0)))
9105    (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
9106               (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
9107    (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
9108               (set (match_dup 0) (const_int 1)))]
9109   "arm_arch5 && TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
9110   [(set (match_dup 0) (clz:SI (match_dup 1)))
9111    (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
9114 ;; Rd = (eq (reg1) (const_int0))  // !ARMv5
9115 ;;      negs Rd, reg1
9116 ;;      adc  Rd, Rd, reg1
9117 (define_peephole2
9118   [(set (reg:CC CC_REGNUM)
9119         (compare:CC (match_operand:SI 1 "register_operand" "")
9120                     (const_int 0)))
9121    (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
9122               (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
9123    (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
9124               (set (match_dup 0) (const_int 1)))
9125    (match_scratch:SI 2 "r")]
9126   "TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
9127   [(parallel
9128     [(set (reg:CC CC_REGNUM)
9129           (compare:CC (const_int 0) (match_dup 1)))
9130      (set (match_dup 2) (minus:SI (const_int 0) (match_dup 1)))])
9131    (set (match_dup 0)
9132         (plus:SI (plus:SI (match_dup 1) (match_dup 2))
9133                  (geu:SI (reg:CC CC_REGNUM) (const_int 0))))]
9136 ;; Rd = (eq (reg1) (reg2/imm))  // ARMv5 and optimising for speed.
9137 ;;      sub  Rd, Reg1, reg2
9138 ;;      clz  Rd, Rd
9139 ;;      lsr  Rd, Rd, #5
9140 (define_peephole2
9141   [(set (reg:CC CC_REGNUM)
9142         (compare:CC (match_operand:SI 1 "register_operand" "")
9143                     (match_operand:SI 2 "arm_rhs_operand" "")))
9144    (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
9145               (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
9146    (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
9147               (set (match_dup 0) (const_int 1)))]
9148   "arm_arch5 && TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)
9149   && !(TARGET_THUMB2 && optimize_insn_for_size_p ())"
9150   [(set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))
9151    (set (match_dup 0) (clz:SI (match_dup 0)))
9152    (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
9156 ;; Rd = (eq (reg1) (reg2))      // ! ARMv5 or optimising for size.
9157 ;;      sub  T1, Reg1, reg2
9158 ;;      negs Rd, T1
9159 ;;      adc  Rd, Rd, T1
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    (match_scratch:SI 3 "r")]
9169   "TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
9170   [(set (match_dup 3) (match_dup 4))
9171    (parallel
9172     [(set (reg:CC CC_REGNUM)
9173           (compare:CC (const_int 0) (match_dup 3)))
9174      (set (match_dup 0) (minus:SI (const_int 0) (match_dup 3)))])
9175    (set (match_dup 0)
9176         (plus:SI (plus:SI (match_dup 0) (match_dup 3))
9177                  (geu:SI (reg:CC CC_REGNUM) (const_int 0))))]
9178   "
9179   if (CONST_INT_P (operands[2]))
9180     operands[4] = plus_constant (SImode, operands[1], -INTVAL (operands[2]));
9181   else
9182     operands[4] = gen_rtx_MINUS (SImode, operands[1], operands[2]);
9183   ")
9185 (define_insn "*cond_move"
9186   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9187         (if_then_else:SI (match_operator 3 "equality_operator"
9188                           [(match_operator 4 "arm_comparison_operator"
9189                             [(match_operand 5 "cc_register" "") (const_int 0)])
9190                            (const_int 0)])
9191                          (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
9192                          (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))]
9193   "TARGET_ARM"
9194   "*
9195     if (GET_CODE (operands[3]) == NE)
9196       {
9197         if (which_alternative != 1)
9198           output_asm_insn (\"mov%D4\\t%0, %2\", operands);
9199         if (which_alternative != 0)
9200           output_asm_insn (\"mov%d4\\t%0, %1\", operands);
9201         return \"\";
9202       }
9203     if (which_alternative != 0)
9204       output_asm_insn (\"mov%D4\\t%0, %1\", operands);
9205     if (which_alternative != 1)
9206       output_asm_insn (\"mov%d4\\t%0, %2\", operands);
9207     return \"\";
9208   "
9209   [(set_attr "conds" "use")
9210    (set_attr_alternative "type"
9211                          [(if_then_else (match_operand 2 "const_int_operand" "")
9212                                         (const_string "mov_imm")
9213                                         (const_string "mov_reg"))
9214                           (if_then_else (match_operand 1 "const_int_operand" "")
9215                                         (const_string "mov_imm")
9216                                         (const_string "mov_reg"))
9217                           (const_string "multiple")])
9218    (set_attr "length" "4,4,8")]
9221 (define_insn "*cond_arith"
9222   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9223         (match_operator:SI 5 "shiftable_operator" 
9224          [(match_operator:SI 4 "arm_comparison_operator"
9225            [(match_operand:SI 2 "s_register_operand" "r,r")
9226             (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
9227           (match_operand:SI 1 "s_register_operand" "0,?r")]))
9228    (clobber (reg:CC CC_REGNUM))]
9229   "TARGET_ARM"
9230   "*
9231     if (GET_CODE (operands[4]) == LT && operands[3] == const0_rtx)
9232       return \"%i5\\t%0, %1, %2, lsr #31\";
9234     output_asm_insn (\"cmp\\t%2, %3\", operands);
9235     if (GET_CODE (operands[5]) == AND)
9236       output_asm_insn (\"mov%D4\\t%0, #0\", operands);
9237     else if (GET_CODE (operands[5]) == MINUS)
9238       output_asm_insn (\"rsb%D4\\t%0, %1, #0\", operands);
9239     else if (which_alternative != 0)
9240       output_asm_insn (\"mov%D4\\t%0, %1\", operands);
9241     return \"%i5%d4\\t%0, %1, #1\";
9242   "
9243   [(set_attr "conds" "clob")
9244    (set_attr "length" "12")
9245    (set_attr "type" "multiple")]
9248 (define_insn "*cond_sub"
9249   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9250         (minus:SI (match_operand:SI 1 "s_register_operand" "0,?r")
9251                   (match_operator:SI 4 "arm_comparison_operator"
9252                    [(match_operand:SI 2 "s_register_operand" "r,r")
9253                     (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
9254    (clobber (reg:CC CC_REGNUM))]
9255   "TARGET_ARM"
9256   "*
9257     output_asm_insn (\"cmp\\t%2, %3\", operands);
9258     if (which_alternative != 0)
9259       output_asm_insn (\"mov%D4\\t%0, %1\", operands);
9260     return \"sub%d4\\t%0, %1, #1\";
9261   "
9262   [(set_attr "conds" "clob")
9263    (set_attr "length" "8,12")
9264    (set_attr "type" "multiple")]
9267 (define_insn "*cmp_ite0"
9268   [(set (match_operand 6 "dominant_cc_register" "")
9269         (compare
9270          (if_then_else:SI
9271           (match_operator 4 "arm_comparison_operator"
9272            [(match_operand:SI 0 "s_register_operand"
9273                 "l,l,l,r,r,r,r,r,r")
9274             (match_operand:SI 1 "arm_add_operand"
9275                 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
9276           (match_operator:SI 5 "arm_comparison_operator"
9277            [(match_operand:SI 2 "s_register_operand"
9278                 "l,r,r,l,l,r,r,r,r")
9279             (match_operand:SI 3 "arm_add_operand"
9280                 "lPy,rI,L,lPy,lPy,rI,rI,L,L")])
9281           (const_int 0))
9282          (const_int 0)))]
9283   "TARGET_32BIT"
9284   "*
9285   {
9286     static const char * const cmp1[NUM_OF_COND_CMP][2] =
9287     {
9288       {\"cmp%d5\\t%0, %1\",
9289        \"cmp%d4\\t%2, %3\"},
9290       {\"cmn%d5\\t%0, #%n1\",
9291        \"cmp%d4\\t%2, %3\"},
9292       {\"cmp%d5\\t%0, %1\",
9293        \"cmn%d4\\t%2, #%n3\"},
9294       {\"cmn%d5\\t%0, #%n1\",
9295        \"cmn%d4\\t%2, #%n3\"}
9296     };
9297     static const char * const cmp2[NUM_OF_COND_CMP][2] =
9298     {
9299       {\"cmp\\t%2, %3\",
9300        \"cmp\\t%0, %1\"},
9301       {\"cmp\\t%2, %3\",
9302        \"cmn\\t%0, #%n1\"},
9303       {\"cmn\\t%2, #%n3\",
9304        \"cmp\\t%0, %1\"},
9305       {\"cmn\\t%2, #%n3\",
9306        \"cmn\\t%0, #%n1\"}
9307     };
9308     static const char * const ite[2] =
9309     {
9310       \"it\\t%d5\",
9311       \"it\\t%d4\"
9312     };
9313     static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
9314                                    CMP_CMP, CMN_CMP, CMP_CMP,
9315                                    CMN_CMP, CMP_CMN, CMN_CMN};
9316     int swap =
9317       comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
9319     output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
9320     if (TARGET_THUMB2) {
9321       output_asm_insn (ite[swap], operands);
9322     }
9323     output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
9324     return \"\";
9325   }"
9326   [(set_attr "conds" "set")
9327    (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
9328    (set_attr "type" "multiple")
9329    (set_attr_alternative "length"
9330       [(const_int 6)
9331        (const_int 8)
9332        (const_int 8)
9333        (const_int 8)
9334        (const_int 8)
9335        (if_then_else (eq_attr "is_thumb" "no")
9336            (const_int 8)
9337            (const_int 10))
9338        (if_then_else (eq_attr "is_thumb" "no")
9339            (const_int 8)
9340            (const_int 10))
9341        (if_then_else (eq_attr "is_thumb" "no")
9342            (const_int 8)
9343            (const_int 10))
9344        (if_then_else (eq_attr "is_thumb" "no")
9345            (const_int 8)
9346            (const_int 10))])]
9349 (define_insn "*cmp_ite1"
9350   [(set (match_operand 6 "dominant_cc_register" "")
9351         (compare
9352          (if_then_else:SI
9353           (match_operator 4 "arm_comparison_operator"
9354            [(match_operand:SI 0 "s_register_operand"
9355                 "l,l,l,r,r,r,r,r,r")
9356             (match_operand:SI 1 "arm_add_operand"
9357                 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
9358           (match_operator:SI 5 "arm_comparison_operator"
9359            [(match_operand:SI 2 "s_register_operand"
9360                 "l,r,r,l,l,r,r,r,r")
9361             (match_operand:SI 3 "arm_add_operand"
9362                 "lPy,rI,L,lPy,lPy,rI,rI,L,L")])
9363           (const_int 1))
9364          (const_int 0)))]
9365   "TARGET_32BIT"
9366   "*
9367   {
9368     static const char * const cmp1[NUM_OF_COND_CMP][2] =
9369     {
9370       {\"cmp\\t%0, %1\",
9371        \"cmp\\t%2, %3\"},
9372       {\"cmn\\t%0, #%n1\",
9373        \"cmp\\t%2, %3\"},
9374       {\"cmp\\t%0, %1\",
9375        \"cmn\\t%2, #%n3\"},
9376       {\"cmn\\t%0, #%n1\",
9377        \"cmn\\t%2, #%n3\"}
9378     };
9379     static const char * const cmp2[NUM_OF_COND_CMP][2] =
9380     {
9381       {\"cmp%d4\\t%2, %3\",
9382        \"cmp%D5\\t%0, %1\"},
9383       {\"cmp%d4\\t%2, %3\",
9384        \"cmn%D5\\t%0, #%n1\"},
9385       {\"cmn%d4\\t%2, #%n3\",
9386        \"cmp%D5\\t%0, %1\"},
9387       {\"cmn%d4\\t%2, #%n3\",
9388        \"cmn%D5\\t%0, #%n1\"}
9389     };
9390     static const char * const ite[2] =
9391     {
9392       \"it\\t%d4\",
9393       \"it\\t%D5\"
9394     };
9395     static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
9396                                    CMP_CMP, CMN_CMP, CMP_CMP,
9397                                    CMN_CMP, CMP_CMN, CMN_CMN};
9398     int swap =
9399       comparison_dominates_p (GET_CODE (operands[5]),
9400                               reverse_condition (GET_CODE (operands[4])));
9402     output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
9403     if (TARGET_THUMB2) {
9404       output_asm_insn (ite[swap], operands);
9405     }
9406     output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
9407     return \"\";
9408   }"
9409   [(set_attr "conds" "set")
9410    (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
9411    (set_attr_alternative "length"
9412       [(const_int 6)
9413        (const_int 8)
9414        (const_int 8)
9415        (const_int 8)
9416        (const_int 8)
9417        (if_then_else (eq_attr "is_thumb" "no")
9418            (const_int 8)
9419            (const_int 10))
9420        (if_then_else (eq_attr "is_thumb" "no")
9421            (const_int 8)
9422            (const_int 10))
9423        (if_then_else (eq_attr "is_thumb" "no")
9424            (const_int 8)
9425            (const_int 10))
9426        (if_then_else (eq_attr "is_thumb" "no")
9427            (const_int 8)
9428            (const_int 10))])
9429    (set_attr "type" "multiple")]
9432 (define_insn "*cmp_and"
9433   [(set (match_operand 6 "dominant_cc_register" "")
9434         (compare
9435          (and:SI
9436           (match_operator 4 "arm_comparison_operator"
9437            [(match_operand:SI 0 "s_register_operand" 
9438                 "l,l,l,r,r,r,r,r,r")
9439             (match_operand:SI 1 "arm_add_operand" 
9440                 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
9441           (match_operator:SI 5 "arm_comparison_operator"
9442            [(match_operand:SI 2 "s_register_operand" 
9443                 "l,r,r,l,l,r,r,r,r")
9444             (match_operand:SI 3 "arm_add_operand" 
9445                 "lPy,rI,L,lPy,lPy,rI,rI,L,L")]))
9446          (const_int 0)))]
9447   "TARGET_32BIT"
9448   "*
9449   {
9450     static const char *const cmp1[NUM_OF_COND_CMP][2] =
9451     {
9452       {\"cmp%d5\\t%0, %1\",
9453        \"cmp%d4\\t%2, %3\"},
9454       {\"cmn%d5\\t%0, #%n1\",
9455        \"cmp%d4\\t%2, %3\"},
9456       {\"cmp%d5\\t%0, %1\",
9457        \"cmn%d4\\t%2, #%n3\"},
9458       {\"cmn%d5\\t%0, #%n1\",
9459        \"cmn%d4\\t%2, #%n3\"}
9460     };
9461     static const char *const cmp2[NUM_OF_COND_CMP][2] =
9462     {
9463       {\"cmp\\t%2, %3\",
9464        \"cmp\\t%0, %1\"},
9465       {\"cmp\\t%2, %3\",
9466        \"cmn\\t%0, #%n1\"},
9467       {\"cmn\\t%2, #%n3\",
9468        \"cmp\\t%0, %1\"},
9469       {\"cmn\\t%2, #%n3\",
9470        \"cmn\\t%0, #%n1\"}
9471     };
9472     static const char *const ite[2] =
9473     {
9474       \"it\\t%d5\",
9475       \"it\\t%d4\"
9476     };
9477     static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
9478                                    CMP_CMP, CMN_CMP, CMP_CMP,
9479                                    CMN_CMP, CMP_CMN, CMN_CMN};
9480     int swap =
9481       comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
9483     output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
9484     if (TARGET_THUMB2) {
9485       output_asm_insn (ite[swap], operands);
9486     }
9487     output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
9488     return \"\";
9489   }"
9490   [(set_attr "conds" "set")
9491    (set_attr "predicable" "no")
9492    (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
9493    (set_attr_alternative "length"
9494       [(const_int 6)
9495        (const_int 8)
9496        (const_int 8)
9497        (const_int 8)
9498        (const_int 8)
9499        (if_then_else (eq_attr "is_thumb" "no")
9500            (const_int 8)
9501            (const_int 10))
9502        (if_then_else (eq_attr "is_thumb" "no")
9503            (const_int 8)
9504            (const_int 10))
9505        (if_then_else (eq_attr "is_thumb" "no")
9506            (const_int 8)
9507            (const_int 10))
9508        (if_then_else (eq_attr "is_thumb" "no")
9509            (const_int 8)
9510            (const_int 10))])
9511    (set_attr "type" "multiple")]
9514 (define_insn "*cmp_ior"
9515   [(set (match_operand 6 "dominant_cc_register" "")
9516         (compare
9517          (ior:SI
9518           (match_operator 4 "arm_comparison_operator"
9519            [(match_operand:SI 0 "s_register_operand"
9520                 "l,l,l,r,r,r,r,r,r")
9521             (match_operand:SI 1 "arm_add_operand"
9522                 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
9523           (match_operator:SI 5 "arm_comparison_operator"
9524            [(match_operand:SI 2 "s_register_operand"
9525                 "l,r,r,l,l,r,r,r,r")
9526             (match_operand:SI 3 "arm_add_operand"
9527                 "lPy,rI,L,lPy,lPy,rI,rI,L,L")]))
9528          (const_int 0)))]
9529   "TARGET_32BIT"
9530   "*
9531   {
9532     static const char *const cmp1[NUM_OF_COND_CMP][2] =
9533     {
9534       {\"cmp\\t%0, %1\",
9535        \"cmp\\t%2, %3\"},
9536       {\"cmn\\t%0, #%n1\",
9537        \"cmp\\t%2, %3\"},
9538       {\"cmp\\t%0, %1\",
9539        \"cmn\\t%2, #%n3\"},
9540       {\"cmn\\t%0, #%n1\",
9541        \"cmn\\t%2, #%n3\"}
9542     };
9543     static const char *const cmp2[NUM_OF_COND_CMP][2] =
9544     {
9545       {\"cmp%D4\\t%2, %3\",
9546        \"cmp%D5\\t%0, %1\"},
9547       {\"cmp%D4\\t%2, %3\",
9548        \"cmn%D5\\t%0, #%n1\"},
9549       {\"cmn%D4\\t%2, #%n3\",
9550        \"cmp%D5\\t%0, %1\"},
9551       {\"cmn%D4\\t%2, #%n3\",
9552        \"cmn%D5\\t%0, #%n1\"}
9553     };
9554     static const char *const ite[2] =
9555     {
9556       \"it\\t%D4\",
9557       \"it\\t%D5\"
9558     };
9559     static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
9560                                    CMP_CMP, CMN_CMP, CMP_CMP,
9561                                    CMN_CMP, CMP_CMN, CMN_CMN};
9562     int swap =
9563       comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
9565     output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
9566     if (TARGET_THUMB2) {
9567       output_asm_insn (ite[swap], operands);
9568     }
9569     output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
9570     return \"\";
9571   }
9572   "
9573   [(set_attr "conds" "set")
9574    (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
9575    (set_attr_alternative "length"
9576       [(const_int 6)
9577        (const_int 8)
9578        (const_int 8)
9579        (const_int 8)
9580        (const_int 8)
9581        (if_then_else (eq_attr "is_thumb" "no")
9582            (const_int 8)
9583            (const_int 10))
9584        (if_then_else (eq_attr "is_thumb" "no")
9585            (const_int 8)
9586            (const_int 10))
9587        (if_then_else (eq_attr "is_thumb" "no")
9588            (const_int 8)
9589            (const_int 10))
9590        (if_then_else (eq_attr "is_thumb" "no")
9591            (const_int 8)
9592            (const_int 10))])
9593    (set_attr "type" "multiple")]
9596 (define_insn_and_split "*ior_scc_scc"
9597   [(set (match_operand:SI 0 "s_register_operand" "=Ts")
9598         (ior:SI (match_operator:SI 3 "arm_comparison_operator"
9599                  [(match_operand:SI 1 "s_register_operand" "r")
9600                   (match_operand:SI 2 "arm_add_operand" "rIL")])
9601                 (match_operator:SI 6 "arm_comparison_operator"
9602                  [(match_operand:SI 4 "s_register_operand" "r")
9603                   (match_operand:SI 5 "arm_add_operand" "rIL")])))
9604    (clobber (reg:CC CC_REGNUM))]
9605   "TARGET_32BIT
9606    && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_OR_Y)
9607        != CCmode)"
9608   "#"
9609   "TARGET_32BIT && reload_completed"
9610   [(set (match_dup 7)
9611         (compare
9612          (ior:SI
9613           (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9614           (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9615          (const_int 0)))
9616    (set (match_dup 0) (ne:SI (match_dup 7) (const_int 0)))]
9617   "operands[7]
9618      = gen_rtx_REG (arm_select_dominance_cc_mode (operands[3], operands[6],
9619                                                   DOM_CC_X_OR_Y),
9620                     CC_REGNUM);"
9621   [(set_attr "conds" "clob")
9622    (set_attr "length" "16")
9623    (set_attr "type" "multiple")]
9626 ; If the above pattern is followed by a CMP insn, then the compare is 
9627 ; redundant, since we can rework the conditional instruction that follows.
9628 (define_insn_and_split "*ior_scc_scc_cmp"
9629   [(set (match_operand 0 "dominant_cc_register" "")
9630         (compare (ior:SI (match_operator:SI 3 "arm_comparison_operator"
9631                           [(match_operand:SI 1 "s_register_operand" "r")
9632                            (match_operand:SI 2 "arm_add_operand" "rIL")])
9633                          (match_operator:SI 6 "arm_comparison_operator"
9634                           [(match_operand:SI 4 "s_register_operand" "r")
9635                            (match_operand:SI 5 "arm_add_operand" "rIL")]))
9636                  (const_int 0)))
9637    (set (match_operand:SI 7 "s_register_operand" "=Ts")
9638         (ior:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9639                 (match_op_dup 6 [(match_dup 4) (match_dup 5)])))]
9640   "TARGET_32BIT"
9641   "#"
9642   "TARGET_32BIT && reload_completed"
9643   [(set (match_dup 0)
9644         (compare
9645          (ior:SI
9646           (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9647           (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9648          (const_int 0)))
9649    (set (match_dup 7) (ne:SI (match_dup 0) (const_int 0)))]
9650   ""
9651   [(set_attr "conds" "set")
9652    (set_attr "length" "16")
9653    (set_attr "type" "multiple")]
9656 (define_insn_and_split "*and_scc_scc"
9657   [(set (match_operand:SI 0 "s_register_operand" "=Ts")
9658         (and:SI (match_operator:SI 3 "arm_comparison_operator"
9659                  [(match_operand:SI 1 "s_register_operand" "r")
9660                   (match_operand:SI 2 "arm_add_operand" "rIL")])
9661                 (match_operator:SI 6 "arm_comparison_operator"
9662                  [(match_operand:SI 4 "s_register_operand" "r")
9663                   (match_operand:SI 5 "arm_add_operand" "rIL")])))
9664    (clobber (reg:CC CC_REGNUM))]
9665   "TARGET_32BIT
9666    && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
9667        != CCmode)"
9668   "#"
9669   "TARGET_32BIT && reload_completed
9670    && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
9671        != CCmode)"
9672   [(set (match_dup 7)
9673         (compare
9674          (and:SI
9675           (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9676           (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9677          (const_int 0)))
9678    (set (match_dup 0) (ne:SI (match_dup 7) (const_int 0)))]
9679   "operands[7]
9680      = gen_rtx_REG (arm_select_dominance_cc_mode (operands[3], operands[6],
9681                                                   DOM_CC_X_AND_Y),
9682                     CC_REGNUM);"
9683   [(set_attr "conds" "clob")
9684    (set_attr "length" "16")
9685    (set_attr "type" "multiple")]
9688 ; If the above pattern is followed by a CMP insn, then the compare is 
9689 ; redundant, since we can rework the conditional instruction that follows.
9690 (define_insn_and_split "*and_scc_scc_cmp"
9691   [(set (match_operand 0 "dominant_cc_register" "")
9692         (compare (and:SI (match_operator:SI 3 "arm_comparison_operator"
9693                           [(match_operand:SI 1 "s_register_operand" "r")
9694                            (match_operand:SI 2 "arm_add_operand" "rIL")])
9695                          (match_operator:SI 6 "arm_comparison_operator"
9696                           [(match_operand:SI 4 "s_register_operand" "r")
9697                            (match_operand:SI 5 "arm_add_operand" "rIL")]))
9698                  (const_int 0)))
9699    (set (match_operand:SI 7 "s_register_operand" "=Ts")
9700         (and:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9701                 (match_op_dup 6 [(match_dup 4) (match_dup 5)])))]
9702   "TARGET_32BIT"
9703   "#"
9704   "TARGET_32BIT && reload_completed"
9705   [(set (match_dup 0)
9706         (compare
9707          (and:SI
9708           (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9709           (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9710          (const_int 0)))
9711    (set (match_dup 7) (ne:SI (match_dup 0) (const_int 0)))]
9712   ""
9713   [(set_attr "conds" "set")
9714    (set_attr "length" "16")
9715    (set_attr "type" "multiple")]
9718 ;; If there is no dominance in the comparison, then we can still save an
9719 ;; instruction in the AND case, since we can know that the second compare
9720 ;; need only zero the value if false (if true, then the value is already
9721 ;; correct).
9722 (define_insn_and_split "*and_scc_scc_nodom"
9723   [(set (match_operand:SI 0 "s_register_operand" "=&Ts,&Ts,&Ts")
9724         (and:SI (match_operator:SI 3 "arm_comparison_operator"
9725                  [(match_operand:SI 1 "s_register_operand" "r,r,0")
9726                   (match_operand:SI 2 "arm_add_operand" "rIL,0,rIL")])
9727                 (match_operator:SI 6 "arm_comparison_operator"
9728                  [(match_operand:SI 4 "s_register_operand" "r,r,r")
9729                   (match_operand:SI 5 "arm_add_operand" "rIL,rIL,rIL")])))
9730    (clobber (reg:CC CC_REGNUM))]
9731   "TARGET_32BIT
9732    && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
9733        == CCmode)"
9734   "#"
9735   "TARGET_32BIT && reload_completed"
9736   [(parallel [(set (match_dup 0)
9737                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
9738               (clobber (reg:CC CC_REGNUM))])
9739    (set (match_dup 7) (match_op_dup 8 [(match_dup 4) (match_dup 5)]))
9740    (set (match_dup 0)
9741         (if_then_else:SI (match_op_dup 6 [(match_dup 7) (const_int 0)])
9742                          (match_dup 0)
9743                          (const_int 0)))]
9744   "operands[7] = gen_rtx_REG (SELECT_CC_MODE (GET_CODE (operands[6]),
9745                                               operands[4], operands[5]),
9746                               CC_REGNUM);
9747    operands[8] = gen_rtx_COMPARE (GET_MODE (operands[7]), operands[4],
9748                                   operands[5]);"
9749   [(set_attr "conds" "clob")
9750    (set_attr "length" "20")
9751    (set_attr "type" "multiple")]
9754 (define_split
9755   [(set (reg:CC_NOOV CC_REGNUM)
9756         (compare:CC_NOOV (ior:SI
9757                           (and:SI (match_operand:SI 0 "s_register_operand" "")
9758                                   (const_int 1))
9759                           (match_operator:SI 1 "arm_comparison_operator"
9760                            [(match_operand:SI 2 "s_register_operand" "")
9761                             (match_operand:SI 3 "arm_add_operand" "")]))
9762                          (const_int 0)))
9763    (clobber (match_operand:SI 4 "s_register_operand" ""))]
9764   "TARGET_ARM"
9765   [(set (match_dup 4)
9766         (ior:SI (match_op_dup 1 [(match_dup 2) (match_dup 3)])
9767                 (match_dup 0)))
9768    (set (reg:CC_NOOV CC_REGNUM)
9769         (compare:CC_NOOV (and:SI (match_dup 4) (const_int 1))
9770                          (const_int 0)))]
9771   "")
9773 (define_split
9774   [(set (reg:CC_NOOV CC_REGNUM)
9775         (compare:CC_NOOV (ior:SI
9776                           (match_operator:SI 1 "arm_comparison_operator"
9777                            [(match_operand:SI 2 "s_register_operand" "")
9778                             (match_operand:SI 3 "arm_add_operand" "")])
9779                           (and:SI (match_operand:SI 0 "s_register_operand" "")
9780                                   (const_int 1)))
9781                          (const_int 0)))
9782    (clobber (match_operand:SI 4 "s_register_operand" ""))]
9783   "TARGET_ARM"
9784   [(set (match_dup 4)
9785         (ior:SI (match_op_dup 1 [(match_dup 2) (match_dup 3)])
9786                 (match_dup 0)))
9787    (set (reg:CC_NOOV CC_REGNUM)
9788         (compare:CC_NOOV (and:SI (match_dup 4) (const_int 1))
9789                          (const_int 0)))]
9790   "")
9791 ;; ??? The conditional patterns above need checking for Thumb-2 usefulness
9793 (define_insn_and_split "*negscc"
9794   [(set (match_operand:SI 0 "s_register_operand" "=r")
9795         (neg:SI (match_operator 3 "arm_comparison_operator"
9796                  [(match_operand:SI 1 "s_register_operand" "r")
9797                   (match_operand:SI 2 "arm_rhs_operand" "rI")])))
9798    (clobber (reg:CC CC_REGNUM))]
9799   "TARGET_ARM"
9800   "#"
9801   "&& reload_completed"
9802   [(const_int 0)]
9803   {
9804     rtx cc_reg = gen_rtx_REG (CCmode, CC_REGNUM);
9806     if (GET_CODE (operands[3]) == LT && operands[2] == const0_rtx)
9807        {
9808          /* Emit mov\\t%0, %1, asr #31 */
9809          emit_insn (gen_rtx_SET (operands[0],
9810                                  gen_rtx_ASHIFTRT (SImode,
9811                                                    operands[1],
9812                                                    GEN_INT (31))));
9813          DONE;
9814        }
9815      else if (GET_CODE (operands[3]) == NE)
9816        {
9817         /* Emit subs\\t%0, %1, %2\;mvnne\\t%0, #0 */
9818         if (CONST_INT_P (operands[2]))
9819           emit_insn (gen_cmpsi2_addneg (operands[0], operands[1], operands[2],
9820                                         GEN_INT (- INTVAL (operands[2]))));
9821         else
9822           emit_insn (gen_subsi3_compare (operands[0], operands[1], operands[2]));
9824         emit_insn (gen_rtx_COND_EXEC (VOIDmode,
9825                                       gen_rtx_NE (SImode,
9826                                                   cc_reg,
9827                                                   const0_rtx),
9828                                       gen_rtx_SET (operands[0],
9829                                                    GEN_INT (~0))));
9830         DONE;
9831       }
9832     else
9833       {
9834         /* Emit: cmp\\t%1, %2\;mov%D3\\t%0, #0\;mvn%d3\\t%0, #0 */
9835         emit_insn (gen_rtx_SET (cc_reg,
9836                                 gen_rtx_COMPARE (CCmode, operands[1], operands[2])));
9837         enum rtx_code rc = GET_CODE (operands[3]);
9839         rc = reverse_condition (rc);
9840         emit_insn (gen_rtx_COND_EXEC (VOIDmode,
9841                                       gen_rtx_fmt_ee (rc,
9842                                                       VOIDmode,
9843                                                       cc_reg,
9844                                                       const0_rtx),
9845                                       gen_rtx_SET (operands[0], const0_rtx)));
9846         rc = GET_CODE (operands[3]);
9847         emit_insn (gen_rtx_COND_EXEC (VOIDmode,
9848                                       gen_rtx_fmt_ee (rc,
9849                                                       VOIDmode,
9850                                                       cc_reg,
9851                                                       const0_rtx),
9852                                       gen_rtx_SET (operands[0],
9853                                                    GEN_INT (~0))));
9854         DONE;
9855       }
9856      FAIL;
9857   }
9858   [(set_attr "conds" "clob")
9859    (set_attr "length" "12")
9860    (set_attr "type" "multiple")]
9863 (define_insn_and_split "movcond_addsi"
9864   [(set (match_operand:SI 0 "s_register_operand" "=r,l,r")
9865         (if_then_else:SI
9866          (match_operator 5 "comparison_operator"
9867           [(plus:SI (match_operand:SI 3 "s_register_operand" "r,r,r")
9868                     (match_operand:SI 4 "arm_add_operand" "rIL,rIL,rIL"))
9869             (const_int 0)])
9870          (match_operand:SI 1 "arm_rhs_operand" "rI,rPy,r")
9871          (match_operand:SI 2 "arm_rhs_operand" "rI,rPy,r")))
9872    (clobber (reg:CC CC_REGNUM))]
9873    "TARGET_32BIT"
9874    "#"
9875    "&& reload_completed"
9876   [(set (reg:CC_NOOV CC_REGNUM)
9877         (compare:CC_NOOV
9878          (plus:SI (match_dup 3)
9879                   (match_dup 4))
9880          (const_int 0)))
9881    (set (match_dup 0) (match_dup 1))
9882    (cond_exec (match_dup 6)
9883               (set (match_dup 0) (match_dup 2)))]
9884   "
9885   {
9886     machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[5]),
9887                                              operands[3], operands[4]);
9888     enum rtx_code rc = GET_CODE (operands[5]);
9889     operands[6] = gen_rtx_REG (mode, CC_REGNUM);
9890     gcc_assert (!(mode == CCFPmode || mode == CCFPEmode));
9891     if (!REG_P (operands[2]) || REGNO (operands[2]) != REGNO (operands[0]))
9892       rc = reverse_condition (rc);
9893     else
9894       std::swap (operands[1], operands[2]);
9896     operands[6] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
9897   }
9898   "
9899   [(set_attr "conds" "clob")
9900    (set_attr "enabled_for_depr_it" "no,yes,yes")
9901    (set_attr "type" "multiple")]
9904 (define_insn "movcond"
9905   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9906         (if_then_else:SI
9907          (match_operator 5 "arm_comparison_operator"
9908           [(match_operand:SI 3 "s_register_operand" "r,r,r")
9909            (match_operand:SI 4 "arm_add_operand" "rIL,rIL,rIL")])
9910          (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
9911          (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
9912    (clobber (reg:CC CC_REGNUM))]
9913   "TARGET_ARM"
9914   "*
9915   if (GET_CODE (operands[5]) == LT
9916       && (operands[4] == const0_rtx))
9917     {
9918       if (which_alternative != 1 && REG_P (operands[1]))
9919         {
9920           if (operands[2] == const0_rtx)
9921             return \"and\\t%0, %1, %3, asr #31\";
9922           return \"ands\\t%0, %1, %3, asr #32\;movcc\\t%0, %2\";
9923         }
9924       else if (which_alternative != 0 && REG_P (operands[2]))
9925         {
9926           if (operands[1] == const0_rtx)
9927             return \"bic\\t%0, %2, %3, asr #31\";
9928           return \"bics\\t%0, %2, %3, asr #32\;movcs\\t%0, %1\";
9929         }
9930       /* The only case that falls through to here is when both ops 1 & 2
9931          are constants.  */
9932     }
9934   if (GET_CODE (operands[5]) == GE
9935       && (operands[4] == const0_rtx))
9936     {
9937       if (which_alternative != 1 && REG_P (operands[1]))
9938         {
9939           if (operands[2] == const0_rtx)
9940             return \"bic\\t%0, %1, %3, asr #31\";
9941           return \"bics\\t%0, %1, %3, asr #32\;movcs\\t%0, %2\";
9942         }
9943       else if (which_alternative != 0 && REG_P (operands[2]))
9944         {
9945           if (operands[1] == const0_rtx)
9946             return \"and\\t%0, %2, %3, asr #31\";
9947           return \"ands\\t%0, %2, %3, asr #32\;movcc\\t%0, %1\";
9948         }
9949       /* The only case that falls through to here is when both ops 1 & 2
9950          are constants.  */
9951     }
9952   if (CONST_INT_P (operands[4])
9953       && !const_ok_for_arm (INTVAL (operands[4])))
9954     output_asm_insn (\"cmn\\t%3, #%n4\", operands);
9955   else
9956     output_asm_insn (\"cmp\\t%3, %4\", operands);
9957   if (which_alternative != 0)
9958     output_asm_insn (\"mov%d5\\t%0, %1\", operands);
9959   if (which_alternative != 1)
9960     output_asm_insn (\"mov%D5\\t%0, %2\", operands);
9961   return \"\";
9962   "
9963   [(set_attr "conds" "clob")
9964    (set_attr "length" "8,8,12")
9965    (set_attr "type" "multiple")]
9968 ;; ??? The patterns below need checking for Thumb-2 usefulness.
9970 (define_insn "*ifcompare_plus_move"
9971   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9972         (if_then_else:SI (match_operator 6 "arm_comparison_operator"
9973                           [(match_operand:SI 4 "s_register_operand" "r,r")
9974                            (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
9975                          (plus:SI
9976                           (match_operand:SI 2 "s_register_operand" "r,r")
9977                           (match_operand:SI 3 "arm_add_operand" "rIL,rIL"))
9978                          (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))
9979    (clobber (reg:CC CC_REGNUM))]
9980   "TARGET_ARM"
9981   "#"
9982   [(set_attr "conds" "clob")
9983    (set_attr "length" "8,12")
9984    (set_attr "type" "multiple")]
9987 (define_insn "*if_plus_move"
9988   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
9989         (if_then_else:SI
9990          (match_operator 4 "arm_comparison_operator"
9991           [(match_operand 5 "cc_register" "") (const_int 0)])
9992          (plus:SI
9993           (match_operand:SI 2 "s_register_operand" "r,r,r,r")
9994           (match_operand:SI 3 "arm_add_operand" "rI,L,rI,L"))
9995          (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")))]
9996   "TARGET_ARM"
9997   "@
9998    add%d4\\t%0, %2, %3
9999    sub%d4\\t%0, %2, #%n3
10000    add%d4\\t%0, %2, %3\;mov%D4\\t%0, %1
10001    sub%d4\\t%0, %2, #%n3\;mov%D4\\t%0, %1"
10002   [(set_attr "conds" "use")
10003    (set_attr "length" "4,4,8,8")
10004    (set_attr_alternative "type"
10005                          [(if_then_else (match_operand 3 "const_int_operand" "")
10006                                         (const_string "alu_imm" )
10007                                         (const_string "alu_sreg"))
10008                           (const_string "alu_imm")
10009                           (const_string "multiple")
10010                           (const_string "multiple")])]
10013 (define_insn "*ifcompare_move_plus"
10014   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10015         (if_then_else:SI (match_operator 6 "arm_comparison_operator"
10016                           [(match_operand:SI 4 "s_register_operand" "r,r")
10017                            (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
10018                          (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
10019                          (plus:SI
10020                           (match_operand:SI 2 "s_register_operand" "r,r")
10021                           (match_operand:SI 3 "arm_add_operand" "rIL,rIL"))))
10022    (clobber (reg:CC CC_REGNUM))]
10023   "TARGET_ARM"
10024   "#"
10025   [(set_attr "conds" "clob")
10026    (set_attr "length" "8,12")
10027    (set_attr "type" "multiple")]
10030 (define_insn "*if_move_plus"
10031   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
10032         (if_then_else:SI
10033          (match_operator 4 "arm_comparison_operator"
10034           [(match_operand 5 "cc_register" "") (const_int 0)])
10035          (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")
10036          (plus:SI
10037           (match_operand:SI 2 "s_register_operand" "r,r,r,r")
10038           (match_operand:SI 3 "arm_add_operand" "rI,L,rI,L"))))]
10039   "TARGET_ARM"
10040   "@
10041    add%D4\\t%0, %2, %3
10042    sub%D4\\t%0, %2, #%n3
10043    add%D4\\t%0, %2, %3\;mov%d4\\t%0, %1
10044    sub%D4\\t%0, %2, #%n3\;mov%d4\\t%0, %1"
10045   [(set_attr "conds" "use")
10046    (set_attr "length" "4,4,8,8")
10047    (set_attr_alternative "type"
10048                          [(if_then_else (match_operand 3 "const_int_operand" "")
10049                                         (const_string "alu_imm" )
10050                                         (const_string "alu_sreg"))
10051                           (const_string "alu_imm")
10052                           (const_string "multiple")
10053                           (const_string "multiple")])]
10056 (define_insn "*ifcompare_arith_arith"
10057   [(set (match_operand:SI 0 "s_register_operand" "=r")
10058         (if_then_else:SI (match_operator 9 "arm_comparison_operator"
10059                           [(match_operand:SI 5 "s_register_operand" "r")
10060                            (match_operand:SI 6 "arm_add_operand" "rIL")])
10061                          (match_operator:SI 8 "shiftable_operator"
10062                           [(match_operand:SI 1 "s_register_operand" "r")
10063                            (match_operand:SI 2 "arm_rhs_operand" "rI")])
10064                          (match_operator:SI 7 "shiftable_operator"
10065                           [(match_operand:SI 3 "s_register_operand" "r")
10066                            (match_operand:SI 4 "arm_rhs_operand" "rI")])))
10067    (clobber (reg:CC CC_REGNUM))]
10068   "TARGET_ARM"
10069   "#"
10070   [(set_attr "conds" "clob")
10071    (set_attr "length" "12")
10072    (set_attr "type" "multiple")]
10075 (define_insn "*if_arith_arith"
10076   [(set (match_operand:SI 0 "s_register_operand" "=r")
10077         (if_then_else:SI (match_operator 5 "arm_comparison_operator"
10078                           [(match_operand 8 "cc_register" "") (const_int 0)])
10079                          (match_operator:SI 6 "shiftable_operator"
10080                           [(match_operand:SI 1 "s_register_operand" "r")
10081                            (match_operand:SI 2 "arm_rhs_operand" "rI")])
10082                          (match_operator:SI 7 "shiftable_operator"
10083                           [(match_operand:SI 3 "s_register_operand" "r")
10084                            (match_operand:SI 4 "arm_rhs_operand" "rI")])))]
10085   "TARGET_ARM"
10086   "%I6%d5\\t%0, %1, %2\;%I7%D5\\t%0, %3, %4"
10087   [(set_attr "conds" "use")
10088    (set_attr "length" "8")
10089    (set_attr "type" "multiple")]
10092 (define_insn "*ifcompare_arith_move"
10093   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10094         (if_then_else:SI (match_operator 6 "arm_comparison_operator"
10095                           [(match_operand:SI 2 "s_register_operand" "r,r")
10096                            (match_operand:SI 3 "arm_add_operand" "rIL,rIL")])
10097                          (match_operator:SI 7 "shiftable_operator"
10098                           [(match_operand:SI 4 "s_register_operand" "r,r")
10099                            (match_operand:SI 5 "arm_rhs_operand" "rI,rI")])
10100                          (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))
10101    (clobber (reg:CC CC_REGNUM))]
10102   "TARGET_ARM"
10103   "*
10104   /* If we have an operation where (op x 0) is the identity operation and
10105      the conditional operator is LT or GE and we are comparing against zero and
10106      everything is in registers then we can do this in two instructions.  */
10107   if (operands[3] == const0_rtx
10108       && GET_CODE (operands[7]) != AND
10109       && REG_P (operands[5])
10110       && REG_P (operands[1])
10111       && REGNO (operands[1]) == REGNO (operands[4])
10112       && REGNO (operands[4]) != REGNO (operands[0]))
10113     {
10114       if (GET_CODE (operands[6]) == LT)
10115         return \"and\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\";
10116       else if (GET_CODE (operands[6]) == GE)
10117         return \"bic\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\";
10118     }
10119   if (CONST_INT_P (operands[3])
10120       && !const_ok_for_arm (INTVAL (operands[3])))
10121     output_asm_insn (\"cmn\\t%2, #%n3\", operands);
10122   else
10123     output_asm_insn (\"cmp\\t%2, %3\", operands);
10124   output_asm_insn (\"%I7%d6\\t%0, %4, %5\", operands);
10125   if (which_alternative != 0)
10126     return \"mov%D6\\t%0, %1\";
10127   return \"\";
10128   "
10129   [(set_attr "conds" "clob")
10130    (set_attr "length" "8,12")
10131    (set_attr "type" "multiple")]
10134 (define_insn "*if_arith_move"
10135   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10136         (if_then_else:SI (match_operator 4 "arm_comparison_operator"
10137                           [(match_operand 6 "cc_register" "") (const_int 0)])
10138                          (match_operator:SI 5 "shiftable_operator"
10139                           [(match_operand:SI 2 "s_register_operand" "r,r")
10140                            (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
10141                          (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))]
10142   "TARGET_ARM"
10143   "@
10144    %I5%d4\\t%0, %2, %3
10145    %I5%d4\\t%0, %2, %3\;mov%D4\\t%0, %1"
10146   [(set_attr "conds" "use")
10147    (set_attr "length" "4,8")
10148    (set_attr_alternative "type"
10149                          [(if_then_else (match_operand 3 "const_int_operand" "")
10150                                         (const_string "alu_shift_imm" )
10151                                         (const_string "alu_shift_reg"))
10152                           (const_string "multiple")])]
10155 (define_insn "*ifcompare_move_arith"
10156   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10157         (if_then_else:SI (match_operator 6 "arm_comparison_operator"
10158                           [(match_operand:SI 4 "s_register_operand" "r,r")
10159                            (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
10160                          (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
10161                          (match_operator:SI 7 "shiftable_operator"
10162                           [(match_operand:SI 2 "s_register_operand" "r,r")
10163                            (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
10164    (clobber (reg:CC CC_REGNUM))]
10165   "TARGET_ARM"
10166   "*
10167   /* If we have an operation where (op x 0) is the identity operation and
10168      the conditional operator is LT or GE and we are comparing against zero and
10169      everything is in registers then we can do this in two instructions */
10170   if (operands[5] == const0_rtx
10171       && GET_CODE (operands[7]) != AND
10172       && REG_P (operands[3])
10173       && REG_P (operands[1])
10174       && REGNO (operands[1]) == REGNO (operands[2])
10175       && REGNO (operands[2]) != REGNO (operands[0]))
10176     {
10177       if (GET_CODE (operands[6]) == GE)
10178         return \"and\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\";
10179       else if (GET_CODE (operands[6]) == LT)
10180         return \"bic\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\";
10181     }
10183   if (CONST_INT_P (operands[5])
10184       && !const_ok_for_arm (INTVAL (operands[5])))
10185     output_asm_insn (\"cmn\\t%4, #%n5\", operands);
10186   else
10187     output_asm_insn (\"cmp\\t%4, %5\", operands);
10189   if (which_alternative != 0)
10190     output_asm_insn (\"mov%d6\\t%0, %1\", operands);
10191   return \"%I7%D6\\t%0, %2, %3\";
10192   "
10193   [(set_attr "conds" "clob")
10194    (set_attr "length" "8,12")
10195    (set_attr "type" "multiple")]
10198 (define_insn "*if_move_arith"
10199   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10200         (if_then_else:SI
10201          (match_operator 4 "arm_comparison_operator"
10202           [(match_operand 6 "cc_register" "") (const_int 0)])
10203          (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
10204          (match_operator:SI 5 "shiftable_operator"
10205           [(match_operand:SI 2 "s_register_operand" "r,r")
10206            (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))]
10207   "TARGET_ARM"
10208   "@
10209    %I5%D4\\t%0, %2, %3
10210    %I5%D4\\t%0, %2, %3\;mov%d4\\t%0, %1"
10211   [(set_attr "conds" "use")
10212    (set_attr "length" "4,8")
10213    (set_attr_alternative "type"
10214                          [(if_then_else (match_operand 3 "const_int_operand" "")
10215                                         (const_string "alu_shift_imm" )
10216                                         (const_string "alu_shift_reg"))
10217                           (const_string "multiple")])]
10220 (define_insn "*ifcompare_move_not"
10221   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10222         (if_then_else:SI
10223          (match_operator 5 "arm_comparison_operator"
10224           [(match_operand:SI 3 "s_register_operand" "r,r")
10225            (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
10226          (match_operand:SI 1 "arm_not_operand" "0,?rIK")
10227          (not:SI
10228           (match_operand:SI 2 "s_register_operand" "r,r"))))
10229    (clobber (reg:CC CC_REGNUM))]
10230   "TARGET_ARM"
10231   "#"
10232   [(set_attr "conds" "clob")
10233    (set_attr "length" "8,12")
10234    (set_attr "type" "multiple")]
10237 (define_insn "*if_move_not"
10238   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
10239         (if_then_else:SI
10240          (match_operator 4 "arm_comparison_operator"
10241           [(match_operand 3 "cc_register" "") (const_int 0)])
10242          (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
10243          (not:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))))]
10244   "TARGET_ARM"
10245   "@
10246    mvn%D4\\t%0, %2
10247    mov%d4\\t%0, %1\;mvn%D4\\t%0, %2
10248    mvn%d4\\t%0, #%B1\;mvn%D4\\t%0, %2"
10249   [(set_attr "conds" "use")
10250    (set_attr "type" "mvn_reg")
10251    (set_attr "length" "4,8,8")
10252    (set_attr "type" "mvn_reg,multiple,multiple")]
10255 (define_insn "*ifcompare_not_move"
10256   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10257         (if_then_else:SI 
10258          (match_operator 5 "arm_comparison_operator"
10259           [(match_operand:SI 3 "s_register_operand" "r,r")
10260            (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
10261          (not:SI
10262           (match_operand:SI 2 "s_register_operand" "r,r"))
10263          (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
10264    (clobber (reg:CC CC_REGNUM))]
10265   "TARGET_ARM"
10266   "#"
10267   [(set_attr "conds" "clob")
10268    (set_attr "length" "8,12")
10269    (set_attr "type" "multiple")]
10272 (define_insn "*if_not_move"
10273   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
10274         (if_then_else:SI
10275          (match_operator 4 "arm_comparison_operator"
10276           [(match_operand 3 "cc_register" "") (const_int 0)])
10277          (not:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))
10278          (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
10279   "TARGET_ARM"
10280   "@
10281    mvn%d4\\t%0, %2
10282    mov%D4\\t%0, %1\;mvn%d4\\t%0, %2
10283    mvn%D4\\t%0, #%B1\;mvn%d4\\t%0, %2"
10284   [(set_attr "conds" "use")
10285    (set_attr "type" "mvn_reg,multiple,multiple")
10286    (set_attr "length" "4,8,8")]
10289 (define_insn "*ifcompare_shift_move"
10290   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10291         (if_then_else:SI
10292          (match_operator 6 "arm_comparison_operator"
10293           [(match_operand:SI 4 "s_register_operand" "r,r")
10294            (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
10295          (match_operator:SI 7 "shift_operator"
10296           [(match_operand:SI 2 "s_register_operand" "r,r")
10297            (match_operand:SI 3 "arm_rhs_operand" "rM,rM")])
10298          (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
10299    (clobber (reg:CC CC_REGNUM))]
10300   "TARGET_ARM"
10301   "#"
10302   [(set_attr "conds" "clob")
10303    (set_attr "length" "8,12")
10304    (set_attr "type" "multiple")]
10307 (define_insn "*if_shift_move"
10308   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
10309         (if_then_else:SI
10310          (match_operator 5 "arm_comparison_operator"
10311           [(match_operand 6 "cc_register" "") (const_int 0)])
10312          (match_operator:SI 4 "shift_operator"
10313           [(match_operand:SI 2 "s_register_operand" "r,r,r")
10314            (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM")])
10315          (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
10316   "TARGET_ARM"
10317   "@
10318    mov%d5\\t%0, %2%S4
10319    mov%D5\\t%0, %1\;mov%d5\\t%0, %2%S4
10320    mvn%D5\\t%0, #%B1\;mov%d5\\t%0, %2%S4"
10321   [(set_attr "conds" "use")
10322    (set_attr "shift" "2")
10323    (set_attr "length" "4,8,8")
10324    (set_attr_alternative "type"
10325                          [(if_then_else (match_operand 3 "const_int_operand" "")
10326                                         (const_string "mov_shift" )
10327                                         (const_string "mov_shift_reg"))
10328                           (const_string "multiple")
10329                           (const_string "multiple")])]
10332 (define_insn "*ifcompare_move_shift"
10333   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10334         (if_then_else:SI
10335          (match_operator 6 "arm_comparison_operator"
10336           [(match_operand:SI 4 "s_register_operand" "r,r")
10337            (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
10338          (match_operand:SI 1 "arm_not_operand" "0,?rIK")
10339          (match_operator:SI 7 "shift_operator"
10340           [(match_operand:SI 2 "s_register_operand" "r,r")
10341            (match_operand:SI 3 "arm_rhs_operand" "rM,rM")])))
10342    (clobber (reg:CC CC_REGNUM))]
10343   "TARGET_ARM"
10344   "#"
10345   [(set_attr "conds" "clob")
10346    (set_attr "length" "8,12")
10347    (set_attr "type" "multiple")]
10350 (define_insn "*if_move_shift"
10351   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
10352         (if_then_else:SI
10353          (match_operator 5 "arm_comparison_operator"
10354           [(match_operand 6 "cc_register" "") (const_int 0)])
10355          (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
10356          (match_operator:SI 4 "shift_operator"
10357           [(match_operand:SI 2 "s_register_operand" "r,r,r")
10358            (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM")])))]
10359   "TARGET_ARM"
10360   "@
10361    mov%D5\\t%0, %2%S4
10362    mov%d5\\t%0, %1\;mov%D5\\t%0, %2%S4
10363    mvn%d5\\t%0, #%B1\;mov%D5\\t%0, %2%S4"
10364   [(set_attr "conds" "use")
10365    (set_attr "shift" "2")
10366    (set_attr "length" "4,8,8")
10367    (set_attr_alternative "type"
10368                          [(if_then_else (match_operand 3 "const_int_operand" "")
10369                                         (const_string "mov_shift" )
10370                                         (const_string "mov_shift_reg"))
10371                           (const_string "multiple")
10372                           (const_string "multiple")])]
10375 (define_insn "*ifcompare_shift_shift"
10376   [(set (match_operand:SI 0 "s_register_operand" "=r")
10377         (if_then_else:SI
10378          (match_operator 7 "arm_comparison_operator"
10379           [(match_operand:SI 5 "s_register_operand" "r")
10380            (match_operand:SI 6 "arm_add_operand" "rIL")])
10381          (match_operator:SI 8 "shift_operator"
10382           [(match_operand:SI 1 "s_register_operand" "r")
10383            (match_operand:SI 2 "arm_rhs_operand" "rM")])
10384          (match_operator:SI 9 "shift_operator"
10385           [(match_operand:SI 3 "s_register_operand" "r")
10386            (match_operand:SI 4 "arm_rhs_operand" "rM")])))
10387    (clobber (reg:CC CC_REGNUM))]
10388   "TARGET_ARM"
10389   "#"
10390   [(set_attr "conds" "clob")
10391    (set_attr "length" "12")
10392    (set_attr "type" "multiple")]
10395 (define_insn "*if_shift_shift"
10396   [(set (match_operand:SI 0 "s_register_operand" "=r")
10397         (if_then_else:SI
10398          (match_operator 5 "arm_comparison_operator"
10399           [(match_operand 8 "cc_register" "") (const_int 0)])
10400          (match_operator:SI 6 "shift_operator"
10401           [(match_operand:SI 1 "s_register_operand" "r")
10402            (match_operand:SI 2 "arm_rhs_operand" "rM")])
10403          (match_operator:SI 7 "shift_operator"
10404           [(match_operand:SI 3 "s_register_operand" "r")
10405            (match_operand:SI 4 "arm_rhs_operand" "rM")])))]
10406   "TARGET_ARM"
10407   "mov%d5\\t%0, %1%S6\;mov%D5\\t%0, %3%S7"
10408   [(set_attr "conds" "use")
10409    (set_attr "shift" "1")
10410    (set_attr "length" "8")
10411    (set (attr "type") (if_then_else
10412                         (and (match_operand 2 "const_int_operand" "")
10413                              (match_operand 4 "const_int_operand" ""))
10414                       (const_string "mov_shift")
10415                       (const_string "mov_shift_reg")))]
10418 (define_insn "*ifcompare_not_arith"
10419   [(set (match_operand:SI 0 "s_register_operand" "=r")
10420         (if_then_else:SI
10421          (match_operator 6 "arm_comparison_operator"
10422           [(match_operand:SI 4 "s_register_operand" "r")
10423            (match_operand:SI 5 "arm_add_operand" "rIL")])
10424          (not:SI (match_operand:SI 1 "s_register_operand" "r"))
10425          (match_operator:SI 7 "shiftable_operator"
10426           [(match_operand:SI 2 "s_register_operand" "r")
10427            (match_operand:SI 3 "arm_rhs_operand" "rI")])))
10428    (clobber (reg:CC CC_REGNUM))]
10429   "TARGET_ARM"
10430   "#"
10431   [(set_attr "conds" "clob")
10432    (set_attr "length" "12")
10433    (set_attr "type" "multiple")]
10436 (define_insn "*if_not_arith"
10437   [(set (match_operand:SI 0 "s_register_operand" "=r")
10438         (if_then_else:SI
10439          (match_operator 5 "arm_comparison_operator"
10440           [(match_operand 4 "cc_register" "") (const_int 0)])
10441          (not:SI (match_operand:SI 1 "s_register_operand" "r"))
10442          (match_operator:SI 6 "shiftable_operator"
10443           [(match_operand:SI 2 "s_register_operand" "r")
10444            (match_operand:SI 3 "arm_rhs_operand" "rI")])))]
10445   "TARGET_ARM"
10446   "mvn%d5\\t%0, %1\;%I6%D5\\t%0, %2, %3"
10447   [(set_attr "conds" "use")
10448    (set_attr "type" "mvn_reg")
10449    (set_attr "length" "8")]
10452 (define_insn "*ifcompare_arith_not"
10453   [(set (match_operand:SI 0 "s_register_operand" "=r")
10454         (if_then_else:SI
10455          (match_operator 6 "arm_comparison_operator"
10456           [(match_operand:SI 4 "s_register_operand" "r")
10457            (match_operand:SI 5 "arm_add_operand" "rIL")])
10458          (match_operator:SI 7 "shiftable_operator"
10459           [(match_operand:SI 2 "s_register_operand" "r")
10460            (match_operand:SI 3 "arm_rhs_operand" "rI")])
10461          (not:SI (match_operand:SI 1 "s_register_operand" "r"))))
10462    (clobber (reg:CC CC_REGNUM))]
10463   "TARGET_ARM"
10464   "#"
10465   [(set_attr "conds" "clob")
10466    (set_attr "length" "12")
10467    (set_attr "type" "multiple")]
10470 (define_insn "*if_arith_not"
10471   [(set (match_operand:SI 0 "s_register_operand" "=r")
10472         (if_then_else:SI
10473          (match_operator 5 "arm_comparison_operator"
10474           [(match_operand 4 "cc_register" "") (const_int 0)])
10475          (match_operator:SI 6 "shiftable_operator"
10476           [(match_operand:SI 2 "s_register_operand" "r")
10477            (match_operand:SI 3 "arm_rhs_operand" "rI")])
10478          (not:SI (match_operand:SI 1 "s_register_operand" "r"))))]
10479   "TARGET_ARM"
10480   "mvn%D5\\t%0, %1\;%I6%d5\\t%0, %2, %3"
10481   [(set_attr "conds" "use")
10482    (set_attr "type" "multiple")
10483    (set_attr "length" "8")]
10486 (define_insn "*ifcompare_neg_move"
10487   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10488         (if_then_else:SI
10489          (match_operator 5 "arm_comparison_operator"
10490           [(match_operand:SI 3 "s_register_operand" "r,r")
10491            (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
10492          (neg:SI (match_operand:SI 2 "s_register_operand" "r,r"))
10493          (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
10494    (clobber (reg:CC CC_REGNUM))]
10495   "TARGET_ARM"
10496   "#"
10497   [(set_attr "conds" "clob")
10498    (set_attr "length" "8,12")
10499    (set_attr "type" "multiple")]
10502 (define_insn_and_split "*if_neg_move"
10503   [(set (match_operand:SI 0 "s_register_operand" "=l,r")
10504         (if_then_else:SI
10505          (match_operator 4 "arm_comparison_operator"
10506           [(match_operand 3 "cc_register" "") (const_int 0)])
10507          (neg:SI (match_operand:SI 2 "s_register_operand" "l,r"))
10508          (match_operand:SI 1 "s_register_operand" "0,0")))]
10509   "TARGET_32BIT"
10510   "#"
10511   "&& reload_completed"
10512   [(cond_exec (match_op_dup 4 [(match_dup 3) (const_int 0)])
10513               (set (match_dup 0) (neg:SI (match_dup 2))))]
10514   ""
10515   [(set_attr "conds" "use")
10516    (set_attr "length" "4")
10517    (set_attr "arch" "t2,32")
10518    (set_attr "enabled_for_depr_it" "yes,no")
10519    (set_attr "type" "logic_shift_imm")]
10522 (define_insn "*ifcompare_move_neg"
10523   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10524         (if_then_else:SI
10525          (match_operator 5 "arm_comparison_operator"
10526           [(match_operand:SI 3 "s_register_operand" "r,r")
10527            (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
10528          (match_operand:SI 1 "arm_not_operand" "0,?rIK")
10529          (neg:SI (match_operand:SI 2 "s_register_operand" "r,r"))))
10530    (clobber (reg:CC CC_REGNUM))]
10531   "TARGET_ARM"
10532   "#"
10533   [(set_attr "conds" "clob")
10534    (set_attr "length" "8,12")
10535    (set_attr "type" "multiple")]
10538 (define_insn_and_split "*if_move_neg"
10539   [(set (match_operand:SI 0 "s_register_operand" "=l,r")
10540         (if_then_else:SI
10541          (match_operator 4 "arm_comparison_operator"
10542           [(match_operand 3 "cc_register" "") (const_int 0)])
10543          (match_operand:SI 1 "s_register_operand" "0,0")
10544          (neg:SI (match_operand:SI 2 "s_register_operand" "l,r"))))]
10545   "TARGET_32BIT"
10546   "#"
10547   "&& reload_completed"
10548   [(cond_exec (match_dup 5)
10549               (set (match_dup 0) (neg:SI (match_dup 2))))]
10550   {
10551     machine_mode mode = GET_MODE (operands[3]);
10552     rtx_code rc = GET_CODE (operands[4]);
10554     if (mode == CCFPmode || mode == CCFPEmode)
10555       rc = reverse_condition_maybe_unordered (rc);
10556     else
10557       rc = reverse_condition (rc);
10559     operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[3], const0_rtx);
10560   }
10561   [(set_attr "conds" "use")
10562    (set_attr "length" "4")
10563    (set_attr "arch" "t2,32")
10564    (set_attr "enabled_for_depr_it" "yes,no")
10565    (set_attr "type" "logic_shift_imm")]
10568 (define_insn "*arith_adjacentmem"
10569   [(set (match_operand:SI 0 "s_register_operand" "=r")
10570         (match_operator:SI 1 "shiftable_operator"
10571          [(match_operand:SI 2 "memory_operand" "m")
10572           (match_operand:SI 3 "memory_operand" "m")]))
10573    (clobber (match_scratch:SI 4 "=r"))]
10574   "TARGET_ARM && adjacent_mem_locations (operands[2], operands[3])"
10575   "*
10576   {
10577     rtx ldm[3];
10578     rtx arith[4];
10579     rtx base_reg;
10580     HOST_WIDE_INT val1 = 0, val2 = 0;
10582     if (REGNO (operands[0]) > REGNO (operands[4]))
10583       {
10584         ldm[1] = operands[4];
10585         ldm[2] = operands[0];
10586       }
10587     else
10588       {
10589         ldm[1] = operands[0];
10590         ldm[2] = operands[4];
10591       }
10593     base_reg = XEXP (operands[2], 0);
10595     if (!REG_P (base_reg))
10596       {
10597         val1 = INTVAL (XEXP (base_reg, 1));
10598         base_reg = XEXP (base_reg, 0);
10599       }
10601     if (!REG_P (XEXP (operands[3], 0)))
10602       val2 = INTVAL (XEXP (XEXP (operands[3], 0), 1));
10604     arith[0] = operands[0];
10605     arith[3] = operands[1];
10607     if (val1 < val2)
10608       {
10609         arith[1] = ldm[1];
10610         arith[2] = ldm[2];
10611       }
10612     else
10613       {
10614         arith[1] = ldm[2];
10615         arith[2] = ldm[1];
10616       }
10618     ldm[0] = base_reg;
10619     if (val1 !=0 && val2 != 0)
10620       {
10621         rtx ops[3];
10623         if (val1 == 4 || val2 == 4)
10624           /* Other val must be 8, since we know they are adjacent and neither
10625              is zero.  */
10626           output_asm_insn (\"ldmib%?\\t%0, {%1, %2}\", ldm);
10627         else if (const_ok_for_arm (val1) || const_ok_for_arm (-val1))
10628           {
10629             ldm[0] = ops[0] = operands[4];
10630             ops[1] = base_reg;
10631             ops[2] = GEN_INT (val1);
10632             output_add_immediate (ops);
10633             if (val1 < val2)
10634               output_asm_insn (\"ldmia%?\\t%0, {%1, %2}\", ldm);
10635             else
10636               output_asm_insn (\"ldmda%?\\t%0, {%1, %2}\", ldm);
10637           }
10638         else
10639           {
10640             /* Offset is out of range for a single add, so use two ldr.  */
10641             ops[0] = ldm[1];
10642             ops[1] = base_reg;
10643             ops[2] = GEN_INT (val1);
10644             output_asm_insn (\"ldr%?\\t%0, [%1, %2]\", ops);
10645             ops[0] = ldm[2];
10646             ops[2] = GEN_INT (val2);
10647             output_asm_insn (\"ldr%?\\t%0, [%1, %2]\", ops);
10648           }
10649       }
10650     else if (val1 != 0)
10651       {
10652         if (val1 < val2)
10653           output_asm_insn (\"ldmda%?\\t%0, {%1, %2}\", ldm);
10654         else
10655           output_asm_insn (\"ldmia%?\\t%0, {%1, %2}\", ldm);
10656       }
10657     else
10658       {
10659         if (val1 < val2)
10660           output_asm_insn (\"ldmia%?\\t%0, {%1, %2}\", ldm);
10661         else
10662           output_asm_insn (\"ldmda%?\\t%0, {%1, %2}\", ldm);
10663       }
10664     output_asm_insn (\"%I3%?\\t%0, %1, %2\", arith);
10665     return \"\";
10666   }"
10667   [(set_attr "length" "12")
10668    (set_attr "predicable" "yes")
10669    (set_attr "type" "load1")]
10672 ; This pattern is never tried by combine, so do it as a peephole
10674 (define_peephole2
10675   [(set (match_operand:SI 0 "arm_general_register_operand" "")
10676         (match_operand:SI 1 "arm_general_register_operand" ""))
10677    (set (reg:CC CC_REGNUM)
10678         (compare:CC (match_dup 1) (const_int 0)))]
10679   "TARGET_ARM"
10680   [(parallel [(set (reg:CC CC_REGNUM) (compare:CC (match_dup 1) (const_int 0)))
10681               (set (match_dup 0) (match_dup 1))])]
10682   ""
10685 (define_split
10686   [(set (match_operand:SI 0 "s_register_operand" "")
10687         (and:SI (ge:SI (match_operand:SI 1 "s_register_operand" "")
10688                        (const_int 0))
10689                 (neg:SI (match_operator:SI 2 "arm_comparison_operator"
10690                          [(match_operand:SI 3 "s_register_operand" "")
10691                           (match_operand:SI 4 "arm_rhs_operand" "")]))))
10692    (clobber (match_operand:SI 5 "s_register_operand" ""))]
10693   "TARGET_ARM"
10694   [(set (match_dup 5) (not:SI (ashiftrt:SI (match_dup 1) (const_int 31))))
10695    (set (match_dup 0) (and:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
10696                               (match_dup 5)))]
10697   ""
10700 ;; This split can be used because CC_Z mode implies that the following
10701 ;; branch will be an equality, or an unsigned inequality, so the sign
10702 ;; extension is not needed.
10704 (define_split
10705   [(set (reg:CC_Z CC_REGNUM)
10706         (compare:CC_Z
10707          (ashift:SI (subreg:SI (match_operand:QI 0 "memory_operand" "") 0)
10708                     (const_int 24))
10709          (match_operand 1 "const_int_operand" "")))
10710    (clobber (match_scratch:SI 2 ""))]
10711   "TARGET_ARM
10712    && ((UINTVAL (operands[1]))
10713        == ((UINTVAL (operands[1])) >> 24) << 24)"
10714   [(set (match_dup 2) (zero_extend:SI (match_dup 0)))
10715    (set (reg:CC CC_REGNUM) (compare:CC (match_dup 2) (match_dup 1)))]
10716   "
10717   operands[1] = GEN_INT (((unsigned long) INTVAL (operands[1])) >> 24);
10718   "
10720 ;; ??? Check the patterns above for Thumb-2 usefulness
10722 (define_expand "prologue"
10723   [(clobber (const_int 0))]
10724   "TARGET_EITHER"
10725   "if (TARGET_32BIT)
10726      arm_expand_prologue ();
10727    else
10728      thumb1_expand_prologue ();
10729   DONE;
10730   "
10733 (define_expand "epilogue"
10734   [(clobber (const_int 0))]
10735   "TARGET_EITHER"
10736   "
10737   if (crtl->calls_eh_return)
10738     emit_insn (gen_force_register_use (gen_rtx_REG (Pmode, 2)));
10739   if (TARGET_THUMB1)
10740    {
10741      thumb1_expand_epilogue ();
10742      emit_jump_insn (gen_rtx_UNSPEC_VOLATILE (VOIDmode,
10743                      gen_rtvec (1, ret_rtx), VUNSPEC_EPILOGUE));
10744    }
10745   else if (HAVE_return)
10746    {
10747      /* HAVE_return is testing for USE_RETURN_INSN (FALSE).  Hence,
10748         no need for explicit testing again.  */
10749      emit_jump_insn (gen_return ());
10750    }
10751   else if (TARGET_32BIT)
10752    {
10753     arm_expand_epilogue (true);
10754    }
10755   DONE;
10756   "
10759 ;; Note - although unspec_volatile's USE all hard registers,
10760 ;; USEs are ignored after relaod has completed.  Thus we need
10761 ;; to add an unspec of the link register to ensure that flow
10762 ;; does not think that it is unused by the sibcall branch that
10763 ;; will replace the standard function epilogue.
10764 (define_expand "sibcall_epilogue"
10765    [(parallel [(unspec:SI [(reg:SI LR_REGNUM)] UNSPEC_REGISTER_USE)
10766                (unspec_volatile [(return)] VUNSPEC_EPILOGUE)])]
10767    "TARGET_32BIT"
10768    "
10769    arm_expand_epilogue (false);
10770    DONE;
10771    "
10774 (define_expand "eh_epilogue"
10775   [(use (match_operand:SI 0 "register_operand" ""))
10776    (use (match_operand:SI 1 "register_operand" ""))
10777    (use (match_operand:SI 2 "register_operand" ""))]
10778   "TARGET_EITHER"
10779   "
10780   {
10781     cfun->machine->eh_epilogue_sp_ofs = operands[1];
10782     if (!REG_P (operands[2]) || REGNO (operands[2]) != 2)
10783       {
10784         rtx ra = gen_rtx_REG (Pmode, 2);
10786         emit_move_insn (ra, operands[2]);
10787         operands[2] = ra;
10788       }
10789     /* This is a hack -- we may have crystalized the function type too
10790        early.  */
10791     cfun->machine->func_type = 0;
10792   }"
10795 ;; This split is only used during output to reduce the number of patterns
10796 ;; that need assembler instructions adding to them.  We allowed the setting
10797 ;; of the conditions to be implicit during rtl generation so that
10798 ;; the conditional compare patterns would work.  However this conflicts to
10799 ;; some extent with the conditional data operations, so we have to split them
10800 ;; up again here.
10802 ;; ??? Need to audit these splitters for Thumb-2.  Why isn't normal
10803 ;; conditional execution sufficient?
10805 (define_split
10806   [(set (match_operand:SI 0 "s_register_operand" "")
10807         (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10808                           [(match_operand 2 "" "") (match_operand 3 "" "")])
10809                          (match_dup 0)
10810                          (match_operand 4 "" "")))
10811    (clobber (reg:CC CC_REGNUM))]
10812   "TARGET_ARM && reload_completed"
10813   [(set (match_dup 5) (match_dup 6))
10814    (cond_exec (match_dup 7)
10815               (set (match_dup 0) (match_dup 4)))]
10816   "
10817   {
10818     machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10819                                              operands[2], operands[3]);
10820     enum rtx_code rc = GET_CODE (operands[1]);
10822     operands[5] = gen_rtx_REG (mode, CC_REGNUM);
10823     operands[6] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10824     if (mode == CCFPmode || mode == CCFPEmode)
10825       rc = reverse_condition_maybe_unordered (rc);
10826     else
10827       rc = reverse_condition (rc);
10829     operands[7] = gen_rtx_fmt_ee (rc, VOIDmode, operands[5], const0_rtx);
10830   }"
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_operand 4 "" "")
10838                          (match_dup 0)))
10839    (clobber (reg:CC CC_REGNUM))]
10840   "TARGET_ARM && reload_completed"
10841   [(set (match_dup 5) (match_dup 6))
10842    (cond_exec (match_op_dup 1 [(match_dup 5) (const_int 0)])
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]);
10849     operands[5] = gen_rtx_REG (mode, CC_REGNUM);
10850     operands[6] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10851   }"
10854 (define_split
10855   [(set (match_operand:SI 0 "s_register_operand" "")
10856         (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10857                           [(match_operand 2 "" "") (match_operand 3 "" "")])
10858                          (match_operand 4 "" "")
10859                          (match_operand 5 "" "")))
10860    (clobber (reg:CC CC_REGNUM))]
10861   "TARGET_ARM && reload_completed"
10862   [(set (match_dup 6) (match_dup 7))
10863    (cond_exec (match_op_dup 1 [(match_dup 6) (const_int 0)])
10864               (set (match_dup 0) (match_dup 4)))
10865    (cond_exec (match_dup 8)
10866               (set (match_dup 0) (match_dup 5)))]
10867   "
10868   {
10869     machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10870                                              operands[2], operands[3]);
10871     enum rtx_code rc = GET_CODE (operands[1]);
10873     operands[6] = gen_rtx_REG (mode, CC_REGNUM);
10874     operands[7] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10875     if (mode == CCFPmode || mode == CCFPEmode)
10876       rc = reverse_condition_maybe_unordered (rc);
10877     else
10878       rc = reverse_condition (rc);
10880     operands[8] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
10881   }"
10884 (define_split
10885   [(set (match_operand:SI 0 "s_register_operand" "")
10886         (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10887                           [(match_operand:SI 2 "s_register_operand" "")
10888                            (match_operand:SI 3 "arm_add_operand" "")])
10889                          (match_operand:SI 4 "arm_rhs_operand" "")
10890                          (not:SI
10891                           (match_operand:SI 5 "s_register_operand" ""))))
10892    (clobber (reg:CC CC_REGNUM))]
10893   "TARGET_ARM && reload_completed"
10894   [(set (match_dup 6) (match_dup 7))
10895    (cond_exec (match_op_dup 1 [(match_dup 6) (const_int 0)])
10896               (set (match_dup 0) (match_dup 4)))
10897    (cond_exec (match_dup 8)
10898               (set (match_dup 0) (not:SI (match_dup 5))))]
10899   "
10900   {
10901     machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10902                                              operands[2], operands[3]);
10903     enum rtx_code rc = GET_CODE (operands[1]);
10905     operands[6] = gen_rtx_REG (mode, CC_REGNUM);
10906     operands[7] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10907     if (mode == CCFPmode || mode == CCFPEmode)
10908       rc = reverse_condition_maybe_unordered (rc);
10909     else
10910       rc = reverse_condition (rc);
10912     operands[8] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
10913   }"
10916 (define_insn "*cond_move_not"
10917   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10918         (if_then_else:SI (match_operator 4 "arm_comparison_operator"
10919                           [(match_operand 3 "cc_register" "") (const_int 0)])
10920                          (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
10921                          (not:SI
10922                           (match_operand:SI 2 "s_register_operand" "r,r"))))]
10923   "TARGET_ARM"
10924   "@
10925    mvn%D4\\t%0, %2
10926    mov%d4\\t%0, %1\;mvn%D4\\t%0, %2"
10927   [(set_attr "conds" "use")
10928    (set_attr "type" "mvn_reg,multiple")
10929    (set_attr "length" "4,8")]
10932 ;; The next two patterns occur when an AND operation is followed by a
10933 ;; scc insn sequence 
10935 (define_insn "*sign_extract_onebit"
10936   [(set (match_operand:SI 0 "s_register_operand" "=r")
10937         (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
10938                          (const_int 1)
10939                          (match_operand:SI 2 "const_int_operand" "n")))
10940     (clobber (reg:CC CC_REGNUM))]
10941   "TARGET_ARM"
10942   "*
10943     operands[2] = GEN_INT (1 << INTVAL (operands[2]));
10944     output_asm_insn (\"ands\\t%0, %1, %2\", operands);
10945     return \"mvnne\\t%0, #0\";
10946   "
10947   [(set_attr "conds" "clob")
10948    (set_attr "length" "8")
10949    (set_attr "type" "multiple")]
10952 (define_insn "*not_signextract_onebit"
10953   [(set (match_operand:SI 0 "s_register_operand" "=r")
10954         (not:SI
10955          (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
10956                           (const_int 1)
10957                           (match_operand:SI 2 "const_int_operand" "n"))))
10958    (clobber (reg:CC CC_REGNUM))]
10959   "TARGET_ARM"
10960   "*
10961     operands[2] = GEN_INT (1 << INTVAL (operands[2]));
10962     output_asm_insn (\"tst\\t%1, %2\", operands);
10963     output_asm_insn (\"mvneq\\t%0, #0\", operands);
10964     return \"movne\\t%0, #0\";
10965   "
10966   [(set_attr "conds" "clob")
10967    (set_attr "length" "12")
10968    (set_attr "type" "multiple")]
10970 ;; ??? The above patterns need auditing for Thumb-2
10972 ;; Push multiple registers to the stack.  Registers are in parallel (use ...)
10973 ;; expressions.  For simplicity, the first register is also in the unspec
10974 ;; part.
10975 ;; To avoid the usage of GNU extension, the length attribute is computed
10976 ;; in a C function arm_attr_length_push_multi.
10977 (define_insn "*push_multi"
10978   [(match_parallel 2 "multi_register_push"
10979     [(set (match_operand:BLK 0 "push_mult_memory_operand" "")
10980           (unspec:BLK [(match_operand:SI 1 "s_register_operand" "")]
10981                       UNSPEC_PUSH_MULT))])]
10982   ""
10983   "*
10984   {
10985     int num_saves = XVECLEN (operands[2], 0);
10986      
10987     /* For the StrongARM at least it is faster to
10988        use STR to store only a single register.
10989        In Thumb mode always use push, and the assembler will pick
10990        something appropriate.  */
10991     if (num_saves == 1 && TARGET_ARM)
10992       output_asm_insn (\"str%?\\t%1, [%m0, #-4]!\", operands);
10993     else
10994       {
10995         int i;
10996         char pattern[100];
10998         if (TARGET_32BIT)
10999             strcpy (pattern, \"push%?\\t{%1\");
11000         else
11001             strcpy (pattern, \"push\\t{%1\");
11003         for (i = 1; i < num_saves; i++)
11004           {
11005             strcat (pattern, \", %|\");
11006             strcat (pattern,
11007                     reg_names[REGNO (XEXP (XVECEXP (operands[2], 0, i), 0))]);
11008           }
11010         strcat (pattern, \"}\");
11011         output_asm_insn (pattern, operands);
11012       }
11014     return \"\";
11015   }"
11016   [(set_attr "type" "store4")
11017    (set (attr "length")
11018         (symbol_ref "arm_attr_length_push_multi (operands[2], operands[1])"))]
11021 (define_insn "stack_tie"
11022   [(set (mem:BLK (scratch))
11023         (unspec:BLK [(match_operand:SI 0 "s_register_operand" "rk")
11024                      (match_operand:SI 1 "s_register_operand" "rk")]
11025                     UNSPEC_PRLG_STK))]
11026   ""
11027   ""
11028   [(set_attr "length" "0")
11029    (set_attr "type" "block")]
11032 ;; Pop (as used in epilogue RTL)
11034 (define_insn "*load_multiple_with_writeback"
11035   [(match_parallel 0 "load_multiple_operation"
11036     [(set (match_operand:SI 1 "s_register_operand" "+rk")
11037           (plus:SI (match_dup 1)
11038                    (match_operand:SI 2 "const_int_I_operand" "I")))
11039      (set (match_operand:SI 3 "s_register_operand" "=rk")
11040           (mem:SI (match_dup 1)))
11041         ])]
11042   "TARGET_32BIT && (reload_in_progress || reload_completed)"
11043   "*
11044   {
11045     arm_output_multireg_pop (operands, /*return_pc=*/false,
11046                                        /*cond=*/const_true_rtx,
11047                                        /*reverse=*/false,
11048                                        /*update=*/true);
11049     return \"\";
11050   }
11051   "
11052   [(set_attr "type" "load4")
11053    (set_attr "predicable" "yes")
11054    (set (attr "length")
11055         (symbol_ref "arm_attr_length_pop_multi (operands,
11056                                                 /*return_pc=*/false,
11057                                                 /*write_back_p=*/true)"))]
11060 ;; Pop with return (as used in epilogue RTL)
11062 ;; This instruction is generated when the registers are popped at the end of
11063 ;; epilogue.  Here, instead of popping the value into LR and then generating
11064 ;; jump to LR, value is popped into PC directly.  Hence, the pattern is combined
11065 ;;  with (return).
11066 (define_insn "*pop_multiple_with_writeback_and_return"
11067   [(match_parallel 0 "pop_multiple_return"
11068     [(return)
11069      (set (match_operand:SI 1 "s_register_operand" "+rk")
11070           (plus:SI (match_dup 1)
11071                    (match_operand:SI 2 "const_int_I_operand" "I")))
11072      (set (match_operand:SI 3 "s_register_operand" "=rk")
11073           (mem:SI (match_dup 1)))
11074         ])]
11075   "TARGET_32BIT && (reload_in_progress || reload_completed)"
11076   "*
11077   {
11078     arm_output_multireg_pop (operands, /*return_pc=*/true,
11079                                        /*cond=*/const_true_rtx,
11080                                        /*reverse=*/false,
11081                                        /*update=*/true);
11082     return \"\";
11083   }
11084   "
11085   [(set_attr "type" "load4")
11086    (set_attr "predicable" "yes")
11087    (set (attr "length")
11088         (symbol_ref "arm_attr_length_pop_multi (operands, /*return_pc=*/true,
11089                                                 /*write_back_p=*/true)"))]
11092 (define_insn "*pop_multiple_with_return"
11093   [(match_parallel 0 "pop_multiple_return"
11094     [(return)
11095      (set (match_operand:SI 2 "s_register_operand" "=rk")
11096           (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
11097         ])]
11098   "TARGET_32BIT && (reload_in_progress || reload_completed)"
11099   "*
11100   {
11101     arm_output_multireg_pop (operands, /*return_pc=*/true,
11102                                        /*cond=*/const_true_rtx,
11103                                        /*reverse=*/false,
11104                                        /*update=*/false);
11105     return \"\";
11106   }
11107   "
11108   [(set_attr "type" "load4")
11109    (set_attr "predicable" "yes")
11110    (set (attr "length")
11111         (symbol_ref "arm_attr_length_pop_multi (operands, /*return_pc=*/true,
11112                                                 /*write_back_p=*/false)"))]
11115 ;; Load into PC and return
11116 (define_insn "*ldr_with_return"
11117   [(return)
11118    (set (reg:SI PC_REGNUM)
11119         (mem:SI (post_inc:SI (match_operand:SI 0 "s_register_operand" "+rk"))))]
11120   "TARGET_32BIT && (reload_in_progress || reload_completed)"
11121   "ldr%?\t%|pc, [%0], #4"
11122   [(set_attr "type" "load1")
11123    (set_attr "predicable" "yes")]
11125 ;; Pop for floating point registers (as used in epilogue RTL)
11126 (define_insn "*vfp_pop_multiple_with_writeback"
11127   [(match_parallel 0 "pop_multiple_fp"
11128     [(set (match_operand:SI 1 "s_register_operand" "+rk")
11129           (plus:SI (match_dup 1)
11130                    (match_operand:SI 2 "const_int_I_operand" "I")))
11131      (set (match_operand:DF 3 "vfp_hard_register_operand" "")
11132           (mem:DF (match_dup 1)))])]
11133   "TARGET_32BIT && TARGET_HARD_FLOAT"
11134   "*
11135   {
11136     int num_regs = XVECLEN (operands[0], 0);
11137     char pattern[100];
11138     rtx op_list[2];
11139     strcpy (pattern, \"vldm\\t\");
11140     strcat (pattern, reg_names[REGNO (SET_DEST (XVECEXP (operands[0], 0, 0)))]);
11141     strcat (pattern, \"!, {\");
11142     op_list[0] = XEXP (XVECEXP (operands[0], 0, 1), 0);
11143     strcat (pattern, \"%P0\");
11144     if ((num_regs - 1) > 1)
11145       {
11146         strcat (pattern, \"-%P1\");
11147         op_list [1] = XEXP (XVECEXP (operands[0], 0, num_regs - 1), 0);
11148       }
11150     strcat (pattern, \"}\");
11151     output_asm_insn (pattern, op_list);
11152     return \"\";
11153   }
11154   "
11155   [(set_attr "type" "load4")
11156    (set_attr "conds" "unconditional")
11157    (set_attr "predicable" "no")]
11160 ;; Special patterns for dealing with the constant pool
11162 (define_insn "align_4"
11163   [(unspec_volatile [(const_int 0)] VUNSPEC_ALIGN)]
11164   "TARGET_EITHER"
11165   "*
11166   assemble_align (32);
11167   return \"\";
11168   "
11169   [(set_attr "type" "no_insn")]
11172 (define_insn "align_8"
11173   [(unspec_volatile [(const_int 0)] VUNSPEC_ALIGN8)]
11174   "TARGET_EITHER"
11175   "*
11176   assemble_align (64);
11177   return \"\";
11178   "
11179   [(set_attr "type" "no_insn")]
11182 (define_insn "consttable_end"
11183   [(unspec_volatile [(const_int 0)] VUNSPEC_POOL_END)]
11184   "TARGET_EITHER"
11185   "*
11186   making_const_table = FALSE;
11187   return \"\";
11188   "
11189   [(set_attr "type" "no_insn")]
11192 (define_insn "consttable_1"
11193   [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_1)]
11194   "TARGET_EITHER"
11195   "*
11196   making_const_table = TRUE;
11197   assemble_integer (operands[0], 1, BITS_PER_WORD, 1);
11198   assemble_zeros (3);
11199   return \"\";
11200   "
11201   [(set_attr "length" "4")
11202    (set_attr "type" "no_insn")]
11205 (define_insn "consttable_2"
11206   [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_2)]
11207   "TARGET_EITHER"
11208   "*
11209   {
11210     rtx x = operands[0];
11211     making_const_table = TRUE;
11212     switch (GET_MODE_CLASS (GET_MODE (x)))
11213       {
11214       case MODE_FLOAT:
11215         arm_emit_fp16_const (x);
11216         break;
11217       default:
11218         assemble_integer (operands[0], 2, BITS_PER_WORD, 1);
11219         assemble_zeros (2);
11220         break;
11221       }
11222     return \"\";
11223   }"
11224   [(set_attr "length" "4")
11225    (set_attr "type" "no_insn")]
11228 (define_insn "consttable_4"
11229   [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_4)]
11230   "TARGET_EITHER"
11231   "*
11232   {
11233     rtx x = operands[0];
11234     making_const_table = TRUE;
11235     switch (GET_MODE_CLASS (GET_MODE (x)))
11236       {
11237       case MODE_FLOAT:
11238         assemble_real (*CONST_DOUBLE_REAL_VALUE (x), GET_MODE (x),
11239                        BITS_PER_WORD);
11240         break;
11241       default:
11242         /* XXX: Sometimes gcc does something really dumb and ends up with
11243            a HIGH in a constant pool entry, usually because it's trying to
11244            load into a VFP register.  We know this will always be used in
11245            combination with a LO_SUM which ignores the high bits, so just
11246            strip off the HIGH.  */
11247         if (GET_CODE (x) == HIGH)
11248           x = XEXP (x, 0);
11249         assemble_integer (x, 4, BITS_PER_WORD, 1);
11250         mark_symbol_refs_as_used (x);
11251         break;
11252       }
11253     return \"\";
11254   }"
11255   [(set_attr "length" "4")
11256    (set_attr "type" "no_insn")]
11259 (define_insn "consttable_8"
11260   [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_8)]
11261   "TARGET_EITHER"
11262   "*
11263   {
11264     making_const_table = TRUE;
11265     switch (GET_MODE_CLASS (GET_MODE (operands[0])))
11266       {
11267       case MODE_FLOAT:
11268         assemble_real (*CONST_DOUBLE_REAL_VALUE (operands[0]),
11269                        GET_MODE (operands[0]), BITS_PER_WORD);
11270         break;
11271       default:
11272         assemble_integer (operands[0], 8, BITS_PER_WORD, 1);
11273         break;
11274       }
11275     return \"\";
11276   }"
11277   [(set_attr "length" "8")
11278    (set_attr "type" "no_insn")]
11281 (define_insn "consttable_16"
11282   [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_16)]
11283   "TARGET_EITHER"
11284   "*
11285   {
11286     making_const_table = TRUE;
11287     switch (GET_MODE_CLASS (GET_MODE (operands[0])))
11288       {
11289       case MODE_FLOAT:
11290         assemble_real (*CONST_DOUBLE_REAL_VALUE (operands[0]),
11291                        GET_MODE (operands[0]), BITS_PER_WORD);
11292         break;
11293       default:
11294         assemble_integer (operands[0], 16, BITS_PER_WORD, 1);
11295         break;
11296       }
11297     return \"\";
11298   }"
11299   [(set_attr "length" "16")
11300    (set_attr "type" "no_insn")]
11303 ;; V5 Instructions,
11305 (define_insn "clzsi2"
11306   [(set (match_operand:SI 0 "s_register_operand" "=r")
11307         (clz:SI (match_operand:SI 1 "s_register_operand" "r")))]
11308   "TARGET_32BIT && arm_arch5"
11309   "clz%?\\t%0, %1"
11310   [(set_attr "predicable" "yes")
11311    (set_attr "predicable_short_it" "no")
11312    (set_attr "type" "clz")])
11314 (define_insn "rbitsi2"
11315   [(set (match_operand:SI 0 "s_register_operand" "=r")
11316         (unspec:SI [(match_operand:SI 1 "s_register_operand" "r")] UNSPEC_RBIT))]
11317   "TARGET_32BIT && arm_arch_thumb2"
11318   "rbit%?\\t%0, %1"
11319   [(set_attr "predicable" "yes")
11320    (set_attr "predicable_short_it" "no")
11321    (set_attr "type" "clz")])
11323 ;; Keep this as a CTZ expression until after reload and then split
11324 ;; into RBIT + CLZ.  Since RBIT is represented as an UNSPEC it is unlikely
11325 ;; to fold with any other expression.
11327 (define_insn_and_split "ctzsi2"
11328  [(set (match_operand:SI           0 "s_register_operand" "=r")
11329        (ctz:SI (match_operand:SI  1 "s_register_operand" "r")))]
11330   "TARGET_32BIT && arm_arch_thumb2"
11331   "#"
11332   "&& reload_completed"
11333   [(const_int 0)]
11334   "
11335   emit_insn (gen_rbitsi2 (operands[0], operands[1]));
11336   emit_insn (gen_clzsi2 (operands[0], operands[0]));
11337   DONE;
11340 ;; V5E instructions.
11342 (define_insn "prefetch"
11343   [(prefetch (match_operand:SI 0 "address_operand" "p")
11344              (match_operand:SI 1 "" "")
11345              (match_operand:SI 2 "" ""))]
11346   "TARGET_32BIT && arm_arch5e"
11347   "pld\\t%a0"
11348   [(set_attr "type" "load1")]
11351 ;; General predication pattern
11353 (define_cond_exec
11354   [(match_operator 0 "arm_comparison_operator"
11355     [(match_operand 1 "cc_register" "")
11356      (const_int 0)])]
11357   "TARGET_32BIT
11358    && (!TARGET_NO_VOLATILE_CE || !volatile_refs_p (PATTERN (insn)))"
11359   ""
11360 [(set_attr "predicated" "yes")]
11363 (define_insn "force_register_use"
11364   [(unspec:SI [(match_operand:SI 0 "register_operand" "")] UNSPEC_REGISTER_USE)]
11365   ""
11366   "%@ %0 needed"
11367   [(set_attr "length" "0")
11368    (set_attr "type" "no_insn")]
11372 ;; Patterns for exception handling
11374 (define_expand "eh_return"
11375   [(use (match_operand 0 "general_operand" ""))]
11376   "TARGET_EITHER"
11377   "
11378   {
11379     if (TARGET_32BIT)
11380       emit_insn (gen_arm_eh_return (operands[0]));
11381     else
11382       emit_insn (gen_thumb_eh_return (operands[0]));
11383     DONE;
11384   }"
11386                                    
11387 ;; We can't expand this before we know where the link register is stored.
11388 (define_insn_and_split "arm_eh_return"
11389   [(unspec_volatile [(match_operand:SI 0 "s_register_operand" "r")]
11390                     VUNSPEC_EH_RETURN)
11391    (clobber (match_scratch:SI 1 "=&r"))]
11392   "TARGET_ARM"
11393   "#"
11394   "&& reload_completed"
11395   [(const_int 0)]
11396   "
11397   {
11398     arm_set_return_address (operands[0], operands[1]);
11399     DONE;
11400   }"
11404 ;; TLS support
11406 (define_insn "load_tp_hard"
11407   [(set (match_operand:SI 0 "register_operand" "=r")
11408         (unspec:SI [(const_int 0)] UNSPEC_TLS))]
11409   "TARGET_HARD_TP"
11410   "mrc%?\\tp15, 0, %0, c13, c0, 3\\t@ load_tp_hard"
11411   [(set_attr "predicable" "yes")
11412    (set_attr "type" "mrs")]
11415 ;; Doesn't clobber R1-R3.  Must use r0 for the first operand.
11416 (define_insn "load_tp_soft"
11417   [(set (reg:SI 0) (unspec:SI [(const_int 0)] UNSPEC_TLS))
11418    (clobber (reg:SI LR_REGNUM))
11419    (clobber (reg:SI IP_REGNUM))
11420    (clobber (reg:CC CC_REGNUM))]
11421   "TARGET_SOFT_TP"
11422   "bl\\t__aeabi_read_tp\\t@ load_tp_soft"
11423   [(set_attr "conds" "clob")
11424    (set_attr "type" "branch")]
11427 ;; tls descriptor call
11428 (define_insn "tlscall"
11429   [(set (reg:SI R0_REGNUM)
11430         (unspec:SI [(reg:SI R0_REGNUM)
11431                     (match_operand:SI 0 "" "X")
11432                     (match_operand 1 "" "")] UNSPEC_TLS))
11433    (clobber (reg:SI R1_REGNUM))
11434    (clobber (reg:SI LR_REGNUM))
11435    (clobber (reg:SI CC_REGNUM))]
11436   "TARGET_GNU2_TLS"
11437   {
11438     targetm.asm_out.internal_label (asm_out_file, "LPIC",
11439                                     INTVAL (operands[1]));
11440     return "bl\\t%c0(tlscall)";
11441   }
11442   [(set_attr "conds" "clob")
11443    (set_attr "length" "4")
11444    (set_attr "type" "branch")]
11447 ;; For thread pointer builtin
11448 (define_expand "get_thread_pointersi"
11449   [(match_operand:SI 0 "s_register_operand" "=r")]
11450  ""
11453    arm_load_tp (operands[0]);
11454    DONE;
11455  }")
11459 ;; We only care about the lower 16 bits of the constant 
11460 ;; being inserted into the upper 16 bits of the register.
11461 (define_insn "*arm_movtas_ze" 
11462   [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r,r")
11463                    (const_int 16)
11464                    (const_int 16))
11465         (match_operand:SI 1 "const_int_operand" ""))]
11466   "TARGET_HAVE_MOVT"
11467   "@
11468    movt%?\t%0, %L1
11469    movt\t%0, %L1"
11470  [(set_attr "arch" "32,v8mb")
11471   (set_attr "predicable" "yes")
11472   (set_attr "predicable_short_it" "no")
11473   (set_attr "length" "4")
11474   (set_attr "type" "alu_sreg")]
11477 (define_insn "*arm_rev"
11478   [(set (match_operand:SI 0 "s_register_operand" "=l,l,r")
11479         (bswap:SI (match_operand:SI 1 "s_register_operand" "l,l,r")))]
11480   "arm_arch6"
11481   "@
11482    rev\t%0, %1
11483    rev%?\t%0, %1
11484    rev%?\t%0, %1"
11485   [(set_attr "arch" "t1,t2,32")
11486    (set_attr "length" "2,2,4")
11487    (set_attr "predicable" "no,yes,yes")
11488    (set_attr "predicable_short_it" "no")
11489    (set_attr "type" "rev")]
11492 (define_expand "arm_legacy_rev"
11493   [(set (match_operand:SI 2 "s_register_operand" "")
11494         (xor:SI (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
11495                              (const_int 16))
11496                 (match_dup 1)))
11497    (set (match_dup 2)
11498         (lshiftrt:SI (match_dup 2)
11499                      (const_int 8)))
11500    (set (match_operand:SI 3 "s_register_operand" "")
11501         (rotatert:SI (match_dup 1)
11502                      (const_int 8)))
11503    (set (match_dup 2)
11504         (and:SI (match_dup 2)
11505                 (const_int -65281)))
11506    (set (match_operand:SI 0 "s_register_operand" "")
11507         (xor:SI (match_dup 3)
11508                 (match_dup 2)))]
11509   "TARGET_32BIT"
11510   ""
11513 ;; Reuse temporaries to keep register pressure down.
11514 (define_expand "thumb_legacy_rev"
11515   [(set (match_operand:SI 2 "s_register_operand" "")
11516      (ashift:SI (match_operand:SI 1 "s_register_operand" "")
11517                 (const_int 24)))
11518    (set (match_operand:SI 3 "s_register_operand" "")
11519      (lshiftrt:SI (match_dup 1)
11520                   (const_int 24)))
11521    (set (match_dup 3)
11522      (ior:SI (match_dup 3)
11523              (match_dup 2)))
11524    (set (match_operand:SI 4 "s_register_operand" "")
11525      (const_int 16))
11526    (set (match_operand:SI 5 "s_register_operand" "")
11527      (rotatert:SI (match_dup 1)
11528                   (match_dup 4)))
11529    (set (match_dup 2)
11530      (ashift:SI (match_dup 5)
11531                 (const_int 24)))
11532    (set (match_dup 5)
11533      (lshiftrt:SI (match_dup 5)
11534                   (const_int 24)))
11535    (set (match_dup 5)
11536      (ior:SI (match_dup 5)
11537              (match_dup 2)))
11538    (set (match_dup 5)
11539      (rotatert:SI (match_dup 5)
11540                   (match_dup 4)))
11541    (set (match_operand:SI 0 "s_register_operand" "")
11542      (ior:SI (match_dup 5)
11543              (match_dup 3)))]
11544   "TARGET_THUMB"
11545   ""
11548 ;; ARM-specific expansion of signed mod by power of 2
11549 ;; using conditional negate.
11550 ;; For r0 % n where n is a power of 2 produce:
11551 ;; rsbs    r1, r0, #0
11552 ;; and     r0, r0, #(n - 1)
11553 ;; and     r1, r1, #(n - 1)
11554 ;; rsbpl   r0, r1, #0
11556 (define_expand "modsi3"
11557   [(match_operand:SI 0 "register_operand" "")
11558    (match_operand:SI 1 "register_operand" "")
11559    (match_operand:SI 2 "const_int_operand" "")]
11560   "TARGET_32BIT"
11561   {
11562     HOST_WIDE_INT val = INTVAL (operands[2]);
11564     if (val <= 0
11565        || exact_log2 (val) <= 0)
11566       FAIL;
11568     rtx mask = GEN_INT (val - 1);
11570     /* In the special case of x0 % 2 we can do the even shorter:
11571         cmp     r0, #0
11572         and     r0, r0, #1
11573         rsblt   r0, r0, #0.  */
11575     if (val == 2)
11576       {
11577         rtx cc_reg = arm_gen_compare_reg (LT,
11578                                           operands[1], const0_rtx, NULL_RTX);
11579         rtx cond = gen_rtx_LT (SImode, cc_reg, const0_rtx);
11580         rtx masked = gen_reg_rtx (SImode);
11582         emit_insn (gen_andsi3 (masked, operands[1], mask));
11583         emit_move_insn (operands[0],
11584                         gen_rtx_IF_THEN_ELSE (SImode, cond,
11585                                               gen_rtx_NEG (SImode,
11586                                                            masked),
11587                                               masked));
11588         DONE;
11589       }
11591     rtx neg_op = gen_reg_rtx (SImode);
11592     rtx_insn *insn = emit_insn (gen_subsi3_compare0 (neg_op, const0_rtx,
11593                                                       operands[1]));
11595     /* Extract the condition register and mode.  */
11596     rtx cmp = XVECEXP (PATTERN (insn), 0, 0);
11597     rtx cc_reg = SET_DEST (cmp);
11598     rtx cond = gen_rtx_GE (SImode, cc_reg, const0_rtx);
11600     emit_insn (gen_andsi3 (operands[0], operands[1], mask));
11602     rtx masked_neg = gen_reg_rtx (SImode);
11603     emit_insn (gen_andsi3 (masked_neg, neg_op, mask));
11605     /* We want a conditional negate here, but emitting COND_EXEC rtxes
11606        during expand does not always work.  Do an IF_THEN_ELSE instead.  */
11607     emit_move_insn (operands[0],
11608                     gen_rtx_IF_THEN_ELSE (SImode, cond,
11609                                           gen_rtx_NEG (SImode, masked_neg),
11610                                           operands[0]));
11613     DONE;
11614   }
11617 (define_expand "bswapsi2"
11618   [(set (match_operand:SI 0 "s_register_operand" "=r")
11619         (bswap:SI (match_operand:SI 1 "s_register_operand" "r")))]
11620 "TARGET_EITHER && (arm_arch6 || !optimize_size)"
11622     if (!arm_arch6)
11623       {
11624         rtx op2 = gen_reg_rtx (SImode);
11625         rtx op3 = gen_reg_rtx (SImode);
11627         if (TARGET_THUMB)
11628           {
11629             rtx op4 = gen_reg_rtx (SImode);
11630             rtx op5 = gen_reg_rtx (SImode);
11632             emit_insn (gen_thumb_legacy_rev (operands[0], operands[1],
11633                                              op2, op3, op4, op5));
11634           }
11635         else
11636           {
11637             emit_insn (gen_arm_legacy_rev (operands[0], operands[1],
11638                                            op2, op3));
11639           }
11641         DONE;
11642       }
11643   "
11646 ;; bswap16 patterns: use revsh and rev16 instructions for the signed
11647 ;; and unsigned variants, respectively. For rev16, expose
11648 ;; byte-swapping in the lower 16 bits only.
11649 (define_insn "*arm_revsh"
11650   [(set (match_operand:SI 0 "s_register_operand" "=l,l,r")
11651         (sign_extend:SI (bswap:HI (match_operand:HI 1 "s_register_operand" "l,l,r"))))]
11652   "arm_arch6"
11653   "@
11654   revsh\t%0, %1
11655   revsh%?\t%0, %1
11656   revsh%?\t%0, %1"
11657   [(set_attr "arch" "t1,t2,32")
11658    (set_attr "length" "2,2,4")
11659    (set_attr "type" "rev")]
11662 (define_insn "*arm_rev16"
11663   [(set (match_operand:HI 0 "s_register_operand" "=l,l,r")
11664         (bswap:HI (match_operand:HI 1 "s_register_operand" "l,l,r")))]
11665   "arm_arch6"
11666   "@
11667    rev16\t%0, %1
11668    rev16%?\t%0, %1
11669    rev16%?\t%0, %1"
11670   [(set_attr "arch" "t1,t2,32")
11671    (set_attr "length" "2,2,4")
11672    (set_attr "type" "rev")]
11675 ;; There are no canonicalisation rules for the position of the lshiftrt, ashift
11676 ;; operations within an IOR/AND RTX, therefore we have two patterns matching
11677 ;; each valid permutation.
11679 (define_insn "arm_rev16si2"
11680   [(set (match_operand:SI 0 "register_operand" "=l,l,r")
11681         (ior:SI (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "l,l,r")
11682                                    (const_int 8))
11683                         (match_operand:SI 3 "const_int_operand" "n,n,n"))
11684                 (and:SI (lshiftrt:SI (match_dup 1)
11685                                      (const_int 8))
11686                         (match_operand:SI 2 "const_int_operand" "n,n,n"))))]
11687   "arm_arch6
11688    && aarch_rev16_shleft_mask_imm_p (operands[3], SImode)
11689    && aarch_rev16_shright_mask_imm_p (operands[2], SImode)"
11690   "rev16\\t%0, %1"
11691   [(set_attr "arch" "t1,t2,32")
11692    (set_attr "length" "2,2,4")
11693    (set_attr "type" "rev")]
11696 (define_insn "arm_rev16si2_alt"
11697   [(set (match_operand:SI 0 "register_operand" "=l,l,r")
11698         (ior:SI (and:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "l,l,r")
11699                                      (const_int 8))
11700                         (match_operand:SI 2 "const_int_operand" "n,n,n"))
11701                 (and:SI (ashift:SI (match_dup 1)
11702                                    (const_int 8))
11703                         (match_operand:SI 3 "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_expand "bswaphi2"
11714   [(set (match_operand:HI 0 "s_register_operand" "=r")
11715         (bswap:HI (match_operand:HI 1 "s_register_operand" "r")))]
11716 "arm_arch6"
11720 ;; Patterns for LDRD/STRD in Thumb2 mode
11722 (define_insn "*thumb2_ldrd"
11723   [(set (match_operand:SI 0 "s_register_operand" "=r")
11724         (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "rk")
11725                          (match_operand:SI 2 "ldrd_strd_offset_operand" "Do"))))
11726    (set (match_operand:SI 3 "s_register_operand" "=r")
11727         (mem:SI (plus:SI (match_dup 1)
11728                          (match_operand:SI 4 "const_int_operand" ""))))]
11729   "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11730      && ((INTVAL (operands[2]) + 4) == INTVAL (operands[4]))
11731      && (operands_ok_ldrd_strd (operands[0], operands[3],
11732                                   operands[1], INTVAL (operands[2]),
11733                                   false, true))"
11734   "ldrd%?\t%0, %3, [%1, %2]"
11735   [(set_attr "type" "load2")
11736    (set_attr "predicable" "yes")
11737    (set_attr "predicable_short_it" "no")])
11739 (define_insn "*thumb2_ldrd_base"
11740   [(set (match_operand:SI 0 "s_register_operand" "=r")
11741         (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
11742    (set (match_operand:SI 2 "s_register_operand" "=r")
11743         (mem:SI (plus:SI (match_dup 1)
11744                          (const_int 4))))]
11745   "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11746      && (operands_ok_ldrd_strd (operands[0], operands[2],
11747                                   operands[1], 0, false, true))"
11748   "ldrd%?\t%0, %2, [%1]"
11749   [(set_attr "type" "load2")
11750    (set_attr "predicable" "yes")
11751    (set_attr "predicable_short_it" "no")])
11753 (define_insn "*thumb2_ldrd_base_neg"
11754   [(set (match_operand:SI 0 "s_register_operand" "=r")
11755         (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "rk")
11756                          (const_int -4))))
11757    (set (match_operand:SI 2 "s_register_operand" "=r")
11758         (mem:SI (match_dup 1)))]
11759   "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11760      && (operands_ok_ldrd_strd (operands[0], operands[2],
11761                                   operands[1], -4, false, true))"
11762   "ldrd%?\t%0, %2, [%1, #-4]"
11763   [(set_attr "type" "load2")
11764    (set_attr "predicable" "yes")
11765    (set_attr "predicable_short_it" "no")])
11767 (define_insn "*thumb2_strd"
11768   [(set (mem:SI (plus:SI (match_operand:SI 0 "s_register_operand" "rk")
11769                          (match_operand:SI 1 "ldrd_strd_offset_operand" "Do")))
11770         (match_operand:SI 2 "s_register_operand" "r"))
11771    (set (mem:SI (plus:SI (match_dup 0)
11772                          (match_operand:SI 3 "const_int_operand" "")))
11773         (match_operand:SI 4 "s_register_operand" "r"))]
11774   "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11775      && ((INTVAL (operands[1]) + 4) == INTVAL (operands[3]))
11776      && (operands_ok_ldrd_strd (operands[2], operands[4],
11777                                   operands[0], INTVAL (operands[1]),
11778                                   false, false))"
11779   "strd%?\t%2, %4, [%0, %1]"
11780   [(set_attr "type" "store2")
11781    (set_attr "predicable" "yes")
11782    (set_attr "predicable_short_it" "no")])
11784 (define_insn "*thumb2_strd_base"
11785   [(set (mem:SI (match_operand:SI 0 "s_register_operand" "rk"))
11786         (match_operand:SI 1 "s_register_operand" "r"))
11787    (set (mem:SI (plus:SI (match_dup 0)
11788                          (const_int 4)))
11789         (match_operand:SI 2 "s_register_operand" "r"))]
11790   "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11791      && (operands_ok_ldrd_strd (operands[1], operands[2],
11792                                   operands[0], 0, false, false))"
11793   "strd%?\t%1, %2, [%0]"
11794   [(set_attr "type" "store2")
11795    (set_attr "predicable" "yes")
11796    (set_attr "predicable_short_it" "no")])
11798 (define_insn "*thumb2_strd_base_neg"
11799   [(set (mem:SI (plus:SI (match_operand:SI 0 "s_register_operand" "rk")
11800                          (const_int -4)))
11801         (match_operand:SI 1 "s_register_operand" "r"))
11802    (set (mem:SI (match_dup 0))
11803         (match_operand:SI 2 "s_register_operand" "r"))]
11804   "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11805      && (operands_ok_ldrd_strd (operands[1], operands[2],
11806                                   operands[0], -4, false, false))"
11807   "strd%?\t%1, %2, [%0, #-4]"
11808   [(set_attr "type" "store2")
11809    (set_attr "predicable" "yes")
11810    (set_attr "predicable_short_it" "no")])
11812 ;; ARMv8 CRC32 instructions.
11813 (define_insn "<crc_variant>"
11814   [(set (match_operand:SI 0 "s_register_operand" "=r")
11815         (unspec:SI [(match_operand:SI 1 "s_register_operand" "r")
11816                     (match_operand:<crc_mode> 2 "s_register_operand" "r")]
11817          CRC))]
11818   "TARGET_CRC32"
11819   "<crc_variant>\\t%0, %1, %2"
11820   [(set_attr "type" "crc")
11821    (set_attr "conds" "unconditional")]
11824 ;; Load the load/store double peephole optimizations.
11825 (include "ldrdstrd.md")
11827 ;; Load the load/store multiple patterns
11828 (include "ldmstm.md")
11830 ;; Patterns in ldmstm.md don't cover more than 4 registers. This pattern covers
11831 ;; large lists without explicit writeback generated for APCS_FRAME epilogue.
11832 ;; The operands are validated through the load_multiple_operation
11833 ;; match_parallel predicate rather than through constraints so enable it only
11834 ;; after reload.
11835 (define_insn "*load_multiple"
11836   [(match_parallel 0 "load_multiple_operation"
11837     [(set (match_operand:SI 2 "s_register_operand" "=rk")
11838           (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
11839         ])]
11840   "TARGET_32BIT && reload_completed"
11841   "*
11842   {
11843     arm_output_multireg_pop (operands, /*return_pc=*/false,
11844                                        /*cond=*/const_true_rtx,
11845                                        /*reverse=*/false,
11846                                        /*update=*/false);
11847     return \"\";
11848   }
11849   "
11850   [(set_attr "predicable" "yes")]
11853 (define_expand "copysignsf3"
11854   [(match_operand:SF 0 "register_operand")
11855    (match_operand:SF 1 "register_operand")
11856    (match_operand:SF 2 "register_operand")]
11857   "TARGET_SOFT_FLOAT && arm_arch_thumb2"
11858   "{
11859      emit_move_insn (operands[0], operands[2]);
11860      emit_insn (gen_insv_t2 (simplify_gen_subreg (SImode, operands[0], SFmode, 0),
11861                 GEN_INT (31), GEN_INT (0),
11862                 simplify_gen_subreg (SImode, operands[1], SFmode, 0)));
11863      DONE;
11864   }"
11867 (define_expand "copysigndf3"
11868   [(match_operand:DF 0 "register_operand")
11869    (match_operand:DF 1 "register_operand")
11870    (match_operand:DF 2 "register_operand")]
11871   "TARGET_SOFT_FLOAT && arm_arch_thumb2"
11872   "{
11873      rtx op0_low = gen_lowpart (SImode, operands[0]);
11874      rtx op0_high = gen_highpart (SImode, operands[0]);
11875      rtx op1_low = gen_lowpart (SImode, operands[1]);
11876      rtx op1_high = gen_highpart (SImode, operands[1]);
11877      rtx op2_high = gen_highpart (SImode, operands[2]);
11879      rtx scratch1 = gen_reg_rtx (SImode);
11880      rtx scratch2 = gen_reg_rtx (SImode);
11881      emit_move_insn (scratch1, op2_high);
11882      emit_move_insn (scratch2, op1_high);
11884      emit_insn(gen_rtx_SET(scratch1,
11885                            gen_rtx_LSHIFTRT (SImode, op2_high, GEN_INT(31))));
11886      emit_insn(gen_insv_t2(scratch2, GEN_INT(1), GEN_INT(31), scratch1));
11887      emit_move_insn (op0_low, op1_low);
11888      emit_move_insn (op0_high, scratch2);
11890      DONE;
11891   }"
11894 ;; movmisalign patterns for HImode and SImode.
11895 (define_expand "movmisalign<mode>"
11896   [(match_operand:HSI 0 "general_operand")
11897    (match_operand:HSI 1 "general_operand")]
11898   "unaligned_access"
11900   /* This pattern is not permitted to fail during expansion: if both arguments
11901      are non-registers (e.g. memory := constant), force operand 1 into a
11902      register.  */
11903   rtx (* gen_unaligned_load)(rtx, rtx);
11904   rtx tmp_dest = operands[0];
11905   if (!s_register_operand (operands[0], <MODE>mode)
11906       && !s_register_operand (operands[1], <MODE>mode))
11907     operands[1] = force_reg (<MODE>mode, operands[1]);
11909   if (<MODE>mode == HImode)
11910    {
11911     gen_unaligned_load = gen_unaligned_loadhiu;
11912     tmp_dest = gen_reg_rtx (SImode);
11913    }
11914   else
11915     gen_unaligned_load = gen_unaligned_loadsi;
11917   if (MEM_P (operands[1]))
11918    {
11919     emit_insn (gen_unaligned_load (tmp_dest, operands[1]));
11920     if (<MODE>mode == HImode)
11921       emit_move_insn (operands[0], gen_lowpart (HImode, tmp_dest));
11922    }
11923   else
11924     emit_insn (gen_unaligned_store<mode> (operands[0], operands[1]));
11926   DONE;
11929 (define_insn "<cdp>"
11930   [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "n")
11931                      (match_operand:SI 1 "immediate_operand" "n")
11932                      (match_operand:SI 2 "immediate_operand" "n")
11933                      (match_operand:SI 3 "immediate_operand" "n")
11934                      (match_operand:SI 4 "immediate_operand" "n")
11935                      (match_operand:SI 5 "immediate_operand" "n")] CDPI)]
11936   "arm_coproc_builtin_available (VUNSPEC_<CDP>)"
11938   arm_const_bounds (operands[0], 0, 16);
11939   arm_const_bounds (operands[1], 0, 16);
11940   arm_const_bounds (operands[2], 0, (1 << 5));
11941   arm_const_bounds (operands[3], 0, (1 << 5));
11942   arm_const_bounds (operands[4], 0, (1 << 5));
11943   arm_const_bounds (operands[5], 0, 8);
11944   return "<cdp>\\tp%c0, %1, CR%c2, CR%c3, CR%c4, %5";
11946   [(set_attr "length" "4")
11947    (set_attr "type" "coproc")])
11949 (define_insn "*ldc"
11950   [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "n")
11951                      (match_operand:SI 1 "immediate_operand" "n")
11952                      (match_operand:SI 2 "memory_operand" "Uz")] LDCI)]
11953   "arm_coproc_builtin_available (VUNSPEC_<LDC>)"
11955   arm_const_bounds (operands[0], 0, 16);
11956   arm_const_bounds (operands[1], 0, (1 << 5));
11957   return "<ldc>\\tp%c0, CR%c1, %2";
11959   [(set_attr "length" "4")
11960    (set_attr "type" "coproc")])
11962 (define_insn "*stc"
11963   [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "n")
11964                      (match_operand:SI 1 "immediate_operand" "n")
11965                      (match_operand:SI 2 "memory_operand" "=Uz")] STCI)]
11966   "arm_coproc_builtin_available (VUNSPEC_<STC>)"
11968   arm_const_bounds (operands[0], 0, 16);
11969   arm_const_bounds (operands[1], 0, (1 << 5));
11970   return "<stc>\\tp%c0, CR%c1, %2";
11972   [(set_attr "length" "4")
11973    (set_attr "type" "coproc")])
11975 (define_expand "<ldc>"
11976   [(unspec_volatile [(match_operand:SI 0 "immediate_operand")
11977                      (match_operand:SI 1 "immediate_operand")
11978                      (mem:SI (match_operand:SI 2 "s_register_operand"))] LDCI)]
11979   "arm_coproc_builtin_available (VUNSPEC_<LDC>)")
11981 (define_expand "<stc>"
11982   [(unspec_volatile [(match_operand:SI 0 "immediate_operand")
11983                      (match_operand:SI 1 "immediate_operand")
11984                      (mem:SI (match_operand:SI 2 "s_register_operand"))] STCI)]
11985   "arm_coproc_builtin_available (VUNSPEC_<STC>)")
11987 (define_insn "<mcr>"
11988   [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "n")
11989                      (match_operand:SI 1 "immediate_operand" "n")
11990                      (match_operand:SI 2 "s_register_operand" "r")
11991                      (match_operand:SI 3 "immediate_operand" "n")
11992                      (match_operand:SI 4 "immediate_operand" "n")
11993                      (match_operand:SI 5 "immediate_operand" "n")] MCRI)
11994    (use (match_dup 2))]
11995   "arm_coproc_builtin_available (VUNSPEC_<MCR>)"
11997   arm_const_bounds (operands[0], 0, 16);
11998   arm_const_bounds (operands[1], 0, 8);
11999   arm_const_bounds (operands[3], 0, (1 << 5));
12000   arm_const_bounds (operands[4], 0, (1 << 5));
12001   arm_const_bounds (operands[5], 0, 8);
12002   return "<mcr>\\tp%c0, %1, %2, CR%c3, CR%c4, %5";
12004   [(set_attr "length" "4")
12005    (set_attr "type" "coproc")])
12007 (define_insn "<mrc>"
12008   [(set (match_operand:SI 0 "s_register_operand" "=r")
12009         (unspec_volatile:SI [(match_operand:SI 1 "immediate_operand" "n")
12010                           (match_operand:SI 2 "immediate_operand" "n")
12011                           (match_operand:SI 3 "immediate_operand" "n")
12012                           (match_operand:SI 4 "immediate_operand" "n")
12013                           (match_operand:SI 5 "immediate_operand" "n")] MRCI))]
12014   "arm_coproc_builtin_available (VUNSPEC_<MRC>)"
12016   arm_const_bounds (operands[1], 0, 16);
12017   arm_const_bounds (operands[2], 0, 8);
12018   arm_const_bounds (operands[3], 0, (1 << 5));
12019   arm_const_bounds (operands[4], 0, (1 << 5));
12020   arm_const_bounds (operands[5], 0, 8);
12021   return "<mrc>\\tp%c1, %2, %0, CR%c3, CR%c4, %5";
12023   [(set_attr "length" "4")
12024    (set_attr "type" "coproc")])
12026 (define_insn "<mcrr>"
12027   [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "n")
12028                      (match_operand:SI 1 "immediate_operand" "n")
12029                      (match_operand:DI 2 "s_register_operand" "r")
12030                      (match_operand:SI 3 "immediate_operand" "n")] MCRRI)
12031    (use (match_dup 2))]
12032   "arm_coproc_builtin_available (VUNSPEC_<MCRR>)"
12034   arm_const_bounds (operands[0], 0, 16);
12035   arm_const_bounds (operands[1], 0, 8);
12036   arm_const_bounds (operands[3], 0, (1 << 5));
12037   return "<mcrr>\\tp%c0, %1, %Q2, %R2, CR%c3";
12039   [(set_attr "length" "4")
12040    (set_attr "type" "coproc")])
12042 (define_insn "<mrrc>"
12043   [(set (match_operand:DI 0 "s_register_operand" "=r")
12044         (unspec_volatile:DI [(match_operand:SI 1 "immediate_operand" "n")
12045                           (match_operand:SI 2 "immediate_operand" "n")
12046                           (match_operand:SI 3 "immediate_operand" "n")] MRRCI))]
12047   "arm_coproc_builtin_available (VUNSPEC_<MRRC>)"
12049   arm_const_bounds (operands[1], 0, 16);
12050   arm_const_bounds (operands[2], 0, 8);
12051   arm_const_bounds (operands[3], 0, (1 << 5));
12052   return "<mrrc>\\tp%c1, %2, %Q0, %R0, CR%c3";
12054   [(set_attr "length" "4")
12055    (set_attr "type" "coproc")])
12057 ;; Vector bits common to IWMMXT and Neon
12058 (include "vec-common.md")
12059 ;; Load the Intel Wireless Multimedia Extension patterns
12060 (include "iwmmxt.md")
12061 ;; Load the VFP co-processor patterns
12062 (include "vfp.md")
12063 ;; Thumb-1 patterns
12064 (include "thumb1.md")
12065 ;; Thumb-2 patterns
12066 (include "thumb2.md")
12067 ;; Neon patterns
12068 (include "neon.md")
12069 ;; Crypto patterns
12070 (include "crypto.md")
12071 ;; Synchronization Primitives
12072 (include "sync.md")
12073 ;; Fixed-point patterns
12074 (include "arm-fixed.md")