Merge branches/gcc-4_9-branch rev 225109.
[official-gcc.git] / gcc-4_9-branch / gcc / config / arm / arm.md
blobfd5024dc917a60e47ffcc4ad9d7e2370c1e74a71
1 ;;- Machine description for ARM for GNU compiler
2 ;;  Copyright (C) 1991-2014 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.
25 ;; Beware of splitting Thumb1 patterns that output multiple
26 ;; assembly instructions, in particular instruction such as SBC and
27 ;; ADC which consume flags.  For example, in the pattern thumb_subdi3
28 ;; below, the output SUB implicitly sets the flags (assembled to SUBS)
29 ;; and then the Carry flag is used by SBC to compute the correct
30 ;; result.  If we split thumb_subdi3 pattern into two separate RTL
31 ;; insns (using define_insn_and_split), the scheduler might place
32 ;; other RTL insns between SUB and SBC, possibly modifying the Carry
33 ;; flag used by SBC.  This might happen because most Thumb1 patterns
34 ;; for flag-setting instructions do not have explicit RTL for setting
35 ;; or clobbering the flags.  Instead, they have the attribute "conds"
36 ;; with value "set" or "clob".  However, this attribute is not used to
37 ;; identify dependencies and therefore the scheduler might reorder
38 ;; these instruction.  Currenly, this problem cannot happen because
39 ;; there are no separate Thumb1 patterns for individual instruction
40 ;; that consume flags (except conditional execution, which is treated
41 ;; differently).  In particular there is no Thumb1 armv6-m pattern for
42 ;; sbc or adc.
45 ;;---------------------------------------------------------------------------
46 ;; Constants
48 ;; Register numbers -- All machine registers should be defined here
49 (define_constants
50   [(R0_REGNUM         0)        ; First CORE register
51    (R1_REGNUM         1)        ; Second CORE register
52    (IP_REGNUM        12)        ; Scratch register
53    (SP_REGNUM        13)        ; Stack pointer
54    (LR_REGNUM        14)        ; Return address register
55    (PC_REGNUM        15)        ; Program counter
56    (LAST_ARM_REGNUM  15)        ;
57    (CC_REGNUM       100)        ; Condition code pseudo register
58    (VFPCC_REGNUM    101)        ; VFP Condition code pseudo register
59   ]
61 ;; 3rd operand to select_dominance_cc_mode
62 (define_constants
63   [(DOM_CC_X_AND_Y  0)
64    (DOM_CC_NX_OR_Y  1)
65    (DOM_CC_X_OR_Y   2)
66   ]
68 ;; conditional compare combination
69 (define_constants
70   [(CMP_CMP 0)
71    (CMN_CMP 1)
72    (CMP_CMN 2)
73    (CMN_CMN 3)
74    (NUM_OF_COND_CMP 4)
75   ]
79 ;;---------------------------------------------------------------------------
80 ;; Attributes
82 ;; Processor type.  This is created automatically from arm-cores.def.
83 (include "arm-tune.md")
85 ;; Instruction classification types
86 (include "types.md")
88 ; IS_THUMB is set to 'yes' when we are generating Thumb code, and 'no' when
89 ; generating ARM code.  This is used to control the length of some insn
90 ; patterns that share the same RTL in both ARM and Thumb code.
91 (define_attr "is_thumb" "no,yes" (const (symbol_ref "thumb_code")))
93 ; IS_ARCH6 is set to 'yes' when we are generating code form ARMv6.
94 (define_attr "is_arch6" "no,yes" (const (symbol_ref "arm_arch6")))
96 ; IS_THUMB1 is set to 'yes' iff we are generating Thumb-1 code.
97 (define_attr "is_thumb1" "no,yes" (const (symbol_ref "thumb1_code")))
99 ; We use this attribute to disable alternatives that can produce 32-bit
100 ; instructions inside an IT-block in Thumb2 state.  ARMv8 deprecates IT blocks
101 ; that contain 32-bit instructions.
102 (define_attr "enabled_for_depr_it" "no,yes" (const_string "yes"))
104 ; This attribute is used to disable a predicated alternative when we have
105 ; arm_restrict_it.
106 (define_attr "predicable_short_it" "no,yes" (const_string "yes"))
108 ;; Operand number of an input operand that is shifted.  Zero if the
109 ;; given instruction does not shift one of its input operands.
110 (define_attr "shift" "" (const_int 0))
112 ;; [For compatibility with AArch64 in pipeline models]
113 ;; Attribute that specifies whether or not the instruction touches fp
114 ;; registers.
115 (define_attr "fp" "no,yes" (const_string "no"))
117 ; Floating Point Unit.  If we only have floating point emulation, then there
118 ; is no point in scheduling the floating point insns.  (Well, for best
119 ; performance we should try and group them together).
120 (define_attr "fpu" "none,vfp"
121   (const (symbol_ref "arm_fpu_attr")))
123 (define_attr "predicated" "yes,no" (const_string "no"))
125 ; LENGTH of an instruction (in bytes)
126 (define_attr "length" ""
127   (const_int 4))
129 ; The architecture which supports the instruction (or alternative).
130 ; This can be "a" for ARM, "t" for either of the Thumbs, "32" for
131 ; TARGET_32BIT, "t1" or "t2" to specify a specific Thumb mode.  "v6"
132 ; for ARM or Thumb-2 with arm_arch6, and nov6 for ARM without
133 ; arm_arch6.  "v6t2" for Thumb-2 with arm_arch6.  This attribute is
134 ; used to compute attribute "enabled", use type "any" to enable an
135 ; alternative in all cases.
136 (define_attr "arch" "any,a,t,32,t1,t2,v6,nov6,v6t2,neon_for_64bits,avoid_neon_for_64bits,iwmmxt,iwmmxt2"
137   (const_string "any"))
139 (define_attr "arch_enabled" "no,yes"
140   (cond [(eq_attr "arch" "any")
141          (const_string "yes")
143          (and (eq_attr "arch" "a")
144               (match_test "TARGET_ARM"))
145          (const_string "yes")
147          (and (eq_attr "arch" "t")
148               (match_test "TARGET_THUMB"))
149          (const_string "yes")
151          (and (eq_attr "arch" "t1")
152               (match_test "TARGET_THUMB1"))
153          (const_string "yes")
155          (and (eq_attr "arch" "t2")
156               (match_test "TARGET_THUMB2"))
157          (const_string "yes")
159          (and (eq_attr "arch" "32")
160               (match_test "TARGET_32BIT"))
161          (const_string "yes")
163          (and (eq_attr "arch" "v6")
164               (match_test "TARGET_32BIT && arm_arch6"))
165          (const_string "yes")
167          (and (eq_attr "arch" "nov6")
168               (match_test "TARGET_32BIT && !arm_arch6"))
169          (const_string "yes")
171          (and (eq_attr "arch" "v6t2")
172               (match_test "TARGET_32BIT && arm_arch6 && arm_arch_thumb2"))
173          (const_string "yes")
175          (and (eq_attr "arch" "avoid_neon_for_64bits")
176               (match_test "TARGET_NEON")
177               (not (match_test "TARGET_PREFER_NEON_64BITS")))
178          (const_string "yes")
180          (and (eq_attr "arch" "neon_for_64bits")
181               (match_test "TARGET_NEON")
182               (match_test "TARGET_PREFER_NEON_64BITS"))
183          (const_string "yes")
185          (and (eq_attr "arch" "iwmmxt2")
186               (match_test "TARGET_REALLY_IWMMXT2"))
187          (const_string "yes")]
189         (const_string "no")))
191 (define_attr "opt" "any,speed,size"
192   (const_string "any"))
194 (define_attr "opt_enabled" "no,yes"
195   (cond [(eq_attr "opt" "any")
196          (const_string "yes")
198          (and (eq_attr "opt" "speed")
199               (match_test "optimize_function_for_speed_p (cfun)"))
200          (const_string "yes")
202          (and (eq_attr "opt" "size")
203               (match_test "optimize_function_for_size_p (cfun)"))
204          (const_string "yes")]
205         (const_string "no")))
207 (define_attr "use_literal_pool" "no,yes"
208    (cond [(and (eq_attr "type" "f_loads,f_loadd")
209                (match_test "CONSTANT_P (operands[1])"))
210           (const_string "yes")]
211          (const_string "no")))
213 ; Enable all alternatives that are both arch_enabled and insn_enabled.
214  (define_attr "enabled" "no,yes"
215    (cond [(and (eq_attr "predicable_short_it" "no")
216                (and (eq_attr "predicated" "yes")
217                     (match_test "arm_restrict_it")))
218           (const_string "no")
220           (and (eq_attr "enabled_for_depr_it" "no")
221                (match_test "arm_restrict_it"))
222           (const_string "no")
224           (and (eq_attr "use_literal_pool" "yes")
225                (match_test "arm_disable_literal_pool"))
226           (const_string "no")
228           (eq_attr "arch_enabled" "no")
229           (const_string "no")
231           (eq_attr "opt_enabled" "no")
232           (const_string "no")]
233          (const_string "yes")))
235 ; POOL_RANGE is how far away from a constant pool entry that this insn
236 ; can be placed.  If the distance is zero, then this insn will never
237 ; reference the pool.
238 ; Note that for Thumb constant pools the PC value is rounded down to the
239 ; nearest multiple of four.  Therefore, THUMB2_POOL_RANGE (and POOL_RANGE for
240 ; Thumb insns) should be set to <max_range> - 2.
241 ; NEG_POOL_RANGE is nonzero for insns that can reference a constant pool entry
242 ; before its address.  It is set to <max_range> - (8 + <data_size>).
243 (define_attr "arm_pool_range" "" (const_int 0))
244 (define_attr "thumb2_pool_range" "" (const_int 0))
245 (define_attr "arm_neg_pool_range" "" (const_int 0))
246 (define_attr "thumb2_neg_pool_range" "" (const_int 0))
248 (define_attr "pool_range" ""
249   (cond [(eq_attr "is_thumb" "yes") (attr "thumb2_pool_range")]
250         (attr "arm_pool_range")))
251 (define_attr "neg_pool_range" ""
252   (cond [(eq_attr "is_thumb" "yes") (attr "thumb2_neg_pool_range")]
253         (attr "arm_neg_pool_range")))
255 ; An assembler sequence may clobber the condition codes without us knowing.
256 ; If such an insn references the pool, then we have no way of knowing how,
257 ; so use the most conservative value for pool_range.
258 (define_asm_attributes
259  [(set_attr "conds" "clob")
260   (set_attr "length" "4")
261   (set_attr "pool_range" "250")])
263 ; Load scheduling, set from the arm_ld_sched variable
264 ; initialized by arm_option_override()
265 (define_attr "ldsched" "no,yes" (const (symbol_ref "arm_ld_sched")))
267 ; condition codes: this one is used by final_prescan_insn to speed up
268 ; conditionalizing instructions.  It saves having to scan the rtl to see if
269 ; it uses or alters the condition codes.
271 ; USE means that the condition codes are used by the insn in the process of
272 ;   outputting code, this means (at present) that we can't use the insn in
273 ;   inlined branches
275 ; SET means that the purpose of the insn is to set the condition codes in a
276 ;   well defined manner.
278 ; CLOB means that the condition codes are altered in an undefined manner, if
279 ;   they are altered at all
281 ; UNCONDITIONAL means the instruction can not be conditionally executed and
282 ;   that the instruction does not use or alter the condition codes.
284 ; NOCOND means that the instruction does not use or alter the condition
285 ;   codes but can be converted into a conditionally exectuted instruction.
287 (define_attr "conds" "use,set,clob,unconditional,nocond"
288         (if_then_else
289          (ior (eq_attr "is_thumb1" "yes")
290               (eq_attr "type" "call"))
291          (const_string "clob")
292          (if_then_else (eq_attr "is_neon_type" "no")
293          (const_string "nocond")
294          (const_string "unconditional"))))
296 ; Predicable means that the insn can be conditionally executed based on
297 ; an automatically added predicate (additional patterns are generated by 
298 ; gen...).  We default to 'no' because no Thumb patterns match this rule
299 ; and not all ARM patterns do.
300 (define_attr "predicable" "no,yes" (const_string "no"))
302 ; Only model the write buffer for ARM6 and ARM7.  Earlier processors don't
303 ; have one.  Later ones, such as StrongARM, have write-back caches, so don't
304 ; suffer blockages enough to warrant modelling this (and it can adversely
305 ; affect the schedule).
306 (define_attr "model_wbuf" "no,yes" (const (symbol_ref "arm_tune_wbuf")))
308 ; WRITE_CONFLICT implies that a read following an unrelated write is likely
309 ; to stall the processor.  Used with model_wbuf above.
310 (define_attr "write_conflict" "no,yes"
311   (if_then_else (eq_attr "type"
312                  "block,call,load1")
313                 (const_string "yes")
314                 (const_string "no")))
316 ; Classify the insns into those that take one cycle and those that take more
317 ; than one on the main cpu execution unit.
318 (define_attr "core_cycles" "single,multi"
319   (if_then_else (eq_attr "type"
320     "adc_imm, adc_reg, adcs_imm, adcs_reg, adr, alu_ext, alu_imm, alu_reg,\
321     alu_shift_imm, alu_shift_reg, alus_ext, alus_imm, alus_reg,\
322     alus_shift_imm, alus_shift_reg, bfm, csel, rev, logic_imm, logic_reg,\
323     logic_shift_imm, logic_shift_reg, logics_imm, logics_reg,\
324     logics_shift_imm, logics_shift_reg, extend, shift_imm, float, fcsel,\
325     wmmx_wor, wmmx_wxor, wmmx_wand, wmmx_wandn, wmmx_wmov, wmmx_tmcrr,\
326     wmmx_tmrrc, wmmx_wldr, wmmx_wstr, wmmx_tmcr, wmmx_tmrc, wmmx_wadd,\
327     wmmx_wsub, wmmx_wmul, wmmx_wmac, wmmx_wavg2, wmmx_tinsr, wmmx_textrm,\
328     wmmx_wshufh, wmmx_wcmpeq, wmmx_wcmpgt, wmmx_wmax, wmmx_wmin, wmmx_wpack,\
329     wmmx_wunpckih, wmmx_wunpckil, wmmx_wunpckeh, wmmx_wunpckel, wmmx_wror,\
330     wmmx_wsra, wmmx_wsrl, wmmx_wsll, wmmx_wmadd, wmmx_tmia, wmmx_tmiaph,\
331     wmmx_tmiaxy, wmmx_tbcst, wmmx_tmovmsk, wmmx_wacc, wmmx_waligni,\
332     wmmx_walignr, wmmx_tandc, wmmx_textrc, wmmx_torc, wmmx_torvsc, wmmx_wsad,\
333     wmmx_wabs, wmmx_wabsdiff, wmmx_waddsubhx, wmmx_wsubaddhx, wmmx_wavg4,\
334     wmmx_wmulw, wmmx_wqmulm, wmmx_wqmulwm, wmmx_waddbhus, wmmx_wqmiaxy,\
335     wmmx_wmiaxy, wmmx_wmiawxy, wmmx_wmerge")
336                 (const_string "single")
337                 (const_string "multi")))
339 ;; FAR_JUMP is "yes" if a BL instruction is used to generate a branch to a
340 ;; distant label.  Only applicable to Thumb code.
341 (define_attr "far_jump" "yes,no" (const_string "no"))
344 ;; The number of machine instructions this pattern expands to.
345 ;; Used for Thumb-2 conditional execution.
346 (define_attr "ce_count" "" (const_int 1))
348 ;;---------------------------------------------------------------------------
349 ;; Unspecs
351 (include "unspecs.md")
353 ;;---------------------------------------------------------------------------
354 ;; Mode iterators
356 (include "iterators.md")
358 ;;---------------------------------------------------------------------------
359 ;; Predicates
361 (include "predicates.md")
362 (include "constraints.md")
364 ;;---------------------------------------------------------------------------
365 ;; Pipeline descriptions
367 (define_attr "tune_cortexr4" "yes,no"
368   (const (if_then_else
369           (eq_attr "tune" "cortexr4,cortexr4f,cortexr5")
370           (const_string "yes")
371           (const_string "no"))))
373 ;; True if the generic scheduling description should be used.
375 (define_attr "generic_sched" "yes,no"
376   (const (if_then_else
377           (ior (eq_attr "tune" "fa526,fa626,fa606te,fa626te,fmp626,fa726te,\
378                                 arm926ejs,arm1020e,arm1026ejs,arm1136js,\
379                                 arm1136jfs,cortexa5,cortexa7,cortexa8,\
380                                 cortexa9,cortexa12,cortexa15,cortexa17,\
381                                 cortexa53,cortexa57,cortexm4,cortexm7,\
382                                 marvell_pj4,xgene1")
383                (eq_attr "tune_cortexr4" "yes"))
384           (const_string "no")
385           (const_string "yes"))))
387 (define_attr "generic_vfp" "yes,no"
388   (const (if_then_else
389           (and (eq_attr "fpu" "vfp")
390                (eq_attr "tune" "!arm1020e,arm1022e,cortexa5,cortexa7,\
391                                 cortexa8,cortexa9,cortexa53,cortexm4,\
392                                 cortexm7,marvell_pj4,xgene1")
393                (eq_attr "tune_cortexr4" "no"))
394           (const_string "yes")
395           (const_string "no"))))
397 (include "marvell-f-iwmmxt.md")
398 (include "arm-generic.md")
399 (include "arm926ejs.md")
400 (include "arm1020e.md")
401 (include "arm1026ejs.md")
402 (include "arm1136jfs.md")
403 (include "fa526.md")
404 (include "fa606te.md")
405 (include "fa626te.md")
406 (include "fmp626.md")
407 (include "fa726te.md")
408 (include "cortex-a5.md")
409 (include "cortex-a7.md")
410 (include "cortex-a8.md")
411 (include "cortex-a9.md")
412 (include "cortex-a15.md")
413 (include "cortex-a17.md")
414 (include "cortex-a53.md")
415 (include "cortex-a57.md")
416 (include "cortex-r4.md")
417 (include "cortex-r4f.md")
418 (include "cortex-m7.md")
419 (include "cortex-m4.md")
420 (include "cortex-m4-fpu.md")
421 (include "vfp11.md")
422 (include "marvell-pj4.md")
423 (include "xgene1.md")
426 ;;---------------------------------------------------------------------------
427 ;; Insn patterns
429 ;; Addition insns.
431 ;; Note: For DImode insns, there is normally no reason why operands should
432 ;; not be in the same register, what we don't want is for something being
433 ;; written to partially overlap something that is an input.
435 (define_expand "adddi3"
436  [(parallel
437    [(set (match_operand:DI           0 "s_register_operand" "")
438           (plus:DI (match_operand:DI 1 "s_register_operand" "")
439                    (match_operand:DI 2 "arm_adddi_operand"  "")))
440     (clobber (reg:CC CC_REGNUM))])]
441   "TARGET_EITHER"
442   "
443   if (TARGET_THUMB1)
444     {
445       if (!REG_P (operands[1]))
446         operands[1] = force_reg (DImode, operands[1]);
447       if (!REG_P (operands[2]))
448         operands[2] = force_reg (DImode, operands[2]);
449      }
450   "
453 (define_insn "*thumb1_adddi3"
454   [(set (match_operand:DI          0 "register_operand" "=l")
455         (plus:DI (match_operand:DI 1 "register_operand" "%0")
456                  (match_operand:DI 2 "register_operand" "l")))
457    (clobber (reg:CC CC_REGNUM))
458   ]
459   "TARGET_THUMB1"
460   "add\\t%Q0, %Q0, %Q2\;adc\\t%R0, %R0, %R2"
461   [(set_attr "length" "4")
462    (set_attr "type" "multiple")]
465 (define_insn_and_split "*arm_adddi3"
466   [(set (match_operand:DI          0 "s_register_operand" "=&r,&r,&r,&r,&r")
467         (plus:DI (match_operand:DI 1 "s_register_operand" "%0, 0, r, 0, r")
468                  (match_operand:DI 2 "arm_adddi_operand"  "r,  0, r, Dd, Dd")))
469    (clobber (reg:CC CC_REGNUM))]
470   "TARGET_32BIT && !TARGET_NEON"
471   "#"
472   "TARGET_32BIT && reload_completed
473    && ! (TARGET_NEON && IS_VFP_REGNUM (REGNO (operands[0])))"
474   [(parallel [(set (reg:CC_C CC_REGNUM)
475                    (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
476                                  (match_dup 1)))
477               (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
478    (set (match_dup 3) (plus:SI (plus:SI (match_dup 4) (match_dup 5))
479                                (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
480   "
481   {
482     operands[3] = gen_highpart (SImode, operands[0]);
483     operands[0] = gen_lowpart (SImode, operands[0]);
484     operands[4] = gen_highpart (SImode, operands[1]);
485     operands[1] = gen_lowpart (SImode, operands[1]);
486     operands[5] = gen_highpart_mode (SImode, DImode, operands[2]);
487     operands[2] = gen_lowpart (SImode, operands[2]);
488   }"
489   [(set_attr "conds" "clob")
490    (set_attr "length" "8")
491    (set_attr "type" "multiple")]
494 (define_insn_and_split "*adddi_sesidi_di"
495   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
496         (plus:DI (sign_extend:DI
497                   (match_operand:SI 2 "s_register_operand" "r,r"))
498                  (match_operand:DI 1 "s_register_operand" "0,r")))
499    (clobber (reg:CC CC_REGNUM))]
500   "TARGET_32BIT"
501   "#"
502   "TARGET_32BIT && reload_completed"
503   [(parallel [(set (reg:CC_C CC_REGNUM)
504                    (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
505                                  (match_dup 1)))
506               (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
507    (set (match_dup 3) (plus:SI (plus:SI (ashiftrt:SI (match_dup 2)
508                                                      (const_int 31))
509                                         (match_dup 4))
510                                (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
511   "
512   {
513     operands[3] = gen_highpart (SImode, operands[0]);
514     operands[0] = gen_lowpart (SImode, operands[0]);
515     operands[4] = gen_highpart (SImode, operands[1]);
516     operands[1] = gen_lowpart (SImode, operands[1]);
517     operands[2] = gen_lowpart (SImode, operands[2]);
518   }"
519   [(set_attr "conds" "clob")
520    (set_attr "length" "8")
521    (set_attr "type" "multiple")]
524 (define_insn_and_split "*adddi_zesidi_di"
525   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
526         (plus:DI (zero_extend:DI
527                   (match_operand:SI 2 "s_register_operand" "r,r"))
528                  (match_operand:DI 1 "s_register_operand" "0,r")))
529    (clobber (reg:CC CC_REGNUM))]
530   "TARGET_32BIT"
531   "#"
532   "TARGET_32BIT && reload_completed"
533   [(parallel [(set (reg:CC_C CC_REGNUM)
534                    (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
535                                  (match_dup 1)))
536               (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
537    (set (match_dup 3) (plus:SI (plus:SI (match_dup 4) (const_int 0))
538                                (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
539   "
540   {
541     operands[3] = gen_highpart (SImode, operands[0]);
542     operands[0] = gen_lowpart (SImode, operands[0]);
543     operands[4] = gen_highpart (SImode, operands[1]);
544     operands[1] = gen_lowpart (SImode, operands[1]);
545     operands[2] = gen_lowpart (SImode, operands[2]);
546   }"
547   [(set_attr "conds" "clob")
548    (set_attr "length" "8")
549    (set_attr "type" "multiple")]
552 (define_expand "addsi3"
553   [(set (match_operand:SI          0 "s_register_operand" "")
554         (plus:SI (match_operand:SI 1 "s_register_operand" "")
555                  (match_operand:SI 2 "reg_or_int_operand" "")))]
556   "TARGET_EITHER"
557   "
558   if (TARGET_32BIT && CONST_INT_P (operands[2]))
559     {
560       arm_split_constant (PLUS, SImode, NULL_RTX,
561                           INTVAL (operands[2]), operands[0], operands[1],
562                           optimize && can_create_pseudo_p ());
563       DONE;
564     }
565   "
568 ; If there is a scratch available, this will be faster than synthesizing the
569 ; addition.
570 (define_peephole2
571   [(match_scratch:SI 3 "r")
572    (set (match_operand:SI          0 "arm_general_register_operand" "")
573         (plus:SI (match_operand:SI 1 "arm_general_register_operand" "")
574                  (match_operand:SI 2 "const_int_operand"  "")))]
575   "TARGET_32BIT &&
576    !(const_ok_for_arm (INTVAL (operands[2]))
577      || const_ok_for_arm (-INTVAL (operands[2])))
578     && const_ok_for_arm (~INTVAL (operands[2]))"
579   [(set (match_dup 3) (match_dup 2))
580    (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 3)))]
581   ""
584 ;; The r/r/k alternative is required when reloading the address
585 ;;  (plus (reg rN) (reg sp)) into (reg rN).  In this case reload will
586 ;; put the duplicated register first, and not try the commutative version.
587 (define_insn_and_split "*arm_addsi3"
588   [(set (match_operand:SI          0 "s_register_operand" "=rk,l,l ,l ,r ,k ,r,r ,k ,r ,k,k,r ,k ,r")
589         (plus:SI (match_operand:SI 1 "s_register_operand" "%0 ,l,0 ,l ,rk,k ,r,rk,k ,rk,k,r,rk,k ,rk")
590                  (match_operand:SI 2 "reg_or_int_operand" "rk ,l,Py,Pd,rI,rI,k,Pj,Pj,L ,L,L,PJ,PJ,?n")))]
591   "TARGET_32BIT"
592   "@
593    add%?\\t%0, %0, %2
594    add%?\\t%0, %1, %2
595    add%?\\t%0, %1, %2
596    add%?\\t%0, %1, %2
597    add%?\\t%0, %1, %2
598    add%?\\t%0, %1, %2
599    add%?\\t%0, %2, %1
600    addw%?\\t%0, %1, %2
601    addw%?\\t%0, %1, %2
602    sub%?\\t%0, %1, #%n2
603    sub%?\\t%0, %1, #%n2
604    sub%?\\t%0, %1, #%n2
605    subw%?\\t%0, %1, #%n2
606    subw%?\\t%0, %1, #%n2
607    #"
608   "TARGET_32BIT
609    && CONST_INT_P (operands[2])
610    && !const_ok_for_op (INTVAL (operands[2]), PLUS)
611    && (reload_completed || !arm_eliminable_register (operands[1]))"
612   [(clobber (const_int 0))]
613   "
614   arm_split_constant (PLUS, SImode, curr_insn,
615                       INTVAL (operands[2]), operands[0],
616                       operands[1], 0);
617   DONE;
618   "
619   [(set_attr "length" "2,4,4,4,4,4,4,4,4,4,4,4,4,4,16")
620    (set_attr "predicable" "yes")
621    (set_attr "predicable_short_it" "yes,yes,yes,yes,no,no,no,no,no,no,no,no,no,no,no")
622    (set_attr "arch" "t2,t2,t2,t2,*,*,*,t2,t2,*,*,a,t2,t2,*")
623    (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
624                       (const_string "alu_imm")
625                       (const_string "alu_reg")))
629 (define_insn_and_split "*thumb1_addsi3"
630   [(set (match_operand:SI          0 "register_operand" "=l,l,l,*rk,*hk,l,k,l,l,l")
631         (plus:SI (match_operand:SI 1 "register_operand" "%0,0,l,*0,*0,k,k,0,l,k")
632                  (match_operand:SI 2 "nonmemory_operand" "I,J,lL,*hk,*rk,M,O,Pa,Pb,Pc")))]
633   "TARGET_THUMB1"
634   "*
635    static const char * const asms[] = 
636    {
637      \"add\\t%0, %0, %2\",
638      \"sub\\t%0, %0, #%n2\",
639      \"add\\t%0, %1, %2\",
640      \"add\\t%0, %0, %2\",
641      \"add\\t%0, %0, %2\",
642      \"add\\t%0, %1, %2\",
643      \"add\\t%0, %1, %2\",
644      \"#\",
645      \"#\",
646      \"#\"
647    };
648    if ((which_alternative == 2 || which_alternative == 6)
649        && CONST_INT_P (operands[2])
650        && INTVAL (operands[2]) < 0)
651      return \"sub\\t%0, %1, #%n2\";
652    return asms[which_alternative];
653   "
654   "&& reload_completed && CONST_INT_P (operands[2])
655    && ((operands[1] != stack_pointer_rtx
656         && (INTVAL (operands[2]) > 255 || INTVAL (operands[2]) < -255))
657        || (operands[1] == stack_pointer_rtx
658            && INTVAL (operands[2]) > 1020))"
659   [(set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))
660    (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 3)))]
661   {
662     HOST_WIDE_INT offset = INTVAL (operands[2]);
663     if (operands[1] == stack_pointer_rtx)
664       offset -= 1020;
665     else
666       {
667         if (offset > 255)
668           offset = 255;
669         else if (offset < -255)
670           offset = -255;
671       }
672     operands[3] = GEN_INT (offset);
673     operands[2] = GEN_INT (INTVAL (operands[2]) - offset);
674   }
675   [(set_attr "length" "2,2,2,2,2,2,2,4,4,4")
676    (set_attr "type" "alus_imm,alus_imm,alus_reg,alus_reg,alus_reg,
677                      alus_reg,alus_reg,multiple,multiple,multiple")]
680 ;; Reloading and elimination of the frame pointer can
681 ;; sometimes cause this optimization to be missed.
682 (define_peephole2
683   [(set (match_operand:SI 0 "arm_general_register_operand" "")
684         (match_operand:SI 1 "const_int_operand" ""))
685    (set (match_dup 0)
686         (plus:SI (match_dup 0) (reg:SI SP_REGNUM)))]
687   "TARGET_THUMB1
688    && (unsigned HOST_WIDE_INT) (INTVAL (operands[1])) < 1024
689    && (INTVAL (operands[1]) & 3) == 0"
690   [(set (match_dup 0) (plus:SI (reg:SI SP_REGNUM) (match_dup 1)))]
691   ""
694 (define_insn "addsi3_compare0"
695   [(set (reg:CC_NOOV CC_REGNUM)
696         (compare:CC_NOOV
697          (plus:SI (match_operand:SI 1 "s_register_operand" "r, r,r")
698                   (match_operand:SI 2 "arm_add_operand"    "I,L,r"))
699          (const_int 0)))
700    (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
701         (plus:SI (match_dup 1) (match_dup 2)))]
702   "TARGET_ARM"
703   "@
704    add%.\\t%0, %1, %2
705    sub%.\\t%0, %1, #%n2
706    add%.\\t%0, %1, %2"
707   [(set_attr "conds" "set")
708    (set_attr "type" "alus_imm,alus_imm,alus_reg")]
711 (define_insn "*addsi3_compare0_scratch"
712   [(set (reg:CC_NOOV CC_REGNUM)
713         (compare:CC_NOOV
714          (plus:SI (match_operand:SI 0 "s_register_operand" "r, r, r")
715                   (match_operand:SI 1 "arm_add_operand"    "I,L, r"))
716          (const_int 0)))]
717   "TARGET_ARM"
718   "@
719    cmn%?\\t%0, %1
720    cmp%?\\t%0, #%n1
721    cmn%?\\t%0, %1"
722   [(set_attr "conds" "set")
723    (set_attr "predicable" "yes")
724    (set_attr "type" "alus_imm,alus_imm,alus_reg")]
727 (define_insn "*compare_negsi_si"
728   [(set (reg:CC_Z CC_REGNUM)
729         (compare:CC_Z
730          (neg:SI (match_operand:SI 0 "s_register_operand" "l,r"))
731          (match_operand:SI 1 "s_register_operand" "l,r")))]
732   "TARGET_32BIT"
733   "cmn%?\\t%1, %0"
734   [(set_attr "conds" "set")
735    (set_attr "predicable" "yes")
736    (set_attr "arch" "t2,*")
737    (set_attr "length" "2,4")
738    (set_attr "predicable_short_it" "yes,no")
739    (set_attr "type" "alus_reg")]
742 ;; This is the canonicalization of addsi3_compare0_for_combiner when the
743 ;; addend is a constant.
744 (define_insn "cmpsi2_addneg"
745   [(set (reg:CC CC_REGNUM)
746         (compare:CC
747          (match_operand:SI 1 "s_register_operand" "r,r")
748          (match_operand:SI 2 "arm_addimm_operand" "L,I")))
749    (set (match_operand:SI 0 "s_register_operand" "=r,r")
750         (plus:SI (match_dup 1)
751                  (match_operand:SI 3 "arm_addimm_operand" "I,L")))]
752   "TARGET_32BIT && INTVAL (operands[2]) == -INTVAL (operands[3])"
753   "@
754    add%.\\t%0, %1, %3
755    sub%.\\t%0, %1, #%n3"
756   [(set_attr "conds" "set")
757    (set_attr "type" "alus_reg")]
760 ;; Convert the sequence
761 ;;  sub  rd, rn, #1
762 ;;  cmn  rd, #1 (equivalent to cmp rd, #-1)
763 ;;  bne  dest
764 ;; into
765 ;;  subs rd, rn, #1
766 ;;  bcs  dest   ((unsigned)rn >= 1)
767 ;; similarly for the beq variant using bcc.
768 ;; This is a common looping idiom (while (n--))
769 (define_peephole2
770   [(set (match_operand:SI 0 "arm_general_register_operand" "")
771         (plus:SI (match_operand:SI 1 "arm_general_register_operand" "")
772                  (const_int -1)))
773    (set (match_operand 2 "cc_register" "")
774         (compare (match_dup 0) (const_int -1)))
775    (set (pc)
776         (if_then_else (match_operator 3 "equality_operator"
777                        [(match_dup 2) (const_int 0)])
778                       (match_operand 4 "" "")
779                       (match_operand 5 "" "")))]
780   "TARGET_32BIT && peep2_reg_dead_p (3, operands[2])"
781   [(parallel[
782     (set (match_dup 2)
783          (compare:CC
784           (match_dup 1) (const_int 1)))
785     (set (match_dup 0) (plus:SI (match_dup 1) (const_int -1)))])
786    (set (pc)
787         (if_then_else (match_op_dup 3 [(match_dup 2) (const_int 0)])
788                       (match_dup 4)
789                       (match_dup 5)))]
790   "operands[2] = gen_rtx_REG (CCmode, CC_REGNUM);
791    operands[3] = gen_rtx_fmt_ee ((GET_CODE (operands[3]) == NE
792                                   ? GEU : LTU),
793                                  VOIDmode, 
794                                  operands[2], const0_rtx);"
797 ;; The next four insns work because they compare the result with one of
798 ;; the operands, and we know that the use of the condition code is
799 ;; either GEU or LTU, so we can use the carry flag from the addition
800 ;; instead of doing the compare a second time.
801 (define_insn "*addsi3_compare_op1"
802   [(set (reg:CC_C CC_REGNUM)
803         (compare:CC_C
804          (plus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
805                   (match_operand:SI 2 "arm_add_operand" "I,L,r"))
806          (match_dup 1)))
807    (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
808         (plus:SI (match_dup 1) (match_dup 2)))]
809   "TARGET_32BIT"
810   "@
811    add%.\\t%0, %1, %2
812    sub%.\\t%0, %1, #%n2
813    add%.\\t%0, %1, %2"
814   [(set_attr "conds" "set")
815    (set_attr "type"  "alus_imm,alus_imm,alus_reg")]
818 (define_insn "*addsi3_compare_op2"
819   [(set (reg:CC_C CC_REGNUM)
820         (compare:CC_C
821          (plus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
822                   (match_operand:SI 2 "arm_add_operand" "I,L,r"))
823          (match_dup 2)))
824    (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
825         (plus:SI (match_dup 1) (match_dup 2)))]
826   "TARGET_32BIT"
827   "@
828    add%.\\t%0, %1, %2
829    add%.\\t%0, %1, %2
830    sub%.\\t%0, %1, #%n2"
831   [(set_attr "conds" "set")
832    (set_attr "type" "alus_imm,alus_imm,alus_reg")]
835 (define_insn "*compare_addsi2_op0"
836   [(set (reg:CC_C CC_REGNUM)
837         (compare:CC_C
838           (plus:SI (match_operand:SI 0 "s_register_operand" "l,l,r,r,r")
839                    (match_operand:SI 1 "arm_add_operand" "Pv,l,I,L,r"))
840           (match_dup 0)))]
841   "TARGET_32BIT"
842   "@
843    cmp%?\\t%0, #%n1
844    cmn%?\\t%0, %1
845    cmn%?\\t%0, %1
846    cmp%?\\t%0, #%n1
847    cmn%?\\t%0, %1"
848   [(set_attr "conds" "set")
849    (set_attr "predicable" "yes")
850    (set_attr "arch" "t2,t2,*,*,*")
851    (set_attr "predicable_short_it" "yes,yes,no,no,no")
852    (set_attr "length" "2,2,4,4,4")
853    (set_attr "type" "alus_imm,alus_reg,alus_imm,alus_imm,alus_reg")]
856 (define_insn "*compare_addsi2_op1"
857   [(set (reg:CC_C CC_REGNUM)
858         (compare:CC_C
859           (plus:SI (match_operand:SI 0 "s_register_operand" "l,l,r,r,r")
860                    (match_operand:SI 1 "arm_add_operand" "Pv,l,I,L,r"))
861           (match_dup 1)))]
862   "TARGET_32BIT"
863   "@
864    cmp%?\\t%0, #%n1
865    cmn%?\\t%0, %1
866    cmn%?\\t%0, %1
867    cmp%?\\t%0, #%n1
868    cmn%?\\t%0, %1"
869   [(set_attr "conds" "set")
870    (set_attr "predicable" "yes")
871    (set_attr "arch" "t2,t2,*,*,*")
872    (set_attr "predicable_short_it" "yes,yes,no,no,no")
873    (set_attr "length" "2,2,4,4,4")
874    (set_attr "type" "alus_imm,alus_reg,alus_imm,alus_imm,alus_reg")]
877 (define_insn "*addsi3_carryin_<optab>"
878   [(set (match_operand:SI 0 "s_register_operand" "=l,r,r")
879         (plus:SI (plus:SI (match_operand:SI 1 "s_register_operand" "%l,r,r")
880                           (match_operand:SI 2 "arm_not_operand" "0,rI,K"))
881                  (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))))]
882   "TARGET_32BIT"
883   "@
884    adc%?\\t%0, %1, %2
885    adc%?\\t%0, %1, %2
886    sbc%?\\t%0, %1, #%B2"
887   [(set_attr "conds" "use")
888    (set_attr "predicable" "yes")
889    (set_attr "arch" "t2,*,*")
890    (set_attr "length" "4")
891    (set_attr "predicable_short_it" "yes,no,no")
892    (set_attr "type" "adc_reg,adc_reg,adc_imm")]
895 (define_insn "*addsi3_carryin_alt2_<optab>"
896   [(set (match_operand:SI 0 "s_register_operand" "=l,r,r")
897         (plus:SI (plus:SI (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))
898                           (match_operand:SI 1 "s_register_operand" "%l,r,r"))
899                  (match_operand:SI 2 "arm_rhs_operand" "l,rI,K")))]
900   "TARGET_32BIT"
901   "@
902    adc%?\\t%0, %1, %2
903    adc%?\\t%0, %1, %2
904    sbc%?\\t%0, %1, #%B2"
905   [(set_attr "conds" "use")
906    (set_attr "predicable" "yes")
907    (set_attr "arch" "t2,*,*")
908    (set_attr "length" "4")
909    (set_attr "predicable_short_it" "yes,no,no")
910    (set_attr "type" "adc_reg,adc_reg,adc_imm")]
913 (define_insn "*addsi3_carryin_shift_<optab>"
914   [(set (match_operand:SI 0 "s_register_operand" "=r")
915         (plus:SI (plus:SI
916                   (match_operator:SI 2 "shift_operator"
917                     [(match_operand:SI 3 "s_register_operand" "r")
918                      (match_operand:SI 4 "reg_or_int_operand" "rM")])
919                   (match_operand:SI 1 "s_register_operand" "r"))
920                  (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))))]
921   "TARGET_32BIT"
922   "adc%?\\t%0, %1, %3%S2"
923   [(set_attr "conds" "use")
924    (set_attr "predicable" "yes")
925    (set_attr "predicable_short_it" "no")
926    (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
927                       (const_string "alu_shift_imm")
928                       (const_string "alu_shift_reg")))]
931 (define_insn "*addsi3_carryin_clobercc_<optab>"
932   [(set (match_operand:SI 0 "s_register_operand" "=r")
933         (plus:SI (plus:SI (match_operand:SI 1 "s_register_operand" "%r")
934                           (match_operand:SI 2 "arm_rhs_operand" "rI"))
935                  (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))))
936    (clobber (reg:CC CC_REGNUM))]
937    "TARGET_32BIT"
938    "adc%.\\t%0, %1, %2"
939    [(set_attr "conds" "set")
940     (set_attr "type" "adcs_reg")]
943 (define_insn "*subsi3_carryin"
944   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
945         (minus:SI (minus:SI (match_operand:SI 1 "reg_or_int_operand" "r,I")
946                             (match_operand:SI 2 "s_register_operand" "r,r"))
947                   (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
948   "TARGET_32BIT"
949   "@
950    sbc%?\\t%0, %1, %2
951    rsc%?\\t%0, %2, %1"
952   [(set_attr "conds" "use")
953    (set_attr "arch" "*,a")
954    (set_attr "predicable" "yes")
955    (set_attr "predicable_short_it" "no")
956    (set_attr "type" "adc_reg,adc_imm")]
959 (define_insn "*subsi3_carryin_const"
960   [(set (match_operand:SI 0 "s_register_operand" "=r")
961         (minus:SI (plus:SI (match_operand:SI 1 "reg_or_int_operand" "r")
962                            (match_operand:SI 2 "arm_not_operand" "K"))
963                   (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
964   "TARGET_32BIT"
965   "sbc\\t%0, %1, #%B2"
966   [(set_attr "conds" "use")
967    (set_attr "type" "adc_imm")]
970 (define_insn "*subsi3_carryin_compare"
971   [(set (reg:CC CC_REGNUM)
972         (compare:CC (match_operand:SI 1 "s_register_operand" "r")
973                     (match_operand:SI 2 "s_register_operand" "r")))
974    (set (match_operand:SI 0 "s_register_operand" "=r")
975         (minus:SI (minus:SI (match_dup 1)
976                             (match_dup 2))
977                   (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
978   "TARGET_32BIT"
979   "sbcs\\t%0, %1, %2"
980   [(set_attr "conds" "set")
981    (set_attr "type" "adcs_reg")]
984 (define_insn "*subsi3_carryin_compare_const"
985   [(set (reg:CC CC_REGNUM)
986         (compare:CC (match_operand:SI 1 "reg_or_int_operand" "r")
987                     (match_operand:SI 2 "arm_not_operand" "K")))
988    (set (match_operand:SI 0 "s_register_operand" "=r")
989         (minus:SI (plus:SI (match_dup 1)
990                            (match_dup 2))
991                   (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
992   "TARGET_32BIT"
993   "sbcs\\t%0, %1, #%B2"
994   [(set_attr "conds" "set")
995    (set_attr "type" "adcs_imm")]
998 (define_insn "*subsi3_carryin_shift"
999   [(set (match_operand:SI 0 "s_register_operand" "=r")
1000         (minus:SI (minus:SI
1001                   (match_operand:SI 1 "s_register_operand" "r")
1002                   (match_operator:SI 2 "shift_operator"
1003                    [(match_operand:SI 3 "s_register_operand" "r")
1004                     (match_operand:SI 4 "reg_or_int_operand" "rM")]))
1005                  (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1006   "TARGET_32BIT"
1007   "sbc%?\\t%0, %1, %3%S2"
1008   [(set_attr "conds" "use")
1009    (set_attr "predicable" "yes")
1010    (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
1011                       (const_string "alu_shift_imm")
1012                      (const_string "alu_shift_reg")))]
1015 (define_insn "*rsbsi3_carryin_shift"
1016   [(set (match_operand:SI 0 "s_register_operand" "=r")
1017         (minus:SI (minus:SI
1018                   (match_operator:SI 2 "shift_operator"
1019                    [(match_operand:SI 3 "s_register_operand" "r")
1020                     (match_operand:SI 4 "reg_or_int_operand" "rM")])
1021                    (match_operand:SI 1 "s_register_operand" "r"))
1022                  (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1023   "TARGET_ARM"
1024   "rsc%?\\t%0, %1, %3%S2"
1025   [(set_attr "conds" "use")
1026    (set_attr "predicable" "yes")
1027    (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
1028                       (const_string "alu_shift_imm")
1029                       (const_string "alu_shift_reg")))]
1032 ; transform ((x << y) - 1) to ~(~(x-1) << y)  Where X is a constant.
1033 (define_split
1034   [(set (match_operand:SI 0 "s_register_operand" "")
1035         (plus:SI (ashift:SI (match_operand:SI 1 "const_int_operand" "")
1036                             (match_operand:SI 2 "s_register_operand" ""))
1037                  (const_int -1)))
1038    (clobber (match_operand:SI 3 "s_register_operand" ""))]
1039   "TARGET_32BIT"
1040   [(set (match_dup 3) (match_dup 1))
1041    (set (match_dup 0) (not:SI (ashift:SI (match_dup 3) (match_dup 2))))]
1042   "
1043   operands[1] = GEN_INT (~(INTVAL (operands[1]) - 1));
1046 (define_expand "addsf3"
1047   [(set (match_operand:SF          0 "s_register_operand" "")
1048         (plus:SF (match_operand:SF 1 "s_register_operand" "")
1049                  (match_operand:SF 2 "s_register_operand" "")))]
1050   "TARGET_32BIT && TARGET_HARD_FLOAT"
1051   "
1054 (define_expand "adddf3"
1055   [(set (match_operand:DF          0 "s_register_operand" "")
1056         (plus:DF (match_operand:DF 1 "s_register_operand" "")
1057                  (match_operand:DF 2 "s_register_operand" "")))]
1058   "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
1059   "
1062 (define_expand "subdi3"
1063  [(parallel
1064    [(set (match_operand:DI            0 "s_register_operand" "")
1065           (minus:DI (match_operand:DI 1 "s_register_operand" "")
1066                     (match_operand:DI 2 "s_register_operand" "")))
1067     (clobber (reg:CC CC_REGNUM))])]
1068   "TARGET_EITHER"
1069   "
1070   if (TARGET_THUMB1)
1071     {
1072       if (!REG_P (operands[1]))
1073         operands[1] = force_reg (DImode, operands[1]);
1074       if (!REG_P (operands[2]))
1075         operands[2] = force_reg (DImode, operands[2]);
1076      }  
1077   "
1080 (define_insn_and_split "*arm_subdi3"
1081   [(set (match_operand:DI           0 "s_register_operand" "=&r,&r,&r")
1082         (minus:DI (match_operand:DI 1 "s_register_operand" "0,r,0")
1083                   (match_operand:DI 2 "s_register_operand" "r,0,0")))
1084    (clobber (reg:CC CC_REGNUM))]
1085   "TARGET_32BIT && !TARGET_NEON"
1086   "#"  ; "subs\\t%Q0, %Q1, %Q2\;sbc\\t%R0, %R1, %R2"
1087   "&& reload_completed"
1088   [(parallel [(set (reg:CC CC_REGNUM)
1089                    (compare:CC (match_dup 1) (match_dup 2)))
1090               (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1091    (set (match_dup 3) (minus:SI (minus:SI (match_dup 4) (match_dup 5))
1092                                (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1093   {
1094     operands[3] = gen_highpart (SImode, operands[0]);
1095     operands[0] = gen_lowpart (SImode, operands[0]);
1096     operands[4] = gen_highpart (SImode, operands[1]);
1097     operands[1] = gen_lowpart (SImode, operands[1]);
1098     operands[5] = gen_highpart (SImode, operands[2]);
1099     operands[2] = gen_lowpart (SImode, operands[2]);
1100    }
1101   [(set_attr "conds" "clob")
1102    (set_attr "length" "8")
1103    (set_attr "type" "multiple")]
1106 (define_insn "*thumb_subdi3"
1107   [(set (match_operand:DI           0 "register_operand" "=l")
1108         (minus:DI (match_operand:DI 1 "register_operand"  "0")
1109                   (match_operand:DI 2 "register_operand"  "l")))
1110    (clobber (reg:CC CC_REGNUM))]
1111   "TARGET_THUMB1"
1112   "sub\\t%Q0, %Q0, %Q2\;sbc\\t%R0, %R0, %R2"
1113   [(set_attr "length" "4")
1114    (set_attr "type" "multiple")]
1117 (define_insn_and_split "*subdi_di_zesidi"
1118   [(set (match_operand:DI           0 "s_register_operand" "=&r,&r")
1119         (minus:DI (match_operand:DI 1 "s_register_operand"  "0,r")
1120                   (zero_extend:DI
1121                    (match_operand:SI 2 "s_register_operand"  "r,r"))))
1122    (clobber (reg:CC CC_REGNUM))]
1123   "TARGET_32BIT"
1124   "#"   ; "subs\\t%Q0, %Q1, %2\;sbc\\t%R0, %R1, #0"
1125   "&& reload_completed"
1126   [(parallel [(set (reg:CC CC_REGNUM)
1127                    (compare:CC (match_dup 1) (match_dup 2)))
1128               (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1129    (set (match_dup 3) (minus:SI (plus:SI (match_dup 4) (match_dup 5))
1130                                 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1131   {
1132     operands[3] = gen_highpart (SImode, operands[0]);
1133     operands[0] = gen_lowpart (SImode, operands[0]);
1134     operands[4] = gen_highpart (SImode, operands[1]);
1135     operands[1] = gen_lowpart (SImode, operands[1]);
1136     operands[5] = GEN_INT (~0);
1137    }
1138   [(set_attr "conds" "clob")
1139    (set_attr "length" "8")
1140    (set_attr "type" "multiple")]
1143 (define_insn_and_split "*subdi_di_sesidi"
1144   [(set (match_operand:DI            0 "s_register_operand" "=&r,&r")
1145         (minus:DI (match_operand:DI  1 "s_register_operand"  "0,r")
1146                   (sign_extend:DI
1147                    (match_operand:SI 2 "s_register_operand"  "r,r"))))
1148    (clobber (reg:CC CC_REGNUM))]
1149   "TARGET_32BIT"
1150   "#"   ; "subs\\t%Q0, %Q1, %2\;sbc\\t%R0, %R1, %2, asr #31"
1151   "&& reload_completed"
1152   [(parallel [(set (reg:CC CC_REGNUM)
1153                    (compare:CC (match_dup 1) (match_dup 2)))
1154               (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1155    (set (match_dup 3) (minus:SI (minus:SI (match_dup 4)
1156                                          (ashiftrt:SI (match_dup 2)
1157                                                       (const_int 31)))
1158                                 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1159   {
1160     operands[3] = gen_highpart (SImode, operands[0]);
1161     operands[0] = gen_lowpart (SImode, operands[0]);
1162     operands[4] = gen_highpart (SImode, operands[1]);
1163     operands[1] = gen_lowpart (SImode, operands[1]);
1164   }
1165   [(set_attr "conds" "clob")
1166    (set_attr "length" "8")
1167    (set_attr "type" "multiple")]
1170 (define_insn_and_split "*subdi_zesidi_di"
1171   [(set (match_operand:DI            0 "s_register_operand" "=&r,&r")
1172         (minus:DI (zero_extend:DI
1173                    (match_operand:SI 2 "s_register_operand"  "r,r"))
1174                   (match_operand:DI  1 "s_register_operand" "0,r")))
1175    (clobber (reg:CC CC_REGNUM))]
1176   "TARGET_ARM"
1177   "#"   ; "rsbs\\t%Q0, %Q1, %2\;rsc\\t%R0, %R1, #0"
1178         ; is equivalent to:
1179         ; "subs\\t%Q0, %2, %Q1\;rsc\\t%R0, %R1, #0"
1180   "&& reload_completed"
1181   [(parallel [(set (reg:CC CC_REGNUM)
1182                    (compare:CC (match_dup 2) (match_dup 1)))
1183               (set (match_dup 0) (minus:SI (match_dup 2) (match_dup 1)))])
1184    (set (match_dup 3) (minus:SI (minus:SI (const_int 0) (match_dup 4))
1185                                (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1186   {
1187     operands[3] = gen_highpart (SImode, operands[0]);
1188     operands[0] = gen_lowpart (SImode, operands[0]);
1189     operands[4] = gen_highpart (SImode, operands[1]);
1190     operands[1] = gen_lowpart (SImode, operands[1]);
1191   }
1192   [(set_attr "conds" "clob")
1193    (set_attr "length" "8")
1194    (set_attr "type" "multiple")]
1197 (define_insn_and_split "*subdi_sesidi_di"
1198   [(set (match_operand:DI            0 "s_register_operand" "=&r,&r")
1199         (minus:DI (sign_extend:DI
1200                    (match_operand:SI 2 "s_register_operand"   "r,r"))
1201                   (match_operand:DI  1 "s_register_operand"  "0,r")))
1202    (clobber (reg:CC CC_REGNUM))]
1203   "TARGET_ARM"
1204   "#"   ; "rsbs\\t%Q0, %Q1, %2\;rsc\\t%R0, %R1, %2, asr #31"
1205         ; is equivalent to:
1206         ; "subs\\t%Q0, %2, %Q1\;rsc\\t%R0, %R1, %2, asr #31"
1207   "&& reload_completed"
1208   [(parallel [(set (reg:CC CC_REGNUM)
1209                    (compare:CC (match_dup 2) (match_dup 1)))
1210               (set (match_dup 0) (minus:SI (match_dup 2) (match_dup 1)))])
1211    (set (match_dup 3) (minus:SI (minus:SI
1212                                 (ashiftrt:SI (match_dup 2)
1213                                              (const_int 31))
1214                                 (match_dup 4))
1215                                (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1216   {
1217     operands[3] = gen_highpart (SImode, operands[0]);
1218     operands[0] = gen_lowpart (SImode, operands[0]);
1219     operands[4] = gen_highpart (SImode, operands[1]);
1220     operands[1] = gen_lowpart (SImode, operands[1]);
1221   }
1222   [(set_attr "conds" "clob")
1223    (set_attr "length" "8")
1224    (set_attr "type" "multiple")]
1227 (define_insn_and_split "*subdi_zesidi_zesidi"
1228   [(set (match_operand:DI            0 "s_register_operand" "=r")
1229         (minus:DI (zero_extend:DI
1230                    (match_operand:SI 1 "s_register_operand"  "r"))
1231                   (zero_extend:DI
1232                    (match_operand:SI 2 "s_register_operand"  "r"))))
1233    (clobber (reg:CC CC_REGNUM))]
1234   "TARGET_32BIT"
1235   "#"   ; "subs\\t%Q0, %1, %2\;sbc\\t%R0, %1, %1"
1236   "&& reload_completed"
1237   [(parallel [(set (reg:CC CC_REGNUM)
1238                    (compare:CC (match_dup 1) (match_dup 2)))
1239               (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1240    (set (match_dup 3) (minus:SI (minus:SI (match_dup 1) (match_dup 1))
1241                                (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1242   {
1243        operands[3] = gen_highpart (SImode, operands[0]);
1244        operands[0] = gen_lowpart (SImode, operands[0]);
1245   }
1246   [(set_attr "conds" "clob")
1247    (set_attr "length" "8")
1248    (set_attr "type" "multiple")]
1251 (define_expand "subsi3"
1252   [(set (match_operand:SI           0 "s_register_operand" "")
1253         (minus:SI (match_operand:SI 1 "reg_or_int_operand" "")
1254                   (match_operand:SI 2 "s_register_operand" "")))]
1255   "TARGET_EITHER"
1256   "
1257   if (CONST_INT_P (operands[1]))
1258     {
1259       if (TARGET_32BIT)
1260         {
1261           arm_split_constant (MINUS, SImode, NULL_RTX,
1262                               INTVAL (operands[1]), operands[0],
1263                               operands[2], optimize && can_create_pseudo_p ());
1264           DONE;
1265         }
1266       else /* TARGET_THUMB1 */
1267         operands[1] = force_reg (SImode, operands[1]);
1268     }
1269   "
1272 (define_insn "thumb1_subsi3_insn"
1273   [(set (match_operand:SI           0 "register_operand" "=l")
1274         (minus:SI (match_operand:SI 1 "register_operand" "l")
1275                   (match_operand:SI 2 "reg_or_int_operand" "lPd")))]
1276   "TARGET_THUMB1"
1277   "sub\\t%0, %1, %2"
1278   [(set_attr "length" "2")
1279    (set_attr "conds" "set")
1280    (set_attr "type" "alus_reg")]
1283 ; ??? Check Thumb-2 split length
1284 (define_insn_and_split "*arm_subsi3_insn"
1285   [(set (match_operand:SI           0 "s_register_operand" "=l,l ,l ,l ,r ,r,r,rk,r")
1286         (minus:SI (match_operand:SI 1 "reg_or_int_operand" "l ,0 ,l ,Pz,rI,r,r,k ,?n")
1287                   (match_operand:SI 2 "reg_or_int_operand" "l ,Py,Pd,l ,r ,I,r,r ,r")))]
1288   "TARGET_32BIT"
1289   "@
1290    sub%?\\t%0, %1, %2
1291    sub%?\\t%0, %2
1292    sub%?\\t%0, %1, %2
1293    rsb%?\\t%0, %2, %1
1294    rsb%?\\t%0, %2, %1
1295    sub%?\\t%0, %1, %2
1296    sub%?\\t%0, %1, %2
1297    sub%?\\t%0, %1, %2
1298    #"
1299   "&& (CONST_INT_P (operands[1])
1300        && !const_ok_for_arm (INTVAL (operands[1])))"
1301   [(clobber (const_int 0))]
1302   "
1303   arm_split_constant (MINUS, SImode, curr_insn,
1304                       INTVAL (operands[1]), operands[0], operands[2], 0);
1305   DONE;
1306   "
1307   [(set_attr "length" "4,4,4,4,4,4,4,4,16")
1308    (set_attr "arch" "t2,t2,t2,t2,*,*,*,*,*")
1309    (set_attr "predicable" "yes")
1310    (set_attr "predicable_short_it" "yes,yes,yes,yes,no,no,no,no,no")
1311    (set_attr "type" "alu_reg,alu_reg,alu_reg,alu_reg,alu_imm,alu_imm,alu_reg,alu_reg,multiple")]
1314 (define_peephole2
1315   [(match_scratch:SI 3 "r")
1316    (set (match_operand:SI 0 "arm_general_register_operand" "")
1317         (minus:SI (match_operand:SI 1 "const_int_operand" "")
1318                   (match_operand:SI 2 "arm_general_register_operand" "")))]
1319   "TARGET_32BIT
1320    && !const_ok_for_arm (INTVAL (operands[1]))
1321    && const_ok_for_arm (~INTVAL (operands[1]))"
1322   [(set (match_dup 3) (match_dup 1))
1323    (set (match_dup 0) (minus:SI (match_dup 3) (match_dup 2)))]
1324   ""
1327 (define_insn "*subsi3_compare0"
1328   [(set (reg:CC_NOOV CC_REGNUM)
1329         (compare:CC_NOOV
1330          (minus:SI (match_operand:SI 1 "arm_rhs_operand" "r,r,I")
1331                    (match_operand:SI 2 "arm_rhs_operand" "I,r,r"))
1332          (const_int 0)))
1333    (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
1334         (minus:SI (match_dup 1) (match_dup 2)))]
1335   "TARGET_32BIT"
1336   "@
1337    sub%.\\t%0, %1, %2
1338    sub%.\\t%0, %1, %2
1339    rsb%.\\t%0, %2, %1"
1340   [(set_attr "conds" "set")
1341    (set_attr "type"  "alus_imm,alus_reg,alus_reg")]
1344 (define_insn "subsi3_compare"
1345   [(set (reg:CC CC_REGNUM)
1346         (compare:CC (match_operand:SI 1 "arm_rhs_operand" "r,r,I")
1347                     (match_operand:SI 2 "arm_rhs_operand" "I,r,r")))
1348    (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
1349         (minus:SI (match_dup 1) (match_dup 2)))]
1350   "TARGET_32BIT"
1351   "@
1352    sub%.\\t%0, %1, %2
1353    sub%.\\t%0, %1, %2
1354    rsb%.\\t%0, %2, %1"
1355   [(set_attr "conds" "set")
1356    (set_attr "type" "alus_imm,alus_reg,alus_reg")]
1359 (define_expand "subsf3"
1360   [(set (match_operand:SF           0 "s_register_operand" "")
1361         (minus:SF (match_operand:SF 1 "s_register_operand" "")
1362                   (match_operand:SF 2 "s_register_operand" "")))]
1363   "TARGET_32BIT && TARGET_HARD_FLOAT"
1364   "
1367 (define_expand "subdf3"
1368   [(set (match_operand:DF           0 "s_register_operand" "")
1369         (minus:DF (match_operand:DF 1 "s_register_operand" "")
1370                   (match_operand:DF 2 "s_register_operand" "")))]
1371   "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
1372   "
1376 ;; Multiplication insns
1378 (define_expand "mulhi3"
1379   [(set (match_operand:HI 0 "s_register_operand" "")
1380         (mult:HI (match_operand:HI 1 "s_register_operand" "")
1381                  (match_operand:HI 2 "s_register_operand" "")))]
1382   "TARGET_DSP_MULTIPLY"
1383   "
1384   {
1385     rtx result = gen_reg_rtx (SImode);
1386     emit_insn (gen_mulhisi3 (result, operands[1], operands[2]));
1387     emit_move_insn (operands[0], gen_lowpart (HImode, result));
1388     DONE;
1389   }"
1392 (define_expand "mulsi3"
1393   [(set (match_operand:SI          0 "s_register_operand" "")
1394         (mult:SI (match_operand:SI 2 "s_register_operand" "")
1395                  (match_operand:SI 1 "s_register_operand" "")))]
1396   "TARGET_EITHER"
1397   ""
1400 ;; Use `&' and then `0' to prevent the operands 0 and 1 being the same
1401 (define_insn "*arm_mulsi3"
1402   [(set (match_operand:SI          0 "s_register_operand" "=&r,&r")
1403         (mult:SI (match_operand:SI 2 "s_register_operand" "r,r")
1404                  (match_operand:SI 1 "s_register_operand" "%0,r")))]
1405   "TARGET_32BIT && !arm_arch6"
1406   "mul%?\\t%0, %2, %1"
1407   [(set_attr "type" "mul")
1408    (set_attr "predicable" "yes")]
1411 (define_insn "*arm_mulsi3_v6"
1412   [(set (match_operand:SI          0 "s_register_operand" "=l,l,r")
1413         (mult:SI (match_operand:SI 1 "s_register_operand" "0,l,r")
1414                  (match_operand:SI 2 "s_register_operand" "l,0,r")))]
1415   "TARGET_32BIT && arm_arch6"
1416   "mul%?\\t%0, %1, %2"
1417   [(set_attr "type" "mul")
1418    (set_attr "predicable" "yes")
1419    (set_attr "arch" "t2,t2,*")
1420    (set_attr "length" "4")
1421    (set_attr "predicable_short_it" "yes,yes,no")]
1424 ; Unfortunately with the Thumb the '&'/'0' trick can fails when operands 
1425 ; 1 and 2; are the same, because reload will make operand 0 match 
1426 ; operand 1 without realizing that this conflicts with operand 2.  We fix 
1427 ; this by adding another alternative to match this case, and then `reload' 
1428 ; it ourselves.  This alternative must come first.
1429 (define_insn "*thumb_mulsi3"
1430   [(set (match_operand:SI          0 "register_operand" "=&l,&l,&l")
1431         (mult:SI (match_operand:SI 1 "register_operand" "%l,*h,0")
1432                  (match_operand:SI 2 "register_operand" "l,l,l")))]
1433   "TARGET_THUMB1 && !arm_arch6"
1434   "*
1435   if (which_alternative < 2)
1436     return \"mov\\t%0, %1\;mul\\t%0, %2\";
1437   else
1438     return \"mul\\t%0, %2\";
1439   "
1440   [(set_attr "length" "4,4,2")
1441    (set_attr "type" "muls")]
1444 (define_insn "*thumb_mulsi3_v6"
1445   [(set (match_operand:SI          0 "register_operand" "=l,l,l")
1446         (mult:SI (match_operand:SI 1 "register_operand" "0,l,0")
1447                  (match_operand:SI 2 "register_operand" "l,0,0")))]
1448   "TARGET_THUMB1 && arm_arch6"
1449   "@
1450    mul\\t%0, %2
1451    mul\\t%0, %1
1452    mul\\t%0, %1"
1453   [(set_attr "length" "2")
1454    (set_attr "type" "muls")]
1457 (define_insn "*mulsi3_compare0"
1458   [(set (reg:CC_NOOV CC_REGNUM)
1459         (compare:CC_NOOV (mult:SI
1460                           (match_operand:SI 2 "s_register_operand" "r,r")
1461                           (match_operand:SI 1 "s_register_operand" "%0,r"))
1462                          (const_int 0)))
1463    (set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1464         (mult:SI (match_dup 2) (match_dup 1)))]
1465   "TARGET_ARM && !arm_arch6"
1466   "mul%.\\t%0, %2, %1"
1467   [(set_attr "conds" "set")
1468    (set_attr "type" "muls")]
1471 (define_insn "*mulsi3_compare0_v6"
1472   [(set (reg:CC_NOOV CC_REGNUM)
1473         (compare:CC_NOOV (mult:SI
1474                           (match_operand:SI 2 "s_register_operand" "r")
1475                           (match_operand:SI 1 "s_register_operand" "r"))
1476                          (const_int 0)))
1477    (set (match_operand:SI 0 "s_register_operand" "=r")
1478         (mult:SI (match_dup 2) (match_dup 1)))]
1479   "TARGET_ARM && arm_arch6 && optimize_size"
1480   "mul%.\\t%0, %2, %1"
1481   [(set_attr "conds" "set")
1482    (set_attr "type" "muls")]
1485 (define_insn "*mulsi_compare0_scratch"
1486   [(set (reg:CC_NOOV CC_REGNUM)
1487         (compare:CC_NOOV (mult:SI
1488                           (match_operand:SI 2 "s_register_operand" "r,r")
1489                           (match_operand:SI 1 "s_register_operand" "%0,r"))
1490                          (const_int 0)))
1491    (clobber (match_scratch:SI 0 "=&r,&r"))]
1492   "TARGET_ARM && !arm_arch6"
1493   "mul%.\\t%0, %2, %1"
1494   [(set_attr "conds" "set")
1495    (set_attr "type" "muls")]
1498 (define_insn "*mulsi_compare0_scratch_v6"
1499   [(set (reg:CC_NOOV CC_REGNUM)
1500         (compare:CC_NOOV (mult:SI
1501                           (match_operand:SI 2 "s_register_operand" "r")
1502                           (match_operand:SI 1 "s_register_operand" "r"))
1503                          (const_int 0)))
1504    (clobber (match_scratch:SI 0 "=r"))]
1505   "TARGET_ARM && arm_arch6 && optimize_size"
1506   "mul%.\\t%0, %2, %1"
1507   [(set_attr "conds" "set")
1508    (set_attr "type" "muls")]
1511 ;; Unnamed templates to match MLA instruction.
1513 (define_insn "*mulsi3addsi"
1514   [(set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r,&r")
1515         (plus:SI
1516           (mult:SI (match_operand:SI 2 "s_register_operand" "r,r,r,r")
1517                    (match_operand:SI 1 "s_register_operand" "%0,r,0,r"))
1518           (match_operand:SI 3 "s_register_operand" "r,r,0,0")))]
1519   "TARGET_32BIT && !arm_arch6"
1520   "mla%?\\t%0, %2, %1, %3"
1521   [(set_attr "type" "mla")
1522    (set_attr "predicable" "yes")]
1525 (define_insn "*mulsi3addsi_v6"
1526   [(set (match_operand:SI 0 "s_register_operand" "=r")
1527         (plus:SI
1528           (mult:SI (match_operand:SI 2 "s_register_operand" "r")
1529                    (match_operand:SI 1 "s_register_operand" "r"))
1530           (match_operand:SI 3 "s_register_operand" "r")))]
1531   "TARGET_32BIT && arm_arch6"
1532   "mla%?\\t%0, %2, %1, %3"
1533   [(set_attr "type" "mla")
1534    (set_attr "predicable" "yes")
1535    (set_attr "predicable_short_it" "no")]
1538 (define_insn "*mulsi3addsi_compare0"
1539   [(set (reg:CC_NOOV CC_REGNUM)
1540         (compare:CC_NOOV
1541          (plus:SI (mult:SI
1542                    (match_operand:SI 2 "s_register_operand" "r,r,r,r")
1543                    (match_operand:SI 1 "s_register_operand" "%0,r,0,r"))
1544                   (match_operand:SI 3 "s_register_operand" "r,r,0,0"))
1545          (const_int 0)))
1546    (set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r,&r")
1547         (plus:SI (mult:SI (match_dup 2) (match_dup 1))
1548                  (match_dup 3)))]
1549   "TARGET_ARM && arm_arch6"
1550   "mla%.\\t%0, %2, %1, %3"
1551   [(set_attr "conds" "set")
1552    (set_attr "type" "mlas")]
1555 (define_insn "*mulsi3addsi_compare0_v6"
1556   [(set (reg:CC_NOOV CC_REGNUM)
1557         (compare:CC_NOOV
1558          (plus:SI (mult:SI
1559                    (match_operand:SI 2 "s_register_operand" "r")
1560                    (match_operand:SI 1 "s_register_operand" "r"))
1561                   (match_operand:SI 3 "s_register_operand" "r"))
1562          (const_int 0)))
1563    (set (match_operand:SI 0 "s_register_operand" "=r")
1564         (plus:SI (mult:SI (match_dup 2) (match_dup 1))
1565                  (match_dup 3)))]
1566   "TARGET_ARM && arm_arch6 && optimize_size"
1567   "mla%.\\t%0, %2, %1, %3"
1568   [(set_attr "conds" "set")
1569    (set_attr "type" "mlas")]
1572 (define_insn "*mulsi3addsi_compare0_scratch"
1573   [(set (reg:CC_NOOV CC_REGNUM)
1574         (compare:CC_NOOV
1575          (plus:SI (mult:SI
1576                    (match_operand:SI 2 "s_register_operand" "r,r,r,r")
1577                    (match_operand:SI 1 "s_register_operand" "%0,r,0,r"))
1578                   (match_operand:SI 3 "s_register_operand" "?r,r,0,0"))
1579          (const_int 0)))
1580    (clobber (match_scratch:SI 0 "=&r,&r,&r,&r"))]
1581   "TARGET_ARM && !arm_arch6"
1582   "mla%.\\t%0, %2, %1, %3"
1583   [(set_attr "conds" "set")
1584    (set_attr "type" "mlas")]
1587 (define_insn "*mulsi3addsi_compare0_scratch_v6"
1588   [(set (reg:CC_NOOV CC_REGNUM)
1589         (compare:CC_NOOV
1590          (plus:SI (mult:SI
1591                    (match_operand:SI 2 "s_register_operand" "r")
1592                    (match_operand:SI 1 "s_register_operand" "r"))
1593                   (match_operand:SI 3 "s_register_operand" "r"))
1594          (const_int 0)))
1595    (clobber (match_scratch:SI 0 "=r"))]
1596   "TARGET_ARM && arm_arch6 && optimize_size"
1597   "mla%.\\t%0, %2, %1, %3"
1598   [(set_attr "conds" "set")
1599    (set_attr "type" "mlas")]
1602 (define_insn "*mulsi3subsi"
1603   [(set (match_operand:SI 0 "s_register_operand" "=r")
1604         (minus:SI
1605           (match_operand:SI 3 "s_register_operand" "r")
1606           (mult:SI (match_operand:SI 2 "s_register_operand" "r")
1607                    (match_operand:SI 1 "s_register_operand" "r"))))]
1608   "TARGET_32BIT && arm_arch_thumb2"
1609   "mls%?\\t%0, %2, %1, %3"
1610   [(set_attr "type" "mla")
1611    (set_attr "predicable" "yes")
1612    (set_attr "predicable_short_it" "no")]
1615 (define_expand "maddsidi4"
1616   [(set (match_operand:DI 0 "s_register_operand" "")
1617         (plus:DI
1618          (mult:DI
1619           (sign_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1620           (sign_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1621          (match_operand:DI 3 "s_register_operand" "")))]
1622   "TARGET_32BIT && arm_arch3m"
1623   "")
1625 (define_insn "*mulsidi3adddi"
1626   [(set (match_operand:DI 0 "s_register_operand" "=&r")
1627         (plus:DI
1628          (mult:DI
1629           (sign_extend:DI (match_operand:SI 2 "s_register_operand" "%r"))
1630           (sign_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1631          (match_operand:DI 1 "s_register_operand" "0")))]
1632   "TARGET_32BIT && arm_arch3m && !arm_arch6"
1633   "smlal%?\\t%Q0, %R0, %3, %2"
1634   [(set_attr "type" "smlal")
1635    (set_attr "predicable" "yes")]
1638 (define_insn "*mulsidi3adddi_v6"
1639   [(set (match_operand:DI 0 "s_register_operand" "=r")
1640         (plus:DI
1641          (mult:DI
1642           (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r"))
1643           (sign_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1644          (match_operand:DI 1 "s_register_operand" "0")))]
1645   "TARGET_32BIT && arm_arch6"
1646   "smlal%?\\t%Q0, %R0, %3, %2"
1647   [(set_attr "type" "smlal")
1648    (set_attr "predicable" "yes")
1649    (set_attr "predicable_short_it" "no")]
1652 ;; 32x32->64 widening multiply.
1653 ;; As with mulsi3, the only difference between the v3-5 and v6+
1654 ;; versions of these patterns is the requirement that the output not
1655 ;; overlap the inputs, but that still means we have to have a named
1656 ;; expander and two different starred insns.
1658 (define_expand "mulsidi3"
1659   [(set (match_operand:DI 0 "s_register_operand" "")
1660         (mult:DI
1661          (sign_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1662          (sign_extend:DI (match_operand:SI 2 "s_register_operand" ""))))]
1663   "TARGET_32BIT && arm_arch3m"
1664   ""
1667 (define_insn "*mulsidi3_nov6"
1668   [(set (match_operand:DI 0 "s_register_operand" "=&r")
1669         (mult:DI
1670          (sign_extend:DI (match_operand:SI 1 "s_register_operand" "%r"))
1671          (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1672   "TARGET_32BIT && arm_arch3m && !arm_arch6"
1673   "smull%?\\t%Q0, %R0, %1, %2"
1674   [(set_attr "type" "smull")
1675    (set_attr "predicable" "yes")]
1678 (define_insn "*mulsidi3_v6"
1679   [(set (match_operand:DI 0 "s_register_operand" "=r")
1680         (mult:DI
1681          (sign_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1682          (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1683   "TARGET_32BIT && arm_arch6"
1684   "smull%?\\t%Q0, %R0, %1, %2"
1685   [(set_attr "type" "smull")
1686    (set_attr "predicable" "yes")
1687    (set_attr "predicable_short_it" "no")]
1690 (define_expand "umulsidi3"
1691   [(set (match_operand:DI 0 "s_register_operand" "")
1692         (mult:DI
1693          (zero_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1694          (zero_extend:DI (match_operand:SI 2 "s_register_operand" ""))))]
1695   "TARGET_32BIT && arm_arch3m"
1696   ""
1699 (define_insn "*umulsidi3_nov6"
1700   [(set (match_operand:DI 0 "s_register_operand" "=&r")
1701         (mult:DI
1702          (zero_extend:DI (match_operand:SI 1 "s_register_operand" "%r"))
1703          (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1704   "TARGET_32BIT && arm_arch3m && !arm_arch6"
1705   "umull%?\\t%Q0, %R0, %1, %2"
1706   [(set_attr "type" "umull")
1707    (set_attr "predicable" "yes")]
1710 (define_insn "*umulsidi3_v6"
1711   [(set (match_operand:DI 0 "s_register_operand" "=r")
1712         (mult:DI
1713          (zero_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1714          (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1715   "TARGET_32BIT && arm_arch6"
1716   "umull%?\\t%Q0, %R0, %1, %2"
1717   [(set_attr "type" "umull")
1718    (set_attr "predicable" "yes")
1719    (set_attr "predicable_short_it" "no")]
1722 (define_expand "umaddsidi4"
1723   [(set (match_operand:DI 0 "s_register_operand" "")
1724         (plus:DI
1725          (mult:DI
1726           (zero_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1727           (zero_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1728          (match_operand:DI 3 "s_register_operand" "")))]
1729   "TARGET_32BIT && arm_arch3m"
1730   "")
1732 (define_insn "*umulsidi3adddi"
1733   [(set (match_operand:DI 0 "s_register_operand" "=&r")
1734         (plus:DI
1735          (mult:DI
1736           (zero_extend:DI (match_operand:SI 2 "s_register_operand" "%r"))
1737           (zero_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1738          (match_operand:DI 1 "s_register_operand" "0")))]
1739   "TARGET_32BIT && arm_arch3m && !arm_arch6"
1740   "umlal%?\\t%Q0, %R0, %3, %2"
1741   [(set_attr "type" "umlal")
1742    (set_attr "predicable" "yes")]
1745 (define_insn "*umulsidi3adddi_v6"
1746   [(set (match_operand:DI 0 "s_register_operand" "=r")
1747         (plus:DI
1748          (mult:DI
1749           (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r"))
1750           (zero_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1751          (match_operand:DI 1 "s_register_operand" "0")))]
1752   "TARGET_32BIT && arm_arch6"
1753   "umlal%?\\t%Q0, %R0, %3, %2"
1754   [(set_attr "type" "umlal")
1755    (set_attr "predicable" "yes")
1756    (set_attr "predicable_short_it" "no")]
1759 (define_expand "smulsi3_highpart"
1760   [(parallel
1761     [(set (match_operand:SI 0 "s_register_operand" "")
1762           (truncate:SI
1763            (lshiftrt:DI
1764             (mult:DI
1765              (sign_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1766              (sign_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1767             (const_int 32))))
1768      (clobber (match_scratch:SI 3 ""))])]
1769   "TARGET_32BIT && arm_arch3m"
1770   ""
1773 (define_insn "*smulsi3_highpart_nov6"
1774   [(set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1775         (truncate:SI
1776          (lshiftrt:DI
1777           (mult:DI
1778            (sign_extend:DI (match_operand:SI 1 "s_register_operand" "%0,r"))
1779            (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r,r")))
1780           (const_int 32))))
1781    (clobber (match_scratch:SI 3 "=&r,&r"))]
1782   "TARGET_32BIT && arm_arch3m && !arm_arch6"
1783   "smull%?\\t%3, %0, %2, %1"
1784   [(set_attr "type" "smull")
1785    (set_attr "predicable" "yes")]
1788 (define_insn "*smulsi3_highpart_v6"
1789   [(set (match_operand:SI 0 "s_register_operand" "=r")
1790         (truncate:SI
1791          (lshiftrt:DI
1792           (mult:DI
1793            (sign_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1794            (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r")))
1795           (const_int 32))))
1796    (clobber (match_scratch:SI 3 "=r"))]
1797   "TARGET_32BIT && arm_arch6"
1798   "smull%?\\t%3, %0, %2, %1"
1799   [(set_attr "type" "smull")
1800    (set_attr "predicable" "yes")
1801    (set_attr "predicable_short_it" "no")]
1804 (define_expand "umulsi3_highpart"
1805   [(parallel
1806     [(set (match_operand:SI 0 "s_register_operand" "")
1807           (truncate:SI
1808            (lshiftrt:DI
1809             (mult:DI
1810              (zero_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1811               (zero_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1812             (const_int 32))))
1813      (clobber (match_scratch:SI 3 ""))])]
1814   "TARGET_32BIT && arm_arch3m"
1815   ""
1818 (define_insn "*umulsi3_highpart_nov6"
1819   [(set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1820         (truncate:SI
1821          (lshiftrt:DI
1822           (mult:DI
1823            (zero_extend:DI (match_operand:SI 1 "s_register_operand" "%0,r"))
1824            (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r,r")))
1825           (const_int 32))))
1826    (clobber (match_scratch:SI 3 "=&r,&r"))]
1827   "TARGET_32BIT && arm_arch3m && !arm_arch6"
1828   "umull%?\\t%3, %0, %2, %1"
1829   [(set_attr "type" "umull")
1830    (set_attr "predicable" "yes")]
1833 (define_insn "*umulsi3_highpart_v6"
1834   [(set (match_operand:SI 0 "s_register_operand" "=r")
1835         (truncate:SI
1836          (lshiftrt:DI
1837           (mult:DI
1838            (zero_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1839            (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r")))
1840           (const_int 32))))
1841    (clobber (match_scratch:SI 3 "=r"))]
1842   "TARGET_32BIT && arm_arch6"
1843   "umull%?\\t%3, %0, %2, %1"
1844   [(set_attr "type" "umull")
1845    (set_attr "predicable" "yes")
1846    (set_attr "predicable_short_it" "no")]
1849 (define_insn "mulhisi3"
1850   [(set (match_operand:SI 0 "s_register_operand" "=r")
1851         (mult:SI (sign_extend:SI
1852                   (match_operand:HI 1 "s_register_operand" "%r"))
1853                  (sign_extend:SI
1854                   (match_operand:HI 2 "s_register_operand" "r"))))]
1855   "TARGET_DSP_MULTIPLY"
1856   "smulbb%?\\t%0, %1, %2"
1857   [(set_attr "type" "smulxy")
1858    (set_attr "predicable" "yes")]
1861 (define_insn "*mulhisi3tb"
1862   [(set (match_operand:SI 0 "s_register_operand" "=r")
1863         (mult:SI (ashiftrt:SI
1864                   (match_operand:SI 1 "s_register_operand" "r")
1865                   (const_int 16))
1866                  (sign_extend:SI
1867                   (match_operand:HI 2 "s_register_operand" "r"))))]
1868   "TARGET_DSP_MULTIPLY"
1869   "smultb%?\\t%0, %1, %2"
1870   [(set_attr "type" "smulxy")
1871    (set_attr "predicable" "yes")
1872    (set_attr "predicable_short_it" "no")]
1875 (define_insn "*mulhisi3bt"
1876   [(set (match_operand:SI 0 "s_register_operand" "=r")
1877         (mult:SI (sign_extend:SI
1878                   (match_operand:HI 1 "s_register_operand" "r"))
1879                  (ashiftrt:SI
1880                   (match_operand:SI 2 "s_register_operand" "r")
1881                   (const_int 16))))]
1882   "TARGET_DSP_MULTIPLY"
1883   "smulbt%?\\t%0, %1, %2"
1884   [(set_attr "type" "smulxy")
1885    (set_attr "predicable" "yes")
1886    (set_attr "predicable_short_it" "no")]
1889 (define_insn "*mulhisi3tt"
1890   [(set (match_operand:SI 0 "s_register_operand" "=r")
1891         (mult:SI (ashiftrt:SI
1892                   (match_operand:SI 1 "s_register_operand" "r")
1893                   (const_int 16))
1894                  (ashiftrt:SI
1895                   (match_operand:SI 2 "s_register_operand" "r")
1896                   (const_int 16))))]
1897   "TARGET_DSP_MULTIPLY"
1898   "smultt%?\\t%0, %1, %2"
1899   [(set_attr "type" "smulxy")
1900    (set_attr "predicable" "yes")
1901    (set_attr "predicable_short_it" "no")]
1904 (define_insn "maddhisi4"
1905   [(set (match_operand:SI 0 "s_register_operand" "=r")
1906         (plus:SI (mult:SI (sign_extend:SI
1907                            (match_operand:HI 1 "s_register_operand" "r"))
1908                           (sign_extend:SI
1909                            (match_operand:HI 2 "s_register_operand" "r")))
1910                  (match_operand:SI 3 "s_register_operand" "r")))]
1911   "TARGET_DSP_MULTIPLY"
1912   "smlabb%?\\t%0, %1, %2, %3"
1913   [(set_attr "type" "smlaxy")
1914    (set_attr "predicable" "yes")
1915    (set_attr "predicable_short_it" "no")]
1918 ;; Note: there is no maddhisi4ibt because this one is canonical form
1919 (define_insn "*maddhisi4tb"
1920   [(set (match_operand:SI 0 "s_register_operand" "=r")
1921         (plus:SI (mult:SI (ashiftrt:SI
1922                            (match_operand:SI 1 "s_register_operand" "r")
1923                            (const_int 16))
1924                           (sign_extend:SI
1925                            (match_operand:HI 2 "s_register_operand" "r")))
1926                  (match_operand:SI 3 "s_register_operand" "r")))]
1927   "TARGET_DSP_MULTIPLY"
1928   "smlatb%?\\t%0, %1, %2, %3"
1929   [(set_attr "type" "smlaxy")
1930    (set_attr "predicable" "yes")
1931    (set_attr "predicable_short_it" "no")]
1934 (define_insn "*maddhisi4tt"
1935   [(set (match_operand:SI 0 "s_register_operand" "=r")
1936         (plus:SI (mult:SI (ashiftrt:SI
1937                            (match_operand:SI 1 "s_register_operand" "r")
1938                            (const_int 16))
1939                           (ashiftrt:SI
1940                            (match_operand:SI 2 "s_register_operand" "r")
1941                            (const_int 16)))
1942                  (match_operand:SI 3 "s_register_operand" "r")))]
1943   "TARGET_DSP_MULTIPLY"
1944   "smlatt%?\\t%0, %1, %2, %3"
1945   [(set_attr "type" "smlaxy")
1946    (set_attr "predicable" "yes")
1947    (set_attr "predicable_short_it" "no")]
1950 (define_insn "maddhidi4"
1951   [(set (match_operand:DI 0 "s_register_operand" "=r")
1952         (plus:DI
1953           (mult:DI (sign_extend:DI
1954                     (match_operand:HI 1 "s_register_operand" "r"))
1955                    (sign_extend:DI
1956                     (match_operand:HI 2 "s_register_operand" "r")))
1957           (match_operand:DI 3 "s_register_operand" "0")))]
1958   "TARGET_DSP_MULTIPLY"
1959   "smlalbb%?\\t%Q0, %R0, %1, %2"
1960   [(set_attr "type" "smlalxy")
1961    (set_attr "predicable" "yes")
1962    (set_attr "predicable_short_it" "no")])
1964 ;; Note: there is no maddhidi4ibt because this one is canonical form
1965 (define_insn "*maddhidi4tb"
1966   [(set (match_operand:DI 0 "s_register_operand" "=r")
1967         (plus:DI
1968           (mult:DI (sign_extend:DI
1969                     (ashiftrt:SI
1970                      (match_operand:SI 1 "s_register_operand" "r")
1971                      (const_int 16)))
1972                    (sign_extend:DI
1973                     (match_operand:HI 2 "s_register_operand" "r")))
1974           (match_operand:DI 3 "s_register_operand" "0")))]
1975   "TARGET_DSP_MULTIPLY"
1976   "smlaltb%?\\t%Q0, %R0, %1, %2"
1977   [(set_attr "type" "smlalxy")
1978    (set_attr "predicable" "yes")
1979    (set_attr "predicable_short_it" "no")])
1981 (define_insn "*maddhidi4tt"
1982   [(set (match_operand:DI 0 "s_register_operand" "=r")
1983         (plus:DI
1984           (mult:DI (sign_extend:DI
1985                     (ashiftrt:SI
1986                      (match_operand:SI 1 "s_register_operand" "r")
1987                      (const_int 16)))
1988                    (sign_extend:DI
1989                     (ashiftrt:SI
1990                      (match_operand:SI 2 "s_register_operand" "r")
1991                      (const_int 16))))
1992           (match_operand:DI 3 "s_register_operand" "0")))]
1993   "TARGET_DSP_MULTIPLY"
1994   "smlaltt%?\\t%Q0, %R0, %1, %2"
1995   [(set_attr "type" "smlalxy")
1996    (set_attr "predicable" "yes")
1997    (set_attr "predicable_short_it" "no")])
1999 (define_expand "mulsf3"
2000   [(set (match_operand:SF          0 "s_register_operand" "")
2001         (mult:SF (match_operand:SF 1 "s_register_operand" "")
2002                  (match_operand:SF 2 "s_register_operand" "")))]
2003   "TARGET_32BIT && TARGET_HARD_FLOAT"
2004   "
2007 (define_expand "muldf3"
2008   [(set (match_operand:DF          0 "s_register_operand" "")
2009         (mult:DF (match_operand:DF 1 "s_register_operand" "")
2010                  (match_operand:DF 2 "s_register_operand" "")))]
2011   "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
2012   "
2015 ;; Division insns
2017 (define_expand "divsf3"
2018   [(set (match_operand:SF 0 "s_register_operand" "")
2019         (div:SF (match_operand:SF 1 "s_register_operand" "")
2020                 (match_operand:SF 2 "s_register_operand" "")))]
2021   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
2022   "")
2024 (define_expand "divdf3"
2025   [(set (match_operand:DF 0 "s_register_operand" "")
2026         (div:DF (match_operand:DF 1 "s_register_operand" "")
2027                 (match_operand:DF 2 "s_register_operand" "")))]
2028   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
2029   "")
2031 ;; Boolean and,ior,xor insns
2033 ;; Split up double word logical operations
2035 ;; Split up simple DImode logical operations.  Simply perform the logical
2036 ;; operation on the upper and lower halves of the registers.
2037 (define_split
2038   [(set (match_operand:DI 0 "s_register_operand" "")
2039         (match_operator:DI 6 "logical_binary_operator"
2040           [(match_operand:DI 1 "s_register_operand" "")
2041            (match_operand:DI 2 "s_register_operand" "")]))]
2042   "TARGET_32BIT && reload_completed
2043    && ! (TARGET_NEON && IS_VFP_REGNUM (REGNO (operands[0])))
2044    && ! IS_IWMMXT_REGNUM (REGNO (operands[0]))"
2045   [(set (match_dup 0) (match_op_dup:SI 6 [(match_dup 1) (match_dup 2)]))
2046    (set (match_dup 3) (match_op_dup:SI 6 [(match_dup 4) (match_dup 5)]))]
2047   "
2048   {
2049     operands[3] = gen_highpart (SImode, operands[0]);
2050     operands[0] = gen_lowpart (SImode, operands[0]);
2051     operands[4] = gen_highpart (SImode, operands[1]);
2052     operands[1] = gen_lowpart (SImode, operands[1]);
2053     operands[5] = gen_highpart (SImode, operands[2]);
2054     operands[2] = gen_lowpart (SImode, operands[2]);
2055   }"
2058 (define_split
2059   [(set (match_operand:DI 0 "s_register_operand" "")
2060         (match_operator:DI 6 "logical_binary_operator"
2061           [(sign_extend:DI (match_operand:SI 2 "s_register_operand" ""))
2062            (match_operand:DI 1 "s_register_operand" "")]))]
2063   "TARGET_32BIT && reload_completed"
2064   [(set (match_dup 0) (match_op_dup:SI 6 [(match_dup 1) (match_dup 2)]))
2065    (set (match_dup 3) (match_op_dup:SI 6
2066                         [(ashiftrt:SI (match_dup 2) (const_int 31))
2067                          (match_dup 4)]))]
2068   "
2069   {
2070     operands[3] = gen_highpart (SImode, operands[0]);
2071     operands[0] = gen_lowpart (SImode, operands[0]);
2072     operands[4] = gen_highpart (SImode, operands[1]);
2073     operands[1] = gen_lowpart (SImode, operands[1]);
2074     operands[5] = gen_highpart (SImode, operands[2]);
2075     operands[2] = gen_lowpart (SImode, operands[2]);
2076   }"
2079 ;; The zero extend of operand 2 means we can just copy the high part of
2080 ;; operand1 into operand0.
2081 (define_split
2082   [(set (match_operand:DI 0 "s_register_operand" "")
2083         (ior:DI
2084           (zero_extend:DI (match_operand:SI 2 "s_register_operand" ""))
2085           (match_operand:DI 1 "s_register_operand" "")))]
2086   "TARGET_32BIT && operands[0] != operands[1] && reload_completed"
2087   [(set (match_dup 0) (ior:SI (match_dup 1) (match_dup 2)))
2088    (set (match_dup 3) (match_dup 4))]
2089   "
2090   {
2091     operands[4] = gen_highpart (SImode, operands[1]);
2092     operands[3] = gen_highpart (SImode, operands[0]);
2093     operands[0] = gen_lowpart (SImode, operands[0]);
2094     operands[1] = gen_lowpart (SImode, operands[1]);
2095   }"
2098 ;; The zero extend of operand 2 means we can just copy the high part of
2099 ;; operand1 into operand0.
2100 (define_split
2101   [(set (match_operand:DI 0 "s_register_operand" "")
2102         (xor:DI
2103           (zero_extend:DI (match_operand:SI 2 "s_register_operand" ""))
2104           (match_operand:DI 1 "s_register_operand" "")))]
2105   "TARGET_32BIT && operands[0] != operands[1] && reload_completed"
2106   [(set (match_dup 0) (xor:SI (match_dup 1) (match_dup 2)))
2107    (set (match_dup 3) (match_dup 4))]
2108   "
2109   {
2110     operands[4] = gen_highpart (SImode, operands[1]);
2111     operands[3] = gen_highpart (SImode, operands[0]);
2112     operands[0] = gen_lowpart (SImode, operands[0]);
2113     operands[1] = gen_lowpart (SImode, operands[1]);
2114   }"
2117 (define_expand "anddi3"
2118   [(set (match_operand:DI         0 "s_register_operand" "")
2119         (and:DI (match_operand:DI 1 "s_register_operand" "")
2120                 (match_operand:DI 2 "neon_inv_logic_op2" "")))]
2121   "TARGET_32BIT"
2122   ""
2125 (define_insn_and_split "*anddi3_insn"
2126   [(set (match_operand:DI         0 "s_register_operand"     "=w,w ,&r,&r,&r,&r,?w,?w")
2127         (and:DI (match_operand:DI 1 "s_register_operand"     "%w,0 ,0 ,r ,0 ,r ,w ,0")
2128                 (match_operand:DI 2 "arm_anddi_operand_neon" "w ,DL,r ,r ,De,De,w ,DL")))]
2129   "TARGET_32BIT && !TARGET_IWMMXT"
2131   switch (which_alternative)
2132     {
2133     case 0: /* fall through */
2134     case 6: return "vand\t%P0, %P1, %P2";
2135     case 1: /* fall through */
2136     case 7: return neon_output_logic_immediate ("vand", &operands[2],
2137                     DImode, 1, VALID_NEON_QREG_MODE (DImode));
2138     case 2:
2139     case 3:
2140     case 4:
2141     case 5: /* fall through */
2142       return "#";
2143     default: gcc_unreachable ();
2144     }
2146   "TARGET_32BIT && !TARGET_IWMMXT && reload_completed
2147    && !(IS_VFP_REGNUM (REGNO (operands[0])))"
2148   [(set (match_dup 3) (match_dup 4))
2149    (set (match_dup 5) (match_dup 6))]
2150   "
2151   {
2152     operands[3] = gen_lowpart (SImode, operands[0]);
2153     operands[5] = gen_highpart (SImode, operands[0]);
2155     operands[4] = simplify_gen_binary (AND, SImode,
2156                                            gen_lowpart (SImode, operands[1]),
2157                                            gen_lowpart (SImode, operands[2]));
2158     operands[6] = simplify_gen_binary (AND, SImode,
2159                                            gen_highpart (SImode, operands[1]),
2160                                            gen_highpart_mode (SImode, DImode, operands[2]));
2162   }"
2163   [(set_attr "type" "neon_logic,neon_logic,multiple,multiple,\
2164                      multiple,multiple,neon_logic,neon_logic")
2165    (set_attr "arch" "neon_for_64bits,neon_for_64bits,*,*,*,*,
2166                      avoid_neon_for_64bits,avoid_neon_for_64bits")
2167    (set_attr "length" "*,*,8,8,8,8,*,*")
2168   ]
2171 (define_insn_and_split "*anddi_zesidi_di"
2172   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2173         (and:DI (zero_extend:DI
2174                  (match_operand:SI 2 "s_register_operand" "r,r"))
2175                 (match_operand:DI 1 "s_register_operand" "0,r")))]
2176   "TARGET_32BIT"
2177   "#"
2178   "TARGET_32BIT && reload_completed"
2179   ; The zero extend of operand 2 clears the high word of the output
2180   ; operand.
2181   [(set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))
2182    (set (match_dup 3) (const_int 0))]
2183   "
2184   {
2185     operands[3] = gen_highpart (SImode, operands[0]);
2186     operands[0] = gen_lowpart (SImode, operands[0]);
2187     operands[1] = gen_lowpart (SImode, operands[1]);
2188   }"
2189   [(set_attr "length" "8")
2190    (set_attr "type" "multiple")]
2193 (define_insn "*anddi_sesdi_di"
2194   [(set (match_operand:DI          0 "s_register_operand" "=&r,&r")
2195         (and:DI (sign_extend:DI
2196                  (match_operand:SI 2 "s_register_operand" "r,r"))
2197                 (match_operand:DI  1 "s_register_operand" "0,r")))]
2198   "TARGET_32BIT"
2199   "#"
2200   [(set_attr "length" "8")
2201    (set_attr "type" "multiple")]
2204 (define_expand "andsi3"
2205   [(set (match_operand:SI         0 "s_register_operand" "")
2206         (and:SI (match_operand:SI 1 "s_register_operand" "")
2207                 (match_operand:SI 2 "reg_or_int_operand" "")))]
2208   "TARGET_EITHER"
2209   "
2210   if (TARGET_32BIT)
2211     {
2212       if (CONST_INT_P (operands[2]))
2213         {
2214           if (INTVAL (operands[2]) == 255 && arm_arch6)
2215             {
2216               operands[1] = convert_to_mode (QImode, operands[1], 1);
2217               emit_insn (gen_thumb2_zero_extendqisi2_v6 (operands[0],
2218                                                          operands[1]));
2219             }
2220           else
2221             arm_split_constant (AND, SImode, NULL_RTX,
2222                                 INTVAL (operands[2]), operands[0],
2223                                 operands[1],
2224                                 optimize && can_create_pseudo_p ());
2226           DONE;
2227         }
2228     }
2229   else /* TARGET_THUMB1 */
2230     {
2231       if (!CONST_INT_P (operands[2]))
2232         {
2233           rtx tmp = force_reg (SImode, operands[2]);
2234           if (rtx_equal_p (operands[0], operands[1]))
2235             operands[2] = tmp;
2236           else
2237             {
2238               operands[2] = operands[1];
2239               operands[1] = tmp;
2240             }
2241         }
2242       else
2243         {
2244           int i;
2245           
2246           if (((unsigned HOST_WIDE_INT) ~INTVAL (operands[2])) < 256)
2247             {
2248               operands[2] = force_reg (SImode,
2249                                        GEN_INT (~INTVAL (operands[2])));
2250               
2251               emit_insn (gen_thumb1_bicsi3 (operands[0], operands[2], operands[1]));
2252               
2253               DONE;
2254             }
2256           for (i = 9; i <= 31; i++)
2257             {
2258               if ((((HOST_WIDE_INT) 1) << i) - 1 == INTVAL (operands[2]))
2259                 {
2260                   emit_insn (gen_extzv (operands[0], operands[1], GEN_INT (i),
2261                                         const0_rtx));
2262                   DONE;
2263                 }
2264               else if ((((HOST_WIDE_INT) 1) << i) - 1
2265                        == ~INTVAL (operands[2]))
2266                 {
2267                   rtx shift = GEN_INT (i);
2268                   rtx reg = gen_reg_rtx (SImode);
2269                 
2270                   emit_insn (gen_lshrsi3 (reg, operands[1], shift));
2271                   emit_insn (gen_ashlsi3 (operands[0], reg, shift));
2272                   
2273                   DONE;
2274                 }
2275             }
2277           operands[2] = force_reg (SImode, operands[2]);
2278         }
2279     }
2280   "
2283 ; ??? Check split length for Thumb-2
2284 (define_insn_and_split "*arm_andsi3_insn"
2285   [(set (match_operand:SI         0 "s_register_operand" "=r,l,r,r,r")
2286         (and:SI (match_operand:SI 1 "s_register_operand" "%r,0,r,r,r")
2287                 (match_operand:SI 2 "reg_or_int_operand" "I,l,K,r,?n")))]
2288   "TARGET_32BIT"
2289   "@
2290    and%?\\t%0, %1, %2
2291    and%?\\t%0, %1, %2
2292    bic%?\\t%0, %1, #%B2
2293    and%?\\t%0, %1, %2
2294    #"
2295   "TARGET_32BIT
2296    && CONST_INT_P (operands[2])
2297    && !(const_ok_for_arm (INTVAL (operands[2]))
2298         || const_ok_for_arm (~INTVAL (operands[2])))"
2299   [(clobber (const_int 0))]
2300   "
2301   arm_split_constant  (AND, SImode, curr_insn, 
2302                        INTVAL (operands[2]), operands[0], operands[1], 0);
2303   DONE;
2304   "
2305   [(set_attr "length" "4,4,4,4,16")
2306    (set_attr "predicable" "yes")
2307    (set_attr "predicable_short_it" "no,yes,no,no,no")
2308    (set_attr "type" "logic_imm,logic_imm,logic_reg,logic_reg,logic_imm")]
2311 (define_insn "*thumb1_andsi3_insn"
2312   [(set (match_operand:SI         0 "register_operand" "=l")
2313         (and:SI (match_operand:SI 1 "register_operand" "%0")
2314                 (match_operand:SI 2 "register_operand" "l")))]
2315   "TARGET_THUMB1"
2316   "and\\t%0, %2"
2317   [(set_attr "length" "2")
2318    (set_attr "type"  "logic_imm")
2319    (set_attr "conds" "set")])
2321 (define_insn "*andsi3_compare0"
2322   [(set (reg:CC_NOOV CC_REGNUM)
2323         (compare:CC_NOOV
2324          (and:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
2325                  (match_operand:SI 2 "arm_not_operand" "I,K,r"))
2326          (const_int 0)))
2327    (set (match_operand:SI          0 "s_register_operand" "=r,r,r")
2328         (and:SI (match_dup 1) (match_dup 2)))]
2329   "TARGET_32BIT"
2330   "@
2331    and%.\\t%0, %1, %2
2332    bic%.\\t%0, %1, #%B2
2333    and%.\\t%0, %1, %2"
2334   [(set_attr "conds" "set")
2335    (set_attr "type" "logics_imm,logics_imm,logics_reg")]
2338 (define_insn "*andsi3_compare0_scratch"
2339   [(set (reg:CC_NOOV CC_REGNUM)
2340         (compare:CC_NOOV
2341          (and:SI (match_operand:SI 0 "s_register_operand" "r,r,r")
2342                  (match_operand:SI 1 "arm_not_operand" "I,K,r"))
2343          (const_int 0)))
2344    (clobber (match_scratch:SI 2 "=X,r,X"))]
2345   "TARGET_32BIT"
2346   "@
2347    tst%?\\t%0, %1
2348    bic%.\\t%2, %0, #%B1
2349    tst%?\\t%0, %1"
2350   [(set_attr "conds" "set")
2351    (set_attr "type"  "logics_imm,logics_imm,logics_reg")]
2354 (define_insn "*zeroextractsi_compare0_scratch"
2355   [(set (reg:CC_NOOV CC_REGNUM)
2356         (compare:CC_NOOV (zero_extract:SI
2357                           (match_operand:SI 0 "s_register_operand" "r")
2358                           (match_operand 1 "const_int_operand" "n")
2359                           (match_operand 2 "const_int_operand" "n"))
2360                          (const_int 0)))]
2361   "TARGET_32BIT
2362   && (INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) < 32
2363       && INTVAL (operands[1]) > 0 
2364       && INTVAL (operands[1]) + (INTVAL (operands[2]) & 1) <= 8
2365       && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32)"
2366   "*
2367   operands[1] = GEN_INT (((1 << INTVAL (operands[1])) - 1)
2368                          << INTVAL (operands[2]));
2369   output_asm_insn (\"tst%?\\t%0, %1\", operands);
2370   return \"\";
2371   "
2372   [(set_attr "conds" "set")
2373    (set_attr "predicable" "yes")
2374    (set_attr "predicable_short_it" "no")
2375    (set_attr "type" "logics_imm")]
2378 (define_insn_and_split "*ne_zeroextractsi"
2379   [(set (match_operand:SI 0 "s_register_operand" "=r")
2380         (ne:SI (zero_extract:SI
2381                 (match_operand:SI 1 "s_register_operand" "r")
2382                 (match_operand:SI 2 "const_int_operand" "n")
2383                 (match_operand:SI 3 "const_int_operand" "n"))
2384                (const_int 0)))
2385    (clobber (reg:CC CC_REGNUM))]
2386   "TARGET_32BIT
2387    && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2388        && INTVAL (operands[2]) > 0 
2389        && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2390        && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)"
2391   "#"
2392   "TARGET_32BIT
2393    && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2394        && INTVAL (operands[2]) > 0 
2395        && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2396        && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)"
2397   [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2398                    (compare:CC_NOOV (and:SI (match_dup 1) (match_dup 2))
2399                                     (const_int 0)))
2400               (set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))])
2401    (set (match_dup 0)
2402         (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2403                          (match_dup 0) (const_int 1)))]
2404   "
2405   operands[2] = GEN_INT (((1 << INTVAL (operands[2])) - 1)
2406                          << INTVAL (operands[3])); 
2407   "
2408   [(set_attr "conds" "clob")
2409    (set (attr "length")
2410         (if_then_else (eq_attr "is_thumb" "yes")
2411                       (const_int 12)
2412                       (const_int 8)))
2413    (set_attr "type" "multiple")]
2416 (define_insn_and_split "*ne_zeroextractsi_shifted"
2417   [(set (match_operand:SI 0 "s_register_operand" "=r")
2418         (ne:SI (zero_extract:SI
2419                 (match_operand:SI 1 "s_register_operand" "r")
2420                 (match_operand:SI 2 "const_int_operand" "n")
2421                 (const_int 0))
2422                (const_int 0)))
2423    (clobber (reg:CC CC_REGNUM))]
2424   "TARGET_ARM"
2425   "#"
2426   "TARGET_ARM"
2427   [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2428                    (compare:CC_NOOV (ashift:SI (match_dup 1) (match_dup 2))
2429                                     (const_int 0)))
2430               (set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))])
2431    (set (match_dup 0)
2432         (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2433                          (match_dup 0) (const_int 1)))]
2434   "
2435   operands[2] = GEN_INT (32 - INTVAL (operands[2]));
2436   "
2437   [(set_attr "conds" "clob")
2438    (set_attr "length" "8")
2439    (set_attr "type" "multiple")]
2442 (define_insn_and_split "*ite_ne_zeroextractsi"
2443   [(set (match_operand:SI 0 "s_register_operand" "=r")
2444         (if_then_else:SI (ne (zero_extract:SI
2445                               (match_operand:SI 1 "s_register_operand" "r")
2446                               (match_operand:SI 2 "const_int_operand" "n")
2447                               (match_operand:SI 3 "const_int_operand" "n"))
2448                              (const_int 0))
2449                          (match_operand:SI 4 "arm_not_operand" "rIK")
2450                          (const_int 0)))
2451    (clobber (reg:CC CC_REGNUM))]
2452   "TARGET_ARM
2453    && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2454        && INTVAL (operands[2]) > 0 
2455        && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2456        && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)
2457    && !reg_overlap_mentioned_p (operands[0], operands[4])"
2458   "#"
2459   "TARGET_ARM
2460    && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2461        && INTVAL (operands[2]) > 0 
2462        && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2463        && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)
2464    && !reg_overlap_mentioned_p (operands[0], operands[4])"
2465   [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2466                    (compare:CC_NOOV (and:SI (match_dup 1) (match_dup 2))
2467                                     (const_int 0)))
2468               (set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))])
2469    (set (match_dup 0)
2470         (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2471                          (match_dup 0) (match_dup 4)))]
2472   "
2473   operands[2] = GEN_INT (((1 << INTVAL (operands[2])) - 1)
2474                          << INTVAL (operands[3])); 
2475   "
2476   [(set_attr "conds" "clob")
2477    (set_attr "length" "8")
2478    (set_attr "type" "multiple")]
2481 (define_insn_and_split "*ite_ne_zeroextractsi_shifted"
2482   [(set (match_operand:SI 0 "s_register_operand" "=r")
2483         (if_then_else:SI (ne (zero_extract:SI
2484                               (match_operand:SI 1 "s_register_operand" "r")
2485                               (match_operand:SI 2 "const_int_operand" "n")
2486                               (const_int 0))
2487                              (const_int 0))
2488                          (match_operand:SI 3 "arm_not_operand" "rIK")
2489                          (const_int 0)))
2490    (clobber (reg:CC CC_REGNUM))]
2491   "TARGET_ARM && !reg_overlap_mentioned_p (operands[0], operands[3])"
2492   "#"
2493   "TARGET_ARM && !reg_overlap_mentioned_p (operands[0], operands[3])"
2494   [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2495                    (compare:CC_NOOV (ashift:SI (match_dup 1) (match_dup 2))
2496                                     (const_int 0)))
2497               (set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))])
2498    (set (match_dup 0)
2499         (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2500                          (match_dup 0) (match_dup 3)))]
2501   "
2502   operands[2] = GEN_INT (32 - INTVAL (operands[2]));
2503   "
2504   [(set_attr "conds" "clob")
2505    (set_attr "length" "8")
2506    (set_attr "type" "multiple")]
2509 (define_split
2510   [(set (match_operand:SI 0 "s_register_operand" "")
2511         (zero_extract:SI (match_operand:SI 1 "s_register_operand" "")
2512                          (match_operand:SI 2 "const_int_operand" "")
2513                          (match_operand:SI 3 "const_int_operand" "")))
2514    (clobber (match_operand:SI 4 "s_register_operand" ""))]
2515   "TARGET_THUMB1"
2516   [(set (match_dup 4) (ashift:SI (match_dup 1) (match_dup 2)))
2517    (set (match_dup 0) (lshiftrt:SI (match_dup 4) (match_dup 3)))]
2518   "{
2519      HOST_WIDE_INT temp = INTVAL (operands[2]);
2521      operands[2] = GEN_INT (32 - temp - INTVAL (operands[3]));
2522      operands[3] = GEN_INT (32 - temp);
2523    }"
2526 ;; ??? Use Thumb-2 has bitfield insert/extract instructions.
2527 (define_split
2528   [(set (match_operand:SI 0 "s_register_operand" "")
2529         (match_operator:SI 1 "shiftable_operator"
2530          [(zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
2531                            (match_operand:SI 3 "const_int_operand" "")
2532                            (match_operand:SI 4 "const_int_operand" ""))
2533           (match_operand:SI 5 "s_register_operand" "")]))
2534    (clobber (match_operand:SI 6 "s_register_operand" ""))]
2535   "TARGET_ARM"
2536   [(set (match_dup 6) (ashift:SI (match_dup 2) (match_dup 3)))
2537    (set (match_dup 0)
2538         (match_op_dup 1
2539          [(lshiftrt:SI (match_dup 6) (match_dup 4))
2540           (match_dup 5)]))]
2541   "{
2542      HOST_WIDE_INT temp = INTVAL (operands[3]);
2544      operands[3] = GEN_INT (32 - temp - INTVAL (operands[4]));
2545      operands[4] = GEN_INT (32 - temp);
2546    }"
2548   
2549 (define_split
2550   [(set (match_operand:SI 0 "s_register_operand" "")
2551         (sign_extract:SI (match_operand:SI 1 "s_register_operand" "")
2552                          (match_operand:SI 2 "const_int_operand" "")
2553                          (match_operand:SI 3 "const_int_operand" "")))]
2554   "TARGET_THUMB1"
2555   [(set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))
2556    (set (match_dup 0) (ashiftrt:SI (match_dup 0) (match_dup 3)))]
2557   "{
2558      HOST_WIDE_INT temp = INTVAL (operands[2]);
2560      operands[2] = GEN_INT (32 - temp - INTVAL (operands[3]));
2561      operands[3] = GEN_INT (32 - temp);
2562    }"
2565 (define_split
2566   [(set (match_operand:SI 0 "s_register_operand" "")
2567         (match_operator:SI 1 "shiftable_operator"
2568          [(sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
2569                            (match_operand:SI 3 "const_int_operand" "")
2570                            (match_operand:SI 4 "const_int_operand" ""))
2571           (match_operand:SI 5 "s_register_operand" "")]))
2572    (clobber (match_operand:SI 6 "s_register_operand" ""))]
2573   "TARGET_ARM"
2574   [(set (match_dup 6) (ashift:SI (match_dup 2) (match_dup 3)))
2575    (set (match_dup 0)
2576         (match_op_dup 1
2577          [(ashiftrt:SI (match_dup 6) (match_dup 4))
2578           (match_dup 5)]))]
2579   "{
2580      HOST_WIDE_INT temp = INTVAL (operands[3]);
2582      operands[3] = GEN_INT (32 - temp - INTVAL (operands[4]));
2583      operands[4] = GEN_INT (32 - temp);
2584    }"
2586   
2587 ;;; ??? This pattern is bogus.  If operand3 has bits outside the range
2588 ;;; represented by the bitfield, then this will produce incorrect results.
2589 ;;; Somewhere, the value needs to be truncated.  On targets like the m68k,
2590 ;;; which have a real bit-field insert instruction, the truncation happens
2591 ;;; in the bit-field insert instruction itself.  Since arm does not have a
2592 ;;; bit-field insert instruction, we would have to emit code here to truncate
2593 ;;; the value before we insert.  This loses some of the advantage of having
2594 ;;; this insv pattern, so this pattern needs to be reevalutated.
2596 (define_expand "insv"
2597   [(set (zero_extract (match_operand 0 "nonimmediate_operand" "")
2598                       (match_operand 1 "general_operand" "")
2599                       (match_operand 2 "general_operand" ""))
2600         (match_operand 3 "reg_or_int_operand" ""))]
2601   "TARGET_ARM || arm_arch_thumb2"
2602   "
2603   {
2604     int start_bit = INTVAL (operands[2]);
2605     int width = INTVAL (operands[1]);
2606     HOST_WIDE_INT mask = (((HOST_WIDE_INT)1) << width) - 1;
2607     rtx target, subtarget;
2609     if (arm_arch_thumb2)
2610       {
2611         if (unaligned_access && MEM_P (operands[0])
2612             && s_register_operand (operands[3], GET_MODE (operands[3]))
2613             && (width == 16 || width == 32) && (start_bit % BITS_PER_UNIT) == 0)
2614           {
2615             rtx base_addr;
2617             if (BYTES_BIG_ENDIAN)
2618               start_bit = GET_MODE_BITSIZE (GET_MODE (operands[3])) - width
2619                           - start_bit;
2621             if (width == 32)
2622               {
2623                 base_addr = adjust_address (operands[0], SImode,
2624                                             start_bit / BITS_PER_UNIT);
2625                 emit_insn (gen_unaligned_storesi (base_addr, operands[3]));
2626               }
2627             else
2628               {
2629                 rtx tmp = gen_reg_rtx (HImode);
2631                 base_addr = adjust_address (operands[0], HImode,
2632                                             start_bit / BITS_PER_UNIT);
2633                 emit_move_insn (tmp, gen_lowpart (HImode, operands[3]));
2634                 emit_insn (gen_unaligned_storehi (base_addr, tmp));
2635               }
2636             DONE;
2637           }
2638         else if (s_register_operand (operands[0], GET_MODE (operands[0])))
2639           {
2640             bool use_bfi = TRUE;
2642             if (CONST_INT_P (operands[3]))
2643               {
2644                 HOST_WIDE_INT val = INTVAL (operands[3]) & mask;
2646                 if (val == 0)
2647                   {
2648                     emit_insn (gen_insv_zero (operands[0], operands[1],
2649                                               operands[2]));
2650                     DONE;
2651                   }
2653                 /* See if the set can be done with a single orr instruction.  */
2654                 if (val == mask && const_ok_for_arm (val << start_bit))
2655                   use_bfi = FALSE;
2656               }
2658             if (use_bfi)
2659               {
2660                 if (!REG_P (operands[3]))
2661                   operands[3] = force_reg (SImode, operands[3]);
2663                 emit_insn (gen_insv_t2 (operands[0], operands[1], operands[2],
2664                                         operands[3]));
2665                 DONE;
2666               }
2667           }
2668         else
2669           FAIL;
2670       }
2672     if (!s_register_operand (operands[0], GET_MODE (operands[0])))
2673       FAIL;
2675     target = copy_rtx (operands[0]);
2676     /* Avoid using a subreg as a subtarget, and avoid writing a paradoxical 
2677        subreg as the final target.  */
2678     if (GET_CODE (target) == SUBREG)
2679       {
2680         subtarget = gen_reg_rtx (SImode);
2681         if (GET_MODE_SIZE (GET_MODE (SUBREG_REG (target)))
2682             < GET_MODE_SIZE (SImode))
2683           target = SUBREG_REG (target);
2684       }
2685     else
2686       subtarget = target;    
2688     if (CONST_INT_P (operands[3]))
2689       {
2690         /* Since we are inserting a known constant, we may be able to
2691            reduce the number of bits that we have to clear so that
2692            the mask becomes simple.  */
2693         /* ??? This code does not check to see if the new mask is actually
2694            simpler.  It may not be.  */
2695         rtx op1 = gen_reg_rtx (SImode);
2696         /* ??? Truncate operand3 to fit in the bitfield.  See comment before
2697            start of this pattern.  */
2698         HOST_WIDE_INT op3_value = mask & INTVAL (operands[3]);
2699         HOST_WIDE_INT mask2 = ((mask & ~op3_value) << start_bit);
2701         emit_insn (gen_andsi3 (op1, operands[0],
2702                                gen_int_mode (~mask2, SImode)));
2703         emit_insn (gen_iorsi3 (subtarget, op1,
2704                                gen_int_mode (op3_value << start_bit, SImode)));
2705       }
2706     else if (start_bit == 0
2707              && !(const_ok_for_arm (mask)
2708                   || const_ok_for_arm (~mask)))
2709       {
2710         /* A Trick, since we are setting the bottom bits in the word,
2711            we can shift operand[3] up, operand[0] down, OR them together
2712            and rotate the result back again.  This takes 3 insns, and
2713            the third might be mergeable into another op.  */
2714         /* The shift up copes with the possibility that operand[3] is
2715            wider than the bitfield.  */
2716         rtx op0 = gen_reg_rtx (SImode);
2717         rtx op1 = gen_reg_rtx (SImode);
2719         emit_insn (gen_ashlsi3 (op0, operands[3], GEN_INT (32 - width)));
2720         emit_insn (gen_lshrsi3 (op1, operands[0], operands[1]));
2721         emit_insn (gen_iorsi3  (op1, op1, op0));
2722         emit_insn (gen_rotlsi3 (subtarget, op1, operands[1]));
2723       }
2724     else if ((width + start_bit == 32)
2725              && !(const_ok_for_arm (mask)
2726                   || const_ok_for_arm (~mask)))
2727       {
2728         /* Similar trick, but slightly less efficient.  */
2730         rtx op0 = gen_reg_rtx (SImode);
2731         rtx op1 = gen_reg_rtx (SImode);
2733         emit_insn (gen_ashlsi3 (op0, operands[3], GEN_INT (32 - width)));
2734         emit_insn (gen_ashlsi3 (op1, operands[0], operands[1]));
2735         emit_insn (gen_lshrsi3 (op1, op1, operands[1]));
2736         emit_insn (gen_iorsi3 (subtarget, op1, op0));
2737       }
2738     else
2739       {
2740         rtx op0 = gen_int_mode (mask, SImode);
2741         rtx op1 = gen_reg_rtx (SImode);
2742         rtx op2 = gen_reg_rtx (SImode);
2744         if (!(const_ok_for_arm (mask) || const_ok_for_arm (~mask)))
2745           {
2746             rtx tmp = gen_reg_rtx (SImode);
2748             emit_insn (gen_movsi (tmp, op0));
2749             op0 = tmp;
2750           }
2752         /* Mask out any bits in operand[3] that are not needed.  */
2753            emit_insn (gen_andsi3 (op1, operands[3], op0));
2755         if (CONST_INT_P (op0)
2756             && (const_ok_for_arm (mask << start_bit)
2757                 || const_ok_for_arm (~(mask << start_bit))))
2758           {
2759             op0 = gen_int_mode (~(mask << start_bit), SImode);
2760             emit_insn (gen_andsi3 (op2, operands[0], op0));
2761           }
2762         else
2763           {
2764             if (CONST_INT_P (op0))
2765               {
2766                 rtx tmp = gen_reg_rtx (SImode);
2768                 emit_insn (gen_movsi (tmp, op0));
2769                 op0 = tmp;
2770               }
2772             if (start_bit != 0)
2773               emit_insn (gen_ashlsi3 (op0, op0, operands[2]));
2774             
2775             emit_insn (gen_andsi_notsi_si (op2, operands[0], op0));
2776           }
2778         if (start_bit != 0)
2779           emit_insn (gen_ashlsi3 (op1, op1, operands[2]));
2781         emit_insn (gen_iorsi3 (subtarget, op1, op2));
2782       }
2784     if (subtarget != target)
2785       {
2786         /* If TARGET is still a SUBREG, then it must be wider than a word,
2787            so we must be careful only to set the subword we were asked to.  */
2788         if (GET_CODE (target) == SUBREG)
2789           emit_move_insn (target, subtarget);
2790         else
2791           emit_move_insn (target, gen_lowpart (GET_MODE (target), subtarget));
2792       }
2794     DONE;
2795   }"
2798 (define_insn "insv_zero"
2799   [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r")
2800                          (match_operand:SI 1 "const_int_M_operand" "M")
2801                          (match_operand:SI 2 "const_int_M_operand" "M"))
2802         (const_int 0))]
2803   "arm_arch_thumb2"
2804   "bfc%?\t%0, %2, %1"
2805   [(set_attr "length" "4")
2806    (set_attr "predicable" "yes")
2807    (set_attr "predicable_short_it" "no")
2808    (set_attr "type" "bfm")]
2811 (define_insn "insv_t2"
2812   [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r")
2813                          (match_operand:SI 1 "const_int_M_operand" "M")
2814                          (match_operand:SI 2 "const_int_M_operand" "M"))
2815         (match_operand:SI 3 "s_register_operand" "r"))]
2816   "arm_arch_thumb2"
2817   "bfi%?\t%0, %3, %2, %1"
2818   [(set_attr "length" "4")
2819    (set_attr "predicable" "yes")
2820    (set_attr "predicable_short_it" "no")
2821    (set_attr "type" "bfm")]
2824 ; constants for op 2 will never be given to these patterns.
2825 (define_insn_and_split "*anddi_notdi_di"
2826   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2827         (and:DI (not:DI (match_operand:DI 1 "s_register_operand" "0,r"))
2828                 (match_operand:DI 2 "s_register_operand" "r,0")))]
2829   "TARGET_32BIT"
2830   "#"
2831   "TARGET_32BIT && reload_completed
2832    && ! (TARGET_NEON && IS_VFP_REGNUM (REGNO (operands[0])))
2833    && ! IS_IWMMXT_REGNUM (REGNO (operands[0]))"
2834   [(set (match_dup 0) (and:SI (not:SI (match_dup 1)) (match_dup 2)))
2835    (set (match_dup 3) (and:SI (not:SI (match_dup 4)) (match_dup 5)))]
2836   "
2837   {
2838     operands[3] = gen_highpart (SImode, operands[0]);
2839     operands[0] = gen_lowpart (SImode, operands[0]);
2840     operands[4] = gen_highpart (SImode, operands[1]);
2841     operands[1] = gen_lowpart (SImode, operands[1]);
2842     operands[5] = gen_highpart (SImode, operands[2]);
2843     operands[2] = gen_lowpart (SImode, operands[2]);
2844   }"
2845   [(set_attr "length" "8")
2846    (set_attr "predicable" "yes")
2847    (set_attr "type" "multiple")]
2850 (define_insn_and_split "*anddi_notzesidi_di"
2851   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2852         (and:DI (not:DI (zero_extend:DI
2853                          (match_operand:SI 2 "s_register_operand" "r,r")))
2854                 (match_operand:DI 1 "s_register_operand" "0,?r")))]
2855   "TARGET_32BIT"
2856   "@
2857    bic%?\\t%Q0, %Q1, %2
2858    #"
2859   ; (not (zero_extend ...)) allows us to just copy the high word from
2860   ; operand1 to operand0.
2861   "TARGET_32BIT
2862    && reload_completed
2863    && operands[0] != operands[1]"
2864   [(set (match_dup 0) (and:SI (not:SI (match_dup 2)) (match_dup 1)))
2865    (set (match_dup 3) (match_dup 4))]
2866   "
2867   {
2868     operands[3] = gen_highpart (SImode, operands[0]);
2869     operands[0] = gen_lowpart (SImode, operands[0]);
2870     operands[4] = gen_highpart (SImode, operands[1]);
2871     operands[1] = gen_lowpart (SImode, operands[1]);
2872   }"
2873   [(set_attr "length" "4,8")
2874    (set_attr "predicable" "yes")
2875    (set_attr "predicable_short_it" "no")
2876    (set_attr "type" "multiple")]
2879 (define_insn_and_split "*anddi_notdi_zesidi"
2880   [(set (match_operand:DI 0 "s_register_operand" "=r")
2881         (and:DI (not:DI (match_operand:DI 2 "s_register_operand" "r"))
2882                 (zero_extend:DI
2883                  (match_operand:SI 1 "s_register_operand" "r"))))]
2884   "TARGET_32BIT"
2885   "#"
2886   "TARGET_32BIT && reload_completed"
2887   [(set (match_dup 0) (and:SI (not:SI (match_dup 2)) (match_dup 1)))
2888    (set (match_dup 3) (const_int 0))]
2889   "
2890   {
2891     operands[3] = gen_highpart (SImode, operands[0]);
2892     operands[0] = gen_lowpart (SImode, operands[0]);
2893     operands[2] = gen_lowpart (SImode, operands[2]);
2894   }"
2895   [(set_attr "length" "8")
2896    (set_attr "predicable" "yes")
2897    (set_attr "predicable_short_it" "no")
2898    (set_attr "type" "multiple")]
2901 (define_insn_and_split "*anddi_notsesidi_di"
2902   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2903         (and:DI (not:DI (sign_extend:DI
2904                          (match_operand:SI 2 "s_register_operand" "r,r")))
2905                 (match_operand:DI 1 "s_register_operand" "0,r")))]
2906   "TARGET_32BIT"
2907   "#"
2908   "TARGET_32BIT && reload_completed"
2909   [(set (match_dup 0) (and:SI (not:SI (match_dup 2)) (match_dup 1)))
2910    (set (match_dup 3) (and:SI (not:SI
2911                                 (ashiftrt:SI (match_dup 2) (const_int 31)))
2912                                (match_dup 4)))]
2913   "
2914   {
2915     operands[3] = gen_highpart (SImode, operands[0]);
2916     operands[0] = gen_lowpart (SImode, operands[0]);
2917     operands[4] = gen_highpart (SImode, operands[1]);
2918     operands[1] = gen_lowpart (SImode, operands[1]);
2919   }"
2920   [(set_attr "length" "8")
2921    (set_attr "predicable" "yes")
2922    (set_attr "predicable_short_it" "no")
2923    (set_attr "type" "multiple")]
2926 (define_insn "andsi_notsi_si"
2927   [(set (match_operand:SI 0 "s_register_operand" "=r")
2928         (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
2929                 (match_operand:SI 1 "s_register_operand" "r")))]
2930   "TARGET_32BIT"
2931   "bic%?\\t%0, %1, %2"
2932   [(set_attr "predicable" "yes")
2933    (set_attr "predicable_short_it" "no")
2934    (set_attr "type" "logic_reg")]
2937 (define_insn "thumb1_bicsi3"
2938   [(set (match_operand:SI                 0 "register_operand" "=l")
2939         (and:SI (not:SI (match_operand:SI 1 "register_operand" "l"))
2940                 (match_operand:SI         2 "register_operand" "0")))]
2941   "TARGET_THUMB1"
2942   "bic\\t%0, %1"
2943   [(set_attr "length" "2")
2944    (set_attr "conds" "set")
2945    (set_attr "type" "logics_reg")]
2948 (define_insn "andsi_not_shiftsi_si"
2949   [(set (match_operand:SI 0 "s_register_operand" "=r")
2950         (and:SI (not:SI (match_operator:SI 4 "shift_operator"
2951                          [(match_operand:SI 2 "s_register_operand" "r")
2952                           (match_operand:SI 3 "arm_rhs_operand" "rM")]))
2953                 (match_operand:SI 1 "s_register_operand" "r")))]
2954   "TARGET_ARM"
2955   "bic%?\\t%0, %1, %2%S4"
2956   [(set_attr "predicable" "yes")
2957    (set_attr "shift" "2")
2958    (set (attr "type") (if_then_else (match_operand 3 "const_int_operand" "")
2959                       (const_string "logic_shift_imm")
2960                       (const_string "logic_shift_reg")))]
2963 (define_insn "*andsi_notsi_si_compare0"
2964   [(set (reg:CC_NOOV CC_REGNUM)
2965         (compare:CC_NOOV
2966          (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
2967                  (match_operand:SI 1 "s_register_operand" "r"))
2968          (const_int 0)))
2969    (set (match_operand:SI 0 "s_register_operand" "=r")
2970         (and:SI (not:SI (match_dup 2)) (match_dup 1)))]
2971   "TARGET_32BIT"
2972   "bic%.\\t%0, %1, %2"
2973   [(set_attr "conds" "set")
2974    (set_attr "type" "logics_shift_reg")]
2977 (define_insn "*andsi_notsi_si_compare0_scratch"
2978   [(set (reg:CC_NOOV CC_REGNUM)
2979         (compare:CC_NOOV
2980          (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
2981                  (match_operand:SI 1 "s_register_operand" "r"))
2982          (const_int 0)))
2983    (clobber (match_scratch:SI 0 "=r"))]
2984   "TARGET_32BIT"
2985   "bic%.\\t%0, %1, %2"
2986   [(set_attr "conds" "set")
2987    (set_attr "type" "logics_shift_reg")]
2990 (define_expand "iordi3"
2991   [(set (match_operand:DI         0 "s_register_operand" "")
2992         (ior:DI (match_operand:DI 1 "s_register_operand" "")
2993                 (match_operand:DI 2 "neon_logic_op2" "")))]
2994   "TARGET_32BIT"
2995   ""
2998 (define_insn_and_split "*iordi3_insn"
2999   [(set (match_operand:DI         0 "s_register_operand"     "=w,w ,&r,&r,&r,&r,?w,?w")
3000         (ior:DI (match_operand:DI 1 "s_register_operand"     "%w,0 ,0 ,r ,0 ,r ,w ,0")
3001                 (match_operand:DI 2 "arm_iordi_operand_neon" "w ,Dl,r ,r ,Df,Df,w ,Dl")))]
3002   "TARGET_32BIT && !TARGET_IWMMXT"
3003   {
3004   switch (which_alternative)
3005     {
3006     case 0: /* fall through */
3007     case 6: return "vorr\t%P0, %P1, %P2";
3008     case 1: /* fall through */
3009     case 7: return neon_output_logic_immediate ("vorr", &operands[2],
3010                      DImode, 0, VALID_NEON_QREG_MODE (DImode));
3011     case 2:
3012     case 3:
3013     case 4:
3014     case 5:
3015       return "#";
3016     default: gcc_unreachable ();
3017     }
3018   }
3019   "TARGET_32BIT && !TARGET_IWMMXT && reload_completed
3020    && !(IS_VFP_REGNUM (REGNO (operands[0])))"
3021   [(set (match_dup 3) (match_dup 4))
3022    (set (match_dup 5) (match_dup 6))]
3023   "
3024   {
3025     operands[3] = gen_lowpart (SImode, operands[0]);
3026     operands[5] = gen_highpart (SImode, operands[0]);
3028     operands[4] = simplify_gen_binary (IOR, SImode,
3029                                            gen_lowpart (SImode, operands[1]),
3030                                            gen_lowpart (SImode, operands[2]));
3031     operands[6] = simplify_gen_binary (IOR, SImode,
3032                                            gen_highpart (SImode, operands[1]),
3033                                            gen_highpart_mode (SImode, DImode, operands[2]));
3035   }"
3036   [(set_attr "type" "neon_logic,neon_logic,multiple,multiple,multiple,\
3037                      multiple,neon_logic,neon_logic")
3038    (set_attr "length" "*,*,8,8,8,8,*,*")
3039    (set_attr "arch" "neon_for_64bits,neon_for_64bits,*,*,*,*,avoid_neon_for_64bits,avoid_neon_for_64bits")]
3042 (define_insn "*iordi_zesidi_di"
3043   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
3044         (ior:DI (zero_extend:DI
3045                  (match_operand:SI 2 "s_register_operand" "r,r"))
3046                 (match_operand:DI 1 "s_register_operand" "0,?r")))]
3047   "TARGET_32BIT"
3048   "@
3049    orr%?\\t%Q0, %Q1, %2
3050    #"
3051   [(set_attr "length" "4,8")
3052    (set_attr "predicable" "yes")
3053    (set_attr "predicable_short_it" "no")
3054    (set_attr "type" "logic_reg,multiple")]
3057 (define_insn "*iordi_sesidi_di"
3058   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
3059         (ior:DI (sign_extend:DI
3060                  (match_operand:SI 2 "s_register_operand" "r,r"))
3061                 (match_operand:DI 1 "s_register_operand" "0,r")))]
3062   "TARGET_32BIT"
3063   "#"
3064   [(set_attr "length" "8")
3065    (set_attr "predicable" "yes")
3066    (set_attr "type" "multiple")]
3069 (define_expand "iorsi3"
3070   [(set (match_operand:SI         0 "s_register_operand" "")
3071         (ior:SI (match_operand:SI 1 "s_register_operand" "")
3072                 (match_operand:SI 2 "reg_or_int_operand" "")))]
3073   "TARGET_EITHER"
3074   "
3075   if (CONST_INT_P (operands[2]))
3076     {
3077       if (TARGET_32BIT)
3078         {
3079           arm_split_constant (IOR, SImode, NULL_RTX,
3080                               INTVAL (operands[2]), operands[0], operands[1],
3081                               optimize && can_create_pseudo_p ());
3082           DONE;
3083         }
3084       else /* TARGET_THUMB1 */
3085         {
3086           rtx tmp = force_reg (SImode, operands[2]);
3087           if (rtx_equal_p (operands[0], operands[1]))
3088             operands[2] = tmp;
3089           else
3090             {
3091               operands[2] = operands[1];
3092               operands[1] = tmp;
3093             }
3094         }
3095     }
3096   "
3099 (define_insn_and_split "*iorsi3_insn"
3100   [(set (match_operand:SI 0 "s_register_operand" "=r,l,r,r,r")
3101         (ior:SI (match_operand:SI 1 "s_register_operand" "%r,0,r,r,r")
3102                 (match_operand:SI 2 "reg_or_int_operand" "I,l,K,r,?n")))]
3103   "TARGET_32BIT"
3104   "@
3105    orr%?\\t%0, %1, %2
3106    orr%?\\t%0, %1, %2
3107    orn%?\\t%0, %1, #%B2
3108    orr%?\\t%0, %1, %2
3109    #"
3110   "TARGET_32BIT
3111    && CONST_INT_P (operands[2])
3112    && !(const_ok_for_arm (INTVAL (operands[2]))
3113         || (TARGET_THUMB2 && const_ok_for_arm (~INTVAL (operands[2]))))"
3114   [(clobber (const_int 0))]
3116   arm_split_constant (IOR, SImode, curr_insn,
3117                       INTVAL (operands[2]), operands[0], operands[1], 0);
3118   DONE;
3120   [(set_attr "length" "4,4,4,4,16")
3121    (set_attr "arch" "32,t2,t2,32,32")
3122    (set_attr "predicable" "yes")
3123    (set_attr "predicable_short_it" "no,yes,no,no,no")
3124    (set_attr "type" "logic_imm,logic_reg,logic_imm,logic_reg,logic_reg")]
3127 (define_insn "*thumb1_iorsi3_insn"
3128   [(set (match_operand:SI         0 "register_operand" "=l")
3129         (ior:SI (match_operand:SI 1 "register_operand" "%0")
3130                 (match_operand:SI 2 "register_operand" "l")))]
3131   "TARGET_THUMB1"
3132   "orr\\t%0, %2"
3133   [(set_attr "length" "2")
3134    (set_attr "conds" "set")
3135    (set_attr "type" "logics_reg")])
3137 (define_peephole2
3138   [(match_scratch:SI 3 "r")
3139    (set (match_operand:SI 0 "arm_general_register_operand" "")
3140         (ior:SI (match_operand:SI 1 "arm_general_register_operand" "")
3141                 (match_operand:SI 2 "const_int_operand" "")))]
3142   "TARGET_ARM
3143    && !const_ok_for_arm (INTVAL (operands[2]))
3144    && const_ok_for_arm (~INTVAL (operands[2]))"
3145   [(set (match_dup 3) (match_dup 2))
3146    (set (match_dup 0) (ior:SI (match_dup 1) (match_dup 3)))]
3147   ""
3150 (define_insn "*iorsi3_compare0"
3151   [(set (reg:CC_NOOV CC_REGNUM)
3152         (compare:CC_NOOV (ior:SI (match_operand:SI 1 "s_register_operand" "%r,r")
3153                                  (match_operand:SI 2 "arm_rhs_operand" "I,r"))
3154                          (const_int 0)))
3155    (set (match_operand:SI 0 "s_register_operand" "=r,r")
3156         (ior:SI (match_dup 1) (match_dup 2)))]
3157   "TARGET_32BIT"
3158   "orr%.\\t%0, %1, %2"
3159   [(set_attr "conds" "set")
3160    (set_attr "type" "logics_imm,logics_reg")]
3163 (define_insn "*iorsi3_compare0_scratch"
3164   [(set (reg:CC_NOOV CC_REGNUM)
3165         (compare:CC_NOOV (ior:SI (match_operand:SI 1 "s_register_operand" "%r,r")
3166                                  (match_operand:SI 2 "arm_rhs_operand" "I,r"))
3167                          (const_int 0)))
3168    (clobber (match_scratch:SI 0 "=r,r"))]
3169   "TARGET_32BIT"
3170   "orr%.\\t%0, %1, %2"
3171   [(set_attr "conds" "set")
3172    (set_attr "type" "logics_imm,logics_reg")]
3175 (define_expand "xordi3"
3176   [(set (match_operand:DI         0 "s_register_operand" "")
3177         (xor:DI (match_operand:DI 1 "s_register_operand" "")
3178                 (match_operand:DI 2 "arm_xordi_operand" "")))]
3179   "TARGET_32BIT"
3180   ""
3183 (define_insn_and_split "*xordi3_insn"
3184   [(set (match_operand:DI         0 "s_register_operand" "=w,&r,&r,&r,&r,?w")
3185         (xor:DI (match_operand:DI 1 "s_register_operand" "w ,%0,r ,0 ,r ,w")
3186                 (match_operand:DI 2 "arm_xordi_operand"  "w ,r ,r ,Dg,Dg,w")))]
3187   "TARGET_32BIT && !TARGET_IWMMXT"
3189   switch (which_alternative)
3190     {
3191     case 1:
3192     case 2:
3193     case 3:
3194     case 4:  /* fall through */
3195       return "#";
3196     case 0: /* fall through */
3197     case 5: return "veor\t%P0, %P1, %P2";
3198     default: gcc_unreachable ();
3199     }
3201   "TARGET_32BIT && !TARGET_IWMMXT && reload_completed
3202    && !(IS_VFP_REGNUM (REGNO (operands[0])))"
3203   [(set (match_dup 3) (match_dup 4))
3204    (set (match_dup 5) (match_dup 6))]
3205   "
3206   {
3207     operands[3] = gen_lowpart (SImode, operands[0]);
3208     operands[5] = gen_highpart (SImode, operands[0]);
3210     operands[4] = simplify_gen_binary (XOR, SImode,
3211                                            gen_lowpart (SImode, operands[1]),
3212                                            gen_lowpart (SImode, operands[2]));
3213     operands[6] = simplify_gen_binary (XOR, SImode,
3214                                            gen_highpart (SImode, operands[1]),
3215                                            gen_highpart_mode (SImode, DImode, operands[2]));
3217   }"
3218   [(set_attr "length" "*,8,8,8,8,*")
3219    (set_attr "type" "neon_logic,multiple,multiple,multiple,multiple,neon_logic")
3220    (set_attr "arch" "neon_for_64bits,*,*,*,*,avoid_neon_for_64bits")]
3223 (define_insn "*xordi_zesidi_di"
3224   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
3225         (xor:DI (zero_extend:DI
3226                  (match_operand:SI 2 "s_register_operand" "r,r"))
3227                 (match_operand:DI 1 "s_register_operand" "0,?r")))]
3228   "TARGET_32BIT"
3229   "@
3230    eor%?\\t%Q0, %Q1, %2
3231    #"
3232   [(set_attr "length" "4,8")
3233    (set_attr "predicable" "yes")
3234    (set_attr "predicable_short_it" "no")
3235    (set_attr "type" "logic_reg")]
3238 (define_insn "*xordi_sesidi_di"
3239   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
3240         (xor:DI (sign_extend:DI
3241                  (match_operand:SI 2 "s_register_operand" "r,r"))
3242                 (match_operand:DI 1 "s_register_operand" "0,r")))]
3243   "TARGET_32BIT"
3244   "#"
3245   [(set_attr "length" "8")
3246    (set_attr "predicable" "yes")
3247    (set_attr "type" "multiple")]
3250 (define_expand "xorsi3"
3251   [(set (match_operand:SI         0 "s_register_operand" "")
3252         (xor:SI (match_operand:SI 1 "s_register_operand" "")
3253                 (match_operand:SI 2 "reg_or_int_operand" "")))]
3254   "TARGET_EITHER"
3255   "if (CONST_INT_P (operands[2]))
3256     {
3257       if (TARGET_32BIT)
3258         {
3259           arm_split_constant (XOR, SImode, NULL_RTX,
3260                               INTVAL (operands[2]), operands[0], operands[1],
3261                               optimize && can_create_pseudo_p ());
3262           DONE;
3263         }
3264       else /* TARGET_THUMB1 */
3265         {
3266           rtx tmp = force_reg (SImode, operands[2]);
3267           if (rtx_equal_p (operands[0], operands[1]))
3268             operands[2] = tmp;
3269           else
3270             {
3271               operands[2] = operands[1];
3272               operands[1] = tmp;
3273             }
3274         }
3275     }"
3278 (define_insn_and_split "*arm_xorsi3"
3279   [(set (match_operand:SI         0 "s_register_operand" "=r,l,r,r")
3280         (xor:SI (match_operand:SI 1 "s_register_operand" "%r,0,r,r")
3281                 (match_operand:SI 2 "reg_or_int_operand" "I,l,r,?n")))]
3282   "TARGET_32BIT"
3283   "@
3284    eor%?\\t%0, %1, %2
3285    eor%?\\t%0, %1, %2
3286    eor%?\\t%0, %1, %2
3287    #"
3288   "TARGET_32BIT
3289    && CONST_INT_P (operands[2])
3290    && !const_ok_for_arm (INTVAL (operands[2]))"
3291   [(clobber (const_int 0))]
3293   arm_split_constant (XOR, SImode, curr_insn,
3294                       INTVAL (operands[2]), operands[0], operands[1], 0);
3295   DONE;
3297   [(set_attr "length" "4,4,4,16")
3298    (set_attr "predicable" "yes")
3299    (set_attr "predicable_short_it" "no,yes,no,no")
3300    (set_attr "type"  "logic_imm,logic_reg,logic_reg,multiple")]
3303 (define_insn "*thumb1_xorsi3_insn"
3304   [(set (match_operand:SI         0 "register_operand" "=l")
3305         (xor:SI (match_operand:SI 1 "register_operand" "%0")
3306                 (match_operand:SI 2 "register_operand" "l")))]
3307   "TARGET_THUMB1"
3308   "eor\\t%0, %2"
3309   [(set_attr "length" "2")
3310    (set_attr "conds" "set")
3311    (set_attr "type" "logics_reg")]
3314 (define_insn "*xorsi3_compare0"
3315   [(set (reg:CC_NOOV CC_REGNUM)
3316         (compare:CC_NOOV (xor:SI (match_operand:SI 1 "s_register_operand" "r,r")
3317                                  (match_operand:SI 2 "arm_rhs_operand" "I,r"))
3318                          (const_int 0)))
3319    (set (match_operand:SI 0 "s_register_operand" "=r,r")
3320         (xor:SI (match_dup 1) (match_dup 2)))]
3321   "TARGET_32BIT"
3322   "eor%.\\t%0, %1, %2"
3323   [(set_attr "conds" "set")
3324    (set_attr "type" "logics_imm,logics_reg")]
3327 (define_insn "*xorsi3_compare0_scratch"
3328   [(set (reg:CC_NOOV CC_REGNUM)
3329         (compare:CC_NOOV (xor:SI (match_operand:SI 0 "s_register_operand" "r,r")
3330                                  (match_operand:SI 1 "arm_rhs_operand" "I,r"))
3331                          (const_int 0)))]
3332   "TARGET_32BIT"
3333   "teq%?\\t%0, %1"
3334   [(set_attr "conds" "set")
3335    (set_attr "type" "logics_imm,logics_reg")]
3338 ; By splitting (IOR (AND (NOT A) (NOT B)) C) as D = AND (IOR A B) (NOT C), 
3339 ; (NOT D) we can sometimes merge the final NOT into one of the following
3340 ; insns.
3342 (define_split
3343   [(set (match_operand:SI 0 "s_register_operand" "")
3344         (ior:SI (and:SI (not:SI (match_operand:SI 1 "s_register_operand" ""))
3345                         (not:SI (match_operand:SI 2 "arm_rhs_operand" "")))
3346                 (match_operand:SI 3 "arm_rhs_operand" "")))
3347    (clobber (match_operand:SI 4 "s_register_operand" ""))]
3348   "TARGET_32BIT"
3349   [(set (match_dup 4) (and:SI (ior:SI (match_dup 1) (match_dup 2))
3350                               (not:SI (match_dup 3))))
3351    (set (match_dup 0) (not:SI (match_dup 4)))]
3352   ""
3355 (define_insn_and_split "*andsi_iorsi3_notsi"
3356   [(set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r")
3357         (and:SI (ior:SI (match_operand:SI 1 "s_register_operand" "%0,r,r")
3358                         (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI"))
3359                 (not:SI (match_operand:SI 3 "arm_rhs_operand" "rI,rI,rI"))))]
3360   "TARGET_32BIT"
3361   "#"   ; "orr%?\\t%0, %1, %2\;bic%?\\t%0, %0, %3"
3362   "&& reload_completed"
3363   [(set (match_dup 0) (ior:SI (match_dup 1) (match_dup 2)))
3364    (set (match_dup 0) (and:SI (not:SI (match_dup 3)) (match_dup 0)))]
3365   ""
3366   [(set_attr "length" "8")
3367    (set_attr "ce_count" "2")
3368    (set_attr "predicable" "yes")
3369    (set_attr "predicable_short_it" "no")
3370    (set_attr "type" "multiple")]
3373 ; ??? Are these four splitters still beneficial when the Thumb-2 bitfield
3374 ; insns are available?
3375 (define_split
3376   [(set (match_operand:SI 0 "s_register_operand" "")
3377         (match_operator:SI 1 "logical_binary_operator"
3378          [(zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
3379                            (match_operand:SI 3 "const_int_operand" "")
3380                            (match_operand:SI 4 "const_int_operand" ""))
3381           (match_operator:SI 9 "logical_binary_operator"
3382            [(lshiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3383                          (match_operand:SI 6 "const_int_operand" ""))
3384             (match_operand:SI 7 "s_register_operand" "")])]))
3385    (clobber (match_operand:SI 8 "s_register_operand" ""))]
3386   "TARGET_32BIT
3387    && GET_CODE (operands[1]) == GET_CODE (operands[9])
3388    && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3389   [(set (match_dup 8)
3390         (match_op_dup 1
3391          [(ashift:SI (match_dup 2) (match_dup 4))
3392           (match_dup 5)]))
3393    (set (match_dup 0)
3394         (match_op_dup 1
3395          [(lshiftrt:SI (match_dup 8) (match_dup 6))
3396           (match_dup 7)]))]
3397   "
3398   operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3401 (define_split
3402   [(set (match_operand:SI 0 "s_register_operand" "")
3403         (match_operator:SI 1 "logical_binary_operator"
3404          [(match_operator:SI 9 "logical_binary_operator"
3405            [(lshiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3406                          (match_operand:SI 6 "const_int_operand" ""))
3407             (match_operand:SI 7 "s_register_operand" "")])
3408           (zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
3409                            (match_operand:SI 3 "const_int_operand" "")
3410                            (match_operand:SI 4 "const_int_operand" ""))]))
3411    (clobber (match_operand:SI 8 "s_register_operand" ""))]
3412   "TARGET_32BIT
3413    && GET_CODE (operands[1]) == GET_CODE (operands[9])
3414    && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3415   [(set (match_dup 8)
3416         (match_op_dup 1
3417          [(ashift:SI (match_dup 2) (match_dup 4))
3418           (match_dup 5)]))
3419    (set (match_dup 0)
3420         (match_op_dup 1
3421          [(lshiftrt:SI (match_dup 8) (match_dup 6))
3422           (match_dup 7)]))]
3423   "
3424   operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3427 (define_split
3428   [(set (match_operand:SI 0 "s_register_operand" "")
3429         (match_operator:SI 1 "logical_binary_operator"
3430          [(sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
3431                            (match_operand:SI 3 "const_int_operand" "")
3432                            (match_operand:SI 4 "const_int_operand" ""))
3433           (match_operator:SI 9 "logical_binary_operator"
3434            [(ashiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3435                          (match_operand:SI 6 "const_int_operand" ""))
3436             (match_operand:SI 7 "s_register_operand" "")])]))
3437    (clobber (match_operand:SI 8 "s_register_operand" ""))]
3438   "TARGET_32BIT
3439    && GET_CODE (operands[1]) == GET_CODE (operands[9])
3440    && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3441   [(set (match_dup 8)
3442         (match_op_dup 1
3443          [(ashift:SI (match_dup 2) (match_dup 4))
3444           (match_dup 5)]))
3445    (set (match_dup 0)
3446         (match_op_dup 1
3447          [(ashiftrt:SI (match_dup 8) (match_dup 6))
3448           (match_dup 7)]))]
3449   "
3450   operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3453 (define_split
3454   [(set (match_operand:SI 0 "s_register_operand" "")
3455         (match_operator:SI 1 "logical_binary_operator"
3456          [(match_operator:SI 9 "logical_binary_operator"
3457            [(ashiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3458                          (match_operand:SI 6 "const_int_operand" ""))
3459             (match_operand:SI 7 "s_register_operand" "")])
3460           (sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
3461                            (match_operand:SI 3 "const_int_operand" "")
3462                            (match_operand:SI 4 "const_int_operand" ""))]))
3463    (clobber (match_operand:SI 8 "s_register_operand" ""))]
3464   "TARGET_32BIT
3465    && GET_CODE (operands[1]) == GET_CODE (operands[9])
3466    && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3467   [(set (match_dup 8)
3468         (match_op_dup 1
3469          [(ashift:SI (match_dup 2) (match_dup 4))
3470           (match_dup 5)]))
3471    (set (match_dup 0)
3472         (match_op_dup 1
3473          [(ashiftrt:SI (match_dup 8) (match_dup 6))
3474           (match_dup 7)]))]
3475   "
3476   operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3480 ;; Minimum and maximum insns
3482 (define_expand "smaxsi3"
3483   [(parallel [
3484     (set (match_operand:SI 0 "s_register_operand" "")
3485          (smax:SI (match_operand:SI 1 "s_register_operand" "")
3486                   (match_operand:SI 2 "arm_rhs_operand" "")))
3487     (clobber (reg:CC CC_REGNUM))])]
3488   "TARGET_32BIT"
3489   "
3490   if (operands[2] == const0_rtx || operands[2] == constm1_rtx)
3491     {
3492       /* No need for a clobber of the condition code register here.  */
3493       emit_insn (gen_rtx_SET (VOIDmode, operands[0],
3494                               gen_rtx_SMAX (SImode, operands[1],
3495                                             operands[2])));
3496       DONE;
3497     }
3500 (define_insn "*smax_0"
3501   [(set (match_operand:SI 0 "s_register_operand" "=r")
3502         (smax:SI (match_operand:SI 1 "s_register_operand" "r")
3503                  (const_int 0)))]
3504   "TARGET_32BIT"
3505   "bic%?\\t%0, %1, %1, asr #31"
3506   [(set_attr "predicable" "yes")
3507    (set_attr "predicable_short_it" "no")
3508    (set_attr "type" "logic_shift_reg")]
3511 (define_insn "*smax_m1"
3512   [(set (match_operand:SI 0 "s_register_operand" "=r")
3513         (smax:SI (match_operand:SI 1 "s_register_operand" "r")
3514                  (const_int -1)))]
3515   "TARGET_32BIT"
3516   "orr%?\\t%0, %1, %1, asr #31"
3517   [(set_attr "predicable" "yes")
3518    (set_attr "predicable_short_it" "no")
3519    (set_attr "type" "logic_shift_reg")]
3522 (define_insn_and_split "*arm_smax_insn"
3523   [(set (match_operand:SI          0 "s_register_operand" "=r,r")
3524         (smax:SI (match_operand:SI 1 "s_register_operand"  "%0,?r")
3525                  (match_operand:SI 2 "arm_rhs_operand"    "rI,rI")))
3526    (clobber (reg:CC CC_REGNUM))]
3527   "TARGET_ARM"
3528   "#"
3529    ; cmp\\t%1, %2\;movlt\\t%0, %2
3530    ; cmp\\t%1, %2\;movge\\t%0, %1\;movlt\\t%0, %2"
3531   "TARGET_ARM"
3532   [(set (reg:CC CC_REGNUM)
3533         (compare:CC (match_dup 1) (match_dup 2)))
3534    (set (match_dup 0)
3535         (if_then_else:SI (ge:SI (reg:CC CC_REGNUM) (const_int 0))
3536                          (match_dup 1)
3537                          (match_dup 2)))]
3538   ""
3539   [(set_attr "conds" "clob")
3540    (set_attr "length" "8,12")
3541    (set_attr "type" "multiple")]
3544 (define_expand "sminsi3"
3545   [(parallel [
3546     (set (match_operand:SI 0 "s_register_operand" "")
3547          (smin:SI (match_operand:SI 1 "s_register_operand" "")
3548                   (match_operand:SI 2 "arm_rhs_operand" "")))
3549     (clobber (reg:CC CC_REGNUM))])]
3550   "TARGET_32BIT"
3551   "
3552   if (operands[2] == const0_rtx)
3553     {
3554       /* No need for a clobber of the condition code register here.  */
3555       emit_insn (gen_rtx_SET (VOIDmode, operands[0],
3556                               gen_rtx_SMIN (SImode, operands[1],
3557                                             operands[2])));
3558       DONE;
3559     }
3562 (define_insn "*smin_0"
3563   [(set (match_operand:SI 0 "s_register_operand" "=r")
3564         (smin:SI (match_operand:SI 1 "s_register_operand" "r")
3565                  (const_int 0)))]
3566   "TARGET_32BIT"
3567   "and%?\\t%0, %1, %1, asr #31"
3568   [(set_attr "predicable" "yes")
3569    (set_attr "predicable_short_it" "no")
3570    (set_attr "type" "logic_shift_reg")]
3573 (define_insn_and_split "*arm_smin_insn"
3574   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3575         (smin:SI (match_operand:SI 1 "s_register_operand" "%0,?r")
3576                  (match_operand:SI 2 "arm_rhs_operand" "rI,rI")))
3577    (clobber (reg:CC CC_REGNUM))]
3578   "TARGET_ARM"
3579   "#"
3580     ; cmp\\t%1, %2\;movge\\t%0, %2
3581     ; cmp\\t%1, %2\;movlt\\t%0, %1\;movge\\t%0, %2"
3582   "TARGET_ARM"
3583   [(set (reg:CC CC_REGNUM)
3584         (compare:CC (match_dup 1) (match_dup 2)))
3585    (set (match_dup 0)
3586         (if_then_else:SI (lt:SI (reg:CC CC_REGNUM) (const_int 0))
3587                          (match_dup 1)
3588                          (match_dup 2)))]
3589   ""
3590   [(set_attr "conds" "clob")
3591    (set_attr "length" "8,12")
3592    (set_attr "type" "multiple,multiple")]
3595 (define_expand "umaxsi3"
3596   [(parallel [
3597     (set (match_operand:SI 0 "s_register_operand" "")
3598          (umax:SI (match_operand:SI 1 "s_register_operand" "")
3599                   (match_operand:SI 2 "arm_rhs_operand" "")))
3600     (clobber (reg:CC CC_REGNUM))])]
3601   "TARGET_32BIT"
3602   ""
3605 (define_insn_and_split "*arm_umaxsi3"
3606   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
3607         (umax:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
3608                  (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
3609    (clobber (reg:CC CC_REGNUM))]
3610   "TARGET_ARM"
3611   "#"
3612     ; cmp\\t%1, %2\;movcc\\t%0, %2
3613     ; cmp\\t%1, %2\;movcs\\t%0, %1
3614     ; cmp\\t%1, %2\;movcs\\t%0, %1\;movcc\\t%0, %2"
3615   "TARGET_ARM"
3616   [(set (reg:CC CC_REGNUM)
3617         (compare:CC (match_dup 1) (match_dup 2)))
3618    (set (match_dup 0)
3619         (if_then_else:SI (geu:SI (reg:CC CC_REGNUM) (const_int 0))
3620                          (match_dup 1)
3621                          (match_dup 2)))]
3622   ""
3623   [(set_attr "conds" "clob")
3624    (set_attr "length" "8,8,12")
3625    (set_attr "type" "store1")]
3628 (define_expand "uminsi3"
3629   [(parallel [
3630     (set (match_operand:SI 0 "s_register_operand" "")
3631          (umin:SI (match_operand:SI 1 "s_register_operand" "")
3632                   (match_operand:SI 2 "arm_rhs_operand" "")))
3633     (clobber (reg:CC CC_REGNUM))])]
3634   "TARGET_32BIT"
3635   ""
3638 (define_insn_and_split "*arm_uminsi3"
3639   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
3640         (umin:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
3641                  (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
3642    (clobber (reg:CC CC_REGNUM))]
3643   "TARGET_ARM"
3644   "#"
3645    ; cmp\\t%1, %2\;movcs\\t%0, %2
3646    ; cmp\\t%1, %2\;movcc\\t%0, %1
3647    ; cmp\\t%1, %2\;movcc\\t%0, %1\;movcs\\t%0, %2"
3648   "TARGET_ARM"
3649   [(set (reg:CC CC_REGNUM)
3650         (compare:CC (match_dup 1) (match_dup 2)))
3651    (set (match_dup 0)
3652         (if_then_else:SI (ltu:SI (reg:CC CC_REGNUM) (const_int 0))
3653                          (match_dup 1)
3654                          (match_dup 2)))]
3655   ""
3656   [(set_attr "conds" "clob")
3657    (set_attr "length" "8,8,12")
3658    (set_attr "type" "store1")]
3661 (define_insn "*store_minmaxsi"
3662   [(set (match_operand:SI 0 "memory_operand" "=m")
3663         (match_operator:SI 3 "minmax_operator"
3664          [(match_operand:SI 1 "s_register_operand" "r")
3665           (match_operand:SI 2 "s_register_operand" "r")]))
3666    (clobber (reg:CC CC_REGNUM))]
3667   "TARGET_32BIT && optimize_function_for_size_p (cfun) && !arm_restrict_it"
3668   "*
3669   operands[3] = gen_rtx_fmt_ee (minmax_code (operands[3]), SImode,
3670                                 operands[1], operands[2]);
3671   output_asm_insn (\"cmp\\t%1, %2\", operands);
3672   if (TARGET_THUMB2)
3673     output_asm_insn (\"ite\t%d3\", operands);
3674   output_asm_insn (\"str%d3\\t%1, %0\", operands);
3675   output_asm_insn (\"str%D3\\t%2, %0\", operands);
3676   return \"\";
3677   "
3678   [(set_attr "conds" "clob")
3679    (set (attr "length")
3680         (if_then_else (eq_attr "is_thumb" "yes")
3681                       (const_int 14)
3682                       (const_int 12)))
3683    (set_attr "type" "store1")]
3686 ; Reject the frame pointer in operand[1], since reloading this after
3687 ; it has been eliminated can cause carnage.
3688 (define_insn "*minmax_arithsi"
3689   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3690         (match_operator:SI 4 "shiftable_operator"
3691          [(match_operator:SI 5 "minmax_operator"
3692            [(match_operand:SI 2 "s_register_operand" "r,r")
3693             (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
3694           (match_operand:SI 1 "s_register_operand" "0,?r")]))
3695    (clobber (reg:CC CC_REGNUM))]
3696   "TARGET_32BIT && !arm_eliminable_register (operands[1]) && !arm_restrict_it"
3697   "*
3698   {
3699     enum rtx_code code = GET_CODE (operands[4]);
3700     bool need_else;
3702     if (which_alternative != 0 || operands[3] != const0_rtx
3703         || (code != PLUS && code != IOR && code != XOR))
3704       need_else = true;
3705     else
3706       need_else = false;
3708     operands[5] = gen_rtx_fmt_ee (minmax_code (operands[5]), SImode,
3709                                   operands[2], operands[3]);
3710     output_asm_insn (\"cmp\\t%2, %3\", operands);
3711     if (TARGET_THUMB2)
3712       {
3713         if (need_else)
3714           output_asm_insn (\"ite\\t%d5\", operands);
3715         else
3716           output_asm_insn (\"it\\t%d5\", operands);
3717       }
3718     output_asm_insn (\"%i4%d5\\t%0, %1, %2\", operands);
3719     if (need_else)
3720       output_asm_insn (\"%i4%D5\\t%0, %1, %3\", operands);
3721     return \"\";
3722   }"
3723   [(set_attr "conds" "clob")
3724    (set (attr "length")
3725         (if_then_else (eq_attr "is_thumb" "yes")
3726                       (const_int 14)
3727                       (const_int 12)))
3728    (set_attr "type" "multiple")]
3731 ; Reject the frame pointer in operand[1], since reloading this after
3732 ; it has been eliminated can cause carnage.
3733 (define_insn_and_split "*minmax_arithsi_non_canon"
3734   [(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts")
3735         (minus:SI
3736          (match_operand:SI 1 "s_register_operand" "0,?Ts")
3737           (match_operator:SI 4 "minmax_operator"
3738            [(match_operand:SI 2 "s_register_operand" "Ts,Ts")
3739             (match_operand:SI 3 "arm_rhs_operand" "TsI,TsI")])))
3740    (clobber (reg:CC CC_REGNUM))]
3741   "TARGET_32BIT && !arm_eliminable_register (operands[1])
3742    && !(arm_restrict_it && CONST_INT_P (operands[3]))"
3743   "#"
3744   "TARGET_32BIT && !arm_eliminable_register (operands[1]) && reload_completed"
3745   [(set (reg:CC CC_REGNUM)
3746         (compare:CC (match_dup 2) (match_dup 3)))
3748    (cond_exec (match_op_dup 4 [(reg:CC CC_REGNUM) (const_int 0)])
3749               (set (match_dup 0)
3750                    (minus:SI (match_dup 1)
3751                              (match_dup 2))))
3752    (cond_exec (match_op_dup 5 [(reg:CC CC_REGNUM) (const_int 0)])
3753               (set (match_dup 0)
3754                    (match_dup 6)))]
3755   {
3756   enum machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
3757                                            operands[2], operands[3]);
3758   enum rtx_code rc = minmax_code (operands[4]);
3759   operands[4] = gen_rtx_fmt_ee (rc, VOIDmode,
3760                                 operands[2], operands[3]);
3762   if (mode == CCFPmode || mode == CCFPEmode)
3763     rc = reverse_condition_maybe_unordered (rc);
3764   else
3765     rc = reverse_condition (rc);
3766   operands[5] = gen_rtx_fmt_ee (rc, SImode, operands[2], operands[3]);
3767   if (CONST_INT_P (operands[3]))
3768     operands[6] = plus_constant (SImode, operands[1], -INTVAL (operands[3]));
3769   else
3770     operands[6] = gen_rtx_MINUS (SImode, operands[1], operands[3]);
3771   }
3772   [(set_attr "conds" "clob")
3773    (set (attr "length")
3774         (if_then_else (eq_attr "is_thumb" "yes")
3775                       (const_int 14)
3776                       (const_int 12)))
3777    (set_attr "type" "multiple")]
3780 (define_code_iterator SAT [smin smax])
3781 (define_code_iterator SATrev [smin smax])
3782 (define_code_attr SATlo [(smin "1") (smax "2")])
3783 (define_code_attr SAThi [(smin "2") (smax "1")])
3785 (define_insn "*satsi_<SAT:code>"
3786   [(set (match_operand:SI 0 "s_register_operand" "=r")
3787         (SAT:SI (SATrev:SI (match_operand:SI 3 "s_register_operand" "r")
3788                            (match_operand:SI 1 "const_int_operand" "i"))
3789                 (match_operand:SI 2 "const_int_operand" "i")))]
3790   "TARGET_32BIT && arm_arch6 && <SAT:CODE> != <SATrev:CODE>
3791    && arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>], NULL, NULL)"
3793   int mask;
3794   bool signed_sat;
3795   if (!arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>],
3796                                &mask, &signed_sat))
3797     gcc_unreachable ();
3799   operands[1] = GEN_INT (mask);
3800   if (signed_sat)
3801     return "ssat%?\t%0, %1, %3";
3802   else
3803     return "usat%?\t%0, %1, %3";
3805   [(set_attr "predicable" "yes")
3806    (set_attr "predicable_short_it" "no")
3807    (set_attr "type" "alus_imm")]
3810 (define_insn "*satsi_<SAT:code>_shift"
3811   [(set (match_operand:SI 0 "s_register_operand" "=r")
3812         (SAT:SI (SATrev:SI (match_operator:SI 3 "sat_shift_operator"
3813                              [(match_operand:SI 4 "s_register_operand" "r")
3814                               (match_operand:SI 5 "const_int_operand" "i")])
3815                            (match_operand:SI 1 "const_int_operand" "i"))
3816                 (match_operand:SI 2 "const_int_operand" "i")))]
3817   "TARGET_32BIT && arm_arch6 && <SAT:CODE> != <SATrev:CODE>
3818    && arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>], NULL, NULL)"
3820   int mask;
3821   bool signed_sat;
3822   if (!arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>],
3823                                &mask, &signed_sat))
3824     gcc_unreachable ();
3826   operands[1] = GEN_INT (mask);
3827   if (signed_sat)
3828     return "ssat%?\t%0, %1, %4%S3";
3829   else
3830     return "usat%?\t%0, %1, %4%S3";
3832   [(set_attr "predicable" "yes")
3833    (set_attr "predicable_short_it" "no")
3834    (set_attr "shift" "3")
3835    (set_attr "type" "logic_shift_reg")])
3837 ;; Shift and rotation insns
3839 (define_expand "ashldi3"
3840   [(set (match_operand:DI            0 "s_register_operand" "")
3841         (ashift:DI (match_operand:DI 1 "s_register_operand" "")
3842                    (match_operand:SI 2 "general_operand" "")))]
3843   "TARGET_32BIT"
3844   "
3845   if (TARGET_NEON)
3846     {
3847       /* Delay the decision whether to use NEON or core-regs until
3848          register allocation.  */
3849       emit_insn (gen_ashldi3_neon (operands[0], operands[1], operands[2]));
3850       DONE;
3851     }
3852   else
3853     {
3854       /* Only the NEON case can handle in-memory shift counts.  */
3855       if (!reg_or_int_operand (operands[2], SImode))
3856         operands[2] = force_reg (SImode, operands[2]);
3857     }
3859   if (!CONST_INT_P (operands[2]) && TARGET_REALLY_IWMMXT)
3860     ; /* No special preparation statements; expand pattern as above.  */
3861   else
3862     {
3863       rtx scratch1, scratch2;
3865       if (CONST_INT_P (operands[2])
3866           && (HOST_WIDE_INT) INTVAL (operands[2]) == 1)
3867         {
3868           emit_insn (gen_arm_ashldi3_1bit (operands[0], operands[1]));
3869           DONE;
3870         }
3872       /* Ideally we should use iwmmxt here if we could know that operands[1]
3873          ends up already living in an iwmmxt register. Otherwise it's
3874          cheaper to have the alternate code being generated than moving
3875          values to iwmmxt regs and back.  */
3877       /* If we're optimizing for size, we prefer the libgcc calls.  */
3878       if (optimize_function_for_size_p (cfun))
3879         FAIL;
3881       /* Expand operation using core-registers.
3882          'FAIL' would achieve the same thing, but this is a bit smarter.  */
3883       scratch1 = gen_reg_rtx (SImode);
3884       scratch2 = gen_reg_rtx (SImode);
3885       arm_emit_coreregs_64bit_shift (ASHIFT, operands[0], operands[1],
3886                                      operands[2], scratch1, scratch2);
3887       DONE;
3888     }
3889   "
3892 (define_insn "arm_ashldi3_1bit"
3893   [(set (match_operand:DI            0 "s_register_operand" "=r,&r")
3894         (ashift:DI (match_operand:DI 1 "s_register_operand" "0,r")
3895                    (const_int 1)))
3896    (clobber (reg:CC CC_REGNUM))]
3897   "TARGET_32BIT"
3898   "movs\\t%Q0, %Q1, asl #1\;adc\\t%R0, %R1, %R1"
3899   [(set_attr "conds" "clob")
3900    (set_attr "length" "8")
3901    (set_attr "type" "multiple")]
3904 (define_expand "ashlsi3"
3905   [(set (match_operand:SI            0 "s_register_operand" "")
3906         (ashift:SI (match_operand:SI 1 "s_register_operand" "")
3907                    (match_operand:SI 2 "arm_rhs_operand" "")))]
3908   "TARGET_EITHER"
3909   "
3910   if (CONST_INT_P (operands[2])
3911       && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) > 31)
3912     {
3913       emit_insn (gen_movsi (operands[0], const0_rtx));
3914       DONE;
3915     }
3916   "
3919 (define_insn "*thumb1_ashlsi3"
3920   [(set (match_operand:SI            0 "register_operand" "=l,l")
3921         (ashift:SI (match_operand:SI 1 "register_operand" "l,0")
3922                    (match_operand:SI 2 "nonmemory_operand" "N,l")))]
3923   "TARGET_THUMB1"
3924   "lsl\\t%0, %1, %2"
3925   [(set_attr "length" "2")
3926    (set_attr "type" "shift_imm,shift_reg")
3927    (set_attr "conds" "set")])
3929 (define_expand "ashrdi3"
3930   [(set (match_operand:DI              0 "s_register_operand" "")
3931         (ashiftrt:DI (match_operand:DI 1 "s_register_operand" "")
3932                      (match_operand:SI 2 "reg_or_int_operand" "")))]
3933   "TARGET_32BIT"
3934   "
3935   if (TARGET_NEON)
3936     {
3937       /* Delay the decision whether to use NEON or core-regs until
3938          register allocation.  */
3939       emit_insn (gen_ashrdi3_neon (operands[0], operands[1], operands[2]));
3940       DONE;
3941     }
3943   if (!CONST_INT_P (operands[2]) && TARGET_REALLY_IWMMXT)
3944     ; /* No special preparation statements; expand pattern as above.  */
3945   else
3946     {
3947       rtx scratch1, scratch2;
3949       if (CONST_INT_P (operands[2])
3950           && (HOST_WIDE_INT) INTVAL (operands[2]) == 1)
3951         {
3952           emit_insn (gen_arm_ashrdi3_1bit (operands[0], operands[1]));
3953           DONE;
3954         }
3956       /* Ideally we should use iwmmxt here if we could know that operands[1]
3957          ends up already living in an iwmmxt register. Otherwise it's
3958          cheaper to have the alternate code being generated than moving
3959          values to iwmmxt regs and back.  */
3961       /* If we're optimizing for size, we prefer the libgcc calls.  */
3962       if (optimize_function_for_size_p (cfun))
3963         FAIL;
3965       /* Expand operation using core-registers.
3966          'FAIL' would achieve the same thing, but this is a bit smarter.  */
3967       scratch1 = gen_reg_rtx (SImode);
3968       scratch2 = gen_reg_rtx (SImode);
3969       arm_emit_coreregs_64bit_shift (ASHIFTRT, operands[0], operands[1],
3970                                      operands[2], scratch1, scratch2);
3971       DONE;
3972     }
3973   "
3976 (define_insn "arm_ashrdi3_1bit"
3977   [(set (match_operand:DI              0 "s_register_operand" "=r,&r")
3978         (ashiftrt:DI (match_operand:DI 1 "s_register_operand" "0,r")
3979                      (const_int 1)))
3980    (clobber (reg:CC CC_REGNUM))]
3981   "TARGET_32BIT"
3982   "movs\\t%R0, %R1, asr #1\;mov\\t%Q0, %Q1, rrx"
3983   [(set_attr "conds" "clob")
3984    (set_attr "length" "8")
3985    (set_attr "type" "multiple")]
3988 (define_expand "ashrsi3"
3989   [(set (match_operand:SI              0 "s_register_operand" "")
3990         (ashiftrt:SI (match_operand:SI 1 "s_register_operand" "")
3991                      (match_operand:SI 2 "arm_rhs_operand" "")))]
3992   "TARGET_EITHER"
3993   "
3994   if (CONST_INT_P (operands[2])
3995       && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) > 31)
3996     operands[2] = GEN_INT (31);
3997   "
4000 (define_insn "*thumb1_ashrsi3"
4001   [(set (match_operand:SI              0 "register_operand" "=l,l")
4002         (ashiftrt:SI (match_operand:SI 1 "register_operand" "l,0")
4003                      (match_operand:SI 2 "nonmemory_operand" "N,l")))]
4004   "TARGET_THUMB1"
4005   "asr\\t%0, %1, %2"
4006   [(set_attr "length" "2")
4007    (set_attr "type" "shift_imm,shift_reg")
4008    (set_attr "conds" "set")])
4010 (define_expand "lshrdi3"
4011   [(set (match_operand:DI              0 "s_register_operand" "")
4012         (lshiftrt:DI (match_operand:DI 1 "s_register_operand" "")
4013                      (match_operand:SI 2 "reg_or_int_operand" "")))]
4014   "TARGET_32BIT"
4015   "
4016   if (TARGET_NEON)
4017     {
4018       /* Delay the decision whether to use NEON or core-regs until
4019          register allocation.  */
4020       emit_insn (gen_lshrdi3_neon (operands[0], operands[1], operands[2]));
4021       DONE;
4022     }
4024   if (!CONST_INT_P (operands[2]) && TARGET_REALLY_IWMMXT)
4025     ; /* No special preparation statements; expand pattern as above.  */
4026   else
4027     {
4028       rtx scratch1, scratch2;
4030       if (CONST_INT_P (operands[2])
4031           && (HOST_WIDE_INT) INTVAL (operands[2]) == 1)
4032         {
4033           emit_insn (gen_arm_lshrdi3_1bit (operands[0], operands[1]));
4034           DONE;
4035         }
4037       /* Ideally we should use iwmmxt here if we could know that operands[1]
4038          ends up already living in an iwmmxt register. Otherwise it's
4039          cheaper to have the alternate code being generated than moving
4040          values to iwmmxt regs and back.  */
4042       /* If we're optimizing for size, we prefer the libgcc calls.  */
4043       if (optimize_function_for_size_p (cfun))
4044         FAIL;
4046       /* Expand operation using core-registers.
4047          'FAIL' would achieve the same thing, but this is a bit smarter.  */
4048       scratch1 = gen_reg_rtx (SImode);
4049       scratch2 = gen_reg_rtx (SImode);
4050       arm_emit_coreregs_64bit_shift (LSHIFTRT, operands[0], operands[1],
4051                                      operands[2], scratch1, scratch2);
4052       DONE;
4053     }
4054   "
4057 (define_insn "arm_lshrdi3_1bit"
4058   [(set (match_operand:DI              0 "s_register_operand" "=r,&r")
4059         (lshiftrt:DI (match_operand:DI 1 "s_register_operand" "0,r")
4060                      (const_int 1)))
4061    (clobber (reg:CC CC_REGNUM))]
4062   "TARGET_32BIT"
4063   "movs\\t%R0, %R1, lsr #1\;mov\\t%Q0, %Q1, rrx"
4064   [(set_attr "conds" "clob")
4065    (set_attr "length" "8")
4066    (set_attr "type" "multiple")]
4069 (define_expand "lshrsi3"
4070   [(set (match_operand:SI              0 "s_register_operand" "")
4071         (lshiftrt:SI (match_operand:SI 1 "s_register_operand" "")
4072                      (match_operand:SI 2 "arm_rhs_operand" "")))]
4073   "TARGET_EITHER"
4074   "
4075   if (CONST_INT_P (operands[2])
4076       && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) > 31)
4077     {
4078       emit_insn (gen_movsi (operands[0], const0_rtx));
4079       DONE;
4080     }
4081   "
4084 (define_insn "*thumb1_lshrsi3"
4085   [(set (match_operand:SI              0 "register_operand" "=l,l")
4086         (lshiftrt:SI (match_operand:SI 1 "register_operand" "l,0")
4087                      (match_operand:SI 2 "nonmemory_operand" "N,l")))]
4088   "TARGET_THUMB1"
4089   "lsr\\t%0, %1, %2"
4090   [(set_attr "length" "2")
4091    (set_attr "type" "shift_imm,shift_reg")
4092    (set_attr "conds" "set")])
4094 (define_expand "rotlsi3"
4095   [(set (match_operand:SI              0 "s_register_operand" "")
4096         (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
4097                      (match_operand:SI 2 "reg_or_int_operand" "")))]
4098   "TARGET_32BIT"
4099   "
4100   if (CONST_INT_P (operands[2]))
4101     operands[2] = GEN_INT ((32 - INTVAL (operands[2])) % 32);
4102   else
4103     {
4104       rtx reg = gen_reg_rtx (SImode);
4105       emit_insn (gen_subsi3 (reg, GEN_INT (32), operands[2]));
4106       operands[2] = reg;
4107     }
4108   "
4111 (define_expand "rotrsi3"
4112   [(set (match_operand:SI              0 "s_register_operand" "")
4113         (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
4114                      (match_operand:SI 2 "arm_rhs_operand" "")))]
4115   "TARGET_EITHER"
4116   "
4117   if (TARGET_32BIT)
4118     {
4119       if (CONST_INT_P (operands[2])
4120           && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) > 31)
4121         operands[2] = GEN_INT (INTVAL (operands[2]) % 32);
4122     }
4123   else /* TARGET_THUMB1 */
4124     {
4125       if (CONST_INT_P (operands [2]))
4126         operands [2] = force_reg (SImode, operands[2]);
4127     }
4128   "
4131 (define_insn "*thumb1_rotrsi3"
4132   [(set (match_operand:SI              0 "register_operand" "=l")
4133         (rotatert:SI (match_operand:SI 1 "register_operand" "0")
4134                      (match_operand:SI 2 "register_operand" "l")))]
4135   "TARGET_THUMB1"
4136   "ror\\t%0, %0, %2"
4137   [(set_attr "type" "shift_reg")
4138    (set_attr "length" "2")]
4141 (define_insn "*arm_shiftsi3"
4142   [(set (match_operand:SI   0 "s_register_operand" "=l,l,r,r")
4143         (match_operator:SI  3 "shift_operator"
4144          [(match_operand:SI 1 "s_register_operand"  "0,l,r,r")
4145           (match_operand:SI 2 "reg_or_int_operand" "l,M,M,r")]))]
4146   "TARGET_32BIT"
4147   "* return arm_output_shift(operands, 0);"
4148   [(set_attr "predicable" "yes")
4149    (set_attr "arch" "t2,t2,*,*")
4150    (set_attr "predicable_short_it" "yes,yes,no,no")
4151    (set_attr "length" "4")
4152    (set_attr "shift" "1")
4153    (set_attr "type" "alu_shift_reg,alu_shift_imm,alu_shift_imm,alu_shift_reg")]
4156 (define_insn "*shiftsi3_compare0"
4157   [(set (reg:CC_NOOV CC_REGNUM)
4158         (compare:CC_NOOV (match_operator:SI 3 "shift_operator"
4159                           [(match_operand:SI 1 "s_register_operand" "r,r")
4160                            (match_operand:SI 2 "arm_rhs_operand" "M,r")])
4161                          (const_int 0)))
4162    (set (match_operand:SI 0 "s_register_operand" "=r,r")
4163         (match_op_dup 3 [(match_dup 1) (match_dup 2)]))]
4164   "TARGET_32BIT"
4165   "* return arm_output_shift(operands, 1);"
4166   [(set_attr "conds" "set")
4167    (set_attr "shift" "1")
4168    (set_attr "type" "alus_shift_imm,alus_shift_reg")]
4171 (define_insn "*shiftsi3_compare0_scratch"
4172   [(set (reg:CC_NOOV CC_REGNUM)
4173         (compare:CC_NOOV (match_operator:SI 3 "shift_operator"
4174                           [(match_operand:SI 1 "s_register_operand" "r,r")
4175                            (match_operand:SI 2 "arm_rhs_operand" "M,r")])
4176                          (const_int 0)))
4177    (clobber (match_scratch:SI 0 "=r,r"))]
4178   "TARGET_32BIT"
4179   "* return arm_output_shift(operands, 1);"
4180   [(set_attr "conds" "set")
4181    (set_attr "shift" "1")
4182    (set_attr "type" "shift_imm,shift_reg")]
4185 (define_insn "*not_shiftsi"
4186   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4187         (not:SI (match_operator:SI 3 "shift_operator"
4188                  [(match_operand:SI 1 "s_register_operand" "r,r")
4189                   (match_operand:SI 2 "shift_amount_operand" "M,rM")])))]
4190   "TARGET_32BIT"
4191   "mvn%?\\t%0, %1%S3"
4192   [(set_attr "predicable" "yes")
4193    (set_attr "predicable_short_it" "no")
4194    (set_attr "shift" "1")
4195    (set_attr "arch" "32,a")
4196    (set_attr "type" "mvn_shift,mvn_shift_reg")])
4198 (define_insn "*not_shiftsi_compare0"
4199   [(set (reg:CC_NOOV CC_REGNUM)
4200         (compare:CC_NOOV
4201          (not:SI (match_operator:SI 3 "shift_operator"
4202                   [(match_operand:SI 1 "s_register_operand" "r,r")
4203                    (match_operand:SI 2 "shift_amount_operand" "M,rM")]))
4204          (const_int 0)))
4205    (set (match_operand:SI 0 "s_register_operand" "=r,r")
4206         (not:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])))]
4207   "TARGET_32BIT"
4208   "mvn%.\\t%0, %1%S3"
4209   [(set_attr "conds" "set")
4210    (set_attr "shift" "1")
4211    (set_attr "arch" "32,a")
4212    (set_attr "type" "mvn_shift,mvn_shift_reg")])
4214 (define_insn "*not_shiftsi_compare0_scratch"
4215   [(set (reg:CC_NOOV CC_REGNUM)
4216         (compare:CC_NOOV
4217          (not:SI (match_operator:SI 3 "shift_operator"
4218                   [(match_operand:SI 1 "s_register_operand" "r,r")
4219                    (match_operand:SI 2 "shift_amount_operand" "M,rM")]))
4220          (const_int 0)))
4221    (clobber (match_scratch:SI 0 "=r,r"))]
4222   "TARGET_32BIT"
4223   "mvn%.\\t%0, %1%S3"
4224   [(set_attr "conds" "set")
4225    (set_attr "shift" "1")
4226    (set_attr "arch" "32,a")
4227    (set_attr "type" "mvn_shift,mvn_shift_reg")])
4229 ;; We don't really have extzv, but defining this using shifts helps
4230 ;; to reduce register pressure later on.
4232 (define_expand "extzv"
4233   [(set (match_operand 0 "s_register_operand" "")
4234         (zero_extract (match_operand 1 "nonimmediate_operand" "")
4235                       (match_operand 2 "const_int_operand" "")
4236                       (match_operand 3 "const_int_operand" "")))]
4237   "TARGET_THUMB1 || arm_arch_thumb2"
4238   "
4239   {
4240     HOST_WIDE_INT lshift = 32 - INTVAL (operands[2]) - INTVAL (operands[3]);
4241     HOST_WIDE_INT rshift = 32 - INTVAL (operands[2]);
4242     
4243     if (arm_arch_thumb2)
4244       {
4245         HOST_WIDE_INT width = INTVAL (operands[2]);
4246         HOST_WIDE_INT bitpos = INTVAL (operands[3]);
4248         if (unaligned_access && MEM_P (operands[1])
4249             && (width == 16 || width == 32) && (bitpos % BITS_PER_UNIT) == 0)
4250           {
4251             rtx base_addr;
4253             if (BYTES_BIG_ENDIAN)
4254               bitpos = GET_MODE_BITSIZE (GET_MODE (operands[0])) - width
4255                        - bitpos;
4257             if (width == 32)
4258               {
4259                 base_addr = adjust_address (operands[1], SImode,
4260                                             bitpos / BITS_PER_UNIT);
4261                 emit_insn (gen_unaligned_loadsi (operands[0], base_addr));
4262               }
4263             else
4264               {
4265                 rtx dest = operands[0];
4266                 rtx tmp = gen_reg_rtx (SImode);
4268                 /* We may get a paradoxical subreg here.  Strip it off.  */
4269                 if (GET_CODE (dest) == SUBREG
4270                     && GET_MODE (dest) == SImode
4271                     && GET_MODE (SUBREG_REG (dest)) == HImode)
4272                   dest = SUBREG_REG (dest);
4274                 if (GET_MODE_BITSIZE (GET_MODE (dest)) != width)
4275                   FAIL;
4277                 base_addr = adjust_address (operands[1], HImode,
4278                                             bitpos / BITS_PER_UNIT);
4279                 emit_insn (gen_unaligned_loadhiu (tmp, base_addr));
4280                 emit_move_insn (gen_lowpart (SImode, dest), tmp);
4281               }
4282             DONE;
4283           }
4284         else if (s_register_operand (operands[1], GET_MODE (operands[1])))
4285           {
4286             emit_insn (gen_extzv_t2 (operands[0], operands[1], operands[2],
4287                                      operands[3]));
4288             DONE;
4289           }
4290         else
4291           FAIL;
4292       }
4293     
4294     if (!s_register_operand (operands[1], GET_MODE (operands[1])))
4295       FAIL;
4297     operands[3] = GEN_INT (rshift);
4298     
4299     if (lshift == 0)
4300       {
4301         emit_insn (gen_lshrsi3 (operands[0], operands[1], operands[3]));
4302         DONE;
4303       }
4304       
4305     emit_insn (gen_extzv_t1 (operands[0], operands[1], GEN_INT (lshift),
4306                              operands[3], gen_reg_rtx (SImode)));
4307     DONE;
4308   }"
4311 ;; Helper for extzv, for the Thumb-1 register-shifts case.
4313 (define_expand "extzv_t1"
4314   [(set (match_operand:SI 4 "s_register_operand" "")
4315         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
4316                    (match_operand:SI 2 "const_int_operand" "")))
4317    (set (match_operand:SI 0 "s_register_operand" "")
4318         (lshiftrt:SI (match_dup 4)
4319                      (match_operand:SI 3 "const_int_operand" "")))]
4320   "TARGET_THUMB1"
4321   "")
4323 (define_expand "extv"
4324   [(set (match_operand 0 "s_register_operand" "")
4325         (sign_extract (match_operand 1 "nonimmediate_operand" "")
4326                       (match_operand 2 "const_int_operand" "")
4327                       (match_operand 3 "const_int_operand" "")))]
4328   "arm_arch_thumb2"
4330   HOST_WIDE_INT width = INTVAL (operands[2]);
4331   HOST_WIDE_INT bitpos = INTVAL (operands[3]);
4333   if (unaligned_access && MEM_P (operands[1]) && (width == 16 || width == 32)
4334       && (bitpos % BITS_PER_UNIT)  == 0)
4335     {
4336       rtx base_addr;
4337       
4338       if (BYTES_BIG_ENDIAN)
4339         bitpos = GET_MODE_BITSIZE (GET_MODE (operands[0])) - width - bitpos;
4340       
4341       if (width == 32)
4342         {
4343           base_addr = adjust_address (operands[1], SImode,
4344                                       bitpos / BITS_PER_UNIT);
4345           emit_insn (gen_unaligned_loadsi (operands[0], base_addr));
4346         }
4347       else
4348         {
4349           rtx dest = operands[0];
4350           rtx tmp = gen_reg_rtx (SImode);
4351           
4352           /* We may get a paradoxical subreg here.  Strip it off.  */
4353           if (GET_CODE (dest) == SUBREG
4354               && GET_MODE (dest) == SImode
4355               && GET_MODE (SUBREG_REG (dest)) == HImode)
4356             dest = SUBREG_REG (dest);
4357           
4358           if (GET_MODE_BITSIZE (GET_MODE (dest)) != width)
4359             FAIL;
4360           
4361           base_addr = adjust_address (operands[1], HImode,
4362                                       bitpos / BITS_PER_UNIT);
4363           emit_insn (gen_unaligned_loadhis (tmp, base_addr));
4364           emit_move_insn (gen_lowpart (SImode, dest), tmp);
4365         }
4367       DONE;
4368     }
4369   else if (!s_register_operand (operands[1], GET_MODE (operands[1])))
4370     FAIL;
4371   else if (GET_MODE (operands[0]) == SImode
4372            && GET_MODE (operands[1]) == SImode)
4373     {
4374       emit_insn (gen_extv_regsi (operands[0], operands[1], operands[2],
4375                                  operands[3]));
4376       DONE;
4377     }
4379   FAIL;
4382 ; Helper to expand register forms of extv with the proper modes.
4384 (define_expand "extv_regsi"
4385   [(set (match_operand:SI 0 "s_register_operand" "")
4386         (sign_extract:SI (match_operand:SI 1 "s_register_operand" "")
4387                          (match_operand 2 "const_int_operand" "")
4388                          (match_operand 3 "const_int_operand" "")))]
4389   ""
4393 ; ARMv6+ unaligned load/store instructions (used for packed structure accesses).
4395 (define_insn "unaligned_loadsi"
4396   [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4397         (unspec:SI [(match_operand:SI 1 "memory_operand" "Uw,m")]
4398                    UNSPEC_UNALIGNED_LOAD))]
4399   "unaligned_access && TARGET_32BIT"
4400   "ldr%?\t%0, %1\t@ unaligned"
4401   [(set_attr "arch" "t2,any")
4402    (set_attr "length" "2,4")
4403    (set_attr "predicable" "yes")
4404    (set_attr "predicable_short_it" "yes,no")
4405    (set_attr "type" "load1")])
4407 (define_insn "unaligned_loadhis"
4408   [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4409         (sign_extend:SI
4410           (unspec:HI [(match_operand:HI 1 "memory_operand" "Uw,Uh")]
4411                      UNSPEC_UNALIGNED_LOAD)))]
4412   "unaligned_access && TARGET_32BIT"
4413   "ldr%(sh%)\t%0, %1\t@ unaligned"
4414   [(set_attr "arch" "t2,any")
4415    (set_attr "length" "2,4")
4416    (set_attr "predicable" "yes")
4417    (set_attr "predicable_short_it" "yes,no")
4418    (set_attr "type" "load_byte")])
4420 (define_insn "unaligned_loadhiu"
4421   [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4422         (zero_extend:SI
4423           (unspec:HI [(match_operand:HI 1 "memory_operand" "Uw,m")]
4424                      UNSPEC_UNALIGNED_LOAD)))]
4425   "unaligned_access && TARGET_32BIT"
4426   "ldr%(h%)\t%0, %1\t@ unaligned"
4427   [(set_attr "arch" "t2,any")
4428    (set_attr "length" "2,4")
4429    (set_attr "predicable" "yes")
4430    (set_attr "predicable_short_it" "yes,no")
4431    (set_attr "type" "load_byte")])
4433 (define_insn "unaligned_storesi"
4434   [(set (match_operand:SI 0 "memory_operand" "=Uw,m")
4435         (unspec:SI [(match_operand:SI 1 "s_register_operand" "l,r")]
4436                    UNSPEC_UNALIGNED_STORE))]
4437   "unaligned_access && TARGET_32BIT"
4438   "str%?\t%1, %0\t@ unaligned"
4439   [(set_attr "arch" "t2,any")
4440    (set_attr "length" "2,4")
4441    (set_attr "predicable" "yes")
4442    (set_attr "predicable_short_it" "yes,no")
4443    (set_attr "type" "store1")])
4445 (define_insn "unaligned_storehi"
4446   [(set (match_operand:HI 0 "memory_operand" "=Uw,m")
4447         (unspec:HI [(match_operand:HI 1 "s_register_operand" "l,r")]
4448                    UNSPEC_UNALIGNED_STORE))]
4449   "unaligned_access && TARGET_32BIT"
4450   "str%(h%)\t%1, %0\t@ unaligned"
4451   [(set_attr "arch" "t2,any")
4452    (set_attr "length" "2,4")
4453    (set_attr "predicable" "yes")
4454    (set_attr "predicable_short_it" "yes,no")
4455    (set_attr "type" "store1")])
4457 ;; Unaligned double-word load and store.
4458 ;; Split after reload into two unaligned single-word accesses.
4459 ;; It prevents lower_subreg from splitting some other aligned
4460 ;; double-word accesses too early. Used for internal memcpy.
4462 (define_insn_and_split "unaligned_loaddi"
4463   [(set (match_operand:DI 0 "s_register_operand" "=l,r")
4464         (unspec:DI [(match_operand:DI 1 "memory_operand" "o,o")]
4465                    UNSPEC_UNALIGNED_LOAD))]
4466   "unaligned_access && TARGET_32BIT"
4467   "#"
4468   "&& reload_completed"
4469   [(set (match_dup 0) (unspec:SI [(match_dup 1)] UNSPEC_UNALIGNED_LOAD))
4470    (set (match_dup 2) (unspec:SI [(match_dup 3)] UNSPEC_UNALIGNED_LOAD))]
4471   {
4472     operands[2] = gen_highpart (SImode, operands[0]);
4473     operands[0] = gen_lowpart (SImode, operands[0]);
4474     operands[3] = gen_highpart (SImode, operands[1]);
4475     operands[1] = gen_lowpart (SImode, operands[1]);
4477     /* If the first destination register overlaps with the base address,
4478        swap the order in which the loads are emitted.  */
4479     if (reg_overlap_mentioned_p (operands[0], operands[1]))
4480       {
4481         rtx tmp = operands[1];
4482         operands[1] = operands[3];
4483         operands[3] = tmp;
4484         tmp = operands[0];
4485         operands[0] = operands[2];
4486         operands[2] = tmp;
4487       }
4488   }
4489   [(set_attr "arch" "t2,any")
4490    (set_attr "length" "4,8")
4491    (set_attr "predicable" "yes")
4492    (set_attr "type" "load2")])
4494 (define_insn_and_split "unaligned_storedi"
4495   [(set (match_operand:DI 0 "memory_operand" "=o,o")
4496         (unspec:DI [(match_operand:DI 1 "s_register_operand" "l,r")]
4497                    UNSPEC_UNALIGNED_STORE))]
4498   "unaligned_access && TARGET_32BIT"
4499   "#"
4500   "&& reload_completed"
4501   [(set (match_dup 0) (unspec:SI [(match_dup 1)] UNSPEC_UNALIGNED_STORE))
4502    (set (match_dup 2) (unspec:SI [(match_dup 3)] UNSPEC_UNALIGNED_STORE))]
4503   {
4504     operands[2] = gen_highpart (SImode, operands[0]);
4505     operands[0] = gen_lowpart (SImode, operands[0]);
4506     operands[3] = gen_highpart (SImode, operands[1]);
4507     operands[1] = gen_lowpart (SImode, operands[1]);
4508   }
4509   [(set_attr "arch" "t2,any")
4510    (set_attr "length" "4,8")
4511    (set_attr "predicable" "yes")
4512    (set_attr "type" "store2")])
4515 (define_insn "*extv_reg"
4516   [(set (match_operand:SI 0 "s_register_operand" "=r")
4517         (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
4518                          (match_operand:SI 2 "const_int_M_operand" "M")
4519                          (match_operand:SI 3 "const_int_M_operand" "M")))]
4520   "arm_arch_thumb2"
4521   "sbfx%?\t%0, %1, %3, %2"
4522   [(set_attr "length" "4")
4523    (set_attr "predicable" "yes")
4524    (set_attr "predicable_short_it" "no")
4525    (set_attr "type" "bfm")]
4528 (define_insn "extzv_t2"
4529   [(set (match_operand:SI 0 "s_register_operand" "=r")
4530         (zero_extract:SI (match_operand:SI 1 "s_register_operand" "r")
4531                          (match_operand:SI 2 "const_int_M_operand" "M")
4532                          (match_operand:SI 3 "const_int_M_operand" "M")))]
4533   "arm_arch_thumb2"
4534   "ubfx%?\t%0, %1, %3, %2"
4535   [(set_attr "length" "4")
4536    (set_attr "predicable" "yes")
4537    (set_attr "predicable_short_it" "no")
4538    (set_attr "type" "bfm")]
4542 ;; Division instructions
4543 (define_insn "divsi3"
4544   [(set (match_operand:SI         0 "s_register_operand" "=r")
4545         (div:SI (match_operand:SI 1 "s_register_operand"  "r")
4546                 (match_operand:SI 2 "s_register_operand"  "r")))]
4547   "TARGET_IDIV"
4548   "sdiv%?\t%0, %1, %2"
4549   [(set_attr "predicable" "yes")
4550    (set_attr "predicable_short_it" "no")
4551    (set_attr "type" "sdiv")]
4554 (define_insn "udivsi3"
4555   [(set (match_operand:SI          0 "s_register_operand" "=r")
4556         (udiv:SI (match_operand:SI 1 "s_register_operand"  "r")
4557                  (match_operand:SI 2 "s_register_operand"  "r")))]
4558   "TARGET_IDIV"
4559   "udiv%?\t%0, %1, %2"
4560   [(set_attr "predicable" "yes")
4561    (set_attr "predicable_short_it" "no")
4562    (set_attr "type" "udiv")]
4566 ;; Unary arithmetic insns
4568 (define_expand "negdi2"
4569  [(parallel
4570    [(set (match_operand:DI 0 "s_register_operand" "")
4571          (neg:DI (match_operand:DI 1 "s_register_operand" "")))
4572     (clobber (reg:CC CC_REGNUM))])]
4573   "TARGET_EITHER"
4574   {
4575     if (TARGET_NEON)
4576       {
4577         emit_insn (gen_negdi2_neon (operands[0], operands[1]));
4578         DONE;
4579       }
4580   }
4583 ;; The constraints here are to prevent a *partial* overlap (where %Q0 == %R1).
4584 ;; The first alternative allows the common case of a *full* overlap.
4585 (define_insn_and_split "*arm_negdi2"
4586   [(set (match_operand:DI         0 "s_register_operand" "=r,&r")
4587         (neg:DI (match_operand:DI 1 "s_register_operand"  "0,r")))
4588    (clobber (reg:CC CC_REGNUM))]
4589   "TARGET_ARM"
4590   "#"   ; "rsbs\\t%Q0, %Q1, #0\;rsc\\t%R0, %R1, #0"
4591   "&& reload_completed"
4592   [(parallel [(set (reg:CC CC_REGNUM)
4593                    (compare:CC (const_int 0) (match_dup 1)))
4594               (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1)))])
4595    (set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3))
4596                                 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
4597   {
4598     operands[2] = gen_highpart (SImode, operands[0]);
4599     operands[0] = gen_lowpart (SImode, operands[0]);
4600     operands[3] = gen_highpart (SImode, operands[1]);
4601     operands[1] = gen_lowpart (SImode, operands[1]);
4602   }
4603   [(set_attr "conds" "clob")
4604    (set_attr "length" "8")
4605    (set_attr "type" "multiple")]
4608 (define_insn "*thumb1_negdi2"
4609   [(set (match_operand:DI 0 "register_operand" "=&l")
4610         (neg:DI (match_operand:DI 1 "register_operand" "l")))
4611    (clobber (reg:CC CC_REGNUM))]
4612   "TARGET_THUMB1"
4613   "mov\\t%R0, #0\;neg\\t%Q0, %Q1\;sbc\\t%R0, %R1"
4614   [(set_attr "length" "6")
4615    (set_attr "type" "multiple")]
4618 (define_expand "negsi2"
4619   [(set (match_operand:SI         0 "s_register_operand" "")
4620         (neg:SI (match_operand:SI 1 "s_register_operand" "")))]
4621   "TARGET_EITHER"
4622   ""
4625 (define_insn "*arm_negsi2"
4626   [(set (match_operand:SI         0 "s_register_operand" "=l,r")
4627         (neg:SI (match_operand:SI 1 "s_register_operand" "l,r")))]
4628   "TARGET_32BIT"
4629   "rsb%?\\t%0, %1, #0"
4630   [(set_attr "predicable" "yes")
4631    (set_attr "predicable_short_it" "yes,no")
4632    (set_attr "arch" "t2,*")
4633    (set_attr "length" "4")
4634    (set_attr "type" "alu_reg")]
4637 (define_insn "*thumb1_negsi2"
4638   [(set (match_operand:SI         0 "register_operand" "=l")
4639         (neg:SI (match_operand:SI 1 "register_operand" "l")))]
4640   "TARGET_THUMB1"
4641   "neg\\t%0, %1"
4642   [(set_attr "length" "2")
4643    (set_attr "type" "alu_imm")]
4646 (define_expand "negsf2"
4647   [(set (match_operand:SF         0 "s_register_operand" "")
4648         (neg:SF (match_operand:SF 1 "s_register_operand" "")))]
4649   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
4650   ""
4653 (define_expand "negdf2"
4654   [(set (match_operand:DF         0 "s_register_operand" "")
4655         (neg:DF (match_operand:DF 1 "s_register_operand" "")))]
4656   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
4657   "")
4659 (define_insn_and_split "*zextendsidi_negsi"
4660   [(set (match_operand:DI 0 "s_register_operand" "=r")
4661         (zero_extend:DI (neg:SI (match_operand:SI 1 "s_register_operand" "r"))))]
4662    "TARGET_32BIT"
4663    "#"
4664    ""
4665    [(set (match_dup 2)
4666          (neg:SI (match_dup 1)))
4667     (set (match_dup 3)
4668          (const_int 0))]
4669    {
4670       operands[2] = gen_lowpart (SImode, operands[0]);
4671       operands[3] = gen_highpart (SImode, operands[0]);
4672    }
4673  [(set_attr "length" "8")
4674   (set_attr "type" "multiple")]
4677 ;; Negate an extended 32-bit value.
4678 (define_insn_and_split "*negdi_extendsidi"
4679   [(set (match_operand:DI 0 "s_register_operand" "=l,r")
4680         (neg:DI (sign_extend:DI
4681                  (match_operand:SI 1 "s_register_operand" "l,r"))))
4682    (clobber (reg:CC CC_REGNUM))]
4683   "TARGET_32BIT"
4684   "#"
4685   "&& reload_completed"
4686   [(const_int 0)]
4687   {
4688     rtx low = gen_lowpart (SImode, operands[0]);
4689     rtx high = gen_highpart (SImode, operands[0]);
4691     if (reg_overlap_mentioned_p (low, operands[1]))
4692       {
4693         /* Input overlaps the low word of the output.  Use:
4694                 asr     Rhi, Rin, #31
4695                 rsbs    Rlo, Rin, #0
4696                 rsc     Rhi, Rhi, #0 (thumb2: sbc Rhi, Rhi, Rhi, lsl #1).  */
4697         rtx cc_reg = gen_rtx_REG (CC_Cmode, CC_REGNUM);
4699         emit_insn (gen_rtx_SET (VOIDmode, high,
4700                                 gen_rtx_ASHIFTRT (SImode, operands[1],
4701                                                   GEN_INT (31))));
4703         emit_insn (gen_subsi3_compare (low, const0_rtx, operands[1]));
4704         if (TARGET_ARM)
4705           emit_insn (gen_rtx_SET (VOIDmode, high,
4706                                   gen_rtx_MINUS (SImode,
4707                                                  gen_rtx_MINUS (SImode,
4708                                                                 const0_rtx,
4709                                                                 high),
4710                                                  gen_rtx_LTU (SImode,
4711                                                               cc_reg,
4712                                                               const0_rtx))));
4713         else
4714           {
4715             rtx two_x = gen_rtx_ASHIFT (SImode, high, GEN_INT (1));
4716             emit_insn (gen_rtx_SET (VOIDmode, high,
4717                                     gen_rtx_MINUS (SImode,
4718                                                    gen_rtx_MINUS (SImode,
4719                                                                   high,
4720                                                                   two_x),
4721                                                    gen_rtx_LTU (SImode,
4722                                                                 cc_reg,
4723                                                                 const0_rtx))));
4724           }
4725       }
4726     else
4727       {
4728         /* No overlap, or overlap on high word.  Use:
4729                 rsb     Rlo, Rin, #0
4730                 bic     Rhi, Rlo, Rin
4731                 asr     Rhi, Rhi, #31
4732            Flags not needed for this sequence.  */
4733         emit_insn (gen_rtx_SET (VOIDmode, low,
4734                                 gen_rtx_NEG (SImode, operands[1])));
4735         emit_insn (gen_rtx_SET (VOIDmode, high,
4736                                 gen_rtx_AND (SImode,
4737                                              gen_rtx_NOT (SImode, operands[1]),
4738                                              low)));
4739         emit_insn (gen_rtx_SET (VOIDmode, high,
4740                                 gen_rtx_ASHIFTRT (SImode, high,
4741                                                   GEN_INT (31))));
4742       }
4743     DONE;
4744   }
4745   [(set_attr "length" "12")
4746    (set_attr "arch" "t2,*")
4747    (set_attr "type" "multiple")]
4750 (define_insn_and_split "*negdi_zero_extendsidi"
4751   [(set (match_operand:DI 0 "s_register_operand" "=r,&r")
4752         (neg:DI (zero_extend:DI (match_operand:SI 1 "s_register_operand" "0,r"))))
4753    (clobber (reg:CC CC_REGNUM))]
4754   "TARGET_32BIT"
4755   "#" ; "rsbs\\t%Q0, %1, #0\;sbc\\t%R0,%R0,%R0"
4756       ;; Don't care what register is input to sbc,
4757       ;; since we just just need to propagate the carry.
4758   "&& reload_completed"
4759   [(parallel [(set (reg:CC CC_REGNUM)
4760                    (compare:CC (const_int 0) (match_dup 1)))
4761               (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1)))])
4762    (set (match_dup 2) (minus:SI (minus:SI (match_dup 2) (match_dup 2))
4763                                 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
4764   {
4765     operands[2] = gen_highpart (SImode, operands[0]);
4766     operands[0] = gen_lowpart (SImode, operands[0]);
4767   }
4768   [(set_attr "conds" "clob")
4769    (set_attr "length" "8")
4770    (set_attr "type" "multiple")]   ;; length in thumb is 4
4773 ;; abssi2 doesn't really clobber the condition codes if a different register
4774 ;; is being set.  To keep things simple, assume during rtl manipulations that
4775 ;; it does, but tell the final scan operator the truth.  Similarly for
4776 ;; (neg (abs...))
4778 (define_expand "abssi2"
4779   [(parallel
4780     [(set (match_operand:SI         0 "s_register_operand" "")
4781           (abs:SI (match_operand:SI 1 "s_register_operand" "")))
4782      (clobber (match_dup 2))])]
4783   "TARGET_EITHER"
4784   "
4785   if (TARGET_THUMB1)
4786     operands[2] = gen_rtx_SCRATCH (SImode);
4787   else
4788     operands[2] = gen_rtx_REG (CCmode, CC_REGNUM);
4791 (define_insn_and_split "*arm_abssi2"
4792   [(set (match_operand:SI 0 "s_register_operand" "=r,&r")
4793         (abs:SI (match_operand:SI 1 "s_register_operand" "0,r")))
4794    (clobber (reg:CC CC_REGNUM))]
4795   "TARGET_ARM"
4796   "#"
4797   "&& reload_completed"
4798   [(const_int 0)]
4799   {
4800    /* if (which_alternative == 0) */
4801    if (REGNO(operands[0]) == REGNO(operands[1]))
4802      {
4803       /* Emit the pattern:
4804          cmp\\t%0, #0\;rsblt\\t%0, %0, #0
4805          [(set (reg:CC CC_REGNUM)
4806                (compare:CC (match_dup 0) (const_int 0)))
4807           (cond_exec (lt:CC (reg:CC CC_REGNUM) (const_int 0))
4808                      (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1))))]
4809       */
4810       emit_insn (gen_rtx_SET (VOIDmode,
4811                               gen_rtx_REG (CCmode, CC_REGNUM),
4812                               gen_rtx_COMPARE (CCmode, operands[0], const0_rtx)));
4813       emit_insn (gen_rtx_COND_EXEC (VOIDmode,
4814                                     (gen_rtx_LT (SImode,
4815                                                  gen_rtx_REG (CCmode, CC_REGNUM),
4816                                                  const0_rtx)),
4817                                     (gen_rtx_SET (VOIDmode,
4818                                                   operands[0],
4819                                                   (gen_rtx_MINUS (SImode,
4820                                                                   const0_rtx,
4821                                                                   operands[1]))))));
4822       DONE;
4823      }
4824    else
4825      {
4826       /* Emit the pattern:
4827          alt1: eor%?\\t%0, %1, %1, asr #31\;sub%?\\t%0, %0, %1, asr #31
4828          [(set (match_dup 0)
4829                (xor:SI (match_dup 1)
4830                        (ashiftrt:SI (match_dup 1) (const_int 31))))
4831           (set (match_dup 0)
4832                (minus:SI (match_dup 0)
4833                       (ashiftrt:SI (match_dup 1) (const_int 31))))]
4834       */
4835       emit_insn (gen_rtx_SET (VOIDmode,
4836                               operands[0],
4837                               gen_rtx_XOR (SImode,
4838                                            gen_rtx_ASHIFTRT (SImode,
4839                                                              operands[1],
4840                                                              GEN_INT (31)),
4841                                            operands[1])));
4842       emit_insn (gen_rtx_SET (VOIDmode,
4843                               operands[0],
4844                               gen_rtx_MINUS (SImode,
4845                                              operands[0],
4846                                              gen_rtx_ASHIFTRT (SImode,
4847                                                                operands[1],
4848                                                                GEN_INT (31)))));
4849       DONE;
4850      }
4851   }
4852   [(set_attr "conds" "clob,*")
4853    (set_attr "shift" "1")
4854    (set_attr "predicable" "no, yes")
4855    (set_attr "length" "8")
4856    (set_attr "type" "multiple")]
4859 (define_insn_and_split "*thumb1_abssi2"
4860   [(set (match_operand:SI 0 "s_register_operand" "=l")
4861         (abs:SI (match_operand:SI 1 "s_register_operand" "l")))
4862    (clobber (match_scratch:SI 2 "=&l"))]
4863   "TARGET_THUMB1"
4864   "#"
4865   "TARGET_THUMB1 && reload_completed"
4866   [(set (match_dup 2) (ashiftrt:SI (match_dup 1) (const_int 31)))
4867    (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))
4868    (set (match_dup 0) (xor:SI (match_dup 0) (match_dup 2)))]
4869   ""
4870   [(set_attr "length" "6")
4871    (set_attr "type" "multiple")]
4874 (define_insn_and_split "*arm_neg_abssi2"
4875   [(set (match_operand:SI 0 "s_register_operand" "=r,&r")
4876         (neg:SI (abs:SI (match_operand:SI 1 "s_register_operand" "0,r"))))
4877    (clobber (reg:CC CC_REGNUM))]
4878   "TARGET_ARM"
4879   "#"
4880   "&& reload_completed"
4881   [(const_int 0)]
4882   {
4883    /* if (which_alternative == 0) */
4884    if (REGNO (operands[0]) == REGNO (operands[1]))
4885      {
4886       /* Emit the pattern:
4887          cmp\\t%0, #0\;rsbgt\\t%0, %0, #0
4888       */
4889       emit_insn (gen_rtx_SET (VOIDmode,
4890                               gen_rtx_REG (CCmode, CC_REGNUM),
4891                               gen_rtx_COMPARE (CCmode, operands[0], const0_rtx)));
4892       emit_insn (gen_rtx_COND_EXEC (VOIDmode,
4893                                     gen_rtx_GT (SImode,
4894                                                 gen_rtx_REG (CCmode, CC_REGNUM),
4895                                                 const0_rtx),
4896                                     gen_rtx_SET (VOIDmode,
4897                                                  operands[0],
4898                                                  (gen_rtx_MINUS (SImode,
4899                                                                  const0_rtx,
4900                                                                  operands[1])))));
4901      }
4902    else
4903      {
4904       /* Emit the pattern:
4905          eor%?\\t%0, %1, %1, asr #31\;rsb%?\\t%0, %0, %1, asr #31
4906       */
4907       emit_insn (gen_rtx_SET (VOIDmode,
4908                               operands[0],
4909                               gen_rtx_XOR (SImode,
4910                                            gen_rtx_ASHIFTRT (SImode,
4911                                                              operands[1],
4912                                                              GEN_INT (31)),
4913                                            operands[1])));
4914       emit_insn (gen_rtx_SET (VOIDmode,
4915                               operands[0],
4916                               gen_rtx_MINUS (SImode,
4917                                              gen_rtx_ASHIFTRT (SImode,
4918                                                                operands[1],
4919                                                                GEN_INT (31)),
4920                                              operands[0])));
4921      }
4922    DONE;
4923   }
4924   [(set_attr "conds" "clob,*")
4925    (set_attr "shift" "1")
4926    (set_attr "predicable" "no, yes")
4927    (set_attr "length" "8")
4928    (set_attr "type" "multiple")]
4931 (define_insn_and_split "*thumb1_neg_abssi2"
4932   [(set (match_operand:SI 0 "s_register_operand" "=l")
4933         (neg:SI (abs:SI (match_operand:SI 1 "s_register_operand" "l"))))
4934    (clobber (match_scratch:SI 2 "=&l"))]
4935   "TARGET_THUMB1"
4936   "#"
4937   "TARGET_THUMB1 && reload_completed"
4938   [(set (match_dup 2) (ashiftrt:SI (match_dup 1) (const_int 31)))
4939    (set (match_dup 0) (minus:SI (match_dup 2) (match_dup 1)))
4940    (set (match_dup 0) (xor:SI (match_dup 0) (match_dup 2)))]
4941   ""
4942   [(set_attr "length" "6")
4943    (set_attr "type" "multiple")]
4946 (define_expand "abssf2"
4947   [(set (match_operand:SF         0 "s_register_operand" "")
4948         (abs:SF (match_operand:SF 1 "s_register_operand" "")))]
4949   "TARGET_32BIT && TARGET_HARD_FLOAT"
4950   "")
4952 (define_expand "absdf2"
4953   [(set (match_operand:DF         0 "s_register_operand" "")
4954         (abs:DF (match_operand:DF 1 "s_register_operand" "")))]
4955   "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
4956   "")
4958 (define_expand "sqrtsf2"
4959   [(set (match_operand:SF 0 "s_register_operand" "")
4960         (sqrt:SF (match_operand:SF 1 "s_register_operand" "")))]
4961   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
4962   "")
4964 (define_expand "sqrtdf2"
4965   [(set (match_operand:DF 0 "s_register_operand" "")
4966         (sqrt:DF (match_operand:DF 1 "s_register_operand" "")))]
4967   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
4968   "")
4970 (define_insn_and_split "one_cmpldi2"
4971   [(set (match_operand:DI 0 "s_register_operand"         "=w,&r,&r,?w")
4972         (not:DI (match_operand:DI 1 "s_register_operand" " w, 0, r, w")))]
4973   "TARGET_32BIT"
4974   "@
4975    vmvn\t%P0, %P1
4976    #
4977    #
4978    vmvn\t%P0, %P1"
4979   "TARGET_32BIT && reload_completed
4980    && arm_general_register_operand (operands[0], DImode)"
4981   [(set (match_dup 0) (not:SI (match_dup 1)))
4982    (set (match_dup 2) (not:SI (match_dup 3)))]
4983   "
4984   {
4985     operands[2] = gen_highpart (SImode, operands[0]);
4986     operands[0] = gen_lowpart (SImode, operands[0]);
4987     operands[3] = gen_highpart (SImode, operands[1]);
4988     operands[1] = gen_lowpart (SImode, operands[1]);
4989   }"
4990   [(set_attr "length" "*,8,8,*")
4991    (set_attr "predicable" "no,yes,yes,no")
4992    (set_attr "type" "neon_move,multiple,multiple,neon_move")
4993    (set_attr "arch" "neon_for_64bits,*,*,avoid_neon_for_64bits")]
4996 (define_expand "one_cmplsi2"
4997   [(set (match_operand:SI         0 "s_register_operand" "")
4998         (not:SI (match_operand:SI 1 "s_register_operand" "")))]
4999   "TARGET_EITHER"
5000   ""
5003 (define_insn "*arm_one_cmplsi2"
5004   [(set (match_operand:SI         0 "s_register_operand" "=l,r")
5005         (not:SI (match_operand:SI 1 "s_register_operand"  "l,r")))]
5006   "TARGET_32BIT"
5007   "mvn%?\\t%0, %1"
5008   [(set_attr "predicable" "yes")
5009    (set_attr "predicable_short_it" "yes,no")
5010    (set_attr "arch" "t2,*")
5011    (set_attr "length" "4")
5012    (set_attr "type" "mvn_reg")]
5015 (define_insn "*thumb1_one_cmplsi2"
5016   [(set (match_operand:SI         0 "register_operand" "=l")
5017         (not:SI (match_operand:SI 1 "register_operand"  "l")))]
5018   "TARGET_THUMB1"
5019   "mvn\\t%0, %1"
5020   [(set_attr "length" "2")
5021    (set_attr "type" "mvn_reg")]
5024 (define_insn "*notsi_compare0"
5025   [(set (reg:CC_NOOV CC_REGNUM)
5026         (compare:CC_NOOV (not:SI (match_operand:SI 1 "s_register_operand" "r"))
5027                          (const_int 0)))
5028    (set (match_operand:SI 0 "s_register_operand" "=r")
5029         (not:SI (match_dup 1)))]
5030   "TARGET_32BIT"
5031   "mvn%.\\t%0, %1"
5032   [(set_attr "conds" "set")
5033    (set_attr "type" "mvn_reg")]
5036 (define_insn "*notsi_compare0_scratch"
5037   [(set (reg:CC_NOOV CC_REGNUM)
5038         (compare:CC_NOOV (not:SI (match_operand:SI 1 "s_register_operand" "r"))
5039                          (const_int 0)))
5040    (clobber (match_scratch:SI 0 "=r"))]
5041   "TARGET_32BIT"
5042   "mvn%.\\t%0, %1"
5043   [(set_attr "conds" "set")
5044    (set_attr "type" "mvn_reg")]
5047 ;; Fixed <--> Floating conversion insns
5049 (define_expand "floatsihf2"
5050   [(set (match_operand:HF           0 "general_operand" "")
5051         (float:HF (match_operand:SI 1 "general_operand" "")))]
5052   "TARGET_EITHER"
5053   "
5054   {
5055     rtx op1 = gen_reg_rtx (SFmode);
5056     expand_float (op1, operands[1], 0);
5057     op1 = convert_to_mode (HFmode, op1, 0);
5058     emit_move_insn (operands[0], op1);
5059     DONE;
5060   }"
5063 (define_expand "floatdihf2"
5064   [(set (match_operand:HF           0 "general_operand" "")
5065         (float:HF (match_operand:DI 1 "general_operand" "")))]
5066   "TARGET_EITHER"
5067   "
5068   {
5069     rtx op1 = gen_reg_rtx (SFmode);
5070     expand_float (op1, operands[1], 0);
5071     op1 = convert_to_mode (HFmode, op1, 0);
5072     emit_move_insn (operands[0], op1);
5073     DONE;
5074   }"
5077 (define_expand "floatsisf2"
5078   [(set (match_operand:SF           0 "s_register_operand" "")
5079         (float:SF (match_operand:SI 1 "s_register_operand" "")))]
5080   "TARGET_32BIT && TARGET_HARD_FLOAT"
5081   "
5084 (define_expand "floatsidf2"
5085   [(set (match_operand:DF           0 "s_register_operand" "")
5086         (float:DF (match_operand:SI 1 "s_register_operand" "")))]
5087   "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
5088   "
5091 (define_expand "fix_trunchfsi2"
5092   [(set (match_operand:SI         0 "general_operand" "")
5093         (fix:SI (fix:HF (match_operand:HF 1 "general_operand"  ""))))]
5094   "TARGET_EITHER"
5095   "
5096   {
5097     rtx op1 = convert_to_mode (SFmode, operands[1], 0);
5098     expand_fix (operands[0], op1, 0);
5099     DONE;
5100   }"
5103 (define_expand "fix_trunchfdi2"
5104   [(set (match_operand:DI         0 "general_operand" "")
5105         (fix:DI (fix:HF (match_operand:HF 1 "general_operand"  ""))))]
5106   "TARGET_EITHER"
5107   "
5108   {
5109     rtx op1 = convert_to_mode (SFmode, operands[1], 0);
5110     expand_fix (operands[0], op1, 0);
5111     DONE;
5112   }"
5115 (define_expand "fix_truncsfsi2"
5116   [(set (match_operand:SI         0 "s_register_operand" "")
5117         (fix:SI (fix:SF (match_operand:SF 1 "s_register_operand"  ""))))]
5118   "TARGET_32BIT && TARGET_HARD_FLOAT"
5119   "
5122 (define_expand "fix_truncdfsi2"
5123   [(set (match_operand:SI         0 "s_register_operand" "")
5124         (fix:SI (fix:DF (match_operand:DF 1 "s_register_operand"  ""))))]
5125   "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
5126   "
5129 ;; Truncation insns
5131 (define_expand "truncdfsf2"
5132   [(set (match_operand:SF  0 "s_register_operand" "")
5133         (float_truncate:SF
5134          (match_operand:DF 1 "s_register_operand" "")))]
5135   "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
5136   ""
5139 /* DFmode -> HFmode conversions have to go through SFmode.  */
5140 (define_expand "truncdfhf2"
5141   [(set (match_operand:HF  0 "general_operand" "")
5142         (float_truncate:HF
5143          (match_operand:DF 1 "general_operand" "")))]
5144   "TARGET_EITHER"
5145   "
5146   {
5147     rtx op1;
5148     op1 = convert_to_mode (SFmode, operands[1], 0);
5149     op1 = convert_to_mode (HFmode, op1, 0);
5150     emit_move_insn (operands[0], op1);
5151     DONE;
5152   }"
5155 ;; Zero and sign extension instructions.
5157 (define_insn "zero_extend<mode>di2"
5158   [(set (match_operand:DI 0 "s_register_operand" "=w,r,?r,w")
5159         (zero_extend:DI (match_operand:QHSI 1 "<qhs_zextenddi_op>"
5160                                             "<qhs_zextenddi_cstr>")))]
5161   "TARGET_32BIT <qhs_zextenddi_cond>"
5162   "#"
5163   [(set_attr "length" "8,4,8,8")
5164    (set_attr "arch" "neon_for_64bits,*,*,avoid_neon_for_64bits")
5165    (set_attr "ce_count" "2")
5166    (set_attr "predicable" "yes")
5167    (set_attr "type" "multiple,mov_reg,multiple,multiple")]
5170 (define_insn "extend<mode>di2"
5171   [(set (match_operand:DI 0 "s_register_operand" "=w,r,?r,?r,w")
5172         (sign_extend:DI (match_operand:QHSI 1 "<qhs_extenddi_op>"
5173                                             "<qhs_extenddi_cstr>")))]
5174   "TARGET_32BIT <qhs_sextenddi_cond>"
5175   "#"
5176   [(set_attr "length" "8,4,8,8,8")
5177    (set_attr "ce_count" "2")
5178    (set_attr "shift" "1")
5179    (set_attr "predicable" "yes")
5180    (set_attr "arch" "neon_for_64bits,*,a,t,avoid_neon_for_64bits")
5181    (set_attr "type" "multiple,mov_reg,multiple,multiple,multiple")]
5184 ;; Splits for all extensions to DImode
5185 (define_split
5186   [(set (match_operand:DI 0 "s_register_operand" "")
5187         (zero_extend:DI (match_operand 1 "nonimmediate_operand" "")))]
5188   "TARGET_32BIT && reload_completed && !IS_VFP_REGNUM (REGNO (operands[0]))"
5189   [(set (match_dup 0) (match_dup 1))]
5191   rtx lo_part = gen_lowpart (SImode, operands[0]);
5192   enum machine_mode src_mode = GET_MODE (operands[1]);
5194   if (REG_P (operands[0])
5195       && !reg_overlap_mentioned_p (operands[0], operands[1]))
5196     emit_clobber (operands[0]);
5197   if (!REG_P (lo_part) || src_mode != SImode
5198       || !rtx_equal_p (lo_part, operands[1]))
5199     {
5200       if (src_mode == SImode)
5201         emit_move_insn (lo_part, operands[1]);
5202       else
5203         emit_insn (gen_rtx_SET (VOIDmode, lo_part,
5204                                 gen_rtx_ZERO_EXTEND (SImode, operands[1])));
5205       operands[1] = lo_part;
5206     }
5207   operands[0] = gen_highpart (SImode, operands[0]);
5208   operands[1] = const0_rtx;
5211 (define_split
5212   [(set (match_operand:DI 0 "s_register_operand" "")
5213         (sign_extend:DI (match_operand 1 "nonimmediate_operand" "")))]
5214   "TARGET_32BIT && reload_completed && !IS_VFP_REGNUM (REGNO (operands[0]))"
5215   [(set (match_dup 0) (ashiftrt:SI (match_dup 1) (const_int 31)))]
5217   rtx lo_part = gen_lowpart (SImode, operands[0]);
5218   enum machine_mode src_mode = GET_MODE (operands[1]);
5220   if (REG_P (operands[0])
5221       && !reg_overlap_mentioned_p (operands[0], operands[1]))
5222     emit_clobber (operands[0]);
5224   if (!REG_P (lo_part) || src_mode != SImode
5225       || !rtx_equal_p (lo_part, operands[1]))
5226     {
5227       if (src_mode == SImode)
5228         emit_move_insn (lo_part, operands[1]);
5229       else
5230         emit_insn (gen_rtx_SET (VOIDmode, lo_part,
5231                                 gen_rtx_SIGN_EXTEND (SImode, operands[1])));
5232       operands[1] = lo_part;
5233     }
5234   operands[0] = gen_highpart (SImode, operands[0]);
5237 (define_expand "zero_extendhisi2"
5238   [(set (match_operand:SI 0 "s_register_operand" "")
5239         (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
5240   "TARGET_EITHER"
5242   if (TARGET_ARM && !arm_arch4 && MEM_P (operands[1]))
5243     {
5244       emit_insn (gen_movhi_bytes (operands[0], operands[1]));
5245       DONE;
5246     }
5247   if (!arm_arch6 && !MEM_P (operands[1]))
5248     {
5249       rtx t = gen_lowpart (SImode, operands[1]);
5250       rtx tmp = gen_reg_rtx (SImode);
5251       emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (16)));
5252       emit_insn (gen_lshrsi3 (operands[0], tmp, GEN_INT (16)));
5253       DONE;
5254     }
5257 (define_split
5258   [(set (match_operand:SI 0 "s_register_operand" "")
5259         (zero_extend:SI (match_operand:HI 1 "s_register_operand" "")))]
5260   "!TARGET_THUMB2 && !arm_arch6"
5261   [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
5262    (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 16)))]
5264   operands[2] = gen_lowpart (SImode, operands[1]);
5267 (define_insn "*thumb1_zero_extendhisi2"
5268   [(set (match_operand:SI 0 "register_operand" "=l,l")
5269         (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "l,m")))]
5270   "TARGET_THUMB1"
5272   rtx mem;
5274   if (which_alternative == 0 && arm_arch6)
5275     return "uxth\t%0, %1";
5276   if (which_alternative == 0)
5277     return "#";
5279   mem = XEXP (operands[1], 0);
5281   if (GET_CODE (mem) == CONST)
5282     mem = XEXP (mem, 0);
5283     
5284   if (GET_CODE (mem) == PLUS)
5285     {
5286       rtx a = XEXP (mem, 0);
5288       /* This can happen due to bugs in reload.  */
5289       if (REG_P (a) && REGNO (a) == SP_REGNUM)
5290         {
5291           rtx ops[2];
5292           ops[0] = operands[0];
5293           ops[1] = a;
5294       
5295           output_asm_insn ("mov\t%0, %1", ops);
5297           XEXP (mem, 0) = operands[0];
5298        }
5299     }
5300     
5301   return "ldrh\t%0, %1";
5303   [(set_attr_alternative "length"
5304                          [(if_then_else (eq_attr "is_arch6" "yes")
5305                                        (const_int 2) (const_int 4))
5306                          (const_int 4)])
5307    (set_attr "type" "extend,load_byte")]
5310 (define_insn "*arm_zero_extendhisi2"
5311   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5312         (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
5313   "TARGET_ARM && arm_arch4 && !arm_arch6"
5314   "@
5315    #
5316    ldr%(h%)\\t%0, %1"
5317   [(set_attr "type" "alu_shift_reg,load_byte")
5318    (set_attr "predicable" "yes")]
5321 (define_insn "*arm_zero_extendhisi2_v6"
5322   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5323         (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,Uh")))]
5324   "TARGET_ARM && arm_arch6"
5325   "@
5326    uxth%?\\t%0, %1
5327    ldr%(h%)\\t%0, %1"
5328   [(set_attr "predicable" "yes")
5329    (set_attr "type" "extend,load_byte")]
5332 (define_insn "*arm_zero_extendhisi2addsi"
5333   [(set (match_operand:SI 0 "s_register_operand" "=r")
5334         (plus:SI (zero_extend:SI (match_operand:HI 1 "s_register_operand" "r"))
5335                  (match_operand:SI 2 "s_register_operand" "r")))]
5336   "TARGET_INT_SIMD"
5337   "uxtah%?\\t%0, %2, %1"
5338   [(set_attr "type" "alu_shift_reg")
5339    (set_attr "predicable" "yes")
5340    (set_attr "predicable_short_it" "no")]
5343 (define_expand "zero_extendqisi2"
5344   [(set (match_operand:SI 0 "s_register_operand" "")
5345         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))]
5346   "TARGET_EITHER"
5348   if (TARGET_ARM && !arm_arch6 && !MEM_P (operands[1]))
5349     {
5350       emit_insn (gen_andsi3 (operands[0],
5351                              gen_lowpart (SImode, operands[1]),
5352                                           GEN_INT (255)));
5353       DONE;
5354     }
5355   if (!arm_arch6 && !MEM_P (operands[1]))
5356     {
5357       rtx t = gen_lowpart (SImode, operands[1]);
5358       rtx tmp = gen_reg_rtx (SImode);
5359       emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (24)));
5360       emit_insn (gen_lshrsi3 (operands[0], tmp, GEN_INT (24)));
5361       DONE;
5362     }
5365 (define_split
5366   [(set (match_operand:SI 0 "s_register_operand" "")
5367         (zero_extend:SI (match_operand:QI 1 "s_register_operand" "")))]
5368   "!arm_arch6"
5369   [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 24)))
5370    (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 24)))]
5372   operands[2] = simplify_gen_subreg (SImode, operands[1], QImode, 0);
5373   if (TARGET_ARM)
5374     {
5375       emit_insn (gen_andsi3 (operands[0], operands[2], GEN_INT (255)));
5376       DONE;
5377     }
5380 (define_insn "*thumb1_zero_extendqisi2"
5381   [(set (match_operand:SI 0 "register_operand" "=l,l")
5382         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "l,m")))]
5383   "TARGET_THUMB1 && !arm_arch6"
5384   "@
5385    #
5386    ldrb\\t%0, %1"
5387   [(set_attr "length" "4,2")
5388    (set_attr "type" "alu_shift_reg,load_byte")
5389    (set_attr "pool_range" "*,32")]
5392 (define_insn "*thumb1_zero_extendqisi2_v6"
5393   [(set (match_operand:SI 0 "register_operand" "=l,l")
5394         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "l,m")))]
5395   "TARGET_THUMB1 && arm_arch6"
5396   "@
5397    uxtb\\t%0, %1
5398    ldrb\\t%0, %1"
5399   [(set_attr "length" "2")
5400    (set_attr "type" "extend,load_byte")]
5403 (define_insn "*arm_zero_extendqisi2"
5404   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5405         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
5406   "TARGET_ARM && !arm_arch6"
5407   "@
5408    #
5409    ldr%(b%)\\t%0, %1\\t%@ zero_extendqisi2"
5410   [(set_attr "length" "8,4")
5411    (set_attr "type" "alu_shift_reg,load_byte")
5412    (set_attr "predicable" "yes")]
5415 (define_insn "*arm_zero_extendqisi2_v6"
5416   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5417         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,Uh")))]
5418   "TARGET_ARM && arm_arch6"
5419   "@
5420    uxtb%(%)\\t%0, %1
5421    ldr%(b%)\\t%0, %1\\t%@ zero_extendqisi2"
5422   [(set_attr "type" "extend,load_byte")
5423    (set_attr "predicable" "yes")]
5426 (define_insn "*arm_zero_extendqisi2addsi"
5427   [(set (match_operand:SI 0 "s_register_operand" "=r")
5428         (plus:SI (zero_extend:SI (match_operand:QI 1 "s_register_operand" "r"))
5429                  (match_operand:SI 2 "s_register_operand" "r")))]
5430   "TARGET_INT_SIMD"
5431   "uxtab%?\\t%0, %2, %1"
5432   [(set_attr "predicable" "yes")
5433    (set_attr "predicable_short_it" "no")
5434    (set_attr "type" "alu_shift_reg")]
5437 (define_split
5438   [(set (match_operand:SI 0 "s_register_operand" "")
5439         (zero_extend:SI (subreg:QI (match_operand:SI 1 "" "") 0)))
5440    (clobber (match_operand:SI 2 "s_register_operand" ""))]
5441   "TARGET_32BIT && (!MEM_P (operands[1])) && ! BYTES_BIG_ENDIAN"
5442   [(set (match_dup 2) (match_dup 1))
5443    (set (match_dup 0) (and:SI (match_dup 2) (const_int 255)))]
5444   ""
5447 (define_split
5448   [(set (match_operand:SI 0 "s_register_operand" "")
5449         (zero_extend:SI (subreg:QI (match_operand:SI 1 "" "") 3)))
5450    (clobber (match_operand:SI 2 "s_register_operand" ""))]
5451   "TARGET_32BIT && (!MEM_P (operands[1])) && BYTES_BIG_ENDIAN"
5452   [(set (match_dup 2) (match_dup 1))
5453    (set (match_dup 0) (and:SI (match_dup 2) (const_int 255)))]
5454   ""
5458 (define_split
5459   [(set (match_operand:SI 0 "s_register_operand" "")
5460         (ior_xor:SI (and:SI (ashift:SI
5461                              (match_operand:SI 1 "s_register_operand" "")
5462                              (match_operand:SI 2 "const_int_operand" ""))
5463                             (match_operand:SI 3 "const_int_operand" ""))
5464                     (zero_extend:SI
5465                      (match_operator 5 "subreg_lowpart_operator"
5466                       [(match_operand:SI 4 "s_register_operand" "")]))))]
5467   "TARGET_32BIT
5468    && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
5469        == (GET_MODE_MASK (GET_MODE (operands[5]))
5470            & (GET_MODE_MASK (GET_MODE (operands[5]))
5471               << (INTVAL (operands[2])))))"
5472   [(set (match_dup 0) (ior_xor:SI (ashift:SI (match_dup 1) (match_dup 2))
5473                                   (match_dup 4)))
5474    (set (match_dup 0) (zero_extend:SI (match_dup 5)))]
5475   "operands[5] = gen_lowpart (GET_MODE (operands[5]), operands[0]);"
5478 (define_insn "*compareqi_eq0"
5479   [(set (reg:CC_Z CC_REGNUM)
5480         (compare:CC_Z (match_operand:QI 0 "s_register_operand" "r")
5481                          (const_int 0)))]
5482   "TARGET_32BIT"
5483   "tst%?\\t%0, #255"
5484   [(set_attr "conds" "set")
5485    (set_attr "predicable" "yes")
5486    (set_attr "predicable_short_it" "no")
5487    (set_attr "type" "logic_imm")]
5490 (define_expand "extendhisi2"
5491   [(set (match_operand:SI 0 "s_register_operand" "")
5492         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
5493   "TARGET_EITHER"
5495   if (TARGET_THUMB1)
5496     {
5497       emit_insn (gen_thumb1_extendhisi2 (operands[0], operands[1]));
5498       DONE;
5499     }
5500   if (MEM_P (operands[1]) && TARGET_ARM && !arm_arch4)
5501     {
5502       emit_insn (gen_extendhisi2_mem (operands[0], operands[1]));
5503       DONE;
5504     }
5506   if (!arm_arch6 && !MEM_P (operands[1]))
5507     {
5508       rtx t = gen_lowpart (SImode, operands[1]);
5509       rtx tmp = gen_reg_rtx (SImode);
5510       emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (16)));
5511       emit_insn (gen_ashrsi3 (operands[0], tmp, GEN_INT (16)));
5512       DONE;
5513     }
5516 (define_split
5517   [(parallel
5518     [(set (match_operand:SI 0 "register_operand" "")
5519           (sign_extend:SI (match_operand:HI 1 "register_operand" "")))
5520      (clobber (match_scratch:SI 2 ""))])]
5521   "!arm_arch6"
5522   [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
5523    (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
5525   operands[2] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
5528 ;; We used to have an early-clobber on the scratch register here.
5529 ;; However, there's a bug somewhere in reload which means that this
5530 ;; can be partially ignored during spill allocation if the memory
5531 ;; address also needs reloading; this causes us to die later on when
5532 ;; we try to verify the operands.  Fortunately, we don't really need
5533 ;; the early-clobber: we can always use operand 0 if operand 2
5534 ;; overlaps the address.
5535 (define_insn "thumb1_extendhisi2"
5536   [(set (match_operand:SI 0 "register_operand" "=l,l")
5537         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "l,m")))
5538    (clobber (match_scratch:SI 2 "=X,l"))]
5539   "TARGET_THUMB1"
5540   "*
5541   {
5542     rtx ops[4];
5543     rtx mem;
5545     if (which_alternative == 0 && !arm_arch6)
5546       return \"#\";
5547     if (which_alternative == 0)
5548       return \"sxth\\t%0, %1\";
5550     mem = XEXP (operands[1], 0);
5552     /* This code used to try to use 'V', and fix the address only if it was
5553        offsettable, but this fails for e.g. REG+48 because 48 is outside the
5554        range of QImode offsets, and offsettable_address_p does a QImode
5555        address check.  */
5556        
5557     if (GET_CODE (mem) == CONST)
5558       mem = XEXP (mem, 0);
5559     
5560     if (GET_CODE (mem) == LABEL_REF)
5561       return \"ldr\\t%0, %1\";
5562     
5563     if (GET_CODE (mem) == PLUS)
5564       {
5565         rtx a = XEXP (mem, 0);
5566         rtx b = XEXP (mem, 1);
5568         if (GET_CODE (a) == LABEL_REF
5569             && CONST_INT_P (b))
5570           return \"ldr\\t%0, %1\";
5572         if (REG_P (b))
5573           return \"ldrsh\\t%0, %1\";
5574           
5575         ops[1] = a;
5576         ops[2] = b;
5577       }
5578     else
5579       {
5580         ops[1] = mem;
5581         ops[2] = const0_rtx;
5582       }
5583       
5584     gcc_assert (REG_P (ops[1]));
5586     ops[0] = operands[0];
5587     if (reg_mentioned_p (operands[2], ops[1]))
5588       ops[3] = ops[0];
5589     else
5590       ops[3] = operands[2];
5591     output_asm_insn (\"mov\\t%3, %2\;ldrsh\\t%0, [%1, %3]\", ops);
5592     return \"\";
5593   }"
5594   [(set_attr_alternative "length"
5595                          [(if_then_else (eq_attr "is_arch6" "yes")
5596                                         (const_int 2) (const_int 4))
5597                           (const_int 4)])
5598    (set_attr "type" "extend,load_byte")
5599    (set_attr "pool_range" "*,1018")]
5602 ;; This pattern will only be used when ldsh is not available
5603 (define_expand "extendhisi2_mem"
5604   [(set (match_dup 2) (zero_extend:SI (match_operand:HI 1 "" "")))
5605    (set (match_dup 3)
5606         (zero_extend:SI (match_dup 7)))
5607    (set (match_dup 6) (ashift:SI (match_dup 4) (const_int 24)))
5608    (set (match_operand:SI 0 "" "")
5609         (ior:SI (ashiftrt:SI (match_dup 6) (const_int 16)) (match_dup 5)))]
5610   "TARGET_ARM"
5611   "
5612   {
5613     rtx mem1, mem2;
5614     rtx addr = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
5616     mem1 = change_address (operands[1], QImode, addr);
5617     mem2 = change_address (operands[1], QImode,
5618                            plus_constant (Pmode, addr, 1));
5619     operands[0] = gen_lowpart (SImode, operands[0]);
5620     operands[1] = mem1;
5621     operands[2] = gen_reg_rtx (SImode);
5622     operands[3] = gen_reg_rtx (SImode);
5623     operands[6] = gen_reg_rtx (SImode);
5624     operands[7] = mem2;
5626     if (BYTES_BIG_ENDIAN)
5627       {
5628         operands[4] = operands[2];
5629         operands[5] = operands[3];
5630       }
5631     else
5632       {
5633         operands[4] = operands[3];
5634         operands[5] = operands[2];
5635       }
5636   }"
5639 (define_split
5640   [(set (match_operand:SI 0 "register_operand" "")
5641         (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
5642   "!arm_arch6"
5643   [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
5644    (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
5646   operands[2] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
5649 (define_insn "*arm_extendhisi2"
5650   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5651         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,Uh")))]
5652   "TARGET_ARM && arm_arch4 && !arm_arch6"
5653   "@
5654    #
5655    ldr%(sh%)\\t%0, %1"
5656   [(set_attr "length" "8,4")
5657    (set_attr "type" "alu_shift_reg,load_byte")
5658    (set_attr "predicable" "yes")]
5661 ;; ??? Check Thumb-2 pool range
5662 (define_insn "*arm_extendhisi2_v6"
5663   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5664         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,Uh")))]
5665   "TARGET_32BIT && arm_arch6"
5666   "@
5667    sxth%?\\t%0, %1
5668    ldr%(sh%)\\t%0, %1"
5669   [(set_attr "type" "extend,load_byte")
5670    (set_attr "predicable" "yes")
5671    (set_attr "predicable_short_it" "no")]
5674 (define_insn "*arm_extendhisi2addsi"
5675   [(set (match_operand:SI 0 "s_register_operand" "=r")
5676         (plus:SI (sign_extend:SI (match_operand:HI 1 "s_register_operand" "r"))
5677                  (match_operand:SI 2 "s_register_operand" "r")))]
5678   "TARGET_INT_SIMD"
5679   "sxtah%?\\t%0, %2, %1"
5680   [(set_attr "type" "alu_shift_reg")]
5683 (define_expand "extendqihi2"
5684   [(set (match_dup 2)
5685         (ashift:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "")
5686                    (const_int 24)))
5687    (set (match_operand:HI 0 "s_register_operand" "")
5688         (ashiftrt:SI (match_dup 2)
5689                      (const_int 24)))]
5690   "TARGET_ARM"
5691   "
5692   {
5693     if (arm_arch4 && MEM_P (operands[1]))
5694       {
5695         emit_insn (gen_rtx_SET (VOIDmode,
5696                                 operands[0],
5697                                 gen_rtx_SIGN_EXTEND (HImode, operands[1])));
5698         DONE;
5699       }
5700     if (!s_register_operand (operands[1], QImode))
5701       operands[1] = copy_to_mode_reg (QImode, operands[1]);
5702     operands[0] = gen_lowpart (SImode, operands[0]);
5703     operands[1] = gen_lowpart (SImode, operands[1]);
5704     operands[2] = gen_reg_rtx (SImode);
5705   }"
5708 (define_insn "*arm_extendqihi_insn"
5709   [(set (match_operand:HI 0 "s_register_operand" "=r")
5710         (sign_extend:HI (match_operand:QI 1 "arm_extendqisi_mem_op" "Uq")))]
5711   "TARGET_ARM && arm_arch4"
5712   "ldr%(sb%)\\t%0, %1"
5713   [(set_attr "type" "load_byte")
5714    (set_attr "predicable" "yes")]
5717 (define_expand "extendqisi2"
5718   [(set (match_operand:SI 0 "s_register_operand" "")
5719         (sign_extend:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "")))]
5720   "TARGET_EITHER"
5722   if (!arm_arch4 && MEM_P (operands[1]))
5723     operands[1] = copy_to_mode_reg (QImode, operands[1]);
5725   if (!arm_arch6 && !MEM_P (operands[1]))
5726     {
5727       rtx t = gen_lowpart (SImode, operands[1]);
5728       rtx tmp = gen_reg_rtx (SImode);
5729       emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (24)));
5730       emit_insn (gen_ashrsi3 (operands[0], tmp, GEN_INT (24)));
5731       DONE;
5732     }
5735 (define_split
5736   [(set (match_operand:SI 0 "register_operand" "")
5737         (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
5738   "!arm_arch6"
5739   [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 24)))
5740    (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 24)))]
5742   operands[2] = simplify_gen_subreg (SImode, operands[1], QImode, 0);
5745 (define_insn "*arm_extendqisi"
5746   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5747         (sign_extend:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "r,Uq")))]
5748   "TARGET_ARM && arm_arch4 && !arm_arch6"
5749   "@
5750    #
5751    ldr%(sb%)\\t%0, %1"
5752   [(set_attr "length" "8,4")
5753    (set_attr "type" "alu_shift_reg,load_byte")
5754    (set_attr "predicable" "yes")]
5757 (define_insn "*arm_extendqisi_v6"
5758   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5759         (sign_extend:SI
5760          (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "r,Uq")))]
5761   "TARGET_ARM && arm_arch6"
5762   "@
5763    sxtb%?\\t%0, %1
5764    ldr%(sb%)\\t%0, %1"
5765   [(set_attr "type" "extend,load_byte")
5766    (set_attr "predicable" "yes")]
5769 (define_insn "*arm_extendqisi2addsi"
5770   [(set (match_operand:SI 0 "s_register_operand" "=r")
5771         (plus:SI (sign_extend:SI (match_operand:QI 1 "s_register_operand" "r"))
5772                  (match_operand:SI 2 "s_register_operand" "r")))]
5773   "TARGET_INT_SIMD"
5774   "sxtab%?\\t%0, %2, %1"
5775   [(set_attr "type" "alu_shift_reg")
5776    (set_attr "predicable" "yes")
5777    (set_attr "predicable_short_it" "no")]
5780 (define_split
5781   [(set (match_operand:SI 0 "register_operand" "")
5782         (sign_extend:SI (match_operand:QI 1 "memory_operand" "")))]
5783   "TARGET_THUMB1 && reload_completed"
5784   [(set (match_dup 0) (match_dup 2))
5785    (set (match_dup 0) (sign_extend:SI (match_dup 3)))]
5787   rtx addr = XEXP (operands[1], 0);
5789   if (GET_CODE (addr) == CONST)
5790     addr = XEXP (addr, 0);
5792   if (GET_CODE (addr) == PLUS
5793       && REG_P (XEXP (addr, 0)) && REG_P (XEXP (addr, 1)))
5794     /* No split necessary.  */
5795     FAIL;
5797   if (GET_CODE (addr) == PLUS
5798       && !REG_P (XEXP (addr, 0)) && !REG_P (XEXP (addr, 1)))
5799     FAIL;
5801   if (reg_overlap_mentioned_p (operands[0], addr))
5802     {
5803       rtx t = gen_lowpart (QImode, operands[0]);
5804       emit_move_insn (t, operands[1]);
5805       emit_insn (gen_thumb1_extendqisi2 (operands[0], t));
5806       DONE;
5807     }
5809   if (REG_P (addr))
5810     {
5811       addr = gen_rtx_PLUS (Pmode, addr, operands[0]);
5812       operands[2] = const0_rtx;
5813     }
5814   else if (GET_CODE (addr) != PLUS)
5815     FAIL;
5816   else if (REG_P (XEXP (addr, 0)))
5817     {
5818       operands[2] = XEXP (addr, 1);
5819       addr = gen_rtx_PLUS (Pmode, XEXP (addr, 0), operands[0]);
5820     }
5821   else
5822     {
5823       operands[2] = XEXP (addr, 0);
5824       addr = gen_rtx_PLUS (Pmode, XEXP (addr, 1), operands[0]);
5825     }
5827   operands[3] = change_address (operands[1], QImode, addr);
5830 (define_peephole2
5831   [(set (match_operand:SI 0 "register_operand" "")
5832         (plus:SI (match_dup 0) (match_operand 1 "const_int_operand")))
5833    (set (match_operand:SI 2 "register_operand" "") (const_int 0))
5834    (set (match_operand:SI 3 "register_operand" "")
5835         (sign_extend:SI (match_operand:QI 4 "memory_operand" "")))]
5836   "TARGET_THUMB1
5837    && GET_CODE (XEXP (operands[4], 0)) == PLUS
5838    && rtx_equal_p (operands[0], XEXP (XEXP (operands[4], 0), 0))
5839    && rtx_equal_p (operands[2], XEXP (XEXP (operands[4], 0), 1))
5840    && (peep2_reg_dead_p (3, operands[0])
5841        || rtx_equal_p (operands[0], operands[3]))
5842    && (peep2_reg_dead_p (3, operands[2])
5843        || rtx_equal_p (operands[2], operands[3]))"
5844   [(set (match_dup 2) (match_dup 1))
5845    (set (match_dup 3) (sign_extend:SI (match_dup 4)))]
5847   rtx addr = gen_rtx_PLUS (Pmode, operands[0], operands[2]);
5848   operands[4] = change_address (operands[4], QImode, addr);
5851 (define_insn "thumb1_extendqisi2"
5852   [(set (match_operand:SI 0 "register_operand" "=l,l,l")
5853         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "l,V,m")))]
5854   "TARGET_THUMB1"
5856   rtx addr;
5858   if (which_alternative == 0 && arm_arch6)
5859     return "sxtb\\t%0, %1";
5860   if (which_alternative == 0)
5861     return "#";
5863   addr = XEXP (operands[1], 0);
5864   if (GET_CODE (addr) == PLUS
5865       && REG_P (XEXP (addr, 0)) && REG_P (XEXP (addr, 1)))
5866     return "ldrsb\\t%0, %1";
5867       
5868   return "#";
5870   [(set_attr_alternative "length"
5871                          [(if_then_else (eq_attr "is_arch6" "yes")
5872                                         (const_int 2) (const_int 4))
5873                           (const_int 2)
5874                           (if_then_else (eq_attr "is_arch6" "yes")
5875                                         (const_int 4) (const_int 6))])
5876    (set_attr "type" "extend,load_byte,load_byte")]
5879 (define_expand "extendsfdf2"
5880   [(set (match_operand:DF                  0 "s_register_operand" "")
5881         (float_extend:DF (match_operand:SF 1 "s_register_operand"  "")))]
5882   "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
5883   ""
5886 /* HFmode -> DFmode conversions have to go through SFmode.  */
5887 (define_expand "extendhfdf2"
5888   [(set (match_operand:DF                  0 "general_operand" "")
5889         (float_extend:DF (match_operand:HF 1 "general_operand"  "")))]
5890   "TARGET_EITHER"
5891   "
5892   {
5893     rtx op1;
5894     op1 = convert_to_mode (SFmode, operands[1], 0);
5895     op1 = convert_to_mode (DFmode, op1, 0);
5896     emit_insn (gen_movdf (operands[0], op1));
5897     DONE;
5898   }"
5901 ;; Move insns (including loads and stores)
5903 ;; XXX Just some ideas about movti.
5904 ;; I don't think these are a good idea on the arm, there just aren't enough
5905 ;; registers
5906 ;;(define_expand "loadti"
5907 ;;  [(set (match_operand:TI 0 "s_register_operand" "")
5908 ;;      (mem:TI (match_operand:SI 1 "address_operand" "")))]
5909 ;;  "" "")
5911 ;;(define_expand "storeti"
5912 ;;  [(set (mem:TI (match_operand:TI 0 "address_operand" ""))
5913 ;;      (match_operand:TI 1 "s_register_operand" ""))]
5914 ;;  "" "")
5916 ;;(define_expand "movti"
5917 ;;  [(set (match_operand:TI 0 "general_operand" "")
5918 ;;      (match_operand:TI 1 "general_operand" ""))]
5919 ;;  ""
5920 ;;  "
5922 ;;  rtx insn;
5924 ;;  if (MEM_P (operands[0]) && MEM_P (operands[1]))
5925 ;;    operands[1] = copy_to_reg (operands[1]);
5926 ;;  if (MEM_P (operands[0]))
5927 ;;    insn = gen_storeti (XEXP (operands[0], 0), operands[1]);
5928 ;;  else if (MEM_P (operands[1]))
5929 ;;    insn = gen_loadti (operands[0], XEXP (operands[1], 0));
5930 ;;  else
5931 ;;    FAIL;
5933 ;;  emit_insn (insn);
5934 ;;  DONE;
5935 ;;}")
5937 ;; Recognize garbage generated above.
5939 ;;(define_insn ""
5940 ;;  [(set (match_operand:TI 0 "general_operand" "=r,r,r,<,>,m")
5941 ;;      (match_operand:TI 1 "general_operand" "<,>,m,r,r,r"))]
5942 ;;  ""
5943 ;;  "*
5944 ;;  {
5945 ;;    register mem = (which_alternative < 3);
5946 ;;    register const char *template;
5948 ;;    operands[mem] = XEXP (operands[mem], 0);
5949 ;;    switch (which_alternative)
5950 ;;      {
5951 ;;      case 0: template = \"ldmdb\\t%1!, %M0\"; break;
5952 ;;      case 1: template = \"ldmia\\t%1!, %M0\"; break;
5953 ;;      case 2: template = \"ldmia\\t%1, %M0\"; break;
5954 ;;      case 3: template = \"stmdb\\t%0!, %M1\"; break;
5955 ;;      case 4: template = \"stmia\\t%0!, %M1\"; break;
5956 ;;      case 5: template = \"stmia\\t%0, %M1\"; break;
5957 ;;      }
5958 ;;    output_asm_insn (template, operands);
5959 ;;    return \"\";
5960 ;;  }")
5962 (define_expand "movdi"
5963   [(set (match_operand:DI 0 "general_operand" "")
5964         (match_operand:DI 1 "general_operand" ""))]
5965   "TARGET_EITHER"
5966   "
5967   if (can_create_pseudo_p ())
5968     {
5969       if (!REG_P (operands[0]))
5970         operands[1] = force_reg (DImode, operands[1]);
5971     }
5972   "
5975 (define_insn "*arm_movdi"
5976   [(set (match_operand:DI 0 "nonimmediate_di_operand" "=r, r, r, q, m")
5977         (match_operand:DI 1 "di_operand"              "rDa,Db,Dc,mi,q"))]
5978   "TARGET_32BIT
5979    && !(TARGET_HARD_FLOAT && TARGET_VFP)
5980    && !TARGET_IWMMXT
5981    && (   register_operand (operands[0], DImode)
5982        || register_operand (operands[1], DImode))"
5983   "*
5984   switch (which_alternative)
5985     {
5986     case 0:
5987     case 1:
5988     case 2:
5989       return \"#\";
5990     default:
5991       return output_move_double (operands, true, NULL);
5992     }
5993   "
5994   [(set_attr "length" "8,12,16,8,8")
5995    (set_attr "type" "multiple,multiple,multiple,load2,store2")
5996    (set_attr "arm_pool_range" "*,*,*,1020,*")
5997    (set_attr "arm_neg_pool_range" "*,*,*,1004,*")
5998    (set_attr "thumb2_pool_range" "*,*,*,4094,*")
5999    (set_attr "thumb2_neg_pool_range" "*,*,*,0,*")]
6002 (define_split
6003   [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
6004         (match_operand:ANY64 1 "const_double_operand" ""))]
6005   "TARGET_32BIT
6006    && reload_completed
6007    && (arm_const_double_inline_cost (operands[1])
6008        <= arm_max_const_double_inline_cost ())"
6009   [(const_int 0)]
6010   "
6011   arm_split_constant (SET, SImode, curr_insn,
6012                       INTVAL (gen_lowpart (SImode, operands[1])),
6013                       gen_lowpart (SImode, operands[0]), NULL_RTX, 0);
6014   arm_split_constant (SET, SImode, curr_insn,
6015                       INTVAL (gen_highpart_mode (SImode,
6016                                                  GET_MODE (operands[0]),
6017                                                  operands[1])),
6018                       gen_highpart (SImode, operands[0]), NULL_RTX, 0);
6019   DONE;
6020   "
6023 ; If optimizing for size, or if we have load delay slots, then 
6024 ; we want to split the constant into two separate operations. 
6025 ; In both cases this may split a trivial part into a single data op
6026 ; leaving a single complex constant to load.  We can also get longer
6027 ; offsets in a LDR which means we get better chances of sharing the pool
6028 ; entries.  Finally, we can normally do a better job of scheduling
6029 ; LDR instructions than we can with LDM.
6030 ; This pattern will only match if the one above did not.
6031 (define_split
6032   [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
6033         (match_operand:ANY64 1 "const_double_operand" ""))]
6034   "TARGET_ARM && reload_completed
6035    && arm_const_double_by_parts (operands[1])"
6036   [(set (match_dup 0) (match_dup 1))
6037    (set (match_dup 2) (match_dup 3))]
6038   "
6039   operands[2] = gen_highpart (SImode, operands[0]);
6040   operands[3] = gen_highpart_mode (SImode, GET_MODE (operands[0]),
6041                                    operands[1]);
6042   operands[0] = gen_lowpart (SImode, operands[0]);
6043   operands[1] = gen_lowpart (SImode, operands[1]);
6044   "
6047 (define_split
6048   [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
6049         (match_operand:ANY64 1 "arm_general_register_operand" ""))]
6050   "TARGET_EITHER && reload_completed"
6051   [(set (match_dup 0) (match_dup 1))
6052    (set (match_dup 2) (match_dup 3))]
6053   "
6054   operands[2] = gen_highpart (SImode, operands[0]);
6055   operands[3] = gen_highpart (SImode, operands[1]);
6056   operands[0] = gen_lowpart (SImode, operands[0]);
6057   operands[1] = gen_lowpart (SImode, operands[1]);
6059   /* Handle a partial overlap.  */
6060   if (rtx_equal_p (operands[0], operands[3]))
6061     {
6062       rtx tmp0 = operands[0];
6063       rtx tmp1 = operands[1];
6065       operands[0] = operands[2];
6066       operands[1] = operands[3];
6067       operands[2] = tmp0;
6068       operands[3] = tmp1;
6069     }
6070   "
6073 ;; We can't actually do base+index doubleword loads if the index and
6074 ;; destination overlap.  Split here so that we at least have chance to
6075 ;; schedule.
6076 (define_split
6077   [(set (match_operand:DI 0 "s_register_operand" "")
6078         (mem:DI (plus:SI (match_operand:SI 1 "s_register_operand" "")
6079                          (match_operand:SI 2 "s_register_operand" ""))))]
6080   "TARGET_LDRD
6081   && reg_overlap_mentioned_p (operands[0], operands[1])
6082   && reg_overlap_mentioned_p (operands[0], operands[2])"
6083   [(set (match_dup 4)
6084         (plus:SI (match_dup 1)
6085                  (match_dup 2)))
6086    (set (match_dup 0)
6087         (mem:DI (match_dup 4)))]
6088   "
6089   operands[4] = gen_rtx_REG (SImode, REGNO(operands[0]));
6090   "
6093 ;;; ??? This should have alternatives for constants.
6094 ;;; ??? This was originally identical to the movdf_insn pattern.
6095 ;;; ??? The 'i' constraint looks funny, but it should always be replaced by
6096 ;;; thumb_reorg with a memory reference.
6097 (define_insn "*thumb1_movdi_insn"
6098   [(set (match_operand:DI 0 "nonimmediate_operand" "=l,l,l,l,>,l, m,*r")
6099         (match_operand:DI 1 "general_operand"      "l, I,J,>,l,mi,l,*r"))]
6100   "TARGET_THUMB1
6101    && (   register_operand (operands[0], DImode)
6102        || register_operand (operands[1], DImode))"
6103   "*
6104   {
6105   switch (which_alternative)
6106     {
6107     default:
6108     case 0:
6109       if (REGNO (operands[1]) == REGNO (operands[0]) + 1)
6110         return \"add\\t%0,  %1,  #0\;add\\t%H0, %H1, #0\";
6111       return   \"add\\t%H0, %H1, #0\;add\\t%0,  %1,  #0\";
6112     case 1:
6113       return \"mov\\t%Q0, %1\;mov\\t%R0, #0\";
6114     case 2:
6115       operands[1] = GEN_INT (- INTVAL (operands[1]));
6116       return \"mov\\t%Q0, %1\;neg\\t%Q0, %Q0\;asr\\t%R0, %Q0, #31\";
6117     case 3:
6118       return \"ldmia\\t%1, {%0, %H0}\";
6119     case 4:
6120       return \"stmia\\t%0, {%1, %H1}\";
6121     case 5:
6122       return thumb_load_double_from_address (operands);
6123     case 6:
6124       operands[2] = gen_rtx_MEM (SImode,
6125                              plus_constant (Pmode, XEXP (operands[0], 0), 4));
6126       output_asm_insn (\"str\\t%1, %0\;str\\t%H1, %2\", operands);
6127       return \"\";
6128     case 7:
6129       if (REGNO (operands[1]) == REGNO (operands[0]) + 1)
6130         return \"mov\\t%0, %1\;mov\\t%H0, %H1\";
6131       return \"mov\\t%H0, %H1\;mov\\t%0, %1\";
6132     }
6133   }"
6134   [(set_attr "length" "4,4,6,2,2,6,4,4")
6135    (set_attr "type" "multiple,multiple,multiple,load2,store2,load2,store2,multiple")
6136    (set_attr "pool_range" "*,*,*,*,*,1018,*,*")]
6139 (define_expand "movsi"
6140   [(set (match_operand:SI 0 "general_operand" "")
6141         (match_operand:SI 1 "general_operand" ""))]
6142   "TARGET_EITHER"
6143   "
6144   {
6145   rtx base, offset, tmp;
6147   if (TARGET_32BIT)
6148     {
6149       /* Everything except mem = const or mem = mem can be done easily.  */
6150       if (MEM_P (operands[0]))
6151         operands[1] = force_reg (SImode, operands[1]);
6152       if (arm_general_register_operand (operands[0], SImode)
6153           && CONST_INT_P (operands[1])
6154           && !(const_ok_for_arm (INTVAL (operands[1]))
6155                || const_ok_for_arm (~INTVAL (operands[1]))))
6156         {
6157            arm_split_constant (SET, SImode, NULL_RTX,
6158                                INTVAL (operands[1]), operands[0], NULL_RTX,
6159                                optimize && can_create_pseudo_p ());
6160           DONE;
6161         }
6162     }
6163   else /* TARGET_THUMB1...  */
6164     {
6165       if (can_create_pseudo_p ())
6166         {
6167           if (!REG_P (operands[0]))
6168             operands[1] = force_reg (SImode, operands[1]);
6169         }
6170     }
6172   if (ARM_OFFSETS_MUST_BE_WITHIN_SECTIONS_P)
6173     {
6174       split_const (operands[1], &base, &offset);
6175       if (GET_CODE (base) == SYMBOL_REF
6176           && !offset_within_block_p (base, INTVAL (offset)))
6177         {
6178           tmp = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];
6179           emit_move_insn (tmp, base);
6180           emit_insn (gen_addsi3 (operands[0], tmp, offset));
6181           DONE;
6182         }
6183     }
6185   /* Recognize the case where operand[1] is a reference to thread-local
6186      data and load its address to a register.  */
6187   if (arm_tls_referenced_p (operands[1]))
6188     {
6189       rtx tmp = operands[1];
6190       rtx addend = NULL;
6192       if (GET_CODE (tmp) == CONST && GET_CODE (XEXP (tmp, 0)) == PLUS)
6193         {
6194           addend = XEXP (XEXP (tmp, 0), 1);
6195           tmp = XEXP (XEXP (tmp, 0), 0);
6196         }
6198       gcc_assert (GET_CODE (tmp) == SYMBOL_REF);
6199       gcc_assert (SYMBOL_REF_TLS_MODEL (tmp) != 0);
6201       tmp = legitimize_tls_address (tmp,
6202                                     !can_create_pseudo_p () ? operands[0] : 0);
6203       if (addend)
6204         {
6205           tmp = gen_rtx_PLUS (SImode, tmp, addend);
6206           tmp = force_operand (tmp, operands[0]);
6207         }
6208       operands[1] = tmp;
6209     }
6210   else if (flag_pic
6211            && (CONSTANT_P (operands[1])
6212                || symbol_mentioned_p (operands[1])
6213                || label_mentioned_p (operands[1])))
6214       operands[1] = legitimize_pic_address (operands[1], SImode,
6215                                             (!can_create_pseudo_p ()
6216                                              ? operands[0]
6217                                              : 0));
6218   }
6219   "
6222 ;; The ARM LO_SUM and HIGH are backwards - HIGH sets the low bits, and
6223 ;; LO_SUM adds in the high bits.  Fortunately these are opaque operations
6224 ;; so this does not matter.
6225 (define_insn "*arm_movt"
6226   [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
6227         (lo_sum:SI (match_operand:SI 1 "nonimmediate_operand" "0")
6228                    (match_operand:SI 2 "general_operand"      "i")))]
6229   "arm_arch_thumb2"
6230   "movt%?\t%0, #:upper16:%c2"
6231   [(set_attr "predicable" "yes")
6232    (set_attr "predicable_short_it" "no")
6233    (set_attr "length" "4")
6234    (set_attr "type" "mov_imm")]
6237 (define_insn "*arm_movsi_insn"
6238   [(set (match_operand:SI 0 "nonimmediate_operand" "=rk,r,r,r,rk,m")
6239         (match_operand:SI 1 "general_operand"      "rk, I,K,j,mi,rk"))]
6240   "TARGET_ARM && ! TARGET_IWMMXT
6241    && !(TARGET_HARD_FLOAT && TARGET_VFP)
6242    && (   register_operand (operands[0], SImode)
6243        || register_operand (operands[1], SImode))"
6244   "@
6245    mov%?\\t%0, %1
6246    mov%?\\t%0, %1
6247    mvn%?\\t%0, #%B1
6248    movw%?\\t%0, %1
6249    ldr%?\\t%0, %1
6250    str%?\\t%1, %0"
6251   [(set_attr "type" "mov_reg,mov_imm,mvn_imm,mov_imm,load1,store1")
6252    (set_attr "predicable" "yes")
6253    (set_attr "pool_range" "*,*,*,*,4096,*")
6254    (set_attr "neg_pool_range" "*,*,*,*,4084,*")]
6257 (define_split
6258   [(set (match_operand:SI 0 "arm_general_register_operand" "")
6259         (match_operand:SI 1 "const_int_operand" ""))]
6260   "TARGET_32BIT
6261   && (!(const_ok_for_arm (INTVAL (operands[1]))
6262         || const_ok_for_arm (~INTVAL (operands[1]))))"
6263   [(clobber (const_int 0))]
6264   "
6265   arm_split_constant (SET, SImode, NULL_RTX, 
6266                       INTVAL (operands[1]), operands[0], NULL_RTX, 0);
6267   DONE;
6268   "
6271 ;; A normal way to do (symbol + offset) requires three instructions at least
6272 ;; (depends on how big the offset is) as below:
6273 ;; movw r0, #:lower16:g
6274 ;; movw r0, #:upper16:g
6275 ;; adds r0, #4
6277 ;; A better way would be:
6278 ;; movw r0, #:lower16:g+4
6279 ;; movw r0, #:upper16:g+4
6281 ;; The limitation of this way is that the length of offset should be a 16-bit
6282 ;; signed value, because current assembler only supports REL type relocation for
6283 ;; such case.  If the more powerful RELA type is supported in future, we should
6284 ;; update this pattern to go with better way.
6285 (define_split
6286   [(set (match_operand:SI 0 "arm_general_register_operand" "")
6287         (const:SI (plus:SI (match_operand:SI 1 "general_operand" "")
6288                            (match_operand:SI 2 "const_int_operand" ""))))]
6289   "TARGET_THUMB2
6290    && arm_disable_literal_pool
6291    && reload_completed
6292    && GET_CODE (operands[1]) == SYMBOL_REF"
6293   [(clobber (const_int 0))]
6294   "
6295     int offset = INTVAL (operands[2]);
6297     if (offset < -0x8000 || offset > 0x7fff)
6298       {
6299         arm_emit_movpair (operands[0], operands[1]);
6300         emit_insn (gen_rtx_SET (SImode, operands[0],
6301                                 gen_rtx_PLUS (SImode, operands[0], operands[2])));
6302       }
6303     else
6304       {
6305         rtx op = gen_rtx_CONST (SImode,
6306                                 gen_rtx_PLUS (SImode, operands[1], operands[2]));
6307         arm_emit_movpair (operands[0], op);
6308       }
6309   "
6312 ;; Split symbol_refs at the later stage (after cprop), instead of generating
6313 ;; movt/movw pair directly at expand.  Otherwise corresponding high_sum
6314 ;; and lo_sum would be merged back into memory load at cprop.  However,
6315 ;; if the default is to prefer movt/movw rather than a load from the constant
6316 ;; pool, the performance is better.
6317 (define_split
6318   [(set (match_operand:SI 0 "arm_general_register_operand" "")
6319        (match_operand:SI 1 "general_operand" ""))]
6320   "TARGET_32BIT
6321    && TARGET_USE_MOVT && GET_CODE (operands[1]) == SYMBOL_REF
6322    && !flag_pic && !target_word_relocations
6323    && !arm_tls_referenced_p (operands[1])"
6324   [(clobber (const_int 0))]
6326   arm_emit_movpair (operands[0], operands[1]);
6327   DONE;
6330 (define_insn "*thumb1_movsi_insn"
6331   [(set (match_operand:SI 0 "nonimmediate_operand" "=l,l,l,l,l,>,l, m,*l*h*k")
6332         (match_operand:SI 1 "general_operand"      "l, I,J,K,>,l,mi,l,*l*h*k"))]
6333   "TARGET_THUMB1
6334    && (   register_operand (operands[0], SImode) 
6335        || register_operand (operands[1], SImode))"
6336   "@
6337    mov  %0, %1
6338    mov  %0, %1
6339    #
6340    #
6341    ldmia\\t%1, {%0}
6342    stmia\\t%0, {%1}
6343    ldr\\t%0, %1
6344    str\\t%1, %0
6345    mov\\t%0, %1"
6346   [(set_attr "length" "2,2,4,4,2,2,2,2,2")
6347    (set_attr "type" "mov_reg,mov_imm,multiple,multiple,load1,store1,load1,store1,mov_reg")
6348    (set_attr "pool_range" "*,*,*,*,*,*,1018,*,*")
6349    (set_attr "conds" "set,clob,*,*,nocond,nocond,nocond,nocond,nocond")])
6351 (define_split 
6352   [(set (match_operand:SI 0 "register_operand" "")
6353         (match_operand:SI 1 "const_int_operand" ""))]
6354   "TARGET_THUMB1 && satisfies_constraint_J (operands[1])"
6355   [(set (match_dup 2) (match_dup 1))
6356    (set (match_dup 0) (neg:SI (match_dup 2)))]
6357   "
6358   {
6359     operands[1] = GEN_INT (- INTVAL (operands[1]));
6360     operands[2] = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];
6361   }"
6364 (define_split 
6365   [(set (match_operand:SI 0 "register_operand" "")
6366         (match_operand:SI 1 "const_int_operand" ""))]
6367   "TARGET_THUMB1 && satisfies_constraint_K (operands[1])"
6368   [(set (match_dup 2) (match_dup 1))
6369    (set (match_dup 0) (ashift:SI (match_dup 2) (match_dup 3)))]
6370   "
6371   {
6372     unsigned HOST_WIDE_INT val = INTVAL (operands[1]) & 0xffffffffu;
6373     unsigned HOST_WIDE_INT mask = 0xff;
6374     int i;
6375     
6376     for (i = 0; i < 25; i++)
6377       if ((val & (mask << i)) == val)
6378         break;
6380     /* Don't split if the shift is zero.  */
6381     if (i == 0)
6382       FAIL;
6384     operands[1] = GEN_INT (val >> i);
6385     operands[2] = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];
6386     operands[3] = GEN_INT (i);
6387   }"
6390 ;; For thumb1 split imm move [256-510] into mov [1-255] and add #255
6391 (define_split 
6392   [(set (match_operand:SI 0 "register_operand" "")
6393         (match_operand:SI 1 "const_int_operand" ""))]
6394   "TARGET_THUMB1 && satisfies_constraint_Pe (operands[1])"
6395   [(set (match_dup 2) (match_dup 1))
6396    (set (match_dup 0) (plus:SI (match_dup 2) (match_dup 3)))]
6397   "
6398   {
6399     operands[1] = GEN_INT (INTVAL (operands[1]) - 255);
6400     operands[2] = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];
6401     operands[3] = GEN_INT (255);
6402   }"
6405 ;; When generating pic, we need to load the symbol offset into a register.
6406 ;; So that the optimizer does not confuse this with a normal symbol load
6407 ;; we use an unspec.  The offset will be loaded from a constant pool entry,
6408 ;; since that is the only type of relocation we can use.
6410 ;; Wrap calculation of the whole PIC address in a single pattern for the
6411 ;; benefit of optimizers, particularly, PRE and HOIST.  Calculation of
6412 ;; a PIC address involves two loads from memory, so we want to CSE it
6413 ;; as often as possible.
6414 ;; This pattern will be split into one of the pic_load_addr_* patterns
6415 ;; and a move after GCSE optimizations.
6417 ;; Note: Update arm.c: legitimize_pic_address() when changing this pattern.
6418 (define_expand "calculate_pic_address"
6419   [(set (match_operand:SI 0 "register_operand" "")
6420         (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "")
6421                          (unspec:SI [(match_operand:SI 2 "" "")]
6422                                     UNSPEC_PIC_SYM))))]
6423   "flag_pic"
6426 ;; Split calculate_pic_address into pic_load_addr_* and a move.
6427 (define_split
6428   [(set (match_operand:SI 0 "register_operand" "")
6429         (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "")
6430                          (unspec:SI [(match_operand:SI 2 "" "")]
6431                                     UNSPEC_PIC_SYM))))]
6432   "flag_pic"
6433   [(set (match_dup 3) (unspec:SI [(match_dup 2)] UNSPEC_PIC_SYM))
6434    (set (match_dup 0) (mem:SI (plus:SI (match_dup 1) (match_dup 3))))]
6435   "operands[3] = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];"
6438 ;; operand1 is the memory address to go into 
6439 ;; pic_load_addr_32bit.
6440 ;; operand2 is the PIC label to be emitted 
6441 ;; from pic_add_dot_plus_eight.
6442 ;; We do this to allow hoisting of the entire insn.
6443 (define_insn_and_split "pic_load_addr_unified"
6444   [(set (match_operand:SI 0 "s_register_operand" "=r,r,l")
6445         (unspec:SI [(match_operand:SI 1 "" "mX,mX,mX") 
6446                     (match_operand:SI 2 "" "")] 
6447                     UNSPEC_PIC_UNIFIED))]
6448  "flag_pic"
6449  "#"
6450  "&& reload_completed"
6451  [(set (match_dup 0) (unspec:SI [(match_dup 1)] UNSPEC_PIC_SYM))
6452   (set (match_dup 0) (unspec:SI [(match_dup 0) (match_dup 3)
6453                                  (match_dup 2)] UNSPEC_PIC_BASE))]
6454  "operands[3] = TARGET_THUMB ? GEN_INT (4) : GEN_INT (8);"
6455  [(set_attr "type" "load1,load1,load1")
6456   (set_attr "pool_range" "4096,4094,1022")
6457   (set_attr "neg_pool_range" "4084,0,0")
6458   (set_attr "arch"  "a,t2,t1")    
6459   (set_attr "length" "8,6,4")]
6462 ;; The rather odd constraints on the following are to force reload to leave
6463 ;; the insn alone, and to force the minipool generation pass to then move
6464 ;; the GOT symbol to memory.
6466 (define_insn "pic_load_addr_32bit"
6467   [(set (match_operand:SI 0 "s_register_operand" "=r")
6468         (unspec:SI [(match_operand:SI 1 "" "mX")] UNSPEC_PIC_SYM))]
6469   "TARGET_32BIT && flag_pic"
6470   "ldr%?\\t%0, %1"
6471   [(set_attr "type" "load1")
6472    (set (attr "pool_range")
6473         (if_then_else (eq_attr "is_thumb" "no")
6474                       (const_int 4096)
6475                       (const_int 4094)))
6476    (set (attr "neg_pool_range")
6477         (if_then_else (eq_attr "is_thumb" "no")
6478                       (const_int 4084)
6479                       (const_int 0)))]
6482 (define_insn "pic_load_addr_thumb1"
6483   [(set (match_operand:SI 0 "s_register_operand" "=l")
6484         (unspec:SI [(match_operand:SI 1 "" "mX")] UNSPEC_PIC_SYM))]
6485   "TARGET_THUMB1 && flag_pic"
6486   "ldr\\t%0, %1"
6487   [(set_attr "type" "load1")
6488    (set (attr "pool_range") (const_int 1018))]
6491 (define_insn "pic_add_dot_plus_four"
6492   [(set (match_operand:SI 0 "register_operand" "=r")
6493         (unspec:SI [(match_operand:SI 1 "register_operand" "0")
6494                     (const_int 4)
6495                     (match_operand 2 "" "")]
6496                    UNSPEC_PIC_BASE))]
6497   "TARGET_THUMB"
6498   "*
6499   (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
6500                                      INTVAL (operands[2]));
6501   return \"add\\t%0, %|pc\";
6502   "
6503   [(set_attr "length" "2")
6504    (set_attr "type" "alu_reg")]
6507 (define_insn "pic_add_dot_plus_eight"
6508   [(set (match_operand:SI 0 "register_operand" "=r")
6509         (unspec:SI [(match_operand:SI 1 "register_operand" "r")
6510                     (const_int 8)
6511                     (match_operand 2 "" "")]
6512                    UNSPEC_PIC_BASE))]
6513   "TARGET_ARM"
6514   "*
6515     (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
6516                                        INTVAL (operands[2]));
6517     return \"add%?\\t%0, %|pc, %1\";
6518   "
6519   [(set_attr "predicable" "yes")
6520    (set_attr "type" "alu_reg")]
6523 (define_insn "tls_load_dot_plus_eight"
6524   [(set (match_operand:SI 0 "register_operand" "=r")
6525         (mem:SI (unspec:SI [(match_operand:SI 1 "register_operand" "r")
6526                             (const_int 8)
6527                             (match_operand 2 "" "")]
6528                            UNSPEC_PIC_BASE)))]
6529   "TARGET_ARM"
6530   "*
6531     (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
6532                                        INTVAL (operands[2]));
6533     return \"ldr%?\\t%0, [%|pc, %1]\t\t@ tls_load_dot_plus_eight\";
6534   "
6535   [(set_attr "predicable" "yes")
6536    (set_attr "type" "load1")]
6539 ;; PIC references to local variables can generate pic_add_dot_plus_eight
6540 ;; followed by a load.  These sequences can be crunched down to
6541 ;; tls_load_dot_plus_eight by a peephole.
6543 (define_peephole2
6544   [(set (match_operand:SI 0 "register_operand" "")
6545         (unspec:SI [(match_operand:SI 3 "register_operand" "")
6546                     (const_int 8)
6547                     (match_operand 1 "" "")]
6548                    UNSPEC_PIC_BASE))
6549    (set (match_operand:SI 2 "arm_general_register_operand" "")
6550         (mem:SI (match_dup 0)))]
6551   "TARGET_ARM && peep2_reg_dead_p (2, operands[0])"
6552   [(set (match_dup 2)
6553         (mem:SI (unspec:SI [(match_dup 3)
6554                             (const_int 8)
6555                             (match_dup 1)]
6556                            UNSPEC_PIC_BASE)))]
6557   ""
6560 (define_insn "pic_offset_arm"
6561   [(set (match_operand:SI 0 "register_operand" "=r")
6562         (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
6563                          (unspec:SI [(match_operand:SI 2 "" "X")]
6564                                     UNSPEC_PIC_OFFSET))))]
6565   "TARGET_VXWORKS_RTP && TARGET_ARM && flag_pic"
6566   "ldr%?\\t%0, [%1,%2]"
6567   [(set_attr "type" "load1")]
6570 (define_expand "builtin_setjmp_receiver"
6571   [(label_ref (match_operand 0 "" ""))]
6572   "flag_pic"
6573   "
6575   /* r3 is clobbered by set/longjmp, so we can use it as a scratch
6576      register.  */
6577   if (arm_pic_register != INVALID_REGNUM)
6578     arm_load_pic_register (1UL << 3);
6579   DONE;
6582 ;; If copying one reg to another we can set the condition codes according to
6583 ;; its value.  Such a move is common after a return from subroutine and the
6584 ;; result is being tested against zero.
6586 (define_insn "*movsi_compare0"
6587   [(set (reg:CC CC_REGNUM)
6588         (compare:CC (match_operand:SI 1 "s_register_operand" "0,r")
6589                     (const_int 0)))
6590    (set (match_operand:SI 0 "s_register_operand" "=r,r")
6591         (match_dup 1))]
6592   "TARGET_32BIT"
6593   "@
6594    cmp%?\\t%0, #0
6595    sub%.\\t%0, %1, #0"
6596   [(set_attr "conds" "set")
6597    (set_attr "type" "alus_imm,alus_imm")]
6600 ;; Subroutine to store a half word from a register into memory.
6601 ;; Operand 0 is the source register (HImode)
6602 ;; Operand 1 is the destination address in a register (SImode)
6604 ;; In both this routine and the next, we must be careful not to spill
6605 ;; a memory address of reg+large_const into a separate PLUS insn, since this
6606 ;; can generate unrecognizable rtl.
6608 (define_expand "storehi"
6609   [;; store the low byte
6610    (set (match_operand 1 "" "") (match_dup 3))
6611    ;; extract the high byte
6612    (set (match_dup 2)
6613         (ashiftrt:SI (match_operand 0 "" "") (const_int 8)))
6614    ;; store the high byte
6615    (set (match_dup 4) (match_dup 5))]
6616   "TARGET_ARM"
6617   "
6618   {
6619     rtx op1 = operands[1];
6620     rtx addr = XEXP (op1, 0);
6621     enum rtx_code code = GET_CODE (addr);
6623     if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1)))
6624         || code == MINUS)
6625       op1 = replace_equiv_address (operands[1], force_reg (SImode, addr));
6627     operands[4] = adjust_address (op1, QImode, 1);
6628     operands[1] = adjust_address (operands[1], QImode, 0);
6629     operands[3] = gen_lowpart (QImode, operands[0]);
6630     operands[0] = gen_lowpart (SImode, operands[0]);
6631     operands[2] = gen_reg_rtx (SImode);
6632     operands[5] = gen_lowpart (QImode, operands[2]);
6633   }"
6636 (define_expand "storehi_bigend"
6637   [(set (match_dup 4) (match_dup 3))
6638    (set (match_dup 2)
6639         (ashiftrt:SI (match_operand 0 "" "") (const_int 8)))
6640    (set (match_operand 1 "" "") (match_dup 5))]
6641   "TARGET_ARM"
6642   "
6643   {
6644     rtx op1 = operands[1];
6645     rtx addr = XEXP (op1, 0);
6646     enum rtx_code code = GET_CODE (addr);
6648     if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1)))
6649         || code == MINUS)
6650       op1 = replace_equiv_address (op1, force_reg (SImode, addr));
6652     operands[4] = adjust_address (op1, QImode, 1);
6653     operands[1] = adjust_address (operands[1], QImode, 0);
6654     operands[3] = gen_lowpart (QImode, operands[0]);
6655     operands[0] = gen_lowpart (SImode, operands[0]);
6656     operands[2] = gen_reg_rtx (SImode);
6657     operands[5] = gen_lowpart (QImode, operands[2]);
6658   }"
6661 ;; Subroutine to store a half word integer constant into memory.
6662 (define_expand "storeinthi"
6663   [(set (match_operand 0 "" "")
6664         (match_operand 1 "" ""))
6665    (set (match_dup 3) (match_dup 2))]
6666   "TARGET_ARM"
6667   "
6668   {
6669     HOST_WIDE_INT value = INTVAL (operands[1]);
6670     rtx addr = XEXP (operands[0], 0);
6671     rtx op0 = operands[0];
6672     enum rtx_code code = GET_CODE (addr);
6674     if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1)))
6675         || code == MINUS)
6676       op0 = replace_equiv_address (op0, force_reg (SImode, addr));
6678     operands[1] = gen_reg_rtx (SImode);
6679     if (BYTES_BIG_ENDIAN)
6680       {
6681         emit_insn (gen_movsi (operands[1], GEN_INT ((value >> 8) & 255)));
6682         if ((value & 255) == ((value >> 8) & 255))
6683           operands[2] = operands[1];
6684         else
6685           {
6686             operands[2] = gen_reg_rtx (SImode);
6687             emit_insn (gen_movsi (operands[2], GEN_INT (value & 255)));
6688           }
6689       }
6690     else
6691       {
6692         emit_insn (gen_movsi (operands[1], GEN_INT (value & 255)));
6693         if ((value & 255) == ((value >> 8) & 255))
6694           operands[2] = operands[1];
6695         else
6696           {
6697             operands[2] = gen_reg_rtx (SImode);
6698             emit_insn (gen_movsi (operands[2], GEN_INT ((value >> 8) & 255)));
6699           }
6700       }
6702     operands[3] = adjust_address (op0, QImode, 1);
6703     operands[0] = adjust_address (operands[0], QImode, 0);
6704     operands[2] = gen_lowpart (QImode, operands[2]);
6705     operands[1] = gen_lowpart (QImode, operands[1]);
6706   }"
6709 (define_expand "storehi_single_op"
6710   [(set (match_operand:HI 0 "memory_operand" "")
6711         (match_operand:HI 1 "general_operand" ""))]
6712   "TARGET_32BIT && arm_arch4"
6713   "
6714   if (!s_register_operand (operands[1], HImode))
6715     operands[1] = copy_to_mode_reg (HImode, operands[1]);
6716   "
6719 (define_expand "movhi"
6720   [(set (match_operand:HI 0 "general_operand" "")
6721         (match_operand:HI 1 "general_operand" ""))]
6722   "TARGET_EITHER"
6723   "
6724   if (TARGET_ARM)
6725     {
6726       if (can_create_pseudo_p ())
6727         {
6728           if (MEM_P (operands[0]))
6729             {
6730               if (arm_arch4)
6731                 {
6732                   emit_insn (gen_storehi_single_op (operands[0], operands[1]));
6733                   DONE;
6734                 }
6735               if (CONST_INT_P (operands[1]))
6736                 emit_insn (gen_storeinthi (operands[0], operands[1]));
6737               else
6738                 {
6739                   if (MEM_P (operands[1]))
6740                     operands[1] = force_reg (HImode, operands[1]);
6741                   if (BYTES_BIG_ENDIAN)
6742                     emit_insn (gen_storehi_bigend (operands[1], operands[0]));
6743                   else
6744                    emit_insn (gen_storehi (operands[1], operands[0]));
6745                 }
6746               DONE;
6747             }
6748           /* Sign extend a constant, and keep it in an SImode reg.  */
6749           else if (CONST_INT_P (operands[1]))
6750             {
6751               rtx reg = gen_reg_rtx (SImode);
6752               HOST_WIDE_INT val = INTVAL (operands[1]) & 0xffff;
6754               /* If the constant is already valid, leave it alone.  */
6755               if (!const_ok_for_arm (val))
6756                 {
6757                   /* If setting all the top bits will make the constant 
6758                      loadable in a single instruction, then set them.  
6759                      Otherwise, sign extend the number.  */
6761                   if (const_ok_for_arm (~(val | ~0xffff)))
6762                     val |= ~0xffff;
6763                   else if (val & 0x8000)
6764                     val |= ~0xffff;
6765                 }
6767               emit_insn (gen_movsi (reg, GEN_INT (val)));
6768               operands[1] = gen_lowpart (HImode, reg);
6769             }
6770           else if (arm_arch4 && optimize && can_create_pseudo_p ()
6771                    && MEM_P (operands[1]))
6772             {
6773               rtx reg = gen_reg_rtx (SImode);
6775               emit_insn (gen_zero_extendhisi2 (reg, operands[1]));
6776               operands[1] = gen_lowpart (HImode, reg);
6777             }
6778           else if (!arm_arch4)
6779             {
6780               if (MEM_P (operands[1]))
6781                 {
6782                   rtx base;
6783                   rtx offset = const0_rtx;
6784                   rtx reg = gen_reg_rtx (SImode);
6786                   if ((REG_P (base = XEXP (operands[1], 0))
6787                        || (GET_CODE (base) == PLUS
6788                            && (CONST_INT_P (offset = XEXP (base, 1)))
6789                            && ((INTVAL(offset) & 1) != 1)
6790                            && REG_P (base = XEXP (base, 0))))
6791                       && REGNO_POINTER_ALIGN (REGNO (base)) >= 32)
6792                     {
6793                       rtx new_rtx;
6795                       new_rtx = widen_memory_access (operands[1], SImode,
6796                                                      ((INTVAL (offset) & ~3)
6797                                                       - INTVAL (offset)));
6798                       emit_insn (gen_movsi (reg, new_rtx));
6799                       if (((INTVAL (offset) & 2) != 0)
6800                           ^ (BYTES_BIG_ENDIAN ? 1 : 0))
6801                         {
6802                           rtx reg2 = gen_reg_rtx (SImode);
6804                           emit_insn (gen_lshrsi3 (reg2, reg, GEN_INT (16)));
6805                           reg = reg2;
6806                         }
6807                     }
6808                   else
6809                     emit_insn (gen_movhi_bytes (reg, operands[1]));
6811                   operands[1] = gen_lowpart (HImode, reg);
6812                }
6813            }
6814         }
6815       /* Handle loading a large integer during reload.  */
6816       else if (CONST_INT_P (operands[1])
6817                && !const_ok_for_arm (INTVAL (operands[1]))
6818                && !const_ok_for_arm (~INTVAL (operands[1])))
6819         {
6820           /* Writing a constant to memory needs a scratch, which should
6821              be handled with SECONDARY_RELOADs.  */
6822           gcc_assert (REG_P (operands[0]));
6824           operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
6825           emit_insn (gen_movsi (operands[0], operands[1]));
6826           DONE;
6827        }
6828     }
6829   else if (TARGET_THUMB2)
6830     {
6831       /* Thumb-2 can do everything except mem=mem and mem=const easily.  */
6832       if (can_create_pseudo_p ())
6833         {
6834           if (!REG_P (operands[0]))
6835             operands[1] = force_reg (HImode, operands[1]);
6836           /* Zero extend a constant, and keep it in an SImode reg.  */
6837           else if (CONST_INT_P (operands[1]))
6838             {
6839               rtx reg = gen_reg_rtx (SImode);
6840               HOST_WIDE_INT val = INTVAL (operands[1]) & 0xffff;
6842               emit_insn (gen_movsi (reg, GEN_INT (val)));
6843               operands[1] = gen_lowpart (HImode, reg);
6844             }
6845         }
6846     }
6847   else /* TARGET_THUMB1 */
6848     {
6849       if (can_create_pseudo_p ())
6850         {
6851           if (CONST_INT_P (operands[1]))
6852             {
6853               rtx reg = gen_reg_rtx (SImode);
6855               emit_insn (gen_movsi (reg, operands[1]));
6856               operands[1] = gen_lowpart (HImode, reg);
6857             }
6859           /* ??? We shouldn't really get invalid addresses here, but this can
6860              happen if we are passed a SP (never OK for HImode/QImode) or 
6861              virtual register (also rejected as illegitimate for HImode/QImode)
6862              relative address.  */
6863           /* ??? This should perhaps be fixed elsewhere, for instance, in
6864              fixup_stack_1, by checking for other kinds of invalid addresses,
6865              e.g. a bare reference to a virtual register.  This may confuse the
6866              alpha though, which must handle this case differently.  */
6867           if (MEM_P (operands[0])
6868               && !memory_address_p (GET_MODE (operands[0]),
6869                                     XEXP (operands[0], 0)))
6870             operands[0]
6871               = replace_equiv_address (operands[0],
6872                                        copy_to_reg (XEXP (operands[0], 0)));
6873    
6874           if (MEM_P (operands[1])
6875               && !memory_address_p (GET_MODE (operands[1]),
6876                                     XEXP (operands[1], 0)))
6877             operands[1]
6878               = replace_equiv_address (operands[1],
6879                                        copy_to_reg (XEXP (operands[1], 0)));
6881           if (MEM_P (operands[1]) && optimize > 0)
6882             {
6883               rtx reg = gen_reg_rtx (SImode);
6885               emit_insn (gen_zero_extendhisi2 (reg, operands[1]));
6886               operands[1] = gen_lowpart (HImode, reg);
6887             }
6889           if (MEM_P (operands[0]))
6890             operands[1] = force_reg (HImode, operands[1]);
6891         }
6892       else if (CONST_INT_P (operands[1])
6893                 && !satisfies_constraint_I (operands[1]))
6894         {
6895           /* Handle loading a large integer during reload.  */
6897           /* Writing a constant to memory needs a scratch, which should
6898              be handled with SECONDARY_RELOADs.  */
6899           gcc_assert (REG_P (operands[0]));
6901           operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
6902           emit_insn (gen_movsi (operands[0], operands[1]));
6903           DONE;
6904         }
6905     }
6906   "
6909 (define_insn "*thumb1_movhi_insn"
6910   [(set (match_operand:HI 0 "nonimmediate_operand" "=l,l,m,*r,*h,l")
6911         (match_operand:HI 1 "general_operand"       "l,m,l,*h,*r,I"))]
6912   "TARGET_THUMB1
6913    && (   register_operand (operands[0], HImode)
6914        || register_operand (operands[1], HImode))"
6915   "*
6916   switch (which_alternative)
6917     {
6918     case 0: return \"add        %0, %1, #0\";
6919     case 2: return \"strh       %1, %0\";
6920     case 3: return \"mov        %0, %1\";
6921     case 4: return \"mov        %0, %1\";
6922     case 5: return \"mov        %0, %1\";
6923     default: gcc_unreachable ();
6924     case 1:
6925       /* The stack pointer can end up being taken as an index register.
6926           Catch this case here and deal with it.  */
6927       if (GET_CODE (XEXP (operands[1], 0)) == PLUS
6928           && REG_P (XEXP (XEXP (operands[1], 0), 0))
6929           && REGNO    (XEXP (XEXP (operands[1], 0), 0)) == SP_REGNUM)
6930         {
6931           rtx ops[2];
6932           ops[0] = operands[0];
6933           ops[1] = XEXP (XEXP (operands[1], 0), 0);
6934       
6935           output_asm_insn (\"mov        %0, %1\", ops);
6937           XEXP (XEXP (operands[1], 0), 0) = operands[0];
6938     
6939         }
6940       return \"ldrh     %0, %1\";
6941     }"
6942   [(set_attr "length" "2,4,2,2,2,2")
6943    (set_attr "type" "alus_imm,load1,store1,mov_reg,mov_reg,mov_imm")
6944    (set_attr "conds" "clob,nocond,nocond,nocond,nocond,clob")])
6947 (define_expand "movhi_bytes"
6948   [(set (match_dup 2) (zero_extend:SI (match_operand:HI 1 "" "")))
6949    (set (match_dup 3)
6950         (zero_extend:SI (match_dup 6)))
6951    (set (match_operand:SI 0 "" "")
6952          (ior:SI (ashift:SI (match_dup 4) (const_int 8)) (match_dup 5)))]
6953   "TARGET_ARM"
6954   "
6955   {
6956     rtx mem1, mem2;
6957     rtx addr = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
6959     mem1 = change_address (operands[1], QImode, addr);
6960     mem2 = change_address (operands[1], QImode,
6961                            plus_constant (Pmode, addr, 1));
6962     operands[0] = gen_lowpart (SImode, operands[0]);
6963     operands[1] = mem1;
6964     operands[2] = gen_reg_rtx (SImode);
6965     operands[3] = gen_reg_rtx (SImode);
6966     operands[6] = mem2;
6968     if (BYTES_BIG_ENDIAN)
6969       {
6970         operands[4] = operands[2];
6971         operands[5] = operands[3];
6972       }
6973     else
6974       {
6975         operands[4] = operands[3];
6976         operands[5] = operands[2];
6977       }
6978   }"
6981 (define_expand "movhi_bigend"
6982   [(set (match_dup 2)
6983         (rotate:SI (subreg:SI (match_operand:HI 1 "memory_operand" "") 0)
6984                    (const_int 16)))
6985    (set (match_dup 3)
6986         (ashiftrt:SI (match_dup 2) (const_int 16)))
6987    (set (match_operand:HI 0 "s_register_operand" "")
6988         (match_dup 4))]
6989   "TARGET_ARM"
6990   "
6991   operands[2] = gen_reg_rtx (SImode);
6992   operands[3] = gen_reg_rtx (SImode);
6993   operands[4] = gen_lowpart (HImode, operands[3]);
6994   "
6997 ;; Pattern to recognize insn generated default case above
6998 (define_insn "*movhi_insn_arch4"
6999   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m,r")
7000         (match_operand:HI 1 "general_operand"      "rI,K,n,r,mi"))]
7001   "TARGET_ARM
7002    && arm_arch4
7003    && (register_operand (operands[0], HImode)
7004        || register_operand (operands[1], HImode))"
7005   "@
7006    mov%?\\t%0, %1\\t%@ movhi
7007    mvn%?\\t%0, #%B1\\t%@ movhi
7008    movw%?\\t%0, %L1\\t%@ movhi
7009    str%(h%)\\t%1, %0\\t%@ movhi
7010    ldr%(h%)\\t%0, %1\\t%@ movhi"
7011   [(set_attr "predicable" "yes")
7012    (set_attr "pool_range" "*,*,*,*,256")
7013    (set_attr "neg_pool_range" "*,*,*,*,244")
7014    (set_attr "arch" "*,*,v6t2,*,*")
7015    (set_attr_alternative "type"
7016                          [(if_then_else (match_operand 1 "const_int_operand" "")
7017                                         (const_string "mov_imm" )
7018                                         (const_string "mov_reg"))
7019                           (const_string "mvn_imm")
7020                           (const_string "mov_imm")
7021                           (const_string "store1")
7022                           (const_string "load1")])]
7025 (define_insn "*movhi_bytes"
7026   [(set (match_operand:HI 0 "s_register_operand" "=r,r,r")
7027         (match_operand:HI 1 "arm_rhs_operand"  "I,r,K"))]
7028   "TARGET_ARM"
7029   "@
7030    mov%?\\t%0, %1\\t%@ movhi
7031    mov%?\\t%0, %1\\t%@ movhi
7032    mvn%?\\t%0, #%B1\\t%@ movhi"
7033   [(set_attr "predicable" "yes")
7034    (set_attr "type" "mov_imm,mov_reg,mvn_imm")]
7037 (define_expand "thumb_movhi_clobber"
7038   [(set (match_operand:HI     0 "memory_operand"   "")
7039         (match_operand:HI     1 "register_operand" ""))
7040    (clobber (match_operand:DI 2 "register_operand" ""))]
7041   "TARGET_THUMB1"
7042   "
7043   if (strict_memory_address_p (HImode, XEXP (operands[0], 0))
7044       && REGNO (operands[1]) <= LAST_LO_REGNUM)
7045     {
7046       emit_insn (gen_movhi (operands[0], operands[1]));
7047       DONE;
7048     }
7049   /* XXX Fixme, need to handle other cases here as well.  */
7050   gcc_unreachable ();
7051   "
7053         
7054 ;; We use a DImode scratch because we may occasionally need an additional
7055 ;; temporary if the address isn't offsettable -- push_reload doesn't seem
7056 ;; to take any notice of the "o" constraints on reload_memory_operand operand.
7057 (define_expand "reload_outhi"
7058   [(parallel [(match_operand:HI 0 "arm_reload_memory_operand" "=o")
7059               (match_operand:HI 1 "s_register_operand"        "r")
7060               (match_operand:DI 2 "s_register_operand"        "=&l")])]
7061   "TARGET_EITHER"
7062   "if (TARGET_ARM)
7063      arm_reload_out_hi (operands);
7064    else
7065      thumb_reload_out_hi (operands);
7066   DONE;
7067   "
7070 (define_expand "reload_inhi"
7071   [(parallel [(match_operand:HI 0 "s_register_operand" "=r")
7072               (match_operand:HI 1 "arm_reload_memory_operand" "o")
7073               (match_operand:DI 2 "s_register_operand" "=&r")])]
7074   "TARGET_EITHER"
7075   "
7076   if (TARGET_ARM)
7077     arm_reload_in_hi (operands);
7078   else
7079     thumb_reload_out_hi (operands);
7080   DONE;
7083 (define_expand "movqi"
7084   [(set (match_operand:QI 0 "general_operand" "")
7085         (match_operand:QI 1 "general_operand" ""))]
7086   "TARGET_EITHER"
7087   "
7088   /* Everything except mem = const or mem = mem can be done easily */
7090   if (can_create_pseudo_p ())
7091     {
7092       if (CONST_INT_P (operands[1]))
7093         {
7094           rtx reg = gen_reg_rtx (SImode);
7096           /* For thumb we want an unsigned immediate, then we are more likely 
7097              to be able to use a movs insn.  */
7098           if (TARGET_THUMB)
7099             operands[1] = GEN_INT (INTVAL (operands[1]) & 255);
7101           emit_insn (gen_movsi (reg, operands[1]));
7102           operands[1] = gen_lowpart (QImode, reg);
7103         }
7105       if (TARGET_THUMB)
7106         {
7107           /* ??? We shouldn't really get invalid addresses here, but this can
7108              happen if we are passed a SP (never OK for HImode/QImode) or
7109              virtual register (also rejected as illegitimate for HImode/QImode)
7110              relative address.  */
7111           /* ??? This should perhaps be fixed elsewhere, for instance, in
7112              fixup_stack_1, by checking for other kinds of invalid addresses,
7113              e.g. a bare reference to a virtual register.  This may confuse the
7114              alpha though, which must handle this case differently.  */
7115           if (MEM_P (operands[0])
7116               && !memory_address_p (GET_MODE (operands[0]),
7117                                      XEXP (operands[0], 0)))
7118             operands[0]
7119               = replace_equiv_address (operands[0],
7120                                        copy_to_reg (XEXP (operands[0], 0)));
7121           if (MEM_P (operands[1])
7122               && !memory_address_p (GET_MODE (operands[1]),
7123                                     XEXP (operands[1], 0)))
7124              operands[1]
7125                = replace_equiv_address (operands[1],
7126                                         copy_to_reg (XEXP (operands[1], 0)));
7127         }
7129       if (MEM_P (operands[1]) && optimize > 0)
7130         {
7131           rtx reg = gen_reg_rtx (SImode);
7133           emit_insn (gen_zero_extendqisi2 (reg, operands[1]));
7134           operands[1] = gen_lowpart (QImode, reg);
7135         }
7137       if (MEM_P (operands[0]))
7138         operands[1] = force_reg (QImode, operands[1]);
7139     }
7140   else if (TARGET_THUMB
7141            && CONST_INT_P (operands[1])
7142            && !satisfies_constraint_I (operands[1]))
7143     {
7144       /* Handle loading a large integer during reload.  */
7146       /* Writing a constant to memory needs a scratch, which should
7147          be handled with SECONDARY_RELOADs.  */
7148       gcc_assert (REG_P (operands[0]));
7150       operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
7151       emit_insn (gen_movsi (operands[0], operands[1]));
7152       DONE;
7153     }
7154   "
7157 (define_insn "*arm_movqi_insn"
7158   [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,r,l,r,l,Uu,r,m")
7159         (match_operand:QI 1 "general_operand" "r,r,I,Py,K,Uu,l,m,r"))]
7160   "TARGET_32BIT
7161    && (   register_operand (operands[0], QImode)
7162        || register_operand (operands[1], QImode))"
7163   "@
7164    mov%?\\t%0, %1
7165    mov%?\\t%0, %1
7166    mov%?\\t%0, %1
7167    mov%?\\t%0, %1
7168    mvn%?\\t%0, #%B1
7169    ldr%(b%)\\t%0, %1
7170    str%(b%)\\t%1, %0
7171    ldr%(b%)\\t%0, %1
7172    str%(b%)\\t%1, %0"
7173   [(set_attr "type" "mov_reg,mov_reg,mov_imm,mov_imm,mvn_imm,load1,store1,load1,store1")
7174    (set_attr "predicable" "yes")
7175    (set_attr "predicable_short_it" "yes,yes,yes,no,no,no,no,no,no")
7176    (set_attr "arch" "t2,any,any,t2,any,t2,t2,any,any")
7177    (set_attr "length" "2,4,4,2,4,2,2,4,4")]
7180 (define_insn "*thumb1_movqi_insn"
7181   [(set (match_operand:QI 0 "nonimmediate_operand" "=l,l,m,*r,*h,l")
7182         (match_operand:QI 1 "general_operand"      "l, m,l,*h,*r,I"))]
7183   "TARGET_THUMB1
7184    && (   register_operand (operands[0], QImode)
7185        || register_operand (operands[1], QImode))"
7186   "@
7187    add\\t%0, %1, #0
7188    ldrb\\t%0, %1
7189    strb\\t%1, %0
7190    mov\\t%0, %1
7191    mov\\t%0, %1
7192    mov\\t%0, %1"
7193   [(set_attr "length" "2")
7194    (set_attr "type" "alu_imm,load1,store1,mov_reg,mov_imm,mov_imm")
7195    (set_attr "pool_range" "*,32,*,*,*,*")
7196    (set_attr "conds" "clob,nocond,nocond,nocond,nocond,clob")])
7198 ;; HFmode moves
7199 (define_expand "movhf"
7200   [(set (match_operand:HF 0 "general_operand" "")
7201         (match_operand:HF 1 "general_operand" ""))]
7202   "TARGET_EITHER"
7203   "
7204   if (TARGET_32BIT)
7205     {
7206       if (MEM_P (operands[0]))
7207         operands[1] = force_reg (HFmode, operands[1]);
7208     }
7209   else /* TARGET_THUMB1 */
7210     {
7211       if (can_create_pseudo_p ())
7212         {
7213            if (!REG_P (operands[0]))
7214              operands[1] = force_reg (HFmode, operands[1]);
7215         }
7216     }
7217   "
7220 (define_insn "*arm32_movhf"
7221   [(set (match_operand:HF 0 "nonimmediate_operand" "=r,m,r,r")
7222         (match_operand:HF 1 "general_operand"      " m,r,r,F"))]
7223   "TARGET_32BIT && !(TARGET_HARD_FLOAT && TARGET_FP16) && !arm_restrict_it
7224    && (   s_register_operand (operands[0], HFmode)
7225        || s_register_operand (operands[1], HFmode))"
7226   "*
7227   switch (which_alternative)
7228     {
7229     case 0:     /* ARM register from memory */
7230       return \"ldr%(h%)\\t%0, %1\\t%@ __fp16\";
7231     case 1:     /* memory from ARM register */
7232       return \"str%(h%)\\t%1, %0\\t%@ __fp16\";
7233     case 2:     /* ARM register from ARM register */
7234       return \"mov%?\\t%0, %1\\t%@ __fp16\";
7235     case 3:     /* ARM register from constant */
7236       {
7237         REAL_VALUE_TYPE r;
7238         long bits;
7239         rtx ops[4];
7241         REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
7242         bits = real_to_target (NULL, &r, HFmode);
7243         ops[0] = operands[0];
7244         ops[1] = GEN_INT (bits);
7245         ops[2] = GEN_INT (bits & 0xff00);
7246         ops[3] = GEN_INT (bits & 0x00ff);
7248         if (arm_arch_thumb2)
7249           output_asm_insn (\"movw%?\\t%0, %1\", ops);
7250         else
7251           output_asm_insn (\"mov%?\\t%0, %2\;orr%?\\t%0, %0, %3\", ops);
7252         return \"\";
7253        }
7254     default:
7255       gcc_unreachable ();
7256     }
7257   "
7258   [(set_attr "conds" "unconditional")
7259    (set_attr "type" "load1,store1,mov_reg,multiple")
7260    (set_attr "length" "4,4,4,8")
7261    (set_attr "predicable" "yes")]
7264 (define_insn "*thumb1_movhf"
7265   [(set (match_operand:HF     0 "nonimmediate_operand" "=l,l,m,*r,*h")
7266         (match_operand:HF     1 "general_operand"      "l,mF,l,*h,*r"))]
7267   "TARGET_THUMB1
7268    && (   s_register_operand (operands[0], HFmode) 
7269        || s_register_operand (operands[1], HFmode))"
7270   "*
7271   switch (which_alternative)
7272     {
7273     case 1:
7274       {
7275         rtx addr;
7276         gcc_assert (MEM_P (operands[1]));
7277         addr = XEXP (operands[1], 0);
7278         if (GET_CODE (addr) == LABEL_REF
7279             || (GET_CODE (addr) == CONST
7280                 && GET_CODE (XEXP (addr, 0)) == PLUS
7281                 && GET_CODE (XEXP (XEXP (addr, 0), 0)) == LABEL_REF
7282                 && CONST_INT_P (XEXP (XEXP (addr, 0), 1))))
7283           {
7284             /* Constant pool entry.  */
7285             return \"ldr\\t%0, %1\";
7286           }
7287         return \"ldrh\\t%0, %1\";
7288       }
7289     case 2: return \"strh\\t%1, %0\";
7290     default: return \"mov\\t%0, %1\";
7291     }
7292   "
7293   [(set_attr "length" "2")
7294    (set_attr "type" "mov_reg,load1,store1,mov_reg,mov_reg")
7295    (set_attr "pool_range" "*,1018,*,*,*")
7296    (set_attr "conds" "clob,nocond,nocond,nocond,nocond")])
7298 (define_expand "movsf"
7299   [(set (match_operand:SF 0 "general_operand" "")
7300         (match_operand:SF 1 "general_operand" ""))]
7301   "TARGET_EITHER"
7302   "
7303   if (TARGET_32BIT)
7304     {
7305       if (MEM_P (operands[0]))
7306         operands[1] = force_reg (SFmode, operands[1]);
7307     }
7308   else /* TARGET_THUMB1 */
7309     {
7310       if (can_create_pseudo_p ())
7311         {
7312            if (!REG_P (operands[0]))
7313              operands[1] = force_reg (SFmode, operands[1]);
7314         }
7315     }
7316   "
7319 ;; Transform a floating-point move of a constant into a core register into
7320 ;; an SImode operation.
7321 (define_split
7322   [(set (match_operand:SF 0 "arm_general_register_operand" "")
7323         (match_operand:SF 1 "immediate_operand" ""))]
7324   "TARGET_EITHER
7325    && reload_completed
7326    && CONST_DOUBLE_P (operands[1])"
7327   [(set (match_dup 2) (match_dup 3))]
7328   "
7329   operands[2] = gen_lowpart (SImode, operands[0]);
7330   operands[3] = gen_lowpart (SImode, operands[1]);
7331   if (operands[2] == 0 || operands[3] == 0)
7332     FAIL;
7333   "
7336 (define_insn "*arm_movsf_soft_insn"
7337   [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,m")
7338         (match_operand:SF 1 "general_operand"  "r,mE,r"))]
7339   "TARGET_32BIT
7340    && TARGET_SOFT_FLOAT
7341    && (!MEM_P (operands[0])
7342        || register_operand (operands[1], SFmode))"
7343   "@
7344    mov%?\\t%0, %1
7345    ldr%?\\t%0, %1\\t%@ float
7346    str%?\\t%1, %0\\t%@ float"
7347   [(set_attr "predicable" "yes")
7348    (set_attr "predicable_short_it" "no")
7349    (set_attr "type" "mov_reg,load1,store1")
7350    (set_attr "arm_pool_range" "*,4096,*")
7351    (set_attr "thumb2_pool_range" "*,4094,*")
7352    (set_attr "arm_neg_pool_range" "*,4084,*")
7353    (set_attr "thumb2_neg_pool_range" "*,0,*")]
7356 ;;; ??? This should have alternatives for constants.
7357 (define_insn "*thumb1_movsf_insn"
7358   [(set (match_operand:SF     0 "nonimmediate_operand" "=l,l,>,l, m,*r,*h")
7359         (match_operand:SF     1 "general_operand"      "l, >,l,mF,l,*h,*r"))]
7360   "TARGET_THUMB1
7361    && (   register_operand (operands[0], SFmode) 
7362        || register_operand (operands[1], SFmode))"
7363   "@
7364    add\\t%0, %1, #0
7365    ldmia\\t%1, {%0}
7366    stmia\\t%0, {%1}
7367    ldr\\t%0, %1
7368    str\\t%1, %0
7369    mov\\t%0, %1
7370    mov\\t%0, %1"
7371   [(set_attr "length" "2")
7372    (set_attr "type" "alus_imm,load1,store1,load1,store1,mov_reg,mov_reg")
7373    (set_attr "pool_range" "*,*,*,1018,*,*,*")
7374    (set_attr "conds" "clob,nocond,nocond,nocond,nocond,nocond,nocond")]
7377 (define_expand "movdf"
7378   [(set (match_operand:DF 0 "general_operand" "")
7379         (match_operand:DF 1 "general_operand" ""))]
7380   "TARGET_EITHER"
7381   "
7382   if (TARGET_32BIT)
7383     {
7384       if (MEM_P (operands[0]))
7385         operands[1] = force_reg (DFmode, operands[1]);
7386     }
7387   else /* TARGET_THUMB */
7388     {
7389       if (can_create_pseudo_p ())
7390         {
7391           if (!REG_P (operands[0]))
7392             operands[1] = force_reg (DFmode, operands[1]);
7393         }
7394     }
7395   "
7398 ;; Reloading a df mode value stored in integer regs to memory can require a
7399 ;; scratch reg.
7400 (define_expand "reload_outdf"
7401   [(match_operand:DF 0 "arm_reload_memory_operand" "=o")
7402    (match_operand:DF 1 "s_register_operand" "r")
7403    (match_operand:SI 2 "s_register_operand" "=&r")]
7404   "TARGET_THUMB2"
7405   "
7406   {
7407     enum rtx_code code = GET_CODE (XEXP (operands[0], 0));
7409     if (code == REG)
7410       operands[2] = XEXP (operands[0], 0);
7411     else if (code == POST_INC || code == PRE_DEC)
7412       {
7413         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7414         operands[1] = gen_rtx_SUBREG (DImode, operands[1], 0);
7415         emit_insn (gen_movdi (operands[0], operands[1]));
7416         DONE;
7417       }
7418     else if (code == PRE_INC)
7419       {
7420         rtx reg = XEXP (XEXP (operands[0], 0), 0);
7422         emit_insn (gen_addsi3 (reg, reg, GEN_INT (8)));
7423         operands[2] = reg;
7424       }
7425     else if (code == POST_DEC)
7426       operands[2] = XEXP (XEXP (operands[0], 0), 0);
7427     else
7428       emit_insn (gen_addsi3 (operands[2], XEXP (XEXP (operands[0], 0), 0),
7429                              XEXP (XEXP (operands[0], 0), 1)));
7431     emit_insn (gen_rtx_SET (VOIDmode,
7432                             replace_equiv_address (operands[0], operands[2]),
7433                             operands[1]));
7435     if (code == POST_DEC)
7436       emit_insn (gen_addsi3 (operands[2], operands[2], GEN_INT (-8)));
7438     DONE;
7439   }"
7442 (define_insn "*movdf_soft_insn"
7443   [(set (match_operand:DF 0 "nonimmediate_soft_df_operand" "=r,r,r,q,m")
7444         (match_operand:DF 1 "soft_df_operand" "rDa,Db,Dc,mF,q"))]
7445   "TARGET_32BIT && TARGET_SOFT_FLOAT
7446    && (   register_operand (operands[0], DFmode)
7447        || register_operand (operands[1], DFmode))"
7448   "*
7449   switch (which_alternative)
7450     {
7451     case 0:
7452     case 1:
7453     case 2:
7454       return \"#\";
7455     default:
7456       return output_move_double (operands, true, NULL);
7457     }
7458   "
7459   [(set_attr "length" "8,12,16,8,8")
7460    (set_attr "type" "multiple,multiple,multiple,load2,store2")
7461    (set_attr "arm_pool_range" "*,*,*,1020,*")
7462    (set_attr "thumb2_pool_range" "*,*,*,1018,*")
7463    (set_attr "arm_neg_pool_range" "*,*,*,1004,*")
7464    (set_attr "thumb2_neg_pool_range" "*,*,*,0,*")]
7467 ;;; ??? This should have alternatives for constants.
7468 ;;; ??? This was originally identical to the movdi_insn pattern.
7469 ;;; ??? The 'F' constraint looks funny, but it should always be replaced by
7470 ;;; thumb_reorg with a memory reference.
7471 (define_insn "*thumb_movdf_insn"
7472   [(set (match_operand:DF 0 "nonimmediate_operand" "=l,l,>,l, m,*r")
7473         (match_operand:DF 1 "general_operand"      "l, >,l,mF,l,*r"))]
7474   "TARGET_THUMB1
7475    && (   register_operand (operands[0], DFmode)
7476        || register_operand (operands[1], DFmode))"
7477   "*
7478   switch (which_alternative)
7479     {
7480     default:
7481     case 0:
7482       if (REGNO (operands[1]) == REGNO (operands[0]) + 1)
7483         return \"add\\t%0, %1, #0\;add\\t%H0, %H1, #0\";
7484       return \"add\\t%H0, %H1, #0\;add\\t%0, %1, #0\";
7485     case 1:
7486       return \"ldmia\\t%1, {%0, %H0}\";
7487     case 2:
7488       return \"stmia\\t%0, {%1, %H1}\";
7489     case 3:
7490       return thumb_load_double_from_address (operands);
7491     case 4:
7492       operands[2] = gen_rtx_MEM (SImode,
7493                                  plus_constant (Pmode,
7494                                                 XEXP (operands[0], 0), 4));
7495       output_asm_insn (\"str\\t%1, %0\;str\\t%H1, %2\", operands);
7496       return \"\";
7497     case 5:
7498       if (REGNO (operands[1]) == REGNO (operands[0]) + 1)
7499         return \"mov\\t%0, %1\;mov\\t%H0, %H1\";
7500       return \"mov\\t%H0, %H1\;mov\\t%0, %1\";
7501     }
7502   "
7503   [(set_attr "length" "4,2,2,6,4,4")
7504    (set_attr "type" "multiple,load2,store2,load2,store2,multiple")
7505    (set_attr "pool_range" "*,*,*,1018,*,*")]
7509 ;; load- and store-multiple insns
7510 ;; The arm can load/store any set of registers, provided that they are in
7511 ;; ascending order, but these expanders assume a contiguous set.
7513 (define_expand "load_multiple"
7514   [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
7515                           (match_operand:SI 1 "" ""))
7516                      (use (match_operand:SI 2 "" ""))])]
7517   "TARGET_32BIT"
7519   HOST_WIDE_INT offset = 0;
7521   /* Support only fixed point registers.  */
7522   if (!CONST_INT_P (operands[2])
7523       || INTVAL (operands[2]) > 14
7524       || INTVAL (operands[2]) < 2
7525       || !MEM_P (operands[1])
7526       || !REG_P (operands[0])
7527       || REGNO (operands[0]) > (LAST_ARM_REGNUM - 1)
7528       || REGNO (operands[0]) + INTVAL (operands[2]) > LAST_ARM_REGNUM)
7529     FAIL;
7531   operands[3]
7532     = arm_gen_load_multiple (arm_regs_in_sequence + REGNO (operands[0]),
7533                              INTVAL (operands[2]),
7534                              force_reg (SImode, XEXP (operands[1], 0)),
7535                              FALSE, operands[1], &offset);
7538 (define_expand "store_multiple"
7539   [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
7540                           (match_operand:SI 1 "" ""))
7541                      (use (match_operand:SI 2 "" ""))])]
7542   "TARGET_32BIT"
7544   HOST_WIDE_INT offset = 0;
7546   /* Support only fixed point registers.  */
7547   if (!CONST_INT_P (operands[2])
7548       || INTVAL (operands[2]) > 14
7549       || INTVAL (operands[2]) < 2
7550       || !REG_P (operands[1])
7551       || !MEM_P (operands[0])
7552       || REGNO (operands[1]) > (LAST_ARM_REGNUM - 1)
7553       || REGNO (operands[1]) + INTVAL (operands[2]) > LAST_ARM_REGNUM)
7554     FAIL;
7556   operands[3]
7557     = arm_gen_store_multiple (arm_regs_in_sequence + REGNO (operands[1]),
7558                               INTVAL (operands[2]),
7559                               force_reg (SImode, XEXP (operands[0], 0)),
7560                               FALSE, operands[0], &offset);
7564 ;; Move a block of memory if it is word aligned and MORE than 2 words long.
7565 ;; We could let this apply for blocks of less than this, but it clobbers so
7566 ;; many registers that there is then probably a better way.
7568 (define_expand "movmemqi"
7569   [(match_operand:BLK 0 "general_operand" "")
7570    (match_operand:BLK 1 "general_operand" "")
7571    (match_operand:SI 2 "const_int_operand" "")
7572    (match_operand:SI 3 "const_int_operand" "")]
7573   ""
7574   "
7575   if (TARGET_32BIT)
7576     {
7577       if (TARGET_LDRD && current_tune->prefer_ldrd_strd
7578           && !optimize_function_for_size_p (cfun))
7579         {
7580           if (gen_movmem_ldrd_strd (operands))
7581             DONE;
7582           FAIL;
7583         }
7585       if (arm_gen_movmemqi (operands))
7586         DONE;
7587       FAIL;
7588     }
7589   else /* TARGET_THUMB1 */
7590     {
7591       if (   INTVAL (operands[3]) != 4
7592           || INTVAL (operands[2]) > 48)
7593         FAIL;
7595       thumb_expand_movmemqi (operands);
7596       DONE;
7597     }
7598   "
7601 ;; Thumb block-move insns
7603 (define_insn "movmem12b"
7604   [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
7605         (mem:SI (match_operand:SI 3 "register_operand" "1")))
7606    (set (mem:SI (plus:SI (match_dup 2) (const_int 4)))
7607         (mem:SI (plus:SI (match_dup 3) (const_int 4))))
7608    (set (mem:SI (plus:SI (match_dup 2) (const_int 8)))
7609         (mem:SI (plus:SI (match_dup 3) (const_int 8))))
7610    (set (match_operand:SI 0 "register_operand" "=l")
7611         (plus:SI (match_dup 2) (const_int 12)))
7612    (set (match_operand:SI 1 "register_operand" "=l")
7613         (plus:SI (match_dup 3) (const_int 12)))
7614    (clobber (match_scratch:SI 4 "=&l"))
7615    (clobber (match_scratch:SI 5 "=&l"))
7616    (clobber (match_scratch:SI 6 "=&l"))]
7617   "TARGET_THUMB1"
7618   "* return thumb_output_move_mem_multiple (3, operands);"
7619   [(set_attr "length" "4")
7620    ; This isn't entirely accurate...  It loads as well, but in terms of
7621    ; scheduling the following insn it is better to consider it as a store
7622    (set_attr "type" "store3")]
7625 (define_insn "movmem8b"
7626   [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
7627         (mem:SI (match_operand:SI 3 "register_operand" "1")))
7628    (set (mem:SI (plus:SI (match_dup 2) (const_int 4)))
7629         (mem:SI (plus:SI (match_dup 3) (const_int 4))))
7630    (set (match_operand:SI 0 "register_operand" "=l")
7631         (plus:SI (match_dup 2) (const_int 8)))
7632    (set (match_operand:SI 1 "register_operand" "=l")
7633         (plus:SI (match_dup 3) (const_int 8)))
7634    (clobber (match_scratch:SI 4 "=&l"))
7635    (clobber (match_scratch:SI 5 "=&l"))]
7636   "TARGET_THUMB1"
7637   "* return thumb_output_move_mem_multiple (2, operands);"
7638   [(set_attr "length" "4")
7639    ; This isn't entirely accurate...  It loads as well, but in terms of
7640    ; scheduling the following insn it is better to consider it as a store
7641    (set_attr "type" "store2")]
7646 ;; Compare & branch insns
7647 ;; The range calculations are based as follows:
7648 ;; For forward branches, the address calculation returns the address of
7649 ;; the next instruction.  This is 2 beyond the branch instruction.
7650 ;; For backward branches, the address calculation returns the address of
7651 ;; the first instruction in this pattern (cmp).  This is 2 before the branch
7652 ;; instruction for the shortest sequence, and 4 before the branch instruction
7653 ;; if we have to jump around an unconditional branch.
7654 ;; To the basic branch range the PC offset must be added (this is +4).
7655 ;; So for forward branches we have 
7656 ;;   (pos_range - pos_base_offs + pc_offs) = (pos_range - 2 + 4).
7657 ;; And for backward branches we have 
7658 ;;   (neg_range - neg_base_offs + pc_offs) = (neg_range - (-2 or -4) + 4).
7660 ;; For a 'b'       pos_range = 2046, neg_range = -2048 giving (-2040->2048).
7661 ;; For a 'b<cond>' pos_range = 254,  neg_range = -256  giving (-250 ->256).
7663 (define_expand "cbranchsi4"
7664   [(set (pc) (if_then_else
7665               (match_operator 0 "expandable_comparison_operator"
7666                [(match_operand:SI 1 "s_register_operand" "")
7667                 (match_operand:SI 2 "nonmemory_operand" "")])
7668               (label_ref (match_operand 3 "" ""))
7669               (pc)))]
7670   "TARGET_EITHER"
7671   "
7672   if (!TARGET_THUMB1)
7673     {
7674       if (!arm_validize_comparison (&operands[0], &operands[1], &operands[2]))
7675         FAIL;
7676       emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
7677                                       operands[3]));
7678       DONE;
7679     }
7680   if (thumb1_cmpneg_operand (operands[2], SImode))
7681     {
7682       emit_jump_insn (gen_cbranchsi4_scratch (NULL, operands[1], operands[2],
7683                                               operands[3], operands[0]));
7684       DONE;
7685     }
7686   if (!thumb1_cmp_operand (operands[2], SImode))
7687     operands[2] = force_reg (SImode, operands[2]);
7688   ")
7690 ;; A pattern to recognize a special situation and optimize for it.
7691 ;; On the thumb, zero-extension from memory is preferrable to sign-extension
7692 ;; due to the available addressing modes.  Hence, convert a signed comparison
7693 ;; with zero into an unsigned comparison with 127 if possible.
7694 (define_expand "cbranchqi4"
7695   [(set (pc) (if_then_else
7696               (match_operator 0 "lt_ge_comparison_operator"
7697                [(match_operand:QI 1 "memory_operand" "")
7698                 (match_operand:QI 2 "const0_operand" "")])
7699               (label_ref (match_operand 3 "" ""))
7700               (pc)))]
7701   "TARGET_THUMB1"
7703   rtx xops[4];
7704   xops[1] = gen_reg_rtx (SImode);
7705   emit_insn (gen_zero_extendqisi2 (xops[1], operands[1]));
7706   xops[2] = GEN_INT (127);
7707   xops[0] = gen_rtx_fmt_ee (GET_CODE (operands[0]) == GE ? LEU : GTU,
7708                             VOIDmode, xops[1], xops[2]);
7709   xops[3] = operands[3];
7710   emit_insn (gen_cbranchsi4 (xops[0], xops[1], xops[2], xops[3]));
7711   DONE;
7714 (define_expand "cbranchsf4"
7715   [(set (pc) (if_then_else
7716               (match_operator 0 "expandable_comparison_operator"
7717                [(match_operand:SF 1 "s_register_operand" "")
7718                 (match_operand:SF 2 "arm_float_compare_operand" "")])
7719               (label_ref (match_operand 3 "" ""))
7720               (pc)))]
7721   "TARGET_32BIT && TARGET_HARD_FLOAT"
7722   "emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
7723                                    operands[3])); DONE;"
7726 (define_expand "cbranchdf4"
7727   [(set (pc) (if_then_else
7728               (match_operator 0 "expandable_comparison_operator"
7729                [(match_operand:DF 1 "s_register_operand" "")
7730                 (match_operand:DF 2 "arm_float_compare_operand" "")])
7731               (label_ref (match_operand 3 "" ""))
7732               (pc)))]
7733   "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
7734   "emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
7735                                    operands[3])); DONE;"
7738 (define_expand "cbranchdi4"
7739   [(set (pc) (if_then_else
7740               (match_operator 0 "expandable_comparison_operator"
7741                [(match_operand:DI 1 "s_register_operand" "")
7742                 (match_operand:DI 2 "cmpdi_operand" "")])
7743               (label_ref (match_operand 3 "" ""))
7744               (pc)))]
7745   "TARGET_32BIT"
7746   "{
7747      if (!arm_validize_comparison (&operands[0], &operands[1], &operands[2]))
7748        FAIL;
7749      emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
7750                                        operands[3]));
7751      DONE;
7752    }"
7755 (define_insn "cbranchsi4_insn"
7756   [(set (pc) (if_then_else
7757               (match_operator 0 "arm_comparison_operator"
7758                [(match_operand:SI 1 "s_register_operand" "l,l*h")
7759                 (match_operand:SI 2 "thumb1_cmp_operand" "lI*h,*r")])
7760               (label_ref (match_operand 3 "" ""))
7761               (pc)))]
7762   "TARGET_THUMB1"
7764   rtx t = cfun->machine->thumb1_cc_insn;
7765   if (t != NULL_RTX)
7766     {
7767       if (!rtx_equal_p (cfun->machine->thumb1_cc_op0, operands[1])
7768           || !rtx_equal_p (cfun->machine->thumb1_cc_op1, operands[2]))
7769         t = NULL_RTX;
7770       if (cfun->machine->thumb1_cc_mode == CC_NOOVmode)
7771         {
7772           if (!noov_comparison_operator (operands[0], VOIDmode))
7773             t = NULL_RTX;
7774         }
7775       else if (cfun->machine->thumb1_cc_mode != CCmode)
7776         t = NULL_RTX;
7777     }
7778   if (t == NULL_RTX)
7779     {
7780       output_asm_insn ("cmp\t%1, %2", operands);
7781       cfun->machine->thumb1_cc_insn = insn;
7782       cfun->machine->thumb1_cc_op0 = operands[1];
7783       cfun->machine->thumb1_cc_op1 = operands[2];
7784       cfun->machine->thumb1_cc_mode = CCmode;
7785     }
7786   else
7787     /* Ensure we emit the right type of condition code on the jump.  */
7788     XEXP (operands[0], 0) = gen_rtx_REG (cfun->machine->thumb1_cc_mode,
7789                                          CC_REGNUM);
7791   switch (get_attr_length (insn))
7792     {
7793     case 4:  return \"b%d0\\t%l3\";
7794     case 6:  return \"b%D0\\t.LCB%=\;b\\t%l3\\t%@long jump\\n.LCB%=:\";
7795     default: return \"b%D0\\t.LCB%=\;bl\\t%l3\\t%@far jump\\n.LCB%=:\";
7796     }
7798   [(set (attr "far_jump")
7799         (if_then_else
7800             (eq_attr "length" "8")
7801             (const_string "yes")
7802             (const_string "no")))
7803    (set (attr "length") 
7804         (if_then_else
7805             (and (ge (minus (match_dup 3) (pc)) (const_int -250))
7806                  (le (minus (match_dup 3) (pc)) (const_int 256)))
7807             (const_int 4)
7808             (if_then_else
7809                 (and (ge (minus (match_dup 3) (pc)) (const_int -2040))
7810                      (le (minus (match_dup 3) (pc)) (const_int 2048)))
7811                 (const_int 6)
7812                 (const_int 8))))
7813    (set_attr "type" "multiple")]
7816 (define_insn "cbranchsi4_scratch"
7817   [(set (pc) (if_then_else
7818               (match_operator 4 "arm_comparison_operator"
7819                [(match_operand:SI 1 "s_register_operand" "l,0")
7820                 (match_operand:SI 2 "thumb1_cmpneg_operand" "L,J")])
7821               (label_ref (match_operand 3 "" ""))
7822               (pc)))
7823    (clobber (match_scratch:SI 0 "=l,l"))]
7824   "TARGET_THUMB1"
7825   "*
7826   output_asm_insn (\"add\\t%0, %1, #%n2\", operands);
7828   switch (get_attr_length (insn))
7829     {
7830     case 4:  return \"b%d4\\t%l3\";
7831     case 6:  return \"b%D4\\t.LCB%=\;b\\t%l3\\t%@long jump\\n.LCB%=:\";
7832     default: return \"b%D4\\t.LCB%=\;bl\\t%l3\\t%@far jump\\n.LCB%=:\";
7833     }
7834   "
7835   [(set (attr "far_jump")
7836         (if_then_else
7837             (eq_attr "length" "8")
7838             (const_string "yes")
7839             (const_string "no")))
7840    (set (attr "length") 
7841         (if_then_else
7842             (and (ge (minus (match_dup 3) (pc)) (const_int -250))
7843                  (le (minus (match_dup 3) (pc)) (const_int 256)))
7844             (const_int 4)
7845             (if_then_else
7846                 (and (ge (minus (match_dup 3) (pc)) (const_int -2040))
7847                      (le (minus (match_dup 3) (pc)) (const_int 2048)))
7848                 (const_int 6)
7849                 (const_int 8))))
7850    (set_attr "type" "multiple")]
7853 (define_insn "*negated_cbranchsi4"
7854   [(set (pc)
7855         (if_then_else
7856          (match_operator 0 "equality_operator"
7857           [(match_operand:SI 1 "s_register_operand" "l")
7858            (neg:SI (match_operand:SI 2 "s_register_operand" "l"))])
7859          (label_ref (match_operand 3 "" ""))
7860          (pc)))]
7861   "TARGET_THUMB1"
7862   "*
7863   output_asm_insn (\"cmn\\t%1, %2\", operands);
7864   switch (get_attr_length (insn))
7865     {
7866     case 4:  return \"b%d0\\t%l3\";
7867     case 6:  return \"b%D0\\t.LCB%=\;b\\t%l3\\t%@long jump\\n.LCB%=:\";
7868     default: return \"b%D0\\t.LCB%=\;bl\\t%l3\\t%@far jump\\n.LCB%=:\";
7869     }
7870   "
7871   [(set (attr "far_jump")
7872         (if_then_else
7873             (eq_attr "length" "8")
7874             (const_string "yes")
7875             (const_string "no")))
7876    (set (attr "length") 
7877         (if_then_else
7878             (and (ge (minus (match_dup 3) (pc)) (const_int -250))
7879                  (le (minus (match_dup 3) (pc)) (const_int 256)))
7880             (const_int 4)
7881             (if_then_else
7882                 (and (ge (minus (match_dup 3) (pc)) (const_int -2040))
7883                      (le (minus (match_dup 3) (pc)) (const_int 2048)))
7884                 (const_int 6)
7885                 (const_int 8))))
7886    (set_attr "type" "multiple")]
7889 (define_insn "*tbit_cbranch"
7890   [(set (pc)
7891         (if_then_else
7892          (match_operator 0 "equality_operator"
7893           [(zero_extract:SI (match_operand:SI 1 "s_register_operand" "l")
7894                             (const_int 1)
7895                             (match_operand:SI 2 "const_int_operand" "i"))
7896            (const_int 0)])
7897          (label_ref (match_operand 3 "" ""))
7898          (pc)))
7899    (clobber (match_scratch:SI 4 "=l"))]
7900   "TARGET_THUMB1"
7901   "*
7902   {
7903   rtx op[3];
7904   op[0] = operands[4];
7905   op[1] = operands[1];
7906   op[2] = GEN_INT (32 - 1 - INTVAL (operands[2]));
7908   output_asm_insn (\"lsl\\t%0, %1, %2\", op);
7909   switch (get_attr_length (insn))
7910     {
7911     case 4:  return \"b%d0\\t%l3\";
7912     case 6:  return \"b%D0\\t.LCB%=\;b\\t%l3\\t%@long jump\\n.LCB%=:\";
7913     default: return \"b%D0\\t.LCB%=\;bl\\t%l3\\t%@far jump\\n.LCB%=:\";
7914     }
7915   }"
7916   [(set (attr "far_jump")
7917         (if_then_else
7918             (eq_attr "length" "8")
7919             (const_string "yes")
7920             (const_string "no")))
7921    (set (attr "length") 
7922         (if_then_else
7923             (and (ge (minus (match_dup 3) (pc)) (const_int -250))
7924                  (le (minus (match_dup 3) (pc)) (const_int 256)))
7925             (const_int 4)
7926             (if_then_else
7927                 (and (ge (minus (match_dup 3) (pc)) (const_int -2040))
7928                      (le (minus (match_dup 3) (pc)) (const_int 2048)))
7929                 (const_int 6)
7930                 (const_int 8))))
7931    (set_attr "type" "multiple")]
7933   
7934 (define_insn "*tlobits_cbranch"
7935   [(set (pc)
7936         (if_then_else
7937          (match_operator 0 "equality_operator"
7938           [(zero_extract:SI (match_operand:SI 1 "s_register_operand" "l")
7939                             (match_operand:SI 2 "const_int_operand" "i")
7940                             (const_int 0))
7941            (const_int 0)])
7942          (label_ref (match_operand 3 "" ""))
7943          (pc)))
7944    (clobber (match_scratch:SI 4 "=l"))]
7945   "TARGET_THUMB1"
7946   "*
7947   {
7948   rtx op[3];
7949   op[0] = operands[4];
7950   op[1] = operands[1];
7951   op[2] = GEN_INT (32 - INTVAL (operands[2]));
7953   output_asm_insn (\"lsl\\t%0, %1, %2\", op);
7954   switch (get_attr_length (insn))
7955     {
7956     case 4:  return \"b%d0\\t%l3\";
7957     case 6:  return \"b%D0\\t.LCB%=\;b\\t%l3\\t%@long jump\\n.LCB%=:\";
7958     default: return \"b%D0\\t.LCB%=\;bl\\t%l3\\t%@far jump\\n.LCB%=:\";
7959     }
7960   }"
7961   [(set (attr "far_jump")
7962         (if_then_else
7963             (eq_attr "length" "8")
7964             (const_string "yes")
7965             (const_string "no")))
7966    (set (attr "length") 
7967         (if_then_else
7968             (and (ge (minus (match_dup 3) (pc)) (const_int -250))
7969                  (le (minus (match_dup 3) (pc)) (const_int 256)))
7970             (const_int 4)
7971             (if_then_else
7972                 (and (ge (minus (match_dup 3) (pc)) (const_int -2040))
7973                      (le (minus (match_dup 3) (pc)) (const_int 2048)))
7974                 (const_int 6)
7975                 (const_int 8))))
7976    (set_attr "type" "multiple")]
7979 (define_insn "*tstsi3_cbranch"
7980   [(set (pc)
7981         (if_then_else
7982          (match_operator 3 "equality_operator"
7983           [(and:SI (match_operand:SI 0 "s_register_operand" "%l")
7984                    (match_operand:SI 1 "s_register_operand" "l"))
7985            (const_int 0)])
7986          (label_ref (match_operand 2 "" ""))
7987          (pc)))]
7988   "TARGET_THUMB1"
7989   "*
7990   {
7991   output_asm_insn (\"tst\\t%0, %1\", operands);
7992   switch (get_attr_length (insn))
7993     {
7994     case 4:  return \"b%d3\\t%l2\";
7995     case 6:  return \"b%D3\\t.LCB%=\;b\\t%l2\\t%@long jump\\n.LCB%=:\";
7996     default: return \"b%D3\\t.LCB%=\;bl\\t%l2\\t%@far jump\\n.LCB%=:\";
7997     }
7998   }"
7999   [(set (attr "far_jump")
8000         (if_then_else
8001             (eq_attr "length" "8")
8002             (const_string "yes")
8003             (const_string "no")))
8004    (set (attr "length") 
8005         (if_then_else
8006             (and (ge (minus (match_dup 2) (pc)) (const_int -250))
8007                  (le (minus (match_dup 2) (pc)) (const_int 256)))
8008             (const_int 4)
8009             (if_then_else
8010                 (and (ge (minus (match_dup 2) (pc)) (const_int -2040))
8011                      (le (minus (match_dup 2) (pc)) (const_int 2048)))
8012                 (const_int 6)
8013                 (const_int 8))))
8014    (set_attr "type" "multiple")]
8016   
8017 (define_insn "*cbranchne_decr1"
8018   [(set (pc)
8019         (if_then_else (match_operator 3 "equality_operator"
8020                        [(match_operand:SI 2 "s_register_operand" "l,l,1,l")
8021                         (const_int 0)])
8022                       (label_ref (match_operand 4 "" ""))
8023                       (pc)))
8024    (set (match_operand:SI 0 "thumb_cbrch_target_operand" "=l,*?h,*?m,*?m")
8025         (plus:SI (match_dup 2) (const_int -1)))
8026    (clobber (match_scratch:SI 1 "=X,l,&l,&l"))]
8027   "TARGET_THUMB1"
8028   "*
8029    {
8030      rtx cond[2];
8031      cond[0] = gen_rtx_fmt_ee ((GET_CODE (operands[3]) == NE
8032                                 ? GEU : LTU),
8033                                VOIDmode, operands[2], const1_rtx);
8034      cond[1] = operands[4];
8036      if (which_alternative == 0)
8037        output_asm_insn (\"sub\\t%0, %2, #1\", operands);
8038      else if (which_alternative == 1)
8039        {
8040          /* We must provide an alternative for a hi reg because reload 
8041             cannot handle output reloads on a jump instruction, but we
8042             can't subtract into that.  Fortunately a mov from lo to hi
8043             does not clobber the condition codes.  */
8044          output_asm_insn (\"sub\\t%1, %2, #1\", operands);
8045          output_asm_insn (\"mov\\t%0, %1\", operands);
8046        }
8047      else
8048        {
8049          /* Similarly, but the target is memory.  */
8050          output_asm_insn (\"sub\\t%1, %2, #1\", operands);
8051          output_asm_insn (\"str\\t%1, %0\", operands);
8052        }
8054      switch (get_attr_length (insn) - (which_alternative ? 2 : 0))
8055        {
8056          case 4:
8057            output_asm_insn (\"b%d0\\t%l1\", cond);
8058            return \"\";
8059          case 6:
8060            output_asm_insn (\"b%D0\\t.LCB%=\", cond);
8061            return \"b\\t%l4\\t%@long jump\\n.LCB%=:\";
8062          default:
8063            output_asm_insn (\"b%D0\\t.LCB%=\", cond);
8064            return \"bl\\t%l4\\t%@far jump\\n.LCB%=:\";
8065        }
8066    }
8067   "
8068   [(set (attr "far_jump")
8069         (if_then_else
8070             (ior (and (eq (symbol_ref ("which_alternative"))
8071                           (const_int 0))
8072                       (eq_attr "length" "8"))
8073                  (eq_attr "length" "10"))
8074             (const_string "yes")
8075             (const_string "no")))
8076    (set_attr_alternative "length"
8077       [
8078        ;; Alternative 0
8079        (if_then_else
8080          (and (ge (minus (match_dup 4) (pc)) (const_int -250))
8081               (le (minus (match_dup 4) (pc)) (const_int 256)))
8082          (const_int 4)
8083          (if_then_else
8084            (and (ge (minus (match_dup 4) (pc)) (const_int -2040))
8085                 (le (minus (match_dup 4) (pc)) (const_int 2048)))
8086            (const_int 6)
8087            (const_int 8)))
8088        ;; Alternative 1
8089        (if_then_else
8090          (and (ge (minus (match_dup 4) (pc)) (const_int -248))
8091               (le (minus (match_dup 4) (pc)) (const_int 256)))
8092          (const_int 6)
8093          (if_then_else
8094            (and (ge (minus (match_dup 4) (pc)) (const_int -2038))
8095                 (le (minus (match_dup 4) (pc)) (const_int 2048)))
8096            (const_int 8)
8097            (const_int 10)))
8098        ;; Alternative 2
8099        (if_then_else
8100          (and (ge (minus (match_dup 4) (pc)) (const_int -248))
8101               (le (minus (match_dup 4) (pc)) (const_int 256)))
8102          (const_int 6)
8103          (if_then_else
8104            (and (ge (minus (match_dup 4) (pc)) (const_int -2038))
8105                 (le (minus (match_dup 4) (pc)) (const_int 2048)))
8106            (const_int 8)
8107            (const_int 10)))
8108        ;; Alternative 3
8109        (if_then_else
8110          (and (ge (minus (match_dup 4) (pc)) (const_int -248))
8111               (le (minus (match_dup 4) (pc)) (const_int 256)))
8112          (const_int 6)
8113          (if_then_else
8114            (and (ge (minus (match_dup 4) (pc)) (const_int -2038))
8115                 (le (minus (match_dup 4) (pc)) (const_int 2048)))
8116            (const_int 8)
8117            (const_int 10)))])
8118    (set_attr "type" "multiple")]
8121 (define_insn "*addsi3_cbranch"
8122   [(set (pc)
8123         (if_then_else
8124          (match_operator 4 "arm_comparison_operator"
8125           [(plus:SI
8126             (match_operand:SI 2 "s_register_operand" "%0,l,*l,1,1,1")
8127             (match_operand:SI 3 "reg_or_int_operand" "IJ,lL,*l,lIJ,lIJ,lIJ"))
8128            (const_int 0)])
8129          (label_ref (match_operand 5 "" ""))
8130          (pc)))
8131    (set
8132     (match_operand:SI 0 "thumb_cbrch_target_operand" "=l,l,*!h,*?h,*?m,*?m")
8133     (plus:SI (match_dup 2) (match_dup 3)))
8134    (clobber (match_scratch:SI 1 "=X,X,l,l,&l,&l"))]
8135   "TARGET_THUMB1
8136    && (GET_CODE (operands[4]) == EQ
8137        || GET_CODE (operands[4]) == NE
8138        || GET_CODE (operands[4]) == GE
8139        || GET_CODE (operands[4]) == LT)"
8140   "*
8141    {
8142      rtx cond[3];
8144      cond[0] = (which_alternative < 2) ? operands[0] : operands[1];
8145      cond[1] = operands[2];
8146      cond[2] = operands[3];
8148      if (CONST_INT_P (cond[2]) && INTVAL (cond[2]) < 0)
8149        output_asm_insn (\"sub\\t%0, %1, #%n2\", cond);
8150      else
8151        output_asm_insn (\"add\\t%0, %1, %2\", cond);
8153      if (which_alternative >= 2
8154          && which_alternative < 4)
8155        output_asm_insn (\"mov\\t%0, %1\", operands);
8156      else if (which_alternative >= 4)
8157        output_asm_insn (\"str\\t%1, %0\", operands);
8159      switch (get_attr_length (insn) - ((which_alternative >= 2) ? 2 : 0))
8160        {
8161          case 4:
8162            return \"b%d4\\t%l5\";
8163          case 6:
8164            return \"b%D4\\t.LCB%=\;b\\t%l5\\t%@long jump\\n.LCB%=:\";
8165          default:
8166            return \"b%D4\\t.LCB%=\;bl\\t%l5\\t%@far jump\\n.LCB%=:\";
8167        }
8168    }
8169   "
8170   [(set (attr "far_jump")
8171         (if_then_else
8172             (ior (and (lt (symbol_ref ("which_alternative"))
8173                           (const_int 2))
8174                       (eq_attr "length" "8"))
8175                  (eq_attr "length" "10"))
8176             (const_string "yes")
8177             (const_string "no")))
8178    (set (attr "length")
8179      (if_then_else
8180        (lt (symbol_ref ("which_alternative"))
8181                        (const_int 2))
8182        (if_then_else
8183          (and (ge (minus (match_dup 5) (pc)) (const_int -250))
8184               (le (minus (match_dup 5) (pc)) (const_int 256)))
8185          (const_int 4)
8186          (if_then_else
8187            (and (ge (minus (match_dup 5) (pc)) (const_int -2040))
8188                 (le (minus (match_dup 5) (pc)) (const_int 2048)))
8189            (const_int 6)
8190            (const_int 8)))
8191        (if_then_else
8192          (and (ge (minus (match_dup 5) (pc)) (const_int -248))
8193               (le (minus (match_dup 5) (pc)) (const_int 256)))
8194          (const_int 6)
8195          (if_then_else
8196            (and (ge (minus (match_dup 5) (pc)) (const_int -2038))
8197                 (le (minus (match_dup 5) (pc)) (const_int 2048)))
8198            (const_int 8)
8199            (const_int 10)))))
8200    (set_attr "type" "multiple")]
8203 (define_insn "*addsi3_cbranch_scratch"
8204   [(set (pc)
8205         (if_then_else
8206          (match_operator 3 "arm_comparison_operator"
8207           [(plus:SI
8208             (match_operand:SI 1 "s_register_operand" "%l,l,l,0")
8209             (match_operand:SI 2 "reg_or_int_operand" "J,l,L,IJ"))
8210            (const_int 0)])
8211          (label_ref (match_operand 4 "" ""))
8212          (pc)))
8213    (clobber (match_scratch:SI 0 "=X,X,l,l"))]
8214   "TARGET_THUMB1
8215    && (GET_CODE (operands[3]) == EQ
8216        || GET_CODE (operands[3]) == NE
8217        || GET_CODE (operands[3]) == GE
8218        || GET_CODE (operands[3]) == LT)"
8219   "*
8220    {
8221      switch (which_alternative)
8222        {
8223        case 0:
8224          output_asm_insn (\"cmp\t%1, #%n2\", operands);
8225          break;
8226        case 1:
8227          output_asm_insn (\"cmn\t%1, %2\", operands);
8228          break;
8229        case 2:
8230          if (INTVAL (operands[2]) < 0)
8231            output_asm_insn (\"sub\t%0, %1, %2\", operands);
8232          else
8233            output_asm_insn (\"add\t%0, %1, %2\", operands);
8234          break;
8235        case 3:
8236          if (INTVAL (operands[2]) < 0)
8237            output_asm_insn (\"sub\t%0, %0, %2\", operands);
8238          else
8239            output_asm_insn (\"add\t%0, %0, %2\", operands);
8240          break;
8241        }
8243      switch (get_attr_length (insn))
8244        {
8245          case 4:
8246            return \"b%d3\\t%l4\";
8247          case 6:
8248            return \"b%D3\\t.LCB%=\;b\\t%l4\\t%@long jump\\n.LCB%=:\";
8249          default:
8250            return \"b%D3\\t.LCB%=\;bl\\t%l4\\t%@far jump\\n.LCB%=:\";
8251        }
8252    }
8253   "
8254   [(set (attr "far_jump")
8255         (if_then_else
8256             (eq_attr "length" "8")
8257             (const_string "yes")
8258             (const_string "no")))
8259    (set (attr "length")
8260        (if_then_else
8261          (and (ge (minus (match_dup 4) (pc)) (const_int -250))
8262               (le (minus (match_dup 4) (pc)) (const_int 256)))
8263          (const_int 4)
8264          (if_then_else
8265            (and (ge (minus (match_dup 4) (pc)) (const_int -2040))
8266                 (le (minus (match_dup 4) (pc)) (const_int 2048)))
8267            (const_int 6)
8268            (const_int 8))))
8269    (set_attr "type" "multiple")]
8273 ;; Comparison and test insns
8275 (define_insn "*arm_cmpsi_insn"
8276   [(set (reg:CC CC_REGNUM)
8277         (compare:CC (match_operand:SI 0 "s_register_operand" "l,r,r,r,r")
8278                     (match_operand:SI 1 "arm_add_operand"    "Py,r,r,I,L")))]
8279   "TARGET_32BIT"
8280   "@
8281    cmp%?\\t%0, %1
8282    cmp%?\\t%0, %1
8283    cmp%?\\t%0, %1
8284    cmp%?\\t%0, %1
8285    cmn%?\\t%0, #%n1"
8286   [(set_attr "conds" "set")
8287    (set_attr "arch" "t2,t2,any,any,any")
8288    (set_attr "length" "2,2,4,4,4")
8289    (set_attr "predicable" "yes")
8290    (set_attr "predicable_short_it" "yes,yes,yes,no,no")
8291    (set_attr "type" "alus_imm,alus_reg,alus_reg,alus_imm,alus_imm")]
8294 (define_insn "*cmpsi_shiftsi"
8295   [(set (reg:CC CC_REGNUM)
8296         (compare:CC (match_operand:SI   0 "s_register_operand" "r,r,r")
8297                     (match_operator:SI  3 "shift_operator"
8298                      [(match_operand:SI 1 "s_register_operand" "r,r,r")
8299                       (match_operand:SI 2 "shift_amount_operand" "M,r,M")])))]
8300   "TARGET_32BIT"
8301   "cmp\\t%0, %1%S3"
8302   [(set_attr "conds" "set")
8303    (set_attr "shift" "1")
8304    (set_attr "arch" "32,a,a")
8305    (set_attr "type" "alus_shift_imm,alu_shift_reg,alus_shift_imm")])
8307 (define_insn "*cmpsi_shiftsi_swp"
8308   [(set (reg:CC_SWP CC_REGNUM)
8309         (compare:CC_SWP (match_operator:SI 3 "shift_operator"
8310                          [(match_operand:SI 1 "s_register_operand" "r,r,r")
8311                           (match_operand:SI 2 "shift_amount_operand" "M,r,M")])
8312                         (match_operand:SI 0 "s_register_operand" "r,r,r")))]
8313   "TARGET_32BIT"
8314   "cmp%?\\t%0, %1%S3"
8315   [(set_attr "conds" "set")
8316    (set_attr "shift" "1")
8317    (set_attr "arch" "32,a,a")
8318    (set_attr "type" "alus_shift_imm,alu_shift_reg,alus_shift_imm")])
8320 (define_insn "*arm_cmpsi_negshiftsi_si"
8321   [(set (reg:CC_Z CC_REGNUM)
8322         (compare:CC_Z
8323          (neg:SI (match_operator:SI 1 "shift_operator"
8324                     [(match_operand:SI 2 "s_register_operand" "r")
8325                      (match_operand:SI 3 "reg_or_int_operand" "rM")]))
8326          (match_operand:SI 0 "s_register_operand" "r")))]
8327   "TARGET_ARM"
8328   "cmn%?\\t%0, %2%S1"
8329   [(set_attr "conds" "set")
8330    (set (attr "type") (if_then_else (match_operand 3 "const_int_operand" "")
8331                                     (const_string "alus_shift_imm")
8332                                     (const_string "alus_shift_reg")))
8333    (set_attr "predicable" "yes")]
8336 ;; DImode comparisons.  The generic code generates branches that
8337 ;; if-conversion can not reduce to a conditional compare, so we do
8338 ;; that directly.
8340 (define_insn_and_split "*arm_cmpdi_insn"
8341   [(set (reg:CC_NCV CC_REGNUM)
8342         (compare:CC_NCV (match_operand:DI 0 "s_register_operand" "r")
8343                         (match_operand:DI 1 "arm_di_operand"       "rDi")))
8344    (clobber (match_scratch:SI 2 "=r"))]
8345   "TARGET_32BIT"
8346   "#"   ; "cmp\\t%Q0, %Q1\;sbcs\\t%2, %R0, %R1"
8347   "&& reload_completed"
8348   [(set (reg:CC CC_REGNUM)
8349         (compare:CC (match_dup 0) (match_dup 1)))
8350    (parallel [(set (reg:CC CC_REGNUM)
8351                    (compare:CC (match_dup 3) (match_dup 4)))
8352               (set (match_dup 2)
8353                    (minus:SI (match_dup 5)
8354                             (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))])]
8355   {
8356     operands[3] = gen_highpart (SImode, operands[0]);
8357     operands[0] = gen_lowpart (SImode, operands[0]);
8358     if (CONST_INT_P (operands[1]))
8359       {
8360         operands[4] = GEN_INT (~INTVAL (gen_highpart_mode (SImode,
8361                                                            DImode,
8362                                                            operands[1])));
8363         operands[5] = gen_rtx_PLUS (SImode, operands[3], operands[4]);
8364       }
8365     else
8366       {
8367         operands[4] = gen_highpart (SImode, operands[1]);
8368         operands[5] = gen_rtx_MINUS (SImode, operands[3], operands[4]);
8369       }
8370     operands[1] = gen_lowpart (SImode, operands[1]);
8371     operands[2] = gen_lowpart (SImode, operands[2]);
8372   }
8373   [(set_attr "conds" "set")
8374    (set_attr "length" "8")
8375    (set_attr "type" "multiple")]
8378 (define_insn_and_split "*arm_cmpdi_unsigned"
8379   [(set (reg:CC_CZ CC_REGNUM)
8380         (compare:CC_CZ (match_operand:DI 0 "s_register_operand" "l,r,r,r")
8381                        (match_operand:DI 1 "arm_di_operand"     "Py,r,Di,rDi")))]
8383   "TARGET_32BIT"
8384   "#"   ; "cmp\\t%R0, %R1\;it eq\;cmpeq\\t%Q0, %Q1"
8385   "&& reload_completed"
8386   [(set (reg:CC CC_REGNUM)
8387         (compare:CC (match_dup 2) (match_dup 3)))
8388    (cond_exec (eq:SI (reg:CC CC_REGNUM) (const_int 0))
8389               (set (reg:CC CC_REGNUM)
8390                    (compare:CC (match_dup 0) (match_dup 1))))]
8391   {
8392     operands[2] = gen_highpart (SImode, operands[0]);
8393     operands[0] = gen_lowpart (SImode, operands[0]);
8394     if (CONST_INT_P (operands[1]))
8395       operands[3] = gen_highpart_mode (SImode, DImode, operands[1]);
8396     else
8397       operands[3] = gen_highpart (SImode, operands[1]);
8398     operands[1] = gen_lowpart (SImode, operands[1]);
8399   }
8400   [(set_attr "conds" "set")
8401    (set_attr "enabled_for_depr_it" "yes,yes,no,*")
8402    (set_attr "arch" "t2,t2,t2,a")
8403    (set_attr "length" "6,6,10,8")
8404    (set_attr "type" "multiple")]
8407 (define_insn "*arm_cmpdi_zero"
8408   [(set (reg:CC_Z CC_REGNUM)
8409         (compare:CC_Z (match_operand:DI 0 "s_register_operand" "r")
8410                       (const_int 0)))
8411    (clobber (match_scratch:SI 1 "=r"))]
8412   "TARGET_32BIT"
8413   "orr%.\\t%1, %Q0, %R0"
8414   [(set_attr "conds" "set")
8415    (set_attr "type" "logics_reg")]
8418 (define_insn "*thumb_cmpdi_zero"
8419   [(set (reg:CC_Z CC_REGNUM)
8420         (compare:CC_Z (match_operand:DI 0 "s_register_operand" "l")
8421                       (const_int 0)))
8422    (clobber (match_scratch:SI 1 "=l"))]
8423   "TARGET_THUMB1"
8424   "orr\\t%1, %Q0, %R0"
8425   [(set_attr "conds" "set")
8426    (set_attr "length" "2")
8427    (set_attr "type" "logics_reg")]
8430 ; This insn allows redundant compares to be removed by cse, nothing should
8431 ; ever appear in the output file since (set (reg x) (reg x)) is a no-op that
8432 ; is deleted later on. The match_dup will match the mode here, so that
8433 ; mode changes of the condition codes aren't lost by this even though we don't
8434 ; specify what they are.
8436 (define_insn "*deleted_compare"
8437   [(set (match_operand 0 "cc_register" "") (match_dup 0))]
8438   "TARGET_32BIT"
8439   "\\t%@ deleted compare"
8440   [(set_attr "conds" "set")
8441    (set_attr "length" "0")
8442    (set_attr "type" "no_insn")]
8446 ;; Conditional branch insns
8448 (define_expand "cbranch_cc"
8449   [(set (pc)
8450         (if_then_else (match_operator 0 "" [(match_operand 1 "" "")
8451                                             (match_operand 2 "" "")])
8452                       (label_ref (match_operand 3 "" ""))
8453                       (pc)))]
8454   "TARGET_32BIT"
8455   "operands[1] = arm_gen_compare_reg (GET_CODE (operands[0]),
8456                                       operands[1], operands[2], NULL_RTX);
8457    operands[2] = const0_rtx;"
8461 ;; Patterns to match conditional branch insns.
8464 (define_insn "arm_cond_branch"
8465   [(set (pc)
8466         (if_then_else (match_operator 1 "arm_comparison_operator"
8467                        [(match_operand 2 "cc_register" "") (const_int 0)])
8468                       (label_ref (match_operand 0 "" ""))
8469                       (pc)))]
8470   "TARGET_32BIT"
8471   "*
8472   if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
8473     {
8474       arm_ccfsm_state += 2;
8475       return \"\";
8476     }
8477   return \"b%d1\\t%l0\";
8478   "
8479   [(set_attr "conds" "use")
8480    (set_attr "type" "branch")
8481    (set (attr "length")
8482         (if_then_else
8483            (and (match_test "TARGET_THUMB2")
8484                 (and (ge (minus (match_dup 0) (pc)) (const_int -250))
8485                      (le (minus (match_dup 0) (pc)) (const_int 256))))
8486            (const_int 2)
8487            (const_int 4)))]
8490 (define_insn "*arm_cond_branch_reversed"
8491   [(set (pc)
8492         (if_then_else (match_operator 1 "arm_comparison_operator"
8493                        [(match_operand 2 "cc_register" "") (const_int 0)])
8494                       (pc)
8495                       (label_ref (match_operand 0 "" ""))))]
8496   "TARGET_32BIT"
8497   "*
8498   if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
8499     {
8500       arm_ccfsm_state += 2;
8501       return \"\";
8502     }
8503   return \"b%D1\\t%l0\";
8504   "
8505   [(set_attr "conds" "use")
8506    (set_attr "type" "branch")
8507    (set (attr "length")
8508         (if_then_else
8509            (and (match_test "TARGET_THUMB2")
8510                 (and (ge (minus (match_dup 0) (pc)) (const_int -250))
8511                      (le (minus (match_dup 0) (pc)) (const_int 256))))
8512            (const_int 2)
8513            (const_int 4)))]
8518 ; scc insns
8520 (define_expand "cstore_cc"
8521   [(set (match_operand:SI 0 "s_register_operand" "")
8522         (match_operator:SI 1 "" [(match_operand 2 "" "")
8523                                  (match_operand 3 "" "")]))]
8524   "TARGET_32BIT"
8525   "operands[2] = arm_gen_compare_reg (GET_CODE (operands[1]),
8526                                       operands[2], operands[3], NULL_RTX);
8527    operands[3] = const0_rtx;"
8530 (define_insn_and_split "*mov_scc"
8531   [(set (match_operand:SI 0 "s_register_operand" "=r")
8532         (match_operator:SI 1 "arm_comparison_operator"
8533          [(match_operand 2 "cc_register" "") (const_int 0)]))]
8534   "TARGET_ARM"
8535   "#"   ; "mov%D1\\t%0, #0\;mov%d1\\t%0, #1"
8536   "TARGET_ARM"
8537   [(set (match_dup 0)
8538         (if_then_else:SI (match_dup 1)
8539                          (const_int 1)
8540                          (const_int 0)))]
8541   ""
8542   [(set_attr "conds" "use")
8543    (set_attr "length" "8")
8544    (set_attr "type" "multiple")]
8547 (define_insn_and_split "*mov_negscc"
8548   [(set (match_operand:SI 0 "s_register_operand" "=r")
8549         (neg:SI (match_operator:SI 1 "arm_comparison_operator"
8550                  [(match_operand 2 "cc_register" "") (const_int 0)])))]
8551   "TARGET_ARM"
8552   "#"   ; "mov%D1\\t%0, #0\;mvn%d1\\t%0, #0"
8553   "TARGET_ARM"
8554   [(set (match_dup 0)
8555         (if_then_else:SI (match_dup 1)
8556                          (match_dup 3)
8557                          (const_int 0)))]
8558   {
8559     operands[3] = GEN_INT (~0);
8560   }
8561   [(set_attr "conds" "use")
8562    (set_attr "length" "8")
8563    (set_attr "type" "multiple")]
8566 (define_insn_and_split "*mov_notscc"
8567   [(set (match_operand:SI 0 "s_register_operand" "=r")
8568         (not:SI (match_operator:SI 1 "arm_comparison_operator"
8569                  [(match_operand 2 "cc_register" "") (const_int 0)])))]
8570   "TARGET_ARM"
8571   "#"   ; "mvn%D1\\t%0, #0\;mvn%d1\\t%0, #1"
8572   "TARGET_ARM"
8573   [(set (match_dup 0)
8574         (if_then_else:SI (match_dup 1)
8575                          (match_dup 3)
8576                          (match_dup 4)))]
8577   {
8578     operands[3] = GEN_INT (~1);
8579     operands[4] = GEN_INT (~0);
8580   }
8581   [(set_attr "conds" "use")
8582    (set_attr "length" "8")
8583    (set_attr "type" "multiple")]
8586 (define_expand "cstoresi4"
8587   [(set (match_operand:SI 0 "s_register_operand" "")
8588         (match_operator:SI 1 "expandable_comparison_operator"
8589          [(match_operand:SI 2 "s_register_operand" "")
8590           (match_operand:SI 3 "reg_or_int_operand" "")]))]
8591   "TARGET_32BIT || TARGET_THUMB1"
8592   "{
8593   rtx op3, scratch, scratch2;
8595   if (!TARGET_THUMB1)
8596     {
8597       if (!arm_add_operand (operands[3], SImode))
8598         operands[3] = force_reg (SImode, operands[3]);
8599       emit_insn (gen_cstore_cc (operands[0], operands[1],
8600                                 operands[2], operands[3]));
8601       DONE;
8602     }
8604   if (operands[3] == const0_rtx)
8605     {
8606       switch (GET_CODE (operands[1]))
8607         {
8608         case EQ:
8609           emit_insn (gen_cstoresi_eq0_thumb1 (operands[0], operands[2]));
8610           break;
8612         case NE:
8613           emit_insn (gen_cstoresi_ne0_thumb1 (operands[0], operands[2]));
8614           break;
8616         case LE:
8617           scratch = expand_binop (SImode, add_optab, operands[2], constm1_rtx,
8618                                   NULL_RTX, 0, OPTAB_WIDEN);
8619           scratch = expand_binop (SImode, ior_optab, operands[2], scratch,
8620                                   NULL_RTX, 0, OPTAB_WIDEN);
8621           expand_binop (SImode, lshr_optab, scratch, GEN_INT (31),
8622                         operands[0], 1, OPTAB_WIDEN);
8623           break;
8625         case GE:
8626           scratch = expand_unop (SImode, one_cmpl_optab, operands[2],
8627                                  NULL_RTX, 1);
8628           expand_binop (SImode, lshr_optab, scratch, GEN_INT (31),
8629                         NULL_RTX, 1, OPTAB_WIDEN);
8630           break;
8632         case GT:
8633           scratch = expand_binop (SImode, ashr_optab, operands[2],
8634                                   GEN_INT (31), NULL_RTX, 0, OPTAB_WIDEN);
8635           scratch = expand_binop (SImode, sub_optab, scratch, operands[2],
8636                                   NULL_RTX, 0, OPTAB_WIDEN);
8637           expand_binop (SImode, lshr_optab, scratch, GEN_INT (31), operands[0],
8638                         0, OPTAB_WIDEN);
8639           break;
8641         /* LT is handled by generic code.  No need for unsigned with 0.  */
8642         default:
8643           FAIL;
8644         }
8645       DONE;
8646     }
8648   switch (GET_CODE (operands[1]))
8649     {
8650     case EQ:
8651       scratch = expand_binop (SImode, sub_optab, operands[2], operands[3],
8652                               NULL_RTX, 0, OPTAB_WIDEN);
8653       emit_insn (gen_cstoresi_eq0_thumb1 (operands[0], scratch));
8654       break;
8656     case NE:
8657       scratch = expand_binop (SImode, sub_optab, operands[2], operands[3],
8658                               NULL_RTX, 0, OPTAB_WIDEN);
8659       emit_insn (gen_cstoresi_ne0_thumb1 (operands[0], scratch));
8660       break;
8662     case LE:
8663       op3 = force_reg (SImode, operands[3]);
8665       scratch = expand_binop (SImode, lshr_optab, operands[2], GEN_INT (31),
8666                               NULL_RTX, 1, OPTAB_WIDEN);
8667       scratch2 = expand_binop (SImode, ashr_optab, op3, GEN_INT (31),
8668                               NULL_RTX, 0, OPTAB_WIDEN);
8669       emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch2,
8670                                           op3, operands[2]));
8671       break;
8673     case GE:
8674       op3 = operands[3];
8675       if (!thumb1_cmp_operand (op3, SImode))
8676         op3 = force_reg (SImode, op3);
8677       scratch = expand_binop (SImode, ashr_optab, operands[2], GEN_INT (31),
8678                               NULL_RTX, 0, OPTAB_WIDEN);
8679       scratch2 = expand_binop (SImode, lshr_optab, op3, GEN_INT (31),
8680                                NULL_RTX, 1, OPTAB_WIDEN);
8681       emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch2,
8682                                           operands[2], op3));
8683       break;
8685     case LEU:
8686       op3 = force_reg (SImode, operands[3]);
8687       scratch = force_reg (SImode, const0_rtx);
8688       emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch,
8689                                           op3, operands[2]));
8690       break;
8692     case GEU:
8693       op3 = operands[3];
8694       if (!thumb1_cmp_operand (op3, SImode))
8695         op3 = force_reg (SImode, op3);
8696       scratch = force_reg (SImode, const0_rtx);
8697       emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch,
8698                                           operands[2], op3));
8699       break;
8701     case LTU:
8702       op3 = operands[3];
8703       if (!thumb1_cmp_operand (op3, SImode))
8704         op3 = force_reg (SImode, op3);
8705       scratch = gen_reg_rtx (SImode);
8706       emit_insn (gen_cstoresi_ltu_thumb1 (operands[0], operands[2], op3));
8707       break;
8709     case GTU:
8710       op3 = force_reg (SImode, operands[3]);
8711       scratch = gen_reg_rtx (SImode);
8712       emit_insn (gen_cstoresi_ltu_thumb1 (operands[0], op3, operands[2]));
8713       break;
8715     /* No good sequences for GT, LT.  */
8716     default:
8717       FAIL;
8718     }
8719   DONE;
8722 (define_expand "cstoresf4"
8723   [(set (match_operand:SI 0 "s_register_operand" "")
8724         (match_operator:SI 1 "expandable_comparison_operator"
8725          [(match_operand:SF 2 "s_register_operand" "")
8726           (match_operand:SF 3 "arm_float_compare_operand" "")]))]
8727   "TARGET_32BIT && TARGET_HARD_FLOAT"
8728   "emit_insn (gen_cstore_cc (operands[0], operands[1],
8729                              operands[2], operands[3])); DONE;"
8732 (define_expand "cstoredf4"
8733   [(set (match_operand:SI 0 "s_register_operand" "")
8734         (match_operator:SI 1 "expandable_comparison_operator"
8735          [(match_operand:DF 2 "s_register_operand" "")
8736           (match_operand:DF 3 "arm_float_compare_operand" "")]))]
8737   "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
8738   "emit_insn (gen_cstore_cc (operands[0], operands[1],
8739                              operands[2], operands[3])); DONE;"
8742 (define_expand "cstoredi4"
8743   [(set (match_operand:SI 0 "s_register_operand" "")
8744         (match_operator:SI 1 "expandable_comparison_operator"
8745          [(match_operand:DI 2 "s_register_operand" "")
8746           (match_operand:DI 3 "cmpdi_operand" "")]))]
8747   "TARGET_32BIT"
8748   "{
8749      if (!arm_validize_comparison (&operands[1],
8750                                    &operands[2],
8751                                    &operands[3]))
8752        FAIL;
8753      emit_insn (gen_cstore_cc (operands[0], operands[1], operands[2],
8754                                  operands[3]));
8755      DONE;
8756    }"
8759 (define_expand "cstoresi_eq0_thumb1"
8760   [(parallel
8761     [(set (match_operand:SI 0 "s_register_operand" "")
8762           (eq:SI (match_operand:SI 1 "s_register_operand" "")
8763                  (const_int 0)))
8764      (clobber (match_dup:SI 2))])]
8765   "TARGET_THUMB1"
8766   "operands[2] = gen_reg_rtx (SImode);"
8769 (define_expand "cstoresi_ne0_thumb1"
8770   [(parallel
8771     [(set (match_operand:SI 0 "s_register_operand" "")
8772           (ne:SI (match_operand:SI 1 "s_register_operand" "")
8773                  (const_int 0)))
8774      (clobber (match_dup:SI 2))])]
8775   "TARGET_THUMB1"
8776   "operands[2] = gen_reg_rtx (SImode);"
8779 (define_insn "*cstoresi_eq0_thumb1_insn"
8780   [(set (match_operand:SI 0 "s_register_operand" "=&l,l")
8781         (eq:SI (match_operand:SI 1 "s_register_operand" "l,0")
8782                (const_int 0)))
8783    (clobber (match_operand:SI 2 "s_register_operand" "=X,l"))]
8784   "TARGET_THUMB1"
8785   "@
8786    neg\\t%0, %1\;adc\\t%0, %0, %1
8787    neg\\t%2, %1\;adc\\t%0, %1, %2"
8788   [(set_attr "length" "4")
8789    (set_attr "type" "multiple")]
8792 (define_insn "*cstoresi_ne0_thumb1_insn"
8793   [(set (match_operand:SI 0 "s_register_operand" "=l")
8794         (ne:SI (match_operand:SI 1 "s_register_operand" "0")
8795                (const_int 0)))
8796    (clobber (match_operand:SI 2 "s_register_operand" "=l"))]
8797   "TARGET_THUMB1"
8798   "sub\\t%2, %1, #1\;sbc\\t%0, %1, %2"
8799   [(set_attr "length" "4")]
8802 ;; Used as part of the expansion of thumb ltu and gtu sequences
8803 (define_insn "cstoresi_nltu_thumb1"
8804   [(set (match_operand:SI 0 "s_register_operand" "=l,l")
8805         (neg:SI (ltu:SI (match_operand:SI 1 "s_register_operand" "l,*h")
8806                         (match_operand:SI 2 "thumb1_cmp_operand" "lI*h,*r"))))]
8807   "TARGET_THUMB1"
8808   "cmp\\t%1, %2\;sbc\\t%0, %0, %0"
8809   [(set_attr "length" "4")
8810    (set_attr "type" "multiple")]
8813 (define_insn_and_split "cstoresi_ltu_thumb1"
8814   [(set (match_operand:SI 0 "s_register_operand" "=l,l")
8815         (ltu:SI (match_operand:SI 1 "s_register_operand" "l,*h")
8816                 (match_operand:SI 2 "thumb1_cmp_operand" "lI*h,*r")))]
8817   "TARGET_THUMB1"
8818   "#"
8819   "TARGET_THUMB1"
8820   [(set (match_dup 3)
8821         (neg:SI (ltu:SI (match_dup 1) (match_dup 2))))
8822    (set (match_dup 0) (neg:SI (match_dup 3)))]
8823   "operands[3] = gen_reg_rtx (SImode);"
8824   [(set_attr "length" "4")
8825    (set_attr "type" "multiple")]
8828 ;; Used as part of the expansion of thumb les sequence.
8829 (define_insn "thumb1_addsi3_addgeu"
8830   [(set (match_operand:SI 0 "s_register_operand" "=l")
8831         (plus:SI (plus:SI (match_operand:SI 1 "s_register_operand" "%0")
8832                           (match_operand:SI 2 "s_register_operand" "l"))
8833                  (geu:SI (match_operand:SI 3 "s_register_operand" "l")
8834                          (match_operand:SI 4 "thumb1_cmp_operand" "lI"))))]
8835   "TARGET_THUMB1"
8836   "cmp\\t%3, %4\;adc\\t%0, %1, %2"
8837   [(set_attr "length" "4")
8838    (set_attr "type" "multiple")]
8842 ;; Conditional move insns
8844 (define_expand "movsicc"
8845   [(set (match_operand:SI 0 "s_register_operand" "")
8846         (if_then_else:SI (match_operand 1 "expandable_comparison_operator" "")
8847                          (match_operand:SI 2 "arm_not_operand" "")
8848                          (match_operand:SI 3 "arm_not_operand" "")))]
8849   "TARGET_32BIT"
8850   "
8851   {
8852     enum rtx_code code;
8853     rtx ccreg;
8855     if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0), 
8856                                   &XEXP (operands[1], 1)))
8857       FAIL;
8858     
8859     code = GET_CODE (operands[1]);
8860     ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
8861                                  XEXP (operands[1], 1), NULL_RTX);
8862     operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
8863   }"
8866 (define_expand "movsfcc"
8867   [(set (match_operand:SF 0 "s_register_operand" "")
8868         (if_then_else:SF (match_operand 1 "arm_cond_move_operator" "")
8869                          (match_operand:SF 2 "s_register_operand" "")
8870                          (match_operand:SF 3 "s_register_operand" "")))]
8871   "TARGET_32BIT && TARGET_HARD_FLOAT"
8872   "
8873   {
8874     enum rtx_code code = GET_CODE (operands[1]);
8875     rtx ccreg;
8877     if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0), 
8878                                   &XEXP (operands[1], 1)))
8879        FAIL;
8881     code = GET_CODE (operands[1]);
8882     ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
8883                                  XEXP (operands[1], 1), NULL_RTX);
8884     operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
8885   }"
8888 (define_expand "movdfcc"
8889   [(set (match_operand:DF 0 "s_register_operand" "")
8890         (if_then_else:DF (match_operand 1 "arm_cond_move_operator" "")
8891                          (match_operand:DF 2 "s_register_operand" "")
8892                          (match_operand:DF 3 "s_register_operand" "")))]
8893   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
8894   "
8895   {
8896     enum rtx_code code = GET_CODE (operands[1]);
8897     rtx ccreg;
8899     if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0), 
8900                                   &XEXP (operands[1], 1)))
8901        FAIL;
8902     code = GET_CODE (operands[1]);
8903     ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
8904                                  XEXP (operands[1], 1), NULL_RTX);
8905     operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
8906   }"
8909 (define_insn "*cmov<mode>"
8910     [(set (match_operand:SDF 0 "s_register_operand" "=<F_constraint>")
8911         (if_then_else:SDF (match_operator 1 "arm_vsel_comparison_operator"
8912                           [(match_operand 2 "cc_register" "") (const_int 0)])
8913                           (match_operand:SDF 3 "s_register_operand"
8914                                               "<F_constraint>")
8915                           (match_operand:SDF 4 "s_register_operand"
8916                                               "<F_constraint>")))]
8917   "TARGET_HARD_FLOAT && TARGET_FPU_ARMV8 <vfp_double_cond>"
8918   "*
8919   {
8920     enum arm_cond_code code = maybe_get_arm_condition_code (operands[1]);
8921     switch (code)
8922       {
8923       case ARM_GE:
8924       case ARM_GT:
8925       case ARM_EQ:
8926       case ARM_VS:
8927         return \"vsel%d1.<V_if_elem>\\t%<V_reg>0, %<V_reg>3, %<V_reg>4\";
8928       case ARM_LT:
8929       case ARM_LE:
8930       case ARM_NE:
8931       case ARM_VC:
8932         return \"vsel%D1.<V_if_elem>\\t%<V_reg>0, %<V_reg>4, %<V_reg>3\";
8933       default:
8934         gcc_unreachable ();
8935       }
8936     return \"\";
8937   }"
8938   [(set_attr "conds" "use")
8939    (set_attr "type" "fcsel")]
8942 (define_insn_and_split "*movsicc_insn"
8943   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r,r,r,r,r")
8944         (if_then_else:SI
8945          (match_operator 3 "arm_comparison_operator"
8946           [(match_operand 4 "cc_register" "") (const_int 0)])
8947          (match_operand:SI 1 "arm_not_operand" "0,0,rI,K,rI,rI,K,K")
8948          (match_operand:SI 2 "arm_not_operand" "rI,K,0,0,rI,K,rI,K")))]
8949   "TARGET_ARM"
8950   "@
8951    mov%D3\\t%0, %2
8952    mvn%D3\\t%0, #%B2
8953    mov%d3\\t%0, %1
8954    mvn%d3\\t%0, #%B1
8955    #
8956    #
8957    #
8958    #"
8959    ; alt4: mov%d3\\t%0, %1\;mov%D3\\t%0, %2
8960    ; alt5: mov%d3\\t%0, %1\;mvn%D3\\t%0, #%B2
8961    ; alt6: mvn%d3\\t%0, #%B1\;mov%D3\\t%0, %2
8962    ; alt7: mvn%d3\\t%0, #%B1\;mvn%D3\\t%0, #%B2"
8963   "&& reload_completed"
8964   [(const_int 0)]
8965   {
8966     enum rtx_code rev_code;
8967     enum machine_mode mode;
8968     rtx rev_cond;
8970     emit_insn (gen_rtx_COND_EXEC (VOIDmode,
8971                                   operands[3],
8972                                   gen_rtx_SET (VOIDmode,
8973                                                operands[0],
8974                                                operands[1])));
8976     rev_code = GET_CODE (operands[3]);
8977     mode = GET_MODE (operands[4]);
8978     if (mode == CCFPmode || mode == CCFPEmode)
8979       rev_code = reverse_condition_maybe_unordered (rev_code);
8980     else
8981       rev_code = reverse_condition (rev_code);
8983     rev_cond = gen_rtx_fmt_ee (rev_code,
8984                                VOIDmode,
8985                                operands[4],
8986                                const0_rtx);
8987     emit_insn (gen_rtx_COND_EXEC (VOIDmode,
8988                                   rev_cond,
8989                                   gen_rtx_SET (VOIDmode,
8990                                                operands[0],
8991                                                operands[2])));
8992     DONE;
8993   }
8994   [(set_attr "length" "4,4,4,4,8,8,8,8")
8995    (set_attr "conds" "use")
8996    (set_attr_alternative "type"
8997                          [(if_then_else (match_operand 2 "const_int_operand" "")
8998                                         (const_string "mov_imm")
8999                                         (const_string "mov_reg"))
9000                           (const_string "mvn_imm")
9001                           (if_then_else (match_operand 1 "const_int_operand" "")
9002                                         (const_string "mov_imm")
9003                                         (const_string "mov_reg"))
9004                           (const_string "mvn_imm")
9005                           (const_string "mov_reg")
9006                           (const_string "mov_reg")
9007                           (const_string "mov_reg")
9008                           (const_string "mov_reg")])]
9011 (define_insn "*movsfcc_soft_insn"
9012   [(set (match_operand:SF 0 "s_register_operand" "=r,r")
9013         (if_then_else:SF (match_operator 3 "arm_comparison_operator"
9014                           [(match_operand 4 "cc_register" "") (const_int 0)])
9015                          (match_operand:SF 1 "s_register_operand" "0,r")
9016                          (match_operand:SF 2 "s_register_operand" "r,0")))]
9017   "TARGET_ARM && TARGET_SOFT_FLOAT"
9018   "@
9019    mov%D3\\t%0, %2
9020    mov%d3\\t%0, %1"
9021   [(set_attr "conds" "use")
9022    (set_attr "type" "mov_reg")]
9026 ;; Jump and linkage insns
9028 (define_expand "jump"
9029   [(set (pc)
9030         (label_ref (match_operand 0 "" "")))]
9031   "TARGET_EITHER"
9032   ""
9035 (define_insn "*arm_jump"
9036   [(set (pc)
9037         (label_ref (match_operand 0 "" "")))]
9038   "TARGET_32BIT"
9039   "*
9040   {
9041     if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
9042       {
9043         arm_ccfsm_state += 2;
9044         return \"\";
9045       }
9046     return \"b%?\\t%l0\";
9047   }
9048   "
9049   [(set_attr "predicable" "yes")
9050    (set (attr "length")
9051         (if_then_else
9052            (and (match_test "TARGET_THUMB2")
9053                 (and (ge (minus (match_dup 0) (pc)) (const_int -2044))
9054                      (le (minus (match_dup 0) (pc)) (const_int 2048))))
9055            (const_int 2)
9056            (const_int 4)))
9057    (set_attr "type" "branch")]
9060 (define_insn "*thumb_jump"
9061   [(set (pc)
9062         (label_ref (match_operand 0 "" "")))]
9063   "TARGET_THUMB1"
9064   "*
9065   if (get_attr_length (insn) == 2)
9066     return \"b\\t%l0\";
9067   return \"bl\\t%l0\\t%@ far jump\";
9068   "
9069   [(set (attr "far_jump")
9070         (if_then_else
9071             (eq_attr "length" "4")
9072             (const_string "yes")
9073             (const_string "no")))
9074    (set (attr "length") 
9075         (if_then_else
9076             (and (ge (minus (match_dup 0) (pc)) (const_int -2044))
9077                  (le (minus (match_dup 0) (pc)) (const_int 2048)))
9078             (const_int 2)
9079             (const_int 4)))
9080    (set_attr "type" "branch")]
9083 (define_expand "call"
9084   [(parallel [(call (match_operand 0 "memory_operand" "")
9085                     (match_operand 1 "general_operand" ""))
9086               (use (match_operand 2 "" ""))
9087               (clobber (reg:SI LR_REGNUM))])]
9088   "TARGET_EITHER"
9089   "
9090   {
9091     rtx callee, pat;
9092     
9093     /* In an untyped call, we can get NULL for operand 2.  */
9094     if (operands[2] == NULL_RTX)
9095       operands[2] = const0_rtx;
9096       
9097     /* Decide if we should generate indirect calls by loading the
9098        32-bit address of the callee into a register before performing the
9099        branch and link.  */
9100     callee = XEXP (operands[0], 0);
9101     if (GET_CODE (callee) == SYMBOL_REF
9102         ? arm_is_long_call_p (SYMBOL_REF_DECL (callee))
9103         : !REG_P (callee))
9104       XEXP (operands[0], 0) = force_reg (Pmode, callee);
9106     pat = gen_call_internal (operands[0], operands[1], operands[2]);
9107     arm_emit_call_insn (pat, XEXP (operands[0], 0));
9108     DONE;
9109   }"
9112 (define_expand "call_internal"
9113   [(parallel [(call (match_operand 0 "memory_operand" "")
9114                     (match_operand 1 "general_operand" ""))
9115               (use (match_operand 2 "" ""))
9116               (clobber (reg:SI LR_REGNUM))])])
9118 (define_insn "*call_reg_armv5"
9119   [(call (mem:SI (match_operand:SI 0 "s_register_operand" "r"))
9120          (match_operand 1 "" ""))
9121    (use (match_operand 2 "" ""))
9122    (clobber (reg:SI LR_REGNUM))]
9123   "TARGET_ARM && arm_arch5 && !SIBLING_CALL_P (insn)"
9124   "blx%?\\t%0"
9125   [(set_attr "type" "call")]
9128 (define_insn "*call_reg_arm"
9129   [(call (mem:SI (match_operand:SI 0 "s_register_operand" "r"))
9130          (match_operand 1 "" ""))
9131    (use (match_operand 2 "" ""))
9132    (clobber (reg:SI LR_REGNUM))]
9133   "TARGET_ARM && !arm_arch5 && !SIBLING_CALL_P (insn)"
9134   "*
9135   return output_call (operands);
9136   "
9137   ;; length is worst case, normally it is only two
9138   [(set_attr "length" "12")
9139    (set_attr "type" "call")]
9143 ;; Note: not used for armv5+ because the sequence used (ldr pc, ...) is not
9144 ;; considered a function call by the branch predictor of some cores (PR40887).
9145 ;; Falls back to blx rN (*call_reg_armv5).
9147 (define_insn "*call_mem"
9148   [(call (mem:SI (match_operand:SI 0 "call_memory_operand" "m"))
9149          (match_operand 1 "" ""))
9150    (use (match_operand 2 "" ""))
9151    (clobber (reg:SI LR_REGNUM))]
9152   "TARGET_ARM && !arm_arch5 && !SIBLING_CALL_P (insn)"
9153   "*
9154   return output_call_mem (operands);
9155   "
9156   [(set_attr "length" "12")
9157    (set_attr "type" "call")]
9160 (define_insn "*call_reg_thumb1_v5"
9161   [(call (mem:SI (match_operand:SI 0 "register_operand" "l*r"))
9162          (match_operand 1 "" ""))
9163    (use (match_operand 2 "" ""))
9164    (clobber (reg:SI LR_REGNUM))]
9165   "TARGET_THUMB1 && arm_arch5 && !SIBLING_CALL_P (insn)"
9166   "blx\\t%0"
9167   [(set_attr "length" "2")
9168    (set_attr "type" "call")]
9171 (define_insn "*call_reg_thumb1"
9172   [(call (mem:SI (match_operand:SI 0 "register_operand" "l*r"))
9173          (match_operand 1 "" ""))
9174    (use (match_operand 2 "" ""))
9175    (clobber (reg:SI LR_REGNUM))]
9176   "TARGET_THUMB1 && !arm_arch5 && !SIBLING_CALL_P (insn)"
9177   "*
9178   {
9179     if (!TARGET_CALLER_INTERWORKING)
9180       return thumb_call_via_reg (operands[0]);
9181     else if (operands[1] == const0_rtx)
9182       return \"bl\\t%__interwork_call_via_%0\";
9183     else if (frame_pointer_needed)
9184       return \"bl\\t%__interwork_r7_call_via_%0\";
9185     else
9186       return \"bl\\t%__interwork_r11_call_via_%0\";
9187   }"
9188   [(set_attr "type" "call")]
9191 (define_expand "call_value"
9192   [(parallel [(set (match_operand       0 "" "")
9193                    (call (match_operand 1 "memory_operand" "")
9194                          (match_operand 2 "general_operand" "")))
9195               (use (match_operand 3 "" ""))
9196               (clobber (reg:SI LR_REGNUM))])]
9197   "TARGET_EITHER"
9198   "
9199   {
9200     rtx pat, callee;
9201     
9202     /* In an untyped call, we can get NULL for operand 2.  */
9203     if (operands[3] == 0)
9204       operands[3] = const0_rtx;
9205       
9206     /* Decide if we should generate indirect calls by loading the
9207        32-bit address of the callee into a register before performing the
9208        branch and link.  */
9209     callee = XEXP (operands[1], 0);
9210     if (GET_CODE (callee) == SYMBOL_REF
9211         ? arm_is_long_call_p (SYMBOL_REF_DECL (callee))
9212         : !REG_P (callee))
9213       XEXP (operands[1], 0) = force_reg (Pmode, callee);
9215     pat = gen_call_value_internal (operands[0], operands[1],
9216                                    operands[2], operands[3]);
9217     arm_emit_call_insn (pat, XEXP (operands[1], 0));
9218     DONE;
9219   }"
9222 (define_expand "call_value_internal"
9223   [(parallel [(set (match_operand       0 "" "")
9224                    (call (match_operand 1 "memory_operand" "")
9225                          (match_operand 2 "general_operand" "")))
9226               (use (match_operand 3 "" ""))
9227               (clobber (reg:SI LR_REGNUM))])])
9229 (define_insn "*call_value_reg_armv5"
9230   [(set (match_operand 0 "" "")
9231         (call (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
9232               (match_operand 2 "" "")))
9233    (use (match_operand 3 "" ""))
9234    (clobber (reg:SI LR_REGNUM))]
9235   "TARGET_ARM && arm_arch5 && !SIBLING_CALL_P (insn)"
9236   "blx%?\\t%1"
9237   [(set_attr "type" "call")]
9240 (define_insn "*call_value_reg_arm"
9241   [(set (match_operand 0 "" "")
9242         (call (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
9243               (match_operand 2 "" "")))
9244    (use (match_operand 3 "" ""))
9245    (clobber (reg:SI LR_REGNUM))]
9246   "TARGET_ARM && !arm_arch5 && !SIBLING_CALL_P (insn)"
9247   "*
9248   return output_call (&operands[1]);
9249   "
9250   [(set_attr "length" "12")
9251    (set_attr "type" "call")]
9254 ;; Note: see *call_mem
9256 (define_insn "*call_value_mem"
9257   [(set (match_operand 0 "" "")
9258         (call (mem:SI (match_operand:SI 1 "call_memory_operand" "m"))
9259               (match_operand 2 "" "")))
9260    (use (match_operand 3 "" ""))
9261    (clobber (reg:SI LR_REGNUM))]
9262   "TARGET_ARM && !arm_arch5 && (!CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
9263    && !SIBLING_CALL_P (insn)"
9264   "*
9265   return output_call_mem (&operands[1]);
9266   "
9267   [(set_attr "length" "12")
9268    (set_attr "type" "call")]
9271 (define_insn "*call_value_reg_thumb1_v5"
9272   [(set (match_operand 0 "" "")
9273         (call (mem:SI (match_operand:SI 1 "register_operand" "l*r"))
9274               (match_operand 2 "" "")))
9275    (use (match_operand 3 "" ""))
9276    (clobber (reg:SI LR_REGNUM))]
9277   "TARGET_THUMB1 && arm_arch5"
9278   "blx\\t%1"
9279   [(set_attr "length" "2")
9280    (set_attr "type" "call")]
9283 (define_insn "*call_value_reg_thumb1"
9284   [(set (match_operand 0 "" "")
9285         (call (mem:SI (match_operand:SI 1 "register_operand" "l*r"))
9286               (match_operand 2 "" "")))
9287    (use (match_operand 3 "" ""))
9288    (clobber (reg:SI LR_REGNUM))]
9289   "TARGET_THUMB1 && !arm_arch5"
9290   "*
9291   {
9292     if (!TARGET_CALLER_INTERWORKING)
9293       return thumb_call_via_reg (operands[1]);
9294     else if (operands[2] == const0_rtx)
9295       return \"bl\\t%__interwork_call_via_%1\";
9296     else if (frame_pointer_needed)
9297       return \"bl\\t%__interwork_r7_call_via_%1\";
9298     else
9299       return \"bl\\t%__interwork_r11_call_via_%1\";
9300   }"
9301   [(set_attr "type" "call")]
9304 ;; Allow calls to SYMBOL_REFs specially as they are not valid general addresses
9305 ;; The 'a' causes the operand to be treated as an address, i.e. no '#' output.
9307 (define_insn "*call_symbol"
9308   [(call (mem:SI (match_operand:SI 0 "" ""))
9309          (match_operand 1 "" ""))
9310    (use (match_operand 2 "" ""))
9311    (clobber (reg:SI LR_REGNUM))]
9312   "TARGET_32BIT
9313    && !SIBLING_CALL_P (insn)
9314    && (GET_CODE (operands[0]) == SYMBOL_REF)
9315    && !arm_is_long_call_p (SYMBOL_REF_DECL (operands[0]))"
9316   "*
9317   {
9318     return NEED_PLT_RELOC ? \"bl%?\\t%a0(PLT)\" : \"bl%?\\t%a0\";
9319   }"
9320   [(set_attr "type" "call")]
9323 (define_insn "*call_value_symbol"
9324   [(set (match_operand 0 "" "")
9325         (call (mem:SI (match_operand:SI 1 "" ""))
9326         (match_operand:SI 2 "" "")))
9327    (use (match_operand 3 "" ""))
9328    (clobber (reg:SI LR_REGNUM))]
9329   "TARGET_32BIT
9330    && !SIBLING_CALL_P (insn)
9331    && (GET_CODE (operands[1]) == SYMBOL_REF)
9332    && !arm_is_long_call_p (SYMBOL_REF_DECL (operands[1]))"
9333   "*
9334   {
9335     return NEED_PLT_RELOC ? \"bl%?\\t%a1(PLT)\" : \"bl%?\\t%a1\";
9336   }"
9337   [(set_attr "type" "call")]
9340 (define_insn "*call_insn"
9341   [(call (mem:SI (match_operand:SI 0 "" ""))
9342          (match_operand:SI 1 "" ""))
9343    (use (match_operand 2 "" ""))
9344    (clobber (reg:SI LR_REGNUM))]
9345   "TARGET_THUMB1
9346    && GET_CODE (operands[0]) == SYMBOL_REF
9347    && !arm_is_long_call_p (SYMBOL_REF_DECL (operands[0]))"
9348   "bl\\t%a0"
9349   [(set_attr "length" "4")
9350    (set_attr "type" "call")]
9353 (define_insn "*call_value_insn"
9354   [(set (match_operand 0 "" "")
9355         (call (mem:SI (match_operand 1 "" ""))
9356               (match_operand 2 "" "")))
9357    (use (match_operand 3 "" ""))
9358    (clobber (reg:SI LR_REGNUM))]
9359   "TARGET_THUMB1
9360    && GET_CODE (operands[1]) == SYMBOL_REF
9361    && !arm_is_long_call_p (SYMBOL_REF_DECL (operands[1]))"
9362   "bl\\t%a1"
9363   [(set_attr "length" "4")
9364    (set_attr "type" "call")]
9367 ;; We may also be able to do sibcalls for Thumb, but it's much harder...
9368 (define_expand "sibcall"
9369   [(parallel [(call (match_operand 0 "memory_operand" "")
9370                     (match_operand 1 "general_operand" ""))
9371               (return)
9372               (use (match_operand 2 "" ""))])]
9373   "TARGET_32BIT"
9374   "
9375   {
9376     if ((!REG_P (XEXP (operands[0], 0))
9377          && GET_CODE (XEXP (operands[0], 0)) != SYMBOL_REF)
9378         || (GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
9379             && arm_is_long_call_p (SYMBOL_REF_DECL (XEXP (operands[0], 0)))))
9380      XEXP (operands[0], 0) = force_reg (SImode, XEXP (operands[0], 0));
9382     if (operands[2] == NULL_RTX)
9383       operands[2] = const0_rtx;
9384   }"
9387 (define_expand "sibcall_value"
9388   [(parallel [(set (match_operand 0 "" "")
9389                    (call (match_operand 1 "memory_operand" "")
9390                          (match_operand 2 "general_operand" "")))
9391               (return)
9392               (use (match_operand 3 "" ""))])]
9393   "TARGET_32BIT"
9394   "
9395   {
9396     if ((!REG_P (XEXP (operands[1], 0))
9397          && GET_CODE (XEXP (operands[1], 0)) != SYMBOL_REF)
9398         || (GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
9399             && arm_is_long_call_p (SYMBOL_REF_DECL (XEXP (operands[1], 0)))))
9400      XEXP (operands[1], 0) = force_reg (SImode, XEXP (operands[1], 0));
9402     if (operands[3] == NULL_RTX)
9403       operands[3] = const0_rtx;
9404   }"
9407 (define_insn "*sibcall_insn"
9408  [(call (mem:SI (match_operand:SI 0 "call_insn_operand" "Cs, US"))
9409         (match_operand 1 "" ""))
9410   (return)
9411   (use (match_operand 2 "" ""))]
9412   "TARGET_32BIT && SIBLING_CALL_P (insn)"
9413   "*
9414   if (which_alternative == 1)
9415     return NEED_PLT_RELOC ? \"b%?\\t%a0(PLT)\" : \"b%?\\t%a0\";
9416   else
9417     {
9418       if (arm_arch5 || arm_arch4t)
9419         return \"bx%?\\t%0\\t%@ indirect register sibling call\";
9420       else
9421         return \"mov%?\\t%|pc, %0\\t%@ indirect register sibling call\";
9422     }
9423   "
9424   [(set_attr "type" "call")]
9427 (define_insn "*sibcall_value_insn"
9428  [(set (match_operand 0 "" "")
9429        (call (mem:SI (match_operand:SI 1 "call_insn_operand" "Cs,US"))
9430              (match_operand 2 "" "")))
9431   (return)
9432   (use (match_operand 3 "" ""))]
9433   "TARGET_32BIT && SIBLING_CALL_P (insn)"
9434   "*
9435   if (which_alternative == 1)
9436    return NEED_PLT_RELOC ? \"b%?\\t%a1(PLT)\" : \"b%?\\t%a1\";
9437   else
9438     {
9439       if (arm_arch5 || arm_arch4t)
9440         return \"bx%?\\t%1\";
9441       else
9442         return \"mov%?\\t%|pc, %1\\t@ indirect sibling call \";
9443     }
9444   "
9445   [(set_attr "type" "call")]
9448 (define_expand "<return_str>return"
9449   [(returns)]
9450   "(TARGET_ARM || (TARGET_THUMB2
9451                    && ARM_FUNC_TYPE (arm_current_func_type ()) == ARM_FT_NORMAL
9452                    && !IS_STACKALIGN (arm_current_func_type ())))
9453     <return_cond_false>"
9454   "
9455   {
9456     if (TARGET_THUMB2)
9457       {
9458         thumb2_expand_return (<return_simple_p>);
9459         DONE;
9460       }
9461   }
9462   "
9465 ;; Often the return insn will be the same as loading from memory, so set attr
9466 (define_insn "*arm_return"
9467   [(return)]
9468   "TARGET_ARM && USE_RETURN_INSN (FALSE)"
9469   "*
9470   {
9471     if (arm_ccfsm_state == 2)
9472       {
9473         arm_ccfsm_state += 2;
9474         return \"\";
9475       }
9476     return output_return_instruction (const_true_rtx, true, false, false);
9477   }"
9478   [(set_attr "type" "load1")
9479    (set_attr "length" "12")
9480    (set_attr "predicable" "yes")]
9483 (define_insn "*cond_<return_str>return"
9484   [(set (pc)
9485         (if_then_else (match_operator 0 "arm_comparison_operator"
9486                        [(match_operand 1 "cc_register" "") (const_int 0)])
9487                       (returns)
9488                       (pc)))]
9489   "TARGET_ARM  <return_cond_true>"
9490   "*
9491   {
9492     if (arm_ccfsm_state == 2)
9493       {
9494         arm_ccfsm_state += 2;
9495         return \"\";
9496       }
9497     return output_return_instruction (operands[0], true, false,
9498                                       <return_simple_p>);
9499   }"
9500   [(set_attr "conds" "use")
9501    (set_attr "length" "12")
9502    (set_attr "type" "load1")]
9505 (define_insn "*cond_<return_str>return_inverted"
9506   [(set (pc)
9507         (if_then_else (match_operator 0 "arm_comparison_operator"
9508                        [(match_operand 1 "cc_register" "") (const_int 0)])
9509                       (pc)
9510                       (returns)))]
9511   "TARGET_ARM <return_cond_true>"
9512   "*
9513   {
9514     if (arm_ccfsm_state == 2)
9515       {
9516         arm_ccfsm_state += 2;
9517         return \"\";
9518       }
9519     return output_return_instruction (operands[0], true, true,
9520                                       <return_simple_p>);
9521   }"
9522   [(set_attr "conds" "use")
9523    (set_attr "length" "12")
9524    (set_attr "type" "load1")]
9527 (define_insn "*arm_simple_return"
9528   [(simple_return)]
9529   "TARGET_ARM"
9530   "*
9531   {
9532     if (arm_ccfsm_state == 2)
9533       {
9534         arm_ccfsm_state += 2;
9535         return \"\";
9536       }
9537     return output_return_instruction (const_true_rtx, true, false, true);
9538   }"
9539   [(set_attr "type" "branch")
9540    (set_attr "length" "4")
9541    (set_attr "predicable" "yes")]
9544 ;; Generate a sequence of instructions to determine if the processor is
9545 ;; in 26-bit or 32-bit mode, and return the appropriate return address
9546 ;; mask.
9548 (define_expand "return_addr_mask"
9549   [(set (match_dup 1)
9550       (compare:CC_NOOV (unspec [(const_int 0)] UNSPEC_CHECK_ARCH)
9551                        (const_int 0)))
9552    (set (match_operand:SI 0 "s_register_operand" "")
9553       (if_then_else:SI (eq (match_dup 1) (const_int 0))
9554                        (const_int -1)
9555                        (const_int 67108860)))] ; 0x03fffffc
9556   "TARGET_ARM"
9557   "
9558   operands[1] = gen_rtx_REG (CC_NOOVmode, CC_REGNUM);
9559   ")
9561 (define_insn "*check_arch2"
9562   [(set (match_operand:CC_NOOV 0 "cc_register" "")
9563       (compare:CC_NOOV (unspec [(const_int 0)] UNSPEC_CHECK_ARCH)
9564                        (const_int 0)))]
9565   "TARGET_ARM"
9566   "teq\\t%|r0, %|r0\;teq\\t%|pc, %|pc"
9567   [(set_attr "length" "8")
9568    (set_attr "conds" "set")
9569    (set_attr "type" "multiple")]
9572 ;; Call subroutine returning any type.
9574 (define_expand "untyped_call"
9575   [(parallel [(call (match_operand 0 "" "")
9576                     (const_int 0))
9577               (match_operand 1 "" "")
9578               (match_operand 2 "" "")])]
9579   "TARGET_EITHER"
9580   "
9581   {
9582     int i;
9583     rtx par = gen_rtx_PARALLEL (VOIDmode,
9584                                 rtvec_alloc (XVECLEN (operands[2], 0)));
9585     rtx addr = gen_reg_rtx (Pmode);
9586     rtx mem;
9587     int size = 0;
9589     emit_move_insn (addr, XEXP (operands[1], 0));
9590     mem = change_address (operands[1], BLKmode, addr);
9592     for (i = 0; i < XVECLEN (operands[2], 0); i++)
9593       {
9594         rtx src = SET_SRC (XVECEXP (operands[2], 0, i));
9596         /* Default code only uses r0 as a return value, but we could
9597            be using anything up to 4 registers.  */
9598         if (REGNO (src) == R0_REGNUM)
9599           src = gen_rtx_REG (TImode, R0_REGNUM);
9601         XVECEXP (par, 0, i) = gen_rtx_EXPR_LIST (VOIDmode, src,
9602                                                  GEN_INT (size));
9603         size += GET_MODE_SIZE (GET_MODE (src));
9604       }
9606     emit_call_insn (GEN_CALL_VALUE (par, operands[0], const0_rtx, NULL,
9607                                     const0_rtx));
9609     size = 0;
9611     for (i = 0; i < XVECLEN (par, 0); i++)
9612       {
9613         HOST_WIDE_INT offset = 0;
9614         rtx reg = XEXP (XVECEXP (par, 0, i), 0);
9616         if (size != 0)
9617           emit_move_insn (addr, plus_constant (Pmode, addr, size));
9619         mem = change_address (mem, GET_MODE (reg), NULL);
9620         if (REGNO (reg) == R0_REGNUM)
9621           {
9622             /* On thumb we have to use a write-back instruction.  */
9623             emit_insn (arm_gen_store_multiple (arm_regs_in_sequence, 4, addr,
9624                        TARGET_THUMB ? TRUE : FALSE, mem, &offset));
9625             size = TARGET_ARM ? 16 : 0;
9626           }
9627         else
9628           {
9629             emit_move_insn (mem, reg);
9630             size = GET_MODE_SIZE (GET_MODE (reg));
9631           }
9632       }
9634     /* The optimizer does not know that the call sets the function value
9635        registers we stored in the result block.  We avoid problems by
9636        claiming that all hard registers are used and clobbered at this
9637        point.  */
9638     emit_insn (gen_blockage ());
9640     DONE;
9641   }"
9644 (define_expand "untyped_return"
9645   [(match_operand:BLK 0 "memory_operand" "")
9646    (match_operand 1 "" "")]
9647   "TARGET_EITHER"
9648   "
9649   {
9650     int i;
9651     rtx addr = gen_reg_rtx (Pmode);
9652     rtx mem;
9653     int size = 0;
9655     emit_move_insn (addr, XEXP (operands[0], 0));
9656     mem = change_address (operands[0], BLKmode, addr);
9658     for (i = 0; i < XVECLEN (operands[1], 0); i++)
9659       {
9660         HOST_WIDE_INT offset = 0;
9661         rtx reg = SET_DEST (XVECEXP (operands[1], 0, i));
9663         if (size != 0)
9664           emit_move_insn (addr, plus_constant (Pmode, addr, size));
9666         mem = change_address (mem, GET_MODE (reg), NULL);
9667         if (REGNO (reg) == R0_REGNUM)
9668           {
9669             /* On thumb we have to use a write-back instruction.  */
9670             emit_insn (arm_gen_load_multiple (arm_regs_in_sequence, 4, addr,
9671                        TARGET_THUMB ? TRUE : FALSE, mem, &offset));
9672             size = TARGET_ARM ? 16 : 0;
9673           }
9674         else
9675           {
9676             emit_move_insn (reg, mem);
9677             size = GET_MODE_SIZE (GET_MODE (reg));
9678           }
9679       }
9681     /* Emit USE insns before the return.  */
9682     for (i = 0; i < XVECLEN (operands[1], 0); i++)
9683       emit_use (SET_DEST (XVECEXP (operands[1], 0, i)));
9685     /* Construct the return.  */
9686     expand_naked_return ();
9688     DONE;
9689   }"
9692 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
9693 ;; all of memory.  This blocks insns from being moved across this point.
9695 (define_insn "blockage"
9696   [(unspec_volatile [(const_int 0)] VUNSPEC_BLOCKAGE)]
9697   "TARGET_EITHER"
9698   ""
9699   [(set_attr "length" "0")
9700    (set_attr "type" "block")]
9703 (define_expand "casesi"
9704   [(match_operand:SI 0 "s_register_operand" "") ; index to jump on
9705    (match_operand:SI 1 "const_int_operand" "")  ; lower bound
9706    (match_operand:SI 2 "const_int_operand" "")  ; total range
9707    (match_operand:SI 3 "" "")                   ; table label
9708    (match_operand:SI 4 "" "")]                  ; Out of range label
9709   "TARGET_32BIT || optimize_size || flag_pic"
9710   "
9711   {
9712     enum insn_code code;
9713     if (operands[1] != const0_rtx)
9714       {
9715         rtx reg = gen_reg_rtx (SImode);
9717         emit_insn (gen_addsi3 (reg, operands[0],
9718                                gen_int_mode (-INTVAL (operands[1]),
9719                                              SImode)));
9720         operands[0] = reg;
9721       }
9723     if (TARGET_ARM)
9724       code = CODE_FOR_arm_casesi_internal;
9725     else if (TARGET_THUMB1)
9726       code = CODE_FOR_thumb1_casesi_internal_pic;
9727     else if (flag_pic)
9728       code = CODE_FOR_thumb2_casesi_internal_pic;
9729     else
9730       code = CODE_FOR_thumb2_casesi_internal;
9732     if (!insn_data[(int) code].operand[1].predicate(operands[2], SImode))
9733       operands[2] = force_reg (SImode, operands[2]);
9735     emit_jump_insn (GEN_FCN ((int) code) (operands[0], operands[2],
9736                                           operands[3], operands[4]));
9737     DONE;
9738   }"
9741 ;; The USE in this pattern is needed to tell flow analysis that this is
9742 ;; a CASESI insn.  It has no other purpose.
9743 (define_insn "arm_casesi_internal"
9744   [(parallel [(set (pc)
9745                (if_then_else
9746                 (leu (match_operand:SI 0 "s_register_operand" "r")
9747                      (match_operand:SI 1 "arm_rhs_operand" "rI"))
9748                 (mem:SI (plus:SI (mult:SI (match_dup 0) (const_int 4))
9749                                  (label_ref (match_operand 2 "" ""))))
9750                 (label_ref (match_operand 3 "" ""))))
9751               (clobber (reg:CC CC_REGNUM))
9752               (use (label_ref (match_dup 2)))])]
9753   "TARGET_ARM"
9754   "*
9755     if (flag_pic)
9756       return \"cmp\\t%0, %1\;addls\\t%|pc, %|pc, %0, asl #2\;b\\t%l3\";
9757     return   \"cmp\\t%0, %1\;ldrls\\t%|pc, [%|pc, %0, asl #2]\;b\\t%l3\";
9758   "
9759   [(set_attr "conds" "clob")
9760    (set_attr "length" "12")
9761    (set_attr "type" "multiple")]
9764 (define_expand "thumb1_casesi_internal_pic"
9765   [(match_operand:SI 0 "s_register_operand" "")
9766    (match_operand:SI 1 "thumb1_cmp_operand" "")
9767    (match_operand 2 "" "")
9768    (match_operand 3 "" "")]
9769   "TARGET_THUMB1"
9770   {
9771     rtx reg0;
9772     rtx test = gen_rtx_GTU (VOIDmode, operands[0], operands[1]);
9773     emit_jump_insn (gen_cbranchsi4 (test, operands[0], operands[1],
9774                                     operands[3]));
9775     reg0 = gen_rtx_REG (SImode, 0);
9776     emit_move_insn (reg0, operands[0]);
9777     emit_jump_insn (gen_thumb1_casesi_dispatch (operands[2]/*, operands[3]*/));
9778     DONE;
9779   }
9782 (define_insn "thumb1_casesi_dispatch"
9783   [(parallel [(set (pc) (unspec [(reg:SI 0)
9784                                  (label_ref (match_operand 0 "" ""))
9785 ;;                               (label_ref (match_operand 1 "" ""))
9787                          UNSPEC_THUMB1_CASESI))
9788               (clobber (reg:SI IP_REGNUM))
9789               (clobber (reg:SI LR_REGNUM))])]
9790   "TARGET_THUMB1"
9791   "* return thumb1_output_casesi(operands);"
9792   [(set_attr "length" "4")
9793    (set_attr "type" "multiple")]
9796 (define_expand "indirect_jump"
9797   [(set (pc)
9798         (match_operand:SI 0 "s_register_operand" ""))]
9799   "TARGET_EITHER"
9800   "
9801   /* Thumb-2 doesn't have mov pc, reg.  Explicitly set the low bit of the
9802      address and use bx.  */
9803   if (TARGET_THUMB2)
9804     {
9805       rtx tmp;
9806       tmp = gen_reg_rtx (SImode);
9807       emit_insn (gen_iorsi3 (tmp, operands[0], GEN_INT(1)));
9808       operands[0] = tmp;
9809     }
9810   "
9813 ;; NB Never uses BX.
9814 (define_insn "*arm_indirect_jump"
9815   [(set (pc)
9816         (match_operand:SI 0 "s_register_operand" "r"))]
9817   "TARGET_ARM"
9818   "mov%?\\t%|pc, %0\\t%@ indirect register jump"
9819   [(set_attr "predicable" "yes")
9820    (set_attr "type" "branch")]
9823 (define_insn "*load_indirect_jump"
9824   [(set (pc)
9825         (match_operand:SI 0 "memory_operand" "m"))]
9826   "TARGET_ARM"
9827   "ldr%?\\t%|pc, %0\\t%@ indirect memory jump"
9828   [(set_attr "type" "load1")
9829    (set_attr "pool_range" "4096")
9830    (set_attr "neg_pool_range" "4084")
9831    (set_attr "predicable" "yes")]
9834 ;; NB Never uses BX.
9835 (define_insn "*thumb1_indirect_jump"
9836   [(set (pc)
9837         (match_operand:SI 0 "register_operand" "l*r"))]
9838   "TARGET_THUMB1"
9839   "mov\\tpc, %0"
9840   [(set_attr "conds" "clob")
9841    (set_attr "length" "2")
9842    (set_attr "type" "branch")]
9846 ;; Misc insns
9848 (define_insn "nop"
9849   [(const_int 0)]
9850   "TARGET_EITHER"
9851   "*
9852   if (TARGET_UNIFIED_ASM)
9853     return \"nop\";
9854   if (TARGET_ARM)
9855     return \"mov%?\\t%|r0, %|r0\\t%@ nop\";
9856   return  \"mov\\tr8, r8\";
9857   "
9858   [(set (attr "length")
9859         (if_then_else (eq_attr "is_thumb" "yes")
9860                       (const_int 2)
9861                       (const_int 4)))
9862    (set_attr "type" "mov_reg")]
9865 (define_insn "trap"
9866   [(trap_if (const_int 1) (const_int 0))]
9867   ""
9868   "*
9869   if (TARGET_ARM)
9870     return \".inst\\t0xe7f000f0\";
9871   else
9872     return \".inst\\t0xdeff\";
9873   "
9874   [(set (attr "length")
9875         (if_then_else (eq_attr "is_thumb" "yes")
9876                       (const_int 2)
9877                       (const_int 4)))
9878    (set_attr "type" "trap")
9879    (set_attr "conds" "unconditional")]
9883 ;; Patterns to allow combination of arithmetic, cond code and shifts
9885 (define_insn "*<arith_shift_insn>_multsi"
9886   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9887         (shiftable_ops:SI
9888          (mult:SI (match_operand:SI 2 "s_register_operand" "r,r")
9889                   (match_operand:SI 3 "power_of_two_operand" ""))
9890          (match_operand:SI 1 "s_register_operand" "rk,<t2_binop0>")))]
9891   "TARGET_32BIT"
9892   "<arith_shift_insn>%?\\t%0, %1, %2, lsl %b3"
9893   [(set_attr "predicable" "yes")
9894    (set_attr "predicable_short_it" "no")
9895    (set_attr "shift" "2")
9896    (set_attr "arch" "a,t2")
9897    (set_attr "type" "alu_shift_imm")])
9899 (define_insn "*<arith_shift_insn>_shiftsi"
9900   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9901         (shiftable_ops:SI
9902          (match_operator:SI 2 "shift_nomul_operator"
9903           [(match_operand:SI 3 "s_register_operand" "r,r,r")
9904            (match_operand:SI 4 "shift_amount_operand" "M,M,r")])
9905          (match_operand:SI 1 "s_register_operand" "rk,<t2_binop0>,rk")))]
9906   "TARGET_32BIT && GET_CODE (operands[2]) != MULT"
9907   "<arith_shift_insn>%?\\t%0, %1, %3%S2"
9908   [(set_attr "predicable" "yes")
9909    (set_attr "predicable_short_it" "no")
9910    (set_attr "shift" "3")
9911    (set_attr "arch" "a,t2,a")
9912    (set_attr "type" "alu_shift_imm,alu_shift_imm,alu_shift_reg")])
9914 (define_split
9915   [(set (match_operand:SI 0 "s_register_operand" "")
9916         (match_operator:SI 1 "shiftable_operator"
9917          [(match_operator:SI 2 "shiftable_operator"
9918            [(match_operator:SI 3 "shift_operator"
9919              [(match_operand:SI 4 "s_register_operand" "")
9920               (match_operand:SI 5 "reg_or_int_operand" "")])
9921             (match_operand:SI 6 "s_register_operand" "")])
9922           (match_operand:SI 7 "arm_rhs_operand" "")]))
9923    (clobber (match_operand:SI 8 "s_register_operand" ""))]
9924   "TARGET_32BIT"
9925   [(set (match_dup 8)
9926         (match_op_dup 2 [(match_op_dup 3 [(match_dup 4) (match_dup 5)])
9927                          (match_dup 6)]))
9928    (set (match_dup 0)
9929         (match_op_dup 1 [(match_dup 8) (match_dup 7)]))]
9930   "")
9932 (define_insn "*arith_shiftsi_compare0"
9933   [(set (reg:CC_NOOV CC_REGNUM)
9934         (compare:CC_NOOV
9935          (match_operator:SI 1 "shiftable_operator"
9936           [(match_operator:SI 3 "shift_operator"
9937             [(match_operand:SI 4 "s_register_operand" "r,r")
9938              (match_operand:SI 5 "shift_amount_operand" "M,r")])
9939            (match_operand:SI 2 "s_register_operand" "r,r")])
9940          (const_int 0)))
9941    (set (match_operand:SI 0 "s_register_operand" "=r,r")
9942         (match_op_dup 1 [(match_op_dup 3 [(match_dup 4) (match_dup 5)])
9943                          (match_dup 2)]))]
9944   "TARGET_32BIT"
9945   "%i1%.\\t%0, %2, %4%S3"
9946   [(set_attr "conds" "set")
9947    (set_attr "shift" "4")
9948    (set_attr "arch" "32,a")
9949    (set_attr "type" "alus_shift_imm,alus_shift_reg")])
9951 (define_insn "*arith_shiftsi_compare0_scratch"
9952   [(set (reg:CC_NOOV CC_REGNUM)
9953         (compare:CC_NOOV
9954          (match_operator:SI 1 "shiftable_operator"
9955           [(match_operator:SI 3 "shift_operator"
9956             [(match_operand:SI 4 "s_register_operand" "r,r")
9957              (match_operand:SI 5 "shift_amount_operand" "M,r")])
9958            (match_operand:SI 2 "s_register_operand" "r,r")])
9959          (const_int 0)))
9960    (clobber (match_scratch:SI 0 "=r,r"))]
9961   "TARGET_32BIT"
9962   "%i1%.\\t%0, %2, %4%S3"
9963   [(set_attr "conds" "set")
9964    (set_attr "shift" "4")
9965    (set_attr "arch" "32,a")
9966    (set_attr "type" "alus_shift_imm,alus_shift_reg")])
9968 (define_insn "*sub_shiftsi"
9969   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9970         (minus:SI (match_operand:SI 1 "s_register_operand" "r,r")
9971                   (match_operator:SI 2 "shift_operator"
9972                    [(match_operand:SI 3 "s_register_operand" "r,r")
9973                     (match_operand:SI 4 "shift_amount_operand" "M,r")])))]
9974   "TARGET_32BIT"
9975   "sub%?\\t%0, %1, %3%S2"
9976   [(set_attr "predicable" "yes")
9977    (set_attr "shift" "3")
9978    (set_attr "arch" "32,a")
9979    (set_attr "type" "alus_shift_imm,alus_shift_reg")])
9981 (define_insn "*sub_shiftsi_compare0"
9982   [(set (reg:CC_NOOV CC_REGNUM)
9983         (compare:CC_NOOV
9984          (minus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
9985                    (match_operator:SI 2 "shift_operator"
9986                     [(match_operand:SI 3 "s_register_operand" "r,r,r")
9987                      (match_operand:SI 4 "shift_amount_operand" "M,r,M")]))
9988          (const_int 0)))
9989    (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9990         (minus:SI (match_dup 1)
9991                   (match_op_dup 2 [(match_dup 3) (match_dup 4)])))]
9992   "TARGET_32BIT"
9993   "sub%.\\t%0, %1, %3%S2"
9994   [(set_attr "conds" "set")
9995    (set_attr "shift" "3")
9996    (set_attr "arch" "32,a,a")
9997    (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
9999 (define_insn "*sub_shiftsi_compare0_scratch"
10000   [(set (reg:CC_NOOV CC_REGNUM)
10001         (compare:CC_NOOV
10002          (minus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
10003                    (match_operator:SI 2 "shift_operator"
10004                     [(match_operand:SI 3 "s_register_operand" "r,r,r")
10005                      (match_operand:SI 4 "shift_amount_operand" "M,r,M")]))
10006          (const_int 0)))
10007    (clobber (match_scratch:SI 0 "=r,r,r"))]
10008   "TARGET_32BIT"
10009   "sub%.\\t%0, %1, %3%S2"
10010   [(set_attr "conds" "set")
10011    (set_attr "shift" "3")
10012    (set_attr "arch" "32,a,a")
10013    (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
10016 (define_insn_and_split "*and_scc"
10017   [(set (match_operand:SI 0 "s_register_operand" "=r")
10018         (and:SI (match_operator:SI 1 "arm_comparison_operator"
10019                  [(match_operand 2 "cc_register" "") (const_int 0)])
10020                 (match_operand:SI 3 "s_register_operand" "r")))]
10021   "TARGET_ARM"
10022   "#"   ; "mov%D1\\t%0, #0\;and%d1\\t%0, %3, #1"
10023   "&& reload_completed"
10024   [(cond_exec (match_dup 5) (set (match_dup 0) (const_int 0)))
10025    (cond_exec (match_dup 4) (set (match_dup 0)
10026                                  (and:SI (match_dup 3) (const_int 1))))]
10027   {
10028     enum machine_mode mode = GET_MODE (operands[2]);
10029     enum rtx_code rc = GET_CODE (operands[1]);
10031     /* Note that operands[4] is the same as operands[1],
10032        but with VOIDmode as the result. */
10033     operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
10034     if (mode == CCFPmode || mode == CCFPEmode)
10035       rc = reverse_condition_maybe_unordered (rc);
10036     else
10037       rc = reverse_condition (rc);
10038     operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
10039   }
10040   [(set_attr "conds" "use")
10041    (set_attr "type" "multiple")
10042    (set_attr "length" "8")]
10045 (define_insn_and_split "*ior_scc"
10046   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10047         (ior:SI (match_operator:SI 1 "arm_comparison_operator"
10048                  [(match_operand 2 "cc_register" "") (const_int 0)])
10049                 (match_operand:SI 3 "s_register_operand" "0,?r")))]
10050   "TARGET_ARM"
10051   "@
10052    orr%d1\\t%0, %3, #1
10053    #"
10054   "&& reload_completed
10055    && REGNO (operands [0]) != REGNO (operands[3])"
10056   ;; && which_alternative == 1
10057   ; mov%D1\\t%0, %3\;orr%d1\\t%0, %3, #1
10058   [(cond_exec (match_dup 5) (set (match_dup 0) (match_dup 3)))
10059    (cond_exec (match_dup 4) (set (match_dup 0)
10060                                  (ior:SI (match_dup 3) (const_int 1))))]
10061   {
10062     enum machine_mode mode = GET_MODE (operands[2]);
10063     enum rtx_code rc = GET_CODE (operands[1]);
10065     /* Note that operands[4] is the same as operands[1],
10066        but with VOIDmode as the result. */
10067     operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
10068     if (mode == CCFPmode || mode == CCFPEmode)
10069       rc = reverse_condition_maybe_unordered (rc);
10070     else
10071       rc = reverse_condition (rc);
10072     operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
10073   }
10074   [(set_attr "conds" "use")
10075    (set_attr "length" "4,8")
10076    (set_attr "type" "logic_imm,multiple")]
10079 ; A series of splitters for the compare_scc pattern below.  Note that
10080 ; order is important.
10081 (define_split
10082   [(set (match_operand:SI 0 "s_register_operand" "")
10083         (lt:SI (match_operand:SI 1 "s_register_operand" "")
10084                (const_int 0)))
10085    (clobber (reg:CC CC_REGNUM))]
10086   "TARGET_32BIT && reload_completed"
10087   [(set (match_dup 0) (lshiftrt:SI (match_dup 1) (const_int 31)))])
10089 (define_split
10090   [(set (match_operand:SI 0 "s_register_operand" "")
10091         (ge:SI (match_operand:SI 1 "s_register_operand" "")
10092                (const_int 0)))
10093    (clobber (reg:CC CC_REGNUM))]
10094   "TARGET_32BIT && reload_completed"
10095   [(set (match_dup 0) (not:SI (match_dup 1)))
10096    (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 31)))])
10098 (define_split
10099   [(set (match_operand:SI 0 "s_register_operand" "")
10100         (eq:SI (match_operand:SI 1 "s_register_operand" "")
10101                (const_int 0)))
10102    (clobber (reg:CC CC_REGNUM))]
10103   "arm_arch5 && TARGET_32BIT"
10104   [(set (match_dup 0) (clz:SI (match_dup 1)))
10105    (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
10108 (define_split
10109   [(set (match_operand:SI 0 "s_register_operand" "")
10110         (eq:SI (match_operand:SI 1 "s_register_operand" "")
10111                (const_int 0)))
10112    (clobber (reg:CC CC_REGNUM))]
10113   "TARGET_32BIT && reload_completed"
10114   [(parallel
10115     [(set (reg:CC CC_REGNUM)
10116           (compare:CC (const_int 1) (match_dup 1)))
10117      (set (match_dup 0)
10118           (minus:SI (const_int 1) (match_dup 1)))])
10119    (cond_exec (ltu:CC (reg:CC CC_REGNUM) (const_int 0))
10120               (set (match_dup 0) (const_int 0)))])
10122 (define_split
10123   [(set (match_operand:SI 0 "s_register_operand" "")
10124         (ne:SI (match_operand:SI 1 "s_register_operand" "")
10125                (match_operand:SI 2 "const_int_operand" "")))
10126    (clobber (reg:CC CC_REGNUM))]
10127   "TARGET_32BIT && reload_completed"
10128   [(parallel
10129     [(set (reg:CC CC_REGNUM)
10130           (compare:CC (match_dup 1) (match_dup 2)))
10131      (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 3)))])
10132    (cond_exec (ne:CC (reg:CC CC_REGNUM) (const_int 0))
10133               (set (match_dup 0) (const_int 1)))]
10135   operands[3] = GEN_INT (-INTVAL (operands[2]));
10138 (define_split
10139   [(set (match_operand:SI 0 "s_register_operand" "")
10140         (ne:SI (match_operand:SI 1 "s_register_operand" "")
10141                (match_operand:SI 2 "arm_add_operand" "")))
10142    (clobber (reg:CC CC_REGNUM))]
10143   "TARGET_32BIT && reload_completed"
10144   [(parallel
10145     [(set (reg:CC_NOOV CC_REGNUM)
10146           (compare:CC_NOOV (minus:SI (match_dup 1) (match_dup 2))
10147                            (const_int 0)))
10148      (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
10149    (cond_exec (ne:CC_NOOV (reg:CC_NOOV CC_REGNUM) (const_int 0))
10150               (set (match_dup 0) (const_int 1)))])
10152 (define_insn_and_split "*compare_scc"
10153   [(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts")
10154         (match_operator:SI 1 "arm_comparison_operator"
10155          [(match_operand:SI 2 "s_register_operand" "r,r")
10156           (match_operand:SI 3 "arm_add_operand" "rI,L")]))
10157    (clobber (reg:CC CC_REGNUM))]
10158   "TARGET_32BIT"
10159   "#"
10160   "&& reload_completed"
10161   [(set (reg:CC CC_REGNUM) (compare:CC (match_dup 2) (match_dup 3)))
10162    (cond_exec (match_dup 4) (set (match_dup 0) (const_int 0)))
10163    (cond_exec (match_dup 5) (set (match_dup 0) (const_int 1)))]
10165   rtx tmp1;
10166   enum machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10167                                            operands[2], operands[3]);
10168   enum rtx_code rc = GET_CODE (operands[1]);
10170   tmp1 = gen_rtx_REG (mode, CC_REGNUM);
10172   operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, tmp1, const0_rtx);
10173   if (mode == CCFPmode || mode == CCFPEmode)
10174     rc = reverse_condition_maybe_unordered (rc);
10175   else
10176     rc = reverse_condition (rc);
10177   operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, tmp1, const0_rtx);
10179   [(set_attr "type" "multiple")]
10182 ;; Attempt to improve the sequence generated by the compare_scc splitters
10183 ;; not to use conditional execution.
10185 ;; Rd = (eq (reg1) (const_int0))  // ARMv5
10186 ;;      clz Rd, reg1
10187 ;;      lsr Rd, Rd, #5
10188 (define_peephole2
10189   [(set (reg:CC CC_REGNUM)
10190         (compare:CC (match_operand:SI 1 "register_operand" "")
10191                     (const_int 0)))
10192    (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
10193               (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
10194    (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
10195               (set (match_dup 0) (const_int 1)))]
10196   "arm_arch5 && TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
10197   [(set (match_dup 0) (clz:SI (match_dup 1)))
10198    (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
10201 ;; Rd = (eq (reg1) (const_int0))  // !ARMv5
10202 ;;      negs Rd, reg1
10203 ;;      adc  Rd, Rd, reg1
10204 (define_peephole2
10205   [(set (reg:CC CC_REGNUM)
10206         (compare:CC (match_operand:SI 1 "register_operand" "")
10207                     (const_int 0)))
10208    (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
10209               (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
10210    (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
10211               (set (match_dup 0) (const_int 1)))
10212    (match_scratch:SI 2 "r")]
10213   "TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
10214   [(parallel
10215     [(set (reg:CC CC_REGNUM)
10216           (compare:CC (const_int 0) (match_dup 1)))
10217      (set (match_dup 2) (minus:SI (const_int 0) (match_dup 1)))])
10218    (set (match_dup 0)
10219         (plus:SI (plus:SI (match_dup 1) (match_dup 2))
10220                  (geu:SI (reg:CC CC_REGNUM) (const_int 0))))]
10223 ;; Rd = (eq (reg1) (reg2/imm))  // ARMv5 and optimising for speed.
10224 ;;      sub  Rd, Reg1, reg2
10225 ;;      clz  Rd, Rd
10226 ;;      lsr  Rd, Rd, #5
10227 (define_peephole2
10228   [(set (reg:CC CC_REGNUM)
10229         (compare:CC (match_operand:SI 1 "register_operand" "")
10230                     (match_operand:SI 2 "arm_rhs_operand" "")))
10231    (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
10232               (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
10233    (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
10234               (set (match_dup 0) (const_int 1)))]
10235   "arm_arch5 && TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)
10236   && !(TARGET_THUMB2 && optimize_insn_for_size_p ())"
10237   [(set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))
10238    (set (match_dup 0) (clz:SI (match_dup 0)))
10239    (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
10243 ;; Rd = (eq (reg1) (reg2))      // ! ARMv5 or optimising for size.
10244 ;;      sub  T1, Reg1, reg2
10245 ;;      negs Rd, T1
10246 ;;      adc  Rd, Rd, T1
10247 (define_peephole2
10248   [(set (reg:CC CC_REGNUM)
10249         (compare:CC (match_operand:SI 1 "register_operand" "")
10250                     (match_operand:SI 2 "arm_rhs_operand" "")))
10251    (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
10252               (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
10253    (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
10254               (set (match_dup 0) (const_int 1)))
10255    (match_scratch:SI 3 "r")]
10256   "TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
10257   [(set (match_dup 3) (match_dup 4))
10258    (parallel
10259     [(set (reg:CC CC_REGNUM)
10260           (compare:CC (const_int 0) (match_dup 3)))
10261      (set (match_dup 0) (minus:SI (const_int 0) (match_dup 3)))])
10262    (set (match_dup 0)
10263         (plus:SI (plus:SI (match_dup 0) (match_dup 3))
10264                  (geu:SI (reg:CC CC_REGNUM) (const_int 0))))]
10265   "
10266   if (CONST_INT_P (operands[2]))
10267     operands[4] = plus_constant (SImode, operands[1], -INTVAL (operands[2]));
10268   else
10269     operands[4] = gen_rtx_MINUS (SImode, operands[1], operands[2]);
10270   ")
10272 (define_insn "*cond_move"
10273   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
10274         (if_then_else:SI (match_operator 3 "equality_operator"
10275                           [(match_operator 4 "arm_comparison_operator"
10276                             [(match_operand 5 "cc_register" "") (const_int 0)])
10277                            (const_int 0)])
10278                          (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
10279                          (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))]
10280   "TARGET_ARM"
10281   "*
10282     if (GET_CODE (operands[3]) == NE)
10283       {
10284         if (which_alternative != 1)
10285           output_asm_insn (\"mov%D4\\t%0, %2\", operands);
10286         if (which_alternative != 0)
10287           output_asm_insn (\"mov%d4\\t%0, %1\", operands);
10288         return \"\";
10289       }
10290     if (which_alternative != 0)
10291       output_asm_insn (\"mov%D4\\t%0, %1\", operands);
10292     if (which_alternative != 1)
10293       output_asm_insn (\"mov%d4\\t%0, %2\", operands);
10294     return \"\";
10295   "
10296   [(set_attr "conds" "use")
10297    (set_attr "type" "mov_reg,mov_reg,multiple")
10298    (set_attr "length" "4,4,8")]
10301 (define_insn "*cond_arith"
10302   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10303         (match_operator:SI 5 "shiftable_operator" 
10304          [(match_operator:SI 4 "arm_comparison_operator"
10305            [(match_operand:SI 2 "s_register_operand" "r,r")
10306             (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
10307           (match_operand:SI 1 "s_register_operand" "0,?r")]))
10308    (clobber (reg:CC CC_REGNUM))]
10309   "TARGET_ARM"
10310   "*
10311     if (GET_CODE (operands[4]) == LT && operands[3] == const0_rtx)
10312       return \"%i5\\t%0, %1, %2, lsr #31\";
10314     output_asm_insn (\"cmp\\t%2, %3\", operands);
10315     if (GET_CODE (operands[5]) == AND)
10316       output_asm_insn (\"mov%D4\\t%0, #0\", operands);
10317     else if (GET_CODE (operands[5]) == MINUS)
10318       output_asm_insn (\"rsb%D4\\t%0, %1, #0\", operands);
10319     else if (which_alternative != 0)
10320       output_asm_insn (\"mov%D4\\t%0, %1\", operands);
10321     return \"%i5%d4\\t%0, %1, #1\";
10322   "
10323   [(set_attr "conds" "clob")
10324    (set_attr "length" "12")
10325    (set_attr "type" "multiple")]
10328 (define_insn "*cond_sub"
10329   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10330         (minus:SI (match_operand:SI 1 "s_register_operand" "0,?r")
10331                   (match_operator:SI 4 "arm_comparison_operator"
10332                    [(match_operand:SI 2 "s_register_operand" "r,r")
10333                     (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
10334    (clobber (reg:CC CC_REGNUM))]
10335   "TARGET_ARM"
10336   "*
10337     output_asm_insn (\"cmp\\t%2, %3\", operands);
10338     if (which_alternative != 0)
10339       output_asm_insn (\"mov%D4\\t%0, %1\", operands);
10340     return \"sub%d4\\t%0, %1, #1\";
10341   "
10342   [(set_attr "conds" "clob")
10343    (set_attr "length" "8,12")
10344    (set_attr "type" "multiple")]
10347 (define_insn "*cmp_ite0"
10348   [(set (match_operand 6 "dominant_cc_register" "")
10349         (compare
10350          (if_then_else:SI
10351           (match_operator 4 "arm_comparison_operator"
10352            [(match_operand:SI 0 "s_register_operand"
10353                 "l,l,l,r,r,r,r,r,r")
10354             (match_operand:SI 1 "arm_add_operand"
10355                 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
10356           (match_operator:SI 5 "arm_comparison_operator"
10357            [(match_operand:SI 2 "s_register_operand"
10358                 "l,r,r,l,l,r,r,r,r")
10359             (match_operand:SI 3 "arm_add_operand"
10360                 "lPy,rI,L,lPy,lPy,rI,rI,L,L")])
10361           (const_int 0))
10362          (const_int 0)))]
10363   "TARGET_32BIT"
10364   "*
10365   {
10366     static const char * const cmp1[NUM_OF_COND_CMP][2] =
10367     {
10368       {\"cmp%d5\\t%0, %1\",
10369        \"cmp%d4\\t%2, %3\"},
10370       {\"cmn%d5\\t%0, #%n1\",
10371        \"cmp%d4\\t%2, %3\"},
10372       {\"cmp%d5\\t%0, %1\",
10373        \"cmn%d4\\t%2, #%n3\"},
10374       {\"cmn%d5\\t%0, #%n1\",
10375        \"cmn%d4\\t%2, #%n3\"}
10376     };
10377     static const char * const cmp2[NUM_OF_COND_CMP][2] =
10378     {
10379       {\"cmp\\t%2, %3\",
10380        \"cmp\\t%0, %1\"},
10381       {\"cmp\\t%2, %3\",
10382        \"cmn\\t%0, #%n1\"},
10383       {\"cmn\\t%2, #%n3\",
10384        \"cmp\\t%0, %1\"},
10385       {\"cmn\\t%2, #%n3\",
10386        \"cmn\\t%0, #%n1\"}
10387     };
10388     static const char * const ite[2] =
10389     {
10390       \"it\\t%d5\",
10391       \"it\\t%d4\"
10392     };
10393     static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
10394                                    CMP_CMP, CMN_CMP, CMP_CMP,
10395                                    CMN_CMP, CMP_CMN, CMN_CMN};
10396     int swap =
10397       comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
10399     output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
10400     if (TARGET_THUMB2) {
10401       output_asm_insn (ite[swap], operands);
10402     }
10403     output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
10404     return \"\";
10405   }"
10406   [(set_attr "conds" "set")
10407    (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
10408    (set_attr "type" "multiple")
10409    (set_attr_alternative "length"
10410       [(const_int 6)
10411        (const_int 8)
10412        (const_int 8)
10413        (const_int 8)
10414        (const_int 8)
10415        (if_then_else (eq_attr "is_thumb" "no")
10416            (const_int 8)
10417            (const_int 10))
10418        (if_then_else (eq_attr "is_thumb" "no")
10419            (const_int 8)
10420            (const_int 10))
10421        (if_then_else (eq_attr "is_thumb" "no")
10422            (const_int 8)
10423            (const_int 10))
10424        (if_then_else (eq_attr "is_thumb" "no")
10425            (const_int 8)
10426            (const_int 10))])]
10429 (define_insn "*cmp_ite1"
10430   [(set (match_operand 6 "dominant_cc_register" "")
10431         (compare
10432          (if_then_else:SI
10433           (match_operator 4 "arm_comparison_operator"
10434            [(match_operand:SI 0 "s_register_operand"
10435                 "l,l,l,r,r,r,r,r,r")
10436             (match_operand:SI 1 "arm_add_operand"
10437                 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
10438           (match_operator:SI 5 "arm_comparison_operator"
10439            [(match_operand:SI 2 "s_register_operand"
10440                 "l,r,r,l,l,r,r,r,r")
10441             (match_operand:SI 3 "arm_add_operand"
10442                 "lPy,rI,L,lPy,lPy,rI,rI,L,L")])
10443           (const_int 1))
10444          (const_int 0)))]
10445   "TARGET_32BIT"
10446   "*
10447   {
10448     static const char * const cmp1[NUM_OF_COND_CMP][2] =
10449     {
10450       {\"cmp\\t%0, %1\",
10451        \"cmp\\t%2, %3\"},
10452       {\"cmn\\t%0, #%n1\",
10453        \"cmp\\t%2, %3\"},
10454       {\"cmp\\t%0, %1\",
10455        \"cmn\\t%2, #%n3\"},
10456       {\"cmn\\t%0, #%n1\",
10457        \"cmn\\t%2, #%n3\"}
10458     };
10459     static const char * const cmp2[NUM_OF_COND_CMP][2] =
10460     {
10461       {\"cmp%d4\\t%2, %3\",
10462        \"cmp%D5\\t%0, %1\"},
10463       {\"cmp%d4\\t%2, %3\",
10464        \"cmn%D5\\t%0, #%n1\"},
10465       {\"cmn%d4\\t%2, #%n3\",
10466        \"cmp%D5\\t%0, %1\"},
10467       {\"cmn%d4\\t%2, #%n3\",
10468        \"cmn%D5\\t%0, #%n1\"}
10469     };
10470     static const char * const ite[2] =
10471     {
10472       \"it\\t%d4\",
10473       \"it\\t%D5\"
10474     };
10475     static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
10476                                    CMP_CMP, CMN_CMP, CMP_CMP,
10477                                    CMN_CMP, CMP_CMN, CMN_CMN};
10478     int swap =
10479       comparison_dominates_p (GET_CODE (operands[5]),
10480                               reverse_condition (GET_CODE (operands[4])));
10482     output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
10483     if (TARGET_THUMB2) {
10484       output_asm_insn (ite[swap], operands);
10485     }
10486     output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
10487     return \"\";
10488   }"
10489   [(set_attr "conds" "set")
10490    (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
10491    (set_attr_alternative "length"
10492       [(const_int 6)
10493        (const_int 8)
10494        (const_int 8)
10495        (const_int 8)
10496        (const_int 8)
10497        (if_then_else (eq_attr "is_thumb" "no")
10498            (const_int 8)
10499            (const_int 10))
10500        (if_then_else (eq_attr "is_thumb" "no")
10501            (const_int 8)
10502            (const_int 10))
10503        (if_then_else (eq_attr "is_thumb" "no")
10504            (const_int 8)
10505            (const_int 10))
10506        (if_then_else (eq_attr "is_thumb" "no")
10507            (const_int 8)
10508            (const_int 10))])
10509    (set_attr "type" "multiple")]
10512 (define_insn "*cmp_and"
10513   [(set (match_operand 6 "dominant_cc_register" "")
10514         (compare
10515          (and:SI
10516           (match_operator 4 "arm_comparison_operator"
10517            [(match_operand:SI 0 "s_register_operand" 
10518                 "l,l,l,r,r,r,r,r,r")
10519             (match_operand:SI 1 "arm_add_operand" 
10520                 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
10521           (match_operator:SI 5 "arm_comparison_operator"
10522            [(match_operand:SI 2 "s_register_operand" 
10523                 "l,r,r,l,l,r,r,r,r")
10524             (match_operand:SI 3 "arm_add_operand" 
10525                 "lPy,rI,L,lPy,lPy,rI,rI,L,L")]))
10526          (const_int 0)))]
10527   "TARGET_32BIT"
10528   "*
10529   {
10530     static const char *const cmp1[NUM_OF_COND_CMP][2] =
10531     {
10532       {\"cmp%d5\\t%0, %1\",
10533        \"cmp%d4\\t%2, %3\"},
10534       {\"cmn%d5\\t%0, #%n1\",
10535        \"cmp%d4\\t%2, %3\"},
10536       {\"cmp%d5\\t%0, %1\",
10537        \"cmn%d4\\t%2, #%n3\"},
10538       {\"cmn%d5\\t%0, #%n1\",
10539        \"cmn%d4\\t%2, #%n3\"}
10540     };
10541     static const char *const cmp2[NUM_OF_COND_CMP][2] =
10542     {
10543       {\"cmp\\t%2, %3\",
10544        \"cmp\\t%0, %1\"},
10545       {\"cmp\\t%2, %3\",
10546        \"cmn\\t%0, #%n1\"},
10547       {\"cmn\\t%2, #%n3\",
10548        \"cmp\\t%0, %1\"},
10549       {\"cmn\\t%2, #%n3\",
10550        \"cmn\\t%0, #%n1\"}
10551     };
10552     static const char *const ite[2] =
10553     {
10554       \"it\\t%d5\",
10555       \"it\\t%d4\"
10556     };
10557     static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
10558                                    CMP_CMP, CMN_CMP, CMP_CMP,
10559                                    CMN_CMP, CMP_CMN, CMN_CMN};
10560     int swap =
10561       comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
10563     output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
10564     if (TARGET_THUMB2) {
10565       output_asm_insn (ite[swap], operands);
10566     }
10567     output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
10568     return \"\";
10569   }"
10570   [(set_attr "conds" "set")
10571    (set_attr "predicable" "no")
10572    (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
10573    (set_attr_alternative "length"
10574       [(const_int 6)
10575        (const_int 8)
10576        (const_int 8)
10577        (const_int 8)
10578        (const_int 8)
10579        (if_then_else (eq_attr "is_thumb" "no")
10580            (const_int 8)
10581            (const_int 10))
10582        (if_then_else (eq_attr "is_thumb" "no")
10583            (const_int 8)
10584            (const_int 10))
10585        (if_then_else (eq_attr "is_thumb" "no")
10586            (const_int 8)
10587            (const_int 10))
10588        (if_then_else (eq_attr "is_thumb" "no")
10589            (const_int 8)
10590            (const_int 10))])
10591    (set_attr "type" "multiple")]
10594 (define_insn "*cmp_ior"
10595   [(set (match_operand 6 "dominant_cc_register" "")
10596         (compare
10597          (ior:SI
10598           (match_operator 4 "arm_comparison_operator"
10599            [(match_operand:SI 0 "s_register_operand"
10600                 "l,l,l,r,r,r,r,r,r")
10601             (match_operand:SI 1 "arm_add_operand"
10602                 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
10603           (match_operator:SI 5 "arm_comparison_operator"
10604            [(match_operand:SI 2 "s_register_operand"
10605                 "l,r,r,l,l,r,r,r,r")
10606             (match_operand:SI 3 "arm_add_operand"
10607                 "lPy,rI,L,lPy,lPy,rI,rI,L,L")]))
10608          (const_int 0)))]
10609   "TARGET_32BIT"
10610   "*
10611   {
10612     static const char *const cmp1[NUM_OF_COND_CMP][2] =
10613     {
10614       {\"cmp\\t%0, %1\",
10615        \"cmp\\t%2, %3\"},
10616       {\"cmn\\t%0, #%n1\",
10617        \"cmp\\t%2, %3\"},
10618       {\"cmp\\t%0, %1\",
10619        \"cmn\\t%2, #%n3\"},
10620       {\"cmn\\t%0, #%n1\",
10621        \"cmn\\t%2, #%n3\"}
10622     };
10623     static const char *const cmp2[NUM_OF_COND_CMP][2] =
10624     {
10625       {\"cmp%D4\\t%2, %3\",
10626        \"cmp%D5\\t%0, %1\"},
10627       {\"cmp%D4\\t%2, %3\",
10628        \"cmn%D5\\t%0, #%n1\"},
10629       {\"cmn%D4\\t%2, #%n3\",
10630        \"cmp%D5\\t%0, %1\"},
10631       {\"cmn%D4\\t%2, #%n3\",
10632        \"cmn%D5\\t%0, #%n1\"}
10633     };
10634     static const char *const ite[2] =
10635     {
10636       \"it\\t%D4\",
10637       \"it\\t%D5\"
10638     };
10639     static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
10640                                    CMP_CMP, CMN_CMP, CMP_CMP,
10641                                    CMN_CMP, CMP_CMN, CMN_CMN};
10642     int swap =
10643       comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
10645     output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
10646     if (TARGET_THUMB2) {
10647       output_asm_insn (ite[swap], operands);
10648     }
10649     output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
10650     return \"\";
10651   }
10652   "
10653   [(set_attr "conds" "set")
10654    (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
10655    (set_attr_alternative "length"
10656       [(const_int 6)
10657        (const_int 8)
10658        (const_int 8)
10659        (const_int 8)
10660        (const_int 8)
10661        (if_then_else (eq_attr "is_thumb" "no")
10662            (const_int 8)
10663            (const_int 10))
10664        (if_then_else (eq_attr "is_thumb" "no")
10665            (const_int 8)
10666            (const_int 10))
10667        (if_then_else (eq_attr "is_thumb" "no")
10668            (const_int 8)
10669            (const_int 10))
10670        (if_then_else (eq_attr "is_thumb" "no")
10671            (const_int 8)
10672            (const_int 10))])
10673    (set_attr "type" "multiple")]
10676 (define_insn_and_split "*ior_scc_scc"
10677   [(set (match_operand:SI 0 "s_register_operand" "=Ts")
10678         (ior:SI (match_operator:SI 3 "arm_comparison_operator"
10679                  [(match_operand:SI 1 "s_register_operand" "r")
10680                   (match_operand:SI 2 "arm_add_operand" "rIL")])
10681                 (match_operator:SI 6 "arm_comparison_operator"
10682                  [(match_operand:SI 4 "s_register_operand" "r")
10683                   (match_operand:SI 5 "arm_add_operand" "rIL")])))
10684    (clobber (reg:CC CC_REGNUM))]
10685   "TARGET_32BIT
10686    && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_OR_Y)
10687        != CCmode)"
10688   "#"
10689   "TARGET_32BIT && reload_completed"
10690   [(set (match_dup 7)
10691         (compare
10692          (ior:SI
10693           (match_op_dup 3 [(match_dup 1) (match_dup 2)])
10694           (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
10695          (const_int 0)))
10696    (set (match_dup 0) (ne:SI (match_dup 7) (const_int 0)))]
10697   "operands[7]
10698      = gen_rtx_REG (arm_select_dominance_cc_mode (operands[3], operands[6],
10699                                                   DOM_CC_X_OR_Y),
10700                     CC_REGNUM);"
10701   [(set_attr "conds" "clob")
10702    (set_attr "length" "16")
10703    (set_attr "type" "multiple")]
10706 ; If the above pattern is followed by a CMP insn, then the compare is 
10707 ; redundant, since we can rework the conditional instruction that follows.
10708 (define_insn_and_split "*ior_scc_scc_cmp"
10709   [(set (match_operand 0 "dominant_cc_register" "")
10710         (compare (ior:SI (match_operator:SI 3 "arm_comparison_operator"
10711                           [(match_operand:SI 1 "s_register_operand" "r")
10712                            (match_operand:SI 2 "arm_add_operand" "rIL")])
10713                          (match_operator:SI 6 "arm_comparison_operator"
10714                           [(match_operand:SI 4 "s_register_operand" "r")
10715                            (match_operand:SI 5 "arm_add_operand" "rIL")]))
10716                  (const_int 0)))
10717    (set (match_operand:SI 7 "s_register_operand" "=Ts")
10718         (ior:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])
10719                 (match_op_dup 6 [(match_dup 4) (match_dup 5)])))]
10720   "TARGET_32BIT"
10721   "#"
10722   "TARGET_32BIT && reload_completed"
10723   [(set (match_dup 0)
10724         (compare
10725          (ior:SI
10726           (match_op_dup 3 [(match_dup 1) (match_dup 2)])
10727           (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
10728          (const_int 0)))
10729    (set (match_dup 7) (ne:SI (match_dup 0) (const_int 0)))]
10730   ""
10731   [(set_attr "conds" "set")
10732    (set_attr "length" "16")
10733    (set_attr "type" "multiple")]
10736 (define_insn_and_split "*and_scc_scc"
10737   [(set (match_operand:SI 0 "s_register_operand" "=Ts")
10738         (and:SI (match_operator:SI 3 "arm_comparison_operator"
10739                  [(match_operand:SI 1 "s_register_operand" "r")
10740                   (match_operand:SI 2 "arm_add_operand" "rIL")])
10741                 (match_operator:SI 6 "arm_comparison_operator"
10742                  [(match_operand:SI 4 "s_register_operand" "r")
10743                   (match_operand:SI 5 "arm_add_operand" "rIL")])))
10744    (clobber (reg:CC CC_REGNUM))]
10745   "TARGET_32BIT
10746    && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
10747        != CCmode)"
10748   "#"
10749   "TARGET_32BIT && reload_completed
10750    && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
10751        != CCmode)"
10752   [(set (match_dup 7)
10753         (compare
10754          (and:SI
10755           (match_op_dup 3 [(match_dup 1) (match_dup 2)])
10756           (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
10757          (const_int 0)))
10758    (set (match_dup 0) (ne:SI (match_dup 7) (const_int 0)))]
10759   "operands[7]
10760      = gen_rtx_REG (arm_select_dominance_cc_mode (operands[3], operands[6],
10761                                                   DOM_CC_X_AND_Y),
10762                     CC_REGNUM);"
10763   [(set_attr "conds" "clob")
10764    (set_attr "length" "16")
10765    (set_attr "type" "multiple")]
10768 ; If the above pattern is followed by a CMP insn, then the compare is 
10769 ; redundant, since we can rework the conditional instruction that follows.
10770 (define_insn_and_split "*and_scc_scc_cmp"
10771   [(set (match_operand 0 "dominant_cc_register" "")
10772         (compare (and:SI (match_operator:SI 3 "arm_comparison_operator"
10773                           [(match_operand:SI 1 "s_register_operand" "r")
10774                            (match_operand:SI 2 "arm_add_operand" "rIL")])
10775                          (match_operator:SI 6 "arm_comparison_operator"
10776                           [(match_operand:SI 4 "s_register_operand" "r")
10777                            (match_operand:SI 5 "arm_add_operand" "rIL")]))
10778                  (const_int 0)))
10779    (set (match_operand:SI 7 "s_register_operand" "=Ts")
10780         (and:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])
10781                 (match_op_dup 6 [(match_dup 4) (match_dup 5)])))]
10782   "TARGET_32BIT"
10783   "#"
10784   "TARGET_32BIT && reload_completed"
10785   [(set (match_dup 0)
10786         (compare
10787          (and:SI
10788           (match_op_dup 3 [(match_dup 1) (match_dup 2)])
10789           (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
10790          (const_int 0)))
10791    (set (match_dup 7) (ne:SI (match_dup 0) (const_int 0)))]
10792   ""
10793   [(set_attr "conds" "set")
10794    (set_attr "length" "16")
10795    (set_attr "type" "multiple")]
10798 ;; If there is no dominance in the comparison, then we can still save an
10799 ;; instruction in the AND case, since we can know that the second compare
10800 ;; need only zero the value if false (if true, then the value is already
10801 ;; correct).
10802 (define_insn_and_split "*and_scc_scc_nodom"
10803   [(set (match_operand:SI 0 "s_register_operand" "=&Ts,&Ts,&Ts")
10804         (and:SI (match_operator:SI 3 "arm_comparison_operator"
10805                  [(match_operand:SI 1 "s_register_operand" "r,r,0")
10806                   (match_operand:SI 2 "arm_add_operand" "rIL,0,rIL")])
10807                 (match_operator:SI 6 "arm_comparison_operator"
10808                  [(match_operand:SI 4 "s_register_operand" "r,r,r")
10809                   (match_operand:SI 5 "arm_add_operand" "rIL,rIL,rIL")])))
10810    (clobber (reg:CC CC_REGNUM))]
10811   "TARGET_32BIT
10812    && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
10813        == CCmode)"
10814   "#"
10815   "TARGET_32BIT && reload_completed"
10816   [(parallel [(set (match_dup 0)
10817                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
10818               (clobber (reg:CC CC_REGNUM))])
10819    (set (match_dup 7) (match_op_dup 8 [(match_dup 4) (match_dup 5)]))
10820    (set (match_dup 0)
10821         (if_then_else:SI (match_op_dup 6 [(match_dup 7) (const_int 0)])
10822                          (match_dup 0)
10823                          (const_int 0)))]
10824   "operands[7] = gen_rtx_REG (SELECT_CC_MODE (GET_CODE (operands[6]),
10825                                               operands[4], operands[5]),
10826                               CC_REGNUM);
10827    operands[8] = gen_rtx_COMPARE (GET_MODE (operands[7]), operands[4],
10828                                   operands[5]);"
10829   [(set_attr "conds" "clob")
10830    (set_attr "length" "20")
10831    (set_attr "type" "multiple")]
10834 (define_split
10835   [(set (reg:CC_NOOV CC_REGNUM)
10836         (compare:CC_NOOV (ior:SI
10837                           (and:SI (match_operand:SI 0 "s_register_operand" "")
10838                                   (const_int 1))
10839                           (match_operator:SI 1 "arm_comparison_operator"
10840                            [(match_operand:SI 2 "s_register_operand" "")
10841                             (match_operand:SI 3 "arm_add_operand" "")]))
10842                          (const_int 0)))
10843    (clobber (match_operand:SI 4 "s_register_operand" ""))]
10844   "TARGET_ARM"
10845   [(set (match_dup 4)
10846         (ior:SI (match_op_dup 1 [(match_dup 2) (match_dup 3)])
10847                 (match_dup 0)))
10848    (set (reg:CC_NOOV CC_REGNUM)
10849         (compare:CC_NOOV (and:SI (match_dup 4) (const_int 1))
10850                          (const_int 0)))]
10851   "")
10853 (define_split
10854   [(set (reg:CC_NOOV CC_REGNUM)
10855         (compare:CC_NOOV (ior:SI
10856                           (match_operator:SI 1 "arm_comparison_operator"
10857                            [(match_operand:SI 2 "s_register_operand" "")
10858                             (match_operand:SI 3 "arm_add_operand" "")])
10859                           (and:SI (match_operand:SI 0 "s_register_operand" "")
10860                                   (const_int 1)))
10861                          (const_int 0)))
10862    (clobber (match_operand:SI 4 "s_register_operand" ""))]
10863   "TARGET_ARM"
10864   [(set (match_dup 4)
10865         (ior:SI (match_op_dup 1 [(match_dup 2) (match_dup 3)])
10866                 (match_dup 0)))
10867    (set (reg:CC_NOOV CC_REGNUM)
10868         (compare:CC_NOOV (and:SI (match_dup 4) (const_int 1))
10869                          (const_int 0)))]
10870   "")
10871 ;; ??? The conditional patterns above need checking for Thumb-2 usefulness
10873 (define_insn_and_split "*negscc"
10874   [(set (match_operand:SI 0 "s_register_operand" "=r")
10875         (neg:SI (match_operator 3 "arm_comparison_operator"
10876                  [(match_operand:SI 1 "s_register_operand" "r")
10877                   (match_operand:SI 2 "arm_rhs_operand" "rI")])))
10878    (clobber (reg:CC CC_REGNUM))]
10879   "TARGET_ARM"
10880   "#"
10881   "&& reload_completed"
10882   [(const_int 0)]
10883   {
10884     rtx cc_reg = gen_rtx_REG (CCmode, CC_REGNUM);
10886     if (GET_CODE (operands[3]) == LT && operands[2] == const0_rtx)
10887        {
10888          /* Emit mov\\t%0, %1, asr #31 */
10889          emit_insn (gen_rtx_SET (VOIDmode,
10890                                  operands[0],
10891                                  gen_rtx_ASHIFTRT (SImode,
10892                                                    operands[1],
10893                                                    GEN_INT (31))));
10894          DONE;
10895        }
10896      else if (GET_CODE (operands[3]) == NE)
10897        {
10898         /* Emit subs\\t%0, %1, %2\;mvnne\\t%0, #0 */
10899         if (CONST_INT_P (operands[2]))
10900           emit_insn (gen_cmpsi2_addneg (operands[0], operands[1], operands[2],
10901                                         GEN_INT (- INTVAL (operands[2]))));
10902         else
10903           emit_insn (gen_subsi3_compare (operands[0], operands[1], operands[2]));
10905         emit_insn (gen_rtx_COND_EXEC (VOIDmode,
10906                                       gen_rtx_NE (SImode,
10907                                                   cc_reg,
10908                                                   const0_rtx),
10909                                       gen_rtx_SET (SImode,
10910                                                    operands[0],
10911                                                    GEN_INT (~0))));
10912         DONE;
10913       }
10914     else
10915       {
10916         /* Emit: cmp\\t%1, %2\;mov%D3\\t%0, #0\;mvn%d3\\t%0, #0 */
10917         emit_insn (gen_rtx_SET (VOIDmode,
10918                                 cc_reg,
10919                                 gen_rtx_COMPARE (CCmode, operands[1], operands[2])));
10920         enum rtx_code rc = GET_CODE (operands[3]);
10922         rc = reverse_condition (rc);
10923         emit_insn (gen_rtx_COND_EXEC (VOIDmode,
10924                                       gen_rtx_fmt_ee (rc,
10925                                                       VOIDmode,
10926                                                       cc_reg,
10927                                                       const0_rtx),
10928                                       gen_rtx_SET (VOIDmode, operands[0], const0_rtx)));
10929         rc = GET_CODE (operands[3]);
10930         emit_insn (gen_rtx_COND_EXEC (VOIDmode,
10931                                       gen_rtx_fmt_ee (rc,
10932                                                       VOIDmode,
10933                                                       cc_reg,
10934                                                       const0_rtx),
10935                                       gen_rtx_SET (VOIDmode,
10936                                                    operands[0],
10937                                                    GEN_INT (~0))));
10938         DONE;
10939       }
10940      FAIL;
10941   }
10942   [(set_attr "conds" "clob")
10943    (set_attr "length" "12")
10944    (set_attr "type" "multiple")]
10947 (define_insn_and_split "movcond_addsi"
10948   [(set (match_operand:SI 0 "s_register_operand" "=r,l,r")
10949         (if_then_else:SI
10950          (match_operator 5 "comparison_operator"
10951           [(plus:SI (match_operand:SI 3 "s_register_operand" "r,r,r")
10952                     (match_operand:SI 4 "arm_add_operand" "rIL,rIL,rIL"))
10953             (const_int 0)])
10954          (match_operand:SI 1 "arm_rhs_operand" "rI,rPy,r")
10955          (match_operand:SI 2 "arm_rhs_operand" "rI,rPy,r")))
10956    (clobber (reg:CC CC_REGNUM))]
10957    "TARGET_32BIT"
10958    "#"
10959    "&& reload_completed"
10960   [(set (reg:CC_NOOV CC_REGNUM)
10961         (compare:CC_NOOV
10962          (plus:SI (match_dup 3)
10963                   (match_dup 4))
10964          (const_int 0)))
10965    (set (match_dup 0) (match_dup 1))
10966    (cond_exec (match_dup 6)
10967               (set (match_dup 0) (match_dup 2)))]
10968   "
10969   {
10970     enum machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[5]),
10971                                              operands[3], operands[4]);
10972     enum rtx_code rc = GET_CODE (operands[5]);
10973     operands[6] = gen_rtx_REG (mode, CC_REGNUM);
10974     gcc_assert (!(mode == CCFPmode || mode == CCFPEmode));
10975     if (!REG_P (operands[2]) || REGNO (operands[2]) != REGNO (operands[0]))
10976       rc = reverse_condition (rc);
10977     else 
10978       {
10979         rtx tmp = operands[1];
10980         operands[1] = operands[2];
10981         operands[2] = tmp;
10982       }
10984     operands[6] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
10985   }
10986   "
10987   [(set_attr "conds" "clob")
10988    (set_attr "enabled_for_depr_it" "no,yes,yes")
10989    (set_attr "type" "multiple")]
10992 (define_insn "movcond"
10993   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
10994         (if_then_else:SI
10995          (match_operator 5 "arm_comparison_operator"
10996           [(match_operand:SI 3 "s_register_operand" "r,r,r")
10997            (match_operand:SI 4 "arm_add_operand" "rIL,rIL,rIL")])
10998          (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
10999          (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
11000    (clobber (reg:CC CC_REGNUM))]
11001   "TARGET_ARM"
11002   "*
11003   if (GET_CODE (operands[5]) == LT
11004       && (operands[4] == const0_rtx))
11005     {
11006       if (which_alternative != 1 && REG_P (operands[1]))
11007         {
11008           if (operands[2] == const0_rtx)
11009             return \"and\\t%0, %1, %3, asr #31\";
11010           return \"ands\\t%0, %1, %3, asr #32\;movcc\\t%0, %2\";
11011         }
11012       else if (which_alternative != 0 && REG_P (operands[2]))
11013         {
11014           if (operands[1] == const0_rtx)
11015             return \"bic\\t%0, %2, %3, asr #31\";
11016           return \"bics\\t%0, %2, %3, asr #32\;movcs\\t%0, %1\";
11017         }
11018       /* The only case that falls through to here is when both ops 1 & 2
11019          are constants.  */
11020     }
11022   if (GET_CODE (operands[5]) == GE
11023       && (operands[4] == const0_rtx))
11024     {
11025       if (which_alternative != 1 && REG_P (operands[1]))
11026         {
11027           if (operands[2] == const0_rtx)
11028             return \"bic\\t%0, %1, %3, asr #31\";
11029           return \"bics\\t%0, %1, %3, asr #32\;movcs\\t%0, %2\";
11030         }
11031       else if (which_alternative != 0 && REG_P (operands[2]))
11032         {
11033           if (operands[1] == const0_rtx)
11034             return \"and\\t%0, %2, %3, asr #31\";
11035           return \"ands\\t%0, %2, %3, asr #32\;movcc\\t%0, %1\";
11036         }
11037       /* The only case that falls through to here is when both ops 1 & 2
11038          are constants.  */
11039     }
11040   if (CONST_INT_P (operands[4])
11041       && !const_ok_for_arm (INTVAL (operands[4])))
11042     output_asm_insn (\"cmn\\t%3, #%n4\", operands);
11043   else
11044     output_asm_insn (\"cmp\\t%3, %4\", operands);
11045   if (which_alternative != 0)
11046     output_asm_insn (\"mov%d5\\t%0, %1\", operands);
11047   if (which_alternative != 1)
11048     output_asm_insn (\"mov%D5\\t%0, %2\", operands);
11049   return \"\";
11050   "
11051   [(set_attr "conds" "clob")
11052    (set_attr "length" "8,8,12")
11053    (set_attr "type" "multiple")]
11056 ;; ??? The patterns below need checking for Thumb-2 usefulness.
11058 (define_insn "*ifcompare_plus_move"
11059   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
11060         (if_then_else:SI (match_operator 6 "arm_comparison_operator"
11061                           [(match_operand:SI 4 "s_register_operand" "r,r")
11062                            (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
11063                          (plus:SI
11064                           (match_operand:SI 2 "s_register_operand" "r,r")
11065                           (match_operand:SI 3 "arm_add_operand" "rIL,rIL"))
11066                          (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))
11067    (clobber (reg:CC CC_REGNUM))]
11068   "TARGET_ARM"
11069   "#"
11070   [(set_attr "conds" "clob")
11071    (set_attr "length" "8,12")
11072    (set_attr "type" "multiple")]
11075 (define_insn "*if_plus_move"
11076   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
11077         (if_then_else:SI
11078          (match_operator 4 "arm_comparison_operator"
11079           [(match_operand 5 "cc_register" "") (const_int 0)])
11080          (plus:SI
11081           (match_operand:SI 2 "s_register_operand" "r,r,r,r")
11082           (match_operand:SI 3 "arm_add_operand" "rI,L,rI,L"))
11083          (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")))]
11084   "TARGET_ARM"
11085   "@
11086    add%d4\\t%0, %2, %3
11087    sub%d4\\t%0, %2, #%n3
11088    add%d4\\t%0, %2, %3\;mov%D4\\t%0, %1
11089    sub%d4\\t%0, %2, #%n3\;mov%D4\\t%0, %1"
11090   [(set_attr "conds" "use")
11091    (set_attr "length" "4,4,8,8")
11092    (set_attr_alternative "type"
11093                          [(if_then_else (match_operand 3 "const_int_operand" "")
11094                                         (const_string "alu_imm" )
11095                                         (const_string "alu_reg"))
11096                           (const_string "alu_imm")
11097                           (const_string "alu_reg")
11098                           (const_string "alu_reg")])]
11101 (define_insn "*ifcompare_move_plus"
11102   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
11103         (if_then_else:SI (match_operator 6 "arm_comparison_operator"
11104                           [(match_operand:SI 4 "s_register_operand" "r,r")
11105                            (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
11106                          (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
11107                          (plus:SI
11108                           (match_operand:SI 2 "s_register_operand" "r,r")
11109                           (match_operand:SI 3 "arm_add_operand" "rIL,rIL"))))
11110    (clobber (reg:CC CC_REGNUM))]
11111   "TARGET_ARM"
11112   "#"
11113   [(set_attr "conds" "clob")
11114    (set_attr "length" "8,12")
11115    (set_attr "type" "multiple")]
11118 (define_insn "*if_move_plus"
11119   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
11120         (if_then_else:SI
11121          (match_operator 4 "arm_comparison_operator"
11122           [(match_operand 5 "cc_register" "") (const_int 0)])
11123          (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")
11124          (plus:SI
11125           (match_operand:SI 2 "s_register_operand" "r,r,r,r")
11126           (match_operand:SI 3 "arm_add_operand" "rI,L,rI,L"))))]
11127   "TARGET_ARM"
11128   "@
11129    add%D4\\t%0, %2, %3
11130    sub%D4\\t%0, %2, #%n3
11131    add%D4\\t%0, %2, %3\;mov%d4\\t%0, %1
11132    sub%D4\\t%0, %2, #%n3\;mov%d4\\t%0, %1"
11133   [(set_attr "conds" "use")
11134    (set_attr "length" "4,4,8,8")
11135    (set_attr "type" "alu_reg,alu_imm,multiple,multiple")]
11138 (define_insn "*ifcompare_arith_arith"
11139   [(set (match_operand:SI 0 "s_register_operand" "=r")
11140         (if_then_else:SI (match_operator 9 "arm_comparison_operator"
11141                           [(match_operand:SI 5 "s_register_operand" "r")
11142                            (match_operand:SI 6 "arm_add_operand" "rIL")])
11143                          (match_operator:SI 8 "shiftable_operator"
11144                           [(match_operand:SI 1 "s_register_operand" "r")
11145                            (match_operand:SI 2 "arm_rhs_operand" "rI")])
11146                          (match_operator:SI 7 "shiftable_operator"
11147                           [(match_operand:SI 3 "s_register_operand" "r")
11148                            (match_operand:SI 4 "arm_rhs_operand" "rI")])))
11149    (clobber (reg:CC CC_REGNUM))]
11150   "TARGET_ARM"
11151   "#"
11152   [(set_attr "conds" "clob")
11153    (set_attr "length" "12")
11154    (set_attr "type" "multiple")]
11157 (define_insn "*if_arith_arith"
11158   [(set (match_operand:SI 0 "s_register_operand" "=r")
11159         (if_then_else:SI (match_operator 5 "arm_comparison_operator"
11160                           [(match_operand 8 "cc_register" "") (const_int 0)])
11161                          (match_operator:SI 6 "shiftable_operator"
11162                           [(match_operand:SI 1 "s_register_operand" "r")
11163                            (match_operand:SI 2 "arm_rhs_operand" "rI")])
11164                          (match_operator:SI 7 "shiftable_operator"
11165                           [(match_operand:SI 3 "s_register_operand" "r")
11166                            (match_operand:SI 4 "arm_rhs_operand" "rI")])))]
11167   "TARGET_ARM"
11168   "%I6%d5\\t%0, %1, %2\;%I7%D5\\t%0, %3, %4"
11169   [(set_attr "conds" "use")
11170    (set_attr "length" "8")
11171    (set_attr "type" "multiple")]
11174 (define_insn "*ifcompare_arith_move"
11175   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
11176         (if_then_else:SI (match_operator 6 "arm_comparison_operator"
11177                           [(match_operand:SI 2 "s_register_operand" "r,r")
11178                            (match_operand:SI 3 "arm_add_operand" "rIL,rIL")])
11179                          (match_operator:SI 7 "shiftable_operator"
11180                           [(match_operand:SI 4 "s_register_operand" "r,r")
11181                            (match_operand:SI 5 "arm_rhs_operand" "rI,rI")])
11182                          (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))
11183    (clobber (reg:CC CC_REGNUM))]
11184   "TARGET_ARM"
11185   "*
11186   /* If we have an operation where (op x 0) is the identity operation and
11187      the conditional operator is LT or GE and we are comparing against zero and
11188      everything is in registers then we can do this in two instructions.  */
11189   if (operands[3] == const0_rtx
11190       && GET_CODE (operands[7]) != AND
11191       && REG_P (operands[5])
11192       && REG_P (operands[1])
11193       && REGNO (operands[1]) == REGNO (operands[4])
11194       && REGNO (operands[4]) != REGNO (operands[0]))
11195     {
11196       if (GET_CODE (operands[6]) == LT)
11197         return \"and\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\";
11198       else if (GET_CODE (operands[6]) == GE)
11199         return \"bic\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\";
11200     }
11201   if (CONST_INT_P (operands[3])
11202       && !const_ok_for_arm (INTVAL (operands[3])))
11203     output_asm_insn (\"cmn\\t%2, #%n3\", operands);
11204   else
11205     output_asm_insn (\"cmp\\t%2, %3\", operands);
11206   output_asm_insn (\"%I7%d6\\t%0, %4, %5\", operands);
11207   if (which_alternative != 0)
11208     return \"mov%D6\\t%0, %1\";
11209   return \"\";
11210   "
11211   [(set_attr "conds" "clob")
11212    (set_attr "length" "8,12")
11213    (set_attr "type" "multiple")]
11216 (define_insn "*if_arith_move"
11217   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
11218         (if_then_else:SI (match_operator 4 "arm_comparison_operator"
11219                           [(match_operand 6 "cc_register" "") (const_int 0)])
11220                          (match_operator:SI 5 "shiftable_operator"
11221                           [(match_operand:SI 2 "s_register_operand" "r,r")
11222                            (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
11223                          (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))]
11224   "TARGET_ARM"
11225   "@
11226    %I5%d4\\t%0, %2, %3
11227    %I5%d4\\t%0, %2, %3\;mov%D4\\t%0, %1"
11228   [(set_attr "conds" "use")
11229    (set_attr "length" "4,8")
11230    (set_attr "type" "alu_shift_reg,multiple")]
11233 (define_insn "*ifcompare_move_arith"
11234   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
11235         (if_then_else:SI (match_operator 6 "arm_comparison_operator"
11236                           [(match_operand:SI 4 "s_register_operand" "r,r")
11237                            (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
11238                          (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
11239                          (match_operator:SI 7 "shiftable_operator"
11240                           [(match_operand:SI 2 "s_register_operand" "r,r")
11241                            (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
11242    (clobber (reg:CC CC_REGNUM))]
11243   "TARGET_ARM"
11244   "*
11245   /* If we have an operation where (op x 0) is the identity operation and
11246      the conditional operator is LT or GE and we are comparing against zero and
11247      everything is in registers then we can do this in two instructions */
11248   if (operands[5] == const0_rtx
11249       && GET_CODE (operands[7]) != AND
11250       && REG_P (operands[3])
11251       && REG_P (operands[1])
11252       && REGNO (operands[1]) == REGNO (operands[2])
11253       && REGNO (operands[2]) != REGNO (operands[0]))
11254     {
11255       if (GET_CODE (operands[6]) == GE)
11256         return \"and\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\";
11257       else if (GET_CODE (operands[6]) == LT)
11258         return \"bic\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\";
11259     }
11261   if (CONST_INT_P (operands[5])
11262       && !const_ok_for_arm (INTVAL (operands[5])))
11263     output_asm_insn (\"cmn\\t%4, #%n5\", operands);
11264   else
11265     output_asm_insn (\"cmp\\t%4, %5\", operands);
11267   if (which_alternative != 0)
11268     output_asm_insn (\"mov%d6\\t%0, %1\", operands);
11269   return \"%I7%D6\\t%0, %2, %3\";
11270   "
11271   [(set_attr "conds" "clob")
11272    (set_attr "length" "8,12")
11273    (set_attr "type" "multiple")]
11276 (define_insn "*if_move_arith"
11277   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
11278         (if_then_else:SI
11279          (match_operator 4 "arm_comparison_operator"
11280           [(match_operand 6 "cc_register" "") (const_int 0)])
11281          (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
11282          (match_operator:SI 5 "shiftable_operator"
11283           [(match_operand:SI 2 "s_register_operand" "r,r")
11284            (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))]
11285   "TARGET_ARM"
11286   "@
11287    %I5%D4\\t%0, %2, %3
11288    %I5%D4\\t%0, %2, %3\;mov%d4\\t%0, %1"
11289   [(set_attr "conds" "use")
11290    (set_attr "length" "4,8")
11291    (set_attr "type" "alu_shift_reg,multiple")]
11294 (define_insn "*ifcompare_move_not"
11295   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
11296         (if_then_else:SI
11297          (match_operator 5 "arm_comparison_operator"
11298           [(match_operand:SI 3 "s_register_operand" "r,r")
11299            (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
11300          (match_operand:SI 1 "arm_not_operand" "0,?rIK")
11301          (not:SI
11302           (match_operand:SI 2 "s_register_operand" "r,r"))))
11303    (clobber (reg:CC CC_REGNUM))]
11304   "TARGET_ARM"
11305   "#"
11306   [(set_attr "conds" "clob")
11307    (set_attr "length" "8,12")
11308    (set_attr "type" "multiple")]
11311 (define_insn "*if_move_not"
11312   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
11313         (if_then_else:SI
11314          (match_operator 4 "arm_comparison_operator"
11315           [(match_operand 3 "cc_register" "") (const_int 0)])
11316          (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
11317          (not:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))))]
11318   "TARGET_ARM"
11319   "@
11320    mvn%D4\\t%0, %2
11321    mov%d4\\t%0, %1\;mvn%D4\\t%0, %2
11322    mvn%d4\\t%0, #%B1\;mvn%D4\\t%0, %2"
11323   [(set_attr "conds" "use")
11324    (set_attr "type" "mvn_reg")
11325    (set_attr "length" "4,8,8")
11326    (set_attr "type" "mvn_reg,multiple,multiple")]
11329 (define_insn "*ifcompare_not_move"
11330   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
11331         (if_then_else:SI 
11332          (match_operator 5 "arm_comparison_operator"
11333           [(match_operand:SI 3 "s_register_operand" "r,r")
11334            (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
11335          (not:SI
11336           (match_operand:SI 2 "s_register_operand" "r,r"))
11337          (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
11338    (clobber (reg:CC CC_REGNUM))]
11339   "TARGET_ARM"
11340   "#"
11341   [(set_attr "conds" "clob")
11342    (set_attr "length" "8,12")
11343    (set_attr "type" "multiple")]
11346 (define_insn "*if_not_move"
11347   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
11348         (if_then_else:SI
11349          (match_operator 4 "arm_comparison_operator"
11350           [(match_operand 3 "cc_register" "") (const_int 0)])
11351          (not:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))
11352          (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
11353   "TARGET_ARM"
11354   "@
11355    mvn%d4\\t%0, %2
11356    mov%D4\\t%0, %1\;mvn%d4\\t%0, %2
11357    mvn%D4\\t%0, #%B1\;mvn%d4\\t%0, %2"
11358   [(set_attr "conds" "use")
11359    (set_attr "type" "mvn_reg,multiple,multiple")
11360    (set_attr "length" "4,8,8")]
11363 (define_insn "*ifcompare_shift_move"
11364   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
11365         (if_then_else:SI
11366          (match_operator 6 "arm_comparison_operator"
11367           [(match_operand:SI 4 "s_register_operand" "r,r")
11368            (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
11369          (match_operator:SI 7 "shift_operator"
11370           [(match_operand:SI 2 "s_register_operand" "r,r")
11371            (match_operand:SI 3 "arm_rhs_operand" "rM,rM")])
11372          (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
11373    (clobber (reg:CC CC_REGNUM))]
11374   "TARGET_ARM"
11375   "#"
11376   [(set_attr "conds" "clob")
11377    (set_attr "length" "8,12")
11378    (set_attr "type" "multiple")]
11381 (define_insn "*if_shift_move"
11382   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
11383         (if_then_else:SI
11384          (match_operator 5 "arm_comparison_operator"
11385           [(match_operand 6 "cc_register" "") (const_int 0)])
11386          (match_operator:SI 4 "shift_operator"
11387           [(match_operand:SI 2 "s_register_operand" "r,r,r")
11388            (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM")])
11389          (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
11390   "TARGET_ARM"
11391   "@
11392    mov%d5\\t%0, %2%S4
11393    mov%D5\\t%0, %1\;mov%d5\\t%0, %2%S4
11394    mvn%D5\\t%0, #%B1\;mov%d5\\t%0, %2%S4"
11395   [(set_attr "conds" "use")
11396    (set_attr "shift" "2")
11397    (set_attr "length" "4,8,8")
11398    (set_attr "type" "mov_shift_reg,multiple,multiple")]
11401 (define_insn "*ifcompare_move_shift"
11402   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
11403         (if_then_else:SI
11404          (match_operator 6 "arm_comparison_operator"
11405           [(match_operand:SI 4 "s_register_operand" "r,r")
11406            (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
11407          (match_operand:SI 1 "arm_not_operand" "0,?rIK")
11408          (match_operator:SI 7 "shift_operator"
11409           [(match_operand:SI 2 "s_register_operand" "r,r")
11410            (match_operand:SI 3 "arm_rhs_operand" "rM,rM")])))
11411    (clobber (reg:CC CC_REGNUM))]
11412   "TARGET_ARM"
11413   "#"
11414   [(set_attr "conds" "clob")
11415    (set_attr "length" "8,12")
11416    (set_attr "type" "multiple")]
11419 (define_insn "*if_move_shift"
11420   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
11421         (if_then_else:SI
11422          (match_operator 5 "arm_comparison_operator"
11423           [(match_operand 6 "cc_register" "") (const_int 0)])
11424          (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
11425          (match_operator:SI 4 "shift_operator"
11426           [(match_operand:SI 2 "s_register_operand" "r,r,r")
11427            (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM")])))]
11428   "TARGET_ARM"
11429   "@
11430    mov%D5\\t%0, %2%S4
11431    mov%d5\\t%0, %1\;mov%D5\\t%0, %2%S4
11432    mvn%d5\\t%0, #%B1\;mov%D5\\t%0, %2%S4"
11433   [(set_attr "conds" "use")
11434    (set_attr "shift" "2")
11435    (set_attr "length" "4,8,8")
11436    (set_attr "type" "mov_shift_reg,multiple,multiple")]
11439 (define_insn "*ifcompare_shift_shift"
11440   [(set (match_operand:SI 0 "s_register_operand" "=r")
11441         (if_then_else:SI
11442          (match_operator 7 "arm_comparison_operator"
11443           [(match_operand:SI 5 "s_register_operand" "r")
11444            (match_operand:SI 6 "arm_add_operand" "rIL")])
11445          (match_operator:SI 8 "shift_operator"
11446           [(match_operand:SI 1 "s_register_operand" "r")
11447            (match_operand:SI 2 "arm_rhs_operand" "rM")])
11448          (match_operator:SI 9 "shift_operator"
11449           [(match_operand:SI 3 "s_register_operand" "r")
11450            (match_operand:SI 4 "arm_rhs_operand" "rM")])))
11451    (clobber (reg:CC CC_REGNUM))]
11452   "TARGET_ARM"
11453   "#"
11454   [(set_attr "conds" "clob")
11455    (set_attr "length" "12")
11456    (set_attr "type" "multiple")]
11459 (define_insn "*if_shift_shift"
11460   [(set (match_operand:SI 0 "s_register_operand" "=r")
11461         (if_then_else:SI
11462          (match_operator 5 "arm_comparison_operator"
11463           [(match_operand 8 "cc_register" "") (const_int 0)])
11464          (match_operator:SI 6 "shift_operator"
11465           [(match_operand:SI 1 "s_register_operand" "r")
11466            (match_operand:SI 2 "arm_rhs_operand" "rM")])
11467          (match_operator:SI 7 "shift_operator"
11468           [(match_operand:SI 3 "s_register_operand" "r")
11469            (match_operand:SI 4 "arm_rhs_operand" "rM")])))]
11470   "TARGET_ARM"
11471   "mov%d5\\t%0, %1%S6\;mov%D5\\t%0, %3%S7"
11472   [(set_attr "conds" "use")
11473    (set_attr "shift" "1")
11474    (set_attr "length" "8")
11475    (set (attr "type") (if_then_else
11476                         (and (match_operand 2 "const_int_operand" "")
11477                              (match_operand 4 "const_int_operand" ""))
11478                       (const_string "mov_shift")
11479                       (const_string "mov_shift_reg")))]
11482 (define_insn "*ifcompare_not_arith"
11483   [(set (match_operand:SI 0 "s_register_operand" "=r")
11484         (if_then_else:SI
11485          (match_operator 6 "arm_comparison_operator"
11486           [(match_operand:SI 4 "s_register_operand" "r")
11487            (match_operand:SI 5 "arm_add_operand" "rIL")])
11488          (not:SI (match_operand:SI 1 "s_register_operand" "r"))
11489          (match_operator:SI 7 "shiftable_operator"
11490           [(match_operand:SI 2 "s_register_operand" "r")
11491            (match_operand:SI 3 "arm_rhs_operand" "rI")])))
11492    (clobber (reg:CC CC_REGNUM))]
11493   "TARGET_ARM"
11494   "#"
11495   [(set_attr "conds" "clob")
11496    (set_attr "length" "12")
11497    (set_attr "type" "multiple")]
11500 (define_insn "*if_not_arith"
11501   [(set (match_operand:SI 0 "s_register_operand" "=r")
11502         (if_then_else:SI
11503          (match_operator 5 "arm_comparison_operator"
11504           [(match_operand 4 "cc_register" "") (const_int 0)])
11505          (not:SI (match_operand:SI 1 "s_register_operand" "r"))
11506          (match_operator:SI 6 "shiftable_operator"
11507           [(match_operand:SI 2 "s_register_operand" "r")
11508            (match_operand:SI 3 "arm_rhs_operand" "rI")])))]
11509   "TARGET_ARM"
11510   "mvn%d5\\t%0, %1\;%I6%D5\\t%0, %2, %3"
11511   [(set_attr "conds" "use")
11512    (set_attr "type" "mvn_reg")
11513    (set_attr "length" "8")]
11516 (define_insn "*ifcompare_arith_not"
11517   [(set (match_operand:SI 0 "s_register_operand" "=r")
11518         (if_then_else:SI
11519          (match_operator 6 "arm_comparison_operator"
11520           [(match_operand:SI 4 "s_register_operand" "r")
11521            (match_operand:SI 5 "arm_add_operand" "rIL")])
11522          (match_operator:SI 7 "shiftable_operator"
11523           [(match_operand:SI 2 "s_register_operand" "r")
11524            (match_operand:SI 3 "arm_rhs_operand" "rI")])
11525          (not:SI (match_operand:SI 1 "s_register_operand" "r"))))
11526    (clobber (reg:CC CC_REGNUM))]
11527   "TARGET_ARM"
11528   "#"
11529   [(set_attr "conds" "clob")
11530    (set_attr "length" "12")
11531    (set_attr "type" "multiple")]
11534 (define_insn "*if_arith_not"
11535   [(set (match_operand:SI 0 "s_register_operand" "=r")
11536         (if_then_else:SI
11537          (match_operator 5 "arm_comparison_operator"
11538           [(match_operand 4 "cc_register" "") (const_int 0)])
11539          (match_operator:SI 6 "shiftable_operator"
11540           [(match_operand:SI 2 "s_register_operand" "r")
11541            (match_operand:SI 3 "arm_rhs_operand" "rI")])
11542          (not:SI (match_operand:SI 1 "s_register_operand" "r"))))]
11543   "TARGET_ARM"
11544   "mvn%D5\\t%0, %1\;%I6%d5\\t%0, %2, %3"
11545   [(set_attr "conds" "use")
11546    (set_attr "type" "multiple")
11547    (set_attr "length" "8")]
11550 (define_insn "*ifcompare_neg_move"
11551   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
11552         (if_then_else:SI
11553          (match_operator 5 "arm_comparison_operator"
11554           [(match_operand:SI 3 "s_register_operand" "r,r")
11555            (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
11556          (neg:SI (match_operand:SI 2 "s_register_operand" "r,r"))
11557          (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
11558    (clobber (reg:CC CC_REGNUM))]
11559   "TARGET_ARM"
11560   "#"
11561   [(set_attr "conds" "clob")
11562    (set_attr "length" "8,12")
11563    (set_attr "type" "multiple")]
11566 (define_insn "*if_neg_move"
11567   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
11568         (if_then_else:SI
11569          (match_operator 4 "arm_comparison_operator"
11570           [(match_operand 3 "cc_register" "") (const_int 0)])
11571          (neg:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))
11572          (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
11573   "TARGET_ARM"
11574   "@
11575    rsb%d4\\t%0, %2, #0
11576    mov%D4\\t%0, %1\;rsb%d4\\t%0, %2, #0
11577    mvn%D4\\t%0, #%B1\;rsb%d4\\t%0, %2, #0"
11578   [(set_attr "conds" "use")
11579    (set_attr "length" "4,8,8")
11580    (set_attr "type" "logic_shift_imm,multiple,multiple")]
11583 (define_insn "*ifcompare_move_neg"
11584   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
11585         (if_then_else:SI
11586          (match_operator 5 "arm_comparison_operator"
11587           [(match_operand:SI 3 "s_register_operand" "r,r")
11588            (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
11589          (match_operand:SI 1 "arm_not_operand" "0,?rIK")
11590          (neg:SI (match_operand:SI 2 "s_register_operand" "r,r"))))
11591    (clobber (reg:CC CC_REGNUM))]
11592   "TARGET_ARM"
11593   "#"
11594   [(set_attr "conds" "clob")
11595    (set_attr "length" "8,12")
11596    (set_attr "type" "multiple")]
11599 (define_insn "*if_move_neg"
11600   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
11601         (if_then_else:SI
11602          (match_operator 4 "arm_comparison_operator"
11603           [(match_operand 3 "cc_register" "") (const_int 0)])
11604          (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
11605          (neg:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))))]
11606   "TARGET_ARM"
11607   "@
11608    rsb%D4\\t%0, %2, #0
11609    mov%d4\\t%0, %1\;rsb%D4\\t%0, %2, #0
11610    mvn%d4\\t%0, #%B1\;rsb%D4\\t%0, %2, #0"
11611   [(set_attr "conds" "use")
11612    (set_attr "length" "4,8,8")
11613    (set_attr "type" "logic_shift_imm,multiple,multiple")]
11616 (define_insn "*arith_adjacentmem"
11617   [(set (match_operand:SI 0 "s_register_operand" "=r")
11618         (match_operator:SI 1 "shiftable_operator"
11619          [(match_operand:SI 2 "memory_operand" "m")
11620           (match_operand:SI 3 "memory_operand" "m")]))
11621    (clobber (match_scratch:SI 4 "=r"))]
11622   "TARGET_ARM && adjacent_mem_locations (operands[2], operands[3])"
11623   "*
11624   {
11625     rtx ldm[3];
11626     rtx arith[4];
11627     rtx base_reg;
11628     HOST_WIDE_INT val1 = 0, val2 = 0;
11630     if (REGNO (operands[0]) > REGNO (operands[4]))
11631       {
11632         ldm[1] = operands[4];
11633         ldm[2] = operands[0];
11634       }
11635     else
11636       {
11637         ldm[1] = operands[0];
11638         ldm[2] = operands[4];
11639       }
11641     base_reg = XEXP (operands[2], 0);
11643     if (!REG_P (base_reg))
11644       {
11645         val1 = INTVAL (XEXP (base_reg, 1));
11646         base_reg = XEXP (base_reg, 0);
11647       }
11649     if (!REG_P (XEXP (operands[3], 0)))
11650       val2 = INTVAL (XEXP (XEXP (operands[3], 0), 1));
11652     arith[0] = operands[0];
11653     arith[3] = operands[1];
11655     if (val1 < val2)
11656       {
11657         arith[1] = ldm[1];
11658         arith[2] = ldm[2];
11659       }
11660     else
11661       {
11662         arith[1] = ldm[2];
11663         arith[2] = ldm[1];
11664       }
11666     ldm[0] = base_reg;
11667     if (val1 !=0 && val2 != 0)
11668       {
11669         rtx ops[3];
11671         if (val1 == 4 || val2 == 4)
11672           /* Other val must be 8, since we know they are adjacent and neither
11673              is zero.  */
11674           output_asm_insn (\"ldm%(ib%)\\t%0, {%1, %2}\", ldm);
11675         else if (const_ok_for_arm (val1) || const_ok_for_arm (-val1))
11676           {
11677             ldm[0] = ops[0] = operands[4];
11678             ops[1] = base_reg;
11679             ops[2] = GEN_INT (val1);
11680             output_add_immediate (ops);
11681             if (val1 < val2)
11682               output_asm_insn (\"ldm%(ia%)\\t%0, {%1, %2}\", ldm);
11683             else
11684               output_asm_insn (\"ldm%(da%)\\t%0, {%1, %2}\", ldm);
11685           }
11686         else
11687           {
11688             /* Offset is out of range for a single add, so use two ldr.  */
11689             ops[0] = ldm[1];
11690             ops[1] = base_reg;
11691             ops[2] = GEN_INT (val1);
11692             output_asm_insn (\"ldr%?\\t%0, [%1, %2]\", ops);
11693             ops[0] = ldm[2];
11694             ops[2] = GEN_INT (val2);
11695             output_asm_insn (\"ldr%?\\t%0, [%1, %2]\", ops);
11696           }
11697       }
11698     else if (val1 != 0)
11699       {
11700         if (val1 < val2)
11701           output_asm_insn (\"ldm%(da%)\\t%0, {%1, %2}\", ldm);
11702         else
11703           output_asm_insn (\"ldm%(ia%)\\t%0, {%1, %2}\", ldm);
11704       }
11705     else
11706       {
11707         if (val1 < val2)
11708           output_asm_insn (\"ldm%(ia%)\\t%0, {%1, %2}\", ldm);
11709         else
11710           output_asm_insn (\"ldm%(da%)\\t%0, {%1, %2}\", ldm);
11711       }
11712     output_asm_insn (\"%I3%?\\t%0, %1, %2\", arith);
11713     return \"\";
11714   }"
11715   [(set_attr "length" "12")
11716    (set_attr "predicable" "yes")
11717    (set_attr "type" "load1")]
11720 ; This pattern is never tried by combine, so do it as a peephole
11722 (define_peephole2
11723   [(set (match_operand:SI 0 "arm_general_register_operand" "")
11724         (match_operand:SI 1 "arm_general_register_operand" ""))
11725    (set (reg:CC CC_REGNUM)
11726         (compare:CC (match_dup 1) (const_int 0)))]
11727   "TARGET_ARM"
11728   [(parallel [(set (reg:CC CC_REGNUM) (compare:CC (match_dup 1) (const_int 0)))
11729               (set (match_dup 0) (match_dup 1))])]
11730   ""
11733 (define_split
11734   [(set (match_operand:SI 0 "s_register_operand" "")
11735         (and:SI (ge:SI (match_operand:SI 1 "s_register_operand" "")
11736                        (const_int 0))
11737                 (neg:SI (match_operator:SI 2 "arm_comparison_operator"
11738                          [(match_operand:SI 3 "s_register_operand" "")
11739                           (match_operand:SI 4 "arm_rhs_operand" "")]))))
11740    (clobber (match_operand:SI 5 "s_register_operand" ""))]
11741   "TARGET_ARM"
11742   [(set (match_dup 5) (not:SI (ashiftrt:SI (match_dup 1) (const_int 31))))
11743    (set (match_dup 0) (and:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
11744                               (match_dup 5)))]
11745   ""
11748 ;; This split can be used because CC_Z mode implies that the following
11749 ;; branch will be an equality, or an unsigned inequality, so the sign
11750 ;; extension is not needed.
11752 (define_split
11753   [(set (reg:CC_Z CC_REGNUM)
11754         (compare:CC_Z
11755          (ashift:SI (subreg:SI (match_operand:QI 0 "memory_operand" "") 0)
11756                     (const_int 24))
11757          (match_operand 1 "const_int_operand" "")))
11758    (clobber (match_scratch:SI 2 ""))]
11759   "TARGET_ARM
11760    && (((unsigned HOST_WIDE_INT) INTVAL (operands[1]))
11761        == (((unsigned HOST_WIDE_INT) INTVAL (operands[1])) >> 24) << 24)"
11762   [(set (match_dup 2) (zero_extend:SI (match_dup 0)))
11763    (set (reg:CC CC_REGNUM) (compare:CC (match_dup 2) (match_dup 1)))]
11764   "
11765   operands[1] = GEN_INT (((unsigned long) INTVAL (operands[1])) >> 24);
11766   "
11768 ;; ??? Check the patterns above for Thumb-2 usefulness
11770 (define_expand "prologue"
11771   [(clobber (const_int 0))]
11772   "TARGET_EITHER"
11773   "if (TARGET_32BIT)
11774      arm_expand_prologue ();
11775    else
11776      thumb1_expand_prologue ();
11777   DONE;
11778   "
11781 (define_expand "epilogue"
11782   [(clobber (const_int 0))]
11783   "TARGET_EITHER"
11784   "
11785   if (crtl->calls_eh_return)
11786     emit_insn (gen_force_register_use (gen_rtx_REG (Pmode, 2)));
11787   if (TARGET_THUMB1)
11788    {
11789      thumb1_expand_epilogue ();
11790      emit_jump_insn (gen_rtx_UNSPEC_VOLATILE (VOIDmode,
11791                      gen_rtvec (1, ret_rtx), VUNSPEC_EPILOGUE));
11792    }
11793   else if (HAVE_return)
11794    {
11795      /* HAVE_return is testing for USE_RETURN_INSN (FALSE).  Hence,
11796         no need for explicit testing again.  */
11797      emit_jump_insn (gen_return ());
11798    }
11799   else if (TARGET_32BIT)
11800    {
11801     arm_expand_epilogue (true);
11802    }
11803   DONE;
11804   "
11807 (define_insn "prologue_thumb1_interwork"
11808   [(unspec_volatile [(const_int 0)] VUNSPEC_THUMB1_INTERWORK)]
11809   "TARGET_THUMB1"
11810   "* return thumb1_output_interwork ();"
11811   [(set_attr "length" "8")
11812    (set_attr "type" "multiple")]
11815 ;; Note - although unspec_volatile's USE all hard registers,
11816 ;; USEs are ignored after relaod has completed.  Thus we need
11817 ;; to add an unspec of the link register to ensure that flow
11818 ;; does not think that it is unused by the sibcall branch that
11819 ;; will replace the standard function epilogue.
11820 (define_expand "sibcall_epilogue"
11821    [(parallel [(unspec:SI [(reg:SI LR_REGNUM)] UNSPEC_REGISTER_USE)
11822                (unspec_volatile [(return)] VUNSPEC_EPILOGUE)])]
11823    "TARGET_32BIT"
11824    "
11825    arm_expand_epilogue (false);
11826    DONE;
11827    "
11830 (define_insn "*epilogue_insns"
11831   [(unspec_volatile [(return)] VUNSPEC_EPILOGUE)]
11832   "TARGET_THUMB1"
11833   "*
11834     return thumb1_unexpanded_epilogue ();
11835   "
11836   ; Length is absolute worst case
11837   [(set_attr "length" "44")
11838    (set_attr "type" "block")
11839    ;; We don't clobber the conditions, but the potential length of this
11840    ;; operation is sufficient to make conditionalizing the sequence 
11841    ;; unlikely to be profitable.
11842    (set_attr "conds" "clob")]
11845 (define_expand "eh_epilogue"
11846   [(use (match_operand:SI 0 "register_operand" ""))
11847    (use (match_operand:SI 1 "register_operand" ""))
11848    (use (match_operand:SI 2 "register_operand" ""))]
11849   "TARGET_EITHER"
11850   "
11851   {
11852     cfun->machine->eh_epilogue_sp_ofs = operands[1];
11853     if (!REG_P (operands[2]) || REGNO (operands[2]) != 2)
11854       {
11855         rtx ra = gen_rtx_REG (Pmode, 2);
11857         emit_move_insn (ra, operands[2]);
11858         operands[2] = ra;
11859       }
11860     /* This is a hack -- we may have crystalized the function type too
11861        early.  */
11862     cfun->machine->func_type = 0;
11863   }"
11866 ;; This split is only used during output to reduce the number of patterns
11867 ;; that need assembler instructions adding to them.  We allowed the setting
11868 ;; of the conditions to be implicit during rtl generation so that
11869 ;; the conditional compare patterns would work.  However this conflicts to
11870 ;; some extent with the conditional data operations, so we have to split them
11871 ;; up again here.
11873 ;; ??? Need to audit these splitters for Thumb-2.  Why isn't normal
11874 ;; conditional execution sufficient?
11876 (define_split
11877   [(set (match_operand:SI 0 "s_register_operand" "")
11878         (if_then_else:SI (match_operator 1 "arm_comparison_operator"
11879                           [(match_operand 2 "" "") (match_operand 3 "" "")])
11880                          (match_dup 0)
11881                          (match_operand 4 "" "")))
11882    (clobber (reg:CC CC_REGNUM))]
11883   "TARGET_ARM && reload_completed"
11884   [(set (match_dup 5) (match_dup 6))
11885    (cond_exec (match_dup 7)
11886               (set (match_dup 0) (match_dup 4)))]
11887   "
11888   {
11889     enum machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
11890                                              operands[2], operands[3]);
11891     enum rtx_code rc = GET_CODE (operands[1]);
11893     operands[5] = gen_rtx_REG (mode, CC_REGNUM);
11894     operands[6] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
11895     if (mode == CCFPmode || mode == CCFPEmode)
11896       rc = reverse_condition_maybe_unordered (rc);
11897     else
11898       rc = reverse_condition (rc);
11900     operands[7] = gen_rtx_fmt_ee (rc, VOIDmode, operands[5], const0_rtx);
11901   }"
11904 (define_split
11905   [(set (match_operand:SI 0 "s_register_operand" "")
11906         (if_then_else:SI (match_operator 1 "arm_comparison_operator"
11907                           [(match_operand 2 "" "") (match_operand 3 "" "")])
11908                          (match_operand 4 "" "")
11909                          (match_dup 0)))
11910    (clobber (reg:CC CC_REGNUM))]
11911   "TARGET_ARM && reload_completed"
11912   [(set (match_dup 5) (match_dup 6))
11913    (cond_exec (match_op_dup 1 [(match_dup 5) (const_int 0)])
11914               (set (match_dup 0) (match_dup 4)))]
11915   "
11916   {
11917     enum machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
11918                                              operands[2], operands[3]);
11920     operands[5] = gen_rtx_REG (mode, CC_REGNUM);
11921     operands[6] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
11922   }"
11925 (define_split
11926   [(set (match_operand:SI 0 "s_register_operand" "")
11927         (if_then_else:SI (match_operator 1 "arm_comparison_operator"
11928                           [(match_operand 2 "" "") (match_operand 3 "" "")])
11929                          (match_operand 4 "" "")
11930                          (match_operand 5 "" "")))
11931    (clobber (reg:CC CC_REGNUM))]
11932   "TARGET_ARM && reload_completed"
11933   [(set (match_dup 6) (match_dup 7))
11934    (cond_exec (match_op_dup 1 [(match_dup 6) (const_int 0)])
11935               (set (match_dup 0) (match_dup 4)))
11936    (cond_exec (match_dup 8)
11937               (set (match_dup 0) (match_dup 5)))]
11938   "
11939   {
11940     enum machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
11941                                              operands[2], operands[3]);
11942     enum rtx_code rc = GET_CODE (operands[1]);
11944     operands[6] = gen_rtx_REG (mode, CC_REGNUM);
11945     operands[7] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
11946     if (mode == CCFPmode || mode == CCFPEmode)
11947       rc = reverse_condition_maybe_unordered (rc);
11948     else
11949       rc = reverse_condition (rc);
11951     operands[8] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
11952   }"
11955 (define_split
11956   [(set (match_operand:SI 0 "s_register_operand" "")
11957         (if_then_else:SI (match_operator 1 "arm_comparison_operator"
11958                           [(match_operand:SI 2 "s_register_operand" "")
11959                            (match_operand:SI 3 "arm_add_operand" "")])
11960                          (match_operand:SI 4 "arm_rhs_operand" "")
11961                          (not:SI
11962                           (match_operand:SI 5 "s_register_operand" ""))))
11963    (clobber (reg:CC CC_REGNUM))]
11964   "TARGET_ARM && reload_completed"
11965   [(set (match_dup 6) (match_dup 7))
11966    (cond_exec (match_op_dup 1 [(match_dup 6) (const_int 0)])
11967               (set (match_dup 0) (match_dup 4)))
11968    (cond_exec (match_dup 8)
11969               (set (match_dup 0) (not:SI (match_dup 5))))]
11970   "
11971   {
11972     enum machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
11973                                              operands[2], operands[3]);
11974     enum rtx_code rc = GET_CODE (operands[1]);
11976     operands[6] = gen_rtx_REG (mode, CC_REGNUM);
11977     operands[7] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
11978     if (mode == CCFPmode || mode == CCFPEmode)
11979       rc = reverse_condition_maybe_unordered (rc);
11980     else
11981       rc = reverse_condition (rc);
11983     operands[8] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
11984   }"
11987 (define_insn "*cond_move_not"
11988   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
11989         (if_then_else:SI (match_operator 4 "arm_comparison_operator"
11990                           [(match_operand 3 "cc_register" "") (const_int 0)])
11991                          (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
11992                          (not:SI
11993                           (match_operand:SI 2 "s_register_operand" "r,r"))))]
11994   "TARGET_ARM"
11995   "@
11996    mvn%D4\\t%0, %2
11997    mov%d4\\t%0, %1\;mvn%D4\\t%0, %2"
11998   [(set_attr "conds" "use")
11999    (set_attr "type" "mvn_reg,multiple")
12000    (set_attr "length" "4,8")]
12003 ;; The next two patterns occur when an AND operation is followed by a
12004 ;; scc insn sequence 
12006 (define_insn "*sign_extract_onebit"
12007   [(set (match_operand:SI 0 "s_register_operand" "=r")
12008         (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
12009                          (const_int 1)
12010                          (match_operand:SI 2 "const_int_operand" "n")))
12011     (clobber (reg:CC CC_REGNUM))]
12012   "TARGET_ARM"
12013   "*
12014     operands[2] = GEN_INT (1 << INTVAL (operands[2]));
12015     output_asm_insn (\"ands\\t%0, %1, %2\", operands);
12016     return \"mvnne\\t%0, #0\";
12017   "
12018   [(set_attr "conds" "clob")
12019    (set_attr "length" "8")
12020    (set_attr "type" "multiple")]
12023 (define_insn "*not_signextract_onebit"
12024   [(set (match_operand:SI 0 "s_register_operand" "=r")
12025         (not:SI
12026          (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
12027                           (const_int 1)
12028                           (match_operand:SI 2 "const_int_operand" "n"))))
12029    (clobber (reg:CC CC_REGNUM))]
12030   "TARGET_ARM"
12031   "*
12032     operands[2] = GEN_INT (1 << INTVAL (operands[2]));
12033     output_asm_insn (\"tst\\t%1, %2\", operands);
12034     output_asm_insn (\"mvneq\\t%0, #0\", operands);
12035     return \"movne\\t%0, #0\";
12036   "
12037   [(set_attr "conds" "clob")
12038    (set_attr "length" "12")
12039    (set_attr "type" "multiple")]
12041 ;; ??? The above patterns need auditing for Thumb-2
12043 ;; Push multiple registers to the stack.  Registers are in parallel (use ...)
12044 ;; expressions.  For simplicity, the first register is also in the unspec
12045 ;; part.
12046 ;; To avoid the usage of GNU extension, the length attribute is computed
12047 ;; in a C function arm_attr_length_push_multi.
12048 (define_insn "*push_multi"
12049   [(match_parallel 2 "multi_register_push"
12050     [(set (match_operand:BLK 0 "push_mult_memory_operand" "")
12051           (unspec:BLK [(match_operand:SI 1 "s_register_operand" "")]
12052                       UNSPEC_PUSH_MULT))])]
12053   ""
12054   "*
12055   {
12056     int num_saves = XVECLEN (operands[2], 0);
12057      
12058     /* For the StrongARM at least it is faster to
12059        use STR to store only a single register.
12060        In Thumb mode always use push, and the assembler will pick
12061        something appropriate.  */
12062     if (num_saves == 1 && TARGET_ARM)
12063       output_asm_insn (\"str%?\\t%1, [%m0, #-4]!\", operands);
12064     else
12065       {
12066         int i;
12067         char pattern[100];
12069         if (TARGET_ARM)
12070             strcpy (pattern, \"stm%(fd%)\\t%m0!, {%1\");
12071         else if (TARGET_THUMB2)
12072             strcpy (pattern, \"push%?\\t{%1\");
12073         else
12074             strcpy (pattern, \"push\\t{%1\");
12076         for (i = 1; i < num_saves; i++)
12077           {
12078             strcat (pattern, \", %|\");
12079             strcat (pattern,
12080                     reg_names[REGNO (XEXP (XVECEXP (operands[2], 0, i), 0))]);
12081           }
12083         strcat (pattern, \"}\");
12084         output_asm_insn (pattern, operands);
12085       }
12087     return \"\";
12088   }"
12089   [(set_attr "type" "store4")
12090    (set (attr "length")
12091         (symbol_ref "arm_attr_length_push_multi (operands[2], operands[1])"))]
12094 (define_insn "stack_tie"
12095   [(set (mem:BLK (scratch))
12096         (unspec:BLK [(match_operand:SI 0 "s_register_operand" "rk")
12097                      (match_operand:SI 1 "s_register_operand" "rk")]
12098                     UNSPEC_PRLG_STK))]
12099   ""
12100   ""
12101   [(set_attr "length" "0")
12102    (set_attr "type" "block")]
12105 ;; Pop (as used in epilogue RTL)
12107 (define_insn "*load_multiple_with_writeback"
12108   [(match_parallel 0 "load_multiple_operation"
12109     [(set (match_operand:SI 1 "s_register_operand" "+rk")
12110           (plus:SI (match_dup 1)
12111                    (match_operand:SI 2 "const_int_I_operand" "I")))
12112      (set (match_operand:SI 3 "s_register_operand" "=rk")
12113           (mem:SI (match_dup 1)))
12114         ])]
12115   "TARGET_32BIT && (reload_in_progress || reload_completed)"
12116   "*
12117   {
12118     arm_output_multireg_pop (operands, /*return_pc=*/false,
12119                                        /*cond=*/const_true_rtx,
12120                                        /*reverse=*/false,
12121                                        /*update=*/true);
12122     return \"\";
12123   }
12124   "
12125   [(set_attr "type" "load4")
12126    (set_attr "predicable" "yes")]
12129 ;; Pop with return (as used in epilogue RTL)
12131 ;; This instruction is generated when the registers are popped at the end of
12132 ;; epilogue.  Here, instead of popping the value into LR and then generating
12133 ;; jump to LR, value is popped into PC directly.  Hence, the pattern is combined
12134 ;;  with (return).
12135 (define_insn "*pop_multiple_with_writeback_and_return"
12136   [(match_parallel 0 "pop_multiple_return"
12137     [(return)
12138      (set (match_operand:SI 1 "s_register_operand" "+rk")
12139           (plus:SI (match_dup 1)
12140                    (match_operand:SI 2 "const_int_I_operand" "I")))
12141      (set (match_operand:SI 3 "s_register_operand" "=rk")
12142           (mem:SI (match_dup 1)))
12143         ])]
12144   "TARGET_32BIT && (reload_in_progress || reload_completed)"
12145   "*
12146   {
12147     arm_output_multireg_pop (operands, /*return_pc=*/true,
12148                                        /*cond=*/const_true_rtx,
12149                                        /*reverse=*/false,
12150                                        /*update=*/true);
12151     return \"\";
12152   }
12153   "
12154   [(set_attr "type" "load4")
12155    (set_attr "predicable" "yes")]
12158 (define_insn "*pop_multiple_with_return"
12159   [(match_parallel 0 "pop_multiple_return"
12160     [(return)
12161      (set (match_operand:SI 2 "s_register_operand" "=rk")
12162           (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
12163         ])]
12164   "TARGET_32BIT && (reload_in_progress || reload_completed)"
12165   "*
12166   {
12167     arm_output_multireg_pop (operands, /*return_pc=*/true,
12168                                        /*cond=*/const_true_rtx,
12169                                        /*reverse=*/false,
12170                                        /*update=*/false);
12171     return \"\";
12172   }
12173   "
12174   [(set_attr "type" "load4")
12175    (set_attr "predicable" "yes")]
12178 ;; Load into PC and return
12179 (define_insn "*ldr_with_return"
12180   [(return)
12181    (set (reg:SI PC_REGNUM)
12182         (mem:SI (post_inc:SI (match_operand:SI 0 "s_register_operand" "+rk"))))]
12183   "TARGET_32BIT && (reload_in_progress || reload_completed)"
12184   "ldr%?\t%|pc, [%0], #4"
12185   [(set_attr "type" "load1")
12186    (set_attr "predicable" "yes")]
12188 ;; Pop for floating point registers (as used in epilogue RTL)
12189 (define_insn "*vfp_pop_multiple_with_writeback"
12190   [(match_parallel 0 "pop_multiple_fp"
12191     [(set (match_operand:SI 1 "s_register_operand" "+rk")
12192           (plus:SI (match_dup 1)
12193                    (match_operand:SI 2 "const_int_I_operand" "I")))
12194      (set (match_operand:DF 3 "vfp_hard_register_operand" "")
12195           (mem:DF (match_dup 1)))])]
12196   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
12197   "*
12198   {
12199     int num_regs = XVECLEN (operands[0], 0);
12200     char pattern[100];
12201     rtx op_list[2];
12202     strcpy (pattern, \"vldm\\t\");
12203     strcat (pattern, reg_names[REGNO (SET_DEST (XVECEXP (operands[0], 0, 0)))]);
12204     strcat (pattern, \"!, {\");
12205     op_list[0] = XEXP (XVECEXP (operands[0], 0, 1), 0);
12206     strcat (pattern, \"%P0\");
12207     if ((num_regs - 1) > 1)
12208       {
12209         strcat (pattern, \"-%P1\");
12210         op_list [1] = XEXP (XVECEXP (operands[0], 0, num_regs - 1), 0);
12211       }
12213     strcat (pattern, \"}\");
12214     output_asm_insn (pattern, op_list);
12215     return \"\";
12216   }
12217   "
12218   [(set_attr "type" "load4")
12219    (set_attr "conds" "unconditional")
12220    (set_attr "predicable" "no")]
12223 ;; Special patterns for dealing with the constant pool
12225 (define_insn "align_4"
12226   [(unspec_volatile [(const_int 0)] VUNSPEC_ALIGN)]
12227   "TARGET_EITHER"
12228   "*
12229   assemble_align (32);
12230   return \"\";
12231   "
12232   [(set_attr "type" "no_insn")]
12235 (define_insn "align_8"
12236   [(unspec_volatile [(const_int 0)] VUNSPEC_ALIGN8)]
12237   "TARGET_EITHER"
12238   "*
12239   assemble_align (64);
12240   return \"\";
12241   "
12242   [(set_attr "type" "no_insn")]
12245 (define_insn "consttable_end"
12246   [(unspec_volatile [(const_int 0)] VUNSPEC_POOL_END)]
12247   "TARGET_EITHER"
12248   "*
12249   making_const_table = FALSE;
12250   return \"\";
12251   "
12252   [(set_attr "type" "no_insn")]
12255 (define_insn "consttable_1"
12256   [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_1)]
12257   "TARGET_EITHER"
12258   "*
12259   making_const_table = TRUE;
12260   assemble_integer (operands[0], 1, BITS_PER_WORD, 1);
12261   assemble_zeros (3);
12262   return \"\";
12263   "
12264   [(set_attr "length" "4")
12265    (set_attr "type" "no_insn")]
12268 (define_insn "consttable_2"
12269   [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_2)]
12270   "TARGET_EITHER"
12271   "*
12272   {
12273     rtx x = operands[0];
12274     making_const_table = TRUE;
12275     switch (GET_MODE_CLASS (GET_MODE (x)))
12276       {
12277       case MODE_FLOAT:
12278         arm_emit_fp16_const (x);
12279         break;
12280       default:
12281         assemble_integer (operands[0], 2, BITS_PER_WORD, 1);
12282         assemble_zeros (2);
12283         break;
12284       }
12285     return \"\";
12286   }"
12287   [(set_attr "length" "4")
12288    (set_attr "type" "no_insn")]
12291 (define_insn "consttable_4"
12292   [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_4)]
12293   "TARGET_EITHER"
12294   "*
12295   {
12296     rtx x = operands[0];
12297     making_const_table = TRUE;
12298     switch (GET_MODE_CLASS (GET_MODE (x)))
12299       {
12300       case MODE_FLOAT:
12301         {
12302           REAL_VALUE_TYPE r;
12303           REAL_VALUE_FROM_CONST_DOUBLE (r, x);
12304           assemble_real (r, GET_MODE (x), BITS_PER_WORD);
12305           break;
12306         }
12307       default:
12308         /* XXX: Sometimes gcc does something really dumb and ends up with
12309            a HIGH in a constant pool entry, usually because it's trying to
12310            load into a VFP register.  We know this will always be used in
12311            combination with a LO_SUM which ignores the high bits, so just
12312            strip off the HIGH.  */
12313         if (GET_CODE (x) == HIGH)
12314           x = XEXP (x, 0);
12315         assemble_integer (x, 4, BITS_PER_WORD, 1);
12316         mark_symbol_refs_as_used (x);
12317         break;
12318       }
12319     return \"\";
12320   }"
12321   [(set_attr "length" "4")
12322    (set_attr "type" "no_insn")]
12325 (define_insn "consttable_8"
12326   [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_8)]
12327   "TARGET_EITHER"
12328   "*
12329   {
12330     making_const_table = TRUE;
12331     switch (GET_MODE_CLASS (GET_MODE (operands[0])))
12332       {
12333        case MODE_FLOAT:
12334         {
12335           REAL_VALUE_TYPE r;
12336           REAL_VALUE_FROM_CONST_DOUBLE (r, operands[0]);
12337           assemble_real (r, GET_MODE (operands[0]), BITS_PER_WORD);
12338           break;
12339         }
12340       default:
12341         assemble_integer (operands[0], 8, BITS_PER_WORD, 1);
12342         break;
12343       }
12344     return \"\";
12345   }"
12346   [(set_attr "length" "8")
12347    (set_attr "type" "no_insn")]
12350 (define_insn "consttable_16"
12351   [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_16)]
12352   "TARGET_EITHER"
12353   "*
12354   {
12355     making_const_table = TRUE;
12356     switch (GET_MODE_CLASS (GET_MODE (operands[0])))
12357       {
12358        case MODE_FLOAT:
12359         {
12360           REAL_VALUE_TYPE r;
12361           REAL_VALUE_FROM_CONST_DOUBLE (r, operands[0]);
12362           assemble_real (r, GET_MODE (operands[0]), BITS_PER_WORD);
12363           break;
12364         }
12365       default:
12366         assemble_integer (operands[0], 16, BITS_PER_WORD, 1);
12367         break;
12368       }
12369     return \"\";
12370   }"
12371   [(set_attr "length" "16")
12372    (set_attr "type" "no_insn")]
12375 ;; Miscellaneous Thumb patterns
12377 (define_expand "tablejump"
12378   [(parallel [(set (pc) (match_operand:SI 0 "register_operand" ""))
12379               (use (label_ref (match_operand 1 "" "")))])]
12380   "TARGET_THUMB1"
12381   "
12382   if (flag_pic)
12383     {
12384       /* Hopefully, CSE will eliminate this copy.  */
12385       rtx reg1 = copy_addr_to_reg (gen_rtx_LABEL_REF (Pmode, operands[1]));
12386       rtx reg2 = gen_reg_rtx (SImode);
12388       emit_insn (gen_addsi3 (reg2, operands[0], reg1));
12389       operands[0] = reg2;
12390     }
12391   "
12394 ;; NB never uses BX.
12395 (define_insn "*thumb1_tablejump"
12396   [(set (pc) (match_operand:SI 0 "register_operand" "l*r"))
12397    (use (label_ref (match_operand 1 "" "")))]
12398   "TARGET_THUMB1"
12399   "mov\\t%|pc, %0"
12400   [(set_attr "length" "2")
12401    (set_attr "type" "no_insn")]
12404 ;; V5 Instructions,
12406 (define_insn "clzsi2"
12407   [(set (match_operand:SI 0 "s_register_operand" "=r")
12408         (clz:SI (match_operand:SI 1 "s_register_operand" "r")))]
12409   "TARGET_32BIT && arm_arch5"
12410   "clz%?\\t%0, %1"
12411   [(set_attr "predicable" "yes")
12412    (set_attr "predicable_short_it" "no")
12413    (set_attr "type" "clz")])
12415 (define_insn "rbitsi2"
12416   [(set (match_operand:SI 0 "s_register_operand" "=r")
12417         (unspec:SI [(match_operand:SI 1 "s_register_operand" "r")] UNSPEC_RBIT))]
12418   "TARGET_32BIT && arm_arch_thumb2"
12419   "rbit%?\\t%0, %1"
12420   [(set_attr "predicable" "yes")
12421    (set_attr "predicable_short_it" "no")
12422    (set_attr "type" "clz")])
12424 (define_expand "ctzsi2"
12425  [(set (match_operand:SI           0 "s_register_operand" "")
12426        (ctz:SI (match_operand:SI  1 "s_register_operand" "")))]
12427   "TARGET_32BIT && arm_arch_thumb2"
12428   "
12429    {
12430      rtx tmp = gen_reg_rtx (SImode); 
12431      emit_insn (gen_rbitsi2 (tmp, operands[1]));
12432      emit_insn (gen_clzsi2 (operands[0], tmp));
12433    }
12434    DONE;
12435   "
12438 ;; V5E instructions.
12440 (define_insn "prefetch"
12441   [(prefetch (match_operand:SI 0 "address_operand" "p")
12442              (match_operand:SI 1 "" "")
12443              (match_operand:SI 2 "" ""))]
12444   "TARGET_32BIT && arm_arch5e"
12445   "pld\\t%a0"
12446   [(set_attr "type" "load1")]
12449 ;; General predication pattern
12451 (define_cond_exec
12452   [(match_operator 0 "arm_comparison_operator"
12453     [(match_operand 1 "cc_register" "")
12454      (const_int 0)])]
12455   "TARGET_32BIT"
12456   ""
12457 [(set_attr "predicated" "yes")]
12460 (define_insn "force_register_use"
12461   [(unspec:SI [(match_operand:SI 0 "register_operand" "")] UNSPEC_REGISTER_USE)]
12462   ""
12463   "%@ %0 needed"
12464   [(set_attr "length" "0")
12465    (set_attr "type" "no_insn")]
12469 ;; Patterns for exception handling
12471 (define_expand "eh_return"
12472   [(use (match_operand 0 "general_operand" ""))]
12473   "TARGET_EITHER"
12474   "
12475   {
12476     if (TARGET_32BIT)
12477       emit_insn (gen_arm_eh_return (operands[0]));
12478     else
12479       emit_insn (gen_thumb_eh_return (operands[0]));
12480     DONE;
12481   }"
12483                                    
12484 ;; We can't expand this before we know where the link register is stored.
12485 (define_insn_and_split "arm_eh_return"
12486   [(unspec_volatile [(match_operand:SI 0 "s_register_operand" "r")]
12487                     VUNSPEC_EH_RETURN)
12488    (clobber (match_scratch:SI 1 "=&r"))]
12489   "TARGET_ARM"
12490   "#"
12491   "&& reload_completed"
12492   [(const_int 0)]
12493   "
12494   {
12495     arm_set_return_address (operands[0], operands[1]);
12496     DONE;
12497   }"
12500 (define_insn_and_split "thumb_eh_return"
12501   [(unspec_volatile [(match_operand:SI 0 "s_register_operand" "l")]
12502                     VUNSPEC_EH_RETURN)
12503    (clobber (match_scratch:SI 1 "=&l"))]
12504   "TARGET_THUMB1"
12505   "#"
12506   "&& reload_completed"
12507   [(const_int 0)]
12508   "
12509   {
12510     thumb_set_return_address (operands[0], operands[1]);
12511     DONE;
12512   }"
12513   [(set_attr "type" "mov_reg")]
12517 ;; TLS support
12519 (define_insn "load_tp_hard"
12520   [(set (match_operand:SI 0 "register_operand" "=r")
12521         (unspec:SI [(const_int 0)] UNSPEC_TLS))]
12522   "TARGET_HARD_TP"
12523   "mrc%?\\tp15, 0, %0, c13, c0, 3\\t@ load_tp_hard"
12524   [(set_attr "predicable" "yes")
12525    (set_attr "type" "mrs")]
12528 ;; Doesn't clobber R1-R3.  Must use r0 for the first operand.
12529 (define_insn "load_tp_soft"
12530   [(set (reg:SI 0) (unspec:SI [(const_int 0)] UNSPEC_TLS))
12531    (clobber (reg:SI LR_REGNUM))
12532    (clobber (reg:SI IP_REGNUM))
12533    (clobber (reg:CC CC_REGNUM))]
12534   "TARGET_SOFT_TP"
12535   "bl\\t__aeabi_read_tp\\t@ load_tp_soft"
12536   [(set_attr "conds" "clob")
12537    (set_attr "type" "branch")]
12540 ;; tls descriptor call
12541 (define_insn "tlscall"
12542   [(set (reg:SI R0_REGNUM)
12543         (unspec:SI [(reg:SI R0_REGNUM)
12544                     (match_operand:SI 0 "" "X")
12545                     (match_operand 1 "" "")] UNSPEC_TLS))
12546    (clobber (reg:SI R1_REGNUM))
12547    (clobber (reg:SI LR_REGNUM))
12548    (clobber (reg:SI CC_REGNUM))]
12549   "TARGET_GNU2_TLS"
12550   {
12551     targetm.asm_out.internal_label (asm_out_file, "LPIC",
12552                                     INTVAL (operands[1]));
12553     return "bl\\t%c0(tlscall)";
12554   }
12555   [(set_attr "conds" "clob")
12556    (set_attr "length" "4")
12557    (set_attr "type" "branch")]
12560 ;; For thread pointer builtin
12561 (define_expand "get_thread_pointersi"
12562   [(match_operand:SI 0 "s_register_operand" "=r")]
12563  ""
12566    arm_load_tp (operands[0]);
12567    DONE;
12568  }")
12572 ;; We only care about the lower 16 bits of the constant 
12573 ;; being inserted into the upper 16 bits of the register.
12574 (define_insn "*arm_movtas_ze" 
12575   [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r")
12576                    (const_int 16)
12577                    (const_int 16))
12578         (match_operand:SI 1 "const_int_operand" ""))]
12579   "arm_arch_thumb2"
12580   "movt%?\t%0, %L1"
12581  [(set_attr "predicable" "yes")
12582   (set_attr "predicable_short_it" "no")
12583   (set_attr "length" "4")
12584   (set_attr "type" "mov_imm")]
12587 (define_insn "*arm_rev"
12588   [(set (match_operand:SI 0 "s_register_operand" "=l,l,r")
12589         (bswap:SI (match_operand:SI 1 "s_register_operand" "l,l,r")))]
12590   "arm_arch6"
12591   "@
12592    rev\t%0, %1
12593    rev%?\t%0, %1
12594    rev%?\t%0, %1"
12595   [(set_attr "arch" "t1,t2,32")
12596    (set_attr "length" "2,2,4")
12597    (set_attr "predicable" "no,yes,yes")
12598    (set_attr "predicable_short_it" "no")
12599    (set_attr "type" "rev")]
12602 (define_expand "arm_legacy_rev"
12603   [(set (match_operand:SI 2 "s_register_operand" "")
12604         (xor:SI (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
12605                              (const_int 16))
12606                 (match_dup 1)))
12607    (set (match_dup 2)
12608         (lshiftrt:SI (match_dup 2)
12609                      (const_int 8)))
12610    (set (match_operand:SI 3 "s_register_operand" "")
12611         (rotatert:SI (match_dup 1)
12612                      (const_int 8)))
12613    (set (match_dup 2)
12614         (and:SI (match_dup 2)
12615                 (const_int -65281)))
12616    (set (match_operand:SI 0 "s_register_operand" "")
12617         (xor:SI (match_dup 3)
12618                 (match_dup 2)))]
12619   "TARGET_32BIT"
12620   ""
12623 ;; Reuse temporaries to keep register pressure down.
12624 (define_expand "thumb_legacy_rev"
12625   [(set (match_operand:SI 2 "s_register_operand" "")
12626      (ashift:SI (match_operand:SI 1 "s_register_operand" "")
12627                 (const_int 24)))
12628    (set (match_operand:SI 3 "s_register_operand" "")
12629      (lshiftrt:SI (match_dup 1)
12630                   (const_int 24)))
12631    (set (match_dup 3)
12632      (ior:SI (match_dup 3)
12633              (match_dup 2)))
12634    (set (match_operand:SI 4 "s_register_operand" "")
12635      (const_int 16))
12636    (set (match_operand:SI 5 "s_register_operand" "")
12637      (rotatert:SI (match_dup 1)
12638                   (match_dup 4)))
12639    (set (match_dup 2)
12640      (ashift:SI (match_dup 5)
12641                 (const_int 24)))
12642    (set (match_dup 5)
12643      (lshiftrt:SI (match_dup 5)
12644                   (const_int 24)))
12645    (set (match_dup 5)
12646      (ior:SI (match_dup 5)
12647              (match_dup 2)))
12648    (set (match_dup 5)
12649      (rotatert:SI (match_dup 5)
12650                   (match_dup 4)))
12651    (set (match_operand:SI 0 "s_register_operand" "")
12652      (ior:SI (match_dup 5)
12653              (match_dup 3)))]
12654   "TARGET_THUMB"
12655   ""
12658 (define_expand "bswapsi2"
12659   [(set (match_operand:SI 0 "s_register_operand" "=r")
12660         (bswap:SI (match_operand:SI 1 "s_register_operand" "r")))]
12661 "TARGET_EITHER && (arm_arch6 || !optimize_size)"
12663     if (!arm_arch6)
12664       {
12665         rtx op2 = gen_reg_rtx (SImode);
12666         rtx op3 = gen_reg_rtx (SImode);
12668         if (TARGET_THUMB)
12669           {
12670             rtx op4 = gen_reg_rtx (SImode);
12671             rtx op5 = gen_reg_rtx (SImode);
12673             emit_insn (gen_thumb_legacy_rev (operands[0], operands[1],
12674                                              op2, op3, op4, op5));
12675           }
12676         else
12677           {
12678             emit_insn (gen_arm_legacy_rev (operands[0], operands[1],
12679                                            op2, op3));
12680           }
12682         DONE;
12683       }
12684   "
12687 ;; bswap16 patterns: use revsh and rev16 instructions for the signed
12688 ;; and unsigned variants, respectively. For rev16, expose
12689 ;; byte-swapping in the lower 16 bits only.
12690 (define_insn "*arm_revsh"
12691   [(set (match_operand:SI 0 "s_register_operand" "=l,l,r")
12692         (sign_extend:SI (bswap:HI (match_operand:HI 1 "s_register_operand" "l,l,r"))))]
12693   "arm_arch6"
12694   "@
12695   revsh\t%0, %1
12696   revsh%?\t%0, %1
12697   revsh%?\t%0, %1"
12698   [(set_attr "arch" "t1,t2,32")
12699    (set_attr "length" "2,2,4")
12700    (set_attr "type" "rev")]
12703 (define_insn "*arm_rev16"
12704   [(set (match_operand:HI 0 "s_register_operand" "=l,l,r")
12705         (bswap:HI (match_operand:HI 1 "s_register_operand" "l,l,r")))]
12706   "arm_arch6"
12707   "@
12708    rev16\t%0, %1
12709    rev16%?\t%0, %1
12710    rev16%?\t%0, %1"
12711   [(set_attr "arch" "t1,t2,32")
12712    (set_attr "length" "2,2,4")
12713    (set_attr "type" "rev")]
12716 ;; There are no canonicalisation rules for the position of the lshiftrt, ashift
12717 ;; operations within an IOR/AND RTX, therefore we have two patterns matching
12718 ;; each valid permutation.
12720 (define_insn "arm_rev16si2"
12721   [(set (match_operand:SI 0 "register_operand" "=l,l,r")
12722         (ior:SI (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "l,l,r")
12723                                    (const_int 8))
12724                         (match_operand:SI 3 "const_int_operand" "n,n,n"))
12725                 (and:SI (lshiftrt:SI (match_dup 1)
12726                                      (const_int 8))
12727                         (match_operand:SI 2 "const_int_operand" "n,n,n"))))]
12728   "arm_arch6
12729    && aarch_rev16_shleft_mask_imm_p (operands[3], SImode)
12730    && aarch_rev16_shright_mask_imm_p (operands[2], SImode)"
12731   "rev16\\t%0, %1"
12732   [(set_attr "arch" "t1,t2,32")
12733    (set_attr "length" "2,2,4")
12734    (set_attr "type" "rev")]
12737 (define_insn "arm_rev16si2_alt"
12738   [(set (match_operand:SI 0 "register_operand" "=l,l,r")
12739         (ior:SI (and:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "l,l,r")
12740                                      (const_int 8))
12741                         (match_operand:SI 2 "const_int_operand" "n,n,n"))
12742                 (and:SI (ashift:SI (match_dup 1)
12743                                    (const_int 8))
12744                         (match_operand:SI 3 "const_int_operand" "n,n,n"))))]
12745   "arm_arch6
12746    && aarch_rev16_shleft_mask_imm_p (operands[3], SImode)
12747    && aarch_rev16_shright_mask_imm_p (operands[2], SImode)"
12748   "rev16\\t%0, %1"
12749   [(set_attr "arch" "t1,t2,32")
12750    (set_attr "length" "2,2,4")
12751    (set_attr "type" "rev")]
12754 (define_expand "bswaphi2"
12755   [(set (match_operand:HI 0 "s_register_operand" "=r")
12756         (bswap:HI (match_operand:HI 1 "s_register_operand" "r")))]
12757 "arm_arch6"
12761 ;; Patterns for LDRD/STRD in Thumb2 mode
12763 (define_insn "*thumb2_ldrd"
12764   [(set (match_operand:SI 0 "s_register_operand" "=r")
12765         (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "rk")
12766                          (match_operand:SI 2 "ldrd_strd_offset_operand" "Do"))))
12767    (set (match_operand:SI 3 "s_register_operand" "=r")
12768         (mem:SI (plus:SI (match_dup 1)
12769                          (match_operand:SI 4 "const_int_operand" ""))))]
12770   "TARGET_LDRD && TARGET_THUMB2 && reload_completed
12771      && current_tune->prefer_ldrd_strd
12772      && ((INTVAL (operands[2]) + 4) == INTVAL (operands[4]))
12773      && (operands_ok_ldrd_strd (operands[0], operands[3],
12774                                   operands[1], INTVAL (operands[2]),
12775                                   false, true))"
12776   "ldrd%?\t%0, %3, [%1, %2]"
12777   [(set_attr "type" "load2")
12778    (set_attr "predicable" "yes")
12779    (set_attr "predicable_short_it" "no")])
12781 (define_insn "*thumb2_ldrd_base"
12782   [(set (match_operand:SI 0 "s_register_operand" "=r")
12783         (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
12784    (set (match_operand:SI 2 "s_register_operand" "=r")
12785         (mem:SI (plus:SI (match_dup 1)
12786                          (const_int 4))))]
12787   "TARGET_LDRD && TARGET_THUMB2 && reload_completed
12788      && current_tune->prefer_ldrd_strd
12789      && (operands_ok_ldrd_strd (operands[0], operands[2],
12790                                   operands[1], 0, false, true))"
12791   "ldrd%?\t%0, %2, [%1]"
12792   [(set_attr "type" "load2")
12793    (set_attr "predicable" "yes")
12794    (set_attr "predicable_short_it" "no")])
12796 (define_insn "*thumb2_ldrd_base_neg"
12797   [(set (match_operand:SI 0 "s_register_operand" "=r")
12798         (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "rk")
12799                          (const_int -4))))
12800    (set (match_operand:SI 2 "s_register_operand" "=r")
12801         (mem:SI (match_dup 1)))]
12802   "TARGET_LDRD && TARGET_THUMB2 && reload_completed
12803      && current_tune->prefer_ldrd_strd
12804      && (operands_ok_ldrd_strd (operands[0], operands[2],
12805                                   operands[1], -4, false, true))"
12806   "ldrd%?\t%0, %2, [%1, #-4]"
12807   [(set_attr "type" "load2")
12808    (set_attr "predicable" "yes")
12809    (set_attr "predicable_short_it" "no")])
12811 (define_insn "*thumb2_strd"
12812   [(set (mem:SI (plus:SI (match_operand:SI 0 "s_register_operand" "rk")
12813                          (match_operand:SI 1 "ldrd_strd_offset_operand" "Do")))
12814         (match_operand:SI 2 "s_register_operand" "r"))
12815    (set (mem:SI (plus:SI (match_dup 0)
12816                          (match_operand:SI 3 "const_int_operand" "")))
12817         (match_operand:SI 4 "s_register_operand" "r"))]
12818   "TARGET_LDRD && TARGET_THUMB2 && reload_completed
12819      && current_tune->prefer_ldrd_strd
12820      && ((INTVAL (operands[1]) + 4) == INTVAL (operands[3]))
12821      && (operands_ok_ldrd_strd (operands[2], operands[4],
12822                                   operands[0], INTVAL (operands[1]),
12823                                   false, false))"
12824   "strd%?\t%2, %4, [%0, %1]"
12825   [(set_attr "type" "store2")
12826    (set_attr "predicable" "yes")
12827    (set_attr "predicable_short_it" "no")])
12829 (define_insn "*thumb2_strd_base"
12830   [(set (mem:SI (match_operand:SI 0 "s_register_operand" "rk"))
12831         (match_operand:SI 1 "s_register_operand" "r"))
12832    (set (mem:SI (plus:SI (match_dup 0)
12833                          (const_int 4)))
12834         (match_operand:SI 2 "s_register_operand" "r"))]
12835   "TARGET_LDRD && TARGET_THUMB2 && reload_completed
12836      && current_tune->prefer_ldrd_strd
12837      && (operands_ok_ldrd_strd (operands[1], operands[2],
12838                                   operands[0], 0, false, false))"
12839   "strd%?\t%1, %2, [%0]"
12840   [(set_attr "type" "store2")
12841    (set_attr "predicable" "yes")
12842    (set_attr "predicable_short_it" "no")])
12844 (define_insn "*thumb2_strd_base_neg"
12845   [(set (mem:SI (plus:SI (match_operand:SI 0 "s_register_operand" "rk")
12846                          (const_int -4)))
12847         (match_operand:SI 1 "s_register_operand" "r"))
12848    (set (mem:SI (match_dup 0))
12849         (match_operand:SI 2 "s_register_operand" "r"))]
12850   "TARGET_LDRD && TARGET_THUMB2 && reload_completed
12851      && current_tune->prefer_ldrd_strd
12852      && (operands_ok_ldrd_strd (operands[1], operands[2],
12853                                   operands[0], -4, false, false))"
12854   "strd%?\t%1, %2, [%0, #-4]"
12855   [(set_attr "type" "store2")
12856    (set_attr "predicable" "yes")
12857    (set_attr "predicable_short_it" "no")])
12859 ;; ARMv8 CRC32 instructions.
12860 (define_insn "<crc_variant>"
12861   [(set (match_operand:SI 0 "s_register_operand" "=r")
12862         (unspec:SI [(match_operand:SI 1 "s_register_operand" "r")
12863                     (match_operand:<crc_mode> 2 "s_register_operand" "r")]
12864          CRC))]
12865   "TARGET_CRC32"
12866   "<crc_variant>\\t%0, %1, %2"
12867   [(set_attr "type" "crc")
12868    (set_attr "conds" "unconditional")]
12871 ;; Load the load/store double peephole optimizations.
12872 (include "ldrdstrd.md")
12874 ;; Load the load/store multiple patterns
12875 (include "ldmstm.md")
12877 ;; Patterns in ldmstm.md don't cover more than 4 registers. This pattern covers
12878 ;; large lists without explicit writeback generated for APCS_FRAME epilogue.
12879 (define_insn "*load_multiple"
12880   [(match_parallel 0 "load_multiple_operation"
12881     [(set (match_operand:SI 2 "s_register_operand" "=rk")
12882           (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
12883         ])]
12884   "TARGET_32BIT"
12885   "*
12886   {
12887     arm_output_multireg_pop (operands, /*return_pc=*/false,
12888                                        /*cond=*/const_true_rtx,
12889                                        /*reverse=*/false,
12890                                        /*update=*/false);
12891     return \"\";
12892   }
12893   "
12894   [(set_attr "predicable" "yes")]
12897 ;; Vector bits common to IWMMXT and Neon
12898 (include "vec-common.md")
12899 ;; Load the Intel Wireless Multimedia Extension patterns
12900 (include "iwmmxt.md")
12901 ;; Load the VFP co-processor patterns
12902 (include "vfp.md")
12903 ;; Thumb-2 patterns
12904 (include "thumb2.md")
12905 ;; Neon patterns
12906 (include "neon.md")
12907 ;; Crypto patterns
12908 (include "crypto.md")
12909 ;; Synchronization Primitives
12910 (include "sync.md")
12911 ;; Fixed-point patterns
12912 (include "arm-fixed.md")