gcc/
[official-gcc.git] / gcc / config / arm / arm.md
blob7c87bcdeca1e450a81f8aacb195c5c6e3a6a92a5
1 ;;- Machine description for ARM for GNU compiler
2 ;;  Copyright (C) 1991-2015 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" "no,yes" (const (symbol_ref "thumb_code")))
74 ; IS_ARCH6 is set to 'yes' when we are generating code form ARMv6.
75 (define_attr "is_arch6" "no,yes" (const (symbol_ref "arm_arch6")))
77 ; IS_THUMB1 is set to 'yes' iff we are generating Thumb-1 code.
78 (define_attr "is_thumb1" "no,yes" (const (symbol_ref "thumb1_code")))
80 ; We use this attribute to disable alternatives that can produce 32-bit
81 ; instructions inside an IT-block in Thumb2 state.  ARMv8 deprecates IT blocks
82 ; that contain 32-bit instructions.
83 (define_attr "enabled_for_depr_it" "no,yes" (const_string "yes"))
85 ; This attribute is used to disable a predicated alternative when we have
86 ; arm_restrict_it.
87 (define_attr "predicable_short_it" "no,yes" (const_string "yes"))
89 ;; Operand number of an input operand that is shifted.  Zero if the
90 ;; given instruction does not shift one of its input operands.
91 (define_attr "shift" "" (const_int 0))
93 ;; [For compatibility with AArch64 in pipeline models]
94 ;; Attribute that specifies whether or not the instruction touches fp
95 ;; registers.
96 (define_attr "fp" "no,yes" (const_string "no"))
98 ; Floating Point Unit.  If we only have floating point emulation, then there
99 ; is no point in scheduling the floating point insns.  (Well, for best
100 ; performance we should try and group them together).
101 (define_attr "fpu" "none,vfp"
102   (const (symbol_ref "arm_fpu_attr")))
104 (define_attr "predicated" "yes,no" (const_string "no"))
106 ; LENGTH of an instruction (in bytes)
107 (define_attr "length" ""
108   (const_int 4))
110 ; The architecture which supports the instruction (or alternative).
111 ; This can be "a" for ARM, "t" for either of the Thumbs, "32" for
112 ; TARGET_32BIT, "t1" or "t2" to specify a specific Thumb mode.  "v6"
113 ; for ARM or Thumb-2 with arm_arch6, and nov6 for ARM without
114 ; arm_arch6.  "v6t2" for Thumb-2 with arm_arch6.  This attribute is
115 ; used to compute attribute "enabled", use type "any" to enable an
116 ; alternative in all cases.
117 (define_attr "arch" "any,a,t,32,t1,t2,v6,nov6,v6t2,neon_for_64bits,avoid_neon_for_64bits,iwmmxt,iwmmxt2,armv6_or_vfpv3"
118   (const_string "any"))
120 (define_attr "arch_enabled" "no,yes"
121   (cond [(eq_attr "arch" "any")
122          (const_string "yes")
124          (and (eq_attr "arch" "a")
125               (match_test "TARGET_ARM"))
126          (const_string "yes")
128          (and (eq_attr "arch" "t")
129               (match_test "TARGET_THUMB"))
130          (const_string "yes")
132          (and (eq_attr "arch" "t1")
133               (match_test "TARGET_THUMB1"))
134          (const_string "yes")
136          (and (eq_attr "arch" "t2")
137               (match_test "TARGET_THUMB2"))
138          (const_string "yes")
140          (and (eq_attr "arch" "32")
141               (match_test "TARGET_32BIT"))
142          (const_string "yes")
144          (and (eq_attr "arch" "v6")
145               (match_test "TARGET_32BIT && arm_arch6"))
146          (const_string "yes")
148          (and (eq_attr "arch" "nov6")
149               (match_test "TARGET_32BIT && !arm_arch6"))
150          (const_string "yes")
152          (and (eq_attr "arch" "v6t2")
153               (match_test "TARGET_32BIT && arm_arch6 && arm_arch_thumb2"))
154          (const_string "yes")
156          (and (eq_attr "arch" "avoid_neon_for_64bits")
157               (match_test "TARGET_NEON")
158               (not (match_test "TARGET_PREFER_NEON_64BITS")))
159          (const_string "yes")
161          (and (eq_attr "arch" "neon_for_64bits")
162               (match_test "TARGET_NEON")
163               (match_test "TARGET_PREFER_NEON_64BITS"))
164          (const_string "yes")
166          (and (eq_attr "arch" "iwmmxt2")
167               (match_test "TARGET_REALLY_IWMMXT2"))
168          (const_string "yes")
170          (and (eq_attr "arch" "armv6_or_vfpv3")
171               (match_test "arm_arch6 || TARGET_VFP3"))
172          (const_string "yes")
173         ]
175         (const_string "no")))
177 (define_attr "opt" "any,speed,size"
178   (const_string "any"))
180 (define_attr "opt_enabled" "no,yes"
181   (cond [(eq_attr "opt" "any")
182          (const_string "yes")
184          (and (eq_attr "opt" "speed")
185               (match_test "optimize_function_for_speed_p (cfun)"))
186          (const_string "yes")
188          (and (eq_attr "opt" "size")
189               (match_test "optimize_function_for_size_p (cfun)"))
190          (const_string "yes")]
191         (const_string "no")))
193 (define_attr "use_literal_pool" "no,yes"
194    (cond [(and (eq_attr "type" "f_loads,f_loadd")
195                (match_test "CONSTANT_P (operands[1])"))
196           (const_string "yes")]
197          (const_string "no")))
199 ; Enable all alternatives that are both arch_enabled and insn_enabled.
200 ; FIXME:: opt_enabled has been temporarily removed till the time we have
201 ; an attribute that allows the use of such alternatives.
202 ; This depends on caching of speed_p, size_p on a per
203 ; alternative basis. The problem is that the enabled attribute
204 ; cannot depend on any state that is not cached or is not constant
205 ; for a compilation unit. We probably need a generic "hot/cold"
206 ; alternative which if implemented can help with this. We disable this
207 ; until such a time as this is implemented and / or the improvements or
208 ; regressions with removing this attribute are double checked.
209 ; See ashldi3_neon and <shift>di3_neon in neon.md.
211  (define_attr "enabled" "no,yes"
212    (cond [(and (eq_attr "predicable_short_it" "no")
213                (and (eq_attr "predicated" "yes")
214                     (match_test "arm_restrict_it")))
215           (const_string "no")
217           (and (eq_attr "enabled_for_depr_it" "no")
218                (match_test "arm_restrict_it"))
219           (const_string "no")
221           (and (eq_attr "use_literal_pool" "yes")
222                (match_test "arm_disable_literal_pool"))
223           (const_string "no")
225           (eq_attr "arch_enabled" "no")
226           (const_string "no")]
227          (const_string "yes")))
229 ; POOL_RANGE is how far away from a constant pool entry that this insn
230 ; can be placed.  If the distance is zero, then this insn will never
231 ; reference the pool.
232 ; Note that for Thumb constant pools the PC value is rounded down to the
233 ; nearest multiple of four.  Therefore, THUMB2_POOL_RANGE (and POOL_RANGE for
234 ; Thumb insns) should be set to <max_range> - 2.
235 ; NEG_POOL_RANGE is nonzero for insns that can reference a constant pool entry
236 ; before its address.  It is set to <max_range> - (8 + <data_size>).
237 (define_attr "arm_pool_range" "" (const_int 0))
238 (define_attr "thumb2_pool_range" "" (const_int 0))
239 (define_attr "arm_neg_pool_range" "" (const_int 0))
240 (define_attr "thumb2_neg_pool_range" "" (const_int 0))
242 (define_attr "pool_range" ""
243   (cond [(eq_attr "is_thumb" "yes") (attr "thumb2_pool_range")]
244         (attr "arm_pool_range")))
245 (define_attr "neg_pool_range" ""
246   (cond [(eq_attr "is_thumb" "yes") (attr "thumb2_neg_pool_range")]
247         (attr "arm_neg_pool_range")))
249 ; An assembler sequence may clobber the condition codes without us knowing.
250 ; If such an insn references the pool, then we have no way of knowing how,
251 ; so use the most conservative value for pool_range.
252 (define_asm_attributes
253  [(set_attr "conds" "clob")
254   (set_attr "length" "4")
255   (set_attr "pool_range" "250")])
257 ; Load scheduling, set from the arm_ld_sched variable
258 ; initialized by arm_option_override()
259 (define_attr "ldsched" "no,yes" (const (symbol_ref "arm_ld_sched")))
261 ; condition codes: this one is used by final_prescan_insn to speed up
262 ; conditionalizing instructions.  It saves having to scan the rtl to see if
263 ; it uses or alters the condition codes.
265 ; USE means that the condition codes are used by the insn in the process of
266 ;   outputting code, this means (at present) that we can't use the insn in
267 ;   inlined branches
269 ; SET means that the purpose of the insn is to set the condition codes in a
270 ;   well defined manner.
272 ; CLOB means that the condition codes are altered in an undefined manner, if
273 ;   they are altered at all
275 ; UNCONDITIONAL means the instruction can not be conditionally executed and
276 ;   that the instruction does not use or alter the condition codes.
278 ; NOCOND means that the instruction does not use or alter the condition
279 ;   codes but can be converted into a conditionally exectuted instruction.
281 (define_attr "conds" "use,set,clob,unconditional,nocond"
282         (if_then_else
283          (ior (eq_attr "is_thumb1" "yes")
284               (eq_attr "type" "call"))
285          (const_string "clob")
286          (if_then_else (eq_attr "is_neon_type" "no")
287          (const_string "nocond")
288          (const_string "unconditional"))))
290 ; Predicable means that the insn can be conditionally executed based on
291 ; an automatically added predicate (additional patterns are generated by 
292 ; gen...).  We default to 'no' because no Thumb patterns match this rule
293 ; and not all ARM patterns do.
294 (define_attr "predicable" "no,yes" (const_string "no"))
296 ; Only model the write buffer for ARM6 and ARM7.  Earlier processors don't
297 ; have one.  Later ones, such as StrongARM, have write-back caches, so don't
298 ; suffer blockages enough to warrant modelling this (and it can adversely
299 ; affect the schedule).
300 (define_attr "model_wbuf" "no,yes" (const (symbol_ref "arm_tune_wbuf")))
302 ; WRITE_CONFLICT implies that a read following an unrelated write is likely
303 ; to stall the processor.  Used with model_wbuf above.
304 (define_attr "write_conflict" "no,yes"
305   (if_then_else (eq_attr "type"
306                  "block,call,load1")
307                 (const_string "yes")
308                 (const_string "no")))
310 ; Classify the insns into those that take one cycle and those that take more
311 ; than one on the main cpu execution unit.
312 (define_attr "core_cycles" "single,multi"
313   (if_then_else (eq_attr "type"
314     "adc_imm, adc_reg, adcs_imm, adcs_reg, adr, alu_ext, alu_imm, alu_sreg,\
315     alu_shift_imm, alu_shift_reg, alu_dsp_reg, alus_ext, alus_imm, alus_sreg,\
316     alus_shift_imm, alus_shift_reg, bfm, csel, rev, logic_imm, logic_reg,\
317     logic_shift_imm, logic_shift_reg, logics_imm, logics_reg,\
318     logics_shift_imm, logics_shift_reg, extend, shift_imm, float, fcsel,\
319     wmmx_wor, wmmx_wxor, wmmx_wand, wmmx_wandn, wmmx_wmov, wmmx_tmcrr,\
320     wmmx_tmrrc, wmmx_wldr, wmmx_wstr, wmmx_tmcr, wmmx_tmrc, wmmx_wadd,\
321     wmmx_wsub, wmmx_wmul, wmmx_wmac, wmmx_wavg2, wmmx_tinsr, wmmx_textrm,\
322     wmmx_wshufh, wmmx_wcmpeq, wmmx_wcmpgt, wmmx_wmax, wmmx_wmin, wmmx_wpack,\
323     wmmx_wunpckih, wmmx_wunpckil, wmmx_wunpckeh, wmmx_wunpckel, wmmx_wror,\
324     wmmx_wsra, wmmx_wsrl, wmmx_wsll, wmmx_wmadd, wmmx_tmia, wmmx_tmiaph,\
325     wmmx_tmiaxy, wmmx_tbcst, wmmx_tmovmsk, wmmx_wacc, wmmx_waligni,\
326     wmmx_walignr, wmmx_tandc, wmmx_textrc, wmmx_torc, wmmx_torvsc, wmmx_wsad,\
327     wmmx_wabs, wmmx_wabsdiff, wmmx_waddsubhx, wmmx_wsubaddhx, wmmx_wavg4,\
328     wmmx_wmulw, wmmx_wqmulm, wmmx_wqmulwm, wmmx_waddbhus, wmmx_wqmiaxy,\
329     wmmx_wmiaxy, wmmx_wmiawxy, wmmx_wmerge")
330                 (const_string "single")
331                 (const_string "multi")))
333 ;; FAR_JUMP is "yes" if a BL instruction is used to generate a branch to a
334 ;; distant label.  Only applicable to Thumb code.
335 (define_attr "far_jump" "yes,no" (const_string "no"))
338 ;; The number of machine instructions this pattern expands to.
339 ;; Used for Thumb-2 conditional execution.
340 (define_attr "ce_count" "" (const_int 1))
342 ;;---------------------------------------------------------------------------
343 ;; Unspecs
345 (include "unspecs.md")
347 ;;---------------------------------------------------------------------------
348 ;; Mode iterators
350 (include "iterators.md")
352 ;;---------------------------------------------------------------------------
353 ;; Predicates
355 (include "predicates.md")
356 (include "constraints.md")
358 ;;---------------------------------------------------------------------------
359 ;; Pipeline descriptions
361 (define_attr "tune_cortexr4" "yes,no"
362   (const (if_then_else
363           (eq_attr "tune" "cortexr4,cortexr4f,cortexr5")
364           (const_string "yes")
365           (const_string "no"))))
367 ;; True if the generic scheduling description should be used.
369 (define_attr "generic_sched" "yes,no"
370   (const (if_then_else
371           (ior (eq_attr "tune" "fa526,fa626,fa606te,fa626te,fmp626,fa726te,\
372                                 arm926ejs,arm1020e,arm1026ejs,arm1136js,\
373                                 arm1136jfs,cortexa5,cortexa7,cortexa8,\
374                                 cortexa9,cortexa12,cortexa15,cortexa17,\
375                                 cortexa53,cortexa57,cortexm4,cortexm7,\
376                                 marvell_pj4,xgene1")
377                (eq_attr "tune_cortexr4" "yes"))
378           (const_string "no")
379           (const_string "yes"))))
381 (define_attr "generic_vfp" "yes,no"
382   (const (if_then_else
383           (and (eq_attr "fpu" "vfp")
384                (eq_attr "tune" "!arm1020e,arm1022e,cortexa5,cortexa7,\
385                                 cortexa8,cortexa9,cortexa53,cortexm4,\
386                                 cortexm7,marvell_pj4,xgene1")
387                (eq_attr "tune_cortexr4" "no"))
388           (const_string "yes")
389           (const_string "no"))))
391 (include "marvell-f-iwmmxt.md")
392 (include "arm-generic.md")
393 (include "arm926ejs.md")
394 (include "arm1020e.md")
395 (include "arm1026ejs.md")
396 (include "arm1136jfs.md")
397 (include "fa526.md")
398 (include "fa606te.md")
399 (include "fa626te.md")
400 (include "fmp626.md")
401 (include "fa726te.md")
402 (include "cortex-a5.md")
403 (include "cortex-a7.md")
404 (include "cortex-a8.md")
405 (include "cortex-a9.md")
406 (include "cortex-a15.md")
407 (include "cortex-a17.md")
408 (include "cortex-a53.md")
409 (include "cortex-a57.md")
410 (include "cortex-r4.md")
411 (include "cortex-r4f.md")
412 (include "cortex-m7.md")
413 (include "cortex-m4.md")
414 (include "cortex-m4-fpu.md")
415 (include "vfp11.md")
416 (include "marvell-pj4.md")
417 (include "xgene1.md")
420 ;;---------------------------------------------------------------------------
421 ;; Insn patterns
423 ;; Addition insns.
425 ;; Note: For DImode insns, there is normally no reason why operands should
426 ;; not be in the same register, what we don't want is for something being
427 ;; written to partially overlap something that is an input.
429 (define_expand "adddi3"
430  [(parallel
431    [(set (match_operand:DI           0 "s_register_operand" "")
432           (plus:DI (match_operand:DI 1 "s_register_operand" "")
433                    (match_operand:DI 2 "arm_adddi_operand"  "")))
434     (clobber (reg:CC CC_REGNUM))])]
435   "TARGET_EITHER"
436   "
437   if (TARGET_THUMB1)
438     {
439       if (!REG_P (operands[1]))
440         operands[1] = force_reg (DImode, operands[1]);
441       if (!REG_P (operands[2]))
442         operands[2] = force_reg (DImode, operands[2]);
443      }
444   "
447 (define_insn_and_split "*arm_adddi3"
448   [(set (match_operand:DI          0 "s_register_operand" "=&r,&r,&r,&r,&r")
449         (plus:DI (match_operand:DI 1 "s_register_operand" "%0, 0, r, 0, r")
450                  (match_operand:DI 2 "arm_adddi_operand"  "r,  0, r, Dd, Dd")))
451    (clobber (reg:CC CC_REGNUM))]
452   "TARGET_32BIT && !TARGET_NEON"
453   "#"
454   "TARGET_32BIT && reload_completed
455    && ! (TARGET_NEON && IS_VFP_REGNUM (REGNO (operands[0])))"
456   [(parallel [(set (reg:CC_C CC_REGNUM)
457                    (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
458                                  (match_dup 1)))
459               (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
460    (set (match_dup 3) (plus:SI (plus:SI (match_dup 4) (match_dup 5))
461                                (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
462   "
463   {
464     operands[3] = gen_highpart (SImode, operands[0]);
465     operands[0] = gen_lowpart (SImode, operands[0]);
466     operands[4] = gen_highpart (SImode, operands[1]);
467     operands[1] = gen_lowpart (SImode, operands[1]);
468     operands[5] = gen_highpart_mode (SImode, DImode, operands[2]);
469     operands[2] = gen_lowpart (SImode, operands[2]);
470   }"
471   [(set_attr "conds" "clob")
472    (set_attr "length" "8")
473    (set_attr "type" "multiple")]
476 (define_insn_and_split "*adddi_sesidi_di"
477   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
478         (plus:DI (sign_extend:DI
479                   (match_operand:SI 2 "s_register_operand" "r,r"))
480                  (match_operand:DI 1 "s_register_operand" "0,r")))
481    (clobber (reg:CC CC_REGNUM))]
482   "TARGET_32BIT"
483   "#"
484   "TARGET_32BIT && reload_completed"
485   [(parallel [(set (reg:CC_C CC_REGNUM)
486                    (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
487                                  (match_dup 1)))
488               (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
489    (set (match_dup 3) (plus:SI (plus:SI (ashiftrt:SI (match_dup 2)
490                                                      (const_int 31))
491                                         (match_dup 4))
492                                (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
493   "
494   {
495     operands[3] = gen_highpart (SImode, operands[0]);
496     operands[0] = gen_lowpart (SImode, operands[0]);
497     operands[4] = gen_highpart (SImode, operands[1]);
498     operands[1] = gen_lowpart (SImode, operands[1]);
499     operands[2] = gen_lowpart (SImode, operands[2]);
500   }"
501   [(set_attr "conds" "clob")
502    (set_attr "length" "8")
503    (set_attr "type" "multiple")]
506 (define_insn_and_split "*adddi_zesidi_di"
507   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
508         (plus:DI (zero_extend:DI
509                   (match_operand:SI 2 "s_register_operand" "r,r"))
510                  (match_operand:DI 1 "s_register_operand" "0,r")))
511    (clobber (reg:CC CC_REGNUM))]
512   "TARGET_32BIT"
513   "#"
514   "TARGET_32BIT && reload_completed"
515   [(parallel [(set (reg:CC_C CC_REGNUM)
516                    (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
517                                  (match_dup 1)))
518               (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
519    (set (match_dup 3) (plus:SI (plus:SI (match_dup 4) (const_int 0))
520                                (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
521   "
522   {
523     operands[3] = gen_highpart (SImode, operands[0]);
524     operands[0] = gen_lowpart (SImode, operands[0]);
525     operands[4] = gen_highpart (SImode, operands[1]);
526     operands[1] = gen_lowpart (SImode, operands[1]);
527     operands[2] = gen_lowpart (SImode, operands[2]);
528   }"
529   [(set_attr "conds" "clob")
530    (set_attr "length" "8")
531    (set_attr "type" "multiple")]
534 (define_expand "addsi3"
535   [(set (match_operand:SI          0 "s_register_operand" "")
536         (plus:SI (match_operand:SI 1 "s_register_operand" "")
537                  (match_operand:SI 2 "reg_or_int_operand" "")))]
538   "TARGET_EITHER"
539   "
540   if (TARGET_32BIT && CONST_INT_P (operands[2]))
541     {
542       arm_split_constant (PLUS, SImode, NULL_RTX,
543                           INTVAL (operands[2]), operands[0], operands[1],
544                           optimize && can_create_pseudo_p ());
545       DONE;
546     }
547   "
550 ; If there is a scratch available, this will be faster than synthesizing the
551 ; addition.
552 (define_peephole2
553   [(match_scratch:SI 3 "r")
554    (set (match_operand:SI          0 "arm_general_register_operand" "")
555         (plus:SI (match_operand:SI 1 "arm_general_register_operand" "")
556                  (match_operand:SI 2 "const_int_operand"  "")))]
557   "TARGET_32BIT &&
558    !(const_ok_for_arm (INTVAL (operands[2]))
559      || const_ok_for_arm (-INTVAL (operands[2])))
560     && const_ok_for_arm (~INTVAL (operands[2]))"
561   [(set (match_dup 3) (match_dup 2))
562    (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 3)))]
563   ""
566 ;; The r/r/k alternative is required when reloading the address
567 ;;  (plus (reg rN) (reg sp)) into (reg rN).  In this case reload will
568 ;; put the duplicated register first, and not try the commutative version.
569 (define_insn_and_split "*arm_addsi3"
570   [(set (match_operand:SI          0 "s_register_operand" "=rk,l,l ,l ,r ,k ,r,r ,k ,r ,k,k,r ,k ,r")
571         (plus:SI (match_operand:SI 1 "s_register_operand" "%0 ,l,0 ,l ,rk,k ,r,rk,k ,rk,k,r,rk,k ,rk")
572                  (match_operand:SI 2 "reg_or_int_operand" "rk ,l,Py,Pd,rI,rI,k,Pj,Pj,L ,L,L,PJ,PJ,?n")))]
573   "TARGET_32BIT"
574   "@
575    add%?\\t%0, %0, %2
576    add%?\\t%0, %1, %2
577    add%?\\t%0, %1, %2
578    add%?\\t%0, %1, %2
579    add%?\\t%0, %1, %2
580    add%?\\t%0, %1, %2
581    add%?\\t%0, %2, %1
582    addw%?\\t%0, %1, %2
583    addw%?\\t%0, %1, %2
584    sub%?\\t%0, %1, #%n2
585    sub%?\\t%0, %1, #%n2
586    sub%?\\t%0, %1, #%n2
587    subw%?\\t%0, %1, #%n2
588    subw%?\\t%0, %1, #%n2
589    #"
590   "TARGET_32BIT
591    && CONST_INT_P (operands[2])
592    && !const_ok_for_op (INTVAL (operands[2]), PLUS)
593    && (reload_completed || !arm_eliminable_register (operands[1]))"
594   [(clobber (const_int 0))]
595   "
596   arm_split_constant (PLUS, SImode, curr_insn,
597                       INTVAL (operands[2]), operands[0],
598                       operands[1], 0);
599   DONE;
600   "
601   [(set_attr "length" "2,4,4,4,4,4,4,4,4,4,4,4,4,4,16")
602    (set_attr "predicable" "yes")
603    (set_attr "predicable_short_it" "yes,yes,yes,yes,no,no,no,no,no,no,no,no,no,no,no")
604    (set_attr "arch" "t2,t2,t2,t2,*,*,*,t2,t2,*,*,a,t2,t2,*")
605    (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
606                       (const_string "alu_imm")
607                       (const_string "alu_sreg")))
611 (define_insn "addsi3_compare0"
612   [(set (reg:CC_NOOV CC_REGNUM)
613         (compare:CC_NOOV
614          (plus:SI (match_operand:SI 1 "s_register_operand" "r, r,r")
615                   (match_operand:SI 2 "arm_add_operand"    "I,L,r"))
616          (const_int 0)))
617    (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
618         (plus:SI (match_dup 1) (match_dup 2)))]
619   "TARGET_ARM"
620   "@
621    add%.\\t%0, %1, %2
622    sub%.\\t%0, %1, #%n2
623    add%.\\t%0, %1, %2"
624   [(set_attr "conds" "set")
625    (set_attr "type" "alus_imm,alus_imm,alus_sreg")]
628 (define_insn "*addsi3_compare0_scratch"
629   [(set (reg:CC_NOOV CC_REGNUM)
630         (compare:CC_NOOV
631          (plus:SI (match_operand:SI 0 "s_register_operand" "r, r, r")
632                   (match_operand:SI 1 "arm_add_operand"    "I,L, r"))
633          (const_int 0)))]
634   "TARGET_ARM"
635   "@
636    cmn%?\\t%0, %1
637    cmp%?\\t%0, #%n1
638    cmn%?\\t%0, %1"
639   [(set_attr "conds" "set")
640    (set_attr "predicable" "yes")
641    (set_attr "type" "alus_imm,alus_imm,alus_sreg")]
644 (define_insn "*compare_negsi_si"
645   [(set (reg:CC_Z CC_REGNUM)
646         (compare:CC_Z
647          (neg:SI (match_operand:SI 0 "s_register_operand" "l,r"))
648          (match_operand:SI 1 "s_register_operand" "l,r")))]
649   "TARGET_32BIT"
650   "cmn%?\\t%1, %0"
651   [(set_attr "conds" "set")
652    (set_attr "predicable" "yes")
653    (set_attr "arch" "t2,*")
654    (set_attr "length" "2,4")
655    (set_attr "predicable_short_it" "yes,no")
656    (set_attr "type" "alus_sreg")]
659 ;; This is the canonicalization of addsi3_compare0_for_combiner when the
660 ;; addend is a constant.
661 (define_insn "cmpsi2_addneg"
662   [(set (reg:CC CC_REGNUM)
663         (compare:CC
664          (match_operand:SI 1 "s_register_operand" "r,r")
665          (match_operand:SI 2 "arm_addimm_operand" "L,I")))
666    (set (match_operand:SI 0 "s_register_operand" "=r,r")
667         (plus:SI (match_dup 1)
668                  (match_operand:SI 3 "arm_addimm_operand" "I,L")))]
669   "TARGET_32BIT && INTVAL (operands[2]) == -INTVAL (operands[3])"
670   "@
671    add%.\\t%0, %1, %3
672    sub%.\\t%0, %1, #%n3"
673   [(set_attr "conds" "set")
674    (set_attr "type" "alus_sreg")]
677 ;; Convert the sequence
678 ;;  sub  rd, rn, #1
679 ;;  cmn  rd, #1 (equivalent to cmp rd, #-1)
680 ;;  bne  dest
681 ;; into
682 ;;  subs rd, rn, #1
683 ;;  bcs  dest   ((unsigned)rn >= 1)
684 ;; similarly for the beq variant using bcc.
685 ;; This is a common looping idiom (while (n--))
686 (define_peephole2
687   [(set (match_operand:SI 0 "arm_general_register_operand" "")
688         (plus:SI (match_operand:SI 1 "arm_general_register_operand" "")
689                  (const_int -1)))
690    (set (match_operand 2 "cc_register" "")
691         (compare (match_dup 0) (const_int -1)))
692    (set (pc)
693         (if_then_else (match_operator 3 "equality_operator"
694                        [(match_dup 2) (const_int 0)])
695                       (match_operand 4 "" "")
696                       (match_operand 5 "" "")))]
697   "TARGET_32BIT && peep2_reg_dead_p (3, operands[2])"
698   [(parallel[
699     (set (match_dup 2)
700          (compare:CC
701           (match_dup 1) (const_int 1)))
702     (set (match_dup 0) (plus:SI (match_dup 1) (const_int -1)))])
703    (set (pc)
704         (if_then_else (match_op_dup 3 [(match_dup 2) (const_int 0)])
705                       (match_dup 4)
706                       (match_dup 5)))]
707   "operands[2] = gen_rtx_REG (CCmode, CC_REGNUM);
708    operands[3] = gen_rtx_fmt_ee ((GET_CODE (operands[3]) == NE
709                                   ? GEU : LTU),
710                                  VOIDmode, 
711                                  operands[2], const0_rtx);"
714 ;; The next four insns work because they compare the result with one of
715 ;; the operands, and we know that the use of the condition code is
716 ;; either GEU or LTU, so we can use the carry flag from the addition
717 ;; instead of doing the compare a second time.
718 (define_insn "*addsi3_compare_op1"
719   [(set (reg:CC_C CC_REGNUM)
720         (compare:CC_C
721          (plus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
722                   (match_operand:SI 2 "arm_add_operand" "I,L,r"))
723          (match_dup 1)))
724    (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
725         (plus:SI (match_dup 1) (match_dup 2)))]
726   "TARGET_32BIT"
727   "@
728    add%.\\t%0, %1, %2
729    sub%.\\t%0, %1, #%n2
730    add%.\\t%0, %1, %2"
731   [(set_attr "conds" "set")
732    (set_attr "type"  "alus_imm,alus_imm,alus_sreg")]
735 (define_insn "*addsi3_compare_op2"
736   [(set (reg:CC_C CC_REGNUM)
737         (compare:CC_C
738          (plus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
739                   (match_operand:SI 2 "arm_add_operand" "I,L,r"))
740          (match_dup 2)))
741    (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
742         (plus:SI (match_dup 1) (match_dup 2)))]
743   "TARGET_32BIT"
744   "@
745    add%.\\t%0, %1, %2
746    add%.\\t%0, %1, %2
747    sub%.\\t%0, %1, #%n2"
748   [(set_attr "conds" "set")
749    (set_attr "type" "alus_imm,alus_imm,alus_sreg")]
752 (define_insn "*compare_addsi2_op0"
753   [(set (reg:CC_C CC_REGNUM)
754         (compare:CC_C
755           (plus:SI (match_operand:SI 0 "s_register_operand" "l,l,r,r,r")
756                    (match_operand:SI 1 "arm_add_operand" "Pv,l,I,L,r"))
757           (match_dup 0)))]
758   "TARGET_32BIT"
759   "@
760    cmp%?\\t%0, #%n1
761    cmn%?\\t%0, %1
762    cmn%?\\t%0, %1
763    cmp%?\\t%0, #%n1
764    cmn%?\\t%0, %1"
765   [(set_attr "conds" "set")
766    (set_attr "predicable" "yes")
767    (set_attr "arch" "t2,t2,*,*,*")
768    (set_attr "predicable_short_it" "yes,yes,no,no,no")
769    (set_attr "length" "2,2,4,4,4")
770    (set_attr "type" "alus_imm,alus_sreg,alus_imm,alus_imm,alus_sreg")]
773 (define_insn "*compare_addsi2_op1"
774   [(set (reg:CC_C CC_REGNUM)
775         (compare:CC_C
776           (plus:SI (match_operand:SI 0 "s_register_operand" "l,l,r,r,r")
777                    (match_operand:SI 1 "arm_add_operand" "Pv,l,I,L,r"))
778           (match_dup 1)))]
779   "TARGET_32BIT"
780   "@
781    cmp%?\\t%0, #%n1
782    cmn%?\\t%0, %1
783    cmn%?\\t%0, %1
784    cmp%?\\t%0, #%n1
785    cmn%?\\t%0, %1"
786   [(set_attr "conds" "set")
787    (set_attr "predicable" "yes")
788    (set_attr "arch" "t2,t2,*,*,*")
789    (set_attr "predicable_short_it" "yes,yes,no,no,no")
790    (set_attr "length" "2,2,4,4,4")
791    (set_attr "type" "alus_imm,alus_sreg,alus_imm,alus_imm,alus_sreg")]
794 (define_insn "*addsi3_carryin_<optab>"
795   [(set (match_operand:SI 0 "s_register_operand" "=l,r,r")
796         (plus:SI (plus:SI (match_operand:SI 1 "s_register_operand" "%l,r,r")
797                           (match_operand:SI 2 "arm_not_operand" "0,rI,K"))
798                  (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))))]
799   "TARGET_32BIT"
800   "@
801    adc%?\\t%0, %1, %2
802    adc%?\\t%0, %1, %2
803    sbc%?\\t%0, %1, #%B2"
804   [(set_attr "conds" "use")
805    (set_attr "predicable" "yes")
806    (set_attr "arch" "t2,*,*")
807    (set_attr "length" "4")
808    (set_attr "predicable_short_it" "yes,no,no")
809    (set_attr "type" "adc_reg,adc_reg,adc_imm")]
812 (define_insn "*addsi3_carryin_alt2_<optab>"
813   [(set (match_operand:SI 0 "s_register_operand" "=l,r,r")
814         (plus:SI (plus:SI (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))
815                           (match_operand:SI 1 "s_register_operand" "%l,r,r"))
816                  (match_operand:SI 2 "arm_rhs_operand" "l,rI,K")))]
817   "TARGET_32BIT"
818   "@
819    adc%?\\t%0, %1, %2
820    adc%?\\t%0, %1, %2
821    sbc%?\\t%0, %1, #%B2"
822   [(set_attr "conds" "use")
823    (set_attr "predicable" "yes")
824    (set_attr "arch" "t2,*,*")
825    (set_attr "length" "4")
826    (set_attr "predicable_short_it" "yes,no,no")
827    (set_attr "type" "adc_reg,adc_reg,adc_imm")]
830 (define_insn "*addsi3_carryin_shift_<optab>"
831   [(set (match_operand:SI 0 "s_register_operand" "=r")
832         (plus:SI (plus:SI
833                   (match_operator:SI 2 "shift_operator"
834                     [(match_operand:SI 3 "s_register_operand" "r")
835                      (match_operand:SI 4 "reg_or_int_operand" "rM")])
836                   (match_operand:SI 1 "s_register_operand" "r"))
837                  (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))))]
838   "TARGET_32BIT"
839   "adc%?\\t%0, %1, %3%S2"
840   [(set_attr "conds" "use")
841    (set_attr "predicable" "yes")
842    (set_attr "predicable_short_it" "no")
843    (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
844                       (const_string "alu_shift_imm")
845                       (const_string "alu_shift_reg")))]
848 (define_insn "*addsi3_carryin_clobercc_<optab>"
849   [(set (match_operand:SI 0 "s_register_operand" "=r")
850         (plus:SI (plus:SI (match_operand:SI 1 "s_register_operand" "%r")
851                           (match_operand:SI 2 "arm_rhs_operand" "rI"))
852                  (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))))
853    (clobber (reg:CC CC_REGNUM))]
854    "TARGET_32BIT"
855    "adc%.\\t%0, %1, %2"
856    [(set_attr "conds" "set")
857     (set_attr "type" "adcs_reg")]
860 (define_insn "*subsi3_carryin"
861   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
862         (minus:SI (minus:SI (match_operand:SI 1 "reg_or_int_operand" "r,I")
863                             (match_operand:SI 2 "s_register_operand" "r,r"))
864                   (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
865   "TARGET_32BIT"
866   "@
867    sbc%?\\t%0, %1, %2
868    rsc%?\\t%0, %2, %1"
869   [(set_attr "conds" "use")
870    (set_attr "arch" "*,a")
871    (set_attr "predicable" "yes")
872    (set_attr "predicable_short_it" "no")
873    (set_attr "type" "adc_reg,adc_imm")]
876 (define_insn "*subsi3_carryin_const"
877   [(set (match_operand:SI 0 "s_register_operand" "=r")
878         (minus:SI (plus:SI (match_operand:SI 1 "reg_or_int_operand" "r")
879                            (match_operand:SI 2 "arm_not_operand" "K"))
880                   (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
881   "TARGET_32BIT"
882   "sbc\\t%0, %1, #%B2"
883   [(set_attr "conds" "use")
884    (set_attr "type" "adc_imm")]
887 (define_insn "*subsi3_carryin_compare"
888   [(set (reg:CC CC_REGNUM)
889         (compare:CC (match_operand:SI 1 "s_register_operand" "r")
890                     (match_operand:SI 2 "s_register_operand" "r")))
891    (set (match_operand:SI 0 "s_register_operand" "=r")
892         (minus:SI (minus:SI (match_dup 1)
893                             (match_dup 2))
894                   (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
895   "TARGET_32BIT"
896   "sbcs\\t%0, %1, %2"
897   [(set_attr "conds" "set")
898    (set_attr "type" "adcs_reg")]
901 (define_insn "*subsi3_carryin_compare_const"
902   [(set (reg:CC CC_REGNUM)
903         (compare:CC (match_operand:SI 1 "reg_or_int_operand" "r")
904                     (match_operand:SI 2 "arm_not_operand" "K")))
905    (set (match_operand:SI 0 "s_register_operand" "=r")
906         (minus:SI (plus:SI (match_dup 1)
907                            (match_dup 2))
908                   (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
909   "TARGET_32BIT"
910   "sbcs\\t%0, %1, #%B2"
911   [(set_attr "conds" "set")
912    (set_attr "type" "adcs_imm")]
915 (define_insn "*subsi3_carryin_shift"
916   [(set (match_operand:SI 0 "s_register_operand" "=r")
917         (minus:SI (minus:SI
918                   (match_operand:SI 1 "s_register_operand" "r")
919                   (match_operator:SI 2 "shift_operator"
920                    [(match_operand:SI 3 "s_register_operand" "r")
921                     (match_operand:SI 4 "reg_or_int_operand" "rM")]))
922                  (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
923   "TARGET_32BIT"
924   "sbc%?\\t%0, %1, %3%S2"
925   [(set_attr "conds" "use")
926    (set_attr "predicable" "yes")
927    (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
928                       (const_string "alu_shift_imm")
929                      (const_string "alu_shift_reg")))]
932 (define_insn "*rsbsi3_carryin_shift"
933   [(set (match_operand:SI 0 "s_register_operand" "=r")
934         (minus:SI (minus:SI
935                   (match_operator:SI 2 "shift_operator"
936                    [(match_operand:SI 3 "s_register_operand" "r")
937                     (match_operand:SI 4 "reg_or_int_operand" "rM")])
938                    (match_operand:SI 1 "s_register_operand" "r"))
939                  (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
940   "TARGET_ARM"
941   "rsc%?\\t%0, %1, %3%S2"
942   [(set_attr "conds" "use")
943    (set_attr "predicable" "yes")
944    (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
945                       (const_string "alu_shift_imm")
946                       (const_string "alu_shift_reg")))]
949 ; transform ((x << y) - 1) to ~(~(x-1) << y)  Where X is a constant.
950 (define_split
951   [(set (match_operand:SI 0 "s_register_operand" "")
952         (plus:SI (ashift:SI (match_operand:SI 1 "const_int_operand" "")
953                             (match_operand:SI 2 "s_register_operand" ""))
954                  (const_int -1)))
955    (clobber (match_operand:SI 3 "s_register_operand" ""))]
956   "TARGET_32BIT"
957   [(set (match_dup 3) (match_dup 1))
958    (set (match_dup 0) (not:SI (ashift:SI (match_dup 3) (match_dup 2))))]
959   "
960   operands[1] = GEN_INT (~(INTVAL (operands[1]) - 1));
963 (define_expand "addsf3"
964   [(set (match_operand:SF          0 "s_register_operand" "")
965         (plus:SF (match_operand:SF 1 "s_register_operand" "")
966                  (match_operand:SF 2 "s_register_operand" "")))]
967   "TARGET_32BIT && TARGET_HARD_FLOAT"
968   "
971 (define_expand "adddf3"
972   [(set (match_operand:DF          0 "s_register_operand" "")
973         (plus:DF (match_operand:DF 1 "s_register_operand" "")
974                  (match_operand:DF 2 "s_register_operand" "")))]
975   "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
976   "
979 (define_expand "subdi3"
980  [(parallel
981    [(set (match_operand:DI            0 "s_register_operand" "")
982           (minus:DI (match_operand:DI 1 "s_register_operand" "")
983                     (match_operand:DI 2 "s_register_operand" "")))
984     (clobber (reg:CC CC_REGNUM))])]
985   "TARGET_EITHER"
986   "
987   if (TARGET_THUMB1)
988     {
989       if (!REG_P (operands[1]))
990         operands[1] = force_reg (DImode, operands[1]);
991       if (!REG_P (operands[2]))
992         operands[2] = force_reg (DImode, operands[2]);
993      }  
994   "
997 (define_insn_and_split "*arm_subdi3"
998   [(set (match_operand:DI           0 "s_register_operand" "=&r,&r,&r")
999         (minus:DI (match_operand:DI 1 "s_register_operand" "0,r,0")
1000                   (match_operand:DI 2 "s_register_operand" "r,0,0")))
1001    (clobber (reg:CC CC_REGNUM))]
1002   "TARGET_32BIT && !TARGET_NEON"
1003   "#"  ; "subs\\t%Q0, %Q1, %Q2\;sbc\\t%R0, %R1, %R2"
1004   "&& reload_completed"
1005   [(parallel [(set (reg:CC CC_REGNUM)
1006                    (compare:CC (match_dup 1) (match_dup 2)))
1007               (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1008    (set (match_dup 3) (minus:SI (minus:SI (match_dup 4) (match_dup 5))
1009                                (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1010   {
1011     operands[3] = gen_highpart (SImode, operands[0]);
1012     operands[0] = gen_lowpart (SImode, operands[0]);
1013     operands[4] = gen_highpart (SImode, operands[1]);
1014     operands[1] = gen_lowpart (SImode, operands[1]);
1015     operands[5] = gen_highpart (SImode, operands[2]);
1016     operands[2] = gen_lowpart (SImode, operands[2]);
1017    }
1018   [(set_attr "conds" "clob")
1019    (set_attr "length" "8")
1020    (set_attr "type" "multiple")]
1023 (define_insn_and_split "*subdi_di_zesidi"
1024   [(set (match_operand:DI           0 "s_register_operand" "=&r,&r")
1025         (minus:DI (match_operand:DI 1 "s_register_operand"  "0,r")
1026                   (zero_extend:DI
1027                    (match_operand:SI 2 "s_register_operand"  "r,r"))))
1028    (clobber (reg:CC CC_REGNUM))]
1029   "TARGET_32BIT"
1030   "#"   ; "subs\\t%Q0, %Q1, %2\;sbc\\t%R0, %R1, #0"
1031   "&& reload_completed"
1032   [(parallel [(set (reg:CC CC_REGNUM)
1033                    (compare:CC (match_dup 1) (match_dup 2)))
1034               (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1035    (set (match_dup 3) (minus:SI (plus:SI (match_dup 4) (match_dup 5))
1036                                 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1037   {
1038     operands[3] = gen_highpart (SImode, operands[0]);
1039     operands[0] = gen_lowpart (SImode, operands[0]);
1040     operands[4] = gen_highpart (SImode, operands[1]);
1041     operands[1] = gen_lowpart (SImode, operands[1]);
1042     operands[5] = GEN_INT (~0);
1043    }
1044   [(set_attr "conds" "clob")
1045    (set_attr "length" "8")
1046    (set_attr "type" "multiple")]
1049 (define_insn_and_split "*subdi_di_sesidi"
1050   [(set (match_operand:DI            0 "s_register_operand" "=&r,&r")
1051         (minus:DI (match_operand:DI  1 "s_register_operand"  "0,r")
1052                   (sign_extend:DI
1053                    (match_operand:SI 2 "s_register_operand"  "r,r"))))
1054    (clobber (reg:CC CC_REGNUM))]
1055   "TARGET_32BIT"
1056   "#"   ; "subs\\t%Q0, %Q1, %2\;sbc\\t%R0, %R1, %2, asr #31"
1057   "&& reload_completed"
1058   [(parallel [(set (reg:CC CC_REGNUM)
1059                    (compare:CC (match_dup 1) (match_dup 2)))
1060               (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1061    (set (match_dup 3) (minus:SI (minus:SI (match_dup 4)
1062                                          (ashiftrt:SI (match_dup 2)
1063                                                       (const_int 31)))
1064                                 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1065   {
1066     operands[3] = gen_highpart (SImode, operands[0]);
1067     operands[0] = gen_lowpart (SImode, operands[0]);
1068     operands[4] = gen_highpart (SImode, operands[1]);
1069     operands[1] = gen_lowpart (SImode, operands[1]);
1070   }
1071   [(set_attr "conds" "clob")
1072    (set_attr "length" "8")
1073    (set_attr "type" "multiple")]
1076 (define_insn_and_split "*subdi_zesidi_di"
1077   [(set (match_operand:DI            0 "s_register_operand" "=&r,&r")
1078         (minus:DI (zero_extend:DI
1079                    (match_operand:SI 2 "s_register_operand"  "r,r"))
1080                   (match_operand:DI  1 "s_register_operand" "0,r")))
1081    (clobber (reg:CC CC_REGNUM))]
1082   "TARGET_ARM"
1083   "#"   ; "rsbs\\t%Q0, %Q1, %2\;rsc\\t%R0, %R1, #0"
1084         ; is equivalent to:
1085         ; "subs\\t%Q0, %2, %Q1\;rsc\\t%R0, %R1, #0"
1086   "&& reload_completed"
1087   [(parallel [(set (reg:CC CC_REGNUM)
1088                    (compare:CC (match_dup 2) (match_dup 1)))
1089               (set (match_dup 0) (minus:SI (match_dup 2) (match_dup 1)))])
1090    (set (match_dup 3) (minus:SI (minus:SI (const_int 0) (match_dup 4))
1091                                (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1092   {
1093     operands[3] = gen_highpart (SImode, operands[0]);
1094     operands[0] = gen_lowpart (SImode, operands[0]);
1095     operands[4] = gen_highpart (SImode, operands[1]);
1096     operands[1] = gen_lowpart (SImode, operands[1]);
1097   }
1098   [(set_attr "conds" "clob")
1099    (set_attr "length" "8")
1100    (set_attr "type" "multiple")]
1103 (define_insn_and_split "*subdi_sesidi_di"
1104   [(set (match_operand:DI            0 "s_register_operand" "=&r,&r")
1105         (minus:DI (sign_extend:DI
1106                    (match_operand:SI 2 "s_register_operand"   "r,r"))
1107                   (match_operand:DI  1 "s_register_operand"  "0,r")))
1108    (clobber (reg:CC CC_REGNUM))]
1109   "TARGET_ARM"
1110   "#"   ; "rsbs\\t%Q0, %Q1, %2\;rsc\\t%R0, %R1, %2, asr #31"
1111         ; is equivalent to:
1112         ; "subs\\t%Q0, %2, %Q1\;rsc\\t%R0, %R1, %2, asr #31"
1113   "&& reload_completed"
1114   [(parallel [(set (reg:CC CC_REGNUM)
1115                    (compare:CC (match_dup 2) (match_dup 1)))
1116               (set (match_dup 0) (minus:SI (match_dup 2) (match_dup 1)))])
1117    (set (match_dup 3) (minus:SI (minus:SI
1118                                 (ashiftrt:SI (match_dup 2)
1119                                              (const_int 31))
1120                                 (match_dup 4))
1121                                (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1122   {
1123     operands[3] = gen_highpart (SImode, operands[0]);
1124     operands[0] = gen_lowpart (SImode, operands[0]);
1125     operands[4] = gen_highpart (SImode, operands[1]);
1126     operands[1] = gen_lowpart (SImode, operands[1]);
1127   }
1128   [(set_attr "conds" "clob")
1129    (set_attr "length" "8")
1130    (set_attr "type" "multiple")]
1133 (define_insn_and_split "*subdi_zesidi_zesidi"
1134   [(set (match_operand:DI            0 "s_register_operand" "=r")
1135         (minus:DI (zero_extend:DI
1136                    (match_operand:SI 1 "s_register_operand"  "r"))
1137                   (zero_extend:DI
1138                    (match_operand:SI 2 "s_register_operand"  "r"))))
1139    (clobber (reg:CC CC_REGNUM))]
1140   "TARGET_32BIT"
1141   "#"   ; "subs\\t%Q0, %1, %2\;sbc\\t%R0, %1, %1"
1142   "&& reload_completed"
1143   [(parallel [(set (reg:CC CC_REGNUM)
1144                    (compare:CC (match_dup 1) (match_dup 2)))
1145               (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1146    (set (match_dup 3) (minus:SI (minus:SI (match_dup 1) (match_dup 1))
1147                                (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1148   {
1149        operands[3] = gen_highpart (SImode, operands[0]);
1150        operands[0] = gen_lowpart (SImode, operands[0]);
1151   }
1152   [(set_attr "conds" "clob")
1153    (set_attr "length" "8")
1154    (set_attr "type" "multiple")]
1157 (define_expand "subsi3"
1158   [(set (match_operand:SI           0 "s_register_operand" "")
1159         (minus:SI (match_operand:SI 1 "reg_or_int_operand" "")
1160                   (match_operand:SI 2 "s_register_operand" "")))]
1161   "TARGET_EITHER"
1162   "
1163   if (CONST_INT_P (operands[1]))
1164     {
1165       if (TARGET_32BIT)
1166         {
1167           arm_split_constant (MINUS, SImode, NULL_RTX,
1168                               INTVAL (operands[1]), operands[0],
1169                               operands[2], optimize && can_create_pseudo_p ());
1170           DONE;
1171         }
1172       else /* TARGET_THUMB1 */
1173         operands[1] = force_reg (SImode, operands[1]);
1174     }
1175   "
1178 ; ??? Check Thumb-2 split length
1179 (define_insn_and_split "*arm_subsi3_insn"
1180   [(set (match_operand:SI           0 "s_register_operand" "=l,l ,l ,l ,r,r,r,rk,r")
1181         (minus:SI (match_operand:SI 1 "reg_or_int_operand" "l ,0 ,l ,Pz,I,r,r,k ,?n")
1182                   (match_operand:SI 2 "reg_or_int_operand" "l ,Py,Pd,l ,r,I,r,r ,r")))]
1183   "TARGET_32BIT"
1184   "@
1185    sub%?\\t%0, %1, %2
1186    sub%?\\t%0, %2
1187    sub%?\\t%0, %1, %2
1188    rsb%?\\t%0, %2, %1
1189    rsb%?\\t%0, %2, %1
1190    sub%?\\t%0, %1, %2
1191    sub%?\\t%0, %1, %2
1192    sub%?\\t%0, %1, %2
1193    #"
1194   "&& (CONST_INT_P (operands[1])
1195        && !const_ok_for_arm (INTVAL (operands[1])))"
1196   [(clobber (const_int 0))]
1197   "
1198   arm_split_constant (MINUS, SImode, curr_insn,
1199                       INTVAL (operands[1]), operands[0], operands[2], 0);
1200   DONE;
1201   "
1202   [(set_attr "length" "4,4,4,4,4,4,4,4,16")
1203    (set_attr "arch" "t2,t2,t2,t2,*,*,*,*,*")
1204    (set_attr "predicable" "yes")
1205    (set_attr "predicable_short_it" "yes,yes,yes,yes,no,no,no,no,no")
1206    (set_attr "type" "alu_sreg,alu_sreg,alu_sreg,alu_sreg,alu_imm,alu_imm,alu_sreg,alu_sreg,multiple")]
1209 (define_peephole2
1210   [(match_scratch:SI 3 "r")
1211    (set (match_operand:SI 0 "arm_general_register_operand" "")
1212         (minus:SI (match_operand:SI 1 "const_int_operand" "")
1213                   (match_operand:SI 2 "arm_general_register_operand" "")))]
1214   "TARGET_32BIT
1215    && !const_ok_for_arm (INTVAL (operands[1]))
1216    && const_ok_for_arm (~INTVAL (operands[1]))"
1217   [(set (match_dup 3) (match_dup 1))
1218    (set (match_dup 0) (minus:SI (match_dup 3) (match_dup 2)))]
1219   ""
1222 (define_insn "*subsi3_compare0"
1223   [(set (reg:CC_NOOV CC_REGNUM)
1224         (compare:CC_NOOV
1225          (minus:SI (match_operand:SI 1 "arm_rhs_operand" "r,r,I")
1226                    (match_operand:SI 2 "arm_rhs_operand" "I,r,r"))
1227          (const_int 0)))
1228    (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
1229         (minus:SI (match_dup 1) (match_dup 2)))]
1230   "TARGET_32BIT"
1231   "@
1232    sub%.\\t%0, %1, %2
1233    sub%.\\t%0, %1, %2
1234    rsb%.\\t%0, %2, %1"
1235   [(set_attr "conds" "set")
1236    (set_attr "type"  "alus_imm,alus_sreg,alus_sreg")]
1239 (define_insn "subsi3_compare"
1240   [(set (reg:CC CC_REGNUM)
1241         (compare:CC (match_operand:SI 1 "arm_rhs_operand" "r,r,I")
1242                     (match_operand:SI 2 "arm_rhs_operand" "I,r,r")))
1243    (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
1244         (minus:SI (match_dup 1) (match_dup 2)))]
1245   "TARGET_32BIT"
1246   "@
1247    sub%.\\t%0, %1, %2
1248    sub%.\\t%0, %1, %2
1249    rsb%.\\t%0, %2, %1"
1250   [(set_attr "conds" "set")
1251    (set_attr "type" "alus_imm,alus_sreg,alus_sreg")]
1254 (define_expand "subsf3"
1255   [(set (match_operand:SF           0 "s_register_operand" "")
1256         (minus:SF (match_operand:SF 1 "s_register_operand" "")
1257                   (match_operand:SF 2 "s_register_operand" "")))]
1258   "TARGET_32BIT && TARGET_HARD_FLOAT"
1259   "
1262 (define_expand "subdf3"
1263   [(set (match_operand:DF           0 "s_register_operand" "")
1264         (minus:DF (match_operand:DF 1 "s_register_operand" "")
1265                   (match_operand:DF 2 "s_register_operand" "")))]
1266   "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
1267   "
1271 ;; Multiplication insns
1273 (define_expand "mulhi3"
1274   [(set (match_operand:HI 0 "s_register_operand" "")
1275         (mult:HI (match_operand:HI 1 "s_register_operand" "")
1276                  (match_operand:HI 2 "s_register_operand" "")))]
1277   "TARGET_DSP_MULTIPLY"
1278   "
1279   {
1280     rtx result = gen_reg_rtx (SImode);
1281     emit_insn (gen_mulhisi3 (result, operands[1], operands[2]));
1282     emit_move_insn (operands[0], gen_lowpart (HImode, result));
1283     DONE;
1284   }"
1287 (define_expand "mulsi3"
1288   [(set (match_operand:SI          0 "s_register_operand" "")
1289         (mult:SI (match_operand:SI 2 "s_register_operand" "")
1290                  (match_operand:SI 1 "s_register_operand" "")))]
1291   "TARGET_EITHER"
1292   ""
1295 ;; Use `&' and then `0' to prevent the operands 0 and 1 being the same
1296 (define_insn "*arm_mulsi3"
1297   [(set (match_operand:SI          0 "s_register_operand" "=&r,&r")
1298         (mult:SI (match_operand:SI 2 "s_register_operand" "r,r")
1299                  (match_operand:SI 1 "s_register_operand" "%0,r")))]
1300   "TARGET_32BIT && !arm_arch6"
1301   "mul%?\\t%0, %2, %1"
1302   [(set_attr "type" "mul")
1303    (set_attr "predicable" "yes")]
1306 (define_insn "*arm_mulsi3_v6"
1307   [(set (match_operand:SI          0 "s_register_operand" "=l,l,r")
1308         (mult:SI (match_operand:SI 1 "s_register_operand" "0,l,r")
1309                  (match_operand:SI 2 "s_register_operand" "l,0,r")))]
1310   "TARGET_32BIT && arm_arch6"
1311   "mul%?\\t%0, %1, %2"
1312   [(set_attr "type" "mul")
1313    (set_attr "predicable" "yes")
1314    (set_attr "arch" "t2,t2,*")
1315    (set_attr "length" "4")
1316    (set_attr "predicable_short_it" "yes,yes,no")]
1319 (define_insn "*mulsi3_compare0"
1320   [(set (reg:CC_NOOV CC_REGNUM)
1321         (compare:CC_NOOV (mult:SI
1322                           (match_operand:SI 2 "s_register_operand" "r,r")
1323                           (match_operand:SI 1 "s_register_operand" "%0,r"))
1324                          (const_int 0)))
1325    (set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1326         (mult:SI (match_dup 2) (match_dup 1)))]
1327   "TARGET_ARM && !arm_arch6"
1328   "mul%.\\t%0, %2, %1"
1329   [(set_attr "conds" "set")
1330    (set_attr "type" "muls")]
1333 (define_insn "*mulsi3_compare0_v6"
1334   [(set (reg:CC_NOOV CC_REGNUM)
1335         (compare:CC_NOOV (mult:SI
1336                           (match_operand:SI 2 "s_register_operand" "r")
1337                           (match_operand:SI 1 "s_register_operand" "r"))
1338                          (const_int 0)))
1339    (set (match_operand:SI 0 "s_register_operand" "=r")
1340         (mult:SI (match_dup 2) (match_dup 1)))]
1341   "TARGET_ARM && arm_arch6 && optimize_size"
1342   "mul%.\\t%0, %2, %1"
1343   [(set_attr "conds" "set")
1344    (set_attr "type" "muls")]
1347 (define_insn "*mulsi_compare0_scratch"
1348   [(set (reg:CC_NOOV CC_REGNUM)
1349         (compare:CC_NOOV (mult:SI
1350                           (match_operand:SI 2 "s_register_operand" "r,r")
1351                           (match_operand:SI 1 "s_register_operand" "%0,r"))
1352                          (const_int 0)))
1353    (clobber (match_scratch:SI 0 "=&r,&r"))]
1354   "TARGET_ARM && !arm_arch6"
1355   "mul%.\\t%0, %2, %1"
1356   [(set_attr "conds" "set")
1357    (set_attr "type" "muls")]
1360 (define_insn "*mulsi_compare0_scratch_v6"
1361   [(set (reg:CC_NOOV CC_REGNUM)
1362         (compare:CC_NOOV (mult:SI
1363                           (match_operand:SI 2 "s_register_operand" "r")
1364                           (match_operand:SI 1 "s_register_operand" "r"))
1365                          (const_int 0)))
1366    (clobber (match_scratch:SI 0 "=r"))]
1367   "TARGET_ARM && arm_arch6 && optimize_size"
1368   "mul%.\\t%0, %2, %1"
1369   [(set_attr "conds" "set")
1370    (set_attr "type" "muls")]
1373 ;; Unnamed templates to match MLA instruction.
1375 (define_insn "*mulsi3addsi"
1376   [(set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r,&r")
1377         (plus:SI
1378           (mult:SI (match_operand:SI 2 "s_register_operand" "r,r,r,r")
1379                    (match_operand:SI 1 "s_register_operand" "%0,r,0,r"))
1380           (match_operand:SI 3 "s_register_operand" "r,r,0,0")))]
1381   "TARGET_32BIT && !arm_arch6"
1382   "mla%?\\t%0, %2, %1, %3"
1383   [(set_attr "type" "mla")
1384    (set_attr "predicable" "yes")]
1387 (define_insn "*mulsi3addsi_v6"
1388   [(set (match_operand:SI 0 "s_register_operand" "=r")
1389         (plus:SI
1390           (mult:SI (match_operand:SI 2 "s_register_operand" "r")
1391                    (match_operand:SI 1 "s_register_operand" "r"))
1392           (match_operand:SI 3 "s_register_operand" "r")))]
1393   "TARGET_32BIT && arm_arch6"
1394   "mla%?\\t%0, %2, %1, %3"
1395   [(set_attr "type" "mla")
1396    (set_attr "predicable" "yes")
1397    (set_attr "predicable_short_it" "no")]
1400 (define_insn "*mulsi3addsi_compare0"
1401   [(set (reg:CC_NOOV CC_REGNUM)
1402         (compare:CC_NOOV
1403          (plus:SI (mult:SI
1404                    (match_operand:SI 2 "s_register_operand" "r,r,r,r")
1405                    (match_operand:SI 1 "s_register_operand" "%0,r,0,r"))
1406                   (match_operand:SI 3 "s_register_operand" "r,r,0,0"))
1407          (const_int 0)))
1408    (set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r,&r")
1409         (plus:SI (mult:SI (match_dup 2) (match_dup 1))
1410                  (match_dup 3)))]
1411   "TARGET_ARM && arm_arch6"
1412   "mla%.\\t%0, %2, %1, %3"
1413   [(set_attr "conds" "set")
1414    (set_attr "type" "mlas")]
1417 (define_insn "*mulsi3addsi_compare0_v6"
1418   [(set (reg:CC_NOOV CC_REGNUM)
1419         (compare:CC_NOOV
1420          (plus:SI (mult:SI
1421                    (match_operand:SI 2 "s_register_operand" "r")
1422                    (match_operand:SI 1 "s_register_operand" "r"))
1423                   (match_operand:SI 3 "s_register_operand" "r"))
1424          (const_int 0)))
1425    (set (match_operand:SI 0 "s_register_operand" "=r")
1426         (plus:SI (mult:SI (match_dup 2) (match_dup 1))
1427                  (match_dup 3)))]
1428   "TARGET_ARM && arm_arch6 && optimize_size"
1429   "mla%.\\t%0, %2, %1, %3"
1430   [(set_attr "conds" "set")
1431    (set_attr "type" "mlas")]
1434 (define_insn "*mulsi3addsi_compare0_scratch"
1435   [(set (reg:CC_NOOV CC_REGNUM)
1436         (compare:CC_NOOV
1437          (plus:SI (mult:SI
1438                    (match_operand:SI 2 "s_register_operand" "r,r,r,r")
1439                    (match_operand:SI 1 "s_register_operand" "%0,r,0,r"))
1440                   (match_operand:SI 3 "s_register_operand" "?r,r,0,0"))
1441          (const_int 0)))
1442    (clobber (match_scratch:SI 0 "=&r,&r,&r,&r"))]
1443   "TARGET_ARM && !arm_arch6"
1444   "mla%.\\t%0, %2, %1, %3"
1445   [(set_attr "conds" "set")
1446    (set_attr "type" "mlas")]
1449 (define_insn "*mulsi3addsi_compare0_scratch_v6"
1450   [(set (reg:CC_NOOV CC_REGNUM)
1451         (compare:CC_NOOV
1452          (plus:SI (mult:SI
1453                    (match_operand:SI 2 "s_register_operand" "r")
1454                    (match_operand:SI 1 "s_register_operand" "r"))
1455                   (match_operand:SI 3 "s_register_operand" "r"))
1456          (const_int 0)))
1457    (clobber (match_scratch:SI 0 "=r"))]
1458   "TARGET_ARM && arm_arch6 && optimize_size"
1459   "mla%.\\t%0, %2, %1, %3"
1460   [(set_attr "conds" "set")
1461    (set_attr "type" "mlas")]
1464 (define_insn "*mulsi3subsi"
1465   [(set (match_operand:SI 0 "s_register_operand" "=r")
1466         (minus:SI
1467           (match_operand:SI 3 "s_register_operand" "r")
1468           (mult:SI (match_operand:SI 2 "s_register_operand" "r")
1469                    (match_operand:SI 1 "s_register_operand" "r"))))]
1470   "TARGET_32BIT && arm_arch_thumb2"
1471   "mls%?\\t%0, %2, %1, %3"
1472   [(set_attr "type" "mla")
1473    (set_attr "predicable" "yes")
1474    (set_attr "predicable_short_it" "no")]
1477 (define_expand "maddsidi4"
1478   [(set (match_operand:DI 0 "s_register_operand" "")
1479         (plus:DI
1480          (mult:DI
1481           (sign_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1482           (sign_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1483          (match_operand:DI 3 "s_register_operand" "")))]
1484   "TARGET_32BIT && arm_arch3m"
1485   "")
1487 (define_insn "*mulsidi3adddi"
1488   [(set (match_operand:DI 0 "s_register_operand" "=&r")
1489         (plus:DI
1490          (mult:DI
1491           (sign_extend:DI (match_operand:SI 2 "s_register_operand" "%r"))
1492           (sign_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1493          (match_operand:DI 1 "s_register_operand" "0")))]
1494   "TARGET_32BIT && arm_arch3m && !arm_arch6"
1495   "smlal%?\\t%Q0, %R0, %3, %2"
1496   [(set_attr "type" "smlal")
1497    (set_attr "predicable" "yes")]
1500 (define_insn "*mulsidi3adddi_v6"
1501   [(set (match_operand:DI 0 "s_register_operand" "=r")
1502         (plus:DI
1503          (mult:DI
1504           (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r"))
1505           (sign_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1506          (match_operand:DI 1 "s_register_operand" "0")))]
1507   "TARGET_32BIT && arm_arch6"
1508   "smlal%?\\t%Q0, %R0, %3, %2"
1509   [(set_attr "type" "smlal")
1510    (set_attr "predicable" "yes")
1511    (set_attr "predicable_short_it" "no")]
1514 ;; 32x32->64 widening multiply.
1515 ;; As with mulsi3, the only difference between the v3-5 and v6+
1516 ;; versions of these patterns is the requirement that the output not
1517 ;; overlap the inputs, but that still means we have to have a named
1518 ;; expander and two different starred insns.
1520 (define_expand "mulsidi3"
1521   [(set (match_operand:DI 0 "s_register_operand" "")
1522         (mult:DI
1523          (sign_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1524          (sign_extend:DI (match_operand:SI 2 "s_register_operand" ""))))]
1525   "TARGET_32BIT && arm_arch3m"
1526   ""
1529 (define_insn "*mulsidi3_nov6"
1530   [(set (match_operand:DI 0 "s_register_operand" "=&r")
1531         (mult:DI
1532          (sign_extend:DI (match_operand:SI 1 "s_register_operand" "%r"))
1533          (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1534   "TARGET_32BIT && arm_arch3m && !arm_arch6"
1535   "smull%?\\t%Q0, %R0, %1, %2"
1536   [(set_attr "type" "smull")
1537    (set_attr "predicable" "yes")]
1540 (define_insn "*mulsidi3_v6"
1541   [(set (match_operand:DI 0 "s_register_operand" "=r")
1542         (mult:DI
1543          (sign_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1544          (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1545   "TARGET_32BIT && arm_arch6"
1546   "smull%?\\t%Q0, %R0, %1, %2"
1547   [(set_attr "type" "smull")
1548    (set_attr "predicable" "yes")
1549    (set_attr "predicable_short_it" "no")]
1552 (define_expand "umulsidi3"
1553   [(set (match_operand:DI 0 "s_register_operand" "")
1554         (mult:DI
1555          (zero_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1556          (zero_extend:DI (match_operand:SI 2 "s_register_operand" ""))))]
1557   "TARGET_32BIT && arm_arch3m"
1558   ""
1561 (define_insn "*umulsidi3_nov6"
1562   [(set (match_operand:DI 0 "s_register_operand" "=&r")
1563         (mult:DI
1564          (zero_extend:DI (match_operand:SI 1 "s_register_operand" "%r"))
1565          (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1566   "TARGET_32BIT && arm_arch3m && !arm_arch6"
1567   "umull%?\\t%Q0, %R0, %1, %2"
1568   [(set_attr "type" "umull")
1569    (set_attr "predicable" "yes")]
1572 (define_insn "*umulsidi3_v6"
1573   [(set (match_operand:DI 0 "s_register_operand" "=r")
1574         (mult:DI
1575          (zero_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1576          (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1577   "TARGET_32BIT && arm_arch6"
1578   "umull%?\\t%Q0, %R0, %1, %2"
1579   [(set_attr "type" "umull")
1580    (set_attr "predicable" "yes")
1581    (set_attr "predicable_short_it" "no")]
1584 (define_expand "umaddsidi4"
1585   [(set (match_operand:DI 0 "s_register_operand" "")
1586         (plus:DI
1587          (mult:DI
1588           (zero_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1589           (zero_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1590          (match_operand:DI 3 "s_register_operand" "")))]
1591   "TARGET_32BIT && arm_arch3m"
1592   "")
1594 (define_insn "*umulsidi3adddi"
1595   [(set (match_operand:DI 0 "s_register_operand" "=&r")
1596         (plus:DI
1597          (mult:DI
1598           (zero_extend:DI (match_operand:SI 2 "s_register_operand" "%r"))
1599           (zero_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1600          (match_operand:DI 1 "s_register_operand" "0")))]
1601   "TARGET_32BIT && arm_arch3m && !arm_arch6"
1602   "umlal%?\\t%Q0, %R0, %3, %2"
1603   [(set_attr "type" "umlal")
1604    (set_attr "predicable" "yes")]
1607 (define_insn "*umulsidi3adddi_v6"
1608   [(set (match_operand:DI 0 "s_register_operand" "=r")
1609         (plus:DI
1610          (mult:DI
1611           (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r"))
1612           (zero_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1613          (match_operand:DI 1 "s_register_operand" "0")))]
1614   "TARGET_32BIT && arm_arch6"
1615   "umlal%?\\t%Q0, %R0, %3, %2"
1616   [(set_attr "type" "umlal")
1617    (set_attr "predicable" "yes")
1618    (set_attr "predicable_short_it" "no")]
1621 (define_expand "smulsi3_highpart"
1622   [(parallel
1623     [(set (match_operand:SI 0 "s_register_operand" "")
1624           (truncate:SI
1625            (lshiftrt:DI
1626             (mult:DI
1627              (sign_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1628              (sign_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1629             (const_int 32))))
1630      (clobber (match_scratch:SI 3 ""))])]
1631   "TARGET_32BIT && arm_arch3m"
1632   ""
1635 (define_insn "*smulsi3_highpart_nov6"
1636   [(set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1637         (truncate:SI
1638          (lshiftrt:DI
1639           (mult:DI
1640            (sign_extend:DI (match_operand:SI 1 "s_register_operand" "%0,r"))
1641            (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r,r")))
1642           (const_int 32))))
1643    (clobber (match_scratch:SI 3 "=&r,&r"))]
1644   "TARGET_32BIT && arm_arch3m && !arm_arch6"
1645   "smull%?\\t%3, %0, %2, %1"
1646   [(set_attr "type" "smull")
1647    (set_attr "predicable" "yes")]
1650 (define_insn "*smulsi3_highpart_v6"
1651   [(set (match_operand:SI 0 "s_register_operand" "=r")
1652         (truncate:SI
1653          (lshiftrt:DI
1654           (mult:DI
1655            (sign_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1656            (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r")))
1657           (const_int 32))))
1658    (clobber (match_scratch:SI 3 "=r"))]
1659   "TARGET_32BIT && arm_arch6"
1660   "smull%?\\t%3, %0, %2, %1"
1661   [(set_attr "type" "smull")
1662    (set_attr "predicable" "yes")
1663    (set_attr "predicable_short_it" "no")]
1666 (define_expand "umulsi3_highpart"
1667   [(parallel
1668     [(set (match_operand:SI 0 "s_register_operand" "")
1669           (truncate:SI
1670            (lshiftrt:DI
1671             (mult:DI
1672              (zero_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1673               (zero_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1674             (const_int 32))))
1675      (clobber (match_scratch:SI 3 ""))])]
1676   "TARGET_32BIT && arm_arch3m"
1677   ""
1680 (define_insn "*umulsi3_highpart_nov6"
1681   [(set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1682         (truncate:SI
1683          (lshiftrt:DI
1684           (mult:DI
1685            (zero_extend:DI (match_operand:SI 1 "s_register_operand" "%0,r"))
1686            (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r,r")))
1687           (const_int 32))))
1688    (clobber (match_scratch:SI 3 "=&r,&r"))]
1689   "TARGET_32BIT && arm_arch3m && !arm_arch6"
1690   "umull%?\\t%3, %0, %2, %1"
1691   [(set_attr "type" "umull")
1692    (set_attr "predicable" "yes")]
1695 (define_insn "*umulsi3_highpart_v6"
1696   [(set (match_operand:SI 0 "s_register_operand" "=r")
1697         (truncate:SI
1698          (lshiftrt:DI
1699           (mult:DI
1700            (zero_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1701            (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r")))
1702           (const_int 32))))
1703    (clobber (match_scratch:SI 3 "=r"))]
1704   "TARGET_32BIT && arm_arch6"
1705   "umull%?\\t%3, %0, %2, %1"
1706   [(set_attr "type" "umull")
1707    (set_attr "predicable" "yes")
1708    (set_attr "predicable_short_it" "no")]
1711 (define_insn "mulhisi3"
1712   [(set (match_operand:SI 0 "s_register_operand" "=r")
1713         (mult:SI (sign_extend:SI
1714                   (match_operand:HI 1 "s_register_operand" "%r"))
1715                  (sign_extend:SI
1716                   (match_operand:HI 2 "s_register_operand" "r"))))]
1717   "TARGET_DSP_MULTIPLY"
1718   "smulbb%?\\t%0, %1, %2"
1719   [(set_attr "type" "smulxy")
1720    (set_attr "predicable" "yes")]
1723 (define_insn "*mulhisi3tb"
1724   [(set (match_operand:SI 0 "s_register_operand" "=r")
1725         (mult:SI (ashiftrt:SI
1726                   (match_operand:SI 1 "s_register_operand" "r")
1727                   (const_int 16))
1728                  (sign_extend:SI
1729                   (match_operand:HI 2 "s_register_operand" "r"))))]
1730   "TARGET_DSP_MULTIPLY"
1731   "smultb%?\\t%0, %1, %2"
1732   [(set_attr "type" "smulxy")
1733    (set_attr "predicable" "yes")
1734    (set_attr "predicable_short_it" "no")]
1737 (define_insn "*mulhisi3bt"
1738   [(set (match_operand:SI 0 "s_register_operand" "=r")
1739         (mult:SI (sign_extend:SI
1740                   (match_operand:HI 1 "s_register_operand" "r"))
1741                  (ashiftrt:SI
1742                   (match_operand:SI 2 "s_register_operand" "r")
1743                   (const_int 16))))]
1744   "TARGET_DSP_MULTIPLY"
1745   "smulbt%?\\t%0, %1, %2"
1746   [(set_attr "type" "smulxy")
1747    (set_attr "predicable" "yes")
1748    (set_attr "predicable_short_it" "no")]
1751 (define_insn "*mulhisi3tt"
1752   [(set (match_operand:SI 0 "s_register_operand" "=r")
1753         (mult:SI (ashiftrt:SI
1754                   (match_operand:SI 1 "s_register_operand" "r")
1755                   (const_int 16))
1756                  (ashiftrt:SI
1757                   (match_operand:SI 2 "s_register_operand" "r")
1758                   (const_int 16))))]
1759   "TARGET_DSP_MULTIPLY"
1760   "smultt%?\\t%0, %1, %2"
1761   [(set_attr "type" "smulxy")
1762    (set_attr "predicable" "yes")
1763    (set_attr "predicable_short_it" "no")]
1766 (define_insn "maddhisi4"
1767   [(set (match_operand:SI 0 "s_register_operand" "=r")
1768         (plus:SI (mult:SI (sign_extend:SI
1769                            (match_operand:HI 1 "s_register_operand" "r"))
1770                           (sign_extend:SI
1771                            (match_operand:HI 2 "s_register_operand" "r")))
1772                  (match_operand:SI 3 "s_register_operand" "r")))]
1773   "TARGET_DSP_MULTIPLY"
1774   "smlabb%?\\t%0, %1, %2, %3"
1775   [(set_attr "type" "smlaxy")
1776    (set_attr "predicable" "yes")
1777    (set_attr "predicable_short_it" "no")]
1780 ;; Note: there is no maddhisi4ibt because this one is canonical form
1781 (define_insn "*maddhisi4tb"
1782   [(set (match_operand:SI 0 "s_register_operand" "=r")
1783         (plus:SI (mult:SI (ashiftrt:SI
1784                            (match_operand:SI 1 "s_register_operand" "r")
1785                            (const_int 16))
1786                           (sign_extend:SI
1787                            (match_operand:HI 2 "s_register_operand" "r")))
1788                  (match_operand:SI 3 "s_register_operand" "r")))]
1789   "TARGET_DSP_MULTIPLY"
1790   "smlatb%?\\t%0, %1, %2, %3"
1791   [(set_attr "type" "smlaxy")
1792    (set_attr "predicable" "yes")
1793    (set_attr "predicable_short_it" "no")]
1796 (define_insn "*maddhisi4tt"
1797   [(set (match_operand:SI 0 "s_register_operand" "=r")
1798         (plus:SI (mult:SI (ashiftrt:SI
1799                            (match_operand:SI 1 "s_register_operand" "r")
1800                            (const_int 16))
1801                           (ashiftrt:SI
1802                            (match_operand:SI 2 "s_register_operand" "r")
1803                            (const_int 16)))
1804                  (match_operand:SI 3 "s_register_operand" "r")))]
1805   "TARGET_DSP_MULTIPLY"
1806   "smlatt%?\\t%0, %1, %2, %3"
1807   [(set_attr "type" "smlaxy")
1808    (set_attr "predicable" "yes")
1809    (set_attr "predicable_short_it" "no")]
1812 (define_insn "maddhidi4"
1813   [(set (match_operand:DI 0 "s_register_operand" "=r")
1814         (plus:DI
1815           (mult:DI (sign_extend:DI
1816                     (match_operand:HI 1 "s_register_operand" "r"))
1817                    (sign_extend:DI
1818                     (match_operand:HI 2 "s_register_operand" "r")))
1819           (match_operand:DI 3 "s_register_operand" "0")))]
1820   "TARGET_DSP_MULTIPLY"
1821   "smlalbb%?\\t%Q0, %R0, %1, %2"
1822   [(set_attr "type" "smlalxy")
1823    (set_attr "predicable" "yes")
1824    (set_attr "predicable_short_it" "no")])
1826 ;; Note: there is no maddhidi4ibt because this one is canonical form
1827 (define_insn "*maddhidi4tb"
1828   [(set (match_operand:DI 0 "s_register_operand" "=r")
1829         (plus:DI
1830           (mult:DI (sign_extend:DI
1831                     (ashiftrt:SI
1832                      (match_operand:SI 1 "s_register_operand" "r")
1833                      (const_int 16)))
1834                    (sign_extend:DI
1835                     (match_operand:HI 2 "s_register_operand" "r")))
1836           (match_operand:DI 3 "s_register_operand" "0")))]
1837   "TARGET_DSP_MULTIPLY"
1838   "smlaltb%?\\t%Q0, %R0, %1, %2"
1839   [(set_attr "type" "smlalxy")
1840    (set_attr "predicable" "yes")
1841    (set_attr "predicable_short_it" "no")])
1843 (define_insn "*maddhidi4tt"
1844   [(set (match_operand:DI 0 "s_register_operand" "=r")
1845         (plus:DI
1846           (mult:DI (sign_extend:DI
1847                     (ashiftrt:SI
1848                      (match_operand:SI 1 "s_register_operand" "r")
1849                      (const_int 16)))
1850                    (sign_extend:DI
1851                     (ashiftrt:SI
1852                      (match_operand:SI 2 "s_register_operand" "r")
1853                      (const_int 16))))
1854           (match_operand:DI 3 "s_register_operand" "0")))]
1855   "TARGET_DSP_MULTIPLY"
1856   "smlaltt%?\\t%Q0, %R0, %1, %2"
1857   [(set_attr "type" "smlalxy")
1858    (set_attr "predicable" "yes")
1859    (set_attr "predicable_short_it" "no")])
1861 (define_expand "mulsf3"
1862   [(set (match_operand:SF          0 "s_register_operand" "")
1863         (mult:SF (match_operand:SF 1 "s_register_operand" "")
1864                  (match_operand:SF 2 "s_register_operand" "")))]
1865   "TARGET_32BIT && TARGET_HARD_FLOAT"
1866   "
1869 (define_expand "muldf3"
1870   [(set (match_operand:DF          0 "s_register_operand" "")
1871         (mult:DF (match_operand:DF 1 "s_register_operand" "")
1872                  (match_operand:DF 2 "s_register_operand" "")))]
1873   "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
1874   "
1877 ;; Division insns
1879 (define_expand "divsf3"
1880   [(set (match_operand:SF 0 "s_register_operand" "")
1881         (div:SF (match_operand:SF 1 "s_register_operand" "")
1882                 (match_operand:SF 2 "s_register_operand" "")))]
1883   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
1884   "")
1886 (define_expand "divdf3"
1887   [(set (match_operand:DF 0 "s_register_operand" "")
1888         (div:DF (match_operand:DF 1 "s_register_operand" "")
1889                 (match_operand:DF 2 "s_register_operand" "")))]
1890   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
1891   "")
1893 ;; Boolean and,ior,xor insns
1895 ;; Split up double word logical operations
1897 ;; Split up simple DImode logical operations.  Simply perform the logical
1898 ;; operation on the upper and lower halves of the registers.
1899 (define_split
1900   [(set (match_operand:DI 0 "s_register_operand" "")
1901         (match_operator:DI 6 "logical_binary_operator"
1902           [(match_operand:DI 1 "s_register_operand" "")
1903            (match_operand:DI 2 "s_register_operand" "")]))]
1904   "TARGET_32BIT && reload_completed
1905    && ! (TARGET_NEON && IS_VFP_REGNUM (REGNO (operands[0])))
1906    && ! IS_IWMMXT_REGNUM (REGNO (operands[0]))"
1907   [(set (match_dup 0) (match_op_dup:SI 6 [(match_dup 1) (match_dup 2)]))
1908    (set (match_dup 3) (match_op_dup:SI 6 [(match_dup 4) (match_dup 5)]))]
1909   "
1910   {
1911     operands[3] = gen_highpart (SImode, operands[0]);
1912     operands[0] = gen_lowpart (SImode, operands[0]);
1913     operands[4] = gen_highpart (SImode, operands[1]);
1914     operands[1] = gen_lowpart (SImode, operands[1]);
1915     operands[5] = gen_highpart (SImode, operands[2]);
1916     operands[2] = gen_lowpart (SImode, operands[2]);
1917   }"
1920 (define_split
1921   [(set (match_operand:DI 0 "s_register_operand" "")
1922         (match_operator:DI 6 "logical_binary_operator"
1923           [(sign_extend:DI (match_operand:SI 2 "s_register_operand" ""))
1924            (match_operand:DI 1 "s_register_operand" "")]))]
1925   "TARGET_32BIT && reload_completed"
1926   [(set (match_dup 0) (match_op_dup:SI 6 [(match_dup 1) (match_dup 2)]))
1927    (set (match_dup 3) (match_op_dup:SI 6
1928                         [(ashiftrt:SI (match_dup 2) (const_int 31))
1929                          (match_dup 4)]))]
1930   "
1931   {
1932     operands[3] = gen_highpart (SImode, operands[0]);
1933     operands[0] = gen_lowpart (SImode, operands[0]);
1934     operands[4] = gen_highpart (SImode, operands[1]);
1935     operands[1] = gen_lowpart (SImode, operands[1]);
1936     operands[5] = gen_highpart (SImode, operands[2]);
1937     operands[2] = gen_lowpart (SImode, operands[2]);
1938   }"
1941 ;; The zero extend of operand 2 means we can just copy the high part of
1942 ;; operand1 into operand0.
1943 (define_split
1944   [(set (match_operand:DI 0 "s_register_operand" "")
1945         (ior:DI
1946           (zero_extend:DI (match_operand:SI 2 "s_register_operand" ""))
1947           (match_operand:DI 1 "s_register_operand" "")))]
1948   "TARGET_32BIT && operands[0] != operands[1] && reload_completed"
1949   [(set (match_dup 0) (ior:SI (match_dup 1) (match_dup 2)))
1950    (set (match_dup 3) (match_dup 4))]
1951   "
1952   {
1953     operands[4] = gen_highpart (SImode, operands[1]);
1954     operands[3] = gen_highpart (SImode, operands[0]);
1955     operands[0] = gen_lowpart (SImode, operands[0]);
1956     operands[1] = gen_lowpart (SImode, operands[1]);
1957   }"
1960 ;; The zero extend of operand 2 means we can just copy the high part of
1961 ;; operand1 into operand0.
1962 (define_split
1963   [(set (match_operand:DI 0 "s_register_operand" "")
1964         (xor:DI
1965           (zero_extend:DI (match_operand:SI 2 "s_register_operand" ""))
1966           (match_operand:DI 1 "s_register_operand" "")))]
1967   "TARGET_32BIT && operands[0] != operands[1] && reload_completed"
1968   [(set (match_dup 0) (xor:SI (match_dup 1) (match_dup 2)))
1969    (set (match_dup 3) (match_dup 4))]
1970   "
1971   {
1972     operands[4] = gen_highpart (SImode, operands[1]);
1973     operands[3] = gen_highpart (SImode, operands[0]);
1974     operands[0] = gen_lowpart (SImode, operands[0]);
1975     operands[1] = gen_lowpart (SImode, operands[1]);
1976   }"
1979 (define_expand "anddi3"
1980   [(set (match_operand:DI         0 "s_register_operand" "")
1981         (and:DI (match_operand:DI 1 "s_register_operand" "")
1982                 (match_operand:DI 2 "neon_inv_logic_op2" "")))]
1983   "TARGET_32BIT"
1984   ""
1987 (define_insn_and_split "*anddi3_insn"
1988   [(set (match_operand:DI         0 "s_register_operand"     "=w,w ,&r,&r,&r,&r,?w,?w")
1989         (and:DI (match_operand:DI 1 "s_register_operand"     "%w,0 ,0 ,r ,0 ,r ,w ,0")
1990                 (match_operand:DI 2 "arm_anddi_operand_neon" "w ,DL,r ,r ,De,De,w ,DL")))]
1991   "TARGET_32BIT && !TARGET_IWMMXT"
1993   switch (which_alternative)
1994     {
1995     case 0: /* fall through */
1996     case 6: return "vand\t%P0, %P1, %P2";
1997     case 1: /* fall through */
1998     case 7: return neon_output_logic_immediate ("vand", &operands[2],
1999                     DImode, 1, VALID_NEON_QREG_MODE (DImode));
2000     case 2:
2001     case 3:
2002     case 4:
2003     case 5: /* fall through */
2004       return "#";
2005     default: gcc_unreachable ();
2006     }
2008   "TARGET_32BIT && !TARGET_IWMMXT && reload_completed
2009    && !(IS_VFP_REGNUM (REGNO (operands[0])))"
2010   [(set (match_dup 3) (match_dup 4))
2011    (set (match_dup 5) (match_dup 6))]
2012   "
2013   {
2014     operands[3] = gen_lowpart (SImode, operands[0]);
2015     operands[5] = gen_highpart (SImode, operands[0]);
2017     operands[4] = simplify_gen_binary (AND, SImode,
2018                                            gen_lowpart (SImode, operands[1]),
2019                                            gen_lowpart (SImode, operands[2]));
2020     operands[6] = simplify_gen_binary (AND, SImode,
2021                                            gen_highpart (SImode, operands[1]),
2022                                            gen_highpart_mode (SImode, DImode, operands[2]));
2024   }"
2025   [(set_attr "type" "neon_logic,neon_logic,multiple,multiple,\
2026                      multiple,multiple,neon_logic,neon_logic")
2027    (set_attr "arch" "neon_for_64bits,neon_for_64bits,*,*,*,*,
2028                      avoid_neon_for_64bits,avoid_neon_for_64bits")
2029    (set_attr "length" "*,*,8,8,8,8,*,*")
2030   ]
2033 (define_insn_and_split "*anddi_zesidi_di"
2034   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2035         (and:DI (zero_extend:DI
2036                  (match_operand:SI 2 "s_register_operand" "r,r"))
2037                 (match_operand:DI 1 "s_register_operand" "0,r")))]
2038   "TARGET_32BIT"
2039   "#"
2040   "TARGET_32BIT && reload_completed"
2041   ; The zero extend of operand 2 clears the high word of the output
2042   ; operand.
2043   [(set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))
2044    (set (match_dup 3) (const_int 0))]
2045   "
2046   {
2047     operands[3] = gen_highpart (SImode, operands[0]);
2048     operands[0] = gen_lowpart (SImode, operands[0]);
2049     operands[1] = gen_lowpart (SImode, operands[1]);
2050   }"
2051   [(set_attr "length" "8")
2052    (set_attr "type" "multiple")]
2055 (define_insn "*anddi_sesdi_di"
2056   [(set (match_operand:DI          0 "s_register_operand" "=&r,&r")
2057         (and:DI (sign_extend:DI
2058                  (match_operand:SI 2 "s_register_operand" "r,r"))
2059                 (match_operand:DI  1 "s_register_operand" "0,r")))]
2060   "TARGET_32BIT"
2061   "#"
2062   [(set_attr "length" "8")
2063    (set_attr "type" "multiple")]
2066 (define_expand "andsi3"
2067   [(set (match_operand:SI         0 "s_register_operand" "")
2068         (and:SI (match_operand:SI 1 "s_register_operand" "")
2069                 (match_operand:SI 2 "reg_or_int_operand" "")))]
2070   "TARGET_EITHER"
2071   "
2072   if (TARGET_32BIT)
2073     {
2074       if (CONST_INT_P (operands[2]))
2075         {
2076           if (INTVAL (operands[2]) == 255 && arm_arch6)
2077             {
2078               operands[1] = convert_to_mode (QImode, operands[1], 1);
2079               emit_insn (gen_thumb2_zero_extendqisi2_v6 (operands[0],
2080                                                          operands[1]));
2081             }
2082           else
2083             arm_split_constant (AND, SImode, NULL_RTX,
2084                                 INTVAL (operands[2]), operands[0],
2085                                 operands[1],
2086                                 optimize && can_create_pseudo_p ());
2088           DONE;
2089         }
2090     }
2091   else /* TARGET_THUMB1 */
2092     {
2093       if (!CONST_INT_P (operands[2]))
2094         {
2095           rtx tmp = force_reg (SImode, operands[2]);
2096           if (rtx_equal_p (operands[0], operands[1]))
2097             operands[2] = tmp;
2098           else
2099             {
2100               operands[2] = operands[1];
2101               operands[1] = tmp;
2102             }
2103         }
2104       else
2105         {
2106           int i;
2107           
2108           if (((unsigned HOST_WIDE_INT) ~INTVAL (operands[2])) < 256)
2109             {
2110               operands[2] = force_reg (SImode,
2111                                        GEN_INT (~INTVAL (operands[2])));
2112               
2113               emit_insn (gen_thumb1_bicsi3 (operands[0], operands[2], operands[1]));
2114               
2115               DONE;
2116             }
2118           for (i = 9; i <= 31; i++)
2119             {
2120               if ((((HOST_WIDE_INT) 1) << i) - 1 == INTVAL (operands[2]))
2121                 {
2122                   emit_insn (gen_extzv (operands[0], operands[1], GEN_INT (i),
2123                                         const0_rtx));
2124                   DONE;
2125                 }
2126               else if ((((HOST_WIDE_INT) 1) << i) - 1
2127                        == ~INTVAL (operands[2]))
2128                 {
2129                   rtx shift = GEN_INT (i);
2130                   rtx reg = gen_reg_rtx (SImode);
2131                 
2132                   emit_insn (gen_lshrsi3 (reg, operands[1], shift));
2133                   emit_insn (gen_ashlsi3 (operands[0], reg, shift));
2134                   
2135                   DONE;
2136                 }
2137             }
2139           operands[2] = force_reg (SImode, operands[2]);
2140         }
2141     }
2142   "
2145 ; ??? Check split length for Thumb-2
2146 (define_insn_and_split "*arm_andsi3_insn"
2147   [(set (match_operand:SI         0 "s_register_operand" "=r,l,r,r,r")
2148         (and:SI (match_operand:SI 1 "s_register_operand" "%r,0,r,r,r")
2149                 (match_operand:SI 2 "reg_or_int_operand" "I,l,K,r,?n")))]
2150   "TARGET_32BIT"
2151   "@
2152    and%?\\t%0, %1, %2
2153    and%?\\t%0, %1, %2
2154    bic%?\\t%0, %1, #%B2
2155    and%?\\t%0, %1, %2
2156    #"
2157   "TARGET_32BIT
2158    && CONST_INT_P (operands[2])
2159    && !(const_ok_for_arm (INTVAL (operands[2]))
2160         || const_ok_for_arm (~INTVAL (operands[2])))"
2161   [(clobber (const_int 0))]
2162   "
2163   arm_split_constant  (AND, SImode, curr_insn, 
2164                        INTVAL (operands[2]), operands[0], operands[1], 0);
2165   DONE;
2166   "
2167   [(set_attr "length" "4,4,4,4,16")
2168    (set_attr "predicable" "yes")
2169    (set_attr "predicable_short_it" "no,yes,no,no,no")
2170    (set_attr "type" "logic_imm,logic_imm,logic_reg,logic_reg,logic_imm")]
2173 (define_insn "*andsi3_compare0"
2174   [(set (reg:CC_NOOV CC_REGNUM)
2175         (compare:CC_NOOV
2176          (and:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
2177                  (match_operand:SI 2 "arm_not_operand" "I,K,r"))
2178          (const_int 0)))
2179    (set (match_operand:SI          0 "s_register_operand" "=r,r,r")
2180         (and:SI (match_dup 1) (match_dup 2)))]
2181   "TARGET_32BIT"
2182   "@
2183    and%.\\t%0, %1, %2
2184    bic%.\\t%0, %1, #%B2
2185    and%.\\t%0, %1, %2"
2186   [(set_attr "conds" "set")
2187    (set_attr "type" "logics_imm,logics_imm,logics_reg")]
2190 (define_insn "*andsi3_compare0_scratch"
2191   [(set (reg:CC_NOOV CC_REGNUM)
2192         (compare:CC_NOOV
2193          (and:SI (match_operand:SI 0 "s_register_operand" "r,r,r")
2194                  (match_operand:SI 1 "arm_not_operand" "I,K,r"))
2195          (const_int 0)))
2196    (clobber (match_scratch:SI 2 "=X,r,X"))]
2197   "TARGET_32BIT"
2198   "@
2199    tst%?\\t%0, %1
2200    bic%.\\t%2, %0, #%B1
2201    tst%?\\t%0, %1"
2202   [(set_attr "conds" "set")
2203    (set_attr "type"  "logics_imm,logics_imm,logics_reg")]
2206 (define_insn "*zeroextractsi_compare0_scratch"
2207   [(set (reg:CC_NOOV CC_REGNUM)
2208         (compare:CC_NOOV (zero_extract:SI
2209                           (match_operand:SI 0 "s_register_operand" "r")
2210                           (match_operand 1 "const_int_operand" "n")
2211                           (match_operand 2 "const_int_operand" "n"))
2212                          (const_int 0)))]
2213   "TARGET_32BIT
2214   && (INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) < 32
2215       && INTVAL (operands[1]) > 0 
2216       && INTVAL (operands[1]) + (INTVAL (operands[2]) & 1) <= 8
2217       && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32)"
2218   "*
2219   operands[1] = GEN_INT (((1 << INTVAL (operands[1])) - 1)
2220                          << INTVAL (operands[2]));
2221   output_asm_insn (\"tst%?\\t%0, %1\", operands);
2222   return \"\";
2223   "
2224   [(set_attr "conds" "set")
2225    (set_attr "predicable" "yes")
2226    (set_attr "predicable_short_it" "no")
2227    (set_attr "type" "logics_imm")]
2230 (define_insn_and_split "*ne_zeroextractsi"
2231   [(set (match_operand:SI 0 "s_register_operand" "=r")
2232         (ne:SI (zero_extract:SI
2233                 (match_operand:SI 1 "s_register_operand" "r")
2234                 (match_operand:SI 2 "const_int_operand" "n")
2235                 (match_operand:SI 3 "const_int_operand" "n"))
2236                (const_int 0)))
2237    (clobber (reg:CC CC_REGNUM))]
2238   "TARGET_32BIT
2239    && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2240        && INTVAL (operands[2]) > 0 
2241        && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2242        && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)"
2243   "#"
2244   "TARGET_32BIT
2245    && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2246        && INTVAL (operands[2]) > 0 
2247        && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2248        && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)"
2249   [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2250                    (compare:CC_NOOV (and:SI (match_dup 1) (match_dup 2))
2251                                     (const_int 0)))
2252               (set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))])
2253    (set (match_dup 0)
2254         (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2255                          (match_dup 0) (const_int 1)))]
2256   "
2257   operands[2] = GEN_INT (((1 << INTVAL (operands[2])) - 1)
2258                          << INTVAL (operands[3])); 
2259   "
2260   [(set_attr "conds" "clob")
2261    (set (attr "length")
2262         (if_then_else (eq_attr "is_thumb" "yes")
2263                       (const_int 12)
2264                       (const_int 8)))
2265    (set_attr "type" "multiple")]
2268 (define_insn_and_split "*ne_zeroextractsi_shifted"
2269   [(set (match_operand:SI 0 "s_register_operand" "=r")
2270         (ne:SI (zero_extract:SI
2271                 (match_operand:SI 1 "s_register_operand" "r")
2272                 (match_operand:SI 2 "const_int_operand" "n")
2273                 (const_int 0))
2274                (const_int 0)))
2275    (clobber (reg:CC CC_REGNUM))]
2276   "TARGET_ARM"
2277   "#"
2278   "TARGET_ARM"
2279   [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2280                    (compare:CC_NOOV (ashift:SI (match_dup 1) (match_dup 2))
2281                                     (const_int 0)))
2282               (set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))])
2283    (set (match_dup 0)
2284         (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2285                          (match_dup 0) (const_int 1)))]
2286   "
2287   operands[2] = GEN_INT (32 - INTVAL (operands[2]));
2288   "
2289   [(set_attr "conds" "clob")
2290    (set_attr "length" "8")
2291    (set_attr "type" "multiple")]
2294 (define_insn_and_split "*ite_ne_zeroextractsi"
2295   [(set (match_operand:SI 0 "s_register_operand" "=r")
2296         (if_then_else:SI (ne (zero_extract:SI
2297                               (match_operand:SI 1 "s_register_operand" "r")
2298                               (match_operand:SI 2 "const_int_operand" "n")
2299                               (match_operand:SI 3 "const_int_operand" "n"))
2300                              (const_int 0))
2301                          (match_operand:SI 4 "arm_not_operand" "rIK")
2302                          (const_int 0)))
2303    (clobber (reg:CC CC_REGNUM))]
2304   "TARGET_ARM
2305    && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2306        && INTVAL (operands[2]) > 0 
2307        && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2308        && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)
2309    && !reg_overlap_mentioned_p (operands[0], operands[4])"
2310   "#"
2311   "TARGET_ARM
2312    && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2313        && INTVAL (operands[2]) > 0 
2314        && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2315        && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)
2316    && !reg_overlap_mentioned_p (operands[0], operands[4])"
2317   [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2318                    (compare:CC_NOOV (and:SI (match_dup 1) (match_dup 2))
2319                                     (const_int 0)))
2320               (set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))])
2321    (set (match_dup 0)
2322         (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2323                          (match_dup 0) (match_dup 4)))]
2324   "
2325   operands[2] = GEN_INT (((1 << INTVAL (operands[2])) - 1)
2326                          << INTVAL (operands[3])); 
2327   "
2328   [(set_attr "conds" "clob")
2329    (set_attr "length" "8")
2330    (set_attr "type" "multiple")]
2333 (define_insn_and_split "*ite_ne_zeroextractsi_shifted"
2334   [(set (match_operand:SI 0 "s_register_operand" "=r")
2335         (if_then_else:SI (ne (zero_extract:SI
2336                               (match_operand:SI 1 "s_register_operand" "r")
2337                               (match_operand:SI 2 "const_int_operand" "n")
2338                               (const_int 0))
2339                              (const_int 0))
2340                          (match_operand:SI 3 "arm_not_operand" "rIK")
2341                          (const_int 0)))
2342    (clobber (reg:CC CC_REGNUM))]
2343   "TARGET_ARM && !reg_overlap_mentioned_p (operands[0], operands[3])"
2344   "#"
2345   "TARGET_ARM && !reg_overlap_mentioned_p (operands[0], operands[3])"
2346   [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2347                    (compare:CC_NOOV (ashift:SI (match_dup 1) (match_dup 2))
2348                                     (const_int 0)))
2349               (set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))])
2350    (set (match_dup 0)
2351         (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2352                          (match_dup 0) (match_dup 3)))]
2353   "
2354   operands[2] = GEN_INT (32 - INTVAL (operands[2]));
2355   "
2356   [(set_attr "conds" "clob")
2357    (set_attr "length" "8")
2358    (set_attr "type" "multiple")]
2361 ;; ??? Use Thumb-2 has bitfield insert/extract instructions.
2362 (define_split
2363   [(set (match_operand:SI 0 "s_register_operand" "")
2364         (match_operator:SI 1 "shiftable_operator"
2365          [(zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
2366                            (match_operand:SI 3 "const_int_operand" "")
2367                            (match_operand:SI 4 "const_int_operand" ""))
2368           (match_operand:SI 5 "s_register_operand" "")]))
2369    (clobber (match_operand:SI 6 "s_register_operand" ""))]
2370   "TARGET_ARM"
2371   [(set (match_dup 6) (ashift:SI (match_dup 2) (match_dup 3)))
2372    (set (match_dup 0)
2373         (match_op_dup 1
2374          [(lshiftrt:SI (match_dup 6) (match_dup 4))
2375           (match_dup 5)]))]
2376   "{
2377      HOST_WIDE_INT temp = INTVAL (operands[3]);
2379      operands[3] = GEN_INT (32 - temp - INTVAL (operands[4]));
2380      operands[4] = GEN_INT (32 - temp);
2381    }"
2383   
2384 (define_split
2385   [(set (match_operand:SI 0 "s_register_operand" "")
2386         (match_operator:SI 1 "shiftable_operator"
2387          [(sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
2388                            (match_operand:SI 3 "const_int_operand" "")
2389                            (match_operand:SI 4 "const_int_operand" ""))
2390           (match_operand:SI 5 "s_register_operand" "")]))
2391    (clobber (match_operand:SI 6 "s_register_operand" ""))]
2392   "TARGET_ARM"
2393   [(set (match_dup 6) (ashift:SI (match_dup 2) (match_dup 3)))
2394    (set (match_dup 0)
2395         (match_op_dup 1
2396          [(ashiftrt:SI (match_dup 6) (match_dup 4))
2397           (match_dup 5)]))]
2398   "{
2399      HOST_WIDE_INT temp = INTVAL (operands[3]);
2401      operands[3] = GEN_INT (32 - temp - INTVAL (operands[4]));
2402      operands[4] = GEN_INT (32 - temp);
2403    }"
2405   
2406 ;;; ??? This pattern is bogus.  If operand3 has bits outside the range
2407 ;;; represented by the bitfield, then this will produce incorrect results.
2408 ;;; Somewhere, the value needs to be truncated.  On targets like the m68k,
2409 ;;; which have a real bit-field insert instruction, the truncation happens
2410 ;;; in the bit-field insert instruction itself.  Since arm does not have a
2411 ;;; bit-field insert instruction, we would have to emit code here to truncate
2412 ;;; the value before we insert.  This loses some of the advantage of having
2413 ;;; this insv pattern, so this pattern needs to be reevalutated.
2415 (define_expand "insv"
2416   [(set (zero_extract (match_operand 0 "nonimmediate_operand" "")
2417                       (match_operand 1 "general_operand" "")
2418                       (match_operand 2 "general_operand" ""))
2419         (match_operand 3 "reg_or_int_operand" ""))]
2420   "TARGET_ARM || arm_arch_thumb2"
2421   "
2422   {
2423     int start_bit = INTVAL (operands[2]);
2424     int width = INTVAL (operands[1]);
2425     HOST_WIDE_INT mask = (((HOST_WIDE_INT)1) << width) - 1;
2426     rtx target, subtarget;
2428     if (arm_arch_thumb2)
2429       {
2430         if (unaligned_access && MEM_P (operands[0])
2431             && s_register_operand (operands[3], GET_MODE (operands[3]))
2432             && (width == 16 || width == 32) && (start_bit % BITS_PER_UNIT) == 0)
2433           {
2434             rtx base_addr;
2436             if (BYTES_BIG_ENDIAN)
2437               start_bit = GET_MODE_BITSIZE (GET_MODE (operands[3])) - width
2438                           - start_bit;
2440             if (width == 32)
2441               {
2442                 base_addr = adjust_address (operands[0], SImode,
2443                                             start_bit / BITS_PER_UNIT);
2444                 emit_insn (gen_unaligned_storesi (base_addr, operands[3]));
2445               }
2446             else
2447               {
2448                 rtx tmp = gen_reg_rtx (HImode);
2450                 base_addr = adjust_address (operands[0], HImode,
2451                                             start_bit / BITS_PER_UNIT);
2452                 emit_move_insn (tmp, gen_lowpart (HImode, operands[3]));
2453                 emit_insn (gen_unaligned_storehi (base_addr, tmp));
2454               }
2455             DONE;
2456           }
2457         else if (s_register_operand (operands[0], GET_MODE (operands[0])))
2458           {
2459             bool use_bfi = TRUE;
2461             if (CONST_INT_P (operands[3]))
2462               {
2463                 HOST_WIDE_INT val = INTVAL (operands[3]) & mask;
2465                 if (val == 0)
2466                   {
2467                     emit_insn (gen_insv_zero (operands[0], operands[1],
2468                                               operands[2]));
2469                     DONE;
2470                   }
2472                 /* See if the set can be done with a single orr instruction.  */
2473                 if (val == mask && const_ok_for_arm (val << start_bit))
2474                   use_bfi = FALSE;
2475               }
2477             if (use_bfi)
2478               {
2479                 if (!REG_P (operands[3]))
2480                   operands[3] = force_reg (SImode, operands[3]);
2482                 emit_insn (gen_insv_t2 (operands[0], operands[1], operands[2],
2483                                         operands[3]));
2484                 DONE;
2485               }
2486           }
2487         else
2488           FAIL;
2489       }
2491     if (!s_register_operand (operands[0], GET_MODE (operands[0])))
2492       FAIL;
2494     target = copy_rtx (operands[0]);
2495     /* Avoid using a subreg as a subtarget, and avoid writing a paradoxical 
2496        subreg as the final target.  */
2497     if (GET_CODE (target) == SUBREG)
2498       {
2499         subtarget = gen_reg_rtx (SImode);
2500         if (GET_MODE_SIZE (GET_MODE (SUBREG_REG (target)))
2501             < GET_MODE_SIZE (SImode))
2502           target = SUBREG_REG (target);
2503       }
2504     else
2505       subtarget = target;    
2507     if (CONST_INT_P (operands[3]))
2508       {
2509         /* Since we are inserting a known constant, we may be able to
2510            reduce the number of bits that we have to clear so that
2511            the mask becomes simple.  */
2512         /* ??? This code does not check to see if the new mask is actually
2513            simpler.  It may not be.  */
2514         rtx op1 = gen_reg_rtx (SImode);
2515         /* ??? Truncate operand3 to fit in the bitfield.  See comment before
2516            start of this pattern.  */
2517         HOST_WIDE_INT op3_value = mask & INTVAL (operands[3]);
2518         HOST_WIDE_INT mask2 = ((mask & ~op3_value) << start_bit);
2520         emit_insn (gen_andsi3 (op1, operands[0],
2521                                gen_int_mode (~mask2, SImode)));
2522         emit_insn (gen_iorsi3 (subtarget, op1,
2523                                gen_int_mode (op3_value << start_bit, SImode)));
2524       }
2525     else if (start_bit == 0
2526              && !(const_ok_for_arm (mask)
2527                   || const_ok_for_arm (~mask)))
2528       {
2529         /* A Trick, since we are setting the bottom bits in the word,
2530            we can shift operand[3] up, operand[0] down, OR them together
2531            and rotate the result back again.  This takes 3 insns, and
2532            the third might be mergeable into another op.  */
2533         /* The shift up copes with the possibility that operand[3] is
2534            wider than the bitfield.  */
2535         rtx op0 = gen_reg_rtx (SImode);
2536         rtx op1 = gen_reg_rtx (SImode);
2538         emit_insn (gen_ashlsi3 (op0, operands[3], GEN_INT (32 - width)));
2539         emit_insn (gen_lshrsi3 (op1, operands[0], operands[1]));
2540         emit_insn (gen_iorsi3  (op1, op1, op0));
2541         emit_insn (gen_rotlsi3 (subtarget, op1, operands[1]));
2542       }
2543     else if ((width + start_bit == 32)
2544              && !(const_ok_for_arm (mask)
2545                   || const_ok_for_arm (~mask)))
2546       {
2547         /* Similar trick, but slightly less efficient.  */
2549         rtx op0 = gen_reg_rtx (SImode);
2550         rtx op1 = gen_reg_rtx (SImode);
2552         emit_insn (gen_ashlsi3 (op0, operands[3], GEN_INT (32 - width)));
2553         emit_insn (gen_ashlsi3 (op1, operands[0], operands[1]));
2554         emit_insn (gen_lshrsi3 (op1, op1, operands[1]));
2555         emit_insn (gen_iorsi3 (subtarget, op1, op0));
2556       }
2557     else
2558       {
2559         rtx op0 = gen_int_mode (mask, SImode);
2560         rtx op1 = gen_reg_rtx (SImode);
2561         rtx op2 = gen_reg_rtx (SImode);
2563         if (!(const_ok_for_arm (mask) || const_ok_for_arm (~mask)))
2564           {
2565             rtx tmp = gen_reg_rtx (SImode);
2567             emit_insn (gen_movsi (tmp, op0));
2568             op0 = tmp;
2569           }
2571         /* Mask out any bits in operand[3] that are not needed.  */
2572            emit_insn (gen_andsi3 (op1, operands[3], op0));
2574         if (CONST_INT_P (op0)
2575             && (const_ok_for_arm (mask << start_bit)
2576                 || const_ok_for_arm (~(mask << start_bit))))
2577           {
2578             op0 = gen_int_mode (~(mask << start_bit), SImode);
2579             emit_insn (gen_andsi3 (op2, operands[0], op0));
2580           }
2581         else
2582           {
2583             if (CONST_INT_P (op0))
2584               {
2585                 rtx tmp = gen_reg_rtx (SImode);
2587                 emit_insn (gen_movsi (tmp, op0));
2588                 op0 = tmp;
2589               }
2591             if (start_bit != 0)
2592               emit_insn (gen_ashlsi3 (op0, op0, operands[2]));
2593             
2594             emit_insn (gen_andsi_notsi_si (op2, operands[0], op0));
2595           }
2597         if (start_bit != 0)
2598           emit_insn (gen_ashlsi3 (op1, op1, operands[2]));
2600         emit_insn (gen_iorsi3 (subtarget, op1, op2));
2601       }
2603     if (subtarget != target)
2604       {
2605         /* If TARGET is still a SUBREG, then it must be wider than a word,
2606            so we must be careful only to set the subword we were asked to.  */
2607         if (GET_CODE (target) == SUBREG)
2608           emit_move_insn (target, subtarget);
2609         else
2610           emit_move_insn (target, gen_lowpart (GET_MODE (target), subtarget));
2611       }
2613     DONE;
2614   }"
2617 (define_insn "insv_zero"
2618   [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r")
2619                          (match_operand:SI 1 "const_int_M_operand" "M")
2620                          (match_operand:SI 2 "const_int_M_operand" "M"))
2621         (const_int 0))]
2622   "arm_arch_thumb2"
2623   "bfc%?\t%0, %2, %1"
2624   [(set_attr "length" "4")
2625    (set_attr "predicable" "yes")
2626    (set_attr "predicable_short_it" "no")
2627    (set_attr "type" "bfm")]
2630 (define_insn "insv_t2"
2631   [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r")
2632                          (match_operand:SI 1 "const_int_M_operand" "M")
2633                          (match_operand:SI 2 "const_int_M_operand" "M"))
2634         (match_operand:SI 3 "s_register_operand" "r"))]
2635   "arm_arch_thumb2"
2636   "bfi%?\t%0, %3, %2, %1"
2637   [(set_attr "length" "4")
2638    (set_attr "predicable" "yes")
2639    (set_attr "predicable_short_it" "no")
2640    (set_attr "type" "bfm")]
2643 ; constants for op 2 will never be given to these patterns.
2644 (define_insn_and_split "*anddi_notdi_di"
2645   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2646         (and:DI (not:DI (match_operand:DI 1 "s_register_operand" "0,r"))
2647                 (match_operand:DI 2 "s_register_operand" "r,0")))]
2648   "TARGET_32BIT"
2649   "#"
2650   "TARGET_32BIT && reload_completed
2651    && ! (TARGET_NEON && IS_VFP_REGNUM (REGNO (operands[0])))
2652    && ! IS_IWMMXT_REGNUM (REGNO (operands[0]))"
2653   [(set (match_dup 0) (and:SI (not:SI (match_dup 1)) (match_dup 2)))
2654    (set (match_dup 3) (and:SI (not:SI (match_dup 4)) (match_dup 5)))]
2655   "
2656   {
2657     operands[3] = gen_highpart (SImode, operands[0]);
2658     operands[0] = gen_lowpart (SImode, operands[0]);
2659     operands[4] = gen_highpart (SImode, operands[1]);
2660     operands[1] = gen_lowpart (SImode, operands[1]);
2661     operands[5] = gen_highpart (SImode, operands[2]);
2662     operands[2] = gen_lowpart (SImode, operands[2]);
2663   }"
2664   [(set_attr "length" "8")
2665    (set_attr "predicable" "yes")
2666    (set_attr "type" "multiple")]
2669 (define_insn_and_split "*anddi_notzesidi_di"
2670   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2671         (and:DI (not:DI (zero_extend:DI
2672                          (match_operand:SI 2 "s_register_operand" "r,r")))
2673                 (match_operand:DI 1 "s_register_operand" "0,?r")))]
2674   "TARGET_32BIT"
2675   "@
2676    bic%?\\t%Q0, %Q1, %2
2677    #"
2678   ; (not (zero_extend ...)) allows us to just copy the high word from
2679   ; operand1 to operand0.
2680   "TARGET_32BIT
2681    && reload_completed
2682    && operands[0] != operands[1]"
2683   [(set (match_dup 0) (and:SI (not:SI (match_dup 2)) (match_dup 1)))
2684    (set (match_dup 3) (match_dup 4))]
2685   "
2686   {
2687     operands[3] = gen_highpart (SImode, operands[0]);
2688     operands[0] = gen_lowpart (SImode, operands[0]);
2689     operands[4] = gen_highpart (SImode, operands[1]);
2690     operands[1] = gen_lowpart (SImode, operands[1]);
2691   }"
2692   [(set_attr "length" "4,8")
2693    (set_attr "predicable" "yes")
2694    (set_attr "predicable_short_it" "no")
2695    (set_attr "type" "multiple")]
2698 (define_insn_and_split "*anddi_notdi_zesidi"
2699   [(set (match_operand:DI 0 "s_register_operand" "=r")
2700         (and:DI (not:DI (match_operand:DI 2 "s_register_operand" "r"))
2701                 (zero_extend:DI
2702                  (match_operand:SI 1 "s_register_operand" "r"))))]
2703   "TARGET_32BIT"
2704   "#"
2705   "TARGET_32BIT && reload_completed"
2706   [(set (match_dup 0) (and:SI (not:SI (match_dup 2)) (match_dup 1)))
2707    (set (match_dup 3) (const_int 0))]
2708   "
2709   {
2710     operands[3] = gen_highpart (SImode, operands[0]);
2711     operands[0] = gen_lowpart (SImode, operands[0]);
2712     operands[2] = gen_lowpart (SImode, operands[2]);
2713   }"
2714   [(set_attr "length" "8")
2715    (set_attr "predicable" "yes")
2716    (set_attr "predicable_short_it" "no")
2717    (set_attr "type" "multiple")]
2720 (define_insn_and_split "*anddi_notsesidi_di"
2721   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2722         (and:DI (not:DI (sign_extend:DI
2723                          (match_operand:SI 2 "s_register_operand" "r,r")))
2724                 (match_operand:DI 1 "s_register_operand" "0,r")))]
2725   "TARGET_32BIT"
2726   "#"
2727   "TARGET_32BIT && reload_completed"
2728   [(set (match_dup 0) (and:SI (not:SI (match_dup 2)) (match_dup 1)))
2729    (set (match_dup 3) (and:SI (not:SI
2730                                 (ashiftrt:SI (match_dup 2) (const_int 31)))
2731                                (match_dup 4)))]
2732   "
2733   {
2734     operands[3] = gen_highpart (SImode, operands[0]);
2735     operands[0] = gen_lowpart (SImode, operands[0]);
2736     operands[4] = gen_highpart (SImode, operands[1]);
2737     operands[1] = gen_lowpart (SImode, operands[1]);
2738   }"
2739   [(set_attr "length" "8")
2740    (set_attr "predicable" "yes")
2741    (set_attr "predicable_short_it" "no")
2742    (set_attr "type" "multiple")]
2745 (define_insn "andsi_notsi_si"
2746   [(set (match_operand:SI 0 "s_register_operand" "=r")
2747         (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
2748                 (match_operand:SI 1 "s_register_operand" "r")))]
2749   "TARGET_32BIT"
2750   "bic%?\\t%0, %1, %2"
2751   [(set_attr "predicable" "yes")
2752    (set_attr "predicable_short_it" "no")
2753    (set_attr "type" "logic_reg")]
2756 (define_insn "andsi_not_shiftsi_si"
2757   [(set (match_operand:SI 0 "s_register_operand" "=r")
2758         (and:SI (not:SI (match_operator:SI 4 "shift_operator"
2759                          [(match_operand:SI 2 "s_register_operand" "r")
2760                           (match_operand:SI 3 "arm_rhs_operand" "rM")]))
2761                 (match_operand:SI 1 "s_register_operand" "r")))]
2762   "TARGET_ARM"
2763   "bic%?\\t%0, %1, %2%S4"
2764   [(set_attr "predicable" "yes")
2765    (set_attr "shift" "2")
2766    (set (attr "type") (if_then_else (match_operand 3 "const_int_operand" "")
2767                       (const_string "logic_shift_imm")
2768                       (const_string "logic_shift_reg")))]
2771 (define_insn "*andsi_notsi_si_compare0"
2772   [(set (reg:CC_NOOV CC_REGNUM)
2773         (compare:CC_NOOV
2774          (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
2775                  (match_operand:SI 1 "s_register_operand" "r"))
2776          (const_int 0)))
2777    (set (match_operand:SI 0 "s_register_operand" "=r")
2778         (and:SI (not:SI (match_dup 2)) (match_dup 1)))]
2779   "TARGET_32BIT"
2780   "bic%.\\t%0, %1, %2"
2781   [(set_attr "conds" "set")
2782    (set_attr "type" "logics_shift_reg")]
2785 (define_insn "*andsi_notsi_si_compare0_scratch"
2786   [(set (reg:CC_NOOV CC_REGNUM)
2787         (compare:CC_NOOV
2788          (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
2789                  (match_operand:SI 1 "s_register_operand" "r"))
2790          (const_int 0)))
2791    (clobber (match_scratch:SI 0 "=r"))]
2792   "TARGET_32BIT"
2793   "bic%.\\t%0, %1, %2"
2794   [(set_attr "conds" "set")
2795    (set_attr "type" "logics_shift_reg")]
2798 (define_expand "iordi3"
2799   [(set (match_operand:DI         0 "s_register_operand" "")
2800         (ior:DI (match_operand:DI 1 "s_register_operand" "")
2801                 (match_operand:DI 2 "neon_logic_op2" "")))]
2802   "TARGET_32BIT"
2803   ""
2806 (define_insn_and_split "*iordi3_insn"
2807   [(set (match_operand:DI         0 "s_register_operand"     "=w,w ,&r,&r,&r,&r,?w,?w")
2808         (ior:DI (match_operand:DI 1 "s_register_operand"     "%w,0 ,0 ,r ,0 ,r ,w ,0")
2809                 (match_operand:DI 2 "arm_iordi_operand_neon" "w ,Dl,r ,r ,Df,Df,w ,Dl")))]
2810   "TARGET_32BIT && !TARGET_IWMMXT"
2811   {
2812   switch (which_alternative)
2813     {
2814     case 0: /* fall through */
2815     case 6: return "vorr\t%P0, %P1, %P2";
2816     case 1: /* fall through */
2817     case 7: return neon_output_logic_immediate ("vorr", &operands[2],
2818                      DImode, 0, VALID_NEON_QREG_MODE (DImode));
2819     case 2:
2820     case 3:
2821     case 4:
2822     case 5:
2823       return "#";
2824     default: gcc_unreachable ();
2825     }
2826   }
2827   "TARGET_32BIT && !TARGET_IWMMXT && reload_completed
2828    && !(IS_VFP_REGNUM (REGNO (operands[0])))"
2829   [(set (match_dup 3) (match_dup 4))
2830    (set (match_dup 5) (match_dup 6))]
2831   "
2832   {
2833     operands[3] = gen_lowpart (SImode, operands[0]);
2834     operands[5] = gen_highpart (SImode, operands[0]);
2836     operands[4] = simplify_gen_binary (IOR, SImode,
2837                                            gen_lowpart (SImode, operands[1]),
2838                                            gen_lowpart (SImode, operands[2]));
2839     operands[6] = simplify_gen_binary (IOR, SImode,
2840                                            gen_highpart (SImode, operands[1]),
2841                                            gen_highpart_mode (SImode, DImode, operands[2]));
2843   }"
2844   [(set_attr "type" "neon_logic,neon_logic,multiple,multiple,multiple,\
2845                      multiple,neon_logic,neon_logic")
2846    (set_attr "length" "*,*,8,8,8,8,*,*")
2847    (set_attr "arch" "neon_for_64bits,neon_for_64bits,*,*,*,*,avoid_neon_for_64bits,avoid_neon_for_64bits")]
2850 (define_insn "*iordi_zesidi_di"
2851   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2852         (ior:DI (zero_extend:DI
2853                  (match_operand:SI 2 "s_register_operand" "r,r"))
2854                 (match_operand:DI 1 "s_register_operand" "0,?r")))]
2855   "TARGET_32BIT"
2856   "@
2857    orr%?\\t%Q0, %Q1, %2
2858    #"
2859   [(set_attr "length" "4,8")
2860    (set_attr "predicable" "yes")
2861    (set_attr "predicable_short_it" "no")
2862    (set_attr "type" "logic_reg,multiple")]
2865 (define_insn "*iordi_sesidi_di"
2866   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2867         (ior:DI (sign_extend:DI
2868                  (match_operand:SI 2 "s_register_operand" "r,r"))
2869                 (match_operand:DI 1 "s_register_operand" "0,r")))]
2870   "TARGET_32BIT"
2871   "#"
2872   [(set_attr "length" "8")
2873    (set_attr "predicable" "yes")
2874    (set_attr "type" "multiple")]
2877 (define_expand "iorsi3"
2878   [(set (match_operand:SI         0 "s_register_operand" "")
2879         (ior:SI (match_operand:SI 1 "s_register_operand" "")
2880                 (match_operand:SI 2 "reg_or_int_operand" "")))]
2881   "TARGET_EITHER"
2882   "
2883   if (CONST_INT_P (operands[2]))
2884     {
2885       if (TARGET_32BIT)
2886         {
2887           arm_split_constant (IOR, SImode, NULL_RTX,
2888                               INTVAL (operands[2]), operands[0], operands[1],
2889                               optimize && can_create_pseudo_p ());
2890           DONE;
2891         }
2892       else /* TARGET_THUMB1 */
2893         {
2894           rtx tmp = force_reg (SImode, operands[2]);
2895           if (rtx_equal_p (operands[0], operands[1]))
2896             operands[2] = tmp;
2897           else
2898             {
2899               operands[2] = operands[1];
2900               operands[1] = tmp;
2901             }
2902         }
2903     }
2904   "
2907 (define_insn_and_split "*iorsi3_insn"
2908   [(set (match_operand:SI 0 "s_register_operand" "=r,l,r,r,r")
2909         (ior:SI (match_operand:SI 1 "s_register_operand" "%r,0,r,r,r")
2910                 (match_operand:SI 2 "reg_or_int_operand" "I,l,K,r,?n")))]
2911   "TARGET_32BIT"
2912   "@
2913    orr%?\\t%0, %1, %2
2914    orr%?\\t%0, %1, %2
2915    orn%?\\t%0, %1, #%B2
2916    orr%?\\t%0, %1, %2
2917    #"
2918   "TARGET_32BIT
2919    && CONST_INT_P (operands[2])
2920    && !(const_ok_for_arm (INTVAL (operands[2]))
2921         || (TARGET_THUMB2 && const_ok_for_arm (~INTVAL (operands[2]))))"
2922   [(clobber (const_int 0))]
2924   arm_split_constant (IOR, SImode, curr_insn,
2925                       INTVAL (operands[2]), operands[0], operands[1], 0);
2926   DONE;
2928   [(set_attr "length" "4,4,4,4,16")
2929    (set_attr "arch" "32,t2,t2,32,32")
2930    (set_attr "predicable" "yes")
2931    (set_attr "predicable_short_it" "no,yes,no,no,no")
2932    (set_attr "type" "logic_imm,logic_reg,logic_imm,logic_reg,logic_reg")]
2935 (define_peephole2
2936   [(match_scratch:SI 3 "r")
2937    (set (match_operand:SI 0 "arm_general_register_operand" "")
2938         (ior:SI (match_operand:SI 1 "arm_general_register_operand" "")
2939                 (match_operand:SI 2 "const_int_operand" "")))]
2940   "TARGET_ARM
2941    && !const_ok_for_arm (INTVAL (operands[2]))
2942    && const_ok_for_arm (~INTVAL (operands[2]))"
2943   [(set (match_dup 3) (match_dup 2))
2944    (set (match_dup 0) (ior:SI (match_dup 1) (match_dup 3)))]
2945   ""
2948 (define_insn "*iorsi3_compare0"
2949   [(set (reg:CC_NOOV CC_REGNUM)
2950         (compare:CC_NOOV (ior:SI (match_operand:SI 1 "s_register_operand" "%r,r")
2951                                  (match_operand:SI 2 "arm_rhs_operand" "I,r"))
2952                          (const_int 0)))
2953    (set (match_operand:SI 0 "s_register_operand" "=r,r")
2954         (ior:SI (match_dup 1) (match_dup 2)))]
2955   "TARGET_32BIT"
2956   "orr%.\\t%0, %1, %2"
2957   [(set_attr "conds" "set")
2958    (set_attr "type" "logics_imm,logics_reg")]
2961 (define_insn "*iorsi3_compare0_scratch"
2962   [(set (reg:CC_NOOV CC_REGNUM)
2963         (compare:CC_NOOV (ior:SI (match_operand:SI 1 "s_register_operand" "%r,r")
2964                                  (match_operand:SI 2 "arm_rhs_operand" "I,r"))
2965                          (const_int 0)))
2966    (clobber (match_scratch:SI 0 "=r,r"))]
2967   "TARGET_32BIT"
2968   "orr%.\\t%0, %1, %2"
2969   [(set_attr "conds" "set")
2970    (set_attr "type" "logics_imm,logics_reg")]
2973 (define_expand "xordi3"
2974   [(set (match_operand:DI         0 "s_register_operand" "")
2975         (xor:DI (match_operand:DI 1 "s_register_operand" "")
2976                 (match_operand:DI 2 "arm_xordi_operand" "")))]
2977   "TARGET_32BIT"
2978   ""
2981 (define_insn_and_split "*xordi3_insn"
2982   [(set (match_operand:DI         0 "s_register_operand" "=w,&r,&r,&r,&r,?w")
2983         (xor:DI (match_operand:DI 1 "s_register_operand" "%w ,0,r ,0 ,r ,w")
2984                 (match_operand:DI 2 "arm_xordi_operand"  "w ,r ,r ,Dg,Dg,w")))]
2985   "TARGET_32BIT && !TARGET_IWMMXT"
2987   switch (which_alternative)
2988     {
2989     case 1:
2990     case 2:
2991     case 3:
2992     case 4:  /* fall through */
2993       return "#";
2994     case 0: /* fall through */
2995     case 5: return "veor\t%P0, %P1, %P2";
2996     default: gcc_unreachable ();
2997     }
2999   "TARGET_32BIT && !TARGET_IWMMXT && reload_completed
3000    && !(IS_VFP_REGNUM (REGNO (operands[0])))"
3001   [(set (match_dup 3) (match_dup 4))
3002    (set (match_dup 5) (match_dup 6))]
3003   "
3004   {
3005     operands[3] = gen_lowpart (SImode, operands[0]);
3006     operands[5] = gen_highpart (SImode, operands[0]);
3008     operands[4] = simplify_gen_binary (XOR, SImode,
3009                                            gen_lowpart (SImode, operands[1]),
3010                                            gen_lowpart (SImode, operands[2]));
3011     operands[6] = simplify_gen_binary (XOR, SImode,
3012                                            gen_highpart (SImode, operands[1]),
3013                                            gen_highpart_mode (SImode, DImode, operands[2]));
3015   }"
3016   [(set_attr "length" "*,8,8,8,8,*")
3017    (set_attr "type" "neon_logic,multiple,multiple,multiple,multiple,neon_logic")
3018    (set_attr "arch" "neon_for_64bits,*,*,*,*,avoid_neon_for_64bits")]
3021 (define_insn "*xordi_zesidi_di"
3022   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
3023         (xor:DI (zero_extend:DI
3024                  (match_operand:SI 2 "s_register_operand" "r,r"))
3025                 (match_operand:DI 1 "s_register_operand" "0,?r")))]
3026   "TARGET_32BIT"
3027   "@
3028    eor%?\\t%Q0, %Q1, %2
3029    #"
3030   [(set_attr "length" "4,8")
3031    (set_attr "predicable" "yes")
3032    (set_attr "predicable_short_it" "no")
3033    (set_attr "type" "logic_reg")]
3036 (define_insn "*xordi_sesidi_di"
3037   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
3038         (xor:DI (sign_extend:DI
3039                  (match_operand:SI 2 "s_register_operand" "r,r"))
3040                 (match_operand:DI 1 "s_register_operand" "0,r")))]
3041   "TARGET_32BIT"
3042   "#"
3043   [(set_attr "length" "8")
3044    (set_attr "predicable" "yes")
3045    (set_attr "type" "multiple")]
3048 (define_expand "xorsi3"
3049   [(set (match_operand:SI         0 "s_register_operand" "")
3050         (xor:SI (match_operand:SI 1 "s_register_operand" "")
3051                 (match_operand:SI 2 "reg_or_int_operand" "")))]
3052   "TARGET_EITHER"
3053   "if (CONST_INT_P (operands[2]))
3054     {
3055       if (TARGET_32BIT)
3056         {
3057           arm_split_constant (XOR, SImode, NULL_RTX,
3058                               INTVAL (operands[2]), operands[0], operands[1],
3059                               optimize && can_create_pseudo_p ());
3060           DONE;
3061         }
3062       else /* TARGET_THUMB1 */
3063         {
3064           rtx tmp = force_reg (SImode, operands[2]);
3065           if (rtx_equal_p (operands[0], operands[1]))
3066             operands[2] = tmp;
3067           else
3068             {
3069               operands[2] = operands[1];
3070               operands[1] = tmp;
3071             }
3072         }
3073     }"
3076 (define_insn_and_split "*arm_xorsi3"
3077   [(set (match_operand:SI         0 "s_register_operand" "=r,l,r,r")
3078         (xor:SI (match_operand:SI 1 "s_register_operand" "%r,0,r,r")
3079                 (match_operand:SI 2 "reg_or_int_operand" "I,l,r,?n")))]
3080   "TARGET_32BIT"
3081   "@
3082    eor%?\\t%0, %1, %2
3083    eor%?\\t%0, %1, %2
3084    eor%?\\t%0, %1, %2
3085    #"
3086   "TARGET_32BIT
3087    && CONST_INT_P (operands[2])
3088    && !const_ok_for_arm (INTVAL (operands[2]))"
3089   [(clobber (const_int 0))]
3091   arm_split_constant (XOR, SImode, curr_insn,
3092                       INTVAL (operands[2]), operands[0], operands[1], 0);
3093   DONE;
3095   [(set_attr "length" "4,4,4,16")
3096    (set_attr "predicable" "yes")
3097    (set_attr "predicable_short_it" "no,yes,no,no")
3098    (set_attr "type"  "logic_imm,logic_reg,logic_reg,multiple")]
3101 (define_insn "*xorsi3_compare0"
3102   [(set (reg:CC_NOOV CC_REGNUM)
3103         (compare:CC_NOOV (xor:SI (match_operand:SI 1 "s_register_operand" "r,r")
3104                                  (match_operand:SI 2 "arm_rhs_operand" "I,r"))
3105                          (const_int 0)))
3106    (set (match_operand:SI 0 "s_register_operand" "=r,r")
3107         (xor:SI (match_dup 1) (match_dup 2)))]
3108   "TARGET_32BIT"
3109   "eor%.\\t%0, %1, %2"
3110   [(set_attr "conds" "set")
3111    (set_attr "type" "logics_imm,logics_reg")]
3114 (define_insn "*xorsi3_compare0_scratch"
3115   [(set (reg:CC_NOOV CC_REGNUM)
3116         (compare:CC_NOOV (xor:SI (match_operand:SI 0 "s_register_operand" "r,r")
3117                                  (match_operand:SI 1 "arm_rhs_operand" "I,r"))
3118                          (const_int 0)))]
3119   "TARGET_32BIT"
3120   "teq%?\\t%0, %1"
3121   [(set_attr "conds" "set")
3122    (set_attr "type" "logics_imm,logics_reg")]
3125 ; By splitting (IOR (AND (NOT A) (NOT B)) C) as D = AND (IOR A B) (NOT C), 
3126 ; (NOT D) we can sometimes merge the final NOT into one of the following
3127 ; insns.
3129 (define_split
3130   [(set (match_operand:SI 0 "s_register_operand" "")
3131         (ior:SI (and:SI (not:SI (match_operand:SI 1 "s_register_operand" ""))
3132                         (not:SI (match_operand:SI 2 "arm_rhs_operand" "")))
3133                 (match_operand:SI 3 "arm_rhs_operand" "")))
3134    (clobber (match_operand:SI 4 "s_register_operand" ""))]
3135   "TARGET_32BIT"
3136   [(set (match_dup 4) (and:SI (ior:SI (match_dup 1) (match_dup 2))
3137                               (not:SI (match_dup 3))))
3138    (set (match_dup 0) (not:SI (match_dup 4)))]
3139   ""
3142 (define_insn_and_split "*andsi_iorsi3_notsi"
3143   [(set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r")
3144         (and:SI (ior:SI (match_operand:SI 1 "s_register_operand" "%0,r,r")
3145                         (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI"))
3146                 (not:SI (match_operand:SI 3 "arm_rhs_operand" "rI,rI,rI"))))]
3147   "TARGET_32BIT"
3148   "#"   ; "orr%?\\t%0, %1, %2\;bic%?\\t%0, %0, %3"
3149   "&& reload_completed"
3150   [(set (match_dup 0) (ior:SI (match_dup 1) (match_dup 2)))
3151    (set (match_dup 0) (and:SI (not:SI (match_dup 3)) (match_dup 0)))]
3152   ""
3153   [(set_attr "length" "8")
3154    (set_attr "ce_count" "2")
3155    (set_attr "predicable" "yes")
3156    (set_attr "predicable_short_it" "no")
3157    (set_attr "type" "multiple")]
3160 ; ??? Are these four splitters still beneficial when the Thumb-2 bitfield
3161 ; insns are available?
3162 (define_split
3163   [(set (match_operand:SI 0 "s_register_operand" "")
3164         (match_operator:SI 1 "logical_binary_operator"
3165          [(zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
3166                            (match_operand:SI 3 "const_int_operand" "")
3167                            (match_operand:SI 4 "const_int_operand" ""))
3168           (match_operator:SI 9 "logical_binary_operator"
3169            [(lshiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3170                          (match_operand:SI 6 "const_int_operand" ""))
3171             (match_operand:SI 7 "s_register_operand" "")])]))
3172    (clobber (match_operand:SI 8 "s_register_operand" ""))]
3173   "TARGET_32BIT
3174    && GET_CODE (operands[1]) == GET_CODE (operands[9])
3175    && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3176   [(set (match_dup 8)
3177         (match_op_dup 1
3178          [(ashift:SI (match_dup 2) (match_dup 4))
3179           (match_dup 5)]))
3180    (set (match_dup 0)
3181         (match_op_dup 1
3182          [(lshiftrt:SI (match_dup 8) (match_dup 6))
3183           (match_dup 7)]))]
3184   "
3185   operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3188 (define_split
3189   [(set (match_operand:SI 0 "s_register_operand" "")
3190         (match_operator:SI 1 "logical_binary_operator"
3191          [(match_operator:SI 9 "logical_binary_operator"
3192            [(lshiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3193                          (match_operand:SI 6 "const_int_operand" ""))
3194             (match_operand:SI 7 "s_register_operand" "")])
3195           (zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
3196                            (match_operand:SI 3 "const_int_operand" "")
3197                            (match_operand:SI 4 "const_int_operand" ""))]))
3198    (clobber (match_operand:SI 8 "s_register_operand" ""))]
3199   "TARGET_32BIT
3200    && GET_CODE (operands[1]) == GET_CODE (operands[9])
3201    && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3202   [(set (match_dup 8)
3203         (match_op_dup 1
3204          [(ashift:SI (match_dup 2) (match_dup 4))
3205           (match_dup 5)]))
3206    (set (match_dup 0)
3207         (match_op_dup 1
3208          [(lshiftrt:SI (match_dup 8) (match_dup 6))
3209           (match_dup 7)]))]
3210   "
3211   operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3214 (define_split
3215   [(set (match_operand:SI 0 "s_register_operand" "")
3216         (match_operator:SI 1 "logical_binary_operator"
3217          [(sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
3218                            (match_operand:SI 3 "const_int_operand" "")
3219                            (match_operand:SI 4 "const_int_operand" ""))
3220           (match_operator:SI 9 "logical_binary_operator"
3221            [(ashiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3222                          (match_operand:SI 6 "const_int_operand" ""))
3223             (match_operand:SI 7 "s_register_operand" "")])]))
3224    (clobber (match_operand:SI 8 "s_register_operand" ""))]
3225   "TARGET_32BIT
3226    && GET_CODE (operands[1]) == GET_CODE (operands[9])
3227    && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3228   [(set (match_dup 8)
3229         (match_op_dup 1
3230          [(ashift:SI (match_dup 2) (match_dup 4))
3231           (match_dup 5)]))
3232    (set (match_dup 0)
3233         (match_op_dup 1
3234          [(ashiftrt:SI (match_dup 8) (match_dup 6))
3235           (match_dup 7)]))]
3236   "
3237   operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3240 (define_split
3241   [(set (match_operand:SI 0 "s_register_operand" "")
3242         (match_operator:SI 1 "logical_binary_operator"
3243          [(match_operator:SI 9 "logical_binary_operator"
3244            [(ashiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3245                          (match_operand:SI 6 "const_int_operand" ""))
3246             (match_operand:SI 7 "s_register_operand" "")])
3247           (sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
3248                            (match_operand:SI 3 "const_int_operand" "")
3249                            (match_operand:SI 4 "const_int_operand" ""))]))
3250    (clobber (match_operand:SI 8 "s_register_operand" ""))]
3251   "TARGET_32BIT
3252    && GET_CODE (operands[1]) == GET_CODE (operands[9])
3253    && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3254   [(set (match_dup 8)
3255         (match_op_dup 1
3256          [(ashift:SI (match_dup 2) (match_dup 4))
3257           (match_dup 5)]))
3258    (set (match_dup 0)
3259         (match_op_dup 1
3260          [(ashiftrt:SI (match_dup 8) (match_dup 6))
3261           (match_dup 7)]))]
3262   "
3263   operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3267 ;; Minimum and maximum insns
3269 (define_expand "smaxsi3"
3270   [(parallel [
3271     (set (match_operand:SI 0 "s_register_operand" "")
3272          (smax:SI (match_operand:SI 1 "s_register_operand" "")
3273                   (match_operand:SI 2 "arm_rhs_operand" "")))
3274     (clobber (reg:CC CC_REGNUM))])]
3275   "TARGET_32BIT"
3276   "
3277   if (operands[2] == const0_rtx || operands[2] == constm1_rtx)
3278     {
3279       /* No need for a clobber of the condition code register here.  */
3280       emit_insn (gen_rtx_SET (operands[0],
3281                               gen_rtx_SMAX (SImode, operands[1],
3282                                             operands[2])));
3283       DONE;
3284     }
3287 (define_insn "*smax_0"
3288   [(set (match_operand:SI 0 "s_register_operand" "=r")
3289         (smax:SI (match_operand:SI 1 "s_register_operand" "r")
3290                  (const_int 0)))]
3291   "TARGET_32BIT"
3292   "bic%?\\t%0, %1, %1, asr #31"
3293   [(set_attr "predicable" "yes")
3294    (set_attr "predicable_short_it" "no")
3295    (set_attr "type" "logic_shift_reg")]
3298 (define_insn "*smax_m1"
3299   [(set (match_operand:SI 0 "s_register_operand" "=r")
3300         (smax:SI (match_operand:SI 1 "s_register_operand" "r")
3301                  (const_int -1)))]
3302   "TARGET_32BIT"
3303   "orr%?\\t%0, %1, %1, asr #31"
3304   [(set_attr "predicable" "yes")
3305    (set_attr "predicable_short_it" "no")
3306    (set_attr "type" "logic_shift_reg")]
3309 (define_insn_and_split "*arm_smax_insn"
3310   [(set (match_operand:SI          0 "s_register_operand" "=r,r")
3311         (smax:SI (match_operand:SI 1 "s_register_operand"  "%0,?r")
3312                  (match_operand:SI 2 "arm_rhs_operand"    "rI,rI")))
3313    (clobber (reg:CC CC_REGNUM))]
3314   "TARGET_ARM"
3315   "#"
3316    ; cmp\\t%1, %2\;movlt\\t%0, %2
3317    ; cmp\\t%1, %2\;movge\\t%0, %1\;movlt\\t%0, %2"
3318   "TARGET_ARM"
3319   [(set (reg:CC CC_REGNUM)
3320         (compare:CC (match_dup 1) (match_dup 2)))
3321    (set (match_dup 0)
3322         (if_then_else:SI (ge:SI (reg:CC CC_REGNUM) (const_int 0))
3323                          (match_dup 1)
3324                          (match_dup 2)))]
3325   ""
3326   [(set_attr "conds" "clob")
3327    (set_attr "length" "8,12")
3328    (set_attr "type" "multiple")]
3331 (define_expand "sminsi3"
3332   [(parallel [
3333     (set (match_operand:SI 0 "s_register_operand" "")
3334          (smin:SI (match_operand:SI 1 "s_register_operand" "")
3335                   (match_operand:SI 2 "arm_rhs_operand" "")))
3336     (clobber (reg:CC CC_REGNUM))])]
3337   "TARGET_32BIT"
3338   "
3339   if (operands[2] == const0_rtx)
3340     {
3341       /* No need for a clobber of the condition code register here.  */
3342       emit_insn (gen_rtx_SET (operands[0],
3343                               gen_rtx_SMIN (SImode, operands[1],
3344                                             operands[2])));
3345       DONE;
3346     }
3349 (define_insn "*smin_0"
3350   [(set (match_operand:SI 0 "s_register_operand" "=r")
3351         (smin:SI (match_operand:SI 1 "s_register_operand" "r")
3352                  (const_int 0)))]
3353   "TARGET_32BIT"
3354   "and%?\\t%0, %1, %1, asr #31"
3355   [(set_attr "predicable" "yes")
3356    (set_attr "predicable_short_it" "no")
3357    (set_attr "type" "logic_shift_reg")]
3360 (define_insn_and_split "*arm_smin_insn"
3361   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3362         (smin:SI (match_operand:SI 1 "s_register_operand" "%0,?r")
3363                  (match_operand:SI 2 "arm_rhs_operand" "rI,rI")))
3364    (clobber (reg:CC CC_REGNUM))]
3365   "TARGET_ARM"
3366   "#"
3367     ; cmp\\t%1, %2\;movge\\t%0, %2
3368     ; cmp\\t%1, %2\;movlt\\t%0, %1\;movge\\t%0, %2"
3369   "TARGET_ARM"
3370   [(set (reg:CC CC_REGNUM)
3371         (compare:CC (match_dup 1) (match_dup 2)))
3372    (set (match_dup 0)
3373         (if_then_else:SI (lt:SI (reg:CC CC_REGNUM) (const_int 0))
3374                          (match_dup 1)
3375                          (match_dup 2)))]
3376   ""
3377   [(set_attr "conds" "clob")
3378    (set_attr "length" "8,12")
3379    (set_attr "type" "multiple,multiple")]
3382 (define_expand "umaxsi3"
3383   [(parallel [
3384     (set (match_operand:SI 0 "s_register_operand" "")
3385          (umax:SI (match_operand:SI 1 "s_register_operand" "")
3386                   (match_operand:SI 2 "arm_rhs_operand" "")))
3387     (clobber (reg:CC CC_REGNUM))])]
3388   "TARGET_32BIT"
3389   ""
3392 (define_insn_and_split "*arm_umaxsi3"
3393   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
3394         (umax:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
3395                  (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
3396    (clobber (reg:CC CC_REGNUM))]
3397   "TARGET_ARM"
3398   "#"
3399     ; cmp\\t%1, %2\;movcc\\t%0, %2
3400     ; cmp\\t%1, %2\;movcs\\t%0, %1
3401     ; cmp\\t%1, %2\;movcs\\t%0, %1\;movcc\\t%0, %2"
3402   "TARGET_ARM"
3403   [(set (reg:CC CC_REGNUM)
3404         (compare:CC (match_dup 1) (match_dup 2)))
3405    (set (match_dup 0)
3406         (if_then_else:SI (geu:SI (reg:CC CC_REGNUM) (const_int 0))
3407                          (match_dup 1)
3408                          (match_dup 2)))]
3409   ""
3410   [(set_attr "conds" "clob")
3411    (set_attr "length" "8,8,12")
3412    (set_attr "type" "store1")]
3415 (define_expand "uminsi3"
3416   [(parallel [
3417     (set (match_operand:SI 0 "s_register_operand" "")
3418          (umin:SI (match_operand:SI 1 "s_register_operand" "")
3419                   (match_operand:SI 2 "arm_rhs_operand" "")))
3420     (clobber (reg:CC CC_REGNUM))])]
3421   "TARGET_32BIT"
3422   ""
3425 (define_insn_and_split "*arm_uminsi3"
3426   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
3427         (umin:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
3428                  (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
3429    (clobber (reg:CC CC_REGNUM))]
3430   "TARGET_ARM"
3431   "#"
3432    ; cmp\\t%1, %2\;movcs\\t%0, %2
3433    ; cmp\\t%1, %2\;movcc\\t%0, %1
3434    ; cmp\\t%1, %2\;movcc\\t%0, %1\;movcs\\t%0, %2"
3435   "TARGET_ARM"
3436   [(set (reg:CC CC_REGNUM)
3437         (compare:CC (match_dup 1) (match_dup 2)))
3438    (set (match_dup 0)
3439         (if_then_else:SI (ltu:SI (reg:CC CC_REGNUM) (const_int 0))
3440                          (match_dup 1)
3441                          (match_dup 2)))]
3442   ""
3443   [(set_attr "conds" "clob")
3444    (set_attr "length" "8,8,12")
3445    (set_attr "type" "store1")]
3448 (define_insn "*store_minmaxsi"
3449   [(set (match_operand:SI 0 "memory_operand" "=m")
3450         (match_operator:SI 3 "minmax_operator"
3451          [(match_operand:SI 1 "s_register_operand" "r")
3452           (match_operand:SI 2 "s_register_operand" "r")]))
3453    (clobber (reg:CC CC_REGNUM))]
3454   "TARGET_32BIT && optimize_function_for_size_p (cfun) && !arm_restrict_it"
3455   "*
3456   operands[3] = gen_rtx_fmt_ee (minmax_code (operands[3]), SImode,
3457                                 operands[1], operands[2]);
3458   output_asm_insn (\"cmp\\t%1, %2\", operands);
3459   if (TARGET_THUMB2)
3460     output_asm_insn (\"ite\t%d3\", operands);
3461   output_asm_insn (\"str%d3\\t%1, %0\", operands);
3462   output_asm_insn (\"str%D3\\t%2, %0\", operands);
3463   return \"\";
3464   "
3465   [(set_attr "conds" "clob")
3466    (set (attr "length")
3467         (if_then_else (eq_attr "is_thumb" "yes")
3468                       (const_int 14)
3469                       (const_int 12)))
3470    (set_attr "type" "store1")]
3473 ; Reject the frame pointer in operand[1], since reloading this after
3474 ; it has been eliminated can cause carnage.
3475 (define_insn "*minmax_arithsi"
3476   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3477         (match_operator:SI 4 "shiftable_operator"
3478          [(match_operator:SI 5 "minmax_operator"
3479            [(match_operand:SI 2 "s_register_operand" "r,r")
3480             (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
3481           (match_operand:SI 1 "s_register_operand" "0,?r")]))
3482    (clobber (reg:CC CC_REGNUM))]
3483   "TARGET_32BIT && !arm_eliminable_register (operands[1]) && !arm_restrict_it"
3484   "*
3485   {
3486     enum rtx_code code = GET_CODE (operands[4]);
3487     bool need_else;
3489     if (which_alternative != 0 || operands[3] != const0_rtx
3490         || (code != PLUS && code != IOR && code != XOR))
3491       need_else = true;
3492     else
3493       need_else = false;
3495     operands[5] = gen_rtx_fmt_ee (minmax_code (operands[5]), SImode,
3496                                   operands[2], operands[3]);
3497     output_asm_insn (\"cmp\\t%2, %3\", operands);
3498     if (TARGET_THUMB2)
3499       {
3500         if (need_else)
3501           output_asm_insn (\"ite\\t%d5\", operands);
3502         else
3503           output_asm_insn (\"it\\t%d5\", operands);
3504       }
3505     output_asm_insn (\"%i4%d5\\t%0, %1, %2\", operands);
3506     if (need_else)
3507       output_asm_insn (\"%i4%D5\\t%0, %1, %3\", operands);
3508     return \"\";
3509   }"
3510   [(set_attr "conds" "clob")
3511    (set (attr "length")
3512         (if_then_else (eq_attr "is_thumb" "yes")
3513                       (const_int 14)
3514                       (const_int 12)))
3515    (set_attr "type" "multiple")]
3518 ; Reject the frame pointer in operand[1], since reloading this after
3519 ; it has been eliminated can cause carnage.
3520 (define_insn_and_split "*minmax_arithsi_non_canon"
3521   [(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts")
3522         (minus:SI
3523          (match_operand:SI 1 "s_register_operand" "0,?Ts")
3524           (match_operator:SI 4 "minmax_operator"
3525            [(match_operand:SI 2 "s_register_operand" "Ts,Ts")
3526             (match_operand:SI 3 "arm_rhs_operand" "TsI,TsI")])))
3527    (clobber (reg:CC CC_REGNUM))]
3528   "TARGET_32BIT && !arm_eliminable_register (operands[1])
3529    && !(arm_restrict_it && CONST_INT_P (operands[3]))"
3530   "#"
3531   "TARGET_32BIT && !arm_eliminable_register (operands[1]) && reload_completed"
3532   [(set (reg:CC CC_REGNUM)
3533         (compare:CC (match_dup 2) (match_dup 3)))
3535    (cond_exec (match_op_dup 4 [(reg:CC CC_REGNUM) (const_int 0)])
3536               (set (match_dup 0)
3537                    (minus:SI (match_dup 1)
3538                              (match_dup 2))))
3539    (cond_exec (match_op_dup 5 [(reg:CC CC_REGNUM) (const_int 0)])
3540               (set (match_dup 0)
3541                    (match_dup 6)))]
3542   {
3543   machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
3544                                            operands[2], operands[3]);
3545   enum rtx_code rc = minmax_code (operands[4]);
3546   operands[4] = gen_rtx_fmt_ee (rc, VOIDmode,
3547                                 operands[2], operands[3]);
3549   if (mode == CCFPmode || mode == CCFPEmode)
3550     rc = reverse_condition_maybe_unordered (rc);
3551   else
3552     rc = reverse_condition (rc);
3553   operands[5] = gen_rtx_fmt_ee (rc, SImode, operands[2], operands[3]);
3554   if (CONST_INT_P (operands[3]))
3555     operands[6] = plus_constant (SImode, operands[1], -INTVAL (operands[3]));
3556   else
3557     operands[6] = gen_rtx_MINUS (SImode, operands[1], operands[3]);
3558   }
3559   [(set_attr "conds" "clob")
3560    (set (attr "length")
3561         (if_then_else (eq_attr "is_thumb" "yes")
3562                       (const_int 14)
3563                       (const_int 12)))
3564    (set_attr "type" "multiple")]
3567 (define_code_iterator SAT [smin smax])
3568 (define_code_iterator SATrev [smin smax])
3569 (define_code_attr SATlo [(smin "1") (smax "2")])
3570 (define_code_attr SAThi [(smin "2") (smax "1")])
3572 (define_insn "*satsi_<SAT:code>"
3573   [(set (match_operand:SI 0 "s_register_operand" "=r")
3574         (SAT:SI (SATrev:SI (match_operand:SI 3 "s_register_operand" "r")
3575                            (match_operand:SI 1 "const_int_operand" "i"))
3576                 (match_operand:SI 2 "const_int_operand" "i")))]
3577   "TARGET_32BIT && arm_arch6 && <SAT:CODE> != <SATrev:CODE>
3578    && arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>], NULL, NULL)"
3580   int mask;
3581   bool signed_sat;
3582   if (!arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>],
3583                                &mask, &signed_sat))
3584     gcc_unreachable ();
3586   operands[1] = GEN_INT (mask);
3587   if (signed_sat)
3588     return "ssat%?\t%0, %1, %3";
3589   else
3590     return "usat%?\t%0, %1, %3";
3592   [(set_attr "predicable" "yes")
3593    (set_attr "predicable_short_it" "no")
3594    (set_attr "type" "alus_imm")]
3597 (define_insn "*satsi_<SAT:code>_shift"
3598   [(set (match_operand:SI 0 "s_register_operand" "=r")
3599         (SAT:SI (SATrev:SI (match_operator:SI 3 "sat_shift_operator"
3600                              [(match_operand:SI 4 "s_register_operand" "r")
3601                               (match_operand:SI 5 "const_int_operand" "i")])
3602                            (match_operand:SI 1 "const_int_operand" "i"))
3603                 (match_operand:SI 2 "const_int_operand" "i")))]
3604   "TARGET_32BIT && arm_arch6 && <SAT:CODE> != <SATrev:CODE>
3605    && arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>], NULL, NULL)"
3607   int mask;
3608   bool signed_sat;
3609   if (!arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>],
3610                                &mask, &signed_sat))
3611     gcc_unreachable ();
3613   operands[1] = GEN_INT (mask);
3614   if (signed_sat)
3615     return "ssat%?\t%0, %1, %4%S3";
3616   else
3617     return "usat%?\t%0, %1, %4%S3";
3619   [(set_attr "predicable" "yes")
3620    (set_attr "predicable_short_it" "no")
3621    (set_attr "shift" "3")
3622    (set_attr "type" "logic_shift_reg")])
3624 ;; Shift and rotation insns
3626 (define_expand "ashldi3"
3627   [(set (match_operand:DI            0 "s_register_operand" "")
3628         (ashift:DI (match_operand:DI 1 "s_register_operand" "")
3629                    (match_operand:SI 2 "general_operand" "")))]
3630   "TARGET_32BIT"
3631   "
3632   if (TARGET_NEON)
3633     {
3634       /* Delay the decision whether to use NEON or core-regs until
3635          register allocation.  */
3636       emit_insn (gen_ashldi3_neon (operands[0], operands[1], operands[2]));
3637       DONE;
3638     }
3639   else
3640     {
3641       /* Only the NEON case can handle in-memory shift counts.  */
3642       if (!reg_or_int_operand (operands[2], SImode))
3643         operands[2] = force_reg (SImode, operands[2]);
3644     }
3646   if (!CONST_INT_P (operands[2]) && TARGET_REALLY_IWMMXT)
3647     ; /* No special preparation statements; expand pattern as above.  */
3648   else
3649     {
3650       rtx scratch1, scratch2;
3652       if (CONST_INT_P (operands[2])
3653           && (HOST_WIDE_INT) INTVAL (operands[2]) == 1)
3654         {
3655           emit_insn (gen_arm_ashldi3_1bit (operands[0], operands[1]));
3656           DONE;
3657         }
3659       /* Ideally we should use iwmmxt here if we could know that operands[1]
3660          ends up already living in an iwmmxt register. Otherwise it's
3661          cheaper to have the alternate code being generated than moving
3662          values to iwmmxt regs and back.  */
3664       /* If we're optimizing for size, we prefer the libgcc calls.  */
3665       if (optimize_function_for_size_p (cfun))
3666         FAIL;
3668       /* Expand operation using core-registers.
3669          'FAIL' would achieve the same thing, but this is a bit smarter.  */
3670       scratch1 = gen_reg_rtx (SImode);
3671       scratch2 = gen_reg_rtx (SImode);
3672       arm_emit_coreregs_64bit_shift (ASHIFT, operands[0], operands[1],
3673                                      operands[2], scratch1, scratch2);
3674       DONE;
3675     }
3676   "
3679 (define_insn "arm_ashldi3_1bit"
3680   [(set (match_operand:DI            0 "s_register_operand" "=r,&r")
3681         (ashift:DI (match_operand:DI 1 "s_register_operand" "0,r")
3682                    (const_int 1)))
3683    (clobber (reg:CC CC_REGNUM))]
3684   "TARGET_32BIT"
3685   "movs\\t%Q0, %Q1, asl #1\;adc\\t%R0, %R1, %R1"
3686   [(set_attr "conds" "clob")
3687    (set_attr "length" "8")
3688    (set_attr "type" "multiple")]
3691 (define_expand "ashlsi3"
3692   [(set (match_operand:SI            0 "s_register_operand" "")
3693         (ashift:SI (match_operand:SI 1 "s_register_operand" "")
3694                    (match_operand:SI 2 "arm_rhs_operand" "")))]
3695   "TARGET_EITHER"
3696   "
3697   if (CONST_INT_P (operands[2])
3698       && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) > 31)
3699     {
3700       emit_insn (gen_movsi (operands[0], const0_rtx));
3701       DONE;
3702     }
3703   "
3706 (define_expand "ashrdi3"
3707   [(set (match_operand:DI              0 "s_register_operand" "")
3708         (ashiftrt:DI (match_operand:DI 1 "s_register_operand" "")
3709                      (match_operand:SI 2 "reg_or_int_operand" "")))]
3710   "TARGET_32BIT"
3711   "
3712   if (TARGET_NEON)
3713     {
3714       /* Delay the decision whether to use NEON or core-regs until
3715          register allocation.  */
3716       emit_insn (gen_ashrdi3_neon (operands[0], operands[1], operands[2]));
3717       DONE;
3718     }
3720   if (!CONST_INT_P (operands[2]) && TARGET_REALLY_IWMMXT)
3721     ; /* No special preparation statements; expand pattern as above.  */
3722   else
3723     {
3724       rtx scratch1, scratch2;
3726       if (CONST_INT_P (operands[2])
3727           && (HOST_WIDE_INT) INTVAL (operands[2]) == 1)
3728         {
3729           emit_insn (gen_arm_ashrdi3_1bit (operands[0], operands[1]));
3730           DONE;
3731         }
3733       /* Ideally we should use iwmmxt here if we could know that operands[1]
3734          ends up already living in an iwmmxt register. Otherwise it's
3735          cheaper to have the alternate code being generated than moving
3736          values to iwmmxt regs and back.  */
3738       /* If we're optimizing for size, we prefer the libgcc calls.  */
3739       if (optimize_function_for_size_p (cfun))
3740         FAIL;
3742       /* Expand operation using core-registers.
3743          'FAIL' would achieve the same thing, but this is a bit smarter.  */
3744       scratch1 = gen_reg_rtx (SImode);
3745       scratch2 = gen_reg_rtx (SImode);
3746       arm_emit_coreregs_64bit_shift (ASHIFTRT, operands[0], operands[1],
3747                                      operands[2], scratch1, scratch2);
3748       DONE;
3749     }
3750   "
3753 (define_insn "arm_ashrdi3_1bit"
3754   [(set (match_operand:DI              0 "s_register_operand" "=r,&r")
3755         (ashiftrt:DI (match_operand:DI 1 "s_register_operand" "0,r")
3756                      (const_int 1)))
3757    (clobber (reg:CC CC_REGNUM))]
3758   "TARGET_32BIT"
3759   "movs\\t%R0, %R1, asr #1\;mov\\t%Q0, %Q1, rrx"
3760   [(set_attr "conds" "clob")
3761    (set_attr "length" "8")
3762    (set_attr "type" "multiple")]
3765 (define_expand "ashrsi3"
3766   [(set (match_operand:SI              0 "s_register_operand" "")
3767         (ashiftrt:SI (match_operand:SI 1 "s_register_operand" "")
3768                      (match_operand:SI 2 "arm_rhs_operand" "")))]
3769   "TARGET_EITHER"
3770   "
3771   if (CONST_INT_P (operands[2])
3772       && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) > 31)
3773     operands[2] = GEN_INT (31);
3774   "
3777 (define_expand "lshrdi3"
3778   [(set (match_operand:DI              0 "s_register_operand" "")
3779         (lshiftrt:DI (match_operand:DI 1 "s_register_operand" "")
3780                      (match_operand:SI 2 "reg_or_int_operand" "")))]
3781   "TARGET_32BIT"
3782   "
3783   if (TARGET_NEON)
3784     {
3785       /* Delay the decision whether to use NEON or core-regs until
3786          register allocation.  */
3787       emit_insn (gen_lshrdi3_neon (operands[0], operands[1], operands[2]));
3788       DONE;
3789     }
3791   if (!CONST_INT_P (operands[2]) && TARGET_REALLY_IWMMXT)
3792     ; /* No special preparation statements; expand pattern as above.  */
3793   else
3794     {
3795       rtx scratch1, scratch2;
3797       if (CONST_INT_P (operands[2])
3798           && (HOST_WIDE_INT) INTVAL (operands[2]) == 1)
3799         {
3800           emit_insn (gen_arm_lshrdi3_1bit (operands[0], operands[1]));
3801           DONE;
3802         }
3804       /* Ideally we should use iwmmxt here if we could know that operands[1]
3805          ends up already living in an iwmmxt register. Otherwise it's
3806          cheaper to have the alternate code being generated than moving
3807          values to iwmmxt regs and back.  */
3809       /* If we're optimizing for size, we prefer the libgcc calls.  */
3810       if (optimize_function_for_size_p (cfun))
3811         FAIL;
3813       /* Expand operation using core-registers.
3814          'FAIL' would achieve the same thing, but this is a bit smarter.  */
3815       scratch1 = gen_reg_rtx (SImode);
3816       scratch2 = gen_reg_rtx (SImode);
3817       arm_emit_coreregs_64bit_shift (LSHIFTRT, operands[0], operands[1],
3818                                      operands[2], scratch1, scratch2);
3819       DONE;
3820     }
3821   "
3824 (define_insn "arm_lshrdi3_1bit"
3825   [(set (match_operand:DI              0 "s_register_operand" "=r,&r")
3826         (lshiftrt:DI (match_operand:DI 1 "s_register_operand" "0,r")
3827                      (const_int 1)))
3828    (clobber (reg:CC CC_REGNUM))]
3829   "TARGET_32BIT"
3830   "movs\\t%R0, %R1, lsr #1\;mov\\t%Q0, %Q1, rrx"
3831   [(set_attr "conds" "clob")
3832    (set_attr "length" "8")
3833    (set_attr "type" "multiple")]
3836 (define_expand "lshrsi3"
3837   [(set (match_operand:SI              0 "s_register_operand" "")
3838         (lshiftrt:SI (match_operand:SI 1 "s_register_operand" "")
3839                      (match_operand:SI 2 "arm_rhs_operand" "")))]
3840   "TARGET_EITHER"
3841   "
3842   if (CONST_INT_P (operands[2])
3843       && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) > 31)
3844     {
3845       emit_insn (gen_movsi (operands[0], const0_rtx));
3846       DONE;
3847     }
3848   "
3851 (define_expand "rotlsi3"
3852   [(set (match_operand:SI              0 "s_register_operand" "")
3853         (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
3854                      (match_operand:SI 2 "reg_or_int_operand" "")))]
3855   "TARGET_32BIT"
3856   "
3857   if (CONST_INT_P (operands[2]))
3858     operands[2] = GEN_INT ((32 - INTVAL (operands[2])) % 32);
3859   else
3860     {
3861       rtx reg = gen_reg_rtx (SImode);
3862       emit_insn (gen_subsi3 (reg, GEN_INT (32), operands[2]));
3863       operands[2] = reg;
3864     }
3865   "
3868 (define_expand "rotrsi3"
3869   [(set (match_operand:SI              0 "s_register_operand" "")
3870         (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
3871                      (match_operand:SI 2 "arm_rhs_operand" "")))]
3872   "TARGET_EITHER"
3873   "
3874   if (TARGET_32BIT)
3875     {
3876       if (CONST_INT_P (operands[2])
3877           && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) > 31)
3878         operands[2] = GEN_INT (INTVAL (operands[2]) % 32);
3879     }
3880   else /* TARGET_THUMB1 */
3881     {
3882       if (CONST_INT_P (operands [2]))
3883         operands [2] = force_reg (SImode, operands[2]);
3884     }
3885   "
3888 (define_insn "*arm_shiftsi3"
3889   [(set (match_operand:SI   0 "s_register_operand" "=l,l,r,r")
3890         (match_operator:SI  3 "shift_operator"
3891          [(match_operand:SI 1 "s_register_operand"  "0,l,r,r")
3892           (match_operand:SI 2 "reg_or_int_operand" "l,M,M,r")]))]
3893   "TARGET_32BIT"
3894   "* return arm_output_shift(operands, 0);"
3895   [(set_attr "predicable" "yes")
3896    (set_attr "arch" "t2,t2,*,*")
3897    (set_attr "predicable_short_it" "yes,yes,no,no")
3898    (set_attr "length" "4")
3899    (set_attr "shift" "1")
3900    (set_attr "type" "alu_shift_reg,alu_shift_imm,alu_shift_imm,alu_shift_reg")]
3903 (define_insn "*shiftsi3_compare0"
3904   [(set (reg:CC_NOOV CC_REGNUM)
3905         (compare:CC_NOOV (match_operator:SI 3 "shift_operator"
3906                           [(match_operand:SI 1 "s_register_operand" "r,r")
3907                            (match_operand:SI 2 "arm_rhs_operand" "M,r")])
3908                          (const_int 0)))
3909    (set (match_operand:SI 0 "s_register_operand" "=r,r")
3910         (match_op_dup 3 [(match_dup 1) (match_dup 2)]))]
3911   "TARGET_32BIT"
3912   "* return arm_output_shift(operands, 1);"
3913   [(set_attr "conds" "set")
3914    (set_attr "shift" "1")
3915    (set_attr "type" "alus_shift_imm,alus_shift_reg")]
3918 (define_insn "*shiftsi3_compare0_scratch"
3919   [(set (reg:CC_NOOV CC_REGNUM)
3920         (compare:CC_NOOV (match_operator:SI 3 "shift_operator"
3921                           [(match_operand:SI 1 "s_register_operand" "r,r")
3922                            (match_operand:SI 2 "arm_rhs_operand" "M,r")])
3923                          (const_int 0)))
3924    (clobber (match_scratch:SI 0 "=r,r"))]
3925   "TARGET_32BIT"
3926   "* return arm_output_shift(operands, 1);"
3927   [(set_attr "conds" "set")
3928    (set_attr "shift" "1")
3929    (set_attr "type" "shift_imm,shift_reg")]
3932 (define_insn "*not_shiftsi"
3933   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3934         (not:SI (match_operator:SI 3 "shift_operator"
3935                  [(match_operand:SI 1 "s_register_operand" "r,r")
3936                   (match_operand:SI 2 "shift_amount_operand" "M,rM")])))]
3937   "TARGET_32BIT"
3938   "mvn%?\\t%0, %1%S3"
3939   [(set_attr "predicable" "yes")
3940    (set_attr "predicable_short_it" "no")
3941    (set_attr "shift" "1")
3942    (set_attr "arch" "32,a")
3943    (set_attr "type" "mvn_shift,mvn_shift_reg")])
3945 (define_insn "*not_shiftsi_compare0"
3946   [(set (reg:CC_NOOV CC_REGNUM)
3947         (compare:CC_NOOV
3948          (not:SI (match_operator:SI 3 "shift_operator"
3949                   [(match_operand:SI 1 "s_register_operand" "r,r")
3950                    (match_operand:SI 2 "shift_amount_operand" "M,rM")]))
3951          (const_int 0)))
3952    (set (match_operand:SI 0 "s_register_operand" "=r,r")
3953         (not:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])))]
3954   "TARGET_32BIT"
3955   "mvn%.\\t%0, %1%S3"
3956   [(set_attr "conds" "set")
3957    (set_attr "shift" "1")
3958    (set_attr "arch" "32,a")
3959    (set_attr "type" "mvn_shift,mvn_shift_reg")])
3961 (define_insn "*not_shiftsi_compare0_scratch"
3962   [(set (reg:CC_NOOV CC_REGNUM)
3963         (compare:CC_NOOV
3964          (not:SI (match_operator:SI 3 "shift_operator"
3965                   [(match_operand:SI 1 "s_register_operand" "r,r")
3966                    (match_operand:SI 2 "shift_amount_operand" "M,rM")]))
3967          (const_int 0)))
3968    (clobber (match_scratch:SI 0 "=r,r"))]
3969   "TARGET_32BIT"
3970   "mvn%.\\t%0, %1%S3"
3971   [(set_attr "conds" "set")
3972    (set_attr "shift" "1")
3973    (set_attr "arch" "32,a")
3974    (set_attr "type" "mvn_shift,mvn_shift_reg")])
3976 ;; We don't really have extzv, but defining this using shifts helps
3977 ;; to reduce register pressure later on.
3979 (define_expand "extzv"
3980   [(set (match_operand 0 "s_register_operand" "")
3981         (zero_extract (match_operand 1 "nonimmediate_operand" "")
3982                       (match_operand 2 "const_int_operand" "")
3983                       (match_operand 3 "const_int_operand" "")))]
3984   "TARGET_THUMB1 || arm_arch_thumb2"
3985   "
3986   {
3987     HOST_WIDE_INT lshift = 32 - INTVAL (operands[2]) - INTVAL (operands[3]);
3988     HOST_WIDE_INT rshift = 32 - INTVAL (operands[2]);
3989     
3990     if (arm_arch_thumb2)
3991       {
3992         HOST_WIDE_INT width = INTVAL (operands[2]);
3993         HOST_WIDE_INT bitpos = INTVAL (operands[3]);
3995         if (unaligned_access && MEM_P (operands[1])
3996             && (width == 16 || width == 32) && (bitpos % BITS_PER_UNIT) == 0)
3997           {
3998             rtx base_addr;
4000             if (BYTES_BIG_ENDIAN)
4001               bitpos = GET_MODE_BITSIZE (GET_MODE (operands[0])) - width
4002                        - bitpos;
4004             if (width == 32)
4005               {
4006                 base_addr = adjust_address (operands[1], SImode,
4007                                             bitpos / BITS_PER_UNIT);
4008                 emit_insn (gen_unaligned_loadsi (operands[0], base_addr));
4009               }
4010             else
4011               {
4012                 rtx dest = operands[0];
4013                 rtx tmp = gen_reg_rtx (SImode);
4015                 /* We may get a paradoxical subreg here.  Strip it off.  */
4016                 if (GET_CODE (dest) == SUBREG
4017                     && GET_MODE (dest) == SImode
4018                     && GET_MODE (SUBREG_REG (dest)) == HImode)
4019                   dest = SUBREG_REG (dest);
4021                 if (GET_MODE_BITSIZE (GET_MODE (dest)) != width)
4022                   FAIL;
4024                 base_addr = adjust_address (operands[1], HImode,
4025                                             bitpos / BITS_PER_UNIT);
4026                 emit_insn (gen_unaligned_loadhiu (tmp, base_addr));
4027                 emit_move_insn (gen_lowpart (SImode, dest), tmp);
4028               }
4029             DONE;
4030           }
4031         else if (s_register_operand (operands[1], GET_MODE (operands[1])))
4032           {
4033             emit_insn (gen_extzv_t2 (operands[0], operands[1], operands[2],
4034                                      operands[3]));
4035             DONE;
4036           }
4037         else
4038           FAIL;
4039       }
4040     
4041     if (!s_register_operand (operands[1], GET_MODE (operands[1])))
4042       FAIL;
4044     operands[3] = GEN_INT (rshift);
4045     
4046     if (lshift == 0)
4047       {
4048         emit_insn (gen_lshrsi3 (operands[0], operands[1], operands[3]));
4049         DONE;
4050       }
4051       
4052     emit_insn (gen_extzv_t1 (operands[0], operands[1], GEN_INT (lshift),
4053                              operands[3], gen_reg_rtx (SImode)));
4054     DONE;
4055   }"
4058 ;; Helper for extzv, for the Thumb-1 register-shifts case.
4060 (define_expand "extzv_t1"
4061   [(set (match_operand:SI 4 "s_register_operand" "")
4062         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
4063                    (match_operand:SI 2 "const_int_operand" "")))
4064    (set (match_operand:SI 0 "s_register_operand" "")
4065         (lshiftrt:SI (match_dup 4)
4066                      (match_operand:SI 3 "const_int_operand" "")))]
4067   "TARGET_THUMB1"
4068   "")
4070 (define_expand "extv"
4071   [(set (match_operand 0 "s_register_operand" "")
4072         (sign_extract (match_operand 1 "nonimmediate_operand" "")
4073                       (match_operand 2 "const_int_operand" "")
4074                       (match_operand 3 "const_int_operand" "")))]
4075   "arm_arch_thumb2"
4077   HOST_WIDE_INT width = INTVAL (operands[2]);
4078   HOST_WIDE_INT bitpos = INTVAL (operands[3]);
4080   if (unaligned_access && MEM_P (operands[1]) && (width == 16 || width == 32)
4081       && (bitpos % BITS_PER_UNIT)  == 0)
4082     {
4083       rtx base_addr;
4084       
4085       if (BYTES_BIG_ENDIAN)
4086         bitpos = GET_MODE_BITSIZE (GET_MODE (operands[0])) - width - bitpos;
4087       
4088       if (width == 32)
4089         {
4090           base_addr = adjust_address (operands[1], SImode,
4091                                       bitpos / BITS_PER_UNIT);
4092           emit_insn (gen_unaligned_loadsi (operands[0], base_addr));
4093         }
4094       else
4095         {
4096           rtx dest = operands[0];
4097           rtx tmp = gen_reg_rtx (SImode);
4098           
4099           /* We may get a paradoxical subreg here.  Strip it off.  */
4100           if (GET_CODE (dest) == SUBREG
4101               && GET_MODE (dest) == SImode
4102               && GET_MODE (SUBREG_REG (dest)) == HImode)
4103             dest = SUBREG_REG (dest);
4104           
4105           if (GET_MODE_BITSIZE (GET_MODE (dest)) != width)
4106             FAIL;
4107           
4108           base_addr = adjust_address (operands[1], HImode,
4109                                       bitpos / BITS_PER_UNIT);
4110           emit_insn (gen_unaligned_loadhis (tmp, base_addr));
4111           emit_move_insn (gen_lowpart (SImode, dest), tmp);
4112         }
4114       DONE;
4115     }
4116   else if (!s_register_operand (operands[1], GET_MODE (operands[1])))
4117     FAIL;
4118   else if (GET_MODE (operands[0]) == SImode
4119            && GET_MODE (operands[1]) == SImode)
4120     {
4121       emit_insn (gen_extv_regsi (operands[0], operands[1], operands[2],
4122                                  operands[3]));
4123       DONE;
4124     }
4126   FAIL;
4129 ; Helper to expand register forms of extv with the proper modes.
4131 (define_expand "extv_regsi"
4132   [(set (match_operand:SI 0 "s_register_operand" "")
4133         (sign_extract:SI (match_operand:SI 1 "s_register_operand" "")
4134                          (match_operand 2 "const_int_operand" "")
4135                          (match_operand 3 "const_int_operand" "")))]
4136   ""
4140 ; ARMv6+ unaligned load/store instructions (used for packed structure accesses).
4142 (define_insn "unaligned_loadsi"
4143   [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4144         (unspec:SI [(match_operand:SI 1 "memory_operand" "Uw,m")]
4145                    UNSPEC_UNALIGNED_LOAD))]
4146   "unaligned_access && TARGET_32BIT"
4147   "ldr%?\t%0, %1\t@ unaligned"
4148   [(set_attr "arch" "t2,any")
4149    (set_attr "length" "2,4")
4150    (set_attr "predicable" "yes")
4151    (set_attr "predicable_short_it" "yes,no")
4152    (set_attr "type" "load1")])
4154 (define_insn "unaligned_loadhis"
4155   [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4156         (sign_extend:SI
4157           (unspec:HI [(match_operand:HI 1 "memory_operand" "Uw,Uh")]
4158                      UNSPEC_UNALIGNED_LOAD)))]
4159   "unaligned_access && TARGET_32BIT"
4160   "ldr%(sh%)\t%0, %1\t@ unaligned"
4161   [(set_attr "arch" "t2,any")
4162    (set_attr "length" "2,4")
4163    (set_attr "predicable" "yes")
4164    (set_attr "predicable_short_it" "yes,no")
4165    (set_attr "type" "load_byte")])
4167 (define_insn "unaligned_loadhiu"
4168   [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4169         (zero_extend:SI
4170           (unspec:HI [(match_operand:HI 1 "memory_operand" "Uw,m")]
4171                      UNSPEC_UNALIGNED_LOAD)))]
4172   "unaligned_access && TARGET_32BIT"
4173   "ldr%(h%)\t%0, %1\t@ unaligned"
4174   [(set_attr "arch" "t2,any")
4175    (set_attr "length" "2,4")
4176    (set_attr "predicable" "yes")
4177    (set_attr "predicable_short_it" "yes,no")
4178    (set_attr "type" "load_byte")])
4180 (define_insn "unaligned_storesi"
4181   [(set (match_operand:SI 0 "memory_operand" "=Uw,m")
4182         (unspec:SI [(match_operand:SI 1 "s_register_operand" "l,r")]
4183                    UNSPEC_UNALIGNED_STORE))]
4184   "unaligned_access && TARGET_32BIT"
4185   "str%?\t%1, %0\t@ unaligned"
4186   [(set_attr "arch" "t2,any")
4187    (set_attr "length" "2,4")
4188    (set_attr "predicable" "yes")
4189    (set_attr "predicable_short_it" "yes,no")
4190    (set_attr "type" "store1")])
4192 (define_insn "unaligned_storehi"
4193   [(set (match_operand:HI 0 "memory_operand" "=Uw,m")
4194         (unspec:HI [(match_operand:HI 1 "s_register_operand" "l,r")]
4195                    UNSPEC_UNALIGNED_STORE))]
4196   "unaligned_access && TARGET_32BIT"
4197   "str%(h%)\t%1, %0\t@ unaligned"
4198   [(set_attr "arch" "t2,any")
4199    (set_attr "length" "2,4")
4200    (set_attr "predicable" "yes")
4201    (set_attr "predicable_short_it" "yes,no")
4202    (set_attr "type" "store1")])
4204 ;; Unaligned double-word load and store.
4205 ;; Split after reload into two unaligned single-word accesses.
4206 ;; It prevents lower_subreg from splitting some other aligned
4207 ;; double-word accesses too early. Used for internal memcpy.
4209 (define_insn_and_split "unaligned_loaddi"
4210   [(set (match_operand:DI 0 "s_register_operand" "=l,r")
4211         (unspec:DI [(match_operand:DI 1 "memory_operand" "o,o")]
4212                    UNSPEC_UNALIGNED_LOAD))]
4213   "unaligned_access && TARGET_32BIT"
4214   "#"
4215   "&& reload_completed"
4216   [(set (match_dup 0) (unspec:SI [(match_dup 1)] UNSPEC_UNALIGNED_LOAD))
4217    (set (match_dup 2) (unspec:SI [(match_dup 3)] UNSPEC_UNALIGNED_LOAD))]
4218   {
4219     operands[2] = gen_highpart (SImode, operands[0]);
4220     operands[0] = gen_lowpart (SImode, operands[0]);
4221     operands[3] = gen_highpart (SImode, operands[1]);
4222     operands[1] = gen_lowpart (SImode, operands[1]);
4224     /* If the first destination register overlaps with the base address,
4225        swap the order in which the loads are emitted.  */
4226     if (reg_overlap_mentioned_p (operands[0], operands[1]))
4227       {
4228         std::swap (operands[1], operands[3]);
4229         std::swap (operands[0], operands[2]);
4230       }
4231   }
4232   [(set_attr "arch" "t2,any")
4233    (set_attr "length" "4,8")
4234    (set_attr "predicable" "yes")
4235    (set_attr "type" "load2")])
4237 (define_insn_and_split "unaligned_storedi"
4238   [(set (match_operand:DI 0 "memory_operand" "=o,o")
4239         (unspec:DI [(match_operand:DI 1 "s_register_operand" "l,r")]
4240                    UNSPEC_UNALIGNED_STORE))]
4241   "unaligned_access && TARGET_32BIT"
4242   "#"
4243   "&& reload_completed"
4244   [(set (match_dup 0) (unspec:SI [(match_dup 1)] UNSPEC_UNALIGNED_STORE))
4245    (set (match_dup 2) (unspec:SI [(match_dup 3)] UNSPEC_UNALIGNED_STORE))]
4246   {
4247     operands[2] = gen_highpart (SImode, operands[0]);
4248     operands[0] = gen_lowpart (SImode, operands[0]);
4249     operands[3] = gen_highpart (SImode, operands[1]);
4250     operands[1] = gen_lowpart (SImode, operands[1]);
4251   }
4252   [(set_attr "arch" "t2,any")
4253    (set_attr "length" "4,8")
4254    (set_attr "predicable" "yes")
4255    (set_attr "type" "store2")])
4258 (define_insn "*extv_reg"
4259   [(set (match_operand:SI 0 "s_register_operand" "=r")
4260         (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
4261                          (match_operand:SI 2 "const_int_M_operand" "M")
4262                          (match_operand:SI 3 "const_int_M_operand" "M")))]
4263   "arm_arch_thumb2"
4264   "sbfx%?\t%0, %1, %3, %2"
4265   [(set_attr "length" "4")
4266    (set_attr "predicable" "yes")
4267    (set_attr "predicable_short_it" "no")
4268    (set_attr "type" "bfm")]
4271 (define_insn "extzv_t2"
4272   [(set (match_operand:SI 0 "s_register_operand" "=r")
4273         (zero_extract:SI (match_operand:SI 1 "s_register_operand" "r")
4274                          (match_operand:SI 2 "const_int_M_operand" "M")
4275                          (match_operand:SI 3 "const_int_M_operand" "M")))]
4276   "arm_arch_thumb2"
4277   "ubfx%?\t%0, %1, %3, %2"
4278   [(set_attr "length" "4")
4279    (set_attr "predicable" "yes")
4280    (set_attr "predicable_short_it" "no")
4281    (set_attr "type" "bfm")]
4285 ;; Division instructions
4286 (define_insn "divsi3"
4287   [(set (match_operand:SI         0 "s_register_operand" "=r")
4288         (div:SI (match_operand:SI 1 "s_register_operand"  "r")
4289                 (match_operand:SI 2 "s_register_operand"  "r")))]
4290   "TARGET_IDIV"
4291   "sdiv%?\t%0, %1, %2"
4292   [(set_attr "predicable" "yes")
4293    (set_attr "predicable_short_it" "no")
4294    (set_attr "type" "sdiv")]
4297 (define_insn "udivsi3"
4298   [(set (match_operand:SI          0 "s_register_operand" "=r")
4299         (udiv:SI (match_operand:SI 1 "s_register_operand"  "r")
4300                  (match_operand:SI 2 "s_register_operand"  "r")))]
4301   "TARGET_IDIV"
4302   "udiv%?\t%0, %1, %2"
4303   [(set_attr "predicable" "yes")
4304    (set_attr "predicable_short_it" "no")
4305    (set_attr "type" "udiv")]
4309 ;; Unary arithmetic insns
4311 (define_expand "negdi2"
4312  [(parallel
4313    [(set (match_operand:DI 0 "s_register_operand" "")
4314          (neg:DI (match_operand:DI 1 "s_register_operand" "")))
4315     (clobber (reg:CC CC_REGNUM))])]
4316   "TARGET_EITHER"
4317   {
4318     if (TARGET_NEON)
4319       {
4320         emit_insn (gen_negdi2_neon (operands[0], operands[1]));
4321         DONE;
4322       }
4323   }
4326 ;; The constraints here are to prevent a *partial* overlap (where %Q0 == %R1).
4327 ;; The first alternative allows the common case of a *full* overlap.
4328 (define_insn_and_split "*arm_negdi2"
4329   [(set (match_operand:DI         0 "s_register_operand" "=r,&r")
4330         (neg:DI (match_operand:DI 1 "s_register_operand"  "0,r")))
4331    (clobber (reg:CC CC_REGNUM))]
4332   "TARGET_ARM"
4333   "#"   ; "rsbs\\t%Q0, %Q1, #0\;rsc\\t%R0, %R1, #0"
4334   "&& reload_completed"
4335   [(parallel [(set (reg:CC CC_REGNUM)
4336                    (compare:CC (const_int 0) (match_dup 1)))
4337               (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1)))])
4338    (set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3))
4339                                 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
4340   {
4341     operands[2] = gen_highpart (SImode, operands[0]);
4342     operands[0] = gen_lowpart (SImode, operands[0]);
4343     operands[3] = gen_highpart (SImode, operands[1]);
4344     operands[1] = gen_lowpart (SImode, operands[1]);
4345   }
4346   [(set_attr "conds" "clob")
4347    (set_attr "length" "8")
4348    (set_attr "type" "multiple")]
4351 (define_expand "negsi2"
4352   [(set (match_operand:SI         0 "s_register_operand" "")
4353         (neg:SI (match_operand:SI 1 "s_register_operand" "")))]
4354   "TARGET_EITHER"
4355   ""
4358 (define_insn "*arm_negsi2"
4359   [(set (match_operand:SI         0 "s_register_operand" "=l,r")
4360         (neg:SI (match_operand:SI 1 "s_register_operand" "l,r")))]
4361   "TARGET_32BIT"
4362   "rsb%?\\t%0, %1, #0"
4363   [(set_attr "predicable" "yes")
4364    (set_attr "predicable_short_it" "yes,no")
4365    (set_attr "arch" "t2,*")
4366    (set_attr "length" "4")
4367    (set_attr "type" "alu_sreg")]
4370 (define_expand "negsf2"
4371   [(set (match_operand:SF         0 "s_register_operand" "")
4372         (neg:SF (match_operand:SF 1 "s_register_operand" "")))]
4373   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
4374   ""
4377 (define_expand "negdf2"
4378   [(set (match_operand:DF         0 "s_register_operand" "")
4379         (neg:DF (match_operand:DF 1 "s_register_operand" "")))]
4380   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
4381   "")
4383 (define_insn_and_split "*zextendsidi_negsi"
4384   [(set (match_operand:DI 0 "s_register_operand" "=r")
4385         (zero_extend:DI (neg:SI (match_operand:SI 1 "s_register_operand" "r"))))]
4386    "TARGET_32BIT"
4387    "#"
4388    ""
4389    [(set (match_dup 2)
4390          (neg:SI (match_dup 1)))
4391     (set (match_dup 3)
4392          (const_int 0))]
4393    {
4394       operands[2] = gen_lowpart (SImode, operands[0]);
4395       operands[3] = gen_highpart (SImode, operands[0]);
4396    }
4397  [(set_attr "length" "8")
4398   (set_attr "type" "multiple")]
4401 ;; Negate an extended 32-bit value.
4402 (define_insn_and_split "*negdi_extendsidi"
4403   [(set (match_operand:DI 0 "s_register_operand" "=l,r")
4404         (neg:DI (sign_extend:DI
4405                  (match_operand:SI 1 "s_register_operand" "l,r"))))
4406    (clobber (reg:CC CC_REGNUM))]
4407   "TARGET_32BIT"
4408   "#"
4409   "&& reload_completed"
4410   [(const_int 0)]
4411   {
4412     rtx low = gen_lowpart (SImode, operands[0]);
4413     rtx high = gen_highpart (SImode, operands[0]);
4415     if (reg_overlap_mentioned_p (low, operands[1]))
4416       {
4417         /* Input overlaps the low word of the output.  Use:
4418                 asr     Rhi, Rin, #31
4419                 rsbs    Rlo, Rin, #0
4420                 rsc     Rhi, Rhi, #0 (thumb2: sbc Rhi, Rhi, Rhi, lsl #1).  */
4421         rtx cc_reg = gen_rtx_REG (CC_Cmode, CC_REGNUM);
4423         emit_insn (gen_rtx_SET (high,
4424                                 gen_rtx_ASHIFTRT (SImode, operands[1],
4425                                                   GEN_INT (31))));
4427         emit_insn (gen_subsi3_compare (low, const0_rtx, operands[1]));
4428         if (TARGET_ARM)
4429           emit_insn (gen_rtx_SET (high,
4430                                   gen_rtx_MINUS (SImode,
4431                                                  gen_rtx_MINUS (SImode,
4432                                                                 const0_rtx,
4433                                                                 high),
4434                                                  gen_rtx_LTU (SImode,
4435                                                               cc_reg,
4436                                                               const0_rtx))));
4437         else
4438           {
4439             rtx two_x = gen_rtx_ASHIFT (SImode, high, GEN_INT (1));
4440             emit_insn (gen_rtx_SET (high,
4441                                     gen_rtx_MINUS (SImode,
4442                                                    gen_rtx_MINUS (SImode,
4443                                                                   high,
4444                                                                   two_x),
4445                                                    gen_rtx_LTU (SImode,
4446                                                                 cc_reg,
4447                                                                 const0_rtx))));
4448           }
4449       }
4450     else
4451       {
4452         /* No overlap, or overlap on high word.  Use:
4453                 rsb     Rlo, Rin, #0
4454                 bic     Rhi, Rlo, Rin
4455                 asr     Rhi, Rhi, #31
4456            Flags not needed for this sequence.  */
4457         emit_insn (gen_rtx_SET (low, gen_rtx_NEG (SImode, operands[1])));
4458         emit_insn (gen_rtx_SET (high,
4459                                 gen_rtx_AND (SImode,
4460                                              gen_rtx_NOT (SImode, operands[1]),
4461                                              low)));
4462         emit_insn (gen_rtx_SET (high,
4463                                 gen_rtx_ASHIFTRT (SImode, high,
4464                                                   GEN_INT (31))));
4465       }
4466     DONE;
4467   }
4468   [(set_attr "length" "12")
4469    (set_attr "arch" "t2,*")
4470    (set_attr "type" "multiple")]
4473 (define_insn_and_split "*negdi_zero_extendsidi"
4474   [(set (match_operand:DI 0 "s_register_operand" "=r,&r")
4475         (neg:DI (zero_extend:DI (match_operand:SI 1 "s_register_operand" "0,r"))))
4476    (clobber (reg:CC CC_REGNUM))]
4477   "TARGET_32BIT"
4478   "#" ; "rsbs\\t%Q0, %1, #0\;sbc\\t%R0,%R0,%R0"
4479       ;; Don't care what register is input to sbc,
4480       ;; since we just just need to propagate the carry.
4481   "&& reload_completed"
4482   [(parallel [(set (reg:CC CC_REGNUM)
4483                    (compare:CC (const_int 0) (match_dup 1)))
4484               (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1)))])
4485    (set (match_dup 2) (minus:SI (minus:SI (match_dup 2) (match_dup 2))
4486                                 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
4487   {
4488     operands[2] = gen_highpart (SImode, operands[0]);
4489     operands[0] = gen_lowpart (SImode, operands[0]);
4490   }
4491   [(set_attr "conds" "clob")
4492    (set_attr "length" "8")
4493    (set_attr "type" "multiple")]   ;; length in thumb is 4
4496 ;; abssi2 doesn't really clobber the condition codes if a different register
4497 ;; is being set.  To keep things simple, assume during rtl manipulations that
4498 ;; it does, but tell the final scan operator the truth.  Similarly for
4499 ;; (neg (abs...))
4501 (define_expand "abssi2"
4502   [(parallel
4503     [(set (match_operand:SI         0 "s_register_operand" "")
4504           (abs:SI (match_operand:SI 1 "s_register_operand" "")))
4505      (clobber (match_dup 2))])]
4506   "TARGET_EITHER"
4507   "
4508   if (TARGET_THUMB1)
4509     operands[2] = gen_rtx_SCRATCH (SImode);
4510   else
4511     operands[2] = gen_rtx_REG (CCmode, CC_REGNUM);
4514 (define_insn_and_split "*arm_abssi2"
4515   [(set (match_operand:SI 0 "s_register_operand" "=r,&r")
4516         (abs:SI (match_operand:SI 1 "s_register_operand" "0,r")))
4517    (clobber (reg:CC CC_REGNUM))]
4518   "TARGET_ARM"
4519   "#"
4520   "&& reload_completed"
4521   [(const_int 0)]
4522   {
4523    /* if (which_alternative == 0) */
4524    if (REGNO(operands[0]) == REGNO(operands[1]))
4525      {
4526       /* Emit the pattern:
4527          cmp\\t%0, #0\;rsblt\\t%0, %0, #0
4528          [(set (reg:CC CC_REGNUM)
4529                (compare:CC (match_dup 0) (const_int 0)))
4530           (cond_exec (lt:CC (reg:CC CC_REGNUM) (const_int 0))
4531                      (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1))))]
4532       */
4533       emit_insn (gen_rtx_SET (gen_rtx_REG (CCmode, CC_REGNUM),
4534                               gen_rtx_COMPARE (CCmode, operands[0], const0_rtx)));
4535       emit_insn (gen_rtx_COND_EXEC (VOIDmode,
4536                                     (gen_rtx_LT (SImode,
4537                                                  gen_rtx_REG (CCmode, CC_REGNUM),
4538                                                  const0_rtx)),
4539                                     (gen_rtx_SET (operands[0],
4540                                                   (gen_rtx_MINUS (SImode,
4541                                                                   const0_rtx,
4542                                                                   operands[1]))))));
4543       DONE;
4544      }
4545    else
4546      {
4547       /* Emit the pattern:
4548          alt1: eor%?\\t%0, %1, %1, asr #31\;sub%?\\t%0, %0, %1, asr #31
4549          [(set (match_dup 0)
4550                (xor:SI (match_dup 1)
4551                        (ashiftrt:SI (match_dup 1) (const_int 31))))
4552           (set (match_dup 0)
4553                (minus:SI (match_dup 0)
4554                       (ashiftrt:SI (match_dup 1) (const_int 31))))]
4555       */
4556       emit_insn (gen_rtx_SET (operands[0],
4557                               gen_rtx_XOR (SImode,
4558                                            gen_rtx_ASHIFTRT (SImode,
4559                                                              operands[1],
4560                                                              GEN_INT (31)),
4561                                            operands[1])));
4562       emit_insn (gen_rtx_SET (operands[0],
4563                               gen_rtx_MINUS (SImode,
4564                                              operands[0],
4565                                              gen_rtx_ASHIFTRT (SImode,
4566                                                                operands[1],
4567                                                                GEN_INT (31)))));
4568       DONE;
4569      }
4570   }
4571   [(set_attr "conds" "clob,*")
4572    (set_attr "shift" "1")
4573    (set_attr "predicable" "no, yes")
4574    (set_attr "length" "8")
4575    (set_attr "type" "multiple")]
4578 (define_insn_and_split "*arm_neg_abssi2"
4579   [(set (match_operand:SI 0 "s_register_operand" "=r,&r")
4580         (neg:SI (abs:SI (match_operand:SI 1 "s_register_operand" "0,r"))))
4581    (clobber (reg:CC CC_REGNUM))]
4582   "TARGET_ARM"
4583   "#"
4584   "&& reload_completed"
4585   [(const_int 0)]
4586   {
4587    /* if (which_alternative == 0) */
4588    if (REGNO (operands[0]) == REGNO (operands[1]))
4589      {
4590       /* Emit the pattern:
4591          cmp\\t%0, #0\;rsbgt\\t%0, %0, #0
4592       */
4593       emit_insn (gen_rtx_SET (gen_rtx_REG (CCmode, CC_REGNUM),
4594                               gen_rtx_COMPARE (CCmode, operands[0], const0_rtx)));
4595       emit_insn (gen_rtx_COND_EXEC (VOIDmode,
4596                                     gen_rtx_GT (SImode,
4597                                                 gen_rtx_REG (CCmode, CC_REGNUM),
4598                                                 const0_rtx),
4599                                     gen_rtx_SET (operands[0],
4600                                                  (gen_rtx_MINUS (SImode,
4601                                                                  const0_rtx,
4602                                                                  operands[1])))));
4603      }
4604    else
4605      {
4606       /* Emit the pattern:
4607          eor%?\\t%0, %1, %1, asr #31\;rsb%?\\t%0, %0, %1, asr #31
4608       */
4609       emit_insn (gen_rtx_SET (operands[0],
4610                               gen_rtx_XOR (SImode,
4611                                            gen_rtx_ASHIFTRT (SImode,
4612                                                              operands[1],
4613                                                              GEN_INT (31)),
4614                                            operands[1])));
4615       emit_insn (gen_rtx_SET (operands[0],
4616                               gen_rtx_MINUS (SImode,
4617                                              gen_rtx_ASHIFTRT (SImode,
4618                                                                operands[1],
4619                                                                GEN_INT (31)),
4620                                              operands[0])));
4621      }
4622    DONE;
4623   }
4624   [(set_attr "conds" "clob,*")
4625    (set_attr "shift" "1")
4626    (set_attr "predicable" "no, yes")
4627    (set_attr "length" "8")
4628    (set_attr "type" "multiple")]
4631 (define_expand "abssf2"
4632   [(set (match_operand:SF         0 "s_register_operand" "")
4633         (abs:SF (match_operand:SF 1 "s_register_operand" "")))]
4634   "TARGET_32BIT && TARGET_HARD_FLOAT"
4635   "")
4637 (define_expand "absdf2"
4638   [(set (match_operand:DF         0 "s_register_operand" "")
4639         (abs:DF (match_operand:DF 1 "s_register_operand" "")))]
4640   "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
4641   "")
4643 (define_expand "sqrtsf2"
4644   [(set (match_operand:SF 0 "s_register_operand" "")
4645         (sqrt:SF (match_operand:SF 1 "s_register_operand" "")))]
4646   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
4647   "")
4649 (define_expand "sqrtdf2"
4650   [(set (match_operand:DF 0 "s_register_operand" "")
4651         (sqrt:DF (match_operand:DF 1 "s_register_operand" "")))]
4652   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
4653   "")
4655 (define_insn_and_split "one_cmpldi2"
4656   [(set (match_operand:DI 0 "s_register_operand"         "=w,&r,&r,?w")
4657         (not:DI (match_operand:DI 1 "s_register_operand" " w, 0, r, w")))]
4658   "TARGET_32BIT"
4659   "@
4660    vmvn\t%P0, %P1
4661    #
4662    #
4663    vmvn\t%P0, %P1"
4664   "TARGET_32BIT && reload_completed
4665    && arm_general_register_operand (operands[0], DImode)"
4666   [(set (match_dup 0) (not:SI (match_dup 1)))
4667    (set (match_dup 2) (not:SI (match_dup 3)))]
4668   "
4669   {
4670     operands[2] = gen_highpart (SImode, operands[0]);
4671     operands[0] = gen_lowpart (SImode, operands[0]);
4672     operands[3] = gen_highpart (SImode, operands[1]);
4673     operands[1] = gen_lowpart (SImode, operands[1]);
4674   }"
4675   [(set_attr "length" "*,8,8,*")
4676    (set_attr "predicable" "no,yes,yes,no")
4677    (set_attr "type" "neon_move,multiple,multiple,neon_move")
4678    (set_attr "arch" "neon_for_64bits,*,*,avoid_neon_for_64bits")]
4681 (define_expand "one_cmplsi2"
4682   [(set (match_operand:SI         0 "s_register_operand" "")
4683         (not:SI (match_operand:SI 1 "s_register_operand" "")))]
4684   "TARGET_EITHER"
4685   ""
4688 (define_insn "*arm_one_cmplsi2"
4689   [(set (match_operand:SI         0 "s_register_operand" "=l,r")
4690         (not:SI (match_operand:SI 1 "s_register_operand"  "l,r")))]
4691   "TARGET_32BIT"
4692   "mvn%?\\t%0, %1"
4693   [(set_attr "predicable" "yes")
4694    (set_attr "predicable_short_it" "yes,no")
4695    (set_attr "arch" "t2,*")
4696    (set_attr "length" "4")
4697    (set_attr "type" "mvn_reg")]
4700 (define_insn "*notsi_compare0"
4701   [(set (reg:CC_NOOV CC_REGNUM)
4702         (compare:CC_NOOV (not:SI (match_operand:SI 1 "s_register_operand" "r"))
4703                          (const_int 0)))
4704    (set (match_operand:SI 0 "s_register_operand" "=r")
4705         (not:SI (match_dup 1)))]
4706   "TARGET_32BIT"
4707   "mvn%.\\t%0, %1"
4708   [(set_attr "conds" "set")
4709    (set_attr "type" "mvn_reg")]
4712 (define_insn "*notsi_compare0_scratch"
4713   [(set (reg:CC_NOOV CC_REGNUM)
4714         (compare:CC_NOOV (not:SI (match_operand:SI 1 "s_register_operand" "r"))
4715                          (const_int 0)))
4716    (clobber (match_scratch:SI 0 "=r"))]
4717   "TARGET_32BIT"
4718   "mvn%.\\t%0, %1"
4719   [(set_attr "conds" "set")
4720    (set_attr "type" "mvn_reg")]
4723 ;; Fixed <--> Floating conversion insns
4725 (define_expand "floatsihf2"
4726   [(set (match_operand:HF           0 "general_operand" "")
4727         (float:HF (match_operand:SI 1 "general_operand" "")))]
4728   "TARGET_EITHER"
4729   "
4730   {
4731     rtx op1 = gen_reg_rtx (SFmode);
4732     expand_float (op1, operands[1], 0);
4733     op1 = convert_to_mode (HFmode, op1, 0);
4734     emit_move_insn (operands[0], op1);
4735     DONE;
4736   }"
4739 (define_expand "floatdihf2"
4740   [(set (match_operand:HF           0 "general_operand" "")
4741         (float:HF (match_operand:DI 1 "general_operand" "")))]
4742   "TARGET_EITHER"
4743   "
4744   {
4745     rtx op1 = gen_reg_rtx (SFmode);
4746     expand_float (op1, operands[1], 0);
4747     op1 = convert_to_mode (HFmode, op1, 0);
4748     emit_move_insn (operands[0], op1);
4749     DONE;
4750   }"
4753 (define_expand "floatsisf2"
4754   [(set (match_operand:SF           0 "s_register_operand" "")
4755         (float:SF (match_operand:SI 1 "s_register_operand" "")))]
4756   "TARGET_32BIT && TARGET_HARD_FLOAT"
4757   "
4760 (define_expand "floatsidf2"
4761   [(set (match_operand:DF           0 "s_register_operand" "")
4762         (float:DF (match_operand:SI 1 "s_register_operand" "")))]
4763   "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
4764   "
4767 (define_expand "fix_trunchfsi2"
4768   [(set (match_operand:SI         0 "general_operand" "")
4769         (fix:SI (fix:HF (match_operand:HF 1 "general_operand"  ""))))]
4770   "TARGET_EITHER"
4771   "
4772   {
4773     rtx op1 = convert_to_mode (SFmode, operands[1], 0);
4774     expand_fix (operands[0], op1, 0);
4775     DONE;
4776   }"
4779 (define_expand "fix_trunchfdi2"
4780   [(set (match_operand:DI         0 "general_operand" "")
4781         (fix:DI (fix:HF (match_operand:HF 1 "general_operand"  ""))))]
4782   "TARGET_EITHER"
4783   "
4784   {
4785     rtx op1 = convert_to_mode (SFmode, operands[1], 0);
4786     expand_fix (operands[0], op1, 0);
4787     DONE;
4788   }"
4791 (define_expand "fix_truncsfsi2"
4792   [(set (match_operand:SI         0 "s_register_operand" "")
4793         (fix:SI (fix:SF (match_operand:SF 1 "s_register_operand"  ""))))]
4794   "TARGET_32BIT && TARGET_HARD_FLOAT"
4795   "
4798 (define_expand "fix_truncdfsi2"
4799   [(set (match_operand:SI         0 "s_register_operand" "")
4800         (fix:SI (fix:DF (match_operand:DF 1 "s_register_operand"  ""))))]
4801   "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
4802   "
4805 ;; Truncation insns
4807 (define_expand "truncdfsf2"
4808   [(set (match_operand:SF  0 "s_register_operand" "")
4809         (float_truncate:SF
4810          (match_operand:DF 1 "s_register_operand" "")))]
4811   "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
4812   ""
4815 /* DFmode -> HFmode conversions have to go through SFmode.  */
4816 (define_expand "truncdfhf2"
4817   [(set (match_operand:HF  0 "general_operand" "")
4818         (float_truncate:HF
4819          (match_operand:DF 1 "general_operand" "")))]
4820   "TARGET_EITHER"
4821   "
4822   {
4823     rtx op1;
4824     op1 = convert_to_mode (SFmode, operands[1], 0);
4825     op1 = convert_to_mode (HFmode, op1, 0);
4826     emit_move_insn (operands[0], op1);
4827     DONE;
4828   }"
4831 ;; Zero and sign extension instructions.
4833 (define_insn "zero_extend<mode>di2"
4834   [(set (match_operand:DI 0 "s_register_operand" "=w,r,?r,w")
4835         (zero_extend:DI (match_operand:QHSI 1 "<qhs_zextenddi_op>"
4836                                             "<qhs_zextenddi_cstr>")))]
4837   "TARGET_32BIT <qhs_zextenddi_cond>"
4838   "#"
4839   [(set_attr "length" "8,4,8,8")
4840    (set_attr "arch" "neon_for_64bits,*,*,avoid_neon_for_64bits")
4841    (set_attr "ce_count" "2")
4842    (set_attr "predicable" "yes")
4843    (set_attr "type" "multiple,mov_reg,multiple,multiple")]
4846 (define_insn "extend<mode>di2"
4847   [(set (match_operand:DI 0 "s_register_operand" "=w,r,?r,?r,w")
4848         (sign_extend:DI (match_operand:QHSI 1 "<qhs_extenddi_op>"
4849                                             "<qhs_extenddi_cstr>")))]
4850   "TARGET_32BIT <qhs_sextenddi_cond>"
4851   "#"
4852   [(set_attr "length" "8,4,8,8,8")
4853    (set_attr "ce_count" "2")
4854    (set_attr "shift" "1")
4855    (set_attr "predicable" "yes")
4856    (set_attr "arch" "neon_for_64bits,*,a,t,avoid_neon_for_64bits")
4857    (set_attr "type" "multiple,mov_reg,multiple,multiple,multiple")]
4860 ;; Splits for all extensions to DImode
4861 (define_split
4862   [(set (match_operand:DI 0 "s_register_operand" "")
4863         (zero_extend:DI (match_operand 1 "nonimmediate_operand" "")))]
4864   "TARGET_32BIT && reload_completed && !IS_VFP_REGNUM (REGNO (operands[0]))"
4865   [(set (match_dup 0) (match_dup 1))]
4867   rtx lo_part = gen_lowpart (SImode, operands[0]);
4868   machine_mode src_mode = GET_MODE (operands[1]);
4870   if (REG_P (operands[0])
4871       && !reg_overlap_mentioned_p (operands[0], operands[1]))
4872     emit_clobber (operands[0]);
4873   if (!REG_P (lo_part) || src_mode != SImode
4874       || !rtx_equal_p (lo_part, operands[1]))
4875     {
4876       if (src_mode == SImode)
4877         emit_move_insn (lo_part, operands[1]);
4878       else
4879         emit_insn (gen_rtx_SET (lo_part,
4880                                 gen_rtx_ZERO_EXTEND (SImode, operands[1])));
4881       operands[1] = lo_part;
4882     }
4883   operands[0] = gen_highpart (SImode, operands[0]);
4884   operands[1] = const0_rtx;
4887 (define_split
4888   [(set (match_operand:DI 0 "s_register_operand" "")
4889         (sign_extend:DI (match_operand 1 "nonimmediate_operand" "")))]
4890   "TARGET_32BIT && reload_completed && !IS_VFP_REGNUM (REGNO (operands[0]))"
4891   [(set (match_dup 0) (ashiftrt:SI (match_dup 1) (const_int 31)))]
4893   rtx lo_part = gen_lowpart (SImode, operands[0]);
4894   machine_mode src_mode = GET_MODE (operands[1]);
4896   if (REG_P (operands[0])
4897       && !reg_overlap_mentioned_p (operands[0], operands[1]))
4898     emit_clobber (operands[0]);
4900   if (!REG_P (lo_part) || src_mode != SImode
4901       || !rtx_equal_p (lo_part, operands[1]))
4902     {
4903       if (src_mode == SImode)
4904         emit_move_insn (lo_part, operands[1]);
4905       else
4906         emit_insn (gen_rtx_SET (lo_part,
4907                                 gen_rtx_SIGN_EXTEND (SImode, operands[1])));
4908       operands[1] = lo_part;
4909     }
4910   operands[0] = gen_highpart (SImode, operands[0]);
4913 (define_expand "zero_extendhisi2"
4914   [(set (match_operand:SI 0 "s_register_operand" "")
4915         (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
4916   "TARGET_EITHER"
4918   if (TARGET_ARM && !arm_arch4 && MEM_P (operands[1]))
4919     {
4920       emit_insn (gen_movhi_bytes (operands[0], operands[1]));
4921       DONE;
4922     }
4923   if (!arm_arch6 && !MEM_P (operands[1]))
4924     {
4925       rtx t = gen_lowpart (SImode, operands[1]);
4926       rtx tmp = gen_reg_rtx (SImode);
4927       emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (16)));
4928       emit_insn (gen_lshrsi3 (operands[0], tmp, GEN_INT (16)));
4929       DONE;
4930     }
4933 (define_split
4934   [(set (match_operand:SI 0 "s_register_operand" "")
4935         (zero_extend:SI (match_operand:HI 1 "s_register_operand" "")))]
4936   "!TARGET_THUMB2 && !arm_arch6"
4937   [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
4938    (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 16)))]
4940   operands[2] = gen_lowpart (SImode, operands[1]);
4943 (define_insn "*arm_zero_extendhisi2"
4944   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4945         (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
4946   "TARGET_ARM && arm_arch4 && !arm_arch6"
4947   "@
4948    #
4949    ldr%(h%)\\t%0, %1"
4950   [(set_attr "type" "alu_shift_reg,load_byte")
4951    (set_attr "predicable" "yes")]
4954 (define_insn "*arm_zero_extendhisi2_v6"
4955   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4956         (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,Uh")))]
4957   "TARGET_ARM && arm_arch6"
4958   "@
4959    uxth%?\\t%0, %1
4960    ldr%(h%)\\t%0, %1"
4961   [(set_attr "predicable" "yes")
4962    (set_attr "type" "extend,load_byte")]
4965 (define_insn "*arm_zero_extendhisi2addsi"
4966   [(set (match_operand:SI 0 "s_register_operand" "=r")
4967         (plus:SI (zero_extend:SI (match_operand:HI 1 "s_register_operand" "r"))
4968                  (match_operand:SI 2 "s_register_operand" "r")))]
4969   "TARGET_INT_SIMD"
4970   "uxtah%?\\t%0, %2, %1"
4971   [(set_attr "type" "alu_shift_reg")
4972    (set_attr "predicable" "yes")
4973    (set_attr "predicable_short_it" "no")]
4976 (define_expand "zero_extendqisi2"
4977   [(set (match_operand:SI 0 "s_register_operand" "")
4978         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))]
4979   "TARGET_EITHER"
4981   if (TARGET_ARM && !arm_arch6 && !MEM_P (operands[1]))
4982     {
4983       emit_insn (gen_andsi3 (operands[0],
4984                              gen_lowpart (SImode, operands[1]),
4985                                           GEN_INT (255)));
4986       DONE;
4987     }
4988   if (!arm_arch6 && !MEM_P (operands[1]))
4989     {
4990       rtx t = gen_lowpart (SImode, operands[1]);
4991       rtx tmp = gen_reg_rtx (SImode);
4992       emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (24)));
4993       emit_insn (gen_lshrsi3 (operands[0], tmp, GEN_INT (24)));
4994       DONE;
4995     }
4998 (define_split
4999   [(set (match_operand:SI 0 "s_register_operand" "")
5000         (zero_extend:SI (match_operand:QI 1 "s_register_operand" "")))]
5001   "!arm_arch6"
5002   [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 24)))
5003    (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 24)))]
5005   operands[2] = simplify_gen_subreg (SImode, operands[1], QImode, 0);
5006   if (TARGET_ARM)
5007     {
5008       emit_insn (gen_andsi3 (operands[0], operands[2], GEN_INT (255)));
5009       DONE;
5010     }
5013 (define_insn "*arm_zero_extendqisi2"
5014   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5015         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
5016   "TARGET_ARM && !arm_arch6"
5017   "@
5018    #
5019    ldr%(b%)\\t%0, %1\\t%@ zero_extendqisi2"
5020   [(set_attr "length" "8,4")
5021    (set_attr "type" "alu_shift_reg,load_byte")
5022    (set_attr "predicable" "yes")]
5025 (define_insn "*arm_zero_extendqisi2_v6"
5026   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5027         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,Uh")))]
5028   "TARGET_ARM && arm_arch6"
5029   "@
5030    uxtb%(%)\\t%0, %1
5031    ldr%(b%)\\t%0, %1\\t%@ zero_extendqisi2"
5032   [(set_attr "type" "extend,load_byte")
5033    (set_attr "predicable" "yes")]
5036 (define_insn "*arm_zero_extendqisi2addsi"
5037   [(set (match_operand:SI 0 "s_register_operand" "=r")
5038         (plus:SI (zero_extend:SI (match_operand:QI 1 "s_register_operand" "r"))
5039                  (match_operand:SI 2 "s_register_operand" "r")))]
5040   "TARGET_INT_SIMD"
5041   "uxtab%?\\t%0, %2, %1"
5042   [(set_attr "predicable" "yes")
5043    (set_attr "predicable_short_it" "no")
5044    (set_attr "type" "alu_shift_reg")]
5047 (define_split
5048   [(set (match_operand:SI 0 "s_register_operand" "")
5049         (zero_extend:SI (subreg:QI (match_operand:SI 1 "" "") 0)))
5050    (clobber (match_operand:SI 2 "s_register_operand" ""))]
5051   "TARGET_32BIT && (!MEM_P (operands[1])) && ! BYTES_BIG_ENDIAN"
5052   [(set (match_dup 2) (match_dup 1))
5053    (set (match_dup 0) (and:SI (match_dup 2) (const_int 255)))]
5054   ""
5057 (define_split
5058   [(set (match_operand:SI 0 "s_register_operand" "")
5059         (zero_extend:SI (subreg:QI (match_operand:SI 1 "" "") 3)))
5060    (clobber (match_operand:SI 2 "s_register_operand" ""))]
5061   "TARGET_32BIT && (!MEM_P (operands[1])) && BYTES_BIG_ENDIAN"
5062   [(set (match_dup 2) (match_dup 1))
5063    (set (match_dup 0) (and:SI (match_dup 2) (const_int 255)))]
5064   ""
5068 (define_split
5069   [(set (match_operand:SI 0 "s_register_operand" "")
5070         (IOR_XOR:SI (and:SI (ashift:SI
5071                              (match_operand:SI 1 "s_register_operand" "")
5072                              (match_operand:SI 2 "const_int_operand" ""))
5073                             (match_operand:SI 3 "const_int_operand" ""))
5074                     (zero_extend:SI
5075                      (match_operator 5 "subreg_lowpart_operator"
5076                       [(match_operand:SI 4 "s_register_operand" "")]))))]
5077   "TARGET_32BIT
5078    && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
5079        == (GET_MODE_MASK (GET_MODE (operands[5]))
5080            & (GET_MODE_MASK (GET_MODE (operands[5]))
5081               << (INTVAL (operands[2])))))"
5082   [(set (match_dup 0) (IOR_XOR:SI (ashift:SI (match_dup 1) (match_dup 2))
5083                                   (match_dup 4)))
5084    (set (match_dup 0) (zero_extend:SI (match_dup 5)))]
5085   "operands[5] = gen_lowpart (GET_MODE (operands[5]), operands[0]);"
5088 (define_insn "*compareqi_eq0"
5089   [(set (reg:CC_Z CC_REGNUM)
5090         (compare:CC_Z (match_operand:QI 0 "s_register_operand" "r")
5091                          (const_int 0)))]
5092   "TARGET_32BIT"
5093   "tst%?\\t%0, #255"
5094   [(set_attr "conds" "set")
5095    (set_attr "predicable" "yes")
5096    (set_attr "predicable_short_it" "no")
5097    (set_attr "type" "logic_imm")]
5100 (define_expand "extendhisi2"
5101   [(set (match_operand:SI 0 "s_register_operand" "")
5102         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
5103   "TARGET_EITHER"
5105   if (TARGET_THUMB1)
5106     {
5107       emit_insn (gen_thumb1_extendhisi2 (operands[0], operands[1]));
5108       DONE;
5109     }
5110   if (MEM_P (operands[1]) && TARGET_ARM && !arm_arch4)
5111     {
5112       emit_insn (gen_extendhisi2_mem (operands[0], operands[1]));
5113       DONE;
5114     }
5116   if (!arm_arch6 && !MEM_P (operands[1]))
5117     {
5118       rtx t = gen_lowpart (SImode, operands[1]);
5119       rtx tmp = gen_reg_rtx (SImode);
5120       emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (16)));
5121       emit_insn (gen_ashrsi3 (operands[0], tmp, GEN_INT (16)));
5122       DONE;
5123     }
5126 (define_split
5127   [(parallel
5128     [(set (match_operand:SI 0 "register_operand" "")
5129           (sign_extend:SI (match_operand:HI 1 "register_operand" "")))
5130      (clobber (match_scratch:SI 2 ""))])]
5131   "!arm_arch6"
5132   [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
5133    (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
5135   operands[2] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
5138 ;; This pattern will only be used when ldsh is not available
5139 (define_expand "extendhisi2_mem"
5140   [(set (match_dup 2) (zero_extend:SI (match_operand:HI 1 "" "")))
5141    (set (match_dup 3)
5142         (zero_extend:SI (match_dup 7)))
5143    (set (match_dup 6) (ashift:SI (match_dup 4) (const_int 24)))
5144    (set (match_operand:SI 0 "" "")
5145         (ior:SI (ashiftrt:SI (match_dup 6) (const_int 16)) (match_dup 5)))]
5146   "TARGET_ARM"
5147   "
5148   {
5149     rtx mem1, mem2;
5150     rtx addr = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
5152     mem1 = change_address (operands[1], QImode, addr);
5153     mem2 = change_address (operands[1], QImode,
5154                            plus_constant (Pmode, addr, 1));
5155     operands[0] = gen_lowpart (SImode, operands[0]);
5156     operands[1] = mem1;
5157     operands[2] = gen_reg_rtx (SImode);
5158     operands[3] = gen_reg_rtx (SImode);
5159     operands[6] = gen_reg_rtx (SImode);
5160     operands[7] = mem2;
5162     if (BYTES_BIG_ENDIAN)
5163       {
5164         operands[4] = operands[2];
5165         operands[5] = operands[3];
5166       }
5167     else
5168       {
5169         operands[4] = operands[3];
5170         operands[5] = operands[2];
5171       }
5172   }"
5175 (define_split
5176   [(set (match_operand:SI 0 "register_operand" "")
5177         (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
5178   "!arm_arch6"
5179   [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
5180    (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
5182   operands[2] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
5185 (define_insn "*arm_extendhisi2"
5186   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5187         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,Uh")))]
5188   "TARGET_ARM && arm_arch4 && !arm_arch6"
5189   "@
5190    #
5191    ldr%(sh%)\\t%0, %1"
5192   [(set_attr "length" "8,4")
5193    (set_attr "type" "alu_shift_reg,load_byte")
5194    (set_attr "predicable" "yes")]
5197 ;; ??? Check Thumb-2 pool range
5198 (define_insn "*arm_extendhisi2_v6"
5199   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5200         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,Uh")))]
5201   "TARGET_32BIT && arm_arch6"
5202   "@
5203    sxth%?\\t%0, %1
5204    ldr%(sh%)\\t%0, %1"
5205   [(set_attr "type" "extend,load_byte")
5206    (set_attr "predicable" "yes")
5207    (set_attr "predicable_short_it" "no")]
5210 (define_insn "*arm_extendhisi2addsi"
5211   [(set (match_operand:SI 0 "s_register_operand" "=r")
5212         (plus:SI (sign_extend:SI (match_operand:HI 1 "s_register_operand" "r"))
5213                  (match_operand:SI 2 "s_register_operand" "r")))]
5214   "TARGET_INT_SIMD"
5215   "sxtah%?\\t%0, %2, %1"
5216   [(set_attr "type" "alu_shift_reg")]
5219 (define_expand "extendqihi2"
5220   [(set (match_dup 2)
5221         (ashift:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "")
5222                    (const_int 24)))
5223    (set (match_operand:HI 0 "s_register_operand" "")
5224         (ashiftrt:SI (match_dup 2)
5225                      (const_int 24)))]
5226   "TARGET_ARM"
5227   "
5228   {
5229     if (arm_arch4 && MEM_P (operands[1]))
5230       {
5231         emit_insn (gen_rtx_SET (operands[0],
5232                                 gen_rtx_SIGN_EXTEND (HImode, operands[1])));
5233         DONE;
5234       }
5235     if (!s_register_operand (operands[1], QImode))
5236       operands[1] = copy_to_mode_reg (QImode, operands[1]);
5237     operands[0] = gen_lowpart (SImode, operands[0]);
5238     operands[1] = gen_lowpart (SImode, operands[1]);
5239     operands[2] = gen_reg_rtx (SImode);
5240   }"
5243 (define_insn "*arm_extendqihi_insn"
5244   [(set (match_operand:HI 0 "s_register_operand" "=r")
5245         (sign_extend:HI (match_operand:QI 1 "arm_extendqisi_mem_op" "Uq")))]
5246   "TARGET_ARM && arm_arch4"
5247   "ldr%(sb%)\\t%0, %1"
5248   [(set_attr "type" "load_byte")
5249    (set_attr "predicable" "yes")]
5252 (define_expand "extendqisi2"
5253   [(set (match_operand:SI 0 "s_register_operand" "")
5254         (sign_extend:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "")))]
5255   "TARGET_EITHER"
5257   if (!arm_arch4 && MEM_P (operands[1]))
5258     operands[1] = copy_to_mode_reg (QImode, operands[1]);
5260   if (!arm_arch6 && !MEM_P (operands[1]))
5261     {
5262       rtx t = gen_lowpart (SImode, operands[1]);
5263       rtx tmp = gen_reg_rtx (SImode);
5264       emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (24)));
5265       emit_insn (gen_ashrsi3 (operands[0], tmp, GEN_INT (24)));
5266       DONE;
5267     }
5270 (define_split
5271   [(set (match_operand:SI 0 "register_operand" "")
5272         (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
5273   "!arm_arch6"
5274   [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 24)))
5275    (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 24)))]
5277   operands[2] = simplify_gen_subreg (SImode, operands[1], QImode, 0);
5280 (define_insn "*arm_extendqisi"
5281   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5282         (sign_extend:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "r,Uq")))]
5283   "TARGET_ARM && arm_arch4 && !arm_arch6"
5284   "@
5285    #
5286    ldr%(sb%)\\t%0, %1"
5287   [(set_attr "length" "8,4")
5288    (set_attr "type" "alu_shift_reg,load_byte")
5289    (set_attr "predicable" "yes")]
5292 (define_insn "*arm_extendqisi_v6"
5293   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5294         (sign_extend:SI
5295          (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "r,Uq")))]
5296   "TARGET_ARM && arm_arch6"
5297   "@
5298    sxtb%?\\t%0, %1
5299    ldr%(sb%)\\t%0, %1"
5300   [(set_attr "type" "extend,load_byte")
5301    (set_attr "predicable" "yes")]
5304 (define_insn "*arm_extendqisi2addsi"
5305   [(set (match_operand:SI 0 "s_register_operand" "=r")
5306         (plus:SI (sign_extend:SI (match_operand:QI 1 "s_register_operand" "r"))
5307                  (match_operand:SI 2 "s_register_operand" "r")))]
5308   "TARGET_INT_SIMD"
5309   "sxtab%?\\t%0, %2, %1"
5310   [(set_attr "type" "alu_shift_reg")
5311    (set_attr "predicable" "yes")
5312    (set_attr "predicable_short_it" "no")]
5315 (define_expand "extendsfdf2"
5316   [(set (match_operand:DF                  0 "s_register_operand" "")
5317         (float_extend:DF (match_operand:SF 1 "s_register_operand"  "")))]
5318   "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
5319   ""
5322 /* HFmode -> DFmode conversions have to go through SFmode.  */
5323 (define_expand "extendhfdf2"
5324   [(set (match_operand:DF                  0 "general_operand" "")
5325         (float_extend:DF (match_operand:HF 1 "general_operand"  "")))]
5326   "TARGET_EITHER"
5327   "
5328   {
5329     rtx op1;
5330     op1 = convert_to_mode (SFmode, operands[1], 0);
5331     op1 = convert_to_mode (DFmode, op1, 0);
5332     emit_insn (gen_movdf (operands[0], op1));
5333     DONE;
5334   }"
5337 ;; Move insns (including loads and stores)
5339 ;; XXX Just some ideas about movti.
5340 ;; I don't think these are a good idea on the arm, there just aren't enough
5341 ;; registers
5342 ;;(define_expand "loadti"
5343 ;;  [(set (match_operand:TI 0 "s_register_operand" "")
5344 ;;      (mem:TI (match_operand:SI 1 "address_operand" "")))]
5345 ;;  "" "")
5347 ;;(define_expand "storeti"
5348 ;;  [(set (mem:TI (match_operand:TI 0 "address_operand" ""))
5349 ;;      (match_operand:TI 1 "s_register_operand" ""))]
5350 ;;  "" "")
5352 ;;(define_expand "movti"
5353 ;;  [(set (match_operand:TI 0 "general_operand" "")
5354 ;;      (match_operand:TI 1 "general_operand" ""))]
5355 ;;  ""
5356 ;;  "
5358 ;;  rtx insn;
5360 ;;  if (MEM_P (operands[0]) && MEM_P (operands[1]))
5361 ;;    operands[1] = copy_to_reg (operands[1]);
5362 ;;  if (MEM_P (operands[0]))
5363 ;;    insn = gen_storeti (XEXP (operands[0], 0), operands[1]);
5364 ;;  else if (MEM_P (operands[1]))
5365 ;;    insn = gen_loadti (operands[0], XEXP (operands[1], 0));
5366 ;;  else
5367 ;;    FAIL;
5369 ;;  emit_insn (insn);
5370 ;;  DONE;
5371 ;;}")
5373 ;; Recognize garbage generated above.
5375 ;;(define_insn ""
5376 ;;  [(set (match_operand:TI 0 "general_operand" "=r,r,r,<,>,m")
5377 ;;      (match_operand:TI 1 "general_operand" "<,>,m,r,r,r"))]
5378 ;;  ""
5379 ;;  "*
5380 ;;  {
5381 ;;    register mem = (which_alternative < 3);
5382 ;;    register const char *template;
5384 ;;    operands[mem] = XEXP (operands[mem], 0);
5385 ;;    switch (which_alternative)
5386 ;;      {
5387 ;;      case 0: template = \"ldmdb\\t%1!, %M0\"; break;
5388 ;;      case 1: template = \"ldmia\\t%1!, %M0\"; break;
5389 ;;      case 2: template = \"ldmia\\t%1, %M0\"; break;
5390 ;;      case 3: template = \"stmdb\\t%0!, %M1\"; break;
5391 ;;      case 4: template = \"stmia\\t%0!, %M1\"; break;
5392 ;;      case 5: template = \"stmia\\t%0, %M1\"; break;
5393 ;;      }
5394 ;;    output_asm_insn (template, operands);
5395 ;;    return \"\";
5396 ;;  }")
5398 (define_expand "movdi"
5399   [(set (match_operand:DI 0 "general_operand" "")
5400         (match_operand:DI 1 "general_operand" ""))]
5401   "TARGET_EITHER"
5402   "
5403   if (can_create_pseudo_p ())
5404     {
5405       if (!REG_P (operands[0]))
5406         operands[1] = force_reg (DImode, operands[1]);
5407     }
5408   "
5411 (define_insn "*arm_movdi"
5412   [(set (match_operand:DI 0 "nonimmediate_di_operand" "=r, r, r, q, m")
5413         (match_operand:DI 1 "di_operand"              "rDa,Db,Dc,mi,q"))]
5414   "TARGET_32BIT
5415    && !(TARGET_HARD_FLOAT && TARGET_VFP)
5416    && !TARGET_IWMMXT
5417    && (   register_operand (operands[0], DImode)
5418        || register_operand (operands[1], DImode))"
5419   "*
5420   switch (which_alternative)
5421     {
5422     case 0:
5423     case 1:
5424     case 2:
5425       return \"#\";
5426     default:
5427       return output_move_double (operands, true, NULL);
5428     }
5429   "
5430   [(set_attr "length" "8,12,16,8,8")
5431    (set_attr "type" "multiple,multiple,multiple,load2,store2")
5432    (set_attr "arm_pool_range" "*,*,*,1020,*")
5433    (set_attr "arm_neg_pool_range" "*,*,*,1004,*")
5434    (set_attr "thumb2_pool_range" "*,*,*,4094,*")
5435    (set_attr "thumb2_neg_pool_range" "*,*,*,0,*")]
5438 (define_split
5439   [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
5440         (match_operand:ANY64 1 "immediate_operand" ""))]
5441   "TARGET_32BIT
5442    && reload_completed
5443    && (arm_const_double_inline_cost (operands[1])
5444        <= arm_max_const_double_inline_cost ())"
5445   [(const_int 0)]
5446   "
5447   arm_split_constant (SET, SImode, curr_insn,
5448                       INTVAL (gen_lowpart (SImode, operands[1])),
5449                       gen_lowpart (SImode, operands[0]), NULL_RTX, 0);
5450   arm_split_constant (SET, SImode, curr_insn,
5451                       INTVAL (gen_highpart_mode (SImode,
5452                                                  GET_MODE (operands[0]),
5453                                                  operands[1])),
5454                       gen_highpart (SImode, operands[0]), NULL_RTX, 0);
5455   DONE;
5456   "
5459 ; If optimizing for size, or if we have load delay slots, then 
5460 ; we want to split the constant into two separate operations. 
5461 ; In both cases this may split a trivial part into a single data op
5462 ; leaving a single complex constant to load.  We can also get longer
5463 ; offsets in a LDR which means we get better chances of sharing the pool
5464 ; entries.  Finally, we can normally do a better job of scheduling
5465 ; LDR instructions than we can with LDM.
5466 ; This pattern will only match if the one above did not.
5467 (define_split
5468   [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
5469         (match_operand:ANY64 1 "const_double_operand" ""))]
5470   "TARGET_ARM && reload_completed
5471    && arm_const_double_by_parts (operands[1])"
5472   [(set (match_dup 0) (match_dup 1))
5473    (set (match_dup 2) (match_dup 3))]
5474   "
5475   operands[2] = gen_highpart (SImode, operands[0]);
5476   operands[3] = gen_highpart_mode (SImode, GET_MODE (operands[0]),
5477                                    operands[1]);
5478   operands[0] = gen_lowpart (SImode, operands[0]);
5479   operands[1] = gen_lowpart (SImode, operands[1]);
5480   "
5483 (define_split
5484   [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
5485         (match_operand:ANY64 1 "arm_general_register_operand" ""))]
5486   "TARGET_EITHER && reload_completed"
5487   [(set (match_dup 0) (match_dup 1))
5488    (set (match_dup 2) (match_dup 3))]
5489   "
5490   operands[2] = gen_highpart (SImode, operands[0]);
5491   operands[3] = gen_highpart (SImode, operands[1]);
5492   operands[0] = gen_lowpart (SImode, operands[0]);
5493   operands[1] = gen_lowpart (SImode, operands[1]);
5495   /* Handle a partial overlap.  */
5496   if (rtx_equal_p (operands[0], operands[3]))
5497     {
5498       rtx tmp0 = operands[0];
5499       rtx tmp1 = operands[1];
5501       operands[0] = operands[2];
5502       operands[1] = operands[3];
5503       operands[2] = tmp0;
5504       operands[3] = tmp1;
5505     }
5506   "
5509 ;; We can't actually do base+index doubleword loads if the index and
5510 ;; destination overlap.  Split here so that we at least have chance to
5511 ;; schedule.
5512 (define_split
5513   [(set (match_operand:DI 0 "s_register_operand" "")
5514         (mem:DI (plus:SI (match_operand:SI 1 "s_register_operand" "")
5515                          (match_operand:SI 2 "s_register_operand" ""))))]
5516   "TARGET_LDRD
5517   && reg_overlap_mentioned_p (operands[0], operands[1])
5518   && reg_overlap_mentioned_p (operands[0], operands[2])"
5519   [(set (match_dup 4)
5520         (plus:SI (match_dup 1)
5521                  (match_dup 2)))
5522    (set (match_dup 0)
5523         (mem:DI (match_dup 4)))]
5524   "
5525   operands[4] = gen_rtx_REG (SImode, REGNO(operands[0]));
5526   "
5529 (define_expand "movsi"
5530   [(set (match_operand:SI 0 "general_operand" "")
5531         (match_operand:SI 1 "general_operand" ""))]
5532   "TARGET_EITHER"
5533   "
5534   {
5535   rtx base, offset, tmp;
5537   if (TARGET_32BIT)
5538     {
5539       /* Everything except mem = const or mem = mem can be done easily.  */
5540       if (MEM_P (operands[0]))
5541         operands[1] = force_reg (SImode, operands[1]);
5542       if (arm_general_register_operand (operands[0], SImode)
5543           && CONST_INT_P (operands[1])
5544           && !(const_ok_for_arm (INTVAL (operands[1]))
5545                || const_ok_for_arm (~INTVAL (operands[1]))))
5546         {
5547            arm_split_constant (SET, SImode, NULL_RTX,
5548                                INTVAL (operands[1]), operands[0], NULL_RTX,
5549                                optimize && can_create_pseudo_p ());
5550           DONE;
5551         }
5552     }
5553   else /* TARGET_THUMB1...  */
5554     {
5555       if (can_create_pseudo_p ())
5556         {
5557           if (!REG_P (operands[0]))
5558             operands[1] = force_reg (SImode, operands[1]);
5559         }
5560     }
5562   if (ARM_OFFSETS_MUST_BE_WITHIN_SECTIONS_P)
5563     {
5564       split_const (operands[1], &base, &offset);
5565       if (GET_CODE (base) == SYMBOL_REF
5566           && !offset_within_block_p (base, INTVAL (offset)))
5567         {
5568           tmp = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];
5569           emit_move_insn (tmp, base);
5570           emit_insn (gen_addsi3 (operands[0], tmp, offset));
5571           DONE;
5572         }
5573     }
5575   /* Recognize the case where operand[1] is a reference to thread-local
5576      data and load its address to a register.  */
5577   if (arm_tls_referenced_p (operands[1]))
5578     {
5579       rtx tmp = operands[1];
5580       rtx addend = NULL;
5582       if (GET_CODE (tmp) == CONST && GET_CODE (XEXP (tmp, 0)) == PLUS)
5583         {
5584           addend = XEXP (XEXP (tmp, 0), 1);
5585           tmp = XEXP (XEXP (tmp, 0), 0);
5586         }
5588       gcc_assert (GET_CODE (tmp) == SYMBOL_REF);
5589       gcc_assert (SYMBOL_REF_TLS_MODEL (tmp) != 0);
5591       tmp = legitimize_tls_address (tmp,
5592                                     !can_create_pseudo_p () ? operands[0] : 0);
5593       if (addend)
5594         {
5595           tmp = gen_rtx_PLUS (SImode, tmp, addend);
5596           tmp = force_operand (tmp, operands[0]);
5597         }
5598       operands[1] = tmp;
5599     }
5600   else if (flag_pic
5601            && (CONSTANT_P (operands[1])
5602                || symbol_mentioned_p (operands[1])
5603                || label_mentioned_p (operands[1])))
5604       operands[1] = legitimize_pic_address (operands[1], SImode,
5605                                             (!can_create_pseudo_p ()
5606                                              ? operands[0]
5607                                              : 0));
5608   }
5609   "
5612 ;; The ARM LO_SUM and HIGH are backwards - HIGH sets the low bits, and
5613 ;; LO_SUM adds in the high bits.  Fortunately these are opaque operations
5614 ;; so this does not matter.
5615 (define_insn "*arm_movt"
5616   [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
5617         (lo_sum:SI (match_operand:SI 1 "nonimmediate_operand" "0")
5618                    (match_operand:SI 2 "general_operand"      "i")))]
5619   "arm_arch_thumb2"
5620   "movt%?\t%0, #:upper16:%c2"
5621   [(set_attr "predicable" "yes")
5622    (set_attr "predicable_short_it" "no")
5623    (set_attr "length" "4")
5624    (set_attr "type" "alu_sreg")]
5627 (define_insn "*arm_movsi_insn"
5628   [(set (match_operand:SI 0 "nonimmediate_operand" "=rk,r,r,r,rk,m")
5629         (match_operand:SI 1 "general_operand"      "rk, I,K,j,mi,rk"))]
5630   "TARGET_ARM && ! TARGET_IWMMXT
5631    && !(TARGET_HARD_FLOAT && TARGET_VFP)
5632    && (   register_operand (operands[0], SImode)
5633        || register_operand (operands[1], SImode))"
5634   "@
5635    mov%?\\t%0, %1
5636    mov%?\\t%0, %1
5637    mvn%?\\t%0, #%B1
5638    movw%?\\t%0, %1
5639    ldr%?\\t%0, %1
5640    str%?\\t%1, %0"
5641   [(set_attr "type" "mov_reg,mov_imm,mvn_imm,mov_imm,load1,store1")
5642    (set_attr "predicable" "yes")
5643    (set_attr "pool_range" "*,*,*,*,4096,*")
5644    (set_attr "neg_pool_range" "*,*,*,*,4084,*")]
5647 (define_split
5648   [(set (match_operand:SI 0 "arm_general_register_operand" "")
5649         (match_operand:SI 1 "const_int_operand" ""))]
5650   "TARGET_32BIT
5651   && (!(const_ok_for_arm (INTVAL (operands[1]))
5652         || const_ok_for_arm (~INTVAL (operands[1]))))"
5653   [(clobber (const_int 0))]
5654   "
5655   arm_split_constant (SET, SImode, NULL_RTX, 
5656                       INTVAL (operands[1]), operands[0], NULL_RTX, 0);
5657   DONE;
5658   "
5661 ;; A normal way to do (symbol + offset) requires three instructions at least
5662 ;; (depends on how big the offset is) as below:
5663 ;; movw r0, #:lower16:g
5664 ;; movw r0, #:upper16:g
5665 ;; adds r0, #4
5667 ;; A better way would be:
5668 ;; movw r0, #:lower16:g+4
5669 ;; movw r0, #:upper16:g+4
5671 ;; The limitation of this way is that the length of offset should be a 16-bit
5672 ;; signed value, because current assembler only supports REL type relocation for
5673 ;; such case.  If the more powerful RELA type is supported in future, we should
5674 ;; update this pattern to go with better way.
5675 (define_split
5676   [(set (match_operand:SI 0 "arm_general_register_operand" "")
5677         (const:SI (plus:SI (match_operand:SI 1 "general_operand" "")
5678                            (match_operand:SI 2 "const_int_operand" ""))))]
5679   "TARGET_THUMB2
5680    && arm_disable_literal_pool
5681    && reload_completed
5682    && GET_CODE (operands[1]) == SYMBOL_REF"
5683   [(clobber (const_int 0))]
5684   "
5685     int offset = INTVAL (operands[2]);
5687     if (offset < -0x8000 || offset > 0x7fff)
5688       {
5689         arm_emit_movpair (operands[0], operands[1]);
5690         emit_insn (gen_rtx_SET (operands[0],
5691                                 gen_rtx_PLUS (SImode, operands[0], operands[2])));
5692       }
5693     else
5694       {
5695         rtx op = gen_rtx_CONST (SImode,
5696                                 gen_rtx_PLUS (SImode, operands[1], operands[2]));
5697         arm_emit_movpair (operands[0], op);
5698       }
5699   "
5702 ;; Split symbol_refs at the later stage (after cprop), instead of generating
5703 ;; movt/movw pair directly at expand.  Otherwise corresponding high_sum
5704 ;; and lo_sum would be merged back into memory load at cprop.  However,
5705 ;; if the default is to prefer movt/movw rather than a load from the constant
5706 ;; pool, the performance is better.
5707 (define_split
5708   [(set (match_operand:SI 0 "arm_general_register_operand" "")
5709        (match_operand:SI 1 "general_operand" ""))]
5710   "TARGET_32BIT
5711    && TARGET_USE_MOVT && GET_CODE (operands[1]) == SYMBOL_REF
5712    && !flag_pic && !target_word_relocations
5713    && !arm_tls_referenced_p (operands[1])"
5714   [(clobber (const_int 0))]
5716   arm_emit_movpair (operands[0], operands[1]);
5717   DONE;
5720 ;; When generating pic, we need to load the symbol offset into a register.
5721 ;; So that the optimizer does not confuse this with a normal symbol load
5722 ;; we use an unspec.  The offset will be loaded from a constant pool entry,
5723 ;; since that is the only type of relocation we can use.
5725 ;; Wrap calculation of the whole PIC address in a single pattern for the
5726 ;; benefit of optimizers, particularly, PRE and HOIST.  Calculation of
5727 ;; a PIC address involves two loads from memory, so we want to CSE it
5728 ;; as often as possible.
5729 ;; This pattern will be split into one of the pic_load_addr_* patterns
5730 ;; and a move after GCSE optimizations.
5732 ;; Note: Update arm.c: legitimize_pic_address() when changing this pattern.
5733 (define_expand "calculate_pic_address"
5734   [(set (match_operand:SI 0 "register_operand" "")
5735         (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "")
5736                          (unspec:SI [(match_operand:SI 2 "" "")]
5737                                     UNSPEC_PIC_SYM))))]
5738   "flag_pic"
5741 ;; Split calculate_pic_address into pic_load_addr_* and a move.
5742 (define_split
5743   [(set (match_operand:SI 0 "register_operand" "")
5744         (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "")
5745                          (unspec:SI [(match_operand:SI 2 "" "")]
5746                                     UNSPEC_PIC_SYM))))]
5747   "flag_pic"
5748   [(set (match_dup 3) (unspec:SI [(match_dup 2)] UNSPEC_PIC_SYM))
5749    (set (match_dup 0) (mem:SI (plus:SI (match_dup 1) (match_dup 3))))]
5750   "operands[3] = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];"
5753 ;; operand1 is the memory address to go into 
5754 ;; pic_load_addr_32bit.
5755 ;; operand2 is the PIC label to be emitted 
5756 ;; from pic_add_dot_plus_eight.
5757 ;; We do this to allow hoisting of the entire insn.
5758 (define_insn_and_split "pic_load_addr_unified"
5759   [(set (match_operand:SI 0 "s_register_operand" "=r,r,l")
5760         (unspec:SI [(match_operand:SI 1 "" "mX,mX,mX") 
5761                     (match_operand:SI 2 "" "")] 
5762                     UNSPEC_PIC_UNIFIED))]
5763  "flag_pic"
5764  "#"
5765  "&& reload_completed"
5766  [(set (match_dup 0) (unspec:SI [(match_dup 1)] UNSPEC_PIC_SYM))
5767   (set (match_dup 0) (unspec:SI [(match_dup 0) (match_dup 3)
5768                                  (match_dup 2)] UNSPEC_PIC_BASE))]
5769  "operands[3] = TARGET_THUMB ? GEN_INT (4) : GEN_INT (8);"
5770  [(set_attr "type" "load1,load1,load1")
5771   (set_attr "pool_range" "4096,4094,1022")
5772   (set_attr "neg_pool_range" "4084,0,0")
5773   (set_attr "arch"  "a,t2,t1")    
5774   (set_attr "length" "8,6,4")]
5777 ;; The rather odd constraints on the following are to force reload to leave
5778 ;; the insn alone, and to force the minipool generation pass to then move
5779 ;; the GOT symbol to memory.
5781 (define_insn "pic_load_addr_32bit"
5782   [(set (match_operand:SI 0 "s_register_operand" "=r")
5783         (unspec:SI [(match_operand:SI 1 "" "mX")] UNSPEC_PIC_SYM))]
5784   "TARGET_32BIT && flag_pic"
5785   "ldr%?\\t%0, %1"
5786   [(set_attr "type" "load1")
5787    (set (attr "pool_range")
5788         (if_then_else (eq_attr "is_thumb" "no")
5789                       (const_int 4096)
5790                       (const_int 4094)))
5791    (set (attr "neg_pool_range")
5792         (if_then_else (eq_attr "is_thumb" "no")
5793                       (const_int 4084)
5794                       (const_int 0)))]
5797 (define_insn "pic_load_addr_thumb1"
5798   [(set (match_operand:SI 0 "s_register_operand" "=l")
5799         (unspec:SI [(match_operand:SI 1 "" "mX")] UNSPEC_PIC_SYM))]
5800   "TARGET_THUMB1 && flag_pic"
5801   "ldr\\t%0, %1"
5802   [(set_attr "type" "load1")
5803    (set (attr "pool_range") (const_int 1018))]
5806 (define_insn "pic_add_dot_plus_four"
5807   [(set (match_operand:SI 0 "register_operand" "=r")
5808         (unspec:SI [(match_operand:SI 1 "register_operand" "0")
5809                     (const_int 4)
5810                     (match_operand 2 "" "")]
5811                    UNSPEC_PIC_BASE))]
5812   "TARGET_THUMB"
5813   "*
5814   (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
5815                                      INTVAL (operands[2]));
5816   return \"add\\t%0, %|pc\";
5817   "
5818   [(set_attr "length" "2")
5819    (set_attr "type" "alu_sreg")]
5822 (define_insn "pic_add_dot_plus_eight"
5823   [(set (match_operand:SI 0 "register_operand" "=r")
5824         (unspec:SI [(match_operand:SI 1 "register_operand" "r")
5825                     (const_int 8)
5826                     (match_operand 2 "" "")]
5827                    UNSPEC_PIC_BASE))]
5828   "TARGET_ARM"
5829   "*
5830     (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
5831                                        INTVAL (operands[2]));
5832     return \"add%?\\t%0, %|pc, %1\";
5833   "
5834   [(set_attr "predicable" "yes")
5835    (set_attr "type" "alu_sreg")]
5838 (define_insn "tls_load_dot_plus_eight"
5839   [(set (match_operand:SI 0 "register_operand" "=r")
5840         (mem:SI (unspec:SI [(match_operand:SI 1 "register_operand" "r")
5841                             (const_int 8)
5842                             (match_operand 2 "" "")]
5843                            UNSPEC_PIC_BASE)))]
5844   "TARGET_ARM"
5845   "*
5846     (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
5847                                        INTVAL (operands[2]));
5848     return \"ldr%?\\t%0, [%|pc, %1]\t\t@ tls_load_dot_plus_eight\";
5849   "
5850   [(set_attr "predicable" "yes")
5851    (set_attr "type" "load1")]
5854 ;; PIC references to local variables can generate pic_add_dot_plus_eight
5855 ;; followed by a load.  These sequences can be crunched down to
5856 ;; tls_load_dot_plus_eight by a peephole.
5858 (define_peephole2
5859   [(set (match_operand:SI 0 "register_operand" "")
5860         (unspec:SI [(match_operand:SI 3 "register_operand" "")
5861                     (const_int 8)
5862                     (match_operand 1 "" "")]
5863                    UNSPEC_PIC_BASE))
5864    (set (match_operand:SI 2 "arm_general_register_operand" "")
5865         (mem:SI (match_dup 0)))]
5866   "TARGET_ARM && peep2_reg_dead_p (2, operands[0])"
5867   [(set (match_dup 2)
5868         (mem:SI (unspec:SI [(match_dup 3)
5869                             (const_int 8)
5870                             (match_dup 1)]
5871                            UNSPEC_PIC_BASE)))]
5872   ""
5875 (define_insn "pic_offset_arm"
5876   [(set (match_operand:SI 0 "register_operand" "=r")
5877         (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
5878                          (unspec:SI [(match_operand:SI 2 "" "X")]
5879                                     UNSPEC_PIC_OFFSET))))]
5880   "TARGET_VXWORKS_RTP && TARGET_ARM && flag_pic"
5881   "ldr%?\\t%0, [%1,%2]"
5882   [(set_attr "type" "load1")]
5885 (define_expand "builtin_setjmp_receiver"
5886   [(label_ref (match_operand 0 "" ""))]
5887   "flag_pic"
5888   "
5890   /* r3 is clobbered by set/longjmp, so we can use it as a scratch
5891      register.  */
5892   if (arm_pic_register != INVALID_REGNUM)
5893     arm_load_pic_register (1UL << 3);
5894   DONE;
5897 ;; If copying one reg to another we can set the condition codes according to
5898 ;; its value.  Such a move is common after a return from subroutine and the
5899 ;; result is being tested against zero.
5901 (define_insn "*movsi_compare0"
5902   [(set (reg:CC CC_REGNUM)
5903         (compare:CC (match_operand:SI 1 "s_register_operand" "0,r")
5904                     (const_int 0)))
5905    (set (match_operand:SI 0 "s_register_operand" "=r,r")
5906         (match_dup 1))]
5907   "TARGET_32BIT"
5908   "@
5909    cmp%?\\t%0, #0
5910    sub%.\\t%0, %1, #0"
5911   [(set_attr "conds" "set")
5912    (set_attr "type" "alus_imm,alus_imm")]
5915 ;; Subroutine to store a half word from a register into memory.
5916 ;; Operand 0 is the source register (HImode)
5917 ;; Operand 1 is the destination address in a register (SImode)
5919 ;; In both this routine and the next, we must be careful not to spill
5920 ;; a memory address of reg+large_const into a separate PLUS insn, since this
5921 ;; can generate unrecognizable rtl.
5923 (define_expand "storehi"
5924   [;; store the low byte
5925    (set (match_operand 1 "" "") (match_dup 3))
5926    ;; extract the high byte
5927    (set (match_dup 2)
5928         (ashiftrt:SI (match_operand 0 "" "") (const_int 8)))
5929    ;; store the high byte
5930    (set (match_dup 4) (match_dup 5))]
5931   "TARGET_ARM"
5932   "
5933   {
5934     rtx op1 = operands[1];
5935     rtx addr = XEXP (op1, 0);
5936     enum rtx_code code = GET_CODE (addr);
5938     if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1)))
5939         || code == MINUS)
5940       op1 = replace_equiv_address (operands[1], force_reg (SImode, addr));
5942     operands[4] = adjust_address (op1, QImode, 1);
5943     operands[1] = adjust_address (operands[1], QImode, 0);
5944     operands[3] = gen_lowpart (QImode, operands[0]);
5945     operands[0] = gen_lowpart (SImode, operands[0]);
5946     operands[2] = gen_reg_rtx (SImode);
5947     operands[5] = gen_lowpart (QImode, operands[2]);
5948   }"
5951 (define_expand "storehi_bigend"
5952   [(set (match_dup 4) (match_dup 3))
5953    (set (match_dup 2)
5954         (ashiftrt:SI (match_operand 0 "" "") (const_int 8)))
5955    (set (match_operand 1 "" "") (match_dup 5))]
5956   "TARGET_ARM"
5957   "
5958   {
5959     rtx op1 = operands[1];
5960     rtx addr = XEXP (op1, 0);
5961     enum rtx_code code = GET_CODE (addr);
5963     if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1)))
5964         || code == MINUS)
5965       op1 = replace_equiv_address (op1, force_reg (SImode, addr));
5967     operands[4] = adjust_address (op1, QImode, 1);
5968     operands[1] = adjust_address (operands[1], QImode, 0);
5969     operands[3] = gen_lowpart (QImode, operands[0]);
5970     operands[0] = gen_lowpart (SImode, operands[0]);
5971     operands[2] = gen_reg_rtx (SImode);
5972     operands[5] = gen_lowpart (QImode, operands[2]);
5973   }"
5976 ;; Subroutine to store a half word integer constant into memory.
5977 (define_expand "storeinthi"
5978   [(set (match_operand 0 "" "")
5979         (match_operand 1 "" ""))
5980    (set (match_dup 3) (match_dup 2))]
5981   "TARGET_ARM"
5982   "
5983   {
5984     HOST_WIDE_INT value = INTVAL (operands[1]);
5985     rtx addr = XEXP (operands[0], 0);
5986     rtx op0 = operands[0];
5987     enum rtx_code code = GET_CODE (addr);
5989     if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1)))
5990         || code == MINUS)
5991       op0 = replace_equiv_address (op0, force_reg (SImode, addr));
5993     operands[1] = gen_reg_rtx (SImode);
5994     if (BYTES_BIG_ENDIAN)
5995       {
5996         emit_insn (gen_movsi (operands[1], GEN_INT ((value >> 8) & 255)));
5997         if ((value & 255) == ((value >> 8) & 255))
5998           operands[2] = operands[1];
5999         else
6000           {
6001             operands[2] = gen_reg_rtx (SImode);
6002             emit_insn (gen_movsi (operands[2], GEN_INT (value & 255)));
6003           }
6004       }
6005     else
6006       {
6007         emit_insn (gen_movsi (operands[1], GEN_INT (value & 255)));
6008         if ((value & 255) == ((value >> 8) & 255))
6009           operands[2] = operands[1];
6010         else
6011           {
6012             operands[2] = gen_reg_rtx (SImode);
6013             emit_insn (gen_movsi (operands[2], GEN_INT ((value >> 8) & 255)));
6014           }
6015       }
6017     operands[3] = adjust_address (op0, QImode, 1);
6018     operands[0] = adjust_address (operands[0], QImode, 0);
6019     operands[2] = gen_lowpart (QImode, operands[2]);
6020     operands[1] = gen_lowpart (QImode, operands[1]);
6021   }"
6024 (define_expand "storehi_single_op"
6025   [(set (match_operand:HI 0 "memory_operand" "")
6026         (match_operand:HI 1 "general_operand" ""))]
6027   "TARGET_32BIT && arm_arch4"
6028   "
6029   if (!s_register_operand (operands[1], HImode))
6030     operands[1] = copy_to_mode_reg (HImode, operands[1]);
6031   "
6034 (define_expand "movhi"
6035   [(set (match_operand:HI 0 "general_operand" "")
6036         (match_operand:HI 1 "general_operand" ""))]
6037   "TARGET_EITHER"
6038   "
6039   if (TARGET_ARM)
6040     {
6041       if (can_create_pseudo_p ())
6042         {
6043           if (MEM_P (operands[0]))
6044             {
6045               if (arm_arch4)
6046                 {
6047                   emit_insn (gen_storehi_single_op (operands[0], operands[1]));
6048                   DONE;
6049                 }
6050               if (CONST_INT_P (operands[1]))
6051                 emit_insn (gen_storeinthi (operands[0], operands[1]));
6052               else
6053                 {
6054                   if (MEM_P (operands[1]))
6055                     operands[1] = force_reg (HImode, operands[1]);
6056                   if (BYTES_BIG_ENDIAN)
6057                     emit_insn (gen_storehi_bigend (operands[1], operands[0]));
6058                   else
6059                    emit_insn (gen_storehi (operands[1], operands[0]));
6060                 }
6061               DONE;
6062             }
6063           /* Sign extend a constant, and keep it in an SImode reg.  */
6064           else if (CONST_INT_P (operands[1]))
6065             {
6066               rtx reg = gen_reg_rtx (SImode);
6067               HOST_WIDE_INT val = INTVAL (operands[1]) & 0xffff;
6069               /* If the constant is already valid, leave it alone.  */
6070               if (!const_ok_for_arm (val))
6071                 {
6072                   /* If setting all the top bits will make the constant 
6073                      loadable in a single instruction, then set them.  
6074                      Otherwise, sign extend the number.  */
6076                   if (const_ok_for_arm (~(val | ~0xffff)))
6077                     val |= ~0xffff;
6078                   else if (val & 0x8000)
6079                     val |= ~0xffff;
6080                 }
6082               emit_insn (gen_movsi (reg, GEN_INT (val)));
6083               operands[1] = gen_lowpart (HImode, reg);
6084             }
6085           else if (arm_arch4 && optimize && can_create_pseudo_p ()
6086                    && MEM_P (operands[1]))
6087             {
6088               rtx reg = gen_reg_rtx (SImode);
6090               emit_insn (gen_zero_extendhisi2 (reg, operands[1]));
6091               operands[1] = gen_lowpart (HImode, reg);
6092             }
6093           else if (!arm_arch4)
6094             {
6095               if (MEM_P (operands[1]))
6096                 {
6097                   rtx base;
6098                   rtx offset = const0_rtx;
6099                   rtx reg = gen_reg_rtx (SImode);
6101                   if ((REG_P (base = XEXP (operands[1], 0))
6102                        || (GET_CODE (base) == PLUS
6103                            && (CONST_INT_P (offset = XEXP (base, 1)))
6104                            && ((INTVAL(offset) & 1) != 1)
6105                            && REG_P (base = XEXP (base, 0))))
6106                       && REGNO_POINTER_ALIGN (REGNO (base)) >= 32)
6107                     {
6108                       rtx new_rtx;
6110                       new_rtx = widen_memory_access (operands[1], SImode,
6111                                                      ((INTVAL (offset) & ~3)
6112                                                       - INTVAL (offset)));
6113                       emit_insn (gen_movsi (reg, new_rtx));
6114                       if (((INTVAL (offset) & 2) != 0)
6115                           ^ (BYTES_BIG_ENDIAN ? 1 : 0))
6116                         {
6117                           rtx reg2 = gen_reg_rtx (SImode);
6119                           emit_insn (gen_lshrsi3 (reg2, reg, GEN_INT (16)));
6120                           reg = reg2;
6121                         }
6122                     }
6123                   else
6124                     emit_insn (gen_movhi_bytes (reg, operands[1]));
6126                   operands[1] = gen_lowpart (HImode, reg);
6127                }
6128            }
6129         }
6130       /* Handle loading a large integer during reload.  */
6131       else if (CONST_INT_P (operands[1])
6132                && !const_ok_for_arm (INTVAL (operands[1]))
6133                && !const_ok_for_arm (~INTVAL (operands[1])))
6134         {
6135           /* Writing a constant to memory needs a scratch, which should
6136              be handled with SECONDARY_RELOADs.  */
6137           gcc_assert (REG_P (operands[0]));
6139           operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
6140           emit_insn (gen_movsi (operands[0], operands[1]));
6141           DONE;
6142        }
6143     }
6144   else if (TARGET_THUMB2)
6145     {
6146       /* Thumb-2 can do everything except mem=mem and mem=const easily.  */
6147       if (can_create_pseudo_p ())
6148         {
6149           if (!REG_P (operands[0]))
6150             operands[1] = force_reg (HImode, operands[1]);
6151           /* Zero extend a constant, and keep it in an SImode reg.  */
6152           else if (CONST_INT_P (operands[1]))
6153             {
6154               rtx reg = gen_reg_rtx (SImode);
6155               HOST_WIDE_INT val = INTVAL (operands[1]) & 0xffff;
6157               emit_insn (gen_movsi (reg, GEN_INT (val)));
6158               operands[1] = gen_lowpart (HImode, reg);
6159             }
6160         }
6161     }
6162   else /* TARGET_THUMB1 */
6163     {
6164       if (can_create_pseudo_p ())
6165         {
6166           if (CONST_INT_P (operands[1]))
6167             {
6168               rtx reg = gen_reg_rtx (SImode);
6170               emit_insn (gen_movsi (reg, operands[1]));
6171               operands[1] = gen_lowpart (HImode, reg);
6172             }
6174           /* ??? We shouldn't really get invalid addresses here, but this can
6175              happen if we are passed a SP (never OK for HImode/QImode) or 
6176              virtual register (also rejected as illegitimate for HImode/QImode)
6177              relative address.  */
6178           /* ??? This should perhaps be fixed elsewhere, for instance, in
6179              fixup_stack_1, by checking for other kinds of invalid addresses,
6180              e.g. a bare reference to a virtual register.  This may confuse the
6181              alpha though, which must handle this case differently.  */
6182           if (MEM_P (operands[0])
6183               && !memory_address_p (GET_MODE (operands[0]),
6184                                     XEXP (operands[0], 0)))
6185             operands[0]
6186               = replace_equiv_address (operands[0],
6187                                        copy_to_reg (XEXP (operands[0], 0)));
6188    
6189           if (MEM_P (operands[1])
6190               && !memory_address_p (GET_MODE (operands[1]),
6191                                     XEXP (operands[1], 0)))
6192             operands[1]
6193               = replace_equiv_address (operands[1],
6194                                        copy_to_reg (XEXP (operands[1], 0)));
6196           if (MEM_P (operands[1]) && optimize > 0)
6197             {
6198               rtx reg = gen_reg_rtx (SImode);
6200               emit_insn (gen_zero_extendhisi2 (reg, operands[1]));
6201               operands[1] = gen_lowpart (HImode, reg);
6202             }
6204           if (MEM_P (operands[0]))
6205             operands[1] = force_reg (HImode, operands[1]);
6206         }
6207       else if (CONST_INT_P (operands[1])
6208                 && !satisfies_constraint_I (operands[1]))
6209         {
6210           /* Handle loading a large integer during reload.  */
6212           /* Writing a constant to memory needs a scratch, which should
6213              be handled with SECONDARY_RELOADs.  */
6214           gcc_assert (REG_P (operands[0]));
6216           operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
6217           emit_insn (gen_movsi (operands[0], operands[1]));
6218           DONE;
6219         }
6220     }
6221   "
6224 (define_expand "movhi_bytes"
6225   [(set (match_dup 2) (zero_extend:SI (match_operand:HI 1 "" "")))
6226    (set (match_dup 3)
6227         (zero_extend:SI (match_dup 6)))
6228    (set (match_operand:SI 0 "" "")
6229          (ior:SI (ashift:SI (match_dup 4) (const_int 8)) (match_dup 5)))]
6230   "TARGET_ARM"
6231   "
6232   {
6233     rtx mem1, mem2;
6234     rtx addr = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
6236     mem1 = change_address (operands[1], QImode, addr);
6237     mem2 = change_address (operands[1], QImode,
6238                            plus_constant (Pmode, addr, 1));
6239     operands[0] = gen_lowpart (SImode, operands[0]);
6240     operands[1] = mem1;
6241     operands[2] = gen_reg_rtx (SImode);
6242     operands[3] = gen_reg_rtx (SImode);
6243     operands[6] = mem2;
6245     if (BYTES_BIG_ENDIAN)
6246       {
6247         operands[4] = operands[2];
6248         operands[5] = operands[3];
6249       }
6250     else
6251       {
6252         operands[4] = operands[3];
6253         operands[5] = operands[2];
6254       }
6255   }"
6258 (define_expand "movhi_bigend"
6259   [(set (match_dup 2)
6260         (rotate:SI (subreg:SI (match_operand:HI 1 "memory_operand" "") 0)
6261                    (const_int 16)))
6262    (set (match_dup 3)
6263         (ashiftrt:SI (match_dup 2) (const_int 16)))
6264    (set (match_operand:HI 0 "s_register_operand" "")
6265         (match_dup 4))]
6266   "TARGET_ARM"
6267   "
6268   operands[2] = gen_reg_rtx (SImode);
6269   operands[3] = gen_reg_rtx (SImode);
6270   operands[4] = gen_lowpart (HImode, operands[3]);
6271   "
6274 ;; Pattern to recognize insn generated default case above
6275 (define_insn "*movhi_insn_arch4"
6276   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m,r")
6277         (match_operand:HI 1 "general_operand"      "rIk,K,n,r,mi"))]
6278   "TARGET_ARM
6279    && arm_arch4
6280    && (register_operand (operands[0], HImode)
6281        || register_operand (operands[1], HImode))"
6282   "@
6283    mov%?\\t%0, %1\\t%@ movhi
6284    mvn%?\\t%0, #%B1\\t%@ movhi
6285    movw%?\\t%0, %L1\\t%@ movhi
6286    str%(h%)\\t%1, %0\\t%@ movhi
6287    ldr%(h%)\\t%0, %1\\t%@ movhi"
6288   [(set_attr "predicable" "yes")
6289    (set_attr "pool_range" "*,*,*,*,256")
6290    (set_attr "neg_pool_range" "*,*,*,*,244")
6291    (set_attr "arch" "*,*,v6t2,*,*")
6292    (set_attr_alternative "type"
6293                          [(if_then_else (match_operand 1 "const_int_operand" "")
6294                                         (const_string "mov_imm" )
6295                                         (const_string "mov_reg"))
6296                           (const_string "mvn_imm")
6297                           (const_string "mov_imm")
6298                           (const_string "store1")
6299                           (const_string "load1")])]
6302 (define_insn "*movhi_bytes"
6303   [(set (match_operand:HI 0 "s_register_operand" "=r,r,r")
6304         (match_operand:HI 1 "arm_rhs_operand"  "I,rk,K"))]
6305   "TARGET_ARM"
6306   "@
6307    mov%?\\t%0, %1\\t%@ movhi
6308    mov%?\\t%0, %1\\t%@ movhi
6309    mvn%?\\t%0, #%B1\\t%@ movhi"
6310   [(set_attr "predicable" "yes")
6311    (set_attr "type" "mov_imm,mov_reg,mvn_imm")]
6313         
6314 ;; We use a DImode scratch because we may occasionally need an additional
6315 ;; temporary if the address isn't offsettable -- push_reload doesn't seem
6316 ;; to take any notice of the "o" constraints on reload_memory_operand operand.
6317 (define_expand "reload_outhi"
6318   [(parallel [(match_operand:HI 0 "arm_reload_memory_operand" "=o")
6319               (match_operand:HI 1 "s_register_operand"        "r")
6320               (match_operand:DI 2 "s_register_operand"        "=&l")])]
6321   "TARGET_EITHER"
6322   "if (TARGET_ARM)
6323      arm_reload_out_hi (operands);
6324    else
6325      thumb_reload_out_hi (operands);
6326   DONE;
6327   "
6330 (define_expand "reload_inhi"
6331   [(parallel [(match_operand:HI 0 "s_register_operand" "=r")
6332               (match_operand:HI 1 "arm_reload_memory_operand" "o")
6333               (match_operand:DI 2 "s_register_operand" "=&r")])]
6334   "TARGET_EITHER"
6335   "
6336   if (TARGET_ARM)
6337     arm_reload_in_hi (operands);
6338   else
6339     thumb_reload_out_hi (operands);
6340   DONE;
6343 (define_expand "movqi"
6344   [(set (match_operand:QI 0 "general_operand" "")
6345         (match_operand:QI 1 "general_operand" ""))]
6346   "TARGET_EITHER"
6347   "
6348   /* Everything except mem = const or mem = mem can be done easily */
6350   if (can_create_pseudo_p ())
6351     {
6352       if (CONST_INT_P (operands[1]))
6353         {
6354           rtx reg = gen_reg_rtx (SImode);
6356           /* For thumb we want an unsigned immediate, then we are more likely 
6357              to be able to use a movs insn.  */
6358           if (TARGET_THUMB)
6359             operands[1] = GEN_INT (INTVAL (operands[1]) & 255);
6361           emit_insn (gen_movsi (reg, operands[1]));
6362           operands[1] = gen_lowpart (QImode, reg);
6363         }
6365       if (TARGET_THUMB)
6366         {
6367           /* ??? We shouldn't really get invalid addresses here, but this can
6368              happen if we are passed a SP (never OK for HImode/QImode) or
6369              virtual register (also rejected as illegitimate for HImode/QImode)
6370              relative address.  */
6371           /* ??? This should perhaps be fixed elsewhere, for instance, in
6372              fixup_stack_1, by checking for other kinds of invalid addresses,
6373              e.g. a bare reference to a virtual register.  This may confuse the
6374              alpha though, which must handle this case differently.  */
6375           if (MEM_P (operands[0])
6376               && !memory_address_p (GET_MODE (operands[0]),
6377                                      XEXP (operands[0], 0)))
6378             operands[0]
6379               = replace_equiv_address (operands[0],
6380                                        copy_to_reg (XEXP (operands[0], 0)));
6381           if (MEM_P (operands[1])
6382               && !memory_address_p (GET_MODE (operands[1]),
6383                                     XEXP (operands[1], 0)))
6384              operands[1]
6385                = replace_equiv_address (operands[1],
6386                                         copy_to_reg (XEXP (operands[1], 0)));
6387         }
6389       if (MEM_P (operands[1]) && optimize > 0)
6390         {
6391           rtx reg = gen_reg_rtx (SImode);
6393           emit_insn (gen_zero_extendqisi2 (reg, operands[1]));
6394           operands[1] = gen_lowpart (QImode, reg);
6395         }
6397       if (MEM_P (operands[0]))
6398         operands[1] = force_reg (QImode, operands[1]);
6399     }
6400   else if (TARGET_THUMB
6401            && CONST_INT_P (operands[1])
6402            && !satisfies_constraint_I (operands[1]))
6403     {
6404       /* Handle loading a large integer during reload.  */
6406       /* Writing a constant to memory needs a scratch, which should
6407          be handled with SECONDARY_RELOADs.  */
6408       gcc_assert (REG_P (operands[0]));
6410       operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
6411       emit_insn (gen_movsi (operands[0], operands[1]));
6412       DONE;
6413     }
6414   "
6417 (define_insn "*arm_movqi_insn"
6418   [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,r,l,r,l,Uu,r,m")
6419         (match_operand:QI 1 "general_operand" "rk,rk,I,Py,K,Uu,l,Uh,r"))]
6420   "TARGET_32BIT
6421    && (   register_operand (operands[0], QImode)
6422        || register_operand (operands[1], QImode))"
6423   "@
6424    mov%?\\t%0, %1
6425    mov%?\\t%0, %1
6426    mov%?\\t%0, %1
6427    mov%?\\t%0, %1
6428    mvn%?\\t%0, #%B1
6429    ldr%(b%)\\t%0, %1
6430    str%(b%)\\t%1, %0
6431    ldr%(b%)\\t%0, %1
6432    str%(b%)\\t%1, %0"
6433   [(set_attr "type" "mov_reg,mov_reg,mov_imm,mov_imm,mvn_imm,load1,store1,load1,store1")
6434    (set_attr "predicable" "yes")
6435    (set_attr "predicable_short_it" "yes,yes,yes,no,no,no,no,no,no")
6436    (set_attr "arch" "t2,any,any,t2,any,t2,t2,any,any")
6437    (set_attr "length" "2,4,4,2,4,2,2,4,4")]
6440 ;; HFmode moves
6441 (define_expand "movhf"
6442   [(set (match_operand:HF 0 "general_operand" "")
6443         (match_operand:HF 1 "general_operand" ""))]
6444   "TARGET_EITHER"
6445   "
6446   if (TARGET_32BIT)
6447     {
6448       if (MEM_P (operands[0]))
6449         operands[1] = force_reg (HFmode, operands[1]);
6450     }
6451   else /* TARGET_THUMB1 */
6452     {
6453       if (can_create_pseudo_p ())
6454         {
6455            if (!REG_P (operands[0]))
6456              operands[1] = force_reg (HFmode, operands[1]);
6457         }
6458     }
6459   "
6462 (define_insn "*arm32_movhf"
6463   [(set (match_operand:HF 0 "nonimmediate_operand" "=r,m,r,r")
6464         (match_operand:HF 1 "general_operand"      " m,r,r,F"))]
6465   "TARGET_32BIT && !(TARGET_HARD_FLOAT && TARGET_FP16) && !arm_restrict_it
6466    && (   s_register_operand (operands[0], HFmode)
6467        || s_register_operand (operands[1], HFmode))"
6468   "*
6469   switch (which_alternative)
6470     {
6471     case 0:     /* ARM register from memory */
6472       return \"ldr%(h%)\\t%0, %1\\t%@ __fp16\";
6473     case 1:     /* memory from ARM register */
6474       return \"str%(h%)\\t%1, %0\\t%@ __fp16\";
6475     case 2:     /* ARM register from ARM register */
6476       return \"mov%?\\t%0, %1\\t%@ __fp16\";
6477     case 3:     /* ARM register from constant */
6478       {
6479         REAL_VALUE_TYPE r;
6480         long bits;
6481         rtx ops[4];
6483         REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
6484         bits = real_to_target (NULL, &r, HFmode);
6485         ops[0] = operands[0];
6486         ops[1] = GEN_INT (bits);
6487         ops[2] = GEN_INT (bits & 0xff00);
6488         ops[3] = GEN_INT (bits & 0x00ff);
6490         if (arm_arch_thumb2)
6491           output_asm_insn (\"movw%?\\t%0, %1\", ops);
6492         else
6493           output_asm_insn (\"mov%?\\t%0, %2\;orr%?\\t%0, %0, %3\", ops);
6494         return \"\";
6495        }
6496     default:
6497       gcc_unreachable ();
6498     }
6499   "
6500   [(set_attr "conds" "unconditional")
6501    (set_attr "type" "load1,store1,mov_reg,multiple")
6502    (set_attr "length" "4,4,4,8")
6503    (set_attr "predicable" "yes")]
6506 (define_expand "movsf"
6507   [(set (match_operand:SF 0 "general_operand" "")
6508         (match_operand:SF 1 "general_operand" ""))]
6509   "TARGET_EITHER"
6510   "
6511   if (TARGET_32BIT)
6512     {
6513       if (MEM_P (operands[0]))
6514         operands[1] = force_reg (SFmode, operands[1]);
6515     }
6516   else /* TARGET_THUMB1 */
6517     {
6518       if (can_create_pseudo_p ())
6519         {
6520            if (!REG_P (operands[0]))
6521              operands[1] = force_reg (SFmode, operands[1]);
6522         }
6523     }
6524   "
6527 ;; Transform a floating-point move of a constant into a core register into
6528 ;; an SImode operation.
6529 (define_split
6530   [(set (match_operand:SF 0 "arm_general_register_operand" "")
6531         (match_operand:SF 1 "immediate_operand" ""))]
6532   "TARGET_EITHER
6533    && reload_completed
6534    && CONST_DOUBLE_P (operands[1])"
6535   [(set (match_dup 2) (match_dup 3))]
6536   "
6537   operands[2] = gen_lowpart (SImode, operands[0]);
6538   operands[3] = gen_lowpart (SImode, operands[1]);
6539   if (operands[2] == 0 || operands[3] == 0)
6540     FAIL;
6541   "
6544 (define_insn "*arm_movsf_soft_insn"
6545   [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,m")
6546         (match_operand:SF 1 "general_operand"  "r,mE,r"))]
6547   "TARGET_32BIT
6548    && TARGET_SOFT_FLOAT
6549    && (!MEM_P (operands[0])
6550        || register_operand (operands[1], SFmode))"
6551   "@
6552    mov%?\\t%0, %1
6553    ldr%?\\t%0, %1\\t%@ float
6554    str%?\\t%1, %0\\t%@ float"
6555   [(set_attr "predicable" "yes")
6556    (set_attr "predicable_short_it" "no")
6557    (set_attr "type" "mov_reg,load1,store1")
6558    (set_attr "arm_pool_range" "*,4096,*")
6559    (set_attr "thumb2_pool_range" "*,4094,*")
6560    (set_attr "arm_neg_pool_range" "*,4084,*")
6561    (set_attr "thumb2_neg_pool_range" "*,0,*")]
6564 (define_expand "movdf"
6565   [(set (match_operand:DF 0 "general_operand" "")
6566         (match_operand:DF 1 "general_operand" ""))]
6567   "TARGET_EITHER"
6568   "
6569   if (TARGET_32BIT)
6570     {
6571       if (MEM_P (operands[0]))
6572         operands[1] = force_reg (DFmode, operands[1]);
6573     }
6574   else /* TARGET_THUMB */
6575     {
6576       if (can_create_pseudo_p ())
6577         {
6578           if (!REG_P (operands[0]))
6579             operands[1] = force_reg (DFmode, operands[1]);
6580         }
6581     }
6582   "
6585 ;; Reloading a df mode value stored in integer regs to memory can require a
6586 ;; scratch reg.
6587 (define_expand "reload_outdf"
6588   [(match_operand:DF 0 "arm_reload_memory_operand" "=o")
6589    (match_operand:DF 1 "s_register_operand" "r")
6590    (match_operand:SI 2 "s_register_operand" "=&r")]
6591   "TARGET_THUMB2"
6592   "
6593   {
6594     enum rtx_code code = GET_CODE (XEXP (operands[0], 0));
6596     if (code == REG)
6597       operands[2] = XEXP (operands[0], 0);
6598     else if (code == POST_INC || code == PRE_DEC)
6599       {
6600         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
6601         operands[1] = gen_rtx_SUBREG (DImode, operands[1], 0);
6602         emit_insn (gen_movdi (operands[0], operands[1]));
6603         DONE;
6604       }
6605     else if (code == PRE_INC)
6606       {
6607         rtx reg = XEXP (XEXP (operands[0], 0), 0);
6609         emit_insn (gen_addsi3 (reg, reg, GEN_INT (8)));
6610         operands[2] = reg;
6611       }
6612     else if (code == POST_DEC)
6613       operands[2] = XEXP (XEXP (operands[0], 0), 0);
6614     else
6615       emit_insn (gen_addsi3 (operands[2], XEXP (XEXP (operands[0], 0), 0),
6616                              XEXP (XEXP (operands[0], 0), 1)));
6618     emit_insn (gen_rtx_SET (replace_equiv_address (operands[0], operands[2]),
6619                             operands[1]));
6621     if (code == POST_DEC)
6622       emit_insn (gen_addsi3 (operands[2], operands[2], GEN_INT (-8)));
6624     DONE;
6625   }"
6628 (define_insn "*movdf_soft_insn"
6629   [(set (match_operand:DF 0 "nonimmediate_soft_df_operand" "=r,r,r,q,m")
6630         (match_operand:DF 1 "soft_df_operand" "rDa,Db,Dc,mF,q"))]
6631   "TARGET_32BIT && TARGET_SOFT_FLOAT
6632    && (   register_operand (operands[0], DFmode)
6633        || register_operand (operands[1], DFmode))"
6634   "*
6635   switch (which_alternative)
6636     {
6637     case 0:
6638     case 1:
6639     case 2:
6640       return \"#\";
6641     default:
6642       return output_move_double (operands, true, NULL);
6643     }
6644   "
6645   [(set_attr "length" "8,12,16,8,8")
6646    (set_attr "type" "multiple,multiple,multiple,load2,store2")
6647    (set_attr "arm_pool_range" "*,*,*,1020,*")
6648    (set_attr "thumb2_pool_range" "*,*,*,1018,*")
6649    (set_attr "arm_neg_pool_range" "*,*,*,1004,*")
6650    (set_attr "thumb2_neg_pool_range" "*,*,*,0,*")]
6654 ;; load- and store-multiple insns
6655 ;; The arm can load/store any set of registers, provided that they are in
6656 ;; ascending order, but these expanders assume a contiguous set.
6658 (define_expand "load_multiple"
6659   [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
6660                           (match_operand:SI 1 "" ""))
6661                      (use (match_operand:SI 2 "" ""))])]
6662   "TARGET_32BIT"
6664   HOST_WIDE_INT offset = 0;
6666   /* Support only fixed point registers.  */
6667   if (!CONST_INT_P (operands[2])
6668       || INTVAL (operands[2]) > MAX_LDM_STM_OPS
6669       || INTVAL (operands[2]) < 2
6670       || !MEM_P (operands[1])
6671       || !REG_P (operands[0])
6672       || REGNO (operands[0]) > (LAST_ARM_REGNUM - 1)
6673       || REGNO (operands[0]) + INTVAL (operands[2]) > LAST_ARM_REGNUM)
6674     FAIL;
6676   operands[3]
6677     = arm_gen_load_multiple (arm_regs_in_sequence + REGNO (operands[0]),
6678                              INTVAL (operands[2]),
6679                              force_reg (SImode, XEXP (operands[1], 0)),
6680                              FALSE, operands[1], &offset);
6683 (define_expand "store_multiple"
6684   [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
6685                           (match_operand:SI 1 "" ""))
6686                      (use (match_operand:SI 2 "" ""))])]
6687   "TARGET_32BIT"
6689   HOST_WIDE_INT offset = 0;
6691   /* Support only fixed point registers.  */
6692   if (!CONST_INT_P (operands[2])
6693       || INTVAL (operands[2]) > MAX_LDM_STM_OPS
6694       || INTVAL (operands[2]) < 2
6695       || !REG_P (operands[1])
6696       || !MEM_P (operands[0])
6697       || REGNO (operands[1]) > (LAST_ARM_REGNUM - 1)
6698       || REGNO (operands[1]) + INTVAL (operands[2]) > LAST_ARM_REGNUM)
6699     FAIL;
6701   operands[3]
6702     = arm_gen_store_multiple (arm_regs_in_sequence + REGNO (operands[1]),
6703                               INTVAL (operands[2]),
6704                               force_reg (SImode, XEXP (operands[0], 0)),
6705                               FALSE, operands[0], &offset);
6709 (define_expand "setmemsi"
6710   [(match_operand:BLK 0 "general_operand" "")
6711    (match_operand:SI 1 "const_int_operand" "")
6712    (match_operand:SI 2 "const_int_operand" "")
6713    (match_operand:SI 3 "const_int_operand" "")]
6714   "TARGET_32BIT"
6716   if (arm_gen_setmem (operands))
6717     DONE;
6719   FAIL;
6723 ;; Move a block of memory if it is word aligned and MORE than 2 words long.
6724 ;; We could let this apply for blocks of less than this, but it clobbers so
6725 ;; many registers that there is then probably a better way.
6727 (define_expand "movmemqi"
6728   [(match_operand:BLK 0 "general_operand" "")
6729    (match_operand:BLK 1 "general_operand" "")
6730    (match_operand:SI 2 "const_int_operand" "")
6731    (match_operand:SI 3 "const_int_operand" "")]
6732   ""
6733   "
6734   if (TARGET_32BIT)
6735     {
6736       if (TARGET_LDRD && current_tune->prefer_ldrd_strd
6737           && !optimize_function_for_size_p (cfun))
6738         {
6739           if (gen_movmem_ldrd_strd (operands))
6740             DONE;
6741           FAIL;
6742         }
6744       if (arm_gen_movmemqi (operands))
6745         DONE;
6746       FAIL;
6747     }
6748   else /* TARGET_THUMB1 */
6749     {
6750       if (   INTVAL (operands[3]) != 4
6751           || INTVAL (operands[2]) > 48)
6752         FAIL;
6754       thumb_expand_movmemqi (operands);
6755       DONE;
6756     }
6757   "
6761 ;; Compare & branch insns
6762 ;; The range calculations are based as follows:
6763 ;; For forward branches, the address calculation returns the address of
6764 ;; the next instruction.  This is 2 beyond the branch instruction.
6765 ;; For backward branches, the address calculation returns the address of
6766 ;; the first instruction in this pattern (cmp).  This is 2 before the branch
6767 ;; instruction for the shortest sequence, and 4 before the branch instruction
6768 ;; if we have to jump around an unconditional branch.
6769 ;; To the basic branch range the PC offset must be added (this is +4).
6770 ;; So for forward branches we have 
6771 ;;   (pos_range - pos_base_offs + pc_offs) = (pos_range - 2 + 4).
6772 ;; And for backward branches we have 
6773 ;;   (neg_range - neg_base_offs + pc_offs) = (neg_range - (-2 or -4) + 4).
6775 ;; For a 'b'       pos_range = 2046, neg_range = -2048 giving (-2040->2048).
6776 ;; For a 'b<cond>' pos_range = 254,  neg_range = -256  giving (-250 ->256).
6778 (define_expand "cbranchsi4"
6779   [(set (pc) (if_then_else
6780               (match_operator 0 "expandable_comparison_operator"
6781                [(match_operand:SI 1 "s_register_operand" "")
6782                 (match_operand:SI 2 "nonmemory_operand" "")])
6783               (label_ref (match_operand 3 "" ""))
6784               (pc)))]
6785   "TARGET_EITHER"
6786   "
6787   if (!TARGET_THUMB1)
6788     {
6789       if (!arm_validize_comparison (&operands[0], &operands[1], &operands[2]))
6790         FAIL;
6791       emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
6792                                       operands[3]));
6793       DONE;
6794     }
6795   if (thumb1_cmpneg_operand (operands[2], SImode))
6796     {
6797       emit_jump_insn (gen_cbranchsi4_scratch (NULL, operands[1], operands[2],
6798                                               operands[3], operands[0]));
6799       DONE;
6800     }
6801   if (!thumb1_cmp_operand (operands[2], SImode))
6802     operands[2] = force_reg (SImode, operands[2]);
6803   ")
6805 (define_expand "cbranchsf4"
6806   [(set (pc) (if_then_else
6807               (match_operator 0 "expandable_comparison_operator"
6808                [(match_operand:SF 1 "s_register_operand" "")
6809                 (match_operand:SF 2 "arm_float_compare_operand" "")])
6810               (label_ref (match_operand 3 "" ""))
6811               (pc)))]
6812   "TARGET_32BIT && TARGET_HARD_FLOAT"
6813   "emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
6814                                    operands[3])); DONE;"
6817 (define_expand "cbranchdf4"
6818   [(set (pc) (if_then_else
6819               (match_operator 0 "expandable_comparison_operator"
6820                [(match_operand:DF 1 "s_register_operand" "")
6821                 (match_operand:DF 2 "arm_float_compare_operand" "")])
6822               (label_ref (match_operand 3 "" ""))
6823               (pc)))]
6824   "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
6825   "emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
6826                                    operands[3])); DONE;"
6829 (define_expand "cbranchdi4"
6830   [(set (pc) (if_then_else
6831               (match_operator 0 "expandable_comparison_operator"
6832                [(match_operand:DI 1 "s_register_operand" "")
6833                 (match_operand:DI 2 "cmpdi_operand" "")])
6834               (label_ref (match_operand 3 "" ""))
6835               (pc)))]
6836   "TARGET_32BIT"
6837   "{
6838      if (!arm_validize_comparison (&operands[0], &operands[1], &operands[2]))
6839        FAIL;
6840      emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
6841                                        operands[3]));
6842      DONE;
6843    }"
6846 ;; Comparison and test insns
6848 (define_insn "*arm_cmpsi_insn"
6849   [(set (reg:CC CC_REGNUM)
6850         (compare:CC (match_operand:SI 0 "s_register_operand" "l,r,r,r,r")
6851                     (match_operand:SI 1 "arm_add_operand"    "Py,r,r,I,L")))]
6852   "TARGET_32BIT"
6853   "@
6854    cmp%?\\t%0, %1
6855    cmp%?\\t%0, %1
6856    cmp%?\\t%0, %1
6857    cmp%?\\t%0, %1
6858    cmn%?\\t%0, #%n1"
6859   [(set_attr "conds" "set")
6860    (set_attr "arch" "t2,t2,any,any,any")
6861    (set_attr "length" "2,2,4,4,4")
6862    (set_attr "predicable" "yes")
6863    (set_attr "predicable_short_it" "yes,yes,yes,no,no")
6864    (set_attr "type" "alus_imm,alus_sreg,alus_sreg,alus_imm,alus_imm")]
6867 (define_insn "*cmpsi_shiftsi"
6868   [(set (reg:CC CC_REGNUM)
6869         (compare:CC (match_operand:SI   0 "s_register_operand" "r,r,r")
6870                     (match_operator:SI  3 "shift_operator"
6871                      [(match_operand:SI 1 "s_register_operand" "r,r,r")
6872                       (match_operand:SI 2 "shift_amount_operand" "M,r,M")])))]
6873   "TARGET_32BIT"
6874   "cmp\\t%0, %1%S3"
6875   [(set_attr "conds" "set")
6876    (set_attr "shift" "1")
6877    (set_attr "arch" "32,a,a")
6878    (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
6880 (define_insn "*cmpsi_shiftsi_swp"
6881   [(set (reg:CC_SWP CC_REGNUM)
6882         (compare:CC_SWP (match_operator:SI 3 "shift_operator"
6883                          [(match_operand:SI 1 "s_register_operand" "r,r,r")
6884                           (match_operand:SI 2 "shift_amount_operand" "M,r,M")])
6885                         (match_operand:SI 0 "s_register_operand" "r,r,r")))]
6886   "TARGET_32BIT"
6887   "cmp%?\\t%0, %1%S3"
6888   [(set_attr "conds" "set")
6889    (set_attr "shift" "1")
6890    (set_attr "arch" "32,a,a")
6891    (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
6893 (define_insn "*arm_cmpsi_negshiftsi_si"
6894   [(set (reg:CC_Z CC_REGNUM)
6895         (compare:CC_Z
6896          (neg:SI (match_operator:SI 1 "shift_operator"
6897                     [(match_operand:SI 2 "s_register_operand" "r")
6898                      (match_operand:SI 3 "reg_or_int_operand" "rM")]))
6899          (match_operand:SI 0 "s_register_operand" "r")))]
6900   "TARGET_ARM"
6901   "cmn%?\\t%0, %2%S1"
6902   [(set_attr "conds" "set")
6903    (set (attr "type") (if_then_else (match_operand 3 "const_int_operand" "")
6904                                     (const_string "alus_shift_imm")
6905                                     (const_string "alus_shift_reg")))
6906    (set_attr "predicable" "yes")]
6909 ;; DImode comparisons.  The generic code generates branches that
6910 ;; if-conversion can not reduce to a conditional compare, so we do
6911 ;; that directly.
6913 (define_insn_and_split "*arm_cmpdi_insn"
6914   [(set (reg:CC_NCV CC_REGNUM)
6915         (compare:CC_NCV (match_operand:DI 0 "s_register_operand" "r")
6916                         (match_operand:DI 1 "arm_di_operand"       "rDi")))
6917    (clobber (match_scratch:SI 2 "=r"))]
6918   "TARGET_32BIT"
6919   "#"   ; "cmp\\t%Q0, %Q1\;sbcs\\t%2, %R0, %R1"
6920   "&& reload_completed"
6921   [(set (reg:CC CC_REGNUM)
6922         (compare:CC (match_dup 0) (match_dup 1)))
6923    (parallel [(set (reg:CC CC_REGNUM)
6924                    (compare:CC (match_dup 3) (match_dup 4)))
6925               (set (match_dup 2)
6926                    (minus:SI (match_dup 5)
6927                             (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))])]
6928   {
6929     operands[3] = gen_highpart (SImode, operands[0]);
6930     operands[0] = gen_lowpart (SImode, operands[0]);
6931     if (CONST_INT_P (operands[1]))
6932       {
6933         operands[4] = GEN_INT (~INTVAL (gen_highpart_mode (SImode,
6934                                                            DImode,
6935                                                            operands[1])));
6936         operands[5] = gen_rtx_PLUS (SImode, operands[3], operands[4]);
6937       }
6938     else
6939       {
6940         operands[4] = gen_highpart (SImode, operands[1]);
6941         operands[5] = gen_rtx_MINUS (SImode, operands[3], operands[4]);
6942       }
6943     operands[1] = gen_lowpart (SImode, operands[1]);
6944     operands[2] = gen_lowpart (SImode, operands[2]);
6945   }
6946   [(set_attr "conds" "set")
6947    (set_attr "length" "8")
6948    (set_attr "type" "multiple")]
6951 (define_insn_and_split "*arm_cmpdi_unsigned"
6952   [(set (reg:CC_CZ CC_REGNUM)
6953         (compare:CC_CZ (match_operand:DI 0 "s_register_operand" "l,r,r,r")
6954                        (match_operand:DI 1 "arm_di_operand"     "Py,r,Di,rDi")))]
6956   "TARGET_32BIT"
6957   "#"   ; "cmp\\t%R0, %R1\;it eq\;cmpeq\\t%Q0, %Q1"
6958   "&& reload_completed"
6959   [(set (reg:CC CC_REGNUM)
6960         (compare:CC (match_dup 2) (match_dup 3)))
6961    (cond_exec (eq:SI (reg:CC CC_REGNUM) (const_int 0))
6962               (set (reg:CC CC_REGNUM)
6963                    (compare:CC (match_dup 0) (match_dup 1))))]
6964   {
6965     operands[2] = gen_highpart (SImode, operands[0]);
6966     operands[0] = gen_lowpart (SImode, operands[0]);
6967     if (CONST_INT_P (operands[1]))
6968       operands[3] = gen_highpart_mode (SImode, DImode, operands[1]);
6969     else
6970       operands[3] = gen_highpart (SImode, operands[1]);
6971     operands[1] = gen_lowpart (SImode, operands[1]);
6972   }
6973   [(set_attr "conds" "set")
6974    (set_attr "enabled_for_depr_it" "yes,yes,no,*")
6975    (set_attr "arch" "t2,t2,t2,a")
6976    (set_attr "length" "6,6,10,8")
6977    (set_attr "type" "multiple")]
6980 (define_insn "*arm_cmpdi_zero"
6981   [(set (reg:CC_Z CC_REGNUM)
6982         (compare:CC_Z (match_operand:DI 0 "s_register_operand" "r")
6983                       (const_int 0)))
6984    (clobber (match_scratch:SI 1 "=r"))]
6985   "TARGET_32BIT"
6986   "orr%.\\t%1, %Q0, %R0"
6987   [(set_attr "conds" "set")
6988    (set_attr "type" "logics_reg")]
6991 ; This insn allows redundant compares to be removed by cse, nothing should
6992 ; ever appear in the output file since (set (reg x) (reg x)) is a no-op that
6993 ; is deleted later on. The match_dup will match the mode here, so that
6994 ; mode changes of the condition codes aren't lost by this even though we don't
6995 ; specify what they are.
6997 (define_insn "*deleted_compare"
6998   [(set (match_operand 0 "cc_register" "") (match_dup 0))]
6999   "TARGET_32BIT"
7000   "\\t%@ deleted compare"
7001   [(set_attr "conds" "set")
7002    (set_attr "length" "0")
7003    (set_attr "type" "no_insn")]
7007 ;; Conditional branch insns
7009 (define_expand "cbranch_cc"
7010   [(set (pc)
7011         (if_then_else (match_operator 0 "" [(match_operand 1 "" "")
7012                                             (match_operand 2 "" "")])
7013                       (label_ref (match_operand 3 "" ""))
7014                       (pc)))]
7015   "TARGET_32BIT"
7016   "operands[1] = arm_gen_compare_reg (GET_CODE (operands[0]),
7017                                       operands[1], operands[2], NULL_RTX);
7018    operands[2] = const0_rtx;"
7022 ;; Patterns to match conditional branch insns.
7025 (define_insn "arm_cond_branch"
7026   [(set (pc)
7027         (if_then_else (match_operator 1 "arm_comparison_operator"
7028                        [(match_operand 2 "cc_register" "") (const_int 0)])
7029                       (label_ref (match_operand 0 "" ""))
7030                       (pc)))]
7031   "TARGET_32BIT"
7032   "*
7033   if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
7034     {
7035       arm_ccfsm_state += 2;
7036       return \"\";
7037     }
7038   return \"b%d1\\t%l0\";
7039   "
7040   [(set_attr "conds" "use")
7041    (set_attr "type" "branch")
7042    (set (attr "length")
7043         (if_then_else
7044            (and (match_test "TARGET_THUMB2")
7045                 (and (ge (minus (match_dup 0) (pc)) (const_int -250))
7046                      (le (minus (match_dup 0) (pc)) (const_int 256))))
7047            (const_int 2)
7048            (const_int 4)))]
7051 (define_insn "*arm_cond_branch_reversed"
7052   [(set (pc)
7053         (if_then_else (match_operator 1 "arm_comparison_operator"
7054                        [(match_operand 2 "cc_register" "") (const_int 0)])
7055                       (pc)
7056                       (label_ref (match_operand 0 "" ""))))]
7057   "TARGET_32BIT"
7058   "*
7059   if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
7060     {
7061       arm_ccfsm_state += 2;
7062       return \"\";
7063     }
7064   return \"b%D1\\t%l0\";
7065   "
7066   [(set_attr "conds" "use")
7067    (set_attr "type" "branch")
7068    (set (attr "length")
7069         (if_then_else
7070            (and (match_test "TARGET_THUMB2")
7071                 (and (ge (minus (match_dup 0) (pc)) (const_int -250))
7072                      (le (minus (match_dup 0) (pc)) (const_int 256))))
7073            (const_int 2)
7074            (const_int 4)))]
7079 ; scc insns
7081 (define_expand "cstore_cc"
7082   [(set (match_operand:SI 0 "s_register_operand" "")
7083         (match_operator:SI 1 "" [(match_operand 2 "" "")
7084                                  (match_operand 3 "" "")]))]
7085   "TARGET_32BIT"
7086   "operands[2] = arm_gen_compare_reg (GET_CODE (operands[1]),
7087                                       operands[2], operands[3], NULL_RTX);
7088    operands[3] = const0_rtx;"
7091 (define_insn_and_split "*mov_scc"
7092   [(set (match_operand:SI 0 "s_register_operand" "=r")
7093         (match_operator:SI 1 "arm_comparison_operator"
7094          [(match_operand 2 "cc_register" "") (const_int 0)]))]
7095   "TARGET_ARM"
7096   "#"   ; "mov%D1\\t%0, #0\;mov%d1\\t%0, #1"
7097   "TARGET_ARM"
7098   [(set (match_dup 0)
7099         (if_then_else:SI (match_dup 1)
7100                          (const_int 1)
7101                          (const_int 0)))]
7102   ""
7103   [(set_attr "conds" "use")
7104    (set_attr "length" "8")
7105    (set_attr "type" "multiple")]
7108 (define_insn_and_split "*mov_negscc"
7109   [(set (match_operand:SI 0 "s_register_operand" "=r")
7110         (neg:SI (match_operator:SI 1 "arm_comparison_operator"
7111                  [(match_operand 2 "cc_register" "") (const_int 0)])))]
7112   "TARGET_ARM"
7113   "#"   ; "mov%D1\\t%0, #0\;mvn%d1\\t%0, #0"
7114   "TARGET_ARM"
7115   [(set (match_dup 0)
7116         (if_then_else:SI (match_dup 1)
7117                          (match_dup 3)
7118                          (const_int 0)))]
7119   {
7120     operands[3] = GEN_INT (~0);
7121   }
7122   [(set_attr "conds" "use")
7123    (set_attr "length" "8")
7124    (set_attr "type" "multiple")]
7127 (define_insn_and_split "*mov_notscc"
7128   [(set (match_operand:SI 0 "s_register_operand" "=r")
7129         (not:SI (match_operator:SI 1 "arm_comparison_operator"
7130                  [(match_operand 2 "cc_register" "") (const_int 0)])))]
7131   "TARGET_ARM"
7132   "#"   ; "mvn%D1\\t%0, #0\;mvn%d1\\t%0, #1"
7133   "TARGET_ARM"
7134   [(set (match_dup 0)
7135         (if_then_else:SI (match_dup 1)
7136                          (match_dup 3)
7137                          (match_dup 4)))]
7138   {
7139     operands[3] = GEN_INT (~1);
7140     operands[4] = GEN_INT (~0);
7141   }
7142   [(set_attr "conds" "use")
7143    (set_attr "length" "8")
7144    (set_attr "type" "multiple")]
7147 (define_expand "cstoresi4"
7148   [(set (match_operand:SI 0 "s_register_operand" "")
7149         (match_operator:SI 1 "expandable_comparison_operator"
7150          [(match_operand:SI 2 "s_register_operand" "")
7151           (match_operand:SI 3 "reg_or_int_operand" "")]))]
7152   "TARGET_32BIT || TARGET_THUMB1"
7153   "{
7154   rtx op3, scratch, scratch2;
7156   if (!TARGET_THUMB1)
7157     {
7158       if (!arm_add_operand (operands[3], SImode))
7159         operands[3] = force_reg (SImode, operands[3]);
7160       emit_insn (gen_cstore_cc (operands[0], operands[1],
7161                                 operands[2], operands[3]));
7162       DONE;
7163     }
7165   if (operands[3] == const0_rtx)
7166     {
7167       switch (GET_CODE (operands[1]))
7168         {
7169         case EQ:
7170           emit_insn (gen_cstoresi_eq0_thumb1 (operands[0], operands[2]));
7171           break;
7173         case NE:
7174           emit_insn (gen_cstoresi_ne0_thumb1 (operands[0], operands[2]));
7175           break;
7177         case LE:
7178           scratch = expand_binop (SImode, add_optab, operands[2], constm1_rtx,
7179                                   NULL_RTX, 0, OPTAB_WIDEN);
7180           scratch = expand_binop (SImode, ior_optab, operands[2], scratch,
7181                                   NULL_RTX, 0, OPTAB_WIDEN);
7182           expand_binop (SImode, lshr_optab, scratch, GEN_INT (31),
7183                         operands[0], 1, OPTAB_WIDEN);
7184           break;
7186         case GE:
7187           scratch = expand_unop (SImode, one_cmpl_optab, operands[2],
7188                                  NULL_RTX, 1);
7189           expand_binop (SImode, lshr_optab, scratch, GEN_INT (31),
7190                         NULL_RTX, 1, OPTAB_WIDEN);
7191           break;
7193         case GT:
7194           scratch = expand_binop (SImode, ashr_optab, operands[2],
7195                                   GEN_INT (31), NULL_RTX, 0, OPTAB_WIDEN);
7196           scratch = expand_binop (SImode, sub_optab, scratch, operands[2],
7197                                   NULL_RTX, 0, OPTAB_WIDEN);
7198           expand_binop (SImode, lshr_optab, scratch, GEN_INT (31), operands[0],
7199                         0, OPTAB_WIDEN);
7200           break;
7202         /* LT is handled by generic code.  No need for unsigned with 0.  */
7203         default:
7204           FAIL;
7205         }
7206       DONE;
7207     }
7209   switch (GET_CODE (operands[1]))
7210     {
7211     case EQ:
7212       scratch = expand_binop (SImode, sub_optab, operands[2], operands[3],
7213                               NULL_RTX, 0, OPTAB_WIDEN);
7214       emit_insn (gen_cstoresi_eq0_thumb1 (operands[0], scratch));
7215       break;
7217     case NE:
7218       scratch = expand_binop (SImode, sub_optab, operands[2], operands[3],
7219                               NULL_RTX, 0, OPTAB_WIDEN);
7220       emit_insn (gen_cstoresi_ne0_thumb1 (operands[0], scratch));
7221       break;
7223     case LE:
7224       op3 = force_reg (SImode, operands[3]);
7226       scratch = expand_binop (SImode, lshr_optab, operands[2], GEN_INT (31),
7227                               NULL_RTX, 1, OPTAB_WIDEN);
7228       scratch2 = expand_binop (SImode, ashr_optab, op3, GEN_INT (31),
7229                               NULL_RTX, 0, OPTAB_WIDEN);
7230       emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch2,
7231                                           op3, operands[2]));
7232       break;
7234     case GE:
7235       op3 = operands[3];
7236       if (!thumb1_cmp_operand (op3, SImode))
7237         op3 = force_reg (SImode, op3);
7238       scratch = expand_binop (SImode, ashr_optab, operands[2], GEN_INT (31),
7239                               NULL_RTX, 0, OPTAB_WIDEN);
7240       scratch2 = expand_binop (SImode, lshr_optab, op3, GEN_INT (31),
7241                                NULL_RTX, 1, OPTAB_WIDEN);
7242       emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch2,
7243                                           operands[2], op3));
7244       break;
7246     case LEU:
7247       op3 = force_reg (SImode, operands[3]);
7248       scratch = force_reg (SImode, const0_rtx);
7249       emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch,
7250                                           op3, operands[2]));
7251       break;
7253     case GEU:
7254       op3 = operands[3];
7255       if (!thumb1_cmp_operand (op3, SImode))
7256         op3 = force_reg (SImode, op3);
7257       scratch = force_reg (SImode, const0_rtx);
7258       emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch,
7259                                           operands[2], op3));
7260       break;
7262     case LTU:
7263       op3 = operands[3];
7264       if (!thumb1_cmp_operand (op3, SImode))
7265         op3 = force_reg (SImode, op3);
7266       scratch = gen_reg_rtx (SImode);
7267       emit_insn (gen_cstoresi_ltu_thumb1 (operands[0], operands[2], op3));
7268       break;
7270     case GTU:
7271       op3 = force_reg (SImode, operands[3]);
7272       scratch = gen_reg_rtx (SImode);
7273       emit_insn (gen_cstoresi_ltu_thumb1 (operands[0], op3, operands[2]));
7274       break;
7276     /* No good sequences for GT, LT.  */
7277     default:
7278       FAIL;
7279     }
7280   DONE;
7283 (define_expand "cstoresf4"
7284   [(set (match_operand:SI 0 "s_register_operand" "")
7285         (match_operator:SI 1 "expandable_comparison_operator"
7286          [(match_operand:SF 2 "s_register_operand" "")
7287           (match_operand:SF 3 "arm_float_compare_operand" "")]))]
7288   "TARGET_32BIT && TARGET_HARD_FLOAT"
7289   "emit_insn (gen_cstore_cc (operands[0], operands[1],
7290                              operands[2], operands[3])); DONE;"
7293 (define_expand "cstoredf4"
7294   [(set (match_operand:SI 0 "s_register_operand" "")
7295         (match_operator:SI 1 "expandable_comparison_operator"
7296          [(match_operand:DF 2 "s_register_operand" "")
7297           (match_operand:DF 3 "arm_float_compare_operand" "")]))]
7298   "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
7299   "emit_insn (gen_cstore_cc (operands[0], operands[1],
7300                              operands[2], operands[3])); DONE;"
7303 (define_expand "cstoredi4"
7304   [(set (match_operand:SI 0 "s_register_operand" "")
7305         (match_operator:SI 1 "expandable_comparison_operator"
7306          [(match_operand:DI 2 "s_register_operand" "")
7307           (match_operand:DI 3 "cmpdi_operand" "")]))]
7308   "TARGET_32BIT"
7309   "{
7310      if (!arm_validize_comparison (&operands[1],
7311                                    &operands[2],
7312                                    &operands[3]))
7313        FAIL;
7314      emit_insn (gen_cstore_cc (operands[0], operands[1], operands[2],
7315                                  operands[3]));
7316      DONE;
7317    }"
7321 ;; Conditional move insns
7323 (define_expand "movsicc"
7324   [(set (match_operand:SI 0 "s_register_operand" "")
7325         (if_then_else:SI (match_operand 1 "expandable_comparison_operator" "")
7326                          (match_operand:SI 2 "arm_not_operand" "")
7327                          (match_operand:SI 3 "arm_not_operand" "")))]
7328   "TARGET_32BIT"
7329   "
7330   {
7331     enum rtx_code code;
7332     rtx ccreg;
7334     if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0), 
7335                                   &XEXP (operands[1], 1)))
7336       FAIL;
7337     
7338     code = GET_CODE (operands[1]);
7339     ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
7340                                  XEXP (operands[1], 1), NULL_RTX);
7341     operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7342   }"
7345 (define_expand "movsfcc"
7346   [(set (match_operand:SF 0 "s_register_operand" "")
7347         (if_then_else:SF (match_operand 1 "arm_cond_move_operator" "")
7348                          (match_operand:SF 2 "s_register_operand" "")
7349                          (match_operand:SF 3 "s_register_operand" "")))]
7350   "TARGET_32BIT && TARGET_HARD_FLOAT"
7351   "
7352   {
7353     enum rtx_code code = GET_CODE (operands[1]);
7354     rtx ccreg;
7356     if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0), 
7357                                   &XEXP (operands[1], 1)))
7358        FAIL;
7360     code = GET_CODE (operands[1]);
7361     ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
7362                                  XEXP (operands[1], 1), NULL_RTX);
7363     operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7364   }"
7367 (define_expand "movdfcc"
7368   [(set (match_operand:DF 0 "s_register_operand" "")
7369         (if_then_else:DF (match_operand 1 "arm_cond_move_operator" "")
7370                          (match_operand:DF 2 "s_register_operand" "")
7371                          (match_operand:DF 3 "s_register_operand" "")))]
7372   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
7373   "
7374   {
7375     enum rtx_code code = GET_CODE (operands[1]);
7376     rtx ccreg;
7378     if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0), 
7379                                   &XEXP (operands[1], 1)))
7380        FAIL;
7381     code = GET_CODE (operands[1]);
7382     ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
7383                                  XEXP (operands[1], 1), NULL_RTX);
7384     operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7385   }"
7388 (define_insn "*cmov<mode>"
7389     [(set (match_operand:SDF 0 "s_register_operand" "=<F_constraint>")
7390         (if_then_else:SDF (match_operator 1 "arm_vsel_comparison_operator"
7391                           [(match_operand 2 "cc_register" "") (const_int 0)])
7392                           (match_operand:SDF 3 "s_register_operand"
7393                                               "<F_constraint>")
7394                           (match_operand:SDF 4 "s_register_operand"
7395                                               "<F_constraint>")))]
7396   "TARGET_HARD_FLOAT && TARGET_FPU_ARMV8 <vfp_double_cond>"
7397   "*
7398   {
7399     enum arm_cond_code code = maybe_get_arm_condition_code (operands[1]);
7400     switch (code)
7401       {
7402       case ARM_GE:
7403       case ARM_GT:
7404       case ARM_EQ:
7405       case ARM_VS:
7406         return \"vsel%d1.<V_if_elem>\\t%<V_reg>0, %<V_reg>3, %<V_reg>4\";
7407       case ARM_LT:
7408       case ARM_LE:
7409       case ARM_NE:
7410       case ARM_VC:
7411         return \"vsel%D1.<V_if_elem>\\t%<V_reg>0, %<V_reg>4, %<V_reg>3\";
7412       default:
7413         gcc_unreachable ();
7414       }
7415     return \"\";
7416   }"
7417   [(set_attr "conds" "use")
7418    (set_attr "type" "fcsel")]
7421 (define_insn_and_split "*movsicc_insn"
7422   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r,r,r,r,r")
7423         (if_then_else:SI
7424          (match_operator 3 "arm_comparison_operator"
7425           [(match_operand 4 "cc_register" "") (const_int 0)])
7426          (match_operand:SI 1 "arm_not_operand" "0,0,rI,K,rI,rI,K,K")
7427          (match_operand:SI 2 "arm_not_operand" "rI,K,0,0,rI,K,rI,K")))]
7428   "TARGET_ARM"
7429   "@
7430    mov%D3\\t%0, %2
7431    mvn%D3\\t%0, #%B2
7432    mov%d3\\t%0, %1
7433    mvn%d3\\t%0, #%B1
7434    #
7435    #
7436    #
7437    #"
7438    ; alt4: mov%d3\\t%0, %1\;mov%D3\\t%0, %2
7439    ; alt5: mov%d3\\t%0, %1\;mvn%D3\\t%0, #%B2
7440    ; alt6: mvn%d3\\t%0, #%B1\;mov%D3\\t%0, %2
7441    ; alt7: mvn%d3\\t%0, #%B1\;mvn%D3\\t%0, #%B2"
7442   "&& reload_completed"
7443   [(const_int 0)]
7444   {
7445     enum rtx_code rev_code;
7446     machine_mode mode;
7447     rtx rev_cond;
7449     emit_insn (gen_rtx_COND_EXEC (VOIDmode,
7450                                   operands[3],
7451                                   gen_rtx_SET (operands[0], operands[1])));
7453     rev_code = GET_CODE (operands[3]);
7454     mode = GET_MODE (operands[4]);
7455     if (mode == CCFPmode || mode == CCFPEmode)
7456       rev_code = reverse_condition_maybe_unordered (rev_code);
7457     else
7458       rev_code = reverse_condition (rev_code);
7460     rev_cond = gen_rtx_fmt_ee (rev_code,
7461                                VOIDmode,
7462                                operands[4],
7463                                const0_rtx);
7464     emit_insn (gen_rtx_COND_EXEC (VOIDmode,
7465                                   rev_cond,
7466                                   gen_rtx_SET (operands[0], operands[2])));
7467     DONE;
7468   }
7469   [(set_attr "length" "4,4,4,4,8,8,8,8")
7470    (set_attr "conds" "use")
7471    (set_attr_alternative "type"
7472                          [(if_then_else (match_operand 2 "const_int_operand" "")
7473                                         (const_string "mov_imm")
7474                                         (const_string "mov_reg"))
7475                           (const_string "mvn_imm")
7476                           (if_then_else (match_operand 1 "const_int_operand" "")
7477                                         (const_string "mov_imm")
7478                                         (const_string "mov_reg"))
7479                           (const_string "mvn_imm")
7480                           (const_string "multiple")
7481                           (const_string "multiple")
7482                           (const_string "multiple")
7483                           (const_string "multiple")])]
7486 (define_insn "*movsfcc_soft_insn"
7487   [(set (match_operand:SF 0 "s_register_operand" "=r,r")
7488         (if_then_else:SF (match_operator 3 "arm_comparison_operator"
7489                           [(match_operand 4 "cc_register" "") (const_int 0)])
7490                          (match_operand:SF 1 "s_register_operand" "0,r")
7491                          (match_operand:SF 2 "s_register_operand" "r,0")))]
7492   "TARGET_ARM && TARGET_SOFT_FLOAT"
7493   "@
7494    mov%D3\\t%0, %2
7495    mov%d3\\t%0, %1"
7496   [(set_attr "conds" "use")
7497    (set_attr "type" "mov_reg")]
7501 ;; Jump and linkage insns
7503 (define_expand "jump"
7504   [(set (pc)
7505         (label_ref (match_operand 0 "" "")))]
7506   "TARGET_EITHER"
7507   ""
7510 (define_insn "*arm_jump"
7511   [(set (pc)
7512         (label_ref (match_operand 0 "" "")))]
7513   "TARGET_32BIT"
7514   "*
7515   {
7516     if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
7517       {
7518         arm_ccfsm_state += 2;
7519         return \"\";
7520       }
7521     return \"b%?\\t%l0\";
7522   }
7523   "
7524   [(set_attr "predicable" "yes")
7525    (set (attr "length")
7526         (if_then_else
7527            (and (match_test "TARGET_THUMB2")
7528                 (and (ge (minus (match_dup 0) (pc)) (const_int -2044))
7529                      (le (minus (match_dup 0) (pc)) (const_int 2048))))
7530            (const_int 2)
7531            (const_int 4)))
7532    (set_attr "type" "branch")]
7535 (define_expand "call"
7536   [(parallel [(call (match_operand 0 "memory_operand" "")
7537                     (match_operand 1 "general_operand" ""))
7538               (use (match_operand 2 "" ""))
7539               (clobber (reg:SI LR_REGNUM))])]
7540   "TARGET_EITHER"
7541   "
7542   {
7543     rtx callee, pat;
7544     
7545     /* In an untyped call, we can get NULL for operand 2.  */
7546     if (operands[2] == NULL_RTX)
7547       operands[2] = const0_rtx;
7548       
7549     /* Decide if we should generate indirect calls by loading the
7550        32-bit address of the callee into a register before performing the
7551        branch and link.  */
7552     callee = XEXP (operands[0], 0);
7553     if (GET_CODE (callee) == SYMBOL_REF
7554         ? arm_is_long_call_p (SYMBOL_REF_DECL (callee))
7555         : !REG_P (callee))
7556       XEXP (operands[0], 0) = force_reg (Pmode, callee);
7558     pat = gen_call_internal (operands[0], operands[1], operands[2]);
7559     arm_emit_call_insn (pat, XEXP (operands[0], 0), false);
7560     DONE;
7561   }"
7564 (define_expand "call_internal"
7565   [(parallel [(call (match_operand 0 "memory_operand" "")
7566                     (match_operand 1 "general_operand" ""))
7567               (use (match_operand 2 "" ""))
7568               (clobber (reg:SI LR_REGNUM))])])
7570 (define_insn "*call_reg_armv5"
7571   [(call (mem:SI (match_operand:SI 0 "s_register_operand" "r"))
7572          (match_operand 1 "" ""))
7573    (use (match_operand 2 "" ""))
7574    (clobber (reg:SI LR_REGNUM))]
7575   "TARGET_ARM && arm_arch5 && !SIBLING_CALL_P (insn)"
7576   "blx%?\\t%0"
7577   [(set_attr "type" "call")]
7580 (define_insn "*call_reg_arm"
7581   [(call (mem:SI (match_operand:SI 0 "s_register_operand" "r"))
7582          (match_operand 1 "" ""))
7583    (use (match_operand 2 "" ""))
7584    (clobber (reg:SI LR_REGNUM))]
7585   "TARGET_ARM && !arm_arch5 && !SIBLING_CALL_P (insn)"
7586   "*
7587   return output_call (operands);
7588   "
7589   ;; length is worst case, normally it is only two
7590   [(set_attr "length" "12")
7591    (set_attr "type" "call")]
7595 ;; Note: not used for armv5+ because the sequence used (ldr pc, ...) is not
7596 ;; considered a function call by the branch predictor of some cores (PR40887).
7597 ;; Falls back to blx rN (*call_reg_armv5).
7599 (define_insn "*call_mem"
7600   [(call (mem:SI (match_operand:SI 0 "call_memory_operand" "m"))
7601          (match_operand 1 "" ""))
7602    (use (match_operand 2 "" ""))
7603    (clobber (reg:SI LR_REGNUM))]
7604   "TARGET_ARM && !arm_arch5 && !SIBLING_CALL_P (insn)"
7605   "*
7606   return output_call_mem (operands);
7607   "
7608   [(set_attr "length" "12")
7609    (set_attr "type" "call")]
7612 (define_expand "call_value"
7613   [(parallel [(set (match_operand       0 "" "")
7614                    (call (match_operand 1 "memory_operand" "")
7615                          (match_operand 2 "general_operand" "")))
7616               (use (match_operand 3 "" ""))
7617               (clobber (reg:SI LR_REGNUM))])]
7618   "TARGET_EITHER"
7619   "
7620   {
7621     rtx pat, callee;
7622     
7623     /* In an untyped call, we can get NULL for operand 2.  */
7624     if (operands[3] == 0)
7625       operands[3] = const0_rtx;
7626       
7627     /* Decide if we should generate indirect calls by loading the
7628        32-bit address of the callee into a register before performing the
7629        branch and link.  */
7630     callee = XEXP (operands[1], 0);
7631     if (GET_CODE (callee) == SYMBOL_REF
7632         ? arm_is_long_call_p (SYMBOL_REF_DECL (callee))
7633         : !REG_P (callee))
7634       XEXP (operands[1], 0) = force_reg (Pmode, callee);
7636     pat = gen_call_value_internal (operands[0], operands[1],
7637                                    operands[2], operands[3]);
7638     arm_emit_call_insn (pat, XEXP (operands[1], 0), false);
7639     DONE;
7640   }"
7643 (define_expand "call_value_internal"
7644   [(parallel [(set (match_operand       0 "" "")
7645                    (call (match_operand 1 "memory_operand" "")
7646                          (match_operand 2 "general_operand" "")))
7647               (use (match_operand 3 "" ""))
7648               (clobber (reg:SI LR_REGNUM))])])
7650 (define_insn "*call_value_reg_armv5"
7651   [(set (match_operand 0 "" "")
7652         (call (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
7653               (match_operand 2 "" "")))
7654    (use (match_operand 3 "" ""))
7655    (clobber (reg:SI LR_REGNUM))]
7656   "TARGET_ARM && arm_arch5 && !SIBLING_CALL_P (insn)"
7657   "blx%?\\t%1"
7658   [(set_attr "type" "call")]
7661 (define_insn "*call_value_reg_arm"
7662   [(set (match_operand 0 "" "")
7663         (call (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
7664               (match_operand 2 "" "")))
7665    (use (match_operand 3 "" ""))
7666    (clobber (reg:SI LR_REGNUM))]
7667   "TARGET_ARM && !arm_arch5 && !SIBLING_CALL_P (insn)"
7668   "*
7669   return output_call (&operands[1]);
7670   "
7671   [(set_attr "length" "12")
7672    (set_attr "type" "call")]
7675 ;; Note: see *call_mem
7677 (define_insn "*call_value_mem"
7678   [(set (match_operand 0 "" "")
7679         (call (mem:SI (match_operand:SI 1 "call_memory_operand" "m"))
7680               (match_operand 2 "" "")))
7681    (use (match_operand 3 "" ""))
7682    (clobber (reg:SI LR_REGNUM))]
7683   "TARGET_ARM && !arm_arch5 && (!CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
7684    && !SIBLING_CALL_P (insn)"
7685   "*
7686   return output_call_mem (&operands[1]);
7687   "
7688   [(set_attr "length" "12")
7689    (set_attr "type" "call")]
7692 ;; Allow calls to SYMBOL_REFs specially as they are not valid general addresses
7693 ;; The 'a' causes the operand to be treated as an address, i.e. no '#' output.
7695 (define_insn "*call_symbol"
7696   [(call (mem:SI (match_operand:SI 0 "" ""))
7697          (match_operand 1 "" ""))
7698    (use (match_operand 2 "" ""))
7699    (clobber (reg:SI LR_REGNUM))]
7700   "TARGET_32BIT
7701    && !SIBLING_CALL_P (insn)
7702    && (GET_CODE (operands[0]) == SYMBOL_REF)
7703    && !arm_is_long_call_p (SYMBOL_REF_DECL (operands[0]))"
7704   "*
7705   {
7706     return NEED_PLT_RELOC ? \"bl%?\\t%a0(PLT)\" : \"bl%?\\t%a0\";
7707   }"
7708   [(set_attr "type" "call")]
7711 (define_insn "*call_value_symbol"
7712   [(set (match_operand 0 "" "")
7713         (call (mem:SI (match_operand:SI 1 "" ""))
7714         (match_operand:SI 2 "" "")))
7715    (use (match_operand 3 "" ""))
7716    (clobber (reg:SI LR_REGNUM))]
7717   "TARGET_32BIT
7718    && !SIBLING_CALL_P (insn)
7719    && (GET_CODE (operands[1]) == SYMBOL_REF)
7720    && !arm_is_long_call_p (SYMBOL_REF_DECL (operands[1]))"
7721   "*
7722   {
7723     return NEED_PLT_RELOC ? \"bl%?\\t%a1(PLT)\" : \"bl%?\\t%a1\";
7724   }"
7725   [(set_attr "type" "call")]
7728 (define_expand "sibcall_internal"
7729   [(parallel [(call (match_operand 0 "memory_operand" "")
7730                     (match_operand 1 "general_operand" ""))
7731               (return)
7732               (use (match_operand 2 "" ""))])])
7734 ;; We may also be able to do sibcalls for Thumb, but it's much harder...
7735 (define_expand "sibcall"
7736   [(parallel [(call (match_operand 0 "memory_operand" "")
7737                     (match_operand 1 "general_operand" ""))
7738               (return)
7739               (use (match_operand 2 "" ""))])]
7740   "TARGET_32BIT"
7741   "
7742   {
7743     rtx pat;
7745     if ((!REG_P (XEXP (operands[0], 0))
7746          && GET_CODE (XEXP (operands[0], 0)) != SYMBOL_REF)
7747         || (GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
7748             && arm_is_long_call_p (SYMBOL_REF_DECL (XEXP (operands[0], 0)))))
7749      XEXP (operands[0], 0) = force_reg (SImode, XEXP (operands[0], 0));
7751     if (operands[2] == NULL_RTX)
7752       operands[2] = const0_rtx;
7754     pat = gen_sibcall_internal (operands[0], operands[1], operands[2]);
7755     arm_emit_call_insn (pat, operands[0], true);
7756     DONE;
7757   }"
7760 (define_expand "sibcall_value_internal"
7761   [(parallel [(set (match_operand 0 "" "")
7762                    (call (match_operand 1 "memory_operand" "")
7763                          (match_operand 2 "general_operand" "")))
7764               (return)
7765               (use (match_operand 3 "" ""))])])
7767 (define_expand "sibcall_value"
7768   [(parallel [(set (match_operand 0 "" "")
7769                    (call (match_operand 1 "memory_operand" "")
7770                          (match_operand 2 "general_operand" "")))
7771               (return)
7772               (use (match_operand 3 "" ""))])]
7773   "TARGET_32BIT"
7774   "
7775   {
7776     rtx pat;
7778     if ((!REG_P (XEXP (operands[1], 0))
7779          && GET_CODE (XEXP (operands[1], 0)) != SYMBOL_REF)
7780         || (GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
7781             && arm_is_long_call_p (SYMBOL_REF_DECL (XEXP (operands[1], 0)))))
7782      XEXP (operands[1], 0) = force_reg (SImode, XEXP (operands[1], 0));
7784     if (operands[3] == NULL_RTX)
7785       operands[3] = const0_rtx;
7787     pat = gen_sibcall_value_internal (operands[0], operands[1],
7788                                       operands[2], operands[3]);
7789     arm_emit_call_insn (pat, operands[1], true);
7790     DONE;
7791   }"
7794 (define_insn "*sibcall_insn"
7795  [(call (mem:SI (match_operand:SI 0 "call_insn_operand" "Cs, US"))
7796         (match_operand 1 "" ""))
7797   (return)
7798   (use (match_operand 2 "" ""))]
7799   "TARGET_32BIT && SIBLING_CALL_P (insn)"
7800   "*
7801   if (which_alternative == 1)
7802     return NEED_PLT_RELOC ? \"b%?\\t%a0(PLT)\" : \"b%?\\t%a0\";
7803   else
7804     {
7805       if (arm_arch5 || arm_arch4t)
7806         return \"bx%?\\t%0\\t%@ indirect register sibling call\";
7807       else
7808         return \"mov%?\\t%|pc, %0\\t%@ indirect register sibling call\";
7809     }
7810   "
7811   [(set_attr "type" "call")]
7814 (define_insn "*sibcall_value_insn"
7815  [(set (match_operand 0 "" "")
7816        (call (mem:SI (match_operand:SI 1 "call_insn_operand" "Cs,US"))
7817              (match_operand 2 "" "")))
7818   (return)
7819   (use (match_operand 3 "" ""))]
7820   "TARGET_32BIT && SIBLING_CALL_P (insn)"
7821   "*
7822   if (which_alternative == 1)
7823    return NEED_PLT_RELOC ? \"b%?\\t%a1(PLT)\" : \"b%?\\t%a1\";
7824   else
7825     {
7826       if (arm_arch5 || arm_arch4t)
7827         return \"bx%?\\t%1\";
7828       else
7829         return \"mov%?\\t%|pc, %1\\t@ indirect sibling call \";
7830     }
7831   "
7832   [(set_attr "type" "call")]
7835 (define_expand "<return_str>return"
7836   [(RETURNS)]
7837   "(TARGET_ARM || (TARGET_THUMB2
7838                    && ARM_FUNC_TYPE (arm_current_func_type ()) == ARM_FT_NORMAL
7839                    && !IS_STACKALIGN (arm_current_func_type ())))
7840     <return_cond_false>"
7841   "
7842   {
7843     if (TARGET_THUMB2)
7844       {
7845         thumb2_expand_return (<return_simple_p>);
7846         DONE;
7847       }
7848   }
7849   "
7852 ;; Often the return insn will be the same as loading from memory, so set attr
7853 (define_insn "*arm_return"
7854   [(return)]
7855   "TARGET_ARM && USE_RETURN_INSN (FALSE)"
7856   "*
7857   {
7858     if (arm_ccfsm_state == 2)
7859       {
7860         arm_ccfsm_state += 2;
7861         return \"\";
7862       }
7863     return output_return_instruction (const_true_rtx, true, false, false);
7864   }"
7865   [(set_attr "type" "load1")
7866    (set_attr "length" "12")
7867    (set_attr "predicable" "yes")]
7870 (define_insn "*cond_<return_str>return"
7871   [(set (pc)
7872         (if_then_else (match_operator 0 "arm_comparison_operator"
7873                        [(match_operand 1 "cc_register" "") (const_int 0)])
7874                       (RETURNS)
7875                       (pc)))]
7876   "TARGET_ARM  <return_cond_true>"
7877   "*
7878   {
7879     if (arm_ccfsm_state == 2)
7880       {
7881         arm_ccfsm_state += 2;
7882         return \"\";
7883       }
7884     return output_return_instruction (operands[0], true, false,
7885                                       <return_simple_p>);
7886   }"
7887   [(set_attr "conds" "use")
7888    (set_attr "length" "12")
7889    (set_attr "type" "load1")]
7892 (define_insn "*cond_<return_str>return_inverted"
7893   [(set (pc)
7894         (if_then_else (match_operator 0 "arm_comparison_operator"
7895                        [(match_operand 1 "cc_register" "") (const_int 0)])
7896                       (pc)
7897                       (RETURNS)))]
7898   "TARGET_ARM <return_cond_true>"
7899   "*
7900   {
7901     if (arm_ccfsm_state == 2)
7902       {
7903         arm_ccfsm_state += 2;
7904         return \"\";
7905       }
7906     return output_return_instruction (operands[0], true, true,
7907                                       <return_simple_p>);
7908   }"
7909   [(set_attr "conds" "use")
7910    (set_attr "length" "12")
7911    (set_attr "type" "load1")]
7914 (define_insn "*arm_simple_return"
7915   [(simple_return)]
7916   "TARGET_ARM"
7917   "*
7918   {
7919     if (arm_ccfsm_state == 2)
7920       {
7921         arm_ccfsm_state += 2;
7922         return \"\";
7923       }
7924     return output_return_instruction (const_true_rtx, true, false, true);
7925   }"
7926   [(set_attr "type" "branch")
7927    (set_attr "length" "4")
7928    (set_attr "predicable" "yes")]
7931 ;; Generate a sequence of instructions to determine if the processor is
7932 ;; in 26-bit or 32-bit mode, and return the appropriate return address
7933 ;; mask.
7935 (define_expand "return_addr_mask"
7936   [(set (match_dup 1)
7937       (compare:CC_NOOV (unspec [(const_int 0)] UNSPEC_CHECK_ARCH)
7938                        (const_int 0)))
7939    (set (match_operand:SI 0 "s_register_operand" "")
7940       (if_then_else:SI (eq (match_dup 1) (const_int 0))
7941                        (const_int -1)
7942                        (const_int 67108860)))] ; 0x03fffffc
7943   "TARGET_ARM"
7944   "
7945   operands[1] = gen_rtx_REG (CC_NOOVmode, CC_REGNUM);
7946   ")
7948 (define_insn "*check_arch2"
7949   [(set (match_operand:CC_NOOV 0 "cc_register" "")
7950       (compare:CC_NOOV (unspec [(const_int 0)] UNSPEC_CHECK_ARCH)
7951                        (const_int 0)))]
7952   "TARGET_ARM"
7953   "teq\\t%|r0, %|r0\;teq\\t%|pc, %|pc"
7954   [(set_attr "length" "8")
7955    (set_attr "conds" "set")
7956    (set_attr "type" "multiple")]
7959 ;; Call subroutine returning any type.
7961 (define_expand "untyped_call"
7962   [(parallel [(call (match_operand 0 "" "")
7963                     (const_int 0))
7964               (match_operand 1 "" "")
7965               (match_operand 2 "" "")])]
7966   "TARGET_EITHER"
7967   "
7968   {
7969     int i;
7970     rtx par = gen_rtx_PARALLEL (VOIDmode,
7971                                 rtvec_alloc (XVECLEN (operands[2], 0)));
7972     rtx addr = gen_reg_rtx (Pmode);
7973     rtx mem;
7974     int size = 0;
7976     emit_move_insn (addr, XEXP (operands[1], 0));
7977     mem = change_address (operands[1], BLKmode, addr);
7979     for (i = 0; i < XVECLEN (operands[2], 0); i++)
7980       {
7981         rtx src = SET_SRC (XVECEXP (operands[2], 0, i));
7983         /* Default code only uses r0 as a return value, but we could
7984            be using anything up to 4 registers.  */
7985         if (REGNO (src) == R0_REGNUM)
7986           src = gen_rtx_REG (TImode, R0_REGNUM);
7988         XVECEXP (par, 0, i) = gen_rtx_EXPR_LIST (VOIDmode, src,
7989                                                  GEN_INT (size));
7990         size += GET_MODE_SIZE (GET_MODE (src));
7991       }
7993     emit_call_insn (GEN_CALL_VALUE (par, operands[0], const0_rtx, NULL,
7994                                     const0_rtx));
7996     size = 0;
7998     for (i = 0; i < XVECLEN (par, 0); i++)
7999       {
8000         HOST_WIDE_INT offset = 0;
8001         rtx reg = XEXP (XVECEXP (par, 0, i), 0);
8003         if (size != 0)
8004           emit_move_insn (addr, plus_constant (Pmode, addr, size));
8006         mem = change_address (mem, GET_MODE (reg), NULL);
8007         if (REGNO (reg) == R0_REGNUM)
8008           {
8009             /* On thumb we have to use a write-back instruction.  */
8010             emit_insn (arm_gen_store_multiple (arm_regs_in_sequence, 4, addr,
8011                        TARGET_THUMB ? TRUE : FALSE, mem, &offset));
8012             size = TARGET_ARM ? 16 : 0;
8013           }
8014         else
8015           {
8016             emit_move_insn (mem, reg);
8017             size = GET_MODE_SIZE (GET_MODE (reg));
8018           }
8019       }
8021     /* The optimizer does not know that the call sets the function value
8022        registers we stored in the result block.  We avoid problems by
8023        claiming that all hard registers are used and clobbered at this
8024        point.  */
8025     emit_insn (gen_blockage ());
8027     DONE;
8028   }"
8031 (define_expand "untyped_return"
8032   [(match_operand:BLK 0 "memory_operand" "")
8033    (match_operand 1 "" "")]
8034   "TARGET_EITHER"
8035   "
8036   {
8037     int i;
8038     rtx addr = gen_reg_rtx (Pmode);
8039     rtx mem;
8040     int size = 0;
8042     emit_move_insn (addr, XEXP (operands[0], 0));
8043     mem = change_address (operands[0], BLKmode, addr);
8045     for (i = 0; i < XVECLEN (operands[1], 0); i++)
8046       {
8047         HOST_WIDE_INT offset = 0;
8048         rtx reg = SET_DEST (XVECEXP (operands[1], 0, i));
8050         if (size != 0)
8051           emit_move_insn (addr, plus_constant (Pmode, addr, size));
8053         mem = change_address (mem, GET_MODE (reg), NULL);
8054         if (REGNO (reg) == R0_REGNUM)
8055           {
8056             /* On thumb we have to use a write-back instruction.  */
8057             emit_insn (arm_gen_load_multiple (arm_regs_in_sequence, 4, addr,
8058                        TARGET_THUMB ? TRUE : FALSE, mem, &offset));
8059             size = TARGET_ARM ? 16 : 0;
8060           }
8061         else
8062           {
8063             emit_move_insn (reg, mem);
8064             size = GET_MODE_SIZE (GET_MODE (reg));
8065           }
8066       }
8068     /* Emit USE insns before the return.  */
8069     for (i = 0; i < XVECLEN (operands[1], 0); i++)
8070       emit_use (SET_DEST (XVECEXP (operands[1], 0, i)));
8072     /* Construct the return.  */
8073     expand_naked_return ();
8075     DONE;
8076   }"
8079 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
8080 ;; all of memory.  This blocks insns from being moved across this point.
8082 (define_insn "blockage"
8083   [(unspec_volatile [(const_int 0)] VUNSPEC_BLOCKAGE)]
8084   "TARGET_EITHER"
8085   ""
8086   [(set_attr "length" "0")
8087    (set_attr "type" "block")]
8090 (define_expand "casesi"
8091   [(match_operand:SI 0 "s_register_operand" "") ; index to jump on
8092    (match_operand:SI 1 "const_int_operand" "")  ; lower bound
8093    (match_operand:SI 2 "const_int_operand" "")  ; total range
8094    (match_operand:SI 3 "" "")                   ; table label
8095    (match_operand:SI 4 "" "")]                  ; Out of range label
8096   "TARGET_32BIT || optimize_size || flag_pic"
8097   "
8098   {
8099     enum insn_code code;
8100     if (operands[1] != const0_rtx)
8101       {
8102         rtx reg = gen_reg_rtx (SImode);
8104         emit_insn (gen_addsi3 (reg, operands[0],
8105                                gen_int_mode (-INTVAL (operands[1]),
8106                                              SImode)));
8107         operands[0] = reg;
8108       }
8110     if (TARGET_ARM)
8111       code = CODE_FOR_arm_casesi_internal;
8112     else if (TARGET_THUMB1)
8113       code = CODE_FOR_thumb1_casesi_internal_pic;
8114     else if (flag_pic)
8115       code = CODE_FOR_thumb2_casesi_internal_pic;
8116     else
8117       code = CODE_FOR_thumb2_casesi_internal;
8119     if (!insn_data[(int) code].operand[1].predicate(operands[2], SImode))
8120       operands[2] = force_reg (SImode, operands[2]);
8122     emit_jump_insn (GEN_FCN ((int) code) (operands[0], operands[2],
8123                                           operands[3], operands[4]));
8124     DONE;
8125   }"
8128 ;; The USE in this pattern is needed to tell flow analysis that this is
8129 ;; a CASESI insn.  It has no other purpose.
8130 (define_insn "arm_casesi_internal"
8131   [(parallel [(set (pc)
8132                (if_then_else
8133                 (leu (match_operand:SI 0 "s_register_operand" "r")
8134                      (match_operand:SI 1 "arm_rhs_operand" "rI"))
8135                 (mem:SI (plus:SI (mult:SI (match_dup 0) (const_int 4))
8136                                  (label_ref (match_operand 2 "" ""))))
8137                 (label_ref (match_operand 3 "" ""))))
8138               (clobber (reg:CC CC_REGNUM))
8139               (use (label_ref (match_dup 2)))])]
8140   "TARGET_ARM"
8141   "*
8142     if (flag_pic)
8143       return \"cmp\\t%0, %1\;addls\\t%|pc, %|pc, %0, asl #2\;b\\t%l3\";
8144     return   \"cmp\\t%0, %1\;ldrls\\t%|pc, [%|pc, %0, asl #2]\;b\\t%l3\";
8145   "
8146   [(set_attr "conds" "clob")
8147    (set_attr "length" "12")
8148    (set_attr "type" "multiple")]
8151 (define_expand "indirect_jump"
8152   [(set (pc)
8153         (match_operand:SI 0 "s_register_operand" ""))]
8154   "TARGET_EITHER"
8155   "
8156   /* Thumb-2 doesn't have mov pc, reg.  Explicitly set the low bit of the
8157      address and use bx.  */
8158   if (TARGET_THUMB2)
8159     {
8160       rtx tmp;
8161       tmp = gen_reg_rtx (SImode);
8162       emit_insn (gen_iorsi3 (tmp, operands[0], GEN_INT(1)));
8163       operands[0] = tmp;
8164     }
8165   "
8168 ;; NB Never uses BX.
8169 (define_insn "*arm_indirect_jump"
8170   [(set (pc)
8171         (match_operand:SI 0 "s_register_operand" "r"))]
8172   "TARGET_ARM"
8173   "mov%?\\t%|pc, %0\\t%@ indirect register jump"
8174   [(set_attr "predicable" "yes")
8175    (set_attr "type" "branch")]
8178 (define_insn "*load_indirect_jump"
8179   [(set (pc)
8180         (match_operand:SI 0 "memory_operand" "m"))]
8181   "TARGET_ARM"
8182   "ldr%?\\t%|pc, %0\\t%@ indirect memory jump"
8183   [(set_attr "type" "load1")
8184    (set_attr "pool_range" "4096")
8185    (set_attr "neg_pool_range" "4084")
8186    (set_attr "predicable" "yes")]
8190 ;; Misc insns
8192 (define_insn "nop"
8193   [(const_int 0)]
8194   "TARGET_EITHER"
8195   "*
8196   if (TARGET_UNIFIED_ASM)
8197     return \"nop\";
8198   if (TARGET_ARM)
8199     return \"mov%?\\t%|r0, %|r0\\t%@ nop\";
8200   return  \"mov\\tr8, r8\";
8201   "
8202   [(set (attr "length")
8203         (if_then_else (eq_attr "is_thumb" "yes")
8204                       (const_int 2)
8205                       (const_int 4)))
8206    (set_attr "type" "mov_reg")]
8209 (define_insn "trap"
8210   [(trap_if (const_int 1) (const_int 0))]
8211   ""
8212   "*
8213   if (TARGET_ARM)
8214     return \".inst\\t0xe7f000f0\";
8215   else
8216     return \".inst\\t0xdeff\";
8217   "
8218   [(set (attr "length")
8219         (if_then_else (eq_attr "is_thumb" "yes")
8220                       (const_int 2)
8221                       (const_int 4)))
8222    (set_attr "type" "trap")
8223    (set_attr "conds" "unconditional")]
8227 ;; Patterns to allow combination of arithmetic, cond code and shifts
8229 (define_insn "*<arith_shift_insn>_multsi"
8230   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8231         (SHIFTABLE_OPS:SI
8232          (mult:SI (match_operand:SI 2 "s_register_operand" "r,r")
8233                   (match_operand:SI 3 "power_of_two_operand" ""))
8234          (match_operand:SI 1 "s_register_operand" "rk,<t2_binop0>")))]
8235   "TARGET_32BIT"
8236   "<arith_shift_insn>%?\\t%0, %1, %2, lsl %b3"
8237   [(set_attr "predicable" "yes")
8238    (set_attr "predicable_short_it" "no")
8239    (set_attr "shift" "2")
8240    (set_attr "arch" "a,t2")
8241    (set_attr "type" "alu_shift_imm")])
8243 (define_insn "*<arith_shift_insn>_shiftsi"
8244   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
8245         (SHIFTABLE_OPS:SI
8246          (match_operator:SI 2 "shift_nomul_operator"
8247           [(match_operand:SI 3 "s_register_operand" "r,r,r")
8248            (match_operand:SI 4 "shift_amount_operand" "M,M,r")])
8249          (match_operand:SI 1 "s_register_operand" "rk,<t2_binop0>,rk")))]
8250   "TARGET_32BIT && GET_CODE (operands[2]) != MULT"
8251   "<arith_shift_insn>%?\\t%0, %1, %3%S2"
8252   [(set_attr "predicable" "yes")
8253    (set_attr "predicable_short_it" "no")
8254    (set_attr "shift" "3")
8255    (set_attr "arch" "a,t2,a")
8256    (set_attr "type" "alu_shift_imm,alu_shift_imm,alu_shift_reg")])
8258 (define_split
8259   [(set (match_operand:SI 0 "s_register_operand" "")
8260         (match_operator:SI 1 "shiftable_operator"
8261          [(match_operator:SI 2 "shiftable_operator"
8262            [(match_operator:SI 3 "shift_operator"
8263              [(match_operand:SI 4 "s_register_operand" "")
8264               (match_operand:SI 5 "reg_or_int_operand" "")])
8265             (match_operand:SI 6 "s_register_operand" "")])
8266           (match_operand:SI 7 "arm_rhs_operand" "")]))
8267    (clobber (match_operand:SI 8 "s_register_operand" ""))]
8268   "TARGET_32BIT"
8269   [(set (match_dup 8)
8270         (match_op_dup 2 [(match_op_dup 3 [(match_dup 4) (match_dup 5)])
8271                          (match_dup 6)]))
8272    (set (match_dup 0)
8273         (match_op_dup 1 [(match_dup 8) (match_dup 7)]))]
8274   "")
8276 (define_insn "*arith_shiftsi_compare0"
8277   [(set (reg:CC_NOOV CC_REGNUM)
8278         (compare:CC_NOOV
8279          (match_operator:SI 1 "shiftable_operator"
8280           [(match_operator:SI 3 "shift_operator"
8281             [(match_operand:SI 4 "s_register_operand" "r,r")
8282              (match_operand:SI 5 "shift_amount_operand" "M,r")])
8283            (match_operand:SI 2 "s_register_operand" "r,r")])
8284          (const_int 0)))
8285    (set (match_operand:SI 0 "s_register_operand" "=r,r")
8286         (match_op_dup 1 [(match_op_dup 3 [(match_dup 4) (match_dup 5)])
8287                          (match_dup 2)]))]
8288   "TARGET_32BIT"
8289   "%i1%.\\t%0, %2, %4%S3"
8290   [(set_attr "conds" "set")
8291    (set_attr "shift" "4")
8292    (set_attr "arch" "32,a")
8293    (set_attr "type" "alus_shift_imm,alus_shift_reg")])
8295 (define_insn "*arith_shiftsi_compare0_scratch"
8296   [(set (reg:CC_NOOV CC_REGNUM)
8297         (compare:CC_NOOV
8298          (match_operator:SI 1 "shiftable_operator"
8299           [(match_operator:SI 3 "shift_operator"
8300             [(match_operand:SI 4 "s_register_operand" "r,r")
8301              (match_operand:SI 5 "shift_amount_operand" "M,r")])
8302            (match_operand:SI 2 "s_register_operand" "r,r")])
8303          (const_int 0)))
8304    (clobber (match_scratch:SI 0 "=r,r"))]
8305   "TARGET_32BIT"
8306   "%i1%.\\t%0, %2, %4%S3"
8307   [(set_attr "conds" "set")
8308    (set_attr "shift" "4")
8309    (set_attr "arch" "32,a")
8310    (set_attr "type" "alus_shift_imm,alus_shift_reg")])
8312 (define_insn "*sub_shiftsi"
8313   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8314         (minus:SI (match_operand:SI 1 "s_register_operand" "r,r")
8315                   (match_operator:SI 2 "shift_operator"
8316                    [(match_operand:SI 3 "s_register_operand" "r,r")
8317                     (match_operand:SI 4 "shift_amount_operand" "M,r")])))]
8318   "TARGET_32BIT"
8319   "sub%?\\t%0, %1, %3%S2"
8320   [(set_attr "predicable" "yes")
8321    (set_attr "shift" "3")
8322    (set_attr "arch" "32,a")
8323    (set_attr "type" "alus_shift_imm,alus_shift_reg")])
8325 (define_insn "*sub_shiftsi_compare0"
8326   [(set (reg:CC_NOOV CC_REGNUM)
8327         (compare:CC_NOOV
8328          (minus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
8329                    (match_operator:SI 2 "shift_operator"
8330                     [(match_operand:SI 3 "s_register_operand" "r,r,r")
8331                      (match_operand:SI 4 "shift_amount_operand" "M,r,M")]))
8332          (const_int 0)))
8333    (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
8334         (minus:SI (match_dup 1)
8335                   (match_op_dup 2 [(match_dup 3) (match_dup 4)])))]
8336   "TARGET_32BIT"
8337   "sub%.\\t%0, %1, %3%S2"
8338   [(set_attr "conds" "set")
8339    (set_attr "shift" "3")
8340    (set_attr "arch" "32,a,a")
8341    (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
8343 (define_insn "*sub_shiftsi_compare0_scratch"
8344   [(set (reg:CC_NOOV CC_REGNUM)
8345         (compare:CC_NOOV
8346          (minus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
8347                    (match_operator:SI 2 "shift_operator"
8348                     [(match_operand:SI 3 "s_register_operand" "r,r,r")
8349                      (match_operand:SI 4 "shift_amount_operand" "M,r,M")]))
8350          (const_int 0)))
8351    (clobber (match_scratch:SI 0 "=r,r,r"))]
8352   "TARGET_32BIT"
8353   "sub%.\\t%0, %1, %3%S2"
8354   [(set_attr "conds" "set")
8355    (set_attr "shift" "3")
8356    (set_attr "arch" "32,a,a")
8357    (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
8360 (define_insn_and_split "*and_scc"
8361   [(set (match_operand:SI 0 "s_register_operand" "=r")
8362         (and:SI (match_operator:SI 1 "arm_comparison_operator"
8363                  [(match_operand 2 "cc_register" "") (const_int 0)])
8364                 (match_operand:SI 3 "s_register_operand" "r")))]
8365   "TARGET_ARM"
8366   "#"   ; "mov%D1\\t%0, #0\;and%d1\\t%0, %3, #1"
8367   "&& reload_completed"
8368   [(cond_exec (match_dup 5) (set (match_dup 0) (const_int 0)))
8369    (cond_exec (match_dup 4) (set (match_dup 0)
8370                                  (and:SI (match_dup 3) (const_int 1))))]
8371   {
8372     machine_mode mode = GET_MODE (operands[2]);
8373     enum rtx_code rc = GET_CODE (operands[1]);
8375     /* Note that operands[4] is the same as operands[1],
8376        but with VOIDmode as the result. */
8377     operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
8378     if (mode == CCFPmode || mode == CCFPEmode)
8379       rc = reverse_condition_maybe_unordered (rc);
8380     else
8381       rc = reverse_condition (rc);
8382     operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
8383   }
8384   [(set_attr "conds" "use")
8385    (set_attr "type" "multiple")
8386    (set_attr "length" "8")]
8389 (define_insn_and_split "*ior_scc"
8390   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8391         (ior:SI (match_operator:SI 1 "arm_comparison_operator"
8392                  [(match_operand 2 "cc_register" "") (const_int 0)])
8393                 (match_operand:SI 3 "s_register_operand" "0,?r")))]
8394   "TARGET_ARM"
8395   "@
8396    orr%d1\\t%0, %3, #1
8397    #"
8398   "&& reload_completed
8399    && REGNO (operands [0]) != REGNO (operands[3])"
8400   ;; && which_alternative == 1
8401   ; mov%D1\\t%0, %3\;orr%d1\\t%0, %3, #1
8402   [(cond_exec (match_dup 5) (set (match_dup 0) (match_dup 3)))
8403    (cond_exec (match_dup 4) (set (match_dup 0)
8404                                  (ior:SI (match_dup 3) (const_int 1))))]
8405   {
8406     machine_mode mode = GET_MODE (operands[2]);
8407     enum rtx_code rc = GET_CODE (operands[1]);
8409     /* Note that operands[4] is the same as operands[1],
8410        but with VOIDmode as the result. */
8411     operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
8412     if (mode == CCFPmode || mode == CCFPEmode)
8413       rc = reverse_condition_maybe_unordered (rc);
8414     else
8415       rc = reverse_condition (rc);
8416     operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
8417   }
8418   [(set_attr "conds" "use")
8419    (set_attr "length" "4,8")
8420    (set_attr "type" "logic_imm,multiple")]
8423 ; A series of splitters for the compare_scc pattern below.  Note that
8424 ; order is important.
8425 (define_split
8426   [(set (match_operand:SI 0 "s_register_operand" "")
8427         (lt:SI (match_operand:SI 1 "s_register_operand" "")
8428                (const_int 0)))
8429    (clobber (reg:CC CC_REGNUM))]
8430   "TARGET_32BIT && reload_completed"
8431   [(set (match_dup 0) (lshiftrt:SI (match_dup 1) (const_int 31)))])
8433 (define_split
8434   [(set (match_operand:SI 0 "s_register_operand" "")
8435         (ge:SI (match_operand:SI 1 "s_register_operand" "")
8436                (const_int 0)))
8437    (clobber (reg:CC CC_REGNUM))]
8438   "TARGET_32BIT && reload_completed"
8439   [(set (match_dup 0) (not:SI (match_dup 1)))
8440    (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 31)))])
8442 (define_split
8443   [(set (match_operand:SI 0 "s_register_operand" "")
8444         (eq:SI (match_operand:SI 1 "s_register_operand" "")
8445                (const_int 0)))
8446    (clobber (reg:CC CC_REGNUM))]
8447   "arm_arch5 && TARGET_32BIT"
8448   [(set (match_dup 0) (clz:SI (match_dup 1)))
8449    (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
8452 (define_split
8453   [(set (match_operand:SI 0 "s_register_operand" "")
8454         (eq:SI (match_operand:SI 1 "s_register_operand" "")
8455                (const_int 0)))
8456    (clobber (reg:CC CC_REGNUM))]
8457   "TARGET_32BIT && reload_completed"
8458   [(parallel
8459     [(set (reg:CC CC_REGNUM)
8460           (compare:CC (const_int 1) (match_dup 1)))
8461      (set (match_dup 0)
8462           (minus:SI (const_int 1) (match_dup 1)))])
8463    (cond_exec (ltu:CC (reg:CC CC_REGNUM) (const_int 0))
8464               (set (match_dup 0) (const_int 0)))])
8466 (define_split
8467   [(set (match_operand:SI 0 "s_register_operand" "")
8468         (ne:SI (match_operand:SI 1 "s_register_operand" "")
8469                (match_operand:SI 2 "const_int_operand" "")))
8470    (clobber (reg:CC CC_REGNUM))]
8471   "TARGET_32BIT && reload_completed"
8472   [(parallel
8473     [(set (reg:CC CC_REGNUM)
8474           (compare:CC (match_dup 1) (match_dup 2)))
8475      (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 3)))])
8476    (cond_exec (ne:CC (reg:CC CC_REGNUM) (const_int 0))
8477               (set (match_dup 0) (const_int 1)))]
8479   operands[3] = GEN_INT (-INTVAL (operands[2]));
8482 (define_split
8483   [(set (match_operand:SI 0 "s_register_operand" "")
8484         (ne:SI (match_operand:SI 1 "s_register_operand" "")
8485                (match_operand:SI 2 "arm_add_operand" "")))
8486    (clobber (reg:CC CC_REGNUM))]
8487   "TARGET_32BIT && reload_completed"
8488   [(parallel
8489     [(set (reg:CC_NOOV CC_REGNUM)
8490           (compare:CC_NOOV (minus:SI (match_dup 1) (match_dup 2))
8491                            (const_int 0)))
8492      (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
8493    (cond_exec (ne:CC_NOOV (reg:CC_NOOV CC_REGNUM) (const_int 0))
8494               (set (match_dup 0) (const_int 1)))])
8496 (define_insn_and_split "*compare_scc"
8497   [(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts")
8498         (match_operator:SI 1 "arm_comparison_operator"
8499          [(match_operand:SI 2 "s_register_operand" "r,r")
8500           (match_operand:SI 3 "arm_add_operand" "rI,L")]))
8501    (clobber (reg:CC CC_REGNUM))]
8502   "TARGET_32BIT"
8503   "#"
8504   "&& reload_completed"
8505   [(set (reg:CC CC_REGNUM) (compare:CC (match_dup 2) (match_dup 3)))
8506    (cond_exec (match_dup 4) (set (match_dup 0) (const_int 0)))
8507    (cond_exec (match_dup 5) (set (match_dup 0) (const_int 1)))]
8509   rtx tmp1;
8510   machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
8511                                            operands[2], operands[3]);
8512   enum rtx_code rc = GET_CODE (operands[1]);
8514   tmp1 = gen_rtx_REG (mode, CC_REGNUM);
8516   operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, tmp1, const0_rtx);
8517   if (mode == CCFPmode || mode == CCFPEmode)
8518     rc = reverse_condition_maybe_unordered (rc);
8519   else
8520     rc = reverse_condition (rc);
8521   operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, tmp1, const0_rtx);
8523   [(set_attr "type" "multiple")]
8526 ;; Attempt to improve the sequence generated by the compare_scc splitters
8527 ;; not to use conditional execution.
8529 ;; Rd = (eq (reg1) (const_int0))  // ARMv5
8530 ;;      clz Rd, reg1
8531 ;;      lsr Rd, Rd, #5
8532 (define_peephole2
8533   [(set (reg:CC CC_REGNUM)
8534         (compare:CC (match_operand:SI 1 "register_operand" "")
8535                     (const_int 0)))
8536    (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
8537               (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
8538    (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
8539               (set (match_dup 0) (const_int 1)))]
8540   "arm_arch5 && TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
8541   [(set (match_dup 0) (clz:SI (match_dup 1)))
8542    (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
8545 ;; Rd = (eq (reg1) (const_int0))  // !ARMv5
8546 ;;      negs Rd, reg1
8547 ;;      adc  Rd, Rd, reg1
8548 (define_peephole2
8549   [(set (reg:CC CC_REGNUM)
8550         (compare:CC (match_operand:SI 1 "register_operand" "")
8551                     (const_int 0)))
8552    (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
8553               (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
8554    (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
8555               (set (match_dup 0) (const_int 1)))
8556    (match_scratch:SI 2 "r")]
8557   "TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
8558   [(parallel
8559     [(set (reg:CC CC_REGNUM)
8560           (compare:CC (const_int 0) (match_dup 1)))
8561      (set (match_dup 2) (minus:SI (const_int 0) (match_dup 1)))])
8562    (set (match_dup 0)
8563         (plus:SI (plus:SI (match_dup 1) (match_dup 2))
8564                  (geu:SI (reg:CC CC_REGNUM) (const_int 0))))]
8567 ;; Rd = (eq (reg1) (reg2/imm))  // ARMv5 and optimising for speed.
8568 ;;      sub  Rd, Reg1, reg2
8569 ;;      clz  Rd, Rd
8570 ;;      lsr  Rd, Rd, #5
8571 (define_peephole2
8572   [(set (reg:CC CC_REGNUM)
8573         (compare:CC (match_operand:SI 1 "register_operand" "")
8574                     (match_operand:SI 2 "arm_rhs_operand" "")))
8575    (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
8576               (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
8577    (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
8578               (set (match_dup 0) (const_int 1)))]
8579   "arm_arch5 && TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)
8580   && !(TARGET_THUMB2 && optimize_insn_for_size_p ())"
8581   [(set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))
8582    (set (match_dup 0) (clz:SI (match_dup 0)))
8583    (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
8587 ;; Rd = (eq (reg1) (reg2))      // ! ARMv5 or optimising for size.
8588 ;;      sub  T1, Reg1, reg2
8589 ;;      negs Rd, T1
8590 ;;      adc  Rd, Rd, T1
8591 (define_peephole2
8592   [(set (reg:CC CC_REGNUM)
8593         (compare:CC (match_operand:SI 1 "register_operand" "")
8594                     (match_operand:SI 2 "arm_rhs_operand" "")))
8595    (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
8596               (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
8597    (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
8598               (set (match_dup 0) (const_int 1)))
8599    (match_scratch:SI 3 "r")]
8600   "TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
8601   [(set (match_dup 3) (match_dup 4))
8602    (parallel
8603     [(set (reg:CC CC_REGNUM)
8604           (compare:CC (const_int 0) (match_dup 3)))
8605      (set (match_dup 0) (minus:SI (const_int 0) (match_dup 3)))])
8606    (set (match_dup 0)
8607         (plus:SI (plus:SI (match_dup 0) (match_dup 3))
8608                  (geu:SI (reg:CC CC_REGNUM) (const_int 0))))]
8609   "
8610   if (CONST_INT_P (operands[2]))
8611     operands[4] = plus_constant (SImode, operands[1], -INTVAL (operands[2]));
8612   else
8613     operands[4] = gen_rtx_MINUS (SImode, operands[1], operands[2]);
8614   ")
8616 (define_insn "*cond_move"
8617   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
8618         (if_then_else:SI (match_operator 3 "equality_operator"
8619                           [(match_operator 4 "arm_comparison_operator"
8620                             [(match_operand 5 "cc_register" "") (const_int 0)])
8621                            (const_int 0)])
8622                          (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
8623                          (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))]
8624   "TARGET_ARM"
8625   "*
8626     if (GET_CODE (operands[3]) == NE)
8627       {
8628         if (which_alternative != 1)
8629           output_asm_insn (\"mov%D4\\t%0, %2\", operands);
8630         if (which_alternative != 0)
8631           output_asm_insn (\"mov%d4\\t%0, %1\", operands);
8632         return \"\";
8633       }
8634     if (which_alternative != 0)
8635       output_asm_insn (\"mov%D4\\t%0, %1\", operands);
8636     if (which_alternative != 1)
8637       output_asm_insn (\"mov%d4\\t%0, %2\", operands);
8638     return \"\";
8639   "
8640   [(set_attr "conds" "use")
8641    (set_attr_alternative "type"
8642                          [(if_then_else (match_operand 2 "const_int_operand" "")
8643                                         (const_string "mov_imm")
8644                                         (const_string "mov_reg"))
8645                           (if_then_else (match_operand 1 "const_int_operand" "")
8646                                         (const_string "mov_imm")
8647                                         (const_string "mov_reg"))
8648                           (const_string "multiple")])
8649    (set_attr "length" "4,4,8")]
8652 (define_insn "*cond_arith"
8653   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8654         (match_operator:SI 5 "shiftable_operator" 
8655          [(match_operator:SI 4 "arm_comparison_operator"
8656            [(match_operand:SI 2 "s_register_operand" "r,r")
8657             (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
8658           (match_operand:SI 1 "s_register_operand" "0,?r")]))
8659    (clobber (reg:CC CC_REGNUM))]
8660   "TARGET_ARM"
8661   "*
8662     if (GET_CODE (operands[4]) == LT && operands[3] == const0_rtx)
8663       return \"%i5\\t%0, %1, %2, lsr #31\";
8665     output_asm_insn (\"cmp\\t%2, %3\", operands);
8666     if (GET_CODE (operands[5]) == AND)
8667       output_asm_insn (\"mov%D4\\t%0, #0\", operands);
8668     else if (GET_CODE (operands[5]) == MINUS)
8669       output_asm_insn (\"rsb%D4\\t%0, %1, #0\", operands);
8670     else if (which_alternative != 0)
8671       output_asm_insn (\"mov%D4\\t%0, %1\", operands);
8672     return \"%i5%d4\\t%0, %1, #1\";
8673   "
8674   [(set_attr "conds" "clob")
8675    (set_attr "length" "12")
8676    (set_attr "type" "multiple")]
8679 (define_insn "*cond_sub"
8680   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8681         (minus:SI (match_operand:SI 1 "s_register_operand" "0,?r")
8682                   (match_operator:SI 4 "arm_comparison_operator"
8683                    [(match_operand:SI 2 "s_register_operand" "r,r")
8684                     (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
8685    (clobber (reg:CC CC_REGNUM))]
8686   "TARGET_ARM"
8687   "*
8688     output_asm_insn (\"cmp\\t%2, %3\", operands);
8689     if (which_alternative != 0)
8690       output_asm_insn (\"mov%D4\\t%0, %1\", operands);
8691     return \"sub%d4\\t%0, %1, #1\";
8692   "
8693   [(set_attr "conds" "clob")
8694    (set_attr "length" "8,12")
8695    (set_attr "type" "multiple")]
8698 (define_insn "*cmp_ite0"
8699   [(set (match_operand 6 "dominant_cc_register" "")
8700         (compare
8701          (if_then_else:SI
8702           (match_operator 4 "arm_comparison_operator"
8703            [(match_operand:SI 0 "s_register_operand"
8704                 "l,l,l,r,r,r,r,r,r")
8705             (match_operand:SI 1 "arm_add_operand"
8706                 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
8707           (match_operator:SI 5 "arm_comparison_operator"
8708            [(match_operand:SI 2 "s_register_operand"
8709                 "l,r,r,l,l,r,r,r,r")
8710             (match_operand:SI 3 "arm_add_operand"
8711                 "lPy,rI,L,lPy,lPy,rI,rI,L,L")])
8712           (const_int 0))
8713          (const_int 0)))]
8714   "TARGET_32BIT"
8715   "*
8716   {
8717     static const char * const cmp1[NUM_OF_COND_CMP][2] =
8718     {
8719       {\"cmp%d5\\t%0, %1\",
8720        \"cmp%d4\\t%2, %3\"},
8721       {\"cmn%d5\\t%0, #%n1\",
8722        \"cmp%d4\\t%2, %3\"},
8723       {\"cmp%d5\\t%0, %1\",
8724        \"cmn%d4\\t%2, #%n3\"},
8725       {\"cmn%d5\\t%0, #%n1\",
8726        \"cmn%d4\\t%2, #%n3\"}
8727     };
8728     static const char * const cmp2[NUM_OF_COND_CMP][2] =
8729     {
8730       {\"cmp\\t%2, %3\",
8731        \"cmp\\t%0, %1\"},
8732       {\"cmp\\t%2, %3\",
8733        \"cmn\\t%0, #%n1\"},
8734       {\"cmn\\t%2, #%n3\",
8735        \"cmp\\t%0, %1\"},
8736       {\"cmn\\t%2, #%n3\",
8737        \"cmn\\t%0, #%n1\"}
8738     };
8739     static const char * const ite[2] =
8740     {
8741       \"it\\t%d5\",
8742       \"it\\t%d4\"
8743     };
8744     static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
8745                                    CMP_CMP, CMN_CMP, CMP_CMP,
8746                                    CMN_CMP, CMP_CMN, CMN_CMN};
8747     int swap =
8748       comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
8750     output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
8751     if (TARGET_THUMB2) {
8752       output_asm_insn (ite[swap], operands);
8753     }
8754     output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
8755     return \"\";
8756   }"
8757   [(set_attr "conds" "set")
8758    (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
8759    (set_attr "type" "multiple")
8760    (set_attr_alternative "length"
8761       [(const_int 6)
8762        (const_int 8)
8763        (const_int 8)
8764        (const_int 8)
8765        (const_int 8)
8766        (if_then_else (eq_attr "is_thumb" "no")
8767            (const_int 8)
8768            (const_int 10))
8769        (if_then_else (eq_attr "is_thumb" "no")
8770            (const_int 8)
8771            (const_int 10))
8772        (if_then_else (eq_attr "is_thumb" "no")
8773            (const_int 8)
8774            (const_int 10))
8775        (if_then_else (eq_attr "is_thumb" "no")
8776            (const_int 8)
8777            (const_int 10))])]
8780 (define_insn "*cmp_ite1"
8781   [(set (match_operand 6 "dominant_cc_register" "")
8782         (compare
8783          (if_then_else:SI
8784           (match_operator 4 "arm_comparison_operator"
8785            [(match_operand:SI 0 "s_register_operand"
8786                 "l,l,l,r,r,r,r,r,r")
8787             (match_operand:SI 1 "arm_add_operand"
8788                 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
8789           (match_operator:SI 5 "arm_comparison_operator"
8790            [(match_operand:SI 2 "s_register_operand"
8791                 "l,r,r,l,l,r,r,r,r")
8792             (match_operand:SI 3 "arm_add_operand"
8793                 "lPy,rI,L,lPy,lPy,rI,rI,L,L")])
8794           (const_int 1))
8795          (const_int 0)))]
8796   "TARGET_32BIT"
8797   "*
8798   {
8799     static const char * const cmp1[NUM_OF_COND_CMP][2] =
8800     {
8801       {\"cmp\\t%0, %1\",
8802        \"cmp\\t%2, %3\"},
8803       {\"cmn\\t%0, #%n1\",
8804        \"cmp\\t%2, %3\"},
8805       {\"cmp\\t%0, %1\",
8806        \"cmn\\t%2, #%n3\"},
8807       {\"cmn\\t%0, #%n1\",
8808        \"cmn\\t%2, #%n3\"}
8809     };
8810     static const char * const cmp2[NUM_OF_COND_CMP][2] =
8811     {
8812       {\"cmp%d4\\t%2, %3\",
8813        \"cmp%D5\\t%0, %1\"},
8814       {\"cmp%d4\\t%2, %3\",
8815        \"cmn%D5\\t%0, #%n1\"},
8816       {\"cmn%d4\\t%2, #%n3\",
8817        \"cmp%D5\\t%0, %1\"},
8818       {\"cmn%d4\\t%2, #%n3\",
8819        \"cmn%D5\\t%0, #%n1\"}
8820     };
8821     static const char * const ite[2] =
8822     {
8823       \"it\\t%d4\",
8824       \"it\\t%D5\"
8825     };
8826     static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
8827                                    CMP_CMP, CMN_CMP, CMP_CMP,
8828                                    CMN_CMP, CMP_CMN, CMN_CMN};
8829     int swap =
8830       comparison_dominates_p (GET_CODE (operands[5]),
8831                               reverse_condition (GET_CODE (operands[4])));
8833     output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
8834     if (TARGET_THUMB2) {
8835       output_asm_insn (ite[swap], operands);
8836     }
8837     output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
8838     return \"\";
8839   }"
8840   [(set_attr "conds" "set")
8841    (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
8842    (set_attr_alternative "length"
8843       [(const_int 6)
8844        (const_int 8)
8845        (const_int 8)
8846        (const_int 8)
8847        (const_int 8)
8848        (if_then_else (eq_attr "is_thumb" "no")
8849            (const_int 8)
8850            (const_int 10))
8851        (if_then_else (eq_attr "is_thumb" "no")
8852            (const_int 8)
8853            (const_int 10))
8854        (if_then_else (eq_attr "is_thumb" "no")
8855            (const_int 8)
8856            (const_int 10))
8857        (if_then_else (eq_attr "is_thumb" "no")
8858            (const_int 8)
8859            (const_int 10))])
8860    (set_attr "type" "multiple")]
8863 (define_insn "*cmp_and"
8864   [(set (match_operand 6 "dominant_cc_register" "")
8865         (compare
8866          (and:SI
8867           (match_operator 4 "arm_comparison_operator"
8868            [(match_operand:SI 0 "s_register_operand" 
8869                 "l,l,l,r,r,r,r,r,r")
8870             (match_operand:SI 1 "arm_add_operand" 
8871                 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
8872           (match_operator:SI 5 "arm_comparison_operator"
8873            [(match_operand:SI 2 "s_register_operand" 
8874                 "l,r,r,l,l,r,r,r,r")
8875             (match_operand:SI 3 "arm_add_operand" 
8876                 "lPy,rI,L,lPy,lPy,rI,rI,L,L")]))
8877          (const_int 0)))]
8878   "TARGET_32BIT"
8879   "*
8880   {
8881     static const char *const cmp1[NUM_OF_COND_CMP][2] =
8882     {
8883       {\"cmp%d5\\t%0, %1\",
8884        \"cmp%d4\\t%2, %3\"},
8885       {\"cmn%d5\\t%0, #%n1\",
8886        \"cmp%d4\\t%2, %3\"},
8887       {\"cmp%d5\\t%0, %1\",
8888        \"cmn%d4\\t%2, #%n3\"},
8889       {\"cmn%d5\\t%0, #%n1\",
8890        \"cmn%d4\\t%2, #%n3\"}
8891     };
8892     static const char *const cmp2[NUM_OF_COND_CMP][2] =
8893     {
8894       {\"cmp\\t%2, %3\",
8895        \"cmp\\t%0, %1\"},
8896       {\"cmp\\t%2, %3\",
8897        \"cmn\\t%0, #%n1\"},
8898       {\"cmn\\t%2, #%n3\",
8899        \"cmp\\t%0, %1\"},
8900       {\"cmn\\t%2, #%n3\",
8901        \"cmn\\t%0, #%n1\"}
8902     };
8903     static const char *const ite[2] =
8904     {
8905       \"it\\t%d5\",
8906       \"it\\t%d4\"
8907     };
8908     static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
8909                                    CMP_CMP, CMN_CMP, CMP_CMP,
8910                                    CMN_CMP, CMP_CMN, CMN_CMN};
8911     int swap =
8912       comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
8914     output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
8915     if (TARGET_THUMB2) {
8916       output_asm_insn (ite[swap], operands);
8917     }
8918     output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
8919     return \"\";
8920   }"
8921   [(set_attr "conds" "set")
8922    (set_attr "predicable" "no")
8923    (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
8924    (set_attr_alternative "length"
8925       [(const_int 6)
8926        (const_int 8)
8927        (const_int 8)
8928        (const_int 8)
8929        (const_int 8)
8930        (if_then_else (eq_attr "is_thumb" "no")
8931            (const_int 8)
8932            (const_int 10))
8933        (if_then_else (eq_attr "is_thumb" "no")
8934            (const_int 8)
8935            (const_int 10))
8936        (if_then_else (eq_attr "is_thumb" "no")
8937            (const_int 8)
8938            (const_int 10))
8939        (if_then_else (eq_attr "is_thumb" "no")
8940            (const_int 8)
8941            (const_int 10))])
8942    (set_attr "type" "multiple")]
8945 (define_insn "*cmp_ior"
8946   [(set (match_operand 6 "dominant_cc_register" "")
8947         (compare
8948          (ior:SI
8949           (match_operator 4 "arm_comparison_operator"
8950            [(match_operand:SI 0 "s_register_operand"
8951                 "l,l,l,r,r,r,r,r,r")
8952             (match_operand:SI 1 "arm_add_operand"
8953                 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
8954           (match_operator:SI 5 "arm_comparison_operator"
8955            [(match_operand:SI 2 "s_register_operand"
8956                 "l,r,r,l,l,r,r,r,r")
8957             (match_operand:SI 3 "arm_add_operand"
8958                 "lPy,rI,L,lPy,lPy,rI,rI,L,L")]))
8959          (const_int 0)))]
8960   "TARGET_32BIT"
8961   "*
8962   {
8963     static const char *const cmp1[NUM_OF_COND_CMP][2] =
8964     {
8965       {\"cmp\\t%0, %1\",
8966        \"cmp\\t%2, %3\"},
8967       {\"cmn\\t%0, #%n1\",
8968        \"cmp\\t%2, %3\"},
8969       {\"cmp\\t%0, %1\",
8970        \"cmn\\t%2, #%n3\"},
8971       {\"cmn\\t%0, #%n1\",
8972        \"cmn\\t%2, #%n3\"}
8973     };
8974     static const char *const cmp2[NUM_OF_COND_CMP][2] =
8975     {
8976       {\"cmp%D4\\t%2, %3\",
8977        \"cmp%D5\\t%0, %1\"},
8978       {\"cmp%D4\\t%2, %3\",
8979        \"cmn%D5\\t%0, #%n1\"},
8980       {\"cmn%D4\\t%2, #%n3\",
8981        \"cmp%D5\\t%0, %1\"},
8982       {\"cmn%D4\\t%2, #%n3\",
8983        \"cmn%D5\\t%0, #%n1\"}
8984     };
8985     static const char *const ite[2] =
8986     {
8987       \"it\\t%D4\",
8988       \"it\\t%D5\"
8989     };
8990     static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
8991                                    CMP_CMP, CMN_CMP, CMP_CMP,
8992                                    CMN_CMP, CMP_CMN, CMN_CMN};
8993     int swap =
8994       comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
8996     output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
8997     if (TARGET_THUMB2) {
8998       output_asm_insn (ite[swap], operands);
8999     }
9000     output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
9001     return \"\";
9002   }
9003   "
9004   [(set_attr "conds" "set")
9005    (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
9006    (set_attr_alternative "length"
9007       [(const_int 6)
9008        (const_int 8)
9009        (const_int 8)
9010        (const_int 8)
9011        (const_int 8)
9012        (if_then_else (eq_attr "is_thumb" "no")
9013            (const_int 8)
9014            (const_int 10))
9015        (if_then_else (eq_attr "is_thumb" "no")
9016            (const_int 8)
9017            (const_int 10))
9018        (if_then_else (eq_attr "is_thumb" "no")
9019            (const_int 8)
9020            (const_int 10))
9021        (if_then_else (eq_attr "is_thumb" "no")
9022            (const_int 8)
9023            (const_int 10))])
9024    (set_attr "type" "multiple")]
9027 (define_insn_and_split "*ior_scc_scc"
9028   [(set (match_operand:SI 0 "s_register_operand" "=Ts")
9029         (ior:SI (match_operator:SI 3 "arm_comparison_operator"
9030                  [(match_operand:SI 1 "s_register_operand" "r")
9031                   (match_operand:SI 2 "arm_add_operand" "rIL")])
9032                 (match_operator:SI 6 "arm_comparison_operator"
9033                  [(match_operand:SI 4 "s_register_operand" "r")
9034                   (match_operand:SI 5 "arm_add_operand" "rIL")])))
9035    (clobber (reg:CC CC_REGNUM))]
9036   "TARGET_32BIT
9037    && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_OR_Y)
9038        != CCmode)"
9039   "#"
9040   "TARGET_32BIT && reload_completed"
9041   [(set (match_dup 7)
9042         (compare
9043          (ior:SI
9044           (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9045           (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9046          (const_int 0)))
9047    (set (match_dup 0) (ne:SI (match_dup 7) (const_int 0)))]
9048   "operands[7]
9049      = gen_rtx_REG (arm_select_dominance_cc_mode (operands[3], operands[6],
9050                                                   DOM_CC_X_OR_Y),
9051                     CC_REGNUM);"
9052   [(set_attr "conds" "clob")
9053    (set_attr "length" "16")
9054    (set_attr "type" "multiple")]
9057 ; If the above pattern is followed by a CMP insn, then the compare is 
9058 ; redundant, since we can rework the conditional instruction that follows.
9059 (define_insn_and_split "*ior_scc_scc_cmp"
9060   [(set (match_operand 0 "dominant_cc_register" "")
9061         (compare (ior:SI (match_operator:SI 3 "arm_comparison_operator"
9062                           [(match_operand:SI 1 "s_register_operand" "r")
9063                            (match_operand:SI 2 "arm_add_operand" "rIL")])
9064                          (match_operator:SI 6 "arm_comparison_operator"
9065                           [(match_operand:SI 4 "s_register_operand" "r")
9066                            (match_operand:SI 5 "arm_add_operand" "rIL")]))
9067                  (const_int 0)))
9068    (set (match_operand:SI 7 "s_register_operand" "=Ts")
9069         (ior:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9070                 (match_op_dup 6 [(match_dup 4) (match_dup 5)])))]
9071   "TARGET_32BIT"
9072   "#"
9073   "TARGET_32BIT && reload_completed"
9074   [(set (match_dup 0)
9075         (compare
9076          (ior:SI
9077           (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9078           (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9079          (const_int 0)))
9080    (set (match_dup 7) (ne:SI (match_dup 0) (const_int 0)))]
9081   ""
9082   [(set_attr "conds" "set")
9083    (set_attr "length" "16")
9084    (set_attr "type" "multiple")]
9087 (define_insn_and_split "*and_scc_scc"
9088   [(set (match_operand:SI 0 "s_register_operand" "=Ts")
9089         (and:SI (match_operator:SI 3 "arm_comparison_operator"
9090                  [(match_operand:SI 1 "s_register_operand" "r")
9091                   (match_operand:SI 2 "arm_add_operand" "rIL")])
9092                 (match_operator:SI 6 "arm_comparison_operator"
9093                  [(match_operand:SI 4 "s_register_operand" "r")
9094                   (match_operand:SI 5 "arm_add_operand" "rIL")])))
9095    (clobber (reg:CC CC_REGNUM))]
9096   "TARGET_32BIT
9097    && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
9098        != CCmode)"
9099   "#"
9100   "TARGET_32BIT && reload_completed
9101    && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
9102        != CCmode)"
9103   [(set (match_dup 7)
9104         (compare
9105          (and:SI
9106           (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9107           (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9108          (const_int 0)))
9109    (set (match_dup 0) (ne:SI (match_dup 7) (const_int 0)))]
9110   "operands[7]
9111      = gen_rtx_REG (arm_select_dominance_cc_mode (operands[3], operands[6],
9112                                                   DOM_CC_X_AND_Y),
9113                     CC_REGNUM);"
9114   [(set_attr "conds" "clob")
9115    (set_attr "length" "16")
9116    (set_attr "type" "multiple")]
9119 ; If the above pattern is followed by a CMP insn, then the compare is 
9120 ; redundant, since we can rework the conditional instruction that follows.
9121 (define_insn_and_split "*and_scc_scc_cmp"
9122   [(set (match_operand 0 "dominant_cc_register" "")
9123         (compare (and:SI (match_operator:SI 3 "arm_comparison_operator"
9124                           [(match_operand:SI 1 "s_register_operand" "r")
9125                            (match_operand:SI 2 "arm_add_operand" "rIL")])
9126                          (match_operator:SI 6 "arm_comparison_operator"
9127                           [(match_operand:SI 4 "s_register_operand" "r")
9128                            (match_operand:SI 5 "arm_add_operand" "rIL")]))
9129                  (const_int 0)))
9130    (set (match_operand:SI 7 "s_register_operand" "=Ts")
9131         (and:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9132                 (match_op_dup 6 [(match_dup 4) (match_dup 5)])))]
9133   "TARGET_32BIT"
9134   "#"
9135   "TARGET_32BIT && reload_completed"
9136   [(set (match_dup 0)
9137         (compare
9138          (and:SI
9139           (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9140           (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9141          (const_int 0)))
9142    (set (match_dup 7) (ne:SI (match_dup 0) (const_int 0)))]
9143   ""
9144   [(set_attr "conds" "set")
9145    (set_attr "length" "16")
9146    (set_attr "type" "multiple")]
9149 ;; If there is no dominance in the comparison, then we can still save an
9150 ;; instruction in the AND case, since we can know that the second compare
9151 ;; need only zero the value if false (if true, then the value is already
9152 ;; correct).
9153 (define_insn_and_split "*and_scc_scc_nodom"
9154   [(set (match_operand:SI 0 "s_register_operand" "=&Ts,&Ts,&Ts")
9155         (and:SI (match_operator:SI 3 "arm_comparison_operator"
9156                  [(match_operand:SI 1 "s_register_operand" "r,r,0")
9157                   (match_operand:SI 2 "arm_add_operand" "rIL,0,rIL")])
9158                 (match_operator:SI 6 "arm_comparison_operator"
9159                  [(match_operand:SI 4 "s_register_operand" "r,r,r")
9160                   (match_operand:SI 5 "arm_add_operand" "rIL,rIL,rIL")])))
9161    (clobber (reg:CC CC_REGNUM))]
9162   "TARGET_32BIT
9163    && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
9164        == CCmode)"
9165   "#"
9166   "TARGET_32BIT && reload_completed"
9167   [(parallel [(set (match_dup 0)
9168                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
9169               (clobber (reg:CC CC_REGNUM))])
9170    (set (match_dup 7) (match_op_dup 8 [(match_dup 4) (match_dup 5)]))
9171    (set (match_dup 0)
9172         (if_then_else:SI (match_op_dup 6 [(match_dup 7) (const_int 0)])
9173                          (match_dup 0)
9174                          (const_int 0)))]
9175   "operands[7] = gen_rtx_REG (SELECT_CC_MODE (GET_CODE (operands[6]),
9176                                               operands[4], operands[5]),
9177                               CC_REGNUM);
9178    operands[8] = gen_rtx_COMPARE (GET_MODE (operands[7]), operands[4],
9179                                   operands[5]);"
9180   [(set_attr "conds" "clob")
9181    (set_attr "length" "20")
9182    (set_attr "type" "multiple")]
9185 (define_split
9186   [(set (reg:CC_NOOV CC_REGNUM)
9187         (compare:CC_NOOV (ior:SI
9188                           (and:SI (match_operand:SI 0 "s_register_operand" "")
9189                                   (const_int 1))
9190                           (match_operator:SI 1 "arm_comparison_operator"
9191                            [(match_operand:SI 2 "s_register_operand" "")
9192                             (match_operand:SI 3 "arm_add_operand" "")]))
9193                          (const_int 0)))
9194    (clobber (match_operand:SI 4 "s_register_operand" ""))]
9195   "TARGET_ARM"
9196   [(set (match_dup 4)
9197         (ior:SI (match_op_dup 1 [(match_dup 2) (match_dup 3)])
9198                 (match_dup 0)))
9199    (set (reg:CC_NOOV CC_REGNUM)
9200         (compare:CC_NOOV (and:SI (match_dup 4) (const_int 1))
9201                          (const_int 0)))]
9202   "")
9204 (define_split
9205   [(set (reg:CC_NOOV CC_REGNUM)
9206         (compare:CC_NOOV (ior:SI
9207                           (match_operator:SI 1 "arm_comparison_operator"
9208                            [(match_operand:SI 2 "s_register_operand" "")
9209                             (match_operand:SI 3 "arm_add_operand" "")])
9210                           (and:SI (match_operand:SI 0 "s_register_operand" "")
9211                                   (const_int 1)))
9212                          (const_int 0)))
9213    (clobber (match_operand:SI 4 "s_register_operand" ""))]
9214   "TARGET_ARM"
9215   [(set (match_dup 4)
9216         (ior:SI (match_op_dup 1 [(match_dup 2) (match_dup 3)])
9217                 (match_dup 0)))
9218    (set (reg:CC_NOOV CC_REGNUM)
9219         (compare:CC_NOOV (and:SI (match_dup 4) (const_int 1))
9220                          (const_int 0)))]
9221   "")
9222 ;; ??? The conditional patterns above need checking for Thumb-2 usefulness
9224 (define_insn_and_split "*negscc"
9225   [(set (match_operand:SI 0 "s_register_operand" "=r")
9226         (neg:SI (match_operator 3 "arm_comparison_operator"
9227                  [(match_operand:SI 1 "s_register_operand" "r")
9228                   (match_operand:SI 2 "arm_rhs_operand" "rI")])))
9229    (clobber (reg:CC CC_REGNUM))]
9230   "TARGET_ARM"
9231   "#"
9232   "&& reload_completed"
9233   [(const_int 0)]
9234   {
9235     rtx cc_reg = gen_rtx_REG (CCmode, CC_REGNUM);
9237     if (GET_CODE (operands[3]) == LT && operands[2] == const0_rtx)
9238        {
9239          /* Emit mov\\t%0, %1, asr #31 */
9240          emit_insn (gen_rtx_SET (operands[0],
9241                                  gen_rtx_ASHIFTRT (SImode,
9242                                                    operands[1],
9243                                                    GEN_INT (31))));
9244          DONE;
9245        }
9246      else if (GET_CODE (operands[3]) == NE)
9247        {
9248         /* Emit subs\\t%0, %1, %2\;mvnne\\t%0, #0 */
9249         if (CONST_INT_P (operands[2]))
9250           emit_insn (gen_cmpsi2_addneg (operands[0], operands[1], operands[2],
9251                                         GEN_INT (- INTVAL (operands[2]))));
9252         else
9253           emit_insn (gen_subsi3_compare (operands[0], operands[1], operands[2]));
9255         emit_insn (gen_rtx_COND_EXEC (VOIDmode,
9256                                       gen_rtx_NE (SImode,
9257                                                   cc_reg,
9258                                                   const0_rtx),
9259                                       gen_rtx_SET (operands[0],
9260                                                    GEN_INT (~0))));
9261         DONE;
9262       }
9263     else
9264       {
9265         /* Emit: cmp\\t%1, %2\;mov%D3\\t%0, #0\;mvn%d3\\t%0, #0 */
9266         emit_insn (gen_rtx_SET (cc_reg,
9267                                 gen_rtx_COMPARE (CCmode, operands[1], operands[2])));
9268         enum rtx_code rc = GET_CODE (operands[3]);
9270         rc = reverse_condition (rc);
9271         emit_insn (gen_rtx_COND_EXEC (VOIDmode,
9272                                       gen_rtx_fmt_ee (rc,
9273                                                       VOIDmode,
9274                                                       cc_reg,
9275                                                       const0_rtx),
9276                                       gen_rtx_SET (operands[0], const0_rtx)));
9277         rc = GET_CODE (operands[3]);
9278         emit_insn (gen_rtx_COND_EXEC (VOIDmode,
9279                                       gen_rtx_fmt_ee (rc,
9280                                                       VOIDmode,
9281                                                       cc_reg,
9282                                                       const0_rtx),
9283                                       gen_rtx_SET (operands[0],
9284                                                    GEN_INT (~0))));
9285         DONE;
9286       }
9287      FAIL;
9288   }
9289   [(set_attr "conds" "clob")
9290    (set_attr "length" "12")
9291    (set_attr "type" "multiple")]
9294 (define_insn_and_split "movcond_addsi"
9295   [(set (match_operand:SI 0 "s_register_operand" "=r,l,r")
9296         (if_then_else:SI
9297          (match_operator 5 "comparison_operator"
9298           [(plus:SI (match_operand:SI 3 "s_register_operand" "r,r,r")
9299                     (match_operand:SI 4 "arm_add_operand" "rIL,rIL,rIL"))
9300             (const_int 0)])
9301          (match_operand:SI 1 "arm_rhs_operand" "rI,rPy,r")
9302          (match_operand:SI 2 "arm_rhs_operand" "rI,rPy,r")))
9303    (clobber (reg:CC CC_REGNUM))]
9304    "TARGET_32BIT"
9305    "#"
9306    "&& reload_completed"
9307   [(set (reg:CC_NOOV CC_REGNUM)
9308         (compare:CC_NOOV
9309          (plus:SI (match_dup 3)
9310                   (match_dup 4))
9311          (const_int 0)))
9312    (set (match_dup 0) (match_dup 1))
9313    (cond_exec (match_dup 6)
9314               (set (match_dup 0) (match_dup 2)))]
9315   "
9316   {
9317     machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[5]),
9318                                              operands[3], operands[4]);
9319     enum rtx_code rc = GET_CODE (operands[5]);
9320     operands[6] = gen_rtx_REG (mode, CC_REGNUM);
9321     gcc_assert (!(mode == CCFPmode || mode == CCFPEmode));
9322     if (REGNO (operands[2]) != REGNO (operands[0]))
9323       rc = reverse_condition (rc);
9324     else
9325       std::swap (operands[1], operands[2]);
9327     operands[6] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
9328   }
9329   "
9330   [(set_attr "conds" "clob")
9331    (set_attr "enabled_for_depr_it" "no,yes,yes")
9332    (set_attr "type" "multiple")]
9335 (define_insn "movcond"
9336   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9337         (if_then_else:SI
9338          (match_operator 5 "arm_comparison_operator"
9339           [(match_operand:SI 3 "s_register_operand" "r,r,r")
9340            (match_operand:SI 4 "arm_add_operand" "rIL,rIL,rIL")])
9341          (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
9342          (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
9343    (clobber (reg:CC CC_REGNUM))]
9344   "TARGET_ARM"
9345   "*
9346   if (GET_CODE (operands[5]) == LT
9347       && (operands[4] == const0_rtx))
9348     {
9349       if (which_alternative != 1 && REG_P (operands[1]))
9350         {
9351           if (operands[2] == const0_rtx)
9352             return \"and\\t%0, %1, %3, asr #31\";
9353           return \"ands\\t%0, %1, %3, asr #32\;movcc\\t%0, %2\";
9354         }
9355       else if (which_alternative != 0 && REG_P (operands[2]))
9356         {
9357           if (operands[1] == const0_rtx)
9358             return \"bic\\t%0, %2, %3, asr #31\";
9359           return \"bics\\t%0, %2, %3, asr #32\;movcs\\t%0, %1\";
9360         }
9361       /* The only case that falls through to here is when both ops 1 & 2
9362          are constants.  */
9363     }
9365   if (GET_CODE (operands[5]) == GE
9366       && (operands[4] == const0_rtx))
9367     {
9368       if (which_alternative != 1 && REG_P (operands[1]))
9369         {
9370           if (operands[2] == const0_rtx)
9371             return \"bic\\t%0, %1, %3, asr #31\";
9372           return \"bics\\t%0, %1, %3, asr #32\;movcs\\t%0, %2\";
9373         }
9374       else if (which_alternative != 0 && REG_P (operands[2]))
9375         {
9376           if (operands[1] == const0_rtx)
9377             return \"and\\t%0, %2, %3, asr #31\";
9378           return \"ands\\t%0, %2, %3, asr #32\;movcc\\t%0, %1\";
9379         }
9380       /* The only case that falls through to here is when both ops 1 & 2
9381          are constants.  */
9382     }
9383   if (CONST_INT_P (operands[4])
9384       && !const_ok_for_arm (INTVAL (operands[4])))
9385     output_asm_insn (\"cmn\\t%3, #%n4\", operands);
9386   else
9387     output_asm_insn (\"cmp\\t%3, %4\", operands);
9388   if (which_alternative != 0)
9389     output_asm_insn (\"mov%d5\\t%0, %1\", operands);
9390   if (which_alternative != 1)
9391     output_asm_insn (\"mov%D5\\t%0, %2\", operands);
9392   return \"\";
9393   "
9394   [(set_attr "conds" "clob")
9395    (set_attr "length" "8,8,12")
9396    (set_attr "type" "multiple")]
9399 ;; ??? The patterns below need checking for Thumb-2 usefulness.
9401 (define_insn "*ifcompare_plus_move"
9402   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9403         (if_then_else:SI (match_operator 6 "arm_comparison_operator"
9404                           [(match_operand:SI 4 "s_register_operand" "r,r")
9405                            (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
9406                          (plus:SI
9407                           (match_operand:SI 2 "s_register_operand" "r,r")
9408                           (match_operand:SI 3 "arm_add_operand" "rIL,rIL"))
9409                          (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))
9410    (clobber (reg:CC CC_REGNUM))]
9411   "TARGET_ARM"
9412   "#"
9413   [(set_attr "conds" "clob")
9414    (set_attr "length" "8,12")
9415    (set_attr "type" "multiple")]
9418 (define_insn "*if_plus_move"
9419   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
9420         (if_then_else:SI
9421          (match_operator 4 "arm_comparison_operator"
9422           [(match_operand 5 "cc_register" "") (const_int 0)])
9423          (plus:SI
9424           (match_operand:SI 2 "s_register_operand" "r,r,r,r")
9425           (match_operand:SI 3 "arm_add_operand" "rI,L,rI,L"))
9426          (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")))]
9427   "TARGET_ARM"
9428   "@
9429    add%d4\\t%0, %2, %3
9430    sub%d4\\t%0, %2, #%n3
9431    add%d4\\t%0, %2, %3\;mov%D4\\t%0, %1
9432    sub%d4\\t%0, %2, #%n3\;mov%D4\\t%0, %1"
9433   [(set_attr "conds" "use")
9434    (set_attr "length" "4,4,8,8")
9435    (set_attr_alternative "type"
9436                          [(if_then_else (match_operand 3 "const_int_operand" "")
9437                                         (const_string "alu_imm" )
9438                                         (const_string "alu_sreg"))
9439                           (const_string "alu_imm")
9440                           (const_string "multiple")
9441                           (const_string "multiple")])]
9444 (define_insn "*ifcompare_move_plus"
9445   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9446         (if_then_else:SI (match_operator 6 "arm_comparison_operator"
9447                           [(match_operand:SI 4 "s_register_operand" "r,r")
9448                            (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
9449                          (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
9450                          (plus:SI
9451                           (match_operand:SI 2 "s_register_operand" "r,r")
9452                           (match_operand:SI 3 "arm_add_operand" "rIL,rIL"))))
9453    (clobber (reg:CC CC_REGNUM))]
9454   "TARGET_ARM"
9455   "#"
9456   [(set_attr "conds" "clob")
9457    (set_attr "length" "8,12")
9458    (set_attr "type" "multiple")]
9461 (define_insn "*if_move_plus"
9462   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
9463         (if_then_else:SI
9464          (match_operator 4 "arm_comparison_operator"
9465           [(match_operand 5 "cc_register" "") (const_int 0)])
9466          (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")
9467          (plus:SI
9468           (match_operand:SI 2 "s_register_operand" "r,r,r,r")
9469           (match_operand:SI 3 "arm_add_operand" "rI,L,rI,L"))))]
9470   "TARGET_ARM"
9471   "@
9472    add%D4\\t%0, %2, %3
9473    sub%D4\\t%0, %2, #%n3
9474    add%D4\\t%0, %2, %3\;mov%d4\\t%0, %1
9475    sub%D4\\t%0, %2, #%n3\;mov%d4\\t%0, %1"
9476   [(set_attr "conds" "use")
9477    (set_attr "length" "4,4,8,8")
9478    (set_attr_alternative "type"
9479                          [(if_then_else (match_operand 3 "const_int_operand" "")
9480                                         (const_string "alu_imm" )
9481                                         (const_string "alu_sreg"))
9482                           (const_string "alu_imm")
9483                           (const_string "multiple")
9484                           (const_string "multiple")])]
9487 (define_insn "*ifcompare_arith_arith"
9488   [(set (match_operand:SI 0 "s_register_operand" "=r")
9489         (if_then_else:SI (match_operator 9 "arm_comparison_operator"
9490                           [(match_operand:SI 5 "s_register_operand" "r")
9491                            (match_operand:SI 6 "arm_add_operand" "rIL")])
9492                          (match_operator:SI 8 "shiftable_operator"
9493                           [(match_operand:SI 1 "s_register_operand" "r")
9494                            (match_operand:SI 2 "arm_rhs_operand" "rI")])
9495                          (match_operator:SI 7 "shiftable_operator"
9496                           [(match_operand:SI 3 "s_register_operand" "r")
9497                            (match_operand:SI 4 "arm_rhs_operand" "rI")])))
9498    (clobber (reg:CC CC_REGNUM))]
9499   "TARGET_ARM"
9500   "#"
9501   [(set_attr "conds" "clob")
9502    (set_attr "length" "12")
9503    (set_attr "type" "multiple")]
9506 (define_insn "*if_arith_arith"
9507   [(set (match_operand:SI 0 "s_register_operand" "=r")
9508         (if_then_else:SI (match_operator 5 "arm_comparison_operator"
9509                           [(match_operand 8 "cc_register" "") (const_int 0)])
9510                          (match_operator:SI 6 "shiftable_operator"
9511                           [(match_operand:SI 1 "s_register_operand" "r")
9512                            (match_operand:SI 2 "arm_rhs_operand" "rI")])
9513                          (match_operator:SI 7 "shiftable_operator"
9514                           [(match_operand:SI 3 "s_register_operand" "r")
9515                            (match_operand:SI 4 "arm_rhs_operand" "rI")])))]
9516   "TARGET_ARM"
9517   "%I6%d5\\t%0, %1, %2\;%I7%D5\\t%0, %3, %4"
9518   [(set_attr "conds" "use")
9519    (set_attr "length" "8")
9520    (set_attr "type" "multiple")]
9523 (define_insn "*ifcompare_arith_move"
9524   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9525         (if_then_else:SI (match_operator 6 "arm_comparison_operator"
9526                           [(match_operand:SI 2 "s_register_operand" "r,r")
9527                            (match_operand:SI 3 "arm_add_operand" "rIL,rIL")])
9528                          (match_operator:SI 7 "shiftable_operator"
9529                           [(match_operand:SI 4 "s_register_operand" "r,r")
9530                            (match_operand:SI 5 "arm_rhs_operand" "rI,rI")])
9531                          (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))
9532    (clobber (reg:CC CC_REGNUM))]
9533   "TARGET_ARM"
9534   "*
9535   /* If we have an operation where (op x 0) is the identity operation and
9536      the conditional operator is LT or GE and we are comparing against zero and
9537      everything is in registers then we can do this in two instructions.  */
9538   if (operands[3] == const0_rtx
9539       && GET_CODE (operands[7]) != AND
9540       && REG_P (operands[5])
9541       && REG_P (operands[1])
9542       && REGNO (operands[1]) == REGNO (operands[4])
9543       && REGNO (operands[4]) != REGNO (operands[0]))
9544     {
9545       if (GET_CODE (operands[6]) == LT)
9546         return \"and\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\";
9547       else if (GET_CODE (operands[6]) == GE)
9548         return \"bic\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\";
9549     }
9550   if (CONST_INT_P (operands[3])
9551       && !const_ok_for_arm (INTVAL (operands[3])))
9552     output_asm_insn (\"cmn\\t%2, #%n3\", operands);
9553   else
9554     output_asm_insn (\"cmp\\t%2, %3\", operands);
9555   output_asm_insn (\"%I7%d6\\t%0, %4, %5\", operands);
9556   if (which_alternative != 0)
9557     return \"mov%D6\\t%0, %1\";
9558   return \"\";
9559   "
9560   [(set_attr "conds" "clob")
9561    (set_attr "length" "8,12")
9562    (set_attr "type" "multiple")]
9565 (define_insn "*if_arith_move"
9566   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9567         (if_then_else:SI (match_operator 4 "arm_comparison_operator"
9568                           [(match_operand 6 "cc_register" "") (const_int 0)])
9569                          (match_operator:SI 5 "shiftable_operator"
9570                           [(match_operand:SI 2 "s_register_operand" "r,r")
9571                            (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
9572                          (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))]
9573   "TARGET_ARM"
9574   "@
9575    %I5%d4\\t%0, %2, %3
9576    %I5%d4\\t%0, %2, %3\;mov%D4\\t%0, %1"
9577   [(set_attr "conds" "use")
9578    (set_attr "length" "4,8")
9579    (set_attr_alternative "type"
9580                          [(if_then_else (match_operand 3 "const_int_operand" "")
9581                                         (const_string "alu_shift_imm" )
9582                                         (const_string "alu_shift_reg"))
9583                           (const_string "multiple")])]
9586 (define_insn "*ifcompare_move_arith"
9587   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9588         (if_then_else:SI (match_operator 6 "arm_comparison_operator"
9589                           [(match_operand:SI 4 "s_register_operand" "r,r")
9590                            (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
9591                          (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
9592                          (match_operator:SI 7 "shiftable_operator"
9593                           [(match_operand:SI 2 "s_register_operand" "r,r")
9594                            (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
9595    (clobber (reg:CC CC_REGNUM))]
9596   "TARGET_ARM"
9597   "*
9598   /* If we have an operation where (op x 0) is the identity operation and
9599      the conditional operator is LT or GE and we are comparing against zero and
9600      everything is in registers then we can do this in two instructions */
9601   if (operands[5] == const0_rtx
9602       && GET_CODE (operands[7]) != AND
9603       && REG_P (operands[3])
9604       && REG_P (operands[1])
9605       && REGNO (operands[1]) == REGNO (operands[2])
9606       && REGNO (operands[2]) != REGNO (operands[0]))
9607     {
9608       if (GET_CODE (operands[6]) == GE)
9609         return \"and\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\";
9610       else if (GET_CODE (operands[6]) == LT)
9611         return \"bic\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\";
9612     }
9614   if (CONST_INT_P (operands[5])
9615       && !const_ok_for_arm (INTVAL (operands[5])))
9616     output_asm_insn (\"cmn\\t%4, #%n5\", operands);
9617   else
9618     output_asm_insn (\"cmp\\t%4, %5\", operands);
9620   if (which_alternative != 0)
9621     output_asm_insn (\"mov%d6\\t%0, %1\", operands);
9622   return \"%I7%D6\\t%0, %2, %3\";
9623   "
9624   [(set_attr "conds" "clob")
9625    (set_attr "length" "8,12")
9626    (set_attr "type" "multiple")]
9629 (define_insn "*if_move_arith"
9630   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9631         (if_then_else:SI
9632          (match_operator 4 "arm_comparison_operator"
9633           [(match_operand 6 "cc_register" "") (const_int 0)])
9634          (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
9635          (match_operator:SI 5 "shiftable_operator"
9636           [(match_operand:SI 2 "s_register_operand" "r,r")
9637            (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))]
9638   "TARGET_ARM"
9639   "@
9640    %I5%D4\\t%0, %2, %3
9641    %I5%D4\\t%0, %2, %3\;mov%d4\\t%0, %1"
9642   [(set_attr "conds" "use")
9643    (set_attr "length" "4,8")
9644    (set_attr_alternative "type"
9645                          [(if_then_else (match_operand 3 "const_int_operand" "")
9646                                         (const_string "alu_shift_imm" )
9647                                         (const_string "alu_shift_reg"))
9648                           (const_string "multiple")])]
9651 (define_insn "*ifcompare_move_not"
9652   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9653         (if_then_else:SI
9654          (match_operator 5 "arm_comparison_operator"
9655           [(match_operand:SI 3 "s_register_operand" "r,r")
9656            (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
9657          (match_operand:SI 1 "arm_not_operand" "0,?rIK")
9658          (not:SI
9659           (match_operand:SI 2 "s_register_operand" "r,r"))))
9660    (clobber (reg:CC CC_REGNUM))]
9661   "TARGET_ARM"
9662   "#"
9663   [(set_attr "conds" "clob")
9664    (set_attr "length" "8,12")
9665    (set_attr "type" "multiple")]
9668 (define_insn "*if_move_not"
9669   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9670         (if_then_else:SI
9671          (match_operator 4 "arm_comparison_operator"
9672           [(match_operand 3 "cc_register" "") (const_int 0)])
9673          (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
9674          (not:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))))]
9675   "TARGET_ARM"
9676   "@
9677    mvn%D4\\t%0, %2
9678    mov%d4\\t%0, %1\;mvn%D4\\t%0, %2
9679    mvn%d4\\t%0, #%B1\;mvn%D4\\t%0, %2"
9680   [(set_attr "conds" "use")
9681    (set_attr "type" "mvn_reg")
9682    (set_attr "length" "4,8,8")
9683    (set_attr "type" "mvn_reg,multiple,multiple")]
9686 (define_insn "*ifcompare_not_move"
9687   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9688         (if_then_else:SI 
9689          (match_operator 5 "arm_comparison_operator"
9690           [(match_operand:SI 3 "s_register_operand" "r,r")
9691            (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
9692          (not:SI
9693           (match_operand:SI 2 "s_register_operand" "r,r"))
9694          (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
9695    (clobber (reg:CC CC_REGNUM))]
9696   "TARGET_ARM"
9697   "#"
9698   [(set_attr "conds" "clob")
9699    (set_attr "length" "8,12")
9700    (set_attr "type" "multiple")]
9703 (define_insn "*if_not_move"
9704   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9705         (if_then_else:SI
9706          (match_operator 4 "arm_comparison_operator"
9707           [(match_operand 3 "cc_register" "") (const_int 0)])
9708          (not:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))
9709          (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
9710   "TARGET_ARM"
9711   "@
9712    mvn%d4\\t%0, %2
9713    mov%D4\\t%0, %1\;mvn%d4\\t%0, %2
9714    mvn%D4\\t%0, #%B1\;mvn%d4\\t%0, %2"
9715   [(set_attr "conds" "use")
9716    (set_attr "type" "mvn_reg,multiple,multiple")
9717    (set_attr "length" "4,8,8")]
9720 (define_insn "*ifcompare_shift_move"
9721   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9722         (if_then_else:SI
9723          (match_operator 6 "arm_comparison_operator"
9724           [(match_operand:SI 4 "s_register_operand" "r,r")
9725            (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
9726          (match_operator:SI 7 "shift_operator"
9727           [(match_operand:SI 2 "s_register_operand" "r,r")
9728            (match_operand:SI 3 "arm_rhs_operand" "rM,rM")])
9729          (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
9730    (clobber (reg:CC CC_REGNUM))]
9731   "TARGET_ARM"
9732   "#"
9733   [(set_attr "conds" "clob")
9734    (set_attr "length" "8,12")
9735    (set_attr "type" "multiple")]
9738 (define_insn "*if_shift_move"
9739   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9740         (if_then_else:SI
9741          (match_operator 5 "arm_comparison_operator"
9742           [(match_operand 6 "cc_register" "") (const_int 0)])
9743          (match_operator:SI 4 "shift_operator"
9744           [(match_operand:SI 2 "s_register_operand" "r,r,r")
9745            (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM")])
9746          (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
9747   "TARGET_ARM"
9748   "@
9749    mov%d5\\t%0, %2%S4
9750    mov%D5\\t%0, %1\;mov%d5\\t%0, %2%S4
9751    mvn%D5\\t%0, #%B1\;mov%d5\\t%0, %2%S4"
9752   [(set_attr "conds" "use")
9753    (set_attr "shift" "2")
9754    (set_attr "length" "4,8,8")
9755    (set_attr_alternative "type"
9756                          [(if_then_else (match_operand 3 "const_int_operand" "")
9757                                         (const_string "mov_shift" )
9758                                         (const_string "mov_shift_reg"))
9759                           (const_string "multiple")
9760                           (const_string "multiple")])]
9763 (define_insn "*ifcompare_move_shift"
9764   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9765         (if_then_else:SI
9766          (match_operator 6 "arm_comparison_operator"
9767           [(match_operand:SI 4 "s_register_operand" "r,r")
9768            (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
9769          (match_operand:SI 1 "arm_not_operand" "0,?rIK")
9770          (match_operator:SI 7 "shift_operator"
9771           [(match_operand:SI 2 "s_register_operand" "r,r")
9772            (match_operand:SI 3 "arm_rhs_operand" "rM,rM")])))
9773    (clobber (reg:CC CC_REGNUM))]
9774   "TARGET_ARM"
9775   "#"
9776   [(set_attr "conds" "clob")
9777    (set_attr "length" "8,12")
9778    (set_attr "type" "multiple")]
9781 (define_insn "*if_move_shift"
9782   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9783         (if_then_else:SI
9784          (match_operator 5 "arm_comparison_operator"
9785           [(match_operand 6 "cc_register" "") (const_int 0)])
9786          (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
9787          (match_operator:SI 4 "shift_operator"
9788           [(match_operand:SI 2 "s_register_operand" "r,r,r")
9789            (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM")])))]
9790   "TARGET_ARM"
9791   "@
9792    mov%D5\\t%0, %2%S4
9793    mov%d5\\t%0, %1\;mov%D5\\t%0, %2%S4
9794    mvn%d5\\t%0, #%B1\;mov%D5\\t%0, %2%S4"
9795   [(set_attr "conds" "use")
9796    (set_attr "shift" "2")
9797    (set_attr "length" "4,8,8")
9798    (set_attr_alternative "type"
9799                          [(if_then_else (match_operand 3 "const_int_operand" "")
9800                                         (const_string "mov_shift" )
9801                                         (const_string "mov_shift_reg"))
9802                           (const_string "multiple")
9803                           (const_string "multiple")])]
9806 (define_insn "*ifcompare_shift_shift"
9807   [(set (match_operand:SI 0 "s_register_operand" "=r")
9808         (if_then_else:SI
9809          (match_operator 7 "arm_comparison_operator"
9810           [(match_operand:SI 5 "s_register_operand" "r")
9811            (match_operand:SI 6 "arm_add_operand" "rIL")])
9812          (match_operator:SI 8 "shift_operator"
9813           [(match_operand:SI 1 "s_register_operand" "r")
9814            (match_operand:SI 2 "arm_rhs_operand" "rM")])
9815          (match_operator:SI 9 "shift_operator"
9816           [(match_operand:SI 3 "s_register_operand" "r")
9817            (match_operand:SI 4 "arm_rhs_operand" "rM")])))
9818    (clobber (reg:CC CC_REGNUM))]
9819   "TARGET_ARM"
9820   "#"
9821   [(set_attr "conds" "clob")
9822    (set_attr "length" "12")
9823    (set_attr "type" "multiple")]
9826 (define_insn "*if_shift_shift"
9827   [(set (match_operand:SI 0 "s_register_operand" "=r")
9828         (if_then_else:SI
9829          (match_operator 5 "arm_comparison_operator"
9830           [(match_operand 8 "cc_register" "") (const_int 0)])
9831          (match_operator:SI 6 "shift_operator"
9832           [(match_operand:SI 1 "s_register_operand" "r")
9833            (match_operand:SI 2 "arm_rhs_operand" "rM")])
9834          (match_operator:SI 7 "shift_operator"
9835           [(match_operand:SI 3 "s_register_operand" "r")
9836            (match_operand:SI 4 "arm_rhs_operand" "rM")])))]
9837   "TARGET_ARM"
9838   "mov%d5\\t%0, %1%S6\;mov%D5\\t%0, %3%S7"
9839   [(set_attr "conds" "use")
9840    (set_attr "shift" "1")
9841    (set_attr "length" "8")
9842    (set (attr "type") (if_then_else
9843                         (and (match_operand 2 "const_int_operand" "")
9844                              (match_operand 4 "const_int_operand" ""))
9845                       (const_string "mov_shift")
9846                       (const_string "mov_shift_reg")))]
9849 (define_insn "*ifcompare_not_arith"
9850   [(set (match_operand:SI 0 "s_register_operand" "=r")
9851         (if_then_else:SI
9852          (match_operator 6 "arm_comparison_operator"
9853           [(match_operand:SI 4 "s_register_operand" "r")
9854            (match_operand:SI 5 "arm_add_operand" "rIL")])
9855          (not:SI (match_operand:SI 1 "s_register_operand" "r"))
9856          (match_operator:SI 7 "shiftable_operator"
9857           [(match_operand:SI 2 "s_register_operand" "r")
9858            (match_operand:SI 3 "arm_rhs_operand" "rI")])))
9859    (clobber (reg:CC CC_REGNUM))]
9860   "TARGET_ARM"
9861   "#"
9862   [(set_attr "conds" "clob")
9863    (set_attr "length" "12")
9864    (set_attr "type" "multiple")]
9867 (define_insn "*if_not_arith"
9868   [(set (match_operand:SI 0 "s_register_operand" "=r")
9869         (if_then_else:SI
9870          (match_operator 5 "arm_comparison_operator"
9871           [(match_operand 4 "cc_register" "") (const_int 0)])
9872          (not:SI (match_operand:SI 1 "s_register_operand" "r"))
9873          (match_operator:SI 6 "shiftable_operator"
9874           [(match_operand:SI 2 "s_register_operand" "r")
9875            (match_operand:SI 3 "arm_rhs_operand" "rI")])))]
9876   "TARGET_ARM"
9877   "mvn%d5\\t%0, %1\;%I6%D5\\t%0, %2, %3"
9878   [(set_attr "conds" "use")
9879    (set_attr "type" "mvn_reg")
9880    (set_attr "length" "8")]
9883 (define_insn "*ifcompare_arith_not"
9884   [(set (match_operand:SI 0 "s_register_operand" "=r")
9885         (if_then_else:SI
9886          (match_operator 6 "arm_comparison_operator"
9887           [(match_operand:SI 4 "s_register_operand" "r")
9888            (match_operand:SI 5 "arm_add_operand" "rIL")])
9889          (match_operator:SI 7 "shiftable_operator"
9890           [(match_operand:SI 2 "s_register_operand" "r")
9891            (match_operand:SI 3 "arm_rhs_operand" "rI")])
9892          (not:SI (match_operand:SI 1 "s_register_operand" "r"))))
9893    (clobber (reg:CC CC_REGNUM))]
9894   "TARGET_ARM"
9895   "#"
9896   [(set_attr "conds" "clob")
9897    (set_attr "length" "12")
9898    (set_attr "type" "multiple")]
9901 (define_insn "*if_arith_not"
9902   [(set (match_operand:SI 0 "s_register_operand" "=r")
9903         (if_then_else:SI
9904          (match_operator 5 "arm_comparison_operator"
9905           [(match_operand 4 "cc_register" "") (const_int 0)])
9906          (match_operator:SI 6 "shiftable_operator"
9907           [(match_operand:SI 2 "s_register_operand" "r")
9908            (match_operand:SI 3 "arm_rhs_operand" "rI")])
9909          (not:SI (match_operand:SI 1 "s_register_operand" "r"))))]
9910   "TARGET_ARM"
9911   "mvn%D5\\t%0, %1\;%I6%d5\\t%0, %2, %3"
9912   [(set_attr "conds" "use")
9913    (set_attr "type" "multiple")
9914    (set_attr "length" "8")]
9917 (define_insn "*ifcompare_neg_move"
9918   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9919         (if_then_else:SI
9920          (match_operator 5 "arm_comparison_operator"
9921           [(match_operand:SI 3 "s_register_operand" "r,r")
9922            (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
9923          (neg:SI (match_operand:SI 2 "s_register_operand" "r,r"))
9924          (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
9925    (clobber (reg:CC CC_REGNUM))]
9926   "TARGET_ARM"
9927   "#"
9928   [(set_attr "conds" "clob")
9929    (set_attr "length" "8,12")
9930    (set_attr "type" "multiple")]
9933 (define_insn "*if_neg_move"
9934   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9935         (if_then_else:SI
9936          (match_operator 4 "arm_comparison_operator"
9937           [(match_operand 3 "cc_register" "") (const_int 0)])
9938          (neg:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))
9939          (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
9940   "TARGET_ARM"
9941   "@
9942    rsb%d4\\t%0, %2, #0
9943    mov%D4\\t%0, %1\;rsb%d4\\t%0, %2, #0
9944    mvn%D4\\t%0, #%B1\;rsb%d4\\t%0, %2, #0"
9945   [(set_attr "conds" "use")
9946    (set_attr "length" "4,8,8")
9947    (set_attr "type" "logic_shift_imm,multiple,multiple")]
9950 (define_insn "*ifcompare_move_neg"
9951   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9952         (if_then_else:SI
9953          (match_operator 5 "arm_comparison_operator"
9954           [(match_operand:SI 3 "s_register_operand" "r,r")
9955            (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
9956          (match_operand:SI 1 "arm_not_operand" "0,?rIK")
9957          (neg:SI (match_operand:SI 2 "s_register_operand" "r,r"))))
9958    (clobber (reg:CC CC_REGNUM))]
9959   "TARGET_ARM"
9960   "#"
9961   [(set_attr "conds" "clob")
9962    (set_attr "length" "8,12")
9963    (set_attr "type" "multiple")]
9966 (define_insn "*if_move_neg"
9967   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9968         (if_then_else:SI
9969          (match_operator 4 "arm_comparison_operator"
9970           [(match_operand 3 "cc_register" "") (const_int 0)])
9971          (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
9972          (neg:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))))]
9973   "TARGET_ARM"
9974   "@
9975    rsb%D4\\t%0, %2, #0
9976    mov%d4\\t%0, %1\;rsb%D4\\t%0, %2, #0
9977    mvn%d4\\t%0, #%B1\;rsb%D4\\t%0, %2, #0"
9978   [(set_attr "conds" "use")
9979    (set_attr "length" "4,8,8")
9980    (set_attr "type" "logic_shift_imm,multiple,multiple")]
9983 (define_insn "*arith_adjacentmem"
9984   [(set (match_operand:SI 0 "s_register_operand" "=r")
9985         (match_operator:SI 1 "shiftable_operator"
9986          [(match_operand:SI 2 "memory_operand" "m")
9987           (match_operand:SI 3 "memory_operand" "m")]))
9988    (clobber (match_scratch:SI 4 "=r"))]
9989   "TARGET_ARM && adjacent_mem_locations (operands[2], operands[3])"
9990   "*
9991   {
9992     rtx ldm[3];
9993     rtx arith[4];
9994     rtx base_reg;
9995     HOST_WIDE_INT val1 = 0, val2 = 0;
9997     if (REGNO (operands[0]) > REGNO (operands[4]))
9998       {
9999         ldm[1] = operands[4];
10000         ldm[2] = operands[0];
10001       }
10002     else
10003       {
10004         ldm[1] = operands[0];
10005         ldm[2] = operands[4];
10006       }
10008     base_reg = XEXP (operands[2], 0);
10010     if (!REG_P (base_reg))
10011       {
10012         val1 = INTVAL (XEXP (base_reg, 1));
10013         base_reg = XEXP (base_reg, 0);
10014       }
10016     if (!REG_P (XEXP (operands[3], 0)))
10017       val2 = INTVAL (XEXP (XEXP (operands[3], 0), 1));
10019     arith[0] = operands[0];
10020     arith[3] = operands[1];
10022     if (val1 < val2)
10023       {
10024         arith[1] = ldm[1];
10025         arith[2] = ldm[2];
10026       }
10027     else
10028       {
10029         arith[1] = ldm[2];
10030         arith[2] = ldm[1];
10031       }
10033     ldm[0] = base_reg;
10034     if (val1 !=0 && val2 != 0)
10035       {
10036         rtx ops[3];
10038         if (val1 == 4 || val2 == 4)
10039           /* Other val must be 8, since we know they are adjacent and neither
10040              is zero.  */
10041           output_asm_insn (\"ldm%(ib%)\\t%0, {%1, %2}\", ldm);
10042         else if (const_ok_for_arm (val1) || const_ok_for_arm (-val1))
10043           {
10044             ldm[0] = ops[0] = operands[4];
10045             ops[1] = base_reg;
10046             ops[2] = GEN_INT (val1);
10047             output_add_immediate (ops);
10048             if (val1 < val2)
10049               output_asm_insn (\"ldm%(ia%)\\t%0, {%1, %2}\", ldm);
10050             else
10051               output_asm_insn (\"ldm%(da%)\\t%0, {%1, %2}\", ldm);
10052           }
10053         else
10054           {
10055             /* Offset is out of range for a single add, so use two ldr.  */
10056             ops[0] = ldm[1];
10057             ops[1] = base_reg;
10058             ops[2] = GEN_INT (val1);
10059             output_asm_insn (\"ldr%?\\t%0, [%1, %2]\", ops);
10060             ops[0] = ldm[2];
10061             ops[2] = GEN_INT (val2);
10062             output_asm_insn (\"ldr%?\\t%0, [%1, %2]\", ops);
10063           }
10064       }
10065     else if (val1 != 0)
10066       {
10067         if (val1 < val2)
10068           output_asm_insn (\"ldm%(da%)\\t%0, {%1, %2}\", ldm);
10069         else
10070           output_asm_insn (\"ldm%(ia%)\\t%0, {%1, %2}\", ldm);
10071       }
10072     else
10073       {
10074         if (val1 < val2)
10075           output_asm_insn (\"ldm%(ia%)\\t%0, {%1, %2}\", ldm);
10076         else
10077           output_asm_insn (\"ldm%(da%)\\t%0, {%1, %2}\", ldm);
10078       }
10079     output_asm_insn (\"%I3%?\\t%0, %1, %2\", arith);
10080     return \"\";
10081   }"
10082   [(set_attr "length" "12")
10083    (set_attr "predicable" "yes")
10084    (set_attr "type" "load1")]
10087 ; This pattern is never tried by combine, so do it as a peephole
10089 (define_peephole2
10090   [(set (match_operand:SI 0 "arm_general_register_operand" "")
10091         (match_operand:SI 1 "arm_general_register_operand" ""))
10092    (set (reg:CC CC_REGNUM)
10093         (compare:CC (match_dup 1) (const_int 0)))]
10094   "TARGET_ARM"
10095   [(parallel [(set (reg:CC CC_REGNUM) (compare:CC (match_dup 1) (const_int 0)))
10096               (set (match_dup 0) (match_dup 1))])]
10097   ""
10100 (define_split
10101   [(set (match_operand:SI 0 "s_register_operand" "")
10102         (and:SI (ge:SI (match_operand:SI 1 "s_register_operand" "")
10103                        (const_int 0))
10104                 (neg:SI (match_operator:SI 2 "arm_comparison_operator"
10105                          [(match_operand:SI 3 "s_register_operand" "")
10106                           (match_operand:SI 4 "arm_rhs_operand" "")]))))
10107    (clobber (match_operand:SI 5 "s_register_operand" ""))]
10108   "TARGET_ARM"
10109   [(set (match_dup 5) (not:SI (ashiftrt:SI (match_dup 1) (const_int 31))))
10110    (set (match_dup 0) (and:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
10111                               (match_dup 5)))]
10112   ""
10115 ;; This split can be used because CC_Z mode implies that the following
10116 ;; branch will be an equality, or an unsigned inequality, so the sign
10117 ;; extension is not needed.
10119 (define_split
10120   [(set (reg:CC_Z CC_REGNUM)
10121         (compare:CC_Z
10122          (ashift:SI (subreg:SI (match_operand:QI 0 "memory_operand" "") 0)
10123                     (const_int 24))
10124          (match_operand 1 "const_int_operand" "")))
10125    (clobber (match_scratch:SI 2 ""))]
10126   "TARGET_ARM
10127    && (((unsigned HOST_WIDE_INT) INTVAL (operands[1]))
10128        == (((unsigned HOST_WIDE_INT) INTVAL (operands[1])) >> 24) << 24)"
10129   [(set (match_dup 2) (zero_extend:SI (match_dup 0)))
10130    (set (reg:CC CC_REGNUM) (compare:CC (match_dup 2) (match_dup 1)))]
10131   "
10132   operands[1] = GEN_INT (((unsigned long) INTVAL (operands[1])) >> 24);
10133   "
10135 ;; ??? Check the patterns above for Thumb-2 usefulness
10137 (define_expand "prologue"
10138   [(clobber (const_int 0))]
10139   "TARGET_EITHER"
10140   "if (TARGET_32BIT)
10141      arm_expand_prologue ();
10142    else
10143      thumb1_expand_prologue ();
10144   DONE;
10145   "
10148 (define_expand "epilogue"
10149   [(clobber (const_int 0))]
10150   "TARGET_EITHER"
10151   "
10152   if (crtl->calls_eh_return)
10153     emit_insn (gen_force_register_use (gen_rtx_REG (Pmode, 2)));
10154   if (TARGET_THUMB1)
10155    {
10156      thumb1_expand_epilogue ();
10157      emit_jump_insn (gen_rtx_UNSPEC_VOLATILE (VOIDmode,
10158                      gen_rtvec (1, ret_rtx), VUNSPEC_EPILOGUE));
10159    }
10160   else if (HAVE_return)
10161    {
10162      /* HAVE_return is testing for USE_RETURN_INSN (FALSE).  Hence,
10163         no need for explicit testing again.  */
10164      emit_jump_insn (gen_return ());
10165    }
10166   else if (TARGET_32BIT)
10167    {
10168     arm_expand_epilogue (true);
10169    }
10170   DONE;
10171   "
10174 ;; Note - although unspec_volatile's USE all hard registers,
10175 ;; USEs are ignored after relaod has completed.  Thus we need
10176 ;; to add an unspec of the link register to ensure that flow
10177 ;; does not think that it is unused by the sibcall branch that
10178 ;; will replace the standard function epilogue.
10179 (define_expand "sibcall_epilogue"
10180    [(parallel [(unspec:SI [(reg:SI LR_REGNUM)] UNSPEC_REGISTER_USE)
10181                (unspec_volatile [(return)] VUNSPEC_EPILOGUE)])]
10182    "TARGET_32BIT"
10183    "
10184    arm_expand_epilogue (false);
10185    DONE;
10186    "
10189 (define_expand "eh_epilogue"
10190   [(use (match_operand:SI 0 "register_operand" ""))
10191    (use (match_operand:SI 1 "register_operand" ""))
10192    (use (match_operand:SI 2 "register_operand" ""))]
10193   "TARGET_EITHER"
10194   "
10195   {
10196     cfun->machine->eh_epilogue_sp_ofs = operands[1];
10197     if (!REG_P (operands[2]) || REGNO (operands[2]) != 2)
10198       {
10199         rtx ra = gen_rtx_REG (Pmode, 2);
10201         emit_move_insn (ra, operands[2]);
10202         operands[2] = ra;
10203       }
10204     /* This is a hack -- we may have crystalized the function type too
10205        early.  */
10206     cfun->machine->func_type = 0;
10207   }"
10210 ;; This split is only used during output to reduce the number of patterns
10211 ;; that need assembler instructions adding to them.  We allowed the setting
10212 ;; of the conditions to be implicit during rtl generation so that
10213 ;; the conditional compare patterns would work.  However this conflicts to
10214 ;; some extent with the conditional data operations, so we have to split them
10215 ;; up again here.
10217 ;; ??? Need to audit these splitters for Thumb-2.  Why isn't normal
10218 ;; conditional execution sufficient?
10220 (define_split
10221   [(set (match_operand:SI 0 "s_register_operand" "")
10222         (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10223                           [(match_operand 2 "" "") (match_operand 3 "" "")])
10224                          (match_dup 0)
10225                          (match_operand 4 "" "")))
10226    (clobber (reg:CC CC_REGNUM))]
10227   "TARGET_ARM && reload_completed"
10228   [(set (match_dup 5) (match_dup 6))
10229    (cond_exec (match_dup 7)
10230               (set (match_dup 0) (match_dup 4)))]
10231   "
10232   {
10233     machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10234                                              operands[2], operands[3]);
10235     enum rtx_code rc = GET_CODE (operands[1]);
10237     operands[5] = gen_rtx_REG (mode, CC_REGNUM);
10238     operands[6] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10239     if (mode == CCFPmode || mode == CCFPEmode)
10240       rc = reverse_condition_maybe_unordered (rc);
10241     else
10242       rc = reverse_condition (rc);
10244     operands[7] = gen_rtx_fmt_ee (rc, VOIDmode, operands[5], const0_rtx);
10245   }"
10248 (define_split
10249   [(set (match_operand:SI 0 "s_register_operand" "")
10250         (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10251                           [(match_operand 2 "" "") (match_operand 3 "" "")])
10252                          (match_operand 4 "" "")
10253                          (match_dup 0)))
10254    (clobber (reg:CC CC_REGNUM))]
10255   "TARGET_ARM && reload_completed"
10256   [(set (match_dup 5) (match_dup 6))
10257    (cond_exec (match_op_dup 1 [(match_dup 5) (const_int 0)])
10258               (set (match_dup 0) (match_dup 4)))]
10259   "
10260   {
10261     machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10262                                              operands[2], operands[3]);
10264     operands[5] = gen_rtx_REG (mode, CC_REGNUM);
10265     operands[6] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10266   }"
10269 (define_split
10270   [(set (match_operand:SI 0 "s_register_operand" "")
10271         (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10272                           [(match_operand 2 "" "") (match_operand 3 "" "")])
10273                          (match_operand 4 "" "")
10274                          (match_operand 5 "" "")))
10275    (clobber (reg:CC CC_REGNUM))]
10276   "TARGET_ARM && reload_completed"
10277   [(set (match_dup 6) (match_dup 7))
10278    (cond_exec (match_op_dup 1 [(match_dup 6) (const_int 0)])
10279               (set (match_dup 0) (match_dup 4)))
10280    (cond_exec (match_dup 8)
10281               (set (match_dup 0) (match_dup 5)))]
10282   "
10283   {
10284     machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10285                                              operands[2], operands[3]);
10286     enum rtx_code rc = GET_CODE (operands[1]);
10288     operands[6] = gen_rtx_REG (mode, CC_REGNUM);
10289     operands[7] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10290     if (mode == CCFPmode || mode == CCFPEmode)
10291       rc = reverse_condition_maybe_unordered (rc);
10292     else
10293       rc = reverse_condition (rc);
10295     operands[8] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
10296   }"
10299 (define_split
10300   [(set (match_operand:SI 0 "s_register_operand" "")
10301         (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10302                           [(match_operand:SI 2 "s_register_operand" "")
10303                            (match_operand:SI 3 "arm_add_operand" "")])
10304                          (match_operand:SI 4 "arm_rhs_operand" "")
10305                          (not:SI
10306                           (match_operand:SI 5 "s_register_operand" ""))))
10307    (clobber (reg:CC CC_REGNUM))]
10308   "TARGET_ARM && reload_completed"
10309   [(set (match_dup 6) (match_dup 7))
10310    (cond_exec (match_op_dup 1 [(match_dup 6) (const_int 0)])
10311               (set (match_dup 0) (match_dup 4)))
10312    (cond_exec (match_dup 8)
10313               (set (match_dup 0) (not:SI (match_dup 5))))]
10314   "
10315   {
10316     machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10317                                              operands[2], operands[3]);
10318     enum rtx_code rc = GET_CODE (operands[1]);
10320     operands[6] = gen_rtx_REG (mode, CC_REGNUM);
10321     operands[7] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10322     if (mode == CCFPmode || mode == CCFPEmode)
10323       rc = reverse_condition_maybe_unordered (rc);
10324     else
10325       rc = reverse_condition (rc);
10327     operands[8] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
10328   }"
10331 (define_insn "*cond_move_not"
10332   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10333         (if_then_else:SI (match_operator 4 "arm_comparison_operator"
10334                           [(match_operand 3 "cc_register" "") (const_int 0)])
10335                          (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
10336                          (not:SI
10337                           (match_operand:SI 2 "s_register_operand" "r,r"))))]
10338   "TARGET_ARM"
10339   "@
10340    mvn%D4\\t%0, %2
10341    mov%d4\\t%0, %1\;mvn%D4\\t%0, %2"
10342   [(set_attr "conds" "use")
10343    (set_attr "type" "mvn_reg,multiple")
10344    (set_attr "length" "4,8")]
10347 ;; The next two patterns occur when an AND operation is followed by a
10348 ;; scc insn sequence 
10350 (define_insn "*sign_extract_onebit"
10351   [(set (match_operand:SI 0 "s_register_operand" "=r")
10352         (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
10353                          (const_int 1)
10354                          (match_operand:SI 2 "const_int_operand" "n")))
10355     (clobber (reg:CC CC_REGNUM))]
10356   "TARGET_ARM"
10357   "*
10358     operands[2] = GEN_INT (1 << INTVAL (operands[2]));
10359     output_asm_insn (\"ands\\t%0, %1, %2\", operands);
10360     return \"mvnne\\t%0, #0\";
10361   "
10362   [(set_attr "conds" "clob")
10363    (set_attr "length" "8")
10364    (set_attr "type" "multiple")]
10367 (define_insn "*not_signextract_onebit"
10368   [(set (match_operand:SI 0 "s_register_operand" "=r")
10369         (not:SI
10370          (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
10371                           (const_int 1)
10372                           (match_operand:SI 2 "const_int_operand" "n"))))
10373    (clobber (reg:CC CC_REGNUM))]
10374   "TARGET_ARM"
10375   "*
10376     operands[2] = GEN_INT (1 << INTVAL (operands[2]));
10377     output_asm_insn (\"tst\\t%1, %2\", operands);
10378     output_asm_insn (\"mvneq\\t%0, #0\", operands);
10379     return \"movne\\t%0, #0\";
10380   "
10381   [(set_attr "conds" "clob")
10382    (set_attr "length" "12")
10383    (set_attr "type" "multiple")]
10385 ;; ??? The above patterns need auditing for Thumb-2
10387 ;; Push multiple registers to the stack.  Registers are in parallel (use ...)
10388 ;; expressions.  For simplicity, the first register is also in the unspec
10389 ;; part.
10390 ;; To avoid the usage of GNU extension, the length attribute is computed
10391 ;; in a C function arm_attr_length_push_multi.
10392 (define_insn "*push_multi"
10393   [(match_parallel 2 "multi_register_push"
10394     [(set (match_operand:BLK 0 "push_mult_memory_operand" "")
10395           (unspec:BLK [(match_operand:SI 1 "s_register_operand" "")]
10396                       UNSPEC_PUSH_MULT))])]
10397   ""
10398   "*
10399   {
10400     int num_saves = XVECLEN (operands[2], 0);
10401      
10402     /* For the StrongARM at least it is faster to
10403        use STR to store only a single register.
10404        In Thumb mode always use push, and the assembler will pick
10405        something appropriate.  */
10406     if (num_saves == 1 && TARGET_ARM)
10407       output_asm_insn (\"str%?\\t%1, [%m0, #-4]!\", operands);
10408     else
10409       {
10410         int i;
10411         char pattern[100];
10413         if (TARGET_ARM)
10414             strcpy (pattern, \"stm%(fd%)\\t%m0!, {%1\");
10415         else if (TARGET_THUMB2)
10416             strcpy (pattern, \"push%?\\t{%1\");
10417         else
10418             strcpy (pattern, \"push\\t{%1\");
10420         for (i = 1; i < num_saves; i++)
10421           {
10422             strcat (pattern, \", %|\");
10423             strcat (pattern,
10424                     reg_names[REGNO (XEXP (XVECEXP (operands[2], 0, i), 0))]);
10425           }
10427         strcat (pattern, \"}\");
10428         output_asm_insn (pattern, operands);
10429       }
10431     return \"\";
10432   }"
10433   [(set_attr "type" "store4")
10434    (set (attr "length")
10435         (symbol_ref "arm_attr_length_push_multi (operands[2], operands[1])"))]
10438 (define_insn "stack_tie"
10439   [(set (mem:BLK (scratch))
10440         (unspec:BLK [(match_operand:SI 0 "s_register_operand" "rk")
10441                      (match_operand:SI 1 "s_register_operand" "rk")]
10442                     UNSPEC_PRLG_STK))]
10443   ""
10444   ""
10445   [(set_attr "length" "0")
10446    (set_attr "type" "block")]
10449 ;; Pop (as used in epilogue RTL)
10451 (define_insn "*load_multiple_with_writeback"
10452   [(match_parallel 0 "load_multiple_operation"
10453     [(set (match_operand:SI 1 "s_register_operand" "+rk")
10454           (plus:SI (match_dup 1)
10455                    (match_operand:SI 2 "const_int_I_operand" "I")))
10456      (set (match_operand:SI 3 "s_register_operand" "=rk")
10457           (mem:SI (match_dup 1)))
10458         ])]
10459   "TARGET_32BIT && (reload_in_progress || reload_completed)"
10460   "*
10461   {
10462     arm_output_multireg_pop (operands, /*return_pc=*/false,
10463                                        /*cond=*/const_true_rtx,
10464                                        /*reverse=*/false,
10465                                        /*update=*/true);
10466     return \"\";
10467   }
10468   "
10469   [(set_attr "type" "load4")
10470    (set_attr "predicable" "yes")]
10473 ;; Pop with return (as used in epilogue RTL)
10475 ;; This instruction is generated when the registers are popped at the end of
10476 ;; epilogue.  Here, instead of popping the value into LR and then generating
10477 ;; jump to LR, value is popped into PC directly.  Hence, the pattern is combined
10478 ;;  with (return).
10479 (define_insn "*pop_multiple_with_writeback_and_return"
10480   [(match_parallel 0 "pop_multiple_return"
10481     [(return)
10482      (set (match_operand:SI 1 "s_register_operand" "+rk")
10483           (plus:SI (match_dup 1)
10484                    (match_operand:SI 2 "const_int_I_operand" "I")))
10485      (set (match_operand:SI 3 "s_register_operand" "=rk")
10486           (mem:SI (match_dup 1)))
10487         ])]
10488   "TARGET_32BIT && (reload_in_progress || reload_completed)"
10489   "*
10490   {
10491     arm_output_multireg_pop (operands, /*return_pc=*/true,
10492                                        /*cond=*/const_true_rtx,
10493                                        /*reverse=*/false,
10494                                        /*update=*/true);
10495     return \"\";
10496   }
10497   "
10498   [(set_attr "type" "load4")
10499    (set_attr "predicable" "yes")]
10502 (define_insn "*pop_multiple_with_return"
10503   [(match_parallel 0 "pop_multiple_return"
10504     [(return)
10505      (set (match_operand:SI 2 "s_register_operand" "=rk")
10506           (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
10507         ])]
10508   "TARGET_32BIT && (reload_in_progress || reload_completed)"
10509   "*
10510   {
10511     arm_output_multireg_pop (operands, /*return_pc=*/true,
10512                                        /*cond=*/const_true_rtx,
10513                                        /*reverse=*/false,
10514                                        /*update=*/false);
10515     return \"\";
10516   }
10517   "
10518   [(set_attr "type" "load4")
10519    (set_attr "predicable" "yes")]
10522 ;; Load into PC and return
10523 (define_insn "*ldr_with_return"
10524   [(return)
10525    (set (reg:SI PC_REGNUM)
10526         (mem:SI (post_inc:SI (match_operand:SI 0 "s_register_operand" "+rk"))))]
10527   "TARGET_32BIT && (reload_in_progress || reload_completed)"
10528   "ldr%?\t%|pc, [%0], #4"
10529   [(set_attr "type" "load1")
10530    (set_attr "predicable" "yes")]
10532 ;; Pop for floating point registers (as used in epilogue RTL)
10533 (define_insn "*vfp_pop_multiple_with_writeback"
10534   [(match_parallel 0 "pop_multiple_fp"
10535     [(set (match_operand:SI 1 "s_register_operand" "+rk")
10536           (plus:SI (match_dup 1)
10537                    (match_operand:SI 2 "const_int_I_operand" "I")))
10538      (set (match_operand:DF 3 "vfp_hard_register_operand" "")
10539           (mem:DF (match_dup 1)))])]
10540   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
10541   "*
10542   {
10543     int num_regs = XVECLEN (operands[0], 0);
10544     char pattern[100];
10545     rtx op_list[2];
10546     strcpy (pattern, \"vldm\\t\");
10547     strcat (pattern, reg_names[REGNO (SET_DEST (XVECEXP (operands[0], 0, 0)))]);
10548     strcat (pattern, \"!, {\");
10549     op_list[0] = XEXP (XVECEXP (operands[0], 0, 1), 0);
10550     strcat (pattern, \"%P0\");
10551     if ((num_regs - 1) > 1)
10552       {
10553         strcat (pattern, \"-%P1\");
10554         op_list [1] = XEXP (XVECEXP (operands[0], 0, num_regs - 1), 0);
10555       }
10557     strcat (pattern, \"}\");
10558     output_asm_insn (pattern, op_list);
10559     return \"\";
10560   }
10561   "
10562   [(set_attr "type" "load4")
10563    (set_attr "conds" "unconditional")
10564    (set_attr "predicable" "no")]
10567 ;; Special patterns for dealing with the constant pool
10569 (define_insn "align_4"
10570   [(unspec_volatile [(const_int 0)] VUNSPEC_ALIGN)]
10571   "TARGET_EITHER"
10572   "*
10573   assemble_align (32);
10574   return \"\";
10575   "
10576   [(set_attr "type" "no_insn")]
10579 (define_insn "align_8"
10580   [(unspec_volatile [(const_int 0)] VUNSPEC_ALIGN8)]
10581   "TARGET_EITHER"
10582   "*
10583   assemble_align (64);
10584   return \"\";
10585   "
10586   [(set_attr "type" "no_insn")]
10589 (define_insn "consttable_end"
10590   [(unspec_volatile [(const_int 0)] VUNSPEC_POOL_END)]
10591   "TARGET_EITHER"
10592   "*
10593   making_const_table = FALSE;
10594   return \"\";
10595   "
10596   [(set_attr "type" "no_insn")]
10599 (define_insn "consttable_1"
10600   [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_1)]
10601   "TARGET_EITHER"
10602   "*
10603   making_const_table = TRUE;
10604   assemble_integer (operands[0], 1, BITS_PER_WORD, 1);
10605   assemble_zeros (3);
10606   return \"\";
10607   "
10608   [(set_attr "length" "4")
10609    (set_attr "type" "no_insn")]
10612 (define_insn "consttable_2"
10613   [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_2)]
10614   "TARGET_EITHER"
10615   "*
10616   {
10617     rtx x = operands[0];
10618     making_const_table = TRUE;
10619     switch (GET_MODE_CLASS (GET_MODE (x)))
10620       {
10621       case MODE_FLOAT:
10622         arm_emit_fp16_const (x);
10623         break;
10624       default:
10625         assemble_integer (operands[0], 2, BITS_PER_WORD, 1);
10626         assemble_zeros (2);
10627         break;
10628       }
10629     return \"\";
10630   }"
10631   [(set_attr "length" "4")
10632    (set_attr "type" "no_insn")]
10635 (define_insn "consttable_4"
10636   [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_4)]
10637   "TARGET_EITHER"
10638   "*
10639   {
10640     rtx x = operands[0];
10641     making_const_table = TRUE;
10642     switch (GET_MODE_CLASS (GET_MODE (x)))
10643       {
10644       case MODE_FLOAT:
10645         {
10646           REAL_VALUE_TYPE r;
10647           REAL_VALUE_FROM_CONST_DOUBLE (r, x);
10648           assemble_real (r, GET_MODE (x), BITS_PER_WORD);
10649           break;
10650         }
10651       default:
10652         /* XXX: Sometimes gcc does something really dumb and ends up with
10653            a HIGH in a constant pool entry, usually because it's trying to
10654            load into a VFP register.  We know this will always be used in
10655            combination with a LO_SUM which ignores the high bits, so just
10656            strip off the HIGH.  */
10657         if (GET_CODE (x) == HIGH)
10658           x = XEXP (x, 0);
10659         assemble_integer (x, 4, BITS_PER_WORD, 1);
10660         mark_symbol_refs_as_used (x);
10661         break;
10662       }
10663     return \"\";
10664   }"
10665   [(set_attr "length" "4")
10666    (set_attr "type" "no_insn")]
10669 (define_insn "consttable_8"
10670   [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_8)]
10671   "TARGET_EITHER"
10672   "*
10673   {
10674     making_const_table = TRUE;
10675     switch (GET_MODE_CLASS (GET_MODE (operands[0])))
10676       {
10677        case MODE_FLOAT:
10678         {
10679           REAL_VALUE_TYPE r;
10680           REAL_VALUE_FROM_CONST_DOUBLE (r, operands[0]);
10681           assemble_real (r, GET_MODE (operands[0]), BITS_PER_WORD);
10682           break;
10683         }
10684       default:
10685         assemble_integer (operands[0], 8, BITS_PER_WORD, 1);
10686         break;
10687       }
10688     return \"\";
10689   }"
10690   [(set_attr "length" "8")
10691    (set_attr "type" "no_insn")]
10694 (define_insn "consttable_16"
10695   [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_16)]
10696   "TARGET_EITHER"
10697   "*
10698   {
10699     making_const_table = TRUE;
10700     switch (GET_MODE_CLASS (GET_MODE (operands[0])))
10701       {
10702        case MODE_FLOAT:
10703         {
10704           REAL_VALUE_TYPE r;
10705           REAL_VALUE_FROM_CONST_DOUBLE (r, operands[0]);
10706           assemble_real (r, GET_MODE (operands[0]), BITS_PER_WORD);
10707           break;
10708         }
10709       default:
10710         assemble_integer (operands[0], 16, BITS_PER_WORD, 1);
10711         break;
10712       }
10713     return \"\";
10714   }"
10715   [(set_attr "length" "16")
10716    (set_attr "type" "no_insn")]
10719 ;; V5 Instructions,
10721 (define_insn "clzsi2"
10722   [(set (match_operand:SI 0 "s_register_operand" "=r")
10723         (clz:SI (match_operand:SI 1 "s_register_operand" "r")))]
10724   "TARGET_32BIT && arm_arch5"
10725   "clz%?\\t%0, %1"
10726   [(set_attr "predicable" "yes")
10727    (set_attr "predicable_short_it" "no")
10728    (set_attr "type" "clz")])
10730 (define_insn "rbitsi2"
10731   [(set (match_operand:SI 0 "s_register_operand" "=r")
10732         (unspec:SI [(match_operand:SI 1 "s_register_operand" "r")] UNSPEC_RBIT))]
10733   "TARGET_32BIT && arm_arch_thumb2"
10734   "rbit%?\\t%0, %1"
10735   [(set_attr "predicable" "yes")
10736    (set_attr "predicable_short_it" "no")
10737    (set_attr "type" "clz")])
10739 (define_expand "ctzsi2"
10740  [(set (match_operand:SI           0 "s_register_operand" "")
10741        (ctz:SI (match_operand:SI  1 "s_register_operand" "")))]
10742   "TARGET_32BIT && arm_arch_thumb2"
10743   "
10744    {
10745      rtx tmp = gen_reg_rtx (SImode); 
10746      emit_insn (gen_rbitsi2 (tmp, operands[1]));
10747      emit_insn (gen_clzsi2 (operands[0], tmp));
10748    }
10749    DONE;
10750   "
10753 ;; V5E instructions.
10755 (define_insn "prefetch"
10756   [(prefetch (match_operand:SI 0 "address_operand" "p")
10757              (match_operand:SI 1 "" "")
10758              (match_operand:SI 2 "" ""))]
10759   "TARGET_32BIT && arm_arch5e"
10760   "pld\\t%a0"
10761   [(set_attr "type" "load1")]
10764 ;; General predication pattern
10766 (define_cond_exec
10767   [(match_operator 0 "arm_comparison_operator"
10768     [(match_operand 1 "cc_register" "")
10769      (const_int 0)])]
10770   "TARGET_32BIT
10771    && (!TARGET_NO_VOLATILE_CE || !volatile_refs_p (PATTERN (insn)))"
10772   ""
10773 [(set_attr "predicated" "yes")]
10776 (define_insn "force_register_use"
10777   [(unspec:SI [(match_operand:SI 0 "register_operand" "")] UNSPEC_REGISTER_USE)]
10778   ""
10779   "%@ %0 needed"
10780   [(set_attr "length" "0")
10781    (set_attr "type" "no_insn")]
10785 ;; Patterns for exception handling
10787 (define_expand "eh_return"
10788   [(use (match_operand 0 "general_operand" ""))]
10789   "TARGET_EITHER"
10790   "
10791   {
10792     if (TARGET_32BIT)
10793       emit_insn (gen_arm_eh_return (operands[0]));
10794     else
10795       emit_insn (gen_thumb_eh_return (operands[0]));
10796     DONE;
10797   }"
10799                                    
10800 ;; We can't expand this before we know where the link register is stored.
10801 (define_insn_and_split "arm_eh_return"
10802   [(unspec_volatile [(match_operand:SI 0 "s_register_operand" "r")]
10803                     VUNSPEC_EH_RETURN)
10804    (clobber (match_scratch:SI 1 "=&r"))]
10805   "TARGET_ARM"
10806   "#"
10807   "&& reload_completed"
10808   [(const_int 0)]
10809   "
10810   {
10811     arm_set_return_address (operands[0], operands[1]);
10812     DONE;
10813   }"
10817 ;; TLS support
10819 (define_insn "load_tp_hard"
10820   [(set (match_operand:SI 0 "register_operand" "=r")
10821         (unspec:SI [(const_int 0)] UNSPEC_TLS))]
10822   "TARGET_HARD_TP"
10823   "mrc%?\\tp15, 0, %0, c13, c0, 3\\t@ load_tp_hard"
10824   [(set_attr "predicable" "yes")
10825    (set_attr "type" "mrs")]
10828 ;; Doesn't clobber R1-R3.  Must use r0 for the first operand.
10829 (define_insn "load_tp_soft"
10830   [(set (reg:SI 0) (unspec:SI [(const_int 0)] UNSPEC_TLS))
10831    (clobber (reg:SI LR_REGNUM))
10832    (clobber (reg:SI IP_REGNUM))
10833    (clobber (reg:CC CC_REGNUM))]
10834   "TARGET_SOFT_TP"
10835   "bl\\t__aeabi_read_tp\\t@ load_tp_soft"
10836   [(set_attr "conds" "clob")
10837    (set_attr "type" "branch")]
10840 ;; tls descriptor call
10841 (define_insn "tlscall"
10842   [(set (reg:SI R0_REGNUM)
10843         (unspec:SI [(reg:SI R0_REGNUM)
10844                     (match_operand:SI 0 "" "X")
10845                     (match_operand 1 "" "")] UNSPEC_TLS))
10846    (clobber (reg:SI R1_REGNUM))
10847    (clobber (reg:SI LR_REGNUM))
10848    (clobber (reg:SI CC_REGNUM))]
10849   "TARGET_GNU2_TLS"
10850   {
10851     targetm.asm_out.internal_label (asm_out_file, "LPIC",
10852                                     INTVAL (operands[1]));
10853     return "bl\\t%c0(tlscall)";
10854   }
10855   [(set_attr "conds" "clob")
10856    (set_attr "length" "4")
10857    (set_attr "type" "branch")]
10860 ;; For thread pointer builtin
10861 (define_expand "get_thread_pointersi"
10862   [(match_operand:SI 0 "s_register_operand" "=r")]
10863  ""
10866    arm_load_tp (operands[0]);
10867    DONE;
10868  }")
10872 ;; We only care about the lower 16 bits of the constant 
10873 ;; being inserted into the upper 16 bits of the register.
10874 (define_insn "*arm_movtas_ze" 
10875   [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r")
10876                    (const_int 16)
10877                    (const_int 16))
10878         (match_operand:SI 1 "const_int_operand" ""))]
10879   "arm_arch_thumb2"
10880   "movt%?\t%0, %L1"
10881  [(set_attr "predicable" "yes")
10882   (set_attr "predicable_short_it" "no")
10883   (set_attr "length" "4")
10884   (set_attr "type" "alu_sreg")]
10887 (define_insn "*arm_rev"
10888   [(set (match_operand:SI 0 "s_register_operand" "=l,l,r")
10889         (bswap:SI (match_operand:SI 1 "s_register_operand" "l,l,r")))]
10890   "arm_arch6"
10891   "@
10892    rev\t%0, %1
10893    rev%?\t%0, %1
10894    rev%?\t%0, %1"
10895   [(set_attr "arch" "t1,t2,32")
10896    (set_attr "length" "2,2,4")
10897    (set_attr "predicable" "no,yes,yes")
10898    (set_attr "predicable_short_it" "no")
10899    (set_attr "type" "rev")]
10902 (define_expand "arm_legacy_rev"
10903   [(set (match_operand:SI 2 "s_register_operand" "")
10904         (xor:SI (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
10905                              (const_int 16))
10906                 (match_dup 1)))
10907    (set (match_dup 2)
10908         (lshiftrt:SI (match_dup 2)
10909                      (const_int 8)))
10910    (set (match_operand:SI 3 "s_register_operand" "")
10911         (rotatert:SI (match_dup 1)
10912                      (const_int 8)))
10913    (set (match_dup 2)
10914         (and:SI (match_dup 2)
10915                 (const_int -65281)))
10916    (set (match_operand:SI 0 "s_register_operand" "")
10917         (xor:SI (match_dup 3)
10918                 (match_dup 2)))]
10919   "TARGET_32BIT"
10920   ""
10923 ;; Reuse temporaries to keep register pressure down.
10924 (define_expand "thumb_legacy_rev"
10925   [(set (match_operand:SI 2 "s_register_operand" "")
10926      (ashift:SI (match_operand:SI 1 "s_register_operand" "")
10927                 (const_int 24)))
10928    (set (match_operand:SI 3 "s_register_operand" "")
10929      (lshiftrt:SI (match_dup 1)
10930                   (const_int 24)))
10931    (set (match_dup 3)
10932      (ior:SI (match_dup 3)
10933              (match_dup 2)))
10934    (set (match_operand:SI 4 "s_register_operand" "")
10935      (const_int 16))
10936    (set (match_operand:SI 5 "s_register_operand" "")
10937      (rotatert:SI (match_dup 1)
10938                   (match_dup 4)))
10939    (set (match_dup 2)
10940      (ashift:SI (match_dup 5)
10941                 (const_int 24)))
10942    (set (match_dup 5)
10943      (lshiftrt:SI (match_dup 5)
10944                   (const_int 24)))
10945    (set (match_dup 5)
10946      (ior:SI (match_dup 5)
10947              (match_dup 2)))
10948    (set (match_dup 5)
10949      (rotatert:SI (match_dup 5)
10950                   (match_dup 4)))
10951    (set (match_operand:SI 0 "s_register_operand" "")
10952      (ior:SI (match_dup 5)
10953              (match_dup 3)))]
10954   "TARGET_THUMB"
10955   ""
10958 (define_expand "bswapsi2"
10959   [(set (match_operand:SI 0 "s_register_operand" "=r")
10960         (bswap:SI (match_operand:SI 1 "s_register_operand" "r")))]
10961 "TARGET_EITHER && (arm_arch6 || !optimize_size)"
10963     if (!arm_arch6)
10964       {
10965         rtx op2 = gen_reg_rtx (SImode);
10966         rtx op3 = gen_reg_rtx (SImode);
10968         if (TARGET_THUMB)
10969           {
10970             rtx op4 = gen_reg_rtx (SImode);
10971             rtx op5 = gen_reg_rtx (SImode);
10973             emit_insn (gen_thumb_legacy_rev (operands[0], operands[1],
10974                                              op2, op3, op4, op5));
10975           }
10976         else
10977           {
10978             emit_insn (gen_arm_legacy_rev (operands[0], operands[1],
10979                                            op2, op3));
10980           }
10982         DONE;
10983       }
10984   "
10987 ;; bswap16 patterns: use revsh and rev16 instructions for the signed
10988 ;; and unsigned variants, respectively. For rev16, expose
10989 ;; byte-swapping in the lower 16 bits only.
10990 (define_insn "*arm_revsh"
10991   [(set (match_operand:SI 0 "s_register_operand" "=l,l,r")
10992         (sign_extend:SI (bswap:HI (match_operand:HI 1 "s_register_operand" "l,l,r"))))]
10993   "arm_arch6"
10994   "@
10995   revsh\t%0, %1
10996   revsh%?\t%0, %1
10997   revsh%?\t%0, %1"
10998   [(set_attr "arch" "t1,t2,32")
10999    (set_attr "length" "2,2,4")
11000    (set_attr "type" "rev")]
11003 (define_insn "*arm_rev16"
11004   [(set (match_operand:HI 0 "s_register_operand" "=l,l,r")
11005         (bswap:HI (match_operand:HI 1 "s_register_operand" "l,l,r")))]
11006   "arm_arch6"
11007   "@
11008    rev16\t%0, %1
11009    rev16%?\t%0, %1
11010    rev16%?\t%0, %1"
11011   [(set_attr "arch" "t1,t2,32")
11012    (set_attr "length" "2,2,4")
11013    (set_attr "type" "rev")]
11016 ;; There are no canonicalisation rules for the position of the lshiftrt, ashift
11017 ;; operations within an IOR/AND RTX, therefore we have two patterns matching
11018 ;; each valid permutation.
11020 (define_insn "arm_rev16si2"
11021   [(set (match_operand:SI 0 "register_operand" "=l,l,r")
11022         (ior:SI (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "l,l,r")
11023                                    (const_int 8))
11024                         (match_operand:SI 3 "const_int_operand" "n,n,n"))
11025                 (and:SI (lshiftrt:SI (match_dup 1)
11026                                      (const_int 8))
11027                         (match_operand:SI 2 "const_int_operand" "n,n,n"))))]
11028   "arm_arch6
11029    && aarch_rev16_shleft_mask_imm_p (operands[3], SImode)
11030    && aarch_rev16_shright_mask_imm_p (operands[2], SImode)"
11031   "rev16\\t%0, %1"
11032   [(set_attr "arch" "t1,t2,32")
11033    (set_attr "length" "2,2,4")
11034    (set_attr "type" "rev")]
11037 (define_insn "arm_rev16si2_alt"
11038   [(set (match_operand:SI 0 "register_operand" "=l,l,r")
11039         (ior:SI (and:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "l,l,r")
11040                                      (const_int 8))
11041                         (match_operand:SI 2 "const_int_operand" "n,n,n"))
11042                 (and:SI (ashift:SI (match_dup 1)
11043                                    (const_int 8))
11044                         (match_operand:SI 3 "const_int_operand" "n,n,n"))))]
11045   "arm_arch6
11046    && aarch_rev16_shleft_mask_imm_p (operands[3], SImode)
11047    && aarch_rev16_shright_mask_imm_p (operands[2], SImode)"
11048   "rev16\\t%0, %1"
11049   [(set_attr "arch" "t1,t2,32")
11050    (set_attr "length" "2,2,4")
11051    (set_attr "type" "rev")]
11054 (define_expand "bswaphi2"
11055   [(set (match_operand:HI 0 "s_register_operand" "=r")
11056         (bswap:HI (match_operand:HI 1 "s_register_operand" "r")))]
11057 "arm_arch6"
11061 ;; Patterns for LDRD/STRD in Thumb2 mode
11063 (define_insn "*thumb2_ldrd"
11064   [(set (match_operand:SI 0 "s_register_operand" "=r")
11065         (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "rk")
11066                          (match_operand:SI 2 "ldrd_strd_offset_operand" "Do"))))
11067    (set (match_operand:SI 3 "s_register_operand" "=r")
11068         (mem:SI (plus:SI (match_dup 1)
11069                          (match_operand:SI 4 "const_int_operand" ""))))]
11070   "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11071      && current_tune->prefer_ldrd_strd
11072      && ((INTVAL (operands[2]) + 4) == INTVAL (operands[4]))
11073      && (operands_ok_ldrd_strd (operands[0], operands[3],
11074                                   operands[1], INTVAL (operands[2]),
11075                                   false, true))"
11076   "ldrd%?\t%0, %3, [%1, %2]"
11077   [(set_attr "type" "load2")
11078    (set_attr "predicable" "yes")
11079    (set_attr "predicable_short_it" "no")])
11081 (define_insn "*thumb2_ldrd_base"
11082   [(set (match_operand:SI 0 "s_register_operand" "=r")
11083         (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
11084    (set (match_operand:SI 2 "s_register_operand" "=r")
11085         (mem:SI (plus:SI (match_dup 1)
11086                          (const_int 4))))]
11087   "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11088      && current_tune->prefer_ldrd_strd
11089      && (operands_ok_ldrd_strd (operands[0], operands[2],
11090                                   operands[1], 0, false, true))"
11091   "ldrd%?\t%0, %2, [%1]"
11092   [(set_attr "type" "load2")
11093    (set_attr "predicable" "yes")
11094    (set_attr "predicable_short_it" "no")])
11096 (define_insn "*thumb2_ldrd_base_neg"
11097   [(set (match_operand:SI 0 "s_register_operand" "=r")
11098         (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "rk")
11099                          (const_int -4))))
11100    (set (match_operand:SI 2 "s_register_operand" "=r")
11101         (mem:SI (match_dup 1)))]
11102   "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11103      && current_tune->prefer_ldrd_strd
11104      && (operands_ok_ldrd_strd (operands[0], operands[2],
11105                                   operands[1], -4, false, true))"
11106   "ldrd%?\t%0, %2, [%1, #-4]"
11107   [(set_attr "type" "load2")
11108    (set_attr "predicable" "yes")
11109    (set_attr "predicable_short_it" "no")])
11111 (define_insn "*thumb2_strd"
11112   [(set (mem:SI (plus:SI (match_operand:SI 0 "s_register_operand" "rk")
11113                          (match_operand:SI 1 "ldrd_strd_offset_operand" "Do")))
11114         (match_operand:SI 2 "s_register_operand" "r"))
11115    (set (mem:SI (plus:SI (match_dup 0)
11116                          (match_operand:SI 3 "const_int_operand" "")))
11117         (match_operand:SI 4 "s_register_operand" "r"))]
11118   "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11119      && current_tune->prefer_ldrd_strd
11120      && ((INTVAL (operands[1]) + 4) == INTVAL (operands[3]))
11121      && (operands_ok_ldrd_strd (operands[2], operands[4],
11122                                   operands[0], INTVAL (operands[1]),
11123                                   false, false))"
11124   "strd%?\t%2, %4, [%0, %1]"
11125   [(set_attr "type" "store2")
11126    (set_attr "predicable" "yes")
11127    (set_attr "predicable_short_it" "no")])
11129 (define_insn "*thumb2_strd_base"
11130   [(set (mem:SI (match_operand:SI 0 "s_register_operand" "rk"))
11131         (match_operand:SI 1 "s_register_operand" "r"))
11132    (set (mem:SI (plus:SI (match_dup 0)
11133                          (const_int 4)))
11134         (match_operand:SI 2 "s_register_operand" "r"))]
11135   "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11136      && current_tune->prefer_ldrd_strd
11137      && (operands_ok_ldrd_strd (operands[1], operands[2],
11138                                   operands[0], 0, false, false))"
11139   "strd%?\t%1, %2, [%0]"
11140   [(set_attr "type" "store2")
11141    (set_attr "predicable" "yes")
11142    (set_attr "predicable_short_it" "no")])
11144 (define_insn "*thumb2_strd_base_neg"
11145   [(set (mem:SI (plus:SI (match_operand:SI 0 "s_register_operand" "rk")
11146                          (const_int -4)))
11147         (match_operand:SI 1 "s_register_operand" "r"))
11148    (set (mem:SI (match_dup 0))
11149         (match_operand:SI 2 "s_register_operand" "r"))]
11150   "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11151      && current_tune->prefer_ldrd_strd
11152      && (operands_ok_ldrd_strd (operands[1], operands[2],
11153                                   operands[0], -4, false, false))"
11154   "strd%?\t%1, %2, [%0, #-4]"
11155   [(set_attr "type" "store2")
11156    (set_attr "predicable" "yes")
11157    (set_attr "predicable_short_it" "no")])
11159 ;; ARMv8 CRC32 instructions.
11160 (define_insn "<crc_variant>"
11161   [(set (match_operand:SI 0 "s_register_operand" "=r")
11162         (unspec:SI [(match_operand:SI 1 "s_register_operand" "r")
11163                     (match_operand:<crc_mode> 2 "s_register_operand" "r")]
11164          CRC))]
11165   "TARGET_CRC32"
11166   "<crc_variant>\\t%0, %1, %2"
11167   [(set_attr "type" "crc")
11168    (set_attr "conds" "unconditional")]
11171 ;; Load the load/store double peephole optimizations.
11172 (include "ldrdstrd.md")
11174 ;; Load the load/store multiple patterns
11175 (include "ldmstm.md")
11177 ;; Patterns in ldmstm.md don't cover more than 4 registers. This pattern covers
11178 ;; large lists without explicit writeback generated for APCS_FRAME epilogue.
11179 (define_insn "*load_multiple"
11180   [(match_parallel 0 "load_multiple_operation"
11181     [(set (match_operand:SI 2 "s_register_operand" "=rk")
11182           (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
11183         ])]
11184   "TARGET_32BIT"
11185   "*
11186   {
11187     arm_output_multireg_pop (operands, /*return_pc=*/false,
11188                                        /*cond=*/const_true_rtx,
11189                                        /*reverse=*/false,
11190                                        /*update=*/false);
11191     return \"\";
11192   }
11193   "
11194   [(set_attr "predicable" "yes")]
11197 (define_expand "copysignsf3"
11198   [(match_operand:SF 0 "register_operand")
11199    (match_operand:SF 1 "register_operand")
11200    (match_operand:SF 2 "register_operand")]
11201   "TARGET_SOFT_FLOAT && arm_arch_thumb2"
11202   "{
11203      emit_move_insn (operands[0], operands[2]);
11204      emit_insn (gen_insv_t2 (simplify_gen_subreg (SImode, operands[0], SFmode, 0),
11205                 GEN_INT (31), GEN_INT (0),
11206                 simplify_gen_subreg (SImode, operands[1], SFmode, 0)));
11207      DONE;
11208   }"
11211 (define_expand "copysigndf3"
11212   [(match_operand:DF 0 "register_operand")
11213    (match_operand:DF 1 "register_operand")
11214    (match_operand:DF 2 "register_operand")]
11215   "TARGET_SOFT_FLOAT && arm_arch_thumb2"
11216   "{
11217      rtx op0_low = gen_lowpart (SImode, operands[0]);
11218      rtx op0_high = gen_highpart (SImode, operands[0]);
11219      rtx op1_low = gen_lowpart (SImode, operands[1]);
11220      rtx op1_high = gen_highpart (SImode, operands[1]);
11221      rtx op2_high = gen_highpart (SImode, operands[2]);
11223      rtx scratch1 = gen_reg_rtx (SImode);
11224      rtx scratch2 = gen_reg_rtx (SImode);
11225      emit_move_insn (scratch1, op2_high);
11226      emit_move_insn (scratch2, op1_high);
11228      emit_insn(gen_rtx_SET(scratch1,
11229                            gen_rtx_LSHIFTRT (SImode, op2_high, GEN_INT(31))));
11230      emit_insn(gen_insv_t2(scratch2, GEN_INT(1), GEN_INT(31), scratch1));
11231      emit_move_insn (op0_low, op1_low);
11232      emit_move_insn (op0_high, scratch2);
11234      DONE;
11235   }"
11238 ;; Vector bits common to IWMMXT and Neon
11239 (include "vec-common.md")
11240 ;; Load the Intel Wireless Multimedia Extension patterns
11241 (include "iwmmxt.md")
11242 ;; Load the VFP co-processor patterns
11243 (include "vfp.md")
11244 ;; Thumb-1 patterns
11245 (include "thumb1.md")
11246 ;; Thumb-2 patterns
11247 (include "thumb2.md")
11248 ;; Neon patterns
11249 (include "neon.md")
11250 ;; Crypto patterns
11251 (include "crypto.md")
11252 ;; Synchronization Primitives
11253 (include "sync.md")
11254 ;; Fixed-point patterns
11255 (include "arm-fixed.md")