2016-07-07 Thomas Preud'homme <thomas.preudhomme@arm.com>
[official-gcc.git] / gcc / config / arm / arm.md
blob3cd76f935a45305b4e7fe7b55b517a1404edfa0b
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.  This attribute is
122 ; used to compute attribute "enabled", use type "any" to enable an
123 ; alternative in all cases.
124 (define_attr "arch" "any,a,t,32,t1,t2,v6,nov6,v6t2,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" "avoid_neon_for_64bits")
164               (match_test "TARGET_NEON")
165               (not (match_test "TARGET_PREFER_NEON_64BITS")))
166          (const_string "yes")
168          (and (eq_attr "arch" "neon_for_64bits")
169               (match_test "TARGET_NEON")
170               (match_test "TARGET_PREFER_NEON_64BITS"))
171          (const_string "yes")
173          (and (eq_attr "arch" "iwmmxt2")
174               (match_test "TARGET_REALLY_IWMMXT2"))
175          (const_string "yes")
177          (and (eq_attr "arch" "armv6_or_vfpv3")
178               (match_test "arm_arch6 || TARGET_VFP3"))
179          (const_string "yes")
181          (and (eq_attr "arch" "neon")
182               (match_test "TARGET_NEON"))
183          (const_string "yes")
184         ]
186         (const_string "no")))
188 (define_attr "opt" "any,speed,size"
189   (const_string "any"))
191 (define_attr "opt_enabled" "no,yes"
192   (cond [(eq_attr "opt" "any")
193          (const_string "yes")
195          (and (eq_attr "opt" "speed")
196               (match_test "optimize_function_for_speed_p (cfun)"))
197          (const_string "yes")
199          (and (eq_attr "opt" "size")
200               (match_test "optimize_function_for_size_p (cfun)"))
201          (const_string "yes")]
202         (const_string "no")))
204 (define_attr "use_literal_pool" "no,yes"
205    (cond [(and (eq_attr "type" "f_loads,f_loadd")
206                (match_test "CONSTANT_P (operands[1])"))
207           (const_string "yes")]
208          (const_string "no")))
210 ; Enable all alternatives that are both arch_enabled and insn_enabled.
211 ; FIXME:: opt_enabled has been temporarily removed till the time we have
212 ; an attribute that allows the use of such alternatives.
213 ; This depends on caching of speed_p, size_p on a per
214 ; alternative basis. The problem is that the enabled attribute
215 ; cannot depend on any state that is not cached or is not constant
216 ; for a compilation unit. We probably need a generic "hot/cold"
217 ; alternative which if implemented can help with this. We disable this
218 ; until such a time as this is implemented and / or the improvements or
219 ; regressions with removing this attribute are double checked.
220 ; See ashldi3_neon and <shift>di3_neon in neon.md.
222  (define_attr "enabled" "no,yes"
223    (cond [(and (eq_attr "predicable_short_it" "no")
224                (and (eq_attr "predicated" "yes")
225                     (match_test "arm_restrict_it")))
226           (const_string "no")
228           (and (eq_attr "enabled_for_depr_it" "no")
229                (match_test "arm_restrict_it"))
230           (const_string "no")
232           (and (eq_attr "use_literal_pool" "yes")
233                (match_test "arm_disable_literal_pool"))
234           (const_string "no")
236           (eq_attr "arch_enabled" "no")
237           (const_string "no")]
238          (const_string "yes")))
240 ; POOL_RANGE is how far away from a constant pool entry that this insn
241 ; can be placed.  If the distance is zero, then this insn will never
242 ; reference the pool.
243 ; Note that for Thumb constant pools the PC value is rounded down to the
244 ; nearest multiple of four.  Therefore, THUMB2_POOL_RANGE (and POOL_RANGE for
245 ; Thumb insns) should be set to <max_range> - 2.
246 ; NEG_POOL_RANGE is nonzero for insns that can reference a constant pool entry
247 ; before its address.  It is set to <max_range> - (8 + <data_size>).
248 (define_attr "arm_pool_range" "" (const_int 0))
249 (define_attr "thumb2_pool_range" "" (const_int 0))
250 (define_attr "arm_neg_pool_range" "" (const_int 0))
251 (define_attr "thumb2_neg_pool_range" "" (const_int 0))
253 (define_attr "pool_range" ""
254   (cond [(eq_attr "is_thumb" "yes") (attr "thumb2_pool_range")]
255         (attr "arm_pool_range")))
256 (define_attr "neg_pool_range" ""
257   (cond [(eq_attr "is_thumb" "yes") (attr "thumb2_neg_pool_range")]
258         (attr "arm_neg_pool_range")))
260 ; An assembler sequence may clobber the condition codes without us knowing.
261 ; If such an insn references the pool, then we have no way of knowing how,
262 ; so use the most conservative value for pool_range.
263 (define_asm_attributes
264  [(set_attr "conds" "clob")
265   (set_attr "length" "4")
266   (set_attr "pool_range" "250")])
268 ; Load scheduling, set from the arm_ld_sched variable
269 ; initialized by arm_option_override()
270 (define_attr "ldsched" "no,yes" (const (symbol_ref "arm_ld_sched")))
272 ; condition codes: this one is used by final_prescan_insn to speed up
273 ; conditionalizing instructions.  It saves having to scan the rtl to see if
274 ; it uses or alters the condition codes.
276 ; USE means that the condition codes are used by the insn in the process of
277 ;   outputting code, this means (at present) that we can't use the insn in
278 ;   inlined branches
280 ; SET means that the purpose of the insn is to set the condition codes in a
281 ;   well defined manner.
283 ; CLOB means that the condition codes are altered in an undefined manner, if
284 ;   they are altered at all
286 ; UNCONDITIONAL means the instruction can not be conditionally executed and
287 ;   that the instruction does not use or alter the condition codes.
289 ; NOCOND means that the instruction does not use or alter the condition
290 ;   codes but can be converted into a conditionally exectuted instruction.
292 (define_attr "conds" "use,set,clob,unconditional,nocond"
293         (if_then_else
294          (ior (eq_attr "is_thumb1" "yes")
295               (eq_attr "type" "call"))
296          (const_string "clob")
297          (if_then_else (eq_attr "is_neon_type" "no")
298          (const_string "nocond")
299          (const_string "unconditional"))))
301 ; Predicable means that the insn can be conditionally executed based on
302 ; an automatically added predicate (additional patterns are generated by 
303 ; gen...).  We default to 'no' because no Thumb patterns match this rule
304 ; and not all ARM patterns do.
305 (define_attr "predicable" "no,yes" (const_string "no"))
307 ; Only model the write buffer for ARM6 and ARM7.  Earlier processors don't
308 ; have one.  Later ones, such as StrongARM, have write-back caches, so don't
309 ; suffer blockages enough to warrant modelling this (and it can adversely
310 ; affect the schedule).
311 (define_attr "model_wbuf" "no,yes" (const (symbol_ref "arm_tune_wbuf")))
313 ; WRITE_CONFLICT implies that a read following an unrelated write is likely
314 ; to stall the processor.  Used with model_wbuf above.
315 (define_attr "write_conflict" "no,yes"
316   (if_then_else (eq_attr "type"
317                  "block,call,load1")
318                 (const_string "yes")
319                 (const_string "no")))
321 ; Classify the insns into those that take one cycle and those that take more
322 ; than one on the main cpu execution unit.
323 (define_attr "core_cycles" "single,multi"
324   (if_then_else (eq_attr "type"
325     "adc_imm, adc_reg, adcs_imm, adcs_reg, adr, alu_ext, alu_imm, alu_sreg,\
326     alu_shift_imm, alu_shift_reg, alu_dsp_reg, alus_ext, alus_imm, alus_sreg,\
327     alus_shift_imm, alus_shift_reg, bfm, csel, rev, logic_imm, logic_reg,\
328     logic_shift_imm, logic_shift_reg, logics_imm, logics_reg,\
329     logics_shift_imm, logics_shift_reg, extend, shift_imm, float, fcsel,\
330     wmmx_wor, wmmx_wxor, wmmx_wand, wmmx_wandn, wmmx_wmov, wmmx_tmcrr,\
331     wmmx_tmrrc, wmmx_wldr, wmmx_wstr, wmmx_tmcr, wmmx_tmrc, wmmx_wadd,\
332     wmmx_wsub, wmmx_wmul, wmmx_wmac, wmmx_wavg2, wmmx_tinsr, wmmx_textrm,\
333     wmmx_wshufh, wmmx_wcmpeq, wmmx_wcmpgt, wmmx_wmax, wmmx_wmin, wmmx_wpack,\
334     wmmx_wunpckih, wmmx_wunpckil, wmmx_wunpckeh, wmmx_wunpckel, wmmx_wror,\
335     wmmx_wsra, wmmx_wsrl, wmmx_wsll, wmmx_wmadd, wmmx_tmia, wmmx_tmiaph,\
336     wmmx_tmiaxy, wmmx_tbcst, wmmx_tmovmsk, wmmx_wacc, wmmx_waligni,\
337     wmmx_walignr, wmmx_tandc, wmmx_textrc, wmmx_torc, wmmx_torvsc, wmmx_wsad,\
338     wmmx_wabs, wmmx_wabsdiff, wmmx_waddsubhx, wmmx_wsubaddhx, wmmx_wavg4,\
339     wmmx_wmulw, wmmx_wqmulm, wmmx_wqmulwm, wmmx_waddbhus, wmmx_wqmiaxy,\
340     wmmx_wmiaxy, wmmx_wmiawxy, wmmx_wmerge")
341                 (const_string "single")
342                 (const_string "multi")))
344 ;; FAR_JUMP is "yes" if a BL instruction is used to generate a branch to a
345 ;; distant label.  Only applicable to Thumb code.
346 (define_attr "far_jump" "yes,no" (const_string "no"))
349 ;; The number of machine instructions this pattern expands to.
350 ;; Used for Thumb-2 conditional execution.
351 (define_attr "ce_count" "" (const_int 1))
353 ;;---------------------------------------------------------------------------
354 ;; Unspecs
356 (include "unspecs.md")
358 ;;---------------------------------------------------------------------------
359 ;; Mode iterators
361 (include "iterators.md")
363 ;;---------------------------------------------------------------------------
364 ;; Predicates
366 (include "predicates.md")
367 (include "constraints.md")
369 ;;---------------------------------------------------------------------------
370 ;; Pipeline descriptions
372 (define_attr "tune_cortexr4" "yes,no"
373   (const (if_then_else
374           (eq_attr "tune" "cortexr4,cortexr4f,cortexr5")
375           (const_string "yes")
376           (const_string "no"))))
378 ;; True if the generic scheduling description should be used.
380 (define_attr "generic_sched" "yes,no"
381   (const (if_then_else
382           (ior (eq_attr "tune" "fa526,fa626,fa606te,fa626te,fmp626,fa726te,\
383                                 arm926ejs,arm1020e,arm1026ejs,arm1136js,\
384                                 arm1136jfs,cortexa5,cortexa7,cortexa8,\
385                                 cortexa9,cortexa12,cortexa15,cortexa17,\
386                                 cortexa53,cortexa57,cortexm4,cortexm7,\
387                                 exynosm1,marvell_pj4,xgene1")
388                (eq_attr "tune_cortexr4" "yes"))
389           (const_string "no")
390           (const_string "yes"))))
392 (define_attr "generic_vfp" "yes,no"
393   (const (if_then_else
394           (and (eq_attr "fpu" "vfp")
395                (eq_attr "tune" "!arm1020e,arm1022e,cortexa5,cortexa7,\
396                                 cortexa8,cortexa9,cortexa53,cortexm4,\
397                                 cortexm7,marvell_pj4,xgene1")
398                (eq_attr "tune_cortexr4" "no"))
399           (const_string "yes")
400           (const_string "no"))))
402 (include "marvell-f-iwmmxt.md")
403 (include "arm-generic.md")
404 (include "arm926ejs.md")
405 (include "arm1020e.md")
406 (include "arm1026ejs.md")
407 (include "arm1136jfs.md")
408 (include "fa526.md")
409 (include "fa606te.md")
410 (include "fa626te.md")
411 (include "fmp626.md")
412 (include "fa726te.md")
413 (include "cortex-a5.md")
414 (include "cortex-a7.md")
415 (include "cortex-a8.md")
416 (include "cortex-a9.md")
417 (include "cortex-a15.md")
418 (include "cortex-a17.md")
419 (include "cortex-a53.md")
420 (include "cortex-a57.md")
421 (include "cortex-r4.md")
422 (include "cortex-r4f.md")
423 (include "cortex-m7.md")
424 (include "cortex-m4.md")
425 (include "cortex-m4-fpu.md")
426 (include "exynos-m1.md")
427 (include "vfp11.md")
428 (include "marvell-pj4.md")
429 (include "xgene1.md")
432 ;;---------------------------------------------------------------------------
433 ;; Insn patterns
435 ;; Addition insns.
437 ;; Note: For DImode insns, there is normally no reason why operands should
438 ;; not be in the same register, what we don't want is for something being
439 ;; written to partially overlap something that is an input.
441 (define_expand "adddi3"
442  [(parallel
443    [(set (match_operand:DI           0 "s_register_operand" "")
444           (plus:DI (match_operand:DI 1 "s_register_operand" "")
445                    (match_operand:DI 2 "arm_adddi_operand"  "")))
446     (clobber (reg:CC CC_REGNUM))])]
447   "TARGET_EITHER"
448   "
449   if (TARGET_THUMB1)
450     {
451       if (!REG_P (operands[1]))
452         operands[1] = force_reg (DImode, operands[1]);
453       if (!REG_P (operands[2]))
454         operands[2] = force_reg (DImode, operands[2]);
455      }
456   "
459 (define_insn_and_split "*arm_adddi3"
460   [(set (match_operand:DI          0 "s_register_operand" "=&r,&r,&r,&r,&r")
461         (plus:DI (match_operand:DI 1 "s_register_operand" "%0, 0, r, 0, r")
462                  (match_operand:DI 2 "arm_adddi_operand"  "r,  0, r, Dd, Dd")))
463    (clobber (reg:CC CC_REGNUM))]
464   "TARGET_32BIT && !TARGET_NEON"
465   "#"
466   "TARGET_32BIT && reload_completed
467    && ! (TARGET_NEON && IS_VFP_REGNUM (REGNO (operands[0])))"
468   [(parallel [(set (reg:CC_C CC_REGNUM)
469                    (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
470                                  (match_dup 1)))
471               (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
472    (set (match_dup 3) (plus:SI (plus:SI (match_dup 4) (match_dup 5))
473                                (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
474   "
475   {
476     operands[3] = gen_highpart (SImode, operands[0]);
477     operands[0] = gen_lowpart (SImode, operands[0]);
478     operands[4] = gen_highpart (SImode, operands[1]);
479     operands[1] = gen_lowpart (SImode, operands[1]);
480     operands[5] = gen_highpart_mode (SImode, DImode, operands[2]);
481     operands[2] = gen_lowpart (SImode, operands[2]);
482   }"
483   [(set_attr "conds" "clob")
484    (set_attr "length" "8")
485    (set_attr "type" "multiple")]
488 (define_insn_and_split "*adddi_sesidi_di"
489   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
490         (plus:DI (sign_extend:DI
491                   (match_operand:SI 2 "s_register_operand" "r,r"))
492                  (match_operand:DI 1 "s_register_operand" "0,r")))
493    (clobber (reg:CC CC_REGNUM))]
494   "TARGET_32BIT"
495   "#"
496   "TARGET_32BIT && reload_completed"
497   [(parallel [(set (reg:CC_C CC_REGNUM)
498                    (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
499                                  (match_dup 1)))
500               (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
501    (set (match_dup 3) (plus:SI (plus:SI (ashiftrt:SI (match_dup 2)
502                                                      (const_int 31))
503                                         (match_dup 4))
504                                (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
505   "
506   {
507     operands[3] = gen_highpart (SImode, operands[0]);
508     operands[0] = gen_lowpart (SImode, operands[0]);
509     operands[4] = gen_highpart (SImode, operands[1]);
510     operands[1] = gen_lowpart (SImode, operands[1]);
511     operands[2] = gen_lowpart (SImode, operands[2]);
512   }"
513   [(set_attr "conds" "clob")
514    (set_attr "length" "8")
515    (set_attr "type" "multiple")]
518 (define_insn_and_split "*adddi_zesidi_di"
519   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
520         (plus:DI (zero_extend:DI
521                   (match_operand:SI 2 "s_register_operand" "r,r"))
522                  (match_operand:DI 1 "s_register_operand" "0,r")))
523    (clobber (reg:CC CC_REGNUM))]
524   "TARGET_32BIT"
525   "#"
526   "TARGET_32BIT && reload_completed"
527   [(parallel [(set (reg:CC_C CC_REGNUM)
528                    (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
529                                  (match_dup 1)))
530               (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
531    (set (match_dup 3) (plus:SI (plus:SI (match_dup 4) (const_int 0))
532                                (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
533   "
534   {
535     operands[3] = gen_highpart (SImode, operands[0]);
536     operands[0] = gen_lowpart (SImode, operands[0]);
537     operands[4] = gen_highpart (SImode, operands[1]);
538     operands[1] = gen_lowpart (SImode, operands[1]);
539     operands[2] = gen_lowpart (SImode, operands[2]);
540   }"
541   [(set_attr "conds" "clob")
542    (set_attr "length" "8")
543    (set_attr "type" "multiple")]
546 (define_expand "addsi3"
547   [(set (match_operand:SI          0 "s_register_operand" "")
548         (plus:SI (match_operand:SI 1 "s_register_operand" "")
549                  (match_operand:SI 2 "reg_or_int_operand" "")))]
550   "TARGET_EITHER"
551   "
552   if (TARGET_32BIT && CONST_INT_P (operands[2]))
553     {
554       arm_split_constant (PLUS, SImode, NULL_RTX,
555                           INTVAL (operands[2]), operands[0], operands[1],
556                           optimize && can_create_pseudo_p ());
557       DONE;
558     }
559   "
562 ; If there is a scratch available, this will be faster than synthesizing the
563 ; addition.
564 (define_peephole2
565   [(match_scratch:SI 3 "r")
566    (set (match_operand:SI          0 "arm_general_register_operand" "")
567         (plus:SI (match_operand:SI 1 "arm_general_register_operand" "")
568                  (match_operand:SI 2 "const_int_operand"  "")))]
569   "TARGET_32BIT &&
570    !(const_ok_for_arm (INTVAL (operands[2]))
571      || const_ok_for_arm (-INTVAL (operands[2])))
572     && const_ok_for_arm (~INTVAL (operands[2]))"
573   [(set (match_dup 3) (match_dup 2))
574    (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 3)))]
575   ""
578 ;; The r/r/k alternative is required when reloading the address
579 ;;  (plus (reg rN) (reg sp)) into (reg rN).  In this case reload will
580 ;; put the duplicated register first, and not try the commutative version.
581 (define_insn_and_split "*arm_addsi3"
582   [(set (match_operand:SI          0 "s_register_operand" "=rk,l,l ,l ,r ,k ,r,r ,k ,r ,k,k,r ,k ,r")
583         (plus:SI (match_operand:SI 1 "s_register_operand" "%0 ,l,0 ,l ,rk,k ,r,rk,k ,rk,k,r,rk,k ,rk")
584                  (match_operand:SI 2 "reg_or_int_operand" "rk ,l,Py,Pd,rI,rI,k,Pj,Pj,L ,L,L,PJ,PJ,?n")))]
585   "TARGET_32BIT"
586   "@
587    add%?\\t%0, %0, %2
588    add%?\\t%0, %1, %2
589    add%?\\t%0, %1, %2
590    add%?\\t%0, %1, %2
591    add%?\\t%0, %1, %2
592    add%?\\t%0, %1, %2
593    add%?\\t%0, %2, %1
594    addw%?\\t%0, %1, %2
595    addw%?\\t%0, %1, %2
596    sub%?\\t%0, %1, #%n2
597    sub%?\\t%0, %1, #%n2
598    sub%?\\t%0, %1, #%n2
599    subw%?\\t%0, %1, #%n2
600    subw%?\\t%0, %1, #%n2
601    #"
602   "TARGET_32BIT
603    && CONST_INT_P (operands[2])
604    && !const_ok_for_op (INTVAL (operands[2]), PLUS)
605    && (reload_completed || !arm_eliminable_register (operands[1]))"
606   [(clobber (const_int 0))]
607   "
608   arm_split_constant (PLUS, SImode, curr_insn,
609                       INTVAL (operands[2]), operands[0],
610                       operands[1], 0);
611   DONE;
612   "
613   [(set_attr "length" "2,4,4,4,4,4,4,4,4,4,4,4,4,4,16")
614    (set_attr "predicable" "yes")
615    (set_attr "predicable_short_it" "yes,yes,yes,yes,no,no,no,no,no,no,no,no,no,no,no")
616    (set_attr "arch" "t2,t2,t2,t2,*,*,*,t2,t2,*,*,a,t2,t2,*")
617    (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
618                       (const_string "alu_imm")
619                       (const_string "alu_sreg")))
623 (define_insn "addsi3_compare0"
624   [(set (reg:CC_NOOV CC_REGNUM)
625         (compare:CC_NOOV
626          (plus:SI (match_operand:SI 1 "s_register_operand" "r, r,r")
627                   (match_operand:SI 2 "arm_add_operand"    "I,L,r"))
628          (const_int 0)))
629    (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
630         (plus:SI (match_dup 1) (match_dup 2)))]
631   "TARGET_ARM"
632   "@
633    adds%?\\t%0, %1, %2
634    subs%?\\t%0, %1, #%n2
635    adds%?\\t%0, %1, %2"
636   [(set_attr "conds" "set")
637    (set_attr "type" "alus_imm,alus_imm,alus_sreg")]
640 (define_insn "*addsi3_compare0_scratch"
641   [(set (reg:CC_NOOV CC_REGNUM)
642         (compare:CC_NOOV
643          (plus:SI (match_operand:SI 0 "s_register_operand" "r, r, r")
644                   (match_operand:SI 1 "arm_add_operand"    "I,L, r"))
645          (const_int 0)))]
646   "TARGET_ARM"
647   "@
648    cmn%?\\t%0, %1
649    cmp%?\\t%0, #%n1
650    cmn%?\\t%0, %1"
651   [(set_attr "conds" "set")
652    (set_attr "predicable" "yes")
653    (set_attr "type" "alus_imm,alus_imm,alus_sreg")]
656 (define_insn "*compare_negsi_si"
657   [(set (reg:CC_Z CC_REGNUM)
658         (compare:CC_Z
659          (neg:SI (match_operand:SI 0 "s_register_operand" "l,r"))
660          (match_operand:SI 1 "s_register_operand" "l,r")))]
661   "TARGET_32BIT"
662   "cmn%?\\t%1, %0"
663   [(set_attr "conds" "set")
664    (set_attr "predicable" "yes")
665    (set_attr "arch" "t2,*")
666    (set_attr "length" "2,4")
667    (set_attr "predicable_short_it" "yes,no")
668    (set_attr "type" "alus_sreg")]
671 ;; This is the canonicalization of addsi3_compare0_for_combiner when the
672 ;; addend is a constant.
673 (define_insn "cmpsi2_addneg"
674   [(set (reg:CC CC_REGNUM)
675         (compare:CC
676          (match_operand:SI 1 "s_register_operand" "r,r")
677          (match_operand:SI 2 "arm_addimm_operand" "L,I")))
678    (set (match_operand:SI 0 "s_register_operand" "=r,r")
679         (plus:SI (match_dup 1)
680                  (match_operand:SI 3 "arm_addimm_operand" "I,L")))]
681   "TARGET_32BIT && INTVAL (operands[2]) == -INTVAL (operands[3])"
682   "@
683    adds%?\\t%0, %1, %3
684    subs%?\\t%0, %1, #%n3"
685   [(set_attr "conds" "set")
686    (set_attr "type" "alus_sreg")]
689 ;; Convert the sequence
690 ;;  sub  rd, rn, #1
691 ;;  cmn  rd, #1 (equivalent to cmp rd, #-1)
692 ;;  bne  dest
693 ;; into
694 ;;  subs rd, rn, #1
695 ;;  bcs  dest   ((unsigned)rn >= 1)
696 ;; similarly for the beq variant using bcc.
697 ;; This is a common looping idiom (while (n--))
698 (define_peephole2
699   [(set (match_operand:SI 0 "arm_general_register_operand" "")
700         (plus:SI (match_operand:SI 1 "arm_general_register_operand" "")
701                  (const_int -1)))
702    (set (match_operand 2 "cc_register" "")
703         (compare (match_dup 0) (const_int -1)))
704    (set (pc)
705         (if_then_else (match_operator 3 "equality_operator"
706                        [(match_dup 2) (const_int 0)])
707                       (match_operand 4 "" "")
708                       (match_operand 5 "" "")))]
709   "TARGET_32BIT && peep2_reg_dead_p (3, operands[2])"
710   [(parallel[
711     (set (match_dup 2)
712          (compare:CC
713           (match_dup 1) (const_int 1)))
714     (set (match_dup 0) (plus:SI (match_dup 1) (const_int -1)))])
715    (set (pc)
716         (if_then_else (match_op_dup 3 [(match_dup 2) (const_int 0)])
717                       (match_dup 4)
718                       (match_dup 5)))]
719   "operands[2] = gen_rtx_REG (CCmode, CC_REGNUM);
720    operands[3] = gen_rtx_fmt_ee ((GET_CODE (operands[3]) == NE
721                                   ? GEU : LTU),
722                                  VOIDmode, 
723                                  operands[2], const0_rtx);"
726 ;; The next four insns work because they compare the result with one of
727 ;; the operands, and we know that the use of the condition code is
728 ;; either GEU or LTU, so we can use the carry flag from the addition
729 ;; instead of doing the compare a second time.
730 (define_insn "*addsi3_compare_op1"
731   [(set (reg:CC_C CC_REGNUM)
732         (compare:CC_C
733          (plus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
734                   (match_operand:SI 2 "arm_add_operand" "I,L,r"))
735          (match_dup 1)))
736    (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
737         (plus:SI (match_dup 1) (match_dup 2)))]
738   "TARGET_32BIT"
739   "@
740    adds%?\\t%0, %1, %2
741    subs%?\\t%0, %1, #%n2
742    adds%?\\t%0, %1, %2"
743   [(set_attr "conds" "set")
744    (set_attr "type"  "alus_imm,alus_imm,alus_sreg")]
747 (define_insn "*addsi3_compare_op2"
748   [(set (reg:CC_C CC_REGNUM)
749         (compare:CC_C
750          (plus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
751                   (match_operand:SI 2 "arm_add_operand" "I,L,r"))
752          (match_dup 2)))
753    (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
754         (plus:SI (match_dup 1) (match_dup 2)))]
755   "TARGET_32BIT"
756   "@
757    adds%?\\t%0, %1, %2
758    subs%?\\t%0, %1, #%n2
759    adds%?\\t%0, %1, %2"
760   [(set_attr "conds" "set")
761    (set_attr "type" "alus_imm,alus_imm,alus_sreg")]
764 (define_insn "*compare_addsi2_op0"
765   [(set (reg:CC_C CC_REGNUM)
766         (compare:CC_C
767           (plus:SI (match_operand:SI 0 "s_register_operand" "l,l,r,r,r")
768                    (match_operand:SI 1 "arm_add_operand" "Pv,l,I,L,r"))
769           (match_dup 0)))]
770   "TARGET_32BIT"
771   "@
772    cmp%?\\t%0, #%n1
773    cmn%?\\t%0, %1
774    cmn%?\\t%0, %1
775    cmp%?\\t%0, #%n1
776    cmn%?\\t%0, %1"
777   [(set_attr "conds" "set")
778    (set_attr "predicable" "yes")
779    (set_attr "arch" "t2,t2,*,*,*")
780    (set_attr "predicable_short_it" "yes,yes,no,no,no")
781    (set_attr "length" "2,2,4,4,4")
782    (set_attr "type" "alus_imm,alus_sreg,alus_imm,alus_imm,alus_sreg")]
785 (define_insn "*compare_addsi2_op1"
786   [(set (reg:CC_C CC_REGNUM)
787         (compare:CC_C
788           (plus:SI (match_operand:SI 0 "s_register_operand" "l,l,r,r,r")
789                    (match_operand:SI 1 "arm_add_operand" "Pv,l,I,L,r"))
790           (match_dup 1)))]
791   "TARGET_32BIT"
792   "@
793    cmp%?\\t%0, #%n1
794    cmn%?\\t%0, %1
795    cmn%?\\t%0, %1
796    cmp%?\\t%0, #%n1
797    cmn%?\\t%0, %1"
798   [(set_attr "conds" "set")
799    (set_attr "predicable" "yes")
800    (set_attr "arch" "t2,t2,*,*,*")
801    (set_attr "predicable_short_it" "yes,yes,no,no,no")
802    (set_attr "length" "2,2,4,4,4")
803    (set_attr "type" "alus_imm,alus_sreg,alus_imm,alus_imm,alus_sreg")]
806 (define_insn "*addsi3_carryin_<optab>"
807   [(set (match_operand:SI 0 "s_register_operand" "=l,r,r")
808         (plus:SI (plus:SI (match_operand:SI 1 "s_register_operand" "%l,r,r")
809                           (match_operand:SI 2 "arm_not_operand" "0,rI,K"))
810                  (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))))]
811   "TARGET_32BIT"
812   "@
813    adc%?\\t%0, %1, %2
814    adc%?\\t%0, %1, %2
815    sbc%?\\t%0, %1, #%B2"
816   [(set_attr "conds" "use")
817    (set_attr "predicable" "yes")
818    (set_attr "arch" "t2,*,*")
819    (set_attr "length" "4")
820    (set_attr "predicable_short_it" "yes,no,no")
821    (set_attr "type" "adc_reg,adc_reg,adc_imm")]
824 (define_insn "*addsi3_carryin_alt2_<optab>"
825   [(set (match_operand:SI 0 "s_register_operand" "=l,r,r")
826         (plus:SI (plus:SI (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))
827                           (match_operand:SI 1 "s_register_operand" "%l,r,r"))
828                  (match_operand:SI 2 "arm_rhs_operand" "l,rI,K")))]
829   "TARGET_32BIT"
830   "@
831    adc%?\\t%0, %1, %2
832    adc%?\\t%0, %1, %2
833    sbc%?\\t%0, %1, #%B2"
834   [(set_attr "conds" "use")
835    (set_attr "predicable" "yes")
836    (set_attr "arch" "t2,*,*")
837    (set_attr "length" "4")
838    (set_attr "predicable_short_it" "yes,no,no")
839    (set_attr "type" "adc_reg,adc_reg,adc_imm")]
842 (define_insn "*addsi3_carryin_shift_<optab>"
843   [(set (match_operand:SI 0 "s_register_operand" "=r")
844         (plus:SI (plus:SI
845                   (match_operator:SI 2 "shift_operator"
846                     [(match_operand:SI 3 "s_register_operand" "r")
847                      (match_operand:SI 4 "reg_or_int_operand" "rM")])
848                   (match_operand:SI 1 "s_register_operand" "r"))
849                  (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))))]
850   "TARGET_32BIT"
851   "adc%?\\t%0, %1, %3%S2"
852   [(set_attr "conds" "use")
853    (set_attr "predicable" "yes")
854    (set_attr "predicable_short_it" "no")
855    (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
856                       (const_string "alu_shift_imm")
857                       (const_string "alu_shift_reg")))]
860 (define_insn "*addsi3_carryin_clobercc_<optab>"
861   [(set (match_operand:SI 0 "s_register_operand" "=r")
862         (plus:SI (plus:SI (match_operand:SI 1 "s_register_operand" "%r")
863                           (match_operand:SI 2 "arm_rhs_operand" "rI"))
864                  (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))))
865    (clobber (reg:CC CC_REGNUM))]
866    "TARGET_32BIT"
867    "adcs%?\\t%0, %1, %2"
868    [(set_attr "conds" "set")
869     (set_attr "type" "adcs_reg")]
872 (define_insn "*subsi3_carryin"
873   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
874         (minus:SI (minus:SI (match_operand:SI 1 "reg_or_int_operand" "r,I")
875                             (match_operand:SI 2 "s_register_operand" "r,r"))
876                   (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
877   "TARGET_32BIT"
878   "@
879    sbc%?\\t%0, %1, %2
880    rsc%?\\t%0, %2, %1"
881   [(set_attr "conds" "use")
882    (set_attr "arch" "*,a")
883    (set_attr "predicable" "yes")
884    (set_attr "predicable_short_it" "no")
885    (set_attr "type" "adc_reg,adc_imm")]
888 (define_insn "*subsi3_carryin_const"
889   [(set (match_operand:SI 0 "s_register_operand" "=r")
890         (minus:SI (plus:SI (match_operand:SI 1 "s_register_operand" "r")
891                            (match_operand:SI 2 "arm_not_immediate_operand" "K"))
892                   (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
893   "TARGET_32BIT"
894   "sbc\\t%0, %1, #%B2"
895   [(set_attr "conds" "use")
896    (set_attr "type" "adc_imm")]
899 (define_insn "*subsi3_carryin_compare"
900   [(set (reg:CC CC_REGNUM)
901         (compare:CC (match_operand:SI 1 "s_register_operand" "r")
902                     (match_operand:SI 2 "s_register_operand" "r")))
903    (set (match_operand:SI 0 "s_register_operand" "=r")
904         (minus:SI (minus:SI (match_dup 1)
905                             (match_dup 2))
906                   (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
907   "TARGET_32BIT"
908   "sbcs\\t%0, %1, %2"
909   [(set_attr "conds" "set")
910    (set_attr "type" "adcs_reg")]
913 (define_insn "*subsi3_carryin_compare_const"
914   [(set (reg:CC CC_REGNUM)
915         (compare:CC (match_operand:SI 1 "reg_or_int_operand" "r")
916                     (match_operand:SI 2 "arm_not_operand" "K")))
917    (set (match_operand:SI 0 "s_register_operand" "=r")
918         (minus:SI (plus:SI (match_dup 1)
919                            (match_dup 2))
920                   (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
921   "TARGET_32BIT"
922   "sbcs\\t%0, %1, #%B2"
923   [(set_attr "conds" "set")
924    (set_attr "type" "adcs_imm")]
927 (define_insn "*subsi3_carryin_shift"
928   [(set (match_operand:SI 0 "s_register_operand" "=r")
929         (minus:SI (minus:SI
930                   (match_operand:SI 1 "s_register_operand" "r")
931                   (match_operator:SI 2 "shift_operator"
932                    [(match_operand:SI 3 "s_register_operand" "r")
933                     (match_operand:SI 4 "reg_or_int_operand" "rM")]))
934                  (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
935   "TARGET_32BIT"
936   "sbc%?\\t%0, %1, %3%S2"
937   [(set_attr "conds" "use")
938    (set_attr "predicable" "yes")
939    (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
940                       (const_string "alu_shift_imm")
941                      (const_string "alu_shift_reg")))]
944 (define_insn "*rsbsi3_carryin_shift"
945   [(set (match_operand:SI 0 "s_register_operand" "=r")
946         (minus:SI (minus:SI
947                   (match_operator:SI 2 "shift_operator"
948                    [(match_operand:SI 3 "s_register_operand" "r")
949                     (match_operand:SI 4 "reg_or_int_operand" "rM")])
950                    (match_operand:SI 1 "s_register_operand" "r"))
951                  (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
952   "TARGET_ARM"
953   "rsc%?\\t%0, %1, %3%S2"
954   [(set_attr "conds" "use")
955    (set_attr "predicable" "yes")
956    (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
957                       (const_string "alu_shift_imm")
958                       (const_string "alu_shift_reg")))]
961 ; transform ((x << y) - 1) to ~(~(x-1) << y)  Where X is a constant.
962 (define_split
963   [(set (match_operand:SI 0 "s_register_operand" "")
964         (plus:SI (ashift:SI (match_operand:SI 1 "const_int_operand" "")
965                             (match_operand:SI 2 "s_register_operand" ""))
966                  (const_int -1)))
967    (clobber (match_operand:SI 3 "s_register_operand" ""))]
968   "TARGET_32BIT"
969   [(set (match_dup 3) (match_dup 1))
970    (set (match_dup 0) (not:SI (ashift:SI (match_dup 3) (match_dup 2))))]
971   "
972   operands[1] = GEN_INT (~(INTVAL (operands[1]) - 1));
975 (define_expand "addsf3"
976   [(set (match_operand:SF          0 "s_register_operand" "")
977         (plus:SF (match_operand:SF 1 "s_register_operand" "")
978                  (match_operand:SF 2 "s_register_operand" "")))]
979   "TARGET_32BIT && TARGET_HARD_FLOAT"
980   "
983 (define_expand "adddf3"
984   [(set (match_operand:DF          0 "s_register_operand" "")
985         (plus:DF (match_operand:DF 1 "s_register_operand" "")
986                  (match_operand:DF 2 "s_register_operand" "")))]
987   "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
988   "
991 (define_expand "subdi3"
992  [(parallel
993    [(set (match_operand:DI            0 "s_register_operand" "")
994           (minus:DI (match_operand:DI 1 "s_register_operand" "")
995                     (match_operand:DI 2 "s_register_operand" "")))
996     (clobber (reg:CC CC_REGNUM))])]
997   "TARGET_EITHER"
998   "
999   if (TARGET_THUMB1)
1000     {
1001       if (!REG_P (operands[1]))
1002         operands[1] = force_reg (DImode, operands[1]);
1003       if (!REG_P (operands[2]))
1004         operands[2] = force_reg (DImode, operands[2]);
1005      }  
1006   "
1009 (define_insn_and_split "*arm_subdi3"
1010   [(set (match_operand:DI           0 "s_register_operand" "=&r,&r,&r")
1011         (minus:DI (match_operand:DI 1 "s_register_operand" "0,r,0")
1012                   (match_operand:DI 2 "s_register_operand" "r,0,0")))
1013    (clobber (reg:CC CC_REGNUM))]
1014   "TARGET_32BIT && !TARGET_NEON"
1015   "#"  ; "subs\\t%Q0, %Q1, %Q2\;sbc\\t%R0, %R1, %R2"
1016   "&& reload_completed"
1017   [(parallel [(set (reg:CC CC_REGNUM)
1018                    (compare:CC (match_dup 1) (match_dup 2)))
1019               (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1020    (set (match_dup 3) (minus:SI (minus:SI (match_dup 4) (match_dup 5))
1021                                (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1022   {
1023     operands[3] = gen_highpart (SImode, operands[0]);
1024     operands[0] = gen_lowpart (SImode, operands[0]);
1025     operands[4] = gen_highpart (SImode, operands[1]);
1026     operands[1] = gen_lowpart (SImode, operands[1]);
1027     operands[5] = gen_highpart (SImode, operands[2]);
1028     operands[2] = gen_lowpart (SImode, operands[2]);
1029    }
1030   [(set_attr "conds" "clob")
1031    (set_attr "length" "8")
1032    (set_attr "type" "multiple")]
1035 (define_insn_and_split "*subdi_di_zesidi"
1036   [(set (match_operand:DI           0 "s_register_operand" "=&r,&r")
1037         (minus:DI (match_operand:DI 1 "s_register_operand"  "0,r")
1038                   (zero_extend:DI
1039                    (match_operand:SI 2 "s_register_operand"  "r,r"))))
1040    (clobber (reg:CC CC_REGNUM))]
1041   "TARGET_32BIT"
1042   "#"   ; "subs\\t%Q0, %Q1, %2\;sbc\\t%R0, %R1, #0"
1043   "&& reload_completed"
1044   [(parallel [(set (reg:CC CC_REGNUM)
1045                    (compare:CC (match_dup 1) (match_dup 2)))
1046               (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1047    (set (match_dup 3) (minus:SI (plus:SI (match_dup 4) (match_dup 5))
1048                                 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1049   {
1050     operands[3] = gen_highpart (SImode, operands[0]);
1051     operands[0] = gen_lowpart (SImode, operands[0]);
1052     operands[4] = gen_highpart (SImode, operands[1]);
1053     operands[1] = gen_lowpart (SImode, operands[1]);
1054     operands[5] = GEN_INT (~0);
1055    }
1056   [(set_attr "conds" "clob")
1057    (set_attr "length" "8")
1058    (set_attr "type" "multiple")]
1061 (define_insn_and_split "*subdi_di_sesidi"
1062   [(set (match_operand:DI            0 "s_register_operand" "=&r,&r")
1063         (minus:DI (match_operand:DI  1 "s_register_operand"  "0,r")
1064                   (sign_extend:DI
1065                    (match_operand:SI 2 "s_register_operand"  "r,r"))))
1066    (clobber (reg:CC CC_REGNUM))]
1067   "TARGET_32BIT"
1068   "#"   ; "subs\\t%Q0, %Q1, %2\;sbc\\t%R0, %R1, %2, asr #31"
1069   "&& reload_completed"
1070   [(parallel [(set (reg:CC CC_REGNUM)
1071                    (compare:CC (match_dup 1) (match_dup 2)))
1072               (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1073    (set (match_dup 3) (minus:SI (minus:SI (match_dup 4)
1074                                          (ashiftrt:SI (match_dup 2)
1075                                                       (const_int 31)))
1076                                 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1077   {
1078     operands[3] = gen_highpart (SImode, operands[0]);
1079     operands[0] = gen_lowpart (SImode, operands[0]);
1080     operands[4] = gen_highpart (SImode, operands[1]);
1081     operands[1] = gen_lowpart (SImode, operands[1]);
1082   }
1083   [(set_attr "conds" "clob")
1084    (set_attr "length" "8")
1085    (set_attr "type" "multiple")]
1088 (define_insn_and_split "*subdi_zesidi_di"
1089   [(set (match_operand:DI            0 "s_register_operand" "=&r,&r")
1090         (minus:DI (zero_extend:DI
1091                    (match_operand:SI 2 "s_register_operand"  "r,r"))
1092                   (match_operand:DI  1 "s_register_operand" "0,r")))
1093    (clobber (reg:CC CC_REGNUM))]
1094   "TARGET_ARM"
1095   "#"   ; "rsbs\\t%Q0, %Q1, %2\;rsc\\t%R0, %R1, #0"
1096         ; is equivalent to:
1097         ; "subs\\t%Q0, %2, %Q1\;rsc\\t%R0, %R1, #0"
1098   "&& reload_completed"
1099   [(parallel [(set (reg:CC CC_REGNUM)
1100                    (compare:CC (match_dup 2) (match_dup 1)))
1101               (set (match_dup 0) (minus:SI (match_dup 2) (match_dup 1)))])
1102    (set (match_dup 3) (minus:SI (minus:SI (const_int 0) (match_dup 4))
1103                                (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1104   {
1105     operands[3] = gen_highpart (SImode, operands[0]);
1106     operands[0] = gen_lowpart (SImode, operands[0]);
1107     operands[4] = gen_highpart (SImode, operands[1]);
1108     operands[1] = gen_lowpart (SImode, operands[1]);
1109   }
1110   [(set_attr "conds" "clob")
1111    (set_attr "length" "8")
1112    (set_attr "type" "multiple")]
1115 (define_insn_and_split "*subdi_sesidi_di"
1116   [(set (match_operand:DI            0 "s_register_operand" "=&r,&r")
1117         (minus:DI (sign_extend:DI
1118                    (match_operand:SI 2 "s_register_operand"   "r,r"))
1119                   (match_operand:DI  1 "s_register_operand"  "0,r")))
1120    (clobber (reg:CC CC_REGNUM))]
1121   "TARGET_ARM"
1122   "#"   ; "rsbs\\t%Q0, %Q1, %2\;rsc\\t%R0, %R1, %2, asr #31"
1123         ; is equivalent to:
1124         ; "subs\\t%Q0, %2, %Q1\;rsc\\t%R0, %R1, %2, asr #31"
1125   "&& reload_completed"
1126   [(parallel [(set (reg:CC CC_REGNUM)
1127                    (compare:CC (match_dup 2) (match_dup 1)))
1128               (set (match_dup 0) (minus:SI (match_dup 2) (match_dup 1)))])
1129    (set (match_dup 3) (minus:SI (minus:SI
1130                                 (ashiftrt:SI (match_dup 2)
1131                                              (const_int 31))
1132                                 (match_dup 4))
1133                                (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1134   {
1135     operands[3] = gen_highpart (SImode, operands[0]);
1136     operands[0] = gen_lowpart (SImode, operands[0]);
1137     operands[4] = gen_highpart (SImode, operands[1]);
1138     operands[1] = gen_lowpart (SImode, operands[1]);
1139   }
1140   [(set_attr "conds" "clob")
1141    (set_attr "length" "8")
1142    (set_attr "type" "multiple")]
1145 (define_insn_and_split "*subdi_zesidi_zesidi"
1146   [(set (match_operand:DI            0 "s_register_operand" "=r")
1147         (minus:DI (zero_extend:DI
1148                    (match_operand:SI 1 "s_register_operand"  "r"))
1149                   (zero_extend:DI
1150                    (match_operand:SI 2 "s_register_operand"  "r"))))
1151    (clobber (reg:CC CC_REGNUM))]
1152   "TARGET_32BIT"
1153   "#"   ; "subs\\t%Q0, %1, %2\;sbc\\t%R0, %1, %1"
1154   "&& reload_completed"
1155   [(parallel [(set (reg:CC CC_REGNUM)
1156                    (compare:CC (match_dup 1) (match_dup 2)))
1157               (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1158    (set (match_dup 3) (minus:SI (minus:SI (match_dup 1) (match_dup 1))
1159                                (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1160   {
1161        operands[3] = gen_highpart (SImode, operands[0]);
1162        operands[0] = gen_lowpart (SImode, operands[0]);
1163   }
1164   [(set_attr "conds" "clob")
1165    (set_attr "length" "8")
1166    (set_attr "type" "multiple")]
1169 (define_expand "subsi3"
1170   [(set (match_operand:SI           0 "s_register_operand" "")
1171         (minus:SI (match_operand:SI 1 "reg_or_int_operand" "")
1172                   (match_operand:SI 2 "s_register_operand" "")))]
1173   "TARGET_EITHER"
1174   "
1175   if (CONST_INT_P (operands[1]))
1176     {
1177       if (TARGET_32BIT)
1178         {
1179           if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[1]), MINUS))
1180             operands[1] = force_reg (SImode, operands[1]);
1181           else
1182             {
1183               arm_split_constant (MINUS, SImode, NULL_RTX,
1184                                   INTVAL (operands[1]), operands[0],
1185                                   operands[2],
1186                                   optimize && can_create_pseudo_p ());
1187               DONE;
1188             }
1189         }
1190       else /* TARGET_THUMB1 */
1191         operands[1] = force_reg (SImode, operands[1]);
1192     }
1193   "
1196 ; ??? Check Thumb-2 split length
1197 (define_insn_and_split "*arm_subsi3_insn"
1198   [(set (match_operand:SI           0 "s_register_operand" "=l,l ,l ,l ,r,r,r,rk,r")
1199         (minus:SI (match_operand:SI 1 "reg_or_int_operand" "l ,0 ,l ,Pz,I,r,r,k ,?n")
1200                   (match_operand:SI 2 "reg_or_int_operand" "l ,Py,Pd,l ,r,I,r,r ,r")))]
1201   "TARGET_32BIT"
1202   "@
1203    sub%?\\t%0, %1, %2
1204    sub%?\\t%0, %2
1205    sub%?\\t%0, %1, %2
1206    rsb%?\\t%0, %2, %1
1207    rsb%?\\t%0, %2, %1
1208    sub%?\\t%0, %1, %2
1209    sub%?\\t%0, %1, %2
1210    sub%?\\t%0, %1, %2
1211    #"
1212   "&& (CONST_INT_P (operands[1])
1213        && !const_ok_for_arm (INTVAL (operands[1])))"
1214   [(clobber (const_int 0))]
1215   "
1216   arm_split_constant (MINUS, SImode, curr_insn,
1217                       INTVAL (operands[1]), operands[0], operands[2], 0);
1218   DONE;
1219   "
1220   [(set_attr "length" "4,4,4,4,4,4,4,4,16")
1221    (set_attr "arch" "t2,t2,t2,t2,*,*,*,*,*")
1222    (set_attr "predicable" "yes")
1223    (set_attr "predicable_short_it" "yes,yes,yes,yes,no,no,no,no,no")
1224    (set_attr "type" "alu_sreg,alu_sreg,alu_sreg,alu_sreg,alu_imm,alu_imm,alu_sreg,alu_sreg,multiple")]
1227 (define_peephole2
1228   [(match_scratch:SI 3 "r")
1229    (set (match_operand:SI 0 "arm_general_register_operand" "")
1230         (minus:SI (match_operand:SI 1 "const_int_operand" "")
1231                   (match_operand:SI 2 "arm_general_register_operand" "")))]
1232   "TARGET_32BIT
1233    && !const_ok_for_arm (INTVAL (operands[1]))
1234    && const_ok_for_arm (~INTVAL (operands[1]))"
1235   [(set (match_dup 3) (match_dup 1))
1236    (set (match_dup 0) (minus:SI (match_dup 3) (match_dup 2)))]
1237   ""
1240 (define_insn "subsi3_compare0"
1241   [(set (reg:CC_NOOV CC_REGNUM)
1242         (compare:CC_NOOV
1243          (minus:SI (match_operand:SI 1 "arm_rhs_operand" "r,r,I")
1244                    (match_operand:SI 2 "arm_rhs_operand" "I,r,r"))
1245          (const_int 0)))
1246    (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
1247         (minus:SI (match_dup 1) (match_dup 2)))]
1248   "TARGET_32BIT"
1249   "@
1250    subs%?\\t%0, %1, %2
1251    subs%?\\t%0, %1, %2
1252    rsbs%?\\t%0, %2, %1"
1253   [(set_attr "conds" "set")
1254    (set_attr "type"  "alus_imm,alus_sreg,alus_sreg")]
1257 (define_insn "subsi3_compare"
1258   [(set (reg:CC CC_REGNUM)
1259         (compare:CC (match_operand:SI 1 "arm_rhs_operand" "r,r,I")
1260                     (match_operand:SI 2 "arm_rhs_operand" "I,r,r")))
1261    (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
1262         (minus:SI (match_dup 1) (match_dup 2)))]
1263   "TARGET_32BIT"
1264   "@
1265    subs%?\\t%0, %1, %2
1266    subs%?\\t%0, %1, %2
1267    rsbs%?\\t%0, %2, %1"
1268   [(set_attr "conds" "set")
1269    (set_attr "type" "alus_imm,alus_sreg,alus_sreg")]
1272 (define_expand "subsf3"
1273   [(set (match_operand:SF           0 "s_register_operand" "")
1274         (minus:SF (match_operand:SF 1 "s_register_operand" "")
1275                   (match_operand:SF 2 "s_register_operand" "")))]
1276   "TARGET_32BIT && TARGET_HARD_FLOAT"
1277   "
1280 (define_expand "subdf3"
1281   [(set (match_operand:DF           0 "s_register_operand" "")
1282         (minus:DF (match_operand:DF 1 "s_register_operand" "")
1283                   (match_operand:DF 2 "s_register_operand" "")))]
1284   "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
1285   "
1289 ;; Multiplication insns
1291 (define_expand "mulhi3"
1292   [(set (match_operand:HI 0 "s_register_operand" "")
1293         (mult:HI (match_operand:HI 1 "s_register_operand" "")
1294                  (match_operand:HI 2 "s_register_operand" "")))]
1295   "TARGET_DSP_MULTIPLY"
1296   "
1297   {
1298     rtx result = gen_reg_rtx (SImode);
1299     emit_insn (gen_mulhisi3 (result, operands[1], operands[2]));
1300     emit_move_insn (operands[0], gen_lowpart (HImode, result));
1301     DONE;
1302   }"
1305 (define_expand "mulsi3"
1306   [(set (match_operand:SI          0 "s_register_operand" "")
1307         (mult:SI (match_operand:SI 2 "s_register_operand" "")
1308                  (match_operand:SI 1 "s_register_operand" "")))]
1309   "TARGET_EITHER"
1310   ""
1313 ;; Use `&' and then `0' to prevent the operands 0 and 1 being the same
1314 (define_insn "*arm_mulsi3"
1315   [(set (match_operand:SI          0 "s_register_operand" "=&r,&r")
1316         (mult:SI (match_operand:SI 2 "s_register_operand" "r,r")
1317                  (match_operand:SI 1 "s_register_operand" "%0,r")))]
1318   "TARGET_32BIT && !arm_arch6"
1319   "mul%?\\t%0, %2, %1"
1320   [(set_attr "type" "mul")
1321    (set_attr "predicable" "yes")]
1324 (define_insn "*arm_mulsi3_v6"
1325   [(set (match_operand:SI          0 "s_register_operand" "=l,l,r")
1326         (mult:SI (match_operand:SI 1 "s_register_operand" "0,l,r")
1327                  (match_operand:SI 2 "s_register_operand" "l,0,r")))]
1328   "TARGET_32BIT && arm_arch6"
1329   "mul%?\\t%0, %1, %2"
1330   [(set_attr "type" "mul")
1331    (set_attr "predicable" "yes")
1332    (set_attr "arch" "t2,t2,*")
1333    (set_attr "length" "4")
1334    (set_attr "predicable_short_it" "yes,yes,no")]
1337 (define_insn "*mulsi3_compare0"
1338   [(set (reg:CC_NOOV CC_REGNUM)
1339         (compare:CC_NOOV (mult:SI
1340                           (match_operand:SI 2 "s_register_operand" "r,r")
1341                           (match_operand:SI 1 "s_register_operand" "%0,r"))
1342                          (const_int 0)))
1343    (set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1344         (mult:SI (match_dup 2) (match_dup 1)))]
1345   "TARGET_ARM && !arm_arch6"
1346   "muls%?\\t%0, %2, %1"
1347   [(set_attr "conds" "set")
1348    (set_attr "type" "muls")]
1351 (define_insn "*mulsi3_compare0_v6"
1352   [(set (reg:CC_NOOV CC_REGNUM)
1353         (compare:CC_NOOV (mult:SI
1354                           (match_operand:SI 2 "s_register_operand" "r")
1355                           (match_operand:SI 1 "s_register_operand" "r"))
1356                          (const_int 0)))
1357    (set (match_operand:SI 0 "s_register_operand" "=r")
1358         (mult:SI (match_dup 2) (match_dup 1)))]
1359   "TARGET_ARM && arm_arch6 && optimize_size"
1360   "muls%?\\t%0, %2, %1"
1361   [(set_attr "conds" "set")
1362    (set_attr "type" "muls")]
1365 (define_insn "*mulsi_compare0_scratch"
1366   [(set (reg:CC_NOOV CC_REGNUM)
1367         (compare:CC_NOOV (mult:SI
1368                           (match_operand:SI 2 "s_register_operand" "r,r")
1369                           (match_operand:SI 1 "s_register_operand" "%0,r"))
1370                          (const_int 0)))
1371    (clobber (match_scratch:SI 0 "=&r,&r"))]
1372   "TARGET_ARM && !arm_arch6"
1373   "muls%?\\t%0, %2, %1"
1374   [(set_attr "conds" "set")
1375    (set_attr "type" "muls")]
1378 (define_insn "*mulsi_compare0_scratch_v6"
1379   [(set (reg:CC_NOOV CC_REGNUM)
1380         (compare:CC_NOOV (mult:SI
1381                           (match_operand:SI 2 "s_register_operand" "r")
1382                           (match_operand:SI 1 "s_register_operand" "r"))
1383                          (const_int 0)))
1384    (clobber (match_scratch:SI 0 "=r"))]
1385   "TARGET_ARM && arm_arch6 && optimize_size"
1386   "muls%?\\t%0, %2, %1"
1387   [(set_attr "conds" "set")
1388    (set_attr "type" "muls")]
1391 ;; Unnamed templates to match MLA instruction.
1393 (define_insn "*mulsi3addsi"
1394   [(set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r,&r")
1395         (plus:SI
1396           (mult:SI (match_operand:SI 2 "s_register_operand" "r,r,r,r")
1397                    (match_operand:SI 1 "s_register_operand" "%0,r,0,r"))
1398           (match_operand:SI 3 "s_register_operand" "r,r,0,0")))]
1399   "TARGET_32BIT && !arm_arch6"
1400   "mla%?\\t%0, %2, %1, %3"
1401   [(set_attr "type" "mla")
1402    (set_attr "predicable" "yes")]
1405 (define_insn "*mulsi3addsi_v6"
1406   [(set (match_operand:SI 0 "s_register_operand" "=r")
1407         (plus:SI
1408           (mult:SI (match_operand:SI 2 "s_register_operand" "r")
1409                    (match_operand:SI 1 "s_register_operand" "r"))
1410           (match_operand:SI 3 "s_register_operand" "r")))]
1411   "TARGET_32BIT && arm_arch6"
1412   "mla%?\\t%0, %2, %1, %3"
1413   [(set_attr "type" "mla")
1414    (set_attr "predicable" "yes")
1415    (set_attr "predicable_short_it" "no")]
1418 (define_insn "*mulsi3addsi_compare0"
1419   [(set (reg:CC_NOOV CC_REGNUM)
1420         (compare:CC_NOOV
1421          (plus:SI (mult:SI
1422                    (match_operand:SI 2 "s_register_operand" "r,r,r,r")
1423                    (match_operand:SI 1 "s_register_operand" "%0,r,0,r"))
1424                   (match_operand:SI 3 "s_register_operand" "r,r,0,0"))
1425          (const_int 0)))
1426    (set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r,&r")
1427         (plus:SI (mult:SI (match_dup 2) (match_dup 1))
1428                  (match_dup 3)))]
1429   "TARGET_ARM && arm_arch6"
1430   "mlas%?\\t%0, %2, %1, %3"
1431   [(set_attr "conds" "set")
1432    (set_attr "type" "mlas")]
1435 (define_insn "*mulsi3addsi_compare0_v6"
1436   [(set (reg:CC_NOOV CC_REGNUM)
1437         (compare:CC_NOOV
1438          (plus:SI (mult:SI
1439                    (match_operand:SI 2 "s_register_operand" "r")
1440                    (match_operand:SI 1 "s_register_operand" "r"))
1441                   (match_operand:SI 3 "s_register_operand" "r"))
1442          (const_int 0)))
1443    (set (match_operand:SI 0 "s_register_operand" "=r")
1444         (plus:SI (mult:SI (match_dup 2) (match_dup 1))
1445                  (match_dup 3)))]
1446   "TARGET_ARM && arm_arch6 && optimize_size"
1447   "mlas%?\\t%0, %2, %1, %3"
1448   [(set_attr "conds" "set")
1449    (set_attr "type" "mlas")]
1452 (define_insn "*mulsi3addsi_compare0_scratch"
1453   [(set (reg:CC_NOOV CC_REGNUM)
1454         (compare:CC_NOOV
1455          (plus:SI (mult:SI
1456                    (match_operand:SI 2 "s_register_operand" "r,r,r,r")
1457                    (match_operand:SI 1 "s_register_operand" "%0,r,0,r"))
1458                   (match_operand:SI 3 "s_register_operand" "?r,r,0,0"))
1459          (const_int 0)))
1460    (clobber (match_scratch:SI 0 "=&r,&r,&r,&r"))]
1461   "TARGET_ARM && !arm_arch6"
1462   "mlas%?\\t%0, %2, %1, %3"
1463   [(set_attr "conds" "set")
1464    (set_attr "type" "mlas")]
1467 (define_insn "*mulsi3addsi_compare0_scratch_v6"
1468   [(set (reg:CC_NOOV CC_REGNUM)
1469         (compare:CC_NOOV
1470          (plus:SI (mult:SI
1471                    (match_operand:SI 2 "s_register_operand" "r")
1472                    (match_operand:SI 1 "s_register_operand" "r"))
1473                   (match_operand:SI 3 "s_register_operand" "r"))
1474          (const_int 0)))
1475    (clobber (match_scratch:SI 0 "=r"))]
1476   "TARGET_ARM && arm_arch6 && optimize_size"
1477   "mlas%?\\t%0, %2, %1, %3"
1478   [(set_attr "conds" "set")
1479    (set_attr "type" "mlas")]
1482 (define_insn "*mulsi3subsi"
1483   [(set (match_operand:SI 0 "s_register_operand" "=r")
1484         (minus:SI
1485           (match_operand:SI 3 "s_register_operand" "r")
1486           (mult:SI (match_operand:SI 2 "s_register_operand" "r")
1487                    (match_operand:SI 1 "s_register_operand" "r"))))]
1488   "TARGET_32BIT && arm_arch_thumb2"
1489   "mls%?\\t%0, %2, %1, %3"
1490   [(set_attr "type" "mla")
1491    (set_attr "predicable" "yes")
1492    (set_attr "predicable_short_it" "no")]
1495 (define_expand "maddsidi4"
1496   [(set (match_operand:DI 0 "s_register_operand" "")
1497         (plus:DI
1498          (mult:DI
1499           (sign_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1500           (sign_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1501          (match_operand:DI 3 "s_register_operand" "")))]
1502   "TARGET_32BIT && arm_arch3m"
1503   "")
1505 (define_insn "*mulsidi3adddi"
1506   [(set (match_operand:DI 0 "s_register_operand" "=&r")
1507         (plus:DI
1508          (mult:DI
1509           (sign_extend:DI (match_operand:SI 2 "s_register_operand" "%r"))
1510           (sign_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1511          (match_operand:DI 1 "s_register_operand" "0")))]
1512   "TARGET_32BIT && arm_arch3m && !arm_arch6"
1513   "smlal%?\\t%Q0, %R0, %3, %2"
1514   [(set_attr "type" "smlal")
1515    (set_attr "predicable" "yes")]
1518 (define_insn "*mulsidi3adddi_v6"
1519   [(set (match_operand:DI 0 "s_register_operand" "=r")
1520         (plus:DI
1521          (mult:DI
1522           (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r"))
1523           (sign_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1524          (match_operand:DI 1 "s_register_operand" "0")))]
1525   "TARGET_32BIT && arm_arch6"
1526   "smlal%?\\t%Q0, %R0, %3, %2"
1527   [(set_attr "type" "smlal")
1528    (set_attr "predicable" "yes")
1529    (set_attr "predicable_short_it" "no")]
1532 ;; 32x32->64 widening multiply.
1533 ;; As with mulsi3, the only difference between the v3-5 and v6+
1534 ;; versions of these patterns is the requirement that the output not
1535 ;; overlap the inputs, but that still means we have to have a named
1536 ;; expander and two different starred insns.
1538 (define_expand "mulsidi3"
1539   [(set (match_operand:DI 0 "s_register_operand" "")
1540         (mult:DI
1541          (sign_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1542          (sign_extend:DI (match_operand:SI 2 "s_register_operand" ""))))]
1543   "TARGET_32BIT && arm_arch3m"
1544   ""
1547 (define_insn "*mulsidi3_nov6"
1548   [(set (match_operand:DI 0 "s_register_operand" "=&r")
1549         (mult:DI
1550          (sign_extend:DI (match_operand:SI 1 "s_register_operand" "%r"))
1551          (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1552   "TARGET_32BIT && arm_arch3m && !arm_arch6"
1553   "smull%?\\t%Q0, %R0, %1, %2"
1554   [(set_attr "type" "smull")
1555    (set_attr "predicable" "yes")]
1558 (define_insn "*mulsidi3_v6"
1559   [(set (match_operand:DI 0 "s_register_operand" "=r")
1560         (mult:DI
1561          (sign_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1562          (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1563   "TARGET_32BIT && arm_arch6"
1564   "smull%?\\t%Q0, %R0, %1, %2"
1565   [(set_attr "type" "smull")
1566    (set_attr "predicable" "yes")
1567    (set_attr "predicable_short_it" "no")]
1570 (define_expand "umulsidi3"
1571   [(set (match_operand:DI 0 "s_register_operand" "")
1572         (mult:DI
1573          (zero_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1574          (zero_extend:DI (match_operand:SI 2 "s_register_operand" ""))))]
1575   "TARGET_32BIT && arm_arch3m"
1576   ""
1579 (define_insn "*umulsidi3_nov6"
1580   [(set (match_operand:DI 0 "s_register_operand" "=&r")
1581         (mult:DI
1582          (zero_extend:DI (match_operand:SI 1 "s_register_operand" "%r"))
1583          (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1584   "TARGET_32BIT && arm_arch3m && !arm_arch6"
1585   "umull%?\\t%Q0, %R0, %1, %2"
1586   [(set_attr "type" "umull")
1587    (set_attr "predicable" "yes")]
1590 (define_insn "*umulsidi3_v6"
1591   [(set (match_operand:DI 0 "s_register_operand" "=r")
1592         (mult:DI
1593          (zero_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1594          (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1595   "TARGET_32BIT && arm_arch6"
1596   "umull%?\\t%Q0, %R0, %1, %2"
1597   [(set_attr "type" "umull")
1598    (set_attr "predicable" "yes")
1599    (set_attr "predicable_short_it" "no")]
1602 (define_expand "umaddsidi4"
1603   [(set (match_operand:DI 0 "s_register_operand" "")
1604         (plus:DI
1605          (mult:DI
1606           (zero_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1607           (zero_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1608          (match_operand:DI 3 "s_register_operand" "")))]
1609   "TARGET_32BIT && arm_arch3m"
1610   "")
1612 (define_insn "*umulsidi3adddi"
1613   [(set (match_operand:DI 0 "s_register_operand" "=&r")
1614         (plus:DI
1615          (mult:DI
1616           (zero_extend:DI (match_operand:SI 2 "s_register_operand" "%r"))
1617           (zero_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1618          (match_operand:DI 1 "s_register_operand" "0")))]
1619   "TARGET_32BIT && arm_arch3m && !arm_arch6"
1620   "umlal%?\\t%Q0, %R0, %3, %2"
1621   [(set_attr "type" "umlal")
1622    (set_attr "predicable" "yes")]
1625 (define_insn "*umulsidi3adddi_v6"
1626   [(set (match_operand:DI 0 "s_register_operand" "=r")
1627         (plus:DI
1628          (mult:DI
1629           (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r"))
1630           (zero_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1631          (match_operand:DI 1 "s_register_operand" "0")))]
1632   "TARGET_32BIT && arm_arch6"
1633   "umlal%?\\t%Q0, %R0, %3, %2"
1634   [(set_attr "type" "umlal")
1635    (set_attr "predicable" "yes")
1636    (set_attr "predicable_short_it" "no")]
1639 (define_expand "smulsi3_highpart"
1640   [(parallel
1641     [(set (match_operand:SI 0 "s_register_operand" "")
1642           (truncate:SI
1643            (lshiftrt:DI
1644             (mult:DI
1645              (sign_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1646              (sign_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1647             (const_int 32))))
1648      (clobber (match_scratch:SI 3 ""))])]
1649   "TARGET_32BIT && arm_arch3m"
1650   ""
1653 (define_insn "*smulsi3_highpart_nov6"
1654   [(set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1655         (truncate:SI
1656          (lshiftrt:DI
1657           (mult:DI
1658            (sign_extend:DI (match_operand:SI 1 "s_register_operand" "%0,r"))
1659            (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r,r")))
1660           (const_int 32))))
1661    (clobber (match_scratch:SI 3 "=&r,&r"))]
1662   "TARGET_32BIT && arm_arch3m && !arm_arch6"
1663   "smull%?\\t%3, %0, %2, %1"
1664   [(set_attr "type" "smull")
1665    (set_attr "predicable" "yes")]
1668 (define_insn "*smulsi3_highpart_v6"
1669   [(set (match_operand:SI 0 "s_register_operand" "=r")
1670         (truncate:SI
1671          (lshiftrt:DI
1672           (mult:DI
1673            (sign_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1674            (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r")))
1675           (const_int 32))))
1676    (clobber (match_scratch:SI 3 "=r"))]
1677   "TARGET_32BIT && arm_arch6"
1678   "smull%?\\t%3, %0, %2, %1"
1679   [(set_attr "type" "smull")
1680    (set_attr "predicable" "yes")
1681    (set_attr "predicable_short_it" "no")]
1684 (define_expand "umulsi3_highpart"
1685   [(parallel
1686     [(set (match_operand:SI 0 "s_register_operand" "")
1687           (truncate:SI
1688            (lshiftrt:DI
1689             (mult:DI
1690              (zero_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1691               (zero_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1692             (const_int 32))))
1693      (clobber (match_scratch:SI 3 ""))])]
1694   "TARGET_32BIT && arm_arch3m"
1695   ""
1698 (define_insn "*umulsi3_highpart_nov6"
1699   [(set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1700         (truncate:SI
1701          (lshiftrt:DI
1702           (mult:DI
1703            (zero_extend:DI (match_operand:SI 1 "s_register_operand" "%0,r"))
1704            (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r,r")))
1705           (const_int 32))))
1706    (clobber (match_scratch:SI 3 "=&r,&r"))]
1707   "TARGET_32BIT && arm_arch3m && !arm_arch6"
1708   "umull%?\\t%3, %0, %2, %1"
1709   [(set_attr "type" "umull")
1710    (set_attr "predicable" "yes")]
1713 (define_insn "*umulsi3_highpart_v6"
1714   [(set (match_operand:SI 0 "s_register_operand" "=r")
1715         (truncate:SI
1716          (lshiftrt:DI
1717           (mult:DI
1718            (zero_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1719            (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r")))
1720           (const_int 32))))
1721    (clobber (match_scratch:SI 3 "=r"))]
1722   "TARGET_32BIT && arm_arch6"
1723   "umull%?\\t%3, %0, %2, %1"
1724   [(set_attr "type" "umull")
1725    (set_attr "predicable" "yes")
1726    (set_attr "predicable_short_it" "no")]
1729 (define_insn "mulhisi3"
1730   [(set (match_operand:SI 0 "s_register_operand" "=r")
1731         (mult:SI (sign_extend:SI
1732                   (match_operand:HI 1 "s_register_operand" "%r"))
1733                  (sign_extend:SI
1734                   (match_operand:HI 2 "s_register_operand" "r"))))]
1735   "TARGET_DSP_MULTIPLY"
1736   "smulbb%?\\t%0, %1, %2"
1737   [(set_attr "type" "smulxy")
1738    (set_attr "predicable" "yes")]
1741 (define_insn "*mulhisi3tb"
1742   [(set (match_operand:SI 0 "s_register_operand" "=r")
1743         (mult:SI (ashiftrt:SI
1744                   (match_operand:SI 1 "s_register_operand" "r")
1745                   (const_int 16))
1746                  (sign_extend:SI
1747                   (match_operand:HI 2 "s_register_operand" "r"))))]
1748   "TARGET_DSP_MULTIPLY"
1749   "smultb%?\\t%0, %1, %2"
1750   [(set_attr "type" "smulxy")
1751    (set_attr "predicable" "yes")
1752    (set_attr "predicable_short_it" "no")]
1755 (define_insn "*mulhisi3bt"
1756   [(set (match_operand:SI 0 "s_register_operand" "=r")
1757         (mult:SI (sign_extend:SI
1758                   (match_operand:HI 1 "s_register_operand" "r"))
1759                  (ashiftrt:SI
1760                   (match_operand:SI 2 "s_register_operand" "r")
1761                   (const_int 16))))]
1762   "TARGET_DSP_MULTIPLY"
1763   "smulbt%?\\t%0, %1, %2"
1764   [(set_attr "type" "smulxy")
1765    (set_attr "predicable" "yes")
1766    (set_attr "predicable_short_it" "no")]
1769 (define_insn "*mulhisi3tt"
1770   [(set (match_operand:SI 0 "s_register_operand" "=r")
1771         (mult:SI (ashiftrt:SI
1772                   (match_operand:SI 1 "s_register_operand" "r")
1773                   (const_int 16))
1774                  (ashiftrt:SI
1775                   (match_operand:SI 2 "s_register_operand" "r")
1776                   (const_int 16))))]
1777   "TARGET_DSP_MULTIPLY"
1778   "smultt%?\\t%0, %1, %2"
1779   [(set_attr "type" "smulxy")
1780    (set_attr "predicable" "yes")
1781    (set_attr "predicable_short_it" "no")]
1784 (define_insn "maddhisi4"
1785   [(set (match_operand:SI 0 "s_register_operand" "=r")
1786         (plus:SI (mult:SI (sign_extend:SI
1787                            (match_operand:HI 1 "s_register_operand" "r"))
1788                           (sign_extend:SI
1789                            (match_operand:HI 2 "s_register_operand" "r")))
1790                  (match_operand:SI 3 "s_register_operand" "r")))]
1791   "TARGET_DSP_MULTIPLY"
1792   "smlabb%?\\t%0, %1, %2, %3"
1793   [(set_attr "type" "smlaxy")
1794    (set_attr "predicable" "yes")
1795    (set_attr "predicable_short_it" "no")]
1798 ;; Note: there is no maddhisi4ibt because this one is canonical form
1799 (define_insn "*maddhisi4tb"
1800   [(set (match_operand:SI 0 "s_register_operand" "=r")
1801         (plus:SI (mult:SI (ashiftrt:SI
1802                            (match_operand:SI 1 "s_register_operand" "r")
1803                            (const_int 16))
1804                           (sign_extend:SI
1805                            (match_operand:HI 2 "s_register_operand" "r")))
1806                  (match_operand:SI 3 "s_register_operand" "r")))]
1807   "TARGET_DSP_MULTIPLY"
1808   "smlatb%?\\t%0, %1, %2, %3"
1809   [(set_attr "type" "smlaxy")
1810    (set_attr "predicable" "yes")
1811    (set_attr "predicable_short_it" "no")]
1814 (define_insn "*maddhisi4tt"
1815   [(set (match_operand:SI 0 "s_register_operand" "=r")
1816         (plus:SI (mult:SI (ashiftrt:SI
1817                            (match_operand:SI 1 "s_register_operand" "r")
1818                            (const_int 16))
1819                           (ashiftrt:SI
1820                            (match_operand:SI 2 "s_register_operand" "r")
1821                            (const_int 16)))
1822                  (match_operand:SI 3 "s_register_operand" "r")))]
1823   "TARGET_DSP_MULTIPLY"
1824   "smlatt%?\\t%0, %1, %2, %3"
1825   [(set_attr "type" "smlaxy")
1826    (set_attr "predicable" "yes")
1827    (set_attr "predicable_short_it" "no")]
1830 (define_insn "maddhidi4"
1831   [(set (match_operand:DI 0 "s_register_operand" "=r")
1832         (plus:DI
1833           (mult:DI (sign_extend:DI
1834                     (match_operand:HI 1 "s_register_operand" "r"))
1835                    (sign_extend:DI
1836                     (match_operand:HI 2 "s_register_operand" "r")))
1837           (match_operand:DI 3 "s_register_operand" "0")))]
1838   "TARGET_DSP_MULTIPLY"
1839   "smlalbb%?\\t%Q0, %R0, %1, %2"
1840   [(set_attr "type" "smlalxy")
1841    (set_attr "predicable" "yes")
1842    (set_attr "predicable_short_it" "no")])
1844 ;; Note: there is no maddhidi4ibt because this one is canonical form
1845 (define_insn "*maddhidi4tb"
1846   [(set (match_operand:DI 0 "s_register_operand" "=r")
1847         (plus:DI
1848           (mult:DI (sign_extend:DI
1849                     (ashiftrt:SI
1850                      (match_operand:SI 1 "s_register_operand" "r")
1851                      (const_int 16)))
1852                    (sign_extend:DI
1853                     (match_operand:HI 2 "s_register_operand" "r")))
1854           (match_operand:DI 3 "s_register_operand" "0")))]
1855   "TARGET_DSP_MULTIPLY"
1856   "smlaltb%?\\t%Q0, %R0, %1, %2"
1857   [(set_attr "type" "smlalxy")
1858    (set_attr "predicable" "yes")
1859    (set_attr "predicable_short_it" "no")])
1861 (define_insn "*maddhidi4tt"
1862   [(set (match_operand:DI 0 "s_register_operand" "=r")
1863         (plus:DI
1864           (mult:DI (sign_extend:DI
1865                     (ashiftrt:SI
1866                      (match_operand:SI 1 "s_register_operand" "r")
1867                      (const_int 16)))
1868                    (sign_extend:DI
1869                     (ashiftrt:SI
1870                      (match_operand:SI 2 "s_register_operand" "r")
1871                      (const_int 16))))
1872           (match_operand:DI 3 "s_register_operand" "0")))]
1873   "TARGET_DSP_MULTIPLY"
1874   "smlaltt%?\\t%Q0, %R0, %1, %2"
1875   [(set_attr "type" "smlalxy")
1876    (set_attr "predicable" "yes")
1877    (set_attr "predicable_short_it" "no")])
1879 (define_expand "mulsf3"
1880   [(set (match_operand:SF          0 "s_register_operand" "")
1881         (mult:SF (match_operand:SF 1 "s_register_operand" "")
1882                  (match_operand:SF 2 "s_register_operand" "")))]
1883   "TARGET_32BIT && TARGET_HARD_FLOAT"
1884   "
1887 (define_expand "muldf3"
1888   [(set (match_operand:DF          0 "s_register_operand" "")
1889         (mult:DF (match_operand:DF 1 "s_register_operand" "")
1890                  (match_operand:DF 2 "s_register_operand" "")))]
1891   "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
1892   "
1895 ;; Division insns
1897 (define_expand "divsf3"
1898   [(set (match_operand:SF 0 "s_register_operand" "")
1899         (div:SF (match_operand:SF 1 "s_register_operand" "")
1900                 (match_operand:SF 2 "s_register_operand" "")))]
1901   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
1902   "")
1904 (define_expand "divdf3"
1905   [(set (match_operand:DF 0 "s_register_operand" "")
1906         (div:DF (match_operand:DF 1 "s_register_operand" "")
1907                 (match_operand:DF 2 "s_register_operand" "")))]
1908   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
1909   "")
1911 ;; Boolean and,ior,xor insns
1913 ;; Split up double word logical operations
1915 ;; Split up simple DImode logical operations.  Simply perform the logical
1916 ;; operation on the upper and lower halves of the registers.
1917 (define_split
1918   [(set (match_operand:DI 0 "s_register_operand" "")
1919         (match_operator:DI 6 "logical_binary_operator"
1920           [(match_operand:DI 1 "s_register_operand" "")
1921            (match_operand:DI 2 "s_register_operand" "")]))]
1922   "TARGET_32BIT && reload_completed
1923    && ! (TARGET_NEON && IS_VFP_REGNUM (REGNO (operands[0])))
1924    && ! IS_IWMMXT_REGNUM (REGNO (operands[0]))"
1925   [(set (match_dup 0) (match_op_dup:SI 6 [(match_dup 1) (match_dup 2)]))
1926    (set (match_dup 3) (match_op_dup:SI 6 [(match_dup 4) (match_dup 5)]))]
1927   "
1928   {
1929     operands[3] = gen_highpart (SImode, operands[0]);
1930     operands[0] = gen_lowpart (SImode, operands[0]);
1931     operands[4] = gen_highpart (SImode, operands[1]);
1932     operands[1] = gen_lowpart (SImode, operands[1]);
1933     operands[5] = gen_highpart (SImode, operands[2]);
1934     operands[2] = gen_lowpart (SImode, operands[2]);
1935   }"
1938 (define_split
1939   [(set (match_operand:DI 0 "s_register_operand" "")
1940         (match_operator:DI 6 "logical_binary_operator"
1941           [(sign_extend:DI (match_operand:SI 2 "s_register_operand" ""))
1942            (match_operand:DI 1 "s_register_operand" "")]))]
1943   "TARGET_32BIT && reload_completed"
1944   [(set (match_dup 0) (match_op_dup:SI 6 [(match_dup 1) (match_dup 2)]))
1945    (set (match_dup 3) (match_op_dup:SI 6
1946                         [(ashiftrt:SI (match_dup 2) (const_int 31))
1947                          (match_dup 4)]))]
1948   "
1949   {
1950     operands[3] = gen_highpart (SImode, operands[0]);
1951     operands[0] = gen_lowpart (SImode, operands[0]);
1952     operands[4] = gen_highpart (SImode, operands[1]);
1953     operands[1] = gen_lowpart (SImode, operands[1]);
1954     operands[5] = gen_highpart (SImode, operands[2]);
1955     operands[2] = gen_lowpart (SImode, operands[2]);
1956   }"
1959 ;; The zero extend of operand 2 means we can just copy the high part of
1960 ;; operand1 into operand0.
1961 (define_split
1962   [(set (match_operand:DI 0 "s_register_operand" "")
1963         (ior:DI
1964           (zero_extend:DI (match_operand:SI 2 "s_register_operand" ""))
1965           (match_operand:DI 1 "s_register_operand" "")))]
1966   "TARGET_32BIT && operands[0] != operands[1] && reload_completed"
1967   [(set (match_dup 0) (ior:SI (match_dup 1) (match_dup 2)))
1968    (set (match_dup 3) (match_dup 4))]
1969   "
1970   {
1971     operands[4] = gen_highpart (SImode, operands[1]);
1972     operands[3] = gen_highpart (SImode, operands[0]);
1973     operands[0] = gen_lowpart (SImode, operands[0]);
1974     operands[1] = gen_lowpart (SImode, operands[1]);
1975   }"
1978 ;; The zero extend of operand 2 means we can just copy the high part of
1979 ;; operand1 into operand0.
1980 (define_split
1981   [(set (match_operand:DI 0 "s_register_operand" "")
1982         (xor:DI
1983           (zero_extend:DI (match_operand:SI 2 "s_register_operand" ""))
1984           (match_operand:DI 1 "s_register_operand" "")))]
1985   "TARGET_32BIT && operands[0] != operands[1] && reload_completed"
1986   [(set (match_dup 0) (xor:SI (match_dup 1) (match_dup 2)))
1987    (set (match_dup 3) (match_dup 4))]
1988   "
1989   {
1990     operands[4] = gen_highpart (SImode, operands[1]);
1991     operands[3] = gen_highpart (SImode, operands[0]);
1992     operands[0] = gen_lowpart (SImode, operands[0]);
1993     operands[1] = gen_lowpart (SImode, operands[1]);
1994   }"
1997 (define_expand "anddi3"
1998   [(set (match_operand:DI         0 "s_register_operand" "")
1999         (and:DI (match_operand:DI 1 "s_register_operand" "")
2000                 (match_operand:DI 2 "neon_inv_logic_op2" "")))]
2001   "TARGET_32BIT"
2002   ""
2005 (define_insn_and_split "*anddi3_insn"
2006   [(set (match_operand:DI         0 "s_register_operand"     "=w,w ,&r,&r,&r,&r,?w,?w")
2007         (and:DI (match_operand:DI 1 "s_register_operand"     "%w,0 ,0 ,r ,0 ,r ,w ,0")
2008                 (match_operand:DI 2 "arm_anddi_operand_neon" "w ,DL,r ,r ,De,De,w ,DL")))]
2009   "TARGET_32BIT && !TARGET_IWMMXT"
2011   switch (which_alternative)
2012     {
2013     case 0: /* fall through */
2014     case 6: return "vand\t%P0, %P1, %P2";
2015     case 1: /* fall through */
2016     case 7: return neon_output_logic_immediate ("vand", &operands[2],
2017                     DImode, 1, VALID_NEON_QREG_MODE (DImode));
2018     case 2:
2019     case 3:
2020     case 4:
2021     case 5: /* fall through */
2022       return "#";
2023     default: gcc_unreachable ();
2024     }
2026   "TARGET_32BIT && !TARGET_IWMMXT && reload_completed
2027    && !(IS_VFP_REGNUM (REGNO (operands[0])))"
2028   [(set (match_dup 3) (match_dup 4))
2029    (set (match_dup 5) (match_dup 6))]
2030   "
2031   {
2032     operands[3] = gen_lowpart (SImode, operands[0]);
2033     operands[5] = gen_highpart (SImode, operands[0]);
2035     operands[4] = simplify_gen_binary (AND, SImode,
2036                                            gen_lowpart (SImode, operands[1]),
2037                                            gen_lowpart (SImode, operands[2]));
2038     operands[6] = simplify_gen_binary (AND, SImode,
2039                                            gen_highpart (SImode, operands[1]),
2040                                            gen_highpart_mode (SImode, DImode, operands[2]));
2042   }"
2043   [(set_attr "type" "neon_logic,neon_logic,multiple,multiple,\
2044                      multiple,multiple,neon_logic,neon_logic")
2045    (set_attr "arch" "neon_for_64bits,neon_for_64bits,*,*,*,*,
2046                      avoid_neon_for_64bits,avoid_neon_for_64bits")
2047    (set_attr "length" "*,*,8,8,8,8,*,*")
2048   ]
2051 (define_insn_and_split "*anddi_zesidi_di"
2052   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2053         (and:DI (zero_extend:DI
2054                  (match_operand:SI 2 "s_register_operand" "r,r"))
2055                 (match_operand:DI 1 "s_register_operand" "0,r")))]
2056   "TARGET_32BIT"
2057   "#"
2058   "TARGET_32BIT && reload_completed"
2059   ; The zero extend of operand 2 clears the high word of the output
2060   ; operand.
2061   [(set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))
2062    (set (match_dup 3) (const_int 0))]
2063   "
2064   {
2065     operands[3] = gen_highpart (SImode, operands[0]);
2066     operands[0] = gen_lowpart (SImode, operands[0]);
2067     operands[1] = gen_lowpart (SImode, operands[1]);
2068   }"
2069   [(set_attr "length" "8")
2070    (set_attr "type" "multiple")]
2073 (define_insn "*anddi_sesdi_di"
2074   [(set (match_operand:DI          0 "s_register_operand" "=&r,&r")
2075         (and:DI (sign_extend:DI
2076                  (match_operand:SI 2 "s_register_operand" "r,r"))
2077                 (match_operand:DI  1 "s_register_operand" "0,r")))]
2078   "TARGET_32BIT"
2079   "#"
2080   [(set_attr "length" "8")
2081    (set_attr "type" "multiple")]
2084 (define_expand "andsi3"
2085   [(set (match_operand:SI         0 "s_register_operand" "")
2086         (and:SI (match_operand:SI 1 "s_register_operand" "")
2087                 (match_operand:SI 2 "reg_or_int_operand" "")))]
2088   "TARGET_EITHER"
2089   "
2090   if (TARGET_32BIT)
2091     {
2092       if (CONST_INT_P (operands[2]))
2093         {
2094           if (INTVAL (operands[2]) == 255 && arm_arch6)
2095             {
2096               operands[1] = convert_to_mode (QImode, operands[1], 1);
2097               emit_insn (gen_thumb2_zero_extendqisi2_v6 (operands[0],
2098                                                          operands[1]));
2099               DONE;
2100             }
2101           else if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[2]), AND))
2102             operands[2] = force_reg (SImode, operands[2]);
2103           else
2104             {
2105               arm_split_constant (AND, SImode, NULL_RTX,
2106                                   INTVAL (operands[2]), operands[0],
2107                                   operands[1],
2108                                   optimize && can_create_pseudo_p ());
2110               DONE;
2111             }
2112         }
2113     }
2114   else /* TARGET_THUMB1 */
2115     {
2116       if (!CONST_INT_P (operands[2]))
2117         {
2118           rtx tmp = force_reg (SImode, operands[2]);
2119           if (rtx_equal_p (operands[0], operands[1]))
2120             operands[2] = tmp;
2121           else
2122             {
2123               operands[2] = operands[1];
2124               operands[1] = tmp;
2125             }
2126         }
2127       else
2128         {
2129           int i;
2130           
2131           if (((unsigned HOST_WIDE_INT) ~INTVAL (operands[2])) < 256)
2132             {
2133               operands[2] = force_reg (SImode,
2134                                        GEN_INT (~INTVAL (operands[2])));
2135               
2136               emit_insn (gen_thumb1_bicsi3 (operands[0], operands[2], operands[1]));
2137               
2138               DONE;
2139             }
2141           for (i = 9; i <= 31; i++)
2142             {
2143               if ((HOST_WIDE_INT_1 << i) - 1 == INTVAL (operands[2]))
2144                 {
2145                   emit_insn (gen_extzv (operands[0], operands[1], GEN_INT (i),
2146                                         const0_rtx));
2147                   DONE;
2148                 }
2149               else if ((HOST_WIDE_INT_1 << i) - 1
2150                        == ~INTVAL (operands[2]))
2151                 {
2152                   rtx shift = GEN_INT (i);
2153                   rtx reg = gen_reg_rtx (SImode);
2154                 
2155                   emit_insn (gen_lshrsi3 (reg, operands[1], shift));
2156                   emit_insn (gen_ashlsi3 (operands[0], reg, shift));
2157                   
2158                   DONE;
2159                 }
2160             }
2162           operands[2] = force_reg (SImode, operands[2]);
2163         }
2164     }
2165   "
2168 ; ??? Check split length for Thumb-2
2169 (define_insn_and_split "*arm_andsi3_insn"
2170   [(set (match_operand:SI         0 "s_register_operand" "=r,l,r,r,r")
2171         (and:SI (match_operand:SI 1 "s_register_operand" "%r,0,r,r,r")
2172                 (match_operand:SI 2 "reg_or_int_operand" "I,l,K,r,?n")))]
2173   "TARGET_32BIT"
2174   "@
2175    and%?\\t%0, %1, %2
2176    and%?\\t%0, %1, %2
2177    bic%?\\t%0, %1, #%B2
2178    and%?\\t%0, %1, %2
2179    #"
2180   "TARGET_32BIT
2181    && CONST_INT_P (operands[2])
2182    && !(const_ok_for_arm (INTVAL (operands[2]))
2183         || const_ok_for_arm (~INTVAL (operands[2])))"
2184   [(clobber (const_int 0))]
2185   "
2186   arm_split_constant  (AND, SImode, curr_insn, 
2187                        INTVAL (operands[2]), operands[0], operands[1], 0);
2188   DONE;
2189   "
2190   [(set_attr "length" "4,4,4,4,16")
2191    (set_attr "predicable" "yes")
2192    (set_attr "predicable_short_it" "no,yes,no,no,no")
2193    (set_attr "type" "logic_imm,logic_imm,logic_reg,logic_reg,logic_imm")]
2196 (define_insn "*andsi3_compare0"
2197   [(set (reg:CC_NOOV CC_REGNUM)
2198         (compare:CC_NOOV
2199          (and:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
2200                  (match_operand:SI 2 "arm_not_operand" "I,K,r"))
2201          (const_int 0)))
2202    (set (match_operand:SI          0 "s_register_operand" "=r,r,r")
2203         (and:SI (match_dup 1) (match_dup 2)))]
2204   "TARGET_32BIT"
2205   "@
2206    ands%?\\t%0, %1, %2
2207    bics%?\\t%0, %1, #%B2
2208    ands%?\\t%0, %1, %2"
2209   [(set_attr "conds" "set")
2210    (set_attr "type" "logics_imm,logics_imm,logics_reg")]
2213 (define_insn "*andsi3_compare0_scratch"
2214   [(set (reg:CC_NOOV CC_REGNUM)
2215         (compare:CC_NOOV
2216          (and:SI (match_operand:SI 0 "s_register_operand" "r,r,r")
2217                  (match_operand:SI 1 "arm_not_operand" "I,K,r"))
2218          (const_int 0)))
2219    (clobber (match_scratch:SI 2 "=X,r,X"))]
2220   "TARGET_32BIT"
2221   "@
2222    tst%?\\t%0, %1
2223    bics%?\\t%2, %0, #%B1
2224    tst%?\\t%0, %1"
2225   [(set_attr "conds" "set")
2226    (set_attr "type"  "logics_imm,logics_imm,logics_reg")]
2229 (define_insn "*zeroextractsi_compare0_scratch"
2230   [(set (reg:CC_NOOV CC_REGNUM)
2231         (compare:CC_NOOV (zero_extract:SI
2232                           (match_operand:SI 0 "s_register_operand" "r")
2233                           (match_operand 1 "const_int_operand" "n")
2234                           (match_operand 2 "const_int_operand" "n"))
2235                          (const_int 0)))]
2236   "TARGET_32BIT
2237   && (INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) < 32
2238       && INTVAL (operands[1]) > 0 
2239       && INTVAL (operands[1]) + (INTVAL (operands[2]) & 1) <= 8
2240       && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32)"
2241   "*
2242   operands[1] = GEN_INT (((1 << INTVAL (operands[1])) - 1)
2243                          << INTVAL (operands[2]));
2244   output_asm_insn (\"tst%?\\t%0, %1\", operands);
2245   return \"\";
2246   "
2247   [(set_attr "conds" "set")
2248    (set_attr "predicable" "yes")
2249    (set_attr "predicable_short_it" "no")
2250    (set_attr "type" "logics_imm")]
2253 (define_insn_and_split "*ne_zeroextractsi"
2254   [(set (match_operand:SI 0 "s_register_operand" "=r")
2255         (ne:SI (zero_extract:SI
2256                 (match_operand:SI 1 "s_register_operand" "r")
2257                 (match_operand:SI 2 "const_int_operand" "n")
2258                 (match_operand:SI 3 "const_int_operand" "n"))
2259                (const_int 0)))
2260    (clobber (reg:CC CC_REGNUM))]
2261   "TARGET_32BIT
2262    && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2263        && INTVAL (operands[2]) > 0 
2264        && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2265        && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)"
2266   "#"
2267   "TARGET_32BIT
2268    && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2269        && INTVAL (operands[2]) > 0 
2270        && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2271        && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)"
2272   [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2273                    (compare:CC_NOOV (and:SI (match_dup 1) (match_dup 2))
2274                                     (const_int 0)))
2275               (set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))])
2276    (set (match_dup 0)
2277         (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2278                          (match_dup 0) (const_int 1)))]
2279   "
2280   operands[2] = GEN_INT (((1 << INTVAL (operands[2])) - 1)
2281                          << INTVAL (operands[3])); 
2282   "
2283   [(set_attr "conds" "clob")
2284    (set (attr "length")
2285         (if_then_else (eq_attr "is_thumb" "yes")
2286                       (const_int 12)
2287                       (const_int 8)))
2288    (set_attr "type" "multiple")]
2291 (define_insn_and_split "*ne_zeroextractsi_shifted"
2292   [(set (match_operand:SI 0 "s_register_operand" "=r")
2293         (ne:SI (zero_extract:SI
2294                 (match_operand:SI 1 "s_register_operand" "r")
2295                 (match_operand:SI 2 "const_int_operand" "n")
2296                 (const_int 0))
2297                (const_int 0)))
2298    (clobber (reg:CC CC_REGNUM))]
2299   "TARGET_ARM"
2300   "#"
2301   "TARGET_ARM"
2302   [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2303                    (compare:CC_NOOV (ashift:SI (match_dup 1) (match_dup 2))
2304                                     (const_int 0)))
2305               (set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))])
2306    (set (match_dup 0)
2307         (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2308                          (match_dup 0) (const_int 1)))]
2309   "
2310   operands[2] = GEN_INT (32 - INTVAL (operands[2]));
2311   "
2312   [(set_attr "conds" "clob")
2313    (set_attr "length" "8")
2314    (set_attr "type" "multiple")]
2317 (define_insn_and_split "*ite_ne_zeroextractsi"
2318   [(set (match_operand:SI 0 "s_register_operand" "=r")
2319         (if_then_else:SI (ne (zero_extract:SI
2320                               (match_operand:SI 1 "s_register_operand" "r")
2321                               (match_operand:SI 2 "const_int_operand" "n")
2322                               (match_operand:SI 3 "const_int_operand" "n"))
2323                              (const_int 0))
2324                          (match_operand:SI 4 "arm_not_operand" "rIK")
2325                          (const_int 0)))
2326    (clobber (reg:CC CC_REGNUM))]
2327   "TARGET_ARM
2328    && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2329        && INTVAL (operands[2]) > 0 
2330        && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2331        && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)
2332    && !reg_overlap_mentioned_p (operands[0], operands[4])"
2333   "#"
2334   "TARGET_ARM
2335    && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2336        && INTVAL (operands[2]) > 0 
2337        && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2338        && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)
2339    && !reg_overlap_mentioned_p (operands[0], operands[4])"
2340   [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2341                    (compare:CC_NOOV (and:SI (match_dup 1) (match_dup 2))
2342                                     (const_int 0)))
2343               (set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))])
2344    (set (match_dup 0)
2345         (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2346                          (match_dup 0) (match_dup 4)))]
2347   "
2348   operands[2] = GEN_INT (((1 << INTVAL (operands[2])) - 1)
2349                          << INTVAL (operands[3])); 
2350   "
2351   [(set_attr "conds" "clob")
2352    (set_attr "length" "8")
2353    (set_attr "type" "multiple")]
2356 (define_insn_and_split "*ite_ne_zeroextractsi_shifted"
2357   [(set (match_operand:SI 0 "s_register_operand" "=r")
2358         (if_then_else:SI (ne (zero_extract:SI
2359                               (match_operand:SI 1 "s_register_operand" "r")
2360                               (match_operand:SI 2 "const_int_operand" "n")
2361                               (const_int 0))
2362                              (const_int 0))
2363                          (match_operand:SI 3 "arm_not_operand" "rIK")
2364                          (const_int 0)))
2365    (clobber (reg:CC CC_REGNUM))]
2366   "TARGET_ARM && !reg_overlap_mentioned_p (operands[0], operands[3])"
2367   "#"
2368   "TARGET_ARM && !reg_overlap_mentioned_p (operands[0], operands[3])"
2369   [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2370                    (compare:CC_NOOV (ashift:SI (match_dup 1) (match_dup 2))
2371                                     (const_int 0)))
2372               (set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))])
2373    (set (match_dup 0)
2374         (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2375                          (match_dup 0) (match_dup 3)))]
2376   "
2377   operands[2] = GEN_INT (32 - INTVAL (operands[2]));
2378   "
2379   [(set_attr "conds" "clob")
2380    (set_attr "length" "8")
2381    (set_attr "type" "multiple")]
2384 ;; ??? Use Thumb-2 has bitfield insert/extract instructions.
2385 (define_split
2386   [(set (match_operand:SI 0 "s_register_operand" "")
2387         (match_operator:SI 1 "shiftable_operator"
2388          [(zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
2389                            (match_operand:SI 3 "const_int_operand" "")
2390                            (match_operand:SI 4 "const_int_operand" ""))
2391           (match_operand:SI 5 "s_register_operand" "")]))
2392    (clobber (match_operand:SI 6 "s_register_operand" ""))]
2393   "TARGET_ARM"
2394   [(set (match_dup 6) (ashift:SI (match_dup 2) (match_dup 3)))
2395    (set (match_dup 0)
2396         (match_op_dup 1
2397          [(lshiftrt:SI (match_dup 6) (match_dup 4))
2398           (match_dup 5)]))]
2399   "{
2400      HOST_WIDE_INT temp = INTVAL (operands[3]);
2402      operands[3] = GEN_INT (32 - temp - INTVAL (operands[4]));
2403      operands[4] = GEN_INT (32 - temp);
2404    }"
2406   
2407 (define_split
2408   [(set (match_operand:SI 0 "s_register_operand" "")
2409         (match_operator:SI 1 "shiftable_operator"
2410          [(sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
2411                            (match_operand:SI 3 "const_int_operand" "")
2412                            (match_operand:SI 4 "const_int_operand" ""))
2413           (match_operand:SI 5 "s_register_operand" "")]))
2414    (clobber (match_operand:SI 6 "s_register_operand" ""))]
2415   "TARGET_ARM"
2416   [(set (match_dup 6) (ashift:SI (match_dup 2) (match_dup 3)))
2417    (set (match_dup 0)
2418         (match_op_dup 1
2419          [(ashiftrt:SI (match_dup 6) (match_dup 4))
2420           (match_dup 5)]))]
2421   "{
2422      HOST_WIDE_INT temp = INTVAL (operands[3]);
2424      operands[3] = GEN_INT (32 - temp - INTVAL (operands[4]));
2425      operands[4] = GEN_INT (32 - temp);
2426    }"
2428   
2429 ;;; ??? This pattern is bogus.  If operand3 has bits outside the range
2430 ;;; represented by the bitfield, then this will produce incorrect results.
2431 ;;; Somewhere, the value needs to be truncated.  On targets like the m68k,
2432 ;;; which have a real bit-field insert instruction, the truncation happens
2433 ;;; in the bit-field insert instruction itself.  Since arm does not have a
2434 ;;; bit-field insert instruction, we would have to emit code here to truncate
2435 ;;; the value before we insert.  This loses some of the advantage of having
2436 ;;; this insv pattern, so this pattern needs to be reevalutated.
2438 (define_expand "insv"
2439   [(set (zero_extract (match_operand 0 "nonimmediate_operand" "")
2440                       (match_operand 1 "general_operand" "")
2441                       (match_operand 2 "general_operand" ""))
2442         (match_operand 3 "reg_or_int_operand" ""))]
2443   "TARGET_ARM || arm_arch_thumb2"
2444   "
2445   {
2446     int start_bit = INTVAL (operands[2]);
2447     int width = INTVAL (operands[1]);
2448     HOST_WIDE_INT mask = (HOST_WIDE_INT_1 << width) - 1;
2449     rtx target, subtarget;
2451     if (arm_arch_thumb2)
2452       {
2453         if (unaligned_access && MEM_P (operands[0])
2454             && s_register_operand (operands[3], GET_MODE (operands[3]))
2455             && (width == 16 || width == 32) && (start_bit % BITS_PER_UNIT) == 0)
2456           {
2457             rtx base_addr;
2459             if (BYTES_BIG_ENDIAN)
2460               start_bit = GET_MODE_BITSIZE (GET_MODE (operands[3])) - width
2461                           - start_bit;
2463             if (width == 32)
2464               {
2465                 base_addr = adjust_address (operands[0], SImode,
2466                                             start_bit / BITS_PER_UNIT);
2467                 emit_insn (gen_unaligned_storesi (base_addr, operands[3]));
2468               }
2469             else
2470               {
2471                 rtx tmp = gen_reg_rtx (HImode);
2473                 base_addr = adjust_address (operands[0], HImode,
2474                                             start_bit / BITS_PER_UNIT);
2475                 emit_move_insn (tmp, gen_lowpart (HImode, operands[3]));
2476                 emit_insn (gen_unaligned_storehi (base_addr, tmp));
2477               }
2478             DONE;
2479           }
2480         else if (s_register_operand (operands[0], GET_MODE (operands[0])))
2481           {
2482             bool use_bfi = TRUE;
2484             if (CONST_INT_P (operands[3]))
2485               {
2486                 HOST_WIDE_INT val = INTVAL (operands[3]) & mask;
2488                 if (val == 0)
2489                   {
2490                     emit_insn (gen_insv_zero (operands[0], operands[1],
2491                                               operands[2]));
2492                     DONE;
2493                   }
2495                 /* See if the set can be done with a single orr instruction.  */
2496                 if (val == mask && const_ok_for_arm (val << start_bit))
2497                   use_bfi = FALSE;
2498               }
2500             if (use_bfi)
2501               {
2502                 if (!REG_P (operands[3]))
2503                   operands[3] = force_reg (SImode, operands[3]);
2505                 emit_insn (gen_insv_t2 (operands[0], operands[1], operands[2],
2506                                         operands[3]));
2507                 DONE;
2508               }
2509           }
2510         else
2511           FAIL;
2512       }
2514     if (!s_register_operand (operands[0], GET_MODE (operands[0])))
2515       FAIL;
2517     target = copy_rtx (operands[0]);
2518     /* Avoid using a subreg as a subtarget, and avoid writing a paradoxical 
2519        subreg as the final target.  */
2520     if (GET_CODE (target) == SUBREG)
2521       {
2522         subtarget = gen_reg_rtx (SImode);
2523         if (GET_MODE_SIZE (GET_MODE (SUBREG_REG (target)))
2524             < GET_MODE_SIZE (SImode))
2525           target = SUBREG_REG (target);
2526       }
2527     else
2528       subtarget = target;    
2530     if (CONST_INT_P (operands[3]))
2531       {
2532         /* Since we are inserting a known constant, we may be able to
2533            reduce the number of bits that we have to clear so that
2534            the mask becomes simple.  */
2535         /* ??? This code does not check to see if the new mask is actually
2536            simpler.  It may not be.  */
2537         rtx op1 = gen_reg_rtx (SImode);
2538         /* ??? Truncate operand3 to fit in the bitfield.  See comment before
2539            start of this pattern.  */
2540         HOST_WIDE_INT op3_value = mask & INTVAL (operands[3]);
2541         HOST_WIDE_INT mask2 = ((mask & ~op3_value) << start_bit);
2543         emit_insn (gen_andsi3 (op1, operands[0],
2544                                gen_int_mode (~mask2, SImode)));
2545         emit_insn (gen_iorsi3 (subtarget, op1,
2546                                gen_int_mode (op3_value << start_bit, SImode)));
2547       }
2548     else if (start_bit == 0
2549              && !(const_ok_for_arm (mask)
2550                   || const_ok_for_arm (~mask)))
2551       {
2552         /* A Trick, since we are setting the bottom bits in the word,
2553            we can shift operand[3] up, operand[0] down, OR them together
2554            and rotate the result back again.  This takes 3 insns, and
2555            the third might be mergeable into another op.  */
2556         /* The shift up copes with the possibility that operand[3] is
2557            wider than the bitfield.  */
2558         rtx op0 = gen_reg_rtx (SImode);
2559         rtx op1 = gen_reg_rtx (SImode);
2561         emit_insn (gen_ashlsi3 (op0, operands[3], GEN_INT (32 - width)));
2562         emit_insn (gen_lshrsi3 (op1, operands[0], operands[1]));
2563         emit_insn (gen_iorsi3  (op1, op1, op0));
2564         emit_insn (gen_rotlsi3 (subtarget, op1, operands[1]));
2565       }
2566     else if ((width + start_bit == 32)
2567              && !(const_ok_for_arm (mask)
2568                   || const_ok_for_arm (~mask)))
2569       {
2570         /* Similar trick, but slightly less efficient.  */
2572         rtx op0 = gen_reg_rtx (SImode);
2573         rtx op1 = gen_reg_rtx (SImode);
2575         emit_insn (gen_ashlsi3 (op0, operands[3], GEN_INT (32 - width)));
2576         emit_insn (gen_ashlsi3 (op1, operands[0], operands[1]));
2577         emit_insn (gen_lshrsi3 (op1, op1, operands[1]));
2578         emit_insn (gen_iorsi3 (subtarget, op1, op0));
2579       }
2580     else
2581       {
2582         rtx op0 = gen_int_mode (mask, SImode);
2583         rtx op1 = gen_reg_rtx (SImode);
2584         rtx op2 = gen_reg_rtx (SImode);
2586         if (!(const_ok_for_arm (mask) || const_ok_for_arm (~mask)))
2587           {
2588             rtx tmp = gen_reg_rtx (SImode);
2590             emit_insn (gen_movsi (tmp, op0));
2591             op0 = tmp;
2592           }
2594         /* Mask out any bits in operand[3] that are not needed.  */
2595            emit_insn (gen_andsi3 (op1, operands[3], op0));
2597         if (CONST_INT_P (op0)
2598             && (const_ok_for_arm (mask << start_bit)
2599                 || const_ok_for_arm (~(mask << start_bit))))
2600           {
2601             op0 = gen_int_mode (~(mask << start_bit), SImode);
2602             emit_insn (gen_andsi3 (op2, operands[0], op0));
2603           }
2604         else
2605           {
2606             if (CONST_INT_P (op0))
2607               {
2608                 rtx tmp = gen_reg_rtx (SImode);
2610                 emit_insn (gen_movsi (tmp, op0));
2611                 op0 = tmp;
2612               }
2614             if (start_bit != 0)
2615               emit_insn (gen_ashlsi3 (op0, op0, operands[2]));
2616             
2617             emit_insn (gen_andsi_notsi_si (op2, operands[0], op0));
2618           }
2620         if (start_bit != 0)
2621           emit_insn (gen_ashlsi3 (op1, op1, operands[2]));
2623         emit_insn (gen_iorsi3 (subtarget, op1, op2));
2624       }
2626     if (subtarget != target)
2627       {
2628         /* If TARGET is still a SUBREG, then it must be wider than a word,
2629            so we must be careful only to set the subword we were asked to.  */
2630         if (GET_CODE (target) == SUBREG)
2631           emit_move_insn (target, subtarget);
2632         else
2633           emit_move_insn (target, gen_lowpart (GET_MODE (target), subtarget));
2634       }
2636     DONE;
2637   }"
2640 (define_insn "insv_zero"
2641   [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r")
2642                          (match_operand:SI 1 "const_int_M_operand" "M")
2643                          (match_operand:SI 2 "const_int_M_operand" "M"))
2644         (const_int 0))]
2645   "arm_arch_thumb2"
2646   "bfc%?\t%0, %2, %1"
2647   [(set_attr "length" "4")
2648    (set_attr "predicable" "yes")
2649    (set_attr "predicable_short_it" "no")
2650    (set_attr "type" "bfm")]
2653 (define_insn "insv_t2"
2654   [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r")
2655                          (match_operand:SI 1 "const_int_M_operand" "M")
2656                          (match_operand:SI 2 "const_int_M_operand" "M"))
2657         (match_operand:SI 3 "s_register_operand" "r"))]
2658   "arm_arch_thumb2"
2659   "bfi%?\t%0, %3, %2, %1"
2660   [(set_attr "length" "4")
2661    (set_attr "predicable" "yes")
2662    (set_attr "predicable_short_it" "no")
2663    (set_attr "type" "bfm")]
2666 ; constants for op 2 will never be given to these patterns.
2667 (define_insn_and_split "*anddi_notdi_di"
2668   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2669         (and:DI (not:DI (match_operand:DI 1 "s_register_operand" "0,r"))
2670                 (match_operand:DI 2 "s_register_operand" "r,0")))]
2671   "TARGET_32BIT"
2672   "#"
2673   "TARGET_32BIT && reload_completed
2674    && ! (TARGET_NEON && IS_VFP_REGNUM (REGNO (operands[0])))
2675    && ! IS_IWMMXT_REGNUM (REGNO (operands[0]))"
2676   [(set (match_dup 0) (and:SI (not:SI (match_dup 1)) (match_dup 2)))
2677    (set (match_dup 3) (and:SI (not:SI (match_dup 4)) (match_dup 5)))]
2678   "
2679   {
2680     operands[3] = gen_highpart (SImode, operands[0]);
2681     operands[0] = gen_lowpart (SImode, operands[0]);
2682     operands[4] = gen_highpart (SImode, operands[1]);
2683     operands[1] = gen_lowpart (SImode, operands[1]);
2684     operands[5] = gen_highpart (SImode, operands[2]);
2685     operands[2] = gen_lowpart (SImode, operands[2]);
2686   }"
2687   [(set_attr "length" "8")
2688    (set_attr "predicable" "yes")
2689    (set_attr "type" "multiple")]
2692 (define_insn_and_split "*anddi_notzesidi_di"
2693   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2694         (and:DI (not:DI (zero_extend:DI
2695                          (match_operand:SI 2 "s_register_operand" "r,r")))
2696                 (match_operand:DI 1 "s_register_operand" "0,?r")))]
2697   "TARGET_32BIT"
2698   "@
2699    bic%?\\t%Q0, %Q1, %2
2700    #"
2701   ; (not (zero_extend ...)) allows us to just copy the high word from
2702   ; operand1 to operand0.
2703   "TARGET_32BIT
2704    && reload_completed
2705    && operands[0] != operands[1]"
2706   [(set (match_dup 0) (and:SI (not:SI (match_dup 2)) (match_dup 1)))
2707    (set (match_dup 3) (match_dup 4))]
2708   "
2709   {
2710     operands[3] = gen_highpart (SImode, operands[0]);
2711     operands[0] = gen_lowpart (SImode, operands[0]);
2712     operands[4] = gen_highpart (SImode, operands[1]);
2713     operands[1] = gen_lowpart (SImode, operands[1]);
2714   }"
2715   [(set_attr "length" "4,8")
2716    (set_attr "predicable" "yes")
2717    (set_attr "predicable_short_it" "no")
2718    (set_attr "type" "multiple")]
2721 (define_insn_and_split "*anddi_notdi_zesidi"
2722   [(set (match_operand:DI 0 "s_register_operand" "=r")
2723         (and:DI (not:DI (match_operand:DI 2 "s_register_operand" "r"))
2724                 (zero_extend:DI
2725                  (match_operand:SI 1 "s_register_operand" "r"))))]
2726   "TARGET_32BIT"
2727   "#"
2728   "TARGET_32BIT && reload_completed"
2729   [(set (match_dup 0) (and:SI (not:SI (match_dup 2)) (match_dup 1)))
2730    (set (match_dup 3) (const_int 0))]
2731   "
2732   {
2733     operands[3] = gen_highpart (SImode, operands[0]);
2734     operands[0] = gen_lowpart (SImode, operands[0]);
2735     operands[2] = gen_lowpart (SImode, operands[2]);
2736   }"
2737   [(set_attr "length" "8")
2738    (set_attr "predicable" "yes")
2739    (set_attr "predicable_short_it" "no")
2740    (set_attr "type" "multiple")]
2743 (define_insn_and_split "*anddi_notsesidi_di"
2744   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2745         (and:DI (not:DI (sign_extend:DI
2746                          (match_operand:SI 2 "s_register_operand" "r,r")))
2747                 (match_operand:DI 1 "s_register_operand" "0,r")))]
2748   "TARGET_32BIT"
2749   "#"
2750   "TARGET_32BIT && reload_completed"
2751   [(set (match_dup 0) (and:SI (not:SI (match_dup 2)) (match_dup 1)))
2752    (set (match_dup 3) (and:SI (not:SI
2753                                 (ashiftrt:SI (match_dup 2) (const_int 31)))
2754                                (match_dup 4)))]
2755   "
2756   {
2757     operands[3] = gen_highpart (SImode, operands[0]);
2758     operands[0] = gen_lowpart (SImode, operands[0]);
2759     operands[4] = gen_highpart (SImode, operands[1]);
2760     operands[1] = gen_lowpart (SImode, operands[1]);
2761   }"
2762   [(set_attr "length" "8")
2763    (set_attr "predicable" "yes")
2764    (set_attr "predicable_short_it" "no")
2765    (set_attr "type" "multiple")]
2768 (define_insn "andsi_notsi_si"
2769   [(set (match_operand:SI 0 "s_register_operand" "=r")
2770         (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
2771                 (match_operand:SI 1 "s_register_operand" "r")))]
2772   "TARGET_32BIT"
2773   "bic%?\\t%0, %1, %2"
2774   [(set_attr "predicable" "yes")
2775    (set_attr "predicable_short_it" "no")
2776    (set_attr "type" "logic_reg")]
2779 (define_insn "andsi_not_shiftsi_si"
2780   [(set (match_operand:SI 0 "s_register_operand" "=r")
2781         (and:SI (not:SI (match_operator:SI 4 "shift_operator"
2782                          [(match_operand:SI 2 "s_register_operand" "r")
2783                           (match_operand:SI 3 "arm_rhs_operand" "rM")]))
2784                 (match_operand:SI 1 "s_register_operand" "r")))]
2785   "TARGET_ARM"
2786   "bic%?\\t%0, %1, %2%S4"
2787   [(set_attr "predicable" "yes")
2788    (set_attr "shift" "2")
2789    (set (attr "type") (if_then_else (match_operand 3 "const_int_operand" "")
2790                       (const_string "logic_shift_imm")
2791                       (const_string "logic_shift_reg")))]
2794 ;; Shifted bics pattern used to set up CC status register and not reusing
2795 ;; bics output.  Pattern restricts Thumb2 shift operand as bics for Thumb2
2796 ;; does not support shift by register.
2797 (define_insn "andsi_not_shiftsi_si_scc_no_reuse"
2798   [(set (reg:CC_NOOV CC_REGNUM)
2799         (compare:CC_NOOV
2800                 (and:SI (not:SI (match_operator:SI 0 "shift_operator"
2801                         [(match_operand:SI 1 "s_register_operand" "r")
2802                          (match_operand:SI 2 "arm_rhs_operand" "rM")]))
2803                         (match_operand:SI 3 "s_register_operand" "r"))
2804                 (const_int 0)))
2805    (clobber (match_scratch:SI 4 "=r"))]
2806   "TARGET_ARM || (TARGET_THUMB2 && CONST_INT_P (operands[2]))"
2807   "bics%?\\t%4, %3, %1%S0"
2808   [(set_attr "predicable" "yes")
2809    (set_attr "predicable_short_it" "no")
2810    (set_attr "conds" "set")
2811    (set_attr "shift" "1")
2812    (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
2813                       (const_string "logic_shift_imm")
2814                       (const_string "logic_shift_reg")))]
2817 ;; Same as andsi_not_shiftsi_si_scc_no_reuse, but the bics result is also
2818 ;; getting reused later.
2819 (define_insn "andsi_not_shiftsi_si_scc"
2820   [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2821         (compare:CC_NOOV
2822                 (and:SI (not:SI (match_operator:SI 0 "shift_operator"
2823                         [(match_operand:SI 1 "s_register_operand" "r")
2824                          (match_operand:SI 2 "arm_rhs_operand" "rM")]))
2825                         (match_operand:SI 3 "s_register_operand" "r"))
2826                 (const_int 0)))
2827         (set (match_operand:SI 4 "s_register_operand" "=r")
2828              (and:SI (not:SI (match_op_dup 0
2829                      [(match_dup 1)
2830                       (match_dup 2)]))
2831                      (match_dup 3)))])]
2832   "TARGET_ARM || (TARGET_THUMB2 && CONST_INT_P (operands[2]))"
2833   "bics%?\\t%4, %3, %1%S0"
2834   [(set_attr "predicable" "yes")
2835    (set_attr "predicable_short_it" "no")
2836    (set_attr "conds" "set")
2837    (set_attr "shift" "1")
2838    (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
2839                       (const_string "logic_shift_imm")
2840                       (const_string "logic_shift_reg")))]
2843 (define_insn "*andsi_notsi_si_compare0"
2844   [(set (reg:CC_NOOV CC_REGNUM)
2845         (compare:CC_NOOV
2846          (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
2847                  (match_operand:SI 1 "s_register_operand" "r"))
2848          (const_int 0)))
2849    (set (match_operand:SI 0 "s_register_operand" "=r")
2850         (and:SI (not:SI (match_dup 2)) (match_dup 1)))]
2851   "TARGET_32BIT"
2852   "bics\\t%0, %1, %2"
2853   [(set_attr "conds" "set")
2854    (set_attr "type" "logics_shift_reg")]
2857 (define_insn "*andsi_notsi_si_compare0_scratch"
2858   [(set (reg:CC_NOOV CC_REGNUM)
2859         (compare:CC_NOOV
2860          (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
2861                  (match_operand:SI 1 "s_register_operand" "r"))
2862          (const_int 0)))
2863    (clobber (match_scratch:SI 0 "=r"))]
2864   "TARGET_32BIT"
2865   "bics\\t%0, %1, %2"
2866   [(set_attr "conds" "set")
2867    (set_attr "type" "logics_shift_reg")]
2870 (define_expand "iordi3"
2871   [(set (match_operand:DI         0 "s_register_operand" "")
2872         (ior:DI (match_operand:DI 1 "s_register_operand" "")
2873                 (match_operand:DI 2 "neon_logic_op2" "")))]
2874   "TARGET_32BIT"
2875   ""
2878 (define_insn_and_split "*iordi3_insn"
2879   [(set (match_operand:DI         0 "s_register_operand"     "=w,w ,&r,&r,&r,&r,?w,?w")
2880         (ior:DI (match_operand:DI 1 "s_register_operand"     "%w,0 ,0 ,r ,0 ,r ,w ,0")
2881                 (match_operand:DI 2 "arm_iordi_operand_neon" "w ,Dl,r ,r ,Df,Df,w ,Dl")))]
2882   "TARGET_32BIT && !TARGET_IWMMXT"
2883   {
2884   switch (which_alternative)
2885     {
2886     case 0: /* fall through */
2887     case 6: return "vorr\t%P0, %P1, %P2";
2888     case 1: /* fall through */
2889     case 7: return neon_output_logic_immediate ("vorr", &operands[2],
2890                      DImode, 0, VALID_NEON_QREG_MODE (DImode));
2891     case 2:
2892     case 3:
2893     case 4:
2894     case 5:
2895       return "#";
2896     default: gcc_unreachable ();
2897     }
2898   }
2899   "TARGET_32BIT && !TARGET_IWMMXT && reload_completed
2900    && !(IS_VFP_REGNUM (REGNO (operands[0])))"
2901   [(set (match_dup 3) (match_dup 4))
2902    (set (match_dup 5) (match_dup 6))]
2903   "
2904   {
2905     operands[3] = gen_lowpart (SImode, operands[0]);
2906     operands[5] = gen_highpart (SImode, operands[0]);
2908     operands[4] = simplify_gen_binary (IOR, SImode,
2909                                            gen_lowpart (SImode, operands[1]),
2910                                            gen_lowpart (SImode, operands[2]));
2911     operands[6] = simplify_gen_binary (IOR, SImode,
2912                                            gen_highpart (SImode, operands[1]),
2913                                            gen_highpart_mode (SImode, DImode, operands[2]));
2915   }"
2916   [(set_attr "type" "neon_logic,neon_logic,multiple,multiple,multiple,\
2917                      multiple,neon_logic,neon_logic")
2918    (set_attr "length" "*,*,8,8,8,8,*,*")
2919    (set_attr "arch" "neon_for_64bits,neon_for_64bits,*,*,*,*,avoid_neon_for_64bits,avoid_neon_for_64bits")]
2922 (define_insn "*iordi_zesidi_di"
2923   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2924         (ior:DI (zero_extend:DI
2925                  (match_operand:SI 2 "s_register_operand" "r,r"))
2926                 (match_operand:DI 1 "s_register_operand" "0,?r")))]
2927   "TARGET_32BIT"
2928   "@
2929    orr%?\\t%Q0, %Q1, %2
2930    #"
2931   [(set_attr "length" "4,8")
2932    (set_attr "predicable" "yes")
2933    (set_attr "predicable_short_it" "no")
2934    (set_attr "type" "logic_reg,multiple")]
2937 (define_insn "*iordi_sesidi_di"
2938   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2939         (ior:DI (sign_extend:DI
2940                  (match_operand:SI 2 "s_register_operand" "r,r"))
2941                 (match_operand:DI 1 "s_register_operand" "0,r")))]
2942   "TARGET_32BIT"
2943   "#"
2944   [(set_attr "length" "8")
2945    (set_attr "predicable" "yes")
2946    (set_attr "type" "multiple")]
2949 (define_expand "iorsi3"
2950   [(set (match_operand:SI         0 "s_register_operand" "")
2951         (ior:SI (match_operand:SI 1 "s_register_operand" "")
2952                 (match_operand:SI 2 "reg_or_int_operand" "")))]
2953   "TARGET_EITHER"
2954   "
2955   if (CONST_INT_P (operands[2]))
2956     {
2957       if (TARGET_32BIT)
2958         {
2959           if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[2]), IOR))
2960             operands[2] = force_reg (SImode, operands[2]);
2961           else
2962             {
2963               arm_split_constant (IOR, SImode, NULL_RTX,
2964                                   INTVAL (operands[2]), operands[0],
2965                                   operands[1],
2966                                   optimize && can_create_pseudo_p ());
2967               DONE;
2968             }
2969         }
2970       else /* TARGET_THUMB1 */
2971         {
2972           rtx tmp = force_reg (SImode, operands[2]);
2973           if (rtx_equal_p (operands[0], operands[1]))
2974             operands[2] = tmp;
2975           else
2976             {
2977               operands[2] = operands[1];
2978               operands[1] = tmp;
2979             }
2980         }
2981     }
2982   "
2985 (define_insn_and_split "*iorsi3_insn"
2986   [(set (match_operand:SI 0 "s_register_operand" "=r,l,r,r,r")
2987         (ior:SI (match_operand:SI 1 "s_register_operand" "%r,0,r,r,r")
2988                 (match_operand:SI 2 "reg_or_int_operand" "I,l,K,r,?n")))]
2989   "TARGET_32BIT"
2990   "@
2991    orr%?\\t%0, %1, %2
2992    orr%?\\t%0, %1, %2
2993    orn%?\\t%0, %1, #%B2
2994    orr%?\\t%0, %1, %2
2995    #"
2996   "TARGET_32BIT
2997    && CONST_INT_P (operands[2])
2998    && !(const_ok_for_arm (INTVAL (operands[2]))
2999         || (TARGET_THUMB2 && const_ok_for_arm (~INTVAL (operands[2]))))"
3000   [(clobber (const_int 0))]
3002   arm_split_constant (IOR, SImode, curr_insn,
3003                       INTVAL (operands[2]), operands[0], operands[1], 0);
3004   DONE;
3006   [(set_attr "length" "4,4,4,4,16")
3007    (set_attr "arch" "32,t2,t2,32,32")
3008    (set_attr "predicable" "yes")
3009    (set_attr "predicable_short_it" "no,yes,no,no,no")
3010    (set_attr "type" "logic_imm,logic_reg,logic_imm,logic_reg,logic_reg")]
3013 (define_peephole2
3014   [(match_scratch:SI 3 "r")
3015    (set (match_operand:SI 0 "arm_general_register_operand" "")
3016         (ior:SI (match_operand:SI 1 "arm_general_register_operand" "")
3017                 (match_operand:SI 2 "const_int_operand" "")))]
3018   "TARGET_ARM
3019    && !const_ok_for_arm (INTVAL (operands[2]))
3020    && const_ok_for_arm (~INTVAL (operands[2]))"
3021   [(set (match_dup 3) (match_dup 2))
3022    (set (match_dup 0) (ior:SI (match_dup 1) (match_dup 3)))]
3023   ""
3026 (define_insn "*iorsi3_compare0"
3027   [(set (reg:CC_NOOV CC_REGNUM)
3028         (compare:CC_NOOV (ior:SI (match_operand:SI 1 "s_register_operand" "%r,r")
3029                                  (match_operand:SI 2 "arm_rhs_operand" "I,r"))
3030                          (const_int 0)))
3031    (set (match_operand:SI 0 "s_register_operand" "=r,r")
3032         (ior:SI (match_dup 1) (match_dup 2)))]
3033   "TARGET_32BIT"
3034   "orrs%?\\t%0, %1, %2"
3035   [(set_attr "conds" "set")
3036    (set_attr "type" "logics_imm,logics_reg")]
3039 (define_insn "*iorsi3_compare0_scratch"
3040   [(set (reg:CC_NOOV CC_REGNUM)
3041         (compare:CC_NOOV (ior:SI (match_operand:SI 1 "s_register_operand" "%r,r")
3042                                  (match_operand:SI 2 "arm_rhs_operand" "I,r"))
3043                          (const_int 0)))
3044    (clobber (match_scratch:SI 0 "=r,r"))]
3045   "TARGET_32BIT"
3046   "orrs%?\\t%0, %1, %2"
3047   [(set_attr "conds" "set")
3048    (set_attr "type" "logics_imm,logics_reg")]
3051 (define_expand "xordi3"
3052   [(set (match_operand:DI         0 "s_register_operand" "")
3053         (xor:DI (match_operand:DI 1 "s_register_operand" "")
3054                 (match_operand:DI 2 "arm_xordi_operand" "")))]
3055   "TARGET_32BIT"
3056   ""
3059 (define_insn_and_split "*xordi3_insn"
3060   [(set (match_operand:DI         0 "s_register_operand" "=w,&r,&r,&r,&r,?w")
3061         (xor:DI (match_operand:DI 1 "s_register_operand" "%w ,0,r ,0 ,r ,w")
3062                 (match_operand:DI 2 "arm_xordi_operand"  "w ,r ,r ,Dg,Dg,w")))]
3063   "TARGET_32BIT && !TARGET_IWMMXT"
3065   switch (which_alternative)
3066     {
3067     case 1:
3068     case 2:
3069     case 3:
3070     case 4:  /* fall through */
3071       return "#";
3072     case 0: /* fall through */
3073     case 5: return "veor\t%P0, %P1, %P2";
3074     default: gcc_unreachable ();
3075     }
3077   "TARGET_32BIT && !TARGET_IWMMXT && reload_completed
3078    && !(IS_VFP_REGNUM (REGNO (operands[0])))"
3079   [(set (match_dup 3) (match_dup 4))
3080    (set (match_dup 5) (match_dup 6))]
3081   "
3082   {
3083     operands[3] = gen_lowpart (SImode, operands[0]);
3084     operands[5] = gen_highpart (SImode, operands[0]);
3086     operands[4] = simplify_gen_binary (XOR, SImode,
3087                                            gen_lowpart (SImode, operands[1]),
3088                                            gen_lowpart (SImode, operands[2]));
3089     operands[6] = simplify_gen_binary (XOR, SImode,
3090                                            gen_highpart (SImode, operands[1]),
3091                                            gen_highpart_mode (SImode, DImode, operands[2]));
3093   }"
3094   [(set_attr "length" "*,8,8,8,8,*")
3095    (set_attr "type" "neon_logic,multiple,multiple,multiple,multiple,neon_logic")
3096    (set_attr "arch" "neon_for_64bits,*,*,*,*,avoid_neon_for_64bits")]
3099 (define_insn "*xordi_zesidi_di"
3100   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
3101         (xor:DI (zero_extend:DI
3102                  (match_operand:SI 2 "s_register_operand" "r,r"))
3103                 (match_operand:DI 1 "s_register_operand" "0,?r")))]
3104   "TARGET_32BIT"
3105   "@
3106    eor%?\\t%Q0, %Q1, %2
3107    #"
3108   [(set_attr "length" "4,8")
3109    (set_attr "predicable" "yes")
3110    (set_attr "predicable_short_it" "no")
3111    (set_attr "type" "logic_reg")]
3114 (define_insn "*xordi_sesidi_di"
3115   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
3116         (xor:DI (sign_extend:DI
3117                  (match_operand:SI 2 "s_register_operand" "r,r"))
3118                 (match_operand:DI 1 "s_register_operand" "0,r")))]
3119   "TARGET_32BIT"
3120   "#"
3121   [(set_attr "length" "8")
3122    (set_attr "predicable" "yes")
3123    (set_attr "type" "multiple")]
3126 (define_expand "xorsi3"
3127   [(set (match_operand:SI         0 "s_register_operand" "")
3128         (xor:SI (match_operand:SI 1 "s_register_operand" "")
3129                 (match_operand:SI 2 "reg_or_int_operand" "")))]
3130   "TARGET_EITHER"
3131   "if (CONST_INT_P (operands[2]))
3132     {
3133       if (TARGET_32BIT)
3134         {
3135           if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[2]), XOR))
3136             operands[2] = force_reg (SImode, operands[2]);
3137           else
3138             {
3139               arm_split_constant (XOR, SImode, NULL_RTX,
3140                                   INTVAL (operands[2]), operands[0],
3141                                   operands[1],
3142                                   optimize && can_create_pseudo_p ());
3143               DONE;
3144             }
3145         }
3146       else /* TARGET_THUMB1 */
3147         {
3148           rtx tmp = force_reg (SImode, operands[2]);
3149           if (rtx_equal_p (operands[0], operands[1]))
3150             operands[2] = tmp;
3151           else
3152             {
3153               operands[2] = operands[1];
3154               operands[1] = tmp;
3155             }
3156         }
3157     }"
3160 (define_insn_and_split "*arm_xorsi3"
3161   [(set (match_operand:SI         0 "s_register_operand" "=r,l,r,r")
3162         (xor:SI (match_operand:SI 1 "s_register_operand" "%r,0,r,r")
3163                 (match_operand:SI 2 "reg_or_int_operand" "I,l,r,?n")))]
3164   "TARGET_32BIT"
3165   "@
3166    eor%?\\t%0, %1, %2
3167    eor%?\\t%0, %1, %2
3168    eor%?\\t%0, %1, %2
3169    #"
3170   "TARGET_32BIT
3171    && CONST_INT_P (operands[2])
3172    && !const_ok_for_arm (INTVAL (operands[2]))"
3173   [(clobber (const_int 0))]
3175   arm_split_constant (XOR, SImode, curr_insn,
3176                       INTVAL (operands[2]), operands[0], operands[1], 0);
3177   DONE;
3179   [(set_attr "length" "4,4,4,16")
3180    (set_attr "predicable" "yes")
3181    (set_attr "predicable_short_it" "no,yes,no,no")
3182    (set_attr "type"  "logic_imm,logic_reg,logic_reg,multiple")]
3185 (define_insn "*xorsi3_compare0"
3186   [(set (reg:CC_NOOV CC_REGNUM)
3187         (compare:CC_NOOV (xor:SI (match_operand:SI 1 "s_register_operand" "r,r")
3188                                  (match_operand:SI 2 "arm_rhs_operand" "I,r"))
3189                          (const_int 0)))
3190    (set (match_operand:SI 0 "s_register_operand" "=r,r")
3191         (xor:SI (match_dup 1) (match_dup 2)))]
3192   "TARGET_32BIT"
3193   "eors%?\\t%0, %1, %2"
3194   [(set_attr "conds" "set")
3195    (set_attr "type" "logics_imm,logics_reg")]
3198 (define_insn "*xorsi3_compare0_scratch"
3199   [(set (reg:CC_NOOV CC_REGNUM)
3200         (compare:CC_NOOV (xor:SI (match_operand:SI 0 "s_register_operand" "r,r")
3201                                  (match_operand:SI 1 "arm_rhs_operand" "I,r"))
3202                          (const_int 0)))]
3203   "TARGET_32BIT"
3204   "teq%?\\t%0, %1"
3205   [(set_attr "conds" "set")
3206    (set_attr "type" "logics_imm,logics_reg")]
3209 ; By splitting (IOR (AND (NOT A) (NOT B)) C) as D = AND (IOR A B) (NOT C), 
3210 ; (NOT D) we can sometimes merge the final NOT into one of the following
3211 ; insns.
3213 (define_split
3214   [(set (match_operand:SI 0 "s_register_operand" "")
3215         (ior:SI (and:SI (not:SI (match_operand:SI 1 "s_register_operand" ""))
3216                         (not:SI (match_operand:SI 2 "arm_rhs_operand" "")))
3217                 (match_operand:SI 3 "arm_rhs_operand" "")))
3218    (clobber (match_operand:SI 4 "s_register_operand" ""))]
3219   "TARGET_32BIT"
3220   [(set (match_dup 4) (and:SI (ior:SI (match_dup 1) (match_dup 2))
3221                               (not:SI (match_dup 3))))
3222    (set (match_dup 0) (not:SI (match_dup 4)))]
3223   ""
3226 (define_insn_and_split "*andsi_iorsi3_notsi"
3227   [(set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r")
3228         (and:SI (ior:SI (match_operand:SI 1 "s_register_operand" "%0,r,r")
3229                         (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI"))
3230                 (not:SI (match_operand:SI 3 "arm_rhs_operand" "rI,rI,rI"))))]
3231   "TARGET_32BIT"
3232   "#"   ; "orr%?\\t%0, %1, %2\;bic%?\\t%0, %0, %3"
3233   "&& reload_completed"
3234   [(set (match_dup 0) (ior:SI (match_dup 1) (match_dup 2)))
3235    (set (match_dup 0) (and:SI (match_dup 4) (match_dup 5)))]
3236   {
3237      /* If operands[3] is a constant make sure to fold the NOT into it
3238         to avoid creating a NOT of a CONST_INT.  */
3239     rtx not_rtx = simplify_gen_unary (NOT, SImode, operands[3], SImode);
3240     if (CONST_INT_P (not_rtx))
3241       {
3242         operands[4] = operands[0];
3243         operands[5] = not_rtx;
3244       }
3245     else
3246       {
3247         operands[5] = operands[0];
3248         operands[4] = not_rtx;
3249       }
3250   }
3251   [(set_attr "length" "8")
3252    (set_attr "ce_count" "2")
3253    (set_attr "predicable" "yes")
3254    (set_attr "predicable_short_it" "no")
3255    (set_attr "type" "multiple")]
3258 ; ??? Are these four splitters still beneficial when the Thumb-2 bitfield
3259 ; insns are available?
3260 (define_split
3261   [(set (match_operand:SI 0 "s_register_operand" "")
3262         (match_operator:SI 1 "logical_binary_operator"
3263          [(zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
3264                            (match_operand:SI 3 "const_int_operand" "")
3265                            (match_operand:SI 4 "const_int_operand" ""))
3266           (match_operator:SI 9 "logical_binary_operator"
3267            [(lshiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3268                          (match_operand:SI 6 "const_int_operand" ""))
3269             (match_operand:SI 7 "s_register_operand" "")])]))
3270    (clobber (match_operand:SI 8 "s_register_operand" ""))]
3271   "TARGET_32BIT
3272    && GET_CODE (operands[1]) == GET_CODE (operands[9])
3273    && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3274   [(set (match_dup 8)
3275         (match_op_dup 1
3276          [(ashift:SI (match_dup 2) (match_dup 4))
3277           (match_dup 5)]))
3278    (set (match_dup 0)
3279         (match_op_dup 1
3280          [(lshiftrt:SI (match_dup 8) (match_dup 6))
3281           (match_dup 7)]))]
3282   "
3283   operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3286 (define_split
3287   [(set (match_operand:SI 0 "s_register_operand" "")
3288         (match_operator:SI 1 "logical_binary_operator"
3289          [(match_operator:SI 9 "logical_binary_operator"
3290            [(lshiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3291                          (match_operand:SI 6 "const_int_operand" ""))
3292             (match_operand:SI 7 "s_register_operand" "")])
3293           (zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
3294                            (match_operand:SI 3 "const_int_operand" "")
3295                            (match_operand:SI 4 "const_int_operand" ""))]))
3296    (clobber (match_operand:SI 8 "s_register_operand" ""))]
3297   "TARGET_32BIT
3298    && GET_CODE (operands[1]) == GET_CODE (operands[9])
3299    && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3300   [(set (match_dup 8)
3301         (match_op_dup 1
3302          [(ashift:SI (match_dup 2) (match_dup 4))
3303           (match_dup 5)]))
3304    (set (match_dup 0)
3305         (match_op_dup 1
3306          [(lshiftrt:SI (match_dup 8) (match_dup 6))
3307           (match_dup 7)]))]
3308   "
3309   operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3312 (define_split
3313   [(set (match_operand:SI 0 "s_register_operand" "")
3314         (match_operator:SI 1 "logical_binary_operator"
3315          [(sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
3316                            (match_operand:SI 3 "const_int_operand" "")
3317                            (match_operand:SI 4 "const_int_operand" ""))
3318           (match_operator:SI 9 "logical_binary_operator"
3319            [(ashiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3320                          (match_operand:SI 6 "const_int_operand" ""))
3321             (match_operand:SI 7 "s_register_operand" "")])]))
3322    (clobber (match_operand:SI 8 "s_register_operand" ""))]
3323   "TARGET_32BIT
3324    && GET_CODE (operands[1]) == GET_CODE (operands[9])
3325    && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3326   [(set (match_dup 8)
3327         (match_op_dup 1
3328          [(ashift:SI (match_dup 2) (match_dup 4))
3329           (match_dup 5)]))
3330    (set (match_dup 0)
3331         (match_op_dup 1
3332          [(ashiftrt:SI (match_dup 8) (match_dup 6))
3333           (match_dup 7)]))]
3334   "
3335   operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3338 (define_split
3339   [(set (match_operand:SI 0 "s_register_operand" "")
3340         (match_operator:SI 1 "logical_binary_operator"
3341          [(match_operator:SI 9 "logical_binary_operator"
3342            [(ashiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3343                          (match_operand:SI 6 "const_int_operand" ""))
3344             (match_operand:SI 7 "s_register_operand" "")])
3345           (sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
3346                            (match_operand:SI 3 "const_int_operand" "")
3347                            (match_operand:SI 4 "const_int_operand" ""))]))
3348    (clobber (match_operand:SI 8 "s_register_operand" ""))]
3349   "TARGET_32BIT
3350    && GET_CODE (operands[1]) == GET_CODE (operands[9])
3351    && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3352   [(set (match_dup 8)
3353         (match_op_dup 1
3354          [(ashift:SI (match_dup 2) (match_dup 4))
3355           (match_dup 5)]))
3356    (set (match_dup 0)
3357         (match_op_dup 1
3358          [(ashiftrt:SI (match_dup 8) (match_dup 6))
3359           (match_dup 7)]))]
3360   "
3361   operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3365 ;; Minimum and maximum insns
3367 (define_expand "smaxsi3"
3368   [(parallel [
3369     (set (match_operand:SI 0 "s_register_operand" "")
3370          (smax:SI (match_operand:SI 1 "s_register_operand" "")
3371                   (match_operand:SI 2 "arm_rhs_operand" "")))
3372     (clobber (reg:CC CC_REGNUM))])]
3373   "TARGET_32BIT"
3374   "
3375   if (operands[2] == const0_rtx || operands[2] == constm1_rtx)
3376     {
3377       /* No need for a clobber of the condition code register here.  */
3378       emit_insn (gen_rtx_SET (operands[0],
3379                               gen_rtx_SMAX (SImode, operands[1],
3380                                             operands[2])));
3381       DONE;
3382     }
3385 (define_insn "*smax_0"
3386   [(set (match_operand:SI 0 "s_register_operand" "=r")
3387         (smax:SI (match_operand:SI 1 "s_register_operand" "r")
3388                  (const_int 0)))]
3389   "TARGET_32BIT"
3390   "bic%?\\t%0, %1, %1, asr #31"
3391   [(set_attr "predicable" "yes")
3392    (set_attr "predicable_short_it" "no")
3393    (set_attr "type" "logic_shift_reg")]
3396 (define_insn "*smax_m1"
3397   [(set (match_operand:SI 0 "s_register_operand" "=r")
3398         (smax:SI (match_operand:SI 1 "s_register_operand" "r")
3399                  (const_int -1)))]
3400   "TARGET_32BIT"
3401   "orr%?\\t%0, %1, %1, asr #31"
3402   [(set_attr "predicable" "yes")
3403    (set_attr "predicable_short_it" "no")
3404    (set_attr "type" "logic_shift_reg")]
3407 (define_insn_and_split "*arm_smax_insn"
3408   [(set (match_operand:SI          0 "s_register_operand" "=r,r")
3409         (smax:SI (match_operand:SI 1 "s_register_operand"  "%0,?r")
3410                  (match_operand:SI 2 "arm_rhs_operand"    "rI,rI")))
3411    (clobber (reg:CC CC_REGNUM))]
3412   "TARGET_ARM"
3413   "#"
3414    ; cmp\\t%1, %2\;movlt\\t%0, %2
3415    ; cmp\\t%1, %2\;movge\\t%0, %1\;movlt\\t%0, %2"
3416   "TARGET_ARM"
3417   [(set (reg:CC CC_REGNUM)
3418         (compare:CC (match_dup 1) (match_dup 2)))
3419    (set (match_dup 0)
3420         (if_then_else:SI (ge:SI (reg:CC CC_REGNUM) (const_int 0))
3421                          (match_dup 1)
3422                          (match_dup 2)))]
3423   ""
3424   [(set_attr "conds" "clob")
3425    (set_attr "length" "8,12")
3426    (set_attr "type" "multiple")]
3429 (define_expand "sminsi3"
3430   [(parallel [
3431     (set (match_operand:SI 0 "s_register_operand" "")
3432          (smin:SI (match_operand:SI 1 "s_register_operand" "")
3433                   (match_operand:SI 2 "arm_rhs_operand" "")))
3434     (clobber (reg:CC CC_REGNUM))])]
3435   "TARGET_32BIT"
3436   "
3437   if (operands[2] == const0_rtx)
3438     {
3439       /* No need for a clobber of the condition code register here.  */
3440       emit_insn (gen_rtx_SET (operands[0],
3441                               gen_rtx_SMIN (SImode, operands[1],
3442                                             operands[2])));
3443       DONE;
3444     }
3447 (define_insn "*smin_0"
3448   [(set (match_operand:SI 0 "s_register_operand" "=r")
3449         (smin:SI (match_operand:SI 1 "s_register_operand" "r")
3450                  (const_int 0)))]
3451   "TARGET_32BIT"
3452   "and%?\\t%0, %1, %1, asr #31"
3453   [(set_attr "predicable" "yes")
3454    (set_attr "predicable_short_it" "no")
3455    (set_attr "type" "logic_shift_reg")]
3458 (define_insn_and_split "*arm_smin_insn"
3459   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3460         (smin:SI (match_operand:SI 1 "s_register_operand" "%0,?r")
3461                  (match_operand:SI 2 "arm_rhs_operand" "rI,rI")))
3462    (clobber (reg:CC CC_REGNUM))]
3463   "TARGET_ARM"
3464   "#"
3465     ; cmp\\t%1, %2\;movge\\t%0, %2
3466     ; cmp\\t%1, %2\;movlt\\t%0, %1\;movge\\t%0, %2"
3467   "TARGET_ARM"
3468   [(set (reg:CC CC_REGNUM)
3469         (compare:CC (match_dup 1) (match_dup 2)))
3470    (set (match_dup 0)
3471         (if_then_else:SI (lt:SI (reg:CC CC_REGNUM) (const_int 0))
3472                          (match_dup 1)
3473                          (match_dup 2)))]
3474   ""
3475   [(set_attr "conds" "clob")
3476    (set_attr "length" "8,12")
3477    (set_attr "type" "multiple,multiple")]
3480 (define_expand "umaxsi3"
3481   [(parallel [
3482     (set (match_operand:SI 0 "s_register_operand" "")
3483          (umax:SI (match_operand:SI 1 "s_register_operand" "")
3484                   (match_operand:SI 2 "arm_rhs_operand" "")))
3485     (clobber (reg:CC CC_REGNUM))])]
3486   "TARGET_32BIT"
3487   ""
3490 (define_insn_and_split "*arm_umaxsi3"
3491   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
3492         (umax:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
3493                  (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
3494    (clobber (reg:CC CC_REGNUM))]
3495   "TARGET_ARM"
3496   "#"
3497     ; cmp\\t%1, %2\;movcc\\t%0, %2
3498     ; cmp\\t%1, %2\;movcs\\t%0, %1
3499     ; cmp\\t%1, %2\;movcs\\t%0, %1\;movcc\\t%0, %2"
3500   "TARGET_ARM"
3501   [(set (reg:CC CC_REGNUM)
3502         (compare:CC (match_dup 1) (match_dup 2)))
3503    (set (match_dup 0)
3504         (if_then_else:SI (geu:SI (reg:CC CC_REGNUM) (const_int 0))
3505                          (match_dup 1)
3506                          (match_dup 2)))]
3507   ""
3508   [(set_attr "conds" "clob")
3509    (set_attr "length" "8,8,12")
3510    (set_attr "type" "store1")]
3513 (define_expand "uminsi3"
3514   [(parallel [
3515     (set (match_operand:SI 0 "s_register_operand" "")
3516          (umin:SI (match_operand:SI 1 "s_register_operand" "")
3517                   (match_operand:SI 2 "arm_rhs_operand" "")))
3518     (clobber (reg:CC CC_REGNUM))])]
3519   "TARGET_32BIT"
3520   ""
3523 (define_insn_and_split "*arm_uminsi3"
3524   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
3525         (umin:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
3526                  (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
3527    (clobber (reg:CC CC_REGNUM))]
3528   "TARGET_ARM"
3529   "#"
3530    ; cmp\\t%1, %2\;movcs\\t%0, %2
3531    ; cmp\\t%1, %2\;movcc\\t%0, %1
3532    ; cmp\\t%1, %2\;movcc\\t%0, %1\;movcs\\t%0, %2"
3533   "TARGET_ARM"
3534   [(set (reg:CC CC_REGNUM)
3535         (compare:CC (match_dup 1) (match_dup 2)))
3536    (set (match_dup 0)
3537         (if_then_else:SI (ltu:SI (reg:CC CC_REGNUM) (const_int 0))
3538                          (match_dup 1)
3539                          (match_dup 2)))]
3540   ""
3541   [(set_attr "conds" "clob")
3542    (set_attr "length" "8,8,12")
3543    (set_attr "type" "store1")]
3546 (define_insn "*store_minmaxsi"
3547   [(set (match_operand:SI 0 "memory_operand" "=m")
3548         (match_operator:SI 3 "minmax_operator"
3549          [(match_operand:SI 1 "s_register_operand" "r")
3550           (match_operand:SI 2 "s_register_operand" "r")]))
3551    (clobber (reg:CC CC_REGNUM))]
3552   "TARGET_32BIT && optimize_function_for_size_p (cfun) && !arm_restrict_it"
3553   "*
3554   operands[3] = gen_rtx_fmt_ee (minmax_code (operands[3]), SImode,
3555                                 operands[1], operands[2]);
3556   output_asm_insn (\"cmp\\t%1, %2\", operands);
3557   if (TARGET_THUMB2)
3558     output_asm_insn (\"ite\t%d3\", operands);
3559   output_asm_insn (\"str%d3\\t%1, %0\", operands);
3560   output_asm_insn (\"str%D3\\t%2, %0\", operands);
3561   return \"\";
3562   "
3563   [(set_attr "conds" "clob")
3564    (set (attr "length")
3565         (if_then_else (eq_attr "is_thumb" "yes")
3566                       (const_int 14)
3567                       (const_int 12)))
3568    (set_attr "type" "store1")]
3571 ; Reject the frame pointer in operand[1], since reloading this after
3572 ; it has been eliminated can cause carnage.
3573 (define_insn "*minmax_arithsi"
3574   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3575         (match_operator:SI 4 "shiftable_operator"
3576          [(match_operator:SI 5 "minmax_operator"
3577            [(match_operand:SI 2 "s_register_operand" "r,r")
3578             (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
3579           (match_operand:SI 1 "s_register_operand" "0,?r")]))
3580    (clobber (reg:CC CC_REGNUM))]
3581   "TARGET_32BIT && !arm_eliminable_register (operands[1]) && !arm_restrict_it"
3582   "*
3583   {
3584     enum rtx_code code = GET_CODE (operands[4]);
3585     bool need_else;
3587     if (which_alternative != 0 || operands[3] != const0_rtx
3588         || (code != PLUS && code != IOR && code != XOR))
3589       need_else = true;
3590     else
3591       need_else = false;
3593     operands[5] = gen_rtx_fmt_ee (minmax_code (operands[5]), SImode,
3594                                   operands[2], operands[3]);
3595     output_asm_insn (\"cmp\\t%2, %3\", operands);
3596     if (TARGET_THUMB2)
3597       {
3598         if (need_else)
3599           output_asm_insn (\"ite\\t%d5\", operands);
3600         else
3601           output_asm_insn (\"it\\t%d5\", operands);
3602       }
3603     output_asm_insn (\"%i4%d5\\t%0, %1, %2\", operands);
3604     if (need_else)
3605       output_asm_insn (\"%i4%D5\\t%0, %1, %3\", operands);
3606     return \"\";
3607   }"
3608   [(set_attr "conds" "clob")
3609    (set (attr "length")
3610         (if_then_else (eq_attr "is_thumb" "yes")
3611                       (const_int 14)
3612                       (const_int 12)))
3613    (set_attr "type" "multiple")]
3616 ; Reject the frame pointer in operand[1], since reloading this after
3617 ; it has been eliminated can cause carnage.
3618 (define_insn_and_split "*minmax_arithsi_non_canon"
3619   [(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts")
3620         (minus:SI
3621          (match_operand:SI 1 "s_register_operand" "0,?Ts")
3622           (match_operator:SI 4 "minmax_operator"
3623            [(match_operand:SI 2 "s_register_operand" "Ts,Ts")
3624             (match_operand:SI 3 "arm_rhs_operand" "TsI,TsI")])))
3625    (clobber (reg:CC CC_REGNUM))]
3626   "TARGET_32BIT && !arm_eliminable_register (operands[1])
3627    && !(arm_restrict_it && CONST_INT_P (operands[3]))"
3628   "#"
3629   "TARGET_32BIT && !arm_eliminable_register (operands[1]) && reload_completed"
3630   [(set (reg:CC CC_REGNUM)
3631         (compare:CC (match_dup 2) (match_dup 3)))
3633    (cond_exec (match_op_dup 4 [(reg:CC CC_REGNUM) (const_int 0)])
3634               (set (match_dup 0)
3635                    (minus:SI (match_dup 1)
3636                              (match_dup 2))))
3637    (cond_exec (match_op_dup 5 [(reg:CC CC_REGNUM) (const_int 0)])
3638               (set (match_dup 0)
3639                    (match_dup 6)))]
3640   {
3641   machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
3642                                            operands[2], operands[3]);
3643   enum rtx_code rc = minmax_code (operands[4]);
3644   operands[4] = gen_rtx_fmt_ee (rc, VOIDmode,
3645                                 operands[2], operands[3]);
3647   if (mode == CCFPmode || mode == CCFPEmode)
3648     rc = reverse_condition_maybe_unordered (rc);
3649   else
3650     rc = reverse_condition (rc);
3651   operands[5] = gen_rtx_fmt_ee (rc, SImode, operands[2], operands[3]);
3652   if (CONST_INT_P (operands[3]))
3653     operands[6] = plus_constant (SImode, operands[1], -INTVAL (operands[3]));
3654   else
3655     operands[6] = gen_rtx_MINUS (SImode, operands[1], operands[3]);
3656   }
3657   [(set_attr "conds" "clob")
3658    (set (attr "length")
3659         (if_then_else (eq_attr "is_thumb" "yes")
3660                       (const_int 14)
3661                       (const_int 12)))
3662    (set_attr "type" "multiple")]
3665 (define_code_iterator SAT [smin smax])
3666 (define_code_iterator SATrev [smin smax])
3667 (define_code_attr SATlo [(smin "1") (smax "2")])
3668 (define_code_attr SAThi [(smin "2") (smax "1")])
3670 (define_insn "*satsi_<SAT:code>"
3671   [(set (match_operand:SI 0 "s_register_operand" "=r")
3672         (SAT:SI (SATrev:SI (match_operand:SI 3 "s_register_operand" "r")
3673                            (match_operand:SI 1 "const_int_operand" "i"))
3674                 (match_operand:SI 2 "const_int_operand" "i")))]
3675   "TARGET_32BIT && arm_arch6 && <SAT:CODE> != <SATrev:CODE>
3676    && arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>], NULL, NULL)"
3678   int mask;
3679   bool signed_sat;
3680   if (!arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>],
3681                                &mask, &signed_sat))
3682     gcc_unreachable ();
3684   operands[1] = GEN_INT (mask);
3685   if (signed_sat)
3686     return "ssat%?\t%0, %1, %3";
3687   else
3688     return "usat%?\t%0, %1, %3";
3690   [(set_attr "predicable" "yes")
3691    (set_attr "predicable_short_it" "no")
3692    (set_attr "type" "alus_imm")]
3695 (define_insn "*satsi_<SAT:code>_shift"
3696   [(set (match_operand:SI 0 "s_register_operand" "=r")
3697         (SAT:SI (SATrev:SI (match_operator:SI 3 "sat_shift_operator"
3698                              [(match_operand:SI 4 "s_register_operand" "r")
3699                               (match_operand:SI 5 "const_int_operand" "i")])
3700                            (match_operand:SI 1 "const_int_operand" "i"))
3701                 (match_operand:SI 2 "const_int_operand" "i")))]
3702   "TARGET_32BIT && arm_arch6 && <SAT:CODE> != <SATrev:CODE>
3703    && arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>], NULL, NULL)"
3705   int mask;
3706   bool signed_sat;
3707   if (!arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>],
3708                                &mask, &signed_sat))
3709     gcc_unreachable ();
3711   operands[1] = GEN_INT (mask);
3712   if (signed_sat)
3713     return "ssat%?\t%0, %1, %4%S3";
3714   else
3715     return "usat%?\t%0, %1, %4%S3";
3717   [(set_attr "predicable" "yes")
3718    (set_attr "predicable_short_it" "no")
3719    (set_attr "shift" "3")
3720    (set_attr "type" "logic_shift_reg")])
3722 ;; Shift and rotation insns
3724 (define_expand "ashldi3"
3725   [(set (match_operand:DI            0 "s_register_operand" "")
3726         (ashift:DI (match_operand:DI 1 "s_register_operand" "")
3727                    (match_operand:SI 2 "general_operand" "")))]
3728   "TARGET_32BIT"
3729   "
3730   if (TARGET_NEON)
3731     {
3732       /* Delay the decision whether to use NEON or core-regs until
3733          register allocation.  */
3734       emit_insn (gen_ashldi3_neon (operands[0], operands[1], operands[2]));
3735       DONE;
3736     }
3737   else
3738     {
3739       /* Only the NEON case can handle in-memory shift counts.  */
3740       if (!reg_or_int_operand (operands[2], SImode))
3741         operands[2] = force_reg (SImode, operands[2]);
3742     }
3744   if (!CONST_INT_P (operands[2]) && TARGET_REALLY_IWMMXT)
3745     ; /* No special preparation statements; expand pattern as above.  */
3746   else
3747     {
3748       rtx scratch1, scratch2;
3750       if (operands[2] == CONST1_RTX (SImode))
3751         {
3752           emit_insn (gen_arm_ashldi3_1bit (operands[0], operands[1]));
3753           DONE;
3754         }
3756       /* Ideally we should use iwmmxt here if we could know that operands[1]
3757          ends up already living in an iwmmxt register. Otherwise it's
3758          cheaper to have the alternate code being generated than moving
3759          values to iwmmxt regs and back.  */
3761       /* If we're optimizing for size, we prefer the libgcc calls.  */
3762       if (optimize_function_for_size_p (cfun))
3763         FAIL;
3765       /* Expand operation using core-registers.
3766          'FAIL' would achieve the same thing, but this is a bit smarter.  */
3767       scratch1 = gen_reg_rtx (SImode);
3768       scratch2 = gen_reg_rtx (SImode);
3769       arm_emit_coreregs_64bit_shift (ASHIFT, operands[0], operands[1],
3770                                      operands[2], scratch1, scratch2);
3771       DONE;
3772     }
3773   "
3776 (define_insn "arm_ashldi3_1bit"
3777   [(set (match_operand:DI            0 "s_register_operand" "=r,&r")
3778         (ashift:DI (match_operand:DI 1 "s_register_operand" "0,r")
3779                    (const_int 1)))
3780    (clobber (reg:CC CC_REGNUM))]
3781   "TARGET_32BIT"
3782   "movs\\t%Q0, %Q1, asl #1\;adc\\t%R0, %R1, %R1"
3783   [(set_attr "conds" "clob")
3784    (set_attr "length" "8")
3785    (set_attr "type" "multiple")]
3788 (define_expand "ashlsi3"
3789   [(set (match_operand:SI            0 "s_register_operand" "")
3790         (ashift:SI (match_operand:SI 1 "s_register_operand" "")
3791                    (match_operand:SI 2 "arm_rhs_operand" "")))]
3792   "TARGET_EITHER"
3793   "
3794   if (CONST_INT_P (operands[2])
3795       && (UINTVAL (operands[2])) > 31)
3796     {
3797       emit_insn (gen_movsi (operands[0], const0_rtx));
3798       DONE;
3799     }
3800   "
3803 (define_expand "ashrdi3"
3804   [(set (match_operand:DI              0 "s_register_operand" "")
3805         (ashiftrt:DI (match_operand:DI 1 "s_register_operand" "")
3806                      (match_operand:SI 2 "reg_or_int_operand" "")))]
3807   "TARGET_32BIT"
3808   "
3809   if (TARGET_NEON)
3810     {
3811       /* Delay the decision whether to use NEON or core-regs until
3812          register allocation.  */
3813       emit_insn (gen_ashrdi3_neon (operands[0], operands[1], operands[2]));
3814       DONE;
3815     }
3817   if (!CONST_INT_P (operands[2]) && TARGET_REALLY_IWMMXT)
3818     ; /* No special preparation statements; expand pattern as above.  */
3819   else
3820     {
3821       rtx scratch1, scratch2;
3823       if (operands[2] == CONST1_RTX (SImode))
3824         {
3825           emit_insn (gen_arm_ashrdi3_1bit (operands[0], operands[1]));
3826           DONE;
3827         }
3829       /* Ideally we should use iwmmxt here if we could know that operands[1]
3830          ends up already living in an iwmmxt register. Otherwise it's
3831          cheaper to have the alternate code being generated than moving
3832          values to iwmmxt regs and back.  */
3834       /* If we're optimizing for size, we prefer the libgcc calls.  */
3835       if (optimize_function_for_size_p (cfun))
3836         FAIL;
3838       /* Expand operation using core-registers.
3839          'FAIL' would achieve the same thing, but this is a bit smarter.  */
3840       scratch1 = gen_reg_rtx (SImode);
3841       scratch2 = gen_reg_rtx (SImode);
3842       arm_emit_coreregs_64bit_shift (ASHIFTRT, operands[0], operands[1],
3843                                      operands[2], scratch1, scratch2);
3844       DONE;
3845     }
3846   "
3849 (define_insn "arm_ashrdi3_1bit"
3850   [(set (match_operand:DI              0 "s_register_operand" "=r,&r")
3851         (ashiftrt:DI (match_operand:DI 1 "s_register_operand" "0,r")
3852                      (const_int 1)))
3853    (clobber (reg:CC CC_REGNUM))]
3854   "TARGET_32BIT"
3855   "movs\\t%R0, %R1, asr #1\;mov\\t%Q0, %Q1, rrx"
3856   [(set_attr "conds" "clob")
3857    (set_attr "length" "8")
3858    (set_attr "type" "multiple")]
3861 (define_expand "ashrsi3"
3862   [(set (match_operand:SI              0 "s_register_operand" "")
3863         (ashiftrt:SI (match_operand:SI 1 "s_register_operand" "")
3864                      (match_operand:SI 2 "arm_rhs_operand" "")))]
3865   "TARGET_EITHER"
3866   "
3867   if (CONST_INT_P (operands[2])
3868       && UINTVAL (operands[2]) > 31)
3869     operands[2] = GEN_INT (31);
3870   "
3873 (define_expand "lshrdi3"
3874   [(set (match_operand:DI              0 "s_register_operand" "")
3875         (lshiftrt:DI (match_operand:DI 1 "s_register_operand" "")
3876                      (match_operand:SI 2 "reg_or_int_operand" "")))]
3877   "TARGET_32BIT"
3878   "
3879   if (TARGET_NEON)
3880     {
3881       /* Delay the decision whether to use NEON or core-regs until
3882          register allocation.  */
3883       emit_insn (gen_lshrdi3_neon (operands[0], operands[1], operands[2]));
3884       DONE;
3885     }
3887   if (!CONST_INT_P (operands[2]) && TARGET_REALLY_IWMMXT)
3888     ; /* No special preparation statements; expand pattern as above.  */
3889   else
3890     {
3891       rtx scratch1, scratch2;
3893       if (operands[2] == CONST1_RTX (SImode))
3894         {
3895           emit_insn (gen_arm_lshrdi3_1bit (operands[0], operands[1]));
3896           DONE;
3897         }
3899       /* Ideally we should use iwmmxt here if we could know that operands[1]
3900          ends up already living in an iwmmxt register. Otherwise it's
3901          cheaper to have the alternate code being generated than moving
3902          values to iwmmxt regs and back.  */
3904       /* If we're optimizing for size, we prefer the libgcc calls.  */
3905       if (optimize_function_for_size_p (cfun))
3906         FAIL;
3908       /* Expand operation using core-registers.
3909          'FAIL' would achieve the same thing, but this is a bit smarter.  */
3910       scratch1 = gen_reg_rtx (SImode);
3911       scratch2 = gen_reg_rtx (SImode);
3912       arm_emit_coreregs_64bit_shift (LSHIFTRT, operands[0], operands[1],
3913                                      operands[2], scratch1, scratch2);
3914       DONE;
3915     }
3916   "
3919 (define_insn "arm_lshrdi3_1bit"
3920   [(set (match_operand:DI              0 "s_register_operand" "=r,&r")
3921         (lshiftrt:DI (match_operand:DI 1 "s_register_operand" "0,r")
3922                      (const_int 1)))
3923    (clobber (reg:CC CC_REGNUM))]
3924   "TARGET_32BIT"
3925   "movs\\t%R0, %R1, lsr #1\;mov\\t%Q0, %Q1, rrx"
3926   [(set_attr "conds" "clob")
3927    (set_attr "length" "8")
3928    (set_attr "type" "multiple")]
3931 (define_expand "lshrsi3"
3932   [(set (match_operand:SI              0 "s_register_operand" "")
3933         (lshiftrt:SI (match_operand:SI 1 "s_register_operand" "")
3934                      (match_operand:SI 2 "arm_rhs_operand" "")))]
3935   "TARGET_EITHER"
3936   "
3937   if (CONST_INT_P (operands[2])
3938       && (UINTVAL (operands[2])) > 31)
3939     {
3940       emit_insn (gen_movsi (operands[0], const0_rtx));
3941       DONE;
3942     }
3943   "
3946 (define_expand "rotlsi3"
3947   [(set (match_operand:SI              0 "s_register_operand" "")
3948         (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
3949                      (match_operand:SI 2 "reg_or_int_operand" "")))]
3950   "TARGET_32BIT"
3951   "
3952   if (CONST_INT_P (operands[2]))
3953     operands[2] = GEN_INT ((32 - INTVAL (operands[2])) % 32);
3954   else
3955     {
3956       rtx reg = gen_reg_rtx (SImode);
3957       emit_insn (gen_subsi3 (reg, GEN_INT (32), operands[2]));
3958       operands[2] = reg;
3959     }
3960   "
3963 (define_expand "rotrsi3"
3964   [(set (match_operand:SI              0 "s_register_operand" "")
3965         (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
3966                      (match_operand:SI 2 "arm_rhs_operand" "")))]
3967   "TARGET_EITHER"
3968   "
3969   if (TARGET_32BIT)
3970     {
3971       if (CONST_INT_P (operands[2])
3972           && UINTVAL (operands[2]) > 31)
3973         operands[2] = GEN_INT (INTVAL (operands[2]) % 32);
3974     }
3975   else /* TARGET_THUMB1 */
3976     {
3977       if (CONST_INT_P (operands [2]))
3978         operands [2] = force_reg (SImode, operands[2]);
3979     }
3980   "
3983 (define_insn "*arm_shiftsi3"
3984   [(set (match_operand:SI   0 "s_register_operand" "=l,l,r,r")
3985         (match_operator:SI  3 "shift_operator"
3986          [(match_operand:SI 1 "s_register_operand"  "0,l,r,r")
3987           (match_operand:SI 2 "reg_or_int_operand" "l,M,M,r")]))]
3988   "TARGET_32BIT"
3989   "* return arm_output_shift(operands, 0);"
3990   [(set_attr "predicable" "yes")
3991    (set_attr "arch" "t2,t2,*,*")
3992    (set_attr "predicable_short_it" "yes,yes,no,no")
3993    (set_attr "length" "4")
3994    (set_attr "shift" "1")
3995    (set_attr "type" "alu_shift_reg,alu_shift_imm,alu_shift_imm,alu_shift_reg")]
3998 (define_insn "*shiftsi3_compare0"
3999   [(set (reg:CC_NOOV CC_REGNUM)
4000         (compare:CC_NOOV (match_operator:SI 3 "shift_operator"
4001                           [(match_operand:SI 1 "s_register_operand" "r,r")
4002                            (match_operand:SI 2 "arm_rhs_operand" "M,r")])
4003                          (const_int 0)))
4004    (set (match_operand:SI 0 "s_register_operand" "=r,r")
4005         (match_op_dup 3 [(match_dup 1) (match_dup 2)]))]
4006   "TARGET_32BIT"
4007   "* return arm_output_shift(operands, 1);"
4008   [(set_attr "conds" "set")
4009    (set_attr "shift" "1")
4010    (set_attr "type" "alus_shift_imm,alus_shift_reg")]
4013 (define_insn "*shiftsi3_compare0_scratch"
4014   [(set (reg:CC_NOOV CC_REGNUM)
4015         (compare:CC_NOOV (match_operator:SI 3 "shift_operator"
4016                           [(match_operand:SI 1 "s_register_operand" "r,r")
4017                            (match_operand:SI 2 "arm_rhs_operand" "M,r")])
4018                          (const_int 0)))
4019    (clobber (match_scratch:SI 0 "=r,r"))]
4020   "TARGET_32BIT"
4021   "* return arm_output_shift(operands, 1);"
4022   [(set_attr "conds" "set")
4023    (set_attr "shift" "1")
4024    (set_attr "type" "shift_imm,shift_reg")]
4027 (define_insn "*not_shiftsi"
4028   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4029         (not:SI (match_operator:SI 3 "shift_operator"
4030                  [(match_operand:SI 1 "s_register_operand" "r,r")
4031                   (match_operand:SI 2 "shift_amount_operand" "M,rM")])))]
4032   "TARGET_32BIT"
4033   "mvn%?\\t%0, %1%S3"
4034   [(set_attr "predicable" "yes")
4035    (set_attr "predicable_short_it" "no")
4036    (set_attr "shift" "1")
4037    (set_attr "arch" "32,a")
4038    (set_attr "type" "mvn_shift,mvn_shift_reg")])
4040 (define_insn "*not_shiftsi_compare0"
4041   [(set (reg:CC_NOOV CC_REGNUM)
4042         (compare:CC_NOOV
4043          (not:SI (match_operator:SI 3 "shift_operator"
4044                   [(match_operand:SI 1 "s_register_operand" "r,r")
4045                    (match_operand:SI 2 "shift_amount_operand" "M,rM")]))
4046          (const_int 0)))
4047    (set (match_operand:SI 0 "s_register_operand" "=r,r")
4048         (not:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])))]
4049   "TARGET_32BIT"
4050   "mvns%?\\t%0, %1%S3"
4051   [(set_attr "conds" "set")
4052    (set_attr "shift" "1")
4053    (set_attr "arch" "32,a")
4054    (set_attr "type" "mvn_shift,mvn_shift_reg")])
4056 (define_insn "*not_shiftsi_compare0_scratch"
4057   [(set (reg:CC_NOOV CC_REGNUM)
4058         (compare:CC_NOOV
4059          (not:SI (match_operator:SI 3 "shift_operator"
4060                   [(match_operand:SI 1 "s_register_operand" "r,r")
4061                    (match_operand:SI 2 "shift_amount_operand" "M,rM")]))
4062          (const_int 0)))
4063    (clobber (match_scratch:SI 0 "=r,r"))]
4064   "TARGET_32BIT"
4065   "mvns%?\\t%0, %1%S3"
4066   [(set_attr "conds" "set")
4067    (set_attr "shift" "1")
4068    (set_attr "arch" "32,a")
4069    (set_attr "type" "mvn_shift,mvn_shift_reg")])
4071 ;; We don't really have extzv, but defining this using shifts helps
4072 ;; to reduce register pressure later on.
4074 (define_expand "extzv"
4075   [(set (match_operand 0 "s_register_operand" "")
4076         (zero_extract (match_operand 1 "nonimmediate_operand" "")
4077                       (match_operand 2 "const_int_operand" "")
4078                       (match_operand 3 "const_int_operand" "")))]
4079   "TARGET_THUMB1 || arm_arch_thumb2"
4080   "
4081   {
4082     HOST_WIDE_INT lshift = 32 - INTVAL (operands[2]) - INTVAL (operands[3]);
4083     HOST_WIDE_INT rshift = 32 - INTVAL (operands[2]);
4084     
4085     if (arm_arch_thumb2)
4086       {
4087         HOST_WIDE_INT width = INTVAL (operands[2]);
4088         HOST_WIDE_INT bitpos = INTVAL (operands[3]);
4090         if (unaligned_access && MEM_P (operands[1])
4091             && (width == 16 || width == 32) && (bitpos % BITS_PER_UNIT) == 0)
4092           {
4093             rtx base_addr;
4095             if (BYTES_BIG_ENDIAN)
4096               bitpos = GET_MODE_BITSIZE (GET_MODE (operands[0])) - width
4097                        - bitpos;
4099             if (width == 32)
4100               {
4101                 base_addr = adjust_address (operands[1], SImode,
4102                                             bitpos / BITS_PER_UNIT);
4103                 emit_insn (gen_unaligned_loadsi (operands[0], base_addr));
4104               }
4105             else
4106               {
4107                 rtx dest = operands[0];
4108                 rtx tmp = gen_reg_rtx (SImode);
4110                 /* We may get a paradoxical subreg here.  Strip it off.  */
4111                 if (GET_CODE (dest) == SUBREG
4112                     && GET_MODE (dest) == SImode
4113                     && GET_MODE (SUBREG_REG (dest)) == HImode)
4114                   dest = SUBREG_REG (dest);
4116                 if (GET_MODE_BITSIZE (GET_MODE (dest)) != width)
4117                   FAIL;
4119                 base_addr = adjust_address (operands[1], HImode,
4120                                             bitpos / BITS_PER_UNIT);
4121                 emit_insn (gen_unaligned_loadhiu (tmp, base_addr));
4122                 emit_move_insn (gen_lowpart (SImode, dest), tmp);
4123               }
4124             DONE;
4125           }
4126         else if (s_register_operand (operands[1], GET_MODE (operands[1])))
4127           {
4128             emit_insn (gen_extzv_t2 (operands[0], operands[1], operands[2],
4129                                      operands[3]));
4130             DONE;
4131           }
4132         else
4133           FAIL;
4134       }
4135     
4136     if (!s_register_operand (operands[1], GET_MODE (operands[1])))
4137       FAIL;
4139     operands[3] = GEN_INT (rshift);
4140     
4141     if (lshift == 0)
4142       {
4143         emit_insn (gen_lshrsi3 (operands[0], operands[1], operands[3]));
4144         DONE;
4145       }
4146       
4147     emit_insn (gen_extzv_t1 (operands[0], operands[1], GEN_INT (lshift),
4148                              operands[3], gen_reg_rtx (SImode)));
4149     DONE;
4150   }"
4153 ;; Helper for extzv, for the Thumb-1 register-shifts case.
4155 (define_expand "extzv_t1"
4156   [(set (match_operand:SI 4 "s_register_operand" "")
4157         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
4158                    (match_operand:SI 2 "const_int_operand" "")))
4159    (set (match_operand:SI 0 "s_register_operand" "")
4160         (lshiftrt:SI (match_dup 4)
4161                      (match_operand:SI 3 "const_int_operand" "")))]
4162   "TARGET_THUMB1"
4163   "")
4165 (define_expand "extv"
4166   [(set (match_operand 0 "s_register_operand" "")
4167         (sign_extract (match_operand 1 "nonimmediate_operand" "")
4168                       (match_operand 2 "const_int_operand" "")
4169                       (match_operand 3 "const_int_operand" "")))]
4170   "arm_arch_thumb2"
4172   HOST_WIDE_INT width = INTVAL (operands[2]);
4173   HOST_WIDE_INT bitpos = INTVAL (operands[3]);
4175   if (unaligned_access && MEM_P (operands[1]) && (width == 16 || width == 32)
4176       && (bitpos % BITS_PER_UNIT)  == 0)
4177     {
4178       rtx base_addr;
4179       
4180       if (BYTES_BIG_ENDIAN)
4181         bitpos = GET_MODE_BITSIZE (GET_MODE (operands[0])) - width - bitpos;
4182       
4183       if (width == 32)
4184         {
4185           base_addr = adjust_address (operands[1], SImode,
4186                                       bitpos / BITS_PER_UNIT);
4187           emit_insn (gen_unaligned_loadsi (operands[0], base_addr));
4188         }
4189       else
4190         {
4191           rtx dest = operands[0];
4192           rtx tmp = gen_reg_rtx (SImode);
4193           
4194           /* We may get a paradoxical subreg here.  Strip it off.  */
4195           if (GET_CODE (dest) == SUBREG
4196               && GET_MODE (dest) == SImode
4197               && GET_MODE (SUBREG_REG (dest)) == HImode)
4198             dest = SUBREG_REG (dest);
4199           
4200           if (GET_MODE_BITSIZE (GET_MODE (dest)) != width)
4201             FAIL;
4202           
4203           base_addr = adjust_address (operands[1], HImode,
4204                                       bitpos / BITS_PER_UNIT);
4205           emit_insn (gen_unaligned_loadhis (tmp, base_addr));
4206           emit_move_insn (gen_lowpart (SImode, dest), tmp);
4207         }
4209       DONE;
4210     }
4211   else if (!s_register_operand (operands[1], GET_MODE (operands[1])))
4212     FAIL;
4213   else if (GET_MODE (operands[0]) == SImode
4214            && GET_MODE (operands[1]) == SImode)
4215     {
4216       emit_insn (gen_extv_regsi (operands[0], operands[1], operands[2],
4217                                  operands[3]));
4218       DONE;
4219     }
4221   FAIL;
4224 ; Helper to expand register forms of extv with the proper modes.
4226 (define_expand "extv_regsi"
4227   [(set (match_operand:SI 0 "s_register_operand" "")
4228         (sign_extract:SI (match_operand:SI 1 "s_register_operand" "")
4229                          (match_operand 2 "const_int_operand" "")
4230                          (match_operand 3 "const_int_operand" "")))]
4231   ""
4235 ; ARMv6+ unaligned load/store instructions (used for packed structure accesses).
4237 (define_insn "unaligned_loadsi"
4238   [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4239         (unspec:SI [(match_operand:SI 1 "memory_operand" "Uw,m")]
4240                    UNSPEC_UNALIGNED_LOAD))]
4241   "unaligned_access"
4242   "ldr%?\t%0, %1\t@ unaligned"
4243   [(set_attr "arch" "t2,any")
4244    (set_attr "length" "2,4")
4245    (set_attr "predicable" "yes")
4246    (set_attr "predicable_short_it" "yes,no")
4247    (set_attr "type" "load1")])
4249 (define_insn "unaligned_loadhis"
4250   [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4251         (sign_extend:SI
4252           (unspec:HI [(match_operand:HI 1 "memory_operand" "Uw,Uh")]
4253                      UNSPEC_UNALIGNED_LOAD)))]
4254   "unaligned_access"
4255   "ldrsh%?\t%0, %1\t@ unaligned"
4256   [(set_attr "arch" "t2,any")
4257    (set_attr "length" "2,4")
4258    (set_attr "predicable" "yes")
4259    (set_attr "predicable_short_it" "yes,no")
4260    (set_attr "type" "load_byte")])
4262 (define_insn "unaligned_loadhiu"
4263   [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4264         (zero_extend:SI
4265           (unspec:HI [(match_operand:HI 1 "memory_operand" "Uw,m")]
4266                      UNSPEC_UNALIGNED_LOAD)))]
4267   "unaligned_access"
4268   "ldrh%?\t%0, %1\t@ unaligned"
4269   [(set_attr "arch" "t2,any")
4270    (set_attr "length" "2,4")
4271    (set_attr "predicable" "yes")
4272    (set_attr "predicable_short_it" "yes,no")
4273    (set_attr "type" "load_byte")])
4275 (define_insn "unaligned_storesi"
4276   [(set (match_operand:SI 0 "memory_operand" "=Uw,m")
4277         (unspec:SI [(match_operand:SI 1 "s_register_operand" "l,r")]
4278                    UNSPEC_UNALIGNED_STORE))]
4279   "unaligned_access"
4280   "str%?\t%1, %0\t@ unaligned"
4281   [(set_attr "arch" "t2,any")
4282    (set_attr "length" "2,4")
4283    (set_attr "predicable" "yes")
4284    (set_attr "predicable_short_it" "yes,no")
4285    (set_attr "type" "store1")])
4287 (define_insn "unaligned_storehi"
4288   [(set (match_operand:HI 0 "memory_operand" "=Uw,m")
4289         (unspec:HI [(match_operand:HI 1 "s_register_operand" "l,r")]
4290                    UNSPEC_UNALIGNED_STORE))]
4291   "unaligned_access"
4292   "strh%?\t%1, %0\t@ unaligned"
4293   [(set_attr "arch" "t2,any")
4294    (set_attr "length" "2,4")
4295    (set_attr "predicable" "yes")
4296    (set_attr "predicable_short_it" "yes,no")
4297    (set_attr "type" "store1")])
4300 (define_insn "*extv_reg"
4301   [(set (match_operand:SI 0 "s_register_operand" "=r")
4302         (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
4303                          (match_operand:SI 2 "const_int_M_operand" "M")
4304                          (match_operand:SI 3 "const_int_M_operand" "M")))]
4305   "arm_arch_thumb2"
4306   "sbfx%?\t%0, %1, %3, %2"
4307   [(set_attr "length" "4")
4308    (set_attr "predicable" "yes")
4309    (set_attr "predicable_short_it" "no")
4310    (set_attr "type" "bfm")]
4313 (define_insn "extzv_t2"
4314   [(set (match_operand:SI 0 "s_register_operand" "=r")
4315         (zero_extract:SI (match_operand:SI 1 "s_register_operand" "r")
4316                          (match_operand:SI 2 "const_int_M_operand" "M")
4317                          (match_operand:SI 3 "const_int_M_operand" "M")))]
4318   "arm_arch_thumb2"
4319   "ubfx%?\t%0, %1, %3, %2"
4320   [(set_attr "length" "4")
4321    (set_attr "predicable" "yes")
4322    (set_attr "predicable_short_it" "no")
4323    (set_attr "type" "bfm")]
4327 ;; Division instructions
4328 (define_insn "divsi3"
4329   [(set (match_operand:SI         0 "s_register_operand" "=r")
4330         (div:SI (match_operand:SI 1 "s_register_operand"  "r")
4331                 (match_operand:SI 2 "s_register_operand"  "r")))]
4332   "TARGET_IDIV"
4333   "sdiv%?\t%0, %1, %2"
4334   [(set_attr "predicable" "yes")
4335    (set_attr "predicable_short_it" "no")
4336    (set_attr "type" "sdiv")]
4339 (define_insn "udivsi3"
4340   [(set (match_operand:SI          0 "s_register_operand" "=r")
4341         (udiv:SI (match_operand:SI 1 "s_register_operand"  "r")
4342                  (match_operand:SI 2 "s_register_operand"  "r")))]
4343   "TARGET_IDIV"
4344   "udiv%?\t%0, %1, %2"
4345   [(set_attr "predicable" "yes")
4346    (set_attr "predicable_short_it" "no")
4347    (set_attr "type" "udiv")]
4351 ;; Unary arithmetic insns
4353 (define_expand "negdi2"
4354  [(parallel
4355    [(set (match_operand:DI 0 "s_register_operand" "")
4356          (neg:DI (match_operand:DI 1 "s_register_operand" "")))
4357     (clobber (reg:CC CC_REGNUM))])]
4358   "TARGET_EITHER"
4359   {
4360     if (TARGET_NEON)
4361       {
4362         emit_insn (gen_negdi2_neon (operands[0], operands[1]));
4363         DONE;
4364       }
4365   }
4368 ;; The constraints here are to prevent a *partial* overlap (where %Q0 == %R1).
4369 ;; The first alternative allows the common case of a *full* overlap.
4370 (define_insn_and_split "*arm_negdi2"
4371   [(set (match_operand:DI         0 "s_register_operand" "=r,&r")
4372         (neg:DI (match_operand:DI 1 "s_register_operand"  "0,r")))
4373    (clobber (reg:CC CC_REGNUM))]
4374   "TARGET_ARM"
4375   "#"   ; "rsbs\\t%Q0, %Q1, #0\;rsc\\t%R0, %R1, #0"
4376   "&& reload_completed"
4377   [(parallel [(set (reg:CC CC_REGNUM)
4378                    (compare:CC (const_int 0) (match_dup 1)))
4379               (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1)))])
4380    (set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3))
4381                                 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
4382   {
4383     operands[2] = gen_highpart (SImode, operands[0]);
4384     operands[0] = gen_lowpart (SImode, operands[0]);
4385     operands[3] = gen_highpart (SImode, operands[1]);
4386     operands[1] = gen_lowpart (SImode, operands[1]);
4387   }
4388   [(set_attr "conds" "clob")
4389    (set_attr "length" "8")
4390    (set_attr "type" "multiple")]
4393 (define_expand "negsi2"
4394   [(set (match_operand:SI         0 "s_register_operand" "")
4395         (neg:SI (match_operand:SI 1 "s_register_operand" "")))]
4396   "TARGET_EITHER"
4397   ""
4400 (define_insn "*arm_negsi2"
4401   [(set (match_operand:SI         0 "s_register_operand" "=l,r")
4402         (neg:SI (match_operand:SI 1 "s_register_operand" "l,r")))]
4403   "TARGET_32BIT"
4404   "rsb%?\\t%0, %1, #0"
4405   [(set_attr "predicable" "yes")
4406    (set_attr "predicable_short_it" "yes,no")
4407    (set_attr "arch" "t2,*")
4408    (set_attr "length" "4")
4409    (set_attr "type" "alu_sreg")]
4412 (define_expand "negsf2"
4413   [(set (match_operand:SF         0 "s_register_operand" "")
4414         (neg:SF (match_operand:SF 1 "s_register_operand" "")))]
4415   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
4416   ""
4419 (define_expand "negdf2"
4420   [(set (match_operand:DF         0 "s_register_operand" "")
4421         (neg:DF (match_operand:DF 1 "s_register_operand" "")))]
4422   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
4423   "")
4425 (define_insn_and_split "*zextendsidi_negsi"
4426   [(set (match_operand:DI 0 "s_register_operand" "=r")
4427         (zero_extend:DI (neg:SI (match_operand:SI 1 "s_register_operand" "r"))))]
4428    "TARGET_32BIT"
4429    "#"
4430    ""
4431    [(set (match_dup 2)
4432          (neg:SI (match_dup 1)))
4433     (set (match_dup 3)
4434          (const_int 0))]
4435    {
4436       operands[2] = gen_lowpart (SImode, operands[0]);
4437       operands[3] = gen_highpart (SImode, operands[0]);
4438    }
4439  [(set_attr "length" "8")
4440   (set_attr "type" "multiple")]
4443 ;; Negate an extended 32-bit value.
4444 (define_insn_and_split "*negdi_extendsidi"
4445   [(set (match_operand:DI 0 "s_register_operand" "=l,r")
4446         (neg:DI (sign_extend:DI
4447                  (match_operand:SI 1 "s_register_operand" "l,r"))))
4448    (clobber (reg:CC CC_REGNUM))]
4449   "TARGET_32BIT"
4450   "#"
4451   "&& reload_completed"
4452   [(const_int 0)]
4453   {
4454     rtx low = gen_lowpart (SImode, operands[0]);
4455     rtx high = gen_highpart (SImode, operands[0]);
4457     if (reg_overlap_mentioned_p (low, operands[1]))
4458       {
4459         /* Input overlaps the low word of the output.  Use:
4460                 asr     Rhi, Rin, #31
4461                 rsbs    Rlo, Rin, #0
4462                 rsc     Rhi, Rhi, #0 (thumb2: sbc Rhi, Rhi, Rhi, lsl #1).  */
4463         rtx cc_reg = gen_rtx_REG (CC_Cmode, CC_REGNUM);
4465         emit_insn (gen_rtx_SET (high,
4466                                 gen_rtx_ASHIFTRT (SImode, operands[1],
4467                                                   GEN_INT (31))));
4469         emit_insn (gen_subsi3_compare (low, const0_rtx, operands[1]));
4470         if (TARGET_ARM)
4471           emit_insn (gen_rtx_SET (high,
4472                                   gen_rtx_MINUS (SImode,
4473                                                  gen_rtx_MINUS (SImode,
4474                                                                 const0_rtx,
4475                                                                 high),
4476                                                  gen_rtx_LTU (SImode,
4477                                                               cc_reg,
4478                                                               const0_rtx))));
4479         else
4480           {
4481             rtx two_x = gen_rtx_ASHIFT (SImode, high, GEN_INT (1));
4482             emit_insn (gen_rtx_SET (high,
4483                                     gen_rtx_MINUS (SImode,
4484                                                    gen_rtx_MINUS (SImode,
4485                                                                   high,
4486                                                                   two_x),
4487                                                    gen_rtx_LTU (SImode,
4488                                                                 cc_reg,
4489                                                                 const0_rtx))));
4490           }
4491       }
4492     else
4493       {
4494         /* No overlap, or overlap on high word.  Use:
4495                 rsb     Rlo, Rin, #0
4496                 bic     Rhi, Rlo, Rin
4497                 asr     Rhi, Rhi, #31
4498            Flags not needed for this sequence.  */
4499         emit_insn (gen_rtx_SET (low, gen_rtx_NEG (SImode, operands[1])));
4500         emit_insn (gen_rtx_SET (high,
4501                                 gen_rtx_AND (SImode,
4502                                              gen_rtx_NOT (SImode, operands[1]),
4503                                              low)));
4504         emit_insn (gen_rtx_SET (high,
4505                                 gen_rtx_ASHIFTRT (SImode, high,
4506                                                   GEN_INT (31))));
4507       }
4508     DONE;
4509   }
4510   [(set_attr "length" "12")
4511    (set_attr "arch" "t2,*")
4512    (set_attr "type" "multiple")]
4515 (define_insn_and_split "*negdi_zero_extendsidi"
4516   [(set (match_operand:DI 0 "s_register_operand" "=r,&r")
4517         (neg:DI (zero_extend:DI (match_operand:SI 1 "s_register_operand" "0,r"))))
4518    (clobber (reg:CC CC_REGNUM))]
4519   "TARGET_32BIT"
4520   "#" ; "rsbs\\t%Q0, %1, #0\;sbc\\t%R0,%R0,%R0"
4521       ;; Don't care what register is input to sbc,
4522       ;; since we just need to propagate the carry.
4523   "&& reload_completed"
4524   [(parallel [(set (reg:CC CC_REGNUM)
4525                    (compare:CC (const_int 0) (match_dup 1)))
4526               (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1)))])
4527    (set (match_dup 2) (minus:SI (minus:SI (match_dup 2) (match_dup 2))
4528                                 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
4529   {
4530     operands[2] = gen_highpart (SImode, operands[0]);
4531     operands[0] = gen_lowpart (SImode, operands[0]);
4532   }
4533   [(set_attr "conds" "clob")
4534    (set_attr "length" "8")
4535    (set_attr "type" "multiple")]   ;; length in thumb is 4
4538 ;; abssi2 doesn't really clobber the condition codes if a different register
4539 ;; is being set.  To keep things simple, assume during rtl manipulations that
4540 ;; it does, but tell the final scan operator the truth.  Similarly for
4541 ;; (neg (abs...))
4543 (define_expand "abssi2"
4544   [(parallel
4545     [(set (match_operand:SI         0 "s_register_operand" "")
4546           (abs:SI (match_operand:SI 1 "s_register_operand" "")))
4547      (clobber (match_dup 2))])]
4548   "TARGET_EITHER"
4549   "
4550   if (TARGET_THUMB1)
4551     operands[2] = gen_rtx_SCRATCH (SImode);
4552   else
4553     operands[2] = gen_rtx_REG (CCmode, CC_REGNUM);
4556 (define_insn_and_split "*arm_abssi2"
4557   [(set (match_operand:SI 0 "s_register_operand" "=r,&r")
4558         (abs:SI (match_operand:SI 1 "s_register_operand" "0,r")))
4559    (clobber (reg:CC CC_REGNUM))]
4560   "TARGET_ARM"
4561   "#"
4562   "&& reload_completed"
4563   [(const_int 0)]
4564   {
4565    /* if (which_alternative == 0) */
4566    if (REGNO(operands[0]) == REGNO(operands[1]))
4567      {
4568       /* Emit the pattern:
4569          cmp\\t%0, #0\;rsblt\\t%0, %0, #0
4570          [(set (reg:CC CC_REGNUM)
4571                (compare:CC (match_dup 0) (const_int 0)))
4572           (cond_exec (lt:CC (reg:CC CC_REGNUM) (const_int 0))
4573                      (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1))))]
4574       */
4575       emit_insn (gen_rtx_SET (gen_rtx_REG (CCmode, CC_REGNUM),
4576                               gen_rtx_COMPARE (CCmode, operands[0], const0_rtx)));
4577       emit_insn (gen_rtx_COND_EXEC (VOIDmode,
4578                                     (gen_rtx_LT (SImode,
4579                                                  gen_rtx_REG (CCmode, CC_REGNUM),
4580                                                  const0_rtx)),
4581                                     (gen_rtx_SET (operands[0],
4582                                                   (gen_rtx_MINUS (SImode,
4583                                                                   const0_rtx,
4584                                                                   operands[1]))))));
4585       DONE;
4586      }
4587    else
4588      {
4589       /* Emit the pattern:
4590          alt1: eor%?\\t%0, %1, %1, asr #31\;sub%?\\t%0, %0, %1, asr #31
4591          [(set (match_dup 0)
4592                (xor:SI (match_dup 1)
4593                        (ashiftrt:SI (match_dup 1) (const_int 31))))
4594           (set (match_dup 0)
4595                (minus:SI (match_dup 0)
4596                       (ashiftrt:SI (match_dup 1) (const_int 31))))]
4597       */
4598       emit_insn (gen_rtx_SET (operands[0],
4599                               gen_rtx_XOR (SImode,
4600                                            gen_rtx_ASHIFTRT (SImode,
4601                                                              operands[1],
4602                                                              GEN_INT (31)),
4603                                            operands[1])));
4604       emit_insn (gen_rtx_SET (operands[0],
4605                               gen_rtx_MINUS (SImode,
4606                                              operands[0],
4607                                              gen_rtx_ASHIFTRT (SImode,
4608                                                                operands[1],
4609                                                                GEN_INT (31)))));
4610       DONE;
4611      }
4612   }
4613   [(set_attr "conds" "clob,*")
4614    (set_attr "shift" "1")
4615    (set_attr "predicable" "no, yes")
4616    (set_attr "length" "8")
4617    (set_attr "type" "multiple")]
4620 (define_insn_and_split "*arm_neg_abssi2"
4621   [(set (match_operand:SI 0 "s_register_operand" "=r,&r")
4622         (neg:SI (abs:SI (match_operand:SI 1 "s_register_operand" "0,r"))))
4623    (clobber (reg:CC CC_REGNUM))]
4624   "TARGET_ARM"
4625   "#"
4626   "&& reload_completed"
4627   [(const_int 0)]
4628   {
4629    /* if (which_alternative == 0) */
4630    if (REGNO (operands[0]) == REGNO (operands[1]))
4631      {
4632       /* Emit the pattern:
4633          cmp\\t%0, #0\;rsbgt\\t%0, %0, #0
4634       */
4635       emit_insn (gen_rtx_SET (gen_rtx_REG (CCmode, CC_REGNUM),
4636                               gen_rtx_COMPARE (CCmode, operands[0], const0_rtx)));
4637       emit_insn (gen_rtx_COND_EXEC (VOIDmode,
4638                                     gen_rtx_GT (SImode,
4639                                                 gen_rtx_REG (CCmode, CC_REGNUM),
4640                                                 const0_rtx),
4641                                     gen_rtx_SET (operands[0],
4642                                                  (gen_rtx_MINUS (SImode,
4643                                                                  const0_rtx,
4644                                                                  operands[1])))));
4645      }
4646    else
4647      {
4648       /* Emit the pattern:
4649          eor%?\\t%0, %1, %1, asr #31\;rsb%?\\t%0, %0, %1, asr #31
4650       */
4651       emit_insn (gen_rtx_SET (operands[0],
4652                               gen_rtx_XOR (SImode,
4653                                            gen_rtx_ASHIFTRT (SImode,
4654                                                              operands[1],
4655                                                              GEN_INT (31)),
4656                                            operands[1])));
4657       emit_insn (gen_rtx_SET (operands[0],
4658                               gen_rtx_MINUS (SImode,
4659                                              gen_rtx_ASHIFTRT (SImode,
4660                                                                operands[1],
4661                                                                GEN_INT (31)),
4662                                              operands[0])));
4663      }
4664    DONE;
4665   }
4666   [(set_attr "conds" "clob,*")
4667    (set_attr "shift" "1")
4668    (set_attr "predicable" "no, yes")
4669    (set_attr "length" "8")
4670    (set_attr "type" "multiple")]
4673 (define_expand "abssf2"
4674   [(set (match_operand:SF         0 "s_register_operand" "")
4675         (abs:SF (match_operand:SF 1 "s_register_operand" "")))]
4676   "TARGET_32BIT && TARGET_HARD_FLOAT"
4677   "")
4679 (define_expand "absdf2"
4680   [(set (match_operand:DF         0 "s_register_operand" "")
4681         (abs:DF (match_operand:DF 1 "s_register_operand" "")))]
4682   "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
4683   "")
4685 (define_expand "sqrtsf2"
4686   [(set (match_operand:SF 0 "s_register_operand" "")
4687         (sqrt:SF (match_operand:SF 1 "s_register_operand" "")))]
4688   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
4689   "")
4691 (define_expand "sqrtdf2"
4692   [(set (match_operand:DF 0 "s_register_operand" "")
4693         (sqrt:DF (match_operand:DF 1 "s_register_operand" "")))]
4694   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
4695   "")
4697 (define_insn_and_split "one_cmpldi2"
4698   [(set (match_operand:DI 0 "s_register_operand"         "=w,&r,&r,?w")
4699         (not:DI (match_operand:DI 1 "s_register_operand" " w, 0, r, w")))]
4700   "TARGET_32BIT"
4701   "@
4702    vmvn\t%P0, %P1
4703    #
4704    #
4705    vmvn\t%P0, %P1"
4706   "TARGET_32BIT && reload_completed
4707    && arm_general_register_operand (operands[0], DImode)"
4708   [(set (match_dup 0) (not:SI (match_dup 1)))
4709    (set (match_dup 2) (not:SI (match_dup 3)))]
4710   "
4711   {
4712     operands[2] = gen_highpart (SImode, operands[0]);
4713     operands[0] = gen_lowpart (SImode, operands[0]);
4714     operands[3] = gen_highpart (SImode, operands[1]);
4715     operands[1] = gen_lowpart (SImode, operands[1]);
4716   }"
4717   [(set_attr "length" "*,8,8,*")
4718    (set_attr "predicable" "no,yes,yes,no")
4719    (set_attr "type" "neon_move,multiple,multiple,neon_move")
4720    (set_attr "arch" "neon_for_64bits,*,*,avoid_neon_for_64bits")]
4723 (define_expand "one_cmplsi2"
4724   [(set (match_operand:SI         0 "s_register_operand" "")
4725         (not:SI (match_operand:SI 1 "s_register_operand" "")))]
4726   "TARGET_EITHER"
4727   ""
4730 (define_insn "*arm_one_cmplsi2"
4731   [(set (match_operand:SI         0 "s_register_operand" "=l,r")
4732         (not:SI (match_operand:SI 1 "s_register_operand"  "l,r")))]
4733   "TARGET_32BIT"
4734   "mvn%?\\t%0, %1"
4735   [(set_attr "predicable" "yes")
4736    (set_attr "predicable_short_it" "yes,no")
4737    (set_attr "arch" "t2,*")
4738    (set_attr "length" "4")
4739    (set_attr "type" "mvn_reg")]
4742 (define_insn "*notsi_compare0"
4743   [(set (reg:CC_NOOV CC_REGNUM)
4744         (compare:CC_NOOV (not:SI (match_operand:SI 1 "s_register_operand" "r"))
4745                          (const_int 0)))
4746    (set (match_operand:SI 0 "s_register_operand" "=r")
4747         (not:SI (match_dup 1)))]
4748   "TARGET_32BIT"
4749   "mvns%?\\t%0, %1"
4750   [(set_attr "conds" "set")
4751    (set_attr "type" "mvn_reg")]
4754 (define_insn "*notsi_compare0_scratch"
4755   [(set (reg:CC_NOOV CC_REGNUM)
4756         (compare:CC_NOOV (not:SI (match_operand:SI 1 "s_register_operand" "r"))
4757                          (const_int 0)))
4758    (clobber (match_scratch:SI 0 "=r"))]
4759   "TARGET_32BIT"
4760   "mvns%?\\t%0, %1"
4761   [(set_attr "conds" "set")
4762    (set_attr "type" "mvn_reg")]
4765 ;; Fixed <--> Floating conversion insns
4767 (define_expand "floatsihf2"
4768   [(set (match_operand:HF           0 "general_operand" "")
4769         (float:HF (match_operand:SI 1 "general_operand" "")))]
4770   "TARGET_EITHER"
4771   "
4772   {
4773     rtx op1 = gen_reg_rtx (SFmode);
4774     expand_float (op1, operands[1], 0);
4775     op1 = convert_to_mode (HFmode, op1, 0);
4776     emit_move_insn (operands[0], op1);
4777     DONE;
4778   }"
4781 (define_expand "floatdihf2"
4782   [(set (match_operand:HF           0 "general_operand" "")
4783         (float:HF (match_operand:DI 1 "general_operand" "")))]
4784   "TARGET_EITHER"
4785   "
4786   {
4787     rtx op1 = gen_reg_rtx (SFmode);
4788     expand_float (op1, operands[1], 0);
4789     op1 = convert_to_mode (HFmode, op1, 0);
4790     emit_move_insn (operands[0], op1);
4791     DONE;
4792   }"
4795 (define_expand "floatsisf2"
4796   [(set (match_operand:SF           0 "s_register_operand" "")
4797         (float:SF (match_operand:SI 1 "s_register_operand" "")))]
4798   "TARGET_32BIT && TARGET_HARD_FLOAT"
4799   "
4802 (define_expand "floatsidf2"
4803   [(set (match_operand:DF           0 "s_register_operand" "")
4804         (float:DF (match_operand:SI 1 "s_register_operand" "")))]
4805   "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
4806   "
4809 (define_expand "fix_trunchfsi2"
4810   [(set (match_operand:SI         0 "general_operand" "")
4811         (fix:SI (fix:HF (match_operand:HF 1 "general_operand"  ""))))]
4812   "TARGET_EITHER"
4813   "
4814   {
4815     rtx op1 = convert_to_mode (SFmode, operands[1], 0);
4816     expand_fix (operands[0], op1, 0);
4817     DONE;
4818   }"
4821 (define_expand "fix_trunchfdi2"
4822   [(set (match_operand:DI         0 "general_operand" "")
4823         (fix:DI (fix:HF (match_operand:HF 1 "general_operand"  ""))))]
4824   "TARGET_EITHER"
4825   "
4826   {
4827     rtx op1 = convert_to_mode (SFmode, operands[1], 0);
4828     expand_fix (operands[0], op1, 0);
4829     DONE;
4830   }"
4833 (define_expand "fix_truncsfsi2"
4834   [(set (match_operand:SI         0 "s_register_operand" "")
4835         (fix:SI (fix:SF (match_operand:SF 1 "s_register_operand"  ""))))]
4836   "TARGET_32BIT && TARGET_HARD_FLOAT"
4837   "
4840 (define_expand "fix_truncdfsi2"
4841   [(set (match_operand:SI         0 "s_register_operand" "")
4842         (fix:SI (fix:DF (match_operand:DF 1 "s_register_operand"  ""))))]
4843   "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
4844   "
4847 ;; Truncation insns
4849 (define_expand "truncdfsf2"
4850   [(set (match_operand:SF  0 "s_register_operand" "")
4851         (float_truncate:SF
4852          (match_operand:DF 1 "s_register_operand" "")))]
4853   "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
4854   ""
4857 /* DFmode -> HFmode conversions have to go through SFmode.  */
4858 (define_expand "truncdfhf2"
4859   [(set (match_operand:HF  0 "general_operand" "")
4860         (float_truncate:HF
4861          (match_operand:DF 1 "general_operand" "")))]
4862   "TARGET_EITHER"
4863   "
4864   {
4865     rtx op1;
4866     op1 = convert_to_mode (SFmode, operands[1], 0);
4867     op1 = convert_to_mode (HFmode, op1, 0);
4868     emit_move_insn (operands[0], op1);
4869     DONE;
4870   }"
4873 ;; Zero and sign extension instructions.
4875 (define_insn "zero_extend<mode>di2"
4876   [(set (match_operand:DI 0 "s_register_operand" "=w,r,?r,w")
4877         (zero_extend:DI (match_operand:QHSI 1 "<qhs_zextenddi_op>"
4878                                             "<qhs_zextenddi_cstr>")))]
4879   "TARGET_32BIT <qhs_zextenddi_cond>"
4880   "#"
4881   [(set_attr "length" "8,4,8,8")
4882    (set_attr "arch" "neon_for_64bits,*,*,avoid_neon_for_64bits")
4883    (set_attr "ce_count" "2")
4884    (set_attr "predicable" "yes")
4885    (set_attr "type" "multiple,mov_reg,multiple,multiple")]
4888 (define_insn "extend<mode>di2"
4889   [(set (match_operand:DI 0 "s_register_operand" "=w,r,?r,?r,w")
4890         (sign_extend:DI (match_operand:QHSI 1 "<qhs_extenddi_op>"
4891                                             "<qhs_extenddi_cstr>")))]
4892   "TARGET_32BIT <qhs_sextenddi_cond>"
4893   "#"
4894   [(set_attr "length" "8,4,8,8,8")
4895    (set_attr "ce_count" "2")
4896    (set_attr "shift" "1")
4897    (set_attr "predicable" "yes")
4898    (set_attr "arch" "neon_for_64bits,*,a,t,avoid_neon_for_64bits")
4899    (set_attr "type" "multiple,mov_reg,multiple,multiple,multiple")]
4902 ;; Splits for all extensions to DImode
4903 (define_split
4904   [(set (match_operand:DI 0 "s_register_operand" "")
4905         (zero_extend:DI (match_operand 1 "nonimmediate_operand" "")))]
4906   "TARGET_32BIT && reload_completed && !IS_VFP_REGNUM (REGNO (operands[0]))"
4907   [(set (match_dup 0) (match_dup 1))]
4909   rtx lo_part = gen_lowpart (SImode, operands[0]);
4910   machine_mode src_mode = GET_MODE (operands[1]);
4912   if (REG_P (operands[0])
4913       && !reg_overlap_mentioned_p (operands[0], operands[1]))
4914     emit_clobber (operands[0]);
4915   if (!REG_P (lo_part) || src_mode != SImode
4916       || !rtx_equal_p (lo_part, operands[1]))
4917     {
4918       if (src_mode == SImode)
4919         emit_move_insn (lo_part, operands[1]);
4920       else
4921         emit_insn (gen_rtx_SET (lo_part,
4922                                 gen_rtx_ZERO_EXTEND (SImode, operands[1])));
4923       operands[1] = lo_part;
4924     }
4925   operands[0] = gen_highpart (SImode, operands[0]);
4926   operands[1] = const0_rtx;
4929 (define_split
4930   [(set (match_operand:DI 0 "s_register_operand" "")
4931         (sign_extend:DI (match_operand 1 "nonimmediate_operand" "")))]
4932   "TARGET_32BIT && reload_completed && !IS_VFP_REGNUM (REGNO (operands[0]))"
4933   [(set (match_dup 0) (ashiftrt:SI (match_dup 1) (const_int 31)))]
4935   rtx lo_part = gen_lowpart (SImode, operands[0]);
4936   machine_mode src_mode = GET_MODE (operands[1]);
4938   if (REG_P (operands[0])
4939       && !reg_overlap_mentioned_p (operands[0], operands[1]))
4940     emit_clobber (operands[0]);
4942   if (!REG_P (lo_part) || src_mode != SImode
4943       || !rtx_equal_p (lo_part, operands[1]))
4944     {
4945       if (src_mode == SImode)
4946         emit_move_insn (lo_part, operands[1]);
4947       else
4948         emit_insn (gen_rtx_SET (lo_part,
4949                                 gen_rtx_SIGN_EXTEND (SImode, operands[1])));
4950       operands[1] = lo_part;
4951     }
4952   operands[0] = gen_highpart (SImode, operands[0]);
4955 (define_expand "zero_extendhisi2"
4956   [(set (match_operand:SI 0 "s_register_operand" "")
4957         (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
4958   "TARGET_EITHER"
4960   if (TARGET_ARM && !arm_arch4 && MEM_P (operands[1]))
4961     {
4962       emit_insn (gen_movhi_bytes (operands[0], operands[1]));
4963       DONE;
4964     }
4965   if (!arm_arch6 && !MEM_P (operands[1]))
4966     {
4967       rtx t = gen_lowpart (SImode, operands[1]);
4968       rtx tmp = gen_reg_rtx (SImode);
4969       emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (16)));
4970       emit_insn (gen_lshrsi3 (operands[0], tmp, GEN_INT (16)));
4971       DONE;
4972     }
4975 (define_split
4976   [(set (match_operand:SI 0 "s_register_operand" "")
4977         (zero_extend:SI (match_operand:HI 1 "s_register_operand" "")))]
4978   "!TARGET_THUMB2 && !arm_arch6"
4979   [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
4980    (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 16)))]
4982   operands[2] = gen_lowpart (SImode, operands[1]);
4985 (define_insn "*arm_zero_extendhisi2"
4986   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4987         (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
4988   "TARGET_ARM && arm_arch4 && !arm_arch6"
4989   "@
4990    #
4991    ldrh%?\\t%0, %1"
4992   [(set_attr "type" "alu_shift_reg,load_byte")
4993    (set_attr "predicable" "yes")]
4996 (define_insn "*arm_zero_extendhisi2_v6"
4997   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4998         (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,Uh")))]
4999   "TARGET_ARM && arm_arch6"
5000   "@
5001    uxth%?\\t%0, %1
5002    ldrh%?\\t%0, %1"
5003   [(set_attr "predicable" "yes")
5004    (set_attr "type" "extend,load_byte")]
5007 (define_insn "*arm_zero_extendhisi2addsi"
5008   [(set (match_operand:SI 0 "s_register_operand" "=r")
5009         (plus:SI (zero_extend:SI (match_operand:HI 1 "s_register_operand" "r"))
5010                  (match_operand:SI 2 "s_register_operand" "r")))]
5011   "TARGET_INT_SIMD"
5012   "uxtah%?\\t%0, %2, %1"
5013   [(set_attr "type" "alu_shift_reg")
5014    (set_attr "predicable" "yes")
5015    (set_attr "predicable_short_it" "no")]
5018 (define_expand "zero_extendqisi2"
5019   [(set (match_operand:SI 0 "s_register_operand" "")
5020         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))]
5021   "TARGET_EITHER"
5023   if (TARGET_ARM && !arm_arch6 && !MEM_P (operands[1]))
5024     {
5025       emit_insn (gen_andsi3 (operands[0],
5026                              gen_lowpart (SImode, operands[1]),
5027                                           GEN_INT (255)));
5028       DONE;
5029     }
5030   if (!arm_arch6 && !MEM_P (operands[1]))
5031     {
5032       rtx t = gen_lowpart (SImode, operands[1]);
5033       rtx tmp = gen_reg_rtx (SImode);
5034       emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (24)));
5035       emit_insn (gen_lshrsi3 (operands[0], tmp, GEN_INT (24)));
5036       DONE;
5037     }
5040 (define_split
5041   [(set (match_operand:SI 0 "s_register_operand" "")
5042         (zero_extend:SI (match_operand:QI 1 "s_register_operand" "")))]
5043   "!arm_arch6"
5044   [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 24)))
5045    (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 24)))]
5047   operands[2] = simplify_gen_subreg (SImode, operands[1], QImode, 0);
5048   if (TARGET_ARM)
5049     {
5050       emit_insn (gen_andsi3 (operands[0], operands[2], GEN_INT (255)));
5051       DONE;
5052     }
5055 (define_insn "*arm_zero_extendqisi2"
5056   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5057         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
5058   "TARGET_ARM && !arm_arch6"
5059   "@
5060    #
5061    ldrb%?\\t%0, %1\\t%@ zero_extendqisi2"
5062   [(set_attr "length" "8,4")
5063    (set_attr "type" "alu_shift_reg,load_byte")
5064    (set_attr "predicable" "yes")]
5067 (define_insn "*arm_zero_extendqisi2_v6"
5068   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5069         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,Uh")))]
5070   "TARGET_ARM && arm_arch6"
5071   "@
5072    uxtb%?\\t%0, %1
5073    ldrb%?\\t%0, %1\\t%@ zero_extendqisi2"
5074   [(set_attr "type" "extend,load_byte")
5075    (set_attr "predicable" "yes")]
5078 (define_insn "*arm_zero_extendqisi2addsi"
5079   [(set (match_operand:SI 0 "s_register_operand" "=r")
5080         (plus:SI (zero_extend:SI (match_operand:QI 1 "s_register_operand" "r"))
5081                  (match_operand:SI 2 "s_register_operand" "r")))]
5082   "TARGET_INT_SIMD"
5083   "uxtab%?\\t%0, %2, %1"
5084   [(set_attr "predicable" "yes")
5085    (set_attr "predicable_short_it" "no")
5086    (set_attr "type" "alu_shift_reg")]
5089 (define_split
5090   [(set (match_operand:SI 0 "s_register_operand" "")
5091         (zero_extend:SI (subreg:QI (match_operand:SI 1 "" "") 0)))
5092    (clobber (match_operand:SI 2 "s_register_operand" ""))]
5093   "TARGET_32BIT && (!MEM_P (operands[1])) && ! BYTES_BIG_ENDIAN"
5094   [(set (match_dup 2) (match_dup 1))
5095    (set (match_dup 0) (and:SI (match_dup 2) (const_int 255)))]
5096   ""
5099 (define_split
5100   [(set (match_operand:SI 0 "s_register_operand" "")
5101         (zero_extend:SI (subreg:QI (match_operand:SI 1 "" "") 3)))
5102    (clobber (match_operand:SI 2 "s_register_operand" ""))]
5103   "TARGET_32BIT && (!MEM_P (operands[1])) && BYTES_BIG_ENDIAN"
5104   [(set (match_dup 2) (match_dup 1))
5105    (set (match_dup 0) (and:SI (match_dup 2) (const_int 255)))]
5106   ""
5110 (define_split
5111   [(set (match_operand:SI 0 "s_register_operand" "")
5112         (IOR_XOR:SI (and:SI (ashift:SI
5113                              (match_operand:SI 1 "s_register_operand" "")
5114                              (match_operand:SI 2 "const_int_operand" ""))
5115                             (match_operand:SI 3 "const_int_operand" ""))
5116                     (zero_extend:SI
5117                      (match_operator 5 "subreg_lowpart_operator"
5118                       [(match_operand:SI 4 "s_register_operand" "")]))))]
5119   "TARGET_32BIT
5120    && (UINTVAL (operands[3])
5121        == (GET_MODE_MASK (GET_MODE (operands[5]))
5122            & (GET_MODE_MASK (GET_MODE (operands[5]))
5123               << (INTVAL (operands[2])))))"
5124   [(set (match_dup 0) (IOR_XOR:SI (ashift:SI (match_dup 1) (match_dup 2))
5125                                   (match_dup 4)))
5126    (set (match_dup 0) (zero_extend:SI (match_dup 5)))]
5127   "operands[5] = gen_lowpart (GET_MODE (operands[5]), operands[0]);"
5130 (define_insn "*compareqi_eq0"
5131   [(set (reg:CC_Z CC_REGNUM)
5132         (compare:CC_Z (match_operand:QI 0 "s_register_operand" "r")
5133                          (const_int 0)))]
5134   "TARGET_32BIT"
5135   "tst%?\\t%0, #255"
5136   [(set_attr "conds" "set")
5137    (set_attr "predicable" "yes")
5138    (set_attr "predicable_short_it" "no")
5139    (set_attr "type" "logic_imm")]
5142 (define_expand "extendhisi2"
5143   [(set (match_operand:SI 0 "s_register_operand" "")
5144         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
5145   "TARGET_EITHER"
5147   if (TARGET_THUMB1)
5148     {
5149       emit_insn (gen_thumb1_extendhisi2 (operands[0], operands[1]));
5150       DONE;
5151     }
5152   if (MEM_P (operands[1]) && TARGET_ARM && !arm_arch4)
5153     {
5154       emit_insn (gen_extendhisi2_mem (operands[0], operands[1]));
5155       DONE;
5156     }
5158   if (!arm_arch6 && !MEM_P (operands[1]))
5159     {
5160       rtx t = gen_lowpart (SImode, operands[1]);
5161       rtx tmp = gen_reg_rtx (SImode);
5162       emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (16)));
5163       emit_insn (gen_ashrsi3 (operands[0], tmp, GEN_INT (16)));
5164       DONE;
5165     }
5168 (define_split
5169   [(parallel
5170     [(set (match_operand:SI 0 "register_operand" "")
5171           (sign_extend:SI (match_operand:HI 1 "register_operand" "")))
5172      (clobber (match_scratch:SI 2 ""))])]
5173   "!arm_arch6"
5174   [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
5175    (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
5177   operands[2] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
5180 ;; This pattern will only be used when ldsh is not available
5181 (define_expand "extendhisi2_mem"
5182   [(set (match_dup 2) (zero_extend:SI (match_operand:HI 1 "" "")))
5183    (set (match_dup 3)
5184         (zero_extend:SI (match_dup 7)))
5185    (set (match_dup 6) (ashift:SI (match_dup 4) (const_int 24)))
5186    (set (match_operand:SI 0 "" "")
5187         (ior:SI (ashiftrt:SI (match_dup 6) (const_int 16)) (match_dup 5)))]
5188   "TARGET_ARM"
5189   "
5190   {
5191     rtx mem1, mem2;
5192     rtx addr = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
5194     mem1 = change_address (operands[1], QImode, addr);
5195     mem2 = change_address (operands[1], QImode,
5196                            plus_constant (Pmode, addr, 1));
5197     operands[0] = gen_lowpart (SImode, operands[0]);
5198     operands[1] = mem1;
5199     operands[2] = gen_reg_rtx (SImode);
5200     operands[3] = gen_reg_rtx (SImode);
5201     operands[6] = gen_reg_rtx (SImode);
5202     operands[7] = mem2;
5204     if (BYTES_BIG_ENDIAN)
5205       {
5206         operands[4] = operands[2];
5207         operands[5] = operands[3];
5208       }
5209     else
5210       {
5211         operands[4] = operands[3];
5212         operands[5] = operands[2];
5213       }
5214   }"
5217 (define_split
5218   [(set (match_operand:SI 0 "register_operand" "")
5219         (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
5220   "!arm_arch6"
5221   [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
5222    (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
5224   operands[2] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
5227 (define_insn "*arm_extendhisi2"
5228   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5229         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,Uh")))]
5230   "TARGET_ARM && arm_arch4 && !arm_arch6"
5231   "@
5232    #
5233    ldrsh%?\\t%0, %1"
5234   [(set_attr "length" "8,4")
5235    (set_attr "type" "alu_shift_reg,load_byte")
5236    (set_attr "predicable" "yes")]
5239 ;; ??? Check Thumb-2 pool range
5240 (define_insn "*arm_extendhisi2_v6"
5241   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5242         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,Uh")))]
5243   "TARGET_32BIT && arm_arch6"
5244   "@
5245    sxth%?\\t%0, %1
5246    ldrsh%?\\t%0, %1"
5247   [(set_attr "type" "extend,load_byte")
5248    (set_attr "predicable" "yes")
5249    (set_attr "predicable_short_it" "no")]
5252 (define_insn "*arm_extendhisi2addsi"
5253   [(set (match_operand:SI 0 "s_register_operand" "=r")
5254         (plus:SI (sign_extend:SI (match_operand:HI 1 "s_register_operand" "r"))
5255                  (match_operand:SI 2 "s_register_operand" "r")))]
5256   "TARGET_INT_SIMD"
5257   "sxtah%?\\t%0, %2, %1"
5258   [(set_attr "type" "alu_shift_reg")]
5261 (define_expand "extendqihi2"
5262   [(set (match_dup 2)
5263         (ashift:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "")
5264                    (const_int 24)))
5265    (set (match_operand:HI 0 "s_register_operand" "")
5266         (ashiftrt:SI (match_dup 2)
5267                      (const_int 24)))]
5268   "TARGET_ARM"
5269   "
5270   {
5271     if (arm_arch4 && MEM_P (operands[1]))
5272       {
5273         emit_insn (gen_rtx_SET (operands[0],
5274                                 gen_rtx_SIGN_EXTEND (HImode, operands[1])));
5275         DONE;
5276       }
5277     if (!s_register_operand (operands[1], QImode))
5278       operands[1] = copy_to_mode_reg (QImode, operands[1]);
5279     operands[0] = gen_lowpart (SImode, operands[0]);
5280     operands[1] = gen_lowpart (SImode, operands[1]);
5281     operands[2] = gen_reg_rtx (SImode);
5282   }"
5285 (define_insn "*arm_extendqihi_insn"
5286   [(set (match_operand:HI 0 "s_register_operand" "=r")
5287         (sign_extend:HI (match_operand:QI 1 "arm_extendqisi_mem_op" "Uq")))]
5288   "TARGET_ARM && arm_arch4"
5289   "ldrsb%?\\t%0, %1"
5290   [(set_attr "type" "load_byte")
5291    (set_attr "predicable" "yes")]
5294 (define_expand "extendqisi2"
5295   [(set (match_operand:SI 0 "s_register_operand" "")
5296         (sign_extend:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "")))]
5297   "TARGET_EITHER"
5299   if (!arm_arch4 && MEM_P (operands[1]))
5300     operands[1] = copy_to_mode_reg (QImode, operands[1]);
5302   if (!arm_arch6 && !MEM_P (operands[1]))
5303     {
5304       rtx t = gen_lowpart (SImode, operands[1]);
5305       rtx tmp = gen_reg_rtx (SImode);
5306       emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (24)));
5307       emit_insn (gen_ashrsi3 (operands[0], tmp, GEN_INT (24)));
5308       DONE;
5309     }
5312 (define_split
5313   [(set (match_operand:SI 0 "register_operand" "")
5314         (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
5315   "!arm_arch6"
5316   [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 24)))
5317    (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 24)))]
5319   operands[2] = simplify_gen_subreg (SImode, operands[1], QImode, 0);
5322 (define_insn "*arm_extendqisi"
5323   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5324         (sign_extend:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "r,Uq")))]
5325   "TARGET_ARM && arm_arch4 && !arm_arch6"
5326   "@
5327    #
5328    ldrsb%?\\t%0, %1"
5329   [(set_attr "length" "8,4")
5330    (set_attr "type" "alu_shift_reg,load_byte")
5331    (set_attr "predicable" "yes")]
5334 (define_insn "*arm_extendqisi_v6"
5335   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5336         (sign_extend:SI
5337          (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "r,Uq")))]
5338   "TARGET_ARM && arm_arch6"
5339   "@
5340    sxtb%?\\t%0, %1
5341    ldrsb%?\\t%0, %1"
5342   [(set_attr "type" "extend,load_byte")
5343    (set_attr "predicable" "yes")]
5346 (define_insn "*arm_extendqisi2addsi"
5347   [(set (match_operand:SI 0 "s_register_operand" "=r")
5348         (plus:SI (sign_extend:SI (match_operand:QI 1 "s_register_operand" "r"))
5349                  (match_operand:SI 2 "s_register_operand" "r")))]
5350   "TARGET_INT_SIMD"
5351   "sxtab%?\\t%0, %2, %1"
5352   [(set_attr "type" "alu_shift_reg")
5353    (set_attr "predicable" "yes")
5354    (set_attr "predicable_short_it" "no")]
5357 (define_expand "extendsfdf2"
5358   [(set (match_operand:DF                  0 "s_register_operand" "")
5359         (float_extend:DF (match_operand:SF 1 "s_register_operand"  "")))]
5360   "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
5361   ""
5364 /* HFmode -> DFmode conversions have to go through SFmode.  */
5365 (define_expand "extendhfdf2"
5366   [(set (match_operand:DF                  0 "general_operand" "")
5367         (float_extend:DF (match_operand:HF 1 "general_operand"  "")))]
5368   "TARGET_EITHER"
5369   "
5370   {
5371     rtx op1;
5372     op1 = convert_to_mode (SFmode, operands[1], 0);
5373     op1 = convert_to_mode (DFmode, op1, 0);
5374     emit_insn (gen_movdf (operands[0], op1));
5375     DONE;
5376   }"
5379 ;; Move insns (including loads and stores)
5381 ;; XXX Just some ideas about movti.
5382 ;; I don't think these are a good idea on the arm, there just aren't enough
5383 ;; registers
5384 ;;(define_expand "loadti"
5385 ;;  [(set (match_operand:TI 0 "s_register_operand" "")
5386 ;;      (mem:TI (match_operand:SI 1 "address_operand" "")))]
5387 ;;  "" "")
5389 ;;(define_expand "storeti"
5390 ;;  [(set (mem:TI (match_operand:TI 0 "address_operand" ""))
5391 ;;      (match_operand:TI 1 "s_register_operand" ""))]
5392 ;;  "" "")
5394 ;;(define_expand "movti"
5395 ;;  [(set (match_operand:TI 0 "general_operand" "")
5396 ;;      (match_operand:TI 1 "general_operand" ""))]
5397 ;;  ""
5398 ;;  "
5400 ;;  rtx insn;
5402 ;;  if (MEM_P (operands[0]) && MEM_P (operands[1]))
5403 ;;    operands[1] = copy_to_reg (operands[1]);
5404 ;;  if (MEM_P (operands[0]))
5405 ;;    insn = gen_storeti (XEXP (operands[0], 0), operands[1]);
5406 ;;  else if (MEM_P (operands[1]))
5407 ;;    insn = gen_loadti (operands[0], XEXP (operands[1], 0));
5408 ;;  else
5409 ;;    FAIL;
5411 ;;  emit_insn (insn);
5412 ;;  DONE;
5413 ;;}")
5415 ;; Recognize garbage generated above.
5417 ;;(define_insn ""
5418 ;;  [(set (match_operand:TI 0 "general_operand" "=r,r,r,<,>,m")
5419 ;;      (match_operand:TI 1 "general_operand" "<,>,m,r,r,r"))]
5420 ;;  ""
5421 ;;  "*
5422 ;;  {
5423 ;;    register mem = (which_alternative < 3);
5424 ;;    register const char *template;
5426 ;;    operands[mem] = XEXP (operands[mem], 0);
5427 ;;    switch (which_alternative)
5428 ;;      {
5429 ;;      case 0: template = \"ldmdb\\t%1!, %M0\"; break;
5430 ;;      case 1: template = \"ldmia\\t%1!, %M0\"; break;
5431 ;;      case 2: template = \"ldmia\\t%1, %M0\"; break;
5432 ;;      case 3: template = \"stmdb\\t%0!, %M1\"; break;
5433 ;;      case 4: template = \"stmia\\t%0!, %M1\"; break;
5434 ;;      case 5: template = \"stmia\\t%0, %M1\"; break;
5435 ;;      }
5436 ;;    output_asm_insn (template, operands);
5437 ;;    return \"\";
5438 ;;  }")
5440 (define_expand "movdi"
5441   [(set (match_operand:DI 0 "general_operand" "")
5442         (match_operand:DI 1 "general_operand" ""))]
5443   "TARGET_EITHER"
5444   "
5445   if (can_create_pseudo_p ())
5446     {
5447       if (!REG_P (operands[0]))
5448         operands[1] = force_reg (DImode, operands[1]);
5449     }
5450   if (REG_P (operands[0]) && REGNO (operands[0]) <= LAST_ARM_REGNUM
5451       && !HARD_REGNO_MODE_OK (REGNO (operands[0]), DImode))
5452     {
5453       /* Avoid LDRD's into an odd-numbered register pair in ARM state
5454          when expanding function calls.  */
5455       gcc_assert (can_create_pseudo_p ());
5456       if (MEM_P (operands[1]) && MEM_VOLATILE_P (operands[1]))
5457         {
5458           /* Perform load into legal reg pair first, then move.  */
5459           rtx reg = gen_reg_rtx (DImode);
5460           emit_insn (gen_movdi (reg, operands[1]));
5461           operands[1] = reg;
5462         }
5463       emit_move_insn (gen_lowpart (SImode, operands[0]),
5464                       gen_lowpart (SImode, operands[1]));
5465       emit_move_insn (gen_highpart (SImode, operands[0]),
5466                       gen_highpart (SImode, operands[1]));
5467       DONE;
5468     }
5469   else if (REG_P (operands[1]) && REGNO (operands[1]) <= LAST_ARM_REGNUM
5470            && !HARD_REGNO_MODE_OK (REGNO (operands[1]), DImode))
5471     {
5472       /* Avoid STRD's from an odd-numbered register pair in ARM state
5473          when expanding function prologue.  */
5474       gcc_assert (can_create_pseudo_p ());
5475       rtx split_dest = (MEM_P (operands[0]) && MEM_VOLATILE_P (operands[0]))
5476                        ? gen_reg_rtx (DImode)
5477                        : operands[0];
5478       emit_move_insn (gen_lowpart (SImode, split_dest),
5479                       gen_lowpart (SImode, operands[1]));
5480       emit_move_insn (gen_highpart (SImode, split_dest),
5481                       gen_highpart (SImode, operands[1]));
5482       if (split_dest != operands[0])
5483         emit_insn (gen_movdi (operands[0], split_dest));
5484       DONE;
5485     }
5486   "
5489 (define_insn "*arm_movdi"
5490   [(set (match_operand:DI 0 "nonimmediate_di_operand" "=r, r, r, q, m")
5491         (match_operand:DI 1 "di_operand"              "rDa,Db,Dc,mi,q"))]
5492   "TARGET_32BIT
5493    && !(TARGET_HARD_FLOAT && TARGET_VFP)
5494    && !TARGET_IWMMXT
5495    && (   register_operand (operands[0], DImode)
5496        || register_operand (operands[1], DImode))"
5497   "*
5498   switch (which_alternative)
5499     {
5500     case 0:
5501     case 1:
5502     case 2:
5503       return \"#\";
5504     default:
5505       return output_move_double (operands, true, NULL);
5506     }
5507   "
5508   [(set_attr "length" "8,12,16,8,8")
5509    (set_attr "type" "multiple,multiple,multiple,load2,store2")
5510    (set_attr "arm_pool_range" "*,*,*,1020,*")
5511    (set_attr "arm_neg_pool_range" "*,*,*,1004,*")
5512    (set_attr "thumb2_pool_range" "*,*,*,4094,*")
5513    (set_attr "thumb2_neg_pool_range" "*,*,*,0,*")]
5516 (define_split
5517   [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
5518         (match_operand:ANY64 1 "immediate_operand" ""))]
5519   "TARGET_32BIT
5520    && reload_completed
5521    && (arm_const_double_inline_cost (operands[1])
5522        <= arm_max_const_double_inline_cost ())"
5523   [(const_int 0)]
5524   "
5525   arm_split_constant (SET, SImode, curr_insn,
5526                       INTVAL (gen_lowpart (SImode, operands[1])),
5527                       gen_lowpart (SImode, operands[0]), NULL_RTX, 0);
5528   arm_split_constant (SET, SImode, curr_insn,
5529                       INTVAL (gen_highpart_mode (SImode,
5530                                                  GET_MODE (operands[0]),
5531                                                  operands[1])),
5532                       gen_highpart (SImode, operands[0]), NULL_RTX, 0);
5533   DONE;
5534   "
5537 ; If optimizing for size, or if we have load delay slots, then 
5538 ; we want to split the constant into two separate operations. 
5539 ; In both cases this may split a trivial part into a single data op
5540 ; leaving a single complex constant to load.  We can also get longer
5541 ; offsets in a LDR which means we get better chances of sharing the pool
5542 ; entries.  Finally, we can normally do a better job of scheduling
5543 ; LDR instructions than we can with LDM.
5544 ; This pattern will only match if the one above did not.
5545 (define_split
5546   [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
5547         (match_operand:ANY64 1 "const_double_operand" ""))]
5548   "TARGET_ARM && reload_completed
5549    && arm_const_double_by_parts (operands[1])"
5550   [(set (match_dup 0) (match_dup 1))
5551    (set (match_dup 2) (match_dup 3))]
5552   "
5553   operands[2] = gen_highpart (SImode, operands[0]);
5554   operands[3] = gen_highpart_mode (SImode, GET_MODE (operands[0]),
5555                                    operands[1]);
5556   operands[0] = gen_lowpart (SImode, operands[0]);
5557   operands[1] = gen_lowpart (SImode, operands[1]);
5558   "
5561 (define_split
5562   [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
5563         (match_operand:ANY64 1 "arm_general_register_operand" ""))]
5564   "TARGET_EITHER && reload_completed"
5565   [(set (match_dup 0) (match_dup 1))
5566    (set (match_dup 2) (match_dup 3))]
5567   "
5568   operands[2] = gen_highpart (SImode, operands[0]);
5569   operands[3] = gen_highpart (SImode, operands[1]);
5570   operands[0] = gen_lowpart (SImode, operands[0]);
5571   operands[1] = gen_lowpart (SImode, operands[1]);
5573   /* Handle a partial overlap.  */
5574   if (rtx_equal_p (operands[0], operands[3]))
5575     {
5576       rtx tmp0 = operands[0];
5577       rtx tmp1 = operands[1];
5579       operands[0] = operands[2];
5580       operands[1] = operands[3];
5581       operands[2] = tmp0;
5582       operands[3] = tmp1;
5583     }
5584   "
5587 ;; We can't actually do base+index doubleword loads if the index and
5588 ;; destination overlap.  Split here so that we at least have chance to
5589 ;; schedule.
5590 (define_split
5591   [(set (match_operand:DI 0 "s_register_operand" "")
5592         (mem:DI (plus:SI (match_operand:SI 1 "s_register_operand" "")
5593                          (match_operand:SI 2 "s_register_operand" ""))))]
5594   "TARGET_LDRD
5595   && reg_overlap_mentioned_p (operands[0], operands[1])
5596   && reg_overlap_mentioned_p (operands[0], operands[2])"
5597   [(set (match_dup 4)
5598         (plus:SI (match_dup 1)
5599                  (match_dup 2)))
5600    (set (match_dup 0)
5601         (mem:DI (match_dup 4)))]
5602   "
5603   operands[4] = gen_rtx_REG (SImode, REGNO(operands[0]));
5604   "
5607 (define_expand "movsi"
5608   [(set (match_operand:SI 0 "general_operand" "")
5609         (match_operand:SI 1 "general_operand" ""))]
5610   "TARGET_EITHER"
5611   "
5612   {
5613   rtx base, offset, tmp;
5615   if (TARGET_32BIT)
5616     {
5617       /* Everything except mem = const or mem = mem can be done easily.  */
5618       if (MEM_P (operands[0]))
5619         operands[1] = force_reg (SImode, operands[1]);
5620       if (arm_general_register_operand (operands[0], SImode)
5621           && CONST_INT_P (operands[1])
5622           && !(const_ok_for_arm (INTVAL (operands[1]))
5623                || const_ok_for_arm (~INTVAL (operands[1]))))
5624         {
5625            if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[1]), SET))
5626              {
5627                 emit_insn (gen_rtx_SET (operands[0], operands[1]));
5628                 DONE;
5629              }
5630           else
5631              {
5632                 arm_split_constant (SET, SImode, NULL_RTX,
5633                                     INTVAL (operands[1]), operands[0], NULL_RTX,
5634                                     optimize && can_create_pseudo_p ());
5635                 DONE;
5636              }
5637         }
5638     }
5639   else /* TARGET_THUMB1...  */
5640     {
5641       if (can_create_pseudo_p ())
5642         {
5643           if (!REG_P (operands[0]))
5644             operands[1] = force_reg (SImode, operands[1]);
5645         }
5646     }
5648   if (ARM_OFFSETS_MUST_BE_WITHIN_SECTIONS_P)
5649     {
5650       split_const (operands[1], &base, &offset);
5651       if (GET_CODE (base) == SYMBOL_REF
5652           && !offset_within_block_p (base, INTVAL (offset)))
5653         {
5654           tmp = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];
5655           emit_move_insn (tmp, base);
5656           emit_insn (gen_addsi3 (operands[0], tmp, offset));
5657           DONE;
5658         }
5659     }
5661   /* Recognize the case where operand[1] is a reference to thread-local
5662      data and load its address to a register.  */
5663   if (arm_tls_referenced_p (operands[1]))
5664     {
5665       rtx tmp = operands[1];
5666       rtx addend = NULL;
5668       if (GET_CODE (tmp) == CONST && GET_CODE (XEXP (tmp, 0)) == PLUS)
5669         {
5670           addend = XEXP (XEXP (tmp, 0), 1);
5671           tmp = XEXP (XEXP (tmp, 0), 0);
5672         }
5674       gcc_assert (GET_CODE (tmp) == SYMBOL_REF);
5675       gcc_assert (SYMBOL_REF_TLS_MODEL (tmp) != 0);
5677       tmp = legitimize_tls_address (tmp,
5678                                     !can_create_pseudo_p () ? operands[0] : 0);
5679       if (addend)
5680         {
5681           tmp = gen_rtx_PLUS (SImode, tmp, addend);
5682           tmp = force_operand (tmp, operands[0]);
5683         }
5684       operands[1] = tmp;
5685     }
5686   else if (flag_pic
5687            && (CONSTANT_P (operands[1])
5688                || symbol_mentioned_p (operands[1])
5689                || label_mentioned_p (operands[1])))
5690       operands[1] = legitimize_pic_address (operands[1], SImode,
5691                                             (!can_create_pseudo_p ()
5692                                              ? operands[0]
5693                                              : 0));
5694   }
5695   "
5698 ;; The ARM LO_SUM and HIGH are backwards - HIGH sets the low bits, and
5699 ;; LO_SUM adds in the high bits.  Fortunately these are opaque operations
5700 ;; so this does not matter.
5701 (define_insn "*arm_movt"
5702   [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
5703         (lo_sum:SI (match_operand:SI 1 "nonimmediate_operand" "0")
5704                    (match_operand:SI 2 "general_operand"      "i")))]
5705   "TARGET_HAVE_MOVT && arm_valid_symbolic_address_p (operands[2])"
5706   "movt%?\t%0, #:upper16:%c2"
5707   [(set_attr "predicable" "yes")
5708    (set_attr "predicable_short_it" "no")
5709    (set_attr "length" "4")
5710    (set_attr "type" "alu_sreg")]
5713 (define_insn "*arm_movsi_insn"
5714   [(set (match_operand:SI 0 "nonimmediate_operand" "=rk,r,r,r,rk,m")
5715         (match_operand:SI 1 "general_operand"      "rk, I,K,j,mi,rk"))]
5716   "TARGET_ARM && ! TARGET_IWMMXT
5717    && !(TARGET_HARD_FLOAT && TARGET_VFP)
5718    && (   register_operand (operands[0], SImode)
5719        || register_operand (operands[1], SImode))"
5720   "@
5721    mov%?\\t%0, %1
5722    mov%?\\t%0, %1
5723    mvn%?\\t%0, #%B1
5724    movw%?\\t%0, %1
5725    ldr%?\\t%0, %1
5726    str%?\\t%1, %0"
5727   [(set_attr "type" "mov_reg,mov_imm,mvn_imm,mov_imm,load1,store1")
5728    (set_attr "predicable" "yes")
5729    (set_attr "pool_range" "*,*,*,*,4096,*")
5730    (set_attr "neg_pool_range" "*,*,*,*,4084,*")]
5733 (define_split
5734   [(set (match_operand:SI 0 "arm_general_register_operand" "")
5735         (match_operand:SI 1 "const_int_operand" ""))]
5736   "TARGET_32BIT
5737   && (!(const_ok_for_arm (INTVAL (operands[1]))
5738         || const_ok_for_arm (~INTVAL (operands[1]))))"
5739   [(clobber (const_int 0))]
5740   "
5741   arm_split_constant (SET, SImode, NULL_RTX, 
5742                       INTVAL (operands[1]), operands[0], NULL_RTX, 0);
5743   DONE;
5744   "
5747 ;; A normal way to do (symbol + offset) requires three instructions at least
5748 ;; (depends on how big the offset is) as below:
5749 ;; movw r0, #:lower16:g
5750 ;; movw r0, #:upper16:g
5751 ;; adds r0, #4
5753 ;; A better way would be:
5754 ;; movw r0, #:lower16:g+4
5755 ;; movw r0, #:upper16:g+4
5757 ;; The limitation of this way is that the length of offset should be a 16-bit
5758 ;; signed value, because current assembler only supports REL type relocation for
5759 ;; such case.  If the more powerful RELA type is supported in future, we should
5760 ;; update this pattern to go with better way.
5761 (define_split
5762   [(set (match_operand:SI 0 "arm_general_register_operand" "")
5763         (const:SI (plus:SI (match_operand:SI 1 "general_operand" "")
5764                            (match_operand:SI 2 "const_int_operand" ""))))]
5765   "TARGET_THUMB
5766    && TARGET_HAVE_MOVT
5767    && arm_disable_literal_pool
5768    && reload_completed
5769    && GET_CODE (operands[1]) == SYMBOL_REF"
5770   [(clobber (const_int 0))]
5771   "
5772     int offset = INTVAL (operands[2]);
5774     if (offset < -0x8000 || offset > 0x7fff)
5775       {
5776         arm_emit_movpair (operands[0], operands[1]);
5777         emit_insn (gen_rtx_SET (operands[0],
5778                                 gen_rtx_PLUS (SImode, operands[0], operands[2])));
5779       }
5780     else
5781       {
5782         rtx op = gen_rtx_CONST (SImode,
5783                                 gen_rtx_PLUS (SImode, operands[1], operands[2]));
5784         arm_emit_movpair (operands[0], op);
5785       }
5786   "
5789 ;; Split symbol_refs at the later stage (after cprop), instead of generating
5790 ;; movt/movw pair directly at expand.  Otherwise corresponding high_sum
5791 ;; and lo_sum would be merged back into memory load at cprop.  However,
5792 ;; if the default is to prefer movt/movw rather than a load from the constant
5793 ;; pool, the performance is better.
5794 (define_split
5795   [(set (match_operand:SI 0 "arm_general_register_operand" "")
5796        (match_operand:SI 1 "general_operand" ""))]
5797   "TARGET_USE_MOVT && GET_CODE (operands[1]) == SYMBOL_REF
5798    && !flag_pic && !target_word_relocations
5799    && !arm_tls_referenced_p (operands[1])"
5800   [(clobber (const_int 0))]
5802   arm_emit_movpair (operands[0], operands[1]);
5803   DONE;
5806 ;; When generating pic, we need to load the symbol offset into a register.
5807 ;; So that the optimizer does not confuse this with a normal symbol load
5808 ;; we use an unspec.  The offset will be loaded from a constant pool entry,
5809 ;; since that is the only type of relocation we can use.
5811 ;; Wrap calculation of the whole PIC address in a single pattern for the
5812 ;; benefit of optimizers, particularly, PRE and HOIST.  Calculation of
5813 ;; a PIC address involves two loads from memory, so we want to CSE it
5814 ;; as often as possible.
5815 ;; This pattern will be split into one of the pic_load_addr_* patterns
5816 ;; and a move after GCSE optimizations.
5818 ;; Note: Update arm.c: legitimize_pic_address() when changing this pattern.
5819 (define_expand "calculate_pic_address"
5820   [(set (match_operand:SI 0 "register_operand" "")
5821         (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "")
5822                          (unspec:SI [(match_operand:SI 2 "" "")]
5823                                     UNSPEC_PIC_SYM))))]
5824   "flag_pic"
5827 ;; Split calculate_pic_address into pic_load_addr_* and a move.
5828 (define_split
5829   [(set (match_operand:SI 0 "register_operand" "")
5830         (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "")
5831                          (unspec:SI [(match_operand:SI 2 "" "")]
5832                                     UNSPEC_PIC_SYM))))]
5833   "flag_pic"
5834   [(set (match_dup 3) (unspec:SI [(match_dup 2)] UNSPEC_PIC_SYM))
5835    (set (match_dup 0) (mem:SI (plus:SI (match_dup 1) (match_dup 3))))]
5836   "operands[3] = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];"
5839 ;; operand1 is the memory address to go into 
5840 ;; pic_load_addr_32bit.
5841 ;; operand2 is the PIC label to be emitted 
5842 ;; from pic_add_dot_plus_eight.
5843 ;; We do this to allow hoisting of the entire insn.
5844 (define_insn_and_split "pic_load_addr_unified"
5845   [(set (match_operand:SI 0 "s_register_operand" "=r,r,l")
5846         (unspec:SI [(match_operand:SI 1 "" "mX,mX,mX") 
5847                     (match_operand:SI 2 "" "")] 
5848                     UNSPEC_PIC_UNIFIED))]
5849  "flag_pic"
5850  "#"
5851  "&& reload_completed"
5852  [(set (match_dup 0) (unspec:SI [(match_dup 1)] UNSPEC_PIC_SYM))
5853   (set (match_dup 0) (unspec:SI [(match_dup 0) (match_dup 3)
5854                                  (match_dup 2)] UNSPEC_PIC_BASE))]
5855  "operands[3] = TARGET_THUMB ? GEN_INT (4) : GEN_INT (8);"
5856  [(set_attr "type" "load1,load1,load1")
5857   (set_attr "pool_range" "4096,4094,1022")
5858   (set_attr "neg_pool_range" "4084,0,0")
5859   (set_attr "arch"  "a,t2,t1")    
5860   (set_attr "length" "8,6,4")]
5863 ;; The rather odd constraints on the following are to force reload to leave
5864 ;; the insn alone, and to force the minipool generation pass to then move
5865 ;; the GOT symbol to memory.
5867 (define_insn "pic_load_addr_32bit"
5868   [(set (match_operand:SI 0 "s_register_operand" "=r")
5869         (unspec:SI [(match_operand:SI 1 "" "mX")] UNSPEC_PIC_SYM))]
5870   "TARGET_32BIT && flag_pic"
5871   "ldr%?\\t%0, %1"
5872   [(set_attr "type" "load1")
5873    (set (attr "pool_range")
5874         (if_then_else (eq_attr "is_thumb" "no")
5875                       (const_int 4096)
5876                       (const_int 4094)))
5877    (set (attr "neg_pool_range")
5878         (if_then_else (eq_attr "is_thumb" "no")
5879                       (const_int 4084)
5880                       (const_int 0)))]
5883 (define_insn "pic_load_addr_thumb1"
5884   [(set (match_operand:SI 0 "s_register_operand" "=l")
5885         (unspec:SI [(match_operand:SI 1 "" "mX")] UNSPEC_PIC_SYM))]
5886   "TARGET_THUMB1 && flag_pic"
5887   "ldr\\t%0, %1"
5888   [(set_attr "type" "load1")
5889    (set (attr "pool_range") (const_int 1018))]
5892 (define_insn "pic_add_dot_plus_four"
5893   [(set (match_operand:SI 0 "register_operand" "=r")
5894         (unspec:SI [(match_operand:SI 1 "register_operand" "0")
5895                     (const_int 4)
5896                     (match_operand 2 "" "")]
5897                    UNSPEC_PIC_BASE))]
5898   "TARGET_THUMB"
5899   "*
5900   (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
5901                                      INTVAL (operands[2]));
5902   return \"add\\t%0, %|pc\";
5903   "
5904   [(set_attr "length" "2")
5905    (set_attr "type" "alu_sreg")]
5908 (define_insn "pic_add_dot_plus_eight"
5909   [(set (match_operand:SI 0 "register_operand" "=r")
5910         (unspec:SI [(match_operand:SI 1 "register_operand" "r")
5911                     (const_int 8)
5912                     (match_operand 2 "" "")]
5913                    UNSPEC_PIC_BASE))]
5914   "TARGET_ARM"
5915   "*
5916     (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
5917                                        INTVAL (operands[2]));
5918     return \"add%?\\t%0, %|pc, %1\";
5919   "
5920   [(set_attr "predicable" "yes")
5921    (set_attr "type" "alu_sreg")]
5924 (define_insn "tls_load_dot_plus_eight"
5925   [(set (match_operand:SI 0 "register_operand" "=r")
5926         (mem:SI (unspec:SI [(match_operand:SI 1 "register_operand" "r")
5927                             (const_int 8)
5928                             (match_operand 2 "" "")]
5929                            UNSPEC_PIC_BASE)))]
5930   "TARGET_ARM"
5931   "*
5932     (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
5933                                        INTVAL (operands[2]));
5934     return \"ldr%?\\t%0, [%|pc, %1]\t\t@ tls_load_dot_plus_eight\";
5935   "
5936   [(set_attr "predicable" "yes")
5937    (set_attr "type" "load1")]
5940 ;; PIC references to local variables can generate pic_add_dot_plus_eight
5941 ;; followed by a load.  These sequences can be crunched down to
5942 ;; tls_load_dot_plus_eight by a peephole.
5944 (define_peephole2
5945   [(set (match_operand:SI 0 "register_operand" "")
5946         (unspec:SI [(match_operand:SI 3 "register_operand" "")
5947                     (const_int 8)
5948                     (match_operand 1 "" "")]
5949                    UNSPEC_PIC_BASE))
5950    (set (match_operand:SI 2 "arm_general_register_operand" "")
5951         (mem:SI (match_dup 0)))]
5952   "TARGET_ARM && peep2_reg_dead_p (2, operands[0])"
5953   [(set (match_dup 2)
5954         (mem:SI (unspec:SI [(match_dup 3)
5955                             (const_int 8)
5956                             (match_dup 1)]
5957                            UNSPEC_PIC_BASE)))]
5958   ""
5961 (define_insn "pic_offset_arm"
5962   [(set (match_operand:SI 0 "register_operand" "=r")
5963         (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
5964                          (unspec:SI [(match_operand:SI 2 "" "X")]
5965                                     UNSPEC_PIC_OFFSET))))]
5966   "TARGET_VXWORKS_RTP && TARGET_ARM && flag_pic"
5967   "ldr%?\\t%0, [%1,%2]"
5968   [(set_attr "type" "load1")]
5971 (define_expand "builtin_setjmp_receiver"
5972   [(label_ref (match_operand 0 "" ""))]
5973   "flag_pic"
5974   "
5976   /* r3 is clobbered by set/longjmp, so we can use it as a scratch
5977      register.  */
5978   if (arm_pic_register != INVALID_REGNUM)
5979     arm_load_pic_register (1UL << 3);
5980   DONE;
5983 ;; If copying one reg to another we can set the condition codes according to
5984 ;; its value.  Such a move is common after a return from subroutine and the
5985 ;; result is being tested against zero.
5987 (define_insn "*movsi_compare0"
5988   [(set (reg:CC CC_REGNUM)
5989         (compare:CC (match_operand:SI 1 "s_register_operand" "0,r")
5990                     (const_int 0)))
5991    (set (match_operand:SI 0 "s_register_operand" "=r,r")
5992         (match_dup 1))]
5993   "TARGET_32BIT"
5994   "@
5995    cmp%?\\t%0, #0
5996    subs%?\\t%0, %1, #0"
5997   [(set_attr "conds" "set")
5998    (set_attr "type" "alus_imm,alus_imm")]
6001 ;; Subroutine to store a half word from a register into memory.
6002 ;; Operand 0 is the source register (HImode)
6003 ;; Operand 1 is the destination address in a register (SImode)
6005 ;; In both this routine and the next, we must be careful not to spill
6006 ;; a memory address of reg+large_const into a separate PLUS insn, since this
6007 ;; can generate unrecognizable rtl.
6009 (define_expand "storehi"
6010   [;; store the low byte
6011    (set (match_operand 1 "" "") (match_dup 3))
6012    ;; extract the high byte
6013    (set (match_dup 2)
6014         (ashiftrt:SI (match_operand 0 "" "") (const_int 8)))
6015    ;; store the high byte
6016    (set (match_dup 4) (match_dup 5))]
6017   "TARGET_ARM"
6018   "
6019   {
6020     rtx op1 = operands[1];
6021     rtx addr = XEXP (op1, 0);
6022     enum rtx_code code = GET_CODE (addr);
6024     if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1)))
6025         || code == MINUS)
6026       op1 = replace_equiv_address (operands[1], force_reg (SImode, addr));
6028     operands[4] = adjust_address (op1, QImode, 1);
6029     operands[1] = adjust_address (operands[1], QImode, 0);
6030     operands[3] = gen_lowpart (QImode, operands[0]);
6031     operands[0] = gen_lowpart (SImode, operands[0]);
6032     operands[2] = gen_reg_rtx (SImode);
6033     operands[5] = gen_lowpart (QImode, operands[2]);
6034   }"
6037 (define_expand "storehi_bigend"
6038   [(set (match_dup 4) (match_dup 3))
6039    (set (match_dup 2)
6040         (ashiftrt:SI (match_operand 0 "" "") (const_int 8)))
6041    (set (match_operand 1 "" "") (match_dup 5))]
6042   "TARGET_ARM"
6043   "
6044   {
6045     rtx op1 = operands[1];
6046     rtx addr = XEXP (op1, 0);
6047     enum rtx_code code = GET_CODE (addr);
6049     if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1)))
6050         || code == MINUS)
6051       op1 = replace_equiv_address (op1, force_reg (SImode, addr));
6053     operands[4] = adjust_address (op1, QImode, 1);
6054     operands[1] = adjust_address (operands[1], QImode, 0);
6055     operands[3] = gen_lowpart (QImode, operands[0]);
6056     operands[0] = gen_lowpart (SImode, operands[0]);
6057     operands[2] = gen_reg_rtx (SImode);
6058     operands[5] = gen_lowpart (QImode, operands[2]);
6059   }"
6062 ;; Subroutine to store a half word integer constant into memory.
6063 (define_expand "storeinthi"
6064   [(set (match_operand 0 "" "")
6065         (match_operand 1 "" ""))
6066    (set (match_dup 3) (match_dup 2))]
6067   "TARGET_ARM"
6068   "
6069   {
6070     HOST_WIDE_INT value = INTVAL (operands[1]);
6071     rtx addr = XEXP (operands[0], 0);
6072     rtx op0 = operands[0];
6073     enum rtx_code code = GET_CODE (addr);
6075     if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1)))
6076         || code == MINUS)
6077       op0 = replace_equiv_address (op0, force_reg (SImode, addr));
6079     operands[1] = gen_reg_rtx (SImode);
6080     if (BYTES_BIG_ENDIAN)
6081       {
6082         emit_insn (gen_movsi (operands[1], GEN_INT ((value >> 8) & 255)));
6083         if ((value & 255) == ((value >> 8) & 255))
6084           operands[2] = operands[1];
6085         else
6086           {
6087             operands[2] = gen_reg_rtx (SImode);
6088             emit_insn (gen_movsi (operands[2], GEN_INT (value & 255)));
6089           }
6090       }
6091     else
6092       {
6093         emit_insn (gen_movsi (operands[1], GEN_INT (value & 255)));
6094         if ((value & 255) == ((value >> 8) & 255))
6095           operands[2] = operands[1];
6096         else
6097           {
6098             operands[2] = gen_reg_rtx (SImode);
6099             emit_insn (gen_movsi (operands[2], GEN_INT ((value >> 8) & 255)));
6100           }
6101       }
6103     operands[3] = adjust_address (op0, QImode, 1);
6104     operands[0] = adjust_address (operands[0], QImode, 0);
6105     operands[2] = gen_lowpart (QImode, operands[2]);
6106     operands[1] = gen_lowpart (QImode, operands[1]);
6107   }"
6110 (define_expand "storehi_single_op"
6111   [(set (match_operand:HI 0 "memory_operand" "")
6112         (match_operand:HI 1 "general_operand" ""))]
6113   "TARGET_32BIT && arm_arch4"
6114   "
6115   if (!s_register_operand (operands[1], HImode))
6116     operands[1] = copy_to_mode_reg (HImode, operands[1]);
6117   "
6120 (define_expand "movhi"
6121   [(set (match_operand:HI 0 "general_operand" "")
6122         (match_operand:HI 1 "general_operand" ""))]
6123   "TARGET_EITHER"
6124   "
6125   if (TARGET_ARM)
6126     {
6127       if (can_create_pseudo_p ())
6128         {
6129           if (MEM_P (operands[0]))
6130             {
6131               if (arm_arch4)
6132                 {
6133                   emit_insn (gen_storehi_single_op (operands[0], operands[1]));
6134                   DONE;
6135                 }
6136               if (CONST_INT_P (operands[1]))
6137                 emit_insn (gen_storeinthi (operands[0], operands[1]));
6138               else
6139                 {
6140                   if (MEM_P (operands[1]))
6141                     operands[1] = force_reg (HImode, operands[1]);
6142                   if (BYTES_BIG_ENDIAN)
6143                     emit_insn (gen_storehi_bigend (operands[1], operands[0]));
6144                   else
6145                    emit_insn (gen_storehi (operands[1], operands[0]));
6146                 }
6147               DONE;
6148             }
6149           /* Sign extend a constant, and keep it in an SImode reg.  */
6150           else if (CONST_INT_P (operands[1]))
6151             {
6152               rtx reg = gen_reg_rtx (SImode);
6153               HOST_WIDE_INT val = INTVAL (operands[1]) & 0xffff;
6155               /* If the constant is already valid, leave it alone.  */
6156               if (!const_ok_for_arm (val))
6157                 {
6158                   /* If setting all the top bits will make the constant 
6159                      loadable in a single instruction, then set them.  
6160                      Otherwise, sign extend the number.  */
6162                   if (const_ok_for_arm (~(val | ~0xffff)))
6163                     val |= ~0xffff;
6164                   else if (val & 0x8000)
6165                     val |= ~0xffff;
6166                 }
6168               emit_insn (gen_movsi (reg, GEN_INT (val)));
6169               operands[1] = gen_lowpart (HImode, reg);
6170             }
6171           else if (arm_arch4 && optimize && can_create_pseudo_p ()
6172                    && MEM_P (operands[1]))
6173             {
6174               rtx reg = gen_reg_rtx (SImode);
6176               emit_insn (gen_zero_extendhisi2 (reg, operands[1]));
6177               operands[1] = gen_lowpart (HImode, reg);
6178             }
6179           else if (!arm_arch4)
6180             {
6181               if (MEM_P (operands[1]))
6182                 {
6183                   rtx base;
6184                   rtx offset = const0_rtx;
6185                   rtx reg = gen_reg_rtx (SImode);
6187                   if ((REG_P (base = XEXP (operands[1], 0))
6188                        || (GET_CODE (base) == PLUS
6189                            && (CONST_INT_P (offset = XEXP (base, 1)))
6190                            && ((INTVAL(offset) & 1) != 1)
6191                            && REG_P (base = XEXP (base, 0))))
6192                       && REGNO_POINTER_ALIGN (REGNO (base)) >= 32)
6193                     {
6194                       rtx new_rtx;
6196                       new_rtx = widen_memory_access (operands[1], SImode,
6197                                                      ((INTVAL (offset) & ~3)
6198                                                       - INTVAL (offset)));
6199                       emit_insn (gen_movsi (reg, new_rtx));
6200                       if (((INTVAL (offset) & 2) != 0)
6201                           ^ (BYTES_BIG_ENDIAN ? 1 : 0))
6202                         {
6203                           rtx reg2 = gen_reg_rtx (SImode);
6205                           emit_insn (gen_lshrsi3 (reg2, reg, GEN_INT (16)));
6206                           reg = reg2;
6207                         }
6208                     }
6209                   else
6210                     emit_insn (gen_movhi_bytes (reg, operands[1]));
6212                   operands[1] = gen_lowpart (HImode, reg);
6213                }
6214            }
6215         }
6216       /* Handle loading a large integer during reload.  */
6217       else if (CONST_INT_P (operands[1])
6218                && !const_ok_for_arm (INTVAL (operands[1]))
6219                && !const_ok_for_arm (~INTVAL (operands[1])))
6220         {
6221           /* Writing a constant to memory needs a scratch, which should
6222              be handled with SECONDARY_RELOADs.  */
6223           gcc_assert (REG_P (operands[0]));
6225           operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
6226           emit_insn (gen_movsi (operands[0], operands[1]));
6227           DONE;
6228        }
6229     }
6230   else if (TARGET_THUMB2)
6231     {
6232       /* Thumb-2 can do everything except mem=mem and mem=const easily.  */
6233       if (can_create_pseudo_p ())
6234         {
6235           if (!REG_P (operands[0]))
6236             operands[1] = force_reg (HImode, operands[1]);
6237           /* Zero extend a constant, and keep it in an SImode reg.  */
6238           else if (CONST_INT_P (operands[1]))
6239             {
6240               rtx reg = gen_reg_rtx (SImode);
6241               HOST_WIDE_INT val = INTVAL (operands[1]) & 0xffff;
6243               emit_insn (gen_movsi (reg, GEN_INT (val)));
6244               operands[1] = gen_lowpart (HImode, reg);
6245             }
6246         }
6247     }
6248   else /* TARGET_THUMB1 */
6249     {
6250       if (can_create_pseudo_p ())
6251         {
6252           if (CONST_INT_P (operands[1]))
6253             {
6254               rtx reg = gen_reg_rtx (SImode);
6256               emit_insn (gen_movsi (reg, operands[1]));
6257               operands[1] = gen_lowpart (HImode, reg);
6258             }
6260           /* ??? We shouldn't really get invalid addresses here, but this can
6261              happen if we are passed a SP (never OK for HImode/QImode) or 
6262              virtual register (also rejected as illegitimate for HImode/QImode)
6263              relative address.  */
6264           /* ??? This should perhaps be fixed elsewhere, for instance, in
6265              fixup_stack_1, by checking for other kinds of invalid addresses,
6266              e.g. a bare reference to a virtual register.  This may confuse the
6267              alpha though, which must handle this case differently.  */
6268           if (MEM_P (operands[0])
6269               && !memory_address_p (GET_MODE (operands[0]),
6270                                     XEXP (operands[0], 0)))
6271             operands[0]
6272               = replace_equiv_address (operands[0],
6273                                        copy_to_reg (XEXP (operands[0], 0)));
6274    
6275           if (MEM_P (operands[1])
6276               && !memory_address_p (GET_MODE (operands[1]),
6277                                     XEXP (operands[1], 0)))
6278             operands[1]
6279               = replace_equiv_address (operands[1],
6280                                        copy_to_reg (XEXP (operands[1], 0)));
6282           if (MEM_P (operands[1]) && optimize > 0)
6283             {
6284               rtx reg = gen_reg_rtx (SImode);
6286               emit_insn (gen_zero_extendhisi2 (reg, operands[1]));
6287               operands[1] = gen_lowpart (HImode, reg);
6288             }
6290           if (MEM_P (operands[0]))
6291             operands[1] = force_reg (HImode, operands[1]);
6292         }
6293       else if (CONST_INT_P (operands[1])
6294                 && !satisfies_constraint_I (operands[1]))
6295         {
6296           /* Handle loading a large integer during reload.  */
6298           /* Writing a constant to memory needs a scratch, which should
6299              be handled with SECONDARY_RELOADs.  */
6300           gcc_assert (REG_P (operands[0]));
6302           operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
6303           emit_insn (gen_movsi (operands[0], operands[1]));
6304           DONE;
6305         }
6306     }
6307   "
6310 (define_expand "movhi_bytes"
6311   [(set (match_dup 2) (zero_extend:SI (match_operand:HI 1 "" "")))
6312    (set (match_dup 3)
6313         (zero_extend:SI (match_dup 6)))
6314    (set (match_operand:SI 0 "" "")
6315          (ior:SI (ashift:SI (match_dup 4) (const_int 8)) (match_dup 5)))]
6316   "TARGET_ARM"
6317   "
6318   {
6319     rtx mem1, mem2;
6320     rtx addr = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
6322     mem1 = change_address (operands[1], QImode, addr);
6323     mem2 = change_address (operands[1], QImode,
6324                            plus_constant (Pmode, addr, 1));
6325     operands[0] = gen_lowpart (SImode, operands[0]);
6326     operands[1] = mem1;
6327     operands[2] = gen_reg_rtx (SImode);
6328     operands[3] = gen_reg_rtx (SImode);
6329     operands[6] = mem2;
6331     if (BYTES_BIG_ENDIAN)
6332       {
6333         operands[4] = operands[2];
6334         operands[5] = operands[3];
6335       }
6336     else
6337       {
6338         operands[4] = operands[3];
6339         operands[5] = operands[2];
6340       }
6341   }"
6344 (define_expand "movhi_bigend"
6345   [(set (match_dup 2)
6346         (rotate:SI (subreg:SI (match_operand:HI 1 "memory_operand" "") 0)
6347                    (const_int 16)))
6348    (set (match_dup 3)
6349         (ashiftrt:SI (match_dup 2) (const_int 16)))
6350    (set (match_operand:HI 0 "s_register_operand" "")
6351         (match_dup 4))]
6352   "TARGET_ARM"
6353   "
6354   operands[2] = gen_reg_rtx (SImode);
6355   operands[3] = gen_reg_rtx (SImode);
6356   operands[4] = gen_lowpart (HImode, operands[3]);
6357   "
6360 ;; Pattern to recognize insn generated default case above
6361 (define_insn "*movhi_insn_arch4"
6362   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m,r")
6363         (match_operand:HI 1 "general_operand"      "rIk,K,n,r,mi"))]
6364   "TARGET_ARM
6365    && arm_arch4
6366    && (register_operand (operands[0], HImode)
6367        || register_operand (operands[1], HImode))"
6368   "@
6369    mov%?\\t%0, %1\\t%@ movhi
6370    mvn%?\\t%0, #%B1\\t%@ movhi
6371    movw%?\\t%0, %L1\\t%@ movhi
6372    strh%?\\t%1, %0\\t%@ movhi
6373    ldrh%?\\t%0, %1\\t%@ movhi"
6374   [(set_attr "predicable" "yes")
6375    (set_attr "pool_range" "*,*,*,*,256")
6376    (set_attr "neg_pool_range" "*,*,*,*,244")
6377    (set_attr "arch" "*,*,v6t2,*,*")
6378    (set_attr_alternative "type"
6379                          [(if_then_else (match_operand 1 "const_int_operand" "")
6380                                         (const_string "mov_imm" )
6381                                         (const_string "mov_reg"))
6382                           (const_string "mvn_imm")
6383                           (const_string "mov_imm")
6384                           (const_string "store1")
6385                           (const_string "load1")])]
6388 (define_insn "*movhi_bytes"
6389   [(set (match_operand:HI 0 "s_register_operand" "=r,r,r")
6390         (match_operand:HI 1 "arm_rhs_operand"  "I,rk,K"))]
6391   "TARGET_ARM"
6392   "@
6393    mov%?\\t%0, %1\\t%@ movhi
6394    mov%?\\t%0, %1\\t%@ movhi
6395    mvn%?\\t%0, #%B1\\t%@ movhi"
6396   [(set_attr "predicable" "yes")
6397    (set_attr "type" "mov_imm,mov_reg,mvn_imm")]
6399         
6400 ;; We use a DImode scratch because we may occasionally need an additional
6401 ;; temporary if the address isn't offsettable -- push_reload doesn't seem
6402 ;; to take any notice of the "o" constraints on reload_memory_operand operand.
6403 (define_expand "reload_outhi"
6404   [(parallel [(match_operand:HI 0 "arm_reload_memory_operand" "=o")
6405               (match_operand:HI 1 "s_register_operand"        "r")
6406               (match_operand:DI 2 "s_register_operand"        "=&l")])]
6407   "TARGET_EITHER"
6408   "if (TARGET_ARM)
6409      arm_reload_out_hi (operands);
6410    else
6411      thumb_reload_out_hi (operands);
6412   DONE;
6413   "
6416 (define_expand "reload_inhi"
6417   [(parallel [(match_operand:HI 0 "s_register_operand" "=r")
6418               (match_operand:HI 1 "arm_reload_memory_operand" "o")
6419               (match_operand:DI 2 "s_register_operand" "=&r")])]
6420   "TARGET_EITHER"
6421   "
6422   if (TARGET_ARM)
6423     arm_reload_in_hi (operands);
6424   else
6425     thumb_reload_out_hi (operands);
6426   DONE;
6429 (define_expand "movqi"
6430   [(set (match_operand:QI 0 "general_operand" "")
6431         (match_operand:QI 1 "general_operand" ""))]
6432   "TARGET_EITHER"
6433   "
6434   /* Everything except mem = const or mem = mem can be done easily */
6436   if (can_create_pseudo_p ())
6437     {
6438       if (CONST_INT_P (operands[1]))
6439         {
6440           rtx reg = gen_reg_rtx (SImode);
6442           /* For thumb we want an unsigned immediate, then we are more likely 
6443              to be able to use a movs insn.  */
6444           if (TARGET_THUMB)
6445             operands[1] = GEN_INT (INTVAL (operands[1]) & 255);
6447           emit_insn (gen_movsi (reg, operands[1]));
6448           operands[1] = gen_lowpart (QImode, reg);
6449         }
6451       if (TARGET_THUMB)
6452         {
6453           /* ??? We shouldn't really get invalid addresses here, but this can
6454              happen if we are passed a SP (never OK for HImode/QImode) or
6455              virtual register (also rejected as illegitimate for HImode/QImode)
6456              relative address.  */
6457           /* ??? This should perhaps be fixed elsewhere, for instance, in
6458              fixup_stack_1, by checking for other kinds of invalid addresses,
6459              e.g. a bare reference to a virtual register.  This may confuse the
6460              alpha though, which must handle this case differently.  */
6461           if (MEM_P (operands[0])
6462               && !memory_address_p (GET_MODE (operands[0]),
6463                                      XEXP (operands[0], 0)))
6464             operands[0]
6465               = replace_equiv_address (operands[0],
6466                                        copy_to_reg (XEXP (operands[0], 0)));
6467           if (MEM_P (operands[1])
6468               && !memory_address_p (GET_MODE (operands[1]),
6469                                     XEXP (operands[1], 0)))
6470              operands[1]
6471                = replace_equiv_address (operands[1],
6472                                         copy_to_reg (XEXP (operands[1], 0)));
6473         }
6475       if (MEM_P (operands[1]) && optimize > 0)
6476         {
6477           rtx reg = gen_reg_rtx (SImode);
6479           emit_insn (gen_zero_extendqisi2 (reg, operands[1]));
6480           operands[1] = gen_lowpart (QImode, reg);
6481         }
6483       if (MEM_P (operands[0]))
6484         operands[1] = force_reg (QImode, operands[1]);
6485     }
6486   else if (TARGET_THUMB
6487            && CONST_INT_P (operands[1])
6488            && !satisfies_constraint_I (operands[1]))
6489     {
6490       /* Handle loading a large integer during reload.  */
6492       /* Writing a constant to memory needs a scratch, which should
6493          be handled with SECONDARY_RELOADs.  */
6494       gcc_assert (REG_P (operands[0]));
6496       operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
6497       emit_insn (gen_movsi (operands[0], operands[1]));
6498       DONE;
6499     }
6500   "
6503 (define_insn "*arm_movqi_insn"
6504   [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,r,l,r,l,Uu,r,m")
6505         (match_operand:QI 1 "general_operand" "rk,rk,I,Py,K,Uu,l,Uh,r"))]
6506   "TARGET_32BIT
6507    && (   register_operand (operands[0], QImode)
6508        || register_operand (operands[1], QImode))"
6509   "@
6510    mov%?\\t%0, %1
6511    mov%?\\t%0, %1
6512    mov%?\\t%0, %1
6513    mov%?\\t%0, %1
6514    mvn%?\\t%0, #%B1
6515    ldrb%?\\t%0, %1
6516    strb%?\\t%1, %0
6517    ldrb%?\\t%0, %1
6518    strb%?\\t%1, %0"
6519   [(set_attr "type" "mov_reg,mov_reg,mov_imm,mov_imm,mvn_imm,load1,store1,load1,store1")
6520    (set_attr "predicable" "yes")
6521    (set_attr "predicable_short_it" "yes,yes,yes,no,no,no,no,no,no")
6522    (set_attr "arch" "t2,any,any,t2,any,t2,t2,any,any")
6523    (set_attr "length" "2,4,4,2,4,2,2,4,4")]
6526 ;; HFmode moves
6527 (define_expand "movhf"
6528   [(set (match_operand:HF 0 "general_operand" "")
6529         (match_operand:HF 1 "general_operand" ""))]
6530   "TARGET_EITHER"
6531   "
6532   if (TARGET_32BIT)
6533     {
6534       if (MEM_P (operands[0]))
6535         operands[1] = force_reg (HFmode, operands[1]);
6536     }
6537   else /* TARGET_THUMB1 */
6538     {
6539       if (can_create_pseudo_p ())
6540         {
6541            if (!REG_P (operands[0]))
6542              operands[1] = force_reg (HFmode, operands[1]);
6543         }
6544     }
6545   "
6548 (define_insn "*arm32_movhf"
6549   [(set (match_operand:HF 0 "nonimmediate_operand" "=r,m,r,r")
6550         (match_operand:HF 1 "general_operand"      " m,r,r,F"))]
6551   "TARGET_32BIT && !(TARGET_HARD_FLOAT && TARGET_VFP)
6552    && (   s_register_operand (operands[0], HFmode)
6553        || s_register_operand (operands[1], HFmode))"
6554   "*
6555   switch (which_alternative)
6556     {
6557     case 0:     /* ARM register from memory */
6558       return \"ldrh%?\\t%0, %1\\t%@ __fp16\";
6559     case 1:     /* memory from ARM register */
6560       return \"strh%?\\t%1, %0\\t%@ __fp16\";
6561     case 2:     /* ARM register from ARM register */
6562       return \"mov%?\\t%0, %1\\t%@ __fp16\";
6563     case 3:     /* ARM register from constant */
6564       {
6565         long bits;
6566         rtx ops[4];
6568         bits = real_to_target (NULL, CONST_DOUBLE_REAL_VALUE (operands[1]),
6569                                HFmode);
6570         ops[0] = operands[0];
6571         ops[1] = GEN_INT (bits);
6572         ops[2] = GEN_INT (bits & 0xff00);
6573         ops[3] = GEN_INT (bits & 0x00ff);
6575         if (arm_arch_thumb2)
6576           output_asm_insn (\"movw%?\\t%0, %1\", ops);
6577         else
6578           output_asm_insn (\"mov%?\\t%0, %2\;orr%?\\t%0, %0, %3\", ops);
6579         return \"\";
6580        }
6581     default:
6582       gcc_unreachable ();
6583     }
6584   "
6585   [(set_attr "conds" "unconditional")
6586    (set_attr "type" "load1,store1,mov_reg,multiple")
6587    (set_attr "length" "4,4,4,8")
6588    (set_attr "predicable" "yes")
6589    (set_attr "predicable_short_it" "no")]
6592 (define_expand "movsf"
6593   [(set (match_operand:SF 0 "general_operand" "")
6594         (match_operand:SF 1 "general_operand" ""))]
6595   "TARGET_EITHER"
6596   "
6597   if (TARGET_32BIT)
6598     {
6599       if (MEM_P (operands[0]))
6600         operands[1] = force_reg (SFmode, operands[1]);
6601     }
6602   else /* TARGET_THUMB1 */
6603     {
6604       if (can_create_pseudo_p ())
6605         {
6606            if (!REG_P (operands[0]))
6607              operands[1] = force_reg (SFmode, operands[1]);
6608         }
6609     }
6610   "
6613 ;; Transform a floating-point move of a constant into a core register into
6614 ;; an SImode operation.
6615 (define_split
6616   [(set (match_operand:SF 0 "arm_general_register_operand" "")
6617         (match_operand:SF 1 "immediate_operand" ""))]
6618   "TARGET_EITHER
6619    && reload_completed
6620    && CONST_DOUBLE_P (operands[1])"
6621   [(set (match_dup 2) (match_dup 3))]
6622   "
6623   operands[2] = gen_lowpart (SImode, operands[0]);
6624   operands[3] = gen_lowpart (SImode, operands[1]);
6625   if (operands[2] == 0 || operands[3] == 0)
6626     FAIL;
6627   "
6630 (define_insn "*arm_movsf_soft_insn"
6631   [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,m")
6632         (match_operand:SF 1 "general_operand"  "r,mE,r"))]
6633   "TARGET_32BIT
6634    && TARGET_SOFT_FLOAT
6635    && (!MEM_P (operands[0])
6636        || register_operand (operands[1], SFmode))"
6637   "@
6638    mov%?\\t%0, %1
6639    ldr%?\\t%0, %1\\t%@ float
6640    str%?\\t%1, %0\\t%@ float"
6641   [(set_attr "predicable" "yes")
6642    (set_attr "predicable_short_it" "no")
6643    (set_attr "type" "mov_reg,load1,store1")
6644    (set_attr "arm_pool_range" "*,4096,*")
6645    (set_attr "thumb2_pool_range" "*,4094,*")
6646    (set_attr "arm_neg_pool_range" "*,4084,*")
6647    (set_attr "thumb2_neg_pool_range" "*,0,*")]
6650 (define_expand "movdf"
6651   [(set (match_operand:DF 0 "general_operand" "")
6652         (match_operand:DF 1 "general_operand" ""))]
6653   "TARGET_EITHER"
6654   "
6655   if (TARGET_32BIT)
6656     {
6657       if (MEM_P (operands[0]))
6658         operands[1] = force_reg (DFmode, operands[1]);
6659     }
6660   else /* TARGET_THUMB */
6661     {
6662       if (can_create_pseudo_p ())
6663         {
6664           if (!REG_P (operands[0]))
6665             operands[1] = force_reg (DFmode, operands[1]);
6666         }
6667     }
6668   "
6671 ;; Reloading a df mode value stored in integer regs to memory can require a
6672 ;; scratch reg.
6673 (define_expand "reload_outdf"
6674   [(match_operand:DF 0 "arm_reload_memory_operand" "=o")
6675    (match_operand:DF 1 "s_register_operand" "r")
6676    (match_operand:SI 2 "s_register_operand" "=&r")]
6677   "TARGET_THUMB2"
6678   "
6679   {
6680     enum rtx_code code = GET_CODE (XEXP (operands[0], 0));
6682     if (code == REG)
6683       operands[2] = XEXP (operands[0], 0);
6684     else if (code == POST_INC || code == PRE_DEC)
6685       {
6686         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
6687         operands[1] = gen_rtx_SUBREG (DImode, operands[1], 0);
6688         emit_insn (gen_movdi (operands[0], operands[1]));
6689         DONE;
6690       }
6691     else if (code == PRE_INC)
6692       {
6693         rtx reg = XEXP (XEXP (operands[0], 0), 0);
6695         emit_insn (gen_addsi3 (reg, reg, GEN_INT (8)));
6696         operands[2] = reg;
6697       }
6698     else if (code == POST_DEC)
6699       operands[2] = XEXP (XEXP (operands[0], 0), 0);
6700     else
6701       emit_insn (gen_addsi3 (operands[2], XEXP (XEXP (operands[0], 0), 0),
6702                              XEXP (XEXP (operands[0], 0), 1)));
6704     emit_insn (gen_rtx_SET (replace_equiv_address (operands[0], operands[2]),
6705                             operands[1]));
6707     if (code == POST_DEC)
6708       emit_insn (gen_addsi3 (operands[2], operands[2], GEN_INT (-8)));
6710     DONE;
6711   }"
6714 (define_insn "*movdf_soft_insn"
6715   [(set (match_operand:DF 0 "nonimmediate_soft_df_operand" "=r,r,r,q,m")
6716         (match_operand:DF 1 "soft_df_operand" "rDa,Db,Dc,mF,q"))]
6717   "TARGET_32BIT && TARGET_SOFT_FLOAT
6718    && (   register_operand (operands[0], DFmode)
6719        || register_operand (operands[1], DFmode))"
6720   "*
6721   switch (which_alternative)
6722     {
6723     case 0:
6724     case 1:
6725     case 2:
6726       return \"#\";
6727     default:
6728       return output_move_double (operands, true, NULL);
6729     }
6730   "
6731   [(set_attr "length" "8,12,16,8,8")
6732    (set_attr "type" "multiple,multiple,multiple,load2,store2")
6733    (set_attr "arm_pool_range" "*,*,*,1020,*")
6734    (set_attr "thumb2_pool_range" "*,*,*,1018,*")
6735    (set_attr "arm_neg_pool_range" "*,*,*,1004,*")
6736    (set_attr "thumb2_neg_pool_range" "*,*,*,0,*")]
6740 ;; load- and store-multiple insns
6741 ;; The arm can load/store any set of registers, provided that they are in
6742 ;; ascending order, but these expanders assume a contiguous set.
6744 (define_expand "load_multiple"
6745   [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
6746                           (match_operand:SI 1 "" ""))
6747                      (use (match_operand:SI 2 "" ""))])]
6748   "TARGET_32BIT"
6750   HOST_WIDE_INT offset = 0;
6752   /* Support only fixed point registers.  */
6753   if (!CONST_INT_P (operands[2])
6754       || INTVAL (operands[2]) > MAX_LDM_STM_OPS
6755       || INTVAL (operands[2]) < 2
6756       || !MEM_P (operands[1])
6757       || !REG_P (operands[0])
6758       || REGNO (operands[0]) > (LAST_ARM_REGNUM - 1)
6759       || REGNO (operands[0]) + INTVAL (operands[2]) > LAST_ARM_REGNUM)
6760     FAIL;
6762   operands[3]
6763     = arm_gen_load_multiple (arm_regs_in_sequence + REGNO (operands[0]),
6764                              INTVAL (operands[2]),
6765                              force_reg (SImode, XEXP (operands[1], 0)),
6766                              FALSE, operands[1], &offset);
6769 (define_expand "store_multiple"
6770   [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
6771                           (match_operand:SI 1 "" ""))
6772                      (use (match_operand:SI 2 "" ""))])]
6773   "TARGET_32BIT"
6775   HOST_WIDE_INT offset = 0;
6777   /* Support only fixed point registers.  */
6778   if (!CONST_INT_P (operands[2])
6779       || INTVAL (operands[2]) > MAX_LDM_STM_OPS
6780       || INTVAL (operands[2]) < 2
6781       || !REG_P (operands[1])
6782       || !MEM_P (operands[0])
6783       || REGNO (operands[1]) > (LAST_ARM_REGNUM - 1)
6784       || REGNO (operands[1]) + INTVAL (operands[2]) > LAST_ARM_REGNUM)
6785     FAIL;
6787   operands[3]
6788     = arm_gen_store_multiple (arm_regs_in_sequence + REGNO (operands[1]),
6789                               INTVAL (operands[2]),
6790                               force_reg (SImode, XEXP (operands[0], 0)),
6791                               FALSE, operands[0], &offset);
6795 (define_expand "setmemsi"
6796   [(match_operand:BLK 0 "general_operand" "")
6797    (match_operand:SI 1 "const_int_operand" "")
6798    (match_operand:SI 2 "const_int_operand" "")
6799    (match_operand:SI 3 "const_int_operand" "")]
6800   "TARGET_32BIT"
6802   if (arm_gen_setmem (operands))
6803     DONE;
6805   FAIL;
6809 ;; Move a block of memory if it is word aligned and MORE than 2 words long.
6810 ;; We could let this apply for blocks of less than this, but it clobbers so
6811 ;; many registers that there is then probably a better way.
6813 (define_expand "movmemqi"
6814   [(match_operand:BLK 0 "general_operand" "")
6815    (match_operand:BLK 1 "general_operand" "")
6816    (match_operand:SI 2 "const_int_operand" "")
6817    (match_operand:SI 3 "const_int_operand" "")]
6818   ""
6819   "
6820   if (TARGET_32BIT)
6821     {
6822       if (TARGET_LDRD && current_tune->prefer_ldrd_strd
6823           && !optimize_function_for_size_p (cfun))
6824         {
6825           if (gen_movmem_ldrd_strd (operands))
6826             DONE;
6827           FAIL;
6828         }
6830       if (arm_gen_movmemqi (operands))
6831         DONE;
6832       FAIL;
6833     }
6834   else /* TARGET_THUMB1 */
6835     {
6836       if (   INTVAL (operands[3]) != 4
6837           || INTVAL (operands[2]) > 48)
6838         FAIL;
6840       thumb_expand_movmemqi (operands);
6841       DONE;
6842     }
6843   "
6847 ;; Compare & branch insns
6848 ;; The range calculations are based as follows:
6849 ;; For forward branches, the address calculation returns the address of
6850 ;; the next instruction.  This is 2 beyond the branch instruction.
6851 ;; For backward branches, the address calculation returns the address of
6852 ;; the first instruction in this pattern (cmp).  This is 2 before the branch
6853 ;; instruction for the shortest sequence, and 4 before the branch instruction
6854 ;; if we have to jump around an unconditional branch.
6855 ;; To the basic branch range the PC offset must be added (this is +4).
6856 ;; So for forward branches we have 
6857 ;;   (pos_range - pos_base_offs + pc_offs) = (pos_range - 2 + 4).
6858 ;; And for backward branches we have 
6859 ;;   (neg_range - neg_base_offs + pc_offs) = (neg_range - (-2 or -4) + 4).
6861 ;; For a 'b'       pos_range = 2046, neg_range = -2048 giving (-2040->2048).
6862 ;; For a 'b<cond>' pos_range = 254,  neg_range = -256  giving (-250 ->256).
6864 (define_expand "cbranchsi4"
6865   [(set (pc) (if_then_else
6866               (match_operator 0 "expandable_comparison_operator"
6867                [(match_operand:SI 1 "s_register_operand" "")
6868                 (match_operand:SI 2 "nonmemory_operand" "")])
6869               (label_ref (match_operand 3 "" ""))
6870               (pc)))]
6871   "TARGET_EITHER"
6872   "
6873   if (!TARGET_THUMB1)
6874     {
6875       if (!arm_validize_comparison (&operands[0], &operands[1], &operands[2]))
6876         FAIL;
6877       emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
6878                                       operands[3]));
6879       DONE;
6880     }
6881   if (thumb1_cmpneg_operand (operands[2], SImode))
6882     {
6883       emit_jump_insn (gen_cbranchsi4_scratch (NULL, operands[1], operands[2],
6884                                               operands[3], operands[0]));
6885       DONE;
6886     }
6887   if (!thumb1_cmp_operand (operands[2], SImode))
6888     operands[2] = force_reg (SImode, operands[2]);
6889   ")
6891 (define_expand "cbranchsf4"
6892   [(set (pc) (if_then_else
6893               (match_operator 0 "expandable_comparison_operator"
6894                [(match_operand:SF 1 "s_register_operand" "")
6895                 (match_operand:SF 2 "arm_float_compare_operand" "")])
6896               (label_ref (match_operand 3 "" ""))
6897               (pc)))]
6898   "TARGET_32BIT && TARGET_HARD_FLOAT"
6899   "emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
6900                                    operands[3])); DONE;"
6903 (define_expand "cbranchdf4"
6904   [(set (pc) (if_then_else
6905               (match_operator 0 "expandable_comparison_operator"
6906                [(match_operand:DF 1 "s_register_operand" "")
6907                 (match_operand:DF 2 "arm_float_compare_operand" "")])
6908               (label_ref (match_operand 3 "" ""))
6909               (pc)))]
6910   "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
6911   "emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
6912                                    operands[3])); DONE;"
6915 (define_expand "cbranchdi4"
6916   [(set (pc) (if_then_else
6917               (match_operator 0 "expandable_comparison_operator"
6918                [(match_operand:DI 1 "s_register_operand" "")
6919                 (match_operand:DI 2 "cmpdi_operand" "")])
6920               (label_ref (match_operand 3 "" ""))
6921               (pc)))]
6922   "TARGET_32BIT"
6923   "{
6924      if (!arm_validize_comparison (&operands[0], &operands[1], &operands[2]))
6925        FAIL;
6926      emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
6927                                        operands[3]));
6928      DONE;
6929    }"
6932 ;; Comparison and test insns
6934 (define_insn "*arm_cmpsi_insn"
6935   [(set (reg:CC CC_REGNUM)
6936         (compare:CC (match_operand:SI 0 "s_register_operand" "l,r,r,r,r")
6937                     (match_operand:SI 1 "arm_add_operand"    "Py,r,r,I,L")))]
6938   "TARGET_32BIT"
6939   "@
6940    cmp%?\\t%0, %1
6941    cmp%?\\t%0, %1
6942    cmp%?\\t%0, %1
6943    cmp%?\\t%0, %1
6944    cmn%?\\t%0, #%n1"
6945   [(set_attr "conds" "set")
6946    (set_attr "arch" "t2,t2,any,any,any")
6947    (set_attr "length" "2,2,4,4,4")
6948    (set_attr "predicable" "yes")
6949    (set_attr "predicable_short_it" "yes,yes,yes,no,no")
6950    (set_attr "type" "alus_imm,alus_sreg,alus_sreg,alus_imm,alus_imm")]
6953 (define_insn "*cmpsi_shiftsi"
6954   [(set (reg:CC CC_REGNUM)
6955         (compare:CC (match_operand:SI   0 "s_register_operand" "r,r,r")
6956                     (match_operator:SI  3 "shift_operator"
6957                      [(match_operand:SI 1 "s_register_operand" "r,r,r")
6958                       (match_operand:SI 2 "shift_amount_operand" "M,r,M")])))]
6959   "TARGET_32BIT"
6960   "cmp\\t%0, %1%S3"
6961   [(set_attr "conds" "set")
6962    (set_attr "shift" "1")
6963    (set_attr "arch" "32,a,a")
6964    (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
6966 (define_insn "*cmpsi_shiftsi_swp"
6967   [(set (reg:CC_SWP CC_REGNUM)
6968         (compare:CC_SWP (match_operator:SI 3 "shift_operator"
6969                          [(match_operand:SI 1 "s_register_operand" "r,r,r")
6970                           (match_operand:SI 2 "shift_amount_operand" "M,r,M")])
6971                         (match_operand:SI 0 "s_register_operand" "r,r,r")))]
6972   "TARGET_32BIT"
6973   "cmp%?\\t%0, %1%S3"
6974   [(set_attr "conds" "set")
6975    (set_attr "shift" "1")
6976    (set_attr "arch" "32,a,a")
6977    (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
6979 (define_insn "*arm_cmpsi_negshiftsi_si"
6980   [(set (reg:CC_Z CC_REGNUM)
6981         (compare:CC_Z
6982          (neg:SI (match_operator:SI 1 "shift_operator"
6983                     [(match_operand:SI 2 "s_register_operand" "r")
6984                      (match_operand:SI 3 "reg_or_int_operand" "rM")]))
6985          (match_operand:SI 0 "s_register_operand" "r")))]
6986   "TARGET_ARM"
6987   "cmn%?\\t%0, %2%S1"
6988   [(set_attr "conds" "set")
6989    (set (attr "type") (if_then_else (match_operand 3 "const_int_operand" "")
6990                                     (const_string "alus_shift_imm")
6991                                     (const_string "alus_shift_reg")))
6992    (set_attr "predicable" "yes")]
6995 ;; DImode comparisons.  The generic code generates branches that
6996 ;; if-conversion can not reduce to a conditional compare, so we do
6997 ;; that directly.
6999 (define_insn_and_split "*arm_cmpdi_insn"
7000   [(set (reg:CC_NCV CC_REGNUM)
7001         (compare:CC_NCV (match_operand:DI 0 "s_register_operand" "r")
7002                         (match_operand:DI 1 "arm_di_operand"       "rDi")))
7003    (clobber (match_scratch:SI 2 "=r"))]
7004   "TARGET_32BIT"
7005   "#"   ; "cmp\\t%Q0, %Q1\;sbcs\\t%2, %R0, %R1"
7006   "&& reload_completed"
7007   [(set (reg:CC CC_REGNUM)
7008         (compare:CC (match_dup 0) (match_dup 1)))
7009    (parallel [(set (reg:CC CC_REGNUM)
7010                    (compare:CC (match_dup 3) (match_dup 4)))
7011               (set (match_dup 2)
7012                    (minus:SI (match_dup 5)
7013                             (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))])]
7014   {
7015     operands[3] = gen_highpart (SImode, operands[0]);
7016     operands[0] = gen_lowpart (SImode, operands[0]);
7017     if (CONST_INT_P (operands[1]))
7018       {
7019         operands[4] = GEN_INT (~INTVAL (gen_highpart_mode (SImode,
7020                                                            DImode,
7021                                                            operands[1])));
7022         operands[5] = gen_rtx_PLUS (SImode, operands[3], operands[4]);
7023       }
7024     else
7025       {
7026         operands[4] = gen_highpart (SImode, operands[1]);
7027         operands[5] = gen_rtx_MINUS (SImode, operands[3], operands[4]);
7028       }
7029     operands[1] = gen_lowpart (SImode, operands[1]);
7030     operands[2] = gen_lowpart (SImode, operands[2]);
7031   }
7032   [(set_attr "conds" "set")
7033    (set_attr "length" "8")
7034    (set_attr "type" "multiple")]
7037 (define_insn_and_split "*arm_cmpdi_unsigned"
7038   [(set (reg:CC_CZ CC_REGNUM)
7039         (compare:CC_CZ (match_operand:DI 0 "s_register_operand" "l,r,r,r")
7040                        (match_operand:DI 1 "arm_di_operand"     "Py,r,Di,rDi")))]
7042   "TARGET_32BIT"
7043   "#"   ; "cmp\\t%R0, %R1\;it eq\;cmpeq\\t%Q0, %Q1"
7044   "&& reload_completed"
7045   [(set (reg:CC CC_REGNUM)
7046         (compare:CC (match_dup 2) (match_dup 3)))
7047    (cond_exec (eq:SI (reg:CC CC_REGNUM) (const_int 0))
7048               (set (reg:CC CC_REGNUM)
7049                    (compare:CC (match_dup 0) (match_dup 1))))]
7050   {
7051     operands[2] = gen_highpart (SImode, operands[0]);
7052     operands[0] = gen_lowpart (SImode, operands[0]);
7053     if (CONST_INT_P (operands[1]))
7054       operands[3] = gen_highpart_mode (SImode, DImode, operands[1]);
7055     else
7056       operands[3] = gen_highpart (SImode, operands[1]);
7057     operands[1] = gen_lowpart (SImode, operands[1]);
7058   }
7059   [(set_attr "conds" "set")
7060    (set_attr "enabled_for_depr_it" "yes,yes,no,*")
7061    (set_attr "arch" "t2,t2,t2,a")
7062    (set_attr "length" "6,6,10,8")
7063    (set_attr "type" "multiple")]
7066 (define_insn "*arm_cmpdi_zero"
7067   [(set (reg:CC_Z CC_REGNUM)
7068         (compare:CC_Z (match_operand:DI 0 "s_register_operand" "r")
7069                       (const_int 0)))
7070    (clobber (match_scratch:SI 1 "=r"))]
7071   "TARGET_32BIT"
7072   "orrs%?\\t%1, %Q0, %R0"
7073   [(set_attr "conds" "set")
7074    (set_attr "type" "logics_reg")]
7077 ; This insn allows redundant compares to be removed by cse, nothing should
7078 ; ever appear in the output file since (set (reg x) (reg x)) is a no-op that
7079 ; is deleted later on. The match_dup will match the mode here, so that
7080 ; mode changes of the condition codes aren't lost by this even though we don't
7081 ; specify what they are.
7083 (define_insn "*deleted_compare"
7084   [(set (match_operand 0 "cc_register" "") (match_dup 0))]
7085   "TARGET_32BIT"
7086   "\\t%@ deleted compare"
7087   [(set_attr "conds" "set")
7088    (set_attr "length" "0")
7089    (set_attr "type" "no_insn")]
7093 ;; Conditional branch insns
7095 (define_expand "cbranch_cc"
7096   [(set (pc)
7097         (if_then_else (match_operator 0 "" [(match_operand 1 "" "")
7098                                             (match_operand 2 "" "")])
7099                       (label_ref (match_operand 3 "" ""))
7100                       (pc)))]
7101   "TARGET_32BIT"
7102   "operands[1] = arm_gen_compare_reg (GET_CODE (operands[0]),
7103                                       operands[1], operands[2], NULL_RTX);
7104    operands[2] = const0_rtx;"
7108 ;; Patterns to match conditional branch insns.
7111 (define_insn "arm_cond_branch"
7112   [(set (pc)
7113         (if_then_else (match_operator 1 "arm_comparison_operator"
7114                        [(match_operand 2 "cc_register" "") (const_int 0)])
7115                       (label_ref (match_operand 0 "" ""))
7116                       (pc)))]
7117   "TARGET_32BIT"
7118   "*
7119   if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
7120     {
7121       arm_ccfsm_state += 2;
7122       return \"\";
7123     }
7124   return \"b%d1\\t%l0\";
7125   "
7126   [(set_attr "conds" "use")
7127    (set_attr "type" "branch")
7128    (set (attr "length")
7129         (if_then_else
7130            (and (match_test "TARGET_THUMB2")
7131                 (and (ge (minus (match_dup 0) (pc)) (const_int -250))
7132                      (le (minus (match_dup 0) (pc)) (const_int 256))))
7133            (const_int 2)
7134            (const_int 4)))]
7137 (define_insn "*arm_cond_branch_reversed"
7138   [(set (pc)
7139         (if_then_else (match_operator 1 "arm_comparison_operator"
7140                        [(match_operand 2 "cc_register" "") (const_int 0)])
7141                       (pc)
7142                       (label_ref (match_operand 0 "" ""))))]
7143   "TARGET_32BIT"
7144   "*
7145   if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
7146     {
7147       arm_ccfsm_state += 2;
7148       return \"\";
7149     }
7150   return \"b%D1\\t%l0\";
7151   "
7152   [(set_attr "conds" "use")
7153    (set_attr "type" "branch")
7154    (set (attr "length")
7155         (if_then_else
7156            (and (match_test "TARGET_THUMB2")
7157                 (and (ge (minus (match_dup 0) (pc)) (const_int -250))
7158                      (le (minus (match_dup 0) (pc)) (const_int 256))))
7159            (const_int 2)
7160            (const_int 4)))]
7165 ; scc insns
7167 (define_expand "cstore_cc"
7168   [(set (match_operand:SI 0 "s_register_operand" "")
7169         (match_operator:SI 1 "" [(match_operand 2 "" "")
7170                                  (match_operand 3 "" "")]))]
7171   "TARGET_32BIT"
7172   "operands[2] = arm_gen_compare_reg (GET_CODE (operands[1]),
7173                                       operands[2], operands[3], NULL_RTX);
7174    operands[3] = const0_rtx;"
7177 (define_insn_and_split "*mov_scc"
7178   [(set (match_operand:SI 0 "s_register_operand" "=r")
7179         (match_operator:SI 1 "arm_comparison_operator_mode"
7180          [(match_operand 2 "cc_register" "") (const_int 0)]))]
7181   "TARGET_ARM"
7182   "#"   ; "mov%D1\\t%0, #0\;mov%d1\\t%0, #1"
7183   "TARGET_ARM"
7184   [(set (match_dup 0)
7185         (if_then_else:SI (match_dup 1)
7186                          (const_int 1)
7187                          (const_int 0)))]
7188   ""
7189   [(set_attr "conds" "use")
7190    (set_attr "length" "8")
7191    (set_attr "type" "multiple")]
7194 (define_insn_and_split "*mov_negscc"
7195   [(set (match_operand:SI 0 "s_register_operand" "=r")
7196         (neg:SI (match_operator:SI 1 "arm_comparison_operator_mode"
7197                  [(match_operand 2 "cc_register" "") (const_int 0)])))]
7198   "TARGET_ARM"
7199   "#"   ; "mov%D1\\t%0, #0\;mvn%d1\\t%0, #0"
7200   "TARGET_ARM"
7201   [(set (match_dup 0)
7202         (if_then_else:SI (match_dup 1)
7203                          (match_dup 3)
7204                          (const_int 0)))]
7205   {
7206     operands[3] = GEN_INT (~0);
7207   }
7208   [(set_attr "conds" "use")
7209    (set_attr "length" "8")
7210    (set_attr "type" "multiple")]
7213 (define_insn_and_split "*mov_notscc"
7214   [(set (match_operand:SI 0 "s_register_operand" "=r")
7215         (not:SI (match_operator:SI 1 "arm_comparison_operator"
7216                  [(match_operand 2 "cc_register" "") (const_int 0)])))]
7217   "TARGET_ARM"
7218   "#"   ; "mvn%D1\\t%0, #0\;mvn%d1\\t%0, #1"
7219   "TARGET_ARM"
7220   [(set (match_dup 0)
7221         (if_then_else:SI (match_dup 1)
7222                          (match_dup 3)
7223                          (match_dup 4)))]
7224   {
7225     operands[3] = GEN_INT (~1);
7226     operands[4] = GEN_INT (~0);
7227   }
7228   [(set_attr "conds" "use")
7229    (set_attr "length" "8")
7230    (set_attr "type" "multiple")]
7233 (define_expand "cstoresi4"
7234   [(set (match_operand:SI 0 "s_register_operand" "")
7235         (match_operator:SI 1 "expandable_comparison_operator"
7236          [(match_operand:SI 2 "s_register_operand" "")
7237           (match_operand:SI 3 "reg_or_int_operand" "")]))]
7238   "TARGET_32BIT || TARGET_THUMB1"
7239   "{
7240   rtx op3, scratch, scratch2;
7242   if (!TARGET_THUMB1)
7243     {
7244       if (!arm_add_operand (operands[3], SImode))
7245         operands[3] = force_reg (SImode, operands[3]);
7246       emit_insn (gen_cstore_cc (operands[0], operands[1],
7247                                 operands[2], operands[3]));
7248       DONE;
7249     }
7251   if (operands[3] == const0_rtx)
7252     {
7253       switch (GET_CODE (operands[1]))
7254         {
7255         case EQ:
7256           emit_insn (gen_cstoresi_eq0_thumb1 (operands[0], operands[2]));
7257           break;
7259         case NE:
7260           emit_insn (gen_cstoresi_ne0_thumb1 (operands[0], operands[2]));
7261           break;
7263         case LE:
7264           scratch = expand_binop (SImode, add_optab, operands[2], constm1_rtx,
7265                                   NULL_RTX, 0, OPTAB_WIDEN);
7266           scratch = expand_binop (SImode, ior_optab, operands[2], scratch,
7267                                   NULL_RTX, 0, OPTAB_WIDEN);
7268           expand_binop (SImode, lshr_optab, scratch, GEN_INT (31),
7269                         operands[0], 1, OPTAB_WIDEN);
7270           break;
7272         case GE:
7273           scratch = expand_unop (SImode, one_cmpl_optab, operands[2],
7274                                  NULL_RTX, 1);
7275           expand_binop (SImode, lshr_optab, scratch, GEN_INT (31),
7276                         NULL_RTX, 1, OPTAB_WIDEN);
7277           break;
7279         case GT:
7280           scratch = expand_binop (SImode, ashr_optab, operands[2],
7281                                   GEN_INT (31), NULL_RTX, 0, OPTAB_WIDEN);
7282           scratch = expand_binop (SImode, sub_optab, scratch, operands[2],
7283                                   NULL_RTX, 0, OPTAB_WIDEN);
7284           expand_binop (SImode, lshr_optab, scratch, GEN_INT (31), operands[0],
7285                         0, OPTAB_WIDEN);
7286           break;
7288         /* LT is handled by generic code.  No need for unsigned with 0.  */
7289         default:
7290           FAIL;
7291         }
7292       DONE;
7293     }
7295   switch (GET_CODE (operands[1]))
7296     {
7297     case EQ:
7298       scratch = expand_binop (SImode, sub_optab, operands[2], operands[3],
7299                               NULL_RTX, 0, OPTAB_WIDEN);
7300       emit_insn (gen_cstoresi_eq0_thumb1 (operands[0], scratch));
7301       break;
7303     case NE:
7304       scratch = expand_binop (SImode, sub_optab, operands[2], operands[3],
7305                               NULL_RTX, 0, OPTAB_WIDEN);
7306       emit_insn (gen_cstoresi_ne0_thumb1 (operands[0], scratch));
7307       break;
7309     case LE:
7310       op3 = force_reg (SImode, operands[3]);
7312       scratch = expand_binop (SImode, lshr_optab, operands[2], GEN_INT (31),
7313                               NULL_RTX, 1, OPTAB_WIDEN);
7314       scratch2 = expand_binop (SImode, ashr_optab, op3, GEN_INT (31),
7315                               NULL_RTX, 0, OPTAB_WIDEN);
7316       emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch2,
7317                                           op3, operands[2]));
7318       break;
7320     case GE:
7321       op3 = operands[3];
7322       if (!thumb1_cmp_operand (op3, SImode))
7323         op3 = force_reg (SImode, op3);
7324       scratch = expand_binop (SImode, ashr_optab, operands[2], GEN_INT (31),
7325                               NULL_RTX, 0, OPTAB_WIDEN);
7326       scratch2 = expand_binop (SImode, lshr_optab, op3, GEN_INT (31),
7327                                NULL_RTX, 1, OPTAB_WIDEN);
7328       emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch2,
7329                                           operands[2], op3));
7330       break;
7332     case LEU:
7333       op3 = force_reg (SImode, operands[3]);
7334       scratch = force_reg (SImode, const0_rtx);
7335       emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch,
7336                                           op3, operands[2]));
7337       break;
7339     case GEU:
7340       op3 = operands[3];
7341       if (!thumb1_cmp_operand (op3, SImode))
7342         op3 = force_reg (SImode, op3);
7343       scratch = force_reg (SImode, const0_rtx);
7344       emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch,
7345                                           operands[2], op3));
7346       break;
7348     case LTU:
7349       op3 = operands[3];
7350       if (!thumb1_cmp_operand (op3, SImode))
7351         op3 = force_reg (SImode, op3);
7352       scratch = gen_reg_rtx (SImode);
7353       emit_insn (gen_cstoresi_ltu_thumb1 (operands[0], operands[2], op3));
7354       break;
7356     case GTU:
7357       op3 = force_reg (SImode, operands[3]);
7358       scratch = gen_reg_rtx (SImode);
7359       emit_insn (gen_cstoresi_ltu_thumb1 (operands[0], op3, operands[2]));
7360       break;
7362     /* No good sequences for GT, LT.  */
7363     default:
7364       FAIL;
7365     }
7366   DONE;
7369 (define_expand "cstoresf4"
7370   [(set (match_operand:SI 0 "s_register_operand" "")
7371         (match_operator:SI 1 "expandable_comparison_operator"
7372          [(match_operand:SF 2 "s_register_operand" "")
7373           (match_operand:SF 3 "arm_float_compare_operand" "")]))]
7374   "TARGET_32BIT && TARGET_HARD_FLOAT"
7375   "emit_insn (gen_cstore_cc (operands[0], operands[1],
7376                              operands[2], operands[3])); DONE;"
7379 (define_expand "cstoredf4"
7380   [(set (match_operand:SI 0 "s_register_operand" "")
7381         (match_operator:SI 1 "expandable_comparison_operator"
7382          [(match_operand:DF 2 "s_register_operand" "")
7383           (match_operand:DF 3 "arm_float_compare_operand" "")]))]
7384   "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
7385   "emit_insn (gen_cstore_cc (operands[0], operands[1],
7386                              operands[2], operands[3])); DONE;"
7389 (define_expand "cstoredi4"
7390   [(set (match_operand:SI 0 "s_register_operand" "")
7391         (match_operator:SI 1 "expandable_comparison_operator"
7392          [(match_operand:DI 2 "s_register_operand" "")
7393           (match_operand:DI 3 "cmpdi_operand" "")]))]
7394   "TARGET_32BIT"
7395   "{
7396      if (!arm_validize_comparison (&operands[1],
7397                                    &operands[2],
7398                                    &operands[3]))
7399        FAIL;
7400      emit_insn (gen_cstore_cc (operands[0], operands[1], operands[2],
7401                                  operands[3]));
7402      DONE;
7403    }"
7407 ;; Conditional move insns
7409 (define_expand "movsicc"
7410   [(set (match_operand:SI 0 "s_register_operand" "")
7411         (if_then_else:SI (match_operand 1 "expandable_comparison_operator" "")
7412                          (match_operand:SI 2 "arm_not_operand" "")
7413                          (match_operand:SI 3 "arm_not_operand" "")))]
7414   "TARGET_32BIT"
7415   "
7416   {
7417     enum rtx_code code;
7418     rtx ccreg;
7420     if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0), 
7421                                   &XEXP (operands[1], 1)))
7422       FAIL;
7423     
7424     code = GET_CODE (operands[1]);
7425     ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
7426                                  XEXP (operands[1], 1), NULL_RTX);
7427     operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7428   }"
7431 (define_expand "movsfcc"
7432   [(set (match_operand:SF 0 "s_register_operand" "")
7433         (if_then_else:SF (match_operand 1 "arm_cond_move_operator" "")
7434                          (match_operand:SF 2 "s_register_operand" "")
7435                          (match_operand:SF 3 "s_register_operand" "")))]
7436   "TARGET_32BIT && TARGET_HARD_FLOAT"
7437   "
7438   {
7439     enum rtx_code code = GET_CODE (operands[1]);
7440     rtx ccreg;
7442     if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0), 
7443                                   &XEXP (operands[1], 1)))
7444        FAIL;
7446     code = GET_CODE (operands[1]);
7447     ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
7448                                  XEXP (operands[1], 1), NULL_RTX);
7449     operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7450   }"
7453 (define_expand "movdfcc"
7454   [(set (match_operand:DF 0 "s_register_operand" "")
7455         (if_then_else:DF (match_operand 1 "arm_cond_move_operator" "")
7456                          (match_operand:DF 2 "s_register_operand" "")
7457                          (match_operand:DF 3 "s_register_operand" "")))]
7458   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
7459   "
7460   {
7461     enum rtx_code code = GET_CODE (operands[1]);
7462     rtx ccreg;
7464     if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0), 
7465                                   &XEXP (operands[1], 1)))
7466        FAIL;
7467     code = GET_CODE (operands[1]);
7468     ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
7469                                  XEXP (operands[1], 1), NULL_RTX);
7470     operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7471   }"
7474 (define_insn "*cmov<mode>"
7475     [(set (match_operand:SDF 0 "s_register_operand" "=<F_constraint>")
7476         (if_then_else:SDF (match_operator 1 "arm_vsel_comparison_operator"
7477                           [(match_operand 2 "cc_register" "") (const_int 0)])
7478                           (match_operand:SDF 3 "s_register_operand"
7479                                               "<F_constraint>")
7480                           (match_operand:SDF 4 "s_register_operand"
7481                                               "<F_constraint>")))]
7482   "TARGET_HARD_FLOAT && TARGET_FPU_ARMV8 <vfp_double_cond>"
7483   "*
7484   {
7485     enum arm_cond_code code = maybe_get_arm_condition_code (operands[1]);
7486     switch (code)
7487       {
7488       case ARM_GE:
7489       case ARM_GT:
7490       case ARM_EQ:
7491       case ARM_VS:
7492         return \"vsel%d1.<V_if_elem>\\t%<V_reg>0, %<V_reg>3, %<V_reg>4\";
7493       case ARM_LT:
7494       case ARM_LE:
7495       case ARM_NE:
7496       case ARM_VC:
7497         return \"vsel%D1.<V_if_elem>\\t%<V_reg>0, %<V_reg>4, %<V_reg>3\";
7498       default:
7499         gcc_unreachable ();
7500       }
7501     return \"\";
7502   }"
7503   [(set_attr "conds" "use")
7504    (set_attr "type" "fcsel")]
7507 (define_insn_and_split "*movsicc_insn"
7508   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r,r,r,r,r")
7509         (if_then_else:SI
7510          (match_operator 3 "arm_comparison_operator"
7511           [(match_operand 4 "cc_register" "") (const_int 0)])
7512          (match_operand:SI 1 "arm_not_operand" "0,0,rI,K,rI,rI,K,K")
7513          (match_operand:SI 2 "arm_not_operand" "rI,K,0,0,rI,K,rI,K")))]
7514   "TARGET_ARM"
7515   "@
7516    mov%D3\\t%0, %2
7517    mvn%D3\\t%0, #%B2
7518    mov%d3\\t%0, %1
7519    mvn%d3\\t%0, #%B1
7520    #
7521    #
7522    #
7523    #"
7524    ; alt4: mov%d3\\t%0, %1\;mov%D3\\t%0, %2
7525    ; alt5: mov%d3\\t%0, %1\;mvn%D3\\t%0, #%B2
7526    ; alt6: mvn%d3\\t%0, #%B1\;mov%D3\\t%0, %2
7527    ; alt7: mvn%d3\\t%0, #%B1\;mvn%D3\\t%0, #%B2"
7528   "&& reload_completed"
7529   [(const_int 0)]
7530   {
7531     enum rtx_code rev_code;
7532     machine_mode mode;
7533     rtx rev_cond;
7535     emit_insn (gen_rtx_COND_EXEC (VOIDmode,
7536                                   operands[3],
7537                                   gen_rtx_SET (operands[0], operands[1])));
7539     rev_code = GET_CODE (operands[3]);
7540     mode = GET_MODE (operands[4]);
7541     if (mode == CCFPmode || mode == CCFPEmode)
7542       rev_code = reverse_condition_maybe_unordered (rev_code);
7543     else
7544       rev_code = reverse_condition (rev_code);
7546     rev_cond = gen_rtx_fmt_ee (rev_code,
7547                                VOIDmode,
7548                                operands[4],
7549                                const0_rtx);
7550     emit_insn (gen_rtx_COND_EXEC (VOIDmode,
7551                                   rev_cond,
7552                                   gen_rtx_SET (operands[0], operands[2])));
7553     DONE;
7554   }
7555   [(set_attr "length" "4,4,4,4,8,8,8,8")
7556    (set_attr "conds" "use")
7557    (set_attr_alternative "type"
7558                          [(if_then_else (match_operand 2 "const_int_operand" "")
7559                                         (const_string "mov_imm")
7560                                         (const_string "mov_reg"))
7561                           (const_string "mvn_imm")
7562                           (if_then_else (match_operand 1 "const_int_operand" "")
7563                                         (const_string "mov_imm")
7564                                         (const_string "mov_reg"))
7565                           (const_string "mvn_imm")
7566                           (const_string "multiple")
7567                           (const_string "multiple")
7568                           (const_string "multiple")
7569                           (const_string "multiple")])]
7572 (define_insn "*movsfcc_soft_insn"
7573   [(set (match_operand:SF 0 "s_register_operand" "=r,r")
7574         (if_then_else:SF (match_operator 3 "arm_comparison_operator"
7575                           [(match_operand 4 "cc_register" "") (const_int 0)])
7576                          (match_operand:SF 1 "s_register_operand" "0,r")
7577                          (match_operand:SF 2 "s_register_operand" "r,0")))]
7578   "TARGET_ARM && TARGET_SOFT_FLOAT"
7579   "@
7580    mov%D3\\t%0, %2
7581    mov%d3\\t%0, %1"
7582   [(set_attr "conds" "use")
7583    (set_attr "type" "mov_reg")]
7587 ;; Jump and linkage insns
7589 (define_expand "jump"
7590   [(set (pc)
7591         (label_ref (match_operand 0 "" "")))]
7592   "TARGET_EITHER"
7593   ""
7596 (define_insn "*arm_jump"
7597   [(set (pc)
7598         (label_ref (match_operand 0 "" "")))]
7599   "TARGET_32BIT"
7600   "*
7601   {
7602     if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
7603       {
7604         arm_ccfsm_state += 2;
7605         return \"\";
7606       }
7607     return \"b%?\\t%l0\";
7608   }
7609   "
7610   [(set_attr "predicable" "yes")
7611    (set (attr "length")
7612         (if_then_else
7613            (and (match_test "TARGET_THUMB2")
7614                 (and (ge (minus (match_dup 0) (pc)) (const_int -2044))
7615                      (le (minus (match_dup 0) (pc)) (const_int 2048))))
7616            (const_int 2)
7617            (const_int 4)))
7618    (set_attr "type" "branch")]
7621 (define_expand "call"
7622   [(parallel [(call (match_operand 0 "memory_operand" "")
7623                     (match_operand 1 "general_operand" ""))
7624               (use (match_operand 2 "" ""))
7625               (clobber (reg:SI LR_REGNUM))])]
7626   "TARGET_EITHER"
7627   "
7628   {
7629     rtx callee, pat;
7630     
7631     /* In an untyped call, we can get NULL for operand 2.  */
7632     if (operands[2] == NULL_RTX)
7633       operands[2] = const0_rtx;
7634       
7635     /* Decide if we should generate indirect calls by loading the
7636        32-bit address of the callee into a register before performing the
7637        branch and link.  */
7638     callee = XEXP (operands[0], 0);
7639     if (GET_CODE (callee) == SYMBOL_REF
7640         ? arm_is_long_call_p (SYMBOL_REF_DECL (callee))
7641         : !REG_P (callee))
7642       XEXP (operands[0], 0) = force_reg (Pmode, callee);
7644     pat = gen_call_internal (operands[0], operands[1], operands[2]);
7645     arm_emit_call_insn (pat, XEXP (operands[0], 0), false);
7646     DONE;
7647   }"
7650 (define_expand "call_internal"
7651   [(parallel [(call (match_operand 0 "memory_operand" "")
7652                     (match_operand 1 "general_operand" ""))
7653               (use (match_operand 2 "" ""))
7654               (clobber (reg:SI LR_REGNUM))])])
7656 (define_insn "*call_reg_armv5"
7657   [(call (mem:SI (match_operand:SI 0 "s_register_operand" "r"))
7658          (match_operand 1 "" ""))
7659    (use (match_operand 2 "" ""))
7660    (clobber (reg:SI LR_REGNUM))]
7661   "TARGET_ARM && arm_arch5 && !SIBLING_CALL_P (insn)"
7662   "blx%?\\t%0"
7663   [(set_attr "type" "call")]
7666 (define_insn "*call_reg_arm"
7667   [(call (mem:SI (match_operand:SI 0 "s_register_operand" "r"))
7668          (match_operand 1 "" ""))
7669    (use (match_operand 2 "" ""))
7670    (clobber (reg:SI LR_REGNUM))]
7671   "TARGET_ARM && !arm_arch5 && !SIBLING_CALL_P (insn)"
7672   "*
7673   return output_call (operands);
7674   "
7675   ;; length is worst case, normally it is only two
7676   [(set_attr "length" "12")
7677    (set_attr "type" "call")]
7681 (define_expand "call_value"
7682   [(parallel [(set (match_operand       0 "" "")
7683                    (call (match_operand 1 "memory_operand" "")
7684                          (match_operand 2 "general_operand" "")))
7685               (use (match_operand 3 "" ""))
7686               (clobber (reg:SI LR_REGNUM))])]
7687   "TARGET_EITHER"
7688   "
7689   {
7690     rtx pat, callee;
7691     
7692     /* In an untyped call, we can get NULL for operand 2.  */
7693     if (operands[3] == 0)
7694       operands[3] = const0_rtx;
7695       
7696     /* Decide if we should generate indirect calls by loading the
7697        32-bit address of the callee into a register before performing the
7698        branch and link.  */
7699     callee = XEXP (operands[1], 0);
7700     if (GET_CODE (callee) == SYMBOL_REF
7701         ? arm_is_long_call_p (SYMBOL_REF_DECL (callee))
7702         : !REG_P (callee))
7703       XEXP (operands[1], 0) = force_reg (Pmode, callee);
7705     pat = gen_call_value_internal (operands[0], operands[1],
7706                                    operands[2], operands[3]);
7707     arm_emit_call_insn (pat, XEXP (operands[1], 0), false);
7708     DONE;
7709   }"
7712 (define_expand "call_value_internal"
7713   [(parallel [(set (match_operand       0 "" "")
7714                    (call (match_operand 1 "memory_operand" "")
7715                          (match_operand 2 "general_operand" "")))
7716               (use (match_operand 3 "" ""))
7717               (clobber (reg:SI LR_REGNUM))])])
7719 (define_insn "*call_value_reg_armv5"
7720   [(set (match_operand 0 "" "")
7721         (call (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
7722               (match_operand 2 "" "")))
7723    (use (match_operand 3 "" ""))
7724    (clobber (reg:SI LR_REGNUM))]
7725   "TARGET_ARM && arm_arch5 && !SIBLING_CALL_P (insn)"
7726   "blx%?\\t%1"
7727   [(set_attr "type" "call")]
7730 (define_insn "*call_value_reg_arm"
7731   [(set (match_operand 0 "" "")
7732         (call (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
7733               (match_operand 2 "" "")))
7734    (use (match_operand 3 "" ""))
7735    (clobber (reg:SI LR_REGNUM))]
7736   "TARGET_ARM && !arm_arch5 && !SIBLING_CALL_P (insn)"
7737   "*
7738   return output_call (&operands[1]);
7739   "
7740   [(set_attr "length" "12")
7741    (set_attr "type" "call")]
7744 ;; Allow calls to SYMBOL_REFs specially as they are not valid general addresses
7745 ;; The 'a' causes the operand to be treated as an address, i.e. no '#' output.
7747 (define_insn "*call_symbol"
7748   [(call (mem:SI (match_operand:SI 0 "" ""))
7749          (match_operand 1 "" ""))
7750    (use (match_operand 2 "" ""))
7751    (clobber (reg:SI LR_REGNUM))]
7752   "TARGET_32BIT
7753    && !SIBLING_CALL_P (insn)
7754    && (GET_CODE (operands[0]) == SYMBOL_REF)
7755    && !arm_is_long_call_p (SYMBOL_REF_DECL (operands[0]))"
7756   "*
7757   {
7758    rtx op = operands[0];
7760    /* Switch mode now when possible.  */
7761    if (SYMBOL_REF_DECL (op) && !TREE_PUBLIC (SYMBOL_REF_DECL (op))
7762         && arm_arch5 && arm_change_mode_p (SYMBOL_REF_DECL (op)))
7763       return NEED_PLT_RELOC ? \"blx%?\\t%a0(PLT)\" : \"blx%?\\t(%a0)\";
7765     return NEED_PLT_RELOC ? \"bl%?\\t%a0(PLT)\" : \"bl%?\\t%a0\";
7766   }"
7767   [(set_attr "type" "call")]
7770 (define_insn "*call_value_symbol"
7771   [(set (match_operand 0 "" "")
7772         (call (mem:SI (match_operand:SI 1 "" ""))
7773         (match_operand:SI 2 "" "")))
7774    (use (match_operand 3 "" ""))
7775    (clobber (reg:SI LR_REGNUM))]
7776   "TARGET_32BIT
7777    && !SIBLING_CALL_P (insn)
7778    && (GET_CODE (operands[1]) == SYMBOL_REF)
7779    && !arm_is_long_call_p (SYMBOL_REF_DECL (operands[1]))"
7780   "*
7781   {
7782    rtx op = operands[1];
7784    /* Switch mode now when possible.  */
7785    if (SYMBOL_REF_DECL (op) && !TREE_PUBLIC (SYMBOL_REF_DECL (op))
7786         && arm_arch5 && arm_change_mode_p (SYMBOL_REF_DECL (op)))
7787       return NEED_PLT_RELOC ? \"blx%?\\t%a1(PLT)\" : \"blx%?\\t(%a1)\";
7789     return NEED_PLT_RELOC ? \"bl%?\\t%a1(PLT)\" : \"bl%?\\t%a1\";
7790   }"
7791   [(set_attr "type" "call")]
7794 (define_expand "sibcall_internal"
7795   [(parallel [(call (match_operand 0 "memory_operand" "")
7796                     (match_operand 1 "general_operand" ""))
7797               (return)
7798               (use (match_operand 2 "" ""))])])
7800 ;; We may also be able to do sibcalls for Thumb, but it's much harder...
7801 (define_expand "sibcall"
7802   [(parallel [(call (match_operand 0 "memory_operand" "")
7803                     (match_operand 1 "general_operand" ""))
7804               (return)
7805               (use (match_operand 2 "" ""))])]
7806   "TARGET_32BIT"
7807   "
7808   {
7809     rtx pat;
7811     if ((!REG_P (XEXP (operands[0], 0))
7812          && GET_CODE (XEXP (operands[0], 0)) != SYMBOL_REF)
7813         || (GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
7814             && arm_is_long_call_p (SYMBOL_REF_DECL (XEXP (operands[0], 0)))))
7815      XEXP (operands[0], 0) = force_reg (SImode, XEXP (operands[0], 0));
7817     if (operands[2] == NULL_RTX)
7818       operands[2] = const0_rtx;
7820     pat = gen_sibcall_internal (operands[0], operands[1], operands[2]);
7821     arm_emit_call_insn (pat, operands[0], true);
7822     DONE;
7823   }"
7826 (define_expand "sibcall_value_internal"
7827   [(parallel [(set (match_operand 0 "" "")
7828                    (call (match_operand 1 "memory_operand" "")
7829                          (match_operand 2 "general_operand" "")))
7830               (return)
7831               (use (match_operand 3 "" ""))])])
7833 (define_expand "sibcall_value"
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 "" ""))])]
7839   "TARGET_32BIT"
7840   "
7841   {
7842     rtx pat;
7844     if ((!REG_P (XEXP (operands[1], 0))
7845          && GET_CODE (XEXP (operands[1], 0)) != SYMBOL_REF)
7846         || (GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
7847             && arm_is_long_call_p (SYMBOL_REF_DECL (XEXP (operands[1], 0)))))
7848      XEXP (operands[1], 0) = force_reg (SImode, XEXP (operands[1], 0));
7850     if (operands[3] == NULL_RTX)
7851       operands[3] = const0_rtx;
7853     pat = gen_sibcall_value_internal (operands[0], operands[1],
7854                                       operands[2], operands[3]);
7855     arm_emit_call_insn (pat, operands[1], true);
7856     DONE;
7857   }"
7860 (define_insn "*sibcall_insn"
7861  [(call (mem:SI (match_operand:SI 0 "call_insn_operand" "Cs, US"))
7862         (match_operand 1 "" ""))
7863   (return)
7864   (use (match_operand 2 "" ""))]
7865   "TARGET_32BIT && SIBLING_CALL_P (insn)"
7866   "*
7867   if (which_alternative == 1)
7868     return NEED_PLT_RELOC ? \"b%?\\t%a0(PLT)\" : \"b%?\\t%a0\";
7869   else
7870     {
7871       if (arm_arch5 || arm_arch4t)
7872         return \"bx%?\\t%0\\t%@ indirect register sibling call\";
7873       else
7874         return \"mov%?\\t%|pc, %0\\t%@ indirect register sibling call\";
7875     }
7876   "
7877   [(set_attr "type" "call")]
7880 (define_insn "*sibcall_value_insn"
7881  [(set (match_operand 0 "" "")
7882        (call (mem:SI (match_operand:SI 1 "call_insn_operand" "Cs,US"))
7883              (match_operand 2 "" "")))
7884   (return)
7885   (use (match_operand 3 "" ""))]
7886   "TARGET_32BIT && SIBLING_CALL_P (insn)"
7887   "*
7888   if (which_alternative == 1)
7889    return NEED_PLT_RELOC ? \"b%?\\t%a1(PLT)\" : \"b%?\\t%a1\";
7890   else
7891     {
7892       if (arm_arch5 || arm_arch4t)
7893         return \"bx%?\\t%1\";
7894       else
7895         return \"mov%?\\t%|pc, %1\\t@ indirect sibling call \";
7896     }
7897   "
7898   [(set_attr "type" "call")]
7901 (define_expand "<return_str>return"
7902   [(RETURNS)]
7903   "(TARGET_ARM || (TARGET_THUMB2
7904                    && ARM_FUNC_TYPE (arm_current_func_type ()) == ARM_FT_NORMAL
7905                    && !IS_STACKALIGN (arm_current_func_type ())))
7906     <return_cond_false>"
7907   "
7908   {
7909     if (TARGET_THUMB2)
7910       {
7911         thumb2_expand_return (<return_simple_p>);
7912         DONE;
7913       }
7914   }
7915   "
7918 ;; Often the return insn will be the same as loading from memory, so set attr
7919 (define_insn "*arm_return"
7920   [(return)]
7921   "TARGET_ARM && USE_RETURN_INSN (FALSE)"
7922   "*
7923   {
7924     if (arm_ccfsm_state == 2)
7925       {
7926         arm_ccfsm_state += 2;
7927         return \"\";
7928       }
7929     return output_return_instruction (const_true_rtx, true, false, false);
7930   }"
7931   [(set_attr "type" "load1")
7932    (set_attr "length" "12")
7933    (set_attr "predicable" "yes")]
7936 (define_insn "*cond_<return_str>return"
7937   [(set (pc)
7938         (if_then_else (match_operator 0 "arm_comparison_operator"
7939                        [(match_operand 1 "cc_register" "") (const_int 0)])
7940                       (RETURNS)
7941                       (pc)))]
7942   "TARGET_ARM  <return_cond_true>"
7943   "*
7944   {
7945     if (arm_ccfsm_state == 2)
7946       {
7947         arm_ccfsm_state += 2;
7948         return \"\";
7949       }
7950     return output_return_instruction (operands[0], true, false,
7951                                       <return_simple_p>);
7952   }"
7953   [(set_attr "conds" "use")
7954    (set_attr "length" "12")
7955    (set_attr "type" "load1")]
7958 (define_insn "*cond_<return_str>return_inverted"
7959   [(set (pc)
7960         (if_then_else (match_operator 0 "arm_comparison_operator"
7961                        [(match_operand 1 "cc_register" "") (const_int 0)])
7962                       (pc)
7963                       (RETURNS)))]
7964   "TARGET_ARM <return_cond_true>"
7965   "*
7966   {
7967     if (arm_ccfsm_state == 2)
7968       {
7969         arm_ccfsm_state += 2;
7970         return \"\";
7971       }
7972     return output_return_instruction (operands[0], true, true,
7973                                       <return_simple_p>);
7974   }"
7975   [(set_attr "conds" "use")
7976    (set_attr "length" "12")
7977    (set_attr "type" "load1")]
7980 (define_insn "*arm_simple_return"
7981   [(simple_return)]
7982   "TARGET_ARM"
7983   "*
7984   {
7985     if (arm_ccfsm_state == 2)
7986       {
7987         arm_ccfsm_state += 2;
7988         return \"\";
7989       }
7990     return output_return_instruction (const_true_rtx, true, false, true);
7991   }"
7992   [(set_attr "type" "branch")
7993    (set_attr "length" "4")
7994    (set_attr "predicable" "yes")]
7997 ;; Generate a sequence of instructions to determine if the processor is
7998 ;; in 26-bit or 32-bit mode, and return the appropriate return address
7999 ;; mask.
8001 (define_expand "return_addr_mask"
8002   [(set (match_dup 1)
8003       (compare:CC_NOOV (unspec [(const_int 0)] UNSPEC_CHECK_ARCH)
8004                        (const_int 0)))
8005    (set (match_operand:SI 0 "s_register_operand" "")
8006       (if_then_else:SI (eq (match_dup 1) (const_int 0))
8007                        (const_int -1)
8008                        (const_int 67108860)))] ; 0x03fffffc
8009   "TARGET_ARM"
8010   "
8011   operands[1] = gen_rtx_REG (CC_NOOVmode, CC_REGNUM);
8012   ")
8014 (define_insn "*check_arch2"
8015   [(set (match_operand:CC_NOOV 0 "cc_register" "")
8016       (compare:CC_NOOV (unspec [(const_int 0)] UNSPEC_CHECK_ARCH)
8017                        (const_int 0)))]
8018   "TARGET_ARM"
8019   "teq\\t%|r0, %|r0\;teq\\t%|pc, %|pc"
8020   [(set_attr "length" "8")
8021    (set_attr "conds" "set")
8022    (set_attr "type" "multiple")]
8025 ;; Call subroutine returning any type.
8027 (define_expand "untyped_call"
8028   [(parallel [(call (match_operand 0 "" "")
8029                     (const_int 0))
8030               (match_operand 1 "" "")
8031               (match_operand 2 "" "")])]
8032   "TARGET_EITHER"
8033   "
8034   {
8035     int i;
8036     rtx par = gen_rtx_PARALLEL (VOIDmode,
8037                                 rtvec_alloc (XVECLEN (operands[2], 0)));
8038     rtx addr = gen_reg_rtx (Pmode);
8039     rtx mem;
8040     int size = 0;
8042     emit_move_insn (addr, XEXP (operands[1], 0));
8043     mem = change_address (operands[1], BLKmode, addr);
8045     for (i = 0; i < XVECLEN (operands[2], 0); i++)
8046       {
8047         rtx src = SET_SRC (XVECEXP (operands[2], 0, i));
8049         /* Default code only uses r0 as a return value, but we could
8050            be using anything up to 4 registers.  */
8051         if (REGNO (src) == R0_REGNUM)
8052           src = gen_rtx_REG (TImode, R0_REGNUM);
8054         XVECEXP (par, 0, i) = gen_rtx_EXPR_LIST (VOIDmode, src,
8055                                                  GEN_INT (size));
8056         size += GET_MODE_SIZE (GET_MODE (src));
8057       }
8059     emit_call_insn (gen_call_value (par, operands[0], const0_rtx, NULL));
8061     size = 0;
8063     for (i = 0; i < XVECLEN (par, 0); i++)
8064       {
8065         HOST_WIDE_INT offset = 0;
8066         rtx reg = XEXP (XVECEXP (par, 0, i), 0);
8068         if (size != 0)
8069           emit_move_insn (addr, plus_constant (Pmode, addr, size));
8071         mem = change_address (mem, GET_MODE (reg), NULL);
8072         if (REGNO (reg) == R0_REGNUM)
8073           {
8074             /* On thumb we have to use a write-back instruction.  */
8075             emit_insn (arm_gen_store_multiple (arm_regs_in_sequence, 4, addr,
8076                        TARGET_THUMB ? TRUE : FALSE, mem, &offset));
8077             size = TARGET_ARM ? 16 : 0;
8078           }
8079         else
8080           {
8081             emit_move_insn (mem, reg);
8082             size = GET_MODE_SIZE (GET_MODE (reg));
8083           }
8084       }
8086     /* The optimizer does not know that the call sets the function value
8087        registers we stored in the result block.  We avoid problems by
8088        claiming that all hard registers are used and clobbered at this
8089        point.  */
8090     emit_insn (gen_blockage ());
8092     DONE;
8093   }"
8096 (define_expand "untyped_return"
8097   [(match_operand:BLK 0 "memory_operand" "")
8098    (match_operand 1 "" "")]
8099   "TARGET_EITHER"
8100   "
8101   {
8102     int i;
8103     rtx addr = gen_reg_rtx (Pmode);
8104     rtx mem;
8105     int size = 0;
8107     emit_move_insn (addr, XEXP (operands[0], 0));
8108     mem = change_address (operands[0], BLKmode, addr);
8110     for (i = 0; i < XVECLEN (operands[1], 0); i++)
8111       {
8112         HOST_WIDE_INT offset = 0;
8113         rtx reg = SET_DEST (XVECEXP (operands[1], 0, i));
8115         if (size != 0)
8116           emit_move_insn (addr, plus_constant (Pmode, addr, size));
8118         mem = change_address (mem, GET_MODE (reg), NULL);
8119         if (REGNO (reg) == R0_REGNUM)
8120           {
8121             /* On thumb we have to use a write-back instruction.  */
8122             emit_insn (arm_gen_load_multiple (arm_regs_in_sequence, 4, addr,
8123                        TARGET_THUMB ? TRUE : FALSE, mem, &offset));
8124             size = TARGET_ARM ? 16 : 0;
8125           }
8126         else
8127           {
8128             emit_move_insn (reg, mem);
8129             size = GET_MODE_SIZE (GET_MODE (reg));
8130           }
8131       }
8133     /* Emit USE insns before the return.  */
8134     for (i = 0; i < XVECLEN (operands[1], 0); i++)
8135       emit_use (SET_DEST (XVECEXP (operands[1], 0, i)));
8137     /* Construct the return.  */
8138     expand_naked_return ();
8140     DONE;
8141   }"
8144 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
8145 ;; all of memory.  This blocks insns from being moved across this point.
8147 (define_insn "blockage"
8148   [(unspec_volatile [(const_int 0)] VUNSPEC_BLOCKAGE)]
8149   "TARGET_EITHER"
8150   ""
8151   [(set_attr "length" "0")
8152    (set_attr "type" "block")]
8155 (define_insn "probe_stack"
8156   [(set (match_operand:SI 0 "memory_operand" "=m")
8157         (unspec:SI [(const_int 0)] UNSPEC_PROBE_STACK))]
8158   "TARGET_32BIT"
8159   "str%?\\tr0, %0"
8160   [(set_attr "type" "store1")
8161    (set_attr "predicable" "yes")]
8164 (define_insn "probe_stack_range"
8165   [(set (match_operand:SI 0 "register_operand" "=r")
8166         (unspec_volatile:SI [(match_operand:SI 1 "register_operand" "0")
8167                              (match_operand:SI 2 "register_operand" "r")]
8168                              VUNSPEC_PROBE_STACK_RANGE))]
8169   "TARGET_32BIT"
8171   return output_probe_stack_range (operands[0], operands[2]);
8173   [(set_attr "type" "multiple")
8174    (set_attr "conds" "clob")]
8177 (define_expand "casesi"
8178   [(match_operand:SI 0 "s_register_operand" "") ; index to jump on
8179    (match_operand:SI 1 "const_int_operand" "")  ; lower bound
8180    (match_operand:SI 2 "const_int_operand" "")  ; total range
8181    (match_operand:SI 3 "" "")                   ; table label
8182    (match_operand:SI 4 "" "")]                  ; Out of range label
8183   "TARGET_32BIT || optimize_size || flag_pic"
8184   "
8185   {
8186     enum insn_code code;
8187     if (operands[1] != const0_rtx)
8188       {
8189         rtx reg = gen_reg_rtx (SImode);
8191         emit_insn (gen_addsi3 (reg, operands[0],
8192                                gen_int_mode (-INTVAL (operands[1]),
8193                                              SImode)));
8194         operands[0] = reg;
8195       }
8197     if (TARGET_ARM)
8198       code = CODE_FOR_arm_casesi_internal;
8199     else if (TARGET_THUMB1)
8200       code = CODE_FOR_thumb1_casesi_internal_pic;
8201     else if (flag_pic)
8202       code = CODE_FOR_thumb2_casesi_internal_pic;
8203     else
8204       code = CODE_FOR_thumb2_casesi_internal;
8206     if (!insn_data[(int) code].operand[1].predicate(operands[2], SImode))
8207       operands[2] = force_reg (SImode, operands[2]);
8209     emit_jump_insn (GEN_FCN ((int) code) (operands[0], operands[2],
8210                                           operands[3], operands[4]));
8211     DONE;
8212   }"
8215 ;; The USE in this pattern is needed to tell flow analysis that this is
8216 ;; a CASESI insn.  It has no other purpose.
8217 (define_insn "arm_casesi_internal"
8218   [(parallel [(set (pc)
8219                (if_then_else
8220                 (leu (match_operand:SI 0 "s_register_operand" "r")
8221                      (match_operand:SI 1 "arm_rhs_operand" "rI"))
8222                 (mem:SI (plus:SI (mult:SI (match_dup 0) (const_int 4))
8223                                  (label_ref (match_operand 2 "" ""))))
8224                 (label_ref (match_operand 3 "" ""))))
8225               (clobber (reg:CC CC_REGNUM))
8226               (use (label_ref (match_dup 2)))])]
8227   "TARGET_ARM"
8228   "*
8229     if (flag_pic)
8230       return \"cmp\\t%0, %1\;addls\\t%|pc, %|pc, %0, asl #2\;b\\t%l3\";
8231     return   \"cmp\\t%0, %1\;ldrls\\t%|pc, [%|pc, %0, asl #2]\;b\\t%l3\";
8232   "
8233   [(set_attr "conds" "clob")
8234    (set_attr "length" "12")
8235    (set_attr "type" "multiple")]
8238 (define_expand "indirect_jump"
8239   [(set (pc)
8240         (match_operand:SI 0 "s_register_operand" ""))]
8241   "TARGET_EITHER"
8242   "
8243   /* Thumb-2 doesn't have mov pc, reg.  Explicitly set the low bit of the
8244      address and use bx.  */
8245   if (TARGET_THUMB2)
8246     {
8247       rtx tmp;
8248       tmp = gen_reg_rtx (SImode);
8249       emit_insn (gen_iorsi3 (tmp, operands[0], GEN_INT(1)));
8250       operands[0] = tmp;
8251     }
8252   "
8255 ;; NB Never uses BX.
8256 (define_insn "*arm_indirect_jump"
8257   [(set (pc)
8258         (match_operand:SI 0 "s_register_operand" "r"))]
8259   "TARGET_ARM"
8260   "mov%?\\t%|pc, %0\\t%@ indirect register jump"
8261   [(set_attr "predicable" "yes")
8262    (set_attr "type" "branch")]
8265 (define_insn "*load_indirect_jump"
8266   [(set (pc)
8267         (match_operand:SI 0 "memory_operand" "m"))]
8268   "TARGET_ARM"
8269   "ldr%?\\t%|pc, %0\\t%@ indirect memory jump"
8270   [(set_attr "type" "load1")
8271    (set_attr "pool_range" "4096")
8272    (set_attr "neg_pool_range" "4084")
8273    (set_attr "predicable" "yes")]
8277 ;; Misc insns
8279 (define_insn "nop"
8280   [(const_int 0)]
8281   "TARGET_EITHER"
8282   "nop"
8283   [(set (attr "length")
8284         (if_then_else (eq_attr "is_thumb" "yes")
8285                       (const_int 2)
8286                       (const_int 4)))
8287    (set_attr "type" "mov_reg")]
8290 (define_insn "trap"
8291   [(trap_if (const_int 1) (const_int 0))]
8292   ""
8293   "*
8294   if (TARGET_ARM)
8295     return \".inst\\t0xe7f000f0\";
8296   else
8297     return \".inst\\t0xdeff\";
8298   "
8299   [(set (attr "length")
8300         (if_then_else (eq_attr "is_thumb" "yes")
8301                       (const_int 2)
8302                       (const_int 4)))
8303    (set_attr "type" "trap")
8304    (set_attr "conds" "unconditional")]
8308 ;; Patterns to allow combination of arithmetic, cond code and shifts
8310 (define_insn "*<arith_shift_insn>_multsi"
8311   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8312         (SHIFTABLE_OPS:SI
8313          (mult:SI (match_operand:SI 2 "s_register_operand" "r,r")
8314                   (match_operand:SI 3 "power_of_two_operand" ""))
8315          (match_operand:SI 1 "s_register_operand" "rk,<t2_binop0>")))]
8316   "TARGET_32BIT"
8317   "<arith_shift_insn>%?\\t%0, %1, %2, lsl %b3"
8318   [(set_attr "predicable" "yes")
8319    (set_attr "predicable_short_it" "no")
8320    (set_attr "shift" "2")
8321    (set_attr "arch" "a,t2")
8322    (set_attr "type" "alu_shift_imm")])
8324 (define_insn "*<arith_shift_insn>_shiftsi"
8325   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
8326         (SHIFTABLE_OPS:SI
8327          (match_operator:SI 2 "shift_nomul_operator"
8328           [(match_operand:SI 3 "s_register_operand" "r,r,r")
8329            (match_operand:SI 4 "shift_amount_operand" "M,M,r")])
8330          (match_operand:SI 1 "s_register_operand" "rk,<t2_binop0>,rk")))]
8331   "TARGET_32BIT && GET_CODE (operands[2]) != MULT"
8332   "<arith_shift_insn>%?\\t%0, %1, %3%S2"
8333   [(set_attr "predicable" "yes")
8334    (set_attr "predicable_short_it" "no")
8335    (set_attr "shift" "3")
8336    (set_attr "arch" "a,t2,a")
8337    (set_attr "type" "alu_shift_imm,alu_shift_imm,alu_shift_reg")])
8339 (define_split
8340   [(set (match_operand:SI 0 "s_register_operand" "")
8341         (match_operator:SI 1 "shiftable_operator"
8342          [(match_operator:SI 2 "shiftable_operator"
8343            [(match_operator:SI 3 "shift_operator"
8344              [(match_operand:SI 4 "s_register_operand" "")
8345               (match_operand:SI 5 "reg_or_int_operand" "")])
8346             (match_operand:SI 6 "s_register_operand" "")])
8347           (match_operand:SI 7 "arm_rhs_operand" "")]))
8348    (clobber (match_operand:SI 8 "s_register_operand" ""))]
8349   "TARGET_32BIT"
8350   [(set (match_dup 8)
8351         (match_op_dup 2 [(match_op_dup 3 [(match_dup 4) (match_dup 5)])
8352                          (match_dup 6)]))
8353    (set (match_dup 0)
8354         (match_op_dup 1 [(match_dup 8) (match_dup 7)]))]
8355   "")
8357 (define_insn "*arith_shiftsi_compare0"
8358   [(set (reg:CC_NOOV CC_REGNUM)
8359         (compare:CC_NOOV
8360          (match_operator:SI 1 "shiftable_operator"
8361           [(match_operator:SI 3 "shift_operator"
8362             [(match_operand:SI 4 "s_register_operand" "r,r")
8363              (match_operand:SI 5 "shift_amount_operand" "M,r")])
8364            (match_operand:SI 2 "s_register_operand" "r,r")])
8365          (const_int 0)))
8366    (set (match_operand:SI 0 "s_register_operand" "=r,r")
8367         (match_op_dup 1 [(match_op_dup 3 [(match_dup 4) (match_dup 5)])
8368                          (match_dup 2)]))]
8369   "TARGET_32BIT"
8370   "%i1s%?\\t%0, %2, %4%S3"
8371   [(set_attr "conds" "set")
8372    (set_attr "shift" "4")
8373    (set_attr "arch" "32,a")
8374    (set_attr "type" "alus_shift_imm,alus_shift_reg")])
8376 (define_insn "*arith_shiftsi_compare0_scratch"
8377   [(set (reg:CC_NOOV CC_REGNUM)
8378         (compare:CC_NOOV
8379          (match_operator:SI 1 "shiftable_operator"
8380           [(match_operator:SI 3 "shift_operator"
8381             [(match_operand:SI 4 "s_register_operand" "r,r")
8382              (match_operand:SI 5 "shift_amount_operand" "M,r")])
8383            (match_operand:SI 2 "s_register_operand" "r,r")])
8384          (const_int 0)))
8385    (clobber (match_scratch:SI 0 "=r,r"))]
8386   "TARGET_32BIT"
8387   "%i1s%?\\t%0, %2, %4%S3"
8388   [(set_attr "conds" "set")
8389    (set_attr "shift" "4")
8390    (set_attr "arch" "32,a")
8391    (set_attr "type" "alus_shift_imm,alus_shift_reg")])
8393 (define_insn "*sub_shiftsi"
8394   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8395         (minus:SI (match_operand:SI 1 "s_register_operand" "r,r")
8396                   (match_operator:SI 2 "shift_operator"
8397                    [(match_operand:SI 3 "s_register_operand" "r,r")
8398                     (match_operand:SI 4 "shift_amount_operand" "M,r")])))]
8399   "TARGET_32BIT"
8400   "sub%?\\t%0, %1, %3%S2"
8401   [(set_attr "predicable" "yes")
8402    (set_attr "shift" "3")
8403    (set_attr "arch" "32,a")
8404    (set_attr "type" "alus_shift_imm,alus_shift_reg")])
8406 (define_insn "*sub_shiftsi_compare0"
8407   [(set (reg:CC_NOOV CC_REGNUM)
8408         (compare:CC_NOOV
8409          (minus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
8410                    (match_operator:SI 2 "shift_operator"
8411                     [(match_operand:SI 3 "s_register_operand" "r,r,r")
8412                      (match_operand:SI 4 "shift_amount_operand" "M,r,M")]))
8413          (const_int 0)))
8414    (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
8415         (minus:SI (match_dup 1)
8416                   (match_op_dup 2 [(match_dup 3) (match_dup 4)])))]
8417   "TARGET_32BIT"
8418   "subs%?\\t%0, %1, %3%S2"
8419   [(set_attr "conds" "set")
8420    (set_attr "shift" "3")
8421    (set_attr "arch" "32,a,a")
8422    (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
8424 (define_insn "*sub_shiftsi_compare0_scratch"
8425   [(set (reg:CC_NOOV CC_REGNUM)
8426         (compare:CC_NOOV
8427          (minus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
8428                    (match_operator:SI 2 "shift_operator"
8429                     [(match_operand:SI 3 "s_register_operand" "r,r,r")
8430                      (match_operand:SI 4 "shift_amount_operand" "M,r,M")]))
8431          (const_int 0)))
8432    (clobber (match_scratch:SI 0 "=r,r,r"))]
8433   "TARGET_32BIT"
8434   "subs%?\\t%0, %1, %3%S2"
8435   [(set_attr "conds" "set")
8436    (set_attr "shift" "3")
8437    (set_attr "arch" "32,a,a")
8438    (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
8441 (define_insn_and_split "*and_scc"
8442   [(set (match_operand:SI 0 "s_register_operand" "=r")
8443         (and:SI (match_operator:SI 1 "arm_comparison_operator"
8444                  [(match_operand 2 "cc_register" "") (const_int 0)])
8445                 (match_operand:SI 3 "s_register_operand" "r")))]
8446   "TARGET_ARM"
8447   "#"   ; "mov%D1\\t%0, #0\;and%d1\\t%0, %3, #1"
8448   "&& reload_completed"
8449   [(cond_exec (match_dup 5) (set (match_dup 0) (const_int 0)))
8450    (cond_exec (match_dup 4) (set (match_dup 0)
8451                                  (and:SI (match_dup 3) (const_int 1))))]
8452   {
8453     machine_mode mode = GET_MODE (operands[2]);
8454     enum rtx_code rc = GET_CODE (operands[1]);
8456     /* Note that operands[4] is the same as operands[1],
8457        but with VOIDmode as the result. */
8458     operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
8459     if (mode == CCFPmode || mode == CCFPEmode)
8460       rc = reverse_condition_maybe_unordered (rc);
8461     else
8462       rc = reverse_condition (rc);
8463     operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
8464   }
8465   [(set_attr "conds" "use")
8466    (set_attr "type" "multiple")
8467    (set_attr "length" "8")]
8470 (define_insn_and_split "*ior_scc"
8471   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8472         (ior:SI (match_operator:SI 1 "arm_comparison_operator"
8473                  [(match_operand 2 "cc_register" "") (const_int 0)])
8474                 (match_operand:SI 3 "s_register_operand" "0,?r")))]
8475   "TARGET_ARM"
8476   "@
8477    orr%d1\\t%0, %3, #1
8478    #"
8479   "&& reload_completed
8480    && REGNO (operands [0]) != REGNO (operands[3])"
8481   ;; && which_alternative == 1
8482   ; mov%D1\\t%0, %3\;orr%d1\\t%0, %3, #1
8483   [(cond_exec (match_dup 5) (set (match_dup 0) (match_dup 3)))
8484    (cond_exec (match_dup 4) (set (match_dup 0)
8485                                  (ior:SI (match_dup 3) (const_int 1))))]
8486   {
8487     machine_mode mode = GET_MODE (operands[2]);
8488     enum rtx_code rc = GET_CODE (operands[1]);
8490     /* Note that operands[4] is the same as operands[1],
8491        but with VOIDmode as the result. */
8492     operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
8493     if (mode == CCFPmode || mode == CCFPEmode)
8494       rc = reverse_condition_maybe_unordered (rc);
8495     else
8496       rc = reverse_condition (rc);
8497     operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
8498   }
8499   [(set_attr "conds" "use")
8500    (set_attr "length" "4,8")
8501    (set_attr "type" "logic_imm,multiple")]
8504 ; A series of splitters for the compare_scc pattern below.  Note that
8505 ; order is important.
8506 (define_split
8507   [(set (match_operand:SI 0 "s_register_operand" "")
8508         (lt:SI (match_operand:SI 1 "s_register_operand" "")
8509                (const_int 0)))
8510    (clobber (reg:CC CC_REGNUM))]
8511   "TARGET_32BIT && reload_completed"
8512   [(set (match_dup 0) (lshiftrt:SI (match_dup 1) (const_int 31)))])
8514 (define_split
8515   [(set (match_operand:SI 0 "s_register_operand" "")
8516         (ge:SI (match_operand:SI 1 "s_register_operand" "")
8517                (const_int 0)))
8518    (clobber (reg:CC CC_REGNUM))]
8519   "TARGET_32BIT && reload_completed"
8520   [(set (match_dup 0) (not:SI (match_dup 1)))
8521    (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 31)))])
8523 (define_split
8524   [(set (match_operand:SI 0 "s_register_operand" "")
8525         (eq:SI (match_operand:SI 1 "s_register_operand" "")
8526                (const_int 0)))
8527    (clobber (reg:CC CC_REGNUM))]
8528   "arm_arch5 && TARGET_32BIT"
8529   [(set (match_dup 0) (clz:SI (match_dup 1)))
8530    (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
8533 (define_split
8534   [(set (match_operand:SI 0 "s_register_operand" "")
8535         (eq:SI (match_operand:SI 1 "s_register_operand" "")
8536                (const_int 0)))
8537    (clobber (reg:CC CC_REGNUM))]
8538   "TARGET_32BIT && reload_completed"
8539   [(parallel
8540     [(set (reg:CC CC_REGNUM)
8541           (compare:CC (const_int 1) (match_dup 1)))
8542      (set (match_dup 0)
8543           (minus:SI (const_int 1) (match_dup 1)))])
8544    (cond_exec (ltu:CC (reg:CC CC_REGNUM) (const_int 0))
8545               (set (match_dup 0) (const_int 0)))])
8547 (define_split
8548   [(set (match_operand:SI 0 "s_register_operand" "")
8549         (ne:SI (match_operand:SI 1 "s_register_operand" "")
8550                (match_operand:SI 2 "const_int_operand" "")))
8551    (clobber (reg:CC CC_REGNUM))]
8552   "TARGET_32BIT && reload_completed"
8553   [(parallel
8554     [(set (reg:CC CC_REGNUM)
8555           (compare:CC (match_dup 1) (match_dup 2)))
8556      (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 3)))])
8557    (cond_exec (ne:CC (reg:CC CC_REGNUM) (const_int 0))
8558               (set (match_dup 0) (const_int 1)))]
8560   operands[3] = GEN_INT (-INTVAL (operands[2]));
8563 (define_split
8564   [(set (match_operand:SI 0 "s_register_operand" "")
8565         (ne:SI (match_operand:SI 1 "s_register_operand" "")
8566                (match_operand:SI 2 "arm_add_operand" "")))
8567    (clobber (reg:CC CC_REGNUM))]
8568   "TARGET_32BIT && reload_completed"
8569   [(parallel
8570     [(set (reg:CC_NOOV CC_REGNUM)
8571           (compare:CC_NOOV (minus:SI (match_dup 1) (match_dup 2))
8572                            (const_int 0)))
8573      (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
8574    (cond_exec (ne:CC_NOOV (reg:CC_NOOV CC_REGNUM) (const_int 0))
8575               (set (match_dup 0) (const_int 1)))])
8577 (define_insn_and_split "*compare_scc"
8578   [(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts")
8579         (match_operator:SI 1 "arm_comparison_operator"
8580          [(match_operand:SI 2 "s_register_operand" "r,r")
8581           (match_operand:SI 3 "arm_add_operand" "rI,L")]))
8582    (clobber (reg:CC CC_REGNUM))]
8583   "TARGET_32BIT"
8584   "#"
8585   "&& reload_completed"
8586   [(set (reg:CC CC_REGNUM) (compare:CC (match_dup 2) (match_dup 3)))
8587    (cond_exec (match_dup 4) (set (match_dup 0) (const_int 0)))
8588    (cond_exec (match_dup 5) (set (match_dup 0) (const_int 1)))]
8590   rtx tmp1;
8591   machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
8592                                            operands[2], operands[3]);
8593   enum rtx_code rc = GET_CODE (operands[1]);
8595   tmp1 = gen_rtx_REG (mode, CC_REGNUM);
8597   operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, tmp1, const0_rtx);
8598   if (mode == CCFPmode || mode == CCFPEmode)
8599     rc = reverse_condition_maybe_unordered (rc);
8600   else
8601     rc = reverse_condition (rc);
8602   operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, tmp1, const0_rtx);
8604   [(set_attr "type" "multiple")]
8607 ;; Attempt to improve the sequence generated by the compare_scc splitters
8608 ;; not to use conditional execution.
8610 ;; Rd = (eq (reg1) (const_int0))  // ARMv5
8611 ;;      clz Rd, reg1
8612 ;;      lsr Rd, Rd, #5
8613 (define_peephole2
8614   [(set (reg:CC CC_REGNUM)
8615         (compare:CC (match_operand:SI 1 "register_operand" "")
8616                     (const_int 0)))
8617    (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
8618               (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
8619    (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
8620               (set (match_dup 0) (const_int 1)))]
8621   "arm_arch5 && TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
8622   [(set (match_dup 0) (clz:SI (match_dup 1)))
8623    (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
8626 ;; Rd = (eq (reg1) (const_int0))  // !ARMv5
8627 ;;      negs Rd, reg1
8628 ;;      adc  Rd, Rd, reg1
8629 (define_peephole2
8630   [(set (reg:CC CC_REGNUM)
8631         (compare:CC (match_operand:SI 1 "register_operand" "")
8632                     (const_int 0)))
8633    (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
8634               (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
8635    (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
8636               (set (match_dup 0) (const_int 1)))
8637    (match_scratch:SI 2 "r")]
8638   "TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
8639   [(parallel
8640     [(set (reg:CC CC_REGNUM)
8641           (compare:CC (const_int 0) (match_dup 1)))
8642      (set (match_dup 2) (minus:SI (const_int 0) (match_dup 1)))])
8643    (set (match_dup 0)
8644         (plus:SI (plus:SI (match_dup 1) (match_dup 2))
8645                  (geu:SI (reg:CC CC_REGNUM) (const_int 0))))]
8648 ;; Rd = (eq (reg1) (reg2/imm))  // ARMv5 and optimising for speed.
8649 ;;      sub  Rd, Reg1, reg2
8650 ;;      clz  Rd, Rd
8651 ;;      lsr  Rd, Rd, #5
8652 (define_peephole2
8653   [(set (reg:CC CC_REGNUM)
8654         (compare:CC (match_operand:SI 1 "register_operand" "")
8655                     (match_operand:SI 2 "arm_rhs_operand" "")))
8656    (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
8657               (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
8658    (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
8659               (set (match_dup 0) (const_int 1)))]
8660   "arm_arch5 && TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)
8661   && !(TARGET_THUMB2 && optimize_insn_for_size_p ())"
8662   [(set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))
8663    (set (match_dup 0) (clz:SI (match_dup 0)))
8664    (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
8668 ;; Rd = (eq (reg1) (reg2))      // ! ARMv5 or optimising for size.
8669 ;;      sub  T1, Reg1, reg2
8670 ;;      negs Rd, T1
8671 ;;      adc  Rd, Rd, T1
8672 (define_peephole2
8673   [(set (reg:CC CC_REGNUM)
8674         (compare:CC (match_operand:SI 1 "register_operand" "")
8675                     (match_operand:SI 2 "arm_rhs_operand" "")))
8676    (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
8677               (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
8678    (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
8679               (set (match_dup 0) (const_int 1)))
8680    (match_scratch:SI 3 "r")]
8681   "TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
8682   [(set (match_dup 3) (match_dup 4))
8683    (parallel
8684     [(set (reg:CC CC_REGNUM)
8685           (compare:CC (const_int 0) (match_dup 3)))
8686      (set (match_dup 0) (minus:SI (const_int 0) (match_dup 3)))])
8687    (set (match_dup 0)
8688         (plus:SI (plus:SI (match_dup 0) (match_dup 3))
8689                  (geu:SI (reg:CC CC_REGNUM) (const_int 0))))]
8690   "
8691   if (CONST_INT_P (operands[2]))
8692     operands[4] = plus_constant (SImode, operands[1], -INTVAL (operands[2]));
8693   else
8694     operands[4] = gen_rtx_MINUS (SImode, operands[1], operands[2]);
8695   ")
8697 (define_insn "*cond_move"
8698   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
8699         (if_then_else:SI (match_operator 3 "equality_operator"
8700                           [(match_operator 4 "arm_comparison_operator"
8701                             [(match_operand 5 "cc_register" "") (const_int 0)])
8702                            (const_int 0)])
8703                          (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
8704                          (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))]
8705   "TARGET_ARM"
8706   "*
8707     if (GET_CODE (operands[3]) == NE)
8708       {
8709         if (which_alternative != 1)
8710           output_asm_insn (\"mov%D4\\t%0, %2\", operands);
8711         if (which_alternative != 0)
8712           output_asm_insn (\"mov%d4\\t%0, %1\", operands);
8713         return \"\";
8714       }
8715     if (which_alternative != 0)
8716       output_asm_insn (\"mov%D4\\t%0, %1\", operands);
8717     if (which_alternative != 1)
8718       output_asm_insn (\"mov%d4\\t%0, %2\", operands);
8719     return \"\";
8720   "
8721   [(set_attr "conds" "use")
8722    (set_attr_alternative "type"
8723                          [(if_then_else (match_operand 2 "const_int_operand" "")
8724                                         (const_string "mov_imm")
8725                                         (const_string "mov_reg"))
8726                           (if_then_else (match_operand 1 "const_int_operand" "")
8727                                         (const_string "mov_imm")
8728                                         (const_string "mov_reg"))
8729                           (const_string "multiple")])
8730    (set_attr "length" "4,4,8")]
8733 (define_insn "*cond_arith"
8734   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8735         (match_operator:SI 5 "shiftable_operator" 
8736          [(match_operator:SI 4 "arm_comparison_operator"
8737            [(match_operand:SI 2 "s_register_operand" "r,r")
8738             (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
8739           (match_operand:SI 1 "s_register_operand" "0,?r")]))
8740    (clobber (reg:CC CC_REGNUM))]
8741   "TARGET_ARM"
8742   "*
8743     if (GET_CODE (operands[4]) == LT && operands[3] == const0_rtx)
8744       return \"%i5\\t%0, %1, %2, lsr #31\";
8746     output_asm_insn (\"cmp\\t%2, %3\", operands);
8747     if (GET_CODE (operands[5]) == AND)
8748       output_asm_insn (\"mov%D4\\t%0, #0\", operands);
8749     else if (GET_CODE (operands[5]) == MINUS)
8750       output_asm_insn (\"rsb%D4\\t%0, %1, #0\", operands);
8751     else if (which_alternative != 0)
8752       output_asm_insn (\"mov%D4\\t%0, %1\", operands);
8753     return \"%i5%d4\\t%0, %1, #1\";
8754   "
8755   [(set_attr "conds" "clob")
8756    (set_attr "length" "12")
8757    (set_attr "type" "multiple")]
8760 (define_insn "*cond_sub"
8761   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8762         (minus:SI (match_operand:SI 1 "s_register_operand" "0,?r")
8763                   (match_operator:SI 4 "arm_comparison_operator"
8764                    [(match_operand:SI 2 "s_register_operand" "r,r")
8765                     (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
8766    (clobber (reg:CC CC_REGNUM))]
8767   "TARGET_ARM"
8768   "*
8769     output_asm_insn (\"cmp\\t%2, %3\", operands);
8770     if (which_alternative != 0)
8771       output_asm_insn (\"mov%D4\\t%0, %1\", operands);
8772     return \"sub%d4\\t%0, %1, #1\";
8773   "
8774   [(set_attr "conds" "clob")
8775    (set_attr "length" "8,12")
8776    (set_attr "type" "multiple")]
8779 (define_insn "*cmp_ite0"
8780   [(set (match_operand 6 "dominant_cc_register" "")
8781         (compare
8782          (if_then_else:SI
8783           (match_operator 4 "arm_comparison_operator"
8784            [(match_operand:SI 0 "s_register_operand"
8785                 "l,l,l,r,r,r,r,r,r")
8786             (match_operand:SI 1 "arm_add_operand"
8787                 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
8788           (match_operator:SI 5 "arm_comparison_operator"
8789            [(match_operand:SI 2 "s_register_operand"
8790                 "l,r,r,l,l,r,r,r,r")
8791             (match_operand:SI 3 "arm_add_operand"
8792                 "lPy,rI,L,lPy,lPy,rI,rI,L,L")])
8793           (const_int 0))
8794          (const_int 0)))]
8795   "TARGET_32BIT"
8796   "*
8797   {
8798     static const char * const cmp1[NUM_OF_COND_CMP][2] =
8799     {
8800       {\"cmp%d5\\t%0, %1\",
8801        \"cmp%d4\\t%2, %3\"},
8802       {\"cmn%d5\\t%0, #%n1\",
8803        \"cmp%d4\\t%2, %3\"},
8804       {\"cmp%d5\\t%0, %1\",
8805        \"cmn%d4\\t%2, #%n3\"},
8806       {\"cmn%d5\\t%0, #%n1\",
8807        \"cmn%d4\\t%2, #%n3\"}
8808     };
8809     static const char * const cmp2[NUM_OF_COND_CMP][2] =
8810     {
8811       {\"cmp\\t%2, %3\",
8812        \"cmp\\t%0, %1\"},
8813       {\"cmp\\t%2, %3\",
8814        \"cmn\\t%0, #%n1\"},
8815       {\"cmn\\t%2, #%n3\",
8816        \"cmp\\t%0, %1\"},
8817       {\"cmn\\t%2, #%n3\",
8818        \"cmn\\t%0, #%n1\"}
8819     };
8820     static const char * const ite[2] =
8821     {
8822       \"it\\t%d5\",
8823       \"it\\t%d4\"
8824     };
8825     static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
8826                                    CMP_CMP, CMN_CMP, CMP_CMP,
8827                                    CMN_CMP, CMP_CMN, CMN_CMN};
8828     int swap =
8829       comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
8831     output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
8832     if (TARGET_THUMB2) {
8833       output_asm_insn (ite[swap], operands);
8834     }
8835     output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
8836     return \"\";
8837   }"
8838   [(set_attr "conds" "set")
8839    (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
8840    (set_attr "type" "multiple")
8841    (set_attr_alternative "length"
8842       [(const_int 6)
8843        (const_int 8)
8844        (const_int 8)
8845        (const_int 8)
8846        (const_int 8)
8847        (if_then_else (eq_attr "is_thumb" "no")
8848            (const_int 8)
8849            (const_int 10))
8850        (if_then_else (eq_attr "is_thumb" "no")
8851            (const_int 8)
8852            (const_int 10))
8853        (if_then_else (eq_attr "is_thumb" "no")
8854            (const_int 8)
8855            (const_int 10))
8856        (if_then_else (eq_attr "is_thumb" "no")
8857            (const_int 8)
8858            (const_int 10))])]
8861 (define_insn "*cmp_ite1"
8862   [(set (match_operand 6 "dominant_cc_register" "")
8863         (compare
8864          (if_then_else:SI
8865           (match_operator 4 "arm_comparison_operator"
8866            [(match_operand:SI 0 "s_register_operand"
8867                 "l,l,l,r,r,r,r,r,r")
8868             (match_operand:SI 1 "arm_add_operand"
8869                 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
8870           (match_operator:SI 5 "arm_comparison_operator"
8871            [(match_operand:SI 2 "s_register_operand"
8872                 "l,r,r,l,l,r,r,r,r")
8873             (match_operand:SI 3 "arm_add_operand"
8874                 "lPy,rI,L,lPy,lPy,rI,rI,L,L")])
8875           (const_int 1))
8876          (const_int 0)))]
8877   "TARGET_32BIT"
8878   "*
8879   {
8880     static const char * const cmp1[NUM_OF_COND_CMP][2] =
8881     {
8882       {\"cmp\\t%0, %1\",
8883        \"cmp\\t%2, %3\"},
8884       {\"cmn\\t%0, #%n1\",
8885        \"cmp\\t%2, %3\"},
8886       {\"cmp\\t%0, %1\",
8887        \"cmn\\t%2, #%n3\"},
8888       {\"cmn\\t%0, #%n1\",
8889        \"cmn\\t%2, #%n3\"}
8890     };
8891     static const char * const cmp2[NUM_OF_COND_CMP][2] =
8892     {
8893       {\"cmp%d4\\t%2, %3\",
8894        \"cmp%D5\\t%0, %1\"},
8895       {\"cmp%d4\\t%2, %3\",
8896        \"cmn%D5\\t%0, #%n1\"},
8897       {\"cmn%d4\\t%2, #%n3\",
8898        \"cmp%D5\\t%0, %1\"},
8899       {\"cmn%d4\\t%2, #%n3\",
8900        \"cmn%D5\\t%0, #%n1\"}
8901     };
8902     static const char * const ite[2] =
8903     {
8904       \"it\\t%d4\",
8905       \"it\\t%D5\"
8906     };
8907     static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
8908                                    CMP_CMP, CMN_CMP, CMP_CMP,
8909                                    CMN_CMP, CMP_CMN, CMN_CMN};
8910     int swap =
8911       comparison_dominates_p (GET_CODE (operands[5]),
8912                               reverse_condition (GET_CODE (operands[4])));
8914     output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
8915     if (TARGET_THUMB2) {
8916       output_asm_insn (ite[swap], operands);
8917     }
8918     output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
8919     return \"\";
8920   }"
8921   [(set_attr "conds" "set")
8922    (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
8923    (set_attr_alternative "length"
8924       [(const_int 6)
8925        (const_int 8)
8926        (const_int 8)
8927        (const_int 8)
8928        (const_int 8)
8929        (if_then_else (eq_attr "is_thumb" "no")
8930            (const_int 8)
8931            (const_int 10))
8932        (if_then_else (eq_attr "is_thumb" "no")
8933            (const_int 8)
8934            (const_int 10))
8935        (if_then_else (eq_attr "is_thumb" "no")
8936            (const_int 8)
8937            (const_int 10))
8938        (if_then_else (eq_attr "is_thumb" "no")
8939            (const_int 8)
8940            (const_int 10))])
8941    (set_attr "type" "multiple")]
8944 (define_insn "*cmp_and"
8945   [(set (match_operand 6 "dominant_cc_register" "")
8946         (compare
8947          (and:SI
8948           (match_operator 4 "arm_comparison_operator"
8949            [(match_operand:SI 0 "s_register_operand" 
8950                 "l,l,l,r,r,r,r,r,r")
8951             (match_operand:SI 1 "arm_add_operand" 
8952                 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
8953           (match_operator:SI 5 "arm_comparison_operator"
8954            [(match_operand:SI 2 "s_register_operand" 
8955                 "l,r,r,l,l,r,r,r,r")
8956             (match_operand:SI 3 "arm_add_operand" 
8957                 "lPy,rI,L,lPy,lPy,rI,rI,L,L")]))
8958          (const_int 0)))]
8959   "TARGET_32BIT"
8960   "*
8961   {
8962     static const char *const cmp1[NUM_OF_COND_CMP][2] =
8963     {
8964       {\"cmp%d5\\t%0, %1\",
8965        \"cmp%d4\\t%2, %3\"},
8966       {\"cmn%d5\\t%0, #%n1\",
8967        \"cmp%d4\\t%2, %3\"},
8968       {\"cmp%d5\\t%0, %1\",
8969        \"cmn%d4\\t%2, #%n3\"},
8970       {\"cmn%d5\\t%0, #%n1\",
8971        \"cmn%d4\\t%2, #%n3\"}
8972     };
8973     static const char *const cmp2[NUM_OF_COND_CMP][2] =
8974     {
8975       {\"cmp\\t%2, %3\",
8976        \"cmp\\t%0, %1\"},
8977       {\"cmp\\t%2, %3\",
8978        \"cmn\\t%0, #%n1\"},
8979       {\"cmn\\t%2, #%n3\",
8980        \"cmp\\t%0, %1\"},
8981       {\"cmn\\t%2, #%n3\",
8982        \"cmn\\t%0, #%n1\"}
8983     };
8984     static const char *const ite[2] =
8985     {
8986       \"it\\t%d5\",
8987       \"it\\t%d4\"
8988     };
8989     static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
8990                                    CMP_CMP, CMN_CMP, CMP_CMP,
8991                                    CMN_CMP, CMP_CMN, CMN_CMN};
8992     int swap =
8993       comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
8995     output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
8996     if (TARGET_THUMB2) {
8997       output_asm_insn (ite[swap], operands);
8998     }
8999     output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
9000     return \"\";
9001   }"
9002   [(set_attr "conds" "set")
9003    (set_attr "predicable" "no")
9004    (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
9005    (set_attr_alternative "length"
9006       [(const_int 6)
9007        (const_int 8)
9008        (const_int 8)
9009        (const_int 8)
9010        (const_int 8)
9011        (if_then_else (eq_attr "is_thumb" "no")
9012            (const_int 8)
9013            (const_int 10))
9014        (if_then_else (eq_attr "is_thumb" "no")
9015            (const_int 8)
9016            (const_int 10))
9017        (if_then_else (eq_attr "is_thumb" "no")
9018            (const_int 8)
9019            (const_int 10))
9020        (if_then_else (eq_attr "is_thumb" "no")
9021            (const_int 8)
9022            (const_int 10))])
9023    (set_attr "type" "multiple")]
9026 (define_insn "*cmp_ior"
9027   [(set (match_operand 6 "dominant_cc_register" "")
9028         (compare
9029          (ior:SI
9030           (match_operator 4 "arm_comparison_operator"
9031            [(match_operand:SI 0 "s_register_operand"
9032                 "l,l,l,r,r,r,r,r,r")
9033             (match_operand:SI 1 "arm_add_operand"
9034                 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
9035           (match_operator:SI 5 "arm_comparison_operator"
9036            [(match_operand:SI 2 "s_register_operand"
9037                 "l,r,r,l,l,r,r,r,r")
9038             (match_operand:SI 3 "arm_add_operand"
9039                 "lPy,rI,L,lPy,lPy,rI,rI,L,L")]))
9040          (const_int 0)))]
9041   "TARGET_32BIT"
9042   "*
9043   {
9044     static const char *const cmp1[NUM_OF_COND_CMP][2] =
9045     {
9046       {\"cmp\\t%0, %1\",
9047        \"cmp\\t%2, %3\"},
9048       {\"cmn\\t%0, #%n1\",
9049        \"cmp\\t%2, %3\"},
9050       {\"cmp\\t%0, %1\",
9051        \"cmn\\t%2, #%n3\"},
9052       {\"cmn\\t%0, #%n1\",
9053        \"cmn\\t%2, #%n3\"}
9054     };
9055     static const char *const cmp2[NUM_OF_COND_CMP][2] =
9056     {
9057       {\"cmp%D4\\t%2, %3\",
9058        \"cmp%D5\\t%0, %1\"},
9059       {\"cmp%D4\\t%2, %3\",
9060        \"cmn%D5\\t%0, #%n1\"},
9061       {\"cmn%D4\\t%2, #%n3\",
9062        \"cmp%D5\\t%0, %1\"},
9063       {\"cmn%D4\\t%2, #%n3\",
9064        \"cmn%D5\\t%0, #%n1\"}
9065     };
9066     static const char *const ite[2] =
9067     {
9068       \"it\\t%D4\",
9069       \"it\\t%D5\"
9070     };
9071     static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
9072                                    CMP_CMP, CMN_CMP, CMP_CMP,
9073                                    CMN_CMP, CMP_CMN, CMN_CMN};
9074     int swap =
9075       comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
9077     output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
9078     if (TARGET_THUMB2) {
9079       output_asm_insn (ite[swap], operands);
9080     }
9081     output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
9082     return \"\";
9083   }
9084   "
9085   [(set_attr "conds" "set")
9086    (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
9087    (set_attr_alternative "length"
9088       [(const_int 6)
9089        (const_int 8)
9090        (const_int 8)
9091        (const_int 8)
9092        (const_int 8)
9093        (if_then_else (eq_attr "is_thumb" "no")
9094            (const_int 8)
9095            (const_int 10))
9096        (if_then_else (eq_attr "is_thumb" "no")
9097            (const_int 8)
9098            (const_int 10))
9099        (if_then_else (eq_attr "is_thumb" "no")
9100            (const_int 8)
9101            (const_int 10))
9102        (if_then_else (eq_attr "is_thumb" "no")
9103            (const_int 8)
9104            (const_int 10))])
9105    (set_attr "type" "multiple")]
9108 (define_insn_and_split "*ior_scc_scc"
9109   [(set (match_operand:SI 0 "s_register_operand" "=Ts")
9110         (ior:SI (match_operator:SI 3 "arm_comparison_operator"
9111                  [(match_operand:SI 1 "s_register_operand" "r")
9112                   (match_operand:SI 2 "arm_add_operand" "rIL")])
9113                 (match_operator:SI 6 "arm_comparison_operator"
9114                  [(match_operand:SI 4 "s_register_operand" "r")
9115                   (match_operand:SI 5 "arm_add_operand" "rIL")])))
9116    (clobber (reg:CC CC_REGNUM))]
9117   "TARGET_32BIT
9118    && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_OR_Y)
9119        != CCmode)"
9120   "#"
9121   "TARGET_32BIT && reload_completed"
9122   [(set (match_dup 7)
9123         (compare
9124          (ior:SI
9125           (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9126           (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9127          (const_int 0)))
9128    (set (match_dup 0) (ne:SI (match_dup 7) (const_int 0)))]
9129   "operands[7]
9130      = gen_rtx_REG (arm_select_dominance_cc_mode (operands[3], operands[6],
9131                                                   DOM_CC_X_OR_Y),
9132                     CC_REGNUM);"
9133   [(set_attr "conds" "clob")
9134    (set_attr "length" "16")
9135    (set_attr "type" "multiple")]
9138 ; If the above pattern is followed by a CMP insn, then the compare is 
9139 ; redundant, since we can rework the conditional instruction that follows.
9140 (define_insn_and_split "*ior_scc_scc_cmp"
9141   [(set (match_operand 0 "dominant_cc_register" "")
9142         (compare (ior:SI (match_operator:SI 3 "arm_comparison_operator"
9143                           [(match_operand:SI 1 "s_register_operand" "r")
9144                            (match_operand:SI 2 "arm_add_operand" "rIL")])
9145                          (match_operator:SI 6 "arm_comparison_operator"
9146                           [(match_operand:SI 4 "s_register_operand" "r")
9147                            (match_operand:SI 5 "arm_add_operand" "rIL")]))
9148                  (const_int 0)))
9149    (set (match_operand:SI 7 "s_register_operand" "=Ts")
9150         (ior:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9151                 (match_op_dup 6 [(match_dup 4) (match_dup 5)])))]
9152   "TARGET_32BIT"
9153   "#"
9154   "TARGET_32BIT && reload_completed"
9155   [(set (match_dup 0)
9156         (compare
9157          (ior:SI
9158           (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9159           (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9160          (const_int 0)))
9161    (set (match_dup 7) (ne:SI (match_dup 0) (const_int 0)))]
9162   ""
9163   [(set_attr "conds" "set")
9164    (set_attr "length" "16")
9165    (set_attr "type" "multiple")]
9168 (define_insn_and_split "*and_scc_scc"
9169   [(set (match_operand:SI 0 "s_register_operand" "=Ts")
9170         (and:SI (match_operator:SI 3 "arm_comparison_operator"
9171                  [(match_operand:SI 1 "s_register_operand" "r")
9172                   (match_operand:SI 2 "arm_add_operand" "rIL")])
9173                 (match_operator:SI 6 "arm_comparison_operator"
9174                  [(match_operand:SI 4 "s_register_operand" "r")
9175                   (match_operand:SI 5 "arm_add_operand" "rIL")])))
9176    (clobber (reg:CC CC_REGNUM))]
9177   "TARGET_32BIT
9178    && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
9179        != CCmode)"
9180   "#"
9181   "TARGET_32BIT && reload_completed
9182    && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
9183        != CCmode)"
9184   [(set (match_dup 7)
9185         (compare
9186          (and:SI
9187           (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9188           (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9189          (const_int 0)))
9190    (set (match_dup 0) (ne:SI (match_dup 7) (const_int 0)))]
9191   "operands[7]
9192      = gen_rtx_REG (arm_select_dominance_cc_mode (operands[3], operands[6],
9193                                                   DOM_CC_X_AND_Y),
9194                     CC_REGNUM);"
9195   [(set_attr "conds" "clob")
9196    (set_attr "length" "16")
9197    (set_attr "type" "multiple")]
9200 ; If the above pattern is followed by a CMP insn, then the compare is 
9201 ; redundant, since we can rework the conditional instruction that follows.
9202 (define_insn_and_split "*and_scc_scc_cmp"
9203   [(set (match_operand 0 "dominant_cc_register" "")
9204         (compare (and:SI (match_operator:SI 3 "arm_comparison_operator"
9205                           [(match_operand:SI 1 "s_register_operand" "r")
9206                            (match_operand:SI 2 "arm_add_operand" "rIL")])
9207                          (match_operator:SI 6 "arm_comparison_operator"
9208                           [(match_operand:SI 4 "s_register_operand" "r")
9209                            (match_operand:SI 5 "arm_add_operand" "rIL")]))
9210                  (const_int 0)))
9211    (set (match_operand:SI 7 "s_register_operand" "=Ts")
9212         (and:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9213                 (match_op_dup 6 [(match_dup 4) (match_dup 5)])))]
9214   "TARGET_32BIT"
9215   "#"
9216   "TARGET_32BIT && reload_completed"
9217   [(set (match_dup 0)
9218         (compare
9219          (and:SI
9220           (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9221           (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9222          (const_int 0)))
9223    (set (match_dup 7) (ne:SI (match_dup 0) (const_int 0)))]
9224   ""
9225   [(set_attr "conds" "set")
9226    (set_attr "length" "16")
9227    (set_attr "type" "multiple")]
9230 ;; If there is no dominance in the comparison, then we can still save an
9231 ;; instruction in the AND case, since we can know that the second compare
9232 ;; need only zero the value if false (if true, then the value is already
9233 ;; correct).
9234 (define_insn_and_split "*and_scc_scc_nodom"
9235   [(set (match_operand:SI 0 "s_register_operand" "=&Ts,&Ts,&Ts")
9236         (and:SI (match_operator:SI 3 "arm_comparison_operator"
9237                  [(match_operand:SI 1 "s_register_operand" "r,r,0")
9238                   (match_operand:SI 2 "arm_add_operand" "rIL,0,rIL")])
9239                 (match_operator:SI 6 "arm_comparison_operator"
9240                  [(match_operand:SI 4 "s_register_operand" "r,r,r")
9241                   (match_operand:SI 5 "arm_add_operand" "rIL,rIL,rIL")])))
9242    (clobber (reg:CC CC_REGNUM))]
9243   "TARGET_32BIT
9244    && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
9245        == CCmode)"
9246   "#"
9247   "TARGET_32BIT && reload_completed"
9248   [(parallel [(set (match_dup 0)
9249                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
9250               (clobber (reg:CC CC_REGNUM))])
9251    (set (match_dup 7) (match_op_dup 8 [(match_dup 4) (match_dup 5)]))
9252    (set (match_dup 0)
9253         (if_then_else:SI (match_op_dup 6 [(match_dup 7) (const_int 0)])
9254                          (match_dup 0)
9255                          (const_int 0)))]
9256   "operands[7] = gen_rtx_REG (SELECT_CC_MODE (GET_CODE (operands[6]),
9257                                               operands[4], operands[5]),
9258                               CC_REGNUM);
9259    operands[8] = gen_rtx_COMPARE (GET_MODE (operands[7]), operands[4],
9260                                   operands[5]);"
9261   [(set_attr "conds" "clob")
9262    (set_attr "length" "20")
9263    (set_attr "type" "multiple")]
9266 (define_split
9267   [(set (reg:CC_NOOV CC_REGNUM)
9268         (compare:CC_NOOV (ior:SI
9269                           (and:SI (match_operand:SI 0 "s_register_operand" "")
9270                                   (const_int 1))
9271                           (match_operator:SI 1 "arm_comparison_operator"
9272                            [(match_operand:SI 2 "s_register_operand" "")
9273                             (match_operand:SI 3 "arm_add_operand" "")]))
9274                          (const_int 0)))
9275    (clobber (match_operand:SI 4 "s_register_operand" ""))]
9276   "TARGET_ARM"
9277   [(set (match_dup 4)
9278         (ior:SI (match_op_dup 1 [(match_dup 2) (match_dup 3)])
9279                 (match_dup 0)))
9280    (set (reg:CC_NOOV CC_REGNUM)
9281         (compare:CC_NOOV (and:SI (match_dup 4) (const_int 1))
9282                          (const_int 0)))]
9283   "")
9285 (define_split
9286   [(set (reg:CC_NOOV CC_REGNUM)
9287         (compare:CC_NOOV (ior:SI
9288                           (match_operator:SI 1 "arm_comparison_operator"
9289                            [(match_operand:SI 2 "s_register_operand" "")
9290                             (match_operand:SI 3 "arm_add_operand" "")])
9291                           (and:SI (match_operand:SI 0 "s_register_operand" "")
9292                                   (const_int 1)))
9293                          (const_int 0)))
9294    (clobber (match_operand:SI 4 "s_register_operand" ""))]
9295   "TARGET_ARM"
9296   [(set (match_dup 4)
9297         (ior:SI (match_op_dup 1 [(match_dup 2) (match_dup 3)])
9298                 (match_dup 0)))
9299    (set (reg:CC_NOOV CC_REGNUM)
9300         (compare:CC_NOOV (and:SI (match_dup 4) (const_int 1))
9301                          (const_int 0)))]
9302   "")
9303 ;; ??? The conditional patterns above need checking for Thumb-2 usefulness
9305 (define_insn_and_split "*negscc"
9306   [(set (match_operand:SI 0 "s_register_operand" "=r")
9307         (neg:SI (match_operator 3 "arm_comparison_operator"
9308                  [(match_operand:SI 1 "s_register_operand" "r")
9309                   (match_operand:SI 2 "arm_rhs_operand" "rI")])))
9310    (clobber (reg:CC CC_REGNUM))]
9311   "TARGET_ARM"
9312   "#"
9313   "&& reload_completed"
9314   [(const_int 0)]
9315   {
9316     rtx cc_reg = gen_rtx_REG (CCmode, CC_REGNUM);
9318     if (GET_CODE (operands[3]) == LT && operands[2] == const0_rtx)
9319        {
9320          /* Emit mov\\t%0, %1, asr #31 */
9321          emit_insn (gen_rtx_SET (operands[0],
9322                                  gen_rtx_ASHIFTRT (SImode,
9323                                                    operands[1],
9324                                                    GEN_INT (31))));
9325          DONE;
9326        }
9327      else if (GET_CODE (operands[3]) == NE)
9328        {
9329         /* Emit subs\\t%0, %1, %2\;mvnne\\t%0, #0 */
9330         if (CONST_INT_P (operands[2]))
9331           emit_insn (gen_cmpsi2_addneg (operands[0], operands[1], operands[2],
9332                                         GEN_INT (- INTVAL (operands[2]))));
9333         else
9334           emit_insn (gen_subsi3_compare (operands[0], operands[1], operands[2]));
9336         emit_insn (gen_rtx_COND_EXEC (VOIDmode,
9337                                       gen_rtx_NE (SImode,
9338                                                   cc_reg,
9339                                                   const0_rtx),
9340                                       gen_rtx_SET (operands[0],
9341                                                    GEN_INT (~0))));
9342         DONE;
9343       }
9344     else
9345       {
9346         /* Emit: cmp\\t%1, %2\;mov%D3\\t%0, #0\;mvn%d3\\t%0, #0 */
9347         emit_insn (gen_rtx_SET (cc_reg,
9348                                 gen_rtx_COMPARE (CCmode, operands[1], operands[2])));
9349         enum rtx_code rc = GET_CODE (operands[3]);
9351         rc = reverse_condition (rc);
9352         emit_insn (gen_rtx_COND_EXEC (VOIDmode,
9353                                       gen_rtx_fmt_ee (rc,
9354                                                       VOIDmode,
9355                                                       cc_reg,
9356                                                       const0_rtx),
9357                                       gen_rtx_SET (operands[0], const0_rtx)));
9358         rc = GET_CODE (operands[3]);
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],
9365                                                    GEN_INT (~0))));
9366         DONE;
9367       }
9368      FAIL;
9369   }
9370   [(set_attr "conds" "clob")
9371    (set_attr "length" "12")
9372    (set_attr "type" "multiple")]
9375 (define_insn_and_split "movcond_addsi"
9376   [(set (match_operand:SI 0 "s_register_operand" "=r,l,r")
9377         (if_then_else:SI
9378          (match_operator 5 "comparison_operator"
9379           [(plus:SI (match_operand:SI 3 "s_register_operand" "r,r,r")
9380                     (match_operand:SI 4 "arm_add_operand" "rIL,rIL,rIL"))
9381             (const_int 0)])
9382          (match_operand:SI 1 "arm_rhs_operand" "rI,rPy,r")
9383          (match_operand:SI 2 "arm_rhs_operand" "rI,rPy,r")))
9384    (clobber (reg:CC CC_REGNUM))]
9385    "TARGET_32BIT"
9386    "#"
9387    "&& reload_completed"
9388   [(set (reg:CC_NOOV CC_REGNUM)
9389         (compare:CC_NOOV
9390          (plus:SI (match_dup 3)
9391                   (match_dup 4))
9392          (const_int 0)))
9393    (set (match_dup 0) (match_dup 1))
9394    (cond_exec (match_dup 6)
9395               (set (match_dup 0) (match_dup 2)))]
9396   "
9397   {
9398     machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[5]),
9399                                              operands[3], operands[4]);
9400     enum rtx_code rc = GET_CODE (operands[5]);
9401     operands[6] = gen_rtx_REG (mode, CC_REGNUM);
9402     gcc_assert (!(mode == CCFPmode || mode == CCFPEmode));
9403     if (!REG_P (operands[2]) || REGNO (operands[2]) != REGNO (operands[0]))
9404       rc = reverse_condition (rc);
9405     else
9406       std::swap (operands[1], operands[2]);
9408     operands[6] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
9409   }
9410   "
9411   [(set_attr "conds" "clob")
9412    (set_attr "enabled_for_depr_it" "no,yes,yes")
9413    (set_attr "type" "multiple")]
9416 (define_insn "movcond"
9417   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9418         (if_then_else:SI
9419          (match_operator 5 "arm_comparison_operator"
9420           [(match_operand:SI 3 "s_register_operand" "r,r,r")
9421            (match_operand:SI 4 "arm_add_operand" "rIL,rIL,rIL")])
9422          (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
9423          (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
9424    (clobber (reg:CC CC_REGNUM))]
9425   "TARGET_ARM"
9426   "*
9427   if (GET_CODE (operands[5]) == LT
9428       && (operands[4] == const0_rtx))
9429     {
9430       if (which_alternative != 1 && REG_P (operands[1]))
9431         {
9432           if (operands[2] == const0_rtx)
9433             return \"and\\t%0, %1, %3, asr #31\";
9434           return \"ands\\t%0, %1, %3, asr #32\;movcc\\t%0, %2\";
9435         }
9436       else if (which_alternative != 0 && REG_P (operands[2]))
9437         {
9438           if (operands[1] == const0_rtx)
9439             return \"bic\\t%0, %2, %3, asr #31\";
9440           return \"bics\\t%0, %2, %3, asr #32\;movcs\\t%0, %1\";
9441         }
9442       /* The only case that falls through to here is when both ops 1 & 2
9443          are constants.  */
9444     }
9446   if (GET_CODE (operands[5]) == GE
9447       && (operands[4] == const0_rtx))
9448     {
9449       if (which_alternative != 1 && REG_P (operands[1]))
9450         {
9451           if (operands[2] == const0_rtx)
9452             return \"bic\\t%0, %1, %3, asr #31\";
9453           return \"bics\\t%0, %1, %3, asr #32\;movcs\\t%0, %2\";
9454         }
9455       else if (which_alternative != 0 && REG_P (operands[2]))
9456         {
9457           if (operands[1] == const0_rtx)
9458             return \"and\\t%0, %2, %3, asr #31\";
9459           return \"ands\\t%0, %2, %3, asr #32\;movcc\\t%0, %1\";
9460         }
9461       /* The only case that falls through to here is when both ops 1 & 2
9462          are constants.  */
9463     }
9464   if (CONST_INT_P (operands[4])
9465       && !const_ok_for_arm (INTVAL (operands[4])))
9466     output_asm_insn (\"cmn\\t%3, #%n4\", operands);
9467   else
9468     output_asm_insn (\"cmp\\t%3, %4\", operands);
9469   if (which_alternative != 0)
9470     output_asm_insn (\"mov%d5\\t%0, %1\", operands);
9471   if (which_alternative != 1)
9472     output_asm_insn (\"mov%D5\\t%0, %2\", operands);
9473   return \"\";
9474   "
9475   [(set_attr "conds" "clob")
9476    (set_attr "length" "8,8,12")
9477    (set_attr "type" "multiple")]
9480 ;; ??? The patterns below need checking for Thumb-2 usefulness.
9482 (define_insn "*ifcompare_plus_move"
9483   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9484         (if_then_else:SI (match_operator 6 "arm_comparison_operator"
9485                           [(match_operand:SI 4 "s_register_operand" "r,r")
9486                            (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
9487                          (plus:SI
9488                           (match_operand:SI 2 "s_register_operand" "r,r")
9489                           (match_operand:SI 3 "arm_add_operand" "rIL,rIL"))
9490                          (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))
9491    (clobber (reg:CC CC_REGNUM))]
9492   "TARGET_ARM"
9493   "#"
9494   [(set_attr "conds" "clob")
9495    (set_attr "length" "8,12")
9496    (set_attr "type" "multiple")]
9499 (define_insn "*if_plus_move"
9500   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
9501         (if_then_else:SI
9502          (match_operator 4 "arm_comparison_operator"
9503           [(match_operand 5 "cc_register" "") (const_int 0)])
9504          (plus:SI
9505           (match_operand:SI 2 "s_register_operand" "r,r,r,r")
9506           (match_operand:SI 3 "arm_add_operand" "rI,L,rI,L"))
9507          (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")))]
9508   "TARGET_ARM"
9509   "@
9510    add%d4\\t%0, %2, %3
9511    sub%d4\\t%0, %2, #%n3
9512    add%d4\\t%0, %2, %3\;mov%D4\\t%0, %1
9513    sub%d4\\t%0, %2, #%n3\;mov%D4\\t%0, %1"
9514   [(set_attr "conds" "use")
9515    (set_attr "length" "4,4,8,8")
9516    (set_attr_alternative "type"
9517                          [(if_then_else (match_operand 3 "const_int_operand" "")
9518                                         (const_string "alu_imm" )
9519                                         (const_string "alu_sreg"))
9520                           (const_string "alu_imm")
9521                           (const_string "multiple")
9522                           (const_string "multiple")])]
9525 (define_insn "*ifcompare_move_plus"
9526   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9527         (if_then_else:SI (match_operator 6 "arm_comparison_operator"
9528                           [(match_operand:SI 4 "s_register_operand" "r,r")
9529                            (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
9530                          (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
9531                          (plus:SI
9532                           (match_operand:SI 2 "s_register_operand" "r,r")
9533                           (match_operand:SI 3 "arm_add_operand" "rIL,rIL"))))
9534    (clobber (reg:CC CC_REGNUM))]
9535   "TARGET_ARM"
9536   "#"
9537   [(set_attr "conds" "clob")
9538    (set_attr "length" "8,12")
9539    (set_attr "type" "multiple")]
9542 (define_insn "*if_move_plus"
9543   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
9544         (if_then_else:SI
9545          (match_operator 4 "arm_comparison_operator"
9546           [(match_operand 5 "cc_register" "") (const_int 0)])
9547          (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")
9548          (plus:SI
9549           (match_operand:SI 2 "s_register_operand" "r,r,r,r")
9550           (match_operand:SI 3 "arm_add_operand" "rI,L,rI,L"))))]
9551   "TARGET_ARM"
9552   "@
9553    add%D4\\t%0, %2, %3
9554    sub%D4\\t%0, %2, #%n3
9555    add%D4\\t%0, %2, %3\;mov%d4\\t%0, %1
9556    sub%D4\\t%0, %2, #%n3\;mov%d4\\t%0, %1"
9557   [(set_attr "conds" "use")
9558    (set_attr "length" "4,4,8,8")
9559    (set_attr_alternative "type"
9560                          [(if_then_else (match_operand 3 "const_int_operand" "")
9561                                         (const_string "alu_imm" )
9562                                         (const_string "alu_sreg"))
9563                           (const_string "alu_imm")
9564                           (const_string "multiple")
9565                           (const_string "multiple")])]
9568 (define_insn "*ifcompare_arith_arith"
9569   [(set (match_operand:SI 0 "s_register_operand" "=r")
9570         (if_then_else:SI (match_operator 9 "arm_comparison_operator"
9571                           [(match_operand:SI 5 "s_register_operand" "r")
9572                            (match_operand:SI 6 "arm_add_operand" "rIL")])
9573                          (match_operator:SI 8 "shiftable_operator"
9574                           [(match_operand:SI 1 "s_register_operand" "r")
9575                            (match_operand:SI 2 "arm_rhs_operand" "rI")])
9576                          (match_operator:SI 7 "shiftable_operator"
9577                           [(match_operand:SI 3 "s_register_operand" "r")
9578                            (match_operand:SI 4 "arm_rhs_operand" "rI")])))
9579    (clobber (reg:CC CC_REGNUM))]
9580   "TARGET_ARM"
9581   "#"
9582   [(set_attr "conds" "clob")
9583    (set_attr "length" "12")
9584    (set_attr "type" "multiple")]
9587 (define_insn "*if_arith_arith"
9588   [(set (match_operand:SI 0 "s_register_operand" "=r")
9589         (if_then_else:SI (match_operator 5 "arm_comparison_operator"
9590                           [(match_operand 8 "cc_register" "") (const_int 0)])
9591                          (match_operator:SI 6 "shiftable_operator"
9592                           [(match_operand:SI 1 "s_register_operand" "r")
9593                            (match_operand:SI 2 "arm_rhs_operand" "rI")])
9594                          (match_operator:SI 7 "shiftable_operator"
9595                           [(match_operand:SI 3 "s_register_operand" "r")
9596                            (match_operand:SI 4 "arm_rhs_operand" "rI")])))]
9597   "TARGET_ARM"
9598   "%I6%d5\\t%0, %1, %2\;%I7%D5\\t%0, %3, %4"
9599   [(set_attr "conds" "use")
9600    (set_attr "length" "8")
9601    (set_attr "type" "multiple")]
9604 (define_insn "*ifcompare_arith_move"
9605   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9606         (if_then_else:SI (match_operator 6 "arm_comparison_operator"
9607                           [(match_operand:SI 2 "s_register_operand" "r,r")
9608                            (match_operand:SI 3 "arm_add_operand" "rIL,rIL")])
9609                          (match_operator:SI 7 "shiftable_operator"
9610                           [(match_operand:SI 4 "s_register_operand" "r,r")
9611                            (match_operand:SI 5 "arm_rhs_operand" "rI,rI")])
9612                          (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))
9613    (clobber (reg:CC CC_REGNUM))]
9614   "TARGET_ARM"
9615   "*
9616   /* If we have an operation where (op x 0) is the identity operation and
9617      the conditional operator is LT or GE and we are comparing against zero and
9618      everything is in registers then we can do this in two instructions.  */
9619   if (operands[3] == const0_rtx
9620       && GET_CODE (operands[7]) != AND
9621       && REG_P (operands[5])
9622       && REG_P (operands[1])
9623       && REGNO (operands[1]) == REGNO (operands[4])
9624       && REGNO (operands[4]) != REGNO (operands[0]))
9625     {
9626       if (GET_CODE (operands[6]) == LT)
9627         return \"and\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\";
9628       else if (GET_CODE (operands[6]) == GE)
9629         return \"bic\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\";
9630     }
9631   if (CONST_INT_P (operands[3])
9632       && !const_ok_for_arm (INTVAL (operands[3])))
9633     output_asm_insn (\"cmn\\t%2, #%n3\", operands);
9634   else
9635     output_asm_insn (\"cmp\\t%2, %3\", operands);
9636   output_asm_insn (\"%I7%d6\\t%0, %4, %5\", operands);
9637   if (which_alternative != 0)
9638     return \"mov%D6\\t%0, %1\";
9639   return \"\";
9640   "
9641   [(set_attr "conds" "clob")
9642    (set_attr "length" "8,12")
9643    (set_attr "type" "multiple")]
9646 (define_insn "*if_arith_move"
9647   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9648         (if_then_else:SI (match_operator 4 "arm_comparison_operator"
9649                           [(match_operand 6 "cc_register" "") (const_int 0)])
9650                          (match_operator:SI 5 "shiftable_operator"
9651                           [(match_operand:SI 2 "s_register_operand" "r,r")
9652                            (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
9653                          (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))]
9654   "TARGET_ARM"
9655   "@
9656    %I5%d4\\t%0, %2, %3
9657    %I5%d4\\t%0, %2, %3\;mov%D4\\t%0, %1"
9658   [(set_attr "conds" "use")
9659    (set_attr "length" "4,8")
9660    (set_attr_alternative "type"
9661                          [(if_then_else (match_operand 3 "const_int_operand" "")
9662                                         (const_string "alu_shift_imm" )
9663                                         (const_string "alu_shift_reg"))
9664                           (const_string "multiple")])]
9667 (define_insn "*ifcompare_move_arith"
9668   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9669         (if_then_else:SI (match_operator 6 "arm_comparison_operator"
9670                           [(match_operand:SI 4 "s_register_operand" "r,r")
9671                            (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
9672                          (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
9673                          (match_operator:SI 7 "shiftable_operator"
9674                           [(match_operand:SI 2 "s_register_operand" "r,r")
9675                            (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
9676    (clobber (reg:CC CC_REGNUM))]
9677   "TARGET_ARM"
9678   "*
9679   /* If we have an operation where (op x 0) is the identity operation and
9680      the conditional operator is LT or GE and we are comparing against zero and
9681      everything is in registers then we can do this in two instructions */
9682   if (operands[5] == const0_rtx
9683       && GET_CODE (operands[7]) != AND
9684       && REG_P (operands[3])
9685       && REG_P (operands[1])
9686       && REGNO (operands[1]) == REGNO (operands[2])
9687       && REGNO (operands[2]) != REGNO (operands[0]))
9688     {
9689       if (GET_CODE (operands[6]) == GE)
9690         return \"and\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\";
9691       else if (GET_CODE (operands[6]) == LT)
9692         return \"bic\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\";
9693     }
9695   if (CONST_INT_P (operands[5])
9696       && !const_ok_for_arm (INTVAL (operands[5])))
9697     output_asm_insn (\"cmn\\t%4, #%n5\", operands);
9698   else
9699     output_asm_insn (\"cmp\\t%4, %5\", operands);
9701   if (which_alternative != 0)
9702     output_asm_insn (\"mov%d6\\t%0, %1\", operands);
9703   return \"%I7%D6\\t%0, %2, %3\";
9704   "
9705   [(set_attr "conds" "clob")
9706    (set_attr "length" "8,12")
9707    (set_attr "type" "multiple")]
9710 (define_insn "*if_move_arith"
9711   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9712         (if_then_else:SI
9713          (match_operator 4 "arm_comparison_operator"
9714           [(match_operand 6 "cc_register" "") (const_int 0)])
9715          (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
9716          (match_operator:SI 5 "shiftable_operator"
9717           [(match_operand:SI 2 "s_register_operand" "r,r")
9718            (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))]
9719   "TARGET_ARM"
9720   "@
9721    %I5%D4\\t%0, %2, %3
9722    %I5%D4\\t%0, %2, %3\;mov%d4\\t%0, %1"
9723   [(set_attr "conds" "use")
9724    (set_attr "length" "4,8")
9725    (set_attr_alternative "type"
9726                          [(if_then_else (match_operand 3 "const_int_operand" "")
9727                                         (const_string "alu_shift_imm" )
9728                                         (const_string "alu_shift_reg"))
9729                           (const_string "multiple")])]
9732 (define_insn "*ifcompare_move_not"
9733   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9734         (if_then_else:SI
9735          (match_operator 5 "arm_comparison_operator"
9736           [(match_operand:SI 3 "s_register_operand" "r,r")
9737            (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
9738          (match_operand:SI 1 "arm_not_operand" "0,?rIK")
9739          (not:SI
9740           (match_operand:SI 2 "s_register_operand" "r,r"))))
9741    (clobber (reg:CC CC_REGNUM))]
9742   "TARGET_ARM"
9743   "#"
9744   [(set_attr "conds" "clob")
9745    (set_attr "length" "8,12")
9746    (set_attr "type" "multiple")]
9749 (define_insn "*if_move_not"
9750   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9751         (if_then_else:SI
9752          (match_operator 4 "arm_comparison_operator"
9753           [(match_operand 3 "cc_register" "") (const_int 0)])
9754          (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
9755          (not:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))))]
9756   "TARGET_ARM"
9757   "@
9758    mvn%D4\\t%0, %2
9759    mov%d4\\t%0, %1\;mvn%D4\\t%0, %2
9760    mvn%d4\\t%0, #%B1\;mvn%D4\\t%0, %2"
9761   [(set_attr "conds" "use")
9762    (set_attr "type" "mvn_reg")
9763    (set_attr "length" "4,8,8")
9764    (set_attr "type" "mvn_reg,multiple,multiple")]
9767 (define_insn "*ifcompare_not_move"
9768   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9769         (if_then_else:SI 
9770          (match_operator 5 "arm_comparison_operator"
9771           [(match_operand:SI 3 "s_register_operand" "r,r")
9772            (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
9773          (not:SI
9774           (match_operand:SI 2 "s_register_operand" "r,r"))
9775          (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
9776    (clobber (reg:CC CC_REGNUM))]
9777   "TARGET_ARM"
9778   "#"
9779   [(set_attr "conds" "clob")
9780    (set_attr "length" "8,12")
9781    (set_attr "type" "multiple")]
9784 (define_insn "*if_not_move"
9785   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9786         (if_then_else:SI
9787          (match_operator 4 "arm_comparison_operator"
9788           [(match_operand 3 "cc_register" "") (const_int 0)])
9789          (not:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))
9790          (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
9791   "TARGET_ARM"
9792   "@
9793    mvn%d4\\t%0, %2
9794    mov%D4\\t%0, %1\;mvn%d4\\t%0, %2
9795    mvn%D4\\t%0, #%B1\;mvn%d4\\t%0, %2"
9796   [(set_attr "conds" "use")
9797    (set_attr "type" "mvn_reg,multiple,multiple")
9798    (set_attr "length" "4,8,8")]
9801 (define_insn "*ifcompare_shift_move"
9802   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9803         (if_then_else:SI
9804          (match_operator 6 "arm_comparison_operator"
9805           [(match_operand:SI 4 "s_register_operand" "r,r")
9806            (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
9807          (match_operator:SI 7 "shift_operator"
9808           [(match_operand:SI 2 "s_register_operand" "r,r")
9809            (match_operand:SI 3 "arm_rhs_operand" "rM,rM")])
9810          (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
9811    (clobber (reg:CC CC_REGNUM))]
9812   "TARGET_ARM"
9813   "#"
9814   [(set_attr "conds" "clob")
9815    (set_attr "length" "8,12")
9816    (set_attr "type" "multiple")]
9819 (define_insn "*if_shift_move"
9820   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9821         (if_then_else:SI
9822          (match_operator 5 "arm_comparison_operator"
9823           [(match_operand 6 "cc_register" "") (const_int 0)])
9824          (match_operator:SI 4 "shift_operator"
9825           [(match_operand:SI 2 "s_register_operand" "r,r,r")
9826            (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM")])
9827          (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
9828   "TARGET_ARM"
9829   "@
9830    mov%d5\\t%0, %2%S4
9831    mov%D5\\t%0, %1\;mov%d5\\t%0, %2%S4
9832    mvn%D5\\t%0, #%B1\;mov%d5\\t%0, %2%S4"
9833   [(set_attr "conds" "use")
9834    (set_attr "shift" "2")
9835    (set_attr "length" "4,8,8")
9836    (set_attr_alternative "type"
9837                          [(if_then_else (match_operand 3 "const_int_operand" "")
9838                                         (const_string "mov_shift" )
9839                                         (const_string "mov_shift_reg"))
9840                           (const_string "multiple")
9841                           (const_string "multiple")])]
9844 (define_insn "*ifcompare_move_shift"
9845   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9846         (if_then_else:SI
9847          (match_operator 6 "arm_comparison_operator"
9848           [(match_operand:SI 4 "s_register_operand" "r,r")
9849            (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
9850          (match_operand:SI 1 "arm_not_operand" "0,?rIK")
9851          (match_operator:SI 7 "shift_operator"
9852           [(match_operand:SI 2 "s_register_operand" "r,r")
9853            (match_operand:SI 3 "arm_rhs_operand" "rM,rM")])))
9854    (clobber (reg:CC CC_REGNUM))]
9855   "TARGET_ARM"
9856   "#"
9857   [(set_attr "conds" "clob")
9858    (set_attr "length" "8,12")
9859    (set_attr "type" "multiple")]
9862 (define_insn "*if_move_shift"
9863   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9864         (if_then_else:SI
9865          (match_operator 5 "arm_comparison_operator"
9866           [(match_operand 6 "cc_register" "") (const_int 0)])
9867          (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
9868          (match_operator:SI 4 "shift_operator"
9869           [(match_operand:SI 2 "s_register_operand" "r,r,r")
9870            (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM")])))]
9871   "TARGET_ARM"
9872   "@
9873    mov%D5\\t%0, %2%S4
9874    mov%d5\\t%0, %1\;mov%D5\\t%0, %2%S4
9875    mvn%d5\\t%0, #%B1\;mov%D5\\t%0, %2%S4"
9876   [(set_attr "conds" "use")
9877    (set_attr "shift" "2")
9878    (set_attr "length" "4,8,8")
9879    (set_attr_alternative "type"
9880                          [(if_then_else (match_operand 3 "const_int_operand" "")
9881                                         (const_string "mov_shift" )
9882                                         (const_string "mov_shift_reg"))
9883                           (const_string "multiple")
9884                           (const_string "multiple")])]
9887 (define_insn "*ifcompare_shift_shift"
9888   [(set (match_operand:SI 0 "s_register_operand" "=r")
9889         (if_then_else:SI
9890          (match_operator 7 "arm_comparison_operator"
9891           [(match_operand:SI 5 "s_register_operand" "r")
9892            (match_operand:SI 6 "arm_add_operand" "rIL")])
9893          (match_operator:SI 8 "shift_operator"
9894           [(match_operand:SI 1 "s_register_operand" "r")
9895            (match_operand:SI 2 "arm_rhs_operand" "rM")])
9896          (match_operator:SI 9 "shift_operator"
9897           [(match_operand:SI 3 "s_register_operand" "r")
9898            (match_operand:SI 4 "arm_rhs_operand" "rM")])))
9899    (clobber (reg:CC CC_REGNUM))]
9900   "TARGET_ARM"
9901   "#"
9902   [(set_attr "conds" "clob")
9903    (set_attr "length" "12")
9904    (set_attr "type" "multiple")]
9907 (define_insn "*if_shift_shift"
9908   [(set (match_operand:SI 0 "s_register_operand" "=r")
9909         (if_then_else:SI
9910          (match_operator 5 "arm_comparison_operator"
9911           [(match_operand 8 "cc_register" "") (const_int 0)])
9912          (match_operator:SI 6 "shift_operator"
9913           [(match_operand:SI 1 "s_register_operand" "r")
9914            (match_operand:SI 2 "arm_rhs_operand" "rM")])
9915          (match_operator:SI 7 "shift_operator"
9916           [(match_operand:SI 3 "s_register_operand" "r")
9917            (match_operand:SI 4 "arm_rhs_operand" "rM")])))]
9918   "TARGET_ARM"
9919   "mov%d5\\t%0, %1%S6\;mov%D5\\t%0, %3%S7"
9920   [(set_attr "conds" "use")
9921    (set_attr "shift" "1")
9922    (set_attr "length" "8")
9923    (set (attr "type") (if_then_else
9924                         (and (match_operand 2 "const_int_operand" "")
9925                              (match_operand 4 "const_int_operand" ""))
9926                       (const_string "mov_shift")
9927                       (const_string "mov_shift_reg")))]
9930 (define_insn "*ifcompare_not_arith"
9931   [(set (match_operand:SI 0 "s_register_operand" "=r")
9932         (if_then_else:SI
9933          (match_operator 6 "arm_comparison_operator"
9934           [(match_operand:SI 4 "s_register_operand" "r")
9935            (match_operand:SI 5 "arm_add_operand" "rIL")])
9936          (not:SI (match_operand:SI 1 "s_register_operand" "r"))
9937          (match_operator:SI 7 "shiftable_operator"
9938           [(match_operand:SI 2 "s_register_operand" "r")
9939            (match_operand:SI 3 "arm_rhs_operand" "rI")])))
9940    (clobber (reg:CC CC_REGNUM))]
9941   "TARGET_ARM"
9942   "#"
9943   [(set_attr "conds" "clob")
9944    (set_attr "length" "12")
9945    (set_attr "type" "multiple")]
9948 (define_insn "*if_not_arith"
9949   [(set (match_operand:SI 0 "s_register_operand" "=r")
9950         (if_then_else:SI
9951          (match_operator 5 "arm_comparison_operator"
9952           [(match_operand 4 "cc_register" "") (const_int 0)])
9953          (not:SI (match_operand:SI 1 "s_register_operand" "r"))
9954          (match_operator:SI 6 "shiftable_operator"
9955           [(match_operand:SI 2 "s_register_operand" "r")
9956            (match_operand:SI 3 "arm_rhs_operand" "rI")])))]
9957   "TARGET_ARM"
9958   "mvn%d5\\t%0, %1\;%I6%D5\\t%0, %2, %3"
9959   [(set_attr "conds" "use")
9960    (set_attr "type" "mvn_reg")
9961    (set_attr "length" "8")]
9964 (define_insn "*ifcompare_arith_not"
9965   [(set (match_operand:SI 0 "s_register_operand" "=r")
9966         (if_then_else:SI
9967          (match_operator 6 "arm_comparison_operator"
9968           [(match_operand:SI 4 "s_register_operand" "r")
9969            (match_operand:SI 5 "arm_add_operand" "rIL")])
9970          (match_operator:SI 7 "shiftable_operator"
9971           [(match_operand:SI 2 "s_register_operand" "r")
9972            (match_operand:SI 3 "arm_rhs_operand" "rI")])
9973          (not:SI (match_operand:SI 1 "s_register_operand" "r"))))
9974    (clobber (reg:CC CC_REGNUM))]
9975   "TARGET_ARM"
9976   "#"
9977   [(set_attr "conds" "clob")
9978    (set_attr "length" "12")
9979    (set_attr "type" "multiple")]
9982 (define_insn "*if_arith_not"
9983   [(set (match_operand:SI 0 "s_register_operand" "=r")
9984         (if_then_else:SI
9985          (match_operator 5 "arm_comparison_operator"
9986           [(match_operand 4 "cc_register" "") (const_int 0)])
9987          (match_operator:SI 6 "shiftable_operator"
9988           [(match_operand:SI 2 "s_register_operand" "r")
9989            (match_operand:SI 3 "arm_rhs_operand" "rI")])
9990          (not:SI (match_operand:SI 1 "s_register_operand" "r"))))]
9991   "TARGET_ARM"
9992   "mvn%D5\\t%0, %1\;%I6%d5\\t%0, %2, %3"
9993   [(set_attr "conds" "use")
9994    (set_attr "type" "multiple")
9995    (set_attr "length" "8")]
9998 (define_insn "*ifcompare_neg_move"
9999   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10000         (if_then_else:SI
10001          (match_operator 5 "arm_comparison_operator"
10002           [(match_operand:SI 3 "s_register_operand" "r,r")
10003            (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
10004          (neg:SI (match_operand:SI 2 "s_register_operand" "r,r"))
10005          (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
10006    (clobber (reg:CC CC_REGNUM))]
10007   "TARGET_ARM"
10008   "#"
10009   [(set_attr "conds" "clob")
10010    (set_attr "length" "8,12")
10011    (set_attr "type" "multiple")]
10014 (define_insn_and_split "*if_neg_move"
10015   [(set (match_operand:SI 0 "s_register_operand" "=l,r")
10016         (if_then_else:SI
10017          (match_operator 4 "arm_comparison_operator"
10018           [(match_operand 3 "cc_register" "") (const_int 0)])
10019          (neg:SI (match_operand:SI 2 "s_register_operand" "l,r"))
10020          (match_operand:SI 1 "s_register_operand" "0,0")))]
10021   "TARGET_32BIT"
10022   "#"
10023   "&& reload_completed"
10024   [(cond_exec (match_op_dup 4 [(match_dup 3) (const_int 0)])
10025               (set (match_dup 0) (neg:SI (match_dup 2))))]
10026   ""
10027   [(set_attr "conds" "use")
10028    (set_attr "length" "4")
10029    (set_attr "arch" "t2,32")
10030    (set_attr "enabled_for_depr_it" "yes,no")
10031    (set_attr "type" "logic_shift_imm")]
10034 (define_insn "*ifcompare_move_neg"
10035   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10036         (if_then_else:SI
10037          (match_operator 5 "arm_comparison_operator"
10038           [(match_operand:SI 3 "s_register_operand" "r,r")
10039            (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
10040          (match_operand:SI 1 "arm_not_operand" "0,?rIK")
10041          (neg:SI (match_operand:SI 2 "s_register_operand" "r,r"))))
10042    (clobber (reg:CC CC_REGNUM))]
10043   "TARGET_ARM"
10044   "#"
10045   [(set_attr "conds" "clob")
10046    (set_attr "length" "8,12")
10047    (set_attr "type" "multiple")]
10050 (define_insn_and_split "*if_move_neg"
10051   [(set (match_operand:SI 0 "s_register_operand" "=l,r")
10052         (if_then_else:SI
10053          (match_operator 4 "arm_comparison_operator"
10054           [(match_operand 3 "cc_register" "") (const_int 0)])
10055          (match_operand:SI 1 "s_register_operand" "0,0")
10056          (neg:SI (match_operand:SI 2 "s_register_operand" "l,r"))))]
10057   "TARGET_32BIT"
10058   "#"
10059   "&& reload_completed"
10060   [(cond_exec (match_dup 5)
10061               (set (match_dup 0) (neg:SI (match_dup 2))))]
10062   {
10063     machine_mode mode = GET_MODE (operands[3]);
10064     rtx_code rc = GET_CODE (operands[4]);
10066     if (mode == CCFPmode || mode == CCFPEmode)
10067       rc = reverse_condition_maybe_unordered (rc);
10068     else
10069       rc = reverse_condition (rc);
10071     operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[3], const0_rtx);
10072   }
10073   [(set_attr "conds" "use")
10074    (set_attr "length" "4")
10075    (set_attr "arch" "t2,32")
10076    (set_attr "enabled_for_depr_it" "yes,no")
10077    (set_attr "type" "logic_shift_imm")]
10080 (define_insn "*arith_adjacentmem"
10081   [(set (match_operand:SI 0 "s_register_operand" "=r")
10082         (match_operator:SI 1 "shiftable_operator"
10083          [(match_operand:SI 2 "memory_operand" "m")
10084           (match_operand:SI 3 "memory_operand" "m")]))
10085    (clobber (match_scratch:SI 4 "=r"))]
10086   "TARGET_ARM && adjacent_mem_locations (operands[2], operands[3])"
10087   "*
10088   {
10089     rtx ldm[3];
10090     rtx arith[4];
10091     rtx base_reg;
10092     HOST_WIDE_INT val1 = 0, val2 = 0;
10094     if (REGNO (operands[0]) > REGNO (operands[4]))
10095       {
10096         ldm[1] = operands[4];
10097         ldm[2] = operands[0];
10098       }
10099     else
10100       {
10101         ldm[1] = operands[0];
10102         ldm[2] = operands[4];
10103       }
10105     base_reg = XEXP (operands[2], 0);
10107     if (!REG_P (base_reg))
10108       {
10109         val1 = INTVAL (XEXP (base_reg, 1));
10110         base_reg = XEXP (base_reg, 0);
10111       }
10113     if (!REG_P (XEXP (operands[3], 0)))
10114       val2 = INTVAL (XEXP (XEXP (operands[3], 0), 1));
10116     arith[0] = operands[0];
10117     arith[3] = operands[1];
10119     if (val1 < val2)
10120       {
10121         arith[1] = ldm[1];
10122         arith[2] = ldm[2];
10123       }
10124     else
10125       {
10126         arith[1] = ldm[2];
10127         arith[2] = ldm[1];
10128       }
10130     ldm[0] = base_reg;
10131     if (val1 !=0 && val2 != 0)
10132       {
10133         rtx ops[3];
10135         if (val1 == 4 || val2 == 4)
10136           /* Other val must be 8, since we know they are adjacent and neither
10137              is zero.  */
10138           output_asm_insn (\"ldmib%?\\t%0, {%1, %2}\", ldm);
10139         else if (const_ok_for_arm (val1) || const_ok_for_arm (-val1))
10140           {
10141             ldm[0] = ops[0] = operands[4];
10142             ops[1] = base_reg;
10143             ops[2] = GEN_INT (val1);
10144             output_add_immediate (ops);
10145             if (val1 < val2)
10146               output_asm_insn (\"ldmia%?\\t%0, {%1, %2}\", ldm);
10147             else
10148               output_asm_insn (\"ldmda%?\\t%0, {%1, %2}\", ldm);
10149           }
10150         else
10151           {
10152             /* Offset is out of range for a single add, so use two ldr.  */
10153             ops[0] = ldm[1];
10154             ops[1] = base_reg;
10155             ops[2] = GEN_INT (val1);
10156             output_asm_insn (\"ldr%?\\t%0, [%1, %2]\", ops);
10157             ops[0] = ldm[2];
10158             ops[2] = GEN_INT (val2);
10159             output_asm_insn (\"ldr%?\\t%0, [%1, %2]\", ops);
10160           }
10161       }
10162     else if (val1 != 0)
10163       {
10164         if (val1 < val2)
10165           output_asm_insn (\"ldmda%?\\t%0, {%1, %2}\", ldm);
10166         else
10167           output_asm_insn (\"ldmia%?\\t%0, {%1, %2}\", ldm);
10168       }
10169     else
10170       {
10171         if (val1 < val2)
10172           output_asm_insn (\"ldmia%?\\t%0, {%1, %2}\", ldm);
10173         else
10174           output_asm_insn (\"ldmda%?\\t%0, {%1, %2}\", ldm);
10175       }
10176     output_asm_insn (\"%I3%?\\t%0, %1, %2\", arith);
10177     return \"\";
10178   }"
10179   [(set_attr "length" "12")
10180    (set_attr "predicable" "yes")
10181    (set_attr "type" "load1")]
10184 ; This pattern is never tried by combine, so do it as a peephole
10186 (define_peephole2
10187   [(set (match_operand:SI 0 "arm_general_register_operand" "")
10188         (match_operand:SI 1 "arm_general_register_operand" ""))
10189    (set (reg:CC CC_REGNUM)
10190         (compare:CC (match_dup 1) (const_int 0)))]
10191   "TARGET_ARM"
10192   [(parallel [(set (reg:CC CC_REGNUM) (compare:CC (match_dup 1) (const_int 0)))
10193               (set (match_dup 0) (match_dup 1))])]
10194   ""
10197 (define_split
10198   [(set (match_operand:SI 0 "s_register_operand" "")
10199         (and:SI (ge:SI (match_operand:SI 1 "s_register_operand" "")
10200                        (const_int 0))
10201                 (neg:SI (match_operator:SI 2 "arm_comparison_operator"
10202                          [(match_operand:SI 3 "s_register_operand" "")
10203                           (match_operand:SI 4 "arm_rhs_operand" "")]))))
10204    (clobber (match_operand:SI 5 "s_register_operand" ""))]
10205   "TARGET_ARM"
10206   [(set (match_dup 5) (not:SI (ashiftrt:SI (match_dup 1) (const_int 31))))
10207    (set (match_dup 0) (and:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
10208                               (match_dup 5)))]
10209   ""
10212 ;; This split can be used because CC_Z mode implies that the following
10213 ;; branch will be an equality, or an unsigned inequality, so the sign
10214 ;; extension is not needed.
10216 (define_split
10217   [(set (reg:CC_Z CC_REGNUM)
10218         (compare:CC_Z
10219          (ashift:SI (subreg:SI (match_operand:QI 0 "memory_operand" "") 0)
10220                     (const_int 24))
10221          (match_operand 1 "const_int_operand" "")))
10222    (clobber (match_scratch:SI 2 ""))]
10223   "TARGET_ARM
10224    && ((UINTVAL (operands[1]))
10225        == ((UINTVAL (operands[1])) >> 24) << 24)"
10226   [(set (match_dup 2) (zero_extend:SI (match_dup 0)))
10227    (set (reg:CC CC_REGNUM) (compare:CC (match_dup 2) (match_dup 1)))]
10228   "
10229   operands[1] = GEN_INT (((unsigned long) INTVAL (operands[1])) >> 24);
10230   "
10232 ;; ??? Check the patterns above for Thumb-2 usefulness
10234 (define_expand "prologue"
10235   [(clobber (const_int 0))]
10236   "TARGET_EITHER"
10237   "if (TARGET_32BIT)
10238      arm_expand_prologue ();
10239    else
10240      thumb1_expand_prologue ();
10241   DONE;
10242   "
10245 (define_expand "epilogue"
10246   [(clobber (const_int 0))]
10247   "TARGET_EITHER"
10248   "
10249   if (crtl->calls_eh_return)
10250     emit_insn (gen_force_register_use (gen_rtx_REG (Pmode, 2)));
10251   if (TARGET_THUMB1)
10252    {
10253      thumb1_expand_epilogue ();
10254      emit_jump_insn (gen_rtx_UNSPEC_VOLATILE (VOIDmode,
10255                      gen_rtvec (1, ret_rtx), VUNSPEC_EPILOGUE));
10256    }
10257   else if (HAVE_return)
10258    {
10259      /* HAVE_return is testing for USE_RETURN_INSN (FALSE).  Hence,
10260         no need for explicit testing again.  */
10261      emit_jump_insn (gen_return ());
10262    }
10263   else if (TARGET_32BIT)
10264    {
10265     arm_expand_epilogue (true);
10266    }
10267   DONE;
10268   "
10271 ;; Note - although unspec_volatile's USE all hard registers,
10272 ;; USEs are ignored after relaod has completed.  Thus we need
10273 ;; to add an unspec of the link register to ensure that flow
10274 ;; does not think that it is unused by the sibcall branch that
10275 ;; will replace the standard function epilogue.
10276 (define_expand "sibcall_epilogue"
10277    [(parallel [(unspec:SI [(reg:SI LR_REGNUM)] UNSPEC_REGISTER_USE)
10278                (unspec_volatile [(return)] VUNSPEC_EPILOGUE)])]
10279    "TARGET_32BIT"
10280    "
10281    arm_expand_epilogue (false);
10282    DONE;
10283    "
10286 (define_expand "eh_epilogue"
10287   [(use (match_operand:SI 0 "register_operand" ""))
10288    (use (match_operand:SI 1 "register_operand" ""))
10289    (use (match_operand:SI 2 "register_operand" ""))]
10290   "TARGET_EITHER"
10291   "
10292   {
10293     cfun->machine->eh_epilogue_sp_ofs = operands[1];
10294     if (!REG_P (operands[2]) || REGNO (operands[2]) != 2)
10295       {
10296         rtx ra = gen_rtx_REG (Pmode, 2);
10298         emit_move_insn (ra, operands[2]);
10299         operands[2] = ra;
10300       }
10301     /* This is a hack -- we may have crystalized the function type too
10302        early.  */
10303     cfun->machine->func_type = 0;
10304   }"
10307 ;; This split is only used during output to reduce the number of patterns
10308 ;; that need assembler instructions adding to them.  We allowed the setting
10309 ;; of the conditions to be implicit during rtl generation so that
10310 ;; the conditional compare patterns would work.  However this conflicts to
10311 ;; some extent with the conditional data operations, so we have to split them
10312 ;; up again here.
10314 ;; ??? Need to audit these splitters for Thumb-2.  Why isn't normal
10315 ;; conditional execution sufficient?
10317 (define_split
10318   [(set (match_operand:SI 0 "s_register_operand" "")
10319         (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10320                           [(match_operand 2 "" "") (match_operand 3 "" "")])
10321                          (match_dup 0)
10322                          (match_operand 4 "" "")))
10323    (clobber (reg:CC CC_REGNUM))]
10324   "TARGET_ARM && reload_completed"
10325   [(set (match_dup 5) (match_dup 6))
10326    (cond_exec (match_dup 7)
10327               (set (match_dup 0) (match_dup 4)))]
10328   "
10329   {
10330     machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10331                                              operands[2], operands[3]);
10332     enum rtx_code rc = GET_CODE (operands[1]);
10334     operands[5] = gen_rtx_REG (mode, CC_REGNUM);
10335     operands[6] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10336     if (mode == CCFPmode || mode == CCFPEmode)
10337       rc = reverse_condition_maybe_unordered (rc);
10338     else
10339       rc = reverse_condition (rc);
10341     operands[7] = gen_rtx_fmt_ee (rc, VOIDmode, operands[5], const0_rtx);
10342   }"
10345 (define_split
10346   [(set (match_operand:SI 0 "s_register_operand" "")
10347         (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10348                           [(match_operand 2 "" "") (match_operand 3 "" "")])
10349                          (match_operand 4 "" "")
10350                          (match_dup 0)))
10351    (clobber (reg:CC CC_REGNUM))]
10352   "TARGET_ARM && reload_completed"
10353   [(set (match_dup 5) (match_dup 6))
10354    (cond_exec (match_op_dup 1 [(match_dup 5) (const_int 0)])
10355               (set (match_dup 0) (match_dup 4)))]
10356   "
10357   {
10358     machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10359                                              operands[2], operands[3]);
10361     operands[5] = gen_rtx_REG (mode, CC_REGNUM);
10362     operands[6] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10363   }"
10366 (define_split
10367   [(set (match_operand:SI 0 "s_register_operand" "")
10368         (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10369                           [(match_operand 2 "" "") (match_operand 3 "" "")])
10370                          (match_operand 4 "" "")
10371                          (match_operand 5 "" "")))
10372    (clobber (reg:CC CC_REGNUM))]
10373   "TARGET_ARM && reload_completed"
10374   [(set (match_dup 6) (match_dup 7))
10375    (cond_exec (match_op_dup 1 [(match_dup 6) (const_int 0)])
10376               (set (match_dup 0) (match_dup 4)))
10377    (cond_exec (match_dup 8)
10378               (set (match_dup 0) (match_dup 5)))]
10379   "
10380   {
10381     machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10382                                              operands[2], operands[3]);
10383     enum rtx_code rc = GET_CODE (operands[1]);
10385     operands[6] = gen_rtx_REG (mode, CC_REGNUM);
10386     operands[7] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10387     if (mode == CCFPmode || mode == CCFPEmode)
10388       rc = reverse_condition_maybe_unordered (rc);
10389     else
10390       rc = reverse_condition (rc);
10392     operands[8] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
10393   }"
10396 (define_split
10397   [(set (match_operand:SI 0 "s_register_operand" "")
10398         (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10399                           [(match_operand:SI 2 "s_register_operand" "")
10400                            (match_operand:SI 3 "arm_add_operand" "")])
10401                          (match_operand:SI 4 "arm_rhs_operand" "")
10402                          (not:SI
10403                           (match_operand:SI 5 "s_register_operand" ""))))
10404    (clobber (reg:CC CC_REGNUM))]
10405   "TARGET_ARM && reload_completed"
10406   [(set (match_dup 6) (match_dup 7))
10407    (cond_exec (match_op_dup 1 [(match_dup 6) (const_int 0)])
10408               (set (match_dup 0) (match_dup 4)))
10409    (cond_exec (match_dup 8)
10410               (set (match_dup 0) (not:SI (match_dup 5))))]
10411   "
10412   {
10413     machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10414                                              operands[2], operands[3]);
10415     enum rtx_code rc = GET_CODE (operands[1]);
10417     operands[6] = gen_rtx_REG (mode, CC_REGNUM);
10418     operands[7] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10419     if (mode == CCFPmode || mode == CCFPEmode)
10420       rc = reverse_condition_maybe_unordered (rc);
10421     else
10422       rc = reverse_condition (rc);
10424     operands[8] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
10425   }"
10428 (define_insn "*cond_move_not"
10429   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10430         (if_then_else:SI (match_operator 4 "arm_comparison_operator"
10431                           [(match_operand 3 "cc_register" "") (const_int 0)])
10432                          (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
10433                          (not:SI
10434                           (match_operand:SI 2 "s_register_operand" "r,r"))))]
10435   "TARGET_ARM"
10436   "@
10437    mvn%D4\\t%0, %2
10438    mov%d4\\t%0, %1\;mvn%D4\\t%0, %2"
10439   [(set_attr "conds" "use")
10440    (set_attr "type" "mvn_reg,multiple")
10441    (set_attr "length" "4,8")]
10444 ;; The next two patterns occur when an AND operation is followed by a
10445 ;; scc insn sequence 
10447 (define_insn "*sign_extract_onebit"
10448   [(set (match_operand:SI 0 "s_register_operand" "=r")
10449         (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
10450                          (const_int 1)
10451                          (match_operand:SI 2 "const_int_operand" "n")))
10452     (clobber (reg:CC CC_REGNUM))]
10453   "TARGET_ARM"
10454   "*
10455     operands[2] = GEN_INT (1 << INTVAL (operands[2]));
10456     output_asm_insn (\"ands\\t%0, %1, %2\", operands);
10457     return \"mvnne\\t%0, #0\";
10458   "
10459   [(set_attr "conds" "clob")
10460    (set_attr "length" "8")
10461    (set_attr "type" "multiple")]
10464 (define_insn "*not_signextract_onebit"
10465   [(set (match_operand:SI 0 "s_register_operand" "=r")
10466         (not:SI
10467          (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
10468                           (const_int 1)
10469                           (match_operand:SI 2 "const_int_operand" "n"))))
10470    (clobber (reg:CC CC_REGNUM))]
10471   "TARGET_ARM"
10472   "*
10473     operands[2] = GEN_INT (1 << INTVAL (operands[2]));
10474     output_asm_insn (\"tst\\t%1, %2\", operands);
10475     output_asm_insn (\"mvneq\\t%0, #0\", operands);
10476     return \"movne\\t%0, #0\";
10477   "
10478   [(set_attr "conds" "clob")
10479    (set_attr "length" "12")
10480    (set_attr "type" "multiple")]
10482 ;; ??? The above patterns need auditing for Thumb-2
10484 ;; Push multiple registers to the stack.  Registers are in parallel (use ...)
10485 ;; expressions.  For simplicity, the first register is also in the unspec
10486 ;; part.
10487 ;; To avoid the usage of GNU extension, the length attribute is computed
10488 ;; in a C function arm_attr_length_push_multi.
10489 (define_insn "*push_multi"
10490   [(match_parallel 2 "multi_register_push"
10491     [(set (match_operand:BLK 0 "push_mult_memory_operand" "")
10492           (unspec:BLK [(match_operand:SI 1 "s_register_operand" "")]
10493                       UNSPEC_PUSH_MULT))])]
10494   ""
10495   "*
10496   {
10497     int num_saves = XVECLEN (operands[2], 0);
10498      
10499     /* For the StrongARM at least it is faster to
10500        use STR to store only a single register.
10501        In Thumb mode always use push, and the assembler will pick
10502        something appropriate.  */
10503     if (num_saves == 1 && TARGET_ARM)
10504       output_asm_insn (\"str%?\\t%1, [%m0, #-4]!\", operands);
10505     else
10506       {
10507         int i;
10508         char pattern[100];
10510         if (TARGET_32BIT)
10511             strcpy (pattern, \"push%?\\t{%1\");
10512         else
10513             strcpy (pattern, \"push\\t{%1\");
10515         for (i = 1; i < num_saves; i++)
10516           {
10517             strcat (pattern, \", %|\");
10518             strcat (pattern,
10519                     reg_names[REGNO (XEXP (XVECEXP (operands[2], 0, i), 0))]);
10520           }
10522         strcat (pattern, \"}\");
10523         output_asm_insn (pattern, operands);
10524       }
10526     return \"\";
10527   }"
10528   [(set_attr "type" "store4")
10529    (set (attr "length")
10530         (symbol_ref "arm_attr_length_push_multi (operands[2], operands[1])"))]
10533 (define_insn "stack_tie"
10534   [(set (mem:BLK (scratch))
10535         (unspec:BLK [(match_operand:SI 0 "s_register_operand" "rk")
10536                      (match_operand:SI 1 "s_register_operand" "rk")]
10537                     UNSPEC_PRLG_STK))]
10538   ""
10539   ""
10540   [(set_attr "length" "0")
10541    (set_attr "type" "block")]
10544 ;; Pop (as used in epilogue RTL)
10546 (define_insn "*load_multiple_with_writeback"
10547   [(match_parallel 0 "load_multiple_operation"
10548     [(set (match_operand:SI 1 "s_register_operand" "+rk")
10549           (plus:SI (match_dup 1)
10550                    (match_operand:SI 2 "const_int_I_operand" "I")))
10551      (set (match_operand:SI 3 "s_register_operand" "=rk")
10552           (mem:SI (match_dup 1)))
10553         ])]
10554   "TARGET_32BIT && (reload_in_progress || reload_completed)"
10555   "*
10556   {
10557     arm_output_multireg_pop (operands, /*return_pc=*/false,
10558                                        /*cond=*/const_true_rtx,
10559                                        /*reverse=*/false,
10560                                        /*update=*/true);
10561     return \"\";
10562   }
10563   "
10564   [(set_attr "type" "load4")
10565    (set_attr "predicable" "yes")
10566    (set (attr "length")
10567         (symbol_ref "arm_attr_length_pop_multi (operands,
10568                                                 /*return_pc=*/false,
10569                                                 /*write_back_p=*/true)"))]
10572 ;; Pop with return (as used in epilogue RTL)
10574 ;; This instruction is generated when the registers are popped at the end of
10575 ;; epilogue.  Here, instead of popping the value into LR and then generating
10576 ;; jump to LR, value is popped into PC directly.  Hence, the pattern is combined
10577 ;;  with (return).
10578 (define_insn "*pop_multiple_with_writeback_and_return"
10579   [(match_parallel 0 "pop_multiple_return"
10580     [(return)
10581      (set (match_operand:SI 1 "s_register_operand" "+rk")
10582           (plus:SI (match_dup 1)
10583                    (match_operand:SI 2 "const_int_I_operand" "I")))
10584      (set (match_operand:SI 3 "s_register_operand" "=rk")
10585           (mem:SI (match_dup 1)))
10586         ])]
10587   "TARGET_32BIT && (reload_in_progress || reload_completed)"
10588   "*
10589   {
10590     arm_output_multireg_pop (operands, /*return_pc=*/true,
10591                                        /*cond=*/const_true_rtx,
10592                                        /*reverse=*/false,
10593                                        /*update=*/true);
10594     return \"\";
10595   }
10596   "
10597   [(set_attr "type" "load4")
10598    (set_attr "predicable" "yes")
10599    (set (attr "length")
10600         (symbol_ref "arm_attr_length_pop_multi (operands, /*return_pc=*/true,
10601                                                 /*write_back_p=*/true)"))]
10604 (define_insn "*pop_multiple_with_return"
10605   [(match_parallel 0 "pop_multiple_return"
10606     [(return)
10607      (set (match_operand:SI 2 "s_register_operand" "=rk")
10608           (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
10609         ])]
10610   "TARGET_32BIT && (reload_in_progress || reload_completed)"
10611   "*
10612   {
10613     arm_output_multireg_pop (operands, /*return_pc=*/true,
10614                                        /*cond=*/const_true_rtx,
10615                                        /*reverse=*/false,
10616                                        /*update=*/false);
10617     return \"\";
10618   }
10619   "
10620   [(set_attr "type" "load4")
10621    (set_attr "predicable" "yes")
10622    (set (attr "length")
10623         (symbol_ref "arm_attr_length_pop_multi (operands, /*return_pc=*/true,
10624                                                 /*write_back_p=*/false)"))]
10627 ;; Load into PC and return
10628 (define_insn "*ldr_with_return"
10629   [(return)
10630    (set (reg:SI PC_REGNUM)
10631         (mem:SI (post_inc:SI (match_operand:SI 0 "s_register_operand" "+rk"))))]
10632   "TARGET_32BIT && (reload_in_progress || reload_completed)"
10633   "ldr%?\t%|pc, [%0], #4"
10634   [(set_attr "type" "load1")
10635    (set_attr "predicable" "yes")]
10637 ;; Pop for floating point registers (as used in epilogue RTL)
10638 (define_insn "*vfp_pop_multiple_with_writeback"
10639   [(match_parallel 0 "pop_multiple_fp"
10640     [(set (match_operand:SI 1 "s_register_operand" "+rk")
10641           (plus:SI (match_dup 1)
10642                    (match_operand:SI 2 "const_int_I_operand" "I")))
10643      (set (match_operand:DF 3 "vfp_hard_register_operand" "")
10644           (mem:DF (match_dup 1)))])]
10645   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
10646   "*
10647   {
10648     int num_regs = XVECLEN (operands[0], 0);
10649     char pattern[100];
10650     rtx op_list[2];
10651     strcpy (pattern, \"vldm\\t\");
10652     strcat (pattern, reg_names[REGNO (SET_DEST (XVECEXP (operands[0], 0, 0)))]);
10653     strcat (pattern, \"!, {\");
10654     op_list[0] = XEXP (XVECEXP (operands[0], 0, 1), 0);
10655     strcat (pattern, \"%P0\");
10656     if ((num_regs - 1) > 1)
10657       {
10658         strcat (pattern, \"-%P1\");
10659         op_list [1] = XEXP (XVECEXP (operands[0], 0, num_regs - 1), 0);
10660       }
10662     strcat (pattern, \"}\");
10663     output_asm_insn (pattern, op_list);
10664     return \"\";
10665   }
10666   "
10667   [(set_attr "type" "load4")
10668    (set_attr "conds" "unconditional")
10669    (set_attr "predicable" "no")]
10672 ;; Special patterns for dealing with the constant pool
10674 (define_insn "align_4"
10675   [(unspec_volatile [(const_int 0)] VUNSPEC_ALIGN)]
10676   "TARGET_EITHER"
10677   "*
10678   assemble_align (32);
10679   return \"\";
10680   "
10681   [(set_attr "type" "no_insn")]
10684 (define_insn "align_8"
10685   [(unspec_volatile [(const_int 0)] VUNSPEC_ALIGN8)]
10686   "TARGET_EITHER"
10687   "*
10688   assemble_align (64);
10689   return \"\";
10690   "
10691   [(set_attr "type" "no_insn")]
10694 (define_insn "consttable_end"
10695   [(unspec_volatile [(const_int 0)] VUNSPEC_POOL_END)]
10696   "TARGET_EITHER"
10697   "*
10698   making_const_table = FALSE;
10699   return \"\";
10700   "
10701   [(set_attr "type" "no_insn")]
10704 (define_insn "consttable_1"
10705   [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_1)]
10706   "TARGET_EITHER"
10707   "*
10708   making_const_table = TRUE;
10709   assemble_integer (operands[0], 1, BITS_PER_WORD, 1);
10710   assemble_zeros (3);
10711   return \"\";
10712   "
10713   [(set_attr "length" "4")
10714    (set_attr "type" "no_insn")]
10717 (define_insn "consttable_2"
10718   [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_2)]
10719   "TARGET_EITHER"
10720   "*
10721   {
10722     rtx x = operands[0];
10723     making_const_table = TRUE;
10724     switch (GET_MODE_CLASS (GET_MODE (x)))
10725       {
10726       case MODE_FLOAT:
10727         arm_emit_fp16_const (x);
10728         break;
10729       default:
10730         assemble_integer (operands[0], 2, BITS_PER_WORD, 1);
10731         assemble_zeros (2);
10732         break;
10733       }
10734     return \"\";
10735   }"
10736   [(set_attr "length" "4")
10737    (set_attr "type" "no_insn")]
10740 (define_insn "consttable_4"
10741   [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_4)]
10742   "TARGET_EITHER"
10743   "*
10744   {
10745     rtx x = operands[0];
10746     making_const_table = TRUE;
10747     switch (GET_MODE_CLASS (GET_MODE (x)))
10748       {
10749       case MODE_FLOAT:
10750         assemble_real (*CONST_DOUBLE_REAL_VALUE (x), GET_MODE (x),
10751                        BITS_PER_WORD);
10752         break;
10753       default:
10754         /* XXX: Sometimes gcc does something really dumb and ends up with
10755            a HIGH in a constant pool entry, usually because it's trying to
10756            load into a VFP register.  We know this will always be used in
10757            combination with a LO_SUM which ignores the high bits, so just
10758            strip off the HIGH.  */
10759         if (GET_CODE (x) == HIGH)
10760           x = XEXP (x, 0);
10761         assemble_integer (x, 4, BITS_PER_WORD, 1);
10762         mark_symbol_refs_as_used (x);
10763         break;
10764       }
10765     return \"\";
10766   }"
10767   [(set_attr "length" "4")
10768    (set_attr "type" "no_insn")]
10771 (define_insn "consttable_8"
10772   [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_8)]
10773   "TARGET_EITHER"
10774   "*
10775   {
10776     making_const_table = TRUE;
10777     switch (GET_MODE_CLASS (GET_MODE (operands[0])))
10778       {
10779       case MODE_FLOAT:
10780         assemble_real (*CONST_DOUBLE_REAL_VALUE (operands[0]),
10781                        GET_MODE (operands[0]), BITS_PER_WORD);
10782         break;
10783       default:
10784         assemble_integer (operands[0], 8, BITS_PER_WORD, 1);
10785         break;
10786       }
10787     return \"\";
10788   }"
10789   [(set_attr "length" "8")
10790    (set_attr "type" "no_insn")]
10793 (define_insn "consttable_16"
10794   [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_16)]
10795   "TARGET_EITHER"
10796   "*
10797   {
10798     making_const_table = TRUE;
10799     switch (GET_MODE_CLASS (GET_MODE (operands[0])))
10800       {
10801       case MODE_FLOAT:
10802         assemble_real (*CONST_DOUBLE_REAL_VALUE (operands[0]),
10803                        GET_MODE (operands[0]), BITS_PER_WORD);
10804         break;
10805       default:
10806         assemble_integer (operands[0], 16, BITS_PER_WORD, 1);
10807         break;
10808       }
10809     return \"\";
10810   }"
10811   [(set_attr "length" "16")
10812    (set_attr "type" "no_insn")]
10815 ;; V5 Instructions,
10817 (define_insn "clzsi2"
10818   [(set (match_operand:SI 0 "s_register_operand" "=r")
10819         (clz:SI (match_operand:SI 1 "s_register_operand" "r")))]
10820   "TARGET_32BIT && arm_arch5"
10821   "clz%?\\t%0, %1"
10822   [(set_attr "predicable" "yes")
10823    (set_attr "predicable_short_it" "no")
10824    (set_attr "type" "clz")])
10826 (define_insn "rbitsi2"
10827   [(set (match_operand:SI 0 "s_register_operand" "=r")
10828         (unspec:SI [(match_operand:SI 1 "s_register_operand" "r")] UNSPEC_RBIT))]
10829   "TARGET_32BIT && arm_arch_thumb2"
10830   "rbit%?\\t%0, %1"
10831   [(set_attr "predicable" "yes")
10832    (set_attr "predicable_short_it" "no")
10833    (set_attr "type" "clz")])
10835 ;; Keep this as a CTZ expression until after reload and then split
10836 ;; into RBIT + CLZ.  Since RBIT is represented as an UNSPEC it is unlikely
10837 ;; to fold with any other expression.
10839 (define_insn_and_split "ctzsi2"
10840  [(set (match_operand:SI           0 "s_register_operand" "=r")
10841        (ctz:SI (match_operand:SI  1 "s_register_operand" "r")))]
10842   "TARGET_32BIT && arm_arch_thumb2"
10843   "#"
10844   "&& reload_completed"
10845   [(const_int 0)]
10846   "
10847   emit_insn (gen_rbitsi2 (operands[0], operands[1]));
10848   emit_insn (gen_clzsi2 (operands[0], operands[0]));
10849   DONE;
10852 ;; V5E instructions.
10854 (define_insn "prefetch"
10855   [(prefetch (match_operand:SI 0 "address_operand" "p")
10856              (match_operand:SI 1 "" "")
10857              (match_operand:SI 2 "" ""))]
10858   "TARGET_32BIT && arm_arch5e"
10859   "pld\\t%a0"
10860   [(set_attr "type" "load1")]
10863 ;; General predication pattern
10865 (define_cond_exec
10866   [(match_operator 0 "arm_comparison_operator"
10867     [(match_operand 1 "cc_register" "")
10868      (const_int 0)])]
10869   "TARGET_32BIT
10870    && (!TARGET_NO_VOLATILE_CE || !volatile_refs_p (PATTERN (insn)))"
10871   ""
10872 [(set_attr "predicated" "yes")]
10875 (define_insn "force_register_use"
10876   [(unspec:SI [(match_operand:SI 0 "register_operand" "")] UNSPEC_REGISTER_USE)]
10877   ""
10878   "%@ %0 needed"
10879   [(set_attr "length" "0")
10880    (set_attr "type" "no_insn")]
10884 ;; Patterns for exception handling
10886 (define_expand "eh_return"
10887   [(use (match_operand 0 "general_operand" ""))]
10888   "TARGET_EITHER"
10889   "
10890   {
10891     if (TARGET_32BIT)
10892       emit_insn (gen_arm_eh_return (operands[0]));
10893     else
10894       emit_insn (gen_thumb_eh_return (operands[0]));
10895     DONE;
10896   }"
10898                                    
10899 ;; We can't expand this before we know where the link register is stored.
10900 (define_insn_and_split "arm_eh_return"
10901   [(unspec_volatile [(match_operand:SI 0 "s_register_operand" "r")]
10902                     VUNSPEC_EH_RETURN)
10903    (clobber (match_scratch:SI 1 "=&r"))]
10904   "TARGET_ARM"
10905   "#"
10906   "&& reload_completed"
10907   [(const_int 0)]
10908   "
10909   {
10910     arm_set_return_address (operands[0], operands[1]);
10911     DONE;
10912   }"
10916 ;; TLS support
10918 (define_insn "load_tp_hard"
10919   [(set (match_operand:SI 0 "register_operand" "=r")
10920         (unspec:SI [(const_int 0)] UNSPEC_TLS))]
10921   "TARGET_HARD_TP"
10922   "mrc%?\\tp15, 0, %0, c13, c0, 3\\t@ load_tp_hard"
10923   [(set_attr "predicable" "yes")
10924    (set_attr "type" "mrs")]
10927 ;; Doesn't clobber R1-R3.  Must use r0 for the first operand.
10928 (define_insn "load_tp_soft"
10929   [(set (reg:SI 0) (unspec:SI [(const_int 0)] UNSPEC_TLS))
10930    (clobber (reg:SI LR_REGNUM))
10931    (clobber (reg:SI IP_REGNUM))
10932    (clobber (reg:CC CC_REGNUM))]
10933   "TARGET_SOFT_TP"
10934   "bl\\t__aeabi_read_tp\\t@ load_tp_soft"
10935   [(set_attr "conds" "clob")
10936    (set_attr "type" "branch")]
10939 ;; tls descriptor call
10940 (define_insn "tlscall"
10941   [(set (reg:SI R0_REGNUM)
10942         (unspec:SI [(reg:SI R0_REGNUM)
10943                     (match_operand:SI 0 "" "X")
10944                     (match_operand 1 "" "")] UNSPEC_TLS))
10945    (clobber (reg:SI R1_REGNUM))
10946    (clobber (reg:SI LR_REGNUM))
10947    (clobber (reg:SI CC_REGNUM))]
10948   "TARGET_GNU2_TLS"
10949   {
10950     targetm.asm_out.internal_label (asm_out_file, "LPIC",
10951                                     INTVAL (operands[1]));
10952     return "bl\\t%c0(tlscall)";
10953   }
10954   [(set_attr "conds" "clob")
10955    (set_attr "length" "4")
10956    (set_attr "type" "branch")]
10959 ;; For thread pointer builtin
10960 (define_expand "get_thread_pointersi"
10961   [(match_operand:SI 0 "s_register_operand" "=r")]
10962  ""
10965    arm_load_tp (operands[0]);
10966    DONE;
10967  }")
10971 ;; We only care about the lower 16 bits of the constant 
10972 ;; being inserted into the upper 16 bits of the register.
10973 (define_insn "*arm_movtas_ze" 
10974   [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r")
10975                    (const_int 16)
10976                    (const_int 16))
10977         (match_operand:SI 1 "const_int_operand" ""))]
10978   "TARGET_HAVE_MOVT"
10979   "movt%?\t%0, %L1"
10980  [(set_attr "predicable" "yes")
10981   (set_attr "predicable_short_it" "no")
10982   (set_attr "length" "4")
10983   (set_attr "type" "alu_sreg")]
10986 (define_insn "*arm_rev"
10987   [(set (match_operand:SI 0 "s_register_operand" "=l,l,r")
10988         (bswap:SI (match_operand:SI 1 "s_register_operand" "l,l,r")))]
10989   "arm_arch6"
10990   "@
10991    rev\t%0, %1
10992    rev%?\t%0, %1
10993    rev%?\t%0, %1"
10994   [(set_attr "arch" "t1,t2,32")
10995    (set_attr "length" "2,2,4")
10996    (set_attr "predicable" "no,yes,yes")
10997    (set_attr "predicable_short_it" "no")
10998    (set_attr "type" "rev")]
11001 (define_expand "arm_legacy_rev"
11002   [(set (match_operand:SI 2 "s_register_operand" "")
11003         (xor:SI (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
11004                              (const_int 16))
11005                 (match_dup 1)))
11006    (set (match_dup 2)
11007         (lshiftrt:SI (match_dup 2)
11008                      (const_int 8)))
11009    (set (match_operand:SI 3 "s_register_operand" "")
11010         (rotatert:SI (match_dup 1)
11011                      (const_int 8)))
11012    (set (match_dup 2)
11013         (and:SI (match_dup 2)
11014                 (const_int -65281)))
11015    (set (match_operand:SI 0 "s_register_operand" "")
11016         (xor:SI (match_dup 3)
11017                 (match_dup 2)))]
11018   "TARGET_32BIT"
11019   ""
11022 ;; Reuse temporaries to keep register pressure down.
11023 (define_expand "thumb_legacy_rev"
11024   [(set (match_operand:SI 2 "s_register_operand" "")
11025      (ashift:SI (match_operand:SI 1 "s_register_operand" "")
11026                 (const_int 24)))
11027    (set (match_operand:SI 3 "s_register_operand" "")
11028      (lshiftrt:SI (match_dup 1)
11029                   (const_int 24)))
11030    (set (match_dup 3)
11031      (ior:SI (match_dup 3)
11032              (match_dup 2)))
11033    (set (match_operand:SI 4 "s_register_operand" "")
11034      (const_int 16))
11035    (set (match_operand:SI 5 "s_register_operand" "")
11036      (rotatert:SI (match_dup 1)
11037                   (match_dup 4)))
11038    (set (match_dup 2)
11039      (ashift:SI (match_dup 5)
11040                 (const_int 24)))
11041    (set (match_dup 5)
11042      (lshiftrt:SI (match_dup 5)
11043                   (const_int 24)))
11044    (set (match_dup 5)
11045      (ior:SI (match_dup 5)
11046              (match_dup 2)))
11047    (set (match_dup 5)
11048      (rotatert:SI (match_dup 5)
11049                   (match_dup 4)))
11050    (set (match_operand:SI 0 "s_register_operand" "")
11051      (ior:SI (match_dup 5)
11052              (match_dup 3)))]
11053   "TARGET_THUMB"
11054   ""
11057 ;; ARM-specific expansion of signed mod by power of 2
11058 ;; using conditional negate.
11059 ;; For r0 % n where n is a power of 2 produce:
11060 ;; rsbs    r1, r0, #0
11061 ;; and     r0, r0, #(n - 1)
11062 ;; and     r1, r1, #(n - 1)
11063 ;; rsbpl   r0, r1, #0
11065 (define_expand "modsi3"
11066   [(match_operand:SI 0 "register_operand" "")
11067    (match_operand:SI 1 "register_operand" "")
11068    (match_operand:SI 2 "const_int_operand" "")]
11069   "TARGET_32BIT"
11070   {
11071     HOST_WIDE_INT val = INTVAL (operands[2]);
11073     if (val <= 0
11074        || exact_log2 (val) <= 0)
11075       FAIL;
11077     rtx mask = GEN_INT (val - 1);
11079     /* In the special case of x0 % 2 we can do the even shorter:
11080         cmp     r0, #0
11081         and     r0, r0, #1
11082         rsblt   r0, r0, #0.  */
11084     if (val == 2)
11085       {
11086         rtx cc_reg = arm_gen_compare_reg (LT,
11087                                           operands[1], const0_rtx, NULL_RTX);
11088         rtx cond = gen_rtx_LT (SImode, cc_reg, const0_rtx);
11089         rtx masked = gen_reg_rtx (SImode);
11091         emit_insn (gen_andsi3 (masked, operands[1], mask));
11092         emit_move_insn (operands[0],
11093                         gen_rtx_IF_THEN_ELSE (SImode, cond,
11094                                               gen_rtx_NEG (SImode,
11095                                                            masked),
11096                                               masked));
11097         DONE;
11098       }
11100     rtx neg_op = gen_reg_rtx (SImode);
11101     rtx_insn *insn = emit_insn (gen_subsi3_compare0 (neg_op, const0_rtx,
11102                                                       operands[1]));
11104     /* Extract the condition register and mode.  */
11105     rtx cmp = XVECEXP (PATTERN (insn), 0, 0);
11106     rtx cc_reg = SET_DEST (cmp);
11107     rtx cond = gen_rtx_GE (SImode, cc_reg, const0_rtx);
11109     emit_insn (gen_andsi3 (operands[0], operands[1], mask));
11111     rtx masked_neg = gen_reg_rtx (SImode);
11112     emit_insn (gen_andsi3 (masked_neg, neg_op, mask));
11114     /* We want a conditional negate here, but emitting COND_EXEC rtxes
11115        during expand does not always work.  Do an IF_THEN_ELSE instead.  */
11116     emit_move_insn (operands[0],
11117                     gen_rtx_IF_THEN_ELSE (SImode, cond,
11118                                           gen_rtx_NEG (SImode, masked_neg),
11119                                           operands[0]));
11122     DONE;
11123   }
11126 (define_expand "bswapsi2"
11127   [(set (match_operand:SI 0 "s_register_operand" "=r")
11128         (bswap:SI (match_operand:SI 1 "s_register_operand" "r")))]
11129 "TARGET_EITHER && (arm_arch6 || !optimize_size)"
11131     if (!arm_arch6)
11132       {
11133         rtx op2 = gen_reg_rtx (SImode);
11134         rtx op3 = gen_reg_rtx (SImode);
11136         if (TARGET_THUMB)
11137           {
11138             rtx op4 = gen_reg_rtx (SImode);
11139             rtx op5 = gen_reg_rtx (SImode);
11141             emit_insn (gen_thumb_legacy_rev (operands[0], operands[1],
11142                                              op2, op3, op4, op5));
11143           }
11144         else
11145           {
11146             emit_insn (gen_arm_legacy_rev (operands[0], operands[1],
11147                                            op2, op3));
11148           }
11150         DONE;
11151       }
11152   "
11155 ;; bswap16 patterns: use revsh and rev16 instructions for the signed
11156 ;; and unsigned variants, respectively. For rev16, expose
11157 ;; byte-swapping in the lower 16 bits only.
11158 (define_insn "*arm_revsh"
11159   [(set (match_operand:SI 0 "s_register_operand" "=l,l,r")
11160         (sign_extend:SI (bswap:HI (match_operand:HI 1 "s_register_operand" "l,l,r"))))]
11161   "arm_arch6"
11162   "@
11163   revsh\t%0, %1
11164   revsh%?\t%0, %1
11165   revsh%?\t%0, %1"
11166   [(set_attr "arch" "t1,t2,32")
11167    (set_attr "length" "2,2,4")
11168    (set_attr "type" "rev")]
11171 (define_insn "*arm_rev16"
11172   [(set (match_operand:HI 0 "s_register_operand" "=l,l,r")
11173         (bswap:HI (match_operand:HI 1 "s_register_operand" "l,l,r")))]
11174   "arm_arch6"
11175   "@
11176    rev16\t%0, %1
11177    rev16%?\t%0, %1
11178    rev16%?\t%0, %1"
11179   [(set_attr "arch" "t1,t2,32")
11180    (set_attr "length" "2,2,4")
11181    (set_attr "type" "rev")]
11184 ;; There are no canonicalisation rules for the position of the lshiftrt, ashift
11185 ;; operations within an IOR/AND RTX, therefore we have two patterns matching
11186 ;; each valid permutation.
11188 (define_insn "arm_rev16si2"
11189   [(set (match_operand:SI 0 "register_operand" "=l,l,r")
11190         (ior:SI (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "l,l,r")
11191                                    (const_int 8))
11192                         (match_operand:SI 3 "const_int_operand" "n,n,n"))
11193                 (and:SI (lshiftrt:SI (match_dup 1)
11194                                      (const_int 8))
11195                         (match_operand:SI 2 "const_int_operand" "n,n,n"))))]
11196   "arm_arch6
11197    && aarch_rev16_shleft_mask_imm_p (operands[3], SImode)
11198    && aarch_rev16_shright_mask_imm_p (operands[2], SImode)"
11199   "rev16\\t%0, %1"
11200   [(set_attr "arch" "t1,t2,32")
11201    (set_attr "length" "2,2,4")
11202    (set_attr "type" "rev")]
11205 (define_insn "arm_rev16si2_alt"
11206   [(set (match_operand:SI 0 "register_operand" "=l,l,r")
11207         (ior:SI (and:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "l,l,r")
11208                                      (const_int 8))
11209                         (match_operand:SI 2 "const_int_operand" "n,n,n"))
11210                 (and:SI (ashift:SI (match_dup 1)
11211                                    (const_int 8))
11212                         (match_operand:SI 3 "const_int_operand" "n,n,n"))))]
11213   "arm_arch6
11214    && aarch_rev16_shleft_mask_imm_p (operands[3], SImode)
11215    && aarch_rev16_shright_mask_imm_p (operands[2], SImode)"
11216   "rev16\\t%0, %1"
11217   [(set_attr "arch" "t1,t2,32")
11218    (set_attr "length" "2,2,4")
11219    (set_attr "type" "rev")]
11222 (define_expand "bswaphi2"
11223   [(set (match_operand:HI 0 "s_register_operand" "=r")
11224         (bswap:HI (match_operand:HI 1 "s_register_operand" "r")))]
11225 "arm_arch6"
11229 ;; Patterns for LDRD/STRD in Thumb2 mode
11231 (define_insn "*thumb2_ldrd"
11232   [(set (match_operand:SI 0 "s_register_operand" "=r")
11233         (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "rk")
11234                          (match_operand:SI 2 "ldrd_strd_offset_operand" "Do"))))
11235    (set (match_operand:SI 3 "s_register_operand" "=r")
11236         (mem:SI (plus:SI (match_dup 1)
11237                          (match_operand:SI 4 "const_int_operand" ""))))]
11238   "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11239      && current_tune->prefer_ldrd_strd
11240      && ((INTVAL (operands[2]) + 4) == INTVAL (operands[4]))
11241      && (operands_ok_ldrd_strd (operands[0], operands[3],
11242                                   operands[1], INTVAL (operands[2]),
11243                                   false, true))"
11244   "ldrd%?\t%0, %3, [%1, %2]"
11245   [(set_attr "type" "load2")
11246    (set_attr "predicable" "yes")
11247    (set_attr "predicable_short_it" "no")])
11249 (define_insn "*thumb2_ldrd_base"
11250   [(set (match_operand:SI 0 "s_register_operand" "=r")
11251         (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
11252    (set (match_operand:SI 2 "s_register_operand" "=r")
11253         (mem:SI (plus:SI (match_dup 1)
11254                          (const_int 4))))]
11255   "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11256      && current_tune->prefer_ldrd_strd
11257      && (operands_ok_ldrd_strd (operands[0], operands[2],
11258                                   operands[1], 0, false, true))"
11259   "ldrd%?\t%0, %2, [%1]"
11260   [(set_attr "type" "load2")
11261    (set_attr "predicable" "yes")
11262    (set_attr "predicable_short_it" "no")])
11264 (define_insn "*thumb2_ldrd_base_neg"
11265   [(set (match_operand:SI 0 "s_register_operand" "=r")
11266         (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "rk")
11267                          (const_int -4))))
11268    (set (match_operand:SI 2 "s_register_operand" "=r")
11269         (mem:SI (match_dup 1)))]
11270   "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11271      && current_tune->prefer_ldrd_strd
11272      && (operands_ok_ldrd_strd (operands[0], operands[2],
11273                                   operands[1], -4, false, true))"
11274   "ldrd%?\t%0, %2, [%1, #-4]"
11275   [(set_attr "type" "load2")
11276    (set_attr "predicable" "yes")
11277    (set_attr "predicable_short_it" "no")])
11279 (define_insn "*thumb2_strd"
11280   [(set (mem:SI (plus:SI (match_operand:SI 0 "s_register_operand" "rk")
11281                          (match_operand:SI 1 "ldrd_strd_offset_operand" "Do")))
11282         (match_operand:SI 2 "s_register_operand" "r"))
11283    (set (mem:SI (plus:SI (match_dup 0)
11284                          (match_operand:SI 3 "const_int_operand" "")))
11285         (match_operand:SI 4 "s_register_operand" "r"))]
11286   "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11287      && current_tune->prefer_ldrd_strd
11288      && ((INTVAL (operands[1]) + 4) == INTVAL (operands[3]))
11289      && (operands_ok_ldrd_strd (operands[2], operands[4],
11290                                   operands[0], INTVAL (operands[1]),
11291                                   false, false))"
11292   "strd%?\t%2, %4, [%0, %1]"
11293   [(set_attr "type" "store2")
11294    (set_attr "predicable" "yes")
11295    (set_attr "predicable_short_it" "no")])
11297 (define_insn "*thumb2_strd_base"
11298   [(set (mem:SI (match_operand:SI 0 "s_register_operand" "rk"))
11299         (match_operand:SI 1 "s_register_operand" "r"))
11300    (set (mem:SI (plus:SI (match_dup 0)
11301                          (const_int 4)))
11302         (match_operand:SI 2 "s_register_operand" "r"))]
11303   "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11304      && current_tune->prefer_ldrd_strd
11305      && (operands_ok_ldrd_strd (operands[1], operands[2],
11306                                   operands[0], 0, false, false))"
11307   "strd%?\t%1, %2, [%0]"
11308   [(set_attr "type" "store2")
11309    (set_attr "predicable" "yes")
11310    (set_attr "predicable_short_it" "no")])
11312 (define_insn "*thumb2_strd_base_neg"
11313   [(set (mem:SI (plus:SI (match_operand:SI 0 "s_register_operand" "rk")
11314                          (const_int -4)))
11315         (match_operand:SI 1 "s_register_operand" "r"))
11316    (set (mem:SI (match_dup 0))
11317         (match_operand:SI 2 "s_register_operand" "r"))]
11318   "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11319      && current_tune->prefer_ldrd_strd
11320      && (operands_ok_ldrd_strd (operands[1], operands[2],
11321                                   operands[0], -4, false, false))"
11322   "strd%?\t%1, %2, [%0, #-4]"
11323   [(set_attr "type" "store2")
11324    (set_attr "predicable" "yes")
11325    (set_attr "predicable_short_it" "no")])
11327 ;; ARMv8 CRC32 instructions.
11328 (define_insn "<crc_variant>"
11329   [(set (match_operand:SI 0 "s_register_operand" "=r")
11330         (unspec:SI [(match_operand:SI 1 "s_register_operand" "r")
11331                     (match_operand:<crc_mode> 2 "s_register_operand" "r")]
11332          CRC))]
11333   "TARGET_CRC32"
11334   "<crc_variant>\\t%0, %1, %2"
11335   [(set_attr "type" "crc")
11336    (set_attr "conds" "unconditional")]
11339 ;; Load the load/store double peephole optimizations.
11340 (include "ldrdstrd.md")
11342 ;; Load the load/store multiple patterns
11343 (include "ldmstm.md")
11345 ;; Patterns in ldmstm.md don't cover more than 4 registers. This pattern covers
11346 ;; large lists without explicit writeback generated for APCS_FRAME epilogue.
11347 (define_insn "*load_multiple"
11348   [(match_parallel 0 "load_multiple_operation"
11349     [(set (match_operand:SI 2 "s_register_operand" "=rk")
11350           (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
11351         ])]
11352   "TARGET_32BIT"
11353   "*
11354   {
11355     arm_output_multireg_pop (operands, /*return_pc=*/false,
11356                                        /*cond=*/const_true_rtx,
11357                                        /*reverse=*/false,
11358                                        /*update=*/false);
11359     return \"\";
11360   }
11361   "
11362   [(set_attr "predicable" "yes")]
11365 (define_expand "copysignsf3"
11366   [(match_operand:SF 0 "register_operand")
11367    (match_operand:SF 1 "register_operand")
11368    (match_operand:SF 2 "register_operand")]
11369   "TARGET_SOFT_FLOAT && arm_arch_thumb2"
11370   "{
11371      emit_move_insn (operands[0], operands[2]);
11372      emit_insn (gen_insv_t2 (simplify_gen_subreg (SImode, operands[0], SFmode, 0),
11373                 GEN_INT (31), GEN_INT (0),
11374                 simplify_gen_subreg (SImode, operands[1], SFmode, 0)));
11375      DONE;
11376   }"
11379 (define_expand "copysigndf3"
11380   [(match_operand:DF 0 "register_operand")
11381    (match_operand:DF 1 "register_operand")
11382    (match_operand:DF 2 "register_operand")]
11383   "TARGET_SOFT_FLOAT && arm_arch_thumb2"
11384   "{
11385      rtx op0_low = gen_lowpart (SImode, operands[0]);
11386      rtx op0_high = gen_highpart (SImode, operands[0]);
11387      rtx op1_low = gen_lowpart (SImode, operands[1]);
11388      rtx op1_high = gen_highpart (SImode, operands[1]);
11389      rtx op2_high = gen_highpart (SImode, operands[2]);
11391      rtx scratch1 = gen_reg_rtx (SImode);
11392      rtx scratch2 = gen_reg_rtx (SImode);
11393      emit_move_insn (scratch1, op2_high);
11394      emit_move_insn (scratch2, op1_high);
11396      emit_insn(gen_rtx_SET(scratch1,
11397                            gen_rtx_LSHIFTRT (SImode, op2_high, GEN_INT(31))));
11398      emit_insn(gen_insv_t2(scratch2, GEN_INT(1), GEN_INT(31), scratch1));
11399      emit_move_insn (op0_low, op1_low);
11400      emit_move_insn (op0_high, scratch2);
11402      DONE;
11403   }"
11406 ;; movmisalign patterns for HImode and SImode.
11407 (define_expand "movmisalign<mode>"
11408   [(match_operand:HSI 0 "general_operand")
11409    (match_operand:HSI 1 "general_operand")]
11410   "unaligned_access"
11412   /* This pattern is not permitted to fail during expansion: if both arguments
11413      are non-registers (e.g. memory := constant), force operand 1 into a
11414      register.  */
11415   rtx (* gen_unaligned_load)(rtx, rtx);
11416   rtx tmp_dest = operands[0];
11417   if (!s_register_operand (operands[0], <MODE>mode)
11418       && !s_register_operand (operands[1], <MODE>mode))
11419     operands[1] = force_reg (<MODE>mode, operands[1]);
11421   if (<MODE>mode == HImode)
11422    {
11423     gen_unaligned_load = gen_unaligned_loadhiu;
11424     tmp_dest = gen_reg_rtx (SImode);
11425    }
11426   else
11427     gen_unaligned_load = gen_unaligned_loadsi;
11429   if (MEM_P (operands[1]))
11430    {
11431     emit_insn (gen_unaligned_load (tmp_dest, operands[1]));
11432     if (<MODE>mode == HImode)
11433       emit_move_insn (operands[0], gen_lowpart (HImode, tmp_dest));
11434    }
11435   else
11436     emit_insn (gen_unaligned_store<mode> (operands[0], operands[1]));
11438   DONE;
11441 ;; Vector bits common to IWMMXT and Neon
11442 (include "vec-common.md")
11443 ;; Load the Intel Wireless Multimedia Extension patterns
11444 (include "iwmmxt.md")
11445 ;; Load the VFP co-processor patterns
11446 (include "vfp.md")
11447 ;; Thumb-1 patterns
11448 (include "thumb1.md")
11449 ;; Thumb-2 patterns
11450 (include "thumb2.md")
11451 ;; Neon patterns
11452 (include "neon.md")
11453 ;; Crypto patterns
11454 (include "crypto.md")
11455 ;; Synchronization Primitives
11456 (include "sync.md")
11457 ;; Fixed-point patterns
11458 (include "arm-fixed.md")