Fix type in the changelog entry,
[official-gcc.git] / gcc / config / arm / arm.md
blobad5b02e5589ed0aaa47f869c8a1ccb2177e8d1c4
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" "yes,no"
73   (const (if_then_else (symbol_ref "TARGET_THUMB")
74                        (const_string "yes") (const_string "no"))))
76 ; IS_ARCH6 is set to 'yes' when we are generating code form ARMv6.
77 (define_attr "is_arch6" "no,yes" (const (symbol_ref "arm_arch6")))
79 ; IS_THUMB1 is set to 'yes' iff we are generating Thumb-1 code.
80 (define_attr "is_thumb1" "yes,no"
81   (const (if_then_else (symbol_ref "TARGET_THUMB1")
82                        (const_string "yes") (const_string "no"))))
84 ; We use this attribute to disable alternatives that can produce 32-bit
85 ; instructions inside an IT-block in Thumb2 state.  ARMv8 deprecates IT blocks
86 ; that contain 32-bit instructions.
87 (define_attr "enabled_for_depr_it" "no,yes" (const_string "yes"))
89 ; This attribute is used to disable a predicated alternative when we have
90 ; arm_restrict_it.
91 (define_attr "predicable_short_it" "no,yes" (const_string "yes"))
93 ;; Operand number of an input operand that is shifted.  Zero if the
94 ;; given instruction does not shift one of its input operands.
95 (define_attr "shift" "" (const_int 0))
97 ;; [For compatibility with AArch64 in pipeline models]
98 ;; Attribute that specifies whether or not the instruction touches fp
99 ;; registers.
100 (define_attr "fp" "no,yes" (const_string "no"))
102 ; Floating Point Unit.  If we only have floating point emulation, then there
103 ; is no point in scheduling the floating point insns.  (Well, for best
104 ; performance we should try and group them together).
105 (define_attr "fpu" "none,vfp"
106   (const (symbol_ref "arm_fpu_attr")))
108 (define_attr "predicated" "yes,no" (const_string "no"))
110 ; LENGTH of an instruction (in bytes)
111 (define_attr "length" ""
112   (const_int 4))
114 ; The architecture which supports the instruction (or alternative).
115 ; This can be "a" for ARM, "t" for either of the Thumbs, "32" for
116 ; TARGET_32BIT, "t1" or "t2" to specify a specific Thumb mode.  "v6"
117 ; for ARM or Thumb-2 with arm_arch6, and nov6 for ARM without
118 ; arm_arch6.  "v6t2" for Thumb-2 with arm_arch6.  This attribute is
119 ; used to compute attribute "enabled", use type "any" to enable an
120 ; alternative in all cases.
121 (define_attr "arch" "any,a,t,32,t1,t2,v6,nov6,v6t2,neon_for_64bits,avoid_neon_for_64bits,iwmmxt,iwmmxt2,armv6_or_vfpv3"
122   (const_string "any"))
124 (define_attr "arch_enabled" "no,yes"
125   (cond [(eq_attr "arch" "any")
126          (const_string "yes")
128          (and (eq_attr "arch" "a")
129               (match_test "TARGET_ARM"))
130          (const_string "yes")
132          (and (eq_attr "arch" "t")
133               (match_test "TARGET_THUMB"))
134          (const_string "yes")
136          (and (eq_attr "arch" "t1")
137               (match_test "TARGET_THUMB1"))
138          (const_string "yes")
140          (and (eq_attr "arch" "t2")
141               (match_test "TARGET_THUMB2"))
142          (const_string "yes")
144          (and (eq_attr "arch" "32")
145               (match_test "TARGET_32BIT"))
146          (const_string "yes")
148          (and (eq_attr "arch" "v6")
149               (match_test "TARGET_32BIT && arm_arch6"))
150          (const_string "yes")
152          (and (eq_attr "arch" "nov6")
153               (match_test "TARGET_32BIT && !arm_arch6"))
154          (const_string "yes")
156          (and (eq_attr "arch" "v6t2")
157               (match_test "TARGET_32BIT && arm_arch6 && arm_arch_thumb2"))
158          (const_string "yes")
160          (and (eq_attr "arch" "avoid_neon_for_64bits")
161               (match_test "TARGET_NEON")
162               (not (match_test "TARGET_PREFER_NEON_64BITS")))
163          (const_string "yes")
165          (and (eq_attr "arch" "neon_for_64bits")
166               (match_test "TARGET_NEON")
167               (match_test "TARGET_PREFER_NEON_64BITS"))
168          (const_string "yes")
170          (and (eq_attr "arch" "iwmmxt2")
171               (match_test "TARGET_REALLY_IWMMXT2"))
172          (const_string "yes")
174          (and (eq_attr "arch" "armv6_or_vfpv3")
175               (match_test "arm_arch6 || TARGET_VFP3"))
176          (const_string "yes")
177         ]
179         (const_string "no")))
181 (define_attr "opt" "any,speed,size"
182   (const_string "any"))
184 (define_attr "opt_enabled" "no,yes"
185   (cond [(eq_attr "opt" "any")
186          (const_string "yes")
188          (and (eq_attr "opt" "speed")
189               (match_test "optimize_function_for_speed_p (cfun)"))
190          (const_string "yes")
192          (and (eq_attr "opt" "size")
193               (match_test "optimize_function_for_size_p (cfun)"))
194          (const_string "yes")]
195         (const_string "no")))
197 (define_attr "use_literal_pool" "no,yes"
198    (cond [(and (eq_attr "type" "f_loads,f_loadd")
199                (match_test "CONSTANT_P (operands[1])"))
200           (const_string "yes")]
201          (const_string "no")))
203 ; Enable all alternatives that are both arch_enabled and insn_enabled.
204 ; FIXME:: opt_enabled has been temporarily removed till the time we have
205 ; an attribute that allows the use of such alternatives.
206 ; This depends on caching of speed_p, size_p on a per
207 ; alternative basis. The problem is that the enabled attribute
208 ; cannot depend on any state that is not cached or is not constant
209 ; for a compilation unit. We probably need a generic "hot/cold"
210 ; alternative which if implemented can help with this. We disable this
211 ; until such a time as this is implemented and / or the improvements or
212 ; regressions with removing this attribute are double checked.
213 ; See ashldi3_neon and <shift>di3_neon in neon.md.
215  (define_attr "enabled" "no,yes"
216    (cond [(and (eq_attr "predicable_short_it" "no")
217                (and (eq_attr "predicated" "yes")
218                     (match_test "arm_restrict_it")))
219           (const_string "no")
221           (and (eq_attr "enabled_for_depr_it" "no")
222                (match_test "arm_restrict_it"))
223           (const_string "no")
225           (and (eq_attr "use_literal_pool" "yes")
226                (match_test "arm_disable_literal_pool"))
227           (const_string "no")
229           (eq_attr "arch_enabled" "no")
230           (const_string "no")]
231          (const_string "yes")))
233 ; POOL_RANGE is how far away from a constant pool entry that this insn
234 ; can be placed.  If the distance is zero, then this insn will never
235 ; reference the pool.
236 ; Note that for Thumb constant pools the PC value is rounded down to the
237 ; nearest multiple of four.  Therefore, THUMB2_POOL_RANGE (and POOL_RANGE for
238 ; Thumb insns) should be set to <max_range> - 2.
239 ; NEG_POOL_RANGE is nonzero for insns that can reference a constant pool entry
240 ; before its address.  It is set to <max_range> - (8 + <data_size>).
241 (define_attr "arm_pool_range" "" (const_int 0))
242 (define_attr "thumb2_pool_range" "" (const_int 0))
243 (define_attr "arm_neg_pool_range" "" (const_int 0))
244 (define_attr "thumb2_neg_pool_range" "" (const_int 0))
246 (define_attr "pool_range" ""
247   (cond [(eq_attr "is_thumb" "yes") (attr "thumb2_pool_range")]
248         (attr "arm_pool_range")))
249 (define_attr "neg_pool_range" ""
250   (cond [(eq_attr "is_thumb" "yes") (attr "thumb2_neg_pool_range")]
251         (attr "arm_neg_pool_range")))
253 ; An assembler sequence may clobber the condition codes without us knowing.
254 ; If such an insn references the pool, then we have no way of knowing how,
255 ; so use the most conservative value for pool_range.
256 (define_asm_attributes
257  [(set_attr "conds" "clob")
258   (set_attr "length" "4")
259   (set_attr "pool_range" "250")])
261 ; Load scheduling, set from the arm_ld_sched variable
262 ; initialized by arm_option_override()
263 (define_attr "ldsched" "no,yes" (const (symbol_ref "arm_ld_sched")))
265 ; condition codes: this one is used by final_prescan_insn to speed up
266 ; conditionalizing instructions.  It saves having to scan the rtl to see if
267 ; it uses or alters the condition codes.
269 ; USE means that the condition codes are used by the insn in the process of
270 ;   outputting code, this means (at present) that we can't use the insn in
271 ;   inlined branches
273 ; SET means that the purpose of the insn is to set the condition codes in a
274 ;   well defined manner.
276 ; CLOB means that the condition codes are altered in an undefined manner, if
277 ;   they are altered at all
279 ; UNCONDITIONAL means the instruction can not be conditionally executed and
280 ;   that the instruction does not use or alter the condition codes.
282 ; NOCOND means that the instruction does not use or alter the condition
283 ;   codes but can be converted into a conditionally exectuted instruction.
285 (define_attr "conds" "use,set,clob,unconditional,nocond"
286         (if_then_else
287          (ior (eq_attr "is_thumb1" "yes")
288               (eq_attr "type" "call"))
289          (const_string "clob")
290          (if_then_else (eq_attr "is_neon_type" "no")
291          (const_string "nocond")
292          (const_string "unconditional"))))
294 ; Predicable means that the insn can be conditionally executed based on
295 ; an automatically added predicate (additional patterns are generated by 
296 ; gen...).  We default to 'no' because no Thumb patterns match this rule
297 ; and not all ARM patterns do.
298 (define_attr "predicable" "no,yes" (const_string "no"))
300 ; Only model the write buffer for ARM6 and ARM7.  Earlier processors don't
301 ; have one.  Later ones, such as StrongARM, have write-back caches, so don't
302 ; suffer blockages enough to warrant modelling this (and it can adversely
303 ; affect the schedule).
304 (define_attr "model_wbuf" "no,yes" (const (symbol_ref "arm_tune_wbuf")))
306 ; WRITE_CONFLICT implies that a read following an unrelated write is likely
307 ; to stall the processor.  Used with model_wbuf above.
308 (define_attr "write_conflict" "no,yes"
309   (if_then_else (eq_attr "type"
310                  "block,call,load1")
311                 (const_string "yes")
312                 (const_string "no")))
314 ; Classify the insns into those that take one cycle and those that take more
315 ; than one on the main cpu execution unit.
316 (define_attr "core_cycles" "single,multi"
317   (if_then_else (eq_attr "type"
318     "adc_imm, adc_reg, adcs_imm, adcs_reg, adr, alu_ext, alu_imm, alu_sreg,\
319     alu_shift_imm, alu_shift_reg, alu_dsp_reg, alus_ext, alus_imm, alus_sreg,\
320     alus_shift_imm, alus_shift_reg, bfm, csel, rev, logic_imm, logic_reg,\
321     logic_shift_imm, logic_shift_reg, logics_imm, logics_reg,\
322     logics_shift_imm, logics_shift_reg, extend, shift_imm, float, fcsel,\
323     wmmx_wor, wmmx_wxor, wmmx_wand, wmmx_wandn, wmmx_wmov, wmmx_tmcrr,\
324     wmmx_tmrrc, wmmx_wldr, wmmx_wstr, wmmx_tmcr, wmmx_tmrc, wmmx_wadd,\
325     wmmx_wsub, wmmx_wmul, wmmx_wmac, wmmx_wavg2, wmmx_tinsr, wmmx_textrm,\
326     wmmx_wshufh, wmmx_wcmpeq, wmmx_wcmpgt, wmmx_wmax, wmmx_wmin, wmmx_wpack,\
327     wmmx_wunpckih, wmmx_wunpckil, wmmx_wunpckeh, wmmx_wunpckel, wmmx_wror,\
328     wmmx_wsra, wmmx_wsrl, wmmx_wsll, wmmx_wmadd, wmmx_tmia, wmmx_tmiaph,\
329     wmmx_tmiaxy, wmmx_tbcst, wmmx_tmovmsk, wmmx_wacc, wmmx_waligni,\
330     wmmx_walignr, wmmx_tandc, wmmx_textrc, wmmx_torc, wmmx_torvsc, wmmx_wsad,\
331     wmmx_wabs, wmmx_wabsdiff, wmmx_waddsubhx, wmmx_wsubaddhx, wmmx_wavg4,\
332     wmmx_wmulw, wmmx_wqmulm, wmmx_wqmulwm, wmmx_waddbhus, wmmx_wqmiaxy,\
333     wmmx_wmiaxy, wmmx_wmiawxy, wmmx_wmerge")
334                 (const_string "single")
335                 (const_string "multi")))
337 ;; FAR_JUMP is "yes" if a BL instruction is used to generate a branch to a
338 ;; distant label.  Only applicable to Thumb code.
339 (define_attr "far_jump" "yes,no" (const_string "no"))
342 ;; The number of machine instructions this pattern expands to.
343 ;; Used for Thumb-2 conditional execution.
344 (define_attr "ce_count" "" (const_int 1))
346 ;;---------------------------------------------------------------------------
347 ;; Unspecs
349 (include "unspecs.md")
351 ;;---------------------------------------------------------------------------
352 ;; Mode iterators
354 (include "iterators.md")
356 ;;---------------------------------------------------------------------------
357 ;; Predicates
359 (include "predicates.md")
360 (include "constraints.md")
362 ;;---------------------------------------------------------------------------
363 ;; Pipeline descriptions
365 (define_attr "tune_cortexr4" "yes,no"
366   (const (if_then_else
367           (eq_attr "tune" "cortexr4,cortexr4f,cortexr5")
368           (const_string "yes")
369           (const_string "no"))))
371 ;; True if the generic scheduling description should be used.
373 (define_attr "generic_sched" "yes,no"
374   (const (if_then_else
375           (ior (eq_attr "tune" "fa526,fa626,fa606te,fa626te,fmp626,fa726te,\
376                                 arm926ejs,arm1020e,arm1026ejs,arm1136js,\
377                                 arm1136jfs,cortexa5,cortexa7,cortexa8,\
378                                 cortexa9,cortexa12,cortexa15,cortexa17,\
379                                 cortexa53,cortexa57,cortexm4,cortexm7,\
380                                 marvell_pj4,xgene1")
381                (eq_attr "tune_cortexr4" "yes"))
382           (const_string "no")
383           (const_string "yes"))))
385 (define_attr "generic_vfp" "yes,no"
386   (const (if_then_else
387           (and (eq_attr "fpu" "vfp")
388                (eq_attr "tune" "!arm1020e,arm1022e,cortexa5,cortexa7,\
389                                 cortexa8,cortexa9,cortexa53,cortexm4,\
390                                 cortexm7,marvell_pj4,xgene1")
391                (eq_attr "tune_cortexr4" "no"))
392           (const_string "yes")
393           (const_string "no"))))
395 (include "marvell-f-iwmmxt.md")
396 (include "arm-generic.md")
397 (include "arm926ejs.md")
398 (include "arm1020e.md")
399 (include "arm1026ejs.md")
400 (include "arm1136jfs.md")
401 (include "fa526.md")
402 (include "fa606te.md")
403 (include "fa626te.md")
404 (include "fmp626.md")
405 (include "fa726te.md")
406 (include "cortex-a5.md")
407 (include "cortex-a7.md")
408 (include "cortex-a8.md")
409 (include "cortex-a9.md")
410 (include "cortex-a15.md")
411 (include "cortex-a17.md")
412 (include "cortex-a53.md")
413 (include "cortex-a57.md")
414 (include "cortex-r4.md")
415 (include "cortex-r4f.md")
416 (include "cortex-m7.md")
417 (include "cortex-m4.md")
418 (include "cortex-m4-fpu.md")
419 (include "vfp11.md")
420 (include "marvell-pj4.md")
421 (include "xgene1.md")
424 ;;---------------------------------------------------------------------------
425 ;; Insn patterns
427 ;; Addition insns.
429 ;; Note: For DImode insns, there is normally no reason why operands should
430 ;; not be in the same register, what we don't want is for something being
431 ;; written to partially overlap something that is an input.
433 (define_expand "adddi3"
434  [(parallel
435    [(set (match_operand:DI           0 "s_register_operand" "")
436           (plus:DI (match_operand:DI 1 "s_register_operand" "")
437                    (match_operand:DI 2 "arm_adddi_operand"  "")))
438     (clobber (reg:CC CC_REGNUM))])]
439   "TARGET_EITHER"
440   "
441   if (TARGET_THUMB1)
442     {
443       if (!REG_P (operands[1]))
444         operands[1] = force_reg (DImode, operands[1]);
445       if (!REG_P (operands[2]))
446         operands[2] = force_reg (DImode, operands[2]);
447      }
448   "
451 (define_insn_and_split "*arm_adddi3"
452   [(set (match_operand:DI          0 "s_register_operand" "=&r,&r,&r,&r,&r")
453         (plus:DI (match_operand:DI 1 "s_register_operand" "%0, 0, r, 0, r")
454                  (match_operand:DI 2 "arm_adddi_operand"  "r,  0, r, Dd, Dd")))
455    (clobber (reg:CC CC_REGNUM))]
456   "TARGET_32BIT && !TARGET_NEON"
457   "#"
458   "TARGET_32BIT && reload_completed
459    && ! (TARGET_NEON && IS_VFP_REGNUM (REGNO (operands[0])))"
460   [(parallel [(set (reg:CC_C CC_REGNUM)
461                    (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
462                                  (match_dup 1)))
463               (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
464    (set (match_dup 3) (plus:SI (plus:SI (match_dup 4) (match_dup 5))
465                                (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
466   "
467   {
468     operands[3] = gen_highpart (SImode, operands[0]);
469     operands[0] = gen_lowpart (SImode, operands[0]);
470     operands[4] = gen_highpart (SImode, operands[1]);
471     operands[1] = gen_lowpart (SImode, operands[1]);
472     operands[5] = gen_highpart_mode (SImode, DImode, operands[2]);
473     operands[2] = gen_lowpart (SImode, operands[2]);
474   }"
475   [(set_attr "conds" "clob")
476    (set_attr "length" "8")
477    (set_attr "type" "multiple")]
480 (define_insn_and_split "*adddi_sesidi_di"
481   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
482         (plus:DI (sign_extend:DI
483                   (match_operand:SI 2 "s_register_operand" "r,r"))
484                  (match_operand:DI 1 "s_register_operand" "0,r")))
485    (clobber (reg:CC CC_REGNUM))]
486   "TARGET_32BIT"
487   "#"
488   "TARGET_32BIT && reload_completed"
489   [(parallel [(set (reg:CC_C CC_REGNUM)
490                    (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
491                                  (match_dup 1)))
492               (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
493    (set (match_dup 3) (plus:SI (plus:SI (ashiftrt:SI (match_dup 2)
494                                                      (const_int 31))
495                                         (match_dup 4))
496                                (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
497   "
498   {
499     operands[3] = gen_highpart (SImode, operands[0]);
500     operands[0] = gen_lowpart (SImode, operands[0]);
501     operands[4] = gen_highpart (SImode, operands[1]);
502     operands[1] = gen_lowpart (SImode, operands[1]);
503     operands[2] = gen_lowpart (SImode, operands[2]);
504   }"
505   [(set_attr "conds" "clob")
506    (set_attr "length" "8")
507    (set_attr "type" "multiple")]
510 (define_insn_and_split "*adddi_zesidi_di"
511   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
512         (plus:DI (zero_extend:DI
513                   (match_operand:SI 2 "s_register_operand" "r,r"))
514                  (match_operand:DI 1 "s_register_operand" "0,r")))
515    (clobber (reg:CC CC_REGNUM))]
516   "TARGET_32BIT"
517   "#"
518   "TARGET_32BIT && reload_completed"
519   [(parallel [(set (reg:CC_C CC_REGNUM)
520                    (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
521                                  (match_dup 1)))
522               (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
523    (set (match_dup 3) (plus:SI (plus:SI (match_dup 4) (const_int 0))
524                                (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
525   "
526   {
527     operands[3] = gen_highpart (SImode, operands[0]);
528     operands[0] = gen_lowpart (SImode, operands[0]);
529     operands[4] = gen_highpart (SImode, operands[1]);
530     operands[1] = gen_lowpart (SImode, operands[1]);
531     operands[2] = gen_lowpart (SImode, operands[2]);
532   }"
533   [(set_attr "conds" "clob")
534    (set_attr "length" "8")
535    (set_attr "type" "multiple")]
538 (define_expand "addsi3"
539   [(set (match_operand:SI          0 "s_register_operand" "")
540         (plus:SI (match_operand:SI 1 "s_register_operand" "")
541                  (match_operand:SI 2 "reg_or_int_operand" "")))]
542   "TARGET_EITHER"
543   "
544   if (TARGET_32BIT && CONST_INT_P (operands[2]))
545     {
546       arm_split_constant (PLUS, SImode, NULL_RTX,
547                           INTVAL (operands[2]), operands[0], operands[1],
548                           optimize && can_create_pseudo_p ());
549       DONE;
550     }
551   "
554 ; If there is a scratch available, this will be faster than synthesizing the
555 ; addition.
556 (define_peephole2
557   [(match_scratch:SI 3 "r")
558    (set (match_operand:SI          0 "arm_general_register_operand" "")
559         (plus:SI (match_operand:SI 1 "arm_general_register_operand" "")
560                  (match_operand:SI 2 "const_int_operand"  "")))]
561   "TARGET_32BIT &&
562    !(const_ok_for_arm (INTVAL (operands[2]))
563      || const_ok_for_arm (-INTVAL (operands[2])))
564     && const_ok_for_arm (~INTVAL (operands[2]))"
565   [(set (match_dup 3) (match_dup 2))
566    (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 3)))]
567   ""
570 ;; The r/r/k alternative is required when reloading the address
571 ;;  (plus (reg rN) (reg sp)) into (reg rN).  In this case reload will
572 ;; put the duplicated register first, and not try the commutative version.
573 (define_insn_and_split "*arm_addsi3"
574   [(set (match_operand:SI          0 "s_register_operand" "=rk,l,l ,l ,r ,k ,r,r ,k ,r ,k,k,r ,k ,r")
575         (plus:SI (match_operand:SI 1 "s_register_operand" "%0 ,l,0 ,l ,rk,k ,r,rk,k ,rk,k,r,rk,k ,rk")
576                  (match_operand:SI 2 "reg_or_int_operand" "rk ,l,Py,Pd,rI,rI,k,Pj,Pj,L ,L,L,PJ,PJ,?n")))]
577   "TARGET_32BIT"
578   "@
579    add%?\\t%0, %0, %2
580    add%?\\t%0, %1, %2
581    add%?\\t%0, %1, %2
582    add%?\\t%0, %1, %2
583    add%?\\t%0, %1, %2
584    add%?\\t%0, %1, %2
585    add%?\\t%0, %2, %1
586    addw%?\\t%0, %1, %2
587    addw%?\\t%0, %1, %2
588    sub%?\\t%0, %1, #%n2
589    sub%?\\t%0, %1, #%n2
590    sub%?\\t%0, %1, #%n2
591    subw%?\\t%0, %1, #%n2
592    subw%?\\t%0, %1, #%n2
593    #"
594   "TARGET_32BIT
595    && CONST_INT_P (operands[2])
596    && !const_ok_for_op (INTVAL (operands[2]), PLUS)
597    && (reload_completed || !arm_eliminable_register (operands[1]))"
598   [(clobber (const_int 0))]
599   "
600   arm_split_constant (PLUS, SImode, curr_insn,
601                       INTVAL (operands[2]), operands[0],
602                       operands[1], 0);
603   DONE;
604   "
605   [(set_attr "length" "2,4,4,4,4,4,4,4,4,4,4,4,4,4,16")
606    (set_attr "predicable" "yes")
607    (set_attr "predicable_short_it" "yes,yes,yes,yes,no,no,no,no,no,no,no,no,no,no,no")
608    (set_attr "arch" "t2,t2,t2,t2,*,*,*,t2,t2,*,*,a,t2,t2,*")
609    (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
610                       (const_string "alu_imm")
611                       (const_string "alu_sreg")))
615 (define_insn "addsi3_compare0"
616   [(set (reg:CC_NOOV CC_REGNUM)
617         (compare:CC_NOOV
618          (plus:SI (match_operand:SI 1 "s_register_operand" "r, r,r")
619                   (match_operand:SI 2 "arm_add_operand"    "I,L,r"))
620          (const_int 0)))
621    (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
622         (plus:SI (match_dup 1) (match_dup 2)))]
623   "TARGET_ARM"
624   "@
625    add%.\\t%0, %1, %2
626    sub%.\\t%0, %1, #%n2
627    add%.\\t%0, %1, %2"
628   [(set_attr "conds" "set")
629    (set_attr "type" "alus_imm,alus_imm,alus_sreg")]
632 (define_insn "*addsi3_compare0_scratch"
633   [(set (reg:CC_NOOV CC_REGNUM)
634         (compare:CC_NOOV
635          (plus:SI (match_operand:SI 0 "s_register_operand" "r, r, r")
636                   (match_operand:SI 1 "arm_add_operand"    "I,L, r"))
637          (const_int 0)))]
638   "TARGET_ARM"
639   "@
640    cmn%?\\t%0, %1
641    cmp%?\\t%0, #%n1
642    cmn%?\\t%0, %1"
643   [(set_attr "conds" "set")
644    (set_attr "predicable" "yes")
645    (set_attr "type" "alus_imm,alus_imm,alus_sreg")]
648 (define_insn "*compare_negsi_si"
649   [(set (reg:CC_Z CC_REGNUM)
650         (compare:CC_Z
651          (neg:SI (match_operand:SI 0 "s_register_operand" "l,r"))
652          (match_operand:SI 1 "s_register_operand" "l,r")))]
653   "TARGET_32BIT"
654   "cmn%?\\t%1, %0"
655   [(set_attr "conds" "set")
656    (set_attr "predicable" "yes")
657    (set_attr "arch" "t2,*")
658    (set_attr "length" "2,4")
659    (set_attr "predicable_short_it" "yes,no")
660    (set_attr "type" "alus_sreg")]
663 ;; This is the canonicalization of addsi3_compare0_for_combiner when the
664 ;; addend is a constant.
665 (define_insn "cmpsi2_addneg"
666   [(set (reg:CC CC_REGNUM)
667         (compare:CC
668          (match_operand:SI 1 "s_register_operand" "r,r")
669          (match_operand:SI 2 "arm_addimm_operand" "L,I")))
670    (set (match_operand:SI 0 "s_register_operand" "=r,r")
671         (plus:SI (match_dup 1)
672                  (match_operand:SI 3 "arm_addimm_operand" "I,L")))]
673   "TARGET_32BIT && INTVAL (operands[2]) == -INTVAL (operands[3])"
674   "@
675    add%.\\t%0, %1, %3
676    sub%.\\t%0, %1, #%n3"
677   [(set_attr "conds" "set")
678    (set_attr "type" "alus_sreg")]
681 ;; Convert the sequence
682 ;;  sub  rd, rn, #1
683 ;;  cmn  rd, #1 (equivalent to cmp rd, #-1)
684 ;;  bne  dest
685 ;; into
686 ;;  subs rd, rn, #1
687 ;;  bcs  dest   ((unsigned)rn >= 1)
688 ;; similarly for the beq variant using bcc.
689 ;; This is a common looping idiom (while (n--))
690 (define_peephole2
691   [(set (match_operand:SI 0 "arm_general_register_operand" "")
692         (plus:SI (match_operand:SI 1 "arm_general_register_operand" "")
693                  (const_int -1)))
694    (set (match_operand 2 "cc_register" "")
695         (compare (match_dup 0) (const_int -1)))
696    (set (pc)
697         (if_then_else (match_operator 3 "equality_operator"
698                        [(match_dup 2) (const_int 0)])
699                       (match_operand 4 "" "")
700                       (match_operand 5 "" "")))]
701   "TARGET_32BIT && peep2_reg_dead_p (3, operands[2])"
702   [(parallel[
703     (set (match_dup 2)
704          (compare:CC
705           (match_dup 1) (const_int 1)))
706     (set (match_dup 0) (plus:SI (match_dup 1) (const_int -1)))])
707    (set (pc)
708         (if_then_else (match_op_dup 3 [(match_dup 2) (const_int 0)])
709                       (match_dup 4)
710                       (match_dup 5)))]
711   "operands[2] = gen_rtx_REG (CCmode, CC_REGNUM);
712    operands[3] = gen_rtx_fmt_ee ((GET_CODE (operands[3]) == NE
713                                   ? GEU : LTU),
714                                  VOIDmode, 
715                                  operands[2], const0_rtx);"
718 ;; The next four insns work because they compare the result with one of
719 ;; the operands, and we know that the use of the condition code is
720 ;; either GEU or LTU, so we can use the carry flag from the addition
721 ;; instead of doing the compare a second time.
722 (define_insn "*addsi3_compare_op1"
723   [(set (reg:CC_C CC_REGNUM)
724         (compare:CC_C
725          (plus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
726                   (match_operand:SI 2 "arm_add_operand" "I,L,r"))
727          (match_dup 1)))
728    (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
729         (plus:SI (match_dup 1) (match_dup 2)))]
730   "TARGET_32BIT"
731   "@
732    add%.\\t%0, %1, %2
733    sub%.\\t%0, %1, #%n2
734    add%.\\t%0, %1, %2"
735   [(set_attr "conds" "set")
736    (set_attr "type"  "alus_imm,alus_imm,alus_sreg")]
739 (define_insn "*addsi3_compare_op2"
740   [(set (reg:CC_C CC_REGNUM)
741         (compare:CC_C
742          (plus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
743                   (match_operand:SI 2 "arm_add_operand" "I,L,r"))
744          (match_dup 2)))
745    (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
746         (plus:SI (match_dup 1) (match_dup 2)))]
747   "TARGET_32BIT"
748   "@
749    add%.\\t%0, %1, %2
750    add%.\\t%0, %1, %2
751    sub%.\\t%0, %1, #%n2"
752   [(set_attr "conds" "set")
753    (set_attr "type" "alus_imm,alus_imm,alus_sreg")]
756 (define_insn "*compare_addsi2_op0"
757   [(set (reg:CC_C CC_REGNUM)
758         (compare:CC_C
759           (plus:SI (match_operand:SI 0 "s_register_operand" "l,l,r,r,r")
760                    (match_operand:SI 1 "arm_add_operand" "Pv,l,I,L,r"))
761           (match_dup 0)))]
762   "TARGET_32BIT"
763   "@
764    cmp%?\\t%0, #%n1
765    cmn%?\\t%0, %1
766    cmn%?\\t%0, %1
767    cmp%?\\t%0, #%n1
768    cmn%?\\t%0, %1"
769   [(set_attr "conds" "set")
770    (set_attr "predicable" "yes")
771    (set_attr "arch" "t2,t2,*,*,*")
772    (set_attr "predicable_short_it" "yes,yes,no,no,no")
773    (set_attr "length" "2,2,4,4,4")
774    (set_attr "type" "alus_imm,alus_sreg,alus_imm,alus_imm,alus_sreg")]
777 (define_insn "*compare_addsi2_op1"
778   [(set (reg:CC_C CC_REGNUM)
779         (compare:CC_C
780           (plus:SI (match_operand:SI 0 "s_register_operand" "l,l,r,r,r")
781                    (match_operand:SI 1 "arm_add_operand" "Pv,l,I,L,r"))
782           (match_dup 1)))]
783   "TARGET_32BIT"
784   "@
785    cmp%?\\t%0, #%n1
786    cmn%?\\t%0, %1
787    cmn%?\\t%0, %1
788    cmp%?\\t%0, #%n1
789    cmn%?\\t%0, %1"
790   [(set_attr "conds" "set")
791    (set_attr "predicable" "yes")
792    (set_attr "arch" "t2,t2,*,*,*")
793    (set_attr "predicable_short_it" "yes,yes,no,no,no")
794    (set_attr "length" "2,2,4,4,4")
795    (set_attr "type" "alus_imm,alus_sreg,alus_imm,alus_imm,alus_sreg")]
798 (define_insn "*addsi3_carryin_<optab>"
799   [(set (match_operand:SI 0 "s_register_operand" "=l,r,r")
800         (plus:SI (plus:SI (match_operand:SI 1 "s_register_operand" "%l,r,r")
801                           (match_operand:SI 2 "arm_not_operand" "0,rI,K"))
802                  (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))))]
803   "TARGET_32BIT"
804   "@
805    adc%?\\t%0, %1, %2
806    adc%?\\t%0, %1, %2
807    sbc%?\\t%0, %1, #%B2"
808   [(set_attr "conds" "use")
809    (set_attr "predicable" "yes")
810    (set_attr "arch" "t2,*,*")
811    (set_attr "length" "4")
812    (set_attr "predicable_short_it" "yes,no,no")
813    (set_attr "type" "adc_reg,adc_reg,adc_imm")]
816 (define_insn "*addsi3_carryin_alt2_<optab>"
817   [(set (match_operand:SI 0 "s_register_operand" "=l,r,r")
818         (plus:SI (plus:SI (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))
819                           (match_operand:SI 1 "s_register_operand" "%l,r,r"))
820                  (match_operand:SI 2 "arm_rhs_operand" "l,rI,K")))]
821   "TARGET_32BIT"
822   "@
823    adc%?\\t%0, %1, %2
824    adc%?\\t%0, %1, %2
825    sbc%?\\t%0, %1, #%B2"
826   [(set_attr "conds" "use")
827    (set_attr "predicable" "yes")
828    (set_attr "arch" "t2,*,*")
829    (set_attr "length" "4")
830    (set_attr "predicable_short_it" "yes,no,no")
831    (set_attr "type" "adc_reg,adc_reg,adc_imm")]
834 (define_insn "*addsi3_carryin_shift_<optab>"
835   [(set (match_operand:SI 0 "s_register_operand" "=r")
836         (plus:SI (plus:SI
837                   (match_operator:SI 2 "shift_operator"
838                     [(match_operand:SI 3 "s_register_operand" "r")
839                      (match_operand:SI 4 "reg_or_int_operand" "rM")])
840                   (match_operand:SI 1 "s_register_operand" "r"))
841                  (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))))]
842   "TARGET_32BIT"
843   "adc%?\\t%0, %1, %3%S2"
844   [(set_attr "conds" "use")
845    (set_attr "predicable" "yes")
846    (set_attr "predicable_short_it" "no")
847    (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
848                       (const_string "alu_shift_imm")
849                       (const_string "alu_shift_reg")))]
852 (define_insn "*addsi3_carryin_clobercc_<optab>"
853   [(set (match_operand:SI 0 "s_register_operand" "=r")
854         (plus:SI (plus:SI (match_operand:SI 1 "s_register_operand" "%r")
855                           (match_operand:SI 2 "arm_rhs_operand" "rI"))
856                  (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))))
857    (clobber (reg:CC CC_REGNUM))]
858    "TARGET_32BIT"
859    "adc%.\\t%0, %1, %2"
860    [(set_attr "conds" "set")
861     (set_attr "type" "adcs_reg")]
864 (define_insn "*subsi3_carryin"
865   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
866         (minus:SI (minus:SI (match_operand:SI 1 "reg_or_int_operand" "r,I")
867                             (match_operand:SI 2 "s_register_operand" "r,r"))
868                   (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
869   "TARGET_32BIT"
870   "@
871    sbc%?\\t%0, %1, %2
872    rsc%?\\t%0, %2, %1"
873   [(set_attr "conds" "use")
874    (set_attr "arch" "*,a")
875    (set_attr "predicable" "yes")
876    (set_attr "predicable_short_it" "no")
877    (set_attr "type" "adc_reg,adc_imm")]
880 (define_insn "*subsi3_carryin_const"
881   [(set (match_operand:SI 0 "s_register_operand" "=r")
882         (minus:SI (plus:SI (match_operand:SI 1 "reg_or_int_operand" "r")
883                            (match_operand:SI 2 "arm_not_operand" "K"))
884                   (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
885   "TARGET_32BIT"
886   "sbc\\t%0, %1, #%B2"
887   [(set_attr "conds" "use")
888    (set_attr "type" "adc_imm")]
891 (define_insn "*subsi3_carryin_compare"
892   [(set (reg:CC CC_REGNUM)
893         (compare:CC (match_operand:SI 1 "s_register_operand" "r")
894                     (match_operand:SI 2 "s_register_operand" "r")))
895    (set (match_operand:SI 0 "s_register_operand" "=r")
896         (minus:SI (minus:SI (match_dup 1)
897                             (match_dup 2))
898                   (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
899   "TARGET_32BIT"
900   "sbcs\\t%0, %1, %2"
901   [(set_attr "conds" "set")
902    (set_attr "type" "adcs_reg")]
905 (define_insn "*subsi3_carryin_compare_const"
906   [(set (reg:CC CC_REGNUM)
907         (compare:CC (match_operand:SI 1 "reg_or_int_operand" "r")
908                     (match_operand:SI 2 "arm_not_operand" "K")))
909    (set (match_operand:SI 0 "s_register_operand" "=r")
910         (minus:SI (plus:SI (match_dup 1)
911                            (match_dup 2))
912                   (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
913   "TARGET_32BIT"
914   "sbcs\\t%0, %1, #%B2"
915   [(set_attr "conds" "set")
916    (set_attr "type" "adcs_imm")]
919 (define_insn "*subsi3_carryin_shift"
920   [(set (match_operand:SI 0 "s_register_operand" "=r")
921         (minus:SI (minus:SI
922                   (match_operand:SI 1 "s_register_operand" "r")
923                   (match_operator:SI 2 "shift_operator"
924                    [(match_operand:SI 3 "s_register_operand" "r")
925                     (match_operand:SI 4 "reg_or_int_operand" "rM")]))
926                  (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
927   "TARGET_32BIT"
928   "sbc%?\\t%0, %1, %3%S2"
929   [(set_attr "conds" "use")
930    (set_attr "predicable" "yes")
931    (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
932                       (const_string "alu_shift_imm")
933                      (const_string "alu_shift_reg")))]
936 (define_insn "*rsbsi3_carryin_shift"
937   [(set (match_operand:SI 0 "s_register_operand" "=r")
938         (minus:SI (minus:SI
939                   (match_operator:SI 2 "shift_operator"
940                    [(match_operand:SI 3 "s_register_operand" "r")
941                     (match_operand:SI 4 "reg_or_int_operand" "rM")])
942                    (match_operand:SI 1 "s_register_operand" "r"))
943                  (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
944   "TARGET_ARM"
945   "rsc%?\\t%0, %1, %3%S2"
946   [(set_attr "conds" "use")
947    (set_attr "predicable" "yes")
948    (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
949                       (const_string "alu_shift_imm")
950                       (const_string "alu_shift_reg")))]
953 ; transform ((x << y) - 1) to ~(~(x-1) << y)  Where X is a constant.
954 (define_split
955   [(set (match_operand:SI 0 "s_register_operand" "")
956         (plus:SI (ashift:SI (match_operand:SI 1 "const_int_operand" "")
957                             (match_operand:SI 2 "s_register_operand" ""))
958                  (const_int -1)))
959    (clobber (match_operand:SI 3 "s_register_operand" ""))]
960   "TARGET_32BIT"
961   [(set (match_dup 3) (match_dup 1))
962    (set (match_dup 0) (not:SI (ashift:SI (match_dup 3) (match_dup 2))))]
963   "
964   operands[1] = GEN_INT (~(INTVAL (operands[1]) - 1));
967 (define_expand "addsf3"
968   [(set (match_operand:SF          0 "s_register_operand" "")
969         (plus:SF (match_operand:SF 1 "s_register_operand" "")
970                  (match_operand:SF 2 "s_register_operand" "")))]
971   "TARGET_32BIT && TARGET_HARD_FLOAT"
972   "
975 (define_expand "adddf3"
976   [(set (match_operand:DF          0 "s_register_operand" "")
977         (plus:DF (match_operand:DF 1 "s_register_operand" "")
978                  (match_operand:DF 2 "s_register_operand" "")))]
979   "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
980   "
983 (define_expand "subdi3"
984  [(parallel
985    [(set (match_operand:DI            0 "s_register_operand" "")
986           (minus:DI (match_operand:DI 1 "s_register_operand" "")
987                     (match_operand:DI 2 "s_register_operand" "")))
988     (clobber (reg:CC CC_REGNUM))])]
989   "TARGET_EITHER"
990   "
991   if (TARGET_THUMB1)
992     {
993       if (!REG_P (operands[1]))
994         operands[1] = force_reg (DImode, operands[1]);
995       if (!REG_P (operands[2]))
996         operands[2] = force_reg (DImode, operands[2]);
997      }  
998   "
1001 (define_insn_and_split "*arm_subdi3"
1002   [(set (match_operand:DI           0 "s_register_operand" "=&r,&r,&r")
1003         (minus:DI (match_operand:DI 1 "s_register_operand" "0,r,0")
1004                   (match_operand:DI 2 "s_register_operand" "r,0,0")))
1005    (clobber (reg:CC CC_REGNUM))]
1006   "TARGET_32BIT && !TARGET_NEON"
1007   "#"  ; "subs\\t%Q0, %Q1, %Q2\;sbc\\t%R0, %R1, %R2"
1008   "&& reload_completed"
1009   [(parallel [(set (reg:CC CC_REGNUM)
1010                    (compare:CC (match_dup 1) (match_dup 2)))
1011               (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1012    (set (match_dup 3) (minus:SI (minus:SI (match_dup 4) (match_dup 5))
1013                                (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1014   {
1015     operands[3] = gen_highpart (SImode, operands[0]);
1016     operands[0] = gen_lowpart (SImode, operands[0]);
1017     operands[4] = gen_highpart (SImode, operands[1]);
1018     operands[1] = gen_lowpart (SImode, operands[1]);
1019     operands[5] = gen_highpart (SImode, operands[2]);
1020     operands[2] = gen_lowpart (SImode, operands[2]);
1021    }
1022   [(set_attr "conds" "clob")
1023    (set_attr "length" "8")
1024    (set_attr "type" "multiple")]
1027 (define_insn_and_split "*subdi_di_zesidi"
1028   [(set (match_operand:DI           0 "s_register_operand" "=&r,&r")
1029         (minus:DI (match_operand:DI 1 "s_register_operand"  "0,r")
1030                   (zero_extend:DI
1031                    (match_operand:SI 2 "s_register_operand"  "r,r"))))
1032    (clobber (reg:CC CC_REGNUM))]
1033   "TARGET_32BIT"
1034   "#"   ; "subs\\t%Q0, %Q1, %2\;sbc\\t%R0, %R1, #0"
1035   "&& reload_completed"
1036   [(parallel [(set (reg:CC CC_REGNUM)
1037                    (compare:CC (match_dup 1) (match_dup 2)))
1038               (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1039    (set (match_dup 3) (minus:SI (plus:SI (match_dup 4) (match_dup 5))
1040                                 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1041   {
1042     operands[3] = gen_highpart (SImode, operands[0]);
1043     operands[0] = gen_lowpart (SImode, operands[0]);
1044     operands[4] = gen_highpart (SImode, operands[1]);
1045     operands[1] = gen_lowpart (SImode, operands[1]);
1046     operands[5] = GEN_INT (~0);
1047    }
1048   [(set_attr "conds" "clob")
1049    (set_attr "length" "8")
1050    (set_attr "type" "multiple")]
1053 (define_insn_and_split "*subdi_di_sesidi"
1054   [(set (match_operand:DI            0 "s_register_operand" "=&r,&r")
1055         (minus:DI (match_operand:DI  1 "s_register_operand"  "0,r")
1056                   (sign_extend:DI
1057                    (match_operand:SI 2 "s_register_operand"  "r,r"))))
1058    (clobber (reg:CC CC_REGNUM))]
1059   "TARGET_32BIT"
1060   "#"   ; "subs\\t%Q0, %Q1, %2\;sbc\\t%R0, %R1, %2, asr #31"
1061   "&& reload_completed"
1062   [(parallel [(set (reg:CC CC_REGNUM)
1063                    (compare:CC (match_dup 1) (match_dup 2)))
1064               (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1065    (set (match_dup 3) (minus:SI (minus:SI (match_dup 4)
1066                                          (ashiftrt:SI (match_dup 2)
1067                                                       (const_int 31)))
1068                                 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1069   {
1070     operands[3] = gen_highpart (SImode, operands[0]);
1071     operands[0] = gen_lowpart (SImode, operands[0]);
1072     operands[4] = gen_highpart (SImode, operands[1]);
1073     operands[1] = gen_lowpart (SImode, operands[1]);
1074   }
1075   [(set_attr "conds" "clob")
1076    (set_attr "length" "8")
1077    (set_attr "type" "multiple")]
1080 (define_insn_and_split "*subdi_zesidi_di"
1081   [(set (match_operand:DI            0 "s_register_operand" "=&r,&r")
1082         (minus:DI (zero_extend:DI
1083                    (match_operand:SI 2 "s_register_operand"  "r,r"))
1084                   (match_operand:DI  1 "s_register_operand" "0,r")))
1085    (clobber (reg:CC CC_REGNUM))]
1086   "TARGET_ARM"
1087   "#"   ; "rsbs\\t%Q0, %Q1, %2\;rsc\\t%R0, %R1, #0"
1088         ; is equivalent to:
1089         ; "subs\\t%Q0, %2, %Q1\;rsc\\t%R0, %R1, #0"
1090   "&& reload_completed"
1091   [(parallel [(set (reg:CC CC_REGNUM)
1092                    (compare:CC (match_dup 2) (match_dup 1)))
1093               (set (match_dup 0) (minus:SI (match_dup 2) (match_dup 1)))])
1094    (set (match_dup 3) (minus:SI (minus:SI (const_int 0) (match_dup 4))
1095                                (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1096   {
1097     operands[3] = gen_highpart (SImode, operands[0]);
1098     operands[0] = gen_lowpart (SImode, operands[0]);
1099     operands[4] = gen_highpart (SImode, operands[1]);
1100     operands[1] = gen_lowpart (SImode, operands[1]);
1101   }
1102   [(set_attr "conds" "clob")
1103    (set_attr "length" "8")
1104    (set_attr "type" "multiple")]
1107 (define_insn_and_split "*subdi_sesidi_di"
1108   [(set (match_operand:DI            0 "s_register_operand" "=&r,&r")
1109         (minus:DI (sign_extend:DI
1110                    (match_operand:SI 2 "s_register_operand"   "r,r"))
1111                   (match_operand:DI  1 "s_register_operand"  "0,r")))
1112    (clobber (reg:CC CC_REGNUM))]
1113   "TARGET_ARM"
1114   "#"   ; "rsbs\\t%Q0, %Q1, %2\;rsc\\t%R0, %R1, %2, asr #31"
1115         ; is equivalent to:
1116         ; "subs\\t%Q0, %2, %Q1\;rsc\\t%R0, %R1, %2, asr #31"
1117   "&& reload_completed"
1118   [(parallel [(set (reg:CC CC_REGNUM)
1119                    (compare:CC (match_dup 2) (match_dup 1)))
1120               (set (match_dup 0) (minus:SI (match_dup 2) (match_dup 1)))])
1121    (set (match_dup 3) (minus:SI (minus:SI
1122                                 (ashiftrt:SI (match_dup 2)
1123                                              (const_int 31))
1124                                 (match_dup 4))
1125                                (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1126   {
1127     operands[3] = gen_highpart (SImode, operands[0]);
1128     operands[0] = gen_lowpart (SImode, operands[0]);
1129     operands[4] = gen_highpart (SImode, operands[1]);
1130     operands[1] = gen_lowpart (SImode, operands[1]);
1131   }
1132   [(set_attr "conds" "clob")
1133    (set_attr "length" "8")
1134    (set_attr "type" "multiple")]
1137 (define_insn_and_split "*subdi_zesidi_zesidi"
1138   [(set (match_operand:DI            0 "s_register_operand" "=r")
1139         (minus:DI (zero_extend:DI
1140                    (match_operand:SI 1 "s_register_operand"  "r"))
1141                   (zero_extend:DI
1142                    (match_operand:SI 2 "s_register_operand"  "r"))))
1143    (clobber (reg:CC CC_REGNUM))]
1144   "TARGET_32BIT"
1145   "#"   ; "subs\\t%Q0, %1, %2\;sbc\\t%R0, %1, %1"
1146   "&& reload_completed"
1147   [(parallel [(set (reg:CC CC_REGNUM)
1148                    (compare:CC (match_dup 1) (match_dup 2)))
1149               (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1150    (set (match_dup 3) (minus:SI (minus:SI (match_dup 1) (match_dup 1))
1151                                (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1152   {
1153        operands[3] = gen_highpart (SImode, operands[0]);
1154        operands[0] = gen_lowpart (SImode, operands[0]);
1155   }
1156   [(set_attr "conds" "clob")
1157    (set_attr "length" "8")
1158    (set_attr "type" "multiple")]
1161 (define_expand "subsi3"
1162   [(set (match_operand:SI           0 "s_register_operand" "")
1163         (minus:SI (match_operand:SI 1 "reg_or_int_operand" "")
1164                   (match_operand:SI 2 "s_register_operand" "")))]
1165   "TARGET_EITHER"
1166   "
1167   if (CONST_INT_P (operands[1]))
1168     {
1169       if (TARGET_32BIT)
1170         {
1171           if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[1]), MINUS))
1172             operands[1] = force_reg (SImode, operands[1]);
1173           else
1174             {
1175               arm_split_constant (MINUS, SImode, NULL_RTX,
1176                                   INTVAL (operands[1]), operands[0],
1177                                   operands[2],
1178                                   optimize && can_create_pseudo_p ());
1179               DONE;
1180             }
1181         }
1182       else /* TARGET_THUMB1 */
1183         operands[1] = force_reg (SImode, operands[1]);
1184     }
1185   "
1188 ; ??? Check Thumb-2 split length
1189 (define_insn_and_split "*arm_subsi3_insn"
1190   [(set (match_operand:SI           0 "s_register_operand" "=l,l ,l ,l ,r,r,r,rk,r")
1191         (minus:SI (match_operand:SI 1 "reg_or_int_operand" "l ,0 ,l ,Pz,I,r,r,k ,?n")
1192                   (match_operand:SI 2 "reg_or_int_operand" "l ,Py,Pd,l ,r,I,r,r ,r")))]
1193   "TARGET_32BIT"
1194   "@
1195    sub%?\\t%0, %1, %2
1196    sub%?\\t%0, %2
1197    sub%?\\t%0, %1, %2
1198    rsb%?\\t%0, %2, %1
1199    rsb%?\\t%0, %2, %1
1200    sub%?\\t%0, %1, %2
1201    sub%?\\t%0, %1, %2
1202    sub%?\\t%0, %1, %2
1203    #"
1204   "&& (CONST_INT_P (operands[1])
1205        && !const_ok_for_arm (INTVAL (operands[1])))"
1206   [(clobber (const_int 0))]
1207   "
1208   arm_split_constant (MINUS, SImode, curr_insn,
1209                       INTVAL (operands[1]), operands[0], operands[2], 0);
1210   DONE;
1211   "
1212   [(set_attr "length" "4,4,4,4,4,4,4,4,16")
1213    (set_attr "arch" "t2,t2,t2,t2,*,*,*,*,*")
1214    (set_attr "predicable" "yes")
1215    (set_attr "predicable_short_it" "yes,yes,yes,yes,no,no,no,no,no")
1216    (set_attr "type" "alu_sreg,alu_sreg,alu_sreg,alu_sreg,alu_imm,alu_imm,alu_sreg,alu_sreg,multiple")]
1219 (define_peephole2
1220   [(match_scratch:SI 3 "r")
1221    (set (match_operand:SI 0 "arm_general_register_operand" "")
1222         (minus:SI (match_operand:SI 1 "const_int_operand" "")
1223                   (match_operand:SI 2 "arm_general_register_operand" "")))]
1224   "TARGET_32BIT
1225    && !const_ok_for_arm (INTVAL (operands[1]))
1226    && const_ok_for_arm (~INTVAL (operands[1]))"
1227   [(set (match_dup 3) (match_dup 1))
1228    (set (match_dup 0) (minus:SI (match_dup 3) (match_dup 2)))]
1229   ""
1232 (define_insn "subsi3_compare0"
1233   [(set (reg:CC_NOOV CC_REGNUM)
1234         (compare:CC_NOOV
1235          (minus:SI (match_operand:SI 1 "arm_rhs_operand" "r,r,I")
1236                    (match_operand:SI 2 "arm_rhs_operand" "I,r,r"))
1237          (const_int 0)))
1238    (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
1239         (minus:SI (match_dup 1) (match_dup 2)))]
1240   "TARGET_32BIT"
1241   "@
1242    sub%.\\t%0, %1, %2
1243    sub%.\\t%0, %1, %2
1244    rsb%.\\t%0, %2, %1"
1245   [(set_attr "conds" "set")
1246    (set_attr "type"  "alus_imm,alus_sreg,alus_sreg")]
1249 (define_insn "subsi3_compare"
1250   [(set (reg:CC CC_REGNUM)
1251         (compare:CC (match_operand:SI 1 "arm_rhs_operand" "r,r,I")
1252                     (match_operand:SI 2 "arm_rhs_operand" "I,r,r")))
1253    (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
1254         (minus:SI (match_dup 1) (match_dup 2)))]
1255   "TARGET_32BIT"
1256   "@
1257    sub%.\\t%0, %1, %2
1258    sub%.\\t%0, %1, %2
1259    rsb%.\\t%0, %2, %1"
1260   [(set_attr "conds" "set")
1261    (set_attr "type" "alus_imm,alus_sreg,alus_sreg")]
1264 (define_expand "subsf3"
1265   [(set (match_operand:SF           0 "s_register_operand" "")
1266         (minus:SF (match_operand:SF 1 "s_register_operand" "")
1267                   (match_operand:SF 2 "s_register_operand" "")))]
1268   "TARGET_32BIT && TARGET_HARD_FLOAT"
1269   "
1272 (define_expand "subdf3"
1273   [(set (match_operand:DF           0 "s_register_operand" "")
1274         (minus:DF (match_operand:DF 1 "s_register_operand" "")
1275                   (match_operand:DF 2 "s_register_operand" "")))]
1276   "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
1277   "
1281 ;; Multiplication insns
1283 (define_expand "mulhi3"
1284   [(set (match_operand:HI 0 "s_register_operand" "")
1285         (mult:HI (match_operand:HI 1 "s_register_operand" "")
1286                  (match_operand:HI 2 "s_register_operand" "")))]
1287   "TARGET_DSP_MULTIPLY"
1288   "
1289   {
1290     rtx result = gen_reg_rtx (SImode);
1291     emit_insn (gen_mulhisi3 (result, operands[1], operands[2]));
1292     emit_move_insn (operands[0], gen_lowpart (HImode, result));
1293     DONE;
1294   }"
1297 (define_expand "mulsi3"
1298   [(set (match_operand:SI          0 "s_register_operand" "")
1299         (mult:SI (match_operand:SI 2 "s_register_operand" "")
1300                  (match_operand:SI 1 "s_register_operand" "")))]
1301   "TARGET_EITHER"
1302   ""
1305 ;; Use `&' and then `0' to prevent the operands 0 and 1 being the same
1306 (define_insn "*arm_mulsi3"
1307   [(set (match_operand:SI          0 "s_register_operand" "=&r,&r")
1308         (mult:SI (match_operand:SI 2 "s_register_operand" "r,r")
1309                  (match_operand:SI 1 "s_register_operand" "%0,r")))]
1310   "TARGET_32BIT && !arm_arch6"
1311   "mul%?\\t%0, %2, %1"
1312   [(set_attr "type" "mul")
1313    (set_attr "predicable" "yes")]
1316 (define_insn "*arm_mulsi3_v6"
1317   [(set (match_operand:SI          0 "s_register_operand" "=l,l,r")
1318         (mult:SI (match_operand:SI 1 "s_register_operand" "0,l,r")
1319                  (match_operand:SI 2 "s_register_operand" "l,0,r")))]
1320   "TARGET_32BIT && arm_arch6"
1321   "mul%?\\t%0, %1, %2"
1322   [(set_attr "type" "mul")
1323    (set_attr "predicable" "yes")
1324    (set_attr "arch" "t2,t2,*")
1325    (set_attr "length" "4")
1326    (set_attr "predicable_short_it" "yes,yes,no")]
1329 (define_insn "*mulsi3_compare0"
1330   [(set (reg:CC_NOOV CC_REGNUM)
1331         (compare:CC_NOOV (mult:SI
1332                           (match_operand:SI 2 "s_register_operand" "r,r")
1333                           (match_operand:SI 1 "s_register_operand" "%0,r"))
1334                          (const_int 0)))
1335    (set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1336         (mult:SI (match_dup 2) (match_dup 1)))]
1337   "TARGET_ARM && !arm_arch6"
1338   "mul%.\\t%0, %2, %1"
1339   [(set_attr "conds" "set")
1340    (set_attr "type" "muls")]
1343 (define_insn "*mulsi3_compare0_v6"
1344   [(set (reg:CC_NOOV CC_REGNUM)
1345         (compare:CC_NOOV (mult:SI
1346                           (match_operand:SI 2 "s_register_operand" "r")
1347                           (match_operand:SI 1 "s_register_operand" "r"))
1348                          (const_int 0)))
1349    (set (match_operand:SI 0 "s_register_operand" "=r")
1350         (mult:SI (match_dup 2) (match_dup 1)))]
1351   "TARGET_ARM && arm_arch6 && optimize_size"
1352   "mul%.\\t%0, %2, %1"
1353   [(set_attr "conds" "set")
1354    (set_attr "type" "muls")]
1357 (define_insn "*mulsi_compare0_scratch"
1358   [(set (reg:CC_NOOV CC_REGNUM)
1359         (compare:CC_NOOV (mult:SI
1360                           (match_operand:SI 2 "s_register_operand" "r,r")
1361                           (match_operand:SI 1 "s_register_operand" "%0,r"))
1362                          (const_int 0)))
1363    (clobber (match_scratch:SI 0 "=&r,&r"))]
1364   "TARGET_ARM && !arm_arch6"
1365   "mul%.\\t%0, %2, %1"
1366   [(set_attr "conds" "set")
1367    (set_attr "type" "muls")]
1370 (define_insn "*mulsi_compare0_scratch_v6"
1371   [(set (reg:CC_NOOV CC_REGNUM)
1372         (compare:CC_NOOV (mult:SI
1373                           (match_operand:SI 2 "s_register_operand" "r")
1374                           (match_operand:SI 1 "s_register_operand" "r"))
1375                          (const_int 0)))
1376    (clobber (match_scratch:SI 0 "=r"))]
1377   "TARGET_ARM && arm_arch6 && optimize_size"
1378   "mul%.\\t%0, %2, %1"
1379   [(set_attr "conds" "set")
1380    (set_attr "type" "muls")]
1383 ;; Unnamed templates to match MLA instruction.
1385 (define_insn "*mulsi3addsi"
1386   [(set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r,&r")
1387         (plus:SI
1388           (mult:SI (match_operand:SI 2 "s_register_operand" "r,r,r,r")
1389                    (match_operand:SI 1 "s_register_operand" "%0,r,0,r"))
1390           (match_operand:SI 3 "s_register_operand" "r,r,0,0")))]
1391   "TARGET_32BIT && !arm_arch6"
1392   "mla%?\\t%0, %2, %1, %3"
1393   [(set_attr "type" "mla")
1394    (set_attr "predicable" "yes")]
1397 (define_insn "*mulsi3addsi_v6"
1398   [(set (match_operand:SI 0 "s_register_operand" "=r")
1399         (plus:SI
1400           (mult:SI (match_operand:SI 2 "s_register_operand" "r")
1401                    (match_operand:SI 1 "s_register_operand" "r"))
1402           (match_operand:SI 3 "s_register_operand" "r")))]
1403   "TARGET_32BIT && arm_arch6"
1404   "mla%?\\t%0, %2, %1, %3"
1405   [(set_attr "type" "mla")
1406    (set_attr "predicable" "yes")
1407    (set_attr "predicable_short_it" "no")]
1410 (define_insn "*mulsi3addsi_compare0"
1411   [(set (reg:CC_NOOV CC_REGNUM)
1412         (compare:CC_NOOV
1413          (plus:SI (mult:SI
1414                    (match_operand:SI 2 "s_register_operand" "r,r,r,r")
1415                    (match_operand:SI 1 "s_register_operand" "%0,r,0,r"))
1416                   (match_operand:SI 3 "s_register_operand" "r,r,0,0"))
1417          (const_int 0)))
1418    (set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r,&r")
1419         (plus:SI (mult:SI (match_dup 2) (match_dup 1))
1420                  (match_dup 3)))]
1421   "TARGET_ARM && arm_arch6"
1422   "mla%.\\t%0, %2, %1, %3"
1423   [(set_attr "conds" "set")
1424    (set_attr "type" "mlas")]
1427 (define_insn "*mulsi3addsi_compare0_v6"
1428   [(set (reg:CC_NOOV CC_REGNUM)
1429         (compare:CC_NOOV
1430          (plus:SI (mult:SI
1431                    (match_operand:SI 2 "s_register_operand" "r")
1432                    (match_operand:SI 1 "s_register_operand" "r"))
1433                   (match_operand:SI 3 "s_register_operand" "r"))
1434          (const_int 0)))
1435    (set (match_operand:SI 0 "s_register_operand" "=r")
1436         (plus:SI (mult:SI (match_dup 2) (match_dup 1))
1437                  (match_dup 3)))]
1438   "TARGET_ARM && arm_arch6 && optimize_size"
1439   "mla%.\\t%0, %2, %1, %3"
1440   [(set_attr "conds" "set")
1441    (set_attr "type" "mlas")]
1444 (define_insn "*mulsi3addsi_compare0_scratch"
1445   [(set (reg:CC_NOOV CC_REGNUM)
1446         (compare:CC_NOOV
1447          (plus:SI (mult:SI
1448                    (match_operand:SI 2 "s_register_operand" "r,r,r,r")
1449                    (match_operand:SI 1 "s_register_operand" "%0,r,0,r"))
1450                   (match_operand:SI 3 "s_register_operand" "?r,r,0,0"))
1451          (const_int 0)))
1452    (clobber (match_scratch:SI 0 "=&r,&r,&r,&r"))]
1453   "TARGET_ARM && !arm_arch6"
1454   "mla%.\\t%0, %2, %1, %3"
1455   [(set_attr "conds" "set")
1456    (set_attr "type" "mlas")]
1459 (define_insn "*mulsi3addsi_compare0_scratch_v6"
1460   [(set (reg:CC_NOOV CC_REGNUM)
1461         (compare:CC_NOOV
1462          (plus:SI (mult:SI
1463                    (match_operand:SI 2 "s_register_operand" "r")
1464                    (match_operand:SI 1 "s_register_operand" "r"))
1465                   (match_operand:SI 3 "s_register_operand" "r"))
1466          (const_int 0)))
1467    (clobber (match_scratch:SI 0 "=r"))]
1468   "TARGET_ARM && arm_arch6 && optimize_size"
1469   "mla%.\\t%0, %2, %1, %3"
1470   [(set_attr "conds" "set")
1471    (set_attr "type" "mlas")]
1474 (define_insn "*mulsi3subsi"
1475   [(set (match_operand:SI 0 "s_register_operand" "=r")
1476         (minus:SI
1477           (match_operand:SI 3 "s_register_operand" "r")
1478           (mult:SI (match_operand:SI 2 "s_register_operand" "r")
1479                    (match_operand:SI 1 "s_register_operand" "r"))))]
1480   "TARGET_32BIT && arm_arch_thumb2"
1481   "mls%?\\t%0, %2, %1, %3"
1482   [(set_attr "type" "mla")
1483    (set_attr "predicable" "yes")
1484    (set_attr "predicable_short_it" "no")]
1487 (define_expand "maddsidi4"
1488   [(set (match_operand:DI 0 "s_register_operand" "")
1489         (plus:DI
1490          (mult:DI
1491           (sign_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1492           (sign_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1493          (match_operand:DI 3 "s_register_operand" "")))]
1494   "TARGET_32BIT && arm_arch3m"
1495   "")
1497 (define_insn "*mulsidi3adddi"
1498   [(set (match_operand:DI 0 "s_register_operand" "=&r")
1499         (plus:DI
1500          (mult:DI
1501           (sign_extend:DI (match_operand:SI 2 "s_register_operand" "%r"))
1502           (sign_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1503          (match_operand:DI 1 "s_register_operand" "0")))]
1504   "TARGET_32BIT && arm_arch3m && !arm_arch6"
1505   "smlal%?\\t%Q0, %R0, %3, %2"
1506   [(set_attr "type" "smlal")
1507    (set_attr "predicable" "yes")]
1510 (define_insn "*mulsidi3adddi_v6"
1511   [(set (match_operand:DI 0 "s_register_operand" "=r")
1512         (plus:DI
1513          (mult:DI
1514           (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r"))
1515           (sign_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1516          (match_operand:DI 1 "s_register_operand" "0")))]
1517   "TARGET_32BIT && arm_arch6"
1518   "smlal%?\\t%Q0, %R0, %3, %2"
1519   [(set_attr "type" "smlal")
1520    (set_attr "predicable" "yes")
1521    (set_attr "predicable_short_it" "no")]
1524 ;; 32x32->64 widening multiply.
1525 ;; As with mulsi3, the only difference between the v3-5 and v6+
1526 ;; versions of these patterns is the requirement that the output not
1527 ;; overlap the inputs, but that still means we have to have a named
1528 ;; expander and two different starred insns.
1530 (define_expand "mulsidi3"
1531   [(set (match_operand:DI 0 "s_register_operand" "")
1532         (mult:DI
1533          (sign_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1534          (sign_extend:DI (match_operand:SI 2 "s_register_operand" ""))))]
1535   "TARGET_32BIT && arm_arch3m"
1536   ""
1539 (define_insn "*mulsidi3_nov6"
1540   [(set (match_operand:DI 0 "s_register_operand" "=&r")
1541         (mult:DI
1542          (sign_extend:DI (match_operand:SI 1 "s_register_operand" "%r"))
1543          (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1544   "TARGET_32BIT && arm_arch3m && !arm_arch6"
1545   "smull%?\\t%Q0, %R0, %1, %2"
1546   [(set_attr "type" "smull")
1547    (set_attr "predicable" "yes")]
1550 (define_insn "*mulsidi3_v6"
1551   [(set (match_operand:DI 0 "s_register_operand" "=r")
1552         (mult:DI
1553          (sign_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1554          (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1555   "TARGET_32BIT && arm_arch6"
1556   "smull%?\\t%Q0, %R0, %1, %2"
1557   [(set_attr "type" "smull")
1558    (set_attr "predicable" "yes")
1559    (set_attr "predicable_short_it" "no")]
1562 (define_expand "umulsidi3"
1563   [(set (match_operand:DI 0 "s_register_operand" "")
1564         (mult:DI
1565          (zero_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1566          (zero_extend:DI (match_operand:SI 2 "s_register_operand" ""))))]
1567   "TARGET_32BIT && arm_arch3m"
1568   ""
1571 (define_insn "*umulsidi3_nov6"
1572   [(set (match_operand:DI 0 "s_register_operand" "=&r")
1573         (mult:DI
1574          (zero_extend:DI (match_operand:SI 1 "s_register_operand" "%r"))
1575          (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1576   "TARGET_32BIT && arm_arch3m && !arm_arch6"
1577   "umull%?\\t%Q0, %R0, %1, %2"
1578   [(set_attr "type" "umull")
1579    (set_attr "predicable" "yes")]
1582 (define_insn "*umulsidi3_v6"
1583   [(set (match_operand:DI 0 "s_register_operand" "=r")
1584         (mult:DI
1585          (zero_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1586          (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1587   "TARGET_32BIT && arm_arch6"
1588   "umull%?\\t%Q0, %R0, %1, %2"
1589   [(set_attr "type" "umull")
1590    (set_attr "predicable" "yes")
1591    (set_attr "predicable_short_it" "no")]
1594 (define_expand "umaddsidi4"
1595   [(set (match_operand:DI 0 "s_register_operand" "")
1596         (plus:DI
1597          (mult:DI
1598           (zero_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1599           (zero_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1600          (match_operand:DI 3 "s_register_operand" "")))]
1601   "TARGET_32BIT && arm_arch3m"
1602   "")
1604 (define_insn "*umulsidi3adddi"
1605   [(set (match_operand:DI 0 "s_register_operand" "=&r")
1606         (plus:DI
1607          (mult:DI
1608           (zero_extend:DI (match_operand:SI 2 "s_register_operand" "%r"))
1609           (zero_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1610          (match_operand:DI 1 "s_register_operand" "0")))]
1611   "TARGET_32BIT && arm_arch3m && !arm_arch6"
1612   "umlal%?\\t%Q0, %R0, %3, %2"
1613   [(set_attr "type" "umlal")
1614    (set_attr "predicable" "yes")]
1617 (define_insn "*umulsidi3adddi_v6"
1618   [(set (match_operand:DI 0 "s_register_operand" "=r")
1619         (plus:DI
1620          (mult:DI
1621           (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r"))
1622           (zero_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1623          (match_operand:DI 1 "s_register_operand" "0")))]
1624   "TARGET_32BIT && arm_arch6"
1625   "umlal%?\\t%Q0, %R0, %3, %2"
1626   [(set_attr "type" "umlal")
1627    (set_attr "predicable" "yes")
1628    (set_attr "predicable_short_it" "no")]
1631 (define_expand "smulsi3_highpart"
1632   [(parallel
1633     [(set (match_operand:SI 0 "s_register_operand" "")
1634           (truncate:SI
1635            (lshiftrt:DI
1636             (mult:DI
1637              (sign_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1638              (sign_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1639             (const_int 32))))
1640      (clobber (match_scratch:SI 3 ""))])]
1641   "TARGET_32BIT && arm_arch3m"
1642   ""
1645 (define_insn "*smulsi3_highpart_nov6"
1646   [(set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1647         (truncate:SI
1648          (lshiftrt:DI
1649           (mult:DI
1650            (sign_extend:DI (match_operand:SI 1 "s_register_operand" "%0,r"))
1651            (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r,r")))
1652           (const_int 32))))
1653    (clobber (match_scratch:SI 3 "=&r,&r"))]
1654   "TARGET_32BIT && arm_arch3m && !arm_arch6"
1655   "smull%?\\t%3, %0, %2, %1"
1656   [(set_attr "type" "smull")
1657    (set_attr "predicable" "yes")]
1660 (define_insn "*smulsi3_highpart_v6"
1661   [(set (match_operand:SI 0 "s_register_operand" "=r")
1662         (truncate:SI
1663          (lshiftrt:DI
1664           (mult:DI
1665            (sign_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1666            (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r")))
1667           (const_int 32))))
1668    (clobber (match_scratch:SI 3 "=r"))]
1669   "TARGET_32BIT && arm_arch6"
1670   "smull%?\\t%3, %0, %2, %1"
1671   [(set_attr "type" "smull")
1672    (set_attr "predicable" "yes")
1673    (set_attr "predicable_short_it" "no")]
1676 (define_expand "umulsi3_highpart"
1677   [(parallel
1678     [(set (match_operand:SI 0 "s_register_operand" "")
1679           (truncate:SI
1680            (lshiftrt:DI
1681             (mult:DI
1682              (zero_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1683               (zero_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1684             (const_int 32))))
1685      (clobber (match_scratch:SI 3 ""))])]
1686   "TARGET_32BIT && arm_arch3m"
1687   ""
1690 (define_insn "*umulsi3_highpart_nov6"
1691   [(set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1692         (truncate:SI
1693          (lshiftrt:DI
1694           (mult:DI
1695            (zero_extend:DI (match_operand:SI 1 "s_register_operand" "%0,r"))
1696            (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r,r")))
1697           (const_int 32))))
1698    (clobber (match_scratch:SI 3 "=&r,&r"))]
1699   "TARGET_32BIT && arm_arch3m && !arm_arch6"
1700   "umull%?\\t%3, %0, %2, %1"
1701   [(set_attr "type" "umull")
1702    (set_attr "predicable" "yes")]
1705 (define_insn "*umulsi3_highpart_v6"
1706   [(set (match_operand:SI 0 "s_register_operand" "=r")
1707         (truncate:SI
1708          (lshiftrt:DI
1709           (mult:DI
1710            (zero_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1711            (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r")))
1712           (const_int 32))))
1713    (clobber (match_scratch:SI 3 "=r"))]
1714   "TARGET_32BIT && arm_arch6"
1715   "umull%?\\t%3, %0, %2, %1"
1716   [(set_attr "type" "umull")
1717    (set_attr "predicable" "yes")
1718    (set_attr "predicable_short_it" "no")]
1721 (define_insn "mulhisi3"
1722   [(set (match_operand:SI 0 "s_register_operand" "=r")
1723         (mult:SI (sign_extend:SI
1724                   (match_operand:HI 1 "s_register_operand" "%r"))
1725                  (sign_extend:SI
1726                   (match_operand:HI 2 "s_register_operand" "r"))))]
1727   "TARGET_DSP_MULTIPLY"
1728   "smulbb%?\\t%0, %1, %2"
1729   [(set_attr "type" "smulxy")
1730    (set_attr "predicable" "yes")]
1733 (define_insn "*mulhisi3tb"
1734   [(set (match_operand:SI 0 "s_register_operand" "=r")
1735         (mult:SI (ashiftrt:SI
1736                   (match_operand:SI 1 "s_register_operand" "r")
1737                   (const_int 16))
1738                  (sign_extend:SI
1739                   (match_operand:HI 2 "s_register_operand" "r"))))]
1740   "TARGET_DSP_MULTIPLY"
1741   "smultb%?\\t%0, %1, %2"
1742   [(set_attr "type" "smulxy")
1743    (set_attr "predicable" "yes")
1744    (set_attr "predicable_short_it" "no")]
1747 (define_insn "*mulhisi3bt"
1748   [(set (match_operand:SI 0 "s_register_operand" "=r")
1749         (mult:SI (sign_extend:SI
1750                   (match_operand:HI 1 "s_register_operand" "r"))
1751                  (ashiftrt:SI
1752                   (match_operand:SI 2 "s_register_operand" "r")
1753                   (const_int 16))))]
1754   "TARGET_DSP_MULTIPLY"
1755   "smulbt%?\\t%0, %1, %2"
1756   [(set_attr "type" "smulxy")
1757    (set_attr "predicable" "yes")
1758    (set_attr "predicable_short_it" "no")]
1761 (define_insn "*mulhisi3tt"
1762   [(set (match_operand:SI 0 "s_register_operand" "=r")
1763         (mult:SI (ashiftrt:SI
1764                   (match_operand:SI 1 "s_register_operand" "r")
1765                   (const_int 16))
1766                  (ashiftrt:SI
1767                   (match_operand:SI 2 "s_register_operand" "r")
1768                   (const_int 16))))]
1769   "TARGET_DSP_MULTIPLY"
1770   "smultt%?\\t%0, %1, %2"
1771   [(set_attr "type" "smulxy")
1772    (set_attr "predicable" "yes")
1773    (set_attr "predicable_short_it" "no")]
1776 (define_insn "maddhisi4"
1777   [(set (match_operand:SI 0 "s_register_operand" "=r")
1778         (plus:SI (mult:SI (sign_extend:SI
1779                            (match_operand:HI 1 "s_register_operand" "r"))
1780                           (sign_extend:SI
1781                            (match_operand:HI 2 "s_register_operand" "r")))
1782                  (match_operand:SI 3 "s_register_operand" "r")))]
1783   "TARGET_DSP_MULTIPLY"
1784   "smlabb%?\\t%0, %1, %2, %3"
1785   [(set_attr "type" "smlaxy")
1786    (set_attr "predicable" "yes")
1787    (set_attr "predicable_short_it" "no")]
1790 ;; Note: there is no maddhisi4ibt because this one is canonical form
1791 (define_insn "*maddhisi4tb"
1792   [(set (match_operand:SI 0 "s_register_operand" "=r")
1793         (plus:SI (mult:SI (ashiftrt:SI
1794                            (match_operand:SI 1 "s_register_operand" "r")
1795                            (const_int 16))
1796                           (sign_extend:SI
1797                            (match_operand:HI 2 "s_register_operand" "r")))
1798                  (match_operand:SI 3 "s_register_operand" "r")))]
1799   "TARGET_DSP_MULTIPLY"
1800   "smlatb%?\\t%0, %1, %2, %3"
1801   [(set_attr "type" "smlaxy")
1802    (set_attr "predicable" "yes")
1803    (set_attr "predicable_short_it" "no")]
1806 (define_insn "*maddhisi4tt"
1807   [(set (match_operand:SI 0 "s_register_operand" "=r")
1808         (plus:SI (mult:SI (ashiftrt:SI
1809                            (match_operand:SI 1 "s_register_operand" "r")
1810                            (const_int 16))
1811                           (ashiftrt:SI
1812                            (match_operand:SI 2 "s_register_operand" "r")
1813                            (const_int 16)))
1814                  (match_operand:SI 3 "s_register_operand" "r")))]
1815   "TARGET_DSP_MULTIPLY"
1816   "smlatt%?\\t%0, %1, %2, %3"
1817   [(set_attr "type" "smlaxy")
1818    (set_attr "predicable" "yes")
1819    (set_attr "predicable_short_it" "no")]
1822 (define_insn "maddhidi4"
1823   [(set (match_operand:DI 0 "s_register_operand" "=r")
1824         (plus:DI
1825           (mult:DI (sign_extend:DI
1826                     (match_operand:HI 1 "s_register_operand" "r"))
1827                    (sign_extend:DI
1828                     (match_operand:HI 2 "s_register_operand" "r")))
1829           (match_operand:DI 3 "s_register_operand" "0")))]
1830   "TARGET_DSP_MULTIPLY"
1831   "smlalbb%?\\t%Q0, %R0, %1, %2"
1832   [(set_attr "type" "smlalxy")
1833    (set_attr "predicable" "yes")
1834    (set_attr "predicable_short_it" "no")])
1836 ;; Note: there is no maddhidi4ibt because this one is canonical form
1837 (define_insn "*maddhidi4tb"
1838   [(set (match_operand:DI 0 "s_register_operand" "=r")
1839         (plus:DI
1840           (mult:DI (sign_extend:DI
1841                     (ashiftrt:SI
1842                      (match_operand:SI 1 "s_register_operand" "r")
1843                      (const_int 16)))
1844                    (sign_extend:DI
1845                     (match_operand:HI 2 "s_register_operand" "r")))
1846           (match_operand:DI 3 "s_register_operand" "0")))]
1847   "TARGET_DSP_MULTIPLY"
1848   "smlaltb%?\\t%Q0, %R0, %1, %2"
1849   [(set_attr "type" "smlalxy")
1850    (set_attr "predicable" "yes")
1851    (set_attr "predicable_short_it" "no")])
1853 (define_insn "*maddhidi4tt"
1854   [(set (match_operand:DI 0 "s_register_operand" "=r")
1855         (plus:DI
1856           (mult:DI (sign_extend:DI
1857                     (ashiftrt:SI
1858                      (match_operand:SI 1 "s_register_operand" "r")
1859                      (const_int 16)))
1860                    (sign_extend:DI
1861                     (ashiftrt:SI
1862                      (match_operand:SI 2 "s_register_operand" "r")
1863                      (const_int 16))))
1864           (match_operand:DI 3 "s_register_operand" "0")))]
1865   "TARGET_DSP_MULTIPLY"
1866   "smlaltt%?\\t%Q0, %R0, %1, %2"
1867   [(set_attr "type" "smlalxy")
1868    (set_attr "predicable" "yes")
1869    (set_attr "predicable_short_it" "no")])
1871 (define_expand "mulsf3"
1872   [(set (match_operand:SF          0 "s_register_operand" "")
1873         (mult:SF (match_operand:SF 1 "s_register_operand" "")
1874                  (match_operand:SF 2 "s_register_operand" "")))]
1875   "TARGET_32BIT && TARGET_HARD_FLOAT"
1876   "
1879 (define_expand "muldf3"
1880   [(set (match_operand:DF          0 "s_register_operand" "")
1881         (mult:DF (match_operand:DF 1 "s_register_operand" "")
1882                  (match_operand:DF 2 "s_register_operand" "")))]
1883   "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
1884   "
1887 ;; Division insns
1889 (define_expand "divsf3"
1890   [(set (match_operand:SF 0 "s_register_operand" "")
1891         (div:SF (match_operand:SF 1 "s_register_operand" "")
1892                 (match_operand:SF 2 "s_register_operand" "")))]
1893   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
1894   "")
1896 (define_expand "divdf3"
1897   [(set (match_operand:DF 0 "s_register_operand" "")
1898         (div:DF (match_operand:DF 1 "s_register_operand" "")
1899                 (match_operand:DF 2 "s_register_operand" "")))]
1900   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
1901   "")
1903 ;; Boolean and,ior,xor insns
1905 ;; Split up double word logical operations
1907 ;; Split up simple DImode logical operations.  Simply perform the logical
1908 ;; operation on the upper and lower halves of the registers.
1909 (define_split
1910   [(set (match_operand:DI 0 "s_register_operand" "")
1911         (match_operator:DI 6 "logical_binary_operator"
1912           [(match_operand:DI 1 "s_register_operand" "")
1913            (match_operand:DI 2 "s_register_operand" "")]))]
1914   "TARGET_32BIT && reload_completed
1915    && ! (TARGET_NEON && IS_VFP_REGNUM (REGNO (operands[0])))
1916    && ! IS_IWMMXT_REGNUM (REGNO (operands[0]))"
1917   [(set (match_dup 0) (match_op_dup:SI 6 [(match_dup 1) (match_dup 2)]))
1918    (set (match_dup 3) (match_op_dup:SI 6 [(match_dup 4) (match_dup 5)]))]
1919   "
1920   {
1921     operands[3] = gen_highpart (SImode, operands[0]);
1922     operands[0] = gen_lowpart (SImode, operands[0]);
1923     operands[4] = gen_highpart (SImode, operands[1]);
1924     operands[1] = gen_lowpart (SImode, operands[1]);
1925     operands[5] = gen_highpart (SImode, operands[2]);
1926     operands[2] = gen_lowpart (SImode, operands[2]);
1927   }"
1930 (define_split
1931   [(set (match_operand:DI 0 "s_register_operand" "")
1932         (match_operator:DI 6 "logical_binary_operator"
1933           [(sign_extend:DI (match_operand:SI 2 "s_register_operand" ""))
1934            (match_operand:DI 1 "s_register_operand" "")]))]
1935   "TARGET_32BIT && reload_completed"
1936   [(set (match_dup 0) (match_op_dup:SI 6 [(match_dup 1) (match_dup 2)]))
1937    (set (match_dup 3) (match_op_dup:SI 6
1938                         [(ashiftrt:SI (match_dup 2) (const_int 31))
1939                          (match_dup 4)]))]
1940   "
1941   {
1942     operands[3] = gen_highpart (SImode, operands[0]);
1943     operands[0] = gen_lowpart (SImode, operands[0]);
1944     operands[4] = gen_highpart (SImode, operands[1]);
1945     operands[1] = gen_lowpart (SImode, operands[1]);
1946     operands[5] = gen_highpart (SImode, operands[2]);
1947     operands[2] = gen_lowpart (SImode, operands[2]);
1948   }"
1951 ;; The zero extend of operand 2 means we can just copy the high part of
1952 ;; operand1 into operand0.
1953 (define_split
1954   [(set (match_operand:DI 0 "s_register_operand" "")
1955         (ior:DI
1956           (zero_extend:DI (match_operand:SI 2 "s_register_operand" ""))
1957           (match_operand:DI 1 "s_register_operand" "")))]
1958   "TARGET_32BIT && operands[0] != operands[1] && reload_completed"
1959   [(set (match_dup 0) (ior:SI (match_dup 1) (match_dup 2)))
1960    (set (match_dup 3) (match_dup 4))]
1961   "
1962   {
1963     operands[4] = gen_highpart (SImode, operands[1]);
1964     operands[3] = gen_highpart (SImode, operands[0]);
1965     operands[0] = gen_lowpart (SImode, operands[0]);
1966     operands[1] = gen_lowpart (SImode, operands[1]);
1967   }"
1970 ;; The zero extend of operand 2 means we can just copy the high part of
1971 ;; operand1 into operand0.
1972 (define_split
1973   [(set (match_operand:DI 0 "s_register_operand" "")
1974         (xor:DI
1975           (zero_extend:DI (match_operand:SI 2 "s_register_operand" ""))
1976           (match_operand:DI 1 "s_register_operand" "")))]
1977   "TARGET_32BIT && operands[0] != operands[1] && reload_completed"
1978   [(set (match_dup 0) (xor:SI (match_dup 1) (match_dup 2)))
1979    (set (match_dup 3) (match_dup 4))]
1980   "
1981   {
1982     operands[4] = gen_highpart (SImode, operands[1]);
1983     operands[3] = gen_highpart (SImode, operands[0]);
1984     operands[0] = gen_lowpart (SImode, operands[0]);
1985     operands[1] = gen_lowpart (SImode, operands[1]);
1986   }"
1989 (define_expand "anddi3"
1990   [(set (match_operand:DI         0 "s_register_operand" "")
1991         (and:DI (match_operand:DI 1 "s_register_operand" "")
1992                 (match_operand:DI 2 "neon_inv_logic_op2" "")))]
1993   "TARGET_32BIT"
1994   ""
1997 (define_insn_and_split "*anddi3_insn"
1998   [(set (match_operand:DI         0 "s_register_operand"     "=w,w ,&r,&r,&r,&r,?w,?w")
1999         (and:DI (match_operand:DI 1 "s_register_operand"     "%w,0 ,0 ,r ,0 ,r ,w ,0")
2000                 (match_operand:DI 2 "arm_anddi_operand_neon" "w ,DL,r ,r ,De,De,w ,DL")))]
2001   "TARGET_32BIT && !TARGET_IWMMXT"
2003   switch (which_alternative)
2004     {
2005     case 0: /* fall through */
2006     case 6: return "vand\t%P0, %P1, %P2";
2007     case 1: /* fall through */
2008     case 7: return neon_output_logic_immediate ("vand", &operands[2],
2009                     DImode, 1, VALID_NEON_QREG_MODE (DImode));
2010     case 2:
2011     case 3:
2012     case 4:
2013     case 5: /* fall through */
2014       return "#";
2015     default: gcc_unreachable ();
2016     }
2018   "TARGET_32BIT && !TARGET_IWMMXT && reload_completed
2019    && !(IS_VFP_REGNUM (REGNO (operands[0])))"
2020   [(set (match_dup 3) (match_dup 4))
2021    (set (match_dup 5) (match_dup 6))]
2022   "
2023   {
2024     operands[3] = gen_lowpart (SImode, operands[0]);
2025     operands[5] = gen_highpart (SImode, operands[0]);
2027     operands[4] = simplify_gen_binary (AND, SImode,
2028                                            gen_lowpart (SImode, operands[1]),
2029                                            gen_lowpart (SImode, operands[2]));
2030     operands[6] = simplify_gen_binary (AND, SImode,
2031                                            gen_highpart (SImode, operands[1]),
2032                                            gen_highpart_mode (SImode, DImode, operands[2]));
2034   }"
2035   [(set_attr "type" "neon_logic,neon_logic,multiple,multiple,\
2036                      multiple,multiple,neon_logic,neon_logic")
2037    (set_attr "arch" "neon_for_64bits,neon_for_64bits,*,*,*,*,
2038                      avoid_neon_for_64bits,avoid_neon_for_64bits")
2039    (set_attr "length" "*,*,8,8,8,8,*,*")
2040   ]
2043 (define_insn_and_split "*anddi_zesidi_di"
2044   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2045         (and:DI (zero_extend:DI
2046                  (match_operand:SI 2 "s_register_operand" "r,r"))
2047                 (match_operand:DI 1 "s_register_operand" "0,r")))]
2048   "TARGET_32BIT"
2049   "#"
2050   "TARGET_32BIT && reload_completed"
2051   ; The zero extend of operand 2 clears the high word of the output
2052   ; operand.
2053   [(set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))
2054    (set (match_dup 3) (const_int 0))]
2055   "
2056   {
2057     operands[3] = gen_highpart (SImode, operands[0]);
2058     operands[0] = gen_lowpart (SImode, operands[0]);
2059     operands[1] = gen_lowpart (SImode, operands[1]);
2060   }"
2061   [(set_attr "length" "8")
2062    (set_attr "type" "multiple")]
2065 (define_insn "*anddi_sesdi_di"
2066   [(set (match_operand:DI          0 "s_register_operand" "=&r,&r")
2067         (and:DI (sign_extend:DI
2068                  (match_operand:SI 2 "s_register_operand" "r,r"))
2069                 (match_operand:DI  1 "s_register_operand" "0,r")))]
2070   "TARGET_32BIT"
2071   "#"
2072   [(set_attr "length" "8")
2073    (set_attr "type" "multiple")]
2076 (define_expand "andsi3"
2077   [(set (match_operand:SI         0 "s_register_operand" "")
2078         (and:SI (match_operand:SI 1 "s_register_operand" "")
2079                 (match_operand:SI 2 "reg_or_int_operand" "")))]
2080   "TARGET_EITHER"
2081   "
2082   if (TARGET_32BIT)
2083     {
2084       if (CONST_INT_P (operands[2]))
2085         {
2086           if (INTVAL (operands[2]) == 255 && arm_arch6)
2087             {
2088               operands[1] = convert_to_mode (QImode, operands[1], 1);
2089               emit_insn (gen_thumb2_zero_extendqisi2_v6 (operands[0],
2090                                                          operands[1]));
2091               DONE;
2092             }
2093           else if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[2]), AND))
2094             operands[2] = force_reg (SImode, operands[2]);
2095           else
2096             {
2097               arm_split_constant (AND, SImode, NULL_RTX,
2098                                   INTVAL (operands[2]), operands[0],
2099                                   operands[1],
2100                                   optimize && can_create_pseudo_p ());
2102               DONE;
2103             }
2104         }
2105     }
2106   else /* TARGET_THUMB1 */
2107     {
2108       if (!CONST_INT_P (operands[2]))
2109         {
2110           rtx tmp = force_reg (SImode, operands[2]);
2111           if (rtx_equal_p (operands[0], operands[1]))
2112             operands[2] = tmp;
2113           else
2114             {
2115               operands[2] = operands[1];
2116               operands[1] = tmp;
2117             }
2118         }
2119       else
2120         {
2121           int i;
2122           
2123           if (((unsigned HOST_WIDE_INT) ~INTVAL (operands[2])) < 256)
2124             {
2125               operands[2] = force_reg (SImode,
2126                                        GEN_INT (~INTVAL (operands[2])));
2127               
2128               emit_insn (gen_thumb1_bicsi3 (operands[0], operands[2], operands[1]));
2129               
2130               DONE;
2131             }
2133           for (i = 9; i <= 31; i++)
2134             {
2135               if ((((HOST_WIDE_INT) 1) << i) - 1 == INTVAL (operands[2]))
2136                 {
2137                   emit_insn (gen_extzv (operands[0], operands[1], GEN_INT (i),
2138                                         const0_rtx));
2139                   DONE;
2140                 }
2141               else if ((((HOST_WIDE_INT) 1) << i) - 1
2142                        == ~INTVAL (operands[2]))
2143                 {
2144                   rtx shift = GEN_INT (i);
2145                   rtx reg = gen_reg_rtx (SImode);
2146                 
2147                   emit_insn (gen_lshrsi3 (reg, operands[1], shift));
2148                   emit_insn (gen_ashlsi3 (operands[0], reg, shift));
2149                   
2150                   DONE;
2151                 }
2152             }
2154           operands[2] = force_reg (SImode, operands[2]);
2155         }
2156     }
2157   "
2160 ; ??? Check split length for Thumb-2
2161 (define_insn_and_split "*arm_andsi3_insn"
2162   [(set (match_operand:SI         0 "s_register_operand" "=r,l,r,r,r")
2163         (and:SI (match_operand:SI 1 "s_register_operand" "%r,0,r,r,r")
2164                 (match_operand:SI 2 "reg_or_int_operand" "I,l,K,r,?n")))]
2165   "TARGET_32BIT"
2166   "@
2167    and%?\\t%0, %1, %2
2168    and%?\\t%0, %1, %2
2169    bic%?\\t%0, %1, #%B2
2170    and%?\\t%0, %1, %2
2171    #"
2172   "TARGET_32BIT
2173    && CONST_INT_P (operands[2])
2174    && !(const_ok_for_arm (INTVAL (operands[2]))
2175         || const_ok_for_arm (~INTVAL (operands[2])))"
2176   [(clobber (const_int 0))]
2177   "
2178   arm_split_constant  (AND, SImode, curr_insn, 
2179                        INTVAL (operands[2]), operands[0], operands[1], 0);
2180   DONE;
2181   "
2182   [(set_attr "length" "4,4,4,4,16")
2183    (set_attr "predicable" "yes")
2184    (set_attr "predicable_short_it" "no,yes,no,no,no")
2185    (set_attr "type" "logic_imm,logic_imm,logic_reg,logic_reg,logic_imm")]
2188 (define_insn "*andsi3_compare0"
2189   [(set (reg:CC_NOOV CC_REGNUM)
2190         (compare:CC_NOOV
2191          (and:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
2192                  (match_operand:SI 2 "arm_not_operand" "I,K,r"))
2193          (const_int 0)))
2194    (set (match_operand:SI          0 "s_register_operand" "=r,r,r")
2195         (and:SI (match_dup 1) (match_dup 2)))]
2196   "TARGET_32BIT"
2197   "@
2198    and%.\\t%0, %1, %2
2199    bic%.\\t%0, %1, #%B2
2200    and%.\\t%0, %1, %2"
2201   [(set_attr "conds" "set")
2202    (set_attr "type" "logics_imm,logics_imm,logics_reg")]
2205 (define_insn "*andsi3_compare0_scratch"
2206   [(set (reg:CC_NOOV CC_REGNUM)
2207         (compare:CC_NOOV
2208          (and:SI (match_operand:SI 0 "s_register_operand" "r,r,r")
2209                  (match_operand:SI 1 "arm_not_operand" "I,K,r"))
2210          (const_int 0)))
2211    (clobber (match_scratch:SI 2 "=X,r,X"))]
2212   "TARGET_32BIT"
2213   "@
2214    tst%?\\t%0, %1
2215    bic%.\\t%2, %0, #%B1
2216    tst%?\\t%0, %1"
2217   [(set_attr "conds" "set")
2218    (set_attr "type"  "logics_imm,logics_imm,logics_reg")]
2221 (define_insn "*zeroextractsi_compare0_scratch"
2222   [(set (reg:CC_NOOV CC_REGNUM)
2223         (compare:CC_NOOV (zero_extract:SI
2224                           (match_operand:SI 0 "s_register_operand" "r")
2225                           (match_operand 1 "const_int_operand" "n")
2226                           (match_operand 2 "const_int_operand" "n"))
2227                          (const_int 0)))]
2228   "TARGET_32BIT
2229   && (INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) < 32
2230       && INTVAL (operands[1]) > 0 
2231       && INTVAL (operands[1]) + (INTVAL (operands[2]) & 1) <= 8
2232       && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32)"
2233   "*
2234   operands[1] = GEN_INT (((1 << INTVAL (operands[1])) - 1)
2235                          << INTVAL (operands[2]));
2236   output_asm_insn (\"tst%?\\t%0, %1\", operands);
2237   return \"\";
2238   "
2239   [(set_attr "conds" "set")
2240    (set_attr "predicable" "yes")
2241    (set_attr "predicable_short_it" "no")
2242    (set_attr "type" "logics_imm")]
2245 (define_insn_and_split "*ne_zeroextractsi"
2246   [(set (match_operand:SI 0 "s_register_operand" "=r")
2247         (ne:SI (zero_extract:SI
2248                 (match_operand:SI 1 "s_register_operand" "r")
2249                 (match_operand:SI 2 "const_int_operand" "n")
2250                 (match_operand:SI 3 "const_int_operand" "n"))
2251                (const_int 0)))
2252    (clobber (reg:CC CC_REGNUM))]
2253   "TARGET_32BIT
2254    && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2255        && INTVAL (operands[2]) > 0 
2256        && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2257        && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)"
2258   "#"
2259   "TARGET_32BIT
2260    && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2261        && INTVAL (operands[2]) > 0 
2262        && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2263        && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)"
2264   [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2265                    (compare:CC_NOOV (and:SI (match_dup 1) (match_dup 2))
2266                                     (const_int 0)))
2267               (set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))])
2268    (set (match_dup 0)
2269         (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2270                          (match_dup 0) (const_int 1)))]
2271   "
2272   operands[2] = GEN_INT (((1 << INTVAL (operands[2])) - 1)
2273                          << INTVAL (operands[3])); 
2274   "
2275   [(set_attr "conds" "clob")
2276    (set (attr "length")
2277         (if_then_else (eq_attr "is_thumb" "yes")
2278                       (const_int 12)
2279                       (const_int 8)))
2280    (set_attr "type" "multiple")]
2283 (define_insn_and_split "*ne_zeroextractsi_shifted"
2284   [(set (match_operand:SI 0 "s_register_operand" "=r")
2285         (ne:SI (zero_extract:SI
2286                 (match_operand:SI 1 "s_register_operand" "r")
2287                 (match_operand:SI 2 "const_int_operand" "n")
2288                 (const_int 0))
2289                (const_int 0)))
2290    (clobber (reg:CC CC_REGNUM))]
2291   "TARGET_ARM"
2292   "#"
2293   "TARGET_ARM"
2294   [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2295                    (compare:CC_NOOV (ashift:SI (match_dup 1) (match_dup 2))
2296                                     (const_int 0)))
2297               (set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))])
2298    (set (match_dup 0)
2299         (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2300                          (match_dup 0) (const_int 1)))]
2301   "
2302   operands[2] = GEN_INT (32 - INTVAL (operands[2]));
2303   "
2304   [(set_attr "conds" "clob")
2305    (set_attr "length" "8")
2306    (set_attr "type" "multiple")]
2309 (define_insn_and_split "*ite_ne_zeroextractsi"
2310   [(set (match_operand:SI 0 "s_register_operand" "=r")
2311         (if_then_else:SI (ne (zero_extract:SI
2312                               (match_operand:SI 1 "s_register_operand" "r")
2313                               (match_operand:SI 2 "const_int_operand" "n")
2314                               (match_operand:SI 3 "const_int_operand" "n"))
2315                              (const_int 0))
2316                          (match_operand:SI 4 "arm_not_operand" "rIK")
2317                          (const_int 0)))
2318    (clobber (reg:CC CC_REGNUM))]
2319   "TARGET_ARM
2320    && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2321        && INTVAL (operands[2]) > 0 
2322        && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2323        && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)
2324    && !reg_overlap_mentioned_p (operands[0], operands[4])"
2325   "#"
2326   "TARGET_ARM
2327    && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2328        && INTVAL (operands[2]) > 0 
2329        && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2330        && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)
2331    && !reg_overlap_mentioned_p (operands[0], operands[4])"
2332   [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2333                    (compare:CC_NOOV (and:SI (match_dup 1) (match_dup 2))
2334                                     (const_int 0)))
2335               (set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))])
2336    (set (match_dup 0)
2337         (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2338                          (match_dup 0) (match_dup 4)))]
2339   "
2340   operands[2] = GEN_INT (((1 << INTVAL (operands[2])) - 1)
2341                          << INTVAL (operands[3])); 
2342   "
2343   [(set_attr "conds" "clob")
2344    (set_attr "length" "8")
2345    (set_attr "type" "multiple")]
2348 (define_insn_and_split "*ite_ne_zeroextractsi_shifted"
2349   [(set (match_operand:SI 0 "s_register_operand" "=r")
2350         (if_then_else:SI (ne (zero_extract:SI
2351                               (match_operand:SI 1 "s_register_operand" "r")
2352                               (match_operand:SI 2 "const_int_operand" "n")
2353                               (const_int 0))
2354                              (const_int 0))
2355                          (match_operand:SI 3 "arm_not_operand" "rIK")
2356                          (const_int 0)))
2357    (clobber (reg:CC CC_REGNUM))]
2358   "TARGET_ARM && !reg_overlap_mentioned_p (operands[0], operands[3])"
2359   "#"
2360   "TARGET_ARM && !reg_overlap_mentioned_p (operands[0], operands[3])"
2361   [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2362                    (compare:CC_NOOV (ashift:SI (match_dup 1) (match_dup 2))
2363                                     (const_int 0)))
2364               (set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))])
2365    (set (match_dup 0)
2366         (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2367                          (match_dup 0) (match_dup 3)))]
2368   "
2369   operands[2] = GEN_INT (32 - INTVAL (operands[2]));
2370   "
2371   [(set_attr "conds" "clob")
2372    (set_attr "length" "8")
2373    (set_attr "type" "multiple")]
2376 ;; ??? Use Thumb-2 has bitfield insert/extract instructions.
2377 (define_split
2378   [(set (match_operand:SI 0 "s_register_operand" "")
2379         (match_operator:SI 1 "shiftable_operator"
2380          [(zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
2381                            (match_operand:SI 3 "const_int_operand" "")
2382                            (match_operand:SI 4 "const_int_operand" ""))
2383           (match_operand:SI 5 "s_register_operand" "")]))
2384    (clobber (match_operand:SI 6 "s_register_operand" ""))]
2385   "TARGET_ARM"
2386   [(set (match_dup 6) (ashift:SI (match_dup 2) (match_dup 3)))
2387    (set (match_dup 0)
2388         (match_op_dup 1
2389          [(lshiftrt:SI (match_dup 6) (match_dup 4))
2390           (match_dup 5)]))]
2391   "{
2392      HOST_WIDE_INT temp = INTVAL (operands[3]);
2394      operands[3] = GEN_INT (32 - temp - INTVAL (operands[4]));
2395      operands[4] = GEN_INT (32 - temp);
2396    }"
2398   
2399 (define_split
2400   [(set (match_operand:SI 0 "s_register_operand" "")
2401         (match_operator:SI 1 "shiftable_operator"
2402          [(sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
2403                            (match_operand:SI 3 "const_int_operand" "")
2404                            (match_operand:SI 4 "const_int_operand" ""))
2405           (match_operand:SI 5 "s_register_operand" "")]))
2406    (clobber (match_operand:SI 6 "s_register_operand" ""))]
2407   "TARGET_ARM"
2408   [(set (match_dup 6) (ashift:SI (match_dup 2) (match_dup 3)))
2409    (set (match_dup 0)
2410         (match_op_dup 1
2411          [(ashiftrt:SI (match_dup 6) (match_dup 4))
2412           (match_dup 5)]))]
2413   "{
2414      HOST_WIDE_INT temp = INTVAL (operands[3]);
2416      operands[3] = GEN_INT (32 - temp - INTVAL (operands[4]));
2417      operands[4] = GEN_INT (32 - temp);
2418    }"
2420   
2421 ;;; ??? This pattern is bogus.  If operand3 has bits outside the range
2422 ;;; represented by the bitfield, then this will produce incorrect results.
2423 ;;; Somewhere, the value needs to be truncated.  On targets like the m68k,
2424 ;;; which have a real bit-field insert instruction, the truncation happens
2425 ;;; in the bit-field insert instruction itself.  Since arm does not have a
2426 ;;; bit-field insert instruction, we would have to emit code here to truncate
2427 ;;; the value before we insert.  This loses some of the advantage of having
2428 ;;; this insv pattern, so this pattern needs to be reevalutated.
2430 (define_expand "insv"
2431   [(set (zero_extract (match_operand 0 "nonimmediate_operand" "")
2432                       (match_operand 1 "general_operand" "")
2433                       (match_operand 2 "general_operand" ""))
2434         (match_operand 3 "reg_or_int_operand" ""))]
2435   "TARGET_ARM || arm_arch_thumb2"
2436   "
2437   {
2438     int start_bit = INTVAL (operands[2]);
2439     int width = INTVAL (operands[1]);
2440     HOST_WIDE_INT mask = (((HOST_WIDE_INT)1) << width) - 1;
2441     rtx target, subtarget;
2443     if (arm_arch_thumb2)
2444       {
2445         if (unaligned_access && MEM_P (operands[0])
2446             && s_register_operand (operands[3], GET_MODE (operands[3]))
2447             && (width == 16 || width == 32) && (start_bit % BITS_PER_UNIT) == 0)
2448           {
2449             rtx base_addr;
2451             if (BYTES_BIG_ENDIAN)
2452               start_bit = GET_MODE_BITSIZE (GET_MODE (operands[3])) - width
2453                           - start_bit;
2455             if (width == 32)
2456               {
2457                 base_addr = adjust_address (operands[0], SImode,
2458                                             start_bit / BITS_PER_UNIT);
2459                 emit_insn (gen_unaligned_storesi (base_addr, operands[3]));
2460               }
2461             else
2462               {
2463                 rtx tmp = gen_reg_rtx (HImode);
2465                 base_addr = adjust_address (operands[0], HImode,
2466                                             start_bit / BITS_PER_UNIT);
2467                 emit_move_insn (tmp, gen_lowpart (HImode, operands[3]));
2468                 emit_insn (gen_unaligned_storehi (base_addr, tmp));
2469               }
2470             DONE;
2471           }
2472         else if (s_register_operand (operands[0], GET_MODE (operands[0])))
2473           {
2474             bool use_bfi = TRUE;
2476             if (CONST_INT_P (operands[3]))
2477               {
2478                 HOST_WIDE_INT val = INTVAL (operands[3]) & mask;
2480                 if (val == 0)
2481                   {
2482                     emit_insn (gen_insv_zero (operands[0], operands[1],
2483                                               operands[2]));
2484                     DONE;
2485                   }
2487                 /* See if the set can be done with a single orr instruction.  */
2488                 if (val == mask && const_ok_for_arm (val << start_bit))
2489                   use_bfi = FALSE;
2490               }
2492             if (use_bfi)
2493               {
2494                 if (!REG_P (operands[3]))
2495                   operands[3] = force_reg (SImode, operands[3]);
2497                 emit_insn (gen_insv_t2 (operands[0], operands[1], operands[2],
2498                                         operands[3]));
2499                 DONE;
2500               }
2501           }
2502         else
2503           FAIL;
2504       }
2506     if (!s_register_operand (operands[0], GET_MODE (operands[0])))
2507       FAIL;
2509     target = copy_rtx (operands[0]);
2510     /* Avoid using a subreg as a subtarget, and avoid writing a paradoxical 
2511        subreg as the final target.  */
2512     if (GET_CODE (target) == SUBREG)
2513       {
2514         subtarget = gen_reg_rtx (SImode);
2515         if (GET_MODE_SIZE (GET_MODE (SUBREG_REG (target)))
2516             < GET_MODE_SIZE (SImode))
2517           target = SUBREG_REG (target);
2518       }
2519     else
2520       subtarget = target;    
2522     if (CONST_INT_P (operands[3]))
2523       {
2524         /* Since we are inserting a known constant, we may be able to
2525            reduce the number of bits that we have to clear so that
2526            the mask becomes simple.  */
2527         /* ??? This code does not check to see if the new mask is actually
2528            simpler.  It may not be.  */
2529         rtx op1 = gen_reg_rtx (SImode);
2530         /* ??? Truncate operand3 to fit in the bitfield.  See comment before
2531            start of this pattern.  */
2532         HOST_WIDE_INT op3_value = mask & INTVAL (operands[3]);
2533         HOST_WIDE_INT mask2 = ((mask & ~op3_value) << start_bit);
2535         emit_insn (gen_andsi3 (op1, operands[0],
2536                                gen_int_mode (~mask2, SImode)));
2537         emit_insn (gen_iorsi3 (subtarget, op1,
2538                                gen_int_mode (op3_value << start_bit, SImode)));
2539       }
2540     else if (start_bit == 0
2541              && !(const_ok_for_arm (mask)
2542                   || const_ok_for_arm (~mask)))
2543       {
2544         /* A Trick, since we are setting the bottom bits in the word,
2545            we can shift operand[3] up, operand[0] down, OR them together
2546            and rotate the result back again.  This takes 3 insns, and
2547            the third might be mergeable into another op.  */
2548         /* The shift up copes with the possibility that operand[3] is
2549            wider than the bitfield.  */
2550         rtx op0 = gen_reg_rtx (SImode);
2551         rtx op1 = gen_reg_rtx (SImode);
2553         emit_insn (gen_ashlsi3 (op0, operands[3], GEN_INT (32 - width)));
2554         emit_insn (gen_lshrsi3 (op1, operands[0], operands[1]));
2555         emit_insn (gen_iorsi3  (op1, op1, op0));
2556         emit_insn (gen_rotlsi3 (subtarget, op1, operands[1]));
2557       }
2558     else if ((width + start_bit == 32)
2559              && !(const_ok_for_arm (mask)
2560                   || const_ok_for_arm (~mask)))
2561       {
2562         /* Similar trick, but slightly less efficient.  */
2564         rtx op0 = gen_reg_rtx (SImode);
2565         rtx op1 = gen_reg_rtx (SImode);
2567         emit_insn (gen_ashlsi3 (op0, operands[3], GEN_INT (32 - width)));
2568         emit_insn (gen_ashlsi3 (op1, operands[0], operands[1]));
2569         emit_insn (gen_lshrsi3 (op1, op1, operands[1]));
2570         emit_insn (gen_iorsi3 (subtarget, op1, op0));
2571       }
2572     else
2573       {
2574         rtx op0 = gen_int_mode (mask, SImode);
2575         rtx op1 = gen_reg_rtx (SImode);
2576         rtx op2 = gen_reg_rtx (SImode);
2578         if (!(const_ok_for_arm (mask) || const_ok_for_arm (~mask)))
2579           {
2580             rtx tmp = gen_reg_rtx (SImode);
2582             emit_insn (gen_movsi (tmp, op0));
2583             op0 = tmp;
2584           }
2586         /* Mask out any bits in operand[3] that are not needed.  */
2587            emit_insn (gen_andsi3 (op1, operands[3], op0));
2589         if (CONST_INT_P (op0)
2590             && (const_ok_for_arm (mask << start_bit)
2591                 || const_ok_for_arm (~(mask << start_bit))))
2592           {
2593             op0 = gen_int_mode (~(mask << start_bit), SImode);
2594             emit_insn (gen_andsi3 (op2, operands[0], op0));
2595           }
2596         else
2597           {
2598             if (CONST_INT_P (op0))
2599               {
2600                 rtx tmp = gen_reg_rtx (SImode);
2602                 emit_insn (gen_movsi (tmp, op0));
2603                 op0 = tmp;
2604               }
2606             if (start_bit != 0)
2607               emit_insn (gen_ashlsi3 (op0, op0, operands[2]));
2608             
2609             emit_insn (gen_andsi_notsi_si (op2, operands[0], op0));
2610           }
2612         if (start_bit != 0)
2613           emit_insn (gen_ashlsi3 (op1, op1, operands[2]));
2615         emit_insn (gen_iorsi3 (subtarget, op1, op2));
2616       }
2618     if (subtarget != target)
2619       {
2620         /* If TARGET is still a SUBREG, then it must be wider than a word,
2621            so we must be careful only to set the subword we were asked to.  */
2622         if (GET_CODE (target) == SUBREG)
2623           emit_move_insn (target, subtarget);
2624         else
2625           emit_move_insn (target, gen_lowpart (GET_MODE (target), subtarget));
2626       }
2628     DONE;
2629   }"
2632 (define_insn "insv_zero"
2633   [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r")
2634                          (match_operand:SI 1 "const_int_M_operand" "M")
2635                          (match_operand:SI 2 "const_int_M_operand" "M"))
2636         (const_int 0))]
2637   "arm_arch_thumb2"
2638   "bfc%?\t%0, %2, %1"
2639   [(set_attr "length" "4")
2640    (set_attr "predicable" "yes")
2641    (set_attr "predicable_short_it" "no")
2642    (set_attr "type" "bfm")]
2645 (define_insn "insv_t2"
2646   [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r")
2647                          (match_operand:SI 1 "const_int_M_operand" "M")
2648                          (match_operand:SI 2 "const_int_M_operand" "M"))
2649         (match_operand:SI 3 "s_register_operand" "r"))]
2650   "arm_arch_thumb2"
2651   "bfi%?\t%0, %3, %2, %1"
2652   [(set_attr "length" "4")
2653    (set_attr "predicable" "yes")
2654    (set_attr "predicable_short_it" "no")
2655    (set_attr "type" "bfm")]
2658 ; constants for op 2 will never be given to these patterns.
2659 (define_insn_and_split "*anddi_notdi_di"
2660   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2661         (and:DI (not:DI (match_operand:DI 1 "s_register_operand" "0,r"))
2662                 (match_operand:DI 2 "s_register_operand" "r,0")))]
2663   "TARGET_32BIT"
2664   "#"
2665   "TARGET_32BIT && reload_completed
2666    && ! (TARGET_NEON && IS_VFP_REGNUM (REGNO (operands[0])))
2667    && ! IS_IWMMXT_REGNUM (REGNO (operands[0]))"
2668   [(set (match_dup 0) (and:SI (not:SI (match_dup 1)) (match_dup 2)))
2669    (set (match_dup 3) (and:SI (not:SI (match_dup 4)) (match_dup 5)))]
2670   "
2671   {
2672     operands[3] = gen_highpart (SImode, operands[0]);
2673     operands[0] = gen_lowpart (SImode, operands[0]);
2674     operands[4] = gen_highpart (SImode, operands[1]);
2675     operands[1] = gen_lowpart (SImode, operands[1]);
2676     operands[5] = gen_highpart (SImode, operands[2]);
2677     operands[2] = gen_lowpart (SImode, operands[2]);
2678   }"
2679   [(set_attr "length" "8")
2680    (set_attr "predicable" "yes")
2681    (set_attr "type" "multiple")]
2684 (define_insn_and_split "*anddi_notzesidi_di"
2685   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2686         (and:DI (not:DI (zero_extend:DI
2687                          (match_operand:SI 2 "s_register_operand" "r,r")))
2688                 (match_operand:DI 1 "s_register_operand" "0,?r")))]
2689   "TARGET_32BIT"
2690   "@
2691    bic%?\\t%Q0, %Q1, %2
2692    #"
2693   ; (not (zero_extend ...)) allows us to just copy the high word from
2694   ; operand1 to operand0.
2695   "TARGET_32BIT
2696    && reload_completed
2697    && operands[0] != operands[1]"
2698   [(set (match_dup 0) (and:SI (not:SI (match_dup 2)) (match_dup 1)))
2699    (set (match_dup 3) (match_dup 4))]
2700   "
2701   {
2702     operands[3] = gen_highpart (SImode, operands[0]);
2703     operands[0] = gen_lowpart (SImode, operands[0]);
2704     operands[4] = gen_highpart (SImode, operands[1]);
2705     operands[1] = gen_lowpart (SImode, operands[1]);
2706   }"
2707   [(set_attr "length" "4,8")
2708    (set_attr "predicable" "yes")
2709    (set_attr "predicable_short_it" "no")
2710    (set_attr "type" "multiple")]
2713 (define_insn_and_split "*anddi_notdi_zesidi"
2714   [(set (match_operand:DI 0 "s_register_operand" "=r")
2715         (and:DI (not:DI (match_operand:DI 2 "s_register_operand" "r"))
2716                 (zero_extend:DI
2717                  (match_operand:SI 1 "s_register_operand" "r"))))]
2718   "TARGET_32BIT"
2719   "#"
2720   "TARGET_32BIT && reload_completed"
2721   [(set (match_dup 0) (and:SI (not:SI (match_dup 2)) (match_dup 1)))
2722    (set (match_dup 3) (const_int 0))]
2723   "
2724   {
2725     operands[3] = gen_highpart (SImode, operands[0]);
2726     operands[0] = gen_lowpart (SImode, operands[0]);
2727     operands[2] = gen_lowpart (SImode, operands[2]);
2728   }"
2729   [(set_attr "length" "8")
2730    (set_attr "predicable" "yes")
2731    (set_attr "predicable_short_it" "no")
2732    (set_attr "type" "multiple")]
2735 (define_insn_and_split "*anddi_notsesidi_di"
2736   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2737         (and:DI (not:DI (sign_extend:DI
2738                          (match_operand:SI 2 "s_register_operand" "r,r")))
2739                 (match_operand:DI 1 "s_register_operand" "0,r")))]
2740   "TARGET_32BIT"
2741   "#"
2742   "TARGET_32BIT && reload_completed"
2743   [(set (match_dup 0) (and:SI (not:SI (match_dup 2)) (match_dup 1)))
2744    (set (match_dup 3) (and:SI (not:SI
2745                                 (ashiftrt:SI (match_dup 2) (const_int 31)))
2746                                (match_dup 4)))]
2747   "
2748   {
2749     operands[3] = gen_highpart (SImode, operands[0]);
2750     operands[0] = gen_lowpart (SImode, operands[0]);
2751     operands[4] = gen_highpart (SImode, operands[1]);
2752     operands[1] = gen_lowpart (SImode, operands[1]);
2753   }"
2754   [(set_attr "length" "8")
2755    (set_attr "predicable" "yes")
2756    (set_attr "predicable_short_it" "no")
2757    (set_attr "type" "multiple")]
2760 (define_insn "andsi_notsi_si"
2761   [(set (match_operand:SI 0 "s_register_operand" "=r")
2762         (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
2763                 (match_operand:SI 1 "s_register_operand" "r")))]
2764   "TARGET_32BIT"
2765   "bic%?\\t%0, %1, %2"
2766   [(set_attr "predicable" "yes")
2767    (set_attr "predicable_short_it" "no")
2768    (set_attr "type" "logic_reg")]
2771 (define_insn "andsi_not_shiftsi_si"
2772   [(set (match_operand:SI 0 "s_register_operand" "=r")
2773         (and:SI (not:SI (match_operator:SI 4 "shift_operator"
2774                          [(match_operand:SI 2 "s_register_operand" "r")
2775                           (match_operand:SI 3 "arm_rhs_operand" "rM")]))
2776                 (match_operand:SI 1 "s_register_operand" "r")))]
2777   "TARGET_ARM"
2778   "bic%?\\t%0, %1, %2%S4"
2779   [(set_attr "predicable" "yes")
2780    (set_attr "shift" "2")
2781    (set (attr "type") (if_then_else (match_operand 3 "const_int_operand" "")
2782                       (const_string "logic_shift_imm")
2783                       (const_string "logic_shift_reg")))]
2786 ;; Shifted bics pattern used to set up CC status register and not reusing
2787 ;; bics output.  Pattern restricts Thumb2 shift operand as bics for Thumb2
2788 ;; does not support shift by register.
2789 (define_insn "andsi_not_shiftsi_si_scc_no_reuse"
2790   [(set (reg:CC_NOOV CC_REGNUM)
2791         (compare:CC_NOOV
2792                 (and:SI (not:SI (match_operator:SI 0 "shift_operator"
2793                         [(match_operand:SI 1 "s_register_operand" "r")
2794                          (match_operand:SI 2 "arm_rhs_operand" "rM")]))
2795                         (match_operand:SI 3 "s_register_operand" "r"))
2796                 (const_int 0)))
2797    (clobber (match_scratch:SI 4 "=r"))]
2798   "TARGET_ARM || (TARGET_THUMB2 && CONST_INT_P (operands[2]))"
2799   "bic%.%?\\t%4, %3, %1%S0"
2800   [(set_attr "predicable" "yes")
2801    (set_attr "predicable_short_it" "no")
2802    (set_attr "conds" "set")
2803    (set_attr "shift" "1")
2804    (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
2805                       (const_string "logic_shift_imm")
2806                       (const_string "logic_shift_reg")))]
2809 ;; Same as andsi_not_shiftsi_si_scc_no_reuse, but the bics result is also
2810 ;; getting reused later.
2811 (define_insn "andsi_not_shiftsi_si_scc"
2812   [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2813         (compare:CC_NOOV
2814                 (and:SI (not:SI (match_operator:SI 0 "shift_operator"
2815                         [(match_operand:SI 1 "s_register_operand" "r")
2816                          (match_operand:SI 2 "arm_rhs_operand" "rM")]))
2817                         (match_operand:SI 3 "s_register_operand" "r"))
2818                 (const_int 0)))
2819         (set (match_operand:SI 4 "s_register_operand" "=r")
2820              (and:SI (not:SI (match_op_dup 0
2821                      [(match_dup 1)
2822                       (match_dup 2)]))
2823                      (match_dup 3)))])]
2824   "TARGET_ARM || (TARGET_THUMB2 && CONST_INT_P (operands[2]))"
2825   "bic%.%?\\t%4, %3, %1%S0"
2826   [(set_attr "predicable" "yes")
2827    (set_attr "predicable_short_it" "no")
2828    (set_attr "conds" "set")
2829    (set_attr "shift" "1")
2830    (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
2831                       (const_string "logic_shift_imm")
2832                       (const_string "logic_shift_reg")))]
2835 (define_insn "*andsi_notsi_si_compare0"
2836   [(set (reg:CC_NOOV CC_REGNUM)
2837         (compare:CC_NOOV
2838          (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
2839                  (match_operand:SI 1 "s_register_operand" "r"))
2840          (const_int 0)))
2841    (set (match_operand:SI 0 "s_register_operand" "=r")
2842         (and:SI (not:SI (match_dup 2)) (match_dup 1)))]
2843   "TARGET_32BIT"
2844   "bic%.\\t%0, %1, %2"
2845   [(set_attr "conds" "set")
2846    (set_attr "type" "logics_shift_reg")]
2849 (define_insn "*andsi_notsi_si_compare0_scratch"
2850   [(set (reg:CC_NOOV CC_REGNUM)
2851         (compare:CC_NOOV
2852          (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
2853                  (match_operand:SI 1 "s_register_operand" "r"))
2854          (const_int 0)))
2855    (clobber (match_scratch:SI 0 "=r"))]
2856   "TARGET_32BIT"
2857   "bic%.\\t%0, %1, %2"
2858   [(set_attr "conds" "set")
2859    (set_attr "type" "logics_shift_reg")]
2862 (define_expand "iordi3"
2863   [(set (match_operand:DI         0 "s_register_operand" "")
2864         (ior:DI (match_operand:DI 1 "s_register_operand" "")
2865                 (match_operand:DI 2 "neon_logic_op2" "")))]
2866   "TARGET_32BIT"
2867   ""
2870 (define_insn_and_split "*iordi3_insn"
2871   [(set (match_operand:DI         0 "s_register_operand"     "=w,w ,&r,&r,&r,&r,?w,?w")
2872         (ior:DI (match_operand:DI 1 "s_register_operand"     "%w,0 ,0 ,r ,0 ,r ,w ,0")
2873                 (match_operand:DI 2 "arm_iordi_operand_neon" "w ,Dl,r ,r ,Df,Df,w ,Dl")))]
2874   "TARGET_32BIT && !TARGET_IWMMXT"
2875   {
2876   switch (which_alternative)
2877     {
2878     case 0: /* fall through */
2879     case 6: return "vorr\t%P0, %P1, %P2";
2880     case 1: /* fall through */
2881     case 7: return neon_output_logic_immediate ("vorr", &operands[2],
2882                      DImode, 0, VALID_NEON_QREG_MODE (DImode));
2883     case 2:
2884     case 3:
2885     case 4:
2886     case 5:
2887       return "#";
2888     default: gcc_unreachable ();
2889     }
2890   }
2891   "TARGET_32BIT && !TARGET_IWMMXT && reload_completed
2892    && !(IS_VFP_REGNUM (REGNO (operands[0])))"
2893   [(set (match_dup 3) (match_dup 4))
2894    (set (match_dup 5) (match_dup 6))]
2895   "
2896   {
2897     operands[3] = gen_lowpart (SImode, operands[0]);
2898     operands[5] = gen_highpart (SImode, operands[0]);
2900     operands[4] = simplify_gen_binary (IOR, SImode,
2901                                            gen_lowpart (SImode, operands[1]),
2902                                            gen_lowpart (SImode, operands[2]));
2903     operands[6] = simplify_gen_binary (IOR, SImode,
2904                                            gen_highpart (SImode, operands[1]),
2905                                            gen_highpart_mode (SImode, DImode, operands[2]));
2907   }"
2908   [(set_attr "type" "neon_logic,neon_logic,multiple,multiple,multiple,\
2909                      multiple,neon_logic,neon_logic")
2910    (set_attr "length" "*,*,8,8,8,8,*,*")
2911    (set_attr "arch" "neon_for_64bits,neon_for_64bits,*,*,*,*,avoid_neon_for_64bits,avoid_neon_for_64bits")]
2914 (define_insn "*iordi_zesidi_di"
2915   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2916         (ior:DI (zero_extend:DI
2917                  (match_operand:SI 2 "s_register_operand" "r,r"))
2918                 (match_operand:DI 1 "s_register_operand" "0,?r")))]
2919   "TARGET_32BIT"
2920   "@
2921    orr%?\\t%Q0, %Q1, %2
2922    #"
2923   [(set_attr "length" "4,8")
2924    (set_attr "predicable" "yes")
2925    (set_attr "predicable_short_it" "no")
2926    (set_attr "type" "logic_reg,multiple")]
2929 (define_insn "*iordi_sesidi_di"
2930   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2931         (ior:DI (sign_extend:DI
2932                  (match_operand:SI 2 "s_register_operand" "r,r"))
2933                 (match_operand:DI 1 "s_register_operand" "0,r")))]
2934   "TARGET_32BIT"
2935   "#"
2936   [(set_attr "length" "8")
2937    (set_attr "predicable" "yes")
2938    (set_attr "type" "multiple")]
2941 (define_expand "iorsi3"
2942   [(set (match_operand:SI         0 "s_register_operand" "")
2943         (ior:SI (match_operand:SI 1 "s_register_operand" "")
2944                 (match_operand:SI 2 "reg_or_int_operand" "")))]
2945   "TARGET_EITHER"
2946   "
2947   if (CONST_INT_P (operands[2]))
2948     {
2949       if (TARGET_32BIT)
2950         {
2951           if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[2]), IOR))
2952             operands[2] = force_reg (SImode, operands[2]);
2953           else
2954             {
2955               arm_split_constant (IOR, SImode, NULL_RTX,
2956                                   INTVAL (operands[2]), operands[0],
2957                                   operands[1],
2958                                   optimize && can_create_pseudo_p ());
2959               DONE;
2960             }
2961         }
2962       else /* TARGET_THUMB1 */
2963         {
2964           rtx tmp = force_reg (SImode, operands[2]);
2965           if (rtx_equal_p (operands[0], operands[1]))
2966             operands[2] = tmp;
2967           else
2968             {
2969               operands[2] = operands[1];
2970               operands[1] = tmp;
2971             }
2972         }
2973     }
2974   "
2977 (define_insn_and_split "*iorsi3_insn"
2978   [(set (match_operand:SI 0 "s_register_operand" "=r,l,r,r,r")
2979         (ior:SI (match_operand:SI 1 "s_register_operand" "%r,0,r,r,r")
2980                 (match_operand:SI 2 "reg_or_int_operand" "I,l,K,r,?n")))]
2981   "TARGET_32BIT"
2982   "@
2983    orr%?\\t%0, %1, %2
2984    orr%?\\t%0, %1, %2
2985    orn%?\\t%0, %1, #%B2
2986    orr%?\\t%0, %1, %2
2987    #"
2988   "TARGET_32BIT
2989    && CONST_INT_P (operands[2])
2990    && !(const_ok_for_arm (INTVAL (operands[2]))
2991         || (TARGET_THUMB2 && const_ok_for_arm (~INTVAL (operands[2]))))"
2992   [(clobber (const_int 0))]
2994   arm_split_constant (IOR, SImode, curr_insn,
2995                       INTVAL (operands[2]), operands[0], operands[1], 0);
2996   DONE;
2998   [(set_attr "length" "4,4,4,4,16")
2999    (set_attr "arch" "32,t2,t2,32,32")
3000    (set_attr "predicable" "yes")
3001    (set_attr "predicable_short_it" "no,yes,no,no,no")
3002    (set_attr "type" "logic_imm,logic_reg,logic_imm,logic_reg,logic_reg")]
3005 (define_peephole2
3006   [(match_scratch:SI 3 "r")
3007    (set (match_operand:SI 0 "arm_general_register_operand" "")
3008         (ior:SI (match_operand:SI 1 "arm_general_register_operand" "")
3009                 (match_operand:SI 2 "const_int_operand" "")))]
3010   "TARGET_ARM
3011    && !const_ok_for_arm (INTVAL (operands[2]))
3012    && const_ok_for_arm (~INTVAL (operands[2]))"
3013   [(set (match_dup 3) (match_dup 2))
3014    (set (match_dup 0) (ior:SI (match_dup 1) (match_dup 3)))]
3015   ""
3018 (define_insn "*iorsi3_compare0"
3019   [(set (reg:CC_NOOV CC_REGNUM)
3020         (compare:CC_NOOV (ior:SI (match_operand:SI 1 "s_register_operand" "%r,r")
3021                                  (match_operand:SI 2 "arm_rhs_operand" "I,r"))
3022                          (const_int 0)))
3023    (set (match_operand:SI 0 "s_register_operand" "=r,r")
3024         (ior:SI (match_dup 1) (match_dup 2)))]
3025   "TARGET_32BIT"
3026   "orr%.\\t%0, %1, %2"
3027   [(set_attr "conds" "set")
3028    (set_attr "type" "logics_imm,logics_reg")]
3031 (define_insn "*iorsi3_compare0_scratch"
3032   [(set (reg:CC_NOOV CC_REGNUM)
3033         (compare:CC_NOOV (ior:SI (match_operand:SI 1 "s_register_operand" "%r,r")
3034                                  (match_operand:SI 2 "arm_rhs_operand" "I,r"))
3035                          (const_int 0)))
3036    (clobber (match_scratch:SI 0 "=r,r"))]
3037   "TARGET_32BIT"
3038   "orr%.\\t%0, %1, %2"
3039   [(set_attr "conds" "set")
3040    (set_attr "type" "logics_imm,logics_reg")]
3043 (define_expand "xordi3"
3044   [(set (match_operand:DI         0 "s_register_operand" "")
3045         (xor:DI (match_operand:DI 1 "s_register_operand" "")
3046                 (match_operand:DI 2 "arm_xordi_operand" "")))]
3047   "TARGET_32BIT"
3048   ""
3051 (define_insn_and_split "*xordi3_insn"
3052   [(set (match_operand:DI         0 "s_register_operand" "=w,&r,&r,&r,&r,?w")
3053         (xor:DI (match_operand:DI 1 "s_register_operand" "%w ,0,r ,0 ,r ,w")
3054                 (match_operand:DI 2 "arm_xordi_operand"  "w ,r ,r ,Dg,Dg,w")))]
3055   "TARGET_32BIT && !TARGET_IWMMXT"
3057   switch (which_alternative)
3058     {
3059     case 1:
3060     case 2:
3061     case 3:
3062     case 4:  /* fall through */
3063       return "#";
3064     case 0: /* fall through */
3065     case 5: return "veor\t%P0, %P1, %P2";
3066     default: gcc_unreachable ();
3067     }
3069   "TARGET_32BIT && !TARGET_IWMMXT && reload_completed
3070    && !(IS_VFP_REGNUM (REGNO (operands[0])))"
3071   [(set (match_dup 3) (match_dup 4))
3072    (set (match_dup 5) (match_dup 6))]
3073   "
3074   {
3075     operands[3] = gen_lowpart (SImode, operands[0]);
3076     operands[5] = gen_highpart (SImode, operands[0]);
3078     operands[4] = simplify_gen_binary (XOR, SImode,
3079                                            gen_lowpart (SImode, operands[1]),
3080                                            gen_lowpart (SImode, operands[2]));
3081     operands[6] = simplify_gen_binary (XOR, SImode,
3082                                            gen_highpart (SImode, operands[1]),
3083                                            gen_highpart_mode (SImode, DImode, operands[2]));
3085   }"
3086   [(set_attr "length" "*,8,8,8,8,*")
3087    (set_attr "type" "neon_logic,multiple,multiple,multiple,multiple,neon_logic")
3088    (set_attr "arch" "neon_for_64bits,*,*,*,*,avoid_neon_for_64bits")]
3091 (define_insn "*xordi_zesidi_di"
3092   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
3093         (xor:DI (zero_extend:DI
3094                  (match_operand:SI 2 "s_register_operand" "r,r"))
3095                 (match_operand:DI 1 "s_register_operand" "0,?r")))]
3096   "TARGET_32BIT"
3097   "@
3098    eor%?\\t%Q0, %Q1, %2
3099    #"
3100   [(set_attr "length" "4,8")
3101    (set_attr "predicable" "yes")
3102    (set_attr "predicable_short_it" "no")
3103    (set_attr "type" "logic_reg")]
3106 (define_insn "*xordi_sesidi_di"
3107   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
3108         (xor:DI (sign_extend:DI
3109                  (match_operand:SI 2 "s_register_operand" "r,r"))
3110                 (match_operand:DI 1 "s_register_operand" "0,r")))]
3111   "TARGET_32BIT"
3112   "#"
3113   [(set_attr "length" "8")
3114    (set_attr "predicable" "yes")
3115    (set_attr "type" "multiple")]
3118 (define_expand "xorsi3"
3119   [(set (match_operand:SI         0 "s_register_operand" "")
3120         (xor:SI (match_operand:SI 1 "s_register_operand" "")
3121                 (match_operand:SI 2 "reg_or_int_operand" "")))]
3122   "TARGET_EITHER"
3123   "if (CONST_INT_P (operands[2]))
3124     {
3125       if (TARGET_32BIT)
3126         {
3127           if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[2]), XOR))
3128             operands[2] = force_reg (SImode, operands[2]);
3129           else
3130             {
3131               arm_split_constant (XOR, SImode, NULL_RTX,
3132                                   INTVAL (operands[2]), operands[0],
3133                                   operands[1],
3134                                   optimize && can_create_pseudo_p ());
3135               DONE;
3136             }
3137         }
3138       else /* TARGET_THUMB1 */
3139         {
3140           rtx tmp = force_reg (SImode, operands[2]);
3141           if (rtx_equal_p (operands[0], operands[1]))
3142             operands[2] = tmp;
3143           else
3144             {
3145               operands[2] = operands[1];
3146               operands[1] = tmp;
3147             }
3148         }
3149     }"
3152 (define_insn_and_split "*arm_xorsi3"
3153   [(set (match_operand:SI         0 "s_register_operand" "=r,l,r,r")
3154         (xor:SI (match_operand:SI 1 "s_register_operand" "%r,0,r,r")
3155                 (match_operand:SI 2 "reg_or_int_operand" "I,l,r,?n")))]
3156   "TARGET_32BIT"
3157   "@
3158    eor%?\\t%0, %1, %2
3159    eor%?\\t%0, %1, %2
3160    eor%?\\t%0, %1, %2
3161    #"
3162   "TARGET_32BIT
3163    && CONST_INT_P (operands[2])
3164    && !const_ok_for_arm (INTVAL (operands[2]))"
3165   [(clobber (const_int 0))]
3167   arm_split_constant (XOR, SImode, curr_insn,
3168                       INTVAL (operands[2]), operands[0], operands[1], 0);
3169   DONE;
3171   [(set_attr "length" "4,4,4,16")
3172    (set_attr "predicable" "yes")
3173    (set_attr "predicable_short_it" "no,yes,no,no")
3174    (set_attr "type"  "logic_imm,logic_reg,logic_reg,multiple")]
3177 (define_insn "*xorsi3_compare0"
3178   [(set (reg:CC_NOOV CC_REGNUM)
3179         (compare:CC_NOOV (xor:SI (match_operand:SI 1 "s_register_operand" "r,r")
3180                                  (match_operand:SI 2 "arm_rhs_operand" "I,r"))
3181                          (const_int 0)))
3182    (set (match_operand:SI 0 "s_register_operand" "=r,r")
3183         (xor:SI (match_dup 1) (match_dup 2)))]
3184   "TARGET_32BIT"
3185   "eor%.\\t%0, %1, %2"
3186   [(set_attr "conds" "set")
3187    (set_attr "type" "logics_imm,logics_reg")]
3190 (define_insn "*xorsi3_compare0_scratch"
3191   [(set (reg:CC_NOOV CC_REGNUM)
3192         (compare:CC_NOOV (xor:SI (match_operand:SI 0 "s_register_operand" "r,r")
3193                                  (match_operand:SI 1 "arm_rhs_operand" "I,r"))
3194                          (const_int 0)))]
3195   "TARGET_32BIT"
3196   "teq%?\\t%0, %1"
3197   [(set_attr "conds" "set")
3198    (set_attr "type" "logics_imm,logics_reg")]
3201 ; By splitting (IOR (AND (NOT A) (NOT B)) C) as D = AND (IOR A B) (NOT C), 
3202 ; (NOT D) we can sometimes merge the final NOT into one of the following
3203 ; insns.
3205 (define_split
3206   [(set (match_operand:SI 0 "s_register_operand" "")
3207         (ior:SI (and:SI (not:SI (match_operand:SI 1 "s_register_operand" ""))
3208                         (not:SI (match_operand:SI 2 "arm_rhs_operand" "")))
3209                 (match_operand:SI 3 "arm_rhs_operand" "")))
3210    (clobber (match_operand:SI 4 "s_register_operand" ""))]
3211   "TARGET_32BIT"
3212   [(set (match_dup 4) (and:SI (ior:SI (match_dup 1) (match_dup 2))
3213                               (not:SI (match_dup 3))))
3214    (set (match_dup 0) (not:SI (match_dup 4)))]
3215   ""
3218 (define_insn_and_split "*andsi_iorsi3_notsi"
3219   [(set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r")
3220         (and:SI (ior:SI (match_operand:SI 1 "s_register_operand" "%0,r,r")
3221                         (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI"))
3222                 (not:SI (match_operand:SI 3 "arm_rhs_operand" "rI,rI,rI"))))]
3223   "TARGET_32BIT"
3224   "#"   ; "orr%?\\t%0, %1, %2\;bic%?\\t%0, %0, %3"
3225   "&& reload_completed"
3226   [(set (match_dup 0) (ior:SI (match_dup 1) (match_dup 2)))
3227    (set (match_dup 0) (and:SI (not:SI (match_dup 3)) (match_dup 0)))]
3228   ""
3229   [(set_attr "length" "8")
3230    (set_attr "ce_count" "2")
3231    (set_attr "predicable" "yes")
3232    (set_attr "predicable_short_it" "no")
3233    (set_attr "type" "multiple")]
3236 ; ??? Are these four splitters still beneficial when the Thumb-2 bitfield
3237 ; insns are available?
3238 (define_split
3239   [(set (match_operand:SI 0 "s_register_operand" "")
3240         (match_operator:SI 1 "logical_binary_operator"
3241          [(zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
3242                            (match_operand:SI 3 "const_int_operand" "")
3243                            (match_operand:SI 4 "const_int_operand" ""))
3244           (match_operator:SI 9 "logical_binary_operator"
3245            [(lshiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3246                          (match_operand:SI 6 "const_int_operand" ""))
3247             (match_operand:SI 7 "s_register_operand" "")])]))
3248    (clobber (match_operand:SI 8 "s_register_operand" ""))]
3249   "TARGET_32BIT
3250    && GET_CODE (operands[1]) == GET_CODE (operands[9])
3251    && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3252   [(set (match_dup 8)
3253         (match_op_dup 1
3254          [(ashift:SI (match_dup 2) (match_dup 4))
3255           (match_dup 5)]))
3256    (set (match_dup 0)
3257         (match_op_dup 1
3258          [(lshiftrt:SI (match_dup 8) (match_dup 6))
3259           (match_dup 7)]))]
3260   "
3261   operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3264 (define_split
3265   [(set (match_operand:SI 0 "s_register_operand" "")
3266         (match_operator:SI 1 "logical_binary_operator"
3267          [(match_operator:SI 9 "logical_binary_operator"
3268            [(lshiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3269                          (match_operand:SI 6 "const_int_operand" ""))
3270             (match_operand:SI 7 "s_register_operand" "")])
3271           (zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
3272                            (match_operand:SI 3 "const_int_operand" "")
3273                            (match_operand:SI 4 "const_int_operand" ""))]))
3274    (clobber (match_operand:SI 8 "s_register_operand" ""))]
3275   "TARGET_32BIT
3276    && GET_CODE (operands[1]) == GET_CODE (operands[9])
3277    && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3278   [(set (match_dup 8)
3279         (match_op_dup 1
3280          [(ashift:SI (match_dup 2) (match_dup 4))
3281           (match_dup 5)]))
3282    (set (match_dup 0)
3283         (match_op_dup 1
3284          [(lshiftrt:SI (match_dup 8) (match_dup 6))
3285           (match_dup 7)]))]
3286   "
3287   operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3290 (define_split
3291   [(set (match_operand:SI 0 "s_register_operand" "")
3292         (match_operator:SI 1 "logical_binary_operator"
3293          [(sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
3294                            (match_operand:SI 3 "const_int_operand" "")
3295                            (match_operand:SI 4 "const_int_operand" ""))
3296           (match_operator:SI 9 "logical_binary_operator"
3297            [(ashiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3298                          (match_operand:SI 6 "const_int_operand" ""))
3299             (match_operand:SI 7 "s_register_operand" "")])]))
3300    (clobber (match_operand:SI 8 "s_register_operand" ""))]
3301   "TARGET_32BIT
3302    && GET_CODE (operands[1]) == GET_CODE (operands[9])
3303    && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3304   [(set (match_dup 8)
3305         (match_op_dup 1
3306          [(ashift:SI (match_dup 2) (match_dup 4))
3307           (match_dup 5)]))
3308    (set (match_dup 0)
3309         (match_op_dup 1
3310          [(ashiftrt:SI (match_dup 8) (match_dup 6))
3311           (match_dup 7)]))]
3312   "
3313   operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3316 (define_split
3317   [(set (match_operand:SI 0 "s_register_operand" "")
3318         (match_operator:SI 1 "logical_binary_operator"
3319          [(match_operator:SI 9 "logical_binary_operator"
3320            [(ashiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3321                          (match_operand:SI 6 "const_int_operand" ""))
3322             (match_operand:SI 7 "s_register_operand" "")])
3323           (sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
3324                            (match_operand:SI 3 "const_int_operand" "")
3325                            (match_operand:SI 4 "const_int_operand" ""))]))
3326    (clobber (match_operand:SI 8 "s_register_operand" ""))]
3327   "TARGET_32BIT
3328    && GET_CODE (operands[1]) == GET_CODE (operands[9])
3329    && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3330   [(set (match_dup 8)
3331         (match_op_dup 1
3332          [(ashift:SI (match_dup 2) (match_dup 4))
3333           (match_dup 5)]))
3334    (set (match_dup 0)
3335         (match_op_dup 1
3336          [(ashiftrt:SI (match_dup 8) (match_dup 6))
3337           (match_dup 7)]))]
3338   "
3339   operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3343 ;; Minimum and maximum insns
3345 (define_expand "smaxsi3"
3346   [(parallel [
3347     (set (match_operand:SI 0 "s_register_operand" "")
3348          (smax:SI (match_operand:SI 1 "s_register_operand" "")
3349                   (match_operand:SI 2 "arm_rhs_operand" "")))
3350     (clobber (reg:CC CC_REGNUM))])]
3351   "TARGET_32BIT"
3352   "
3353   if (operands[2] == const0_rtx || operands[2] == constm1_rtx)
3354     {
3355       /* No need for a clobber of the condition code register here.  */
3356       emit_insn (gen_rtx_SET (operands[0],
3357                               gen_rtx_SMAX (SImode, operands[1],
3358                                             operands[2])));
3359       DONE;
3360     }
3363 (define_insn "*smax_0"
3364   [(set (match_operand:SI 0 "s_register_operand" "=r")
3365         (smax:SI (match_operand:SI 1 "s_register_operand" "r")
3366                  (const_int 0)))]
3367   "TARGET_32BIT"
3368   "bic%?\\t%0, %1, %1, asr #31"
3369   [(set_attr "predicable" "yes")
3370    (set_attr "predicable_short_it" "no")
3371    (set_attr "type" "logic_shift_reg")]
3374 (define_insn "*smax_m1"
3375   [(set (match_operand:SI 0 "s_register_operand" "=r")
3376         (smax:SI (match_operand:SI 1 "s_register_operand" "r")
3377                  (const_int -1)))]
3378   "TARGET_32BIT"
3379   "orr%?\\t%0, %1, %1, asr #31"
3380   [(set_attr "predicable" "yes")
3381    (set_attr "predicable_short_it" "no")
3382    (set_attr "type" "logic_shift_reg")]
3385 (define_insn_and_split "*arm_smax_insn"
3386   [(set (match_operand:SI          0 "s_register_operand" "=r,r")
3387         (smax:SI (match_operand:SI 1 "s_register_operand"  "%0,?r")
3388                  (match_operand:SI 2 "arm_rhs_operand"    "rI,rI")))
3389    (clobber (reg:CC CC_REGNUM))]
3390   "TARGET_ARM"
3391   "#"
3392    ; cmp\\t%1, %2\;movlt\\t%0, %2
3393    ; cmp\\t%1, %2\;movge\\t%0, %1\;movlt\\t%0, %2"
3394   "TARGET_ARM"
3395   [(set (reg:CC CC_REGNUM)
3396         (compare:CC (match_dup 1) (match_dup 2)))
3397    (set (match_dup 0)
3398         (if_then_else:SI (ge:SI (reg:CC CC_REGNUM) (const_int 0))
3399                          (match_dup 1)
3400                          (match_dup 2)))]
3401   ""
3402   [(set_attr "conds" "clob")
3403    (set_attr "length" "8,12")
3404    (set_attr "type" "multiple")]
3407 (define_expand "sminsi3"
3408   [(parallel [
3409     (set (match_operand:SI 0 "s_register_operand" "")
3410          (smin:SI (match_operand:SI 1 "s_register_operand" "")
3411                   (match_operand:SI 2 "arm_rhs_operand" "")))
3412     (clobber (reg:CC CC_REGNUM))])]
3413   "TARGET_32BIT"
3414   "
3415   if (operands[2] == const0_rtx)
3416     {
3417       /* No need for a clobber of the condition code register here.  */
3418       emit_insn (gen_rtx_SET (operands[0],
3419                               gen_rtx_SMIN (SImode, operands[1],
3420                                             operands[2])));
3421       DONE;
3422     }
3425 (define_insn "*smin_0"
3426   [(set (match_operand:SI 0 "s_register_operand" "=r")
3427         (smin:SI (match_operand:SI 1 "s_register_operand" "r")
3428                  (const_int 0)))]
3429   "TARGET_32BIT"
3430   "and%?\\t%0, %1, %1, asr #31"
3431   [(set_attr "predicable" "yes")
3432    (set_attr "predicable_short_it" "no")
3433    (set_attr "type" "logic_shift_reg")]
3436 (define_insn_and_split "*arm_smin_insn"
3437   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3438         (smin:SI (match_operand:SI 1 "s_register_operand" "%0,?r")
3439                  (match_operand:SI 2 "arm_rhs_operand" "rI,rI")))
3440    (clobber (reg:CC CC_REGNUM))]
3441   "TARGET_ARM"
3442   "#"
3443     ; cmp\\t%1, %2\;movge\\t%0, %2
3444     ; cmp\\t%1, %2\;movlt\\t%0, %1\;movge\\t%0, %2"
3445   "TARGET_ARM"
3446   [(set (reg:CC CC_REGNUM)
3447         (compare:CC (match_dup 1) (match_dup 2)))
3448    (set (match_dup 0)
3449         (if_then_else:SI (lt:SI (reg:CC CC_REGNUM) (const_int 0))
3450                          (match_dup 1)
3451                          (match_dup 2)))]
3452   ""
3453   [(set_attr "conds" "clob")
3454    (set_attr "length" "8,12")
3455    (set_attr "type" "multiple,multiple")]
3458 ;; t = (s/u)min (x, y)
3459 ;; cc = cmp (t, z)
3460 ;; is the same as
3461 ;; cmp x, z
3462 ;; cmpge(u) y, z
3464 (define_insn_and_split "*arm_smin_cmp"
3465   [(set (reg:CC CC_REGNUM)
3466         (compare:CC
3467          (smin:SI (match_operand:SI 0 "s_register_operand" "r")
3468                   (match_operand:SI 1 "s_register_operand" "r"))
3469          (match_operand:SI 2 "s_register_operand" "r")))]
3470   "TARGET_32BIT"
3471   "#"
3472   "&& reload_completed"
3473   [(set (reg:CC CC_REGNUM)
3474         (compare:CC (match_dup 0) (match_dup 2)))
3475    (cond_exec (ge:CC (reg:CC CC_REGNUM) (const_int 0))
3476               (set (reg:CC CC_REGNUM)
3477                    (compare:CC (match_dup 1) (match_dup 2))))]
3480 (define_insn_and_split "*arm_umin_cmp"
3481   [(set (reg:CC CC_REGNUM)
3482         (compare:CC
3483          (umin:SI (match_operand:SI 0 "s_register_operand" "r")
3484                   (match_operand:SI 1 "s_register_operand" "r"))
3485          (match_operand:SI 2 "s_register_operand" "r")))]
3486   "TARGET_32BIT"
3487   "#"
3488   "&& reload_completed"
3489   [(set (reg:CC CC_REGNUM)
3490         (compare:CC (match_dup 0) (match_dup 2)))
3491    (cond_exec (geu:CC (reg:CC CC_REGNUM) (const_int 0))
3492               (set (reg:CC CC_REGNUM)
3493                    (compare:CC (match_dup 1) (match_dup 2))))]
3496 (define_expand "umaxsi3"
3497   [(parallel [
3498     (set (match_operand:SI 0 "s_register_operand" "")
3499          (umax:SI (match_operand:SI 1 "s_register_operand" "")
3500                   (match_operand:SI 2 "arm_rhs_operand" "")))
3501     (clobber (reg:CC CC_REGNUM))])]
3502   "TARGET_32BIT"
3503   ""
3506 (define_insn_and_split "*arm_umaxsi3"
3507   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
3508         (umax:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
3509                  (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
3510    (clobber (reg:CC CC_REGNUM))]
3511   "TARGET_ARM"
3512   "#"
3513     ; cmp\\t%1, %2\;movcc\\t%0, %2
3514     ; cmp\\t%1, %2\;movcs\\t%0, %1
3515     ; cmp\\t%1, %2\;movcs\\t%0, %1\;movcc\\t%0, %2"
3516   "TARGET_ARM"
3517   [(set (reg:CC CC_REGNUM)
3518         (compare:CC (match_dup 1) (match_dup 2)))
3519    (set (match_dup 0)
3520         (if_then_else:SI (geu:SI (reg:CC CC_REGNUM) (const_int 0))
3521                          (match_dup 1)
3522                          (match_dup 2)))]
3523   ""
3524   [(set_attr "conds" "clob")
3525    (set_attr "length" "8,8,12")
3526    (set_attr "type" "store1")]
3529 (define_expand "uminsi3"
3530   [(parallel [
3531     (set (match_operand:SI 0 "s_register_operand" "")
3532          (umin:SI (match_operand:SI 1 "s_register_operand" "")
3533                   (match_operand:SI 2 "arm_rhs_operand" "")))
3534     (clobber (reg:CC CC_REGNUM))])]
3535   "TARGET_32BIT"
3536   ""
3539 (define_insn_and_split "*arm_uminsi3"
3540   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
3541         (umin:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
3542                  (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
3543    (clobber (reg:CC CC_REGNUM))]
3544   "TARGET_ARM"
3545   "#"
3546    ; cmp\\t%1, %2\;movcs\\t%0, %2
3547    ; cmp\\t%1, %2\;movcc\\t%0, %1
3548    ; cmp\\t%1, %2\;movcc\\t%0, %1\;movcs\\t%0, %2"
3549   "TARGET_ARM"
3550   [(set (reg:CC CC_REGNUM)
3551         (compare:CC (match_dup 1) (match_dup 2)))
3552    (set (match_dup 0)
3553         (if_then_else:SI (ltu:SI (reg:CC CC_REGNUM) (const_int 0))
3554                          (match_dup 1)
3555                          (match_dup 2)))]
3556   ""
3557   [(set_attr "conds" "clob")
3558    (set_attr "length" "8,8,12")
3559    (set_attr "type" "store1")]
3562 (define_insn "*store_minmaxsi"
3563   [(set (match_operand:SI 0 "memory_operand" "=m")
3564         (match_operator:SI 3 "minmax_operator"
3565          [(match_operand:SI 1 "s_register_operand" "r")
3566           (match_operand:SI 2 "s_register_operand" "r")]))
3567    (clobber (reg:CC CC_REGNUM))]
3568   "TARGET_32BIT && optimize_function_for_size_p (cfun) && !arm_restrict_it"
3569   "*
3570   operands[3] = gen_rtx_fmt_ee (minmax_code (operands[3]), SImode,
3571                                 operands[1], operands[2]);
3572   output_asm_insn (\"cmp\\t%1, %2\", operands);
3573   if (TARGET_THUMB2)
3574     output_asm_insn (\"ite\t%d3\", operands);
3575   output_asm_insn (\"str%d3\\t%1, %0\", operands);
3576   output_asm_insn (\"str%D3\\t%2, %0\", operands);
3577   return \"\";
3578   "
3579   [(set_attr "conds" "clob")
3580    (set (attr "length")
3581         (if_then_else (eq_attr "is_thumb" "yes")
3582                       (const_int 14)
3583                       (const_int 12)))
3584    (set_attr "type" "store1")]
3587 ; Reject the frame pointer in operand[1], since reloading this after
3588 ; it has been eliminated can cause carnage.
3589 (define_insn "*minmax_arithsi"
3590   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3591         (match_operator:SI 4 "shiftable_operator"
3592          [(match_operator:SI 5 "minmax_operator"
3593            [(match_operand:SI 2 "s_register_operand" "r,r")
3594             (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
3595           (match_operand:SI 1 "s_register_operand" "0,?r")]))
3596    (clobber (reg:CC CC_REGNUM))]
3597   "TARGET_32BIT && !arm_eliminable_register (operands[1]) && !arm_restrict_it"
3598   "*
3599   {
3600     enum rtx_code code = GET_CODE (operands[4]);
3601     bool need_else;
3603     if (which_alternative != 0 || operands[3] != const0_rtx
3604         || (code != PLUS && code != IOR && code != XOR))
3605       need_else = true;
3606     else
3607       need_else = false;
3609     operands[5] = gen_rtx_fmt_ee (minmax_code (operands[5]), SImode,
3610                                   operands[2], operands[3]);
3611     output_asm_insn (\"cmp\\t%2, %3\", operands);
3612     if (TARGET_THUMB2)
3613       {
3614         if (need_else)
3615           output_asm_insn (\"ite\\t%d5\", operands);
3616         else
3617           output_asm_insn (\"it\\t%d5\", operands);
3618       }
3619     output_asm_insn (\"%i4%d5\\t%0, %1, %2\", operands);
3620     if (need_else)
3621       output_asm_insn (\"%i4%D5\\t%0, %1, %3\", operands);
3622     return \"\";
3623   }"
3624   [(set_attr "conds" "clob")
3625    (set (attr "length")
3626         (if_then_else (eq_attr "is_thumb" "yes")
3627                       (const_int 14)
3628                       (const_int 12)))
3629    (set_attr "type" "multiple")]
3632 ; Reject the frame pointer in operand[1], since reloading this after
3633 ; it has been eliminated can cause carnage.
3634 (define_insn_and_split "*minmax_arithsi_non_canon"
3635   [(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts")
3636         (minus:SI
3637          (match_operand:SI 1 "s_register_operand" "0,?Ts")
3638           (match_operator:SI 4 "minmax_operator"
3639            [(match_operand:SI 2 "s_register_operand" "Ts,Ts")
3640             (match_operand:SI 3 "arm_rhs_operand" "TsI,TsI")])))
3641    (clobber (reg:CC CC_REGNUM))]
3642   "TARGET_32BIT && !arm_eliminable_register (operands[1])
3643    && !(arm_restrict_it && CONST_INT_P (operands[3]))"
3644   "#"
3645   "TARGET_32BIT && !arm_eliminable_register (operands[1]) && reload_completed"
3646   [(set (reg:CC CC_REGNUM)
3647         (compare:CC (match_dup 2) (match_dup 3)))
3649    (cond_exec (match_op_dup 4 [(reg:CC CC_REGNUM) (const_int 0)])
3650               (set (match_dup 0)
3651                    (minus:SI (match_dup 1)
3652                              (match_dup 2))))
3653    (cond_exec (match_op_dup 5 [(reg:CC CC_REGNUM) (const_int 0)])
3654               (set (match_dup 0)
3655                    (match_dup 6)))]
3656   {
3657   machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
3658                                            operands[2], operands[3]);
3659   enum rtx_code rc = minmax_code (operands[4]);
3660   operands[4] = gen_rtx_fmt_ee (rc, VOIDmode,
3661                                 operands[2], operands[3]);
3663   if (mode == CCFPmode || mode == CCFPEmode)
3664     rc = reverse_condition_maybe_unordered (rc);
3665   else
3666     rc = reverse_condition (rc);
3667   operands[5] = gen_rtx_fmt_ee (rc, SImode, operands[2], operands[3]);
3668   if (CONST_INT_P (operands[3]))
3669     operands[6] = plus_constant (SImode, operands[1], -INTVAL (operands[3]));
3670   else
3671     operands[6] = gen_rtx_MINUS (SImode, operands[1], operands[3]);
3672   }
3673   [(set_attr "conds" "clob")
3674    (set (attr "length")
3675         (if_then_else (eq_attr "is_thumb" "yes")
3676                       (const_int 14)
3677                       (const_int 12)))
3678    (set_attr "type" "multiple")]
3681 (define_code_iterator SAT [smin smax])
3682 (define_code_iterator SATrev [smin smax])
3683 (define_code_attr SATlo [(smin "1") (smax "2")])
3684 (define_code_attr SAThi [(smin "2") (smax "1")])
3686 (define_insn "*satsi_<SAT:code>"
3687   [(set (match_operand:SI 0 "s_register_operand" "=r")
3688         (SAT:SI (SATrev:SI (match_operand:SI 3 "s_register_operand" "r")
3689                            (match_operand:SI 1 "const_int_operand" "i"))
3690                 (match_operand:SI 2 "const_int_operand" "i")))]
3691   "TARGET_32BIT && arm_arch6 && <SAT:CODE> != <SATrev:CODE>
3692    && arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>], NULL, NULL)"
3694   int mask;
3695   bool signed_sat;
3696   if (!arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>],
3697                                &mask, &signed_sat))
3698     gcc_unreachable ();
3700   operands[1] = GEN_INT (mask);
3701   if (signed_sat)
3702     return "ssat%?\t%0, %1, %3";
3703   else
3704     return "usat%?\t%0, %1, %3";
3706   [(set_attr "predicable" "yes")
3707    (set_attr "predicable_short_it" "no")
3708    (set_attr "type" "alus_imm")]
3711 (define_insn "*satsi_<SAT:code>_shift"
3712   [(set (match_operand:SI 0 "s_register_operand" "=r")
3713         (SAT:SI (SATrev:SI (match_operator:SI 3 "sat_shift_operator"
3714                              [(match_operand:SI 4 "s_register_operand" "r")
3715                               (match_operand:SI 5 "const_int_operand" "i")])
3716                            (match_operand:SI 1 "const_int_operand" "i"))
3717                 (match_operand:SI 2 "const_int_operand" "i")))]
3718   "TARGET_32BIT && arm_arch6 && <SAT:CODE> != <SATrev:CODE>
3719    && arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>], NULL, NULL)"
3721   int mask;
3722   bool signed_sat;
3723   if (!arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>],
3724                                &mask, &signed_sat))
3725     gcc_unreachable ();
3727   operands[1] = GEN_INT (mask);
3728   if (signed_sat)
3729     return "ssat%?\t%0, %1, %4%S3";
3730   else
3731     return "usat%?\t%0, %1, %4%S3";
3733   [(set_attr "predicable" "yes")
3734    (set_attr "predicable_short_it" "no")
3735    (set_attr "shift" "3")
3736    (set_attr "type" "logic_shift_reg")])
3738 ;; Shift and rotation insns
3740 (define_expand "ashldi3"
3741   [(set (match_operand:DI            0 "s_register_operand" "")
3742         (ashift:DI (match_operand:DI 1 "s_register_operand" "")
3743                    (match_operand:SI 2 "general_operand" "")))]
3744   "TARGET_32BIT"
3745   "
3746   if (TARGET_NEON)
3747     {
3748       /* Delay the decision whether to use NEON or core-regs until
3749          register allocation.  */
3750       emit_insn (gen_ashldi3_neon (operands[0], operands[1], operands[2]));
3751       DONE;
3752     }
3753   else
3754     {
3755       /* Only the NEON case can handle in-memory shift counts.  */
3756       if (!reg_or_int_operand (operands[2], SImode))
3757         operands[2] = force_reg (SImode, operands[2]);
3758     }
3760   if (!CONST_INT_P (operands[2]) && TARGET_REALLY_IWMMXT)
3761     ; /* No special preparation statements; expand pattern as above.  */
3762   else
3763     {
3764       rtx scratch1, scratch2;
3766       if (CONST_INT_P (operands[2])
3767           && (HOST_WIDE_INT) INTVAL (operands[2]) == 1)
3768         {
3769           emit_insn (gen_arm_ashldi3_1bit (operands[0], operands[1]));
3770           DONE;
3771         }
3773       /* Ideally we should use iwmmxt here if we could know that operands[1]
3774          ends up already living in an iwmmxt register. Otherwise it's
3775          cheaper to have the alternate code being generated than moving
3776          values to iwmmxt regs and back.  */
3778       /* If we're optimizing for size, we prefer the libgcc calls.  */
3779       if (optimize_function_for_size_p (cfun))
3780         FAIL;
3782       /* Expand operation using core-registers.
3783          'FAIL' would achieve the same thing, but this is a bit smarter.  */
3784       scratch1 = gen_reg_rtx (SImode);
3785       scratch2 = gen_reg_rtx (SImode);
3786       arm_emit_coreregs_64bit_shift (ASHIFT, operands[0], operands[1],
3787                                      operands[2], scratch1, scratch2);
3788       DONE;
3789     }
3790   "
3793 (define_insn "arm_ashldi3_1bit"
3794   [(set (match_operand:DI            0 "s_register_operand" "=r,&r")
3795         (ashift:DI (match_operand:DI 1 "s_register_operand" "0,r")
3796                    (const_int 1)))
3797    (clobber (reg:CC CC_REGNUM))]
3798   "TARGET_32BIT"
3799   "movs\\t%Q0, %Q1, asl #1\;adc\\t%R0, %R1, %R1"
3800   [(set_attr "conds" "clob")
3801    (set_attr "length" "8")
3802    (set_attr "type" "multiple")]
3805 (define_expand "ashlsi3"
3806   [(set (match_operand:SI            0 "s_register_operand" "")
3807         (ashift:SI (match_operand:SI 1 "s_register_operand" "")
3808                    (match_operand:SI 2 "arm_rhs_operand" "")))]
3809   "TARGET_EITHER"
3810   "
3811   if (CONST_INT_P (operands[2])
3812       && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) > 31)
3813     {
3814       emit_insn (gen_movsi (operands[0], const0_rtx));
3815       DONE;
3816     }
3817   "
3820 (define_expand "ashrdi3"
3821   [(set (match_operand:DI              0 "s_register_operand" "")
3822         (ashiftrt:DI (match_operand:DI 1 "s_register_operand" "")
3823                      (match_operand:SI 2 "reg_or_int_operand" "")))]
3824   "TARGET_32BIT"
3825   "
3826   if (TARGET_NEON)
3827     {
3828       /* Delay the decision whether to use NEON or core-regs until
3829          register allocation.  */
3830       emit_insn (gen_ashrdi3_neon (operands[0], operands[1], operands[2]));
3831       DONE;
3832     }
3834   if (!CONST_INT_P (operands[2]) && TARGET_REALLY_IWMMXT)
3835     ; /* No special preparation statements; expand pattern as above.  */
3836   else
3837     {
3838       rtx scratch1, scratch2;
3840       if (CONST_INT_P (operands[2])
3841           && (HOST_WIDE_INT) INTVAL (operands[2]) == 1)
3842         {
3843           emit_insn (gen_arm_ashrdi3_1bit (operands[0], operands[1]));
3844           DONE;
3845         }
3847       /* Ideally we should use iwmmxt here if we could know that operands[1]
3848          ends up already living in an iwmmxt register. Otherwise it's
3849          cheaper to have the alternate code being generated than moving
3850          values to iwmmxt regs and back.  */
3852       /* If we're optimizing for size, we prefer the libgcc calls.  */
3853       if (optimize_function_for_size_p (cfun))
3854         FAIL;
3856       /* Expand operation using core-registers.
3857          'FAIL' would achieve the same thing, but this is a bit smarter.  */
3858       scratch1 = gen_reg_rtx (SImode);
3859       scratch2 = gen_reg_rtx (SImode);
3860       arm_emit_coreregs_64bit_shift (ASHIFTRT, operands[0], operands[1],
3861                                      operands[2], scratch1, scratch2);
3862       DONE;
3863     }
3864   "
3867 (define_insn "arm_ashrdi3_1bit"
3868   [(set (match_operand:DI              0 "s_register_operand" "=r,&r")
3869         (ashiftrt:DI (match_operand:DI 1 "s_register_operand" "0,r")
3870                      (const_int 1)))
3871    (clobber (reg:CC CC_REGNUM))]
3872   "TARGET_32BIT"
3873   "movs\\t%R0, %R1, asr #1\;mov\\t%Q0, %Q1, rrx"
3874   [(set_attr "conds" "clob")
3875    (set_attr "length" "8")
3876    (set_attr "type" "multiple")]
3879 (define_expand "ashrsi3"
3880   [(set (match_operand:SI              0 "s_register_operand" "")
3881         (ashiftrt:SI (match_operand:SI 1 "s_register_operand" "")
3882                      (match_operand:SI 2 "arm_rhs_operand" "")))]
3883   "TARGET_EITHER"
3884   "
3885   if (CONST_INT_P (operands[2])
3886       && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) > 31)
3887     operands[2] = GEN_INT (31);
3888   "
3891 (define_expand "lshrdi3"
3892   [(set (match_operand:DI              0 "s_register_operand" "")
3893         (lshiftrt:DI (match_operand:DI 1 "s_register_operand" "")
3894                      (match_operand:SI 2 "reg_or_int_operand" "")))]
3895   "TARGET_32BIT"
3896   "
3897   if (TARGET_NEON)
3898     {
3899       /* Delay the decision whether to use NEON or core-regs until
3900          register allocation.  */
3901       emit_insn (gen_lshrdi3_neon (operands[0], operands[1], operands[2]));
3902       DONE;
3903     }
3905   if (!CONST_INT_P (operands[2]) && TARGET_REALLY_IWMMXT)
3906     ; /* No special preparation statements; expand pattern as above.  */
3907   else
3908     {
3909       rtx scratch1, scratch2;
3911       if (CONST_INT_P (operands[2])
3912           && (HOST_WIDE_INT) INTVAL (operands[2]) == 1)
3913         {
3914           emit_insn (gen_arm_lshrdi3_1bit (operands[0], operands[1]));
3915           DONE;
3916         }
3918       /* Ideally we should use iwmmxt here if we could know that operands[1]
3919          ends up already living in an iwmmxt register. Otherwise it's
3920          cheaper to have the alternate code being generated than moving
3921          values to iwmmxt regs and back.  */
3923       /* If we're optimizing for size, we prefer the libgcc calls.  */
3924       if (optimize_function_for_size_p (cfun))
3925         FAIL;
3927       /* Expand operation using core-registers.
3928          'FAIL' would achieve the same thing, but this is a bit smarter.  */
3929       scratch1 = gen_reg_rtx (SImode);
3930       scratch2 = gen_reg_rtx (SImode);
3931       arm_emit_coreregs_64bit_shift (LSHIFTRT, operands[0], operands[1],
3932                                      operands[2], scratch1, scratch2);
3933       DONE;
3934     }
3935   "
3938 (define_insn "arm_lshrdi3_1bit"
3939   [(set (match_operand:DI              0 "s_register_operand" "=r,&r")
3940         (lshiftrt:DI (match_operand:DI 1 "s_register_operand" "0,r")
3941                      (const_int 1)))
3942    (clobber (reg:CC CC_REGNUM))]
3943   "TARGET_32BIT"
3944   "movs\\t%R0, %R1, lsr #1\;mov\\t%Q0, %Q1, rrx"
3945   [(set_attr "conds" "clob")
3946    (set_attr "length" "8")
3947    (set_attr "type" "multiple")]
3950 (define_expand "lshrsi3"
3951   [(set (match_operand:SI              0 "s_register_operand" "")
3952         (lshiftrt:SI (match_operand:SI 1 "s_register_operand" "")
3953                      (match_operand:SI 2 "arm_rhs_operand" "")))]
3954   "TARGET_EITHER"
3955   "
3956   if (CONST_INT_P (operands[2])
3957       && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) > 31)
3958     {
3959       emit_insn (gen_movsi (operands[0], const0_rtx));
3960       DONE;
3961     }
3962   "
3965 (define_expand "rotlsi3"
3966   [(set (match_operand:SI              0 "s_register_operand" "")
3967         (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
3968                      (match_operand:SI 2 "reg_or_int_operand" "")))]
3969   "TARGET_32BIT"
3970   "
3971   if (CONST_INT_P (operands[2]))
3972     operands[2] = GEN_INT ((32 - INTVAL (operands[2])) % 32);
3973   else
3974     {
3975       rtx reg = gen_reg_rtx (SImode);
3976       emit_insn (gen_subsi3 (reg, GEN_INT (32), operands[2]));
3977       operands[2] = reg;
3978     }
3979   "
3982 (define_expand "rotrsi3"
3983   [(set (match_operand:SI              0 "s_register_operand" "")
3984         (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
3985                      (match_operand:SI 2 "arm_rhs_operand" "")))]
3986   "TARGET_EITHER"
3987   "
3988   if (TARGET_32BIT)
3989     {
3990       if (CONST_INT_P (operands[2])
3991           && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) > 31)
3992         operands[2] = GEN_INT (INTVAL (operands[2]) % 32);
3993     }
3994   else /* TARGET_THUMB1 */
3995     {
3996       if (CONST_INT_P (operands [2]))
3997         operands [2] = force_reg (SImode, operands[2]);
3998     }
3999   "
4002 (define_insn "*arm_shiftsi3"
4003   [(set (match_operand:SI   0 "s_register_operand" "=l,l,r,r")
4004         (match_operator:SI  3 "shift_operator"
4005          [(match_operand:SI 1 "s_register_operand"  "0,l,r,r")
4006           (match_operand:SI 2 "reg_or_int_operand" "l,M,M,r")]))]
4007   "TARGET_32BIT"
4008   "* return arm_output_shift(operands, 0);"
4009   [(set_attr "predicable" "yes")
4010    (set_attr "arch" "t2,t2,*,*")
4011    (set_attr "predicable_short_it" "yes,yes,no,no")
4012    (set_attr "length" "4")
4013    (set_attr "shift" "1")
4014    (set_attr "type" "alu_shift_reg,alu_shift_imm,alu_shift_imm,alu_shift_reg")]
4017 (define_insn "*shiftsi3_compare0"
4018   [(set (reg:CC_NOOV CC_REGNUM)
4019         (compare:CC_NOOV (match_operator:SI 3 "shift_operator"
4020                           [(match_operand:SI 1 "s_register_operand" "r,r")
4021                            (match_operand:SI 2 "arm_rhs_operand" "M,r")])
4022                          (const_int 0)))
4023    (set (match_operand:SI 0 "s_register_operand" "=r,r")
4024         (match_op_dup 3 [(match_dup 1) (match_dup 2)]))]
4025   "TARGET_32BIT"
4026   "* return arm_output_shift(operands, 1);"
4027   [(set_attr "conds" "set")
4028    (set_attr "shift" "1")
4029    (set_attr "type" "alus_shift_imm,alus_shift_reg")]
4032 (define_insn "*shiftsi3_compare0_scratch"
4033   [(set (reg:CC_NOOV CC_REGNUM)
4034         (compare:CC_NOOV (match_operator:SI 3 "shift_operator"
4035                           [(match_operand:SI 1 "s_register_operand" "r,r")
4036                            (match_operand:SI 2 "arm_rhs_operand" "M,r")])
4037                          (const_int 0)))
4038    (clobber (match_scratch:SI 0 "=r,r"))]
4039   "TARGET_32BIT"
4040   "* return arm_output_shift(operands, 1);"
4041   [(set_attr "conds" "set")
4042    (set_attr "shift" "1")
4043    (set_attr "type" "shift_imm,shift_reg")]
4046 (define_insn "*not_shiftsi"
4047   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4048         (not:SI (match_operator:SI 3 "shift_operator"
4049                  [(match_operand:SI 1 "s_register_operand" "r,r")
4050                   (match_operand:SI 2 "shift_amount_operand" "M,rM")])))]
4051   "TARGET_32BIT"
4052   "mvn%?\\t%0, %1%S3"
4053   [(set_attr "predicable" "yes")
4054    (set_attr "predicable_short_it" "no")
4055    (set_attr "shift" "1")
4056    (set_attr "arch" "32,a")
4057    (set_attr "type" "mvn_shift,mvn_shift_reg")])
4059 (define_insn "*not_shiftsi_compare0"
4060   [(set (reg:CC_NOOV CC_REGNUM)
4061         (compare:CC_NOOV
4062          (not:SI (match_operator:SI 3 "shift_operator"
4063                   [(match_operand:SI 1 "s_register_operand" "r,r")
4064                    (match_operand:SI 2 "shift_amount_operand" "M,rM")]))
4065          (const_int 0)))
4066    (set (match_operand:SI 0 "s_register_operand" "=r,r")
4067         (not:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])))]
4068   "TARGET_32BIT"
4069   "mvn%.\\t%0, %1%S3"
4070   [(set_attr "conds" "set")
4071    (set_attr "shift" "1")
4072    (set_attr "arch" "32,a")
4073    (set_attr "type" "mvn_shift,mvn_shift_reg")])
4075 (define_insn "*not_shiftsi_compare0_scratch"
4076   [(set (reg:CC_NOOV CC_REGNUM)
4077         (compare:CC_NOOV
4078          (not:SI (match_operator:SI 3 "shift_operator"
4079                   [(match_operand:SI 1 "s_register_operand" "r,r")
4080                    (match_operand:SI 2 "shift_amount_operand" "M,rM")]))
4081          (const_int 0)))
4082    (clobber (match_scratch:SI 0 "=r,r"))]
4083   "TARGET_32BIT"
4084   "mvn%.\\t%0, %1%S3"
4085   [(set_attr "conds" "set")
4086    (set_attr "shift" "1")
4087    (set_attr "arch" "32,a")
4088    (set_attr "type" "mvn_shift,mvn_shift_reg")])
4090 ;; We don't really have extzv, but defining this using shifts helps
4091 ;; to reduce register pressure later on.
4093 (define_expand "extzv"
4094   [(set (match_operand 0 "s_register_operand" "")
4095         (zero_extract (match_operand 1 "nonimmediate_operand" "")
4096                       (match_operand 2 "const_int_operand" "")
4097                       (match_operand 3 "const_int_operand" "")))]
4098   "TARGET_THUMB1 || arm_arch_thumb2"
4099   "
4100   {
4101     HOST_WIDE_INT lshift = 32 - INTVAL (operands[2]) - INTVAL (operands[3]);
4102     HOST_WIDE_INT rshift = 32 - INTVAL (operands[2]);
4103     
4104     if (arm_arch_thumb2)
4105       {
4106         HOST_WIDE_INT width = INTVAL (operands[2]);
4107         HOST_WIDE_INT bitpos = INTVAL (operands[3]);
4109         if (unaligned_access && MEM_P (operands[1])
4110             && (width == 16 || width == 32) && (bitpos % BITS_PER_UNIT) == 0)
4111           {
4112             rtx base_addr;
4114             if (BYTES_BIG_ENDIAN)
4115               bitpos = GET_MODE_BITSIZE (GET_MODE (operands[0])) - width
4116                        - bitpos;
4118             if (width == 32)
4119               {
4120                 base_addr = adjust_address (operands[1], SImode,
4121                                             bitpos / BITS_PER_UNIT);
4122                 emit_insn (gen_unaligned_loadsi (operands[0], base_addr));
4123               }
4124             else
4125               {
4126                 rtx dest = operands[0];
4127                 rtx tmp = gen_reg_rtx (SImode);
4129                 /* We may get a paradoxical subreg here.  Strip it off.  */
4130                 if (GET_CODE (dest) == SUBREG
4131                     && GET_MODE (dest) == SImode
4132                     && GET_MODE (SUBREG_REG (dest)) == HImode)
4133                   dest = SUBREG_REG (dest);
4135                 if (GET_MODE_BITSIZE (GET_MODE (dest)) != width)
4136                   FAIL;
4138                 base_addr = adjust_address (operands[1], HImode,
4139                                             bitpos / BITS_PER_UNIT);
4140                 emit_insn (gen_unaligned_loadhiu (tmp, base_addr));
4141                 emit_move_insn (gen_lowpart (SImode, dest), tmp);
4142               }
4143             DONE;
4144           }
4145         else if (s_register_operand (operands[1], GET_MODE (operands[1])))
4146           {
4147             emit_insn (gen_extzv_t2 (operands[0], operands[1], operands[2],
4148                                      operands[3]));
4149             DONE;
4150           }
4151         else
4152           FAIL;
4153       }
4154     
4155     if (!s_register_operand (operands[1], GET_MODE (operands[1])))
4156       FAIL;
4158     operands[3] = GEN_INT (rshift);
4159     
4160     if (lshift == 0)
4161       {
4162         emit_insn (gen_lshrsi3 (operands[0], operands[1], operands[3]));
4163         DONE;
4164       }
4165       
4166     emit_insn (gen_extzv_t1 (operands[0], operands[1], GEN_INT (lshift),
4167                              operands[3], gen_reg_rtx (SImode)));
4168     DONE;
4169   }"
4172 ;; Helper for extzv, for the Thumb-1 register-shifts case.
4174 (define_expand "extzv_t1"
4175   [(set (match_operand:SI 4 "s_register_operand" "")
4176         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
4177                    (match_operand:SI 2 "const_int_operand" "")))
4178    (set (match_operand:SI 0 "s_register_operand" "")
4179         (lshiftrt:SI (match_dup 4)
4180                      (match_operand:SI 3 "const_int_operand" "")))]
4181   "TARGET_THUMB1"
4182   "")
4184 (define_expand "extv"
4185   [(set (match_operand 0 "s_register_operand" "")
4186         (sign_extract (match_operand 1 "nonimmediate_operand" "")
4187                       (match_operand 2 "const_int_operand" "")
4188                       (match_operand 3 "const_int_operand" "")))]
4189   "arm_arch_thumb2"
4191   HOST_WIDE_INT width = INTVAL (operands[2]);
4192   HOST_WIDE_INT bitpos = INTVAL (operands[3]);
4194   if (unaligned_access && MEM_P (operands[1]) && (width == 16 || width == 32)
4195       && (bitpos % BITS_PER_UNIT)  == 0)
4196     {
4197       rtx base_addr;
4198       
4199       if (BYTES_BIG_ENDIAN)
4200         bitpos = GET_MODE_BITSIZE (GET_MODE (operands[0])) - width - bitpos;
4201       
4202       if (width == 32)
4203         {
4204           base_addr = adjust_address (operands[1], SImode,
4205                                       bitpos / BITS_PER_UNIT);
4206           emit_insn (gen_unaligned_loadsi (operands[0], base_addr));
4207         }
4208       else
4209         {
4210           rtx dest = operands[0];
4211           rtx tmp = gen_reg_rtx (SImode);
4212           
4213           /* We may get a paradoxical subreg here.  Strip it off.  */
4214           if (GET_CODE (dest) == SUBREG
4215               && GET_MODE (dest) == SImode
4216               && GET_MODE (SUBREG_REG (dest)) == HImode)
4217             dest = SUBREG_REG (dest);
4218           
4219           if (GET_MODE_BITSIZE (GET_MODE (dest)) != width)
4220             FAIL;
4221           
4222           base_addr = adjust_address (operands[1], HImode,
4223                                       bitpos / BITS_PER_UNIT);
4224           emit_insn (gen_unaligned_loadhis (tmp, base_addr));
4225           emit_move_insn (gen_lowpart (SImode, dest), tmp);
4226         }
4228       DONE;
4229     }
4230   else if (!s_register_operand (operands[1], GET_MODE (operands[1])))
4231     FAIL;
4232   else if (GET_MODE (operands[0]) == SImode
4233            && GET_MODE (operands[1]) == SImode)
4234     {
4235       emit_insn (gen_extv_regsi (operands[0], operands[1], operands[2],
4236                                  operands[3]));
4237       DONE;
4238     }
4240   FAIL;
4243 ; Helper to expand register forms of extv with the proper modes.
4245 (define_expand "extv_regsi"
4246   [(set (match_operand:SI 0 "s_register_operand" "")
4247         (sign_extract:SI (match_operand:SI 1 "s_register_operand" "")
4248                          (match_operand 2 "const_int_operand" "")
4249                          (match_operand 3 "const_int_operand" "")))]
4250   ""
4254 ; ARMv6+ unaligned load/store instructions (used for packed structure accesses).
4256 (define_insn "unaligned_loadsi"
4257   [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4258         (unspec:SI [(match_operand:SI 1 "memory_operand" "Uw,m")]
4259                    UNSPEC_UNALIGNED_LOAD))]
4260   "unaligned_access && TARGET_32BIT"
4261   "ldr%?\t%0, %1\t@ unaligned"
4262   [(set_attr "arch" "t2,any")
4263    (set_attr "length" "2,4")
4264    (set_attr "predicable" "yes")
4265    (set_attr "predicable_short_it" "yes,no")
4266    (set_attr "type" "load1")])
4268 (define_insn "unaligned_loadhis"
4269   [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4270         (sign_extend:SI
4271           (unspec:HI [(match_operand:HI 1 "memory_operand" "Uw,Uh")]
4272                      UNSPEC_UNALIGNED_LOAD)))]
4273   "unaligned_access && TARGET_32BIT"
4274   "ldr%(sh%)\t%0, %1\t@ unaligned"
4275   [(set_attr "arch" "t2,any")
4276    (set_attr "length" "2,4")
4277    (set_attr "predicable" "yes")
4278    (set_attr "predicable_short_it" "yes,no")
4279    (set_attr "type" "load_byte")])
4281 (define_insn "unaligned_loadhiu"
4282   [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4283         (zero_extend:SI
4284           (unspec:HI [(match_operand:HI 1 "memory_operand" "Uw,m")]
4285                      UNSPEC_UNALIGNED_LOAD)))]
4286   "unaligned_access && TARGET_32BIT"
4287   "ldr%(h%)\t%0, %1\t@ unaligned"
4288   [(set_attr "arch" "t2,any")
4289    (set_attr "length" "2,4")
4290    (set_attr "predicable" "yes")
4291    (set_attr "predicable_short_it" "yes,no")
4292    (set_attr "type" "load_byte")])
4294 (define_insn "unaligned_storesi"
4295   [(set (match_operand:SI 0 "memory_operand" "=Uw,m")
4296         (unspec:SI [(match_operand:SI 1 "s_register_operand" "l,r")]
4297                    UNSPEC_UNALIGNED_STORE))]
4298   "unaligned_access && TARGET_32BIT"
4299   "str%?\t%1, %0\t@ unaligned"
4300   [(set_attr "arch" "t2,any")
4301    (set_attr "length" "2,4")
4302    (set_attr "predicable" "yes")
4303    (set_attr "predicable_short_it" "yes,no")
4304    (set_attr "type" "store1")])
4306 (define_insn "unaligned_storehi"
4307   [(set (match_operand:HI 0 "memory_operand" "=Uw,m")
4308         (unspec:HI [(match_operand:HI 1 "s_register_operand" "l,r")]
4309                    UNSPEC_UNALIGNED_STORE))]
4310   "unaligned_access && TARGET_32BIT"
4311   "str%(h%)\t%1, %0\t@ unaligned"
4312   [(set_attr "arch" "t2,any")
4313    (set_attr "length" "2,4")
4314    (set_attr "predicable" "yes")
4315    (set_attr "predicable_short_it" "yes,no")
4316    (set_attr "type" "store1")])
4318 ;; Unaligned double-word load and store.
4319 ;; Split after reload into two unaligned single-word accesses.
4320 ;; It prevents lower_subreg from splitting some other aligned
4321 ;; double-word accesses too early. Used for internal memcpy.
4323 (define_insn_and_split "unaligned_loaddi"
4324   [(set (match_operand:DI 0 "s_register_operand" "=l,r")
4325         (unspec:DI [(match_operand:DI 1 "memory_operand" "o,o")]
4326                    UNSPEC_UNALIGNED_LOAD))]
4327   "unaligned_access && TARGET_32BIT"
4328   "#"
4329   "&& reload_completed"
4330   [(set (match_dup 0) (unspec:SI [(match_dup 1)] UNSPEC_UNALIGNED_LOAD))
4331    (set (match_dup 2) (unspec:SI [(match_dup 3)] UNSPEC_UNALIGNED_LOAD))]
4332   {
4333     operands[2] = gen_highpart (SImode, operands[0]);
4334     operands[0] = gen_lowpart (SImode, operands[0]);
4335     operands[3] = gen_highpart (SImode, operands[1]);
4336     operands[1] = gen_lowpart (SImode, operands[1]);
4338     /* If the first destination register overlaps with the base address,
4339        swap the order in which the loads are emitted.  */
4340     if (reg_overlap_mentioned_p (operands[0], operands[1]))
4341       {
4342         std::swap (operands[1], operands[3]);
4343         std::swap (operands[0], operands[2]);
4344       }
4345   }
4346   [(set_attr "arch" "t2,any")
4347    (set_attr "length" "4,8")
4348    (set_attr "predicable" "yes")
4349    (set_attr "type" "load2")])
4351 (define_insn_and_split "unaligned_storedi"
4352   [(set (match_operand:DI 0 "memory_operand" "=o,o")
4353         (unspec:DI [(match_operand:DI 1 "s_register_operand" "l,r")]
4354                    UNSPEC_UNALIGNED_STORE))]
4355   "unaligned_access && TARGET_32BIT"
4356   "#"
4357   "&& reload_completed"
4358   [(set (match_dup 0) (unspec:SI [(match_dup 1)] UNSPEC_UNALIGNED_STORE))
4359    (set (match_dup 2) (unspec:SI [(match_dup 3)] UNSPEC_UNALIGNED_STORE))]
4360   {
4361     operands[2] = gen_highpart (SImode, operands[0]);
4362     operands[0] = gen_lowpart (SImode, operands[0]);
4363     operands[3] = gen_highpart (SImode, operands[1]);
4364     operands[1] = gen_lowpart (SImode, operands[1]);
4365   }
4366   [(set_attr "arch" "t2,any")
4367    (set_attr "length" "4,8")
4368    (set_attr "predicable" "yes")
4369    (set_attr "type" "store2")])
4372 (define_insn "*extv_reg"
4373   [(set (match_operand:SI 0 "s_register_operand" "=r")
4374         (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
4375                          (match_operand:SI 2 "const_int_M_operand" "M")
4376                          (match_operand:SI 3 "const_int_M_operand" "M")))]
4377   "arm_arch_thumb2"
4378   "sbfx%?\t%0, %1, %3, %2"
4379   [(set_attr "length" "4")
4380    (set_attr "predicable" "yes")
4381    (set_attr "predicable_short_it" "no")
4382    (set_attr "type" "bfm")]
4385 (define_insn "extzv_t2"
4386   [(set (match_operand:SI 0 "s_register_operand" "=r")
4387         (zero_extract:SI (match_operand:SI 1 "s_register_operand" "r")
4388                          (match_operand:SI 2 "const_int_M_operand" "M")
4389                          (match_operand:SI 3 "const_int_M_operand" "M")))]
4390   "arm_arch_thumb2"
4391   "ubfx%?\t%0, %1, %3, %2"
4392   [(set_attr "length" "4")
4393    (set_attr "predicable" "yes")
4394    (set_attr "predicable_short_it" "no")
4395    (set_attr "type" "bfm")]
4399 ;; Division instructions
4400 (define_insn "divsi3"
4401   [(set (match_operand:SI         0 "s_register_operand" "=r")
4402         (div:SI (match_operand:SI 1 "s_register_operand"  "r")
4403                 (match_operand:SI 2 "s_register_operand"  "r")))]
4404   "TARGET_IDIV"
4405   "sdiv%?\t%0, %1, %2"
4406   [(set_attr "predicable" "yes")
4407    (set_attr "predicable_short_it" "no")
4408    (set_attr "type" "sdiv")]
4411 (define_insn "udivsi3"
4412   [(set (match_operand:SI          0 "s_register_operand" "=r")
4413         (udiv:SI (match_operand:SI 1 "s_register_operand"  "r")
4414                  (match_operand:SI 2 "s_register_operand"  "r")))]
4415   "TARGET_IDIV"
4416   "udiv%?\t%0, %1, %2"
4417   [(set_attr "predicable" "yes")
4418    (set_attr "predicable_short_it" "no")
4419    (set_attr "type" "udiv")]
4423 ;; Unary arithmetic insns
4425 (define_expand "negdi2"
4426  [(parallel
4427    [(set (match_operand:DI 0 "s_register_operand" "")
4428          (neg:DI (match_operand:DI 1 "s_register_operand" "")))
4429     (clobber (reg:CC CC_REGNUM))])]
4430   "TARGET_EITHER"
4431   {
4432     if (TARGET_NEON)
4433       {
4434         emit_insn (gen_negdi2_neon (operands[0], operands[1]));
4435         DONE;
4436       }
4437   }
4440 ;; The constraints here are to prevent a *partial* overlap (where %Q0 == %R1).
4441 ;; The first alternative allows the common case of a *full* overlap.
4442 (define_insn_and_split "*arm_negdi2"
4443   [(set (match_operand:DI         0 "s_register_operand" "=r,&r")
4444         (neg:DI (match_operand:DI 1 "s_register_operand"  "0,r")))
4445    (clobber (reg:CC CC_REGNUM))]
4446   "TARGET_ARM"
4447   "#"   ; "rsbs\\t%Q0, %Q1, #0\;rsc\\t%R0, %R1, #0"
4448   "&& reload_completed"
4449   [(parallel [(set (reg:CC CC_REGNUM)
4450                    (compare:CC (const_int 0) (match_dup 1)))
4451               (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1)))])
4452    (set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3))
4453                                 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
4454   {
4455     operands[2] = gen_highpart (SImode, operands[0]);
4456     operands[0] = gen_lowpart (SImode, operands[0]);
4457     operands[3] = gen_highpart (SImode, operands[1]);
4458     operands[1] = gen_lowpart (SImode, operands[1]);
4459   }
4460   [(set_attr "conds" "clob")
4461    (set_attr "length" "8")
4462    (set_attr "type" "multiple")]
4465 (define_expand "negsi2"
4466   [(set (match_operand:SI         0 "s_register_operand" "")
4467         (neg:SI (match_operand:SI 1 "s_register_operand" "")))]
4468   "TARGET_EITHER"
4469   ""
4472 (define_insn "*arm_negsi2"
4473   [(set (match_operand:SI         0 "s_register_operand" "=l,r")
4474         (neg:SI (match_operand:SI 1 "s_register_operand" "l,r")))]
4475   "TARGET_32BIT"
4476   "rsb%?\\t%0, %1, #0"
4477   [(set_attr "predicable" "yes")
4478    (set_attr "predicable_short_it" "yes,no")
4479    (set_attr "arch" "t2,*")
4480    (set_attr "length" "4")
4481    (set_attr "type" "alu_sreg")]
4484 (define_expand "negsf2"
4485   [(set (match_operand:SF         0 "s_register_operand" "")
4486         (neg:SF (match_operand:SF 1 "s_register_operand" "")))]
4487   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
4488   ""
4491 (define_expand "negdf2"
4492   [(set (match_operand:DF         0 "s_register_operand" "")
4493         (neg:DF (match_operand:DF 1 "s_register_operand" "")))]
4494   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
4495   "")
4497 (define_insn_and_split "*zextendsidi_negsi"
4498   [(set (match_operand:DI 0 "s_register_operand" "=r")
4499         (zero_extend:DI (neg:SI (match_operand:SI 1 "s_register_operand" "r"))))]
4500    "TARGET_32BIT"
4501    "#"
4502    ""
4503    [(set (match_dup 2)
4504          (neg:SI (match_dup 1)))
4505     (set (match_dup 3)
4506          (const_int 0))]
4507    {
4508       operands[2] = gen_lowpart (SImode, operands[0]);
4509       operands[3] = gen_highpart (SImode, operands[0]);
4510    }
4511  [(set_attr "length" "8")
4512   (set_attr "type" "multiple")]
4515 ;; Negate an extended 32-bit value.
4516 (define_insn_and_split "*negdi_extendsidi"
4517   [(set (match_operand:DI 0 "s_register_operand" "=l,r")
4518         (neg:DI (sign_extend:DI
4519                  (match_operand:SI 1 "s_register_operand" "l,r"))))
4520    (clobber (reg:CC CC_REGNUM))]
4521   "TARGET_32BIT"
4522   "#"
4523   "&& reload_completed"
4524   [(const_int 0)]
4525   {
4526     rtx low = gen_lowpart (SImode, operands[0]);
4527     rtx high = gen_highpart (SImode, operands[0]);
4529     if (reg_overlap_mentioned_p (low, operands[1]))
4530       {
4531         /* Input overlaps the low word of the output.  Use:
4532                 asr     Rhi, Rin, #31
4533                 rsbs    Rlo, Rin, #0
4534                 rsc     Rhi, Rhi, #0 (thumb2: sbc Rhi, Rhi, Rhi, lsl #1).  */
4535         rtx cc_reg = gen_rtx_REG (CC_Cmode, CC_REGNUM);
4537         emit_insn (gen_rtx_SET (high,
4538                                 gen_rtx_ASHIFTRT (SImode, operands[1],
4539                                                   GEN_INT (31))));
4541         emit_insn (gen_subsi3_compare (low, const0_rtx, operands[1]));
4542         if (TARGET_ARM)
4543           emit_insn (gen_rtx_SET (high,
4544                                   gen_rtx_MINUS (SImode,
4545                                                  gen_rtx_MINUS (SImode,
4546                                                                 const0_rtx,
4547                                                                 high),
4548                                                  gen_rtx_LTU (SImode,
4549                                                               cc_reg,
4550                                                               const0_rtx))));
4551         else
4552           {
4553             rtx two_x = gen_rtx_ASHIFT (SImode, high, GEN_INT (1));
4554             emit_insn (gen_rtx_SET (high,
4555                                     gen_rtx_MINUS (SImode,
4556                                                    gen_rtx_MINUS (SImode,
4557                                                                   high,
4558                                                                   two_x),
4559                                                    gen_rtx_LTU (SImode,
4560                                                                 cc_reg,
4561                                                                 const0_rtx))));
4562           }
4563       }
4564     else
4565       {
4566         /* No overlap, or overlap on high word.  Use:
4567                 rsb     Rlo, Rin, #0
4568                 bic     Rhi, Rlo, Rin
4569                 asr     Rhi, Rhi, #31
4570            Flags not needed for this sequence.  */
4571         emit_insn (gen_rtx_SET (low, gen_rtx_NEG (SImode, operands[1])));
4572         emit_insn (gen_rtx_SET (high,
4573                                 gen_rtx_AND (SImode,
4574                                              gen_rtx_NOT (SImode, operands[1]),
4575                                              low)));
4576         emit_insn (gen_rtx_SET (high,
4577                                 gen_rtx_ASHIFTRT (SImode, high,
4578                                                   GEN_INT (31))));
4579       }
4580     DONE;
4581   }
4582   [(set_attr "length" "12")
4583    (set_attr "arch" "t2,*")
4584    (set_attr "type" "multiple")]
4587 (define_insn_and_split "*negdi_zero_extendsidi"
4588   [(set (match_operand:DI 0 "s_register_operand" "=r,&r")
4589         (neg:DI (zero_extend:DI (match_operand:SI 1 "s_register_operand" "0,r"))))
4590    (clobber (reg:CC CC_REGNUM))]
4591   "TARGET_32BIT"
4592   "#" ; "rsbs\\t%Q0, %1, #0\;sbc\\t%R0,%R0,%R0"
4593       ;; Don't care what register is input to sbc,
4594       ;; since we just need to propagate the carry.
4595   "&& reload_completed"
4596   [(parallel [(set (reg:CC CC_REGNUM)
4597                    (compare:CC (const_int 0) (match_dup 1)))
4598               (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1)))])
4599    (set (match_dup 2) (minus:SI (minus:SI (match_dup 2) (match_dup 2))
4600                                 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
4601   {
4602     operands[2] = gen_highpart (SImode, operands[0]);
4603     operands[0] = gen_lowpart (SImode, operands[0]);
4604   }
4605   [(set_attr "conds" "clob")
4606    (set_attr "length" "8")
4607    (set_attr "type" "multiple")]   ;; length in thumb is 4
4610 ;; abssi2 doesn't really clobber the condition codes if a different register
4611 ;; is being set.  To keep things simple, assume during rtl manipulations that
4612 ;; it does, but tell the final scan operator the truth.  Similarly for
4613 ;; (neg (abs...))
4615 (define_expand "abssi2"
4616   [(parallel
4617     [(set (match_operand:SI         0 "s_register_operand" "")
4618           (abs:SI (match_operand:SI 1 "s_register_operand" "")))
4619      (clobber (match_dup 2))])]
4620   "TARGET_EITHER"
4621   "
4622   if (TARGET_THUMB1)
4623     operands[2] = gen_rtx_SCRATCH (SImode);
4624   else
4625     operands[2] = gen_rtx_REG (CCmode, CC_REGNUM);
4628 (define_insn_and_split "*arm_abssi2"
4629   [(set (match_operand:SI 0 "s_register_operand" "=r,&r")
4630         (abs:SI (match_operand:SI 1 "s_register_operand" "0,r")))
4631    (clobber (reg:CC CC_REGNUM))]
4632   "TARGET_ARM"
4633   "#"
4634   "&& reload_completed"
4635   [(const_int 0)]
4636   {
4637    /* if (which_alternative == 0) */
4638    if (REGNO(operands[0]) == REGNO(operands[1]))
4639      {
4640       /* Emit the pattern:
4641          cmp\\t%0, #0\;rsblt\\t%0, %0, #0
4642          [(set (reg:CC CC_REGNUM)
4643                (compare:CC (match_dup 0) (const_int 0)))
4644           (cond_exec (lt:CC (reg:CC CC_REGNUM) (const_int 0))
4645                      (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1))))]
4646       */
4647       emit_insn (gen_rtx_SET (gen_rtx_REG (CCmode, CC_REGNUM),
4648                               gen_rtx_COMPARE (CCmode, operands[0], const0_rtx)));
4649       emit_insn (gen_rtx_COND_EXEC (VOIDmode,
4650                                     (gen_rtx_LT (SImode,
4651                                                  gen_rtx_REG (CCmode, CC_REGNUM),
4652                                                  const0_rtx)),
4653                                     (gen_rtx_SET (operands[0],
4654                                                   (gen_rtx_MINUS (SImode,
4655                                                                   const0_rtx,
4656                                                                   operands[1]))))));
4657       DONE;
4658      }
4659    else
4660      {
4661       /* Emit the pattern:
4662          alt1: eor%?\\t%0, %1, %1, asr #31\;sub%?\\t%0, %0, %1, asr #31
4663          [(set (match_dup 0)
4664                (xor:SI (match_dup 1)
4665                        (ashiftrt:SI (match_dup 1) (const_int 31))))
4666           (set (match_dup 0)
4667                (minus:SI (match_dup 0)
4668                       (ashiftrt:SI (match_dup 1) (const_int 31))))]
4669       */
4670       emit_insn (gen_rtx_SET (operands[0],
4671                               gen_rtx_XOR (SImode,
4672                                            gen_rtx_ASHIFTRT (SImode,
4673                                                              operands[1],
4674                                                              GEN_INT (31)),
4675                                            operands[1])));
4676       emit_insn (gen_rtx_SET (operands[0],
4677                               gen_rtx_MINUS (SImode,
4678                                              operands[0],
4679                                              gen_rtx_ASHIFTRT (SImode,
4680                                                                operands[1],
4681                                                                GEN_INT (31)))));
4682       DONE;
4683      }
4684   }
4685   [(set_attr "conds" "clob,*")
4686    (set_attr "shift" "1")
4687    (set_attr "predicable" "no, yes")
4688    (set_attr "length" "8")
4689    (set_attr "type" "multiple")]
4692 (define_insn_and_split "*arm_neg_abssi2"
4693   [(set (match_operand:SI 0 "s_register_operand" "=r,&r")
4694         (neg:SI (abs:SI (match_operand:SI 1 "s_register_operand" "0,r"))))
4695    (clobber (reg:CC CC_REGNUM))]
4696   "TARGET_ARM"
4697   "#"
4698   "&& reload_completed"
4699   [(const_int 0)]
4700   {
4701    /* if (which_alternative == 0) */
4702    if (REGNO (operands[0]) == REGNO (operands[1]))
4703      {
4704       /* Emit the pattern:
4705          cmp\\t%0, #0\;rsbgt\\t%0, %0, #0
4706       */
4707       emit_insn (gen_rtx_SET (gen_rtx_REG (CCmode, CC_REGNUM),
4708                               gen_rtx_COMPARE (CCmode, operands[0], const0_rtx)));
4709       emit_insn (gen_rtx_COND_EXEC (VOIDmode,
4710                                     gen_rtx_GT (SImode,
4711                                                 gen_rtx_REG (CCmode, CC_REGNUM),
4712                                                 const0_rtx),
4713                                     gen_rtx_SET (operands[0],
4714                                                  (gen_rtx_MINUS (SImode,
4715                                                                  const0_rtx,
4716                                                                  operands[1])))));
4717      }
4718    else
4719      {
4720       /* Emit the pattern:
4721          eor%?\\t%0, %1, %1, asr #31\;rsb%?\\t%0, %0, %1, asr #31
4722       */
4723       emit_insn (gen_rtx_SET (operands[0],
4724                               gen_rtx_XOR (SImode,
4725                                            gen_rtx_ASHIFTRT (SImode,
4726                                                              operands[1],
4727                                                              GEN_INT (31)),
4728                                            operands[1])));
4729       emit_insn (gen_rtx_SET (operands[0],
4730                               gen_rtx_MINUS (SImode,
4731                                              gen_rtx_ASHIFTRT (SImode,
4732                                                                operands[1],
4733                                                                GEN_INT (31)),
4734                                              operands[0])));
4735      }
4736    DONE;
4737   }
4738   [(set_attr "conds" "clob,*")
4739    (set_attr "shift" "1")
4740    (set_attr "predicable" "no, yes")
4741    (set_attr "length" "8")
4742    (set_attr "type" "multiple")]
4745 (define_expand "abssf2"
4746   [(set (match_operand:SF         0 "s_register_operand" "")
4747         (abs:SF (match_operand:SF 1 "s_register_operand" "")))]
4748   "TARGET_32BIT && TARGET_HARD_FLOAT"
4749   "")
4751 (define_expand "absdf2"
4752   [(set (match_operand:DF         0 "s_register_operand" "")
4753         (abs:DF (match_operand:DF 1 "s_register_operand" "")))]
4754   "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
4755   "")
4757 (define_expand "sqrtsf2"
4758   [(set (match_operand:SF 0 "s_register_operand" "")
4759         (sqrt:SF (match_operand:SF 1 "s_register_operand" "")))]
4760   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
4761   "")
4763 (define_expand "sqrtdf2"
4764   [(set (match_operand:DF 0 "s_register_operand" "")
4765         (sqrt:DF (match_operand:DF 1 "s_register_operand" "")))]
4766   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
4767   "")
4769 (define_insn_and_split "one_cmpldi2"
4770   [(set (match_operand:DI 0 "s_register_operand"         "=w,&r,&r,?w")
4771         (not:DI (match_operand:DI 1 "s_register_operand" " w, 0, r, w")))]
4772   "TARGET_32BIT"
4773   "@
4774    vmvn\t%P0, %P1
4775    #
4776    #
4777    vmvn\t%P0, %P1"
4778   "TARGET_32BIT && reload_completed
4779    && arm_general_register_operand (operands[0], DImode)"
4780   [(set (match_dup 0) (not:SI (match_dup 1)))
4781    (set (match_dup 2) (not:SI (match_dup 3)))]
4782   "
4783   {
4784     operands[2] = gen_highpart (SImode, operands[0]);
4785     operands[0] = gen_lowpart (SImode, operands[0]);
4786     operands[3] = gen_highpart (SImode, operands[1]);
4787     operands[1] = gen_lowpart (SImode, operands[1]);
4788   }"
4789   [(set_attr "length" "*,8,8,*")
4790    (set_attr "predicable" "no,yes,yes,no")
4791    (set_attr "type" "neon_move,multiple,multiple,neon_move")
4792    (set_attr "arch" "neon_for_64bits,*,*,avoid_neon_for_64bits")]
4795 (define_expand "one_cmplsi2"
4796   [(set (match_operand:SI         0 "s_register_operand" "")
4797         (not:SI (match_operand:SI 1 "s_register_operand" "")))]
4798   "TARGET_EITHER"
4799   ""
4802 (define_insn "*arm_one_cmplsi2"
4803   [(set (match_operand:SI         0 "s_register_operand" "=l,r")
4804         (not:SI (match_operand:SI 1 "s_register_operand"  "l,r")))]
4805   "TARGET_32BIT"
4806   "mvn%?\\t%0, %1"
4807   [(set_attr "predicable" "yes")
4808    (set_attr "predicable_short_it" "yes,no")
4809    (set_attr "arch" "t2,*")
4810    (set_attr "length" "4")
4811    (set_attr "type" "mvn_reg")]
4814 (define_insn "*notsi_compare0"
4815   [(set (reg:CC_NOOV CC_REGNUM)
4816         (compare:CC_NOOV (not:SI (match_operand:SI 1 "s_register_operand" "r"))
4817                          (const_int 0)))
4818    (set (match_operand:SI 0 "s_register_operand" "=r")
4819         (not:SI (match_dup 1)))]
4820   "TARGET_32BIT"
4821   "mvn%.\\t%0, %1"
4822   [(set_attr "conds" "set")
4823    (set_attr "type" "mvn_reg")]
4826 (define_insn "*notsi_compare0_scratch"
4827   [(set (reg:CC_NOOV CC_REGNUM)
4828         (compare:CC_NOOV (not:SI (match_operand:SI 1 "s_register_operand" "r"))
4829                          (const_int 0)))
4830    (clobber (match_scratch:SI 0 "=r"))]
4831   "TARGET_32BIT"
4832   "mvn%.\\t%0, %1"
4833   [(set_attr "conds" "set")
4834    (set_attr "type" "mvn_reg")]
4837 ;; Fixed <--> Floating conversion insns
4839 (define_expand "floatsihf2"
4840   [(set (match_operand:HF           0 "general_operand" "")
4841         (float:HF (match_operand:SI 1 "general_operand" "")))]
4842   "TARGET_EITHER"
4843   "
4844   {
4845     rtx op1 = gen_reg_rtx (SFmode);
4846     expand_float (op1, operands[1], 0);
4847     op1 = convert_to_mode (HFmode, op1, 0);
4848     emit_move_insn (operands[0], op1);
4849     DONE;
4850   }"
4853 (define_expand "floatdihf2"
4854   [(set (match_operand:HF           0 "general_operand" "")
4855         (float:HF (match_operand:DI 1 "general_operand" "")))]
4856   "TARGET_EITHER"
4857   "
4858   {
4859     rtx op1 = gen_reg_rtx (SFmode);
4860     expand_float (op1, operands[1], 0);
4861     op1 = convert_to_mode (HFmode, op1, 0);
4862     emit_move_insn (operands[0], op1);
4863     DONE;
4864   }"
4867 (define_expand "floatsisf2"
4868   [(set (match_operand:SF           0 "s_register_operand" "")
4869         (float:SF (match_operand:SI 1 "s_register_operand" "")))]
4870   "TARGET_32BIT && TARGET_HARD_FLOAT"
4871   "
4874 (define_expand "floatsidf2"
4875   [(set (match_operand:DF           0 "s_register_operand" "")
4876         (float:DF (match_operand:SI 1 "s_register_operand" "")))]
4877   "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
4878   "
4881 (define_expand "fix_trunchfsi2"
4882   [(set (match_operand:SI         0 "general_operand" "")
4883         (fix:SI (fix:HF (match_operand:HF 1 "general_operand"  ""))))]
4884   "TARGET_EITHER"
4885   "
4886   {
4887     rtx op1 = convert_to_mode (SFmode, operands[1], 0);
4888     expand_fix (operands[0], op1, 0);
4889     DONE;
4890   }"
4893 (define_expand "fix_trunchfdi2"
4894   [(set (match_operand:DI         0 "general_operand" "")
4895         (fix:DI (fix:HF (match_operand:HF 1 "general_operand"  ""))))]
4896   "TARGET_EITHER"
4897   "
4898   {
4899     rtx op1 = convert_to_mode (SFmode, operands[1], 0);
4900     expand_fix (operands[0], op1, 0);
4901     DONE;
4902   }"
4905 (define_expand "fix_truncsfsi2"
4906   [(set (match_operand:SI         0 "s_register_operand" "")
4907         (fix:SI (fix:SF (match_operand:SF 1 "s_register_operand"  ""))))]
4908   "TARGET_32BIT && TARGET_HARD_FLOAT"
4909   "
4912 (define_expand "fix_truncdfsi2"
4913   [(set (match_operand:SI         0 "s_register_operand" "")
4914         (fix:SI (fix:DF (match_operand:DF 1 "s_register_operand"  ""))))]
4915   "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
4916   "
4919 ;; Truncation insns
4921 (define_expand "truncdfsf2"
4922   [(set (match_operand:SF  0 "s_register_operand" "")
4923         (float_truncate:SF
4924          (match_operand:DF 1 "s_register_operand" "")))]
4925   "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
4926   ""
4929 /* DFmode -> HFmode conversions have to go through SFmode.  */
4930 (define_expand "truncdfhf2"
4931   [(set (match_operand:HF  0 "general_operand" "")
4932         (float_truncate:HF
4933          (match_operand:DF 1 "general_operand" "")))]
4934   "TARGET_EITHER"
4935   "
4936   {
4937     rtx op1;
4938     op1 = convert_to_mode (SFmode, operands[1], 0);
4939     op1 = convert_to_mode (HFmode, op1, 0);
4940     emit_move_insn (operands[0], op1);
4941     DONE;
4942   }"
4945 ;; Zero and sign extension instructions.
4947 (define_insn "zero_extend<mode>di2"
4948   [(set (match_operand:DI 0 "s_register_operand" "=w,r,?r,w")
4949         (zero_extend:DI (match_operand:QHSI 1 "<qhs_zextenddi_op>"
4950                                             "<qhs_zextenddi_cstr>")))]
4951   "TARGET_32BIT <qhs_zextenddi_cond>"
4952   "#"
4953   [(set_attr "length" "8,4,8,8")
4954    (set_attr "arch" "neon_for_64bits,*,*,avoid_neon_for_64bits")
4955    (set_attr "ce_count" "2")
4956    (set_attr "predicable" "yes")
4957    (set_attr "type" "multiple,mov_reg,multiple,multiple")]
4960 (define_insn "extend<mode>di2"
4961   [(set (match_operand:DI 0 "s_register_operand" "=w,r,?r,?r,w")
4962         (sign_extend:DI (match_operand:QHSI 1 "<qhs_extenddi_op>"
4963                                             "<qhs_extenddi_cstr>")))]
4964   "TARGET_32BIT <qhs_sextenddi_cond>"
4965   "#"
4966   [(set_attr "length" "8,4,8,8,8")
4967    (set_attr "ce_count" "2")
4968    (set_attr "shift" "1")
4969    (set_attr "predicable" "yes")
4970    (set_attr "arch" "neon_for_64bits,*,a,t,avoid_neon_for_64bits")
4971    (set_attr "type" "multiple,mov_reg,multiple,multiple,multiple")]
4974 ;; Splits for all extensions to DImode
4975 (define_split
4976   [(set (match_operand:DI 0 "s_register_operand" "")
4977         (zero_extend:DI (match_operand 1 "nonimmediate_operand" "")))]
4978   "TARGET_32BIT && reload_completed && !IS_VFP_REGNUM (REGNO (operands[0]))"
4979   [(set (match_dup 0) (match_dup 1))]
4981   rtx lo_part = gen_lowpart (SImode, operands[0]);
4982   machine_mode src_mode = GET_MODE (operands[1]);
4984   if (REG_P (operands[0])
4985       && !reg_overlap_mentioned_p (operands[0], operands[1]))
4986     emit_clobber (operands[0]);
4987   if (!REG_P (lo_part) || src_mode != SImode
4988       || !rtx_equal_p (lo_part, operands[1]))
4989     {
4990       if (src_mode == SImode)
4991         emit_move_insn (lo_part, operands[1]);
4992       else
4993         emit_insn (gen_rtx_SET (lo_part,
4994                                 gen_rtx_ZERO_EXTEND (SImode, operands[1])));
4995       operands[1] = lo_part;
4996     }
4997   operands[0] = gen_highpart (SImode, operands[0]);
4998   operands[1] = const0_rtx;
5001 (define_split
5002   [(set (match_operand:DI 0 "s_register_operand" "")
5003         (sign_extend:DI (match_operand 1 "nonimmediate_operand" "")))]
5004   "TARGET_32BIT && reload_completed && !IS_VFP_REGNUM (REGNO (operands[0]))"
5005   [(set (match_dup 0) (ashiftrt:SI (match_dup 1) (const_int 31)))]
5007   rtx lo_part = gen_lowpart (SImode, operands[0]);
5008   machine_mode src_mode = GET_MODE (operands[1]);
5010   if (REG_P (operands[0])
5011       && !reg_overlap_mentioned_p (operands[0], operands[1]))
5012     emit_clobber (operands[0]);
5014   if (!REG_P (lo_part) || src_mode != SImode
5015       || !rtx_equal_p (lo_part, operands[1]))
5016     {
5017       if (src_mode == SImode)
5018         emit_move_insn (lo_part, operands[1]);
5019       else
5020         emit_insn (gen_rtx_SET (lo_part,
5021                                 gen_rtx_SIGN_EXTEND (SImode, operands[1])));
5022       operands[1] = lo_part;
5023     }
5024   operands[0] = gen_highpart (SImode, operands[0]);
5027 (define_expand "zero_extendhisi2"
5028   [(set (match_operand:SI 0 "s_register_operand" "")
5029         (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
5030   "TARGET_EITHER"
5032   if (TARGET_ARM && !arm_arch4 && MEM_P (operands[1]))
5033     {
5034       emit_insn (gen_movhi_bytes (operands[0], operands[1]));
5035       DONE;
5036     }
5037   if (!arm_arch6 && !MEM_P (operands[1]))
5038     {
5039       rtx t = gen_lowpart (SImode, operands[1]);
5040       rtx tmp = gen_reg_rtx (SImode);
5041       emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (16)));
5042       emit_insn (gen_lshrsi3 (operands[0], tmp, GEN_INT (16)));
5043       DONE;
5044     }
5047 (define_split
5048   [(set (match_operand:SI 0 "s_register_operand" "")
5049         (zero_extend:SI (match_operand:HI 1 "s_register_operand" "")))]
5050   "!TARGET_THUMB2 && !arm_arch6"
5051   [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
5052    (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 16)))]
5054   operands[2] = gen_lowpart (SImode, operands[1]);
5057 (define_insn "*arm_zero_extendhisi2"
5058   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5059         (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
5060   "TARGET_ARM && arm_arch4 && !arm_arch6"
5061   "@
5062    #
5063    ldr%(h%)\\t%0, %1"
5064   [(set_attr "type" "alu_shift_reg,load_byte")
5065    (set_attr "predicable" "yes")]
5068 (define_insn "*arm_zero_extendhisi2_v6"
5069   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5070         (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,Uh")))]
5071   "TARGET_ARM && arm_arch6"
5072   "@
5073    uxth%?\\t%0, %1
5074    ldr%(h%)\\t%0, %1"
5075   [(set_attr "predicable" "yes")
5076    (set_attr "type" "extend,load_byte")]
5079 (define_insn "*arm_zero_extendhisi2addsi"
5080   [(set (match_operand:SI 0 "s_register_operand" "=r")
5081         (plus:SI (zero_extend:SI (match_operand:HI 1 "s_register_operand" "r"))
5082                  (match_operand:SI 2 "s_register_operand" "r")))]
5083   "TARGET_INT_SIMD"
5084   "uxtah%?\\t%0, %2, %1"
5085   [(set_attr "type" "alu_shift_reg")
5086    (set_attr "predicable" "yes")
5087    (set_attr "predicable_short_it" "no")]
5090 (define_expand "zero_extendqisi2"
5091   [(set (match_operand:SI 0 "s_register_operand" "")
5092         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))]
5093   "TARGET_EITHER"
5095   if (TARGET_ARM && !arm_arch6 && !MEM_P (operands[1]))
5096     {
5097       emit_insn (gen_andsi3 (operands[0],
5098                              gen_lowpart (SImode, operands[1]),
5099                                           GEN_INT (255)));
5100       DONE;
5101     }
5102   if (!arm_arch6 && !MEM_P (operands[1]))
5103     {
5104       rtx t = gen_lowpart (SImode, operands[1]);
5105       rtx tmp = gen_reg_rtx (SImode);
5106       emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (24)));
5107       emit_insn (gen_lshrsi3 (operands[0], tmp, GEN_INT (24)));
5108       DONE;
5109     }
5112 (define_split
5113   [(set (match_operand:SI 0 "s_register_operand" "")
5114         (zero_extend:SI (match_operand:QI 1 "s_register_operand" "")))]
5115   "!arm_arch6"
5116   [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 24)))
5117    (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 24)))]
5119   operands[2] = simplify_gen_subreg (SImode, operands[1], QImode, 0);
5120   if (TARGET_ARM)
5121     {
5122       emit_insn (gen_andsi3 (operands[0], operands[2], GEN_INT (255)));
5123       DONE;
5124     }
5127 (define_insn "*arm_zero_extendqisi2"
5128   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5129         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
5130   "TARGET_ARM && !arm_arch6"
5131   "@
5132    #
5133    ldr%(b%)\\t%0, %1\\t%@ zero_extendqisi2"
5134   [(set_attr "length" "8,4")
5135    (set_attr "type" "alu_shift_reg,load_byte")
5136    (set_attr "predicable" "yes")]
5139 (define_insn "*arm_zero_extendqisi2_v6"
5140   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5141         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,Uh")))]
5142   "TARGET_ARM && arm_arch6"
5143   "@
5144    uxtb%(%)\\t%0, %1
5145    ldr%(b%)\\t%0, %1\\t%@ zero_extendqisi2"
5146   [(set_attr "type" "extend,load_byte")
5147    (set_attr "predicable" "yes")]
5150 (define_insn "*arm_zero_extendqisi2addsi"
5151   [(set (match_operand:SI 0 "s_register_operand" "=r")
5152         (plus:SI (zero_extend:SI (match_operand:QI 1 "s_register_operand" "r"))
5153                  (match_operand:SI 2 "s_register_operand" "r")))]
5154   "TARGET_INT_SIMD"
5155   "uxtab%?\\t%0, %2, %1"
5156   [(set_attr "predicable" "yes")
5157    (set_attr "predicable_short_it" "no")
5158    (set_attr "type" "alu_shift_reg")]
5161 (define_split
5162   [(set (match_operand:SI 0 "s_register_operand" "")
5163         (zero_extend:SI (subreg:QI (match_operand:SI 1 "" "") 0)))
5164    (clobber (match_operand:SI 2 "s_register_operand" ""))]
5165   "TARGET_32BIT && (!MEM_P (operands[1])) && ! BYTES_BIG_ENDIAN"
5166   [(set (match_dup 2) (match_dup 1))
5167    (set (match_dup 0) (and:SI (match_dup 2) (const_int 255)))]
5168   ""
5171 (define_split
5172   [(set (match_operand:SI 0 "s_register_operand" "")
5173         (zero_extend:SI (subreg:QI (match_operand:SI 1 "" "") 3)))
5174    (clobber (match_operand:SI 2 "s_register_operand" ""))]
5175   "TARGET_32BIT && (!MEM_P (operands[1])) && BYTES_BIG_ENDIAN"
5176   [(set (match_dup 2) (match_dup 1))
5177    (set (match_dup 0) (and:SI (match_dup 2) (const_int 255)))]
5178   ""
5182 (define_split
5183   [(set (match_operand:SI 0 "s_register_operand" "")
5184         (IOR_XOR:SI (and:SI (ashift:SI
5185                              (match_operand:SI 1 "s_register_operand" "")
5186                              (match_operand:SI 2 "const_int_operand" ""))
5187                             (match_operand:SI 3 "const_int_operand" ""))
5188                     (zero_extend:SI
5189                      (match_operator 5 "subreg_lowpart_operator"
5190                       [(match_operand:SI 4 "s_register_operand" "")]))))]
5191   "TARGET_32BIT
5192    && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
5193        == (GET_MODE_MASK (GET_MODE (operands[5]))
5194            & (GET_MODE_MASK (GET_MODE (operands[5]))
5195               << (INTVAL (operands[2])))))"
5196   [(set (match_dup 0) (IOR_XOR:SI (ashift:SI (match_dup 1) (match_dup 2))
5197                                   (match_dup 4)))
5198    (set (match_dup 0) (zero_extend:SI (match_dup 5)))]
5199   "operands[5] = gen_lowpart (GET_MODE (operands[5]), operands[0]);"
5202 (define_insn "*compareqi_eq0"
5203   [(set (reg:CC_Z CC_REGNUM)
5204         (compare:CC_Z (match_operand:QI 0 "s_register_operand" "r")
5205                          (const_int 0)))]
5206   "TARGET_32BIT"
5207   "tst%?\\t%0, #255"
5208   [(set_attr "conds" "set")
5209    (set_attr "predicable" "yes")
5210    (set_attr "predicable_short_it" "no")
5211    (set_attr "type" "logic_imm")]
5214 (define_expand "extendhisi2"
5215   [(set (match_operand:SI 0 "s_register_operand" "")
5216         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
5217   "TARGET_EITHER"
5219   if (TARGET_THUMB1)
5220     {
5221       emit_insn (gen_thumb1_extendhisi2 (operands[0], operands[1]));
5222       DONE;
5223     }
5224   if (MEM_P (operands[1]) && TARGET_ARM && !arm_arch4)
5225     {
5226       emit_insn (gen_extendhisi2_mem (operands[0], operands[1]));
5227       DONE;
5228     }
5230   if (!arm_arch6 && !MEM_P (operands[1]))
5231     {
5232       rtx t = gen_lowpart (SImode, operands[1]);
5233       rtx tmp = gen_reg_rtx (SImode);
5234       emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (16)));
5235       emit_insn (gen_ashrsi3 (operands[0], tmp, GEN_INT (16)));
5236       DONE;
5237     }
5240 (define_split
5241   [(parallel
5242     [(set (match_operand:SI 0 "register_operand" "")
5243           (sign_extend:SI (match_operand:HI 1 "register_operand" "")))
5244      (clobber (match_scratch:SI 2 ""))])]
5245   "!arm_arch6"
5246   [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
5247    (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
5249   operands[2] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
5252 ;; This pattern will only be used when ldsh is not available
5253 (define_expand "extendhisi2_mem"
5254   [(set (match_dup 2) (zero_extend:SI (match_operand:HI 1 "" "")))
5255    (set (match_dup 3)
5256         (zero_extend:SI (match_dup 7)))
5257    (set (match_dup 6) (ashift:SI (match_dup 4) (const_int 24)))
5258    (set (match_operand:SI 0 "" "")
5259         (ior:SI (ashiftrt:SI (match_dup 6) (const_int 16)) (match_dup 5)))]
5260   "TARGET_ARM"
5261   "
5262   {
5263     rtx mem1, mem2;
5264     rtx addr = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
5266     mem1 = change_address (operands[1], QImode, addr);
5267     mem2 = change_address (operands[1], QImode,
5268                            plus_constant (Pmode, addr, 1));
5269     operands[0] = gen_lowpart (SImode, operands[0]);
5270     operands[1] = mem1;
5271     operands[2] = gen_reg_rtx (SImode);
5272     operands[3] = gen_reg_rtx (SImode);
5273     operands[6] = gen_reg_rtx (SImode);
5274     operands[7] = mem2;
5276     if (BYTES_BIG_ENDIAN)
5277       {
5278         operands[4] = operands[2];
5279         operands[5] = operands[3];
5280       }
5281     else
5282       {
5283         operands[4] = operands[3];
5284         operands[5] = operands[2];
5285       }
5286   }"
5289 (define_split
5290   [(set (match_operand:SI 0 "register_operand" "")
5291         (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
5292   "!arm_arch6"
5293   [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
5294    (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
5296   operands[2] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
5299 (define_insn "*arm_extendhisi2"
5300   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5301         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,Uh")))]
5302   "TARGET_ARM && arm_arch4 && !arm_arch6"
5303   "@
5304    #
5305    ldr%(sh%)\\t%0, %1"
5306   [(set_attr "length" "8,4")
5307    (set_attr "type" "alu_shift_reg,load_byte")
5308    (set_attr "predicable" "yes")]
5311 ;; ??? Check Thumb-2 pool range
5312 (define_insn "*arm_extendhisi2_v6"
5313   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5314         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,Uh")))]
5315   "TARGET_32BIT && arm_arch6"
5316   "@
5317    sxth%?\\t%0, %1
5318    ldr%(sh%)\\t%0, %1"
5319   [(set_attr "type" "extend,load_byte")
5320    (set_attr "predicable" "yes")
5321    (set_attr "predicable_short_it" "no")]
5324 (define_insn "*arm_extendhisi2addsi"
5325   [(set (match_operand:SI 0 "s_register_operand" "=r")
5326         (plus:SI (sign_extend:SI (match_operand:HI 1 "s_register_operand" "r"))
5327                  (match_operand:SI 2 "s_register_operand" "r")))]
5328   "TARGET_INT_SIMD"
5329   "sxtah%?\\t%0, %2, %1"
5330   [(set_attr "type" "alu_shift_reg")]
5333 (define_expand "extendqihi2"
5334   [(set (match_dup 2)
5335         (ashift:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "")
5336                    (const_int 24)))
5337    (set (match_operand:HI 0 "s_register_operand" "")
5338         (ashiftrt:SI (match_dup 2)
5339                      (const_int 24)))]
5340   "TARGET_ARM"
5341   "
5342   {
5343     if (arm_arch4 && MEM_P (operands[1]))
5344       {
5345         emit_insn (gen_rtx_SET (operands[0],
5346                                 gen_rtx_SIGN_EXTEND (HImode, operands[1])));
5347         DONE;
5348       }
5349     if (!s_register_operand (operands[1], QImode))
5350       operands[1] = copy_to_mode_reg (QImode, operands[1]);
5351     operands[0] = gen_lowpart (SImode, operands[0]);
5352     operands[1] = gen_lowpart (SImode, operands[1]);
5353     operands[2] = gen_reg_rtx (SImode);
5354   }"
5357 (define_insn "*arm_extendqihi_insn"
5358   [(set (match_operand:HI 0 "s_register_operand" "=r")
5359         (sign_extend:HI (match_operand:QI 1 "arm_extendqisi_mem_op" "Uq")))]
5360   "TARGET_ARM && arm_arch4"
5361   "ldr%(sb%)\\t%0, %1"
5362   [(set_attr "type" "load_byte")
5363    (set_attr "predicable" "yes")]
5366 (define_expand "extendqisi2"
5367   [(set (match_operand:SI 0 "s_register_operand" "")
5368         (sign_extend:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "")))]
5369   "TARGET_EITHER"
5371   if (!arm_arch4 && MEM_P (operands[1]))
5372     operands[1] = copy_to_mode_reg (QImode, operands[1]);
5374   if (!arm_arch6 && !MEM_P (operands[1]))
5375     {
5376       rtx t = gen_lowpart (SImode, operands[1]);
5377       rtx tmp = gen_reg_rtx (SImode);
5378       emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (24)));
5379       emit_insn (gen_ashrsi3 (operands[0], tmp, GEN_INT (24)));
5380       DONE;
5381     }
5384 (define_split
5385   [(set (match_operand:SI 0 "register_operand" "")
5386         (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
5387   "!arm_arch6"
5388   [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 24)))
5389    (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 24)))]
5391   operands[2] = simplify_gen_subreg (SImode, operands[1], QImode, 0);
5394 (define_insn "*arm_extendqisi"
5395   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5396         (sign_extend:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "r,Uq")))]
5397   "TARGET_ARM && arm_arch4 && !arm_arch6"
5398   "@
5399    #
5400    ldr%(sb%)\\t%0, %1"
5401   [(set_attr "length" "8,4")
5402    (set_attr "type" "alu_shift_reg,load_byte")
5403    (set_attr "predicable" "yes")]
5406 (define_insn "*arm_extendqisi_v6"
5407   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5408         (sign_extend:SI
5409          (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "r,Uq")))]
5410   "TARGET_ARM && arm_arch6"
5411   "@
5412    sxtb%?\\t%0, %1
5413    ldr%(sb%)\\t%0, %1"
5414   [(set_attr "type" "extend,load_byte")
5415    (set_attr "predicable" "yes")]
5418 (define_insn "*arm_extendqisi2addsi"
5419   [(set (match_operand:SI 0 "s_register_operand" "=r")
5420         (plus:SI (sign_extend:SI (match_operand:QI 1 "s_register_operand" "r"))
5421                  (match_operand:SI 2 "s_register_operand" "r")))]
5422   "TARGET_INT_SIMD"
5423   "sxtab%?\\t%0, %2, %1"
5424   [(set_attr "type" "alu_shift_reg")
5425    (set_attr "predicable" "yes")
5426    (set_attr "predicable_short_it" "no")]
5429 (define_expand "extendsfdf2"
5430   [(set (match_operand:DF                  0 "s_register_operand" "")
5431         (float_extend:DF (match_operand:SF 1 "s_register_operand"  "")))]
5432   "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
5433   ""
5436 /* HFmode -> DFmode conversions have to go through SFmode.  */
5437 (define_expand "extendhfdf2"
5438   [(set (match_operand:DF                  0 "general_operand" "")
5439         (float_extend:DF (match_operand:HF 1 "general_operand"  "")))]
5440   "TARGET_EITHER"
5441   "
5442   {
5443     rtx op1;
5444     op1 = convert_to_mode (SFmode, operands[1], 0);
5445     op1 = convert_to_mode (DFmode, op1, 0);
5446     emit_insn (gen_movdf (operands[0], op1));
5447     DONE;
5448   }"
5451 ;; Move insns (including loads and stores)
5453 ;; XXX Just some ideas about movti.
5454 ;; I don't think these are a good idea on the arm, there just aren't enough
5455 ;; registers
5456 ;;(define_expand "loadti"
5457 ;;  [(set (match_operand:TI 0 "s_register_operand" "")
5458 ;;      (mem:TI (match_operand:SI 1 "address_operand" "")))]
5459 ;;  "" "")
5461 ;;(define_expand "storeti"
5462 ;;  [(set (mem:TI (match_operand:TI 0 "address_operand" ""))
5463 ;;      (match_operand:TI 1 "s_register_operand" ""))]
5464 ;;  "" "")
5466 ;;(define_expand "movti"
5467 ;;  [(set (match_operand:TI 0 "general_operand" "")
5468 ;;      (match_operand:TI 1 "general_operand" ""))]
5469 ;;  ""
5470 ;;  "
5472 ;;  rtx insn;
5474 ;;  if (MEM_P (operands[0]) && MEM_P (operands[1]))
5475 ;;    operands[1] = copy_to_reg (operands[1]);
5476 ;;  if (MEM_P (operands[0]))
5477 ;;    insn = gen_storeti (XEXP (operands[0], 0), operands[1]);
5478 ;;  else if (MEM_P (operands[1]))
5479 ;;    insn = gen_loadti (operands[0], XEXP (operands[1], 0));
5480 ;;  else
5481 ;;    FAIL;
5483 ;;  emit_insn (insn);
5484 ;;  DONE;
5485 ;;}")
5487 ;; Recognize garbage generated above.
5489 ;;(define_insn ""
5490 ;;  [(set (match_operand:TI 0 "general_operand" "=r,r,r,<,>,m")
5491 ;;      (match_operand:TI 1 "general_operand" "<,>,m,r,r,r"))]
5492 ;;  ""
5493 ;;  "*
5494 ;;  {
5495 ;;    register mem = (which_alternative < 3);
5496 ;;    register const char *template;
5498 ;;    operands[mem] = XEXP (operands[mem], 0);
5499 ;;    switch (which_alternative)
5500 ;;      {
5501 ;;      case 0: template = \"ldmdb\\t%1!, %M0\"; break;
5502 ;;      case 1: template = \"ldmia\\t%1!, %M0\"; break;
5503 ;;      case 2: template = \"ldmia\\t%1, %M0\"; break;
5504 ;;      case 3: template = \"stmdb\\t%0!, %M1\"; break;
5505 ;;      case 4: template = \"stmia\\t%0!, %M1\"; break;
5506 ;;      case 5: template = \"stmia\\t%0, %M1\"; break;
5507 ;;      }
5508 ;;    output_asm_insn (template, operands);
5509 ;;    return \"\";
5510 ;;  }")
5512 (define_expand "movdi"
5513   [(set (match_operand:DI 0 "general_operand" "")
5514         (match_operand:DI 1 "general_operand" ""))]
5515   "TARGET_EITHER"
5516   "
5517   if (can_create_pseudo_p ())
5518     {
5519       if (!REG_P (operands[0]))
5520         operands[1] = force_reg (DImode, operands[1]);
5521     }
5522   if (REG_P (operands[0]) && REGNO (operands[0]) <= LAST_ARM_REGNUM
5523       && !HARD_REGNO_MODE_OK (REGNO (operands[0]), DImode))
5524     {
5525       /* Avoid LDRD's into an odd-numbered register pair in ARM state
5526          when expanding function calls.  */
5527       gcc_assert (can_create_pseudo_p ());
5528       if (MEM_P (operands[1]) && MEM_VOLATILE_P (operands[1]))
5529         {
5530           /* Perform load into legal reg pair first, then move.  */
5531           rtx reg = gen_reg_rtx (DImode);
5532           emit_insn (gen_movdi (reg, operands[1]));
5533           operands[1] = reg;
5534         }
5535       emit_move_insn (gen_lowpart (SImode, operands[0]),
5536                       gen_lowpart (SImode, operands[1]));
5537       emit_move_insn (gen_highpart (SImode, operands[0]),
5538                       gen_highpart (SImode, operands[1]));
5539       DONE;
5540     }
5541   else if (REG_P (operands[1]) && REGNO (operands[1]) <= LAST_ARM_REGNUM
5542            && !HARD_REGNO_MODE_OK (REGNO (operands[1]), DImode))
5543     {
5544       /* Avoid STRD's from an odd-numbered register pair in ARM state
5545          when expanding function prologue.  */
5546       gcc_assert (can_create_pseudo_p ());
5547       rtx split_dest = (MEM_P (operands[0]) && MEM_VOLATILE_P (operands[0]))
5548                        ? gen_reg_rtx (DImode)
5549                        : operands[0];
5550       emit_move_insn (gen_lowpart (SImode, split_dest),
5551                       gen_lowpart (SImode, operands[1]));
5552       emit_move_insn (gen_highpart (SImode, split_dest),
5553                       gen_highpart (SImode, operands[1]));
5554       if (split_dest != operands[0])
5555         emit_insn (gen_movdi (operands[0], split_dest));
5556       DONE;
5557     }
5558   "
5561 (define_insn "*arm_movdi"
5562   [(set (match_operand:DI 0 "nonimmediate_di_operand" "=r, r, r, q, m")
5563         (match_operand:DI 1 "di_operand"              "rDa,Db,Dc,mi,q"))]
5564   "TARGET_32BIT
5565    && !(TARGET_HARD_FLOAT && TARGET_VFP)
5566    && !TARGET_IWMMXT
5567    && (   register_operand (operands[0], DImode)
5568        || register_operand (operands[1], DImode))"
5569   "*
5570   switch (which_alternative)
5571     {
5572     case 0:
5573     case 1:
5574     case 2:
5575       return \"#\";
5576     default:
5577       return output_move_double (operands, true, NULL);
5578     }
5579   "
5580   [(set_attr "length" "8,12,16,8,8")
5581    (set_attr "type" "multiple,multiple,multiple,load2,store2")
5582    (set_attr "arm_pool_range" "*,*,*,1020,*")
5583    (set_attr "arm_neg_pool_range" "*,*,*,1004,*")
5584    (set_attr "thumb2_pool_range" "*,*,*,4094,*")
5585    (set_attr "thumb2_neg_pool_range" "*,*,*,0,*")]
5588 (define_split
5589   [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
5590         (match_operand:ANY64 1 "immediate_operand" ""))]
5591   "TARGET_32BIT
5592    && reload_completed
5593    && (arm_const_double_inline_cost (operands[1])
5594        <= arm_max_const_double_inline_cost ())"
5595   [(const_int 0)]
5596   "
5597   arm_split_constant (SET, SImode, curr_insn,
5598                       INTVAL (gen_lowpart (SImode, operands[1])),
5599                       gen_lowpart (SImode, operands[0]), NULL_RTX, 0);
5600   arm_split_constant (SET, SImode, curr_insn,
5601                       INTVAL (gen_highpart_mode (SImode,
5602                                                  GET_MODE (operands[0]),
5603                                                  operands[1])),
5604                       gen_highpart (SImode, operands[0]), NULL_RTX, 0);
5605   DONE;
5606   "
5609 ; If optimizing for size, or if we have load delay slots, then 
5610 ; we want to split the constant into two separate operations. 
5611 ; In both cases this may split a trivial part into a single data op
5612 ; leaving a single complex constant to load.  We can also get longer
5613 ; offsets in a LDR which means we get better chances of sharing the pool
5614 ; entries.  Finally, we can normally do a better job of scheduling
5615 ; LDR instructions than we can with LDM.
5616 ; This pattern will only match if the one above did not.
5617 (define_split
5618   [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
5619         (match_operand:ANY64 1 "const_double_operand" ""))]
5620   "TARGET_ARM && reload_completed
5621    && arm_const_double_by_parts (operands[1])"
5622   [(set (match_dup 0) (match_dup 1))
5623    (set (match_dup 2) (match_dup 3))]
5624   "
5625   operands[2] = gen_highpart (SImode, operands[0]);
5626   operands[3] = gen_highpart_mode (SImode, GET_MODE (operands[0]),
5627                                    operands[1]);
5628   operands[0] = gen_lowpart (SImode, operands[0]);
5629   operands[1] = gen_lowpart (SImode, operands[1]);
5630   "
5633 (define_split
5634   [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
5635         (match_operand:ANY64 1 "arm_general_register_operand" ""))]
5636   "TARGET_EITHER && reload_completed"
5637   [(set (match_dup 0) (match_dup 1))
5638    (set (match_dup 2) (match_dup 3))]
5639   "
5640   operands[2] = gen_highpart (SImode, operands[0]);
5641   operands[3] = gen_highpart (SImode, operands[1]);
5642   operands[0] = gen_lowpart (SImode, operands[0]);
5643   operands[1] = gen_lowpart (SImode, operands[1]);
5645   /* Handle a partial overlap.  */
5646   if (rtx_equal_p (operands[0], operands[3]))
5647     {
5648       rtx tmp0 = operands[0];
5649       rtx tmp1 = operands[1];
5651       operands[0] = operands[2];
5652       operands[1] = operands[3];
5653       operands[2] = tmp0;
5654       operands[3] = tmp1;
5655     }
5656   "
5659 ;; We can't actually do base+index doubleword loads if the index and
5660 ;; destination overlap.  Split here so that we at least have chance to
5661 ;; schedule.
5662 (define_split
5663   [(set (match_operand:DI 0 "s_register_operand" "")
5664         (mem:DI (plus:SI (match_operand:SI 1 "s_register_operand" "")
5665                          (match_operand:SI 2 "s_register_operand" ""))))]
5666   "TARGET_LDRD
5667   && reg_overlap_mentioned_p (operands[0], operands[1])
5668   && reg_overlap_mentioned_p (operands[0], operands[2])"
5669   [(set (match_dup 4)
5670         (plus:SI (match_dup 1)
5671                  (match_dup 2)))
5672    (set (match_dup 0)
5673         (mem:DI (match_dup 4)))]
5674   "
5675   operands[4] = gen_rtx_REG (SImode, REGNO(operands[0]));
5676   "
5679 (define_expand "movsi"
5680   [(set (match_operand:SI 0 "general_operand" "")
5681         (match_operand:SI 1 "general_operand" ""))]
5682   "TARGET_EITHER"
5683   "
5684   {
5685   rtx base, offset, tmp;
5687   if (TARGET_32BIT)
5688     {
5689       /* Everything except mem = const or mem = mem can be done easily.  */
5690       if (MEM_P (operands[0]))
5691         operands[1] = force_reg (SImode, operands[1]);
5692       if (arm_general_register_operand (operands[0], SImode)
5693           && CONST_INT_P (operands[1])
5694           && !(const_ok_for_arm (INTVAL (operands[1]))
5695                || const_ok_for_arm (~INTVAL (operands[1]))))
5696         {
5697            if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[1]), SET))
5698              {
5699                 emit_insn (gen_rtx_SET (operands[0], operands[1]));
5700                 DONE;
5701              }
5702           else
5703              {
5704                 arm_split_constant (SET, SImode, NULL_RTX,
5705                                     INTVAL (operands[1]), operands[0], NULL_RTX,
5706                                     optimize && can_create_pseudo_p ());
5707                 DONE;
5708              }
5709         }
5710     }
5711   else /* TARGET_THUMB1...  */
5712     {
5713       if (can_create_pseudo_p ())
5714         {
5715           if (!REG_P (operands[0]))
5716             operands[1] = force_reg (SImode, operands[1]);
5717         }
5718     }
5720   if (ARM_OFFSETS_MUST_BE_WITHIN_SECTIONS_P)
5721     {
5722       split_const (operands[1], &base, &offset);
5723       if (GET_CODE (base) == SYMBOL_REF
5724           && !offset_within_block_p (base, INTVAL (offset)))
5725         {
5726           tmp = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];
5727           emit_move_insn (tmp, base);
5728           emit_insn (gen_addsi3 (operands[0], tmp, offset));
5729           DONE;
5730         }
5731     }
5733   /* Recognize the case where operand[1] is a reference to thread-local
5734      data and load its address to a register.  */
5735   if (arm_tls_referenced_p (operands[1]))
5736     {
5737       rtx tmp = operands[1];
5738       rtx addend = NULL;
5740       if (GET_CODE (tmp) == CONST && GET_CODE (XEXP (tmp, 0)) == PLUS)
5741         {
5742           addend = XEXP (XEXP (tmp, 0), 1);
5743           tmp = XEXP (XEXP (tmp, 0), 0);
5744         }
5746       gcc_assert (GET_CODE (tmp) == SYMBOL_REF);
5747       gcc_assert (SYMBOL_REF_TLS_MODEL (tmp) != 0);
5749       tmp = legitimize_tls_address (tmp,
5750                                     !can_create_pseudo_p () ? operands[0] : 0);
5751       if (addend)
5752         {
5753           tmp = gen_rtx_PLUS (SImode, tmp, addend);
5754           tmp = force_operand (tmp, operands[0]);
5755         }
5756       operands[1] = tmp;
5757     }
5758   else if (flag_pic
5759            && (CONSTANT_P (operands[1])
5760                || symbol_mentioned_p (operands[1])
5761                || label_mentioned_p (operands[1])))
5762       operands[1] = legitimize_pic_address (operands[1], SImode,
5763                                             (!can_create_pseudo_p ()
5764                                              ? operands[0]
5765                                              : 0));
5766   }
5767   "
5770 ;; The ARM LO_SUM and HIGH are backwards - HIGH sets the low bits, and
5771 ;; LO_SUM adds in the high bits.  Fortunately these are opaque operations
5772 ;; so this does not matter.
5773 (define_insn "*arm_movt"
5774   [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
5775         (lo_sum:SI (match_operand:SI 1 "nonimmediate_operand" "0")
5776                    (match_operand:SI 2 "general_operand"      "i")))]
5777   "arm_arch_thumb2 && arm_valid_symbolic_address_p (operands[2])"
5778   "movt%?\t%0, #:upper16:%c2"
5779   [(set_attr "predicable" "yes")
5780    (set_attr "predicable_short_it" "no")
5781    (set_attr "length" "4")
5782    (set_attr "type" "alu_sreg")]
5785 (define_insn "*arm_movsi_insn"
5786   [(set (match_operand:SI 0 "nonimmediate_operand" "=rk,r,r,r,rk,m")
5787         (match_operand:SI 1 "general_operand"      "rk, I,K,j,mi,rk"))]
5788   "TARGET_ARM && ! TARGET_IWMMXT
5789    && !(TARGET_HARD_FLOAT && TARGET_VFP)
5790    && (   register_operand (operands[0], SImode)
5791        || register_operand (operands[1], SImode))"
5792   "@
5793    mov%?\\t%0, %1
5794    mov%?\\t%0, %1
5795    mvn%?\\t%0, #%B1
5796    movw%?\\t%0, %1
5797    ldr%?\\t%0, %1
5798    str%?\\t%1, %0"
5799   [(set_attr "type" "mov_reg,mov_imm,mvn_imm,mov_imm,load1,store1")
5800    (set_attr "predicable" "yes")
5801    (set_attr "pool_range" "*,*,*,*,4096,*")
5802    (set_attr "neg_pool_range" "*,*,*,*,4084,*")]
5805 (define_split
5806   [(set (match_operand:SI 0 "arm_general_register_operand" "")
5807         (match_operand:SI 1 "const_int_operand" ""))]
5808   "TARGET_32BIT
5809   && (!(const_ok_for_arm (INTVAL (operands[1]))
5810         || const_ok_for_arm (~INTVAL (operands[1]))))"
5811   [(clobber (const_int 0))]
5812   "
5813   arm_split_constant (SET, SImode, NULL_RTX, 
5814                       INTVAL (operands[1]), operands[0], NULL_RTX, 0);
5815   DONE;
5816   "
5819 ;; A normal way to do (symbol + offset) requires three instructions at least
5820 ;; (depends on how big the offset is) as below:
5821 ;; movw r0, #:lower16:g
5822 ;; movw r0, #:upper16:g
5823 ;; adds r0, #4
5825 ;; A better way would be:
5826 ;; movw r0, #:lower16:g+4
5827 ;; movw r0, #:upper16:g+4
5829 ;; The limitation of this way is that the length of offset should be a 16-bit
5830 ;; signed value, because current assembler only supports REL type relocation for
5831 ;; such case.  If the more powerful RELA type is supported in future, we should
5832 ;; update this pattern to go with better way.
5833 (define_split
5834   [(set (match_operand:SI 0 "arm_general_register_operand" "")
5835         (const:SI (plus:SI (match_operand:SI 1 "general_operand" "")
5836                            (match_operand:SI 2 "const_int_operand" ""))))]
5837   "TARGET_THUMB2
5838    && arm_disable_literal_pool
5839    && reload_completed
5840    && GET_CODE (operands[1]) == SYMBOL_REF"
5841   [(clobber (const_int 0))]
5842   "
5843     int offset = INTVAL (operands[2]);
5845     if (offset < -0x8000 || offset > 0x7fff)
5846       {
5847         arm_emit_movpair (operands[0], operands[1]);
5848         emit_insn (gen_rtx_SET (operands[0],
5849                                 gen_rtx_PLUS (SImode, operands[0], operands[2])));
5850       }
5851     else
5852       {
5853         rtx op = gen_rtx_CONST (SImode,
5854                                 gen_rtx_PLUS (SImode, operands[1], operands[2]));
5855         arm_emit_movpair (operands[0], op);
5856       }
5857   "
5860 ;; Split symbol_refs at the later stage (after cprop), instead of generating
5861 ;; movt/movw pair directly at expand.  Otherwise corresponding high_sum
5862 ;; and lo_sum would be merged back into memory load at cprop.  However,
5863 ;; if the default is to prefer movt/movw rather than a load from the constant
5864 ;; pool, the performance is better.
5865 (define_split
5866   [(set (match_operand:SI 0 "arm_general_register_operand" "")
5867        (match_operand:SI 1 "general_operand" ""))]
5868   "TARGET_32BIT
5869    && TARGET_USE_MOVT && GET_CODE (operands[1]) == SYMBOL_REF
5870    && !flag_pic && !target_word_relocations
5871    && !arm_tls_referenced_p (operands[1])"
5872   [(clobber (const_int 0))]
5874   arm_emit_movpair (operands[0], operands[1]);
5875   DONE;
5878 ;; When generating pic, we need to load the symbol offset into a register.
5879 ;; So that the optimizer does not confuse this with a normal symbol load
5880 ;; we use an unspec.  The offset will be loaded from a constant pool entry,
5881 ;; since that is the only type of relocation we can use.
5883 ;; Wrap calculation of the whole PIC address in a single pattern for the
5884 ;; benefit of optimizers, particularly, PRE and HOIST.  Calculation of
5885 ;; a PIC address involves two loads from memory, so we want to CSE it
5886 ;; as often as possible.
5887 ;; This pattern will be split into one of the pic_load_addr_* patterns
5888 ;; and a move after GCSE optimizations.
5890 ;; Note: Update arm.c: legitimize_pic_address() when changing this pattern.
5891 (define_expand "calculate_pic_address"
5892   [(set (match_operand:SI 0 "register_operand" "")
5893         (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "")
5894                          (unspec:SI [(match_operand:SI 2 "" "")]
5895                                     UNSPEC_PIC_SYM))))]
5896   "flag_pic"
5899 ;; Split calculate_pic_address into pic_load_addr_* and a move.
5900 (define_split
5901   [(set (match_operand:SI 0 "register_operand" "")
5902         (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "")
5903                          (unspec:SI [(match_operand:SI 2 "" "")]
5904                                     UNSPEC_PIC_SYM))))]
5905   "flag_pic"
5906   [(set (match_dup 3) (unspec:SI [(match_dup 2)] UNSPEC_PIC_SYM))
5907    (set (match_dup 0) (mem:SI (plus:SI (match_dup 1) (match_dup 3))))]
5908   "operands[3] = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];"
5911 ;; operand1 is the memory address to go into 
5912 ;; pic_load_addr_32bit.
5913 ;; operand2 is the PIC label to be emitted 
5914 ;; from pic_add_dot_plus_eight.
5915 ;; We do this to allow hoisting of the entire insn.
5916 (define_insn_and_split "pic_load_addr_unified"
5917   [(set (match_operand:SI 0 "s_register_operand" "=r,r,l")
5918         (unspec:SI [(match_operand:SI 1 "" "mX,mX,mX") 
5919                     (match_operand:SI 2 "" "")] 
5920                     UNSPEC_PIC_UNIFIED))]
5921  "flag_pic"
5922  "#"
5923  "&& reload_completed"
5924  [(set (match_dup 0) (unspec:SI [(match_dup 1)] UNSPEC_PIC_SYM))
5925   (set (match_dup 0) (unspec:SI [(match_dup 0) (match_dup 3)
5926                                  (match_dup 2)] UNSPEC_PIC_BASE))]
5927  "operands[3] = TARGET_THUMB ? GEN_INT (4) : GEN_INT (8);"
5928  [(set_attr "type" "load1,load1,load1")
5929   (set_attr "pool_range" "4096,4094,1022")
5930   (set_attr "neg_pool_range" "4084,0,0")
5931   (set_attr "arch"  "a,t2,t1")    
5932   (set_attr "length" "8,6,4")]
5935 ;; The rather odd constraints on the following are to force reload to leave
5936 ;; the insn alone, and to force the minipool generation pass to then move
5937 ;; the GOT symbol to memory.
5939 (define_insn "pic_load_addr_32bit"
5940   [(set (match_operand:SI 0 "s_register_operand" "=r")
5941         (unspec:SI [(match_operand:SI 1 "" "mX")] UNSPEC_PIC_SYM))]
5942   "TARGET_32BIT && flag_pic"
5943   "ldr%?\\t%0, %1"
5944   [(set_attr "type" "load1")
5945    (set (attr "pool_range")
5946         (if_then_else (eq_attr "is_thumb" "no")
5947                       (const_int 4096)
5948                       (const_int 4094)))
5949    (set (attr "neg_pool_range")
5950         (if_then_else (eq_attr "is_thumb" "no")
5951                       (const_int 4084)
5952                       (const_int 0)))]
5955 (define_insn "pic_load_addr_thumb1"
5956   [(set (match_operand:SI 0 "s_register_operand" "=l")
5957         (unspec:SI [(match_operand:SI 1 "" "mX")] UNSPEC_PIC_SYM))]
5958   "TARGET_THUMB1 && flag_pic"
5959   "ldr\\t%0, %1"
5960   [(set_attr "type" "load1")
5961    (set (attr "pool_range") (const_int 1018))]
5964 (define_insn "pic_add_dot_plus_four"
5965   [(set (match_operand:SI 0 "register_operand" "=r")
5966         (unspec:SI [(match_operand:SI 1 "register_operand" "0")
5967                     (const_int 4)
5968                     (match_operand 2 "" "")]
5969                    UNSPEC_PIC_BASE))]
5970   "TARGET_THUMB"
5971   "*
5972   (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
5973                                      INTVAL (operands[2]));
5974   return \"add\\t%0, %|pc\";
5975   "
5976   [(set_attr "length" "2")
5977    (set_attr "type" "alu_sreg")]
5980 (define_insn "pic_add_dot_plus_eight"
5981   [(set (match_operand:SI 0 "register_operand" "=r")
5982         (unspec:SI [(match_operand:SI 1 "register_operand" "r")
5983                     (const_int 8)
5984                     (match_operand 2 "" "")]
5985                    UNSPEC_PIC_BASE))]
5986   "TARGET_ARM"
5987   "*
5988     (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
5989                                        INTVAL (operands[2]));
5990     return \"add%?\\t%0, %|pc, %1\";
5991   "
5992   [(set_attr "predicable" "yes")
5993    (set_attr "type" "alu_sreg")]
5996 (define_insn "tls_load_dot_plus_eight"
5997   [(set (match_operand:SI 0 "register_operand" "=r")
5998         (mem:SI (unspec:SI [(match_operand:SI 1 "register_operand" "r")
5999                             (const_int 8)
6000                             (match_operand 2 "" "")]
6001                            UNSPEC_PIC_BASE)))]
6002   "TARGET_ARM"
6003   "*
6004     (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
6005                                        INTVAL (operands[2]));
6006     return \"ldr%?\\t%0, [%|pc, %1]\t\t@ tls_load_dot_plus_eight\";
6007   "
6008   [(set_attr "predicable" "yes")
6009    (set_attr "type" "load1")]
6012 ;; PIC references to local variables can generate pic_add_dot_plus_eight
6013 ;; followed by a load.  These sequences can be crunched down to
6014 ;; tls_load_dot_plus_eight by a peephole.
6016 (define_peephole2
6017   [(set (match_operand:SI 0 "register_operand" "")
6018         (unspec:SI [(match_operand:SI 3 "register_operand" "")
6019                     (const_int 8)
6020                     (match_operand 1 "" "")]
6021                    UNSPEC_PIC_BASE))
6022    (set (match_operand:SI 2 "arm_general_register_operand" "")
6023         (mem:SI (match_dup 0)))]
6024   "TARGET_ARM && peep2_reg_dead_p (2, operands[0])"
6025   [(set (match_dup 2)
6026         (mem:SI (unspec:SI [(match_dup 3)
6027                             (const_int 8)
6028                             (match_dup 1)]
6029                            UNSPEC_PIC_BASE)))]
6030   ""
6033 (define_insn "pic_offset_arm"
6034   [(set (match_operand:SI 0 "register_operand" "=r")
6035         (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
6036                          (unspec:SI [(match_operand:SI 2 "" "X")]
6037                                     UNSPEC_PIC_OFFSET))))]
6038   "TARGET_VXWORKS_RTP && TARGET_ARM && flag_pic"
6039   "ldr%?\\t%0, [%1,%2]"
6040   [(set_attr "type" "load1")]
6043 (define_expand "builtin_setjmp_receiver"
6044   [(label_ref (match_operand 0 "" ""))]
6045   "flag_pic"
6046   "
6048   /* r3 is clobbered by set/longjmp, so we can use it as a scratch
6049      register.  */
6050   if (arm_pic_register != INVALID_REGNUM)
6051     arm_load_pic_register (1UL << 3);
6052   DONE;
6055 ;; If copying one reg to another we can set the condition codes according to
6056 ;; its value.  Such a move is common after a return from subroutine and the
6057 ;; result is being tested against zero.
6059 (define_insn "*movsi_compare0"
6060   [(set (reg:CC CC_REGNUM)
6061         (compare:CC (match_operand:SI 1 "s_register_operand" "0,r")
6062                     (const_int 0)))
6063    (set (match_operand:SI 0 "s_register_operand" "=r,r")
6064         (match_dup 1))]
6065   "TARGET_32BIT"
6066   "@
6067    cmp%?\\t%0, #0
6068    sub%.\\t%0, %1, #0"
6069   [(set_attr "conds" "set")
6070    (set_attr "type" "alus_imm,alus_imm")]
6073 ;; Subroutine to store a half word from a register into memory.
6074 ;; Operand 0 is the source register (HImode)
6075 ;; Operand 1 is the destination address in a register (SImode)
6077 ;; In both this routine and the next, we must be careful not to spill
6078 ;; a memory address of reg+large_const into a separate PLUS insn, since this
6079 ;; can generate unrecognizable rtl.
6081 (define_expand "storehi"
6082   [;; store the low byte
6083    (set (match_operand 1 "" "") (match_dup 3))
6084    ;; extract the high byte
6085    (set (match_dup 2)
6086         (ashiftrt:SI (match_operand 0 "" "") (const_int 8)))
6087    ;; store the high byte
6088    (set (match_dup 4) (match_dup 5))]
6089   "TARGET_ARM"
6090   "
6091   {
6092     rtx op1 = operands[1];
6093     rtx addr = XEXP (op1, 0);
6094     enum rtx_code code = GET_CODE (addr);
6096     if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1)))
6097         || code == MINUS)
6098       op1 = replace_equiv_address (operands[1], force_reg (SImode, addr));
6100     operands[4] = adjust_address (op1, QImode, 1);
6101     operands[1] = adjust_address (operands[1], QImode, 0);
6102     operands[3] = gen_lowpart (QImode, operands[0]);
6103     operands[0] = gen_lowpart (SImode, operands[0]);
6104     operands[2] = gen_reg_rtx (SImode);
6105     operands[5] = gen_lowpart (QImode, operands[2]);
6106   }"
6109 (define_expand "storehi_bigend"
6110   [(set (match_dup 4) (match_dup 3))
6111    (set (match_dup 2)
6112         (ashiftrt:SI (match_operand 0 "" "") (const_int 8)))
6113    (set (match_operand 1 "" "") (match_dup 5))]
6114   "TARGET_ARM"
6115   "
6116   {
6117     rtx op1 = operands[1];
6118     rtx addr = XEXP (op1, 0);
6119     enum rtx_code code = GET_CODE (addr);
6121     if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1)))
6122         || code == MINUS)
6123       op1 = replace_equiv_address (op1, force_reg (SImode, addr));
6125     operands[4] = adjust_address (op1, QImode, 1);
6126     operands[1] = adjust_address (operands[1], QImode, 0);
6127     operands[3] = gen_lowpart (QImode, operands[0]);
6128     operands[0] = gen_lowpart (SImode, operands[0]);
6129     operands[2] = gen_reg_rtx (SImode);
6130     operands[5] = gen_lowpart (QImode, operands[2]);
6131   }"
6134 ;; Subroutine to store a half word integer constant into memory.
6135 (define_expand "storeinthi"
6136   [(set (match_operand 0 "" "")
6137         (match_operand 1 "" ""))
6138    (set (match_dup 3) (match_dup 2))]
6139   "TARGET_ARM"
6140   "
6141   {
6142     HOST_WIDE_INT value = INTVAL (operands[1]);
6143     rtx addr = XEXP (operands[0], 0);
6144     rtx op0 = operands[0];
6145     enum rtx_code code = GET_CODE (addr);
6147     if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1)))
6148         || code == MINUS)
6149       op0 = replace_equiv_address (op0, force_reg (SImode, addr));
6151     operands[1] = gen_reg_rtx (SImode);
6152     if (BYTES_BIG_ENDIAN)
6153       {
6154         emit_insn (gen_movsi (operands[1], GEN_INT ((value >> 8) & 255)));
6155         if ((value & 255) == ((value >> 8) & 255))
6156           operands[2] = operands[1];
6157         else
6158           {
6159             operands[2] = gen_reg_rtx (SImode);
6160             emit_insn (gen_movsi (operands[2], GEN_INT (value & 255)));
6161           }
6162       }
6163     else
6164       {
6165         emit_insn (gen_movsi (operands[1], GEN_INT (value & 255)));
6166         if ((value & 255) == ((value >> 8) & 255))
6167           operands[2] = operands[1];
6168         else
6169           {
6170             operands[2] = gen_reg_rtx (SImode);
6171             emit_insn (gen_movsi (operands[2], GEN_INT ((value >> 8) & 255)));
6172           }
6173       }
6175     operands[3] = adjust_address (op0, QImode, 1);
6176     operands[0] = adjust_address (operands[0], QImode, 0);
6177     operands[2] = gen_lowpart (QImode, operands[2]);
6178     operands[1] = gen_lowpart (QImode, operands[1]);
6179   }"
6182 (define_expand "storehi_single_op"
6183   [(set (match_operand:HI 0 "memory_operand" "")
6184         (match_operand:HI 1 "general_operand" ""))]
6185   "TARGET_32BIT && arm_arch4"
6186   "
6187   if (!s_register_operand (operands[1], HImode))
6188     operands[1] = copy_to_mode_reg (HImode, operands[1]);
6189   "
6192 (define_expand "movhi"
6193   [(set (match_operand:HI 0 "general_operand" "")
6194         (match_operand:HI 1 "general_operand" ""))]
6195   "TARGET_EITHER"
6196   "
6197   if (TARGET_ARM)
6198     {
6199       if (can_create_pseudo_p ())
6200         {
6201           if (MEM_P (operands[0]))
6202             {
6203               if (arm_arch4)
6204                 {
6205                   emit_insn (gen_storehi_single_op (operands[0], operands[1]));
6206                   DONE;
6207                 }
6208               if (CONST_INT_P (operands[1]))
6209                 emit_insn (gen_storeinthi (operands[0], operands[1]));
6210               else
6211                 {
6212                   if (MEM_P (operands[1]))
6213                     operands[1] = force_reg (HImode, operands[1]);
6214                   if (BYTES_BIG_ENDIAN)
6215                     emit_insn (gen_storehi_bigend (operands[1], operands[0]));
6216                   else
6217                    emit_insn (gen_storehi (operands[1], operands[0]));
6218                 }
6219               DONE;
6220             }
6221           /* Sign extend a constant, and keep it in an SImode reg.  */
6222           else if (CONST_INT_P (operands[1]))
6223             {
6224               rtx reg = gen_reg_rtx (SImode);
6225               HOST_WIDE_INT val = INTVAL (operands[1]) & 0xffff;
6227               /* If the constant is already valid, leave it alone.  */
6228               if (!const_ok_for_arm (val))
6229                 {
6230                   /* If setting all the top bits will make the constant 
6231                      loadable in a single instruction, then set them.  
6232                      Otherwise, sign extend the number.  */
6234                   if (const_ok_for_arm (~(val | ~0xffff)))
6235                     val |= ~0xffff;
6236                   else if (val & 0x8000)
6237                     val |= ~0xffff;
6238                 }
6240               emit_insn (gen_movsi (reg, GEN_INT (val)));
6241               operands[1] = gen_lowpart (HImode, reg);
6242             }
6243           else if (arm_arch4 && optimize && can_create_pseudo_p ()
6244                    && MEM_P (operands[1]))
6245             {
6246               rtx reg = gen_reg_rtx (SImode);
6248               emit_insn (gen_zero_extendhisi2 (reg, operands[1]));
6249               operands[1] = gen_lowpart (HImode, reg);
6250             }
6251           else if (!arm_arch4)
6252             {
6253               if (MEM_P (operands[1]))
6254                 {
6255                   rtx base;
6256                   rtx offset = const0_rtx;
6257                   rtx reg = gen_reg_rtx (SImode);
6259                   if ((REG_P (base = XEXP (operands[1], 0))
6260                        || (GET_CODE (base) == PLUS
6261                            && (CONST_INT_P (offset = XEXP (base, 1)))
6262                            && ((INTVAL(offset) & 1) != 1)
6263                            && REG_P (base = XEXP (base, 0))))
6264                       && REGNO_POINTER_ALIGN (REGNO (base)) >= 32)
6265                     {
6266                       rtx new_rtx;
6268                       new_rtx = widen_memory_access (operands[1], SImode,
6269                                                      ((INTVAL (offset) & ~3)
6270                                                       - INTVAL (offset)));
6271                       emit_insn (gen_movsi (reg, new_rtx));
6272                       if (((INTVAL (offset) & 2) != 0)
6273                           ^ (BYTES_BIG_ENDIAN ? 1 : 0))
6274                         {
6275                           rtx reg2 = gen_reg_rtx (SImode);
6277                           emit_insn (gen_lshrsi3 (reg2, reg, GEN_INT (16)));
6278                           reg = reg2;
6279                         }
6280                     }
6281                   else
6282                     emit_insn (gen_movhi_bytes (reg, operands[1]));
6284                   operands[1] = gen_lowpart (HImode, reg);
6285                }
6286            }
6287         }
6288       /* Handle loading a large integer during reload.  */
6289       else if (CONST_INT_P (operands[1])
6290                && !const_ok_for_arm (INTVAL (operands[1]))
6291                && !const_ok_for_arm (~INTVAL (operands[1])))
6292         {
6293           /* Writing a constant to memory needs a scratch, which should
6294              be handled with SECONDARY_RELOADs.  */
6295           gcc_assert (REG_P (operands[0]));
6297           operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
6298           emit_insn (gen_movsi (operands[0], operands[1]));
6299           DONE;
6300        }
6301     }
6302   else if (TARGET_THUMB2)
6303     {
6304       /* Thumb-2 can do everything except mem=mem and mem=const easily.  */
6305       if (can_create_pseudo_p ())
6306         {
6307           if (!REG_P (operands[0]))
6308             operands[1] = force_reg (HImode, operands[1]);
6309           /* Zero extend a constant, and keep it in an SImode reg.  */
6310           else if (CONST_INT_P (operands[1]))
6311             {
6312               rtx reg = gen_reg_rtx (SImode);
6313               HOST_WIDE_INT val = INTVAL (operands[1]) & 0xffff;
6315               emit_insn (gen_movsi (reg, GEN_INT (val)));
6316               operands[1] = gen_lowpart (HImode, reg);
6317             }
6318         }
6319     }
6320   else /* TARGET_THUMB1 */
6321     {
6322       if (can_create_pseudo_p ())
6323         {
6324           if (CONST_INT_P (operands[1]))
6325             {
6326               rtx reg = gen_reg_rtx (SImode);
6328               emit_insn (gen_movsi (reg, operands[1]));
6329               operands[1] = gen_lowpart (HImode, reg);
6330             }
6332           /* ??? We shouldn't really get invalid addresses here, but this can
6333              happen if we are passed a SP (never OK for HImode/QImode) or 
6334              virtual register (also rejected as illegitimate for HImode/QImode)
6335              relative address.  */
6336           /* ??? This should perhaps be fixed elsewhere, for instance, in
6337              fixup_stack_1, by checking for other kinds of invalid addresses,
6338              e.g. a bare reference to a virtual register.  This may confuse the
6339              alpha though, which must handle this case differently.  */
6340           if (MEM_P (operands[0])
6341               && !memory_address_p (GET_MODE (operands[0]),
6342                                     XEXP (operands[0], 0)))
6343             operands[0]
6344               = replace_equiv_address (operands[0],
6345                                        copy_to_reg (XEXP (operands[0], 0)));
6346    
6347           if (MEM_P (operands[1])
6348               && !memory_address_p (GET_MODE (operands[1]),
6349                                     XEXP (operands[1], 0)))
6350             operands[1]
6351               = replace_equiv_address (operands[1],
6352                                        copy_to_reg (XEXP (operands[1], 0)));
6354           if (MEM_P (operands[1]) && optimize > 0)
6355             {
6356               rtx reg = gen_reg_rtx (SImode);
6358               emit_insn (gen_zero_extendhisi2 (reg, operands[1]));
6359               operands[1] = gen_lowpart (HImode, reg);
6360             }
6362           if (MEM_P (operands[0]))
6363             operands[1] = force_reg (HImode, operands[1]);
6364         }
6365       else if (CONST_INT_P (operands[1])
6366                 && !satisfies_constraint_I (operands[1]))
6367         {
6368           /* Handle loading a large integer during reload.  */
6370           /* Writing a constant to memory needs a scratch, which should
6371              be handled with SECONDARY_RELOADs.  */
6372           gcc_assert (REG_P (operands[0]));
6374           operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
6375           emit_insn (gen_movsi (operands[0], operands[1]));
6376           DONE;
6377         }
6378     }
6379   "
6382 (define_expand "movhi_bytes"
6383   [(set (match_dup 2) (zero_extend:SI (match_operand:HI 1 "" "")))
6384    (set (match_dup 3)
6385         (zero_extend:SI (match_dup 6)))
6386    (set (match_operand:SI 0 "" "")
6387          (ior:SI (ashift:SI (match_dup 4) (const_int 8)) (match_dup 5)))]
6388   "TARGET_ARM"
6389   "
6390   {
6391     rtx mem1, mem2;
6392     rtx addr = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
6394     mem1 = change_address (operands[1], QImode, addr);
6395     mem2 = change_address (operands[1], QImode,
6396                            plus_constant (Pmode, addr, 1));
6397     operands[0] = gen_lowpart (SImode, operands[0]);
6398     operands[1] = mem1;
6399     operands[2] = gen_reg_rtx (SImode);
6400     operands[3] = gen_reg_rtx (SImode);
6401     operands[6] = mem2;
6403     if (BYTES_BIG_ENDIAN)
6404       {
6405         operands[4] = operands[2];
6406         operands[5] = operands[3];
6407       }
6408     else
6409       {
6410         operands[4] = operands[3];
6411         operands[5] = operands[2];
6412       }
6413   }"
6416 (define_expand "movhi_bigend"
6417   [(set (match_dup 2)
6418         (rotate:SI (subreg:SI (match_operand:HI 1 "memory_operand" "") 0)
6419                    (const_int 16)))
6420    (set (match_dup 3)
6421         (ashiftrt:SI (match_dup 2) (const_int 16)))
6422    (set (match_operand:HI 0 "s_register_operand" "")
6423         (match_dup 4))]
6424   "TARGET_ARM"
6425   "
6426   operands[2] = gen_reg_rtx (SImode);
6427   operands[3] = gen_reg_rtx (SImode);
6428   operands[4] = gen_lowpart (HImode, operands[3]);
6429   "
6432 ;; Pattern to recognize insn generated default case above
6433 (define_insn "*movhi_insn_arch4"
6434   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m,r")
6435         (match_operand:HI 1 "general_operand"      "rIk,K,n,r,mi"))]
6436   "TARGET_ARM
6437    && arm_arch4
6438    && (register_operand (operands[0], HImode)
6439        || register_operand (operands[1], HImode))"
6440   "@
6441    mov%?\\t%0, %1\\t%@ movhi
6442    mvn%?\\t%0, #%B1\\t%@ movhi
6443    movw%?\\t%0, %L1\\t%@ movhi
6444    str%(h%)\\t%1, %0\\t%@ movhi
6445    ldr%(h%)\\t%0, %1\\t%@ movhi"
6446   [(set_attr "predicable" "yes")
6447    (set_attr "pool_range" "*,*,*,*,256")
6448    (set_attr "neg_pool_range" "*,*,*,*,244")
6449    (set_attr "arch" "*,*,v6t2,*,*")
6450    (set_attr_alternative "type"
6451                          [(if_then_else (match_operand 1 "const_int_operand" "")
6452                                         (const_string "mov_imm" )
6453                                         (const_string "mov_reg"))
6454                           (const_string "mvn_imm")
6455                           (const_string "mov_imm")
6456                           (const_string "store1")
6457                           (const_string "load1")])]
6460 (define_insn "*movhi_bytes"
6461   [(set (match_operand:HI 0 "s_register_operand" "=r,r,r")
6462         (match_operand:HI 1 "arm_rhs_operand"  "I,rk,K"))]
6463   "TARGET_ARM"
6464   "@
6465    mov%?\\t%0, %1\\t%@ movhi
6466    mov%?\\t%0, %1\\t%@ movhi
6467    mvn%?\\t%0, #%B1\\t%@ movhi"
6468   [(set_attr "predicable" "yes")
6469    (set_attr "type" "mov_imm,mov_reg,mvn_imm")]
6471         
6472 ;; We use a DImode scratch because we may occasionally need an additional
6473 ;; temporary if the address isn't offsettable -- push_reload doesn't seem
6474 ;; to take any notice of the "o" constraints on reload_memory_operand operand.
6475 (define_expand "reload_outhi"
6476   [(parallel [(match_operand:HI 0 "arm_reload_memory_operand" "=o")
6477               (match_operand:HI 1 "s_register_operand"        "r")
6478               (match_operand:DI 2 "s_register_operand"        "=&l")])]
6479   "TARGET_EITHER"
6480   "if (TARGET_ARM)
6481      arm_reload_out_hi (operands);
6482    else
6483      thumb_reload_out_hi (operands);
6484   DONE;
6485   "
6488 (define_expand "reload_inhi"
6489   [(parallel [(match_operand:HI 0 "s_register_operand" "=r")
6490               (match_operand:HI 1 "arm_reload_memory_operand" "o")
6491               (match_operand:DI 2 "s_register_operand" "=&r")])]
6492   "TARGET_EITHER"
6493   "
6494   if (TARGET_ARM)
6495     arm_reload_in_hi (operands);
6496   else
6497     thumb_reload_out_hi (operands);
6498   DONE;
6501 (define_expand "movqi"
6502   [(set (match_operand:QI 0 "general_operand" "")
6503         (match_operand:QI 1 "general_operand" ""))]
6504   "TARGET_EITHER"
6505   "
6506   /* Everything except mem = const or mem = mem can be done easily */
6508   if (can_create_pseudo_p ())
6509     {
6510       if (CONST_INT_P (operands[1]))
6511         {
6512           rtx reg = gen_reg_rtx (SImode);
6514           /* For thumb we want an unsigned immediate, then we are more likely 
6515              to be able to use a movs insn.  */
6516           if (TARGET_THUMB)
6517             operands[1] = GEN_INT (INTVAL (operands[1]) & 255);
6519           emit_insn (gen_movsi (reg, operands[1]));
6520           operands[1] = gen_lowpart (QImode, reg);
6521         }
6523       if (TARGET_THUMB)
6524         {
6525           /* ??? We shouldn't really get invalid addresses here, but this can
6526              happen if we are passed a SP (never OK for HImode/QImode) or
6527              virtual register (also rejected as illegitimate for HImode/QImode)
6528              relative address.  */
6529           /* ??? This should perhaps be fixed elsewhere, for instance, in
6530              fixup_stack_1, by checking for other kinds of invalid addresses,
6531              e.g. a bare reference to a virtual register.  This may confuse the
6532              alpha though, which must handle this case differently.  */
6533           if (MEM_P (operands[0])
6534               && !memory_address_p (GET_MODE (operands[0]),
6535                                      XEXP (operands[0], 0)))
6536             operands[0]
6537               = replace_equiv_address (operands[0],
6538                                        copy_to_reg (XEXP (operands[0], 0)));
6539           if (MEM_P (operands[1])
6540               && !memory_address_p (GET_MODE (operands[1]),
6541                                     XEXP (operands[1], 0)))
6542              operands[1]
6543                = replace_equiv_address (operands[1],
6544                                         copy_to_reg (XEXP (operands[1], 0)));
6545         }
6547       if (MEM_P (operands[1]) && optimize > 0)
6548         {
6549           rtx reg = gen_reg_rtx (SImode);
6551           emit_insn (gen_zero_extendqisi2 (reg, operands[1]));
6552           operands[1] = gen_lowpart (QImode, reg);
6553         }
6555       if (MEM_P (operands[0]))
6556         operands[1] = force_reg (QImode, operands[1]);
6557     }
6558   else if (TARGET_THUMB
6559            && CONST_INT_P (operands[1])
6560            && !satisfies_constraint_I (operands[1]))
6561     {
6562       /* Handle loading a large integer during reload.  */
6564       /* Writing a constant to memory needs a scratch, which should
6565          be handled with SECONDARY_RELOADs.  */
6566       gcc_assert (REG_P (operands[0]));
6568       operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
6569       emit_insn (gen_movsi (operands[0], operands[1]));
6570       DONE;
6571     }
6572   "
6575 (define_insn "*arm_movqi_insn"
6576   [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,r,l,r,l,Uu,r,m")
6577         (match_operand:QI 1 "general_operand" "rk,rk,I,Py,K,Uu,l,Uh,r"))]
6578   "TARGET_32BIT
6579    && (   register_operand (operands[0], QImode)
6580        || register_operand (operands[1], QImode))"
6581   "@
6582    mov%?\\t%0, %1
6583    mov%?\\t%0, %1
6584    mov%?\\t%0, %1
6585    mov%?\\t%0, %1
6586    mvn%?\\t%0, #%B1
6587    ldr%(b%)\\t%0, %1
6588    str%(b%)\\t%1, %0
6589    ldr%(b%)\\t%0, %1
6590    str%(b%)\\t%1, %0"
6591   [(set_attr "type" "mov_reg,mov_reg,mov_imm,mov_imm,mvn_imm,load1,store1,load1,store1")
6592    (set_attr "predicable" "yes")
6593    (set_attr "predicable_short_it" "yes,yes,yes,no,no,no,no,no,no")
6594    (set_attr "arch" "t2,any,any,t2,any,t2,t2,any,any")
6595    (set_attr "length" "2,4,4,2,4,2,2,4,4")]
6598 ;; HFmode moves
6599 (define_expand "movhf"
6600   [(set (match_operand:HF 0 "general_operand" "")
6601         (match_operand:HF 1 "general_operand" ""))]
6602   "TARGET_EITHER"
6603   "
6604   if (TARGET_32BIT)
6605     {
6606       if (MEM_P (operands[0]))
6607         operands[1] = force_reg (HFmode, operands[1]);
6608     }
6609   else /* TARGET_THUMB1 */
6610     {
6611       if (can_create_pseudo_p ())
6612         {
6613            if (!REG_P (operands[0]))
6614              operands[1] = force_reg (HFmode, operands[1]);
6615         }
6616     }
6617   "
6620 (define_insn "*arm32_movhf"
6621   [(set (match_operand:HF 0 "nonimmediate_operand" "=r,m,r,r")
6622         (match_operand:HF 1 "general_operand"      " m,r,r,F"))]
6623   "TARGET_32BIT && !(TARGET_HARD_FLOAT && TARGET_FP16)
6624    && (   s_register_operand (operands[0], HFmode)
6625        || s_register_operand (operands[1], HFmode))"
6626   "*
6627   switch (which_alternative)
6628     {
6629     case 0:     /* ARM register from memory */
6630       return \"ldr%(h%)\\t%0, %1\\t%@ __fp16\";
6631     case 1:     /* memory from ARM register */
6632       return \"str%(h%)\\t%1, %0\\t%@ __fp16\";
6633     case 2:     /* ARM register from ARM register */
6634       return \"mov%?\\t%0, %1\\t%@ __fp16\";
6635     case 3:     /* ARM register from constant */
6636       {
6637         REAL_VALUE_TYPE r;
6638         long bits;
6639         rtx ops[4];
6641         REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
6642         bits = real_to_target (NULL, &r, HFmode);
6643         ops[0] = operands[0];
6644         ops[1] = GEN_INT (bits);
6645         ops[2] = GEN_INT (bits & 0xff00);
6646         ops[3] = GEN_INT (bits & 0x00ff);
6648         if (arm_arch_thumb2)
6649           output_asm_insn (\"movw%?\\t%0, %1\", ops);
6650         else
6651           output_asm_insn (\"mov%?\\t%0, %2\;orr%?\\t%0, %0, %3\", ops);
6652         return \"\";
6653        }
6654     default:
6655       gcc_unreachable ();
6656     }
6657   "
6658   [(set_attr "conds" "unconditional")
6659    (set_attr "type" "load1,store1,mov_reg,multiple")
6660    (set_attr "length" "4,4,4,8")
6661    (set_attr "predicable" "yes")
6662    (set_attr "predicable_short_it" "no")]
6665 (define_expand "movsf"
6666   [(set (match_operand:SF 0 "general_operand" "")
6667         (match_operand:SF 1 "general_operand" ""))]
6668   "TARGET_EITHER"
6669   "
6670   if (TARGET_32BIT)
6671     {
6672       if (MEM_P (operands[0]))
6673         operands[1] = force_reg (SFmode, operands[1]);
6674     }
6675   else /* TARGET_THUMB1 */
6676     {
6677       if (can_create_pseudo_p ())
6678         {
6679            if (!REG_P (operands[0]))
6680              operands[1] = force_reg (SFmode, operands[1]);
6681         }
6682     }
6683   "
6686 ;; Transform a floating-point move of a constant into a core register into
6687 ;; an SImode operation.
6688 (define_split
6689   [(set (match_operand:SF 0 "arm_general_register_operand" "")
6690         (match_operand:SF 1 "immediate_operand" ""))]
6691   "TARGET_EITHER
6692    && reload_completed
6693    && CONST_DOUBLE_P (operands[1])"
6694   [(set (match_dup 2) (match_dup 3))]
6695   "
6696   operands[2] = gen_lowpart (SImode, operands[0]);
6697   operands[3] = gen_lowpart (SImode, operands[1]);
6698   if (operands[2] == 0 || operands[3] == 0)
6699     FAIL;
6700   "
6703 (define_insn "*arm_movsf_soft_insn"
6704   [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,m")
6705         (match_operand:SF 1 "general_operand"  "r,mE,r"))]
6706   "TARGET_32BIT
6707    && TARGET_SOFT_FLOAT
6708    && (!MEM_P (operands[0])
6709        || register_operand (operands[1], SFmode))"
6710   "@
6711    mov%?\\t%0, %1
6712    ldr%?\\t%0, %1\\t%@ float
6713    str%?\\t%1, %0\\t%@ float"
6714   [(set_attr "predicable" "yes")
6715    (set_attr "predicable_short_it" "no")
6716    (set_attr "type" "mov_reg,load1,store1")
6717    (set_attr "arm_pool_range" "*,4096,*")
6718    (set_attr "thumb2_pool_range" "*,4094,*")
6719    (set_attr "arm_neg_pool_range" "*,4084,*")
6720    (set_attr "thumb2_neg_pool_range" "*,0,*")]
6723 (define_expand "movdf"
6724   [(set (match_operand:DF 0 "general_operand" "")
6725         (match_operand:DF 1 "general_operand" ""))]
6726   "TARGET_EITHER"
6727   "
6728   if (TARGET_32BIT)
6729     {
6730       if (MEM_P (operands[0]))
6731         operands[1] = force_reg (DFmode, operands[1]);
6732     }
6733   else /* TARGET_THUMB */
6734     {
6735       if (can_create_pseudo_p ())
6736         {
6737           if (!REG_P (operands[0]))
6738             operands[1] = force_reg (DFmode, operands[1]);
6739         }
6740     }
6741   "
6744 ;; Reloading a df mode value stored in integer regs to memory can require a
6745 ;; scratch reg.
6746 (define_expand "reload_outdf"
6747   [(match_operand:DF 0 "arm_reload_memory_operand" "=o")
6748    (match_operand:DF 1 "s_register_operand" "r")
6749    (match_operand:SI 2 "s_register_operand" "=&r")]
6750   "TARGET_THUMB2"
6751   "
6752   {
6753     enum rtx_code code = GET_CODE (XEXP (operands[0], 0));
6755     if (code == REG)
6756       operands[2] = XEXP (operands[0], 0);
6757     else if (code == POST_INC || code == PRE_DEC)
6758       {
6759         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
6760         operands[1] = gen_rtx_SUBREG (DImode, operands[1], 0);
6761         emit_insn (gen_movdi (operands[0], operands[1]));
6762         DONE;
6763       }
6764     else if (code == PRE_INC)
6765       {
6766         rtx reg = XEXP (XEXP (operands[0], 0), 0);
6768         emit_insn (gen_addsi3 (reg, reg, GEN_INT (8)));
6769         operands[2] = reg;
6770       }
6771     else if (code == POST_DEC)
6772       operands[2] = XEXP (XEXP (operands[0], 0), 0);
6773     else
6774       emit_insn (gen_addsi3 (operands[2], XEXP (XEXP (operands[0], 0), 0),
6775                              XEXP (XEXP (operands[0], 0), 1)));
6777     emit_insn (gen_rtx_SET (replace_equiv_address (operands[0], operands[2]),
6778                             operands[1]));
6780     if (code == POST_DEC)
6781       emit_insn (gen_addsi3 (operands[2], operands[2], GEN_INT (-8)));
6783     DONE;
6784   }"
6787 (define_insn "*movdf_soft_insn"
6788   [(set (match_operand:DF 0 "nonimmediate_soft_df_operand" "=r,r,r,q,m")
6789         (match_operand:DF 1 "soft_df_operand" "rDa,Db,Dc,mF,q"))]
6790   "TARGET_32BIT && TARGET_SOFT_FLOAT
6791    && (   register_operand (operands[0], DFmode)
6792        || register_operand (operands[1], DFmode))"
6793   "*
6794   switch (which_alternative)
6795     {
6796     case 0:
6797     case 1:
6798     case 2:
6799       return \"#\";
6800     default:
6801       return output_move_double (operands, true, NULL);
6802     }
6803   "
6804   [(set_attr "length" "8,12,16,8,8")
6805    (set_attr "type" "multiple,multiple,multiple,load2,store2")
6806    (set_attr "arm_pool_range" "*,*,*,1020,*")
6807    (set_attr "thumb2_pool_range" "*,*,*,1018,*")
6808    (set_attr "arm_neg_pool_range" "*,*,*,1004,*")
6809    (set_attr "thumb2_neg_pool_range" "*,*,*,0,*")]
6813 ;; load- and store-multiple insns
6814 ;; The arm can load/store any set of registers, provided that they are in
6815 ;; ascending order, but these expanders assume a contiguous set.
6817 (define_expand "load_multiple"
6818   [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
6819                           (match_operand:SI 1 "" ""))
6820                      (use (match_operand:SI 2 "" ""))])]
6821   "TARGET_32BIT"
6823   HOST_WIDE_INT offset = 0;
6825   /* Support only fixed point registers.  */
6826   if (!CONST_INT_P (operands[2])
6827       || INTVAL (operands[2]) > MAX_LDM_STM_OPS
6828       || INTVAL (operands[2]) < 2
6829       || !MEM_P (operands[1])
6830       || !REG_P (operands[0])
6831       || REGNO (operands[0]) > (LAST_ARM_REGNUM - 1)
6832       || REGNO (operands[0]) + INTVAL (operands[2]) > LAST_ARM_REGNUM)
6833     FAIL;
6835   operands[3]
6836     = arm_gen_load_multiple (arm_regs_in_sequence + REGNO (operands[0]),
6837                              INTVAL (operands[2]),
6838                              force_reg (SImode, XEXP (operands[1], 0)),
6839                              FALSE, operands[1], &offset);
6842 (define_expand "store_multiple"
6843   [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
6844                           (match_operand:SI 1 "" ""))
6845                      (use (match_operand:SI 2 "" ""))])]
6846   "TARGET_32BIT"
6848   HOST_WIDE_INT offset = 0;
6850   /* Support only fixed point registers.  */
6851   if (!CONST_INT_P (operands[2])
6852       || INTVAL (operands[2]) > MAX_LDM_STM_OPS
6853       || INTVAL (operands[2]) < 2
6854       || !REG_P (operands[1])
6855       || !MEM_P (operands[0])
6856       || REGNO (operands[1]) > (LAST_ARM_REGNUM - 1)
6857       || REGNO (operands[1]) + INTVAL (operands[2]) > LAST_ARM_REGNUM)
6858     FAIL;
6860   operands[3]
6861     = arm_gen_store_multiple (arm_regs_in_sequence + REGNO (operands[1]),
6862                               INTVAL (operands[2]),
6863                               force_reg (SImode, XEXP (operands[0], 0)),
6864                               FALSE, operands[0], &offset);
6868 (define_expand "setmemsi"
6869   [(match_operand:BLK 0 "general_operand" "")
6870    (match_operand:SI 1 "const_int_operand" "")
6871    (match_operand:SI 2 "const_int_operand" "")
6872    (match_operand:SI 3 "const_int_operand" "")]
6873   "TARGET_32BIT"
6875   if (arm_gen_setmem (operands))
6876     DONE;
6878   FAIL;
6882 ;; Move a block of memory if it is word aligned and MORE than 2 words long.
6883 ;; We could let this apply for blocks of less than this, but it clobbers so
6884 ;; many registers that there is then probably a better way.
6886 (define_expand "movmemqi"
6887   [(match_operand:BLK 0 "general_operand" "")
6888    (match_operand:BLK 1 "general_operand" "")
6889    (match_operand:SI 2 "const_int_operand" "")
6890    (match_operand:SI 3 "const_int_operand" "")]
6891   ""
6892   "
6893   if (TARGET_32BIT)
6894     {
6895       if (TARGET_LDRD && current_tune->prefer_ldrd_strd
6896           && !optimize_function_for_size_p (cfun))
6897         {
6898           if (gen_movmem_ldrd_strd (operands))
6899             DONE;
6900           FAIL;
6901         }
6903       if (arm_gen_movmemqi (operands))
6904         DONE;
6905       FAIL;
6906     }
6907   else /* TARGET_THUMB1 */
6908     {
6909       if (   INTVAL (operands[3]) != 4
6910           || INTVAL (operands[2]) > 48)
6911         FAIL;
6913       thumb_expand_movmemqi (operands);
6914       DONE;
6915     }
6916   "
6920 ;; Compare & branch insns
6921 ;; The range calculations are based as follows:
6922 ;; For forward branches, the address calculation returns the address of
6923 ;; the next instruction.  This is 2 beyond the branch instruction.
6924 ;; For backward branches, the address calculation returns the address of
6925 ;; the first instruction in this pattern (cmp).  This is 2 before the branch
6926 ;; instruction for the shortest sequence, and 4 before the branch instruction
6927 ;; if we have to jump around an unconditional branch.
6928 ;; To the basic branch range the PC offset must be added (this is +4).
6929 ;; So for forward branches we have 
6930 ;;   (pos_range - pos_base_offs + pc_offs) = (pos_range - 2 + 4).
6931 ;; And for backward branches we have 
6932 ;;   (neg_range - neg_base_offs + pc_offs) = (neg_range - (-2 or -4) + 4).
6934 ;; For a 'b'       pos_range = 2046, neg_range = -2048 giving (-2040->2048).
6935 ;; For a 'b<cond>' pos_range = 254,  neg_range = -256  giving (-250 ->256).
6937 (define_expand "cbranchsi4"
6938   [(set (pc) (if_then_else
6939               (match_operator 0 "expandable_comparison_operator"
6940                [(match_operand:SI 1 "s_register_operand" "")
6941                 (match_operand:SI 2 "nonmemory_operand" "")])
6942               (label_ref (match_operand 3 "" ""))
6943               (pc)))]
6944   "TARGET_EITHER"
6945   "
6946   if (!TARGET_THUMB1)
6947     {
6948       if (!arm_validize_comparison (&operands[0], &operands[1], &operands[2]))
6949         FAIL;
6950       emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
6951                                       operands[3]));
6952       DONE;
6953     }
6954   if (thumb1_cmpneg_operand (operands[2], SImode))
6955     {
6956       emit_jump_insn (gen_cbranchsi4_scratch (NULL, operands[1], operands[2],
6957                                               operands[3], operands[0]));
6958       DONE;
6959     }
6960   if (!thumb1_cmp_operand (operands[2], SImode))
6961     operands[2] = force_reg (SImode, operands[2]);
6962   ")
6964 (define_expand "cbranchsf4"
6965   [(set (pc) (if_then_else
6966               (match_operator 0 "expandable_comparison_operator"
6967                [(match_operand:SF 1 "s_register_operand" "")
6968                 (match_operand:SF 2 "arm_float_compare_operand" "")])
6969               (label_ref (match_operand 3 "" ""))
6970               (pc)))]
6971   "TARGET_32BIT && TARGET_HARD_FLOAT"
6972   "emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
6973                                    operands[3])); DONE;"
6976 (define_expand "cbranchdf4"
6977   [(set (pc) (if_then_else
6978               (match_operator 0 "expandable_comparison_operator"
6979                [(match_operand:DF 1 "s_register_operand" "")
6980                 (match_operand:DF 2 "arm_float_compare_operand" "")])
6981               (label_ref (match_operand 3 "" ""))
6982               (pc)))]
6983   "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
6984   "emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
6985                                    operands[3])); DONE;"
6988 (define_expand "cbranchdi4"
6989   [(set (pc) (if_then_else
6990               (match_operator 0 "expandable_comparison_operator"
6991                [(match_operand:DI 1 "s_register_operand" "")
6992                 (match_operand:DI 2 "cmpdi_operand" "")])
6993               (label_ref (match_operand 3 "" ""))
6994               (pc)))]
6995   "TARGET_32BIT"
6996   "{
6997      if (!arm_validize_comparison (&operands[0], &operands[1], &operands[2]))
6998        FAIL;
6999      emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
7000                                        operands[3]));
7001      DONE;
7002    }"
7005 ;; Comparison and test insns
7007 (define_insn "*arm_cmpsi_insn"
7008   [(set (reg:CC CC_REGNUM)
7009         (compare:CC (match_operand:SI 0 "s_register_operand" "l,r,r,r,r")
7010                     (match_operand:SI 1 "arm_add_operand"    "Py,r,r,I,L")))]
7011   "TARGET_32BIT"
7012   "@
7013    cmp%?\\t%0, %1
7014    cmp%?\\t%0, %1
7015    cmp%?\\t%0, %1
7016    cmp%?\\t%0, %1
7017    cmn%?\\t%0, #%n1"
7018   [(set_attr "conds" "set")
7019    (set_attr "arch" "t2,t2,any,any,any")
7020    (set_attr "length" "2,2,4,4,4")
7021    (set_attr "predicable" "yes")
7022    (set_attr "predicable_short_it" "yes,yes,yes,no,no")
7023    (set_attr "type" "alus_imm,alus_sreg,alus_sreg,alus_imm,alus_imm")]
7026 (define_insn "*cmpsi_shiftsi"
7027   [(set (reg:CC CC_REGNUM)
7028         (compare:CC (match_operand:SI   0 "s_register_operand" "r,r,r")
7029                     (match_operator:SI  3 "shift_operator"
7030                      [(match_operand:SI 1 "s_register_operand" "r,r,r")
7031                       (match_operand:SI 2 "shift_amount_operand" "M,r,M")])))]
7032   "TARGET_32BIT"
7033   "cmp\\t%0, %1%S3"
7034   [(set_attr "conds" "set")
7035    (set_attr "shift" "1")
7036    (set_attr "arch" "32,a,a")
7037    (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
7039 (define_insn "*cmpsi_shiftsi_swp"
7040   [(set (reg:CC_SWP CC_REGNUM)
7041         (compare:CC_SWP (match_operator:SI 3 "shift_operator"
7042                          [(match_operand:SI 1 "s_register_operand" "r,r,r")
7043                           (match_operand:SI 2 "shift_amount_operand" "M,r,M")])
7044                         (match_operand:SI 0 "s_register_operand" "r,r,r")))]
7045   "TARGET_32BIT"
7046   "cmp%?\\t%0, %1%S3"
7047   [(set_attr "conds" "set")
7048    (set_attr "shift" "1")
7049    (set_attr "arch" "32,a,a")
7050    (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
7052 (define_insn "*arm_cmpsi_negshiftsi_si"
7053   [(set (reg:CC_Z CC_REGNUM)
7054         (compare:CC_Z
7055          (neg:SI (match_operator:SI 1 "shift_operator"
7056                     [(match_operand:SI 2 "s_register_operand" "r")
7057                      (match_operand:SI 3 "reg_or_int_operand" "rM")]))
7058          (match_operand:SI 0 "s_register_operand" "r")))]
7059   "TARGET_ARM"
7060   "cmn%?\\t%0, %2%S1"
7061   [(set_attr "conds" "set")
7062    (set (attr "type") (if_then_else (match_operand 3 "const_int_operand" "")
7063                                     (const_string "alus_shift_imm")
7064                                     (const_string "alus_shift_reg")))
7065    (set_attr "predicable" "yes")]
7068 ;; DImode comparisons.  The generic code generates branches that
7069 ;; if-conversion can not reduce to a conditional compare, so we do
7070 ;; that directly.
7072 (define_insn_and_split "*arm_cmpdi_insn"
7073   [(set (reg:CC_NCV CC_REGNUM)
7074         (compare:CC_NCV (match_operand:DI 0 "s_register_operand" "r")
7075                         (match_operand:DI 1 "arm_di_operand"       "rDi")))
7076    (clobber (match_scratch:SI 2 "=r"))]
7077   "TARGET_32BIT"
7078   "#"   ; "cmp\\t%Q0, %Q1\;sbcs\\t%2, %R0, %R1"
7079   "&& reload_completed"
7080   [(set (reg:CC CC_REGNUM)
7081         (compare:CC (match_dup 0) (match_dup 1)))
7082    (parallel [(set (reg:CC CC_REGNUM)
7083                    (compare:CC (match_dup 3) (match_dup 4)))
7084               (set (match_dup 2)
7085                    (minus:SI (match_dup 5)
7086                             (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))])]
7087   {
7088     operands[3] = gen_highpart (SImode, operands[0]);
7089     operands[0] = gen_lowpart (SImode, operands[0]);
7090     if (CONST_INT_P (operands[1]))
7091       {
7092         operands[4] = GEN_INT (~INTVAL (gen_highpart_mode (SImode,
7093                                                            DImode,
7094                                                            operands[1])));
7095         operands[5] = gen_rtx_PLUS (SImode, operands[3], operands[4]);
7096       }
7097     else
7098       {
7099         operands[4] = gen_highpart (SImode, operands[1]);
7100         operands[5] = gen_rtx_MINUS (SImode, operands[3], operands[4]);
7101       }
7102     operands[1] = gen_lowpart (SImode, operands[1]);
7103     operands[2] = gen_lowpart (SImode, operands[2]);
7104   }
7105   [(set_attr "conds" "set")
7106    (set_attr "length" "8")
7107    (set_attr "type" "multiple")]
7110 (define_insn_and_split "*arm_cmpdi_unsigned"
7111   [(set (reg:CC_CZ CC_REGNUM)
7112         (compare:CC_CZ (match_operand:DI 0 "s_register_operand" "l,r,r,r")
7113                        (match_operand:DI 1 "arm_di_operand"     "Py,r,Di,rDi")))]
7115   "TARGET_32BIT"
7116   "#"   ; "cmp\\t%R0, %R1\;it eq\;cmpeq\\t%Q0, %Q1"
7117   "&& reload_completed"
7118   [(set (reg:CC CC_REGNUM)
7119         (compare:CC (match_dup 2) (match_dup 3)))
7120    (cond_exec (eq:SI (reg:CC CC_REGNUM) (const_int 0))
7121               (set (reg:CC CC_REGNUM)
7122                    (compare:CC (match_dup 0) (match_dup 1))))]
7123   {
7124     operands[2] = gen_highpart (SImode, operands[0]);
7125     operands[0] = gen_lowpart (SImode, operands[0]);
7126     if (CONST_INT_P (operands[1]))
7127       operands[3] = gen_highpart_mode (SImode, DImode, operands[1]);
7128     else
7129       operands[3] = gen_highpart (SImode, operands[1]);
7130     operands[1] = gen_lowpart (SImode, operands[1]);
7131   }
7132   [(set_attr "conds" "set")
7133    (set_attr "enabled_for_depr_it" "yes,yes,no,*")
7134    (set_attr "arch" "t2,t2,t2,a")
7135    (set_attr "length" "6,6,10,8")
7136    (set_attr "type" "multiple")]
7139 (define_insn "*arm_cmpdi_zero"
7140   [(set (reg:CC_Z CC_REGNUM)
7141         (compare:CC_Z (match_operand:DI 0 "s_register_operand" "r")
7142                       (const_int 0)))
7143    (clobber (match_scratch:SI 1 "=r"))]
7144   "TARGET_32BIT"
7145   "orr%.\\t%1, %Q0, %R0"
7146   [(set_attr "conds" "set")
7147    (set_attr "type" "logics_reg")]
7150 ; This insn allows redundant compares to be removed by cse, nothing should
7151 ; ever appear in the output file since (set (reg x) (reg x)) is a no-op that
7152 ; is deleted later on. The match_dup will match the mode here, so that
7153 ; mode changes of the condition codes aren't lost by this even though we don't
7154 ; specify what they are.
7156 (define_insn "*deleted_compare"
7157   [(set (match_operand 0 "cc_register" "") (match_dup 0))]
7158   "TARGET_32BIT"
7159   "\\t%@ deleted compare"
7160   [(set_attr "conds" "set")
7161    (set_attr "length" "0")
7162    (set_attr "type" "no_insn")]
7166 ;; Conditional branch insns
7168 (define_expand "cbranch_cc"
7169   [(set (pc)
7170         (if_then_else (match_operator 0 "" [(match_operand 1 "" "")
7171                                             (match_operand 2 "" "")])
7172                       (label_ref (match_operand 3 "" ""))
7173                       (pc)))]
7174   "TARGET_32BIT"
7175   "operands[1] = arm_gen_compare_reg (GET_CODE (operands[0]),
7176                                       operands[1], operands[2], NULL_RTX);
7177    operands[2] = const0_rtx;"
7181 ;; Patterns to match conditional branch insns.
7184 (define_insn "arm_cond_branch"
7185   [(set (pc)
7186         (if_then_else (match_operator 1 "arm_comparison_operator"
7187                        [(match_operand 2 "cc_register" "") (const_int 0)])
7188                       (label_ref (match_operand 0 "" ""))
7189                       (pc)))]
7190   "TARGET_32BIT"
7191   "*
7192   if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
7193     {
7194       arm_ccfsm_state += 2;
7195       return \"\";
7196     }
7197   return \"b%d1\\t%l0\";
7198   "
7199   [(set_attr "conds" "use")
7200    (set_attr "type" "branch")
7201    (set (attr "length")
7202         (if_then_else
7203            (and (match_test "TARGET_THUMB2")
7204                 (and (ge (minus (match_dup 0) (pc)) (const_int -250))
7205                      (le (minus (match_dup 0) (pc)) (const_int 256))))
7206            (const_int 2)
7207            (const_int 4)))]
7210 (define_insn "*arm_cond_branch_reversed"
7211   [(set (pc)
7212         (if_then_else (match_operator 1 "arm_comparison_operator"
7213                        [(match_operand 2 "cc_register" "") (const_int 0)])
7214                       (pc)
7215                       (label_ref (match_operand 0 "" ""))))]
7216   "TARGET_32BIT"
7217   "*
7218   if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
7219     {
7220       arm_ccfsm_state += 2;
7221       return \"\";
7222     }
7223   return \"b%D1\\t%l0\";
7224   "
7225   [(set_attr "conds" "use")
7226    (set_attr "type" "branch")
7227    (set (attr "length")
7228         (if_then_else
7229            (and (match_test "TARGET_THUMB2")
7230                 (and (ge (minus (match_dup 0) (pc)) (const_int -250))
7231                      (le (minus (match_dup 0) (pc)) (const_int 256))))
7232            (const_int 2)
7233            (const_int 4)))]
7238 ; scc insns
7240 (define_expand "cstore_cc"
7241   [(set (match_operand:SI 0 "s_register_operand" "")
7242         (match_operator:SI 1 "" [(match_operand 2 "" "")
7243                                  (match_operand 3 "" "")]))]
7244   "TARGET_32BIT"
7245   "operands[2] = arm_gen_compare_reg (GET_CODE (operands[1]),
7246                                       operands[2], operands[3], NULL_RTX);
7247    operands[3] = const0_rtx;"
7250 (define_insn_and_split "*mov_scc"
7251   [(set (match_operand:SI 0 "s_register_operand" "=r")
7252         (match_operator:SI 1 "arm_comparison_operator"
7253          [(match_operand 2 "cc_register" "") (const_int 0)]))]
7254   "TARGET_ARM"
7255   "#"   ; "mov%D1\\t%0, #0\;mov%d1\\t%0, #1"
7256   "TARGET_ARM"
7257   [(set (match_dup 0)
7258         (if_then_else:SI (match_dup 1)
7259                          (const_int 1)
7260                          (const_int 0)))]
7261   ""
7262   [(set_attr "conds" "use")
7263    (set_attr "length" "8")
7264    (set_attr "type" "multiple")]
7267 (define_insn_and_split "*mov_negscc"
7268   [(set (match_operand:SI 0 "s_register_operand" "=r")
7269         (neg:SI (match_operator:SI 1 "arm_comparison_operator"
7270                  [(match_operand 2 "cc_register" "") (const_int 0)])))]
7271   "TARGET_ARM"
7272   "#"   ; "mov%D1\\t%0, #0\;mvn%d1\\t%0, #0"
7273   "TARGET_ARM"
7274   [(set (match_dup 0)
7275         (if_then_else:SI (match_dup 1)
7276                          (match_dup 3)
7277                          (const_int 0)))]
7278   {
7279     operands[3] = GEN_INT (~0);
7280   }
7281   [(set_attr "conds" "use")
7282    (set_attr "length" "8")
7283    (set_attr "type" "multiple")]
7286 (define_insn_and_split "*mov_notscc"
7287   [(set (match_operand:SI 0 "s_register_operand" "=r")
7288         (not:SI (match_operator:SI 1 "arm_comparison_operator"
7289                  [(match_operand 2 "cc_register" "") (const_int 0)])))]
7290   "TARGET_ARM"
7291   "#"   ; "mvn%D1\\t%0, #0\;mvn%d1\\t%0, #1"
7292   "TARGET_ARM"
7293   [(set (match_dup 0)
7294         (if_then_else:SI (match_dup 1)
7295                          (match_dup 3)
7296                          (match_dup 4)))]
7297   {
7298     operands[3] = GEN_INT (~1);
7299     operands[4] = GEN_INT (~0);
7300   }
7301   [(set_attr "conds" "use")
7302    (set_attr "length" "8")
7303    (set_attr "type" "multiple")]
7306 (define_expand "cstoresi4"
7307   [(set (match_operand:SI 0 "s_register_operand" "")
7308         (match_operator:SI 1 "expandable_comparison_operator"
7309          [(match_operand:SI 2 "s_register_operand" "")
7310           (match_operand:SI 3 "reg_or_int_operand" "")]))]
7311   "TARGET_32BIT || TARGET_THUMB1"
7312   "{
7313   rtx op3, scratch, scratch2;
7315   if (!TARGET_THUMB1)
7316     {
7317       if (!arm_add_operand (operands[3], SImode))
7318         operands[3] = force_reg (SImode, operands[3]);
7319       emit_insn (gen_cstore_cc (operands[0], operands[1],
7320                                 operands[2], operands[3]));
7321       DONE;
7322     }
7324   if (operands[3] == const0_rtx)
7325     {
7326       switch (GET_CODE (operands[1]))
7327         {
7328         case EQ:
7329           emit_insn (gen_cstoresi_eq0_thumb1 (operands[0], operands[2]));
7330           break;
7332         case NE:
7333           emit_insn (gen_cstoresi_ne0_thumb1 (operands[0], operands[2]));
7334           break;
7336         case LE:
7337           scratch = expand_binop (SImode, add_optab, operands[2], constm1_rtx,
7338                                   NULL_RTX, 0, OPTAB_WIDEN);
7339           scratch = expand_binop (SImode, ior_optab, operands[2], scratch,
7340                                   NULL_RTX, 0, OPTAB_WIDEN);
7341           expand_binop (SImode, lshr_optab, scratch, GEN_INT (31),
7342                         operands[0], 1, OPTAB_WIDEN);
7343           break;
7345         case GE:
7346           scratch = expand_unop (SImode, one_cmpl_optab, operands[2],
7347                                  NULL_RTX, 1);
7348           expand_binop (SImode, lshr_optab, scratch, GEN_INT (31),
7349                         NULL_RTX, 1, OPTAB_WIDEN);
7350           break;
7352         case GT:
7353           scratch = expand_binop (SImode, ashr_optab, operands[2],
7354                                   GEN_INT (31), NULL_RTX, 0, OPTAB_WIDEN);
7355           scratch = expand_binop (SImode, sub_optab, scratch, operands[2],
7356                                   NULL_RTX, 0, OPTAB_WIDEN);
7357           expand_binop (SImode, lshr_optab, scratch, GEN_INT (31), operands[0],
7358                         0, OPTAB_WIDEN);
7359           break;
7361         /* LT is handled by generic code.  No need for unsigned with 0.  */
7362         default:
7363           FAIL;
7364         }
7365       DONE;
7366     }
7368   switch (GET_CODE (operands[1]))
7369     {
7370     case EQ:
7371       scratch = expand_binop (SImode, sub_optab, operands[2], operands[3],
7372                               NULL_RTX, 0, OPTAB_WIDEN);
7373       emit_insn (gen_cstoresi_eq0_thumb1 (operands[0], scratch));
7374       break;
7376     case NE:
7377       scratch = expand_binop (SImode, sub_optab, operands[2], operands[3],
7378                               NULL_RTX, 0, OPTAB_WIDEN);
7379       emit_insn (gen_cstoresi_ne0_thumb1 (operands[0], scratch));
7380       break;
7382     case LE:
7383       op3 = force_reg (SImode, operands[3]);
7385       scratch = expand_binop (SImode, lshr_optab, operands[2], GEN_INT (31),
7386                               NULL_RTX, 1, OPTAB_WIDEN);
7387       scratch2 = expand_binop (SImode, ashr_optab, op3, GEN_INT (31),
7388                               NULL_RTX, 0, OPTAB_WIDEN);
7389       emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch2,
7390                                           op3, operands[2]));
7391       break;
7393     case GE:
7394       op3 = operands[3];
7395       if (!thumb1_cmp_operand (op3, SImode))
7396         op3 = force_reg (SImode, op3);
7397       scratch = expand_binop (SImode, ashr_optab, operands[2], GEN_INT (31),
7398                               NULL_RTX, 0, OPTAB_WIDEN);
7399       scratch2 = expand_binop (SImode, lshr_optab, op3, GEN_INT (31),
7400                                NULL_RTX, 1, OPTAB_WIDEN);
7401       emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch2,
7402                                           operands[2], op3));
7403       break;
7405     case LEU:
7406       op3 = force_reg (SImode, operands[3]);
7407       scratch = force_reg (SImode, const0_rtx);
7408       emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch,
7409                                           op3, operands[2]));
7410       break;
7412     case GEU:
7413       op3 = operands[3];
7414       if (!thumb1_cmp_operand (op3, SImode))
7415         op3 = force_reg (SImode, op3);
7416       scratch = force_reg (SImode, const0_rtx);
7417       emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch,
7418                                           operands[2], op3));
7419       break;
7421     case LTU:
7422       op3 = operands[3];
7423       if (!thumb1_cmp_operand (op3, SImode))
7424         op3 = force_reg (SImode, op3);
7425       scratch = gen_reg_rtx (SImode);
7426       emit_insn (gen_cstoresi_ltu_thumb1 (operands[0], operands[2], op3));
7427       break;
7429     case GTU:
7430       op3 = force_reg (SImode, operands[3]);
7431       scratch = gen_reg_rtx (SImode);
7432       emit_insn (gen_cstoresi_ltu_thumb1 (operands[0], op3, operands[2]));
7433       break;
7435     /* No good sequences for GT, LT.  */
7436     default:
7437       FAIL;
7438     }
7439   DONE;
7442 (define_expand "cstoresf4"
7443   [(set (match_operand:SI 0 "s_register_operand" "")
7444         (match_operator:SI 1 "expandable_comparison_operator"
7445          [(match_operand:SF 2 "s_register_operand" "")
7446           (match_operand:SF 3 "arm_float_compare_operand" "")]))]
7447   "TARGET_32BIT && TARGET_HARD_FLOAT"
7448   "emit_insn (gen_cstore_cc (operands[0], operands[1],
7449                              operands[2], operands[3])); DONE;"
7452 (define_expand "cstoredf4"
7453   [(set (match_operand:SI 0 "s_register_operand" "")
7454         (match_operator:SI 1 "expandable_comparison_operator"
7455          [(match_operand:DF 2 "s_register_operand" "")
7456           (match_operand:DF 3 "arm_float_compare_operand" "")]))]
7457   "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
7458   "emit_insn (gen_cstore_cc (operands[0], operands[1],
7459                              operands[2], operands[3])); DONE;"
7462 (define_expand "cstoredi4"
7463   [(set (match_operand:SI 0 "s_register_operand" "")
7464         (match_operator:SI 1 "expandable_comparison_operator"
7465          [(match_operand:DI 2 "s_register_operand" "")
7466           (match_operand:DI 3 "cmpdi_operand" "")]))]
7467   "TARGET_32BIT"
7468   "{
7469      if (!arm_validize_comparison (&operands[1],
7470                                    &operands[2],
7471                                    &operands[3]))
7472        FAIL;
7473      emit_insn (gen_cstore_cc (operands[0], operands[1], operands[2],
7474                                  operands[3]));
7475      DONE;
7476    }"
7480 ;; Conditional move insns
7482 (define_expand "movsicc"
7483   [(set (match_operand:SI 0 "s_register_operand" "")
7484         (if_then_else:SI (match_operand 1 "expandable_comparison_operator" "")
7485                          (match_operand:SI 2 "arm_not_operand" "")
7486                          (match_operand:SI 3 "arm_not_operand" "")))]
7487   "TARGET_32BIT"
7488   "
7489   {
7490     enum rtx_code code;
7491     rtx ccreg;
7493     if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0), 
7494                                   &XEXP (operands[1], 1)))
7495       FAIL;
7496     
7497     code = GET_CODE (operands[1]);
7498     ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
7499                                  XEXP (operands[1], 1), NULL_RTX);
7500     operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7501   }"
7504 (define_expand "movsfcc"
7505   [(set (match_operand:SF 0 "s_register_operand" "")
7506         (if_then_else:SF (match_operand 1 "arm_cond_move_operator" "")
7507                          (match_operand:SF 2 "s_register_operand" "")
7508                          (match_operand:SF 3 "s_register_operand" "")))]
7509   "TARGET_32BIT && TARGET_HARD_FLOAT"
7510   "
7511   {
7512     enum rtx_code code = GET_CODE (operands[1]);
7513     rtx ccreg;
7515     if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0), 
7516                                   &XEXP (operands[1], 1)))
7517        FAIL;
7519     code = GET_CODE (operands[1]);
7520     ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
7521                                  XEXP (operands[1], 1), NULL_RTX);
7522     operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7523   }"
7526 (define_expand "movdfcc"
7527   [(set (match_operand:DF 0 "s_register_operand" "")
7528         (if_then_else:DF (match_operand 1 "arm_cond_move_operator" "")
7529                          (match_operand:DF 2 "s_register_operand" "")
7530                          (match_operand:DF 3 "s_register_operand" "")))]
7531   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
7532   "
7533   {
7534     enum rtx_code code = GET_CODE (operands[1]);
7535     rtx ccreg;
7537     if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0), 
7538                                   &XEXP (operands[1], 1)))
7539        FAIL;
7540     code = GET_CODE (operands[1]);
7541     ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
7542                                  XEXP (operands[1], 1), NULL_RTX);
7543     operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7544   }"
7547 (define_insn "*cmov<mode>"
7548     [(set (match_operand:SDF 0 "s_register_operand" "=<F_constraint>")
7549         (if_then_else:SDF (match_operator 1 "arm_vsel_comparison_operator"
7550                           [(match_operand 2 "cc_register" "") (const_int 0)])
7551                           (match_operand:SDF 3 "s_register_operand"
7552                                               "<F_constraint>")
7553                           (match_operand:SDF 4 "s_register_operand"
7554                                               "<F_constraint>")))]
7555   "TARGET_HARD_FLOAT && TARGET_FPU_ARMV8 <vfp_double_cond>"
7556   "*
7557   {
7558     enum arm_cond_code code = maybe_get_arm_condition_code (operands[1]);
7559     switch (code)
7560       {
7561       case ARM_GE:
7562       case ARM_GT:
7563       case ARM_EQ:
7564       case ARM_VS:
7565         return \"vsel%d1.<V_if_elem>\\t%<V_reg>0, %<V_reg>3, %<V_reg>4\";
7566       case ARM_LT:
7567       case ARM_LE:
7568       case ARM_NE:
7569       case ARM_VC:
7570         return \"vsel%D1.<V_if_elem>\\t%<V_reg>0, %<V_reg>4, %<V_reg>3\";
7571       default:
7572         gcc_unreachable ();
7573       }
7574     return \"\";
7575   }"
7576   [(set_attr "conds" "use")
7577    (set_attr "type" "fcsel")]
7580 (define_insn_and_split "*movsicc_insn"
7581   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r,r,r,r,r")
7582         (if_then_else:SI
7583          (match_operator 3 "arm_comparison_operator"
7584           [(match_operand 4 "cc_register" "") (const_int 0)])
7585          (match_operand:SI 1 "arm_not_operand" "0,0,rI,K,rI,rI,K,K")
7586          (match_operand:SI 2 "arm_not_operand" "rI,K,0,0,rI,K,rI,K")))]
7587   "TARGET_ARM"
7588   "@
7589    mov%D3\\t%0, %2
7590    mvn%D3\\t%0, #%B2
7591    mov%d3\\t%0, %1
7592    mvn%d3\\t%0, #%B1
7593    #
7594    #
7595    #
7596    #"
7597    ; alt4: mov%d3\\t%0, %1\;mov%D3\\t%0, %2
7598    ; alt5: mov%d3\\t%0, %1\;mvn%D3\\t%0, #%B2
7599    ; alt6: mvn%d3\\t%0, #%B1\;mov%D3\\t%0, %2
7600    ; alt7: mvn%d3\\t%0, #%B1\;mvn%D3\\t%0, #%B2"
7601   "&& reload_completed"
7602   [(const_int 0)]
7603   {
7604     enum rtx_code rev_code;
7605     machine_mode mode;
7606     rtx rev_cond;
7608     emit_insn (gen_rtx_COND_EXEC (VOIDmode,
7609                                   operands[3],
7610                                   gen_rtx_SET (operands[0], operands[1])));
7612     rev_code = GET_CODE (operands[3]);
7613     mode = GET_MODE (operands[4]);
7614     if (mode == CCFPmode || mode == CCFPEmode)
7615       rev_code = reverse_condition_maybe_unordered (rev_code);
7616     else
7617       rev_code = reverse_condition (rev_code);
7619     rev_cond = gen_rtx_fmt_ee (rev_code,
7620                                VOIDmode,
7621                                operands[4],
7622                                const0_rtx);
7623     emit_insn (gen_rtx_COND_EXEC (VOIDmode,
7624                                   rev_cond,
7625                                   gen_rtx_SET (operands[0], operands[2])));
7626     DONE;
7627   }
7628   [(set_attr "length" "4,4,4,4,8,8,8,8")
7629    (set_attr "conds" "use")
7630    (set_attr_alternative "type"
7631                          [(if_then_else (match_operand 2 "const_int_operand" "")
7632                                         (const_string "mov_imm")
7633                                         (const_string "mov_reg"))
7634                           (const_string "mvn_imm")
7635                           (if_then_else (match_operand 1 "const_int_operand" "")
7636                                         (const_string "mov_imm")
7637                                         (const_string "mov_reg"))
7638                           (const_string "mvn_imm")
7639                           (const_string "multiple")
7640                           (const_string "multiple")
7641                           (const_string "multiple")
7642                           (const_string "multiple")])]
7645 (define_insn "*movsfcc_soft_insn"
7646   [(set (match_operand:SF 0 "s_register_operand" "=r,r")
7647         (if_then_else:SF (match_operator 3 "arm_comparison_operator"
7648                           [(match_operand 4 "cc_register" "") (const_int 0)])
7649                          (match_operand:SF 1 "s_register_operand" "0,r")
7650                          (match_operand:SF 2 "s_register_operand" "r,0")))]
7651   "TARGET_ARM && TARGET_SOFT_FLOAT"
7652   "@
7653    mov%D3\\t%0, %2
7654    mov%d3\\t%0, %1"
7655   [(set_attr "conds" "use")
7656    (set_attr "type" "mov_reg")]
7660 ;; Jump and linkage insns
7662 (define_expand "jump"
7663   [(set (pc)
7664         (label_ref (match_operand 0 "" "")))]
7665   "TARGET_EITHER"
7666   ""
7669 (define_insn "*arm_jump"
7670   [(set (pc)
7671         (label_ref (match_operand 0 "" "")))]
7672   "TARGET_32BIT"
7673   "*
7674   {
7675     if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
7676       {
7677         arm_ccfsm_state += 2;
7678         return \"\";
7679       }
7680     return \"b%?\\t%l0\";
7681   }
7682   "
7683   [(set_attr "predicable" "yes")
7684    (set (attr "length")
7685         (if_then_else
7686            (and (match_test "TARGET_THUMB2")
7687                 (and (ge (minus (match_dup 0) (pc)) (const_int -2044))
7688                      (le (minus (match_dup 0) (pc)) (const_int 2048))))
7689            (const_int 2)
7690            (const_int 4)))
7691    (set_attr "type" "branch")]
7694 (define_expand "call"
7695   [(parallel [(call (match_operand 0 "memory_operand" "")
7696                     (match_operand 1 "general_operand" ""))
7697               (use (match_operand 2 "" ""))
7698               (clobber (reg:SI LR_REGNUM))])]
7699   "TARGET_EITHER"
7700   "
7701   {
7702     rtx callee, pat;
7703     
7704     /* In an untyped call, we can get NULL for operand 2.  */
7705     if (operands[2] == NULL_RTX)
7706       operands[2] = const0_rtx;
7707       
7708     /* Decide if we should generate indirect calls by loading the
7709        32-bit address of the callee into a register before performing the
7710        branch and link.  */
7711     callee = XEXP (operands[0], 0);
7712     if (GET_CODE (callee) == SYMBOL_REF
7713         ? arm_is_long_call_p (SYMBOL_REF_DECL (callee))
7714         : !REG_P (callee))
7715       XEXP (operands[0], 0) = force_reg (Pmode, callee);
7717     pat = gen_call_internal (operands[0], operands[1], operands[2]);
7718     arm_emit_call_insn (pat, XEXP (operands[0], 0), false);
7719     DONE;
7720   }"
7723 (define_expand "call_internal"
7724   [(parallel [(call (match_operand 0 "memory_operand" "")
7725                     (match_operand 1 "general_operand" ""))
7726               (use (match_operand 2 "" ""))
7727               (clobber (reg:SI LR_REGNUM))])])
7729 (define_insn "*call_reg_armv5"
7730   [(call (mem:SI (match_operand:SI 0 "s_register_operand" "r"))
7731          (match_operand 1 "" ""))
7732    (use (match_operand 2 "" ""))
7733    (clobber (reg:SI LR_REGNUM))]
7734   "TARGET_ARM && arm_arch5 && !SIBLING_CALL_P (insn)"
7735   "blx%?\\t%0"
7736   [(set_attr "type" "call")]
7739 (define_insn "*call_reg_arm"
7740   [(call (mem:SI (match_operand:SI 0 "s_register_operand" "r"))
7741          (match_operand 1 "" ""))
7742    (use (match_operand 2 "" ""))
7743    (clobber (reg:SI LR_REGNUM))]
7744   "TARGET_ARM && !arm_arch5 && !SIBLING_CALL_P (insn)"
7745   "*
7746   return output_call (operands);
7747   "
7748   ;; length is worst case, normally it is only two
7749   [(set_attr "length" "12")
7750    (set_attr "type" "call")]
7754 ;; Note: not used for armv5+ because the sequence used (ldr pc, ...) is not
7755 ;; considered a function call by the branch predictor of some cores (PR40887).
7756 ;; Falls back to blx rN (*call_reg_armv5).
7758 (define_insn "*call_mem"
7759   [(call (mem:SI (match_operand:SI 0 "call_memory_operand" "m"))
7760          (match_operand 1 "" ""))
7761    (use (match_operand 2 "" ""))
7762    (clobber (reg:SI LR_REGNUM))]
7763   "TARGET_ARM && !arm_arch5 && !SIBLING_CALL_P (insn)"
7764   "*
7765   return output_call_mem (operands);
7766   "
7767   [(set_attr "length" "12")
7768    (set_attr "type" "call")]
7771 (define_expand "call_value"
7772   [(parallel [(set (match_operand       0 "" "")
7773                    (call (match_operand 1 "memory_operand" "")
7774                          (match_operand 2 "general_operand" "")))
7775               (use (match_operand 3 "" ""))
7776               (clobber (reg:SI LR_REGNUM))])]
7777   "TARGET_EITHER"
7778   "
7779   {
7780     rtx pat, callee;
7781     
7782     /* In an untyped call, we can get NULL for operand 2.  */
7783     if (operands[3] == 0)
7784       operands[3] = const0_rtx;
7785       
7786     /* Decide if we should generate indirect calls by loading the
7787        32-bit address of the callee into a register before performing the
7788        branch and link.  */
7789     callee = XEXP (operands[1], 0);
7790     if (GET_CODE (callee) == SYMBOL_REF
7791         ? arm_is_long_call_p (SYMBOL_REF_DECL (callee))
7792         : !REG_P (callee))
7793       XEXP (operands[1], 0) = force_reg (Pmode, callee);
7795     pat = gen_call_value_internal (operands[0], operands[1],
7796                                    operands[2], operands[3]);
7797     arm_emit_call_insn (pat, XEXP (operands[1], 0), false);
7798     DONE;
7799   }"
7802 (define_expand "call_value_internal"
7803   [(parallel [(set (match_operand       0 "" "")
7804                    (call (match_operand 1 "memory_operand" "")
7805                          (match_operand 2 "general_operand" "")))
7806               (use (match_operand 3 "" ""))
7807               (clobber (reg:SI LR_REGNUM))])])
7809 (define_insn "*call_value_reg_armv5"
7810   [(set (match_operand 0 "" "")
7811         (call (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
7812               (match_operand 2 "" "")))
7813    (use (match_operand 3 "" ""))
7814    (clobber (reg:SI LR_REGNUM))]
7815   "TARGET_ARM && arm_arch5 && !SIBLING_CALL_P (insn)"
7816   "blx%?\\t%1"
7817   [(set_attr "type" "call")]
7820 (define_insn "*call_value_reg_arm"
7821   [(set (match_operand 0 "" "")
7822         (call (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
7823               (match_operand 2 "" "")))
7824    (use (match_operand 3 "" ""))
7825    (clobber (reg:SI LR_REGNUM))]
7826   "TARGET_ARM && !arm_arch5 && !SIBLING_CALL_P (insn)"
7827   "*
7828   return output_call (&operands[1]);
7829   "
7830   [(set_attr "length" "12")
7831    (set_attr "type" "call")]
7834 ;; Note: see *call_mem
7836 (define_insn "*call_value_mem"
7837   [(set (match_operand 0 "" "")
7838         (call (mem:SI (match_operand:SI 1 "call_memory_operand" "m"))
7839               (match_operand 2 "" "")))
7840    (use (match_operand 3 "" ""))
7841    (clobber (reg:SI LR_REGNUM))]
7842   "TARGET_ARM && !arm_arch5 && (!CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
7843    && !SIBLING_CALL_P (insn)"
7844   "*
7845   return output_call_mem (&operands[1]);
7846   "
7847   [(set_attr "length" "12")
7848    (set_attr "type" "call")]
7851 ;; Allow calls to SYMBOL_REFs specially as they are not valid general addresses
7852 ;; The 'a' causes the operand to be treated as an address, i.e. no '#' output.
7854 (define_insn "*call_symbol"
7855   [(call (mem:SI (match_operand:SI 0 "" ""))
7856          (match_operand 1 "" ""))
7857    (use (match_operand 2 "" ""))
7858    (clobber (reg:SI LR_REGNUM))]
7859   "TARGET_32BIT
7860    && !SIBLING_CALL_P (insn)
7861    && (GET_CODE (operands[0]) == SYMBOL_REF)
7862    && !arm_is_long_call_p (SYMBOL_REF_DECL (operands[0]))"
7863   "*
7864   {
7865    rtx op = operands[0];
7867    /* Switch mode now when possible.  */
7868    if (SYMBOL_REF_DECL (op) && !TREE_PUBLIC (SYMBOL_REF_DECL (op))
7869         && arm_arch5 && arm_change_mode_p (SYMBOL_REF_DECL (op)))
7870       return NEED_PLT_RELOC ? \"blx%?\\t%a0(PLT)\" : \"blx%?\\t(%a0)\";
7872     return NEED_PLT_RELOC ? \"bl%?\\t%a0(PLT)\" : \"bl%?\\t%a0\";
7873   }"
7874   [(set_attr "type" "call")]
7877 (define_insn "*call_value_symbol"
7878   [(set (match_operand 0 "" "")
7879         (call (mem:SI (match_operand:SI 1 "" ""))
7880         (match_operand:SI 2 "" "")))
7881    (use (match_operand 3 "" ""))
7882    (clobber (reg:SI LR_REGNUM))]
7883   "TARGET_32BIT
7884    && !SIBLING_CALL_P (insn)
7885    && (GET_CODE (operands[1]) == SYMBOL_REF)
7886    && !arm_is_long_call_p (SYMBOL_REF_DECL (operands[1]))"
7887   "*
7888   {
7889    rtx op = operands[1];
7891    /* Switch mode now when possible.  */
7892    if (SYMBOL_REF_DECL (op) && !TREE_PUBLIC (SYMBOL_REF_DECL (op))
7893         && arm_arch5 && arm_change_mode_p (SYMBOL_REF_DECL (op)))
7894       return NEED_PLT_RELOC ? \"blx%?\\t%a1(PLT)\" : \"blx%?\\t(%a1)\";
7896     return NEED_PLT_RELOC ? \"bl%?\\t%a1(PLT)\" : \"bl%?\\t%a1\";
7897   }"
7898   [(set_attr "type" "call")]
7901 (define_expand "sibcall_internal"
7902   [(parallel [(call (match_operand 0 "memory_operand" "")
7903                     (match_operand 1 "general_operand" ""))
7904               (return)
7905               (use (match_operand 2 "" ""))])])
7907 ;; We may also be able to do sibcalls for Thumb, but it's much harder...
7908 (define_expand "sibcall"
7909   [(parallel [(call (match_operand 0 "memory_operand" "")
7910                     (match_operand 1 "general_operand" ""))
7911               (return)
7912               (use (match_operand 2 "" ""))])]
7913   "TARGET_32BIT"
7914   "
7915   {
7916     rtx pat;
7918     if ((!REG_P (XEXP (operands[0], 0))
7919          && GET_CODE (XEXP (operands[0], 0)) != SYMBOL_REF)
7920         || (GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
7921             && arm_is_long_call_p (SYMBOL_REF_DECL (XEXP (operands[0], 0)))))
7922      XEXP (operands[0], 0) = force_reg (SImode, XEXP (operands[0], 0));
7924     if (operands[2] == NULL_RTX)
7925       operands[2] = const0_rtx;
7927     pat = gen_sibcall_internal (operands[0], operands[1], operands[2]);
7928     arm_emit_call_insn (pat, operands[0], true);
7929     DONE;
7930   }"
7933 (define_expand "sibcall_value_internal"
7934   [(parallel [(set (match_operand 0 "" "")
7935                    (call (match_operand 1 "memory_operand" "")
7936                          (match_operand 2 "general_operand" "")))
7937               (return)
7938               (use (match_operand 3 "" ""))])])
7940 (define_expand "sibcall_value"
7941   [(parallel [(set (match_operand 0 "" "")
7942                    (call (match_operand 1 "memory_operand" "")
7943                          (match_operand 2 "general_operand" "")))
7944               (return)
7945               (use (match_operand 3 "" ""))])]
7946   "TARGET_32BIT"
7947   "
7948   {
7949     rtx pat;
7951     if ((!REG_P (XEXP (operands[1], 0))
7952          && GET_CODE (XEXP (operands[1], 0)) != SYMBOL_REF)
7953         || (GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
7954             && arm_is_long_call_p (SYMBOL_REF_DECL (XEXP (operands[1], 0)))))
7955      XEXP (operands[1], 0) = force_reg (SImode, XEXP (operands[1], 0));
7957     if (operands[3] == NULL_RTX)
7958       operands[3] = const0_rtx;
7960     pat = gen_sibcall_value_internal (operands[0], operands[1],
7961                                       operands[2], operands[3]);
7962     arm_emit_call_insn (pat, operands[1], true);
7963     DONE;
7964   }"
7967 (define_insn "*sibcall_insn"
7968  [(call (mem:SI (match_operand:SI 0 "call_insn_operand" "Cs, US"))
7969         (match_operand 1 "" ""))
7970   (return)
7971   (use (match_operand 2 "" ""))]
7972   "TARGET_32BIT && SIBLING_CALL_P (insn)"
7973   "*
7974   if (which_alternative == 1)
7975     return NEED_PLT_RELOC ? \"b%?\\t%a0(PLT)\" : \"b%?\\t%a0\";
7976   else
7977     {
7978       if (arm_arch5 || arm_arch4t)
7979         return \"bx%?\\t%0\\t%@ indirect register sibling call\";
7980       else
7981         return \"mov%?\\t%|pc, %0\\t%@ indirect register sibling call\";
7982     }
7983   "
7984   [(set_attr "type" "call")]
7987 (define_insn "*sibcall_value_insn"
7988  [(set (match_operand 0 "" "")
7989        (call (mem:SI (match_operand:SI 1 "call_insn_operand" "Cs,US"))
7990              (match_operand 2 "" "")))
7991   (return)
7992   (use (match_operand 3 "" ""))]
7993   "TARGET_32BIT && SIBLING_CALL_P (insn)"
7994   "*
7995   if (which_alternative == 1)
7996    return NEED_PLT_RELOC ? \"b%?\\t%a1(PLT)\" : \"b%?\\t%a1\";
7997   else
7998     {
7999       if (arm_arch5 || arm_arch4t)
8000         return \"bx%?\\t%1\";
8001       else
8002         return \"mov%?\\t%|pc, %1\\t@ indirect sibling call \";
8003     }
8004   "
8005   [(set_attr "type" "call")]
8008 (define_expand "<return_str>return"
8009   [(RETURNS)]
8010   "(TARGET_ARM || (TARGET_THUMB2
8011                    && ARM_FUNC_TYPE (arm_current_func_type ()) == ARM_FT_NORMAL
8012                    && !IS_STACKALIGN (arm_current_func_type ())))
8013     <return_cond_false>"
8014   "
8015   {
8016     if (TARGET_THUMB2)
8017       {
8018         thumb2_expand_return (<return_simple_p>);
8019         DONE;
8020       }
8021   }
8022   "
8025 ;; Often the return insn will be the same as loading from memory, so set attr
8026 (define_insn "*arm_return"
8027   [(return)]
8028   "TARGET_ARM && USE_RETURN_INSN (FALSE)"
8029   "*
8030   {
8031     if (arm_ccfsm_state == 2)
8032       {
8033         arm_ccfsm_state += 2;
8034         return \"\";
8035       }
8036     return output_return_instruction (const_true_rtx, true, false, false);
8037   }"
8038   [(set_attr "type" "load1")
8039    (set_attr "length" "12")
8040    (set_attr "predicable" "yes")]
8043 (define_insn "*cond_<return_str>return"
8044   [(set (pc)
8045         (if_then_else (match_operator 0 "arm_comparison_operator"
8046                        [(match_operand 1 "cc_register" "") (const_int 0)])
8047                       (RETURNS)
8048                       (pc)))]
8049   "TARGET_ARM  <return_cond_true>"
8050   "*
8051   {
8052     if (arm_ccfsm_state == 2)
8053       {
8054         arm_ccfsm_state += 2;
8055         return \"\";
8056       }
8057     return output_return_instruction (operands[0], true, false,
8058                                       <return_simple_p>);
8059   }"
8060   [(set_attr "conds" "use")
8061    (set_attr "length" "12")
8062    (set_attr "type" "load1")]
8065 (define_insn "*cond_<return_str>return_inverted"
8066   [(set (pc)
8067         (if_then_else (match_operator 0 "arm_comparison_operator"
8068                        [(match_operand 1 "cc_register" "") (const_int 0)])
8069                       (pc)
8070                       (RETURNS)))]
8071   "TARGET_ARM <return_cond_true>"
8072   "*
8073   {
8074     if (arm_ccfsm_state == 2)
8075       {
8076         arm_ccfsm_state += 2;
8077         return \"\";
8078       }
8079     return output_return_instruction (operands[0], true, true,
8080                                       <return_simple_p>);
8081   }"
8082   [(set_attr "conds" "use")
8083    (set_attr "length" "12")
8084    (set_attr "type" "load1")]
8087 (define_insn "*arm_simple_return"
8088   [(simple_return)]
8089   "TARGET_ARM"
8090   "*
8091   {
8092     if (arm_ccfsm_state == 2)
8093       {
8094         arm_ccfsm_state += 2;
8095         return \"\";
8096       }
8097     return output_return_instruction (const_true_rtx, true, false, true);
8098   }"
8099   [(set_attr "type" "branch")
8100    (set_attr "length" "4")
8101    (set_attr "predicable" "yes")]
8104 ;; Generate a sequence of instructions to determine if the processor is
8105 ;; in 26-bit or 32-bit mode, and return the appropriate return address
8106 ;; mask.
8108 (define_expand "return_addr_mask"
8109   [(set (match_dup 1)
8110       (compare:CC_NOOV (unspec [(const_int 0)] UNSPEC_CHECK_ARCH)
8111                        (const_int 0)))
8112    (set (match_operand:SI 0 "s_register_operand" "")
8113       (if_then_else:SI (eq (match_dup 1) (const_int 0))
8114                        (const_int -1)
8115                        (const_int 67108860)))] ; 0x03fffffc
8116   "TARGET_ARM"
8117   "
8118   operands[1] = gen_rtx_REG (CC_NOOVmode, CC_REGNUM);
8119   ")
8121 (define_insn "*check_arch2"
8122   [(set (match_operand:CC_NOOV 0 "cc_register" "")
8123       (compare:CC_NOOV (unspec [(const_int 0)] UNSPEC_CHECK_ARCH)
8124                        (const_int 0)))]
8125   "TARGET_ARM"
8126   "teq\\t%|r0, %|r0\;teq\\t%|pc, %|pc"
8127   [(set_attr "length" "8")
8128    (set_attr "conds" "set")
8129    (set_attr "type" "multiple")]
8132 ;; Call subroutine returning any type.
8134 (define_expand "untyped_call"
8135   [(parallel [(call (match_operand 0 "" "")
8136                     (const_int 0))
8137               (match_operand 1 "" "")
8138               (match_operand 2 "" "")])]
8139   "TARGET_EITHER"
8140   "
8141   {
8142     int i;
8143     rtx par = gen_rtx_PARALLEL (VOIDmode,
8144                                 rtvec_alloc (XVECLEN (operands[2], 0)));
8145     rtx addr = gen_reg_rtx (Pmode);
8146     rtx mem;
8147     int size = 0;
8149     emit_move_insn (addr, XEXP (operands[1], 0));
8150     mem = change_address (operands[1], BLKmode, addr);
8152     for (i = 0; i < XVECLEN (operands[2], 0); i++)
8153       {
8154         rtx src = SET_SRC (XVECEXP (operands[2], 0, i));
8156         /* Default code only uses r0 as a return value, but we could
8157            be using anything up to 4 registers.  */
8158         if (REGNO (src) == R0_REGNUM)
8159           src = gen_rtx_REG (TImode, R0_REGNUM);
8161         XVECEXP (par, 0, i) = gen_rtx_EXPR_LIST (VOIDmode, src,
8162                                                  GEN_INT (size));
8163         size += GET_MODE_SIZE (GET_MODE (src));
8164       }
8166     emit_call_insn (gen_call_value (par, operands[0], const0_rtx, NULL));
8168     size = 0;
8170     for (i = 0; i < XVECLEN (par, 0); i++)
8171       {
8172         HOST_WIDE_INT offset = 0;
8173         rtx reg = XEXP (XVECEXP (par, 0, i), 0);
8175         if (size != 0)
8176           emit_move_insn (addr, plus_constant (Pmode, addr, size));
8178         mem = change_address (mem, GET_MODE (reg), NULL);
8179         if (REGNO (reg) == R0_REGNUM)
8180           {
8181             /* On thumb we have to use a write-back instruction.  */
8182             emit_insn (arm_gen_store_multiple (arm_regs_in_sequence, 4, addr,
8183                        TARGET_THUMB ? TRUE : FALSE, mem, &offset));
8184             size = TARGET_ARM ? 16 : 0;
8185           }
8186         else
8187           {
8188             emit_move_insn (mem, reg);
8189             size = GET_MODE_SIZE (GET_MODE (reg));
8190           }
8191       }
8193     /* The optimizer does not know that the call sets the function value
8194        registers we stored in the result block.  We avoid problems by
8195        claiming that all hard registers are used and clobbered at this
8196        point.  */
8197     emit_insn (gen_blockage ());
8199     DONE;
8200   }"
8203 (define_expand "untyped_return"
8204   [(match_operand:BLK 0 "memory_operand" "")
8205    (match_operand 1 "" "")]
8206   "TARGET_EITHER"
8207   "
8208   {
8209     int i;
8210     rtx addr = gen_reg_rtx (Pmode);
8211     rtx mem;
8212     int size = 0;
8214     emit_move_insn (addr, XEXP (operands[0], 0));
8215     mem = change_address (operands[0], BLKmode, addr);
8217     for (i = 0; i < XVECLEN (operands[1], 0); i++)
8218       {
8219         HOST_WIDE_INT offset = 0;
8220         rtx reg = SET_DEST (XVECEXP (operands[1], 0, i));
8222         if (size != 0)
8223           emit_move_insn (addr, plus_constant (Pmode, addr, size));
8225         mem = change_address (mem, GET_MODE (reg), NULL);
8226         if (REGNO (reg) == R0_REGNUM)
8227           {
8228             /* On thumb we have to use a write-back instruction.  */
8229             emit_insn (arm_gen_load_multiple (arm_regs_in_sequence, 4, addr,
8230                        TARGET_THUMB ? TRUE : FALSE, mem, &offset));
8231             size = TARGET_ARM ? 16 : 0;
8232           }
8233         else
8234           {
8235             emit_move_insn (reg, mem);
8236             size = GET_MODE_SIZE (GET_MODE (reg));
8237           }
8238       }
8240     /* Emit USE insns before the return.  */
8241     for (i = 0; i < XVECLEN (operands[1], 0); i++)
8242       emit_use (SET_DEST (XVECEXP (operands[1], 0, i)));
8244     /* Construct the return.  */
8245     expand_naked_return ();
8247     DONE;
8248   }"
8251 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
8252 ;; all of memory.  This blocks insns from being moved across this point.
8254 (define_insn "blockage"
8255   [(unspec_volatile [(const_int 0)] VUNSPEC_BLOCKAGE)]
8256   "TARGET_EITHER"
8257   ""
8258   [(set_attr "length" "0")
8259    (set_attr "type" "block")]
8262 (define_insn "probe_stack"
8263   [(set (match_operand 0 "memory_operand" "=m")
8264         (unspec [(const_int 0)] UNSPEC_PROBE_STACK))]
8265   "TARGET_32BIT"
8267   return "str%?\\tr0, %0";
8269   [(set_attr "type" "store1")
8270    (set_attr "predicable" "yes")]
8273 (define_insn "probe_stack_range"
8274   [(set (match_operand:SI 0 "register_operand" "=r")
8275         (unspec_volatile:SI [(match_operand:SI 1 "register_operand" "0")
8276                              (match_operand:SI 2 "register_operand" "r")]
8277                              UNSPEC_PROBE_STACK_RANGE))]
8278   "TARGET_32BIT"
8280   return output_probe_stack_range (operands[0], operands[2]);
8282   [(set_attr "type" "multiple")
8283    (set_attr "conds" "clob")]
8286 (define_expand "casesi"
8287   [(match_operand:SI 0 "s_register_operand" "") ; index to jump on
8288    (match_operand:SI 1 "const_int_operand" "")  ; lower bound
8289    (match_operand:SI 2 "const_int_operand" "")  ; total range
8290    (match_operand:SI 3 "" "")                   ; table label
8291    (match_operand:SI 4 "" "")]                  ; Out of range label
8292   "TARGET_32BIT || optimize_size || flag_pic"
8293   "
8294   {
8295     enum insn_code code;
8296     if (operands[1] != const0_rtx)
8297       {
8298         rtx reg = gen_reg_rtx (SImode);
8300         emit_insn (gen_addsi3 (reg, operands[0],
8301                                gen_int_mode (-INTVAL (operands[1]),
8302                                              SImode)));
8303         operands[0] = reg;
8304       }
8306     if (TARGET_ARM)
8307       code = CODE_FOR_arm_casesi_internal;
8308     else if (TARGET_THUMB1)
8309       code = CODE_FOR_thumb1_casesi_internal_pic;
8310     else if (flag_pic)
8311       code = CODE_FOR_thumb2_casesi_internal_pic;
8312     else
8313       code = CODE_FOR_thumb2_casesi_internal;
8315     if (!insn_data[(int) code].operand[1].predicate(operands[2], SImode))
8316       operands[2] = force_reg (SImode, operands[2]);
8318     emit_jump_insn (GEN_FCN ((int) code) (operands[0], operands[2],
8319                                           operands[3], operands[4]));
8320     DONE;
8321   }"
8324 ;; The USE in this pattern is needed to tell flow analysis that this is
8325 ;; a CASESI insn.  It has no other purpose.
8326 (define_insn "arm_casesi_internal"
8327   [(parallel [(set (pc)
8328                (if_then_else
8329                 (leu (match_operand:SI 0 "s_register_operand" "r")
8330                      (match_operand:SI 1 "arm_rhs_operand" "rI"))
8331                 (mem:SI (plus:SI (mult:SI (match_dup 0) (const_int 4))
8332                                  (label_ref (match_operand 2 "" ""))))
8333                 (label_ref (match_operand 3 "" ""))))
8334               (clobber (reg:CC CC_REGNUM))
8335               (use (label_ref (match_dup 2)))])]
8336   "TARGET_ARM"
8337   "*
8338     if (flag_pic)
8339       return \"cmp\\t%0, %1\;addls\\t%|pc, %|pc, %0, asl #2\;b\\t%l3\";
8340     return   \"cmp\\t%0, %1\;ldrls\\t%|pc, [%|pc, %0, asl #2]\;b\\t%l3\";
8341   "
8342   [(set_attr "conds" "clob")
8343    (set_attr "length" "12")
8344    (set_attr "type" "multiple")]
8347 (define_expand "indirect_jump"
8348   [(set (pc)
8349         (match_operand:SI 0 "s_register_operand" ""))]
8350   "TARGET_EITHER"
8351   "
8352   /* Thumb-2 doesn't have mov pc, reg.  Explicitly set the low bit of the
8353      address and use bx.  */
8354   if (TARGET_THUMB2)
8355     {
8356       rtx tmp;
8357       tmp = gen_reg_rtx (SImode);
8358       emit_insn (gen_iorsi3 (tmp, operands[0], GEN_INT(1)));
8359       operands[0] = tmp;
8360     }
8361   "
8364 ;; NB Never uses BX.
8365 (define_insn "*arm_indirect_jump"
8366   [(set (pc)
8367         (match_operand:SI 0 "s_register_operand" "r"))]
8368   "TARGET_ARM"
8369   "mov%?\\t%|pc, %0\\t%@ indirect register jump"
8370   [(set_attr "predicable" "yes")
8371    (set_attr "type" "branch")]
8374 (define_insn "*load_indirect_jump"
8375   [(set (pc)
8376         (match_operand:SI 0 "memory_operand" "m"))]
8377   "TARGET_ARM"
8378   "ldr%?\\t%|pc, %0\\t%@ indirect memory jump"
8379   [(set_attr "type" "load1")
8380    (set_attr "pool_range" "4096")
8381    (set_attr "neg_pool_range" "4084")
8382    (set_attr "predicable" "yes")]
8386 ;; Misc insns
8388 (define_insn "nop"
8389   [(const_int 0)]
8390   "TARGET_EITHER"
8391   "*
8392   if (TARGET_UNIFIED_ASM)
8393     return \"nop\";
8394   if (TARGET_ARM)
8395     return \"mov%?\\t%|r0, %|r0\\t%@ nop\";
8396   return  \"mov\\tr8, r8\";
8397   "
8398   [(set (attr "length")
8399         (if_then_else (eq_attr "is_thumb" "yes")
8400                       (const_int 2)
8401                       (const_int 4)))
8402    (set_attr "type" "mov_reg")]
8405 (define_insn "trap"
8406   [(trap_if (const_int 1) (const_int 0))]
8407   ""
8408   "*
8409   if (TARGET_ARM)
8410     return \".inst\\t0xe7f000f0\";
8411   else
8412     return \".inst\\t0xdeff\";
8413   "
8414   [(set (attr "length")
8415         (if_then_else (eq_attr "is_thumb" "yes")
8416                       (const_int 2)
8417                       (const_int 4)))
8418    (set_attr "type" "trap")
8419    (set_attr "conds" "unconditional")]
8423 ;; Patterns to allow combination of arithmetic, cond code and shifts
8425 (define_insn "*<arith_shift_insn>_multsi"
8426   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8427         (SHIFTABLE_OPS:SI
8428          (mult:SI (match_operand:SI 2 "s_register_operand" "r,r")
8429                   (match_operand:SI 3 "power_of_two_operand" ""))
8430          (match_operand:SI 1 "s_register_operand" "rk,<t2_binop0>")))]
8431   "TARGET_32BIT"
8432   "<arith_shift_insn>%?\\t%0, %1, %2, lsl %b3"
8433   [(set_attr "predicable" "yes")
8434    (set_attr "predicable_short_it" "no")
8435    (set_attr "shift" "2")
8436    (set_attr "arch" "a,t2")
8437    (set_attr "type" "alu_shift_imm")])
8439 (define_insn "*<arith_shift_insn>_shiftsi"
8440   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
8441         (SHIFTABLE_OPS:SI
8442          (match_operator:SI 2 "shift_nomul_operator"
8443           [(match_operand:SI 3 "s_register_operand" "r,r,r")
8444            (match_operand:SI 4 "shift_amount_operand" "M,M,r")])
8445          (match_operand:SI 1 "s_register_operand" "rk,<t2_binop0>,rk")))]
8446   "TARGET_32BIT && GET_CODE (operands[2]) != MULT"
8447   "<arith_shift_insn>%?\\t%0, %1, %3%S2"
8448   [(set_attr "predicable" "yes")
8449    (set_attr "predicable_short_it" "no")
8450    (set_attr "shift" "3")
8451    (set_attr "arch" "a,t2,a")
8452    (set_attr "type" "alu_shift_imm,alu_shift_imm,alu_shift_reg")])
8454 (define_split
8455   [(set (match_operand:SI 0 "s_register_operand" "")
8456         (match_operator:SI 1 "shiftable_operator"
8457          [(match_operator:SI 2 "shiftable_operator"
8458            [(match_operator:SI 3 "shift_operator"
8459              [(match_operand:SI 4 "s_register_operand" "")
8460               (match_operand:SI 5 "reg_or_int_operand" "")])
8461             (match_operand:SI 6 "s_register_operand" "")])
8462           (match_operand:SI 7 "arm_rhs_operand" "")]))
8463    (clobber (match_operand:SI 8 "s_register_operand" ""))]
8464   "TARGET_32BIT"
8465   [(set (match_dup 8)
8466         (match_op_dup 2 [(match_op_dup 3 [(match_dup 4) (match_dup 5)])
8467                          (match_dup 6)]))
8468    (set (match_dup 0)
8469         (match_op_dup 1 [(match_dup 8) (match_dup 7)]))]
8470   "")
8472 (define_insn "*arith_shiftsi_compare0"
8473   [(set (reg:CC_NOOV CC_REGNUM)
8474         (compare:CC_NOOV
8475          (match_operator:SI 1 "shiftable_operator"
8476           [(match_operator:SI 3 "shift_operator"
8477             [(match_operand:SI 4 "s_register_operand" "r,r")
8478              (match_operand:SI 5 "shift_amount_operand" "M,r")])
8479            (match_operand:SI 2 "s_register_operand" "r,r")])
8480          (const_int 0)))
8481    (set (match_operand:SI 0 "s_register_operand" "=r,r")
8482         (match_op_dup 1 [(match_op_dup 3 [(match_dup 4) (match_dup 5)])
8483                          (match_dup 2)]))]
8484   "TARGET_32BIT"
8485   "%i1%.\\t%0, %2, %4%S3"
8486   [(set_attr "conds" "set")
8487    (set_attr "shift" "4")
8488    (set_attr "arch" "32,a")
8489    (set_attr "type" "alus_shift_imm,alus_shift_reg")])
8491 (define_insn "*arith_shiftsi_compare0_scratch"
8492   [(set (reg:CC_NOOV CC_REGNUM)
8493         (compare:CC_NOOV
8494          (match_operator:SI 1 "shiftable_operator"
8495           [(match_operator:SI 3 "shift_operator"
8496             [(match_operand:SI 4 "s_register_operand" "r,r")
8497              (match_operand:SI 5 "shift_amount_operand" "M,r")])
8498            (match_operand:SI 2 "s_register_operand" "r,r")])
8499          (const_int 0)))
8500    (clobber (match_scratch:SI 0 "=r,r"))]
8501   "TARGET_32BIT"
8502   "%i1%.\\t%0, %2, %4%S3"
8503   [(set_attr "conds" "set")
8504    (set_attr "shift" "4")
8505    (set_attr "arch" "32,a")
8506    (set_attr "type" "alus_shift_imm,alus_shift_reg")])
8508 (define_insn "*sub_shiftsi"
8509   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8510         (minus:SI (match_operand:SI 1 "s_register_operand" "r,r")
8511                   (match_operator:SI 2 "shift_operator"
8512                    [(match_operand:SI 3 "s_register_operand" "r,r")
8513                     (match_operand:SI 4 "shift_amount_operand" "M,r")])))]
8514   "TARGET_32BIT"
8515   "sub%?\\t%0, %1, %3%S2"
8516   [(set_attr "predicable" "yes")
8517    (set_attr "shift" "3")
8518    (set_attr "arch" "32,a")
8519    (set_attr "type" "alus_shift_imm,alus_shift_reg")])
8521 (define_insn "*sub_shiftsi_compare0"
8522   [(set (reg:CC_NOOV CC_REGNUM)
8523         (compare:CC_NOOV
8524          (minus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
8525                    (match_operator:SI 2 "shift_operator"
8526                     [(match_operand:SI 3 "s_register_operand" "r,r,r")
8527                      (match_operand:SI 4 "shift_amount_operand" "M,r,M")]))
8528          (const_int 0)))
8529    (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
8530         (minus:SI (match_dup 1)
8531                   (match_op_dup 2 [(match_dup 3) (match_dup 4)])))]
8532   "TARGET_32BIT"
8533   "sub%.\\t%0, %1, %3%S2"
8534   [(set_attr "conds" "set")
8535    (set_attr "shift" "3")
8536    (set_attr "arch" "32,a,a")
8537    (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
8539 (define_insn "*sub_shiftsi_compare0_scratch"
8540   [(set (reg:CC_NOOV CC_REGNUM)
8541         (compare:CC_NOOV
8542          (minus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
8543                    (match_operator:SI 2 "shift_operator"
8544                     [(match_operand:SI 3 "s_register_operand" "r,r,r")
8545                      (match_operand:SI 4 "shift_amount_operand" "M,r,M")]))
8546          (const_int 0)))
8547    (clobber (match_scratch:SI 0 "=r,r,r"))]
8548   "TARGET_32BIT"
8549   "sub%.\\t%0, %1, %3%S2"
8550   [(set_attr "conds" "set")
8551    (set_attr "shift" "3")
8552    (set_attr "arch" "32,a,a")
8553    (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
8556 (define_insn_and_split "*and_scc"
8557   [(set (match_operand:SI 0 "s_register_operand" "=r")
8558         (and:SI (match_operator:SI 1 "arm_comparison_operator"
8559                  [(match_operand 2 "cc_register" "") (const_int 0)])
8560                 (match_operand:SI 3 "s_register_operand" "r")))]
8561   "TARGET_ARM"
8562   "#"   ; "mov%D1\\t%0, #0\;and%d1\\t%0, %3, #1"
8563   "&& reload_completed"
8564   [(cond_exec (match_dup 5) (set (match_dup 0) (const_int 0)))
8565    (cond_exec (match_dup 4) (set (match_dup 0)
8566                                  (and:SI (match_dup 3) (const_int 1))))]
8567   {
8568     machine_mode mode = GET_MODE (operands[2]);
8569     enum rtx_code rc = GET_CODE (operands[1]);
8571     /* Note that operands[4] is the same as operands[1],
8572        but with VOIDmode as the result. */
8573     operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
8574     if (mode == CCFPmode || mode == CCFPEmode)
8575       rc = reverse_condition_maybe_unordered (rc);
8576     else
8577       rc = reverse_condition (rc);
8578     operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
8579   }
8580   [(set_attr "conds" "use")
8581    (set_attr "type" "multiple")
8582    (set_attr "length" "8")]
8585 (define_insn_and_split "*ior_scc"
8586   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8587         (ior:SI (match_operator:SI 1 "arm_comparison_operator"
8588                  [(match_operand 2 "cc_register" "") (const_int 0)])
8589                 (match_operand:SI 3 "s_register_operand" "0,?r")))]
8590   "TARGET_ARM"
8591   "@
8592    orr%d1\\t%0, %3, #1
8593    #"
8594   "&& reload_completed
8595    && REGNO (operands [0]) != REGNO (operands[3])"
8596   ;; && which_alternative == 1
8597   ; mov%D1\\t%0, %3\;orr%d1\\t%0, %3, #1
8598   [(cond_exec (match_dup 5) (set (match_dup 0) (match_dup 3)))
8599    (cond_exec (match_dup 4) (set (match_dup 0)
8600                                  (ior:SI (match_dup 3) (const_int 1))))]
8601   {
8602     machine_mode mode = GET_MODE (operands[2]);
8603     enum rtx_code rc = GET_CODE (operands[1]);
8605     /* Note that operands[4] is the same as operands[1],
8606        but with VOIDmode as the result. */
8607     operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
8608     if (mode == CCFPmode || mode == CCFPEmode)
8609       rc = reverse_condition_maybe_unordered (rc);
8610     else
8611       rc = reverse_condition (rc);
8612     operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
8613   }
8614   [(set_attr "conds" "use")
8615    (set_attr "length" "4,8")
8616    (set_attr "type" "logic_imm,multiple")]
8619 ; A series of splitters for the compare_scc pattern below.  Note that
8620 ; order is important.
8621 (define_split
8622   [(set (match_operand:SI 0 "s_register_operand" "")
8623         (lt:SI (match_operand:SI 1 "s_register_operand" "")
8624                (const_int 0)))
8625    (clobber (reg:CC CC_REGNUM))]
8626   "TARGET_32BIT && reload_completed"
8627   [(set (match_dup 0) (lshiftrt:SI (match_dup 1) (const_int 31)))])
8629 (define_split
8630   [(set (match_operand:SI 0 "s_register_operand" "")
8631         (ge:SI (match_operand:SI 1 "s_register_operand" "")
8632                (const_int 0)))
8633    (clobber (reg:CC CC_REGNUM))]
8634   "TARGET_32BIT && reload_completed"
8635   [(set (match_dup 0) (not:SI (match_dup 1)))
8636    (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 31)))])
8638 (define_split
8639   [(set (match_operand:SI 0 "s_register_operand" "")
8640         (eq:SI (match_operand:SI 1 "s_register_operand" "")
8641                (const_int 0)))
8642    (clobber (reg:CC CC_REGNUM))]
8643   "arm_arch5 && TARGET_32BIT"
8644   [(set (match_dup 0) (clz:SI (match_dup 1)))
8645    (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
8648 (define_split
8649   [(set (match_operand:SI 0 "s_register_operand" "")
8650         (eq:SI (match_operand:SI 1 "s_register_operand" "")
8651                (const_int 0)))
8652    (clobber (reg:CC CC_REGNUM))]
8653   "TARGET_32BIT && reload_completed"
8654   [(parallel
8655     [(set (reg:CC CC_REGNUM)
8656           (compare:CC (const_int 1) (match_dup 1)))
8657      (set (match_dup 0)
8658           (minus:SI (const_int 1) (match_dup 1)))])
8659    (cond_exec (ltu:CC (reg:CC CC_REGNUM) (const_int 0))
8660               (set (match_dup 0) (const_int 0)))])
8662 (define_split
8663   [(set (match_operand:SI 0 "s_register_operand" "")
8664         (ne:SI (match_operand:SI 1 "s_register_operand" "")
8665                (match_operand:SI 2 "const_int_operand" "")))
8666    (clobber (reg:CC CC_REGNUM))]
8667   "TARGET_32BIT && reload_completed"
8668   [(parallel
8669     [(set (reg:CC CC_REGNUM)
8670           (compare:CC (match_dup 1) (match_dup 2)))
8671      (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 3)))])
8672    (cond_exec (ne:CC (reg:CC CC_REGNUM) (const_int 0))
8673               (set (match_dup 0) (const_int 1)))]
8675   operands[3] = GEN_INT (-INTVAL (operands[2]));
8678 (define_split
8679   [(set (match_operand:SI 0 "s_register_operand" "")
8680         (ne:SI (match_operand:SI 1 "s_register_operand" "")
8681                (match_operand:SI 2 "arm_add_operand" "")))
8682    (clobber (reg:CC CC_REGNUM))]
8683   "TARGET_32BIT && reload_completed"
8684   [(parallel
8685     [(set (reg:CC_NOOV CC_REGNUM)
8686           (compare:CC_NOOV (minus:SI (match_dup 1) (match_dup 2))
8687                            (const_int 0)))
8688      (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
8689    (cond_exec (ne:CC_NOOV (reg:CC_NOOV CC_REGNUM) (const_int 0))
8690               (set (match_dup 0) (const_int 1)))])
8692 (define_insn_and_split "*compare_scc"
8693   [(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts")
8694         (match_operator:SI 1 "arm_comparison_operator"
8695          [(match_operand:SI 2 "s_register_operand" "r,r")
8696           (match_operand:SI 3 "arm_add_operand" "rI,L")]))
8697    (clobber (reg:CC CC_REGNUM))]
8698   "TARGET_32BIT"
8699   "#"
8700   "&& reload_completed"
8701   [(set (reg:CC CC_REGNUM) (compare:CC (match_dup 2) (match_dup 3)))
8702    (cond_exec (match_dup 4) (set (match_dup 0) (const_int 0)))
8703    (cond_exec (match_dup 5) (set (match_dup 0) (const_int 1)))]
8705   rtx tmp1;
8706   machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
8707                                            operands[2], operands[3]);
8708   enum rtx_code rc = GET_CODE (operands[1]);
8710   tmp1 = gen_rtx_REG (mode, CC_REGNUM);
8712   operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, tmp1, const0_rtx);
8713   if (mode == CCFPmode || mode == CCFPEmode)
8714     rc = reverse_condition_maybe_unordered (rc);
8715   else
8716     rc = reverse_condition (rc);
8717   operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, tmp1, const0_rtx);
8719   [(set_attr "type" "multiple")]
8722 ;; Attempt to improve the sequence generated by the compare_scc splitters
8723 ;; not to use conditional execution.
8725 ;; Rd = (eq (reg1) (const_int0))  // ARMv5
8726 ;;      clz Rd, reg1
8727 ;;      lsr Rd, Rd, #5
8728 (define_peephole2
8729   [(set (reg:CC CC_REGNUM)
8730         (compare:CC (match_operand:SI 1 "register_operand" "")
8731                     (const_int 0)))
8732    (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
8733               (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
8734    (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
8735               (set (match_dup 0) (const_int 1)))]
8736   "arm_arch5 && TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
8737   [(set (match_dup 0) (clz:SI (match_dup 1)))
8738    (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
8741 ;; Rd = (eq (reg1) (const_int0))  // !ARMv5
8742 ;;      negs Rd, reg1
8743 ;;      adc  Rd, Rd, reg1
8744 (define_peephole2
8745   [(set (reg:CC CC_REGNUM)
8746         (compare:CC (match_operand:SI 1 "register_operand" "")
8747                     (const_int 0)))
8748    (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
8749               (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
8750    (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
8751               (set (match_dup 0) (const_int 1)))
8752    (match_scratch:SI 2 "r")]
8753   "TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
8754   [(parallel
8755     [(set (reg:CC CC_REGNUM)
8756           (compare:CC (const_int 0) (match_dup 1)))
8757      (set (match_dup 2) (minus:SI (const_int 0) (match_dup 1)))])
8758    (set (match_dup 0)
8759         (plus:SI (plus:SI (match_dup 1) (match_dup 2))
8760                  (geu:SI (reg:CC CC_REGNUM) (const_int 0))))]
8763 ;; Rd = (eq (reg1) (reg2/imm))  // ARMv5 and optimising for speed.
8764 ;;      sub  Rd, Reg1, reg2
8765 ;;      clz  Rd, Rd
8766 ;;      lsr  Rd, Rd, #5
8767 (define_peephole2
8768   [(set (reg:CC CC_REGNUM)
8769         (compare:CC (match_operand:SI 1 "register_operand" "")
8770                     (match_operand:SI 2 "arm_rhs_operand" "")))
8771    (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
8772               (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
8773    (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
8774               (set (match_dup 0) (const_int 1)))]
8775   "arm_arch5 && TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)
8776   && !(TARGET_THUMB2 && optimize_insn_for_size_p ())"
8777   [(set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))
8778    (set (match_dup 0) (clz:SI (match_dup 0)))
8779    (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
8783 ;; Rd = (eq (reg1) (reg2))      // ! ARMv5 or optimising for size.
8784 ;;      sub  T1, Reg1, reg2
8785 ;;      negs Rd, T1
8786 ;;      adc  Rd, Rd, T1
8787 (define_peephole2
8788   [(set (reg:CC CC_REGNUM)
8789         (compare:CC (match_operand:SI 1 "register_operand" "")
8790                     (match_operand:SI 2 "arm_rhs_operand" "")))
8791    (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
8792               (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
8793    (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
8794               (set (match_dup 0) (const_int 1)))
8795    (match_scratch:SI 3 "r")]
8796   "TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
8797   [(set (match_dup 3) (match_dup 4))
8798    (parallel
8799     [(set (reg:CC CC_REGNUM)
8800           (compare:CC (const_int 0) (match_dup 3)))
8801      (set (match_dup 0) (minus:SI (const_int 0) (match_dup 3)))])
8802    (set (match_dup 0)
8803         (plus:SI (plus:SI (match_dup 0) (match_dup 3))
8804                  (geu:SI (reg:CC CC_REGNUM) (const_int 0))))]
8805   "
8806   if (CONST_INT_P (operands[2]))
8807     operands[4] = plus_constant (SImode, operands[1], -INTVAL (operands[2]));
8808   else
8809     operands[4] = gen_rtx_MINUS (SImode, operands[1], operands[2]);
8810   ")
8812 (define_insn "*cond_move"
8813   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
8814         (if_then_else:SI (match_operator 3 "equality_operator"
8815                           [(match_operator 4 "arm_comparison_operator"
8816                             [(match_operand 5 "cc_register" "") (const_int 0)])
8817                            (const_int 0)])
8818                          (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
8819                          (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))]
8820   "TARGET_ARM"
8821   "*
8822     if (GET_CODE (operands[3]) == NE)
8823       {
8824         if (which_alternative != 1)
8825           output_asm_insn (\"mov%D4\\t%0, %2\", operands);
8826         if (which_alternative != 0)
8827           output_asm_insn (\"mov%d4\\t%0, %1\", operands);
8828         return \"\";
8829       }
8830     if (which_alternative != 0)
8831       output_asm_insn (\"mov%D4\\t%0, %1\", operands);
8832     if (which_alternative != 1)
8833       output_asm_insn (\"mov%d4\\t%0, %2\", operands);
8834     return \"\";
8835   "
8836   [(set_attr "conds" "use")
8837    (set_attr_alternative "type"
8838                          [(if_then_else (match_operand 2 "const_int_operand" "")
8839                                         (const_string "mov_imm")
8840                                         (const_string "mov_reg"))
8841                           (if_then_else (match_operand 1 "const_int_operand" "")
8842                                         (const_string "mov_imm")
8843                                         (const_string "mov_reg"))
8844                           (const_string "multiple")])
8845    (set_attr "length" "4,4,8")]
8848 (define_insn "*cond_arith"
8849   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8850         (match_operator:SI 5 "shiftable_operator" 
8851          [(match_operator:SI 4 "arm_comparison_operator"
8852            [(match_operand:SI 2 "s_register_operand" "r,r")
8853             (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
8854           (match_operand:SI 1 "s_register_operand" "0,?r")]))
8855    (clobber (reg:CC CC_REGNUM))]
8856   "TARGET_ARM"
8857   "*
8858     if (GET_CODE (operands[4]) == LT && operands[3] == const0_rtx)
8859       return \"%i5\\t%0, %1, %2, lsr #31\";
8861     output_asm_insn (\"cmp\\t%2, %3\", operands);
8862     if (GET_CODE (operands[5]) == AND)
8863       output_asm_insn (\"mov%D4\\t%0, #0\", operands);
8864     else if (GET_CODE (operands[5]) == MINUS)
8865       output_asm_insn (\"rsb%D4\\t%0, %1, #0\", operands);
8866     else if (which_alternative != 0)
8867       output_asm_insn (\"mov%D4\\t%0, %1\", operands);
8868     return \"%i5%d4\\t%0, %1, #1\";
8869   "
8870   [(set_attr "conds" "clob")
8871    (set_attr "length" "12")
8872    (set_attr "type" "multiple")]
8875 (define_insn "*cond_sub"
8876   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8877         (minus:SI (match_operand:SI 1 "s_register_operand" "0,?r")
8878                   (match_operator:SI 4 "arm_comparison_operator"
8879                    [(match_operand:SI 2 "s_register_operand" "r,r")
8880                     (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
8881    (clobber (reg:CC CC_REGNUM))]
8882   "TARGET_ARM"
8883   "*
8884     output_asm_insn (\"cmp\\t%2, %3\", operands);
8885     if (which_alternative != 0)
8886       output_asm_insn (\"mov%D4\\t%0, %1\", operands);
8887     return \"sub%d4\\t%0, %1, #1\";
8888   "
8889   [(set_attr "conds" "clob")
8890    (set_attr "length" "8,12")
8891    (set_attr "type" "multiple")]
8894 (define_insn "*cmp_ite0"
8895   [(set (match_operand 6 "dominant_cc_register" "")
8896         (compare
8897          (if_then_else:SI
8898           (match_operator 4 "arm_comparison_operator"
8899            [(match_operand:SI 0 "s_register_operand"
8900                 "l,l,l,r,r,r,r,r,r")
8901             (match_operand:SI 1 "arm_add_operand"
8902                 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
8903           (match_operator:SI 5 "arm_comparison_operator"
8904            [(match_operand:SI 2 "s_register_operand"
8905                 "l,r,r,l,l,r,r,r,r")
8906             (match_operand:SI 3 "arm_add_operand"
8907                 "lPy,rI,L,lPy,lPy,rI,rI,L,L")])
8908           (const_int 0))
8909          (const_int 0)))]
8910   "TARGET_32BIT"
8911   "*
8912   {
8913     static const char * const cmp1[NUM_OF_COND_CMP][2] =
8914     {
8915       {\"cmp%d5\\t%0, %1\",
8916        \"cmp%d4\\t%2, %3\"},
8917       {\"cmn%d5\\t%0, #%n1\",
8918        \"cmp%d4\\t%2, %3\"},
8919       {\"cmp%d5\\t%0, %1\",
8920        \"cmn%d4\\t%2, #%n3\"},
8921       {\"cmn%d5\\t%0, #%n1\",
8922        \"cmn%d4\\t%2, #%n3\"}
8923     };
8924     static const char * const cmp2[NUM_OF_COND_CMP][2] =
8925     {
8926       {\"cmp\\t%2, %3\",
8927        \"cmp\\t%0, %1\"},
8928       {\"cmp\\t%2, %3\",
8929        \"cmn\\t%0, #%n1\"},
8930       {\"cmn\\t%2, #%n3\",
8931        \"cmp\\t%0, %1\"},
8932       {\"cmn\\t%2, #%n3\",
8933        \"cmn\\t%0, #%n1\"}
8934     };
8935     static const char * const ite[2] =
8936     {
8937       \"it\\t%d5\",
8938       \"it\\t%d4\"
8939     };
8940     static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
8941                                    CMP_CMP, CMN_CMP, CMP_CMP,
8942                                    CMN_CMP, CMP_CMN, CMN_CMN};
8943     int swap =
8944       comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
8946     output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
8947     if (TARGET_THUMB2) {
8948       output_asm_insn (ite[swap], operands);
8949     }
8950     output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
8951     return \"\";
8952   }"
8953   [(set_attr "conds" "set")
8954    (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
8955    (set_attr "type" "multiple")
8956    (set_attr_alternative "length"
8957       [(const_int 6)
8958        (const_int 8)
8959        (const_int 8)
8960        (const_int 8)
8961        (const_int 8)
8962        (if_then_else (eq_attr "is_thumb" "no")
8963            (const_int 8)
8964            (const_int 10))
8965        (if_then_else (eq_attr "is_thumb" "no")
8966            (const_int 8)
8967            (const_int 10))
8968        (if_then_else (eq_attr "is_thumb" "no")
8969            (const_int 8)
8970            (const_int 10))
8971        (if_then_else (eq_attr "is_thumb" "no")
8972            (const_int 8)
8973            (const_int 10))])]
8976 (define_insn "*cmp_ite1"
8977   [(set (match_operand 6 "dominant_cc_register" "")
8978         (compare
8979          (if_then_else:SI
8980           (match_operator 4 "arm_comparison_operator"
8981            [(match_operand:SI 0 "s_register_operand"
8982                 "l,l,l,r,r,r,r,r,r")
8983             (match_operand:SI 1 "arm_add_operand"
8984                 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
8985           (match_operator:SI 5 "arm_comparison_operator"
8986            [(match_operand:SI 2 "s_register_operand"
8987                 "l,r,r,l,l,r,r,r,r")
8988             (match_operand:SI 3 "arm_add_operand"
8989                 "lPy,rI,L,lPy,lPy,rI,rI,L,L")])
8990           (const_int 1))
8991          (const_int 0)))]
8992   "TARGET_32BIT"
8993   "*
8994   {
8995     static const char * const cmp1[NUM_OF_COND_CMP][2] =
8996     {
8997       {\"cmp\\t%0, %1\",
8998        \"cmp\\t%2, %3\"},
8999       {\"cmn\\t%0, #%n1\",
9000        \"cmp\\t%2, %3\"},
9001       {\"cmp\\t%0, %1\",
9002        \"cmn\\t%2, #%n3\"},
9003       {\"cmn\\t%0, #%n1\",
9004        \"cmn\\t%2, #%n3\"}
9005     };
9006     static const char * const cmp2[NUM_OF_COND_CMP][2] =
9007     {
9008       {\"cmp%d4\\t%2, %3\",
9009        \"cmp%D5\\t%0, %1\"},
9010       {\"cmp%d4\\t%2, %3\",
9011        \"cmn%D5\\t%0, #%n1\"},
9012       {\"cmn%d4\\t%2, #%n3\",
9013        \"cmp%D5\\t%0, %1\"},
9014       {\"cmn%d4\\t%2, #%n3\",
9015        \"cmn%D5\\t%0, #%n1\"}
9016     };
9017     static const char * const ite[2] =
9018     {
9019       \"it\\t%d4\",
9020       \"it\\t%D5\"
9021     };
9022     static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
9023                                    CMP_CMP, CMN_CMP, CMP_CMP,
9024                                    CMN_CMP, CMP_CMN, CMN_CMN};
9025     int swap =
9026       comparison_dominates_p (GET_CODE (operands[5]),
9027                               reverse_condition (GET_CODE (operands[4])));
9029     output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
9030     if (TARGET_THUMB2) {
9031       output_asm_insn (ite[swap], operands);
9032     }
9033     output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
9034     return \"\";
9035   }"
9036   [(set_attr "conds" "set")
9037    (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
9038    (set_attr_alternative "length"
9039       [(const_int 6)
9040        (const_int 8)
9041        (const_int 8)
9042        (const_int 8)
9043        (const_int 8)
9044        (if_then_else (eq_attr "is_thumb" "no")
9045            (const_int 8)
9046            (const_int 10))
9047        (if_then_else (eq_attr "is_thumb" "no")
9048            (const_int 8)
9049            (const_int 10))
9050        (if_then_else (eq_attr "is_thumb" "no")
9051            (const_int 8)
9052            (const_int 10))
9053        (if_then_else (eq_attr "is_thumb" "no")
9054            (const_int 8)
9055            (const_int 10))])
9056    (set_attr "type" "multiple")]
9059 (define_insn "*cmp_and"
9060   [(set (match_operand 6 "dominant_cc_register" "")
9061         (compare
9062          (and:SI
9063           (match_operator 4 "arm_comparison_operator"
9064            [(match_operand:SI 0 "s_register_operand" 
9065                 "l,l,l,r,r,r,r,r,r")
9066             (match_operand:SI 1 "arm_add_operand" 
9067                 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
9068           (match_operator:SI 5 "arm_comparison_operator"
9069            [(match_operand:SI 2 "s_register_operand" 
9070                 "l,r,r,l,l,r,r,r,r")
9071             (match_operand:SI 3 "arm_add_operand" 
9072                 "lPy,rI,L,lPy,lPy,rI,rI,L,L")]))
9073          (const_int 0)))]
9074   "TARGET_32BIT"
9075   "*
9076   {
9077     static const char *const cmp1[NUM_OF_COND_CMP][2] =
9078     {
9079       {\"cmp%d5\\t%0, %1\",
9080        \"cmp%d4\\t%2, %3\"},
9081       {\"cmn%d5\\t%0, #%n1\",
9082        \"cmp%d4\\t%2, %3\"},
9083       {\"cmp%d5\\t%0, %1\",
9084        \"cmn%d4\\t%2, #%n3\"},
9085       {\"cmn%d5\\t%0, #%n1\",
9086        \"cmn%d4\\t%2, #%n3\"}
9087     };
9088     static const char *const cmp2[NUM_OF_COND_CMP][2] =
9089     {
9090       {\"cmp\\t%2, %3\",
9091        \"cmp\\t%0, %1\"},
9092       {\"cmp\\t%2, %3\",
9093        \"cmn\\t%0, #%n1\"},
9094       {\"cmn\\t%2, #%n3\",
9095        \"cmp\\t%0, %1\"},
9096       {\"cmn\\t%2, #%n3\",
9097        \"cmn\\t%0, #%n1\"}
9098     };
9099     static const char *const ite[2] =
9100     {
9101       \"it\\t%d5\",
9102       \"it\\t%d4\"
9103     };
9104     static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
9105                                    CMP_CMP, CMN_CMP, CMP_CMP,
9106                                    CMN_CMP, CMP_CMN, CMN_CMN};
9107     int swap =
9108       comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
9110     output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
9111     if (TARGET_THUMB2) {
9112       output_asm_insn (ite[swap], operands);
9113     }
9114     output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
9115     return \"\";
9116   }"
9117   [(set_attr "conds" "set")
9118    (set_attr "predicable" "no")
9119    (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
9120    (set_attr_alternative "length"
9121       [(const_int 6)
9122        (const_int 8)
9123        (const_int 8)
9124        (const_int 8)
9125        (const_int 8)
9126        (if_then_else (eq_attr "is_thumb" "no")
9127            (const_int 8)
9128            (const_int 10))
9129        (if_then_else (eq_attr "is_thumb" "no")
9130            (const_int 8)
9131            (const_int 10))
9132        (if_then_else (eq_attr "is_thumb" "no")
9133            (const_int 8)
9134            (const_int 10))
9135        (if_then_else (eq_attr "is_thumb" "no")
9136            (const_int 8)
9137            (const_int 10))])
9138    (set_attr "type" "multiple")]
9141 (define_insn "*cmp_ior"
9142   [(set (match_operand 6 "dominant_cc_register" "")
9143         (compare
9144          (ior:SI
9145           (match_operator 4 "arm_comparison_operator"
9146            [(match_operand:SI 0 "s_register_operand"
9147                 "l,l,l,r,r,r,r,r,r")
9148             (match_operand:SI 1 "arm_add_operand"
9149                 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
9150           (match_operator:SI 5 "arm_comparison_operator"
9151            [(match_operand:SI 2 "s_register_operand"
9152                 "l,r,r,l,l,r,r,r,r")
9153             (match_operand:SI 3 "arm_add_operand"
9154                 "lPy,rI,L,lPy,lPy,rI,rI,L,L")]))
9155          (const_int 0)))]
9156   "TARGET_32BIT"
9157   "*
9158   {
9159     static const char *const cmp1[NUM_OF_COND_CMP][2] =
9160     {
9161       {\"cmp\\t%0, %1\",
9162        \"cmp\\t%2, %3\"},
9163       {\"cmn\\t%0, #%n1\",
9164        \"cmp\\t%2, %3\"},
9165       {\"cmp\\t%0, %1\",
9166        \"cmn\\t%2, #%n3\"},
9167       {\"cmn\\t%0, #%n1\",
9168        \"cmn\\t%2, #%n3\"}
9169     };
9170     static const char *const cmp2[NUM_OF_COND_CMP][2] =
9171     {
9172       {\"cmp%D4\\t%2, %3\",
9173        \"cmp%D5\\t%0, %1\"},
9174       {\"cmp%D4\\t%2, %3\",
9175        \"cmn%D5\\t%0, #%n1\"},
9176       {\"cmn%D4\\t%2, #%n3\",
9177        \"cmp%D5\\t%0, %1\"},
9178       {\"cmn%D4\\t%2, #%n3\",
9179        \"cmn%D5\\t%0, #%n1\"}
9180     };
9181     static const char *const ite[2] =
9182     {
9183       \"it\\t%D4\",
9184       \"it\\t%D5\"
9185     };
9186     static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
9187                                    CMP_CMP, CMN_CMP, CMP_CMP,
9188                                    CMN_CMP, CMP_CMN, CMN_CMN};
9189     int swap =
9190       comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
9192     output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
9193     if (TARGET_THUMB2) {
9194       output_asm_insn (ite[swap], operands);
9195     }
9196     output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
9197     return \"\";
9198   }
9199   "
9200   [(set_attr "conds" "set")
9201    (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
9202    (set_attr_alternative "length"
9203       [(const_int 6)
9204        (const_int 8)
9205        (const_int 8)
9206        (const_int 8)
9207        (const_int 8)
9208        (if_then_else (eq_attr "is_thumb" "no")
9209            (const_int 8)
9210            (const_int 10))
9211        (if_then_else (eq_attr "is_thumb" "no")
9212            (const_int 8)
9213            (const_int 10))
9214        (if_then_else (eq_attr "is_thumb" "no")
9215            (const_int 8)
9216            (const_int 10))
9217        (if_then_else (eq_attr "is_thumb" "no")
9218            (const_int 8)
9219            (const_int 10))])
9220    (set_attr "type" "multiple")]
9223 (define_insn_and_split "*ior_scc_scc"
9224   [(set (match_operand:SI 0 "s_register_operand" "=Ts")
9225         (ior:SI (match_operator:SI 3 "arm_comparison_operator"
9226                  [(match_operand:SI 1 "s_register_operand" "r")
9227                   (match_operand:SI 2 "arm_add_operand" "rIL")])
9228                 (match_operator:SI 6 "arm_comparison_operator"
9229                  [(match_operand:SI 4 "s_register_operand" "r")
9230                   (match_operand:SI 5 "arm_add_operand" "rIL")])))
9231    (clobber (reg:CC CC_REGNUM))]
9232   "TARGET_32BIT
9233    && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_OR_Y)
9234        != CCmode)"
9235   "#"
9236   "TARGET_32BIT && reload_completed"
9237   [(set (match_dup 7)
9238         (compare
9239          (ior:SI
9240           (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9241           (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9242          (const_int 0)))
9243    (set (match_dup 0) (ne:SI (match_dup 7) (const_int 0)))]
9244   "operands[7]
9245      = gen_rtx_REG (arm_select_dominance_cc_mode (operands[3], operands[6],
9246                                                   DOM_CC_X_OR_Y),
9247                     CC_REGNUM);"
9248   [(set_attr "conds" "clob")
9249    (set_attr "length" "16")
9250    (set_attr "type" "multiple")]
9253 ; If the above pattern is followed by a CMP insn, then the compare is 
9254 ; redundant, since we can rework the conditional instruction that follows.
9255 (define_insn_and_split "*ior_scc_scc_cmp"
9256   [(set (match_operand 0 "dominant_cc_register" "")
9257         (compare (ior:SI (match_operator:SI 3 "arm_comparison_operator"
9258                           [(match_operand:SI 1 "s_register_operand" "r")
9259                            (match_operand:SI 2 "arm_add_operand" "rIL")])
9260                          (match_operator:SI 6 "arm_comparison_operator"
9261                           [(match_operand:SI 4 "s_register_operand" "r")
9262                            (match_operand:SI 5 "arm_add_operand" "rIL")]))
9263                  (const_int 0)))
9264    (set (match_operand:SI 7 "s_register_operand" "=Ts")
9265         (ior:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9266                 (match_op_dup 6 [(match_dup 4) (match_dup 5)])))]
9267   "TARGET_32BIT"
9268   "#"
9269   "TARGET_32BIT && reload_completed"
9270   [(set (match_dup 0)
9271         (compare
9272          (ior:SI
9273           (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9274           (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9275          (const_int 0)))
9276    (set (match_dup 7) (ne:SI (match_dup 0) (const_int 0)))]
9277   ""
9278   [(set_attr "conds" "set")
9279    (set_attr "length" "16")
9280    (set_attr "type" "multiple")]
9283 (define_insn_and_split "*and_scc_scc"
9284   [(set (match_operand:SI 0 "s_register_operand" "=Ts")
9285         (and:SI (match_operator:SI 3 "arm_comparison_operator"
9286                  [(match_operand:SI 1 "s_register_operand" "r")
9287                   (match_operand:SI 2 "arm_add_operand" "rIL")])
9288                 (match_operator:SI 6 "arm_comparison_operator"
9289                  [(match_operand:SI 4 "s_register_operand" "r")
9290                   (match_operand:SI 5 "arm_add_operand" "rIL")])))
9291    (clobber (reg:CC CC_REGNUM))]
9292   "TARGET_32BIT
9293    && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
9294        != CCmode)"
9295   "#"
9296   "TARGET_32BIT && reload_completed
9297    && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
9298        != CCmode)"
9299   [(set (match_dup 7)
9300         (compare
9301          (and:SI
9302           (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9303           (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9304          (const_int 0)))
9305    (set (match_dup 0) (ne:SI (match_dup 7) (const_int 0)))]
9306   "operands[7]
9307      = gen_rtx_REG (arm_select_dominance_cc_mode (operands[3], operands[6],
9308                                                   DOM_CC_X_AND_Y),
9309                     CC_REGNUM);"
9310   [(set_attr "conds" "clob")
9311    (set_attr "length" "16")
9312    (set_attr "type" "multiple")]
9315 ; If the above pattern is followed by a CMP insn, then the compare is 
9316 ; redundant, since we can rework the conditional instruction that follows.
9317 (define_insn_and_split "*and_scc_scc_cmp"
9318   [(set (match_operand 0 "dominant_cc_register" "")
9319         (compare (and:SI (match_operator:SI 3 "arm_comparison_operator"
9320                           [(match_operand:SI 1 "s_register_operand" "r")
9321                            (match_operand:SI 2 "arm_add_operand" "rIL")])
9322                          (match_operator:SI 6 "arm_comparison_operator"
9323                           [(match_operand:SI 4 "s_register_operand" "r")
9324                            (match_operand:SI 5 "arm_add_operand" "rIL")]))
9325                  (const_int 0)))
9326    (set (match_operand:SI 7 "s_register_operand" "=Ts")
9327         (and:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9328                 (match_op_dup 6 [(match_dup 4) (match_dup 5)])))]
9329   "TARGET_32BIT"
9330   "#"
9331   "TARGET_32BIT && reload_completed"
9332   [(set (match_dup 0)
9333         (compare
9334          (and:SI
9335           (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9336           (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9337          (const_int 0)))
9338    (set (match_dup 7) (ne:SI (match_dup 0) (const_int 0)))]
9339   ""
9340   [(set_attr "conds" "set")
9341    (set_attr "length" "16")
9342    (set_attr "type" "multiple")]
9345 ;; If there is no dominance in the comparison, then we can still save an
9346 ;; instruction in the AND case, since we can know that the second compare
9347 ;; need only zero the value if false (if true, then the value is already
9348 ;; correct).
9349 (define_insn_and_split "*and_scc_scc_nodom"
9350   [(set (match_operand:SI 0 "s_register_operand" "=&Ts,&Ts,&Ts")
9351         (and:SI (match_operator:SI 3 "arm_comparison_operator"
9352                  [(match_operand:SI 1 "s_register_operand" "r,r,0")
9353                   (match_operand:SI 2 "arm_add_operand" "rIL,0,rIL")])
9354                 (match_operator:SI 6 "arm_comparison_operator"
9355                  [(match_operand:SI 4 "s_register_operand" "r,r,r")
9356                   (match_operand:SI 5 "arm_add_operand" "rIL,rIL,rIL")])))
9357    (clobber (reg:CC CC_REGNUM))]
9358   "TARGET_32BIT
9359    && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
9360        == CCmode)"
9361   "#"
9362   "TARGET_32BIT && reload_completed"
9363   [(parallel [(set (match_dup 0)
9364                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
9365               (clobber (reg:CC CC_REGNUM))])
9366    (set (match_dup 7) (match_op_dup 8 [(match_dup 4) (match_dup 5)]))
9367    (set (match_dup 0)
9368         (if_then_else:SI (match_op_dup 6 [(match_dup 7) (const_int 0)])
9369                          (match_dup 0)
9370                          (const_int 0)))]
9371   "operands[7] = gen_rtx_REG (SELECT_CC_MODE (GET_CODE (operands[6]),
9372                                               operands[4], operands[5]),
9373                               CC_REGNUM);
9374    operands[8] = gen_rtx_COMPARE (GET_MODE (operands[7]), operands[4],
9375                                   operands[5]);"
9376   [(set_attr "conds" "clob")
9377    (set_attr "length" "20")
9378    (set_attr "type" "multiple")]
9381 (define_split
9382   [(set (reg:CC_NOOV CC_REGNUM)
9383         (compare:CC_NOOV (ior:SI
9384                           (and:SI (match_operand:SI 0 "s_register_operand" "")
9385                                   (const_int 1))
9386                           (match_operator:SI 1 "arm_comparison_operator"
9387                            [(match_operand:SI 2 "s_register_operand" "")
9388                             (match_operand:SI 3 "arm_add_operand" "")]))
9389                          (const_int 0)))
9390    (clobber (match_operand:SI 4 "s_register_operand" ""))]
9391   "TARGET_ARM"
9392   [(set (match_dup 4)
9393         (ior:SI (match_op_dup 1 [(match_dup 2) (match_dup 3)])
9394                 (match_dup 0)))
9395    (set (reg:CC_NOOV CC_REGNUM)
9396         (compare:CC_NOOV (and:SI (match_dup 4) (const_int 1))
9397                          (const_int 0)))]
9398   "")
9400 (define_split
9401   [(set (reg:CC_NOOV CC_REGNUM)
9402         (compare:CC_NOOV (ior:SI
9403                           (match_operator:SI 1 "arm_comparison_operator"
9404                            [(match_operand:SI 2 "s_register_operand" "")
9405                             (match_operand:SI 3 "arm_add_operand" "")])
9406                           (and:SI (match_operand:SI 0 "s_register_operand" "")
9407                                   (const_int 1)))
9408                          (const_int 0)))
9409    (clobber (match_operand:SI 4 "s_register_operand" ""))]
9410   "TARGET_ARM"
9411   [(set (match_dup 4)
9412         (ior:SI (match_op_dup 1 [(match_dup 2) (match_dup 3)])
9413                 (match_dup 0)))
9414    (set (reg:CC_NOOV CC_REGNUM)
9415         (compare:CC_NOOV (and:SI (match_dup 4) (const_int 1))
9416                          (const_int 0)))]
9417   "")
9418 ;; ??? The conditional patterns above need checking for Thumb-2 usefulness
9420 (define_insn_and_split "*negscc"
9421   [(set (match_operand:SI 0 "s_register_operand" "=r")
9422         (neg:SI (match_operator 3 "arm_comparison_operator"
9423                  [(match_operand:SI 1 "s_register_operand" "r")
9424                   (match_operand:SI 2 "arm_rhs_operand" "rI")])))
9425    (clobber (reg:CC CC_REGNUM))]
9426   "TARGET_ARM"
9427   "#"
9428   "&& reload_completed"
9429   [(const_int 0)]
9430   {
9431     rtx cc_reg = gen_rtx_REG (CCmode, CC_REGNUM);
9433     if (GET_CODE (operands[3]) == LT && operands[2] == const0_rtx)
9434        {
9435          /* Emit mov\\t%0, %1, asr #31 */
9436          emit_insn (gen_rtx_SET (operands[0],
9437                                  gen_rtx_ASHIFTRT (SImode,
9438                                                    operands[1],
9439                                                    GEN_INT (31))));
9440          DONE;
9441        }
9442      else if (GET_CODE (operands[3]) == NE)
9443        {
9444         /* Emit subs\\t%0, %1, %2\;mvnne\\t%0, #0 */
9445         if (CONST_INT_P (operands[2]))
9446           emit_insn (gen_cmpsi2_addneg (operands[0], operands[1], operands[2],
9447                                         GEN_INT (- INTVAL (operands[2]))));
9448         else
9449           emit_insn (gen_subsi3_compare (operands[0], operands[1], operands[2]));
9451         emit_insn (gen_rtx_COND_EXEC (VOIDmode,
9452                                       gen_rtx_NE (SImode,
9453                                                   cc_reg,
9454                                                   const0_rtx),
9455                                       gen_rtx_SET (operands[0],
9456                                                    GEN_INT (~0))));
9457         DONE;
9458       }
9459     else
9460       {
9461         /* Emit: cmp\\t%1, %2\;mov%D3\\t%0, #0\;mvn%d3\\t%0, #0 */
9462         emit_insn (gen_rtx_SET (cc_reg,
9463                                 gen_rtx_COMPARE (CCmode, operands[1], operands[2])));
9464         enum rtx_code rc = GET_CODE (operands[3]);
9466         rc = reverse_condition (rc);
9467         emit_insn (gen_rtx_COND_EXEC (VOIDmode,
9468                                       gen_rtx_fmt_ee (rc,
9469                                                       VOIDmode,
9470                                                       cc_reg,
9471                                                       const0_rtx),
9472                                       gen_rtx_SET (operands[0], const0_rtx)));
9473         rc = GET_CODE (operands[3]);
9474         emit_insn (gen_rtx_COND_EXEC (VOIDmode,
9475                                       gen_rtx_fmt_ee (rc,
9476                                                       VOIDmode,
9477                                                       cc_reg,
9478                                                       const0_rtx),
9479                                       gen_rtx_SET (operands[0],
9480                                                    GEN_INT (~0))));
9481         DONE;
9482       }
9483      FAIL;
9484   }
9485   [(set_attr "conds" "clob")
9486    (set_attr "length" "12")
9487    (set_attr "type" "multiple")]
9490 (define_insn_and_split "movcond_addsi"
9491   [(set (match_operand:SI 0 "s_register_operand" "=r,l,r")
9492         (if_then_else:SI
9493          (match_operator 5 "comparison_operator"
9494           [(plus:SI (match_operand:SI 3 "s_register_operand" "r,r,r")
9495                     (match_operand:SI 4 "arm_add_operand" "rIL,rIL,rIL"))
9496             (const_int 0)])
9497          (match_operand:SI 1 "arm_rhs_operand" "rI,rPy,r")
9498          (match_operand:SI 2 "arm_rhs_operand" "rI,rPy,r")))
9499    (clobber (reg:CC CC_REGNUM))]
9500    "TARGET_32BIT"
9501    "#"
9502    "&& reload_completed"
9503   [(set (reg:CC_NOOV CC_REGNUM)
9504         (compare:CC_NOOV
9505          (plus:SI (match_dup 3)
9506                   (match_dup 4))
9507          (const_int 0)))
9508    (set (match_dup 0) (match_dup 1))
9509    (cond_exec (match_dup 6)
9510               (set (match_dup 0) (match_dup 2)))]
9511   "
9512   {
9513     machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[5]),
9514                                              operands[3], operands[4]);
9515     enum rtx_code rc = GET_CODE (operands[5]);
9516     operands[6] = gen_rtx_REG (mode, CC_REGNUM);
9517     gcc_assert (!(mode == CCFPmode || mode == CCFPEmode));
9518     if (!REG_P (operands[2]) || REGNO (operands[2]) != REGNO (operands[0]))
9519       rc = reverse_condition (rc);
9520     else
9521       std::swap (operands[1], operands[2]);
9523     operands[6] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
9524   }
9525   "
9526   [(set_attr "conds" "clob")
9527    (set_attr "enabled_for_depr_it" "no,yes,yes")
9528    (set_attr "type" "multiple")]
9531 (define_insn "movcond"
9532   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9533         (if_then_else:SI
9534          (match_operator 5 "arm_comparison_operator"
9535           [(match_operand:SI 3 "s_register_operand" "r,r,r")
9536            (match_operand:SI 4 "arm_add_operand" "rIL,rIL,rIL")])
9537          (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
9538          (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
9539    (clobber (reg:CC CC_REGNUM))]
9540   "TARGET_ARM"
9541   "*
9542   if (GET_CODE (operands[5]) == LT
9543       && (operands[4] == const0_rtx))
9544     {
9545       if (which_alternative != 1 && REG_P (operands[1]))
9546         {
9547           if (operands[2] == const0_rtx)
9548             return \"and\\t%0, %1, %3, asr #31\";
9549           return \"ands\\t%0, %1, %3, asr #32\;movcc\\t%0, %2\";
9550         }
9551       else if (which_alternative != 0 && REG_P (operands[2]))
9552         {
9553           if (operands[1] == const0_rtx)
9554             return \"bic\\t%0, %2, %3, asr #31\";
9555           return \"bics\\t%0, %2, %3, asr #32\;movcs\\t%0, %1\";
9556         }
9557       /* The only case that falls through to here is when both ops 1 & 2
9558          are constants.  */
9559     }
9561   if (GET_CODE (operands[5]) == GE
9562       && (operands[4] == const0_rtx))
9563     {
9564       if (which_alternative != 1 && REG_P (operands[1]))
9565         {
9566           if (operands[2] == const0_rtx)
9567             return \"bic\\t%0, %1, %3, asr #31\";
9568           return \"bics\\t%0, %1, %3, asr #32\;movcs\\t%0, %2\";
9569         }
9570       else if (which_alternative != 0 && REG_P (operands[2]))
9571         {
9572           if (operands[1] == const0_rtx)
9573             return \"and\\t%0, %2, %3, asr #31\";
9574           return \"ands\\t%0, %2, %3, asr #32\;movcc\\t%0, %1\";
9575         }
9576       /* The only case that falls through to here is when both ops 1 & 2
9577          are constants.  */
9578     }
9579   if (CONST_INT_P (operands[4])
9580       && !const_ok_for_arm (INTVAL (operands[4])))
9581     output_asm_insn (\"cmn\\t%3, #%n4\", operands);
9582   else
9583     output_asm_insn (\"cmp\\t%3, %4\", operands);
9584   if (which_alternative != 0)
9585     output_asm_insn (\"mov%d5\\t%0, %1\", operands);
9586   if (which_alternative != 1)
9587     output_asm_insn (\"mov%D5\\t%0, %2\", operands);
9588   return \"\";
9589   "
9590   [(set_attr "conds" "clob")
9591    (set_attr "length" "8,8,12")
9592    (set_attr "type" "multiple")]
9595 ;; ??? The patterns below need checking for Thumb-2 usefulness.
9597 (define_insn "*ifcompare_plus_move"
9598   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9599         (if_then_else:SI (match_operator 6 "arm_comparison_operator"
9600                           [(match_operand:SI 4 "s_register_operand" "r,r")
9601                            (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
9602                          (plus:SI
9603                           (match_operand:SI 2 "s_register_operand" "r,r")
9604                           (match_operand:SI 3 "arm_add_operand" "rIL,rIL"))
9605                          (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))
9606    (clobber (reg:CC CC_REGNUM))]
9607   "TARGET_ARM"
9608   "#"
9609   [(set_attr "conds" "clob")
9610    (set_attr "length" "8,12")
9611    (set_attr "type" "multiple")]
9614 (define_insn "*if_plus_move"
9615   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
9616         (if_then_else:SI
9617          (match_operator 4 "arm_comparison_operator"
9618           [(match_operand 5 "cc_register" "") (const_int 0)])
9619          (plus:SI
9620           (match_operand:SI 2 "s_register_operand" "r,r,r,r")
9621           (match_operand:SI 3 "arm_add_operand" "rI,L,rI,L"))
9622          (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")))]
9623   "TARGET_ARM"
9624   "@
9625    add%d4\\t%0, %2, %3
9626    sub%d4\\t%0, %2, #%n3
9627    add%d4\\t%0, %2, %3\;mov%D4\\t%0, %1
9628    sub%d4\\t%0, %2, #%n3\;mov%D4\\t%0, %1"
9629   [(set_attr "conds" "use")
9630    (set_attr "length" "4,4,8,8")
9631    (set_attr_alternative "type"
9632                          [(if_then_else (match_operand 3 "const_int_operand" "")
9633                                         (const_string "alu_imm" )
9634                                         (const_string "alu_sreg"))
9635                           (const_string "alu_imm")
9636                           (const_string "multiple")
9637                           (const_string "multiple")])]
9640 (define_insn "*ifcompare_move_plus"
9641   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9642         (if_then_else:SI (match_operator 6 "arm_comparison_operator"
9643                           [(match_operand:SI 4 "s_register_operand" "r,r")
9644                            (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
9645                          (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
9646                          (plus:SI
9647                           (match_operand:SI 2 "s_register_operand" "r,r")
9648                           (match_operand:SI 3 "arm_add_operand" "rIL,rIL"))))
9649    (clobber (reg:CC CC_REGNUM))]
9650   "TARGET_ARM"
9651   "#"
9652   [(set_attr "conds" "clob")
9653    (set_attr "length" "8,12")
9654    (set_attr "type" "multiple")]
9657 (define_insn "*if_move_plus"
9658   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
9659         (if_then_else:SI
9660          (match_operator 4 "arm_comparison_operator"
9661           [(match_operand 5 "cc_register" "") (const_int 0)])
9662          (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")
9663          (plus:SI
9664           (match_operand:SI 2 "s_register_operand" "r,r,r,r")
9665           (match_operand:SI 3 "arm_add_operand" "rI,L,rI,L"))))]
9666   "TARGET_ARM"
9667   "@
9668    add%D4\\t%0, %2, %3
9669    sub%D4\\t%0, %2, #%n3
9670    add%D4\\t%0, %2, %3\;mov%d4\\t%0, %1
9671    sub%D4\\t%0, %2, #%n3\;mov%d4\\t%0, %1"
9672   [(set_attr "conds" "use")
9673    (set_attr "length" "4,4,8,8")
9674    (set_attr_alternative "type"
9675                          [(if_then_else (match_operand 3 "const_int_operand" "")
9676                                         (const_string "alu_imm" )
9677                                         (const_string "alu_sreg"))
9678                           (const_string "alu_imm")
9679                           (const_string "multiple")
9680                           (const_string "multiple")])]
9683 (define_insn "*ifcompare_arith_arith"
9684   [(set (match_operand:SI 0 "s_register_operand" "=r")
9685         (if_then_else:SI (match_operator 9 "arm_comparison_operator"
9686                           [(match_operand:SI 5 "s_register_operand" "r")
9687                            (match_operand:SI 6 "arm_add_operand" "rIL")])
9688                          (match_operator:SI 8 "shiftable_operator"
9689                           [(match_operand:SI 1 "s_register_operand" "r")
9690                            (match_operand:SI 2 "arm_rhs_operand" "rI")])
9691                          (match_operator:SI 7 "shiftable_operator"
9692                           [(match_operand:SI 3 "s_register_operand" "r")
9693                            (match_operand:SI 4 "arm_rhs_operand" "rI")])))
9694    (clobber (reg:CC CC_REGNUM))]
9695   "TARGET_ARM"
9696   "#"
9697   [(set_attr "conds" "clob")
9698    (set_attr "length" "12")
9699    (set_attr "type" "multiple")]
9702 (define_insn "*if_arith_arith"
9703   [(set (match_operand:SI 0 "s_register_operand" "=r")
9704         (if_then_else:SI (match_operator 5 "arm_comparison_operator"
9705                           [(match_operand 8 "cc_register" "") (const_int 0)])
9706                          (match_operator:SI 6 "shiftable_operator"
9707                           [(match_operand:SI 1 "s_register_operand" "r")
9708                            (match_operand:SI 2 "arm_rhs_operand" "rI")])
9709                          (match_operator:SI 7 "shiftable_operator"
9710                           [(match_operand:SI 3 "s_register_operand" "r")
9711                            (match_operand:SI 4 "arm_rhs_operand" "rI")])))]
9712   "TARGET_ARM"
9713   "%I6%d5\\t%0, %1, %2\;%I7%D5\\t%0, %3, %4"
9714   [(set_attr "conds" "use")
9715    (set_attr "length" "8")
9716    (set_attr "type" "multiple")]
9719 (define_insn "*ifcompare_arith_move"
9720   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9721         (if_then_else:SI (match_operator 6 "arm_comparison_operator"
9722                           [(match_operand:SI 2 "s_register_operand" "r,r")
9723                            (match_operand:SI 3 "arm_add_operand" "rIL,rIL")])
9724                          (match_operator:SI 7 "shiftable_operator"
9725                           [(match_operand:SI 4 "s_register_operand" "r,r")
9726                            (match_operand:SI 5 "arm_rhs_operand" "rI,rI")])
9727                          (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))
9728    (clobber (reg:CC CC_REGNUM))]
9729   "TARGET_ARM"
9730   "*
9731   /* If we have an operation where (op x 0) is the identity operation and
9732      the conditional operator is LT or GE and we are comparing against zero and
9733      everything is in registers then we can do this in two instructions.  */
9734   if (operands[3] == const0_rtx
9735       && GET_CODE (operands[7]) != AND
9736       && REG_P (operands[5])
9737       && REG_P (operands[1])
9738       && REGNO (operands[1]) == REGNO (operands[4])
9739       && REGNO (operands[4]) != REGNO (operands[0]))
9740     {
9741       if (GET_CODE (operands[6]) == LT)
9742         return \"and\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\";
9743       else if (GET_CODE (operands[6]) == GE)
9744         return \"bic\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\";
9745     }
9746   if (CONST_INT_P (operands[3])
9747       && !const_ok_for_arm (INTVAL (operands[3])))
9748     output_asm_insn (\"cmn\\t%2, #%n3\", operands);
9749   else
9750     output_asm_insn (\"cmp\\t%2, %3\", operands);
9751   output_asm_insn (\"%I7%d6\\t%0, %4, %5\", operands);
9752   if (which_alternative != 0)
9753     return \"mov%D6\\t%0, %1\";
9754   return \"\";
9755   "
9756   [(set_attr "conds" "clob")
9757    (set_attr "length" "8,12")
9758    (set_attr "type" "multiple")]
9761 (define_insn "*if_arith_move"
9762   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9763         (if_then_else:SI (match_operator 4 "arm_comparison_operator"
9764                           [(match_operand 6 "cc_register" "") (const_int 0)])
9765                          (match_operator:SI 5 "shiftable_operator"
9766                           [(match_operand:SI 2 "s_register_operand" "r,r")
9767                            (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
9768                          (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))]
9769   "TARGET_ARM"
9770   "@
9771    %I5%d4\\t%0, %2, %3
9772    %I5%d4\\t%0, %2, %3\;mov%D4\\t%0, %1"
9773   [(set_attr "conds" "use")
9774    (set_attr "length" "4,8")
9775    (set_attr_alternative "type"
9776                          [(if_then_else (match_operand 3 "const_int_operand" "")
9777                                         (const_string "alu_shift_imm" )
9778                                         (const_string "alu_shift_reg"))
9779                           (const_string "multiple")])]
9782 (define_insn "*ifcompare_move_arith"
9783   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9784         (if_then_else:SI (match_operator 6 "arm_comparison_operator"
9785                           [(match_operand:SI 4 "s_register_operand" "r,r")
9786                            (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
9787                          (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
9788                          (match_operator:SI 7 "shiftable_operator"
9789                           [(match_operand:SI 2 "s_register_operand" "r,r")
9790                            (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
9791    (clobber (reg:CC CC_REGNUM))]
9792   "TARGET_ARM"
9793   "*
9794   /* If we have an operation where (op x 0) is the identity operation and
9795      the conditional operator is LT or GE and we are comparing against zero and
9796      everything is in registers then we can do this in two instructions */
9797   if (operands[5] == const0_rtx
9798       && GET_CODE (operands[7]) != AND
9799       && REG_P (operands[3])
9800       && REG_P (operands[1])
9801       && REGNO (operands[1]) == REGNO (operands[2])
9802       && REGNO (operands[2]) != REGNO (operands[0]))
9803     {
9804       if (GET_CODE (operands[6]) == GE)
9805         return \"and\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\";
9806       else if (GET_CODE (operands[6]) == LT)
9807         return \"bic\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\";
9808     }
9810   if (CONST_INT_P (operands[5])
9811       && !const_ok_for_arm (INTVAL (operands[5])))
9812     output_asm_insn (\"cmn\\t%4, #%n5\", operands);
9813   else
9814     output_asm_insn (\"cmp\\t%4, %5\", operands);
9816   if (which_alternative != 0)
9817     output_asm_insn (\"mov%d6\\t%0, %1\", operands);
9818   return \"%I7%D6\\t%0, %2, %3\";
9819   "
9820   [(set_attr "conds" "clob")
9821    (set_attr "length" "8,12")
9822    (set_attr "type" "multiple")]
9825 (define_insn "*if_move_arith"
9826   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9827         (if_then_else:SI
9828          (match_operator 4 "arm_comparison_operator"
9829           [(match_operand 6 "cc_register" "") (const_int 0)])
9830          (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
9831          (match_operator:SI 5 "shiftable_operator"
9832           [(match_operand:SI 2 "s_register_operand" "r,r")
9833            (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))]
9834   "TARGET_ARM"
9835   "@
9836    %I5%D4\\t%0, %2, %3
9837    %I5%D4\\t%0, %2, %3\;mov%d4\\t%0, %1"
9838   [(set_attr "conds" "use")
9839    (set_attr "length" "4,8")
9840    (set_attr_alternative "type"
9841                          [(if_then_else (match_operand 3 "const_int_operand" "")
9842                                         (const_string "alu_shift_imm" )
9843                                         (const_string "alu_shift_reg"))
9844                           (const_string "multiple")])]
9847 (define_insn "*ifcompare_move_not"
9848   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9849         (if_then_else:SI
9850          (match_operator 5 "arm_comparison_operator"
9851           [(match_operand:SI 3 "s_register_operand" "r,r")
9852            (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
9853          (match_operand:SI 1 "arm_not_operand" "0,?rIK")
9854          (not:SI
9855           (match_operand:SI 2 "s_register_operand" "r,r"))))
9856    (clobber (reg:CC CC_REGNUM))]
9857   "TARGET_ARM"
9858   "#"
9859   [(set_attr "conds" "clob")
9860    (set_attr "length" "8,12")
9861    (set_attr "type" "multiple")]
9864 (define_insn "*if_move_not"
9865   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9866         (if_then_else:SI
9867          (match_operator 4 "arm_comparison_operator"
9868           [(match_operand 3 "cc_register" "") (const_int 0)])
9869          (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
9870          (not:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))))]
9871   "TARGET_ARM"
9872   "@
9873    mvn%D4\\t%0, %2
9874    mov%d4\\t%0, %1\;mvn%D4\\t%0, %2
9875    mvn%d4\\t%0, #%B1\;mvn%D4\\t%0, %2"
9876   [(set_attr "conds" "use")
9877    (set_attr "type" "mvn_reg")
9878    (set_attr "length" "4,8,8")
9879    (set_attr "type" "mvn_reg,multiple,multiple")]
9882 (define_insn "*ifcompare_not_move"
9883   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9884         (if_then_else:SI 
9885          (match_operator 5 "arm_comparison_operator"
9886           [(match_operand:SI 3 "s_register_operand" "r,r")
9887            (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
9888          (not:SI
9889           (match_operand:SI 2 "s_register_operand" "r,r"))
9890          (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
9891    (clobber (reg:CC CC_REGNUM))]
9892   "TARGET_ARM"
9893   "#"
9894   [(set_attr "conds" "clob")
9895    (set_attr "length" "8,12")
9896    (set_attr "type" "multiple")]
9899 (define_insn "*if_not_move"
9900   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9901         (if_then_else:SI
9902          (match_operator 4 "arm_comparison_operator"
9903           [(match_operand 3 "cc_register" "") (const_int 0)])
9904          (not:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))
9905          (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
9906   "TARGET_ARM"
9907   "@
9908    mvn%d4\\t%0, %2
9909    mov%D4\\t%0, %1\;mvn%d4\\t%0, %2
9910    mvn%D4\\t%0, #%B1\;mvn%d4\\t%0, %2"
9911   [(set_attr "conds" "use")
9912    (set_attr "type" "mvn_reg,multiple,multiple")
9913    (set_attr "length" "4,8,8")]
9916 (define_insn "*ifcompare_shift_move"
9917   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9918         (if_then_else:SI
9919          (match_operator 6 "arm_comparison_operator"
9920           [(match_operand:SI 4 "s_register_operand" "r,r")
9921            (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
9922          (match_operator:SI 7 "shift_operator"
9923           [(match_operand:SI 2 "s_register_operand" "r,r")
9924            (match_operand:SI 3 "arm_rhs_operand" "rM,rM")])
9925          (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
9926    (clobber (reg:CC CC_REGNUM))]
9927   "TARGET_ARM"
9928   "#"
9929   [(set_attr "conds" "clob")
9930    (set_attr "length" "8,12")
9931    (set_attr "type" "multiple")]
9934 (define_insn "*if_shift_move"
9935   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9936         (if_then_else:SI
9937          (match_operator 5 "arm_comparison_operator"
9938           [(match_operand 6 "cc_register" "") (const_int 0)])
9939          (match_operator:SI 4 "shift_operator"
9940           [(match_operand:SI 2 "s_register_operand" "r,r,r")
9941            (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM")])
9942          (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
9943   "TARGET_ARM"
9944   "@
9945    mov%d5\\t%0, %2%S4
9946    mov%D5\\t%0, %1\;mov%d5\\t%0, %2%S4
9947    mvn%D5\\t%0, #%B1\;mov%d5\\t%0, %2%S4"
9948   [(set_attr "conds" "use")
9949    (set_attr "shift" "2")
9950    (set_attr "length" "4,8,8")
9951    (set_attr_alternative "type"
9952                          [(if_then_else (match_operand 3 "const_int_operand" "")
9953                                         (const_string "mov_shift" )
9954                                         (const_string "mov_shift_reg"))
9955                           (const_string "multiple")
9956                           (const_string "multiple")])]
9959 (define_insn "*ifcompare_move_shift"
9960   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9961         (if_then_else:SI
9962          (match_operator 6 "arm_comparison_operator"
9963           [(match_operand:SI 4 "s_register_operand" "r,r")
9964            (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
9965          (match_operand:SI 1 "arm_not_operand" "0,?rIK")
9966          (match_operator:SI 7 "shift_operator"
9967           [(match_operand:SI 2 "s_register_operand" "r,r")
9968            (match_operand:SI 3 "arm_rhs_operand" "rM,rM")])))
9969    (clobber (reg:CC CC_REGNUM))]
9970   "TARGET_ARM"
9971   "#"
9972   [(set_attr "conds" "clob")
9973    (set_attr "length" "8,12")
9974    (set_attr "type" "multiple")]
9977 (define_insn "*if_move_shift"
9978   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9979         (if_then_else:SI
9980          (match_operator 5 "arm_comparison_operator"
9981           [(match_operand 6 "cc_register" "") (const_int 0)])
9982          (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
9983          (match_operator:SI 4 "shift_operator"
9984           [(match_operand:SI 2 "s_register_operand" "r,r,r")
9985            (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM")])))]
9986   "TARGET_ARM"
9987   "@
9988    mov%D5\\t%0, %2%S4
9989    mov%d5\\t%0, %1\;mov%D5\\t%0, %2%S4
9990    mvn%d5\\t%0, #%B1\;mov%D5\\t%0, %2%S4"
9991   [(set_attr "conds" "use")
9992    (set_attr "shift" "2")
9993    (set_attr "length" "4,8,8")
9994    (set_attr_alternative "type"
9995                          [(if_then_else (match_operand 3 "const_int_operand" "")
9996                                         (const_string "mov_shift" )
9997                                         (const_string "mov_shift_reg"))
9998                           (const_string "multiple")
9999                           (const_string "multiple")])]
10002 (define_insn "*ifcompare_shift_shift"
10003   [(set (match_operand:SI 0 "s_register_operand" "=r")
10004         (if_then_else:SI
10005          (match_operator 7 "arm_comparison_operator"
10006           [(match_operand:SI 5 "s_register_operand" "r")
10007            (match_operand:SI 6 "arm_add_operand" "rIL")])
10008          (match_operator:SI 8 "shift_operator"
10009           [(match_operand:SI 1 "s_register_operand" "r")
10010            (match_operand:SI 2 "arm_rhs_operand" "rM")])
10011          (match_operator:SI 9 "shift_operator"
10012           [(match_operand:SI 3 "s_register_operand" "r")
10013            (match_operand:SI 4 "arm_rhs_operand" "rM")])))
10014    (clobber (reg:CC CC_REGNUM))]
10015   "TARGET_ARM"
10016   "#"
10017   [(set_attr "conds" "clob")
10018    (set_attr "length" "12")
10019    (set_attr "type" "multiple")]
10022 (define_insn "*if_shift_shift"
10023   [(set (match_operand:SI 0 "s_register_operand" "=r")
10024         (if_then_else:SI
10025          (match_operator 5 "arm_comparison_operator"
10026           [(match_operand 8 "cc_register" "") (const_int 0)])
10027          (match_operator:SI 6 "shift_operator"
10028           [(match_operand:SI 1 "s_register_operand" "r")
10029            (match_operand:SI 2 "arm_rhs_operand" "rM")])
10030          (match_operator:SI 7 "shift_operator"
10031           [(match_operand:SI 3 "s_register_operand" "r")
10032            (match_operand:SI 4 "arm_rhs_operand" "rM")])))]
10033   "TARGET_ARM"
10034   "mov%d5\\t%0, %1%S6\;mov%D5\\t%0, %3%S7"
10035   [(set_attr "conds" "use")
10036    (set_attr "shift" "1")
10037    (set_attr "length" "8")
10038    (set (attr "type") (if_then_else
10039                         (and (match_operand 2 "const_int_operand" "")
10040                              (match_operand 4 "const_int_operand" ""))
10041                       (const_string "mov_shift")
10042                       (const_string "mov_shift_reg")))]
10045 (define_insn "*ifcompare_not_arith"
10046   [(set (match_operand:SI 0 "s_register_operand" "=r")
10047         (if_then_else:SI
10048          (match_operator 6 "arm_comparison_operator"
10049           [(match_operand:SI 4 "s_register_operand" "r")
10050            (match_operand:SI 5 "arm_add_operand" "rIL")])
10051          (not:SI (match_operand:SI 1 "s_register_operand" "r"))
10052          (match_operator:SI 7 "shiftable_operator"
10053           [(match_operand:SI 2 "s_register_operand" "r")
10054            (match_operand:SI 3 "arm_rhs_operand" "rI")])))
10055    (clobber (reg:CC CC_REGNUM))]
10056   "TARGET_ARM"
10057   "#"
10058   [(set_attr "conds" "clob")
10059    (set_attr "length" "12")
10060    (set_attr "type" "multiple")]
10063 (define_insn "*if_not_arith"
10064   [(set (match_operand:SI 0 "s_register_operand" "=r")
10065         (if_then_else:SI
10066          (match_operator 5 "arm_comparison_operator"
10067           [(match_operand 4 "cc_register" "") (const_int 0)])
10068          (not:SI (match_operand:SI 1 "s_register_operand" "r"))
10069          (match_operator:SI 6 "shiftable_operator"
10070           [(match_operand:SI 2 "s_register_operand" "r")
10071            (match_operand:SI 3 "arm_rhs_operand" "rI")])))]
10072   "TARGET_ARM"
10073   "mvn%d5\\t%0, %1\;%I6%D5\\t%0, %2, %3"
10074   [(set_attr "conds" "use")
10075    (set_attr "type" "mvn_reg")
10076    (set_attr "length" "8")]
10079 (define_insn "*ifcompare_arith_not"
10080   [(set (match_operand:SI 0 "s_register_operand" "=r")
10081         (if_then_else:SI
10082          (match_operator 6 "arm_comparison_operator"
10083           [(match_operand:SI 4 "s_register_operand" "r")
10084            (match_operand:SI 5 "arm_add_operand" "rIL")])
10085          (match_operator:SI 7 "shiftable_operator"
10086           [(match_operand:SI 2 "s_register_operand" "r")
10087            (match_operand:SI 3 "arm_rhs_operand" "rI")])
10088          (not:SI (match_operand:SI 1 "s_register_operand" "r"))))
10089    (clobber (reg:CC CC_REGNUM))]
10090   "TARGET_ARM"
10091   "#"
10092   [(set_attr "conds" "clob")
10093    (set_attr "length" "12")
10094    (set_attr "type" "multiple")]
10097 (define_insn "*if_arith_not"
10098   [(set (match_operand:SI 0 "s_register_operand" "=r")
10099         (if_then_else:SI
10100          (match_operator 5 "arm_comparison_operator"
10101           [(match_operand 4 "cc_register" "") (const_int 0)])
10102          (match_operator:SI 6 "shiftable_operator"
10103           [(match_operand:SI 2 "s_register_operand" "r")
10104            (match_operand:SI 3 "arm_rhs_operand" "rI")])
10105          (not:SI (match_operand:SI 1 "s_register_operand" "r"))))]
10106   "TARGET_ARM"
10107   "mvn%D5\\t%0, %1\;%I6%d5\\t%0, %2, %3"
10108   [(set_attr "conds" "use")
10109    (set_attr "type" "multiple")
10110    (set_attr "length" "8")]
10113 (define_insn "*ifcompare_neg_move"
10114   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10115         (if_then_else:SI
10116          (match_operator 5 "arm_comparison_operator"
10117           [(match_operand:SI 3 "s_register_operand" "r,r")
10118            (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
10119          (neg:SI (match_operand:SI 2 "s_register_operand" "r,r"))
10120          (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
10121    (clobber (reg:CC CC_REGNUM))]
10122   "TARGET_ARM"
10123   "#"
10124   [(set_attr "conds" "clob")
10125    (set_attr "length" "8,12")
10126    (set_attr "type" "multiple")]
10129 (define_insn_and_split "*if_neg_move"
10130   [(set (match_operand:SI 0 "s_register_operand" "=l,r")
10131         (if_then_else:SI
10132          (match_operator 4 "arm_comparison_operator"
10133           [(match_operand 3 "cc_register" "") (const_int 0)])
10134          (neg:SI (match_operand:SI 2 "s_register_operand" "l,r"))
10135          (match_operand:SI 1 "s_register_operand" "0,0")))]
10136   "TARGET_32BIT"
10137   "#"
10138   "&& reload_completed"
10139   [(cond_exec (match_op_dup 4 [(match_dup 3) (const_int 0)])
10140               (set (match_dup 0) (neg:SI (match_dup 2))))]
10141   ""
10142   [(set_attr "conds" "use")
10143    (set_attr "length" "4")
10144    (set_attr "arch" "t2,32")
10145    (set_attr "enabled_for_depr_it" "yes,no")
10146    (set_attr "type" "logic_shift_imm")]
10149 (define_insn "*ifcompare_move_neg"
10150   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10151         (if_then_else:SI
10152          (match_operator 5 "arm_comparison_operator"
10153           [(match_operand:SI 3 "s_register_operand" "r,r")
10154            (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
10155          (match_operand:SI 1 "arm_not_operand" "0,?rIK")
10156          (neg:SI (match_operand:SI 2 "s_register_operand" "r,r"))))
10157    (clobber (reg:CC CC_REGNUM))]
10158   "TARGET_ARM"
10159   "#"
10160   [(set_attr "conds" "clob")
10161    (set_attr "length" "8,12")
10162    (set_attr "type" "multiple")]
10165 (define_insn_and_split "*if_move_neg"
10166   [(set (match_operand:SI 0 "s_register_operand" "=l,r")
10167         (if_then_else:SI
10168          (match_operator 4 "arm_comparison_operator"
10169           [(match_operand 3 "cc_register" "") (const_int 0)])
10170          (match_operand:SI 1 "s_register_operand" "0,0")
10171          (neg:SI (match_operand:SI 2 "s_register_operand" "l,r"))))]
10172   "TARGET_32BIT"
10173   "#"
10174   "&& reload_completed"
10175   [(cond_exec (match_dup 5)
10176               (set (match_dup 0) (neg:SI (match_dup 2))))]
10177   {
10178     machine_mode mode = GET_MODE (operands[3]);
10179     rtx_code rc = GET_CODE (operands[4]);
10181     if (mode == CCFPmode || mode == CCFPEmode)
10182       rc = reverse_condition_maybe_unordered (rc);
10183     else
10184       rc = reverse_condition (rc);
10186     operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[3], const0_rtx);
10187   }
10188   [(set_attr "conds" "use")
10189    (set_attr "length" "4")
10190    (set_attr "arch" "t2,32")
10191    (set_attr "enabled_for_depr_it" "yes,no")
10192    (set_attr "type" "logic_shift_imm")]
10195 (define_insn "*arith_adjacentmem"
10196   [(set (match_operand:SI 0 "s_register_operand" "=r")
10197         (match_operator:SI 1 "shiftable_operator"
10198          [(match_operand:SI 2 "memory_operand" "m")
10199           (match_operand:SI 3 "memory_operand" "m")]))
10200    (clobber (match_scratch:SI 4 "=r"))]
10201   "TARGET_ARM && adjacent_mem_locations (operands[2], operands[3])"
10202   "*
10203   {
10204     rtx ldm[3];
10205     rtx arith[4];
10206     rtx base_reg;
10207     HOST_WIDE_INT val1 = 0, val2 = 0;
10209     if (REGNO (operands[0]) > REGNO (operands[4]))
10210       {
10211         ldm[1] = operands[4];
10212         ldm[2] = operands[0];
10213       }
10214     else
10215       {
10216         ldm[1] = operands[0];
10217         ldm[2] = operands[4];
10218       }
10220     base_reg = XEXP (operands[2], 0);
10222     if (!REG_P (base_reg))
10223       {
10224         val1 = INTVAL (XEXP (base_reg, 1));
10225         base_reg = XEXP (base_reg, 0);
10226       }
10228     if (!REG_P (XEXP (operands[3], 0)))
10229       val2 = INTVAL (XEXP (XEXP (operands[3], 0), 1));
10231     arith[0] = operands[0];
10232     arith[3] = operands[1];
10234     if (val1 < val2)
10235       {
10236         arith[1] = ldm[1];
10237         arith[2] = ldm[2];
10238       }
10239     else
10240       {
10241         arith[1] = ldm[2];
10242         arith[2] = ldm[1];
10243       }
10245     ldm[0] = base_reg;
10246     if (val1 !=0 && val2 != 0)
10247       {
10248         rtx ops[3];
10250         if (val1 == 4 || val2 == 4)
10251           /* Other val must be 8, since we know they are adjacent and neither
10252              is zero.  */
10253           output_asm_insn (\"ldm%(ib%)\\t%0, {%1, %2}\", ldm);
10254         else if (const_ok_for_arm (val1) || const_ok_for_arm (-val1))
10255           {
10256             ldm[0] = ops[0] = operands[4];
10257             ops[1] = base_reg;
10258             ops[2] = GEN_INT (val1);
10259             output_add_immediate (ops);
10260             if (val1 < val2)
10261               output_asm_insn (\"ldm%(ia%)\\t%0, {%1, %2}\", ldm);
10262             else
10263               output_asm_insn (\"ldm%(da%)\\t%0, {%1, %2}\", ldm);
10264           }
10265         else
10266           {
10267             /* Offset is out of range for a single add, so use two ldr.  */
10268             ops[0] = ldm[1];
10269             ops[1] = base_reg;
10270             ops[2] = GEN_INT (val1);
10271             output_asm_insn (\"ldr%?\\t%0, [%1, %2]\", ops);
10272             ops[0] = ldm[2];
10273             ops[2] = GEN_INT (val2);
10274             output_asm_insn (\"ldr%?\\t%0, [%1, %2]\", ops);
10275           }
10276       }
10277     else if (val1 != 0)
10278       {
10279         if (val1 < val2)
10280           output_asm_insn (\"ldm%(da%)\\t%0, {%1, %2}\", ldm);
10281         else
10282           output_asm_insn (\"ldm%(ia%)\\t%0, {%1, %2}\", ldm);
10283       }
10284     else
10285       {
10286         if (val1 < val2)
10287           output_asm_insn (\"ldm%(ia%)\\t%0, {%1, %2}\", ldm);
10288         else
10289           output_asm_insn (\"ldm%(da%)\\t%0, {%1, %2}\", ldm);
10290       }
10291     output_asm_insn (\"%I3%?\\t%0, %1, %2\", arith);
10292     return \"\";
10293   }"
10294   [(set_attr "length" "12")
10295    (set_attr "predicable" "yes")
10296    (set_attr "type" "load1")]
10299 ; This pattern is never tried by combine, so do it as a peephole
10301 (define_peephole2
10302   [(set (match_operand:SI 0 "arm_general_register_operand" "")
10303         (match_operand:SI 1 "arm_general_register_operand" ""))
10304    (set (reg:CC CC_REGNUM)
10305         (compare:CC (match_dup 1) (const_int 0)))]
10306   "TARGET_ARM"
10307   [(parallel [(set (reg:CC CC_REGNUM) (compare:CC (match_dup 1) (const_int 0)))
10308               (set (match_dup 0) (match_dup 1))])]
10309   ""
10312 (define_split
10313   [(set (match_operand:SI 0 "s_register_operand" "")
10314         (and:SI (ge:SI (match_operand:SI 1 "s_register_operand" "")
10315                        (const_int 0))
10316                 (neg:SI (match_operator:SI 2 "arm_comparison_operator"
10317                          [(match_operand:SI 3 "s_register_operand" "")
10318                           (match_operand:SI 4 "arm_rhs_operand" "")]))))
10319    (clobber (match_operand:SI 5 "s_register_operand" ""))]
10320   "TARGET_ARM"
10321   [(set (match_dup 5) (not:SI (ashiftrt:SI (match_dup 1) (const_int 31))))
10322    (set (match_dup 0) (and:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
10323                               (match_dup 5)))]
10324   ""
10327 ;; This split can be used because CC_Z mode implies that the following
10328 ;; branch will be an equality, or an unsigned inequality, so the sign
10329 ;; extension is not needed.
10331 (define_split
10332   [(set (reg:CC_Z CC_REGNUM)
10333         (compare:CC_Z
10334          (ashift:SI (subreg:SI (match_operand:QI 0 "memory_operand" "") 0)
10335                     (const_int 24))
10336          (match_operand 1 "const_int_operand" "")))
10337    (clobber (match_scratch:SI 2 ""))]
10338   "TARGET_ARM
10339    && (((unsigned HOST_WIDE_INT) INTVAL (operands[1]))
10340        == (((unsigned HOST_WIDE_INT) INTVAL (operands[1])) >> 24) << 24)"
10341   [(set (match_dup 2) (zero_extend:SI (match_dup 0)))
10342    (set (reg:CC CC_REGNUM) (compare:CC (match_dup 2) (match_dup 1)))]
10343   "
10344   operands[1] = GEN_INT (((unsigned long) INTVAL (operands[1])) >> 24);
10345   "
10347 ;; ??? Check the patterns above for Thumb-2 usefulness
10349 (define_expand "prologue"
10350   [(clobber (const_int 0))]
10351   "TARGET_EITHER"
10352   "if (TARGET_32BIT)
10353      arm_expand_prologue ();
10354    else
10355      thumb1_expand_prologue ();
10356   DONE;
10357   "
10360 (define_expand "epilogue"
10361   [(clobber (const_int 0))]
10362   "TARGET_EITHER"
10363   "
10364   if (crtl->calls_eh_return)
10365     emit_insn (gen_force_register_use (gen_rtx_REG (Pmode, 2)));
10366   if (TARGET_THUMB1)
10367    {
10368      thumb1_expand_epilogue ();
10369      emit_jump_insn (gen_rtx_UNSPEC_VOLATILE (VOIDmode,
10370                      gen_rtvec (1, ret_rtx), VUNSPEC_EPILOGUE));
10371    }
10372   else if (HAVE_return)
10373    {
10374      /* HAVE_return is testing for USE_RETURN_INSN (FALSE).  Hence,
10375         no need for explicit testing again.  */
10376      emit_jump_insn (gen_return ());
10377    }
10378   else if (TARGET_32BIT)
10379    {
10380     arm_expand_epilogue (true);
10381    }
10382   DONE;
10383   "
10386 ;; Note - although unspec_volatile's USE all hard registers,
10387 ;; USEs are ignored after relaod has completed.  Thus we need
10388 ;; to add an unspec of the link register to ensure that flow
10389 ;; does not think that it is unused by the sibcall branch that
10390 ;; will replace the standard function epilogue.
10391 (define_expand "sibcall_epilogue"
10392    [(parallel [(unspec:SI [(reg:SI LR_REGNUM)] UNSPEC_REGISTER_USE)
10393                (unspec_volatile [(return)] VUNSPEC_EPILOGUE)])]
10394    "TARGET_32BIT"
10395    "
10396    arm_expand_epilogue (false);
10397    DONE;
10398    "
10401 (define_expand "eh_epilogue"
10402   [(use (match_operand:SI 0 "register_operand" ""))
10403    (use (match_operand:SI 1 "register_operand" ""))
10404    (use (match_operand:SI 2 "register_operand" ""))]
10405   "TARGET_EITHER"
10406   "
10407   {
10408     cfun->machine->eh_epilogue_sp_ofs = operands[1];
10409     if (!REG_P (operands[2]) || REGNO (operands[2]) != 2)
10410       {
10411         rtx ra = gen_rtx_REG (Pmode, 2);
10413         emit_move_insn (ra, operands[2]);
10414         operands[2] = ra;
10415       }
10416     /* This is a hack -- we may have crystalized the function type too
10417        early.  */
10418     cfun->machine->func_type = 0;
10419   }"
10422 ;; This split is only used during output to reduce the number of patterns
10423 ;; that need assembler instructions adding to them.  We allowed the setting
10424 ;; of the conditions to be implicit during rtl generation so that
10425 ;; the conditional compare patterns would work.  However this conflicts to
10426 ;; some extent with the conditional data operations, so we have to split them
10427 ;; up again here.
10429 ;; ??? Need to audit these splitters for Thumb-2.  Why isn't normal
10430 ;; conditional execution sufficient?
10432 (define_split
10433   [(set (match_operand:SI 0 "s_register_operand" "")
10434         (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10435                           [(match_operand 2 "" "") (match_operand 3 "" "")])
10436                          (match_dup 0)
10437                          (match_operand 4 "" "")))
10438    (clobber (reg:CC CC_REGNUM))]
10439   "TARGET_ARM && reload_completed"
10440   [(set (match_dup 5) (match_dup 6))
10441    (cond_exec (match_dup 7)
10442               (set (match_dup 0) (match_dup 4)))]
10443   "
10444   {
10445     machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10446                                              operands[2], operands[3]);
10447     enum rtx_code rc = GET_CODE (operands[1]);
10449     operands[5] = gen_rtx_REG (mode, CC_REGNUM);
10450     operands[6] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10451     if (mode == CCFPmode || mode == CCFPEmode)
10452       rc = reverse_condition_maybe_unordered (rc);
10453     else
10454       rc = reverse_condition (rc);
10456     operands[7] = gen_rtx_fmt_ee (rc, VOIDmode, operands[5], const0_rtx);
10457   }"
10460 (define_split
10461   [(set (match_operand:SI 0 "s_register_operand" "")
10462         (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10463                           [(match_operand 2 "" "") (match_operand 3 "" "")])
10464                          (match_operand 4 "" "")
10465                          (match_dup 0)))
10466    (clobber (reg:CC CC_REGNUM))]
10467   "TARGET_ARM && reload_completed"
10468   [(set (match_dup 5) (match_dup 6))
10469    (cond_exec (match_op_dup 1 [(match_dup 5) (const_int 0)])
10470               (set (match_dup 0) (match_dup 4)))]
10471   "
10472   {
10473     machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10474                                              operands[2], operands[3]);
10476     operands[5] = gen_rtx_REG (mode, CC_REGNUM);
10477     operands[6] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10478   }"
10481 (define_split
10482   [(set (match_operand:SI 0 "s_register_operand" "")
10483         (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10484                           [(match_operand 2 "" "") (match_operand 3 "" "")])
10485                          (match_operand 4 "" "")
10486                          (match_operand 5 "" "")))
10487    (clobber (reg:CC CC_REGNUM))]
10488   "TARGET_ARM && reload_completed"
10489   [(set (match_dup 6) (match_dup 7))
10490    (cond_exec (match_op_dup 1 [(match_dup 6) (const_int 0)])
10491               (set (match_dup 0) (match_dup 4)))
10492    (cond_exec (match_dup 8)
10493               (set (match_dup 0) (match_dup 5)))]
10494   "
10495   {
10496     machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10497                                              operands[2], operands[3]);
10498     enum rtx_code rc = GET_CODE (operands[1]);
10500     operands[6] = gen_rtx_REG (mode, CC_REGNUM);
10501     operands[7] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10502     if (mode == CCFPmode || mode == CCFPEmode)
10503       rc = reverse_condition_maybe_unordered (rc);
10504     else
10505       rc = reverse_condition (rc);
10507     operands[8] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
10508   }"
10511 (define_split
10512   [(set (match_operand:SI 0 "s_register_operand" "")
10513         (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10514                           [(match_operand:SI 2 "s_register_operand" "")
10515                            (match_operand:SI 3 "arm_add_operand" "")])
10516                          (match_operand:SI 4 "arm_rhs_operand" "")
10517                          (not:SI
10518                           (match_operand:SI 5 "s_register_operand" ""))))
10519    (clobber (reg:CC CC_REGNUM))]
10520   "TARGET_ARM && reload_completed"
10521   [(set (match_dup 6) (match_dup 7))
10522    (cond_exec (match_op_dup 1 [(match_dup 6) (const_int 0)])
10523               (set (match_dup 0) (match_dup 4)))
10524    (cond_exec (match_dup 8)
10525               (set (match_dup 0) (not:SI (match_dup 5))))]
10526   "
10527   {
10528     machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10529                                              operands[2], operands[3]);
10530     enum rtx_code rc = GET_CODE (operands[1]);
10532     operands[6] = gen_rtx_REG (mode, CC_REGNUM);
10533     operands[7] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10534     if (mode == CCFPmode || mode == CCFPEmode)
10535       rc = reverse_condition_maybe_unordered (rc);
10536     else
10537       rc = reverse_condition (rc);
10539     operands[8] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
10540   }"
10543 (define_insn "*cond_move_not"
10544   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10545         (if_then_else:SI (match_operator 4 "arm_comparison_operator"
10546                           [(match_operand 3 "cc_register" "") (const_int 0)])
10547                          (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
10548                          (not:SI
10549                           (match_operand:SI 2 "s_register_operand" "r,r"))))]
10550   "TARGET_ARM"
10551   "@
10552    mvn%D4\\t%0, %2
10553    mov%d4\\t%0, %1\;mvn%D4\\t%0, %2"
10554   [(set_attr "conds" "use")
10555    (set_attr "type" "mvn_reg,multiple")
10556    (set_attr "length" "4,8")]
10559 ;; The next two patterns occur when an AND operation is followed by a
10560 ;; scc insn sequence 
10562 (define_insn "*sign_extract_onebit"
10563   [(set (match_operand:SI 0 "s_register_operand" "=r")
10564         (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
10565                          (const_int 1)
10566                          (match_operand:SI 2 "const_int_operand" "n")))
10567     (clobber (reg:CC CC_REGNUM))]
10568   "TARGET_ARM"
10569   "*
10570     operands[2] = GEN_INT (1 << INTVAL (operands[2]));
10571     output_asm_insn (\"ands\\t%0, %1, %2\", operands);
10572     return \"mvnne\\t%0, #0\";
10573   "
10574   [(set_attr "conds" "clob")
10575    (set_attr "length" "8")
10576    (set_attr "type" "multiple")]
10579 (define_insn "*not_signextract_onebit"
10580   [(set (match_operand:SI 0 "s_register_operand" "=r")
10581         (not:SI
10582          (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
10583                           (const_int 1)
10584                           (match_operand:SI 2 "const_int_operand" "n"))))
10585    (clobber (reg:CC CC_REGNUM))]
10586   "TARGET_ARM"
10587   "*
10588     operands[2] = GEN_INT (1 << INTVAL (operands[2]));
10589     output_asm_insn (\"tst\\t%1, %2\", operands);
10590     output_asm_insn (\"mvneq\\t%0, #0\", operands);
10591     return \"movne\\t%0, #0\";
10592   "
10593   [(set_attr "conds" "clob")
10594    (set_attr "length" "12")
10595    (set_attr "type" "multiple")]
10597 ;; ??? The above patterns need auditing for Thumb-2
10599 ;; Push multiple registers to the stack.  Registers are in parallel (use ...)
10600 ;; expressions.  For simplicity, the first register is also in the unspec
10601 ;; part.
10602 ;; To avoid the usage of GNU extension, the length attribute is computed
10603 ;; in a C function arm_attr_length_push_multi.
10604 (define_insn "*push_multi"
10605   [(match_parallel 2 "multi_register_push"
10606     [(set (match_operand:BLK 0 "push_mult_memory_operand" "")
10607           (unspec:BLK [(match_operand:SI 1 "s_register_operand" "")]
10608                       UNSPEC_PUSH_MULT))])]
10609   ""
10610   "*
10611   {
10612     int num_saves = XVECLEN (operands[2], 0);
10613      
10614     /* For the StrongARM at least it is faster to
10615        use STR to store only a single register.
10616        In Thumb mode always use push, and the assembler will pick
10617        something appropriate.  */
10618     if (num_saves == 1 && TARGET_ARM)
10619       output_asm_insn (\"str%?\\t%1, [%m0, #-4]!\", operands);
10620     else
10621       {
10622         int i;
10623         char pattern[100];
10625         if (TARGET_ARM)
10626             strcpy (pattern, \"stm%(fd%)\\t%m0!, {%1\");
10627         else if (TARGET_THUMB2)
10628             strcpy (pattern, \"push%?\\t{%1\");
10629         else
10630             strcpy (pattern, \"push\\t{%1\");
10632         for (i = 1; i < num_saves; i++)
10633           {
10634             strcat (pattern, \", %|\");
10635             strcat (pattern,
10636                     reg_names[REGNO (XEXP (XVECEXP (operands[2], 0, i), 0))]);
10637           }
10639         strcat (pattern, \"}\");
10640         output_asm_insn (pattern, operands);
10641       }
10643     return \"\";
10644   }"
10645   [(set_attr "type" "store4")
10646    (set (attr "length")
10647         (symbol_ref "arm_attr_length_push_multi (operands[2], operands[1])"))]
10650 (define_insn "stack_tie"
10651   [(set (mem:BLK (scratch))
10652         (unspec:BLK [(match_operand:SI 0 "s_register_operand" "rk")
10653                      (match_operand:SI 1 "s_register_operand" "rk")]
10654                     UNSPEC_PRLG_STK))]
10655   ""
10656   ""
10657   [(set_attr "length" "0")
10658    (set_attr "type" "block")]
10661 ;; Pop (as used in epilogue RTL)
10663 (define_insn "*load_multiple_with_writeback"
10664   [(match_parallel 0 "load_multiple_operation"
10665     [(set (match_operand:SI 1 "s_register_operand" "+rk")
10666           (plus:SI (match_dup 1)
10667                    (match_operand:SI 2 "const_int_I_operand" "I")))
10668      (set (match_operand:SI 3 "s_register_operand" "=rk")
10669           (mem:SI (match_dup 1)))
10670         ])]
10671   "TARGET_32BIT && (reload_in_progress || reload_completed)"
10672   "*
10673   {
10674     arm_output_multireg_pop (operands, /*return_pc=*/false,
10675                                        /*cond=*/const_true_rtx,
10676                                        /*reverse=*/false,
10677                                        /*update=*/true);
10678     return \"\";
10679   }
10680   "
10681   [(set_attr "type" "load4")
10682    (set_attr "predicable" "yes")]
10685 ;; Pop with return (as used in epilogue RTL)
10687 ;; This instruction is generated when the registers are popped at the end of
10688 ;; epilogue.  Here, instead of popping the value into LR and then generating
10689 ;; jump to LR, value is popped into PC directly.  Hence, the pattern is combined
10690 ;;  with (return).
10691 (define_insn "*pop_multiple_with_writeback_and_return"
10692   [(match_parallel 0 "pop_multiple_return"
10693     [(return)
10694      (set (match_operand:SI 1 "s_register_operand" "+rk")
10695           (plus:SI (match_dup 1)
10696                    (match_operand:SI 2 "const_int_I_operand" "I")))
10697      (set (match_operand:SI 3 "s_register_operand" "=rk")
10698           (mem:SI (match_dup 1)))
10699         ])]
10700   "TARGET_32BIT && (reload_in_progress || reload_completed)"
10701   "*
10702   {
10703     arm_output_multireg_pop (operands, /*return_pc=*/true,
10704                                        /*cond=*/const_true_rtx,
10705                                        /*reverse=*/false,
10706                                        /*update=*/true);
10707     return \"\";
10708   }
10709   "
10710   [(set_attr "type" "load4")
10711    (set_attr "predicable" "yes")]
10714 (define_insn "*pop_multiple_with_return"
10715   [(match_parallel 0 "pop_multiple_return"
10716     [(return)
10717      (set (match_operand:SI 2 "s_register_operand" "=rk")
10718           (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
10719         ])]
10720   "TARGET_32BIT && (reload_in_progress || reload_completed)"
10721   "*
10722   {
10723     arm_output_multireg_pop (operands, /*return_pc=*/true,
10724                                        /*cond=*/const_true_rtx,
10725                                        /*reverse=*/false,
10726                                        /*update=*/false);
10727     return \"\";
10728   }
10729   "
10730   [(set_attr "type" "load4")
10731    (set_attr "predicable" "yes")]
10734 ;; Load into PC and return
10735 (define_insn "*ldr_with_return"
10736   [(return)
10737    (set (reg:SI PC_REGNUM)
10738         (mem:SI (post_inc:SI (match_operand:SI 0 "s_register_operand" "+rk"))))]
10739   "TARGET_32BIT && (reload_in_progress || reload_completed)"
10740   "ldr%?\t%|pc, [%0], #4"
10741   [(set_attr "type" "load1")
10742    (set_attr "predicable" "yes")]
10744 ;; Pop for floating point registers (as used in epilogue RTL)
10745 (define_insn "*vfp_pop_multiple_with_writeback"
10746   [(match_parallel 0 "pop_multiple_fp"
10747     [(set (match_operand:SI 1 "s_register_operand" "+rk")
10748           (plus:SI (match_dup 1)
10749                    (match_operand:SI 2 "const_int_I_operand" "I")))
10750      (set (match_operand:DF 3 "vfp_hard_register_operand" "")
10751           (mem:DF (match_dup 1)))])]
10752   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
10753   "*
10754   {
10755     int num_regs = XVECLEN (operands[0], 0);
10756     char pattern[100];
10757     rtx op_list[2];
10758     strcpy (pattern, \"vldm\\t\");
10759     strcat (pattern, reg_names[REGNO (SET_DEST (XVECEXP (operands[0], 0, 0)))]);
10760     strcat (pattern, \"!, {\");
10761     op_list[0] = XEXP (XVECEXP (operands[0], 0, 1), 0);
10762     strcat (pattern, \"%P0\");
10763     if ((num_regs - 1) > 1)
10764       {
10765         strcat (pattern, \"-%P1\");
10766         op_list [1] = XEXP (XVECEXP (operands[0], 0, num_regs - 1), 0);
10767       }
10769     strcat (pattern, \"}\");
10770     output_asm_insn (pattern, op_list);
10771     return \"\";
10772   }
10773   "
10774   [(set_attr "type" "load4")
10775    (set_attr "conds" "unconditional")
10776    (set_attr "predicable" "no")]
10779 ;; Special patterns for dealing with the constant pool
10781 (define_insn "align_4"
10782   [(unspec_volatile [(const_int 0)] VUNSPEC_ALIGN)]
10783   "TARGET_EITHER"
10784   "*
10785   assemble_align (32);
10786   return \"\";
10787   "
10788   [(set_attr "type" "no_insn")]
10791 (define_insn "align_8"
10792   [(unspec_volatile [(const_int 0)] VUNSPEC_ALIGN8)]
10793   "TARGET_EITHER"
10794   "*
10795   assemble_align (64);
10796   return \"\";
10797   "
10798   [(set_attr "type" "no_insn")]
10801 (define_insn "consttable_end"
10802   [(unspec_volatile [(const_int 0)] VUNSPEC_POOL_END)]
10803   "TARGET_EITHER"
10804   "*
10805   making_const_table = FALSE;
10806   return \"\";
10807   "
10808   [(set_attr "type" "no_insn")]
10811 (define_insn "consttable_1"
10812   [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_1)]
10813   "TARGET_EITHER"
10814   "*
10815   making_const_table = TRUE;
10816   assemble_integer (operands[0], 1, BITS_PER_WORD, 1);
10817   assemble_zeros (3);
10818   return \"\";
10819   "
10820   [(set_attr "length" "4")
10821    (set_attr "type" "no_insn")]
10824 (define_insn "consttable_2"
10825   [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_2)]
10826   "TARGET_EITHER"
10827   "*
10828   {
10829     rtx x = operands[0];
10830     making_const_table = TRUE;
10831     switch (GET_MODE_CLASS (GET_MODE (x)))
10832       {
10833       case MODE_FLOAT:
10834         arm_emit_fp16_const (x);
10835         break;
10836       default:
10837         assemble_integer (operands[0], 2, BITS_PER_WORD, 1);
10838         assemble_zeros (2);
10839         break;
10840       }
10841     return \"\";
10842   }"
10843   [(set_attr "length" "4")
10844    (set_attr "type" "no_insn")]
10847 (define_insn "consttable_4"
10848   [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_4)]
10849   "TARGET_EITHER"
10850   "*
10851   {
10852     rtx x = operands[0];
10853     making_const_table = TRUE;
10854     switch (GET_MODE_CLASS (GET_MODE (x)))
10855       {
10856       case MODE_FLOAT:
10857         {
10858           REAL_VALUE_TYPE r;
10859           REAL_VALUE_FROM_CONST_DOUBLE (r, x);
10860           assemble_real (r, GET_MODE (x), BITS_PER_WORD);
10861           break;
10862         }
10863       default:
10864         /* XXX: Sometimes gcc does something really dumb and ends up with
10865            a HIGH in a constant pool entry, usually because it's trying to
10866            load into a VFP register.  We know this will always be used in
10867            combination with a LO_SUM which ignores the high bits, so just
10868            strip off the HIGH.  */
10869         if (GET_CODE (x) == HIGH)
10870           x = XEXP (x, 0);
10871         assemble_integer (x, 4, BITS_PER_WORD, 1);
10872         mark_symbol_refs_as_used (x);
10873         break;
10874       }
10875     return \"\";
10876   }"
10877   [(set_attr "length" "4")
10878    (set_attr "type" "no_insn")]
10881 (define_insn "consttable_8"
10882   [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_8)]
10883   "TARGET_EITHER"
10884   "*
10885   {
10886     making_const_table = TRUE;
10887     switch (GET_MODE_CLASS (GET_MODE (operands[0])))
10888       {
10889        case MODE_FLOAT:
10890         {
10891           REAL_VALUE_TYPE r;
10892           REAL_VALUE_FROM_CONST_DOUBLE (r, operands[0]);
10893           assemble_real (r, GET_MODE (operands[0]), BITS_PER_WORD);
10894           break;
10895         }
10896       default:
10897         assemble_integer (operands[0], 8, BITS_PER_WORD, 1);
10898         break;
10899       }
10900     return \"\";
10901   }"
10902   [(set_attr "length" "8")
10903    (set_attr "type" "no_insn")]
10906 (define_insn "consttable_16"
10907   [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_16)]
10908   "TARGET_EITHER"
10909   "*
10910   {
10911     making_const_table = TRUE;
10912     switch (GET_MODE_CLASS (GET_MODE (operands[0])))
10913       {
10914        case MODE_FLOAT:
10915         {
10916           REAL_VALUE_TYPE r;
10917           REAL_VALUE_FROM_CONST_DOUBLE (r, operands[0]);
10918           assemble_real (r, GET_MODE (operands[0]), BITS_PER_WORD);
10919           break;
10920         }
10921       default:
10922         assemble_integer (operands[0], 16, BITS_PER_WORD, 1);
10923         break;
10924       }
10925     return \"\";
10926   }"
10927   [(set_attr "length" "16")
10928    (set_attr "type" "no_insn")]
10931 ;; V5 Instructions,
10933 (define_insn "clzsi2"
10934   [(set (match_operand:SI 0 "s_register_operand" "=r")
10935         (clz:SI (match_operand:SI 1 "s_register_operand" "r")))]
10936   "TARGET_32BIT && arm_arch5"
10937   "clz%?\\t%0, %1"
10938   [(set_attr "predicable" "yes")
10939    (set_attr "predicable_short_it" "no")
10940    (set_attr "type" "clz")])
10942 (define_insn "rbitsi2"
10943   [(set (match_operand:SI 0 "s_register_operand" "=r")
10944         (unspec:SI [(match_operand:SI 1 "s_register_operand" "r")] UNSPEC_RBIT))]
10945   "TARGET_32BIT && arm_arch_thumb2"
10946   "rbit%?\\t%0, %1"
10947   [(set_attr "predicable" "yes")
10948    (set_attr "predicable_short_it" "no")
10949    (set_attr "type" "clz")])
10951 (define_expand "ctzsi2"
10952  [(set (match_operand:SI           0 "s_register_operand" "")
10953        (ctz:SI (match_operand:SI  1 "s_register_operand" "")))]
10954   "TARGET_32BIT && arm_arch_thumb2"
10955   "
10956    {
10957      rtx tmp = gen_reg_rtx (SImode); 
10958      emit_insn (gen_rbitsi2 (tmp, operands[1]));
10959      emit_insn (gen_clzsi2 (operands[0], tmp));
10960    }
10961    DONE;
10962   "
10965 ;; V5E instructions.
10967 (define_insn "prefetch"
10968   [(prefetch (match_operand:SI 0 "address_operand" "p")
10969              (match_operand:SI 1 "" "")
10970              (match_operand:SI 2 "" ""))]
10971   "TARGET_32BIT && arm_arch5e"
10972   "pld\\t%a0"
10973   [(set_attr "type" "load1")]
10976 ;; General predication pattern
10978 (define_cond_exec
10979   [(match_operator 0 "arm_comparison_operator"
10980     [(match_operand 1 "cc_register" "")
10981      (const_int 0)])]
10982   "TARGET_32BIT
10983    && (!TARGET_NO_VOLATILE_CE || !volatile_refs_p (PATTERN (insn)))"
10984   ""
10985 [(set_attr "predicated" "yes")]
10988 (define_insn "force_register_use"
10989   [(unspec:SI [(match_operand:SI 0 "register_operand" "")] UNSPEC_REGISTER_USE)]
10990   ""
10991   "%@ %0 needed"
10992   [(set_attr "length" "0")
10993    (set_attr "type" "no_insn")]
10997 ;; Patterns for exception handling
10999 (define_expand "eh_return"
11000   [(use (match_operand 0 "general_operand" ""))]
11001   "TARGET_EITHER"
11002   "
11003   {
11004     if (TARGET_32BIT)
11005       emit_insn (gen_arm_eh_return (operands[0]));
11006     else
11007       emit_insn (gen_thumb_eh_return (operands[0]));
11008     DONE;
11009   }"
11011                                    
11012 ;; We can't expand this before we know where the link register is stored.
11013 (define_insn_and_split "arm_eh_return"
11014   [(unspec_volatile [(match_operand:SI 0 "s_register_operand" "r")]
11015                     VUNSPEC_EH_RETURN)
11016    (clobber (match_scratch:SI 1 "=&r"))]
11017   "TARGET_ARM"
11018   "#"
11019   "&& reload_completed"
11020   [(const_int 0)]
11021   "
11022   {
11023     arm_set_return_address (operands[0], operands[1]);
11024     DONE;
11025   }"
11029 ;; TLS support
11031 (define_insn "load_tp_hard"
11032   [(set (match_operand:SI 0 "register_operand" "=r")
11033         (unspec:SI [(const_int 0)] UNSPEC_TLS))]
11034   "TARGET_HARD_TP"
11035   "mrc%?\\tp15, 0, %0, c13, c0, 3\\t@ load_tp_hard"
11036   [(set_attr "predicable" "yes")
11037    (set_attr "type" "mrs")]
11040 ;; Doesn't clobber R1-R3.  Must use r0 for the first operand.
11041 (define_insn "load_tp_soft"
11042   [(set (reg:SI 0) (unspec:SI [(const_int 0)] UNSPEC_TLS))
11043    (clobber (reg:SI LR_REGNUM))
11044    (clobber (reg:SI IP_REGNUM))
11045    (clobber (reg:CC CC_REGNUM))]
11046   "TARGET_SOFT_TP"
11047   "bl\\t__aeabi_read_tp\\t@ load_tp_soft"
11048   [(set_attr "conds" "clob")
11049    (set_attr "type" "branch")]
11052 ;; tls descriptor call
11053 (define_insn "tlscall"
11054   [(set (reg:SI R0_REGNUM)
11055         (unspec:SI [(reg:SI R0_REGNUM)
11056                     (match_operand:SI 0 "" "X")
11057                     (match_operand 1 "" "")] UNSPEC_TLS))
11058    (clobber (reg:SI R1_REGNUM))
11059    (clobber (reg:SI LR_REGNUM))
11060    (clobber (reg:SI CC_REGNUM))]
11061   "TARGET_GNU2_TLS"
11062   {
11063     targetm.asm_out.internal_label (asm_out_file, "LPIC",
11064                                     INTVAL (operands[1]));
11065     return "bl\\t%c0(tlscall)";
11066   }
11067   [(set_attr "conds" "clob")
11068    (set_attr "length" "4")
11069    (set_attr "type" "branch")]
11072 ;; For thread pointer builtin
11073 (define_expand "get_thread_pointersi"
11074   [(match_operand:SI 0 "s_register_operand" "=r")]
11075  ""
11078    arm_load_tp (operands[0]);
11079    DONE;
11080  }")
11084 ;; We only care about the lower 16 bits of the constant 
11085 ;; being inserted into the upper 16 bits of the register.
11086 (define_insn "*arm_movtas_ze" 
11087   [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r")
11088                    (const_int 16)
11089                    (const_int 16))
11090         (match_operand:SI 1 "const_int_operand" ""))]
11091   "arm_arch_thumb2"
11092   "movt%?\t%0, %L1"
11093  [(set_attr "predicable" "yes")
11094   (set_attr "predicable_short_it" "no")
11095   (set_attr "length" "4")
11096   (set_attr "type" "alu_sreg")]
11099 (define_insn "*arm_rev"
11100   [(set (match_operand:SI 0 "s_register_operand" "=l,l,r")
11101         (bswap:SI (match_operand:SI 1 "s_register_operand" "l,l,r")))]
11102   "arm_arch6"
11103   "@
11104    rev\t%0, %1
11105    rev%?\t%0, %1
11106    rev%?\t%0, %1"
11107   [(set_attr "arch" "t1,t2,32")
11108    (set_attr "length" "2,2,4")
11109    (set_attr "predicable" "no,yes,yes")
11110    (set_attr "predicable_short_it" "no")
11111    (set_attr "type" "rev")]
11114 (define_expand "arm_legacy_rev"
11115   [(set (match_operand:SI 2 "s_register_operand" "")
11116         (xor:SI (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
11117                              (const_int 16))
11118                 (match_dup 1)))
11119    (set (match_dup 2)
11120         (lshiftrt:SI (match_dup 2)
11121                      (const_int 8)))
11122    (set (match_operand:SI 3 "s_register_operand" "")
11123         (rotatert:SI (match_dup 1)
11124                      (const_int 8)))
11125    (set (match_dup 2)
11126         (and:SI (match_dup 2)
11127                 (const_int -65281)))
11128    (set (match_operand:SI 0 "s_register_operand" "")
11129         (xor:SI (match_dup 3)
11130                 (match_dup 2)))]
11131   "TARGET_32BIT"
11132   ""
11135 ;; Reuse temporaries to keep register pressure down.
11136 (define_expand "thumb_legacy_rev"
11137   [(set (match_operand:SI 2 "s_register_operand" "")
11138      (ashift:SI (match_operand:SI 1 "s_register_operand" "")
11139                 (const_int 24)))
11140    (set (match_operand:SI 3 "s_register_operand" "")
11141      (lshiftrt:SI (match_dup 1)
11142                   (const_int 24)))
11143    (set (match_dup 3)
11144      (ior:SI (match_dup 3)
11145              (match_dup 2)))
11146    (set (match_operand:SI 4 "s_register_operand" "")
11147      (const_int 16))
11148    (set (match_operand:SI 5 "s_register_operand" "")
11149      (rotatert:SI (match_dup 1)
11150                   (match_dup 4)))
11151    (set (match_dup 2)
11152      (ashift:SI (match_dup 5)
11153                 (const_int 24)))
11154    (set (match_dup 5)
11155      (lshiftrt:SI (match_dup 5)
11156                   (const_int 24)))
11157    (set (match_dup 5)
11158      (ior:SI (match_dup 5)
11159              (match_dup 2)))
11160    (set (match_dup 5)
11161      (rotatert:SI (match_dup 5)
11162                   (match_dup 4)))
11163    (set (match_operand:SI 0 "s_register_operand" "")
11164      (ior:SI (match_dup 5)
11165              (match_dup 3)))]
11166   "TARGET_THUMB"
11167   ""
11170 ;; ARM-specific expansion of signed mod by power of 2
11171 ;; using conditional negate.
11172 ;; For r0 % n where n is a power of 2 produce:
11173 ;; rsbs    r1, r0, #0
11174 ;; and     r0, r0, #(n - 1)
11175 ;; and     r1, r1, #(n - 1)
11176 ;; rsbpl   r0, r1, #0
11178 (define_expand "modsi3"
11179   [(match_operand:SI 0 "register_operand" "")
11180    (match_operand:SI 1 "register_operand" "")
11181    (match_operand:SI 2 "const_int_operand" "")]
11182   "TARGET_32BIT"
11183   {
11184     HOST_WIDE_INT val = INTVAL (operands[2]);
11186     if (val <= 0
11187        || exact_log2 (val) <= 0)
11188       FAIL;
11190     rtx mask = GEN_INT (val - 1);
11192     /* In the special case of x0 % 2 we can do the even shorter:
11193         cmp     r0, #0
11194         and     r0, r0, #1
11195         rsblt   r0, r0, #0.  */
11197     if (val == 2)
11198       {
11199         rtx cc_reg = arm_gen_compare_reg (LT,
11200                                           operands[1], const0_rtx, NULL_RTX);
11201         rtx cond = gen_rtx_LT (SImode, cc_reg, const0_rtx);
11202         rtx masked = gen_reg_rtx (SImode);
11204         emit_insn (gen_andsi3 (masked, operands[1], mask));
11205         emit_move_insn (operands[0],
11206                         gen_rtx_IF_THEN_ELSE (SImode, cond,
11207                                               gen_rtx_NEG (SImode,
11208                                                            masked),
11209                                               masked));
11210         DONE;
11211       }
11213     rtx neg_op = gen_reg_rtx (SImode);
11214     rtx_insn *insn = emit_insn (gen_subsi3_compare0 (neg_op, const0_rtx,
11215                                                       operands[1]));
11217     /* Extract the condition register and mode.  */
11218     rtx cmp = XVECEXP (PATTERN (insn), 0, 0);
11219     rtx cc_reg = SET_DEST (cmp);
11220     rtx cond = gen_rtx_GE (SImode, cc_reg, const0_rtx);
11222     emit_insn (gen_andsi3 (operands[0], operands[1], mask));
11224     rtx masked_neg = gen_reg_rtx (SImode);
11225     emit_insn (gen_andsi3 (masked_neg, neg_op, mask));
11227     /* We want a conditional negate here, but emitting COND_EXEC rtxes
11228        during expand does not always work.  Do an IF_THEN_ELSE instead.  */
11229     emit_move_insn (operands[0],
11230                     gen_rtx_IF_THEN_ELSE (SImode, cond,
11231                                           gen_rtx_NEG (SImode, masked_neg),
11232                                           operands[0]));
11235     DONE;
11236   }
11239 (define_expand "bswapsi2"
11240   [(set (match_operand:SI 0 "s_register_operand" "=r")
11241         (bswap:SI (match_operand:SI 1 "s_register_operand" "r")))]
11242 "TARGET_EITHER && (arm_arch6 || !optimize_size)"
11244     if (!arm_arch6)
11245       {
11246         rtx op2 = gen_reg_rtx (SImode);
11247         rtx op3 = gen_reg_rtx (SImode);
11249         if (TARGET_THUMB)
11250           {
11251             rtx op4 = gen_reg_rtx (SImode);
11252             rtx op5 = gen_reg_rtx (SImode);
11254             emit_insn (gen_thumb_legacy_rev (operands[0], operands[1],
11255                                              op2, op3, op4, op5));
11256           }
11257         else
11258           {
11259             emit_insn (gen_arm_legacy_rev (operands[0], operands[1],
11260                                            op2, op3));
11261           }
11263         DONE;
11264       }
11265   "
11268 ;; bswap16 patterns: use revsh and rev16 instructions for the signed
11269 ;; and unsigned variants, respectively. For rev16, expose
11270 ;; byte-swapping in the lower 16 bits only.
11271 (define_insn "*arm_revsh"
11272   [(set (match_operand:SI 0 "s_register_operand" "=l,l,r")
11273         (sign_extend:SI (bswap:HI (match_operand:HI 1 "s_register_operand" "l,l,r"))))]
11274   "arm_arch6"
11275   "@
11276   revsh\t%0, %1
11277   revsh%?\t%0, %1
11278   revsh%?\t%0, %1"
11279   [(set_attr "arch" "t1,t2,32")
11280    (set_attr "length" "2,2,4")
11281    (set_attr "type" "rev")]
11284 (define_insn "*arm_rev16"
11285   [(set (match_operand:HI 0 "s_register_operand" "=l,l,r")
11286         (bswap:HI (match_operand:HI 1 "s_register_operand" "l,l,r")))]
11287   "arm_arch6"
11288   "@
11289    rev16\t%0, %1
11290    rev16%?\t%0, %1
11291    rev16%?\t%0, %1"
11292   [(set_attr "arch" "t1,t2,32")
11293    (set_attr "length" "2,2,4")
11294    (set_attr "type" "rev")]
11297 ;; There are no canonicalisation rules for the position of the lshiftrt, ashift
11298 ;; operations within an IOR/AND RTX, therefore we have two patterns matching
11299 ;; each valid permutation.
11301 (define_insn "arm_rev16si2"
11302   [(set (match_operand:SI 0 "register_operand" "=l,l,r")
11303         (ior:SI (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "l,l,r")
11304                                    (const_int 8))
11305                         (match_operand:SI 3 "const_int_operand" "n,n,n"))
11306                 (and:SI (lshiftrt:SI (match_dup 1)
11307                                      (const_int 8))
11308                         (match_operand:SI 2 "const_int_operand" "n,n,n"))))]
11309   "arm_arch6
11310    && aarch_rev16_shleft_mask_imm_p (operands[3], SImode)
11311    && aarch_rev16_shright_mask_imm_p (operands[2], SImode)"
11312   "rev16\\t%0, %1"
11313   [(set_attr "arch" "t1,t2,32")
11314    (set_attr "length" "2,2,4")
11315    (set_attr "type" "rev")]
11318 (define_insn "arm_rev16si2_alt"
11319   [(set (match_operand:SI 0 "register_operand" "=l,l,r")
11320         (ior:SI (and:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "l,l,r")
11321                                      (const_int 8))
11322                         (match_operand:SI 2 "const_int_operand" "n,n,n"))
11323                 (and:SI (ashift:SI (match_dup 1)
11324                                    (const_int 8))
11325                         (match_operand:SI 3 "const_int_operand" "n,n,n"))))]
11326   "arm_arch6
11327    && aarch_rev16_shleft_mask_imm_p (operands[3], SImode)
11328    && aarch_rev16_shright_mask_imm_p (operands[2], SImode)"
11329   "rev16\\t%0, %1"
11330   [(set_attr "arch" "t1,t2,32")
11331    (set_attr "length" "2,2,4")
11332    (set_attr "type" "rev")]
11335 (define_expand "bswaphi2"
11336   [(set (match_operand:HI 0 "s_register_operand" "=r")
11337         (bswap:HI (match_operand:HI 1 "s_register_operand" "r")))]
11338 "arm_arch6"
11342 ;; Patterns for LDRD/STRD in Thumb2 mode
11344 (define_insn "*thumb2_ldrd"
11345   [(set (match_operand:SI 0 "s_register_operand" "=r")
11346         (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "rk")
11347                          (match_operand:SI 2 "ldrd_strd_offset_operand" "Do"))))
11348    (set (match_operand:SI 3 "s_register_operand" "=r")
11349         (mem:SI (plus:SI (match_dup 1)
11350                          (match_operand:SI 4 "const_int_operand" ""))))]
11351   "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11352      && current_tune->prefer_ldrd_strd
11353      && ((INTVAL (operands[2]) + 4) == INTVAL (operands[4]))
11354      && (operands_ok_ldrd_strd (operands[0], operands[3],
11355                                   operands[1], INTVAL (operands[2]),
11356                                   false, true))"
11357   "ldrd%?\t%0, %3, [%1, %2]"
11358   [(set_attr "type" "load2")
11359    (set_attr "predicable" "yes")
11360    (set_attr "predicable_short_it" "no")])
11362 (define_insn "*thumb2_ldrd_base"
11363   [(set (match_operand:SI 0 "s_register_operand" "=r")
11364         (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
11365    (set (match_operand:SI 2 "s_register_operand" "=r")
11366         (mem:SI (plus:SI (match_dup 1)
11367                          (const_int 4))))]
11368   "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11369      && current_tune->prefer_ldrd_strd
11370      && (operands_ok_ldrd_strd (operands[0], operands[2],
11371                                   operands[1], 0, false, true))"
11372   "ldrd%?\t%0, %2, [%1]"
11373   [(set_attr "type" "load2")
11374    (set_attr "predicable" "yes")
11375    (set_attr "predicable_short_it" "no")])
11377 (define_insn "*thumb2_ldrd_base_neg"
11378   [(set (match_operand:SI 0 "s_register_operand" "=r")
11379         (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "rk")
11380                          (const_int -4))))
11381    (set (match_operand:SI 2 "s_register_operand" "=r")
11382         (mem:SI (match_dup 1)))]
11383   "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11384      && current_tune->prefer_ldrd_strd
11385      && (operands_ok_ldrd_strd (operands[0], operands[2],
11386                                   operands[1], -4, false, true))"
11387   "ldrd%?\t%0, %2, [%1, #-4]"
11388   [(set_attr "type" "load2")
11389    (set_attr "predicable" "yes")
11390    (set_attr "predicable_short_it" "no")])
11392 (define_insn "*thumb2_strd"
11393   [(set (mem:SI (plus:SI (match_operand:SI 0 "s_register_operand" "rk")
11394                          (match_operand:SI 1 "ldrd_strd_offset_operand" "Do")))
11395         (match_operand:SI 2 "s_register_operand" "r"))
11396    (set (mem:SI (plus:SI (match_dup 0)
11397                          (match_operand:SI 3 "const_int_operand" "")))
11398         (match_operand:SI 4 "s_register_operand" "r"))]
11399   "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11400      && current_tune->prefer_ldrd_strd
11401      && ((INTVAL (operands[1]) + 4) == INTVAL (operands[3]))
11402      && (operands_ok_ldrd_strd (operands[2], operands[4],
11403                                   operands[0], INTVAL (operands[1]),
11404                                   false, false))"
11405   "strd%?\t%2, %4, [%0, %1]"
11406   [(set_attr "type" "store2")
11407    (set_attr "predicable" "yes")
11408    (set_attr "predicable_short_it" "no")])
11410 (define_insn "*thumb2_strd_base"
11411   [(set (mem:SI (match_operand:SI 0 "s_register_operand" "rk"))
11412         (match_operand:SI 1 "s_register_operand" "r"))
11413    (set (mem:SI (plus:SI (match_dup 0)
11414                          (const_int 4)))
11415         (match_operand:SI 2 "s_register_operand" "r"))]
11416   "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11417      && current_tune->prefer_ldrd_strd
11418      && (operands_ok_ldrd_strd (operands[1], operands[2],
11419                                   operands[0], 0, false, false))"
11420   "strd%?\t%1, %2, [%0]"
11421   [(set_attr "type" "store2")
11422    (set_attr "predicable" "yes")
11423    (set_attr "predicable_short_it" "no")])
11425 (define_insn "*thumb2_strd_base_neg"
11426   [(set (mem:SI (plus:SI (match_operand:SI 0 "s_register_operand" "rk")
11427                          (const_int -4)))
11428         (match_operand:SI 1 "s_register_operand" "r"))
11429    (set (mem:SI (match_dup 0))
11430         (match_operand:SI 2 "s_register_operand" "r"))]
11431   "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11432      && current_tune->prefer_ldrd_strd
11433      && (operands_ok_ldrd_strd (operands[1], operands[2],
11434                                   operands[0], -4, false, false))"
11435   "strd%?\t%1, %2, [%0, #-4]"
11436   [(set_attr "type" "store2")
11437    (set_attr "predicable" "yes")
11438    (set_attr "predicable_short_it" "no")])
11440 ;; ARMv8 CRC32 instructions.
11441 (define_insn "<crc_variant>"
11442   [(set (match_operand:SI 0 "s_register_operand" "=r")
11443         (unspec:SI [(match_operand:SI 1 "s_register_operand" "r")
11444                     (match_operand:<crc_mode> 2 "s_register_operand" "r")]
11445          CRC))]
11446   "TARGET_CRC32"
11447   "<crc_variant>\\t%0, %1, %2"
11448   [(set_attr "type" "crc")
11449    (set_attr "conds" "unconditional")]
11452 ;; Load the load/store double peephole optimizations.
11453 (include "ldrdstrd.md")
11455 ;; Load the load/store multiple patterns
11456 (include "ldmstm.md")
11458 ;; Patterns in ldmstm.md don't cover more than 4 registers. This pattern covers
11459 ;; large lists without explicit writeback generated for APCS_FRAME epilogue.
11460 (define_insn "*load_multiple"
11461   [(match_parallel 0 "load_multiple_operation"
11462     [(set (match_operand:SI 2 "s_register_operand" "=rk")
11463           (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
11464         ])]
11465   "TARGET_32BIT"
11466   "*
11467   {
11468     arm_output_multireg_pop (operands, /*return_pc=*/false,
11469                                        /*cond=*/const_true_rtx,
11470                                        /*reverse=*/false,
11471                                        /*update=*/false);
11472     return \"\";
11473   }
11474   "
11475   [(set_attr "predicable" "yes")]
11478 (define_expand "copysignsf3"
11479   [(match_operand:SF 0 "register_operand")
11480    (match_operand:SF 1 "register_operand")
11481    (match_operand:SF 2 "register_operand")]
11482   "TARGET_SOFT_FLOAT && arm_arch_thumb2"
11483   "{
11484      emit_move_insn (operands[0], operands[2]);
11485      emit_insn (gen_insv_t2 (simplify_gen_subreg (SImode, operands[0], SFmode, 0),
11486                 GEN_INT (31), GEN_INT (0),
11487                 simplify_gen_subreg (SImode, operands[1], SFmode, 0)));
11488      DONE;
11489   }"
11492 (define_expand "copysigndf3"
11493   [(match_operand:DF 0 "register_operand")
11494    (match_operand:DF 1 "register_operand")
11495    (match_operand:DF 2 "register_operand")]
11496   "TARGET_SOFT_FLOAT && arm_arch_thumb2"
11497   "{
11498      rtx op0_low = gen_lowpart (SImode, operands[0]);
11499      rtx op0_high = gen_highpart (SImode, operands[0]);
11500      rtx op1_low = gen_lowpart (SImode, operands[1]);
11501      rtx op1_high = gen_highpart (SImode, operands[1]);
11502      rtx op2_high = gen_highpart (SImode, operands[2]);
11504      rtx scratch1 = gen_reg_rtx (SImode);
11505      rtx scratch2 = gen_reg_rtx (SImode);
11506      emit_move_insn (scratch1, op2_high);
11507      emit_move_insn (scratch2, op1_high);
11509      emit_insn(gen_rtx_SET(scratch1,
11510                            gen_rtx_LSHIFTRT (SImode, op2_high, GEN_INT(31))));
11511      emit_insn(gen_insv_t2(scratch2, GEN_INT(1), GEN_INT(31), scratch1));
11512      emit_move_insn (op0_low, op1_low);
11513      emit_move_insn (op0_high, scratch2);
11515      DONE;
11516   }"
11519 ;; Vector bits common to IWMMXT and Neon
11520 (include "vec-common.md")
11521 ;; Load the Intel Wireless Multimedia Extension patterns
11522 (include "iwmmxt.md")
11523 ;; Load the VFP co-processor patterns
11524 (include "vfp.md")
11525 ;; Thumb-1 patterns
11526 (include "thumb1.md")
11527 ;; Thumb-2 patterns
11528 (include "thumb2.md")
11529 ;; Neon patterns
11530 (include "neon.md")
11531 ;; Crypto patterns
11532 (include "crypto.md")
11533 ;; Synchronization Primitives
11534 (include "sync.md")
11535 ;; Fixed-point patterns
11536 (include "arm-fixed.md")