1;;- Machine description for ARM for GNU compiler
2;;  Copyright (C) 1991-2019 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).
6
7;; This file is part of GCC.
8
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.
13
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.
18
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/>.
22
23;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
24
25
26;;---------------------------------------------------------------------------
27;; Constants
28
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  ]
42)
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  ]
49)
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  ]
58)
59
60
61;;---------------------------------------------------------------------------
62;; Attributes
63
64;; Processor type.  This is created automatically from arm-cores.def.
65(include "arm-tune.md")
66
67;; Instruction classification types
68(include "types.md")
69
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"))))
76
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")))
79
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"))))
84
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"))
91
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"))
96
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))
100
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"))
105
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")))
111
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"))
116
117; LENGTH of an instruction (in bytes)
118(define_attr "length" ""
119  (const_int 4))
120
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"))
130
131(define_attr "arch_enabled" "no,yes"
132  (cond [(eq_attr "arch" "any")
133	 (const_string "yes")
134
135	 (and (eq_attr "arch" "a")
136	      (match_test "TARGET_ARM"))
137	 (const_string "yes")
138
139	 (and (eq_attr "arch" "t")
140	      (match_test "TARGET_THUMB"))
141	 (const_string "yes")
142
143	 (and (eq_attr "arch" "t1")
144	      (match_test "TARGET_THUMB1"))
145	 (const_string "yes")
146
147	 (and (eq_attr "arch" "t2")
148	      (match_test "TARGET_THUMB2"))
149	 (const_string "yes")
150
151	 (and (eq_attr "arch" "32")
152	      (match_test "TARGET_32BIT"))
153	 (const_string "yes")
154
155	 (and (eq_attr "arch" "v6")
156	      (match_test "TARGET_32BIT && arm_arch6"))
157	 (const_string "yes")
158
159	 (and (eq_attr "arch" "nov6")
160	      (match_test "TARGET_32BIT && !arm_arch6"))
161	 (const_string "yes")
162
163	 (and (eq_attr "arch" "v6t2")
164	      (match_test "TARGET_32BIT && arm_arch6 && arm_arch_thumb2"))
165	 (const_string "yes")
166
167	 (and (eq_attr "arch" "v8mb")
168	      (match_test "TARGET_THUMB1 && arm_arch8"))
169	 (const_string "yes")
170
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")
175
176	 (and (eq_attr "arch" "neon_for_64bits")
177	      (match_test "TARGET_NEON")
178	      (match_test "TARGET_PREFER_NEON_64BITS"))
179	 (const_string "yes")
180
181	 (and (eq_attr "arch" "iwmmxt2")
182	      (match_test "TARGET_REALLY_IWMMXT2"))
183	 (const_string "yes")
184
185	 (and (eq_attr "arch" "armv6_or_vfpv3")
186	      (match_test "arm_arch6 || TARGET_VFP3"))
187	 (const_string "yes")
188
189	 (and (eq_attr "arch" "neon")
190	      (match_test "TARGET_NEON"))
191	 (const_string "yes")
192	]
193
194	(const_string "no")))
195
196(define_attr "opt" "any,speed,size"
197  (const_string "any"))
198
199(define_attr "opt_enabled" "no,yes"
200  (cond [(eq_attr "opt" "any")
201         (const_string "yes")
202
203	 (and (eq_attr "opt" "speed")
204	      (match_test "optimize_function_for_speed_p (cfun)"))
205	 (const_string "yes")
206
207	 (and (eq_attr "opt" "size")
208	      (match_test "optimize_function_for_size_p (cfun)"))
209	 (const_string "yes")]
210	(const_string "no")))
211
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")))
217
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.
229
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")
235
236	  (and (eq_attr "enabled_for_short_it" "no")
237	       (match_test "arm_restrict_it"))
238	  (const_string "no")
239
240	  (eq_attr "arch_enabled" "no")
241	  (const_string "no")]
242	 (const_string "yes")))
243
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))
256
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")))
263
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")])
271
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")))
275
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.
279;
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
283;
284; SET means that the purpose of the insn is to set the condition codes in a
285;   well defined manner.
286;
287; CLOB means that the condition codes are altered in an undefined manner, if
288;   they are altered at all
289;
290; UNCONDITIONAL means the instruction cannot be conditionally executed and
291;   that the instruction does not use or alter the condition codes.
292;
293; NOCOND means that the instruction does not use or alter the condition
294;   codes but can be converted into a conditionally exectuted instruction.
295
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"))))
304
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"))
310
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")))
316
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")))
324
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")))
347
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"))
351
352
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))
356
357;;---------------------------------------------------------------------------
358;; Unspecs
359
360(include "unspecs.md")
361
362;;---------------------------------------------------------------------------
363;; Mode iterators
364
365(include "iterators.md")
366
367;;---------------------------------------------------------------------------
368;; Predicates
369
370(include "predicates.md")
371(include "constraints.md")
372
373;;---------------------------------------------------------------------------
374;; Pipeline descriptions
375
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"))))
381
382;; True if the generic scheduling description should be used.
383
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,arm10e,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"))))
395
396(define_attr "generic_vfp" "yes,no"
397  (const (if_then_else
398	  (and (eq_attr "fpu" "vfp")
399	       (eq_attr "tune" "!arm10e,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"))))
405
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")
434
435
436;;---------------------------------------------------------------------------
437;; Insn patterns
438;;
439;; Addition insns.
440
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.
444
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  "
461)
462
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")]
489)
490
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")]
519)
520
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")]
547)
548
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"
555{
556  emit_insn (gen_add<mode>3_compareV (operands[0], operands[1], operands[2]));
557  arm_gen_unlikely_cbranch (NE, CC_Vmode, operands[3]);
558
559  DONE;
560})
561
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"
568{
569  emit_insn (gen_add<mode>3_compareC (operands[0], operands[1], operands[2]));
570  arm_gen_unlikely_cbranch (NE, CC_Cmode, operands[3]);
571
572  DONE;
573})
574
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  "
589)
590
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  ""
605)
606
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")))
650 ]
651)
652
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")]
694)
695
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")]
709)
710
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")]
730)
731
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")]
773)
774
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")]
794)
795
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")]
810)
811
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")]
827)
828
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")]
843)
844
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")]
858)
859
860;; This is the canonicalization of subsi3_compare 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" "I,L")))
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" "L,I")))]
870  "TARGET_32BIT
871   && (INTVAL (operands[2])
872       == trunc_int_for_mode (-INTVAL (operands[3]), SImode))"
873{
874  /* For 0 and INT_MIN it is essential that we use subs, as adds will result
875     in different condition codes (like cmn rather than like cmp), so that
876     alternative comes first.  Both alternatives can match for any 0x??000000
877     where except for 0 and INT_MIN it doesn't matter what we choose, and also
878     for -1 and 1 with TARGET_THUMB2, in that case prefer instruction with #1
879     as it is shorter.  */
880  if (which_alternative == 0 && operands[3] != const1_rtx)
881    return "subs%?\\t%0, %1, #%n3";
882  else
883    return "adds%?\\t%0, %1, %3";
884}
885  [(set_attr "conds" "set")
886   (set_attr "type" "alus_sreg")]
887)
888
889;; Convert the sequence
890;;  sub  rd, rn, #1
891;;  cmn  rd, #1	(equivalent to cmp rd, #-1)
892;;  bne  dest
893;; into
894;;  subs rd, rn, #1
895;;  bcs  dest	((unsigned)rn >= 1)
896;; similarly for the beq variant using bcc.
897;; This is a common looping idiom (while (n--))
898(define_peephole2
899  [(set (match_operand:SI 0 "arm_general_register_operand" "")
900	(plus:SI (match_operand:SI 1 "arm_general_register_operand" "")
901		 (const_int -1)))
902   (set (match_operand 2 "cc_register" "")
903	(compare (match_dup 0) (const_int -1)))
904   (set (pc)
905	(if_then_else (match_operator 3 "equality_operator"
906		       [(match_dup 2) (const_int 0)])
907		      (match_operand 4 "" "")
908		      (match_operand 5 "" "")))]
909  "TARGET_32BIT && peep2_reg_dead_p (3, operands[2])"
910  [(parallel[
911    (set (match_dup 2)
912	 (compare:CC
913	  (match_dup 1) (const_int 1)))
914    (set (match_dup 0) (plus:SI (match_dup 1) (const_int -1)))])
915   (set (pc)
916	(if_then_else (match_op_dup 3 [(match_dup 2) (const_int 0)])
917		      (match_dup 4)
918		      (match_dup 5)))]
919  "operands[2] = gen_rtx_REG (CCmode, CC_REGNUM);
920   operands[3] = gen_rtx_fmt_ee ((GET_CODE (operands[3]) == NE
921				  ? GEU : LTU),
922				 VOIDmode,
923				 operands[2], const0_rtx);"
924)
925
926;; The next four insns work because they compare the result with one of
927;; the operands, and we know that the use of the condition code is
928;; either GEU or LTU, so we can use the carry flag from the addition
929;; instead of doing the compare a second time.
930(define_insn "*addsi3_compare_op1"
931  [(set (reg:CC_C CC_REGNUM)
932	(compare:CC_C
933	 (plus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
934		  (match_operand:SI 2 "arm_add_operand" "I,L,r"))
935	 (match_dup 1)))
936   (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
937	(plus:SI (match_dup 1) (match_dup 2)))]
938  "TARGET_32BIT"
939  "@
940   adds%?\\t%0, %1, %2
941   subs%?\\t%0, %1, #%n2
942   adds%?\\t%0, %1, %2"
943  [(set_attr "conds" "set")
944   (set_attr "type"  "alus_imm,alus_imm,alus_sreg")]
945)
946
947(define_insn "*addsi3_compare_op2"
948  [(set (reg:CC_C CC_REGNUM)
949	(compare:CC_C
950	 (plus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
951		  (match_operand:SI 2 "arm_add_operand" "I,L,r"))
952	 (match_dup 2)))
953   (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
954	(plus:SI (match_dup 1) (match_dup 2)))]
955  "TARGET_32BIT"
956  "@
957   adds%?\\t%0, %1, %2
958   subs%?\\t%0, %1, #%n2
959   adds%?\\t%0, %1, %2"
960  [(set_attr "conds" "set")
961   (set_attr "type" "alus_imm,alus_imm,alus_sreg")]
962)
963
964(define_insn "*compare_addsi2_op0"
965  [(set (reg:CC_C CC_REGNUM)
966        (compare:CC_C
967          (plus:SI (match_operand:SI 0 "s_register_operand" "l,l,r,r,r")
968                   (match_operand:SI 1 "arm_add_operand" "Pv,l,I,L,r"))
969          (match_dup 0)))]
970  "TARGET_32BIT"
971  "@
972   cmp%?\\t%0, #%n1
973   cmn%?\\t%0, %1
974   cmn%?\\t%0, %1
975   cmp%?\\t%0, #%n1
976   cmn%?\\t%0, %1"
977  [(set_attr "conds" "set")
978   (set_attr "predicable" "yes")
979   (set_attr "arch" "t2,t2,*,*,*")
980   (set_attr "predicable_short_it" "yes,yes,no,no,no")
981   (set_attr "length" "2,2,4,4,4")
982   (set_attr "type" "alus_imm,alus_sreg,alus_imm,alus_imm,alus_sreg")]
983)
984
985(define_insn "*compare_addsi2_op1"
986  [(set (reg:CC_C CC_REGNUM)
987        (compare:CC_C
988          (plus:SI (match_operand:SI 0 "s_register_operand" "l,l,r,r,r")
989                   (match_operand:SI 1 "arm_add_operand" "Pv,l,I,L,r"))
990          (match_dup 1)))]
991  "TARGET_32BIT"
992  "@
993   cmp%?\\t%0, #%n1
994   cmn%?\\t%0, %1
995   cmn%?\\t%0, %1
996   cmp%?\\t%0, #%n1
997   cmn%?\\t%0, %1"
998  [(set_attr "conds" "set")
999   (set_attr "predicable" "yes")
1000   (set_attr "arch" "t2,t2,*,*,*")
1001   (set_attr "predicable_short_it" "yes,yes,no,no,no")
1002   (set_attr "length" "2,2,4,4,4")
1003   (set_attr "type" "alus_imm,alus_sreg,alus_imm,alus_imm,alus_sreg")]
1004 )
1005
1006(define_insn "*addsi3_carryin_<optab>"
1007  [(set (match_operand:SI 0 "s_register_operand" "=l,r,r")
1008        (plus:SI (plus:SI (match_operand:SI 1 "s_register_operand" "%l,r,r")
1009                          (match_operand:SI 2 "arm_not_operand" "0,rI,K"))
1010                 (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))))]
1011  "TARGET_32BIT"
1012  "@
1013   adc%?\\t%0, %1, %2
1014   adc%?\\t%0, %1, %2
1015   sbc%?\\t%0, %1, #%B2"
1016  [(set_attr "conds" "use")
1017   (set_attr "predicable" "yes")
1018   (set_attr "arch" "t2,*,*")
1019   (set_attr "length" "4")
1020   (set_attr "predicable_short_it" "yes,no,no")
1021   (set_attr "type" "adc_reg,adc_reg,adc_imm")]
1022)
1023
1024(define_insn "*addsi3_carryin_alt2_<optab>"
1025  [(set (match_operand:SI 0 "s_register_operand" "=l,r,r")
1026        (plus:SI (plus:SI (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))
1027                          (match_operand:SI 1 "s_register_operand" "%l,r,r"))
1028                 (match_operand:SI 2 "arm_rhs_operand" "l,rI,K")))]
1029  "TARGET_32BIT"
1030  "@
1031   adc%?\\t%0, %1, %2
1032   adc%?\\t%0, %1, %2
1033   sbc%?\\t%0, %1, #%B2"
1034  [(set_attr "conds" "use")
1035   (set_attr "predicable" "yes")
1036   (set_attr "arch" "t2,*,*")
1037   (set_attr "length" "4")
1038   (set_attr "predicable_short_it" "yes,no,no")
1039   (set_attr "type" "adc_reg,adc_reg,adc_imm")]
1040)
1041
1042(define_insn "*addsi3_carryin_shift_<optab>"
1043  [(set (match_operand:SI 0 "s_register_operand" "=r")
1044	(plus:SI (plus:SI
1045		  (match_operator:SI 2 "shift_operator"
1046		    [(match_operand:SI 3 "s_register_operand" "r")
1047		     (match_operand:SI 4 "reg_or_int_operand" "rM")])
1048		  (match_operand:SI 1 "s_register_operand" "r"))
1049		 (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))))]
1050  "TARGET_32BIT"
1051  "adc%?\\t%0, %1, %3%S2"
1052  [(set_attr "conds" "use")
1053   (set_attr "predicable" "yes")
1054   (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
1055		      (const_string "alu_shift_imm")
1056		      (const_string "alu_shift_reg")))]
1057)
1058
1059(define_insn "*addsi3_carryin_clobercc_<optab>"
1060  [(set (match_operand:SI 0 "s_register_operand" "=r")
1061	(plus:SI (plus:SI (match_operand:SI 1 "s_register_operand" "%r")
1062			  (match_operand:SI 2 "arm_rhs_operand" "rI"))
1063		 (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))))
1064   (clobber (reg:CC CC_REGNUM))]
1065   "TARGET_32BIT"
1066   "adcs%?\\t%0, %1, %2"
1067   [(set_attr "conds" "set")
1068    (set_attr "type" "adcs_reg")]
1069)
1070
1071(define_expand "subv<mode>4"
1072  [(match_operand:SIDI 0 "register_operand")
1073   (match_operand:SIDI 1 "register_operand")
1074   (match_operand:SIDI 2 "register_operand")
1075   (match_operand 3 "")]
1076  "TARGET_32BIT"
1077{
1078  emit_insn (gen_sub<mode>3_compare1 (operands[0], operands[1], operands[2]));
1079  arm_gen_unlikely_cbranch (NE, CC_Vmode, operands[3]);
1080
1081  DONE;
1082})
1083
1084(define_expand "usubv<mode>4"
1085  [(match_operand:SIDI 0 "register_operand")
1086   (match_operand:SIDI 1 "register_operand")
1087   (match_operand:SIDI 2 "register_operand")
1088   (match_operand 3 "")]
1089  "TARGET_32BIT"
1090{
1091  emit_insn (gen_sub<mode>3_compare1 (operands[0], operands[1], operands[2]));
1092  arm_gen_unlikely_cbranch (LTU, CCmode, operands[3]);
1093
1094  DONE;
1095})
1096
1097(define_insn_and_split "subdi3_compare1"
1098  [(set (reg:CC CC_REGNUM)
1099	(compare:CC
1100	  (match_operand:DI 1 "register_operand" "r")
1101	  (match_operand:DI 2 "register_operand" "r")))
1102   (set (match_operand:DI 0 "register_operand" "=&r")
1103	(minus:DI (match_dup 1) (match_dup 2)))]
1104  "TARGET_32BIT"
1105  "#"
1106  "&& reload_completed"
1107  [(parallel [(set (reg:CC CC_REGNUM)
1108		   (compare:CC (match_dup 1) (match_dup 2)))
1109	      (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1110   (parallel [(set (reg:CC CC_REGNUM)
1111		   (compare:CC (match_dup 4) (match_dup 5)))
1112	     (set (match_dup 3) (minus:SI (minus:SI (match_dup 4) (match_dup 5))
1113			       (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))])]
1114  {
1115    operands[3] = gen_highpart (SImode, operands[0]);
1116    operands[0] = gen_lowpart (SImode, operands[0]);
1117    operands[4] = gen_highpart (SImode, operands[1]);
1118    operands[1] = gen_lowpart (SImode, operands[1]);
1119    operands[5] = gen_highpart (SImode, operands[2]);
1120    operands[2] = gen_lowpart (SImode, operands[2]);
1121   }
1122  [(set_attr "conds" "set")
1123   (set_attr "length" "8")
1124   (set_attr "type" "multiple")]
1125)
1126
1127(define_insn "subsi3_compare1"
1128  [(set (reg:CC CC_REGNUM)
1129	(compare:CC
1130	  (match_operand:SI 1 "register_operand" "r")
1131	  (match_operand:SI 2 "register_operand" "r")))
1132   (set (match_operand:SI 0 "register_operand" "=r")
1133	(minus:SI (match_dup 1) (match_dup 2)))]
1134  "TARGET_32BIT"
1135  "subs%?\\t%0, %1, %2"
1136  [(set_attr "conds" "set")
1137   (set_attr "type" "alus_sreg")]
1138)
1139
1140(define_insn "*subsi3_carryin"
1141  [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
1142	(minus:SI (minus:SI (match_operand:SI 1 "reg_or_int_operand" "r,I,Pz")
1143			    (match_operand:SI 2 "s_register_operand" "r,r,r"))
1144		  (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1145  "TARGET_32BIT"
1146  "@
1147   sbc%?\\t%0, %1, %2
1148   rsc%?\\t%0, %2, %1
1149   sbc%?\\t%0, %2, %2, lsl #1"
1150  [(set_attr "conds" "use")
1151   (set_attr "arch" "*,a,t2")
1152   (set_attr "predicable" "yes")
1153   (set_attr "type" "adc_reg,adc_imm,alu_shift_imm")]
1154)
1155
1156(define_insn "*subsi3_carryin_const"
1157  [(set (match_operand:SI 0 "s_register_operand" "=r")
1158        (minus:SI (plus:SI (match_operand:SI 1 "s_register_operand" "r")
1159                           (match_operand:SI 2 "arm_neg_immediate_operand" "L"))
1160                  (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1161  "TARGET_32BIT"
1162  "sbc\\t%0, %1, #%n2"
1163  [(set_attr "conds" "use")
1164   (set_attr "type" "adc_imm")]
1165)
1166
1167(define_insn "*subsi3_carryin_const0"
1168  [(set (match_operand:SI 0 "s_register_operand" "=r")
1169        (minus:SI (match_operand:SI 1 "s_register_operand" "r")
1170                  (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1171  "TARGET_32BIT"
1172  "sbc\\t%0, %1, #0"
1173  [(set_attr "conds" "use")
1174   (set_attr "type" "adc_imm")]
1175)
1176
1177(define_insn "*subsi3_carryin_compare"
1178  [(set (reg:CC CC_REGNUM)
1179        (compare:CC (match_operand:SI 1 "s_register_operand" "r")
1180                    (match_operand:SI 2 "s_register_operand" "r")))
1181   (set (match_operand:SI 0 "s_register_operand" "=r")
1182        (minus:SI (minus:SI (match_dup 1)
1183                            (match_dup 2))
1184                  (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1185  "TARGET_32BIT"
1186  "sbcs\\t%0, %1, %2"
1187  [(set_attr "conds" "set")
1188   (set_attr "type" "adcs_reg")]
1189)
1190
1191(define_insn "*subsi3_carryin_compare_const"
1192  [(set (reg:CC CC_REGNUM)
1193        (compare:CC (match_operand:SI 1 "reg_or_int_operand" "r")
1194                    (match_operand:SI 2 "const_int_I_operand" "I")))
1195   (set (match_operand:SI 0 "s_register_operand" "=r")
1196        (minus:SI (plus:SI (match_dup 1)
1197                           (match_operand:SI 3 "arm_neg_immediate_operand" "L"))
1198                  (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1199  "TARGET_32BIT
1200   && (INTVAL (operands[2])
1201       == trunc_int_for_mode (-INTVAL (operands[3]), SImode))"
1202  "sbcs\\t%0, %1, #%n3"
1203  [(set_attr "conds" "set")
1204   (set_attr "type" "adcs_imm")]
1205)
1206
1207(define_insn "*subsi3_carryin_compare_const0"
1208  [(set (reg:CC CC_REGNUM)
1209        (compare:CC (match_operand:SI 1 "reg_or_int_operand" "r")
1210		    (const_int 0)))
1211   (set (match_operand:SI 0 "s_register_operand" "=r")
1212        (minus:SI (match_dup 1)
1213                  (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1214  "TARGET_32BIT"
1215  "sbcs\\t%0, %1, #0"
1216  [(set_attr "conds" "set")
1217   (set_attr "type" "adcs_imm")]
1218)
1219
1220(define_insn "*subsi3_carryin_shift"
1221  [(set (match_operand:SI 0 "s_register_operand" "=r")
1222	(minus:SI (minus:SI
1223		  (match_operand:SI 1 "s_register_operand" "r")
1224                  (match_operator:SI 2 "shift_operator"
1225                   [(match_operand:SI 3 "s_register_operand" "r")
1226                    (match_operand:SI 4 "reg_or_int_operand" "rM")]))
1227                 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1228  "TARGET_32BIT"
1229  "sbc%?\\t%0, %1, %3%S2"
1230  [(set_attr "conds" "use")
1231   (set_attr "predicable" "yes")
1232   (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
1233		      (const_string "alu_shift_imm")
1234                     (const_string "alu_shift_reg")))]
1235)
1236
1237(define_insn "*rsbsi3_carryin_shift"
1238  [(set (match_operand:SI 0 "s_register_operand" "=r")
1239	(minus:SI (minus:SI
1240                  (match_operator:SI 2 "shift_operator"
1241                   [(match_operand:SI 3 "s_register_operand" "r")
1242                    (match_operand:SI 4 "reg_or_int_operand" "rM")])
1243		   (match_operand:SI 1 "s_register_operand" "r"))
1244                 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1245  "TARGET_ARM"
1246  "rsc%?\\t%0, %1, %3%S2"
1247  [(set_attr "conds" "use")
1248   (set_attr "predicable" "yes")
1249   (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
1250		      (const_string "alu_shift_imm")
1251		      (const_string "alu_shift_reg")))]
1252)
1253
1254; transform ((x << y) - 1) to ~(~(x-1) << y)  Where X is a constant.
1255(define_split
1256  [(set (match_operand:SI 0 "s_register_operand" "")
1257	(plus:SI (ashift:SI (match_operand:SI 1 "const_int_operand" "")
1258			    (match_operand:SI 2 "s_register_operand" ""))
1259		 (const_int -1)))
1260   (clobber (match_operand:SI 3 "s_register_operand" ""))]
1261  "TARGET_32BIT"
1262  [(set (match_dup 3) (match_dup 1))
1263   (set (match_dup 0) (not:SI (ashift:SI (match_dup 3) (match_dup 2))))]
1264  "
1265  operands[1] = GEN_INT (~(INTVAL (operands[1]) - 1));
1266")
1267
1268(define_expand "addsf3"
1269  [(set (match_operand:SF          0 "s_register_operand" "")
1270	(plus:SF (match_operand:SF 1 "s_register_operand" "")
1271		 (match_operand:SF 2 "s_register_operand" "")))]
1272  "TARGET_32BIT && TARGET_HARD_FLOAT"
1273  "
1274")
1275
1276(define_expand "adddf3"
1277  [(set (match_operand:DF          0 "s_register_operand" "")
1278	(plus:DF (match_operand:DF 1 "s_register_operand" "")
1279		 (match_operand:DF 2 "s_register_operand" "")))]
1280  "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
1281  "
1282")
1283
1284(define_expand "subdi3"
1285 [(parallel
1286   [(set (match_operand:DI            0 "s_register_operand" "")
1287	  (minus:DI (match_operand:DI 1 "s_register_operand" "")
1288	            (match_operand:DI 2 "s_register_operand" "")))
1289    (clobber (reg:CC CC_REGNUM))])]
1290  "TARGET_EITHER"
1291  "
1292  if (TARGET_THUMB1)
1293    {
1294      if (!REG_P (operands[1]))
1295        operands[1] = force_reg (DImode, operands[1]);
1296      if (!REG_P (operands[2]))
1297        operands[2] = force_reg (DImode, operands[2]);
1298     }
1299  "
1300)
1301
1302(define_insn_and_split "*arm_subdi3"
1303  [(set (match_operand:DI           0 "arm_general_register_operand" "=&r,&r,&r")
1304	(minus:DI (match_operand:DI 1 "arm_general_register_operand" "0,r,0")
1305		  (match_operand:DI 2 "arm_general_register_operand" "r,0,0")))
1306   (clobber (reg:CC CC_REGNUM))]
1307  "TARGET_32BIT && !TARGET_NEON"
1308  "#"  ; "subs\\t%Q0, %Q1, %Q2\;sbc\\t%R0, %R1, %R2"
1309  "&& (!TARGET_IWMMXT || reload_completed)"
1310  [(parallel [(set (reg:CC CC_REGNUM)
1311		   (compare:CC (match_dup 1) (match_dup 2)))
1312	      (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1313   (set (match_dup 3) (minus:SI (minus:SI (match_dup 4) (match_dup 5))
1314			       (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1315  {
1316    operands[3] = gen_highpart (SImode, operands[0]);
1317    operands[0] = gen_lowpart (SImode, operands[0]);
1318    operands[4] = gen_highpart (SImode, operands[1]);
1319    operands[1] = gen_lowpart (SImode, operands[1]);
1320    operands[5] = gen_highpart (SImode, operands[2]);
1321    operands[2] = gen_lowpart (SImode, operands[2]);
1322   }
1323  [(set_attr "conds" "clob")
1324   (set_attr "length" "8")
1325   (set_attr "type" "multiple")]
1326)
1327
1328(define_insn_and_split "*subdi_di_zesidi"
1329  [(set (match_operand:DI           0 "s_register_operand" "=&r,&r")
1330	(minus:DI (match_operand:DI 1 "s_register_operand"  "0,r")
1331		  (zero_extend:DI
1332		   (match_operand:SI 2 "s_register_operand"  "r,r"))))
1333   (clobber (reg:CC CC_REGNUM))]
1334  "TARGET_32BIT"
1335  "#"   ; "subs\\t%Q0, %Q1, %2\;sbc\\t%R0, %R1, #0"
1336  "&& reload_completed"
1337  [(parallel [(set (reg:CC CC_REGNUM)
1338		   (compare:CC (match_dup 1) (match_dup 2)))
1339	      (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1340   (set (match_dup 3) (minus:SI (match_dup 4)
1341                                (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1342  {
1343    operands[3] = gen_highpart (SImode, operands[0]);
1344    operands[0] = gen_lowpart (SImode, operands[0]);
1345    operands[4] = gen_highpart (SImode, operands[1]);
1346    operands[1] = gen_lowpart (SImode, operands[1]);
1347   }
1348  [(set_attr "conds" "clob")
1349   (set_attr "length" "8")
1350   (set_attr "type" "multiple")]
1351)
1352
1353(define_insn_and_split "*subdi_di_sesidi"
1354  [(set (match_operand:DI            0 "s_register_operand" "=&r,&r")
1355	(minus:DI (match_operand:DI  1 "s_register_operand"  "0,r")
1356		  (sign_extend:DI
1357		   (match_operand:SI 2 "s_register_operand"  "r,r"))))
1358   (clobber (reg:CC CC_REGNUM))]
1359  "TARGET_32BIT"
1360  "#"   ; "subs\\t%Q0, %Q1, %2\;sbc\\t%R0, %R1, %2, asr #31"
1361  "&& reload_completed"
1362  [(parallel [(set (reg:CC CC_REGNUM)
1363		   (compare:CC (match_dup 1) (match_dup 2)))
1364	      (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1365   (set (match_dup 3) (minus:SI (minus:SI (match_dup 4)
1366                                         (ashiftrt:SI (match_dup 2)
1367                                                      (const_int 31)))
1368                                (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1369  {
1370    operands[3] = gen_highpart (SImode, operands[0]);
1371    operands[0] = gen_lowpart (SImode, operands[0]);
1372    operands[4] = gen_highpart (SImode, operands[1]);
1373    operands[1] = gen_lowpart (SImode, operands[1]);
1374  }
1375  [(set_attr "conds" "clob")
1376   (set_attr "length" "8")
1377   (set_attr "type" "multiple")]
1378)
1379
1380(define_insn_and_split "*subdi_zesidi_di"
1381  [(set (match_operand:DI            0 "s_register_operand" "=&r,&r")
1382	(minus:DI (zero_extend:DI
1383		   (match_operand:SI 2 "s_register_operand"  "r,r"))
1384		  (match_operand:DI  1 "s_register_operand" "0,r")))
1385   (clobber (reg:CC CC_REGNUM))]
1386  "TARGET_ARM"
1387  "#"   ; "rsbs\\t%Q0, %Q1, %2\;rsc\\t%R0, %R1, #0"
1388        ; is equivalent to:
1389        ; "subs\\t%Q0, %2, %Q1\;rsc\\t%R0, %R1, #0"
1390  "&& reload_completed"
1391  [(parallel [(set (reg:CC CC_REGNUM)
1392		   (compare:CC (match_dup 2) (match_dup 1)))
1393	      (set (match_dup 0) (minus:SI (match_dup 2) (match_dup 1)))])
1394   (set (match_dup 3) (minus:SI (minus:SI (const_int 0) (match_dup 4))
1395			       (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1396  {
1397    operands[3] = gen_highpart (SImode, operands[0]);
1398    operands[0] = gen_lowpart (SImode, operands[0]);
1399    operands[4] = gen_highpart (SImode, operands[1]);
1400    operands[1] = gen_lowpart (SImode, operands[1]);
1401  }
1402  [(set_attr "conds" "clob")
1403   (set_attr "length" "8")
1404   (set_attr "type" "multiple")]
1405)
1406
1407(define_insn_and_split "*subdi_sesidi_di"
1408  [(set (match_operand:DI            0 "s_register_operand" "=&r,&r")
1409	(minus:DI (sign_extend:DI
1410		   (match_operand:SI 2 "s_register_operand"   "r,r"))
1411		  (match_operand:DI  1 "s_register_operand"  "0,r")))
1412   (clobber (reg:CC CC_REGNUM))]
1413  "TARGET_ARM"
1414  "#"   ; "rsbs\\t%Q0, %Q1, %2\;rsc\\t%R0, %R1, %2, asr #31"
1415        ; is equivalent to:
1416        ; "subs\\t%Q0, %2, %Q1\;rsc\\t%R0, %R1, %2, asr #31"
1417  "&& reload_completed"
1418  [(parallel [(set (reg:CC CC_REGNUM)
1419		   (compare:CC (match_dup 2) (match_dup 1)))
1420	      (set (match_dup 0) (minus:SI (match_dup 2) (match_dup 1)))])
1421   (set (match_dup 3) (minus:SI (minus:SI
1422                                (ashiftrt:SI (match_dup 2)
1423                                             (const_int 31))
1424                                (match_dup 4))
1425			       (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1426  {
1427    operands[3] = gen_highpart (SImode, operands[0]);
1428    operands[0] = gen_lowpart (SImode, operands[0]);
1429    operands[4] = gen_highpart (SImode, operands[1]);
1430    operands[1] = gen_lowpart (SImode, operands[1]);
1431  }
1432  [(set_attr "conds" "clob")
1433   (set_attr "length" "8")
1434   (set_attr "type" "multiple")]
1435)
1436
1437(define_insn_and_split "*subdi_zesidi_zesidi"
1438  [(set (match_operand:DI            0 "s_register_operand" "=r")
1439	(minus:DI (zero_extend:DI
1440		   (match_operand:SI 1 "s_register_operand"  "r"))
1441		  (zero_extend:DI
1442		   (match_operand:SI 2 "s_register_operand"  "r"))))
1443   (clobber (reg:CC CC_REGNUM))]
1444  "TARGET_32BIT"
1445  "#"   ; "subs\\t%Q0, %1, %2\;sbc\\t%R0, %1, %1"
1446  "&& reload_completed"
1447  [(parallel [(set (reg:CC CC_REGNUM)
1448		   (compare:CC (match_dup 1) (match_dup 2)))
1449	      (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1450   (set (match_dup 3) (minus:SI (minus:SI (match_dup 1) (match_dup 1))
1451			       (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1452  {
1453       operands[3] = gen_highpart (SImode, operands[0]);
1454       operands[0] = gen_lowpart (SImode, operands[0]);
1455  }
1456  [(set_attr "conds" "clob")
1457   (set_attr "length" "8")
1458   (set_attr "type" "multiple")]
1459)
1460
1461(define_expand "subsi3"
1462  [(set (match_operand:SI           0 "s_register_operand" "")
1463	(minus:SI (match_operand:SI 1 "reg_or_int_operand" "")
1464		  (match_operand:SI 2 "s_register_operand" "")))]
1465  "TARGET_EITHER"
1466  "
1467  if (CONST_INT_P (operands[1]))
1468    {
1469      if (TARGET_32BIT)
1470        {
1471	  if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[1]), MINUS))
1472	    operands[1] = force_reg (SImode, operands[1]);
1473	  else
1474	    {
1475	      arm_split_constant (MINUS, SImode, NULL_RTX,
1476				  INTVAL (operands[1]), operands[0],
1477				  operands[2],
1478				  optimize && can_create_pseudo_p ());
1479	      DONE;
1480	    }
1481	}
1482      else /* TARGET_THUMB1 */
1483        operands[1] = force_reg (SImode, operands[1]);
1484    }
1485  "
1486)
1487
1488; ??? Check Thumb-2 split length
1489(define_insn_and_split "*arm_subsi3_insn"
1490  [(set (match_operand:SI           0 "s_register_operand" "=l,l ,l ,l ,r,r,r,rk,r")
1491	(minus:SI (match_operand:SI 1 "reg_or_int_operand" "l ,0 ,l ,Pz,I,r,r,k ,?n")
1492		  (match_operand:SI 2 "reg_or_int_operand" "l ,Py,Pd,l ,r,I,r,r ,r")))]
1493  "TARGET_32BIT"
1494  "@
1495   sub%?\\t%0, %1, %2
1496   sub%?\\t%0, %2
1497   sub%?\\t%0, %1, %2
1498   rsb%?\\t%0, %2, %1
1499   rsb%?\\t%0, %2, %1
1500   sub%?\\t%0, %1, %2
1501   sub%?\\t%0, %1, %2
1502   sub%?\\t%0, %1, %2
1503   #"
1504  "&& (CONST_INT_P (operands[1])
1505       && !const_ok_for_arm (INTVAL (operands[1])))"
1506  [(clobber (const_int 0))]
1507  "
1508  arm_split_constant (MINUS, SImode, curr_insn,
1509                      INTVAL (operands[1]), operands[0], operands[2], 0);
1510  DONE;
1511  "
1512  [(set_attr "length" "4,4,4,4,4,4,4,4,16")
1513   (set_attr "arch" "t2,t2,t2,t2,*,*,*,*,*")
1514   (set_attr "predicable" "yes")
1515   (set_attr "predicable_short_it" "yes,yes,yes,yes,no,no,no,no,no")
1516   (set_attr "type" "alu_sreg,alu_sreg,alu_sreg,alu_sreg,alu_imm,alu_imm,alu_sreg,alu_sreg,multiple")]
1517)
1518
1519(define_peephole2
1520  [(match_scratch:SI 3 "r")
1521   (set (match_operand:SI 0 "arm_general_register_operand" "")
1522	(minus:SI (match_operand:SI 1 "const_int_operand" "")
1523		  (match_operand:SI 2 "arm_general_register_operand" "")))]
1524  "TARGET_32BIT
1525   && !const_ok_for_arm (INTVAL (operands[1]))
1526   && const_ok_for_arm (~INTVAL (operands[1]))"
1527  [(set (match_dup 3) (match_dup 1))
1528   (set (match_dup 0) (minus:SI (match_dup 3) (match_dup 2)))]
1529  ""
1530)
1531
1532(define_insn "subsi3_compare0"
1533  [(set (reg:CC_NOOV CC_REGNUM)
1534	(compare:CC_NOOV
1535	 (minus:SI (match_operand:SI 1 "arm_rhs_operand" "r,r,I")
1536		   (match_operand:SI 2 "arm_rhs_operand" "I,r,r"))
1537	 (const_int 0)))
1538   (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
1539	(minus:SI (match_dup 1) (match_dup 2)))]
1540  "TARGET_32BIT"
1541  "@
1542   subs%?\\t%0, %1, %2
1543   subs%?\\t%0, %1, %2
1544   rsbs%?\\t%0, %2, %1"
1545  [(set_attr "conds" "set")
1546   (set_attr "type"  "alus_imm,alus_sreg,alus_sreg")]
1547)
1548
1549(define_insn "subsi3_compare"
1550  [(set (reg:CC CC_REGNUM)
1551	(compare:CC (match_operand:SI 1 "arm_rhs_operand" "r,r,I")
1552		    (match_operand:SI 2 "arm_rhs_operand" "I,r,r")))
1553   (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
1554	(minus:SI (match_dup 1) (match_dup 2)))]
1555  "TARGET_32BIT"
1556  "@
1557   subs%?\\t%0, %1, %2
1558   subs%?\\t%0, %1, %2
1559   rsbs%?\\t%0, %2, %1"
1560  [(set_attr "conds" "set")
1561   (set_attr "type" "alus_imm,alus_sreg,alus_sreg")]
1562)
1563
1564(define_expand "subsf3"
1565  [(set (match_operand:SF           0 "s_register_operand" "")
1566	(minus:SF (match_operand:SF 1 "s_register_operand" "")
1567		  (match_operand:SF 2 "s_register_operand" "")))]
1568  "TARGET_32BIT && TARGET_HARD_FLOAT"
1569  "
1570")
1571
1572(define_expand "subdf3"
1573  [(set (match_operand:DF           0 "s_register_operand" "")
1574	(minus:DF (match_operand:DF 1 "s_register_operand" "")
1575		  (match_operand:DF 2 "s_register_operand" "")))]
1576  "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
1577  "
1578")
1579
1580
1581;; Multiplication insns
1582
1583(define_expand "mulhi3"
1584  [(set (match_operand:HI 0 "s_register_operand" "")
1585	(mult:HI (match_operand:HI 1 "s_register_operand" "")
1586		 (match_operand:HI 2 "s_register_operand" "")))]
1587  "TARGET_DSP_MULTIPLY"
1588  "
1589  {
1590    rtx result = gen_reg_rtx (SImode);
1591    emit_insn (gen_mulhisi3 (result, operands[1], operands[2]));
1592    emit_move_insn (operands[0], gen_lowpart (HImode, result));
1593    DONE;
1594  }"
1595)
1596
1597(define_expand "mulsi3"
1598  [(set (match_operand:SI          0 "s_register_operand" "")
1599	(mult:SI (match_operand:SI 2 "s_register_operand" "")
1600		 (match_operand:SI 1 "s_register_operand" "")))]
1601  "TARGET_EITHER"
1602  ""
1603)
1604
1605;; Use `&' and then `0' to prevent the operands 0 and 1 being the same
1606(define_insn "*arm_mulsi3"
1607  [(set (match_operand:SI          0 "s_register_operand" "=&r,&r")
1608	(mult:SI (match_operand:SI 2 "s_register_operand" "r,r")
1609		 (match_operand:SI 1 "s_register_operand" "%0,r")))]
1610  "TARGET_32BIT && !arm_arch6"
1611  "mul%?\\t%0, %2, %1"
1612  [(set_attr "type" "mul")
1613   (set_attr "predicable" "yes")]
1614)
1615
1616(define_insn "*arm_mulsi3_v6"
1617  [(set (match_operand:SI          0 "s_register_operand" "=l,l,r")
1618	(mult:SI (match_operand:SI 1 "s_register_operand" "0,l,r")
1619		 (match_operand:SI 2 "s_register_operand" "l,0,r")))]
1620  "TARGET_32BIT && arm_arch6"
1621  "mul%?\\t%0, %1, %2"
1622  [(set_attr "type" "mul")
1623   (set_attr "predicable" "yes")
1624   (set_attr "arch" "t2,t2,*")
1625   (set_attr "length" "4")
1626   (set_attr "predicable_short_it" "yes,yes,no")]
1627)
1628
1629(define_insn "*mulsi3_compare0"
1630  [(set (reg:CC_NOOV CC_REGNUM)
1631	(compare:CC_NOOV (mult:SI
1632			  (match_operand:SI 2 "s_register_operand" "r,r")
1633			  (match_operand:SI 1 "s_register_operand" "%0,r"))
1634			 (const_int 0)))
1635   (set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1636	(mult:SI (match_dup 2) (match_dup 1)))]
1637  "TARGET_ARM && !arm_arch6"
1638  "muls%?\\t%0, %2, %1"
1639  [(set_attr "conds" "set")
1640   (set_attr "type" "muls")]
1641)
1642
1643(define_insn "*mulsi3_compare0_v6"
1644  [(set (reg:CC_NOOV CC_REGNUM)
1645	(compare:CC_NOOV (mult:SI
1646			  (match_operand:SI 2 "s_register_operand" "r")
1647			  (match_operand:SI 1 "s_register_operand" "r"))
1648			 (const_int 0)))
1649   (set (match_operand:SI 0 "s_register_operand" "=r")
1650	(mult:SI (match_dup 2) (match_dup 1)))]
1651  "TARGET_ARM && arm_arch6 && optimize_size"
1652  "muls%?\\t%0, %2, %1"
1653  [(set_attr "conds" "set")
1654   (set_attr "type" "muls")]
1655)
1656
1657(define_insn "*mulsi_compare0_scratch"
1658  [(set (reg:CC_NOOV CC_REGNUM)
1659	(compare:CC_NOOV (mult:SI
1660			  (match_operand:SI 2 "s_register_operand" "r,r")
1661			  (match_operand:SI 1 "s_register_operand" "%0,r"))
1662			 (const_int 0)))
1663   (clobber (match_scratch:SI 0 "=&r,&r"))]
1664  "TARGET_ARM && !arm_arch6"
1665  "muls%?\\t%0, %2, %1"
1666  [(set_attr "conds" "set")
1667   (set_attr "type" "muls")]
1668)
1669
1670(define_insn "*mulsi_compare0_scratch_v6"
1671  [(set (reg:CC_NOOV CC_REGNUM)
1672	(compare:CC_NOOV (mult:SI
1673			  (match_operand:SI 2 "s_register_operand" "r")
1674			  (match_operand:SI 1 "s_register_operand" "r"))
1675			 (const_int 0)))
1676   (clobber (match_scratch:SI 0 "=r"))]
1677  "TARGET_ARM && arm_arch6 && optimize_size"
1678  "muls%?\\t%0, %2, %1"
1679  [(set_attr "conds" "set")
1680   (set_attr "type" "muls")]
1681)
1682
1683;; Unnamed templates to match MLA instruction.
1684
1685(define_insn "*mulsi3addsi"
1686  [(set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r,&r")
1687	(plus:SI
1688	  (mult:SI (match_operand:SI 2 "s_register_operand" "r,r,r,r")
1689		   (match_operand:SI 1 "s_register_operand" "%0,r,0,r"))
1690	  (match_operand:SI 3 "s_register_operand" "r,r,0,0")))]
1691  "TARGET_32BIT && !arm_arch6"
1692  "mla%?\\t%0, %2, %1, %3"
1693  [(set_attr "type" "mla")
1694   (set_attr "predicable" "yes")]
1695)
1696
1697(define_insn "*mulsi3addsi_v6"
1698  [(set (match_operand:SI 0 "s_register_operand" "=r")
1699	(plus:SI
1700	  (mult:SI (match_operand:SI 2 "s_register_operand" "r")
1701		   (match_operand:SI 1 "s_register_operand" "r"))
1702	  (match_operand:SI 3 "s_register_operand" "r")))]
1703  "TARGET_32BIT && arm_arch6"
1704  "mla%?\\t%0, %2, %1, %3"
1705  [(set_attr "type" "mla")
1706   (set_attr "predicable" "yes")]
1707)
1708
1709(define_insn "*mulsi3addsi_compare0"
1710  [(set (reg:CC_NOOV CC_REGNUM)
1711	(compare:CC_NOOV
1712	 (plus:SI (mult:SI
1713		   (match_operand:SI 2 "s_register_operand" "r,r,r,r")
1714		   (match_operand:SI 1 "s_register_operand" "%0,r,0,r"))
1715		  (match_operand:SI 3 "s_register_operand" "r,r,0,0"))
1716	 (const_int 0)))
1717   (set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r,&r")
1718	(plus:SI (mult:SI (match_dup 2) (match_dup 1))
1719		 (match_dup 3)))]
1720  "TARGET_ARM && arm_arch6"
1721  "mlas%?\\t%0, %2, %1, %3"
1722  [(set_attr "conds" "set")
1723   (set_attr "type" "mlas")]
1724)
1725
1726(define_insn "*mulsi3addsi_compare0_v6"
1727  [(set (reg:CC_NOOV CC_REGNUM)
1728	(compare:CC_NOOV
1729	 (plus:SI (mult:SI
1730		   (match_operand:SI 2 "s_register_operand" "r")
1731		   (match_operand:SI 1 "s_register_operand" "r"))
1732		  (match_operand:SI 3 "s_register_operand" "r"))
1733	 (const_int 0)))
1734   (set (match_operand:SI 0 "s_register_operand" "=r")
1735	(plus:SI (mult:SI (match_dup 2) (match_dup 1))
1736		 (match_dup 3)))]
1737  "TARGET_ARM && arm_arch6 && optimize_size"
1738  "mlas%?\\t%0, %2, %1, %3"
1739  [(set_attr "conds" "set")
1740   (set_attr "type" "mlas")]
1741)
1742
1743(define_insn "*mulsi3addsi_compare0_scratch"
1744  [(set (reg:CC_NOOV CC_REGNUM)
1745	(compare:CC_NOOV
1746	 (plus:SI (mult:SI
1747		   (match_operand:SI 2 "s_register_operand" "r,r,r,r")
1748		   (match_operand:SI 1 "s_register_operand" "%0,r,0,r"))
1749		  (match_operand:SI 3 "s_register_operand" "?r,r,0,0"))
1750	 (const_int 0)))
1751   (clobber (match_scratch:SI 0 "=&r,&r,&r,&r"))]
1752  "TARGET_ARM && !arm_arch6"
1753  "mlas%?\\t%0, %2, %1, %3"
1754  [(set_attr "conds" "set")
1755   (set_attr "type" "mlas")]
1756)
1757
1758(define_insn "*mulsi3addsi_compare0_scratch_v6"
1759  [(set (reg:CC_NOOV CC_REGNUM)
1760	(compare:CC_NOOV
1761	 (plus:SI (mult:SI
1762		   (match_operand:SI 2 "s_register_operand" "r")
1763		   (match_operand:SI 1 "s_register_operand" "r"))
1764		  (match_operand:SI 3 "s_register_operand" "r"))
1765	 (const_int 0)))
1766   (clobber (match_scratch:SI 0 "=r"))]
1767  "TARGET_ARM && arm_arch6 && optimize_size"
1768  "mlas%?\\t%0, %2, %1, %3"
1769  [(set_attr "conds" "set")
1770   (set_attr "type" "mlas")]
1771)
1772
1773(define_insn "*mulsi3subsi"
1774  [(set (match_operand:SI 0 "s_register_operand" "=r")
1775	(minus:SI
1776	  (match_operand:SI 3 "s_register_operand" "r")
1777	  (mult:SI (match_operand:SI 2 "s_register_operand" "r")
1778		   (match_operand:SI 1 "s_register_operand" "r"))))]
1779  "TARGET_32BIT && arm_arch_thumb2"
1780  "mls%?\\t%0, %2, %1, %3"
1781  [(set_attr "type" "mla")
1782   (set_attr "predicable" "yes")]
1783)
1784
1785(define_expand "maddsidi4"
1786  [(set (match_operand:DI 0 "s_register_operand" "")
1787	(plus:DI
1788	 (mult:DI
1789	  (sign_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1790	  (sign_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1791	 (match_operand:DI 3 "s_register_operand" "")))]
1792  "TARGET_32BIT"
1793  "")
1794
1795(define_insn "*mulsidi3adddi"
1796  [(set (match_operand:DI 0 "s_register_operand" "=&r")
1797	(plus:DI
1798	 (mult:DI
1799	  (sign_extend:DI (match_operand:SI 2 "s_register_operand" "%r"))
1800	  (sign_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1801	 (match_operand:DI 1 "s_register_operand" "0")))]
1802  "TARGET_32BIT && !arm_arch6"
1803  "smlal%?\\t%Q0, %R0, %3, %2"
1804  [(set_attr "type" "smlal")
1805   (set_attr "predicable" "yes")]
1806)
1807
1808(define_insn "*mulsidi3adddi_v6"
1809  [(set (match_operand:DI 0 "s_register_operand" "=r")
1810	(plus:DI
1811	 (mult:DI
1812	  (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r"))
1813	  (sign_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1814	 (match_operand:DI 1 "s_register_operand" "0")))]
1815  "TARGET_32BIT && arm_arch6"
1816  "smlal%?\\t%Q0, %R0, %3, %2"
1817  [(set_attr "type" "smlal")
1818   (set_attr "predicable" "yes")]
1819)
1820
1821;; 32x32->64 widening multiply.
1822;; As with mulsi3, the only difference between the v3-5 and v6+
1823;; versions of these patterns is the requirement that the output not
1824;; overlap the inputs, but that still means we have to have a named
1825;; expander and two different starred insns.
1826
1827(define_expand "mulsidi3"
1828  [(set (match_operand:DI 0 "s_register_operand" "")
1829	(mult:DI
1830	 (sign_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1831	 (sign_extend:DI (match_operand:SI 2 "s_register_operand" ""))))]
1832  "TARGET_32BIT"
1833  ""
1834)
1835
1836(define_insn "*mulsidi3_nov6"
1837  [(set (match_operand:DI 0 "s_register_operand" "=&r")
1838	(mult:DI
1839	 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "%r"))
1840	 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1841  "TARGET_32BIT && !arm_arch6"
1842  "smull%?\\t%Q0, %R0, %1, %2"
1843  [(set_attr "type" "smull")
1844   (set_attr "predicable" "yes")]
1845)
1846
1847(define_insn "*mulsidi3_v6"
1848  [(set (match_operand:DI 0 "s_register_operand" "=r")
1849	(mult:DI
1850	 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1851	 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1852  "TARGET_32BIT && arm_arch6"
1853  "smull%?\\t%Q0, %R0, %1, %2"
1854  [(set_attr "type" "smull")
1855   (set_attr "predicable" "yes")]
1856)
1857
1858(define_expand "umulsidi3"
1859  [(set (match_operand:DI 0 "s_register_operand" "")
1860	(mult:DI
1861	 (zero_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1862	 (zero_extend:DI (match_operand:SI 2 "s_register_operand" ""))))]
1863  "TARGET_32BIT"
1864  ""
1865)
1866
1867(define_insn "*umulsidi3_nov6"
1868  [(set (match_operand:DI 0 "s_register_operand" "=&r")
1869	(mult:DI
1870	 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "%r"))
1871	 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1872  "TARGET_32BIT && !arm_arch6"
1873  "umull%?\\t%Q0, %R0, %1, %2"
1874  [(set_attr "type" "umull")
1875   (set_attr "predicable" "yes")]
1876)
1877
1878(define_insn "*umulsidi3_v6"
1879  [(set (match_operand:DI 0 "s_register_operand" "=r")
1880	(mult:DI
1881	 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1882	 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1883  "TARGET_32BIT && arm_arch6"
1884  "umull%?\\t%Q0, %R0, %1, %2"
1885  [(set_attr "type" "umull")
1886   (set_attr "predicable" "yes")]
1887)
1888
1889(define_expand "umaddsidi4"
1890  [(set (match_operand:DI 0 "s_register_operand" "")
1891	(plus:DI
1892	 (mult:DI
1893	  (zero_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1894	  (zero_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1895	 (match_operand:DI 3 "s_register_operand" "")))]
1896  "TARGET_32BIT"
1897  "")
1898
1899(define_insn "*umulsidi3adddi"
1900  [(set (match_operand:DI 0 "s_register_operand" "=&r")
1901	(plus:DI
1902	 (mult:DI
1903	  (zero_extend:DI (match_operand:SI 2 "s_register_operand" "%r"))
1904	  (zero_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1905	 (match_operand:DI 1 "s_register_operand" "0")))]
1906  "TARGET_32BIT && !arm_arch6"
1907  "umlal%?\\t%Q0, %R0, %3, %2"
1908  [(set_attr "type" "umlal")
1909   (set_attr "predicable" "yes")]
1910)
1911
1912(define_insn "*umulsidi3adddi_v6"
1913  [(set (match_operand:DI 0 "s_register_operand" "=r")
1914	(plus:DI
1915	 (mult:DI
1916	  (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r"))
1917	  (zero_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1918	 (match_operand:DI 1 "s_register_operand" "0")))]
1919  "TARGET_32BIT && arm_arch6"
1920  "umlal%?\\t%Q0, %R0, %3, %2"
1921  [(set_attr "type" "umlal")
1922   (set_attr "predicable" "yes")]
1923)
1924
1925(define_expand "smulsi3_highpart"
1926  [(parallel
1927    [(set (match_operand:SI 0 "s_register_operand" "")
1928	  (truncate:SI
1929	   (lshiftrt:DI
1930	    (mult:DI
1931	     (sign_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1932	     (sign_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1933	    (const_int 32))))
1934     (clobber (match_scratch:SI 3 ""))])]
1935  "TARGET_32BIT"
1936  ""
1937)
1938
1939(define_insn "*smulsi3_highpart_nov6"
1940  [(set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1941	(truncate:SI
1942	 (lshiftrt:DI
1943	  (mult:DI
1944	   (sign_extend:DI (match_operand:SI 1 "s_register_operand" "%0,r"))
1945	   (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r,r")))
1946	  (const_int 32))))
1947   (clobber (match_scratch:SI 3 "=&r,&r"))]
1948  "TARGET_32BIT && !arm_arch6"
1949  "smull%?\\t%3, %0, %2, %1"
1950  [(set_attr "type" "smull")
1951   (set_attr "predicable" "yes")]
1952)
1953
1954(define_insn "*smulsi3_highpart_v6"
1955  [(set (match_operand:SI 0 "s_register_operand" "=r")
1956	(truncate:SI
1957	 (lshiftrt:DI
1958	  (mult:DI
1959	   (sign_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1960	   (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r")))
1961	  (const_int 32))))
1962   (clobber (match_scratch:SI 3 "=r"))]
1963  "TARGET_32BIT && arm_arch6"
1964  "smull%?\\t%3, %0, %2, %1"
1965  [(set_attr "type" "smull")
1966   (set_attr "predicable" "yes")]
1967)
1968
1969(define_expand "umulsi3_highpart"
1970  [(parallel
1971    [(set (match_operand:SI 0 "s_register_operand" "")
1972	  (truncate:SI
1973	   (lshiftrt:DI
1974	    (mult:DI
1975	     (zero_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1976	      (zero_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1977	    (const_int 32))))
1978     (clobber (match_scratch:SI 3 ""))])]
1979  "TARGET_32BIT"
1980  ""
1981)
1982
1983(define_insn "*umulsi3_highpart_nov6"
1984  [(set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1985	(truncate:SI
1986	 (lshiftrt:DI
1987	  (mult:DI
1988	   (zero_extend:DI (match_operand:SI 1 "s_register_operand" "%0,r"))
1989	   (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r,r")))
1990	  (const_int 32))))
1991   (clobber (match_scratch:SI 3 "=&r,&r"))]
1992  "TARGET_32BIT && !arm_arch6"
1993  "umull%?\\t%3, %0, %2, %1"
1994  [(set_attr "type" "umull")
1995   (set_attr "predicable" "yes")]
1996)
1997
1998(define_insn "*umulsi3_highpart_v6"
1999  [(set (match_operand:SI 0 "s_register_operand" "=r")
2000	(truncate:SI
2001	 (lshiftrt:DI
2002	  (mult:DI
2003	   (zero_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
2004	   (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r")))
2005	  (const_int 32))))
2006   (clobber (match_scratch:SI 3 "=r"))]
2007  "TARGET_32BIT && arm_arch6"
2008  "umull%?\\t%3, %0, %2, %1"
2009  [(set_attr "type" "umull")
2010   (set_attr "predicable" "yes")]
2011)
2012
2013(define_insn "mulhisi3"
2014  [(set (match_operand:SI 0 "s_register_operand" "=r")
2015	(mult:SI (sign_extend:SI
2016		  (match_operand:HI 1 "s_register_operand" "%r"))
2017		 (sign_extend:SI
2018		  (match_operand:HI 2 "s_register_operand" "r"))))]
2019  "TARGET_DSP_MULTIPLY"
2020  "smulbb%?\\t%0, %1, %2"
2021  [(set_attr "type" "smulxy")
2022   (set_attr "predicable" "yes")]
2023)
2024
2025(define_insn "*mulhisi3tb"
2026  [(set (match_operand:SI 0 "s_register_operand" "=r")
2027	(mult:SI (ashiftrt:SI
2028		  (match_operand:SI 1 "s_register_operand" "r")
2029		  (const_int 16))
2030		 (sign_extend:SI
2031		  (match_operand:HI 2 "s_register_operand" "r"))))]
2032  "TARGET_DSP_MULTIPLY"
2033  "smultb%?\\t%0, %1, %2"
2034  [(set_attr "type" "smulxy")
2035   (set_attr "predicable" "yes")]
2036)
2037
2038(define_insn "*mulhisi3bt"
2039  [(set (match_operand:SI 0 "s_register_operand" "=r")
2040	(mult:SI (sign_extend:SI
2041		  (match_operand:HI 1 "s_register_operand" "r"))
2042		 (ashiftrt:SI
2043		  (match_operand:SI 2 "s_register_operand" "r")
2044		  (const_int 16))))]
2045  "TARGET_DSP_MULTIPLY"
2046  "smulbt%?\\t%0, %1, %2"
2047  [(set_attr "type" "smulxy")
2048   (set_attr "predicable" "yes")]
2049)
2050
2051(define_insn "*mulhisi3tt"
2052  [(set (match_operand:SI 0 "s_register_operand" "=r")
2053	(mult:SI (ashiftrt:SI
2054		  (match_operand:SI 1 "s_register_operand" "r")
2055		  (const_int 16))
2056		 (ashiftrt:SI
2057		  (match_operand:SI 2 "s_register_operand" "r")
2058		  (const_int 16))))]
2059  "TARGET_DSP_MULTIPLY"
2060  "smultt%?\\t%0, %1, %2"
2061  [(set_attr "type" "smulxy")
2062   (set_attr "predicable" "yes")]
2063)
2064
2065(define_insn "maddhisi4"
2066  [(set (match_operand:SI 0 "s_register_operand" "=r")
2067	(plus:SI (mult:SI (sign_extend:SI
2068			   (match_operand:HI 1 "s_register_operand" "r"))
2069			  (sign_extend:SI
2070			   (match_operand:HI 2 "s_register_operand" "r")))
2071		 (match_operand:SI 3 "s_register_operand" "r")))]
2072  "TARGET_DSP_MULTIPLY"
2073  "smlabb%?\\t%0, %1, %2, %3"
2074  [(set_attr "type" "smlaxy")
2075   (set_attr "predicable" "yes")]
2076)
2077
2078;; Note: there is no maddhisi4ibt because this one is canonical form
2079(define_insn "*maddhisi4tb"
2080  [(set (match_operand:SI 0 "s_register_operand" "=r")
2081	(plus:SI (mult:SI (ashiftrt:SI
2082			   (match_operand:SI 1 "s_register_operand" "r")
2083			   (const_int 16))
2084			  (sign_extend:SI
2085			   (match_operand:HI 2 "s_register_operand" "r")))
2086		 (match_operand:SI 3 "s_register_operand" "r")))]
2087  "TARGET_DSP_MULTIPLY"
2088  "smlatb%?\\t%0, %1, %2, %3"
2089  [(set_attr "type" "smlaxy")
2090   (set_attr "predicable" "yes")]
2091)
2092
2093(define_insn "*maddhisi4tt"
2094  [(set (match_operand:SI 0 "s_register_operand" "=r")
2095	(plus:SI (mult:SI (ashiftrt:SI
2096			   (match_operand:SI 1 "s_register_operand" "r")
2097			   (const_int 16))
2098			  (ashiftrt:SI
2099			   (match_operand:SI 2 "s_register_operand" "r")
2100			   (const_int 16)))
2101		 (match_operand:SI 3 "s_register_operand" "r")))]
2102  "TARGET_DSP_MULTIPLY"
2103  "smlatt%?\\t%0, %1, %2, %3"
2104  [(set_attr "type" "smlaxy")
2105   (set_attr "predicable" "yes")]
2106)
2107
2108(define_insn "maddhidi4"
2109  [(set (match_operand:DI 0 "s_register_operand" "=r")
2110	(plus:DI
2111	  (mult:DI (sign_extend:DI
2112		    (match_operand:HI 1 "s_register_operand" "r"))
2113		   (sign_extend:DI
2114		    (match_operand:HI 2 "s_register_operand" "r")))
2115	  (match_operand:DI 3 "s_register_operand" "0")))]
2116  "TARGET_DSP_MULTIPLY"
2117  "smlalbb%?\\t%Q0, %R0, %1, %2"
2118  [(set_attr "type" "smlalxy")
2119   (set_attr "predicable" "yes")])
2120
2121;; Note: there is no maddhidi4ibt because this one is canonical form
2122(define_insn "*maddhidi4tb"
2123  [(set (match_operand:DI 0 "s_register_operand" "=r")
2124	(plus:DI
2125	  (mult:DI (sign_extend:DI
2126		    (ashiftrt:SI
2127		     (match_operand:SI 1 "s_register_operand" "r")
2128		     (const_int 16)))
2129		   (sign_extend:DI
2130		    (match_operand:HI 2 "s_register_operand" "r")))
2131	  (match_operand:DI 3 "s_register_operand" "0")))]
2132  "TARGET_DSP_MULTIPLY"
2133  "smlaltb%?\\t%Q0, %R0, %1, %2"
2134  [(set_attr "type" "smlalxy")
2135   (set_attr "predicable" "yes")])
2136
2137(define_insn "*maddhidi4tt"
2138  [(set (match_operand:DI 0 "s_register_operand" "=r")
2139	(plus:DI
2140	  (mult:DI (sign_extend:DI
2141		    (ashiftrt:SI
2142		     (match_operand:SI 1 "s_register_operand" "r")
2143		     (const_int 16)))
2144		   (sign_extend:DI
2145		    (ashiftrt:SI
2146		     (match_operand:SI 2 "s_register_operand" "r")
2147		     (const_int 16))))
2148	  (match_operand:DI 3 "s_register_operand" "0")))]
2149  "TARGET_DSP_MULTIPLY"
2150  "smlaltt%?\\t%Q0, %R0, %1, %2"
2151  [(set_attr "type" "smlalxy")
2152   (set_attr "predicable" "yes")])
2153
2154(define_expand "mulsf3"
2155  [(set (match_operand:SF          0 "s_register_operand" "")
2156	(mult:SF (match_operand:SF 1 "s_register_operand" "")
2157		 (match_operand:SF 2 "s_register_operand" "")))]
2158  "TARGET_32BIT && TARGET_HARD_FLOAT"
2159  "
2160")
2161
2162(define_expand "muldf3"
2163  [(set (match_operand:DF          0 "s_register_operand" "")
2164	(mult:DF (match_operand:DF 1 "s_register_operand" "")
2165		 (match_operand:DF 2 "s_register_operand" "")))]
2166  "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
2167  "
2168")
2169
2170;; Division insns
2171
2172(define_expand "divsf3"
2173  [(set (match_operand:SF 0 "s_register_operand" "")
2174	(div:SF (match_operand:SF 1 "s_register_operand" "")
2175		(match_operand:SF 2 "s_register_operand" "")))]
2176  "TARGET_32BIT && TARGET_HARD_FLOAT"
2177  "")
2178
2179(define_expand "divdf3"
2180  [(set (match_operand:DF 0 "s_register_operand" "")
2181	(div:DF (match_operand:DF 1 "s_register_operand" "")
2182		(match_operand:DF 2 "s_register_operand" "")))]
2183  "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
2184  "")
2185
2186;; Boolean and,ior,xor insns
2187
2188;; Split up double word logical operations
2189
2190;; Split up simple DImode logical operations.  Simply perform the logical
2191;; operation on the upper and lower halves of the registers.
2192(define_split
2193  [(set (match_operand:DI 0 "s_register_operand" "")
2194	(match_operator:DI 6 "logical_binary_operator"
2195	  [(match_operand:DI 1 "s_register_operand" "")
2196	   (match_operand:DI 2 "s_register_operand" "")]))]
2197  "TARGET_32BIT && reload_completed
2198   && ! (TARGET_NEON && IS_VFP_REGNUM (REGNO (operands[0])))
2199   && ! IS_IWMMXT_REGNUM (REGNO (operands[0]))"
2200  [(set (match_dup 0) (match_op_dup:SI 6 [(match_dup 1) (match_dup 2)]))
2201   (set (match_dup 3) (match_op_dup:SI 6 [(match_dup 4) (match_dup 5)]))]
2202  "
2203  {
2204    operands[3] = gen_highpart (SImode, operands[0]);
2205    operands[0] = gen_lowpart (SImode, operands[0]);
2206    operands[4] = gen_highpart (SImode, operands[1]);
2207    operands[1] = gen_lowpart (SImode, operands[1]);
2208    operands[5] = gen_highpart (SImode, operands[2]);
2209    operands[2] = gen_lowpart (SImode, operands[2]);
2210  }"
2211)
2212
2213(define_split
2214  [(set (match_operand:DI 0 "s_register_operand" "")
2215	(match_operator:DI 6 "logical_binary_operator"
2216	  [(sign_extend:DI (match_operand:SI 2 "s_register_operand" ""))
2217	   (match_operand:DI 1 "s_register_operand" "")]))]
2218  "TARGET_32BIT && reload_completed"
2219  [(set (match_dup 0) (match_op_dup:SI 6 [(match_dup 1) (match_dup 2)]))
2220   (set (match_dup 3) (match_op_dup:SI 6
2221			[(ashiftrt:SI (match_dup 2) (const_int 31))
2222			 (match_dup 4)]))]
2223  "
2224  {
2225    operands[3] = gen_highpart (SImode, operands[0]);
2226    operands[0] = gen_lowpart (SImode, operands[0]);
2227    operands[4] = gen_highpart (SImode, operands[1]);
2228    operands[1] = gen_lowpart (SImode, operands[1]);
2229    operands[5] = gen_highpart (SImode, operands[2]);
2230    operands[2] = gen_lowpart (SImode, operands[2]);
2231  }"
2232)
2233
2234;; The zero extend of operand 2 means we can just copy the high part of
2235;; operand1 into operand0.
2236(define_split
2237  [(set (match_operand:DI 0 "s_register_operand" "")
2238	(ior:DI
2239	  (zero_extend:DI (match_operand:SI 2 "s_register_operand" ""))
2240	  (match_operand:DI 1 "s_register_operand" "")))]
2241  "TARGET_32BIT && operands[0] != operands[1] && reload_completed"
2242  [(set (match_dup 0) (ior:SI (match_dup 1) (match_dup 2)))
2243   (set (match_dup 3) (match_dup 4))]
2244  "
2245  {
2246    operands[4] = gen_highpart (SImode, operands[1]);
2247    operands[3] = gen_highpart (SImode, operands[0]);
2248    operands[0] = gen_lowpart (SImode, operands[0]);
2249    operands[1] = gen_lowpart (SImode, operands[1]);
2250  }"
2251)
2252
2253;; The zero extend of operand 2 means we can just copy the high part of
2254;; operand1 into operand0.
2255(define_split
2256  [(set (match_operand:DI 0 "s_register_operand" "")
2257	(xor:DI
2258	  (zero_extend:DI (match_operand:SI 2 "s_register_operand" ""))
2259	  (match_operand:DI 1 "s_register_operand" "")))]
2260  "TARGET_32BIT && operands[0] != operands[1] && reload_completed"
2261  [(set (match_dup 0) (xor:SI (match_dup 1) (match_dup 2)))
2262   (set (match_dup 3) (match_dup 4))]
2263  "
2264  {
2265    operands[4] = gen_highpart (SImode, operands[1]);
2266    operands[3] = gen_highpart (SImode, operands[0]);
2267    operands[0] = gen_lowpart (SImode, operands[0]);
2268    operands[1] = gen_lowpart (SImode, operands[1]);
2269  }"
2270)
2271
2272(define_expand "anddi3"
2273  [(set (match_operand:DI         0 "s_register_operand" "")
2274	(and:DI (match_operand:DI 1 "s_register_operand" "")
2275		(match_operand:DI 2 "neon_inv_logic_op2" "")))]
2276  "TARGET_32BIT"
2277  "
2278  if (!TARGET_NEON && !TARGET_IWMMXT)
2279    {
2280      rtx low  = simplify_gen_binary (AND, SImode,
2281				      gen_lowpart (SImode, operands[1]),
2282				      gen_lowpart (SImode, operands[2]));
2283      rtx high = simplify_gen_binary (AND, SImode,
2284				      gen_highpart (SImode, operands[1]),
2285				      gen_highpart_mode (SImode, DImode,
2286							 operands[2]));
2287
2288      emit_insn (gen_rtx_SET (gen_lowpart (SImode, operands[0]), low));
2289      emit_insn (gen_rtx_SET (gen_highpart (SImode, operands[0]), high));
2290
2291      DONE;
2292    }
2293  /* Otherwise expand pattern as above.  */
2294  "
2295)
2296
2297(define_insn_and_split "*anddi3_insn"
2298  [(set (match_operand:DI         0 "s_register_operand"     "=w,w ,&r,&r,&r,&r,?w,?w")
2299        (and:DI (match_operand:DI 1 "s_register_operand"     "%w,0 ,0 ,r ,0 ,r ,w ,0")
2300                (match_operand:DI 2 "arm_anddi_operand_neon" "w ,DL,r ,r ,De,De,w ,DL")))]
2301  "TARGET_32BIT && !TARGET_IWMMXT"
2302{
2303  switch (which_alternative)
2304    {
2305    case 0: /* fall through */
2306    case 6: return "vand\t%P0, %P1, %P2";
2307    case 1: /* fall through */
2308    case 7: return neon_output_logic_immediate ("vand", &operands[2],
2309                    DImode, 1, VALID_NEON_QREG_MODE (DImode));
2310    case 2:
2311    case 3:
2312    case 4:
2313    case 5: /* fall through */
2314      return "#";
2315    default: gcc_unreachable ();
2316    }
2317}
2318  "TARGET_32BIT && !TARGET_IWMMXT && reload_completed
2319   && !(IS_VFP_REGNUM (REGNO (operands[0])))"
2320  [(set (match_dup 3) (match_dup 4))
2321   (set (match_dup 5) (match_dup 6))]
2322  "
2323  {
2324    operands[3] = gen_lowpart (SImode, operands[0]);
2325    operands[5] = gen_highpart (SImode, operands[0]);
2326
2327    operands[4] = simplify_gen_binary (AND, SImode,
2328                                           gen_lowpart (SImode, operands[1]),
2329                                           gen_lowpart (SImode, operands[2]));
2330    operands[6] = simplify_gen_binary (AND, SImode,
2331                                           gen_highpart (SImode, operands[1]),
2332                                           gen_highpart_mode (SImode, DImode, operands[2]));
2333
2334  }"
2335  [(set_attr "type" "neon_logic,neon_logic,multiple,multiple,\
2336                     multiple,multiple,neon_logic,neon_logic")
2337   (set_attr "arch" "neon_for_64bits,neon_for_64bits,*,*,*,*,
2338                     avoid_neon_for_64bits,avoid_neon_for_64bits")
2339   (set_attr "length" "*,*,8,8,8,8,*,*")
2340  ]
2341)
2342
2343(define_insn_and_split "*anddi_zesidi_di"
2344  [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2345	(and:DI (zero_extend:DI
2346		 (match_operand:SI 2 "s_register_operand" "r,r"))
2347		(match_operand:DI 1 "s_register_operand" "0,r")))]
2348  "TARGET_32BIT"
2349  "#"
2350  "TARGET_32BIT && reload_completed"
2351  ; The zero extend of operand 2 clears the high word of the output
2352  ; operand.
2353  [(set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))
2354   (set (match_dup 3) (const_int 0))]
2355  "
2356  {
2357    operands[3] = gen_highpart (SImode, operands[0]);
2358    operands[0] = gen_lowpart (SImode, operands[0]);
2359    operands[1] = gen_lowpart (SImode, operands[1]);
2360  }"
2361  [(set_attr "length" "8")
2362   (set_attr "type" "multiple")]
2363)
2364
2365(define_insn "*anddi_sesdi_di"
2366  [(set (match_operand:DI          0 "s_register_operand" "=&r,&r")
2367	(and:DI (sign_extend:DI
2368		 (match_operand:SI 2 "s_register_operand" "r,r"))
2369		(match_operand:DI  1 "s_register_operand" "0,r")))]
2370  "TARGET_32BIT"
2371  "#"
2372  [(set_attr "length" "8")
2373   (set_attr "type" "multiple")]
2374)
2375
2376(define_expand "andsi3"
2377  [(set (match_operand:SI         0 "s_register_operand" "")
2378	(and:SI (match_operand:SI 1 "s_register_operand" "")
2379		(match_operand:SI 2 "reg_or_int_operand" "")))]
2380  "TARGET_EITHER"
2381  "
2382  if (TARGET_32BIT)
2383    {
2384      if (CONST_INT_P (operands[2]))
2385        {
2386	  if (INTVAL (operands[2]) == 255 && arm_arch6)
2387	    {
2388	      operands[1] = convert_to_mode (QImode, operands[1], 1);
2389	      emit_insn (gen_thumb2_zero_extendqisi2_v6 (operands[0],
2390							 operands[1]));
2391	      DONE;
2392	    }
2393	  else if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[2]), AND))
2394	    operands[2] = force_reg (SImode, operands[2]);
2395	  else
2396	    {
2397	      arm_split_constant (AND, SImode, NULL_RTX,
2398				  INTVAL (operands[2]), operands[0],
2399				  operands[1],
2400				  optimize && can_create_pseudo_p ());
2401
2402	      DONE;
2403	    }
2404        }
2405    }
2406  else /* TARGET_THUMB1 */
2407    {
2408      if (!CONST_INT_P (operands[2]))
2409        {
2410          rtx tmp = force_reg (SImode, operands[2]);
2411	  if (rtx_equal_p (operands[0], operands[1]))
2412	    operands[2] = tmp;
2413	  else
2414	    {
2415              operands[2] = operands[1];
2416              operands[1] = tmp;
2417	    }
2418        }
2419      else
2420        {
2421          int i;
2422
2423          if (((unsigned HOST_WIDE_INT) ~INTVAL (operands[2])) < 256)
2424  	    {
2425	      operands[2] = force_reg (SImode,
2426				       GEN_INT (~INTVAL (operands[2])));
2427
2428	      emit_insn (gen_thumb1_bicsi3 (operands[0], operands[2], operands[1]));
2429
2430	      DONE;
2431	    }
2432
2433          for (i = 9; i <= 31; i++)
2434	    {
2435	      if ((HOST_WIDE_INT_1 << i) - 1 == INTVAL (operands[2]))
2436	        {
2437	          emit_insn (gen_extzv (operands[0], operands[1], GEN_INT (i),
2438			 	        const0_rtx));
2439	          DONE;
2440	        }
2441	      else if ((HOST_WIDE_INT_1 << i) - 1
2442		       == ~INTVAL (operands[2]))
2443	        {
2444	          rtx shift = GEN_INT (i);
2445	          rtx reg = gen_reg_rtx (SImode);
2446
2447	          emit_insn (gen_lshrsi3 (reg, operands[1], shift));
2448	          emit_insn (gen_ashlsi3 (operands[0], reg, shift));
2449
2450	          DONE;
2451	        }
2452	    }
2453
2454          operands[2] = force_reg (SImode, operands[2]);
2455        }
2456    }
2457  "
2458)
2459
2460; ??? Check split length for Thumb-2
2461(define_insn_and_split "*arm_andsi3_insn"
2462  [(set (match_operand:SI         0 "s_register_operand" "=r,l,r,r,r")
2463	(and:SI (match_operand:SI 1 "s_register_operand" "%r,0,r,r,r")
2464		(match_operand:SI 2 "reg_or_int_operand" "I,l,K,r,?n")))]
2465  "TARGET_32BIT"
2466  "@
2467   and%?\\t%0, %1, %2
2468   and%?\\t%0, %1, %2
2469   bic%?\\t%0, %1, #%B2
2470   and%?\\t%0, %1, %2
2471   #"
2472  "TARGET_32BIT
2473   && CONST_INT_P (operands[2])
2474   && !(const_ok_for_arm (INTVAL (operands[2]))
2475	|| const_ok_for_arm (~INTVAL (operands[2])))"
2476  [(clobber (const_int 0))]
2477  "
2478  arm_split_constant  (AND, SImode, curr_insn,
2479	               INTVAL (operands[2]), operands[0], operands[1], 0);
2480  DONE;
2481  "
2482  [(set_attr "length" "4,4,4,4,16")
2483   (set_attr "predicable" "yes")
2484   (set_attr "predicable_short_it" "no,yes,no,no,no")
2485   (set_attr "type" "logic_imm,logic_imm,logic_reg,logic_reg,logic_imm")]
2486)
2487
2488(define_insn "*andsi3_compare0"
2489  [(set (reg:CC_NOOV CC_REGNUM)
2490	(compare:CC_NOOV
2491	 (and:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
2492		 (match_operand:SI 2 "arm_not_operand" "I,K,r"))
2493	 (const_int 0)))
2494   (set (match_operand:SI          0 "s_register_operand" "=r,r,r")
2495	(and:SI (match_dup 1) (match_dup 2)))]
2496  "TARGET_32BIT"
2497  "@
2498   ands%?\\t%0, %1, %2
2499   bics%?\\t%0, %1, #%B2
2500   ands%?\\t%0, %1, %2"
2501  [(set_attr "conds" "set")
2502   (set_attr "type" "logics_imm,logics_imm,logics_reg")]
2503)
2504
2505(define_insn "*andsi3_compare0_scratch"
2506  [(set (reg:CC_NOOV CC_REGNUM)
2507	(compare:CC_NOOV
2508	 (and:SI (match_operand:SI 0 "s_register_operand" "r,r,r")
2509		 (match_operand:SI 1 "arm_not_operand" "I,K,r"))
2510	 (const_int 0)))
2511   (clobber (match_scratch:SI 2 "=X,r,X"))]
2512  "TARGET_32BIT"
2513  "@
2514   tst%?\\t%0, %1
2515   bics%?\\t%2, %0, #%B1
2516   tst%?\\t%0, %1"
2517  [(set_attr "conds" "set")
2518   (set_attr "type"  "logics_imm,logics_imm,logics_reg")]
2519)
2520
2521(define_insn "*zeroextractsi_compare0_scratch"
2522  [(set (reg:CC_NOOV CC_REGNUM)
2523	(compare:CC_NOOV (zero_extract:SI
2524			  (match_operand:SI 0 "s_register_operand" "r")
2525			  (match_operand 1 "const_int_operand" "n")
2526			  (match_operand 2 "const_int_operand" "n"))
2527			 (const_int 0)))]
2528  "TARGET_32BIT
2529  && (INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) < 32
2530      && INTVAL (operands[1]) > 0
2531      && INTVAL (operands[1]) + (INTVAL (operands[2]) & 1) <= 8
2532      && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32)"
2533  "*
2534  operands[1] = GEN_INT (((1 << INTVAL (operands[1])) - 1)
2535			 << INTVAL (operands[2]));
2536  output_asm_insn (\"tst%?\\t%0, %1\", operands);
2537  return \"\";
2538  "
2539  [(set_attr "conds" "set")
2540   (set_attr "predicable" "yes")
2541   (set_attr "type" "logics_imm")]
2542)
2543
2544(define_insn_and_split "*ne_zeroextractsi"
2545  [(set (match_operand:SI 0 "s_register_operand" "=r")
2546	(ne:SI (zero_extract:SI
2547		(match_operand:SI 1 "s_register_operand" "r")
2548		(match_operand:SI 2 "const_int_operand" "n")
2549		(match_operand:SI 3 "const_int_operand" "n"))
2550	       (const_int 0)))
2551   (clobber (reg:CC CC_REGNUM))]
2552  "TARGET_32BIT
2553   && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2554       && INTVAL (operands[2]) > 0
2555       && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2556       && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)"
2557  "#"
2558  "TARGET_32BIT
2559   && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2560       && INTVAL (operands[2]) > 0
2561       && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2562       && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)"
2563  [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2564		   (compare:CC_NOOV (and:SI (match_dup 1) (match_dup 2))
2565				    (const_int 0)))
2566	      (set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))])
2567   (set (match_dup 0)
2568	(if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2569			 (match_dup 0) (const_int 1)))]
2570  "
2571  operands[2] = GEN_INT (((1 << INTVAL (operands[2])) - 1)
2572			 << INTVAL (operands[3]));
2573  "
2574  [(set_attr "conds" "clob")
2575   (set (attr "length")
2576	(if_then_else (eq_attr "is_thumb" "yes")
2577		      (const_int 12)
2578		      (const_int 8)))
2579   (set_attr "type" "multiple")]
2580)
2581
2582(define_insn_and_split "*ne_zeroextractsi_shifted"
2583  [(set (match_operand:SI 0 "s_register_operand" "=r")
2584	(ne:SI (zero_extract:SI
2585		(match_operand:SI 1 "s_register_operand" "r")
2586		(match_operand:SI 2 "const_int_operand" "n")
2587		(const_int 0))
2588	       (const_int 0)))
2589   (clobber (reg:CC CC_REGNUM))]
2590  "TARGET_ARM"
2591  "#"
2592  "TARGET_ARM"
2593  [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2594		   (compare:CC_NOOV (ashift:SI (match_dup 1) (match_dup 2))
2595				    (const_int 0)))
2596	      (set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))])
2597   (set (match_dup 0)
2598	(if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2599			 (match_dup 0) (const_int 1)))]
2600  "
2601  operands[2] = GEN_INT (32 - INTVAL (operands[2]));
2602  "
2603  [(set_attr "conds" "clob")
2604   (set_attr "length" "8")
2605   (set_attr "type" "multiple")]
2606)
2607
2608(define_insn_and_split "*ite_ne_zeroextractsi"
2609  [(set (match_operand:SI 0 "s_register_operand" "=r")
2610	(if_then_else:SI (ne (zero_extract:SI
2611			      (match_operand:SI 1 "s_register_operand" "r")
2612			      (match_operand:SI 2 "const_int_operand" "n")
2613			      (match_operand:SI 3 "const_int_operand" "n"))
2614			     (const_int 0))
2615			 (match_operand:SI 4 "arm_not_operand" "rIK")
2616			 (const_int 0)))
2617   (clobber (reg:CC CC_REGNUM))]
2618  "TARGET_ARM
2619   && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2620       && INTVAL (operands[2]) > 0
2621       && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2622       && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)
2623   && !reg_overlap_mentioned_p (operands[0], operands[4])"
2624  "#"
2625  "TARGET_ARM
2626   && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2627       && INTVAL (operands[2]) > 0
2628       && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2629       && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)
2630   && !reg_overlap_mentioned_p (operands[0], operands[4])"
2631  [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2632		   (compare:CC_NOOV (and:SI (match_dup 1) (match_dup 2))
2633				    (const_int 0)))
2634	      (set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))])
2635   (set (match_dup 0)
2636	(if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2637			 (match_dup 0) (match_dup 4)))]
2638  "
2639  operands[2] = GEN_INT (((1 << INTVAL (operands[2])) - 1)
2640			 << INTVAL (operands[3]));
2641  "
2642  [(set_attr "conds" "clob")
2643   (set_attr "length" "8")
2644   (set_attr "type" "multiple")]
2645)
2646
2647(define_insn_and_split "*ite_ne_zeroextractsi_shifted"
2648  [(set (match_operand:SI 0 "s_register_operand" "=r")
2649	(if_then_else:SI (ne (zero_extract:SI
2650			      (match_operand:SI 1 "s_register_operand" "r")
2651			      (match_operand:SI 2 "const_int_operand" "n")
2652			      (const_int 0))
2653			     (const_int 0))
2654			 (match_operand:SI 3 "arm_not_operand" "rIK")
2655			 (const_int 0)))
2656   (clobber (reg:CC CC_REGNUM))]
2657  "TARGET_ARM && !reg_overlap_mentioned_p (operands[0], operands[3])"
2658  "#"
2659  "TARGET_ARM && !reg_overlap_mentioned_p (operands[0], operands[3])"
2660  [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2661		   (compare:CC_NOOV (ashift:SI (match_dup 1) (match_dup 2))
2662				    (const_int 0)))
2663	      (set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))])
2664   (set (match_dup 0)
2665	(if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2666			 (match_dup 0) (match_dup 3)))]
2667  "
2668  operands[2] = GEN_INT (32 - INTVAL (operands[2]));
2669  "
2670  [(set_attr "conds" "clob")
2671   (set_attr "length" "8")
2672   (set_attr "type" "multiple")]
2673)
2674
2675;; ??? Use Thumb-2 has bitfield insert/extract instructions.
2676(define_split
2677  [(set (match_operand:SI 0 "s_register_operand" "")
2678	(match_operator:SI 1 "shiftable_operator"
2679	 [(zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
2680			   (match_operand:SI 3 "const_int_operand" "")
2681			   (match_operand:SI 4 "const_int_operand" ""))
2682	  (match_operand:SI 5 "s_register_operand" "")]))
2683   (clobber (match_operand:SI 6 "s_register_operand" ""))]
2684  "TARGET_ARM"
2685  [(set (match_dup 6) (ashift:SI (match_dup 2) (match_dup 3)))
2686   (set (match_dup 0)
2687	(match_op_dup 1
2688	 [(lshiftrt:SI (match_dup 6) (match_dup 4))
2689	  (match_dup 5)]))]
2690  "{
2691     HOST_WIDE_INT temp = INTVAL (operands[3]);
2692
2693     operands[3] = GEN_INT (32 - temp - INTVAL (operands[4]));
2694     operands[4] = GEN_INT (32 - temp);
2695   }"
2696)
2697
2698(define_split
2699  [(set (match_operand:SI 0 "s_register_operand" "")
2700	(match_operator:SI 1 "shiftable_operator"
2701	 [(sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
2702			   (match_operand:SI 3 "const_int_operand" "")
2703			   (match_operand:SI 4 "const_int_operand" ""))
2704	  (match_operand:SI 5 "s_register_operand" "")]))
2705   (clobber (match_operand:SI 6 "s_register_operand" ""))]
2706  "TARGET_ARM"
2707  [(set (match_dup 6) (ashift:SI (match_dup 2) (match_dup 3)))
2708   (set (match_dup 0)
2709	(match_op_dup 1
2710	 [(ashiftrt:SI (match_dup 6) (match_dup 4))
2711	  (match_dup 5)]))]
2712  "{
2713     HOST_WIDE_INT temp = INTVAL (operands[3]);
2714
2715     operands[3] = GEN_INT (32 - temp - INTVAL (operands[4]));
2716     operands[4] = GEN_INT (32 - temp);
2717   }"
2718)
2719
2720;;; ??? This pattern is bogus.  If operand3 has bits outside the range
2721;;; represented by the bitfield, then this will produce incorrect results.
2722;;; Somewhere, the value needs to be truncated.  On targets like the m68k,
2723;;; which have a real bit-field insert instruction, the truncation happens
2724;;; in the bit-field insert instruction itself.  Since arm does not have a
2725;;; bit-field insert instruction, we would have to emit code here to truncate
2726;;; the value before we insert.  This loses some of the advantage of having
2727;;; this insv pattern, so this pattern needs to be reevalutated.
2728
2729(define_expand "insv"
2730  [(set (zero_extract (match_operand 0 "nonimmediate_operand" "")
2731                      (match_operand 1 "general_operand" "")
2732                      (match_operand 2 "general_operand" ""))
2733        (match_operand 3 "reg_or_int_operand" ""))]
2734  "TARGET_ARM || arm_arch_thumb2"
2735  "
2736  {
2737    int start_bit = INTVAL (operands[2]);
2738    int width = INTVAL (operands[1]);
2739    HOST_WIDE_INT mask = (HOST_WIDE_INT_1 << width) - 1;
2740    rtx target, subtarget;
2741
2742    if (arm_arch_thumb2)
2743      {
2744        if (unaligned_access && MEM_P (operands[0])
2745	    && s_register_operand (operands[3], GET_MODE (operands[3]))
2746	    && (width == 16 || width == 32) && (start_bit % BITS_PER_UNIT) == 0)
2747	  {
2748	    rtx base_addr;
2749
2750	    if (BYTES_BIG_ENDIAN)
2751	      start_bit = GET_MODE_BITSIZE (GET_MODE (operands[3])) - width
2752			  - start_bit;
2753
2754	    if (width == 32)
2755	      {
2756	        base_addr = adjust_address (operands[0], SImode,
2757					    start_bit / BITS_PER_UNIT);
2758		emit_insn (gen_unaligned_storesi (base_addr, operands[3]));
2759	      }
2760	    else
2761	      {
2762	        rtx tmp = gen_reg_rtx (HImode);
2763
2764	        base_addr = adjust_address (operands[0], HImode,
2765					    start_bit / BITS_PER_UNIT);
2766		emit_move_insn (tmp, gen_lowpart (HImode, operands[3]));
2767		emit_insn (gen_unaligned_storehi (base_addr, tmp));
2768	      }
2769	    DONE;
2770	  }
2771	else if (s_register_operand (operands[0], GET_MODE (operands[0])))
2772	  {
2773	    bool use_bfi = TRUE;
2774
2775	    if (CONST_INT_P (operands[3]))
2776	      {
2777		HOST_WIDE_INT val = INTVAL (operands[3]) & mask;
2778
2779		if (val == 0)
2780		  {
2781		    emit_insn (gen_insv_zero (operands[0], operands[1],
2782					      operands[2]));
2783		    DONE;
2784		  }
2785
2786		/* See if the set can be done with a single orr instruction.  */
2787		if (val == mask && const_ok_for_arm (val << start_bit))
2788		  use_bfi = FALSE;
2789	      }
2790
2791	    if (use_bfi)
2792	      {
2793		if (!REG_P (operands[3]))
2794		  operands[3] = force_reg (SImode, operands[3]);
2795
2796		emit_insn (gen_insv_t2 (operands[0], operands[1], operands[2],
2797					operands[3]));
2798		DONE;
2799	      }
2800	  }
2801	else
2802	  FAIL;
2803      }
2804
2805    if (!s_register_operand (operands[0], GET_MODE (operands[0])))
2806      FAIL;
2807
2808    target = copy_rtx (operands[0]);
2809    /* Avoid using a subreg as a subtarget, and avoid writing a paradoxical
2810       subreg as the final target.  */
2811    if (GET_CODE (target) == SUBREG)
2812      {
2813	subtarget = gen_reg_rtx (SImode);
2814	if (GET_MODE_SIZE (GET_MODE (SUBREG_REG (target)))
2815	    < GET_MODE_SIZE (SImode))
2816	  target = SUBREG_REG (target);
2817      }
2818    else
2819      subtarget = target;
2820
2821    if (CONST_INT_P (operands[3]))
2822      {
2823	/* Since we are inserting a known constant, we may be able to
2824	   reduce the number of bits that we have to clear so that
2825	   the mask becomes simple.  */
2826	/* ??? This code does not check to see if the new mask is actually
2827	   simpler.  It may not be.  */
2828	rtx op1 = gen_reg_rtx (SImode);
2829	/* ??? Truncate operand3 to fit in the bitfield.  See comment before
2830	   start of this pattern.  */
2831	HOST_WIDE_INT op3_value = mask & INTVAL (operands[3]);
2832	HOST_WIDE_INT mask2 = ((mask & ~op3_value) << start_bit);
2833
2834	emit_insn (gen_andsi3 (op1, operands[0],
2835			       gen_int_mode (~mask2, SImode)));
2836	emit_insn (gen_iorsi3 (subtarget, op1,
2837			       gen_int_mode (op3_value << start_bit, SImode)));
2838      }
2839    else if (start_bit == 0
2840	     && !(const_ok_for_arm (mask)
2841		  || const_ok_for_arm (~mask)))
2842      {
2843	/* A Trick, since we are setting the bottom bits in the word,
2844	   we can shift operand[3] up, operand[0] down, OR them together
2845	   and rotate the result back again.  This takes 3 insns, and
2846	   the third might be mergeable into another op.  */
2847	/* The shift up copes with the possibility that operand[3] is
2848           wider than the bitfield.  */
2849	rtx op0 = gen_reg_rtx (SImode);
2850	rtx op1 = gen_reg_rtx (SImode);
2851
2852	emit_insn (gen_ashlsi3 (op0, operands[3], GEN_INT (32 - width)));
2853	emit_insn (gen_lshrsi3 (op1, operands[0], operands[1]));
2854	emit_insn (gen_iorsi3  (op1, op1, op0));
2855	emit_insn (gen_rotlsi3 (subtarget, op1, operands[1]));
2856      }
2857    else if ((width + start_bit == 32)
2858	     && !(const_ok_for_arm (mask)
2859		  || const_ok_for_arm (~mask)))
2860      {
2861	/* Similar trick, but slightly less efficient.  */
2862
2863	rtx op0 = gen_reg_rtx (SImode);
2864	rtx op1 = gen_reg_rtx (SImode);
2865
2866	emit_insn (gen_ashlsi3 (op0, operands[3], GEN_INT (32 - width)));
2867	emit_insn (gen_ashlsi3 (op1, operands[0], operands[1]));
2868	emit_insn (gen_lshrsi3 (op1, op1, operands[1]));
2869	emit_insn (gen_iorsi3 (subtarget, op1, op0));
2870      }
2871    else
2872      {
2873	rtx op0 = gen_int_mode (mask, SImode);
2874	rtx op1 = gen_reg_rtx (SImode);
2875	rtx op2 = gen_reg_rtx (SImode);
2876
2877	if (!(const_ok_for_arm (mask) || const_ok_for_arm (~mask)))
2878	  {
2879	    rtx tmp = gen_reg_rtx (SImode);
2880
2881	    emit_insn (gen_movsi (tmp, op0));
2882	    op0 = tmp;
2883	  }
2884
2885	/* Mask out any bits in operand[3] that are not needed.  */
2886	   emit_insn (gen_andsi3 (op1, operands[3], op0));
2887
2888	if (CONST_INT_P (op0)
2889	    && (const_ok_for_arm (mask << start_bit)
2890		|| const_ok_for_arm (~(mask << start_bit))))
2891	  {
2892	    op0 = gen_int_mode (~(mask << start_bit), SImode);
2893	    emit_insn (gen_andsi3 (op2, operands[0], op0));
2894	  }
2895	else
2896	  {
2897	    if (CONST_INT_P (op0))
2898	      {
2899		rtx tmp = gen_reg_rtx (SImode);
2900
2901		emit_insn (gen_movsi (tmp, op0));
2902		op0 = tmp;
2903	      }
2904
2905	    if (start_bit != 0)
2906	      emit_insn (gen_ashlsi3 (op0, op0, operands[2]));
2907
2908	    emit_insn (gen_andsi_notsi_si (op2, operands[0], op0));
2909	  }
2910
2911	if (start_bit != 0)
2912          emit_insn (gen_ashlsi3 (op1, op1, operands[2]));
2913
2914	emit_insn (gen_iorsi3 (subtarget, op1, op2));
2915      }
2916
2917    if (subtarget != target)
2918      {
2919	/* If TARGET is still a SUBREG, then it must be wider than a word,
2920	   so we must be careful only to set the subword we were asked to.  */
2921	if (GET_CODE (target) == SUBREG)
2922	  emit_move_insn (target, subtarget);
2923	else
2924	  emit_move_insn (target, gen_lowpart (GET_MODE (target), subtarget));
2925      }
2926
2927    DONE;
2928  }"
2929)
2930
2931(define_insn "insv_zero"
2932  [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r")
2933                         (match_operand:SI 1 "const_int_M_operand" "M")
2934                         (match_operand:SI 2 "const_int_M_operand" "M"))
2935        (const_int 0))]
2936  "arm_arch_thumb2"
2937  "bfc%?\t%0, %2, %1"
2938  [(set_attr "length" "4")
2939   (set_attr "predicable" "yes")
2940   (set_attr "type" "bfm")]
2941)
2942
2943(define_insn "insv_t2"
2944  [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r")
2945                         (match_operand:SI 1 "const_int_M_operand" "M")
2946                         (match_operand:SI 2 "const_int_M_operand" "M"))
2947        (match_operand:SI 3 "s_register_operand" "r"))]
2948  "arm_arch_thumb2"
2949  "bfi%?\t%0, %3, %2, %1"
2950  [(set_attr "length" "4")
2951   (set_attr "predicable" "yes")
2952   (set_attr "type" "bfm")]
2953)
2954
2955; constants for op 2 will never be given to these patterns.
2956(define_insn_and_split "*anddi_notdi_di"
2957  [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2958	(and:DI (not:DI (match_operand:DI 1 "s_register_operand" "0,r"))
2959		(match_operand:DI 2 "s_register_operand" "r,0")))]
2960  "TARGET_32BIT"
2961  "#"
2962  "TARGET_32BIT && reload_completed
2963   && ! (TARGET_NEON && IS_VFP_REGNUM (REGNO (operands[0])))
2964   && ! IS_IWMMXT_REGNUM (REGNO (operands[0]))"
2965  [(set (match_dup 0) (and:SI (not:SI (match_dup 1)) (match_dup 2)))
2966   (set (match_dup 3) (and:SI (not:SI (match_dup 4)) (match_dup 5)))]
2967  "
2968  {
2969    operands[3] = gen_highpart (SImode, operands[0]);
2970    operands[0] = gen_lowpart (SImode, operands[0]);
2971    operands[4] = gen_highpart (SImode, operands[1]);
2972    operands[1] = gen_lowpart (SImode, operands[1]);
2973    operands[5] = gen_highpart (SImode, operands[2]);
2974    operands[2] = gen_lowpart (SImode, operands[2]);
2975  }"
2976  [(set_attr "length" "8")
2977   (set_attr "predicable" "yes")
2978   (set_attr "type" "multiple")]
2979)
2980
2981(define_insn_and_split "*anddi_notzesidi_di"
2982  [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2983	(and:DI (not:DI (zero_extend:DI
2984			 (match_operand:SI 2 "s_register_operand" "r,r")))
2985		(match_operand:DI 1 "s_register_operand" "0,?r")))]
2986  "TARGET_32BIT"
2987  "@
2988   bic%?\\t%Q0, %Q1, %2
2989   #"
2990  ; (not (zero_extend ...)) allows us to just copy the high word from
2991  ; operand1 to operand0.
2992  "TARGET_32BIT
2993   && reload_completed
2994   && operands[0] != operands[1]"
2995  [(set (match_dup 0) (and:SI (not:SI (match_dup 2)) (match_dup 1)))
2996   (set (match_dup 3) (match_dup 4))]
2997  "
2998  {
2999    operands[3] = gen_highpart (SImode, operands[0]);
3000    operands[0] = gen_lowpart (SImode, operands[0]);
3001    operands[4] = gen_highpart (SImode, operands[1]);
3002    operands[1] = gen_lowpart (SImode, operands[1]);
3003  }"
3004  [(set_attr "length" "4,8")
3005   (set_attr "predicable" "yes")
3006   (set_attr "type" "multiple")]
3007)
3008
3009(define_insn_and_split "*anddi_notdi_zesidi"
3010  [(set (match_operand:DI 0 "s_register_operand" "=r")
3011        (and:DI (not:DI (match_operand:DI 2 "s_register_operand" "r"))
3012                (zero_extend:DI
3013                 (match_operand:SI 1 "s_register_operand" "r"))))]
3014  "TARGET_32BIT"
3015  "#"
3016  "TARGET_32BIT && reload_completed"
3017  [(set (match_dup 0) (and:SI (not:SI (match_dup 2)) (match_dup 1)))
3018   (set (match_dup 3) (const_int 0))]
3019  "
3020  {
3021    operands[3] = gen_highpart (SImode, operands[0]);
3022    operands[0] = gen_lowpart (SImode, operands[0]);
3023    operands[2] = gen_lowpart (SImode, operands[2]);
3024  }"
3025  [(set_attr "length" "8")
3026   (set_attr "predicable" "yes")
3027   (set_attr "type" "multiple")]
3028)
3029
3030(define_insn_and_split "*anddi_notsesidi_di"
3031  [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
3032	(and:DI (not:DI (sign_extend:DI
3033			 (match_operand:SI 2 "s_register_operand" "r,r")))
3034		(match_operand:DI 1 "s_register_operand" "0,r")))]
3035  "TARGET_32BIT"
3036  "#"
3037  "TARGET_32BIT && reload_completed"
3038  [(set (match_dup 0) (and:SI (not:SI (match_dup 2)) (match_dup 1)))
3039   (set (match_dup 3) (and:SI (not:SI
3040				(ashiftrt:SI (match_dup 2) (const_int 31)))
3041			       (match_dup 4)))]
3042  "
3043  {
3044    operands[3] = gen_highpart (SImode, operands[0]);
3045    operands[0] = gen_lowpart (SImode, operands[0]);
3046    operands[4] = gen_highpart (SImode, operands[1]);
3047    operands[1] = gen_lowpart (SImode, operands[1]);
3048  }"
3049  [(set_attr "length" "8")
3050   (set_attr "predicable" "yes")
3051   (set_attr "type" "multiple")]
3052)
3053
3054(define_insn "andsi_notsi_si"
3055  [(set (match_operand:SI 0 "s_register_operand" "=r")
3056	(and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
3057		(match_operand:SI 1 "s_register_operand" "r")))]
3058  "TARGET_32BIT"
3059  "bic%?\\t%0, %1, %2"
3060  [(set_attr "predicable" "yes")
3061   (set_attr "type" "logic_reg")]
3062)
3063
3064(define_insn "andsi_not_shiftsi_si"
3065  [(set (match_operand:SI 0 "s_register_operand" "=r")
3066	(and:SI (not:SI (match_operator:SI 4 "shift_operator"
3067			 [(match_operand:SI 2 "s_register_operand" "r")
3068			  (match_operand:SI 3 "arm_rhs_operand" "rM")]))
3069		(match_operand:SI 1 "s_register_operand" "r")))]
3070  "TARGET_ARM"
3071  "bic%?\\t%0, %1, %2%S4"
3072  [(set_attr "predicable" "yes")
3073   (set_attr "shift" "2")
3074   (set (attr "type") (if_then_else (match_operand 3 "const_int_operand" "")
3075		      (const_string "logic_shift_imm")
3076		      (const_string "logic_shift_reg")))]
3077)
3078
3079;; Shifted bics pattern used to set up CC status register and not reusing
3080;; bics output.  Pattern restricts Thumb2 shift operand as bics for Thumb2
3081;; does not support shift by register.
3082(define_insn "andsi_not_shiftsi_si_scc_no_reuse"
3083  [(set (reg:CC_NOOV CC_REGNUM)
3084	(compare:CC_NOOV
3085		(and:SI (not:SI (match_operator:SI 0 "shift_operator"
3086			[(match_operand:SI 1 "s_register_operand" "r")
3087			 (match_operand:SI 2 "arm_rhs_operand" "rM")]))
3088			(match_operand:SI 3 "s_register_operand" "r"))
3089		(const_int 0)))
3090   (clobber (match_scratch:SI 4 "=r"))]
3091  "TARGET_ARM || (TARGET_THUMB2 && CONST_INT_P (operands[2]))"
3092  "bics%?\\t%4, %3, %1%S0"
3093  [(set_attr "predicable" "yes")
3094   (set_attr "conds" "set")
3095   (set_attr "shift" "1")
3096   (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
3097		      (const_string "logic_shift_imm")
3098		      (const_string "logic_shift_reg")))]
3099)
3100
3101;; Same as andsi_not_shiftsi_si_scc_no_reuse, but the bics result is also
3102;; getting reused later.
3103(define_insn "andsi_not_shiftsi_si_scc"
3104  [(parallel [(set (reg:CC_NOOV CC_REGNUM)
3105	(compare:CC_NOOV
3106		(and:SI (not:SI (match_operator:SI 0 "shift_operator"
3107			[(match_operand:SI 1 "s_register_operand" "r")
3108			 (match_operand:SI 2 "arm_rhs_operand" "rM")]))
3109			(match_operand:SI 3 "s_register_operand" "r"))
3110		(const_int 0)))
3111	(set (match_operand:SI 4 "s_register_operand" "=r")
3112	     (and:SI (not:SI (match_op_dup 0
3113		     [(match_dup 1)
3114		      (match_dup 2)]))
3115		     (match_dup 3)))])]
3116  "TARGET_ARM || (TARGET_THUMB2 && CONST_INT_P (operands[2]))"
3117  "bics%?\\t%4, %3, %1%S0"
3118  [(set_attr "predicable" "yes")
3119   (set_attr "conds" "set")
3120   (set_attr "shift" "1")
3121   (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
3122		      (const_string "logic_shift_imm")
3123		      (const_string "logic_shift_reg")))]
3124)
3125
3126(define_insn "*andsi_notsi_si_compare0"
3127  [(set (reg:CC_NOOV CC_REGNUM)
3128	(compare:CC_NOOV
3129	 (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
3130		 (match_operand:SI 1 "s_register_operand" "r"))
3131	 (const_int 0)))
3132   (set (match_operand:SI 0 "s_register_operand" "=r")
3133	(and:SI (not:SI (match_dup 2)) (match_dup 1)))]
3134  "TARGET_32BIT"
3135  "bics\\t%0, %1, %2"
3136  [(set_attr "conds" "set")
3137   (set_attr "type" "logics_shift_reg")]
3138)
3139
3140(define_insn "*andsi_notsi_si_compare0_scratch"
3141  [(set (reg:CC_NOOV CC_REGNUM)
3142	(compare:CC_NOOV
3143	 (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
3144		 (match_operand:SI 1 "s_register_operand" "r"))
3145	 (const_int 0)))
3146   (clobber (match_scratch:SI 0 "=r"))]
3147  "TARGET_32BIT"
3148  "bics\\t%0, %1, %2"
3149  [(set_attr "conds" "set")
3150   (set_attr "type" "logics_shift_reg")]
3151)
3152
3153(define_expand "iordi3"
3154  [(set (match_operand:DI         0 "s_register_operand" "")
3155	(ior:DI (match_operand:DI 1 "s_register_operand" "")
3156		(match_operand:DI 2 "neon_logic_op2" "")))]
3157  "TARGET_32BIT"
3158  "
3159  if (!TARGET_NEON && !TARGET_IWMMXT)
3160    {
3161      rtx low  = simplify_gen_binary (IOR, SImode,
3162				      gen_lowpart (SImode, operands[1]),
3163				      gen_lowpart (SImode, operands[2]));
3164      rtx high = simplify_gen_binary (IOR, SImode,
3165				      gen_highpart (SImode, operands[1]),
3166				      gen_highpart_mode (SImode, DImode,
3167							 operands[2]));
3168
3169      emit_insn (gen_rtx_SET (gen_lowpart (SImode, operands[0]), low));
3170      emit_insn (gen_rtx_SET (gen_highpart (SImode, operands[0]), high));
3171
3172      DONE;
3173    }
3174  /* Otherwise expand pattern as above.  */
3175  "
3176)
3177
3178(define_insn_and_split "*iordi3_insn"
3179  [(set (match_operand:DI         0 "s_register_operand"     "=w,w ,&r,&r,&r,&r,?w,?w")
3180	(ior:DI (match_operand:DI 1 "s_register_operand"     "%w,0 ,0 ,r ,0 ,r ,w ,0")
3181		(match_operand:DI 2 "arm_iordi_operand_neon" "w ,Dl,r ,r ,Df,Df,w ,Dl")))]
3182  "TARGET_32BIT && !TARGET_IWMMXT"
3183  {
3184  switch (which_alternative)
3185    {
3186    case 0: /* fall through */
3187    case 6: return "vorr\t%P0, %P1, %P2";
3188    case 1: /* fall through */
3189    case 7: return neon_output_logic_immediate ("vorr", &operands[2],
3190		     DImode, 0, VALID_NEON_QREG_MODE (DImode));
3191    case 2:
3192    case 3:
3193    case 4:
3194    case 5:
3195      return "#";
3196    default: gcc_unreachable ();
3197    }
3198  }
3199  "TARGET_32BIT && !TARGET_IWMMXT && reload_completed
3200   && !(IS_VFP_REGNUM (REGNO (operands[0])))"
3201  [(set (match_dup 3) (match_dup 4))
3202   (set (match_dup 5) (match_dup 6))]
3203  "
3204  {
3205    operands[3] = gen_lowpart (SImode, operands[0]);
3206    operands[5] = gen_highpart (SImode, operands[0]);
3207
3208    operands[4] = simplify_gen_binary (IOR, SImode,
3209                                           gen_lowpart (SImode, operands[1]),
3210                                           gen_lowpart (SImode, operands[2]));
3211    operands[6] = simplify_gen_binary (IOR, SImode,
3212                                           gen_highpart (SImode, operands[1]),
3213                                           gen_highpart_mode (SImode, DImode, operands[2]));
3214
3215  }"
3216  [(set_attr "type" "neon_logic,neon_logic,multiple,multiple,multiple,\
3217                     multiple,neon_logic,neon_logic")
3218   (set_attr "length" "*,*,8,8,8,8,*,*")
3219   (set_attr "arch" "neon_for_64bits,neon_for_64bits,*,*,*,*,avoid_neon_for_64bits,avoid_neon_for_64bits")]
3220)
3221
3222(define_insn "*iordi_zesidi_di"
3223  [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
3224	(ior:DI (zero_extend:DI
3225		 (match_operand:SI 2 "s_register_operand" "r,r"))
3226		(match_operand:DI 1 "s_register_operand" "0,?r")))]
3227  "TARGET_32BIT"
3228  "@
3229   orr%?\\t%Q0, %Q1, %2
3230   #"
3231  [(set_attr "length" "4,8")
3232   (set_attr "predicable" "yes")
3233   (set_attr "type" "logic_reg,multiple")]
3234)
3235
3236(define_insn "*iordi_sesidi_di"
3237  [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
3238	(ior:DI (sign_extend:DI
3239		 (match_operand:SI 2 "s_register_operand" "r,r"))
3240		(match_operand:DI 1 "s_register_operand" "0,r")))]
3241  "TARGET_32BIT"
3242  "#"
3243  [(set_attr "length" "8")
3244   (set_attr "predicable" "yes")
3245   (set_attr "type" "multiple")]
3246)
3247
3248(define_expand "iorsi3"
3249  [(set (match_operand:SI         0 "s_register_operand" "")
3250	(ior:SI (match_operand:SI 1 "s_register_operand" "")
3251		(match_operand:SI 2 "reg_or_int_operand" "")))]
3252  "TARGET_EITHER"
3253  "
3254  if (CONST_INT_P (operands[2]))
3255    {
3256      if (TARGET_32BIT)
3257        {
3258	  if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[2]), IOR))
3259	    operands[2] = force_reg (SImode, operands[2]);
3260	  else
3261	    {
3262	      arm_split_constant (IOR, SImode, NULL_RTX,
3263				  INTVAL (operands[2]), operands[0],
3264				  operands[1],
3265				  optimize && can_create_pseudo_p ());
3266	      DONE;
3267	    }
3268	}
3269      else /* TARGET_THUMB1 */
3270        {
3271          rtx tmp = force_reg (SImode, operands[2]);
3272	  if (rtx_equal_p (operands[0], operands[1]))
3273	    operands[2] = tmp;
3274	  else
3275	    {
3276              operands[2] = operands[1];
3277              operands[1] = tmp;
3278	    }
3279        }
3280    }
3281  "
3282)
3283
3284(define_insn_and_split "*iorsi3_insn"
3285  [(set (match_operand:SI 0 "s_register_operand" "=r,l,r,r,r")
3286	(ior:SI (match_operand:SI 1 "s_register_operand" "%r,0,r,r,r")
3287		(match_operand:SI 2 "reg_or_int_operand" "I,l,K,r,?n")))]
3288  "TARGET_32BIT"
3289  "@
3290   orr%?\\t%0, %1, %2
3291   orr%?\\t%0, %1, %2
3292   orn%?\\t%0, %1, #%B2
3293   orr%?\\t%0, %1, %2
3294   #"
3295  "TARGET_32BIT
3296   && CONST_INT_P (operands[2])
3297   && !(const_ok_for_arm (INTVAL (operands[2]))
3298        || (TARGET_THUMB2 && const_ok_for_arm (~INTVAL (operands[2]))))"
3299  [(clobber (const_int 0))]
3300{
3301  arm_split_constant (IOR, SImode, curr_insn,
3302                      INTVAL (operands[2]), operands[0], operands[1], 0);
3303  DONE;
3304}
3305  [(set_attr "length" "4,4,4,4,16")
3306   (set_attr "arch" "32,t2,t2,32,32")
3307   (set_attr "predicable" "yes")
3308   (set_attr "predicable_short_it" "no,yes,no,no,no")
3309   (set_attr "type" "logic_imm,logic_reg,logic_imm,logic_reg,logic_reg")]
3310)
3311
3312(define_peephole2
3313  [(match_scratch:SI 3 "r")
3314   (set (match_operand:SI 0 "arm_general_register_operand" "")
3315	(ior:SI (match_operand:SI 1 "arm_general_register_operand" "")
3316		(match_operand:SI 2 "const_int_operand" "")))]
3317  "TARGET_ARM
3318   && !const_ok_for_arm (INTVAL (operands[2]))
3319   && const_ok_for_arm (~INTVAL (operands[2]))"
3320  [(set (match_dup 3) (match_dup 2))
3321   (set (match_dup 0) (ior:SI (match_dup 1) (match_dup 3)))]
3322  ""
3323)
3324
3325(define_insn "*iorsi3_compare0"
3326  [(set (reg:CC_NOOV CC_REGNUM)
3327	(compare:CC_NOOV (ior:SI (match_operand:SI 1 "s_register_operand" "%r,r")
3328				 (match_operand:SI 2 "arm_rhs_operand" "I,r"))
3329			 (const_int 0)))
3330   (set (match_operand:SI 0 "s_register_operand" "=r,r")
3331	(ior:SI (match_dup 1) (match_dup 2)))]
3332  "TARGET_32BIT"
3333  "orrs%?\\t%0, %1, %2"
3334  [(set_attr "conds" "set")
3335   (set_attr "type" "logics_imm,logics_reg")]
3336)
3337
3338(define_insn "*iorsi3_compare0_scratch"
3339  [(set (reg:CC_NOOV CC_REGNUM)
3340	(compare:CC_NOOV (ior:SI (match_operand:SI 1 "s_register_operand" "%r,r")
3341				 (match_operand:SI 2 "arm_rhs_operand" "I,r"))
3342			 (const_int 0)))
3343   (clobber (match_scratch:SI 0 "=r,r"))]
3344  "TARGET_32BIT"
3345  "orrs%?\\t%0, %1, %2"
3346  [(set_attr "conds" "set")
3347   (set_attr "type" "logics_imm,logics_reg")]
3348)
3349
3350(define_expand "xordi3"
3351  [(set (match_operand:DI         0 "s_register_operand" "")
3352	(xor:DI (match_operand:DI 1 "s_register_operand" "")
3353		(match_operand:DI 2 "arm_xordi_operand" "")))]
3354  "TARGET_32BIT"
3355  {
3356    /* The iWMMXt pattern for xordi3 accepts only register operands but we want
3357       to reuse this expander for all TARGET_32BIT targets so just force the
3358       constants into a register.  Unlike for the anddi3 and iordi3 there are
3359       no NEON instructions that take an immediate.  */
3360    if (TARGET_IWMMXT && !REG_P (operands[2]))
3361      operands[2] = force_reg (DImode, operands[2]);
3362    if (!TARGET_NEON && !TARGET_IWMMXT)
3363      {
3364	rtx low  = simplify_gen_binary (XOR, SImode,
3365					gen_lowpart (SImode, operands[1]),
3366					gen_lowpart (SImode, operands[2]));
3367	rtx high = simplify_gen_binary (XOR, SImode,
3368					gen_highpart (SImode, operands[1]),
3369					gen_highpart_mode (SImode, DImode,
3370							   operands[2]));
3371
3372	emit_insn (gen_rtx_SET (gen_lowpart (SImode, operands[0]), low));
3373	emit_insn (gen_rtx_SET (gen_highpart (SImode, operands[0]), high));
3374
3375	DONE;
3376      }
3377    /* Otherwise expand pattern as above.  */
3378  }
3379)
3380
3381(define_insn_and_split "*xordi3_insn"
3382  [(set (match_operand:DI         0 "s_register_operand" "=w,&r,&r,&r,&r,?w")
3383	(xor:DI (match_operand:DI 1 "s_register_operand" "%w ,0,r ,0 ,r ,w")
3384		(match_operand:DI 2 "arm_xordi_operand"  "w ,r ,r ,Dg,Dg,w")))]
3385  "TARGET_32BIT && !TARGET_IWMMXT"
3386{
3387  switch (which_alternative)
3388    {
3389    case 1:
3390    case 2:
3391    case 3:
3392    case 4:  /* fall through */
3393      return "#";
3394    case 0: /* fall through */
3395    case 5: return "veor\t%P0, %P1, %P2";
3396    default: gcc_unreachable ();
3397    }
3398}
3399  "TARGET_32BIT && !TARGET_IWMMXT && reload_completed
3400   && !(IS_VFP_REGNUM (REGNO (operands[0])))"
3401  [(set (match_dup 3) (match_dup 4))
3402   (set (match_dup 5) (match_dup 6))]
3403  "
3404  {
3405    operands[3] = gen_lowpart (SImode, operands[0]);
3406    operands[5] = gen_highpart (SImode, operands[0]);
3407
3408    operands[4] = simplify_gen_binary (XOR, SImode,
3409                                           gen_lowpart (SImode, operands[1]),
3410                                           gen_lowpart (SImode, operands[2]));
3411    operands[6] = simplify_gen_binary (XOR, SImode,
3412                                           gen_highpart (SImode, operands[1]),
3413                                           gen_highpart_mode (SImode, DImode, operands[2]));
3414
3415  }"
3416  [(set_attr "length" "*,8,8,8,8,*")
3417   (set_attr "type" "neon_logic,multiple,multiple,multiple,multiple,neon_logic")
3418   (set_attr "arch" "neon_for_64bits,*,*,*,*,avoid_neon_for_64bits")]
3419)
3420
3421(define_insn "*xordi_zesidi_di"
3422  [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
3423	(xor:DI (zero_extend:DI
3424		 (match_operand:SI 2 "s_register_operand" "r,r"))
3425		(match_operand:DI 1 "s_register_operand" "0,?r")))]
3426  "TARGET_32BIT"
3427  "@
3428   eor%?\\t%Q0, %Q1, %2
3429   #"
3430  [(set_attr "length" "4,8")
3431   (set_attr "predicable" "yes")
3432   (set_attr "type" "logic_reg")]
3433)
3434
3435(define_insn "*xordi_sesidi_di"
3436  [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
3437	(xor:DI (sign_extend:DI
3438		 (match_operand:SI 2 "s_register_operand" "r,r"))
3439		(match_operand:DI 1 "s_register_operand" "0,r")))]
3440  "TARGET_32BIT"
3441  "#"
3442  [(set_attr "length" "8")
3443   (set_attr "predicable" "yes")
3444   (set_attr "type" "multiple")]
3445)
3446
3447(define_expand "xorsi3"
3448  [(set (match_operand:SI         0 "s_register_operand" "")
3449	(xor:SI (match_operand:SI 1 "s_register_operand" "")
3450		(match_operand:SI 2 "reg_or_int_operand" "")))]
3451  "TARGET_EITHER"
3452  "if (CONST_INT_P (operands[2]))
3453    {
3454      if (TARGET_32BIT)
3455        {
3456	  if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[2]), XOR))
3457	    operands[2] = force_reg (SImode, operands[2]);
3458	  else
3459	    {
3460	      arm_split_constant (XOR, SImode, NULL_RTX,
3461				  INTVAL (operands[2]), operands[0],
3462				  operands[1],
3463				  optimize && can_create_pseudo_p ());
3464	      DONE;
3465	    }
3466	}
3467      else /* TARGET_THUMB1 */
3468        {
3469          rtx tmp = force_reg (SImode, operands[2]);
3470	  if (rtx_equal_p (operands[0], operands[1]))
3471	    operands[2] = tmp;
3472	  else
3473	    {
3474              operands[2] = operands[1];
3475              operands[1] = tmp;
3476	    }
3477        }
3478    }"
3479)
3480
3481(define_insn_and_split "*arm_xorsi3"
3482  [(set (match_operand:SI         0 "s_register_operand" "=r,l,r,r")
3483	(xor:SI (match_operand:SI 1 "s_register_operand" "%r,0,r,r")
3484		(match_operand:SI 2 "reg_or_int_operand" "I,l,r,?n")))]
3485  "TARGET_32BIT"
3486  "@
3487   eor%?\\t%0, %1, %2
3488   eor%?\\t%0, %1, %2
3489   eor%?\\t%0, %1, %2
3490   #"
3491  "TARGET_32BIT
3492   && CONST_INT_P (operands[2])
3493   && !const_ok_for_arm (INTVAL (operands[2]))"
3494  [(clobber (const_int 0))]
3495{
3496  arm_split_constant (XOR, SImode, curr_insn,
3497                      INTVAL (operands[2]), operands[0], operands[1], 0);
3498  DONE;
3499}
3500  [(set_attr "length" "4,4,4,16")
3501   (set_attr "predicable" "yes")
3502   (set_attr "predicable_short_it" "no,yes,no,no")
3503   (set_attr "type"  "logic_imm,logic_reg,logic_reg,multiple")]
3504)
3505
3506(define_insn "*xorsi3_compare0"
3507  [(set (reg:CC_NOOV CC_REGNUM)
3508	(compare:CC_NOOV (xor:SI (match_operand:SI 1 "s_register_operand" "r,r")
3509				 (match_operand:SI 2 "arm_rhs_operand" "I,r"))
3510			 (const_int 0)))
3511   (set (match_operand:SI 0 "s_register_operand" "=r,r")
3512	(xor:SI (match_dup 1) (match_dup 2)))]
3513  "TARGET_32BIT"
3514  "eors%?\\t%0, %1, %2"
3515  [(set_attr "conds" "set")
3516   (set_attr "type" "logics_imm,logics_reg")]
3517)
3518
3519(define_insn "*xorsi3_compare0_scratch"
3520  [(set (reg:CC_NOOV CC_REGNUM)
3521	(compare:CC_NOOV (xor:SI (match_operand:SI 0 "s_register_operand" "r,r")
3522				 (match_operand:SI 1 "arm_rhs_operand" "I,r"))
3523			 (const_int 0)))]
3524  "TARGET_32BIT"
3525  "teq%?\\t%0, %1"
3526  [(set_attr "conds" "set")
3527   (set_attr "type" "logics_imm,logics_reg")]
3528)
3529
3530; By splitting (IOR (AND (NOT A) (NOT B)) C) as D = AND (IOR A B) (NOT C),
3531; (NOT D) we can sometimes merge the final NOT into one of the following
3532; insns.
3533
3534(define_split
3535  [(set (match_operand:SI 0 "s_register_operand" "")
3536	(ior:SI (and:SI (not:SI (match_operand:SI 1 "s_register_operand" ""))
3537			(not:SI (match_operand:SI 2 "arm_rhs_operand" "")))
3538		(match_operand:SI 3 "arm_rhs_operand" "")))
3539   (clobber (match_operand:SI 4 "s_register_operand" ""))]
3540  "TARGET_32BIT"
3541  [(set (match_dup 4) (and:SI (ior:SI (match_dup 1) (match_dup 2))
3542			      (not:SI (match_dup 3))))
3543   (set (match_dup 0) (not:SI (match_dup 4)))]
3544  ""
3545)
3546
3547(define_insn_and_split "*andsi_iorsi3_notsi"
3548  [(set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r")
3549	(and:SI (ior:SI (match_operand:SI 1 "s_register_operand" "%0,r,r")
3550			(match_operand:SI 2 "arm_rhs_operand" "rI,0,rI"))
3551		(not:SI (match_operand:SI 3 "arm_rhs_operand" "rI,rI,rI"))))]
3552  "TARGET_32BIT"
3553  "#"   ; "orr%?\\t%0, %1, %2\;bic%?\\t%0, %0, %3"
3554  "&& reload_completed"
3555  [(set (match_dup 0) (ior:SI (match_dup 1) (match_dup 2)))
3556   (set (match_dup 0) (and:SI (match_dup 4) (match_dup 5)))]
3557  {
3558     /* If operands[3] is a constant make sure to fold the NOT into it
3559	to avoid creating a NOT of a CONST_INT.  */
3560    rtx not_rtx = simplify_gen_unary (NOT, SImode, operands[3], SImode);
3561    if (CONST_INT_P (not_rtx))
3562      {
3563	operands[4] = operands[0];
3564	operands[5] = not_rtx;
3565      }
3566    else
3567      {
3568	operands[5] = operands[0];
3569	operands[4] = not_rtx;
3570      }
3571  }
3572  [(set_attr "length" "8")
3573   (set_attr "ce_count" "2")
3574   (set_attr "predicable" "yes")
3575   (set_attr "type" "multiple")]
3576)
3577
3578; ??? Are these four splitters still beneficial when the Thumb-2 bitfield
3579; insns are available?
3580(define_split
3581  [(set (match_operand:SI 0 "s_register_operand" "")
3582	(match_operator:SI 1 "logical_binary_operator"
3583	 [(zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
3584			   (match_operand:SI 3 "const_int_operand" "")
3585			   (match_operand:SI 4 "const_int_operand" ""))
3586	  (match_operator:SI 9 "logical_binary_operator"
3587	   [(lshiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3588			 (match_operand:SI 6 "const_int_operand" ""))
3589	    (match_operand:SI 7 "s_register_operand" "")])]))
3590   (clobber (match_operand:SI 8 "s_register_operand" ""))]
3591  "TARGET_32BIT
3592   && GET_CODE (operands[1]) == GET_CODE (operands[9])
3593   && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3594  [(set (match_dup 8)
3595	(match_op_dup 1
3596	 [(ashift:SI (match_dup 2) (match_dup 4))
3597	  (match_dup 5)]))
3598   (set (match_dup 0)
3599	(match_op_dup 1
3600	 [(lshiftrt:SI (match_dup 8) (match_dup 6))
3601	  (match_dup 7)]))]
3602  "
3603  operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3604")
3605
3606(define_split
3607  [(set (match_operand:SI 0 "s_register_operand" "")
3608	(match_operator:SI 1 "logical_binary_operator"
3609	 [(match_operator:SI 9 "logical_binary_operator"
3610	   [(lshiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3611			 (match_operand:SI 6 "const_int_operand" ""))
3612	    (match_operand:SI 7 "s_register_operand" "")])
3613	  (zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
3614			   (match_operand:SI 3 "const_int_operand" "")
3615			   (match_operand:SI 4 "const_int_operand" ""))]))
3616   (clobber (match_operand:SI 8 "s_register_operand" ""))]
3617  "TARGET_32BIT
3618   && GET_CODE (operands[1]) == GET_CODE (operands[9])
3619   && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3620  [(set (match_dup 8)
3621	(match_op_dup 1
3622	 [(ashift:SI (match_dup 2) (match_dup 4))
3623	  (match_dup 5)]))
3624   (set (match_dup 0)
3625	(match_op_dup 1
3626	 [(lshiftrt:SI (match_dup 8) (match_dup 6))
3627	  (match_dup 7)]))]
3628  "
3629  operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3630")
3631
3632(define_split
3633  [(set (match_operand:SI 0 "s_register_operand" "")
3634	(match_operator:SI 1 "logical_binary_operator"
3635	 [(sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
3636			   (match_operand:SI 3 "const_int_operand" "")
3637			   (match_operand:SI 4 "const_int_operand" ""))
3638	  (match_operator:SI 9 "logical_binary_operator"
3639	   [(ashiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3640			 (match_operand:SI 6 "const_int_operand" ""))
3641	    (match_operand:SI 7 "s_register_operand" "")])]))
3642   (clobber (match_operand:SI 8 "s_register_operand" ""))]
3643  "TARGET_32BIT
3644   && GET_CODE (operands[1]) == GET_CODE (operands[9])
3645   && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3646  [(set (match_dup 8)
3647	(match_op_dup 1
3648	 [(ashift:SI (match_dup 2) (match_dup 4))
3649	  (match_dup 5)]))
3650   (set (match_dup 0)
3651	(match_op_dup 1
3652	 [(ashiftrt:SI (match_dup 8) (match_dup 6))
3653	  (match_dup 7)]))]
3654  "
3655  operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3656")
3657
3658(define_split
3659  [(set (match_operand:SI 0 "s_register_operand" "")
3660	(match_operator:SI 1 "logical_binary_operator"
3661	 [(match_operator:SI 9 "logical_binary_operator"
3662	   [(ashiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3663			 (match_operand:SI 6 "const_int_operand" ""))
3664	    (match_operand:SI 7 "s_register_operand" "")])
3665	  (sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
3666			   (match_operand:SI 3 "const_int_operand" "")
3667			   (match_operand:SI 4 "const_int_operand" ""))]))
3668   (clobber (match_operand:SI 8 "s_register_operand" ""))]
3669  "TARGET_32BIT
3670   && GET_CODE (operands[1]) == GET_CODE (operands[9])
3671   && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3672  [(set (match_dup 8)
3673	(match_op_dup 1
3674	 [(ashift:SI (match_dup 2) (match_dup 4))
3675	  (match_dup 5)]))
3676   (set (match_dup 0)
3677	(match_op_dup 1
3678	 [(ashiftrt:SI (match_dup 8) (match_dup 6))
3679	  (match_dup 7)]))]
3680  "
3681  operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3682")
3683
3684
3685;; Minimum and maximum insns
3686
3687(define_expand "smaxsi3"
3688  [(parallel [
3689    (set (match_operand:SI 0 "s_register_operand" "")
3690	 (smax:SI (match_operand:SI 1 "s_register_operand" "")
3691		  (match_operand:SI 2 "arm_rhs_operand" "")))
3692    (clobber (reg:CC CC_REGNUM))])]
3693  "TARGET_32BIT"
3694  "
3695  if (operands[2] == const0_rtx || operands[2] == constm1_rtx)
3696    {
3697      /* No need for a clobber of the condition code register here.  */
3698      emit_insn (gen_rtx_SET (operands[0],
3699			      gen_rtx_SMAX (SImode, operands[1],
3700					    operands[2])));
3701      DONE;
3702    }
3703")
3704
3705(define_insn "*smax_0"
3706  [(set (match_operand:SI 0 "s_register_operand" "=r")
3707	(smax:SI (match_operand:SI 1 "s_register_operand" "r")
3708		 (const_int 0)))]
3709  "TARGET_32BIT"
3710  "bic%?\\t%0, %1, %1, asr #31"
3711  [(set_attr "predicable" "yes")
3712   (set_attr "type" "logic_shift_reg")]
3713)
3714
3715(define_insn "*smax_m1"
3716  [(set (match_operand:SI 0 "s_register_operand" "=r")
3717	(smax:SI (match_operand:SI 1 "s_register_operand" "r")
3718		 (const_int -1)))]
3719  "TARGET_32BIT"
3720  "orr%?\\t%0, %1, %1, asr #31"
3721  [(set_attr "predicable" "yes")
3722   (set_attr "type" "logic_shift_reg")]
3723)
3724
3725(define_insn_and_split "*arm_smax_insn"
3726  [(set (match_operand:SI          0 "s_register_operand" "=r,r")
3727	(smax:SI (match_operand:SI 1 "s_register_operand"  "%0,?r")
3728		 (match_operand:SI 2 "arm_rhs_operand"    "rI,rI")))
3729   (clobber (reg:CC CC_REGNUM))]
3730  "TARGET_ARM"
3731  "#"
3732   ; cmp\\t%1, %2\;movlt\\t%0, %2
3733   ; cmp\\t%1, %2\;movge\\t%0, %1\;movlt\\t%0, %2"
3734  "TARGET_ARM"
3735  [(set (reg:CC CC_REGNUM)
3736        (compare:CC (match_dup 1) (match_dup 2)))
3737   (set (match_dup 0)
3738        (if_then_else:SI (ge:SI (reg:CC CC_REGNUM) (const_int 0))
3739                         (match_dup 1)
3740                         (match_dup 2)))]
3741  ""
3742  [(set_attr "conds" "clob")
3743   (set_attr "length" "8,12")
3744   (set_attr "type" "multiple")]
3745)
3746
3747(define_expand "sminsi3"
3748  [(parallel [
3749    (set (match_operand:SI 0 "s_register_operand" "")
3750	 (smin:SI (match_operand:SI 1 "s_register_operand" "")
3751		  (match_operand:SI 2 "arm_rhs_operand" "")))
3752    (clobber (reg:CC CC_REGNUM))])]
3753  "TARGET_32BIT"
3754  "
3755  if (operands[2] == const0_rtx)
3756    {
3757      /* No need for a clobber of the condition code register here.  */
3758      emit_insn (gen_rtx_SET (operands[0],
3759			      gen_rtx_SMIN (SImode, operands[1],
3760					    operands[2])));
3761      DONE;
3762    }
3763")
3764
3765(define_insn "*smin_0"
3766  [(set (match_operand:SI 0 "s_register_operand" "=r")
3767	(smin:SI (match_operand:SI 1 "s_register_operand" "r")
3768		 (const_int 0)))]
3769  "TARGET_32BIT"
3770  "and%?\\t%0, %1, %1, asr #31"
3771  [(set_attr "predicable" "yes")
3772   (set_attr "type" "logic_shift_reg")]
3773)
3774
3775(define_insn_and_split "*arm_smin_insn"
3776  [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3777	(smin:SI (match_operand:SI 1 "s_register_operand" "%0,?r")
3778		 (match_operand:SI 2 "arm_rhs_operand" "rI,rI")))
3779   (clobber (reg:CC CC_REGNUM))]
3780  "TARGET_ARM"
3781  "#"
3782    ; cmp\\t%1, %2\;movge\\t%0, %2
3783    ; cmp\\t%1, %2\;movlt\\t%0, %1\;movge\\t%0, %2"
3784  "TARGET_ARM"
3785  [(set (reg:CC CC_REGNUM)
3786        (compare:CC (match_dup 1) (match_dup 2)))
3787   (set (match_dup 0)
3788        (if_then_else:SI (lt:SI (reg:CC CC_REGNUM) (const_int 0))
3789                         (match_dup 1)
3790                         (match_dup 2)))]
3791  ""
3792  [(set_attr "conds" "clob")
3793   (set_attr "length" "8,12")
3794   (set_attr "type" "multiple,multiple")]
3795)
3796
3797(define_expand "umaxsi3"
3798  [(parallel [
3799    (set (match_operand:SI 0 "s_register_operand" "")
3800	 (umax:SI (match_operand:SI 1 "s_register_operand" "")
3801		  (match_operand:SI 2 "arm_rhs_operand" "")))
3802    (clobber (reg:CC CC_REGNUM))])]
3803  "TARGET_32BIT"
3804  ""
3805)
3806
3807(define_insn_and_split "*arm_umaxsi3"
3808  [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
3809	(umax:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
3810		 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
3811   (clobber (reg:CC CC_REGNUM))]
3812  "TARGET_ARM"
3813  "#"
3814    ; cmp\\t%1, %2\;movcc\\t%0, %2
3815    ; cmp\\t%1, %2\;movcs\\t%0, %1
3816    ; cmp\\t%1, %2\;movcs\\t%0, %1\;movcc\\t%0, %2"
3817  "TARGET_ARM"
3818  [(set (reg:CC CC_REGNUM)
3819        (compare:CC (match_dup 1) (match_dup 2)))
3820   (set (match_dup 0)
3821        (if_then_else:SI (geu:SI (reg:CC CC_REGNUM) (const_int 0))
3822                         (match_dup 1)
3823                         (match_dup 2)))]
3824  ""
3825  [(set_attr "conds" "clob")
3826   (set_attr "length" "8,8,12")
3827   (set_attr "type" "store_4")]
3828)
3829
3830(define_expand "uminsi3"
3831  [(parallel [
3832    (set (match_operand:SI 0 "s_register_operand" "")
3833	 (umin:SI (match_operand:SI 1 "s_register_operand" "")
3834		  (match_operand:SI 2 "arm_rhs_operand" "")))
3835    (clobber (reg:CC CC_REGNUM))])]
3836  "TARGET_32BIT"
3837  ""
3838)
3839
3840(define_insn_and_split "*arm_uminsi3"
3841  [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
3842	(umin:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
3843		 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
3844   (clobber (reg:CC CC_REGNUM))]
3845  "TARGET_ARM"
3846  "#"
3847   ; cmp\\t%1, %2\;movcs\\t%0, %2
3848   ; cmp\\t%1, %2\;movcc\\t%0, %1
3849   ; cmp\\t%1, %2\;movcc\\t%0, %1\;movcs\\t%0, %2"
3850  "TARGET_ARM"
3851  [(set (reg:CC CC_REGNUM)
3852        (compare:CC (match_dup 1) (match_dup 2)))
3853   (set (match_dup 0)
3854        (if_then_else:SI (ltu:SI (reg:CC CC_REGNUM) (const_int 0))
3855                         (match_dup 1)
3856                         (match_dup 2)))]
3857  ""
3858  [(set_attr "conds" "clob")
3859   (set_attr "length" "8,8,12")
3860   (set_attr "type" "store_4")]
3861)
3862
3863(define_insn "*store_minmaxsi"
3864  [(set (match_operand:SI 0 "memory_operand" "=m")
3865	(match_operator:SI 3 "minmax_operator"
3866	 [(match_operand:SI 1 "s_register_operand" "r")
3867	  (match_operand:SI 2 "s_register_operand" "r")]))
3868   (clobber (reg:CC CC_REGNUM))]
3869  "TARGET_32BIT && optimize_function_for_size_p (cfun) && !arm_restrict_it"
3870  "*
3871  operands[3] = gen_rtx_fmt_ee (minmax_code (operands[3]), SImode,
3872				operands[1], operands[2]);
3873  output_asm_insn (\"cmp\\t%1, %2\", operands);
3874  if (TARGET_THUMB2)
3875    output_asm_insn (\"ite\t%d3\", operands);
3876  output_asm_insn (\"str%d3\\t%1, %0\", operands);
3877  output_asm_insn (\"str%D3\\t%2, %0\", operands);
3878  return \"\";
3879  "
3880  [(set_attr "conds" "clob")
3881   (set (attr "length")
3882	(if_then_else (eq_attr "is_thumb" "yes")
3883		      (const_int 14)
3884		      (const_int 12)))
3885   (set_attr "type" "store_4")]
3886)
3887
3888; Reject the frame pointer in operand[1], since reloading this after
3889; it has been eliminated can cause carnage.
3890(define_insn "*minmax_arithsi"
3891  [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3892	(match_operator:SI 4 "shiftable_operator"
3893	 [(match_operator:SI 5 "minmax_operator"
3894	   [(match_operand:SI 2 "s_register_operand" "r,r")
3895	    (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
3896	  (match_operand:SI 1 "s_register_operand" "0,?r")]))
3897   (clobber (reg:CC CC_REGNUM))]
3898  "TARGET_32BIT && !arm_eliminable_register (operands[1]) && !arm_restrict_it"
3899  "*
3900  {
3901    enum rtx_code code = GET_CODE (operands[4]);
3902    bool need_else;
3903
3904    if (which_alternative != 0 || operands[3] != const0_rtx
3905        || (code != PLUS && code != IOR && code != XOR))
3906      need_else = true;
3907    else
3908      need_else = false;
3909
3910    operands[5] = gen_rtx_fmt_ee (minmax_code (operands[5]), SImode,
3911				  operands[2], operands[3]);
3912    output_asm_insn (\"cmp\\t%2, %3\", operands);
3913    if (TARGET_THUMB2)
3914      {
3915	if (need_else)
3916	  output_asm_insn (\"ite\\t%d5\", operands);
3917	else
3918	  output_asm_insn (\"it\\t%d5\", operands);
3919      }
3920    output_asm_insn (\"%i4%d5\\t%0, %1, %2\", operands);
3921    if (need_else)
3922      output_asm_insn (\"%i4%D5\\t%0, %1, %3\", operands);
3923    return \"\";
3924  }"
3925  [(set_attr "conds" "clob")
3926   (set (attr "length")
3927	(if_then_else (eq_attr "is_thumb" "yes")
3928		      (const_int 14)
3929		      (const_int 12)))
3930   (set_attr "type" "multiple")]
3931)
3932
3933; Reject the frame pointer in operand[1], since reloading this after
3934; it has been eliminated can cause carnage.
3935(define_insn_and_split "*minmax_arithsi_non_canon"
3936  [(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts")
3937	(minus:SI
3938	 (match_operand:SI 1 "s_register_operand" "0,?Ts")
3939	  (match_operator:SI 4 "minmax_operator"
3940	   [(match_operand:SI 2 "s_register_operand" "Ts,Ts")
3941	    (match_operand:SI 3 "arm_rhs_operand" "TsI,TsI")])))
3942   (clobber (reg:CC CC_REGNUM))]
3943  "TARGET_32BIT && !arm_eliminable_register (operands[1])
3944   && !(arm_restrict_it && CONST_INT_P (operands[3]))"
3945  "#"
3946  "TARGET_32BIT && !arm_eliminable_register (operands[1]) && reload_completed"
3947  [(set (reg:CC CC_REGNUM)
3948        (compare:CC (match_dup 2) (match_dup 3)))
3949
3950   (cond_exec (match_op_dup 4 [(reg:CC CC_REGNUM) (const_int 0)])
3951              (set (match_dup 0)
3952                   (minus:SI (match_dup 1)
3953                             (match_dup 2))))
3954   (cond_exec (match_op_dup 5 [(reg:CC CC_REGNUM) (const_int 0)])
3955              (set (match_dup 0)
3956                   (match_dup 6)))]
3957  {
3958  machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
3959                                           operands[2], operands[3]);
3960  enum rtx_code rc = minmax_code (operands[4]);
3961  operands[4] = gen_rtx_fmt_ee (rc, VOIDmode,
3962                                operands[2], operands[3]);
3963
3964  if (mode == CCFPmode || mode == CCFPEmode)
3965    rc = reverse_condition_maybe_unordered (rc);
3966  else
3967    rc = reverse_condition (rc);
3968  operands[5] = gen_rtx_fmt_ee (rc, SImode, operands[2], operands[3]);
3969  if (CONST_INT_P (operands[3]))
3970    operands[6] = plus_constant (SImode, operands[1], -INTVAL (operands[3]));
3971  else
3972    operands[6] = gen_rtx_MINUS (SImode, operands[1], operands[3]);
3973  }
3974  [(set_attr "conds" "clob")
3975   (set (attr "length")
3976	(if_then_else (eq_attr "is_thumb" "yes")
3977		      (const_int 14)
3978		      (const_int 12)))
3979   (set_attr "type" "multiple")]
3980)
3981
3982(define_code_iterator SAT [smin smax])
3983(define_code_iterator SATrev [smin smax])
3984(define_code_attr SATlo [(smin "1") (smax "2")])
3985(define_code_attr SAThi [(smin "2") (smax "1")])
3986
3987(define_insn "*satsi_<SAT:code>"
3988  [(set (match_operand:SI 0 "s_register_operand" "=r")
3989        (SAT:SI (SATrev:SI (match_operand:SI 3 "s_register_operand" "r")
3990                           (match_operand:SI 1 "const_int_operand" "i"))
3991                (match_operand:SI 2 "const_int_operand" "i")))]
3992  "TARGET_32BIT && arm_arch6 && <SAT:CODE> != <SATrev:CODE>
3993   && arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>], NULL, NULL)"
3994{
3995  int mask;
3996  bool signed_sat;
3997  if (!arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>],
3998                               &mask, &signed_sat))
3999    gcc_unreachable ();
4000
4001  operands[1] = GEN_INT (mask);
4002  if (signed_sat)
4003    return "ssat%?\t%0, %1, %3";
4004  else
4005    return "usat%?\t%0, %1, %3";
4006}
4007  [(set_attr "predicable" "yes")
4008   (set_attr "type" "alus_imm")]
4009)
4010
4011(define_insn "*satsi_<SAT:code>_shift"
4012  [(set (match_operand:SI 0 "s_register_operand" "=r")
4013        (SAT:SI (SATrev:SI (match_operator:SI 3 "sat_shift_operator"
4014                             [(match_operand:SI 4 "s_register_operand" "r")
4015                              (match_operand:SI 5 "const_int_operand" "i")])
4016                           (match_operand:SI 1 "const_int_operand" "i"))
4017                (match_operand:SI 2 "const_int_operand" "i")))]
4018  "TARGET_32BIT && arm_arch6 && <SAT:CODE> != <SATrev:CODE>
4019   && arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>], NULL, NULL)"
4020{
4021  int mask;
4022  bool signed_sat;
4023  if (!arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>],
4024                               &mask, &signed_sat))
4025    gcc_unreachable ();
4026
4027  operands[1] = GEN_INT (mask);
4028  if (signed_sat)
4029    return "ssat%?\t%0, %1, %4%S3";
4030  else
4031    return "usat%?\t%0, %1, %4%S3";
4032}
4033  [(set_attr "predicable" "yes")
4034   (set_attr "shift" "3")
4035   (set_attr "type" "logic_shift_reg")])
4036
4037;; Shift and rotation insns
4038
4039(define_expand "ashldi3"
4040  [(set (match_operand:DI            0 "s_register_operand" "")
4041        (ashift:DI (match_operand:DI 1 "s_register_operand" "")
4042                   (match_operand:SI 2 "general_operand" "")))]
4043  "TARGET_32BIT"
4044  "
4045  if (TARGET_NEON)
4046    {
4047      /* Delay the decision whether to use NEON or core-regs until
4048	 register allocation.  */
4049      emit_insn (gen_ashldi3_neon (operands[0], operands[1], operands[2]));
4050      DONE;
4051    }
4052  else
4053    {
4054      /* Only the NEON case can handle in-memory shift counts.  */
4055      if (!reg_or_int_operand (operands[2], SImode))
4056        operands[2] = force_reg (SImode, operands[2]);
4057    }
4058
4059  if (!CONST_INT_P (operands[2]) && TARGET_REALLY_IWMMXT)
4060    ; /* No special preparation statements; expand pattern as above.  */
4061  else
4062    {
4063      rtx scratch1, scratch2;
4064
4065      /* Ideally we should use iwmmxt here if we could know that operands[1]
4066         ends up already living in an iwmmxt register. Otherwise it's
4067         cheaper to have the alternate code being generated than moving
4068         values to iwmmxt regs and back.  */
4069
4070      /* Expand operation using core-registers.
4071	 'FAIL' would achieve the same thing, but this is a bit smarter.  */
4072      scratch1 = gen_reg_rtx (SImode);
4073      scratch2 = gen_reg_rtx (SImode);
4074      arm_emit_coreregs_64bit_shift (ASHIFT, operands[0], operands[1],
4075				     operands[2], scratch1, scratch2);
4076      DONE;
4077    }
4078  "
4079)
4080
4081(define_expand "ashlsi3"
4082  [(set (match_operand:SI            0 "s_register_operand" "")
4083	(ashift:SI (match_operand:SI 1 "s_register_operand" "")
4084		   (match_operand:SI 2 "arm_rhs_operand" "")))]
4085  "TARGET_EITHER"
4086  "
4087  if (CONST_INT_P (operands[2])
4088      && (UINTVAL (operands[2])) > 31)
4089    {
4090      emit_insn (gen_movsi (operands[0], const0_rtx));
4091      DONE;
4092    }
4093  "
4094)
4095
4096(define_expand "ashrdi3"
4097  [(set (match_operand:DI              0 "s_register_operand" "")
4098        (ashiftrt:DI (match_operand:DI 1 "s_register_operand" "")
4099                     (match_operand:SI 2 "reg_or_int_operand" "")))]
4100  "TARGET_32BIT"
4101  "
4102  if (TARGET_NEON)
4103    {
4104      /* Delay the decision whether to use NEON or core-regs until
4105	 register allocation.  */
4106      emit_insn (gen_ashrdi3_neon (operands[0], operands[1], operands[2]));
4107      DONE;
4108    }
4109
4110  if (!CONST_INT_P (operands[2]) && TARGET_REALLY_IWMMXT)
4111    ; /* No special preparation statements; expand pattern as above.  */
4112  else
4113    {
4114      rtx scratch1, scratch2;
4115
4116      /* Ideally we should use iwmmxt here if we could know that operands[1]
4117         ends up already living in an iwmmxt register. Otherwise it's
4118         cheaper to have the alternate code being generated than moving
4119         values to iwmmxt regs and back.  */
4120
4121      /* Expand operation using core-registers.
4122	 'FAIL' would achieve the same thing, but this is a bit smarter.  */
4123      scratch1 = gen_reg_rtx (SImode);
4124      scratch2 = gen_reg_rtx (SImode);
4125      arm_emit_coreregs_64bit_shift (ASHIFTRT, operands[0], operands[1],
4126				     operands[2], scratch1, scratch2);
4127      DONE;
4128    }
4129  "
4130)
4131
4132(define_expand "ashrsi3"
4133  [(set (match_operand:SI              0 "s_register_operand" "")
4134	(ashiftrt:SI (match_operand:SI 1 "s_register_operand" "")
4135		     (match_operand:SI 2 "arm_rhs_operand" "")))]
4136  "TARGET_EITHER"
4137  "
4138  if (CONST_INT_P (operands[2])
4139      && UINTVAL (operands[2]) > 31)
4140    operands[2] = GEN_INT (31);
4141  "
4142)
4143
4144(define_expand "lshrdi3"
4145  [(set (match_operand:DI              0 "s_register_operand" "")
4146        (lshiftrt:DI (match_operand:DI 1 "s_register_operand" "")
4147                     (match_operand:SI 2 "reg_or_int_operand" "")))]
4148  "TARGET_32BIT"
4149  "
4150  if (TARGET_NEON)
4151    {
4152      /* Delay the decision whether to use NEON or core-regs until
4153	 register allocation.  */
4154      emit_insn (gen_lshrdi3_neon (operands[0], operands[1], operands[2]));
4155      DONE;
4156    }
4157
4158  if (!CONST_INT_P (operands[2]) && TARGET_REALLY_IWMMXT)
4159    ; /* No special preparation statements; expand pattern as above.  */
4160  else
4161    {
4162      rtx scratch1, scratch2;
4163
4164      /* Ideally we should use iwmmxt here if we could know that operands[1]
4165         ends up already living in an iwmmxt register. Otherwise it's
4166         cheaper to have the alternate code being generated than moving
4167         values to iwmmxt regs and back.  */
4168
4169      /* Expand operation using core-registers.
4170	 'FAIL' would achieve the same thing, but this is a bit smarter.  */
4171      scratch1 = gen_reg_rtx (SImode);
4172      scratch2 = gen_reg_rtx (SImode);
4173      arm_emit_coreregs_64bit_shift (LSHIFTRT, operands[0], operands[1],
4174				     operands[2], scratch1, scratch2);
4175      DONE;
4176    }
4177  "
4178)
4179
4180(define_expand "lshrsi3"
4181  [(set (match_operand:SI              0 "s_register_operand" "")
4182	(lshiftrt:SI (match_operand:SI 1 "s_register_operand" "")
4183		     (match_operand:SI 2 "arm_rhs_operand" "")))]
4184  "TARGET_EITHER"
4185  "
4186  if (CONST_INT_P (operands[2])
4187      && (UINTVAL (operands[2])) > 31)
4188    {
4189      emit_insn (gen_movsi (operands[0], const0_rtx));
4190      DONE;
4191    }
4192  "
4193)
4194
4195(define_expand "rotlsi3"
4196  [(set (match_operand:SI              0 "s_register_operand" "")
4197	(rotatert:SI (match_operand:SI 1 "s_register_operand" "")
4198		     (match_operand:SI 2 "reg_or_int_operand" "")))]
4199  "TARGET_32BIT"
4200  "
4201  if (CONST_INT_P (operands[2]))
4202    operands[2] = GEN_INT ((32 - INTVAL (operands[2])) % 32);
4203  else
4204    {
4205      rtx reg = gen_reg_rtx (SImode);
4206      emit_insn (gen_subsi3 (reg, GEN_INT (32), operands[2]));
4207      operands[2] = reg;
4208    }
4209  "
4210)
4211
4212(define_expand "rotrsi3"
4213  [(set (match_operand:SI              0 "s_register_operand" "")
4214	(rotatert:SI (match_operand:SI 1 "s_register_operand" "")
4215		     (match_operand:SI 2 "arm_rhs_operand" "")))]
4216  "TARGET_EITHER"
4217  "
4218  if (TARGET_32BIT)
4219    {
4220      if (CONST_INT_P (operands[2])
4221          && UINTVAL (operands[2]) > 31)
4222        operands[2] = GEN_INT (INTVAL (operands[2]) % 32);
4223    }
4224  else /* TARGET_THUMB1 */
4225    {
4226      if (CONST_INT_P (operands [2]))
4227        operands [2] = force_reg (SImode, operands[2]);
4228    }
4229  "
4230)
4231
4232(define_insn "*arm_shiftsi3"
4233  [(set (match_operand:SI   0 "s_register_operand" "=l,l,r,r")
4234	(match_operator:SI  3 "shift_operator"
4235	 [(match_operand:SI 1 "s_register_operand"  "0,l,r,r")
4236	  (match_operand:SI 2 "reg_or_int_operand" "l,M,M,r")]))]
4237  "TARGET_32BIT"
4238  "* return arm_output_shift(operands, 0);"
4239  [(set_attr "predicable" "yes")
4240   (set_attr "arch" "t2,t2,*,*")
4241   (set_attr "predicable_short_it" "yes,yes,no,no")
4242   (set_attr "length" "4")
4243   (set_attr "shift" "1")
4244   (set_attr "type" "alu_shift_reg,alu_shift_imm,alu_shift_imm,alu_shift_reg")]
4245)
4246
4247(define_insn "*shiftsi3_compare0"
4248  [(set (reg:CC_NOOV CC_REGNUM)
4249	(compare:CC_NOOV (match_operator:SI 3 "shift_operator"
4250			  [(match_operand:SI 1 "s_register_operand" "r,r")
4251			   (match_operand:SI 2 "arm_rhs_operand" "M,r")])
4252			 (const_int 0)))
4253   (set (match_operand:SI 0 "s_register_operand" "=r,r")
4254	(match_op_dup 3 [(match_dup 1) (match_dup 2)]))]
4255  "TARGET_32BIT"
4256  "* return arm_output_shift(operands, 1);"
4257  [(set_attr "conds" "set")
4258   (set_attr "shift" "1")
4259   (set_attr "type" "alus_shift_imm,alus_shift_reg")]
4260)
4261
4262(define_insn "*shiftsi3_compare0_scratch"
4263  [(set (reg:CC_NOOV CC_REGNUM)
4264	(compare:CC_NOOV (match_operator:SI 3 "shift_operator"
4265			  [(match_operand:SI 1 "s_register_operand" "r,r")
4266			   (match_operand:SI 2 "arm_rhs_operand" "M,r")])
4267			 (const_int 0)))
4268   (clobber (match_scratch:SI 0 "=r,r"))]
4269  "TARGET_32BIT"
4270  "* return arm_output_shift(operands, 1);"
4271  [(set_attr "conds" "set")
4272   (set_attr "shift" "1")
4273   (set_attr "type" "shift_imm,shift_reg")]
4274)
4275
4276(define_insn "*not_shiftsi"
4277  [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4278	(not:SI (match_operator:SI 3 "shift_operator"
4279		 [(match_operand:SI 1 "s_register_operand" "r,r")
4280		  (match_operand:SI 2 "shift_amount_operand" "M,rM")])))]
4281  "TARGET_32BIT"
4282  "mvn%?\\t%0, %1%S3"
4283  [(set_attr "predicable" "yes")
4284   (set_attr "shift" "1")
4285   (set_attr "arch" "32,a")
4286   (set_attr "type" "mvn_shift,mvn_shift_reg")])
4287
4288(define_insn "*not_shiftsi_compare0"
4289  [(set (reg:CC_NOOV CC_REGNUM)
4290	(compare:CC_NOOV
4291	 (not:SI (match_operator:SI 3 "shift_operator"
4292		  [(match_operand:SI 1 "s_register_operand" "r,r")
4293		   (match_operand:SI 2 "shift_amount_operand" "M,rM")]))
4294	 (const_int 0)))
4295   (set (match_operand:SI 0 "s_register_operand" "=r,r")
4296	(not:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])))]
4297  "TARGET_32BIT"
4298  "mvns%?\\t%0, %1%S3"
4299  [(set_attr "conds" "set")
4300   (set_attr "shift" "1")
4301   (set_attr "arch" "32,a")
4302   (set_attr "type" "mvn_shift,mvn_shift_reg")])
4303
4304(define_insn "*not_shiftsi_compare0_scratch"
4305  [(set (reg:CC_NOOV CC_REGNUM)
4306	(compare:CC_NOOV
4307	 (not:SI (match_operator:SI 3 "shift_operator"
4308		  [(match_operand:SI 1 "s_register_operand" "r,r")
4309		   (match_operand:SI 2 "shift_amount_operand" "M,rM")]))
4310	 (const_int 0)))
4311   (clobber (match_scratch:SI 0 "=r,r"))]
4312  "TARGET_32BIT"
4313  "mvns%?\\t%0, %1%S3"
4314  [(set_attr "conds" "set")
4315   (set_attr "shift" "1")
4316   (set_attr "arch" "32,a")
4317   (set_attr "type" "mvn_shift,mvn_shift_reg")])
4318
4319;; We don't really have extzv, but defining this using shifts helps
4320;; to reduce register pressure later on.
4321
4322(define_expand "extzv"
4323  [(set (match_operand 0 "s_register_operand" "")
4324	(zero_extract (match_operand 1 "nonimmediate_operand" "")
4325		      (match_operand 2 "const_int_operand" "")
4326		      (match_operand 3 "const_int_operand" "")))]
4327  "TARGET_THUMB1 || arm_arch_thumb2"
4328  "
4329  {
4330    HOST_WIDE_INT lshift = 32 - INTVAL (operands[2]) - INTVAL (operands[3]);
4331    HOST_WIDE_INT rshift = 32 - INTVAL (operands[2]);
4332
4333    if (arm_arch_thumb2)
4334      {
4335	HOST_WIDE_INT width = INTVAL (operands[2]);
4336	HOST_WIDE_INT bitpos = INTVAL (operands[3]);
4337
4338	if (unaligned_access && MEM_P (operands[1])
4339	    && (width == 16 || width == 32) && (bitpos % BITS_PER_UNIT) == 0)
4340	  {
4341	    rtx base_addr;
4342
4343	    if (BYTES_BIG_ENDIAN)
4344	      bitpos = GET_MODE_BITSIZE (GET_MODE (operands[0])) - width
4345		       - bitpos;
4346
4347	    if (width == 32)
4348              {
4349		base_addr = adjust_address (operands[1], SImode,
4350					    bitpos / BITS_PER_UNIT);
4351		emit_insn (gen_unaligned_loadsi (operands[0], base_addr));
4352              }
4353	    else
4354              {
4355		rtx dest = operands[0];
4356		rtx tmp = gen_reg_rtx (SImode);
4357
4358		/* We may get a paradoxical subreg here.  Strip it off.  */
4359		if (GET_CODE (dest) == SUBREG
4360		    && GET_MODE (dest) == SImode
4361		    && GET_MODE (SUBREG_REG (dest)) == HImode)
4362		  dest = SUBREG_REG (dest);
4363
4364		if (GET_MODE_BITSIZE (GET_MODE (dest)) != width)
4365		  FAIL;
4366
4367		base_addr = adjust_address (operands[1], HImode,
4368					    bitpos / BITS_PER_UNIT);
4369		emit_insn (gen_unaligned_loadhiu (tmp, base_addr));
4370		emit_move_insn (gen_lowpart (SImode, dest), tmp);
4371	      }
4372	    DONE;
4373	  }
4374	else if (s_register_operand (operands[1], GET_MODE (operands[1])))
4375	  {
4376	    emit_insn (gen_extzv_t2 (operands[0], operands[1], operands[2],
4377				     operands[3]));
4378	    DONE;
4379	  }
4380	else
4381	  FAIL;
4382      }
4383
4384    if (!s_register_operand (operands[1], GET_MODE (operands[1])))
4385      FAIL;
4386
4387    operands[3] = GEN_INT (rshift);
4388
4389    if (lshift == 0)
4390      {
4391        emit_insn (gen_lshrsi3 (operands[0], operands[1], operands[3]));
4392        DONE;
4393      }
4394
4395    emit_insn (gen_extzv_t1 (operands[0], operands[1], GEN_INT (lshift),
4396			     operands[3], gen_reg_rtx (SImode)));
4397    DONE;
4398  }"
4399)
4400
4401;; Helper for extzv, for the Thumb-1 register-shifts case.
4402
4403(define_expand "extzv_t1"
4404  [(set (match_operand:SI 4 "s_register_operand" "")
4405	(ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
4406		   (match_operand:SI 2 "const_int_operand" "")))
4407   (set (match_operand:SI 0 "s_register_operand" "")
4408	(lshiftrt:SI (match_dup 4)
4409		     (match_operand:SI 3 "const_int_operand" "")))]
4410  "TARGET_THUMB1"
4411  "")
4412
4413(define_expand "extv"
4414  [(set (match_operand 0 "s_register_operand" "")
4415	(sign_extract (match_operand 1 "nonimmediate_operand" "")
4416		      (match_operand 2 "const_int_operand" "")
4417		      (match_operand 3 "const_int_operand" "")))]
4418  "arm_arch_thumb2"
4419{
4420  HOST_WIDE_INT width = INTVAL (operands[2]);
4421  HOST_WIDE_INT bitpos = INTVAL (operands[3]);
4422
4423  if (unaligned_access && MEM_P (operands[1]) && (width == 16 || width == 32)
4424      && (bitpos % BITS_PER_UNIT)  == 0)
4425    {
4426      rtx base_addr;
4427
4428      if (BYTES_BIG_ENDIAN)
4429	bitpos = GET_MODE_BITSIZE (GET_MODE (operands[0])) - width - bitpos;
4430
4431      if (width == 32)
4432        {
4433	  base_addr = adjust_address (operands[1], SImode,
4434				      bitpos / BITS_PER_UNIT);
4435	  emit_insn (gen_unaligned_loadsi (operands[0], base_addr));
4436        }
4437      else
4438        {
4439	  rtx dest = operands[0];
4440	  rtx tmp = gen_reg_rtx (SImode);
4441
4442	  /* We may get a paradoxical subreg here.  Strip it off.  */
4443	  if (GET_CODE (dest) == SUBREG
4444	      && GET_MODE (dest) == SImode
4445	      && GET_MODE (SUBREG_REG (dest)) == HImode)
4446	    dest = SUBREG_REG (dest);
4447
4448	  if (GET_MODE_BITSIZE (GET_MODE (dest)) != width)
4449	    FAIL;
4450
4451	  base_addr = adjust_address (operands[1], HImode,
4452				      bitpos / BITS_PER_UNIT);
4453	  emit_insn (gen_unaligned_loadhis (tmp, base_addr));
4454	  emit_move_insn (gen_lowpart (SImode, dest), tmp);
4455	}
4456
4457      DONE;
4458    }
4459  else if (!s_register_operand (operands[1], GET_MODE (operands[1])))
4460    FAIL;
4461  else if (GET_MODE (operands[0]) == SImode
4462	   && GET_MODE (operands[1]) == SImode)
4463    {
4464      emit_insn (gen_extv_regsi (operands[0], operands[1], operands[2],
4465				 operands[3]));
4466      DONE;
4467    }
4468
4469  FAIL;
4470})
4471
4472; Helper to expand register forms of extv with the proper modes.
4473
4474(define_expand "extv_regsi"
4475  [(set (match_operand:SI 0 "s_register_operand" "")
4476	(sign_extract:SI (match_operand:SI 1 "s_register_operand" "")
4477			 (match_operand 2 "const_int_operand" "")
4478			 (match_operand 3 "const_int_operand" "")))]
4479  ""
4480{
4481})
4482
4483; ARMv6+ unaligned load/store instructions (used for packed structure accesses).
4484
4485(define_insn "unaligned_loadsi"
4486  [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4487	(unspec:SI [(match_operand:SI 1 "memory_operand" "Uw,m")]
4488		   UNSPEC_UNALIGNED_LOAD))]
4489  "unaligned_access"
4490  "ldr%?\t%0, %1\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" "load_4")])
4496
4497(define_insn "unaligned_loadhis"
4498  [(set (match_operand:SI 0 "s_register_operand" "=r")
4499	(sign_extend:SI
4500	  (unspec:HI [(match_operand:HI 1 "memory_operand" "Uh")]
4501		     UNSPEC_UNALIGNED_LOAD)))]
4502  "unaligned_access"
4503  "ldrsh%?\t%0, %1\t@ unaligned"
4504  [(set_attr "predicable" "yes")
4505   (set_attr "type" "load_byte")])
4506
4507(define_insn "unaligned_loadhiu"
4508  [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4509	(zero_extend:SI
4510	  (unspec:HI [(match_operand:HI 1 "memory_operand" "Uw,m")]
4511		     UNSPEC_UNALIGNED_LOAD)))]
4512  "unaligned_access"
4513  "ldrh%?\t%0, %1\t@ unaligned"
4514  [(set_attr "arch" "t2,any")
4515   (set_attr "length" "2,4")
4516   (set_attr "predicable" "yes")
4517   (set_attr "predicable_short_it" "yes,no")
4518   (set_attr "type" "load_byte")])
4519
4520(define_insn "unaligned_storesi"
4521  [(set (match_operand:SI 0 "memory_operand" "=Uw,m")
4522	(unspec:SI [(match_operand:SI 1 "s_register_operand" "l,r")]
4523		   UNSPEC_UNALIGNED_STORE))]
4524  "unaligned_access"
4525  "str%?\t%1, %0\t@ unaligned"
4526  [(set_attr "arch" "t2,any")
4527   (set_attr "length" "2,4")
4528   (set_attr "predicable" "yes")
4529   (set_attr "predicable_short_it" "yes,no")
4530   (set_attr "type" "store_4")])
4531
4532(define_insn "unaligned_storehi"
4533  [(set (match_operand:HI 0 "memory_operand" "=Uw,m")
4534	(unspec:HI [(match_operand:HI 1 "s_register_operand" "l,r")]
4535		   UNSPEC_UNALIGNED_STORE))]
4536  "unaligned_access"
4537  "strh%?\t%1, %0\t@ unaligned"
4538  [(set_attr "arch" "t2,any")
4539   (set_attr "length" "2,4")
4540   (set_attr "predicable" "yes")
4541   (set_attr "predicable_short_it" "yes,no")
4542   (set_attr "type" "store_4")])
4543
4544
4545(define_insn "*extv_reg"
4546  [(set (match_operand:SI 0 "s_register_operand" "=r")
4547	(sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
4548			  (match_operand:SI 2 "const_int_operand" "n")
4549			  (match_operand:SI 3 "const_int_operand" "n")))]
4550  "arm_arch_thumb2
4551   && IN_RANGE (INTVAL (operands[3]), 0, 31)
4552   && IN_RANGE (INTVAL (operands[2]), 1, 32 - INTVAL (operands[3]))"
4553  "sbfx%?\t%0, %1, %3, %2"
4554  [(set_attr "length" "4")
4555   (set_attr "predicable" "yes")
4556   (set_attr "type" "bfm")]
4557)
4558
4559(define_insn "extzv_t2"
4560  [(set (match_operand:SI 0 "s_register_operand" "=r")
4561	(zero_extract:SI (match_operand:SI 1 "s_register_operand" "r")
4562			  (match_operand:SI 2 "const_int_operand" "n")
4563			  (match_operand:SI 3 "const_int_operand" "n")))]
4564  "arm_arch_thumb2
4565   && IN_RANGE (INTVAL (operands[3]), 0, 31)
4566   && IN_RANGE (INTVAL (operands[2]), 1, 32 - INTVAL (operands[3]))"
4567  "ubfx%?\t%0, %1, %3, %2"
4568  [(set_attr "length" "4")
4569   (set_attr "predicable" "yes")
4570   (set_attr "type" "bfm")]
4571)
4572
4573
4574;; Division instructions
4575(define_insn "divsi3"
4576  [(set (match_operand:SI	  0 "s_register_operand" "=r,r")
4577	(div:SI (match_operand:SI 1 "s_register_operand"  "r,r")
4578		(match_operand:SI 2 "s_register_operand"  "r,r")))]
4579  "TARGET_IDIV"
4580  "@
4581   sdiv%?\t%0, %1, %2
4582   sdiv\t%0, %1, %2"
4583  [(set_attr "arch" "32,v8mb")
4584   (set_attr "predicable" "yes")
4585   (set_attr "type" "sdiv")]
4586)
4587
4588(define_insn "udivsi3"
4589  [(set (match_operand:SI	   0 "s_register_operand" "=r,r")
4590	(udiv:SI (match_operand:SI 1 "s_register_operand"  "r,r")
4591		 (match_operand:SI 2 "s_register_operand"  "r,r")))]
4592  "TARGET_IDIV"
4593  "@
4594   udiv%?\t%0, %1, %2
4595   udiv\t%0, %1, %2"
4596  [(set_attr "arch" "32,v8mb")
4597   (set_attr "predicable" "yes")
4598   (set_attr "type" "udiv")]
4599)
4600
4601
4602;; Unary arithmetic insns
4603
4604(define_expand "negvsi3"
4605  [(match_operand:SI 0 "register_operand")
4606   (match_operand:SI 1 "register_operand")
4607   (match_operand 2 "")]
4608  "TARGET_32BIT"
4609{
4610  emit_insn (gen_subsi3_compare (operands[0], const0_rtx, operands[1]));
4611  arm_gen_unlikely_cbranch (NE, CC_Vmode, operands[2]);
4612
4613  DONE;
4614})
4615
4616(define_expand "negvdi3"
4617  [(match_operand:DI 0 "register_operand")
4618   (match_operand:DI 1 "register_operand")
4619   (match_operand 2 "")]
4620  "TARGET_ARM"
4621{
4622  emit_insn (gen_negdi2_compare (operands[0], operands[1]));
4623  arm_gen_unlikely_cbranch (NE, CC_Vmode, operands[2]);
4624
4625  DONE;
4626})
4627
4628
4629(define_insn_and_split "negdi2_compare"
4630  [(set (reg:CC CC_REGNUM)
4631	(compare:CC
4632	  (const_int 0)
4633	  (match_operand:DI 1 "register_operand" "0,r")))
4634   (set (match_operand:DI 0 "register_operand" "=r,&r")
4635	(minus:DI (const_int 0) (match_dup 1)))]
4636  "TARGET_ARM"
4637  "#"
4638  "&& reload_completed"
4639  [(parallel [(set (reg:CC CC_REGNUM)
4640		   (compare:CC (const_int 0) (match_dup 1)))
4641	      (set (match_dup 0) (minus:SI (const_int 0)
4642					   (match_dup 1)))])
4643   (parallel [(set (reg:CC CC_REGNUM)
4644		   (compare:CC (const_int 0) (match_dup 3)))
4645	     (set (match_dup 2)
4646		  (minus:SI
4647		   (minus:SI (const_int 0) (match_dup 3))
4648		   (ltu:SI (reg:CC_C CC_REGNUM)
4649			   (const_int 0))))])]
4650  {
4651    operands[2] = gen_highpart (SImode, operands[0]);
4652    operands[0] = gen_lowpart (SImode, operands[0]);
4653    operands[3] = gen_highpart (SImode, operands[1]);
4654    operands[1] = gen_lowpart (SImode, operands[1]);
4655  }
4656  [(set_attr "conds" "set")
4657   (set_attr "length" "8")
4658   (set_attr "type" "multiple")]
4659)
4660
4661(define_expand "negdi2"
4662 [(parallel
4663   [(set (match_operand:DI 0 "s_register_operand" "")
4664	 (neg:DI (match_operand:DI 1 "s_register_operand" "")))
4665    (clobber (reg:CC CC_REGNUM))])]
4666  "TARGET_EITHER"
4667  {
4668    if (TARGET_NEON)
4669      {
4670        emit_insn (gen_negdi2_neon (operands[0], operands[1]));
4671	DONE;
4672      }
4673  }
4674)
4675
4676;; The constraints here are to prevent a *partial* overlap (where %Q0 == %R1).
4677;; The first alternative allows the common case of a *full* overlap.
4678(define_insn_and_split "*negdi2_insn"
4679  [(set (match_operand:DI         0 "s_register_operand" "=r,&r")
4680	(neg:DI (match_operand:DI 1 "s_register_operand"  "0,r")))
4681   (clobber (reg:CC CC_REGNUM))]
4682  "TARGET_32BIT"
4683  "#"	; rsbs %Q0, %Q1, #0; rsc %R0, %R1, #0	       (ARM)
4684	; negs %Q0, %Q1    ; sbc %R0, %R1, %R1, lsl #1 (Thumb-2)
4685  "&& reload_completed"
4686  [(parallel [(set (reg:CC CC_REGNUM)
4687		   (compare:CC (const_int 0) (match_dup 1)))
4688	      (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1)))])
4689   (set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3))
4690                                (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
4691  {
4692    operands[2] = gen_highpart (SImode, operands[0]);
4693    operands[0] = gen_lowpart (SImode, operands[0]);
4694    operands[3] = gen_highpart (SImode, operands[1]);
4695    operands[1] = gen_lowpart (SImode, operands[1]);
4696  }
4697  [(set_attr "conds" "clob")
4698   (set_attr "length" "8")
4699   (set_attr "type" "multiple")]
4700)
4701
4702(define_insn "*negsi2_carryin_compare"
4703  [(set (reg:CC CC_REGNUM)
4704	(compare:CC (const_int 0)
4705		    (match_operand:SI 1 "s_register_operand" "r")))
4706   (set (match_operand:SI 0 "s_register_operand" "=r")
4707	(minus:SI (minus:SI (const_int 0)
4708			    (match_dup 1))
4709		  (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
4710  "TARGET_ARM"
4711  "rscs\\t%0, %1, #0"
4712  [(set_attr "conds" "set")
4713   (set_attr "type" "alus_imm")]
4714)
4715
4716(define_expand "negsi2"
4717  [(set (match_operand:SI         0 "s_register_operand" "")
4718	(neg:SI (match_operand:SI 1 "s_register_operand" "")))]
4719  "TARGET_EITHER"
4720  ""
4721)
4722
4723(define_insn "*arm_negsi2"
4724  [(set (match_operand:SI         0 "s_register_operand" "=l,r")
4725	(neg:SI (match_operand:SI 1 "s_register_operand" "l,r")))]
4726  "TARGET_32BIT"
4727  "rsb%?\\t%0, %1, #0"
4728  [(set_attr "predicable" "yes")
4729   (set_attr "predicable_short_it" "yes,no")
4730   (set_attr "arch" "t2,*")
4731   (set_attr "length" "4")
4732   (set_attr "type" "alu_sreg")]
4733)
4734
4735(define_expand "negsf2"
4736  [(set (match_operand:SF         0 "s_register_operand" "")
4737	(neg:SF (match_operand:SF 1 "s_register_operand" "")))]
4738  "TARGET_32BIT && TARGET_HARD_FLOAT"
4739  ""
4740)
4741
4742(define_expand "negdf2"
4743  [(set (match_operand:DF         0 "s_register_operand" "")
4744	(neg:DF (match_operand:DF 1 "s_register_operand" "")))]
4745  "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
4746  "")
4747
4748(define_insn_and_split "*zextendsidi_negsi"
4749  [(set (match_operand:DI 0 "s_register_operand" "=r")
4750        (zero_extend:DI (neg:SI (match_operand:SI 1 "s_register_operand" "r"))))]
4751   "TARGET_32BIT"
4752   "#"
4753   ""
4754   [(set (match_dup 2)
4755         (neg:SI (match_dup 1)))
4756    (set (match_dup 3)
4757         (const_int 0))]
4758   {
4759      operands[2] = gen_lowpart (SImode, operands[0]);
4760      operands[3] = gen_highpart (SImode, operands[0]);
4761   }
4762 [(set_attr "length" "8")
4763  (set_attr "type" "multiple")]
4764)
4765
4766;; Negate an extended 32-bit value.
4767(define_insn_and_split "*negdi_extendsidi"
4768  [(set (match_operand:DI 0 "s_register_operand" "=l,r")
4769	(neg:DI (sign_extend:DI
4770		 (match_operand:SI 1 "s_register_operand" "l,r"))))
4771   (clobber (reg:CC CC_REGNUM))]
4772  "TARGET_32BIT"
4773  "#"
4774  "&& reload_completed"
4775  [(const_int 0)]
4776  {
4777    rtx low = gen_lowpart (SImode, operands[0]);
4778    rtx high = gen_highpart (SImode, operands[0]);
4779
4780    if (reg_overlap_mentioned_p (low, operands[1]))
4781      {
4782	/* Input overlaps the low word of the output.  Use:
4783		asr	Rhi, Rin, #31
4784		rsbs	Rlo, Rin, #0
4785		rsc	Rhi, Rhi, #0 (thumb2: sbc Rhi, Rhi, Rhi, lsl #1).  */
4786	rtx cc_reg = gen_rtx_REG (CC_Cmode, CC_REGNUM);
4787
4788	emit_insn (gen_rtx_SET (high,
4789				gen_rtx_ASHIFTRT (SImode, operands[1],
4790						  GEN_INT (31))));
4791
4792	emit_insn (gen_subsi3_compare (low, const0_rtx, operands[1]));
4793	if (TARGET_ARM)
4794	  emit_insn (gen_rtx_SET (high,
4795				  gen_rtx_MINUS (SImode,
4796						 gen_rtx_MINUS (SImode,
4797								const0_rtx,
4798								high),
4799						 gen_rtx_LTU (SImode,
4800							      cc_reg,
4801							      const0_rtx))));
4802	else
4803	  {
4804	    rtx two_x = gen_rtx_ASHIFT (SImode, high, GEN_INT (1));
4805	    emit_insn (gen_rtx_SET (high,
4806				    gen_rtx_MINUS (SImode,
4807						   gen_rtx_MINUS (SImode,
4808								  high,
4809								  two_x),
4810						   gen_rtx_LTU (SImode,
4811								cc_reg,
4812								const0_rtx))));
4813	  }
4814      }
4815    else
4816      {
4817	/* No overlap, or overlap on high word.  Use:
4818		rsb	Rlo, Rin, #0
4819		bic	Rhi, Rlo, Rin
4820		asr	Rhi, Rhi, #31
4821	   Flags not needed for this sequence.  */
4822	emit_insn (gen_rtx_SET (low, gen_rtx_NEG (SImode, operands[1])));
4823	emit_insn (gen_rtx_SET (high,
4824				gen_rtx_AND (SImode,
4825					     gen_rtx_NOT (SImode, operands[1]),
4826					     low)));
4827	emit_insn (gen_rtx_SET (high,
4828				gen_rtx_ASHIFTRT (SImode, high,
4829						  GEN_INT (31))));
4830      }
4831    DONE;
4832  }
4833  [(set_attr "length" "12")
4834   (set_attr "arch" "t2,*")
4835   (set_attr "type" "multiple")]
4836)
4837
4838(define_insn_and_split "*negdi_zero_extendsidi"
4839  [(set (match_operand:DI 0 "s_register_operand" "=r,&r")
4840	(neg:DI (zero_extend:DI (match_operand:SI 1 "s_register_operand" "0,r"))))
4841   (clobber (reg:CC CC_REGNUM))]
4842  "TARGET_32BIT"
4843  "#" ; "rsbs\\t%Q0, %1, #0\;sbc\\t%R0,%R0,%R0"
4844      ;; Don't care what register is input to sbc,
4845      ;; since we just need to propagate the carry.
4846  "&& reload_completed"
4847  [(parallel [(set (reg:CC CC_REGNUM)
4848                   (compare:CC (const_int 0) (match_dup 1)))
4849              (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1)))])
4850   (set (match_dup 2) (minus:SI (minus:SI (match_dup 2) (match_dup 2))
4851                                (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
4852  {
4853    operands[2] = gen_highpart (SImode, operands[0]);
4854    operands[0] = gen_lowpart (SImode, operands[0]);
4855  }
4856  [(set_attr "conds" "clob")
4857   (set_attr "length" "8")
4858   (set_attr "type" "multiple")]   ;; length in thumb is 4
4859)
4860
4861;; abssi2 doesn't really clobber the condition codes if a different register
4862;; is being set.  To keep things simple, assume during rtl manipulations that
4863;; it does, but tell the final scan operator the truth.  Similarly for
4864;; (neg (abs...))
4865
4866(define_expand "abssi2"
4867  [(parallel
4868    [(set (match_operand:SI         0 "s_register_operand" "")
4869	  (abs:SI (match_operand:SI 1 "s_register_operand" "")))
4870     (clobber (match_dup 2))])]
4871  "TARGET_EITHER"
4872  "
4873  if (TARGET_THUMB1)
4874    operands[2] = gen_rtx_SCRATCH (SImode);
4875  else
4876    operands[2] = gen_rtx_REG (CCmode, CC_REGNUM);
4877")
4878
4879(define_insn_and_split "*arm_abssi2"
4880  [(set (match_operand:SI 0 "s_register_operand" "=r,&r")
4881	(abs:SI (match_operand:SI 1 "s_register_operand" "0,r")))
4882   (clobber (reg:CC CC_REGNUM))]
4883  "TARGET_ARM"
4884  "#"
4885  "&& reload_completed"
4886  [(const_int 0)]
4887  {
4888   /* if (which_alternative == 0) */
4889   if (REGNO(operands[0]) == REGNO(operands[1]))
4890     {
4891      /* Emit the pattern:
4892         cmp\\t%0, #0\;rsblt\\t%0, %0, #0
4893         [(set (reg:CC CC_REGNUM)
4894               (compare:CC (match_dup 0) (const_int 0)))
4895          (cond_exec (lt:CC (reg:CC CC_REGNUM) (const_int 0))
4896                     (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1))))]
4897      */
4898      emit_insn (gen_rtx_SET (gen_rtx_REG (CCmode, CC_REGNUM),
4899                              gen_rtx_COMPARE (CCmode, operands[0], const0_rtx)));
4900      emit_insn (gen_rtx_COND_EXEC (VOIDmode,
4901                                    (gen_rtx_LT (SImode,
4902                                                 gen_rtx_REG (CCmode, CC_REGNUM),
4903                                                 const0_rtx)),
4904                                    (gen_rtx_SET (operands[0],
4905                                                  (gen_rtx_MINUS (SImode,
4906                                                                  const0_rtx,
4907                                                                  operands[1]))))));
4908      DONE;
4909     }
4910   else
4911     {
4912      /* Emit the pattern:
4913         alt1: eor%?\\t%0, %1, %1, asr #31\;sub%?\\t%0, %0, %1, asr #31
4914         [(set (match_dup 0)
4915               (xor:SI (match_dup 1)
4916                       (ashiftrt:SI (match_dup 1) (const_int 31))))
4917          (set (match_dup 0)
4918               (minus:SI (match_dup 0)
4919                      (ashiftrt:SI (match_dup 1) (const_int 31))))]
4920      */
4921      emit_insn (gen_rtx_SET (operands[0],
4922                              gen_rtx_XOR (SImode,
4923                                           gen_rtx_ASHIFTRT (SImode,
4924                                                             operands[1],
4925                                                             GEN_INT (31)),
4926                                           operands[1])));
4927      emit_insn (gen_rtx_SET (operands[0],
4928                              gen_rtx_MINUS (SImode,
4929                                             operands[0],
4930                                             gen_rtx_ASHIFTRT (SImode,
4931                                                               operands[1],
4932                                                               GEN_INT (31)))));
4933      DONE;
4934     }
4935  }
4936  [(set_attr "conds" "clob,*")
4937   (set_attr "shift" "1")
4938   (set_attr "predicable" "no, yes")
4939   (set_attr "length" "8")
4940   (set_attr "type" "multiple")]
4941)
4942
4943(define_insn_and_split "*arm_neg_abssi2"
4944  [(set (match_operand:SI 0 "s_register_operand" "=r,&r")
4945	(neg:SI (abs:SI (match_operand:SI 1 "s_register_operand" "0,r"))))
4946   (clobber (reg:CC CC_REGNUM))]
4947  "TARGET_ARM"
4948  "#"
4949  "&& reload_completed"
4950  [(const_int 0)]
4951  {
4952   /* if (which_alternative == 0) */
4953   if (REGNO (operands[0]) == REGNO (operands[1]))
4954     {
4955      /* Emit the pattern:
4956         cmp\\t%0, #0\;rsbgt\\t%0, %0, #0
4957      */
4958      emit_insn (gen_rtx_SET (gen_rtx_REG (CCmode, CC_REGNUM),
4959                              gen_rtx_COMPARE (CCmode, operands[0], const0_rtx)));
4960      emit_insn (gen_rtx_COND_EXEC (VOIDmode,
4961                                    gen_rtx_GT (SImode,
4962                                                gen_rtx_REG (CCmode, CC_REGNUM),
4963                                                const0_rtx),
4964                                    gen_rtx_SET (operands[0],
4965                                                 (gen_rtx_MINUS (SImode,
4966                                                                 const0_rtx,
4967                                                                 operands[1])))));
4968     }
4969   else
4970     {
4971      /* Emit the pattern:
4972         eor%?\\t%0, %1, %1, asr #31\;rsb%?\\t%0, %0, %1, asr #31
4973      */
4974      emit_insn (gen_rtx_SET (operands[0],
4975                              gen_rtx_XOR (SImode,
4976                                           gen_rtx_ASHIFTRT (SImode,
4977                                                             operands[1],
4978                                                             GEN_INT (31)),
4979                                           operands[1])));
4980      emit_insn (gen_rtx_SET (operands[0],
4981                              gen_rtx_MINUS (SImode,
4982                                             gen_rtx_ASHIFTRT (SImode,
4983                                                               operands[1],
4984                                                               GEN_INT (31)),
4985                                             operands[0])));
4986     }
4987   DONE;
4988  }
4989  [(set_attr "conds" "clob,*")
4990   (set_attr "shift" "1")
4991   (set_attr "predicable" "no, yes")
4992   (set_attr "length" "8")
4993   (set_attr "type" "multiple")]
4994)
4995
4996(define_expand "abssf2"
4997  [(set (match_operand:SF         0 "s_register_operand" "")
4998	(abs:SF (match_operand:SF 1 "s_register_operand" "")))]
4999  "TARGET_32BIT && TARGET_HARD_FLOAT"
5000  "")
5001
5002(define_expand "absdf2"
5003  [(set (match_operand:DF         0 "s_register_operand" "")
5004	(abs:DF (match_operand:DF 1 "s_register_operand" "")))]
5005  "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
5006  "")
5007
5008(define_expand "sqrtsf2"
5009  [(set (match_operand:SF 0 "s_register_operand" "")
5010	(sqrt:SF (match_operand:SF 1 "s_register_operand" "")))]
5011  "TARGET_32BIT && TARGET_HARD_FLOAT"
5012  "")
5013
5014(define_expand "sqrtdf2"
5015  [(set (match_operand:DF 0 "s_register_operand" "")
5016	(sqrt:DF (match_operand:DF 1 "s_register_operand" "")))]
5017  "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
5018  "")
5019
5020(define_expand "one_cmpldi2"
5021  [(set (match_operand:DI 0 "s_register_operand" "")
5022	(not:DI (match_operand:DI 1 "s_register_operand" "")))]
5023  "TARGET_32BIT"
5024  "
5025  if (!TARGET_NEON && !TARGET_IWMMXT)
5026    {
5027      rtx low  = simplify_gen_unary (NOT, SImode,
5028				     gen_lowpart (SImode, operands[1]),
5029				     SImode);
5030      rtx high = simplify_gen_unary (NOT, SImode,
5031				     gen_highpart_mode (SImode, DImode,
5032							operands[1]),
5033				     SImode);
5034
5035      emit_insn (gen_rtx_SET (gen_lowpart (SImode, operands[0]), low));
5036      emit_insn (gen_rtx_SET (gen_highpart (SImode, operands[0]), high));
5037
5038      DONE;
5039    }
5040  /* Otherwise expand pattern as above.  */
5041  "
5042)
5043
5044(define_insn_and_split "*one_cmpldi2_insn"
5045  [(set (match_operand:DI 0 "s_register_operand"	 "=w,&r,&r,?w")
5046	(not:DI (match_operand:DI 1 "s_register_operand" " w, 0, r, w")))]
5047  "TARGET_32BIT"
5048  "@
5049   vmvn\t%P0, %P1
5050   #
5051   #
5052   vmvn\t%P0, %P1"
5053  "TARGET_32BIT && reload_completed
5054   && arm_general_register_operand (operands[0], DImode)"
5055  [(set (match_dup 0) (not:SI (match_dup 1)))
5056   (set (match_dup 2) (not:SI (match_dup 3)))]
5057  "
5058  {
5059    operands[2] = gen_highpart (SImode, operands[0]);
5060    operands[0] = gen_lowpart (SImode, operands[0]);
5061    operands[3] = gen_highpart (SImode, operands[1]);
5062    operands[1] = gen_lowpart (SImode, operands[1]);
5063  }"
5064  [(set_attr "length" "*,8,8,*")
5065   (set_attr "predicable" "no,yes,yes,no")
5066   (set_attr "type" "neon_move,multiple,multiple,neon_move")
5067   (set_attr "arch" "neon_for_64bits,*,*,avoid_neon_for_64bits")]
5068)
5069
5070(define_expand "one_cmplsi2"
5071  [(set (match_operand:SI         0 "s_register_operand" "")
5072	(not:SI (match_operand:SI 1 "s_register_operand" "")))]
5073  "TARGET_EITHER"
5074  ""
5075)
5076
5077(define_insn "*arm_one_cmplsi2"
5078  [(set (match_operand:SI         0 "s_register_operand" "=l,r")
5079	(not:SI (match_operand:SI 1 "s_register_operand"  "l,r")))]
5080  "TARGET_32BIT"
5081  "mvn%?\\t%0, %1"
5082  [(set_attr "predicable" "yes")
5083   (set_attr "predicable_short_it" "yes,no")
5084   (set_attr "arch" "t2,*")
5085   (set_attr "length" "4")
5086   (set_attr "type" "mvn_reg")]
5087)
5088
5089(define_insn "*notsi_compare0"
5090  [(set (reg:CC_NOOV CC_REGNUM)
5091	(compare:CC_NOOV (not:SI (match_operand:SI 1 "s_register_operand" "r"))
5092			 (const_int 0)))
5093   (set (match_operand:SI 0 "s_register_operand" "=r")
5094	(not:SI (match_dup 1)))]
5095  "TARGET_32BIT"
5096  "mvns%?\\t%0, %1"
5097  [(set_attr "conds" "set")
5098   (set_attr "type" "mvn_reg")]
5099)
5100
5101(define_insn "*notsi_compare0_scratch"
5102  [(set (reg:CC_NOOV CC_REGNUM)
5103	(compare:CC_NOOV (not:SI (match_operand:SI 1 "s_register_operand" "r"))
5104			 (const_int 0)))
5105   (clobber (match_scratch:SI 0 "=r"))]
5106  "TARGET_32BIT"
5107  "mvns%?\\t%0, %1"
5108  [(set_attr "conds" "set")
5109   (set_attr "type" "mvn_reg")]
5110)
5111
5112;; Fixed <--> Floating conversion insns
5113
5114(define_expand "floatsihf2"
5115  [(set (match_operand:HF           0 "general_operand" "")
5116	(float:HF (match_operand:SI 1 "general_operand" "")))]
5117  "TARGET_EITHER"
5118  "
5119  {
5120    rtx op1 = gen_reg_rtx (SFmode);
5121    expand_float (op1, operands[1], 0);
5122    op1 = convert_to_mode (HFmode, op1, 0);
5123    emit_move_insn (operands[0], op1);
5124    DONE;
5125  }"
5126)
5127
5128(define_expand "floatdihf2"
5129  [(set (match_operand:HF           0 "general_operand" "")
5130	(float:HF (match_operand:DI 1 "general_operand" "")))]
5131  "TARGET_EITHER"
5132  "
5133  {
5134    rtx op1 = gen_reg_rtx (SFmode);
5135    expand_float (op1, operands[1], 0);
5136    op1 = convert_to_mode (HFmode, op1, 0);
5137    emit_move_insn (operands[0], op1);
5138    DONE;
5139  }"
5140)
5141
5142(define_expand "floatsisf2"
5143  [(set (match_operand:SF           0 "s_register_operand" "")
5144	(float:SF (match_operand:SI 1 "s_register_operand" "")))]
5145  "TARGET_32BIT && TARGET_HARD_FLOAT"
5146  "
5147")
5148
5149(define_expand "floatsidf2"
5150  [(set (match_operand:DF           0 "s_register_operand" "")
5151	(float:DF (match_operand:SI 1 "s_register_operand" "")))]
5152  "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
5153  "
5154")
5155
5156(define_expand "fix_trunchfsi2"
5157  [(set (match_operand:SI         0 "general_operand" "")
5158	(fix:SI (fix:HF (match_operand:HF 1 "general_operand"  ""))))]
5159  "TARGET_EITHER"
5160  "
5161  {
5162    rtx op1 = convert_to_mode (SFmode, operands[1], 0);
5163    expand_fix (operands[0], op1, 0);
5164    DONE;
5165  }"
5166)
5167
5168(define_expand "fix_trunchfdi2"
5169  [(set (match_operand:DI         0 "general_operand" "")
5170	(fix:DI (fix:HF (match_operand:HF 1 "general_operand"  ""))))]
5171  "TARGET_EITHER"
5172  "
5173  {
5174    rtx op1 = convert_to_mode (SFmode, operands[1], 0);
5175    expand_fix (operands[0], op1, 0);
5176    DONE;
5177  }"
5178)
5179
5180(define_expand "fix_truncsfsi2"
5181  [(set (match_operand:SI         0 "s_register_operand" "")
5182	(fix:SI (fix:SF (match_operand:SF 1 "s_register_operand"  ""))))]
5183  "TARGET_32BIT && TARGET_HARD_FLOAT"
5184  "
5185")
5186
5187(define_expand "fix_truncdfsi2"
5188  [(set (match_operand:SI         0 "s_register_operand" "")
5189	(fix:SI (fix:DF (match_operand:DF 1 "s_register_operand"  ""))))]
5190  "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
5191  "
5192")
5193
5194;; Truncation insns
5195
5196(define_expand "truncdfsf2"
5197  [(set (match_operand:SF  0 "s_register_operand" "")
5198	(float_truncate:SF
5199 	 (match_operand:DF 1 "s_register_operand" "")))]
5200  "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
5201  ""
5202)
5203
5204;; DFmode to HFmode conversions on targets without a single-step hardware
5205;; instruction for it would have to go through SFmode.  This is dangerous
5206;; as it introduces double rounding.
5207;;
5208;; Disable this pattern unless we are in an unsafe math mode, or we have
5209;; a single-step instruction.
5210
5211(define_expand "truncdfhf2"
5212  [(set (match_operand:HF  0 "s_register_operand" "")
5213	(float_truncate:HF
5214	 (match_operand:DF 1 "s_register_operand" "")))]
5215  "(TARGET_EITHER && flag_unsafe_math_optimizations)
5216   || (TARGET_32BIT && TARGET_FP16_TO_DOUBLE)"
5217{
5218  /* We don't have a direct instruction for this, so we must be in
5219     an unsafe math mode, and going via SFmode.  */
5220
5221  if (!(TARGET_32BIT && TARGET_FP16_TO_DOUBLE))
5222    {
5223      rtx op1;
5224      op1 = convert_to_mode (SFmode, operands[1], 0);
5225      op1 = convert_to_mode (HFmode, op1, 0);
5226      emit_move_insn (operands[0], op1);
5227      DONE;
5228    }
5229  /* Otherwise, we will pick this up as a single instruction with
5230     no intermediary rounding.  */
5231}
5232)
5233
5234;; Zero and sign extension instructions.
5235
5236(define_insn "zero_extend<mode>di2"
5237  [(set (match_operand:DI 0 "s_register_operand" "=w,r,?r,w")
5238        (zero_extend:DI (match_operand:QHSI 1 "<qhs_zextenddi_op>"
5239					    "<qhs_zextenddi_cstr>")))]
5240  "TARGET_32BIT <qhs_zextenddi_cond>"
5241  "#"
5242  [(set_attr "length" "8,4,8,8")
5243   (set_attr "arch" "neon_for_64bits,*,*,avoid_neon_for_64bits")
5244   (set_attr "ce_count" "2")
5245   (set_attr "predicable" "yes")
5246   (set_attr "type" "multiple,mov_reg,multiple,multiple")]
5247)
5248
5249(define_insn "extend<mode>di2"
5250  [(set (match_operand:DI 0 "s_register_operand" "=w,r,?r,?r,w")
5251        (sign_extend:DI (match_operand:QHSI 1 "<qhs_extenddi_op>"
5252					    "<qhs_extenddi_cstr>")))]
5253  "TARGET_32BIT <qhs_sextenddi_cond>"
5254  "#"
5255  [(set_attr "length" "8,4,8,8,8")
5256   (set_attr "ce_count" "2")
5257   (set_attr "shift" "1")
5258   (set_attr "predicable" "yes")
5259   (set_attr "arch" "neon_for_64bits,*,a,t,avoid_neon_for_64bits")
5260   (set_attr "type" "multiple,mov_reg,multiple,multiple,multiple")]
5261)
5262
5263;; Splits for all extensions to DImode
5264(define_split
5265  [(set (match_operand:DI 0 "s_register_operand" "")
5266        (zero_extend:DI (match_operand 1 "nonimmediate_operand" "")))]
5267  "TARGET_32BIT && reload_completed && !IS_VFP_REGNUM (REGNO (operands[0]))"
5268  [(set (match_dup 0) (match_dup 1))]
5269{
5270  rtx lo_part = gen_lowpart (SImode, operands[0]);
5271  machine_mode src_mode = GET_MODE (operands[1]);
5272
5273  if (REG_P (operands[0])
5274      && !reg_overlap_mentioned_p (operands[0], operands[1]))
5275    emit_clobber (operands[0]);
5276  if (!REG_P (lo_part) || src_mode != SImode
5277      || !rtx_equal_p (lo_part, operands[1]))
5278    {
5279      if (src_mode == SImode)
5280        emit_move_insn (lo_part, operands[1]);
5281      else
5282        emit_insn (gen_rtx_SET (lo_part,
5283				gen_rtx_ZERO_EXTEND (SImode, operands[1])));
5284      operands[1] = lo_part;
5285    }
5286  operands[0] = gen_highpart (SImode, operands[0]);
5287  operands[1] = const0_rtx;
5288})
5289
5290(define_split
5291  [(set (match_operand:DI 0 "s_register_operand" "")
5292        (sign_extend:DI (match_operand 1 "nonimmediate_operand" "")))]
5293  "TARGET_32BIT && reload_completed && !IS_VFP_REGNUM (REGNO (operands[0]))"
5294  [(set (match_dup 0) (ashiftrt:SI (match_dup 1) (const_int 31)))]
5295{
5296  rtx lo_part = gen_lowpart (SImode, operands[0]);
5297  machine_mode src_mode = GET_MODE (operands[1]);
5298
5299  if (REG_P (operands[0])
5300      && !reg_overlap_mentioned_p (operands[0], operands[1]))
5301    emit_clobber (operands[0]);
5302
5303  if (!REG_P (lo_part) || src_mode != SImode
5304      || !rtx_equal_p (lo_part, operands[1]))
5305    {
5306      if (src_mode == SImode)
5307        emit_move_insn (lo_part, operands[1]);
5308      else
5309        emit_insn (gen_rtx_SET (lo_part,
5310				gen_rtx_SIGN_EXTEND (SImode, operands[1])));
5311      operands[1] = lo_part;
5312    }
5313  operands[0] = gen_highpart (SImode, operands[0]);
5314})
5315
5316(define_expand "zero_extendhisi2"
5317  [(set (match_operand:SI 0 "s_register_operand" "")
5318	(zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
5319  "TARGET_EITHER"
5320{
5321  if (TARGET_ARM && !arm_arch4 && MEM_P (operands[1]))
5322    {
5323      emit_insn (gen_movhi_bytes (operands[0], operands[1]));
5324      DONE;
5325    }
5326  if (!arm_arch6 && !MEM_P (operands[1]))
5327    {
5328      rtx t = gen_lowpart (SImode, operands[1]);
5329      rtx tmp = gen_reg_rtx (SImode);
5330      emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (16)));
5331      emit_insn (gen_lshrsi3 (operands[0], tmp, GEN_INT (16)));
5332      DONE;
5333    }
5334})
5335
5336(define_split
5337  [(set (match_operand:SI 0 "s_register_operand" "")
5338	(zero_extend:SI (match_operand:HI 1 "s_register_operand" "")))]
5339  "!TARGET_THUMB2 && !arm_arch6"
5340  [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
5341   (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 16)))]
5342{
5343  operands[2] = gen_lowpart (SImode, operands[1]);
5344})
5345
5346(define_insn "*arm_zero_extendhisi2"
5347  [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5348	(zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
5349  "TARGET_ARM && arm_arch4 && !arm_arch6"
5350  "@
5351   #
5352   ldrh%?\\t%0, %1"
5353  [(set_attr "type" "alu_shift_reg,load_byte")
5354   (set_attr "predicable" "yes")]
5355)
5356
5357(define_insn "*arm_zero_extendhisi2_v6"
5358  [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5359	(zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,Uh")))]
5360  "TARGET_ARM && arm_arch6"
5361  "@
5362   uxth%?\\t%0, %1
5363   ldrh%?\\t%0, %1"
5364  [(set_attr "predicable" "yes")
5365   (set_attr "type" "extend,load_byte")]
5366)
5367
5368(define_insn "*arm_zero_extendhisi2addsi"
5369  [(set (match_operand:SI 0 "s_register_operand" "=r")
5370	(plus:SI (zero_extend:SI (match_operand:HI 1 "s_register_operand" "r"))
5371		 (match_operand:SI 2 "s_register_operand" "r")))]
5372  "TARGET_INT_SIMD"
5373  "uxtah%?\\t%0, %2, %1"
5374  [(set_attr "type" "alu_shift_reg")
5375   (set_attr "predicable" "yes")]
5376)
5377
5378(define_expand "zero_extendqisi2"
5379  [(set (match_operand:SI 0 "s_register_operand" "")
5380	(zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))]
5381  "TARGET_EITHER"
5382{
5383  if (TARGET_ARM && !arm_arch6 && !MEM_P (operands[1]))
5384    {
5385      emit_insn (gen_andsi3 (operands[0],
5386			     gen_lowpart (SImode, operands[1]),
5387					  GEN_INT (255)));
5388      DONE;
5389    }
5390  if (!arm_arch6 && !MEM_P (operands[1]))
5391    {
5392      rtx t = gen_lowpart (SImode, operands[1]);
5393      rtx tmp = gen_reg_rtx (SImode);
5394      emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (24)));
5395      emit_insn (gen_lshrsi3 (operands[0], tmp, GEN_INT (24)));
5396      DONE;
5397    }
5398})
5399
5400(define_split
5401  [(set (match_operand:SI 0 "s_register_operand" "")
5402	(zero_extend:SI (match_operand:QI 1 "s_register_operand" "")))]
5403  "!arm_arch6"
5404  [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 24)))
5405   (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 24)))]
5406{
5407  operands[2] = simplify_gen_subreg (SImode, operands[1], QImode, 0);
5408  if (TARGET_ARM)
5409    {
5410      emit_insn (gen_andsi3 (operands[0], operands[2], GEN_INT (255)));
5411      DONE;
5412    }
5413})
5414
5415(define_insn "*arm_zero_extendqisi2"
5416  [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5417	(zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
5418  "TARGET_ARM && !arm_arch6"
5419  "@
5420   #
5421   ldrb%?\\t%0, %1\\t%@ zero_extendqisi2"
5422  [(set_attr "length" "8,4")
5423   (set_attr "type" "alu_shift_reg,load_byte")
5424   (set_attr "predicable" "yes")]
5425)
5426
5427(define_insn "*arm_zero_extendqisi2_v6"
5428  [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5429	(zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,Uh")))]
5430  "TARGET_ARM && arm_arch6"
5431  "@
5432   uxtb%?\\t%0, %1
5433   ldrb%?\\t%0, %1\\t%@ zero_extendqisi2"
5434  [(set_attr "type" "extend,load_byte")
5435   (set_attr "predicable" "yes")]
5436)
5437
5438(define_insn "*arm_zero_extendqisi2addsi"
5439  [(set (match_operand:SI 0 "s_register_operand" "=r")
5440	(plus:SI (zero_extend:SI (match_operand:QI 1 "s_register_operand" "r"))
5441		 (match_operand:SI 2 "s_register_operand" "r")))]
5442  "TARGET_INT_SIMD"
5443  "uxtab%?\\t%0, %2, %1"
5444  [(set_attr "predicable" "yes")
5445   (set_attr "type" "alu_shift_reg")]
5446)
5447
5448(define_split
5449  [(set (match_operand:SI 0 "s_register_operand" "")
5450	(zero_extend:SI (subreg:QI (match_operand:SI 1 "" "") 0)))
5451   (clobber (match_operand:SI 2 "s_register_operand" ""))]
5452  "TARGET_32BIT && (!MEM_P (operands[1])) && ! BYTES_BIG_ENDIAN"
5453  [(set (match_dup 2) (match_dup 1))
5454   (set (match_dup 0) (and:SI (match_dup 2) (const_int 255)))]
5455  ""
5456)
5457
5458(define_split
5459  [(set (match_operand:SI 0 "s_register_operand" "")
5460	(zero_extend:SI (subreg:QI (match_operand:SI 1 "" "") 3)))
5461   (clobber (match_operand:SI 2 "s_register_operand" ""))]
5462  "TARGET_32BIT && (!MEM_P (operands[1])) && BYTES_BIG_ENDIAN"
5463  [(set (match_dup 2) (match_dup 1))
5464   (set (match_dup 0) (and:SI (match_dup 2) (const_int 255)))]
5465  ""
5466)
5467
5468
5469(define_split
5470  [(set (match_operand:SI 0 "s_register_operand" "")
5471	(IOR_XOR:SI (and:SI (ashift:SI
5472			     (match_operand:SI 1 "s_register_operand" "")
5473			     (match_operand:SI 2 "const_int_operand" ""))
5474			    (match_operand:SI 3 "const_int_operand" ""))
5475		    (zero_extend:SI
5476		     (match_operator 5 "subreg_lowpart_operator"
5477		      [(match_operand:SI 4 "s_register_operand" "")]))))]
5478  "TARGET_32BIT
5479   && (UINTVAL (operands[3])
5480       == (GET_MODE_MASK (GET_MODE (operands[5]))
5481           & (GET_MODE_MASK (GET_MODE (operands[5]))
5482	      << (INTVAL (operands[2])))))"
5483  [(set (match_dup 0) (IOR_XOR:SI (ashift:SI (match_dup 1) (match_dup 2))
5484				  (match_dup 4)))
5485   (set (match_dup 0) (zero_extend:SI (match_dup 5)))]
5486  "operands[5] = gen_lowpart (GET_MODE (operands[5]), operands[0]);"
5487)
5488
5489(define_insn "*compareqi_eq0"
5490  [(set (reg:CC_Z CC_REGNUM)
5491	(compare:CC_Z (match_operand:QI 0 "s_register_operand" "r")
5492			 (const_int 0)))]
5493  "TARGET_32BIT"
5494  "tst%?\\t%0, #255"
5495  [(set_attr "conds" "set")
5496   (set_attr "predicable" "yes")
5497   (set_attr "type" "logic_imm")]
5498)
5499
5500(define_expand "extendhisi2"
5501  [(set (match_operand:SI 0 "s_register_operand" "")
5502	(sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
5503  "TARGET_EITHER"
5504{
5505  if (TARGET_THUMB1)
5506    {
5507      emit_insn (gen_thumb1_extendhisi2 (operands[0], operands[1]));
5508      DONE;
5509    }
5510  if (MEM_P (operands[1]) && TARGET_ARM && !arm_arch4)
5511    {
5512      emit_insn (gen_extendhisi2_mem (operands[0], operands[1]));
5513      DONE;
5514    }
5515
5516  if (!arm_arch6 && !MEM_P (operands[1]))
5517    {
5518      rtx t = gen_lowpart (SImode, operands[1]);
5519      rtx tmp = gen_reg_rtx (SImode);
5520      emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (16)));
5521      emit_insn (gen_ashrsi3 (operands[0], tmp, GEN_INT (16)));
5522      DONE;
5523    }
5524})
5525
5526(define_split
5527  [(parallel
5528    [(set (match_operand:SI 0 "register_operand" "")
5529	  (sign_extend:SI (match_operand:HI 1 "register_operand" "")))
5530     (clobber (match_scratch:SI 2 ""))])]
5531  "!arm_arch6"
5532  [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
5533   (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
5534{
5535  operands[2] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
5536})
5537
5538;; This pattern will only be used when ldsh is not available
5539(define_expand "extendhisi2_mem"
5540  [(set (match_dup 2) (zero_extend:SI (match_operand:HI 1 "" "")))
5541   (set (match_dup 3)
5542	(zero_extend:SI (match_dup 7)))
5543   (set (match_dup 6) (ashift:SI (match_dup 4) (const_int 24)))
5544   (set (match_operand:SI 0 "" "")
5545	(ior:SI (ashiftrt:SI (match_dup 6) (const_int 16)) (match_dup 5)))]
5546  "TARGET_ARM"
5547  "
5548  {
5549    rtx mem1, mem2;
5550    rtx addr = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
5551
5552    mem1 = change_address (operands[1], QImode, addr);
5553    mem2 = change_address (operands[1], QImode,
5554			   plus_constant (Pmode, addr, 1));
5555    operands[0] = gen_lowpart (SImode, operands[0]);
5556    operands[1] = mem1;
5557    operands[2] = gen_reg_rtx (SImode);
5558    operands[3] = gen_reg_rtx (SImode);
5559    operands[6] = gen_reg_rtx (SImode);
5560    operands[7] = mem2;
5561
5562    if (BYTES_BIG_ENDIAN)
5563      {
5564	operands[4] = operands[2];
5565	operands[5] = operands[3];
5566      }
5567    else
5568      {
5569	operands[4] = operands[3];
5570	operands[5] = operands[2];
5571      }
5572  }"
5573)
5574
5575(define_split
5576  [(set (match_operand:SI 0 "register_operand" "")
5577	(sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
5578  "!arm_arch6"
5579  [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
5580   (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
5581{
5582  operands[2] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
5583})
5584
5585(define_insn "*arm_extendhisi2"
5586  [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5587	(sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,Uh")))]
5588  "TARGET_ARM && arm_arch4 && !arm_arch6"
5589  "@
5590   #
5591   ldrsh%?\\t%0, %1"
5592  [(set_attr "length" "8,4")
5593   (set_attr "type" "alu_shift_reg,load_byte")
5594   (set_attr "predicable" "yes")]
5595)
5596
5597;; ??? Check Thumb-2 pool range
5598(define_insn "*arm_extendhisi2_v6"
5599  [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5600	(sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,Uh")))]
5601  "TARGET_32BIT && arm_arch6"
5602  "@
5603   sxth%?\\t%0, %1
5604   ldrsh%?\\t%0, %1"
5605  [(set_attr "type" "extend,load_byte")
5606   (set_attr "predicable" "yes")]
5607)
5608
5609(define_insn "*arm_extendhisi2addsi"
5610  [(set (match_operand:SI 0 "s_register_operand" "=r")
5611	(plus:SI (sign_extend:SI (match_operand:HI 1 "s_register_operand" "r"))
5612		 (match_operand:SI 2 "s_register_operand" "r")))]
5613  "TARGET_INT_SIMD"
5614  "sxtah%?\\t%0, %2, %1"
5615  [(set_attr "type" "alu_shift_reg")]
5616)
5617
5618(define_expand "extendqihi2"
5619  [(set (match_dup 2)
5620	(ashift:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "")
5621		   (const_int 24)))
5622   (set (match_operand:HI 0 "s_register_operand" "")
5623	(ashiftrt:SI (match_dup 2)
5624		     (const_int 24)))]
5625  "TARGET_ARM"
5626  "
5627  {
5628    if (arm_arch4 && MEM_P (operands[1]))
5629      {
5630	emit_insn (gen_rtx_SET (operands[0],
5631				gen_rtx_SIGN_EXTEND (HImode, operands[1])));
5632	DONE;
5633      }
5634    if (!s_register_operand (operands[1], QImode))
5635      operands[1] = copy_to_mode_reg (QImode, operands[1]);
5636    operands[0] = gen_lowpart (SImode, operands[0]);
5637    operands[1] = gen_lowpart (SImode, operands[1]);
5638    operands[2] = gen_reg_rtx (SImode);
5639  }"
5640)
5641
5642(define_insn "*arm_extendqihi_insn"
5643  [(set (match_operand:HI 0 "s_register_operand" "=r")
5644	(sign_extend:HI (match_operand:QI 1 "arm_extendqisi_mem_op" "Uq")))]
5645  "TARGET_ARM && arm_arch4"
5646  "ldrsb%?\\t%0, %1"
5647  [(set_attr "type" "load_byte")
5648   (set_attr "predicable" "yes")]
5649)
5650
5651(define_expand "extendqisi2"
5652  [(set (match_operand:SI 0 "s_register_operand" "")
5653	(sign_extend:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "")))]
5654  "TARGET_EITHER"
5655{
5656  if (!arm_arch4 && MEM_P (operands[1]))
5657    operands[1] = copy_to_mode_reg (QImode, operands[1]);
5658
5659  if (!arm_arch6 && !MEM_P (operands[1]))
5660    {
5661      rtx t = gen_lowpart (SImode, operands[1]);
5662      rtx tmp = gen_reg_rtx (SImode);
5663      emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (24)));
5664      emit_insn (gen_ashrsi3 (operands[0], tmp, GEN_INT (24)));
5665      DONE;
5666    }
5667})
5668
5669(define_split
5670  [(set (match_operand:SI 0 "register_operand" "")
5671	(sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
5672  "!arm_arch6"
5673  [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 24)))
5674   (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 24)))]
5675{
5676  operands[2] = simplify_gen_subreg (SImode, operands[1], QImode, 0);
5677})
5678
5679(define_insn "*arm_extendqisi"
5680  [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5681	(sign_extend:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "r,Uq")))]
5682  "TARGET_ARM && arm_arch4 && !arm_arch6"
5683  "@
5684   #
5685   ldrsb%?\\t%0, %1"
5686  [(set_attr "length" "8,4")
5687   (set_attr "type" "alu_shift_reg,load_byte")
5688   (set_attr "predicable" "yes")]
5689)
5690
5691(define_insn "*arm_extendqisi_v6"
5692  [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5693	(sign_extend:SI
5694	 (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "r,Uq")))]
5695  "TARGET_ARM && arm_arch6"
5696  "@
5697   sxtb%?\\t%0, %1
5698   ldrsb%?\\t%0, %1"
5699  [(set_attr "type" "extend,load_byte")
5700   (set_attr "predicable" "yes")]
5701)
5702
5703(define_insn "*arm_extendqisi2addsi"
5704  [(set (match_operand:SI 0 "s_register_operand" "=r")
5705	(plus:SI (sign_extend:SI (match_operand:QI 1 "s_register_operand" "r"))
5706		 (match_operand:SI 2 "s_register_operand" "r")))]
5707  "TARGET_INT_SIMD"
5708  "sxtab%?\\t%0, %2, %1"
5709  [(set_attr "type" "alu_shift_reg")
5710   (set_attr "predicable" "yes")]
5711)
5712
5713(define_expand "extendsfdf2"
5714  [(set (match_operand:DF                  0 "s_register_operand" "")
5715	(float_extend:DF (match_operand:SF 1 "s_register_operand"  "")))]
5716  "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
5717  ""
5718)
5719
5720;; HFmode -> DFmode conversions where we don't have an instruction for it
5721;; must go through SFmode.
5722;;
5723;; This is always safe for an extend.
5724
5725(define_expand "extendhfdf2"
5726  [(set (match_operand:DF		   0 "s_register_operand" "")
5727	(float_extend:DF (match_operand:HF 1 "s_register_operand" "")))]
5728  "TARGET_EITHER"
5729{
5730  /* We don't have a direct instruction for this, so go via SFmode.  */
5731  if (!(TARGET_32BIT && TARGET_FP16_TO_DOUBLE))
5732    {
5733      rtx op1;
5734      op1 = convert_to_mode (SFmode, operands[1], 0);
5735      op1 = convert_to_mode (DFmode, op1, 0);
5736      emit_insn (gen_movdf (operands[0], op1));
5737      DONE;
5738    }
5739  /* Otherwise, we're done producing RTL and will pick up the correct
5740     pattern to do this with one rounding-step in a single instruction.  */
5741}
5742)
5743
5744;; Move insns (including loads and stores)
5745
5746;; XXX Just some ideas about movti.
5747;; I don't think these are a good idea on the arm, there just aren't enough
5748;; registers
5749;;(define_expand "loadti"
5750;;  [(set (match_operand:TI 0 "s_register_operand" "")
5751;;	(mem:TI (match_operand:SI 1 "address_operand" "")))]
5752;;  "" "")
5753
5754;;(define_expand "storeti"
5755;;  [(set (mem:TI (match_operand:TI 0 "address_operand" ""))
5756;;	(match_operand:TI 1 "s_register_operand" ""))]
5757;;  "" "")
5758
5759;;(define_expand "movti"
5760;;  [(set (match_operand:TI 0 "general_operand" "")
5761;;	(match_operand:TI 1 "general_operand" ""))]
5762;;  ""
5763;;  "
5764;;{
5765;;  rtx insn;
5766;;
5767;;  if (MEM_P (operands[0]) && MEM_P (operands[1]))
5768;;    operands[1] = copy_to_reg (operands[1]);
5769;;  if (MEM_P (operands[0]))
5770;;    insn = gen_storeti (XEXP (operands[0], 0), operands[1]);
5771;;  else if (MEM_P (operands[1]))
5772;;    insn = gen_loadti (operands[0], XEXP (operands[1], 0));
5773;;  else
5774;;    FAIL;
5775;;
5776;;  emit_insn (insn);
5777;;  DONE;
5778;;}")
5779
5780;; Recognize garbage generated above.
5781
5782;;(define_insn ""
5783;;  [(set (match_operand:TI 0 "general_operand" "=r,r,r,<,>,m")
5784;;	(match_operand:TI 1 "general_operand" "<,>,m,r,r,r"))]
5785;;  ""
5786;;  "*
5787;;  {
5788;;    register mem = (which_alternative < 3);
5789;;    register const char *template;
5790;;
5791;;    operands[mem] = XEXP (operands[mem], 0);
5792;;    switch (which_alternative)
5793;;      {
5794;;      case 0: template = \"ldmdb\\t%1!, %M0\"; break;
5795;;      case 1: template = \"ldmia\\t%1!, %M0\"; break;
5796;;      case 2: template = \"ldmia\\t%1, %M0\"; break;
5797;;      case 3: template = \"stmdb\\t%0!, %M1\"; break;
5798;;      case 4: template = \"stmia\\t%0!, %M1\"; break;
5799;;      case 5: template = \"stmia\\t%0, %M1\"; break;
5800;;      }
5801;;    output_asm_insn (template, operands);
5802;;    return \"\";
5803;;  }")
5804
5805(define_expand "movdi"
5806  [(set (match_operand:DI 0 "general_operand" "")
5807	(match_operand:DI 1 "general_operand" ""))]
5808  "TARGET_EITHER"
5809  "
5810  if (can_create_pseudo_p ())
5811    {
5812      if (!REG_P (operands[0]))
5813	operands[1] = force_reg (DImode, operands[1]);
5814    }
5815  if (REG_P (operands[0]) && REGNO (operands[0]) <= LAST_ARM_REGNUM
5816      && !targetm.hard_regno_mode_ok (REGNO (operands[0]), DImode))
5817    {
5818      /* Avoid LDRD's into an odd-numbered register pair in ARM state
5819	 when expanding function calls.  */
5820      gcc_assert (can_create_pseudo_p ());
5821      if (MEM_P (operands[1]) && MEM_VOLATILE_P (operands[1]))
5822	{
5823	  /* Perform load into legal reg pair first, then move.  */
5824	  rtx reg = gen_reg_rtx (DImode);
5825	  emit_insn (gen_movdi (reg, operands[1]));
5826	  operands[1] = reg;
5827	}
5828      emit_move_insn (gen_lowpart (SImode, operands[0]),
5829		      gen_lowpart (SImode, operands[1]));
5830      emit_move_insn (gen_highpart (SImode, operands[0]),
5831		      gen_highpart (SImode, operands[1]));
5832      DONE;
5833    }
5834  else if (REG_P (operands[1]) && REGNO (operands[1]) <= LAST_ARM_REGNUM
5835	   && !targetm.hard_regno_mode_ok (REGNO (operands[1]), DImode))
5836    {
5837      /* Avoid STRD's from an odd-numbered register pair in ARM state
5838	 when expanding function prologue.  */
5839      gcc_assert (can_create_pseudo_p ());
5840      rtx split_dest = (MEM_P (operands[0]) && MEM_VOLATILE_P (operands[0]))
5841		       ? gen_reg_rtx (DImode)
5842		       : operands[0];
5843      emit_move_insn (gen_lowpart (SImode, split_dest),
5844		      gen_lowpart (SImode, operands[1]));
5845      emit_move_insn (gen_highpart (SImode, split_dest),
5846		      gen_highpart (SImode, operands[1]));
5847      if (split_dest != operands[0])
5848	emit_insn (gen_movdi (operands[0], split_dest));
5849      DONE;
5850    }
5851  "
5852)
5853
5854(define_insn "*arm_movdi"
5855  [(set (match_operand:DI 0 "nonimmediate_di_operand" "=r, r, r, r, m")
5856	(match_operand:DI 1 "di_operand"              "rDa,Db,Dc,mi,r"))]
5857  "TARGET_32BIT
5858   && !(TARGET_HARD_FLOAT)
5859   && !TARGET_IWMMXT
5860   && (   register_operand (operands[0], DImode)
5861       || register_operand (operands[1], DImode))"
5862  "*
5863  switch (which_alternative)
5864    {
5865    case 0:
5866    case 1:
5867    case 2:
5868      return \"#\";
5869    case 3:
5870      /* Cannot load it directly, split to load it via MOV / MOVT.  */
5871      if (!MEM_P (operands[1]) && arm_disable_literal_pool)
5872	return \"#\";
5873      /* Fall through.  */
5874    default:
5875      return output_move_double (operands, true, NULL);
5876    }
5877  "
5878  [(set_attr "length" "8,12,16,8,8")
5879   (set_attr "type" "multiple,multiple,multiple,load_8,store_8")
5880   (set_attr "arm_pool_range" "*,*,*,1020,*")
5881   (set_attr "arm_neg_pool_range" "*,*,*,1004,*")
5882   (set_attr "thumb2_pool_range" "*,*,*,4094,*")
5883   (set_attr "thumb2_neg_pool_range" "*,*,*,0,*")]
5884)
5885
5886(define_split
5887  [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
5888	(match_operand:ANY64 1 "immediate_operand" ""))]
5889  "TARGET_32BIT
5890   && reload_completed
5891   && (arm_disable_literal_pool
5892       || (arm_const_double_inline_cost (operands[1])
5893	   <= arm_max_const_double_inline_cost ()))"
5894  [(const_int 0)]
5895  "
5896  arm_split_constant (SET, SImode, curr_insn,
5897		      INTVAL (gen_lowpart (SImode, operands[1])),
5898		      gen_lowpart (SImode, operands[0]), NULL_RTX, 0);
5899  arm_split_constant (SET, SImode, curr_insn,
5900		      INTVAL (gen_highpart_mode (SImode,
5901						 GET_MODE (operands[0]),
5902						 operands[1])),
5903		      gen_highpart (SImode, operands[0]), NULL_RTX, 0);
5904  DONE;
5905  "
5906)
5907
5908; If optimizing for size, or if we have load delay slots, then
5909; we want to split the constant into two separate operations.
5910; In both cases this may split a trivial part into a single data op
5911; leaving a single complex constant to load.  We can also get longer
5912; offsets in a LDR which means we get better chances of sharing the pool
5913; entries.  Finally, we can normally do a better job of scheduling
5914; LDR instructions than we can with LDM.
5915; This pattern will only match if the one above did not.
5916(define_split
5917  [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
5918	(match_operand:ANY64 1 "const_double_operand" ""))]
5919  "TARGET_ARM && reload_completed
5920   && arm_const_double_by_parts (operands[1])"
5921  [(set (match_dup 0) (match_dup 1))
5922   (set (match_dup 2) (match_dup 3))]
5923  "
5924  operands[2] = gen_highpart (SImode, operands[0]);
5925  operands[3] = gen_highpart_mode (SImode, GET_MODE (operands[0]),
5926				   operands[1]);
5927  operands[0] = gen_lowpart (SImode, operands[0]);
5928  operands[1] = gen_lowpart (SImode, operands[1]);
5929  "
5930)
5931
5932(define_split
5933  [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
5934	(match_operand:ANY64 1 "arm_general_register_operand" ""))]
5935  "TARGET_EITHER && reload_completed"
5936  [(set (match_dup 0) (match_dup 1))
5937   (set (match_dup 2) (match_dup 3))]
5938  "
5939  operands[2] = gen_highpart (SImode, operands[0]);
5940  operands[3] = gen_highpart (SImode, operands[1]);
5941  operands[0] = gen_lowpart (SImode, operands[0]);
5942  operands[1] = gen_lowpart (SImode, operands[1]);
5943
5944  /* Handle a partial overlap.  */
5945  if (rtx_equal_p (operands[0], operands[3]))
5946    {
5947      rtx tmp0 = operands[0];
5948      rtx tmp1 = operands[1];
5949
5950      operands[0] = operands[2];
5951      operands[1] = operands[3];
5952      operands[2] = tmp0;
5953      operands[3] = tmp1;
5954    }
5955  "
5956)
5957
5958;; We can't actually do base+index doubleword loads if the index and
5959;; destination overlap.  Split here so that we at least have chance to
5960;; schedule.
5961(define_split
5962  [(set (match_operand:DI 0 "s_register_operand" "")
5963	(mem:DI (plus:SI (match_operand:SI 1 "s_register_operand" "")
5964			 (match_operand:SI 2 "s_register_operand" ""))))]
5965  "TARGET_LDRD
5966  && reg_overlap_mentioned_p (operands[0], operands[1])
5967  && reg_overlap_mentioned_p (operands[0], operands[2])"
5968  [(set (match_dup 4)
5969	(plus:SI (match_dup 1)
5970		 (match_dup 2)))
5971   (set (match_dup 0)
5972	(mem:DI (match_dup 4)))]
5973  "
5974  operands[4] = gen_rtx_REG (SImode, REGNO(operands[0]));
5975  "
5976)
5977
5978(define_expand "movsi"
5979  [(set (match_operand:SI 0 "general_operand" "")
5980        (match_operand:SI 1 "general_operand" ""))]
5981  "TARGET_EITHER"
5982  "
5983  {
5984  rtx base, offset, tmp;
5985
5986  if (TARGET_32BIT || TARGET_HAVE_MOVT)
5987    {
5988      /* Everything except mem = const or mem = mem can be done easily.  */
5989      if (MEM_P (operands[0]))
5990        operands[1] = force_reg (SImode, operands[1]);
5991      if (arm_general_register_operand (operands[0], SImode)
5992	  && CONST_INT_P (operands[1])
5993          && !(const_ok_for_arm (INTVAL (operands[1]))
5994               || const_ok_for_arm (~INTVAL (operands[1]))))
5995        {
5996	   if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[1]), SET))
5997	     {
5998		emit_insn (gen_rtx_SET (operands[0], operands[1]));
5999		DONE;
6000	     }
6001	  else
6002	     {
6003		arm_split_constant (SET, SImode, NULL_RTX,
6004	                            INTVAL (operands[1]), operands[0], NULL_RTX,
6005			            optimize && can_create_pseudo_p ());
6006		DONE;
6007	     }
6008        }
6009    }
6010  else /* Target doesn't have MOVT...  */
6011    {
6012      if (can_create_pseudo_p ())
6013        {
6014          if (!REG_P (operands[0]))
6015	    operands[1] = force_reg (SImode, operands[1]);
6016        }
6017    }
6018
6019  split_const (operands[1], &base, &offset);
6020  if (INTVAL (offset) != 0
6021      && targetm.cannot_force_const_mem (SImode, operands[1]))
6022    {
6023      tmp = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];
6024      emit_move_insn (tmp, base);
6025      emit_insn (gen_addsi3 (operands[0], tmp, offset));
6026      DONE;
6027    }
6028
6029  tmp = can_create_pseudo_p () ? NULL_RTX : operands[0];
6030
6031  /* Recognize the case where operand[1] is a reference to thread-local
6032     data and load its address to a register.  Offsets have been split off
6033     already.  */
6034  if (arm_tls_referenced_p (operands[1]))
6035    operands[1] = legitimize_tls_address (operands[1], tmp);
6036  else if (flag_pic
6037	   && (CONSTANT_P (operands[1])
6038	       || symbol_mentioned_p (operands[1])
6039	       || label_mentioned_p (operands[1])))
6040    operands[1] =
6041      legitimize_pic_address (operands[1], SImode, tmp, NULL_RTX, false);
6042  }
6043  "
6044)
6045
6046;; The ARM LO_SUM and HIGH are backwards - HIGH sets the low bits, and
6047;; LO_SUM adds in the high bits.  Fortunately these are opaque operations
6048;; so this does not matter.
6049(define_insn "*arm_movt"
6050  [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r")
6051	(lo_sum:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6052		   (match_operand:SI 2 "general_operand"      "i,i")))]
6053  "TARGET_HAVE_MOVT && arm_valid_symbolic_address_p (operands[2])"
6054  "@
6055   movt%?\t%0, #:upper16:%c2
6056   movt\t%0, #:upper16:%c2"
6057  [(set_attr "arch"  "32,v8mb")
6058   (set_attr "predicable" "yes")
6059   (set_attr "length" "4")
6060   (set_attr "type" "alu_sreg")]
6061)
6062
6063(define_insn "*arm_movsi_insn"
6064  [(set (match_operand:SI 0 "nonimmediate_operand" "=rk,r,r,r,rk,m")
6065	(match_operand:SI 1 "general_operand"      "rk, I,K,j,mi,rk"))]
6066  "TARGET_ARM && !TARGET_IWMMXT && !TARGET_HARD_FLOAT
6067   && (   register_operand (operands[0], SImode)
6068       || register_operand (operands[1], SImode))"
6069  "@
6070   mov%?\\t%0, %1
6071   mov%?\\t%0, %1
6072   mvn%?\\t%0, #%B1
6073   movw%?\\t%0, %1
6074   ldr%?\\t%0, %1
6075   str%?\\t%1, %0"
6076  [(set_attr "type" "mov_reg,mov_imm,mvn_imm,mov_imm,load_4,store_4")
6077   (set_attr "predicable" "yes")
6078   (set_attr "arch" "*,*,*,v6t2,*,*")
6079   (set_attr "pool_range" "*,*,*,*,4096,*")
6080   (set_attr "neg_pool_range" "*,*,*,*,4084,*")]
6081)
6082
6083(define_split
6084  [(set (match_operand:SI 0 "arm_general_register_operand" "")
6085	(match_operand:SI 1 "const_int_operand" ""))]
6086  "(TARGET_32BIT || TARGET_HAVE_MOVT)
6087  && (!(const_ok_for_arm (INTVAL (operands[1]))
6088        || const_ok_for_arm (~INTVAL (operands[1]))))"
6089  [(clobber (const_int 0))]
6090  "
6091  arm_split_constant (SET, SImode, NULL_RTX,
6092                      INTVAL (operands[1]), operands[0], NULL_RTX, 0);
6093  DONE;
6094  "
6095)
6096
6097;; A normal way to do (symbol + offset) requires three instructions at least
6098;; (depends on how big the offset is) as below:
6099;; movw r0, #:lower16:g
6100;; movw r0, #:upper16:g
6101;; adds r0, #4
6102;;
6103;; A better way would be:
6104;; movw r0, #:lower16:g+4
6105;; movw r0, #:upper16:g+4
6106;;
6107;; The limitation of this way is that the length of offset should be a 16-bit
6108;; signed value, because current assembler only supports REL type relocation for
6109;; such case.  If the more powerful RELA type is supported in future, we should
6110;; update this pattern to go with better way.
6111(define_split
6112  [(set (match_operand:SI 0 "arm_general_register_operand" "")
6113	(const:SI (plus:SI (match_operand:SI 1 "general_operand" "")
6114			   (match_operand:SI 2 "const_int_operand" ""))))]
6115  "TARGET_THUMB
6116   && TARGET_HAVE_MOVT
6117   && arm_disable_literal_pool
6118   && reload_completed
6119   && GET_CODE (operands[1]) == SYMBOL_REF"
6120  [(clobber (const_int 0))]
6121  "
6122    int offset = INTVAL (operands[2]);
6123
6124    if (offset < -0x8000 || offset > 0x7fff)
6125      {
6126	arm_emit_movpair (operands[0], operands[1]);
6127	emit_insn (gen_rtx_SET (operands[0],
6128				gen_rtx_PLUS (SImode, operands[0], operands[2])));
6129      }
6130    else
6131      {
6132	rtx op = gen_rtx_CONST (SImode,
6133				gen_rtx_PLUS (SImode, operands[1], operands[2]));
6134	arm_emit_movpair (operands[0], op);
6135      }
6136  "
6137)
6138
6139;; Split symbol_refs at the later stage (after cprop), instead of generating
6140;; movt/movw pair directly at expand.  Otherwise corresponding high_sum
6141;; and lo_sum would be merged back into memory load at cprop.  However,
6142;; if the default is to prefer movt/movw rather than a load from the constant
6143;; pool, the performance is better.
6144(define_split
6145  [(set (match_operand:SI 0 "arm_general_register_operand" "")
6146       (match_operand:SI 1 "general_operand" ""))]
6147  "TARGET_USE_MOVT && GET_CODE (operands[1]) == SYMBOL_REF
6148   && !target_word_relocations
6149   && !arm_tls_referenced_p (operands[1])"
6150  [(clobber (const_int 0))]
6151{
6152  arm_emit_movpair (operands[0], operands[1]);
6153  DONE;
6154})
6155
6156;; When generating pic, we need to load the symbol offset into a register.
6157;; So that the optimizer does not confuse this with a normal symbol load
6158;; we use an unspec.  The offset will be loaded from a constant pool entry,
6159;; since that is the only type of relocation we can use.
6160
6161;; Wrap calculation of the whole PIC address in a single pattern for the
6162;; benefit of optimizers, particularly, PRE and HOIST.  Calculation of
6163;; a PIC address involves two loads from memory, so we want to CSE it
6164;; as often as possible.
6165;; This pattern will be split into one of the pic_load_addr_* patterns
6166;; and a move after GCSE optimizations.
6167;;
6168;; Note: Update arm.c: legitimize_pic_address() when changing this pattern.
6169(define_expand "calculate_pic_address"
6170  [(set (match_operand:SI 0 "register_operand" "")
6171	(mem:SI (plus:SI (match_operand:SI 1 "register_operand" "")
6172			 (unspec:SI [(match_operand:SI 2 "" "")]
6173				    UNSPEC_PIC_SYM))))]
6174  "flag_pic"
6175)
6176
6177;; Split calculate_pic_address into pic_load_addr_* and a move.
6178(define_split
6179  [(set (match_operand:SI 0 "register_operand" "")
6180	(mem:SI (plus:SI (match_operand:SI 1 "register_operand" "")
6181			 (unspec:SI [(match_operand:SI 2 "" "")]
6182				    UNSPEC_PIC_SYM))))]
6183  "flag_pic"
6184  [(set (match_dup 3) (unspec:SI [(match_dup 2)] UNSPEC_PIC_SYM))
6185   (set (match_dup 0) (mem:SI (plus:SI (match_dup 1) (match_dup 3))))]
6186  "operands[3] = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];"
6187)
6188
6189;; operand1 is the memory address to go into
6190;; pic_load_addr_32bit.
6191;; operand2 is the PIC label to be emitted
6192;; from pic_add_dot_plus_eight.
6193;; We do this to allow hoisting of the entire insn.
6194(define_insn_and_split "pic_load_addr_unified"
6195  [(set (match_operand:SI 0 "s_register_operand" "=r,r,l")
6196	(unspec:SI [(match_operand:SI 1 "" "mX,mX,mX")
6197		    (match_operand:SI 2 "" "")]
6198		    UNSPEC_PIC_UNIFIED))]
6199 "flag_pic"
6200 "#"
6201 "&& reload_completed"
6202 [(set (match_dup 0) (unspec:SI [(match_dup 1)] UNSPEC_PIC_SYM))
6203  (set (match_dup 0) (unspec:SI [(match_dup 0) (match_dup 3)
6204       		     		 (match_dup 2)] UNSPEC_PIC_BASE))]
6205 "operands[3] = TARGET_THUMB ? GEN_INT (4) : GEN_INT (8);"
6206 [(set_attr "type" "load_4,load_4,load_4")
6207  (set_attr "pool_range" "4096,4094,1022")
6208  (set_attr "neg_pool_range" "4084,0,0")
6209  (set_attr "arch"  "a,t2,t1")
6210  (set_attr "length" "8,6,4")]
6211)
6212
6213;; The rather odd constraints on the following are to force reload to leave
6214;; the insn alone, and to force the minipool generation pass to then move
6215;; the GOT symbol to memory.
6216
6217(define_insn "pic_load_addr_32bit"
6218  [(set (match_operand:SI 0 "s_register_operand" "=r")
6219	(unspec:SI [(match_operand:SI 1 "" "mX")] UNSPEC_PIC_SYM))]
6220  "TARGET_32BIT && flag_pic"
6221  "ldr%?\\t%0, %1"
6222  [(set_attr "type" "load_4")
6223   (set (attr "pool_range")
6224	(if_then_else (eq_attr "is_thumb" "no")
6225		      (const_int 4096)
6226		      (const_int 4094)))
6227   (set (attr "neg_pool_range")
6228	(if_then_else (eq_attr "is_thumb" "no")
6229		      (const_int 4084)
6230		      (const_int 0)))]
6231)
6232
6233(define_insn "pic_load_addr_thumb1"
6234  [(set (match_operand:SI 0 "s_register_operand" "=l")
6235	(unspec:SI [(match_operand:SI 1 "" "mX")] UNSPEC_PIC_SYM))]
6236  "TARGET_THUMB1 && flag_pic"
6237  "ldr\\t%0, %1"
6238  [(set_attr "type" "load_4")
6239   (set (attr "pool_range") (const_int 1018))]
6240)
6241
6242(define_insn "pic_add_dot_plus_four"
6243  [(set (match_operand:SI 0 "register_operand" "=r")
6244	(unspec:SI [(match_operand:SI 1 "register_operand" "0")
6245		    (const_int 4)
6246		    (match_operand 2 "" "")]
6247		   UNSPEC_PIC_BASE))]
6248  "TARGET_THUMB"
6249  "*
6250  (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
6251				     INTVAL (operands[2]));
6252  return \"add\\t%0, %|pc\";
6253  "
6254  [(set_attr "length" "2")
6255   (set_attr "type" "alu_sreg")]
6256)
6257
6258(define_insn "pic_add_dot_plus_eight"
6259  [(set (match_operand:SI 0 "register_operand" "=r")
6260	(unspec:SI [(match_operand:SI 1 "register_operand" "r")
6261		    (const_int 8)
6262		    (match_operand 2 "" "")]
6263		   UNSPEC_PIC_BASE))]
6264  "TARGET_ARM"
6265  "*
6266    (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
6267				       INTVAL (operands[2]));
6268    return \"add%?\\t%0, %|pc, %1\";
6269  "
6270  [(set_attr "predicable" "yes")
6271   (set_attr "type" "alu_sreg")]
6272)
6273
6274(define_insn "tls_load_dot_plus_eight"
6275  [(set (match_operand:SI 0 "register_operand" "=r")
6276	(mem:SI (unspec:SI [(match_operand:SI 1 "register_operand" "r")
6277			    (const_int 8)
6278			    (match_operand 2 "" "")]
6279			   UNSPEC_PIC_BASE)))]
6280  "TARGET_ARM"
6281  "*
6282    (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
6283				       INTVAL (operands[2]));
6284    return \"ldr%?\\t%0, [%|pc, %1]\t\t@ tls_load_dot_plus_eight\";
6285  "
6286  [(set_attr "predicable" "yes")
6287   (set_attr "type" "load_4")]
6288)
6289
6290;; PIC references to local variables can generate pic_add_dot_plus_eight
6291;; followed by a load.  These sequences can be crunched down to
6292;; tls_load_dot_plus_eight by a peephole.
6293
6294(define_peephole2
6295  [(set (match_operand:SI 0 "register_operand" "")
6296	(unspec:SI [(match_operand:SI 3 "register_operand" "")
6297		    (const_int 8)
6298		    (match_operand 1 "" "")]
6299		   UNSPEC_PIC_BASE))
6300   (set (match_operand:SI 2 "arm_general_register_operand" "")
6301	(mem:SI (match_dup 0)))]
6302  "TARGET_ARM && peep2_reg_dead_p (2, operands[0])"
6303  [(set (match_dup 2)
6304	(mem:SI (unspec:SI [(match_dup 3)
6305			    (const_int 8)
6306			    (match_dup 1)]
6307			   UNSPEC_PIC_BASE)))]
6308  ""
6309)
6310
6311(define_insn "pic_offset_arm"
6312  [(set (match_operand:SI 0 "register_operand" "=r")
6313	(mem:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
6314			 (unspec:SI [(match_operand:SI 2 "" "X")]
6315				    UNSPEC_PIC_OFFSET))))]
6316  "TARGET_VXWORKS_RTP && TARGET_ARM && flag_pic"
6317  "ldr%?\\t%0, [%1,%2]"
6318  [(set_attr "type" "load_4")]
6319)
6320
6321(define_expand "builtin_setjmp_receiver"
6322  [(label_ref (match_operand 0 "" ""))]
6323  "flag_pic"
6324  "
6325{
6326  /* r3 is clobbered by set/longjmp, so we can use it as a scratch
6327     register.  */
6328  if (arm_pic_register != INVALID_REGNUM)
6329    arm_load_pic_register (1UL << 3, NULL_RTX);
6330  DONE;
6331}")
6332
6333;; If copying one reg to another we can set the condition codes according to
6334;; its value.  Such a move is common after a return from subroutine and the
6335;; result is being tested against zero.
6336
6337(define_insn "*movsi_compare0"
6338  [(set (reg:CC CC_REGNUM)
6339	(compare:CC (match_operand:SI 1 "s_register_operand" "0,r")
6340		    (const_int 0)))
6341   (set (match_operand:SI 0 "s_register_operand" "=r,r")
6342	(match_dup 1))]
6343  "TARGET_32BIT"
6344  "@
6345   cmp%?\\t%0, #0
6346   subs%?\\t%0, %1, #0"
6347  [(set_attr "conds" "set")
6348   (set_attr "type" "alus_imm,alus_imm")]
6349)
6350
6351;; Subroutine to store a half word from a register into memory.
6352;; Operand 0 is the source register (HImode)
6353;; Operand 1 is the destination address in a register (SImode)
6354
6355;; In both this routine and the next, we must be careful not to spill
6356;; a memory address of reg+large_const into a separate PLUS insn, since this
6357;; can generate unrecognizable rtl.
6358
6359(define_expand "storehi"
6360  [;; store the low byte
6361   (set (match_operand 1 "" "") (match_dup 3))
6362   ;; extract the high byte
6363   (set (match_dup 2)
6364	(ashiftrt:SI (match_operand 0 "" "") (const_int 8)))
6365   ;; store the high byte
6366   (set (match_dup 4) (match_dup 5))]
6367  "TARGET_ARM"
6368  "
6369  {
6370    rtx op1 = operands[1];
6371    rtx addr = XEXP (op1, 0);
6372    enum rtx_code code = GET_CODE (addr);
6373
6374    if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1)))
6375	|| code == MINUS)
6376      op1 = replace_equiv_address (operands[1], force_reg (SImode, addr));
6377
6378    operands[4] = adjust_address (op1, QImode, 1);
6379    operands[1] = adjust_address (operands[1], QImode, 0);
6380    operands[3] = gen_lowpart (QImode, operands[0]);
6381    operands[0] = gen_lowpart (SImode, operands[0]);
6382    operands[2] = gen_reg_rtx (SImode);
6383    operands[5] = gen_lowpart (QImode, operands[2]);
6384  }"
6385)
6386
6387(define_expand "storehi_bigend"
6388  [(set (match_dup 4) (match_dup 3))
6389   (set (match_dup 2)
6390	(ashiftrt:SI (match_operand 0 "" "") (const_int 8)))
6391   (set (match_operand 1 "" "")	(match_dup 5))]
6392  "TARGET_ARM"
6393  "
6394  {
6395    rtx op1 = operands[1];
6396    rtx addr = XEXP (op1, 0);
6397    enum rtx_code code = GET_CODE (addr);
6398
6399    if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1)))
6400	|| code == MINUS)
6401      op1 = replace_equiv_address (op1, force_reg (SImode, addr));
6402
6403    operands[4] = adjust_address (op1, QImode, 1);
6404    operands[1] = adjust_address (operands[1], QImode, 0);
6405    operands[3] = gen_lowpart (QImode, operands[0]);
6406    operands[0] = gen_lowpart (SImode, operands[0]);
6407    operands[2] = gen_reg_rtx (SImode);
6408    operands[5] = gen_lowpart (QImode, operands[2]);
6409  }"
6410)
6411
6412;; Subroutine to store a half word integer constant into memory.
6413(define_expand "storeinthi"
6414  [(set (match_operand 0 "" "")
6415	(match_operand 1 "" ""))
6416   (set (match_dup 3) (match_dup 2))]
6417  "TARGET_ARM"
6418  "
6419  {
6420    HOST_WIDE_INT value = INTVAL (operands[1]);
6421    rtx addr = XEXP (operands[0], 0);
6422    rtx op0 = operands[0];
6423    enum rtx_code code = GET_CODE (addr);
6424
6425    if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1)))
6426	|| code == MINUS)
6427      op0 = replace_equiv_address (op0, force_reg (SImode, addr));
6428
6429    operands[1] = gen_reg_rtx (SImode);
6430    if (BYTES_BIG_ENDIAN)
6431      {
6432	emit_insn (gen_movsi (operands[1], GEN_INT ((value >> 8) & 255)));
6433	if ((value & 255) == ((value >> 8) & 255))
6434	  operands[2] = operands[1];
6435	else
6436	  {
6437	    operands[2] = gen_reg_rtx (SImode);
6438	    emit_insn (gen_movsi (operands[2], GEN_INT (value & 255)));
6439	  }
6440      }
6441    else
6442      {
6443	emit_insn (gen_movsi (operands[1], GEN_INT (value & 255)));
6444	if ((value & 255) == ((value >> 8) & 255))
6445	  operands[2] = operands[1];
6446	else
6447	  {
6448	    operands[2] = gen_reg_rtx (SImode);
6449	    emit_insn (gen_movsi (operands[2], GEN_INT ((value >> 8) & 255)));
6450	  }
6451      }
6452
6453    operands[3] = adjust_address (op0, QImode, 1);
6454    operands[0] = adjust_address (operands[0], QImode, 0);
6455    operands[2] = gen_lowpart (QImode, operands[2]);
6456    operands[1] = gen_lowpart (QImode, operands[1]);
6457  }"
6458)
6459
6460(define_expand "storehi_single_op"
6461  [(set (match_operand:HI 0 "memory_operand" "")
6462	(match_operand:HI 1 "general_operand" ""))]
6463  "TARGET_32BIT && arm_arch4"
6464  "
6465  if (!s_register_operand (operands[1], HImode))
6466    operands[1] = copy_to_mode_reg (HImode, operands[1]);
6467  "
6468)
6469
6470(define_expand "movhi"
6471  [(set (match_operand:HI 0 "general_operand" "")
6472	(match_operand:HI 1 "general_operand" ""))]
6473  "TARGET_EITHER"
6474  "
6475  if (TARGET_ARM)
6476    {
6477      if (can_create_pseudo_p ())
6478        {
6479          if (MEM_P (operands[0]))
6480	    {
6481	      if (arm_arch4)
6482	        {
6483	          emit_insn (gen_storehi_single_op (operands[0], operands[1]));
6484	          DONE;
6485	        }
6486	      if (CONST_INT_P (operands[1]))
6487	        emit_insn (gen_storeinthi (operands[0], operands[1]));
6488	      else
6489	        {
6490	          if (MEM_P (operands[1]))
6491		    operands[1] = force_reg (HImode, operands[1]);
6492	          if (BYTES_BIG_ENDIAN)
6493		    emit_insn (gen_storehi_bigend (operands[1], operands[0]));
6494	          else
6495		   emit_insn (gen_storehi (operands[1], operands[0]));
6496	        }
6497	      DONE;
6498	    }
6499          /* Sign extend a constant, and keep it in an SImode reg.  */
6500          else if (CONST_INT_P (operands[1]))
6501	    {
6502	      rtx reg = gen_reg_rtx (SImode);
6503	      HOST_WIDE_INT val = INTVAL (operands[1]) & 0xffff;
6504
6505	      /* If the constant is already valid, leave it alone.  */
6506	      if (!const_ok_for_arm (val))
6507	        {
6508	          /* If setting all the top bits will make the constant
6509		     loadable in a single instruction, then set them.
6510		     Otherwise, sign extend the number.  */
6511
6512	          if (const_ok_for_arm (~(val | ~0xffff)))
6513		    val |= ~0xffff;
6514	          else if (val & 0x8000)
6515		    val |= ~0xffff;
6516	        }
6517
6518	      emit_insn (gen_movsi (reg, GEN_INT (val)));
6519	      operands[1] = gen_lowpart (HImode, reg);
6520	    }
6521	  else if (arm_arch4 && optimize && can_create_pseudo_p ()
6522		   && MEM_P (operands[1]))
6523	    {
6524	      rtx reg = gen_reg_rtx (SImode);
6525
6526	      emit_insn (gen_zero_extendhisi2 (reg, operands[1]));
6527	      operands[1] = gen_lowpart (HImode, reg);
6528	    }
6529          else if (!arm_arch4)
6530	    {
6531	      if (MEM_P (operands[1]))
6532	        {
6533		  rtx base;
6534		  rtx offset = const0_rtx;
6535		  rtx reg = gen_reg_rtx (SImode);
6536
6537		  if ((REG_P (base = XEXP (operands[1], 0))
6538		       || (GET_CODE (base) == PLUS
6539			   && (CONST_INT_P (offset = XEXP (base, 1)))
6540                           && ((INTVAL(offset) & 1) != 1)
6541			   && REG_P (base = XEXP (base, 0))))
6542		      && REGNO_POINTER_ALIGN (REGNO (base)) >= 32)
6543		    {
6544		      rtx new_rtx;
6545
6546		      new_rtx = widen_memory_access (operands[1], SImode,
6547						     ((INTVAL (offset) & ~3)
6548						      - INTVAL (offset)));
6549		      emit_insn (gen_movsi (reg, new_rtx));
6550		      if (((INTVAL (offset) & 2) != 0)
6551			  ^ (BYTES_BIG_ENDIAN ? 1 : 0))
6552			{
6553			  rtx reg2 = gen_reg_rtx (SImode);
6554
6555			  emit_insn (gen_lshrsi3 (reg2, reg, GEN_INT (16)));
6556			  reg = reg2;
6557			}
6558		    }
6559		  else
6560		    emit_insn (gen_movhi_bytes (reg, operands[1]));
6561
6562		  operands[1] = gen_lowpart (HImode, reg);
6563	       }
6564	   }
6565        }
6566      /* Handle loading a large integer during reload.  */
6567      else if (CONST_INT_P (operands[1])
6568	       && !const_ok_for_arm (INTVAL (operands[1]))
6569	       && !const_ok_for_arm (~INTVAL (operands[1])))
6570        {
6571          /* Writing a constant to memory needs a scratch, which should
6572	     be handled with SECONDARY_RELOADs.  */
6573          gcc_assert (REG_P (operands[0]));
6574
6575          operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
6576          emit_insn (gen_movsi (operands[0], operands[1]));
6577          DONE;
6578       }
6579    }
6580  else if (TARGET_THUMB2)
6581    {
6582      /* Thumb-2 can do everything except mem=mem and mem=const easily.  */
6583      if (can_create_pseudo_p ())
6584	{
6585	  if (!REG_P (operands[0]))
6586	    operands[1] = force_reg (HImode, operands[1]);
6587          /* Zero extend a constant, and keep it in an SImode reg.  */
6588          else if (CONST_INT_P (operands[1]))
6589	    {
6590	      rtx reg = gen_reg_rtx (SImode);
6591	      HOST_WIDE_INT val = INTVAL (operands[1]) & 0xffff;
6592
6593	      emit_insn (gen_movsi (reg, GEN_INT (val)));
6594	      operands[1] = gen_lowpart (HImode, reg);
6595	    }
6596	}
6597    }
6598  else /* TARGET_THUMB1 */
6599    {
6600      if (can_create_pseudo_p ())
6601        {
6602	  if (CONST_INT_P (operands[1]))
6603	    {
6604	      rtx reg = gen_reg_rtx (SImode);
6605
6606	      emit_insn (gen_movsi (reg, operands[1]));
6607	      operands[1] = gen_lowpart (HImode, reg);
6608	    }
6609
6610          /* ??? We shouldn't really get invalid addresses here, but this can
6611	     happen if we are passed a SP (never OK for HImode/QImode) or
6612	     virtual register (also rejected as illegitimate for HImode/QImode)
6613	     relative address.  */
6614          /* ??? This should perhaps be fixed elsewhere, for instance, in
6615	     fixup_stack_1, by checking for other kinds of invalid addresses,
6616	     e.g. a bare reference to a virtual register.  This may confuse the
6617	     alpha though, which must handle this case differently.  */
6618          if (MEM_P (operands[0])
6619	      && !memory_address_p (GET_MODE (operands[0]),
6620				    XEXP (operands[0], 0)))
6621	    operands[0]
6622	      = replace_equiv_address (operands[0],
6623				       copy_to_reg (XEXP (operands[0], 0)));
6624
6625          if (MEM_P (operands[1])
6626	      && !memory_address_p (GET_MODE (operands[1]),
6627				    XEXP (operands[1], 0)))
6628	    operands[1]
6629	      = replace_equiv_address (operands[1],
6630				       copy_to_reg (XEXP (operands[1], 0)));
6631
6632	  if (MEM_P (operands[1]) && optimize > 0)
6633	    {
6634	      rtx reg = gen_reg_rtx (SImode);
6635
6636	      emit_insn (gen_zero_extendhisi2 (reg, operands[1]));
6637	      operands[1] = gen_lowpart (HImode, reg);
6638	    }
6639
6640          if (MEM_P (operands[0]))
6641	    operands[1] = force_reg (HImode, operands[1]);
6642        }
6643      else if (CONST_INT_P (operands[1])
6644	        && !satisfies_constraint_I (operands[1]))
6645        {
6646	  /* Handle loading a large integer during reload.  */
6647
6648          /* Writing a constant to memory needs a scratch, which should
6649	     be handled with SECONDARY_RELOADs.  */
6650          gcc_assert (REG_P (operands[0]));
6651
6652          operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
6653          emit_insn (gen_movsi (operands[0], operands[1]));
6654          DONE;
6655        }
6656    }
6657  "
6658)
6659
6660(define_expand "movhi_bytes"
6661  [(set (match_dup 2) (zero_extend:SI (match_operand:HI 1 "" "")))
6662   (set (match_dup 3)
6663	(zero_extend:SI (match_dup 6)))
6664   (set (match_operand:SI 0 "" "")
6665	 (ior:SI (ashift:SI (match_dup 4) (const_int 8)) (match_dup 5)))]
6666  "TARGET_ARM"
6667  "
6668  {
6669    rtx mem1, mem2;
6670    rtx addr = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
6671
6672    mem1 = change_address (operands[1], QImode, addr);
6673    mem2 = change_address (operands[1], QImode,
6674			   plus_constant (Pmode, addr, 1));
6675    operands[0] = gen_lowpart (SImode, operands[0]);
6676    operands[1] = mem1;
6677    operands[2] = gen_reg_rtx (SImode);
6678    operands[3] = gen_reg_rtx (SImode);
6679    operands[6] = mem2;
6680
6681    if (BYTES_BIG_ENDIAN)
6682      {
6683	operands[4] = operands[2];
6684	operands[5] = operands[3];
6685      }
6686    else
6687      {
6688	operands[4] = operands[3];
6689	operands[5] = operands[2];
6690      }
6691  }"
6692)
6693
6694(define_expand "movhi_bigend"
6695  [(set (match_dup 2)
6696	(rotate:SI (subreg:SI (match_operand:HI 1 "memory_operand" "") 0)
6697		   (const_int 16)))
6698   (set (match_dup 3)
6699	(ashiftrt:SI (match_dup 2) (const_int 16)))
6700   (set (match_operand:HI 0 "s_register_operand" "")
6701	(match_dup 4))]
6702  "TARGET_ARM"
6703  "
6704  operands[2] = gen_reg_rtx (SImode);
6705  operands[3] = gen_reg_rtx (SImode);
6706  operands[4] = gen_lowpart (HImode, operands[3]);
6707  "
6708)
6709
6710;; Pattern to recognize insn generated default case above
6711(define_insn "*movhi_insn_arch4"
6712  [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m,r")
6713	(match_operand:HI 1 "general_operand"      "rIk,K,n,r,mi"))]
6714  "TARGET_ARM
6715   && arm_arch4 && !TARGET_HARD_FLOAT
6716   && (register_operand (operands[0], HImode)
6717       || register_operand (operands[1], HImode))"
6718  "@
6719   mov%?\\t%0, %1\\t%@ movhi
6720   mvn%?\\t%0, #%B1\\t%@ movhi
6721   movw%?\\t%0, %L1\\t%@ movhi
6722   strh%?\\t%1, %0\\t%@ movhi
6723   ldrh%?\\t%0, %1\\t%@ movhi"
6724  [(set_attr "predicable" "yes")
6725   (set_attr "pool_range" "*,*,*,*,256")
6726   (set_attr "neg_pool_range" "*,*,*,*,244")
6727   (set_attr "arch" "*,*,v6t2,*,*")
6728   (set_attr_alternative "type"
6729                         [(if_then_else (match_operand 1 "const_int_operand" "")
6730                                        (const_string "mov_imm" )
6731                                        (const_string "mov_reg"))
6732                          (const_string "mvn_imm")
6733                          (const_string "mov_imm")
6734                          (const_string "store_4")
6735                          (const_string "load_4")])]
6736)
6737
6738(define_insn "*movhi_bytes"
6739  [(set (match_operand:HI 0 "s_register_operand" "=r,r,r")
6740	(match_operand:HI 1 "arm_rhs_operand"  "I,rk,K"))]
6741  "TARGET_ARM && !TARGET_HARD_FLOAT"
6742  "@
6743   mov%?\\t%0, %1\\t%@ movhi
6744   mov%?\\t%0, %1\\t%@ movhi
6745   mvn%?\\t%0, #%B1\\t%@ movhi"
6746  [(set_attr "predicable" "yes")
6747   (set_attr "type" "mov_imm,mov_reg,mvn_imm")]
6748)
6749
6750;; We use a DImode scratch because we may occasionally need an additional
6751;; temporary if the address isn't offsettable -- push_reload doesn't seem
6752;; to take any notice of the "o" constraints on reload_memory_operand operand.
6753(define_expand "reload_outhi"
6754  [(parallel [(match_operand:HI 0 "arm_reload_memory_operand" "=o")
6755	      (match_operand:HI 1 "s_register_operand"        "r")
6756	      (match_operand:DI 2 "s_register_operand"        "=&l")])]
6757  "TARGET_EITHER"
6758  "if (TARGET_ARM)
6759     arm_reload_out_hi (operands);
6760   else
6761     thumb_reload_out_hi (operands);
6762  DONE;
6763  "
6764)
6765
6766(define_expand "reload_inhi"
6767  [(parallel [(match_operand:HI 0 "s_register_operand" "=r")
6768	      (match_operand:HI 1 "arm_reload_memory_operand" "o")
6769	      (match_operand:DI 2 "s_register_operand" "=&r")])]
6770  "TARGET_EITHER"
6771  "
6772  if (TARGET_ARM)
6773    arm_reload_in_hi (operands);
6774  else
6775    thumb_reload_out_hi (operands);
6776  DONE;
6777")
6778
6779(define_expand "movqi"
6780  [(set (match_operand:QI 0 "general_operand" "")
6781        (match_operand:QI 1 "general_operand" ""))]
6782  "TARGET_EITHER"
6783  "
6784  /* Everything except mem = const or mem = mem can be done easily */
6785
6786  if (can_create_pseudo_p ())
6787    {
6788      if (CONST_INT_P (operands[1]))
6789	{
6790	  rtx reg = gen_reg_rtx (SImode);
6791
6792	  /* For thumb we want an unsigned immediate, then we are more likely
6793	     to be able to use a movs insn.  */
6794	  if (TARGET_THUMB)
6795	    operands[1] = GEN_INT (INTVAL (operands[1]) & 255);
6796
6797	  emit_insn (gen_movsi (reg, operands[1]));
6798	  operands[1] = gen_lowpart (QImode, reg);
6799	}
6800
6801      if (TARGET_THUMB)
6802	{
6803          /* ??? We shouldn't really get invalid addresses here, but this can
6804	     happen if we are passed a SP (never OK for HImode/QImode) or
6805	     virtual register (also rejected as illegitimate for HImode/QImode)
6806	     relative address.  */
6807          /* ??? This should perhaps be fixed elsewhere, for instance, in
6808	     fixup_stack_1, by checking for other kinds of invalid addresses,
6809	     e.g. a bare reference to a virtual register.  This may confuse the
6810	     alpha though, which must handle this case differently.  */
6811          if (MEM_P (operands[0])
6812	      && !memory_address_p (GET_MODE (operands[0]),
6813		  		     XEXP (operands[0], 0)))
6814	    operands[0]
6815	      = replace_equiv_address (operands[0],
6816				       copy_to_reg (XEXP (operands[0], 0)));
6817          if (MEM_P (operands[1])
6818	      && !memory_address_p (GET_MODE (operands[1]),
6819				    XEXP (operands[1], 0)))
6820	     operands[1]
6821	       = replace_equiv_address (operands[1],
6822					copy_to_reg (XEXP (operands[1], 0)));
6823	}
6824
6825      if (MEM_P (operands[1]) && optimize > 0)
6826	{
6827	  rtx reg = gen_reg_rtx (SImode);
6828
6829	  emit_insn (gen_zero_extendqisi2 (reg, operands[1]));
6830	  operands[1] = gen_lowpart (QImode, reg);
6831	}
6832
6833      if (MEM_P (operands[0]))
6834	operands[1] = force_reg (QImode, operands[1]);
6835    }
6836  else if (TARGET_THUMB
6837	   && CONST_INT_P (operands[1])
6838	   && !satisfies_constraint_I (operands[1]))
6839    {
6840      /* Handle loading a large integer during reload.  */
6841
6842      /* Writing a constant to memory needs a scratch, which should
6843	 be handled with SECONDARY_RELOADs.  */
6844      gcc_assert (REG_P (operands[0]));
6845
6846      operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
6847      emit_insn (gen_movsi (operands[0], operands[1]));
6848      DONE;
6849    }
6850  "
6851)
6852
6853(define_insn "*arm_movqi_insn"
6854  [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,r,l,r,l,Uu,r,m")
6855	(match_operand:QI 1 "general_operand" "rk,rk,I,Py,K,Uu,l,Uh,r"))]
6856  "TARGET_32BIT
6857   && (   register_operand (operands[0], QImode)
6858       || register_operand (operands[1], QImode))"
6859  "@
6860   mov%?\\t%0, %1
6861   mov%?\\t%0, %1
6862   mov%?\\t%0, %1
6863   mov%?\\t%0, %1
6864   mvn%?\\t%0, #%B1
6865   ldrb%?\\t%0, %1
6866   strb%?\\t%1, %0
6867   ldrb%?\\t%0, %1
6868   strb%?\\t%1, %0"
6869  [(set_attr "type" "mov_reg,mov_reg,mov_imm,mov_imm,mvn_imm,load_4,store_4,load_4,store_4")
6870   (set_attr "predicable" "yes")
6871   (set_attr "predicable_short_it" "yes,yes,no,yes,no,no,no,no,no")
6872   (set_attr "arch" "t2,any,any,t2,any,t2,t2,any,any")
6873   (set_attr "length" "2,4,4,2,4,2,2,4,4")]
6874)
6875
6876;; HFmode moves
6877(define_expand "movhf"
6878  [(set (match_operand:HF 0 "general_operand" "")
6879	(match_operand:HF 1 "general_operand" ""))]
6880  "TARGET_EITHER"
6881  "
6882  if (TARGET_32BIT)
6883    {
6884      if (MEM_P (operands[0]))
6885        operands[1] = force_reg (HFmode, operands[1]);
6886    }
6887  else /* TARGET_THUMB1 */
6888    {
6889      if (can_create_pseudo_p ())
6890        {
6891           if (!REG_P (operands[0]))
6892	     operands[1] = force_reg (HFmode, operands[1]);
6893        }
6894    }
6895  "
6896)
6897
6898(define_insn "*arm32_movhf"
6899  [(set (match_operand:HF 0 "nonimmediate_operand" "=r,m,r,r")
6900	(match_operand:HF 1 "general_operand"	   " m,r,r,F"))]
6901  "TARGET_32BIT && !TARGET_HARD_FLOAT
6902   && (	  s_register_operand (operands[0], HFmode)
6903       || s_register_operand (operands[1], HFmode))"
6904  "*
6905  switch (which_alternative)
6906    {
6907    case 0:	/* ARM register from memory */
6908      return \"ldrh%?\\t%0, %1\\t%@ __fp16\";
6909    case 1:	/* memory from ARM register */
6910      return \"strh%?\\t%1, %0\\t%@ __fp16\";
6911    case 2:	/* ARM register from ARM register */
6912      return \"mov%?\\t%0, %1\\t%@ __fp16\";
6913    case 3:	/* ARM register from constant */
6914      {
6915	long bits;
6916	rtx ops[4];
6917
6918	bits = real_to_target (NULL, CONST_DOUBLE_REAL_VALUE (operands[1]),
6919			       HFmode);
6920	ops[0] = operands[0];
6921	ops[1] = GEN_INT (bits);
6922	ops[2] = GEN_INT (bits & 0xff00);
6923	ops[3] = GEN_INT (bits & 0x00ff);
6924
6925	if (arm_arch_thumb2)
6926	  output_asm_insn (\"movw%?\\t%0, %1\", ops);
6927	else
6928	  output_asm_insn (\"mov%?\\t%0, %2\;orr%?\\t%0, %0, %3\", ops);
6929	return \"\";
6930       }
6931    default:
6932      gcc_unreachable ();
6933    }
6934  "
6935  [(set_attr "conds" "unconditional")
6936   (set_attr "type" "load_4,store_4,mov_reg,multiple")
6937   (set_attr "length" "4,4,4,8")
6938   (set_attr "predicable" "yes")]
6939)
6940
6941(define_expand "movsf"
6942  [(set (match_operand:SF 0 "general_operand" "")
6943	(match_operand:SF 1 "general_operand" ""))]
6944  "TARGET_EITHER"
6945  "
6946  if (TARGET_32BIT)
6947    {
6948      if (MEM_P (operands[0]))
6949        operands[1] = force_reg (SFmode, operands[1]);
6950    }
6951  else /* TARGET_THUMB1 */
6952    {
6953      if (can_create_pseudo_p ())
6954        {
6955           if (!REG_P (operands[0]))
6956	     operands[1] = force_reg (SFmode, operands[1]);
6957        }
6958    }
6959
6960  /* Cannot load it directly, generate a load with clobber so that it can be
6961     loaded via GPR with MOV / MOVT.  */
6962  if (arm_disable_literal_pool
6963      && (REG_P (operands[0]) || SUBREG_P (operands[0]))
6964      && CONST_DOUBLE_P (operands[1])
6965      && TARGET_HARD_FLOAT
6966      && !vfp3_const_double_rtx (operands[1]))
6967    {
6968      rtx clobreg = gen_reg_rtx (SFmode);
6969      emit_insn (gen_no_literal_pool_sf_immediate (operands[0], operands[1],
6970						   clobreg));
6971      DONE;
6972    }
6973  "
6974)
6975
6976;; Transform a floating-point move of a constant into a core register into
6977;; an SImode operation.
6978(define_split
6979  [(set (match_operand:SF 0 "arm_general_register_operand" "")
6980	(match_operand:SF 1 "immediate_operand" ""))]
6981  "TARGET_EITHER
6982   && reload_completed
6983   && CONST_DOUBLE_P (operands[1])"
6984  [(set (match_dup 2) (match_dup 3))]
6985  "
6986  operands[2] = gen_lowpart (SImode, operands[0]);
6987  operands[3] = gen_lowpart (SImode, operands[1]);
6988  if (operands[2] == 0 || operands[3] == 0)
6989    FAIL;
6990  "
6991)
6992
6993(define_insn "*arm_movsf_soft_insn"
6994  [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,m")
6995	(match_operand:SF 1 "general_operand"  "r,mE,r"))]
6996  "TARGET_32BIT
6997   && TARGET_SOFT_FLOAT
6998   && (!MEM_P (operands[0])
6999       || register_operand (operands[1], SFmode))"
7000{
7001  switch (which_alternative)
7002    {
7003    case 0: return \"mov%?\\t%0, %1\";
7004    case 1:
7005      /* Cannot load it directly, split to load it via MOV / MOVT.  */
7006      if (!MEM_P (operands[1]) && arm_disable_literal_pool)
7007	return \"#\";
7008      return \"ldr%?\\t%0, %1\\t%@ float\";
7009    case 2: return \"str%?\\t%1, %0\\t%@ float\";
7010    default: gcc_unreachable ();
7011    }
7012}
7013  [(set_attr "predicable" "yes")
7014   (set_attr "type" "mov_reg,load_4,store_4")
7015   (set_attr "arm_pool_range" "*,4096,*")
7016   (set_attr "thumb2_pool_range" "*,4094,*")
7017   (set_attr "arm_neg_pool_range" "*,4084,*")
7018   (set_attr "thumb2_neg_pool_range" "*,0,*")]
7019)
7020
7021;; Splitter for the above.
7022(define_split
7023  [(set (match_operand:SF 0 "s_register_operand")
7024	(match_operand:SF 1 "const_double_operand"))]
7025  "arm_disable_literal_pool && TARGET_SOFT_FLOAT"
7026  [(const_int 0)]
7027{
7028  long buf;
7029  real_to_target (&buf, CONST_DOUBLE_REAL_VALUE (operands[1]), SFmode);
7030  rtx cst = gen_int_mode (buf, SImode);
7031  emit_move_insn (simplify_gen_subreg (SImode, operands[0], SFmode, 0), cst);
7032  DONE;
7033}
7034)
7035
7036(define_expand "movdf"
7037  [(set (match_operand:DF 0 "general_operand" "")
7038	(match_operand:DF 1 "general_operand" ""))]
7039  "TARGET_EITHER"
7040  "
7041  if (TARGET_32BIT)
7042    {
7043      if (MEM_P (operands[0]))
7044        operands[1] = force_reg (DFmode, operands[1]);
7045    }
7046  else /* TARGET_THUMB */
7047    {
7048      if (can_create_pseudo_p ())
7049        {
7050          if (!REG_P (operands[0]))
7051	    operands[1] = force_reg (DFmode, operands[1]);
7052        }
7053    }
7054
7055  /* Cannot load it directly, generate a load with clobber so that it can be
7056     loaded via GPR with MOV / MOVT.  */
7057  if (arm_disable_literal_pool
7058      && (REG_P (operands[0]) || SUBREG_P (operands[0]))
7059      && CONSTANT_P (operands[1])
7060      && TARGET_HARD_FLOAT
7061      && !arm_const_double_rtx (operands[1])
7062      && !(TARGET_VFP_DOUBLE && vfp3_const_double_rtx (operands[1])))
7063    {
7064      rtx clobreg = gen_reg_rtx (DFmode);
7065      emit_insn (gen_no_literal_pool_df_immediate (operands[0], operands[1],
7066						   clobreg));
7067      DONE;
7068    }
7069  "
7070)
7071
7072;; Reloading a df mode value stored in integer regs to memory can require a
7073;; scratch reg.
7074(define_expand "reload_outdf"
7075  [(match_operand:DF 0 "arm_reload_memory_operand" "=o")
7076   (match_operand:DF 1 "s_register_operand" "r")
7077   (match_operand:SI 2 "s_register_operand" "=&r")]
7078  "TARGET_THUMB2"
7079  "
7080  {
7081    enum rtx_code code = GET_CODE (XEXP (operands[0], 0));
7082
7083    if (code == REG)
7084      operands[2] = XEXP (operands[0], 0);
7085    else if (code == POST_INC || code == PRE_DEC)
7086      {
7087	operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7088	operands[1] = gen_rtx_SUBREG (DImode, operands[1], 0);
7089	emit_insn (gen_movdi (operands[0], operands[1]));
7090	DONE;
7091      }
7092    else if (code == PRE_INC)
7093      {
7094	rtx reg = XEXP (XEXP (operands[0], 0), 0);
7095
7096	emit_insn (gen_addsi3 (reg, reg, GEN_INT (8)));
7097	operands[2] = reg;
7098      }
7099    else if (code == POST_DEC)
7100      operands[2] = XEXP (XEXP (operands[0], 0), 0);
7101    else
7102      emit_insn (gen_addsi3 (operands[2], XEXP (XEXP (operands[0], 0), 0),
7103			     XEXP (XEXP (operands[0], 0), 1)));
7104
7105    emit_insn (gen_rtx_SET (replace_equiv_address (operands[0], operands[2]),
7106			    operands[1]));
7107
7108    if (code == POST_DEC)
7109      emit_insn (gen_addsi3 (operands[2], operands[2], GEN_INT (-8)));
7110
7111    DONE;
7112  }"
7113)
7114
7115(define_insn "*movdf_soft_insn"
7116  [(set (match_operand:DF 0 "nonimmediate_soft_df_operand" "=r,r,r,r,m")
7117	(match_operand:DF 1 "soft_df_operand" "rDa,Db,Dc,mF,r"))]
7118  "TARGET_32BIT && TARGET_SOFT_FLOAT
7119   && (   register_operand (operands[0], DFmode)
7120       || register_operand (operands[1], DFmode))"
7121  "*
7122  switch (which_alternative)
7123    {
7124    case 0:
7125    case 1:
7126    case 2:
7127      return \"#\";
7128    case 3:
7129      /* Cannot load it directly, split to load it via MOV / MOVT.  */
7130      if (!MEM_P (operands[1]) && arm_disable_literal_pool)
7131	return \"#\";
7132      /* Fall through.  */
7133    default:
7134      return output_move_double (operands, true, NULL);
7135    }
7136  "
7137  [(set_attr "length" "8,12,16,8,8")
7138   (set_attr "type" "multiple,multiple,multiple,load_8,store_8")
7139   (set_attr "arm_pool_range" "*,*,*,1020,*")
7140   (set_attr "thumb2_pool_range" "*,*,*,1018,*")
7141   (set_attr "arm_neg_pool_range" "*,*,*,1004,*")
7142   (set_attr "thumb2_neg_pool_range" "*,*,*,0,*")]
7143)
7144
7145;; Splitter for the above.
7146(define_split
7147  [(set (match_operand:DF 0 "s_register_operand")
7148	(match_operand:DF 1 "const_double_operand"))]
7149  "arm_disable_literal_pool && TARGET_SOFT_FLOAT"
7150  [(const_int 0)]
7151{
7152  long buf[2];
7153  int order = BYTES_BIG_ENDIAN ? 1 : 0;
7154  real_to_target (buf, CONST_DOUBLE_REAL_VALUE (operands[1]), DFmode);
7155  unsigned HOST_WIDE_INT ival = zext_hwi (buf[order], 32);
7156  ival |= (zext_hwi (buf[1 - order], 32) << 32);
7157  rtx cst = gen_int_mode (ival, DImode);
7158  emit_move_insn (simplify_gen_subreg (DImode, operands[0], DFmode, 0), cst);
7159  DONE;
7160}
7161)
7162
7163
7164;; load- and store-multiple insns
7165;; The arm can load/store any set of registers, provided that they are in
7166;; ascending order, but these expanders assume a contiguous set.
7167
7168(define_expand "load_multiple"
7169  [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
7170                          (match_operand:SI 1 "" ""))
7171                     (use (match_operand:SI 2 "" ""))])]
7172  "TARGET_32BIT"
7173{
7174  HOST_WIDE_INT offset = 0;
7175
7176  /* Support only fixed point registers.  */
7177  if (!CONST_INT_P (operands[2])
7178      || INTVAL (operands[2]) > MAX_LDM_STM_OPS
7179      || INTVAL (operands[2]) < 2
7180      || !MEM_P (operands[1])
7181      || !REG_P (operands[0])
7182      || REGNO (operands[0]) > (LAST_ARM_REGNUM - 1)
7183      || REGNO (operands[0]) + INTVAL (operands[2]) > LAST_ARM_REGNUM)
7184    FAIL;
7185
7186  operands[3]
7187    = arm_gen_load_multiple (arm_regs_in_sequence + REGNO (operands[0]),
7188			     INTVAL (operands[2]),
7189			     force_reg (SImode, XEXP (operands[1], 0)),
7190			     FALSE, operands[1], &offset);
7191})
7192
7193(define_expand "store_multiple"
7194  [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
7195                          (match_operand:SI 1 "" ""))
7196                     (use (match_operand:SI 2 "" ""))])]
7197  "TARGET_32BIT"
7198{
7199  HOST_WIDE_INT offset = 0;
7200
7201  /* Support only fixed point registers.  */
7202  if (!CONST_INT_P (operands[2])
7203      || INTVAL (operands[2]) > MAX_LDM_STM_OPS
7204      || INTVAL (operands[2]) < 2
7205      || !REG_P (operands[1])
7206      || !MEM_P (operands[0])
7207      || REGNO (operands[1]) > (LAST_ARM_REGNUM - 1)
7208      || REGNO (operands[1]) + INTVAL (operands[2]) > LAST_ARM_REGNUM)
7209    FAIL;
7210
7211  operands[3]
7212    = arm_gen_store_multiple (arm_regs_in_sequence + REGNO (operands[1]),
7213			      INTVAL (operands[2]),
7214			      force_reg (SImode, XEXP (operands[0], 0)),
7215			      FALSE, operands[0], &offset);
7216})
7217
7218
7219(define_expand "setmemsi"
7220  [(match_operand:BLK 0 "general_operand" "")
7221   (match_operand:SI 1 "const_int_operand" "")
7222   (match_operand:SI 2 "const_int_operand" "")
7223   (match_operand:SI 3 "const_int_operand" "")]
7224  "TARGET_32BIT"
7225{
7226  if (arm_gen_setmem (operands))
7227    DONE;
7228
7229  FAIL;
7230})
7231
7232
7233;; Move a block of memory if it is word aligned and MORE than 2 words long.
7234;; We could let this apply for blocks of less than this, but it clobbers so
7235;; many registers that there is then probably a better way.
7236
7237(define_expand "movmemqi"
7238  [(match_operand:BLK 0 "general_operand" "")
7239   (match_operand:BLK 1 "general_operand" "")
7240   (match_operand:SI 2 "const_int_operand" "")
7241   (match_operand:SI 3 "const_int_operand" "")]
7242  ""
7243  "
7244  if (TARGET_32BIT)
7245    {
7246      if (TARGET_LDRD && current_tune->prefer_ldrd_strd
7247          && !optimize_function_for_size_p (cfun))
7248        {
7249          if (gen_movmem_ldrd_strd (operands))
7250            DONE;
7251          FAIL;
7252        }
7253
7254      if (arm_gen_movmemqi (operands))
7255        DONE;
7256      FAIL;
7257    }
7258  else /* TARGET_THUMB1 */
7259    {
7260      if (   INTVAL (operands[3]) != 4
7261          || INTVAL (operands[2]) > 48)
7262        FAIL;
7263
7264      thumb_expand_movmemqi (operands);
7265      DONE;
7266    }
7267  "
7268)
7269
7270
7271;; Compare & branch insns
7272;; The range calculations are based as follows:
7273;; For forward branches, the address calculation returns the address of
7274;; the next instruction.  This is 2 beyond the branch instruction.
7275;; For backward branches, the address calculation returns the address of
7276;; the first instruction in this pattern (cmp).  This is 2 before the branch
7277;; instruction for the shortest sequence, and 4 before the branch instruction
7278;; if we have to jump around an unconditional branch.
7279;; To the basic branch range the PC offset must be added (this is +4).
7280;; So for forward branches we have
7281;;   (pos_range - pos_base_offs + pc_offs) = (pos_range - 2 + 4).
7282;; And for backward branches we have
7283;;   (neg_range - neg_base_offs + pc_offs) = (neg_range - (-2 or -4) + 4).
7284;;
7285;; For a 'b'       pos_range = 2046, neg_range = -2048 giving (-2040->2048).
7286;; For a 'b<cond>' pos_range = 254,  neg_range = -256  giving (-250 ->256).
7287
7288(define_expand "cbranchsi4"
7289  [(set (pc) (if_then_else
7290	      (match_operator 0 "expandable_comparison_operator"
7291	       [(match_operand:SI 1 "s_register_operand" "")
7292	        (match_operand:SI 2 "nonmemory_operand" "")])
7293	      (label_ref (match_operand 3 "" ""))
7294	      (pc)))]
7295  "TARGET_EITHER"
7296  "
7297  if (!TARGET_THUMB1)
7298    {
7299      if (!arm_validize_comparison (&operands[0], &operands[1], &operands[2]))
7300        FAIL;
7301      emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
7302				      operands[3]));
7303      DONE;
7304    }
7305  if (thumb1_cmpneg_operand (operands[2], SImode))
7306    {
7307      emit_jump_insn (gen_cbranchsi4_scratch (NULL, operands[1], operands[2],
7308					      operands[3], operands[0]));
7309      DONE;
7310    }
7311  if (!thumb1_cmp_operand (operands[2], SImode))
7312    operands[2] = force_reg (SImode, operands[2]);
7313  ")
7314
7315(define_expand "cbranchsf4"
7316  [(set (pc) (if_then_else
7317	      (match_operator 0 "expandable_comparison_operator"
7318	       [(match_operand:SF 1 "s_register_operand" "")
7319	        (match_operand:SF 2 "vfp_compare_operand" "")])
7320	      (label_ref (match_operand 3 "" ""))
7321	      (pc)))]
7322  "TARGET_32BIT && TARGET_HARD_FLOAT"
7323  "emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
7324				   operands[3])); DONE;"
7325)
7326
7327(define_expand "cbranchdf4"
7328  [(set (pc) (if_then_else
7329	      (match_operator 0 "expandable_comparison_operator"
7330	       [(match_operand:DF 1 "s_register_operand" "")
7331	        (match_operand:DF 2 "vfp_compare_operand" "")])
7332	      (label_ref (match_operand 3 "" ""))
7333	      (pc)))]
7334  "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
7335  "emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
7336				   operands[3])); DONE;"
7337)
7338
7339(define_expand "cbranchdi4"
7340  [(set (pc) (if_then_else
7341	      (match_operator 0 "expandable_comparison_operator"
7342	       [(match_operand:DI 1 "s_register_operand" "")
7343	        (match_operand:DI 2 "cmpdi_operand" "")])
7344	      (label_ref (match_operand 3 "" ""))
7345	      (pc)))]
7346  "TARGET_32BIT"
7347  "{
7348     if (!arm_validize_comparison (&operands[0], &operands[1], &operands[2]))
7349       FAIL;
7350     emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
7351				       operands[3]));
7352     DONE;
7353   }"
7354)
7355
7356;; Comparison and test insns
7357
7358(define_insn "*arm_cmpsi_insn"
7359  [(set (reg:CC CC_REGNUM)
7360	(compare:CC (match_operand:SI 0 "s_register_operand" "l,r,r,r,r")
7361		    (match_operand:SI 1 "arm_add_operand"    "Py,r,r,I,L")))]
7362  "TARGET_32BIT"
7363  "@
7364   cmp%?\\t%0, %1
7365   cmp%?\\t%0, %1
7366   cmp%?\\t%0, %1
7367   cmp%?\\t%0, %1
7368   cmn%?\\t%0, #%n1"
7369  [(set_attr "conds" "set")
7370   (set_attr "arch" "t2,t2,any,any,any")
7371   (set_attr "length" "2,2,4,4,4")
7372   (set_attr "predicable" "yes")
7373   (set_attr "predicable_short_it" "yes,yes,yes,no,no")
7374   (set_attr "type" "alus_imm,alus_sreg,alus_sreg,alus_imm,alus_imm")]
7375)
7376
7377(define_insn "*cmpsi_shiftsi"
7378  [(set (reg:CC CC_REGNUM)
7379	(compare:CC (match_operand:SI   0 "s_register_operand" "r,r,r")
7380		    (match_operator:SI  3 "shift_operator"
7381		     [(match_operand:SI 1 "s_register_operand" "r,r,r")
7382		      (match_operand:SI 2 "shift_amount_operand" "M,r,M")])))]
7383  "TARGET_32BIT"
7384  "cmp\\t%0, %1%S3"
7385  [(set_attr "conds" "set")
7386   (set_attr "shift" "1")
7387   (set_attr "arch" "32,a,a")
7388   (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
7389
7390(define_insn "*cmpsi_shiftsi_swp"
7391  [(set (reg:CC_SWP CC_REGNUM)
7392	(compare:CC_SWP (match_operator:SI 3 "shift_operator"
7393			 [(match_operand:SI 1 "s_register_operand" "r,r,r")
7394			  (match_operand:SI 2 "shift_amount_operand" "M,r,M")])
7395			(match_operand:SI 0 "s_register_operand" "r,r,r")))]
7396  "TARGET_32BIT"
7397  "cmp%?\\t%0, %1%S3"
7398  [(set_attr "conds" "set")
7399   (set_attr "shift" "1")
7400   (set_attr "arch" "32,a,a")
7401   (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
7402
7403(define_insn "*arm_cmpsi_negshiftsi_si"
7404  [(set (reg:CC_Z CC_REGNUM)
7405	(compare:CC_Z
7406	 (neg:SI (match_operator:SI 1 "shift_operator"
7407		    [(match_operand:SI 2 "s_register_operand" "r")
7408		     (match_operand:SI 3 "reg_or_int_operand" "rM")]))
7409	 (match_operand:SI 0 "s_register_operand" "r")))]
7410  "TARGET_ARM"
7411  "cmn%?\\t%0, %2%S1"
7412  [(set_attr "conds" "set")
7413   (set (attr "type") (if_then_else (match_operand 3 "const_int_operand" "")
7414				    (const_string "alus_shift_imm")
7415				    (const_string "alus_shift_reg")))
7416   (set_attr "predicable" "yes")]
7417)
7418
7419;; DImode comparisons.  The generic code generates branches that
7420;; if-conversion cannot reduce to a conditional compare, so we do
7421;; that directly.
7422
7423(define_insn_and_split "*arm_cmpdi_insn"
7424  [(set (reg:CC_NCV CC_REGNUM)
7425	(compare:CC_NCV (match_operand:DI 0 "s_register_operand" "r")
7426			(match_operand:DI 1 "arm_di_operand"	   "rDi")))
7427   (clobber (match_scratch:SI 2 "=r"))]
7428  "TARGET_32BIT"
7429  "#"   ; "cmp\\t%Q0, %Q1\;sbcs\\t%2, %R0, %R1"
7430  "&& reload_completed"
7431  [(set (reg:CC CC_REGNUM)
7432        (compare:CC (match_dup 0) (match_dup 1)))
7433   (parallel [(set (reg:CC CC_REGNUM)
7434                   (compare:CC (match_dup 3) (match_dup 4)))
7435              (set (match_dup 2)
7436                   (minus:SI (match_dup 5)
7437			     (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))])]
7438  {
7439    operands[3] = gen_highpart (SImode, operands[0]);
7440    operands[0] = gen_lowpart (SImode, operands[0]);
7441    if (CONST_INT_P (operands[1]))
7442      {
7443	operands[4] = gen_highpart_mode (SImode, DImode, operands[1]);
7444	if (operands[4] == const0_rtx)
7445	  operands[5] = operands[3];
7446	else
7447	  operands[5] = gen_rtx_PLUS (SImode, operands[3],
7448				      gen_int_mode (-UINTVAL (operands[4]),
7449						    SImode));
7450      }
7451    else
7452      {
7453        operands[4] = gen_highpart (SImode, operands[1]);
7454        operands[5] = gen_rtx_MINUS (SImode, operands[3], operands[4]);
7455      }
7456    operands[1] = gen_lowpart (SImode, operands[1]);
7457    operands[2] = gen_lowpart (SImode, operands[2]);
7458  }
7459  [(set_attr "conds" "set")
7460   (set_attr "length" "8")
7461   (set_attr "type" "multiple")]
7462)
7463
7464(define_insn_and_split "*arm_cmpdi_unsigned"
7465  [(set (reg:CC_CZ CC_REGNUM)
7466        (compare:CC_CZ (match_operand:DI 0 "s_register_operand" "l,r,r,r")
7467                       (match_operand:DI 1 "arm_di_operand"     "Py,r,Di,rDi")))]
7468
7469  "TARGET_32BIT"
7470  "#"   ; "cmp\\t%R0, %R1\;it eq\;cmpeq\\t%Q0, %Q1"
7471  "&& reload_completed"
7472  [(set (reg:CC CC_REGNUM)
7473        (compare:CC (match_dup 2) (match_dup 3)))
7474   (cond_exec (eq:SI (reg:CC CC_REGNUM) (const_int 0))
7475              (set (reg:CC CC_REGNUM)
7476                   (compare:CC (match_dup 0) (match_dup 1))))]
7477  {
7478    operands[2] = gen_highpart (SImode, operands[0]);
7479    operands[0] = gen_lowpart (SImode, operands[0]);
7480    if (CONST_INT_P (operands[1]))
7481      operands[3] = gen_highpart_mode (SImode, DImode, operands[1]);
7482    else
7483      operands[3] = gen_highpart (SImode, operands[1]);
7484    operands[1] = gen_lowpart (SImode, operands[1]);
7485  }
7486  [(set_attr "conds" "set")
7487   (set_attr "enabled_for_short_it" "yes,yes,no,*")
7488   (set_attr "arch" "t2,t2,t2,a")
7489   (set_attr "length" "6,6,10,8")
7490   (set_attr "type" "multiple")]
7491)
7492
7493(define_insn "*arm_cmpdi_zero"
7494  [(set (reg:CC_Z CC_REGNUM)
7495	(compare:CC_Z (match_operand:DI 0 "s_register_operand" "r")
7496		      (const_int 0)))
7497   (clobber (match_scratch:SI 1 "=r"))]
7498  "TARGET_32BIT"
7499  "orrs%?\\t%1, %Q0, %R0"
7500  [(set_attr "conds" "set")
7501   (set_attr "type" "logics_reg")]
7502)
7503
7504; This insn allows redundant compares to be removed by cse, nothing should
7505; ever appear in the output file since (set (reg x) (reg x)) is a no-op that
7506; is deleted later on. The match_dup will match the mode here, so that
7507; mode changes of the condition codes aren't lost by this even though we don't
7508; specify what they are.
7509
7510(define_insn "*deleted_compare"
7511  [(set (match_operand 0 "cc_register" "") (match_dup 0))]
7512  "TARGET_32BIT"
7513  "\\t%@ deleted compare"
7514  [(set_attr "conds" "set")
7515   (set_attr "length" "0")
7516   (set_attr "type" "no_insn")]
7517)
7518
7519
7520;; Conditional branch insns
7521
7522(define_expand "cbranch_cc"
7523  [(set (pc)
7524	(if_then_else (match_operator 0 "" [(match_operand 1 "" "")
7525					    (match_operand 2 "" "")])
7526		      (label_ref (match_operand 3 "" ""))
7527		      (pc)))]
7528  "TARGET_32BIT"
7529  "operands[1] = arm_gen_compare_reg (GET_CODE (operands[0]),
7530				      operands[1], operands[2], NULL_RTX);
7531   operands[2] = const0_rtx;"
7532)
7533
7534;;
7535;; Patterns to match conditional branch insns.
7536;;
7537
7538(define_insn "arm_cond_branch"
7539  [(set (pc)
7540	(if_then_else (match_operator 1 "arm_comparison_operator"
7541		       [(match_operand 2 "cc_register" "") (const_int 0)])
7542		      (label_ref (match_operand 0 "" ""))
7543		      (pc)))]
7544  "TARGET_32BIT"
7545  "*
7546  if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
7547    {
7548      arm_ccfsm_state += 2;
7549      return \"\";
7550    }
7551  return \"b%d1\\t%l0\";
7552  "
7553  [(set_attr "conds" "use")
7554   (set_attr "type" "branch")
7555   (set (attr "length")
7556	(if_then_else
7557	   (and (match_test "TARGET_THUMB2")
7558		(and (ge (minus (match_dup 0) (pc)) (const_int -250))
7559		     (le (minus (match_dup 0) (pc)) (const_int 256))))
7560	   (const_int 2)
7561	   (const_int 4)))]
7562)
7563
7564(define_insn "*arm_cond_branch_reversed"
7565  [(set (pc)
7566	(if_then_else (match_operator 1 "arm_comparison_operator"
7567		       [(match_operand 2 "cc_register" "") (const_int 0)])
7568		      (pc)
7569		      (label_ref (match_operand 0 "" ""))))]
7570  "TARGET_32BIT"
7571  "*
7572  if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
7573    {
7574      arm_ccfsm_state += 2;
7575      return \"\";
7576    }
7577  return \"b%D1\\t%l0\";
7578  "
7579  [(set_attr "conds" "use")
7580   (set_attr "type" "branch")
7581   (set (attr "length")
7582	(if_then_else
7583	   (and (match_test "TARGET_THUMB2")
7584		(and (ge (minus (match_dup 0) (pc)) (const_int -250))
7585		     (le (minus (match_dup 0) (pc)) (const_int 256))))
7586	   (const_int 2)
7587	   (const_int 4)))]
7588)
7589
7590
7591
7592; scc insns
7593
7594(define_expand "cstore_cc"
7595  [(set (match_operand:SI 0 "s_register_operand" "")
7596	(match_operator:SI 1 "" [(match_operand 2 "" "")
7597				 (match_operand 3 "" "")]))]
7598  "TARGET_32BIT"
7599  "operands[2] = arm_gen_compare_reg (GET_CODE (operands[1]),
7600				      operands[2], operands[3], NULL_RTX);
7601   operands[3] = const0_rtx;"
7602)
7603
7604(define_insn_and_split "*mov_scc"
7605  [(set (match_operand:SI 0 "s_register_operand" "=r")
7606	(match_operator:SI 1 "arm_comparison_operator_mode"
7607	 [(match_operand 2 "cc_register" "") (const_int 0)]))]
7608  "TARGET_ARM"
7609  "#"   ; "mov%D1\\t%0, #0\;mov%d1\\t%0, #1"
7610  "TARGET_ARM"
7611  [(set (match_dup 0)
7612        (if_then_else:SI (match_dup 1)
7613                         (const_int 1)
7614                         (const_int 0)))]
7615  ""
7616  [(set_attr "conds" "use")
7617   (set_attr "length" "8")
7618   (set_attr "type" "multiple")]
7619)
7620
7621(define_insn_and_split "*mov_negscc"
7622  [(set (match_operand:SI 0 "s_register_operand" "=r")
7623	(neg:SI (match_operator:SI 1 "arm_comparison_operator_mode"
7624		 [(match_operand 2 "cc_register" "") (const_int 0)])))]
7625  "TARGET_ARM"
7626  "#"   ; "mov%D1\\t%0, #0\;mvn%d1\\t%0, #0"
7627  "TARGET_ARM"
7628  [(set (match_dup 0)
7629        (if_then_else:SI (match_dup 1)
7630                         (match_dup 3)
7631                         (const_int 0)))]
7632  {
7633    operands[3] = GEN_INT (~0);
7634  }
7635  [(set_attr "conds" "use")
7636   (set_attr "length" "8")
7637   (set_attr "type" "multiple")]
7638)
7639
7640(define_insn_and_split "*mov_notscc"
7641  [(set (match_operand:SI 0 "s_register_operand" "=r")
7642	(not:SI (match_operator:SI 1 "arm_comparison_operator"
7643		 [(match_operand 2 "cc_register" "") (const_int 0)])))]
7644  "TARGET_ARM"
7645  "#"   ; "mvn%D1\\t%0, #0\;mvn%d1\\t%0, #1"
7646  "TARGET_ARM"
7647  [(set (match_dup 0)
7648        (if_then_else:SI (match_dup 1)
7649                         (match_dup 3)
7650                         (match_dup 4)))]
7651  {
7652    operands[3] = GEN_INT (~1);
7653    operands[4] = GEN_INT (~0);
7654  }
7655  [(set_attr "conds" "use")
7656   (set_attr "length" "8")
7657   (set_attr "type" "multiple")]
7658)
7659
7660(define_expand "cstoresi4"
7661  [(set (match_operand:SI 0 "s_register_operand" "")
7662	(match_operator:SI 1 "expandable_comparison_operator"
7663	 [(match_operand:SI 2 "s_register_operand" "")
7664	  (match_operand:SI 3 "reg_or_int_operand" "")]))]
7665  "TARGET_32BIT || TARGET_THUMB1"
7666  "{
7667  rtx op3, scratch, scratch2;
7668
7669  if (!TARGET_THUMB1)
7670    {
7671      if (!arm_add_operand (operands[3], SImode))
7672	operands[3] = force_reg (SImode, operands[3]);
7673      emit_insn (gen_cstore_cc (operands[0], operands[1],
7674				operands[2], operands[3]));
7675      DONE;
7676    }
7677
7678  if (operands[3] == const0_rtx)
7679    {
7680      switch (GET_CODE (operands[1]))
7681	{
7682	case EQ:
7683	  emit_insn (gen_cstoresi_eq0_thumb1 (operands[0], operands[2]));
7684	  break;
7685
7686	case NE:
7687	  emit_insn (gen_cstoresi_ne0_thumb1 (operands[0], operands[2]));
7688	  break;
7689
7690	case LE:
7691          scratch = expand_binop (SImode, add_optab, operands[2], constm1_rtx,
7692				  NULL_RTX, 0, OPTAB_WIDEN);
7693          scratch = expand_binop (SImode, ior_optab, operands[2], scratch,
7694				  NULL_RTX, 0, OPTAB_WIDEN);
7695          expand_binop (SImode, lshr_optab, scratch, GEN_INT (31),
7696			operands[0], 1, OPTAB_WIDEN);
7697	  break;
7698
7699        case GE:
7700          scratch = expand_unop (SImode, one_cmpl_optab, operands[2],
7701				 NULL_RTX, 1);
7702          expand_binop (SImode, lshr_optab, scratch, GEN_INT (31),
7703			NULL_RTX, 1, OPTAB_WIDEN);
7704          break;
7705
7706        case GT:
7707          scratch = expand_binop (SImode, ashr_optab, operands[2],
7708				  GEN_INT (31), NULL_RTX, 0, OPTAB_WIDEN);
7709          scratch = expand_binop (SImode, sub_optab, scratch, operands[2],
7710				  NULL_RTX, 0, OPTAB_WIDEN);
7711          expand_binop (SImode, lshr_optab, scratch, GEN_INT (31), operands[0],
7712			0, OPTAB_WIDEN);
7713          break;
7714
7715	/* LT is handled by generic code.  No need for unsigned with 0.  */
7716	default:
7717	  FAIL;
7718	}
7719      DONE;
7720    }
7721
7722  switch (GET_CODE (operands[1]))
7723    {
7724    case EQ:
7725      scratch = expand_binop (SImode, sub_optab, operands[2], operands[3],
7726			      NULL_RTX, 0, OPTAB_WIDEN);
7727      emit_insn (gen_cstoresi_eq0_thumb1 (operands[0], scratch));
7728      break;
7729
7730    case NE:
7731      scratch = expand_binop (SImode, sub_optab, operands[2], operands[3],
7732			      NULL_RTX, 0, OPTAB_WIDEN);
7733      emit_insn (gen_cstoresi_ne0_thumb1 (operands[0], scratch));
7734      break;
7735
7736    case LE:
7737      op3 = force_reg (SImode, operands[3]);
7738
7739      scratch = expand_binop (SImode, lshr_optab, operands[2], GEN_INT (31),
7740			      NULL_RTX, 1, OPTAB_WIDEN);
7741      scratch2 = expand_binop (SImode, ashr_optab, op3, GEN_INT (31),
7742			      NULL_RTX, 0, OPTAB_WIDEN);
7743      emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch2,
7744					  op3, operands[2]));
7745      break;
7746
7747    case GE:
7748      op3 = operands[3];
7749      if (!thumb1_cmp_operand (op3, SImode))
7750        op3 = force_reg (SImode, op3);
7751      scratch = expand_binop (SImode, ashr_optab, operands[2], GEN_INT (31),
7752			      NULL_RTX, 0, OPTAB_WIDEN);
7753      scratch2 = expand_binop (SImode, lshr_optab, op3, GEN_INT (31),
7754			       NULL_RTX, 1, OPTAB_WIDEN);
7755      emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch2,
7756					  operands[2], op3));
7757      break;
7758
7759    case LEU:
7760      op3 = force_reg (SImode, operands[3]);
7761      scratch = force_reg (SImode, const0_rtx);
7762      emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch,
7763					  op3, operands[2]));
7764      break;
7765
7766    case GEU:
7767      op3 = operands[3];
7768      if (!thumb1_cmp_operand (op3, SImode))
7769        op3 = force_reg (SImode, op3);
7770      scratch = force_reg (SImode, const0_rtx);
7771      emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch,
7772					  operands[2], op3));
7773      break;
7774
7775    case LTU:
7776      op3 = operands[3];
7777      if (!thumb1_cmp_operand (op3, SImode))
7778        op3 = force_reg (SImode, op3);
7779      scratch = gen_reg_rtx (SImode);
7780      emit_insn (gen_cstoresi_ltu_thumb1 (operands[0], operands[2], op3));
7781      break;
7782
7783    case GTU:
7784      op3 = force_reg (SImode, operands[3]);
7785      scratch = gen_reg_rtx (SImode);
7786      emit_insn (gen_cstoresi_ltu_thumb1 (operands[0], op3, operands[2]));
7787      break;
7788
7789    /* No good sequences for GT, LT.  */
7790    default:
7791      FAIL;
7792    }
7793  DONE;
7794}")
7795
7796(define_expand "cstorehf4"
7797  [(set (match_operand:SI 0 "s_register_operand")
7798	(match_operator:SI 1 "expandable_comparison_operator"
7799	 [(match_operand:HF 2 "s_register_operand")
7800	  (match_operand:HF 3 "vfp_compare_operand")]))]
7801  "TARGET_VFP_FP16INST"
7802  {
7803    if (!arm_validize_comparison (&operands[1],
7804				  &operands[2],
7805				  &operands[3]))
7806       FAIL;
7807
7808    emit_insn (gen_cstore_cc (operands[0], operands[1],
7809			      operands[2], operands[3]));
7810    DONE;
7811  }
7812)
7813
7814(define_expand "cstoresf4"
7815  [(set (match_operand:SI 0 "s_register_operand" "")
7816	(match_operator:SI 1 "expandable_comparison_operator"
7817	 [(match_operand:SF 2 "s_register_operand" "")
7818	  (match_operand:SF 3 "vfp_compare_operand" "")]))]
7819  "TARGET_32BIT && TARGET_HARD_FLOAT"
7820  "emit_insn (gen_cstore_cc (operands[0], operands[1],
7821			     operands[2], operands[3])); DONE;"
7822)
7823
7824(define_expand "cstoredf4"
7825  [(set (match_operand:SI 0 "s_register_operand" "")
7826	(match_operator:SI 1 "expandable_comparison_operator"
7827	 [(match_operand:DF 2 "s_register_operand" "")
7828	  (match_operand:DF 3 "vfp_compare_operand" "")]))]
7829  "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
7830  "emit_insn (gen_cstore_cc (operands[0], operands[1],
7831			     operands[2], operands[3])); DONE;"
7832)
7833
7834(define_expand "cstoredi4"
7835  [(set (match_operand:SI 0 "s_register_operand" "")
7836	(match_operator:SI 1 "expandable_comparison_operator"
7837	 [(match_operand:DI 2 "s_register_operand" "")
7838	  (match_operand:DI 3 "cmpdi_operand" "")]))]
7839  "TARGET_32BIT"
7840  "{
7841     if (!arm_validize_comparison (&operands[1],
7842     				   &operands[2],
7843				   &operands[3]))
7844       FAIL;
7845     emit_insn (gen_cstore_cc (operands[0], operands[1], operands[2],
7846		      	         operands[3]));
7847     DONE;
7848   }"
7849)
7850
7851
7852;; Conditional move insns
7853
7854(define_expand "movsicc"
7855  [(set (match_operand:SI 0 "s_register_operand" "")
7856	(if_then_else:SI (match_operand 1 "expandable_comparison_operator" "")
7857			 (match_operand:SI 2 "arm_not_operand" "")
7858			 (match_operand:SI 3 "arm_not_operand" "")))]
7859  "TARGET_32BIT"
7860  "
7861  {
7862    enum rtx_code code;
7863    rtx ccreg;
7864
7865    if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
7866				  &XEXP (operands[1], 1)))
7867      FAIL;
7868
7869    code = GET_CODE (operands[1]);
7870    ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
7871				 XEXP (operands[1], 1), NULL_RTX);
7872    operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7873  }"
7874)
7875
7876(define_expand "movhfcc"
7877  [(set (match_operand:HF 0 "s_register_operand")
7878	(if_then_else:HF (match_operand 1 "arm_cond_move_operator")
7879			 (match_operand:HF 2 "s_register_operand")
7880			 (match_operand:HF 3 "s_register_operand")))]
7881  "TARGET_VFP_FP16INST"
7882  "
7883  {
7884    enum rtx_code code = GET_CODE (operands[1]);
7885    rtx ccreg;
7886
7887    if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
7888				  &XEXP (operands[1], 1)))
7889      FAIL;
7890
7891    code = GET_CODE (operands[1]);
7892    ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
7893				 XEXP (operands[1], 1), NULL_RTX);
7894    operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7895  }"
7896)
7897
7898(define_expand "movsfcc"
7899  [(set (match_operand:SF 0 "s_register_operand" "")
7900	(if_then_else:SF (match_operand 1 "arm_cond_move_operator" "")
7901			 (match_operand:SF 2 "s_register_operand" "")
7902			 (match_operand:SF 3 "s_register_operand" "")))]
7903  "TARGET_32BIT && TARGET_HARD_FLOAT"
7904  "
7905  {
7906    enum rtx_code code = GET_CODE (operands[1]);
7907    rtx ccreg;
7908
7909    if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
7910       				  &XEXP (operands[1], 1)))
7911       FAIL;
7912
7913    code = GET_CODE (operands[1]);
7914    ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
7915				 XEXP (operands[1], 1), NULL_RTX);
7916    operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7917  }"
7918)
7919
7920(define_expand "movdfcc"
7921  [(set (match_operand:DF 0 "s_register_operand" "")
7922	(if_then_else:DF (match_operand 1 "arm_cond_move_operator" "")
7923			 (match_operand:DF 2 "s_register_operand" "")
7924			 (match_operand:DF 3 "s_register_operand" "")))]
7925  "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
7926  "
7927  {
7928    enum rtx_code code = GET_CODE (operands[1]);
7929    rtx ccreg;
7930
7931    if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
7932       				  &XEXP (operands[1], 1)))
7933       FAIL;
7934    code = GET_CODE (operands[1]);
7935    ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
7936				 XEXP (operands[1], 1), NULL_RTX);
7937    operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7938  }"
7939)
7940
7941(define_insn "*cmov<mode>"
7942    [(set (match_operand:SDF 0 "s_register_operand" "=<F_constraint>")
7943	(if_then_else:SDF (match_operator 1 "arm_vsel_comparison_operator"
7944			  [(match_operand 2 "cc_register" "") (const_int 0)])
7945			  (match_operand:SDF 3 "s_register_operand"
7946			                      "<F_constraint>")
7947			  (match_operand:SDF 4 "s_register_operand"
7948			                      "<F_constraint>")))]
7949  "TARGET_HARD_FLOAT && TARGET_VFP5 <vfp_double_cond>"
7950  "*
7951  {
7952    enum arm_cond_code code = maybe_get_arm_condition_code (operands[1]);
7953    switch (code)
7954      {
7955      case ARM_GE:
7956      case ARM_GT:
7957      case ARM_EQ:
7958      case ARM_VS:
7959        return \"vsel%d1.<V_if_elem>\\t%<V_reg>0, %<V_reg>3, %<V_reg>4\";
7960      case ARM_LT:
7961      case ARM_LE:
7962      case ARM_NE:
7963      case ARM_VC:
7964        return \"vsel%D1.<V_if_elem>\\t%<V_reg>0, %<V_reg>4, %<V_reg>3\";
7965      default:
7966        gcc_unreachable ();
7967      }
7968    return \"\";
7969  }"
7970  [(set_attr "conds" "use")
7971   (set_attr "type" "fcsel")]
7972)
7973
7974(define_insn "*cmovhf"
7975    [(set (match_operand:HF 0 "s_register_operand" "=t")
7976	(if_then_else:HF (match_operator 1 "arm_vsel_comparison_operator"
7977			 [(match_operand 2 "cc_register" "") (const_int 0)])
7978			  (match_operand:HF 3 "s_register_operand" "t")
7979			  (match_operand:HF 4 "s_register_operand" "t")))]
7980  "TARGET_VFP_FP16INST"
7981  "*
7982  {
7983    enum arm_cond_code code = maybe_get_arm_condition_code (operands[1]);
7984    switch (code)
7985      {
7986      case ARM_GE:
7987      case ARM_GT:
7988      case ARM_EQ:
7989      case ARM_VS:
7990	return \"vsel%d1.f16\\t%0, %3, %4\";
7991      case ARM_LT:
7992      case ARM_LE:
7993      case ARM_NE:
7994      case ARM_VC:
7995	return \"vsel%D1.f16\\t%0, %4, %3\";
7996      default:
7997	gcc_unreachable ();
7998      }
7999    return \"\";
8000  }"
8001  [(set_attr "conds" "use")
8002   (set_attr "type" "fcsel")]
8003)
8004
8005(define_insn_and_split "*movsicc_insn"
8006  [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r,r,r,r,r")
8007	(if_then_else:SI
8008	 (match_operator 3 "arm_comparison_operator"
8009	  [(match_operand 4 "cc_register" "") (const_int 0)])
8010	 (match_operand:SI 1 "arm_not_operand" "0,0,rI,K,rI,rI,K,K")
8011	 (match_operand:SI 2 "arm_not_operand" "rI,K,0,0,rI,K,rI,K")))]
8012  "TARGET_ARM"
8013  "@
8014   mov%D3\\t%0, %2
8015   mvn%D3\\t%0, #%B2
8016   mov%d3\\t%0, %1
8017   mvn%d3\\t%0, #%B1
8018   #
8019   #
8020   #
8021   #"
8022   ; alt4: mov%d3\\t%0, %1\;mov%D3\\t%0, %2
8023   ; alt5: mov%d3\\t%0, %1\;mvn%D3\\t%0, #%B2
8024   ; alt6: mvn%d3\\t%0, #%B1\;mov%D3\\t%0, %2
8025   ; alt7: mvn%d3\\t%0, #%B1\;mvn%D3\\t%0, #%B2"
8026  "&& reload_completed"
8027  [(const_int 0)]
8028  {
8029    enum rtx_code rev_code;
8030    machine_mode mode;
8031    rtx rev_cond;
8032
8033    emit_insn (gen_rtx_COND_EXEC (VOIDmode,
8034                                  operands[3],
8035                                  gen_rtx_SET (operands[0], operands[1])));
8036
8037    rev_code = GET_CODE (operands[3]);
8038    mode = GET_MODE (operands[4]);
8039    if (mode == CCFPmode || mode == CCFPEmode)
8040      rev_code = reverse_condition_maybe_unordered (rev_code);
8041    else
8042      rev_code = reverse_condition (rev_code);
8043
8044    rev_cond = gen_rtx_fmt_ee (rev_code,
8045                               VOIDmode,
8046                               operands[4],
8047                               const0_rtx);
8048    emit_insn (gen_rtx_COND_EXEC (VOIDmode,
8049                                  rev_cond,
8050                                  gen_rtx_SET (operands[0], operands[2])));
8051    DONE;
8052  }
8053  [(set_attr "length" "4,4,4,4,8,8,8,8")
8054   (set_attr "conds" "use")
8055   (set_attr_alternative "type"
8056                         [(if_then_else (match_operand 2 "const_int_operand" "")
8057                                        (const_string "mov_imm")
8058                                        (const_string "mov_reg"))
8059                          (const_string "mvn_imm")
8060                          (if_then_else (match_operand 1 "const_int_operand" "")
8061                                        (const_string "mov_imm")
8062                                        (const_string "mov_reg"))
8063                          (const_string "mvn_imm")
8064                          (const_string "multiple")
8065                          (const_string "multiple")
8066                          (const_string "multiple")
8067                          (const_string "multiple")])]
8068)
8069
8070(define_insn "*movsfcc_soft_insn"
8071  [(set (match_operand:SF 0 "s_register_operand" "=r,r")
8072	(if_then_else:SF (match_operator 3 "arm_comparison_operator"
8073			  [(match_operand 4 "cc_register" "") (const_int 0)])
8074			 (match_operand:SF 1 "s_register_operand" "0,r")
8075			 (match_operand:SF 2 "s_register_operand" "r,0")))]
8076  "TARGET_ARM && TARGET_SOFT_FLOAT"
8077  "@
8078   mov%D3\\t%0, %2
8079   mov%d3\\t%0, %1"
8080  [(set_attr "conds" "use")
8081   (set_attr "type" "mov_reg")]
8082)
8083
8084
8085;; Jump and linkage insns
8086
8087(define_expand "jump"
8088  [(set (pc)
8089	(label_ref (match_operand 0 "" "")))]
8090  "TARGET_EITHER"
8091  ""
8092)
8093
8094(define_insn "*arm_jump"
8095  [(set (pc)
8096	(label_ref (match_operand 0 "" "")))]
8097  "TARGET_32BIT"
8098  "*
8099  {
8100    if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
8101      {
8102        arm_ccfsm_state += 2;
8103        return \"\";
8104      }
8105    return \"b%?\\t%l0\";
8106  }
8107  "
8108  [(set_attr "predicable" "yes")
8109   (set (attr "length")
8110	(if_then_else
8111	   (and (match_test "TARGET_THUMB2")
8112		(and (ge (minus (match_dup 0) (pc)) (const_int -2044))
8113		     (le (minus (match_dup 0) (pc)) (const_int 2048))))
8114	   (const_int 2)
8115	   (const_int 4)))
8116   (set_attr "type" "branch")]
8117)
8118
8119(define_expand "call"
8120  [(parallel [(call (match_operand 0 "memory_operand" "")
8121	            (match_operand 1 "general_operand" ""))
8122	      (use (match_operand 2 "" ""))
8123	      (clobber (reg:SI LR_REGNUM))])]
8124  "TARGET_EITHER"
8125  "
8126  {
8127    rtx callee, pat;
8128    tree addr = MEM_EXPR (operands[0]);
8129
8130    /* In an untyped call, we can get NULL for operand 2.  */
8131    if (operands[2] == NULL_RTX)
8132      operands[2] = const0_rtx;
8133
8134    /* Decide if we should generate indirect calls by loading the
8135       32-bit address of the callee into a register before performing the
8136       branch and link.  */
8137    callee = XEXP (operands[0], 0);
8138    if (GET_CODE (callee) == SYMBOL_REF
8139	? arm_is_long_call_p (SYMBOL_REF_DECL (callee))
8140	: !REG_P (callee))
8141      XEXP (operands[0], 0) = force_reg (Pmode, callee);
8142
8143    if (detect_cmse_nonsecure_call (addr))
8144      {
8145	pat = gen_nonsecure_call_internal (operands[0], operands[1],
8146					   operands[2]);
8147	emit_call_insn (pat);
8148      }
8149    else
8150      {
8151	pat = gen_call_internal (operands[0], operands[1], operands[2]);
8152	arm_emit_call_insn (pat, XEXP (operands[0], 0), false);
8153      }
8154    DONE;
8155  }"
8156)
8157
8158(define_expand "call_internal"
8159  [(parallel [(call (match_operand 0 "memory_operand" "")
8160	            (match_operand 1 "general_operand" ""))
8161	      (use (match_operand 2 "" ""))
8162	      (clobber (reg:SI LR_REGNUM))])])
8163
8164(define_expand "nonsecure_call_internal"
8165  [(parallel [(call (unspec:SI [(match_operand 0 "memory_operand" "")]
8166			       UNSPEC_NONSECURE_MEM)
8167		    (match_operand 1 "general_operand" ""))
8168	      (use (match_operand 2 "" ""))
8169	      (clobber (reg:SI LR_REGNUM))])]
8170  "use_cmse"
8171  "
8172  {
8173    rtx tmp;
8174    tmp = copy_to_suggested_reg (XEXP (operands[0], 0),
8175				 gen_rtx_REG (SImode, R4_REGNUM),
8176				 SImode);
8177
8178    operands[0] = replace_equiv_address (operands[0], tmp);
8179  }")
8180
8181(define_insn "*call_reg_armv5"
8182  [(call (mem:SI (match_operand:SI 0 "s_register_operand" "r"))
8183         (match_operand 1 "" ""))
8184   (use (match_operand 2 "" ""))
8185   (clobber (reg:SI LR_REGNUM))]
8186  "TARGET_ARM && arm_arch5t && !SIBLING_CALL_P (insn)"
8187  "blx%?\\t%0"
8188  [(set_attr "type" "call")]
8189)
8190
8191(define_insn "*call_reg_arm"
8192  [(call (mem:SI (match_operand:SI 0 "s_register_operand" "r"))
8193         (match_operand 1 "" ""))
8194   (use (match_operand 2 "" ""))
8195   (clobber (reg:SI LR_REGNUM))]
8196  "TARGET_ARM && !arm_arch5t && !SIBLING_CALL_P (insn)"
8197  "*
8198  return output_call (operands);
8199  "
8200  ;; length is worst case, normally it is only two
8201  [(set_attr "length" "12")
8202   (set_attr "type" "call")]
8203)
8204
8205
8206(define_expand "call_value"
8207  [(parallel [(set (match_operand       0 "" "")
8208	           (call (match_operand 1 "memory_operand" "")
8209		         (match_operand 2 "general_operand" "")))
8210	      (use (match_operand 3 "" ""))
8211	      (clobber (reg:SI LR_REGNUM))])]
8212  "TARGET_EITHER"
8213  "
8214  {
8215    rtx pat, callee;
8216    tree addr = MEM_EXPR (operands[1]);
8217
8218    /* In an untyped call, we can get NULL for operand 2.  */
8219    if (operands[3] == 0)
8220      operands[3] = const0_rtx;
8221
8222    /* Decide if we should generate indirect calls by loading the
8223       32-bit address of the callee into a register before performing the
8224       branch and link.  */
8225    callee = XEXP (operands[1], 0);
8226    if (GET_CODE (callee) == SYMBOL_REF
8227	? arm_is_long_call_p (SYMBOL_REF_DECL (callee))
8228	: !REG_P (callee))
8229      XEXP (operands[1], 0) = force_reg (Pmode, callee);
8230
8231    if (detect_cmse_nonsecure_call (addr))
8232      {
8233	pat = gen_nonsecure_call_value_internal (operands[0], operands[1],
8234						 operands[2], operands[3]);
8235	emit_call_insn (pat);
8236      }
8237    else
8238      {
8239	pat = gen_call_value_internal (operands[0], operands[1],
8240				       operands[2], operands[3]);
8241	arm_emit_call_insn (pat, XEXP (operands[1], 0), false);
8242      }
8243    DONE;
8244  }"
8245)
8246
8247(define_expand "call_value_internal"
8248  [(parallel [(set (match_operand       0 "" "")
8249	           (call (match_operand 1 "memory_operand" "")
8250		         (match_operand 2 "general_operand" "")))
8251	      (use (match_operand 3 "" ""))
8252	      (clobber (reg:SI LR_REGNUM))])])
8253
8254(define_expand "nonsecure_call_value_internal"
8255  [(parallel [(set (match_operand       0 "" "")
8256		   (call (unspec:SI [(match_operand 1 "memory_operand" "")]
8257				    UNSPEC_NONSECURE_MEM)
8258			 (match_operand 2 "general_operand" "")))
8259	      (use (match_operand 3 "" ""))
8260	      (clobber (reg:SI LR_REGNUM))])]
8261  "use_cmse"
8262  "
8263  {
8264    rtx tmp;
8265    tmp = copy_to_suggested_reg (XEXP (operands[1], 0),
8266				 gen_rtx_REG (SImode, R4_REGNUM),
8267				 SImode);
8268
8269    operands[1] = replace_equiv_address (operands[1], tmp);
8270  }")
8271
8272(define_insn "*call_value_reg_armv5"
8273  [(set (match_operand 0 "" "")
8274        (call (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
8275	      (match_operand 2 "" "")))
8276   (use (match_operand 3 "" ""))
8277   (clobber (reg:SI LR_REGNUM))]
8278  "TARGET_ARM && arm_arch5t && !SIBLING_CALL_P (insn)"
8279  "blx%?\\t%1"
8280  [(set_attr "type" "call")]
8281)
8282
8283(define_insn "*call_value_reg_arm"
8284  [(set (match_operand 0 "" "")
8285        (call (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
8286	      (match_operand 2 "" "")))
8287   (use (match_operand 3 "" ""))
8288   (clobber (reg:SI LR_REGNUM))]
8289  "TARGET_ARM && !arm_arch5t && !SIBLING_CALL_P (insn)"
8290  "*
8291  return output_call (&operands[1]);
8292  "
8293  [(set_attr "length" "12")
8294   (set_attr "type" "call")]
8295)
8296
8297;; Allow calls to SYMBOL_REFs specially as they are not valid general addresses
8298;; The 'a' causes the operand to be treated as an address, i.e. no '#' output.
8299
8300(define_insn "*call_symbol"
8301  [(call (mem:SI (match_operand:SI 0 "" ""))
8302	 (match_operand 1 "" ""))
8303   (use (match_operand 2 "" ""))
8304   (clobber (reg:SI LR_REGNUM))]
8305  "TARGET_32BIT
8306   && !SIBLING_CALL_P (insn)
8307   && (GET_CODE (operands[0]) == SYMBOL_REF)
8308   && !arm_is_long_call_p (SYMBOL_REF_DECL (operands[0]))"
8309  "*
8310  {
8311   rtx op = operands[0];
8312
8313   /* Switch mode now when possible.  */
8314   if (SYMBOL_REF_DECL (op) && !TREE_PUBLIC (SYMBOL_REF_DECL (op))
8315	&& arm_arch5t && arm_change_mode_p (SYMBOL_REF_DECL (op)))
8316      return NEED_PLT_RELOC ? \"blx%?\\t%a0(PLT)\" : \"blx%?\\t(%a0)\";
8317
8318    return NEED_PLT_RELOC ? \"bl%?\\t%a0(PLT)\" : \"bl%?\\t%a0\";
8319  }"
8320  [(set_attr "type" "call")]
8321)
8322
8323(define_insn "*call_value_symbol"
8324  [(set (match_operand 0 "" "")
8325	(call (mem:SI (match_operand:SI 1 "" ""))
8326	(match_operand:SI 2 "" "")))
8327   (use (match_operand 3 "" ""))
8328   (clobber (reg:SI LR_REGNUM))]
8329  "TARGET_32BIT
8330   && !SIBLING_CALL_P (insn)
8331   && (GET_CODE (operands[1]) == SYMBOL_REF)
8332   && !arm_is_long_call_p (SYMBOL_REF_DECL (operands[1]))"
8333  "*
8334  {
8335   rtx op = operands[1];
8336
8337   /* Switch mode now when possible.  */
8338   if (SYMBOL_REF_DECL (op) && !TREE_PUBLIC (SYMBOL_REF_DECL (op))
8339	&& arm_arch5t && arm_change_mode_p (SYMBOL_REF_DECL (op)))
8340      return NEED_PLT_RELOC ? \"blx%?\\t%a1(PLT)\" : \"blx%?\\t(%a1)\";
8341
8342    return NEED_PLT_RELOC ? \"bl%?\\t%a1(PLT)\" : \"bl%?\\t%a1\";
8343  }"
8344  [(set_attr "type" "call")]
8345)
8346
8347(define_expand "sibcall_internal"
8348  [(parallel [(call (match_operand 0 "memory_operand" "")
8349		    (match_operand 1 "general_operand" ""))
8350	      (return)
8351	      (use (match_operand 2 "" ""))])])
8352
8353;; We may also be able to do sibcalls for Thumb, but it's much harder...
8354(define_expand "sibcall"
8355  [(parallel [(call (match_operand 0 "memory_operand" "")
8356		    (match_operand 1 "general_operand" ""))
8357	      (return)
8358	      (use (match_operand 2 "" ""))])]
8359  "TARGET_32BIT"
8360  "
8361  {
8362    rtx pat;
8363
8364    if ((!REG_P (XEXP (operands[0], 0))
8365	 && GET_CODE (XEXP (operands[0], 0)) != SYMBOL_REF)
8366	|| (GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
8367	    && arm_is_long_call_p (SYMBOL_REF_DECL (XEXP (operands[0], 0)))))
8368     XEXP (operands[0], 0) = force_reg (SImode, XEXP (operands[0], 0));
8369
8370    if (operands[2] == NULL_RTX)
8371      operands[2] = const0_rtx;
8372
8373    pat = gen_sibcall_internal (operands[0], operands[1], operands[2]);
8374    arm_emit_call_insn (pat, operands[0], true);
8375    DONE;
8376  }"
8377)
8378
8379(define_expand "sibcall_value_internal"
8380  [(parallel [(set (match_operand 0 "" "")
8381		   (call (match_operand 1 "memory_operand" "")
8382			 (match_operand 2 "general_operand" "")))
8383	      (return)
8384	      (use (match_operand 3 "" ""))])])
8385
8386(define_expand "sibcall_value"
8387  [(parallel [(set (match_operand 0 "" "")
8388		   (call (match_operand 1 "memory_operand" "")
8389			 (match_operand 2 "general_operand" "")))
8390	      (return)
8391	      (use (match_operand 3 "" ""))])]
8392  "TARGET_32BIT"
8393  "
8394  {
8395    rtx pat;
8396
8397    if ((!REG_P (XEXP (operands[1], 0))
8398	 && GET_CODE (XEXP (operands[1], 0)) != SYMBOL_REF)
8399	|| (GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
8400	    && arm_is_long_call_p (SYMBOL_REF_DECL (XEXP (operands[1], 0)))))
8401     XEXP (operands[1], 0) = force_reg (SImode, XEXP (operands[1], 0));
8402
8403    if (operands[3] == NULL_RTX)
8404      operands[3] = const0_rtx;
8405
8406    pat = gen_sibcall_value_internal (operands[0], operands[1],
8407                                      operands[2], operands[3]);
8408    arm_emit_call_insn (pat, operands[1], true);
8409    DONE;
8410  }"
8411)
8412
8413(define_insn "*sibcall_insn"
8414 [(call (mem:SI (match_operand:SI 0 "call_insn_operand" "Cs, US"))
8415	(match_operand 1 "" ""))
8416  (return)
8417  (use (match_operand 2 "" ""))]
8418  "TARGET_32BIT && SIBLING_CALL_P (insn)"
8419  "*
8420  if (which_alternative == 1)
8421    return NEED_PLT_RELOC ? \"b%?\\t%a0(PLT)\" : \"b%?\\t%a0\";
8422  else
8423    {
8424      if (arm_arch5t || arm_arch4t)
8425	return \"bx%?\\t%0\\t%@ indirect register sibling call\";
8426      else
8427	return \"mov%?\\t%|pc, %0\\t%@ indirect register sibling call\";
8428    }
8429  "
8430  [(set_attr "type" "call")]
8431)
8432
8433(define_insn "*sibcall_value_insn"
8434 [(set (match_operand 0 "" "")
8435       (call (mem:SI (match_operand:SI 1 "call_insn_operand" "Cs,US"))
8436	     (match_operand 2 "" "")))
8437  (return)
8438  (use (match_operand 3 "" ""))]
8439  "TARGET_32BIT && SIBLING_CALL_P (insn)"
8440  "*
8441  if (which_alternative == 1)
8442   return NEED_PLT_RELOC ? \"b%?\\t%a1(PLT)\" : \"b%?\\t%a1\";
8443  else
8444    {
8445      if (arm_arch5t || arm_arch4t)
8446	return \"bx%?\\t%1\";
8447      else
8448	return \"mov%?\\t%|pc, %1\\t@ indirect sibling call \";
8449    }
8450  "
8451  [(set_attr "type" "call")]
8452)
8453
8454(define_expand "<return_str>return"
8455  [(RETURNS)]
8456  "(TARGET_ARM || (TARGET_THUMB2
8457                   && ARM_FUNC_TYPE (arm_current_func_type ()) == ARM_FT_NORMAL
8458                   && !IS_STACKALIGN (arm_current_func_type ())))
8459    <return_cond_false>"
8460  "
8461  {
8462    if (TARGET_THUMB2)
8463      {
8464        thumb2_expand_return (<return_simple_p>);
8465        DONE;
8466      }
8467  }
8468  "
8469)
8470
8471;; Often the return insn will be the same as loading from memory, so set attr
8472(define_insn "*arm_return"
8473  [(return)]
8474  "TARGET_ARM && USE_RETURN_INSN (FALSE)"
8475  "*
8476  {
8477    if (arm_ccfsm_state == 2)
8478      {
8479        arm_ccfsm_state += 2;
8480        return \"\";
8481      }
8482    return output_return_instruction (const_true_rtx, true, false, false);
8483  }"
8484  [(set_attr "type" "load_4")
8485   (set_attr "length" "12")
8486   (set_attr "predicable" "yes")]
8487)
8488
8489(define_insn "*cond_<return_str>return"
8490  [(set (pc)
8491        (if_then_else (match_operator 0 "arm_comparison_operator"
8492		       [(match_operand 1 "cc_register" "") (const_int 0)])
8493                      (RETURNS)
8494                      (pc)))]
8495  "TARGET_ARM  <return_cond_true>"
8496  "*
8497  {
8498    if (arm_ccfsm_state == 2)
8499      {
8500        arm_ccfsm_state += 2;
8501        return \"\";
8502      }
8503    return output_return_instruction (operands[0], true, false,
8504				      <return_simple_p>);
8505  }"
8506  [(set_attr "conds" "use")
8507   (set_attr "length" "12")
8508   (set_attr "type" "load_4")]
8509)
8510
8511(define_insn "*cond_<return_str>return_inverted"
8512  [(set (pc)
8513        (if_then_else (match_operator 0 "arm_comparison_operator"
8514		       [(match_operand 1 "cc_register" "") (const_int 0)])
8515                      (pc)
8516		      (RETURNS)))]
8517  "TARGET_ARM <return_cond_true>"
8518  "*
8519  {
8520    if (arm_ccfsm_state == 2)
8521      {
8522        arm_ccfsm_state += 2;
8523        return \"\";
8524      }
8525    return output_return_instruction (operands[0], true, true,
8526				      <return_simple_p>);
8527  }"
8528  [(set_attr "conds" "use")
8529   (set_attr "length" "12")
8530   (set_attr "type" "load_4")]
8531)
8532
8533(define_insn "*arm_simple_return"
8534  [(simple_return)]
8535  "TARGET_ARM"
8536  "*
8537  {
8538    if (arm_ccfsm_state == 2)
8539      {
8540        arm_ccfsm_state += 2;
8541        return \"\";
8542      }
8543    return output_return_instruction (const_true_rtx, true, false, true);
8544  }"
8545  [(set_attr "type" "branch")
8546   (set_attr "length" "4")
8547   (set_attr "predicable" "yes")]
8548)
8549
8550;; Generate a sequence of instructions to determine if the processor is
8551;; in 26-bit or 32-bit mode, and return the appropriate return address
8552;; mask.
8553
8554(define_expand "return_addr_mask"
8555  [(set (match_dup 1)
8556      (compare:CC_NOOV (unspec [(const_int 0)] UNSPEC_CHECK_ARCH)
8557		       (const_int 0)))
8558   (set (match_operand:SI 0 "s_register_operand" "")
8559      (if_then_else:SI (eq (match_dup 1) (const_int 0))
8560		       (const_int -1)
8561		       (const_int 67108860)))] ; 0x03fffffc
8562  "TARGET_ARM"
8563  "
8564  operands[1] = gen_rtx_REG (CC_NOOVmode, CC_REGNUM);
8565  ")
8566
8567(define_insn "*check_arch2"
8568  [(set (match_operand:CC_NOOV 0 "cc_register" "")
8569      (compare:CC_NOOV (unspec [(const_int 0)] UNSPEC_CHECK_ARCH)
8570		       (const_int 0)))]
8571  "TARGET_ARM"
8572  "teq\\t%|r0, %|r0\;teq\\t%|pc, %|pc"
8573  [(set_attr "length" "8")
8574   (set_attr "conds" "set")
8575   (set_attr "type" "multiple")]
8576)
8577
8578;; Call subroutine returning any type.
8579
8580(define_expand "untyped_call"
8581  [(parallel [(call (match_operand 0 "" "")
8582		    (const_int 0))
8583	      (match_operand 1 "" "")
8584	      (match_operand 2 "" "")])]
8585  "TARGET_EITHER"
8586  "
8587  {
8588    int i;
8589    rtx par = gen_rtx_PARALLEL (VOIDmode,
8590				rtvec_alloc (XVECLEN (operands[2], 0)));
8591    rtx addr = gen_reg_rtx (Pmode);
8592    rtx mem;
8593    int size = 0;
8594
8595    emit_move_insn (addr, XEXP (operands[1], 0));
8596    mem = change_address (operands[1], BLKmode, addr);
8597
8598    for (i = 0; i < XVECLEN (operands[2], 0); i++)
8599      {
8600	rtx src = SET_SRC (XVECEXP (operands[2], 0, i));
8601
8602	/* Default code only uses r0 as a return value, but we could
8603	   be using anything up to 4 registers.  */
8604	if (REGNO (src) == R0_REGNUM)
8605	  src = gen_rtx_REG (TImode, R0_REGNUM);
8606
8607        XVECEXP (par, 0, i) = gen_rtx_EXPR_LIST (VOIDmode, src,
8608						 GEN_INT (size));
8609        size += GET_MODE_SIZE (GET_MODE (src));
8610      }
8611
8612    emit_call_insn (gen_call_value (par, operands[0], const0_rtx, NULL));
8613
8614    size = 0;
8615
8616    for (i = 0; i < XVECLEN (par, 0); i++)
8617      {
8618	HOST_WIDE_INT offset = 0;
8619	rtx reg = XEXP (XVECEXP (par, 0, i), 0);
8620
8621	if (size != 0)
8622	  emit_move_insn (addr, plus_constant (Pmode, addr, size));
8623
8624	mem = change_address (mem, GET_MODE (reg), NULL);
8625	if (REGNO (reg) == R0_REGNUM)
8626	  {
8627	    /* On thumb we have to use a write-back instruction.  */
8628	    emit_insn (arm_gen_store_multiple (arm_regs_in_sequence, 4, addr,
8629 		       TARGET_THUMB ? TRUE : FALSE, mem, &offset));
8630	    size = TARGET_ARM ? 16 : 0;
8631	  }
8632	else
8633	  {
8634	    emit_move_insn (mem, reg);
8635	    size = GET_MODE_SIZE (GET_MODE (reg));
8636	  }
8637      }
8638
8639    /* The optimizer does not know that the call sets the function value
8640       registers we stored in the result block.  We avoid problems by
8641       claiming that all hard registers are used and clobbered at this
8642       point.  */
8643    emit_insn (gen_blockage ());
8644
8645    DONE;
8646  }"
8647)
8648
8649(define_expand "untyped_return"
8650  [(match_operand:BLK 0 "memory_operand" "")
8651   (match_operand 1 "" "")]
8652  "TARGET_EITHER"
8653  "
8654  {
8655    int i;
8656    rtx addr = gen_reg_rtx (Pmode);
8657    rtx mem;
8658    int size = 0;
8659
8660    emit_move_insn (addr, XEXP (operands[0], 0));
8661    mem = change_address (operands[0], BLKmode, addr);
8662
8663    for (i = 0; i < XVECLEN (operands[1], 0); i++)
8664      {
8665	HOST_WIDE_INT offset = 0;
8666	rtx reg = SET_DEST (XVECEXP (operands[1], 0, i));
8667
8668	if (size != 0)
8669	  emit_move_insn (addr, plus_constant (Pmode, addr, size));
8670
8671	mem = change_address (mem, GET_MODE (reg), NULL);
8672	if (REGNO (reg) == R0_REGNUM)
8673	  {
8674	    /* On thumb we have to use a write-back instruction.  */
8675	    emit_insn (arm_gen_load_multiple (arm_regs_in_sequence, 4, addr,
8676 		       TARGET_THUMB ? TRUE : FALSE, mem, &offset));
8677	    size = TARGET_ARM ? 16 : 0;
8678	  }
8679	else
8680	  {
8681	    emit_move_insn (reg, mem);
8682	    size = GET_MODE_SIZE (GET_MODE (reg));
8683	  }
8684      }
8685
8686    /* Emit USE insns before the return.  */
8687    for (i = 0; i < XVECLEN (operands[1], 0); i++)
8688      emit_use (SET_DEST (XVECEXP (operands[1], 0, i)));
8689
8690    /* Construct the return.  */
8691    expand_naked_return ();
8692
8693    DONE;
8694  }"
8695)
8696
8697;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
8698;; all of memory.  This blocks insns from being moved across this point.
8699
8700(define_insn "blockage"
8701  [(unspec_volatile [(const_int 0)] VUNSPEC_BLOCKAGE)]
8702  "TARGET_EITHER"
8703  ""
8704  [(set_attr "length" "0")
8705   (set_attr "type" "block")]
8706)
8707
8708;; Since we hard code r0 here use the 'o' constraint to prevent
8709;; provoking undefined behaviour in the hardware with putting out
8710;; auto-increment operations with potentially r0 as the base register.
8711(define_insn "probe_stack"
8712  [(set (match_operand:SI 0 "memory_operand" "=o")
8713        (unspec:SI [(const_int 0)] UNSPEC_PROBE_STACK))]
8714  "TARGET_32BIT"
8715  "str%?\\tr0, %0"
8716  [(set_attr "type" "store_4")
8717   (set_attr "predicable" "yes")]
8718)
8719
8720(define_insn "probe_stack_range"
8721  [(set (match_operand:SI 0 "register_operand" "=r")
8722	(unspec_volatile:SI [(match_operand:SI 1 "register_operand" "0")
8723			     (match_operand:SI 2 "register_operand" "r")]
8724			     VUNSPEC_PROBE_STACK_RANGE))]
8725  "TARGET_32BIT"
8726{
8727  return output_probe_stack_range (operands[0], operands[2]);
8728}
8729  [(set_attr "type" "multiple")
8730   (set_attr "conds" "clob")]
8731)
8732
8733;; Named patterns for stack smashing protection.
8734(define_expand "stack_protect_combined_set"
8735  [(parallel
8736     [(set (match_operand:SI 0 "memory_operand" "")
8737	   (unspec:SI [(match_operand:SI 1 "guard_operand" "")]
8738		      UNSPEC_SP_SET))
8739      (clobber (match_scratch:SI 2 ""))
8740      (clobber (match_scratch:SI 3 ""))])]
8741  ""
8742  ""
8743)
8744
8745;; Use a separate insn from the above expand to be able to have the mem outside
8746;; the operand #1 when register allocation comes. This is needed to avoid LRA
8747;; try to reload the guard since we need to control how PIC access is done in
8748;; the -fpic/-fPIC case (see COMPUTE_NOW parameter when calling
8749;; legitimize_pic_address ()).
8750(define_insn_and_split "*stack_protect_combined_set_insn"
8751  [(set (match_operand:SI 0 "memory_operand" "=m,m")
8752	(unspec:SI [(mem:SI (match_operand:SI 1 "guard_addr_operand" "X,X"))]
8753		   UNSPEC_SP_SET))
8754   (clobber (match_scratch:SI 2 "=&l,&r"))
8755   (clobber (match_scratch:SI 3 "=&l,&r"))]
8756  ""
8757  "#"
8758  "reload_completed"
8759  [(parallel [(set (match_dup 0) (unspec:SI [(mem:SI (match_dup 2))]
8760					    UNSPEC_SP_SET))
8761	      (clobber (match_dup 2))])]
8762  "
8763{
8764  if (flag_pic)
8765    {
8766      /* Forces recomputing of GOT base now.  */
8767      legitimize_pic_address (operands[1], SImode, operands[2], operands[3],
8768			      true /*compute_now*/);
8769    }
8770  else
8771    {
8772      if (address_operand (operands[1], SImode))
8773	operands[2] = operands[1];
8774      else
8775	{
8776	  rtx mem = XEXP (force_const_mem (SImode, operands[1]), 0);
8777	  emit_move_insn (operands[2], mem);
8778	}
8779    }
8780}"
8781  [(set_attr "arch" "t1,32")]
8782)
8783
8784(define_insn "*stack_protect_set_insn"
8785  [(set (match_operand:SI 0 "memory_operand" "=m,m")
8786	(unspec:SI [(mem:SI (match_operand:SI 1 "register_operand" "+&l,&r"))]
8787	 UNSPEC_SP_SET))
8788   (clobber (match_dup 1))]
8789  ""
8790  "@
8791   ldr\\t%1, [%1]\;str\\t%1, %0\;movs\t%1,#0
8792   ldr\\t%1, [%1]\;str\\t%1, %0\;mov\t%1,#0"
8793  [(set_attr "length" "8,12")
8794   (set_attr "conds" "clob,nocond")
8795   (set_attr "type" "multiple")
8796   (set_attr "arch" "t1,32")]
8797)
8798
8799(define_expand "stack_protect_combined_test"
8800  [(parallel
8801     [(set (pc)
8802	   (if_then_else
8803		(eq (match_operand:SI 0 "memory_operand" "")
8804		    (unspec:SI [(match_operand:SI 1 "guard_operand" "")]
8805			       UNSPEC_SP_TEST))
8806		(label_ref (match_operand 2))
8807		(pc)))
8808      (clobber (match_scratch:SI 3 ""))
8809      (clobber (match_scratch:SI 4 ""))
8810      (clobber (reg:CC CC_REGNUM))])]
8811  ""
8812  ""
8813)
8814
8815;; Use a separate insn from the above expand to be able to have the mem outside
8816;; the operand #1 when register allocation comes. This is needed to avoid LRA
8817;; try to reload the guard since we need to control how PIC access is done in
8818;; the -fpic/-fPIC case (see COMPUTE_NOW parameter when calling
8819;; legitimize_pic_address ()).
8820(define_insn_and_split "*stack_protect_combined_test_insn"
8821  [(set (pc)
8822	(if_then_else
8823		(eq (match_operand:SI 0 "memory_operand" "m,m")
8824		    (unspec:SI [(mem:SI (match_operand:SI 1 "guard_addr_operand" "X,X"))]
8825			       UNSPEC_SP_TEST))
8826		(label_ref (match_operand 2))
8827		(pc)))
8828   (clobber (match_scratch:SI 3 "=&l,&r"))
8829   (clobber (match_scratch:SI 4 "=&l,&r"))
8830   (clobber (reg:CC CC_REGNUM))]
8831  ""
8832  "#"
8833  "reload_completed"
8834  [(const_int 0)]
8835{
8836  rtx eq;
8837
8838  if (flag_pic)
8839    {
8840      /* Forces recomputing of GOT base now.  */
8841      legitimize_pic_address (operands[1], SImode, operands[3], operands[4],
8842			      true /*compute_now*/);
8843    }
8844  else
8845    {
8846      if (address_operand (operands[1], SImode))
8847	operands[3] = operands[1];
8848      else
8849	{
8850	  rtx mem = XEXP (force_const_mem (SImode, operands[1]), 0);
8851	  emit_move_insn (operands[3], mem);
8852	}
8853    }
8854  if (TARGET_32BIT)
8855    {
8856      emit_insn (gen_arm_stack_protect_test_insn (operands[4], operands[0],
8857						  operands[3]));
8858      rtx cc_reg = gen_rtx_REG (CC_Zmode, CC_REGNUM);
8859      eq = gen_rtx_EQ (CC_Zmode, cc_reg, const0_rtx);
8860      emit_jump_insn (gen_arm_cond_branch (operands[2], eq, cc_reg));
8861    }
8862  else
8863    {
8864      emit_insn (gen_thumb1_stack_protect_test_insn (operands[4], operands[0],
8865						     operands[3]));
8866      eq = gen_rtx_EQ (VOIDmode, operands[4], const0_rtx);
8867      emit_jump_insn (gen_cbranchsi4 (eq, operands[4], const0_rtx,
8868				      operands[2]));
8869    }
8870  DONE;
8871}
8872  [(set_attr "arch" "t1,32")]
8873)
8874
8875(define_insn "arm_stack_protect_test_insn"
8876  [(set (reg:CC_Z CC_REGNUM)
8877	(compare:CC_Z (unspec:SI [(match_operand:SI 1 "memory_operand" "m,m")
8878				  (mem:SI (match_operand:SI 2 "register_operand" "+l,r"))]
8879				 UNSPEC_SP_TEST)
8880		      (const_int 0)))
8881   (clobber (match_operand:SI 0 "register_operand" "=&l,&r"))
8882   (clobber (match_dup 2))]
8883  "TARGET_32BIT"
8884  "ldr\t%0, [%2]\;ldr\t%2, %1\;eors\t%0, %2, %0"
8885  [(set_attr "length" "8,12")
8886   (set_attr "conds" "set")
8887   (set_attr "type" "multiple")
8888   (set_attr "arch" "t,32")]
8889)
8890
8891(define_expand "casesi"
8892  [(match_operand:SI 0 "s_register_operand" "")	; index to jump on
8893   (match_operand:SI 1 "const_int_operand" "")	; lower bound
8894   (match_operand:SI 2 "const_int_operand" "")	; total range
8895   (match_operand:SI 3 "" "")			; table label
8896   (match_operand:SI 4 "" "")]			; Out of range label
8897  "(TARGET_32BIT || optimize_size || flag_pic) && !target_pure_code"
8898  "
8899  {
8900    enum insn_code code;
8901    if (operands[1] != const0_rtx)
8902      {
8903	rtx reg = gen_reg_rtx (SImode);
8904
8905	emit_insn (gen_addsi3 (reg, operands[0],
8906			       gen_int_mode (-INTVAL (operands[1]),
8907			       		     SImode)));
8908	operands[0] = reg;
8909      }
8910
8911    if (TARGET_ARM)
8912      code = CODE_FOR_arm_casesi_internal;
8913    else if (TARGET_THUMB1)
8914      code = CODE_FOR_thumb1_casesi_internal_pic;
8915    else if (flag_pic)
8916      code = CODE_FOR_thumb2_casesi_internal_pic;
8917    else
8918      code = CODE_FOR_thumb2_casesi_internal;
8919
8920    if (!insn_data[(int) code].operand[1].predicate(operands[2], SImode))
8921      operands[2] = force_reg (SImode, operands[2]);
8922
8923    emit_jump_insn (GEN_FCN ((int) code) (operands[0], operands[2],
8924					  operands[3], operands[4]));
8925    DONE;
8926  }"
8927)
8928
8929;; The USE in this pattern is needed to tell flow analysis that this is
8930;; a CASESI insn.  It has no other purpose.
8931(define_expand "arm_casesi_internal"
8932  [(parallel [(set (pc)
8933	       (if_then_else
8934		(leu (match_operand:SI 0 "s_register_operand")
8935		     (match_operand:SI 1 "arm_rhs_operand"))
8936		(match_dup 4)
8937		(label_ref:SI (match_operand 3 ""))))
8938	      (clobber (reg:CC CC_REGNUM))
8939	      (use (label_ref:SI (match_operand 2 "")))])]
8940  "TARGET_ARM"
8941{
8942  operands[4] = gen_rtx_MULT (SImode, operands[0], GEN_INT (4));
8943  operands[4] = gen_rtx_PLUS (SImode, operands[4],
8944			      gen_rtx_LABEL_REF (SImode, operands[2]));
8945  operands[4] = gen_rtx_MEM (SImode, operands[4]);
8946  MEM_READONLY_P (operands[4]) = 1;
8947  MEM_NOTRAP_P (operands[4]) = 1;
8948})
8949
8950(define_insn "*arm_casesi_internal"
8951  [(parallel [(set (pc)
8952	       (if_then_else
8953		(leu (match_operand:SI 0 "s_register_operand" "r")
8954		     (match_operand:SI 1 "arm_rhs_operand" "rI"))
8955		(mem:SI (plus:SI (mult:SI (match_dup 0) (const_int 4))
8956				 (label_ref:SI (match_operand 2 "" ""))))
8957		(label_ref:SI (match_operand 3 "" ""))))
8958	      (clobber (reg:CC CC_REGNUM))
8959	      (use (label_ref:SI (match_dup 2)))])]
8960  "TARGET_ARM"
8961  "*
8962    if (flag_pic)
8963      return \"cmp\\t%0, %1\;addls\\t%|pc, %|pc, %0, asl #2\;b\\t%l3\";
8964    return   \"cmp\\t%0, %1\;ldrls\\t%|pc, [%|pc, %0, asl #2]\;b\\t%l3\";
8965  "
8966  [(set_attr "conds" "clob")
8967   (set_attr "length" "12")
8968   (set_attr "type" "multiple")]
8969)
8970
8971(define_expand "indirect_jump"
8972  [(set (pc)
8973	(match_operand:SI 0 "s_register_operand" ""))]
8974  "TARGET_EITHER"
8975  "
8976  /* Thumb-2 doesn't have mov pc, reg.  Explicitly set the low bit of the
8977     address and use bx.  */
8978  if (TARGET_THUMB2)
8979    {
8980      rtx tmp;
8981      tmp = gen_reg_rtx (SImode);
8982      emit_insn (gen_iorsi3 (tmp, operands[0], GEN_INT(1)));
8983      operands[0] = tmp;
8984    }
8985  "
8986)
8987
8988;; NB Never uses BX.
8989(define_insn "*arm_indirect_jump"
8990  [(set (pc)
8991	(match_operand:SI 0 "s_register_operand" "r"))]
8992  "TARGET_ARM"
8993  "mov%?\\t%|pc, %0\\t%@ indirect register jump"
8994  [(set_attr "predicable" "yes")
8995   (set_attr "type" "branch")]
8996)
8997
8998(define_insn "*load_indirect_jump"
8999  [(set (pc)
9000	(match_operand:SI 0 "memory_operand" "m"))]
9001  "TARGET_ARM"
9002  "ldr%?\\t%|pc, %0\\t%@ indirect memory jump"
9003  [(set_attr "type" "load_4")
9004   (set_attr "pool_range" "4096")
9005   (set_attr "neg_pool_range" "4084")
9006   (set_attr "predicable" "yes")]
9007)
9008
9009
9010;; Misc insns
9011
9012(define_insn "nop"
9013  [(const_int 0)]
9014  "TARGET_EITHER"
9015  "nop"
9016  [(set (attr "length")
9017	(if_then_else (eq_attr "is_thumb" "yes")
9018		      (const_int 2)
9019		      (const_int 4)))
9020   (set_attr "type" "mov_reg")]
9021)
9022
9023(define_insn "trap"
9024  [(trap_if (const_int 1) (const_int 0))]
9025  ""
9026  "*
9027  if (TARGET_ARM)
9028    return \".inst\\t0xe7f000f0\";
9029  else
9030    return \".inst\\t0xdeff\";
9031  "
9032  [(set (attr "length")
9033	(if_then_else (eq_attr "is_thumb" "yes")
9034		      (const_int 2)
9035		      (const_int 4)))
9036   (set_attr "type" "trap")
9037   (set_attr "conds" "unconditional")]
9038)
9039
9040
9041;; Patterns to allow combination of arithmetic, cond code and shifts
9042
9043(define_insn "*<arith_shift_insn>_multsi"
9044  [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9045	(SHIFTABLE_OPS:SI
9046	 (mult:SI (match_operand:SI 2 "s_register_operand" "r,r")
9047		  (match_operand:SI 3 "power_of_two_operand" ""))
9048	 (match_operand:SI 1 "s_register_operand" "rk,<t2_binop0>")))]
9049  "TARGET_32BIT"
9050  "<arith_shift_insn>%?\\t%0, %1, %2, lsl %b3"
9051  [(set_attr "predicable" "yes")
9052   (set_attr "shift" "2")
9053   (set_attr "arch" "a,t2")
9054   (set_attr "type" "alu_shift_imm")])
9055
9056(define_insn "*<arith_shift_insn>_shiftsi"
9057  [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9058	(SHIFTABLE_OPS:SI
9059	 (match_operator:SI 2 "shift_nomul_operator"
9060	  [(match_operand:SI 3 "s_register_operand" "r,r,r")
9061	   (match_operand:SI 4 "shift_amount_operand" "M,M,r")])
9062	 (match_operand:SI 1 "s_register_operand" "rk,<t2_binop0>,rk")))]
9063  "TARGET_32BIT && GET_CODE (operands[2]) != MULT"
9064  "<arith_shift_insn>%?\\t%0, %1, %3%S2"
9065  [(set_attr "predicable" "yes")
9066   (set_attr "shift" "3")
9067   (set_attr "arch" "a,t2,a")
9068   (set_attr "type" "alu_shift_imm,alu_shift_imm,alu_shift_reg")])
9069
9070(define_split
9071  [(set (match_operand:SI 0 "s_register_operand" "")
9072	(match_operator:SI 1 "shiftable_operator"
9073	 [(match_operator:SI 2 "shiftable_operator"
9074	   [(match_operator:SI 3 "shift_operator"
9075	     [(match_operand:SI 4 "s_register_operand" "")
9076	      (match_operand:SI 5 "reg_or_int_operand" "")])
9077	    (match_operand:SI 6 "s_register_operand" "")])
9078	  (match_operand:SI 7 "arm_rhs_operand" "")]))
9079   (clobber (match_operand:SI 8 "s_register_operand" ""))]
9080  "TARGET_32BIT"
9081  [(set (match_dup 8)
9082	(match_op_dup 2 [(match_op_dup 3 [(match_dup 4) (match_dup 5)])
9083			 (match_dup 6)]))
9084   (set (match_dup 0)
9085	(match_op_dup 1 [(match_dup 8) (match_dup 7)]))]
9086  "")
9087
9088(define_insn "*arith_shiftsi_compare0"
9089  [(set (reg:CC_NOOV CC_REGNUM)
9090        (compare:CC_NOOV
9091	 (match_operator:SI 1 "shiftable_operator"
9092	  [(match_operator:SI 3 "shift_operator"
9093	    [(match_operand:SI 4 "s_register_operand" "r,r")
9094	     (match_operand:SI 5 "shift_amount_operand" "M,r")])
9095	   (match_operand:SI 2 "s_register_operand" "r,r")])
9096	 (const_int 0)))
9097   (set (match_operand:SI 0 "s_register_operand" "=r,r")
9098	(match_op_dup 1 [(match_op_dup 3 [(match_dup 4) (match_dup 5)])
9099			 (match_dup 2)]))]
9100  "TARGET_32BIT"
9101  "%i1s%?\\t%0, %2, %4%S3"
9102  [(set_attr "conds" "set")
9103   (set_attr "shift" "4")
9104   (set_attr "arch" "32,a")
9105   (set_attr "type" "alus_shift_imm,alus_shift_reg")])
9106
9107(define_insn "*arith_shiftsi_compare0_scratch"
9108  [(set (reg:CC_NOOV CC_REGNUM)
9109        (compare:CC_NOOV
9110	 (match_operator:SI 1 "shiftable_operator"
9111	  [(match_operator:SI 3 "shift_operator"
9112	    [(match_operand:SI 4 "s_register_operand" "r,r")
9113	     (match_operand:SI 5 "shift_amount_operand" "M,r")])
9114	   (match_operand:SI 2 "s_register_operand" "r,r")])
9115	 (const_int 0)))
9116   (clobber (match_scratch:SI 0 "=r,r"))]
9117  "TARGET_32BIT"
9118  "%i1s%?\\t%0, %2, %4%S3"
9119  [(set_attr "conds" "set")
9120   (set_attr "shift" "4")
9121   (set_attr "arch" "32,a")
9122   (set_attr "type" "alus_shift_imm,alus_shift_reg")])
9123
9124(define_insn "*sub_shiftsi"
9125  [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9126	(minus:SI (match_operand:SI 1 "s_register_operand" "r,r")
9127		  (match_operator:SI 2 "shift_operator"
9128		   [(match_operand:SI 3 "s_register_operand" "r,r")
9129		    (match_operand:SI 4 "shift_amount_operand" "M,r")])))]
9130  "TARGET_32BIT"
9131  "sub%?\\t%0, %1, %3%S2"
9132  [(set_attr "predicable" "yes")
9133   (set_attr "predicable_short_it" "no")
9134   (set_attr "shift" "3")
9135   (set_attr "arch" "32,a")
9136   (set_attr "type" "alus_shift_imm,alus_shift_reg")])
9137
9138(define_insn "*sub_shiftsi_compare0"
9139  [(set (reg:CC_NOOV CC_REGNUM)
9140	(compare:CC_NOOV
9141	 (minus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
9142		   (match_operator:SI 2 "shift_operator"
9143		    [(match_operand:SI 3 "s_register_operand" "r,r,r")
9144		     (match_operand:SI 4 "shift_amount_operand" "M,r,M")]))
9145	 (const_int 0)))
9146   (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9147	(minus:SI (match_dup 1)
9148		  (match_op_dup 2 [(match_dup 3) (match_dup 4)])))]
9149  "TARGET_32BIT"
9150  "subs%?\\t%0, %1, %3%S2"
9151  [(set_attr "conds" "set")
9152   (set_attr "shift" "3")
9153   (set_attr "arch" "32,a,a")
9154   (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
9155
9156(define_insn "*sub_shiftsi_compare0_scratch"
9157  [(set (reg:CC_NOOV CC_REGNUM)
9158	(compare:CC_NOOV
9159	 (minus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
9160		   (match_operator:SI 2 "shift_operator"
9161		    [(match_operand:SI 3 "s_register_operand" "r,r,r")
9162		     (match_operand:SI 4 "shift_amount_operand" "M,r,M")]))
9163	 (const_int 0)))
9164   (clobber (match_scratch:SI 0 "=r,r,r"))]
9165  "TARGET_32BIT"
9166  "subs%?\\t%0, %1, %3%S2"
9167  [(set_attr "conds" "set")
9168   (set_attr "shift" "3")
9169   (set_attr "arch" "32,a,a")
9170   (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
9171
9172
9173(define_insn_and_split "*and_scc"
9174  [(set (match_operand:SI 0 "s_register_operand" "=r")
9175	(and:SI (match_operator:SI 1 "arm_comparison_operator"
9176		 [(match_operand 2 "cc_register" "") (const_int 0)])
9177		(match_operand:SI 3 "s_register_operand" "r")))]
9178  "TARGET_ARM"
9179  "#"   ; "mov%D1\\t%0, #0\;and%d1\\t%0, %3, #1"
9180  "&& reload_completed"
9181  [(cond_exec (match_dup 5) (set (match_dup 0) (const_int 0)))
9182   (cond_exec (match_dup 4) (set (match_dup 0)
9183                                 (and:SI (match_dup 3) (const_int 1))))]
9184  {
9185    machine_mode mode = GET_MODE (operands[2]);
9186    enum rtx_code rc = GET_CODE (operands[1]);
9187
9188    /* Note that operands[4] is the same as operands[1],
9189       but with VOIDmode as the result. */
9190    operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
9191    if (mode == CCFPmode || mode == CCFPEmode)
9192      rc = reverse_condition_maybe_unordered (rc);
9193    else
9194      rc = reverse_condition (rc);
9195    operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
9196  }
9197  [(set_attr "conds" "use")
9198   (set_attr "type" "multiple")
9199   (set_attr "length" "8")]
9200)
9201
9202(define_insn_and_split "*ior_scc"
9203  [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9204	(ior:SI (match_operator:SI 1 "arm_comparison_operator"
9205		 [(match_operand 2 "cc_register" "") (const_int 0)])
9206		(match_operand:SI 3 "s_register_operand" "0,?r")))]
9207  "TARGET_ARM"
9208  "@
9209   orr%d1\\t%0, %3, #1
9210   #"
9211  "&& reload_completed
9212   && REGNO (operands [0]) != REGNO (operands[3])"
9213  ;; && which_alternative == 1
9214  ; mov%D1\\t%0, %3\;orr%d1\\t%0, %3, #1
9215  [(cond_exec (match_dup 5) (set (match_dup 0) (match_dup 3)))
9216   (cond_exec (match_dup 4) (set (match_dup 0)
9217                                 (ior:SI (match_dup 3) (const_int 1))))]
9218  {
9219    machine_mode mode = GET_MODE (operands[2]);
9220    enum rtx_code rc = GET_CODE (operands[1]);
9221
9222    /* Note that operands[4] is the same as operands[1],
9223       but with VOIDmode as the result. */
9224    operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
9225    if (mode == CCFPmode || mode == CCFPEmode)
9226      rc = reverse_condition_maybe_unordered (rc);
9227    else
9228      rc = reverse_condition (rc);
9229    operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
9230  }
9231  [(set_attr "conds" "use")
9232   (set_attr "length" "4,8")
9233   (set_attr "type" "logic_imm,multiple")]
9234)
9235
9236; A series of splitters for the compare_scc pattern below.  Note that
9237; order is important.
9238(define_split
9239  [(set (match_operand:SI 0 "s_register_operand" "")
9240	(lt:SI (match_operand:SI 1 "s_register_operand" "")
9241	       (const_int 0)))
9242   (clobber (reg:CC CC_REGNUM))]
9243  "TARGET_32BIT && reload_completed"
9244  [(set (match_dup 0) (lshiftrt:SI (match_dup 1) (const_int 31)))])
9245
9246(define_split
9247  [(set (match_operand:SI 0 "s_register_operand" "")
9248	(ge:SI (match_operand:SI 1 "s_register_operand" "")
9249	       (const_int 0)))
9250   (clobber (reg:CC CC_REGNUM))]
9251  "TARGET_32BIT && reload_completed"
9252  [(set (match_dup 0) (not:SI (match_dup 1)))
9253   (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 31)))])
9254
9255(define_split
9256  [(set (match_operand:SI 0 "s_register_operand" "")
9257	(eq:SI (match_operand:SI 1 "s_register_operand" "")
9258	       (const_int 0)))
9259   (clobber (reg:CC CC_REGNUM))]
9260  "arm_arch5t && TARGET_32BIT"
9261  [(set (match_dup 0) (clz:SI (match_dup 1)))
9262   (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
9263)
9264
9265(define_split
9266  [(set (match_operand:SI 0 "s_register_operand" "")
9267	(eq:SI (match_operand:SI 1 "s_register_operand" "")
9268	       (const_int 0)))
9269   (clobber (reg:CC CC_REGNUM))]
9270  "TARGET_32BIT && reload_completed"
9271  [(parallel
9272    [(set (reg:CC CC_REGNUM)
9273	  (compare:CC (const_int 1) (match_dup 1)))
9274     (set (match_dup 0)
9275	  (minus:SI (const_int 1) (match_dup 1)))])
9276   (cond_exec (ltu:CC (reg:CC CC_REGNUM) (const_int 0))
9277	      (set (match_dup 0) (const_int 0)))])
9278
9279(define_split
9280  [(set (match_operand:SI 0 "s_register_operand" "")
9281	(ne:SI (match_operand:SI 1 "s_register_operand" "")
9282	       (match_operand:SI 2 "const_int_operand" "")))
9283   (clobber (reg:CC CC_REGNUM))]
9284  "TARGET_32BIT && reload_completed"
9285  [(parallel
9286    [(set (reg:CC CC_REGNUM)
9287	  (compare:CC (match_dup 1) (match_dup 2)))
9288     (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 3)))])
9289   (cond_exec (ne:CC (reg:CC CC_REGNUM) (const_int 0))
9290	      (set (match_dup 0) (const_int 1)))]
9291{
9292  operands[3] = gen_int_mode (-INTVAL (operands[2]), SImode);
9293})
9294
9295(define_split
9296  [(set (match_operand:SI 0 "s_register_operand" "")
9297	(ne:SI (match_operand:SI 1 "s_register_operand" "")
9298	       (match_operand:SI 2 "arm_add_operand" "")))
9299   (clobber (reg:CC CC_REGNUM))]
9300  "TARGET_32BIT && reload_completed"
9301  [(parallel
9302    [(set (reg:CC_NOOV CC_REGNUM)
9303	  (compare:CC_NOOV (minus:SI (match_dup 1) (match_dup 2))
9304			   (const_int 0)))
9305     (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
9306   (cond_exec (ne:CC_NOOV (reg:CC_NOOV CC_REGNUM) (const_int 0))
9307	      (set (match_dup 0) (const_int 1)))])
9308
9309(define_insn_and_split "*compare_scc"
9310  [(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts")
9311	(match_operator:SI 1 "arm_comparison_operator"
9312	 [(match_operand:SI 2 "s_register_operand" "r,r")
9313	  (match_operand:SI 3 "arm_add_operand" "rI,L")]))
9314   (clobber (reg:CC CC_REGNUM))]
9315  "TARGET_32BIT"
9316  "#"
9317  "&& reload_completed"
9318  [(set (reg:CC CC_REGNUM) (compare:CC (match_dup 2) (match_dup 3)))
9319   (cond_exec (match_dup 4) (set (match_dup 0) (const_int 0)))
9320   (cond_exec (match_dup 5) (set (match_dup 0) (const_int 1)))]
9321{
9322  rtx tmp1;
9323  machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
9324					   operands[2], operands[3]);
9325  enum rtx_code rc = GET_CODE (operands[1]);
9326
9327  tmp1 = gen_rtx_REG (mode, CC_REGNUM);
9328
9329  operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, tmp1, const0_rtx);
9330  if (mode == CCFPmode || mode == CCFPEmode)
9331    rc = reverse_condition_maybe_unordered (rc);
9332  else
9333    rc = reverse_condition (rc);
9334  operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, tmp1, const0_rtx);
9335}
9336  [(set_attr "type" "multiple")]
9337)
9338
9339;; Attempt to improve the sequence generated by the compare_scc splitters
9340;; not to use conditional execution.
9341
9342;; Rd = (eq (reg1) (const_int0))  // ARMv5
9343;;	clz Rd, reg1
9344;;	lsr Rd, Rd, #5
9345(define_peephole2
9346  [(set (reg:CC CC_REGNUM)
9347	(compare:CC (match_operand:SI 1 "register_operand" "")
9348		    (const_int 0)))
9349   (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
9350	      (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
9351   (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
9352	      (set (match_dup 0) (const_int 1)))]
9353  "arm_arch5t && TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
9354  [(set (match_dup 0) (clz:SI (match_dup 1)))
9355   (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
9356)
9357
9358;; Rd = (eq (reg1) (const_int0))  // !ARMv5
9359;;	negs Rd, reg1
9360;;	adc  Rd, Rd, reg1
9361(define_peephole2
9362  [(set (reg:CC CC_REGNUM)
9363	(compare:CC (match_operand:SI 1 "register_operand" "")
9364		    (const_int 0)))
9365   (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
9366	      (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
9367   (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
9368	      (set (match_dup 0) (const_int 1)))
9369   (match_scratch:SI 2 "r")]
9370  "TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
9371  [(parallel
9372    [(set (reg:CC CC_REGNUM)
9373	  (compare:CC (const_int 0) (match_dup 1)))
9374     (set (match_dup 2) (minus:SI (const_int 0) (match_dup 1)))])
9375   (set (match_dup 0)
9376	(plus:SI (plus:SI (match_dup 1) (match_dup 2))
9377		 (geu:SI (reg:CC CC_REGNUM) (const_int 0))))]
9378)
9379
9380;; Rd = (eq (reg1) (reg2/imm))	// ARMv5 and optimising for speed.
9381;;	sub  Rd, Reg1, reg2
9382;;	clz  Rd, Rd
9383;;	lsr  Rd, Rd, #5
9384(define_peephole2
9385  [(set (reg:CC CC_REGNUM)
9386	(compare:CC (match_operand:SI 1 "register_operand" "")
9387		    (match_operand:SI 2 "arm_rhs_operand" "")))
9388   (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
9389	      (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
9390   (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
9391	      (set (match_dup 0) (const_int 1)))]
9392  "arm_arch5t && TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)
9393  && !(TARGET_THUMB2 && optimize_insn_for_size_p ())"
9394  [(set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))
9395   (set (match_dup 0) (clz:SI (match_dup 0)))
9396   (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
9397)
9398
9399
9400;; Rd = (eq (reg1) (reg2))	// ! ARMv5 or optimising for size.
9401;;	sub  T1, Reg1, reg2
9402;;	negs Rd, T1
9403;;	adc  Rd, Rd, T1
9404(define_peephole2
9405  [(set (reg:CC CC_REGNUM)
9406	(compare:CC (match_operand:SI 1 "register_operand" "")
9407		    (match_operand:SI 2 "arm_rhs_operand" "")))
9408   (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
9409	      (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
9410   (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
9411	      (set (match_dup 0) (const_int 1)))
9412   (match_scratch:SI 3 "r")]
9413  "TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
9414  [(set (match_dup 3) (match_dup 4))
9415   (parallel
9416    [(set (reg:CC CC_REGNUM)
9417	  (compare:CC (const_int 0) (match_dup 3)))
9418     (set (match_dup 0) (minus:SI (const_int 0) (match_dup 3)))])
9419   (set (match_dup 0)
9420	(plus:SI (plus:SI (match_dup 0) (match_dup 3))
9421		 (geu:SI (reg:CC CC_REGNUM) (const_int 0))))]
9422  "
9423  if (CONST_INT_P (operands[2]))
9424    operands[4] = plus_constant (SImode, operands[1], -INTVAL (operands[2]));
9425  else
9426    operands[4] = gen_rtx_MINUS (SImode, operands[1], operands[2]);
9427  ")
9428
9429(define_insn "*cond_move"
9430  [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9431	(if_then_else:SI (match_operator 3 "equality_operator"
9432			  [(match_operator 4 "arm_comparison_operator"
9433			    [(match_operand 5 "cc_register" "") (const_int 0)])
9434			   (const_int 0)])
9435			 (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
9436			 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))]
9437  "TARGET_ARM"
9438  "*
9439    if (GET_CODE (operands[3]) == NE)
9440      {
9441        if (which_alternative != 1)
9442	  output_asm_insn (\"mov%D4\\t%0, %2\", operands);
9443        if (which_alternative != 0)
9444	  output_asm_insn (\"mov%d4\\t%0, %1\", operands);
9445        return \"\";
9446      }
9447    if (which_alternative != 0)
9448      output_asm_insn (\"mov%D4\\t%0, %1\", operands);
9449    if (which_alternative != 1)
9450      output_asm_insn (\"mov%d4\\t%0, %2\", operands);
9451    return \"\";
9452  "
9453  [(set_attr "conds" "use")
9454   (set_attr_alternative "type"
9455                         [(if_then_else (match_operand 2 "const_int_operand" "")
9456                                        (const_string "mov_imm")
9457                                        (const_string "mov_reg"))
9458                          (if_then_else (match_operand 1 "const_int_operand" "")
9459                                        (const_string "mov_imm")
9460                                        (const_string "mov_reg"))
9461                          (const_string "multiple")])
9462   (set_attr "length" "4,4,8")]
9463)
9464
9465(define_insn "*cond_arith"
9466  [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9467        (match_operator:SI 5 "shiftable_operator"
9468	 [(match_operator:SI 4 "arm_comparison_operator"
9469           [(match_operand:SI 2 "s_register_operand" "r,r")
9470	    (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
9471          (match_operand:SI 1 "s_register_operand" "0,?r")]))
9472   (clobber (reg:CC CC_REGNUM))]
9473  "TARGET_ARM"
9474  "*
9475    if (GET_CODE (operands[4]) == LT && operands[3] == const0_rtx)
9476      return \"%i5\\t%0, %1, %2, lsr #31\";
9477
9478    output_asm_insn (\"cmp\\t%2, %3\", operands);
9479    if (GET_CODE (operands[5]) == AND)
9480      output_asm_insn (\"mov%D4\\t%0, #0\", operands);
9481    else if (GET_CODE (operands[5]) == MINUS)
9482      output_asm_insn (\"rsb%D4\\t%0, %1, #0\", operands);
9483    else if (which_alternative != 0)
9484      output_asm_insn (\"mov%D4\\t%0, %1\", operands);
9485    return \"%i5%d4\\t%0, %1, #1\";
9486  "
9487  [(set_attr "conds" "clob")
9488   (set_attr "length" "12")
9489   (set_attr "type" "multiple")]
9490)
9491
9492(define_insn "*cond_sub"
9493  [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9494        (minus:SI (match_operand:SI 1 "s_register_operand" "0,?r")
9495		  (match_operator:SI 4 "arm_comparison_operator"
9496                   [(match_operand:SI 2 "s_register_operand" "r,r")
9497		    (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
9498   (clobber (reg:CC CC_REGNUM))]
9499  "TARGET_ARM"
9500  "*
9501    output_asm_insn (\"cmp\\t%2, %3\", operands);
9502    if (which_alternative != 0)
9503      output_asm_insn (\"mov%D4\\t%0, %1\", operands);
9504    return \"sub%d4\\t%0, %1, #1\";
9505  "
9506  [(set_attr "conds" "clob")
9507   (set_attr "length" "8,12")
9508   (set_attr "type" "multiple")]
9509)
9510
9511(define_insn "*cmp_ite0"
9512  [(set (match_operand 6 "dominant_cc_register" "")
9513	(compare
9514	 (if_then_else:SI
9515	  (match_operator 4 "arm_comparison_operator"
9516	   [(match_operand:SI 0 "s_register_operand"
9517	        "l,l,l,r,r,r,r,r,r")
9518	    (match_operand:SI 1 "arm_add_operand"
9519	        "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
9520	  (match_operator:SI 5 "arm_comparison_operator"
9521	   [(match_operand:SI 2 "s_register_operand"
9522	        "l,r,r,l,l,r,r,r,r")
9523	    (match_operand:SI 3 "arm_add_operand"
9524	        "lPy,rI,L,lPy,lPy,rI,rI,L,L")])
9525	  (const_int 0))
9526	 (const_int 0)))]
9527  "TARGET_32BIT"
9528  "*
9529  {
9530    static const char * const cmp1[NUM_OF_COND_CMP][2] =
9531    {
9532      {\"cmp%d5\\t%0, %1\",
9533       \"cmp%d4\\t%2, %3\"},
9534      {\"cmn%d5\\t%0, #%n1\",
9535       \"cmp%d4\\t%2, %3\"},
9536      {\"cmp%d5\\t%0, %1\",
9537       \"cmn%d4\\t%2, #%n3\"},
9538      {\"cmn%d5\\t%0, #%n1\",
9539       \"cmn%d4\\t%2, #%n3\"}
9540    };
9541    static const char * const cmp2[NUM_OF_COND_CMP][2] =
9542    {
9543      {\"cmp\\t%2, %3\",
9544       \"cmp\\t%0, %1\"},
9545      {\"cmp\\t%2, %3\",
9546       \"cmn\\t%0, #%n1\"},
9547      {\"cmn\\t%2, #%n3\",
9548       \"cmp\\t%0, %1\"},
9549      {\"cmn\\t%2, #%n3\",
9550       \"cmn\\t%0, #%n1\"}
9551    };
9552    static const char * const ite[2] =
9553    {
9554      \"it\\t%d5\",
9555      \"it\\t%d4\"
9556    };
9557    static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
9558                                   CMP_CMP, CMN_CMP, CMP_CMP,
9559                                   CMN_CMP, CMP_CMN, CMN_CMN};
9560    int swap =
9561      comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
9562
9563    output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
9564    if (TARGET_THUMB2) {
9565      output_asm_insn (ite[swap], operands);
9566    }
9567    output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
9568    return \"\";
9569  }"
9570  [(set_attr "conds" "set")
9571   (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
9572   (set_attr "enabled_for_short_it" "yes,no,no,no,no,no,no,no,no")
9573   (set_attr "type" "multiple")
9574   (set_attr_alternative "length"
9575      [(const_int 6)
9576       (const_int 8)
9577       (const_int 8)
9578       (const_int 8)
9579       (const_int 8)
9580       (if_then_else (eq_attr "is_thumb" "no")
9581           (const_int 8)
9582           (const_int 10))
9583       (if_then_else (eq_attr "is_thumb" "no")
9584           (const_int 8)
9585           (const_int 10))
9586       (if_then_else (eq_attr "is_thumb" "no")
9587           (const_int 8)
9588           (const_int 10))
9589       (if_then_else (eq_attr "is_thumb" "no")
9590           (const_int 8)
9591           (const_int 10))])]
9592)
9593
9594(define_insn "*cmp_ite1"
9595  [(set (match_operand 6 "dominant_cc_register" "")
9596	(compare
9597	 (if_then_else:SI
9598	  (match_operator 4 "arm_comparison_operator"
9599	   [(match_operand:SI 0 "s_register_operand"
9600	        "l,l,l,r,r,r,r,r,r")
9601	    (match_operand:SI 1 "arm_add_operand"
9602	        "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
9603	  (match_operator:SI 5 "arm_comparison_operator"
9604	   [(match_operand:SI 2 "s_register_operand"
9605	        "l,r,r,l,l,r,r,r,r")
9606	    (match_operand:SI 3 "arm_add_operand"
9607	        "lPy,rI,L,lPy,lPy,rI,rI,L,L")])
9608	  (const_int 1))
9609	 (const_int 0)))]
9610  "TARGET_32BIT"
9611  "*
9612  {
9613    static const char * const cmp1[NUM_OF_COND_CMP][2] =
9614    {
9615      {\"cmp\\t%0, %1\",
9616       \"cmp\\t%2, %3\"},
9617      {\"cmn\\t%0, #%n1\",
9618       \"cmp\\t%2, %3\"},
9619      {\"cmp\\t%0, %1\",
9620       \"cmn\\t%2, #%n3\"},
9621      {\"cmn\\t%0, #%n1\",
9622       \"cmn\\t%2, #%n3\"}
9623    };
9624    static const char * const cmp2[NUM_OF_COND_CMP][2] =
9625    {
9626      {\"cmp%d4\\t%2, %3\",
9627       \"cmp%D5\\t%0, %1\"},
9628      {\"cmp%d4\\t%2, %3\",
9629       \"cmn%D5\\t%0, #%n1\"},
9630      {\"cmn%d4\\t%2, #%n3\",
9631       \"cmp%D5\\t%0, %1\"},
9632      {\"cmn%d4\\t%2, #%n3\",
9633       \"cmn%D5\\t%0, #%n1\"}
9634    };
9635    static const char * const ite[2] =
9636    {
9637      \"it\\t%d4\",
9638      \"it\\t%D5\"
9639    };
9640    static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
9641                                   CMP_CMP, CMN_CMP, CMP_CMP,
9642                                   CMN_CMP, CMP_CMN, CMN_CMN};
9643    int swap =
9644      comparison_dominates_p (GET_CODE (operands[5]),
9645			      reverse_condition (GET_CODE (operands[4])));
9646
9647    output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
9648    if (TARGET_THUMB2) {
9649      output_asm_insn (ite[swap], operands);
9650    }
9651    output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
9652    return \"\";
9653  }"
9654  [(set_attr "conds" "set")
9655   (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
9656   (set_attr "enabled_for_short_it" "yes,no,no,no,no,no,no,no,no")
9657   (set_attr_alternative "length"
9658      [(const_int 6)
9659       (const_int 8)
9660       (const_int 8)
9661       (const_int 8)
9662       (const_int 8)
9663       (if_then_else (eq_attr "is_thumb" "no")
9664           (const_int 8)
9665           (const_int 10))
9666       (if_then_else (eq_attr "is_thumb" "no")
9667           (const_int 8)
9668           (const_int 10))
9669       (if_then_else (eq_attr "is_thumb" "no")
9670           (const_int 8)
9671           (const_int 10))
9672       (if_then_else (eq_attr "is_thumb" "no")
9673           (const_int 8)
9674           (const_int 10))])
9675   (set_attr "type" "multiple")]
9676)
9677
9678(define_insn "*cmp_and"
9679  [(set (match_operand 6 "dominant_cc_register" "")
9680	(compare
9681	 (and:SI
9682	  (match_operator 4 "arm_comparison_operator"
9683	   [(match_operand:SI 0 "s_register_operand"
9684	        "l,l,l,r,r,r,r,r,r")
9685	    (match_operand:SI 1 "arm_add_operand"
9686	        "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
9687	  (match_operator:SI 5 "arm_comparison_operator"
9688	   [(match_operand:SI 2 "s_register_operand"
9689	        "l,r,r,l,l,r,r,r,r")
9690	    (match_operand:SI 3 "arm_add_operand"
9691	        "lPy,rI,L,lPy,lPy,rI,rI,L,L")]))
9692	 (const_int 0)))]
9693  "TARGET_32BIT"
9694  "*
9695  {
9696    static const char *const cmp1[NUM_OF_COND_CMP][2] =
9697    {
9698      {\"cmp%d5\\t%0, %1\",
9699       \"cmp%d4\\t%2, %3\"},
9700      {\"cmn%d5\\t%0, #%n1\",
9701       \"cmp%d4\\t%2, %3\"},
9702      {\"cmp%d5\\t%0, %1\",
9703       \"cmn%d4\\t%2, #%n3\"},
9704      {\"cmn%d5\\t%0, #%n1\",
9705       \"cmn%d4\\t%2, #%n3\"}
9706    };
9707    static const char *const cmp2[NUM_OF_COND_CMP][2] =
9708    {
9709      {\"cmp\\t%2, %3\",
9710       \"cmp\\t%0, %1\"},
9711      {\"cmp\\t%2, %3\",
9712       \"cmn\\t%0, #%n1\"},
9713      {\"cmn\\t%2, #%n3\",
9714       \"cmp\\t%0, %1\"},
9715      {\"cmn\\t%2, #%n3\",
9716       \"cmn\\t%0, #%n1\"}
9717    };
9718    static const char *const ite[2] =
9719    {
9720      \"it\\t%d5\",
9721      \"it\\t%d4\"
9722    };
9723    static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
9724                                   CMP_CMP, CMN_CMP, CMP_CMP,
9725                                   CMN_CMP, CMP_CMN, CMN_CMN};
9726    int swap =
9727      comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
9728
9729    output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
9730    if (TARGET_THUMB2) {
9731      output_asm_insn (ite[swap], operands);
9732    }
9733    output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
9734    return \"\";
9735  }"
9736  [(set_attr "conds" "set")
9737   (set_attr "predicable" "no")
9738   (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
9739   (set_attr "enabled_for_short_it" "yes,no,no,no,no,no,no,no,no")
9740   (set_attr_alternative "length"
9741      [(const_int 6)
9742       (const_int 8)
9743       (const_int 8)
9744       (const_int 8)
9745       (const_int 8)
9746       (if_then_else (eq_attr "is_thumb" "no")
9747           (const_int 8)
9748           (const_int 10))
9749       (if_then_else (eq_attr "is_thumb" "no")
9750           (const_int 8)
9751           (const_int 10))
9752       (if_then_else (eq_attr "is_thumb" "no")
9753           (const_int 8)
9754           (const_int 10))
9755       (if_then_else (eq_attr "is_thumb" "no")
9756           (const_int 8)
9757           (const_int 10))])
9758   (set_attr "type" "multiple")]
9759)
9760
9761(define_insn "*cmp_ior"
9762  [(set (match_operand 6 "dominant_cc_register" "")
9763	(compare
9764	 (ior:SI
9765	  (match_operator 4 "arm_comparison_operator"
9766	   [(match_operand:SI 0 "s_register_operand"
9767	        "l,l,l,r,r,r,r,r,r")
9768	    (match_operand:SI 1 "arm_add_operand"
9769	        "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
9770	  (match_operator:SI 5 "arm_comparison_operator"
9771	   [(match_operand:SI 2 "s_register_operand"
9772	        "l,r,r,l,l,r,r,r,r")
9773	    (match_operand:SI 3 "arm_add_operand"
9774	        "lPy,rI,L,lPy,lPy,rI,rI,L,L")]))
9775	 (const_int 0)))]
9776  "TARGET_32BIT"
9777  "*
9778  {
9779    static const char *const cmp1[NUM_OF_COND_CMP][2] =
9780    {
9781      {\"cmp\\t%0, %1\",
9782       \"cmp\\t%2, %3\"},
9783      {\"cmn\\t%0, #%n1\",
9784       \"cmp\\t%2, %3\"},
9785      {\"cmp\\t%0, %1\",
9786       \"cmn\\t%2, #%n3\"},
9787      {\"cmn\\t%0, #%n1\",
9788       \"cmn\\t%2, #%n3\"}
9789    };
9790    static const char *const cmp2[NUM_OF_COND_CMP][2] =
9791    {
9792      {\"cmp%D4\\t%2, %3\",
9793       \"cmp%D5\\t%0, %1\"},
9794      {\"cmp%D4\\t%2, %3\",
9795       \"cmn%D5\\t%0, #%n1\"},
9796      {\"cmn%D4\\t%2, #%n3\",
9797       \"cmp%D5\\t%0, %1\"},
9798      {\"cmn%D4\\t%2, #%n3\",
9799       \"cmn%D5\\t%0, #%n1\"}
9800    };
9801    static const char *const ite[2] =
9802    {
9803      \"it\\t%D4\",
9804      \"it\\t%D5\"
9805    };
9806    static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
9807                                   CMP_CMP, CMN_CMP, CMP_CMP,
9808                                   CMN_CMP, CMP_CMN, CMN_CMN};
9809    int swap =
9810      comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
9811
9812    output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
9813    if (TARGET_THUMB2) {
9814      output_asm_insn (ite[swap], operands);
9815    }
9816    output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
9817    return \"\";
9818  }
9819  "
9820  [(set_attr "conds" "set")
9821   (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
9822   (set_attr "enabled_for_short_it" "yes,no,no,no,no,no,no,no,no")
9823   (set_attr_alternative "length"
9824      [(const_int 6)
9825       (const_int 8)
9826       (const_int 8)
9827       (const_int 8)
9828       (const_int 8)
9829       (if_then_else (eq_attr "is_thumb" "no")
9830           (const_int 8)
9831           (const_int 10))
9832       (if_then_else (eq_attr "is_thumb" "no")
9833           (const_int 8)
9834           (const_int 10))
9835       (if_then_else (eq_attr "is_thumb" "no")
9836           (const_int 8)
9837           (const_int 10))
9838       (if_then_else (eq_attr "is_thumb" "no")
9839           (const_int 8)
9840           (const_int 10))])
9841   (set_attr "type" "multiple")]
9842)
9843
9844(define_insn_and_split "*ior_scc_scc"
9845  [(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts")
9846	(ior:SI (match_operator:SI 3 "arm_comparison_operator"
9847		 [(match_operand:SI 1 "s_register_operand" "l,r")
9848		  (match_operand:SI 2 "arm_add_operand" "lPy,rIL")])
9849		(match_operator:SI 6 "arm_comparison_operator"
9850		 [(match_operand:SI 4 "s_register_operand" "l,r")
9851		  (match_operand:SI 5 "arm_add_operand" "lPy,rIL")])))
9852   (clobber (reg:CC CC_REGNUM))]
9853  "TARGET_32BIT
9854   && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_OR_Y)
9855       != CCmode)"
9856  "#"
9857  "TARGET_32BIT && reload_completed"
9858  [(set (match_dup 7)
9859	(compare
9860	 (ior:SI
9861	  (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9862	  (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9863	 (const_int 0)))
9864   (set (match_dup 0) (ne:SI (match_dup 7) (const_int 0)))]
9865  "operands[7]
9866     = gen_rtx_REG (arm_select_dominance_cc_mode (operands[3], operands[6],
9867						  DOM_CC_X_OR_Y),
9868		    CC_REGNUM);"
9869  [(set_attr "conds" "clob")
9870   (set_attr "enabled_for_short_it" "yes,no")
9871   (set_attr "length" "16")
9872   (set_attr "type" "multiple")]
9873)
9874
9875; If the above pattern is followed by a CMP insn, then the compare is
9876; redundant, since we can rework the conditional instruction that follows.
9877(define_insn_and_split "*ior_scc_scc_cmp"
9878  [(set (match_operand 0 "dominant_cc_register" "")
9879	(compare (ior:SI (match_operator:SI 3 "arm_comparison_operator"
9880			  [(match_operand:SI 1 "s_register_operand" "l,r")
9881			   (match_operand:SI 2 "arm_add_operand" "lPy,rIL")])
9882			 (match_operator:SI 6 "arm_comparison_operator"
9883			  [(match_operand:SI 4 "s_register_operand" "l,r")
9884			   (match_operand:SI 5 "arm_add_operand" "lPy,rIL")]))
9885		 (const_int 0)))
9886   (set (match_operand:SI 7 "s_register_operand" "=Ts,Ts")
9887	(ior:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9888		(match_op_dup 6 [(match_dup 4) (match_dup 5)])))]
9889  "TARGET_32BIT"
9890  "#"
9891  "TARGET_32BIT && reload_completed"
9892  [(set (match_dup 0)
9893	(compare
9894	 (ior:SI
9895	  (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9896	  (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9897	 (const_int 0)))
9898   (set (match_dup 7) (ne:SI (match_dup 0) (const_int 0)))]
9899  ""
9900  [(set_attr "conds" "set")
9901   (set_attr "enabled_for_short_it" "yes,no")
9902   (set_attr "length" "16")
9903   (set_attr "type" "multiple")]
9904)
9905
9906(define_insn_and_split "*and_scc_scc"
9907  [(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts")
9908	(and:SI (match_operator:SI 3 "arm_comparison_operator"
9909		 [(match_operand:SI 1 "s_register_operand" "l,r")
9910		  (match_operand:SI 2 "arm_add_operand" "lPy,rIL")])
9911		(match_operator:SI 6 "arm_comparison_operator"
9912		 [(match_operand:SI 4 "s_register_operand" "l,r")
9913		  (match_operand:SI 5 "arm_add_operand" "lPy,rIL")])))
9914   (clobber (reg:CC CC_REGNUM))]
9915  "TARGET_32BIT
9916   && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
9917       != CCmode)"
9918  "#"
9919  "TARGET_32BIT && reload_completed
9920   && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
9921       != CCmode)"
9922  [(set (match_dup 7)
9923	(compare
9924	 (and:SI
9925	  (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9926	  (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9927	 (const_int 0)))
9928   (set (match_dup 0) (ne:SI (match_dup 7) (const_int 0)))]
9929  "operands[7]
9930     = gen_rtx_REG (arm_select_dominance_cc_mode (operands[3], operands[6],
9931						  DOM_CC_X_AND_Y),
9932		    CC_REGNUM);"
9933  [(set_attr "conds" "clob")
9934   (set_attr "enabled_for_short_it" "yes,no")
9935   (set_attr "length" "16")
9936   (set_attr "type" "multiple")]
9937)
9938
9939; If the above pattern is followed by a CMP insn, then the compare is
9940; redundant, since we can rework the conditional instruction that follows.
9941(define_insn_and_split "*and_scc_scc_cmp"
9942  [(set (match_operand 0 "dominant_cc_register" "")
9943	(compare (and:SI (match_operator:SI 3 "arm_comparison_operator"
9944			  [(match_operand:SI 1 "s_register_operand" "l,r")
9945			   (match_operand:SI 2 "arm_add_operand" "lPy,rIL")])
9946			 (match_operator:SI 6 "arm_comparison_operator"
9947			  [(match_operand:SI 4 "s_register_operand" "l,r")
9948			   (match_operand:SI 5 "arm_add_operand" "lPy,rIL")]))
9949		 (const_int 0)))
9950   (set (match_operand:SI 7 "s_register_operand" "=Ts,Ts")
9951	(and:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9952		(match_op_dup 6 [(match_dup 4) (match_dup 5)])))]
9953  "TARGET_32BIT"
9954  "#"
9955  "TARGET_32BIT && reload_completed"
9956  [(set (match_dup 0)
9957	(compare
9958	 (and:SI
9959	  (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9960	  (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9961	 (const_int 0)))
9962   (set (match_dup 7) (ne:SI (match_dup 0) (const_int 0)))]
9963  ""
9964  [(set_attr "conds" "set")
9965   (set_attr "enabled_for_short_it" "yes,no")
9966   (set_attr "length" "16")
9967   (set_attr "type" "multiple")]
9968)
9969
9970;; If there is no dominance in the comparison, then we can still save an
9971;; instruction in the AND case, since we can know that the second compare
9972;; need only zero the value if false (if true, then the value is already
9973;; correct).
9974(define_insn_and_split "*and_scc_scc_nodom"
9975  [(set (match_operand:SI 0 "s_register_operand" "=&Ts,&Ts,&Ts")
9976	(and:SI (match_operator:SI 3 "arm_comparison_operator"
9977		 [(match_operand:SI 1 "s_register_operand" "r,r,0")
9978		  (match_operand:SI 2 "arm_add_operand" "rIL,0,rIL")])
9979		(match_operator:SI 6 "arm_comparison_operator"
9980		 [(match_operand:SI 4 "s_register_operand" "r,r,r")
9981		  (match_operand:SI 5 "arm_add_operand" "rIL,rIL,rIL")])))
9982   (clobber (reg:CC CC_REGNUM))]
9983  "TARGET_32BIT
9984   && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
9985       == CCmode)"
9986  "#"
9987  "TARGET_32BIT && reload_completed"
9988  [(parallel [(set (match_dup 0)
9989		   (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
9990	      (clobber (reg:CC CC_REGNUM))])
9991   (set (match_dup 7) (match_op_dup 8 [(match_dup 4) (match_dup 5)]))
9992   (set (match_dup 0)
9993	(if_then_else:SI (match_op_dup 6 [(match_dup 7) (const_int 0)])
9994			 (match_dup 0)
9995			 (const_int 0)))]
9996  "operands[7] = gen_rtx_REG (SELECT_CC_MODE (GET_CODE (operands[6]),
9997					      operands[4], operands[5]),
9998			      CC_REGNUM);
9999   operands[8] = gen_rtx_COMPARE (GET_MODE (operands[7]), operands[4],
10000				  operands[5]);"
10001  [(set_attr "conds" "clob")
10002   (set_attr "length" "20")
10003   (set_attr "type" "multiple")]
10004)
10005
10006(define_split
10007  [(set (reg:CC_NOOV CC_REGNUM)
10008	(compare:CC_NOOV (ior:SI
10009			  (and:SI (match_operand:SI 0 "s_register_operand" "")
10010				  (const_int 1))
10011			  (match_operator:SI 1 "arm_comparison_operator"
10012			   [(match_operand:SI 2 "s_register_operand" "")
10013			    (match_operand:SI 3 "arm_add_operand" "")]))
10014			 (const_int 0)))
10015   (clobber (match_operand:SI 4 "s_register_operand" ""))]
10016  "TARGET_ARM"
10017  [(set (match_dup 4)
10018	(ior:SI (match_op_dup 1 [(match_dup 2) (match_dup 3)])
10019		(match_dup 0)))
10020   (set (reg:CC_NOOV CC_REGNUM)
10021	(compare:CC_NOOV (and:SI (match_dup 4) (const_int 1))
10022			 (const_int 0)))]
10023  "")
10024
10025(define_split
10026  [(set (reg:CC_NOOV CC_REGNUM)
10027	(compare:CC_NOOV (ior:SI
10028			  (match_operator:SI 1 "arm_comparison_operator"
10029			   [(match_operand:SI 2 "s_register_operand" "")
10030			    (match_operand:SI 3 "arm_add_operand" "")])
10031			  (and:SI (match_operand:SI 0 "s_register_operand" "")
10032				  (const_int 1)))
10033			 (const_int 0)))
10034   (clobber (match_operand:SI 4 "s_register_operand" ""))]
10035  "TARGET_ARM"
10036  [(set (match_dup 4)
10037	(ior:SI (match_op_dup 1 [(match_dup 2) (match_dup 3)])
10038		(match_dup 0)))
10039   (set (reg:CC_NOOV CC_REGNUM)
10040	(compare:CC_NOOV (and:SI (match_dup 4) (const_int 1))
10041			 (const_int 0)))]
10042  "")
10043;; ??? The conditional patterns above need checking for Thumb-2 usefulness
10044
10045(define_insn_and_split "*negscc"
10046  [(set (match_operand:SI 0 "s_register_operand" "=r")
10047	(neg:SI (match_operator 3 "arm_comparison_operator"
10048		 [(match_operand:SI 1 "s_register_operand" "r")
10049		  (match_operand:SI 2 "arm_rhs_operand" "rI")])))
10050   (clobber (reg:CC CC_REGNUM))]
10051  "TARGET_ARM"
10052  "#"
10053  "&& reload_completed"
10054  [(const_int 0)]
10055  {
10056    rtx cc_reg = gen_rtx_REG (CCmode, CC_REGNUM);
10057
10058    if (GET_CODE (operands[3]) == LT && operands[2] == const0_rtx)
10059       {
10060         /* Emit mov\\t%0, %1, asr #31 */
10061         emit_insn (gen_rtx_SET (operands[0],
10062                                 gen_rtx_ASHIFTRT (SImode,
10063                                                   operands[1],
10064                                                   GEN_INT (31))));
10065         DONE;
10066       }
10067     else if (GET_CODE (operands[3]) == NE)
10068       {
10069        /* Emit subs\\t%0, %1, %2\;mvnne\\t%0, #0 */
10070        if (CONST_INT_P (operands[2]))
10071          emit_insn (gen_cmpsi2_addneg (operands[0], operands[1], operands[2],
10072                                        gen_int_mode (-INTVAL (operands[2]),
10073						      SImode)));
10074        else
10075          emit_insn (gen_subsi3_compare (operands[0], operands[1], operands[2]));
10076
10077        emit_insn (gen_rtx_COND_EXEC (VOIDmode,
10078                                      gen_rtx_NE (SImode,
10079                                                  cc_reg,
10080                                                  const0_rtx),
10081                                      gen_rtx_SET (operands[0],
10082                                                   GEN_INT (~0))));
10083        DONE;
10084      }
10085    else
10086      {
10087        /* Emit: cmp\\t%1, %2\;mov%D3\\t%0, #0\;mvn%d3\\t%0, #0 */
10088        emit_insn (gen_rtx_SET (cc_reg,
10089                                gen_rtx_COMPARE (CCmode, operands[1], operands[2])));
10090        enum rtx_code rc = GET_CODE (operands[3]);
10091
10092        rc = reverse_condition (rc);
10093        emit_insn (gen_rtx_COND_EXEC (VOIDmode,
10094                                      gen_rtx_fmt_ee (rc,
10095                                                      VOIDmode,
10096                                                      cc_reg,
10097                                                      const0_rtx),
10098                                      gen_rtx_SET (operands[0], const0_rtx)));
10099        rc = GET_CODE (operands[3]);
10100        emit_insn (gen_rtx_COND_EXEC (VOIDmode,
10101                                      gen_rtx_fmt_ee (rc,
10102                                                      VOIDmode,
10103                                                      cc_reg,
10104                                                      const0_rtx),
10105                                      gen_rtx_SET (operands[0],
10106                                                   GEN_INT (~0))));
10107        DONE;
10108      }
10109     FAIL;
10110  }
10111  [(set_attr "conds" "clob")
10112   (set_attr "length" "12")
10113   (set_attr "type" "multiple")]
10114)
10115
10116(define_insn_and_split "movcond_addsi"
10117  [(set (match_operand:SI 0 "s_register_operand" "=r,l,r")
10118	(if_then_else:SI
10119	 (match_operator 5 "comparison_operator"
10120	  [(plus:SI (match_operand:SI 3 "s_register_operand" "r,r,r")
10121	            (match_operand:SI 4 "arm_add_operand" "rIL,rIL,rIL"))
10122            (const_int 0)])
10123	 (match_operand:SI 1 "arm_rhs_operand" "rI,rPy,r")
10124	 (match_operand:SI 2 "arm_rhs_operand" "rI,rPy,r")))
10125   (clobber (reg:CC CC_REGNUM))]
10126   "TARGET_32BIT"
10127   "#"
10128   "&& reload_completed"
10129  [(set (reg:CC_NOOV CC_REGNUM)
10130	(compare:CC_NOOV
10131	 (plus:SI (match_dup 3)
10132		  (match_dup 4))
10133	 (const_int 0)))
10134   (set (match_dup 0) (match_dup 1))
10135   (cond_exec (match_dup 6)
10136	      (set (match_dup 0) (match_dup 2)))]
10137  "
10138  {
10139    machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[5]),
10140					     operands[3], operands[4]);
10141    enum rtx_code rc = GET_CODE (operands[5]);
10142    operands[6] = gen_rtx_REG (mode, CC_REGNUM);
10143    gcc_assert (!(mode == CCFPmode || mode == CCFPEmode));
10144    if (!REG_P (operands[2]) || REGNO (operands[2]) != REGNO (operands[0]))
10145      rc = reverse_condition (rc);
10146    else
10147      std::swap (operands[1], operands[2]);
10148
10149    operands[6] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
10150  }
10151  "
10152  [(set_attr "conds" "clob")
10153   (set_attr "enabled_for_short_it" "no,yes,yes")
10154   (set_attr "type" "multiple")]
10155)
10156
10157(define_insn "movcond"
10158  [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
10159	(if_then_else:SI
10160	 (match_operator 5 "arm_comparison_operator"
10161	  [(match_operand:SI 3 "s_register_operand" "r,r,r")
10162	   (match_operand:SI 4 "arm_add_operand" "rIL,rIL,rIL")])
10163	 (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
10164	 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
10165   (clobber (reg:CC CC_REGNUM))]
10166  "TARGET_ARM"
10167  "*
10168  if (GET_CODE (operands[5]) == LT
10169      && (operands[4] == const0_rtx))
10170    {
10171      if (which_alternative != 1 && REG_P (operands[1]))
10172	{
10173	  if (operands[2] == const0_rtx)
10174	    return \"and\\t%0, %1, %3, asr #31\";
10175	  return \"ands\\t%0, %1, %3, asr #32\;movcc\\t%0, %2\";
10176	}
10177      else if (which_alternative != 0 && REG_P (operands[2]))
10178	{
10179	  if (operands[1] == const0_rtx)
10180	    return \"bic\\t%0, %2, %3, asr #31\";
10181	  return \"bics\\t%0, %2, %3, asr #32\;movcs\\t%0, %1\";
10182	}
10183      /* The only case that falls through to here is when both ops 1 & 2
10184	 are constants.  */
10185    }
10186
10187  if (GET_CODE (operands[5]) == GE
10188      && (operands[4] == const0_rtx))
10189    {
10190      if (which_alternative != 1 && REG_P (operands[1]))
10191	{
10192	  if (operands[2] == const0_rtx)
10193	    return \"bic\\t%0, %1, %3, asr #31\";
10194	  return \"bics\\t%0, %1, %3, asr #32\;movcs\\t%0, %2\";
10195	}
10196      else if (which_alternative != 0 && REG_P (operands[2]))
10197	{
10198	  if (operands[1] == const0_rtx)
10199	    return \"and\\t%0, %2, %3, asr #31\";
10200	  return \"ands\\t%0, %2, %3, asr #32\;movcc\\t%0, %1\";
10201	}
10202      /* The only case that falls through to here is when both ops 1 & 2
10203	 are constants.  */
10204    }
10205  if (CONST_INT_P (operands[4])
10206      && !const_ok_for_arm (INTVAL (operands[4])))
10207    output_asm_insn (\"cmn\\t%3, #%n4\", operands);
10208  else
10209    output_asm_insn (\"cmp\\t%3, %4\", operands);
10210  if (which_alternative != 0)
10211    output_asm_insn (\"mov%d5\\t%0, %1\", operands);
10212  if (which_alternative != 1)
10213    output_asm_insn (\"mov%D5\\t%0, %2\", operands);
10214  return \"\";
10215  "
10216  [(set_attr "conds" "clob")
10217   (set_attr "length" "8,8,12")
10218   (set_attr "type" "multiple")]
10219)
10220
10221;; ??? The patterns below need checking for Thumb-2 usefulness.
10222
10223(define_insn "*ifcompare_plus_move"
10224  [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10225	(if_then_else:SI (match_operator 6 "arm_comparison_operator"
10226			  [(match_operand:SI 4 "s_register_operand" "r,r")
10227			   (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
10228			 (plus:SI
10229			  (match_operand:SI 2 "s_register_operand" "r,r")
10230			  (match_operand:SI 3 "arm_add_operand" "rIL,rIL"))
10231			 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))
10232   (clobber (reg:CC CC_REGNUM))]
10233  "TARGET_ARM"
10234  "#"
10235  [(set_attr "conds" "clob")
10236   (set_attr "length" "8,12")
10237   (set_attr "type" "multiple")]
10238)
10239
10240(define_insn "*if_plus_move"
10241  [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
10242	(if_then_else:SI
10243	 (match_operator 4 "arm_comparison_operator"
10244	  [(match_operand 5 "cc_register" "") (const_int 0)])
10245	 (plus:SI
10246	  (match_operand:SI 2 "s_register_operand" "r,r,r,r")
10247	  (match_operand:SI 3 "arm_add_operand" "rI,L,rI,L"))
10248	 (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")))]
10249  "TARGET_ARM"
10250  "@
10251   add%d4\\t%0, %2, %3
10252   sub%d4\\t%0, %2, #%n3
10253   add%d4\\t%0, %2, %3\;mov%D4\\t%0, %1
10254   sub%d4\\t%0, %2, #%n3\;mov%D4\\t%0, %1"
10255  [(set_attr "conds" "use")
10256   (set_attr "length" "4,4,8,8")
10257   (set_attr_alternative "type"
10258                         [(if_then_else (match_operand 3 "const_int_operand" "")
10259                                        (const_string "alu_imm" )
10260                                        (const_string "alu_sreg"))
10261                          (const_string "alu_imm")
10262                          (const_string "multiple")
10263                          (const_string "multiple")])]
10264)
10265
10266(define_insn "*ifcompare_move_plus"
10267  [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10268	(if_then_else:SI (match_operator 6 "arm_comparison_operator"
10269			  [(match_operand:SI 4 "s_register_operand" "r,r")
10270			   (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
10271			 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
10272			 (plus:SI
10273			  (match_operand:SI 2 "s_register_operand" "r,r")
10274			  (match_operand:SI 3 "arm_add_operand" "rIL,rIL"))))
10275   (clobber (reg:CC CC_REGNUM))]
10276  "TARGET_ARM"
10277  "#"
10278  [(set_attr "conds" "clob")
10279   (set_attr "length" "8,12")
10280   (set_attr "type" "multiple")]
10281)
10282
10283(define_insn "*if_move_plus"
10284  [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
10285	(if_then_else:SI
10286	 (match_operator 4 "arm_comparison_operator"
10287	  [(match_operand 5 "cc_register" "") (const_int 0)])
10288	 (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")
10289	 (plus:SI
10290	  (match_operand:SI 2 "s_register_operand" "r,r,r,r")
10291	  (match_operand:SI 3 "arm_add_operand" "rI,L,rI,L"))))]
10292  "TARGET_ARM"
10293  "@
10294   add%D4\\t%0, %2, %3
10295   sub%D4\\t%0, %2, #%n3
10296   add%D4\\t%0, %2, %3\;mov%d4\\t%0, %1
10297   sub%D4\\t%0, %2, #%n3\;mov%d4\\t%0, %1"
10298  [(set_attr "conds" "use")
10299   (set_attr "length" "4,4,8,8")
10300   (set_attr_alternative "type"
10301                         [(if_then_else (match_operand 3 "const_int_operand" "")
10302                                        (const_string "alu_imm" )
10303                                        (const_string "alu_sreg"))
10304                          (const_string "alu_imm")
10305                          (const_string "multiple")
10306                          (const_string "multiple")])]
10307)
10308
10309(define_insn "*ifcompare_arith_arith"
10310  [(set (match_operand:SI 0 "s_register_operand" "=r")
10311	(if_then_else:SI (match_operator 9 "arm_comparison_operator"
10312			  [(match_operand:SI 5 "s_register_operand" "r")
10313			   (match_operand:SI 6 "arm_add_operand" "rIL")])
10314			 (match_operator:SI 8 "shiftable_operator"
10315			  [(match_operand:SI 1 "s_register_operand" "r")
10316			   (match_operand:SI 2 "arm_rhs_operand" "rI")])
10317			 (match_operator:SI 7 "shiftable_operator"
10318			  [(match_operand:SI 3 "s_register_operand" "r")
10319			   (match_operand:SI 4 "arm_rhs_operand" "rI")])))
10320   (clobber (reg:CC CC_REGNUM))]
10321  "TARGET_ARM"
10322  "#"
10323  [(set_attr "conds" "clob")
10324   (set_attr "length" "12")
10325   (set_attr "type" "multiple")]
10326)
10327
10328(define_insn "*if_arith_arith"
10329  [(set (match_operand:SI 0 "s_register_operand" "=r")
10330	(if_then_else:SI (match_operator 5 "arm_comparison_operator"
10331			  [(match_operand 8 "cc_register" "") (const_int 0)])
10332			 (match_operator:SI 6 "shiftable_operator"
10333			  [(match_operand:SI 1 "s_register_operand" "r")
10334			   (match_operand:SI 2 "arm_rhs_operand" "rI")])
10335			 (match_operator:SI 7 "shiftable_operator"
10336			  [(match_operand:SI 3 "s_register_operand" "r")
10337			   (match_operand:SI 4 "arm_rhs_operand" "rI")])))]
10338  "TARGET_ARM"
10339  "%I6%d5\\t%0, %1, %2\;%I7%D5\\t%0, %3, %4"
10340  [(set_attr "conds" "use")
10341   (set_attr "length" "8")
10342   (set_attr "type" "multiple")]
10343)
10344
10345(define_insn "*ifcompare_arith_move"
10346  [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10347	(if_then_else:SI (match_operator 6 "arm_comparison_operator"
10348			  [(match_operand:SI 2 "s_register_operand" "r,r")
10349			   (match_operand:SI 3 "arm_add_operand" "rIL,rIL")])
10350			 (match_operator:SI 7 "shiftable_operator"
10351			  [(match_operand:SI 4 "s_register_operand" "r,r")
10352			   (match_operand:SI 5 "arm_rhs_operand" "rI,rI")])
10353			 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))
10354   (clobber (reg:CC CC_REGNUM))]
10355  "TARGET_ARM"
10356  "*
10357  /* If we have an operation where (op x 0) is the identity operation and
10358     the conditional operator is LT or GE and we are comparing against zero and
10359     everything is in registers then we can do this in two instructions.  */
10360  if (operands[3] == const0_rtx
10361      && GET_CODE (operands[7]) != AND
10362      && REG_P (operands[5])
10363      && REG_P (operands[1])
10364      && REGNO (operands[1]) == REGNO (operands[4])
10365      && REGNO (operands[4]) != REGNO (operands[0]))
10366    {
10367      if (GET_CODE (operands[6]) == LT)
10368	return \"and\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\";
10369      else if (GET_CODE (operands[6]) == GE)
10370	return \"bic\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\";
10371    }
10372  if (CONST_INT_P (operands[3])
10373      && !const_ok_for_arm (INTVAL (operands[3])))
10374    output_asm_insn (\"cmn\\t%2, #%n3\", operands);
10375  else
10376    output_asm_insn (\"cmp\\t%2, %3\", operands);
10377  output_asm_insn (\"%I7%d6\\t%0, %4, %5\", operands);
10378  if (which_alternative != 0)
10379    return \"mov%D6\\t%0, %1\";
10380  return \"\";
10381  "
10382  [(set_attr "conds" "clob")
10383   (set_attr "length" "8,12")
10384   (set_attr "type" "multiple")]
10385)
10386
10387(define_insn "*if_arith_move"
10388  [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10389	(if_then_else:SI (match_operator 4 "arm_comparison_operator"
10390			  [(match_operand 6 "cc_register" "") (const_int 0)])
10391			 (match_operator:SI 5 "shiftable_operator"
10392			  [(match_operand:SI 2 "s_register_operand" "r,r")
10393			   (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
10394			 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))]
10395  "TARGET_ARM"
10396  "@
10397   %I5%d4\\t%0, %2, %3
10398   %I5%d4\\t%0, %2, %3\;mov%D4\\t%0, %1"
10399  [(set_attr "conds" "use")
10400   (set_attr "length" "4,8")
10401   (set_attr_alternative "type"
10402                         [(if_then_else (match_operand 3 "const_int_operand" "")
10403                                        (const_string "alu_shift_imm" )
10404                                        (const_string "alu_shift_reg"))
10405                          (const_string "multiple")])]
10406)
10407
10408(define_insn "*ifcompare_move_arith"
10409  [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10410	(if_then_else:SI (match_operator 6 "arm_comparison_operator"
10411			  [(match_operand:SI 4 "s_register_operand" "r,r")
10412			   (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
10413			 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
10414			 (match_operator:SI 7 "shiftable_operator"
10415			  [(match_operand:SI 2 "s_register_operand" "r,r")
10416			   (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
10417   (clobber (reg:CC CC_REGNUM))]
10418  "TARGET_ARM"
10419  "*
10420  /* If we have an operation where (op x 0) is the identity operation and
10421     the conditional operator is LT or GE and we are comparing against zero and
10422     everything is in registers then we can do this in two instructions */
10423  if (operands[5] == const0_rtx
10424      && GET_CODE (operands[7]) != AND
10425      && REG_P (operands[3])
10426      && REG_P (operands[1])
10427      && REGNO (operands[1]) == REGNO (operands[2])
10428      && REGNO (operands[2]) != REGNO (operands[0]))
10429    {
10430      if (GET_CODE (operands[6]) == GE)
10431	return \"and\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\";
10432      else if (GET_CODE (operands[6]) == LT)
10433	return \"bic\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\";
10434    }
10435
10436  if (CONST_INT_P (operands[5])
10437      && !const_ok_for_arm (INTVAL (operands[5])))
10438    output_asm_insn (\"cmn\\t%4, #%n5\", operands);
10439  else
10440    output_asm_insn (\"cmp\\t%4, %5\", operands);
10441
10442  if (which_alternative != 0)
10443    output_asm_insn (\"mov%d6\\t%0, %1\", operands);
10444  return \"%I7%D6\\t%0, %2, %3\";
10445  "
10446  [(set_attr "conds" "clob")
10447   (set_attr "length" "8,12")
10448   (set_attr "type" "multiple")]
10449)
10450
10451(define_insn "*if_move_arith"
10452  [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10453	(if_then_else:SI
10454	 (match_operator 4 "arm_comparison_operator"
10455	  [(match_operand 6 "cc_register" "") (const_int 0)])
10456	 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
10457	 (match_operator:SI 5 "shiftable_operator"
10458	  [(match_operand:SI 2 "s_register_operand" "r,r")
10459	   (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))]
10460  "TARGET_ARM"
10461  "@
10462   %I5%D4\\t%0, %2, %3
10463   %I5%D4\\t%0, %2, %3\;mov%d4\\t%0, %1"
10464  [(set_attr "conds" "use")
10465   (set_attr "length" "4,8")
10466   (set_attr_alternative "type"
10467                         [(if_then_else (match_operand 3 "const_int_operand" "")
10468                                        (const_string "alu_shift_imm" )
10469                                        (const_string "alu_shift_reg"))
10470                          (const_string "multiple")])]
10471)
10472
10473(define_insn "*ifcompare_move_not"
10474  [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10475	(if_then_else:SI
10476	 (match_operator 5 "arm_comparison_operator"
10477	  [(match_operand:SI 3 "s_register_operand" "r,r")
10478	   (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
10479	 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
10480	 (not:SI
10481	  (match_operand:SI 2 "s_register_operand" "r,r"))))
10482   (clobber (reg:CC CC_REGNUM))]
10483  "TARGET_ARM"
10484  "#"
10485  [(set_attr "conds" "clob")
10486   (set_attr "length" "8,12")
10487   (set_attr "type" "multiple")]
10488)
10489
10490(define_insn "*if_move_not"
10491  [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
10492	(if_then_else:SI
10493	 (match_operator 4 "arm_comparison_operator"
10494	  [(match_operand 3 "cc_register" "") (const_int 0)])
10495	 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
10496	 (not:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))))]
10497  "TARGET_ARM"
10498  "@
10499   mvn%D4\\t%0, %2
10500   mov%d4\\t%0, %1\;mvn%D4\\t%0, %2
10501   mvn%d4\\t%0, #%B1\;mvn%D4\\t%0, %2"
10502  [(set_attr "conds" "use")
10503   (set_attr "type" "mvn_reg")
10504   (set_attr "length" "4,8,8")
10505   (set_attr "type" "mvn_reg,multiple,multiple")]
10506)
10507
10508(define_insn "*ifcompare_not_move"
10509  [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10510	(if_then_else:SI
10511	 (match_operator 5 "arm_comparison_operator"
10512	  [(match_operand:SI 3 "s_register_operand" "r,r")
10513	   (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
10514	 (not:SI
10515	  (match_operand:SI 2 "s_register_operand" "r,r"))
10516	 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
10517   (clobber (reg:CC CC_REGNUM))]
10518  "TARGET_ARM"
10519  "#"
10520  [(set_attr "conds" "clob")
10521   (set_attr "length" "8,12")
10522   (set_attr "type" "multiple")]
10523)
10524
10525(define_insn "*if_not_move"
10526  [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
10527	(if_then_else:SI
10528	 (match_operator 4 "arm_comparison_operator"
10529	  [(match_operand 3 "cc_register" "") (const_int 0)])
10530	 (not:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))
10531	 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
10532  "TARGET_ARM"
10533  "@
10534   mvn%d4\\t%0, %2
10535   mov%D4\\t%0, %1\;mvn%d4\\t%0, %2
10536   mvn%D4\\t%0, #%B1\;mvn%d4\\t%0, %2"
10537  [(set_attr "conds" "use")
10538   (set_attr "type" "mvn_reg,multiple,multiple")
10539   (set_attr "length" "4,8,8")]
10540)
10541
10542(define_insn "*ifcompare_shift_move"
10543  [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10544	(if_then_else:SI
10545	 (match_operator 6 "arm_comparison_operator"
10546	  [(match_operand:SI 4 "s_register_operand" "r,r")
10547	   (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
10548	 (match_operator:SI 7 "shift_operator"
10549	  [(match_operand:SI 2 "s_register_operand" "r,r")
10550	   (match_operand:SI 3 "arm_rhs_operand" "rM,rM")])
10551	 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
10552   (clobber (reg:CC CC_REGNUM))]
10553  "TARGET_ARM"
10554  "#"
10555  [(set_attr "conds" "clob")
10556   (set_attr "length" "8,12")
10557   (set_attr "type" "multiple")]
10558)
10559
10560(define_insn "*if_shift_move"
10561  [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
10562	(if_then_else:SI
10563	 (match_operator 5 "arm_comparison_operator"
10564	  [(match_operand 6 "cc_register" "") (const_int 0)])
10565	 (match_operator:SI 4 "shift_operator"
10566	  [(match_operand:SI 2 "s_register_operand" "r,r,r")
10567	   (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM")])
10568	 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
10569  "TARGET_ARM"
10570  "@
10571   mov%d5\\t%0, %2%S4
10572   mov%D5\\t%0, %1\;mov%d5\\t%0, %2%S4
10573   mvn%D5\\t%0, #%B1\;mov%d5\\t%0, %2%S4"
10574  [(set_attr "conds" "use")
10575   (set_attr "shift" "2")
10576   (set_attr "length" "4,8,8")
10577   (set_attr_alternative "type"
10578                         [(if_then_else (match_operand 3 "const_int_operand" "")
10579                                        (const_string "mov_shift" )
10580                                        (const_string "mov_shift_reg"))
10581                          (const_string "multiple")
10582                          (const_string "multiple")])]
10583)
10584
10585(define_insn "*ifcompare_move_shift"
10586  [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10587	(if_then_else:SI
10588	 (match_operator 6 "arm_comparison_operator"
10589	  [(match_operand:SI 4 "s_register_operand" "r,r")
10590	   (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
10591	 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
10592	 (match_operator:SI 7 "shift_operator"
10593	  [(match_operand:SI 2 "s_register_operand" "r,r")
10594	   (match_operand:SI 3 "arm_rhs_operand" "rM,rM")])))
10595   (clobber (reg:CC CC_REGNUM))]
10596  "TARGET_ARM"
10597  "#"
10598  [(set_attr "conds" "clob")
10599   (set_attr "length" "8,12")
10600   (set_attr "type" "multiple")]
10601)
10602
10603(define_insn "*if_move_shift"
10604  [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
10605	(if_then_else:SI
10606	 (match_operator 5 "arm_comparison_operator"
10607	  [(match_operand 6 "cc_register" "") (const_int 0)])
10608	 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
10609	 (match_operator:SI 4 "shift_operator"
10610	  [(match_operand:SI 2 "s_register_operand" "r,r,r")
10611	   (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM")])))]
10612  "TARGET_ARM"
10613  "@
10614   mov%D5\\t%0, %2%S4
10615   mov%d5\\t%0, %1\;mov%D5\\t%0, %2%S4
10616   mvn%d5\\t%0, #%B1\;mov%D5\\t%0, %2%S4"
10617  [(set_attr "conds" "use")
10618   (set_attr "shift" "2")
10619   (set_attr "length" "4,8,8")
10620   (set_attr_alternative "type"
10621                         [(if_then_else (match_operand 3 "const_int_operand" "")
10622                                        (const_string "mov_shift" )
10623                                        (const_string "mov_shift_reg"))
10624                          (const_string "multiple")
10625                          (const_string "multiple")])]
10626)
10627
10628(define_insn "*ifcompare_shift_shift"
10629  [(set (match_operand:SI 0 "s_register_operand" "=r")
10630	(if_then_else:SI
10631	 (match_operator 7 "arm_comparison_operator"
10632	  [(match_operand:SI 5 "s_register_operand" "r")
10633	   (match_operand:SI 6 "arm_add_operand" "rIL")])
10634	 (match_operator:SI 8 "shift_operator"
10635	  [(match_operand:SI 1 "s_register_operand" "r")
10636	   (match_operand:SI 2 "arm_rhs_operand" "rM")])
10637	 (match_operator:SI 9 "shift_operator"
10638	  [(match_operand:SI 3 "s_register_operand" "r")
10639	   (match_operand:SI 4 "arm_rhs_operand" "rM")])))
10640   (clobber (reg:CC CC_REGNUM))]
10641  "TARGET_ARM"
10642  "#"
10643  [(set_attr "conds" "clob")
10644   (set_attr "length" "12")
10645   (set_attr "type" "multiple")]
10646)
10647
10648(define_insn "*if_shift_shift"
10649  [(set (match_operand:SI 0 "s_register_operand" "=r")
10650	(if_then_else:SI
10651	 (match_operator 5 "arm_comparison_operator"
10652	  [(match_operand 8 "cc_register" "") (const_int 0)])
10653	 (match_operator:SI 6 "shift_operator"
10654	  [(match_operand:SI 1 "s_register_operand" "r")
10655	   (match_operand:SI 2 "arm_rhs_operand" "rM")])
10656	 (match_operator:SI 7 "shift_operator"
10657	  [(match_operand:SI 3 "s_register_operand" "r")
10658	   (match_operand:SI 4 "arm_rhs_operand" "rM")])))]
10659  "TARGET_ARM"
10660  "mov%d5\\t%0, %1%S6\;mov%D5\\t%0, %3%S7"
10661  [(set_attr "conds" "use")
10662   (set_attr "shift" "1")
10663   (set_attr "length" "8")
10664   (set (attr "type") (if_then_else
10665		        (and (match_operand 2 "const_int_operand" "")
10666                             (match_operand 4 "const_int_operand" ""))
10667		      (const_string "mov_shift")
10668		      (const_string "mov_shift_reg")))]
10669)
10670
10671(define_insn "*ifcompare_not_arith"
10672  [(set (match_operand:SI 0 "s_register_operand" "=r")
10673	(if_then_else:SI
10674	 (match_operator 6 "arm_comparison_operator"
10675	  [(match_operand:SI 4 "s_register_operand" "r")
10676	   (match_operand:SI 5 "arm_add_operand" "rIL")])
10677	 (not:SI (match_operand:SI 1 "s_register_operand" "r"))
10678	 (match_operator:SI 7 "shiftable_operator"
10679	  [(match_operand:SI 2 "s_register_operand" "r")
10680	   (match_operand:SI 3 "arm_rhs_operand" "rI")])))
10681   (clobber (reg:CC CC_REGNUM))]
10682  "TARGET_ARM"
10683  "#"
10684  [(set_attr "conds" "clob")
10685   (set_attr "length" "12")
10686   (set_attr "type" "multiple")]
10687)
10688
10689(define_insn "*if_not_arith"
10690  [(set (match_operand:SI 0 "s_register_operand" "=r")
10691	(if_then_else:SI
10692	 (match_operator 5 "arm_comparison_operator"
10693	  [(match_operand 4 "cc_register" "") (const_int 0)])
10694	 (not:SI (match_operand:SI 1 "s_register_operand" "r"))
10695	 (match_operator:SI 6 "shiftable_operator"
10696	  [(match_operand:SI 2 "s_register_operand" "r")
10697	   (match_operand:SI 3 "arm_rhs_operand" "rI")])))]
10698  "TARGET_ARM"
10699  "mvn%d5\\t%0, %1\;%I6%D5\\t%0, %2, %3"
10700  [(set_attr "conds" "use")
10701   (set_attr "type" "mvn_reg")
10702   (set_attr "length" "8")]
10703)
10704
10705(define_insn "*ifcompare_arith_not"
10706  [(set (match_operand:SI 0 "s_register_operand" "=r")
10707	(if_then_else:SI
10708	 (match_operator 6 "arm_comparison_operator"
10709	  [(match_operand:SI 4 "s_register_operand" "r")
10710	   (match_operand:SI 5 "arm_add_operand" "rIL")])
10711	 (match_operator:SI 7 "shiftable_operator"
10712	  [(match_operand:SI 2 "s_register_operand" "r")
10713	   (match_operand:SI 3 "arm_rhs_operand" "rI")])
10714	 (not:SI (match_operand:SI 1 "s_register_operand" "r"))))
10715   (clobber (reg:CC CC_REGNUM))]
10716  "TARGET_ARM"
10717  "#"
10718  [(set_attr "conds" "clob")
10719   (set_attr "length" "12")
10720   (set_attr "type" "multiple")]
10721)
10722
10723(define_insn "*if_arith_not"
10724  [(set (match_operand:SI 0 "s_register_operand" "=r")
10725	(if_then_else:SI
10726	 (match_operator 5 "arm_comparison_operator"
10727	  [(match_operand 4 "cc_register" "") (const_int 0)])
10728	 (match_operator:SI 6 "shiftable_operator"
10729	  [(match_operand:SI 2 "s_register_operand" "r")
10730	   (match_operand:SI 3 "arm_rhs_operand" "rI")])
10731	 (not:SI (match_operand:SI 1 "s_register_operand" "r"))))]
10732  "TARGET_ARM"
10733  "mvn%D5\\t%0, %1\;%I6%d5\\t%0, %2, %3"
10734  [(set_attr "conds" "use")
10735   (set_attr "type" "multiple")
10736   (set_attr "length" "8")]
10737)
10738
10739(define_insn "*ifcompare_neg_move"
10740  [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10741	(if_then_else:SI
10742	 (match_operator 5 "arm_comparison_operator"
10743	  [(match_operand:SI 3 "s_register_operand" "r,r")
10744	   (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
10745	 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r"))
10746	 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
10747   (clobber (reg:CC CC_REGNUM))]
10748  "TARGET_ARM"
10749  "#"
10750  [(set_attr "conds" "clob")
10751   (set_attr "length" "8,12")
10752   (set_attr "type" "multiple")]
10753)
10754
10755(define_insn_and_split "*if_neg_move"
10756  [(set (match_operand:SI 0 "s_register_operand" "=l,r")
10757	(if_then_else:SI
10758	 (match_operator 4 "arm_comparison_operator"
10759	  [(match_operand 3 "cc_register" "") (const_int 0)])
10760	 (neg:SI (match_operand:SI 2 "s_register_operand" "l,r"))
10761	 (match_operand:SI 1 "s_register_operand" "0,0")))]
10762  "TARGET_32BIT"
10763  "#"
10764  "&& reload_completed"
10765  [(cond_exec (match_op_dup 4 [(match_dup 3) (const_int 0)])
10766	      (set (match_dup 0) (neg:SI (match_dup 2))))]
10767  ""
10768  [(set_attr "conds" "use")
10769   (set_attr "length" "4")
10770   (set_attr "arch" "t2,32")
10771   (set_attr "enabled_for_short_it" "yes,no")
10772   (set_attr "type" "logic_shift_imm")]
10773)
10774
10775(define_insn "*ifcompare_move_neg"
10776  [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10777	(if_then_else:SI
10778	 (match_operator 5 "arm_comparison_operator"
10779	  [(match_operand:SI 3 "s_register_operand" "r,r")
10780	   (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
10781	 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
10782	 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r"))))
10783   (clobber (reg:CC CC_REGNUM))]
10784  "TARGET_ARM"
10785  "#"
10786  [(set_attr "conds" "clob")
10787   (set_attr "length" "8,12")
10788   (set_attr "type" "multiple")]
10789)
10790
10791(define_insn_and_split "*if_move_neg"
10792  [(set (match_operand:SI 0 "s_register_operand" "=l,r")
10793	(if_then_else:SI
10794	 (match_operator 4 "arm_comparison_operator"
10795	  [(match_operand 3 "cc_register" "") (const_int 0)])
10796	 (match_operand:SI 1 "s_register_operand" "0,0")
10797	 (neg:SI (match_operand:SI 2 "s_register_operand" "l,r"))))]
10798  "TARGET_32BIT"
10799  "#"
10800  "&& reload_completed"
10801  [(cond_exec (match_dup 5)
10802	      (set (match_dup 0) (neg:SI (match_dup 2))))]
10803  {
10804    machine_mode mode = GET_MODE (operands[3]);
10805    rtx_code rc = GET_CODE (operands[4]);
10806
10807    if (mode == CCFPmode || mode == CCFPEmode)
10808      rc = reverse_condition_maybe_unordered (rc);
10809    else
10810      rc = reverse_condition (rc);
10811
10812    operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[3], const0_rtx);
10813  }
10814  [(set_attr "conds" "use")
10815   (set_attr "length" "4")
10816   (set_attr "arch" "t2,32")
10817   (set_attr "enabled_for_short_it" "yes,no")
10818   (set_attr "type" "logic_shift_imm")]
10819)
10820
10821(define_insn "*arith_adjacentmem"
10822  [(set (match_operand:SI 0 "s_register_operand" "=r")
10823	(match_operator:SI 1 "shiftable_operator"
10824	 [(match_operand:SI 2 "memory_operand" "m")
10825	  (match_operand:SI 3 "memory_operand" "m")]))
10826   (clobber (match_scratch:SI 4 "=r"))]
10827  "TARGET_ARM && adjacent_mem_locations (operands[2], operands[3])"
10828  "*
10829  {
10830    rtx ldm[3];
10831    rtx arith[4];
10832    rtx base_reg;
10833    HOST_WIDE_INT val1 = 0, val2 = 0;
10834
10835    if (REGNO (operands[0]) > REGNO (operands[4]))
10836      {
10837	ldm[1] = operands[4];
10838	ldm[2] = operands[0];
10839      }
10840    else
10841      {
10842	ldm[1] = operands[0];
10843	ldm[2] = operands[4];
10844      }
10845
10846    base_reg = XEXP (operands[2], 0);
10847
10848    if (!REG_P (base_reg))
10849      {
10850	val1 = INTVAL (XEXP (base_reg, 1));
10851	base_reg = XEXP (base_reg, 0);
10852      }
10853
10854    if (!REG_P (XEXP (operands[3], 0)))
10855      val2 = INTVAL (XEXP (XEXP (operands[3], 0), 1));
10856
10857    arith[0] = operands[0];
10858    arith[3] = operands[1];
10859
10860    if (val1 < val2)
10861      {
10862	arith[1] = ldm[1];
10863	arith[2] = ldm[2];
10864      }
10865    else
10866      {
10867	arith[1] = ldm[2];
10868	arith[2] = ldm[1];
10869      }
10870
10871    ldm[0] = base_reg;
10872    if (val1 !=0 && val2 != 0)
10873      {
10874	rtx ops[3];
10875
10876	if (val1 == 4 || val2 == 4)
10877	  /* Other val must be 8, since we know they are adjacent and neither
10878	     is zero.  */
10879	  output_asm_insn (\"ldmib%?\\t%0, {%1, %2}\", ldm);
10880	else if (const_ok_for_arm (val1) || const_ok_for_arm (-val1))
10881	  {
10882	    ldm[0] = ops[0] = operands[4];
10883	    ops[1] = base_reg;
10884	    ops[2] = GEN_INT (val1);
10885	    output_add_immediate (ops);
10886	    if (val1 < val2)
10887	      output_asm_insn (\"ldmia%?\\t%0, {%1, %2}\", ldm);
10888	    else
10889	      output_asm_insn (\"ldmda%?\\t%0, {%1, %2}\", ldm);
10890	  }
10891	else
10892	  {
10893	    /* Offset is out of range for a single add, so use two ldr.  */
10894	    ops[0] = ldm[1];
10895	    ops[1] = base_reg;
10896	    ops[2] = GEN_INT (val1);
10897	    output_asm_insn (\"ldr%?\\t%0, [%1, %2]\", ops);
10898	    ops[0] = ldm[2];
10899	    ops[2] = GEN_INT (val2);
10900	    output_asm_insn (\"ldr%?\\t%0, [%1, %2]\", ops);
10901	  }
10902      }
10903    else if (val1 != 0)
10904      {
10905	if (val1 < val2)
10906	  output_asm_insn (\"ldmda%?\\t%0, {%1, %2}\", ldm);
10907	else
10908	  output_asm_insn (\"ldmia%?\\t%0, {%1, %2}\", ldm);
10909      }
10910    else
10911      {
10912	if (val1 < val2)
10913	  output_asm_insn (\"ldmia%?\\t%0, {%1, %2}\", ldm);
10914	else
10915	  output_asm_insn (\"ldmda%?\\t%0, {%1, %2}\", ldm);
10916      }
10917    output_asm_insn (\"%I3%?\\t%0, %1, %2\", arith);
10918    return \"\";
10919  }"
10920  [(set_attr "length" "12")
10921   (set_attr "predicable" "yes")
10922   (set_attr "type" "load_4")]
10923)
10924
10925; This pattern is never tried by combine, so do it as a peephole
10926
10927(define_peephole2
10928  [(set (match_operand:SI 0 "arm_general_register_operand" "")
10929	(match_operand:SI 1 "arm_general_register_operand" ""))
10930   (set (reg:CC CC_REGNUM)
10931	(compare:CC (match_dup 1) (const_int 0)))]
10932  "TARGET_ARM"
10933  [(parallel [(set (reg:CC CC_REGNUM) (compare:CC (match_dup 1) (const_int 0)))
10934	      (set (match_dup 0) (match_dup 1))])]
10935  ""
10936)
10937
10938(define_split
10939  [(set (match_operand:SI 0 "s_register_operand" "")
10940	(and:SI (ge:SI (match_operand:SI 1 "s_register_operand" "")
10941		       (const_int 0))
10942		(neg:SI (match_operator:SI 2 "arm_comparison_operator"
10943			 [(match_operand:SI 3 "s_register_operand" "")
10944			  (match_operand:SI 4 "arm_rhs_operand" "")]))))
10945   (clobber (match_operand:SI 5 "s_register_operand" ""))]
10946  "TARGET_ARM"
10947  [(set (match_dup 5) (not:SI (ashiftrt:SI (match_dup 1) (const_int 31))))
10948   (set (match_dup 0) (and:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
10949			      (match_dup 5)))]
10950  ""
10951)
10952
10953;; This split can be used because CC_Z mode implies that the following
10954;; branch will be an equality, or an unsigned inequality, so the sign
10955;; extension is not needed.
10956
10957(define_split
10958  [(set (reg:CC_Z CC_REGNUM)
10959	(compare:CC_Z
10960	 (ashift:SI (subreg:SI (match_operand:QI 0 "memory_operand" "") 0)
10961		    (const_int 24))
10962	 (match_operand 1 "const_int_operand" "")))
10963   (clobber (match_scratch:SI 2 ""))]
10964  "TARGET_ARM
10965   && ((UINTVAL (operands[1]))
10966       == ((UINTVAL (operands[1])) >> 24) << 24)"
10967  [(set (match_dup 2) (zero_extend:SI (match_dup 0)))
10968   (set (reg:CC CC_REGNUM) (compare:CC (match_dup 2) (match_dup 1)))]
10969  "
10970  operands[1] = GEN_INT (((unsigned long) INTVAL (operands[1])) >> 24);
10971  "
10972)
10973;; ??? Check the patterns above for Thumb-2 usefulness
10974
10975(define_expand "prologue"
10976  [(clobber (const_int 0))]
10977  "TARGET_EITHER"
10978  "if (TARGET_32BIT)
10979     arm_expand_prologue ();
10980   else
10981     thumb1_expand_prologue ();
10982  DONE;
10983  "
10984)
10985
10986(define_expand "epilogue"
10987  [(clobber (const_int 0))]
10988  "TARGET_EITHER"
10989  "
10990  if (crtl->calls_eh_return)
10991    emit_insn (gen_force_register_use (gen_rtx_REG (Pmode, 2)));
10992  if (TARGET_THUMB1)
10993   {
10994     thumb1_expand_epilogue ();
10995     emit_jump_insn (gen_rtx_UNSPEC_VOLATILE (VOIDmode,
10996                     gen_rtvec (1, ret_rtx), VUNSPEC_EPILOGUE));
10997   }
10998  else if (HAVE_return)
10999   {
11000     /* HAVE_return is testing for USE_RETURN_INSN (FALSE).  Hence,
11001        no need for explicit testing again.  */
11002     emit_jump_insn (gen_return ());
11003   }
11004  else if (TARGET_32BIT)
11005   {
11006    arm_expand_epilogue (true);
11007   }
11008  DONE;
11009  "
11010)
11011
11012;; Note - although unspec_volatile's USE all hard registers,
11013;; USEs are ignored after relaod has completed.  Thus we need
11014;; to add an unspec of the link register to ensure that flow
11015;; does not think that it is unused by the sibcall branch that
11016;; will replace the standard function epilogue.
11017(define_expand "sibcall_epilogue"
11018   [(parallel [(unspec:SI [(reg:SI LR_REGNUM)] UNSPEC_REGISTER_USE)
11019               (unspec_volatile [(return)] VUNSPEC_EPILOGUE)])]
11020   "TARGET_32BIT"
11021   "
11022   arm_expand_epilogue (false);
11023   DONE;
11024   "
11025)
11026
11027(define_expand "eh_epilogue"
11028  [(use (match_operand:SI 0 "register_operand" ""))
11029   (use (match_operand:SI 1 "register_operand" ""))
11030   (use (match_operand:SI 2 "register_operand" ""))]
11031  "TARGET_EITHER"
11032  "
11033  {
11034    cfun->machine->eh_epilogue_sp_ofs = operands[1];
11035    if (!REG_P (operands[2]) || REGNO (operands[2]) != 2)
11036      {
11037	rtx ra = gen_rtx_REG (Pmode, 2);
11038
11039	emit_move_insn (ra, operands[2]);
11040	operands[2] = ra;
11041      }
11042    /* This is a hack -- we may have crystalized the function type too
11043       early.  */
11044    cfun->machine->func_type = 0;
11045  }"
11046)
11047
11048;; This split is only used during output to reduce the number of patterns
11049;; that need assembler instructions adding to them.  We allowed the setting
11050;; of the conditions to be implicit during rtl generation so that
11051;; the conditional compare patterns would work.  However this conflicts to
11052;; some extent with the conditional data operations, so we have to split them
11053;; up again here.
11054
11055;; ??? Need to audit these splitters for Thumb-2.  Why isn't normal
11056;; conditional execution sufficient?
11057
11058(define_split
11059  [(set (match_operand:SI 0 "s_register_operand" "")
11060	(if_then_else:SI (match_operator 1 "arm_comparison_operator"
11061			  [(match_operand 2 "" "") (match_operand 3 "" "")])
11062			 (match_dup 0)
11063			 (match_operand 4 "" "")))
11064   (clobber (reg:CC CC_REGNUM))]
11065  "TARGET_ARM && reload_completed"
11066  [(set (match_dup 5) (match_dup 6))
11067   (cond_exec (match_dup 7)
11068	      (set (match_dup 0) (match_dup 4)))]
11069  "
11070  {
11071    machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
11072					     operands[2], operands[3]);
11073    enum rtx_code rc = GET_CODE (operands[1]);
11074
11075    operands[5] = gen_rtx_REG (mode, CC_REGNUM);
11076    operands[6] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
11077    if (mode == CCFPmode || mode == CCFPEmode)
11078      rc = reverse_condition_maybe_unordered (rc);
11079    else
11080      rc = reverse_condition (rc);
11081
11082    operands[7] = gen_rtx_fmt_ee (rc, VOIDmode, operands[5], const0_rtx);
11083  }"
11084)
11085
11086(define_split
11087  [(set (match_operand:SI 0 "s_register_operand" "")
11088	(if_then_else:SI (match_operator 1 "arm_comparison_operator"
11089			  [(match_operand 2 "" "") (match_operand 3 "" "")])
11090			 (match_operand 4 "" "")
11091			 (match_dup 0)))
11092   (clobber (reg:CC CC_REGNUM))]
11093  "TARGET_ARM && reload_completed"
11094  [(set (match_dup 5) (match_dup 6))
11095   (cond_exec (match_op_dup 1 [(match_dup 5) (const_int 0)])
11096	      (set (match_dup 0) (match_dup 4)))]
11097  "
11098  {
11099    machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
11100					     operands[2], operands[3]);
11101
11102    operands[5] = gen_rtx_REG (mode, CC_REGNUM);
11103    operands[6] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
11104  }"
11105)
11106
11107(define_split
11108  [(set (match_operand:SI 0 "s_register_operand" "")
11109	(if_then_else:SI (match_operator 1 "arm_comparison_operator"
11110			  [(match_operand 2 "" "") (match_operand 3 "" "")])
11111			 (match_operand 4 "" "")
11112			 (match_operand 5 "" "")))
11113   (clobber (reg:CC CC_REGNUM))]
11114  "TARGET_ARM && reload_completed"
11115  [(set (match_dup 6) (match_dup 7))
11116   (cond_exec (match_op_dup 1 [(match_dup 6) (const_int 0)])
11117	      (set (match_dup 0) (match_dup 4)))
11118   (cond_exec (match_dup 8)
11119	      (set (match_dup 0) (match_dup 5)))]
11120  "
11121  {
11122    machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
11123					     operands[2], operands[3]);
11124    enum rtx_code rc = GET_CODE (operands[1]);
11125
11126    operands[6] = gen_rtx_REG (mode, CC_REGNUM);
11127    operands[7] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
11128    if (mode == CCFPmode || mode == CCFPEmode)
11129      rc = reverse_condition_maybe_unordered (rc);
11130    else
11131      rc = reverse_condition (rc);
11132
11133    operands[8] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
11134  }"
11135)
11136
11137(define_split
11138  [(set (match_operand:SI 0 "s_register_operand" "")
11139	(if_then_else:SI (match_operator 1 "arm_comparison_operator"
11140			  [(match_operand:SI 2 "s_register_operand" "")
11141			   (match_operand:SI 3 "arm_add_operand" "")])
11142			 (match_operand:SI 4 "arm_rhs_operand" "")
11143			 (not:SI
11144			  (match_operand:SI 5 "s_register_operand" ""))))
11145   (clobber (reg:CC CC_REGNUM))]
11146  "TARGET_ARM && reload_completed"
11147  [(set (match_dup 6) (match_dup 7))
11148   (cond_exec (match_op_dup 1 [(match_dup 6) (const_int 0)])
11149	      (set (match_dup 0) (match_dup 4)))
11150   (cond_exec (match_dup 8)
11151	      (set (match_dup 0) (not:SI (match_dup 5))))]
11152  "
11153  {
11154    machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
11155					     operands[2], operands[3]);
11156    enum rtx_code rc = GET_CODE (operands[1]);
11157
11158    operands[6] = gen_rtx_REG (mode, CC_REGNUM);
11159    operands[7] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
11160    if (mode == CCFPmode || mode == CCFPEmode)
11161      rc = reverse_condition_maybe_unordered (rc);
11162    else
11163      rc = reverse_condition (rc);
11164
11165    operands[8] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
11166  }"
11167)
11168
11169(define_insn "*cond_move_not"
11170  [(set (match_operand:SI 0 "s_register_operand" "=r,r")
11171	(if_then_else:SI (match_operator 4 "arm_comparison_operator"
11172			  [(match_operand 3 "cc_register" "") (const_int 0)])
11173			 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
11174			 (not:SI
11175			  (match_operand:SI 2 "s_register_operand" "r,r"))))]
11176  "TARGET_ARM"
11177  "@
11178   mvn%D4\\t%0, %2
11179   mov%d4\\t%0, %1\;mvn%D4\\t%0, %2"
11180  [(set_attr "conds" "use")
11181   (set_attr "type" "mvn_reg,multiple")
11182   (set_attr "length" "4,8")]
11183)
11184
11185;; The next two patterns occur when an AND operation is followed by a
11186;; scc insn sequence
11187
11188(define_insn "*sign_extract_onebit"
11189  [(set (match_operand:SI 0 "s_register_operand" "=r")
11190	(sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
11191			 (const_int 1)
11192			 (match_operand:SI 2 "const_int_operand" "n")))
11193    (clobber (reg:CC CC_REGNUM))]
11194  "TARGET_ARM"
11195  "*
11196    operands[2] = GEN_INT (1 << INTVAL (operands[2]));
11197    output_asm_insn (\"ands\\t%0, %1, %2\", operands);
11198    return \"mvnne\\t%0, #0\";
11199  "
11200  [(set_attr "conds" "clob")
11201   (set_attr "length" "8")
11202   (set_attr "type" "multiple")]
11203)
11204
11205(define_insn "*not_signextract_onebit"
11206  [(set (match_operand:SI 0 "s_register_operand" "=r")
11207	(not:SI
11208	 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
11209			  (const_int 1)
11210			  (match_operand:SI 2 "const_int_operand" "n"))))
11211   (clobber (reg:CC CC_REGNUM))]
11212  "TARGET_ARM"
11213  "*
11214    operands[2] = GEN_INT (1 << INTVAL (operands[2]));
11215    output_asm_insn (\"tst\\t%1, %2\", operands);
11216    output_asm_insn (\"mvneq\\t%0, #0\", operands);
11217    return \"movne\\t%0, #0\";
11218  "
11219  [(set_attr "conds" "clob")
11220   (set_attr "length" "12")
11221   (set_attr "type" "multiple")]
11222)
11223;; ??? The above patterns need auditing for Thumb-2
11224
11225;; Push multiple registers to the stack.  Registers are in parallel (use ...)
11226;; expressions.  For simplicity, the first register is also in the unspec
11227;; part.
11228;; To avoid the usage of GNU extension, the length attribute is computed
11229;; in a C function arm_attr_length_push_multi.
11230(define_insn "*push_multi"
11231  [(match_parallel 2 "multi_register_push"
11232    [(set (match_operand:BLK 0 "push_mult_memory_operand" "")
11233	  (unspec:BLK [(match_operand:SI 1 "s_register_operand" "")]
11234		      UNSPEC_PUSH_MULT))])]
11235  ""
11236  "*
11237  {
11238    int num_saves = XVECLEN (operands[2], 0);
11239
11240    /* For the StrongARM at least it is faster to
11241       use STR to store only a single register.
11242       In Thumb mode always use push, and the assembler will pick
11243       something appropriate.  */
11244    if (num_saves == 1 && TARGET_ARM)
11245      output_asm_insn (\"str%?\\t%1, [%m0, #-4]!\", operands);
11246    else
11247      {
11248	int i;
11249	char pattern[100];
11250
11251	if (TARGET_32BIT)
11252	    strcpy (pattern, \"push%?\\t{%1\");
11253	else
11254	    strcpy (pattern, \"push\\t{%1\");
11255
11256	for (i = 1; i < num_saves; i++)
11257	  {
11258	    strcat (pattern, \", %|\");
11259	    strcat (pattern,
11260		    reg_names[REGNO (XEXP (XVECEXP (operands[2], 0, i), 0))]);
11261	  }
11262
11263	strcat (pattern, \"}\");
11264	output_asm_insn (pattern, operands);
11265      }
11266
11267    return \"\";
11268  }"
11269  [(set_attr "type" "store_16")
11270   (set (attr "length")
11271	(symbol_ref "arm_attr_length_push_multi (operands[2], operands[1])"))]
11272)
11273
11274(define_insn "stack_tie"
11275  [(set (mem:BLK (scratch))
11276	(unspec:BLK [(match_operand:SI 0 "s_register_operand" "rk")
11277		     (match_operand:SI 1 "s_register_operand" "rk")]
11278		    UNSPEC_PRLG_STK))]
11279  ""
11280  ""
11281  [(set_attr "length" "0")
11282   (set_attr "type" "block")]
11283)
11284
11285;; Pop (as used in epilogue RTL)
11286;;
11287(define_insn "*load_multiple_with_writeback"
11288  [(match_parallel 0 "load_multiple_operation"
11289    [(set (match_operand:SI 1 "s_register_operand" "+rk")
11290          (plus:SI (match_dup 1)
11291                   (match_operand:SI 2 "const_int_I_operand" "I")))
11292     (set (match_operand:SI 3 "s_register_operand" "=rk")
11293          (mem:SI (match_dup 1)))
11294        ])]
11295  "TARGET_32BIT && (reload_in_progress || reload_completed)"
11296  "*
11297  {
11298    arm_output_multireg_pop (operands, /*return_pc=*/false,
11299                                       /*cond=*/const_true_rtx,
11300                                       /*reverse=*/false,
11301                                       /*update=*/true);
11302    return \"\";
11303  }
11304  "
11305  [(set_attr "type" "load_16")
11306   (set_attr "predicable" "yes")
11307   (set (attr "length")
11308	(symbol_ref "arm_attr_length_pop_multi (operands,
11309						/*return_pc=*/false,
11310						/*write_back_p=*/true)"))]
11311)
11312
11313;; Pop with return (as used in epilogue RTL)
11314;;
11315;; This instruction is generated when the registers are popped at the end of
11316;; epilogue.  Here, instead of popping the value into LR and then generating
11317;; jump to LR, value is popped into PC directly.  Hence, the pattern is combined
11318;;  with (return).
11319(define_insn "*pop_multiple_with_writeback_and_return"
11320  [(match_parallel 0 "pop_multiple_return"
11321    [(return)
11322     (set (match_operand:SI 1 "s_register_operand" "+rk")
11323          (plus:SI (match_dup 1)
11324                   (match_operand:SI 2 "const_int_I_operand" "I")))
11325     (set (match_operand:SI 3 "s_register_operand" "=rk")
11326          (mem:SI (match_dup 1)))
11327        ])]
11328  "TARGET_32BIT && (reload_in_progress || reload_completed)"
11329  "*
11330  {
11331    arm_output_multireg_pop (operands, /*return_pc=*/true,
11332                                       /*cond=*/const_true_rtx,
11333                                       /*reverse=*/false,
11334                                       /*update=*/true);
11335    return \"\";
11336  }
11337  "
11338  [(set_attr "type" "load_16")
11339   (set_attr "predicable" "yes")
11340   (set (attr "length")
11341	(symbol_ref "arm_attr_length_pop_multi (operands, /*return_pc=*/true,
11342						/*write_back_p=*/true)"))]
11343)
11344
11345(define_insn "*pop_multiple_with_return"
11346  [(match_parallel 0 "pop_multiple_return"
11347    [(return)
11348     (set (match_operand:SI 2 "s_register_operand" "=rk")
11349          (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
11350        ])]
11351  "TARGET_32BIT && (reload_in_progress || reload_completed)"
11352  "*
11353  {
11354    arm_output_multireg_pop (operands, /*return_pc=*/true,
11355                                       /*cond=*/const_true_rtx,
11356                                       /*reverse=*/false,
11357                                       /*update=*/false);
11358    return \"\";
11359  }
11360  "
11361  [(set_attr "type" "load_16")
11362   (set_attr "predicable" "yes")
11363   (set (attr "length")
11364	(symbol_ref "arm_attr_length_pop_multi (operands, /*return_pc=*/true,
11365						/*write_back_p=*/false)"))]
11366)
11367
11368;; Load into PC and return
11369(define_insn "*ldr_with_return"
11370  [(return)
11371   (set (reg:SI PC_REGNUM)
11372        (mem:SI (post_inc:SI (match_operand:SI 0 "s_register_operand" "+rk"))))]
11373  "TARGET_32BIT && (reload_in_progress || reload_completed)"
11374  "ldr%?\t%|pc, [%0], #4"
11375  [(set_attr "type" "load_4")
11376   (set_attr "predicable" "yes")]
11377)
11378;; Pop for floating point registers (as used in epilogue RTL)
11379(define_insn "*vfp_pop_multiple_with_writeback"
11380  [(match_parallel 0 "pop_multiple_fp"
11381    [(set (match_operand:SI 1 "s_register_operand" "+rk")
11382          (plus:SI (match_dup 1)
11383                   (match_operand:SI 2 "const_int_I_operand" "I")))
11384     (set (match_operand:DF 3 "vfp_hard_register_operand" "")
11385          (mem:DF (match_dup 1)))])]
11386  "TARGET_32BIT && TARGET_HARD_FLOAT"
11387  "*
11388  {
11389    int num_regs = XVECLEN (operands[0], 0);
11390    char pattern[100];
11391    rtx op_list[2];
11392    strcpy (pattern, \"vldm\\t\");
11393    strcat (pattern, reg_names[REGNO (SET_DEST (XVECEXP (operands[0], 0, 0)))]);
11394    strcat (pattern, \"!, {\");
11395    op_list[0] = XEXP (XVECEXP (operands[0], 0, 1), 0);
11396    strcat (pattern, \"%P0\");
11397    if ((num_regs - 1) > 1)
11398      {
11399        strcat (pattern, \"-%P1\");
11400        op_list [1] = XEXP (XVECEXP (operands[0], 0, num_regs - 1), 0);
11401      }
11402
11403    strcat (pattern, \"}\");
11404    output_asm_insn (pattern, op_list);
11405    return \"\";
11406  }
11407  "
11408  [(set_attr "type" "load_16")
11409   (set_attr "conds" "unconditional")
11410   (set_attr "predicable" "no")]
11411)
11412
11413;; Special patterns for dealing with the constant pool
11414
11415(define_insn "align_4"
11416  [(unspec_volatile [(const_int 0)] VUNSPEC_ALIGN)]
11417  "TARGET_EITHER"
11418  "*
11419  assemble_align (32);
11420  return \"\";
11421  "
11422  [(set_attr "type" "no_insn")]
11423)
11424
11425(define_insn "align_8"
11426  [(unspec_volatile [(const_int 0)] VUNSPEC_ALIGN8)]
11427  "TARGET_EITHER"
11428  "*
11429  assemble_align (64);
11430  return \"\";
11431  "
11432  [(set_attr "type" "no_insn")]
11433)
11434
11435(define_insn "consttable_end"
11436  [(unspec_volatile [(const_int 0)] VUNSPEC_POOL_END)]
11437  "TARGET_EITHER"
11438  "*
11439  making_const_table = FALSE;
11440  return \"\";
11441  "
11442  [(set_attr "type" "no_insn")]
11443)
11444
11445(define_insn "consttable_1"
11446  [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_1)]
11447  "TARGET_EITHER"
11448  "*
11449  making_const_table = TRUE;
11450  assemble_integer (operands[0], 1, BITS_PER_WORD, 1);
11451  assemble_zeros (3);
11452  return \"\";
11453  "
11454  [(set_attr "length" "4")
11455   (set_attr "type" "no_insn")]
11456)
11457
11458(define_insn "consttable_2"
11459  [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_2)]
11460  "TARGET_EITHER"
11461  "*
11462  {
11463    rtx x = operands[0];
11464    making_const_table = TRUE;
11465    switch (GET_MODE_CLASS (GET_MODE (x)))
11466      {
11467      case MODE_FLOAT:
11468	arm_emit_fp16_const (x);
11469	break;
11470      default:
11471	assemble_integer (operands[0], 2, BITS_PER_WORD, 1);
11472	assemble_zeros (2);
11473	break;
11474      }
11475    return \"\";
11476  }"
11477  [(set_attr "length" "4")
11478   (set_attr "type" "no_insn")]
11479)
11480
11481(define_insn "consttable_4"
11482  [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_4)]
11483  "TARGET_EITHER"
11484  "*
11485  {
11486    rtx x = operands[0];
11487    making_const_table = TRUE;
11488    scalar_float_mode float_mode;
11489    if (is_a <scalar_float_mode> (GET_MODE (x), &float_mode))
11490      assemble_real (*CONST_DOUBLE_REAL_VALUE (x), float_mode, BITS_PER_WORD);
11491    else
11492      {
11493	/* XXX: Sometimes gcc does something really dumb and ends up with
11494	   a HIGH in a constant pool entry, usually because it's trying to
11495	   load into a VFP register.  We know this will always be used in
11496	   combination with a LO_SUM which ignores the high bits, so just
11497	   strip off the HIGH.  */
11498	if (GET_CODE (x) == HIGH)
11499	  x = XEXP (x, 0);
11500        assemble_integer (x, 4, BITS_PER_WORD, 1);
11501	mark_symbol_refs_as_used (x);
11502      }
11503    return \"\";
11504  }"
11505  [(set_attr "length" "4")
11506   (set_attr "type" "no_insn")]
11507)
11508
11509(define_insn "consttable_8"
11510  [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_8)]
11511  "TARGET_EITHER"
11512  "*
11513  {
11514    making_const_table = TRUE;
11515    scalar_float_mode float_mode;
11516    if (is_a <scalar_float_mode> (GET_MODE (operands[0]), &float_mode))
11517      assemble_real (*CONST_DOUBLE_REAL_VALUE (operands[0]),
11518		     float_mode, BITS_PER_WORD);
11519    else
11520      assemble_integer (operands[0], 8, BITS_PER_WORD, 1);
11521    return \"\";
11522  }"
11523  [(set_attr "length" "8")
11524   (set_attr "type" "no_insn")]
11525)
11526
11527(define_insn "consttable_16"
11528  [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_16)]
11529  "TARGET_EITHER"
11530  "*
11531  {
11532    making_const_table = TRUE;
11533    scalar_float_mode float_mode;
11534    if (is_a <scalar_float_mode> (GET_MODE (operands[0]), &float_mode))
11535      assemble_real (*CONST_DOUBLE_REAL_VALUE (operands[0]),
11536		     float_mode, BITS_PER_WORD);
11537    else
11538      assemble_integer (operands[0], 16, BITS_PER_WORD, 1);
11539    return \"\";
11540  }"
11541  [(set_attr "length" "16")
11542   (set_attr "type" "no_insn")]
11543)
11544
11545;; V5 Instructions,
11546
11547(define_insn "clzsi2"
11548  [(set (match_operand:SI 0 "s_register_operand" "=r")
11549	(clz:SI (match_operand:SI 1 "s_register_operand" "r")))]
11550  "TARGET_32BIT && arm_arch5t"
11551  "clz%?\\t%0, %1"
11552  [(set_attr "predicable" "yes")
11553   (set_attr "type" "clz")])
11554
11555(define_insn "rbitsi2"
11556  [(set (match_operand:SI 0 "s_register_operand" "=r")
11557	(unspec:SI [(match_operand:SI 1 "s_register_operand" "r")] UNSPEC_RBIT))]
11558  "TARGET_32BIT && arm_arch_thumb2"
11559  "rbit%?\\t%0, %1"
11560  [(set_attr "predicable" "yes")
11561   (set_attr "type" "clz")])
11562
11563;; Keep this as a CTZ expression until after reload and then split
11564;; into RBIT + CLZ.  Since RBIT is represented as an UNSPEC it is unlikely
11565;; to fold with any other expression.
11566
11567(define_insn_and_split "ctzsi2"
11568 [(set (match_operand:SI           0 "s_register_operand" "=r")
11569       (ctz:SI (match_operand:SI  1 "s_register_operand" "r")))]
11570  "TARGET_32BIT && arm_arch_thumb2"
11571  "#"
11572  "&& reload_completed"
11573  [(const_int 0)]
11574  "
11575  emit_insn (gen_rbitsi2 (operands[0], operands[1]));
11576  emit_insn (gen_clzsi2 (operands[0], operands[0]));
11577  DONE;
11578")
11579
11580;; V5E instructions.
11581
11582(define_insn "prefetch"
11583  [(prefetch (match_operand:SI 0 "address_operand" "p")
11584	     (match_operand:SI 1 "" "")
11585	     (match_operand:SI 2 "" ""))]
11586  "TARGET_32BIT && arm_arch5te"
11587  "pld\\t%a0"
11588  [(set_attr "type" "load_4")]
11589)
11590
11591;; General predication pattern
11592
11593(define_cond_exec
11594  [(match_operator 0 "arm_comparison_operator"
11595    [(match_operand 1 "cc_register" "")
11596     (const_int 0)])]
11597  "TARGET_32BIT
11598   && (!TARGET_NO_VOLATILE_CE || !volatile_refs_p (PATTERN (insn)))"
11599  ""
11600[(set_attr "predicated" "yes")]
11601)
11602
11603(define_insn "force_register_use"
11604  [(unspec:SI [(match_operand:SI 0 "register_operand" "")] UNSPEC_REGISTER_USE)]
11605  ""
11606  "%@ %0 needed"
11607  [(set_attr "length" "0")
11608   (set_attr "type" "no_insn")]
11609)
11610
11611
11612;; Patterns for exception handling
11613
11614(define_expand "eh_return"
11615  [(use (match_operand 0 "general_operand" ""))]
11616  "TARGET_EITHER"
11617  "
11618  {
11619    if (TARGET_32BIT)
11620      emit_insn (gen_arm_eh_return (operands[0]));
11621    else
11622      emit_insn (gen_thumb_eh_return (operands[0]));
11623    DONE;
11624  }"
11625)
11626
11627;; We can't expand this before we know where the link register is stored.
11628(define_insn_and_split "arm_eh_return"
11629  [(unspec_volatile [(match_operand:SI 0 "s_register_operand" "r")]
11630		    VUNSPEC_EH_RETURN)
11631   (clobber (match_scratch:SI 1 "=&r"))]
11632  "TARGET_ARM"
11633  "#"
11634  "&& reload_completed"
11635  [(const_int 0)]
11636  "
11637  {
11638    arm_set_return_address (operands[0], operands[1]);
11639    DONE;
11640  }"
11641)
11642
11643
11644;; TLS support
11645
11646(define_insn "load_tp_hard"
11647  [(set (match_operand:SI 0 "register_operand" "=r")
11648	(unspec:SI [(const_int 0)] UNSPEC_TLS))]
11649  "TARGET_HARD_TP"
11650  "mrc%?\\tp15, 0, %0, c13, c0, 3\\t@ load_tp_hard"
11651  [(set_attr "predicable" "yes")
11652   (set_attr "type" "mrs")]
11653)
11654
11655;; Doesn't clobber R1-R3.  Must use r0 for the first operand.
11656(define_insn "load_tp_soft"
11657  [(set (reg:SI 0) (unspec:SI [(const_int 0)] UNSPEC_TLS))
11658   (clobber (reg:SI LR_REGNUM))
11659   (clobber (reg:SI IP_REGNUM))
11660   (clobber (reg:CC CC_REGNUM))]
11661  "TARGET_SOFT_TP"
11662  "bl\\t__aeabi_read_tp\\t@ load_tp_soft"
11663  [(set_attr "conds" "clob")
11664   (set_attr "type" "branch")]
11665)
11666
11667;; tls descriptor call
11668(define_insn "tlscall"
11669  [(set (reg:SI R0_REGNUM)
11670        (unspec:SI [(reg:SI R0_REGNUM)
11671                    (match_operand:SI 0 "" "X")
11672	            (match_operand 1 "" "")] UNSPEC_TLS))
11673   (clobber (reg:SI R1_REGNUM))
11674   (clobber (reg:SI LR_REGNUM))
11675   (clobber (reg:SI CC_REGNUM))]
11676  "TARGET_GNU2_TLS"
11677  {
11678    targetm.asm_out.internal_label (asm_out_file, "LPIC",
11679				    INTVAL (operands[1]));
11680    return "bl\\t%c0(tlscall)";
11681  }
11682  [(set_attr "conds" "clob")
11683   (set_attr "length" "4")
11684   (set_attr "type" "branch")]
11685)
11686
11687;; For thread pointer builtin
11688(define_expand "get_thread_pointersi"
11689  [(match_operand:SI 0 "s_register_operand" "=r")]
11690 ""
11691 "
11692 {
11693   arm_load_tp (operands[0]);
11694   DONE;
11695 }")
11696
11697;;
11698
11699;; We only care about the lower 16 bits of the constant
11700;; being inserted into the upper 16 bits of the register.
11701(define_insn "*arm_movtas_ze"
11702  [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r,r")
11703                   (const_int 16)
11704                   (const_int 16))
11705        (match_operand:SI 1 "const_int_operand" ""))]
11706  "TARGET_HAVE_MOVT"
11707  "@
11708   movt%?\t%0, %L1
11709   movt\t%0, %L1"
11710 [(set_attr "arch" "32,v8mb")
11711  (set_attr "predicable" "yes")
11712  (set_attr "length" "4")
11713  (set_attr "type" "alu_sreg")]
11714)
11715
11716(define_insn "*arm_rev"
11717  [(set (match_operand:SI 0 "s_register_operand" "=l,l,r")
11718	(bswap:SI (match_operand:SI 1 "s_register_operand" "l,l,r")))]
11719  "arm_arch6"
11720  "@
11721   rev\t%0, %1
11722   rev%?\t%0, %1
11723   rev%?\t%0, %1"
11724  [(set_attr "arch" "t1,t2,32")
11725   (set_attr "length" "2,2,4")
11726   (set_attr "predicable" "no,yes,yes")
11727   (set_attr "type" "rev")]
11728)
11729
11730(define_expand "arm_legacy_rev"
11731  [(set (match_operand:SI 2 "s_register_operand" "")
11732	(xor:SI (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
11733			     (const_int 16))
11734		(match_dup 1)))
11735   (set (match_dup 2)
11736	(lshiftrt:SI (match_dup 2)
11737		     (const_int 8)))
11738   (set (match_operand:SI 3 "s_register_operand" "")
11739	(rotatert:SI (match_dup 1)
11740		     (const_int 8)))
11741   (set (match_dup 2)
11742	(and:SI (match_dup 2)
11743		(const_int -65281)))
11744   (set (match_operand:SI 0 "s_register_operand" "")
11745	(xor:SI (match_dup 3)
11746		(match_dup 2)))]
11747  "TARGET_32BIT"
11748  ""
11749)
11750
11751;; Reuse temporaries to keep register pressure down.
11752(define_expand "thumb_legacy_rev"
11753  [(set (match_operand:SI 2 "s_register_operand" "")
11754     (ashift:SI (match_operand:SI 1 "s_register_operand" "")
11755                (const_int 24)))
11756   (set (match_operand:SI 3 "s_register_operand" "")
11757     (lshiftrt:SI (match_dup 1)
11758		  (const_int 24)))
11759   (set (match_dup 3)
11760     (ior:SI (match_dup 3)
11761	     (match_dup 2)))
11762   (set (match_operand:SI 4 "s_register_operand" "")
11763     (const_int 16))
11764   (set (match_operand:SI 5 "s_register_operand" "")
11765     (rotatert:SI (match_dup 1)
11766		  (match_dup 4)))
11767   (set (match_dup 2)
11768     (ashift:SI (match_dup 5)
11769                (const_int 24)))
11770   (set (match_dup 5)
11771     (lshiftrt:SI (match_dup 5)
11772		  (const_int 24)))
11773   (set (match_dup 5)
11774     (ior:SI (match_dup 5)
11775	     (match_dup 2)))
11776   (set (match_dup 5)
11777     (rotatert:SI (match_dup 5)
11778		  (match_dup 4)))
11779   (set (match_operand:SI 0 "s_register_operand" "")
11780     (ior:SI (match_dup 5)
11781             (match_dup 3)))]
11782  "TARGET_THUMB"
11783  ""
11784)
11785
11786;; ARM-specific expansion of signed mod by power of 2
11787;; using conditional negate.
11788;; For r0 % n where n is a power of 2 produce:
11789;; rsbs    r1, r0, #0
11790;; and     r0, r0, #(n - 1)
11791;; and     r1, r1, #(n - 1)
11792;; rsbpl   r0, r1, #0
11793
11794(define_expand "modsi3"
11795  [(match_operand:SI 0 "register_operand" "")
11796   (match_operand:SI 1 "register_operand" "")
11797   (match_operand:SI 2 "const_int_operand" "")]
11798  "TARGET_32BIT"
11799  {
11800    HOST_WIDE_INT val = INTVAL (operands[2]);
11801
11802    if (val <= 0
11803       || exact_log2 (val) <= 0)
11804      FAIL;
11805
11806    rtx mask = GEN_INT (val - 1);
11807
11808    /* In the special case of x0 % 2 we can do the even shorter:
11809	cmp     r0, #0
11810	and     r0, r0, #1
11811	rsblt   r0, r0, #0.  */
11812
11813    if (val == 2)
11814      {
11815	rtx cc_reg = arm_gen_compare_reg (LT,
11816					  operands[1], const0_rtx, NULL_RTX);
11817	rtx cond = gen_rtx_LT (SImode, cc_reg, const0_rtx);
11818	rtx masked = gen_reg_rtx (SImode);
11819
11820	emit_insn (gen_andsi3 (masked, operands[1], mask));
11821	emit_move_insn (operands[0],
11822			gen_rtx_IF_THEN_ELSE (SImode, cond,
11823					      gen_rtx_NEG (SImode,
11824							   masked),
11825					      masked));
11826	DONE;
11827      }
11828
11829    rtx neg_op = gen_reg_rtx (SImode);
11830    rtx_insn *insn = emit_insn (gen_subsi3_compare0 (neg_op, const0_rtx,
11831						      operands[1]));
11832
11833    /* Extract the condition register and mode.  */
11834    rtx cmp = XVECEXP (PATTERN (insn), 0, 0);
11835    rtx cc_reg = SET_DEST (cmp);
11836    rtx cond = gen_rtx_GE (SImode, cc_reg, const0_rtx);
11837
11838    emit_insn (gen_andsi3 (operands[0], operands[1], mask));
11839
11840    rtx masked_neg = gen_reg_rtx (SImode);
11841    emit_insn (gen_andsi3 (masked_neg, neg_op, mask));
11842
11843    /* We want a conditional negate here, but emitting COND_EXEC rtxes
11844       during expand does not always work.  Do an IF_THEN_ELSE instead.  */
11845    emit_move_insn (operands[0],
11846		    gen_rtx_IF_THEN_ELSE (SImode, cond,
11847					  gen_rtx_NEG (SImode, masked_neg),
11848					  operands[0]));
11849
11850
11851    DONE;
11852  }
11853)
11854
11855(define_expand "bswapsi2"
11856  [(set (match_operand:SI 0 "s_register_operand" "=r")
11857  	(bswap:SI (match_operand:SI 1 "s_register_operand" "r")))]
11858"TARGET_EITHER && (arm_arch6 || !optimize_size)"
11859"
11860    if (!arm_arch6)
11861      {
11862	rtx op2 = gen_reg_rtx (SImode);
11863	rtx op3 = gen_reg_rtx (SImode);
11864
11865	if (TARGET_THUMB)
11866	  {
11867	    rtx op4 = gen_reg_rtx (SImode);
11868	    rtx op5 = gen_reg_rtx (SImode);
11869
11870	    emit_insn (gen_thumb_legacy_rev (operands[0], operands[1],
11871					     op2, op3, op4, op5));
11872	  }
11873	else
11874	  {
11875	    emit_insn (gen_arm_legacy_rev (operands[0], operands[1],
11876					   op2, op3));
11877	  }
11878
11879	DONE;
11880      }
11881  "
11882)
11883
11884;; bswap16 patterns: use revsh and rev16 instructions for the signed
11885;; and unsigned variants, respectively. For rev16, expose
11886;; byte-swapping in the lower 16 bits only.
11887(define_insn "*arm_revsh"
11888  [(set (match_operand:SI 0 "s_register_operand" "=l,l,r")
11889	(sign_extend:SI (bswap:HI (match_operand:HI 1 "s_register_operand" "l,l,r"))))]
11890  "arm_arch6"
11891  "@
11892  revsh\t%0, %1
11893  revsh%?\t%0, %1
11894  revsh%?\t%0, %1"
11895  [(set_attr "arch" "t1,t2,32")
11896   (set_attr "length" "2,2,4")
11897   (set_attr "type" "rev")]
11898)
11899
11900(define_insn "*arm_rev16"
11901  [(set (match_operand:HI 0 "s_register_operand" "=l,l,r")
11902	(bswap:HI (match_operand:HI 1 "s_register_operand" "l,l,r")))]
11903  "arm_arch6"
11904  "@
11905   rev16\t%0, %1
11906   rev16%?\t%0, %1
11907   rev16%?\t%0, %1"
11908  [(set_attr "arch" "t1,t2,32")
11909   (set_attr "length" "2,2,4")
11910   (set_attr "type" "rev")]
11911)
11912
11913;; There are no canonicalisation rules for the position of the lshiftrt, ashift
11914;; operations within an IOR/AND RTX, therefore we have two patterns matching
11915;; each valid permutation.
11916
11917(define_insn "arm_rev16si2"
11918  [(set (match_operand:SI 0 "register_operand" "=l,l,r")
11919        (ior:SI (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "l,l,r")
11920                                   (const_int 8))
11921                        (match_operand:SI 3 "const_int_operand" "n,n,n"))
11922                (and:SI (lshiftrt:SI (match_dup 1)
11923                                     (const_int 8))
11924                        (match_operand:SI 2 "const_int_operand" "n,n,n"))))]
11925  "arm_arch6
11926   && aarch_rev16_shleft_mask_imm_p (operands[3], SImode)
11927   && aarch_rev16_shright_mask_imm_p (operands[2], SImode)"
11928  "rev16\\t%0, %1"
11929  [(set_attr "arch" "t1,t2,32")
11930   (set_attr "length" "2,2,4")
11931   (set_attr "type" "rev")]
11932)
11933
11934(define_insn "arm_rev16si2_alt"
11935  [(set (match_operand:SI 0 "register_operand" "=l,l,r")
11936        (ior:SI (and:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "l,l,r")
11937                                     (const_int 8))
11938                        (match_operand:SI 2 "const_int_operand" "n,n,n"))
11939                (and:SI (ashift:SI (match_dup 1)
11940                                   (const_int 8))
11941                        (match_operand:SI 3 "const_int_operand" "n,n,n"))))]
11942  "arm_arch6
11943   && aarch_rev16_shleft_mask_imm_p (operands[3], SImode)
11944   && aarch_rev16_shright_mask_imm_p (operands[2], SImode)"
11945  "rev16\\t%0, %1"
11946  [(set_attr "arch" "t1,t2,32")
11947   (set_attr "length" "2,2,4")
11948   (set_attr "type" "rev")]
11949)
11950
11951(define_expand "bswaphi2"
11952  [(set (match_operand:HI 0 "s_register_operand" "=r")
11953	(bswap:HI (match_operand:HI 1 "s_register_operand" "r")))]
11954"arm_arch6"
11955""
11956)
11957
11958;; Patterns for LDRD/STRD in Thumb2 mode
11959
11960(define_insn "*thumb2_ldrd"
11961  [(set (match_operand:SI 0 "s_register_operand" "=r")
11962        (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "rk")
11963                         (match_operand:SI 2 "ldrd_strd_offset_operand" "Do"))))
11964   (set (match_operand:SI 3 "s_register_operand" "=r")
11965        (mem:SI (plus:SI (match_dup 1)
11966                         (match_operand:SI 4 "const_int_operand" ""))))]
11967  "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11968     && ((INTVAL (operands[2]) + 4) == INTVAL (operands[4]))
11969     && (operands_ok_ldrd_strd (operands[0], operands[3],
11970                                  operands[1], INTVAL (operands[2]),
11971                                  false, true))"
11972  "ldrd%?\t%0, %3, [%1, %2]"
11973  [(set_attr "type" "load_8")
11974   (set_attr "predicable" "yes")])
11975
11976(define_insn "*thumb2_ldrd_base"
11977  [(set (match_operand:SI 0 "s_register_operand" "=r")
11978        (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
11979   (set (match_operand:SI 2 "s_register_operand" "=r")
11980        (mem:SI (plus:SI (match_dup 1)
11981                         (const_int 4))))]
11982  "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11983     && (operands_ok_ldrd_strd (operands[0], operands[2],
11984                                  operands[1], 0, false, true))"
11985  "ldrd%?\t%0, %2, [%1]"
11986  [(set_attr "type" "load_8")
11987   (set_attr "predicable" "yes")])
11988
11989(define_insn "*thumb2_ldrd_base_neg"
11990  [(set (match_operand:SI 0 "s_register_operand" "=r")
11991	(mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "rk")
11992                         (const_int -4))))
11993   (set (match_operand:SI 2 "s_register_operand" "=r")
11994        (mem:SI (match_dup 1)))]
11995  "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11996     && (operands_ok_ldrd_strd (operands[0], operands[2],
11997                                  operands[1], -4, false, true))"
11998  "ldrd%?\t%0, %2, [%1, #-4]"
11999  [(set_attr "type" "load_8")
12000   (set_attr "predicable" "yes")])
12001
12002(define_insn "*thumb2_strd"
12003  [(set (mem:SI (plus:SI (match_operand:SI 0 "s_register_operand" "rk")
12004                         (match_operand:SI 1 "ldrd_strd_offset_operand" "Do")))
12005        (match_operand:SI 2 "s_register_operand" "r"))
12006   (set (mem:SI (plus:SI (match_dup 0)
12007                         (match_operand:SI 3 "const_int_operand" "")))
12008        (match_operand:SI 4 "s_register_operand" "r"))]
12009  "TARGET_LDRD && TARGET_THUMB2 && reload_completed
12010     && ((INTVAL (operands[1]) + 4) == INTVAL (operands[3]))
12011     && (operands_ok_ldrd_strd (operands[2], operands[4],
12012                                  operands[0], INTVAL (operands[1]),
12013                                  false, false))"
12014  "strd%?\t%2, %4, [%0, %1]"
12015  [(set_attr "type" "store_8")
12016   (set_attr "predicable" "yes")])
12017
12018(define_insn "*thumb2_strd_base"
12019  [(set (mem:SI (match_operand:SI 0 "s_register_operand" "rk"))
12020        (match_operand:SI 1 "s_register_operand" "r"))
12021   (set (mem:SI (plus:SI (match_dup 0)
12022                         (const_int 4)))
12023        (match_operand:SI 2 "s_register_operand" "r"))]
12024  "TARGET_LDRD && TARGET_THUMB2 && reload_completed
12025     && (operands_ok_ldrd_strd (operands[1], operands[2],
12026                                  operands[0], 0, false, false))"
12027  "strd%?\t%1, %2, [%0]"
12028  [(set_attr "type" "store_8")
12029   (set_attr "predicable" "yes")])
12030
12031(define_insn "*thumb2_strd_base_neg"
12032  [(set (mem:SI (plus:SI (match_operand:SI 0 "s_register_operand" "rk")
12033                         (const_int -4)))
12034        (match_operand:SI 1 "s_register_operand" "r"))
12035   (set (mem:SI (match_dup 0))
12036        (match_operand:SI 2 "s_register_operand" "r"))]
12037  "TARGET_LDRD && TARGET_THUMB2 && reload_completed
12038     && (operands_ok_ldrd_strd (operands[1], operands[2],
12039                                  operands[0], -4, false, false))"
12040  "strd%?\t%1, %2, [%0, #-4]"
12041  [(set_attr "type" "store_8")
12042   (set_attr "predicable" "yes")])
12043
12044;; ARMv8 CRC32 instructions.
12045(define_insn "<crc_variant>"
12046  [(set (match_operand:SI 0 "s_register_operand" "=r")
12047        (unspec:SI [(match_operand:SI 1 "s_register_operand" "r")
12048                    (match_operand:<crc_mode> 2 "s_register_operand" "r")]
12049         CRC))]
12050  "TARGET_CRC32"
12051  "<crc_variant>\\t%0, %1, %2"
12052  [(set_attr "type" "crc")
12053   (set_attr "conds" "unconditional")]
12054)
12055
12056;; Load the load/store double peephole optimizations.
12057(include "ldrdstrd.md")
12058
12059;; Load the load/store multiple patterns
12060(include "ldmstm.md")
12061
12062;; Patterns in ldmstm.md don't cover more than 4 registers. This pattern covers
12063;; large lists without explicit writeback generated for APCS_FRAME epilogue.
12064;; The operands are validated through the load_multiple_operation
12065;; match_parallel predicate rather than through constraints so enable it only
12066;; after reload.
12067(define_insn "*load_multiple"
12068  [(match_parallel 0 "load_multiple_operation"
12069    [(set (match_operand:SI 2 "s_register_operand" "=rk")
12070          (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
12071        ])]
12072  "TARGET_32BIT && reload_completed"
12073  "*
12074  {
12075    arm_output_multireg_pop (operands, /*return_pc=*/false,
12076                                       /*cond=*/const_true_rtx,
12077                                       /*reverse=*/false,
12078                                       /*update=*/false);
12079    return \"\";
12080  }
12081  "
12082  [(set_attr "predicable" "yes")]
12083)
12084
12085(define_expand "copysignsf3"
12086  [(match_operand:SF 0 "register_operand")
12087   (match_operand:SF 1 "register_operand")
12088   (match_operand:SF 2 "register_operand")]
12089  "TARGET_SOFT_FLOAT && arm_arch_thumb2"
12090  "{
12091     emit_move_insn (operands[0], operands[2]);
12092     emit_insn (gen_insv_t2 (simplify_gen_subreg (SImode, operands[0], SFmode, 0),
12093		GEN_INT (31), GEN_INT (0),
12094		simplify_gen_subreg (SImode, operands[1], SFmode, 0)));
12095     DONE;
12096  }"
12097)
12098
12099(define_expand "copysigndf3"
12100  [(match_operand:DF 0 "register_operand")
12101   (match_operand:DF 1 "register_operand")
12102   (match_operand:DF 2 "register_operand")]
12103  "TARGET_SOFT_FLOAT && arm_arch_thumb2"
12104  "{
12105     rtx op0_low = gen_lowpart (SImode, operands[0]);
12106     rtx op0_high = gen_highpart (SImode, operands[0]);
12107     rtx op1_low = gen_lowpart (SImode, operands[1]);
12108     rtx op1_high = gen_highpart (SImode, operands[1]);
12109     rtx op2_high = gen_highpart (SImode, operands[2]);
12110
12111     rtx scratch1 = gen_reg_rtx (SImode);
12112     rtx scratch2 = gen_reg_rtx (SImode);
12113     emit_move_insn (scratch1, op2_high);
12114     emit_move_insn (scratch2, op1_high);
12115
12116     emit_insn(gen_rtx_SET(scratch1,
12117			   gen_rtx_LSHIFTRT (SImode, op2_high, GEN_INT(31))));
12118     emit_insn(gen_insv_t2(scratch2, GEN_INT(1), GEN_INT(31), scratch1));
12119     emit_move_insn (op0_low, op1_low);
12120     emit_move_insn (op0_high, scratch2);
12121
12122     DONE;
12123  }"
12124)
12125
12126;; movmisalign patterns for HImode and SImode.
12127(define_expand "movmisalign<mode>"
12128  [(match_operand:HSI 0 "general_operand")
12129   (match_operand:HSI 1 "general_operand")]
12130  "unaligned_access"
12131{
12132  /* This pattern is not permitted to fail during expansion: if both arguments
12133     are non-registers (e.g. memory := constant), force operand 1 into a
12134     register.  */
12135  rtx (* gen_unaligned_load)(rtx, rtx);
12136  rtx tmp_dest = operands[0];
12137  if (!s_register_operand (operands[0], <MODE>mode)
12138      && !s_register_operand (operands[1], <MODE>mode))
12139    operands[1] = force_reg (<MODE>mode, operands[1]);
12140
12141  if (<MODE>mode == HImode)
12142   {
12143    gen_unaligned_load = gen_unaligned_loadhiu;
12144    tmp_dest = gen_reg_rtx (SImode);
12145   }
12146  else
12147    gen_unaligned_load = gen_unaligned_loadsi;
12148
12149  if (MEM_P (operands[1]))
12150   {
12151    emit_insn (gen_unaligned_load (tmp_dest, operands[1]));
12152    if (<MODE>mode == HImode)
12153      emit_move_insn (operands[0], gen_lowpart (HImode, tmp_dest));
12154   }
12155  else
12156    emit_insn (gen_unaligned_store<mode> (operands[0], operands[1]));
12157
12158  DONE;
12159})
12160
12161(define_insn "<cdp>"
12162  [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "n")
12163		     (match_operand:SI 1 "immediate_operand" "n")
12164		     (match_operand:SI 2 "immediate_operand" "n")
12165		     (match_operand:SI 3 "immediate_operand" "n")
12166		     (match_operand:SI 4 "immediate_operand" "n")
12167		     (match_operand:SI 5 "immediate_operand" "n")] CDPI)]
12168  "arm_coproc_builtin_available (VUNSPEC_<CDP>)"
12169{
12170  arm_const_bounds (operands[0], 0, 16);
12171  arm_const_bounds (operands[1], 0, 16);
12172  arm_const_bounds (operands[2], 0, (1 << 5));
12173  arm_const_bounds (operands[3], 0, (1 << 5));
12174  arm_const_bounds (operands[4], 0, (1 << 5));
12175  arm_const_bounds (operands[5], 0, 8);
12176  return "<cdp>\\tp%c0, %1, CR%c2, CR%c3, CR%c4, %5";
12177}
12178  [(set_attr "length" "4")
12179   (set_attr "type" "coproc")])
12180
12181(define_insn "*ldc"
12182  [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "n")
12183		     (match_operand:SI 1 "immediate_operand" "n")
12184		     (match_operand:SI 2 "memory_operand" "Uz")] LDCI)]
12185  "arm_coproc_builtin_available (VUNSPEC_<LDC>)"
12186{
12187  arm_const_bounds (operands[0], 0, 16);
12188  arm_const_bounds (operands[1], 0, (1 << 5));
12189  return "<ldc>\\tp%c0, CR%c1, %2";
12190}
12191  [(set_attr "length" "4")
12192   (set_attr "type" "coproc")])
12193
12194(define_insn "*stc"
12195  [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "n")
12196		     (match_operand:SI 1 "immediate_operand" "n")
12197		     (match_operand:SI 2 "memory_operand" "=Uz")] STCI)]
12198  "arm_coproc_builtin_available (VUNSPEC_<STC>)"
12199{
12200  arm_const_bounds (operands[0], 0, 16);
12201  arm_const_bounds (operands[1], 0, (1 << 5));
12202  return "<stc>\\tp%c0, CR%c1, %2";
12203}
12204  [(set_attr "length" "4")
12205   (set_attr "type" "coproc")])
12206
12207(define_expand "<ldc>"
12208  [(unspec_volatile [(match_operand:SI 0 "immediate_operand")
12209		     (match_operand:SI 1 "immediate_operand")
12210		     (mem:SI (match_operand:SI 2 "s_register_operand"))] LDCI)]
12211  "arm_coproc_builtin_available (VUNSPEC_<LDC>)")
12212
12213(define_expand "<stc>"
12214  [(unspec_volatile [(match_operand:SI 0 "immediate_operand")
12215		     (match_operand:SI 1 "immediate_operand")
12216		     (mem:SI (match_operand:SI 2 "s_register_operand"))] STCI)]
12217  "arm_coproc_builtin_available (VUNSPEC_<STC>)")
12218
12219(define_insn "<mcr>"
12220  [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "n")
12221		     (match_operand:SI 1 "immediate_operand" "n")
12222		     (match_operand:SI 2 "s_register_operand" "r")
12223		     (match_operand:SI 3 "immediate_operand" "n")
12224		     (match_operand:SI 4 "immediate_operand" "n")
12225		     (match_operand:SI 5 "immediate_operand" "n")] MCRI)
12226   (use (match_dup 2))]
12227  "arm_coproc_builtin_available (VUNSPEC_<MCR>)"
12228{
12229  arm_const_bounds (operands[0], 0, 16);
12230  arm_const_bounds (operands[1], 0, 8);
12231  arm_const_bounds (operands[3], 0, (1 << 5));
12232  arm_const_bounds (operands[4], 0, (1 << 5));
12233  arm_const_bounds (operands[5], 0, 8);
12234  return "<mcr>\\tp%c0, %1, %2, CR%c3, CR%c4, %5";
12235}
12236  [(set_attr "length" "4")
12237   (set_attr "type" "coproc")])
12238
12239(define_insn "<mrc>"
12240  [(set (match_operand:SI 0 "s_register_operand" "=r")
12241	(unspec_volatile:SI [(match_operand:SI 1 "immediate_operand" "n")
12242			  (match_operand:SI 2 "immediate_operand" "n")
12243			  (match_operand:SI 3 "immediate_operand" "n")
12244			  (match_operand:SI 4 "immediate_operand" "n")
12245			  (match_operand:SI 5 "immediate_operand" "n")] MRCI))]
12246  "arm_coproc_builtin_available (VUNSPEC_<MRC>)"
12247{
12248  arm_const_bounds (operands[1], 0, 16);
12249  arm_const_bounds (operands[2], 0, 8);
12250  arm_const_bounds (operands[3], 0, (1 << 5));
12251  arm_const_bounds (operands[4], 0, (1 << 5));
12252  arm_const_bounds (operands[5], 0, 8);
12253  return "<mrc>\\tp%c1, %2, %0, CR%c3, CR%c4, %5";
12254}
12255  [(set_attr "length" "4")
12256   (set_attr "type" "coproc")])
12257
12258(define_insn "<mcrr>"
12259  [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "n")
12260		     (match_operand:SI 1 "immediate_operand" "n")
12261		     (match_operand:DI 2 "s_register_operand" "r")
12262		     (match_operand:SI 3 "immediate_operand" "n")] MCRRI)
12263   (use (match_dup 2))]
12264  "arm_coproc_builtin_available (VUNSPEC_<MCRR>)"
12265{
12266  arm_const_bounds (operands[0], 0, 16);
12267  arm_const_bounds (operands[1], 0, 8);
12268  arm_const_bounds (operands[3], 0, (1 << 5));
12269  return "<mcrr>\\tp%c0, %1, %Q2, %R2, CR%c3";
12270}
12271  [(set_attr "length" "4")
12272   (set_attr "type" "coproc")])
12273
12274(define_insn "<mrrc>"
12275  [(set (match_operand:DI 0 "s_register_operand" "=r")
12276	(unspec_volatile:DI [(match_operand:SI 1 "immediate_operand" "n")
12277			  (match_operand:SI 2 "immediate_operand" "n")
12278			  (match_operand:SI 3 "immediate_operand" "n")] MRRCI))]
12279  "arm_coproc_builtin_available (VUNSPEC_<MRRC>)"
12280{
12281  arm_const_bounds (operands[1], 0, 16);
12282  arm_const_bounds (operands[2], 0, 8);
12283  arm_const_bounds (operands[3], 0, (1 << 5));
12284  return "<mrrc>\\tp%c1, %2, %Q0, %R0, CR%c3";
12285}
12286  [(set_attr "length" "4")
12287   (set_attr "type" "coproc")])
12288
12289(define_expand "speculation_barrier"
12290  [(unspec_volatile [(const_int 0)] VUNSPEC_SPECULATION_BARRIER)]
12291  "TARGET_EITHER"
12292  "
12293  /* For thumb1 (except Armv8 derivatives), and for pre-Armv7 we don't
12294     have a usable barrier (and probably don't need one in practice).
12295     But to be safe if such code is run on later architectures, call a
12296     helper function in libgcc that will do the thing for the active
12297     system.  */
12298  if (!(arm_arch7 || arm_arch8))
12299    {
12300      arm_emit_speculation_barrier_function ();
12301      DONE;
12302    }
12303  "
12304)
12305
12306;; Generate a hard speculation barrier when we have not enabled speculation
12307;; tracking.
12308(define_insn "*speculation_barrier_insn"
12309  [(unspec_volatile [(const_int 0)] VUNSPEC_SPECULATION_BARRIER)]
12310  "arm_arch7 || arm_arch8"
12311  "isb\;dsb\\tsy"
12312  [(set_attr "type" "block")
12313   (set_attr "length" "8")]
12314)
12315
12316;; Vector bits common to IWMMXT and Neon
12317(include "vec-common.md")
12318;; Load the Intel Wireless Multimedia Extension patterns
12319(include "iwmmxt.md")
12320;; Load the VFP co-processor patterns
12321(include "vfp.md")
12322;; Thumb-1 patterns
12323(include "thumb1.md")
12324;; Thumb-2 patterns
12325(include "thumb2.md")
12326;; Neon patterns
12327(include "neon.md")
12328;; Crypto patterns
12329(include "crypto.md")
12330;; Synchronization Primitives
12331(include "sync.md")
12332;; Fixed-point patterns
12333(include "arm-fixed.md")
12334