RISC-V: Error if function declared with different interrupt modes.
[official-gcc.git] / gcc / config / arm / arm.md
blob361a02668b0cfc9780c68a1eaf4a56fdf69b3d9d
1 ;;- Machine description for ARM for GNU compiler
2 ;;  Copyright (C) 1991-2018 Free Software Foundation, Inc.
3 ;;  Contributed by Pieter `Tiggr' Schoenmakers (rcpieter@win.tue.nl)
4 ;;  and Martin Simmons (@harleqn.co.uk).
5 ;;  More major hacks by Richard Earnshaw (rearnsha@arm.com).
7 ;; This file is part of GCC.
9 ;; GCC is free software; you can redistribute it and/or modify it
10 ;; under the terms of the GNU General Public License as published
11 ;; by the Free Software Foundation; either version 3, or (at your
12 ;; option) any later version.
14 ;; GCC is distributed in the hope that it will be useful, but WITHOUT
15 ;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16 ;; or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
17 ;; License for more details.
19 ;; You should have received a copy of the GNU General Public License
20 ;; along with GCC; see the file COPYING3.  If not see
21 ;; <http://www.gnu.org/licenses/>.
23 ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
26 ;;---------------------------------------------------------------------------
27 ;; Constants
29 ;; Register numbers -- All machine registers should be defined here
30 (define_constants
31   [(R0_REGNUM         0)        ; First CORE register
32    (R1_REGNUM         1)        ; Second CORE register
33    (R4_REGNUM         4)        ; Fifth CORE register
34    (IP_REGNUM        12)        ; Scratch register
35    (SP_REGNUM        13)        ; Stack pointer
36    (LR_REGNUM        14)        ; Return address register
37    (PC_REGNUM        15)        ; Program counter
38    (LAST_ARM_REGNUM  15)        ;
39    (CC_REGNUM       100)        ; Condition code pseudo register
40    (VFPCC_REGNUM    101)        ; VFP Condition code pseudo register
41   ]
43 ;; 3rd operand to select_dominance_cc_mode
44 (define_constants
45   [(DOM_CC_X_AND_Y  0)
46    (DOM_CC_NX_OR_Y  1)
47    (DOM_CC_X_OR_Y   2)
48   ]
50 ;; conditional compare combination
51 (define_constants
52   [(CMP_CMP 0)
53    (CMN_CMP 1)
54    (CMP_CMN 2)
55    (CMN_CMN 3)
56    (NUM_OF_COND_CMP 4)
57   ]
61 ;;---------------------------------------------------------------------------
62 ;; Attributes
64 ;; Processor type.  This is created automatically from arm-cores.def.
65 (include "arm-tune.md")
67 ;; Instruction classification types
68 (include "types.md")
70 ; IS_THUMB is set to 'yes' when we are generating Thumb code, and 'no' when
71 ; generating ARM code.  This is used to control the length of some insn
72 ; patterns that share the same RTL in both ARM and Thumb code.
73 (define_attr "is_thumb" "yes,no"
74   (const (if_then_else (symbol_ref "TARGET_THUMB")
75                        (const_string "yes") (const_string "no"))))
77 ; IS_ARCH6 is set to 'yes' when we are generating code form ARMv6.
78 (define_attr "is_arch6" "no,yes" (const (symbol_ref "arm_arch6")))
80 ; IS_THUMB1 is set to 'yes' iff we are generating Thumb-1 code.
81 (define_attr "is_thumb1" "yes,no"
82   (const (if_then_else (symbol_ref "TARGET_THUMB1")
83                        (const_string "yes") (const_string "no"))))
85 ; Mark an instruction as suitable for "short IT" blocks in Thumb-2.
86 ; The arm_restrict_it flag enables the "short IT" feature which
87 ; restricts IT blocks to a single 16-bit instruction.
88 ; This attribute should only be used on 16-bit Thumb-2 instructions
89 ; which may be predicated (the "predicable" attribute must be set).
90 (define_attr "predicable_short_it" "no,yes" (const_string "no"))
92 ; Mark an instruction as suitable for "short IT" blocks in Thumb-2.
93 ; This attribute should only be used on instructions which may emit
94 ; an IT block in their expansion which is not a short IT.
95 (define_attr "enabled_for_short_it" "no,yes" (const_string "yes"))
97 ;; Operand number of an input operand that is shifted.  Zero if the
98 ;; given instruction does not shift one of its input operands.
99 (define_attr "shift" "" (const_int 0))
101 ;; [For compatibility with AArch64 in pipeline models]
102 ;; Attribute that specifies whether or not the instruction touches fp
103 ;; registers.
104 (define_attr "fp" "no,yes" (const_string "no"))
106 ; Floating Point Unit.  If we only have floating point emulation, then there
107 ; is no point in scheduling the floating point insns.  (Well, for best
108 ; performance we should try and group them together).
109 (define_attr "fpu" "none,vfp"
110   (const (symbol_ref "arm_fpu_attr")))
112 ; Predicated means that the insn form is conditionally executed based on a
113 ; predicate.  We default to 'no' because no Thumb patterns match this rule
114 ; and not all ARM insns do.
115 (define_attr "predicated" "yes,no" (const_string "no"))
117 ; LENGTH of an instruction (in bytes)
118 (define_attr "length" ""
119   (const_int 4))
121 ; The architecture which supports the instruction (or alternative).
122 ; This can be "a" for ARM, "t" for either of the Thumbs, "32" for
123 ; TARGET_32BIT, "t1" or "t2" to specify a specific Thumb mode.  "v6"
124 ; for ARM or Thumb-2 with arm_arch6, and nov6 for ARM without
125 ; arm_arch6.  "v6t2" for Thumb-2 with arm_arch6 and "v8mb" for ARMv8-M
126 ; Baseline.  This attribute is used to compute attribute "enabled",
127 ; use type "any" to enable an alternative in all cases.
128 (define_attr "arch" "any,a,t,32,t1,t2,v6,nov6,v6t2,v8mb,neon_for_64bits,avoid_neon_for_64bits,iwmmxt,iwmmxt2,armv6_or_vfpv3,neon"
129   (const_string "any"))
131 (define_attr "arch_enabled" "no,yes"
132   (cond [(eq_attr "arch" "any")
133          (const_string "yes")
135          (and (eq_attr "arch" "a")
136               (match_test "TARGET_ARM"))
137          (const_string "yes")
139          (and (eq_attr "arch" "t")
140               (match_test "TARGET_THUMB"))
141          (const_string "yes")
143          (and (eq_attr "arch" "t1")
144               (match_test "TARGET_THUMB1"))
145          (const_string "yes")
147          (and (eq_attr "arch" "t2")
148               (match_test "TARGET_THUMB2"))
149          (const_string "yes")
151          (and (eq_attr "arch" "32")
152               (match_test "TARGET_32BIT"))
153          (const_string "yes")
155          (and (eq_attr "arch" "v6")
156               (match_test "TARGET_32BIT && arm_arch6"))
157          (const_string "yes")
159          (and (eq_attr "arch" "nov6")
160               (match_test "TARGET_32BIT && !arm_arch6"))
161          (const_string "yes")
163          (and (eq_attr "arch" "v6t2")
164               (match_test "TARGET_32BIT && arm_arch6 && arm_arch_thumb2"))
165          (const_string "yes")
167          (and (eq_attr "arch" "v8mb")
168               (match_test "TARGET_THUMB1 && arm_arch8"))
169          (const_string "yes")
171          (and (eq_attr "arch" "avoid_neon_for_64bits")
172               (match_test "TARGET_NEON")
173               (not (match_test "TARGET_PREFER_NEON_64BITS")))
174          (const_string "yes")
176          (and (eq_attr "arch" "neon_for_64bits")
177               (match_test "TARGET_NEON")
178               (match_test "TARGET_PREFER_NEON_64BITS"))
179          (const_string "yes")
181          (and (eq_attr "arch" "iwmmxt2")
182               (match_test "TARGET_REALLY_IWMMXT2"))
183          (const_string "yes")
185          (and (eq_attr "arch" "armv6_or_vfpv3")
186               (match_test "arm_arch6 || TARGET_VFP3"))
187          (const_string "yes")
189          (and (eq_attr "arch" "neon")
190               (match_test "TARGET_NEON"))
191          (const_string "yes")
192         ]
194         (const_string "no")))
196 (define_attr "opt" "any,speed,size"
197   (const_string "any"))
199 (define_attr "opt_enabled" "no,yes"
200   (cond [(eq_attr "opt" "any")
201          (const_string "yes")
203          (and (eq_attr "opt" "speed")
204               (match_test "optimize_function_for_speed_p (cfun)"))
205          (const_string "yes")
207          (and (eq_attr "opt" "size")
208               (match_test "optimize_function_for_size_p (cfun)"))
209          (const_string "yes")]
210         (const_string "no")))
212 (define_attr "use_literal_pool" "no,yes"
213    (cond [(and (eq_attr "type" "f_loads,f_loadd")
214                (match_test "CONSTANT_P (operands[1])"))
215           (const_string "yes")]
216          (const_string "no")))
218 ; Enable all alternatives that are both arch_enabled and insn_enabled.
219 ; FIXME:: opt_enabled has been temporarily removed till the time we have
220 ; an attribute that allows the use of such alternatives.
221 ; This depends on caching of speed_p, size_p on a per
222 ; alternative basis. The problem is that the enabled attribute
223 ; cannot depend on any state that is not cached or is not constant
224 ; for a compilation unit. We probably need a generic "hot/cold"
225 ; alternative which if implemented can help with this. We disable this
226 ; until such a time as this is implemented and / or the improvements or
227 ; regressions with removing this attribute are double checked.
228 ; See ashldi3_neon and <shift>di3_neon in neon.md.
230  (define_attr "enabled" "no,yes"
231    (cond [(and (eq_attr "predicable_short_it" "no")
232                (and (eq_attr "predicated" "yes")
233                     (match_test "arm_restrict_it")))
234           (const_string "no")
236           (and (eq_attr "enabled_for_short_it" "no")
237                (match_test "arm_restrict_it"))
238           (const_string "no")
240           (eq_attr "arch_enabled" "no")
241           (const_string "no")]
242          (const_string "yes")))
244 ; POOL_RANGE is how far away from a constant pool entry that this insn
245 ; can be placed.  If the distance is zero, then this insn will never
246 ; reference the pool.
247 ; Note that for Thumb constant pools the PC value is rounded down to the
248 ; nearest multiple of four.  Therefore, THUMB2_POOL_RANGE (and POOL_RANGE for
249 ; Thumb insns) should be set to <max_range> - 2.
250 ; NEG_POOL_RANGE is nonzero for insns that can reference a constant pool entry
251 ; before its address.  It is set to <max_range> - (8 + <data_size>).
252 (define_attr "arm_pool_range" "" (const_int 0))
253 (define_attr "thumb2_pool_range" "" (const_int 0))
254 (define_attr "arm_neg_pool_range" "" (const_int 0))
255 (define_attr "thumb2_neg_pool_range" "" (const_int 0))
257 (define_attr "pool_range" ""
258   (cond [(eq_attr "is_thumb" "yes") (attr "thumb2_pool_range")]
259         (attr "arm_pool_range")))
260 (define_attr "neg_pool_range" ""
261   (cond [(eq_attr "is_thumb" "yes") (attr "thumb2_neg_pool_range")]
262         (attr "arm_neg_pool_range")))
264 ; An assembler sequence may clobber the condition codes without us knowing.
265 ; If such an insn references the pool, then we have no way of knowing how,
266 ; so use the most conservative value for pool_range.
267 (define_asm_attributes
268  [(set_attr "conds" "clob")
269   (set_attr "length" "4")
270   (set_attr "pool_range" "250")])
272 ; Load scheduling, set from the arm_ld_sched variable
273 ; initialized by arm_option_override()
274 (define_attr "ldsched" "no,yes" (const (symbol_ref "arm_ld_sched")))
276 ; condition codes: this one is used by final_prescan_insn to speed up
277 ; conditionalizing instructions.  It saves having to scan the rtl to see if
278 ; it uses or alters the condition codes.
280 ; USE means that the condition codes are used by the insn in the process of
281 ;   outputting code, this means (at present) that we can't use the insn in
282 ;   inlined branches
284 ; SET means that the purpose of the insn is to set the condition codes in a
285 ;   well defined manner.
287 ; CLOB means that the condition codes are altered in an undefined manner, if
288 ;   they are altered at all
290 ; UNCONDITIONAL means the instruction can not be conditionally executed and
291 ;   that the instruction does not use or alter the condition codes.
293 ; NOCOND means that the instruction does not use or alter the condition
294 ;   codes but can be converted into a conditionally exectuted instruction.
296 (define_attr "conds" "use,set,clob,unconditional,nocond"
297         (if_then_else
298          (ior (eq_attr "is_thumb1" "yes")
299               (eq_attr "type" "call"))
300          (const_string "clob")
301          (if_then_else (eq_attr "is_neon_type" "no")
302          (const_string "nocond")
303          (const_string "unconditional"))))
305 ; Predicable means that the insn can be conditionally executed based on
306 ; an automatically added predicate (additional patterns are generated by 
307 ; gen...).  We default to 'no' because no Thumb patterns match this rule
308 ; and not all ARM patterns do.
309 (define_attr "predicable" "no,yes" (const_string "no"))
311 ; Only model the write buffer for ARM6 and ARM7.  Earlier processors don't
312 ; have one.  Later ones, such as StrongARM, have write-back caches, so don't
313 ; suffer blockages enough to warrant modelling this (and it can adversely
314 ; affect the schedule).
315 (define_attr "model_wbuf" "no,yes" (const (symbol_ref "arm_tune_wbuf")))
317 ; WRITE_CONFLICT implies that a read following an unrelated write is likely
318 ; to stall the processor.  Used with model_wbuf above.
319 (define_attr "write_conflict" "no,yes"
320   (if_then_else (eq_attr "type"
321                  "block,call,load_4")
322                 (const_string "yes")
323                 (const_string "no")))
325 ; Classify the insns into those that take one cycle and those that take more
326 ; than one on the main cpu execution unit.
327 (define_attr "core_cycles" "single,multi"
328   (if_then_else (eq_attr "type"
329     "adc_imm, adc_reg, adcs_imm, adcs_reg, adr, alu_ext, alu_imm, alu_sreg,\
330     alu_shift_imm, alu_shift_reg, alu_dsp_reg, alus_ext, alus_imm, alus_sreg,\
331     alus_shift_imm, alus_shift_reg, bfm, csel, rev, logic_imm, logic_reg,\
332     logic_shift_imm, logic_shift_reg, logics_imm, logics_reg,\
333     logics_shift_imm, logics_shift_reg, extend, shift_imm, float, fcsel,\
334     wmmx_wor, wmmx_wxor, wmmx_wand, wmmx_wandn, wmmx_wmov, wmmx_tmcrr,\
335     wmmx_tmrrc, wmmx_wldr, wmmx_wstr, wmmx_tmcr, wmmx_tmrc, wmmx_wadd,\
336     wmmx_wsub, wmmx_wmul, wmmx_wmac, wmmx_wavg2, wmmx_tinsr, wmmx_textrm,\
337     wmmx_wshufh, wmmx_wcmpeq, wmmx_wcmpgt, wmmx_wmax, wmmx_wmin, wmmx_wpack,\
338     wmmx_wunpckih, wmmx_wunpckil, wmmx_wunpckeh, wmmx_wunpckel, wmmx_wror,\
339     wmmx_wsra, wmmx_wsrl, wmmx_wsll, wmmx_wmadd, wmmx_tmia, wmmx_tmiaph,\
340     wmmx_tmiaxy, wmmx_tbcst, wmmx_tmovmsk, wmmx_wacc, wmmx_waligni,\
341     wmmx_walignr, wmmx_tandc, wmmx_textrc, wmmx_torc, wmmx_torvsc, wmmx_wsad,\
342     wmmx_wabs, wmmx_wabsdiff, wmmx_waddsubhx, wmmx_wsubaddhx, wmmx_wavg4,\
343     wmmx_wmulw, wmmx_wqmulm, wmmx_wqmulwm, wmmx_waddbhus, wmmx_wqmiaxy,\
344     wmmx_wmiaxy, wmmx_wmiawxy, wmmx_wmerge")
345                 (const_string "single")
346                 (const_string "multi")))
348 ;; FAR_JUMP is "yes" if a BL instruction is used to generate a branch to a
349 ;; distant label.  Only applicable to Thumb code.
350 (define_attr "far_jump" "yes,no" (const_string "no"))
353 ;; The number of machine instructions this pattern expands to.
354 ;; Used for Thumb-2 conditional execution.
355 (define_attr "ce_count" "" (const_int 1))
357 ;;---------------------------------------------------------------------------
358 ;; Unspecs
360 (include "unspecs.md")
362 ;;---------------------------------------------------------------------------
363 ;; Mode iterators
365 (include "iterators.md")
367 ;;---------------------------------------------------------------------------
368 ;; Predicates
370 (include "predicates.md")
371 (include "constraints.md")
373 ;;---------------------------------------------------------------------------
374 ;; Pipeline descriptions
376 (define_attr "tune_cortexr4" "yes,no"
377   (const (if_then_else
378           (eq_attr "tune" "cortexr4,cortexr4f,cortexr5")
379           (const_string "yes")
380           (const_string "no"))))
382 ;; True if the generic scheduling description should be used.
384 (define_attr "generic_sched" "yes,no"
385   (const (if_then_else
386           (ior (eq_attr "tune" "fa526,fa626,fa606te,fa626te,fmp626,fa726te,\
387                                 arm926ejs,arm1020e,arm1026ejs,arm1136js,\
388                                 arm1136jfs,cortexa5,cortexa7,cortexa8,\
389                                 cortexa9,cortexa12,cortexa15,cortexa17,\
390                                 cortexa53,cortexa57,cortexm4,cortexm7,\
391                                 exynosm1,marvell_pj4,xgene1")
392                (eq_attr "tune_cortexr4" "yes"))
393           (const_string "no")
394           (const_string "yes"))))
396 (define_attr "generic_vfp" "yes,no"
397   (const (if_then_else
398           (and (eq_attr "fpu" "vfp")
399                (eq_attr "tune" "!arm1020e,arm1022e,cortexa5,cortexa7,\
400                                 cortexa8,cortexa9,cortexa53,cortexm4,\
401                                 cortexm7,marvell_pj4,xgene1")
402                (eq_attr "tune_cortexr4" "no"))
403           (const_string "yes")
404           (const_string "no"))))
406 (include "marvell-f-iwmmxt.md")
407 (include "arm-generic.md")
408 (include "arm926ejs.md")
409 (include "arm1020e.md")
410 (include "arm1026ejs.md")
411 (include "arm1136jfs.md")
412 (include "fa526.md")
413 (include "fa606te.md")
414 (include "fa626te.md")
415 (include "fmp626.md")
416 (include "fa726te.md")
417 (include "cortex-a5.md")
418 (include "cortex-a7.md")
419 (include "cortex-a8.md")
420 (include "cortex-a9.md")
421 (include "cortex-a15.md")
422 (include "cortex-a17.md")
423 (include "cortex-a53.md")
424 (include "cortex-a57.md")
425 (include "cortex-r4.md")
426 (include "cortex-r4f.md")
427 (include "cortex-m7.md")
428 (include "cortex-m4.md")
429 (include "cortex-m4-fpu.md")
430 (include "exynos-m1.md")
431 (include "vfp11.md")
432 (include "marvell-pj4.md")
433 (include "xgene1.md")
436 ;;---------------------------------------------------------------------------
437 ;; Insn patterns
439 ;; Addition insns.
441 ;; Note: For DImode insns, there is normally no reason why operands should
442 ;; not be in the same register, what we don't want is for something being
443 ;; written to partially overlap something that is an input.
445 (define_expand "adddi3"
446  [(parallel
447    [(set (match_operand:DI           0 "s_register_operand" "")
448           (plus:DI (match_operand:DI 1 "s_register_operand" "")
449                    (match_operand:DI 2 "arm_adddi_operand"  "")))
450     (clobber (reg:CC CC_REGNUM))])]
451   "TARGET_EITHER"
452   "
453   if (TARGET_THUMB1)
454     {
455       if (!REG_P (operands[1]))
456         operands[1] = force_reg (DImode, operands[1]);
457       if (!REG_P (operands[2]))
458         operands[2] = force_reg (DImode, operands[2]);
459      }
460   "
463 (define_insn_and_split "*arm_adddi3"
464   [(set (match_operand:DI          0 "arm_general_register_operand" "=&r,&r,&r,&r,&r")
465         (plus:DI (match_operand:DI 1 "arm_general_register_operand" "%0, 0, r, 0, r")
466                  (match_operand:DI 2 "arm_general_adddi_operand"    "r,  0, r, Dd, Dd")))
467    (clobber (reg:CC CC_REGNUM))]
468   "TARGET_32BIT && !TARGET_NEON"
469   "#"
470   "TARGET_32BIT && ((!TARGET_NEON && !TARGET_IWMMXT) || reload_completed)"
471   [(parallel [(set (reg:CC_C CC_REGNUM)
472                    (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
473                                  (match_dup 1)))
474               (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
475    (set (match_dup 3) (plus:SI (plus:SI (match_dup 4) (match_dup 5))
476                                (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
477   "
478   {
479     operands[3] = gen_highpart (SImode, operands[0]);
480     operands[0] = gen_lowpart (SImode, operands[0]);
481     operands[4] = gen_highpart (SImode, operands[1]);
482     operands[1] = gen_lowpart (SImode, operands[1]);
483     operands[5] = gen_highpart_mode (SImode, DImode, operands[2]);
484     operands[2] = gen_lowpart (SImode, operands[2]);
485   }"
486   [(set_attr "conds" "clob")
487    (set_attr "length" "8")
488    (set_attr "type" "multiple")]
491 (define_insn_and_split "*adddi_sesidi_di"
492   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
493         (plus:DI (sign_extend:DI
494                   (match_operand:SI 2 "s_register_operand" "r,r"))
495                  (match_operand:DI 1 "s_register_operand" "0,r")))
496    (clobber (reg:CC CC_REGNUM))]
497   "TARGET_32BIT"
498   "#"
499   "TARGET_32BIT && reload_completed"
500   [(parallel [(set (reg:CC_C CC_REGNUM)
501                    (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
502                                  (match_dup 1)))
503               (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
504    (set (match_dup 3) (plus:SI (plus:SI (ashiftrt:SI (match_dup 2)
505                                                      (const_int 31))
506                                         (match_dup 4))
507                                (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
508   "
509   {
510     operands[3] = gen_highpart (SImode, operands[0]);
511     operands[0] = gen_lowpart (SImode, operands[0]);
512     operands[4] = gen_highpart (SImode, operands[1]);
513     operands[1] = gen_lowpart (SImode, operands[1]);
514     operands[2] = gen_lowpart (SImode, operands[2]);
515   }"
516   [(set_attr "conds" "clob")
517    (set_attr "length" "8")
518    (set_attr "type" "multiple")]
521 (define_insn_and_split "*adddi_zesidi_di"
522   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
523         (plus:DI (zero_extend:DI
524                   (match_operand:SI 2 "s_register_operand" "r,r"))
525                  (match_operand:DI 1 "s_register_operand" "0,r")))
526    (clobber (reg:CC CC_REGNUM))]
527   "TARGET_32BIT"
528   "#"
529   "TARGET_32BIT && reload_completed"
530   [(parallel [(set (reg:CC_C CC_REGNUM)
531                    (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
532                                  (match_dup 1)))
533               (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
534    (set (match_dup 3) (plus:SI (plus:SI (match_dup 4) (const_int 0))
535                                (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
536   "
537   {
538     operands[3] = gen_highpart (SImode, operands[0]);
539     operands[0] = gen_lowpart (SImode, operands[0]);
540     operands[4] = gen_highpart (SImode, operands[1]);
541     operands[1] = gen_lowpart (SImode, operands[1]);
542     operands[2] = gen_lowpart (SImode, operands[2]);
543   }"
544   [(set_attr "conds" "clob")
545    (set_attr "length" "8")
546    (set_attr "type" "multiple")]
549 (define_expand "addv<mode>4"
550   [(match_operand:SIDI 0 "register_operand")
551    (match_operand:SIDI 1 "register_operand")
552    (match_operand:SIDI 2 "register_operand")
553    (match_operand 3 "")]
554   "TARGET_32BIT"
556   emit_insn (gen_add<mode>3_compareV (operands[0], operands[1], operands[2]));
557   arm_gen_unlikely_cbranch (NE, CC_Vmode, operands[3]);
559   DONE;
562 (define_expand "uaddv<mode>4"
563   [(match_operand:SIDI 0 "register_operand")
564    (match_operand:SIDI 1 "register_operand")
565    (match_operand:SIDI 2 "register_operand")
566    (match_operand 3 "")]
567   "TARGET_32BIT"
569   emit_insn (gen_add<mode>3_compareC (operands[0], operands[1], operands[2]));
570   arm_gen_unlikely_cbranch (NE, CC_Cmode, operands[3]);
572   DONE;
575 (define_expand "addsi3"
576   [(set (match_operand:SI          0 "s_register_operand" "")
577         (plus:SI (match_operand:SI 1 "s_register_operand" "")
578                  (match_operand:SI 2 "reg_or_int_operand" "")))]
579   "TARGET_EITHER"
580   "
581   if (TARGET_32BIT && CONST_INT_P (operands[2]))
582     {
583       arm_split_constant (PLUS, SImode, NULL_RTX,
584                           INTVAL (operands[2]), operands[0], operands[1],
585                           optimize && can_create_pseudo_p ());
586       DONE;
587     }
588   "
591 ; If there is a scratch available, this will be faster than synthesizing the
592 ; addition.
593 (define_peephole2
594   [(match_scratch:SI 3 "r")
595    (set (match_operand:SI          0 "arm_general_register_operand" "")
596         (plus:SI (match_operand:SI 1 "arm_general_register_operand" "")
597                  (match_operand:SI 2 "const_int_operand"  "")))]
598   "TARGET_32BIT &&
599    !(const_ok_for_arm (INTVAL (operands[2]))
600      || const_ok_for_arm (-INTVAL (operands[2])))
601     && const_ok_for_arm (~INTVAL (operands[2]))"
602   [(set (match_dup 3) (match_dup 2))
603    (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 3)))]
604   ""
607 ;; The r/r/k alternative is required when reloading the address
608 ;;  (plus (reg rN) (reg sp)) into (reg rN).  In this case reload will
609 ;; put the duplicated register first, and not try the commutative version.
610 (define_insn_and_split "*arm_addsi3"
611   [(set (match_operand:SI          0 "s_register_operand" "=rk,l,l ,l ,r ,k ,r,k ,r ,k ,r ,k,k,r ,k ,r")
612         (plus:SI (match_operand:SI 1 "s_register_operand" "%0 ,l,0 ,l ,rk,k ,r,r ,rk,k ,rk,k,r,rk,k ,rk")
613                  (match_operand:SI 2 "reg_or_int_operand" "rk ,l,Py,Pd,rI,rI,k,rI,Pj,Pj,L ,L,L,PJ,PJ,?n")))]
614   "TARGET_32BIT"
615   "@
616    add%?\\t%0, %0, %2
617    add%?\\t%0, %1, %2
618    add%?\\t%0, %1, %2
619    add%?\\t%0, %1, %2
620    add%?\\t%0, %1, %2
621    add%?\\t%0, %1, %2
622    add%?\\t%0, %2, %1
623    add%?\\t%0, %1, %2
624    addw%?\\t%0, %1, %2
625    addw%?\\t%0, %1, %2
626    sub%?\\t%0, %1, #%n2
627    sub%?\\t%0, %1, #%n2
628    sub%?\\t%0, %1, #%n2
629    subw%?\\t%0, %1, #%n2
630    subw%?\\t%0, %1, #%n2
631    #"
632   "TARGET_32BIT
633    && CONST_INT_P (operands[2])
634    && !const_ok_for_op (INTVAL (operands[2]), PLUS)
635    && (reload_completed || !arm_eliminable_register (operands[1]))"
636   [(clobber (const_int 0))]
637   "
638   arm_split_constant (PLUS, SImode, curr_insn,
639                       INTVAL (operands[2]), operands[0],
640                       operands[1], 0);
641   DONE;
642   "
643   [(set_attr "length" "2,4,4,4,4,4,4,4,4,4,4,4,4,4,4,16")
644    (set_attr "predicable" "yes")
645    (set_attr "predicable_short_it" "yes,yes,yes,yes,no,no,no,no,no,no,no,no,no,no,no,no")
646    (set_attr "arch" "t2,t2,t2,t2,*,*,*,a,t2,t2,*,*,a,t2,t2,*")
647    (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
648                       (const_string "alu_imm")
649                       (const_string "alu_sreg")))
653 (define_insn_and_split "adddi3_compareV"
654   [(set (reg:CC_V CC_REGNUM)
655         (ne:CC_V
656           (plus:TI
657             (sign_extend:TI (match_operand:DI 1 "register_operand" "r"))
658             (sign_extend:TI (match_operand:DI 2 "register_operand" "r")))
659           (sign_extend:TI (plus:DI (match_dup 1) (match_dup 2)))))
660    (set (match_operand:DI 0 "register_operand" "=&r")
661         (plus:DI (match_dup 1) (match_dup 2)))]
662   "TARGET_32BIT"
663   "#"
664   "&& reload_completed"
665   [(parallel [(set (reg:CC_C CC_REGNUM)
666                    (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
667                                  (match_dup 1)))
668               (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
669    (parallel [(set (reg:CC_V CC_REGNUM)
670                    (ne:CC_V
671                     (plus:DI (plus:DI
672                               (sign_extend:DI (match_dup 4))
673                               (sign_extend:DI (match_dup 5)))
674                              (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0)))
675                     (plus:DI (sign_extend:DI
676                               (plus:SI (match_dup 4) (match_dup 5)))
677                              (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0)))))
678              (set (match_dup 3) (plus:SI (plus:SI
679                                           (match_dup 4) (match_dup 5))
680                                          (ltu:SI (reg:CC_C CC_REGNUM)
681                                                  (const_int 0))))])]
682   "
683   {
684     operands[3] = gen_highpart (SImode, operands[0]);
685     operands[0] = gen_lowpart (SImode, operands[0]);
686     operands[4] = gen_highpart (SImode, operands[1]);
687     operands[1] = gen_lowpart (SImode, operands[1]);
688     operands[5] = gen_highpart (SImode, operands[2]);
689     operands[2] = gen_lowpart (SImode, operands[2]);
690   }"
691  [(set_attr "conds" "set")
692    (set_attr "length" "8")
693    (set_attr "type" "multiple")]
696 (define_insn "addsi3_compareV"
697   [(set (reg:CC_V CC_REGNUM)
698         (ne:CC_V
699           (plus:DI
700             (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
701             (sign_extend:DI (match_operand:SI 2 "register_operand" "r")))
702           (sign_extend:DI (plus:SI (match_dup 1) (match_dup 2)))))
703    (set (match_operand:SI 0 "register_operand" "=r")
704         (plus:SI (match_dup 1) (match_dup 2)))]
705   "TARGET_32BIT"
706   "adds%?\\t%0, %1, %2"
707   [(set_attr "conds" "set")
708    (set_attr "type" "alus_sreg")]
711 (define_insn "*addsi3_compareV_upper"
712   [(set (reg:CC_V CC_REGNUM)
713         (ne:CC_V
714           (plus:DI
715            (plus:DI
716             (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
717             (sign_extend:DI (match_operand:SI 2 "register_operand" "r")))
718            (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0)))
719           (plus:DI (sign_extend:DI
720                     (plus:SI (match_dup 1) (match_dup 2)))
721                    (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0)))))
722    (set (match_operand:SI 0 "register_operand" "=r")
723         (plus:SI
724          (plus:SI (match_dup 1) (match_dup 2))
725          (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
726   "TARGET_32BIT"
727   "adcs%?\\t%0, %1, %2"
728   [(set_attr "conds" "set")
729    (set_attr "type" "adcs_reg")]
732 (define_insn_and_split "adddi3_compareC"
733   [(set (reg:CC_C CC_REGNUM)
734         (ne:CC_C
735           (plus:TI
736             (zero_extend:TI (match_operand:DI 1 "register_operand" "r"))
737             (zero_extend:TI (match_operand:DI 2 "register_operand" "r")))
738           (zero_extend:TI (plus:DI (match_dup 1) (match_dup 2)))))
739    (set (match_operand:DI 0 "register_operand" "=&r")
740         (plus:DI (match_dup 1) (match_dup 2)))]
741   "TARGET_32BIT"
742   "#"
743   "&& reload_completed"
744   [(parallel [(set (reg:CC_C CC_REGNUM)
745                    (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
746                                  (match_dup 1)))
747               (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
748    (parallel [(set (reg:CC_C CC_REGNUM)
749                    (ne:CC_C
750                     (plus:DI (plus:DI
751                               (zero_extend:DI (match_dup 4))
752                               (zero_extend:DI (match_dup 5)))
753                              (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0)))
754                     (plus:DI (zero_extend:DI
755                               (plus:SI (match_dup 4) (match_dup 5)))
756                              (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0)))))
757              (set (match_dup 3) (plus:SI
758                                  (plus:SI (match_dup 4) (match_dup 5))
759                                  (ltu:SI (reg:CC_C CC_REGNUM)
760                                          (const_int 0))))])]
761   "
762   {
763     operands[3] = gen_highpart (SImode, operands[0]);
764     operands[0] = gen_lowpart (SImode, operands[0]);
765     operands[4] = gen_highpart (SImode, operands[1]);
766     operands[5] = gen_highpart (SImode, operands[2]);
767     operands[1] = gen_lowpart (SImode, operands[1]);
768     operands[2] = gen_lowpart (SImode, operands[2]);
769   }"
770  [(set_attr "conds" "set")
771    (set_attr "length" "8")
772    (set_attr "type" "multiple")]
775 (define_insn "*addsi3_compareC_upper"
776   [(set (reg:CC_C CC_REGNUM)
777         (ne:CC_C
778           (plus:DI
779            (plus:DI
780             (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
781             (zero_extend:DI (match_operand:SI 2 "register_operand" "r")))
782            (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0)))
783           (plus:DI (zero_extend:DI
784                     (plus:SI (match_dup 1) (match_dup 2)))
785                    (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0)))))
786    (set (match_operand:SI 0 "register_operand" "=r")
787         (plus:SI
788          (plus:SI (match_dup 1) (match_dup 2))
789          (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
790   "TARGET_32BIT"
791   "adcs%?\\t%0, %1, %2"
792   [(set_attr "conds" "set")
793    (set_attr "type" "adcs_reg")]
796 (define_insn "addsi3_compareC"
797    [(set (reg:CC_C CC_REGNUM)
798          (ne:CC_C
799           (plus:DI
800            (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
801            (zero_extend:DI (match_operand:SI 2 "register_operand" "r")))
802           (zero_extend:DI
803            (plus:SI (match_dup 1) (match_dup 2)))))
804     (set (match_operand:SI 0 "register_operand" "=r")
805          (plus:SI (match_dup 1) (match_dup 2)))]
806   "TARGET_32BIT"
807   "adds%?\\t%0, %1, %2"
808   [(set_attr "conds" "set")
809    (set_attr "type" "alus_sreg")]
812 (define_insn "addsi3_compare0"
813   [(set (reg:CC_NOOV CC_REGNUM)
814         (compare:CC_NOOV
815          (plus:SI (match_operand:SI 1 "s_register_operand" "r, r,r")
816                   (match_operand:SI 2 "arm_add_operand"    "I,L,r"))
817          (const_int 0)))
818    (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
819         (plus:SI (match_dup 1) (match_dup 2)))]
820   "TARGET_ARM"
821   "@
822    adds%?\\t%0, %1, %2
823    subs%?\\t%0, %1, #%n2
824    adds%?\\t%0, %1, %2"
825   [(set_attr "conds" "set")
826    (set_attr "type" "alus_imm,alus_imm,alus_sreg")]
829 (define_insn "*addsi3_compare0_scratch"
830   [(set (reg:CC_NOOV CC_REGNUM)
831         (compare:CC_NOOV
832          (plus:SI (match_operand:SI 0 "s_register_operand" "r, r, r")
833                   (match_operand:SI 1 "arm_add_operand"    "I,L, r"))
834          (const_int 0)))]
835   "TARGET_ARM"
836   "@
837    cmn%?\\t%0, %1
838    cmp%?\\t%0, #%n1
839    cmn%?\\t%0, %1"
840   [(set_attr "conds" "set")
841    (set_attr "predicable" "yes")
842    (set_attr "type" "alus_imm,alus_imm,alus_sreg")]
845 (define_insn "*compare_negsi_si"
846   [(set (reg:CC_Z CC_REGNUM)
847         (compare:CC_Z
848          (neg:SI (match_operand:SI 0 "s_register_operand" "l,r"))
849          (match_operand:SI 1 "s_register_operand" "l,r")))]
850   "TARGET_32BIT"
851   "cmn%?\\t%1, %0"
852   [(set_attr "conds" "set")
853    (set_attr "predicable" "yes")
854    (set_attr "arch" "t2,*")
855    (set_attr "length" "2,4")
856    (set_attr "predicable_short_it" "yes,no")
857    (set_attr "type" "alus_sreg")]
860 ;; This is the canonicalization of addsi3_compare0_for_combiner when the
861 ;; addend is a constant.
862 (define_insn "cmpsi2_addneg"
863   [(set (reg:CC CC_REGNUM)
864         (compare:CC
865          (match_operand:SI 1 "s_register_operand" "r,r")
866          (match_operand:SI 2 "arm_addimm_operand" "L,I")))
867    (set (match_operand:SI 0 "s_register_operand" "=r,r")
868         (plus:SI (match_dup 1)
869                  (match_operand:SI 3 "arm_addimm_operand" "I,L")))]
870   "TARGET_32BIT && INTVAL (operands[2]) == -INTVAL (operands[3])"
871   "@
872    adds%?\\t%0, %1, %3
873    subs%?\\t%0, %1, #%n3"
874   [(set_attr "conds" "set")
875    (set_attr "type" "alus_sreg")]
878 ;; Convert the sequence
879 ;;  sub  rd, rn, #1
880 ;;  cmn  rd, #1 (equivalent to cmp rd, #-1)
881 ;;  bne  dest
882 ;; into
883 ;;  subs rd, rn, #1
884 ;;  bcs  dest   ((unsigned)rn >= 1)
885 ;; similarly for the beq variant using bcc.
886 ;; This is a common looping idiom (while (n--))
887 (define_peephole2
888   [(set (match_operand:SI 0 "arm_general_register_operand" "")
889         (plus:SI (match_operand:SI 1 "arm_general_register_operand" "")
890                  (const_int -1)))
891    (set (match_operand 2 "cc_register" "")
892         (compare (match_dup 0) (const_int -1)))
893    (set (pc)
894         (if_then_else (match_operator 3 "equality_operator"
895                        [(match_dup 2) (const_int 0)])
896                       (match_operand 4 "" "")
897                       (match_operand 5 "" "")))]
898   "TARGET_32BIT && peep2_reg_dead_p (3, operands[2])"
899   [(parallel[
900     (set (match_dup 2)
901          (compare:CC
902           (match_dup 1) (const_int 1)))
903     (set (match_dup 0) (plus:SI (match_dup 1) (const_int -1)))])
904    (set (pc)
905         (if_then_else (match_op_dup 3 [(match_dup 2) (const_int 0)])
906                       (match_dup 4)
907                       (match_dup 5)))]
908   "operands[2] = gen_rtx_REG (CCmode, CC_REGNUM);
909    operands[3] = gen_rtx_fmt_ee ((GET_CODE (operands[3]) == NE
910                                   ? GEU : LTU),
911                                  VOIDmode, 
912                                  operands[2], const0_rtx);"
915 ;; The next four insns work because they compare the result with one of
916 ;; the operands, and we know that the use of the condition code is
917 ;; either GEU or LTU, so we can use the carry flag from the addition
918 ;; instead of doing the compare a second time.
919 (define_insn "*addsi3_compare_op1"
920   [(set (reg:CC_C CC_REGNUM)
921         (compare:CC_C
922          (plus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
923                   (match_operand:SI 2 "arm_add_operand" "I,L,r"))
924          (match_dup 1)))
925    (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
926         (plus:SI (match_dup 1) (match_dup 2)))]
927   "TARGET_32BIT"
928   "@
929    adds%?\\t%0, %1, %2
930    subs%?\\t%0, %1, #%n2
931    adds%?\\t%0, %1, %2"
932   [(set_attr "conds" "set")
933    (set_attr "type"  "alus_imm,alus_imm,alus_sreg")]
936 (define_insn "*addsi3_compare_op2"
937   [(set (reg:CC_C CC_REGNUM)
938         (compare:CC_C
939          (plus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
940                   (match_operand:SI 2 "arm_add_operand" "I,L,r"))
941          (match_dup 2)))
942    (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
943         (plus:SI (match_dup 1) (match_dup 2)))]
944   "TARGET_32BIT"
945   "@
946    adds%?\\t%0, %1, %2
947    subs%?\\t%0, %1, #%n2
948    adds%?\\t%0, %1, %2"
949   [(set_attr "conds" "set")
950    (set_attr "type" "alus_imm,alus_imm,alus_sreg")]
953 (define_insn "*compare_addsi2_op0"
954   [(set (reg:CC_C CC_REGNUM)
955         (compare:CC_C
956           (plus:SI (match_operand:SI 0 "s_register_operand" "l,l,r,r,r")
957                    (match_operand:SI 1 "arm_add_operand" "Pv,l,I,L,r"))
958           (match_dup 0)))]
959   "TARGET_32BIT"
960   "@
961    cmp%?\\t%0, #%n1
962    cmn%?\\t%0, %1
963    cmn%?\\t%0, %1
964    cmp%?\\t%0, #%n1
965    cmn%?\\t%0, %1"
966   [(set_attr "conds" "set")
967    (set_attr "predicable" "yes")
968    (set_attr "arch" "t2,t2,*,*,*")
969    (set_attr "predicable_short_it" "yes,yes,no,no,no")
970    (set_attr "length" "2,2,4,4,4")
971    (set_attr "type" "alus_imm,alus_sreg,alus_imm,alus_imm,alus_sreg")]
974 (define_insn "*compare_addsi2_op1"
975   [(set (reg:CC_C CC_REGNUM)
976         (compare:CC_C
977           (plus:SI (match_operand:SI 0 "s_register_operand" "l,l,r,r,r")
978                    (match_operand:SI 1 "arm_add_operand" "Pv,l,I,L,r"))
979           (match_dup 1)))]
980   "TARGET_32BIT"
981   "@
982    cmp%?\\t%0, #%n1
983    cmn%?\\t%0, %1
984    cmn%?\\t%0, %1
985    cmp%?\\t%0, #%n1
986    cmn%?\\t%0, %1"
987   [(set_attr "conds" "set")
988    (set_attr "predicable" "yes")
989    (set_attr "arch" "t2,t2,*,*,*")
990    (set_attr "predicable_short_it" "yes,yes,no,no,no")
991    (set_attr "length" "2,2,4,4,4")
992    (set_attr "type" "alus_imm,alus_sreg,alus_imm,alus_imm,alus_sreg")]
995 (define_insn "*addsi3_carryin_<optab>"
996   [(set (match_operand:SI 0 "s_register_operand" "=l,r,r")
997         (plus:SI (plus:SI (match_operand:SI 1 "s_register_operand" "%l,r,r")
998                           (match_operand:SI 2 "arm_not_operand" "0,rI,K"))
999                  (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))))]
1000   "TARGET_32BIT"
1001   "@
1002    adc%?\\t%0, %1, %2
1003    adc%?\\t%0, %1, %2
1004    sbc%?\\t%0, %1, #%B2"
1005   [(set_attr "conds" "use")
1006    (set_attr "predicable" "yes")
1007    (set_attr "arch" "t2,*,*")
1008    (set_attr "length" "4")
1009    (set_attr "predicable_short_it" "yes,no,no")
1010    (set_attr "type" "adc_reg,adc_reg,adc_imm")]
1013 (define_insn "*addsi3_carryin_alt2_<optab>"
1014   [(set (match_operand:SI 0 "s_register_operand" "=l,r,r")
1015         (plus:SI (plus:SI (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))
1016                           (match_operand:SI 1 "s_register_operand" "%l,r,r"))
1017                  (match_operand:SI 2 "arm_rhs_operand" "l,rI,K")))]
1018   "TARGET_32BIT"
1019   "@
1020    adc%?\\t%0, %1, %2
1021    adc%?\\t%0, %1, %2
1022    sbc%?\\t%0, %1, #%B2"
1023   [(set_attr "conds" "use")
1024    (set_attr "predicable" "yes")
1025    (set_attr "arch" "t2,*,*")
1026    (set_attr "length" "4")
1027    (set_attr "predicable_short_it" "yes,no,no")
1028    (set_attr "type" "adc_reg,adc_reg,adc_imm")]
1031 (define_insn "*addsi3_carryin_shift_<optab>"
1032   [(set (match_operand:SI 0 "s_register_operand" "=r")
1033         (plus:SI (plus:SI
1034                   (match_operator:SI 2 "shift_operator"
1035                     [(match_operand:SI 3 "s_register_operand" "r")
1036                      (match_operand:SI 4 "reg_or_int_operand" "rM")])
1037                   (match_operand:SI 1 "s_register_operand" "r"))
1038                  (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))))]
1039   "TARGET_32BIT"
1040   "adc%?\\t%0, %1, %3%S2"
1041   [(set_attr "conds" "use")
1042    (set_attr "predicable" "yes")
1043    (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
1044                       (const_string "alu_shift_imm")
1045                       (const_string "alu_shift_reg")))]
1048 (define_insn "*addsi3_carryin_clobercc_<optab>"
1049   [(set (match_operand:SI 0 "s_register_operand" "=r")
1050         (plus:SI (plus:SI (match_operand:SI 1 "s_register_operand" "%r")
1051                           (match_operand:SI 2 "arm_rhs_operand" "rI"))
1052                  (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))))
1053    (clobber (reg:CC CC_REGNUM))]
1054    "TARGET_32BIT"
1055    "adcs%?\\t%0, %1, %2"
1056    [(set_attr "conds" "set")
1057     (set_attr "type" "adcs_reg")]
1060 (define_expand "subv<mode>4"
1061   [(match_operand:SIDI 0 "register_operand")
1062    (match_operand:SIDI 1 "register_operand")
1063    (match_operand:SIDI 2 "register_operand")
1064    (match_operand 3 "")]
1065   "TARGET_32BIT"
1067   emit_insn (gen_sub<mode>3_compare1 (operands[0], operands[1], operands[2]));
1068   arm_gen_unlikely_cbranch (NE, CC_Vmode, operands[3]);
1070   DONE;
1073 (define_expand "usubv<mode>4"
1074   [(match_operand:SIDI 0 "register_operand")
1075    (match_operand:SIDI 1 "register_operand")
1076    (match_operand:SIDI 2 "register_operand")
1077    (match_operand 3 "")]
1078   "TARGET_32BIT"
1080   emit_insn (gen_sub<mode>3_compare1 (operands[0], operands[1], operands[2]));
1081   arm_gen_unlikely_cbranch (LTU, CCmode, operands[3]);
1083   DONE;
1086 (define_insn_and_split "subdi3_compare1"
1087   [(set (reg:CC CC_REGNUM)
1088         (compare:CC
1089           (match_operand:DI 1 "register_operand" "r")
1090           (match_operand:DI 2 "register_operand" "r")))
1091    (set (match_operand:DI 0 "register_operand" "=&r")
1092         (minus:DI (match_dup 1) (match_dup 2)))]
1093   "TARGET_32BIT"
1094   "#"
1095   "&& reload_completed"
1096   [(parallel [(set (reg:CC CC_REGNUM)
1097                    (compare:CC (match_dup 1) (match_dup 2)))
1098               (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1099    (parallel [(set (reg:CC CC_REGNUM)
1100                    (compare:CC (match_dup 4) (match_dup 5)))
1101              (set (match_dup 3) (minus:SI (minus:SI (match_dup 4) (match_dup 5))
1102                                (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))])]
1103   {
1104     operands[3] = gen_highpart (SImode, operands[0]);
1105     operands[0] = gen_lowpart (SImode, operands[0]);
1106     operands[4] = gen_highpart (SImode, operands[1]);
1107     operands[1] = gen_lowpart (SImode, operands[1]);
1108     operands[5] = gen_highpart (SImode, operands[2]);
1109     operands[2] = gen_lowpart (SImode, operands[2]);
1110    }
1111   [(set_attr "conds" "set")
1112    (set_attr "length" "8")
1113    (set_attr "type" "multiple")]
1116 (define_insn "subsi3_compare1"
1117   [(set (reg:CC CC_REGNUM)
1118         (compare:CC
1119           (match_operand:SI 1 "register_operand" "r")
1120           (match_operand:SI 2 "register_operand" "r")))
1121    (set (match_operand:SI 0 "register_operand" "=r")
1122         (minus:SI (match_dup 1) (match_dup 2)))]
1123   "TARGET_32BIT"
1124   "subs%?\\t%0, %1, %2"
1125   [(set_attr "conds" "set")
1126    (set_attr "type" "alus_sreg")]
1129 (define_insn "*subsi3_carryin"
1130   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
1131         (minus:SI (minus:SI (match_operand:SI 1 "reg_or_int_operand" "r,I,Pz")
1132                             (match_operand:SI 2 "s_register_operand" "r,r,r"))
1133                   (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1134   "TARGET_32BIT"
1135   "@
1136    sbc%?\\t%0, %1, %2
1137    rsc%?\\t%0, %2, %1
1138    sbc%?\\t%0, %2, %2, lsl #1"
1139   [(set_attr "conds" "use")
1140    (set_attr "arch" "*,a,t2")
1141    (set_attr "predicable" "yes")
1142    (set_attr "type" "adc_reg,adc_imm,alu_shift_imm")]
1145 (define_insn "*subsi3_carryin_const"
1146   [(set (match_operand:SI 0 "s_register_operand" "=r")
1147         (minus:SI (plus:SI (match_operand:SI 1 "s_register_operand" "r")
1148                            (match_operand:SI 2 "arm_not_immediate_operand" "K"))
1149                   (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1150   "TARGET_32BIT"
1151   "sbc\\t%0, %1, #%B2"
1152   [(set_attr "conds" "use")
1153    (set_attr "type" "adc_imm")]
1156 (define_insn "*subsi3_carryin_compare"
1157   [(set (reg:CC CC_REGNUM)
1158         (compare:CC (match_operand:SI 1 "s_register_operand" "r")
1159                     (match_operand:SI 2 "s_register_operand" "r")))
1160    (set (match_operand:SI 0 "s_register_operand" "=r")
1161         (minus:SI (minus:SI (match_dup 1)
1162                             (match_dup 2))
1163                   (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1164   "TARGET_32BIT"
1165   "sbcs\\t%0, %1, %2"
1166   [(set_attr "conds" "set")
1167    (set_attr "type" "adcs_reg")]
1170 (define_insn "*subsi3_carryin_compare_const"
1171   [(set (reg:CC CC_REGNUM)
1172         (compare:CC (match_operand:SI 1 "reg_or_int_operand" "r")
1173                     (match_operand:SI 2 "arm_not_operand" "K")))
1174    (set (match_operand:SI 0 "s_register_operand" "=r")
1175         (minus:SI (plus:SI (match_dup 1)
1176                            (match_dup 2))
1177                   (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1178   "TARGET_32BIT"
1179   "sbcs\\t%0, %1, #%B2"
1180   [(set_attr "conds" "set")
1181    (set_attr "type" "adcs_imm")]
1184 (define_insn "*subsi3_carryin_shift"
1185   [(set (match_operand:SI 0 "s_register_operand" "=r")
1186         (minus:SI (minus:SI
1187                   (match_operand:SI 1 "s_register_operand" "r")
1188                   (match_operator:SI 2 "shift_operator"
1189                    [(match_operand:SI 3 "s_register_operand" "r")
1190                     (match_operand:SI 4 "reg_or_int_operand" "rM")]))
1191                  (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1192   "TARGET_32BIT"
1193   "sbc%?\\t%0, %1, %3%S2"
1194   [(set_attr "conds" "use")
1195    (set_attr "predicable" "yes")
1196    (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
1197                       (const_string "alu_shift_imm")
1198                      (const_string "alu_shift_reg")))]
1201 (define_insn "*rsbsi3_carryin_shift"
1202   [(set (match_operand:SI 0 "s_register_operand" "=r")
1203         (minus:SI (minus:SI
1204                   (match_operator:SI 2 "shift_operator"
1205                    [(match_operand:SI 3 "s_register_operand" "r")
1206                     (match_operand:SI 4 "reg_or_int_operand" "rM")])
1207                    (match_operand:SI 1 "s_register_operand" "r"))
1208                  (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1209   "TARGET_ARM"
1210   "rsc%?\\t%0, %1, %3%S2"
1211   [(set_attr "conds" "use")
1212    (set_attr "predicable" "yes")
1213    (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
1214                       (const_string "alu_shift_imm")
1215                       (const_string "alu_shift_reg")))]
1218 ; transform ((x << y) - 1) to ~(~(x-1) << y)  Where X is a constant.
1219 (define_split
1220   [(set (match_operand:SI 0 "s_register_operand" "")
1221         (plus:SI (ashift:SI (match_operand:SI 1 "const_int_operand" "")
1222                             (match_operand:SI 2 "s_register_operand" ""))
1223                  (const_int -1)))
1224    (clobber (match_operand:SI 3 "s_register_operand" ""))]
1225   "TARGET_32BIT"
1226   [(set (match_dup 3) (match_dup 1))
1227    (set (match_dup 0) (not:SI (ashift:SI (match_dup 3) (match_dup 2))))]
1228   "
1229   operands[1] = GEN_INT (~(INTVAL (operands[1]) - 1));
1232 (define_expand "addsf3"
1233   [(set (match_operand:SF          0 "s_register_operand" "")
1234         (plus:SF (match_operand:SF 1 "s_register_operand" "")
1235                  (match_operand:SF 2 "s_register_operand" "")))]
1236   "TARGET_32BIT && TARGET_HARD_FLOAT"
1237   "
1240 (define_expand "adddf3"
1241   [(set (match_operand:DF          0 "s_register_operand" "")
1242         (plus:DF (match_operand:DF 1 "s_register_operand" "")
1243                  (match_operand:DF 2 "s_register_operand" "")))]
1244   "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
1245   "
1248 (define_expand "subdi3"
1249  [(parallel
1250    [(set (match_operand:DI            0 "s_register_operand" "")
1251           (minus:DI (match_operand:DI 1 "s_register_operand" "")
1252                     (match_operand:DI 2 "s_register_operand" "")))
1253     (clobber (reg:CC CC_REGNUM))])]
1254   "TARGET_EITHER"
1255   "
1256   if (TARGET_THUMB1)
1257     {
1258       if (!REG_P (operands[1]))
1259         operands[1] = force_reg (DImode, operands[1]);
1260       if (!REG_P (operands[2]))
1261         operands[2] = force_reg (DImode, operands[2]);
1262      }  
1263   "
1266 (define_insn_and_split "*arm_subdi3"
1267   [(set (match_operand:DI           0 "arm_general_register_operand" "=&r,&r,&r")
1268         (minus:DI (match_operand:DI 1 "arm_general_register_operand" "0,r,0")
1269                   (match_operand:DI 2 "arm_general_register_operand" "r,0,0")))
1270    (clobber (reg:CC CC_REGNUM))]
1271   "TARGET_32BIT && !TARGET_NEON"
1272   "#"  ; "subs\\t%Q0, %Q1, %Q2\;sbc\\t%R0, %R1, %R2"
1273   "&& (!TARGET_IWMMXT || reload_completed)"
1274   [(parallel [(set (reg:CC CC_REGNUM)
1275                    (compare:CC (match_dup 1) (match_dup 2)))
1276               (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1277    (set (match_dup 3) (minus:SI (minus:SI (match_dup 4) (match_dup 5))
1278                                (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1279   {
1280     operands[3] = gen_highpart (SImode, operands[0]);
1281     operands[0] = gen_lowpart (SImode, operands[0]);
1282     operands[4] = gen_highpart (SImode, operands[1]);
1283     operands[1] = gen_lowpart (SImode, operands[1]);
1284     operands[5] = gen_highpart (SImode, operands[2]);
1285     operands[2] = gen_lowpart (SImode, operands[2]);
1286    }
1287   [(set_attr "conds" "clob")
1288    (set_attr "length" "8")
1289    (set_attr "type" "multiple")]
1292 (define_insn_and_split "*subdi_di_zesidi"
1293   [(set (match_operand:DI           0 "s_register_operand" "=&r,&r")
1294         (minus:DI (match_operand:DI 1 "s_register_operand"  "0,r")
1295                   (zero_extend:DI
1296                    (match_operand:SI 2 "s_register_operand"  "r,r"))))
1297    (clobber (reg:CC CC_REGNUM))]
1298   "TARGET_32BIT"
1299   "#"   ; "subs\\t%Q0, %Q1, %2\;sbc\\t%R0, %R1, #0"
1300   "&& reload_completed"
1301   [(parallel [(set (reg:CC CC_REGNUM)
1302                    (compare:CC (match_dup 1) (match_dup 2)))
1303               (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1304    (set (match_dup 3) (minus:SI (plus:SI (match_dup 4) (match_dup 5))
1305                                 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1306   {
1307     operands[3] = gen_highpart (SImode, operands[0]);
1308     operands[0] = gen_lowpart (SImode, operands[0]);
1309     operands[4] = gen_highpart (SImode, operands[1]);
1310     operands[1] = gen_lowpart (SImode, operands[1]);
1311     operands[5] = GEN_INT (~0);
1312    }
1313   [(set_attr "conds" "clob")
1314    (set_attr "length" "8")
1315    (set_attr "type" "multiple")]
1318 (define_insn_and_split "*subdi_di_sesidi"
1319   [(set (match_operand:DI            0 "s_register_operand" "=&r,&r")
1320         (minus:DI (match_operand:DI  1 "s_register_operand"  "0,r")
1321                   (sign_extend:DI
1322                    (match_operand:SI 2 "s_register_operand"  "r,r"))))
1323    (clobber (reg:CC CC_REGNUM))]
1324   "TARGET_32BIT"
1325   "#"   ; "subs\\t%Q0, %Q1, %2\;sbc\\t%R0, %R1, %2, asr #31"
1326   "&& reload_completed"
1327   [(parallel [(set (reg:CC CC_REGNUM)
1328                    (compare:CC (match_dup 1) (match_dup 2)))
1329               (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1330    (set (match_dup 3) (minus:SI (minus:SI (match_dup 4)
1331                                          (ashiftrt:SI (match_dup 2)
1332                                                       (const_int 31)))
1333                                 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1334   {
1335     operands[3] = gen_highpart (SImode, operands[0]);
1336     operands[0] = gen_lowpart (SImode, operands[0]);
1337     operands[4] = gen_highpart (SImode, operands[1]);
1338     operands[1] = gen_lowpart (SImode, operands[1]);
1339   }
1340   [(set_attr "conds" "clob")
1341    (set_attr "length" "8")
1342    (set_attr "type" "multiple")]
1345 (define_insn_and_split "*subdi_zesidi_di"
1346   [(set (match_operand:DI            0 "s_register_operand" "=&r,&r")
1347         (minus:DI (zero_extend:DI
1348                    (match_operand:SI 2 "s_register_operand"  "r,r"))
1349                   (match_operand:DI  1 "s_register_operand" "0,r")))
1350    (clobber (reg:CC CC_REGNUM))]
1351   "TARGET_ARM"
1352   "#"   ; "rsbs\\t%Q0, %Q1, %2\;rsc\\t%R0, %R1, #0"
1353         ; is equivalent to:
1354         ; "subs\\t%Q0, %2, %Q1\;rsc\\t%R0, %R1, #0"
1355   "&& reload_completed"
1356   [(parallel [(set (reg:CC CC_REGNUM)
1357                    (compare:CC (match_dup 2) (match_dup 1)))
1358               (set (match_dup 0) (minus:SI (match_dup 2) (match_dup 1)))])
1359    (set (match_dup 3) (minus:SI (minus:SI (const_int 0) (match_dup 4))
1360                                (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1361   {
1362     operands[3] = gen_highpart (SImode, operands[0]);
1363     operands[0] = gen_lowpart (SImode, operands[0]);
1364     operands[4] = gen_highpart (SImode, operands[1]);
1365     operands[1] = gen_lowpart (SImode, operands[1]);
1366   }
1367   [(set_attr "conds" "clob")
1368    (set_attr "length" "8")
1369    (set_attr "type" "multiple")]
1372 (define_insn_and_split "*subdi_sesidi_di"
1373   [(set (match_operand:DI            0 "s_register_operand" "=&r,&r")
1374         (minus:DI (sign_extend:DI
1375                    (match_operand:SI 2 "s_register_operand"   "r,r"))
1376                   (match_operand:DI  1 "s_register_operand"  "0,r")))
1377    (clobber (reg:CC CC_REGNUM))]
1378   "TARGET_ARM"
1379   "#"   ; "rsbs\\t%Q0, %Q1, %2\;rsc\\t%R0, %R1, %2, asr #31"
1380         ; is equivalent to:
1381         ; "subs\\t%Q0, %2, %Q1\;rsc\\t%R0, %R1, %2, asr #31"
1382   "&& reload_completed"
1383   [(parallel [(set (reg:CC CC_REGNUM)
1384                    (compare:CC (match_dup 2) (match_dup 1)))
1385               (set (match_dup 0) (minus:SI (match_dup 2) (match_dup 1)))])
1386    (set (match_dup 3) (minus:SI (minus:SI
1387                                 (ashiftrt:SI (match_dup 2)
1388                                              (const_int 31))
1389                                 (match_dup 4))
1390                                (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1391   {
1392     operands[3] = gen_highpart (SImode, operands[0]);
1393     operands[0] = gen_lowpart (SImode, operands[0]);
1394     operands[4] = gen_highpart (SImode, operands[1]);
1395     operands[1] = gen_lowpart (SImode, operands[1]);
1396   }
1397   [(set_attr "conds" "clob")
1398    (set_attr "length" "8")
1399    (set_attr "type" "multiple")]
1402 (define_insn_and_split "*subdi_zesidi_zesidi"
1403   [(set (match_operand:DI            0 "s_register_operand" "=r")
1404         (minus:DI (zero_extend:DI
1405                    (match_operand:SI 1 "s_register_operand"  "r"))
1406                   (zero_extend:DI
1407                    (match_operand:SI 2 "s_register_operand"  "r"))))
1408    (clobber (reg:CC CC_REGNUM))]
1409   "TARGET_32BIT"
1410   "#"   ; "subs\\t%Q0, %1, %2\;sbc\\t%R0, %1, %1"
1411   "&& reload_completed"
1412   [(parallel [(set (reg:CC CC_REGNUM)
1413                    (compare:CC (match_dup 1) (match_dup 2)))
1414               (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1415    (set (match_dup 3) (minus:SI (minus:SI (match_dup 1) (match_dup 1))
1416                                (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1417   {
1418        operands[3] = gen_highpart (SImode, operands[0]);
1419        operands[0] = gen_lowpart (SImode, operands[0]);
1420   }
1421   [(set_attr "conds" "clob")
1422    (set_attr "length" "8")
1423    (set_attr "type" "multiple")]
1426 (define_expand "subsi3"
1427   [(set (match_operand:SI           0 "s_register_operand" "")
1428         (minus:SI (match_operand:SI 1 "reg_or_int_operand" "")
1429                   (match_operand:SI 2 "s_register_operand" "")))]
1430   "TARGET_EITHER"
1431   "
1432   if (CONST_INT_P (operands[1]))
1433     {
1434       if (TARGET_32BIT)
1435         {
1436           if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[1]), MINUS))
1437             operands[1] = force_reg (SImode, operands[1]);
1438           else
1439             {
1440               arm_split_constant (MINUS, SImode, NULL_RTX,
1441                                   INTVAL (operands[1]), operands[0],
1442                                   operands[2],
1443                                   optimize && can_create_pseudo_p ());
1444               DONE;
1445             }
1446         }
1447       else /* TARGET_THUMB1 */
1448         operands[1] = force_reg (SImode, operands[1]);
1449     }
1450   "
1453 ; ??? Check Thumb-2 split length
1454 (define_insn_and_split "*arm_subsi3_insn"
1455   [(set (match_operand:SI           0 "s_register_operand" "=l,l ,l ,l ,r,r,r,rk,r")
1456         (minus:SI (match_operand:SI 1 "reg_or_int_operand" "l ,0 ,l ,Pz,I,r,r,k ,?n")
1457                   (match_operand:SI 2 "reg_or_int_operand" "l ,Py,Pd,l ,r,I,r,r ,r")))]
1458   "TARGET_32BIT"
1459   "@
1460    sub%?\\t%0, %1, %2
1461    sub%?\\t%0, %2
1462    sub%?\\t%0, %1, %2
1463    rsb%?\\t%0, %2, %1
1464    rsb%?\\t%0, %2, %1
1465    sub%?\\t%0, %1, %2
1466    sub%?\\t%0, %1, %2
1467    sub%?\\t%0, %1, %2
1468    #"
1469   "&& (CONST_INT_P (operands[1])
1470        && !const_ok_for_arm (INTVAL (operands[1])))"
1471   [(clobber (const_int 0))]
1472   "
1473   arm_split_constant (MINUS, SImode, curr_insn,
1474                       INTVAL (operands[1]), operands[0], operands[2], 0);
1475   DONE;
1476   "
1477   [(set_attr "length" "4,4,4,4,4,4,4,4,16")
1478    (set_attr "arch" "t2,t2,t2,t2,*,*,*,*,*")
1479    (set_attr "predicable" "yes")
1480    (set_attr "predicable_short_it" "yes,yes,yes,yes,no,no,no,no,no")
1481    (set_attr "type" "alu_sreg,alu_sreg,alu_sreg,alu_sreg,alu_imm,alu_imm,alu_sreg,alu_sreg,multiple")]
1484 (define_peephole2
1485   [(match_scratch:SI 3 "r")
1486    (set (match_operand:SI 0 "arm_general_register_operand" "")
1487         (minus:SI (match_operand:SI 1 "const_int_operand" "")
1488                   (match_operand:SI 2 "arm_general_register_operand" "")))]
1489   "TARGET_32BIT
1490    && !const_ok_for_arm (INTVAL (operands[1]))
1491    && const_ok_for_arm (~INTVAL (operands[1]))"
1492   [(set (match_dup 3) (match_dup 1))
1493    (set (match_dup 0) (minus:SI (match_dup 3) (match_dup 2)))]
1494   ""
1497 (define_insn "subsi3_compare0"
1498   [(set (reg:CC_NOOV CC_REGNUM)
1499         (compare:CC_NOOV
1500          (minus:SI (match_operand:SI 1 "arm_rhs_operand" "r,r,I")
1501                    (match_operand:SI 2 "arm_rhs_operand" "I,r,r"))
1502          (const_int 0)))
1503    (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
1504         (minus:SI (match_dup 1) (match_dup 2)))]
1505   "TARGET_32BIT"
1506   "@
1507    subs%?\\t%0, %1, %2
1508    subs%?\\t%0, %1, %2
1509    rsbs%?\\t%0, %2, %1"
1510   [(set_attr "conds" "set")
1511    (set_attr "type"  "alus_imm,alus_sreg,alus_sreg")]
1514 (define_insn "subsi3_compare"
1515   [(set (reg:CC CC_REGNUM)
1516         (compare:CC (match_operand:SI 1 "arm_rhs_operand" "r,r,I")
1517                     (match_operand:SI 2 "arm_rhs_operand" "I,r,r")))
1518    (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
1519         (minus:SI (match_dup 1) (match_dup 2)))]
1520   "TARGET_32BIT"
1521   "@
1522    subs%?\\t%0, %1, %2
1523    subs%?\\t%0, %1, %2
1524    rsbs%?\\t%0, %2, %1"
1525   [(set_attr "conds" "set")
1526    (set_attr "type" "alus_imm,alus_sreg,alus_sreg")]
1529 (define_expand "subsf3"
1530   [(set (match_operand:SF           0 "s_register_operand" "")
1531         (minus:SF (match_operand:SF 1 "s_register_operand" "")
1532                   (match_operand:SF 2 "s_register_operand" "")))]
1533   "TARGET_32BIT && TARGET_HARD_FLOAT"
1534   "
1537 (define_expand "subdf3"
1538   [(set (match_operand:DF           0 "s_register_operand" "")
1539         (minus:DF (match_operand:DF 1 "s_register_operand" "")
1540                   (match_operand:DF 2 "s_register_operand" "")))]
1541   "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
1542   "
1546 ;; Multiplication insns
1548 (define_expand "mulhi3"
1549   [(set (match_operand:HI 0 "s_register_operand" "")
1550         (mult:HI (match_operand:HI 1 "s_register_operand" "")
1551                  (match_operand:HI 2 "s_register_operand" "")))]
1552   "TARGET_DSP_MULTIPLY"
1553   "
1554   {
1555     rtx result = gen_reg_rtx (SImode);
1556     emit_insn (gen_mulhisi3 (result, operands[1], operands[2]));
1557     emit_move_insn (operands[0], gen_lowpart (HImode, result));
1558     DONE;
1559   }"
1562 (define_expand "mulsi3"
1563   [(set (match_operand:SI          0 "s_register_operand" "")
1564         (mult:SI (match_operand:SI 2 "s_register_operand" "")
1565                  (match_operand:SI 1 "s_register_operand" "")))]
1566   "TARGET_EITHER"
1567   ""
1570 ;; Use `&' and then `0' to prevent the operands 0 and 1 being the same
1571 (define_insn "*arm_mulsi3"
1572   [(set (match_operand:SI          0 "s_register_operand" "=&r,&r")
1573         (mult:SI (match_operand:SI 2 "s_register_operand" "r,r")
1574                  (match_operand:SI 1 "s_register_operand" "%0,r")))]
1575   "TARGET_32BIT && !arm_arch6"
1576   "mul%?\\t%0, %2, %1"
1577   [(set_attr "type" "mul")
1578    (set_attr "predicable" "yes")]
1581 (define_insn "*arm_mulsi3_v6"
1582   [(set (match_operand:SI          0 "s_register_operand" "=l,l,r")
1583         (mult:SI (match_operand:SI 1 "s_register_operand" "0,l,r")
1584                  (match_operand:SI 2 "s_register_operand" "l,0,r")))]
1585   "TARGET_32BIT && arm_arch6"
1586   "mul%?\\t%0, %1, %2"
1587   [(set_attr "type" "mul")
1588    (set_attr "predicable" "yes")
1589    (set_attr "arch" "t2,t2,*")
1590    (set_attr "length" "4")
1591    (set_attr "predicable_short_it" "yes,yes,no")]
1594 (define_insn "*mulsi3_compare0"
1595   [(set (reg:CC_NOOV CC_REGNUM)
1596         (compare:CC_NOOV (mult:SI
1597                           (match_operand:SI 2 "s_register_operand" "r,r")
1598                           (match_operand:SI 1 "s_register_operand" "%0,r"))
1599                          (const_int 0)))
1600    (set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1601         (mult:SI (match_dup 2) (match_dup 1)))]
1602   "TARGET_ARM && !arm_arch6"
1603   "muls%?\\t%0, %2, %1"
1604   [(set_attr "conds" "set")
1605    (set_attr "type" "muls")]
1608 (define_insn "*mulsi3_compare0_v6"
1609   [(set (reg:CC_NOOV CC_REGNUM)
1610         (compare:CC_NOOV (mult:SI
1611                           (match_operand:SI 2 "s_register_operand" "r")
1612                           (match_operand:SI 1 "s_register_operand" "r"))
1613                          (const_int 0)))
1614    (set (match_operand:SI 0 "s_register_operand" "=r")
1615         (mult:SI (match_dup 2) (match_dup 1)))]
1616   "TARGET_ARM && arm_arch6 && optimize_size"
1617   "muls%?\\t%0, %2, %1"
1618   [(set_attr "conds" "set")
1619    (set_attr "type" "muls")]
1622 (define_insn "*mulsi_compare0_scratch"
1623   [(set (reg:CC_NOOV CC_REGNUM)
1624         (compare:CC_NOOV (mult:SI
1625                           (match_operand:SI 2 "s_register_operand" "r,r")
1626                           (match_operand:SI 1 "s_register_operand" "%0,r"))
1627                          (const_int 0)))
1628    (clobber (match_scratch:SI 0 "=&r,&r"))]
1629   "TARGET_ARM && !arm_arch6"
1630   "muls%?\\t%0, %2, %1"
1631   [(set_attr "conds" "set")
1632    (set_attr "type" "muls")]
1635 (define_insn "*mulsi_compare0_scratch_v6"
1636   [(set (reg:CC_NOOV CC_REGNUM)
1637         (compare:CC_NOOV (mult:SI
1638                           (match_operand:SI 2 "s_register_operand" "r")
1639                           (match_operand:SI 1 "s_register_operand" "r"))
1640                          (const_int 0)))
1641    (clobber (match_scratch:SI 0 "=r"))]
1642   "TARGET_ARM && arm_arch6 && optimize_size"
1643   "muls%?\\t%0, %2, %1"
1644   [(set_attr "conds" "set")
1645    (set_attr "type" "muls")]
1648 ;; Unnamed templates to match MLA instruction.
1650 (define_insn "*mulsi3addsi"
1651   [(set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r,&r")
1652         (plus:SI
1653           (mult:SI (match_operand:SI 2 "s_register_operand" "r,r,r,r")
1654                    (match_operand:SI 1 "s_register_operand" "%0,r,0,r"))
1655           (match_operand:SI 3 "s_register_operand" "r,r,0,0")))]
1656   "TARGET_32BIT && !arm_arch6"
1657   "mla%?\\t%0, %2, %1, %3"
1658   [(set_attr "type" "mla")
1659    (set_attr "predicable" "yes")]
1662 (define_insn "*mulsi3addsi_v6"
1663   [(set (match_operand:SI 0 "s_register_operand" "=r")
1664         (plus:SI
1665           (mult:SI (match_operand:SI 2 "s_register_operand" "r")
1666                    (match_operand:SI 1 "s_register_operand" "r"))
1667           (match_operand:SI 3 "s_register_operand" "r")))]
1668   "TARGET_32BIT && arm_arch6"
1669   "mla%?\\t%0, %2, %1, %3"
1670   [(set_attr "type" "mla")
1671    (set_attr "predicable" "yes")]
1674 (define_insn "*mulsi3addsi_compare0"
1675   [(set (reg:CC_NOOV CC_REGNUM)
1676         (compare:CC_NOOV
1677          (plus:SI (mult:SI
1678                    (match_operand:SI 2 "s_register_operand" "r,r,r,r")
1679                    (match_operand:SI 1 "s_register_operand" "%0,r,0,r"))
1680                   (match_operand:SI 3 "s_register_operand" "r,r,0,0"))
1681          (const_int 0)))
1682    (set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r,&r")
1683         (plus:SI (mult:SI (match_dup 2) (match_dup 1))
1684                  (match_dup 3)))]
1685   "TARGET_ARM && arm_arch6"
1686   "mlas%?\\t%0, %2, %1, %3"
1687   [(set_attr "conds" "set")
1688    (set_attr "type" "mlas")]
1691 (define_insn "*mulsi3addsi_compare0_v6"
1692   [(set (reg:CC_NOOV CC_REGNUM)
1693         (compare:CC_NOOV
1694          (plus:SI (mult:SI
1695                    (match_operand:SI 2 "s_register_operand" "r")
1696                    (match_operand:SI 1 "s_register_operand" "r"))
1697                   (match_operand:SI 3 "s_register_operand" "r"))
1698          (const_int 0)))
1699    (set (match_operand:SI 0 "s_register_operand" "=r")
1700         (plus:SI (mult:SI (match_dup 2) (match_dup 1))
1701                  (match_dup 3)))]
1702   "TARGET_ARM && arm_arch6 && optimize_size"
1703   "mlas%?\\t%0, %2, %1, %3"
1704   [(set_attr "conds" "set")
1705    (set_attr "type" "mlas")]
1708 (define_insn "*mulsi3addsi_compare0_scratch"
1709   [(set (reg:CC_NOOV CC_REGNUM)
1710         (compare:CC_NOOV
1711          (plus:SI (mult:SI
1712                    (match_operand:SI 2 "s_register_operand" "r,r,r,r")
1713                    (match_operand:SI 1 "s_register_operand" "%0,r,0,r"))
1714                   (match_operand:SI 3 "s_register_operand" "?r,r,0,0"))
1715          (const_int 0)))
1716    (clobber (match_scratch:SI 0 "=&r,&r,&r,&r"))]
1717   "TARGET_ARM && !arm_arch6"
1718   "mlas%?\\t%0, %2, %1, %3"
1719   [(set_attr "conds" "set")
1720    (set_attr "type" "mlas")]
1723 (define_insn "*mulsi3addsi_compare0_scratch_v6"
1724   [(set (reg:CC_NOOV CC_REGNUM)
1725         (compare:CC_NOOV
1726          (plus:SI (mult:SI
1727                    (match_operand:SI 2 "s_register_operand" "r")
1728                    (match_operand:SI 1 "s_register_operand" "r"))
1729                   (match_operand:SI 3 "s_register_operand" "r"))
1730          (const_int 0)))
1731    (clobber (match_scratch:SI 0 "=r"))]
1732   "TARGET_ARM && arm_arch6 && optimize_size"
1733   "mlas%?\\t%0, %2, %1, %3"
1734   [(set_attr "conds" "set")
1735    (set_attr "type" "mlas")]
1738 (define_insn "*mulsi3subsi"
1739   [(set (match_operand:SI 0 "s_register_operand" "=r")
1740         (minus:SI
1741           (match_operand:SI 3 "s_register_operand" "r")
1742           (mult:SI (match_operand:SI 2 "s_register_operand" "r")
1743                    (match_operand:SI 1 "s_register_operand" "r"))))]
1744   "TARGET_32BIT && arm_arch_thumb2"
1745   "mls%?\\t%0, %2, %1, %3"
1746   [(set_attr "type" "mla")
1747    (set_attr "predicable" "yes")]
1750 (define_expand "maddsidi4"
1751   [(set (match_operand:DI 0 "s_register_operand" "")
1752         (plus:DI
1753          (mult:DI
1754           (sign_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1755           (sign_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1756          (match_operand:DI 3 "s_register_operand" "")))]
1757   "TARGET_32BIT"
1758   "")
1760 (define_insn "*mulsidi3adddi"
1761   [(set (match_operand:DI 0 "s_register_operand" "=&r")
1762         (plus:DI
1763          (mult:DI
1764           (sign_extend:DI (match_operand:SI 2 "s_register_operand" "%r"))
1765           (sign_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1766          (match_operand:DI 1 "s_register_operand" "0")))]
1767   "TARGET_32BIT && !arm_arch6"
1768   "smlal%?\\t%Q0, %R0, %3, %2"
1769   [(set_attr "type" "smlal")
1770    (set_attr "predicable" "yes")]
1773 (define_insn "*mulsidi3adddi_v6"
1774   [(set (match_operand:DI 0 "s_register_operand" "=r")
1775         (plus:DI
1776          (mult:DI
1777           (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r"))
1778           (sign_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1779          (match_operand:DI 1 "s_register_operand" "0")))]
1780   "TARGET_32BIT && arm_arch6"
1781   "smlal%?\\t%Q0, %R0, %3, %2"
1782   [(set_attr "type" "smlal")
1783    (set_attr "predicable" "yes")]
1786 ;; 32x32->64 widening multiply.
1787 ;; As with mulsi3, the only difference between the v3-5 and v6+
1788 ;; versions of these patterns is the requirement that the output not
1789 ;; overlap the inputs, but that still means we have to have a named
1790 ;; expander and two different starred insns.
1792 (define_expand "mulsidi3"
1793   [(set (match_operand:DI 0 "s_register_operand" "")
1794         (mult:DI
1795          (sign_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1796          (sign_extend:DI (match_operand:SI 2 "s_register_operand" ""))))]
1797   "TARGET_32BIT"
1798   ""
1801 (define_insn "*mulsidi3_nov6"
1802   [(set (match_operand:DI 0 "s_register_operand" "=&r")
1803         (mult:DI
1804          (sign_extend:DI (match_operand:SI 1 "s_register_operand" "%r"))
1805          (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1806   "TARGET_32BIT && !arm_arch6"
1807   "smull%?\\t%Q0, %R0, %1, %2"
1808   [(set_attr "type" "smull")
1809    (set_attr "predicable" "yes")]
1812 (define_insn "*mulsidi3_v6"
1813   [(set (match_operand:DI 0 "s_register_operand" "=r")
1814         (mult:DI
1815          (sign_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1816          (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1817   "TARGET_32BIT && arm_arch6"
1818   "smull%?\\t%Q0, %R0, %1, %2"
1819   [(set_attr "type" "smull")
1820    (set_attr "predicable" "yes")]
1823 (define_expand "umulsidi3"
1824   [(set (match_operand:DI 0 "s_register_operand" "")
1825         (mult:DI
1826          (zero_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1827          (zero_extend:DI (match_operand:SI 2 "s_register_operand" ""))))]
1828   "TARGET_32BIT"
1829   ""
1832 (define_insn "*umulsidi3_nov6"
1833   [(set (match_operand:DI 0 "s_register_operand" "=&r")
1834         (mult:DI
1835          (zero_extend:DI (match_operand:SI 1 "s_register_operand" "%r"))
1836          (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1837   "TARGET_32BIT && !arm_arch6"
1838   "umull%?\\t%Q0, %R0, %1, %2"
1839   [(set_attr "type" "umull")
1840    (set_attr "predicable" "yes")]
1843 (define_insn "*umulsidi3_v6"
1844   [(set (match_operand:DI 0 "s_register_operand" "=r")
1845         (mult:DI
1846          (zero_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1847          (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1848   "TARGET_32BIT && arm_arch6"
1849   "umull%?\\t%Q0, %R0, %1, %2"
1850   [(set_attr "type" "umull")
1851    (set_attr "predicable" "yes")]
1854 (define_expand "umaddsidi4"
1855   [(set (match_operand:DI 0 "s_register_operand" "")
1856         (plus:DI
1857          (mult:DI
1858           (zero_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1859           (zero_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1860          (match_operand:DI 3 "s_register_operand" "")))]
1861   "TARGET_32BIT"
1862   "")
1864 (define_insn "*umulsidi3adddi"
1865   [(set (match_operand:DI 0 "s_register_operand" "=&r")
1866         (plus:DI
1867          (mult:DI
1868           (zero_extend:DI (match_operand:SI 2 "s_register_operand" "%r"))
1869           (zero_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1870          (match_operand:DI 1 "s_register_operand" "0")))]
1871   "TARGET_32BIT && !arm_arch6"
1872   "umlal%?\\t%Q0, %R0, %3, %2"
1873   [(set_attr "type" "umlal")
1874    (set_attr "predicable" "yes")]
1877 (define_insn "*umulsidi3adddi_v6"
1878   [(set (match_operand:DI 0 "s_register_operand" "=r")
1879         (plus:DI
1880          (mult:DI
1881           (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r"))
1882           (zero_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1883          (match_operand:DI 1 "s_register_operand" "0")))]
1884   "TARGET_32BIT && arm_arch6"
1885   "umlal%?\\t%Q0, %R0, %3, %2"
1886   [(set_attr "type" "umlal")
1887    (set_attr "predicable" "yes")]
1890 (define_expand "smulsi3_highpart"
1891   [(parallel
1892     [(set (match_operand:SI 0 "s_register_operand" "")
1893           (truncate:SI
1894            (lshiftrt:DI
1895             (mult:DI
1896              (sign_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1897              (sign_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1898             (const_int 32))))
1899      (clobber (match_scratch:SI 3 ""))])]
1900   "TARGET_32BIT"
1901   ""
1904 (define_insn "*smulsi3_highpart_nov6"
1905   [(set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1906         (truncate:SI
1907          (lshiftrt:DI
1908           (mult:DI
1909            (sign_extend:DI (match_operand:SI 1 "s_register_operand" "%0,r"))
1910            (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r,r")))
1911           (const_int 32))))
1912    (clobber (match_scratch:SI 3 "=&r,&r"))]
1913   "TARGET_32BIT && !arm_arch6"
1914   "smull%?\\t%3, %0, %2, %1"
1915   [(set_attr "type" "smull")
1916    (set_attr "predicable" "yes")]
1919 (define_insn "*smulsi3_highpart_v6"
1920   [(set (match_operand:SI 0 "s_register_operand" "=r")
1921         (truncate:SI
1922          (lshiftrt:DI
1923           (mult:DI
1924            (sign_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1925            (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r")))
1926           (const_int 32))))
1927    (clobber (match_scratch:SI 3 "=r"))]
1928   "TARGET_32BIT && arm_arch6"
1929   "smull%?\\t%3, %0, %2, %1"
1930   [(set_attr "type" "smull")
1931    (set_attr "predicable" "yes")]
1934 (define_expand "umulsi3_highpart"
1935   [(parallel
1936     [(set (match_operand:SI 0 "s_register_operand" "")
1937           (truncate:SI
1938            (lshiftrt:DI
1939             (mult:DI
1940              (zero_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1941               (zero_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1942             (const_int 32))))
1943      (clobber (match_scratch:SI 3 ""))])]
1944   "TARGET_32BIT"
1945   ""
1948 (define_insn "*umulsi3_highpart_nov6"
1949   [(set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1950         (truncate:SI
1951          (lshiftrt:DI
1952           (mult:DI
1953            (zero_extend:DI (match_operand:SI 1 "s_register_operand" "%0,r"))
1954            (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r,r")))
1955           (const_int 32))))
1956    (clobber (match_scratch:SI 3 "=&r,&r"))]
1957   "TARGET_32BIT && !arm_arch6"
1958   "umull%?\\t%3, %0, %2, %1"
1959   [(set_attr "type" "umull")
1960    (set_attr "predicable" "yes")]
1963 (define_insn "*umulsi3_highpart_v6"
1964   [(set (match_operand:SI 0 "s_register_operand" "=r")
1965         (truncate:SI
1966          (lshiftrt:DI
1967           (mult:DI
1968            (zero_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1969            (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r")))
1970           (const_int 32))))
1971    (clobber (match_scratch:SI 3 "=r"))]
1972   "TARGET_32BIT && arm_arch6"
1973   "umull%?\\t%3, %0, %2, %1"
1974   [(set_attr "type" "umull")
1975    (set_attr "predicable" "yes")]
1978 (define_insn "mulhisi3"
1979   [(set (match_operand:SI 0 "s_register_operand" "=r")
1980         (mult:SI (sign_extend:SI
1981                   (match_operand:HI 1 "s_register_operand" "%r"))
1982                  (sign_extend:SI
1983                   (match_operand:HI 2 "s_register_operand" "r"))))]
1984   "TARGET_DSP_MULTIPLY"
1985   "smulbb%?\\t%0, %1, %2"
1986   [(set_attr "type" "smulxy")
1987    (set_attr "predicable" "yes")]
1990 (define_insn "*mulhisi3tb"
1991   [(set (match_operand:SI 0 "s_register_operand" "=r")
1992         (mult:SI (ashiftrt:SI
1993                   (match_operand:SI 1 "s_register_operand" "r")
1994                   (const_int 16))
1995                  (sign_extend:SI
1996                   (match_operand:HI 2 "s_register_operand" "r"))))]
1997   "TARGET_DSP_MULTIPLY"
1998   "smultb%?\\t%0, %1, %2"
1999   [(set_attr "type" "smulxy")
2000    (set_attr "predicable" "yes")]
2003 (define_insn "*mulhisi3bt"
2004   [(set (match_operand:SI 0 "s_register_operand" "=r")
2005         (mult:SI (sign_extend:SI
2006                   (match_operand:HI 1 "s_register_operand" "r"))
2007                  (ashiftrt:SI
2008                   (match_operand:SI 2 "s_register_operand" "r")
2009                   (const_int 16))))]
2010   "TARGET_DSP_MULTIPLY"
2011   "smulbt%?\\t%0, %1, %2"
2012   [(set_attr "type" "smulxy")
2013    (set_attr "predicable" "yes")]
2016 (define_insn "*mulhisi3tt"
2017   [(set (match_operand:SI 0 "s_register_operand" "=r")
2018         (mult:SI (ashiftrt:SI
2019                   (match_operand:SI 1 "s_register_operand" "r")
2020                   (const_int 16))
2021                  (ashiftrt:SI
2022                   (match_operand:SI 2 "s_register_operand" "r")
2023                   (const_int 16))))]
2024   "TARGET_DSP_MULTIPLY"
2025   "smultt%?\\t%0, %1, %2"
2026   [(set_attr "type" "smulxy")
2027    (set_attr "predicable" "yes")]
2030 (define_insn "maddhisi4"
2031   [(set (match_operand:SI 0 "s_register_operand" "=r")
2032         (plus:SI (mult:SI (sign_extend:SI
2033                            (match_operand:HI 1 "s_register_operand" "r"))
2034                           (sign_extend:SI
2035                            (match_operand:HI 2 "s_register_operand" "r")))
2036                  (match_operand:SI 3 "s_register_operand" "r")))]
2037   "TARGET_DSP_MULTIPLY"
2038   "smlabb%?\\t%0, %1, %2, %3"
2039   [(set_attr "type" "smlaxy")
2040    (set_attr "predicable" "yes")]
2043 ;; Note: there is no maddhisi4ibt because this one is canonical form
2044 (define_insn "*maddhisi4tb"
2045   [(set (match_operand:SI 0 "s_register_operand" "=r")
2046         (plus:SI (mult:SI (ashiftrt:SI
2047                            (match_operand:SI 1 "s_register_operand" "r")
2048                            (const_int 16))
2049                           (sign_extend:SI
2050                            (match_operand:HI 2 "s_register_operand" "r")))
2051                  (match_operand:SI 3 "s_register_operand" "r")))]
2052   "TARGET_DSP_MULTIPLY"
2053   "smlatb%?\\t%0, %1, %2, %3"
2054   [(set_attr "type" "smlaxy")
2055    (set_attr "predicable" "yes")]
2058 (define_insn "*maddhisi4tt"
2059   [(set (match_operand:SI 0 "s_register_operand" "=r")
2060         (plus:SI (mult:SI (ashiftrt:SI
2061                            (match_operand:SI 1 "s_register_operand" "r")
2062                            (const_int 16))
2063                           (ashiftrt:SI
2064                            (match_operand:SI 2 "s_register_operand" "r")
2065                            (const_int 16)))
2066                  (match_operand:SI 3 "s_register_operand" "r")))]
2067   "TARGET_DSP_MULTIPLY"
2068   "smlatt%?\\t%0, %1, %2, %3"
2069   [(set_attr "type" "smlaxy")
2070    (set_attr "predicable" "yes")]
2073 (define_insn "maddhidi4"
2074   [(set (match_operand:DI 0 "s_register_operand" "=r")
2075         (plus:DI
2076           (mult:DI (sign_extend:DI
2077                     (match_operand:HI 1 "s_register_operand" "r"))
2078                    (sign_extend:DI
2079                     (match_operand:HI 2 "s_register_operand" "r")))
2080           (match_operand:DI 3 "s_register_operand" "0")))]
2081   "TARGET_DSP_MULTIPLY"
2082   "smlalbb%?\\t%Q0, %R0, %1, %2"
2083   [(set_attr "type" "smlalxy")
2084    (set_attr "predicable" "yes")])
2086 ;; Note: there is no maddhidi4ibt because this one is canonical form
2087 (define_insn "*maddhidi4tb"
2088   [(set (match_operand:DI 0 "s_register_operand" "=r")
2089         (plus:DI
2090           (mult:DI (sign_extend:DI
2091                     (ashiftrt:SI
2092                      (match_operand:SI 1 "s_register_operand" "r")
2093                      (const_int 16)))
2094                    (sign_extend:DI
2095                     (match_operand:HI 2 "s_register_operand" "r")))
2096           (match_operand:DI 3 "s_register_operand" "0")))]
2097   "TARGET_DSP_MULTIPLY"
2098   "smlaltb%?\\t%Q0, %R0, %1, %2"
2099   [(set_attr "type" "smlalxy")
2100    (set_attr "predicable" "yes")])
2102 (define_insn "*maddhidi4tt"
2103   [(set (match_operand:DI 0 "s_register_operand" "=r")
2104         (plus:DI
2105           (mult:DI (sign_extend:DI
2106                     (ashiftrt:SI
2107                      (match_operand:SI 1 "s_register_operand" "r")
2108                      (const_int 16)))
2109                    (sign_extend:DI
2110                     (ashiftrt:SI
2111                      (match_operand:SI 2 "s_register_operand" "r")
2112                      (const_int 16))))
2113           (match_operand:DI 3 "s_register_operand" "0")))]
2114   "TARGET_DSP_MULTIPLY"
2115   "smlaltt%?\\t%Q0, %R0, %1, %2"
2116   [(set_attr "type" "smlalxy")
2117    (set_attr "predicable" "yes")])
2119 (define_expand "mulsf3"
2120   [(set (match_operand:SF          0 "s_register_operand" "")
2121         (mult:SF (match_operand:SF 1 "s_register_operand" "")
2122                  (match_operand:SF 2 "s_register_operand" "")))]
2123   "TARGET_32BIT && TARGET_HARD_FLOAT"
2124   "
2127 (define_expand "muldf3"
2128   [(set (match_operand:DF          0 "s_register_operand" "")
2129         (mult:DF (match_operand:DF 1 "s_register_operand" "")
2130                  (match_operand:DF 2 "s_register_operand" "")))]
2131   "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
2132   "
2135 ;; Division insns
2137 (define_expand "divsf3"
2138   [(set (match_operand:SF 0 "s_register_operand" "")
2139         (div:SF (match_operand:SF 1 "s_register_operand" "")
2140                 (match_operand:SF 2 "s_register_operand" "")))]
2141   "TARGET_32BIT && TARGET_HARD_FLOAT"
2142   "")
2144 (define_expand "divdf3"
2145   [(set (match_operand:DF 0 "s_register_operand" "")
2146         (div:DF (match_operand:DF 1 "s_register_operand" "")
2147                 (match_operand:DF 2 "s_register_operand" "")))]
2148   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
2149   "")
2151 ;; Boolean and,ior,xor insns
2153 ;; Split up double word logical operations
2155 ;; Split up simple DImode logical operations.  Simply perform the logical
2156 ;; operation on the upper and lower halves of the registers.
2157 (define_split
2158   [(set (match_operand:DI 0 "s_register_operand" "")
2159         (match_operator:DI 6 "logical_binary_operator"
2160           [(match_operand:DI 1 "s_register_operand" "")
2161            (match_operand:DI 2 "s_register_operand" "")]))]
2162   "TARGET_32BIT && reload_completed
2163    && ! (TARGET_NEON && IS_VFP_REGNUM (REGNO (operands[0])))
2164    && ! IS_IWMMXT_REGNUM (REGNO (operands[0]))"
2165   [(set (match_dup 0) (match_op_dup:SI 6 [(match_dup 1) (match_dup 2)]))
2166    (set (match_dup 3) (match_op_dup:SI 6 [(match_dup 4) (match_dup 5)]))]
2167   "
2168   {
2169     operands[3] = gen_highpart (SImode, operands[0]);
2170     operands[0] = gen_lowpart (SImode, operands[0]);
2171     operands[4] = gen_highpart (SImode, operands[1]);
2172     operands[1] = gen_lowpart (SImode, operands[1]);
2173     operands[5] = gen_highpart (SImode, operands[2]);
2174     operands[2] = gen_lowpart (SImode, operands[2]);
2175   }"
2178 (define_split
2179   [(set (match_operand:DI 0 "s_register_operand" "")
2180         (match_operator:DI 6 "logical_binary_operator"
2181           [(sign_extend:DI (match_operand:SI 2 "s_register_operand" ""))
2182            (match_operand:DI 1 "s_register_operand" "")]))]
2183   "TARGET_32BIT && reload_completed"
2184   [(set (match_dup 0) (match_op_dup:SI 6 [(match_dup 1) (match_dup 2)]))
2185    (set (match_dup 3) (match_op_dup:SI 6
2186                         [(ashiftrt:SI (match_dup 2) (const_int 31))
2187                          (match_dup 4)]))]
2188   "
2189   {
2190     operands[3] = gen_highpart (SImode, operands[0]);
2191     operands[0] = gen_lowpart (SImode, operands[0]);
2192     operands[4] = gen_highpart (SImode, operands[1]);
2193     operands[1] = gen_lowpart (SImode, operands[1]);
2194     operands[5] = gen_highpart (SImode, operands[2]);
2195     operands[2] = gen_lowpart (SImode, operands[2]);
2196   }"
2199 ;; The zero extend of operand 2 means we can just copy the high part of
2200 ;; operand1 into operand0.
2201 (define_split
2202   [(set (match_operand:DI 0 "s_register_operand" "")
2203         (ior:DI
2204           (zero_extend:DI (match_operand:SI 2 "s_register_operand" ""))
2205           (match_operand:DI 1 "s_register_operand" "")))]
2206   "TARGET_32BIT && operands[0] != operands[1] && reload_completed"
2207   [(set (match_dup 0) (ior:SI (match_dup 1) (match_dup 2)))
2208    (set (match_dup 3) (match_dup 4))]
2209   "
2210   {
2211     operands[4] = gen_highpart (SImode, operands[1]);
2212     operands[3] = gen_highpart (SImode, operands[0]);
2213     operands[0] = gen_lowpart (SImode, operands[0]);
2214     operands[1] = gen_lowpart (SImode, operands[1]);
2215   }"
2218 ;; The zero extend of operand 2 means we can just copy the high part of
2219 ;; operand1 into operand0.
2220 (define_split
2221   [(set (match_operand:DI 0 "s_register_operand" "")
2222         (xor:DI
2223           (zero_extend:DI (match_operand:SI 2 "s_register_operand" ""))
2224           (match_operand:DI 1 "s_register_operand" "")))]
2225   "TARGET_32BIT && operands[0] != operands[1] && reload_completed"
2226   [(set (match_dup 0) (xor:SI (match_dup 1) (match_dup 2)))
2227    (set (match_dup 3) (match_dup 4))]
2228   "
2229   {
2230     operands[4] = gen_highpart (SImode, operands[1]);
2231     operands[3] = gen_highpart (SImode, operands[0]);
2232     operands[0] = gen_lowpart (SImode, operands[0]);
2233     operands[1] = gen_lowpart (SImode, operands[1]);
2234   }"
2237 (define_expand "anddi3"
2238   [(set (match_operand:DI         0 "s_register_operand" "")
2239         (and:DI (match_operand:DI 1 "s_register_operand" "")
2240                 (match_operand:DI 2 "neon_inv_logic_op2" "")))]
2241   "TARGET_32BIT"
2242   "
2243   if (!TARGET_NEON && !TARGET_IWMMXT)
2244     {
2245       rtx low  = simplify_gen_binary (AND, SImode,
2246                                       gen_lowpart (SImode, operands[1]),
2247                                       gen_lowpart (SImode, operands[2]));
2248       rtx high = simplify_gen_binary (AND, SImode,
2249                                       gen_highpart (SImode, operands[1]),
2250                                       gen_highpart_mode (SImode, DImode,
2251                                                          operands[2]));
2253       emit_insn (gen_rtx_SET (gen_lowpart (SImode, operands[0]), low));
2254       emit_insn (gen_rtx_SET (gen_highpart (SImode, operands[0]), high));
2256       DONE;
2257     }
2258   /* Otherwise expand pattern as above.  */
2259   "
2262 (define_insn_and_split "*anddi3_insn"
2263   [(set (match_operand:DI         0 "s_register_operand"     "=w,w ,&r,&r,&r,&r,?w,?w")
2264         (and:DI (match_operand:DI 1 "s_register_operand"     "%w,0 ,0 ,r ,0 ,r ,w ,0")
2265                 (match_operand:DI 2 "arm_anddi_operand_neon" "w ,DL,r ,r ,De,De,w ,DL")))]
2266   "TARGET_32BIT && !TARGET_IWMMXT"
2268   switch (which_alternative)
2269     {
2270     case 0: /* fall through */
2271     case 6: return "vand\t%P0, %P1, %P2";
2272     case 1: /* fall through */
2273     case 7: return neon_output_logic_immediate ("vand", &operands[2],
2274                     DImode, 1, VALID_NEON_QREG_MODE (DImode));
2275     case 2:
2276     case 3:
2277     case 4:
2278     case 5: /* fall through */
2279       return "#";
2280     default: gcc_unreachable ();
2281     }
2283   "TARGET_32BIT && !TARGET_IWMMXT && reload_completed
2284    && !(IS_VFP_REGNUM (REGNO (operands[0])))"
2285   [(set (match_dup 3) (match_dup 4))
2286    (set (match_dup 5) (match_dup 6))]
2287   "
2288   {
2289     operands[3] = gen_lowpart (SImode, operands[0]);
2290     operands[5] = gen_highpart (SImode, operands[0]);
2292     operands[4] = simplify_gen_binary (AND, SImode,
2293                                            gen_lowpart (SImode, operands[1]),
2294                                            gen_lowpart (SImode, operands[2]));
2295     operands[6] = simplify_gen_binary (AND, SImode,
2296                                            gen_highpart (SImode, operands[1]),
2297                                            gen_highpart_mode (SImode, DImode, operands[2]));
2299   }"
2300   [(set_attr "type" "neon_logic,neon_logic,multiple,multiple,\
2301                      multiple,multiple,neon_logic,neon_logic")
2302    (set_attr "arch" "neon_for_64bits,neon_for_64bits,*,*,*,*,
2303                      avoid_neon_for_64bits,avoid_neon_for_64bits")
2304    (set_attr "length" "*,*,8,8,8,8,*,*")
2305   ]
2308 (define_insn_and_split "*anddi_zesidi_di"
2309   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2310         (and:DI (zero_extend:DI
2311                  (match_operand:SI 2 "s_register_operand" "r,r"))
2312                 (match_operand:DI 1 "s_register_operand" "0,r")))]
2313   "TARGET_32BIT"
2314   "#"
2315   "TARGET_32BIT && reload_completed"
2316   ; The zero extend of operand 2 clears the high word of the output
2317   ; operand.
2318   [(set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))
2319    (set (match_dup 3) (const_int 0))]
2320   "
2321   {
2322     operands[3] = gen_highpart (SImode, operands[0]);
2323     operands[0] = gen_lowpart (SImode, operands[0]);
2324     operands[1] = gen_lowpart (SImode, operands[1]);
2325   }"
2326   [(set_attr "length" "8")
2327    (set_attr "type" "multiple")]
2330 (define_insn "*anddi_sesdi_di"
2331   [(set (match_operand:DI          0 "s_register_operand" "=&r,&r")
2332         (and:DI (sign_extend:DI
2333                  (match_operand:SI 2 "s_register_operand" "r,r"))
2334                 (match_operand:DI  1 "s_register_operand" "0,r")))]
2335   "TARGET_32BIT"
2336   "#"
2337   [(set_attr "length" "8")
2338    (set_attr "type" "multiple")]
2341 (define_expand "andsi3"
2342   [(set (match_operand:SI         0 "s_register_operand" "")
2343         (and:SI (match_operand:SI 1 "s_register_operand" "")
2344                 (match_operand:SI 2 "reg_or_int_operand" "")))]
2345   "TARGET_EITHER"
2346   "
2347   if (TARGET_32BIT)
2348     {
2349       if (CONST_INT_P (operands[2]))
2350         {
2351           if (INTVAL (operands[2]) == 255 && arm_arch6)
2352             {
2353               operands[1] = convert_to_mode (QImode, operands[1], 1);
2354               emit_insn (gen_thumb2_zero_extendqisi2_v6 (operands[0],
2355                                                          operands[1]));
2356               DONE;
2357             }
2358           else if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[2]), AND))
2359             operands[2] = force_reg (SImode, operands[2]);
2360           else
2361             {
2362               arm_split_constant (AND, SImode, NULL_RTX,
2363                                   INTVAL (operands[2]), operands[0],
2364                                   operands[1],
2365                                   optimize && can_create_pseudo_p ());
2367               DONE;
2368             }
2369         }
2370     }
2371   else /* TARGET_THUMB1 */
2372     {
2373       if (!CONST_INT_P (operands[2]))
2374         {
2375           rtx tmp = force_reg (SImode, operands[2]);
2376           if (rtx_equal_p (operands[0], operands[1]))
2377             operands[2] = tmp;
2378           else
2379             {
2380               operands[2] = operands[1];
2381               operands[1] = tmp;
2382             }
2383         }
2384       else
2385         {
2386           int i;
2387           
2388           if (((unsigned HOST_WIDE_INT) ~INTVAL (operands[2])) < 256)
2389             {
2390               operands[2] = force_reg (SImode,
2391                                        GEN_INT (~INTVAL (operands[2])));
2392               
2393               emit_insn (gen_thumb1_bicsi3 (operands[0], operands[2], operands[1]));
2394               
2395               DONE;
2396             }
2398           for (i = 9; i <= 31; i++)
2399             {
2400               if ((HOST_WIDE_INT_1 << i) - 1 == INTVAL (operands[2]))
2401                 {
2402                   emit_insn (gen_extzv (operands[0], operands[1], GEN_INT (i),
2403                                         const0_rtx));
2404                   DONE;
2405                 }
2406               else if ((HOST_WIDE_INT_1 << i) - 1
2407                        == ~INTVAL (operands[2]))
2408                 {
2409                   rtx shift = GEN_INT (i);
2410                   rtx reg = gen_reg_rtx (SImode);
2411                 
2412                   emit_insn (gen_lshrsi3 (reg, operands[1], shift));
2413                   emit_insn (gen_ashlsi3 (operands[0], reg, shift));
2414                   
2415                   DONE;
2416                 }
2417             }
2419           operands[2] = force_reg (SImode, operands[2]);
2420         }
2421     }
2422   "
2425 ; ??? Check split length for Thumb-2
2426 (define_insn_and_split "*arm_andsi3_insn"
2427   [(set (match_operand:SI         0 "s_register_operand" "=r,l,r,r,r")
2428         (and:SI (match_operand:SI 1 "s_register_operand" "%r,0,r,r,r")
2429                 (match_operand:SI 2 "reg_or_int_operand" "I,l,K,r,?n")))]
2430   "TARGET_32BIT"
2431   "@
2432    and%?\\t%0, %1, %2
2433    and%?\\t%0, %1, %2
2434    bic%?\\t%0, %1, #%B2
2435    and%?\\t%0, %1, %2
2436    #"
2437   "TARGET_32BIT
2438    && CONST_INT_P (operands[2])
2439    && !(const_ok_for_arm (INTVAL (operands[2]))
2440         || const_ok_for_arm (~INTVAL (operands[2])))"
2441   [(clobber (const_int 0))]
2442   "
2443   arm_split_constant  (AND, SImode, curr_insn, 
2444                        INTVAL (operands[2]), operands[0], operands[1], 0);
2445   DONE;
2446   "
2447   [(set_attr "length" "4,4,4,4,16")
2448    (set_attr "predicable" "yes")
2449    (set_attr "predicable_short_it" "no,yes,no,no,no")
2450    (set_attr "type" "logic_imm,logic_imm,logic_reg,logic_reg,logic_imm")]
2453 (define_insn "*andsi3_compare0"
2454   [(set (reg:CC_NOOV CC_REGNUM)
2455         (compare:CC_NOOV
2456          (and:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
2457                  (match_operand:SI 2 "arm_not_operand" "I,K,r"))
2458          (const_int 0)))
2459    (set (match_operand:SI          0 "s_register_operand" "=r,r,r")
2460         (and:SI (match_dup 1) (match_dup 2)))]
2461   "TARGET_32BIT"
2462   "@
2463    ands%?\\t%0, %1, %2
2464    bics%?\\t%0, %1, #%B2
2465    ands%?\\t%0, %1, %2"
2466   [(set_attr "conds" "set")
2467    (set_attr "type" "logics_imm,logics_imm,logics_reg")]
2470 (define_insn "*andsi3_compare0_scratch"
2471   [(set (reg:CC_NOOV CC_REGNUM)
2472         (compare:CC_NOOV
2473          (and:SI (match_operand:SI 0 "s_register_operand" "r,r,r")
2474                  (match_operand:SI 1 "arm_not_operand" "I,K,r"))
2475          (const_int 0)))
2476    (clobber (match_scratch:SI 2 "=X,r,X"))]
2477   "TARGET_32BIT"
2478   "@
2479    tst%?\\t%0, %1
2480    bics%?\\t%2, %0, #%B1
2481    tst%?\\t%0, %1"
2482   [(set_attr "conds" "set")
2483    (set_attr "type"  "logics_imm,logics_imm,logics_reg")]
2486 (define_insn "*zeroextractsi_compare0_scratch"
2487   [(set (reg:CC_NOOV CC_REGNUM)
2488         (compare:CC_NOOV (zero_extract:SI
2489                           (match_operand:SI 0 "s_register_operand" "r")
2490                           (match_operand 1 "const_int_operand" "n")
2491                           (match_operand 2 "const_int_operand" "n"))
2492                          (const_int 0)))]
2493   "TARGET_32BIT
2494   && (INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) < 32
2495       && INTVAL (operands[1]) > 0 
2496       && INTVAL (operands[1]) + (INTVAL (operands[2]) & 1) <= 8
2497       && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32)"
2498   "*
2499   operands[1] = GEN_INT (((1 << INTVAL (operands[1])) - 1)
2500                          << INTVAL (operands[2]));
2501   output_asm_insn (\"tst%?\\t%0, %1\", operands);
2502   return \"\";
2503   "
2504   [(set_attr "conds" "set")
2505    (set_attr "predicable" "yes")
2506    (set_attr "type" "logics_imm")]
2509 (define_insn_and_split "*ne_zeroextractsi"
2510   [(set (match_operand:SI 0 "s_register_operand" "=r")
2511         (ne:SI (zero_extract:SI
2512                 (match_operand:SI 1 "s_register_operand" "r")
2513                 (match_operand:SI 2 "const_int_operand" "n")
2514                 (match_operand:SI 3 "const_int_operand" "n"))
2515                (const_int 0)))
2516    (clobber (reg:CC CC_REGNUM))]
2517   "TARGET_32BIT
2518    && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2519        && INTVAL (operands[2]) > 0 
2520        && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2521        && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)"
2522   "#"
2523   "TARGET_32BIT
2524    && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2525        && INTVAL (operands[2]) > 0 
2526        && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2527        && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)"
2528   [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2529                    (compare:CC_NOOV (and:SI (match_dup 1) (match_dup 2))
2530                                     (const_int 0)))
2531               (set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))])
2532    (set (match_dup 0)
2533         (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2534                          (match_dup 0) (const_int 1)))]
2535   "
2536   operands[2] = GEN_INT (((1 << INTVAL (operands[2])) - 1)
2537                          << INTVAL (operands[3])); 
2538   "
2539   [(set_attr "conds" "clob")
2540    (set (attr "length")
2541         (if_then_else (eq_attr "is_thumb" "yes")
2542                       (const_int 12)
2543                       (const_int 8)))
2544    (set_attr "type" "multiple")]
2547 (define_insn_and_split "*ne_zeroextractsi_shifted"
2548   [(set (match_operand:SI 0 "s_register_operand" "=r")
2549         (ne:SI (zero_extract:SI
2550                 (match_operand:SI 1 "s_register_operand" "r")
2551                 (match_operand:SI 2 "const_int_operand" "n")
2552                 (const_int 0))
2553                (const_int 0)))
2554    (clobber (reg:CC CC_REGNUM))]
2555   "TARGET_ARM"
2556   "#"
2557   "TARGET_ARM"
2558   [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2559                    (compare:CC_NOOV (ashift:SI (match_dup 1) (match_dup 2))
2560                                     (const_int 0)))
2561               (set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))])
2562    (set (match_dup 0)
2563         (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2564                          (match_dup 0) (const_int 1)))]
2565   "
2566   operands[2] = GEN_INT (32 - INTVAL (operands[2]));
2567   "
2568   [(set_attr "conds" "clob")
2569    (set_attr "length" "8")
2570    (set_attr "type" "multiple")]
2573 (define_insn_and_split "*ite_ne_zeroextractsi"
2574   [(set (match_operand:SI 0 "s_register_operand" "=r")
2575         (if_then_else:SI (ne (zero_extract:SI
2576                               (match_operand:SI 1 "s_register_operand" "r")
2577                               (match_operand:SI 2 "const_int_operand" "n")
2578                               (match_operand:SI 3 "const_int_operand" "n"))
2579                              (const_int 0))
2580                          (match_operand:SI 4 "arm_not_operand" "rIK")
2581                          (const_int 0)))
2582    (clobber (reg:CC CC_REGNUM))]
2583   "TARGET_ARM
2584    && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2585        && INTVAL (operands[2]) > 0 
2586        && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2587        && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)
2588    && !reg_overlap_mentioned_p (operands[0], operands[4])"
2589   "#"
2590   "TARGET_ARM
2591    && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2592        && INTVAL (operands[2]) > 0 
2593        && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2594        && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)
2595    && !reg_overlap_mentioned_p (operands[0], operands[4])"
2596   [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2597                    (compare:CC_NOOV (and:SI (match_dup 1) (match_dup 2))
2598                                     (const_int 0)))
2599               (set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))])
2600    (set (match_dup 0)
2601         (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2602                          (match_dup 0) (match_dup 4)))]
2603   "
2604   operands[2] = GEN_INT (((1 << INTVAL (operands[2])) - 1)
2605                          << INTVAL (operands[3])); 
2606   "
2607   [(set_attr "conds" "clob")
2608    (set_attr "length" "8")
2609    (set_attr "type" "multiple")]
2612 (define_insn_and_split "*ite_ne_zeroextractsi_shifted"
2613   [(set (match_operand:SI 0 "s_register_operand" "=r")
2614         (if_then_else:SI (ne (zero_extract:SI
2615                               (match_operand:SI 1 "s_register_operand" "r")
2616                               (match_operand:SI 2 "const_int_operand" "n")
2617                               (const_int 0))
2618                              (const_int 0))
2619                          (match_operand:SI 3 "arm_not_operand" "rIK")
2620                          (const_int 0)))
2621    (clobber (reg:CC CC_REGNUM))]
2622   "TARGET_ARM && !reg_overlap_mentioned_p (operands[0], operands[3])"
2623   "#"
2624   "TARGET_ARM && !reg_overlap_mentioned_p (operands[0], operands[3])"
2625   [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2626                    (compare:CC_NOOV (ashift:SI (match_dup 1) (match_dup 2))
2627                                     (const_int 0)))
2628               (set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))])
2629    (set (match_dup 0)
2630         (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2631                          (match_dup 0) (match_dup 3)))]
2632   "
2633   operands[2] = GEN_INT (32 - INTVAL (operands[2]));
2634   "
2635   [(set_attr "conds" "clob")
2636    (set_attr "length" "8")
2637    (set_attr "type" "multiple")]
2640 ;; ??? Use Thumb-2 has bitfield insert/extract instructions.
2641 (define_split
2642   [(set (match_operand:SI 0 "s_register_operand" "")
2643         (match_operator:SI 1 "shiftable_operator"
2644          [(zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
2645                            (match_operand:SI 3 "const_int_operand" "")
2646                            (match_operand:SI 4 "const_int_operand" ""))
2647           (match_operand:SI 5 "s_register_operand" "")]))
2648    (clobber (match_operand:SI 6 "s_register_operand" ""))]
2649   "TARGET_ARM"
2650   [(set (match_dup 6) (ashift:SI (match_dup 2) (match_dup 3)))
2651    (set (match_dup 0)
2652         (match_op_dup 1
2653          [(lshiftrt:SI (match_dup 6) (match_dup 4))
2654           (match_dup 5)]))]
2655   "{
2656      HOST_WIDE_INT temp = INTVAL (operands[3]);
2658      operands[3] = GEN_INT (32 - temp - INTVAL (operands[4]));
2659      operands[4] = GEN_INT (32 - temp);
2660    }"
2662   
2663 (define_split
2664   [(set (match_operand:SI 0 "s_register_operand" "")
2665         (match_operator:SI 1 "shiftable_operator"
2666          [(sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
2667                            (match_operand:SI 3 "const_int_operand" "")
2668                            (match_operand:SI 4 "const_int_operand" ""))
2669           (match_operand:SI 5 "s_register_operand" "")]))
2670    (clobber (match_operand:SI 6 "s_register_operand" ""))]
2671   "TARGET_ARM"
2672   [(set (match_dup 6) (ashift:SI (match_dup 2) (match_dup 3)))
2673    (set (match_dup 0)
2674         (match_op_dup 1
2675          [(ashiftrt:SI (match_dup 6) (match_dup 4))
2676           (match_dup 5)]))]
2677   "{
2678      HOST_WIDE_INT temp = INTVAL (operands[3]);
2680      operands[3] = GEN_INT (32 - temp - INTVAL (operands[4]));
2681      operands[4] = GEN_INT (32 - temp);
2682    }"
2684   
2685 ;;; ??? This pattern is bogus.  If operand3 has bits outside the range
2686 ;;; represented by the bitfield, then this will produce incorrect results.
2687 ;;; Somewhere, the value needs to be truncated.  On targets like the m68k,
2688 ;;; which have a real bit-field insert instruction, the truncation happens
2689 ;;; in the bit-field insert instruction itself.  Since arm does not have a
2690 ;;; bit-field insert instruction, we would have to emit code here to truncate
2691 ;;; the value before we insert.  This loses some of the advantage of having
2692 ;;; this insv pattern, so this pattern needs to be reevalutated.
2694 (define_expand "insv"
2695   [(set (zero_extract (match_operand 0 "nonimmediate_operand" "")
2696                       (match_operand 1 "general_operand" "")
2697                       (match_operand 2 "general_operand" ""))
2698         (match_operand 3 "reg_or_int_operand" ""))]
2699   "TARGET_ARM || arm_arch_thumb2"
2700   "
2701   {
2702     int start_bit = INTVAL (operands[2]);
2703     int width = INTVAL (operands[1]);
2704     HOST_WIDE_INT mask = (HOST_WIDE_INT_1 << width) - 1;
2705     rtx target, subtarget;
2707     if (arm_arch_thumb2)
2708       {
2709         if (unaligned_access && MEM_P (operands[0])
2710             && s_register_operand (operands[3], GET_MODE (operands[3]))
2711             && (width == 16 || width == 32) && (start_bit % BITS_PER_UNIT) == 0)
2712           {
2713             rtx base_addr;
2715             if (BYTES_BIG_ENDIAN)
2716               start_bit = GET_MODE_BITSIZE (GET_MODE (operands[3])) - width
2717                           - start_bit;
2719             if (width == 32)
2720               {
2721                 base_addr = adjust_address (operands[0], SImode,
2722                                             start_bit / BITS_PER_UNIT);
2723                 emit_insn (gen_unaligned_storesi (base_addr, operands[3]));
2724               }
2725             else
2726               {
2727                 rtx tmp = gen_reg_rtx (HImode);
2729                 base_addr = adjust_address (operands[0], HImode,
2730                                             start_bit / BITS_PER_UNIT);
2731                 emit_move_insn (tmp, gen_lowpart (HImode, operands[3]));
2732                 emit_insn (gen_unaligned_storehi (base_addr, tmp));
2733               }
2734             DONE;
2735           }
2736         else if (s_register_operand (operands[0], GET_MODE (operands[0])))
2737           {
2738             bool use_bfi = TRUE;
2740             if (CONST_INT_P (operands[3]))
2741               {
2742                 HOST_WIDE_INT val = INTVAL (operands[3]) & mask;
2744                 if (val == 0)
2745                   {
2746                     emit_insn (gen_insv_zero (operands[0], operands[1],
2747                                               operands[2]));
2748                     DONE;
2749                   }
2751                 /* See if the set can be done with a single orr instruction.  */
2752                 if (val == mask && const_ok_for_arm (val << start_bit))
2753                   use_bfi = FALSE;
2754               }
2756             if (use_bfi)
2757               {
2758                 if (!REG_P (operands[3]))
2759                   operands[3] = force_reg (SImode, operands[3]);
2761                 emit_insn (gen_insv_t2 (operands[0], operands[1], operands[2],
2762                                         operands[3]));
2763                 DONE;
2764               }
2765           }
2766         else
2767           FAIL;
2768       }
2770     if (!s_register_operand (operands[0], GET_MODE (operands[0])))
2771       FAIL;
2773     target = copy_rtx (operands[0]);
2774     /* Avoid using a subreg as a subtarget, and avoid writing a paradoxical 
2775        subreg as the final target.  */
2776     if (GET_CODE (target) == SUBREG)
2777       {
2778         subtarget = gen_reg_rtx (SImode);
2779         if (GET_MODE_SIZE (GET_MODE (SUBREG_REG (target)))
2780             < GET_MODE_SIZE (SImode))
2781           target = SUBREG_REG (target);
2782       }
2783     else
2784       subtarget = target;    
2786     if (CONST_INT_P (operands[3]))
2787       {
2788         /* Since we are inserting a known constant, we may be able to
2789            reduce the number of bits that we have to clear so that
2790            the mask becomes simple.  */
2791         /* ??? This code does not check to see if the new mask is actually
2792            simpler.  It may not be.  */
2793         rtx op1 = gen_reg_rtx (SImode);
2794         /* ??? Truncate operand3 to fit in the bitfield.  See comment before
2795            start of this pattern.  */
2796         HOST_WIDE_INT op3_value = mask & INTVAL (operands[3]);
2797         HOST_WIDE_INT mask2 = ((mask & ~op3_value) << start_bit);
2799         emit_insn (gen_andsi3 (op1, operands[0],
2800                                gen_int_mode (~mask2, SImode)));
2801         emit_insn (gen_iorsi3 (subtarget, op1,
2802                                gen_int_mode (op3_value << start_bit, SImode)));
2803       }
2804     else if (start_bit == 0
2805              && !(const_ok_for_arm (mask)
2806                   || const_ok_for_arm (~mask)))
2807       {
2808         /* A Trick, since we are setting the bottom bits in the word,
2809            we can shift operand[3] up, operand[0] down, OR them together
2810            and rotate the result back again.  This takes 3 insns, and
2811            the third might be mergeable into another op.  */
2812         /* The shift up copes with the possibility that operand[3] is
2813            wider than the bitfield.  */
2814         rtx op0 = gen_reg_rtx (SImode);
2815         rtx op1 = gen_reg_rtx (SImode);
2817         emit_insn (gen_ashlsi3 (op0, operands[3], GEN_INT (32 - width)));
2818         emit_insn (gen_lshrsi3 (op1, operands[0], operands[1]));
2819         emit_insn (gen_iorsi3  (op1, op1, op0));
2820         emit_insn (gen_rotlsi3 (subtarget, op1, operands[1]));
2821       }
2822     else if ((width + start_bit == 32)
2823              && !(const_ok_for_arm (mask)
2824                   || const_ok_for_arm (~mask)))
2825       {
2826         /* Similar trick, but slightly less efficient.  */
2828         rtx op0 = gen_reg_rtx (SImode);
2829         rtx op1 = gen_reg_rtx (SImode);
2831         emit_insn (gen_ashlsi3 (op0, operands[3], GEN_INT (32 - width)));
2832         emit_insn (gen_ashlsi3 (op1, operands[0], operands[1]));
2833         emit_insn (gen_lshrsi3 (op1, op1, operands[1]));
2834         emit_insn (gen_iorsi3 (subtarget, op1, op0));
2835       }
2836     else
2837       {
2838         rtx op0 = gen_int_mode (mask, SImode);
2839         rtx op1 = gen_reg_rtx (SImode);
2840         rtx op2 = gen_reg_rtx (SImode);
2842         if (!(const_ok_for_arm (mask) || const_ok_for_arm (~mask)))
2843           {
2844             rtx tmp = gen_reg_rtx (SImode);
2846             emit_insn (gen_movsi (tmp, op0));
2847             op0 = tmp;
2848           }
2850         /* Mask out any bits in operand[3] that are not needed.  */
2851            emit_insn (gen_andsi3 (op1, operands[3], op0));
2853         if (CONST_INT_P (op0)
2854             && (const_ok_for_arm (mask << start_bit)
2855                 || const_ok_for_arm (~(mask << start_bit))))
2856           {
2857             op0 = gen_int_mode (~(mask << start_bit), SImode);
2858             emit_insn (gen_andsi3 (op2, operands[0], op0));
2859           }
2860         else
2861           {
2862             if (CONST_INT_P (op0))
2863               {
2864                 rtx tmp = gen_reg_rtx (SImode);
2866                 emit_insn (gen_movsi (tmp, op0));
2867                 op0 = tmp;
2868               }
2870             if (start_bit != 0)
2871               emit_insn (gen_ashlsi3 (op0, op0, operands[2]));
2872             
2873             emit_insn (gen_andsi_notsi_si (op2, operands[0], op0));
2874           }
2876         if (start_bit != 0)
2877           emit_insn (gen_ashlsi3 (op1, op1, operands[2]));
2879         emit_insn (gen_iorsi3 (subtarget, op1, op2));
2880       }
2882     if (subtarget != target)
2883       {
2884         /* If TARGET is still a SUBREG, then it must be wider than a word,
2885            so we must be careful only to set the subword we were asked to.  */
2886         if (GET_CODE (target) == SUBREG)
2887           emit_move_insn (target, subtarget);
2888         else
2889           emit_move_insn (target, gen_lowpart (GET_MODE (target), subtarget));
2890       }
2892     DONE;
2893   }"
2896 (define_insn "insv_zero"
2897   [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r")
2898                          (match_operand:SI 1 "const_int_M_operand" "M")
2899                          (match_operand:SI 2 "const_int_M_operand" "M"))
2900         (const_int 0))]
2901   "arm_arch_thumb2"
2902   "bfc%?\t%0, %2, %1"
2903   [(set_attr "length" "4")
2904    (set_attr "predicable" "yes")
2905    (set_attr "type" "bfm")]
2908 (define_insn "insv_t2"
2909   [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r")
2910                          (match_operand:SI 1 "const_int_M_operand" "M")
2911                          (match_operand:SI 2 "const_int_M_operand" "M"))
2912         (match_operand:SI 3 "s_register_operand" "r"))]
2913   "arm_arch_thumb2"
2914   "bfi%?\t%0, %3, %2, %1"
2915   [(set_attr "length" "4")
2916    (set_attr "predicable" "yes")
2917    (set_attr "type" "bfm")]
2920 ; constants for op 2 will never be given to these patterns.
2921 (define_insn_and_split "*anddi_notdi_di"
2922   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2923         (and:DI (not:DI (match_operand:DI 1 "s_register_operand" "0,r"))
2924                 (match_operand:DI 2 "s_register_operand" "r,0")))]
2925   "TARGET_32BIT"
2926   "#"
2927   "TARGET_32BIT && reload_completed
2928    && ! (TARGET_NEON && IS_VFP_REGNUM (REGNO (operands[0])))
2929    && ! IS_IWMMXT_REGNUM (REGNO (operands[0]))"
2930   [(set (match_dup 0) (and:SI (not:SI (match_dup 1)) (match_dup 2)))
2931    (set (match_dup 3) (and:SI (not:SI (match_dup 4)) (match_dup 5)))]
2932   "
2933   {
2934     operands[3] = gen_highpart (SImode, operands[0]);
2935     operands[0] = gen_lowpart (SImode, operands[0]);
2936     operands[4] = gen_highpart (SImode, operands[1]);
2937     operands[1] = gen_lowpart (SImode, operands[1]);
2938     operands[5] = gen_highpart (SImode, operands[2]);
2939     operands[2] = gen_lowpart (SImode, operands[2]);
2940   }"
2941   [(set_attr "length" "8")
2942    (set_attr "predicable" "yes")
2943    (set_attr "type" "multiple")]
2946 (define_insn_and_split "*anddi_notzesidi_di"
2947   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2948         (and:DI (not:DI (zero_extend:DI
2949                          (match_operand:SI 2 "s_register_operand" "r,r")))
2950                 (match_operand:DI 1 "s_register_operand" "0,?r")))]
2951   "TARGET_32BIT"
2952   "@
2953    bic%?\\t%Q0, %Q1, %2
2954    #"
2955   ; (not (zero_extend ...)) allows us to just copy the high word from
2956   ; operand1 to operand0.
2957   "TARGET_32BIT
2958    && reload_completed
2959    && operands[0] != operands[1]"
2960   [(set (match_dup 0) (and:SI (not:SI (match_dup 2)) (match_dup 1)))
2961    (set (match_dup 3) (match_dup 4))]
2962   "
2963   {
2964     operands[3] = gen_highpart (SImode, operands[0]);
2965     operands[0] = gen_lowpart (SImode, operands[0]);
2966     operands[4] = gen_highpart (SImode, operands[1]);
2967     operands[1] = gen_lowpart (SImode, operands[1]);
2968   }"
2969   [(set_attr "length" "4,8")
2970    (set_attr "predicable" "yes")
2971    (set_attr "type" "multiple")]
2974 (define_insn_and_split "*anddi_notdi_zesidi"
2975   [(set (match_operand:DI 0 "s_register_operand" "=r")
2976         (and:DI (not:DI (match_operand:DI 2 "s_register_operand" "r"))
2977                 (zero_extend:DI
2978                  (match_operand:SI 1 "s_register_operand" "r"))))]
2979   "TARGET_32BIT"
2980   "#"
2981   "TARGET_32BIT && reload_completed"
2982   [(set (match_dup 0) (and:SI (not:SI (match_dup 2)) (match_dup 1)))
2983    (set (match_dup 3) (const_int 0))]
2984   "
2985   {
2986     operands[3] = gen_highpart (SImode, operands[0]);
2987     operands[0] = gen_lowpart (SImode, operands[0]);
2988     operands[2] = gen_lowpart (SImode, operands[2]);
2989   }"
2990   [(set_attr "length" "8")
2991    (set_attr "predicable" "yes")
2992    (set_attr "type" "multiple")]
2995 (define_insn_and_split "*anddi_notsesidi_di"
2996   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2997         (and:DI (not:DI (sign_extend:DI
2998                          (match_operand:SI 2 "s_register_operand" "r,r")))
2999                 (match_operand:DI 1 "s_register_operand" "0,r")))]
3000   "TARGET_32BIT"
3001   "#"
3002   "TARGET_32BIT && reload_completed"
3003   [(set (match_dup 0) (and:SI (not:SI (match_dup 2)) (match_dup 1)))
3004    (set (match_dup 3) (and:SI (not:SI
3005                                 (ashiftrt:SI (match_dup 2) (const_int 31)))
3006                                (match_dup 4)))]
3007   "
3008   {
3009     operands[3] = gen_highpart (SImode, operands[0]);
3010     operands[0] = gen_lowpart (SImode, operands[0]);
3011     operands[4] = gen_highpart (SImode, operands[1]);
3012     operands[1] = gen_lowpart (SImode, operands[1]);
3013   }"
3014   [(set_attr "length" "8")
3015    (set_attr "predicable" "yes")
3016    (set_attr "type" "multiple")]
3019 (define_insn "andsi_notsi_si"
3020   [(set (match_operand:SI 0 "s_register_operand" "=r")
3021         (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
3022                 (match_operand:SI 1 "s_register_operand" "r")))]
3023   "TARGET_32BIT"
3024   "bic%?\\t%0, %1, %2"
3025   [(set_attr "predicable" "yes")
3026    (set_attr "type" "logic_reg")]
3029 (define_insn "andsi_not_shiftsi_si"
3030   [(set (match_operand:SI 0 "s_register_operand" "=r")
3031         (and:SI (not:SI (match_operator:SI 4 "shift_operator"
3032                          [(match_operand:SI 2 "s_register_operand" "r")
3033                           (match_operand:SI 3 "arm_rhs_operand" "rM")]))
3034                 (match_operand:SI 1 "s_register_operand" "r")))]
3035   "TARGET_ARM"
3036   "bic%?\\t%0, %1, %2%S4"
3037   [(set_attr "predicable" "yes")
3038    (set_attr "shift" "2")
3039    (set (attr "type") (if_then_else (match_operand 3 "const_int_operand" "")
3040                       (const_string "logic_shift_imm")
3041                       (const_string "logic_shift_reg")))]
3044 ;; Shifted bics pattern used to set up CC status register and not reusing
3045 ;; bics output.  Pattern restricts Thumb2 shift operand as bics for Thumb2
3046 ;; does not support shift by register.
3047 (define_insn "andsi_not_shiftsi_si_scc_no_reuse"
3048   [(set (reg:CC_NOOV CC_REGNUM)
3049         (compare:CC_NOOV
3050                 (and:SI (not:SI (match_operator:SI 0 "shift_operator"
3051                         [(match_operand:SI 1 "s_register_operand" "r")
3052                          (match_operand:SI 2 "arm_rhs_operand" "rM")]))
3053                         (match_operand:SI 3 "s_register_operand" "r"))
3054                 (const_int 0)))
3055    (clobber (match_scratch:SI 4 "=r"))]
3056   "TARGET_ARM || (TARGET_THUMB2 && CONST_INT_P (operands[2]))"
3057   "bics%?\\t%4, %3, %1%S0"
3058   [(set_attr "predicable" "yes")
3059    (set_attr "conds" "set")
3060    (set_attr "shift" "1")
3061    (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
3062                       (const_string "logic_shift_imm")
3063                       (const_string "logic_shift_reg")))]
3066 ;; Same as andsi_not_shiftsi_si_scc_no_reuse, but the bics result is also
3067 ;; getting reused later.
3068 (define_insn "andsi_not_shiftsi_si_scc"
3069   [(parallel [(set (reg:CC_NOOV CC_REGNUM)
3070         (compare:CC_NOOV
3071                 (and:SI (not:SI (match_operator:SI 0 "shift_operator"
3072                         [(match_operand:SI 1 "s_register_operand" "r")
3073                          (match_operand:SI 2 "arm_rhs_operand" "rM")]))
3074                         (match_operand:SI 3 "s_register_operand" "r"))
3075                 (const_int 0)))
3076         (set (match_operand:SI 4 "s_register_operand" "=r")
3077              (and:SI (not:SI (match_op_dup 0
3078                      [(match_dup 1)
3079                       (match_dup 2)]))
3080                      (match_dup 3)))])]
3081   "TARGET_ARM || (TARGET_THUMB2 && CONST_INT_P (operands[2]))"
3082   "bics%?\\t%4, %3, %1%S0"
3083   [(set_attr "predicable" "yes")
3084    (set_attr "conds" "set")
3085    (set_attr "shift" "1")
3086    (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
3087                       (const_string "logic_shift_imm")
3088                       (const_string "logic_shift_reg")))]
3091 (define_insn "*andsi_notsi_si_compare0"
3092   [(set (reg:CC_NOOV CC_REGNUM)
3093         (compare:CC_NOOV
3094          (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
3095                  (match_operand:SI 1 "s_register_operand" "r"))
3096          (const_int 0)))
3097    (set (match_operand:SI 0 "s_register_operand" "=r")
3098         (and:SI (not:SI (match_dup 2)) (match_dup 1)))]
3099   "TARGET_32BIT"
3100   "bics\\t%0, %1, %2"
3101   [(set_attr "conds" "set")
3102    (set_attr "type" "logics_shift_reg")]
3105 (define_insn "*andsi_notsi_si_compare0_scratch"
3106   [(set (reg:CC_NOOV CC_REGNUM)
3107         (compare:CC_NOOV
3108          (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
3109                  (match_operand:SI 1 "s_register_operand" "r"))
3110          (const_int 0)))
3111    (clobber (match_scratch:SI 0 "=r"))]
3112   "TARGET_32BIT"
3113   "bics\\t%0, %1, %2"
3114   [(set_attr "conds" "set")
3115    (set_attr "type" "logics_shift_reg")]
3118 (define_expand "iordi3"
3119   [(set (match_operand:DI         0 "s_register_operand" "")
3120         (ior:DI (match_operand:DI 1 "s_register_operand" "")
3121                 (match_operand:DI 2 "neon_logic_op2" "")))]
3122   "TARGET_32BIT"
3123   "
3124   if (!TARGET_NEON && !TARGET_IWMMXT)
3125     {
3126       rtx low  = simplify_gen_binary (IOR, SImode,
3127                                       gen_lowpart (SImode, operands[1]),
3128                                       gen_lowpart (SImode, operands[2]));
3129       rtx high = simplify_gen_binary (IOR, SImode,
3130                                       gen_highpart (SImode, operands[1]),
3131                                       gen_highpart_mode (SImode, DImode,
3132                                                          operands[2]));
3134       emit_insn (gen_rtx_SET (gen_lowpart (SImode, operands[0]), low));
3135       emit_insn (gen_rtx_SET (gen_highpart (SImode, operands[0]), high));
3137       DONE;
3138     }
3139   /* Otherwise expand pattern as above.  */
3140   "
3143 (define_insn_and_split "*iordi3_insn"
3144   [(set (match_operand:DI         0 "s_register_operand"     "=w,w ,&r,&r,&r,&r,?w,?w")
3145         (ior:DI (match_operand:DI 1 "s_register_operand"     "%w,0 ,0 ,r ,0 ,r ,w ,0")
3146                 (match_operand:DI 2 "arm_iordi_operand_neon" "w ,Dl,r ,r ,Df,Df,w ,Dl")))]
3147   "TARGET_32BIT && !TARGET_IWMMXT"
3148   {
3149   switch (which_alternative)
3150     {
3151     case 0: /* fall through */
3152     case 6: return "vorr\t%P0, %P1, %P2";
3153     case 1: /* fall through */
3154     case 7: return neon_output_logic_immediate ("vorr", &operands[2],
3155                      DImode, 0, VALID_NEON_QREG_MODE (DImode));
3156     case 2:
3157     case 3:
3158     case 4:
3159     case 5:
3160       return "#";
3161     default: gcc_unreachable ();
3162     }
3163   }
3164   "TARGET_32BIT && !TARGET_IWMMXT && reload_completed
3165    && !(IS_VFP_REGNUM (REGNO (operands[0])))"
3166   [(set (match_dup 3) (match_dup 4))
3167    (set (match_dup 5) (match_dup 6))]
3168   "
3169   {
3170     operands[3] = gen_lowpart (SImode, operands[0]);
3171     operands[5] = gen_highpart (SImode, operands[0]);
3173     operands[4] = simplify_gen_binary (IOR, SImode,
3174                                            gen_lowpart (SImode, operands[1]),
3175                                            gen_lowpart (SImode, operands[2]));
3176     operands[6] = simplify_gen_binary (IOR, SImode,
3177                                            gen_highpart (SImode, operands[1]),
3178                                            gen_highpart_mode (SImode, DImode, operands[2]));
3180   }"
3181   [(set_attr "type" "neon_logic,neon_logic,multiple,multiple,multiple,\
3182                      multiple,neon_logic,neon_logic")
3183    (set_attr "length" "*,*,8,8,8,8,*,*")
3184    (set_attr "arch" "neon_for_64bits,neon_for_64bits,*,*,*,*,avoid_neon_for_64bits,avoid_neon_for_64bits")]
3187 (define_insn "*iordi_zesidi_di"
3188   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
3189         (ior:DI (zero_extend:DI
3190                  (match_operand:SI 2 "s_register_operand" "r,r"))
3191                 (match_operand:DI 1 "s_register_operand" "0,?r")))]
3192   "TARGET_32BIT"
3193   "@
3194    orr%?\\t%Q0, %Q1, %2
3195    #"
3196   [(set_attr "length" "4,8")
3197    (set_attr "predicable" "yes")
3198    (set_attr "type" "logic_reg,multiple")]
3201 (define_insn "*iordi_sesidi_di"
3202   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
3203         (ior:DI (sign_extend:DI
3204                  (match_operand:SI 2 "s_register_operand" "r,r"))
3205                 (match_operand:DI 1 "s_register_operand" "0,r")))]
3206   "TARGET_32BIT"
3207   "#"
3208   [(set_attr "length" "8")
3209    (set_attr "predicable" "yes")
3210    (set_attr "type" "multiple")]
3213 (define_expand "iorsi3"
3214   [(set (match_operand:SI         0 "s_register_operand" "")
3215         (ior:SI (match_operand:SI 1 "s_register_operand" "")
3216                 (match_operand:SI 2 "reg_or_int_operand" "")))]
3217   "TARGET_EITHER"
3218   "
3219   if (CONST_INT_P (operands[2]))
3220     {
3221       if (TARGET_32BIT)
3222         {
3223           if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[2]), IOR))
3224             operands[2] = force_reg (SImode, operands[2]);
3225           else
3226             {
3227               arm_split_constant (IOR, SImode, NULL_RTX,
3228                                   INTVAL (operands[2]), operands[0],
3229                                   operands[1],
3230                                   optimize && can_create_pseudo_p ());
3231               DONE;
3232             }
3233         }
3234       else /* TARGET_THUMB1 */
3235         {
3236           rtx tmp = force_reg (SImode, operands[2]);
3237           if (rtx_equal_p (operands[0], operands[1]))
3238             operands[2] = tmp;
3239           else
3240             {
3241               operands[2] = operands[1];
3242               operands[1] = tmp;
3243             }
3244         }
3245     }
3246   "
3249 (define_insn_and_split "*iorsi3_insn"
3250   [(set (match_operand:SI 0 "s_register_operand" "=r,l,r,r,r")
3251         (ior:SI (match_operand:SI 1 "s_register_operand" "%r,0,r,r,r")
3252                 (match_operand:SI 2 "reg_or_int_operand" "I,l,K,r,?n")))]
3253   "TARGET_32BIT"
3254   "@
3255    orr%?\\t%0, %1, %2
3256    orr%?\\t%0, %1, %2
3257    orn%?\\t%0, %1, #%B2
3258    orr%?\\t%0, %1, %2
3259    #"
3260   "TARGET_32BIT
3261    && CONST_INT_P (operands[2])
3262    && !(const_ok_for_arm (INTVAL (operands[2]))
3263         || (TARGET_THUMB2 && const_ok_for_arm (~INTVAL (operands[2]))))"
3264   [(clobber (const_int 0))]
3266   arm_split_constant (IOR, SImode, curr_insn,
3267                       INTVAL (operands[2]), operands[0], operands[1], 0);
3268   DONE;
3270   [(set_attr "length" "4,4,4,4,16")
3271    (set_attr "arch" "32,t2,t2,32,32")
3272    (set_attr "predicable" "yes")
3273    (set_attr "predicable_short_it" "no,yes,no,no,no")
3274    (set_attr "type" "logic_imm,logic_reg,logic_imm,logic_reg,logic_reg")]
3277 (define_peephole2
3278   [(match_scratch:SI 3 "r")
3279    (set (match_operand:SI 0 "arm_general_register_operand" "")
3280         (ior:SI (match_operand:SI 1 "arm_general_register_operand" "")
3281                 (match_operand:SI 2 "const_int_operand" "")))]
3282   "TARGET_ARM
3283    && !const_ok_for_arm (INTVAL (operands[2]))
3284    && const_ok_for_arm (~INTVAL (operands[2]))"
3285   [(set (match_dup 3) (match_dup 2))
3286    (set (match_dup 0) (ior:SI (match_dup 1) (match_dup 3)))]
3287   ""
3290 (define_insn "*iorsi3_compare0"
3291   [(set (reg:CC_NOOV CC_REGNUM)
3292         (compare:CC_NOOV (ior:SI (match_operand:SI 1 "s_register_operand" "%r,r")
3293                                  (match_operand:SI 2 "arm_rhs_operand" "I,r"))
3294                          (const_int 0)))
3295    (set (match_operand:SI 0 "s_register_operand" "=r,r")
3296         (ior:SI (match_dup 1) (match_dup 2)))]
3297   "TARGET_32BIT"
3298   "orrs%?\\t%0, %1, %2"
3299   [(set_attr "conds" "set")
3300    (set_attr "type" "logics_imm,logics_reg")]
3303 (define_insn "*iorsi3_compare0_scratch"
3304   [(set (reg:CC_NOOV CC_REGNUM)
3305         (compare:CC_NOOV (ior:SI (match_operand:SI 1 "s_register_operand" "%r,r")
3306                                  (match_operand:SI 2 "arm_rhs_operand" "I,r"))
3307                          (const_int 0)))
3308    (clobber (match_scratch:SI 0 "=r,r"))]
3309   "TARGET_32BIT"
3310   "orrs%?\\t%0, %1, %2"
3311   [(set_attr "conds" "set")
3312    (set_attr "type" "logics_imm,logics_reg")]
3315 (define_expand "xordi3"
3316   [(set (match_operand:DI         0 "s_register_operand" "")
3317         (xor:DI (match_operand:DI 1 "s_register_operand" "")
3318                 (match_operand:DI 2 "arm_xordi_operand" "")))]
3319   "TARGET_32BIT"
3320   {
3321     /* The iWMMXt pattern for xordi3 accepts only register operands but we want
3322        to reuse this expander for all TARGET_32BIT targets so just force the
3323        constants into a register.  Unlike for the anddi3 and iordi3 there are
3324        no NEON instructions that take an immediate.  */
3325     if (TARGET_IWMMXT && !REG_P (operands[2]))
3326       operands[2] = force_reg (DImode, operands[2]);
3327     if (!TARGET_NEON && !TARGET_IWMMXT)
3328       {
3329         rtx low  = simplify_gen_binary (XOR, SImode,
3330                                         gen_lowpart (SImode, operands[1]),
3331                                         gen_lowpart (SImode, operands[2]));
3332         rtx high = simplify_gen_binary (XOR, SImode,
3333                                         gen_highpart (SImode, operands[1]),
3334                                         gen_highpart_mode (SImode, DImode,
3335                                                            operands[2]));
3337         emit_insn (gen_rtx_SET (gen_lowpart (SImode, operands[0]), low));
3338         emit_insn (gen_rtx_SET (gen_highpart (SImode, operands[0]), high));
3340         DONE;
3341       }
3342     /* Otherwise expand pattern as above.  */
3343   }
3346 (define_insn_and_split "*xordi3_insn"
3347   [(set (match_operand:DI         0 "s_register_operand" "=w,&r,&r,&r,&r,?w")
3348         (xor:DI (match_operand:DI 1 "s_register_operand" "%w ,0,r ,0 ,r ,w")
3349                 (match_operand:DI 2 "arm_xordi_operand"  "w ,r ,r ,Dg,Dg,w")))]
3350   "TARGET_32BIT && !TARGET_IWMMXT"
3352   switch (which_alternative)
3353     {
3354     case 1:
3355     case 2:
3356     case 3:
3357     case 4:  /* fall through */
3358       return "#";
3359     case 0: /* fall through */
3360     case 5: return "veor\t%P0, %P1, %P2";
3361     default: gcc_unreachable ();
3362     }
3364   "TARGET_32BIT && !TARGET_IWMMXT && reload_completed
3365    && !(IS_VFP_REGNUM (REGNO (operands[0])))"
3366   [(set (match_dup 3) (match_dup 4))
3367    (set (match_dup 5) (match_dup 6))]
3368   "
3369   {
3370     operands[3] = gen_lowpart (SImode, operands[0]);
3371     operands[5] = gen_highpart (SImode, operands[0]);
3373     operands[4] = simplify_gen_binary (XOR, SImode,
3374                                            gen_lowpart (SImode, operands[1]),
3375                                            gen_lowpart (SImode, operands[2]));
3376     operands[6] = simplify_gen_binary (XOR, SImode,
3377                                            gen_highpart (SImode, operands[1]),
3378                                            gen_highpart_mode (SImode, DImode, operands[2]));
3380   }"
3381   [(set_attr "length" "*,8,8,8,8,*")
3382    (set_attr "type" "neon_logic,multiple,multiple,multiple,multiple,neon_logic")
3383    (set_attr "arch" "neon_for_64bits,*,*,*,*,avoid_neon_for_64bits")]
3386 (define_insn "*xordi_zesidi_di"
3387   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
3388         (xor:DI (zero_extend:DI
3389                  (match_operand:SI 2 "s_register_operand" "r,r"))
3390                 (match_operand:DI 1 "s_register_operand" "0,?r")))]
3391   "TARGET_32BIT"
3392   "@
3393    eor%?\\t%Q0, %Q1, %2
3394    #"
3395   [(set_attr "length" "4,8")
3396    (set_attr "predicable" "yes")
3397    (set_attr "type" "logic_reg")]
3400 (define_insn "*xordi_sesidi_di"
3401   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
3402         (xor:DI (sign_extend:DI
3403                  (match_operand:SI 2 "s_register_operand" "r,r"))
3404                 (match_operand:DI 1 "s_register_operand" "0,r")))]
3405   "TARGET_32BIT"
3406   "#"
3407   [(set_attr "length" "8")
3408    (set_attr "predicable" "yes")
3409    (set_attr "type" "multiple")]
3412 (define_expand "xorsi3"
3413   [(set (match_operand:SI         0 "s_register_operand" "")
3414         (xor:SI (match_operand:SI 1 "s_register_operand" "")
3415                 (match_operand:SI 2 "reg_or_int_operand" "")))]
3416   "TARGET_EITHER"
3417   "if (CONST_INT_P (operands[2]))
3418     {
3419       if (TARGET_32BIT)
3420         {
3421           if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[2]), XOR))
3422             operands[2] = force_reg (SImode, operands[2]);
3423           else
3424             {
3425               arm_split_constant (XOR, SImode, NULL_RTX,
3426                                   INTVAL (operands[2]), operands[0],
3427                                   operands[1],
3428                                   optimize && can_create_pseudo_p ());
3429               DONE;
3430             }
3431         }
3432       else /* TARGET_THUMB1 */
3433         {
3434           rtx tmp = force_reg (SImode, operands[2]);
3435           if (rtx_equal_p (operands[0], operands[1]))
3436             operands[2] = tmp;
3437           else
3438             {
3439               operands[2] = operands[1];
3440               operands[1] = tmp;
3441             }
3442         }
3443     }"
3446 (define_insn_and_split "*arm_xorsi3"
3447   [(set (match_operand:SI         0 "s_register_operand" "=r,l,r,r")
3448         (xor:SI (match_operand:SI 1 "s_register_operand" "%r,0,r,r")
3449                 (match_operand:SI 2 "reg_or_int_operand" "I,l,r,?n")))]
3450   "TARGET_32BIT"
3451   "@
3452    eor%?\\t%0, %1, %2
3453    eor%?\\t%0, %1, %2
3454    eor%?\\t%0, %1, %2
3455    #"
3456   "TARGET_32BIT
3457    && CONST_INT_P (operands[2])
3458    && !const_ok_for_arm (INTVAL (operands[2]))"
3459   [(clobber (const_int 0))]
3461   arm_split_constant (XOR, SImode, curr_insn,
3462                       INTVAL (operands[2]), operands[0], operands[1], 0);
3463   DONE;
3465   [(set_attr "length" "4,4,4,16")
3466    (set_attr "predicable" "yes")
3467    (set_attr "predicable_short_it" "no,yes,no,no")
3468    (set_attr "type"  "logic_imm,logic_reg,logic_reg,multiple")]
3471 (define_insn "*xorsi3_compare0"
3472   [(set (reg:CC_NOOV CC_REGNUM)
3473         (compare:CC_NOOV (xor:SI (match_operand:SI 1 "s_register_operand" "r,r")
3474                                  (match_operand:SI 2 "arm_rhs_operand" "I,r"))
3475                          (const_int 0)))
3476    (set (match_operand:SI 0 "s_register_operand" "=r,r")
3477         (xor:SI (match_dup 1) (match_dup 2)))]
3478   "TARGET_32BIT"
3479   "eors%?\\t%0, %1, %2"
3480   [(set_attr "conds" "set")
3481    (set_attr "type" "logics_imm,logics_reg")]
3484 (define_insn "*xorsi3_compare0_scratch"
3485   [(set (reg:CC_NOOV CC_REGNUM)
3486         (compare:CC_NOOV (xor:SI (match_operand:SI 0 "s_register_operand" "r,r")
3487                                  (match_operand:SI 1 "arm_rhs_operand" "I,r"))
3488                          (const_int 0)))]
3489   "TARGET_32BIT"
3490   "teq%?\\t%0, %1"
3491   [(set_attr "conds" "set")
3492    (set_attr "type" "logics_imm,logics_reg")]
3495 ; By splitting (IOR (AND (NOT A) (NOT B)) C) as D = AND (IOR A B) (NOT C), 
3496 ; (NOT D) we can sometimes merge the final NOT into one of the following
3497 ; insns.
3499 (define_split
3500   [(set (match_operand:SI 0 "s_register_operand" "")
3501         (ior:SI (and:SI (not:SI (match_operand:SI 1 "s_register_operand" ""))
3502                         (not:SI (match_operand:SI 2 "arm_rhs_operand" "")))
3503                 (match_operand:SI 3 "arm_rhs_operand" "")))
3504    (clobber (match_operand:SI 4 "s_register_operand" ""))]
3505   "TARGET_32BIT"
3506   [(set (match_dup 4) (and:SI (ior:SI (match_dup 1) (match_dup 2))
3507                               (not:SI (match_dup 3))))
3508    (set (match_dup 0) (not:SI (match_dup 4)))]
3509   ""
3512 (define_insn_and_split "*andsi_iorsi3_notsi"
3513   [(set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r")
3514         (and:SI (ior:SI (match_operand:SI 1 "s_register_operand" "%0,r,r")
3515                         (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI"))
3516                 (not:SI (match_operand:SI 3 "arm_rhs_operand" "rI,rI,rI"))))]
3517   "TARGET_32BIT"
3518   "#"   ; "orr%?\\t%0, %1, %2\;bic%?\\t%0, %0, %3"
3519   "&& reload_completed"
3520   [(set (match_dup 0) (ior:SI (match_dup 1) (match_dup 2)))
3521    (set (match_dup 0) (and:SI (match_dup 4) (match_dup 5)))]
3522   {
3523      /* If operands[3] is a constant make sure to fold the NOT into it
3524         to avoid creating a NOT of a CONST_INT.  */
3525     rtx not_rtx = simplify_gen_unary (NOT, SImode, operands[3], SImode);
3526     if (CONST_INT_P (not_rtx))
3527       {
3528         operands[4] = operands[0];
3529         operands[5] = not_rtx;
3530       }
3531     else
3532       {
3533         operands[5] = operands[0];
3534         operands[4] = not_rtx;
3535       }
3536   }
3537   [(set_attr "length" "8")
3538    (set_attr "ce_count" "2")
3539    (set_attr "predicable" "yes")
3540    (set_attr "type" "multiple")]
3543 ; ??? Are these four splitters still beneficial when the Thumb-2 bitfield
3544 ; insns are available?
3545 (define_split
3546   [(set (match_operand:SI 0 "s_register_operand" "")
3547         (match_operator:SI 1 "logical_binary_operator"
3548          [(zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
3549                            (match_operand:SI 3 "const_int_operand" "")
3550                            (match_operand:SI 4 "const_int_operand" ""))
3551           (match_operator:SI 9 "logical_binary_operator"
3552            [(lshiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3553                          (match_operand:SI 6 "const_int_operand" ""))
3554             (match_operand:SI 7 "s_register_operand" "")])]))
3555    (clobber (match_operand:SI 8 "s_register_operand" ""))]
3556   "TARGET_32BIT
3557    && GET_CODE (operands[1]) == GET_CODE (operands[9])
3558    && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3559   [(set (match_dup 8)
3560         (match_op_dup 1
3561          [(ashift:SI (match_dup 2) (match_dup 4))
3562           (match_dup 5)]))
3563    (set (match_dup 0)
3564         (match_op_dup 1
3565          [(lshiftrt:SI (match_dup 8) (match_dup 6))
3566           (match_dup 7)]))]
3567   "
3568   operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3571 (define_split
3572   [(set (match_operand:SI 0 "s_register_operand" "")
3573         (match_operator:SI 1 "logical_binary_operator"
3574          [(match_operator:SI 9 "logical_binary_operator"
3575            [(lshiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3576                          (match_operand:SI 6 "const_int_operand" ""))
3577             (match_operand:SI 7 "s_register_operand" "")])
3578           (zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
3579                            (match_operand:SI 3 "const_int_operand" "")
3580                            (match_operand:SI 4 "const_int_operand" ""))]))
3581    (clobber (match_operand:SI 8 "s_register_operand" ""))]
3582   "TARGET_32BIT
3583    && GET_CODE (operands[1]) == GET_CODE (operands[9])
3584    && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3585   [(set (match_dup 8)
3586         (match_op_dup 1
3587          [(ashift:SI (match_dup 2) (match_dup 4))
3588           (match_dup 5)]))
3589    (set (match_dup 0)
3590         (match_op_dup 1
3591          [(lshiftrt:SI (match_dup 8) (match_dup 6))
3592           (match_dup 7)]))]
3593   "
3594   operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3597 (define_split
3598   [(set (match_operand:SI 0 "s_register_operand" "")
3599         (match_operator:SI 1 "logical_binary_operator"
3600          [(sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
3601                            (match_operand:SI 3 "const_int_operand" "")
3602                            (match_operand:SI 4 "const_int_operand" ""))
3603           (match_operator:SI 9 "logical_binary_operator"
3604            [(ashiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3605                          (match_operand:SI 6 "const_int_operand" ""))
3606             (match_operand:SI 7 "s_register_operand" "")])]))
3607    (clobber (match_operand:SI 8 "s_register_operand" ""))]
3608   "TARGET_32BIT
3609    && GET_CODE (operands[1]) == GET_CODE (operands[9])
3610    && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3611   [(set (match_dup 8)
3612         (match_op_dup 1
3613          [(ashift:SI (match_dup 2) (match_dup 4))
3614           (match_dup 5)]))
3615    (set (match_dup 0)
3616         (match_op_dup 1
3617          [(ashiftrt:SI (match_dup 8) (match_dup 6))
3618           (match_dup 7)]))]
3619   "
3620   operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3623 (define_split
3624   [(set (match_operand:SI 0 "s_register_operand" "")
3625         (match_operator:SI 1 "logical_binary_operator"
3626          [(match_operator:SI 9 "logical_binary_operator"
3627            [(ashiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3628                          (match_operand:SI 6 "const_int_operand" ""))
3629             (match_operand:SI 7 "s_register_operand" "")])
3630           (sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
3631                            (match_operand:SI 3 "const_int_operand" "")
3632                            (match_operand:SI 4 "const_int_operand" ""))]))
3633    (clobber (match_operand:SI 8 "s_register_operand" ""))]
3634   "TARGET_32BIT
3635    && GET_CODE (operands[1]) == GET_CODE (operands[9])
3636    && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3637   [(set (match_dup 8)
3638         (match_op_dup 1
3639          [(ashift:SI (match_dup 2) (match_dup 4))
3640           (match_dup 5)]))
3641    (set (match_dup 0)
3642         (match_op_dup 1
3643          [(ashiftrt:SI (match_dup 8) (match_dup 6))
3644           (match_dup 7)]))]
3645   "
3646   operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3650 ;; Minimum and maximum insns
3652 (define_expand "smaxsi3"
3653   [(parallel [
3654     (set (match_operand:SI 0 "s_register_operand" "")
3655          (smax:SI (match_operand:SI 1 "s_register_operand" "")
3656                   (match_operand:SI 2 "arm_rhs_operand" "")))
3657     (clobber (reg:CC CC_REGNUM))])]
3658   "TARGET_32BIT"
3659   "
3660   if (operands[2] == const0_rtx || operands[2] == constm1_rtx)
3661     {
3662       /* No need for a clobber of the condition code register here.  */
3663       emit_insn (gen_rtx_SET (operands[0],
3664                               gen_rtx_SMAX (SImode, operands[1],
3665                                             operands[2])));
3666       DONE;
3667     }
3670 (define_insn "*smax_0"
3671   [(set (match_operand:SI 0 "s_register_operand" "=r")
3672         (smax:SI (match_operand:SI 1 "s_register_operand" "r")
3673                  (const_int 0)))]
3674   "TARGET_32BIT"
3675   "bic%?\\t%0, %1, %1, asr #31"
3676   [(set_attr "predicable" "yes")
3677    (set_attr "type" "logic_shift_reg")]
3680 (define_insn "*smax_m1"
3681   [(set (match_operand:SI 0 "s_register_operand" "=r")
3682         (smax:SI (match_operand:SI 1 "s_register_operand" "r")
3683                  (const_int -1)))]
3684   "TARGET_32BIT"
3685   "orr%?\\t%0, %1, %1, asr #31"
3686   [(set_attr "predicable" "yes")
3687    (set_attr "type" "logic_shift_reg")]
3690 (define_insn_and_split "*arm_smax_insn"
3691   [(set (match_operand:SI          0 "s_register_operand" "=r,r")
3692         (smax:SI (match_operand:SI 1 "s_register_operand"  "%0,?r")
3693                  (match_operand:SI 2 "arm_rhs_operand"    "rI,rI")))
3694    (clobber (reg:CC CC_REGNUM))]
3695   "TARGET_ARM"
3696   "#"
3697    ; cmp\\t%1, %2\;movlt\\t%0, %2
3698    ; cmp\\t%1, %2\;movge\\t%0, %1\;movlt\\t%0, %2"
3699   "TARGET_ARM"
3700   [(set (reg:CC CC_REGNUM)
3701         (compare:CC (match_dup 1) (match_dup 2)))
3702    (set (match_dup 0)
3703         (if_then_else:SI (ge:SI (reg:CC CC_REGNUM) (const_int 0))
3704                          (match_dup 1)
3705                          (match_dup 2)))]
3706   ""
3707   [(set_attr "conds" "clob")
3708    (set_attr "length" "8,12")
3709    (set_attr "type" "multiple")]
3712 (define_expand "sminsi3"
3713   [(parallel [
3714     (set (match_operand:SI 0 "s_register_operand" "")
3715          (smin:SI (match_operand:SI 1 "s_register_operand" "")
3716                   (match_operand:SI 2 "arm_rhs_operand" "")))
3717     (clobber (reg:CC CC_REGNUM))])]
3718   "TARGET_32BIT"
3719   "
3720   if (operands[2] == const0_rtx)
3721     {
3722       /* No need for a clobber of the condition code register here.  */
3723       emit_insn (gen_rtx_SET (operands[0],
3724                               gen_rtx_SMIN (SImode, operands[1],
3725                                             operands[2])));
3726       DONE;
3727     }
3730 (define_insn "*smin_0"
3731   [(set (match_operand:SI 0 "s_register_operand" "=r")
3732         (smin:SI (match_operand:SI 1 "s_register_operand" "r")
3733                  (const_int 0)))]
3734   "TARGET_32BIT"
3735   "and%?\\t%0, %1, %1, asr #31"
3736   [(set_attr "predicable" "yes")
3737    (set_attr "type" "logic_shift_reg")]
3740 (define_insn_and_split "*arm_smin_insn"
3741   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3742         (smin:SI (match_operand:SI 1 "s_register_operand" "%0,?r")
3743                  (match_operand:SI 2 "arm_rhs_operand" "rI,rI")))
3744    (clobber (reg:CC CC_REGNUM))]
3745   "TARGET_ARM"
3746   "#"
3747     ; cmp\\t%1, %2\;movge\\t%0, %2
3748     ; cmp\\t%1, %2\;movlt\\t%0, %1\;movge\\t%0, %2"
3749   "TARGET_ARM"
3750   [(set (reg:CC CC_REGNUM)
3751         (compare:CC (match_dup 1) (match_dup 2)))
3752    (set (match_dup 0)
3753         (if_then_else:SI (lt:SI (reg:CC CC_REGNUM) (const_int 0))
3754                          (match_dup 1)
3755                          (match_dup 2)))]
3756   ""
3757   [(set_attr "conds" "clob")
3758    (set_attr "length" "8,12")
3759    (set_attr "type" "multiple,multiple")]
3762 (define_expand "umaxsi3"
3763   [(parallel [
3764     (set (match_operand:SI 0 "s_register_operand" "")
3765          (umax:SI (match_operand:SI 1 "s_register_operand" "")
3766                   (match_operand:SI 2 "arm_rhs_operand" "")))
3767     (clobber (reg:CC CC_REGNUM))])]
3768   "TARGET_32BIT"
3769   ""
3772 (define_insn_and_split "*arm_umaxsi3"
3773   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
3774         (umax:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
3775                  (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
3776    (clobber (reg:CC CC_REGNUM))]
3777   "TARGET_ARM"
3778   "#"
3779     ; cmp\\t%1, %2\;movcc\\t%0, %2
3780     ; cmp\\t%1, %2\;movcs\\t%0, %1
3781     ; cmp\\t%1, %2\;movcs\\t%0, %1\;movcc\\t%0, %2"
3782   "TARGET_ARM"
3783   [(set (reg:CC CC_REGNUM)
3784         (compare:CC (match_dup 1) (match_dup 2)))
3785    (set (match_dup 0)
3786         (if_then_else:SI (geu:SI (reg:CC CC_REGNUM) (const_int 0))
3787                          (match_dup 1)
3788                          (match_dup 2)))]
3789   ""
3790   [(set_attr "conds" "clob")
3791    (set_attr "length" "8,8,12")
3792    (set_attr "type" "store_4")]
3795 (define_expand "uminsi3"
3796   [(parallel [
3797     (set (match_operand:SI 0 "s_register_operand" "")
3798          (umin:SI (match_operand:SI 1 "s_register_operand" "")
3799                   (match_operand:SI 2 "arm_rhs_operand" "")))
3800     (clobber (reg:CC CC_REGNUM))])]
3801   "TARGET_32BIT"
3802   ""
3805 (define_insn_and_split "*arm_uminsi3"
3806   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
3807         (umin:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
3808                  (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
3809    (clobber (reg:CC CC_REGNUM))]
3810   "TARGET_ARM"
3811   "#"
3812    ; cmp\\t%1, %2\;movcs\\t%0, %2
3813    ; cmp\\t%1, %2\;movcc\\t%0, %1
3814    ; cmp\\t%1, %2\;movcc\\t%0, %1\;movcs\\t%0, %2"
3815   "TARGET_ARM"
3816   [(set (reg:CC CC_REGNUM)
3817         (compare:CC (match_dup 1) (match_dup 2)))
3818    (set (match_dup 0)
3819         (if_then_else:SI (ltu:SI (reg:CC CC_REGNUM) (const_int 0))
3820                          (match_dup 1)
3821                          (match_dup 2)))]
3822   ""
3823   [(set_attr "conds" "clob")
3824    (set_attr "length" "8,8,12")
3825    (set_attr "type" "store_4")]
3828 (define_insn "*store_minmaxsi"
3829   [(set (match_operand:SI 0 "memory_operand" "=m")
3830         (match_operator:SI 3 "minmax_operator"
3831          [(match_operand:SI 1 "s_register_operand" "r")
3832           (match_operand:SI 2 "s_register_operand" "r")]))
3833    (clobber (reg:CC CC_REGNUM))]
3834   "TARGET_32BIT && optimize_function_for_size_p (cfun) && !arm_restrict_it"
3835   "*
3836   operands[3] = gen_rtx_fmt_ee (minmax_code (operands[3]), SImode,
3837                                 operands[1], operands[2]);
3838   output_asm_insn (\"cmp\\t%1, %2\", operands);
3839   if (TARGET_THUMB2)
3840     output_asm_insn (\"ite\t%d3\", operands);
3841   output_asm_insn (\"str%d3\\t%1, %0\", operands);
3842   output_asm_insn (\"str%D3\\t%2, %0\", operands);
3843   return \"\";
3844   "
3845   [(set_attr "conds" "clob")
3846    (set (attr "length")
3847         (if_then_else (eq_attr "is_thumb" "yes")
3848                       (const_int 14)
3849                       (const_int 12)))
3850    (set_attr "type" "store_4")]
3853 ; Reject the frame pointer in operand[1], since reloading this after
3854 ; it has been eliminated can cause carnage.
3855 (define_insn "*minmax_arithsi"
3856   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3857         (match_operator:SI 4 "shiftable_operator"
3858          [(match_operator:SI 5 "minmax_operator"
3859            [(match_operand:SI 2 "s_register_operand" "r,r")
3860             (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
3861           (match_operand:SI 1 "s_register_operand" "0,?r")]))
3862    (clobber (reg:CC CC_REGNUM))]
3863   "TARGET_32BIT && !arm_eliminable_register (operands[1]) && !arm_restrict_it"
3864   "*
3865   {
3866     enum rtx_code code = GET_CODE (operands[4]);
3867     bool need_else;
3869     if (which_alternative != 0 || operands[3] != const0_rtx
3870         || (code != PLUS && code != IOR && code != XOR))
3871       need_else = true;
3872     else
3873       need_else = false;
3875     operands[5] = gen_rtx_fmt_ee (minmax_code (operands[5]), SImode,
3876                                   operands[2], operands[3]);
3877     output_asm_insn (\"cmp\\t%2, %3\", operands);
3878     if (TARGET_THUMB2)
3879       {
3880         if (need_else)
3881           output_asm_insn (\"ite\\t%d5\", operands);
3882         else
3883           output_asm_insn (\"it\\t%d5\", operands);
3884       }
3885     output_asm_insn (\"%i4%d5\\t%0, %1, %2\", operands);
3886     if (need_else)
3887       output_asm_insn (\"%i4%D5\\t%0, %1, %3\", operands);
3888     return \"\";
3889   }"
3890   [(set_attr "conds" "clob")
3891    (set (attr "length")
3892         (if_then_else (eq_attr "is_thumb" "yes")
3893                       (const_int 14)
3894                       (const_int 12)))
3895    (set_attr "type" "multiple")]
3898 ; Reject the frame pointer in operand[1], since reloading this after
3899 ; it has been eliminated can cause carnage.
3900 (define_insn_and_split "*minmax_arithsi_non_canon"
3901   [(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts")
3902         (minus:SI
3903          (match_operand:SI 1 "s_register_operand" "0,?Ts")
3904           (match_operator:SI 4 "minmax_operator"
3905            [(match_operand:SI 2 "s_register_operand" "Ts,Ts")
3906             (match_operand:SI 3 "arm_rhs_operand" "TsI,TsI")])))
3907    (clobber (reg:CC CC_REGNUM))]
3908   "TARGET_32BIT && !arm_eliminable_register (operands[1])
3909    && !(arm_restrict_it && CONST_INT_P (operands[3]))"
3910   "#"
3911   "TARGET_32BIT && !arm_eliminable_register (operands[1]) && reload_completed"
3912   [(set (reg:CC CC_REGNUM)
3913         (compare:CC (match_dup 2) (match_dup 3)))
3915    (cond_exec (match_op_dup 4 [(reg:CC CC_REGNUM) (const_int 0)])
3916               (set (match_dup 0)
3917                    (minus:SI (match_dup 1)
3918                              (match_dup 2))))
3919    (cond_exec (match_op_dup 5 [(reg:CC CC_REGNUM) (const_int 0)])
3920               (set (match_dup 0)
3921                    (match_dup 6)))]
3922   {
3923   machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
3924                                            operands[2], operands[3]);
3925   enum rtx_code rc = minmax_code (operands[4]);
3926   operands[4] = gen_rtx_fmt_ee (rc, VOIDmode,
3927                                 operands[2], operands[3]);
3929   if (mode == CCFPmode || mode == CCFPEmode)
3930     rc = reverse_condition_maybe_unordered (rc);
3931   else
3932     rc = reverse_condition (rc);
3933   operands[5] = gen_rtx_fmt_ee (rc, SImode, operands[2], operands[3]);
3934   if (CONST_INT_P (operands[3]))
3935     operands[6] = plus_constant (SImode, operands[1], -INTVAL (operands[3]));
3936   else
3937     operands[6] = gen_rtx_MINUS (SImode, operands[1], operands[3]);
3938   }
3939   [(set_attr "conds" "clob")
3940    (set (attr "length")
3941         (if_then_else (eq_attr "is_thumb" "yes")
3942                       (const_int 14)
3943                       (const_int 12)))
3944    (set_attr "type" "multiple")]
3947 (define_code_iterator SAT [smin smax])
3948 (define_code_iterator SATrev [smin smax])
3949 (define_code_attr SATlo [(smin "1") (smax "2")])
3950 (define_code_attr SAThi [(smin "2") (smax "1")])
3952 (define_insn "*satsi_<SAT:code>"
3953   [(set (match_operand:SI 0 "s_register_operand" "=r")
3954         (SAT:SI (SATrev:SI (match_operand:SI 3 "s_register_operand" "r")
3955                            (match_operand:SI 1 "const_int_operand" "i"))
3956                 (match_operand:SI 2 "const_int_operand" "i")))]
3957   "TARGET_32BIT && arm_arch6 && <SAT:CODE> != <SATrev:CODE>
3958    && arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>], NULL, NULL)"
3960   int mask;
3961   bool signed_sat;
3962   if (!arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>],
3963                                &mask, &signed_sat))
3964     gcc_unreachable ();
3966   operands[1] = GEN_INT (mask);
3967   if (signed_sat)
3968     return "ssat%?\t%0, %1, %3";
3969   else
3970     return "usat%?\t%0, %1, %3";
3972   [(set_attr "predicable" "yes")
3973    (set_attr "type" "alus_imm")]
3976 (define_insn "*satsi_<SAT:code>_shift"
3977   [(set (match_operand:SI 0 "s_register_operand" "=r")
3978         (SAT:SI (SATrev:SI (match_operator:SI 3 "sat_shift_operator"
3979                              [(match_operand:SI 4 "s_register_operand" "r")
3980                               (match_operand:SI 5 "const_int_operand" "i")])
3981                            (match_operand:SI 1 "const_int_operand" "i"))
3982                 (match_operand:SI 2 "const_int_operand" "i")))]
3983   "TARGET_32BIT && arm_arch6 && <SAT:CODE> != <SATrev:CODE>
3984    && arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>], NULL, NULL)"
3986   int mask;
3987   bool signed_sat;
3988   if (!arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>],
3989                                &mask, &signed_sat))
3990     gcc_unreachable ();
3992   operands[1] = GEN_INT (mask);
3993   if (signed_sat)
3994     return "ssat%?\t%0, %1, %4%S3";
3995   else
3996     return "usat%?\t%0, %1, %4%S3";
3998   [(set_attr "predicable" "yes")
3999    (set_attr "shift" "3")
4000    (set_attr "type" "logic_shift_reg")])
4002 ;; Shift and rotation insns
4004 (define_expand "ashldi3"
4005   [(set (match_operand:DI            0 "s_register_operand" "")
4006         (ashift:DI (match_operand:DI 1 "s_register_operand" "")
4007                    (match_operand:SI 2 "general_operand" "")))]
4008   "TARGET_32BIT"
4009   "
4010   if (TARGET_NEON)
4011     {
4012       /* Delay the decision whether to use NEON or core-regs until
4013          register allocation.  */
4014       emit_insn (gen_ashldi3_neon (operands[0], operands[1], operands[2]));
4015       DONE;
4016     }
4017   else
4018     {
4019       /* Only the NEON case can handle in-memory shift counts.  */
4020       if (!reg_or_int_operand (operands[2], SImode))
4021         operands[2] = force_reg (SImode, operands[2]);
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       /* Ideally we should use iwmmxt here if we could know that operands[1]
4031          ends up already living in an iwmmxt register. Otherwise it's
4032          cheaper to have the alternate code being generated than moving
4033          values to iwmmxt regs and back.  */
4035       /* Expand operation using core-registers.
4036          'FAIL' would achieve the same thing, but this is a bit smarter.  */
4037       scratch1 = gen_reg_rtx (SImode);
4038       scratch2 = gen_reg_rtx (SImode);
4039       arm_emit_coreregs_64bit_shift (ASHIFT, operands[0], operands[1],
4040                                      operands[2], scratch1, scratch2);
4041       DONE;
4042     }
4043   "
4046 (define_expand "ashlsi3"
4047   [(set (match_operand:SI            0 "s_register_operand" "")
4048         (ashift:SI (match_operand:SI 1 "s_register_operand" "")
4049                    (match_operand:SI 2 "arm_rhs_operand" "")))]
4050   "TARGET_EITHER"
4051   "
4052   if (CONST_INT_P (operands[2])
4053       && (UINTVAL (operands[2])) > 31)
4054     {
4055       emit_insn (gen_movsi (operands[0], const0_rtx));
4056       DONE;
4057     }
4058   "
4061 (define_expand "ashrdi3"
4062   [(set (match_operand:DI              0 "s_register_operand" "")
4063         (ashiftrt:DI (match_operand:DI 1 "s_register_operand" "")
4064                      (match_operand:SI 2 "reg_or_int_operand" "")))]
4065   "TARGET_32BIT"
4066   "
4067   if (TARGET_NEON)
4068     {
4069       /* Delay the decision whether to use NEON or core-regs until
4070          register allocation.  */
4071       emit_insn (gen_ashrdi3_neon (operands[0], operands[1], operands[2]));
4072       DONE;
4073     }
4075   if (!CONST_INT_P (operands[2]) && TARGET_REALLY_IWMMXT)
4076     ; /* No special preparation statements; expand pattern as above.  */
4077   else
4078     {
4079       rtx scratch1, scratch2;
4081       /* Ideally we should use iwmmxt here if we could know that operands[1]
4082          ends up already living in an iwmmxt register. Otherwise it's
4083          cheaper to have the alternate code being generated than moving
4084          values to iwmmxt regs and back.  */
4086       /* Expand operation using core-registers.
4087          'FAIL' would achieve the same thing, but this is a bit smarter.  */
4088       scratch1 = gen_reg_rtx (SImode);
4089       scratch2 = gen_reg_rtx (SImode);
4090       arm_emit_coreregs_64bit_shift (ASHIFTRT, operands[0], operands[1],
4091                                      operands[2], scratch1, scratch2);
4092       DONE;
4093     }
4094   "
4097 (define_expand "ashrsi3"
4098   [(set (match_operand:SI              0 "s_register_operand" "")
4099         (ashiftrt:SI (match_operand:SI 1 "s_register_operand" "")
4100                      (match_operand:SI 2 "arm_rhs_operand" "")))]
4101   "TARGET_EITHER"
4102   "
4103   if (CONST_INT_P (operands[2])
4104       && UINTVAL (operands[2]) > 31)
4105     operands[2] = GEN_INT (31);
4106   "
4109 (define_expand "lshrdi3"
4110   [(set (match_operand:DI              0 "s_register_operand" "")
4111         (lshiftrt:DI (match_operand:DI 1 "s_register_operand" "")
4112                      (match_operand:SI 2 "reg_or_int_operand" "")))]
4113   "TARGET_32BIT"
4114   "
4115   if (TARGET_NEON)
4116     {
4117       /* Delay the decision whether to use NEON or core-regs until
4118          register allocation.  */
4119       emit_insn (gen_lshrdi3_neon (operands[0], operands[1], operands[2]));
4120       DONE;
4121     }
4123   if (!CONST_INT_P (operands[2]) && TARGET_REALLY_IWMMXT)
4124     ; /* No special preparation statements; expand pattern as above.  */
4125   else
4126     {
4127       rtx scratch1, scratch2;
4129       /* Ideally we should use iwmmxt here if we could know that operands[1]
4130          ends up already living in an iwmmxt register. Otherwise it's
4131          cheaper to have the alternate code being generated than moving
4132          values to iwmmxt regs and back.  */
4134       /* Expand operation using core-registers.
4135          'FAIL' would achieve the same thing, but this is a bit smarter.  */
4136       scratch1 = gen_reg_rtx (SImode);
4137       scratch2 = gen_reg_rtx (SImode);
4138       arm_emit_coreregs_64bit_shift (LSHIFTRT, operands[0], operands[1],
4139                                      operands[2], scratch1, scratch2);
4140       DONE;
4141     }
4142   "
4145 (define_expand "lshrsi3"
4146   [(set (match_operand:SI              0 "s_register_operand" "")
4147         (lshiftrt:SI (match_operand:SI 1 "s_register_operand" "")
4148                      (match_operand:SI 2 "arm_rhs_operand" "")))]
4149   "TARGET_EITHER"
4150   "
4151   if (CONST_INT_P (operands[2])
4152       && (UINTVAL (operands[2])) > 31)
4153     {
4154       emit_insn (gen_movsi (operands[0], const0_rtx));
4155       DONE;
4156     }
4157   "
4160 (define_expand "rotlsi3"
4161   [(set (match_operand:SI              0 "s_register_operand" "")
4162         (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
4163                      (match_operand:SI 2 "reg_or_int_operand" "")))]
4164   "TARGET_32BIT"
4165   "
4166   if (CONST_INT_P (operands[2]))
4167     operands[2] = GEN_INT ((32 - INTVAL (operands[2])) % 32);
4168   else
4169     {
4170       rtx reg = gen_reg_rtx (SImode);
4171       emit_insn (gen_subsi3 (reg, GEN_INT (32), operands[2]));
4172       operands[2] = reg;
4173     }
4174   "
4177 (define_expand "rotrsi3"
4178   [(set (match_operand:SI              0 "s_register_operand" "")
4179         (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
4180                      (match_operand:SI 2 "arm_rhs_operand" "")))]
4181   "TARGET_EITHER"
4182   "
4183   if (TARGET_32BIT)
4184     {
4185       if (CONST_INT_P (operands[2])
4186           && UINTVAL (operands[2]) > 31)
4187         operands[2] = GEN_INT (INTVAL (operands[2]) % 32);
4188     }
4189   else /* TARGET_THUMB1 */
4190     {
4191       if (CONST_INT_P (operands [2]))
4192         operands [2] = force_reg (SImode, operands[2]);
4193     }
4194   "
4197 (define_insn "*arm_shiftsi3"
4198   [(set (match_operand:SI   0 "s_register_operand" "=l,l,r,r")
4199         (match_operator:SI  3 "shift_operator"
4200          [(match_operand:SI 1 "s_register_operand"  "0,l,r,r")
4201           (match_operand:SI 2 "reg_or_int_operand" "l,M,M,r")]))]
4202   "TARGET_32BIT"
4203   "* return arm_output_shift(operands, 0);"
4204   [(set_attr "predicable" "yes")
4205    (set_attr "arch" "t2,t2,*,*")
4206    (set_attr "predicable_short_it" "yes,yes,no,no")
4207    (set_attr "length" "4")
4208    (set_attr "shift" "1")
4209    (set_attr "type" "alu_shift_reg,alu_shift_imm,alu_shift_imm,alu_shift_reg")]
4212 (define_insn "*shiftsi3_compare0"
4213   [(set (reg:CC_NOOV CC_REGNUM)
4214         (compare:CC_NOOV (match_operator:SI 3 "shift_operator"
4215                           [(match_operand:SI 1 "s_register_operand" "r,r")
4216                            (match_operand:SI 2 "arm_rhs_operand" "M,r")])
4217                          (const_int 0)))
4218    (set (match_operand:SI 0 "s_register_operand" "=r,r")
4219         (match_op_dup 3 [(match_dup 1) (match_dup 2)]))]
4220   "TARGET_32BIT"
4221   "* return arm_output_shift(operands, 1);"
4222   [(set_attr "conds" "set")
4223    (set_attr "shift" "1")
4224    (set_attr "type" "alus_shift_imm,alus_shift_reg")]
4227 (define_insn "*shiftsi3_compare0_scratch"
4228   [(set (reg:CC_NOOV CC_REGNUM)
4229         (compare:CC_NOOV (match_operator:SI 3 "shift_operator"
4230                           [(match_operand:SI 1 "s_register_operand" "r,r")
4231                            (match_operand:SI 2 "arm_rhs_operand" "M,r")])
4232                          (const_int 0)))
4233    (clobber (match_scratch:SI 0 "=r,r"))]
4234   "TARGET_32BIT"
4235   "* return arm_output_shift(operands, 1);"
4236   [(set_attr "conds" "set")
4237    (set_attr "shift" "1")
4238    (set_attr "type" "shift_imm,shift_reg")]
4241 (define_insn "*not_shiftsi"
4242   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4243         (not:SI (match_operator:SI 3 "shift_operator"
4244                  [(match_operand:SI 1 "s_register_operand" "r,r")
4245                   (match_operand:SI 2 "shift_amount_operand" "M,rM")])))]
4246   "TARGET_32BIT"
4247   "mvn%?\\t%0, %1%S3"
4248   [(set_attr "predicable" "yes")
4249    (set_attr "shift" "1")
4250    (set_attr "arch" "32,a")
4251    (set_attr "type" "mvn_shift,mvn_shift_reg")])
4253 (define_insn "*not_shiftsi_compare0"
4254   [(set (reg:CC_NOOV CC_REGNUM)
4255         (compare:CC_NOOV
4256          (not:SI (match_operator:SI 3 "shift_operator"
4257                   [(match_operand:SI 1 "s_register_operand" "r,r")
4258                    (match_operand:SI 2 "shift_amount_operand" "M,rM")]))
4259          (const_int 0)))
4260    (set (match_operand:SI 0 "s_register_operand" "=r,r")
4261         (not:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])))]
4262   "TARGET_32BIT"
4263   "mvns%?\\t%0, %1%S3"
4264   [(set_attr "conds" "set")
4265    (set_attr "shift" "1")
4266    (set_attr "arch" "32,a")
4267    (set_attr "type" "mvn_shift,mvn_shift_reg")])
4269 (define_insn "*not_shiftsi_compare0_scratch"
4270   [(set (reg:CC_NOOV CC_REGNUM)
4271         (compare:CC_NOOV
4272          (not:SI (match_operator:SI 3 "shift_operator"
4273                   [(match_operand:SI 1 "s_register_operand" "r,r")
4274                    (match_operand:SI 2 "shift_amount_operand" "M,rM")]))
4275          (const_int 0)))
4276    (clobber (match_scratch:SI 0 "=r,r"))]
4277   "TARGET_32BIT"
4278   "mvns%?\\t%0, %1%S3"
4279   [(set_attr "conds" "set")
4280    (set_attr "shift" "1")
4281    (set_attr "arch" "32,a")
4282    (set_attr "type" "mvn_shift,mvn_shift_reg")])
4284 ;; We don't really have extzv, but defining this using shifts helps
4285 ;; to reduce register pressure later on.
4287 (define_expand "extzv"
4288   [(set (match_operand 0 "s_register_operand" "")
4289         (zero_extract (match_operand 1 "nonimmediate_operand" "")
4290                       (match_operand 2 "const_int_operand" "")
4291                       (match_operand 3 "const_int_operand" "")))]
4292   "TARGET_THUMB1 || arm_arch_thumb2"
4293   "
4294   {
4295     HOST_WIDE_INT lshift = 32 - INTVAL (operands[2]) - INTVAL (operands[3]);
4296     HOST_WIDE_INT rshift = 32 - INTVAL (operands[2]);
4297     
4298     if (arm_arch_thumb2)
4299       {
4300         HOST_WIDE_INT width = INTVAL (operands[2]);
4301         HOST_WIDE_INT bitpos = INTVAL (operands[3]);
4303         if (unaligned_access && MEM_P (operands[1])
4304             && (width == 16 || width == 32) && (bitpos % BITS_PER_UNIT) == 0)
4305           {
4306             rtx base_addr;
4308             if (BYTES_BIG_ENDIAN)
4309               bitpos = GET_MODE_BITSIZE (GET_MODE (operands[0])) - width
4310                        - bitpos;
4312             if (width == 32)
4313               {
4314                 base_addr = adjust_address (operands[1], SImode,
4315                                             bitpos / BITS_PER_UNIT);
4316                 emit_insn (gen_unaligned_loadsi (operands[0], base_addr));
4317               }
4318             else
4319               {
4320                 rtx dest = operands[0];
4321                 rtx tmp = gen_reg_rtx (SImode);
4323                 /* We may get a paradoxical subreg here.  Strip it off.  */
4324                 if (GET_CODE (dest) == SUBREG
4325                     && GET_MODE (dest) == SImode
4326                     && GET_MODE (SUBREG_REG (dest)) == HImode)
4327                   dest = SUBREG_REG (dest);
4329                 if (GET_MODE_BITSIZE (GET_MODE (dest)) != width)
4330                   FAIL;
4332                 base_addr = adjust_address (operands[1], HImode,
4333                                             bitpos / BITS_PER_UNIT);
4334                 emit_insn (gen_unaligned_loadhiu (tmp, base_addr));
4335                 emit_move_insn (gen_lowpart (SImode, dest), tmp);
4336               }
4337             DONE;
4338           }
4339         else if (s_register_operand (operands[1], GET_MODE (operands[1])))
4340           {
4341             emit_insn (gen_extzv_t2 (operands[0], operands[1], operands[2],
4342                                      operands[3]));
4343             DONE;
4344           }
4345         else
4346           FAIL;
4347       }
4348     
4349     if (!s_register_operand (operands[1], GET_MODE (operands[1])))
4350       FAIL;
4352     operands[3] = GEN_INT (rshift);
4353     
4354     if (lshift == 0)
4355       {
4356         emit_insn (gen_lshrsi3 (operands[0], operands[1], operands[3]));
4357         DONE;
4358       }
4359       
4360     emit_insn (gen_extzv_t1 (operands[0], operands[1], GEN_INT (lshift),
4361                              operands[3], gen_reg_rtx (SImode)));
4362     DONE;
4363   }"
4366 ;; Helper for extzv, for the Thumb-1 register-shifts case.
4368 (define_expand "extzv_t1"
4369   [(set (match_operand:SI 4 "s_register_operand" "")
4370         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
4371                    (match_operand:SI 2 "const_int_operand" "")))
4372    (set (match_operand:SI 0 "s_register_operand" "")
4373         (lshiftrt:SI (match_dup 4)
4374                      (match_operand:SI 3 "const_int_operand" "")))]
4375   "TARGET_THUMB1"
4376   "")
4378 (define_expand "extv"
4379   [(set (match_operand 0 "s_register_operand" "")
4380         (sign_extract (match_operand 1 "nonimmediate_operand" "")
4381                       (match_operand 2 "const_int_operand" "")
4382                       (match_operand 3 "const_int_operand" "")))]
4383   "arm_arch_thumb2"
4385   HOST_WIDE_INT width = INTVAL (operands[2]);
4386   HOST_WIDE_INT bitpos = INTVAL (operands[3]);
4388   if (unaligned_access && MEM_P (operands[1]) && (width == 16 || width == 32)
4389       && (bitpos % BITS_PER_UNIT)  == 0)
4390     {
4391       rtx base_addr;
4392       
4393       if (BYTES_BIG_ENDIAN)
4394         bitpos = GET_MODE_BITSIZE (GET_MODE (operands[0])) - width - bitpos;
4395       
4396       if (width == 32)
4397         {
4398           base_addr = adjust_address (operands[1], SImode,
4399                                       bitpos / BITS_PER_UNIT);
4400           emit_insn (gen_unaligned_loadsi (operands[0], base_addr));
4401         }
4402       else
4403         {
4404           rtx dest = operands[0];
4405           rtx tmp = gen_reg_rtx (SImode);
4406           
4407           /* We may get a paradoxical subreg here.  Strip it off.  */
4408           if (GET_CODE (dest) == SUBREG
4409               && GET_MODE (dest) == SImode
4410               && GET_MODE (SUBREG_REG (dest)) == HImode)
4411             dest = SUBREG_REG (dest);
4412           
4413           if (GET_MODE_BITSIZE (GET_MODE (dest)) != width)
4414             FAIL;
4415           
4416           base_addr = adjust_address (operands[1], HImode,
4417                                       bitpos / BITS_PER_UNIT);
4418           emit_insn (gen_unaligned_loadhis (tmp, base_addr));
4419           emit_move_insn (gen_lowpart (SImode, dest), tmp);
4420         }
4422       DONE;
4423     }
4424   else if (!s_register_operand (operands[1], GET_MODE (operands[1])))
4425     FAIL;
4426   else if (GET_MODE (operands[0]) == SImode
4427            && GET_MODE (operands[1]) == SImode)
4428     {
4429       emit_insn (gen_extv_regsi (operands[0], operands[1], operands[2],
4430                                  operands[3]));
4431       DONE;
4432     }
4434   FAIL;
4437 ; Helper to expand register forms of extv with the proper modes.
4439 (define_expand "extv_regsi"
4440   [(set (match_operand:SI 0 "s_register_operand" "")
4441         (sign_extract:SI (match_operand:SI 1 "s_register_operand" "")
4442                          (match_operand 2 "const_int_operand" "")
4443                          (match_operand 3 "const_int_operand" "")))]
4444   ""
4448 ; ARMv6+ unaligned load/store instructions (used for packed structure accesses).
4450 (define_insn "unaligned_loadsi"
4451   [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4452         (unspec:SI [(match_operand:SI 1 "memory_operand" "Uw,m")]
4453                    UNSPEC_UNALIGNED_LOAD))]
4454   "unaligned_access"
4455   "ldr%?\t%0, %1\t@ unaligned"
4456   [(set_attr "arch" "t2,any")
4457    (set_attr "length" "2,4")
4458    (set_attr "predicable" "yes")
4459    (set_attr "predicable_short_it" "yes,no")
4460    (set_attr "type" "load_4")])
4462 (define_insn "unaligned_loadhis"
4463   [(set (match_operand:SI 0 "s_register_operand" "=r")
4464         (sign_extend:SI
4465           (unspec:HI [(match_operand:HI 1 "memory_operand" "Uh")]
4466                      UNSPEC_UNALIGNED_LOAD)))]
4467   "unaligned_access"
4468   "ldrsh%?\t%0, %1\t@ unaligned"
4469   [(set_attr "predicable" "yes")
4470    (set_attr "type" "load_byte")])
4472 (define_insn "unaligned_loadhiu"
4473   [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4474         (zero_extend:SI
4475           (unspec:HI [(match_operand:HI 1 "memory_operand" "Uw,m")]
4476                      UNSPEC_UNALIGNED_LOAD)))]
4477   "unaligned_access"
4478   "ldrh%?\t%0, %1\t@ unaligned"
4479   [(set_attr "arch" "t2,any")
4480    (set_attr "length" "2,4")
4481    (set_attr "predicable" "yes")
4482    (set_attr "predicable_short_it" "yes,no")
4483    (set_attr "type" "load_byte")])
4485 (define_insn "unaligned_storesi"
4486   [(set (match_operand:SI 0 "memory_operand" "=Uw,m")
4487         (unspec:SI [(match_operand:SI 1 "s_register_operand" "l,r")]
4488                    UNSPEC_UNALIGNED_STORE))]
4489   "unaligned_access"
4490   "str%?\t%1, %0\t@ unaligned"
4491   [(set_attr "arch" "t2,any")
4492    (set_attr "length" "2,4")
4493    (set_attr "predicable" "yes")
4494    (set_attr "predicable_short_it" "yes,no")
4495    (set_attr "type" "store_4")])
4497 (define_insn "unaligned_storehi"
4498   [(set (match_operand:HI 0 "memory_operand" "=Uw,m")
4499         (unspec:HI [(match_operand:HI 1 "s_register_operand" "l,r")]
4500                    UNSPEC_UNALIGNED_STORE))]
4501   "unaligned_access"
4502   "strh%?\t%1, %0\t@ unaligned"
4503   [(set_attr "arch" "t2,any")
4504    (set_attr "length" "2,4")
4505    (set_attr "predicable" "yes")
4506    (set_attr "predicable_short_it" "yes,no")
4507    (set_attr "type" "store_4")])
4510 (define_insn "*extv_reg"
4511   [(set (match_operand:SI 0 "s_register_operand" "=r")
4512         (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
4513                           (match_operand:SI 2 "const_int_operand" "n")
4514                           (match_operand:SI 3 "const_int_operand" "n")))]
4515   "arm_arch_thumb2
4516    && IN_RANGE (INTVAL (operands[3]), 0, 31)
4517    && IN_RANGE (INTVAL (operands[2]), 1, 32 - INTVAL (operands[3]))"
4518   "sbfx%?\t%0, %1, %3, %2"
4519   [(set_attr "length" "4")
4520    (set_attr "predicable" "yes")
4521    (set_attr "type" "bfm")]
4524 (define_insn "extzv_t2"
4525   [(set (match_operand:SI 0 "s_register_operand" "=r")
4526         (zero_extract:SI (match_operand:SI 1 "s_register_operand" "r")
4527                           (match_operand:SI 2 "const_int_operand" "n")
4528                           (match_operand:SI 3 "const_int_operand" "n")))]
4529   "arm_arch_thumb2
4530    && IN_RANGE (INTVAL (operands[3]), 0, 31)
4531    && IN_RANGE (INTVAL (operands[2]), 1, 32 - INTVAL (operands[3]))"
4532   "ubfx%?\t%0, %1, %3, %2"
4533   [(set_attr "length" "4")
4534    (set_attr "predicable" "yes")
4535    (set_attr "type" "bfm")]
4539 ;; Division instructions
4540 (define_insn "divsi3"
4541   [(set (match_operand:SI         0 "s_register_operand" "=r,r")
4542         (div:SI (match_operand:SI 1 "s_register_operand"  "r,r")
4543                 (match_operand:SI 2 "s_register_operand"  "r,r")))]
4544   "TARGET_IDIV"
4545   "@
4546    sdiv%?\t%0, %1, %2
4547    sdiv\t%0, %1, %2"
4548   [(set_attr "arch" "32,v8mb")
4549    (set_attr "predicable" "yes")
4550    (set_attr "type" "sdiv")]
4553 (define_insn "udivsi3"
4554   [(set (match_operand:SI          0 "s_register_operand" "=r,r")
4555         (udiv:SI (match_operand:SI 1 "s_register_operand"  "r,r")
4556                  (match_operand:SI 2 "s_register_operand"  "r,r")))]
4557   "TARGET_IDIV"
4558   "@
4559    udiv%?\t%0, %1, %2
4560    udiv\t%0, %1, %2"
4561   [(set_attr "arch" "32,v8mb")
4562    (set_attr "predicable" "yes")
4563    (set_attr "type" "udiv")]
4567 ;; Unary arithmetic insns
4569 (define_expand "negvsi3"
4570   [(match_operand:SI 0 "register_operand")
4571    (match_operand:SI 1 "register_operand")
4572    (match_operand 2 "")]
4573   "TARGET_32BIT"
4575   emit_insn (gen_subsi3_compare (operands[0], const0_rtx, operands[1]));
4576   arm_gen_unlikely_cbranch (NE, CC_Vmode, operands[2]);
4578   DONE;
4581 (define_expand "negvdi3"
4582   [(match_operand:DI 0 "register_operand")
4583    (match_operand:DI 1 "register_operand")
4584    (match_operand 2 "")]
4585   "TARGET_ARM"
4587   emit_insn (gen_negdi2_compare (operands[0], operands[1]));
4588   arm_gen_unlikely_cbranch (NE, CC_Vmode, operands[2]);
4590   DONE;
4594 (define_insn_and_split "negdi2_compare"
4595   [(set (reg:CC CC_REGNUM)
4596         (compare:CC
4597           (const_int 0)
4598           (match_operand:DI 1 "register_operand" "0,r")))
4599    (set (match_operand:DI 0 "register_operand" "=r,&r")
4600         (minus:DI (const_int 0) (match_dup 1)))]
4601   "TARGET_ARM"
4602   "#"
4603   "&& reload_completed"
4604   [(parallel [(set (reg:CC CC_REGNUM)
4605                    (compare:CC (const_int 0) (match_dup 1)))
4606               (set (match_dup 0) (minus:SI (const_int 0)
4607                                            (match_dup 1)))])
4608    (parallel [(set (reg:CC CC_REGNUM)
4609                    (compare:CC (const_int 0) (match_dup 3)))
4610              (set (match_dup 2)
4611                   (minus:SI
4612                    (minus:SI (const_int 0) (match_dup 3))
4613                    (ltu:SI (reg:CC_C CC_REGNUM)
4614                            (const_int 0))))])]
4615   {
4616     operands[2] = gen_highpart (SImode, operands[0]);
4617     operands[0] = gen_lowpart (SImode, operands[0]);
4618     operands[3] = gen_highpart (SImode, operands[1]);
4619     operands[1] = gen_lowpart (SImode, operands[1]);
4620   }
4621   [(set_attr "conds" "set")
4622    (set_attr "length" "8")
4623    (set_attr "type" "multiple")]
4626 (define_expand "negdi2"
4627  [(parallel
4628    [(set (match_operand:DI 0 "s_register_operand" "")
4629          (neg:DI (match_operand:DI 1 "s_register_operand" "")))
4630     (clobber (reg:CC CC_REGNUM))])]
4631   "TARGET_EITHER"
4632   {
4633     if (TARGET_NEON)
4634       {
4635         emit_insn (gen_negdi2_neon (operands[0], operands[1]));
4636         DONE;
4637       }
4638   }
4641 ;; The constraints here are to prevent a *partial* overlap (where %Q0 == %R1).
4642 ;; The first alternative allows the common case of a *full* overlap.
4643 (define_insn_and_split "*negdi2_insn"
4644   [(set (match_operand:DI         0 "s_register_operand" "=r,&r")
4645         (neg:DI (match_operand:DI 1 "s_register_operand"  "0,r")))
4646    (clobber (reg:CC CC_REGNUM))]
4647   "TARGET_32BIT"
4648   "#"   ; rsbs %Q0, %Q1, #0; rsc %R0, %R1, #0          (ARM)
4649         ; negs %Q0, %Q1    ; sbc %R0, %R1, %R1, lsl #1 (Thumb-2)
4650   "&& reload_completed"
4651   [(parallel [(set (reg:CC CC_REGNUM)
4652                    (compare:CC (const_int 0) (match_dup 1)))
4653               (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1)))])
4654    (set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3))
4655                                 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
4656   {
4657     operands[2] = gen_highpart (SImode, operands[0]);
4658     operands[0] = gen_lowpart (SImode, operands[0]);
4659     operands[3] = gen_highpart (SImode, operands[1]);
4660     operands[1] = gen_lowpart (SImode, operands[1]);
4661   }
4662   [(set_attr "conds" "clob")
4663    (set_attr "length" "8")
4664    (set_attr "type" "multiple")]
4667 (define_insn "*negsi2_carryin_compare"
4668   [(set (reg:CC CC_REGNUM)
4669         (compare:CC (const_int 0)
4670                     (match_operand:SI 1 "s_register_operand" "r")))
4671    (set (match_operand:SI 0 "s_register_operand" "=r")
4672         (minus:SI (minus:SI (const_int 0)
4673                             (match_dup 1))
4674                   (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
4675   "TARGET_ARM"
4676   "rscs\\t%0, %1, #0"
4677   [(set_attr "conds" "set")
4678    (set_attr "type" "alus_imm")]
4681 (define_expand "negsi2"
4682   [(set (match_operand:SI         0 "s_register_operand" "")
4683         (neg:SI (match_operand:SI 1 "s_register_operand" "")))]
4684   "TARGET_EITHER"
4685   ""
4688 (define_insn "*arm_negsi2"
4689   [(set (match_operand:SI         0 "s_register_operand" "=l,r")
4690         (neg:SI (match_operand:SI 1 "s_register_operand" "l,r")))]
4691   "TARGET_32BIT"
4692   "rsb%?\\t%0, %1, #0"
4693   [(set_attr "predicable" "yes")
4694    (set_attr "predicable_short_it" "yes,no")
4695    (set_attr "arch" "t2,*")
4696    (set_attr "length" "4")
4697    (set_attr "type" "alu_sreg")]
4700 (define_expand "negsf2"
4701   [(set (match_operand:SF         0 "s_register_operand" "")
4702         (neg:SF (match_operand:SF 1 "s_register_operand" "")))]
4703   "TARGET_32BIT && TARGET_HARD_FLOAT"
4704   ""
4707 (define_expand "negdf2"
4708   [(set (match_operand:DF         0 "s_register_operand" "")
4709         (neg:DF (match_operand:DF 1 "s_register_operand" "")))]
4710   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
4711   "")
4713 (define_insn_and_split "*zextendsidi_negsi"
4714   [(set (match_operand:DI 0 "s_register_operand" "=r")
4715         (zero_extend:DI (neg:SI (match_operand:SI 1 "s_register_operand" "r"))))]
4716    "TARGET_32BIT"
4717    "#"
4718    ""
4719    [(set (match_dup 2)
4720          (neg:SI (match_dup 1)))
4721     (set (match_dup 3)
4722          (const_int 0))]
4723    {
4724       operands[2] = gen_lowpart (SImode, operands[0]);
4725       operands[3] = gen_highpart (SImode, operands[0]);
4726    }
4727  [(set_attr "length" "8")
4728   (set_attr "type" "multiple")]
4731 ;; Negate an extended 32-bit value.
4732 (define_insn_and_split "*negdi_extendsidi"
4733   [(set (match_operand:DI 0 "s_register_operand" "=l,r")
4734         (neg:DI (sign_extend:DI
4735                  (match_operand:SI 1 "s_register_operand" "l,r"))))
4736    (clobber (reg:CC CC_REGNUM))]
4737   "TARGET_32BIT"
4738   "#"
4739   "&& reload_completed"
4740   [(const_int 0)]
4741   {
4742     rtx low = gen_lowpart (SImode, operands[0]);
4743     rtx high = gen_highpart (SImode, operands[0]);
4745     if (reg_overlap_mentioned_p (low, operands[1]))
4746       {
4747         /* Input overlaps the low word of the output.  Use:
4748                 asr     Rhi, Rin, #31
4749                 rsbs    Rlo, Rin, #0
4750                 rsc     Rhi, Rhi, #0 (thumb2: sbc Rhi, Rhi, Rhi, lsl #1).  */
4751         rtx cc_reg = gen_rtx_REG (CC_Cmode, CC_REGNUM);
4753         emit_insn (gen_rtx_SET (high,
4754                                 gen_rtx_ASHIFTRT (SImode, operands[1],
4755                                                   GEN_INT (31))));
4757         emit_insn (gen_subsi3_compare (low, const0_rtx, operands[1]));
4758         if (TARGET_ARM)
4759           emit_insn (gen_rtx_SET (high,
4760                                   gen_rtx_MINUS (SImode,
4761                                                  gen_rtx_MINUS (SImode,
4762                                                                 const0_rtx,
4763                                                                 high),
4764                                                  gen_rtx_LTU (SImode,
4765                                                               cc_reg,
4766                                                               const0_rtx))));
4767         else
4768           {
4769             rtx two_x = gen_rtx_ASHIFT (SImode, high, GEN_INT (1));
4770             emit_insn (gen_rtx_SET (high,
4771                                     gen_rtx_MINUS (SImode,
4772                                                    gen_rtx_MINUS (SImode,
4773                                                                   high,
4774                                                                   two_x),
4775                                                    gen_rtx_LTU (SImode,
4776                                                                 cc_reg,
4777                                                                 const0_rtx))));
4778           }
4779       }
4780     else
4781       {
4782         /* No overlap, or overlap on high word.  Use:
4783                 rsb     Rlo, Rin, #0
4784                 bic     Rhi, Rlo, Rin
4785                 asr     Rhi, Rhi, #31
4786            Flags not needed for this sequence.  */
4787         emit_insn (gen_rtx_SET (low, gen_rtx_NEG (SImode, operands[1])));
4788         emit_insn (gen_rtx_SET (high,
4789                                 gen_rtx_AND (SImode,
4790                                              gen_rtx_NOT (SImode, operands[1]),
4791                                              low)));
4792         emit_insn (gen_rtx_SET (high,
4793                                 gen_rtx_ASHIFTRT (SImode, high,
4794                                                   GEN_INT (31))));
4795       }
4796     DONE;
4797   }
4798   [(set_attr "length" "12")
4799    (set_attr "arch" "t2,*")
4800    (set_attr "type" "multiple")]
4803 (define_insn_and_split "*negdi_zero_extendsidi"
4804   [(set (match_operand:DI 0 "s_register_operand" "=r,&r")
4805         (neg:DI (zero_extend:DI (match_operand:SI 1 "s_register_operand" "0,r"))))
4806    (clobber (reg:CC CC_REGNUM))]
4807   "TARGET_32BIT"
4808   "#" ; "rsbs\\t%Q0, %1, #0\;sbc\\t%R0,%R0,%R0"
4809       ;; Don't care what register is input to sbc,
4810       ;; since we just need to propagate the carry.
4811   "&& reload_completed"
4812   [(parallel [(set (reg:CC CC_REGNUM)
4813                    (compare:CC (const_int 0) (match_dup 1)))
4814               (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1)))])
4815    (set (match_dup 2) (minus:SI (minus:SI (match_dup 2) (match_dup 2))
4816                                 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
4817   {
4818     operands[2] = gen_highpart (SImode, operands[0]);
4819     operands[0] = gen_lowpart (SImode, operands[0]);
4820   }
4821   [(set_attr "conds" "clob")
4822    (set_attr "length" "8")
4823    (set_attr "type" "multiple")]   ;; length in thumb is 4
4826 ;; abssi2 doesn't really clobber the condition codes if a different register
4827 ;; is being set.  To keep things simple, assume during rtl manipulations that
4828 ;; it does, but tell the final scan operator the truth.  Similarly for
4829 ;; (neg (abs...))
4831 (define_expand "abssi2"
4832   [(parallel
4833     [(set (match_operand:SI         0 "s_register_operand" "")
4834           (abs:SI (match_operand:SI 1 "s_register_operand" "")))
4835      (clobber (match_dup 2))])]
4836   "TARGET_EITHER"
4837   "
4838   if (TARGET_THUMB1)
4839     operands[2] = gen_rtx_SCRATCH (SImode);
4840   else
4841     operands[2] = gen_rtx_REG (CCmode, CC_REGNUM);
4844 (define_insn_and_split "*arm_abssi2"
4845   [(set (match_operand:SI 0 "s_register_operand" "=r,&r")
4846         (abs:SI (match_operand:SI 1 "s_register_operand" "0,r")))
4847    (clobber (reg:CC CC_REGNUM))]
4848   "TARGET_ARM"
4849   "#"
4850   "&& reload_completed"
4851   [(const_int 0)]
4852   {
4853    /* if (which_alternative == 0) */
4854    if (REGNO(operands[0]) == REGNO(operands[1]))
4855      {
4856       /* Emit the pattern:
4857          cmp\\t%0, #0\;rsblt\\t%0, %0, #0
4858          [(set (reg:CC CC_REGNUM)
4859                (compare:CC (match_dup 0) (const_int 0)))
4860           (cond_exec (lt:CC (reg:CC CC_REGNUM) (const_int 0))
4861                      (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1))))]
4862       */
4863       emit_insn (gen_rtx_SET (gen_rtx_REG (CCmode, CC_REGNUM),
4864                               gen_rtx_COMPARE (CCmode, operands[0], const0_rtx)));
4865       emit_insn (gen_rtx_COND_EXEC (VOIDmode,
4866                                     (gen_rtx_LT (SImode,
4867                                                  gen_rtx_REG (CCmode, CC_REGNUM),
4868                                                  const0_rtx)),
4869                                     (gen_rtx_SET (operands[0],
4870                                                   (gen_rtx_MINUS (SImode,
4871                                                                   const0_rtx,
4872                                                                   operands[1]))))));
4873       DONE;
4874      }
4875    else
4876      {
4877       /* Emit the pattern:
4878          alt1: eor%?\\t%0, %1, %1, asr #31\;sub%?\\t%0, %0, %1, asr #31
4879          [(set (match_dup 0)
4880                (xor:SI (match_dup 1)
4881                        (ashiftrt:SI (match_dup 1) (const_int 31))))
4882           (set (match_dup 0)
4883                (minus:SI (match_dup 0)
4884                       (ashiftrt:SI (match_dup 1) (const_int 31))))]
4885       */
4886       emit_insn (gen_rtx_SET (operands[0],
4887                               gen_rtx_XOR (SImode,
4888                                            gen_rtx_ASHIFTRT (SImode,
4889                                                              operands[1],
4890                                                              GEN_INT (31)),
4891                                            operands[1])));
4892       emit_insn (gen_rtx_SET (operands[0],
4893                               gen_rtx_MINUS (SImode,
4894                                              operands[0],
4895                                              gen_rtx_ASHIFTRT (SImode,
4896                                                                operands[1],
4897                                                                GEN_INT (31)))));
4898       DONE;
4899      }
4900   }
4901   [(set_attr "conds" "clob,*")
4902    (set_attr "shift" "1")
4903    (set_attr "predicable" "no, yes")
4904    (set_attr "length" "8")
4905    (set_attr "type" "multiple")]
4908 (define_insn_and_split "*arm_neg_abssi2"
4909   [(set (match_operand:SI 0 "s_register_operand" "=r,&r")
4910         (neg:SI (abs:SI (match_operand:SI 1 "s_register_operand" "0,r"))))
4911    (clobber (reg:CC CC_REGNUM))]
4912   "TARGET_ARM"
4913   "#"
4914   "&& reload_completed"
4915   [(const_int 0)]
4916   {
4917    /* if (which_alternative == 0) */
4918    if (REGNO (operands[0]) == REGNO (operands[1]))
4919      {
4920       /* Emit the pattern:
4921          cmp\\t%0, #0\;rsbgt\\t%0, %0, #0
4922       */
4923       emit_insn (gen_rtx_SET (gen_rtx_REG (CCmode, CC_REGNUM),
4924                               gen_rtx_COMPARE (CCmode, operands[0], const0_rtx)));
4925       emit_insn (gen_rtx_COND_EXEC (VOIDmode,
4926                                     gen_rtx_GT (SImode,
4927                                                 gen_rtx_REG (CCmode, CC_REGNUM),
4928                                                 const0_rtx),
4929                                     gen_rtx_SET (operands[0],
4930                                                  (gen_rtx_MINUS (SImode,
4931                                                                  const0_rtx,
4932                                                                  operands[1])))));
4933      }
4934    else
4935      {
4936       /* Emit the pattern:
4937          eor%?\\t%0, %1, %1, asr #31\;rsb%?\\t%0, %0, %1, asr #31
4938       */
4939       emit_insn (gen_rtx_SET (operands[0],
4940                               gen_rtx_XOR (SImode,
4941                                            gen_rtx_ASHIFTRT (SImode,
4942                                                              operands[1],
4943                                                              GEN_INT (31)),
4944                                            operands[1])));
4945       emit_insn (gen_rtx_SET (operands[0],
4946                               gen_rtx_MINUS (SImode,
4947                                              gen_rtx_ASHIFTRT (SImode,
4948                                                                operands[1],
4949                                                                GEN_INT (31)),
4950                                              operands[0])));
4951      }
4952    DONE;
4953   }
4954   [(set_attr "conds" "clob,*")
4955    (set_attr "shift" "1")
4956    (set_attr "predicable" "no, yes")
4957    (set_attr "length" "8")
4958    (set_attr "type" "multiple")]
4961 (define_expand "abssf2"
4962   [(set (match_operand:SF         0 "s_register_operand" "")
4963         (abs:SF (match_operand:SF 1 "s_register_operand" "")))]
4964   "TARGET_32BIT && TARGET_HARD_FLOAT"
4965   "")
4967 (define_expand "absdf2"
4968   [(set (match_operand:DF         0 "s_register_operand" "")
4969         (abs:DF (match_operand:DF 1 "s_register_operand" "")))]
4970   "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
4971   "")
4973 (define_expand "sqrtsf2"
4974   [(set (match_operand:SF 0 "s_register_operand" "")
4975         (sqrt:SF (match_operand:SF 1 "s_register_operand" "")))]
4976   "TARGET_32BIT && TARGET_HARD_FLOAT"
4977   "")
4979 (define_expand "sqrtdf2"
4980   [(set (match_operand:DF 0 "s_register_operand" "")
4981         (sqrt:DF (match_operand:DF 1 "s_register_operand" "")))]
4982   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
4983   "")
4985 (define_expand "one_cmpldi2"
4986   [(set (match_operand:DI 0 "s_register_operand" "")
4987         (not:DI (match_operand:DI 1 "s_register_operand" "")))]
4988   "TARGET_32BIT"
4989   "
4990   if (!TARGET_NEON && !TARGET_IWMMXT)
4991     {
4992       rtx low  = simplify_gen_unary (NOT, SImode,
4993                                      gen_lowpart (SImode, operands[1]),
4994                                      SImode);
4995       rtx high = simplify_gen_unary (NOT, SImode,
4996                                      gen_highpart_mode (SImode, DImode,
4997                                                         operands[1]),
4998                                      SImode);
5000       emit_insn (gen_rtx_SET (gen_lowpart (SImode, operands[0]), low));
5001       emit_insn (gen_rtx_SET (gen_highpart (SImode, operands[0]), high));
5003       DONE;
5004     }
5005   /* Otherwise expand pattern as above.  */
5006   "
5009 (define_insn_and_split "*one_cmpldi2_insn"
5010   [(set (match_operand:DI 0 "s_register_operand"         "=w,&r,&r,?w")
5011         (not:DI (match_operand:DI 1 "s_register_operand" " w, 0, r, w")))]
5012   "TARGET_32BIT"
5013   "@
5014    vmvn\t%P0, %P1
5015    #
5016    #
5017    vmvn\t%P0, %P1"
5018   "TARGET_32BIT && reload_completed
5019    && arm_general_register_operand (operands[0], DImode)"
5020   [(set (match_dup 0) (not:SI (match_dup 1)))
5021    (set (match_dup 2) (not:SI (match_dup 3)))]
5022   "
5023   {
5024     operands[2] = gen_highpart (SImode, operands[0]);
5025     operands[0] = gen_lowpart (SImode, operands[0]);
5026     operands[3] = gen_highpart (SImode, operands[1]);
5027     operands[1] = gen_lowpart (SImode, operands[1]);
5028   }"
5029   [(set_attr "length" "*,8,8,*")
5030    (set_attr "predicable" "no,yes,yes,no")
5031    (set_attr "type" "neon_move,multiple,multiple,neon_move")
5032    (set_attr "arch" "neon_for_64bits,*,*,avoid_neon_for_64bits")]
5035 (define_expand "one_cmplsi2"
5036   [(set (match_operand:SI         0 "s_register_operand" "")
5037         (not:SI (match_operand:SI 1 "s_register_operand" "")))]
5038   "TARGET_EITHER"
5039   ""
5042 (define_insn "*arm_one_cmplsi2"
5043   [(set (match_operand:SI         0 "s_register_operand" "=l,r")
5044         (not:SI (match_operand:SI 1 "s_register_operand"  "l,r")))]
5045   "TARGET_32BIT"
5046   "mvn%?\\t%0, %1"
5047   [(set_attr "predicable" "yes")
5048    (set_attr "predicable_short_it" "yes,no")
5049    (set_attr "arch" "t2,*")
5050    (set_attr "length" "4")
5051    (set_attr "type" "mvn_reg")]
5054 (define_insn "*notsi_compare0"
5055   [(set (reg:CC_NOOV CC_REGNUM)
5056         (compare:CC_NOOV (not:SI (match_operand:SI 1 "s_register_operand" "r"))
5057                          (const_int 0)))
5058    (set (match_operand:SI 0 "s_register_operand" "=r")
5059         (not:SI (match_dup 1)))]
5060   "TARGET_32BIT"
5061   "mvns%?\\t%0, %1"
5062   [(set_attr "conds" "set")
5063    (set_attr "type" "mvn_reg")]
5066 (define_insn "*notsi_compare0_scratch"
5067   [(set (reg:CC_NOOV CC_REGNUM)
5068         (compare:CC_NOOV (not:SI (match_operand:SI 1 "s_register_operand" "r"))
5069                          (const_int 0)))
5070    (clobber (match_scratch:SI 0 "=r"))]
5071   "TARGET_32BIT"
5072   "mvns%?\\t%0, %1"
5073   [(set_attr "conds" "set")
5074    (set_attr "type" "mvn_reg")]
5077 ;; Fixed <--> Floating conversion insns
5079 (define_expand "floatsihf2"
5080   [(set (match_operand:HF           0 "general_operand" "")
5081         (float:HF (match_operand:SI 1 "general_operand" "")))]
5082   "TARGET_EITHER"
5083   "
5084   {
5085     rtx op1 = gen_reg_rtx (SFmode);
5086     expand_float (op1, operands[1], 0);
5087     op1 = convert_to_mode (HFmode, op1, 0);
5088     emit_move_insn (operands[0], op1);
5089     DONE;
5090   }"
5093 (define_expand "floatdihf2"
5094   [(set (match_operand:HF           0 "general_operand" "")
5095         (float:HF (match_operand:DI 1 "general_operand" "")))]
5096   "TARGET_EITHER"
5097   "
5098   {
5099     rtx op1 = gen_reg_rtx (SFmode);
5100     expand_float (op1, operands[1], 0);
5101     op1 = convert_to_mode (HFmode, op1, 0);
5102     emit_move_insn (operands[0], op1);
5103     DONE;
5104   }"
5107 (define_expand "floatsisf2"
5108   [(set (match_operand:SF           0 "s_register_operand" "")
5109         (float:SF (match_operand:SI 1 "s_register_operand" "")))]
5110   "TARGET_32BIT && TARGET_HARD_FLOAT"
5111   "
5114 (define_expand "floatsidf2"
5115   [(set (match_operand:DF           0 "s_register_operand" "")
5116         (float:DF (match_operand:SI 1 "s_register_operand" "")))]
5117   "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
5118   "
5121 (define_expand "fix_trunchfsi2"
5122   [(set (match_operand:SI         0 "general_operand" "")
5123         (fix:SI (fix:HF (match_operand:HF 1 "general_operand"  ""))))]
5124   "TARGET_EITHER"
5125   "
5126   {
5127     rtx op1 = convert_to_mode (SFmode, operands[1], 0);
5128     expand_fix (operands[0], op1, 0);
5129     DONE;
5130   }"
5133 (define_expand "fix_trunchfdi2"
5134   [(set (match_operand:DI         0 "general_operand" "")
5135         (fix:DI (fix:HF (match_operand:HF 1 "general_operand"  ""))))]
5136   "TARGET_EITHER"
5137   "
5138   {
5139     rtx op1 = convert_to_mode (SFmode, operands[1], 0);
5140     expand_fix (operands[0], op1, 0);
5141     DONE;
5142   }"
5145 (define_expand "fix_truncsfsi2"
5146   [(set (match_operand:SI         0 "s_register_operand" "")
5147         (fix:SI (fix:SF (match_operand:SF 1 "s_register_operand"  ""))))]
5148   "TARGET_32BIT && TARGET_HARD_FLOAT"
5149   "
5152 (define_expand "fix_truncdfsi2"
5153   [(set (match_operand:SI         0 "s_register_operand" "")
5154         (fix:SI (fix:DF (match_operand:DF 1 "s_register_operand"  ""))))]
5155   "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
5156   "
5159 ;; Truncation insns
5161 (define_expand "truncdfsf2"
5162   [(set (match_operand:SF  0 "s_register_operand" "")
5163         (float_truncate:SF
5164          (match_operand:DF 1 "s_register_operand" "")))]
5165   "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
5166   ""
5169 ;; DFmode to HFmode conversions on targets without a single-step hardware
5170 ;; instruction for it would have to go through SFmode.  This is dangerous
5171 ;; as it introduces double rounding.
5173 ;; Disable this pattern unless we are in an unsafe math mode, or we have
5174 ;; a single-step instruction.
5176 (define_expand "truncdfhf2"
5177   [(set (match_operand:HF  0 "s_register_operand" "")
5178         (float_truncate:HF
5179          (match_operand:DF 1 "s_register_operand" "")))]
5180   "(TARGET_EITHER && flag_unsafe_math_optimizations)
5181    || (TARGET_32BIT && TARGET_FP16_TO_DOUBLE)"
5183   /* We don't have a direct instruction for this, so we must be in
5184      an unsafe math mode, and going via SFmode.  */
5186   if (!(TARGET_32BIT && TARGET_FP16_TO_DOUBLE))
5187     {
5188       rtx op1;
5189       op1 = convert_to_mode (SFmode, operands[1], 0);
5190       op1 = convert_to_mode (HFmode, op1, 0);
5191       emit_move_insn (operands[0], op1);
5192       DONE;
5193     }
5194   /* Otherwise, we will pick this up as a single instruction with
5195      no intermediary rounding.  */
5199 ;; Zero and sign extension instructions.
5201 (define_insn "zero_extend<mode>di2"
5202   [(set (match_operand:DI 0 "s_register_operand" "=w,r,?r,w")
5203         (zero_extend:DI (match_operand:QHSI 1 "<qhs_zextenddi_op>"
5204                                             "<qhs_zextenddi_cstr>")))]
5205   "TARGET_32BIT <qhs_zextenddi_cond>"
5206   "#"
5207   [(set_attr "length" "8,4,8,8")
5208    (set_attr "arch" "neon_for_64bits,*,*,avoid_neon_for_64bits")
5209    (set_attr "ce_count" "2")
5210    (set_attr "predicable" "yes")
5211    (set_attr "type" "multiple,mov_reg,multiple,multiple")]
5214 (define_insn "extend<mode>di2"
5215   [(set (match_operand:DI 0 "s_register_operand" "=w,r,?r,?r,w")
5216         (sign_extend:DI (match_operand:QHSI 1 "<qhs_extenddi_op>"
5217                                             "<qhs_extenddi_cstr>")))]
5218   "TARGET_32BIT <qhs_sextenddi_cond>"
5219   "#"
5220   [(set_attr "length" "8,4,8,8,8")
5221    (set_attr "ce_count" "2")
5222    (set_attr "shift" "1")
5223    (set_attr "predicable" "yes")
5224    (set_attr "arch" "neon_for_64bits,*,a,t,avoid_neon_for_64bits")
5225    (set_attr "type" "multiple,mov_reg,multiple,multiple,multiple")]
5228 ;; Splits for all extensions to DImode
5229 (define_split
5230   [(set (match_operand:DI 0 "s_register_operand" "")
5231         (zero_extend:DI (match_operand 1 "nonimmediate_operand" "")))]
5232   "TARGET_32BIT && reload_completed && !IS_VFP_REGNUM (REGNO (operands[0]))"
5233   [(set (match_dup 0) (match_dup 1))]
5235   rtx lo_part = gen_lowpart (SImode, operands[0]);
5236   machine_mode src_mode = GET_MODE (operands[1]);
5238   if (REG_P (operands[0])
5239       && !reg_overlap_mentioned_p (operands[0], operands[1]))
5240     emit_clobber (operands[0]);
5241   if (!REG_P (lo_part) || src_mode != SImode
5242       || !rtx_equal_p (lo_part, operands[1]))
5243     {
5244       if (src_mode == SImode)
5245         emit_move_insn (lo_part, operands[1]);
5246       else
5247         emit_insn (gen_rtx_SET (lo_part,
5248                                 gen_rtx_ZERO_EXTEND (SImode, operands[1])));
5249       operands[1] = lo_part;
5250     }
5251   operands[0] = gen_highpart (SImode, operands[0]);
5252   operands[1] = const0_rtx;
5255 (define_split
5256   [(set (match_operand:DI 0 "s_register_operand" "")
5257         (sign_extend:DI (match_operand 1 "nonimmediate_operand" "")))]
5258   "TARGET_32BIT && reload_completed && !IS_VFP_REGNUM (REGNO (operands[0]))"
5259   [(set (match_dup 0) (ashiftrt:SI (match_dup 1) (const_int 31)))]
5261   rtx lo_part = gen_lowpart (SImode, operands[0]);
5262   machine_mode src_mode = GET_MODE (operands[1]);
5264   if (REG_P (operands[0])
5265       && !reg_overlap_mentioned_p (operands[0], operands[1]))
5266     emit_clobber (operands[0]);
5268   if (!REG_P (lo_part) || src_mode != SImode
5269       || !rtx_equal_p (lo_part, operands[1]))
5270     {
5271       if (src_mode == SImode)
5272         emit_move_insn (lo_part, operands[1]);
5273       else
5274         emit_insn (gen_rtx_SET (lo_part,
5275                                 gen_rtx_SIGN_EXTEND (SImode, operands[1])));
5276       operands[1] = lo_part;
5277     }
5278   operands[0] = gen_highpart (SImode, operands[0]);
5281 (define_expand "zero_extendhisi2"
5282   [(set (match_operand:SI 0 "s_register_operand" "")
5283         (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
5284   "TARGET_EITHER"
5286   if (TARGET_ARM && !arm_arch4 && MEM_P (operands[1]))
5287     {
5288       emit_insn (gen_movhi_bytes (operands[0], operands[1]));
5289       DONE;
5290     }
5291   if (!arm_arch6 && !MEM_P (operands[1]))
5292     {
5293       rtx t = gen_lowpart (SImode, operands[1]);
5294       rtx tmp = gen_reg_rtx (SImode);
5295       emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (16)));
5296       emit_insn (gen_lshrsi3 (operands[0], tmp, GEN_INT (16)));
5297       DONE;
5298     }
5301 (define_split
5302   [(set (match_operand:SI 0 "s_register_operand" "")
5303         (zero_extend:SI (match_operand:HI 1 "s_register_operand" "")))]
5304   "!TARGET_THUMB2 && !arm_arch6"
5305   [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
5306    (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 16)))]
5308   operands[2] = gen_lowpart (SImode, operands[1]);
5311 (define_insn "*arm_zero_extendhisi2"
5312   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5313         (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
5314   "TARGET_ARM && arm_arch4 && !arm_arch6"
5315   "@
5316    #
5317    ldrh%?\\t%0, %1"
5318   [(set_attr "type" "alu_shift_reg,load_byte")
5319    (set_attr "predicable" "yes")]
5322 (define_insn "*arm_zero_extendhisi2_v6"
5323   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5324         (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,Uh")))]
5325   "TARGET_ARM && arm_arch6"
5326   "@
5327    uxth%?\\t%0, %1
5328    ldrh%?\\t%0, %1"
5329   [(set_attr "predicable" "yes")
5330    (set_attr "type" "extend,load_byte")]
5333 (define_insn "*arm_zero_extendhisi2addsi"
5334   [(set (match_operand:SI 0 "s_register_operand" "=r")
5335         (plus:SI (zero_extend:SI (match_operand:HI 1 "s_register_operand" "r"))
5336                  (match_operand:SI 2 "s_register_operand" "r")))]
5337   "TARGET_INT_SIMD"
5338   "uxtah%?\\t%0, %2, %1"
5339   [(set_attr "type" "alu_shift_reg")
5340    (set_attr "predicable" "yes")]
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 "*arm_zero_extendqisi2"
5381   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5382         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
5383   "TARGET_ARM && !arm_arch6"
5384   "@
5385    #
5386    ldrb%?\\t%0, %1\\t%@ zero_extendqisi2"
5387   [(set_attr "length" "8,4")
5388    (set_attr "type" "alu_shift_reg,load_byte")
5389    (set_attr "predicable" "yes")]
5392 (define_insn "*arm_zero_extendqisi2_v6"
5393   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5394         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,Uh")))]
5395   "TARGET_ARM && arm_arch6"
5396   "@
5397    uxtb%?\\t%0, %1
5398    ldrb%?\\t%0, %1\\t%@ zero_extendqisi2"
5399   [(set_attr "type" "extend,load_byte")
5400    (set_attr "predicable" "yes")]
5403 (define_insn "*arm_zero_extendqisi2addsi"
5404   [(set (match_operand:SI 0 "s_register_operand" "=r")
5405         (plus:SI (zero_extend:SI (match_operand:QI 1 "s_register_operand" "r"))
5406                  (match_operand:SI 2 "s_register_operand" "r")))]
5407   "TARGET_INT_SIMD"
5408   "uxtab%?\\t%0, %2, %1"
5409   [(set_attr "predicable" "yes")
5410    (set_attr "type" "alu_shift_reg")]
5413 (define_split
5414   [(set (match_operand:SI 0 "s_register_operand" "")
5415         (zero_extend:SI (subreg:QI (match_operand:SI 1 "" "") 0)))
5416    (clobber (match_operand:SI 2 "s_register_operand" ""))]
5417   "TARGET_32BIT && (!MEM_P (operands[1])) && ! BYTES_BIG_ENDIAN"
5418   [(set (match_dup 2) (match_dup 1))
5419    (set (match_dup 0) (and:SI (match_dup 2) (const_int 255)))]
5420   ""
5423 (define_split
5424   [(set (match_operand:SI 0 "s_register_operand" "")
5425         (zero_extend:SI (subreg:QI (match_operand:SI 1 "" "") 3)))
5426    (clobber (match_operand:SI 2 "s_register_operand" ""))]
5427   "TARGET_32BIT && (!MEM_P (operands[1])) && BYTES_BIG_ENDIAN"
5428   [(set (match_dup 2) (match_dup 1))
5429    (set (match_dup 0) (and:SI (match_dup 2) (const_int 255)))]
5430   ""
5434 (define_split
5435   [(set (match_operand:SI 0 "s_register_operand" "")
5436         (IOR_XOR:SI (and:SI (ashift:SI
5437                              (match_operand:SI 1 "s_register_operand" "")
5438                              (match_operand:SI 2 "const_int_operand" ""))
5439                             (match_operand:SI 3 "const_int_operand" ""))
5440                     (zero_extend:SI
5441                      (match_operator 5 "subreg_lowpart_operator"
5442                       [(match_operand:SI 4 "s_register_operand" "")]))))]
5443   "TARGET_32BIT
5444    && (UINTVAL (operands[3])
5445        == (GET_MODE_MASK (GET_MODE (operands[5]))
5446            & (GET_MODE_MASK (GET_MODE (operands[5]))
5447               << (INTVAL (operands[2])))))"
5448   [(set (match_dup 0) (IOR_XOR:SI (ashift:SI (match_dup 1) (match_dup 2))
5449                                   (match_dup 4)))
5450    (set (match_dup 0) (zero_extend:SI (match_dup 5)))]
5451   "operands[5] = gen_lowpart (GET_MODE (operands[5]), operands[0]);"
5454 (define_insn "*compareqi_eq0"
5455   [(set (reg:CC_Z CC_REGNUM)
5456         (compare:CC_Z (match_operand:QI 0 "s_register_operand" "r")
5457                          (const_int 0)))]
5458   "TARGET_32BIT"
5459   "tst%?\\t%0, #255"
5460   [(set_attr "conds" "set")
5461    (set_attr "predicable" "yes")
5462    (set_attr "type" "logic_imm")]
5465 (define_expand "extendhisi2"
5466   [(set (match_operand:SI 0 "s_register_operand" "")
5467         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
5468   "TARGET_EITHER"
5470   if (TARGET_THUMB1)
5471     {
5472       emit_insn (gen_thumb1_extendhisi2 (operands[0], operands[1]));
5473       DONE;
5474     }
5475   if (MEM_P (operands[1]) && TARGET_ARM && !arm_arch4)
5476     {
5477       emit_insn (gen_extendhisi2_mem (operands[0], operands[1]));
5478       DONE;
5479     }
5481   if (!arm_arch6 && !MEM_P (operands[1]))
5482     {
5483       rtx t = gen_lowpart (SImode, operands[1]);
5484       rtx tmp = gen_reg_rtx (SImode);
5485       emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (16)));
5486       emit_insn (gen_ashrsi3 (operands[0], tmp, GEN_INT (16)));
5487       DONE;
5488     }
5491 (define_split
5492   [(parallel
5493     [(set (match_operand:SI 0 "register_operand" "")
5494           (sign_extend:SI (match_operand:HI 1 "register_operand" "")))
5495      (clobber (match_scratch:SI 2 ""))])]
5496   "!arm_arch6"
5497   [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
5498    (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
5500   operands[2] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
5503 ;; This pattern will only be used when ldsh is not available
5504 (define_expand "extendhisi2_mem"
5505   [(set (match_dup 2) (zero_extend:SI (match_operand:HI 1 "" "")))
5506    (set (match_dup 3)
5507         (zero_extend:SI (match_dup 7)))
5508    (set (match_dup 6) (ashift:SI (match_dup 4) (const_int 24)))
5509    (set (match_operand:SI 0 "" "")
5510         (ior:SI (ashiftrt:SI (match_dup 6) (const_int 16)) (match_dup 5)))]
5511   "TARGET_ARM"
5512   "
5513   {
5514     rtx mem1, mem2;
5515     rtx addr = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
5517     mem1 = change_address (operands[1], QImode, addr);
5518     mem2 = change_address (operands[1], QImode,
5519                            plus_constant (Pmode, addr, 1));
5520     operands[0] = gen_lowpart (SImode, operands[0]);
5521     operands[1] = mem1;
5522     operands[2] = gen_reg_rtx (SImode);
5523     operands[3] = gen_reg_rtx (SImode);
5524     operands[6] = gen_reg_rtx (SImode);
5525     operands[7] = mem2;
5527     if (BYTES_BIG_ENDIAN)
5528       {
5529         operands[4] = operands[2];
5530         operands[5] = operands[3];
5531       }
5532     else
5533       {
5534         operands[4] = operands[3];
5535         operands[5] = operands[2];
5536       }
5537   }"
5540 (define_split
5541   [(set (match_operand:SI 0 "register_operand" "")
5542         (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
5543   "!arm_arch6"
5544   [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
5545    (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
5547   operands[2] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
5550 (define_insn "*arm_extendhisi2"
5551   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5552         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,Uh")))]
5553   "TARGET_ARM && arm_arch4 && !arm_arch6"
5554   "@
5555    #
5556    ldrsh%?\\t%0, %1"
5557   [(set_attr "length" "8,4")
5558    (set_attr "type" "alu_shift_reg,load_byte")
5559    (set_attr "predicable" "yes")]
5562 ;; ??? Check Thumb-2 pool range
5563 (define_insn "*arm_extendhisi2_v6"
5564   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5565         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,Uh")))]
5566   "TARGET_32BIT && arm_arch6"
5567   "@
5568    sxth%?\\t%0, %1
5569    ldrsh%?\\t%0, %1"
5570   [(set_attr "type" "extend,load_byte")
5571    (set_attr "predicable" "yes")]
5574 (define_insn "*arm_extendhisi2addsi"
5575   [(set (match_operand:SI 0 "s_register_operand" "=r")
5576         (plus:SI (sign_extend:SI (match_operand:HI 1 "s_register_operand" "r"))
5577                  (match_operand:SI 2 "s_register_operand" "r")))]
5578   "TARGET_INT_SIMD"
5579   "sxtah%?\\t%0, %2, %1"
5580   [(set_attr "type" "alu_shift_reg")]
5583 (define_expand "extendqihi2"
5584   [(set (match_dup 2)
5585         (ashift:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "")
5586                    (const_int 24)))
5587    (set (match_operand:HI 0 "s_register_operand" "")
5588         (ashiftrt:SI (match_dup 2)
5589                      (const_int 24)))]
5590   "TARGET_ARM"
5591   "
5592   {
5593     if (arm_arch4 && MEM_P (operands[1]))
5594       {
5595         emit_insn (gen_rtx_SET (operands[0],
5596                                 gen_rtx_SIGN_EXTEND (HImode, operands[1])));
5597         DONE;
5598       }
5599     if (!s_register_operand (operands[1], QImode))
5600       operands[1] = copy_to_mode_reg (QImode, operands[1]);
5601     operands[0] = gen_lowpart (SImode, operands[0]);
5602     operands[1] = gen_lowpart (SImode, operands[1]);
5603     operands[2] = gen_reg_rtx (SImode);
5604   }"
5607 (define_insn "*arm_extendqihi_insn"
5608   [(set (match_operand:HI 0 "s_register_operand" "=r")
5609         (sign_extend:HI (match_operand:QI 1 "arm_extendqisi_mem_op" "Uq")))]
5610   "TARGET_ARM && arm_arch4"
5611   "ldrsb%?\\t%0, %1"
5612   [(set_attr "type" "load_byte")
5613    (set_attr "predicable" "yes")]
5616 (define_expand "extendqisi2"
5617   [(set (match_operand:SI 0 "s_register_operand" "")
5618         (sign_extend:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "")))]
5619   "TARGET_EITHER"
5621   if (!arm_arch4 && MEM_P (operands[1]))
5622     operands[1] = copy_to_mode_reg (QImode, operands[1]);
5624   if (!arm_arch6 && !MEM_P (operands[1]))
5625     {
5626       rtx t = gen_lowpart (SImode, operands[1]);
5627       rtx tmp = gen_reg_rtx (SImode);
5628       emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (24)));
5629       emit_insn (gen_ashrsi3 (operands[0], tmp, GEN_INT (24)));
5630       DONE;
5631     }
5634 (define_split
5635   [(set (match_operand:SI 0 "register_operand" "")
5636         (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
5637   "!arm_arch6"
5638   [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 24)))
5639    (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 24)))]
5641   operands[2] = simplify_gen_subreg (SImode, operands[1], QImode, 0);
5644 (define_insn "*arm_extendqisi"
5645   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5646         (sign_extend:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "r,Uq")))]
5647   "TARGET_ARM && arm_arch4 && !arm_arch6"
5648   "@
5649    #
5650    ldrsb%?\\t%0, %1"
5651   [(set_attr "length" "8,4")
5652    (set_attr "type" "alu_shift_reg,load_byte")
5653    (set_attr "predicable" "yes")]
5656 (define_insn "*arm_extendqisi_v6"
5657   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5658         (sign_extend:SI
5659          (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "r,Uq")))]
5660   "TARGET_ARM && arm_arch6"
5661   "@
5662    sxtb%?\\t%0, %1
5663    ldrsb%?\\t%0, %1"
5664   [(set_attr "type" "extend,load_byte")
5665    (set_attr "predicable" "yes")]
5668 (define_insn "*arm_extendqisi2addsi"
5669   [(set (match_operand:SI 0 "s_register_operand" "=r")
5670         (plus:SI (sign_extend:SI (match_operand:QI 1 "s_register_operand" "r"))
5671                  (match_operand:SI 2 "s_register_operand" "r")))]
5672   "TARGET_INT_SIMD"
5673   "sxtab%?\\t%0, %2, %1"
5674   [(set_attr "type" "alu_shift_reg")
5675    (set_attr "predicable" "yes")]
5678 (define_expand "extendsfdf2"
5679   [(set (match_operand:DF                  0 "s_register_operand" "")
5680         (float_extend:DF (match_operand:SF 1 "s_register_operand"  "")))]
5681   "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
5682   ""
5685 ;; HFmode -> DFmode conversions where we don't have an instruction for it
5686 ;; must go through SFmode.
5688 ;; This is always safe for an extend.
5690 (define_expand "extendhfdf2"
5691   [(set (match_operand:DF                  0 "s_register_operand" "")
5692         (float_extend:DF (match_operand:HF 1 "s_register_operand" "")))]
5693   "TARGET_EITHER"
5695   /* We don't have a direct instruction for this, so go via SFmode.  */
5696   if (!(TARGET_32BIT && TARGET_FP16_TO_DOUBLE))
5697     {
5698       rtx op1;
5699       op1 = convert_to_mode (SFmode, operands[1], 0);
5700       op1 = convert_to_mode (DFmode, op1, 0);
5701       emit_insn (gen_movdf (operands[0], op1));
5702       DONE;
5703     }
5704   /* Otherwise, we're done producing RTL and will pick up the correct
5705      pattern to do this with one rounding-step in a single instruction.  */
5709 ;; Move insns (including loads and stores)
5711 ;; XXX Just some ideas about movti.
5712 ;; I don't think these are a good idea on the arm, there just aren't enough
5713 ;; registers
5714 ;;(define_expand "loadti"
5715 ;;  [(set (match_operand:TI 0 "s_register_operand" "")
5716 ;;      (mem:TI (match_operand:SI 1 "address_operand" "")))]
5717 ;;  "" "")
5719 ;;(define_expand "storeti"
5720 ;;  [(set (mem:TI (match_operand:TI 0 "address_operand" ""))
5721 ;;      (match_operand:TI 1 "s_register_operand" ""))]
5722 ;;  "" "")
5724 ;;(define_expand "movti"
5725 ;;  [(set (match_operand:TI 0 "general_operand" "")
5726 ;;      (match_operand:TI 1 "general_operand" ""))]
5727 ;;  ""
5728 ;;  "
5730 ;;  rtx insn;
5732 ;;  if (MEM_P (operands[0]) && MEM_P (operands[1]))
5733 ;;    operands[1] = copy_to_reg (operands[1]);
5734 ;;  if (MEM_P (operands[0]))
5735 ;;    insn = gen_storeti (XEXP (operands[0], 0), operands[1]);
5736 ;;  else if (MEM_P (operands[1]))
5737 ;;    insn = gen_loadti (operands[0], XEXP (operands[1], 0));
5738 ;;  else
5739 ;;    FAIL;
5741 ;;  emit_insn (insn);
5742 ;;  DONE;
5743 ;;}")
5745 ;; Recognize garbage generated above.
5747 ;;(define_insn ""
5748 ;;  [(set (match_operand:TI 0 "general_operand" "=r,r,r,<,>,m")
5749 ;;      (match_operand:TI 1 "general_operand" "<,>,m,r,r,r"))]
5750 ;;  ""
5751 ;;  "*
5752 ;;  {
5753 ;;    register mem = (which_alternative < 3);
5754 ;;    register const char *template;
5756 ;;    operands[mem] = XEXP (operands[mem], 0);
5757 ;;    switch (which_alternative)
5758 ;;      {
5759 ;;      case 0: template = \"ldmdb\\t%1!, %M0\"; break;
5760 ;;      case 1: template = \"ldmia\\t%1!, %M0\"; break;
5761 ;;      case 2: template = \"ldmia\\t%1, %M0\"; break;
5762 ;;      case 3: template = \"stmdb\\t%0!, %M1\"; break;
5763 ;;      case 4: template = \"stmia\\t%0!, %M1\"; break;
5764 ;;      case 5: template = \"stmia\\t%0, %M1\"; break;
5765 ;;      }
5766 ;;    output_asm_insn (template, operands);
5767 ;;    return \"\";
5768 ;;  }")
5770 (define_expand "movdi"
5771   [(set (match_operand:DI 0 "general_operand" "")
5772         (match_operand:DI 1 "general_operand" ""))]
5773   "TARGET_EITHER"
5774   "
5775   if (can_create_pseudo_p ())
5776     {
5777       if (!REG_P (operands[0]))
5778         operands[1] = force_reg (DImode, operands[1]);
5779     }
5780   if (REG_P (operands[0]) && REGNO (operands[0]) <= LAST_ARM_REGNUM
5781       && !targetm.hard_regno_mode_ok (REGNO (operands[0]), DImode))
5782     {
5783       /* Avoid LDRD's into an odd-numbered register pair in ARM state
5784          when expanding function calls.  */
5785       gcc_assert (can_create_pseudo_p ());
5786       if (MEM_P (operands[1]) && MEM_VOLATILE_P (operands[1]))
5787         {
5788           /* Perform load into legal reg pair first, then move.  */
5789           rtx reg = gen_reg_rtx (DImode);
5790           emit_insn (gen_movdi (reg, operands[1]));
5791           operands[1] = reg;
5792         }
5793       emit_move_insn (gen_lowpart (SImode, operands[0]),
5794                       gen_lowpart (SImode, operands[1]));
5795       emit_move_insn (gen_highpart (SImode, operands[0]),
5796                       gen_highpart (SImode, operands[1]));
5797       DONE;
5798     }
5799   else if (REG_P (operands[1]) && REGNO (operands[1]) <= LAST_ARM_REGNUM
5800            && !targetm.hard_regno_mode_ok (REGNO (operands[1]), DImode))
5801     {
5802       /* Avoid STRD's from an odd-numbered register pair in ARM state
5803          when expanding function prologue.  */
5804       gcc_assert (can_create_pseudo_p ());
5805       rtx split_dest = (MEM_P (operands[0]) && MEM_VOLATILE_P (operands[0]))
5806                        ? gen_reg_rtx (DImode)
5807                        : operands[0];
5808       emit_move_insn (gen_lowpart (SImode, split_dest),
5809                       gen_lowpart (SImode, operands[1]));
5810       emit_move_insn (gen_highpart (SImode, split_dest),
5811                       gen_highpart (SImode, operands[1]));
5812       if (split_dest != operands[0])
5813         emit_insn (gen_movdi (operands[0], split_dest));
5814       DONE;
5815     }
5816   "
5819 (define_insn "*arm_movdi"
5820   [(set (match_operand:DI 0 "nonimmediate_di_operand" "=r, r, r, q, m")
5821         (match_operand:DI 1 "di_operand"              "rDa,Db,Dc,mi,q"))]
5822   "TARGET_32BIT
5823    && !(TARGET_HARD_FLOAT)
5824    && !TARGET_IWMMXT
5825    && (   register_operand (operands[0], DImode)
5826        || register_operand (operands[1], DImode))"
5827   "*
5828   switch (which_alternative)
5829     {
5830     case 0:
5831     case 1:
5832     case 2:
5833       return \"#\";
5834     default:
5835       return output_move_double (operands, true, NULL);
5836     }
5837   "
5838   [(set_attr "length" "8,12,16,8,8")
5839    (set_attr "type" "multiple,multiple,multiple,load_8,store_8")
5840    (set_attr "arm_pool_range" "*,*,*,1020,*")
5841    (set_attr "arm_neg_pool_range" "*,*,*,1004,*")
5842    (set_attr "thumb2_pool_range" "*,*,*,4094,*")
5843    (set_attr "thumb2_neg_pool_range" "*,*,*,0,*")]
5846 (define_split
5847   [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
5848         (match_operand:ANY64 1 "immediate_operand" ""))]
5849   "TARGET_32BIT
5850    && reload_completed
5851    && (arm_disable_literal_pool
5852        || (arm_const_double_inline_cost (operands[1])
5853            <= arm_max_const_double_inline_cost ()))"
5854   [(const_int 0)]
5855   "
5856   arm_split_constant (SET, SImode, curr_insn,
5857                       INTVAL (gen_lowpart (SImode, operands[1])),
5858                       gen_lowpart (SImode, operands[0]), NULL_RTX, 0);
5859   arm_split_constant (SET, SImode, curr_insn,
5860                       INTVAL (gen_highpart_mode (SImode,
5861                                                  GET_MODE (operands[0]),
5862                                                  operands[1])),
5863                       gen_highpart (SImode, operands[0]), NULL_RTX, 0);
5864   DONE;
5865   "
5868 ; If optimizing for size, or if we have load delay slots, then 
5869 ; we want to split the constant into two separate operations. 
5870 ; In both cases this may split a trivial part into a single data op
5871 ; leaving a single complex constant to load.  We can also get longer
5872 ; offsets in a LDR which means we get better chances of sharing the pool
5873 ; entries.  Finally, we can normally do a better job of scheduling
5874 ; LDR instructions than we can with LDM.
5875 ; This pattern will only match if the one above did not.
5876 (define_split
5877   [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
5878         (match_operand:ANY64 1 "const_double_operand" ""))]
5879   "TARGET_ARM && reload_completed
5880    && arm_const_double_by_parts (operands[1])"
5881   [(set (match_dup 0) (match_dup 1))
5882    (set (match_dup 2) (match_dup 3))]
5883   "
5884   operands[2] = gen_highpart (SImode, operands[0]);
5885   operands[3] = gen_highpart_mode (SImode, GET_MODE (operands[0]),
5886                                    operands[1]);
5887   operands[0] = gen_lowpart (SImode, operands[0]);
5888   operands[1] = gen_lowpart (SImode, operands[1]);
5889   "
5892 (define_split
5893   [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
5894         (match_operand:ANY64 1 "arm_general_register_operand" ""))]
5895   "TARGET_EITHER && reload_completed"
5896   [(set (match_dup 0) (match_dup 1))
5897    (set (match_dup 2) (match_dup 3))]
5898   "
5899   operands[2] = gen_highpart (SImode, operands[0]);
5900   operands[3] = gen_highpart (SImode, operands[1]);
5901   operands[0] = gen_lowpart (SImode, operands[0]);
5902   operands[1] = gen_lowpart (SImode, operands[1]);
5904   /* Handle a partial overlap.  */
5905   if (rtx_equal_p (operands[0], operands[3]))
5906     {
5907       rtx tmp0 = operands[0];
5908       rtx tmp1 = operands[1];
5910       operands[0] = operands[2];
5911       operands[1] = operands[3];
5912       operands[2] = tmp0;
5913       operands[3] = tmp1;
5914     }
5915   "
5918 ;; We can't actually do base+index doubleword loads if the index and
5919 ;; destination overlap.  Split here so that we at least have chance to
5920 ;; schedule.
5921 (define_split
5922   [(set (match_operand:DI 0 "s_register_operand" "")
5923         (mem:DI (plus:SI (match_operand:SI 1 "s_register_operand" "")
5924                          (match_operand:SI 2 "s_register_operand" ""))))]
5925   "TARGET_LDRD
5926   && reg_overlap_mentioned_p (operands[0], operands[1])
5927   && reg_overlap_mentioned_p (operands[0], operands[2])"
5928   [(set (match_dup 4)
5929         (plus:SI (match_dup 1)
5930                  (match_dup 2)))
5931    (set (match_dup 0)
5932         (mem:DI (match_dup 4)))]
5933   "
5934   operands[4] = gen_rtx_REG (SImode, REGNO(operands[0]));
5935   "
5938 (define_expand "movsi"
5939   [(set (match_operand:SI 0 "general_operand" "")
5940         (match_operand:SI 1 "general_operand" ""))]
5941   "TARGET_EITHER"
5942   "
5943   {
5944   rtx base, offset, tmp;
5946   if (TARGET_32BIT || TARGET_HAVE_MOVT)
5947     {
5948       /* Everything except mem = const or mem = mem can be done easily.  */
5949       if (MEM_P (operands[0]))
5950         operands[1] = force_reg (SImode, operands[1]);
5951       if (arm_general_register_operand (operands[0], SImode)
5952           && CONST_INT_P (operands[1])
5953           && !(const_ok_for_arm (INTVAL (operands[1]))
5954                || const_ok_for_arm (~INTVAL (operands[1]))))
5955         {
5956            if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[1]), SET))
5957              {
5958                 emit_insn (gen_rtx_SET (operands[0], operands[1]));
5959                 DONE;
5960              }
5961           else
5962              {
5963                 arm_split_constant (SET, SImode, NULL_RTX,
5964                                     INTVAL (operands[1]), operands[0], NULL_RTX,
5965                                     optimize && can_create_pseudo_p ());
5966                 DONE;
5967              }
5968         }
5969     }
5970   else /* Target doesn't have MOVT...  */
5971     {
5972       if (can_create_pseudo_p ())
5973         {
5974           if (!REG_P (operands[0]))
5975             operands[1] = force_reg (SImode, operands[1]);
5976         }
5977     }
5979   if (ARM_OFFSETS_MUST_BE_WITHIN_SECTIONS_P)
5980     {
5981       split_const (operands[1], &base, &offset);
5982       if (GET_CODE (base) == SYMBOL_REF
5983           && !offset_within_block_p (base, INTVAL (offset)))
5984         {
5985           tmp = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];
5986           emit_move_insn (tmp, base);
5987           emit_insn (gen_addsi3 (operands[0], tmp, offset));
5988           DONE;
5989         }
5990     }
5992   /* Recognize the case where operand[1] is a reference to thread-local
5993      data and load its address to a register.  */
5994   if (arm_tls_referenced_p (operands[1]))
5995     {
5996       rtx tmp = operands[1];
5997       rtx addend = NULL;
5999       if (GET_CODE (tmp) == CONST && GET_CODE (XEXP (tmp, 0)) == PLUS)
6000         {
6001           addend = XEXP (XEXP (tmp, 0), 1);
6002           tmp = XEXP (XEXP (tmp, 0), 0);
6003         }
6005       gcc_assert (GET_CODE (tmp) == SYMBOL_REF);
6006       gcc_assert (SYMBOL_REF_TLS_MODEL (tmp) != 0);
6008       tmp = legitimize_tls_address (tmp,
6009                                     !can_create_pseudo_p () ? operands[0] : 0);
6010       if (addend)
6011         {
6012           tmp = gen_rtx_PLUS (SImode, tmp, addend);
6013           tmp = force_operand (tmp, operands[0]);
6014         }
6015       operands[1] = tmp;
6016     }
6017   else if (flag_pic
6018            && (CONSTANT_P (operands[1])
6019                || symbol_mentioned_p (operands[1])
6020                || label_mentioned_p (operands[1])))
6021       operands[1] = legitimize_pic_address (operands[1], SImode,
6022                                             (!can_create_pseudo_p ()
6023                                              ? operands[0]
6024                                              : 0));
6025   }
6026   "
6029 ;; The ARM LO_SUM and HIGH are backwards - HIGH sets the low bits, and
6030 ;; LO_SUM adds in the high bits.  Fortunately these are opaque operations
6031 ;; so this does not matter.
6032 (define_insn "*arm_movt"
6033   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r")
6034         (lo_sum:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6035                    (match_operand:SI 2 "general_operand"      "i,i")))]
6036   "TARGET_HAVE_MOVT && arm_valid_symbolic_address_p (operands[2])"
6037   "@
6038    movt%?\t%0, #:upper16:%c2
6039    movt\t%0, #:upper16:%c2"
6040   [(set_attr "arch"  "32,v8mb")
6041    (set_attr "predicable" "yes")
6042    (set_attr "length" "4")
6043    (set_attr "type" "alu_sreg")]
6046 (define_insn "*arm_movsi_insn"
6047   [(set (match_operand:SI 0 "nonimmediate_operand" "=rk,r,r,r,rk,m")
6048         (match_operand:SI 1 "general_operand"      "rk, I,K,j,mi,rk"))]
6049   "TARGET_ARM && !TARGET_IWMMXT && !TARGET_HARD_FLOAT
6050    && (   register_operand (operands[0], SImode)
6051        || register_operand (operands[1], SImode))"
6052   "@
6053    mov%?\\t%0, %1
6054    mov%?\\t%0, %1
6055    mvn%?\\t%0, #%B1
6056    movw%?\\t%0, %1
6057    ldr%?\\t%0, %1
6058    str%?\\t%1, %0"
6059   [(set_attr "type" "mov_reg,mov_imm,mvn_imm,mov_imm,load_4,store_4")
6060    (set_attr "predicable" "yes")
6061    (set_attr "arch" "*,*,*,v6t2,*,*")
6062    (set_attr "pool_range" "*,*,*,*,4096,*")
6063    (set_attr "neg_pool_range" "*,*,*,*,4084,*")]
6066 (define_split
6067   [(set (match_operand:SI 0 "arm_general_register_operand" "")
6068         (match_operand:SI 1 "const_int_operand" ""))]
6069   "(TARGET_32BIT || TARGET_HAVE_MOVT)
6070   && (!(const_ok_for_arm (INTVAL (operands[1]))
6071         || const_ok_for_arm (~INTVAL (operands[1]))))"
6072   [(clobber (const_int 0))]
6073   "
6074   arm_split_constant (SET, SImode, NULL_RTX, 
6075                       INTVAL (operands[1]), operands[0], NULL_RTX, 0);
6076   DONE;
6077   "
6080 ;; A normal way to do (symbol + offset) requires three instructions at least
6081 ;; (depends on how big the offset is) as below:
6082 ;; movw r0, #:lower16:g
6083 ;; movw r0, #:upper16:g
6084 ;; adds r0, #4
6086 ;; A better way would be:
6087 ;; movw r0, #:lower16:g+4
6088 ;; movw r0, #:upper16:g+4
6090 ;; The limitation of this way is that the length of offset should be a 16-bit
6091 ;; signed value, because current assembler only supports REL type relocation for
6092 ;; such case.  If the more powerful RELA type is supported in future, we should
6093 ;; update this pattern to go with better way.
6094 (define_split
6095   [(set (match_operand:SI 0 "arm_general_register_operand" "")
6096         (const:SI (plus:SI (match_operand:SI 1 "general_operand" "")
6097                            (match_operand:SI 2 "const_int_operand" ""))))]
6098   "TARGET_THUMB
6099    && TARGET_HAVE_MOVT
6100    && arm_disable_literal_pool
6101    && reload_completed
6102    && GET_CODE (operands[1]) == SYMBOL_REF"
6103   [(clobber (const_int 0))]
6104   "
6105     int offset = INTVAL (operands[2]);
6107     if (offset < -0x8000 || offset > 0x7fff)
6108       {
6109         arm_emit_movpair (operands[0], operands[1]);
6110         emit_insn (gen_rtx_SET (operands[0],
6111                                 gen_rtx_PLUS (SImode, operands[0], operands[2])));
6112       }
6113     else
6114       {
6115         rtx op = gen_rtx_CONST (SImode,
6116                                 gen_rtx_PLUS (SImode, operands[1], operands[2]));
6117         arm_emit_movpair (operands[0], op);
6118       }
6119   "
6122 ;; Split symbol_refs at the later stage (after cprop), instead of generating
6123 ;; movt/movw pair directly at expand.  Otherwise corresponding high_sum
6124 ;; and lo_sum would be merged back into memory load at cprop.  However,
6125 ;; if the default is to prefer movt/movw rather than a load from the constant
6126 ;; pool, the performance is better.
6127 (define_split
6128   [(set (match_operand:SI 0 "arm_general_register_operand" "")
6129        (match_operand:SI 1 "general_operand" ""))]
6130   "TARGET_USE_MOVT && GET_CODE (operands[1]) == SYMBOL_REF
6131    && !flag_pic && !target_word_relocations
6132    && !arm_tls_referenced_p (operands[1])"
6133   [(clobber (const_int 0))]
6135   arm_emit_movpair (operands[0], operands[1]);
6136   DONE;
6139 ;; When generating pic, we need to load the symbol offset into a register.
6140 ;; So that the optimizer does not confuse this with a normal symbol load
6141 ;; we use an unspec.  The offset will be loaded from a constant pool entry,
6142 ;; since that is the only type of relocation we can use.
6144 ;; Wrap calculation of the whole PIC address in a single pattern for the
6145 ;; benefit of optimizers, particularly, PRE and HOIST.  Calculation of
6146 ;; a PIC address involves two loads from memory, so we want to CSE it
6147 ;; as often as possible.
6148 ;; This pattern will be split into one of the pic_load_addr_* patterns
6149 ;; and a move after GCSE optimizations.
6151 ;; Note: Update arm.c: legitimize_pic_address() when changing this pattern.
6152 (define_expand "calculate_pic_address"
6153   [(set (match_operand:SI 0 "register_operand" "")
6154         (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "")
6155                          (unspec:SI [(match_operand:SI 2 "" "")]
6156                                     UNSPEC_PIC_SYM))))]
6157   "flag_pic"
6160 ;; Split calculate_pic_address into pic_load_addr_* and a move.
6161 (define_split
6162   [(set (match_operand:SI 0 "register_operand" "")
6163         (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "")
6164                          (unspec:SI [(match_operand:SI 2 "" "")]
6165                                     UNSPEC_PIC_SYM))))]
6166   "flag_pic"
6167   [(set (match_dup 3) (unspec:SI [(match_dup 2)] UNSPEC_PIC_SYM))
6168    (set (match_dup 0) (mem:SI (plus:SI (match_dup 1) (match_dup 3))))]
6169   "operands[3] = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];"
6172 ;; operand1 is the memory address to go into 
6173 ;; pic_load_addr_32bit.
6174 ;; operand2 is the PIC label to be emitted 
6175 ;; from pic_add_dot_plus_eight.
6176 ;; We do this to allow hoisting of the entire insn.
6177 (define_insn_and_split "pic_load_addr_unified"
6178   [(set (match_operand:SI 0 "s_register_operand" "=r,r,l")
6179         (unspec:SI [(match_operand:SI 1 "" "mX,mX,mX") 
6180                     (match_operand:SI 2 "" "")] 
6181                     UNSPEC_PIC_UNIFIED))]
6182  "flag_pic"
6183  "#"
6184  "&& reload_completed"
6185  [(set (match_dup 0) (unspec:SI [(match_dup 1)] UNSPEC_PIC_SYM))
6186   (set (match_dup 0) (unspec:SI [(match_dup 0) (match_dup 3)
6187                                  (match_dup 2)] UNSPEC_PIC_BASE))]
6188  "operands[3] = TARGET_THUMB ? GEN_INT (4) : GEN_INT (8);"
6189  [(set_attr "type" "load_4,load_4,load_4")
6190   (set_attr "pool_range" "4096,4094,1022")
6191   (set_attr "neg_pool_range" "4084,0,0")
6192   (set_attr "arch"  "a,t2,t1")    
6193   (set_attr "length" "8,6,4")]
6196 ;; The rather odd constraints on the following are to force reload to leave
6197 ;; the insn alone, and to force the minipool generation pass to then move
6198 ;; the GOT symbol to memory.
6200 (define_insn "pic_load_addr_32bit"
6201   [(set (match_operand:SI 0 "s_register_operand" "=r")
6202         (unspec:SI [(match_operand:SI 1 "" "mX")] UNSPEC_PIC_SYM))]
6203   "TARGET_32BIT && flag_pic"
6204   "ldr%?\\t%0, %1"
6205   [(set_attr "type" "load_4")
6206    (set (attr "pool_range")
6207         (if_then_else (eq_attr "is_thumb" "no")
6208                       (const_int 4096)
6209                       (const_int 4094)))
6210    (set (attr "neg_pool_range")
6211         (if_then_else (eq_attr "is_thumb" "no")
6212                       (const_int 4084)
6213                       (const_int 0)))]
6216 (define_insn "pic_load_addr_thumb1"
6217   [(set (match_operand:SI 0 "s_register_operand" "=l")
6218         (unspec:SI [(match_operand:SI 1 "" "mX")] UNSPEC_PIC_SYM))]
6219   "TARGET_THUMB1 && flag_pic"
6220   "ldr\\t%0, %1"
6221   [(set_attr "type" "load_4")
6222    (set (attr "pool_range") (const_int 1018))]
6225 (define_insn "pic_add_dot_plus_four"
6226   [(set (match_operand:SI 0 "register_operand" "=r")
6227         (unspec:SI [(match_operand:SI 1 "register_operand" "0")
6228                     (const_int 4)
6229                     (match_operand 2 "" "")]
6230                    UNSPEC_PIC_BASE))]
6231   "TARGET_THUMB"
6232   "*
6233   (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
6234                                      INTVAL (operands[2]));
6235   return \"add\\t%0, %|pc\";
6236   "
6237   [(set_attr "length" "2")
6238    (set_attr "type" "alu_sreg")]
6241 (define_insn "pic_add_dot_plus_eight"
6242   [(set (match_operand:SI 0 "register_operand" "=r")
6243         (unspec:SI [(match_operand:SI 1 "register_operand" "r")
6244                     (const_int 8)
6245                     (match_operand 2 "" "")]
6246                    UNSPEC_PIC_BASE))]
6247   "TARGET_ARM"
6248   "*
6249     (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
6250                                        INTVAL (operands[2]));
6251     return \"add%?\\t%0, %|pc, %1\";
6252   "
6253   [(set_attr "predicable" "yes")
6254    (set_attr "type" "alu_sreg")]
6257 (define_insn "tls_load_dot_plus_eight"
6258   [(set (match_operand:SI 0 "register_operand" "=r")
6259         (mem:SI (unspec:SI [(match_operand:SI 1 "register_operand" "r")
6260                             (const_int 8)
6261                             (match_operand 2 "" "")]
6262                            UNSPEC_PIC_BASE)))]
6263   "TARGET_ARM"
6264   "*
6265     (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
6266                                        INTVAL (operands[2]));
6267     return \"ldr%?\\t%0, [%|pc, %1]\t\t@ tls_load_dot_plus_eight\";
6268   "
6269   [(set_attr "predicable" "yes")
6270    (set_attr "type" "load_4")]
6273 ;; PIC references to local variables can generate pic_add_dot_plus_eight
6274 ;; followed by a load.  These sequences can be crunched down to
6275 ;; tls_load_dot_plus_eight by a peephole.
6277 (define_peephole2
6278   [(set (match_operand:SI 0 "register_operand" "")
6279         (unspec:SI [(match_operand:SI 3 "register_operand" "")
6280                     (const_int 8)
6281                     (match_operand 1 "" "")]
6282                    UNSPEC_PIC_BASE))
6283    (set (match_operand:SI 2 "arm_general_register_operand" "")
6284         (mem:SI (match_dup 0)))]
6285   "TARGET_ARM && peep2_reg_dead_p (2, operands[0])"
6286   [(set (match_dup 2)
6287         (mem:SI (unspec:SI [(match_dup 3)
6288                             (const_int 8)
6289                             (match_dup 1)]
6290                            UNSPEC_PIC_BASE)))]
6291   ""
6294 (define_insn "pic_offset_arm"
6295   [(set (match_operand:SI 0 "register_operand" "=r")
6296         (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
6297                          (unspec:SI [(match_operand:SI 2 "" "X")]
6298                                     UNSPEC_PIC_OFFSET))))]
6299   "TARGET_VXWORKS_RTP && TARGET_ARM && flag_pic"
6300   "ldr%?\\t%0, [%1,%2]"
6301   [(set_attr "type" "load_4")]
6304 (define_expand "builtin_setjmp_receiver"
6305   [(label_ref (match_operand 0 "" ""))]
6306   "flag_pic"
6307   "
6309   /* r3 is clobbered by set/longjmp, so we can use it as a scratch
6310      register.  */
6311   if (arm_pic_register != INVALID_REGNUM)
6312     arm_load_pic_register (1UL << 3);
6313   DONE;
6316 ;; If copying one reg to another we can set the condition codes according to
6317 ;; its value.  Such a move is common after a return from subroutine and the
6318 ;; result is being tested against zero.
6320 (define_insn "*movsi_compare0"
6321   [(set (reg:CC CC_REGNUM)
6322         (compare:CC (match_operand:SI 1 "s_register_operand" "0,r")
6323                     (const_int 0)))
6324    (set (match_operand:SI 0 "s_register_operand" "=r,r")
6325         (match_dup 1))]
6326   "TARGET_32BIT"
6327   "@
6328    cmp%?\\t%0, #0
6329    subs%?\\t%0, %1, #0"
6330   [(set_attr "conds" "set")
6331    (set_attr "type" "alus_imm,alus_imm")]
6334 ;; Subroutine to store a half word from a register into memory.
6335 ;; Operand 0 is the source register (HImode)
6336 ;; Operand 1 is the destination address in a register (SImode)
6338 ;; In both this routine and the next, we must be careful not to spill
6339 ;; a memory address of reg+large_const into a separate PLUS insn, since this
6340 ;; can generate unrecognizable rtl.
6342 (define_expand "storehi"
6343   [;; store the low byte
6344    (set (match_operand 1 "" "") (match_dup 3))
6345    ;; extract the high byte
6346    (set (match_dup 2)
6347         (ashiftrt:SI (match_operand 0 "" "") (const_int 8)))
6348    ;; store the high byte
6349    (set (match_dup 4) (match_dup 5))]
6350   "TARGET_ARM"
6351   "
6352   {
6353     rtx op1 = operands[1];
6354     rtx addr = XEXP (op1, 0);
6355     enum rtx_code code = GET_CODE (addr);
6357     if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1)))
6358         || code == MINUS)
6359       op1 = replace_equiv_address (operands[1], force_reg (SImode, addr));
6361     operands[4] = adjust_address (op1, QImode, 1);
6362     operands[1] = adjust_address (operands[1], QImode, 0);
6363     operands[3] = gen_lowpart (QImode, operands[0]);
6364     operands[0] = gen_lowpart (SImode, operands[0]);
6365     operands[2] = gen_reg_rtx (SImode);
6366     operands[5] = gen_lowpart (QImode, operands[2]);
6367   }"
6370 (define_expand "storehi_bigend"
6371   [(set (match_dup 4) (match_dup 3))
6372    (set (match_dup 2)
6373         (ashiftrt:SI (match_operand 0 "" "") (const_int 8)))
6374    (set (match_operand 1 "" "") (match_dup 5))]
6375   "TARGET_ARM"
6376   "
6377   {
6378     rtx op1 = operands[1];
6379     rtx addr = XEXP (op1, 0);
6380     enum rtx_code code = GET_CODE (addr);
6382     if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1)))
6383         || code == MINUS)
6384       op1 = replace_equiv_address (op1, force_reg (SImode, addr));
6386     operands[4] = adjust_address (op1, QImode, 1);
6387     operands[1] = adjust_address (operands[1], QImode, 0);
6388     operands[3] = gen_lowpart (QImode, operands[0]);
6389     operands[0] = gen_lowpart (SImode, operands[0]);
6390     operands[2] = gen_reg_rtx (SImode);
6391     operands[5] = gen_lowpart (QImode, operands[2]);
6392   }"
6395 ;; Subroutine to store a half word integer constant into memory.
6396 (define_expand "storeinthi"
6397   [(set (match_operand 0 "" "")
6398         (match_operand 1 "" ""))
6399    (set (match_dup 3) (match_dup 2))]
6400   "TARGET_ARM"
6401   "
6402   {
6403     HOST_WIDE_INT value = INTVAL (operands[1]);
6404     rtx addr = XEXP (operands[0], 0);
6405     rtx op0 = operands[0];
6406     enum rtx_code code = GET_CODE (addr);
6408     if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1)))
6409         || code == MINUS)
6410       op0 = replace_equiv_address (op0, force_reg (SImode, addr));
6412     operands[1] = gen_reg_rtx (SImode);
6413     if (BYTES_BIG_ENDIAN)
6414       {
6415         emit_insn (gen_movsi (operands[1], GEN_INT ((value >> 8) & 255)));
6416         if ((value & 255) == ((value >> 8) & 255))
6417           operands[2] = operands[1];
6418         else
6419           {
6420             operands[2] = gen_reg_rtx (SImode);
6421             emit_insn (gen_movsi (operands[2], GEN_INT (value & 255)));
6422           }
6423       }
6424     else
6425       {
6426         emit_insn (gen_movsi (operands[1], GEN_INT (value & 255)));
6427         if ((value & 255) == ((value >> 8) & 255))
6428           operands[2] = operands[1];
6429         else
6430           {
6431             operands[2] = gen_reg_rtx (SImode);
6432             emit_insn (gen_movsi (operands[2], GEN_INT ((value >> 8) & 255)));
6433           }
6434       }
6436     operands[3] = adjust_address (op0, QImode, 1);
6437     operands[0] = adjust_address (operands[0], QImode, 0);
6438     operands[2] = gen_lowpart (QImode, operands[2]);
6439     operands[1] = gen_lowpart (QImode, operands[1]);
6440   }"
6443 (define_expand "storehi_single_op"
6444   [(set (match_operand:HI 0 "memory_operand" "")
6445         (match_operand:HI 1 "general_operand" ""))]
6446   "TARGET_32BIT && arm_arch4"
6447   "
6448   if (!s_register_operand (operands[1], HImode))
6449     operands[1] = copy_to_mode_reg (HImode, operands[1]);
6450   "
6453 (define_expand "movhi"
6454   [(set (match_operand:HI 0 "general_operand" "")
6455         (match_operand:HI 1 "general_operand" ""))]
6456   "TARGET_EITHER"
6457   "
6458   if (TARGET_ARM)
6459     {
6460       if (can_create_pseudo_p ())
6461         {
6462           if (MEM_P (operands[0]))
6463             {
6464               if (arm_arch4)
6465                 {
6466                   emit_insn (gen_storehi_single_op (operands[0], operands[1]));
6467                   DONE;
6468                 }
6469               if (CONST_INT_P (operands[1]))
6470                 emit_insn (gen_storeinthi (operands[0], operands[1]));
6471               else
6472                 {
6473                   if (MEM_P (operands[1]))
6474                     operands[1] = force_reg (HImode, operands[1]);
6475                   if (BYTES_BIG_ENDIAN)
6476                     emit_insn (gen_storehi_bigend (operands[1], operands[0]));
6477                   else
6478                    emit_insn (gen_storehi (operands[1], operands[0]));
6479                 }
6480               DONE;
6481             }
6482           /* Sign extend a constant, and keep it in an SImode reg.  */
6483           else if (CONST_INT_P (operands[1]))
6484             {
6485               rtx reg = gen_reg_rtx (SImode);
6486               HOST_WIDE_INT val = INTVAL (operands[1]) & 0xffff;
6488               /* If the constant is already valid, leave it alone.  */
6489               if (!const_ok_for_arm (val))
6490                 {
6491                   /* If setting all the top bits will make the constant 
6492                      loadable in a single instruction, then set them.  
6493                      Otherwise, sign extend the number.  */
6495                   if (const_ok_for_arm (~(val | ~0xffff)))
6496                     val |= ~0xffff;
6497                   else if (val & 0x8000)
6498                     val |= ~0xffff;
6499                 }
6501               emit_insn (gen_movsi (reg, GEN_INT (val)));
6502               operands[1] = gen_lowpart (HImode, reg);
6503             }
6504           else if (arm_arch4 && optimize && can_create_pseudo_p ()
6505                    && MEM_P (operands[1]))
6506             {
6507               rtx reg = gen_reg_rtx (SImode);
6509               emit_insn (gen_zero_extendhisi2 (reg, operands[1]));
6510               operands[1] = gen_lowpart (HImode, reg);
6511             }
6512           else if (!arm_arch4)
6513             {
6514               if (MEM_P (operands[1]))
6515                 {
6516                   rtx base;
6517                   rtx offset = const0_rtx;
6518                   rtx reg = gen_reg_rtx (SImode);
6520                   if ((REG_P (base = XEXP (operands[1], 0))
6521                        || (GET_CODE (base) == PLUS
6522                            && (CONST_INT_P (offset = XEXP (base, 1)))
6523                            && ((INTVAL(offset) & 1) != 1)
6524                            && REG_P (base = XEXP (base, 0))))
6525                       && REGNO_POINTER_ALIGN (REGNO (base)) >= 32)
6526                     {
6527                       rtx new_rtx;
6529                       new_rtx = widen_memory_access (operands[1], SImode,
6530                                                      ((INTVAL (offset) & ~3)
6531                                                       - INTVAL (offset)));
6532                       emit_insn (gen_movsi (reg, new_rtx));
6533                       if (((INTVAL (offset) & 2) != 0)
6534                           ^ (BYTES_BIG_ENDIAN ? 1 : 0))
6535                         {
6536                           rtx reg2 = gen_reg_rtx (SImode);
6538                           emit_insn (gen_lshrsi3 (reg2, reg, GEN_INT (16)));
6539                           reg = reg2;
6540                         }
6541                     }
6542                   else
6543                     emit_insn (gen_movhi_bytes (reg, operands[1]));
6545                   operands[1] = gen_lowpart (HImode, reg);
6546                }
6547            }
6548         }
6549       /* Handle loading a large integer during reload.  */
6550       else if (CONST_INT_P (operands[1])
6551                && !const_ok_for_arm (INTVAL (operands[1]))
6552                && !const_ok_for_arm (~INTVAL (operands[1])))
6553         {
6554           /* Writing a constant to memory needs a scratch, which should
6555              be handled with SECONDARY_RELOADs.  */
6556           gcc_assert (REG_P (operands[0]));
6558           operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
6559           emit_insn (gen_movsi (operands[0], operands[1]));
6560           DONE;
6561        }
6562     }
6563   else if (TARGET_THUMB2)
6564     {
6565       /* Thumb-2 can do everything except mem=mem and mem=const easily.  */
6566       if (can_create_pseudo_p ())
6567         {
6568           if (!REG_P (operands[0]))
6569             operands[1] = force_reg (HImode, operands[1]);
6570           /* Zero extend a constant, and keep it in an SImode reg.  */
6571           else if (CONST_INT_P (operands[1]))
6572             {
6573               rtx reg = gen_reg_rtx (SImode);
6574               HOST_WIDE_INT val = INTVAL (operands[1]) & 0xffff;
6576               emit_insn (gen_movsi (reg, GEN_INT (val)));
6577               operands[1] = gen_lowpart (HImode, reg);
6578             }
6579         }
6580     }
6581   else /* TARGET_THUMB1 */
6582     {
6583       if (can_create_pseudo_p ())
6584         {
6585           if (CONST_INT_P (operands[1]))
6586             {
6587               rtx reg = gen_reg_rtx (SImode);
6589               emit_insn (gen_movsi (reg, operands[1]));
6590               operands[1] = gen_lowpart (HImode, reg);
6591             }
6593           /* ??? We shouldn't really get invalid addresses here, but this can
6594              happen if we are passed a SP (never OK for HImode/QImode) or 
6595              virtual register (also rejected as illegitimate for HImode/QImode)
6596              relative address.  */
6597           /* ??? This should perhaps be fixed elsewhere, for instance, in
6598              fixup_stack_1, by checking for other kinds of invalid addresses,
6599              e.g. a bare reference to a virtual register.  This may confuse the
6600              alpha though, which must handle this case differently.  */
6601           if (MEM_P (operands[0])
6602               && !memory_address_p (GET_MODE (operands[0]),
6603                                     XEXP (operands[0], 0)))
6604             operands[0]
6605               = replace_equiv_address (operands[0],
6606                                        copy_to_reg (XEXP (operands[0], 0)));
6607    
6608           if (MEM_P (operands[1])
6609               && !memory_address_p (GET_MODE (operands[1]),
6610                                     XEXP (operands[1], 0)))
6611             operands[1]
6612               = replace_equiv_address (operands[1],
6613                                        copy_to_reg (XEXP (operands[1], 0)));
6615           if (MEM_P (operands[1]) && optimize > 0)
6616             {
6617               rtx reg = gen_reg_rtx (SImode);
6619               emit_insn (gen_zero_extendhisi2 (reg, operands[1]));
6620               operands[1] = gen_lowpart (HImode, reg);
6621             }
6623           if (MEM_P (operands[0]))
6624             operands[1] = force_reg (HImode, operands[1]);
6625         }
6626       else if (CONST_INT_P (operands[1])
6627                 && !satisfies_constraint_I (operands[1]))
6628         {
6629           /* Handle loading a large integer during reload.  */
6631           /* Writing a constant to memory needs a scratch, which should
6632              be handled with SECONDARY_RELOADs.  */
6633           gcc_assert (REG_P (operands[0]));
6635           operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
6636           emit_insn (gen_movsi (operands[0], operands[1]));
6637           DONE;
6638         }
6639     }
6640   "
6643 (define_expand "movhi_bytes"
6644   [(set (match_dup 2) (zero_extend:SI (match_operand:HI 1 "" "")))
6645    (set (match_dup 3)
6646         (zero_extend:SI (match_dup 6)))
6647    (set (match_operand:SI 0 "" "")
6648          (ior:SI (ashift:SI (match_dup 4) (const_int 8)) (match_dup 5)))]
6649   "TARGET_ARM"
6650   "
6651   {
6652     rtx mem1, mem2;
6653     rtx addr = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
6655     mem1 = change_address (operands[1], QImode, addr);
6656     mem2 = change_address (operands[1], QImode,
6657                            plus_constant (Pmode, addr, 1));
6658     operands[0] = gen_lowpart (SImode, operands[0]);
6659     operands[1] = mem1;
6660     operands[2] = gen_reg_rtx (SImode);
6661     operands[3] = gen_reg_rtx (SImode);
6662     operands[6] = mem2;
6664     if (BYTES_BIG_ENDIAN)
6665       {
6666         operands[4] = operands[2];
6667         operands[5] = operands[3];
6668       }
6669     else
6670       {
6671         operands[4] = operands[3];
6672         operands[5] = operands[2];
6673       }
6674   }"
6677 (define_expand "movhi_bigend"
6678   [(set (match_dup 2)
6679         (rotate:SI (subreg:SI (match_operand:HI 1 "memory_operand" "") 0)
6680                    (const_int 16)))
6681    (set (match_dup 3)
6682         (ashiftrt:SI (match_dup 2) (const_int 16)))
6683    (set (match_operand:HI 0 "s_register_operand" "")
6684         (match_dup 4))]
6685   "TARGET_ARM"
6686   "
6687   operands[2] = gen_reg_rtx (SImode);
6688   operands[3] = gen_reg_rtx (SImode);
6689   operands[4] = gen_lowpart (HImode, operands[3]);
6690   "
6693 ;; Pattern to recognize insn generated default case above
6694 (define_insn "*movhi_insn_arch4"
6695   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m,r")
6696         (match_operand:HI 1 "general_operand"      "rIk,K,n,r,mi"))]
6697   "TARGET_ARM
6698    && arm_arch4 && !TARGET_HARD_FLOAT
6699    && (register_operand (operands[0], HImode)
6700        || register_operand (operands[1], HImode))"
6701   "@
6702    mov%?\\t%0, %1\\t%@ movhi
6703    mvn%?\\t%0, #%B1\\t%@ movhi
6704    movw%?\\t%0, %L1\\t%@ movhi
6705    strh%?\\t%1, %0\\t%@ movhi
6706    ldrh%?\\t%0, %1\\t%@ movhi"
6707   [(set_attr "predicable" "yes")
6708    (set_attr "pool_range" "*,*,*,*,256")
6709    (set_attr "neg_pool_range" "*,*,*,*,244")
6710    (set_attr "arch" "*,*,v6t2,*,*")
6711    (set_attr_alternative "type"
6712                          [(if_then_else (match_operand 1 "const_int_operand" "")
6713                                         (const_string "mov_imm" )
6714                                         (const_string "mov_reg"))
6715                           (const_string "mvn_imm")
6716                           (const_string "mov_imm")
6717                           (const_string "store_4")
6718                           (const_string "load_4")])]
6721 (define_insn "*movhi_bytes"
6722   [(set (match_operand:HI 0 "s_register_operand" "=r,r,r")
6723         (match_operand:HI 1 "arm_rhs_operand"  "I,rk,K"))]
6724   "TARGET_ARM && !TARGET_HARD_FLOAT"
6725   "@
6726    mov%?\\t%0, %1\\t%@ movhi
6727    mov%?\\t%0, %1\\t%@ movhi
6728    mvn%?\\t%0, #%B1\\t%@ movhi"
6729   [(set_attr "predicable" "yes")
6730    (set_attr "type" "mov_imm,mov_reg,mvn_imm")]
6733 ;; We use a DImode scratch because we may occasionally need an additional
6734 ;; temporary if the address isn't offsettable -- push_reload doesn't seem
6735 ;; to take any notice of the "o" constraints on reload_memory_operand operand.
6736 (define_expand "reload_outhi"
6737   [(parallel [(match_operand:HI 0 "arm_reload_memory_operand" "=o")
6738               (match_operand:HI 1 "s_register_operand"        "r")
6739               (match_operand:DI 2 "s_register_operand"        "=&l")])]
6740   "TARGET_EITHER"
6741   "if (TARGET_ARM)
6742      arm_reload_out_hi (operands);
6743    else
6744      thumb_reload_out_hi (operands);
6745   DONE;
6746   "
6749 (define_expand "reload_inhi"
6750   [(parallel [(match_operand:HI 0 "s_register_operand" "=r")
6751               (match_operand:HI 1 "arm_reload_memory_operand" "o")
6752               (match_operand:DI 2 "s_register_operand" "=&r")])]
6753   "TARGET_EITHER"
6754   "
6755   if (TARGET_ARM)
6756     arm_reload_in_hi (operands);
6757   else
6758     thumb_reload_out_hi (operands);
6759   DONE;
6762 (define_expand "movqi"
6763   [(set (match_operand:QI 0 "general_operand" "")
6764         (match_operand:QI 1 "general_operand" ""))]
6765   "TARGET_EITHER"
6766   "
6767   /* Everything except mem = const or mem = mem can be done easily */
6769   if (can_create_pseudo_p ())
6770     {
6771       if (CONST_INT_P (operands[1]))
6772         {
6773           rtx reg = gen_reg_rtx (SImode);
6775           /* For thumb we want an unsigned immediate, then we are more likely 
6776              to be able to use a movs insn.  */
6777           if (TARGET_THUMB)
6778             operands[1] = GEN_INT (INTVAL (operands[1]) & 255);
6780           emit_insn (gen_movsi (reg, operands[1]));
6781           operands[1] = gen_lowpart (QImode, reg);
6782         }
6784       if (TARGET_THUMB)
6785         {
6786           /* ??? We shouldn't really get invalid addresses here, but this can
6787              happen if we are passed a SP (never OK for HImode/QImode) or
6788              virtual register (also rejected as illegitimate for HImode/QImode)
6789              relative address.  */
6790           /* ??? This should perhaps be fixed elsewhere, for instance, in
6791              fixup_stack_1, by checking for other kinds of invalid addresses,
6792              e.g. a bare reference to a virtual register.  This may confuse the
6793              alpha though, which must handle this case differently.  */
6794           if (MEM_P (operands[0])
6795               && !memory_address_p (GET_MODE (operands[0]),
6796                                      XEXP (operands[0], 0)))
6797             operands[0]
6798               = replace_equiv_address (operands[0],
6799                                        copy_to_reg (XEXP (operands[0], 0)));
6800           if (MEM_P (operands[1])
6801               && !memory_address_p (GET_MODE (operands[1]),
6802                                     XEXP (operands[1], 0)))
6803              operands[1]
6804                = replace_equiv_address (operands[1],
6805                                         copy_to_reg (XEXP (operands[1], 0)));
6806         }
6808       if (MEM_P (operands[1]) && optimize > 0)
6809         {
6810           rtx reg = gen_reg_rtx (SImode);
6812           emit_insn (gen_zero_extendqisi2 (reg, operands[1]));
6813           operands[1] = gen_lowpart (QImode, reg);
6814         }
6816       if (MEM_P (operands[0]))
6817         operands[1] = force_reg (QImode, operands[1]);
6818     }
6819   else if (TARGET_THUMB
6820            && CONST_INT_P (operands[1])
6821            && !satisfies_constraint_I (operands[1]))
6822     {
6823       /* Handle loading a large integer during reload.  */
6825       /* Writing a constant to memory needs a scratch, which should
6826          be handled with SECONDARY_RELOADs.  */
6827       gcc_assert (REG_P (operands[0]));
6829       operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
6830       emit_insn (gen_movsi (operands[0], operands[1]));
6831       DONE;
6832     }
6833   "
6836 (define_insn "*arm_movqi_insn"
6837   [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,r,l,r,l,Uu,r,m")
6838         (match_operand:QI 1 "general_operand" "rk,rk,I,Py,K,Uu,l,Uh,r"))]
6839   "TARGET_32BIT
6840    && (   register_operand (operands[0], QImode)
6841        || register_operand (operands[1], QImode))"
6842   "@
6843    mov%?\\t%0, %1
6844    mov%?\\t%0, %1
6845    mov%?\\t%0, %1
6846    mov%?\\t%0, %1
6847    mvn%?\\t%0, #%B1
6848    ldrb%?\\t%0, %1
6849    strb%?\\t%1, %0
6850    ldrb%?\\t%0, %1
6851    strb%?\\t%1, %0"
6852   [(set_attr "type" "mov_reg,mov_reg,mov_imm,mov_imm,mvn_imm,load_4,store_4,load_4,store_4")
6853    (set_attr "predicable" "yes")
6854    (set_attr "predicable_short_it" "yes,yes,no,yes,no,no,no,no,no")
6855    (set_attr "arch" "t2,any,any,t2,any,t2,t2,any,any")
6856    (set_attr "length" "2,4,4,2,4,2,2,4,4")]
6859 ;; HFmode moves
6860 (define_expand "movhf"
6861   [(set (match_operand:HF 0 "general_operand" "")
6862         (match_operand:HF 1 "general_operand" ""))]
6863   "TARGET_EITHER"
6864   "
6865   if (TARGET_32BIT)
6866     {
6867       if (MEM_P (operands[0]))
6868         operands[1] = force_reg (HFmode, operands[1]);
6869     }
6870   else /* TARGET_THUMB1 */
6871     {
6872       if (can_create_pseudo_p ())
6873         {
6874            if (!REG_P (operands[0]))
6875              operands[1] = force_reg (HFmode, operands[1]);
6876         }
6877     }
6878   "
6881 (define_insn "*arm32_movhf"
6882   [(set (match_operand:HF 0 "nonimmediate_operand" "=r,m,r,r")
6883         (match_operand:HF 1 "general_operand"      " m,r,r,F"))]
6884   "TARGET_32BIT && !TARGET_HARD_FLOAT
6885    && (   s_register_operand (operands[0], HFmode)
6886        || s_register_operand (operands[1], HFmode))"
6887   "*
6888   switch (which_alternative)
6889     {
6890     case 0:     /* ARM register from memory */
6891       return \"ldrh%?\\t%0, %1\\t%@ __fp16\";
6892     case 1:     /* memory from ARM register */
6893       return \"strh%?\\t%1, %0\\t%@ __fp16\";
6894     case 2:     /* ARM register from ARM register */
6895       return \"mov%?\\t%0, %1\\t%@ __fp16\";
6896     case 3:     /* ARM register from constant */
6897       {
6898         long bits;
6899         rtx ops[4];
6901         bits = real_to_target (NULL, CONST_DOUBLE_REAL_VALUE (operands[1]),
6902                                HFmode);
6903         ops[0] = operands[0];
6904         ops[1] = GEN_INT (bits);
6905         ops[2] = GEN_INT (bits & 0xff00);
6906         ops[3] = GEN_INT (bits & 0x00ff);
6908         if (arm_arch_thumb2)
6909           output_asm_insn (\"movw%?\\t%0, %1\", ops);
6910         else
6911           output_asm_insn (\"mov%?\\t%0, %2\;orr%?\\t%0, %0, %3\", ops);
6912         return \"\";
6913        }
6914     default:
6915       gcc_unreachable ();
6916     }
6917   "
6918   [(set_attr "conds" "unconditional")
6919    (set_attr "type" "load_4,store_4,mov_reg,multiple")
6920    (set_attr "length" "4,4,4,8")
6921    (set_attr "predicable" "yes")]
6924 (define_expand "movsf"
6925   [(set (match_operand:SF 0 "general_operand" "")
6926         (match_operand:SF 1 "general_operand" ""))]
6927   "TARGET_EITHER"
6928   "
6929   if (TARGET_32BIT)
6930     {
6931       if (MEM_P (operands[0]))
6932         operands[1] = force_reg (SFmode, operands[1]);
6933     }
6934   else /* TARGET_THUMB1 */
6935     {
6936       if (can_create_pseudo_p ())
6937         {
6938            if (!REG_P (operands[0]))
6939              operands[1] = force_reg (SFmode, operands[1]);
6940         }
6941     }
6942   "
6945 ;; Transform a floating-point move of a constant into a core register into
6946 ;; an SImode operation.
6947 (define_split
6948   [(set (match_operand:SF 0 "arm_general_register_operand" "")
6949         (match_operand:SF 1 "immediate_operand" ""))]
6950   "TARGET_EITHER
6951    && reload_completed
6952    && CONST_DOUBLE_P (operands[1])"
6953   [(set (match_dup 2) (match_dup 3))]
6954   "
6955   operands[2] = gen_lowpart (SImode, operands[0]);
6956   operands[3] = gen_lowpart (SImode, operands[1]);
6957   if (operands[2] == 0 || operands[3] == 0)
6958     FAIL;
6959   "
6962 (define_insn "*arm_movsf_soft_insn"
6963   [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,m")
6964         (match_operand:SF 1 "general_operand"  "r,mE,r"))]
6965   "TARGET_32BIT
6966    && TARGET_SOFT_FLOAT
6967    && (!MEM_P (operands[0])
6968        || register_operand (operands[1], SFmode))"
6969   "@
6970    mov%?\\t%0, %1
6971    ldr%?\\t%0, %1\\t%@ float
6972    str%?\\t%1, %0\\t%@ float"
6973   [(set_attr "predicable" "yes")
6974    (set_attr "type" "mov_reg,load_4,store_4")
6975    (set_attr "arm_pool_range" "*,4096,*")
6976    (set_attr "thumb2_pool_range" "*,4094,*")
6977    (set_attr "arm_neg_pool_range" "*,4084,*")
6978    (set_attr "thumb2_neg_pool_range" "*,0,*")]
6981 (define_expand "movdf"
6982   [(set (match_operand:DF 0 "general_operand" "")
6983         (match_operand:DF 1 "general_operand" ""))]
6984   "TARGET_EITHER"
6985   "
6986   if (TARGET_32BIT)
6987     {
6988       if (MEM_P (operands[0]))
6989         operands[1] = force_reg (DFmode, operands[1]);
6990     }
6991   else /* TARGET_THUMB */
6992     {
6993       if (can_create_pseudo_p ())
6994         {
6995           if (!REG_P (operands[0]))
6996             operands[1] = force_reg (DFmode, operands[1]);
6997         }
6998     }
6999   "
7002 ;; Reloading a df mode value stored in integer regs to memory can require a
7003 ;; scratch reg.
7004 (define_expand "reload_outdf"
7005   [(match_operand:DF 0 "arm_reload_memory_operand" "=o")
7006    (match_operand:DF 1 "s_register_operand" "r")
7007    (match_operand:SI 2 "s_register_operand" "=&r")]
7008   "TARGET_THUMB2"
7009   "
7010   {
7011     enum rtx_code code = GET_CODE (XEXP (operands[0], 0));
7013     if (code == REG)
7014       operands[2] = XEXP (operands[0], 0);
7015     else if (code == POST_INC || code == PRE_DEC)
7016       {
7017         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7018         operands[1] = gen_rtx_SUBREG (DImode, operands[1], 0);
7019         emit_insn (gen_movdi (operands[0], operands[1]));
7020         DONE;
7021       }
7022     else if (code == PRE_INC)
7023       {
7024         rtx reg = XEXP (XEXP (operands[0], 0), 0);
7026         emit_insn (gen_addsi3 (reg, reg, GEN_INT (8)));
7027         operands[2] = reg;
7028       }
7029     else if (code == POST_DEC)
7030       operands[2] = XEXP (XEXP (operands[0], 0), 0);
7031     else
7032       emit_insn (gen_addsi3 (operands[2], XEXP (XEXP (operands[0], 0), 0),
7033                              XEXP (XEXP (operands[0], 0), 1)));
7035     emit_insn (gen_rtx_SET (replace_equiv_address (operands[0], operands[2]),
7036                             operands[1]));
7038     if (code == POST_DEC)
7039       emit_insn (gen_addsi3 (operands[2], operands[2], GEN_INT (-8)));
7041     DONE;
7042   }"
7045 (define_insn "*movdf_soft_insn"
7046   [(set (match_operand:DF 0 "nonimmediate_soft_df_operand" "=r,r,r,q,m")
7047         (match_operand:DF 1 "soft_df_operand" "rDa,Db,Dc,mF,q"))]
7048   "TARGET_32BIT && TARGET_SOFT_FLOAT
7049    && (   register_operand (operands[0], DFmode)
7050        || register_operand (operands[1], DFmode))"
7051   "*
7052   switch (which_alternative)
7053     {
7054     case 0:
7055     case 1:
7056     case 2:
7057       return \"#\";
7058     default:
7059       return output_move_double (operands, true, NULL);
7060     }
7061   "
7062   [(set_attr "length" "8,12,16,8,8")
7063    (set_attr "type" "multiple,multiple,multiple,load_8,store_8")
7064    (set_attr "arm_pool_range" "*,*,*,1020,*")
7065    (set_attr "thumb2_pool_range" "*,*,*,1018,*")
7066    (set_attr "arm_neg_pool_range" "*,*,*,1004,*")
7067    (set_attr "thumb2_neg_pool_range" "*,*,*,0,*")]
7071 ;; load- and store-multiple insns
7072 ;; The arm can load/store any set of registers, provided that they are in
7073 ;; ascending order, but these expanders assume a contiguous set.
7075 (define_expand "load_multiple"
7076   [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
7077                           (match_operand:SI 1 "" ""))
7078                      (use (match_operand:SI 2 "" ""))])]
7079   "TARGET_32BIT"
7081   HOST_WIDE_INT offset = 0;
7083   /* Support only fixed point registers.  */
7084   if (!CONST_INT_P (operands[2])
7085       || INTVAL (operands[2]) > MAX_LDM_STM_OPS
7086       || INTVAL (operands[2]) < 2
7087       || !MEM_P (operands[1])
7088       || !REG_P (operands[0])
7089       || REGNO (operands[0]) > (LAST_ARM_REGNUM - 1)
7090       || REGNO (operands[0]) + INTVAL (operands[2]) > LAST_ARM_REGNUM)
7091     FAIL;
7093   operands[3]
7094     = arm_gen_load_multiple (arm_regs_in_sequence + REGNO (operands[0]),
7095                              INTVAL (operands[2]),
7096                              force_reg (SImode, XEXP (operands[1], 0)),
7097                              FALSE, operands[1], &offset);
7100 (define_expand "store_multiple"
7101   [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
7102                           (match_operand:SI 1 "" ""))
7103                      (use (match_operand:SI 2 "" ""))])]
7104   "TARGET_32BIT"
7106   HOST_WIDE_INT offset = 0;
7108   /* Support only fixed point registers.  */
7109   if (!CONST_INT_P (operands[2])
7110       || INTVAL (operands[2]) > MAX_LDM_STM_OPS
7111       || INTVAL (operands[2]) < 2
7112       || !REG_P (operands[1])
7113       || !MEM_P (operands[0])
7114       || REGNO (operands[1]) > (LAST_ARM_REGNUM - 1)
7115       || REGNO (operands[1]) + INTVAL (operands[2]) > LAST_ARM_REGNUM)
7116     FAIL;
7118   operands[3]
7119     = arm_gen_store_multiple (arm_regs_in_sequence + REGNO (operands[1]),
7120                               INTVAL (operands[2]),
7121                               force_reg (SImode, XEXP (operands[0], 0)),
7122                               FALSE, operands[0], &offset);
7126 (define_expand "setmemsi"
7127   [(match_operand:BLK 0 "general_operand" "")
7128    (match_operand:SI 1 "const_int_operand" "")
7129    (match_operand:SI 2 "const_int_operand" "")
7130    (match_operand:SI 3 "const_int_operand" "")]
7131   "TARGET_32BIT"
7133   if (arm_gen_setmem (operands))
7134     DONE;
7136   FAIL;
7140 ;; Move a block of memory if it is word aligned and MORE than 2 words long.
7141 ;; We could let this apply for blocks of less than this, but it clobbers so
7142 ;; many registers that there is then probably a better way.
7144 (define_expand "movmemqi"
7145   [(match_operand:BLK 0 "general_operand" "")
7146    (match_operand:BLK 1 "general_operand" "")
7147    (match_operand:SI 2 "const_int_operand" "")
7148    (match_operand:SI 3 "const_int_operand" "")]
7149   ""
7150   "
7151   if (TARGET_32BIT)
7152     {
7153       if (TARGET_LDRD && current_tune->prefer_ldrd_strd
7154           && !optimize_function_for_size_p (cfun))
7155         {
7156           if (gen_movmem_ldrd_strd (operands))
7157             DONE;
7158           FAIL;
7159         }
7161       if (arm_gen_movmemqi (operands))
7162         DONE;
7163       FAIL;
7164     }
7165   else /* TARGET_THUMB1 */
7166     {
7167       if (   INTVAL (operands[3]) != 4
7168           || INTVAL (operands[2]) > 48)
7169         FAIL;
7171       thumb_expand_movmemqi (operands);
7172       DONE;
7173     }
7174   "
7178 ;; Compare & branch insns
7179 ;; The range calculations are based as follows:
7180 ;; For forward branches, the address calculation returns the address of
7181 ;; the next instruction.  This is 2 beyond the branch instruction.
7182 ;; For backward branches, the address calculation returns the address of
7183 ;; the first instruction in this pattern (cmp).  This is 2 before the branch
7184 ;; instruction for the shortest sequence, and 4 before the branch instruction
7185 ;; if we have to jump around an unconditional branch.
7186 ;; To the basic branch range the PC offset must be added (this is +4).
7187 ;; So for forward branches we have 
7188 ;;   (pos_range - pos_base_offs + pc_offs) = (pos_range - 2 + 4).
7189 ;; And for backward branches we have 
7190 ;;   (neg_range - neg_base_offs + pc_offs) = (neg_range - (-2 or -4) + 4).
7192 ;; For a 'b'       pos_range = 2046, neg_range = -2048 giving (-2040->2048).
7193 ;; For a 'b<cond>' pos_range = 254,  neg_range = -256  giving (-250 ->256).
7195 (define_expand "cbranchsi4"
7196   [(set (pc) (if_then_else
7197               (match_operator 0 "expandable_comparison_operator"
7198                [(match_operand:SI 1 "s_register_operand" "")
7199                 (match_operand:SI 2 "nonmemory_operand" "")])
7200               (label_ref (match_operand 3 "" ""))
7201               (pc)))]
7202   "TARGET_EITHER"
7203   "
7204   if (!TARGET_THUMB1)
7205     {
7206       if (!arm_validize_comparison (&operands[0], &operands[1], &operands[2]))
7207         FAIL;
7208       emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
7209                                       operands[3]));
7210       DONE;
7211     }
7212   if (thumb1_cmpneg_operand (operands[2], SImode))
7213     {
7214       emit_jump_insn (gen_cbranchsi4_scratch (NULL, operands[1], operands[2],
7215                                               operands[3], operands[0]));
7216       DONE;
7217     }
7218   if (!thumb1_cmp_operand (operands[2], SImode))
7219     operands[2] = force_reg (SImode, operands[2]);
7220   ")
7222 (define_expand "cbranchsf4"
7223   [(set (pc) (if_then_else
7224               (match_operator 0 "expandable_comparison_operator"
7225                [(match_operand:SF 1 "s_register_operand" "")
7226                 (match_operand:SF 2 "vfp_compare_operand" "")])
7227               (label_ref (match_operand 3 "" ""))
7228               (pc)))]
7229   "TARGET_32BIT && TARGET_HARD_FLOAT"
7230   "emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
7231                                    operands[3])); DONE;"
7234 (define_expand "cbranchdf4"
7235   [(set (pc) (if_then_else
7236               (match_operator 0 "expandable_comparison_operator"
7237                [(match_operand:DF 1 "s_register_operand" "")
7238                 (match_operand:DF 2 "vfp_compare_operand" "")])
7239               (label_ref (match_operand 3 "" ""))
7240               (pc)))]
7241   "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
7242   "emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
7243                                    operands[3])); DONE;"
7246 (define_expand "cbranchdi4"
7247   [(set (pc) (if_then_else
7248               (match_operator 0 "expandable_comparison_operator"
7249                [(match_operand:DI 1 "s_register_operand" "")
7250                 (match_operand:DI 2 "cmpdi_operand" "")])
7251               (label_ref (match_operand 3 "" ""))
7252               (pc)))]
7253   "TARGET_32BIT"
7254   "{
7255      if (!arm_validize_comparison (&operands[0], &operands[1], &operands[2]))
7256        FAIL;
7257      emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
7258                                        operands[3]));
7259      DONE;
7260    }"
7263 ;; Comparison and test insns
7265 (define_insn "*arm_cmpsi_insn"
7266   [(set (reg:CC CC_REGNUM)
7267         (compare:CC (match_operand:SI 0 "s_register_operand" "l,r,r,r,r")
7268                     (match_operand:SI 1 "arm_add_operand"    "Py,r,r,I,L")))]
7269   "TARGET_32BIT"
7270   "@
7271    cmp%?\\t%0, %1
7272    cmp%?\\t%0, %1
7273    cmp%?\\t%0, %1
7274    cmp%?\\t%0, %1
7275    cmn%?\\t%0, #%n1"
7276   [(set_attr "conds" "set")
7277    (set_attr "arch" "t2,t2,any,any,any")
7278    (set_attr "length" "2,2,4,4,4")
7279    (set_attr "predicable" "yes")
7280    (set_attr "predicable_short_it" "yes,yes,yes,no,no")
7281    (set_attr "type" "alus_imm,alus_sreg,alus_sreg,alus_imm,alus_imm")]
7284 (define_insn "*cmpsi_shiftsi"
7285   [(set (reg:CC CC_REGNUM)
7286         (compare:CC (match_operand:SI   0 "s_register_operand" "r,r,r")
7287                     (match_operator:SI  3 "shift_operator"
7288                      [(match_operand:SI 1 "s_register_operand" "r,r,r")
7289                       (match_operand:SI 2 "shift_amount_operand" "M,r,M")])))]
7290   "TARGET_32BIT"
7291   "cmp\\t%0, %1%S3"
7292   [(set_attr "conds" "set")
7293    (set_attr "shift" "1")
7294    (set_attr "arch" "32,a,a")
7295    (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
7297 (define_insn "*cmpsi_shiftsi_swp"
7298   [(set (reg:CC_SWP CC_REGNUM)
7299         (compare:CC_SWP (match_operator:SI 3 "shift_operator"
7300                          [(match_operand:SI 1 "s_register_operand" "r,r,r")
7301                           (match_operand:SI 2 "shift_amount_operand" "M,r,M")])
7302                         (match_operand:SI 0 "s_register_operand" "r,r,r")))]
7303   "TARGET_32BIT"
7304   "cmp%?\\t%0, %1%S3"
7305   [(set_attr "conds" "set")
7306    (set_attr "shift" "1")
7307    (set_attr "arch" "32,a,a")
7308    (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
7310 (define_insn "*arm_cmpsi_negshiftsi_si"
7311   [(set (reg:CC_Z CC_REGNUM)
7312         (compare:CC_Z
7313          (neg:SI (match_operator:SI 1 "shift_operator"
7314                     [(match_operand:SI 2 "s_register_operand" "r")
7315                      (match_operand:SI 3 "reg_or_int_operand" "rM")]))
7316          (match_operand:SI 0 "s_register_operand" "r")))]
7317   "TARGET_ARM"
7318   "cmn%?\\t%0, %2%S1"
7319   [(set_attr "conds" "set")
7320    (set (attr "type") (if_then_else (match_operand 3 "const_int_operand" "")
7321                                     (const_string "alus_shift_imm")
7322                                     (const_string "alus_shift_reg")))
7323    (set_attr "predicable" "yes")]
7326 ;; DImode comparisons.  The generic code generates branches that
7327 ;; if-conversion can not reduce to a conditional compare, so we do
7328 ;; that directly.
7330 (define_insn_and_split "*arm_cmpdi_insn"
7331   [(set (reg:CC_NCV CC_REGNUM)
7332         (compare:CC_NCV (match_operand:DI 0 "s_register_operand" "r")
7333                         (match_operand:DI 1 "arm_di_operand"       "rDi")))
7334    (clobber (match_scratch:SI 2 "=r"))]
7335   "TARGET_32BIT"
7336   "#"   ; "cmp\\t%Q0, %Q1\;sbcs\\t%2, %R0, %R1"
7337   "&& reload_completed"
7338   [(set (reg:CC CC_REGNUM)
7339         (compare:CC (match_dup 0) (match_dup 1)))
7340    (parallel [(set (reg:CC CC_REGNUM)
7341                    (compare:CC (match_dup 3) (match_dup 4)))
7342               (set (match_dup 2)
7343                    (minus:SI (match_dup 5)
7344                             (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))])]
7345   {
7346     operands[3] = gen_highpart (SImode, operands[0]);
7347     operands[0] = gen_lowpart (SImode, operands[0]);
7348     if (CONST_INT_P (operands[1]))
7349       {
7350         operands[4] = GEN_INT (~INTVAL (gen_highpart_mode (SImode,
7351                                                            DImode,
7352                                                            operands[1])));
7353         operands[5] = gen_rtx_PLUS (SImode, operands[3], operands[4]);
7354       }
7355     else
7356       {
7357         operands[4] = gen_highpart (SImode, operands[1]);
7358         operands[5] = gen_rtx_MINUS (SImode, operands[3], operands[4]);
7359       }
7360     operands[1] = gen_lowpart (SImode, operands[1]);
7361     operands[2] = gen_lowpart (SImode, operands[2]);
7362   }
7363   [(set_attr "conds" "set")
7364    (set_attr "length" "8")
7365    (set_attr "type" "multiple")]
7368 (define_insn_and_split "*arm_cmpdi_unsigned"
7369   [(set (reg:CC_CZ CC_REGNUM)
7370         (compare:CC_CZ (match_operand:DI 0 "s_register_operand" "l,r,r,r")
7371                        (match_operand:DI 1 "arm_di_operand"     "Py,r,Di,rDi")))]
7373   "TARGET_32BIT"
7374   "#"   ; "cmp\\t%R0, %R1\;it eq\;cmpeq\\t%Q0, %Q1"
7375   "&& reload_completed"
7376   [(set (reg:CC CC_REGNUM)
7377         (compare:CC (match_dup 2) (match_dup 3)))
7378    (cond_exec (eq:SI (reg:CC CC_REGNUM) (const_int 0))
7379               (set (reg:CC CC_REGNUM)
7380                    (compare:CC (match_dup 0) (match_dup 1))))]
7381   {
7382     operands[2] = gen_highpart (SImode, operands[0]);
7383     operands[0] = gen_lowpart (SImode, operands[0]);
7384     if (CONST_INT_P (operands[1]))
7385       operands[3] = gen_highpart_mode (SImode, DImode, operands[1]);
7386     else
7387       operands[3] = gen_highpart (SImode, operands[1]);
7388     operands[1] = gen_lowpart (SImode, operands[1]);
7389   }
7390   [(set_attr "conds" "set")
7391    (set_attr "enabled_for_short_it" "yes,yes,no,*")
7392    (set_attr "arch" "t2,t2,t2,a")
7393    (set_attr "length" "6,6,10,8")
7394    (set_attr "type" "multiple")]
7397 (define_insn "*arm_cmpdi_zero"
7398   [(set (reg:CC_Z CC_REGNUM)
7399         (compare:CC_Z (match_operand:DI 0 "s_register_operand" "r")
7400                       (const_int 0)))
7401    (clobber (match_scratch:SI 1 "=r"))]
7402   "TARGET_32BIT"
7403   "orrs%?\\t%1, %Q0, %R0"
7404   [(set_attr "conds" "set")
7405    (set_attr "type" "logics_reg")]
7408 ; This insn allows redundant compares to be removed by cse, nothing should
7409 ; ever appear in the output file since (set (reg x) (reg x)) is a no-op that
7410 ; is deleted later on. The match_dup will match the mode here, so that
7411 ; mode changes of the condition codes aren't lost by this even though we don't
7412 ; specify what they are.
7414 (define_insn "*deleted_compare"
7415   [(set (match_operand 0 "cc_register" "") (match_dup 0))]
7416   "TARGET_32BIT"
7417   "\\t%@ deleted compare"
7418   [(set_attr "conds" "set")
7419    (set_attr "length" "0")
7420    (set_attr "type" "no_insn")]
7424 ;; Conditional branch insns
7426 (define_expand "cbranch_cc"
7427   [(set (pc)
7428         (if_then_else (match_operator 0 "" [(match_operand 1 "" "")
7429                                             (match_operand 2 "" "")])
7430                       (label_ref (match_operand 3 "" ""))
7431                       (pc)))]
7432   "TARGET_32BIT"
7433   "operands[1] = arm_gen_compare_reg (GET_CODE (operands[0]),
7434                                       operands[1], operands[2], NULL_RTX);
7435    operands[2] = const0_rtx;"
7439 ;; Patterns to match conditional branch insns.
7442 (define_insn "arm_cond_branch"
7443   [(set (pc)
7444         (if_then_else (match_operator 1 "arm_comparison_operator"
7445                        [(match_operand 2 "cc_register" "") (const_int 0)])
7446                       (label_ref (match_operand 0 "" ""))
7447                       (pc)))]
7448   "TARGET_32BIT"
7449   "*
7450   if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
7451     {
7452       arm_ccfsm_state += 2;
7453       return \"\";
7454     }
7455   return \"b%d1\\t%l0\";
7456   "
7457   [(set_attr "conds" "use")
7458    (set_attr "type" "branch")
7459    (set (attr "length")
7460         (if_then_else
7461            (and (match_test "TARGET_THUMB2")
7462                 (and (ge (minus (match_dup 0) (pc)) (const_int -250))
7463                      (le (minus (match_dup 0) (pc)) (const_int 256))))
7464            (const_int 2)
7465            (const_int 4)))]
7468 (define_insn "*arm_cond_branch_reversed"
7469   [(set (pc)
7470         (if_then_else (match_operator 1 "arm_comparison_operator"
7471                        [(match_operand 2 "cc_register" "") (const_int 0)])
7472                       (pc)
7473                       (label_ref (match_operand 0 "" ""))))]
7474   "TARGET_32BIT"
7475   "*
7476   if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
7477     {
7478       arm_ccfsm_state += 2;
7479       return \"\";
7480     }
7481   return \"b%D1\\t%l0\";
7482   "
7483   [(set_attr "conds" "use")
7484    (set_attr "type" "branch")
7485    (set (attr "length")
7486         (if_then_else
7487            (and (match_test "TARGET_THUMB2")
7488                 (and (ge (minus (match_dup 0) (pc)) (const_int -250))
7489                      (le (minus (match_dup 0) (pc)) (const_int 256))))
7490            (const_int 2)
7491            (const_int 4)))]
7496 ; scc insns
7498 (define_expand "cstore_cc"
7499   [(set (match_operand:SI 0 "s_register_operand" "")
7500         (match_operator:SI 1 "" [(match_operand 2 "" "")
7501                                  (match_operand 3 "" "")]))]
7502   "TARGET_32BIT"
7503   "operands[2] = arm_gen_compare_reg (GET_CODE (operands[1]),
7504                                       operands[2], operands[3], NULL_RTX);
7505    operands[3] = const0_rtx;"
7508 (define_insn_and_split "*mov_scc"
7509   [(set (match_operand:SI 0 "s_register_operand" "=r")
7510         (match_operator:SI 1 "arm_comparison_operator_mode"
7511          [(match_operand 2 "cc_register" "") (const_int 0)]))]
7512   "TARGET_ARM"
7513   "#"   ; "mov%D1\\t%0, #0\;mov%d1\\t%0, #1"
7514   "TARGET_ARM"
7515   [(set (match_dup 0)
7516         (if_then_else:SI (match_dup 1)
7517                          (const_int 1)
7518                          (const_int 0)))]
7519   ""
7520   [(set_attr "conds" "use")
7521    (set_attr "length" "8")
7522    (set_attr "type" "multiple")]
7525 (define_insn_and_split "*mov_negscc"
7526   [(set (match_operand:SI 0 "s_register_operand" "=r")
7527         (neg:SI (match_operator:SI 1 "arm_comparison_operator_mode"
7528                  [(match_operand 2 "cc_register" "") (const_int 0)])))]
7529   "TARGET_ARM"
7530   "#"   ; "mov%D1\\t%0, #0\;mvn%d1\\t%0, #0"
7531   "TARGET_ARM"
7532   [(set (match_dup 0)
7533         (if_then_else:SI (match_dup 1)
7534                          (match_dup 3)
7535                          (const_int 0)))]
7536   {
7537     operands[3] = GEN_INT (~0);
7538   }
7539   [(set_attr "conds" "use")
7540    (set_attr "length" "8")
7541    (set_attr "type" "multiple")]
7544 (define_insn_and_split "*mov_notscc"
7545   [(set (match_operand:SI 0 "s_register_operand" "=r")
7546         (not:SI (match_operator:SI 1 "arm_comparison_operator"
7547                  [(match_operand 2 "cc_register" "") (const_int 0)])))]
7548   "TARGET_ARM"
7549   "#"   ; "mvn%D1\\t%0, #0\;mvn%d1\\t%0, #1"
7550   "TARGET_ARM"
7551   [(set (match_dup 0)
7552         (if_then_else:SI (match_dup 1)
7553                          (match_dup 3)
7554                          (match_dup 4)))]
7555   {
7556     operands[3] = GEN_INT (~1);
7557     operands[4] = GEN_INT (~0);
7558   }
7559   [(set_attr "conds" "use")
7560    (set_attr "length" "8")
7561    (set_attr "type" "multiple")]
7564 (define_expand "cstoresi4"
7565   [(set (match_operand:SI 0 "s_register_operand" "")
7566         (match_operator:SI 1 "expandable_comparison_operator"
7567          [(match_operand:SI 2 "s_register_operand" "")
7568           (match_operand:SI 3 "reg_or_int_operand" "")]))]
7569   "TARGET_32BIT || TARGET_THUMB1"
7570   "{
7571   rtx op3, scratch, scratch2;
7573   if (!TARGET_THUMB1)
7574     {
7575       if (!arm_add_operand (operands[3], SImode))
7576         operands[3] = force_reg (SImode, operands[3]);
7577       emit_insn (gen_cstore_cc (operands[0], operands[1],
7578                                 operands[2], operands[3]));
7579       DONE;
7580     }
7582   if (operands[3] == const0_rtx)
7583     {
7584       switch (GET_CODE (operands[1]))
7585         {
7586         case EQ:
7587           emit_insn (gen_cstoresi_eq0_thumb1 (operands[0], operands[2]));
7588           break;
7590         case NE:
7591           emit_insn (gen_cstoresi_ne0_thumb1 (operands[0], operands[2]));
7592           break;
7594         case LE:
7595           scratch = expand_binop (SImode, add_optab, operands[2], constm1_rtx,
7596                                   NULL_RTX, 0, OPTAB_WIDEN);
7597           scratch = expand_binop (SImode, ior_optab, operands[2], scratch,
7598                                   NULL_RTX, 0, OPTAB_WIDEN);
7599           expand_binop (SImode, lshr_optab, scratch, GEN_INT (31),
7600                         operands[0], 1, OPTAB_WIDEN);
7601           break;
7603         case GE:
7604           scratch = expand_unop (SImode, one_cmpl_optab, operands[2],
7605                                  NULL_RTX, 1);
7606           expand_binop (SImode, lshr_optab, scratch, GEN_INT (31),
7607                         NULL_RTX, 1, OPTAB_WIDEN);
7608           break;
7610         case GT:
7611           scratch = expand_binop (SImode, ashr_optab, operands[2],
7612                                   GEN_INT (31), NULL_RTX, 0, OPTAB_WIDEN);
7613           scratch = expand_binop (SImode, sub_optab, scratch, operands[2],
7614                                   NULL_RTX, 0, OPTAB_WIDEN);
7615           expand_binop (SImode, lshr_optab, scratch, GEN_INT (31), operands[0],
7616                         0, OPTAB_WIDEN);
7617           break;
7619         /* LT is handled by generic code.  No need for unsigned with 0.  */
7620         default:
7621           FAIL;
7622         }
7623       DONE;
7624     }
7626   switch (GET_CODE (operands[1]))
7627     {
7628     case EQ:
7629       scratch = expand_binop (SImode, sub_optab, operands[2], operands[3],
7630                               NULL_RTX, 0, OPTAB_WIDEN);
7631       emit_insn (gen_cstoresi_eq0_thumb1 (operands[0], scratch));
7632       break;
7634     case NE:
7635       scratch = expand_binop (SImode, sub_optab, operands[2], operands[3],
7636                               NULL_RTX, 0, OPTAB_WIDEN);
7637       emit_insn (gen_cstoresi_ne0_thumb1 (operands[0], scratch));
7638       break;
7640     case LE:
7641       op3 = force_reg (SImode, operands[3]);
7643       scratch = expand_binop (SImode, lshr_optab, operands[2], GEN_INT (31),
7644                               NULL_RTX, 1, OPTAB_WIDEN);
7645       scratch2 = expand_binop (SImode, ashr_optab, op3, GEN_INT (31),
7646                               NULL_RTX, 0, OPTAB_WIDEN);
7647       emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch2,
7648                                           op3, operands[2]));
7649       break;
7651     case GE:
7652       op3 = operands[3];
7653       if (!thumb1_cmp_operand (op3, SImode))
7654         op3 = force_reg (SImode, op3);
7655       scratch = expand_binop (SImode, ashr_optab, operands[2], GEN_INT (31),
7656                               NULL_RTX, 0, OPTAB_WIDEN);
7657       scratch2 = expand_binop (SImode, lshr_optab, op3, GEN_INT (31),
7658                                NULL_RTX, 1, OPTAB_WIDEN);
7659       emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch2,
7660                                           operands[2], op3));
7661       break;
7663     case LEU:
7664       op3 = force_reg (SImode, operands[3]);
7665       scratch = force_reg (SImode, const0_rtx);
7666       emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch,
7667                                           op3, operands[2]));
7668       break;
7670     case GEU:
7671       op3 = operands[3];
7672       if (!thumb1_cmp_operand (op3, SImode))
7673         op3 = force_reg (SImode, op3);
7674       scratch = force_reg (SImode, const0_rtx);
7675       emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch,
7676                                           operands[2], op3));
7677       break;
7679     case LTU:
7680       op3 = operands[3];
7681       if (!thumb1_cmp_operand (op3, SImode))
7682         op3 = force_reg (SImode, op3);
7683       scratch = gen_reg_rtx (SImode);
7684       emit_insn (gen_cstoresi_ltu_thumb1 (operands[0], operands[2], op3));
7685       break;
7687     case GTU:
7688       op3 = force_reg (SImode, operands[3]);
7689       scratch = gen_reg_rtx (SImode);
7690       emit_insn (gen_cstoresi_ltu_thumb1 (operands[0], op3, operands[2]));
7691       break;
7693     /* No good sequences for GT, LT.  */
7694     default:
7695       FAIL;
7696     }
7697   DONE;
7700 (define_expand "cstorehf4"
7701   [(set (match_operand:SI 0 "s_register_operand")
7702         (match_operator:SI 1 "expandable_comparison_operator"
7703          [(match_operand:HF 2 "s_register_operand")
7704           (match_operand:HF 3 "vfp_compare_operand")]))]
7705   "TARGET_VFP_FP16INST"
7706   {
7707     if (!arm_validize_comparison (&operands[1],
7708                                   &operands[2],
7709                                   &operands[3]))
7710        FAIL;
7712     emit_insn (gen_cstore_cc (operands[0], operands[1],
7713                               operands[2], operands[3]));
7714     DONE;
7715   }
7718 (define_expand "cstoresf4"
7719   [(set (match_operand:SI 0 "s_register_operand" "")
7720         (match_operator:SI 1 "expandable_comparison_operator"
7721          [(match_operand:SF 2 "s_register_operand" "")
7722           (match_operand:SF 3 "vfp_compare_operand" "")]))]
7723   "TARGET_32BIT && TARGET_HARD_FLOAT"
7724   "emit_insn (gen_cstore_cc (operands[0], operands[1],
7725                              operands[2], operands[3])); DONE;"
7728 (define_expand "cstoredf4"
7729   [(set (match_operand:SI 0 "s_register_operand" "")
7730         (match_operator:SI 1 "expandable_comparison_operator"
7731          [(match_operand:DF 2 "s_register_operand" "")
7732           (match_operand:DF 3 "vfp_compare_operand" "")]))]
7733   "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
7734   "emit_insn (gen_cstore_cc (operands[0], operands[1],
7735                              operands[2], operands[3])); DONE;"
7738 (define_expand "cstoredi4"
7739   [(set (match_operand:SI 0 "s_register_operand" "")
7740         (match_operator:SI 1 "expandable_comparison_operator"
7741          [(match_operand:DI 2 "s_register_operand" "")
7742           (match_operand:DI 3 "cmpdi_operand" "")]))]
7743   "TARGET_32BIT"
7744   "{
7745      if (!arm_validize_comparison (&operands[1],
7746                                    &operands[2],
7747                                    &operands[3]))
7748        FAIL;
7749      emit_insn (gen_cstore_cc (operands[0], operands[1], operands[2],
7750                                  operands[3]));
7751      DONE;
7752    }"
7756 ;; Conditional move insns
7758 (define_expand "movsicc"
7759   [(set (match_operand:SI 0 "s_register_operand" "")
7760         (if_then_else:SI (match_operand 1 "expandable_comparison_operator" "")
7761                          (match_operand:SI 2 "arm_not_operand" "")
7762                          (match_operand:SI 3 "arm_not_operand" "")))]
7763   "TARGET_32BIT"
7764   "
7765   {
7766     enum rtx_code code;
7767     rtx ccreg;
7769     if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0), 
7770                                   &XEXP (operands[1], 1)))
7771       FAIL;
7773     code = GET_CODE (operands[1]);
7774     ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
7775                                  XEXP (operands[1], 1), NULL_RTX);
7776     operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7777   }"
7780 (define_expand "movhfcc"
7781   [(set (match_operand:HF 0 "s_register_operand")
7782         (if_then_else:HF (match_operand 1 "arm_cond_move_operator")
7783                          (match_operand:HF 2 "s_register_operand")
7784                          (match_operand:HF 3 "s_register_operand")))]
7785   "TARGET_VFP_FP16INST"
7786   "
7787   {
7788     enum rtx_code code = GET_CODE (operands[1]);
7789     rtx ccreg;
7791     if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
7792                                   &XEXP (operands[1], 1)))
7793       FAIL;
7795     code = GET_CODE (operands[1]);
7796     ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
7797                                  XEXP (operands[1], 1), NULL_RTX);
7798     operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7799   }"
7802 (define_expand "movsfcc"
7803   [(set (match_operand:SF 0 "s_register_operand" "")
7804         (if_then_else:SF (match_operand 1 "arm_cond_move_operator" "")
7805                          (match_operand:SF 2 "s_register_operand" "")
7806                          (match_operand:SF 3 "s_register_operand" "")))]
7807   "TARGET_32BIT && TARGET_HARD_FLOAT"
7808   "
7809   {
7810     enum rtx_code code = GET_CODE (operands[1]);
7811     rtx ccreg;
7813     if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
7814                                   &XEXP (operands[1], 1)))
7815        FAIL;
7817     code = GET_CODE (operands[1]);
7818     ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
7819                                  XEXP (operands[1], 1), NULL_RTX);
7820     operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7821   }"
7824 (define_expand "movdfcc"
7825   [(set (match_operand:DF 0 "s_register_operand" "")
7826         (if_then_else:DF (match_operand 1 "arm_cond_move_operator" "")
7827                          (match_operand:DF 2 "s_register_operand" "")
7828                          (match_operand:DF 3 "s_register_operand" "")))]
7829   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
7830   "
7831   {
7832     enum rtx_code code = GET_CODE (operands[1]);
7833     rtx ccreg;
7835     if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0), 
7836                                   &XEXP (operands[1], 1)))
7837        FAIL;
7838     code = GET_CODE (operands[1]);
7839     ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
7840                                  XEXP (operands[1], 1), NULL_RTX);
7841     operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7842   }"
7845 (define_insn "*cmov<mode>"
7846     [(set (match_operand:SDF 0 "s_register_operand" "=<F_constraint>")
7847         (if_then_else:SDF (match_operator 1 "arm_vsel_comparison_operator"
7848                           [(match_operand 2 "cc_register" "") (const_int 0)])
7849                           (match_operand:SDF 3 "s_register_operand"
7850                                               "<F_constraint>")
7851                           (match_operand:SDF 4 "s_register_operand"
7852                                               "<F_constraint>")))]
7853   "TARGET_HARD_FLOAT && TARGET_VFP5 <vfp_double_cond>"
7854   "*
7855   {
7856     enum arm_cond_code code = maybe_get_arm_condition_code (operands[1]);
7857     switch (code)
7858       {
7859       case ARM_GE:
7860       case ARM_GT:
7861       case ARM_EQ:
7862       case ARM_VS:
7863         return \"vsel%d1.<V_if_elem>\\t%<V_reg>0, %<V_reg>3, %<V_reg>4\";
7864       case ARM_LT:
7865       case ARM_LE:
7866       case ARM_NE:
7867       case ARM_VC:
7868         return \"vsel%D1.<V_if_elem>\\t%<V_reg>0, %<V_reg>4, %<V_reg>3\";
7869       default:
7870         gcc_unreachable ();
7871       }
7872     return \"\";
7873   }"
7874   [(set_attr "conds" "use")
7875    (set_attr "type" "fcsel")]
7878 (define_insn "*cmovhf"
7879     [(set (match_operand:HF 0 "s_register_operand" "=t")
7880         (if_then_else:HF (match_operator 1 "arm_vsel_comparison_operator"
7881                          [(match_operand 2 "cc_register" "") (const_int 0)])
7882                           (match_operand:HF 3 "s_register_operand" "t")
7883                           (match_operand:HF 4 "s_register_operand" "t")))]
7884   "TARGET_VFP_FP16INST"
7885   "*
7886   {
7887     enum arm_cond_code code = maybe_get_arm_condition_code (operands[1]);
7888     switch (code)
7889       {
7890       case ARM_GE:
7891       case ARM_GT:
7892       case ARM_EQ:
7893       case ARM_VS:
7894         return \"vsel%d1.f16\\t%0, %3, %4\";
7895       case ARM_LT:
7896       case ARM_LE:
7897       case ARM_NE:
7898       case ARM_VC:
7899         return \"vsel%D1.f16\\t%0, %4, %3\";
7900       default:
7901         gcc_unreachable ();
7902       }
7903     return \"\";
7904   }"
7905   [(set_attr "conds" "use")
7906    (set_attr "type" "fcsel")]
7909 (define_insn_and_split "*movsicc_insn"
7910   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r,r,r,r,r")
7911         (if_then_else:SI
7912          (match_operator 3 "arm_comparison_operator"
7913           [(match_operand 4 "cc_register" "") (const_int 0)])
7914          (match_operand:SI 1 "arm_not_operand" "0,0,rI,K,rI,rI,K,K")
7915          (match_operand:SI 2 "arm_not_operand" "rI,K,0,0,rI,K,rI,K")))]
7916   "TARGET_ARM"
7917   "@
7918    mov%D3\\t%0, %2
7919    mvn%D3\\t%0, #%B2
7920    mov%d3\\t%0, %1
7921    mvn%d3\\t%0, #%B1
7922    #
7923    #
7924    #
7925    #"
7926    ; alt4: mov%d3\\t%0, %1\;mov%D3\\t%0, %2
7927    ; alt5: mov%d3\\t%0, %1\;mvn%D3\\t%0, #%B2
7928    ; alt6: mvn%d3\\t%0, #%B1\;mov%D3\\t%0, %2
7929    ; alt7: mvn%d3\\t%0, #%B1\;mvn%D3\\t%0, #%B2"
7930   "&& reload_completed"
7931   [(const_int 0)]
7932   {
7933     enum rtx_code rev_code;
7934     machine_mode mode;
7935     rtx rev_cond;
7937     emit_insn (gen_rtx_COND_EXEC (VOIDmode,
7938                                   operands[3],
7939                                   gen_rtx_SET (operands[0], operands[1])));
7941     rev_code = GET_CODE (operands[3]);
7942     mode = GET_MODE (operands[4]);
7943     if (mode == CCFPmode || mode == CCFPEmode)
7944       rev_code = reverse_condition_maybe_unordered (rev_code);
7945     else
7946       rev_code = reverse_condition (rev_code);
7948     rev_cond = gen_rtx_fmt_ee (rev_code,
7949                                VOIDmode,
7950                                operands[4],
7951                                const0_rtx);
7952     emit_insn (gen_rtx_COND_EXEC (VOIDmode,
7953                                   rev_cond,
7954                                   gen_rtx_SET (operands[0], operands[2])));
7955     DONE;
7956   }
7957   [(set_attr "length" "4,4,4,4,8,8,8,8")
7958    (set_attr "conds" "use")
7959    (set_attr_alternative "type"
7960                          [(if_then_else (match_operand 2 "const_int_operand" "")
7961                                         (const_string "mov_imm")
7962                                         (const_string "mov_reg"))
7963                           (const_string "mvn_imm")
7964                           (if_then_else (match_operand 1 "const_int_operand" "")
7965                                         (const_string "mov_imm")
7966                                         (const_string "mov_reg"))
7967                           (const_string "mvn_imm")
7968                           (const_string "multiple")
7969                           (const_string "multiple")
7970                           (const_string "multiple")
7971                           (const_string "multiple")])]
7974 (define_insn "*movsfcc_soft_insn"
7975   [(set (match_operand:SF 0 "s_register_operand" "=r,r")
7976         (if_then_else:SF (match_operator 3 "arm_comparison_operator"
7977                           [(match_operand 4 "cc_register" "") (const_int 0)])
7978                          (match_operand:SF 1 "s_register_operand" "0,r")
7979                          (match_operand:SF 2 "s_register_operand" "r,0")))]
7980   "TARGET_ARM && TARGET_SOFT_FLOAT"
7981   "@
7982    mov%D3\\t%0, %2
7983    mov%d3\\t%0, %1"
7984   [(set_attr "conds" "use")
7985    (set_attr "type" "mov_reg")]
7989 ;; Jump and linkage insns
7991 (define_expand "jump"
7992   [(set (pc)
7993         (label_ref (match_operand 0 "" "")))]
7994   "TARGET_EITHER"
7995   ""
7998 (define_insn "*arm_jump"
7999   [(set (pc)
8000         (label_ref (match_operand 0 "" "")))]
8001   "TARGET_32BIT"
8002   "*
8003   {
8004     if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
8005       {
8006         arm_ccfsm_state += 2;
8007         return \"\";
8008       }
8009     return \"b%?\\t%l0\";
8010   }
8011   "
8012   [(set_attr "predicable" "yes")
8013    (set (attr "length")
8014         (if_then_else
8015            (and (match_test "TARGET_THUMB2")
8016                 (and (ge (minus (match_dup 0) (pc)) (const_int -2044))
8017                      (le (minus (match_dup 0) (pc)) (const_int 2048))))
8018            (const_int 2)
8019            (const_int 4)))
8020    (set_attr "type" "branch")]
8023 (define_expand "call"
8024   [(parallel [(call (match_operand 0 "memory_operand" "")
8025                     (match_operand 1 "general_operand" ""))
8026               (use (match_operand 2 "" ""))
8027               (clobber (reg:SI LR_REGNUM))])]
8028   "TARGET_EITHER"
8029   "
8030   {
8031     rtx callee, pat;
8032     tree addr = MEM_EXPR (operands[0]);
8033     
8034     /* In an untyped call, we can get NULL for operand 2.  */
8035     if (operands[2] == NULL_RTX)
8036       operands[2] = const0_rtx;
8037       
8038     /* Decide if we should generate indirect calls by loading the
8039        32-bit address of the callee into a register before performing the
8040        branch and link.  */
8041     callee = XEXP (operands[0], 0);
8042     if (GET_CODE (callee) == SYMBOL_REF
8043         ? arm_is_long_call_p (SYMBOL_REF_DECL (callee))
8044         : !REG_P (callee))
8045       XEXP (operands[0], 0) = force_reg (Pmode, callee);
8047     if (detect_cmse_nonsecure_call (addr))
8048       {
8049         pat = gen_nonsecure_call_internal (operands[0], operands[1],
8050                                            operands[2]);
8051         emit_call_insn (pat);
8052       }
8053     else
8054       {
8055         pat = gen_call_internal (operands[0], operands[1], operands[2]);
8056         arm_emit_call_insn (pat, XEXP (operands[0], 0), false);
8057       }
8058     DONE;
8059   }"
8062 (define_expand "call_internal"
8063   [(parallel [(call (match_operand 0 "memory_operand" "")
8064                     (match_operand 1 "general_operand" ""))
8065               (use (match_operand 2 "" ""))
8066               (clobber (reg:SI LR_REGNUM))])])
8068 (define_expand "nonsecure_call_internal"
8069   [(parallel [(call (unspec:SI [(match_operand 0 "memory_operand" "")]
8070                                UNSPEC_NONSECURE_MEM)
8071                     (match_operand 1 "general_operand" ""))
8072               (use (match_operand 2 "" ""))
8073               (clobber (reg:SI LR_REGNUM))])]
8074   "use_cmse"
8075   "
8076   {
8077     rtx tmp;
8078     tmp = copy_to_suggested_reg (XEXP (operands[0], 0),
8079                                  gen_rtx_REG (SImode, R4_REGNUM),
8080                                  SImode);
8082     operands[0] = replace_equiv_address (operands[0], tmp);
8083   }")
8085 (define_insn "*call_reg_armv5"
8086   [(call (mem:SI (match_operand:SI 0 "s_register_operand" "r"))
8087          (match_operand 1 "" ""))
8088    (use (match_operand 2 "" ""))
8089    (clobber (reg:SI LR_REGNUM))]
8090   "TARGET_ARM && arm_arch5t && !SIBLING_CALL_P (insn)"
8091   "blx%?\\t%0"
8092   [(set_attr "type" "call")]
8095 (define_insn "*call_reg_arm"
8096   [(call (mem:SI (match_operand:SI 0 "s_register_operand" "r"))
8097          (match_operand 1 "" ""))
8098    (use (match_operand 2 "" ""))
8099    (clobber (reg:SI LR_REGNUM))]
8100   "TARGET_ARM && !arm_arch5t && !SIBLING_CALL_P (insn)"
8101   "*
8102   return output_call (operands);
8103   "
8104   ;; length is worst case, normally it is only two
8105   [(set_attr "length" "12")
8106    (set_attr "type" "call")]
8110 (define_expand "call_value"
8111   [(parallel [(set (match_operand       0 "" "")
8112                    (call (match_operand 1 "memory_operand" "")
8113                          (match_operand 2 "general_operand" "")))
8114               (use (match_operand 3 "" ""))
8115               (clobber (reg:SI LR_REGNUM))])]
8116   "TARGET_EITHER"
8117   "
8118   {
8119     rtx pat, callee;
8120     tree addr = MEM_EXPR (operands[1]);
8121     
8122     /* In an untyped call, we can get NULL for operand 2.  */
8123     if (operands[3] == 0)
8124       operands[3] = const0_rtx;
8125       
8126     /* Decide if we should generate indirect calls by loading the
8127        32-bit address of the callee into a register before performing the
8128        branch and link.  */
8129     callee = XEXP (operands[1], 0);
8130     if (GET_CODE (callee) == SYMBOL_REF
8131         ? arm_is_long_call_p (SYMBOL_REF_DECL (callee))
8132         : !REG_P (callee))
8133       XEXP (operands[1], 0) = force_reg (Pmode, callee);
8135     if (detect_cmse_nonsecure_call (addr))
8136       {
8137         pat = gen_nonsecure_call_value_internal (operands[0], operands[1],
8138                                                  operands[2], operands[3]);
8139         emit_call_insn (pat);
8140       }
8141     else
8142       {
8143         pat = gen_call_value_internal (operands[0], operands[1],
8144                                        operands[2], operands[3]);
8145         arm_emit_call_insn (pat, XEXP (operands[1], 0), false);
8146       }
8147     DONE;
8148   }"
8151 (define_expand "call_value_internal"
8152   [(parallel [(set (match_operand       0 "" "")
8153                    (call (match_operand 1 "memory_operand" "")
8154                          (match_operand 2 "general_operand" "")))
8155               (use (match_operand 3 "" ""))
8156               (clobber (reg:SI LR_REGNUM))])])
8158 (define_expand "nonsecure_call_value_internal"
8159   [(parallel [(set (match_operand       0 "" "")
8160                    (call (unspec:SI [(match_operand 1 "memory_operand" "")]
8161                                     UNSPEC_NONSECURE_MEM)
8162                          (match_operand 2 "general_operand" "")))
8163               (use (match_operand 3 "" ""))
8164               (clobber (reg:SI LR_REGNUM))])]
8165   "use_cmse"
8166   "
8167   {
8168     rtx tmp;
8169     tmp = copy_to_suggested_reg (XEXP (operands[1], 0),
8170                                  gen_rtx_REG (SImode, R4_REGNUM),
8171                                  SImode);
8173     operands[1] = replace_equiv_address (operands[1], tmp);
8174   }")
8176 (define_insn "*call_value_reg_armv5"
8177   [(set (match_operand 0 "" "")
8178         (call (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
8179               (match_operand 2 "" "")))
8180    (use (match_operand 3 "" ""))
8181    (clobber (reg:SI LR_REGNUM))]
8182   "TARGET_ARM && arm_arch5t && !SIBLING_CALL_P (insn)"
8183   "blx%?\\t%1"
8184   [(set_attr "type" "call")]
8187 (define_insn "*call_value_reg_arm"
8188   [(set (match_operand 0 "" "")
8189         (call (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
8190               (match_operand 2 "" "")))
8191    (use (match_operand 3 "" ""))
8192    (clobber (reg:SI LR_REGNUM))]
8193   "TARGET_ARM && !arm_arch5t && !SIBLING_CALL_P (insn)"
8194   "*
8195   return output_call (&operands[1]);
8196   "
8197   [(set_attr "length" "12")
8198    (set_attr "type" "call")]
8201 ;; Allow calls to SYMBOL_REFs specially as they are not valid general addresses
8202 ;; The 'a' causes the operand to be treated as an address, i.e. no '#' output.
8204 (define_insn "*call_symbol"
8205   [(call (mem:SI (match_operand:SI 0 "" ""))
8206          (match_operand 1 "" ""))
8207    (use (match_operand 2 "" ""))
8208    (clobber (reg:SI LR_REGNUM))]
8209   "TARGET_32BIT
8210    && !SIBLING_CALL_P (insn)
8211    && (GET_CODE (operands[0]) == SYMBOL_REF)
8212    && !arm_is_long_call_p (SYMBOL_REF_DECL (operands[0]))"
8213   "*
8214   {
8215    rtx op = operands[0];
8217    /* Switch mode now when possible.  */
8218    if (SYMBOL_REF_DECL (op) && !TREE_PUBLIC (SYMBOL_REF_DECL (op))
8219         && arm_arch5t && arm_change_mode_p (SYMBOL_REF_DECL (op)))
8220       return NEED_PLT_RELOC ? \"blx%?\\t%a0(PLT)\" : \"blx%?\\t(%a0)\";
8222     return NEED_PLT_RELOC ? \"bl%?\\t%a0(PLT)\" : \"bl%?\\t%a0\";
8223   }"
8224   [(set_attr "type" "call")]
8227 (define_insn "*call_value_symbol"
8228   [(set (match_operand 0 "" "")
8229         (call (mem:SI (match_operand:SI 1 "" ""))
8230         (match_operand:SI 2 "" "")))
8231    (use (match_operand 3 "" ""))
8232    (clobber (reg:SI LR_REGNUM))]
8233   "TARGET_32BIT
8234    && !SIBLING_CALL_P (insn)
8235    && (GET_CODE (operands[1]) == SYMBOL_REF)
8236    && !arm_is_long_call_p (SYMBOL_REF_DECL (operands[1]))"
8237   "*
8238   {
8239    rtx op = operands[1];
8241    /* Switch mode now when possible.  */
8242    if (SYMBOL_REF_DECL (op) && !TREE_PUBLIC (SYMBOL_REF_DECL (op))
8243         && arm_arch5t && arm_change_mode_p (SYMBOL_REF_DECL (op)))
8244       return NEED_PLT_RELOC ? \"blx%?\\t%a1(PLT)\" : \"blx%?\\t(%a1)\";
8246     return NEED_PLT_RELOC ? \"bl%?\\t%a1(PLT)\" : \"bl%?\\t%a1\";
8247   }"
8248   [(set_attr "type" "call")]
8251 (define_expand "sibcall_internal"
8252   [(parallel [(call (match_operand 0 "memory_operand" "")
8253                     (match_operand 1 "general_operand" ""))
8254               (return)
8255               (use (match_operand 2 "" ""))])])
8257 ;; We may also be able to do sibcalls for Thumb, but it's much harder...
8258 (define_expand "sibcall"
8259   [(parallel [(call (match_operand 0 "memory_operand" "")
8260                     (match_operand 1 "general_operand" ""))
8261               (return)
8262               (use (match_operand 2 "" ""))])]
8263   "TARGET_32BIT"
8264   "
8265   {
8266     rtx pat;
8268     if ((!REG_P (XEXP (operands[0], 0))
8269          && GET_CODE (XEXP (operands[0], 0)) != SYMBOL_REF)
8270         || (GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
8271             && arm_is_long_call_p (SYMBOL_REF_DECL (XEXP (operands[0], 0)))))
8272      XEXP (operands[0], 0) = force_reg (SImode, XEXP (operands[0], 0));
8274     if (operands[2] == NULL_RTX)
8275       operands[2] = const0_rtx;
8277     pat = gen_sibcall_internal (operands[0], operands[1], operands[2]);
8278     arm_emit_call_insn (pat, operands[0], true);
8279     DONE;
8280   }"
8283 (define_expand "sibcall_value_internal"
8284   [(parallel [(set (match_operand 0 "" "")
8285                    (call (match_operand 1 "memory_operand" "")
8286                          (match_operand 2 "general_operand" "")))
8287               (return)
8288               (use (match_operand 3 "" ""))])])
8290 (define_expand "sibcall_value"
8291   [(parallel [(set (match_operand 0 "" "")
8292                    (call (match_operand 1 "memory_operand" "")
8293                          (match_operand 2 "general_operand" "")))
8294               (return)
8295               (use (match_operand 3 "" ""))])]
8296   "TARGET_32BIT"
8297   "
8298   {
8299     rtx pat;
8301     if ((!REG_P (XEXP (operands[1], 0))
8302          && GET_CODE (XEXP (operands[1], 0)) != SYMBOL_REF)
8303         || (GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
8304             && arm_is_long_call_p (SYMBOL_REF_DECL (XEXP (operands[1], 0)))))
8305      XEXP (operands[1], 0) = force_reg (SImode, XEXP (operands[1], 0));
8307     if (operands[3] == NULL_RTX)
8308       operands[3] = const0_rtx;
8310     pat = gen_sibcall_value_internal (operands[0], operands[1],
8311                                       operands[2], operands[3]);
8312     arm_emit_call_insn (pat, operands[1], true);
8313     DONE;
8314   }"
8317 (define_insn "*sibcall_insn"
8318  [(call (mem:SI (match_operand:SI 0 "call_insn_operand" "Cs, US"))
8319         (match_operand 1 "" ""))
8320   (return)
8321   (use (match_operand 2 "" ""))]
8322   "TARGET_32BIT && SIBLING_CALL_P (insn)"
8323   "*
8324   if (which_alternative == 1)
8325     return NEED_PLT_RELOC ? \"b%?\\t%a0(PLT)\" : \"b%?\\t%a0\";
8326   else
8327     {
8328       if (arm_arch5t || arm_arch4t)
8329         return \"bx%?\\t%0\\t%@ indirect register sibling call\";
8330       else
8331         return \"mov%?\\t%|pc, %0\\t%@ indirect register sibling call\";
8332     }
8333   "
8334   [(set_attr "type" "call")]
8337 (define_insn "*sibcall_value_insn"
8338  [(set (match_operand 0 "" "")
8339        (call (mem:SI (match_operand:SI 1 "call_insn_operand" "Cs,US"))
8340              (match_operand 2 "" "")))
8341   (return)
8342   (use (match_operand 3 "" ""))]
8343   "TARGET_32BIT && SIBLING_CALL_P (insn)"
8344   "*
8345   if (which_alternative == 1)
8346    return NEED_PLT_RELOC ? \"b%?\\t%a1(PLT)\" : \"b%?\\t%a1\";
8347   else
8348     {
8349       if (arm_arch5t || arm_arch4t)
8350         return \"bx%?\\t%1\";
8351       else
8352         return \"mov%?\\t%|pc, %1\\t@ indirect sibling call \";
8353     }
8354   "
8355   [(set_attr "type" "call")]
8358 (define_expand "<return_str>return"
8359   [(RETURNS)]
8360   "(TARGET_ARM || (TARGET_THUMB2
8361                    && ARM_FUNC_TYPE (arm_current_func_type ()) == ARM_FT_NORMAL
8362                    && !IS_STACKALIGN (arm_current_func_type ())))
8363     <return_cond_false>"
8364   "
8365   {
8366     if (TARGET_THUMB2)
8367       {
8368         thumb2_expand_return (<return_simple_p>);
8369         DONE;
8370       }
8371   }
8372   "
8375 ;; Often the return insn will be the same as loading from memory, so set attr
8376 (define_insn "*arm_return"
8377   [(return)]
8378   "TARGET_ARM && USE_RETURN_INSN (FALSE)"
8379   "*
8380   {
8381     if (arm_ccfsm_state == 2)
8382       {
8383         arm_ccfsm_state += 2;
8384         return \"\";
8385       }
8386     return output_return_instruction (const_true_rtx, true, false, false);
8387   }"
8388   [(set_attr "type" "load_4")
8389    (set_attr "length" "12")
8390    (set_attr "predicable" "yes")]
8393 (define_insn "*cond_<return_str>return"
8394   [(set (pc)
8395         (if_then_else (match_operator 0 "arm_comparison_operator"
8396                        [(match_operand 1 "cc_register" "") (const_int 0)])
8397                       (RETURNS)
8398                       (pc)))]
8399   "TARGET_ARM  <return_cond_true>"
8400   "*
8401   {
8402     if (arm_ccfsm_state == 2)
8403       {
8404         arm_ccfsm_state += 2;
8405         return \"\";
8406       }
8407     return output_return_instruction (operands[0], true, false,
8408                                       <return_simple_p>);
8409   }"
8410   [(set_attr "conds" "use")
8411    (set_attr "length" "12")
8412    (set_attr "type" "load_4")]
8415 (define_insn "*cond_<return_str>return_inverted"
8416   [(set (pc)
8417         (if_then_else (match_operator 0 "arm_comparison_operator"
8418                        [(match_operand 1 "cc_register" "") (const_int 0)])
8419                       (pc)
8420                       (RETURNS)))]
8421   "TARGET_ARM <return_cond_true>"
8422   "*
8423   {
8424     if (arm_ccfsm_state == 2)
8425       {
8426         arm_ccfsm_state += 2;
8427         return \"\";
8428       }
8429     return output_return_instruction (operands[0], true, true,
8430                                       <return_simple_p>);
8431   }"
8432   [(set_attr "conds" "use")
8433    (set_attr "length" "12")
8434    (set_attr "type" "load_4")]
8437 (define_insn "*arm_simple_return"
8438   [(simple_return)]
8439   "TARGET_ARM"
8440   "*
8441   {
8442     if (arm_ccfsm_state == 2)
8443       {
8444         arm_ccfsm_state += 2;
8445         return \"\";
8446       }
8447     return output_return_instruction (const_true_rtx, true, false, true);
8448   }"
8449   [(set_attr "type" "branch")
8450    (set_attr "length" "4")
8451    (set_attr "predicable" "yes")]
8454 ;; Generate a sequence of instructions to determine if the processor is
8455 ;; in 26-bit or 32-bit mode, and return the appropriate return address
8456 ;; mask.
8458 (define_expand "return_addr_mask"
8459   [(set (match_dup 1)
8460       (compare:CC_NOOV (unspec [(const_int 0)] UNSPEC_CHECK_ARCH)
8461                        (const_int 0)))
8462    (set (match_operand:SI 0 "s_register_operand" "")
8463       (if_then_else:SI (eq (match_dup 1) (const_int 0))
8464                        (const_int -1)
8465                        (const_int 67108860)))] ; 0x03fffffc
8466   "TARGET_ARM"
8467   "
8468   operands[1] = gen_rtx_REG (CC_NOOVmode, CC_REGNUM);
8469   ")
8471 (define_insn "*check_arch2"
8472   [(set (match_operand:CC_NOOV 0 "cc_register" "")
8473       (compare:CC_NOOV (unspec [(const_int 0)] UNSPEC_CHECK_ARCH)
8474                        (const_int 0)))]
8475   "TARGET_ARM"
8476   "teq\\t%|r0, %|r0\;teq\\t%|pc, %|pc"
8477   [(set_attr "length" "8")
8478    (set_attr "conds" "set")
8479    (set_attr "type" "multiple")]
8482 ;; Call subroutine returning any type.
8484 (define_expand "untyped_call"
8485   [(parallel [(call (match_operand 0 "" "")
8486                     (const_int 0))
8487               (match_operand 1 "" "")
8488               (match_operand 2 "" "")])]
8489   "TARGET_EITHER"
8490   "
8491   {
8492     int i;
8493     rtx par = gen_rtx_PARALLEL (VOIDmode,
8494                                 rtvec_alloc (XVECLEN (operands[2], 0)));
8495     rtx addr = gen_reg_rtx (Pmode);
8496     rtx mem;
8497     int size = 0;
8499     emit_move_insn (addr, XEXP (operands[1], 0));
8500     mem = change_address (operands[1], BLKmode, addr);
8502     for (i = 0; i < XVECLEN (operands[2], 0); i++)
8503       {
8504         rtx src = SET_SRC (XVECEXP (operands[2], 0, i));
8506         /* Default code only uses r0 as a return value, but we could
8507            be using anything up to 4 registers.  */
8508         if (REGNO (src) == R0_REGNUM)
8509           src = gen_rtx_REG (TImode, R0_REGNUM);
8511         XVECEXP (par, 0, i) = gen_rtx_EXPR_LIST (VOIDmode, src,
8512                                                  GEN_INT (size));
8513         size += GET_MODE_SIZE (GET_MODE (src));
8514       }
8516     emit_call_insn (gen_call_value (par, operands[0], const0_rtx, NULL));
8518     size = 0;
8520     for (i = 0; i < XVECLEN (par, 0); i++)
8521       {
8522         HOST_WIDE_INT offset = 0;
8523         rtx reg = XEXP (XVECEXP (par, 0, i), 0);
8525         if (size != 0)
8526           emit_move_insn (addr, plus_constant (Pmode, addr, size));
8528         mem = change_address (mem, GET_MODE (reg), NULL);
8529         if (REGNO (reg) == R0_REGNUM)
8530           {
8531             /* On thumb we have to use a write-back instruction.  */
8532             emit_insn (arm_gen_store_multiple (arm_regs_in_sequence, 4, addr,
8533                        TARGET_THUMB ? TRUE : FALSE, mem, &offset));
8534             size = TARGET_ARM ? 16 : 0;
8535           }
8536         else
8537           {
8538             emit_move_insn (mem, reg);
8539             size = GET_MODE_SIZE (GET_MODE (reg));
8540           }
8541       }
8543     /* The optimizer does not know that the call sets the function value
8544        registers we stored in the result block.  We avoid problems by
8545        claiming that all hard registers are used and clobbered at this
8546        point.  */
8547     emit_insn (gen_blockage ());
8549     DONE;
8550   }"
8553 (define_expand "untyped_return"
8554   [(match_operand:BLK 0 "memory_operand" "")
8555    (match_operand 1 "" "")]
8556   "TARGET_EITHER"
8557   "
8558   {
8559     int i;
8560     rtx addr = gen_reg_rtx (Pmode);
8561     rtx mem;
8562     int size = 0;
8564     emit_move_insn (addr, XEXP (operands[0], 0));
8565     mem = change_address (operands[0], BLKmode, addr);
8567     for (i = 0; i < XVECLEN (operands[1], 0); i++)
8568       {
8569         HOST_WIDE_INT offset = 0;
8570         rtx reg = SET_DEST (XVECEXP (operands[1], 0, i));
8572         if (size != 0)
8573           emit_move_insn (addr, plus_constant (Pmode, addr, size));
8575         mem = change_address (mem, GET_MODE (reg), NULL);
8576         if (REGNO (reg) == R0_REGNUM)
8577           {
8578             /* On thumb we have to use a write-back instruction.  */
8579             emit_insn (arm_gen_load_multiple (arm_regs_in_sequence, 4, addr,
8580                        TARGET_THUMB ? TRUE : FALSE, mem, &offset));
8581             size = TARGET_ARM ? 16 : 0;
8582           }
8583         else
8584           {
8585             emit_move_insn (reg, mem);
8586             size = GET_MODE_SIZE (GET_MODE (reg));
8587           }
8588       }
8590     /* Emit USE insns before the return.  */
8591     for (i = 0; i < XVECLEN (operands[1], 0); i++)
8592       emit_use (SET_DEST (XVECEXP (operands[1], 0, i)));
8594     /* Construct the return.  */
8595     expand_naked_return ();
8597     DONE;
8598   }"
8601 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
8602 ;; all of memory.  This blocks insns from being moved across this point.
8604 (define_insn "blockage"
8605   [(unspec_volatile [(const_int 0)] VUNSPEC_BLOCKAGE)]
8606   "TARGET_EITHER"
8607   ""
8608   [(set_attr "length" "0")
8609    (set_attr "type" "block")]
8612 ;; Since we hard code r0 here use the 'o' constraint to prevent
8613 ;; provoking undefined behaviour in the hardware with putting out
8614 ;; auto-increment operations with potentially r0 as the base register.
8615 (define_insn "probe_stack"
8616   [(set (match_operand:SI 0 "memory_operand" "=o")
8617         (unspec:SI [(const_int 0)] UNSPEC_PROBE_STACK))]
8618   "TARGET_32BIT"
8619   "str%?\\tr0, %0"
8620   [(set_attr "type" "store_4")
8621    (set_attr "predicable" "yes")]
8624 (define_insn "probe_stack_range"
8625   [(set (match_operand:SI 0 "register_operand" "=r")
8626         (unspec_volatile:SI [(match_operand:SI 1 "register_operand" "0")
8627                              (match_operand:SI 2 "register_operand" "r")]
8628                              VUNSPEC_PROBE_STACK_RANGE))]
8629   "TARGET_32BIT"
8631   return output_probe_stack_range (operands[0], operands[2]);
8633   [(set_attr "type" "multiple")
8634    (set_attr "conds" "clob")]
8637 (define_expand "casesi"
8638   [(match_operand:SI 0 "s_register_operand" "") ; index to jump on
8639    (match_operand:SI 1 "const_int_operand" "")  ; lower bound
8640    (match_operand:SI 2 "const_int_operand" "")  ; total range
8641    (match_operand:SI 3 "" "")                   ; table label
8642    (match_operand:SI 4 "" "")]                  ; Out of range label
8643   "(TARGET_32BIT || optimize_size || flag_pic) && !target_pure_code"
8644   "
8645   {
8646     enum insn_code code;
8647     if (operands[1] != const0_rtx)
8648       {
8649         rtx reg = gen_reg_rtx (SImode);
8651         emit_insn (gen_addsi3 (reg, operands[0],
8652                                gen_int_mode (-INTVAL (operands[1]),
8653                                              SImode)));
8654         operands[0] = reg;
8655       }
8657     if (TARGET_ARM)
8658       code = CODE_FOR_arm_casesi_internal;
8659     else if (TARGET_THUMB1)
8660       code = CODE_FOR_thumb1_casesi_internal_pic;
8661     else if (flag_pic)
8662       code = CODE_FOR_thumb2_casesi_internal_pic;
8663     else
8664       code = CODE_FOR_thumb2_casesi_internal;
8666     if (!insn_data[(int) code].operand[1].predicate(operands[2], SImode))
8667       operands[2] = force_reg (SImode, operands[2]);
8669     emit_jump_insn (GEN_FCN ((int) code) (operands[0], operands[2],
8670                                           operands[3], operands[4]));
8671     DONE;
8672   }"
8675 ;; The USE in this pattern is needed to tell flow analysis that this is
8676 ;; a CASESI insn.  It has no other purpose.
8677 (define_insn "arm_casesi_internal"
8678   [(parallel [(set (pc)
8679                (if_then_else
8680                 (leu (match_operand:SI 0 "s_register_operand" "r")
8681                      (match_operand:SI 1 "arm_rhs_operand" "rI"))
8682                 (mem:SI (plus:SI (mult:SI (match_dup 0) (const_int 4))
8683                                  (label_ref (match_operand 2 "" ""))))
8684                 (label_ref (match_operand 3 "" ""))))
8685               (clobber (reg:CC CC_REGNUM))
8686               (use (label_ref (match_dup 2)))])]
8687   "TARGET_ARM"
8688   "*
8689     if (flag_pic)
8690       return \"cmp\\t%0, %1\;addls\\t%|pc, %|pc, %0, asl #2\;b\\t%l3\";
8691     return   \"cmp\\t%0, %1\;ldrls\\t%|pc, [%|pc, %0, asl #2]\;b\\t%l3\";
8692   "
8693   [(set_attr "conds" "clob")
8694    (set_attr "length" "12")
8695    (set_attr "type" "multiple")]
8698 (define_expand "indirect_jump"
8699   [(set (pc)
8700         (match_operand:SI 0 "s_register_operand" ""))]
8701   "TARGET_EITHER"
8702   "
8703   /* Thumb-2 doesn't have mov pc, reg.  Explicitly set the low bit of the
8704      address and use bx.  */
8705   if (TARGET_THUMB2)
8706     {
8707       rtx tmp;
8708       tmp = gen_reg_rtx (SImode);
8709       emit_insn (gen_iorsi3 (tmp, operands[0], GEN_INT(1)));
8710       operands[0] = tmp;
8711     }
8712   "
8715 ;; NB Never uses BX.
8716 (define_insn "*arm_indirect_jump"
8717   [(set (pc)
8718         (match_operand:SI 0 "s_register_operand" "r"))]
8719   "TARGET_ARM"
8720   "mov%?\\t%|pc, %0\\t%@ indirect register jump"
8721   [(set_attr "predicable" "yes")
8722    (set_attr "type" "branch")]
8725 (define_insn "*load_indirect_jump"
8726   [(set (pc)
8727         (match_operand:SI 0 "memory_operand" "m"))]
8728   "TARGET_ARM"
8729   "ldr%?\\t%|pc, %0\\t%@ indirect memory jump"
8730   [(set_attr "type" "load_4")
8731    (set_attr "pool_range" "4096")
8732    (set_attr "neg_pool_range" "4084")
8733    (set_attr "predicable" "yes")]
8737 ;; Misc insns
8739 (define_insn "nop"
8740   [(const_int 0)]
8741   "TARGET_EITHER"
8742   "nop"
8743   [(set (attr "length")
8744         (if_then_else (eq_attr "is_thumb" "yes")
8745                       (const_int 2)
8746                       (const_int 4)))
8747    (set_attr "type" "mov_reg")]
8750 (define_insn "trap"
8751   [(trap_if (const_int 1) (const_int 0))]
8752   ""
8753   "*
8754   if (TARGET_ARM)
8755     return \".inst\\t0xe7f000f0\";
8756   else
8757     return \".inst\\t0xdeff\";
8758   "
8759   [(set (attr "length")
8760         (if_then_else (eq_attr "is_thumb" "yes")
8761                       (const_int 2)
8762                       (const_int 4)))
8763    (set_attr "type" "trap")
8764    (set_attr "conds" "unconditional")]
8768 ;; Patterns to allow combination of arithmetic, cond code and shifts
8770 (define_insn "*<arith_shift_insn>_multsi"
8771   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8772         (SHIFTABLE_OPS:SI
8773          (mult:SI (match_operand:SI 2 "s_register_operand" "r,r")
8774                   (match_operand:SI 3 "power_of_two_operand" ""))
8775          (match_operand:SI 1 "s_register_operand" "rk,<t2_binop0>")))]
8776   "TARGET_32BIT"
8777   "<arith_shift_insn>%?\\t%0, %1, %2, lsl %b3"
8778   [(set_attr "predicable" "yes")
8779    (set_attr "shift" "2")
8780    (set_attr "arch" "a,t2")
8781    (set_attr "type" "alu_shift_imm")])
8783 (define_insn "*<arith_shift_insn>_shiftsi"
8784   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
8785         (SHIFTABLE_OPS:SI
8786          (match_operator:SI 2 "shift_nomul_operator"
8787           [(match_operand:SI 3 "s_register_operand" "r,r,r")
8788            (match_operand:SI 4 "shift_amount_operand" "M,M,r")])
8789          (match_operand:SI 1 "s_register_operand" "rk,<t2_binop0>,rk")))]
8790   "TARGET_32BIT && GET_CODE (operands[2]) != MULT"
8791   "<arith_shift_insn>%?\\t%0, %1, %3%S2"
8792   [(set_attr "predicable" "yes")
8793    (set_attr "shift" "3")
8794    (set_attr "arch" "a,t2,a")
8795    (set_attr "type" "alu_shift_imm,alu_shift_imm,alu_shift_reg")])
8797 (define_split
8798   [(set (match_operand:SI 0 "s_register_operand" "")
8799         (match_operator:SI 1 "shiftable_operator"
8800          [(match_operator:SI 2 "shiftable_operator"
8801            [(match_operator:SI 3 "shift_operator"
8802              [(match_operand:SI 4 "s_register_operand" "")
8803               (match_operand:SI 5 "reg_or_int_operand" "")])
8804             (match_operand:SI 6 "s_register_operand" "")])
8805           (match_operand:SI 7 "arm_rhs_operand" "")]))
8806    (clobber (match_operand:SI 8 "s_register_operand" ""))]
8807   "TARGET_32BIT"
8808   [(set (match_dup 8)
8809         (match_op_dup 2 [(match_op_dup 3 [(match_dup 4) (match_dup 5)])
8810                          (match_dup 6)]))
8811    (set (match_dup 0)
8812         (match_op_dup 1 [(match_dup 8) (match_dup 7)]))]
8813   "")
8815 (define_insn "*arith_shiftsi_compare0"
8816   [(set (reg:CC_NOOV CC_REGNUM)
8817         (compare:CC_NOOV
8818          (match_operator:SI 1 "shiftable_operator"
8819           [(match_operator:SI 3 "shift_operator"
8820             [(match_operand:SI 4 "s_register_operand" "r,r")
8821              (match_operand:SI 5 "shift_amount_operand" "M,r")])
8822            (match_operand:SI 2 "s_register_operand" "r,r")])
8823          (const_int 0)))
8824    (set (match_operand:SI 0 "s_register_operand" "=r,r")
8825         (match_op_dup 1 [(match_op_dup 3 [(match_dup 4) (match_dup 5)])
8826                          (match_dup 2)]))]
8827   "TARGET_32BIT"
8828   "%i1s%?\\t%0, %2, %4%S3"
8829   [(set_attr "conds" "set")
8830    (set_attr "shift" "4")
8831    (set_attr "arch" "32,a")
8832    (set_attr "type" "alus_shift_imm,alus_shift_reg")])
8834 (define_insn "*arith_shiftsi_compare0_scratch"
8835   [(set (reg:CC_NOOV CC_REGNUM)
8836         (compare:CC_NOOV
8837          (match_operator:SI 1 "shiftable_operator"
8838           [(match_operator:SI 3 "shift_operator"
8839             [(match_operand:SI 4 "s_register_operand" "r,r")
8840              (match_operand:SI 5 "shift_amount_operand" "M,r")])
8841            (match_operand:SI 2 "s_register_operand" "r,r")])
8842          (const_int 0)))
8843    (clobber (match_scratch:SI 0 "=r,r"))]
8844   "TARGET_32BIT"
8845   "%i1s%?\\t%0, %2, %4%S3"
8846   [(set_attr "conds" "set")
8847    (set_attr "shift" "4")
8848    (set_attr "arch" "32,a")
8849    (set_attr "type" "alus_shift_imm,alus_shift_reg")])
8851 (define_insn "*sub_shiftsi"
8852   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8853         (minus:SI (match_operand:SI 1 "s_register_operand" "r,r")
8854                   (match_operator:SI 2 "shift_operator"
8855                    [(match_operand:SI 3 "s_register_operand" "r,r")
8856                     (match_operand:SI 4 "shift_amount_operand" "M,r")])))]
8857   "TARGET_32BIT"
8858   "sub%?\\t%0, %1, %3%S2"
8859   [(set_attr "predicable" "yes")
8860    (set_attr "predicable_short_it" "no")
8861    (set_attr "shift" "3")
8862    (set_attr "arch" "32,a")
8863    (set_attr "type" "alus_shift_imm,alus_shift_reg")])
8865 (define_insn "*sub_shiftsi_compare0"
8866   [(set (reg:CC_NOOV CC_REGNUM)
8867         (compare:CC_NOOV
8868          (minus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
8869                    (match_operator:SI 2 "shift_operator"
8870                     [(match_operand:SI 3 "s_register_operand" "r,r,r")
8871                      (match_operand:SI 4 "shift_amount_operand" "M,r,M")]))
8872          (const_int 0)))
8873    (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
8874         (minus:SI (match_dup 1)
8875                   (match_op_dup 2 [(match_dup 3) (match_dup 4)])))]
8876   "TARGET_32BIT"
8877   "subs%?\\t%0, %1, %3%S2"
8878   [(set_attr "conds" "set")
8879    (set_attr "shift" "3")
8880    (set_attr "arch" "32,a,a")
8881    (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
8883 (define_insn "*sub_shiftsi_compare0_scratch"
8884   [(set (reg:CC_NOOV CC_REGNUM)
8885         (compare:CC_NOOV
8886          (minus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
8887                    (match_operator:SI 2 "shift_operator"
8888                     [(match_operand:SI 3 "s_register_operand" "r,r,r")
8889                      (match_operand:SI 4 "shift_amount_operand" "M,r,M")]))
8890          (const_int 0)))
8891    (clobber (match_scratch:SI 0 "=r,r,r"))]
8892   "TARGET_32BIT"
8893   "subs%?\\t%0, %1, %3%S2"
8894   [(set_attr "conds" "set")
8895    (set_attr "shift" "3")
8896    (set_attr "arch" "32,a,a")
8897    (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
8900 (define_insn_and_split "*and_scc"
8901   [(set (match_operand:SI 0 "s_register_operand" "=r")
8902         (and:SI (match_operator:SI 1 "arm_comparison_operator"
8903                  [(match_operand 2 "cc_register" "") (const_int 0)])
8904                 (match_operand:SI 3 "s_register_operand" "r")))]
8905   "TARGET_ARM"
8906   "#"   ; "mov%D1\\t%0, #0\;and%d1\\t%0, %3, #1"
8907   "&& reload_completed"
8908   [(cond_exec (match_dup 5) (set (match_dup 0) (const_int 0)))
8909    (cond_exec (match_dup 4) (set (match_dup 0)
8910                                  (and:SI (match_dup 3) (const_int 1))))]
8911   {
8912     machine_mode mode = GET_MODE (operands[2]);
8913     enum rtx_code rc = GET_CODE (operands[1]);
8915     /* Note that operands[4] is the same as operands[1],
8916        but with VOIDmode as the result. */
8917     operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
8918     if (mode == CCFPmode || mode == CCFPEmode)
8919       rc = reverse_condition_maybe_unordered (rc);
8920     else
8921       rc = reverse_condition (rc);
8922     operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
8923   }
8924   [(set_attr "conds" "use")
8925    (set_attr "type" "multiple")
8926    (set_attr "length" "8")]
8929 (define_insn_and_split "*ior_scc"
8930   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8931         (ior:SI (match_operator:SI 1 "arm_comparison_operator"
8932                  [(match_operand 2 "cc_register" "") (const_int 0)])
8933                 (match_operand:SI 3 "s_register_operand" "0,?r")))]
8934   "TARGET_ARM"
8935   "@
8936    orr%d1\\t%0, %3, #1
8937    #"
8938   "&& reload_completed
8939    && REGNO (operands [0]) != REGNO (operands[3])"
8940   ;; && which_alternative == 1
8941   ; mov%D1\\t%0, %3\;orr%d1\\t%0, %3, #1
8942   [(cond_exec (match_dup 5) (set (match_dup 0) (match_dup 3)))
8943    (cond_exec (match_dup 4) (set (match_dup 0)
8944                                  (ior:SI (match_dup 3) (const_int 1))))]
8945   {
8946     machine_mode mode = GET_MODE (operands[2]);
8947     enum rtx_code rc = GET_CODE (operands[1]);
8949     /* Note that operands[4] is the same as operands[1],
8950        but with VOIDmode as the result. */
8951     operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
8952     if (mode == CCFPmode || mode == CCFPEmode)
8953       rc = reverse_condition_maybe_unordered (rc);
8954     else
8955       rc = reverse_condition (rc);
8956     operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
8957   }
8958   [(set_attr "conds" "use")
8959    (set_attr "length" "4,8")
8960    (set_attr "type" "logic_imm,multiple")]
8963 ; A series of splitters for the compare_scc pattern below.  Note that
8964 ; order is important.
8965 (define_split
8966   [(set (match_operand:SI 0 "s_register_operand" "")
8967         (lt:SI (match_operand:SI 1 "s_register_operand" "")
8968                (const_int 0)))
8969    (clobber (reg:CC CC_REGNUM))]
8970   "TARGET_32BIT && reload_completed"
8971   [(set (match_dup 0) (lshiftrt:SI (match_dup 1) (const_int 31)))])
8973 (define_split
8974   [(set (match_operand:SI 0 "s_register_operand" "")
8975         (ge:SI (match_operand:SI 1 "s_register_operand" "")
8976                (const_int 0)))
8977    (clobber (reg:CC CC_REGNUM))]
8978   "TARGET_32BIT && reload_completed"
8979   [(set (match_dup 0) (not:SI (match_dup 1)))
8980    (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 31)))])
8982 (define_split
8983   [(set (match_operand:SI 0 "s_register_operand" "")
8984         (eq:SI (match_operand:SI 1 "s_register_operand" "")
8985                (const_int 0)))
8986    (clobber (reg:CC CC_REGNUM))]
8987   "arm_arch5t && TARGET_32BIT"
8988   [(set (match_dup 0) (clz:SI (match_dup 1)))
8989    (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
8992 (define_split
8993   [(set (match_operand:SI 0 "s_register_operand" "")
8994         (eq:SI (match_operand:SI 1 "s_register_operand" "")
8995                (const_int 0)))
8996    (clobber (reg:CC CC_REGNUM))]
8997   "TARGET_32BIT && reload_completed"
8998   [(parallel
8999     [(set (reg:CC CC_REGNUM)
9000           (compare:CC (const_int 1) (match_dup 1)))
9001      (set (match_dup 0)
9002           (minus:SI (const_int 1) (match_dup 1)))])
9003    (cond_exec (ltu:CC (reg:CC CC_REGNUM) (const_int 0))
9004               (set (match_dup 0) (const_int 0)))])
9006 (define_split
9007   [(set (match_operand:SI 0 "s_register_operand" "")
9008         (ne:SI (match_operand:SI 1 "s_register_operand" "")
9009                (match_operand:SI 2 "const_int_operand" "")))
9010    (clobber (reg:CC CC_REGNUM))]
9011   "TARGET_32BIT && reload_completed"
9012   [(parallel
9013     [(set (reg:CC CC_REGNUM)
9014           (compare:CC (match_dup 1) (match_dup 2)))
9015      (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 3)))])
9016    (cond_exec (ne:CC (reg:CC CC_REGNUM) (const_int 0))
9017               (set (match_dup 0) (const_int 1)))]
9019   operands[3] = GEN_INT (-INTVAL (operands[2]));
9022 (define_split
9023   [(set (match_operand:SI 0 "s_register_operand" "")
9024         (ne:SI (match_operand:SI 1 "s_register_operand" "")
9025                (match_operand:SI 2 "arm_add_operand" "")))
9026    (clobber (reg:CC CC_REGNUM))]
9027   "TARGET_32BIT && reload_completed"
9028   [(parallel
9029     [(set (reg:CC_NOOV CC_REGNUM)
9030           (compare:CC_NOOV (minus:SI (match_dup 1) (match_dup 2))
9031                            (const_int 0)))
9032      (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
9033    (cond_exec (ne:CC_NOOV (reg:CC_NOOV CC_REGNUM) (const_int 0))
9034               (set (match_dup 0) (const_int 1)))])
9036 (define_insn_and_split "*compare_scc"
9037   [(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts")
9038         (match_operator:SI 1 "arm_comparison_operator"
9039          [(match_operand:SI 2 "s_register_operand" "r,r")
9040           (match_operand:SI 3 "arm_add_operand" "rI,L")]))
9041    (clobber (reg:CC CC_REGNUM))]
9042   "TARGET_32BIT"
9043   "#"
9044   "&& reload_completed"
9045   [(set (reg:CC CC_REGNUM) (compare:CC (match_dup 2) (match_dup 3)))
9046    (cond_exec (match_dup 4) (set (match_dup 0) (const_int 0)))
9047    (cond_exec (match_dup 5) (set (match_dup 0) (const_int 1)))]
9049   rtx tmp1;
9050   machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
9051                                            operands[2], operands[3]);
9052   enum rtx_code rc = GET_CODE (operands[1]);
9054   tmp1 = gen_rtx_REG (mode, CC_REGNUM);
9056   operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, tmp1, const0_rtx);
9057   if (mode == CCFPmode || mode == CCFPEmode)
9058     rc = reverse_condition_maybe_unordered (rc);
9059   else
9060     rc = reverse_condition (rc);
9061   operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, tmp1, const0_rtx);
9063   [(set_attr "type" "multiple")]
9066 ;; Attempt to improve the sequence generated by the compare_scc splitters
9067 ;; not to use conditional execution.
9069 ;; Rd = (eq (reg1) (const_int0))  // ARMv5
9070 ;;      clz Rd, reg1
9071 ;;      lsr Rd, Rd, #5
9072 (define_peephole2
9073   [(set (reg:CC CC_REGNUM)
9074         (compare:CC (match_operand:SI 1 "register_operand" "")
9075                     (const_int 0)))
9076    (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
9077               (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
9078    (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
9079               (set (match_dup 0) (const_int 1)))]
9080   "arm_arch5t && TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
9081   [(set (match_dup 0) (clz:SI (match_dup 1)))
9082    (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
9085 ;; Rd = (eq (reg1) (const_int0))  // !ARMv5
9086 ;;      negs Rd, reg1
9087 ;;      adc  Rd, Rd, reg1
9088 (define_peephole2
9089   [(set (reg:CC CC_REGNUM)
9090         (compare:CC (match_operand:SI 1 "register_operand" "")
9091                     (const_int 0)))
9092    (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
9093               (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
9094    (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
9095               (set (match_dup 0) (const_int 1)))
9096    (match_scratch:SI 2 "r")]
9097   "TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
9098   [(parallel
9099     [(set (reg:CC CC_REGNUM)
9100           (compare:CC (const_int 0) (match_dup 1)))
9101      (set (match_dup 2) (minus:SI (const_int 0) (match_dup 1)))])
9102    (set (match_dup 0)
9103         (plus:SI (plus:SI (match_dup 1) (match_dup 2))
9104                  (geu:SI (reg:CC CC_REGNUM) (const_int 0))))]
9107 ;; Rd = (eq (reg1) (reg2/imm))  // ARMv5 and optimising for speed.
9108 ;;      sub  Rd, Reg1, reg2
9109 ;;      clz  Rd, Rd
9110 ;;      lsr  Rd, Rd, #5
9111 (define_peephole2
9112   [(set (reg:CC CC_REGNUM)
9113         (compare:CC (match_operand:SI 1 "register_operand" "")
9114                     (match_operand:SI 2 "arm_rhs_operand" "")))
9115    (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
9116               (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
9117    (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
9118               (set (match_dup 0) (const_int 1)))]
9119   "arm_arch5t && TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)
9120   && !(TARGET_THUMB2 && optimize_insn_for_size_p ())"
9121   [(set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))
9122    (set (match_dup 0) (clz:SI (match_dup 0)))
9123    (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
9127 ;; Rd = (eq (reg1) (reg2))      // ! ARMv5 or optimising for size.
9128 ;;      sub  T1, Reg1, reg2
9129 ;;      negs Rd, T1
9130 ;;      adc  Rd, Rd, T1
9131 (define_peephole2
9132   [(set (reg:CC CC_REGNUM)
9133         (compare:CC (match_operand:SI 1 "register_operand" "")
9134                     (match_operand:SI 2 "arm_rhs_operand" "")))
9135    (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
9136               (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
9137    (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
9138               (set (match_dup 0) (const_int 1)))
9139    (match_scratch:SI 3 "r")]
9140   "TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
9141   [(set (match_dup 3) (match_dup 4))
9142    (parallel
9143     [(set (reg:CC CC_REGNUM)
9144           (compare:CC (const_int 0) (match_dup 3)))
9145      (set (match_dup 0) (minus:SI (const_int 0) (match_dup 3)))])
9146    (set (match_dup 0)
9147         (plus:SI (plus:SI (match_dup 0) (match_dup 3))
9148                  (geu:SI (reg:CC CC_REGNUM) (const_int 0))))]
9149   "
9150   if (CONST_INT_P (operands[2]))
9151     operands[4] = plus_constant (SImode, operands[1], -INTVAL (operands[2]));
9152   else
9153     operands[4] = gen_rtx_MINUS (SImode, operands[1], operands[2]);
9154   ")
9156 (define_insn "*cond_move"
9157   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9158         (if_then_else:SI (match_operator 3 "equality_operator"
9159                           [(match_operator 4 "arm_comparison_operator"
9160                             [(match_operand 5 "cc_register" "") (const_int 0)])
9161                            (const_int 0)])
9162                          (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
9163                          (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))]
9164   "TARGET_ARM"
9165   "*
9166     if (GET_CODE (operands[3]) == NE)
9167       {
9168         if (which_alternative != 1)
9169           output_asm_insn (\"mov%D4\\t%0, %2\", operands);
9170         if (which_alternative != 0)
9171           output_asm_insn (\"mov%d4\\t%0, %1\", operands);
9172         return \"\";
9173       }
9174     if (which_alternative != 0)
9175       output_asm_insn (\"mov%D4\\t%0, %1\", operands);
9176     if (which_alternative != 1)
9177       output_asm_insn (\"mov%d4\\t%0, %2\", operands);
9178     return \"\";
9179   "
9180   [(set_attr "conds" "use")
9181    (set_attr_alternative "type"
9182                          [(if_then_else (match_operand 2 "const_int_operand" "")
9183                                         (const_string "mov_imm")
9184                                         (const_string "mov_reg"))
9185                           (if_then_else (match_operand 1 "const_int_operand" "")
9186                                         (const_string "mov_imm")
9187                                         (const_string "mov_reg"))
9188                           (const_string "multiple")])
9189    (set_attr "length" "4,4,8")]
9192 (define_insn "*cond_arith"
9193   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9194         (match_operator:SI 5 "shiftable_operator" 
9195          [(match_operator:SI 4 "arm_comparison_operator"
9196            [(match_operand:SI 2 "s_register_operand" "r,r")
9197             (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
9198           (match_operand:SI 1 "s_register_operand" "0,?r")]))
9199    (clobber (reg:CC CC_REGNUM))]
9200   "TARGET_ARM"
9201   "*
9202     if (GET_CODE (operands[4]) == LT && operands[3] == const0_rtx)
9203       return \"%i5\\t%0, %1, %2, lsr #31\";
9205     output_asm_insn (\"cmp\\t%2, %3\", operands);
9206     if (GET_CODE (operands[5]) == AND)
9207       output_asm_insn (\"mov%D4\\t%0, #0\", operands);
9208     else if (GET_CODE (operands[5]) == MINUS)
9209       output_asm_insn (\"rsb%D4\\t%0, %1, #0\", operands);
9210     else if (which_alternative != 0)
9211       output_asm_insn (\"mov%D4\\t%0, %1\", operands);
9212     return \"%i5%d4\\t%0, %1, #1\";
9213   "
9214   [(set_attr "conds" "clob")
9215    (set_attr "length" "12")
9216    (set_attr "type" "multiple")]
9219 (define_insn "*cond_sub"
9220   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9221         (minus:SI (match_operand:SI 1 "s_register_operand" "0,?r")
9222                   (match_operator:SI 4 "arm_comparison_operator"
9223                    [(match_operand:SI 2 "s_register_operand" "r,r")
9224                     (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
9225    (clobber (reg:CC CC_REGNUM))]
9226   "TARGET_ARM"
9227   "*
9228     output_asm_insn (\"cmp\\t%2, %3\", operands);
9229     if (which_alternative != 0)
9230       output_asm_insn (\"mov%D4\\t%0, %1\", operands);
9231     return \"sub%d4\\t%0, %1, #1\";
9232   "
9233   [(set_attr "conds" "clob")
9234    (set_attr "length" "8,12")
9235    (set_attr "type" "multiple")]
9238 (define_insn "*cmp_ite0"
9239   [(set (match_operand 6 "dominant_cc_register" "")
9240         (compare
9241          (if_then_else:SI
9242           (match_operator 4 "arm_comparison_operator"
9243            [(match_operand:SI 0 "s_register_operand"
9244                 "l,l,l,r,r,r,r,r,r")
9245             (match_operand:SI 1 "arm_add_operand"
9246                 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
9247           (match_operator:SI 5 "arm_comparison_operator"
9248            [(match_operand:SI 2 "s_register_operand"
9249                 "l,r,r,l,l,r,r,r,r")
9250             (match_operand:SI 3 "arm_add_operand"
9251                 "lPy,rI,L,lPy,lPy,rI,rI,L,L")])
9252           (const_int 0))
9253          (const_int 0)))]
9254   "TARGET_32BIT"
9255   "*
9256   {
9257     static const char * const cmp1[NUM_OF_COND_CMP][2] =
9258     {
9259       {\"cmp%d5\\t%0, %1\",
9260        \"cmp%d4\\t%2, %3\"},
9261       {\"cmn%d5\\t%0, #%n1\",
9262        \"cmp%d4\\t%2, %3\"},
9263       {\"cmp%d5\\t%0, %1\",
9264        \"cmn%d4\\t%2, #%n3\"},
9265       {\"cmn%d5\\t%0, #%n1\",
9266        \"cmn%d4\\t%2, #%n3\"}
9267     };
9268     static const char * const cmp2[NUM_OF_COND_CMP][2] =
9269     {
9270       {\"cmp\\t%2, %3\",
9271        \"cmp\\t%0, %1\"},
9272       {\"cmp\\t%2, %3\",
9273        \"cmn\\t%0, #%n1\"},
9274       {\"cmn\\t%2, #%n3\",
9275        \"cmp\\t%0, %1\"},
9276       {\"cmn\\t%2, #%n3\",
9277        \"cmn\\t%0, #%n1\"}
9278     };
9279     static const char * const ite[2] =
9280     {
9281       \"it\\t%d5\",
9282       \"it\\t%d4\"
9283     };
9284     static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
9285                                    CMP_CMP, CMN_CMP, CMP_CMP,
9286                                    CMN_CMP, CMP_CMN, CMN_CMN};
9287     int swap =
9288       comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
9290     output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
9291     if (TARGET_THUMB2) {
9292       output_asm_insn (ite[swap], operands);
9293     }
9294     output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
9295     return \"\";
9296   }"
9297   [(set_attr "conds" "set")
9298    (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
9299    (set_attr "enabled_for_short_it" "yes,no,no,no,no,no,no,no,no")
9300    (set_attr "type" "multiple")
9301    (set_attr_alternative "length"
9302       [(const_int 6)
9303        (const_int 8)
9304        (const_int 8)
9305        (const_int 8)
9306        (const_int 8)
9307        (if_then_else (eq_attr "is_thumb" "no")
9308            (const_int 8)
9309            (const_int 10))
9310        (if_then_else (eq_attr "is_thumb" "no")
9311            (const_int 8)
9312            (const_int 10))
9313        (if_then_else (eq_attr "is_thumb" "no")
9314            (const_int 8)
9315            (const_int 10))
9316        (if_then_else (eq_attr "is_thumb" "no")
9317            (const_int 8)
9318            (const_int 10))])]
9321 (define_insn "*cmp_ite1"
9322   [(set (match_operand 6 "dominant_cc_register" "")
9323         (compare
9324          (if_then_else:SI
9325           (match_operator 4 "arm_comparison_operator"
9326            [(match_operand:SI 0 "s_register_operand"
9327                 "l,l,l,r,r,r,r,r,r")
9328             (match_operand:SI 1 "arm_add_operand"
9329                 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
9330           (match_operator:SI 5 "arm_comparison_operator"
9331            [(match_operand:SI 2 "s_register_operand"
9332                 "l,r,r,l,l,r,r,r,r")
9333             (match_operand:SI 3 "arm_add_operand"
9334                 "lPy,rI,L,lPy,lPy,rI,rI,L,L")])
9335           (const_int 1))
9336          (const_int 0)))]
9337   "TARGET_32BIT"
9338   "*
9339   {
9340     static const char * const cmp1[NUM_OF_COND_CMP][2] =
9341     {
9342       {\"cmp\\t%0, %1\",
9343        \"cmp\\t%2, %3\"},
9344       {\"cmn\\t%0, #%n1\",
9345        \"cmp\\t%2, %3\"},
9346       {\"cmp\\t%0, %1\",
9347        \"cmn\\t%2, #%n3\"},
9348       {\"cmn\\t%0, #%n1\",
9349        \"cmn\\t%2, #%n3\"}
9350     };
9351     static const char * const cmp2[NUM_OF_COND_CMP][2] =
9352     {
9353       {\"cmp%d4\\t%2, %3\",
9354        \"cmp%D5\\t%0, %1\"},
9355       {\"cmp%d4\\t%2, %3\",
9356        \"cmn%D5\\t%0, #%n1\"},
9357       {\"cmn%d4\\t%2, #%n3\",
9358        \"cmp%D5\\t%0, %1\"},
9359       {\"cmn%d4\\t%2, #%n3\",
9360        \"cmn%D5\\t%0, #%n1\"}
9361     };
9362     static const char * const ite[2] =
9363     {
9364       \"it\\t%d4\",
9365       \"it\\t%D5\"
9366     };
9367     static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
9368                                    CMP_CMP, CMN_CMP, CMP_CMP,
9369                                    CMN_CMP, CMP_CMN, CMN_CMN};
9370     int swap =
9371       comparison_dominates_p (GET_CODE (operands[5]),
9372                               reverse_condition (GET_CODE (operands[4])));
9374     output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
9375     if (TARGET_THUMB2) {
9376       output_asm_insn (ite[swap], operands);
9377     }
9378     output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
9379     return \"\";
9380   }"
9381   [(set_attr "conds" "set")
9382    (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
9383    (set_attr "enabled_for_short_it" "yes,no,no,no,no,no,no,no,no")
9384    (set_attr_alternative "length"
9385       [(const_int 6)
9386        (const_int 8)
9387        (const_int 8)
9388        (const_int 8)
9389        (const_int 8)
9390        (if_then_else (eq_attr "is_thumb" "no")
9391            (const_int 8)
9392            (const_int 10))
9393        (if_then_else (eq_attr "is_thumb" "no")
9394            (const_int 8)
9395            (const_int 10))
9396        (if_then_else (eq_attr "is_thumb" "no")
9397            (const_int 8)
9398            (const_int 10))
9399        (if_then_else (eq_attr "is_thumb" "no")
9400            (const_int 8)
9401            (const_int 10))])
9402    (set_attr "type" "multiple")]
9405 (define_insn "*cmp_and"
9406   [(set (match_operand 6 "dominant_cc_register" "")
9407         (compare
9408          (and:SI
9409           (match_operator 4 "arm_comparison_operator"
9410            [(match_operand:SI 0 "s_register_operand" 
9411                 "l,l,l,r,r,r,r,r,r")
9412             (match_operand:SI 1 "arm_add_operand" 
9413                 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
9414           (match_operator:SI 5 "arm_comparison_operator"
9415            [(match_operand:SI 2 "s_register_operand" 
9416                 "l,r,r,l,l,r,r,r,r")
9417             (match_operand:SI 3 "arm_add_operand" 
9418                 "lPy,rI,L,lPy,lPy,rI,rI,L,L")]))
9419          (const_int 0)))]
9420   "TARGET_32BIT"
9421   "*
9422   {
9423     static const char *const cmp1[NUM_OF_COND_CMP][2] =
9424     {
9425       {\"cmp%d5\\t%0, %1\",
9426        \"cmp%d4\\t%2, %3\"},
9427       {\"cmn%d5\\t%0, #%n1\",
9428        \"cmp%d4\\t%2, %3\"},
9429       {\"cmp%d5\\t%0, %1\",
9430        \"cmn%d4\\t%2, #%n3\"},
9431       {\"cmn%d5\\t%0, #%n1\",
9432        \"cmn%d4\\t%2, #%n3\"}
9433     };
9434     static const char *const cmp2[NUM_OF_COND_CMP][2] =
9435     {
9436       {\"cmp\\t%2, %3\",
9437        \"cmp\\t%0, %1\"},
9438       {\"cmp\\t%2, %3\",
9439        \"cmn\\t%0, #%n1\"},
9440       {\"cmn\\t%2, #%n3\",
9441        \"cmp\\t%0, %1\"},
9442       {\"cmn\\t%2, #%n3\",
9443        \"cmn\\t%0, #%n1\"}
9444     };
9445     static const char *const ite[2] =
9446     {
9447       \"it\\t%d5\",
9448       \"it\\t%d4\"
9449     };
9450     static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
9451                                    CMP_CMP, CMN_CMP, CMP_CMP,
9452                                    CMN_CMP, CMP_CMN, CMN_CMN};
9453     int swap =
9454       comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
9456     output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
9457     if (TARGET_THUMB2) {
9458       output_asm_insn (ite[swap], operands);
9459     }
9460     output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
9461     return \"\";
9462   }"
9463   [(set_attr "conds" "set")
9464    (set_attr "predicable" "no")
9465    (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
9466    (set_attr "enabled_for_short_it" "yes,no,no,no,no,no,no,no,no")
9467    (set_attr_alternative "length"
9468       [(const_int 6)
9469        (const_int 8)
9470        (const_int 8)
9471        (const_int 8)
9472        (const_int 8)
9473        (if_then_else (eq_attr "is_thumb" "no")
9474            (const_int 8)
9475            (const_int 10))
9476        (if_then_else (eq_attr "is_thumb" "no")
9477            (const_int 8)
9478            (const_int 10))
9479        (if_then_else (eq_attr "is_thumb" "no")
9480            (const_int 8)
9481            (const_int 10))
9482        (if_then_else (eq_attr "is_thumb" "no")
9483            (const_int 8)
9484            (const_int 10))])
9485    (set_attr "type" "multiple")]
9488 (define_insn "*cmp_ior"
9489   [(set (match_operand 6 "dominant_cc_register" "")
9490         (compare
9491          (ior:SI
9492           (match_operator 4 "arm_comparison_operator"
9493            [(match_operand:SI 0 "s_register_operand"
9494                 "l,l,l,r,r,r,r,r,r")
9495             (match_operand:SI 1 "arm_add_operand"
9496                 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
9497           (match_operator:SI 5 "arm_comparison_operator"
9498            [(match_operand:SI 2 "s_register_operand"
9499                 "l,r,r,l,l,r,r,r,r")
9500             (match_operand:SI 3 "arm_add_operand"
9501                 "lPy,rI,L,lPy,lPy,rI,rI,L,L")]))
9502          (const_int 0)))]
9503   "TARGET_32BIT"
9504   "*
9505   {
9506     static const char *const cmp1[NUM_OF_COND_CMP][2] =
9507     {
9508       {\"cmp\\t%0, %1\",
9509        \"cmp\\t%2, %3\"},
9510       {\"cmn\\t%0, #%n1\",
9511        \"cmp\\t%2, %3\"},
9512       {\"cmp\\t%0, %1\",
9513        \"cmn\\t%2, #%n3\"},
9514       {\"cmn\\t%0, #%n1\",
9515        \"cmn\\t%2, #%n3\"}
9516     };
9517     static const char *const cmp2[NUM_OF_COND_CMP][2] =
9518     {
9519       {\"cmp%D4\\t%2, %3\",
9520        \"cmp%D5\\t%0, %1\"},
9521       {\"cmp%D4\\t%2, %3\",
9522        \"cmn%D5\\t%0, #%n1\"},
9523       {\"cmn%D4\\t%2, #%n3\",
9524        \"cmp%D5\\t%0, %1\"},
9525       {\"cmn%D4\\t%2, #%n3\",
9526        \"cmn%D5\\t%0, #%n1\"}
9527     };
9528     static const char *const ite[2] =
9529     {
9530       \"it\\t%D4\",
9531       \"it\\t%D5\"
9532     };
9533     static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
9534                                    CMP_CMP, CMN_CMP, CMP_CMP,
9535                                    CMN_CMP, CMP_CMN, CMN_CMN};
9536     int swap =
9537       comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
9539     output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
9540     if (TARGET_THUMB2) {
9541       output_asm_insn (ite[swap], operands);
9542     }
9543     output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
9544     return \"\";
9545   }
9546   "
9547   [(set_attr "conds" "set")
9548    (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
9549    (set_attr "enabled_for_short_it" "yes,no,no,no,no,no,no,no,no")
9550    (set_attr_alternative "length"
9551       [(const_int 6)
9552        (const_int 8)
9553        (const_int 8)
9554        (const_int 8)
9555        (const_int 8)
9556        (if_then_else (eq_attr "is_thumb" "no")
9557            (const_int 8)
9558            (const_int 10))
9559        (if_then_else (eq_attr "is_thumb" "no")
9560            (const_int 8)
9561            (const_int 10))
9562        (if_then_else (eq_attr "is_thumb" "no")
9563            (const_int 8)
9564            (const_int 10))
9565        (if_then_else (eq_attr "is_thumb" "no")
9566            (const_int 8)
9567            (const_int 10))])
9568    (set_attr "type" "multiple")]
9571 (define_insn_and_split "*ior_scc_scc"
9572   [(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts")
9573         (ior:SI (match_operator:SI 3 "arm_comparison_operator"
9574                  [(match_operand:SI 1 "s_register_operand" "l,r")
9575                   (match_operand:SI 2 "arm_add_operand" "lPy,rIL")])
9576                 (match_operator:SI 6 "arm_comparison_operator"
9577                  [(match_operand:SI 4 "s_register_operand" "l,r")
9578                   (match_operand:SI 5 "arm_add_operand" "lPy,rIL")])))
9579    (clobber (reg:CC CC_REGNUM))]
9580   "TARGET_32BIT
9581    && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_OR_Y)
9582        != CCmode)"
9583   "#"
9584   "TARGET_32BIT && reload_completed"
9585   [(set (match_dup 7)
9586         (compare
9587          (ior:SI
9588           (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9589           (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9590          (const_int 0)))
9591    (set (match_dup 0) (ne:SI (match_dup 7) (const_int 0)))]
9592   "operands[7]
9593      = gen_rtx_REG (arm_select_dominance_cc_mode (operands[3], operands[6],
9594                                                   DOM_CC_X_OR_Y),
9595                     CC_REGNUM);"
9596   [(set_attr "conds" "clob")
9597    (set_attr "enabled_for_short_it" "yes,no")
9598    (set_attr "length" "16")
9599    (set_attr "type" "multiple")]
9602 ; If the above pattern is followed by a CMP insn, then the compare is 
9603 ; redundant, since we can rework the conditional instruction that follows.
9604 (define_insn_and_split "*ior_scc_scc_cmp"
9605   [(set (match_operand 0 "dominant_cc_register" "")
9606         (compare (ior:SI (match_operator:SI 3 "arm_comparison_operator"
9607                           [(match_operand:SI 1 "s_register_operand" "l,r")
9608                            (match_operand:SI 2 "arm_add_operand" "lPy,rIL")])
9609                          (match_operator:SI 6 "arm_comparison_operator"
9610                           [(match_operand:SI 4 "s_register_operand" "l,r")
9611                            (match_operand:SI 5 "arm_add_operand" "lPy,rIL")]))
9612                  (const_int 0)))
9613    (set (match_operand:SI 7 "s_register_operand" "=Ts,Ts")
9614         (ior:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9615                 (match_op_dup 6 [(match_dup 4) (match_dup 5)])))]
9616   "TARGET_32BIT"
9617   "#"
9618   "TARGET_32BIT && reload_completed"
9619   [(set (match_dup 0)
9620         (compare
9621          (ior:SI
9622           (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9623           (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9624          (const_int 0)))
9625    (set (match_dup 7) (ne:SI (match_dup 0) (const_int 0)))]
9626   ""
9627   [(set_attr "conds" "set")
9628    (set_attr "enabled_for_short_it" "yes,no")
9629    (set_attr "length" "16")
9630    (set_attr "type" "multiple")]
9633 (define_insn_and_split "*and_scc_scc"
9634   [(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts")
9635         (and:SI (match_operator:SI 3 "arm_comparison_operator"
9636                  [(match_operand:SI 1 "s_register_operand" "l,r")
9637                   (match_operand:SI 2 "arm_add_operand" "lPy,rIL")])
9638                 (match_operator:SI 6 "arm_comparison_operator"
9639                  [(match_operand:SI 4 "s_register_operand" "l,r")
9640                   (match_operand:SI 5 "arm_add_operand" "lPy,rIL")])))
9641    (clobber (reg:CC CC_REGNUM))]
9642   "TARGET_32BIT
9643    && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
9644        != CCmode)"
9645   "#"
9646   "TARGET_32BIT && reload_completed
9647    && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
9648        != CCmode)"
9649   [(set (match_dup 7)
9650         (compare
9651          (and:SI
9652           (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9653           (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9654          (const_int 0)))
9655    (set (match_dup 0) (ne:SI (match_dup 7) (const_int 0)))]
9656   "operands[7]
9657      = gen_rtx_REG (arm_select_dominance_cc_mode (operands[3], operands[6],
9658                                                   DOM_CC_X_AND_Y),
9659                     CC_REGNUM);"
9660   [(set_attr "conds" "clob")
9661    (set_attr "enabled_for_short_it" "yes,no")
9662    (set_attr "length" "16")
9663    (set_attr "type" "multiple")]
9666 ; If the above pattern is followed by a CMP insn, then the compare is 
9667 ; redundant, since we can rework the conditional instruction that follows.
9668 (define_insn_and_split "*and_scc_scc_cmp"
9669   [(set (match_operand 0 "dominant_cc_register" "")
9670         (compare (and:SI (match_operator:SI 3 "arm_comparison_operator"
9671                           [(match_operand:SI 1 "s_register_operand" "l,r")
9672                            (match_operand:SI 2 "arm_add_operand" "lPy,rIL")])
9673                          (match_operator:SI 6 "arm_comparison_operator"
9674                           [(match_operand:SI 4 "s_register_operand" "l,r")
9675                            (match_operand:SI 5 "arm_add_operand" "lPy,rIL")]))
9676                  (const_int 0)))
9677    (set (match_operand:SI 7 "s_register_operand" "=Ts,Ts")
9678         (and:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9679                 (match_op_dup 6 [(match_dup 4) (match_dup 5)])))]
9680   "TARGET_32BIT"
9681   "#"
9682   "TARGET_32BIT && reload_completed"
9683   [(set (match_dup 0)
9684         (compare
9685          (and:SI
9686           (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9687           (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9688          (const_int 0)))
9689    (set (match_dup 7) (ne:SI (match_dup 0) (const_int 0)))]
9690   ""
9691   [(set_attr "conds" "set")
9692    (set_attr "enabled_for_short_it" "yes,no")
9693    (set_attr "length" "16")
9694    (set_attr "type" "multiple")]
9697 ;; If there is no dominance in the comparison, then we can still save an
9698 ;; instruction in the AND case, since we can know that the second compare
9699 ;; need only zero the value if false (if true, then the value is already
9700 ;; correct).
9701 (define_insn_and_split "*and_scc_scc_nodom"
9702   [(set (match_operand:SI 0 "s_register_operand" "=&Ts,&Ts,&Ts")
9703         (and:SI (match_operator:SI 3 "arm_comparison_operator"
9704                  [(match_operand:SI 1 "s_register_operand" "r,r,0")
9705                   (match_operand:SI 2 "arm_add_operand" "rIL,0,rIL")])
9706                 (match_operator:SI 6 "arm_comparison_operator"
9707                  [(match_operand:SI 4 "s_register_operand" "r,r,r")
9708                   (match_operand:SI 5 "arm_add_operand" "rIL,rIL,rIL")])))
9709    (clobber (reg:CC CC_REGNUM))]
9710   "TARGET_32BIT
9711    && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
9712        == CCmode)"
9713   "#"
9714   "TARGET_32BIT && reload_completed"
9715   [(parallel [(set (match_dup 0)
9716                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
9717               (clobber (reg:CC CC_REGNUM))])
9718    (set (match_dup 7) (match_op_dup 8 [(match_dup 4) (match_dup 5)]))
9719    (set (match_dup 0)
9720         (if_then_else:SI (match_op_dup 6 [(match_dup 7) (const_int 0)])
9721                          (match_dup 0)
9722                          (const_int 0)))]
9723   "operands[7] = gen_rtx_REG (SELECT_CC_MODE (GET_CODE (operands[6]),
9724                                               operands[4], operands[5]),
9725                               CC_REGNUM);
9726    operands[8] = gen_rtx_COMPARE (GET_MODE (operands[7]), operands[4],
9727                                   operands[5]);"
9728   [(set_attr "conds" "clob")
9729    (set_attr "length" "20")
9730    (set_attr "type" "multiple")]
9733 (define_split
9734   [(set (reg:CC_NOOV CC_REGNUM)
9735         (compare:CC_NOOV (ior:SI
9736                           (and:SI (match_operand:SI 0 "s_register_operand" "")
9737                                   (const_int 1))
9738                           (match_operator:SI 1 "arm_comparison_operator"
9739                            [(match_operand:SI 2 "s_register_operand" "")
9740                             (match_operand:SI 3 "arm_add_operand" "")]))
9741                          (const_int 0)))
9742    (clobber (match_operand:SI 4 "s_register_operand" ""))]
9743   "TARGET_ARM"
9744   [(set (match_dup 4)
9745         (ior:SI (match_op_dup 1 [(match_dup 2) (match_dup 3)])
9746                 (match_dup 0)))
9747    (set (reg:CC_NOOV CC_REGNUM)
9748         (compare:CC_NOOV (and:SI (match_dup 4) (const_int 1))
9749                          (const_int 0)))]
9750   "")
9752 (define_split
9753   [(set (reg:CC_NOOV CC_REGNUM)
9754         (compare:CC_NOOV (ior:SI
9755                           (match_operator:SI 1 "arm_comparison_operator"
9756                            [(match_operand:SI 2 "s_register_operand" "")
9757                             (match_operand:SI 3 "arm_add_operand" "")])
9758                           (and:SI (match_operand:SI 0 "s_register_operand" "")
9759                                   (const_int 1)))
9760                          (const_int 0)))
9761    (clobber (match_operand:SI 4 "s_register_operand" ""))]
9762   "TARGET_ARM"
9763   [(set (match_dup 4)
9764         (ior:SI (match_op_dup 1 [(match_dup 2) (match_dup 3)])
9765                 (match_dup 0)))
9766    (set (reg:CC_NOOV CC_REGNUM)
9767         (compare:CC_NOOV (and:SI (match_dup 4) (const_int 1))
9768                          (const_int 0)))]
9769   "")
9770 ;; ??? The conditional patterns above need checking for Thumb-2 usefulness
9772 (define_insn_and_split "*negscc"
9773   [(set (match_operand:SI 0 "s_register_operand" "=r")
9774         (neg:SI (match_operator 3 "arm_comparison_operator"
9775                  [(match_operand:SI 1 "s_register_operand" "r")
9776                   (match_operand:SI 2 "arm_rhs_operand" "rI")])))
9777    (clobber (reg:CC CC_REGNUM))]
9778   "TARGET_ARM"
9779   "#"
9780   "&& reload_completed"
9781   [(const_int 0)]
9782   {
9783     rtx cc_reg = gen_rtx_REG (CCmode, CC_REGNUM);
9785     if (GET_CODE (operands[3]) == LT && operands[2] == const0_rtx)
9786        {
9787          /* Emit mov\\t%0, %1, asr #31 */
9788          emit_insn (gen_rtx_SET (operands[0],
9789                                  gen_rtx_ASHIFTRT (SImode,
9790                                                    operands[1],
9791                                                    GEN_INT (31))));
9792          DONE;
9793        }
9794      else if (GET_CODE (operands[3]) == NE)
9795        {
9796         /* Emit subs\\t%0, %1, %2\;mvnne\\t%0, #0 */
9797         if (CONST_INT_P (operands[2]))
9798           emit_insn (gen_cmpsi2_addneg (operands[0], operands[1], operands[2],
9799                                         GEN_INT (- INTVAL (operands[2]))));
9800         else
9801           emit_insn (gen_subsi3_compare (operands[0], operands[1], operands[2]));
9803         emit_insn (gen_rtx_COND_EXEC (VOIDmode,
9804                                       gen_rtx_NE (SImode,
9805                                                   cc_reg,
9806                                                   const0_rtx),
9807                                       gen_rtx_SET (operands[0],
9808                                                    GEN_INT (~0))));
9809         DONE;
9810       }
9811     else
9812       {
9813         /* Emit: cmp\\t%1, %2\;mov%D3\\t%0, #0\;mvn%d3\\t%0, #0 */
9814         emit_insn (gen_rtx_SET (cc_reg,
9815                                 gen_rtx_COMPARE (CCmode, operands[1], operands[2])));
9816         enum rtx_code rc = GET_CODE (operands[3]);
9818         rc = reverse_condition (rc);
9819         emit_insn (gen_rtx_COND_EXEC (VOIDmode,
9820                                       gen_rtx_fmt_ee (rc,
9821                                                       VOIDmode,
9822                                                       cc_reg,
9823                                                       const0_rtx),
9824                                       gen_rtx_SET (operands[0], const0_rtx)));
9825         rc = GET_CODE (operands[3]);
9826         emit_insn (gen_rtx_COND_EXEC (VOIDmode,
9827                                       gen_rtx_fmt_ee (rc,
9828                                                       VOIDmode,
9829                                                       cc_reg,
9830                                                       const0_rtx),
9831                                       gen_rtx_SET (operands[0],
9832                                                    GEN_INT (~0))));
9833         DONE;
9834       }
9835      FAIL;
9836   }
9837   [(set_attr "conds" "clob")
9838    (set_attr "length" "12")
9839    (set_attr "type" "multiple")]
9842 (define_insn_and_split "movcond_addsi"
9843   [(set (match_operand:SI 0 "s_register_operand" "=r,l,r")
9844         (if_then_else:SI
9845          (match_operator 5 "comparison_operator"
9846           [(plus:SI (match_operand:SI 3 "s_register_operand" "r,r,r")
9847                     (match_operand:SI 4 "arm_add_operand" "rIL,rIL,rIL"))
9848             (const_int 0)])
9849          (match_operand:SI 1 "arm_rhs_operand" "rI,rPy,r")
9850          (match_operand:SI 2 "arm_rhs_operand" "rI,rPy,r")))
9851    (clobber (reg:CC CC_REGNUM))]
9852    "TARGET_32BIT"
9853    "#"
9854    "&& reload_completed"
9855   [(set (reg:CC_NOOV CC_REGNUM)
9856         (compare:CC_NOOV
9857          (plus:SI (match_dup 3)
9858                   (match_dup 4))
9859          (const_int 0)))
9860    (set (match_dup 0) (match_dup 1))
9861    (cond_exec (match_dup 6)
9862               (set (match_dup 0) (match_dup 2)))]
9863   "
9864   {
9865     machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[5]),
9866                                              operands[3], operands[4]);
9867     enum rtx_code rc = GET_CODE (operands[5]);
9868     operands[6] = gen_rtx_REG (mode, CC_REGNUM);
9869     gcc_assert (!(mode == CCFPmode || mode == CCFPEmode));
9870     if (!REG_P (operands[2]) || REGNO (operands[2]) != REGNO (operands[0]))
9871       rc = reverse_condition (rc);
9872     else
9873       std::swap (operands[1], operands[2]);
9875     operands[6] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
9876   }
9877   "
9878   [(set_attr "conds" "clob")
9879    (set_attr "enabled_for_short_it" "no,yes,yes")
9880    (set_attr "type" "multiple")]
9883 (define_insn "movcond"
9884   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9885         (if_then_else:SI
9886          (match_operator 5 "arm_comparison_operator"
9887           [(match_operand:SI 3 "s_register_operand" "r,r,r")
9888            (match_operand:SI 4 "arm_add_operand" "rIL,rIL,rIL")])
9889          (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
9890          (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
9891    (clobber (reg:CC CC_REGNUM))]
9892   "TARGET_ARM"
9893   "*
9894   if (GET_CODE (operands[5]) == LT
9895       && (operands[4] == const0_rtx))
9896     {
9897       if (which_alternative != 1 && REG_P (operands[1]))
9898         {
9899           if (operands[2] == const0_rtx)
9900             return \"and\\t%0, %1, %3, asr #31\";
9901           return \"ands\\t%0, %1, %3, asr #32\;movcc\\t%0, %2\";
9902         }
9903       else if (which_alternative != 0 && REG_P (operands[2]))
9904         {
9905           if (operands[1] == const0_rtx)
9906             return \"bic\\t%0, %2, %3, asr #31\";
9907           return \"bics\\t%0, %2, %3, asr #32\;movcs\\t%0, %1\";
9908         }
9909       /* The only case that falls through to here is when both ops 1 & 2
9910          are constants.  */
9911     }
9913   if (GET_CODE (operands[5]) == GE
9914       && (operands[4] == const0_rtx))
9915     {
9916       if (which_alternative != 1 && REG_P (operands[1]))
9917         {
9918           if (operands[2] == const0_rtx)
9919             return \"bic\\t%0, %1, %3, asr #31\";
9920           return \"bics\\t%0, %1, %3, asr #32\;movcs\\t%0, %2\";
9921         }
9922       else if (which_alternative != 0 && REG_P (operands[2]))
9923         {
9924           if (operands[1] == const0_rtx)
9925             return \"and\\t%0, %2, %3, asr #31\";
9926           return \"ands\\t%0, %2, %3, asr #32\;movcc\\t%0, %1\";
9927         }
9928       /* The only case that falls through to here is when both ops 1 & 2
9929          are constants.  */
9930     }
9931   if (CONST_INT_P (operands[4])
9932       && !const_ok_for_arm (INTVAL (operands[4])))
9933     output_asm_insn (\"cmn\\t%3, #%n4\", operands);
9934   else
9935     output_asm_insn (\"cmp\\t%3, %4\", operands);
9936   if (which_alternative != 0)
9937     output_asm_insn (\"mov%d5\\t%0, %1\", operands);
9938   if (which_alternative != 1)
9939     output_asm_insn (\"mov%D5\\t%0, %2\", operands);
9940   return \"\";
9941   "
9942   [(set_attr "conds" "clob")
9943    (set_attr "length" "8,8,12")
9944    (set_attr "type" "multiple")]
9947 ;; ??? The patterns below need checking for Thumb-2 usefulness.
9949 (define_insn "*ifcompare_plus_move"
9950   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9951         (if_then_else:SI (match_operator 6 "arm_comparison_operator"
9952                           [(match_operand:SI 4 "s_register_operand" "r,r")
9953                            (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
9954                          (plus:SI
9955                           (match_operand:SI 2 "s_register_operand" "r,r")
9956                           (match_operand:SI 3 "arm_add_operand" "rIL,rIL"))
9957                          (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))
9958    (clobber (reg:CC CC_REGNUM))]
9959   "TARGET_ARM"
9960   "#"
9961   [(set_attr "conds" "clob")
9962    (set_attr "length" "8,12")
9963    (set_attr "type" "multiple")]
9966 (define_insn "*if_plus_move"
9967   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
9968         (if_then_else:SI
9969          (match_operator 4 "arm_comparison_operator"
9970           [(match_operand 5 "cc_register" "") (const_int 0)])
9971          (plus:SI
9972           (match_operand:SI 2 "s_register_operand" "r,r,r,r")
9973           (match_operand:SI 3 "arm_add_operand" "rI,L,rI,L"))
9974          (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")))]
9975   "TARGET_ARM"
9976   "@
9977    add%d4\\t%0, %2, %3
9978    sub%d4\\t%0, %2, #%n3
9979    add%d4\\t%0, %2, %3\;mov%D4\\t%0, %1
9980    sub%d4\\t%0, %2, #%n3\;mov%D4\\t%0, %1"
9981   [(set_attr "conds" "use")
9982    (set_attr "length" "4,4,8,8")
9983    (set_attr_alternative "type"
9984                          [(if_then_else (match_operand 3 "const_int_operand" "")
9985                                         (const_string "alu_imm" )
9986                                         (const_string "alu_sreg"))
9987                           (const_string "alu_imm")
9988                           (const_string "multiple")
9989                           (const_string "multiple")])]
9992 (define_insn "*ifcompare_move_plus"
9993   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9994         (if_then_else:SI (match_operator 6 "arm_comparison_operator"
9995                           [(match_operand:SI 4 "s_register_operand" "r,r")
9996                            (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
9997                          (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
9998                          (plus:SI
9999                           (match_operand:SI 2 "s_register_operand" "r,r")
10000                           (match_operand:SI 3 "arm_add_operand" "rIL,rIL"))))
10001    (clobber (reg:CC CC_REGNUM))]
10002   "TARGET_ARM"
10003   "#"
10004   [(set_attr "conds" "clob")
10005    (set_attr "length" "8,12")
10006    (set_attr "type" "multiple")]
10009 (define_insn "*if_move_plus"
10010   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
10011         (if_then_else:SI
10012          (match_operator 4 "arm_comparison_operator"
10013           [(match_operand 5 "cc_register" "") (const_int 0)])
10014          (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")
10015          (plus:SI
10016           (match_operand:SI 2 "s_register_operand" "r,r,r,r")
10017           (match_operand:SI 3 "arm_add_operand" "rI,L,rI,L"))))]
10018   "TARGET_ARM"
10019   "@
10020    add%D4\\t%0, %2, %3
10021    sub%D4\\t%0, %2, #%n3
10022    add%D4\\t%0, %2, %3\;mov%d4\\t%0, %1
10023    sub%D4\\t%0, %2, #%n3\;mov%d4\\t%0, %1"
10024   [(set_attr "conds" "use")
10025    (set_attr "length" "4,4,8,8")
10026    (set_attr_alternative "type"
10027                          [(if_then_else (match_operand 3 "const_int_operand" "")
10028                                         (const_string "alu_imm" )
10029                                         (const_string "alu_sreg"))
10030                           (const_string "alu_imm")
10031                           (const_string "multiple")
10032                           (const_string "multiple")])]
10035 (define_insn "*ifcompare_arith_arith"
10036   [(set (match_operand:SI 0 "s_register_operand" "=r")
10037         (if_then_else:SI (match_operator 9 "arm_comparison_operator"
10038                           [(match_operand:SI 5 "s_register_operand" "r")
10039                            (match_operand:SI 6 "arm_add_operand" "rIL")])
10040                          (match_operator:SI 8 "shiftable_operator"
10041                           [(match_operand:SI 1 "s_register_operand" "r")
10042                            (match_operand:SI 2 "arm_rhs_operand" "rI")])
10043                          (match_operator:SI 7 "shiftable_operator"
10044                           [(match_operand:SI 3 "s_register_operand" "r")
10045                            (match_operand:SI 4 "arm_rhs_operand" "rI")])))
10046    (clobber (reg:CC CC_REGNUM))]
10047   "TARGET_ARM"
10048   "#"
10049   [(set_attr "conds" "clob")
10050    (set_attr "length" "12")
10051    (set_attr "type" "multiple")]
10054 (define_insn "*if_arith_arith"
10055   [(set (match_operand:SI 0 "s_register_operand" "=r")
10056         (if_then_else:SI (match_operator 5 "arm_comparison_operator"
10057                           [(match_operand 8 "cc_register" "") (const_int 0)])
10058                          (match_operator:SI 6 "shiftable_operator"
10059                           [(match_operand:SI 1 "s_register_operand" "r")
10060                            (match_operand:SI 2 "arm_rhs_operand" "rI")])
10061                          (match_operator:SI 7 "shiftable_operator"
10062                           [(match_operand:SI 3 "s_register_operand" "r")
10063                            (match_operand:SI 4 "arm_rhs_operand" "rI")])))]
10064   "TARGET_ARM"
10065   "%I6%d5\\t%0, %1, %2\;%I7%D5\\t%0, %3, %4"
10066   [(set_attr "conds" "use")
10067    (set_attr "length" "8")
10068    (set_attr "type" "multiple")]
10071 (define_insn "*ifcompare_arith_move"
10072   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10073         (if_then_else:SI (match_operator 6 "arm_comparison_operator"
10074                           [(match_operand:SI 2 "s_register_operand" "r,r")
10075                            (match_operand:SI 3 "arm_add_operand" "rIL,rIL")])
10076                          (match_operator:SI 7 "shiftable_operator"
10077                           [(match_operand:SI 4 "s_register_operand" "r,r")
10078                            (match_operand:SI 5 "arm_rhs_operand" "rI,rI")])
10079                          (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))
10080    (clobber (reg:CC CC_REGNUM))]
10081   "TARGET_ARM"
10082   "*
10083   /* If we have an operation where (op x 0) is the identity operation and
10084      the conditional operator is LT or GE and we are comparing against zero and
10085      everything is in registers then we can do this in two instructions.  */
10086   if (operands[3] == const0_rtx
10087       && GET_CODE (operands[7]) != AND
10088       && REG_P (operands[5])
10089       && REG_P (operands[1])
10090       && REGNO (operands[1]) == REGNO (operands[4])
10091       && REGNO (operands[4]) != REGNO (operands[0]))
10092     {
10093       if (GET_CODE (operands[6]) == LT)
10094         return \"and\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\";
10095       else if (GET_CODE (operands[6]) == GE)
10096         return \"bic\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\";
10097     }
10098   if (CONST_INT_P (operands[3])
10099       && !const_ok_for_arm (INTVAL (operands[3])))
10100     output_asm_insn (\"cmn\\t%2, #%n3\", operands);
10101   else
10102     output_asm_insn (\"cmp\\t%2, %3\", operands);
10103   output_asm_insn (\"%I7%d6\\t%0, %4, %5\", operands);
10104   if (which_alternative != 0)
10105     return \"mov%D6\\t%0, %1\";
10106   return \"\";
10107   "
10108   [(set_attr "conds" "clob")
10109    (set_attr "length" "8,12")
10110    (set_attr "type" "multiple")]
10113 (define_insn "*if_arith_move"
10114   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10115         (if_then_else:SI (match_operator 4 "arm_comparison_operator"
10116                           [(match_operand 6 "cc_register" "") (const_int 0)])
10117                          (match_operator:SI 5 "shiftable_operator"
10118                           [(match_operand:SI 2 "s_register_operand" "r,r")
10119                            (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
10120                          (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))]
10121   "TARGET_ARM"
10122   "@
10123    %I5%d4\\t%0, %2, %3
10124    %I5%d4\\t%0, %2, %3\;mov%D4\\t%0, %1"
10125   [(set_attr "conds" "use")
10126    (set_attr "length" "4,8")
10127    (set_attr_alternative "type"
10128                          [(if_then_else (match_operand 3 "const_int_operand" "")
10129                                         (const_string "alu_shift_imm" )
10130                                         (const_string "alu_shift_reg"))
10131                           (const_string "multiple")])]
10134 (define_insn "*ifcompare_move_arith"
10135   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10136         (if_then_else:SI (match_operator 6 "arm_comparison_operator"
10137                           [(match_operand:SI 4 "s_register_operand" "r,r")
10138                            (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
10139                          (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
10140                          (match_operator:SI 7 "shiftable_operator"
10141                           [(match_operand:SI 2 "s_register_operand" "r,r")
10142                            (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
10143    (clobber (reg:CC CC_REGNUM))]
10144   "TARGET_ARM"
10145   "*
10146   /* If we have an operation where (op x 0) is the identity operation and
10147      the conditional operator is LT or GE and we are comparing against zero and
10148      everything is in registers then we can do this in two instructions */
10149   if (operands[5] == const0_rtx
10150       && GET_CODE (operands[7]) != AND
10151       && REG_P (operands[3])
10152       && REG_P (operands[1])
10153       && REGNO (operands[1]) == REGNO (operands[2])
10154       && REGNO (operands[2]) != REGNO (operands[0]))
10155     {
10156       if (GET_CODE (operands[6]) == GE)
10157         return \"and\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\";
10158       else if (GET_CODE (operands[6]) == LT)
10159         return \"bic\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\";
10160     }
10162   if (CONST_INT_P (operands[5])
10163       && !const_ok_for_arm (INTVAL (operands[5])))
10164     output_asm_insn (\"cmn\\t%4, #%n5\", operands);
10165   else
10166     output_asm_insn (\"cmp\\t%4, %5\", operands);
10168   if (which_alternative != 0)
10169     output_asm_insn (\"mov%d6\\t%0, %1\", operands);
10170   return \"%I7%D6\\t%0, %2, %3\";
10171   "
10172   [(set_attr "conds" "clob")
10173    (set_attr "length" "8,12")
10174    (set_attr "type" "multiple")]
10177 (define_insn "*if_move_arith"
10178   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10179         (if_then_else:SI
10180          (match_operator 4 "arm_comparison_operator"
10181           [(match_operand 6 "cc_register" "") (const_int 0)])
10182          (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
10183          (match_operator:SI 5 "shiftable_operator"
10184           [(match_operand:SI 2 "s_register_operand" "r,r")
10185            (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))]
10186   "TARGET_ARM"
10187   "@
10188    %I5%D4\\t%0, %2, %3
10189    %I5%D4\\t%0, %2, %3\;mov%d4\\t%0, %1"
10190   [(set_attr "conds" "use")
10191    (set_attr "length" "4,8")
10192    (set_attr_alternative "type"
10193                          [(if_then_else (match_operand 3 "const_int_operand" "")
10194                                         (const_string "alu_shift_imm" )
10195                                         (const_string "alu_shift_reg"))
10196                           (const_string "multiple")])]
10199 (define_insn "*ifcompare_move_not"
10200   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10201         (if_then_else:SI
10202          (match_operator 5 "arm_comparison_operator"
10203           [(match_operand:SI 3 "s_register_operand" "r,r")
10204            (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
10205          (match_operand:SI 1 "arm_not_operand" "0,?rIK")
10206          (not:SI
10207           (match_operand:SI 2 "s_register_operand" "r,r"))))
10208    (clobber (reg:CC CC_REGNUM))]
10209   "TARGET_ARM"
10210   "#"
10211   [(set_attr "conds" "clob")
10212    (set_attr "length" "8,12")
10213    (set_attr "type" "multiple")]
10216 (define_insn "*if_move_not"
10217   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
10218         (if_then_else:SI
10219          (match_operator 4 "arm_comparison_operator"
10220           [(match_operand 3 "cc_register" "") (const_int 0)])
10221          (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
10222          (not:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))))]
10223   "TARGET_ARM"
10224   "@
10225    mvn%D4\\t%0, %2
10226    mov%d4\\t%0, %1\;mvn%D4\\t%0, %2
10227    mvn%d4\\t%0, #%B1\;mvn%D4\\t%0, %2"
10228   [(set_attr "conds" "use")
10229    (set_attr "type" "mvn_reg")
10230    (set_attr "length" "4,8,8")
10231    (set_attr "type" "mvn_reg,multiple,multiple")]
10234 (define_insn "*ifcompare_not_move"
10235   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10236         (if_then_else:SI 
10237          (match_operator 5 "arm_comparison_operator"
10238           [(match_operand:SI 3 "s_register_operand" "r,r")
10239            (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
10240          (not:SI
10241           (match_operand:SI 2 "s_register_operand" "r,r"))
10242          (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
10243    (clobber (reg:CC CC_REGNUM))]
10244   "TARGET_ARM"
10245   "#"
10246   [(set_attr "conds" "clob")
10247    (set_attr "length" "8,12")
10248    (set_attr "type" "multiple")]
10251 (define_insn "*if_not_move"
10252   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
10253         (if_then_else:SI
10254          (match_operator 4 "arm_comparison_operator"
10255           [(match_operand 3 "cc_register" "") (const_int 0)])
10256          (not:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))
10257          (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
10258   "TARGET_ARM"
10259   "@
10260    mvn%d4\\t%0, %2
10261    mov%D4\\t%0, %1\;mvn%d4\\t%0, %2
10262    mvn%D4\\t%0, #%B1\;mvn%d4\\t%0, %2"
10263   [(set_attr "conds" "use")
10264    (set_attr "type" "mvn_reg,multiple,multiple")
10265    (set_attr "length" "4,8,8")]
10268 (define_insn "*ifcompare_shift_move"
10269   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10270         (if_then_else:SI
10271          (match_operator 6 "arm_comparison_operator"
10272           [(match_operand:SI 4 "s_register_operand" "r,r")
10273            (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
10274          (match_operator:SI 7 "shift_operator"
10275           [(match_operand:SI 2 "s_register_operand" "r,r")
10276            (match_operand:SI 3 "arm_rhs_operand" "rM,rM")])
10277          (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
10278    (clobber (reg:CC CC_REGNUM))]
10279   "TARGET_ARM"
10280   "#"
10281   [(set_attr "conds" "clob")
10282    (set_attr "length" "8,12")
10283    (set_attr "type" "multiple")]
10286 (define_insn "*if_shift_move"
10287   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
10288         (if_then_else:SI
10289          (match_operator 5 "arm_comparison_operator"
10290           [(match_operand 6 "cc_register" "") (const_int 0)])
10291          (match_operator:SI 4 "shift_operator"
10292           [(match_operand:SI 2 "s_register_operand" "r,r,r")
10293            (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM")])
10294          (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
10295   "TARGET_ARM"
10296   "@
10297    mov%d5\\t%0, %2%S4
10298    mov%D5\\t%0, %1\;mov%d5\\t%0, %2%S4
10299    mvn%D5\\t%0, #%B1\;mov%d5\\t%0, %2%S4"
10300   [(set_attr "conds" "use")
10301    (set_attr "shift" "2")
10302    (set_attr "length" "4,8,8")
10303    (set_attr_alternative "type"
10304                          [(if_then_else (match_operand 3 "const_int_operand" "")
10305                                         (const_string "mov_shift" )
10306                                         (const_string "mov_shift_reg"))
10307                           (const_string "multiple")
10308                           (const_string "multiple")])]
10311 (define_insn "*ifcompare_move_shift"
10312   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10313         (if_then_else:SI
10314          (match_operator 6 "arm_comparison_operator"
10315           [(match_operand:SI 4 "s_register_operand" "r,r")
10316            (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
10317          (match_operand:SI 1 "arm_not_operand" "0,?rIK")
10318          (match_operator:SI 7 "shift_operator"
10319           [(match_operand:SI 2 "s_register_operand" "r,r")
10320            (match_operand:SI 3 "arm_rhs_operand" "rM,rM")])))
10321    (clobber (reg:CC CC_REGNUM))]
10322   "TARGET_ARM"
10323   "#"
10324   [(set_attr "conds" "clob")
10325    (set_attr "length" "8,12")
10326    (set_attr "type" "multiple")]
10329 (define_insn "*if_move_shift"
10330   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
10331         (if_then_else:SI
10332          (match_operator 5 "arm_comparison_operator"
10333           [(match_operand 6 "cc_register" "") (const_int 0)])
10334          (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
10335          (match_operator:SI 4 "shift_operator"
10336           [(match_operand:SI 2 "s_register_operand" "r,r,r")
10337            (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM")])))]
10338   "TARGET_ARM"
10339   "@
10340    mov%D5\\t%0, %2%S4
10341    mov%d5\\t%0, %1\;mov%D5\\t%0, %2%S4
10342    mvn%d5\\t%0, #%B1\;mov%D5\\t%0, %2%S4"
10343   [(set_attr "conds" "use")
10344    (set_attr "shift" "2")
10345    (set_attr "length" "4,8,8")
10346    (set_attr_alternative "type"
10347                          [(if_then_else (match_operand 3 "const_int_operand" "")
10348                                         (const_string "mov_shift" )
10349                                         (const_string "mov_shift_reg"))
10350                           (const_string "multiple")
10351                           (const_string "multiple")])]
10354 (define_insn "*ifcompare_shift_shift"
10355   [(set (match_operand:SI 0 "s_register_operand" "=r")
10356         (if_then_else:SI
10357          (match_operator 7 "arm_comparison_operator"
10358           [(match_operand:SI 5 "s_register_operand" "r")
10359            (match_operand:SI 6 "arm_add_operand" "rIL")])
10360          (match_operator:SI 8 "shift_operator"
10361           [(match_operand:SI 1 "s_register_operand" "r")
10362            (match_operand:SI 2 "arm_rhs_operand" "rM")])
10363          (match_operator:SI 9 "shift_operator"
10364           [(match_operand:SI 3 "s_register_operand" "r")
10365            (match_operand:SI 4 "arm_rhs_operand" "rM")])))
10366    (clobber (reg:CC CC_REGNUM))]
10367   "TARGET_ARM"
10368   "#"
10369   [(set_attr "conds" "clob")
10370    (set_attr "length" "12")
10371    (set_attr "type" "multiple")]
10374 (define_insn "*if_shift_shift"
10375   [(set (match_operand:SI 0 "s_register_operand" "=r")
10376         (if_then_else:SI
10377          (match_operator 5 "arm_comparison_operator"
10378           [(match_operand 8 "cc_register" "") (const_int 0)])
10379          (match_operator:SI 6 "shift_operator"
10380           [(match_operand:SI 1 "s_register_operand" "r")
10381            (match_operand:SI 2 "arm_rhs_operand" "rM")])
10382          (match_operator:SI 7 "shift_operator"
10383           [(match_operand:SI 3 "s_register_operand" "r")
10384            (match_operand:SI 4 "arm_rhs_operand" "rM")])))]
10385   "TARGET_ARM"
10386   "mov%d5\\t%0, %1%S6\;mov%D5\\t%0, %3%S7"
10387   [(set_attr "conds" "use")
10388    (set_attr "shift" "1")
10389    (set_attr "length" "8")
10390    (set (attr "type") (if_then_else
10391                         (and (match_operand 2 "const_int_operand" "")
10392                              (match_operand 4 "const_int_operand" ""))
10393                       (const_string "mov_shift")
10394                       (const_string "mov_shift_reg")))]
10397 (define_insn "*ifcompare_not_arith"
10398   [(set (match_operand:SI 0 "s_register_operand" "=r")
10399         (if_then_else:SI
10400          (match_operator 6 "arm_comparison_operator"
10401           [(match_operand:SI 4 "s_register_operand" "r")
10402            (match_operand:SI 5 "arm_add_operand" "rIL")])
10403          (not:SI (match_operand:SI 1 "s_register_operand" "r"))
10404          (match_operator:SI 7 "shiftable_operator"
10405           [(match_operand:SI 2 "s_register_operand" "r")
10406            (match_operand:SI 3 "arm_rhs_operand" "rI")])))
10407    (clobber (reg:CC CC_REGNUM))]
10408   "TARGET_ARM"
10409   "#"
10410   [(set_attr "conds" "clob")
10411    (set_attr "length" "12")
10412    (set_attr "type" "multiple")]
10415 (define_insn "*if_not_arith"
10416   [(set (match_operand:SI 0 "s_register_operand" "=r")
10417         (if_then_else:SI
10418          (match_operator 5 "arm_comparison_operator"
10419           [(match_operand 4 "cc_register" "") (const_int 0)])
10420          (not:SI (match_operand:SI 1 "s_register_operand" "r"))
10421          (match_operator:SI 6 "shiftable_operator"
10422           [(match_operand:SI 2 "s_register_operand" "r")
10423            (match_operand:SI 3 "arm_rhs_operand" "rI")])))]
10424   "TARGET_ARM"
10425   "mvn%d5\\t%0, %1\;%I6%D5\\t%0, %2, %3"
10426   [(set_attr "conds" "use")
10427    (set_attr "type" "mvn_reg")
10428    (set_attr "length" "8")]
10431 (define_insn "*ifcompare_arith_not"
10432   [(set (match_operand:SI 0 "s_register_operand" "=r")
10433         (if_then_else:SI
10434          (match_operator 6 "arm_comparison_operator"
10435           [(match_operand:SI 4 "s_register_operand" "r")
10436            (match_operand:SI 5 "arm_add_operand" "rIL")])
10437          (match_operator:SI 7 "shiftable_operator"
10438           [(match_operand:SI 2 "s_register_operand" "r")
10439            (match_operand:SI 3 "arm_rhs_operand" "rI")])
10440          (not:SI (match_operand:SI 1 "s_register_operand" "r"))))
10441    (clobber (reg:CC CC_REGNUM))]
10442   "TARGET_ARM"
10443   "#"
10444   [(set_attr "conds" "clob")
10445    (set_attr "length" "12")
10446    (set_attr "type" "multiple")]
10449 (define_insn "*if_arith_not"
10450   [(set (match_operand:SI 0 "s_register_operand" "=r")
10451         (if_then_else:SI
10452          (match_operator 5 "arm_comparison_operator"
10453           [(match_operand 4 "cc_register" "") (const_int 0)])
10454          (match_operator:SI 6 "shiftable_operator"
10455           [(match_operand:SI 2 "s_register_operand" "r")
10456            (match_operand:SI 3 "arm_rhs_operand" "rI")])
10457          (not:SI (match_operand:SI 1 "s_register_operand" "r"))))]
10458   "TARGET_ARM"
10459   "mvn%D5\\t%0, %1\;%I6%d5\\t%0, %2, %3"
10460   [(set_attr "conds" "use")
10461    (set_attr "type" "multiple")
10462    (set_attr "length" "8")]
10465 (define_insn "*ifcompare_neg_move"
10466   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10467         (if_then_else:SI
10468          (match_operator 5 "arm_comparison_operator"
10469           [(match_operand:SI 3 "s_register_operand" "r,r")
10470            (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
10471          (neg:SI (match_operand:SI 2 "s_register_operand" "r,r"))
10472          (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
10473    (clobber (reg:CC CC_REGNUM))]
10474   "TARGET_ARM"
10475   "#"
10476   [(set_attr "conds" "clob")
10477    (set_attr "length" "8,12")
10478    (set_attr "type" "multiple")]
10481 (define_insn_and_split "*if_neg_move"
10482   [(set (match_operand:SI 0 "s_register_operand" "=l,r")
10483         (if_then_else:SI
10484          (match_operator 4 "arm_comparison_operator"
10485           [(match_operand 3 "cc_register" "") (const_int 0)])
10486          (neg:SI (match_operand:SI 2 "s_register_operand" "l,r"))
10487          (match_operand:SI 1 "s_register_operand" "0,0")))]
10488   "TARGET_32BIT"
10489   "#"
10490   "&& reload_completed"
10491   [(cond_exec (match_op_dup 4 [(match_dup 3) (const_int 0)])
10492               (set (match_dup 0) (neg:SI (match_dup 2))))]
10493   ""
10494   [(set_attr "conds" "use")
10495    (set_attr "length" "4")
10496    (set_attr "arch" "t2,32")
10497    (set_attr "enabled_for_short_it" "yes,no")
10498    (set_attr "type" "logic_shift_imm")]
10501 (define_insn "*ifcompare_move_neg"
10502   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10503         (if_then_else:SI
10504          (match_operator 5 "arm_comparison_operator"
10505           [(match_operand:SI 3 "s_register_operand" "r,r")
10506            (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
10507          (match_operand:SI 1 "arm_not_operand" "0,?rIK")
10508          (neg:SI (match_operand:SI 2 "s_register_operand" "r,r"))))
10509    (clobber (reg:CC CC_REGNUM))]
10510   "TARGET_ARM"
10511   "#"
10512   [(set_attr "conds" "clob")
10513    (set_attr "length" "8,12")
10514    (set_attr "type" "multiple")]
10517 (define_insn_and_split "*if_move_neg"
10518   [(set (match_operand:SI 0 "s_register_operand" "=l,r")
10519         (if_then_else:SI
10520          (match_operator 4 "arm_comparison_operator"
10521           [(match_operand 3 "cc_register" "") (const_int 0)])
10522          (match_operand:SI 1 "s_register_operand" "0,0")
10523          (neg:SI (match_operand:SI 2 "s_register_operand" "l,r"))))]
10524   "TARGET_32BIT"
10525   "#"
10526   "&& reload_completed"
10527   [(cond_exec (match_dup 5)
10528               (set (match_dup 0) (neg:SI (match_dup 2))))]
10529   {
10530     machine_mode mode = GET_MODE (operands[3]);
10531     rtx_code rc = GET_CODE (operands[4]);
10533     if (mode == CCFPmode || mode == CCFPEmode)
10534       rc = reverse_condition_maybe_unordered (rc);
10535     else
10536       rc = reverse_condition (rc);
10538     operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[3], const0_rtx);
10539   }
10540   [(set_attr "conds" "use")
10541    (set_attr "length" "4")
10542    (set_attr "arch" "t2,32")
10543    (set_attr "enabled_for_short_it" "yes,no")
10544    (set_attr "type" "logic_shift_imm")]
10547 (define_insn "*arith_adjacentmem"
10548   [(set (match_operand:SI 0 "s_register_operand" "=r")
10549         (match_operator:SI 1 "shiftable_operator"
10550          [(match_operand:SI 2 "memory_operand" "m")
10551           (match_operand:SI 3 "memory_operand" "m")]))
10552    (clobber (match_scratch:SI 4 "=r"))]
10553   "TARGET_ARM && adjacent_mem_locations (operands[2], operands[3])"
10554   "*
10555   {
10556     rtx ldm[3];
10557     rtx arith[4];
10558     rtx base_reg;
10559     HOST_WIDE_INT val1 = 0, val2 = 0;
10561     if (REGNO (operands[0]) > REGNO (operands[4]))
10562       {
10563         ldm[1] = operands[4];
10564         ldm[2] = operands[0];
10565       }
10566     else
10567       {
10568         ldm[1] = operands[0];
10569         ldm[2] = operands[4];
10570       }
10572     base_reg = XEXP (operands[2], 0);
10574     if (!REG_P (base_reg))
10575       {
10576         val1 = INTVAL (XEXP (base_reg, 1));
10577         base_reg = XEXP (base_reg, 0);
10578       }
10580     if (!REG_P (XEXP (operands[3], 0)))
10581       val2 = INTVAL (XEXP (XEXP (operands[3], 0), 1));
10583     arith[0] = operands[0];
10584     arith[3] = operands[1];
10586     if (val1 < val2)
10587       {
10588         arith[1] = ldm[1];
10589         arith[2] = ldm[2];
10590       }
10591     else
10592       {
10593         arith[1] = ldm[2];
10594         arith[2] = ldm[1];
10595       }
10597     ldm[0] = base_reg;
10598     if (val1 !=0 && val2 != 0)
10599       {
10600         rtx ops[3];
10602         if (val1 == 4 || val2 == 4)
10603           /* Other val must be 8, since we know they are adjacent and neither
10604              is zero.  */
10605           output_asm_insn (\"ldmib%?\\t%0, {%1, %2}\", ldm);
10606         else if (const_ok_for_arm (val1) || const_ok_for_arm (-val1))
10607           {
10608             ldm[0] = ops[0] = operands[4];
10609             ops[1] = base_reg;
10610             ops[2] = GEN_INT (val1);
10611             output_add_immediate (ops);
10612             if (val1 < val2)
10613               output_asm_insn (\"ldmia%?\\t%0, {%1, %2}\", ldm);
10614             else
10615               output_asm_insn (\"ldmda%?\\t%0, {%1, %2}\", ldm);
10616           }
10617         else
10618           {
10619             /* Offset is out of range for a single add, so use two ldr.  */
10620             ops[0] = ldm[1];
10621             ops[1] = base_reg;
10622             ops[2] = GEN_INT (val1);
10623             output_asm_insn (\"ldr%?\\t%0, [%1, %2]\", ops);
10624             ops[0] = ldm[2];
10625             ops[2] = GEN_INT (val2);
10626             output_asm_insn (\"ldr%?\\t%0, [%1, %2]\", ops);
10627           }
10628       }
10629     else if (val1 != 0)
10630       {
10631         if (val1 < val2)
10632           output_asm_insn (\"ldmda%?\\t%0, {%1, %2}\", ldm);
10633         else
10634           output_asm_insn (\"ldmia%?\\t%0, {%1, %2}\", ldm);
10635       }
10636     else
10637       {
10638         if (val1 < val2)
10639           output_asm_insn (\"ldmia%?\\t%0, {%1, %2}\", ldm);
10640         else
10641           output_asm_insn (\"ldmda%?\\t%0, {%1, %2}\", ldm);
10642       }
10643     output_asm_insn (\"%I3%?\\t%0, %1, %2\", arith);
10644     return \"\";
10645   }"
10646   [(set_attr "length" "12")
10647    (set_attr "predicable" "yes")
10648    (set_attr "type" "load_4")]
10651 ; This pattern is never tried by combine, so do it as a peephole
10653 (define_peephole2
10654   [(set (match_operand:SI 0 "arm_general_register_operand" "")
10655         (match_operand:SI 1 "arm_general_register_operand" ""))
10656    (set (reg:CC CC_REGNUM)
10657         (compare:CC (match_dup 1) (const_int 0)))]
10658   "TARGET_ARM"
10659   [(parallel [(set (reg:CC CC_REGNUM) (compare:CC (match_dup 1) (const_int 0)))
10660               (set (match_dup 0) (match_dup 1))])]
10661   ""
10664 (define_split
10665   [(set (match_operand:SI 0 "s_register_operand" "")
10666         (and:SI (ge:SI (match_operand:SI 1 "s_register_operand" "")
10667                        (const_int 0))
10668                 (neg:SI (match_operator:SI 2 "arm_comparison_operator"
10669                          [(match_operand:SI 3 "s_register_operand" "")
10670                           (match_operand:SI 4 "arm_rhs_operand" "")]))))
10671    (clobber (match_operand:SI 5 "s_register_operand" ""))]
10672   "TARGET_ARM"
10673   [(set (match_dup 5) (not:SI (ashiftrt:SI (match_dup 1) (const_int 31))))
10674    (set (match_dup 0) (and:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
10675                               (match_dup 5)))]
10676   ""
10679 ;; This split can be used because CC_Z mode implies that the following
10680 ;; branch will be an equality, or an unsigned inequality, so the sign
10681 ;; extension is not needed.
10683 (define_split
10684   [(set (reg:CC_Z CC_REGNUM)
10685         (compare:CC_Z
10686          (ashift:SI (subreg:SI (match_operand:QI 0 "memory_operand" "") 0)
10687                     (const_int 24))
10688          (match_operand 1 "const_int_operand" "")))
10689    (clobber (match_scratch:SI 2 ""))]
10690   "TARGET_ARM
10691    && ((UINTVAL (operands[1]))
10692        == ((UINTVAL (operands[1])) >> 24) << 24)"
10693   [(set (match_dup 2) (zero_extend:SI (match_dup 0)))
10694    (set (reg:CC CC_REGNUM) (compare:CC (match_dup 2) (match_dup 1)))]
10695   "
10696   operands[1] = GEN_INT (((unsigned long) INTVAL (operands[1])) >> 24);
10697   "
10699 ;; ??? Check the patterns above for Thumb-2 usefulness
10701 (define_expand "prologue"
10702   [(clobber (const_int 0))]
10703   "TARGET_EITHER"
10704   "if (TARGET_32BIT)
10705      arm_expand_prologue ();
10706    else
10707      thumb1_expand_prologue ();
10708   DONE;
10709   "
10712 (define_expand "epilogue"
10713   [(clobber (const_int 0))]
10714   "TARGET_EITHER"
10715   "
10716   if (crtl->calls_eh_return)
10717     emit_insn (gen_force_register_use (gen_rtx_REG (Pmode, 2)));
10718   if (TARGET_THUMB1)
10719    {
10720      thumb1_expand_epilogue ();
10721      emit_jump_insn (gen_rtx_UNSPEC_VOLATILE (VOIDmode,
10722                      gen_rtvec (1, ret_rtx), VUNSPEC_EPILOGUE));
10723    }
10724   else if (HAVE_return)
10725    {
10726      /* HAVE_return is testing for USE_RETURN_INSN (FALSE).  Hence,
10727         no need for explicit testing again.  */
10728      emit_jump_insn (gen_return ());
10729    }
10730   else if (TARGET_32BIT)
10731    {
10732     arm_expand_epilogue (true);
10733    }
10734   DONE;
10735   "
10738 ;; Note - although unspec_volatile's USE all hard registers,
10739 ;; USEs are ignored after relaod has completed.  Thus we need
10740 ;; to add an unspec of the link register to ensure that flow
10741 ;; does not think that it is unused by the sibcall branch that
10742 ;; will replace the standard function epilogue.
10743 (define_expand "sibcall_epilogue"
10744    [(parallel [(unspec:SI [(reg:SI LR_REGNUM)] UNSPEC_REGISTER_USE)
10745                (unspec_volatile [(return)] VUNSPEC_EPILOGUE)])]
10746    "TARGET_32BIT"
10747    "
10748    arm_expand_epilogue (false);
10749    DONE;
10750    "
10753 (define_expand "eh_epilogue"
10754   [(use (match_operand:SI 0 "register_operand" ""))
10755    (use (match_operand:SI 1 "register_operand" ""))
10756    (use (match_operand:SI 2 "register_operand" ""))]
10757   "TARGET_EITHER"
10758   "
10759   {
10760     cfun->machine->eh_epilogue_sp_ofs = operands[1];
10761     if (!REG_P (operands[2]) || REGNO (operands[2]) != 2)
10762       {
10763         rtx ra = gen_rtx_REG (Pmode, 2);
10765         emit_move_insn (ra, operands[2]);
10766         operands[2] = ra;
10767       }
10768     /* This is a hack -- we may have crystalized the function type too
10769        early.  */
10770     cfun->machine->func_type = 0;
10771   }"
10774 ;; This split is only used during output to reduce the number of patterns
10775 ;; that need assembler instructions adding to them.  We allowed the setting
10776 ;; of the conditions to be implicit during rtl generation so that
10777 ;; the conditional compare patterns would work.  However this conflicts to
10778 ;; some extent with the conditional data operations, so we have to split them
10779 ;; up again here.
10781 ;; ??? Need to audit these splitters for Thumb-2.  Why isn't normal
10782 ;; conditional execution sufficient?
10784 (define_split
10785   [(set (match_operand:SI 0 "s_register_operand" "")
10786         (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10787                           [(match_operand 2 "" "") (match_operand 3 "" "")])
10788                          (match_dup 0)
10789                          (match_operand 4 "" "")))
10790    (clobber (reg:CC CC_REGNUM))]
10791   "TARGET_ARM && reload_completed"
10792   [(set (match_dup 5) (match_dup 6))
10793    (cond_exec (match_dup 7)
10794               (set (match_dup 0) (match_dup 4)))]
10795   "
10796   {
10797     machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10798                                              operands[2], operands[3]);
10799     enum rtx_code rc = GET_CODE (operands[1]);
10801     operands[5] = gen_rtx_REG (mode, CC_REGNUM);
10802     operands[6] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10803     if (mode == CCFPmode || mode == CCFPEmode)
10804       rc = reverse_condition_maybe_unordered (rc);
10805     else
10806       rc = reverse_condition (rc);
10808     operands[7] = gen_rtx_fmt_ee (rc, VOIDmode, operands[5], const0_rtx);
10809   }"
10812 (define_split
10813   [(set (match_operand:SI 0 "s_register_operand" "")
10814         (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10815                           [(match_operand 2 "" "") (match_operand 3 "" "")])
10816                          (match_operand 4 "" "")
10817                          (match_dup 0)))
10818    (clobber (reg:CC CC_REGNUM))]
10819   "TARGET_ARM && reload_completed"
10820   [(set (match_dup 5) (match_dup 6))
10821    (cond_exec (match_op_dup 1 [(match_dup 5) (const_int 0)])
10822               (set (match_dup 0) (match_dup 4)))]
10823   "
10824   {
10825     machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10826                                              operands[2], operands[3]);
10828     operands[5] = gen_rtx_REG (mode, CC_REGNUM);
10829     operands[6] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10830   }"
10833 (define_split
10834   [(set (match_operand:SI 0 "s_register_operand" "")
10835         (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10836                           [(match_operand 2 "" "") (match_operand 3 "" "")])
10837                          (match_operand 4 "" "")
10838                          (match_operand 5 "" "")))
10839    (clobber (reg:CC CC_REGNUM))]
10840   "TARGET_ARM && reload_completed"
10841   [(set (match_dup 6) (match_dup 7))
10842    (cond_exec (match_op_dup 1 [(match_dup 6) (const_int 0)])
10843               (set (match_dup 0) (match_dup 4)))
10844    (cond_exec (match_dup 8)
10845               (set (match_dup 0) (match_dup 5)))]
10846   "
10847   {
10848     machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10849                                              operands[2], operands[3]);
10850     enum rtx_code rc = GET_CODE (operands[1]);
10852     operands[6] = gen_rtx_REG (mode, CC_REGNUM);
10853     operands[7] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10854     if (mode == CCFPmode || mode == CCFPEmode)
10855       rc = reverse_condition_maybe_unordered (rc);
10856     else
10857       rc = reverse_condition (rc);
10859     operands[8] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
10860   }"
10863 (define_split
10864   [(set (match_operand:SI 0 "s_register_operand" "")
10865         (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10866                           [(match_operand:SI 2 "s_register_operand" "")
10867                            (match_operand:SI 3 "arm_add_operand" "")])
10868                          (match_operand:SI 4 "arm_rhs_operand" "")
10869                          (not:SI
10870                           (match_operand:SI 5 "s_register_operand" ""))))
10871    (clobber (reg:CC CC_REGNUM))]
10872   "TARGET_ARM && reload_completed"
10873   [(set (match_dup 6) (match_dup 7))
10874    (cond_exec (match_op_dup 1 [(match_dup 6) (const_int 0)])
10875               (set (match_dup 0) (match_dup 4)))
10876    (cond_exec (match_dup 8)
10877               (set (match_dup 0) (not:SI (match_dup 5))))]
10878   "
10879   {
10880     machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10881                                              operands[2], operands[3]);
10882     enum rtx_code rc = GET_CODE (operands[1]);
10884     operands[6] = gen_rtx_REG (mode, CC_REGNUM);
10885     operands[7] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10886     if (mode == CCFPmode || mode == CCFPEmode)
10887       rc = reverse_condition_maybe_unordered (rc);
10888     else
10889       rc = reverse_condition (rc);
10891     operands[8] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
10892   }"
10895 (define_insn "*cond_move_not"
10896   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10897         (if_then_else:SI (match_operator 4 "arm_comparison_operator"
10898                           [(match_operand 3 "cc_register" "") (const_int 0)])
10899                          (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
10900                          (not:SI
10901                           (match_operand:SI 2 "s_register_operand" "r,r"))))]
10902   "TARGET_ARM"
10903   "@
10904    mvn%D4\\t%0, %2
10905    mov%d4\\t%0, %1\;mvn%D4\\t%0, %2"
10906   [(set_attr "conds" "use")
10907    (set_attr "type" "mvn_reg,multiple")
10908    (set_attr "length" "4,8")]
10911 ;; The next two patterns occur when an AND operation is followed by a
10912 ;; scc insn sequence 
10914 (define_insn "*sign_extract_onebit"
10915   [(set (match_operand:SI 0 "s_register_operand" "=r")
10916         (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
10917                          (const_int 1)
10918                          (match_operand:SI 2 "const_int_operand" "n")))
10919     (clobber (reg:CC CC_REGNUM))]
10920   "TARGET_ARM"
10921   "*
10922     operands[2] = GEN_INT (1 << INTVAL (operands[2]));
10923     output_asm_insn (\"ands\\t%0, %1, %2\", operands);
10924     return \"mvnne\\t%0, #0\";
10925   "
10926   [(set_attr "conds" "clob")
10927    (set_attr "length" "8")
10928    (set_attr "type" "multiple")]
10931 (define_insn "*not_signextract_onebit"
10932   [(set (match_operand:SI 0 "s_register_operand" "=r")
10933         (not:SI
10934          (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
10935                           (const_int 1)
10936                           (match_operand:SI 2 "const_int_operand" "n"))))
10937    (clobber (reg:CC CC_REGNUM))]
10938   "TARGET_ARM"
10939   "*
10940     operands[2] = GEN_INT (1 << INTVAL (operands[2]));
10941     output_asm_insn (\"tst\\t%1, %2\", operands);
10942     output_asm_insn (\"mvneq\\t%0, #0\", operands);
10943     return \"movne\\t%0, #0\";
10944   "
10945   [(set_attr "conds" "clob")
10946    (set_attr "length" "12")
10947    (set_attr "type" "multiple")]
10949 ;; ??? The above patterns need auditing for Thumb-2
10951 ;; Push multiple registers to the stack.  Registers are in parallel (use ...)
10952 ;; expressions.  For simplicity, the first register is also in the unspec
10953 ;; part.
10954 ;; To avoid the usage of GNU extension, the length attribute is computed
10955 ;; in a C function arm_attr_length_push_multi.
10956 (define_insn "*push_multi"
10957   [(match_parallel 2 "multi_register_push"
10958     [(set (match_operand:BLK 0 "push_mult_memory_operand" "")
10959           (unspec:BLK [(match_operand:SI 1 "s_register_operand" "")]
10960                       UNSPEC_PUSH_MULT))])]
10961   ""
10962   "*
10963   {
10964     int num_saves = XVECLEN (operands[2], 0);
10965      
10966     /* For the StrongARM at least it is faster to
10967        use STR to store only a single register.
10968        In Thumb mode always use push, and the assembler will pick
10969        something appropriate.  */
10970     if (num_saves == 1 && TARGET_ARM)
10971       output_asm_insn (\"str%?\\t%1, [%m0, #-4]!\", operands);
10972     else
10973       {
10974         int i;
10975         char pattern[100];
10977         if (TARGET_32BIT)
10978             strcpy (pattern, \"push%?\\t{%1\");
10979         else
10980             strcpy (pattern, \"push\\t{%1\");
10982         for (i = 1; i < num_saves; i++)
10983           {
10984             strcat (pattern, \", %|\");
10985             strcat (pattern,
10986                     reg_names[REGNO (XEXP (XVECEXP (operands[2], 0, i), 0))]);
10987           }
10989         strcat (pattern, \"}\");
10990         output_asm_insn (pattern, operands);
10991       }
10993     return \"\";
10994   }"
10995   [(set_attr "type" "store_16")
10996    (set (attr "length")
10997         (symbol_ref "arm_attr_length_push_multi (operands[2], operands[1])"))]
11000 (define_insn "stack_tie"
11001   [(set (mem:BLK (scratch))
11002         (unspec:BLK [(match_operand:SI 0 "s_register_operand" "rk")
11003                      (match_operand:SI 1 "s_register_operand" "rk")]
11004                     UNSPEC_PRLG_STK))]
11005   ""
11006   ""
11007   [(set_attr "length" "0")
11008    (set_attr "type" "block")]
11011 ;; Pop (as used in epilogue RTL)
11013 (define_insn "*load_multiple_with_writeback"
11014   [(match_parallel 0 "load_multiple_operation"
11015     [(set (match_operand:SI 1 "s_register_operand" "+rk")
11016           (plus:SI (match_dup 1)
11017                    (match_operand:SI 2 "const_int_I_operand" "I")))
11018      (set (match_operand:SI 3 "s_register_operand" "=rk")
11019           (mem:SI (match_dup 1)))
11020         ])]
11021   "TARGET_32BIT && (reload_in_progress || reload_completed)"
11022   "*
11023   {
11024     arm_output_multireg_pop (operands, /*return_pc=*/false,
11025                                        /*cond=*/const_true_rtx,
11026                                        /*reverse=*/false,
11027                                        /*update=*/true);
11028     return \"\";
11029   }
11030   "
11031   [(set_attr "type" "load_16")
11032    (set_attr "predicable" "yes")
11033    (set (attr "length")
11034         (symbol_ref "arm_attr_length_pop_multi (operands,
11035                                                 /*return_pc=*/false,
11036                                                 /*write_back_p=*/true)"))]
11039 ;; Pop with return (as used in epilogue RTL)
11041 ;; This instruction is generated when the registers are popped at the end of
11042 ;; epilogue.  Here, instead of popping the value into LR and then generating
11043 ;; jump to LR, value is popped into PC directly.  Hence, the pattern is combined
11044 ;;  with (return).
11045 (define_insn "*pop_multiple_with_writeback_and_return"
11046   [(match_parallel 0 "pop_multiple_return"
11047     [(return)
11048      (set (match_operand:SI 1 "s_register_operand" "+rk")
11049           (plus:SI (match_dup 1)
11050                    (match_operand:SI 2 "const_int_I_operand" "I")))
11051      (set (match_operand:SI 3 "s_register_operand" "=rk")
11052           (mem:SI (match_dup 1)))
11053         ])]
11054   "TARGET_32BIT && (reload_in_progress || reload_completed)"
11055   "*
11056   {
11057     arm_output_multireg_pop (operands, /*return_pc=*/true,
11058                                        /*cond=*/const_true_rtx,
11059                                        /*reverse=*/false,
11060                                        /*update=*/true);
11061     return \"\";
11062   }
11063   "
11064   [(set_attr "type" "load_16")
11065    (set_attr "predicable" "yes")
11066    (set (attr "length")
11067         (symbol_ref "arm_attr_length_pop_multi (operands, /*return_pc=*/true,
11068                                                 /*write_back_p=*/true)"))]
11071 (define_insn "*pop_multiple_with_return"
11072   [(match_parallel 0 "pop_multiple_return"
11073     [(return)
11074      (set (match_operand:SI 2 "s_register_operand" "=rk")
11075           (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
11076         ])]
11077   "TARGET_32BIT && (reload_in_progress || reload_completed)"
11078   "*
11079   {
11080     arm_output_multireg_pop (operands, /*return_pc=*/true,
11081                                        /*cond=*/const_true_rtx,
11082                                        /*reverse=*/false,
11083                                        /*update=*/false);
11084     return \"\";
11085   }
11086   "
11087   [(set_attr "type" "load_16")
11088    (set_attr "predicable" "yes")
11089    (set (attr "length")
11090         (symbol_ref "arm_attr_length_pop_multi (operands, /*return_pc=*/true,
11091                                                 /*write_back_p=*/false)"))]
11094 ;; Load into PC and return
11095 (define_insn "*ldr_with_return"
11096   [(return)
11097    (set (reg:SI PC_REGNUM)
11098         (mem:SI (post_inc:SI (match_operand:SI 0 "s_register_operand" "+rk"))))]
11099   "TARGET_32BIT && (reload_in_progress || reload_completed)"
11100   "ldr%?\t%|pc, [%0], #4"
11101   [(set_attr "type" "load_4")
11102    (set_attr "predicable" "yes")]
11104 ;; Pop for floating point registers (as used in epilogue RTL)
11105 (define_insn "*vfp_pop_multiple_with_writeback"
11106   [(match_parallel 0 "pop_multiple_fp"
11107     [(set (match_operand:SI 1 "s_register_operand" "+rk")
11108           (plus:SI (match_dup 1)
11109                    (match_operand:SI 2 "const_int_I_operand" "I")))
11110      (set (match_operand:DF 3 "vfp_hard_register_operand" "")
11111           (mem:DF (match_dup 1)))])]
11112   "TARGET_32BIT && TARGET_HARD_FLOAT"
11113   "*
11114   {
11115     int num_regs = XVECLEN (operands[0], 0);
11116     char pattern[100];
11117     rtx op_list[2];
11118     strcpy (pattern, \"vldm\\t\");
11119     strcat (pattern, reg_names[REGNO (SET_DEST (XVECEXP (operands[0], 0, 0)))]);
11120     strcat (pattern, \"!, {\");
11121     op_list[0] = XEXP (XVECEXP (operands[0], 0, 1), 0);
11122     strcat (pattern, \"%P0\");
11123     if ((num_regs - 1) > 1)
11124       {
11125         strcat (pattern, \"-%P1\");
11126         op_list [1] = XEXP (XVECEXP (operands[0], 0, num_regs - 1), 0);
11127       }
11129     strcat (pattern, \"}\");
11130     output_asm_insn (pattern, op_list);
11131     return \"\";
11132   }
11133   "
11134   [(set_attr "type" "load_16")
11135    (set_attr "conds" "unconditional")
11136    (set_attr "predicable" "no")]
11139 ;; Special patterns for dealing with the constant pool
11141 (define_insn "align_4"
11142   [(unspec_volatile [(const_int 0)] VUNSPEC_ALIGN)]
11143   "TARGET_EITHER"
11144   "*
11145   assemble_align (32);
11146   return \"\";
11147   "
11148   [(set_attr "type" "no_insn")]
11151 (define_insn "align_8"
11152   [(unspec_volatile [(const_int 0)] VUNSPEC_ALIGN8)]
11153   "TARGET_EITHER"
11154   "*
11155   assemble_align (64);
11156   return \"\";
11157   "
11158   [(set_attr "type" "no_insn")]
11161 (define_insn "consttable_end"
11162   [(unspec_volatile [(const_int 0)] VUNSPEC_POOL_END)]
11163   "TARGET_EITHER"
11164   "*
11165   making_const_table = FALSE;
11166   return \"\";
11167   "
11168   [(set_attr "type" "no_insn")]
11171 (define_insn "consttable_1"
11172   [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_1)]
11173   "TARGET_EITHER"
11174   "*
11175   making_const_table = TRUE;
11176   assemble_integer (operands[0], 1, BITS_PER_WORD, 1);
11177   assemble_zeros (3);
11178   return \"\";
11179   "
11180   [(set_attr "length" "4")
11181    (set_attr "type" "no_insn")]
11184 (define_insn "consttable_2"
11185   [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_2)]
11186   "TARGET_EITHER"
11187   "*
11188   {
11189     rtx x = operands[0];
11190     making_const_table = TRUE;
11191     switch (GET_MODE_CLASS (GET_MODE (x)))
11192       {
11193       case MODE_FLOAT:
11194         arm_emit_fp16_const (x);
11195         break;
11196       default:
11197         assemble_integer (operands[0], 2, BITS_PER_WORD, 1);
11198         assemble_zeros (2);
11199         break;
11200       }
11201     return \"\";
11202   }"
11203   [(set_attr "length" "4")
11204    (set_attr "type" "no_insn")]
11207 (define_insn "consttable_4"
11208   [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_4)]
11209   "TARGET_EITHER"
11210   "*
11211   {
11212     rtx x = operands[0];
11213     making_const_table = TRUE;
11214     scalar_float_mode float_mode;
11215     if (is_a <scalar_float_mode> (GET_MODE (x), &float_mode))
11216       assemble_real (*CONST_DOUBLE_REAL_VALUE (x), float_mode, BITS_PER_WORD);
11217     else
11218       {
11219         /* XXX: Sometimes gcc does something really dumb and ends up with
11220            a HIGH in a constant pool entry, usually because it's trying to
11221            load into a VFP register.  We know this will always be used in
11222            combination with a LO_SUM which ignores the high bits, so just
11223            strip off the HIGH.  */
11224         if (GET_CODE (x) == HIGH)
11225           x = XEXP (x, 0);
11226         assemble_integer (x, 4, BITS_PER_WORD, 1);
11227         mark_symbol_refs_as_used (x);
11228       }
11229     return \"\";
11230   }"
11231   [(set_attr "length" "4")
11232    (set_attr "type" "no_insn")]
11235 (define_insn "consttable_8"
11236   [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_8)]
11237   "TARGET_EITHER"
11238   "*
11239   {
11240     making_const_table = TRUE;
11241     scalar_float_mode float_mode;
11242     if (is_a <scalar_float_mode> (GET_MODE (operands[0]), &float_mode))
11243       assemble_real (*CONST_DOUBLE_REAL_VALUE (operands[0]),
11244                      float_mode, BITS_PER_WORD);
11245     else
11246       assemble_integer (operands[0], 8, BITS_PER_WORD, 1);
11247     return \"\";
11248   }"
11249   [(set_attr "length" "8")
11250    (set_attr "type" "no_insn")]
11253 (define_insn "consttable_16"
11254   [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_16)]
11255   "TARGET_EITHER"
11256   "*
11257   {
11258     making_const_table = TRUE;
11259     scalar_float_mode float_mode;
11260     if (is_a <scalar_float_mode> (GET_MODE (operands[0]), &float_mode))
11261       assemble_real (*CONST_DOUBLE_REAL_VALUE (operands[0]),
11262                      float_mode, BITS_PER_WORD);
11263     else
11264       assemble_integer (operands[0], 16, BITS_PER_WORD, 1);
11265     return \"\";
11266   }"
11267   [(set_attr "length" "16")
11268    (set_attr "type" "no_insn")]
11271 ;; V5 Instructions,
11273 (define_insn "clzsi2"
11274   [(set (match_operand:SI 0 "s_register_operand" "=r")
11275         (clz:SI (match_operand:SI 1 "s_register_operand" "r")))]
11276   "TARGET_32BIT && arm_arch5t"
11277   "clz%?\\t%0, %1"
11278   [(set_attr "predicable" "yes")
11279    (set_attr "type" "clz")])
11281 (define_insn "rbitsi2"
11282   [(set (match_operand:SI 0 "s_register_operand" "=r")
11283         (unspec:SI [(match_operand:SI 1 "s_register_operand" "r")] UNSPEC_RBIT))]
11284   "TARGET_32BIT && arm_arch_thumb2"
11285   "rbit%?\\t%0, %1"
11286   [(set_attr "predicable" "yes")
11287    (set_attr "type" "clz")])
11289 ;; Keep this as a CTZ expression until after reload and then split
11290 ;; into RBIT + CLZ.  Since RBIT is represented as an UNSPEC it is unlikely
11291 ;; to fold with any other expression.
11293 (define_insn_and_split "ctzsi2"
11294  [(set (match_operand:SI           0 "s_register_operand" "=r")
11295        (ctz:SI (match_operand:SI  1 "s_register_operand" "r")))]
11296   "TARGET_32BIT && arm_arch_thumb2"
11297   "#"
11298   "&& reload_completed"
11299   [(const_int 0)]
11300   "
11301   emit_insn (gen_rbitsi2 (operands[0], operands[1]));
11302   emit_insn (gen_clzsi2 (operands[0], operands[0]));
11303   DONE;
11306 ;; V5E instructions.
11308 (define_insn "prefetch"
11309   [(prefetch (match_operand:SI 0 "address_operand" "p")
11310              (match_operand:SI 1 "" "")
11311              (match_operand:SI 2 "" ""))]
11312   "TARGET_32BIT && arm_arch5te"
11313   "pld\\t%a0"
11314   [(set_attr "type" "load_4")]
11317 ;; General predication pattern
11319 (define_cond_exec
11320   [(match_operator 0 "arm_comparison_operator"
11321     [(match_operand 1 "cc_register" "")
11322      (const_int 0)])]
11323   "TARGET_32BIT
11324    && (!TARGET_NO_VOLATILE_CE || !volatile_refs_p (PATTERN (insn)))"
11325   ""
11326 [(set_attr "predicated" "yes")]
11329 (define_insn "force_register_use"
11330   [(unspec:SI [(match_operand:SI 0 "register_operand" "")] UNSPEC_REGISTER_USE)]
11331   ""
11332   "%@ %0 needed"
11333   [(set_attr "length" "0")
11334    (set_attr "type" "no_insn")]
11338 ;; Patterns for exception handling
11340 (define_expand "eh_return"
11341   [(use (match_operand 0 "general_operand" ""))]
11342   "TARGET_EITHER"
11343   "
11344   {
11345     if (TARGET_32BIT)
11346       emit_insn (gen_arm_eh_return (operands[0]));
11347     else
11348       emit_insn (gen_thumb_eh_return (operands[0]));
11349     DONE;
11350   }"
11352                                    
11353 ;; We can't expand this before we know where the link register is stored.
11354 (define_insn_and_split "arm_eh_return"
11355   [(unspec_volatile [(match_operand:SI 0 "s_register_operand" "r")]
11356                     VUNSPEC_EH_RETURN)
11357    (clobber (match_scratch:SI 1 "=&r"))]
11358   "TARGET_ARM"
11359   "#"
11360   "&& reload_completed"
11361   [(const_int 0)]
11362   "
11363   {
11364     arm_set_return_address (operands[0], operands[1]);
11365     DONE;
11366   }"
11370 ;; TLS support
11372 (define_insn "load_tp_hard"
11373   [(set (match_operand:SI 0 "register_operand" "=r")
11374         (unspec:SI [(const_int 0)] UNSPEC_TLS))]
11375   "TARGET_HARD_TP"
11376   "mrc%?\\tp15, 0, %0, c13, c0, 3\\t@ load_tp_hard"
11377   [(set_attr "predicable" "yes")
11378    (set_attr "type" "mrs")]
11381 ;; Doesn't clobber R1-R3.  Must use r0 for the first operand.
11382 (define_insn "load_tp_soft"
11383   [(set (reg:SI 0) (unspec:SI [(const_int 0)] UNSPEC_TLS))
11384    (clobber (reg:SI LR_REGNUM))
11385    (clobber (reg:SI IP_REGNUM))
11386    (clobber (reg:CC CC_REGNUM))]
11387   "TARGET_SOFT_TP"
11388   "bl\\t__aeabi_read_tp\\t@ load_tp_soft"
11389   [(set_attr "conds" "clob")
11390    (set_attr "type" "branch")]
11393 ;; tls descriptor call
11394 (define_insn "tlscall"
11395   [(set (reg:SI R0_REGNUM)
11396         (unspec:SI [(reg:SI R0_REGNUM)
11397                     (match_operand:SI 0 "" "X")
11398                     (match_operand 1 "" "")] UNSPEC_TLS))
11399    (clobber (reg:SI R1_REGNUM))
11400    (clobber (reg:SI LR_REGNUM))
11401    (clobber (reg:SI CC_REGNUM))]
11402   "TARGET_GNU2_TLS"
11403   {
11404     targetm.asm_out.internal_label (asm_out_file, "LPIC",
11405                                     INTVAL (operands[1]));
11406     return "bl\\t%c0(tlscall)";
11407   }
11408   [(set_attr "conds" "clob")
11409    (set_attr "length" "4")
11410    (set_attr "type" "branch")]
11413 ;; For thread pointer builtin
11414 (define_expand "get_thread_pointersi"
11415   [(match_operand:SI 0 "s_register_operand" "=r")]
11416  ""
11419    arm_load_tp (operands[0]);
11420    DONE;
11421  }")
11425 ;; We only care about the lower 16 bits of the constant 
11426 ;; being inserted into the upper 16 bits of the register.
11427 (define_insn "*arm_movtas_ze" 
11428   [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r,r")
11429                    (const_int 16)
11430                    (const_int 16))
11431         (match_operand:SI 1 "const_int_operand" ""))]
11432   "TARGET_HAVE_MOVT"
11433   "@
11434    movt%?\t%0, %L1
11435    movt\t%0, %L1"
11436  [(set_attr "arch" "32,v8mb")
11437   (set_attr "predicable" "yes")
11438   (set_attr "length" "4")
11439   (set_attr "type" "alu_sreg")]
11442 (define_insn "*arm_rev"
11443   [(set (match_operand:SI 0 "s_register_operand" "=l,l,r")
11444         (bswap:SI (match_operand:SI 1 "s_register_operand" "l,l,r")))]
11445   "arm_arch6"
11446   "@
11447    rev\t%0, %1
11448    rev%?\t%0, %1
11449    rev%?\t%0, %1"
11450   [(set_attr "arch" "t1,t2,32")
11451    (set_attr "length" "2,2,4")
11452    (set_attr "predicable" "no,yes,yes")
11453    (set_attr "type" "rev")]
11456 (define_expand "arm_legacy_rev"
11457   [(set (match_operand:SI 2 "s_register_operand" "")
11458         (xor:SI (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
11459                              (const_int 16))
11460                 (match_dup 1)))
11461    (set (match_dup 2)
11462         (lshiftrt:SI (match_dup 2)
11463                      (const_int 8)))
11464    (set (match_operand:SI 3 "s_register_operand" "")
11465         (rotatert:SI (match_dup 1)
11466                      (const_int 8)))
11467    (set (match_dup 2)
11468         (and:SI (match_dup 2)
11469                 (const_int -65281)))
11470    (set (match_operand:SI 0 "s_register_operand" "")
11471         (xor:SI (match_dup 3)
11472                 (match_dup 2)))]
11473   "TARGET_32BIT"
11474   ""
11477 ;; Reuse temporaries to keep register pressure down.
11478 (define_expand "thumb_legacy_rev"
11479   [(set (match_operand:SI 2 "s_register_operand" "")
11480      (ashift:SI (match_operand:SI 1 "s_register_operand" "")
11481                 (const_int 24)))
11482    (set (match_operand:SI 3 "s_register_operand" "")
11483      (lshiftrt:SI (match_dup 1)
11484                   (const_int 24)))
11485    (set (match_dup 3)
11486      (ior:SI (match_dup 3)
11487              (match_dup 2)))
11488    (set (match_operand:SI 4 "s_register_operand" "")
11489      (const_int 16))
11490    (set (match_operand:SI 5 "s_register_operand" "")
11491      (rotatert:SI (match_dup 1)
11492                   (match_dup 4)))
11493    (set (match_dup 2)
11494      (ashift:SI (match_dup 5)
11495                 (const_int 24)))
11496    (set (match_dup 5)
11497      (lshiftrt:SI (match_dup 5)
11498                   (const_int 24)))
11499    (set (match_dup 5)
11500      (ior:SI (match_dup 5)
11501              (match_dup 2)))
11502    (set (match_dup 5)
11503      (rotatert:SI (match_dup 5)
11504                   (match_dup 4)))
11505    (set (match_operand:SI 0 "s_register_operand" "")
11506      (ior:SI (match_dup 5)
11507              (match_dup 3)))]
11508   "TARGET_THUMB"
11509   ""
11512 ;; ARM-specific expansion of signed mod by power of 2
11513 ;; using conditional negate.
11514 ;; For r0 % n where n is a power of 2 produce:
11515 ;; rsbs    r1, r0, #0
11516 ;; and     r0, r0, #(n - 1)
11517 ;; and     r1, r1, #(n - 1)
11518 ;; rsbpl   r0, r1, #0
11520 (define_expand "modsi3"
11521   [(match_operand:SI 0 "register_operand" "")
11522    (match_operand:SI 1 "register_operand" "")
11523    (match_operand:SI 2 "const_int_operand" "")]
11524   "TARGET_32BIT"
11525   {
11526     HOST_WIDE_INT val = INTVAL (operands[2]);
11528     if (val <= 0
11529        || exact_log2 (val) <= 0)
11530       FAIL;
11532     rtx mask = GEN_INT (val - 1);
11534     /* In the special case of x0 % 2 we can do the even shorter:
11535         cmp     r0, #0
11536         and     r0, r0, #1
11537         rsblt   r0, r0, #0.  */
11539     if (val == 2)
11540       {
11541         rtx cc_reg = arm_gen_compare_reg (LT,
11542                                           operands[1], const0_rtx, NULL_RTX);
11543         rtx cond = gen_rtx_LT (SImode, cc_reg, const0_rtx);
11544         rtx masked = gen_reg_rtx (SImode);
11546         emit_insn (gen_andsi3 (masked, operands[1], mask));
11547         emit_move_insn (operands[0],
11548                         gen_rtx_IF_THEN_ELSE (SImode, cond,
11549                                               gen_rtx_NEG (SImode,
11550                                                            masked),
11551                                               masked));
11552         DONE;
11553       }
11555     rtx neg_op = gen_reg_rtx (SImode);
11556     rtx_insn *insn = emit_insn (gen_subsi3_compare0 (neg_op, const0_rtx,
11557                                                       operands[1]));
11559     /* Extract the condition register and mode.  */
11560     rtx cmp = XVECEXP (PATTERN (insn), 0, 0);
11561     rtx cc_reg = SET_DEST (cmp);
11562     rtx cond = gen_rtx_GE (SImode, cc_reg, const0_rtx);
11564     emit_insn (gen_andsi3 (operands[0], operands[1], mask));
11566     rtx masked_neg = gen_reg_rtx (SImode);
11567     emit_insn (gen_andsi3 (masked_neg, neg_op, mask));
11569     /* We want a conditional negate here, but emitting COND_EXEC rtxes
11570        during expand does not always work.  Do an IF_THEN_ELSE instead.  */
11571     emit_move_insn (operands[0],
11572                     gen_rtx_IF_THEN_ELSE (SImode, cond,
11573                                           gen_rtx_NEG (SImode, masked_neg),
11574                                           operands[0]));
11577     DONE;
11578   }
11581 (define_expand "bswapsi2"
11582   [(set (match_operand:SI 0 "s_register_operand" "=r")
11583         (bswap:SI (match_operand:SI 1 "s_register_operand" "r")))]
11584 "TARGET_EITHER && (arm_arch6 || !optimize_size)"
11586     if (!arm_arch6)
11587       {
11588         rtx op2 = gen_reg_rtx (SImode);
11589         rtx op3 = gen_reg_rtx (SImode);
11591         if (TARGET_THUMB)
11592           {
11593             rtx op4 = gen_reg_rtx (SImode);
11594             rtx op5 = gen_reg_rtx (SImode);
11596             emit_insn (gen_thumb_legacy_rev (operands[0], operands[1],
11597                                              op2, op3, op4, op5));
11598           }
11599         else
11600           {
11601             emit_insn (gen_arm_legacy_rev (operands[0], operands[1],
11602                                            op2, op3));
11603           }
11605         DONE;
11606       }
11607   "
11610 ;; bswap16 patterns: use revsh and rev16 instructions for the signed
11611 ;; and unsigned variants, respectively. For rev16, expose
11612 ;; byte-swapping in the lower 16 bits only.
11613 (define_insn "*arm_revsh"
11614   [(set (match_operand:SI 0 "s_register_operand" "=l,l,r")
11615         (sign_extend:SI (bswap:HI (match_operand:HI 1 "s_register_operand" "l,l,r"))))]
11616   "arm_arch6"
11617   "@
11618   revsh\t%0, %1
11619   revsh%?\t%0, %1
11620   revsh%?\t%0, %1"
11621   [(set_attr "arch" "t1,t2,32")
11622    (set_attr "length" "2,2,4")
11623    (set_attr "type" "rev")]
11626 (define_insn "*arm_rev16"
11627   [(set (match_operand:HI 0 "s_register_operand" "=l,l,r")
11628         (bswap:HI (match_operand:HI 1 "s_register_operand" "l,l,r")))]
11629   "arm_arch6"
11630   "@
11631    rev16\t%0, %1
11632    rev16%?\t%0, %1
11633    rev16%?\t%0, %1"
11634   [(set_attr "arch" "t1,t2,32")
11635    (set_attr "length" "2,2,4")
11636    (set_attr "type" "rev")]
11639 ;; There are no canonicalisation rules for the position of the lshiftrt, ashift
11640 ;; operations within an IOR/AND RTX, therefore we have two patterns matching
11641 ;; each valid permutation.
11643 (define_insn "arm_rev16si2"
11644   [(set (match_operand:SI 0 "register_operand" "=l,l,r")
11645         (ior:SI (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "l,l,r")
11646                                    (const_int 8))
11647                         (match_operand:SI 3 "const_int_operand" "n,n,n"))
11648                 (and:SI (lshiftrt:SI (match_dup 1)
11649                                      (const_int 8))
11650                         (match_operand:SI 2 "const_int_operand" "n,n,n"))))]
11651   "arm_arch6
11652    && aarch_rev16_shleft_mask_imm_p (operands[3], SImode)
11653    && aarch_rev16_shright_mask_imm_p (operands[2], SImode)"
11654   "rev16\\t%0, %1"
11655   [(set_attr "arch" "t1,t2,32")
11656    (set_attr "length" "2,2,4")
11657    (set_attr "type" "rev")]
11660 (define_insn "arm_rev16si2_alt"
11661   [(set (match_operand:SI 0 "register_operand" "=l,l,r")
11662         (ior:SI (and:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "l,l,r")
11663                                      (const_int 8))
11664                         (match_operand:SI 2 "const_int_operand" "n,n,n"))
11665                 (and:SI (ashift:SI (match_dup 1)
11666                                    (const_int 8))
11667                         (match_operand:SI 3 "const_int_operand" "n,n,n"))))]
11668   "arm_arch6
11669    && aarch_rev16_shleft_mask_imm_p (operands[3], SImode)
11670    && aarch_rev16_shright_mask_imm_p (operands[2], SImode)"
11671   "rev16\\t%0, %1"
11672   [(set_attr "arch" "t1,t2,32")
11673    (set_attr "length" "2,2,4")
11674    (set_attr "type" "rev")]
11677 (define_expand "bswaphi2"
11678   [(set (match_operand:HI 0 "s_register_operand" "=r")
11679         (bswap:HI (match_operand:HI 1 "s_register_operand" "r")))]
11680 "arm_arch6"
11684 ;; Patterns for LDRD/STRD in Thumb2 mode
11686 (define_insn "*thumb2_ldrd"
11687   [(set (match_operand:SI 0 "s_register_operand" "=r")
11688         (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "rk")
11689                          (match_operand:SI 2 "ldrd_strd_offset_operand" "Do"))))
11690    (set (match_operand:SI 3 "s_register_operand" "=r")
11691         (mem:SI (plus:SI (match_dup 1)
11692                          (match_operand:SI 4 "const_int_operand" ""))))]
11693   "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11694      && ((INTVAL (operands[2]) + 4) == INTVAL (operands[4]))
11695      && (operands_ok_ldrd_strd (operands[0], operands[3],
11696                                   operands[1], INTVAL (operands[2]),
11697                                   false, true))"
11698   "ldrd%?\t%0, %3, [%1, %2]"
11699   [(set_attr "type" "load_8")
11700    (set_attr "predicable" "yes")])
11702 (define_insn "*thumb2_ldrd_base"
11703   [(set (match_operand:SI 0 "s_register_operand" "=r")
11704         (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
11705    (set (match_operand:SI 2 "s_register_operand" "=r")
11706         (mem:SI (plus:SI (match_dup 1)
11707                          (const_int 4))))]
11708   "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11709      && (operands_ok_ldrd_strd (operands[0], operands[2],
11710                                   operands[1], 0, false, true))"
11711   "ldrd%?\t%0, %2, [%1]"
11712   [(set_attr "type" "load_8")
11713    (set_attr "predicable" "yes")])
11715 (define_insn "*thumb2_ldrd_base_neg"
11716   [(set (match_operand:SI 0 "s_register_operand" "=r")
11717         (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "rk")
11718                          (const_int -4))))
11719    (set (match_operand:SI 2 "s_register_operand" "=r")
11720         (mem:SI (match_dup 1)))]
11721   "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11722      && (operands_ok_ldrd_strd (operands[0], operands[2],
11723                                   operands[1], -4, false, true))"
11724   "ldrd%?\t%0, %2, [%1, #-4]"
11725   [(set_attr "type" "load_8")
11726    (set_attr "predicable" "yes")])
11728 (define_insn "*thumb2_strd"
11729   [(set (mem:SI (plus:SI (match_operand:SI 0 "s_register_operand" "rk")
11730                          (match_operand:SI 1 "ldrd_strd_offset_operand" "Do")))
11731         (match_operand:SI 2 "s_register_operand" "r"))
11732    (set (mem:SI (plus:SI (match_dup 0)
11733                          (match_operand:SI 3 "const_int_operand" "")))
11734         (match_operand:SI 4 "s_register_operand" "r"))]
11735   "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11736      && ((INTVAL (operands[1]) + 4) == INTVAL (operands[3]))
11737      && (operands_ok_ldrd_strd (operands[2], operands[4],
11738                                   operands[0], INTVAL (operands[1]),
11739                                   false, false))"
11740   "strd%?\t%2, %4, [%0, %1]"
11741   [(set_attr "type" "store_8")
11742    (set_attr "predicable" "yes")])
11744 (define_insn "*thumb2_strd_base"
11745   [(set (mem:SI (match_operand:SI 0 "s_register_operand" "rk"))
11746         (match_operand:SI 1 "s_register_operand" "r"))
11747    (set (mem:SI (plus:SI (match_dup 0)
11748                          (const_int 4)))
11749         (match_operand:SI 2 "s_register_operand" "r"))]
11750   "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11751      && (operands_ok_ldrd_strd (operands[1], operands[2],
11752                                   operands[0], 0, false, false))"
11753   "strd%?\t%1, %2, [%0]"
11754   [(set_attr "type" "store_8")
11755    (set_attr "predicable" "yes")])
11757 (define_insn "*thumb2_strd_base_neg"
11758   [(set (mem:SI (plus:SI (match_operand:SI 0 "s_register_operand" "rk")
11759                          (const_int -4)))
11760         (match_operand:SI 1 "s_register_operand" "r"))
11761    (set (mem:SI (match_dup 0))
11762         (match_operand:SI 2 "s_register_operand" "r"))]
11763   "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11764      && (operands_ok_ldrd_strd (operands[1], operands[2],
11765                                   operands[0], -4, false, false))"
11766   "strd%?\t%1, %2, [%0, #-4]"
11767   [(set_attr "type" "store_8")
11768    (set_attr "predicable" "yes")])
11770 ;; ARMv8 CRC32 instructions.
11771 (define_insn "<crc_variant>"
11772   [(set (match_operand:SI 0 "s_register_operand" "=r")
11773         (unspec:SI [(match_operand:SI 1 "s_register_operand" "r")
11774                     (match_operand:<crc_mode> 2 "s_register_operand" "r")]
11775          CRC))]
11776   "TARGET_CRC32"
11777   "<crc_variant>\\t%0, %1, %2"
11778   [(set_attr "type" "crc")
11779    (set_attr "conds" "unconditional")]
11782 ;; Load the load/store double peephole optimizations.
11783 (include "ldrdstrd.md")
11785 ;; Load the load/store multiple patterns
11786 (include "ldmstm.md")
11788 ;; Patterns in ldmstm.md don't cover more than 4 registers. This pattern covers
11789 ;; large lists without explicit writeback generated for APCS_FRAME epilogue.
11790 ;; The operands are validated through the load_multiple_operation
11791 ;; match_parallel predicate rather than through constraints so enable it only
11792 ;; after reload.
11793 (define_insn "*load_multiple"
11794   [(match_parallel 0 "load_multiple_operation"
11795     [(set (match_operand:SI 2 "s_register_operand" "=rk")
11796           (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
11797         ])]
11798   "TARGET_32BIT && reload_completed"
11799   "*
11800   {
11801     arm_output_multireg_pop (operands, /*return_pc=*/false,
11802                                        /*cond=*/const_true_rtx,
11803                                        /*reverse=*/false,
11804                                        /*update=*/false);
11805     return \"\";
11806   }
11807   "
11808   [(set_attr "predicable" "yes")]
11811 (define_expand "copysignsf3"
11812   [(match_operand:SF 0 "register_operand")
11813    (match_operand:SF 1 "register_operand")
11814    (match_operand:SF 2 "register_operand")]
11815   "TARGET_SOFT_FLOAT && arm_arch_thumb2"
11816   "{
11817      emit_move_insn (operands[0], operands[2]);
11818      emit_insn (gen_insv_t2 (simplify_gen_subreg (SImode, operands[0], SFmode, 0),
11819                 GEN_INT (31), GEN_INT (0),
11820                 simplify_gen_subreg (SImode, operands[1], SFmode, 0)));
11821      DONE;
11822   }"
11825 (define_expand "copysigndf3"
11826   [(match_operand:DF 0 "register_operand")
11827    (match_operand:DF 1 "register_operand")
11828    (match_operand:DF 2 "register_operand")]
11829   "TARGET_SOFT_FLOAT && arm_arch_thumb2"
11830   "{
11831      rtx op0_low = gen_lowpart (SImode, operands[0]);
11832      rtx op0_high = gen_highpart (SImode, operands[0]);
11833      rtx op1_low = gen_lowpart (SImode, operands[1]);
11834      rtx op1_high = gen_highpart (SImode, operands[1]);
11835      rtx op2_high = gen_highpart (SImode, operands[2]);
11837      rtx scratch1 = gen_reg_rtx (SImode);
11838      rtx scratch2 = gen_reg_rtx (SImode);
11839      emit_move_insn (scratch1, op2_high);
11840      emit_move_insn (scratch2, op1_high);
11842      emit_insn(gen_rtx_SET(scratch1,
11843                            gen_rtx_LSHIFTRT (SImode, op2_high, GEN_INT(31))));
11844      emit_insn(gen_insv_t2(scratch2, GEN_INT(1), GEN_INT(31), scratch1));
11845      emit_move_insn (op0_low, op1_low);
11846      emit_move_insn (op0_high, scratch2);
11848      DONE;
11849   }"
11852 ;; movmisalign patterns for HImode and SImode.
11853 (define_expand "movmisalign<mode>"
11854   [(match_operand:HSI 0 "general_operand")
11855    (match_operand:HSI 1 "general_operand")]
11856   "unaligned_access"
11858   /* This pattern is not permitted to fail during expansion: if both arguments
11859      are non-registers (e.g. memory := constant), force operand 1 into a
11860      register.  */
11861   rtx (* gen_unaligned_load)(rtx, rtx);
11862   rtx tmp_dest = operands[0];
11863   if (!s_register_operand (operands[0], <MODE>mode)
11864       && !s_register_operand (operands[1], <MODE>mode))
11865     operands[1] = force_reg (<MODE>mode, operands[1]);
11867   if (<MODE>mode == HImode)
11868    {
11869     gen_unaligned_load = gen_unaligned_loadhiu;
11870     tmp_dest = gen_reg_rtx (SImode);
11871    }
11872   else
11873     gen_unaligned_load = gen_unaligned_loadsi;
11875   if (MEM_P (operands[1]))
11876    {
11877     emit_insn (gen_unaligned_load (tmp_dest, operands[1]));
11878     if (<MODE>mode == HImode)
11879       emit_move_insn (operands[0], gen_lowpart (HImode, tmp_dest));
11880    }
11881   else
11882     emit_insn (gen_unaligned_store<mode> (operands[0], operands[1]));
11884   DONE;
11887 (define_insn "<cdp>"
11888   [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "n")
11889                      (match_operand:SI 1 "immediate_operand" "n")
11890                      (match_operand:SI 2 "immediate_operand" "n")
11891                      (match_operand:SI 3 "immediate_operand" "n")
11892                      (match_operand:SI 4 "immediate_operand" "n")
11893                      (match_operand:SI 5 "immediate_operand" "n")] CDPI)]
11894   "arm_coproc_builtin_available (VUNSPEC_<CDP>)"
11896   arm_const_bounds (operands[0], 0, 16);
11897   arm_const_bounds (operands[1], 0, 16);
11898   arm_const_bounds (operands[2], 0, (1 << 5));
11899   arm_const_bounds (operands[3], 0, (1 << 5));
11900   arm_const_bounds (operands[4], 0, (1 << 5));
11901   arm_const_bounds (operands[5], 0, 8);
11902   return "<cdp>\\tp%c0, %1, CR%c2, CR%c3, CR%c4, %5";
11904   [(set_attr "length" "4")
11905    (set_attr "type" "coproc")])
11907 (define_insn "*ldc"
11908   [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "n")
11909                      (match_operand:SI 1 "immediate_operand" "n")
11910                      (match_operand:SI 2 "memory_operand" "Uz")] LDCI)]
11911   "arm_coproc_builtin_available (VUNSPEC_<LDC>)"
11913   arm_const_bounds (operands[0], 0, 16);
11914   arm_const_bounds (operands[1], 0, (1 << 5));
11915   return "<ldc>\\tp%c0, CR%c1, %2";
11917   [(set_attr "length" "4")
11918    (set_attr "type" "coproc")])
11920 (define_insn "*stc"
11921   [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "n")
11922                      (match_operand:SI 1 "immediate_operand" "n")
11923                      (match_operand:SI 2 "memory_operand" "=Uz")] STCI)]
11924   "arm_coproc_builtin_available (VUNSPEC_<STC>)"
11926   arm_const_bounds (operands[0], 0, 16);
11927   arm_const_bounds (operands[1], 0, (1 << 5));
11928   return "<stc>\\tp%c0, CR%c1, %2";
11930   [(set_attr "length" "4")
11931    (set_attr "type" "coproc")])
11933 (define_expand "<ldc>"
11934   [(unspec_volatile [(match_operand:SI 0 "immediate_operand")
11935                      (match_operand:SI 1 "immediate_operand")
11936                      (mem:SI (match_operand:SI 2 "s_register_operand"))] LDCI)]
11937   "arm_coproc_builtin_available (VUNSPEC_<LDC>)")
11939 (define_expand "<stc>"
11940   [(unspec_volatile [(match_operand:SI 0 "immediate_operand")
11941                      (match_operand:SI 1 "immediate_operand")
11942                      (mem:SI (match_operand:SI 2 "s_register_operand"))] STCI)]
11943   "arm_coproc_builtin_available (VUNSPEC_<STC>)")
11945 (define_insn "<mcr>"
11946   [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "n")
11947                      (match_operand:SI 1 "immediate_operand" "n")
11948                      (match_operand:SI 2 "s_register_operand" "r")
11949                      (match_operand:SI 3 "immediate_operand" "n")
11950                      (match_operand:SI 4 "immediate_operand" "n")
11951                      (match_operand:SI 5 "immediate_operand" "n")] MCRI)
11952    (use (match_dup 2))]
11953   "arm_coproc_builtin_available (VUNSPEC_<MCR>)"
11955   arm_const_bounds (operands[0], 0, 16);
11956   arm_const_bounds (operands[1], 0, 8);
11957   arm_const_bounds (operands[3], 0, (1 << 5));
11958   arm_const_bounds (operands[4], 0, (1 << 5));
11959   arm_const_bounds (operands[5], 0, 8);
11960   return "<mcr>\\tp%c0, %1, %2, CR%c3, CR%c4, %5";
11962   [(set_attr "length" "4")
11963    (set_attr "type" "coproc")])
11965 (define_insn "<mrc>"
11966   [(set (match_operand:SI 0 "s_register_operand" "=r")
11967         (unspec_volatile:SI [(match_operand:SI 1 "immediate_operand" "n")
11968                           (match_operand:SI 2 "immediate_operand" "n")
11969                           (match_operand:SI 3 "immediate_operand" "n")
11970                           (match_operand:SI 4 "immediate_operand" "n")
11971                           (match_operand:SI 5 "immediate_operand" "n")] MRCI))]
11972   "arm_coproc_builtin_available (VUNSPEC_<MRC>)"
11974   arm_const_bounds (operands[1], 0, 16);
11975   arm_const_bounds (operands[2], 0, 8);
11976   arm_const_bounds (operands[3], 0, (1 << 5));
11977   arm_const_bounds (operands[4], 0, (1 << 5));
11978   arm_const_bounds (operands[5], 0, 8);
11979   return "<mrc>\\tp%c1, %2, %0, CR%c3, CR%c4, %5";
11981   [(set_attr "length" "4")
11982    (set_attr "type" "coproc")])
11984 (define_insn "<mcrr>"
11985   [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "n")
11986                      (match_operand:SI 1 "immediate_operand" "n")
11987                      (match_operand:DI 2 "s_register_operand" "r")
11988                      (match_operand:SI 3 "immediate_operand" "n")] MCRRI)
11989    (use (match_dup 2))]
11990   "arm_coproc_builtin_available (VUNSPEC_<MCRR>)"
11992   arm_const_bounds (operands[0], 0, 16);
11993   arm_const_bounds (operands[1], 0, 8);
11994   arm_const_bounds (operands[3], 0, (1 << 5));
11995   return "<mcrr>\\tp%c0, %1, %Q2, %R2, CR%c3";
11997   [(set_attr "length" "4")
11998    (set_attr "type" "coproc")])
12000 (define_insn "<mrrc>"
12001   [(set (match_operand:DI 0 "s_register_operand" "=r")
12002         (unspec_volatile:DI [(match_operand:SI 1 "immediate_operand" "n")
12003                           (match_operand:SI 2 "immediate_operand" "n")
12004                           (match_operand:SI 3 "immediate_operand" "n")] MRRCI))]
12005   "arm_coproc_builtin_available (VUNSPEC_<MRRC>)"
12007   arm_const_bounds (operands[1], 0, 16);
12008   arm_const_bounds (operands[2], 0, 8);
12009   arm_const_bounds (operands[3], 0, (1 << 5));
12010   return "<mrrc>\\tp%c1, %2, %Q0, %R0, CR%c3";
12012   [(set_attr "length" "4")
12013    (set_attr "type" "coproc")])
12015 ;; Vector bits common to IWMMXT and Neon
12016 (include "vec-common.md")
12017 ;; Load the Intel Wireless Multimedia Extension patterns
12018 (include "iwmmxt.md")
12019 ;; Load the VFP co-processor patterns
12020 (include "vfp.md")
12021 ;; Thumb-1 patterns
12022 (include "thumb1.md")
12023 ;; Thumb-2 patterns
12024 (include "thumb2.md")
12025 ;; Neon patterns
12026 (include "neon.md")
12027 ;; Crypto patterns
12028 (include "crypto.md")
12029 ;; Synchronization Primitives
12030 (include "sync.md")
12031 ;; Fixed-point patterns
12032 (include "arm-fixed.md")