2016-07-13 Thomas Preud'homme <thomas.preudhomme@arm.com>
[official-gcc.git] / gcc / config / arm / arm.md
blob8727c6df16ea95007dfcdb3249a8467ede3d72ac
1 ;;- Machine description for ARM for GNU compiler
2 ;;  Copyright (C) 1991-2016 Free Software Foundation, Inc.
3 ;;  Contributed by Pieter `Tiggr' Schoenmakers (rcpieter@win.tue.nl)
4 ;;  and Martin Simmons (@harleqn.co.uk).
5 ;;  More major hacks by Richard Earnshaw (rearnsha@arm.com).
7 ;; This file is part of GCC.
9 ;; GCC is free software; you can redistribute it and/or modify it
10 ;; under the terms of the GNU General Public License as published
11 ;; by the Free Software Foundation; either version 3, or (at your
12 ;; option) any later version.
14 ;; GCC is distributed in the hope that it will be useful, but WITHOUT
15 ;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16 ;; or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
17 ;; License for more details.
19 ;; You should have received a copy of the GNU General Public License
20 ;; along with GCC; see the file COPYING3.  If not see
21 ;; <http://www.gnu.org/licenses/>.
23 ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
26 ;;---------------------------------------------------------------------------
27 ;; Constants
29 ;; Register numbers -- All machine registers should be defined here
30 (define_constants
31   [(R0_REGNUM         0)        ; First CORE register
32    (R1_REGNUM         1)        ; Second CORE register
33    (IP_REGNUM        12)        ; Scratch register
34    (SP_REGNUM        13)        ; Stack pointer
35    (LR_REGNUM        14)        ; Return address register
36    (PC_REGNUM        15)        ; Program counter
37    (LAST_ARM_REGNUM  15)        ;
38    (CC_REGNUM       100)        ; Condition code pseudo register
39    (VFPCC_REGNUM    101)        ; VFP Condition code pseudo register
40   ]
42 ;; 3rd operand to select_dominance_cc_mode
43 (define_constants
44   [(DOM_CC_X_AND_Y  0)
45    (DOM_CC_NX_OR_Y  1)
46    (DOM_CC_X_OR_Y   2)
47   ]
49 ;; conditional compare combination
50 (define_constants
51   [(CMP_CMP 0)
52    (CMN_CMP 1)
53    (CMP_CMN 2)
54    (CMN_CMN 3)
55    (NUM_OF_COND_CMP 4)
56   ]
60 ;;---------------------------------------------------------------------------
61 ;; Attributes
63 ;; Processor type.  This is created automatically from arm-cores.def.
64 (include "arm-tune.md")
66 ;; Instruction classification types
67 (include "types.md")
69 ; IS_THUMB is set to 'yes' when we are generating Thumb code, and 'no' when
70 ; generating ARM code.  This is used to control the length of some insn
71 ; patterns that share the same RTL in both ARM and Thumb code.
72 (define_attr "is_thumb" "yes,no"
73   (const (if_then_else (symbol_ref "TARGET_THUMB")
74                        (const_string "yes") (const_string "no"))))
76 ; IS_ARCH6 is set to 'yes' when we are generating code form ARMv6.
77 (define_attr "is_arch6" "no,yes" (const (symbol_ref "arm_arch6")))
79 ; IS_THUMB1 is set to 'yes' iff we are generating Thumb-1 code.
80 (define_attr "is_thumb1" "yes,no"
81   (const (if_then_else (symbol_ref "TARGET_THUMB1")
82                        (const_string "yes") (const_string "no"))))
84 ; We use this attribute to disable alternatives that can produce 32-bit
85 ; instructions inside an IT-block in Thumb2 state.  ARMv8 deprecates IT blocks
86 ; that contain 32-bit instructions.
87 (define_attr "enabled_for_depr_it" "no,yes" (const_string "yes"))
89 ; This attribute is used to disable a predicated alternative when we have
90 ; arm_restrict_it.
91 (define_attr "predicable_short_it" "no,yes" (const_string "yes"))
93 ;; Operand number of an input operand that is shifted.  Zero if the
94 ;; given instruction does not shift one of its input operands.
95 (define_attr "shift" "" (const_int 0))
97 ;; [For compatibility with AArch64 in pipeline models]
98 ;; Attribute that specifies whether or not the instruction touches fp
99 ;; registers.
100 (define_attr "fp" "no,yes" (const_string "no"))
102 ; Floating Point Unit.  If we only have floating point emulation, then there
103 ; is no point in scheduling the floating point insns.  (Well, for best
104 ; performance we should try and group them together).
105 (define_attr "fpu" "none,vfp"
106   (const (symbol_ref "arm_fpu_attr")))
108 ; Predicated means that the insn form is conditionally executed based on a
109 ; predicate.  We default to 'no' because no Thumb patterns match this rule
110 ; and not all ARM insns do.
111 (define_attr "predicated" "yes,no" (const_string "no"))
113 ; LENGTH of an instruction (in bytes)
114 (define_attr "length" ""
115   (const_int 4))
117 ; The architecture which supports the instruction (or alternative).
118 ; This can be "a" for ARM, "t" for either of the Thumbs, "32" for
119 ; TARGET_32BIT, "t1" or "t2" to specify a specific Thumb mode.  "v6"
120 ; for ARM or Thumb-2 with arm_arch6, and nov6 for ARM without
121 ; arm_arch6.  "v6t2" for Thumb-2 with arm_arch6 and "v8mb" for ARMv8-M
122 ; Baseline.  This attribute is used to compute attribute "enabled",
123 ; use type "any" to enable an alternative in all cases.
124 (define_attr "arch" "any,a,t,32,t1,t2,v6,nov6,v6t2,v8mb,neon_for_64bits,avoid_neon_for_64bits,iwmmxt,iwmmxt2,armv6_or_vfpv3,neon"
125   (const_string "any"))
127 (define_attr "arch_enabled" "no,yes"
128   (cond [(eq_attr "arch" "any")
129          (const_string "yes")
131          (and (eq_attr "arch" "a")
132               (match_test "TARGET_ARM"))
133          (const_string "yes")
135          (and (eq_attr "arch" "t")
136               (match_test "TARGET_THUMB"))
137          (const_string "yes")
139          (and (eq_attr "arch" "t1")
140               (match_test "TARGET_THUMB1"))
141          (const_string "yes")
143          (and (eq_attr "arch" "t2")
144               (match_test "TARGET_THUMB2"))
145          (const_string "yes")
147          (and (eq_attr "arch" "32")
148               (match_test "TARGET_32BIT"))
149          (const_string "yes")
151          (and (eq_attr "arch" "v6")
152               (match_test "TARGET_32BIT && arm_arch6"))
153          (const_string "yes")
155          (and (eq_attr "arch" "nov6")
156               (match_test "TARGET_32BIT && !arm_arch6"))
157          (const_string "yes")
159          (and (eq_attr "arch" "v6t2")
160               (match_test "TARGET_32BIT && arm_arch6 && arm_arch_thumb2"))
161          (const_string "yes")
163          (and (eq_attr "arch" "v8mb")
164               (match_test "TARGET_THUMB1 && arm_arch8"))
165          (const_string "yes")
167          (and (eq_attr "arch" "avoid_neon_for_64bits")
168               (match_test "TARGET_NEON")
169               (not (match_test "TARGET_PREFER_NEON_64BITS")))
170          (const_string "yes")
172          (and (eq_attr "arch" "neon_for_64bits")
173               (match_test "TARGET_NEON")
174               (match_test "TARGET_PREFER_NEON_64BITS"))
175          (const_string "yes")
177          (and (eq_attr "arch" "iwmmxt2")
178               (match_test "TARGET_REALLY_IWMMXT2"))
179          (const_string "yes")
181          (and (eq_attr "arch" "armv6_or_vfpv3")
182               (match_test "arm_arch6 || TARGET_VFP3"))
183          (const_string "yes")
185          (and (eq_attr "arch" "neon")
186               (match_test "TARGET_NEON"))
187          (const_string "yes")
188         ]
190         (const_string "no")))
192 (define_attr "opt" "any,speed,size"
193   (const_string "any"))
195 (define_attr "opt_enabled" "no,yes"
196   (cond [(eq_attr "opt" "any")
197          (const_string "yes")
199          (and (eq_attr "opt" "speed")
200               (match_test "optimize_function_for_speed_p (cfun)"))
201          (const_string "yes")
203          (and (eq_attr "opt" "size")
204               (match_test "optimize_function_for_size_p (cfun)"))
205          (const_string "yes")]
206         (const_string "no")))
208 (define_attr "use_literal_pool" "no,yes"
209    (cond [(and (eq_attr "type" "f_loads,f_loadd")
210                (match_test "CONSTANT_P (operands[1])"))
211           (const_string "yes")]
212          (const_string "no")))
214 ; Enable all alternatives that are both arch_enabled and insn_enabled.
215 ; FIXME:: opt_enabled has been temporarily removed till the time we have
216 ; an attribute that allows the use of such alternatives.
217 ; This depends on caching of speed_p, size_p on a per
218 ; alternative basis. The problem is that the enabled attribute
219 ; cannot depend on any state that is not cached or is not constant
220 ; for a compilation unit. We probably need a generic "hot/cold"
221 ; alternative which if implemented can help with this. We disable this
222 ; until such a time as this is implemented and / or the improvements or
223 ; regressions with removing this attribute are double checked.
224 ; See ashldi3_neon and <shift>di3_neon in neon.md.
226  (define_attr "enabled" "no,yes"
227    (cond [(and (eq_attr "predicable_short_it" "no")
228                (and (eq_attr "predicated" "yes")
229                     (match_test "arm_restrict_it")))
230           (const_string "no")
232           (and (eq_attr "enabled_for_depr_it" "no")
233                (match_test "arm_restrict_it"))
234           (const_string "no")
236           (and (eq_attr "use_literal_pool" "yes")
237                (match_test "arm_disable_literal_pool"))
238           (const_string "no")
240           (eq_attr "arch_enabled" "no")
241           (const_string "no")]
242          (const_string "yes")))
244 ; POOL_RANGE is how far away from a constant pool entry that this insn
245 ; can be placed.  If the distance is zero, then this insn will never
246 ; reference the pool.
247 ; Note that for Thumb constant pools the PC value is rounded down to the
248 ; nearest multiple of four.  Therefore, THUMB2_POOL_RANGE (and POOL_RANGE for
249 ; Thumb insns) should be set to <max_range> - 2.
250 ; NEG_POOL_RANGE is nonzero for insns that can reference a constant pool entry
251 ; before its address.  It is set to <max_range> - (8 + <data_size>).
252 (define_attr "arm_pool_range" "" (const_int 0))
253 (define_attr "thumb2_pool_range" "" (const_int 0))
254 (define_attr "arm_neg_pool_range" "" (const_int 0))
255 (define_attr "thumb2_neg_pool_range" "" (const_int 0))
257 (define_attr "pool_range" ""
258   (cond [(eq_attr "is_thumb" "yes") (attr "thumb2_pool_range")]
259         (attr "arm_pool_range")))
260 (define_attr "neg_pool_range" ""
261   (cond [(eq_attr "is_thumb" "yes") (attr "thumb2_neg_pool_range")]
262         (attr "arm_neg_pool_range")))
264 ; An assembler sequence may clobber the condition codes without us knowing.
265 ; If such an insn references the pool, then we have no way of knowing how,
266 ; so use the most conservative value for pool_range.
267 (define_asm_attributes
268  [(set_attr "conds" "clob")
269   (set_attr "length" "4")
270   (set_attr "pool_range" "250")])
272 ; Load scheduling, set from the arm_ld_sched variable
273 ; initialized by arm_option_override()
274 (define_attr "ldsched" "no,yes" (const (symbol_ref "arm_ld_sched")))
276 ; condition codes: this one is used by final_prescan_insn to speed up
277 ; conditionalizing instructions.  It saves having to scan the rtl to see if
278 ; it uses or alters the condition codes.
280 ; USE means that the condition codes are used by the insn in the process of
281 ;   outputting code, this means (at present) that we can't use the insn in
282 ;   inlined branches
284 ; SET means that the purpose of the insn is to set the condition codes in a
285 ;   well defined manner.
287 ; CLOB means that the condition codes are altered in an undefined manner, if
288 ;   they are altered at all
290 ; UNCONDITIONAL means the instruction can not be conditionally executed and
291 ;   that the instruction does not use or alter the condition codes.
293 ; NOCOND means that the instruction does not use or alter the condition
294 ;   codes but can be converted into a conditionally exectuted instruction.
296 (define_attr "conds" "use,set,clob,unconditional,nocond"
297         (if_then_else
298          (ior (eq_attr "is_thumb1" "yes")
299               (eq_attr "type" "call"))
300          (const_string "clob")
301          (if_then_else (eq_attr "is_neon_type" "no")
302          (const_string "nocond")
303          (const_string "unconditional"))))
305 ; Predicable means that the insn can be conditionally executed based on
306 ; an automatically added predicate (additional patterns are generated by 
307 ; gen...).  We default to 'no' because no Thumb patterns match this rule
308 ; and not all ARM patterns do.
309 (define_attr "predicable" "no,yes" (const_string "no"))
311 ; Only model the write buffer for ARM6 and ARM7.  Earlier processors don't
312 ; have one.  Later ones, such as StrongARM, have write-back caches, so don't
313 ; suffer blockages enough to warrant modelling this (and it can adversely
314 ; affect the schedule).
315 (define_attr "model_wbuf" "no,yes" (const (symbol_ref "arm_tune_wbuf")))
317 ; WRITE_CONFLICT implies that a read following an unrelated write is likely
318 ; to stall the processor.  Used with model_wbuf above.
319 (define_attr "write_conflict" "no,yes"
320   (if_then_else (eq_attr "type"
321                  "block,call,load1")
322                 (const_string "yes")
323                 (const_string "no")))
325 ; Classify the insns into those that take one cycle and those that take more
326 ; than one on the main cpu execution unit.
327 (define_attr "core_cycles" "single,multi"
328   (if_then_else (eq_attr "type"
329     "adc_imm, adc_reg, adcs_imm, adcs_reg, adr, alu_ext, alu_imm, alu_sreg,\
330     alu_shift_imm, alu_shift_reg, alu_dsp_reg, alus_ext, alus_imm, alus_sreg,\
331     alus_shift_imm, alus_shift_reg, bfm, csel, rev, logic_imm, logic_reg,\
332     logic_shift_imm, logic_shift_reg, logics_imm, logics_reg,\
333     logics_shift_imm, logics_shift_reg, extend, shift_imm, float, fcsel,\
334     wmmx_wor, wmmx_wxor, wmmx_wand, wmmx_wandn, wmmx_wmov, wmmx_tmcrr,\
335     wmmx_tmrrc, wmmx_wldr, wmmx_wstr, wmmx_tmcr, wmmx_tmrc, wmmx_wadd,\
336     wmmx_wsub, wmmx_wmul, wmmx_wmac, wmmx_wavg2, wmmx_tinsr, wmmx_textrm,\
337     wmmx_wshufh, wmmx_wcmpeq, wmmx_wcmpgt, wmmx_wmax, wmmx_wmin, wmmx_wpack,\
338     wmmx_wunpckih, wmmx_wunpckil, wmmx_wunpckeh, wmmx_wunpckel, wmmx_wror,\
339     wmmx_wsra, wmmx_wsrl, wmmx_wsll, wmmx_wmadd, wmmx_tmia, wmmx_tmiaph,\
340     wmmx_tmiaxy, wmmx_tbcst, wmmx_tmovmsk, wmmx_wacc, wmmx_waligni,\
341     wmmx_walignr, wmmx_tandc, wmmx_textrc, wmmx_torc, wmmx_torvsc, wmmx_wsad,\
342     wmmx_wabs, wmmx_wabsdiff, wmmx_waddsubhx, wmmx_wsubaddhx, wmmx_wavg4,\
343     wmmx_wmulw, wmmx_wqmulm, wmmx_wqmulwm, wmmx_waddbhus, wmmx_wqmiaxy,\
344     wmmx_wmiaxy, wmmx_wmiawxy, wmmx_wmerge")
345                 (const_string "single")
346                 (const_string "multi")))
348 ;; FAR_JUMP is "yes" if a BL instruction is used to generate a branch to a
349 ;; distant label.  Only applicable to Thumb code.
350 (define_attr "far_jump" "yes,no" (const_string "no"))
353 ;; The number of machine instructions this pattern expands to.
354 ;; Used for Thumb-2 conditional execution.
355 (define_attr "ce_count" "" (const_int 1))
357 ;;---------------------------------------------------------------------------
358 ;; Unspecs
360 (include "unspecs.md")
362 ;;---------------------------------------------------------------------------
363 ;; Mode iterators
365 (include "iterators.md")
367 ;;---------------------------------------------------------------------------
368 ;; Predicates
370 (include "predicates.md")
371 (include "constraints.md")
373 ;;---------------------------------------------------------------------------
374 ;; Pipeline descriptions
376 (define_attr "tune_cortexr4" "yes,no"
377   (const (if_then_else
378           (eq_attr "tune" "cortexr4,cortexr4f,cortexr5")
379           (const_string "yes")
380           (const_string "no"))))
382 ;; True if the generic scheduling description should be used.
384 (define_attr "generic_sched" "yes,no"
385   (const (if_then_else
386           (ior (eq_attr "tune" "fa526,fa626,fa606te,fa626te,fmp626,fa726te,\
387                                 arm926ejs,arm1020e,arm1026ejs,arm1136js,\
388                                 arm1136jfs,cortexa5,cortexa7,cortexa8,\
389                                 cortexa9,cortexa12,cortexa15,cortexa17,\
390                                 cortexa53,cortexa57,cortexm4,cortexm7,\
391                                 exynosm1,marvell_pj4,xgene1")
392                (eq_attr "tune_cortexr4" "yes"))
393           (const_string "no")
394           (const_string "yes"))))
396 (define_attr "generic_vfp" "yes,no"
397   (const (if_then_else
398           (and (eq_attr "fpu" "vfp")
399                (eq_attr "tune" "!arm1020e,arm1022e,cortexa5,cortexa7,\
400                                 cortexa8,cortexa9,cortexa53,cortexm4,\
401                                 cortexm7,marvell_pj4,xgene1")
402                (eq_attr "tune_cortexr4" "no"))
403           (const_string "yes")
404           (const_string "no"))))
406 (include "marvell-f-iwmmxt.md")
407 (include "arm-generic.md")
408 (include "arm926ejs.md")
409 (include "arm1020e.md")
410 (include "arm1026ejs.md")
411 (include "arm1136jfs.md")
412 (include "fa526.md")
413 (include "fa606te.md")
414 (include "fa626te.md")
415 (include "fmp626.md")
416 (include "fa726te.md")
417 (include "cortex-a5.md")
418 (include "cortex-a7.md")
419 (include "cortex-a8.md")
420 (include "cortex-a9.md")
421 (include "cortex-a15.md")
422 (include "cortex-a17.md")
423 (include "cortex-a53.md")
424 (include "cortex-a57.md")
425 (include "cortex-r4.md")
426 (include "cortex-r4f.md")
427 (include "cortex-m7.md")
428 (include "cortex-m4.md")
429 (include "cortex-m4-fpu.md")
430 (include "exynos-m1.md")
431 (include "vfp11.md")
432 (include "marvell-pj4.md")
433 (include "xgene1.md")
436 ;;---------------------------------------------------------------------------
437 ;; Insn patterns
439 ;; Addition insns.
441 ;; Note: For DImode insns, there is normally no reason why operands should
442 ;; not be in the same register, what we don't want is for something being
443 ;; written to partially overlap something that is an input.
445 (define_expand "adddi3"
446  [(parallel
447    [(set (match_operand:DI           0 "s_register_operand" "")
448           (plus:DI (match_operand:DI 1 "s_register_operand" "")
449                    (match_operand:DI 2 "arm_adddi_operand"  "")))
450     (clobber (reg:CC CC_REGNUM))])]
451   "TARGET_EITHER"
452   "
453   if (TARGET_THUMB1)
454     {
455       if (!REG_P (operands[1]))
456         operands[1] = force_reg (DImode, operands[1]);
457       if (!REG_P (operands[2]))
458         operands[2] = force_reg (DImode, operands[2]);
459      }
460   "
463 (define_insn_and_split "*arm_adddi3"
464   [(set (match_operand:DI          0 "s_register_operand" "=&r,&r,&r,&r,&r")
465         (plus:DI (match_operand:DI 1 "s_register_operand" "%0, 0, r, 0, r")
466                  (match_operand:DI 2 "arm_adddi_operand"  "r,  0, r, Dd, Dd")))
467    (clobber (reg:CC CC_REGNUM))]
468   "TARGET_32BIT && !TARGET_NEON"
469   "#"
470   "TARGET_32BIT && reload_completed
471    && ! (TARGET_NEON && IS_VFP_REGNUM (REGNO (operands[0])))"
472   [(parallel [(set (reg:CC_C CC_REGNUM)
473                    (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
474                                  (match_dup 1)))
475               (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
476    (set (match_dup 3) (plus:SI (plus:SI (match_dup 4) (match_dup 5))
477                                (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
478   "
479   {
480     operands[3] = gen_highpart (SImode, operands[0]);
481     operands[0] = gen_lowpart (SImode, operands[0]);
482     operands[4] = gen_highpart (SImode, operands[1]);
483     operands[1] = gen_lowpart (SImode, operands[1]);
484     operands[5] = gen_highpart_mode (SImode, DImode, operands[2]);
485     operands[2] = gen_lowpart (SImode, operands[2]);
486   }"
487   [(set_attr "conds" "clob")
488    (set_attr "length" "8")
489    (set_attr "type" "multiple")]
492 (define_insn_and_split "*adddi_sesidi_di"
493   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
494         (plus:DI (sign_extend:DI
495                   (match_operand:SI 2 "s_register_operand" "r,r"))
496                  (match_operand:DI 1 "s_register_operand" "0,r")))
497    (clobber (reg:CC CC_REGNUM))]
498   "TARGET_32BIT"
499   "#"
500   "TARGET_32BIT && reload_completed"
501   [(parallel [(set (reg:CC_C CC_REGNUM)
502                    (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
503                                  (match_dup 1)))
504               (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
505    (set (match_dup 3) (plus:SI (plus:SI (ashiftrt:SI (match_dup 2)
506                                                      (const_int 31))
507                                         (match_dup 4))
508                                (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
509   "
510   {
511     operands[3] = gen_highpart (SImode, operands[0]);
512     operands[0] = gen_lowpart (SImode, operands[0]);
513     operands[4] = gen_highpart (SImode, operands[1]);
514     operands[1] = gen_lowpart (SImode, operands[1]);
515     operands[2] = gen_lowpart (SImode, operands[2]);
516   }"
517   [(set_attr "conds" "clob")
518    (set_attr "length" "8")
519    (set_attr "type" "multiple")]
522 (define_insn_and_split "*adddi_zesidi_di"
523   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
524         (plus:DI (zero_extend:DI
525                   (match_operand:SI 2 "s_register_operand" "r,r"))
526                  (match_operand:DI 1 "s_register_operand" "0,r")))
527    (clobber (reg:CC CC_REGNUM))]
528   "TARGET_32BIT"
529   "#"
530   "TARGET_32BIT && reload_completed"
531   [(parallel [(set (reg:CC_C CC_REGNUM)
532                    (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
533                                  (match_dup 1)))
534               (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
535    (set (match_dup 3) (plus:SI (plus:SI (match_dup 4) (const_int 0))
536                                (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
537   "
538   {
539     operands[3] = gen_highpart (SImode, operands[0]);
540     operands[0] = gen_lowpart (SImode, operands[0]);
541     operands[4] = gen_highpart (SImode, operands[1]);
542     operands[1] = gen_lowpart (SImode, operands[1]);
543     operands[2] = gen_lowpart (SImode, operands[2]);
544   }"
545   [(set_attr "conds" "clob")
546    (set_attr "length" "8")
547    (set_attr "type" "multiple")]
550 (define_expand "addsi3"
551   [(set (match_operand:SI          0 "s_register_operand" "")
552         (plus:SI (match_operand:SI 1 "s_register_operand" "")
553                  (match_operand:SI 2 "reg_or_int_operand" "")))]
554   "TARGET_EITHER"
555   "
556   if (TARGET_32BIT && CONST_INT_P (operands[2]))
557     {
558       arm_split_constant (PLUS, SImode, NULL_RTX,
559                           INTVAL (operands[2]), operands[0], operands[1],
560                           optimize && can_create_pseudo_p ());
561       DONE;
562     }
563   "
566 ; If there is a scratch available, this will be faster than synthesizing the
567 ; addition.
568 (define_peephole2
569   [(match_scratch:SI 3 "r")
570    (set (match_operand:SI          0 "arm_general_register_operand" "")
571         (plus:SI (match_operand:SI 1 "arm_general_register_operand" "")
572                  (match_operand:SI 2 "const_int_operand"  "")))]
573   "TARGET_32BIT &&
574    !(const_ok_for_arm (INTVAL (operands[2]))
575      || const_ok_for_arm (-INTVAL (operands[2])))
576     && const_ok_for_arm (~INTVAL (operands[2]))"
577   [(set (match_dup 3) (match_dup 2))
578    (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 3)))]
579   ""
582 ;; The r/r/k alternative is required when reloading the address
583 ;;  (plus (reg rN) (reg sp)) into (reg rN).  In this case reload will
584 ;; put the duplicated register first, and not try the commutative version.
585 (define_insn_and_split "*arm_addsi3"
586   [(set (match_operand:SI          0 "s_register_operand" "=rk,l,l ,l ,r ,k ,r,r ,k ,r ,k,k,r ,k ,r")
587         (plus:SI (match_operand:SI 1 "s_register_operand" "%0 ,l,0 ,l ,rk,k ,r,rk,k ,rk,k,r,rk,k ,rk")
588                  (match_operand:SI 2 "reg_or_int_operand" "rk ,l,Py,Pd,rI,rI,k,Pj,Pj,L ,L,L,PJ,PJ,?n")))]
589   "TARGET_32BIT"
590   "@
591    add%?\\t%0, %0, %2
592    add%?\\t%0, %1, %2
593    add%?\\t%0, %1, %2
594    add%?\\t%0, %1, %2
595    add%?\\t%0, %1, %2
596    add%?\\t%0, %1, %2
597    add%?\\t%0, %2, %1
598    addw%?\\t%0, %1, %2
599    addw%?\\t%0, %1, %2
600    sub%?\\t%0, %1, #%n2
601    sub%?\\t%0, %1, #%n2
602    sub%?\\t%0, %1, #%n2
603    subw%?\\t%0, %1, #%n2
604    subw%?\\t%0, %1, #%n2
605    #"
606   "TARGET_32BIT
607    && CONST_INT_P (operands[2])
608    && !const_ok_for_op (INTVAL (operands[2]), PLUS)
609    && (reload_completed || !arm_eliminable_register (operands[1]))"
610   [(clobber (const_int 0))]
611   "
612   arm_split_constant (PLUS, SImode, curr_insn,
613                       INTVAL (operands[2]), operands[0],
614                       operands[1], 0);
615   DONE;
616   "
617   [(set_attr "length" "2,4,4,4,4,4,4,4,4,4,4,4,4,4,16")
618    (set_attr "predicable" "yes")
619    (set_attr "predicable_short_it" "yes,yes,yes,yes,no,no,no,no,no,no,no,no,no,no,no")
620    (set_attr "arch" "t2,t2,t2,t2,*,*,*,t2,t2,*,*,a,t2,t2,*")
621    (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
622                       (const_string "alu_imm")
623                       (const_string "alu_sreg")))
627 (define_insn "addsi3_compare0"
628   [(set (reg:CC_NOOV CC_REGNUM)
629         (compare:CC_NOOV
630          (plus:SI (match_operand:SI 1 "s_register_operand" "r, r,r")
631                   (match_operand:SI 2 "arm_add_operand"    "I,L,r"))
632          (const_int 0)))
633    (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
634         (plus:SI (match_dup 1) (match_dup 2)))]
635   "TARGET_ARM"
636   "@
637    adds%?\\t%0, %1, %2
638    subs%?\\t%0, %1, #%n2
639    adds%?\\t%0, %1, %2"
640   [(set_attr "conds" "set")
641    (set_attr "type" "alus_imm,alus_imm,alus_sreg")]
644 (define_insn "*addsi3_compare0_scratch"
645   [(set (reg:CC_NOOV CC_REGNUM)
646         (compare:CC_NOOV
647          (plus:SI (match_operand:SI 0 "s_register_operand" "r, r, r")
648                   (match_operand:SI 1 "arm_add_operand"    "I,L, r"))
649          (const_int 0)))]
650   "TARGET_ARM"
651   "@
652    cmn%?\\t%0, %1
653    cmp%?\\t%0, #%n1
654    cmn%?\\t%0, %1"
655   [(set_attr "conds" "set")
656    (set_attr "predicable" "yes")
657    (set_attr "type" "alus_imm,alus_imm,alus_sreg")]
660 (define_insn "*compare_negsi_si"
661   [(set (reg:CC_Z CC_REGNUM)
662         (compare:CC_Z
663          (neg:SI (match_operand:SI 0 "s_register_operand" "l,r"))
664          (match_operand:SI 1 "s_register_operand" "l,r")))]
665   "TARGET_32BIT"
666   "cmn%?\\t%1, %0"
667   [(set_attr "conds" "set")
668    (set_attr "predicable" "yes")
669    (set_attr "arch" "t2,*")
670    (set_attr "length" "2,4")
671    (set_attr "predicable_short_it" "yes,no")
672    (set_attr "type" "alus_sreg")]
675 ;; This is the canonicalization of addsi3_compare0_for_combiner when the
676 ;; addend is a constant.
677 (define_insn "cmpsi2_addneg"
678   [(set (reg:CC CC_REGNUM)
679         (compare:CC
680          (match_operand:SI 1 "s_register_operand" "r,r")
681          (match_operand:SI 2 "arm_addimm_operand" "L,I")))
682    (set (match_operand:SI 0 "s_register_operand" "=r,r")
683         (plus:SI (match_dup 1)
684                  (match_operand:SI 3 "arm_addimm_operand" "I,L")))]
685   "TARGET_32BIT && INTVAL (operands[2]) == -INTVAL (operands[3])"
686   "@
687    adds%?\\t%0, %1, %3
688    subs%?\\t%0, %1, #%n3"
689   [(set_attr "conds" "set")
690    (set_attr "type" "alus_sreg")]
693 ;; Convert the sequence
694 ;;  sub  rd, rn, #1
695 ;;  cmn  rd, #1 (equivalent to cmp rd, #-1)
696 ;;  bne  dest
697 ;; into
698 ;;  subs rd, rn, #1
699 ;;  bcs  dest   ((unsigned)rn >= 1)
700 ;; similarly for the beq variant using bcc.
701 ;; This is a common looping idiom (while (n--))
702 (define_peephole2
703   [(set (match_operand:SI 0 "arm_general_register_operand" "")
704         (plus:SI (match_operand:SI 1 "arm_general_register_operand" "")
705                  (const_int -1)))
706    (set (match_operand 2 "cc_register" "")
707         (compare (match_dup 0) (const_int -1)))
708    (set (pc)
709         (if_then_else (match_operator 3 "equality_operator"
710                        [(match_dup 2) (const_int 0)])
711                       (match_operand 4 "" "")
712                       (match_operand 5 "" "")))]
713   "TARGET_32BIT && peep2_reg_dead_p (3, operands[2])"
714   [(parallel[
715     (set (match_dup 2)
716          (compare:CC
717           (match_dup 1) (const_int 1)))
718     (set (match_dup 0) (plus:SI (match_dup 1) (const_int -1)))])
719    (set (pc)
720         (if_then_else (match_op_dup 3 [(match_dup 2) (const_int 0)])
721                       (match_dup 4)
722                       (match_dup 5)))]
723   "operands[2] = gen_rtx_REG (CCmode, CC_REGNUM);
724    operands[3] = gen_rtx_fmt_ee ((GET_CODE (operands[3]) == NE
725                                   ? GEU : LTU),
726                                  VOIDmode, 
727                                  operands[2], const0_rtx);"
730 ;; The next four insns work because they compare the result with one of
731 ;; the operands, and we know that the use of the condition code is
732 ;; either GEU or LTU, so we can use the carry flag from the addition
733 ;; instead of doing the compare a second time.
734 (define_insn "*addsi3_compare_op1"
735   [(set (reg:CC_C CC_REGNUM)
736         (compare:CC_C
737          (plus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
738                   (match_operand:SI 2 "arm_add_operand" "I,L,r"))
739          (match_dup 1)))
740    (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
741         (plus:SI (match_dup 1) (match_dup 2)))]
742   "TARGET_32BIT"
743   "@
744    adds%?\\t%0, %1, %2
745    subs%?\\t%0, %1, #%n2
746    adds%?\\t%0, %1, %2"
747   [(set_attr "conds" "set")
748    (set_attr "type"  "alus_imm,alus_imm,alus_sreg")]
751 (define_insn "*addsi3_compare_op2"
752   [(set (reg:CC_C CC_REGNUM)
753         (compare:CC_C
754          (plus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
755                   (match_operand:SI 2 "arm_add_operand" "I,L,r"))
756          (match_dup 2)))
757    (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
758         (plus:SI (match_dup 1) (match_dup 2)))]
759   "TARGET_32BIT"
760   "@
761    adds%?\\t%0, %1, %2
762    subs%?\\t%0, %1, #%n2
763    adds%?\\t%0, %1, %2"
764   [(set_attr "conds" "set")
765    (set_attr "type" "alus_imm,alus_imm,alus_sreg")]
768 (define_insn "*compare_addsi2_op0"
769   [(set (reg:CC_C CC_REGNUM)
770         (compare:CC_C
771           (plus:SI (match_operand:SI 0 "s_register_operand" "l,l,r,r,r")
772                    (match_operand:SI 1 "arm_add_operand" "Pv,l,I,L,r"))
773           (match_dup 0)))]
774   "TARGET_32BIT"
775   "@
776    cmp%?\\t%0, #%n1
777    cmn%?\\t%0, %1
778    cmn%?\\t%0, %1
779    cmp%?\\t%0, #%n1
780    cmn%?\\t%0, %1"
781   [(set_attr "conds" "set")
782    (set_attr "predicable" "yes")
783    (set_attr "arch" "t2,t2,*,*,*")
784    (set_attr "predicable_short_it" "yes,yes,no,no,no")
785    (set_attr "length" "2,2,4,4,4")
786    (set_attr "type" "alus_imm,alus_sreg,alus_imm,alus_imm,alus_sreg")]
789 (define_insn "*compare_addsi2_op1"
790   [(set (reg:CC_C CC_REGNUM)
791         (compare:CC_C
792           (plus:SI (match_operand:SI 0 "s_register_operand" "l,l,r,r,r")
793                    (match_operand:SI 1 "arm_add_operand" "Pv,l,I,L,r"))
794           (match_dup 1)))]
795   "TARGET_32BIT"
796   "@
797    cmp%?\\t%0, #%n1
798    cmn%?\\t%0, %1
799    cmn%?\\t%0, %1
800    cmp%?\\t%0, #%n1
801    cmn%?\\t%0, %1"
802   [(set_attr "conds" "set")
803    (set_attr "predicable" "yes")
804    (set_attr "arch" "t2,t2,*,*,*")
805    (set_attr "predicable_short_it" "yes,yes,no,no,no")
806    (set_attr "length" "2,2,4,4,4")
807    (set_attr "type" "alus_imm,alus_sreg,alus_imm,alus_imm,alus_sreg")]
810 (define_insn "*addsi3_carryin_<optab>"
811   [(set (match_operand:SI 0 "s_register_operand" "=l,r,r")
812         (plus:SI (plus:SI (match_operand:SI 1 "s_register_operand" "%l,r,r")
813                           (match_operand:SI 2 "arm_not_operand" "0,rI,K"))
814                  (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))))]
815   "TARGET_32BIT"
816   "@
817    adc%?\\t%0, %1, %2
818    adc%?\\t%0, %1, %2
819    sbc%?\\t%0, %1, #%B2"
820   [(set_attr "conds" "use")
821    (set_attr "predicable" "yes")
822    (set_attr "arch" "t2,*,*")
823    (set_attr "length" "4")
824    (set_attr "predicable_short_it" "yes,no,no")
825    (set_attr "type" "adc_reg,adc_reg,adc_imm")]
828 (define_insn "*addsi3_carryin_alt2_<optab>"
829   [(set (match_operand:SI 0 "s_register_operand" "=l,r,r")
830         (plus:SI (plus:SI (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))
831                           (match_operand:SI 1 "s_register_operand" "%l,r,r"))
832                  (match_operand:SI 2 "arm_rhs_operand" "l,rI,K")))]
833   "TARGET_32BIT"
834   "@
835    adc%?\\t%0, %1, %2
836    adc%?\\t%0, %1, %2
837    sbc%?\\t%0, %1, #%B2"
838   [(set_attr "conds" "use")
839    (set_attr "predicable" "yes")
840    (set_attr "arch" "t2,*,*")
841    (set_attr "length" "4")
842    (set_attr "predicable_short_it" "yes,no,no")
843    (set_attr "type" "adc_reg,adc_reg,adc_imm")]
846 (define_insn "*addsi3_carryin_shift_<optab>"
847   [(set (match_operand:SI 0 "s_register_operand" "=r")
848         (plus:SI (plus:SI
849                   (match_operator:SI 2 "shift_operator"
850                     [(match_operand:SI 3 "s_register_operand" "r")
851                      (match_operand:SI 4 "reg_or_int_operand" "rM")])
852                   (match_operand:SI 1 "s_register_operand" "r"))
853                  (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))))]
854   "TARGET_32BIT"
855   "adc%?\\t%0, %1, %3%S2"
856   [(set_attr "conds" "use")
857    (set_attr "predicable" "yes")
858    (set_attr "predicable_short_it" "no")
859    (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
860                       (const_string "alu_shift_imm")
861                       (const_string "alu_shift_reg")))]
864 (define_insn "*addsi3_carryin_clobercc_<optab>"
865   [(set (match_operand:SI 0 "s_register_operand" "=r")
866         (plus:SI (plus:SI (match_operand:SI 1 "s_register_operand" "%r")
867                           (match_operand:SI 2 "arm_rhs_operand" "rI"))
868                  (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))))
869    (clobber (reg:CC CC_REGNUM))]
870    "TARGET_32BIT"
871    "adcs%?\\t%0, %1, %2"
872    [(set_attr "conds" "set")
873     (set_attr "type" "adcs_reg")]
876 (define_insn "*subsi3_carryin"
877   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
878         (minus:SI (minus:SI (match_operand:SI 1 "reg_or_int_operand" "r,I")
879                             (match_operand:SI 2 "s_register_operand" "r,r"))
880                   (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
881   "TARGET_32BIT"
882   "@
883    sbc%?\\t%0, %1, %2
884    rsc%?\\t%0, %2, %1"
885   [(set_attr "conds" "use")
886    (set_attr "arch" "*,a")
887    (set_attr "predicable" "yes")
888    (set_attr "predicable_short_it" "no")
889    (set_attr "type" "adc_reg,adc_imm")]
892 (define_insn "*subsi3_carryin_const"
893   [(set (match_operand:SI 0 "s_register_operand" "=r")
894         (minus:SI (plus:SI (match_operand:SI 1 "s_register_operand" "r")
895                            (match_operand:SI 2 "arm_not_immediate_operand" "K"))
896                   (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
897   "TARGET_32BIT"
898   "sbc\\t%0, %1, #%B2"
899   [(set_attr "conds" "use")
900    (set_attr "type" "adc_imm")]
903 (define_insn "*subsi3_carryin_compare"
904   [(set (reg:CC CC_REGNUM)
905         (compare:CC (match_operand:SI 1 "s_register_operand" "r")
906                     (match_operand:SI 2 "s_register_operand" "r")))
907    (set (match_operand:SI 0 "s_register_operand" "=r")
908         (minus:SI (minus:SI (match_dup 1)
909                             (match_dup 2))
910                   (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
911   "TARGET_32BIT"
912   "sbcs\\t%0, %1, %2"
913   [(set_attr "conds" "set")
914    (set_attr "type" "adcs_reg")]
917 (define_insn "*subsi3_carryin_compare_const"
918   [(set (reg:CC CC_REGNUM)
919         (compare:CC (match_operand:SI 1 "reg_or_int_operand" "r")
920                     (match_operand:SI 2 "arm_not_operand" "K")))
921    (set (match_operand:SI 0 "s_register_operand" "=r")
922         (minus:SI (plus:SI (match_dup 1)
923                            (match_dup 2))
924                   (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
925   "TARGET_32BIT"
926   "sbcs\\t%0, %1, #%B2"
927   [(set_attr "conds" "set")
928    (set_attr "type" "adcs_imm")]
931 (define_insn "*subsi3_carryin_shift"
932   [(set (match_operand:SI 0 "s_register_operand" "=r")
933         (minus:SI (minus:SI
934                   (match_operand:SI 1 "s_register_operand" "r")
935                   (match_operator:SI 2 "shift_operator"
936                    [(match_operand:SI 3 "s_register_operand" "r")
937                     (match_operand:SI 4 "reg_or_int_operand" "rM")]))
938                  (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
939   "TARGET_32BIT"
940   "sbc%?\\t%0, %1, %3%S2"
941   [(set_attr "conds" "use")
942    (set_attr "predicable" "yes")
943    (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
944                       (const_string "alu_shift_imm")
945                      (const_string "alu_shift_reg")))]
948 (define_insn "*rsbsi3_carryin_shift"
949   [(set (match_operand:SI 0 "s_register_operand" "=r")
950         (minus:SI (minus:SI
951                   (match_operator:SI 2 "shift_operator"
952                    [(match_operand:SI 3 "s_register_operand" "r")
953                     (match_operand:SI 4 "reg_or_int_operand" "rM")])
954                    (match_operand:SI 1 "s_register_operand" "r"))
955                  (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
956   "TARGET_ARM"
957   "rsc%?\\t%0, %1, %3%S2"
958   [(set_attr "conds" "use")
959    (set_attr "predicable" "yes")
960    (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
961                       (const_string "alu_shift_imm")
962                       (const_string "alu_shift_reg")))]
965 ; transform ((x << y) - 1) to ~(~(x-1) << y)  Where X is a constant.
966 (define_split
967   [(set (match_operand:SI 0 "s_register_operand" "")
968         (plus:SI (ashift:SI (match_operand:SI 1 "const_int_operand" "")
969                             (match_operand:SI 2 "s_register_operand" ""))
970                  (const_int -1)))
971    (clobber (match_operand:SI 3 "s_register_operand" ""))]
972   "TARGET_32BIT"
973   [(set (match_dup 3) (match_dup 1))
974    (set (match_dup 0) (not:SI (ashift:SI (match_dup 3) (match_dup 2))))]
975   "
976   operands[1] = GEN_INT (~(INTVAL (operands[1]) - 1));
979 (define_expand "addsf3"
980   [(set (match_operand:SF          0 "s_register_operand" "")
981         (plus:SF (match_operand:SF 1 "s_register_operand" "")
982                  (match_operand:SF 2 "s_register_operand" "")))]
983   "TARGET_32BIT && TARGET_HARD_FLOAT"
984   "
987 (define_expand "adddf3"
988   [(set (match_operand:DF          0 "s_register_operand" "")
989         (plus:DF (match_operand:DF 1 "s_register_operand" "")
990                  (match_operand:DF 2 "s_register_operand" "")))]
991   "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
992   "
995 (define_expand "subdi3"
996  [(parallel
997    [(set (match_operand:DI            0 "s_register_operand" "")
998           (minus:DI (match_operand:DI 1 "s_register_operand" "")
999                     (match_operand:DI 2 "s_register_operand" "")))
1000     (clobber (reg:CC CC_REGNUM))])]
1001   "TARGET_EITHER"
1002   "
1003   if (TARGET_THUMB1)
1004     {
1005       if (!REG_P (operands[1]))
1006         operands[1] = force_reg (DImode, operands[1]);
1007       if (!REG_P (operands[2]))
1008         operands[2] = force_reg (DImode, operands[2]);
1009      }  
1010   "
1013 (define_insn_and_split "*arm_subdi3"
1014   [(set (match_operand:DI           0 "s_register_operand" "=&r,&r,&r")
1015         (minus:DI (match_operand:DI 1 "s_register_operand" "0,r,0")
1016                   (match_operand:DI 2 "s_register_operand" "r,0,0")))
1017    (clobber (reg:CC CC_REGNUM))]
1018   "TARGET_32BIT && !TARGET_NEON"
1019   "#"  ; "subs\\t%Q0, %Q1, %Q2\;sbc\\t%R0, %R1, %R2"
1020   "&& reload_completed"
1021   [(parallel [(set (reg:CC CC_REGNUM)
1022                    (compare:CC (match_dup 1) (match_dup 2)))
1023               (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1024    (set (match_dup 3) (minus:SI (minus:SI (match_dup 4) (match_dup 5))
1025                                (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1026   {
1027     operands[3] = gen_highpart (SImode, operands[0]);
1028     operands[0] = gen_lowpart (SImode, operands[0]);
1029     operands[4] = gen_highpart (SImode, operands[1]);
1030     operands[1] = gen_lowpart (SImode, operands[1]);
1031     operands[5] = gen_highpart (SImode, operands[2]);
1032     operands[2] = gen_lowpart (SImode, operands[2]);
1033    }
1034   [(set_attr "conds" "clob")
1035    (set_attr "length" "8")
1036    (set_attr "type" "multiple")]
1039 (define_insn_and_split "*subdi_di_zesidi"
1040   [(set (match_operand:DI           0 "s_register_operand" "=&r,&r")
1041         (minus:DI (match_operand:DI 1 "s_register_operand"  "0,r")
1042                   (zero_extend:DI
1043                    (match_operand:SI 2 "s_register_operand"  "r,r"))))
1044    (clobber (reg:CC CC_REGNUM))]
1045   "TARGET_32BIT"
1046   "#"   ; "subs\\t%Q0, %Q1, %2\;sbc\\t%R0, %R1, #0"
1047   "&& reload_completed"
1048   [(parallel [(set (reg:CC CC_REGNUM)
1049                    (compare:CC (match_dup 1) (match_dup 2)))
1050               (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1051    (set (match_dup 3) (minus:SI (plus:SI (match_dup 4) (match_dup 5))
1052                                 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1053   {
1054     operands[3] = gen_highpart (SImode, operands[0]);
1055     operands[0] = gen_lowpart (SImode, operands[0]);
1056     operands[4] = gen_highpart (SImode, operands[1]);
1057     operands[1] = gen_lowpart (SImode, operands[1]);
1058     operands[5] = GEN_INT (~0);
1059    }
1060   [(set_attr "conds" "clob")
1061    (set_attr "length" "8")
1062    (set_attr "type" "multiple")]
1065 (define_insn_and_split "*subdi_di_sesidi"
1066   [(set (match_operand:DI            0 "s_register_operand" "=&r,&r")
1067         (minus:DI (match_operand:DI  1 "s_register_operand"  "0,r")
1068                   (sign_extend:DI
1069                    (match_operand:SI 2 "s_register_operand"  "r,r"))))
1070    (clobber (reg:CC CC_REGNUM))]
1071   "TARGET_32BIT"
1072   "#"   ; "subs\\t%Q0, %Q1, %2\;sbc\\t%R0, %R1, %2, asr #31"
1073   "&& reload_completed"
1074   [(parallel [(set (reg:CC CC_REGNUM)
1075                    (compare:CC (match_dup 1) (match_dup 2)))
1076               (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1077    (set (match_dup 3) (minus:SI (minus:SI (match_dup 4)
1078                                          (ashiftrt:SI (match_dup 2)
1079                                                       (const_int 31)))
1080                                 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1081   {
1082     operands[3] = gen_highpart (SImode, operands[0]);
1083     operands[0] = gen_lowpart (SImode, operands[0]);
1084     operands[4] = gen_highpart (SImode, operands[1]);
1085     operands[1] = gen_lowpart (SImode, operands[1]);
1086   }
1087   [(set_attr "conds" "clob")
1088    (set_attr "length" "8")
1089    (set_attr "type" "multiple")]
1092 (define_insn_and_split "*subdi_zesidi_di"
1093   [(set (match_operand:DI            0 "s_register_operand" "=&r,&r")
1094         (minus:DI (zero_extend:DI
1095                    (match_operand:SI 2 "s_register_operand"  "r,r"))
1096                   (match_operand:DI  1 "s_register_operand" "0,r")))
1097    (clobber (reg:CC CC_REGNUM))]
1098   "TARGET_ARM"
1099   "#"   ; "rsbs\\t%Q0, %Q1, %2\;rsc\\t%R0, %R1, #0"
1100         ; is equivalent to:
1101         ; "subs\\t%Q0, %2, %Q1\;rsc\\t%R0, %R1, #0"
1102   "&& reload_completed"
1103   [(parallel [(set (reg:CC CC_REGNUM)
1104                    (compare:CC (match_dup 2) (match_dup 1)))
1105               (set (match_dup 0) (minus:SI (match_dup 2) (match_dup 1)))])
1106    (set (match_dup 3) (minus:SI (minus:SI (const_int 0) (match_dup 4))
1107                                (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1108   {
1109     operands[3] = gen_highpart (SImode, operands[0]);
1110     operands[0] = gen_lowpart (SImode, operands[0]);
1111     operands[4] = gen_highpart (SImode, operands[1]);
1112     operands[1] = gen_lowpart (SImode, operands[1]);
1113   }
1114   [(set_attr "conds" "clob")
1115    (set_attr "length" "8")
1116    (set_attr "type" "multiple")]
1119 (define_insn_and_split "*subdi_sesidi_di"
1120   [(set (match_operand:DI            0 "s_register_operand" "=&r,&r")
1121         (minus:DI (sign_extend:DI
1122                    (match_operand:SI 2 "s_register_operand"   "r,r"))
1123                   (match_operand:DI  1 "s_register_operand"  "0,r")))
1124    (clobber (reg:CC CC_REGNUM))]
1125   "TARGET_ARM"
1126   "#"   ; "rsbs\\t%Q0, %Q1, %2\;rsc\\t%R0, %R1, %2, asr #31"
1127         ; is equivalent to:
1128         ; "subs\\t%Q0, %2, %Q1\;rsc\\t%R0, %R1, %2, asr #31"
1129   "&& reload_completed"
1130   [(parallel [(set (reg:CC CC_REGNUM)
1131                    (compare:CC (match_dup 2) (match_dup 1)))
1132               (set (match_dup 0) (minus:SI (match_dup 2) (match_dup 1)))])
1133    (set (match_dup 3) (minus:SI (minus:SI
1134                                 (ashiftrt:SI (match_dup 2)
1135                                              (const_int 31))
1136                                 (match_dup 4))
1137                                (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1138   {
1139     operands[3] = gen_highpart (SImode, operands[0]);
1140     operands[0] = gen_lowpart (SImode, operands[0]);
1141     operands[4] = gen_highpart (SImode, operands[1]);
1142     operands[1] = gen_lowpart (SImode, operands[1]);
1143   }
1144   [(set_attr "conds" "clob")
1145    (set_attr "length" "8")
1146    (set_attr "type" "multiple")]
1149 (define_insn_and_split "*subdi_zesidi_zesidi"
1150   [(set (match_operand:DI            0 "s_register_operand" "=r")
1151         (minus:DI (zero_extend:DI
1152                    (match_operand:SI 1 "s_register_operand"  "r"))
1153                   (zero_extend:DI
1154                    (match_operand:SI 2 "s_register_operand"  "r"))))
1155    (clobber (reg:CC CC_REGNUM))]
1156   "TARGET_32BIT"
1157   "#"   ; "subs\\t%Q0, %1, %2\;sbc\\t%R0, %1, %1"
1158   "&& reload_completed"
1159   [(parallel [(set (reg:CC CC_REGNUM)
1160                    (compare:CC (match_dup 1) (match_dup 2)))
1161               (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1162    (set (match_dup 3) (minus:SI (minus:SI (match_dup 1) (match_dup 1))
1163                                (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1164   {
1165        operands[3] = gen_highpart (SImode, operands[0]);
1166        operands[0] = gen_lowpart (SImode, operands[0]);
1167   }
1168   [(set_attr "conds" "clob")
1169    (set_attr "length" "8")
1170    (set_attr "type" "multiple")]
1173 (define_expand "subsi3"
1174   [(set (match_operand:SI           0 "s_register_operand" "")
1175         (minus:SI (match_operand:SI 1 "reg_or_int_operand" "")
1176                   (match_operand:SI 2 "s_register_operand" "")))]
1177   "TARGET_EITHER"
1178   "
1179   if (CONST_INT_P (operands[1]))
1180     {
1181       if (TARGET_32BIT)
1182         {
1183           if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[1]), MINUS))
1184             operands[1] = force_reg (SImode, operands[1]);
1185           else
1186             {
1187               arm_split_constant (MINUS, SImode, NULL_RTX,
1188                                   INTVAL (operands[1]), operands[0],
1189                                   operands[2],
1190                                   optimize && can_create_pseudo_p ());
1191               DONE;
1192             }
1193         }
1194       else /* TARGET_THUMB1 */
1195         operands[1] = force_reg (SImode, operands[1]);
1196     }
1197   "
1200 ; ??? Check Thumb-2 split length
1201 (define_insn_and_split "*arm_subsi3_insn"
1202   [(set (match_operand:SI           0 "s_register_operand" "=l,l ,l ,l ,r,r,r,rk,r")
1203         (minus:SI (match_operand:SI 1 "reg_or_int_operand" "l ,0 ,l ,Pz,I,r,r,k ,?n")
1204                   (match_operand:SI 2 "reg_or_int_operand" "l ,Py,Pd,l ,r,I,r,r ,r")))]
1205   "TARGET_32BIT"
1206   "@
1207    sub%?\\t%0, %1, %2
1208    sub%?\\t%0, %2
1209    sub%?\\t%0, %1, %2
1210    rsb%?\\t%0, %2, %1
1211    rsb%?\\t%0, %2, %1
1212    sub%?\\t%0, %1, %2
1213    sub%?\\t%0, %1, %2
1214    sub%?\\t%0, %1, %2
1215    #"
1216   "&& (CONST_INT_P (operands[1])
1217        && !const_ok_for_arm (INTVAL (operands[1])))"
1218   [(clobber (const_int 0))]
1219   "
1220   arm_split_constant (MINUS, SImode, curr_insn,
1221                       INTVAL (operands[1]), operands[0], operands[2], 0);
1222   DONE;
1223   "
1224   [(set_attr "length" "4,4,4,4,4,4,4,4,16")
1225    (set_attr "arch" "t2,t2,t2,t2,*,*,*,*,*")
1226    (set_attr "predicable" "yes")
1227    (set_attr "predicable_short_it" "yes,yes,yes,yes,no,no,no,no,no")
1228    (set_attr "type" "alu_sreg,alu_sreg,alu_sreg,alu_sreg,alu_imm,alu_imm,alu_sreg,alu_sreg,multiple")]
1231 (define_peephole2
1232   [(match_scratch:SI 3 "r")
1233    (set (match_operand:SI 0 "arm_general_register_operand" "")
1234         (minus:SI (match_operand:SI 1 "const_int_operand" "")
1235                   (match_operand:SI 2 "arm_general_register_operand" "")))]
1236   "TARGET_32BIT
1237    && !const_ok_for_arm (INTVAL (operands[1]))
1238    && const_ok_for_arm (~INTVAL (operands[1]))"
1239   [(set (match_dup 3) (match_dup 1))
1240    (set (match_dup 0) (minus:SI (match_dup 3) (match_dup 2)))]
1241   ""
1244 (define_insn "subsi3_compare0"
1245   [(set (reg:CC_NOOV CC_REGNUM)
1246         (compare:CC_NOOV
1247          (minus:SI (match_operand:SI 1 "arm_rhs_operand" "r,r,I")
1248                    (match_operand:SI 2 "arm_rhs_operand" "I,r,r"))
1249          (const_int 0)))
1250    (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
1251         (minus:SI (match_dup 1) (match_dup 2)))]
1252   "TARGET_32BIT"
1253   "@
1254    subs%?\\t%0, %1, %2
1255    subs%?\\t%0, %1, %2
1256    rsbs%?\\t%0, %2, %1"
1257   [(set_attr "conds" "set")
1258    (set_attr "type"  "alus_imm,alus_sreg,alus_sreg")]
1261 (define_insn "subsi3_compare"
1262   [(set (reg:CC CC_REGNUM)
1263         (compare:CC (match_operand:SI 1 "arm_rhs_operand" "r,r,I")
1264                     (match_operand:SI 2 "arm_rhs_operand" "I,r,r")))
1265    (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
1266         (minus:SI (match_dup 1) (match_dup 2)))]
1267   "TARGET_32BIT"
1268   "@
1269    subs%?\\t%0, %1, %2
1270    subs%?\\t%0, %1, %2
1271    rsbs%?\\t%0, %2, %1"
1272   [(set_attr "conds" "set")
1273    (set_attr "type" "alus_imm,alus_sreg,alus_sreg")]
1276 (define_expand "subsf3"
1277   [(set (match_operand:SF           0 "s_register_operand" "")
1278         (minus:SF (match_operand:SF 1 "s_register_operand" "")
1279                   (match_operand:SF 2 "s_register_operand" "")))]
1280   "TARGET_32BIT && TARGET_HARD_FLOAT"
1281   "
1284 (define_expand "subdf3"
1285   [(set (match_operand:DF           0 "s_register_operand" "")
1286         (minus:DF (match_operand:DF 1 "s_register_operand" "")
1287                   (match_operand:DF 2 "s_register_operand" "")))]
1288   "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
1289   "
1293 ;; Multiplication insns
1295 (define_expand "mulhi3"
1296   [(set (match_operand:HI 0 "s_register_operand" "")
1297         (mult:HI (match_operand:HI 1 "s_register_operand" "")
1298                  (match_operand:HI 2 "s_register_operand" "")))]
1299   "TARGET_DSP_MULTIPLY"
1300   "
1301   {
1302     rtx result = gen_reg_rtx (SImode);
1303     emit_insn (gen_mulhisi3 (result, operands[1], operands[2]));
1304     emit_move_insn (operands[0], gen_lowpart (HImode, result));
1305     DONE;
1306   }"
1309 (define_expand "mulsi3"
1310   [(set (match_operand:SI          0 "s_register_operand" "")
1311         (mult:SI (match_operand:SI 2 "s_register_operand" "")
1312                  (match_operand:SI 1 "s_register_operand" "")))]
1313   "TARGET_EITHER"
1314   ""
1317 ;; Use `&' and then `0' to prevent the operands 0 and 1 being the same
1318 (define_insn "*arm_mulsi3"
1319   [(set (match_operand:SI          0 "s_register_operand" "=&r,&r")
1320         (mult:SI (match_operand:SI 2 "s_register_operand" "r,r")
1321                  (match_operand:SI 1 "s_register_operand" "%0,r")))]
1322   "TARGET_32BIT && !arm_arch6"
1323   "mul%?\\t%0, %2, %1"
1324   [(set_attr "type" "mul")
1325    (set_attr "predicable" "yes")]
1328 (define_insn "*arm_mulsi3_v6"
1329   [(set (match_operand:SI          0 "s_register_operand" "=l,l,r")
1330         (mult:SI (match_operand:SI 1 "s_register_operand" "0,l,r")
1331                  (match_operand:SI 2 "s_register_operand" "l,0,r")))]
1332   "TARGET_32BIT && arm_arch6"
1333   "mul%?\\t%0, %1, %2"
1334   [(set_attr "type" "mul")
1335    (set_attr "predicable" "yes")
1336    (set_attr "arch" "t2,t2,*")
1337    (set_attr "length" "4")
1338    (set_attr "predicable_short_it" "yes,yes,no")]
1341 (define_insn "*mulsi3_compare0"
1342   [(set (reg:CC_NOOV CC_REGNUM)
1343         (compare:CC_NOOV (mult:SI
1344                           (match_operand:SI 2 "s_register_operand" "r,r")
1345                           (match_operand:SI 1 "s_register_operand" "%0,r"))
1346                          (const_int 0)))
1347    (set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1348         (mult:SI (match_dup 2) (match_dup 1)))]
1349   "TARGET_ARM && !arm_arch6"
1350   "muls%?\\t%0, %2, %1"
1351   [(set_attr "conds" "set")
1352    (set_attr "type" "muls")]
1355 (define_insn "*mulsi3_compare0_v6"
1356   [(set (reg:CC_NOOV CC_REGNUM)
1357         (compare:CC_NOOV (mult:SI
1358                           (match_operand:SI 2 "s_register_operand" "r")
1359                           (match_operand:SI 1 "s_register_operand" "r"))
1360                          (const_int 0)))
1361    (set (match_operand:SI 0 "s_register_operand" "=r")
1362         (mult:SI (match_dup 2) (match_dup 1)))]
1363   "TARGET_ARM && arm_arch6 && optimize_size"
1364   "muls%?\\t%0, %2, %1"
1365   [(set_attr "conds" "set")
1366    (set_attr "type" "muls")]
1369 (define_insn "*mulsi_compare0_scratch"
1370   [(set (reg:CC_NOOV CC_REGNUM)
1371         (compare:CC_NOOV (mult:SI
1372                           (match_operand:SI 2 "s_register_operand" "r,r")
1373                           (match_operand:SI 1 "s_register_operand" "%0,r"))
1374                          (const_int 0)))
1375    (clobber (match_scratch:SI 0 "=&r,&r"))]
1376   "TARGET_ARM && !arm_arch6"
1377   "muls%?\\t%0, %2, %1"
1378   [(set_attr "conds" "set")
1379    (set_attr "type" "muls")]
1382 (define_insn "*mulsi_compare0_scratch_v6"
1383   [(set (reg:CC_NOOV CC_REGNUM)
1384         (compare:CC_NOOV (mult:SI
1385                           (match_operand:SI 2 "s_register_operand" "r")
1386                           (match_operand:SI 1 "s_register_operand" "r"))
1387                          (const_int 0)))
1388    (clobber (match_scratch:SI 0 "=r"))]
1389   "TARGET_ARM && arm_arch6 && optimize_size"
1390   "muls%?\\t%0, %2, %1"
1391   [(set_attr "conds" "set")
1392    (set_attr "type" "muls")]
1395 ;; Unnamed templates to match MLA instruction.
1397 (define_insn "*mulsi3addsi"
1398   [(set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r,&r")
1399         (plus:SI
1400           (mult:SI (match_operand:SI 2 "s_register_operand" "r,r,r,r")
1401                    (match_operand:SI 1 "s_register_operand" "%0,r,0,r"))
1402           (match_operand:SI 3 "s_register_operand" "r,r,0,0")))]
1403   "TARGET_32BIT && !arm_arch6"
1404   "mla%?\\t%0, %2, %1, %3"
1405   [(set_attr "type" "mla")
1406    (set_attr "predicable" "yes")]
1409 (define_insn "*mulsi3addsi_v6"
1410   [(set (match_operand:SI 0 "s_register_operand" "=r")
1411         (plus:SI
1412           (mult:SI (match_operand:SI 2 "s_register_operand" "r")
1413                    (match_operand:SI 1 "s_register_operand" "r"))
1414           (match_operand:SI 3 "s_register_operand" "r")))]
1415   "TARGET_32BIT && arm_arch6"
1416   "mla%?\\t%0, %2, %1, %3"
1417   [(set_attr "type" "mla")
1418    (set_attr "predicable" "yes")
1419    (set_attr "predicable_short_it" "no")]
1422 (define_insn "*mulsi3addsi_compare0"
1423   [(set (reg:CC_NOOV CC_REGNUM)
1424         (compare:CC_NOOV
1425          (plus:SI (mult:SI
1426                    (match_operand:SI 2 "s_register_operand" "r,r,r,r")
1427                    (match_operand:SI 1 "s_register_operand" "%0,r,0,r"))
1428                   (match_operand:SI 3 "s_register_operand" "r,r,0,0"))
1429          (const_int 0)))
1430    (set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r,&r")
1431         (plus:SI (mult:SI (match_dup 2) (match_dup 1))
1432                  (match_dup 3)))]
1433   "TARGET_ARM && arm_arch6"
1434   "mlas%?\\t%0, %2, %1, %3"
1435   [(set_attr "conds" "set")
1436    (set_attr "type" "mlas")]
1439 (define_insn "*mulsi3addsi_compare0_v6"
1440   [(set (reg:CC_NOOV CC_REGNUM)
1441         (compare:CC_NOOV
1442          (plus:SI (mult:SI
1443                    (match_operand:SI 2 "s_register_operand" "r")
1444                    (match_operand:SI 1 "s_register_operand" "r"))
1445                   (match_operand:SI 3 "s_register_operand" "r"))
1446          (const_int 0)))
1447    (set (match_operand:SI 0 "s_register_operand" "=r")
1448         (plus:SI (mult:SI (match_dup 2) (match_dup 1))
1449                  (match_dup 3)))]
1450   "TARGET_ARM && arm_arch6 && optimize_size"
1451   "mlas%?\\t%0, %2, %1, %3"
1452   [(set_attr "conds" "set")
1453    (set_attr "type" "mlas")]
1456 (define_insn "*mulsi3addsi_compare0_scratch"
1457   [(set (reg:CC_NOOV CC_REGNUM)
1458         (compare:CC_NOOV
1459          (plus:SI (mult:SI
1460                    (match_operand:SI 2 "s_register_operand" "r,r,r,r")
1461                    (match_operand:SI 1 "s_register_operand" "%0,r,0,r"))
1462                   (match_operand:SI 3 "s_register_operand" "?r,r,0,0"))
1463          (const_int 0)))
1464    (clobber (match_scratch:SI 0 "=&r,&r,&r,&r"))]
1465   "TARGET_ARM && !arm_arch6"
1466   "mlas%?\\t%0, %2, %1, %3"
1467   [(set_attr "conds" "set")
1468    (set_attr "type" "mlas")]
1471 (define_insn "*mulsi3addsi_compare0_scratch_v6"
1472   [(set (reg:CC_NOOV CC_REGNUM)
1473         (compare:CC_NOOV
1474          (plus:SI (mult:SI
1475                    (match_operand:SI 2 "s_register_operand" "r")
1476                    (match_operand:SI 1 "s_register_operand" "r"))
1477                   (match_operand:SI 3 "s_register_operand" "r"))
1478          (const_int 0)))
1479    (clobber (match_scratch:SI 0 "=r"))]
1480   "TARGET_ARM && arm_arch6 && optimize_size"
1481   "mlas%?\\t%0, %2, %1, %3"
1482   [(set_attr "conds" "set")
1483    (set_attr "type" "mlas")]
1486 (define_insn "*mulsi3subsi"
1487   [(set (match_operand:SI 0 "s_register_operand" "=r")
1488         (minus:SI
1489           (match_operand:SI 3 "s_register_operand" "r")
1490           (mult:SI (match_operand:SI 2 "s_register_operand" "r")
1491                    (match_operand:SI 1 "s_register_operand" "r"))))]
1492   "TARGET_32BIT && arm_arch_thumb2"
1493   "mls%?\\t%0, %2, %1, %3"
1494   [(set_attr "type" "mla")
1495    (set_attr "predicable" "yes")
1496    (set_attr "predicable_short_it" "no")]
1499 (define_expand "maddsidi4"
1500   [(set (match_operand:DI 0 "s_register_operand" "")
1501         (plus:DI
1502          (mult:DI
1503           (sign_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1504           (sign_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1505          (match_operand:DI 3 "s_register_operand" "")))]
1506   "TARGET_32BIT && arm_arch3m"
1507   "")
1509 (define_insn "*mulsidi3adddi"
1510   [(set (match_operand:DI 0 "s_register_operand" "=&r")
1511         (plus:DI
1512          (mult:DI
1513           (sign_extend:DI (match_operand:SI 2 "s_register_operand" "%r"))
1514           (sign_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1515          (match_operand:DI 1 "s_register_operand" "0")))]
1516   "TARGET_32BIT && arm_arch3m && !arm_arch6"
1517   "smlal%?\\t%Q0, %R0, %3, %2"
1518   [(set_attr "type" "smlal")
1519    (set_attr "predicable" "yes")]
1522 (define_insn "*mulsidi3adddi_v6"
1523   [(set (match_operand:DI 0 "s_register_operand" "=r")
1524         (plus:DI
1525          (mult:DI
1526           (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r"))
1527           (sign_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1528          (match_operand:DI 1 "s_register_operand" "0")))]
1529   "TARGET_32BIT && arm_arch6"
1530   "smlal%?\\t%Q0, %R0, %3, %2"
1531   [(set_attr "type" "smlal")
1532    (set_attr "predicable" "yes")
1533    (set_attr "predicable_short_it" "no")]
1536 ;; 32x32->64 widening multiply.
1537 ;; As with mulsi3, the only difference between the v3-5 and v6+
1538 ;; versions of these patterns is the requirement that the output not
1539 ;; overlap the inputs, but that still means we have to have a named
1540 ;; expander and two different starred insns.
1542 (define_expand "mulsidi3"
1543   [(set (match_operand:DI 0 "s_register_operand" "")
1544         (mult:DI
1545          (sign_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1546          (sign_extend:DI (match_operand:SI 2 "s_register_operand" ""))))]
1547   "TARGET_32BIT && arm_arch3m"
1548   ""
1551 (define_insn "*mulsidi3_nov6"
1552   [(set (match_operand:DI 0 "s_register_operand" "=&r")
1553         (mult:DI
1554          (sign_extend:DI (match_operand:SI 1 "s_register_operand" "%r"))
1555          (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1556   "TARGET_32BIT && arm_arch3m && !arm_arch6"
1557   "smull%?\\t%Q0, %R0, %1, %2"
1558   [(set_attr "type" "smull")
1559    (set_attr "predicable" "yes")]
1562 (define_insn "*mulsidi3_v6"
1563   [(set (match_operand:DI 0 "s_register_operand" "=r")
1564         (mult:DI
1565          (sign_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1566          (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1567   "TARGET_32BIT && arm_arch6"
1568   "smull%?\\t%Q0, %R0, %1, %2"
1569   [(set_attr "type" "smull")
1570    (set_attr "predicable" "yes")
1571    (set_attr "predicable_short_it" "no")]
1574 (define_expand "umulsidi3"
1575   [(set (match_operand:DI 0 "s_register_operand" "")
1576         (mult:DI
1577          (zero_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1578          (zero_extend:DI (match_operand:SI 2 "s_register_operand" ""))))]
1579   "TARGET_32BIT && arm_arch3m"
1580   ""
1583 (define_insn "*umulsidi3_nov6"
1584   [(set (match_operand:DI 0 "s_register_operand" "=&r")
1585         (mult:DI
1586          (zero_extend:DI (match_operand:SI 1 "s_register_operand" "%r"))
1587          (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1588   "TARGET_32BIT && arm_arch3m && !arm_arch6"
1589   "umull%?\\t%Q0, %R0, %1, %2"
1590   [(set_attr "type" "umull")
1591    (set_attr "predicable" "yes")]
1594 (define_insn "*umulsidi3_v6"
1595   [(set (match_operand:DI 0 "s_register_operand" "=r")
1596         (mult:DI
1597          (zero_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1598          (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1599   "TARGET_32BIT && arm_arch6"
1600   "umull%?\\t%Q0, %R0, %1, %2"
1601   [(set_attr "type" "umull")
1602    (set_attr "predicable" "yes")
1603    (set_attr "predicable_short_it" "no")]
1606 (define_expand "umaddsidi4"
1607   [(set (match_operand:DI 0 "s_register_operand" "")
1608         (plus:DI
1609          (mult:DI
1610           (zero_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1611           (zero_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1612          (match_operand:DI 3 "s_register_operand" "")))]
1613   "TARGET_32BIT && arm_arch3m"
1614   "")
1616 (define_insn "*umulsidi3adddi"
1617   [(set (match_operand:DI 0 "s_register_operand" "=&r")
1618         (plus:DI
1619          (mult:DI
1620           (zero_extend:DI (match_operand:SI 2 "s_register_operand" "%r"))
1621           (zero_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1622          (match_operand:DI 1 "s_register_operand" "0")))]
1623   "TARGET_32BIT && arm_arch3m && !arm_arch6"
1624   "umlal%?\\t%Q0, %R0, %3, %2"
1625   [(set_attr "type" "umlal")
1626    (set_attr "predicable" "yes")]
1629 (define_insn "*umulsidi3adddi_v6"
1630   [(set (match_operand:DI 0 "s_register_operand" "=r")
1631         (plus:DI
1632          (mult:DI
1633           (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r"))
1634           (zero_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1635          (match_operand:DI 1 "s_register_operand" "0")))]
1636   "TARGET_32BIT && arm_arch6"
1637   "umlal%?\\t%Q0, %R0, %3, %2"
1638   [(set_attr "type" "umlal")
1639    (set_attr "predicable" "yes")
1640    (set_attr "predicable_short_it" "no")]
1643 (define_expand "smulsi3_highpart"
1644   [(parallel
1645     [(set (match_operand:SI 0 "s_register_operand" "")
1646           (truncate:SI
1647            (lshiftrt:DI
1648             (mult:DI
1649              (sign_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1650              (sign_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1651             (const_int 32))))
1652      (clobber (match_scratch:SI 3 ""))])]
1653   "TARGET_32BIT && arm_arch3m"
1654   ""
1657 (define_insn "*smulsi3_highpart_nov6"
1658   [(set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1659         (truncate:SI
1660          (lshiftrt:DI
1661           (mult:DI
1662            (sign_extend:DI (match_operand:SI 1 "s_register_operand" "%0,r"))
1663            (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r,r")))
1664           (const_int 32))))
1665    (clobber (match_scratch:SI 3 "=&r,&r"))]
1666   "TARGET_32BIT && arm_arch3m && !arm_arch6"
1667   "smull%?\\t%3, %0, %2, %1"
1668   [(set_attr "type" "smull")
1669    (set_attr "predicable" "yes")]
1672 (define_insn "*smulsi3_highpart_v6"
1673   [(set (match_operand:SI 0 "s_register_operand" "=r")
1674         (truncate:SI
1675          (lshiftrt:DI
1676           (mult:DI
1677            (sign_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1678            (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r")))
1679           (const_int 32))))
1680    (clobber (match_scratch:SI 3 "=r"))]
1681   "TARGET_32BIT && arm_arch6"
1682   "smull%?\\t%3, %0, %2, %1"
1683   [(set_attr "type" "smull")
1684    (set_attr "predicable" "yes")
1685    (set_attr "predicable_short_it" "no")]
1688 (define_expand "umulsi3_highpart"
1689   [(parallel
1690     [(set (match_operand:SI 0 "s_register_operand" "")
1691           (truncate:SI
1692            (lshiftrt:DI
1693             (mult:DI
1694              (zero_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1695               (zero_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1696             (const_int 32))))
1697      (clobber (match_scratch:SI 3 ""))])]
1698   "TARGET_32BIT && arm_arch3m"
1699   ""
1702 (define_insn "*umulsi3_highpart_nov6"
1703   [(set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1704         (truncate:SI
1705          (lshiftrt:DI
1706           (mult:DI
1707            (zero_extend:DI (match_operand:SI 1 "s_register_operand" "%0,r"))
1708            (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r,r")))
1709           (const_int 32))))
1710    (clobber (match_scratch:SI 3 "=&r,&r"))]
1711   "TARGET_32BIT && arm_arch3m && !arm_arch6"
1712   "umull%?\\t%3, %0, %2, %1"
1713   [(set_attr "type" "umull")
1714    (set_attr "predicable" "yes")]
1717 (define_insn "*umulsi3_highpart_v6"
1718   [(set (match_operand:SI 0 "s_register_operand" "=r")
1719         (truncate:SI
1720          (lshiftrt:DI
1721           (mult:DI
1722            (zero_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1723            (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r")))
1724           (const_int 32))))
1725    (clobber (match_scratch:SI 3 "=r"))]
1726   "TARGET_32BIT && arm_arch6"
1727   "umull%?\\t%3, %0, %2, %1"
1728   [(set_attr "type" "umull")
1729    (set_attr "predicable" "yes")
1730    (set_attr "predicable_short_it" "no")]
1733 (define_insn "mulhisi3"
1734   [(set (match_operand:SI 0 "s_register_operand" "=r")
1735         (mult:SI (sign_extend:SI
1736                   (match_operand:HI 1 "s_register_operand" "%r"))
1737                  (sign_extend:SI
1738                   (match_operand:HI 2 "s_register_operand" "r"))))]
1739   "TARGET_DSP_MULTIPLY"
1740   "smulbb%?\\t%0, %1, %2"
1741   [(set_attr "type" "smulxy")
1742    (set_attr "predicable" "yes")]
1745 (define_insn "*mulhisi3tb"
1746   [(set (match_operand:SI 0 "s_register_operand" "=r")
1747         (mult:SI (ashiftrt:SI
1748                   (match_operand:SI 1 "s_register_operand" "r")
1749                   (const_int 16))
1750                  (sign_extend:SI
1751                   (match_operand:HI 2 "s_register_operand" "r"))))]
1752   "TARGET_DSP_MULTIPLY"
1753   "smultb%?\\t%0, %1, %2"
1754   [(set_attr "type" "smulxy")
1755    (set_attr "predicable" "yes")
1756    (set_attr "predicable_short_it" "no")]
1759 (define_insn "*mulhisi3bt"
1760   [(set (match_operand:SI 0 "s_register_operand" "=r")
1761         (mult:SI (sign_extend:SI
1762                   (match_operand:HI 1 "s_register_operand" "r"))
1763                  (ashiftrt:SI
1764                   (match_operand:SI 2 "s_register_operand" "r")
1765                   (const_int 16))))]
1766   "TARGET_DSP_MULTIPLY"
1767   "smulbt%?\\t%0, %1, %2"
1768   [(set_attr "type" "smulxy")
1769    (set_attr "predicable" "yes")
1770    (set_attr "predicable_short_it" "no")]
1773 (define_insn "*mulhisi3tt"
1774   [(set (match_operand:SI 0 "s_register_operand" "=r")
1775         (mult:SI (ashiftrt:SI
1776                   (match_operand:SI 1 "s_register_operand" "r")
1777                   (const_int 16))
1778                  (ashiftrt:SI
1779                   (match_operand:SI 2 "s_register_operand" "r")
1780                   (const_int 16))))]
1781   "TARGET_DSP_MULTIPLY"
1782   "smultt%?\\t%0, %1, %2"
1783   [(set_attr "type" "smulxy")
1784    (set_attr "predicable" "yes")
1785    (set_attr "predicable_short_it" "no")]
1788 (define_insn "maddhisi4"
1789   [(set (match_operand:SI 0 "s_register_operand" "=r")
1790         (plus:SI (mult:SI (sign_extend:SI
1791                            (match_operand:HI 1 "s_register_operand" "r"))
1792                           (sign_extend:SI
1793                            (match_operand:HI 2 "s_register_operand" "r")))
1794                  (match_operand:SI 3 "s_register_operand" "r")))]
1795   "TARGET_DSP_MULTIPLY"
1796   "smlabb%?\\t%0, %1, %2, %3"
1797   [(set_attr "type" "smlaxy")
1798    (set_attr "predicable" "yes")
1799    (set_attr "predicable_short_it" "no")]
1802 ;; Note: there is no maddhisi4ibt because this one is canonical form
1803 (define_insn "*maddhisi4tb"
1804   [(set (match_operand:SI 0 "s_register_operand" "=r")
1805         (plus:SI (mult:SI (ashiftrt:SI
1806                            (match_operand:SI 1 "s_register_operand" "r")
1807                            (const_int 16))
1808                           (sign_extend:SI
1809                            (match_operand:HI 2 "s_register_operand" "r")))
1810                  (match_operand:SI 3 "s_register_operand" "r")))]
1811   "TARGET_DSP_MULTIPLY"
1812   "smlatb%?\\t%0, %1, %2, %3"
1813   [(set_attr "type" "smlaxy")
1814    (set_attr "predicable" "yes")
1815    (set_attr "predicable_short_it" "no")]
1818 (define_insn "*maddhisi4tt"
1819   [(set (match_operand:SI 0 "s_register_operand" "=r")
1820         (plus:SI (mult:SI (ashiftrt:SI
1821                            (match_operand:SI 1 "s_register_operand" "r")
1822                            (const_int 16))
1823                           (ashiftrt:SI
1824                            (match_operand:SI 2 "s_register_operand" "r")
1825                            (const_int 16)))
1826                  (match_operand:SI 3 "s_register_operand" "r")))]
1827   "TARGET_DSP_MULTIPLY"
1828   "smlatt%?\\t%0, %1, %2, %3"
1829   [(set_attr "type" "smlaxy")
1830    (set_attr "predicable" "yes")
1831    (set_attr "predicable_short_it" "no")]
1834 (define_insn "maddhidi4"
1835   [(set (match_operand:DI 0 "s_register_operand" "=r")
1836         (plus:DI
1837           (mult:DI (sign_extend:DI
1838                     (match_operand:HI 1 "s_register_operand" "r"))
1839                    (sign_extend:DI
1840                     (match_operand:HI 2 "s_register_operand" "r")))
1841           (match_operand:DI 3 "s_register_operand" "0")))]
1842   "TARGET_DSP_MULTIPLY"
1843   "smlalbb%?\\t%Q0, %R0, %1, %2"
1844   [(set_attr "type" "smlalxy")
1845    (set_attr "predicable" "yes")
1846    (set_attr "predicable_short_it" "no")])
1848 ;; Note: there is no maddhidi4ibt because this one is canonical form
1849 (define_insn "*maddhidi4tb"
1850   [(set (match_operand:DI 0 "s_register_operand" "=r")
1851         (plus:DI
1852           (mult:DI (sign_extend:DI
1853                     (ashiftrt:SI
1854                      (match_operand:SI 1 "s_register_operand" "r")
1855                      (const_int 16)))
1856                    (sign_extend:DI
1857                     (match_operand:HI 2 "s_register_operand" "r")))
1858           (match_operand:DI 3 "s_register_operand" "0")))]
1859   "TARGET_DSP_MULTIPLY"
1860   "smlaltb%?\\t%Q0, %R0, %1, %2"
1861   [(set_attr "type" "smlalxy")
1862    (set_attr "predicable" "yes")
1863    (set_attr "predicable_short_it" "no")])
1865 (define_insn "*maddhidi4tt"
1866   [(set (match_operand:DI 0 "s_register_operand" "=r")
1867         (plus:DI
1868           (mult:DI (sign_extend:DI
1869                     (ashiftrt:SI
1870                      (match_operand:SI 1 "s_register_operand" "r")
1871                      (const_int 16)))
1872                    (sign_extend:DI
1873                     (ashiftrt:SI
1874                      (match_operand:SI 2 "s_register_operand" "r")
1875                      (const_int 16))))
1876           (match_operand:DI 3 "s_register_operand" "0")))]
1877   "TARGET_DSP_MULTIPLY"
1878   "smlaltt%?\\t%Q0, %R0, %1, %2"
1879   [(set_attr "type" "smlalxy")
1880    (set_attr "predicable" "yes")
1881    (set_attr "predicable_short_it" "no")])
1883 (define_expand "mulsf3"
1884   [(set (match_operand:SF          0 "s_register_operand" "")
1885         (mult:SF (match_operand:SF 1 "s_register_operand" "")
1886                  (match_operand:SF 2 "s_register_operand" "")))]
1887   "TARGET_32BIT && TARGET_HARD_FLOAT"
1888   "
1891 (define_expand "muldf3"
1892   [(set (match_operand:DF          0 "s_register_operand" "")
1893         (mult:DF (match_operand:DF 1 "s_register_operand" "")
1894                  (match_operand:DF 2 "s_register_operand" "")))]
1895   "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
1896   "
1899 ;; Division insns
1901 (define_expand "divsf3"
1902   [(set (match_operand:SF 0 "s_register_operand" "")
1903         (div:SF (match_operand:SF 1 "s_register_operand" "")
1904                 (match_operand:SF 2 "s_register_operand" "")))]
1905   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
1906   "")
1908 (define_expand "divdf3"
1909   [(set (match_operand:DF 0 "s_register_operand" "")
1910         (div:DF (match_operand:DF 1 "s_register_operand" "")
1911                 (match_operand:DF 2 "s_register_operand" "")))]
1912   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
1913   "")
1915 ;; Boolean and,ior,xor insns
1917 ;; Split up double word logical operations
1919 ;; Split up simple DImode logical operations.  Simply perform the logical
1920 ;; operation on the upper and lower halves of the registers.
1921 (define_split
1922   [(set (match_operand:DI 0 "s_register_operand" "")
1923         (match_operator:DI 6 "logical_binary_operator"
1924           [(match_operand:DI 1 "s_register_operand" "")
1925            (match_operand:DI 2 "s_register_operand" "")]))]
1926   "TARGET_32BIT && reload_completed
1927    && ! (TARGET_NEON && IS_VFP_REGNUM (REGNO (operands[0])))
1928    && ! IS_IWMMXT_REGNUM (REGNO (operands[0]))"
1929   [(set (match_dup 0) (match_op_dup:SI 6 [(match_dup 1) (match_dup 2)]))
1930    (set (match_dup 3) (match_op_dup:SI 6 [(match_dup 4) (match_dup 5)]))]
1931   "
1932   {
1933     operands[3] = gen_highpart (SImode, operands[0]);
1934     operands[0] = gen_lowpart (SImode, operands[0]);
1935     operands[4] = gen_highpart (SImode, operands[1]);
1936     operands[1] = gen_lowpart (SImode, operands[1]);
1937     operands[5] = gen_highpart (SImode, operands[2]);
1938     operands[2] = gen_lowpart (SImode, operands[2]);
1939   }"
1942 (define_split
1943   [(set (match_operand:DI 0 "s_register_operand" "")
1944         (match_operator:DI 6 "logical_binary_operator"
1945           [(sign_extend:DI (match_operand:SI 2 "s_register_operand" ""))
1946            (match_operand:DI 1 "s_register_operand" "")]))]
1947   "TARGET_32BIT && reload_completed"
1948   [(set (match_dup 0) (match_op_dup:SI 6 [(match_dup 1) (match_dup 2)]))
1949    (set (match_dup 3) (match_op_dup:SI 6
1950                         [(ashiftrt:SI (match_dup 2) (const_int 31))
1951                          (match_dup 4)]))]
1952   "
1953   {
1954     operands[3] = gen_highpart (SImode, operands[0]);
1955     operands[0] = gen_lowpart (SImode, operands[0]);
1956     operands[4] = gen_highpart (SImode, operands[1]);
1957     operands[1] = gen_lowpart (SImode, operands[1]);
1958     operands[5] = gen_highpart (SImode, operands[2]);
1959     operands[2] = gen_lowpart (SImode, operands[2]);
1960   }"
1963 ;; The zero extend of operand 2 means we can just copy the high part of
1964 ;; operand1 into operand0.
1965 (define_split
1966   [(set (match_operand:DI 0 "s_register_operand" "")
1967         (ior:DI
1968           (zero_extend:DI (match_operand:SI 2 "s_register_operand" ""))
1969           (match_operand:DI 1 "s_register_operand" "")))]
1970   "TARGET_32BIT && operands[0] != operands[1] && reload_completed"
1971   [(set (match_dup 0) (ior:SI (match_dup 1) (match_dup 2)))
1972    (set (match_dup 3) (match_dup 4))]
1973   "
1974   {
1975     operands[4] = gen_highpart (SImode, operands[1]);
1976     operands[3] = gen_highpart (SImode, operands[0]);
1977     operands[0] = gen_lowpart (SImode, operands[0]);
1978     operands[1] = gen_lowpart (SImode, operands[1]);
1979   }"
1982 ;; The zero extend of operand 2 means we can just copy the high part of
1983 ;; operand1 into operand0.
1984 (define_split
1985   [(set (match_operand:DI 0 "s_register_operand" "")
1986         (xor:DI
1987           (zero_extend:DI (match_operand:SI 2 "s_register_operand" ""))
1988           (match_operand:DI 1 "s_register_operand" "")))]
1989   "TARGET_32BIT && operands[0] != operands[1] && reload_completed"
1990   [(set (match_dup 0) (xor:SI (match_dup 1) (match_dup 2)))
1991    (set (match_dup 3) (match_dup 4))]
1992   "
1993   {
1994     operands[4] = gen_highpart (SImode, operands[1]);
1995     operands[3] = gen_highpart (SImode, operands[0]);
1996     operands[0] = gen_lowpart (SImode, operands[0]);
1997     operands[1] = gen_lowpart (SImode, operands[1]);
1998   }"
2001 (define_expand "anddi3"
2002   [(set (match_operand:DI         0 "s_register_operand" "")
2003         (and:DI (match_operand:DI 1 "s_register_operand" "")
2004                 (match_operand:DI 2 "neon_inv_logic_op2" "")))]
2005   "TARGET_32BIT"
2006   ""
2009 (define_insn_and_split "*anddi3_insn"
2010   [(set (match_operand:DI         0 "s_register_operand"     "=w,w ,&r,&r,&r,&r,?w,?w")
2011         (and:DI (match_operand:DI 1 "s_register_operand"     "%w,0 ,0 ,r ,0 ,r ,w ,0")
2012                 (match_operand:DI 2 "arm_anddi_operand_neon" "w ,DL,r ,r ,De,De,w ,DL")))]
2013   "TARGET_32BIT && !TARGET_IWMMXT"
2015   switch (which_alternative)
2016     {
2017     case 0: /* fall through */
2018     case 6: return "vand\t%P0, %P1, %P2";
2019     case 1: /* fall through */
2020     case 7: return neon_output_logic_immediate ("vand", &operands[2],
2021                     DImode, 1, VALID_NEON_QREG_MODE (DImode));
2022     case 2:
2023     case 3:
2024     case 4:
2025     case 5: /* fall through */
2026       return "#";
2027     default: gcc_unreachable ();
2028     }
2030   "TARGET_32BIT && !TARGET_IWMMXT && reload_completed
2031    && !(IS_VFP_REGNUM (REGNO (operands[0])))"
2032   [(set (match_dup 3) (match_dup 4))
2033    (set (match_dup 5) (match_dup 6))]
2034   "
2035   {
2036     operands[3] = gen_lowpart (SImode, operands[0]);
2037     operands[5] = gen_highpart (SImode, operands[0]);
2039     operands[4] = simplify_gen_binary (AND, SImode,
2040                                            gen_lowpart (SImode, operands[1]),
2041                                            gen_lowpart (SImode, operands[2]));
2042     operands[6] = simplify_gen_binary (AND, SImode,
2043                                            gen_highpart (SImode, operands[1]),
2044                                            gen_highpart_mode (SImode, DImode, operands[2]));
2046   }"
2047   [(set_attr "type" "neon_logic,neon_logic,multiple,multiple,\
2048                      multiple,multiple,neon_logic,neon_logic")
2049    (set_attr "arch" "neon_for_64bits,neon_for_64bits,*,*,*,*,
2050                      avoid_neon_for_64bits,avoid_neon_for_64bits")
2051    (set_attr "length" "*,*,8,8,8,8,*,*")
2052   ]
2055 (define_insn_and_split "*anddi_zesidi_di"
2056   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2057         (and:DI (zero_extend:DI
2058                  (match_operand:SI 2 "s_register_operand" "r,r"))
2059                 (match_operand:DI 1 "s_register_operand" "0,r")))]
2060   "TARGET_32BIT"
2061   "#"
2062   "TARGET_32BIT && reload_completed"
2063   ; The zero extend of operand 2 clears the high word of the output
2064   ; operand.
2065   [(set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))
2066    (set (match_dup 3) (const_int 0))]
2067   "
2068   {
2069     operands[3] = gen_highpart (SImode, operands[0]);
2070     operands[0] = gen_lowpart (SImode, operands[0]);
2071     operands[1] = gen_lowpart (SImode, operands[1]);
2072   }"
2073   [(set_attr "length" "8")
2074    (set_attr "type" "multiple")]
2077 (define_insn "*anddi_sesdi_di"
2078   [(set (match_operand:DI          0 "s_register_operand" "=&r,&r")
2079         (and:DI (sign_extend:DI
2080                  (match_operand:SI 2 "s_register_operand" "r,r"))
2081                 (match_operand:DI  1 "s_register_operand" "0,r")))]
2082   "TARGET_32BIT"
2083   "#"
2084   [(set_attr "length" "8")
2085    (set_attr "type" "multiple")]
2088 (define_expand "andsi3"
2089   [(set (match_operand:SI         0 "s_register_operand" "")
2090         (and:SI (match_operand:SI 1 "s_register_operand" "")
2091                 (match_operand:SI 2 "reg_or_int_operand" "")))]
2092   "TARGET_EITHER"
2093   "
2094   if (TARGET_32BIT)
2095     {
2096       if (CONST_INT_P (operands[2]))
2097         {
2098           if (INTVAL (operands[2]) == 255 && arm_arch6)
2099             {
2100               operands[1] = convert_to_mode (QImode, operands[1], 1);
2101               emit_insn (gen_thumb2_zero_extendqisi2_v6 (operands[0],
2102                                                          operands[1]));
2103               DONE;
2104             }
2105           else if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[2]), AND))
2106             operands[2] = force_reg (SImode, operands[2]);
2107           else
2108             {
2109               arm_split_constant (AND, SImode, NULL_RTX,
2110                                   INTVAL (operands[2]), operands[0],
2111                                   operands[1],
2112                                   optimize && can_create_pseudo_p ());
2114               DONE;
2115             }
2116         }
2117     }
2118   else /* TARGET_THUMB1 */
2119     {
2120       if (!CONST_INT_P (operands[2]))
2121         {
2122           rtx tmp = force_reg (SImode, operands[2]);
2123           if (rtx_equal_p (operands[0], operands[1]))
2124             operands[2] = tmp;
2125           else
2126             {
2127               operands[2] = operands[1];
2128               operands[1] = tmp;
2129             }
2130         }
2131       else
2132         {
2133           int i;
2134           
2135           if (((unsigned HOST_WIDE_INT) ~INTVAL (operands[2])) < 256)
2136             {
2137               operands[2] = force_reg (SImode,
2138                                        GEN_INT (~INTVAL (operands[2])));
2139               
2140               emit_insn (gen_thumb1_bicsi3 (operands[0], operands[2], operands[1]));
2141               
2142               DONE;
2143             }
2145           for (i = 9; i <= 31; i++)
2146             {
2147               if ((HOST_WIDE_INT_1 << i) - 1 == INTVAL (operands[2]))
2148                 {
2149                   emit_insn (gen_extzv (operands[0], operands[1], GEN_INT (i),
2150                                         const0_rtx));
2151                   DONE;
2152                 }
2153               else if ((HOST_WIDE_INT_1 << i) - 1
2154                        == ~INTVAL (operands[2]))
2155                 {
2156                   rtx shift = GEN_INT (i);
2157                   rtx reg = gen_reg_rtx (SImode);
2158                 
2159                   emit_insn (gen_lshrsi3 (reg, operands[1], shift));
2160                   emit_insn (gen_ashlsi3 (operands[0], reg, shift));
2161                   
2162                   DONE;
2163                 }
2164             }
2166           operands[2] = force_reg (SImode, operands[2]);
2167         }
2168     }
2169   "
2172 ; ??? Check split length for Thumb-2
2173 (define_insn_and_split "*arm_andsi3_insn"
2174   [(set (match_operand:SI         0 "s_register_operand" "=r,l,r,r,r")
2175         (and:SI (match_operand:SI 1 "s_register_operand" "%r,0,r,r,r")
2176                 (match_operand:SI 2 "reg_or_int_operand" "I,l,K,r,?n")))]
2177   "TARGET_32BIT"
2178   "@
2179    and%?\\t%0, %1, %2
2180    and%?\\t%0, %1, %2
2181    bic%?\\t%0, %1, #%B2
2182    and%?\\t%0, %1, %2
2183    #"
2184   "TARGET_32BIT
2185    && CONST_INT_P (operands[2])
2186    && !(const_ok_for_arm (INTVAL (operands[2]))
2187         || const_ok_for_arm (~INTVAL (operands[2])))"
2188   [(clobber (const_int 0))]
2189   "
2190   arm_split_constant  (AND, SImode, curr_insn, 
2191                        INTVAL (operands[2]), operands[0], operands[1], 0);
2192   DONE;
2193   "
2194   [(set_attr "length" "4,4,4,4,16")
2195    (set_attr "predicable" "yes")
2196    (set_attr "predicable_short_it" "no,yes,no,no,no")
2197    (set_attr "type" "logic_imm,logic_imm,logic_reg,logic_reg,logic_imm")]
2200 (define_insn "*andsi3_compare0"
2201   [(set (reg:CC_NOOV CC_REGNUM)
2202         (compare:CC_NOOV
2203          (and:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
2204                  (match_operand:SI 2 "arm_not_operand" "I,K,r"))
2205          (const_int 0)))
2206    (set (match_operand:SI          0 "s_register_operand" "=r,r,r")
2207         (and:SI (match_dup 1) (match_dup 2)))]
2208   "TARGET_32BIT"
2209   "@
2210    ands%?\\t%0, %1, %2
2211    bics%?\\t%0, %1, #%B2
2212    ands%?\\t%0, %1, %2"
2213   [(set_attr "conds" "set")
2214    (set_attr "type" "logics_imm,logics_imm,logics_reg")]
2217 (define_insn "*andsi3_compare0_scratch"
2218   [(set (reg:CC_NOOV CC_REGNUM)
2219         (compare:CC_NOOV
2220          (and:SI (match_operand:SI 0 "s_register_operand" "r,r,r")
2221                  (match_operand:SI 1 "arm_not_operand" "I,K,r"))
2222          (const_int 0)))
2223    (clobber (match_scratch:SI 2 "=X,r,X"))]
2224   "TARGET_32BIT"
2225   "@
2226    tst%?\\t%0, %1
2227    bics%?\\t%2, %0, #%B1
2228    tst%?\\t%0, %1"
2229   [(set_attr "conds" "set")
2230    (set_attr "type"  "logics_imm,logics_imm,logics_reg")]
2233 (define_insn "*zeroextractsi_compare0_scratch"
2234   [(set (reg:CC_NOOV CC_REGNUM)
2235         (compare:CC_NOOV (zero_extract:SI
2236                           (match_operand:SI 0 "s_register_operand" "r")
2237                           (match_operand 1 "const_int_operand" "n")
2238                           (match_operand 2 "const_int_operand" "n"))
2239                          (const_int 0)))]
2240   "TARGET_32BIT
2241   && (INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) < 32
2242       && INTVAL (operands[1]) > 0 
2243       && INTVAL (operands[1]) + (INTVAL (operands[2]) & 1) <= 8
2244       && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32)"
2245   "*
2246   operands[1] = GEN_INT (((1 << INTVAL (operands[1])) - 1)
2247                          << INTVAL (operands[2]));
2248   output_asm_insn (\"tst%?\\t%0, %1\", operands);
2249   return \"\";
2250   "
2251   [(set_attr "conds" "set")
2252    (set_attr "predicable" "yes")
2253    (set_attr "predicable_short_it" "no")
2254    (set_attr "type" "logics_imm")]
2257 (define_insn_and_split "*ne_zeroextractsi"
2258   [(set (match_operand:SI 0 "s_register_operand" "=r")
2259         (ne:SI (zero_extract:SI
2260                 (match_operand:SI 1 "s_register_operand" "r")
2261                 (match_operand:SI 2 "const_int_operand" "n")
2262                 (match_operand:SI 3 "const_int_operand" "n"))
2263                (const_int 0)))
2264    (clobber (reg:CC CC_REGNUM))]
2265   "TARGET_32BIT
2266    && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2267        && INTVAL (operands[2]) > 0 
2268        && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2269        && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)"
2270   "#"
2271   "TARGET_32BIT
2272    && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2273        && INTVAL (operands[2]) > 0 
2274        && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2275        && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)"
2276   [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2277                    (compare:CC_NOOV (and:SI (match_dup 1) (match_dup 2))
2278                                     (const_int 0)))
2279               (set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))])
2280    (set (match_dup 0)
2281         (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2282                          (match_dup 0) (const_int 1)))]
2283   "
2284   operands[2] = GEN_INT (((1 << INTVAL (operands[2])) - 1)
2285                          << INTVAL (operands[3])); 
2286   "
2287   [(set_attr "conds" "clob")
2288    (set (attr "length")
2289         (if_then_else (eq_attr "is_thumb" "yes")
2290                       (const_int 12)
2291                       (const_int 8)))
2292    (set_attr "type" "multiple")]
2295 (define_insn_and_split "*ne_zeroextractsi_shifted"
2296   [(set (match_operand:SI 0 "s_register_operand" "=r")
2297         (ne:SI (zero_extract:SI
2298                 (match_operand:SI 1 "s_register_operand" "r")
2299                 (match_operand:SI 2 "const_int_operand" "n")
2300                 (const_int 0))
2301                (const_int 0)))
2302    (clobber (reg:CC CC_REGNUM))]
2303   "TARGET_ARM"
2304   "#"
2305   "TARGET_ARM"
2306   [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2307                    (compare:CC_NOOV (ashift:SI (match_dup 1) (match_dup 2))
2308                                     (const_int 0)))
2309               (set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))])
2310    (set (match_dup 0)
2311         (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2312                          (match_dup 0) (const_int 1)))]
2313   "
2314   operands[2] = GEN_INT (32 - INTVAL (operands[2]));
2315   "
2316   [(set_attr "conds" "clob")
2317    (set_attr "length" "8")
2318    (set_attr "type" "multiple")]
2321 (define_insn_and_split "*ite_ne_zeroextractsi"
2322   [(set (match_operand:SI 0 "s_register_operand" "=r")
2323         (if_then_else:SI (ne (zero_extract:SI
2324                               (match_operand:SI 1 "s_register_operand" "r")
2325                               (match_operand:SI 2 "const_int_operand" "n")
2326                               (match_operand:SI 3 "const_int_operand" "n"))
2327                              (const_int 0))
2328                          (match_operand:SI 4 "arm_not_operand" "rIK")
2329                          (const_int 0)))
2330    (clobber (reg:CC CC_REGNUM))]
2331   "TARGET_ARM
2332    && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2333        && INTVAL (operands[2]) > 0 
2334        && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2335        && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)
2336    && !reg_overlap_mentioned_p (operands[0], operands[4])"
2337   "#"
2338   "TARGET_ARM
2339    && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2340        && INTVAL (operands[2]) > 0 
2341        && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2342        && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)
2343    && !reg_overlap_mentioned_p (operands[0], operands[4])"
2344   [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2345                    (compare:CC_NOOV (and:SI (match_dup 1) (match_dup 2))
2346                                     (const_int 0)))
2347               (set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))])
2348    (set (match_dup 0)
2349         (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2350                          (match_dup 0) (match_dup 4)))]
2351   "
2352   operands[2] = GEN_INT (((1 << INTVAL (operands[2])) - 1)
2353                          << INTVAL (operands[3])); 
2354   "
2355   [(set_attr "conds" "clob")
2356    (set_attr "length" "8")
2357    (set_attr "type" "multiple")]
2360 (define_insn_and_split "*ite_ne_zeroextractsi_shifted"
2361   [(set (match_operand:SI 0 "s_register_operand" "=r")
2362         (if_then_else:SI (ne (zero_extract:SI
2363                               (match_operand:SI 1 "s_register_operand" "r")
2364                               (match_operand:SI 2 "const_int_operand" "n")
2365                               (const_int 0))
2366                              (const_int 0))
2367                          (match_operand:SI 3 "arm_not_operand" "rIK")
2368                          (const_int 0)))
2369    (clobber (reg:CC CC_REGNUM))]
2370   "TARGET_ARM && !reg_overlap_mentioned_p (operands[0], operands[3])"
2371   "#"
2372   "TARGET_ARM && !reg_overlap_mentioned_p (operands[0], operands[3])"
2373   [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2374                    (compare:CC_NOOV (ashift:SI (match_dup 1) (match_dup 2))
2375                                     (const_int 0)))
2376               (set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))])
2377    (set (match_dup 0)
2378         (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2379                          (match_dup 0) (match_dup 3)))]
2380   "
2381   operands[2] = GEN_INT (32 - INTVAL (operands[2]));
2382   "
2383   [(set_attr "conds" "clob")
2384    (set_attr "length" "8")
2385    (set_attr "type" "multiple")]
2388 ;; ??? Use Thumb-2 has bitfield insert/extract instructions.
2389 (define_split
2390   [(set (match_operand:SI 0 "s_register_operand" "")
2391         (match_operator:SI 1 "shiftable_operator"
2392          [(zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
2393                            (match_operand:SI 3 "const_int_operand" "")
2394                            (match_operand:SI 4 "const_int_operand" ""))
2395           (match_operand:SI 5 "s_register_operand" "")]))
2396    (clobber (match_operand:SI 6 "s_register_operand" ""))]
2397   "TARGET_ARM"
2398   [(set (match_dup 6) (ashift:SI (match_dup 2) (match_dup 3)))
2399    (set (match_dup 0)
2400         (match_op_dup 1
2401          [(lshiftrt:SI (match_dup 6) (match_dup 4))
2402           (match_dup 5)]))]
2403   "{
2404      HOST_WIDE_INT temp = INTVAL (operands[3]);
2406      operands[3] = GEN_INT (32 - temp - INTVAL (operands[4]));
2407      operands[4] = GEN_INT (32 - temp);
2408    }"
2410   
2411 (define_split
2412   [(set (match_operand:SI 0 "s_register_operand" "")
2413         (match_operator:SI 1 "shiftable_operator"
2414          [(sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
2415                            (match_operand:SI 3 "const_int_operand" "")
2416                            (match_operand:SI 4 "const_int_operand" ""))
2417           (match_operand:SI 5 "s_register_operand" "")]))
2418    (clobber (match_operand:SI 6 "s_register_operand" ""))]
2419   "TARGET_ARM"
2420   [(set (match_dup 6) (ashift:SI (match_dup 2) (match_dup 3)))
2421    (set (match_dup 0)
2422         (match_op_dup 1
2423          [(ashiftrt:SI (match_dup 6) (match_dup 4))
2424           (match_dup 5)]))]
2425   "{
2426      HOST_WIDE_INT temp = INTVAL (operands[3]);
2428      operands[3] = GEN_INT (32 - temp - INTVAL (operands[4]));
2429      operands[4] = GEN_INT (32 - temp);
2430    }"
2432   
2433 ;;; ??? This pattern is bogus.  If operand3 has bits outside the range
2434 ;;; represented by the bitfield, then this will produce incorrect results.
2435 ;;; Somewhere, the value needs to be truncated.  On targets like the m68k,
2436 ;;; which have a real bit-field insert instruction, the truncation happens
2437 ;;; in the bit-field insert instruction itself.  Since arm does not have a
2438 ;;; bit-field insert instruction, we would have to emit code here to truncate
2439 ;;; the value before we insert.  This loses some of the advantage of having
2440 ;;; this insv pattern, so this pattern needs to be reevalutated.
2442 (define_expand "insv"
2443   [(set (zero_extract (match_operand 0 "nonimmediate_operand" "")
2444                       (match_operand 1 "general_operand" "")
2445                       (match_operand 2 "general_operand" ""))
2446         (match_operand 3 "reg_or_int_operand" ""))]
2447   "TARGET_ARM || arm_arch_thumb2"
2448   "
2449   {
2450     int start_bit = INTVAL (operands[2]);
2451     int width = INTVAL (operands[1]);
2452     HOST_WIDE_INT mask = (HOST_WIDE_INT_1 << width) - 1;
2453     rtx target, subtarget;
2455     if (arm_arch_thumb2)
2456       {
2457         if (unaligned_access && MEM_P (operands[0])
2458             && s_register_operand (operands[3], GET_MODE (operands[3]))
2459             && (width == 16 || width == 32) && (start_bit % BITS_PER_UNIT) == 0)
2460           {
2461             rtx base_addr;
2463             if (BYTES_BIG_ENDIAN)
2464               start_bit = GET_MODE_BITSIZE (GET_MODE (operands[3])) - width
2465                           - start_bit;
2467             if (width == 32)
2468               {
2469                 base_addr = adjust_address (operands[0], SImode,
2470                                             start_bit / BITS_PER_UNIT);
2471                 emit_insn (gen_unaligned_storesi (base_addr, operands[3]));
2472               }
2473             else
2474               {
2475                 rtx tmp = gen_reg_rtx (HImode);
2477                 base_addr = adjust_address (operands[0], HImode,
2478                                             start_bit / BITS_PER_UNIT);
2479                 emit_move_insn (tmp, gen_lowpart (HImode, operands[3]));
2480                 emit_insn (gen_unaligned_storehi (base_addr, tmp));
2481               }
2482             DONE;
2483           }
2484         else if (s_register_operand (operands[0], GET_MODE (operands[0])))
2485           {
2486             bool use_bfi = TRUE;
2488             if (CONST_INT_P (operands[3]))
2489               {
2490                 HOST_WIDE_INT val = INTVAL (operands[3]) & mask;
2492                 if (val == 0)
2493                   {
2494                     emit_insn (gen_insv_zero (operands[0], operands[1],
2495                                               operands[2]));
2496                     DONE;
2497                   }
2499                 /* See if the set can be done with a single orr instruction.  */
2500                 if (val == mask && const_ok_for_arm (val << start_bit))
2501                   use_bfi = FALSE;
2502               }
2504             if (use_bfi)
2505               {
2506                 if (!REG_P (operands[3]))
2507                   operands[3] = force_reg (SImode, operands[3]);
2509                 emit_insn (gen_insv_t2 (operands[0], operands[1], operands[2],
2510                                         operands[3]));
2511                 DONE;
2512               }
2513           }
2514         else
2515           FAIL;
2516       }
2518     if (!s_register_operand (operands[0], GET_MODE (operands[0])))
2519       FAIL;
2521     target = copy_rtx (operands[0]);
2522     /* Avoid using a subreg as a subtarget, and avoid writing a paradoxical 
2523        subreg as the final target.  */
2524     if (GET_CODE (target) == SUBREG)
2525       {
2526         subtarget = gen_reg_rtx (SImode);
2527         if (GET_MODE_SIZE (GET_MODE (SUBREG_REG (target)))
2528             < GET_MODE_SIZE (SImode))
2529           target = SUBREG_REG (target);
2530       }
2531     else
2532       subtarget = target;    
2534     if (CONST_INT_P (operands[3]))
2535       {
2536         /* Since we are inserting a known constant, we may be able to
2537            reduce the number of bits that we have to clear so that
2538            the mask becomes simple.  */
2539         /* ??? This code does not check to see if the new mask is actually
2540            simpler.  It may not be.  */
2541         rtx op1 = gen_reg_rtx (SImode);
2542         /* ??? Truncate operand3 to fit in the bitfield.  See comment before
2543            start of this pattern.  */
2544         HOST_WIDE_INT op3_value = mask & INTVAL (operands[3]);
2545         HOST_WIDE_INT mask2 = ((mask & ~op3_value) << start_bit);
2547         emit_insn (gen_andsi3 (op1, operands[0],
2548                                gen_int_mode (~mask2, SImode)));
2549         emit_insn (gen_iorsi3 (subtarget, op1,
2550                                gen_int_mode (op3_value << start_bit, SImode)));
2551       }
2552     else if (start_bit == 0
2553              && !(const_ok_for_arm (mask)
2554                   || const_ok_for_arm (~mask)))
2555       {
2556         /* A Trick, since we are setting the bottom bits in the word,
2557            we can shift operand[3] up, operand[0] down, OR them together
2558            and rotate the result back again.  This takes 3 insns, and
2559            the third might be mergeable into another op.  */
2560         /* The shift up copes with the possibility that operand[3] is
2561            wider than the bitfield.  */
2562         rtx op0 = gen_reg_rtx (SImode);
2563         rtx op1 = gen_reg_rtx (SImode);
2565         emit_insn (gen_ashlsi3 (op0, operands[3], GEN_INT (32 - width)));
2566         emit_insn (gen_lshrsi3 (op1, operands[0], operands[1]));
2567         emit_insn (gen_iorsi3  (op1, op1, op0));
2568         emit_insn (gen_rotlsi3 (subtarget, op1, operands[1]));
2569       }
2570     else if ((width + start_bit == 32)
2571              && !(const_ok_for_arm (mask)
2572                   || const_ok_for_arm (~mask)))
2573       {
2574         /* Similar trick, but slightly less efficient.  */
2576         rtx op0 = gen_reg_rtx (SImode);
2577         rtx op1 = gen_reg_rtx (SImode);
2579         emit_insn (gen_ashlsi3 (op0, operands[3], GEN_INT (32 - width)));
2580         emit_insn (gen_ashlsi3 (op1, operands[0], operands[1]));
2581         emit_insn (gen_lshrsi3 (op1, op1, operands[1]));
2582         emit_insn (gen_iorsi3 (subtarget, op1, op0));
2583       }
2584     else
2585       {
2586         rtx op0 = gen_int_mode (mask, SImode);
2587         rtx op1 = gen_reg_rtx (SImode);
2588         rtx op2 = gen_reg_rtx (SImode);
2590         if (!(const_ok_for_arm (mask) || const_ok_for_arm (~mask)))
2591           {
2592             rtx tmp = gen_reg_rtx (SImode);
2594             emit_insn (gen_movsi (tmp, op0));
2595             op0 = tmp;
2596           }
2598         /* Mask out any bits in operand[3] that are not needed.  */
2599            emit_insn (gen_andsi3 (op1, operands[3], op0));
2601         if (CONST_INT_P (op0)
2602             && (const_ok_for_arm (mask << start_bit)
2603                 || const_ok_for_arm (~(mask << start_bit))))
2604           {
2605             op0 = gen_int_mode (~(mask << start_bit), SImode);
2606             emit_insn (gen_andsi3 (op2, operands[0], op0));
2607           }
2608         else
2609           {
2610             if (CONST_INT_P (op0))
2611               {
2612                 rtx tmp = gen_reg_rtx (SImode);
2614                 emit_insn (gen_movsi (tmp, op0));
2615                 op0 = tmp;
2616               }
2618             if (start_bit != 0)
2619               emit_insn (gen_ashlsi3 (op0, op0, operands[2]));
2620             
2621             emit_insn (gen_andsi_notsi_si (op2, operands[0], op0));
2622           }
2624         if (start_bit != 0)
2625           emit_insn (gen_ashlsi3 (op1, op1, operands[2]));
2627         emit_insn (gen_iorsi3 (subtarget, op1, op2));
2628       }
2630     if (subtarget != target)
2631       {
2632         /* If TARGET is still a SUBREG, then it must be wider than a word,
2633            so we must be careful only to set the subword we were asked to.  */
2634         if (GET_CODE (target) == SUBREG)
2635           emit_move_insn (target, subtarget);
2636         else
2637           emit_move_insn (target, gen_lowpart (GET_MODE (target), subtarget));
2638       }
2640     DONE;
2641   }"
2644 (define_insn "insv_zero"
2645   [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r")
2646                          (match_operand:SI 1 "const_int_M_operand" "M")
2647                          (match_operand:SI 2 "const_int_M_operand" "M"))
2648         (const_int 0))]
2649   "arm_arch_thumb2"
2650   "bfc%?\t%0, %2, %1"
2651   [(set_attr "length" "4")
2652    (set_attr "predicable" "yes")
2653    (set_attr "predicable_short_it" "no")
2654    (set_attr "type" "bfm")]
2657 (define_insn "insv_t2"
2658   [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r")
2659                          (match_operand:SI 1 "const_int_M_operand" "M")
2660                          (match_operand:SI 2 "const_int_M_operand" "M"))
2661         (match_operand:SI 3 "s_register_operand" "r"))]
2662   "arm_arch_thumb2"
2663   "bfi%?\t%0, %3, %2, %1"
2664   [(set_attr "length" "4")
2665    (set_attr "predicable" "yes")
2666    (set_attr "predicable_short_it" "no")
2667    (set_attr "type" "bfm")]
2670 ; constants for op 2 will never be given to these patterns.
2671 (define_insn_and_split "*anddi_notdi_di"
2672   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2673         (and:DI (not:DI (match_operand:DI 1 "s_register_operand" "0,r"))
2674                 (match_operand:DI 2 "s_register_operand" "r,0")))]
2675   "TARGET_32BIT"
2676   "#"
2677   "TARGET_32BIT && reload_completed
2678    && ! (TARGET_NEON && IS_VFP_REGNUM (REGNO (operands[0])))
2679    && ! IS_IWMMXT_REGNUM (REGNO (operands[0]))"
2680   [(set (match_dup 0) (and:SI (not:SI (match_dup 1)) (match_dup 2)))
2681    (set (match_dup 3) (and:SI (not:SI (match_dup 4)) (match_dup 5)))]
2682   "
2683   {
2684     operands[3] = gen_highpart (SImode, operands[0]);
2685     operands[0] = gen_lowpart (SImode, operands[0]);
2686     operands[4] = gen_highpart (SImode, operands[1]);
2687     operands[1] = gen_lowpart (SImode, operands[1]);
2688     operands[5] = gen_highpart (SImode, operands[2]);
2689     operands[2] = gen_lowpart (SImode, operands[2]);
2690   }"
2691   [(set_attr "length" "8")
2692    (set_attr "predicable" "yes")
2693    (set_attr "type" "multiple")]
2696 (define_insn_and_split "*anddi_notzesidi_di"
2697   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2698         (and:DI (not:DI (zero_extend:DI
2699                          (match_operand:SI 2 "s_register_operand" "r,r")))
2700                 (match_operand:DI 1 "s_register_operand" "0,?r")))]
2701   "TARGET_32BIT"
2702   "@
2703    bic%?\\t%Q0, %Q1, %2
2704    #"
2705   ; (not (zero_extend ...)) allows us to just copy the high word from
2706   ; operand1 to operand0.
2707   "TARGET_32BIT
2708    && reload_completed
2709    && operands[0] != operands[1]"
2710   [(set (match_dup 0) (and:SI (not:SI (match_dup 2)) (match_dup 1)))
2711    (set (match_dup 3) (match_dup 4))]
2712   "
2713   {
2714     operands[3] = gen_highpart (SImode, operands[0]);
2715     operands[0] = gen_lowpart (SImode, operands[0]);
2716     operands[4] = gen_highpart (SImode, operands[1]);
2717     operands[1] = gen_lowpart (SImode, operands[1]);
2718   }"
2719   [(set_attr "length" "4,8")
2720    (set_attr "predicable" "yes")
2721    (set_attr "predicable_short_it" "no")
2722    (set_attr "type" "multiple")]
2725 (define_insn_and_split "*anddi_notdi_zesidi"
2726   [(set (match_operand:DI 0 "s_register_operand" "=r")
2727         (and:DI (not:DI (match_operand:DI 2 "s_register_operand" "r"))
2728                 (zero_extend:DI
2729                  (match_operand:SI 1 "s_register_operand" "r"))))]
2730   "TARGET_32BIT"
2731   "#"
2732   "TARGET_32BIT && reload_completed"
2733   [(set (match_dup 0) (and:SI (not:SI (match_dup 2)) (match_dup 1)))
2734    (set (match_dup 3) (const_int 0))]
2735   "
2736   {
2737     operands[3] = gen_highpart (SImode, operands[0]);
2738     operands[0] = gen_lowpart (SImode, operands[0]);
2739     operands[2] = gen_lowpart (SImode, operands[2]);
2740   }"
2741   [(set_attr "length" "8")
2742    (set_attr "predicable" "yes")
2743    (set_attr "predicable_short_it" "no")
2744    (set_attr "type" "multiple")]
2747 (define_insn_and_split "*anddi_notsesidi_di"
2748   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2749         (and:DI (not:DI (sign_extend:DI
2750                          (match_operand:SI 2 "s_register_operand" "r,r")))
2751                 (match_operand:DI 1 "s_register_operand" "0,r")))]
2752   "TARGET_32BIT"
2753   "#"
2754   "TARGET_32BIT && reload_completed"
2755   [(set (match_dup 0) (and:SI (not:SI (match_dup 2)) (match_dup 1)))
2756    (set (match_dup 3) (and:SI (not:SI
2757                                 (ashiftrt:SI (match_dup 2) (const_int 31)))
2758                                (match_dup 4)))]
2759   "
2760   {
2761     operands[3] = gen_highpart (SImode, operands[0]);
2762     operands[0] = gen_lowpart (SImode, operands[0]);
2763     operands[4] = gen_highpart (SImode, operands[1]);
2764     operands[1] = gen_lowpart (SImode, operands[1]);
2765   }"
2766   [(set_attr "length" "8")
2767    (set_attr "predicable" "yes")
2768    (set_attr "predicable_short_it" "no")
2769    (set_attr "type" "multiple")]
2772 (define_insn "andsi_notsi_si"
2773   [(set (match_operand:SI 0 "s_register_operand" "=r")
2774         (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
2775                 (match_operand:SI 1 "s_register_operand" "r")))]
2776   "TARGET_32BIT"
2777   "bic%?\\t%0, %1, %2"
2778   [(set_attr "predicable" "yes")
2779    (set_attr "predicable_short_it" "no")
2780    (set_attr "type" "logic_reg")]
2783 (define_insn "andsi_not_shiftsi_si"
2784   [(set (match_operand:SI 0 "s_register_operand" "=r")
2785         (and:SI (not:SI (match_operator:SI 4 "shift_operator"
2786                          [(match_operand:SI 2 "s_register_operand" "r")
2787                           (match_operand:SI 3 "arm_rhs_operand" "rM")]))
2788                 (match_operand:SI 1 "s_register_operand" "r")))]
2789   "TARGET_ARM"
2790   "bic%?\\t%0, %1, %2%S4"
2791   [(set_attr "predicable" "yes")
2792    (set_attr "shift" "2")
2793    (set (attr "type") (if_then_else (match_operand 3 "const_int_operand" "")
2794                       (const_string "logic_shift_imm")
2795                       (const_string "logic_shift_reg")))]
2798 ;; Shifted bics pattern used to set up CC status register and not reusing
2799 ;; bics output.  Pattern restricts Thumb2 shift operand as bics for Thumb2
2800 ;; does not support shift by register.
2801 (define_insn "andsi_not_shiftsi_si_scc_no_reuse"
2802   [(set (reg:CC_NOOV CC_REGNUM)
2803         (compare:CC_NOOV
2804                 (and:SI (not:SI (match_operator:SI 0 "shift_operator"
2805                         [(match_operand:SI 1 "s_register_operand" "r")
2806                          (match_operand:SI 2 "arm_rhs_operand" "rM")]))
2807                         (match_operand:SI 3 "s_register_operand" "r"))
2808                 (const_int 0)))
2809    (clobber (match_scratch:SI 4 "=r"))]
2810   "TARGET_ARM || (TARGET_THUMB2 && CONST_INT_P (operands[2]))"
2811   "bics%?\\t%4, %3, %1%S0"
2812   [(set_attr "predicable" "yes")
2813    (set_attr "predicable_short_it" "no")
2814    (set_attr "conds" "set")
2815    (set_attr "shift" "1")
2816    (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
2817                       (const_string "logic_shift_imm")
2818                       (const_string "logic_shift_reg")))]
2821 ;; Same as andsi_not_shiftsi_si_scc_no_reuse, but the bics result is also
2822 ;; getting reused later.
2823 (define_insn "andsi_not_shiftsi_si_scc"
2824   [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2825         (compare:CC_NOOV
2826                 (and:SI (not:SI (match_operator:SI 0 "shift_operator"
2827                         [(match_operand:SI 1 "s_register_operand" "r")
2828                          (match_operand:SI 2 "arm_rhs_operand" "rM")]))
2829                         (match_operand:SI 3 "s_register_operand" "r"))
2830                 (const_int 0)))
2831         (set (match_operand:SI 4 "s_register_operand" "=r")
2832              (and:SI (not:SI (match_op_dup 0
2833                      [(match_dup 1)
2834                       (match_dup 2)]))
2835                      (match_dup 3)))])]
2836   "TARGET_ARM || (TARGET_THUMB2 && CONST_INT_P (operands[2]))"
2837   "bics%?\\t%4, %3, %1%S0"
2838   [(set_attr "predicable" "yes")
2839    (set_attr "predicable_short_it" "no")
2840    (set_attr "conds" "set")
2841    (set_attr "shift" "1")
2842    (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
2843                       (const_string "logic_shift_imm")
2844                       (const_string "logic_shift_reg")))]
2847 (define_insn "*andsi_notsi_si_compare0"
2848   [(set (reg:CC_NOOV CC_REGNUM)
2849         (compare:CC_NOOV
2850          (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
2851                  (match_operand:SI 1 "s_register_operand" "r"))
2852          (const_int 0)))
2853    (set (match_operand:SI 0 "s_register_operand" "=r")
2854         (and:SI (not:SI (match_dup 2)) (match_dup 1)))]
2855   "TARGET_32BIT"
2856   "bics\\t%0, %1, %2"
2857   [(set_attr "conds" "set")
2858    (set_attr "type" "logics_shift_reg")]
2861 (define_insn "*andsi_notsi_si_compare0_scratch"
2862   [(set (reg:CC_NOOV CC_REGNUM)
2863         (compare:CC_NOOV
2864          (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
2865                  (match_operand:SI 1 "s_register_operand" "r"))
2866          (const_int 0)))
2867    (clobber (match_scratch:SI 0 "=r"))]
2868   "TARGET_32BIT"
2869   "bics\\t%0, %1, %2"
2870   [(set_attr "conds" "set")
2871    (set_attr "type" "logics_shift_reg")]
2874 (define_expand "iordi3"
2875   [(set (match_operand:DI         0 "s_register_operand" "")
2876         (ior:DI (match_operand:DI 1 "s_register_operand" "")
2877                 (match_operand:DI 2 "neon_logic_op2" "")))]
2878   "TARGET_32BIT"
2879   ""
2882 (define_insn_and_split "*iordi3_insn"
2883   [(set (match_operand:DI         0 "s_register_operand"     "=w,w ,&r,&r,&r,&r,?w,?w")
2884         (ior:DI (match_operand:DI 1 "s_register_operand"     "%w,0 ,0 ,r ,0 ,r ,w ,0")
2885                 (match_operand:DI 2 "arm_iordi_operand_neon" "w ,Dl,r ,r ,Df,Df,w ,Dl")))]
2886   "TARGET_32BIT && !TARGET_IWMMXT"
2887   {
2888   switch (which_alternative)
2889     {
2890     case 0: /* fall through */
2891     case 6: return "vorr\t%P0, %P1, %P2";
2892     case 1: /* fall through */
2893     case 7: return neon_output_logic_immediate ("vorr", &operands[2],
2894                      DImode, 0, VALID_NEON_QREG_MODE (DImode));
2895     case 2:
2896     case 3:
2897     case 4:
2898     case 5:
2899       return "#";
2900     default: gcc_unreachable ();
2901     }
2902   }
2903   "TARGET_32BIT && !TARGET_IWMMXT && reload_completed
2904    && !(IS_VFP_REGNUM (REGNO (operands[0])))"
2905   [(set (match_dup 3) (match_dup 4))
2906    (set (match_dup 5) (match_dup 6))]
2907   "
2908   {
2909     operands[3] = gen_lowpart (SImode, operands[0]);
2910     operands[5] = gen_highpart (SImode, operands[0]);
2912     operands[4] = simplify_gen_binary (IOR, SImode,
2913                                            gen_lowpart (SImode, operands[1]),
2914                                            gen_lowpart (SImode, operands[2]));
2915     operands[6] = simplify_gen_binary (IOR, SImode,
2916                                            gen_highpart (SImode, operands[1]),
2917                                            gen_highpart_mode (SImode, DImode, operands[2]));
2919   }"
2920   [(set_attr "type" "neon_logic,neon_logic,multiple,multiple,multiple,\
2921                      multiple,neon_logic,neon_logic")
2922    (set_attr "length" "*,*,8,8,8,8,*,*")
2923    (set_attr "arch" "neon_for_64bits,neon_for_64bits,*,*,*,*,avoid_neon_for_64bits,avoid_neon_for_64bits")]
2926 (define_insn "*iordi_zesidi_di"
2927   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2928         (ior:DI (zero_extend:DI
2929                  (match_operand:SI 2 "s_register_operand" "r,r"))
2930                 (match_operand:DI 1 "s_register_operand" "0,?r")))]
2931   "TARGET_32BIT"
2932   "@
2933    orr%?\\t%Q0, %Q1, %2
2934    #"
2935   [(set_attr "length" "4,8")
2936    (set_attr "predicable" "yes")
2937    (set_attr "predicable_short_it" "no")
2938    (set_attr "type" "logic_reg,multiple")]
2941 (define_insn "*iordi_sesidi_di"
2942   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2943         (ior:DI (sign_extend:DI
2944                  (match_operand:SI 2 "s_register_operand" "r,r"))
2945                 (match_operand:DI 1 "s_register_operand" "0,r")))]
2946   "TARGET_32BIT"
2947   "#"
2948   [(set_attr "length" "8")
2949    (set_attr "predicable" "yes")
2950    (set_attr "type" "multiple")]
2953 (define_expand "iorsi3"
2954   [(set (match_operand:SI         0 "s_register_operand" "")
2955         (ior:SI (match_operand:SI 1 "s_register_operand" "")
2956                 (match_operand:SI 2 "reg_or_int_operand" "")))]
2957   "TARGET_EITHER"
2958   "
2959   if (CONST_INT_P (operands[2]))
2960     {
2961       if (TARGET_32BIT)
2962         {
2963           if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[2]), IOR))
2964             operands[2] = force_reg (SImode, operands[2]);
2965           else
2966             {
2967               arm_split_constant (IOR, SImode, NULL_RTX,
2968                                   INTVAL (operands[2]), operands[0],
2969                                   operands[1],
2970                                   optimize && can_create_pseudo_p ());
2971               DONE;
2972             }
2973         }
2974       else /* TARGET_THUMB1 */
2975         {
2976           rtx tmp = force_reg (SImode, operands[2]);
2977           if (rtx_equal_p (operands[0], operands[1]))
2978             operands[2] = tmp;
2979           else
2980             {
2981               operands[2] = operands[1];
2982               operands[1] = tmp;
2983             }
2984         }
2985     }
2986   "
2989 (define_insn_and_split "*iorsi3_insn"
2990   [(set (match_operand:SI 0 "s_register_operand" "=r,l,r,r,r")
2991         (ior:SI (match_operand:SI 1 "s_register_operand" "%r,0,r,r,r")
2992                 (match_operand:SI 2 "reg_or_int_operand" "I,l,K,r,?n")))]
2993   "TARGET_32BIT"
2994   "@
2995    orr%?\\t%0, %1, %2
2996    orr%?\\t%0, %1, %2
2997    orn%?\\t%0, %1, #%B2
2998    orr%?\\t%0, %1, %2
2999    #"
3000   "TARGET_32BIT
3001    && CONST_INT_P (operands[2])
3002    && !(const_ok_for_arm (INTVAL (operands[2]))
3003         || (TARGET_THUMB2 && const_ok_for_arm (~INTVAL (operands[2]))))"
3004   [(clobber (const_int 0))]
3006   arm_split_constant (IOR, SImode, curr_insn,
3007                       INTVAL (operands[2]), operands[0], operands[1], 0);
3008   DONE;
3010   [(set_attr "length" "4,4,4,4,16")
3011    (set_attr "arch" "32,t2,t2,32,32")
3012    (set_attr "predicable" "yes")
3013    (set_attr "predicable_short_it" "no,yes,no,no,no")
3014    (set_attr "type" "logic_imm,logic_reg,logic_imm,logic_reg,logic_reg")]
3017 (define_peephole2
3018   [(match_scratch:SI 3 "r")
3019    (set (match_operand:SI 0 "arm_general_register_operand" "")
3020         (ior:SI (match_operand:SI 1 "arm_general_register_operand" "")
3021                 (match_operand:SI 2 "const_int_operand" "")))]
3022   "TARGET_ARM
3023    && !const_ok_for_arm (INTVAL (operands[2]))
3024    && const_ok_for_arm (~INTVAL (operands[2]))"
3025   [(set (match_dup 3) (match_dup 2))
3026    (set (match_dup 0) (ior:SI (match_dup 1) (match_dup 3)))]
3027   ""
3030 (define_insn "*iorsi3_compare0"
3031   [(set (reg:CC_NOOV CC_REGNUM)
3032         (compare:CC_NOOV (ior:SI (match_operand:SI 1 "s_register_operand" "%r,r")
3033                                  (match_operand:SI 2 "arm_rhs_operand" "I,r"))
3034                          (const_int 0)))
3035    (set (match_operand:SI 0 "s_register_operand" "=r,r")
3036         (ior:SI (match_dup 1) (match_dup 2)))]
3037   "TARGET_32BIT"
3038   "orrs%?\\t%0, %1, %2"
3039   [(set_attr "conds" "set")
3040    (set_attr "type" "logics_imm,logics_reg")]
3043 (define_insn "*iorsi3_compare0_scratch"
3044   [(set (reg:CC_NOOV CC_REGNUM)
3045         (compare:CC_NOOV (ior:SI (match_operand:SI 1 "s_register_operand" "%r,r")
3046                                  (match_operand:SI 2 "arm_rhs_operand" "I,r"))
3047                          (const_int 0)))
3048    (clobber (match_scratch:SI 0 "=r,r"))]
3049   "TARGET_32BIT"
3050   "orrs%?\\t%0, %1, %2"
3051   [(set_attr "conds" "set")
3052    (set_attr "type" "logics_imm,logics_reg")]
3055 (define_expand "xordi3"
3056   [(set (match_operand:DI         0 "s_register_operand" "")
3057         (xor:DI (match_operand:DI 1 "s_register_operand" "")
3058                 (match_operand:DI 2 "arm_xordi_operand" "")))]
3059   "TARGET_32BIT"
3060   ""
3063 (define_insn_and_split "*xordi3_insn"
3064   [(set (match_operand:DI         0 "s_register_operand" "=w,&r,&r,&r,&r,?w")
3065         (xor:DI (match_operand:DI 1 "s_register_operand" "%w ,0,r ,0 ,r ,w")
3066                 (match_operand:DI 2 "arm_xordi_operand"  "w ,r ,r ,Dg,Dg,w")))]
3067   "TARGET_32BIT && !TARGET_IWMMXT"
3069   switch (which_alternative)
3070     {
3071     case 1:
3072     case 2:
3073     case 3:
3074     case 4:  /* fall through */
3075       return "#";
3076     case 0: /* fall through */
3077     case 5: return "veor\t%P0, %P1, %P2";
3078     default: gcc_unreachable ();
3079     }
3081   "TARGET_32BIT && !TARGET_IWMMXT && reload_completed
3082    && !(IS_VFP_REGNUM (REGNO (operands[0])))"
3083   [(set (match_dup 3) (match_dup 4))
3084    (set (match_dup 5) (match_dup 6))]
3085   "
3086   {
3087     operands[3] = gen_lowpart (SImode, operands[0]);
3088     operands[5] = gen_highpart (SImode, operands[0]);
3090     operands[4] = simplify_gen_binary (XOR, SImode,
3091                                            gen_lowpart (SImode, operands[1]),
3092                                            gen_lowpart (SImode, operands[2]));
3093     operands[6] = simplify_gen_binary (XOR, SImode,
3094                                            gen_highpart (SImode, operands[1]),
3095                                            gen_highpart_mode (SImode, DImode, operands[2]));
3097   }"
3098   [(set_attr "length" "*,8,8,8,8,*")
3099    (set_attr "type" "neon_logic,multiple,multiple,multiple,multiple,neon_logic")
3100    (set_attr "arch" "neon_for_64bits,*,*,*,*,avoid_neon_for_64bits")]
3103 (define_insn "*xordi_zesidi_di"
3104   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
3105         (xor:DI (zero_extend:DI
3106                  (match_operand:SI 2 "s_register_operand" "r,r"))
3107                 (match_operand:DI 1 "s_register_operand" "0,?r")))]
3108   "TARGET_32BIT"
3109   "@
3110    eor%?\\t%Q0, %Q1, %2
3111    #"
3112   [(set_attr "length" "4,8")
3113    (set_attr "predicable" "yes")
3114    (set_attr "predicable_short_it" "no")
3115    (set_attr "type" "logic_reg")]
3118 (define_insn "*xordi_sesidi_di"
3119   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
3120         (xor:DI (sign_extend:DI
3121                  (match_operand:SI 2 "s_register_operand" "r,r"))
3122                 (match_operand:DI 1 "s_register_operand" "0,r")))]
3123   "TARGET_32BIT"
3124   "#"
3125   [(set_attr "length" "8")
3126    (set_attr "predicable" "yes")
3127    (set_attr "type" "multiple")]
3130 (define_expand "xorsi3"
3131   [(set (match_operand:SI         0 "s_register_operand" "")
3132         (xor:SI (match_operand:SI 1 "s_register_operand" "")
3133                 (match_operand:SI 2 "reg_or_int_operand" "")))]
3134   "TARGET_EITHER"
3135   "if (CONST_INT_P (operands[2]))
3136     {
3137       if (TARGET_32BIT)
3138         {
3139           if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[2]), XOR))
3140             operands[2] = force_reg (SImode, operands[2]);
3141           else
3142             {
3143               arm_split_constant (XOR, SImode, NULL_RTX,
3144                                   INTVAL (operands[2]), operands[0],
3145                                   operands[1],
3146                                   optimize && can_create_pseudo_p ());
3147               DONE;
3148             }
3149         }
3150       else /* TARGET_THUMB1 */
3151         {
3152           rtx tmp = force_reg (SImode, operands[2]);
3153           if (rtx_equal_p (operands[0], operands[1]))
3154             operands[2] = tmp;
3155           else
3156             {
3157               operands[2] = operands[1];
3158               operands[1] = tmp;
3159             }
3160         }
3161     }"
3164 (define_insn_and_split "*arm_xorsi3"
3165   [(set (match_operand:SI         0 "s_register_operand" "=r,l,r,r")
3166         (xor:SI (match_operand:SI 1 "s_register_operand" "%r,0,r,r")
3167                 (match_operand:SI 2 "reg_or_int_operand" "I,l,r,?n")))]
3168   "TARGET_32BIT"
3169   "@
3170    eor%?\\t%0, %1, %2
3171    eor%?\\t%0, %1, %2
3172    eor%?\\t%0, %1, %2
3173    #"
3174   "TARGET_32BIT
3175    && CONST_INT_P (operands[2])
3176    && !const_ok_for_arm (INTVAL (operands[2]))"
3177   [(clobber (const_int 0))]
3179   arm_split_constant (XOR, SImode, curr_insn,
3180                       INTVAL (operands[2]), operands[0], operands[1], 0);
3181   DONE;
3183   [(set_attr "length" "4,4,4,16")
3184    (set_attr "predicable" "yes")
3185    (set_attr "predicable_short_it" "no,yes,no,no")
3186    (set_attr "type"  "logic_imm,logic_reg,logic_reg,multiple")]
3189 (define_insn "*xorsi3_compare0"
3190   [(set (reg:CC_NOOV CC_REGNUM)
3191         (compare:CC_NOOV (xor:SI (match_operand:SI 1 "s_register_operand" "r,r")
3192                                  (match_operand:SI 2 "arm_rhs_operand" "I,r"))
3193                          (const_int 0)))
3194    (set (match_operand:SI 0 "s_register_operand" "=r,r")
3195         (xor:SI (match_dup 1) (match_dup 2)))]
3196   "TARGET_32BIT"
3197   "eors%?\\t%0, %1, %2"
3198   [(set_attr "conds" "set")
3199    (set_attr "type" "logics_imm,logics_reg")]
3202 (define_insn "*xorsi3_compare0_scratch"
3203   [(set (reg:CC_NOOV CC_REGNUM)
3204         (compare:CC_NOOV (xor:SI (match_operand:SI 0 "s_register_operand" "r,r")
3205                                  (match_operand:SI 1 "arm_rhs_operand" "I,r"))
3206                          (const_int 0)))]
3207   "TARGET_32BIT"
3208   "teq%?\\t%0, %1"
3209   [(set_attr "conds" "set")
3210    (set_attr "type" "logics_imm,logics_reg")]
3213 ; By splitting (IOR (AND (NOT A) (NOT B)) C) as D = AND (IOR A B) (NOT C), 
3214 ; (NOT D) we can sometimes merge the final NOT into one of the following
3215 ; insns.
3217 (define_split
3218   [(set (match_operand:SI 0 "s_register_operand" "")
3219         (ior:SI (and:SI (not:SI (match_operand:SI 1 "s_register_operand" ""))
3220                         (not:SI (match_operand:SI 2 "arm_rhs_operand" "")))
3221                 (match_operand:SI 3 "arm_rhs_operand" "")))
3222    (clobber (match_operand:SI 4 "s_register_operand" ""))]
3223   "TARGET_32BIT"
3224   [(set (match_dup 4) (and:SI (ior:SI (match_dup 1) (match_dup 2))
3225                               (not:SI (match_dup 3))))
3226    (set (match_dup 0) (not:SI (match_dup 4)))]
3227   ""
3230 (define_insn_and_split "*andsi_iorsi3_notsi"
3231   [(set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r")
3232         (and:SI (ior:SI (match_operand:SI 1 "s_register_operand" "%0,r,r")
3233                         (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI"))
3234                 (not:SI (match_operand:SI 3 "arm_rhs_operand" "rI,rI,rI"))))]
3235   "TARGET_32BIT"
3236   "#"   ; "orr%?\\t%0, %1, %2\;bic%?\\t%0, %0, %3"
3237   "&& reload_completed"
3238   [(set (match_dup 0) (ior:SI (match_dup 1) (match_dup 2)))
3239    (set (match_dup 0) (and:SI (match_dup 4) (match_dup 5)))]
3240   {
3241      /* If operands[3] is a constant make sure to fold the NOT into it
3242         to avoid creating a NOT of a CONST_INT.  */
3243     rtx not_rtx = simplify_gen_unary (NOT, SImode, operands[3], SImode);
3244     if (CONST_INT_P (not_rtx))
3245       {
3246         operands[4] = operands[0];
3247         operands[5] = not_rtx;
3248       }
3249     else
3250       {
3251         operands[5] = operands[0];
3252         operands[4] = not_rtx;
3253       }
3254   }
3255   [(set_attr "length" "8")
3256    (set_attr "ce_count" "2")
3257    (set_attr "predicable" "yes")
3258    (set_attr "predicable_short_it" "no")
3259    (set_attr "type" "multiple")]
3262 ; ??? Are these four splitters still beneficial when the Thumb-2 bitfield
3263 ; insns are available?
3264 (define_split
3265   [(set (match_operand:SI 0 "s_register_operand" "")
3266         (match_operator:SI 1 "logical_binary_operator"
3267          [(zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
3268                            (match_operand:SI 3 "const_int_operand" "")
3269                            (match_operand:SI 4 "const_int_operand" ""))
3270           (match_operator:SI 9 "logical_binary_operator"
3271            [(lshiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3272                          (match_operand:SI 6 "const_int_operand" ""))
3273             (match_operand:SI 7 "s_register_operand" "")])]))
3274    (clobber (match_operand:SI 8 "s_register_operand" ""))]
3275   "TARGET_32BIT
3276    && GET_CODE (operands[1]) == GET_CODE (operands[9])
3277    && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3278   [(set (match_dup 8)
3279         (match_op_dup 1
3280          [(ashift:SI (match_dup 2) (match_dup 4))
3281           (match_dup 5)]))
3282    (set (match_dup 0)
3283         (match_op_dup 1
3284          [(lshiftrt:SI (match_dup 8) (match_dup 6))
3285           (match_dup 7)]))]
3286   "
3287   operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3290 (define_split
3291   [(set (match_operand:SI 0 "s_register_operand" "")
3292         (match_operator:SI 1 "logical_binary_operator"
3293          [(match_operator:SI 9 "logical_binary_operator"
3294            [(lshiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3295                          (match_operand:SI 6 "const_int_operand" ""))
3296             (match_operand:SI 7 "s_register_operand" "")])
3297           (zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
3298                            (match_operand:SI 3 "const_int_operand" "")
3299                            (match_operand:SI 4 "const_int_operand" ""))]))
3300    (clobber (match_operand:SI 8 "s_register_operand" ""))]
3301   "TARGET_32BIT
3302    && GET_CODE (operands[1]) == GET_CODE (operands[9])
3303    && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3304   [(set (match_dup 8)
3305         (match_op_dup 1
3306          [(ashift:SI (match_dup 2) (match_dup 4))
3307           (match_dup 5)]))
3308    (set (match_dup 0)
3309         (match_op_dup 1
3310          [(lshiftrt:SI (match_dup 8) (match_dup 6))
3311           (match_dup 7)]))]
3312   "
3313   operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3316 (define_split
3317   [(set (match_operand:SI 0 "s_register_operand" "")
3318         (match_operator:SI 1 "logical_binary_operator"
3319          [(sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
3320                            (match_operand:SI 3 "const_int_operand" "")
3321                            (match_operand:SI 4 "const_int_operand" ""))
3322           (match_operator:SI 9 "logical_binary_operator"
3323            [(ashiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3324                          (match_operand:SI 6 "const_int_operand" ""))
3325             (match_operand:SI 7 "s_register_operand" "")])]))
3326    (clobber (match_operand:SI 8 "s_register_operand" ""))]
3327   "TARGET_32BIT
3328    && GET_CODE (operands[1]) == GET_CODE (operands[9])
3329    && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3330   [(set (match_dup 8)
3331         (match_op_dup 1
3332          [(ashift:SI (match_dup 2) (match_dup 4))
3333           (match_dup 5)]))
3334    (set (match_dup 0)
3335         (match_op_dup 1
3336          [(ashiftrt:SI (match_dup 8) (match_dup 6))
3337           (match_dup 7)]))]
3338   "
3339   operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3342 (define_split
3343   [(set (match_operand:SI 0 "s_register_operand" "")
3344         (match_operator:SI 1 "logical_binary_operator"
3345          [(match_operator:SI 9 "logical_binary_operator"
3346            [(ashiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3347                          (match_operand:SI 6 "const_int_operand" ""))
3348             (match_operand:SI 7 "s_register_operand" "")])
3349           (sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
3350                            (match_operand:SI 3 "const_int_operand" "")
3351                            (match_operand:SI 4 "const_int_operand" ""))]))
3352    (clobber (match_operand:SI 8 "s_register_operand" ""))]
3353   "TARGET_32BIT
3354    && GET_CODE (operands[1]) == GET_CODE (operands[9])
3355    && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3356   [(set (match_dup 8)
3357         (match_op_dup 1
3358          [(ashift:SI (match_dup 2) (match_dup 4))
3359           (match_dup 5)]))
3360    (set (match_dup 0)
3361         (match_op_dup 1
3362          [(ashiftrt:SI (match_dup 8) (match_dup 6))
3363           (match_dup 7)]))]
3364   "
3365   operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3369 ;; Minimum and maximum insns
3371 (define_expand "smaxsi3"
3372   [(parallel [
3373     (set (match_operand:SI 0 "s_register_operand" "")
3374          (smax:SI (match_operand:SI 1 "s_register_operand" "")
3375                   (match_operand:SI 2 "arm_rhs_operand" "")))
3376     (clobber (reg:CC CC_REGNUM))])]
3377   "TARGET_32BIT"
3378   "
3379   if (operands[2] == const0_rtx || operands[2] == constm1_rtx)
3380     {
3381       /* No need for a clobber of the condition code register here.  */
3382       emit_insn (gen_rtx_SET (operands[0],
3383                               gen_rtx_SMAX (SImode, operands[1],
3384                                             operands[2])));
3385       DONE;
3386     }
3389 (define_insn "*smax_0"
3390   [(set (match_operand:SI 0 "s_register_operand" "=r")
3391         (smax:SI (match_operand:SI 1 "s_register_operand" "r")
3392                  (const_int 0)))]
3393   "TARGET_32BIT"
3394   "bic%?\\t%0, %1, %1, asr #31"
3395   [(set_attr "predicable" "yes")
3396    (set_attr "predicable_short_it" "no")
3397    (set_attr "type" "logic_shift_reg")]
3400 (define_insn "*smax_m1"
3401   [(set (match_operand:SI 0 "s_register_operand" "=r")
3402         (smax:SI (match_operand:SI 1 "s_register_operand" "r")
3403                  (const_int -1)))]
3404   "TARGET_32BIT"
3405   "orr%?\\t%0, %1, %1, asr #31"
3406   [(set_attr "predicable" "yes")
3407    (set_attr "predicable_short_it" "no")
3408    (set_attr "type" "logic_shift_reg")]
3411 (define_insn_and_split "*arm_smax_insn"
3412   [(set (match_operand:SI          0 "s_register_operand" "=r,r")
3413         (smax:SI (match_operand:SI 1 "s_register_operand"  "%0,?r")
3414                  (match_operand:SI 2 "arm_rhs_operand"    "rI,rI")))
3415    (clobber (reg:CC CC_REGNUM))]
3416   "TARGET_ARM"
3417   "#"
3418    ; cmp\\t%1, %2\;movlt\\t%0, %2
3419    ; cmp\\t%1, %2\;movge\\t%0, %1\;movlt\\t%0, %2"
3420   "TARGET_ARM"
3421   [(set (reg:CC CC_REGNUM)
3422         (compare:CC (match_dup 1) (match_dup 2)))
3423    (set (match_dup 0)
3424         (if_then_else:SI (ge:SI (reg:CC CC_REGNUM) (const_int 0))
3425                          (match_dup 1)
3426                          (match_dup 2)))]
3427   ""
3428   [(set_attr "conds" "clob")
3429    (set_attr "length" "8,12")
3430    (set_attr "type" "multiple")]
3433 (define_expand "sminsi3"
3434   [(parallel [
3435     (set (match_operand:SI 0 "s_register_operand" "")
3436          (smin:SI (match_operand:SI 1 "s_register_operand" "")
3437                   (match_operand:SI 2 "arm_rhs_operand" "")))
3438     (clobber (reg:CC CC_REGNUM))])]
3439   "TARGET_32BIT"
3440   "
3441   if (operands[2] == const0_rtx)
3442     {
3443       /* No need for a clobber of the condition code register here.  */
3444       emit_insn (gen_rtx_SET (operands[0],
3445                               gen_rtx_SMIN (SImode, operands[1],
3446                                             operands[2])));
3447       DONE;
3448     }
3451 (define_insn "*smin_0"
3452   [(set (match_operand:SI 0 "s_register_operand" "=r")
3453         (smin:SI (match_operand:SI 1 "s_register_operand" "r")
3454                  (const_int 0)))]
3455   "TARGET_32BIT"
3456   "and%?\\t%0, %1, %1, asr #31"
3457   [(set_attr "predicable" "yes")
3458    (set_attr "predicable_short_it" "no")
3459    (set_attr "type" "logic_shift_reg")]
3462 (define_insn_and_split "*arm_smin_insn"
3463   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3464         (smin:SI (match_operand:SI 1 "s_register_operand" "%0,?r")
3465                  (match_operand:SI 2 "arm_rhs_operand" "rI,rI")))
3466    (clobber (reg:CC CC_REGNUM))]
3467   "TARGET_ARM"
3468   "#"
3469     ; cmp\\t%1, %2\;movge\\t%0, %2
3470     ; cmp\\t%1, %2\;movlt\\t%0, %1\;movge\\t%0, %2"
3471   "TARGET_ARM"
3472   [(set (reg:CC CC_REGNUM)
3473         (compare:CC (match_dup 1) (match_dup 2)))
3474    (set (match_dup 0)
3475         (if_then_else:SI (lt:SI (reg:CC CC_REGNUM) (const_int 0))
3476                          (match_dup 1)
3477                          (match_dup 2)))]
3478   ""
3479   [(set_attr "conds" "clob")
3480    (set_attr "length" "8,12")
3481    (set_attr "type" "multiple,multiple")]
3484 (define_expand "umaxsi3"
3485   [(parallel [
3486     (set (match_operand:SI 0 "s_register_operand" "")
3487          (umax:SI (match_operand:SI 1 "s_register_operand" "")
3488                   (match_operand:SI 2 "arm_rhs_operand" "")))
3489     (clobber (reg:CC CC_REGNUM))])]
3490   "TARGET_32BIT"
3491   ""
3494 (define_insn_and_split "*arm_umaxsi3"
3495   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
3496         (umax:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
3497                  (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
3498    (clobber (reg:CC CC_REGNUM))]
3499   "TARGET_ARM"
3500   "#"
3501     ; cmp\\t%1, %2\;movcc\\t%0, %2
3502     ; cmp\\t%1, %2\;movcs\\t%0, %1
3503     ; cmp\\t%1, %2\;movcs\\t%0, %1\;movcc\\t%0, %2"
3504   "TARGET_ARM"
3505   [(set (reg:CC CC_REGNUM)
3506         (compare:CC (match_dup 1) (match_dup 2)))
3507    (set (match_dup 0)
3508         (if_then_else:SI (geu:SI (reg:CC CC_REGNUM) (const_int 0))
3509                          (match_dup 1)
3510                          (match_dup 2)))]
3511   ""
3512   [(set_attr "conds" "clob")
3513    (set_attr "length" "8,8,12")
3514    (set_attr "type" "store1")]
3517 (define_expand "uminsi3"
3518   [(parallel [
3519     (set (match_operand:SI 0 "s_register_operand" "")
3520          (umin:SI (match_operand:SI 1 "s_register_operand" "")
3521                   (match_operand:SI 2 "arm_rhs_operand" "")))
3522     (clobber (reg:CC CC_REGNUM))])]
3523   "TARGET_32BIT"
3524   ""
3527 (define_insn_and_split "*arm_uminsi3"
3528   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
3529         (umin:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
3530                  (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
3531    (clobber (reg:CC CC_REGNUM))]
3532   "TARGET_ARM"
3533   "#"
3534    ; cmp\\t%1, %2\;movcs\\t%0, %2
3535    ; cmp\\t%1, %2\;movcc\\t%0, %1
3536    ; cmp\\t%1, %2\;movcc\\t%0, %1\;movcs\\t%0, %2"
3537   "TARGET_ARM"
3538   [(set (reg:CC CC_REGNUM)
3539         (compare:CC (match_dup 1) (match_dup 2)))
3540    (set (match_dup 0)
3541         (if_then_else:SI (ltu:SI (reg:CC CC_REGNUM) (const_int 0))
3542                          (match_dup 1)
3543                          (match_dup 2)))]
3544   ""
3545   [(set_attr "conds" "clob")
3546    (set_attr "length" "8,8,12")
3547    (set_attr "type" "store1")]
3550 (define_insn "*store_minmaxsi"
3551   [(set (match_operand:SI 0 "memory_operand" "=m")
3552         (match_operator:SI 3 "minmax_operator"
3553          [(match_operand:SI 1 "s_register_operand" "r")
3554           (match_operand:SI 2 "s_register_operand" "r")]))
3555    (clobber (reg:CC CC_REGNUM))]
3556   "TARGET_32BIT && optimize_function_for_size_p (cfun) && !arm_restrict_it"
3557   "*
3558   operands[3] = gen_rtx_fmt_ee (minmax_code (operands[3]), SImode,
3559                                 operands[1], operands[2]);
3560   output_asm_insn (\"cmp\\t%1, %2\", operands);
3561   if (TARGET_THUMB2)
3562     output_asm_insn (\"ite\t%d3\", operands);
3563   output_asm_insn (\"str%d3\\t%1, %0\", operands);
3564   output_asm_insn (\"str%D3\\t%2, %0\", operands);
3565   return \"\";
3566   "
3567   [(set_attr "conds" "clob")
3568    (set (attr "length")
3569         (if_then_else (eq_attr "is_thumb" "yes")
3570                       (const_int 14)
3571                       (const_int 12)))
3572    (set_attr "type" "store1")]
3575 ; Reject the frame pointer in operand[1], since reloading this after
3576 ; it has been eliminated can cause carnage.
3577 (define_insn "*minmax_arithsi"
3578   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3579         (match_operator:SI 4 "shiftable_operator"
3580          [(match_operator:SI 5 "minmax_operator"
3581            [(match_operand:SI 2 "s_register_operand" "r,r")
3582             (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
3583           (match_operand:SI 1 "s_register_operand" "0,?r")]))
3584    (clobber (reg:CC CC_REGNUM))]
3585   "TARGET_32BIT && !arm_eliminable_register (operands[1]) && !arm_restrict_it"
3586   "*
3587   {
3588     enum rtx_code code = GET_CODE (operands[4]);
3589     bool need_else;
3591     if (which_alternative != 0 || operands[3] != const0_rtx
3592         || (code != PLUS && code != IOR && code != XOR))
3593       need_else = true;
3594     else
3595       need_else = false;
3597     operands[5] = gen_rtx_fmt_ee (minmax_code (operands[5]), SImode,
3598                                   operands[2], operands[3]);
3599     output_asm_insn (\"cmp\\t%2, %3\", operands);
3600     if (TARGET_THUMB2)
3601       {
3602         if (need_else)
3603           output_asm_insn (\"ite\\t%d5\", operands);
3604         else
3605           output_asm_insn (\"it\\t%d5\", operands);
3606       }
3607     output_asm_insn (\"%i4%d5\\t%0, %1, %2\", operands);
3608     if (need_else)
3609       output_asm_insn (\"%i4%D5\\t%0, %1, %3\", operands);
3610     return \"\";
3611   }"
3612   [(set_attr "conds" "clob")
3613    (set (attr "length")
3614         (if_then_else (eq_attr "is_thumb" "yes")
3615                       (const_int 14)
3616                       (const_int 12)))
3617    (set_attr "type" "multiple")]
3620 ; Reject the frame pointer in operand[1], since reloading this after
3621 ; it has been eliminated can cause carnage.
3622 (define_insn_and_split "*minmax_arithsi_non_canon"
3623   [(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts")
3624         (minus:SI
3625          (match_operand:SI 1 "s_register_operand" "0,?Ts")
3626           (match_operator:SI 4 "minmax_operator"
3627            [(match_operand:SI 2 "s_register_operand" "Ts,Ts")
3628             (match_operand:SI 3 "arm_rhs_operand" "TsI,TsI")])))
3629    (clobber (reg:CC CC_REGNUM))]
3630   "TARGET_32BIT && !arm_eliminable_register (operands[1])
3631    && !(arm_restrict_it && CONST_INT_P (operands[3]))"
3632   "#"
3633   "TARGET_32BIT && !arm_eliminable_register (operands[1]) && reload_completed"
3634   [(set (reg:CC CC_REGNUM)
3635         (compare:CC (match_dup 2) (match_dup 3)))
3637    (cond_exec (match_op_dup 4 [(reg:CC CC_REGNUM) (const_int 0)])
3638               (set (match_dup 0)
3639                    (minus:SI (match_dup 1)
3640                              (match_dup 2))))
3641    (cond_exec (match_op_dup 5 [(reg:CC CC_REGNUM) (const_int 0)])
3642               (set (match_dup 0)
3643                    (match_dup 6)))]
3644   {
3645   machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
3646                                            operands[2], operands[3]);
3647   enum rtx_code rc = minmax_code (operands[4]);
3648   operands[4] = gen_rtx_fmt_ee (rc, VOIDmode,
3649                                 operands[2], operands[3]);
3651   if (mode == CCFPmode || mode == CCFPEmode)
3652     rc = reverse_condition_maybe_unordered (rc);
3653   else
3654     rc = reverse_condition (rc);
3655   operands[5] = gen_rtx_fmt_ee (rc, SImode, operands[2], operands[3]);
3656   if (CONST_INT_P (operands[3]))
3657     operands[6] = plus_constant (SImode, operands[1], -INTVAL (operands[3]));
3658   else
3659     operands[6] = gen_rtx_MINUS (SImode, operands[1], operands[3]);
3660   }
3661   [(set_attr "conds" "clob")
3662    (set (attr "length")
3663         (if_then_else (eq_attr "is_thumb" "yes")
3664                       (const_int 14)
3665                       (const_int 12)))
3666    (set_attr "type" "multiple")]
3669 (define_code_iterator SAT [smin smax])
3670 (define_code_iterator SATrev [smin smax])
3671 (define_code_attr SATlo [(smin "1") (smax "2")])
3672 (define_code_attr SAThi [(smin "2") (smax "1")])
3674 (define_insn "*satsi_<SAT:code>"
3675   [(set (match_operand:SI 0 "s_register_operand" "=r")
3676         (SAT:SI (SATrev:SI (match_operand:SI 3 "s_register_operand" "r")
3677                            (match_operand:SI 1 "const_int_operand" "i"))
3678                 (match_operand:SI 2 "const_int_operand" "i")))]
3679   "TARGET_32BIT && arm_arch6 && <SAT:CODE> != <SATrev:CODE>
3680    && arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>], NULL, NULL)"
3682   int mask;
3683   bool signed_sat;
3684   if (!arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>],
3685                                &mask, &signed_sat))
3686     gcc_unreachable ();
3688   operands[1] = GEN_INT (mask);
3689   if (signed_sat)
3690     return "ssat%?\t%0, %1, %3";
3691   else
3692     return "usat%?\t%0, %1, %3";
3694   [(set_attr "predicable" "yes")
3695    (set_attr "predicable_short_it" "no")
3696    (set_attr "type" "alus_imm")]
3699 (define_insn "*satsi_<SAT:code>_shift"
3700   [(set (match_operand:SI 0 "s_register_operand" "=r")
3701         (SAT:SI (SATrev:SI (match_operator:SI 3 "sat_shift_operator"
3702                              [(match_operand:SI 4 "s_register_operand" "r")
3703                               (match_operand:SI 5 "const_int_operand" "i")])
3704                            (match_operand:SI 1 "const_int_operand" "i"))
3705                 (match_operand:SI 2 "const_int_operand" "i")))]
3706   "TARGET_32BIT && arm_arch6 && <SAT:CODE> != <SATrev:CODE>
3707    && arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>], NULL, NULL)"
3709   int mask;
3710   bool signed_sat;
3711   if (!arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>],
3712                                &mask, &signed_sat))
3713     gcc_unreachable ();
3715   operands[1] = GEN_INT (mask);
3716   if (signed_sat)
3717     return "ssat%?\t%0, %1, %4%S3";
3718   else
3719     return "usat%?\t%0, %1, %4%S3";
3721   [(set_attr "predicable" "yes")
3722    (set_attr "predicable_short_it" "no")
3723    (set_attr "shift" "3")
3724    (set_attr "type" "logic_shift_reg")])
3726 ;; Shift and rotation insns
3728 (define_expand "ashldi3"
3729   [(set (match_operand:DI            0 "s_register_operand" "")
3730         (ashift:DI (match_operand:DI 1 "s_register_operand" "")
3731                    (match_operand:SI 2 "general_operand" "")))]
3732   "TARGET_32BIT"
3733   "
3734   if (TARGET_NEON)
3735     {
3736       /* Delay the decision whether to use NEON or core-regs until
3737          register allocation.  */
3738       emit_insn (gen_ashldi3_neon (operands[0], operands[1], operands[2]));
3739       DONE;
3740     }
3741   else
3742     {
3743       /* Only the NEON case can handle in-memory shift counts.  */
3744       if (!reg_or_int_operand (operands[2], SImode))
3745         operands[2] = force_reg (SImode, operands[2]);
3746     }
3748   if (!CONST_INT_P (operands[2]) && TARGET_REALLY_IWMMXT)
3749     ; /* No special preparation statements; expand pattern as above.  */
3750   else
3751     {
3752       rtx scratch1, scratch2;
3754       if (operands[2] == CONST1_RTX (SImode))
3755         {
3756           emit_insn (gen_arm_ashldi3_1bit (operands[0], operands[1]));
3757           DONE;
3758         }
3760       /* Ideally we should use iwmmxt here if we could know that operands[1]
3761          ends up already living in an iwmmxt register. Otherwise it's
3762          cheaper to have the alternate code being generated than moving
3763          values to iwmmxt regs and back.  */
3765       /* If we're optimizing for size, we prefer the libgcc calls.  */
3766       if (optimize_function_for_size_p (cfun))
3767         FAIL;
3769       /* Expand operation using core-registers.
3770          'FAIL' would achieve the same thing, but this is a bit smarter.  */
3771       scratch1 = gen_reg_rtx (SImode);
3772       scratch2 = gen_reg_rtx (SImode);
3773       arm_emit_coreregs_64bit_shift (ASHIFT, operands[0], operands[1],
3774                                      operands[2], scratch1, scratch2);
3775       DONE;
3776     }
3777   "
3780 (define_insn "arm_ashldi3_1bit"
3781   [(set (match_operand:DI            0 "s_register_operand" "=r,&r")
3782         (ashift:DI (match_operand:DI 1 "s_register_operand" "0,r")
3783                    (const_int 1)))
3784    (clobber (reg:CC CC_REGNUM))]
3785   "TARGET_32BIT"
3786   "movs\\t%Q0, %Q1, asl #1\;adc\\t%R0, %R1, %R1"
3787   [(set_attr "conds" "clob")
3788    (set_attr "length" "8")
3789    (set_attr "type" "multiple")]
3792 (define_expand "ashlsi3"
3793   [(set (match_operand:SI            0 "s_register_operand" "")
3794         (ashift:SI (match_operand:SI 1 "s_register_operand" "")
3795                    (match_operand:SI 2 "arm_rhs_operand" "")))]
3796   "TARGET_EITHER"
3797   "
3798   if (CONST_INT_P (operands[2])
3799       && (UINTVAL (operands[2])) > 31)
3800     {
3801       emit_insn (gen_movsi (operands[0], const0_rtx));
3802       DONE;
3803     }
3804   "
3807 (define_expand "ashrdi3"
3808   [(set (match_operand:DI              0 "s_register_operand" "")
3809         (ashiftrt:DI (match_operand:DI 1 "s_register_operand" "")
3810                      (match_operand:SI 2 "reg_or_int_operand" "")))]
3811   "TARGET_32BIT"
3812   "
3813   if (TARGET_NEON)
3814     {
3815       /* Delay the decision whether to use NEON or core-regs until
3816          register allocation.  */
3817       emit_insn (gen_ashrdi3_neon (operands[0], operands[1], operands[2]));
3818       DONE;
3819     }
3821   if (!CONST_INT_P (operands[2]) && TARGET_REALLY_IWMMXT)
3822     ; /* No special preparation statements; expand pattern as above.  */
3823   else
3824     {
3825       rtx scratch1, scratch2;
3827       if (operands[2] == CONST1_RTX (SImode))
3828         {
3829           emit_insn (gen_arm_ashrdi3_1bit (operands[0], operands[1]));
3830           DONE;
3831         }
3833       /* Ideally we should use iwmmxt here if we could know that operands[1]
3834          ends up already living in an iwmmxt register. Otherwise it's
3835          cheaper to have the alternate code being generated than moving
3836          values to iwmmxt regs and back.  */
3838       /* If we're optimizing for size, we prefer the libgcc calls.  */
3839       if (optimize_function_for_size_p (cfun))
3840         FAIL;
3842       /* Expand operation using core-registers.
3843          'FAIL' would achieve the same thing, but this is a bit smarter.  */
3844       scratch1 = gen_reg_rtx (SImode);
3845       scratch2 = gen_reg_rtx (SImode);
3846       arm_emit_coreregs_64bit_shift (ASHIFTRT, operands[0], operands[1],
3847                                      operands[2], scratch1, scratch2);
3848       DONE;
3849     }
3850   "
3853 (define_insn "arm_ashrdi3_1bit"
3854   [(set (match_operand:DI              0 "s_register_operand" "=r,&r")
3855         (ashiftrt:DI (match_operand:DI 1 "s_register_operand" "0,r")
3856                      (const_int 1)))
3857    (clobber (reg:CC CC_REGNUM))]
3858   "TARGET_32BIT"
3859   "movs\\t%R0, %R1, asr #1\;mov\\t%Q0, %Q1, rrx"
3860   [(set_attr "conds" "clob")
3861    (set_attr "length" "8")
3862    (set_attr "type" "multiple")]
3865 (define_expand "ashrsi3"
3866   [(set (match_operand:SI              0 "s_register_operand" "")
3867         (ashiftrt:SI (match_operand:SI 1 "s_register_operand" "")
3868                      (match_operand:SI 2 "arm_rhs_operand" "")))]
3869   "TARGET_EITHER"
3870   "
3871   if (CONST_INT_P (operands[2])
3872       && UINTVAL (operands[2]) > 31)
3873     operands[2] = GEN_INT (31);
3874   "
3877 (define_expand "lshrdi3"
3878   [(set (match_operand:DI              0 "s_register_operand" "")
3879         (lshiftrt:DI (match_operand:DI 1 "s_register_operand" "")
3880                      (match_operand:SI 2 "reg_or_int_operand" "")))]
3881   "TARGET_32BIT"
3882   "
3883   if (TARGET_NEON)
3884     {
3885       /* Delay the decision whether to use NEON or core-regs until
3886          register allocation.  */
3887       emit_insn (gen_lshrdi3_neon (operands[0], operands[1], operands[2]));
3888       DONE;
3889     }
3891   if (!CONST_INT_P (operands[2]) && TARGET_REALLY_IWMMXT)
3892     ; /* No special preparation statements; expand pattern as above.  */
3893   else
3894     {
3895       rtx scratch1, scratch2;
3897       if (operands[2] == CONST1_RTX (SImode))
3898         {
3899           emit_insn (gen_arm_lshrdi3_1bit (operands[0], operands[1]));
3900           DONE;
3901         }
3903       /* Ideally we should use iwmmxt here if we could know that operands[1]
3904          ends up already living in an iwmmxt register. Otherwise it's
3905          cheaper to have the alternate code being generated than moving
3906          values to iwmmxt regs and back.  */
3908       /* If we're optimizing for size, we prefer the libgcc calls.  */
3909       if (optimize_function_for_size_p (cfun))
3910         FAIL;
3912       /* Expand operation using core-registers.
3913          'FAIL' would achieve the same thing, but this is a bit smarter.  */
3914       scratch1 = gen_reg_rtx (SImode);
3915       scratch2 = gen_reg_rtx (SImode);
3916       arm_emit_coreregs_64bit_shift (LSHIFTRT, operands[0], operands[1],
3917                                      operands[2], scratch1, scratch2);
3918       DONE;
3919     }
3920   "
3923 (define_insn "arm_lshrdi3_1bit"
3924   [(set (match_operand:DI              0 "s_register_operand" "=r,&r")
3925         (lshiftrt:DI (match_operand:DI 1 "s_register_operand" "0,r")
3926                      (const_int 1)))
3927    (clobber (reg:CC CC_REGNUM))]
3928   "TARGET_32BIT"
3929   "movs\\t%R0, %R1, lsr #1\;mov\\t%Q0, %Q1, rrx"
3930   [(set_attr "conds" "clob")
3931    (set_attr "length" "8")
3932    (set_attr "type" "multiple")]
3935 (define_expand "lshrsi3"
3936   [(set (match_operand:SI              0 "s_register_operand" "")
3937         (lshiftrt:SI (match_operand:SI 1 "s_register_operand" "")
3938                      (match_operand:SI 2 "arm_rhs_operand" "")))]
3939   "TARGET_EITHER"
3940   "
3941   if (CONST_INT_P (operands[2])
3942       && (UINTVAL (operands[2])) > 31)
3943     {
3944       emit_insn (gen_movsi (operands[0], const0_rtx));
3945       DONE;
3946     }
3947   "
3950 (define_expand "rotlsi3"
3951   [(set (match_operand:SI              0 "s_register_operand" "")
3952         (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
3953                      (match_operand:SI 2 "reg_or_int_operand" "")))]
3954   "TARGET_32BIT"
3955   "
3956   if (CONST_INT_P (operands[2]))
3957     operands[2] = GEN_INT ((32 - INTVAL (operands[2])) % 32);
3958   else
3959     {
3960       rtx reg = gen_reg_rtx (SImode);
3961       emit_insn (gen_subsi3 (reg, GEN_INT (32), operands[2]));
3962       operands[2] = reg;
3963     }
3964   "
3967 (define_expand "rotrsi3"
3968   [(set (match_operand:SI              0 "s_register_operand" "")
3969         (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
3970                      (match_operand:SI 2 "arm_rhs_operand" "")))]
3971   "TARGET_EITHER"
3972   "
3973   if (TARGET_32BIT)
3974     {
3975       if (CONST_INT_P (operands[2])
3976           && UINTVAL (operands[2]) > 31)
3977         operands[2] = GEN_INT (INTVAL (operands[2]) % 32);
3978     }
3979   else /* TARGET_THUMB1 */
3980     {
3981       if (CONST_INT_P (operands [2]))
3982         operands [2] = force_reg (SImode, operands[2]);
3983     }
3984   "
3987 (define_insn "*arm_shiftsi3"
3988   [(set (match_operand:SI   0 "s_register_operand" "=l,l,r,r")
3989         (match_operator:SI  3 "shift_operator"
3990          [(match_operand:SI 1 "s_register_operand"  "0,l,r,r")
3991           (match_operand:SI 2 "reg_or_int_operand" "l,M,M,r")]))]
3992   "TARGET_32BIT"
3993   "* return arm_output_shift(operands, 0);"
3994   [(set_attr "predicable" "yes")
3995    (set_attr "arch" "t2,t2,*,*")
3996    (set_attr "predicable_short_it" "yes,yes,no,no")
3997    (set_attr "length" "4")
3998    (set_attr "shift" "1")
3999    (set_attr "type" "alu_shift_reg,alu_shift_imm,alu_shift_imm,alu_shift_reg")]
4002 (define_insn "*shiftsi3_compare0"
4003   [(set (reg:CC_NOOV CC_REGNUM)
4004         (compare:CC_NOOV (match_operator:SI 3 "shift_operator"
4005                           [(match_operand:SI 1 "s_register_operand" "r,r")
4006                            (match_operand:SI 2 "arm_rhs_operand" "M,r")])
4007                          (const_int 0)))
4008    (set (match_operand:SI 0 "s_register_operand" "=r,r")
4009         (match_op_dup 3 [(match_dup 1) (match_dup 2)]))]
4010   "TARGET_32BIT"
4011   "* return arm_output_shift(operands, 1);"
4012   [(set_attr "conds" "set")
4013    (set_attr "shift" "1")
4014    (set_attr "type" "alus_shift_imm,alus_shift_reg")]
4017 (define_insn "*shiftsi3_compare0_scratch"
4018   [(set (reg:CC_NOOV CC_REGNUM)
4019         (compare:CC_NOOV (match_operator:SI 3 "shift_operator"
4020                           [(match_operand:SI 1 "s_register_operand" "r,r")
4021                            (match_operand:SI 2 "arm_rhs_operand" "M,r")])
4022                          (const_int 0)))
4023    (clobber (match_scratch:SI 0 "=r,r"))]
4024   "TARGET_32BIT"
4025   "* return arm_output_shift(operands, 1);"
4026   [(set_attr "conds" "set")
4027    (set_attr "shift" "1")
4028    (set_attr "type" "shift_imm,shift_reg")]
4031 (define_insn "*not_shiftsi"
4032   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4033         (not:SI (match_operator:SI 3 "shift_operator"
4034                  [(match_operand:SI 1 "s_register_operand" "r,r")
4035                   (match_operand:SI 2 "shift_amount_operand" "M,rM")])))]
4036   "TARGET_32BIT"
4037   "mvn%?\\t%0, %1%S3"
4038   [(set_attr "predicable" "yes")
4039    (set_attr "predicable_short_it" "no")
4040    (set_attr "shift" "1")
4041    (set_attr "arch" "32,a")
4042    (set_attr "type" "mvn_shift,mvn_shift_reg")])
4044 (define_insn "*not_shiftsi_compare0"
4045   [(set (reg:CC_NOOV CC_REGNUM)
4046         (compare:CC_NOOV
4047          (not:SI (match_operator:SI 3 "shift_operator"
4048                   [(match_operand:SI 1 "s_register_operand" "r,r")
4049                    (match_operand:SI 2 "shift_amount_operand" "M,rM")]))
4050          (const_int 0)))
4051    (set (match_operand:SI 0 "s_register_operand" "=r,r")
4052         (not:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])))]
4053   "TARGET_32BIT"
4054   "mvns%?\\t%0, %1%S3"
4055   [(set_attr "conds" "set")
4056    (set_attr "shift" "1")
4057    (set_attr "arch" "32,a")
4058    (set_attr "type" "mvn_shift,mvn_shift_reg")])
4060 (define_insn "*not_shiftsi_compare0_scratch"
4061   [(set (reg:CC_NOOV CC_REGNUM)
4062         (compare:CC_NOOV
4063          (not:SI (match_operator:SI 3 "shift_operator"
4064                   [(match_operand:SI 1 "s_register_operand" "r,r")
4065                    (match_operand:SI 2 "shift_amount_operand" "M,rM")]))
4066          (const_int 0)))
4067    (clobber (match_scratch:SI 0 "=r,r"))]
4068   "TARGET_32BIT"
4069   "mvns%?\\t%0, %1%S3"
4070   [(set_attr "conds" "set")
4071    (set_attr "shift" "1")
4072    (set_attr "arch" "32,a")
4073    (set_attr "type" "mvn_shift,mvn_shift_reg")])
4075 ;; We don't really have extzv, but defining this using shifts helps
4076 ;; to reduce register pressure later on.
4078 (define_expand "extzv"
4079   [(set (match_operand 0 "s_register_operand" "")
4080         (zero_extract (match_operand 1 "nonimmediate_operand" "")
4081                       (match_operand 2 "const_int_operand" "")
4082                       (match_operand 3 "const_int_operand" "")))]
4083   "TARGET_THUMB1 || arm_arch_thumb2"
4084   "
4085   {
4086     HOST_WIDE_INT lshift = 32 - INTVAL (operands[2]) - INTVAL (operands[3]);
4087     HOST_WIDE_INT rshift = 32 - INTVAL (operands[2]);
4088     
4089     if (arm_arch_thumb2)
4090       {
4091         HOST_WIDE_INT width = INTVAL (operands[2]);
4092         HOST_WIDE_INT bitpos = INTVAL (operands[3]);
4094         if (unaligned_access && MEM_P (operands[1])
4095             && (width == 16 || width == 32) && (bitpos % BITS_PER_UNIT) == 0)
4096           {
4097             rtx base_addr;
4099             if (BYTES_BIG_ENDIAN)
4100               bitpos = GET_MODE_BITSIZE (GET_MODE (operands[0])) - width
4101                        - bitpos;
4103             if (width == 32)
4104               {
4105                 base_addr = adjust_address (operands[1], SImode,
4106                                             bitpos / BITS_PER_UNIT);
4107                 emit_insn (gen_unaligned_loadsi (operands[0], base_addr));
4108               }
4109             else
4110               {
4111                 rtx dest = operands[0];
4112                 rtx tmp = gen_reg_rtx (SImode);
4114                 /* We may get a paradoxical subreg here.  Strip it off.  */
4115                 if (GET_CODE (dest) == SUBREG
4116                     && GET_MODE (dest) == SImode
4117                     && GET_MODE (SUBREG_REG (dest)) == HImode)
4118                   dest = SUBREG_REG (dest);
4120                 if (GET_MODE_BITSIZE (GET_MODE (dest)) != width)
4121                   FAIL;
4123                 base_addr = adjust_address (operands[1], HImode,
4124                                             bitpos / BITS_PER_UNIT);
4125                 emit_insn (gen_unaligned_loadhiu (tmp, base_addr));
4126                 emit_move_insn (gen_lowpart (SImode, dest), tmp);
4127               }
4128             DONE;
4129           }
4130         else if (s_register_operand (operands[1], GET_MODE (operands[1])))
4131           {
4132             emit_insn (gen_extzv_t2 (operands[0], operands[1], operands[2],
4133                                      operands[3]));
4134             DONE;
4135           }
4136         else
4137           FAIL;
4138       }
4139     
4140     if (!s_register_operand (operands[1], GET_MODE (operands[1])))
4141       FAIL;
4143     operands[3] = GEN_INT (rshift);
4144     
4145     if (lshift == 0)
4146       {
4147         emit_insn (gen_lshrsi3 (operands[0], operands[1], operands[3]));
4148         DONE;
4149       }
4150       
4151     emit_insn (gen_extzv_t1 (operands[0], operands[1], GEN_INT (lshift),
4152                              operands[3], gen_reg_rtx (SImode)));
4153     DONE;
4154   }"
4157 ;; Helper for extzv, for the Thumb-1 register-shifts case.
4159 (define_expand "extzv_t1"
4160   [(set (match_operand:SI 4 "s_register_operand" "")
4161         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
4162                    (match_operand:SI 2 "const_int_operand" "")))
4163    (set (match_operand:SI 0 "s_register_operand" "")
4164         (lshiftrt:SI (match_dup 4)
4165                      (match_operand:SI 3 "const_int_operand" "")))]
4166   "TARGET_THUMB1"
4167   "")
4169 (define_expand "extv"
4170   [(set (match_operand 0 "s_register_operand" "")
4171         (sign_extract (match_operand 1 "nonimmediate_operand" "")
4172                       (match_operand 2 "const_int_operand" "")
4173                       (match_operand 3 "const_int_operand" "")))]
4174   "arm_arch_thumb2"
4176   HOST_WIDE_INT width = INTVAL (operands[2]);
4177   HOST_WIDE_INT bitpos = INTVAL (operands[3]);
4179   if (unaligned_access && MEM_P (operands[1]) && (width == 16 || width == 32)
4180       && (bitpos % BITS_PER_UNIT)  == 0)
4181     {
4182       rtx base_addr;
4183       
4184       if (BYTES_BIG_ENDIAN)
4185         bitpos = GET_MODE_BITSIZE (GET_MODE (operands[0])) - width - bitpos;
4186       
4187       if (width == 32)
4188         {
4189           base_addr = adjust_address (operands[1], SImode,
4190                                       bitpos / BITS_PER_UNIT);
4191           emit_insn (gen_unaligned_loadsi (operands[0], base_addr));
4192         }
4193       else
4194         {
4195           rtx dest = operands[0];
4196           rtx tmp = gen_reg_rtx (SImode);
4197           
4198           /* We may get a paradoxical subreg here.  Strip it off.  */
4199           if (GET_CODE (dest) == SUBREG
4200               && GET_MODE (dest) == SImode
4201               && GET_MODE (SUBREG_REG (dest)) == HImode)
4202             dest = SUBREG_REG (dest);
4203           
4204           if (GET_MODE_BITSIZE (GET_MODE (dest)) != width)
4205             FAIL;
4206           
4207           base_addr = adjust_address (operands[1], HImode,
4208                                       bitpos / BITS_PER_UNIT);
4209           emit_insn (gen_unaligned_loadhis (tmp, base_addr));
4210           emit_move_insn (gen_lowpart (SImode, dest), tmp);
4211         }
4213       DONE;
4214     }
4215   else if (!s_register_operand (operands[1], GET_MODE (operands[1])))
4216     FAIL;
4217   else if (GET_MODE (operands[0]) == SImode
4218            && GET_MODE (operands[1]) == SImode)
4219     {
4220       emit_insn (gen_extv_regsi (operands[0], operands[1], operands[2],
4221                                  operands[3]));
4222       DONE;
4223     }
4225   FAIL;
4228 ; Helper to expand register forms of extv with the proper modes.
4230 (define_expand "extv_regsi"
4231   [(set (match_operand:SI 0 "s_register_operand" "")
4232         (sign_extract:SI (match_operand:SI 1 "s_register_operand" "")
4233                          (match_operand 2 "const_int_operand" "")
4234                          (match_operand 3 "const_int_operand" "")))]
4235   ""
4239 ; ARMv6+ unaligned load/store instructions (used for packed structure accesses).
4241 (define_insn "unaligned_loadsi"
4242   [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4243         (unspec:SI [(match_operand:SI 1 "memory_operand" "Uw,m")]
4244                    UNSPEC_UNALIGNED_LOAD))]
4245   "unaligned_access"
4246   "ldr%?\t%0, %1\t@ unaligned"
4247   [(set_attr "arch" "t2,any")
4248    (set_attr "length" "2,4")
4249    (set_attr "predicable" "yes")
4250    (set_attr "predicable_short_it" "yes,no")
4251    (set_attr "type" "load1")])
4253 (define_insn "unaligned_loadhis"
4254   [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4255         (sign_extend:SI
4256           (unspec:HI [(match_operand:HI 1 "memory_operand" "Uw,Uh")]
4257                      UNSPEC_UNALIGNED_LOAD)))]
4258   "unaligned_access"
4259   "ldrsh%?\t%0, %1\t@ unaligned"
4260   [(set_attr "arch" "t2,any")
4261    (set_attr "length" "2,4")
4262    (set_attr "predicable" "yes")
4263    (set_attr "predicable_short_it" "yes,no")
4264    (set_attr "type" "load_byte")])
4266 (define_insn "unaligned_loadhiu"
4267   [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4268         (zero_extend:SI
4269           (unspec:HI [(match_operand:HI 1 "memory_operand" "Uw,m")]
4270                      UNSPEC_UNALIGNED_LOAD)))]
4271   "unaligned_access"
4272   "ldrh%?\t%0, %1\t@ unaligned"
4273   [(set_attr "arch" "t2,any")
4274    (set_attr "length" "2,4")
4275    (set_attr "predicable" "yes")
4276    (set_attr "predicable_short_it" "yes,no")
4277    (set_attr "type" "load_byte")])
4279 (define_insn "unaligned_storesi"
4280   [(set (match_operand:SI 0 "memory_operand" "=Uw,m")
4281         (unspec:SI [(match_operand:SI 1 "s_register_operand" "l,r")]
4282                    UNSPEC_UNALIGNED_STORE))]
4283   "unaligned_access"
4284   "str%?\t%1, %0\t@ unaligned"
4285   [(set_attr "arch" "t2,any")
4286    (set_attr "length" "2,4")
4287    (set_attr "predicable" "yes")
4288    (set_attr "predicable_short_it" "yes,no")
4289    (set_attr "type" "store1")])
4291 (define_insn "unaligned_storehi"
4292   [(set (match_operand:HI 0 "memory_operand" "=Uw,m")
4293         (unspec:HI [(match_operand:HI 1 "s_register_operand" "l,r")]
4294                    UNSPEC_UNALIGNED_STORE))]
4295   "unaligned_access"
4296   "strh%?\t%1, %0\t@ unaligned"
4297   [(set_attr "arch" "t2,any")
4298    (set_attr "length" "2,4")
4299    (set_attr "predicable" "yes")
4300    (set_attr "predicable_short_it" "yes,no")
4301    (set_attr "type" "store1")])
4304 (define_insn "*extv_reg"
4305   [(set (match_operand:SI 0 "s_register_operand" "=r")
4306         (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
4307                          (match_operand:SI 2 "const_int_M_operand" "M")
4308                          (match_operand:SI 3 "const_int_M_operand" "M")))]
4309   "arm_arch_thumb2"
4310   "sbfx%?\t%0, %1, %3, %2"
4311   [(set_attr "length" "4")
4312    (set_attr "predicable" "yes")
4313    (set_attr "predicable_short_it" "no")
4314    (set_attr "type" "bfm")]
4317 (define_insn "extzv_t2"
4318   [(set (match_operand:SI 0 "s_register_operand" "=r")
4319         (zero_extract:SI (match_operand:SI 1 "s_register_operand" "r")
4320                          (match_operand:SI 2 "const_int_M_operand" "M")
4321                          (match_operand:SI 3 "const_int_M_operand" "M")))]
4322   "arm_arch_thumb2"
4323   "ubfx%?\t%0, %1, %3, %2"
4324   [(set_attr "length" "4")
4325    (set_attr "predicable" "yes")
4326    (set_attr "predicable_short_it" "no")
4327    (set_attr "type" "bfm")]
4331 ;; Division instructions
4332 (define_insn "divsi3"
4333   [(set (match_operand:SI         0 "s_register_operand" "=r")
4334         (div:SI (match_operand:SI 1 "s_register_operand"  "r")
4335                 (match_operand:SI 2 "s_register_operand"  "r")))]
4336   "TARGET_IDIV"
4337   "sdiv%?\t%0, %1, %2"
4338   [(set_attr "predicable" "yes")
4339    (set_attr "predicable_short_it" "no")
4340    (set_attr "type" "sdiv")]
4343 (define_insn "udivsi3"
4344   [(set (match_operand:SI          0 "s_register_operand" "=r")
4345         (udiv:SI (match_operand:SI 1 "s_register_operand"  "r")
4346                  (match_operand:SI 2 "s_register_operand"  "r")))]
4347   "TARGET_IDIV"
4348   "udiv%?\t%0, %1, %2"
4349   [(set_attr "predicable" "yes")
4350    (set_attr "predicable_short_it" "no")
4351    (set_attr "type" "udiv")]
4355 ;; Unary arithmetic insns
4357 (define_expand "negdi2"
4358  [(parallel
4359    [(set (match_operand:DI 0 "s_register_operand" "")
4360          (neg:DI (match_operand:DI 1 "s_register_operand" "")))
4361     (clobber (reg:CC CC_REGNUM))])]
4362   "TARGET_EITHER"
4363   {
4364     if (TARGET_NEON)
4365       {
4366         emit_insn (gen_negdi2_neon (operands[0], operands[1]));
4367         DONE;
4368       }
4369   }
4372 ;; The constraints here are to prevent a *partial* overlap (where %Q0 == %R1).
4373 ;; The first alternative allows the common case of a *full* overlap.
4374 (define_insn_and_split "*arm_negdi2"
4375   [(set (match_operand:DI         0 "s_register_operand" "=r,&r")
4376         (neg:DI (match_operand:DI 1 "s_register_operand"  "0,r")))
4377    (clobber (reg:CC CC_REGNUM))]
4378   "TARGET_ARM"
4379   "#"   ; "rsbs\\t%Q0, %Q1, #0\;rsc\\t%R0, %R1, #0"
4380   "&& reload_completed"
4381   [(parallel [(set (reg:CC CC_REGNUM)
4382                    (compare:CC (const_int 0) (match_dup 1)))
4383               (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1)))])
4384    (set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3))
4385                                 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
4386   {
4387     operands[2] = gen_highpart (SImode, operands[0]);
4388     operands[0] = gen_lowpart (SImode, operands[0]);
4389     operands[3] = gen_highpart (SImode, operands[1]);
4390     operands[1] = gen_lowpart (SImode, operands[1]);
4391   }
4392   [(set_attr "conds" "clob")
4393    (set_attr "length" "8")
4394    (set_attr "type" "multiple")]
4397 (define_expand "negsi2"
4398   [(set (match_operand:SI         0 "s_register_operand" "")
4399         (neg:SI (match_operand:SI 1 "s_register_operand" "")))]
4400   "TARGET_EITHER"
4401   ""
4404 (define_insn "*arm_negsi2"
4405   [(set (match_operand:SI         0 "s_register_operand" "=l,r")
4406         (neg:SI (match_operand:SI 1 "s_register_operand" "l,r")))]
4407   "TARGET_32BIT"
4408   "rsb%?\\t%0, %1, #0"
4409   [(set_attr "predicable" "yes")
4410    (set_attr "predicable_short_it" "yes,no")
4411    (set_attr "arch" "t2,*")
4412    (set_attr "length" "4")
4413    (set_attr "type" "alu_sreg")]
4416 (define_expand "negsf2"
4417   [(set (match_operand:SF         0 "s_register_operand" "")
4418         (neg:SF (match_operand:SF 1 "s_register_operand" "")))]
4419   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
4420   ""
4423 (define_expand "negdf2"
4424   [(set (match_operand:DF         0 "s_register_operand" "")
4425         (neg:DF (match_operand:DF 1 "s_register_operand" "")))]
4426   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
4427   "")
4429 (define_insn_and_split "*zextendsidi_negsi"
4430   [(set (match_operand:DI 0 "s_register_operand" "=r")
4431         (zero_extend:DI (neg:SI (match_operand:SI 1 "s_register_operand" "r"))))]
4432    "TARGET_32BIT"
4433    "#"
4434    ""
4435    [(set (match_dup 2)
4436          (neg:SI (match_dup 1)))
4437     (set (match_dup 3)
4438          (const_int 0))]
4439    {
4440       operands[2] = gen_lowpart (SImode, operands[0]);
4441       operands[3] = gen_highpart (SImode, operands[0]);
4442    }
4443  [(set_attr "length" "8")
4444   (set_attr "type" "multiple")]
4447 ;; Negate an extended 32-bit value.
4448 (define_insn_and_split "*negdi_extendsidi"
4449   [(set (match_operand:DI 0 "s_register_operand" "=l,r")
4450         (neg:DI (sign_extend:DI
4451                  (match_operand:SI 1 "s_register_operand" "l,r"))))
4452    (clobber (reg:CC CC_REGNUM))]
4453   "TARGET_32BIT"
4454   "#"
4455   "&& reload_completed"
4456   [(const_int 0)]
4457   {
4458     rtx low = gen_lowpart (SImode, operands[0]);
4459     rtx high = gen_highpart (SImode, operands[0]);
4461     if (reg_overlap_mentioned_p (low, operands[1]))
4462       {
4463         /* Input overlaps the low word of the output.  Use:
4464                 asr     Rhi, Rin, #31
4465                 rsbs    Rlo, Rin, #0
4466                 rsc     Rhi, Rhi, #0 (thumb2: sbc Rhi, Rhi, Rhi, lsl #1).  */
4467         rtx cc_reg = gen_rtx_REG (CC_Cmode, CC_REGNUM);
4469         emit_insn (gen_rtx_SET (high,
4470                                 gen_rtx_ASHIFTRT (SImode, operands[1],
4471                                                   GEN_INT (31))));
4473         emit_insn (gen_subsi3_compare (low, const0_rtx, operands[1]));
4474         if (TARGET_ARM)
4475           emit_insn (gen_rtx_SET (high,
4476                                   gen_rtx_MINUS (SImode,
4477                                                  gen_rtx_MINUS (SImode,
4478                                                                 const0_rtx,
4479                                                                 high),
4480                                                  gen_rtx_LTU (SImode,
4481                                                               cc_reg,
4482                                                               const0_rtx))));
4483         else
4484           {
4485             rtx two_x = gen_rtx_ASHIFT (SImode, high, GEN_INT (1));
4486             emit_insn (gen_rtx_SET (high,
4487                                     gen_rtx_MINUS (SImode,
4488                                                    gen_rtx_MINUS (SImode,
4489                                                                   high,
4490                                                                   two_x),
4491                                                    gen_rtx_LTU (SImode,
4492                                                                 cc_reg,
4493                                                                 const0_rtx))));
4494           }
4495       }
4496     else
4497       {
4498         /* No overlap, or overlap on high word.  Use:
4499                 rsb     Rlo, Rin, #0
4500                 bic     Rhi, Rlo, Rin
4501                 asr     Rhi, Rhi, #31
4502            Flags not needed for this sequence.  */
4503         emit_insn (gen_rtx_SET (low, gen_rtx_NEG (SImode, operands[1])));
4504         emit_insn (gen_rtx_SET (high,
4505                                 gen_rtx_AND (SImode,
4506                                              gen_rtx_NOT (SImode, operands[1]),
4507                                              low)));
4508         emit_insn (gen_rtx_SET (high,
4509                                 gen_rtx_ASHIFTRT (SImode, high,
4510                                                   GEN_INT (31))));
4511       }
4512     DONE;
4513   }
4514   [(set_attr "length" "12")
4515    (set_attr "arch" "t2,*")
4516    (set_attr "type" "multiple")]
4519 (define_insn_and_split "*negdi_zero_extendsidi"
4520   [(set (match_operand:DI 0 "s_register_operand" "=r,&r")
4521         (neg:DI (zero_extend:DI (match_operand:SI 1 "s_register_operand" "0,r"))))
4522    (clobber (reg:CC CC_REGNUM))]
4523   "TARGET_32BIT"
4524   "#" ; "rsbs\\t%Q0, %1, #0\;sbc\\t%R0,%R0,%R0"
4525       ;; Don't care what register is input to sbc,
4526       ;; since we just need to propagate the carry.
4527   "&& reload_completed"
4528   [(parallel [(set (reg:CC CC_REGNUM)
4529                    (compare:CC (const_int 0) (match_dup 1)))
4530               (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1)))])
4531    (set (match_dup 2) (minus:SI (minus:SI (match_dup 2) (match_dup 2))
4532                                 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
4533   {
4534     operands[2] = gen_highpart (SImode, operands[0]);
4535     operands[0] = gen_lowpart (SImode, operands[0]);
4536   }
4537   [(set_attr "conds" "clob")
4538    (set_attr "length" "8")
4539    (set_attr "type" "multiple")]   ;; length in thumb is 4
4542 ;; abssi2 doesn't really clobber the condition codes if a different register
4543 ;; is being set.  To keep things simple, assume during rtl manipulations that
4544 ;; it does, but tell the final scan operator the truth.  Similarly for
4545 ;; (neg (abs...))
4547 (define_expand "abssi2"
4548   [(parallel
4549     [(set (match_operand:SI         0 "s_register_operand" "")
4550           (abs:SI (match_operand:SI 1 "s_register_operand" "")))
4551      (clobber (match_dup 2))])]
4552   "TARGET_EITHER"
4553   "
4554   if (TARGET_THUMB1)
4555     operands[2] = gen_rtx_SCRATCH (SImode);
4556   else
4557     operands[2] = gen_rtx_REG (CCmode, CC_REGNUM);
4560 (define_insn_and_split "*arm_abssi2"
4561   [(set (match_operand:SI 0 "s_register_operand" "=r,&r")
4562         (abs:SI (match_operand:SI 1 "s_register_operand" "0,r")))
4563    (clobber (reg:CC CC_REGNUM))]
4564   "TARGET_ARM"
4565   "#"
4566   "&& reload_completed"
4567   [(const_int 0)]
4568   {
4569    /* if (which_alternative == 0) */
4570    if (REGNO(operands[0]) == REGNO(operands[1]))
4571      {
4572       /* Emit the pattern:
4573          cmp\\t%0, #0\;rsblt\\t%0, %0, #0
4574          [(set (reg:CC CC_REGNUM)
4575                (compare:CC (match_dup 0) (const_int 0)))
4576           (cond_exec (lt:CC (reg:CC CC_REGNUM) (const_int 0))
4577                      (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1))))]
4578       */
4579       emit_insn (gen_rtx_SET (gen_rtx_REG (CCmode, CC_REGNUM),
4580                               gen_rtx_COMPARE (CCmode, operands[0], const0_rtx)));
4581       emit_insn (gen_rtx_COND_EXEC (VOIDmode,
4582                                     (gen_rtx_LT (SImode,
4583                                                  gen_rtx_REG (CCmode, CC_REGNUM),
4584                                                  const0_rtx)),
4585                                     (gen_rtx_SET (operands[0],
4586                                                   (gen_rtx_MINUS (SImode,
4587                                                                   const0_rtx,
4588                                                                   operands[1]))))));
4589       DONE;
4590      }
4591    else
4592      {
4593       /* Emit the pattern:
4594          alt1: eor%?\\t%0, %1, %1, asr #31\;sub%?\\t%0, %0, %1, asr #31
4595          [(set (match_dup 0)
4596                (xor:SI (match_dup 1)
4597                        (ashiftrt:SI (match_dup 1) (const_int 31))))
4598           (set (match_dup 0)
4599                (minus:SI (match_dup 0)
4600                       (ashiftrt:SI (match_dup 1) (const_int 31))))]
4601       */
4602       emit_insn (gen_rtx_SET (operands[0],
4603                               gen_rtx_XOR (SImode,
4604                                            gen_rtx_ASHIFTRT (SImode,
4605                                                              operands[1],
4606                                                              GEN_INT (31)),
4607                                            operands[1])));
4608       emit_insn (gen_rtx_SET (operands[0],
4609                               gen_rtx_MINUS (SImode,
4610                                              operands[0],
4611                                              gen_rtx_ASHIFTRT (SImode,
4612                                                                operands[1],
4613                                                                GEN_INT (31)))));
4614       DONE;
4615      }
4616   }
4617   [(set_attr "conds" "clob,*")
4618    (set_attr "shift" "1")
4619    (set_attr "predicable" "no, yes")
4620    (set_attr "length" "8")
4621    (set_attr "type" "multiple")]
4624 (define_insn_and_split "*arm_neg_abssi2"
4625   [(set (match_operand:SI 0 "s_register_operand" "=r,&r")
4626         (neg:SI (abs:SI (match_operand:SI 1 "s_register_operand" "0,r"))))
4627    (clobber (reg:CC CC_REGNUM))]
4628   "TARGET_ARM"
4629   "#"
4630   "&& reload_completed"
4631   [(const_int 0)]
4632   {
4633    /* if (which_alternative == 0) */
4634    if (REGNO (operands[0]) == REGNO (operands[1]))
4635      {
4636       /* Emit the pattern:
4637          cmp\\t%0, #0\;rsbgt\\t%0, %0, #0
4638       */
4639       emit_insn (gen_rtx_SET (gen_rtx_REG (CCmode, CC_REGNUM),
4640                               gen_rtx_COMPARE (CCmode, operands[0], const0_rtx)));
4641       emit_insn (gen_rtx_COND_EXEC (VOIDmode,
4642                                     gen_rtx_GT (SImode,
4643                                                 gen_rtx_REG (CCmode, CC_REGNUM),
4644                                                 const0_rtx),
4645                                     gen_rtx_SET (operands[0],
4646                                                  (gen_rtx_MINUS (SImode,
4647                                                                  const0_rtx,
4648                                                                  operands[1])))));
4649      }
4650    else
4651      {
4652       /* Emit the pattern:
4653          eor%?\\t%0, %1, %1, asr #31\;rsb%?\\t%0, %0, %1, asr #31
4654       */
4655       emit_insn (gen_rtx_SET (operands[0],
4656                               gen_rtx_XOR (SImode,
4657                                            gen_rtx_ASHIFTRT (SImode,
4658                                                              operands[1],
4659                                                              GEN_INT (31)),
4660                                            operands[1])));
4661       emit_insn (gen_rtx_SET (operands[0],
4662                               gen_rtx_MINUS (SImode,
4663                                              gen_rtx_ASHIFTRT (SImode,
4664                                                                operands[1],
4665                                                                GEN_INT (31)),
4666                                              operands[0])));
4667      }
4668    DONE;
4669   }
4670   [(set_attr "conds" "clob,*")
4671    (set_attr "shift" "1")
4672    (set_attr "predicable" "no, yes")
4673    (set_attr "length" "8")
4674    (set_attr "type" "multiple")]
4677 (define_expand "abssf2"
4678   [(set (match_operand:SF         0 "s_register_operand" "")
4679         (abs:SF (match_operand:SF 1 "s_register_operand" "")))]
4680   "TARGET_32BIT && TARGET_HARD_FLOAT"
4681   "")
4683 (define_expand "absdf2"
4684   [(set (match_operand:DF         0 "s_register_operand" "")
4685         (abs:DF (match_operand:DF 1 "s_register_operand" "")))]
4686   "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
4687   "")
4689 (define_expand "sqrtsf2"
4690   [(set (match_operand:SF 0 "s_register_operand" "")
4691         (sqrt:SF (match_operand:SF 1 "s_register_operand" "")))]
4692   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
4693   "")
4695 (define_expand "sqrtdf2"
4696   [(set (match_operand:DF 0 "s_register_operand" "")
4697         (sqrt:DF (match_operand:DF 1 "s_register_operand" "")))]
4698   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
4699   "")
4701 (define_insn_and_split "one_cmpldi2"
4702   [(set (match_operand:DI 0 "s_register_operand"         "=w,&r,&r,?w")
4703         (not:DI (match_operand:DI 1 "s_register_operand" " w, 0, r, w")))]
4704   "TARGET_32BIT"
4705   "@
4706    vmvn\t%P0, %P1
4707    #
4708    #
4709    vmvn\t%P0, %P1"
4710   "TARGET_32BIT && reload_completed
4711    && arm_general_register_operand (operands[0], DImode)"
4712   [(set (match_dup 0) (not:SI (match_dup 1)))
4713    (set (match_dup 2) (not:SI (match_dup 3)))]
4714   "
4715   {
4716     operands[2] = gen_highpart (SImode, operands[0]);
4717     operands[0] = gen_lowpart (SImode, operands[0]);
4718     operands[3] = gen_highpart (SImode, operands[1]);
4719     operands[1] = gen_lowpart (SImode, operands[1]);
4720   }"
4721   [(set_attr "length" "*,8,8,*")
4722    (set_attr "predicable" "no,yes,yes,no")
4723    (set_attr "type" "neon_move,multiple,multiple,neon_move")
4724    (set_attr "arch" "neon_for_64bits,*,*,avoid_neon_for_64bits")]
4727 (define_expand "one_cmplsi2"
4728   [(set (match_operand:SI         0 "s_register_operand" "")
4729         (not:SI (match_operand:SI 1 "s_register_operand" "")))]
4730   "TARGET_EITHER"
4731   ""
4734 (define_insn "*arm_one_cmplsi2"
4735   [(set (match_operand:SI         0 "s_register_operand" "=l,r")
4736         (not:SI (match_operand:SI 1 "s_register_operand"  "l,r")))]
4737   "TARGET_32BIT"
4738   "mvn%?\\t%0, %1"
4739   [(set_attr "predicable" "yes")
4740    (set_attr "predicable_short_it" "yes,no")
4741    (set_attr "arch" "t2,*")
4742    (set_attr "length" "4")
4743    (set_attr "type" "mvn_reg")]
4746 (define_insn "*notsi_compare0"
4747   [(set (reg:CC_NOOV CC_REGNUM)
4748         (compare:CC_NOOV (not:SI (match_operand:SI 1 "s_register_operand" "r"))
4749                          (const_int 0)))
4750    (set (match_operand:SI 0 "s_register_operand" "=r")
4751         (not:SI (match_dup 1)))]
4752   "TARGET_32BIT"
4753   "mvns%?\\t%0, %1"
4754   [(set_attr "conds" "set")
4755    (set_attr "type" "mvn_reg")]
4758 (define_insn "*notsi_compare0_scratch"
4759   [(set (reg:CC_NOOV CC_REGNUM)
4760         (compare:CC_NOOV (not:SI (match_operand:SI 1 "s_register_operand" "r"))
4761                          (const_int 0)))
4762    (clobber (match_scratch:SI 0 "=r"))]
4763   "TARGET_32BIT"
4764   "mvns%?\\t%0, %1"
4765   [(set_attr "conds" "set")
4766    (set_attr "type" "mvn_reg")]
4769 ;; Fixed <--> Floating conversion insns
4771 (define_expand "floatsihf2"
4772   [(set (match_operand:HF           0 "general_operand" "")
4773         (float:HF (match_operand:SI 1 "general_operand" "")))]
4774   "TARGET_EITHER"
4775   "
4776   {
4777     rtx op1 = gen_reg_rtx (SFmode);
4778     expand_float (op1, operands[1], 0);
4779     op1 = convert_to_mode (HFmode, op1, 0);
4780     emit_move_insn (operands[0], op1);
4781     DONE;
4782   }"
4785 (define_expand "floatdihf2"
4786   [(set (match_operand:HF           0 "general_operand" "")
4787         (float:HF (match_operand:DI 1 "general_operand" "")))]
4788   "TARGET_EITHER"
4789   "
4790   {
4791     rtx op1 = gen_reg_rtx (SFmode);
4792     expand_float (op1, operands[1], 0);
4793     op1 = convert_to_mode (HFmode, op1, 0);
4794     emit_move_insn (operands[0], op1);
4795     DONE;
4796   }"
4799 (define_expand "floatsisf2"
4800   [(set (match_operand:SF           0 "s_register_operand" "")
4801         (float:SF (match_operand:SI 1 "s_register_operand" "")))]
4802   "TARGET_32BIT && TARGET_HARD_FLOAT"
4803   "
4806 (define_expand "floatsidf2"
4807   [(set (match_operand:DF           0 "s_register_operand" "")
4808         (float:DF (match_operand:SI 1 "s_register_operand" "")))]
4809   "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
4810   "
4813 (define_expand "fix_trunchfsi2"
4814   [(set (match_operand:SI         0 "general_operand" "")
4815         (fix:SI (fix:HF (match_operand:HF 1 "general_operand"  ""))))]
4816   "TARGET_EITHER"
4817   "
4818   {
4819     rtx op1 = convert_to_mode (SFmode, operands[1], 0);
4820     expand_fix (operands[0], op1, 0);
4821     DONE;
4822   }"
4825 (define_expand "fix_trunchfdi2"
4826   [(set (match_operand:DI         0 "general_operand" "")
4827         (fix:DI (fix:HF (match_operand:HF 1 "general_operand"  ""))))]
4828   "TARGET_EITHER"
4829   "
4830   {
4831     rtx op1 = convert_to_mode (SFmode, operands[1], 0);
4832     expand_fix (operands[0], op1, 0);
4833     DONE;
4834   }"
4837 (define_expand "fix_truncsfsi2"
4838   [(set (match_operand:SI         0 "s_register_operand" "")
4839         (fix:SI (fix:SF (match_operand:SF 1 "s_register_operand"  ""))))]
4840   "TARGET_32BIT && TARGET_HARD_FLOAT"
4841   "
4844 (define_expand "fix_truncdfsi2"
4845   [(set (match_operand:SI         0 "s_register_operand" "")
4846         (fix:SI (fix:DF (match_operand:DF 1 "s_register_operand"  ""))))]
4847   "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
4848   "
4851 ;; Truncation insns
4853 (define_expand "truncdfsf2"
4854   [(set (match_operand:SF  0 "s_register_operand" "")
4855         (float_truncate:SF
4856          (match_operand:DF 1 "s_register_operand" "")))]
4857   "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
4858   ""
4861 /* DFmode -> HFmode conversions have to go through SFmode.  */
4862 (define_expand "truncdfhf2"
4863   [(set (match_operand:HF  0 "general_operand" "")
4864         (float_truncate:HF
4865          (match_operand:DF 1 "general_operand" "")))]
4866   "TARGET_EITHER"
4867   "
4868   {
4869     rtx op1;
4870     op1 = convert_to_mode (SFmode, operands[1], 0);
4871     op1 = convert_to_mode (HFmode, op1, 0);
4872     emit_move_insn (operands[0], op1);
4873     DONE;
4874   }"
4877 ;; Zero and sign extension instructions.
4879 (define_insn "zero_extend<mode>di2"
4880   [(set (match_operand:DI 0 "s_register_operand" "=w,r,?r,w")
4881         (zero_extend:DI (match_operand:QHSI 1 "<qhs_zextenddi_op>"
4882                                             "<qhs_zextenddi_cstr>")))]
4883   "TARGET_32BIT <qhs_zextenddi_cond>"
4884   "#"
4885   [(set_attr "length" "8,4,8,8")
4886    (set_attr "arch" "neon_for_64bits,*,*,avoid_neon_for_64bits")
4887    (set_attr "ce_count" "2")
4888    (set_attr "predicable" "yes")
4889    (set_attr "type" "multiple,mov_reg,multiple,multiple")]
4892 (define_insn "extend<mode>di2"
4893   [(set (match_operand:DI 0 "s_register_operand" "=w,r,?r,?r,w")
4894         (sign_extend:DI (match_operand:QHSI 1 "<qhs_extenddi_op>"
4895                                             "<qhs_extenddi_cstr>")))]
4896   "TARGET_32BIT <qhs_sextenddi_cond>"
4897   "#"
4898   [(set_attr "length" "8,4,8,8,8")
4899    (set_attr "ce_count" "2")
4900    (set_attr "shift" "1")
4901    (set_attr "predicable" "yes")
4902    (set_attr "arch" "neon_for_64bits,*,a,t,avoid_neon_for_64bits")
4903    (set_attr "type" "multiple,mov_reg,multiple,multiple,multiple")]
4906 ;; Splits for all extensions to DImode
4907 (define_split
4908   [(set (match_operand:DI 0 "s_register_operand" "")
4909         (zero_extend:DI (match_operand 1 "nonimmediate_operand" "")))]
4910   "TARGET_32BIT && reload_completed && !IS_VFP_REGNUM (REGNO (operands[0]))"
4911   [(set (match_dup 0) (match_dup 1))]
4913   rtx lo_part = gen_lowpart (SImode, operands[0]);
4914   machine_mode src_mode = GET_MODE (operands[1]);
4916   if (REG_P (operands[0])
4917       && !reg_overlap_mentioned_p (operands[0], operands[1]))
4918     emit_clobber (operands[0]);
4919   if (!REG_P (lo_part) || src_mode != SImode
4920       || !rtx_equal_p (lo_part, operands[1]))
4921     {
4922       if (src_mode == SImode)
4923         emit_move_insn (lo_part, operands[1]);
4924       else
4925         emit_insn (gen_rtx_SET (lo_part,
4926                                 gen_rtx_ZERO_EXTEND (SImode, operands[1])));
4927       operands[1] = lo_part;
4928     }
4929   operands[0] = gen_highpart (SImode, operands[0]);
4930   operands[1] = const0_rtx;
4933 (define_split
4934   [(set (match_operand:DI 0 "s_register_operand" "")
4935         (sign_extend:DI (match_operand 1 "nonimmediate_operand" "")))]
4936   "TARGET_32BIT && reload_completed && !IS_VFP_REGNUM (REGNO (operands[0]))"
4937   [(set (match_dup 0) (ashiftrt:SI (match_dup 1) (const_int 31)))]
4939   rtx lo_part = gen_lowpart (SImode, operands[0]);
4940   machine_mode src_mode = GET_MODE (operands[1]);
4942   if (REG_P (operands[0])
4943       && !reg_overlap_mentioned_p (operands[0], operands[1]))
4944     emit_clobber (operands[0]);
4946   if (!REG_P (lo_part) || src_mode != SImode
4947       || !rtx_equal_p (lo_part, operands[1]))
4948     {
4949       if (src_mode == SImode)
4950         emit_move_insn (lo_part, operands[1]);
4951       else
4952         emit_insn (gen_rtx_SET (lo_part,
4953                                 gen_rtx_SIGN_EXTEND (SImode, operands[1])));
4954       operands[1] = lo_part;
4955     }
4956   operands[0] = gen_highpart (SImode, operands[0]);
4959 (define_expand "zero_extendhisi2"
4960   [(set (match_operand:SI 0 "s_register_operand" "")
4961         (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
4962   "TARGET_EITHER"
4964   if (TARGET_ARM && !arm_arch4 && MEM_P (operands[1]))
4965     {
4966       emit_insn (gen_movhi_bytes (operands[0], operands[1]));
4967       DONE;
4968     }
4969   if (!arm_arch6 && !MEM_P (operands[1]))
4970     {
4971       rtx t = gen_lowpart (SImode, operands[1]);
4972       rtx tmp = gen_reg_rtx (SImode);
4973       emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (16)));
4974       emit_insn (gen_lshrsi3 (operands[0], tmp, GEN_INT (16)));
4975       DONE;
4976     }
4979 (define_split
4980   [(set (match_operand:SI 0 "s_register_operand" "")
4981         (zero_extend:SI (match_operand:HI 1 "s_register_operand" "")))]
4982   "!TARGET_THUMB2 && !arm_arch6"
4983   [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
4984    (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 16)))]
4986   operands[2] = gen_lowpart (SImode, operands[1]);
4989 (define_insn "*arm_zero_extendhisi2"
4990   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4991         (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
4992   "TARGET_ARM && arm_arch4 && !arm_arch6"
4993   "@
4994    #
4995    ldrh%?\\t%0, %1"
4996   [(set_attr "type" "alu_shift_reg,load_byte")
4997    (set_attr "predicable" "yes")]
5000 (define_insn "*arm_zero_extendhisi2_v6"
5001   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5002         (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,Uh")))]
5003   "TARGET_ARM && arm_arch6"
5004   "@
5005    uxth%?\\t%0, %1
5006    ldrh%?\\t%0, %1"
5007   [(set_attr "predicable" "yes")
5008    (set_attr "type" "extend,load_byte")]
5011 (define_insn "*arm_zero_extendhisi2addsi"
5012   [(set (match_operand:SI 0 "s_register_operand" "=r")
5013         (plus:SI (zero_extend:SI (match_operand:HI 1 "s_register_operand" "r"))
5014                  (match_operand:SI 2 "s_register_operand" "r")))]
5015   "TARGET_INT_SIMD"
5016   "uxtah%?\\t%0, %2, %1"
5017   [(set_attr "type" "alu_shift_reg")
5018    (set_attr "predicable" "yes")
5019    (set_attr "predicable_short_it" "no")]
5022 (define_expand "zero_extendqisi2"
5023   [(set (match_operand:SI 0 "s_register_operand" "")
5024         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))]
5025   "TARGET_EITHER"
5027   if (TARGET_ARM && !arm_arch6 && !MEM_P (operands[1]))
5028     {
5029       emit_insn (gen_andsi3 (operands[0],
5030                              gen_lowpart (SImode, operands[1]),
5031                                           GEN_INT (255)));
5032       DONE;
5033     }
5034   if (!arm_arch6 && !MEM_P (operands[1]))
5035     {
5036       rtx t = gen_lowpart (SImode, operands[1]);
5037       rtx tmp = gen_reg_rtx (SImode);
5038       emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (24)));
5039       emit_insn (gen_lshrsi3 (operands[0], tmp, GEN_INT (24)));
5040       DONE;
5041     }
5044 (define_split
5045   [(set (match_operand:SI 0 "s_register_operand" "")
5046         (zero_extend:SI (match_operand:QI 1 "s_register_operand" "")))]
5047   "!arm_arch6"
5048   [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 24)))
5049    (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 24)))]
5051   operands[2] = simplify_gen_subreg (SImode, operands[1], QImode, 0);
5052   if (TARGET_ARM)
5053     {
5054       emit_insn (gen_andsi3 (operands[0], operands[2], GEN_INT (255)));
5055       DONE;
5056     }
5059 (define_insn "*arm_zero_extendqisi2"
5060   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5061         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
5062   "TARGET_ARM && !arm_arch6"
5063   "@
5064    #
5065    ldrb%?\\t%0, %1\\t%@ zero_extendqisi2"
5066   [(set_attr "length" "8,4")
5067    (set_attr "type" "alu_shift_reg,load_byte")
5068    (set_attr "predicable" "yes")]
5071 (define_insn "*arm_zero_extendqisi2_v6"
5072   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5073         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,Uh")))]
5074   "TARGET_ARM && arm_arch6"
5075   "@
5076    uxtb%?\\t%0, %1
5077    ldrb%?\\t%0, %1\\t%@ zero_extendqisi2"
5078   [(set_attr "type" "extend,load_byte")
5079    (set_attr "predicable" "yes")]
5082 (define_insn "*arm_zero_extendqisi2addsi"
5083   [(set (match_operand:SI 0 "s_register_operand" "=r")
5084         (plus:SI (zero_extend:SI (match_operand:QI 1 "s_register_operand" "r"))
5085                  (match_operand:SI 2 "s_register_operand" "r")))]
5086   "TARGET_INT_SIMD"
5087   "uxtab%?\\t%0, %2, %1"
5088   [(set_attr "predicable" "yes")
5089    (set_attr "predicable_short_it" "no")
5090    (set_attr "type" "alu_shift_reg")]
5093 (define_split
5094   [(set (match_operand:SI 0 "s_register_operand" "")
5095         (zero_extend:SI (subreg:QI (match_operand:SI 1 "" "") 0)))
5096    (clobber (match_operand:SI 2 "s_register_operand" ""))]
5097   "TARGET_32BIT && (!MEM_P (operands[1])) && ! BYTES_BIG_ENDIAN"
5098   [(set (match_dup 2) (match_dup 1))
5099    (set (match_dup 0) (and:SI (match_dup 2) (const_int 255)))]
5100   ""
5103 (define_split
5104   [(set (match_operand:SI 0 "s_register_operand" "")
5105         (zero_extend:SI (subreg:QI (match_operand:SI 1 "" "") 3)))
5106    (clobber (match_operand:SI 2 "s_register_operand" ""))]
5107   "TARGET_32BIT && (!MEM_P (operands[1])) && BYTES_BIG_ENDIAN"
5108   [(set (match_dup 2) (match_dup 1))
5109    (set (match_dup 0) (and:SI (match_dup 2) (const_int 255)))]
5110   ""
5114 (define_split
5115   [(set (match_operand:SI 0 "s_register_operand" "")
5116         (IOR_XOR:SI (and:SI (ashift:SI
5117                              (match_operand:SI 1 "s_register_operand" "")
5118                              (match_operand:SI 2 "const_int_operand" ""))
5119                             (match_operand:SI 3 "const_int_operand" ""))
5120                     (zero_extend:SI
5121                      (match_operator 5 "subreg_lowpart_operator"
5122                       [(match_operand:SI 4 "s_register_operand" "")]))))]
5123   "TARGET_32BIT
5124    && (UINTVAL (operands[3])
5125        == (GET_MODE_MASK (GET_MODE (operands[5]))
5126            & (GET_MODE_MASK (GET_MODE (operands[5]))
5127               << (INTVAL (operands[2])))))"
5128   [(set (match_dup 0) (IOR_XOR:SI (ashift:SI (match_dup 1) (match_dup 2))
5129                                   (match_dup 4)))
5130    (set (match_dup 0) (zero_extend:SI (match_dup 5)))]
5131   "operands[5] = gen_lowpart (GET_MODE (operands[5]), operands[0]);"
5134 (define_insn "*compareqi_eq0"
5135   [(set (reg:CC_Z CC_REGNUM)
5136         (compare:CC_Z (match_operand:QI 0 "s_register_operand" "r")
5137                          (const_int 0)))]
5138   "TARGET_32BIT"
5139   "tst%?\\t%0, #255"
5140   [(set_attr "conds" "set")
5141    (set_attr "predicable" "yes")
5142    (set_attr "predicable_short_it" "no")
5143    (set_attr "type" "logic_imm")]
5146 (define_expand "extendhisi2"
5147   [(set (match_operand:SI 0 "s_register_operand" "")
5148         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
5149   "TARGET_EITHER"
5151   if (TARGET_THUMB1)
5152     {
5153       emit_insn (gen_thumb1_extendhisi2 (operands[0], operands[1]));
5154       DONE;
5155     }
5156   if (MEM_P (operands[1]) && TARGET_ARM && !arm_arch4)
5157     {
5158       emit_insn (gen_extendhisi2_mem (operands[0], operands[1]));
5159       DONE;
5160     }
5162   if (!arm_arch6 && !MEM_P (operands[1]))
5163     {
5164       rtx t = gen_lowpart (SImode, operands[1]);
5165       rtx tmp = gen_reg_rtx (SImode);
5166       emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (16)));
5167       emit_insn (gen_ashrsi3 (operands[0], tmp, GEN_INT (16)));
5168       DONE;
5169     }
5172 (define_split
5173   [(parallel
5174     [(set (match_operand:SI 0 "register_operand" "")
5175           (sign_extend:SI (match_operand:HI 1 "register_operand" "")))
5176      (clobber (match_scratch:SI 2 ""))])]
5177   "!arm_arch6"
5178   [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
5179    (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
5181   operands[2] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
5184 ;; This pattern will only be used when ldsh is not available
5185 (define_expand "extendhisi2_mem"
5186   [(set (match_dup 2) (zero_extend:SI (match_operand:HI 1 "" "")))
5187    (set (match_dup 3)
5188         (zero_extend:SI (match_dup 7)))
5189    (set (match_dup 6) (ashift:SI (match_dup 4) (const_int 24)))
5190    (set (match_operand:SI 0 "" "")
5191         (ior:SI (ashiftrt:SI (match_dup 6) (const_int 16)) (match_dup 5)))]
5192   "TARGET_ARM"
5193   "
5194   {
5195     rtx mem1, mem2;
5196     rtx addr = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
5198     mem1 = change_address (operands[1], QImode, addr);
5199     mem2 = change_address (operands[1], QImode,
5200                            plus_constant (Pmode, addr, 1));
5201     operands[0] = gen_lowpart (SImode, operands[0]);
5202     operands[1] = mem1;
5203     operands[2] = gen_reg_rtx (SImode);
5204     operands[3] = gen_reg_rtx (SImode);
5205     operands[6] = gen_reg_rtx (SImode);
5206     operands[7] = mem2;
5208     if (BYTES_BIG_ENDIAN)
5209       {
5210         operands[4] = operands[2];
5211         operands[5] = operands[3];
5212       }
5213     else
5214       {
5215         operands[4] = operands[3];
5216         operands[5] = operands[2];
5217       }
5218   }"
5221 (define_split
5222   [(set (match_operand:SI 0 "register_operand" "")
5223         (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
5224   "!arm_arch6"
5225   [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
5226    (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
5228   operands[2] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
5231 (define_insn "*arm_extendhisi2"
5232   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5233         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,Uh")))]
5234   "TARGET_ARM && arm_arch4 && !arm_arch6"
5235   "@
5236    #
5237    ldrsh%?\\t%0, %1"
5238   [(set_attr "length" "8,4")
5239    (set_attr "type" "alu_shift_reg,load_byte")
5240    (set_attr "predicable" "yes")]
5243 ;; ??? Check Thumb-2 pool range
5244 (define_insn "*arm_extendhisi2_v6"
5245   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5246         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,Uh")))]
5247   "TARGET_32BIT && arm_arch6"
5248   "@
5249    sxth%?\\t%0, %1
5250    ldrsh%?\\t%0, %1"
5251   [(set_attr "type" "extend,load_byte")
5252    (set_attr "predicable" "yes")
5253    (set_attr "predicable_short_it" "no")]
5256 (define_insn "*arm_extendhisi2addsi"
5257   [(set (match_operand:SI 0 "s_register_operand" "=r")
5258         (plus:SI (sign_extend:SI (match_operand:HI 1 "s_register_operand" "r"))
5259                  (match_operand:SI 2 "s_register_operand" "r")))]
5260   "TARGET_INT_SIMD"
5261   "sxtah%?\\t%0, %2, %1"
5262   [(set_attr "type" "alu_shift_reg")]
5265 (define_expand "extendqihi2"
5266   [(set (match_dup 2)
5267         (ashift:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "")
5268                    (const_int 24)))
5269    (set (match_operand:HI 0 "s_register_operand" "")
5270         (ashiftrt:SI (match_dup 2)
5271                      (const_int 24)))]
5272   "TARGET_ARM"
5273   "
5274   {
5275     if (arm_arch4 && MEM_P (operands[1]))
5276       {
5277         emit_insn (gen_rtx_SET (operands[0],
5278                                 gen_rtx_SIGN_EXTEND (HImode, operands[1])));
5279         DONE;
5280       }
5281     if (!s_register_operand (operands[1], QImode))
5282       operands[1] = copy_to_mode_reg (QImode, operands[1]);
5283     operands[0] = gen_lowpart (SImode, operands[0]);
5284     operands[1] = gen_lowpart (SImode, operands[1]);
5285     operands[2] = gen_reg_rtx (SImode);
5286   }"
5289 (define_insn "*arm_extendqihi_insn"
5290   [(set (match_operand:HI 0 "s_register_operand" "=r")
5291         (sign_extend:HI (match_operand:QI 1 "arm_extendqisi_mem_op" "Uq")))]
5292   "TARGET_ARM && arm_arch4"
5293   "ldrsb%?\\t%0, %1"
5294   [(set_attr "type" "load_byte")
5295    (set_attr "predicable" "yes")]
5298 (define_expand "extendqisi2"
5299   [(set (match_operand:SI 0 "s_register_operand" "")
5300         (sign_extend:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "")))]
5301   "TARGET_EITHER"
5303   if (!arm_arch4 && MEM_P (operands[1]))
5304     operands[1] = copy_to_mode_reg (QImode, operands[1]);
5306   if (!arm_arch6 && !MEM_P (operands[1]))
5307     {
5308       rtx t = gen_lowpart (SImode, operands[1]);
5309       rtx tmp = gen_reg_rtx (SImode);
5310       emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (24)));
5311       emit_insn (gen_ashrsi3 (operands[0], tmp, GEN_INT (24)));
5312       DONE;
5313     }
5316 (define_split
5317   [(set (match_operand:SI 0 "register_operand" "")
5318         (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
5319   "!arm_arch6"
5320   [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 24)))
5321    (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 24)))]
5323   operands[2] = simplify_gen_subreg (SImode, operands[1], QImode, 0);
5326 (define_insn "*arm_extendqisi"
5327   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5328         (sign_extend:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "r,Uq")))]
5329   "TARGET_ARM && arm_arch4 && !arm_arch6"
5330   "@
5331    #
5332    ldrsb%?\\t%0, %1"
5333   [(set_attr "length" "8,4")
5334    (set_attr "type" "alu_shift_reg,load_byte")
5335    (set_attr "predicable" "yes")]
5338 (define_insn "*arm_extendqisi_v6"
5339   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5340         (sign_extend:SI
5341          (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "r,Uq")))]
5342   "TARGET_ARM && arm_arch6"
5343   "@
5344    sxtb%?\\t%0, %1
5345    ldrsb%?\\t%0, %1"
5346   [(set_attr "type" "extend,load_byte")
5347    (set_attr "predicable" "yes")]
5350 (define_insn "*arm_extendqisi2addsi"
5351   [(set (match_operand:SI 0 "s_register_operand" "=r")
5352         (plus:SI (sign_extend:SI (match_operand:QI 1 "s_register_operand" "r"))
5353                  (match_operand:SI 2 "s_register_operand" "r")))]
5354   "TARGET_INT_SIMD"
5355   "sxtab%?\\t%0, %2, %1"
5356   [(set_attr "type" "alu_shift_reg")
5357    (set_attr "predicable" "yes")
5358    (set_attr "predicable_short_it" "no")]
5361 (define_expand "extendsfdf2"
5362   [(set (match_operand:DF                  0 "s_register_operand" "")
5363         (float_extend:DF (match_operand:SF 1 "s_register_operand"  "")))]
5364   "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
5365   ""
5368 /* HFmode -> DFmode conversions have to go through SFmode.  */
5369 (define_expand "extendhfdf2"
5370   [(set (match_operand:DF                  0 "general_operand" "")
5371         (float_extend:DF (match_operand:HF 1 "general_operand"  "")))]
5372   "TARGET_EITHER"
5373   "
5374   {
5375     rtx op1;
5376     op1 = convert_to_mode (SFmode, operands[1], 0);
5377     op1 = convert_to_mode (DFmode, op1, 0);
5378     emit_insn (gen_movdf (operands[0], op1));
5379     DONE;
5380   }"
5383 ;; Move insns (including loads and stores)
5385 ;; XXX Just some ideas about movti.
5386 ;; I don't think these are a good idea on the arm, there just aren't enough
5387 ;; registers
5388 ;;(define_expand "loadti"
5389 ;;  [(set (match_operand:TI 0 "s_register_operand" "")
5390 ;;      (mem:TI (match_operand:SI 1 "address_operand" "")))]
5391 ;;  "" "")
5393 ;;(define_expand "storeti"
5394 ;;  [(set (mem:TI (match_operand:TI 0 "address_operand" ""))
5395 ;;      (match_operand:TI 1 "s_register_operand" ""))]
5396 ;;  "" "")
5398 ;;(define_expand "movti"
5399 ;;  [(set (match_operand:TI 0 "general_operand" "")
5400 ;;      (match_operand:TI 1 "general_operand" ""))]
5401 ;;  ""
5402 ;;  "
5404 ;;  rtx insn;
5406 ;;  if (MEM_P (operands[0]) && MEM_P (operands[1]))
5407 ;;    operands[1] = copy_to_reg (operands[1]);
5408 ;;  if (MEM_P (operands[0]))
5409 ;;    insn = gen_storeti (XEXP (operands[0], 0), operands[1]);
5410 ;;  else if (MEM_P (operands[1]))
5411 ;;    insn = gen_loadti (operands[0], XEXP (operands[1], 0));
5412 ;;  else
5413 ;;    FAIL;
5415 ;;  emit_insn (insn);
5416 ;;  DONE;
5417 ;;}")
5419 ;; Recognize garbage generated above.
5421 ;;(define_insn ""
5422 ;;  [(set (match_operand:TI 0 "general_operand" "=r,r,r,<,>,m")
5423 ;;      (match_operand:TI 1 "general_operand" "<,>,m,r,r,r"))]
5424 ;;  ""
5425 ;;  "*
5426 ;;  {
5427 ;;    register mem = (which_alternative < 3);
5428 ;;    register const char *template;
5430 ;;    operands[mem] = XEXP (operands[mem], 0);
5431 ;;    switch (which_alternative)
5432 ;;      {
5433 ;;      case 0: template = \"ldmdb\\t%1!, %M0\"; break;
5434 ;;      case 1: template = \"ldmia\\t%1!, %M0\"; break;
5435 ;;      case 2: template = \"ldmia\\t%1, %M0\"; break;
5436 ;;      case 3: template = \"stmdb\\t%0!, %M1\"; break;
5437 ;;      case 4: template = \"stmia\\t%0!, %M1\"; break;
5438 ;;      case 5: template = \"stmia\\t%0, %M1\"; break;
5439 ;;      }
5440 ;;    output_asm_insn (template, operands);
5441 ;;    return \"\";
5442 ;;  }")
5444 (define_expand "movdi"
5445   [(set (match_operand:DI 0 "general_operand" "")
5446         (match_operand:DI 1 "general_operand" ""))]
5447   "TARGET_EITHER"
5448   "
5449   if (can_create_pseudo_p ())
5450     {
5451       if (!REG_P (operands[0]))
5452         operands[1] = force_reg (DImode, operands[1]);
5453     }
5454   if (REG_P (operands[0]) && REGNO (operands[0]) <= LAST_ARM_REGNUM
5455       && !HARD_REGNO_MODE_OK (REGNO (operands[0]), DImode))
5456     {
5457       /* Avoid LDRD's into an odd-numbered register pair in ARM state
5458          when expanding function calls.  */
5459       gcc_assert (can_create_pseudo_p ());
5460       if (MEM_P (operands[1]) && MEM_VOLATILE_P (operands[1]))
5461         {
5462           /* Perform load into legal reg pair first, then move.  */
5463           rtx reg = gen_reg_rtx (DImode);
5464           emit_insn (gen_movdi (reg, operands[1]));
5465           operands[1] = reg;
5466         }
5467       emit_move_insn (gen_lowpart (SImode, operands[0]),
5468                       gen_lowpart (SImode, operands[1]));
5469       emit_move_insn (gen_highpart (SImode, operands[0]),
5470                       gen_highpart (SImode, operands[1]));
5471       DONE;
5472     }
5473   else if (REG_P (operands[1]) && REGNO (operands[1]) <= LAST_ARM_REGNUM
5474            && !HARD_REGNO_MODE_OK (REGNO (operands[1]), DImode))
5475     {
5476       /* Avoid STRD's from an odd-numbered register pair in ARM state
5477          when expanding function prologue.  */
5478       gcc_assert (can_create_pseudo_p ());
5479       rtx split_dest = (MEM_P (operands[0]) && MEM_VOLATILE_P (operands[0]))
5480                        ? gen_reg_rtx (DImode)
5481                        : operands[0];
5482       emit_move_insn (gen_lowpart (SImode, split_dest),
5483                       gen_lowpart (SImode, operands[1]));
5484       emit_move_insn (gen_highpart (SImode, split_dest),
5485                       gen_highpart (SImode, operands[1]));
5486       if (split_dest != operands[0])
5487         emit_insn (gen_movdi (operands[0], split_dest));
5488       DONE;
5489     }
5490   "
5493 (define_insn "*arm_movdi"
5494   [(set (match_operand:DI 0 "nonimmediate_di_operand" "=r, r, r, q, m")
5495         (match_operand:DI 1 "di_operand"              "rDa,Db,Dc,mi,q"))]
5496   "TARGET_32BIT
5497    && !(TARGET_HARD_FLOAT && TARGET_VFP)
5498    && !TARGET_IWMMXT
5499    && (   register_operand (operands[0], DImode)
5500        || register_operand (operands[1], DImode))"
5501   "*
5502   switch (which_alternative)
5503     {
5504     case 0:
5505     case 1:
5506     case 2:
5507       return \"#\";
5508     default:
5509       return output_move_double (operands, true, NULL);
5510     }
5511   "
5512   [(set_attr "length" "8,12,16,8,8")
5513    (set_attr "type" "multiple,multiple,multiple,load2,store2")
5514    (set_attr "arm_pool_range" "*,*,*,1020,*")
5515    (set_attr "arm_neg_pool_range" "*,*,*,1004,*")
5516    (set_attr "thumb2_pool_range" "*,*,*,4094,*")
5517    (set_attr "thumb2_neg_pool_range" "*,*,*,0,*")]
5520 (define_split
5521   [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
5522         (match_operand:ANY64 1 "immediate_operand" ""))]
5523   "TARGET_32BIT
5524    && reload_completed
5525    && (arm_const_double_inline_cost (operands[1])
5526        <= arm_max_const_double_inline_cost ())"
5527   [(const_int 0)]
5528   "
5529   arm_split_constant (SET, SImode, curr_insn,
5530                       INTVAL (gen_lowpart (SImode, operands[1])),
5531                       gen_lowpart (SImode, operands[0]), NULL_RTX, 0);
5532   arm_split_constant (SET, SImode, curr_insn,
5533                       INTVAL (gen_highpart_mode (SImode,
5534                                                  GET_MODE (operands[0]),
5535                                                  operands[1])),
5536                       gen_highpart (SImode, operands[0]), NULL_RTX, 0);
5537   DONE;
5538   "
5541 ; If optimizing for size, or if we have load delay slots, then 
5542 ; we want to split the constant into two separate operations. 
5543 ; In both cases this may split a trivial part into a single data op
5544 ; leaving a single complex constant to load.  We can also get longer
5545 ; offsets in a LDR which means we get better chances of sharing the pool
5546 ; entries.  Finally, we can normally do a better job of scheduling
5547 ; LDR instructions than we can with LDM.
5548 ; This pattern will only match if the one above did not.
5549 (define_split
5550   [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
5551         (match_operand:ANY64 1 "const_double_operand" ""))]
5552   "TARGET_ARM && reload_completed
5553    && arm_const_double_by_parts (operands[1])"
5554   [(set (match_dup 0) (match_dup 1))
5555    (set (match_dup 2) (match_dup 3))]
5556   "
5557   operands[2] = gen_highpart (SImode, operands[0]);
5558   operands[3] = gen_highpart_mode (SImode, GET_MODE (operands[0]),
5559                                    operands[1]);
5560   operands[0] = gen_lowpart (SImode, operands[0]);
5561   operands[1] = gen_lowpart (SImode, operands[1]);
5562   "
5565 (define_split
5566   [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
5567         (match_operand:ANY64 1 "arm_general_register_operand" ""))]
5568   "TARGET_EITHER && reload_completed"
5569   [(set (match_dup 0) (match_dup 1))
5570    (set (match_dup 2) (match_dup 3))]
5571   "
5572   operands[2] = gen_highpart (SImode, operands[0]);
5573   operands[3] = gen_highpart (SImode, operands[1]);
5574   operands[0] = gen_lowpart (SImode, operands[0]);
5575   operands[1] = gen_lowpart (SImode, operands[1]);
5577   /* Handle a partial overlap.  */
5578   if (rtx_equal_p (operands[0], operands[3]))
5579     {
5580       rtx tmp0 = operands[0];
5581       rtx tmp1 = operands[1];
5583       operands[0] = operands[2];
5584       operands[1] = operands[3];
5585       operands[2] = tmp0;
5586       operands[3] = tmp1;
5587     }
5588   "
5591 ;; We can't actually do base+index doubleword loads if the index and
5592 ;; destination overlap.  Split here so that we at least have chance to
5593 ;; schedule.
5594 (define_split
5595   [(set (match_operand:DI 0 "s_register_operand" "")
5596         (mem:DI (plus:SI (match_operand:SI 1 "s_register_operand" "")
5597                          (match_operand:SI 2 "s_register_operand" ""))))]
5598   "TARGET_LDRD
5599   && reg_overlap_mentioned_p (operands[0], operands[1])
5600   && reg_overlap_mentioned_p (operands[0], operands[2])"
5601   [(set (match_dup 4)
5602         (plus:SI (match_dup 1)
5603                  (match_dup 2)))
5604    (set (match_dup 0)
5605         (mem:DI (match_dup 4)))]
5606   "
5607   operands[4] = gen_rtx_REG (SImode, REGNO(operands[0]));
5608   "
5611 (define_expand "movsi"
5612   [(set (match_operand:SI 0 "general_operand" "")
5613         (match_operand:SI 1 "general_operand" ""))]
5614   "TARGET_EITHER"
5615   "
5616   {
5617   rtx base, offset, tmp;
5619   if (TARGET_32BIT)
5620     {
5621       /* Everything except mem = const or mem = mem can be done easily.  */
5622       if (MEM_P (operands[0]))
5623         operands[1] = force_reg (SImode, operands[1]);
5624       if (arm_general_register_operand (operands[0], SImode)
5625           && CONST_INT_P (operands[1])
5626           && !(const_ok_for_arm (INTVAL (operands[1]))
5627                || const_ok_for_arm (~INTVAL (operands[1]))))
5628         {
5629            if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[1]), SET))
5630              {
5631                 emit_insn (gen_rtx_SET (operands[0], operands[1]));
5632                 DONE;
5633              }
5634           else
5635              {
5636                 arm_split_constant (SET, SImode, NULL_RTX,
5637                                     INTVAL (operands[1]), operands[0], NULL_RTX,
5638                                     optimize && can_create_pseudo_p ());
5639                 DONE;
5640              }
5641         }
5642     }
5643   else /* TARGET_THUMB1...  */
5644     {
5645       if (can_create_pseudo_p ())
5646         {
5647           if (!REG_P (operands[0]))
5648             operands[1] = force_reg (SImode, operands[1]);
5649         }
5650     }
5652   if (ARM_OFFSETS_MUST_BE_WITHIN_SECTIONS_P)
5653     {
5654       split_const (operands[1], &base, &offset);
5655       if (GET_CODE (base) == SYMBOL_REF
5656           && !offset_within_block_p (base, INTVAL (offset)))
5657         {
5658           tmp = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];
5659           emit_move_insn (tmp, base);
5660           emit_insn (gen_addsi3 (operands[0], tmp, offset));
5661           DONE;
5662         }
5663     }
5665   /* Recognize the case where operand[1] is a reference to thread-local
5666      data and load its address to a register.  */
5667   if (arm_tls_referenced_p (operands[1]))
5668     {
5669       rtx tmp = operands[1];
5670       rtx addend = NULL;
5672       if (GET_CODE (tmp) == CONST && GET_CODE (XEXP (tmp, 0)) == PLUS)
5673         {
5674           addend = XEXP (XEXP (tmp, 0), 1);
5675           tmp = XEXP (XEXP (tmp, 0), 0);
5676         }
5678       gcc_assert (GET_CODE (tmp) == SYMBOL_REF);
5679       gcc_assert (SYMBOL_REF_TLS_MODEL (tmp) != 0);
5681       tmp = legitimize_tls_address (tmp,
5682                                     !can_create_pseudo_p () ? operands[0] : 0);
5683       if (addend)
5684         {
5685           tmp = gen_rtx_PLUS (SImode, tmp, addend);
5686           tmp = force_operand (tmp, operands[0]);
5687         }
5688       operands[1] = tmp;
5689     }
5690   else if (flag_pic
5691            && (CONSTANT_P (operands[1])
5692                || symbol_mentioned_p (operands[1])
5693                || label_mentioned_p (operands[1])))
5694       operands[1] = legitimize_pic_address (operands[1], SImode,
5695                                             (!can_create_pseudo_p ()
5696                                              ? operands[0]
5697                                              : 0));
5698   }
5699   "
5702 ;; The ARM LO_SUM and HIGH are backwards - HIGH sets the low bits, and
5703 ;; LO_SUM adds in the high bits.  Fortunately these are opaque operations
5704 ;; so this does not matter.
5705 (define_insn "*arm_movt"
5706   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r")
5707         (lo_sum:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
5708                    (match_operand:SI 2 "general_operand"      "i,i")))]
5709   "TARGET_HAVE_MOVT && arm_valid_symbolic_address_p (operands[2])"
5710   "@
5711    movt%?\t%0, #:upper16:%c2
5712    movt\t%0, #:upper16:%c2"
5713   [(set_attr "arch"  "32,v8mb")
5714    (set_attr "predicable" "yes")
5715    (set_attr "predicable_short_it" "no")
5716    (set_attr "length" "4")
5717    (set_attr "type" "alu_sreg")]
5720 (define_insn "*arm_movsi_insn"
5721   [(set (match_operand:SI 0 "nonimmediate_operand" "=rk,r,r,r,rk,m")
5722         (match_operand:SI 1 "general_operand"      "rk, I,K,j,mi,rk"))]
5723   "TARGET_ARM && ! TARGET_IWMMXT
5724    && !(TARGET_HARD_FLOAT && TARGET_VFP)
5725    && (   register_operand (operands[0], SImode)
5726        || register_operand (operands[1], SImode))"
5727   "@
5728    mov%?\\t%0, %1
5729    mov%?\\t%0, %1
5730    mvn%?\\t%0, #%B1
5731    movw%?\\t%0, %1
5732    ldr%?\\t%0, %1
5733    str%?\\t%1, %0"
5734   [(set_attr "type" "mov_reg,mov_imm,mvn_imm,mov_imm,load1,store1")
5735    (set_attr "predicable" "yes")
5736    (set_attr "pool_range" "*,*,*,*,4096,*")
5737    (set_attr "neg_pool_range" "*,*,*,*,4084,*")]
5740 (define_split
5741   [(set (match_operand:SI 0 "arm_general_register_operand" "")
5742         (match_operand:SI 1 "const_int_operand" ""))]
5743   "TARGET_32BIT
5744   && (!(const_ok_for_arm (INTVAL (operands[1]))
5745         || const_ok_for_arm (~INTVAL (operands[1]))))"
5746   [(clobber (const_int 0))]
5747   "
5748   arm_split_constant (SET, SImode, NULL_RTX, 
5749                       INTVAL (operands[1]), operands[0], NULL_RTX, 0);
5750   DONE;
5751   "
5754 ;; A normal way to do (symbol + offset) requires three instructions at least
5755 ;; (depends on how big the offset is) as below:
5756 ;; movw r0, #:lower16:g
5757 ;; movw r0, #:upper16:g
5758 ;; adds r0, #4
5760 ;; A better way would be:
5761 ;; movw r0, #:lower16:g+4
5762 ;; movw r0, #:upper16:g+4
5764 ;; The limitation of this way is that the length of offset should be a 16-bit
5765 ;; signed value, because current assembler only supports REL type relocation for
5766 ;; such case.  If the more powerful RELA type is supported in future, we should
5767 ;; update this pattern to go with better way.
5768 (define_split
5769   [(set (match_operand:SI 0 "arm_general_register_operand" "")
5770         (const:SI (plus:SI (match_operand:SI 1 "general_operand" "")
5771                            (match_operand:SI 2 "const_int_operand" ""))))]
5772   "TARGET_THUMB
5773    && TARGET_HAVE_MOVT
5774    && arm_disable_literal_pool
5775    && reload_completed
5776    && GET_CODE (operands[1]) == SYMBOL_REF"
5777   [(clobber (const_int 0))]
5778   "
5779     int offset = INTVAL (operands[2]);
5781     if (offset < -0x8000 || offset > 0x7fff)
5782       {
5783         arm_emit_movpair (operands[0], operands[1]);
5784         emit_insn (gen_rtx_SET (operands[0],
5785                                 gen_rtx_PLUS (SImode, operands[0], operands[2])));
5786       }
5787     else
5788       {
5789         rtx op = gen_rtx_CONST (SImode,
5790                                 gen_rtx_PLUS (SImode, operands[1], operands[2]));
5791         arm_emit_movpair (operands[0], op);
5792       }
5793   "
5796 ;; Split symbol_refs at the later stage (after cprop), instead of generating
5797 ;; movt/movw pair directly at expand.  Otherwise corresponding high_sum
5798 ;; and lo_sum would be merged back into memory load at cprop.  However,
5799 ;; if the default is to prefer movt/movw rather than a load from the constant
5800 ;; pool, the performance is better.
5801 (define_split
5802   [(set (match_operand:SI 0 "arm_general_register_operand" "")
5803        (match_operand:SI 1 "general_operand" ""))]
5804   "TARGET_USE_MOVT && GET_CODE (operands[1]) == SYMBOL_REF
5805    && !flag_pic && !target_word_relocations
5806    && !arm_tls_referenced_p (operands[1])"
5807   [(clobber (const_int 0))]
5809   arm_emit_movpair (operands[0], operands[1]);
5810   DONE;
5813 ;; When generating pic, we need to load the symbol offset into a register.
5814 ;; So that the optimizer does not confuse this with a normal symbol load
5815 ;; we use an unspec.  The offset will be loaded from a constant pool entry,
5816 ;; since that is the only type of relocation we can use.
5818 ;; Wrap calculation of the whole PIC address in a single pattern for the
5819 ;; benefit of optimizers, particularly, PRE and HOIST.  Calculation of
5820 ;; a PIC address involves two loads from memory, so we want to CSE it
5821 ;; as often as possible.
5822 ;; This pattern will be split into one of the pic_load_addr_* patterns
5823 ;; and a move after GCSE optimizations.
5825 ;; Note: Update arm.c: legitimize_pic_address() when changing this pattern.
5826 (define_expand "calculate_pic_address"
5827   [(set (match_operand:SI 0 "register_operand" "")
5828         (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "")
5829                          (unspec:SI [(match_operand:SI 2 "" "")]
5830                                     UNSPEC_PIC_SYM))))]
5831   "flag_pic"
5834 ;; Split calculate_pic_address into pic_load_addr_* and a move.
5835 (define_split
5836   [(set (match_operand:SI 0 "register_operand" "")
5837         (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "")
5838                          (unspec:SI [(match_operand:SI 2 "" "")]
5839                                     UNSPEC_PIC_SYM))))]
5840   "flag_pic"
5841   [(set (match_dup 3) (unspec:SI [(match_dup 2)] UNSPEC_PIC_SYM))
5842    (set (match_dup 0) (mem:SI (plus:SI (match_dup 1) (match_dup 3))))]
5843   "operands[3] = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];"
5846 ;; operand1 is the memory address to go into 
5847 ;; pic_load_addr_32bit.
5848 ;; operand2 is the PIC label to be emitted 
5849 ;; from pic_add_dot_plus_eight.
5850 ;; We do this to allow hoisting of the entire insn.
5851 (define_insn_and_split "pic_load_addr_unified"
5852   [(set (match_operand:SI 0 "s_register_operand" "=r,r,l")
5853         (unspec:SI [(match_operand:SI 1 "" "mX,mX,mX") 
5854                     (match_operand:SI 2 "" "")] 
5855                     UNSPEC_PIC_UNIFIED))]
5856  "flag_pic"
5857  "#"
5858  "&& reload_completed"
5859  [(set (match_dup 0) (unspec:SI [(match_dup 1)] UNSPEC_PIC_SYM))
5860   (set (match_dup 0) (unspec:SI [(match_dup 0) (match_dup 3)
5861                                  (match_dup 2)] UNSPEC_PIC_BASE))]
5862  "operands[3] = TARGET_THUMB ? GEN_INT (4) : GEN_INT (8);"
5863  [(set_attr "type" "load1,load1,load1")
5864   (set_attr "pool_range" "4096,4094,1022")
5865   (set_attr "neg_pool_range" "4084,0,0")
5866   (set_attr "arch"  "a,t2,t1")    
5867   (set_attr "length" "8,6,4")]
5870 ;; The rather odd constraints on the following are to force reload to leave
5871 ;; the insn alone, and to force the minipool generation pass to then move
5872 ;; the GOT symbol to memory.
5874 (define_insn "pic_load_addr_32bit"
5875   [(set (match_operand:SI 0 "s_register_operand" "=r")
5876         (unspec:SI [(match_operand:SI 1 "" "mX")] UNSPEC_PIC_SYM))]
5877   "TARGET_32BIT && flag_pic"
5878   "ldr%?\\t%0, %1"
5879   [(set_attr "type" "load1")
5880    (set (attr "pool_range")
5881         (if_then_else (eq_attr "is_thumb" "no")
5882                       (const_int 4096)
5883                       (const_int 4094)))
5884    (set (attr "neg_pool_range")
5885         (if_then_else (eq_attr "is_thumb" "no")
5886                       (const_int 4084)
5887                       (const_int 0)))]
5890 (define_insn "pic_load_addr_thumb1"
5891   [(set (match_operand:SI 0 "s_register_operand" "=l")
5892         (unspec:SI [(match_operand:SI 1 "" "mX")] UNSPEC_PIC_SYM))]
5893   "TARGET_THUMB1 && flag_pic"
5894   "ldr\\t%0, %1"
5895   [(set_attr "type" "load1")
5896    (set (attr "pool_range") (const_int 1018))]
5899 (define_insn "pic_add_dot_plus_four"
5900   [(set (match_operand:SI 0 "register_operand" "=r")
5901         (unspec:SI [(match_operand:SI 1 "register_operand" "0")
5902                     (const_int 4)
5903                     (match_operand 2 "" "")]
5904                    UNSPEC_PIC_BASE))]
5905   "TARGET_THUMB"
5906   "*
5907   (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
5908                                      INTVAL (operands[2]));
5909   return \"add\\t%0, %|pc\";
5910   "
5911   [(set_attr "length" "2")
5912    (set_attr "type" "alu_sreg")]
5915 (define_insn "pic_add_dot_plus_eight"
5916   [(set (match_operand:SI 0 "register_operand" "=r")
5917         (unspec:SI [(match_operand:SI 1 "register_operand" "r")
5918                     (const_int 8)
5919                     (match_operand 2 "" "")]
5920                    UNSPEC_PIC_BASE))]
5921   "TARGET_ARM"
5922   "*
5923     (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
5924                                        INTVAL (operands[2]));
5925     return \"add%?\\t%0, %|pc, %1\";
5926   "
5927   [(set_attr "predicable" "yes")
5928    (set_attr "type" "alu_sreg")]
5931 (define_insn "tls_load_dot_plus_eight"
5932   [(set (match_operand:SI 0 "register_operand" "=r")
5933         (mem:SI (unspec:SI [(match_operand:SI 1 "register_operand" "r")
5934                             (const_int 8)
5935                             (match_operand 2 "" "")]
5936                            UNSPEC_PIC_BASE)))]
5937   "TARGET_ARM"
5938   "*
5939     (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
5940                                        INTVAL (operands[2]));
5941     return \"ldr%?\\t%0, [%|pc, %1]\t\t@ tls_load_dot_plus_eight\";
5942   "
5943   [(set_attr "predicable" "yes")
5944    (set_attr "type" "load1")]
5947 ;; PIC references to local variables can generate pic_add_dot_plus_eight
5948 ;; followed by a load.  These sequences can be crunched down to
5949 ;; tls_load_dot_plus_eight by a peephole.
5951 (define_peephole2
5952   [(set (match_operand:SI 0 "register_operand" "")
5953         (unspec:SI [(match_operand:SI 3 "register_operand" "")
5954                     (const_int 8)
5955                     (match_operand 1 "" "")]
5956                    UNSPEC_PIC_BASE))
5957    (set (match_operand:SI 2 "arm_general_register_operand" "")
5958         (mem:SI (match_dup 0)))]
5959   "TARGET_ARM && peep2_reg_dead_p (2, operands[0])"
5960   [(set (match_dup 2)
5961         (mem:SI (unspec:SI [(match_dup 3)
5962                             (const_int 8)
5963                             (match_dup 1)]
5964                            UNSPEC_PIC_BASE)))]
5965   ""
5968 (define_insn "pic_offset_arm"
5969   [(set (match_operand:SI 0 "register_operand" "=r")
5970         (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
5971                          (unspec:SI [(match_operand:SI 2 "" "X")]
5972                                     UNSPEC_PIC_OFFSET))))]
5973   "TARGET_VXWORKS_RTP && TARGET_ARM && flag_pic"
5974   "ldr%?\\t%0, [%1,%2]"
5975   [(set_attr "type" "load1")]
5978 (define_expand "builtin_setjmp_receiver"
5979   [(label_ref (match_operand 0 "" ""))]
5980   "flag_pic"
5981   "
5983   /* r3 is clobbered by set/longjmp, so we can use it as a scratch
5984      register.  */
5985   if (arm_pic_register != INVALID_REGNUM)
5986     arm_load_pic_register (1UL << 3);
5987   DONE;
5990 ;; If copying one reg to another we can set the condition codes according to
5991 ;; its value.  Such a move is common after a return from subroutine and the
5992 ;; result is being tested against zero.
5994 (define_insn "*movsi_compare0"
5995   [(set (reg:CC CC_REGNUM)
5996         (compare:CC (match_operand:SI 1 "s_register_operand" "0,r")
5997                     (const_int 0)))
5998    (set (match_operand:SI 0 "s_register_operand" "=r,r")
5999         (match_dup 1))]
6000   "TARGET_32BIT"
6001   "@
6002    cmp%?\\t%0, #0
6003    subs%?\\t%0, %1, #0"
6004   [(set_attr "conds" "set")
6005    (set_attr "type" "alus_imm,alus_imm")]
6008 ;; Subroutine to store a half word from a register into memory.
6009 ;; Operand 0 is the source register (HImode)
6010 ;; Operand 1 is the destination address in a register (SImode)
6012 ;; In both this routine and the next, we must be careful not to spill
6013 ;; a memory address of reg+large_const into a separate PLUS insn, since this
6014 ;; can generate unrecognizable rtl.
6016 (define_expand "storehi"
6017   [;; store the low byte
6018    (set (match_operand 1 "" "") (match_dup 3))
6019    ;; extract the high byte
6020    (set (match_dup 2)
6021         (ashiftrt:SI (match_operand 0 "" "") (const_int 8)))
6022    ;; store the high byte
6023    (set (match_dup 4) (match_dup 5))]
6024   "TARGET_ARM"
6025   "
6026   {
6027     rtx op1 = operands[1];
6028     rtx addr = XEXP (op1, 0);
6029     enum rtx_code code = GET_CODE (addr);
6031     if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1)))
6032         || code == MINUS)
6033       op1 = replace_equiv_address (operands[1], force_reg (SImode, addr));
6035     operands[4] = adjust_address (op1, QImode, 1);
6036     operands[1] = adjust_address (operands[1], QImode, 0);
6037     operands[3] = gen_lowpart (QImode, operands[0]);
6038     operands[0] = gen_lowpart (SImode, operands[0]);
6039     operands[2] = gen_reg_rtx (SImode);
6040     operands[5] = gen_lowpart (QImode, operands[2]);
6041   }"
6044 (define_expand "storehi_bigend"
6045   [(set (match_dup 4) (match_dup 3))
6046    (set (match_dup 2)
6047         (ashiftrt:SI (match_operand 0 "" "") (const_int 8)))
6048    (set (match_operand 1 "" "") (match_dup 5))]
6049   "TARGET_ARM"
6050   "
6051   {
6052     rtx op1 = operands[1];
6053     rtx addr = XEXP (op1, 0);
6054     enum rtx_code code = GET_CODE (addr);
6056     if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1)))
6057         || code == MINUS)
6058       op1 = replace_equiv_address (op1, force_reg (SImode, addr));
6060     operands[4] = adjust_address (op1, QImode, 1);
6061     operands[1] = adjust_address (operands[1], QImode, 0);
6062     operands[3] = gen_lowpart (QImode, operands[0]);
6063     operands[0] = gen_lowpart (SImode, operands[0]);
6064     operands[2] = gen_reg_rtx (SImode);
6065     operands[5] = gen_lowpart (QImode, operands[2]);
6066   }"
6069 ;; Subroutine to store a half word integer constant into memory.
6070 (define_expand "storeinthi"
6071   [(set (match_operand 0 "" "")
6072         (match_operand 1 "" ""))
6073    (set (match_dup 3) (match_dup 2))]
6074   "TARGET_ARM"
6075   "
6076   {
6077     HOST_WIDE_INT value = INTVAL (operands[1]);
6078     rtx addr = XEXP (operands[0], 0);
6079     rtx op0 = operands[0];
6080     enum rtx_code code = GET_CODE (addr);
6082     if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1)))
6083         || code == MINUS)
6084       op0 = replace_equiv_address (op0, force_reg (SImode, addr));
6086     operands[1] = gen_reg_rtx (SImode);
6087     if (BYTES_BIG_ENDIAN)
6088       {
6089         emit_insn (gen_movsi (operands[1], GEN_INT ((value >> 8) & 255)));
6090         if ((value & 255) == ((value >> 8) & 255))
6091           operands[2] = operands[1];
6092         else
6093           {
6094             operands[2] = gen_reg_rtx (SImode);
6095             emit_insn (gen_movsi (operands[2], GEN_INT (value & 255)));
6096           }
6097       }
6098     else
6099       {
6100         emit_insn (gen_movsi (operands[1], GEN_INT (value & 255)));
6101         if ((value & 255) == ((value >> 8) & 255))
6102           operands[2] = operands[1];
6103         else
6104           {
6105             operands[2] = gen_reg_rtx (SImode);
6106             emit_insn (gen_movsi (operands[2], GEN_INT ((value >> 8) & 255)));
6107           }
6108       }
6110     operands[3] = adjust_address (op0, QImode, 1);
6111     operands[0] = adjust_address (operands[0], QImode, 0);
6112     operands[2] = gen_lowpart (QImode, operands[2]);
6113     operands[1] = gen_lowpart (QImode, operands[1]);
6114   }"
6117 (define_expand "storehi_single_op"
6118   [(set (match_operand:HI 0 "memory_operand" "")
6119         (match_operand:HI 1 "general_operand" ""))]
6120   "TARGET_32BIT && arm_arch4"
6121   "
6122   if (!s_register_operand (operands[1], HImode))
6123     operands[1] = copy_to_mode_reg (HImode, operands[1]);
6124   "
6127 (define_expand "movhi"
6128   [(set (match_operand:HI 0 "general_operand" "")
6129         (match_operand:HI 1 "general_operand" ""))]
6130   "TARGET_EITHER"
6131   "
6132   if (TARGET_ARM)
6133     {
6134       if (can_create_pseudo_p ())
6135         {
6136           if (MEM_P (operands[0]))
6137             {
6138               if (arm_arch4)
6139                 {
6140                   emit_insn (gen_storehi_single_op (operands[0], operands[1]));
6141                   DONE;
6142                 }
6143               if (CONST_INT_P (operands[1]))
6144                 emit_insn (gen_storeinthi (operands[0], operands[1]));
6145               else
6146                 {
6147                   if (MEM_P (operands[1]))
6148                     operands[1] = force_reg (HImode, operands[1]);
6149                   if (BYTES_BIG_ENDIAN)
6150                     emit_insn (gen_storehi_bigend (operands[1], operands[0]));
6151                   else
6152                    emit_insn (gen_storehi (operands[1], operands[0]));
6153                 }
6154               DONE;
6155             }
6156           /* Sign extend a constant, and keep it in an SImode reg.  */
6157           else if (CONST_INT_P (operands[1]))
6158             {
6159               rtx reg = gen_reg_rtx (SImode);
6160               HOST_WIDE_INT val = INTVAL (operands[1]) & 0xffff;
6162               /* If the constant is already valid, leave it alone.  */
6163               if (!const_ok_for_arm (val))
6164                 {
6165                   /* If setting all the top bits will make the constant 
6166                      loadable in a single instruction, then set them.  
6167                      Otherwise, sign extend the number.  */
6169                   if (const_ok_for_arm (~(val | ~0xffff)))
6170                     val |= ~0xffff;
6171                   else if (val & 0x8000)
6172                     val |= ~0xffff;
6173                 }
6175               emit_insn (gen_movsi (reg, GEN_INT (val)));
6176               operands[1] = gen_lowpart (HImode, reg);
6177             }
6178           else if (arm_arch4 && optimize && can_create_pseudo_p ()
6179                    && MEM_P (operands[1]))
6180             {
6181               rtx reg = gen_reg_rtx (SImode);
6183               emit_insn (gen_zero_extendhisi2 (reg, operands[1]));
6184               operands[1] = gen_lowpart (HImode, reg);
6185             }
6186           else if (!arm_arch4)
6187             {
6188               if (MEM_P (operands[1]))
6189                 {
6190                   rtx base;
6191                   rtx offset = const0_rtx;
6192                   rtx reg = gen_reg_rtx (SImode);
6194                   if ((REG_P (base = XEXP (operands[1], 0))
6195                        || (GET_CODE (base) == PLUS
6196                            && (CONST_INT_P (offset = XEXP (base, 1)))
6197                            && ((INTVAL(offset) & 1) != 1)
6198                            && REG_P (base = XEXP (base, 0))))
6199                       && REGNO_POINTER_ALIGN (REGNO (base)) >= 32)
6200                     {
6201                       rtx new_rtx;
6203                       new_rtx = widen_memory_access (operands[1], SImode,
6204                                                      ((INTVAL (offset) & ~3)
6205                                                       - INTVAL (offset)));
6206                       emit_insn (gen_movsi (reg, new_rtx));
6207                       if (((INTVAL (offset) & 2) != 0)
6208                           ^ (BYTES_BIG_ENDIAN ? 1 : 0))
6209                         {
6210                           rtx reg2 = gen_reg_rtx (SImode);
6212                           emit_insn (gen_lshrsi3 (reg2, reg, GEN_INT (16)));
6213                           reg = reg2;
6214                         }
6215                     }
6216                   else
6217                     emit_insn (gen_movhi_bytes (reg, operands[1]));
6219                   operands[1] = gen_lowpart (HImode, reg);
6220                }
6221            }
6222         }
6223       /* Handle loading a large integer during reload.  */
6224       else if (CONST_INT_P (operands[1])
6225                && !const_ok_for_arm (INTVAL (operands[1]))
6226                && !const_ok_for_arm (~INTVAL (operands[1])))
6227         {
6228           /* Writing a constant to memory needs a scratch, which should
6229              be handled with SECONDARY_RELOADs.  */
6230           gcc_assert (REG_P (operands[0]));
6232           operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
6233           emit_insn (gen_movsi (operands[0], operands[1]));
6234           DONE;
6235        }
6236     }
6237   else if (TARGET_THUMB2)
6238     {
6239       /* Thumb-2 can do everything except mem=mem and mem=const easily.  */
6240       if (can_create_pseudo_p ())
6241         {
6242           if (!REG_P (operands[0]))
6243             operands[1] = force_reg (HImode, operands[1]);
6244           /* Zero extend a constant, and keep it in an SImode reg.  */
6245           else if (CONST_INT_P (operands[1]))
6246             {
6247               rtx reg = gen_reg_rtx (SImode);
6248               HOST_WIDE_INT val = INTVAL (operands[1]) & 0xffff;
6250               emit_insn (gen_movsi (reg, GEN_INT (val)));
6251               operands[1] = gen_lowpart (HImode, reg);
6252             }
6253         }
6254     }
6255   else /* TARGET_THUMB1 */
6256     {
6257       if (can_create_pseudo_p ())
6258         {
6259           if (CONST_INT_P (operands[1]))
6260             {
6261               rtx reg = gen_reg_rtx (SImode);
6263               emit_insn (gen_movsi (reg, operands[1]));
6264               operands[1] = gen_lowpart (HImode, reg);
6265             }
6267           /* ??? We shouldn't really get invalid addresses here, but this can
6268              happen if we are passed a SP (never OK for HImode/QImode) or 
6269              virtual register (also rejected as illegitimate for HImode/QImode)
6270              relative address.  */
6271           /* ??? This should perhaps be fixed elsewhere, for instance, in
6272              fixup_stack_1, by checking for other kinds of invalid addresses,
6273              e.g. a bare reference to a virtual register.  This may confuse the
6274              alpha though, which must handle this case differently.  */
6275           if (MEM_P (operands[0])
6276               && !memory_address_p (GET_MODE (operands[0]),
6277                                     XEXP (operands[0], 0)))
6278             operands[0]
6279               = replace_equiv_address (operands[0],
6280                                        copy_to_reg (XEXP (operands[0], 0)));
6281    
6282           if (MEM_P (operands[1])
6283               && !memory_address_p (GET_MODE (operands[1]),
6284                                     XEXP (operands[1], 0)))
6285             operands[1]
6286               = replace_equiv_address (operands[1],
6287                                        copy_to_reg (XEXP (operands[1], 0)));
6289           if (MEM_P (operands[1]) && optimize > 0)
6290             {
6291               rtx reg = gen_reg_rtx (SImode);
6293               emit_insn (gen_zero_extendhisi2 (reg, operands[1]));
6294               operands[1] = gen_lowpart (HImode, reg);
6295             }
6297           if (MEM_P (operands[0]))
6298             operands[1] = force_reg (HImode, operands[1]);
6299         }
6300       else if (CONST_INT_P (operands[1])
6301                 && !satisfies_constraint_I (operands[1]))
6302         {
6303           /* Handle loading a large integer during reload.  */
6305           /* Writing a constant to memory needs a scratch, which should
6306              be handled with SECONDARY_RELOADs.  */
6307           gcc_assert (REG_P (operands[0]));
6309           operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
6310           emit_insn (gen_movsi (operands[0], operands[1]));
6311           DONE;
6312         }
6313     }
6314   "
6317 (define_expand "movhi_bytes"
6318   [(set (match_dup 2) (zero_extend:SI (match_operand:HI 1 "" "")))
6319    (set (match_dup 3)
6320         (zero_extend:SI (match_dup 6)))
6321    (set (match_operand:SI 0 "" "")
6322          (ior:SI (ashift:SI (match_dup 4) (const_int 8)) (match_dup 5)))]
6323   "TARGET_ARM"
6324   "
6325   {
6326     rtx mem1, mem2;
6327     rtx addr = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
6329     mem1 = change_address (operands[1], QImode, addr);
6330     mem2 = change_address (operands[1], QImode,
6331                            plus_constant (Pmode, addr, 1));
6332     operands[0] = gen_lowpart (SImode, operands[0]);
6333     operands[1] = mem1;
6334     operands[2] = gen_reg_rtx (SImode);
6335     operands[3] = gen_reg_rtx (SImode);
6336     operands[6] = mem2;
6338     if (BYTES_BIG_ENDIAN)
6339       {
6340         operands[4] = operands[2];
6341         operands[5] = operands[3];
6342       }
6343     else
6344       {
6345         operands[4] = operands[3];
6346         operands[5] = operands[2];
6347       }
6348   }"
6351 (define_expand "movhi_bigend"
6352   [(set (match_dup 2)
6353         (rotate:SI (subreg:SI (match_operand:HI 1 "memory_operand" "") 0)
6354                    (const_int 16)))
6355    (set (match_dup 3)
6356         (ashiftrt:SI (match_dup 2) (const_int 16)))
6357    (set (match_operand:HI 0 "s_register_operand" "")
6358         (match_dup 4))]
6359   "TARGET_ARM"
6360   "
6361   operands[2] = gen_reg_rtx (SImode);
6362   operands[3] = gen_reg_rtx (SImode);
6363   operands[4] = gen_lowpart (HImode, operands[3]);
6364   "
6367 ;; Pattern to recognize insn generated default case above
6368 (define_insn "*movhi_insn_arch4"
6369   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m,r")
6370         (match_operand:HI 1 "general_operand"      "rIk,K,n,r,mi"))]
6371   "TARGET_ARM
6372    && arm_arch4
6373    && (register_operand (operands[0], HImode)
6374        || register_operand (operands[1], HImode))"
6375   "@
6376    mov%?\\t%0, %1\\t%@ movhi
6377    mvn%?\\t%0, #%B1\\t%@ movhi
6378    movw%?\\t%0, %L1\\t%@ movhi
6379    strh%?\\t%1, %0\\t%@ movhi
6380    ldrh%?\\t%0, %1\\t%@ movhi"
6381   [(set_attr "predicable" "yes")
6382    (set_attr "pool_range" "*,*,*,*,256")
6383    (set_attr "neg_pool_range" "*,*,*,*,244")
6384    (set_attr "arch" "*,*,v6t2,*,*")
6385    (set_attr_alternative "type"
6386                          [(if_then_else (match_operand 1 "const_int_operand" "")
6387                                         (const_string "mov_imm" )
6388                                         (const_string "mov_reg"))
6389                           (const_string "mvn_imm")
6390                           (const_string "mov_imm")
6391                           (const_string "store1")
6392                           (const_string "load1")])]
6395 (define_insn "*movhi_bytes"
6396   [(set (match_operand:HI 0 "s_register_operand" "=r,r,r")
6397         (match_operand:HI 1 "arm_rhs_operand"  "I,rk,K"))]
6398   "TARGET_ARM"
6399   "@
6400    mov%?\\t%0, %1\\t%@ movhi
6401    mov%?\\t%0, %1\\t%@ movhi
6402    mvn%?\\t%0, #%B1\\t%@ movhi"
6403   [(set_attr "predicable" "yes")
6404    (set_attr "type" "mov_imm,mov_reg,mvn_imm")]
6406         
6407 ;; We use a DImode scratch because we may occasionally need an additional
6408 ;; temporary if the address isn't offsettable -- push_reload doesn't seem
6409 ;; to take any notice of the "o" constraints on reload_memory_operand operand.
6410 (define_expand "reload_outhi"
6411   [(parallel [(match_operand:HI 0 "arm_reload_memory_operand" "=o")
6412               (match_operand:HI 1 "s_register_operand"        "r")
6413               (match_operand:DI 2 "s_register_operand"        "=&l")])]
6414   "TARGET_EITHER"
6415   "if (TARGET_ARM)
6416      arm_reload_out_hi (operands);
6417    else
6418      thumb_reload_out_hi (operands);
6419   DONE;
6420   "
6423 (define_expand "reload_inhi"
6424   [(parallel [(match_operand:HI 0 "s_register_operand" "=r")
6425               (match_operand:HI 1 "arm_reload_memory_operand" "o")
6426               (match_operand:DI 2 "s_register_operand" "=&r")])]
6427   "TARGET_EITHER"
6428   "
6429   if (TARGET_ARM)
6430     arm_reload_in_hi (operands);
6431   else
6432     thumb_reload_out_hi (operands);
6433   DONE;
6436 (define_expand "movqi"
6437   [(set (match_operand:QI 0 "general_operand" "")
6438         (match_operand:QI 1 "general_operand" ""))]
6439   "TARGET_EITHER"
6440   "
6441   /* Everything except mem = const or mem = mem can be done easily */
6443   if (can_create_pseudo_p ())
6444     {
6445       if (CONST_INT_P (operands[1]))
6446         {
6447           rtx reg = gen_reg_rtx (SImode);
6449           /* For thumb we want an unsigned immediate, then we are more likely 
6450              to be able to use a movs insn.  */
6451           if (TARGET_THUMB)
6452             operands[1] = GEN_INT (INTVAL (operands[1]) & 255);
6454           emit_insn (gen_movsi (reg, operands[1]));
6455           operands[1] = gen_lowpart (QImode, reg);
6456         }
6458       if (TARGET_THUMB)
6459         {
6460           /* ??? We shouldn't really get invalid addresses here, but this can
6461              happen if we are passed a SP (never OK for HImode/QImode) or
6462              virtual register (also rejected as illegitimate for HImode/QImode)
6463              relative address.  */
6464           /* ??? This should perhaps be fixed elsewhere, for instance, in
6465              fixup_stack_1, by checking for other kinds of invalid addresses,
6466              e.g. a bare reference to a virtual register.  This may confuse the
6467              alpha though, which must handle this case differently.  */
6468           if (MEM_P (operands[0])
6469               && !memory_address_p (GET_MODE (operands[0]),
6470                                      XEXP (operands[0], 0)))
6471             operands[0]
6472               = replace_equiv_address (operands[0],
6473                                        copy_to_reg (XEXP (operands[0], 0)));
6474           if (MEM_P (operands[1])
6475               && !memory_address_p (GET_MODE (operands[1]),
6476                                     XEXP (operands[1], 0)))
6477              operands[1]
6478                = replace_equiv_address (operands[1],
6479                                         copy_to_reg (XEXP (operands[1], 0)));
6480         }
6482       if (MEM_P (operands[1]) && optimize > 0)
6483         {
6484           rtx reg = gen_reg_rtx (SImode);
6486           emit_insn (gen_zero_extendqisi2 (reg, operands[1]));
6487           operands[1] = gen_lowpart (QImode, reg);
6488         }
6490       if (MEM_P (operands[0]))
6491         operands[1] = force_reg (QImode, operands[1]);
6492     }
6493   else if (TARGET_THUMB
6494            && CONST_INT_P (operands[1])
6495            && !satisfies_constraint_I (operands[1]))
6496     {
6497       /* Handle loading a large integer during reload.  */
6499       /* Writing a constant to memory needs a scratch, which should
6500          be handled with SECONDARY_RELOADs.  */
6501       gcc_assert (REG_P (operands[0]));
6503       operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
6504       emit_insn (gen_movsi (operands[0], operands[1]));
6505       DONE;
6506     }
6507   "
6510 (define_insn "*arm_movqi_insn"
6511   [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,r,l,r,l,Uu,r,m")
6512         (match_operand:QI 1 "general_operand" "rk,rk,I,Py,K,Uu,l,Uh,r"))]
6513   "TARGET_32BIT
6514    && (   register_operand (operands[0], QImode)
6515        || register_operand (operands[1], QImode))"
6516   "@
6517    mov%?\\t%0, %1
6518    mov%?\\t%0, %1
6519    mov%?\\t%0, %1
6520    mov%?\\t%0, %1
6521    mvn%?\\t%0, #%B1
6522    ldrb%?\\t%0, %1
6523    strb%?\\t%1, %0
6524    ldrb%?\\t%0, %1
6525    strb%?\\t%1, %0"
6526   [(set_attr "type" "mov_reg,mov_reg,mov_imm,mov_imm,mvn_imm,load1,store1,load1,store1")
6527    (set_attr "predicable" "yes")
6528    (set_attr "predicable_short_it" "yes,yes,yes,no,no,no,no,no,no")
6529    (set_attr "arch" "t2,any,any,t2,any,t2,t2,any,any")
6530    (set_attr "length" "2,4,4,2,4,2,2,4,4")]
6533 ;; HFmode moves
6534 (define_expand "movhf"
6535   [(set (match_operand:HF 0 "general_operand" "")
6536         (match_operand:HF 1 "general_operand" ""))]
6537   "TARGET_EITHER"
6538   "
6539   if (TARGET_32BIT)
6540     {
6541       if (MEM_P (operands[0]))
6542         operands[1] = force_reg (HFmode, operands[1]);
6543     }
6544   else /* TARGET_THUMB1 */
6545     {
6546       if (can_create_pseudo_p ())
6547         {
6548            if (!REG_P (operands[0]))
6549              operands[1] = force_reg (HFmode, operands[1]);
6550         }
6551     }
6552   "
6555 (define_insn "*arm32_movhf"
6556   [(set (match_operand:HF 0 "nonimmediate_operand" "=r,m,r,r")
6557         (match_operand:HF 1 "general_operand"      " m,r,r,F"))]
6558   "TARGET_32BIT && !(TARGET_HARD_FLOAT && TARGET_VFP)
6559    && (   s_register_operand (operands[0], HFmode)
6560        || s_register_operand (operands[1], HFmode))"
6561   "*
6562   switch (which_alternative)
6563     {
6564     case 0:     /* ARM register from memory */
6565       return \"ldrh%?\\t%0, %1\\t%@ __fp16\";
6566     case 1:     /* memory from ARM register */
6567       return \"strh%?\\t%1, %0\\t%@ __fp16\";
6568     case 2:     /* ARM register from ARM register */
6569       return \"mov%?\\t%0, %1\\t%@ __fp16\";
6570     case 3:     /* ARM register from constant */
6571       {
6572         long bits;
6573         rtx ops[4];
6575         bits = real_to_target (NULL, CONST_DOUBLE_REAL_VALUE (operands[1]),
6576                                HFmode);
6577         ops[0] = operands[0];
6578         ops[1] = GEN_INT (bits);
6579         ops[2] = GEN_INT (bits & 0xff00);
6580         ops[3] = GEN_INT (bits & 0x00ff);
6582         if (arm_arch_thumb2)
6583           output_asm_insn (\"movw%?\\t%0, %1\", ops);
6584         else
6585           output_asm_insn (\"mov%?\\t%0, %2\;orr%?\\t%0, %0, %3\", ops);
6586         return \"\";
6587        }
6588     default:
6589       gcc_unreachable ();
6590     }
6591   "
6592   [(set_attr "conds" "unconditional")
6593    (set_attr "type" "load1,store1,mov_reg,multiple")
6594    (set_attr "length" "4,4,4,8")
6595    (set_attr "predicable" "yes")
6596    (set_attr "predicable_short_it" "no")]
6599 (define_expand "movsf"
6600   [(set (match_operand:SF 0 "general_operand" "")
6601         (match_operand:SF 1 "general_operand" ""))]
6602   "TARGET_EITHER"
6603   "
6604   if (TARGET_32BIT)
6605     {
6606       if (MEM_P (operands[0]))
6607         operands[1] = force_reg (SFmode, operands[1]);
6608     }
6609   else /* TARGET_THUMB1 */
6610     {
6611       if (can_create_pseudo_p ())
6612         {
6613            if (!REG_P (operands[0]))
6614              operands[1] = force_reg (SFmode, operands[1]);
6615         }
6616     }
6617   "
6620 ;; Transform a floating-point move of a constant into a core register into
6621 ;; an SImode operation.
6622 (define_split
6623   [(set (match_operand:SF 0 "arm_general_register_operand" "")
6624         (match_operand:SF 1 "immediate_operand" ""))]
6625   "TARGET_EITHER
6626    && reload_completed
6627    && CONST_DOUBLE_P (operands[1])"
6628   [(set (match_dup 2) (match_dup 3))]
6629   "
6630   operands[2] = gen_lowpart (SImode, operands[0]);
6631   operands[3] = gen_lowpart (SImode, operands[1]);
6632   if (operands[2] == 0 || operands[3] == 0)
6633     FAIL;
6634   "
6637 (define_insn "*arm_movsf_soft_insn"
6638   [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,m")
6639         (match_operand:SF 1 "general_operand"  "r,mE,r"))]
6640   "TARGET_32BIT
6641    && TARGET_SOFT_FLOAT
6642    && (!MEM_P (operands[0])
6643        || register_operand (operands[1], SFmode))"
6644   "@
6645    mov%?\\t%0, %1
6646    ldr%?\\t%0, %1\\t%@ float
6647    str%?\\t%1, %0\\t%@ float"
6648   [(set_attr "predicable" "yes")
6649    (set_attr "predicable_short_it" "no")
6650    (set_attr "type" "mov_reg,load1,store1")
6651    (set_attr "arm_pool_range" "*,4096,*")
6652    (set_attr "thumb2_pool_range" "*,4094,*")
6653    (set_attr "arm_neg_pool_range" "*,4084,*")
6654    (set_attr "thumb2_neg_pool_range" "*,0,*")]
6657 (define_expand "movdf"
6658   [(set (match_operand:DF 0 "general_operand" "")
6659         (match_operand:DF 1 "general_operand" ""))]
6660   "TARGET_EITHER"
6661   "
6662   if (TARGET_32BIT)
6663     {
6664       if (MEM_P (operands[0]))
6665         operands[1] = force_reg (DFmode, operands[1]);
6666     }
6667   else /* TARGET_THUMB */
6668     {
6669       if (can_create_pseudo_p ())
6670         {
6671           if (!REG_P (operands[0]))
6672             operands[1] = force_reg (DFmode, operands[1]);
6673         }
6674     }
6675   "
6678 ;; Reloading a df mode value stored in integer regs to memory can require a
6679 ;; scratch reg.
6680 (define_expand "reload_outdf"
6681   [(match_operand:DF 0 "arm_reload_memory_operand" "=o")
6682    (match_operand:DF 1 "s_register_operand" "r")
6683    (match_operand:SI 2 "s_register_operand" "=&r")]
6684   "TARGET_THUMB2"
6685   "
6686   {
6687     enum rtx_code code = GET_CODE (XEXP (operands[0], 0));
6689     if (code == REG)
6690       operands[2] = XEXP (operands[0], 0);
6691     else if (code == POST_INC || code == PRE_DEC)
6692       {
6693         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
6694         operands[1] = gen_rtx_SUBREG (DImode, operands[1], 0);
6695         emit_insn (gen_movdi (operands[0], operands[1]));
6696         DONE;
6697       }
6698     else if (code == PRE_INC)
6699       {
6700         rtx reg = XEXP (XEXP (operands[0], 0), 0);
6702         emit_insn (gen_addsi3 (reg, reg, GEN_INT (8)));
6703         operands[2] = reg;
6704       }
6705     else if (code == POST_DEC)
6706       operands[2] = XEXP (XEXP (operands[0], 0), 0);
6707     else
6708       emit_insn (gen_addsi3 (operands[2], XEXP (XEXP (operands[0], 0), 0),
6709                              XEXP (XEXP (operands[0], 0), 1)));
6711     emit_insn (gen_rtx_SET (replace_equiv_address (operands[0], operands[2]),
6712                             operands[1]));
6714     if (code == POST_DEC)
6715       emit_insn (gen_addsi3 (operands[2], operands[2], GEN_INT (-8)));
6717     DONE;
6718   }"
6721 (define_insn "*movdf_soft_insn"
6722   [(set (match_operand:DF 0 "nonimmediate_soft_df_operand" "=r,r,r,q,m")
6723         (match_operand:DF 1 "soft_df_operand" "rDa,Db,Dc,mF,q"))]
6724   "TARGET_32BIT && TARGET_SOFT_FLOAT
6725    && (   register_operand (operands[0], DFmode)
6726        || register_operand (operands[1], DFmode))"
6727   "*
6728   switch (which_alternative)
6729     {
6730     case 0:
6731     case 1:
6732     case 2:
6733       return \"#\";
6734     default:
6735       return output_move_double (operands, true, NULL);
6736     }
6737   "
6738   [(set_attr "length" "8,12,16,8,8")
6739    (set_attr "type" "multiple,multiple,multiple,load2,store2")
6740    (set_attr "arm_pool_range" "*,*,*,1020,*")
6741    (set_attr "thumb2_pool_range" "*,*,*,1018,*")
6742    (set_attr "arm_neg_pool_range" "*,*,*,1004,*")
6743    (set_attr "thumb2_neg_pool_range" "*,*,*,0,*")]
6747 ;; load- and store-multiple insns
6748 ;; The arm can load/store any set of registers, provided that they are in
6749 ;; ascending order, but these expanders assume a contiguous set.
6751 (define_expand "load_multiple"
6752   [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
6753                           (match_operand:SI 1 "" ""))
6754                      (use (match_operand:SI 2 "" ""))])]
6755   "TARGET_32BIT"
6757   HOST_WIDE_INT offset = 0;
6759   /* Support only fixed point registers.  */
6760   if (!CONST_INT_P (operands[2])
6761       || INTVAL (operands[2]) > MAX_LDM_STM_OPS
6762       || INTVAL (operands[2]) < 2
6763       || !MEM_P (operands[1])
6764       || !REG_P (operands[0])
6765       || REGNO (operands[0]) > (LAST_ARM_REGNUM - 1)
6766       || REGNO (operands[0]) + INTVAL (operands[2]) > LAST_ARM_REGNUM)
6767     FAIL;
6769   operands[3]
6770     = arm_gen_load_multiple (arm_regs_in_sequence + REGNO (operands[0]),
6771                              INTVAL (operands[2]),
6772                              force_reg (SImode, XEXP (operands[1], 0)),
6773                              FALSE, operands[1], &offset);
6776 (define_expand "store_multiple"
6777   [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
6778                           (match_operand:SI 1 "" ""))
6779                      (use (match_operand:SI 2 "" ""))])]
6780   "TARGET_32BIT"
6782   HOST_WIDE_INT offset = 0;
6784   /* Support only fixed point registers.  */
6785   if (!CONST_INT_P (operands[2])
6786       || INTVAL (operands[2]) > MAX_LDM_STM_OPS
6787       || INTVAL (operands[2]) < 2
6788       || !REG_P (operands[1])
6789       || !MEM_P (operands[0])
6790       || REGNO (operands[1]) > (LAST_ARM_REGNUM - 1)
6791       || REGNO (operands[1]) + INTVAL (operands[2]) > LAST_ARM_REGNUM)
6792     FAIL;
6794   operands[3]
6795     = arm_gen_store_multiple (arm_regs_in_sequence + REGNO (operands[1]),
6796                               INTVAL (operands[2]),
6797                               force_reg (SImode, XEXP (operands[0], 0)),
6798                               FALSE, operands[0], &offset);
6802 (define_expand "setmemsi"
6803   [(match_operand:BLK 0 "general_operand" "")
6804    (match_operand:SI 1 "const_int_operand" "")
6805    (match_operand:SI 2 "const_int_operand" "")
6806    (match_operand:SI 3 "const_int_operand" "")]
6807   "TARGET_32BIT"
6809   if (arm_gen_setmem (operands))
6810     DONE;
6812   FAIL;
6816 ;; Move a block of memory if it is word aligned and MORE than 2 words long.
6817 ;; We could let this apply for blocks of less than this, but it clobbers so
6818 ;; many registers that there is then probably a better way.
6820 (define_expand "movmemqi"
6821   [(match_operand:BLK 0 "general_operand" "")
6822    (match_operand:BLK 1 "general_operand" "")
6823    (match_operand:SI 2 "const_int_operand" "")
6824    (match_operand:SI 3 "const_int_operand" "")]
6825   ""
6826   "
6827   if (TARGET_32BIT)
6828     {
6829       if (TARGET_LDRD && current_tune->prefer_ldrd_strd
6830           && !optimize_function_for_size_p (cfun))
6831         {
6832           if (gen_movmem_ldrd_strd (operands))
6833             DONE;
6834           FAIL;
6835         }
6837       if (arm_gen_movmemqi (operands))
6838         DONE;
6839       FAIL;
6840     }
6841   else /* TARGET_THUMB1 */
6842     {
6843       if (   INTVAL (operands[3]) != 4
6844           || INTVAL (operands[2]) > 48)
6845         FAIL;
6847       thumb_expand_movmemqi (operands);
6848       DONE;
6849     }
6850   "
6854 ;; Compare & branch insns
6855 ;; The range calculations are based as follows:
6856 ;; For forward branches, the address calculation returns the address of
6857 ;; the next instruction.  This is 2 beyond the branch instruction.
6858 ;; For backward branches, the address calculation returns the address of
6859 ;; the first instruction in this pattern (cmp).  This is 2 before the branch
6860 ;; instruction for the shortest sequence, and 4 before the branch instruction
6861 ;; if we have to jump around an unconditional branch.
6862 ;; To the basic branch range the PC offset must be added (this is +4).
6863 ;; So for forward branches we have 
6864 ;;   (pos_range - pos_base_offs + pc_offs) = (pos_range - 2 + 4).
6865 ;; And for backward branches we have 
6866 ;;   (neg_range - neg_base_offs + pc_offs) = (neg_range - (-2 or -4) + 4).
6868 ;; For a 'b'       pos_range = 2046, neg_range = -2048 giving (-2040->2048).
6869 ;; For a 'b<cond>' pos_range = 254,  neg_range = -256  giving (-250 ->256).
6871 (define_expand "cbranchsi4"
6872   [(set (pc) (if_then_else
6873               (match_operator 0 "expandable_comparison_operator"
6874                [(match_operand:SI 1 "s_register_operand" "")
6875                 (match_operand:SI 2 "nonmemory_operand" "")])
6876               (label_ref (match_operand 3 "" ""))
6877               (pc)))]
6878   "TARGET_EITHER"
6879   "
6880   if (!TARGET_THUMB1)
6881     {
6882       if (!arm_validize_comparison (&operands[0], &operands[1], &operands[2]))
6883         FAIL;
6884       emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
6885                                       operands[3]));
6886       DONE;
6887     }
6888   if (thumb1_cmpneg_operand (operands[2], SImode))
6889     {
6890       emit_jump_insn (gen_cbranchsi4_scratch (NULL, operands[1], operands[2],
6891                                               operands[3], operands[0]));
6892       DONE;
6893     }
6894   if (!thumb1_cmp_operand (operands[2], SImode))
6895     operands[2] = force_reg (SImode, operands[2]);
6896   ")
6898 (define_expand "cbranchsf4"
6899   [(set (pc) (if_then_else
6900               (match_operator 0 "expandable_comparison_operator"
6901                [(match_operand:SF 1 "s_register_operand" "")
6902                 (match_operand:SF 2 "arm_float_compare_operand" "")])
6903               (label_ref (match_operand 3 "" ""))
6904               (pc)))]
6905   "TARGET_32BIT && TARGET_HARD_FLOAT"
6906   "emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
6907                                    operands[3])); DONE;"
6910 (define_expand "cbranchdf4"
6911   [(set (pc) (if_then_else
6912               (match_operator 0 "expandable_comparison_operator"
6913                [(match_operand:DF 1 "s_register_operand" "")
6914                 (match_operand:DF 2 "arm_float_compare_operand" "")])
6915               (label_ref (match_operand 3 "" ""))
6916               (pc)))]
6917   "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
6918   "emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
6919                                    operands[3])); DONE;"
6922 (define_expand "cbranchdi4"
6923   [(set (pc) (if_then_else
6924               (match_operator 0 "expandable_comparison_operator"
6925                [(match_operand:DI 1 "s_register_operand" "")
6926                 (match_operand:DI 2 "cmpdi_operand" "")])
6927               (label_ref (match_operand 3 "" ""))
6928               (pc)))]
6929   "TARGET_32BIT"
6930   "{
6931      if (!arm_validize_comparison (&operands[0], &operands[1], &operands[2]))
6932        FAIL;
6933      emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
6934                                        operands[3]));
6935      DONE;
6936    }"
6939 ;; Comparison and test insns
6941 (define_insn "*arm_cmpsi_insn"
6942   [(set (reg:CC CC_REGNUM)
6943         (compare:CC (match_operand:SI 0 "s_register_operand" "l,r,r,r,r")
6944                     (match_operand:SI 1 "arm_add_operand"    "Py,r,r,I,L")))]
6945   "TARGET_32BIT"
6946   "@
6947    cmp%?\\t%0, %1
6948    cmp%?\\t%0, %1
6949    cmp%?\\t%0, %1
6950    cmp%?\\t%0, %1
6951    cmn%?\\t%0, #%n1"
6952   [(set_attr "conds" "set")
6953    (set_attr "arch" "t2,t2,any,any,any")
6954    (set_attr "length" "2,2,4,4,4")
6955    (set_attr "predicable" "yes")
6956    (set_attr "predicable_short_it" "yes,yes,yes,no,no")
6957    (set_attr "type" "alus_imm,alus_sreg,alus_sreg,alus_imm,alus_imm")]
6960 (define_insn "*cmpsi_shiftsi"
6961   [(set (reg:CC CC_REGNUM)
6962         (compare:CC (match_operand:SI   0 "s_register_operand" "r,r,r")
6963                     (match_operator:SI  3 "shift_operator"
6964                      [(match_operand:SI 1 "s_register_operand" "r,r,r")
6965                       (match_operand:SI 2 "shift_amount_operand" "M,r,M")])))]
6966   "TARGET_32BIT"
6967   "cmp\\t%0, %1%S3"
6968   [(set_attr "conds" "set")
6969    (set_attr "shift" "1")
6970    (set_attr "arch" "32,a,a")
6971    (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
6973 (define_insn "*cmpsi_shiftsi_swp"
6974   [(set (reg:CC_SWP CC_REGNUM)
6975         (compare:CC_SWP (match_operator:SI 3 "shift_operator"
6976                          [(match_operand:SI 1 "s_register_operand" "r,r,r")
6977                           (match_operand:SI 2 "shift_amount_operand" "M,r,M")])
6978                         (match_operand:SI 0 "s_register_operand" "r,r,r")))]
6979   "TARGET_32BIT"
6980   "cmp%?\\t%0, %1%S3"
6981   [(set_attr "conds" "set")
6982    (set_attr "shift" "1")
6983    (set_attr "arch" "32,a,a")
6984    (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
6986 (define_insn "*arm_cmpsi_negshiftsi_si"
6987   [(set (reg:CC_Z CC_REGNUM)
6988         (compare:CC_Z
6989          (neg:SI (match_operator:SI 1 "shift_operator"
6990                     [(match_operand:SI 2 "s_register_operand" "r")
6991                      (match_operand:SI 3 "reg_or_int_operand" "rM")]))
6992          (match_operand:SI 0 "s_register_operand" "r")))]
6993   "TARGET_ARM"
6994   "cmn%?\\t%0, %2%S1"
6995   [(set_attr "conds" "set")
6996    (set (attr "type") (if_then_else (match_operand 3 "const_int_operand" "")
6997                                     (const_string "alus_shift_imm")
6998                                     (const_string "alus_shift_reg")))
6999    (set_attr "predicable" "yes")]
7002 ;; DImode comparisons.  The generic code generates branches that
7003 ;; if-conversion can not reduce to a conditional compare, so we do
7004 ;; that directly.
7006 (define_insn_and_split "*arm_cmpdi_insn"
7007   [(set (reg:CC_NCV CC_REGNUM)
7008         (compare:CC_NCV (match_operand:DI 0 "s_register_operand" "r")
7009                         (match_operand:DI 1 "arm_di_operand"       "rDi")))
7010    (clobber (match_scratch:SI 2 "=r"))]
7011   "TARGET_32BIT"
7012   "#"   ; "cmp\\t%Q0, %Q1\;sbcs\\t%2, %R0, %R1"
7013   "&& reload_completed"
7014   [(set (reg:CC CC_REGNUM)
7015         (compare:CC (match_dup 0) (match_dup 1)))
7016    (parallel [(set (reg:CC CC_REGNUM)
7017                    (compare:CC (match_dup 3) (match_dup 4)))
7018               (set (match_dup 2)
7019                    (minus:SI (match_dup 5)
7020                             (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))])]
7021   {
7022     operands[3] = gen_highpart (SImode, operands[0]);
7023     operands[0] = gen_lowpart (SImode, operands[0]);
7024     if (CONST_INT_P (operands[1]))
7025       {
7026         operands[4] = GEN_INT (~INTVAL (gen_highpart_mode (SImode,
7027                                                            DImode,
7028                                                            operands[1])));
7029         operands[5] = gen_rtx_PLUS (SImode, operands[3], operands[4]);
7030       }
7031     else
7032       {
7033         operands[4] = gen_highpart (SImode, operands[1]);
7034         operands[5] = gen_rtx_MINUS (SImode, operands[3], operands[4]);
7035       }
7036     operands[1] = gen_lowpart (SImode, operands[1]);
7037     operands[2] = gen_lowpart (SImode, operands[2]);
7038   }
7039   [(set_attr "conds" "set")
7040    (set_attr "length" "8")
7041    (set_attr "type" "multiple")]
7044 (define_insn_and_split "*arm_cmpdi_unsigned"
7045   [(set (reg:CC_CZ CC_REGNUM)
7046         (compare:CC_CZ (match_operand:DI 0 "s_register_operand" "l,r,r,r")
7047                        (match_operand:DI 1 "arm_di_operand"     "Py,r,Di,rDi")))]
7049   "TARGET_32BIT"
7050   "#"   ; "cmp\\t%R0, %R1\;it eq\;cmpeq\\t%Q0, %Q1"
7051   "&& reload_completed"
7052   [(set (reg:CC CC_REGNUM)
7053         (compare:CC (match_dup 2) (match_dup 3)))
7054    (cond_exec (eq:SI (reg:CC CC_REGNUM) (const_int 0))
7055               (set (reg:CC CC_REGNUM)
7056                    (compare:CC (match_dup 0) (match_dup 1))))]
7057   {
7058     operands[2] = gen_highpart (SImode, operands[0]);
7059     operands[0] = gen_lowpart (SImode, operands[0]);
7060     if (CONST_INT_P (operands[1]))
7061       operands[3] = gen_highpart_mode (SImode, DImode, operands[1]);
7062     else
7063       operands[3] = gen_highpart (SImode, operands[1]);
7064     operands[1] = gen_lowpart (SImode, operands[1]);
7065   }
7066   [(set_attr "conds" "set")
7067    (set_attr "enabled_for_depr_it" "yes,yes,no,*")
7068    (set_attr "arch" "t2,t2,t2,a")
7069    (set_attr "length" "6,6,10,8")
7070    (set_attr "type" "multiple")]
7073 (define_insn "*arm_cmpdi_zero"
7074   [(set (reg:CC_Z CC_REGNUM)
7075         (compare:CC_Z (match_operand:DI 0 "s_register_operand" "r")
7076                       (const_int 0)))
7077    (clobber (match_scratch:SI 1 "=r"))]
7078   "TARGET_32BIT"
7079   "orrs%?\\t%1, %Q0, %R0"
7080   [(set_attr "conds" "set")
7081    (set_attr "type" "logics_reg")]
7084 ; This insn allows redundant compares to be removed by cse, nothing should
7085 ; ever appear in the output file since (set (reg x) (reg x)) is a no-op that
7086 ; is deleted later on. The match_dup will match the mode here, so that
7087 ; mode changes of the condition codes aren't lost by this even though we don't
7088 ; specify what they are.
7090 (define_insn "*deleted_compare"
7091   [(set (match_operand 0 "cc_register" "") (match_dup 0))]
7092   "TARGET_32BIT"
7093   "\\t%@ deleted compare"
7094   [(set_attr "conds" "set")
7095    (set_attr "length" "0")
7096    (set_attr "type" "no_insn")]
7100 ;; Conditional branch insns
7102 (define_expand "cbranch_cc"
7103   [(set (pc)
7104         (if_then_else (match_operator 0 "" [(match_operand 1 "" "")
7105                                             (match_operand 2 "" "")])
7106                       (label_ref (match_operand 3 "" ""))
7107                       (pc)))]
7108   "TARGET_32BIT"
7109   "operands[1] = arm_gen_compare_reg (GET_CODE (operands[0]),
7110                                       operands[1], operands[2], NULL_RTX);
7111    operands[2] = const0_rtx;"
7115 ;; Patterns to match conditional branch insns.
7118 (define_insn "arm_cond_branch"
7119   [(set (pc)
7120         (if_then_else (match_operator 1 "arm_comparison_operator"
7121                        [(match_operand 2 "cc_register" "") (const_int 0)])
7122                       (label_ref (match_operand 0 "" ""))
7123                       (pc)))]
7124   "TARGET_32BIT"
7125   "*
7126   if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
7127     {
7128       arm_ccfsm_state += 2;
7129       return \"\";
7130     }
7131   return \"b%d1\\t%l0\";
7132   "
7133   [(set_attr "conds" "use")
7134    (set_attr "type" "branch")
7135    (set (attr "length")
7136         (if_then_else
7137            (and (match_test "TARGET_THUMB2")
7138                 (and (ge (minus (match_dup 0) (pc)) (const_int -250))
7139                      (le (minus (match_dup 0) (pc)) (const_int 256))))
7140            (const_int 2)
7141            (const_int 4)))]
7144 (define_insn "*arm_cond_branch_reversed"
7145   [(set (pc)
7146         (if_then_else (match_operator 1 "arm_comparison_operator"
7147                        [(match_operand 2 "cc_register" "") (const_int 0)])
7148                       (pc)
7149                       (label_ref (match_operand 0 "" ""))))]
7150   "TARGET_32BIT"
7151   "*
7152   if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
7153     {
7154       arm_ccfsm_state += 2;
7155       return \"\";
7156     }
7157   return \"b%D1\\t%l0\";
7158   "
7159   [(set_attr "conds" "use")
7160    (set_attr "type" "branch")
7161    (set (attr "length")
7162         (if_then_else
7163            (and (match_test "TARGET_THUMB2")
7164                 (and (ge (minus (match_dup 0) (pc)) (const_int -250))
7165                      (le (minus (match_dup 0) (pc)) (const_int 256))))
7166            (const_int 2)
7167            (const_int 4)))]
7172 ; scc insns
7174 (define_expand "cstore_cc"
7175   [(set (match_operand:SI 0 "s_register_operand" "")
7176         (match_operator:SI 1 "" [(match_operand 2 "" "")
7177                                  (match_operand 3 "" "")]))]
7178   "TARGET_32BIT"
7179   "operands[2] = arm_gen_compare_reg (GET_CODE (operands[1]),
7180                                       operands[2], operands[3], NULL_RTX);
7181    operands[3] = const0_rtx;"
7184 (define_insn_and_split "*mov_scc"
7185   [(set (match_operand:SI 0 "s_register_operand" "=r")
7186         (match_operator:SI 1 "arm_comparison_operator_mode"
7187          [(match_operand 2 "cc_register" "") (const_int 0)]))]
7188   "TARGET_ARM"
7189   "#"   ; "mov%D1\\t%0, #0\;mov%d1\\t%0, #1"
7190   "TARGET_ARM"
7191   [(set (match_dup 0)
7192         (if_then_else:SI (match_dup 1)
7193                          (const_int 1)
7194                          (const_int 0)))]
7195   ""
7196   [(set_attr "conds" "use")
7197    (set_attr "length" "8")
7198    (set_attr "type" "multiple")]
7201 (define_insn_and_split "*mov_negscc"
7202   [(set (match_operand:SI 0 "s_register_operand" "=r")
7203         (neg:SI (match_operator:SI 1 "arm_comparison_operator_mode"
7204                  [(match_operand 2 "cc_register" "") (const_int 0)])))]
7205   "TARGET_ARM"
7206   "#"   ; "mov%D1\\t%0, #0\;mvn%d1\\t%0, #0"
7207   "TARGET_ARM"
7208   [(set (match_dup 0)
7209         (if_then_else:SI (match_dup 1)
7210                          (match_dup 3)
7211                          (const_int 0)))]
7212   {
7213     operands[3] = GEN_INT (~0);
7214   }
7215   [(set_attr "conds" "use")
7216    (set_attr "length" "8")
7217    (set_attr "type" "multiple")]
7220 (define_insn_and_split "*mov_notscc"
7221   [(set (match_operand:SI 0 "s_register_operand" "=r")
7222         (not:SI (match_operator:SI 1 "arm_comparison_operator"
7223                  [(match_operand 2 "cc_register" "") (const_int 0)])))]
7224   "TARGET_ARM"
7225   "#"   ; "mvn%D1\\t%0, #0\;mvn%d1\\t%0, #1"
7226   "TARGET_ARM"
7227   [(set (match_dup 0)
7228         (if_then_else:SI (match_dup 1)
7229                          (match_dup 3)
7230                          (match_dup 4)))]
7231   {
7232     operands[3] = GEN_INT (~1);
7233     operands[4] = GEN_INT (~0);
7234   }
7235   [(set_attr "conds" "use")
7236    (set_attr "length" "8")
7237    (set_attr "type" "multiple")]
7240 (define_expand "cstoresi4"
7241   [(set (match_operand:SI 0 "s_register_operand" "")
7242         (match_operator:SI 1 "expandable_comparison_operator"
7243          [(match_operand:SI 2 "s_register_operand" "")
7244           (match_operand:SI 3 "reg_or_int_operand" "")]))]
7245   "TARGET_32BIT || TARGET_THUMB1"
7246   "{
7247   rtx op3, scratch, scratch2;
7249   if (!TARGET_THUMB1)
7250     {
7251       if (!arm_add_operand (operands[3], SImode))
7252         operands[3] = force_reg (SImode, operands[3]);
7253       emit_insn (gen_cstore_cc (operands[0], operands[1],
7254                                 operands[2], operands[3]));
7255       DONE;
7256     }
7258   if (operands[3] == const0_rtx)
7259     {
7260       switch (GET_CODE (operands[1]))
7261         {
7262         case EQ:
7263           emit_insn (gen_cstoresi_eq0_thumb1 (operands[0], operands[2]));
7264           break;
7266         case NE:
7267           emit_insn (gen_cstoresi_ne0_thumb1 (operands[0], operands[2]));
7268           break;
7270         case LE:
7271           scratch = expand_binop (SImode, add_optab, operands[2], constm1_rtx,
7272                                   NULL_RTX, 0, OPTAB_WIDEN);
7273           scratch = expand_binop (SImode, ior_optab, operands[2], scratch,
7274                                   NULL_RTX, 0, OPTAB_WIDEN);
7275           expand_binop (SImode, lshr_optab, scratch, GEN_INT (31),
7276                         operands[0], 1, OPTAB_WIDEN);
7277           break;
7279         case GE:
7280           scratch = expand_unop (SImode, one_cmpl_optab, operands[2],
7281                                  NULL_RTX, 1);
7282           expand_binop (SImode, lshr_optab, scratch, GEN_INT (31),
7283                         NULL_RTX, 1, OPTAB_WIDEN);
7284           break;
7286         case GT:
7287           scratch = expand_binop (SImode, ashr_optab, operands[2],
7288                                   GEN_INT (31), NULL_RTX, 0, OPTAB_WIDEN);
7289           scratch = expand_binop (SImode, sub_optab, scratch, operands[2],
7290                                   NULL_RTX, 0, OPTAB_WIDEN);
7291           expand_binop (SImode, lshr_optab, scratch, GEN_INT (31), operands[0],
7292                         0, OPTAB_WIDEN);
7293           break;
7295         /* LT is handled by generic code.  No need for unsigned with 0.  */
7296         default:
7297           FAIL;
7298         }
7299       DONE;
7300     }
7302   switch (GET_CODE (operands[1]))
7303     {
7304     case EQ:
7305       scratch = expand_binop (SImode, sub_optab, operands[2], operands[3],
7306                               NULL_RTX, 0, OPTAB_WIDEN);
7307       emit_insn (gen_cstoresi_eq0_thumb1 (operands[0], scratch));
7308       break;
7310     case NE:
7311       scratch = expand_binop (SImode, sub_optab, operands[2], operands[3],
7312                               NULL_RTX, 0, OPTAB_WIDEN);
7313       emit_insn (gen_cstoresi_ne0_thumb1 (operands[0], scratch));
7314       break;
7316     case LE:
7317       op3 = force_reg (SImode, operands[3]);
7319       scratch = expand_binop (SImode, lshr_optab, operands[2], GEN_INT (31),
7320                               NULL_RTX, 1, OPTAB_WIDEN);
7321       scratch2 = expand_binop (SImode, ashr_optab, op3, GEN_INT (31),
7322                               NULL_RTX, 0, OPTAB_WIDEN);
7323       emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch2,
7324                                           op3, operands[2]));
7325       break;
7327     case GE:
7328       op3 = operands[3];
7329       if (!thumb1_cmp_operand (op3, SImode))
7330         op3 = force_reg (SImode, op3);
7331       scratch = expand_binop (SImode, ashr_optab, operands[2], GEN_INT (31),
7332                               NULL_RTX, 0, OPTAB_WIDEN);
7333       scratch2 = expand_binop (SImode, lshr_optab, op3, GEN_INT (31),
7334                                NULL_RTX, 1, OPTAB_WIDEN);
7335       emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch2,
7336                                           operands[2], op3));
7337       break;
7339     case LEU:
7340       op3 = force_reg (SImode, operands[3]);
7341       scratch = force_reg (SImode, const0_rtx);
7342       emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch,
7343                                           op3, operands[2]));
7344       break;
7346     case GEU:
7347       op3 = operands[3];
7348       if (!thumb1_cmp_operand (op3, SImode))
7349         op3 = force_reg (SImode, op3);
7350       scratch = force_reg (SImode, const0_rtx);
7351       emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch,
7352                                           operands[2], op3));
7353       break;
7355     case LTU:
7356       op3 = operands[3];
7357       if (!thumb1_cmp_operand (op3, SImode))
7358         op3 = force_reg (SImode, op3);
7359       scratch = gen_reg_rtx (SImode);
7360       emit_insn (gen_cstoresi_ltu_thumb1 (operands[0], operands[2], op3));
7361       break;
7363     case GTU:
7364       op3 = force_reg (SImode, operands[3]);
7365       scratch = gen_reg_rtx (SImode);
7366       emit_insn (gen_cstoresi_ltu_thumb1 (operands[0], op3, operands[2]));
7367       break;
7369     /* No good sequences for GT, LT.  */
7370     default:
7371       FAIL;
7372     }
7373   DONE;
7376 (define_expand "cstoresf4"
7377   [(set (match_operand:SI 0 "s_register_operand" "")
7378         (match_operator:SI 1 "expandable_comparison_operator"
7379          [(match_operand:SF 2 "s_register_operand" "")
7380           (match_operand:SF 3 "arm_float_compare_operand" "")]))]
7381   "TARGET_32BIT && TARGET_HARD_FLOAT"
7382   "emit_insn (gen_cstore_cc (operands[0], operands[1],
7383                              operands[2], operands[3])); DONE;"
7386 (define_expand "cstoredf4"
7387   [(set (match_operand:SI 0 "s_register_operand" "")
7388         (match_operator:SI 1 "expandable_comparison_operator"
7389          [(match_operand:DF 2 "s_register_operand" "")
7390           (match_operand:DF 3 "arm_float_compare_operand" "")]))]
7391   "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
7392   "emit_insn (gen_cstore_cc (operands[0], operands[1],
7393                              operands[2], operands[3])); DONE;"
7396 (define_expand "cstoredi4"
7397   [(set (match_operand:SI 0 "s_register_operand" "")
7398         (match_operator:SI 1 "expandable_comparison_operator"
7399          [(match_operand:DI 2 "s_register_operand" "")
7400           (match_operand:DI 3 "cmpdi_operand" "")]))]
7401   "TARGET_32BIT"
7402   "{
7403      if (!arm_validize_comparison (&operands[1],
7404                                    &operands[2],
7405                                    &operands[3]))
7406        FAIL;
7407      emit_insn (gen_cstore_cc (operands[0], operands[1], operands[2],
7408                                  operands[3]));
7409      DONE;
7410    }"
7414 ;; Conditional move insns
7416 (define_expand "movsicc"
7417   [(set (match_operand:SI 0 "s_register_operand" "")
7418         (if_then_else:SI (match_operand 1 "expandable_comparison_operator" "")
7419                          (match_operand:SI 2 "arm_not_operand" "")
7420                          (match_operand:SI 3 "arm_not_operand" "")))]
7421   "TARGET_32BIT"
7422   "
7423   {
7424     enum rtx_code code;
7425     rtx ccreg;
7427     if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0), 
7428                                   &XEXP (operands[1], 1)))
7429       FAIL;
7430     
7431     code = GET_CODE (operands[1]);
7432     ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
7433                                  XEXP (operands[1], 1), NULL_RTX);
7434     operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7435   }"
7438 (define_expand "movsfcc"
7439   [(set (match_operand:SF 0 "s_register_operand" "")
7440         (if_then_else:SF (match_operand 1 "arm_cond_move_operator" "")
7441                          (match_operand:SF 2 "s_register_operand" "")
7442                          (match_operand:SF 3 "s_register_operand" "")))]
7443   "TARGET_32BIT && TARGET_HARD_FLOAT"
7444   "
7445   {
7446     enum rtx_code code = GET_CODE (operands[1]);
7447     rtx ccreg;
7449     if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0), 
7450                                   &XEXP (operands[1], 1)))
7451        FAIL;
7453     code = GET_CODE (operands[1]);
7454     ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
7455                                  XEXP (operands[1], 1), NULL_RTX);
7456     operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7457   }"
7460 (define_expand "movdfcc"
7461   [(set (match_operand:DF 0 "s_register_operand" "")
7462         (if_then_else:DF (match_operand 1 "arm_cond_move_operator" "")
7463                          (match_operand:DF 2 "s_register_operand" "")
7464                          (match_operand:DF 3 "s_register_operand" "")))]
7465   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
7466   "
7467   {
7468     enum rtx_code code = GET_CODE (operands[1]);
7469     rtx ccreg;
7471     if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0), 
7472                                   &XEXP (operands[1], 1)))
7473        FAIL;
7474     code = GET_CODE (operands[1]);
7475     ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
7476                                  XEXP (operands[1], 1), NULL_RTX);
7477     operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7478   }"
7481 (define_insn "*cmov<mode>"
7482     [(set (match_operand:SDF 0 "s_register_operand" "=<F_constraint>")
7483         (if_then_else:SDF (match_operator 1 "arm_vsel_comparison_operator"
7484                           [(match_operand 2 "cc_register" "") (const_int 0)])
7485                           (match_operand:SDF 3 "s_register_operand"
7486                                               "<F_constraint>")
7487                           (match_operand:SDF 4 "s_register_operand"
7488                                               "<F_constraint>")))]
7489   "TARGET_HARD_FLOAT && TARGET_FPU_ARMV8 <vfp_double_cond>"
7490   "*
7491   {
7492     enum arm_cond_code code = maybe_get_arm_condition_code (operands[1]);
7493     switch (code)
7494       {
7495       case ARM_GE:
7496       case ARM_GT:
7497       case ARM_EQ:
7498       case ARM_VS:
7499         return \"vsel%d1.<V_if_elem>\\t%<V_reg>0, %<V_reg>3, %<V_reg>4\";
7500       case ARM_LT:
7501       case ARM_LE:
7502       case ARM_NE:
7503       case ARM_VC:
7504         return \"vsel%D1.<V_if_elem>\\t%<V_reg>0, %<V_reg>4, %<V_reg>3\";
7505       default:
7506         gcc_unreachable ();
7507       }
7508     return \"\";
7509   }"
7510   [(set_attr "conds" "use")
7511    (set_attr "type" "fcsel")]
7514 (define_insn_and_split "*movsicc_insn"
7515   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r,r,r,r,r")
7516         (if_then_else:SI
7517          (match_operator 3 "arm_comparison_operator"
7518           [(match_operand 4 "cc_register" "") (const_int 0)])
7519          (match_operand:SI 1 "arm_not_operand" "0,0,rI,K,rI,rI,K,K")
7520          (match_operand:SI 2 "arm_not_operand" "rI,K,0,0,rI,K,rI,K")))]
7521   "TARGET_ARM"
7522   "@
7523    mov%D3\\t%0, %2
7524    mvn%D3\\t%0, #%B2
7525    mov%d3\\t%0, %1
7526    mvn%d3\\t%0, #%B1
7527    #
7528    #
7529    #
7530    #"
7531    ; alt4: mov%d3\\t%0, %1\;mov%D3\\t%0, %2
7532    ; alt5: mov%d3\\t%0, %1\;mvn%D3\\t%0, #%B2
7533    ; alt6: mvn%d3\\t%0, #%B1\;mov%D3\\t%0, %2
7534    ; alt7: mvn%d3\\t%0, #%B1\;mvn%D3\\t%0, #%B2"
7535   "&& reload_completed"
7536   [(const_int 0)]
7537   {
7538     enum rtx_code rev_code;
7539     machine_mode mode;
7540     rtx rev_cond;
7542     emit_insn (gen_rtx_COND_EXEC (VOIDmode,
7543                                   operands[3],
7544                                   gen_rtx_SET (operands[0], operands[1])));
7546     rev_code = GET_CODE (operands[3]);
7547     mode = GET_MODE (operands[4]);
7548     if (mode == CCFPmode || mode == CCFPEmode)
7549       rev_code = reverse_condition_maybe_unordered (rev_code);
7550     else
7551       rev_code = reverse_condition (rev_code);
7553     rev_cond = gen_rtx_fmt_ee (rev_code,
7554                                VOIDmode,
7555                                operands[4],
7556                                const0_rtx);
7557     emit_insn (gen_rtx_COND_EXEC (VOIDmode,
7558                                   rev_cond,
7559                                   gen_rtx_SET (operands[0], operands[2])));
7560     DONE;
7561   }
7562   [(set_attr "length" "4,4,4,4,8,8,8,8")
7563    (set_attr "conds" "use")
7564    (set_attr_alternative "type"
7565                          [(if_then_else (match_operand 2 "const_int_operand" "")
7566                                         (const_string "mov_imm")
7567                                         (const_string "mov_reg"))
7568                           (const_string "mvn_imm")
7569                           (if_then_else (match_operand 1 "const_int_operand" "")
7570                                         (const_string "mov_imm")
7571                                         (const_string "mov_reg"))
7572                           (const_string "mvn_imm")
7573                           (const_string "multiple")
7574                           (const_string "multiple")
7575                           (const_string "multiple")
7576                           (const_string "multiple")])]
7579 (define_insn "*movsfcc_soft_insn"
7580   [(set (match_operand:SF 0 "s_register_operand" "=r,r")
7581         (if_then_else:SF (match_operator 3 "arm_comparison_operator"
7582                           [(match_operand 4 "cc_register" "") (const_int 0)])
7583                          (match_operand:SF 1 "s_register_operand" "0,r")
7584                          (match_operand:SF 2 "s_register_operand" "r,0")))]
7585   "TARGET_ARM && TARGET_SOFT_FLOAT"
7586   "@
7587    mov%D3\\t%0, %2
7588    mov%d3\\t%0, %1"
7589   [(set_attr "conds" "use")
7590    (set_attr "type" "mov_reg")]
7594 ;; Jump and linkage insns
7596 (define_expand "jump"
7597   [(set (pc)
7598         (label_ref (match_operand 0 "" "")))]
7599   "TARGET_EITHER"
7600   ""
7603 (define_insn "*arm_jump"
7604   [(set (pc)
7605         (label_ref (match_operand 0 "" "")))]
7606   "TARGET_32BIT"
7607   "*
7608   {
7609     if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
7610       {
7611         arm_ccfsm_state += 2;
7612         return \"\";
7613       }
7614     return \"b%?\\t%l0\";
7615   }
7616   "
7617   [(set_attr "predicable" "yes")
7618    (set (attr "length")
7619         (if_then_else
7620            (and (match_test "TARGET_THUMB2")
7621                 (and (ge (minus (match_dup 0) (pc)) (const_int -2044))
7622                      (le (minus (match_dup 0) (pc)) (const_int 2048))))
7623            (const_int 2)
7624            (const_int 4)))
7625    (set_attr "type" "branch")]
7628 (define_expand "call"
7629   [(parallel [(call (match_operand 0 "memory_operand" "")
7630                     (match_operand 1 "general_operand" ""))
7631               (use (match_operand 2 "" ""))
7632               (clobber (reg:SI LR_REGNUM))])]
7633   "TARGET_EITHER"
7634   "
7635   {
7636     rtx callee, pat;
7637     
7638     /* In an untyped call, we can get NULL for operand 2.  */
7639     if (operands[2] == NULL_RTX)
7640       operands[2] = const0_rtx;
7641       
7642     /* Decide if we should generate indirect calls by loading the
7643        32-bit address of the callee into a register before performing the
7644        branch and link.  */
7645     callee = XEXP (operands[0], 0);
7646     if (GET_CODE (callee) == SYMBOL_REF
7647         ? arm_is_long_call_p (SYMBOL_REF_DECL (callee))
7648         : !REG_P (callee))
7649       XEXP (operands[0], 0) = force_reg (Pmode, callee);
7651     pat = gen_call_internal (operands[0], operands[1], operands[2]);
7652     arm_emit_call_insn (pat, XEXP (operands[0], 0), false);
7653     DONE;
7654   }"
7657 (define_expand "call_internal"
7658   [(parallel [(call (match_operand 0 "memory_operand" "")
7659                     (match_operand 1 "general_operand" ""))
7660               (use (match_operand 2 "" ""))
7661               (clobber (reg:SI LR_REGNUM))])])
7663 (define_insn "*call_reg_armv5"
7664   [(call (mem:SI (match_operand:SI 0 "s_register_operand" "r"))
7665          (match_operand 1 "" ""))
7666    (use (match_operand 2 "" ""))
7667    (clobber (reg:SI LR_REGNUM))]
7668   "TARGET_ARM && arm_arch5 && !SIBLING_CALL_P (insn)"
7669   "blx%?\\t%0"
7670   [(set_attr "type" "call")]
7673 (define_insn "*call_reg_arm"
7674   [(call (mem:SI (match_operand:SI 0 "s_register_operand" "r"))
7675          (match_operand 1 "" ""))
7676    (use (match_operand 2 "" ""))
7677    (clobber (reg:SI LR_REGNUM))]
7678   "TARGET_ARM && !arm_arch5 && !SIBLING_CALL_P (insn)"
7679   "*
7680   return output_call (operands);
7681   "
7682   ;; length is worst case, normally it is only two
7683   [(set_attr "length" "12")
7684    (set_attr "type" "call")]
7688 (define_expand "call_value"
7689   [(parallel [(set (match_operand       0 "" "")
7690                    (call (match_operand 1 "memory_operand" "")
7691                          (match_operand 2 "general_operand" "")))
7692               (use (match_operand 3 "" ""))
7693               (clobber (reg:SI LR_REGNUM))])]
7694   "TARGET_EITHER"
7695   "
7696   {
7697     rtx pat, callee;
7698     
7699     /* In an untyped call, we can get NULL for operand 2.  */
7700     if (operands[3] == 0)
7701       operands[3] = const0_rtx;
7702       
7703     /* Decide if we should generate indirect calls by loading the
7704        32-bit address of the callee into a register before performing the
7705        branch and link.  */
7706     callee = XEXP (operands[1], 0);
7707     if (GET_CODE (callee) == SYMBOL_REF
7708         ? arm_is_long_call_p (SYMBOL_REF_DECL (callee))
7709         : !REG_P (callee))
7710       XEXP (operands[1], 0) = force_reg (Pmode, callee);
7712     pat = gen_call_value_internal (operands[0], operands[1],
7713                                    operands[2], operands[3]);
7714     arm_emit_call_insn (pat, XEXP (operands[1], 0), false);
7715     DONE;
7716   }"
7719 (define_expand "call_value_internal"
7720   [(parallel [(set (match_operand       0 "" "")
7721                    (call (match_operand 1 "memory_operand" "")
7722                          (match_operand 2 "general_operand" "")))
7723               (use (match_operand 3 "" ""))
7724               (clobber (reg:SI LR_REGNUM))])])
7726 (define_insn "*call_value_reg_armv5"
7727   [(set (match_operand 0 "" "")
7728         (call (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
7729               (match_operand 2 "" "")))
7730    (use (match_operand 3 "" ""))
7731    (clobber (reg:SI LR_REGNUM))]
7732   "TARGET_ARM && arm_arch5 && !SIBLING_CALL_P (insn)"
7733   "blx%?\\t%1"
7734   [(set_attr "type" "call")]
7737 (define_insn "*call_value_reg_arm"
7738   [(set (match_operand 0 "" "")
7739         (call (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
7740               (match_operand 2 "" "")))
7741    (use (match_operand 3 "" ""))
7742    (clobber (reg:SI LR_REGNUM))]
7743   "TARGET_ARM && !arm_arch5 && !SIBLING_CALL_P (insn)"
7744   "*
7745   return output_call (&operands[1]);
7746   "
7747   [(set_attr "length" "12")
7748    (set_attr "type" "call")]
7751 ;; Allow calls to SYMBOL_REFs specially as they are not valid general addresses
7752 ;; The 'a' causes the operand to be treated as an address, i.e. no '#' output.
7754 (define_insn "*call_symbol"
7755   [(call (mem:SI (match_operand:SI 0 "" ""))
7756          (match_operand 1 "" ""))
7757    (use (match_operand 2 "" ""))
7758    (clobber (reg:SI LR_REGNUM))]
7759   "TARGET_32BIT
7760    && !SIBLING_CALL_P (insn)
7761    && (GET_CODE (operands[0]) == SYMBOL_REF)
7762    && !arm_is_long_call_p (SYMBOL_REF_DECL (operands[0]))"
7763   "*
7764   {
7765    rtx op = operands[0];
7767    /* Switch mode now when possible.  */
7768    if (SYMBOL_REF_DECL (op) && !TREE_PUBLIC (SYMBOL_REF_DECL (op))
7769         && arm_arch5 && arm_change_mode_p (SYMBOL_REF_DECL (op)))
7770       return NEED_PLT_RELOC ? \"blx%?\\t%a0(PLT)\" : \"blx%?\\t(%a0)\";
7772     return NEED_PLT_RELOC ? \"bl%?\\t%a0(PLT)\" : \"bl%?\\t%a0\";
7773   }"
7774   [(set_attr "type" "call")]
7777 (define_insn "*call_value_symbol"
7778   [(set (match_operand 0 "" "")
7779         (call (mem:SI (match_operand:SI 1 "" ""))
7780         (match_operand:SI 2 "" "")))
7781    (use (match_operand 3 "" ""))
7782    (clobber (reg:SI LR_REGNUM))]
7783   "TARGET_32BIT
7784    && !SIBLING_CALL_P (insn)
7785    && (GET_CODE (operands[1]) == SYMBOL_REF)
7786    && !arm_is_long_call_p (SYMBOL_REF_DECL (operands[1]))"
7787   "*
7788   {
7789    rtx op = operands[1];
7791    /* Switch mode now when possible.  */
7792    if (SYMBOL_REF_DECL (op) && !TREE_PUBLIC (SYMBOL_REF_DECL (op))
7793         && arm_arch5 && arm_change_mode_p (SYMBOL_REF_DECL (op)))
7794       return NEED_PLT_RELOC ? \"blx%?\\t%a1(PLT)\" : \"blx%?\\t(%a1)\";
7796     return NEED_PLT_RELOC ? \"bl%?\\t%a1(PLT)\" : \"bl%?\\t%a1\";
7797   }"
7798   [(set_attr "type" "call")]
7801 (define_expand "sibcall_internal"
7802   [(parallel [(call (match_operand 0 "memory_operand" "")
7803                     (match_operand 1 "general_operand" ""))
7804               (return)
7805               (use (match_operand 2 "" ""))])])
7807 ;; We may also be able to do sibcalls for Thumb, but it's much harder...
7808 (define_expand "sibcall"
7809   [(parallel [(call (match_operand 0 "memory_operand" "")
7810                     (match_operand 1 "general_operand" ""))
7811               (return)
7812               (use (match_operand 2 "" ""))])]
7813   "TARGET_32BIT"
7814   "
7815   {
7816     rtx pat;
7818     if ((!REG_P (XEXP (operands[0], 0))
7819          && GET_CODE (XEXP (operands[0], 0)) != SYMBOL_REF)
7820         || (GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
7821             && arm_is_long_call_p (SYMBOL_REF_DECL (XEXP (operands[0], 0)))))
7822      XEXP (operands[0], 0) = force_reg (SImode, XEXP (operands[0], 0));
7824     if (operands[2] == NULL_RTX)
7825       operands[2] = const0_rtx;
7827     pat = gen_sibcall_internal (operands[0], operands[1], operands[2]);
7828     arm_emit_call_insn (pat, operands[0], true);
7829     DONE;
7830   }"
7833 (define_expand "sibcall_value_internal"
7834   [(parallel [(set (match_operand 0 "" "")
7835                    (call (match_operand 1 "memory_operand" "")
7836                          (match_operand 2 "general_operand" "")))
7837               (return)
7838               (use (match_operand 3 "" ""))])])
7840 (define_expand "sibcall_value"
7841   [(parallel [(set (match_operand 0 "" "")
7842                    (call (match_operand 1 "memory_operand" "")
7843                          (match_operand 2 "general_operand" "")))
7844               (return)
7845               (use (match_operand 3 "" ""))])]
7846   "TARGET_32BIT"
7847   "
7848   {
7849     rtx pat;
7851     if ((!REG_P (XEXP (operands[1], 0))
7852          && GET_CODE (XEXP (operands[1], 0)) != SYMBOL_REF)
7853         || (GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
7854             && arm_is_long_call_p (SYMBOL_REF_DECL (XEXP (operands[1], 0)))))
7855      XEXP (operands[1], 0) = force_reg (SImode, XEXP (operands[1], 0));
7857     if (operands[3] == NULL_RTX)
7858       operands[3] = const0_rtx;
7860     pat = gen_sibcall_value_internal (operands[0], operands[1],
7861                                       operands[2], operands[3]);
7862     arm_emit_call_insn (pat, operands[1], true);
7863     DONE;
7864   }"
7867 (define_insn "*sibcall_insn"
7868  [(call (mem:SI (match_operand:SI 0 "call_insn_operand" "Cs, US"))
7869         (match_operand 1 "" ""))
7870   (return)
7871   (use (match_operand 2 "" ""))]
7872   "TARGET_32BIT && SIBLING_CALL_P (insn)"
7873   "*
7874   if (which_alternative == 1)
7875     return NEED_PLT_RELOC ? \"b%?\\t%a0(PLT)\" : \"b%?\\t%a0\";
7876   else
7877     {
7878       if (arm_arch5 || arm_arch4t)
7879         return \"bx%?\\t%0\\t%@ indirect register sibling call\";
7880       else
7881         return \"mov%?\\t%|pc, %0\\t%@ indirect register sibling call\";
7882     }
7883   "
7884   [(set_attr "type" "call")]
7887 (define_insn "*sibcall_value_insn"
7888  [(set (match_operand 0 "" "")
7889        (call (mem:SI (match_operand:SI 1 "call_insn_operand" "Cs,US"))
7890              (match_operand 2 "" "")))
7891   (return)
7892   (use (match_operand 3 "" ""))]
7893   "TARGET_32BIT && SIBLING_CALL_P (insn)"
7894   "*
7895   if (which_alternative == 1)
7896    return NEED_PLT_RELOC ? \"b%?\\t%a1(PLT)\" : \"b%?\\t%a1\";
7897   else
7898     {
7899       if (arm_arch5 || arm_arch4t)
7900         return \"bx%?\\t%1\";
7901       else
7902         return \"mov%?\\t%|pc, %1\\t@ indirect sibling call \";
7903     }
7904   "
7905   [(set_attr "type" "call")]
7908 (define_expand "<return_str>return"
7909   [(RETURNS)]
7910   "(TARGET_ARM || (TARGET_THUMB2
7911                    && ARM_FUNC_TYPE (arm_current_func_type ()) == ARM_FT_NORMAL
7912                    && !IS_STACKALIGN (arm_current_func_type ())))
7913     <return_cond_false>"
7914   "
7915   {
7916     if (TARGET_THUMB2)
7917       {
7918         thumb2_expand_return (<return_simple_p>);
7919         DONE;
7920       }
7921   }
7922   "
7925 ;; Often the return insn will be the same as loading from memory, so set attr
7926 (define_insn "*arm_return"
7927   [(return)]
7928   "TARGET_ARM && USE_RETURN_INSN (FALSE)"
7929   "*
7930   {
7931     if (arm_ccfsm_state == 2)
7932       {
7933         arm_ccfsm_state += 2;
7934         return \"\";
7935       }
7936     return output_return_instruction (const_true_rtx, true, false, false);
7937   }"
7938   [(set_attr "type" "load1")
7939    (set_attr "length" "12")
7940    (set_attr "predicable" "yes")]
7943 (define_insn "*cond_<return_str>return"
7944   [(set (pc)
7945         (if_then_else (match_operator 0 "arm_comparison_operator"
7946                        [(match_operand 1 "cc_register" "") (const_int 0)])
7947                       (RETURNS)
7948                       (pc)))]
7949   "TARGET_ARM  <return_cond_true>"
7950   "*
7951   {
7952     if (arm_ccfsm_state == 2)
7953       {
7954         arm_ccfsm_state += 2;
7955         return \"\";
7956       }
7957     return output_return_instruction (operands[0], true, false,
7958                                       <return_simple_p>);
7959   }"
7960   [(set_attr "conds" "use")
7961    (set_attr "length" "12")
7962    (set_attr "type" "load1")]
7965 (define_insn "*cond_<return_str>return_inverted"
7966   [(set (pc)
7967         (if_then_else (match_operator 0 "arm_comparison_operator"
7968                        [(match_operand 1 "cc_register" "") (const_int 0)])
7969                       (pc)
7970                       (RETURNS)))]
7971   "TARGET_ARM <return_cond_true>"
7972   "*
7973   {
7974     if (arm_ccfsm_state == 2)
7975       {
7976         arm_ccfsm_state += 2;
7977         return \"\";
7978       }
7979     return output_return_instruction (operands[0], true, true,
7980                                       <return_simple_p>);
7981   }"
7982   [(set_attr "conds" "use")
7983    (set_attr "length" "12")
7984    (set_attr "type" "load1")]
7987 (define_insn "*arm_simple_return"
7988   [(simple_return)]
7989   "TARGET_ARM"
7990   "*
7991   {
7992     if (arm_ccfsm_state == 2)
7993       {
7994         arm_ccfsm_state += 2;
7995         return \"\";
7996       }
7997     return output_return_instruction (const_true_rtx, true, false, true);
7998   }"
7999   [(set_attr "type" "branch")
8000    (set_attr "length" "4")
8001    (set_attr "predicable" "yes")]
8004 ;; Generate a sequence of instructions to determine if the processor is
8005 ;; in 26-bit or 32-bit mode, and return the appropriate return address
8006 ;; mask.
8008 (define_expand "return_addr_mask"
8009   [(set (match_dup 1)
8010       (compare:CC_NOOV (unspec [(const_int 0)] UNSPEC_CHECK_ARCH)
8011                        (const_int 0)))
8012    (set (match_operand:SI 0 "s_register_operand" "")
8013       (if_then_else:SI (eq (match_dup 1) (const_int 0))
8014                        (const_int -1)
8015                        (const_int 67108860)))] ; 0x03fffffc
8016   "TARGET_ARM"
8017   "
8018   operands[1] = gen_rtx_REG (CC_NOOVmode, CC_REGNUM);
8019   ")
8021 (define_insn "*check_arch2"
8022   [(set (match_operand:CC_NOOV 0 "cc_register" "")
8023       (compare:CC_NOOV (unspec [(const_int 0)] UNSPEC_CHECK_ARCH)
8024                        (const_int 0)))]
8025   "TARGET_ARM"
8026   "teq\\t%|r0, %|r0\;teq\\t%|pc, %|pc"
8027   [(set_attr "length" "8")
8028    (set_attr "conds" "set")
8029    (set_attr "type" "multiple")]
8032 ;; Call subroutine returning any type.
8034 (define_expand "untyped_call"
8035   [(parallel [(call (match_operand 0 "" "")
8036                     (const_int 0))
8037               (match_operand 1 "" "")
8038               (match_operand 2 "" "")])]
8039   "TARGET_EITHER"
8040   "
8041   {
8042     int i;
8043     rtx par = gen_rtx_PARALLEL (VOIDmode,
8044                                 rtvec_alloc (XVECLEN (operands[2], 0)));
8045     rtx addr = gen_reg_rtx (Pmode);
8046     rtx mem;
8047     int size = 0;
8049     emit_move_insn (addr, XEXP (operands[1], 0));
8050     mem = change_address (operands[1], BLKmode, addr);
8052     for (i = 0; i < XVECLEN (operands[2], 0); i++)
8053       {
8054         rtx src = SET_SRC (XVECEXP (operands[2], 0, i));
8056         /* Default code only uses r0 as a return value, but we could
8057            be using anything up to 4 registers.  */
8058         if (REGNO (src) == R0_REGNUM)
8059           src = gen_rtx_REG (TImode, R0_REGNUM);
8061         XVECEXP (par, 0, i) = gen_rtx_EXPR_LIST (VOIDmode, src,
8062                                                  GEN_INT (size));
8063         size += GET_MODE_SIZE (GET_MODE (src));
8064       }
8066     emit_call_insn (gen_call_value (par, operands[0], const0_rtx, NULL));
8068     size = 0;
8070     for (i = 0; i < XVECLEN (par, 0); i++)
8071       {
8072         HOST_WIDE_INT offset = 0;
8073         rtx reg = XEXP (XVECEXP (par, 0, i), 0);
8075         if (size != 0)
8076           emit_move_insn (addr, plus_constant (Pmode, addr, size));
8078         mem = change_address (mem, GET_MODE (reg), NULL);
8079         if (REGNO (reg) == R0_REGNUM)
8080           {
8081             /* On thumb we have to use a write-back instruction.  */
8082             emit_insn (arm_gen_store_multiple (arm_regs_in_sequence, 4, addr,
8083                        TARGET_THUMB ? TRUE : FALSE, mem, &offset));
8084             size = TARGET_ARM ? 16 : 0;
8085           }
8086         else
8087           {
8088             emit_move_insn (mem, reg);
8089             size = GET_MODE_SIZE (GET_MODE (reg));
8090           }
8091       }
8093     /* The optimizer does not know that the call sets the function value
8094        registers we stored in the result block.  We avoid problems by
8095        claiming that all hard registers are used and clobbered at this
8096        point.  */
8097     emit_insn (gen_blockage ());
8099     DONE;
8100   }"
8103 (define_expand "untyped_return"
8104   [(match_operand:BLK 0 "memory_operand" "")
8105    (match_operand 1 "" "")]
8106   "TARGET_EITHER"
8107   "
8108   {
8109     int i;
8110     rtx addr = gen_reg_rtx (Pmode);
8111     rtx mem;
8112     int size = 0;
8114     emit_move_insn (addr, XEXP (operands[0], 0));
8115     mem = change_address (operands[0], BLKmode, addr);
8117     for (i = 0; i < XVECLEN (operands[1], 0); i++)
8118       {
8119         HOST_WIDE_INT offset = 0;
8120         rtx reg = SET_DEST (XVECEXP (operands[1], 0, i));
8122         if (size != 0)
8123           emit_move_insn (addr, plus_constant (Pmode, addr, size));
8125         mem = change_address (mem, GET_MODE (reg), NULL);
8126         if (REGNO (reg) == R0_REGNUM)
8127           {
8128             /* On thumb we have to use a write-back instruction.  */
8129             emit_insn (arm_gen_load_multiple (arm_regs_in_sequence, 4, addr,
8130                        TARGET_THUMB ? TRUE : FALSE, mem, &offset));
8131             size = TARGET_ARM ? 16 : 0;
8132           }
8133         else
8134           {
8135             emit_move_insn (reg, mem);
8136             size = GET_MODE_SIZE (GET_MODE (reg));
8137           }
8138       }
8140     /* Emit USE insns before the return.  */
8141     for (i = 0; i < XVECLEN (operands[1], 0); i++)
8142       emit_use (SET_DEST (XVECEXP (operands[1], 0, i)));
8144     /* Construct the return.  */
8145     expand_naked_return ();
8147     DONE;
8148   }"
8151 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
8152 ;; all of memory.  This blocks insns from being moved across this point.
8154 (define_insn "blockage"
8155   [(unspec_volatile [(const_int 0)] VUNSPEC_BLOCKAGE)]
8156   "TARGET_EITHER"
8157   ""
8158   [(set_attr "length" "0")
8159    (set_attr "type" "block")]
8162 (define_insn "probe_stack"
8163   [(set (match_operand:SI 0 "memory_operand" "=m")
8164         (unspec:SI [(const_int 0)] UNSPEC_PROBE_STACK))]
8165   "TARGET_32BIT"
8166   "str%?\\tr0, %0"
8167   [(set_attr "type" "store1")
8168    (set_attr "predicable" "yes")]
8171 (define_insn "probe_stack_range"
8172   [(set (match_operand:SI 0 "register_operand" "=r")
8173         (unspec_volatile:SI [(match_operand:SI 1 "register_operand" "0")
8174                              (match_operand:SI 2 "register_operand" "r")]
8175                              VUNSPEC_PROBE_STACK_RANGE))]
8176   "TARGET_32BIT"
8178   return output_probe_stack_range (operands[0], operands[2]);
8180   [(set_attr "type" "multiple")
8181    (set_attr "conds" "clob")]
8184 (define_expand "casesi"
8185   [(match_operand:SI 0 "s_register_operand" "") ; index to jump on
8186    (match_operand:SI 1 "const_int_operand" "")  ; lower bound
8187    (match_operand:SI 2 "const_int_operand" "")  ; total range
8188    (match_operand:SI 3 "" "")                   ; table label
8189    (match_operand:SI 4 "" "")]                  ; Out of range label
8190   "TARGET_32BIT || optimize_size || flag_pic"
8191   "
8192   {
8193     enum insn_code code;
8194     if (operands[1] != const0_rtx)
8195       {
8196         rtx reg = gen_reg_rtx (SImode);
8198         emit_insn (gen_addsi3 (reg, operands[0],
8199                                gen_int_mode (-INTVAL (operands[1]),
8200                                              SImode)));
8201         operands[0] = reg;
8202       }
8204     if (TARGET_ARM)
8205       code = CODE_FOR_arm_casesi_internal;
8206     else if (TARGET_THUMB1)
8207       code = CODE_FOR_thumb1_casesi_internal_pic;
8208     else if (flag_pic)
8209       code = CODE_FOR_thumb2_casesi_internal_pic;
8210     else
8211       code = CODE_FOR_thumb2_casesi_internal;
8213     if (!insn_data[(int) code].operand[1].predicate(operands[2], SImode))
8214       operands[2] = force_reg (SImode, operands[2]);
8216     emit_jump_insn (GEN_FCN ((int) code) (operands[0], operands[2],
8217                                           operands[3], operands[4]));
8218     DONE;
8219   }"
8222 ;; The USE in this pattern is needed to tell flow analysis that this is
8223 ;; a CASESI insn.  It has no other purpose.
8224 (define_insn "arm_casesi_internal"
8225   [(parallel [(set (pc)
8226                (if_then_else
8227                 (leu (match_operand:SI 0 "s_register_operand" "r")
8228                      (match_operand:SI 1 "arm_rhs_operand" "rI"))
8229                 (mem:SI (plus:SI (mult:SI (match_dup 0) (const_int 4))
8230                                  (label_ref (match_operand 2 "" ""))))
8231                 (label_ref (match_operand 3 "" ""))))
8232               (clobber (reg:CC CC_REGNUM))
8233               (use (label_ref (match_dup 2)))])]
8234   "TARGET_ARM"
8235   "*
8236     if (flag_pic)
8237       return \"cmp\\t%0, %1\;addls\\t%|pc, %|pc, %0, asl #2\;b\\t%l3\";
8238     return   \"cmp\\t%0, %1\;ldrls\\t%|pc, [%|pc, %0, asl #2]\;b\\t%l3\";
8239   "
8240   [(set_attr "conds" "clob")
8241    (set_attr "length" "12")
8242    (set_attr "type" "multiple")]
8245 (define_expand "indirect_jump"
8246   [(set (pc)
8247         (match_operand:SI 0 "s_register_operand" ""))]
8248   "TARGET_EITHER"
8249   "
8250   /* Thumb-2 doesn't have mov pc, reg.  Explicitly set the low bit of the
8251      address and use bx.  */
8252   if (TARGET_THUMB2)
8253     {
8254       rtx tmp;
8255       tmp = gen_reg_rtx (SImode);
8256       emit_insn (gen_iorsi3 (tmp, operands[0], GEN_INT(1)));
8257       operands[0] = tmp;
8258     }
8259   "
8262 ;; NB Never uses BX.
8263 (define_insn "*arm_indirect_jump"
8264   [(set (pc)
8265         (match_operand:SI 0 "s_register_operand" "r"))]
8266   "TARGET_ARM"
8267   "mov%?\\t%|pc, %0\\t%@ indirect register jump"
8268   [(set_attr "predicable" "yes")
8269    (set_attr "type" "branch")]
8272 (define_insn "*load_indirect_jump"
8273   [(set (pc)
8274         (match_operand:SI 0 "memory_operand" "m"))]
8275   "TARGET_ARM"
8276   "ldr%?\\t%|pc, %0\\t%@ indirect memory jump"
8277   [(set_attr "type" "load1")
8278    (set_attr "pool_range" "4096")
8279    (set_attr "neg_pool_range" "4084")
8280    (set_attr "predicable" "yes")]
8284 ;; Misc insns
8286 (define_insn "nop"
8287   [(const_int 0)]
8288   "TARGET_EITHER"
8289   "nop"
8290   [(set (attr "length")
8291         (if_then_else (eq_attr "is_thumb" "yes")
8292                       (const_int 2)
8293                       (const_int 4)))
8294    (set_attr "type" "mov_reg")]
8297 (define_insn "trap"
8298   [(trap_if (const_int 1) (const_int 0))]
8299   ""
8300   "*
8301   if (TARGET_ARM)
8302     return \".inst\\t0xe7f000f0\";
8303   else
8304     return \".inst\\t0xdeff\";
8305   "
8306   [(set (attr "length")
8307         (if_then_else (eq_attr "is_thumb" "yes")
8308                       (const_int 2)
8309                       (const_int 4)))
8310    (set_attr "type" "trap")
8311    (set_attr "conds" "unconditional")]
8315 ;; Patterns to allow combination of arithmetic, cond code and shifts
8317 (define_insn "*<arith_shift_insn>_multsi"
8318   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8319         (SHIFTABLE_OPS:SI
8320          (mult:SI (match_operand:SI 2 "s_register_operand" "r,r")
8321                   (match_operand:SI 3 "power_of_two_operand" ""))
8322          (match_operand:SI 1 "s_register_operand" "rk,<t2_binop0>")))]
8323   "TARGET_32BIT"
8324   "<arith_shift_insn>%?\\t%0, %1, %2, lsl %b3"
8325   [(set_attr "predicable" "yes")
8326    (set_attr "predicable_short_it" "no")
8327    (set_attr "shift" "2")
8328    (set_attr "arch" "a,t2")
8329    (set_attr "type" "alu_shift_imm")])
8331 (define_insn "*<arith_shift_insn>_shiftsi"
8332   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
8333         (SHIFTABLE_OPS:SI
8334          (match_operator:SI 2 "shift_nomul_operator"
8335           [(match_operand:SI 3 "s_register_operand" "r,r,r")
8336            (match_operand:SI 4 "shift_amount_operand" "M,M,r")])
8337          (match_operand:SI 1 "s_register_operand" "rk,<t2_binop0>,rk")))]
8338   "TARGET_32BIT && GET_CODE (operands[2]) != MULT"
8339   "<arith_shift_insn>%?\\t%0, %1, %3%S2"
8340   [(set_attr "predicable" "yes")
8341    (set_attr "predicable_short_it" "no")
8342    (set_attr "shift" "3")
8343    (set_attr "arch" "a,t2,a")
8344    (set_attr "type" "alu_shift_imm,alu_shift_imm,alu_shift_reg")])
8346 (define_split
8347   [(set (match_operand:SI 0 "s_register_operand" "")
8348         (match_operator:SI 1 "shiftable_operator"
8349          [(match_operator:SI 2 "shiftable_operator"
8350            [(match_operator:SI 3 "shift_operator"
8351              [(match_operand:SI 4 "s_register_operand" "")
8352               (match_operand:SI 5 "reg_or_int_operand" "")])
8353             (match_operand:SI 6 "s_register_operand" "")])
8354           (match_operand:SI 7 "arm_rhs_operand" "")]))
8355    (clobber (match_operand:SI 8 "s_register_operand" ""))]
8356   "TARGET_32BIT"
8357   [(set (match_dup 8)
8358         (match_op_dup 2 [(match_op_dup 3 [(match_dup 4) (match_dup 5)])
8359                          (match_dup 6)]))
8360    (set (match_dup 0)
8361         (match_op_dup 1 [(match_dup 8) (match_dup 7)]))]
8362   "")
8364 (define_insn "*arith_shiftsi_compare0"
8365   [(set (reg:CC_NOOV CC_REGNUM)
8366         (compare:CC_NOOV
8367          (match_operator:SI 1 "shiftable_operator"
8368           [(match_operator:SI 3 "shift_operator"
8369             [(match_operand:SI 4 "s_register_operand" "r,r")
8370              (match_operand:SI 5 "shift_amount_operand" "M,r")])
8371            (match_operand:SI 2 "s_register_operand" "r,r")])
8372          (const_int 0)))
8373    (set (match_operand:SI 0 "s_register_operand" "=r,r")
8374         (match_op_dup 1 [(match_op_dup 3 [(match_dup 4) (match_dup 5)])
8375                          (match_dup 2)]))]
8376   "TARGET_32BIT"
8377   "%i1s%?\\t%0, %2, %4%S3"
8378   [(set_attr "conds" "set")
8379    (set_attr "shift" "4")
8380    (set_attr "arch" "32,a")
8381    (set_attr "type" "alus_shift_imm,alus_shift_reg")])
8383 (define_insn "*arith_shiftsi_compare0_scratch"
8384   [(set (reg:CC_NOOV CC_REGNUM)
8385         (compare:CC_NOOV
8386          (match_operator:SI 1 "shiftable_operator"
8387           [(match_operator:SI 3 "shift_operator"
8388             [(match_operand:SI 4 "s_register_operand" "r,r")
8389              (match_operand:SI 5 "shift_amount_operand" "M,r")])
8390            (match_operand:SI 2 "s_register_operand" "r,r")])
8391          (const_int 0)))
8392    (clobber (match_scratch:SI 0 "=r,r"))]
8393   "TARGET_32BIT"
8394   "%i1s%?\\t%0, %2, %4%S3"
8395   [(set_attr "conds" "set")
8396    (set_attr "shift" "4")
8397    (set_attr "arch" "32,a")
8398    (set_attr "type" "alus_shift_imm,alus_shift_reg")])
8400 (define_insn "*sub_shiftsi"
8401   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8402         (minus:SI (match_operand:SI 1 "s_register_operand" "r,r")
8403                   (match_operator:SI 2 "shift_operator"
8404                    [(match_operand:SI 3 "s_register_operand" "r,r")
8405                     (match_operand:SI 4 "shift_amount_operand" "M,r")])))]
8406   "TARGET_32BIT"
8407   "sub%?\\t%0, %1, %3%S2"
8408   [(set_attr "predicable" "yes")
8409    (set_attr "shift" "3")
8410    (set_attr "arch" "32,a")
8411    (set_attr "type" "alus_shift_imm,alus_shift_reg")])
8413 (define_insn "*sub_shiftsi_compare0"
8414   [(set (reg:CC_NOOV CC_REGNUM)
8415         (compare:CC_NOOV
8416          (minus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
8417                    (match_operator:SI 2 "shift_operator"
8418                     [(match_operand:SI 3 "s_register_operand" "r,r,r")
8419                      (match_operand:SI 4 "shift_amount_operand" "M,r,M")]))
8420          (const_int 0)))
8421    (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
8422         (minus:SI (match_dup 1)
8423                   (match_op_dup 2 [(match_dup 3) (match_dup 4)])))]
8424   "TARGET_32BIT"
8425   "subs%?\\t%0, %1, %3%S2"
8426   [(set_attr "conds" "set")
8427    (set_attr "shift" "3")
8428    (set_attr "arch" "32,a,a")
8429    (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
8431 (define_insn "*sub_shiftsi_compare0_scratch"
8432   [(set (reg:CC_NOOV CC_REGNUM)
8433         (compare:CC_NOOV
8434          (minus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
8435                    (match_operator:SI 2 "shift_operator"
8436                     [(match_operand:SI 3 "s_register_operand" "r,r,r")
8437                      (match_operand:SI 4 "shift_amount_operand" "M,r,M")]))
8438          (const_int 0)))
8439    (clobber (match_scratch:SI 0 "=r,r,r"))]
8440   "TARGET_32BIT"
8441   "subs%?\\t%0, %1, %3%S2"
8442   [(set_attr "conds" "set")
8443    (set_attr "shift" "3")
8444    (set_attr "arch" "32,a,a")
8445    (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
8448 (define_insn_and_split "*and_scc"
8449   [(set (match_operand:SI 0 "s_register_operand" "=r")
8450         (and:SI (match_operator:SI 1 "arm_comparison_operator"
8451                  [(match_operand 2 "cc_register" "") (const_int 0)])
8452                 (match_operand:SI 3 "s_register_operand" "r")))]
8453   "TARGET_ARM"
8454   "#"   ; "mov%D1\\t%0, #0\;and%d1\\t%0, %3, #1"
8455   "&& reload_completed"
8456   [(cond_exec (match_dup 5) (set (match_dup 0) (const_int 0)))
8457    (cond_exec (match_dup 4) (set (match_dup 0)
8458                                  (and:SI (match_dup 3) (const_int 1))))]
8459   {
8460     machine_mode mode = GET_MODE (operands[2]);
8461     enum rtx_code rc = GET_CODE (operands[1]);
8463     /* Note that operands[4] is the same as operands[1],
8464        but with VOIDmode as the result. */
8465     operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
8466     if (mode == CCFPmode || mode == CCFPEmode)
8467       rc = reverse_condition_maybe_unordered (rc);
8468     else
8469       rc = reverse_condition (rc);
8470     operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
8471   }
8472   [(set_attr "conds" "use")
8473    (set_attr "type" "multiple")
8474    (set_attr "length" "8")]
8477 (define_insn_and_split "*ior_scc"
8478   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8479         (ior:SI (match_operator:SI 1 "arm_comparison_operator"
8480                  [(match_operand 2 "cc_register" "") (const_int 0)])
8481                 (match_operand:SI 3 "s_register_operand" "0,?r")))]
8482   "TARGET_ARM"
8483   "@
8484    orr%d1\\t%0, %3, #1
8485    #"
8486   "&& reload_completed
8487    && REGNO (operands [0]) != REGNO (operands[3])"
8488   ;; && which_alternative == 1
8489   ; mov%D1\\t%0, %3\;orr%d1\\t%0, %3, #1
8490   [(cond_exec (match_dup 5) (set (match_dup 0) (match_dup 3)))
8491    (cond_exec (match_dup 4) (set (match_dup 0)
8492                                  (ior:SI (match_dup 3) (const_int 1))))]
8493   {
8494     machine_mode mode = GET_MODE (operands[2]);
8495     enum rtx_code rc = GET_CODE (operands[1]);
8497     /* Note that operands[4] is the same as operands[1],
8498        but with VOIDmode as the result. */
8499     operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
8500     if (mode == CCFPmode || mode == CCFPEmode)
8501       rc = reverse_condition_maybe_unordered (rc);
8502     else
8503       rc = reverse_condition (rc);
8504     operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
8505   }
8506   [(set_attr "conds" "use")
8507    (set_attr "length" "4,8")
8508    (set_attr "type" "logic_imm,multiple")]
8511 ; A series of splitters for the compare_scc pattern below.  Note that
8512 ; order is important.
8513 (define_split
8514   [(set (match_operand:SI 0 "s_register_operand" "")
8515         (lt:SI (match_operand:SI 1 "s_register_operand" "")
8516                (const_int 0)))
8517    (clobber (reg:CC CC_REGNUM))]
8518   "TARGET_32BIT && reload_completed"
8519   [(set (match_dup 0) (lshiftrt:SI (match_dup 1) (const_int 31)))])
8521 (define_split
8522   [(set (match_operand:SI 0 "s_register_operand" "")
8523         (ge:SI (match_operand:SI 1 "s_register_operand" "")
8524                (const_int 0)))
8525    (clobber (reg:CC CC_REGNUM))]
8526   "TARGET_32BIT && reload_completed"
8527   [(set (match_dup 0) (not:SI (match_dup 1)))
8528    (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 31)))])
8530 (define_split
8531   [(set (match_operand:SI 0 "s_register_operand" "")
8532         (eq:SI (match_operand:SI 1 "s_register_operand" "")
8533                (const_int 0)))
8534    (clobber (reg:CC CC_REGNUM))]
8535   "arm_arch5 && TARGET_32BIT"
8536   [(set (match_dup 0) (clz:SI (match_dup 1)))
8537    (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
8540 (define_split
8541   [(set (match_operand:SI 0 "s_register_operand" "")
8542         (eq:SI (match_operand:SI 1 "s_register_operand" "")
8543                (const_int 0)))
8544    (clobber (reg:CC CC_REGNUM))]
8545   "TARGET_32BIT && reload_completed"
8546   [(parallel
8547     [(set (reg:CC CC_REGNUM)
8548           (compare:CC (const_int 1) (match_dup 1)))
8549      (set (match_dup 0)
8550           (minus:SI (const_int 1) (match_dup 1)))])
8551    (cond_exec (ltu:CC (reg:CC CC_REGNUM) (const_int 0))
8552               (set (match_dup 0) (const_int 0)))])
8554 (define_split
8555   [(set (match_operand:SI 0 "s_register_operand" "")
8556         (ne:SI (match_operand:SI 1 "s_register_operand" "")
8557                (match_operand:SI 2 "const_int_operand" "")))
8558    (clobber (reg:CC CC_REGNUM))]
8559   "TARGET_32BIT && reload_completed"
8560   [(parallel
8561     [(set (reg:CC CC_REGNUM)
8562           (compare:CC (match_dup 1) (match_dup 2)))
8563      (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 3)))])
8564    (cond_exec (ne:CC (reg:CC CC_REGNUM) (const_int 0))
8565               (set (match_dup 0) (const_int 1)))]
8567   operands[3] = GEN_INT (-INTVAL (operands[2]));
8570 (define_split
8571   [(set (match_operand:SI 0 "s_register_operand" "")
8572         (ne:SI (match_operand:SI 1 "s_register_operand" "")
8573                (match_operand:SI 2 "arm_add_operand" "")))
8574    (clobber (reg:CC CC_REGNUM))]
8575   "TARGET_32BIT && reload_completed"
8576   [(parallel
8577     [(set (reg:CC_NOOV CC_REGNUM)
8578           (compare:CC_NOOV (minus:SI (match_dup 1) (match_dup 2))
8579                            (const_int 0)))
8580      (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
8581    (cond_exec (ne:CC_NOOV (reg:CC_NOOV CC_REGNUM) (const_int 0))
8582               (set (match_dup 0) (const_int 1)))])
8584 (define_insn_and_split "*compare_scc"
8585   [(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts")
8586         (match_operator:SI 1 "arm_comparison_operator"
8587          [(match_operand:SI 2 "s_register_operand" "r,r")
8588           (match_operand:SI 3 "arm_add_operand" "rI,L")]))
8589    (clobber (reg:CC CC_REGNUM))]
8590   "TARGET_32BIT"
8591   "#"
8592   "&& reload_completed"
8593   [(set (reg:CC CC_REGNUM) (compare:CC (match_dup 2) (match_dup 3)))
8594    (cond_exec (match_dup 4) (set (match_dup 0) (const_int 0)))
8595    (cond_exec (match_dup 5) (set (match_dup 0) (const_int 1)))]
8597   rtx tmp1;
8598   machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
8599                                            operands[2], operands[3]);
8600   enum rtx_code rc = GET_CODE (operands[1]);
8602   tmp1 = gen_rtx_REG (mode, CC_REGNUM);
8604   operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, tmp1, const0_rtx);
8605   if (mode == CCFPmode || mode == CCFPEmode)
8606     rc = reverse_condition_maybe_unordered (rc);
8607   else
8608     rc = reverse_condition (rc);
8609   operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, tmp1, const0_rtx);
8611   [(set_attr "type" "multiple")]
8614 ;; Attempt to improve the sequence generated by the compare_scc splitters
8615 ;; not to use conditional execution.
8617 ;; Rd = (eq (reg1) (const_int0))  // ARMv5
8618 ;;      clz Rd, reg1
8619 ;;      lsr Rd, Rd, #5
8620 (define_peephole2
8621   [(set (reg:CC CC_REGNUM)
8622         (compare:CC (match_operand:SI 1 "register_operand" "")
8623                     (const_int 0)))
8624    (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
8625               (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
8626    (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
8627               (set (match_dup 0) (const_int 1)))]
8628   "arm_arch5 && TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
8629   [(set (match_dup 0) (clz:SI (match_dup 1)))
8630    (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
8633 ;; Rd = (eq (reg1) (const_int0))  // !ARMv5
8634 ;;      negs Rd, reg1
8635 ;;      adc  Rd, Rd, reg1
8636 (define_peephole2
8637   [(set (reg:CC CC_REGNUM)
8638         (compare:CC (match_operand:SI 1 "register_operand" "")
8639                     (const_int 0)))
8640    (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
8641               (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
8642    (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
8643               (set (match_dup 0) (const_int 1)))
8644    (match_scratch:SI 2 "r")]
8645   "TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
8646   [(parallel
8647     [(set (reg:CC CC_REGNUM)
8648           (compare:CC (const_int 0) (match_dup 1)))
8649      (set (match_dup 2) (minus:SI (const_int 0) (match_dup 1)))])
8650    (set (match_dup 0)
8651         (plus:SI (plus:SI (match_dup 1) (match_dup 2))
8652                  (geu:SI (reg:CC CC_REGNUM) (const_int 0))))]
8655 ;; Rd = (eq (reg1) (reg2/imm))  // ARMv5 and optimising for speed.
8656 ;;      sub  Rd, Reg1, reg2
8657 ;;      clz  Rd, Rd
8658 ;;      lsr  Rd, Rd, #5
8659 (define_peephole2
8660   [(set (reg:CC CC_REGNUM)
8661         (compare:CC (match_operand:SI 1 "register_operand" "")
8662                     (match_operand:SI 2 "arm_rhs_operand" "")))
8663    (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
8664               (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
8665    (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
8666               (set (match_dup 0) (const_int 1)))]
8667   "arm_arch5 && TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)
8668   && !(TARGET_THUMB2 && optimize_insn_for_size_p ())"
8669   [(set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))
8670    (set (match_dup 0) (clz:SI (match_dup 0)))
8671    (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
8675 ;; Rd = (eq (reg1) (reg2))      // ! ARMv5 or optimising for size.
8676 ;;      sub  T1, Reg1, reg2
8677 ;;      negs Rd, T1
8678 ;;      adc  Rd, Rd, T1
8679 (define_peephole2
8680   [(set (reg:CC CC_REGNUM)
8681         (compare:CC (match_operand:SI 1 "register_operand" "")
8682                     (match_operand:SI 2 "arm_rhs_operand" "")))
8683    (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
8684               (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
8685    (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
8686               (set (match_dup 0) (const_int 1)))
8687    (match_scratch:SI 3 "r")]
8688   "TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
8689   [(set (match_dup 3) (match_dup 4))
8690    (parallel
8691     [(set (reg:CC CC_REGNUM)
8692           (compare:CC (const_int 0) (match_dup 3)))
8693      (set (match_dup 0) (minus:SI (const_int 0) (match_dup 3)))])
8694    (set (match_dup 0)
8695         (plus:SI (plus:SI (match_dup 0) (match_dup 3))
8696                  (geu:SI (reg:CC CC_REGNUM) (const_int 0))))]
8697   "
8698   if (CONST_INT_P (operands[2]))
8699     operands[4] = plus_constant (SImode, operands[1], -INTVAL (operands[2]));
8700   else
8701     operands[4] = gen_rtx_MINUS (SImode, operands[1], operands[2]);
8702   ")
8704 (define_insn "*cond_move"
8705   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
8706         (if_then_else:SI (match_operator 3 "equality_operator"
8707                           [(match_operator 4 "arm_comparison_operator"
8708                             [(match_operand 5 "cc_register" "") (const_int 0)])
8709                            (const_int 0)])
8710                          (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
8711                          (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))]
8712   "TARGET_ARM"
8713   "*
8714     if (GET_CODE (operands[3]) == NE)
8715       {
8716         if (which_alternative != 1)
8717           output_asm_insn (\"mov%D4\\t%0, %2\", operands);
8718         if (which_alternative != 0)
8719           output_asm_insn (\"mov%d4\\t%0, %1\", operands);
8720         return \"\";
8721       }
8722     if (which_alternative != 0)
8723       output_asm_insn (\"mov%D4\\t%0, %1\", operands);
8724     if (which_alternative != 1)
8725       output_asm_insn (\"mov%d4\\t%0, %2\", operands);
8726     return \"\";
8727   "
8728   [(set_attr "conds" "use")
8729    (set_attr_alternative "type"
8730                          [(if_then_else (match_operand 2 "const_int_operand" "")
8731                                         (const_string "mov_imm")
8732                                         (const_string "mov_reg"))
8733                           (if_then_else (match_operand 1 "const_int_operand" "")
8734                                         (const_string "mov_imm")
8735                                         (const_string "mov_reg"))
8736                           (const_string "multiple")])
8737    (set_attr "length" "4,4,8")]
8740 (define_insn "*cond_arith"
8741   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8742         (match_operator:SI 5 "shiftable_operator" 
8743          [(match_operator:SI 4 "arm_comparison_operator"
8744            [(match_operand:SI 2 "s_register_operand" "r,r")
8745             (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
8746           (match_operand:SI 1 "s_register_operand" "0,?r")]))
8747    (clobber (reg:CC CC_REGNUM))]
8748   "TARGET_ARM"
8749   "*
8750     if (GET_CODE (operands[4]) == LT && operands[3] == const0_rtx)
8751       return \"%i5\\t%0, %1, %2, lsr #31\";
8753     output_asm_insn (\"cmp\\t%2, %3\", operands);
8754     if (GET_CODE (operands[5]) == AND)
8755       output_asm_insn (\"mov%D4\\t%0, #0\", operands);
8756     else if (GET_CODE (operands[5]) == MINUS)
8757       output_asm_insn (\"rsb%D4\\t%0, %1, #0\", operands);
8758     else if (which_alternative != 0)
8759       output_asm_insn (\"mov%D4\\t%0, %1\", operands);
8760     return \"%i5%d4\\t%0, %1, #1\";
8761   "
8762   [(set_attr "conds" "clob")
8763    (set_attr "length" "12")
8764    (set_attr "type" "multiple")]
8767 (define_insn "*cond_sub"
8768   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8769         (minus:SI (match_operand:SI 1 "s_register_operand" "0,?r")
8770                   (match_operator:SI 4 "arm_comparison_operator"
8771                    [(match_operand:SI 2 "s_register_operand" "r,r")
8772                     (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
8773    (clobber (reg:CC CC_REGNUM))]
8774   "TARGET_ARM"
8775   "*
8776     output_asm_insn (\"cmp\\t%2, %3\", operands);
8777     if (which_alternative != 0)
8778       output_asm_insn (\"mov%D4\\t%0, %1\", operands);
8779     return \"sub%d4\\t%0, %1, #1\";
8780   "
8781   [(set_attr "conds" "clob")
8782    (set_attr "length" "8,12")
8783    (set_attr "type" "multiple")]
8786 (define_insn "*cmp_ite0"
8787   [(set (match_operand 6 "dominant_cc_register" "")
8788         (compare
8789          (if_then_else:SI
8790           (match_operator 4 "arm_comparison_operator"
8791            [(match_operand:SI 0 "s_register_operand"
8792                 "l,l,l,r,r,r,r,r,r")
8793             (match_operand:SI 1 "arm_add_operand"
8794                 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
8795           (match_operator:SI 5 "arm_comparison_operator"
8796            [(match_operand:SI 2 "s_register_operand"
8797                 "l,r,r,l,l,r,r,r,r")
8798             (match_operand:SI 3 "arm_add_operand"
8799                 "lPy,rI,L,lPy,lPy,rI,rI,L,L")])
8800           (const_int 0))
8801          (const_int 0)))]
8802   "TARGET_32BIT"
8803   "*
8804   {
8805     static const char * const cmp1[NUM_OF_COND_CMP][2] =
8806     {
8807       {\"cmp%d5\\t%0, %1\",
8808        \"cmp%d4\\t%2, %3\"},
8809       {\"cmn%d5\\t%0, #%n1\",
8810        \"cmp%d4\\t%2, %3\"},
8811       {\"cmp%d5\\t%0, %1\",
8812        \"cmn%d4\\t%2, #%n3\"},
8813       {\"cmn%d5\\t%0, #%n1\",
8814        \"cmn%d4\\t%2, #%n3\"}
8815     };
8816     static const char * const cmp2[NUM_OF_COND_CMP][2] =
8817     {
8818       {\"cmp\\t%2, %3\",
8819        \"cmp\\t%0, %1\"},
8820       {\"cmp\\t%2, %3\",
8821        \"cmn\\t%0, #%n1\"},
8822       {\"cmn\\t%2, #%n3\",
8823        \"cmp\\t%0, %1\"},
8824       {\"cmn\\t%2, #%n3\",
8825        \"cmn\\t%0, #%n1\"}
8826     };
8827     static const char * const ite[2] =
8828     {
8829       \"it\\t%d5\",
8830       \"it\\t%d4\"
8831     };
8832     static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
8833                                    CMP_CMP, CMN_CMP, CMP_CMP,
8834                                    CMN_CMP, CMP_CMN, CMN_CMN};
8835     int swap =
8836       comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
8838     output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
8839     if (TARGET_THUMB2) {
8840       output_asm_insn (ite[swap], operands);
8841     }
8842     output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
8843     return \"\";
8844   }"
8845   [(set_attr "conds" "set")
8846    (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
8847    (set_attr "type" "multiple")
8848    (set_attr_alternative "length"
8849       [(const_int 6)
8850        (const_int 8)
8851        (const_int 8)
8852        (const_int 8)
8853        (const_int 8)
8854        (if_then_else (eq_attr "is_thumb" "no")
8855            (const_int 8)
8856            (const_int 10))
8857        (if_then_else (eq_attr "is_thumb" "no")
8858            (const_int 8)
8859            (const_int 10))
8860        (if_then_else (eq_attr "is_thumb" "no")
8861            (const_int 8)
8862            (const_int 10))
8863        (if_then_else (eq_attr "is_thumb" "no")
8864            (const_int 8)
8865            (const_int 10))])]
8868 (define_insn "*cmp_ite1"
8869   [(set (match_operand 6 "dominant_cc_register" "")
8870         (compare
8871          (if_then_else:SI
8872           (match_operator 4 "arm_comparison_operator"
8873            [(match_operand:SI 0 "s_register_operand"
8874                 "l,l,l,r,r,r,r,r,r")
8875             (match_operand:SI 1 "arm_add_operand"
8876                 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
8877           (match_operator:SI 5 "arm_comparison_operator"
8878            [(match_operand:SI 2 "s_register_operand"
8879                 "l,r,r,l,l,r,r,r,r")
8880             (match_operand:SI 3 "arm_add_operand"
8881                 "lPy,rI,L,lPy,lPy,rI,rI,L,L")])
8882           (const_int 1))
8883          (const_int 0)))]
8884   "TARGET_32BIT"
8885   "*
8886   {
8887     static const char * const cmp1[NUM_OF_COND_CMP][2] =
8888     {
8889       {\"cmp\\t%0, %1\",
8890        \"cmp\\t%2, %3\"},
8891       {\"cmn\\t%0, #%n1\",
8892        \"cmp\\t%2, %3\"},
8893       {\"cmp\\t%0, %1\",
8894        \"cmn\\t%2, #%n3\"},
8895       {\"cmn\\t%0, #%n1\",
8896        \"cmn\\t%2, #%n3\"}
8897     };
8898     static const char * const cmp2[NUM_OF_COND_CMP][2] =
8899     {
8900       {\"cmp%d4\\t%2, %3\",
8901        \"cmp%D5\\t%0, %1\"},
8902       {\"cmp%d4\\t%2, %3\",
8903        \"cmn%D5\\t%0, #%n1\"},
8904       {\"cmn%d4\\t%2, #%n3\",
8905        \"cmp%D5\\t%0, %1\"},
8906       {\"cmn%d4\\t%2, #%n3\",
8907        \"cmn%D5\\t%0, #%n1\"}
8908     };
8909     static const char * const ite[2] =
8910     {
8911       \"it\\t%d4\",
8912       \"it\\t%D5\"
8913     };
8914     static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
8915                                    CMP_CMP, CMN_CMP, CMP_CMP,
8916                                    CMN_CMP, CMP_CMN, CMN_CMN};
8917     int swap =
8918       comparison_dominates_p (GET_CODE (operands[5]),
8919                               reverse_condition (GET_CODE (operands[4])));
8921     output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
8922     if (TARGET_THUMB2) {
8923       output_asm_insn (ite[swap], operands);
8924     }
8925     output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
8926     return \"\";
8927   }"
8928   [(set_attr "conds" "set")
8929    (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
8930    (set_attr_alternative "length"
8931       [(const_int 6)
8932        (const_int 8)
8933        (const_int 8)
8934        (const_int 8)
8935        (const_int 8)
8936        (if_then_else (eq_attr "is_thumb" "no")
8937            (const_int 8)
8938            (const_int 10))
8939        (if_then_else (eq_attr "is_thumb" "no")
8940            (const_int 8)
8941            (const_int 10))
8942        (if_then_else (eq_attr "is_thumb" "no")
8943            (const_int 8)
8944            (const_int 10))
8945        (if_then_else (eq_attr "is_thumb" "no")
8946            (const_int 8)
8947            (const_int 10))])
8948    (set_attr "type" "multiple")]
8951 (define_insn "*cmp_and"
8952   [(set (match_operand 6 "dominant_cc_register" "")
8953         (compare
8954          (and:SI
8955           (match_operator 4 "arm_comparison_operator"
8956            [(match_operand:SI 0 "s_register_operand" 
8957                 "l,l,l,r,r,r,r,r,r")
8958             (match_operand:SI 1 "arm_add_operand" 
8959                 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
8960           (match_operator:SI 5 "arm_comparison_operator"
8961            [(match_operand:SI 2 "s_register_operand" 
8962                 "l,r,r,l,l,r,r,r,r")
8963             (match_operand:SI 3 "arm_add_operand" 
8964                 "lPy,rI,L,lPy,lPy,rI,rI,L,L")]))
8965          (const_int 0)))]
8966   "TARGET_32BIT"
8967   "*
8968   {
8969     static const char *const cmp1[NUM_OF_COND_CMP][2] =
8970     {
8971       {\"cmp%d5\\t%0, %1\",
8972        \"cmp%d4\\t%2, %3\"},
8973       {\"cmn%d5\\t%0, #%n1\",
8974        \"cmp%d4\\t%2, %3\"},
8975       {\"cmp%d5\\t%0, %1\",
8976        \"cmn%d4\\t%2, #%n3\"},
8977       {\"cmn%d5\\t%0, #%n1\",
8978        \"cmn%d4\\t%2, #%n3\"}
8979     };
8980     static const char *const cmp2[NUM_OF_COND_CMP][2] =
8981     {
8982       {\"cmp\\t%2, %3\",
8983        \"cmp\\t%0, %1\"},
8984       {\"cmp\\t%2, %3\",
8985        \"cmn\\t%0, #%n1\"},
8986       {\"cmn\\t%2, #%n3\",
8987        \"cmp\\t%0, %1\"},
8988       {\"cmn\\t%2, #%n3\",
8989        \"cmn\\t%0, #%n1\"}
8990     };
8991     static const char *const ite[2] =
8992     {
8993       \"it\\t%d5\",
8994       \"it\\t%d4\"
8995     };
8996     static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
8997                                    CMP_CMP, CMN_CMP, CMP_CMP,
8998                                    CMN_CMP, CMP_CMN, CMN_CMN};
8999     int swap =
9000       comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
9002     output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
9003     if (TARGET_THUMB2) {
9004       output_asm_insn (ite[swap], operands);
9005     }
9006     output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
9007     return \"\";
9008   }"
9009   [(set_attr "conds" "set")
9010    (set_attr "predicable" "no")
9011    (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
9012    (set_attr_alternative "length"
9013       [(const_int 6)
9014        (const_int 8)
9015        (const_int 8)
9016        (const_int 8)
9017        (const_int 8)
9018        (if_then_else (eq_attr "is_thumb" "no")
9019            (const_int 8)
9020            (const_int 10))
9021        (if_then_else (eq_attr "is_thumb" "no")
9022            (const_int 8)
9023            (const_int 10))
9024        (if_then_else (eq_attr "is_thumb" "no")
9025            (const_int 8)
9026            (const_int 10))
9027        (if_then_else (eq_attr "is_thumb" "no")
9028            (const_int 8)
9029            (const_int 10))])
9030    (set_attr "type" "multiple")]
9033 (define_insn "*cmp_ior"
9034   [(set (match_operand 6 "dominant_cc_register" "")
9035         (compare
9036          (ior:SI
9037           (match_operator 4 "arm_comparison_operator"
9038            [(match_operand:SI 0 "s_register_operand"
9039                 "l,l,l,r,r,r,r,r,r")
9040             (match_operand:SI 1 "arm_add_operand"
9041                 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
9042           (match_operator:SI 5 "arm_comparison_operator"
9043            [(match_operand:SI 2 "s_register_operand"
9044                 "l,r,r,l,l,r,r,r,r")
9045             (match_operand:SI 3 "arm_add_operand"
9046                 "lPy,rI,L,lPy,lPy,rI,rI,L,L")]))
9047          (const_int 0)))]
9048   "TARGET_32BIT"
9049   "*
9050   {
9051     static const char *const cmp1[NUM_OF_COND_CMP][2] =
9052     {
9053       {\"cmp\\t%0, %1\",
9054        \"cmp\\t%2, %3\"},
9055       {\"cmn\\t%0, #%n1\",
9056        \"cmp\\t%2, %3\"},
9057       {\"cmp\\t%0, %1\",
9058        \"cmn\\t%2, #%n3\"},
9059       {\"cmn\\t%0, #%n1\",
9060        \"cmn\\t%2, #%n3\"}
9061     };
9062     static const char *const cmp2[NUM_OF_COND_CMP][2] =
9063     {
9064       {\"cmp%D4\\t%2, %3\",
9065        \"cmp%D5\\t%0, %1\"},
9066       {\"cmp%D4\\t%2, %3\",
9067        \"cmn%D5\\t%0, #%n1\"},
9068       {\"cmn%D4\\t%2, #%n3\",
9069        \"cmp%D5\\t%0, %1\"},
9070       {\"cmn%D4\\t%2, #%n3\",
9071        \"cmn%D5\\t%0, #%n1\"}
9072     };
9073     static const char *const ite[2] =
9074     {
9075       \"it\\t%D4\",
9076       \"it\\t%D5\"
9077     };
9078     static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
9079                                    CMP_CMP, CMN_CMP, CMP_CMP,
9080                                    CMN_CMP, CMP_CMN, CMN_CMN};
9081     int swap =
9082       comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
9084     output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
9085     if (TARGET_THUMB2) {
9086       output_asm_insn (ite[swap], operands);
9087     }
9088     output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
9089     return \"\";
9090   }
9091   "
9092   [(set_attr "conds" "set")
9093    (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
9094    (set_attr_alternative "length"
9095       [(const_int 6)
9096        (const_int 8)
9097        (const_int 8)
9098        (const_int 8)
9099        (const_int 8)
9100        (if_then_else (eq_attr "is_thumb" "no")
9101            (const_int 8)
9102            (const_int 10))
9103        (if_then_else (eq_attr "is_thumb" "no")
9104            (const_int 8)
9105            (const_int 10))
9106        (if_then_else (eq_attr "is_thumb" "no")
9107            (const_int 8)
9108            (const_int 10))
9109        (if_then_else (eq_attr "is_thumb" "no")
9110            (const_int 8)
9111            (const_int 10))])
9112    (set_attr "type" "multiple")]
9115 (define_insn_and_split "*ior_scc_scc"
9116   [(set (match_operand:SI 0 "s_register_operand" "=Ts")
9117         (ior:SI (match_operator:SI 3 "arm_comparison_operator"
9118                  [(match_operand:SI 1 "s_register_operand" "r")
9119                   (match_operand:SI 2 "arm_add_operand" "rIL")])
9120                 (match_operator:SI 6 "arm_comparison_operator"
9121                  [(match_operand:SI 4 "s_register_operand" "r")
9122                   (match_operand:SI 5 "arm_add_operand" "rIL")])))
9123    (clobber (reg:CC CC_REGNUM))]
9124   "TARGET_32BIT
9125    && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_OR_Y)
9126        != CCmode)"
9127   "#"
9128   "TARGET_32BIT && reload_completed"
9129   [(set (match_dup 7)
9130         (compare
9131          (ior:SI
9132           (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9133           (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9134          (const_int 0)))
9135    (set (match_dup 0) (ne:SI (match_dup 7) (const_int 0)))]
9136   "operands[7]
9137      = gen_rtx_REG (arm_select_dominance_cc_mode (operands[3], operands[6],
9138                                                   DOM_CC_X_OR_Y),
9139                     CC_REGNUM);"
9140   [(set_attr "conds" "clob")
9141    (set_attr "length" "16")
9142    (set_attr "type" "multiple")]
9145 ; If the above pattern is followed by a CMP insn, then the compare is 
9146 ; redundant, since we can rework the conditional instruction that follows.
9147 (define_insn_and_split "*ior_scc_scc_cmp"
9148   [(set (match_operand 0 "dominant_cc_register" "")
9149         (compare (ior:SI (match_operator:SI 3 "arm_comparison_operator"
9150                           [(match_operand:SI 1 "s_register_operand" "r")
9151                            (match_operand:SI 2 "arm_add_operand" "rIL")])
9152                          (match_operator:SI 6 "arm_comparison_operator"
9153                           [(match_operand:SI 4 "s_register_operand" "r")
9154                            (match_operand:SI 5 "arm_add_operand" "rIL")]))
9155                  (const_int 0)))
9156    (set (match_operand:SI 7 "s_register_operand" "=Ts")
9157         (ior:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9158                 (match_op_dup 6 [(match_dup 4) (match_dup 5)])))]
9159   "TARGET_32BIT"
9160   "#"
9161   "TARGET_32BIT && reload_completed"
9162   [(set (match_dup 0)
9163         (compare
9164          (ior:SI
9165           (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9166           (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9167          (const_int 0)))
9168    (set (match_dup 7) (ne:SI (match_dup 0) (const_int 0)))]
9169   ""
9170   [(set_attr "conds" "set")
9171    (set_attr "length" "16")
9172    (set_attr "type" "multiple")]
9175 (define_insn_and_split "*and_scc_scc"
9176   [(set (match_operand:SI 0 "s_register_operand" "=Ts")
9177         (and:SI (match_operator:SI 3 "arm_comparison_operator"
9178                  [(match_operand:SI 1 "s_register_operand" "r")
9179                   (match_operand:SI 2 "arm_add_operand" "rIL")])
9180                 (match_operator:SI 6 "arm_comparison_operator"
9181                  [(match_operand:SI 4 "s_register_operand" "r")
9182                   (match_operand:SI 5 "arm_add_operand" "rIL")])))
9183    (clobber (reg:CC CC_REGNUM))]
9184   "TARGET_32BIT
9185    && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
9186        != CCmode)"
9187   "#"
9188   "TARGET_32BIT && reload_completed
9189    && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
9190        != CCmode)"
9191   [(set (match_dup 7)
9192         (compare
9193          (and:SI
9194           (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9195           (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9196          (const_int 0)))
9197    (set (match_dup 0) (ne:SI (match_dup 7) (const_int 0)))]
9198   "operands[7]
9199      = gen_rtx_REG (arm_select_dominance_cc_mode (operands[3], operands[6],
9200                                                   DOM_CC_X_AND_Y),
9201                     CC_REGNUM);"
9202   [(set_attr "conds" "clob")
9203    (set_attr "length" "16")
9204    (set_attr "type" "multiple")]
9207 ; If the above pattern is followed by a CMP insn, then the compare is 
9208 ; redundant, since we can rework the conditional instruction that follows.
9209 (define_insn_and_split "*and_scc_scc_cmp"
9210   [(set (match_operand 0 "dominant_cc_register" "")
9211         (compare (and:SI (match_operator:SI 3 "arm_comparison_operator"
9212                           [(match_operand:SI 1 "s_register_operand" "r")
9213                            (match_operand:SI 2 "arm_add_operand" "rIL")])
9214                          (match_operator:SI 6 "arm_comparison_operator"
9215                           [(match_operand:SI 4 "s_register_operand" "r")
9216                            (match_operand:SI 5 "arm_add_operand" "rIL")]))
9217                  (const_int 0)))
9218    (set (match_operand:SI 7 "s_register_operand" "=Ts")
9219         (and:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9220                 (match_op_dup 6 [(match_dup 4) (match_dup 5)])))]
9221   "TARGET_32BIT"
9222   "#"
9223   "TARGET_32BIT && reload_completed"
9224   [(set (match_dup 0)
9225         (compare
9226          (and:SI
9227           (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9228           (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9229          (const_int 0)))
9230    (set (match_dup 7) (ne:SI (match_dup 0) (const_int 0)))]
9231   ""
9232   [(set_attr "conds" "set")
9233    (set_attr "length" "16")
9234    (set_attr "type" "multiple")]
9237 ;; If there is no dominance in the comparison, then we can still save an
9238 ;; instruction in the AND case, since we can know that the second compare
9239 ;; need only zero the value if false (if true, then the value is already
9240 ;; correct).
9241 (define_insn_and_split "*and_scc_scc_nodom"
9242   [(set (match_operand:SI 0 "s_register_operand" "=&Ts,&Ts,&Ts")
9243         (and:SI (match_operator:SI 3 "arm_comparison_operator"
9244                  [(match_operand:SI 1 "s_register_operand" "r,r,0")
9245                   (match_operand:SI 2 "arm_add_operand" "rIL,0,rIL")])
9246                 (match_operator:SI 6 "arm_comparison_operator"
9247                  [(match_operand:SI 4 "s_register_operand" "r,r,r")
9248                   (match_operand:SI 5 "arm_add_operand" "rIL,rIL,rIL")])))
9249    (clobber (reg:CC CC_REGNUM))]
9250   "TARGET_32BIT
9251    && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
9252        == CCmode)"
9253   "#"
9254   "TARGET_32BIT && reload_completed"
9255   [(parallel [(set (match_dup 0)
9256                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
9257               (clobber (reg:CC CC_REGNUM))])
9258    (set (match_dup 7) (match_op_dup 8 [(match_dup 4) (match_dup 5)]))
9259    (set (match_dup 0)
9260         (if_then_else:SI (match_op_dup 6 [(match_dup 7) (const_int 0)])
9261                          (match_dup 0)
9262                          (const_int 0)))]
9263   "operands[7] = gen_rtx_REG (SELECT_CC_MODE (GET_CODE (operands[6]),
9264                                               operands[4], operands[5]),
9265                               CC_REGNUM);
9266    operands[8] = gen_rtx_COMPARE (GET_MODE (operands[7]), operands[4],
9267                                   operands[5]);"
9268   [(set_attr "conds" "clob")
9269    (set_attr "length" "20")
9270    (set_attr "type" "multiple")]
9273 (define_split
9274   [(set (reg:CC_NOOV CC_REGNUM)
9275         (compare:CC_NOOV (ior:SI
9276                           (and:SI (match_operand:SI 0 "s_register_operand" "")
9277                                   (const_int 1))
9278                           (match_operator:SI 1 "arm_comparison_operator"
9279                            [(match_operand:SI 2 "s_register_operand" "")
9280                             (match_operand:SI 3 "arm_add_operand" "")]))
9281                          (const_int 0)))
9282    (clobber (match_operand:SI 4 "s_register_operand" ""))]
9283   "TARGET_ARM"
9284   [(set (match_dup 4)
9285         (ior:SI (match_op_dup 1 [(match_dup 2) (match_dup 3)])
9286                 (match_dup 0)))
9287    (set (reg:CC_NOOV CC_REGNUM)
9288         (compare:CC_NOOV (and:SI (match_dup 4) (const_int 1))
9289                          (const_int 0)))]
9290   "")
9292 (define_split
9293   [(set (reg:CC_NOOV CC_REGNUM)
9294         (compare:CC_NOOV (ior:SI
9295                           (match_operator:SI 1 "arm_comparison_operator"
9296                            [(match_operand:SI 2 "s_register_operand" "")
9297                             (match_operand:SI 3 "arm_add_operand" "")])
9298                           (and:SI (match_operand:SI 0 "s_register_operand" "")
9299                                   (const_int 1)))
9300                          (const_int 0)))
9301    (clobber (match_operand:SI 4 "s_register_operand" ""))]
9302   "TARGET_ARM"
9303   [(set (match_dup 4)
9304         (ior:SI (match_op_dup 1 [(match_dup 2) (match_dup 3)])
9305                 (match_dup 0)))
9306    (set (reg:CC_NOOV CC_REGNUM)
9307         (compare:CC_NOOV (and:SI (match_dup 4) (const_int 1))
9308                          (const_int 0)))]
9309   "")
9310 ;; ??? The conditional patterns above need checking for Thumb-2 usefulness
9312 (define_insn_and_split "*negscc"
9313   [(set (match_operand:SI 0 "s_register_operand" "=r")
9314         (neg:SI (match_operator 3 "arm_comparison_operator"
9315                  [(match_operand:SI 1 "s_register_operand" "r")
9316                   (match_operand:SI 2 "arm_rhs_operand" "rI")])))
9317    (clobber (reg:CC CC_REGNUM))]
9318   "TARGET_ARM"
9319   "#"
9320   "&& reload_completed"
9321   [(const_int 0)]
9322   {
9323     rtx cc_reg = gen_rtx_REG (CCmode, CC_REGNUM);
9325     if (GET_CODE (operands[3]) == LT && operands[2] == const0_rtx)
9326        {
9327          /* Emit mov\\t%0, %1, asr #31 */
9328          emit_insn (gen_rtx_SET (operands[0],
9329                                  gen_rtx_ASHIFTRT (SImode,
9330                                                    operands[1],
9331                                                    GEN_INT (31))));
9332          DONE;
9333        }
9334      else if (GET_CODE (operands[3]) == NE)
9335        {
9336         /* Emit subs\\t%0, %1, %2\;mvnne\\t%0, #0 */
9337         if (CONST_INT_P (operands[2]))
9338           emit_insn (gen_cmpsi2_addneg (operands[0], operands[1], operands[2],
9339                                         GEN_INT (- INTVAL (operands[2]))));
9340         else
9341           emit_insn (gen_subsi3_compare (operands[0], operands[1], operands[2]));
9343         emit_insn (gen_rtx_COND_EXEC (VOIDmode,
9344                                       gen_rtx_NE (SImode,
9345                                                   cc_reg,
9346                                                   const0_rtx),
9347                                       gen_rtx_SET (operands[0],
9348                                                    GEN_INT (~0))));
9349         DONE;
9350       }
9351     else
9352       {
9353         /* Emit: cmp\\t%1, %2\;mov%D3\\t%0, #0\;mvn%d3\\t%0, #0 */
9354         emit_insn (gen_rtx_SET (cc_reg,
9355                                 gen_rtx_COMPARE (CCmode, operands[1], operands[2])));
9356         enum rtx_code rc = GET_CODE (operands[3]);
9358         rc = reverse_condition (rc);
9359         emit_insn (gen_rtx_COND_EXEC (VOIDmode,
9360                                       gen_rtx_fmt_ee (rc,
9361                                                       VOIDmode,
9362                                                       cc_reg,
9363                                                       const0_rtx),
9364                                       gen_rtx_SET (operands[0], const0_rtx)));
9365         rc = GET_CODE (operands[3]);
9366         emit_insn (gen_rtx_COND_EXEC (VOIDmode,
9367                                       gen_rtx_fmt_ee (rc,
9368                                                       VOIDmode,
9369                                                       cc_reg,
9370                                                       const0_rtx),
9371                                       gen_rtx_SET (operands[0],
9372                                                    GEN_INT (~0))));
9373         DONE;
9374       }
9375      FAIL;
9376   }
9377   [(set_attr "conds" "clob")
9378    (set_attr "length" "12")
9379    (set_attr "type" "multiple")]
9382 (define_insn_and_split "movcond_addsi"
9383   [(set (match_operand:SI 0 "s_register_operand" "=r,l,r")
9384         (if_then_else:SI
9385          (match_operator 5 "comparison_operator"
9386           [(plus:SI (match_operand:SI 3 "s_register_operand" "r,r,r")
9387                     (match_operand:SI 4 "arm_add_operand" "rIL,rIL,rIL"))
9388             (const_int 0)])
9389          (match_operand:SI 1 "arm_rhs_operand" "rI,rPy,r")
9390          (match_operand:SI 2 "arm_rhs_operand" "rI,rPy,r")))
9391    (clobber (reg:CC CC_REGNUM))]
9392    "TARGET_32BIT"
9393    "#"
9394    "&& reload_completed"
9395   [(set (reg:CC_NOOV CC_REGNUM)
9396         (compare:CC_NOOV
9397          (plus:SI (match_dup 3)
9398                   (match_dup 4))
9399          (const_int 0)))
9400    (set (match_dup 0) (match_dup 1))
9401    (cond_exec (match_dup 6)
9402               (set (match_dup 0) (match_dup 2)))]
9403   "
9404   {
9405     machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[5]),
9406                                              operands[3], operands[4]);
9407     enum rtx_code rc = GET_CODE (operands[5]);
9408     operands[6] = gen_rtx_REG (mode, CC_REGNUM);
9409     gcc_assert (!(mode == CCFPmode || mode == CCFPEmode));
9410     if (!REG_P (operands[2]) || REGNO (operands[2]) != REGNO (operands[0]))
9411       rc = reverse_condition (rc);
9412     else
9413       std::swap (operands[1], operands[2]);
9415     operands[6] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
9416   }
9417   "
9418   [(set_attr "conds" "clob")
9419    (set_attr "enabled_for_depr_it" "no,yes,yes")
9420    (set_attr "type" "multiple")]
9423 (define_insn "movcond"
9424   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9425         (if_then_else:SI
9426          (match_operator 5 "arm_comparison_operator"
9427           [(match_operand:SI 3 "s_register_operand" "r,r,r")
9428            (match_operand:SI 4 "arm_add_operand" "rIL,rIL,rIL")])
9429          (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
9430          (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
9431    (clobber (reg:CC CC_REGNUM))]
9432   "TARGET_ARM"
9433   "*
9434   if (GET_CODE (operands[5]) == LT
9435       && (operands[4] == const0_rtx))
9436     {
9437       if (which_alternative != 1 && REG_P (operands[1]))
9438         {
9439           if (operands[2] == const0_rtx)
9440             return \"and\\t%0, %1, %3, asr #31\";
9441           return \"ands\\t%0, %1, %3, asr #32\;movcc\\t%0, %2\";
9442         }
9443       else if (which_alternative != 0 && REG_P (operands[2]))
9444         {
9445           if (operands[1] == const0_rtx)
9446             return \"bic\\t%0, %2, %3, asr #31\";
9447           return \"bics\\t%0, %2, %3, asr #32\;movcs\\t%0, %1\";
9448         }
9449       /* The only case that falls through to here is when both ops 1 & 2
9450          are constants.  */
9451     }
9453   if (GET_CODE (operands[5]) == GE
9454       && (operands[4] == const0_rtx))
9455     {
9456       if (which_alternative != 1 && REG_P (operands[1]))
9457         {
9458           if (operands[2] == const0_rtx)
9459             return \"bic\\t%0, %1, %3, asr #31\";
9460           return \"bics\\t%0, %1, %3, asr #32\;movcs\\t%0, %2\";
9461         }
9462       else if (which_alternative != 0 && REG_P (operands[2]))
9463         {
9464           if (operands[1] == const0_rtx)
9465             return \"and\\t%0, %2, %3, asr #31\";
9466           return \"ands\\t%0, %2, %3, asr #32\;movcc\\t%0, %1\";
9467         }
9468       /* The only case that falls through to here is when both ops 1 & 2
9469          are constants.  */
9470     }
9471   if (CONST_INT_P (operands[4])
9472       && !const_ok_for_arm (INTVAL (operands[4])))
9473     output_asm_insn (\"cmn\\t%3, #%n4\", operands);
9474   else
9475     output_asm_insn (\"cmp\\t%3, %4\", operands);
9476   if (which_alternative != 0)
9477     output_asm_insn (\"mov%d5\\t%0, %1\", operands);
9478   if (which_alternative != 1)
9479     output_asm_insn (\"mov%D5\\t%0, %2\", operands);
9480   return \"\";
9481   "
9482   [(set_attr "conds" "clob")
9483    (set_attr "length" "8,8,12")
9484    (set_attr "type" "multiple")]
9487 ;; ??? The patterns below need checking for Thumb-2 usefulness.
9489 (define_insn "*ifcompare_plus_move"
9490   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9491         (if_then_else:SI (match_operator 6 "arm_comparison_operator"
9492                           [(match_operand:SI 4 "s_register_operand" "r,r")
9493                            (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
9494                          (plus:SI
9495                           (match_operand:SI 2 "s_register_operand" "r,r")
9496                           (match_operand:SI 3 "arm_add_operand" "rIL,rIL"))
9497                          (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))
9498    (clobber (reg:CC CC_REGNUM))]
9499   "TARGET_ARM"
9500   "#"
9501   [(set_attr "conds" "clob")
9502    (set_attr "length" "8,12")
9503    (set_attr "type" "multiple")]
9506 (define_insn "*if_plus_move"
9507   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
9508         (if_then_else:SI
9509          (match_operator 4 "arm_comparison_operator"
9510           [(match_operand 5 "cc_register" "") (const_int 0)])
9511          (plus:SI
9512           (match_operand:SI 2 "s_register_operand" "r,r,r,r")
9513           (match_operand:SI 3 "arm_add_operand" "rI,L,rI,L"))
9514          (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")))]
9515   "TARGET_ARM"
9516   "@
9517    add%d4\\t%0, %2, %3
9518    sub%d4\\t%0, %2, #%n3
9519    add%d4\\t%0, %2, %3\;mov%D4\\t%0, %1
9520    sub%d4\\t%0, %2, #%n3\;mov%D4\\t%0, %1"
9521   [(set_attr "conds" "use")
9522    (set_attr "length" "4,4,8,8")
9523    (set_attr_alternative "type"
9524                          [(if_then_else (match_operand 3 "const_int_operand" "")
9525                                         (const_string "alu_imm" )
9526                                         (const_string "alu_sreg"))
9527                           (const_string "alu_imm")
9528                           (const_string "multiple")
9529                           (const_string "multiple")])]
9532 (define_insn "*ifcompare_move_plus"
9533   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9534         (if_then_else:SI (match_operator 6 "arm_comparison_operator"
9535                           [(match_operand:SI 4 "s_register_operand" "r,r")
9536                            (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
9537                          (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
9538                          (plus:SI
9539                           (match_operand:SI 2 "s_register_operand" "r,r")
9540                           (match_operand:SI 3 "arm_add_operand" "rIL,rIL"))))
9541    (clobber (reg:CC CC_REGNUM))]
9542   "TARGET_ARM"
9543   "#"
9544   [(set_attr "conds" "clob")
9545    (set_attr "length" "8,12")
9546    (set_attr "type" "multiple")]
9549 (define_insn "*if_move_plus"
9550   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
9551         (if_then_else:SI
9552          (match_operator 4 "arm_comparison_operator"
9553           [(match_operand 5 "cc_register" "") (const_int 0)])
9554          (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")
9555          (plus:SI
9556           (match_operand:SI 2 "s_register_operand" "r,r,r,r")
9557           (match_operand:SI 3 "arm_add_operand" "rI,L,rI,L"))))]
9558   "TARGET_ARM"
9559   "@
9560    add%D4\\t%0, %2, %3
9561    sub%D4\\t%0, %2, #%n3
9562    add%D4\\t%0, %2, %3\;mov%d4\\t%0, %1
9563    sub%D4\\t%0, %2, #%n3\;mov%d4\\t%0, %1"
9564   [(set_attr "conds" "use")
9565    (set_attr "length" "4,4,8,8")
9566    (set_attr_alternative "type"
9567                          [(if_then_else (match_operand 3 "const_int_operand" "")
9568                                         (const_string "alu_imm" )
9569                                         (const_string "alu_sreg"))
9570                           (const_string "alu_imm")
9571                           (const_string "multiple")
9572                           (const_string "multiple")])]
9575 (define_insn "*ifcompare_arith_arith"
9576   [(set (match_operand:SI 0 "s_register_operand" "=r")
9577         (if_then_else:SI (match_operator 9 "arm_comparison_operator"
9578                           [(match_operand:SI 5 "s_register_operand" "r")
9579                            (match_operand:SI 6 "arm_add_operand" "rIL")])
9580                          (match_operator:SI 8 "shiftable_operator"
9581                           [(match_operand:SI 1 "s_register_operand" "r")
9582                            (match_operand:SI 2 "arm_rhs_operand" "rI")])
9583                          (match_operator:SI 7 "shiftable_operator"
9584                           [(match_operand:SI 3 "s_register_operand" "r")
9585                            (match_operand:SI 4 "arm_rhs_operand" "rI")])))
9586    (clobber (reg:CC CC_REGNUM))]
9587   "TARGET_ARM"
9588   "#"
9589   [(set_attr "conds" "clob")
9590    (set_attr "length" "12")
9591    (set_attr "type" "multiple")]
9594 (define_insn "*if_arith_arith"
9595   [(set (match_operand:SI 0 "s_register_operand" "=r")
9596         (if_then_else:SI (match_operator 5 "arm_comparison_operator"
9597                           [(match_operand 8 "cc_register" "") (const_int 0)])
9598                          (match_operator:SI 6 "shiftable_operator"
9599                           [(match_operand:SI 1 "s_register_operand" "r")
9600                            (match_operand:SI 2 "arm_rhs_operand" "rI")])
9601                          (match_operator:SI 7 "shiftable_operator"
9602                           [(match_operand:SI 3 "s_register_operand" "r")
9603                            (match_operand:SI 4 "arm_rhs_operand" "rI")])))]
9604   "TARGET_ARM"
9605   "%I6%d5\\t%0, %1, %2\;%I7%D5\\t%0, %3, %4"
9606   [(set_attr "conds" "use")
9607    (set_attr "length" "8")
9608    (set_attr "type" "multiple")]
9611 (define_insn "*ifcompare_arith_move"
9612   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9613         (if_then_else:SI (match_operator 6 "arm_comparison_operator"
9614                           [(match_operand:SI 2 "s_register_operand" "r,r")
9615                            (match_operand:SI 3 "arm_add_operand" "rIL,rIL")])
9616                          (match_operator:SI 7 "shiftable_operator"
9617                           [(match_operand:SI 4 "s_register_operand" "r,r")
9618                            (match_operand:SI 5 "arm_rhs_operand" "rI,rI")])
9619                          (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))
9620    (clobber (reg:CC CC_REGNUM))]
9621   "TARGET_ARM"
9622   "*
9623   /* If we have an operation where (op x 0) is the identity operation and
9624      the conditional operator is LT or GE and we are comparing against zero and
9625      everything is in registers then we can do this in two instructions.  */
9626   if (operands[3] == const0_rtx
9627       && GET_CODE (operands[7]) != AND
9628       && REG_P (operands[5])
9629       && REG_P (operands[1])
9630       && REGNO (operands[1]) == REGNO (operands[4])
9631       && REGNO (operands[4]) != REGNO (operands[0]))
9632     {
9633       if (GET_CODE (operands[6]) == LT)
9634         return \"and\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\";
9635       else if (GET_CODE (operands[6]) == GE)
9636         return \"bic\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\";
9637     }
9638   if (CONST_INT_P (operands[3])
9639       && !const_ok_for_arm (INTVAL (operands[3])))
9640     output_asm_insn (\"cmn\\t%2, #%n3\", operands);
9641   else
9642     output_asm_insn (\"cmp\\t%2, %3\", operands);
9643   output_asm_insn (\"%I7%d6\\t%0, %4, %5\", operands);
9644   if (which_alternative != 0)
9645     return \"mov%D6\\t%0, %1\";
9646   return \"\";
9647   "
9648   [(set_attr "conds" "clob")
9649    (set_attr "length" "8,12")
9650    (set_attr "type" "multiple")]
9653 (define_insn "*if_arith_move"
9654   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9655         (if_then_else:SI (match_operator 4 "arm_comparison_operator"
9656                           [(match_operand 6 "cc_register" "") (const_int 0)])
9657                          (match_operator:SI 5 "shiftable_operator"
9658                           [(match_operand:SI 2 "s_register_operand" "r,r")
9659                            (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
9660                          (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))]
9661   "TARGET_ARM"
9662   "@
9663    %I5%d4\\t%0, %2, %3
9664    %I5%d4\\t%0, %2, %3\;mov%D4\\t%0, %1"
9665   [(set_attr "conds" "use")
9666    (set_attr "length" "4,8")
9667    (set_attr_alternative "type"
9668                          [(if_then_else (match_operand 3 "const_int_operand" "")
9669                                         (const_string "alu_shift_imm" )
9670                                         (const_string "alu_shift_reg"))
9671                           (const_string "multiple")])]
9674 (define_insn "*ifcompare_move_arith"
9675   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9676         (if_then_else:SI (match_operator 6 "arm_comparison_operator"
9677                           [(match_operand:SI 4 "s_register_operand" "r,r")
9678                            (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
9679                          (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
9680                          (match_operator:SI 7 "shiftable_operator"
9681                           [(match_operand:SI 2 "s_register_operand" "r,r")
9682                            (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
9683    (clobber (reg:CC CC_REGNUM))]
9684   "TARGET_ARM"
9685   "*
9686   /* If we have an operation where (op x 0) is the identity operation and
9687      the conditional operator is LT or GE and we are comparing against zero and
9688      everything is in registers then we can do this in two instructions */
9689   if (operands[5] == const0_rtx
9690       && GET_CODE (operands[7]) != AND
9691       && REG_P (operands[3])
9692       && REG_P (operands[1])
9693       && REGNO (operands[1]) == REGNO (operands[2])
9694       && REGNO (operands[2]) != REGNO (operands[0]))
9695     {
9696       if (GET_CODE (operands[6]) == GE)
9697         return \"and\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\";
9698       else if (GET_CODE (operands[6]) == LT)
9699         return \"bic\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\";
9700     }
9702   if (CONST_INT_P (operands[5])
9703       && !const_ok_for_arm (INTVAL (operands[5])))
9704     output_asm_insn (\"cmn\\t%4, #%n5\", operands);
9705   else
9706     output_asm_insn (\"cmp\\t%4, %5\", operands);
9708   if (which_alternative != 0)
9709     output_asm_insn (\"mov%d6\\t%0, %1\", operands);
9710   return \"%I7%D6\\t%0, %2, %3\";
9711   "
9712   [(set_attr "conds" "clob")
9713    (set_attr "length" "8,12")
9714    (set_attr "type" "multiple")]
9717 (define_insn "*if_move_arith"
9718   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9719         (if_then_else:SI
9720          (match_operator 4 "arm_comparison_operator"
9721           [(match_operand 6 "cc_register" "") (const_int 0)])
9722          (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
9723          (match_operator:SI 5 "shiftable_operator"
9724           [(match_operand:SI 2 "s_register_operand" "r,r")
9725            (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))]
9726   "TARGET_ARM"
9727   "@
9728    %I5%D4\\t%0, %2, %3
9729    %I5%D4\\t%0, %2, %3\;mov%d4\\t%0, %1"
9730   [(set_attr "conds" "use")
9731    (set_attr "length" "4,8")
9732    (set_attr_alternative "type"
9733                          [(if_then_else (match_operand 3 "const_int_operand" "")
9734                                         (const_string "alu_shift_imm" )
9735                                         (const_string "alu_shift_reg"))
9736                           (const_string "multiple")])]
9739 (define_insn "*ifcompare_move_not"
9740   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9741         (if_then_else:SI
9742          (match_operator 5 "arm_comparison_operator"
9743           [(match_operand:SI 3 "s_register_operand" "r,r")
9744            (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
9745          (match_operand:SI 1 "arm_not_operand" "0,?rIK")
9746          (not:SI
9747           (match_operand:SI 2 "s_register_operand" "r,r"))))
9748    (clobber (reg:CC CC_REGNUM))]
9749   "TARGET_ARM"
9750   "#"
9751   [(set_attr "conds" "clob")
9752    (set_attr "length" "8,12")
9753    (set_attr "type" "multiple")]
9756 (define_insn "*if_move_not"
9757   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9758         (if_then_else:SI
9759          (match_operator 4 "arm_comparison_operator"
9760           [(match_operand 3 "cc_register" "") (const_int 0)])
9761          (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
9762          (not:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))))]
9763   "TARGET_ARM"
9764   "@
9765    mvn%D4\\t%0, %2
9766    mov%d4\\t%0, %1\;mvn%D4\\t%0, %2
9767    mvn%d4\\t%0, #%B1\;mvn%D4\\t%0, %2"
9768   [(set_attr "conds" "use")
9769    (set_attr "type" "mvn_reg")
9770    (set_attr "length" "4,8,8")
9771    (set_attr "type" "mvn_reg,multiple,multiple")]
9774 (define_insn "*ifcompare_not_move"
9775   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9776         (if_then_else:SI 
9777          (match_operator 5 "arm_comparison_operator"
9778           [(match_operand:SI 3 "s_register_operand" "r,r")
9779            (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
9780          (not:SI
9781           (match_operand:SI 2 "s_register_operand" "r,r"))
9782          (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
9783    (clobber (reg:CC CC_REGNUM))]
9784   "TARGET_ARM"
9785   "#"
9786   [(set_attr "conds" "clob")
9787    (set_attr "length" "8,12")
9788    (set_attr "type" "multiple")]
9791 (define_insn "*if_not_move"
9792   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9793         (if_then_else:SI
9794          (match_operator 4 "arm_comparison_operator"
9795           [(match_operand 3 "cc_register" "") (const_int 0)])
9796          (not:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))
9797          (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
9798   "TARGET_ARM"
9799   "@
9800    mvn%d4\\t%0, %2
9801    mov%D4\\t%0, %1\;mvn%d4\\t%0, %2
9802    mvn%D4\\t%0, #%B1\;mvn%d4\\t%0, %2"
9803   [(set_attr "conds" "use")
9804    (set_attr "type" "mvn_reg,multiple,multiple")
9805    (set_attr "length" "4,8,8")]
9808 (define_insn "*ifcompare_shift_move"
9809   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9810         (if_then_else:SI
9811          (match_operator 6 "arm_comparison_operator"
9812           [(match_operand:SI 4 "s_register_operand" "r,r")
9813            (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
9814          (match_operator:SI 7 "shift_operator"
9815           [(match_operand:SI 2 "s_register_operand" "r,r")
9816            (match_operand:SI 3 "arm_rhs_operand" "rM,rM")])
9817          (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
9818    (clobber (reg:CC CC_REGNUM))]
9819   "TARGET_ARM"
9820   "#"
9821   [(set_attr "conds" "clob")
9822    (set_attr "length" "8,12")
9823    (set_attr "type" "multiple")]
9826 (define_insn "*if_shift_move"
9827   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9828         (if_then_else:SI
9829          (match_operator 5 "arm_comparison_operator"
9830           [(match_operand 6 "cc_register" "") (const_int 0)])
9831          (match_operator:SI 4 "shift_operator"
9832           [(match_operand:SI 2 "s_register_operand" "r,r,r")
9833            (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM")])
9834          (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
9835   "TARGET_ARM"
9836   "@
9837    mov%d5\\t%0, %2%S4
9838    mov%D5\\t%0, %1\;mov%d5\\t%0, %2%S4
9839    mvn%D5\\t%0, #%B1\;mov%d5\\t%0, %2%S4"
9840   [(set_attr "conds" "use")
9841    (set_attr "shift" "2")
9842    (set_attr "length" "4,8,8")
9843    (set_attr_alternative "type"
9844                          [(if_then_else (match_operand 3 "const_int_operand" "")
9845                                         (const_string "mov_shift" )
9846                                         (const_string "mov_shift_reg"))
9847                           (const_string "multiple")
9848                           (const_string "multiple")])]
9851 (define_insn "*ifcompare_move_shift"
9852   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9853         (if_then_else:SI
9854          (match_operator 6 "arm_comparison_operator"
9855           [(match_operand:SI 4 "s_register_operand" "r,r")
9856            (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
9857          (match_operand:SI 1 "arm_not_operand" "0,?rIK")
9858          (match_operator:SI 7 "shift_operator"
9859           [(match_operand:SI 2 "s_register_operand" "r,r")
9860            (match_operand:SI 3 "arm_rhs_operand" "rM,rM")])))
9861    (clobber (reg:CC CC_REGNUM))]
9862   "TARGET_ARM"
9863   "#"
9864   [(set_attr "conds" "clob")
9865    (set_attr "length" "8,12")
9866    (set_attr "type" "multiple")]
9869 (define_insn "*if_move_shift"
9870   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9871         (if_then_else:SI
9872          (match_operator 5 "arm_comparison_operator"
9873           [(match_operand 6 "cc_register" "") (const_int 0)])
9874          (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
9875          (match_operator:SI 4 "shift_operator"
9876           [(match_operand:SI 2 "s_register_operand" "r,r,r")
9877            (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM")])))]
9878   "TARGET_ARM"
9879   "@
9880    mov%D5\\t%0, %2%S4
9881    mov%d5\\t%0, %1\;mov%D5\\t%0, %2%S4
9882    mvn%d5\\t%0, #%B1\;mov%D5\\t%0, %2%S4"
9883   [(set_attr "conds" "use")
9884    (set_attr "shift" "2")
9885    (set_attr "length" "4,8,8")
9886    (set_attr_alternative "type"
9887                          [(if_then_else (match_operand 3 "const_int_operand" "")
9888                                         (const_string "mov_shift" )
9889                                         (const_string "mov_shift_reg"))
9890                           (const_string "multiple")
9891                           (const_string "multiple")])]
9894 (define_insn "*ifcompare_shift_shift"
9895   [(set (match_operand:SI 0 "s_register_operand" "=r")
9896         (if_then_else:SI
9897          (match_operator 7 "arm_comparison_operator"
9898           [(match_operand:SI 5 "s_register_operand" "r")
9899            (match_operand:SI 6 "arm_add_operand" "rIL")])
9900          (match_operator:SI 8 "shift_operator"
9901           [(match_operand:SI 1 "s_register_operand" "r")
9902            (match_operand:SI 2 "arm_rhs_operand" "rM")])
9903          (match_operator:SI 9 "shift_operator"
9904           [(match_operand:SI 3 "s_register_operand" "r")
9905            (match_operand:SI 4 "arm_rhs_operand" "rM")])))
9906    (clobber (reg:CC CC_REGNUM))]
9907   "TARGET_ARM"
9908   "#"
9909   [(set_attr "conds" "clob")
9910    (set_attr "length" "12")
9911    (set_attr "type" "multiple")]
9914 (define_insn "*if_shift_shift"
9915   [(set (match_operand:SI 0 "s_register_operand" "=r")
9916         (if_then_else:SI
9917          (match_operator 5 "arm_comparison_operator"
9918           [(match_operand 8 "cc_register" "") (const_int 0)])
9919          (match_operator:SI 6 "shift_operator"
9920           [(match_operand:SI 1 "s_register_operand" "r")
9921            (match_operand:SI 2 "arm_rhs_operand" "rM")])
9922          (match_operator:SI 7 "shift_operator"
9923           [(match_operand:SI 3 "s_register_operand" "r")
9924            (match_operand:SI 4 "arm_rhs_operand" "rM")])))]
9925   "TARGET_ARM"
9926   "mov%d5\\t%0, %1%S6\;mov%D5\\t%0, %3%S7"
9927   [(set_attr "conds" "use")
9928    (set_attr "shift" "1")
9929    (set_attr "length" "8")
9930    (set (attr "type") (if_then_else
9931                         (and (match_operand 2 "const_int_operand" "")
9932                              (match_operand 4 "const_int_operand" ""))
9933                       (const_string "mov_shift")
9934                       (const_string "mov_shift_reg")))]
9937 (define_insn "*ifcompare_not_arith"
9938   [(set (match_operand:SI 0 "s_register_operand" "=r")
9939         (if_then_else:SI
9940          (match_operator 6 "arm_comparison_operator"
9941           [(match_operand:SI 4 "s_register_operand" "r")
9942            (match_operand:SI 5 "arm_add_operand" "rIL")])
9943          (not:SI (match_operand:SI 1 "s_register_operand" "r"))
9944          (match_operator:SI 7 "shiftable_operator"
9945           [(match_operand:SI 2 "s_register_operand" "r")
9946            (match_operand:SI 3 "arm_rhs_operand" "rI")])))
9947    (clobber (reg:CC CC_REGNUM))]
9948   "TARGET_ARM"
9949   "#"
9950   [(set_attr "conds" "clob")
9951    (set_attr "length" "12")
9952    (set_attr "type" "multiple")]
9955 (define_insn "*if_not_arith"
9956   [(set (match_operand:SI 0 "s_register_operand" "=r")
9957         (if_then_else:SI
9958          (match_operator 5 "arm_comparison_operator"
9959           [(match_operand 4 "cc_register" "") (const_int 0)])
9960          (not:SI (match_operand:SI 1 "s_register_operand" "r"))
9961          (match_operator:SI 6 "shiftable_operator"
9962           [(match_operand:SI 2 "s_register_operand" "r")
9963            (match_operand:SI 3 "arm_rhs_operand" "rI")])))]
9964   "TARGET_ARM"
9965   "mvn%d5\\t%0, %1\;%I6%D5\\t%0, %2, %3"
9966   [(set_attr "conds" "use")
9967    (set_attr "type" "mvn_reg")
9968    (set_attr "length" "8")]
9971 (define_insn "*ifcompare_arith_not"
9972   [(set (match_operand:SI 0 "s_register_operand" "=r")
9973         (if_then_else:SI
9974          (match_operator 6 "arm_comparison_operator"
9975           [(match_operand:SI 4 "s_register_operand" "r")
9976            (match_operand:SI 5 "arm_add_operand" "rIL")])
9977          (match_operator:SI 7 "shiftable_operator"
9978           [(match_operand:SI 2 "s_register_operand" "r")
9979            (match_operand:SI 3 "arm_rhs_operand" "rI")])
9980          (not:SI (match_operand:SI 1 "s_register_operand" "r"))))
9981    (clobber (reg:CC CC_REGNUM))]
9982   "TARGET_ARM"
9983   "#"
9984   [(set_attr "conds" "clob")
9985    (set_attr "length" "12")
9986    (set_attr "type" "multiple")]
9989 (define_insn "*if_arith_not"
9990   [(set (match_operand:SI 0 "s_register_operand" "=r")
9991         (if_then_else:SI
9992          (match_operator 5 "arm_comparison_operator"
9993           [(match_operand 4 "cc_register" "") (const_int 0)])
9994          (match_operator:SI 6 "shiftable_operator"
9995           [(match_operand:SI 2 "s_register_operand" "r")
9996            (match_operand:SI 3 "arm_rhs_operand" "rI")])
9997          (not:SI (match_operand:SI 1 "s_register_operand" "r"))))]
9998   "TARGET_ARM"
9999   "mvn%D5\\t%0, %1\;%I6%d5\\t%0, %2, %3"
10000   [(set_attr "conds" "use")
10001    (set_attr "type" "multiple")
10002    (set_attr "length" "8")]
10005 (define_insn "*ifcompare_neg_move"
10006   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10007         (if_then_else:SI
10008          (match_operator 5 "arm_comparison_operator"
10009           [(match_operand:SI 3 "s_register_operand" "r,r")
10010            (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
10011          (neg:SI (match_operand:SI 2 "s_register_operand" "r,r"))
10012          (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
10013    (clobber (reg:CC CC_REGNUM))]
10014   "TARGET_ARM"
10015   "#"
10016   [(set_attr "conds" "clob")
10017    (set_attr "length" "8,12")
10018    (set_attr "type" "multiple")]
10021 (define_insn_and_split "*if_neg_move"
10022   [(set (match_operand:SI 0 "s_register_operand" "=l,r")
10023         (if_then_else:SI
10024          (match_operator 4 "arm_comparison_operator"
10025           [(match_operand 3 "cc_register" "") (const_int 0)])
10026          (neg:SI (match_operand:SI 2 "s_register_operand" "l,r"))
10027          (match_operand:SI 1 "s_register_operand" "0,0")))]
10028   "TARGET_32BIT"
10029   "#"
10030   "&& reload_completed"
10031   [(cond_exec (match_op_dup 4 [(match_dup 3) (const_int 0)])
10032               (set (match_dup 0) (neg:SI (match_dup 2))))]
10033   ""
10034   [(set_attr "conds" "use")
10035    (set_attr "length" "4")
10036    (set_attr "arch" "t2,32")
10037    (set_attr "enabled_for_depr_it" "yes,no")
10038    (set_attr "type" "logic_shift_imm")]
10041 (define_insn "*ifcompare_move_neg"
10042   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10043         (if_then_else:SI
10044          (match_operator 5 "arm_comparison_operator"
10045           [(match_operand:SI 3 "s_register_operand" "r,r")
10046            (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
10047          (match_operand:SI 1 "arm_not_operand" "0,?rIK")
10048          (neg:SI (match_operand:SI 2 "s_register_operand" "r,r"))))
10049    (clobber (reg:CC CC_REGNUM))]
10050   "TARGET_ARM"
10051   "#"
10052   [(set_attr "conds" "clob")
10053    (set_attr "length" "8,12")
10054    (set_attr "type" "multiple")]
10057 (define_insn_and_split "*if_move_neg"
10058   [(set (match_operand:SI 0 "s_register_operand" "=l,r")
10059         (if_then_else:SI
10060          (match_operator 4 "arm_comparison_operator"
10061           [(match_operand 3 "cc_register" "") (const_int 0)])
10062          (match_operand:SI 1 "s_register_operand" "0,0")
10063          (neg:SI (match_operand:SI 2 "s_register_operand" "l,r"))))]
10064   "TARGET_32BIT"
10065   "#"
10066   "&& reload_completed"
10067   [(cond_exec (match_dup 5)
10068               (set (match_dup 0) (neg:SI (match_dup 2))))]
10069   {
10070     machine_mode mode = GET_MODE (operands[3]);
10071     rtx_code rc = GET_CODE (operands[4]);
10073     if (mode == CCFPmode || mode == CCFPEmode)
10074       rc = reverse_condition_maybe_unordered (rc);
10075     else
10076       rc = reverse_condition (rc);
10078     operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[3], const0_rtx);
10079   }
10080   [(set_attr "conds" "use")
10081    (set_attr "length" "4")
10082    (set_attr "arch" "t2,32")
10083    (set_attr "enabled_for_depr_it" "yes,no")
10084    (set_attr "type" "logic_shift_imm")]
10087 (define_insn "*arith_adjacentmem"
10088   [(set (match_operand:SI 0 "s_register_operand" "=r")
10089         (match_operator:SI 1 "shiftable_operator"
10090          [(match_operand:SI 2 "memory_operand" "m")
10091           (match_operand:SI 3 "memory_operand" "m")]))
10092    (clobber (match_scratch:SI 4 "=r"))]
10093   "TARGET_ARM && adjacent_mem_locations (operands[2], operands[3])"
10094   "*
10095   {
10096     rtx ldm[3];
10097     rtx arith[4];
10098     rtx base_reg;
10099     HOST_WIDE_INT val1 = 0, val2 = 0;
10101     if (REGNO (operands[0]) > REGNO (operands[4]))
10102       {
10103         ldm[1] = operands[4];
10104         ldm[2] = operands[0];
10105       }
10106     else
10107       {
10108         ldm[1] = operands[0];
10109         ldm[2] = operands[4];
10110       }
10112     base_reg = XEXP (operands[2], 0);
10114     if (!REG_P (base_reg))
10115       {
10116         val1 = INTVAL (XEXP (base_reg, 1));
10117         base_reg = XEXP (base_reg, 0);
10118       }
10120     if (!REG_P (XEXP (operands[3], 0)))
10121       val2 = INTVAL (XEXP (XEXP (operands[3], 0), 1));
10123     arith[0] = operands[0];
10124     arith[3] = operands[1];
10126     if (val1 < val2)
10127       {
10128         arith[1] = ldm[1];
10129         arith[2] = ldm[2];
10130       }
10131     else
10132       {
10133         arith[1] = ldm[2];
10134         arith[2] = ldm[1];
10135       }
10137     ldm[0] = base_reg;
10138     if (val1 !=0 && val2 != 0)
10139       {
10140         rtx ops[3];
10142         if (val1 == 4 || val2 == 4)
10143           /* Other val must be 8, since we know they are adjacent and neither
10144              is zero.  */
10145           output_asm_insn (\"ldmib%?\\t%0, {%1, %2}\", ldm);
10146         else if (const_ok_for_arm (val1) || const_ok_for_arm (-val1))
10147           {
10148             ldm[0] = ops[0] = operands[4];
10149             ops[1] = base_reg;
10150             ops[2] = GEN_INT (val1);
10151             output_add_immediate (ops);
10152             if (val1 < val2)
10153               output_asm_insn (\"ldmia%?\\t%0, {%1, %2}\", ldm);
10154             else
10155               output_asm_insn (\"ldmda%?\\t%0, {%1, %2}\", ldm);
10156           }
10157         else
10158           {
10159             /* Offset is out of range for a single add, so use two ldr.  */
10160             ops[0] = ldm[1];
10161             ops[1] = base_reg;
10162             ops[2] = GEN_INT (val1);
10163             output_asm_insn (\"ldr%?\\t%0, [%1, %2]\", ops);
10164             ops[0] = ldm[2];
10165             ops[2] = GEN_INT (val2);
10166             output_asm_insn (\"ldr%?\\t%0, [%1, %2]\", ops);
10167           }
10168       }
10169     else if (val1 != 0)
10170       {
10171         if (val1 < val2)
10172           output_asm_insn (\"ldmda%?\\t%0, {%1, %2}\", ldm);
10173         else
10174           output_asm_insn (\"ldmia%?\\t%0, {%1, %2}\", ldm);
10175       }
10176     else
10177       {
10178         if (val1 < val2)
10179           output_asm_insn (\"ldmia%?\\t%0, {%1, %2}\", ldm);
10180         else
10181           output_asm_insn (\"ldmda%?\\t%0, {%1, %2}\", ldm);
10182       }
10183     output_asm_insn (\"%I3%?\\t%0, %1, %2\", arith);
10184     return \"\";
10185   }"
10186   [(set_attr "length" "12")
10187    (set_attr "predicable" "yes")
10188    (set_attr "type" "load1")]
10191 ; This pattern is never tried by combine, so do it as a peephole
10193 (define_peephole2
10194   [(set (match_operand:SI 0 "arm_general_register_operand" "")
10195         (match_operand:SI 1 "arm_general_register_operand" ""))
10196    (set (reg:CC CC_REGNUM)
10197         (compare:CC (match_dup 1) (const_int 0)))]
10198   "TARGET_ARM"
10199   [(parallel [(set (reg:CC CC_REGNUM) (compare:CC (match_dup 1) (const_int 0)))
10200               (set (match_dup 0) (match_dup 1))])]
10201   ""
10204 (define_split
10205   [(set (match_operand:SI 0 "s_register_operand" "")
10206         (and:SI (ge:SI (match_operand:SI 1 "s_register_operand" "")
10207                        (const_int 0))
10208                 (neg:SI (match_operator:SI 2 "arm_comparison_operator"
10209                          [(match_operand:SI 3 "s_register_operand" "")
10210                           (match_operand:SI 4 "arm_rhs_operand" "")]))))
10211    (clobber (match_operand:SI 5 "s_register_operand" ""))]
10212   "TARGET_ARM"
10213   [(set (match_dup 5) (not:SI (ashiftrt:SI (match_dup 1) (const_int 31))))
10214    (set (match_dup 0) (and:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
10215                               (match_dup 5)))]
10216   ""
10219 ;; This split can be used because CC_Z mode implies that the following
10220 ;; branch will be an equality, or an unsigned inequality, so the sign
10221 ;; extension is not needed.
10223 (define_split
10224   [(set (reg:CC_Z CC_REGNUM)
10225         (compare:CC_Z
10226          (ashift:SI (subreg:SI (match_operand:QI 0 "memory_operand" "") 0)
10227                     (const_int 24))
10228          (match_operand 1 "const_int_operand" "")))
10229    (clobber (match_scratch:SI 2 ""))]
10230   "TARGET_ARM
10231    && ((UINTVAL (operands[1]))
10232        == ((UINTVAL (operands[1])) >> 24) << 24)"
10233   [(set (match_dup 2) (zero_extend:SI (match_dup 0)))
10234    (set (reg:CC CC_REGNUM) (compare:CC (match_dup 2) (match_dup 1)))]
10235   "
10236   operands[1] = GEN_INT (((unsigned long) INTVAL (operands[1])) >> 24);
10237   "
10239 ;; ??? Check the patterns above for Thumb-2 usefulness
10241 (define_expand "prologue"
10242   [(clobber (const_int 0))]
10243   "TARGET_EITHER"
10244   "if (TARGET_32BIT)
10245      arm_expand_prologue ();
10246    else
10247      thumb1_expand_prologue ();
10248   DONE;
10249   "
10252 (define_expand "epilogue"
10253   [(clobber (const_int 0))]
10254   "TARGET_EITHER"
10255   "
10256   if (crtl->calls_eh_return)
10257     emit_insn (gen_force_register_use (gen_rtx_REG (Pmode, 2)));
10258   if (TARGET_THUMB1)
10259    {
10260      thumb1_expand_epilogue ();
10261      emit_jump_insn (gen_rtx_UNSPEC_VOLATILE (VOIDmode,
10262                      gen_rtvec (1, ret_rtx), VUNSPEC_EPILOGUE));
10263    }
10264   else if (HAVE_return)
10265    {
10266      /* HAVE_return is testing for USE_RETURN_INSN (FALSE).  Hence,
10267         no need for explicit testing again.  */
10268      emit_jump_insn (gen_return ());
10269    }
10270   else if (TARGET_32BIT)
10271    {
10272     arm_expand_epilogue (true);
10273    }
10274   DONE;
10275   "
10278 ;; Note - although unspec_volatile's USE all hard registers,
10279 ;; USEs are ignored after relaod has completed.  Thus we need
10280 ;; to add an unspec of the link register to ensure that flow
10281 ;; does not think that it is unused by the sibcall branch that
10282 ;; will replace the standard function epilogue.
10283 (define_expand "sibcall_epilogue"
10284    [(parallel [(unspec:SI [(reg:SI LR_REGNUM)] UNSPEC_REGISTER_USE)
10285                (unspec_volatile [(return)] VUNSPEC_EPILOGUE)])]
10286    "TARGET_32BIT"
10287    "
10288    arm_expand_epilogue (false);
10289    DONE;
10290    "
10293 (define_expand "eh_epilogue"
10294   [(use (match_operand:SI 0 "register_operand" ""))
10295    (use (match_operand:SI 1 "register_operand" ""))
10296    (use (match_operand:SI 2 "register_operand" ""))]
10297   "TARGET_EITHER"
10298   "
10299   {
10300     cfun->machine->eh_epilogue_sp_ofs = operands[1];
10301     if (!REG_P (operands[2]) || REGNO (operands[2]) != 2)
10302       {
10303         rtx ra = gen_rtx_REG (Pmode, 2);
10305         emit_move_insn (ra, operands[2]);
10306         operands[2] = ra;
10307       }
10308     /* This is a hack -- we may have crystalized the function type too
10309        early.  */
10310     cfun->machine->func_type = 0;
10311   }"
10314 ;; This split is only used during output to reduce the number of patterns
10315 ;; that need assembler instructions adding to them.  We allowed the setting
10316 ;; of the conditions to be implicit during rtl generation so that
10317 ;; the conditional compare patterns would work.  However this conflicts to
10318 ;; some extent with the conditional data operations, so we have to split them
10319 ;; up again here.
10321 ;; ??? Need to audit these splitters for Thumb-2.  Why isn't normal
10322 ;; conditional execution sufficient?
10324 (define_split
10325   [(set (match_operand:SI 0 "s_register_operand" "")
10326         (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10327                           [(match_operand 2 "" "") (match_operand 3 "" "")])
10328                          (match_dup 0)
10329                          (match_operand 4 "" "")))
10330    (clobber (reg:CC CC_REGNUM))]
10331   "TARGET_ARM && reload_completed"
10332   [(set (match_dup 5) (match_dup 6))
10333    (cond_exec (match_dup 7)
10334               (set (match_dup 0) (match_dup 4)))]
10335   "
10336   {
10337     machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10338                                              operands[2], operands[3]);
10339     enum rtx_code rc = GET_CODE (operands[1]);
10341     operands[5] = gen_rtx_REG (mode, CC_REGNUM);
10342     operands[6] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10343     if (mode == CCFPmode || mode == CCFPEmode)
10344       rc = reverse_condition_maybe_unordered (rc);
10345     else
10346       rc = reverse_condition (rc);
10348     operands[7] = gen_rtx_fmt_ee (rc, VOIDmode, operands[5], const0_rtx);
10349   }"
10352 (define_split
10353   [(set (match_operand:SI 0 "s_register_operand" "")
10354         (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10355                           [(match_operand 2 "" "") (match_operand 3 "" "")])
10356                          (match_operand 4 "" "")
10357                          (match_dup 0)))
10358    (clobber (reg:CC CC_REGNUM))]
10359   "TARGET_ARM && reload_completed"
10360   [(set (match_dup 5) (match_dup 6))
10361    (cond_exec (match_op_dup 1 [(match_dup 5) (const_int 0)])
10362               (set (match_dup 0) (match_dup 4)))]
10363   "
10364   {
10365     machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10366                                              operands[2], operands[3]);
10368     operands[5] = gen_rtx_REG (mode, CC_REGNUM);
10369     operands[6] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10370   }"
10373 (define_split
10374   [(set (match_operand:SI 0 "s_register_operand" "")
10375         (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10376                           [(match_operand 2 "" "") (match_operand 3 "" "")])
10377                          (match_operand 4 "" "")
10378                          (match_operand 5 "" "")))
10379    (clobber (reg:CC CC_REGNUM))]
10380   "TARGET_ARM && reload_completed"
10381   [(set (match_dup 6) (match_dup 7))
10382    (cond_exec (match_op_dup 1 [(match_dup 6) (const_int 0)])
10383               (set (match_dup 0) (match_dup 4)))
10384    (cond_exec (match_dup 8)
10385               (set (match_dup 0) (match_dup 5)))]
10386   "
10387   {
10388     machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10389                                              operands[2], operands[3]);
10390     enum rtx_code rc = GET_CODE (operands[1]);
10392     operands[6] = gen_rtx_REG (mode, CC_REGNUM);
10393     operands[7] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10394     if (mode == CCFPmode || mode == CCFPEmode)
10395       rc = reverse_condition_maybe_unordered (rc);
10396     else
10397       rc = reverse_condition (rc);
10399     operands[8] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
10400   }"
10403 (define_split
10404   [(set (match_operand:SI 0 "s_register_operand" "")
10405         (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10406                           [(match_operand:SI 2 "s_register_operand" "")
10407                            (match_operand:SI 3 "arm_add_operand" "")])
10408                          (match_operand:SI 4 "arm_rhs_operand" "")
10409                          (not:SI
10410                           (match_operand:SI 5 "s_register_operand" ""))))
10411    (clobber (reg:CC CC_REGNUM))]
10412   "TARGET_ARM && reload_completed"
10413   [(set (match_dup 6) (match_dup 7))
10414    (cond_exec (match_op_dup 1 [(match_dup 6) (const_int 0)])
10415               (set (match_dup 0) (match_dup 4)))
10416    (cond_exec (match_dup 8)
10417               (set (match_dup 0) (not:SI (match_dup 5))))]
10418   "
10419   {
10420     machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10421                                              operands[2], operands[3]);
10422     enum rtx_code rc = GET_CODE (operands[1]);
10424     operands[6] = gen_rtx_REG (mode, CC_REGNUM);
10425     operands[7] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10426     if (mode == CCFPmode || mode == CCFPEmode)
10427       rc = reverse_condition_maybe_unordered (rc);
10428     else
10429       rc = reverse_condition (rc);
10431     operands[8] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
10432   }"
10435 (define_insn "*cond_move_not"
10436   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10437         (if_then_else:SI (match_operator 4 "arm_comparison_operator"
10438                           [(match_operand 3 "cc_register" "") (const_int 0)])
10439                          (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
10440                          (not:SI
10441                           (match_operand:SI 2 "s_register_operand" "r,r"))))]
10442   "TARGET_ARM"
10443   "@
10444    mvn%D4\\t%0, %2
10445    mov%d4\\t%0, %1\;mvn%D4\\t%0, %2"
10446   [(set_attr "conds" "use")
10447    (set_attr "type" "mvn_reg,multiple")
10448    (set_attr "length" "4,8")]
10451 ;; The next two patterns occur when an AND operation is followed by a
10452 ;; scc insn sequence 
10454 (define_insn "*sign_extract_onebit"
10455   [(set (match_operand:SI 0 "s_register_operand" "=r")
10456         (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
10457                          (const_int 1)
10458                          (match_operand:SI 2 "const_int_operand" "n")))
10459     (clobber (reg:CC CC_REGNUM))]
10460   "TARGET_ARM"
10461   "*
10462     operands[2] = GEN_INT (1 << INTVAL (operands[2]));
10463     output_asm_insn (\"ands\\t%0, %1, %2\", operands);
10464     return \"mvnne\\t%0, #0\";
10465   "
10466   [(set_attr "conds" "clob")
10467    (set_attr "length" "8")
10468    (set_attr "type" "multiple")]
10471 (define_insn "*not_signextract_onebit"
10472   [(set (match_operand:SI 0 "s_register_operand" "=r")
10473         (not:SI
10474          (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
10475                           (const_int 1)
10476                           (match_operand:SI 2 "const_int_operand" "n"))))
10477    (clobber (reg:CC CC_REGNUM))]
10478   "TARGET_ARM"
10479   "*
10480     operands[2] = GEN_INT (1 << INTVAL (operands[2]));
10481     output_asm_insn (\"tst\\t%1, %2\", operands);
10482     output_asm_insn (\"mvneq\\t%0, #0\", operands);
10483     return \"movne\\t%0, #0\";
10484   "
10485   [(set_attr "conds" "clob")
10486    (set_attr "length" "12")
10487    (set_attr "type" "multiple")]
10489 ;; ??? The above patterns need auditing for Thumb-2
10491 ;; Push multiple registers to the stack.  Registers are in parallel (use ...)
10492 ;; expressions.  For simplicity, the first register is also in the unspec
10493 ;; part.
10494 ;; To avoid the usage of GNU extension, the length attribute is computed
10495 ;; in a C function arm_attr_length_push_multi.
10496 (define_insn "*push_multi"
10497   [(match_parallel 2 "multi_register_push"
10498     [(set (match_operand:BLK 0 "push_mult_memory_operand" "")
10499           (unspec:BLK [(match_operand:SI 1 "s_register_operand" "")]
10500                       UNSPEC_PUSH_MULT))])]
10501   ""
10502   "*
10503   {
10504     int num_saves = XVECLEN (operands[2], 0);
10505      
10506     /* For the StrongARM at least it is faster to
10507        use STR to store only a single register.
10508        In Thumb mode always use push, and the assembler will pick
10509        something appropriate.  */
10510     if (num_saves == 1 && TARGET_ARM)
10511       output_asm_insn (\"str%?\\t%1, [%m0, #-4]!\", operands);
10512     else
10513       {
10514         int i;
10515         char pattern[100];
10517         if (TARGET_32BIT)
10518             strcpy (pattern, \"push%?\\t{%1\");
10519         else
10520             strcpy (pattern, \"push\\t{%1\");
10522         for (i = 1; i < num_saves; i++)
10523           {
10524             strcat (pattern, \", %|\");
10525             strcat (pattern,
10526                     reg_names[REGNO (XEXP (XVECEXP (operands[2], 0, i), 0))]);
10527           }
10529         strcat (pattern, \"}\");
10530         output_asm_insn (pattern, operands);
10531       }
10533     return \"\";
10534   }"
10535   [(set_attr "type" "store4")
10536    (set (attr "length")
10537         (symbol_ref "arm_attr_length_push_multi (operands[2], operands[1])"))]
10540 (define_insn "stack_tie"
10541   [(set (mem:BLK (scratch))
10542         (unspec:BLK [(match_operand:SI 0 "s_register_operand" "rk")
10543                      (match_operand:SI 1 "s_register_operand" "rk")]
10544                     UNSPEC_PRLG_STK))]
10545   ""
10546   ""
10547   [(set_attr "length" "0")
10548    (set_attr "type" "block")]
10551 ;; Pop (as used in epilogue RTL)
10553 (define_insn "*load_multiple_with_writeback"
10554   [(match_parallel 0 "load_multiple_operation"
10555     [(set (match_operand:SI 1 "s_register_operand" "+rk")
10556           (plus:SI (match_dup 1)
10557                    (match_operand:SI 2 "const_int_I_operand" "I")))
10558      (set (match_operand:SI 3 "s_register_operand" "=rk")
10559           (mem:SI (match_dup 1)))
10560         ])]
10561   "TARGET_32BIT && (reload_in_progress || reload_completed)"
10562   "*
10563   {
10564     arm_output_multireg_pop (operands, /*return_pc=*/false,
10565                                        /*cond=*/const_true_rtx,
10566                                        /*reverse=*/false,
10567                                        /*update=*/true);
10568     return \"\";
10569   }
10570   "
10571   [(set_attr "type" "load4")
10572    (set_attr "predicable" "yes")
10573    (set (attr "length")
10574         (symbol_ref "arm_attr_length_pop_multi (operands,
10575                                                 /*return_pc=*/false,
10576                                                 /*write_back_p=*/true)"))]
10579 ;; Pop with return (as used in epilogue RTL)
10581 ;; This instruction is generated when the registers are popped at the end of
10582 ;; epilogue.  Here, instead of popping the value into LR and then generating
10583 ;; jump to LR, value is popped into PC directly.  Hence, the pattern is combined
10584 ;;  with (return).
10585 (define_insn "*pop_multiple_with_writeback_and_return"
10586   [(match_parallel 0 "pop_multiple_return"
10587     [(return)
10588      (set (match_operand:SI 1 "s_register_operand" "+rk")
10589           (plus:SI (match_dup 1)
10590                    (match_operand:SI 2 "const_int_I_operand" "I")))
10591      (set (match_operand:SI 3 "s_register_operand" "=rk")
10592           (mem:SI (match_dup 1)))
10593         ])]
10594   "TARGET_32BIT && (reload_in_progress || reload_completed)"
10595   "*
10596   {
10597     arm_output_multireg_pop (operands, /*return_pc=*/true,
10598                                        /*cond=*/const_true_rtx,
10599                                        /*reverse=*/false,
10600                                        /*update=*/true);
10601     return \"\";
10602   }
10603   "
10604   [(set_attr "type" "load4")
10605    (set_attr "predicable" "yes")
10606    (set (attr "length")
10607         (symbol_ref "arm_attr_length_pop_multi (operands, /*return_pc=*/true,
10608                                                 /*write_back_p=*/true)"))]
10611 (define_insn "*pop_multiple_with_return"
10612   [(match_parallel 0 "pop_multiple_return"
10613     [(return)
10614      (set (match_operand:SI 2 "s_register_operand" "=rk")
10615           (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
10616         ])]
10617   "TARGET_32BIT && (reload_in_progress || reload_completed)"
10618   "*
10619   {
10620     arm_output_multireg_pop (operands, /*return_pc=*/true,
10621                                        /*cond=*/const_true_rtx,
10622                                        /*reverse=*/false,
10623                                        /*update=*/false);
10624     return \"\";
10625   }
10626   "
10627   [(set_attr "type" "load4")
10628    (set_attr "predicable" "yes")
10629    (set (attr "length")
10630         (symbol_ref "arm_attr_length_pop_multi (operands, /*return_pc=*/true,
10631                                                 /*write_back_p=*/false)"))]
10634 ;; Load into PC and return
10635 (define_insn "*ldr_with_return"
10636   [(return)
10637    (set (reg:SI PC_REGNUM)
10638         (mem:SI (post_inc:SI (match_operand:SI 0 "s_register_operand" "+rk"))))]
10639   "TARGET_32BIT && (reload_in_progress || reload_completed)"
10640   "ldr%?\t%|pc, [%0], #4"
10641   [(set_attr "type" "load1")
10642    (set_attr "predicable" "yes")]
10644 ;; Pop for floating point registers (as used in epilogue RTL)
10645 (define_insn "*vfp_pop_multiple_with_writeback"
10646   [(match_parallel 0 "pop_multiple_fp"
10647     [(set (match_operand:SI 1 "s_register_operand" "+rk")
10648           (plus:SI (match_dup 1)
10649                    (match_operand:SI 2 "const_int_I_operand" "I")))
10650      (set (match_operand:DF 3 "vfp_hard_register_operand" "")
10651           (mem:DF (match_dup 1)))])]
10652   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
10653   "*
10654   {
10655     int num_regs = XVECLEN (operands[0], 0);
10656     char pattern[100];
10657     rtx op_list[2];
10658     strcpy (pattern, \"vldm\\t\");
10659     strcat (pattern, reg_names[REGNO (SET_DEST (XVECEXP (operands[0], 0, 0)))]);
10660     strcat (pattern, \"!, {\");
10661     op_list[0] = XEXP (XVECEXP (operands[0], 0, 1), 0);
10662     strcat (pattern, \"%P0\");
10663     if ((num_regs - 1) > 1)
10664       {
10665         strcat (pattern, \"-%P1\");
10666         op_list [1] = XEXP (XVECEXP (operands[0], 0, num_regs - 1), 0);
10667       }
10669     strcat (pattern, \"}\");
10670     output_asm_insn (pattern, op_list);
10671     return \"\";
10672   }
10673   "
10674   [(set_attr "type" "load4")
10675    (set_attr "conds" "unconditional")
10676    (set_attr "predicable" "no")]
10679 ;; Special patterns for dealing with the constant pool
10681 (define_insn "align_4"
10682   [(unspec_volatile [(const_int 0)] VUNSPEC_ALIGN)]
10683   "TARGET_EITHER"
10684   "*
10685   assemble_align (32);
10686   return \"\";
10687   "
10688   [(set_attr "type" "no_insn")]
10691 (define_insn "align_8"
10692   [(unspec_volatile [(const_int 0)] VUNSPEC_ALIGN8)]
10693   "TARGET_EITHER"
10694   "*
10695   assemble_align (64);
10696   return \"\";
10697   "
10698   [(set_attr "type" "no_insn")]
10701 (define_insn "consttable_end"
10702   [(unspec_volatile [(const_int 0)] VUNSPEC_POOL_END)]
10703   "TARGET_EITHER"
10704   "*
10705   making_const_table = FALSE;
10706   return \"\";
10707   "
10708   [(set_attr "type" "no_insn")]
10711 (define_insn "consttable_1"
10712   [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_1)]
10713   "TARGET_EITHER"
10714   "*
10715   making_const_table = TRUE;
10716   assemble_integer (operands[0], 1, BITS_PER_WORD, 1);
10717   assemble_zeros (3);
10718   return \"\";
10719   "
10720   [(set_attr "length" "4")
10721    (set_attr "type" "no_insn")]
10724 (define_insn "consttable_2"
10725   [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_2)]
10726   "TARGET_EITHER"
10727   "*
10728   {
10729     rtx x = operands[0];
10730     making_const_table = TRUE;
10731     switch (GET_MODE_CLASS (GET_MODE (x)))
10732       {
10733       case MODE_FLOAT:
10734         arm_emit_fp16_const (x);
10735         break;
10736       default:
10737         assemble_integer (operands[0], 2, BITS_PER_WORD, 1);
10738         assemble_zeros (2);
10739         break;
10740       }
10741     return \"\";
10742   }"
10743   [(set_attr "length" "4")
10744    (set_attr "type" "no_insn")]
10747 (define_insn "consttable_4"
10748   [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_4)]
10749   "TARGET_EITHER"
10750   "*
10751   {
10752     rtx x = operands[0];
10753     making_const_table = TRUE;
10754     switch (GET_MODE_CLASS (GET_MODE (x)))
10755       {
10756       case MODE_FLOAT:
10757         assemble_real (*CONST_DOUBLE_REAL_VALUE (x), GET_MODE (x),
10758                        BITS_PER_WORD);
10759         break;
10760       default:
10761         /* XXX: Sometimes gcc does something really dumb and ends up with
10762            a HIGH in a constant pool entry, usually because it's trying to
10763            load into a VFP register.  We know this will always be used in
10764            combination with a LO_SUM which ignores the high bits, so just
10765            strip off the HIGH.  */
10766         if (GET_CODE (x) == HIGH)
10767           x = XEXP (x, 0);
10768         assemble_integer (x, 4, BITS_PER_WORD, 1);
10769         mark_symbol_refs_as_used (x);
10770         break;
10771       }
10772     return \"\";
10773   }"
10774   [(set_attr "length" "4")
10775    (set_attr "type" "no_insn")]
10778 (define_insn "consttable_8"
10779   [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_8)]
10780   "TARGET_EITHER"
10781   "*
10782   {
10783     making_const_table = TRUE;
10784     switch (GET_MODE_CLASS (GET_MODE (operands[0])))
10785       {
10786       case MODE_FLOAT:
10787         assemble_real (*CONST_DOUBLE_REAL_VALUE (operands[0]),
10788                        GET_MODE (operands[0]), BITS_PER_WORD);
10789         break;
10790       default:
10791         assemble_integer (operands[0], 8, BITS_PER_WORD, 1);
10792         break;
10793       }
10794     return \"\";
10795   }"
10796   [(set_attr "length" "8")
10797    (set_attr "type" "no_insn")]
10800 (define_insn "consttable_16"
10801   [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_16)]
10802   "TARGET_EITHER"
10803   "*
10804   {
10805     making_const_table = TRUE;
10806     switch (GET_MODE_CLASS (GET_MODE (operands[0])))
10807       {
10808       case MODE_FLOAT:
10809         assemble_real (*CONST_DOUBLE_REAL_VALUE (operands[0]),
10810                        GET_MODE (operands[0]), BITS_PER_WORD);
10811         break;
10812       default:
10813         assemble_integer (operands[0], 16, BITS_PER_WORD, 1);
10814         break;
10815       }
10816     return \"\";
10817   }"
10818   [(set_attr "length" "16")
10819    (set_attr "type" "no_insn")]
10822 ;; V5 Instructions,
10824 (define_insn "clzsi2"
10825   [(set (match_operand:SI 0 "s_register_operand" "=r")
10826         (clz:SI (match_operand:SI 1 "s_register_operand" "r")))]
10827   "TARGET_32BIT && arm_arch5"
10828   "clz%?\\t%0, %1"
10829   [(set_attr "predicable" "yes")
10830    (set_attr "predicable_short_it" "no")
10831    (set_attr "type" "clz")])
10833 (define_insn "rbitsi2"
10834   [(set (match_operand:SI 0 "s_register_operand" "=r")
10835         (unspec:SI [(match_operand:SI 1 "s_register_operand" "r")] UNSPEC_RBIT))]
10836   "TARGET_32BIT && arm_arch_thumb2"
10837   "rbit%?\\t%0, %1"
10838   [(set_attr "predicable" "yes")
10839    (set_attr "predicable_short_it" "no")
10840    (set_attr "type" "clz")])
10842 ;; Keep this as a CTZ expression until after reload and then split
10843 ;; into RBIT + CLZ.  Since RBIT is represented as an UNSPEC it is unlikely
10844 ;; to fold with any other expression.
10846 (define_insn_and_split "ctzsi2"
10847  [(set (match_operand:SI           0 "s_register_operand" "=r")
10848        (ctz:SI (match_operand:SI  1 "s_register_operand" "r")))]
10849   "TARGET_32BIT && arm_arch_thumb2"
10850   "#"
10851   "&& reload_completed"
10852   [(const_int 0)]
10853   "
10854   emit_insn (gen_rbitsi2 (operands[0], operands[1]));
10855   emit_insn (gen_clzsi2 (operands[0], operands[0]));
10856   DONE;
10859 ;; V5E instructions.
10861 (define_insn "prefetch"
10862   [(prefetch (match_operand:SI 0 "address_operand" "p")
10863              (match_operand:SI 1 "" "")
10864              (match_operand:SI 2 "" ""))]
10865   "TARGET_32BIT && arm_arch5e"
10866   "pld\\t%a0"
10867   [(set_attr "type" "load1")]
10870 ;; General predication pattern
10872 (define_cond_exec
10873   [(match_operator 0 "arm_comparison_operator"
10874     [(match_operand 1 "cc_register" "")
10875      (const_int 0)])]
10876   "TARGET_32BIT
10877    && (!TARGET_NO_VOLATILE_CE || !volatile_refs_p (PATTERN (insn)))"
10878   ""
10879 [(set_attr "predicated" "yes")]
10882 (define_insn "force_register_use"
10883   [(unspec:SI [(match_operand:SI 0 "register_operand" "")] UNSPEC_REGISTER_USE)]
10884   ""
10885   "%@ %0 needed"
10886   [(set_attr "length" "0")
10887    (set_attr "type" "no_insn")]
10891 ;; Patterns for exception handling
10893 (define_expand "eh_return"
10894   [(use (match_operand 0 "general_operand" ""))]
10895   "TARGET_EITHER"
10896   "
10897   {
10898     if (TARGET_32BIT)
10899       emit_insn (gen_arm_eh_return (operands[0]));
10900     else
10901       emit_insn (gen_thumb_eh_return (operands[0]));
10902     DONE;
10903   }"
10905                                    
10906 ;; We can't expand this before we know where the link register is stored.
10907 (define_insn_and_split "arm_eh_return"
10908   [(unspec_volatile [(match_operand:SI 0 "s_register_operand" "r")]
10909                     VUNSPEC_EH_RETURN)
10910    (clobber (match_scratch:SI 1 "=&r"))]
10911   "TARGET_ARM"
10912   "#"
10913   "&& reload_completed"
10914   [(const_int 0)]
10915   "
10916   {
10917     arm_set_return_address (operands[0], operands[1]);
10918     DONE;
10919   }"
10923 ;; TLS support
10925 (define_insn "load_tp_hard"
10926   [(set (match_operand:SI 0 "register_operand" "=r")
10927         (unspec:SI [(const_int 0)] UNSPEC_TLS))]
10928   "TARGET_HARD_TP"
10929   "mrc%?\\tp15, 0, %0, c13, c0, 3\\t@ load_tp_hard"
10930   [(set_attr "predicable" "yes")
10931    (set_attr "type" "mrs")]
10934 ;; Doesn't clobber R1-R3.  Must use r0 for the first operand.
10935 (define_insn "load_tp_soft"
10936   [(set (reg:SI 0) (unspec:SI [(const_int 0)] UNSPEC_TLS))
10937    (clobber (reg:SI LR_REGNUM))
10938    (clobber (reg:SI IP_REGNUM))
10939    (clobber (reg:CC CC_REGNUM))]
10940   "TARGET_SOFT_TP"
10941   "bl\\t__aeabi_read_tp\\t@ load_tp_soft"
10942   [(set_attr "conds" "clob")
10943    (set_attr "type" "branch")]
10946 ;; tls descriptor call
10947 (define_insn "tlscall"
10948   [(set (reg:SI R0_REGNUM)
10949         (unspec:SI [(reg:SI R0_REGNUM)
10950                     (match_operand:SI 0 "" "X")
10951                     (match_operand 1 "" "")] UNSPEC_TLS))
10952    (clobber (reg:SI R1_REGNUM))
10953    (clobber (reg:SI LR_REGNUM))
10954    (clobber (reg:SI CC_REGNUM))]
10955   "TARGET_GNU2_TLS"
10956   {
10957     targetm.asm_out.internal_label (asm_out_file, "LPIC",
10958                                     INTVAL (operands[1]));
10959     return "bl\\t%c0(tlscall)";
10960   }
10961   [(set_attr "conds" "clob")
10962    (set_attr "length" "4")
10963    (set_attr "type" "branch")]
10966 ;; For thread pointer builtin
10967 (define_expand "get_thread_pointersi"
10968   [(match_operand:SI 0 "s_register_operand" "=r")]
10969  ""
10972    arm_load_tp (operands[0]);
10973    DONE;
10974  }")
10978 ;; We only care about the lower 16 bits of the constant 
10979 ;; being inserted into the upper 16 bits of the register.
10980 (define_insn "*arm_movtas_ze" 
10981   [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r,r")
10982                    (const_int 16)
10983                    (const_int 16))
10984         (match_operand:SI 1 "const_int_operand" ""))]
10985   "TARGET_HAVE_MOVT"
10986   "@
10987    movt%?\t%0, %L1
10988    movt\t%0, %L1"
10989  [(set_attr "arch" "32,v8mb")
10990   (set_attr "predicable" "yes")
10991   (set_attr "predicable_short_it" "no")
10992   (set_attr "length" "4")
10993   (set_attr "type" "alu_sreg")]
10996 (define_insn "*arm_rev"
10997   [(set (match_operand:SI 0 "s_register_operand" "=l,l,r")
10998         (bswap:SI (match_operand:SI 1 "s_register_operand" "l,l,r")))]
10999   "arm_arch6"
11000   "@
11001    rev\t%0, %1
11002    rev%?\t%0, %1
11003    rev%?\t%0, %1"
11004   [(set_attr "arch" "t1,t2,32")
11005    (set_attr "length" "2,2,4")
11006    (set_attr "predicable" "no,yes,yes")
11007    (set_attr "predicable_short_it" "no")
11008    (set_attr "type" "rev")]
11011 (define_expand "arm_legacy_rev"
11012   [(set (match_operand:SI 2 "s_register_operand" "")
11013         (xor:SI (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
11014                              (const_int 16))
11015                 (match_dup 1)))
11016    (set (match_dup 2)
11017         (lshiftrt:SI (match_dup 2)
11018                      (const_int 8)))
11019    (set (match_operand:SI 3 "s_register_operand" "")
11020         (rotatert:SI (match_dup 1)
11021                      (const_int 8)))
11022    (set (match_dup 2)
11023         (and:SI (match_dup 2)
11024                 (const_int -65281)))
11025    (set (match_operand:SI 0 "s_register_operand" "")
11026         (xor:SI (match_dup 3)
11027                 (match_dup 2)))]
11028   "TARGET_32BIT"
11029   ""
11032 ;; Reuse temporaries to keep register pressure down.
11033 (define_expand "thumb_legacy_rev"
11034   [(set (match_operand:SI 2 "s_register_operand" "")
11035      (ashift:SI (match_operand:SI 1 "s_register_operand" "")
11036                 (const_int 24)))
11037    (set (match_operand:SI 3 "s_register_operand" "")
11038      (lshiftrt:SI (match_dup 1)
11039                   (const_int 24)))
11040    (set (match_dup 3)
11041      (ior:SI (match_dup 3)
11042              (match_dup 2)))
11043    (set (match_operand:SI 4 "s_register_operand" "")
11044      (const_int 16))
11045    (set (match_operand:SI 5 "s_register_operand" "")
11046      (rotatert:SI (match_dup 1)
11047                   (match_dup 4)))
11048    (set (match_dup 2)
11049      (ashift:SI (match_dup 5)
11050                 (const_int 24)))
11051    (set (match_dup 5)
11052      (lshiftrt:SI (match_dup 5)
11053                   (const_int 24)))
11054    (set (match_dup 5)
11055      (ior:SI (match_dup 5)
11056              (match_dup 2)))
11057    (set (match_dup 5)
11058      (rotatert:SI (match_dup 5)
11059                   (match_dup 4)))
11060    (set (match_operand:SI 0 "s_register_operand" "")
11061      (ior:SI (match_dup 5)
11062              (match_dup 3)))]
11063   "TARGET_THUMB"
11064   ""
11067 ;; ARM-specific expansion of signed mod by power of 2
11068 ;; using conditional negate.
11069 ;; For r0 % n where n is a power of 2 produce:
11070 ;; rsbs    r1, r0, #0
11071 ;; and     r0, r0, #(n - 1)
11072 ;; and     r1, r1, #(n - 1)
11073 ;; rsbpl   r0, r1, #0
11075 (define_expand "modsi3"
11076   [(match_operand:SI 0 "register_operand" "")
11077    (match_operand:SI 1 "register_operand" "")
11078    (match_operand:SI 2 "const_int_operand" "")]
11079   "TARGET_32BIT"
11080   {
11081     HOST_WIDE_INT val = INTVAL (operands[2]);
11083     if (val <= 0
11084        || exact_log2 (val) <= 0)
11085       FAIL;
11087     rtx mask = GEN_INT (val - 1);
11089     /* In the special case of x0 % 2 we can do the even shorter:
11090         cmp     r0, #0
11091         and     r0, r0, #1
11092         rsblt   r0, r0, #0.  */
11094     if (val == 2)
11095       {
11096         rtx cc_reg = arm_gen_compare_reg (LT,
11097                                           operands[1], const0_rtx, NULL_RTX);
11098         rtx cond = gen_rtx_LT (SImode, cc_reg, const0_rtx);
11099         rtx masked = gen_reg_rtx (SImode);
11101         emit_insn (gen_andsi3 (masked, operands[1], mask));
11102         emit_move_insn (operands[0],
11103                         gen_rtx_IF_THEN_ELSE (SImode, cond,
11104                                               gen_rtx_NEG (SImode,
11105                                                            masked),
11106                                               masked));
11107         DONE;
11108       }
11110     rtx neg_op = gen_reg_rtx (SImode);
11111     rtx_insn *insn = emit_insn (gen_subsi3_compare0 (neg_op, const0_rtx,
11112                                                       operands[1]));
11114     /* Extract the condition register and mode.  */
11115     rtx cmp = XVECEXP (PATTERN (insn), 0, 0);
11116     rtx cc_reg = SET_DEST (cmp);
11117     rtx cond = gen_rtx_GE (SImode, cc_reg, const0_rtx);
11119     emit_insn (gen_andsi3 (operands[0], operands[1], mask));
11121     rtx masked_neg = gen_reg_rtx (SImode);
11122     emit_insn (gen_andsi3 (masked_neg, neg_op, mask));
11124     /* We want a conditional negate here, but emitting COND_EXEC rtxes
11125        during expand does not always work.  Do an IF_THEN_ELSE instead.  */
11126     emit_move_insn (operands[0],
11127                     gen_rtx_IF_THEN_ELSE (SImode, cond,
11128                                           gen_rtx_NEG (SImode, masked_neg),
11129                                           operands[0]));
11132     DONE;
11133   }
11136 (define_expand "bswapsi2"
11137   [(set (match_operand:SI 0 "s_register_operand" "=r")
11138         (bswap:SI (match_operand:SI 1 "s_register_operand" "r")))]
11139 "TARGET_EITHER && (arm_arch6 || !optimize_size)"
11141     if (!arm_arch6)
11142       {
11143         rtx op2 = gen_reg_rtx (SImode);
11144         rtx op3 = gen_reg_rtx (SImode);
11146         if (TARGET_THUMB)
11147           {
11148             rtx op4 = gen_reg_rtx (SImode);
11149             rtx op5 = gen_reg_rtx (SImode);
11151             emit_insn (gen_thumb_legacy_rev (operands[0], operands[1],
11152                                              op2, op3, op4, op5));
11153           }
11154         else
11155           {
11156             emit_insn (gen_arm_legacy_rev (operands[0], operands[1],
11157                                            op2, op3));
11158           }
11160         DONE;
11161       }
11162   "
11165 ;; bswap16 patterns: use revsh and rev16 instructions for the signed
11166 ;; and unsigned variants, respectively. For rev16, expose
11167 ;; byte-swapping in the lower 16 bits only.
11168 (define_insn "*arm_revsh"
11169   [(set (match_operand:SI 0 "s_register_operand" "=l,l,r")
11170         (sign_extend:SI (bswap:HI (match_operand:HI 1 "s_register_operand" "l,l,r"))))]
11171   "arm_arch6"
11172   "@
11173   revsh\t%0, %1
11174   revsh%?\t%0, %1
11175   revsh%?\t%0, %1"
11176   [(set_attr "arch" "t1,t2,32")
11177    (set_attr "length" "2,2,4")
11178    (set_attr "type" "rev")]
11181 (define_insn "*arm_rev16"
11182   [(set (match_operand:HI 0 "s_register_operand" "=l,l,r")
11183         (bswap:HI (match_operand:HI 1 "s_register_operand" "l,l,r")))]
11184   "arm_arch6"
11185   "@
11186    rev16\t%0, %1
11187    rev16%?\t%0, %1
11188    rev16%?\t%0, %1"
11189   [(set_attr "arch" "t1,t2,32")
11190    (set_attr "length" "2,2,4")
11191    (set_attr "type" "rev")]
11194 ;; There are no canonicalisation rules for the position of the lshiftrt, ashift
11195 ;; operations within an IOR/AND RTX, therefore we have two patterns matching
11196 ;; each valid permutation.
11198 (define_insn "arm_rev16si2"
11199   [(set (match_operand:SI 0 "register_operand" "=l,l,r")
11200         (ior:SI (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "l,l,r")
11201                                    (const_int 8))
11202                         (match_operand:SI 3 "const_int_operand" "n,n,n"))
11203                 (and:SI (lshiftrt:SI (match_dup 1)
11204                                      (const_int 8))
11205                         (match_operand:SI 2 "const_int_operand" "n,n,n"))))]
11206   "arm_arch6
11207    && aarch_rev16_shleft_mask_imm_p (operands[3], SImode)
11208    && aarch_rev16_shright_mask_imm_p (operands[2], SImode)"
11209   "rev16\\t%0, %1"
11210   [(set_attr "arch" "t1,t2,32")
11211    (set_attr "length" "2,2,4")
11212    (set_attr "type" "rev")]
11215 (define_insn "arm_rev16si2_alt"
11216   [(set (match_operand:SI 0 "register_operand" "=l,l,r")
11217         (ior:SI (and:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "l,l,r")
11218                                      (const_int 8))
11219                         (match_operand:SI 2 "const_int_operand" "n,n,n"))
11220                 (and:SI (ashift:SI (match_dup 1)
11221                                    (const_int 8))
11222                         (match_operand:SI 3 "const_int_operand" "n,n,n"))))]
11223   "arm_arch6
11224    && aarch_rev16_shleft_mask_imm_p (operands[3], SImode)
11225    && aarch_rev16_shright_mask_imm_p (operands[2], SImode)"
11226   "rev16\\t%0, %1"
11227   [(set_attr "arch" "t1,t2,32")
11228    (set_attr "length" "2,2,4")
11229    (set_attr "type" "rev")]
11232 (define_expand "bswaphi2"
11233   [(set (match_operand:HI 0 "s_register_operand" "=r")
11234         (bswap:HI (match_operand:HI 1 "s_register_operand" "r")))]
11235 "arm_arch6"
11239 ;; Patterns for LDRD/STRD in Thumb2 mode
11241 (define_insn "*thumb2_ldrd"
11242   [(set (match_operand:SI 0 "s_register_operand" "=r")
11243         (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "rk")
11244                          (match_operand:SI 2 "ldrd_strd_offset_operand" "Do"))))
11245    (set (match_operand:SI 3 "s_register_operand" "=r")
11246         (mem:SI (plus:SI (match_dup 1)
11247                          (match_operand:SI 4 "const_int_operand" ""))))]
11248   "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11249      && current_tune->prefer_ldrd_strd
11250      && ((INTVAL (operands[2]) + 4) == INTVAL (operands[4]))
11251      && (operands_ok_ldrd_strd (operands[0], operands[3],
11252                                   operands[1], INTVAL (operands[2]),
11253                                   false, true))"
11254   "ldrd%?\t%0, %3, [%1, %2]"
11255   [(set_attr "type" "load2")
11256    (set_attr "predicable" "yes")
11257    (set_attr "predicable_short_it" "no")])
11259 (define_insn "*thumb2_ldrd_base"
11260   [(set (match_operand:SI 0 "s_register_operand" "=r")
11261         (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
11262    (set (match_operand:SI 2 "s_register_operand" "=r")
11263         (mem:SI (plus:SI (match_dup 1)
11264                          (const_int 4))))]
11265   "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11266      && current_tune->prefer_ldrd_strd
11267      && (operands_ok_ldrd_strd (operands[0], operands[2],
11268                                   operands[1], 0, false, true))"
11269   "ldrd%?\t%0, %2, [%1]"
11270   [(set_attr "type" "load2")
11271    (set_attr "predicable" "yes")
11272    (set_attr "predicable_short_it" "no")])
11274 (define_insn "*thumb2_ldrd_base_neg"
11275   [(set (match_operand:SI 0 "s_register_operand" "=r")
11276         (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "rk")
11277                          (const_int -4))))
11278    (set (match_operand:SI 2 "s_register_operand" "=r")
11279         (mem:SI (match_dup 1)))]
11280   "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11281      && current_tune->prefer_ldrd_strd
11282      && (operands_ok_ldrd_strd (operands[0], operands[2],
11283                                   operands[1], -4, false, true))"
11284   "ldrd%?\t%0, %2, [%1, #-4]"
11285   [(set_attr "type" "load2")
11286    (set_attr "predicable" "yes")
11287    (set_attr "predicable_short_it" "no")])
11289 (define_insn "*thumb2_strd"
11290   [(set (mem:SI (plus:SI (match_operand:SI 0 "s_register_operand" "rk")
11291                          (match_operand:SI 1 "ldrd_strd_offset_operand" "Do")))
11292         (match_operand:SI 2 "s_register_operand" "r"))
11293    (set (mem:SI (plus:SI (match_dup 0)
11294                          (match_operand:SI 3 "const_int_operand" "")))
11295         (match_operand:SI 4 "s_register_operand" "r"))]
11296   "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11297      && current_tune->prefer_ldrd_strd
11298      && ((INTVAL (operands[1]) + 4) == INTVAL (operands[3]))
11299      && (operands_ok_ldrd_strd (operands[2], operands[4],
11300                                   operands[0], INTVAL (operands[1]),
11301                                   false, false))"
11302   "strd%?\t%2, %4, [%0, %1]"
11303   [(set_attr "type" "store2")
11304    (set_attr "predicable" "yes")
11305    (set_attr "predicable_short_it" "no")])
11307 (define_insn "*thumb2_strd_base"
11308   [(set (mem:SI (match_operand:SI 0 "s_register_operand" "rk"))
11309         (match_operand:SI 1 "s_register_operand" "r"))
11310    (set (mem:SI (plus:SI (match_dup 0)
11311                          (const_int 4)))
11312         (match_operand:SI 2 "s_register_operand" "r"))]
11313   "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11314      && current_tune->prefer_ldrd_strd
11315      && (operands_ok_ldrd_strd (operands[1], operands[2],
11316                                   operands[0], 0, false, false))"
11317   "strd%?\t%1, %2, [%0]"
11318   [(set_attr "type" "store2")
11319    (set_attr "predicable" "yes")
11320    (set_attr "predicable_short_it" "no")])
11322 (define_insn "*thumb2_strd_base_neg"
11323   [(set (mem:SI (plus:SI (match_operand:SI 0 "s_register_operand" "rk")
11324                          (const_int -4)))
11325         (match_operand:SI 1 "s_register_operand" "r"))
11326    (set (mem:SI (match_dup 0))
11327         (match_operand:SI 2 "s_register_operand" "r"))]
11328   "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11329      && current_tune->prefer_ldrd_strd
11330      && (operands_ok_ldrd_strd (operands[1], operands[2],
11331                                   operands[0], -4, false, false))"
11332   "strd%?\t%1, %2, [%0, #-4]"
11333   [(set_attr "type" "store2")
11334    (set_attr "predicable" "yes")
11335    (set_attr "predicable_short_it" "no")])
11337 ;; ARMv8 CRC32 instructions.
11338 (define_insn "<crc_variant>"
11339   [(set (match_operand:SI 0 "s_register_operand" "=r")
11340         (unspec:SI [(match_operand:SI 1 "s_register_operand" "r")
11341                     (match_operand:<crc_mode> 2 "s_register_operand" "r")]
11342          CRC))]
11343   "TARGET_CRC32"
11344   "<crc_variant>\\t%0, %1, %2"
11345   [(set_attr "type" "crc")
11346    (set_attr "conds" "unconditional")]
11349 ;; Load the load/store double peephole optimizations.
11350 (include "ldrdstrd.md")
11352 ;; Load the load/store multiple patterns
11353 (include "ldmstm.md")
11355 ;; Patterns in ldmstm.md don't cover more than 4 registers. This pattern covers
11356 ;; large lists without explicit writeback generated for APCS_FRAME epilogue.
11357 (define_insn "*load_multiple"
11358   [(match_parallel 0 "load_multiple_operation"
11359     [(set (match_operand:SI 2 "s_register_operand" "=rk")
11360           (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
11361         ])]
11362   "TARGET_32BIT"
11363   "*
11364   {
11365     arm_output_multireg_pop (operands, /*return_pc=*/false,
11366                                        /*cond=*/const_true_rtx,
11367                                        /*reverse=*/false,
11368                                        /*update=*/false);
11369     return \"\";
11370   }
11371   "
11372   [(set_attr "predicable" "yes")]
11375 (define_expand "copysignsf3"
11376   [(match_operand:SF 0 "register_operand")
11377    (match_operand:SF 1 "register_operand")
11378    (match_operand:SF 2 "register_operand")]
11379   "TARGET_SOFT_FLOAT && arm_arch_thumb2"
11380   "{
11381      emit_move_insn (operands[0], operands[2]);
11382      emit_insn (gen_insv_t2 (simplify_gen_subreg (SImode, operands[0], SFmode, 0),
11383                 GEN_INT (31), GEN_INT (0),
11384                 simplify_gen_subreg (SImode, operands[1], SFmode, 0)));
11385      DONE;
11386   }"
11389 (define_expand "copysigndf3"
11390   [(match_operand:DF 0 "register_operand")
11391    (match_operand:DF 1 "register_operand")
11392    (match_operand:DF 2 "register_operand")]
11393   "TARGET_SOFT_FLOAT && arm_arch_thumb2"
11394   "{
11395      rtx op0_low = gen_lowpart (SImode, operands[0]);
11396      rtx op0_high = gen_highpart (SImode, operands[0]);
11397      rtx op1_low = gen_lowpart (SImode, operands[1]);
11398      rtx op1_high = gen_highpart (SImode, operands[1]);
11399      rtx op2_high = gen_highpart (SImode, operands[2]);
11401      rtx scratch1 = gen_reg_rtx (SImode);
11402      rtx scratch2 = gen_reg_rtx (SImode);
11403      emit_move_insn (scratch1, op2_high);
11404      emit_move_insn (scratch2, op1_high);
11406      emit_insn(gen_rtx_SET(scratch1,
11407                            gen_rtx_LSHIFTRT (SImode, op2_high, GEN_INT(31))));
11408      emit_insn(gen_insv_t2(scratch2, GEN_INT(1), GEN_INT(31), scratch1));
11409      emit_move_insn (op0_low, op1_low);
11410      emit_move_insn (op0_high, scratch2);
11412      DONE;
11413   }"
11416 ;; movmisalign patterns for HImode and SImode.
11417 (define_expand "movmisalign<mode>"
11418   [(match_operand:HSI 0 "general_operand")
11419    (match_operand:HSI 1 "general_operand")]
11420   "unaligned_access"
11422   /* This pattern is not permitted to fail during expansion: if both arguments
11423      are non-registers (e.g. memory := constant), force operand 1 into a
11424      register.  */
11425   rtx (* gen_unaligned_load)(rtx, rtx);
11426   rtx tmp_dest = operands[0];
11427   if (!s_register_operand (operands[0], <MODE>mode)
11428       && !s_register_operand (operands[1], <MODE>mode))
11429     operands[1] = force_reg (<MODE>mode, operands[1]);
11431   if (<MODE>mode == HImode)
11432    {
11433     gen_unaligned_load = gen_unaligned_loadhiu;
11434     tmp_dest = gen_reg_rtx (SImode);
11435    }
11436   else
11437     gen_unaligned_load = gen_unaligned_loadsi;
11439   if (MEM_P (operands[1]))
11440    {
11441     emit_insn (gen_unaligned_load (tmp_dest, operands[1]));
11442     if (<MODE>mode == HImode)
11443       emit_move_insn (operands[0], gen_lowpart (HImode, tmp_dest));
11444    }
11445   else
11446     emit_insn (gen_unaligned_store<mode> (operands[0], operands[1]));
11448   DONE;
11451 ;; Vector bits common to IWMMXT and Neon
11452 (include "vec-common.md")
11453 ;; Load the Intel Wireless Multimedia Extension patterns
11454 (include "iwmmxt.md")
11455 ;; Load the VFP co-processor patterns
11456 (include "vfp.md")
11457 ;; Thumb-1 patterns
11458 (include "thumb1.md")
11459 ;; Thumb-2 patterns
11460 (include "thumb2.md")
11461 ;; Neon patterns
11462 (include "neon.md")
11463 ;; Crypto patterns
11464 (include "crypto.md")
11465 ;; Synchronization Primitives
11466 (include "sync.md")
11467 ;; Fixed-point patterns
11468 (include "arm-fixed.md")