1;;- Machine description for ARM for GNU compiler
2;;  Copyright (C) 1991-2018 Free Software Foundation, Inc.
3;;  Contributed by Pieter `Tiggr' Schoenmakers (rcpieter@win.tue.nl)
4;;  and Martin Simmons (@harleqn.co.uk).
5;;  More major hacks by Richard Earnshaw (rearnsha@arm.com).
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 can not 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,arm1020e,arm1026ejs,arm1136js,\
388                                arm1136jfs,cortexa5,cortexa7,cortexa8,\
389                                cortexa9,cortexa12,cortexa15,cortexa17,\
390                                cortexa53,cortexa57,cortexm4,cortexm7,\
391				exynosm1,marvell_pj4,xgene1")
392	       (eq_attr "tune_cortexr4" "yes"))
393          (const_string "no")
394          (const_string "yes"))))
395
396(define_attr "generic_vfp" "yes,no"
397  (const (if_then_else
398	  (and (eq_attr "fpu" "vfp")
399	       (eq_attr "tune" "!arm1020e,arm1022e,cortexa5,cortexa7,\
400                                cortexa8,cortexa9,cortexa53,cortexm4,\
401                                cortexm7,marvell_pj4,xgene1")
402	       (eq_attr "tune_cortexr4" "no"))
403	  (const_string "yes")
404	  (const_string "no"))))
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 addsi3_compare0_for_combiner when the
861;; addend is a constant.
862(define_insn "cmpsi2_addneg"
863  [(set (reg:CC CC_REGNUM)
864	(compare:CC
865	 (match_operand:SI 1 "s_register_operand" "r,r")
866	 (match_operand:SI 2 "arm_addimm_operand" "L,I")))
867   (set (match_operand:SI 0 "s_register_operand" "=r,r")
868	(plus:SI (match_dup 1)
869		 (match_operand:SI 3 "arm_addimm_operand" "I,L")))]
870  "TARGET_32BIT && INTVAL (operands[2]) == -INTVAL (operands[3])"
871  "@
872   adds%?\\t%0, %1, %3
873   subs%?\\t%0, %1, #%n3"
874  [(set_attr "conds" "set")
875   (set_attr "type" "alus_sreg")]
876)
877
878;; Convert the sequence
879;;  sub  rd, rn, #1
880;;  cmn  rd, #1	(equivalent to cmp rd, #-1)
881;;  bne  dest
882;; into
883;;  subs rd, rn, #1
884;;  bcs  dest	((unsigned)rn >= 1)
885;; similarly for the beq variant using bcc.
886;; This is a common looping idiom (while (n--))
887(define_peephole2
888  [(set (match_operand:SI 0 "arm_general_register_operand" "")
889	(plus:SI (match_operand:SI 1 "arm_general_register_operand" "")
890		 (const_int -1)))
891   (set (match_operand 2 "cc_register" "")
892	(compare (match_dup 0) (const_int -1)))
893   (set (pc)
894	(if_then_else (match_operator 3 "equality_operator"
895		       [(match_dup 2) (const_int 0)])
896		      (match_operand 4 "" "")
897		      (match_operand 5 "" "")))]
898  "TARGET_32BIT && peep2_reg_dead_p (3, operands[2])"
899  [(parallel[
900    (set (match_dup 2)
901	 (compare:CC
902	  (match_dup 1) (const_int 1)))
903    (set (match_dup 0) (plus:SI (match_dup 1) (const_int -1)))])
904   (set (pc)
905	(if_then_else (match_op_dup 3 [(match_dup 2) (const_int 0)])
906		      (match_dup 4)
907		      (match_dup 5)))]
908  "operands[2] = gen_rtx_REG (CCmode, CC_REGNUM);
909   operands[3] = gen_rtx_fmt_ee ((GET_CODE (operands[3]) == NE
910				  ? GEU : LTU),
911				 VOIDmode,
912				 operands[2], const0_rtx);"
913)
914
915;; The next four insns work because they compare the result with one of
916;; the operands, and we know that the use of the condition code is
917;; either GEU or LTU, so we can use the carry flag from the addition
918;; instead of doing the compare a second time.
919(define_insn "*addsi3_compare_op1"
920  [(set (reg:CC_C CC_REGNUM)
921	(compare:CC_C
922	 (plus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
923		  (match_operand:SI 2 "arm_add_operand" "I,L,r"))
924	 (match_dup 1)))
925   (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
926	(plus:SI (match_dup 1) (match_dup 2)))]
927  "TARGET_32BIT"
928  "@
929   adds%?\\t%0, %1, %2
930   subs%?\\t%0, %1, #%n2
931   adds%?\\t%0, %1, %2"
932  [(set_attr "conds" "set")
933   (set_attr "type"  "alus_imm,alus_imm,alus_sreg")]
934)
935
936(define_insn "*addsi3_compare_op2"
937  [(set (reg:CC_C CC_REGNUM)
938	(compare:CC_C
939	 (plus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
940		  (match_operand:SI 2 "arm_add_operand" "I,L,r"))
941	 (match_dup 2)))
942   (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
943	(plus:SI (match_dup 1) (match_dup 2)))]
944  "TARGET_32BIT"
945  "@
946   adds%?\\t%0, %1, %2
947   subs%?\\t%0, %1, #%n2
948   adds%?\\t%0, %1, %2"
949  [(set_attr "conds" "set")
950   (set_attr "type" "alus_imm,alus_imm,alus_sreg")]
951)
952
953(define_insn "*compare_addsi2_op0"
954  [(set (reg:CC_C CC_REGNUM)
955        (compare:CC_C
956          (plus:SI (match_operand:SI 0 "s_register_operand" "l,l,r,r,r")
957                   (match_operand:SI 1 "arm_add_operand" "Pv,l,I,L,r"))
958          (match_dup 0)))]
959  "TARGET_32BIT"
960  "@
961   cmp%?\\t%0, #%n1
962   cmn%?\\t%0, %1
963   cmn%?\\t%0, %1
964   cmp%?\\t%0, #%n1
965   cmn%?\\t%0, %1"
966  [(set_attr "conds" "set")
967   (set_attr "predicable" "yes")
968   (set_attr "arch" "t2,t2,*,*,*")
969   (set_attr "predicable_short_it" "yes,yes,no,no,no")
970   (set_attr "length" "2,2,4,4,4")
971   (set_attr "type" "alus_imm,alus_sreg,alus_imm,alus_imm,alus_sreg")]
972)
973
974(define_insn "*compare_addsi2_op1"
975  [(set (reg:CC_C CC_REGNUM)
976        (compare:CC_C
977          (plus:SI (match_operand:SI 0 "s_register_operand" "l,l,r,r,r")
978                   (match_operand:SI 1 "arm_add_operand" "Pv,l,I,L,r"))
979          (match_dup 1)))]
980  "TARGET_32BIT"
981  "@
982   cmp%?\\t%0, #%n1
983   cmn%?\\t%0, %1
984   cmn%?\\t%0, %1
985   cmp%?\\t%0, #%n1
986   cmn%?\\t%0, %1"
987  [(set_attr "conds" "set")
988   (set_attr "predicable" "yes")
989   (set_attr "arch" "t2,t2,*,*,*")
990   (set_attr "predicable_short_it" "yes,yes,no,no,no")
991   (set_attr "length" "2,2,4,4,4")
992   (set_attr "type" "alus_imm,alus_sreg,alus_imm,alus_imm,alus_sreg")]
993 )
994
995(define_insn "*addsi3_carryin_<optab>"
996  [(set (match_operand:SI 0 "s_register_operand" "=l,r,r")
997        (plus:SI (plus:SI (match_operand:SI 1 "s_register_operand" "%l,r,r")
998                          (match_operand:SI 2 "arm_not_operand" "0,rI,K"))
999                 (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))))]
1000  "TARGET_32BIT"
1001  "@
1002   adc%?\\t%0, %1, %2
1003   adc%?\\t%0, %1, %2
1004   sbc%?\\t%0, %1, #%B2"
1005  [(set_attr "conds" "use")
1006   (set_attr "predicable" "yes")
1007   (set_attr "arch" "t2,*,*")
1008   (set_attr "length" "4")
1009   (set_attr "predicable_short_it" "yes,no,no")
1010   (set_attr "type" "adc_reg,adc_reg,adc_imm")]
1011)
1012
1013(define_insn "*addsi3_carryin_alt2_<optab>"
1014  [(set (match_operand:SI 0 "s_register_operand" "=l,r,r")
1015        (plus:SI (plus:SI (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))
1016                          (match_operand:SI 1 "s_register_operand" "%l,r,r"))
1017                 (match_operand:SI 2 "arm_rhs_operand" "l,rI,K")))]
1018  "TARGET_32BIT"
1019  "@
1020   adc%?\\t%0, %1, %2
1021   adc%?\\t%0, %1, %2
1022   sbc%?\\t%0, %1, #%B2"
1023  [(set_attr "conds" "use")
1024   (set_attr "predicable" "yes")
1025   (set_attr "arch" "t2,*,*")
1026   (set_attr "length" "4")
1027   (set_attr "predicable_short_it" "yes,no,no")
1028   (set_attr "type" "adc_reg,adc_reg,adc_imm")]
1029)
1030
1031(define_insn "*addsi3_carryin_shift_<optab>"
1032  [(set (match_operand:SI 0 "s_register_operand" "=r")
1033	(plus:SI (plus:SI
1034		  (match_operator:SI 2 "shift_operator"
1035		    [(match_operand:SI 3 "s_register_operand" "r")
1036		     (match_operand:SI 4 "reg_or_int_operand" "rM")])
1037		  (match_operand:SI 1 "s_register_operand" "r"))
1038		 (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))))]
1039  "TARGET_32BIT"
1040  "adc%?\\t%0, %1, %3%S2"
1041  [(set_attr "conds" "use")
1042   (set_attr "predicable" "yes")
1043   (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
1044		      (const_string "alu_shift_imm")
1045		      (const_string "alu_shift_reg")))]
1046)
1047
1048(define_insn "*addsi3_carryin_clobercc_<optab>"
1049  [(set (match_operand:SI 0 "s_register_operand" "=r")
1050	(plus:SI (plus:SI (match_operand:SI 1 "s_register_operand" "%r")
1051			  (match_operand:SI 2 "arm_rhs_operand" "rI"))
1052		 (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))))
1053   (clobber (reg:CC CC_REGNUM))]
1054   "TARGET_32BIT"
1055   "adcs%?\\t%0, %1, %2"
1056   [(set_attr "conds" "set")
1057    (set_attr "type" "adcs_reg")]
1058)
1059
1060(define_expand "subv<mode>4"
1061  [(match_operand:SIDI 0 "register_operand")
1062   (match_operand:SIDI 1 "register_operand")
1063   (match_operand:SIDI 2 "register_operand")
1064   (match_operand 3 "")]
1065  "TARGET_32BIT"
1066{
1067  emit_insn (gen_sub<mode>3_compare1 (operands[0], operands[1], operands[2]));
1068  arm_gen_unlikely_cbranch (NE, CC_Vmode, operands[3]);
1069
1070  DONE;
1071})
1072
1073(define_expand "usubv<mode>4"
1074  [(match_operand:SIDI 0 "register_operand")
1075   (match_operand:SIDI 1 "register_operand")
1076   (match_operand:SIDI 2 "register_operand")
1077   (match_operand 3 "")]
1078  "TARGET_32BIT"
1079{
1080  emit_insn (gen_sub<mode>3_compare1 (operands[0], operands[1], operands[2]));
1081  arm_gen_unlikely_cbranch (LTU, CCmode, operands[3]);
1082
1083  DONE;
1084})
1085
1086(define_insn_and_split "subdi3_compare1"
1087  [(set (reg:CC CC_REGNUM)
1088	(compare:CC
1089	  (match_operand:DI 1 "register_operand" "r")
1090	  (match_operand:DI 2 "register_operand" "r")))
1091   (set (match_operand:DI 0 "register_operand" "=&r")
1092	(minus:DI (match_dup 1) (match_dup 2)))]
1093  "TARGET_32BIT"
1094  "#"
1095  "&& reload_completed"
1096  [(parallel [(set (reg:CC CC_REGNUM)
1097		   (compare:CC (match_dup 1) (match_dup 2)))
1098	      (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1099   (parallel [(set (reg:CC CC_REGNUM)
1100		   (compare:CC (match_dup 4) (match_dup 5)))
1101	     (set (match_dup 3) (minus:SI (minus:SI (match_dup 4) (match_dup 5))
1102			       (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))])]
1103  {
1104    operands[3] = gen_highpart (SImode, operands[0]);
1105    operands[0] = gen_lowpart (SImode, operands[0]);
1106    operands[4] = gen_highpart (SImode, operands[1]);
1107    operands[1] = gen_lowpart (SImode, operands[1]);
1108    operands[5] = gen_highpart (SImode, operands[2]);
1109    operands[2] = gen_lowpart (SImode, operands[2]);
1110   }
1111  [(set_attr "conds" "set")
1112   (set_attr "length" "8")
1113   (set_attr "type" "multiple")]
1114)
1115
1116(define_insn "subsi3_compare1"
1117  [(set (reg:CC CC_REGNUM)
1118	(compare:CC
1119	  (match_operand:SI 1 "register_operand" "r")
1120	  (match_operand:SI 2 "register_operand" "r")))
1121   (set (match_operand:SI 0 "register_operand" "=r")
1122	(minus:SI (match_dup 1) (match_dup 2)))]
1123  "TARGET_32BIT"
1124  "subs%?\\t%0, %1, %2"
1125  [(set_attr "conds" "set")
1126   (set_attr "type" "alus_sreg")]
1127)
1128
1129(define_insn "*subsi3_carryin"
1130  [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
1131	(minus:SI (minus:SI (match_operand:SI 1 "reg_or_int_operand" "r,I,Pz")
1132			    (match_operand:SI 2 "s_register_operand" "r,r,r"))
1133		  (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1134  "TARGET_32BIT"
1135  "@
1136   sbc%?\\t%0, %1, %2
1137   rsc%?\\t%0, %2, %1
1138   sbc%?\\t%0, %2, %2, lsl #1"
1139  [(set_attr "conds" "use")
1140   (set_attr "arch" "*,a,t2")
1141   (set_attr "predicable" "yes")
1142   (set_attr "type" "adc_reg,adc_imm,alu_shift_imm")]
1143)
1144
1145(define_insn "*subsi3_carryin_const"
1146  [(set (match_operand:SI 0 "s_register_operand" "=r")
1147        (minus:SI (plus:SI (match_operand:SI 1 "s_register_operand" "r")
1148                           (match_operand:SI 2 "arm_not_immediate_operand" "K"))
1149                  (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1150  "TARGET_32BIT"
1151  "sbc\\t%0, %1, #%B2"
1152  [(set_attr "conds" "use")
1153   (set_attr "type" "adc_imm")]
1154)
1155
1156(define_insn "*subsi3_carryin_compare"
1157  [(set (reg:CC CC_REGNUM)
1158        (compare:CC (match_operand:SI 1 "s_register_operand" "r")
1159                    (match_operand:SI 2 "s_register_operand" "r")))
1160   (set (match_operand:SI 0 "s_register_operand" "=r")
1161        (minus:SI (minus:SI (match_dup 1)
1162                            (match_dup 2))
1163                  (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1164  "TARGET_32BIT"
1165  "sbcs\\t%0, %1, %2"
1166  [(set_attr "conds" "set")
1167   (set_attr "type" "adcs_reg")]
1168)
1169
1170(define_insn "*subsi3_carryin_compare_const"
1171  [(set (reg:CC CC_REGNUM)
1172        (compare:CC (match_operand:SI 1 "reg_or_int_operand" "r")
1173                    (match_operand:SI 2 "arm_not_operand" "K")))
1174   (set (match_operand:SI 0 "s_register_operand" "=r")
1175        (minus:SI (plus:SI (match_dup 1)
1176                           (match_dup 2))
1177                  (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1178  "TARGET_32BIT"
1179  "sbcs\\t%0, %1, #%B2"
1180  [(set_attr "conds" "set")
1181   (set_attr "type" "adcs_imm")]
1182)
1183
1184(define_insn "*subsi3_carryin_shift"
1185  [(set (match_operand:SI 0 "s_register_operand" "=r")
1186	(minus:SI (minus:SI
1187		  (match_operand:SI 1 "s_register_operand" "r")
1188                  (match_operator:SI 2 "shift_operator"
1189                   [(match_operand:SI 3 "s_register_operand" "r")
1190                    (match_operand:SI 4 "reg_or_int_operand" "rM")]))
1191                 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1192  "TARGET_32BIT"
1193  "sbc%?\\t%0, %1, %3%S2"
1194  [(set_attr "conds" "use")
1195   (set_attr "predicable" "yes")
1196   (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
1197		      (const_string "alu_shift_imm")
1198                     (const_string "alu_shift_reg")))]
1199)
1200
1201(define_insn "*rsbsi3_carryin_shift"
1202  [(set (match_operand:SI 0 "s_register_operand" "=r")
1203	(minus:SI (minus:SI
1204                  (match_operator:SI 2 "shift_operator"
1205                   [(match_operand:SI 3 "s_register_operand" "r")
1206                    (match_operand:SI 4 "reg_or_int_operand" "rM")])
1207		   (match_operand:SI 1 "s_register_operand" "r"))
1208                 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1209  "TARGET_ARM"
1210  "rsc%?\\t%0, %1, %3%S2"
1211  [(set_attr "conds" "use")
1212   (set_attr "predicable" "yes")
1213   (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
1214		      (const_string "alu_shift_imm")
1215		      (const_string "alu_shift_reg")))]
1216)
1217
1218; transform ((x << y) - 1) to ~(~(x-1) << y)  Where X is a constant.
1219(define_split
1220  [(set (match_operand:SI 0 "s_register_operand" "")
1221	(plus:SI (ashift:SI (match_operand:SI 1 "const_int_operand" "")
1222			    (match_operand:SI 2 "s_register_operand" ""))
1223		 (const_int -1)))
1224   (clobber (match_operand:SI 3 "s_register_operand" ""))]
1225  "TARGET_32BIT"
1226  [(set (match_dup 3) (match_dup 1))
1227   (set (match_dup 0) (not:SI (ashift:SI (match_dup 3) (match_dup 2))))]
1228  "
1229  operands[1] = GEN_INT (~(INTVAL (operands[1]) - 1));
1230")
1231
1232(define_expand "addsf3"
1233  [(set (match_operand:SF          0 "s_register_operand" "")
1234	(plus:SF (match_operand:SF 1 "s_register_operand" "")
1235		 (match_operand:SF 2 "s_register_operand" "")))]
1236  "TARGET_32BIT && TARGET_HARD_FLOAT"
1237  "
1238")
1239
1240(define_expand "adddf3"
1241  [(set (match_operand:DF          0 "s_register_operand" "")
1242	(plus:DF (match_operand:DF 1 "s_register_operand" "")
1243		 (match_operand:DF 2 "s_register_operand" "")))]
1244  "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
1245  "
1246")
1247
1248(define_expand "subdi3"
1249 [(parallel
1250   [(set (match_operand:DI            0 "s_register_operand" "")
1251	  (minus:DI (match_operand:DI 1 "s_register_operand" "")
1252	            (match_operand:DI 2 "s_register_operand" "")))
1253    (clobber (reg:CC CC_REGNUM))])]
1254  "TARGET_EITHER"
1255  "
1256  if (TARGET_THUMB1)
1257    {
1258      if (!REG_P (operands[1]))
1259        operands[1] = force_reg (DImode, operands[1]);
1260      if (!REG_P (operands[2]))
1261        operands[2] = force_reg (DImode, operands[2]);
1262     }
1263  "
1264)
1265
1266(define_insn_and_split "*arm_subdi3"
1267  [(set (match_operand:DI           0 "arm_general_register_operand" "=&r,&r,&r")
1268	(minus:DI (match_operand:DI 1 "arm_general_register_operand" "0,r,0")
1269		  (match_operand:DI 2 "arm_general_register_operand" "r,0,0")))
1270   (clobber (reg:CC CC_REGNUM))]
1271  "TARGET_32BIT && !TARGET_NEON"
1272  "#"  ; "subs\\t%Q0, %Q1, %Q2\;sbc\\t%R0, %R1, %R2"
1273  "&& (!TARGET_IWMMXT || reload_completed)"
1274  [(parallel [(set (reg:CC CC_REGNUM)
1275		   (compare:CC (match_dup 1) (match_dup 2)))
1276	      (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1277   (set (match_dup 3) (minus:SI (minus:SI (match_dup 4) (match_dup 5))
1278			       (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1279  {
1280    operands[3] = gen_highpart (SImode, operands[0]);
1281    operands[0] = gen_lowpart (SImode, operands[0]);
1282    operands[4] = gen_highpart (SImode, operands[1]);
1283    operands[1] = gen_lowpart (SImode, operands[1]);
1284    operands[5] = gen_highpart (SImode, operands[2]);
1285    operands[2] = gen_lowpart (SImode, operands[2]);
1286   }
1287  [(set_attr "conds" "clob")
1288   (set_attr "length" "8")
1289   (set_attr "type" "multiple")]
1290)
1291
1292(define_insn_and_split "*subdi_di_zesidi"
1293  [(set (match_operand:DI           0 "s_register_operand" "=&r,&r")
1294	(minus:DI (match_operand:DI 1 "s_register_operand"  "0,r")
1295		  (zero_extend:DI
1296		   (match_operand:SI 2 "s_register_operand"  "r,r"))))
1297   (clobber (reg:CC CC_REGNUM))]
1298  "TARGET_32BIT"
1299  "#"   ; "subs\\t%Q0, %Q1, %2\;sbc\\t%R0, %R1, #0"
1300  "&& reload_completed"
1301  [(parallel [(set (reg:CC CC_REGNUM)
1302		   (compare:CC (match_dup 1) (match_dup 2)))
1303	      (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1304   (set (match_dup 3) (minus:SI (plus:SI (match_dup 4) (match_dup 5))
1305                                (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1306  {
1307    operands[3] = gen_highpart (SImode, operands[0]);
1308    operands[0] = gen_lowpart (SImode, operands[0]);
1309    operands[4] = gen_highpart (SImode, operands[1]);
1310    operands[1] = gen_lowpart (SImode, operands[1]);
1311    operands[5] = GEN_INT (~0);
1312   }
1313  [(set_attr "conds" "clob")
1314   (set_attr "length" "8")
1315   (set_attr "type" "multiple")]
1316)
1317
1318(define_insn_and_split "*subdi_di_sesidi"
1319  [(set (match_operand:DI            0 "s_register_operand" "=&r,&r")
1320	(minus:DI (match_operand:DI  1 "s_register_operand"  "0,r")
1321		  (sign_extend:DI
1322		   (match_operand:SI 2 "s_register_operand"  "r,r"))))
1323   (clobber (reg:CC CC_REGNUM))]
1324  "TARGET_32BIT"
1325  "#"   ; "subs\\t%Q0, %Q1, %2\;sbc\\t%R0, %R1, %2, asr #31"
1326  "&& reload_completed"
1327  [(parallel [(set (reg:CC CC_REGNUM)
1328		   (compare:CC (match_dup 1) (match_dup 2)))
1329	      (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1330   (set (match_dup 3) (minus:SI (minus:SI (match_dup 4)
1331                                         (ashiftrt:SI (match_dup 2)
1332                                                      (const_int 31)))
1333                                (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1334  {
1335    operands[3] = gen_highpart (SImode, operands[0]);
1336    operands[0] = gen_lowpart (SImode, operands[0]);
1337    operands[4] = gen_highpart (SImode, operands[1]);
1338    operands[1] = gen_lowpart (SImode, operands[1]);
1339  }
1340  [(set_attr "conds" "clob")
1341   (set_attr "length" "8")
1342   (set_attr "type" "multiple")]
1343)
1344
1345(define_insn_and_split "*subdi_zesidi_di"
1346  [(set (match_operand:DI            0 "s_register_operand" "=&r,&r")
1347	(minus:DI (zero_extend:DI
1348		   (match_operand:SI 2 "s_register_operand"  "r,r"))
1349		  (match_operand:DI  1 "s_register_operand" "0,r")))
1350   (clobber (reg:CC CC_REGNUM))]
1351  "TARGET_ARM"
1352  "#"   ; "rsbs\\t%Q0, %Q1, %2\;rsc\\t%R0, %R1, #0"
1353        ; is equivalent to:
1354        ; "subs\\t%Q0, %2, %Q1\;rsc\\t%R0, %R1, #0"
1355  "&& reload_completed"
1356  [(parallel [(set (reg:CC CC_REGNUM)
1357		   (compare:CC (match_dup 2) (match_dup 1)))
1358	      (set (match_dup 0) (minus:SI (match_dup 2) (match_dup 1)))])
1359   (set (match_dup 3) (minus:SI (minus:SI (const_int 0) (match_dup 4))
1360			       (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1361  {
1362    operands[3] = gen_highpart (SImode, operands[0]);
1363    operands[0] = gen_lowpart (SImode, operands[0]);
1364    operands[4] = gen_highpart (SImode, operands[1]);
1365    operands[1] = gen_lowpart (SImode, operands[1]);
1366  }
1367  [(set_attr "conds" "clob")
1368   (set_attr "length" "8")
1369   (set_attr "type" "multiple")]
1370)
1371
1372(define_insn_and_split "*subdi_sesidi_di"
1373  [(set (match_operand:DI            0 "s_register_operand" "=&r,&r")
1374	(minus:DI (sign_extend:DI
1375		   (match_operand:SI 2 "s_register_operand"   "r,r"))
1376		  (match_operand:DI  1 "s_register_operand"  "0,r")))
1377   (clobber (reg:CC CC_REGNUM))]
1378  "TARGET_ARM"
1379  "#"   ; "rsbs\\t%Q0, %Q1, %2\;rsc\\t%R0, %R1, %2, asr #31"
1380        ; is equivalent to:
1381        ; "subs\\t%Q0, %2, %Q1\;rsc\\t%R0, %R1, %2, asr #31"
1382  "&& reload_completed"
1383  [(parallel [(set (reg:CC CC_REGNUM)
1384		   (compare:CC (match_dup 2) (match_dup 1)))
1385	      (set (match_dup 0) (minus:SI (match_dup 2) (match_dup 1)))])
1386   (set (match_dup 3) (minus:SI (minus:SI
1387                                (ashiftrt:SI (match_dup 2)
1388                                             (const_int 31))
1389                                (match_dup 4))
1390			       (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1391  {
1392    operands[3] = gen_highpart (SImode, operands[0]);
1393    operands[0] = gen_lowpart (SImode, operands[0]);
1394    operands[4] = gen_highpart (SImode, operands[1]);
1395    operands[1] = gen_lowpart (SImode, operands[1]);
1396  }
1397  [(set_attr "conds" "clob")
1398   (set_attr "length" "8")
1399   (set_attr "type" "multiple")]
1400)
1401
1402(define_insn_and_split "*subdi_zesidi_zesidi"
1403  [(set (match_operand:DI            0 "s_register_operand" "=r")
1404	(minus:DI (zero_extend:DI
1405		   (match_operand:SI 1 "s_register_operand"  "r"))
1406		  (zero_extend:DI
1407		   (match_operand:SI 2 "s_register_operand"  "r"))))
1408   (clobber (reg:CC CC_REGNUM))]
1409  "TARGET_32BIT"
1410  "#"   ; "subs\\t%Q0, %1, %2\;sbc\\t%R0, %1, %1"
1411  "&& reload_completed"
1412  [(parallel [(set (reg:CC CC_REGNUM)
1413		   (compare:CC (match_dup 1) (match_dup 2)))
1414	      (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1415   (set (match_dup 3) (minus:SI (minus:SI (match_dup 1) (match_dup 1))
1416			       (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1417  {
1418       operands[3] = gen_highpart (SImode, operands[0]);
1419       operands[0] = gen_lowpart (SImode, operands[0]);
1420  }
1421  [(set_attr "conds" "clob")
1422   (set_attr "length" "8")
1423   (set_attr "type" "multiple")]
1424)
1425
1426(define_expand "subsi3"
1427  [(set (match_operand:SI           0 "s_register_operand" "")
1428	(minus:SI (match_operand:SI 1 "reg_or_int_operand" "")
1429		  (match_operand:SI 2 "s_register_operand" "")))]
1430  "TARGET_EITHER"
1431  "
1432  if (CONST_INT_P (operands[1]))
1433    {
1434      if (TARGET_32BIT)
1435        {
1436	  if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[1]), MINUS))
1437	    operands[1] = force_reg (SImode, operands[1]);
1438	  else
1439	    {
1440	      arm_split_constant (MINUS, SImode, NULL_RTX,
1441				  INTVAL (operands[1]), operands[0],
1442				  operands[2],
1443				  optimize && can_create_pseudo_p ());
1444	      DONE;
1445	    }
1446	}
1447      else /* TARGET_THUMB1 */
1448        operands[1] = force_reg (SImode, operands[1]);
1449    }
1450  "
1451)
1452
1453; ??? Check Thumb-2 split length
1454(define_insn_and_split "*arm_subsi3_insn"
1455  [(set (match_operand:SI           0 "s_register_operand" "=l,l ,l ,l ,r,r,r,rk,r")
1456	(minus:SI (match_operand:SI 1 "reg_or_int_operand" "l ,0 ,l ,Pz,I,r,r,k ,?n")
1457		  (match_operand:SI 2 "reg_or_int_operand" "l ,Py,Pd,l ,r,I,r,r ,r")))]
1458  "TARGET_32BIT"
1459  "@
1460   sub%?\\t%0, %1, %2
1461   sub%?\\t%0, %2
1462   sub%?\\t%0, %1, %2
1463   rsb%?\\t%0, %2, %1
1464   rsb%?\\t%0, %2, %1
1465   sub%?\\t%0, %1, %2
1466   sub%?\\t%0, %1, %2
1467   sub%?\\t%0, %1, %2
1468   #"
1469  "&& (CONST_INT_P (operands[1])
1470       && !const_ok_for_arm (INTVAL (operands[1])))"
1471  [(clobber (const_int 0))]
1472  "
1473  arm_split_constant (MINUS, SImode, curr_insn,
1474                      INTVAL (operands[1]), operands[0], operands[2], 0);
1475  DONE;
1476  "
1477  [(set_attr "length" "4,4,4,4,4,4,4,4,16")
1478   (set_attr "arch" "t2,t2,t2,t2,*,*,*,*,*")
1479   (set_attr "predicable" "yes")
1480   (set_attr "predicable_short_it" "yes,yes,yes,yes,no,no,no,no,no")
1481   (set_attr "type" "alu_sreg,alu_sreg,alu_sreg,alu_sreg,alu_imm,alu_imm,alu_sreg,alu_sreg,multiple")]
1482)
1483
1484(define_peephole2
1485  [(match_scratch:SI 3 "r")
1486   (set (match_operand:SI 0 "arm_general_register_operand" "")
1487	(minus:SI (match_operand:SI 1 "const_int_operand" "")
1488		  (match_operand:SI 2 "arm_general_register_operand" "")))]
1489  "TARGET_32BIT
1490   && !const_ok_for_arm (INTVAL (operands[1]))
1491   && const_ok_for_arm (~INTVAL (operands[1]))"
1492  [(set (match_dup 3) (match_dup 1))
1493   (set (match_dup 0) (minus:SI (match_dup 3) (match_dup 2)))]
1494  ""
1495)
1496
1497(define_insn "subsi3_compare0"
1498  [(set (reg:CC_NOOV CC_REGNUM)
1499	(compare:CC_NOOV
1500	 (minus:SI (match_operand:SI 1 "arm_rhs_operand" "r,r,I")
1501		   (match_operand:SI 2 "arm_rhs_operand" "I,r,r"))
1502	 (const_int 0)))
1503   (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
1504	(minus:SI (match_dup 1) (match_dup 2)))]
1505  "TARGET_32BIT"
1506  "@
1507   subs%?\\t%0, %1, %2
1508   subs%?\\t%0, %1, %2
1509   rsbs%?\\t%0, %2, %1"
1510  [(set_attr "conds" "set")
1511   (set_attr "type"  "alus_imm,alus_sreg,alus_sreg")]
1512)
1513
1514(define_insn "subsi3_compare"
1515  [(set (reg:CC CC_REGNUM)
1516	(compare:CC (match_operand:SI 1 "arm_rhs_operand" "r,r,I")
1517		    (match_operand:SI 2 "arm_rhs_operand" "I,r,r")))
1518   (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
1519	(minus:SI (match_dup 1) (match_dup 2)))]
1520  "TARGET_32BIT"
1521  "@
1522   subs%?\\t%0, %1, %2
1523   subs%?\\t%0, %1, %2
1524   rsbs%?\\t%0, %2, %1"
1525  [(set_attr "conds" "set")
1526   (set_attr "type" "alus_imm,alus_sreg,alus_sreg")]
1527)
1528
1529(define_expand "subsf3"
1530  [(set (match_operand:SF           0 "s_register_operand" "")
1531	(minus:SF (match_operand:SF 1 "s_register_operand" "")
1532		  (match_operand:SF 2 "s_register_operand" "")))]
1533  "TARGET_32BIT && TARGET_HARD_FLOAT"
1534  "
1535")
1536
1537(define_expand "subdf3"
1538  [(set (match_operand:DF           0 "s_register_operand" "")
1539	(minus:DF (match_operand:DF 1 "s_register_operand" "")
1540		  (match_operand:DF 2 "s_register_operand" "")))]
1541  "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
1542  "
1543")
1544
1545
1546;; Multiplication insns
1547
1548(define_expand "mulhi3"
1549  [(set (match_operand:HI 0 "s_register_operand" "")
1550	(mult:HI (match_operand:HI 1 "s_register_operand" "")
1551		 (match_operand:HI 2 "s_register_operand" "")))]
1552  "TARGET_DSP_MULTIPLY"
1553  "
1554  {
1555    rtx result = gen_reg_rtx (SImode);
1556    emit_insn (gen_mulhisi3 (result, operands[1], operands[2]));
1557    emit_move_insn (operands[0], gen_lowpart (HImode, result));
1558    DONE;
1559  }"
1560)
1561
1562(define_expand "mulsi3"
1563  [(set (match_operand:SI          0 "s_register_operand" "")
1564	(mult:SI (match_operand:SI 2 "s_register_operand" "")
1565		 (match_operand:SI 1 "s_register_operand" "")))]
1566  "TARGET_EITHER"
1567  ""
1568)
1569
1570;; Use `&' and then `0' to prevent the operands 0 and 1 being the same
1571(define_insn "*arm_mulsi3"
1572  [(set (match_operand:SI          0 "s_register_operand" "=&r,&r")
1573	(mult:SI (match_operand:SI 2 "s_register_operand" "r,r")
1574		 (match_operand:SI 1 "s_register_operand" "%0,r")))]
1575  "TARGET_32BIT && !arm_arch6"
1576  "mul%?\\t%0, %2, %1"
1577  [(set_attr "type" "mul")
1578   (set_attr "predicable" "yes")]
1579)
1580
1581(define_insn "*arm_mulsi3_v6"
1582  [(set (match_operand:SI          0 "s_register_operand" "=l,l,r")
1583	(mult:SI (match_operand:SI 1 "s_register_operand" "0,l,r")
1584		 (match_operand:SI 2 "s_register_operand" "l,0,r")))]
1585  "TARGET_32BIT && arm_arch6"
1586  "mul%?\\t%0, %1, %2"
1587  [(set_attr "type" "mul")
1588   (set_attr "predicable" "yes")
1589   (set_attr "arch" "t2,t2,*")
1590   (set_attr "length" "4")
1591   (set_attr "predicable_short_it" "yes,yes,no")]
1592)
1593
1594(define_insn "*mulsi3_compare0"
1595  [(set (reg:CC_NOOV CC_REGNUM)
1596	(compare:CC_NOOV (mult:SI
1597			  (match_operand:SI 2 "s_register_operand" "r,r")
1598			  (match_operand:SI 1 "s_register_operand" "%0,r"))
1599			 (const_int 0)))
1600   (set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1601	(mult:SI (match_dup 2) (match_dup 1)))]
1602  "TARGET_ARM && !arm_arch6"
1603  "muls%?\\t%0, %2, %1"
1604  [(set_attr "conds" "set")
1605   (set_attr "type" "muls")]
1606)
1607
1608(define_insn "*mulsi3_compare0_v6"
1609  [(set (reg:CC_NOOV CC_REGNUM)
1610	(compare:CC_NOOV (mult:SI
1611			  (match_operand:SI 2 "s_register_operand" "r")
1612			  (match_operand:SI 1 "s_register_operand" "r"))
1613			 (const_int 0)))
1614   (set (match_operand:SI 0 "s_register_operand" "=r")
1615	(mult:SI (match_dup 2) (match_dup 1)))]
1616  "TARGET_ARM && arm_arch6 && optimize_size"
1617  "muls%?\\t%0, %2, %1"
1618  [(set_attr "conds" "set")
1619   (set_attr "type" "muls")]
1620)
1621
1622(define_insn "*mulsi_compare0_scratch"
1623  [(set (reg:CC_NOOV CC_REGNUM)
1624	(compare:CC_NOOV (mult:SI
1625			  (match_operand:SI 2 "s_register_operand" "r,r")
1626			  (match_operand:SI 1 "s_register_operand" "%0,r"))
1627			 (const_int 0)))
1628   (clobber (match_scratch:SI 0 "=&r,&r"))]
1629  "TARGET_ARM && !arm_arch6"
1630  "muls%?\\t%0, %2, %1"
1631  [(set_attr "conds" "set")
1632   (set_attr "type" "muls")]
1633)
1634
1635(define_insn "*mulsi_compare0_scratch_v6"
1636  [(set (reg:CC_NOOV CC_REGNUM)
1637	(compare:CC_NOOV (mult:SI
1638			  (match_operand:SI 2 "s_register_operand" "r")
1639			  (match_operand:SI 1 "s_register_operand" "r"))
1640			 (const_int 0)))
1641   (clobber (match_scratch:SI 0 "=r"))]
1642  "TARGET_ARM && arm_arch6 && optimize_size"
1643  "muls%?\\t%0, %2, %1"
1644  [(set_attr "conds" "set")
1645   (set_attr "type" "muls")]
1646)
1647
1648;; Unnamed templates to match MLA instruction.
1649
1650(define_insn "*mulsi3addsi"
1651  [(set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r,&r")
1652	(plus:SI
1653	  (mult:SI (match_operand:SI 2 "s_register_operand" "r,r,r,r")
1654		   (match_operand:SI 1 "s_register_operand" "%0,r,0,r"))
1655	  (match_operand:SI 3 "s_register_operand" "r,r,0,0")))]
1656  "TARGET_32BIT && !arm_arch6"
1657  "mla%?\\t%0, %2, %1, %3"
1658  [(set_attr "type" "mla")
1659   (set_attr "predicable" "yes")]
1660)
1661
1662(define_insn "*mulsi3addsi_v6"
1663  [(set (match_operand:SI 0 "s_register_operand" "=r")
1664	(plus:SI
1665	  (mult:SI (match_operand:SI 2 "s_register_operand" "r")
1666		   (match_operand:SI 1 "s_register_operand" "r"))
1667	  (match_operand:SI 3 "s_register_operand" "r")))]
1668  "TARGET_32BIT && arm_arch6"
1669  "mla%?\\t%0, %2, %1, %3"
1670  [(set_attr "type" "mla")
1671   (set_attr "predicable" "yes")]
1672)
1673
1674(define_insn "*mulsi3addsi_compare0"
1675  [(set (reg:CC_NOOV CC_REGNUM)
1676	(compare:CC_NOOV
1677	 (plus:SI (mult:SI
1678		   (match_operand:SI 2 "s_register_operand" "r,r,r,r")
1679		   (match_operand:SI 1 "s_register_operand" "%0,r,0,r"))
1680		  (match_operand:SI 3 "s_register_operand" "r,r,0,0"))
1681	 (const_int 0)))
1682   (set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r,&r")
1683	(plus:SI (mult:SI (match_dup 2) (match_dup 1))
1684		 (match_dup 3)))]
1685  "TARGET_ARM && arm_arch6"
1686  "mlas%?\\t%0, %2, %1, %3"
1687  [(set_attr "conds" "set")
1688   (set_attr "type" "mlas")]
1689)
1690
1691(define_insn "*mulsi3addsi_compare0_v6"
1692  [(set (reg:CC_NOOV CC_REGNUM)
1693	(compare:CC_NOOV
1694	 (plus:SI (mult:SI
1695		   (match_operand:SI 2 "s_register_operand" "r")
1696		   (match_operand:SI 1 "s_register_operand" "r"))
1697		  (match_operand:SI 3 "s_register_operand" "r"))
1698	 (const_int 0)))
1699   (set (match_operand:SI 0 "s_register_operand" "=r")
1700	(plus:SI (mult:SI (match_dup 2) (match_dup 1))
1701		 (match_dup 3)))]
1702  "TARGET_ARM && arm_arch6 && optimize_size"
1703  "mlas%?\\t%0, %2, %1, %3"
1704  [(set_attr "conds" "set")
1705   (set_attr "type" "mlas")]
1706)
1707
1708(define_insn "*mulsi3addsi_compare0_scratch"
1709  [(set (reg:CC_NOOV CC_REGNUM)
1710	(compare:CC_NOOV
1711	 (plus:SI (mult:SI
1712		   (match_operand:SI 2 "s_register_operand" "r,r,r,r")
1713		   (match_operand:SI 1 "s_register_operand" "%0,r,0,r"))
1714		  (match_operand:SI 3 "s_register_operand" "?r,r,0,0"))
1715	 (const_int 0)))
1716   (clobber (match_scratch:SI 0 "=&r,&r,&r,&r"))]
1717  "TARGET_ARM && !arm_arch6"
1718  "mlas%?\\t%0, %2, %1, %3"
1719  [(set_attr "conds" "set")
1720   (set_attr "type" "mlas")]
1721)
1722
1723(define_insn "*mulsi3addsi_compare0_scratch_v6"
1724  [(set (reg:CC_NOOV CC_REGNUM)
1725	(compare:CC_NOOV
1726	 (plus:SI (mult:SI
1727		   (match_operand:SI 2 "s_register_operand" "r")
1728		   (match_operand:SI 1 "s_register_operand" "r"))
1729		  (match_operand:SI 3 "s_register_operand" "r"))
1730	 (const_int 0)))
1731   (clobber (match_scratch:SI 0 "=r"))]
1732  "TARGET_ARM && arm_arch6 && optimize_size"
1733  "mlas%?\\t%0, %2, %1, %3"
1734  [(set_attr "conds" "set")
1735   (set_attr "type" "mlas")]
1736)
1737
1738(define_insn "*mulsi3subsi"
1739  [(set (match_operand:SI 0 "s_register_operand" "=r")
1740	(minus:SI
1741	  (match_operand:SI 3 "s_register_operand" "r")
1742	  (mult:SI (match_operand:SI 2 "s_register_operand" "r")
1743		   (match_operand:SI 1 "s_register_operand" "r"))))]
1744  "TARGET_32BIT && arm_arch_thumb2"
1745  "mls%?\\t%0, %2, %1, %3"
1746  [(set_attr "type" "mla")
1747   (set_attr "predicable" "yes")]
1748)
1749
1750(define_expand "maddsidi4"
1751  [(set (match_operand:DI 0 "s_register_operand" "")
1752	(plus:DI
1753	 (mult:DI
1754	  (sign_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1755	  (sign_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1756	 (match_operand:DI 3 "s_register_operand" "")))]
1757  "TARGET_32BIT && arm_arch3m"
1758  "")
1759
1760(define_insn "*mulsidi3adddi"
1761  [(set (match_operand:DI 0 "s_register_operand" "=&r")
1762	(plus:DI
1763	 (mult:DI
1764	  (sign_extend:DI (match_operand:SI 2 "s_register_operand" "%r"))
1765	  (sign_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1766	 (match_operand:DI 1 "s_register_operand" "0")))]
1767  "TARGET_32BIT && arm_arch3m && !arm_arch6"
1768  "smlal%?\\t%Q0, %R0, %3, %2"
1769  [(set_attr "type" "smlal")
1770   (set_attr "predicable" "yes")]
1771)
1772
1773(define_insn "*mulsidi3adddi_v6"
1774  [(set (match_operand:DI 0 "s_register_operand" "=r")
1775	(plus:DI
1776	 (mult:DI
1777	  (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r"))
1778	  (sign_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1779	 (match_operand:DI 1 "s_register_operand" "0")))]
1780  "TARGET_32BIT && arm_arch6"
1781  "smlal%?\\t%Q0, %R0, %3, %2"
1782  [(set_attr "type" "smlal")
1783   (set_attr "predicable" "yes")]
1784)
1785
1786;; 32x32->64 widening multiply.
1787;; As with mulsi3, the only difference between the v3-5 and v6+
1788;; versions of these patterns is the requirement that the output not
1789;; overlap the inputs, but that still means we have to have a named
1790;; expander and two different starred insns.
1791
1792(define_expand "mulsidi3"
1793  [(set (match_operand:DI 0 "s_register_operand" "")
1794	(mult:DI
1795	 (sign_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1796	 (sign_extend:DI (match_operand:SI 2 "s_register_operand" ""))))]
1797  "TARGET_32BIT && arm_arch3m"
1798  ""
1799)
1800
1801(define_insn "*mulsidi3_nov6"
1802  [(set (match_operand:DI 0 "s_register_operand" "=&r")
1803	(mult:DI
1804	 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "%r"))
1805	 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1806  "TARGET_32BIT && arm_arch3m && !arm_arch6"
1807  "smull%?\\t%Q0, %R0, %1, %2"
1808  [(set_attr "type" "smull")
1809   (set_attr "predicable" "yes")]
1810)
1811
1812(define_insn "*mulsidi3_v6"
1813  [(set (match_operand:DI 0 "s_register_operand" "=r")
1814	(mult:DI
1815	 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1816	 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1817  "TARGET_32BIT && arm_arch6"
1818  "smull%?\\t%Q0, %R0, %1, %2"
1819  [(set_attr "type" "smull")
1820   (set_attr "predicable" "yes")]
1821)
1822
1823(define_expand "umulsidi3"
1824  [(set (match_operand:DI 0 "s_register_operand" "")
1825	(mult:DI
1826	 (zero_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1827	 (zero_extend:DI (match_operand:SI 2 "s_register_operand" ""))))]
1828  "TARGET_32BIT && arm_arch3m"
1829  ""
1830)
1831
1832(define_insn "*umulsidi3_nov6"
1833  [(set (match_operand:DI 0 "s_register_operand" "=&r")
1834	(mult:DI
1835	 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "%r"))
1836	 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1837  "TARGET_32BIT && arm_arch3m && !arm_arch6"
1838  "umull%?\\t%Q0, %R0, %1, %2"
1839  [(set_attr "type" "umull")
1840   (set_attr "predicable" "yes")]
1841)
1842
1843(define_insn "*umulsidi3_v6"
1844  [(set (match_operand:DI 0 "s_register_operand" "=r")
1845	(mult:DI
1846	 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1847	 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1848  "TARGET_32BIT && arm_arch6"
1849  "umull%?\\t%Q0, %R0, %1, %2"
1850  [(set_attr "type" "umull")
1851   (set_attr "predicable" "yes")]
1852)
1853
1854(define_expand "umaddsidi4"
1855  [(set (match_operand:DI 0 "s_register_operand" "")
1856	(plus:DI
1857	 (mult:DI
1858	  (zero_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1859	  (zero_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1860	 (match_operand:DI 3 "s_register_operand" "")))]
1861  "TARGET_32BIT && arm_arch3m"
1862  "")
1863
1864(define_insn "*umulsidi3adddi"
1865  [(set (match_operand:DI 0 "s_register_operand" "=&r")
1866	(plus:DI
1867	 (mult:DI
1868	  (zero_extend:DI (match_operand:SI 2 "s_register_operand" "%r"))
1869	  (zero_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1870	 (match_operand:DI 1 "s_register_operand" "0")))]
1871  "TARGET_32BIT && arm_arch3m && !arm_arch6"
1872  "umlal%?\\t%Q0, %R0, %3, %2"
1873  [(set_attr "type" "umlal")
1874   (set_attr "predicable" "yes")]
1875)
1876
1877(define_insn "*umulsidi3adddi_v6"
1878  [(set (match_operand:DI 0 "s_register_operand" "=r")
1879	(plus:DI
1880	 (mult:DI
1881	  (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r"))
1882	  (zero_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1883	 (match_operand:DI 1 "s_register_operand" "0")))]
1884  "TARGET_32BIT && arm_arch6"
1885  "umlal%?\\t%Q0, %R0, %3, %2"
1886  [(set_attr "type" "umlal")
1887   (set_attr "predicable" "yes")]
1888)
1889
1890(define_expand "smulsi3_highpart"
1891  [(parallel
1892    [(set (match_operand:SI 0 "s_register_operand" "")
1893	  (truncate:SI
1894	   (lshiftrt:DI
1895	    (mult:DI
1896	     (sign_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1897	     (sign_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1898	    (const_int 32))))
1899     (clobber (match_scratch:SI 3 ""))])]
1900  "TARGET_32BIT && arm_arch3m"
1901  ""
1902)
1903
1904(define_insn "*smulsi3_highpart_nov6"
1905  [(set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1906	(truncate:SI
1907	 (lshiftrt:DI
1908	  (mult:DI
1909	   (sign_extend:DI (match_operand:SI 1 "s_register_operand" "%0,r"))
1910	   (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r,r")))
1911	  (const_int 32))))
1912   (clobber (match_scratch:SI 3 "=&r,&r"))]
1913  "TARGET_32BIT && arm_arch3m && !arm_arch6"
1914  "smull%?\\t%3, %0, %2, %1"
1915  [(set_attr "type" "smull")
1916   (set_attr "predicable" "yes")]
1917)
1918
1919(define_insn "*smulsi3_highpart_v6"
1920  [(set (match_operand:SI 0 "s_register_operand" "=r")
1921	(truncate:SI
1922	 (lshiftrt:DI
1923	  (mult:DI
1924	   (sign_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1925	   (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r")))
1926	  (const_int 32))))
1927   (clobber (match_scratch:SI 3 "=r"))]
1928  "TARGET_32BIT && arm_arch6"
1929  "smull%?\\t%3, %0, %2, %1"
1930  [(set_attr "type" "smull")
1931   (set_attr "predicable" "yes")]
1932)
1933
1934(define_expand "umulsi3_highpart"
1935  [(parallel
1936    [(set (match_operand:SI 0 "s_register_operand" "")
1937	  (truncate:SI
1938	   (lshiftrt:DI
1939	    (mult:DI
1940	     (zero_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1941	      (zero_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1942	    (const_int 32))))
1943     (clobber (match_scratch:SI 3 ""))])]
1944  "TARGET_32BIT && arm_arch3m"
1945  ""
1946)
1947
1948(define_insn "*umulsi3_highpart_nov6"
1949  [(set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1950	(truncate:SI
1951	 (lshiftrt:DI
1952	  (mult:DI
1953	   (zero_extend:DI (match_operand:SI 1 "s_register_operand" "%0,r"))
1954	   (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r,r")))
1955	  (const_int 32))))
1956   (clobber (match_scratch:SI 3 "=&r,&r"))]
1957  "TARGET_32BIT && arm_arch3m && !arm_arch6"
1958  "umull%?\\t%3, %0, %2, %1"
1959  [(set_attr "type" "umull")
1960   (set_attr "predicable" "yes")]
1961)
1962
1963(define_insn "*umulsi3_highpart_v6"
1964  [(set (match_operand:SI 0 "s_register_operand" "=r")
1965	(truncate:SI
1966	 (lshiftrt:DI
1967	  (mult:DI
1968	   (zero_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1969	   (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r")))
1970	  (const_int 32))))
1971   (clobber (match_scratch:SI 3 "=r"))]
1972  "TARGET_32BIT && arm_arch6"
1973  "umull%?\\t%3, %0, %2, %1"
1974  [(set_attr "type" "umull")
1975   (set_attr "predicable" "yes")]
1976)
1977
1978(define_insn "mulhisi3"
1979  [(set (match_operand:SI 0 "s_register_operand" "=r")
1980	(mult:SI (sign_extend:SI
1981		  (match_operand:HI 1 "s_register_operand" "%r"))
1982		 (sign_extend:SI
1983		  (match_operand:HI 2 "s_register_operand" "r"))))]
1984  "TARGET_DSP_MULTIPLY"
1985  "smulbb%?\\t%0, %1, %2"
1986  [(set_attr "type" "smulxy")
1987   (set_attr "predicable" "yes")]
1988)
1989
1990(define_insn "*mulhisi3tb"
1991  [(set (match_operand:SI 0 "s_register_operand" "=r")
1992	(mult:SI (ashiftrt:SI
1993		  (match_operand:SI 1 "s_register_operand" "r")
1994		  (const_int 16))
1995		 (sign_extend:SI
1996		  (match_operand:HI 2 "s_register_operand" "r"))))]
1997  "TARGET_DSP_MULTIPLY"
1998  "smultb%?\\t%0, %1, %2"
1999  [(set_attr "type" "smulxy")
2000   (set_attr "predicable" "yes")]
2001)
2002
2003(define_insn "*mulhisi3bt"
2004  [(set (match_operand:SI 0 "s_register_operand" "=r")
2005	(mult:SI (sign_extend:SI
2006		  (match_operand:HI 1 "s_register_operand" "r"))
2007		 (ashiftrt:SI
2008		  (match_operand:SI 2 "s_register_operand" "r")
2009		  (const_int 16))))]
2010  "TARGET_DSP_MULTIPLY"
2011  "smulbt%?\\t%0, %1, %2"
2012  [(set_attr "type" "smulxy")
2013   (set_attr "predicable" "yes")]
2014)
2015
2016(define_insn "*mulhisi3tt"
2017  [(set (match_operand:SI 0 "s_register_operand" "=r")
2018	(mult:SI (ashiftrt:SI
2019		  (match_operand:SI 1 "s_register_operand" "r")
2020		  (const_int 16))
2021		 (ashiftrt:SI
2022		  (match_operand:SI 2 "s_register_operand" "r")
2023		  (const_int 16))))]
2024  "TARGET_DSP_MULTIPLY"
2025  "smultt%?\\t%0, %1, %2"
2026  [(set_attr "type" "smulxy")
2027   (set_attr "predicable" "yes")]
2028)
2029
2030(define_insn "maddhisi4"
2031  [(set (match_operand:SI 0 "s_register_operand" "=r")
2032	(plus:SI (mult:SI (sign_extend:SI
2033			   (match_operand:HI 1 "s_register_operand" "r"))
2034			  (sign_extend:SI
2035			   (match_operand:HI 2 "s_register_operand" "r")))
2036		 (match_operand:SI 3 "s_register_operand" "r")))]
2037  "TARGET_DSP_MULTIPLY"
2038  "smlabb%?\\t%0, %1, %2, %3"
2039  [(set_attr "type" "smlaxy")
2040   (set_attr "predicable" "yes")]
2041)
2042
2043;; Note: there is no maddhisi4ibt because this one is canonical form
2044(define_insn "*maddhisi4tb"
2045  [(set (match_operand:SI 0 "s_register_operand" "=r")
2046	(plus:SI (mult:SI (ashiftrt:SI
2047			   (match_operand:SI 1 "s_register_operand" "r")
2048			   (const_int 16))
2049			  (sign_extend:SI
2050			   (match_operand:HI 2 "s_register_operand" "r")))
2051		 (match_operand:SI 3 "s_register_operand" "r")))]
2052  "TARGET_DSP_MULTIPLY"
2053  "smlatb%?\\t%0, %1, %2, %3"
2054  [(set_attr "type" "smlaxy")
2055   (set_attr "predicable" "yes")]
2056)
2057
2058(define_insn "*maddhisi4tt"
2059  [(set (match_operand:SI 0 "s_register_operand" "=r")
2060	(plus:SI (mult:SI (ashiftrt:SI
2061			   (match_operand:SI 1 "s_register_operand" "r")
2062			   (const_int 16))
2063			  (ashiftrt:SI
2064			   (match_operand:SI 2 "s_register_operand" "r")
2065			   (const_int 16)))
2066		 (match_operand:SI 3 "s_register_operand" "r")))]
2067  "TARGET_DSP_MULTIPLY"
2068  "smlatt%?\\t%0, %1, %2, %3"
2069  [(set_attr "type" "smlaxy")
2070   (set_attr "predicable" "yes")]
2071)
2072
2073(define_insn "maddhidi4"
2074  [(set (match_operand:DI 0 "s_register_operand" "=r")
2075	(plus:DI
2076	  (mult:DI (sign_extend:DI
2077		    (match_operand:HI 1 "s_register_operand" "r"))
2078		   (sign_extend:DI
2079		    (match_operand:HI 2 "s_register_operand" "r")))
2080	  (match_operand:DI 3 "s_register_operand" "0")))]
2081  "TARGET_DSP_MULTIPLY"
2082  "smlalbb%?\\t%Q0, %R0, %1, %2"
2083  [(set_attr "type" "smlalxy")
2084   (set_attr "predicable" "yes")])
2085
2086;; Note: there is no maddhidi4ibt because this one is canonical form
2087(define_insn "*maddhidi4tb"
2088  [(set (match_operand:DI 0 "s_register_operand" "=r")
2089	(plus:DI
2090	  (mult:DI (sign_extend:DI
2091		    (ashiftrt:SI
2092		     (match_operand:SI 1 "s_register_operand" "r")
2093		     (const_int 16)))
2094		   (sign_extend:DI
2095		    (match_operand:HI 2 "s_register_operand" "r")))
2096	  (match_operand:DI 3 "s_register_operand" "0")))]
2097  "TARGET_DSP_MULTIPLY"
2098  "smlaltb%?\\t%Q0, %R0, %1, %2"
2099  [(set_attr "type" "smlalxy")
2100   (set_attr "predicable" "yes")])
2101
2102(define_insn "*maddhidi4tt"
2103  [(set (match_operand:DI 0 "s_register_operand" "=r")
2104	(plus:DI
2105	  (mult:DI (sign_extend:DI
2106		    (ashiftrt:SI
2107		     (match_operand:SI 1 "s_register_operand" "r")
2108		     (const_int 16)))
2109		   (sign_extend:DI
2110		    (ashiftrt:SI
2111		     (match_operand:SI 2 "s_register_operand" "r")
2112		     (const_int 16))))
2113	  (match_operand:DI 3 "s_register_operand" "0")))]
2114  "TARGET_DSP_MULTIPLY"
2115  "smlaltt%?\\t%Q0, %R0, %1, %2"
2116  [(set_attr "type" "smlalxy")
2117   (set_attr "predicable" "yes")])
2118
2119(define_expand "mulsf3"
2120  [(set (match_operand:SF          0 "s_register_operand" "")
2121	(mult:SF (match_operand:SF 1 "s_register_operand" "")
2122		 (match_operand:SF 2 "s_register_operand" "")))]
2123  "TARGET_32BIT && TARGET_HARD_FLOAT"
2124  "
2125")
2126
2127(define_expand "muldf3"
2128  [(set (match_operand:DF          0 "s_register_operand" "")
2129	(mult:DF (match_operand:DF 1 "s_register_operand" "")
2130		 (match_operand:DF 2 "s_register_operand" "")))]
2131  "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
2132  "
2133")
2134
2135;; Division insns
2136
2137(define_expand "divsf3"
2138  [(set (match_operand:SF 0 "s_register_operand" "")
2139	(div:SF (match_operand:SF 1 "s_register_operand" "")
2140		(match_operand:SF 2 "s_register_operand" "")))]
2141  "TARGET_32BIT && TARGET_HARD_FLOAT"
2142  "")
2143
2144(define_expand "divdf3"
2145  [(set (match_operand:DF 0 "s_register_operand" "")
2146	(div:DF (match_operand:DF 1 "s_register_operand" "")
2147		(match_operand:DF 2 "s_register_operand" "")))]
2148  "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
2149  "")
2150
2151;; Boolean and,ior,xor insns
2152
2153;; Split up double word logical operations
2154
2155;; Split up simple DImode logical operations.  Simply perform the logical
2156;; operation on the upper and lower halves of the registers.
2157(define_split
2158  [(set (match_operand:DI 0 "s_register_operand" "")
2159	(match_operator:DI 6 "logical_binary_operator"
2160	  [(match_operand:DI 1 "s_register_operand" "")
2161	   (match_operand:DI 2 "s_register_operand" "")]))]
2162  "TARGET_32BIT && reload_completed
2163   && ! (TARGET_NEON && IS_VFP_REGNUM (REGNO (operands[0])))
2164   && ! IS_IWMMXT_REGNUM (REGNO (operands[0]))"
2165  [(set (match_dup 0) (match_op_dup:SI 6 [(match_dup 1) (match_dup 2)]))
2166   (set (match_dup 3) (match_op_dup:SI 6 [(match_dup 4) (match_dup 5)]))]
2167  "
2168  {
2169    operands[3] = gen_highpart (SImode, operands[0]);
2170    operands[0] = gen_lowpart (SImode, operands[0]);
2171    operands[4] = gen_highpart (SImode, operands[1]);
2172    operands[1] = gen_lowpart (SImode, operands[1]);
2173    operands[5] = gen_highpart (SImode, operands[2]);
2174    operands[2] = gen_lowpart (SImode, operands[2]);
2175  }"
2176)
2177
2178(define_split
2179  [(set (match_operand:DI 0 "s_register_operand" "")
2180	(match_operator:DI 6 "logical_binary_operator"
2181	  [(sign_extend:DI (match_operand:SI 2 "s_register_operand" ""))
2182	   (match_operand:DI 1 "s_register_operand" "")]))]
2183  "TARGET_32BIT && reload_completed"
2184  [(set (match_dup 0) (match_op_dup:SI 6 [(match_dup 1) (match_dup 2)]))
2185   (set (match_dup 3) (match_op_dup:SI 6
2186			[(ashiftrt:SI (match_dup 2) (const_int 31))
2187			 (match_dup 4)]))]
2188  "
2189  {
2190    operands[3] = gen_highpart (SImode, operands[0]);
2191    operands[0] = gen_lowpart (SImode, operands[0]);
2192    operands[4] = gen_highpart (SImode, operands[1]);
2193    operands[1] = gen_lowpart (SImode, operands[1]);
2194    operands[5] = gen_highpart (SImode, operands[2]);
2195    operands[2] = gen_lowpart (SImode, operands[2]);
2196  }"
2197)
2198
2199;; The zero extend of operand 2 means we can just copy the high part of
2200;; operand1 into operand0.
2201(define_split
2202  [(set (match_operand:DI 0 "s_register_operand" "")
2203	(ior:DI
2204	  (zero_extend:DI (match_operand:SI 2 "s_register_operand" ""))
2205	  (match_operand:DI 1 "s_register_operand" "")))]
2206  "TARGET_32BIT && operands[0] != operands[1] && reload_completed"
2207  [(set (match_dup 0) (ior:SI (match_dup 1) (match_dup 2)))
2208   (set (match_dup 3) (match_dup 4))]
2209  "
2210  {
2211    operands[4] = gen_highpart (SImode, operands[1]);
2212    operands[3] = gen_highpart (SImode, operands[0]);
2213    operands[0] = gen_lowpart (SImode, operands[0]);
2214    operands[1] = gen_lowpart (SImode, operands[1]);
2215  }"
2216)
2217
2218;; The zero extend of operand 2 means we can just copy the high part of
2219;; operand1 into operand0.
2220(define_split
2221  [(set (match_operand:DI 0 "s_register_operand" "")
2222	(xor:DI
2223	  (zero_extend:DI (match_operand:SI 2 "s_register_operand" ""))
2224	  (match_operand:DI 1 "s_register_operand" "")))]
2225  "TARGET_32BIT && operands[0] != operands[1] && reload_completed"
2226  [(set (match_dup 0) (xor:SI (match_dup 1) (match_dup 2)))
2227   (set (match_dup 3) (match_dup 4))]
2228  "
2229  {
2230    operands[4] = gen_highpart (SImode, operands[1]);
2231    operands[3] = gen_highpart (SImode, operands[0]);
2232    operands[0] = gen_lowpart (SImode, operands[0]);
2233    operands[1] = gen_lowpart (SImode, operands[1]);
2234  }"
2235)
2236
2237(define_expand "anddi3"
2238  [(set (match_operand:DI         0 "s_register_operand" "")
2239	(and:DI (match_operand:DI 1 "s_register_operand" "")
2240		(match_operand:DI 2 "neon_inv_logic_op2" "")))]
2241  "TARGET_32BIT"
2242  "
2243  if (!TARGET_NEON && !TARGET_IWMMXT)
2244    {
2245      rtx low  = simplify_gen_binary (AND, SImode,
2246				      gen_lowpart (SImode, operands[1]),
2247				      gen_lowpart (SImode, operands[2]));
2248      rtx high = simplify_gen_binary (AND, SImode,
2249				      gen_highpart (SImode, operands[1]),
2250				      gen_highpart_mode (SImode, DImode,
2251							 operands[2]));
2252
2253      emit_insn (gen_rtx_SET (gen_lowpart (SImode, operands[0]), low));
2254      emit_insn (gen_rtx_SET (gen_highpart (SImode, operands[0]), high));
2255
2256      DONE;
2257    }
2258  /* Otherwise expand pattern as above.  */
2259  "
2260)
2261
2262(define_insn_and_split "*anddi3_insn"
2263  [(set (match_operand:DI         0 "s_register_operand"     "=w,w ,&r,&r,&r,&r,?w,?w")
2264        (and:DI (match_operand:DI 1 "s_register_operand"     "%w,0 ,0 ,r ,0 ,r ,w ,0")
2265                (match_operand:DI 2 "arm_anddi_operand_neon" "w ,DL,r ,r ,De,De,w ,DL")))]
2266  "TARGET_32BIT && !TARGET_IWMMXT"
2267{
2268  switch (which_alternative)
2269    {
2270    case 0: /* fall through */
2271    case 6: return "vand\t%P0, %P1, %P2";
2272    case 1: /* fall through */
2273    case 7: return neon_output_logic_immediate ("vand", &operands[2],
2274                    DImode, 1, VALID_NEON_QREG_MODE (DImode));
2275    case 2:
2276    case 3:
2277    case 4:
2278    case 5: /* fall through */
2279      return "#";
2280    default: gcc_unreachable ();
2281    }
2282}
2283  "TARGET_32BIT && !TARGET_IWMMXT && reload_completed
2284   && !(IS_VFP_REGNUM (REGNO (operands[0])))"
2285  [(set (match_dup 3) (match_dup 4))
2286   (set (match_dup 5) (match_dup 6))]
2287  "
2288  {
2289    operands[3] = gen_lowpart (SImode, operands[0]);
2290    operands[5] = gen_highpart (SImode, operands[0]);
2291
2292    operands[4] = simplify_gen_binary (AND, SImode,
2293                                           gen_lowpart (SImode, operands[1]),
2294                                           gen_lowpart (SImode, operands[2]));
2295    operands[6] = simplify_gen_binary (AND, SImode,
2296                                           gen_highpart (SImode, operands[1]),
2297                                           gen_highpart_mode (SImode, DImode, operands[2]));
2298
2299  }"
2300  [(set_attr "type" "neon_logic,neon_logic,multiple,multiple,\
2301                     multiple,multiple,neon_logic,neon_logic")
2302   (set_attr "arch" "neon_for_64bits,neon_for_64bits,*,*,*,*,
2303                     avoid_neon_for_64bits,avoid_neon_for_64bits")
2304   (set_attr "length" "*,*,8,8,8,8,*,*")
2305  ]
2306)
2307
2308(define_insn_and_split "*anddi_zesidi_di"
2309  [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2310	(and:DI (zero_extend:DI
2311		 (match_operand:SI 2 "s_register_operand" "r,r"))
2312		(match_operand:DI 1 "s_register_operand" "0,r")))]
2313  "TARGET_32BIT"
2314  "#"
2315  "TARGET_32BIT && reload_completed"
2316  ; The zero extend of operand 2 clears the high word of the output
2317  ; operand.
2318  [(set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))
2319   (set (match_dup 3) (const_int 0))]
2320  "
2321  {
2322    operands[3] = gen_highpart (SImode, operands[0]);
2323    operands[0] = gen_lowpart (SImode, operands[0]);
2324    operands[1] = gen_lowpart (SImode, operands[1]);
2325  }"
2326  [(set_attr "length" "8")
2327   (set_attr "type" "multiple")]
2328)
2329
2330(define_insn "*anddi_sesdi_di"
2331  [(set (match_operand:DI          0 "s_register_operand" "=&r,&r")
2332	(and:DI (sign_extend:DI
2333		 (match_operand:SI 2 "s_register_operand" "r,r"))
2334		(match_operand:DI  1 "s_register_operand" "0,r")))]
2335  "TARGET_32BIT"
2336  "#"
2337  [(set_attr "length" "8")
2338   (set_attr "type" "multiple")]
2339)
2340
2341(define_expand "andsi3"
2342  [(set (match_operand:SI         0 "s_register_operand" "")
2343	(and:SI (match_operand:SI 1 "s_register_operand" "")
2344		(match_operand:SI 2 "reg_or_int_operand" "")))]
2345  "TARGET_EITHER"
2346  "
2347  if (TARGET_32BIT)
2348    {
2349      if (CONST_INT_P (operands[2]))
2350        {
2351	  if (INTVAL (operands[2]) == 255 && arm_arch6)
2352	    {
2353	      operands[1] = convert_to_mode (QImode, operands[1], 1);
2354	      emit_insn (gen_thumb2_zero_extendqisi2_v6 (operands[0],
2355							 operands[1]));
2356	      DONE;
2357	    }
2358	  else if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[2]), AND))
2359	    operands[2] = force_reg (SImode, operands[2]);
2360	  else
2361	    {
2362	      arm_split_constant (AND, SImode, NULL_RTX,
2363				  INTVAL (operands[2]), operands[0],
2364				  operands[1],
2365				  optimize && can_create_pseudo_p ());
2366
2367	      DONE;
2368	    }
2369        }
2370    }
2371  else /* TARGET_THUMB1 */
2372    {
2373      if (!CONST_INT_P (operands[2]))
2374        {
2375          rtx tmp = force_reg (SImode, operands[2]);
2376	  if (rtx_equal_p (operands[0], operands[1]))
2377	    operands[2] = tmp;
2378	  else
2379	    {
2380              operands[2] = operands[1];
2381              operands[1] = tmp;
2382	    }
2383        }
2384      else
2385        {
2386          int i;
2387
2388          if (((unsigned HOST_WIDE_INT) ~INTVAL (operands[2])) < 256)
2389  	    {
2390	      operands[2] = force_reg (SImode,
2391				       GEN_INT (~INTVAL (operands[2])));
2392
2393	      emit_insn (gen_thumb1_bicsi3 (operands[0], operands[2], operands[1]));
2394
2395	      DONE;
2396	    }
2397
2398          for (i = 9; i <= 31; i++)
2399	    {
2400	      if ((HOST_WIDE_INT_1 << i) - 1 == INTVAL (operands[2]))
2401	        {
2402	          emit_insn (gen_extzv (operands[0], operands[1], GEN_INT (i),
2403			 	        const0_rtx));
2404	          DONE;
2405	        }
2406	      else if ((HOST_WIDE_INT_1 << i) - 1
2407		       == ~INTVAL (operands[2]))
2408	        {
2409	          rtx shift = GEN_INT (i);
2410	          rtx reg = gen_reg_rtx (SImode);
2411
2412	          emit_insn (gen_lshrsi3 (reg, operands[1], shift));
2413	          emit_insn (gen_ashlsi3 (operands[0], reg, shift));
2414
2415	          DONE;
2416	        }
2417	    }
2418
2419          operands[2] = force_reg (SImode, operands[2]);
2420        }
2421    }
2422  "
2423)
2424
2425; ??? Check split length for Thumb-2
2426(define_insn_and_split "*arm_andsi3_insn"
2427  [(set (match_operand:SI         0 "s_register_operand" "=r,l,r,r,r")
2428	(and:SI (match_operand:SI 1 "s_register_operand" "%r,0,r,r,r")
2429		(match_operand:SI 2 "reg_or_int_operand" "I,l,K,r,?n")))]
2430  "TARGET_32BIT"
2431  "@
2432   and%?\\t%0, %1, %2
2433   and%?\\t%0, %1, %2
2434   bic%?\\t%0, %1, #%B2
2435   and%?\\t%0, %1, %2
2436   #"
2437  "TARGET_32BIT
2438   && CONST_INT_P (operands[2])
2439   && !(const_ok_for_arm (INTVAL (operands[2]))
2440	|| const_ok_for_arm (~INTVAL (operands[2])))"
2441  [(clobber (const_int 0))]
2442  "
2443  arm_split_constant  (AND, SImode, curr_insn,
2444	               INTVAL (operands[2]), operands[0], operands[1], 0);
2445  DONE;
2446  "
2447  [(set_attr "length" "4,4,4,4,16")
2448   (set_attr "predicable" "yes")
2449   (set_attr "predicable_short_it" "no,yes,no,no,no")
2450   (set_attr "type" "logic_imm,logic_imm,logic_reg,logic_reg,logic_imm")]
2451)
2452
2453(define_insn "*andsi3_compare0"
2454  [(set (reg:CC_NOOV CC_REGNUM)
2455	(compare:CC_NOOV
2456	 (and:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
2457		 (match_operand:SI 2 "arm_not_operand" "I,K,r"))
2458	 (const_int 0)))
2459   (set (match_operand:SI          0 "s_register_operand" "=r,r,r")
2460	(and:SI (match_dup 1) (match_dup 2)))]
2461  "TARGET_32BIT"
2462  "@
2463   ands%?\\t%0, %1, %2
2464   bics%?\\t%0, %1, #%B2
2465   ands%?\\t%0, %1, %2"
2466  [(set_attr "conds" "set")
2467   (set_attr "type" "logics_imm,logics_imm,logics_reg")]
2468)
2469
2470(define_insn "*andsi3_compare0_scratch"
2471  [(set (reg:CC_NOOV CC_REGNUM)
2472	(compare:CC_NOOV
2473	 (and:SI (match_operand:SI 0 "s_register_operand" "r,r,r")
2474		 (match_operand:SI 1 "arm_not_operand" "I,K,r"))
2475	 (const_int 0)))
2476   (clobber (match_scratch:SI 2 "=X,r,X"))]
2477  "TARGET_32BIT"
2478  "@
2479   tst%?\\t%0, %1
2480   bics%?\\t%2, %0, #%B1
2481   tst%?\\t%0, %1"
2482  [(set_attr "conds" "set")
2483   (set_attr "type"  "logics_imm,logics_imm,logics_reg")]
2484)
2485
2486(define_insn "*zeroextractsi_compare0_scratch"
2487  [(set (reg:CC_NOOV CC_REGNUM)
2488	(compare:CC_NOOV (zero_extract:SI
2489			  (match_operand:SI 0 "s_register_operand" "r")
2490			  (match_operand 1 "const_int_operand" "n")
2491			  (match_operand 2 "const_int_operand" "n"))
2492			 (const_int 0)))]
2493  "TARGET_32BIT
2494  && (INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) < 32
2495      && INTVAL (operands[1]) > 0
2496      && INTVAL (operands[1]) + (INTVAL (operands[2]) & 1) <= 8
2497      && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32)"
2498  "*
2499  operands[1] = GEN_INT (((1 << INTVAL (operands[1])) - 1)
2500			 << INTVAL (operands[2]));
2501  output_asm_insn (\"tst%?\\t%0, %1\", operands);
2502  return \"\";
2503  "
2504  [(set_attr "conds" "set")
2505   (set_attr "predicable" "yes")
2506   (set_attr "type" "logics_imm")]
2507)
2508
2509(define_insn_and_split "*ne_zeroextractsi"
2510  [(set (match_operand:SI 0 "s_register_operand" "=r")
2511	(ne:SI (zero_extract:SI
2512		(match_operand:SI 1 "s_register_operand" "r")
2513		(match_operand:SI 2 "const_int_operand" "n")
2514		(match_operand:SI 3 "const_int_operand" "n"))
2515	       (const_int 0)))
2516   (clobber (reg:CC CC_REGNUM))]
2517  "TARGET_32BIT
2518   && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2519       && INTVAL (operands[2]) > 0
2520       && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2521       && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)"
2522  "#"
2523  "TARGET_32BIT
2524   && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2525       && INTVAL (operands[2]) > 0
2526       && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2527       && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)"
2528  [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2529		   (compare:CC_NOOV (and:SI (match_dup 1) (match_dup 2))
2530				    (const_int 0)))
2531	      (set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))])
2532   (set (match_dup 0)
2533	(if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2534			 (match_dup 0) (const_int 1)))]
2535  "
2536  operands[2] = GEN_INT (((1 << INTVAL (operands[2])) - 1)
2537			 << INTVAL (operands[3]));
2538  "
2539  [(set_attr "conds" "clob")
2540   (set (attr "length")
2541	(if_then_else (eq_attr "is_thumb" "yes")
2542		      (const_int 12)
2543		      (const_int 8)))
2544   (set_attr "type" "multiple")]
2545)
2546
2547(define_insn_and_split "*ne_zeroextractsi_shifted"
2548  [(set (match_operand:SI 0 "s_register_operand" "=r")
2549	(ne:SI (zero_extract:SI
2550		(match_operand:SI 1 "s_register_operand" "r")
2551		(match_operand:SI 2 "const_int_operand" "n")
2552		(const_int 0))
2553	       (const_int 0)))
2554   (clobber (reg:CC CC_REGNUM))]
2555  "TARGET_ARM"
2556  "#"
2557  "TARGET_ARM"
2558  [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2559		   (compare:CC_NOOV (ashift:SI (match_dup 1) (match_dup 2))
2560				    (const_int 0)))
2561	      (set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))])
2562   (set (match_dup 0)
2563	(if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2564			 (match_dup 0) (const_int 1)))]
2565  "
2566  operands[2] = GEN_INT (32 - INTVAL (operands[2]));
2567  "
2568  [(set_attr "conds" "clob")
2569   (set_attr "length" "8")
2570   (set_attr "type" "multiple")]
2571)
2572
2573(define_insn_and_split "*ite_ne_zeroextractsi"
2574  [(set (match_operand:SI 0 "s_register_operand" "=r")
2575	(if_then_else:SI (ne (zero_extract:SI
2576			      (match_operand:SI 1 "s_register_operand" "r")
2577			      (match_operand:SI 2 "const_int_operand" "n")
2578			      (match_operand:SI 3 "const_int_operand" "n"))
2579			     (const_int 0))
2580			 (match_operand:SI 4 "arm_not_operand" "rIK")
2581			 (const_int 0)))
2582   (clobber (reg:CC CC_REGNUM))]
2583  "TARGET_ARM
2584   && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2585       && INTVAL (operands[2]) > 0
2586       && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2587       && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)
2588   && !reg_overlap_mentioned_p (operands[0], operands[4])"
2589  "#"
2590  "TARGET_ARM
2591   && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2592       && INTVAL (operands[2]) > 0
2593       && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2594       && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)
2595   && !reg_overlap_mentioned_p (operands[0], operands[4])"
2596  [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2597		   (compare:CC_NOOV (and:SI (match_dup 1) (match_dup 2))
2598				    (const_int 0)))
2599	      (set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))])
2600   (set (match_dup 0)
2601	(if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2602			 (match_dup 0) (match_dup 4)))]
2603  "
2604  operands[2] = GEN_INT (((1 << INTVAL (operands[2])) - 1)
2605			 << INTVAL (operands[3]));
2606  "
2607  [(set_attr "conds" "clob")
2608   (set_attr "length" "8")
2609   (set_attr "type" "multiple")]
2610)
2611
2612(define_insn_and_split "*ite_ne_zeroextractsi_shifted"
2613  [(set (match_operand:SI 0 "s_register_operand" "=r")
2614	(if_then_else:SI (ne (zero_extract:SI
2615			      (match_operand:SI 1 "s_register_operand" "r")
2616			      (match_operand:SI 2 "const_int_operand" "n")
2617			      (const_int 0))
2618			     (const_int 0))
2619			 (match_operand:SI 3 "arm_not_operand" "rIK")
2620			 (const_int 0)))
2621   (clobber (reg:CC CC_REGNUM))]
2622  "TARGET_ARM && !reg_overlap_mentioned_p (operands[0], operands[3])"
2623  "#"
2624  "TARGET_ARM && !reg_overlap_mentioned_p (operands[0], operands[3])"
2625  [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2626		   (compare:CC_NOOV (ashift:SI (match_dup 1) (match_dup 2))
2627				    (const_int 0)))
2628	      (set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))])
2629   (set (match_dup 0)
2630	(if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2631			 (match_dup 0) (match_dup 3)))]
2632  "
2633  operands[2] = GEN_INT (32 - INTVAL (operands[2]));
2634  "
2635  [(set_attr "conds" "clob")
2636   (set_attr "length" "8")
2637   (set_attr "type" "multiple")]
2638)
2639
2640;; ??? Use Thumb-2 has bitfield insert/extract instructions.
2641(define_split
2642  [(set (match_operand:SI 0 "s_register_operand" "")
2643	(match_operator:SI 1 "shiftable_operator"
2644	 [(zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
2645			   (match_operand:SI 3 "const_int_operand" "")
2646			   (match_operand:SI 4 "const_int_operand" ""))
2647	  (match_operand:SI 5 "s_register_operand" "")]))
2648   (clobber (match_operand:SI 6 "s_register_operand" ""))]
2649  "TARGET_ARM"
2650  [(set (match_dup 6) (ashift:SI (match_dup 2) (match_dup 3)))
2651   (set (match_dup 0)
2652	(match_op_dup 1
2653	 [(lshiftrt:SI (match_dup 6) (match_dup 4))
2654	  (match_dup 5)]))]
2655  "{
2656     HOST_WIDE_INT temp = INTVAL (operands[3]);
2657
2658     operands[3] = GEN_INT (32 - temp - INTVAL (operands[4]));
2659     operands[4] = GEN_INT (32 - temp);
2660   }"
2661)
2662
2663(define_split
2664  [(set (match_operand:SI 0 "s_register_operand" "")
2665	(match_operator:SI 1 "shiftable_operator"
2666	 [(sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
2667			   (match_operand:SI 3 "const_int_operand" "")
2668			   (match_operand:SI 4 "const_int_operand" ""))
2669	  (match_operand:SI 5 "s_register_operand" "")]))
2670   (clobber (match_operand:SI 6 "s_register_operand" ""))]
2671  "TARGET_ARM"
2672  [(set (match_dup 6) (ashift:SI (match_dup 2) (match_dup 3)))
2673   (set (match_dup 0)
2674	(match_op_dup 1
2675	 [(ashiftrt:SI (match_dup 6) (match_dup 4))
2676	  (match_dup 5)]))]
2677  "{
2678     HOST_WIDE_INT temp = INTVAL (operands[3]);
2679
2680     operands[3] = GEN_INT (32 - temp - INTVAL (operands[4]));
2681     operands[4] = GEN_INT (32 - temp);
2682   }"
2683)
2684
2685;;; ??? This pattern is bogus.  If operand3 has bits outside the range
2686;;; represented by the bitfield, then this will produce incorrect results.
2687;;; Somewhere, the value needs to be truncated.  On targets like the m68k,
2688;;; which have a real bit-field insert instruction, the truncation happens
2689;;; in the bit-field insert instruction itself.  Since arm does not have a
2690;;; bit-field insert instruction, we would have to emit code here to truncate
2691;;; the value before we insert.  This loses some of the advantage of having
2692;;; this insv pattern, so this pattern needs to be reevalutated.
2693
2694(define_expand "insv"
2695  [(set (zero_extract (match_operand 0 "nonimmediate_operand" "")
2696                      (match_operand 1 "general_operand" "")
2697                      (match_operand 2 "general_operand" ""))
2698        (match_operand 3 "reg_or_int_operand" ""))]
2699  "TARGET_ARM || arm_arch_thumb2"
2700  "
2701  {
2702    int start_bit = INTVAL (operands[2]);
2703    int width = INTVAL (operands[1]);
2704    HOST_WIDE_INT mask = (HOST_WIDE_INT_1 << width) - 1;
2705    rtx target, subtarget;
2706
2707    if (arm_arch_thumb2)
2708      {
2709        if (unaligned_access && MEM_P (operands[0])
2710	    && s_register_operand (operands[3], GET_MODE (operands[3]))
2711	    && (width == 16 || width == 32) && (start_bit % BITS_PER_UNIT) == 0)
2712	  {
2713	    rtx base_addr;
2714
2715	    if (BYTES_BIG_ENDIAN)
2716	      start_bit = GET_MODE_BITSIZE (GET_MODE (operands[3])) - width
2717			  - start_bit;
2718
2719	    if (width == 32)
2720	      {
2721	        base_addr = adjust_address (operands[0], SImode,
2722					    start_bit / BITS_PER_UNIT);
2723		emit_insn (gen_unaligned_storesi (base_addr, operands[3]));
2724	      }
2725	    else
2726	      {
2727	        rtx tmp = gen_reg_rtx (HImode);
2728
2729	        base_addr = adjust_address (operands[0], HImode,
2730					    start_bit / BITS_PER_UNIT);
2731		emit_move_insn (tmp, gen_lowpart (HImode, operands[3]));
2732		emit_insn (gen_unaligned_storehi (base_addr, tmp));
2733	      }
2734	    DONE;
2735	  }
2736	else if (s_register_operand (operands[0], GET_MODE (operands[0])))
2737	  {
2738	    bool use_bfi = TRUE;
2739
2740	    if (CONST_INT_P (operands[3]))
2741	      {
2742		HOST_WIDE_INT val = INTVAL (operands[3]) & mask;
2743
2744		if (val == 0)
2745		  {
2746		    emit_insn (gen_insv_zero (operands[0], operands[1],
2747					      operands[2]));
2748		    DONE;
2749		  }
2750
2751		/* See if the set can be done with a single orr instruction.  */
2752		if (val == mask && const_ok_for_arm (val << start_bit))
2753		  use_bfi = FALSE;
2754	      }
2755
2756	    if (use_bfi)
2757	      {
2758		if (!REG_P (operands[3]))
2759		  operands[3] = force_reg (SImode, operands[3]);
2760
2761		emit_insn (gen_insv_t2 (operands[0], operands[1], operands[2],
2762					operands[3]));
2763		DONE;
2764	      }
2765	  }
2766	else
2767	  FAIL;
2768      }
2769
2770    if (!s_register_operand (operands[0], GET_MODE (operands[0])))
2771      FAIL;
2772
2773    target = copy_rtx (operands[0]);
2774    /* Avoid using a subreg as a subtarget, and avoid writing a paradoxical
2775       subreg as the final target.  */
2776    if (GET_CODE (target) == SUBREG)
2777      {
2778	subtarget = gen_reg_rtx (SImode);
2779	if (GET_MODE_SIZE (GET_MODE (SUBREG_REG (target)))
2780	    < GET_MODE_SIZE (SImode))
2781	  target = SUBREG_REG (target);
2782      }
2783    else
2784      subtarget = target;
2785
2786    if (CONST_INT_P (operands[3]))
2787      {
2788	/* Since we are inserting a known constant, we may be able to
2789	   reduce the number of bits that we have to clear so that
2790	   the mask becomes simple.  */
2791	/* ??? This code does not check to see if the new mask is actually
2792	   simpler.  It may not be.  */
2793	rtx op1 = gen_reg_rtx (SImode);
2794	/* ??? Truncate operand3 to fit in the bitfield.  See comment before
2795	   start of this pattern.  */
2796	HOST_WIDE_INT op3_value = mask & INTVAL (operands[3]);
2797	HOST_WIDE_INT mask2 = ((mask & ~op3_value) << start_bit);
2798
2799	emit_insn (gen_andsi3 (op1, operands[0],
2800			       gen_int_mode (~mask2, SImode)));
2801	emit_insn (gen_iorsi3 (subtarget, op1,
2802			       gen_int_mode (op3_value << start_bit, SImode)));
2803      }
2804    else if (start_bit == 0
2805	     && !(const_ok_for_arm (mask)
2806		  || const_ok_for_arm (~mask)))
2807      {
2808	/* A Trick, since we are setting the bottom bits in the word,
2809	   we can shift operand[3] up, operand[0] down, OR them together
2810	   and rotate the result back again.  This takes 3 insns, and
2811	   the third might be mergeable into another op.  */
2812	/* The shift up copes with the possibility that operand[3] is
2813           wider than the bitfield.  */
2814	rtx op0 = gen_reg_rtx (SImode);
2815	rtx op1 = gen_reg_rtx (SImode);
2816
2817	emit_insn (gen_ashlsi3 (op0, operands[3], GEN_INT (32 - width)));
2818	emit_insn (gen_lshrsi3 (op1, operands[0], operands[1]));
2819	emit_insn (gen_iorsi3  (op1, op1, op0));
2820	emit_insn (gen_rotlsi3 (subtarget, op1, operands[1]));
2821      }
2822    else if ((width + start_bit == 32)
2823	     && !(const_ok_for_arm (mask)
2824		  || const_ok_for_arm (~mask)))
2825      {
2826	/* Similar trick, but slightly less efficient.  */
2827
2828	rtx op0 = gen_reg_rtx (SImode);
2829	rtx op1 = gen_reg_rtx (SImode);
2830
2831	emit_insn (gen_ashlsi3 (op0, operands[3], GEN_INT (32 - width)));
2832	emit_insn (gen_ashlsi3 (op1, operands[0], operands[1]));
2833	emit_insn (gen_lshrsi3 (op1, op1, operands[1]));
2834	emit_insn (gen_iorsi3 (subtarget, op1, op0));
2835      }
2836    else
2837      {
2838	rtx op0 = gen_int_mode (mask, SImode);
2839	rtx op1 = gen_reg_rtx (SImode);
2840	rtx op2 = gen_reg_rtx (SImode);
2841
2842	if (!(const_ok_for_arm (mask) || const_ok_for_arm (~mask)))
2843	  {
2844	    rtx tmp = gen_reg_rtx (SImode);
2845
2846	    emit_insn (gen_movsi (tmp, op0));
2847	    op0 = tmp;
2848	  }
2849
2850	/* Mask out any bits in operand[3] that are not needed.  */
2851	   emit_insn (gen_andsi3 (op1, operands[3], op0));
2852
2853	if (CONST_INT_P (op0)
2854	    && (const_ok_for_arm (mask << start_bit)
2855		|| const_ok_for_arm (~(mask << start_bit))))
2856	  {
2857	    op0 = gen_int_mode (~(mask << start_bit), SImode);
2858	    emit_insn (gen_andsi3 (op2, operands[0], op0));
2859	  }
2860	else
2861	  {
2862	    if (CONST_INT_P (op0))
2863	      {
2864		rtx tmp = gen_reg_rtx (SImode);
2865
2866		emit_insn (gen_movsi (tmp, op0));
2867		op0 = tmp;
2868	      }
2869
2870	    if (start_bit != 0)
2871	      emit_insn (gen_ashlsi3 (op0, op0, operands[2]));
2872
2873	    emit_insn (gen_andsi_notsi_si (op2, operands[0], op0));
2874	  }
2875
2876	if (start_bit != 0)
2877          emit_insn (gen_ashlsi3 (op1, op1, operands[2]));
2878
2879	emit_insn (gen_iorsi3 (subtarget, op1, op2));
2880      }
2881
2882    if (subtarget != target)
2883      {
2884	/* If TARGET is still a SUBREG, then it must be wider than a word,
2885	   so we must be careful only to set the subword we were asked to.  */
2886	if (GET_CODE (target) == SUBREG)
2887	  emit_move_insn (target, subtarget);
2888	else
2889	  emit_move_insn (target, gen_lowpart (GET_MODE (target), subtarget));
2890      }
2891
2892    DONE;
2893  }"
2894)
2895
2896(define_insn "insv_zero"
2897  [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r")
2898                         (match_operand:SI 1 "const_int_M_operand" "M")
2899                         (match_operand:SI 2 "const_int_M_operand" "M"))
2900        (const_int 0))]
2901  "arm_arch_thumb2"
2902  "bfc%?\t%0, %2, %1"
2903  [(set_attr "length" "4")
2904   (set_attr "predicable" "yes")
2905   (set_attr "type" "bfm")]
2906)
2907
2908(define_insn "insv_t2"
2909  [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r")
2910                         (match_operand:SI 1 "const_int_M_operand" "M")
2911                         (match_operand:SI 2 "const_int_M_operand" "M"))
2912        (match_operand:SI 3 "s_register_operand" "r"))]
2913  "arm_arch_thumb2"
2914  "bfi%?\t%0, %3, %2, %1"
2915  [(set_attr "length" "4")
2916   (set_attr "predicable" "yes")
2917   (set_attr "type" "bfm")]
2918)
2919
2920; constants for op 2 will never be given to these patterns.
2921(define_insn_and_split "*anddi_notdi_di"
2922  [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2923	(and:DI (not:DI (match_operand:DI 1 "s_register_operand" "0,r"))
2924		(match_operand:DI 2 "s_register_operand" "r,0")))]
2925  "TARGET_32BIT"
2926  "#"
2927  "TARGET_32BIT && reload_completed
2928   && ! (TARGET_NEON && IS_VFP_REGNUM (REGNO (operands[0])))
2929   && ! IS_IWMMXT_REGNUM (REGNO (operands[0]))"
2930  [(set (match_dup 0) (and:SI (not:SI (match_dup 1)) (match_dup 2)))
2931   (set (match_dup 3) (and:SI (not:SI (match_dup 4)) (match_dup 5)))]
2932  "
2933  {
2934    operands[3] = gen_highpart (SImode, operands[0]);
2935    operands[0] = gen_lowpart (SImode, operands[0]);
2936    operands[4] = gen_highpart (SImode, operands[1]);
2937    operands[1] = gen_lowpart (SImode, operands[1]);
2938    operands[5] = gen_highpart (SImode, operands[2]);
2939    operands[2] = gen_lowpart (SImode, operands[2]);
2940  }"
2941  [(set_attr "length" "8")
2942   (set_attr "predicable" "yes")
2943   (set_attr "type" "multiple")]
2944)
2945
2946(define_insn_and_split "*anddi_notzesidi_di"
2947  [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2948	(and:DI (not:DI (zero_extend:DI
2949			 (match_operand:SI 2 "s_register_operand" "r,r")))
2950		(match_operand:DI 1 "s_register_operand" "0,?r")))]
2951  "TARGET_32BIT"
2952  "@
2953   bic%?\\t%Q0, %Q1, %2
2954   #"
2955  ; (not (zero_extend ...)) allows us to just copy the high word from
2956  ; operand1 to operand0.
2957  "TARGET_32BIT
2958   && reload_completed
2959   && operands[0] != operands[1]"
2960  [(set (match_dup 0) (and:SI (not:SI (match_dup 2)) (match_dup 1)))
2961   (set (match_dup 3) (match_dup 4))]
2962  "
2963  {
2964    operands[3] = gen_highpart (SImode, operands[0]);
2965    operands[0] = gen_lowpart (SImode, operands[0]);
2966    operands[4] = gen_highpart (SImode, operands[1]);
2967    operands[1] = gen_lowpart (SImode, operands[1]);
2968  }"
2969  [(set_attr "length" "4,8")
2970   (set_attr "predicable" "yes")
2971   (set_attr "type" "multiple")]
2972)
2973
2974(define_insn_and_split "*anddi_notdi_zesidi"
2975  [(set (match_operand:DI 0 "s_register_operand" "=r")
2976        (and:DI (not:DI (match_operand:DI 2 "s_register_operand" "r"))
2977                (zero_extend:DI
2978                 (match_operand:SI 1 "s_register_operand" "r"))))]
2979  "TARGET_32BIT"
2980  "#"
2981  "TARGET_32BIT && reload_completed"
2982  [(set (match_dup 0) (and:SI (not:SI (match_dup 2)) (match_dup 1)))
2983   (set (match_dup 3) (const_int 0))]
2984  "
2985  {
2986    operands[3] = gen_highpart (SImode, operands[0]);
2987    operands[0] = gen_lowpart (SImode, operands[0]);
2988    operands[2] = gen_lowpart (SImode, operands[2]);
2989  }"
2990  [(set_attr "length" "8")
2991   (set_attr "predicable" "yes")
2992   (set_attr "type" "multiple")]
2993)
2994
2995(define_insn_and_split "*anddi_notsesidi_di"
2996  [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2997	(and:DI (not:DI (sign_extend:DI
2998			 (match_operand:SI 2 "s_register_operand" "r,r")))
2999		(match_operand:DI 1 "s_register_operand" "0,r")))]
3000  "TARGET_32BIT"
3001  "#"
3002  "TARGET_32BIT && reload_completed"
3003  [(set (match_dup 0) (and:SI (not:SI (match_dup 2)) (match_dup 1)))
3004   (set (match_dup 3) (and:SI (not:SI
3005				(ashiftrt:SI (match_dup 2) (const_int 31)))
3006			       (match_dup 4)))]
3007  "
3008  {
3009    operands[3] = gen_highpart (SImode, operands[0]);
3010    operands[0] = gen_lowpart (SImode, operands[0]);
3011    operands[4] = gen_highpart (SImode, operands[1]);
3012    operands[1] = gen_lowpart (SImode, operands[1]);
3013  }"
3014  [(set_attr "length" "8")
3015   (set_attr "predicable" "yes")
3016   (set_attr "type" "multiple")]
3017)
3018
3019(define_insn "andsi_notsi_si"
3020  [(set (match_operand:SI 0 "s_register_operand" "=r")
3021	(and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
3022		(match_operand:SI 1 "s_register_operand" "r")))]
3023  "TARGET_32BIT"
3024  "bic%?\\t%0, %1, %2"
3025  [(set_attr "predicable" "yes")
3026   (set_attr "type" "logic_reg")]
3027)
3028
3029(define_insn "andsi_not_shiftsi_si"
3030  [(set (match_operand:SI 0 "s_register_operand" "=r")
3031	(and:SI (not:SI (match_operator:SI 4 "shift_operator"
3032			 [(match_operand:SI 2 "s_register_operand" "r")
3033			  (match_operand:SI 3 "arm_rhs_operand" "rM")]))
3034		(match_operand:SI 1 "s_register_operand" "r")))]
3035  "TARGET_ARM"
3036  "bic%?\\t%0, %1, %2%S4"
3037  [(set_attr "predicable" "yes")
3038   (set_attr "shift" "2")
3039   (set (attr "type") (if_then_else (match_operand 3 "const_int_operand" "")
3040		      (const_string "logic_shift_imm")
3041		      (const_string "logic_shift_reg")))]
3042)
3043
3044;; Shifted bics pattern used to set up CC status register and not reusing
3045;; bics output.  Pattern restricts Thumb2 shift operand as bics for Thumb2
3046;; does not support shift by register.
3047(define_insn "andsi_not_shiftsi_si_scc_no_reuse"
3048  [(set (reg:CC_NOOV CC_REGNUM)
3049	(compare:CC_NOOV
3050		(and:SI (not:SI (match_operator:SI 0 "shift_operator"
3051			[(match_operand:SI 1 "s_register_operand" "r")
3052			 (match_operand:SI 2 "arm_rhs_operand" "rM")]))
3053			(match_operand:SI 3 "s_register_operand" "r"))
3054		(const_int 0)))
3055   (clobber (match_scratch:SI 4 "=r"))]
3056  "TARGET_ARM || (TARGET_THUMB2 && CONST_INT_P (operands[2]))"
3057  "bics%?\\t%4, %3, %1%S0"
3058  [(set_attr "predicable" "yes")
3059   (set_attr "conds" "set")
3060   (set_attr "shift" "1")
3061   (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
3062		      (const_string "logic_shift_imm")
3063		      (const_string "logic_shift_reg")))]
3064)
3065
3066;; Same as andsi_not_shiftsi_si_scc_no_reuse, but the bics result is also
3067;; getting reused later.
3068(define_insn "andsi_not_shiftsi_si_scc"
3069  [(parallel [(set (reg:CC_NOOV CC_REGNUM)
3070	(compare:CC_NOOV
3071		(and:SI (not:SI (match_operator:SI 0 "shift_operator"
3072			[(match_operand:SI 1 "s_register_operand" "r")
3073			 (match_operand:SI 2 "arm_rhs_operand" "rM")]))
3074			(match_operand:SI 3 "s_register_operand" "r"))
3075		(const_int 0)))
3076	(set (match_operand:SI 4 "s_register_operand" "=r")
3077	     (and:SI (not:SI (match_op_dup 0
3078		     [(match_dup 1)
3079		      (match_dup 2)]))
3080		     (match_dup 3)))])]
3081  "TARGET_ARM || (TARGET_THUMB2 && CONST_INT_P (operands[2]))"
3082  "bics%?\\t%4, %3, %1%S0"
3083  [(set_attr "predicable" "yes")
3084   (set_attr "conds" "set")
3085   (set_attr "shift" "1")
3086   (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
3087		      (const_string "logic_shift_imm")
3088		      (const_string "logic_shift_reg")))]
3089)
3090
3091(define_insn "*andsi_notsi_si_compare0"
3092  [(set (reg:CC_NOOV CC_REGNUM)
3093	(compare:CC_NOOV
3094	 (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
3095		 (match_operand:SI 1 "s_register_operand" "r"))
3096	 (const_int 0)))
3097   (set (match_operand:SI 0 "s_register_operand" "=r")
3098	(and:SI (not:SI (match_dup 2)) (match_dup 1)))]
3099  "TARGET_32BIT"
3100  "bics\\t%0, %1, %2"
3101  [(set_attr "conds" "set")
3102   (set_attr "type" "logics_shift_reg")]
3103)
3104
3105(define_insn "*andsi_notsi_si_compare0_scratch"
3106  [(set (reg:CC_NOOV CC_REGNUM)
3107	(compare:CC_NOOV
3108	 (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
3109		 (match_operand:SI 1 "s_register_operand" "r"))
3110	 (const_int 0)))
3111   (clobber (match_scratch:SI 0 "=r"))]
3112  "TARGET_32BIT"
3113  "bics\\t%0, %1, %2"
3114  [(set_attr "conds" "set")
3115   (set_attr "type" "logics_shift_reg")]
3116)
3117
3118(define_expand "iordi3"
3119  [(set (match_operand:DI         0 "s_register_operand" "")
3120	(ior:DI (match_operand:DI 1 "s_register_operand" "")
3121		(match_operand:DI 2 "neon_logic_op2" "")))]
3122  "TARGET_32BIT"
3123  "
3124  if (!TARGET_NEON && !TARGET_IWMMXT)
3125    {
3126      rtx low  = simplify_gen_binary (IOR, SImode,
3127				      gen_lowpart (SImode, operands[1]),
3128				      gen_lowpart (SImode, operands[2]));
3129      rtx high = simplify_gen_binary (IOR, SImode,
3130				      gen_highpart (SImode, operands[1]),
3131				      gen_highpart_mode (SImode, DImode,
3132							 operands[2]));
3133
3134      emit_insn (gen_rtx_SET (gen_lowpart (SImode, operands[0]), low));
3135      emit_insn (gen_rtx_SET (gen_highpart (SImode, operands[0]), high));
3136
3137      DONE;
3138    }
3139  /* Otherwise expand pattern as above.  */
3140  "
3141)
3142
3143(define_insn_and_split "*iordi3_insn"
3144  [(set (match_operand:DI         0 "s_register_operand"     "=w,w ,&r,&r,&r,&r,?w,?w")
3145	(ior:DI (match_operand:DI 1 "s_register_operand"     "%w,0 ,0 ,r ,0 ,r ,w ,0")
3146		(match_operand:DI 2 "arm_iordi_operand_neon" "w ,Dl,r ,r ,Df,Df,w ,Dl")))]
3147  "TARGET_32BIT && !TARGET_IWMMXT"
3148  {
3149  switch (which_alternative)
3150    {
3151    case 0: /* fall through */
3152    case 6: return "vorr\t%P0, %P1, %P2";
3153    case 1: /* fall through */
3154    case 7: return neon_output_logic_immediate ("vorr", &operands[2],
3155		     DImode, 0, VALID_NEON_QREG_MODE (DImode));
3156    case 2:
3157    case 3:
3158    case 4:
3159    case 5:
3160      return "#";
3161    default: gcc_unreachable ();
3162    }
3163  }
3164  "TARGET_32BIT && !TARGET_IWMMXT && reload_completed
3165   && !(IS_VFP_REGNUM (REGNO (operands[0])))"
3166  [(set (match_dup 3) (match_dup 4))
3167   (set (match_dup 5) (match_dup 6))]
3168  "
3169  {
3170    operands[3] = gen_lowpart (SImode, operands[0]);
3171    operands[5] = gen_highpart (SImode, operands[0]);
3172
3173    operands[4] = simplify_gen_binary (IOR, SImode,
3174                                           gen_lowpart (SImode, operands[1]),
3175                                           gen_lowpart (SImode, operands[2]));
3176    operands[6] = simplify_gen_binary (IOR, SImode,
3177                                           gen_highpart (SImode, operands[1]),
3178                                           gen_highpart_mode (SImode, DImode, operands[2]));
3179
3180  }"
3181  [(set_attr "type" "neon_logic,neon_logic,multiple,multiple,multiple,\
3182                     multiple,neon_logic,neon_logic")
3183   (set_attr "length" "*,*,8,8,8,8,*,*")
3184   (set_attr "arch" "neon_for_64bits,neon_for_64bits,*,*,*,*,avoid_neon_for_64bits,avoid_neon_for_64bits")]
3185)
3186
3187(define_insn "*iordi_zesidi_di"
3188  [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
3189	(ior:DI (zero_extend:DI
3190		 (match_operand:SI 2 "s_register_operand" "r,r"))
3191		(match_operand:DI 1 "s_register_operand" "0,?r")))]
3192  "TARGET_32BIT"
3193  "@
3194   orr%?\\t%Q0, %Q1, %2
3195   #"
3196  [(set_attr "length" "4,8")
3197   (set_attr "predicable" "yes")
3198   (set_attr "type" "logic_reg,multiple")]
3199)
3200
3201(define_insn "*iordi_sesidi_di"
3202  [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
3203	(ior:DI (sign_extend:DI
3204		 (match_operand:SI 2 "s_register_operand" "r,r"))
3205		(match_operand:DI 1 "s_register_operand" "0,r")))]
3206  "TARGET_32BIT"
3207  "#"
3208  [(set_attr "length" "8")
3209   (set_attr "predicable" "yes")
3210   (set_attr "type" "multiple")]
3211)
3212
3213(define_expand "iorsi3"
3214  [(set (match_operand:SI         0 "s_register_operand" "")
3215	(ior:SI (match_operand:SI 1 "s_register_operand" "")
3216		(match_operand:SI 2 "reg_or_int_operand" "")))]
3217  "TARGET_EITHER"
3218  "
3219  if (CONST_INT_P (operands[2]))
3220    {
3221      if (TARGET_32BIT)
3222        {
3223	  if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[2]), IOR))
3224	    operands[2] = force_reg (SImode, operands[2]);
3225	  else
3226	    {
3227	      arm_split_constant (IOR, SImode, NULL_RTX,
3228				  INTVAL (operands[2]), operands[0],
3229				  operands[1],
3230				  optimize && can_create_pseudo_p ());
3231	      DONE;
3232	    }
3233	}
3234      else /* TARGET_THUMB1 */
3235        {
3236          rtx tmp = force_reg (SImode, operands[2]);
3237	  if (rtx_equal_p (operands[0], operands[1]))
3238	    operands[2] = tmp;
3239	  else
3240	    {
3241              operands[2] = operands[1];
3242              operands[1] = tmp;
3243	    }
3244        }
3245    }
3246  "
3247)
3248
3249(define_insn_and_split "*iorsi3_insn"
3250  [(set (match_operand:SI 0 "s_register_operand" "=r,l,r,r,r")
3251	(ior:SI (match_operand:SI 1 "s_register_operand" "%r,0,r,r,r")
3252		(match_operand:SI 2 "reg_or_int_operand" "I,l,K,r,?n")))]
3253  "TARGET_32BIT"
3254  "@
3255   orr%?\\t%0, %1, %2
3256   orr%?\\t%0, %1, %2
3257   orn%?\\t%0, %1, #%B2
3258   orr%?\\t%0, %1, %2
3259   #"
3260  "TARGET_32BIT
3261   && CONST_INT_P (operands[2])
3262   && !(const_ok_for_arm (INTVAL (operands[2]))
3263        || (TARGET_THUMB2 && const_ok_for_arm (~INTVAL (operands[2]))))"
3264  [(clobber (const_int 0))]
3265{
3266  arm_split_constant (IOR, SImode, curr_insn,
3267                      INTVAL (operands[2]), operands[0], operands[1], 0);
3268  DONE;
3269}
3270  [(set_attr "length" "4,4,4,4,16")
3271   (set_attr "arch" "32,t2,t2,32,32")
3272   (set_attr "predicable" "yes")
3273   (set_attr "predicable_short_it" "no,yes,no,no,no")
3274   (set_attr "type" "logic_imm,logic_reg,logic_imm,logic_reg,logic_reg")]
3275)
3276
3277(define_peephole2
3278  [(match_scratch:SI 3 "r")
3279   (set (match_operand:SI 0 "arm_general_register_operand" "")
3280	(ior:SI (match_operand:SI 1 "arm_general_register_operand" "")
3281		(match_operand:SI 2 "const_int_operand" "")))]
3282  "TARGET_ARM
3283   && !const_ok_for_arm (INTVAL (operands[2]))
3284   && const_ok_for_arm (~INTVAL (operands[2]))"
3285  [(set (match_dup 3) (match_dup 2))
3286   (set (match_dup 0) (ior:SI (match_dup 1) (match_dup 3)))]
3287  ""
3288)
3289
3290(define_insn "*iorsi3_compare0"
3291  [(set (reg:CC_NOOV CC_REGNUM)
3292	(compare:CC_NOOV (ior:SI (match_operand:SI 1 "s_register_operand" "%r,r")
3293				 (match_operand:SI 2 "arm_rhs_operand" "I,r"))
3294			 (const_int 0)))
3295   (set (match_operand:SI 0 "s_register_operand" "=r,r")
3296	(ior:SI (match_dup 1) (match_dup 2)))]
3297  "TARGET_32BIT"
3298  "orrs%?\\t%0, %1, %2"
3299  [(set_attr "conds" "set")
3300   (set_attr "type" "logics_imm,logics_reg")]
3301)
3302
3303(define_insn "*iorsi3_compare0_scratch"
3304  [(set (reg:CC_NOOV CC_REGNUM)
3305	(compare:CC_NOOV (ior:SI (match_operand:SI 1 "s_register_operand" "%r,r")
3306				 (match_operand:SI 2 "arm_rhs_operand" "I,r"))
3307			 (const_int 0)))
3308   (clobber (match_scratch:SI 0 "=r,r"))]
3309  "TARGET_32BIT"
3310  "orrs%?\\t%0, %1, %2"
3311  [(set_attr "conds" "set")
3312   (set_attr "type" "logics_imm,logics_reg")]
3313)
3314
3315(define_expand "xordi3"
3316  [(set (match_operand:DI         0 "s_register_operand" "")
3317	(xor:DI (match_operand:DI 1 "s_register_operand" "")
3318		(match_operand:DI 2 "arm_xordi_operand" "")))]
3319  "TARGET_32BIT"
3320  {
3321    /* The iWMMXt pattern for xordi3 accepts only register operands but we want
3322       to reuse this expander for all TARGET_32BIT targets so just force the
3323       constants into a register.  Unlike for the anddi3 and iordi3 there are
3324       no NEON instructions that take an immediate.  */
3325    if (TARGET_IWMMXT && !REG_P (operands[2]))
3326      operands[2] = force_reg (DImode, operands[2]);
3327    if (!TARGET_NEON && !TARGET_IWMMXT)
3328      {
3329	rtx low  = simplify_gen_binary (XOR, SImode,
3330					gen_lowpart (SImode, operands[1]),
3331					gen_lowpart (SImode, operands[2]));
3332	rtx high = simplify_gen_binary (XOR, SImode,
3333					gen_highpart (SImode, operands[1]),
3334					gen_highpart_mode (SImode, DImode,
3335							   operands[2]));
3336
3337	emit_insn (gen_rtx_SET (gen_lowpart (SImode, operands[0]), low));
3338	emit_insn (gen_rtx_SET (gen_highpart (SImode, operands[0]), high));
3339
3340	DONE;
3341      }
3342    /* Otherwise expand pattern as above.  */
3343  }
3344)
3345
3346(define_insn_and_split "*xordi3_insn"
3347  [(set (match_operand:DI         0 "s_register_operand" "=w,&r,&r,&r,&r,?w")
3348	(xor:DI (match_operand:DI 1 "s_register_operand" "%w ,0,r ,0 ,r ,w")
3349		(match_operand:DI 2 "arm_xordi_operand"  "w ,r ,r ,Dg,Dg,w")))]
3350  "TARGET_32BIT && !TARGET_IWMMXT"
3351{
3352  switch (which_alternative)
3353    {
3354    case 1:
3355    case 2:
3356    case 3:
3357    case 4:  /* fall through */
3358      return "#";
3359    case 0: /* fall through */
3360    case 5: return "veor\t%P0, %P1, %P2";
3361    default: gcc_unreachable ();
3362    }
3363}
3364  "TARGET_32BIT && !TARGET_IWMMXT && reload_completed
3365   && !(IS_VFP_REGNUM (REGNO (operands[0])))"
3366  [(set (match_dup 3) (match_dup 4))
3367   (set (match_dup 5) (match_dup 6))]
3368  "
3369  {
3370    operands[3] = gen_lowpart (SImode, operands[0]);
3371    operands[5] = gen_highpart (SImode, operands[0]);
3372
3373    operands[4] = simplify_gen_binary (XOR, SImode,
3374                                           gen_lowpart (SImode, operands[1]),
3375                                           gen_lowpart (SImode, operands[2]));
3376    operands[6] = simplify_gen_binary (XOR, SImode,
3377                                           gen_highpart (SImode, operands[1]),
3378                                           gen_highpart_mode (SImode, DImode, operands[2]));
3379
3380  }"
3381  [(set_attr "length" "*,8,8,8,8,*")
3382   (set_attr "type" "neon_logic,multiple,multiple,multiple,multiple,neon_logic")
3383   (set_attr "arch" "neon_for_64bits,*,*,*,*,avoid_neon_for_64bits")]
3384)
3385
3386(define_insn "*xordi_zesidi_di"
3387  [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
3388	(xor:DI (zero_extend:DI
3389		 (match_operand:SI 2 "s_register_operand" "r,r"))
3390		(match_operand:DI 1 "s_register_operand" "0,?r")))]
3391  "TARGET_32BIT"
3392  "@
3393   eor%?\\t%Q0, %Q1, %2
3394   #"
3395  [(set_attr "length" "4,8")
3396   (set_attr "predicable" "yes")
3397   (set_attr "type" "logic_reg")]
3398)
3399
3400(define_insn "*xordi_sesidi_di"
3401  [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
3402	(xor:DI (sign_extend:DI
3403		 (match_operand:SI 2 "s_register_operand" "r,r"))
3404		(match_operand:DI 1 "s_register_operand" "0,r")))]
3405  "TARGET_32BIT"
3406  "#"
3407  [(set_attr "length" "8")
3408   (set_attr "predicable" "yes")
3409   (set_attr "type" "multiple")]
3410)
3411
3412(define_expand "xorsi3"
3413  [(set (match_operand:SI         0 "s_register_operand" "")
3414	(xor:SI (match_operand:SI 1 "s_register_operand" "")
3415		(match_operand:SI 2 "reg_or_int_operand" "")))]
3416  "TARGET_EITHER"
3417  "if (CONST_INT_P (operands[2]))
3418    {
3419      if (TARGET_32BIT)
3420        {
3421	  if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[2]), XOR))
3422	    operands[2] = force_reg (SImode, operands[2]);
3423	  else
3424	    {
3425	      arm_split_constant (XOR, SImode, NULL_RTX,
3426				  INTVAL (operands[2]), operands[0],
3427				  operands[1],
3428				  optimize && can_create_pseudo_p ());
3429	      DONE;
3430	    }
3431	}
3432      else /* TARGET_THUMB1 */
3433        {
3434          rtx tmp = force_reg (SImode, operands[2]);
3435	  if (rtx_equal_p (operands[0], operands[1]))
3436	    operands[2] = tmp;
3437	  else
3438	    {
3439              operands[2] = operands[1];
3440              operands[1] = tmp;
3441	    }
3442        }
3443    }"
3444)
3445
3446(define_insn_and_split "*arm_xorsi3"
3447  [(set (match_operand:SI         0 "s_register_operand" "=r,l,r,r")
3448	(xor:SI (match_operand:SI 1 "s_register_operand" "%r,0,r,r")
3449		(match_operand:SI 2 "reg_or_int_operand" "I,l,r,?n")))]
3450  "TARGET_32BIT"
3451  "@
3452   eor%?\\t%0, %1, %2
3453   eor%?\\t%0, %1, %2
3454   eor%?\\t%0, %1, %2
3455   #"
3456  "TARGET_32BIT
3457   && CONST_INT_P (operands[2])
3458   && !const_ok_for_arm (INTVAL (operands[2]))"
3459  [(clobber (const_int 0))]
3460{
3461  arm_split_constant (XOR, SImode, curr_insn,
3462                      INTVAL (operands[2]), operands[0], operands[1], 0);
3463  DONE;
3464}
3465  [(set_attr "length" "4,4,4,16")
3466   (set_attr "predicable" "yes")
3467   (set_attr "predicable_short_it" "no,yes,no,no")
3468   (set_attr "type"  "logic_imm,logic_reg,logic_reg,multiple")]
3469)
3470
3471(define_insn "*xorsi3_compare0"
3472  [(set (reg:CC_NOOV CC_REGNUM)
3473	(compare:CC_NOOV (xor:SI (match_operand:SI 1 "s_register_operand" "r,r")
3474				 (match_operand:SI 2 "arm_rhs_operand" "I,r"))
3475			 (const_int 0)))
3476   (set (match_operand:SI 0 "s_register_operand" "=r,r")
3477	(xor:SI (match_dup 1) (match_dup 2)))]
3478  "TARGET_32BIT"
3479  "eors%?\\t%0, %1, %2"
3480  [(set_attr "conds" "set")
3481   (set_attr "type" "logics_imm,logics_reg")]
3482)
3483
3484(define_insn "*xorsi3_compare0_scratch"
3485  [(set (reg:CC_NOOV CC_REGNUM)
3486	(compare:CC_NOOV (xor:SI (match_operand:SI 0 "s_register_operand" "r,r")
3487				 (match_operand:SI 1 "arm_rhs_operand" "I,r"))
3488			 (const_int 0)))]
3489  "TARGET_32BIT"
3490  "teq%?\\t%0, %1"
3491  [(set_attr "conds" "set")
3492   (set_attr "type" "logics_imm,logics_reg")]
3493)
3494
3495; By splitting (IOR (AND (NOT A) (NOT B)) C) as D = AND (IOR A B) (NOT C),
3496; (NOT D) we can sometimes merge the final NOT into one of the following
3497; insns.
3498
3499(define_split
3500  [(set (match_operand:SI 0 "s_register_operand" "")
3501	(ior:SI (and:SI (not:SI (match_operand:SI 1 "s_register_operand" ""))
3502			(not:SI (match_operand:SI 2 "arm_rhs_operand" "")))
3503		(match_operand:SI 3 "arm_rhs_operand" "")))
3504   (clobber (match_operand:SI 4 "s_register_operand" ""))]
3505  "TARGET_32BIT"
3506  [(set (match_dup 4) (and:SI (ior:SI (match_dup 1) (match_dup 2))
3507			      (not:SI (match_dup 3))))
3508   (set (match_dup 0) (not:SI (match_dup 4)))]
3509  ""
3510)
3511
3512(define_insn_and_split "*andsi_iorsi3_notsi"
3513  [(set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r")
3514	(and:SI (ior:SI (match_operand:SI 1 "s_register_operand" "%0,r,r")
3515			(match_operand:SI 2 "arm_rhs_operand" "rI,0,rI"))
3516		(not:SI (match_operand:SI 3 "arm_rhs_operand" "rI,rI,rI"))))]
3517  "TARGET_32BIT"
3518  "#"   ; "orr%?\\t%0, %1, %2\;bic%?\\t%0, %0, %3"
3519  "&& reload_completed"
3520  [(set (match_dup 0) (ior:SI (match_dup 1) (match_dup 2)))
3521   (set (match_dup 0) (and:SI (match_dup 4) (match_dup 5)))]
3522  {
3523     /* If operands[3] is a constant make sure to fold the NOT into it
3524	to avoid creating a NOT of a CONST_INT.  */
3525    rtx not_rtx = simplify_gen_unary (NOT, SImode, operands[3], SImode);
3526    if (CONST_INT_P (not_rtx))
3527      {
3528	operands[4] = operands[0];
3529	operands[5] = not_rtx;
3530      }
3531    else
3532      {
3533	operands[5] = operands[0];
3534	operands[4] = not_rtx;
3535      }
3536  }
3537  [(set_attr "length" "8")
3538   (set_attr "ce_count" "2")
3539   (set_attr "predicable" "yes")
3540   (set_attr "type" "multiple")]
3541)
3542
3543; ??? Are these four splitters still beneficial when the Thumb-2 bitfield
3544; insns are available?
3545(define_split
3546  [(set (match_operand:SI 0 "s_register_operand" "")
3547	(match_operator:SI 1 "logical_binary_operator"
3548	 [(zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
3549			   (match_operand:SI 3 "const_int_operand" "")
3550			   (match_operand:SI 4 "const_int_operand" ""))
3551	  (match_operator:SI 9 "logical_binary_operator"
3552	   [(lshiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3553			 (match_operand:SI 6 "const_int_operand" ""))
3554	    (match_operand:SI 7 "s_register_operand" "")])]))
3555   (clobber (match_operand:SI 8 "s_register_operand" ""))]
3556  "TARGET_32BIT
3557   && GET_CODE (operands[1]) == GET_CODE (operands[9])
3558   && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3559  [(set (match_dup 8)
3560	(match_op_dup 1
3561	 [(ashift:SI (match_dup 2) (match_dup 4))
3562	  (match_dup 5)]))
3563   (set (match_dup 0)
3564	(match_op_dup 1
3565	 [(lshiftrt:SI (match_dup 8) (match_dup 6))
3566	  (match_dup 7)]))]
3567  "
3568  operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3569")
3570
3571(define_split
3572  [(set (match_operand:SI 0 "s_register_operand" "")
3573	(match_operator:SI 1 "logical_binary_operator"
3574	 [(match_operator:SI 9 "logical_binary_operator"
3575	   [(lshiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3576			 (match_operand:SI 6 "const_int_operand" ""))
3577	    (match_operand:SI 7 "s_register_operand" "")])
3578	  (zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
3579			   (match_operand:SI 3 "const_int_operand" "")
3580			   (match_operand:SI 4 "const_int_operand" ""))]))
3581   (clobber (match_operand:SI 8 "s_register_operand" ""))]
3582  "TARGET_32BIT
3583   && GET_CODE (operands[1]) == GET_CODE (operands[9])
3584   && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3585  [(set (match_dup 8)
3586	(match_op_dup 1
3587	 [(ashift:SI (match_dup 2) (match_dup 4))
3588	  (match_dup 5)]))
3589   (set (match_dup 0)
3590	(match_op_dup 1
3591	 [(lshiftrt:SI (match_dup 8) (match_dup 6))
3592	  (match_dup 7)]))]
3593  "
3594  operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3595")
3596
3597(define_split
3598  [(set (match_operand:SI 0 "s_register_operand" "")
3599	(match_operator:SI 1 "logical_binary_operator"
3600	 [(sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
3601			   (match_operand:SI 3 "const_int_operand" "")
3602			   (match_operand:SI 4 "const_int_operand" ""))
3603	  (match_operator:SI 9 "logical_binary_operator"
3604	   [(ashiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3605			 (match_operand:SI 6 "const_int_operand" ""))
3606	    (match_operand:SI 7 "s_register_operand" "")])]))
3607   (clobber (match_operand:SI 8 "s_register_operand" ""))]
3608  "TARGET_32BIT
3609   && GET_CODE (operands[1]) == GET_CODE (operands[9])
3610   && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3611  [(set (match_dup 8)
3612	(match_op_dup 1
3613	 [(ashift:SI (match_dup 2) (match_dup 4))
3614	  (match_dup 5)]))
3615   (set (match_dup 0)
3616	(match_op_dup 1
3617	 [(ashiftrt:SI (match_dup 8) (match_dup 6))
3618	  (match_dup 7)]))]
3619  "
3620  operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3621")
3622
3623(define_split
3624  [(set (match_operand:SI 0 "s_register_operand" "")
3625	(match_operator:SI 1 "logical_binary_operator"
3626	 [(match_operator:SI 9 "logical_binary_operator"
3627	   [(ashiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3628			 (match_operand:SI 6 "const_int_operand" ""))
3629	    (match_operand:SI 7 "s_register_operand" "")])
3630	  (sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
3631			   (match_operand:SI 3 "const_int_operand" "")
3632			   (match_operand:SI 4 "const_int_operand" ""))]))
3633   (clobber (match_operand:SI 8 "s_register_operand" ""))]
3634  "TARGET_32BIT
3635   && GET_CODE (operands[1]) == GET_CODE (operands[9])
3636   && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3637  [(set (match_dup 8)
3638	(match_op_dup 1
3639	 [(ashift:SI (match_dup 2) (match_dup 4))
3640	  (match_dup 5)]))
3641   (set (match_dup 0)
3642	(match_op_dup 1
3643	 [(ashiftrt:SI (match_dup 8) (match_dup 6))
3644	  (match_dup 7)]))]
3645  "
3646  operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3647")
3648
3649
3650;; Minimum and maximum insns
3651
3652(define_expand "smaxsi3"
3653  [(parallel [
3654    (set (match_operand:SI 0 "s_register_operand" "")
3655	 (smax:SI (match_operand:SI 1 "s_register_operand" "")
3656		  (match_operand:SI 2 "arm_rhs_operand" "")))
3657    (clobber (reg:CC CC_REGNUM))])]
3658  "TARGET_32BIT"
3659  "
3660  if (operands[2] == const0_rtx || operands[2] == constm1_rtx)
3661    {
3662      /* No need for a clobber of the condition code register here.  */
3663      emit_insn (gen_rtx_SET (operands[0],
3664			      gen_rtx_SMAX (SImode, operands[1],
3665					    operands[2])));
3666      DONE;
3667    }
3668")
3669
3670(define_insn "*smax_0"
3671  [(set (match_operand:SI 0 "s_register_operand" "=r")
3672	(smax:SI (match_operand:SI 1 "s_register_operand" "r")
3673		 (const_int 0)))]
3674  "TARGET_32BIT"
3675  "bic%?\\t%0, %1, %1, asr #31"
3676  [(set_attr "predicable" "yes")
3677   (set_attr "type" "logic_shift_reg")]
3678)
3679
3680(define_insn "*smax_m1"
3681  [(set (match_operand:SI 0 "s_register_operand" "=r")
3682	(smax:SI (match_operand:SI 1 "s_register_operand" "r")
3683		 (const_int -1)))]
3684  "TARGET_32BIT"
3685  "orr%?\\t%0, %1, %1, asr #31"
3686  [(set_attr "predicable" "yes")
3687   (set_attr "type" "logic_shift_reg")]
3688)
3689
3690(define_insn_and_split "*arm_smax_insn"
3691  [(set (match_operand:SI          0 "s_register_operand" "=r,r")
3692	(smax:SI (match_operand:SI 1 "s_register_operand"  "%0,?r")
3693		 (match_operand:SI 2 "arm_rhs_operand"    "rI,rI")))
3694   (clobber (reg:CC CC_REGNUM))]
3695  "TARGET_ARM"
3696  "#"
3697   ; cmp\\t%1, %2\;movlt\\t%0, %2
3698   ; cmp\\t%1, %2\;movge\\t%0, %1\;movlt\\t%0, %2"
3699  "TARGET_ARM"
3700  [(set (reg:CC CC_REGNUM)
3701        (compare:CC (match_dup 1) (match_dup 2)))
3702   (set (match_dup 0)
3703        (if_then_else:SI (ge:SI (reg:CC CC_REGNUM) (const_int 0))
3704                         (match_dup 1)
3705                         (match_dup 2)))]
3706  ""
3707  [(set_attr "conds" "clob")
3708   (set_attr "length" "8,12")
3709   (set_attr "type" "multiple")]
3710)
3711
3712(define_expand "sminsi3"
3713  [(parallel [
3714    (set (match_operand:SI 0 "s_register_operand" "")
3715	 (smin:SI (match_operand:SI 1 "s_register_operand" "")
3716		  (match_operand:SI 2 "arm_rhs_operand" "")))
3717    (clobber (reg:CC CC_REGNUM))])]
3718  "TARGET_32BIT"
3719  "
3720  if (operands[2] == const0_rtx)
3721    {
3722      /* No need for a clobber of the condition code register here.  */
3723      emit_insn (gen_rtx_SET (operands[0],
3724			      gen_rtx_SMIN (SImode, operands[1],
3725					    operands[2])));
3726      DONE;
3727    }
3728")
3729
3730(define_insn "*smin_0"
3731  [(set (match_operand:SI 0 "s_register_operand" "=r")
3732	(smin:SI (match_operand:SI 1 "s_register_operand" "r")
3733		 (const_int 0)))]
3734  "TARGET_32BIT"
3735  "and%?\\t%0, %1, %1, asr #31"
3736  [(set_attr "predicable" "yes")
3737   (set_attr "type" "logic_shift_reg")]
3738)
3739
3740(define_insn_and_split "*arm_smin_insn"
3741  [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3742	(smin:SI (match_operand:SI 1 "s_register_operand" "%0,?r")
3743		 (match_operand:SI 2 "arm_rhs_operand" "rI,rI")))
3744   (clobber (reg:CC CC_REGNUM))]
3745  "TARGET_ARM"
3746  "#"
3747    ; cmp\\t%1, %2\;movge\\t%0, %2
3748    ; cmp\\t%1, %2\;movlt\\t%0, %1\;movge\\t%0, %2"
3749  "TARGET_ARM"
3750  [(set (reg:CC CC_REGNUM)
3751        (compare:CC (match_dup 1) (match_dup 2)))
3752   (set (match_dup 0)
3753        (if_then_else:SI (lt:SI (reg:CC CC_REGNUM) (const_int 0))
3754                         (match_dup 1)
3755                         (match_dup 2)))]
3756  ""
3757  [(set_attr "conds" "clob")
3758   (set_attr "length" "8,12")
3759   (set_attr "type" "multiple,multiple")]
3760)
3761
3762(define_expand "umaxsi3"
3763  [(parallel [
3764    (set (match_operand:SI 0 "s_register_operand" "")
3765	 (umax:SI (match_operand:SI 1 "s_register_operand" "")
3766		  (match_operand:SI 2 "arm_rhs_operand" "")))
3767    (clobber (reg:CC CC_REGNUM))])]
3768  "TARGET_32BIT"
3769  ""
3770)
3771
3772(define_insn_and_split "*arm_umaxsi3"
3773  [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
3774	(umax:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
3775		 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
3776   (clobber (reg:CC CC_REGNUM))]
3777  "TARGET_ARM"
3778  "#"
3779    ; cmp\\t%1, %2\;movcc\\t%0, %2
3780    ; cmp\\t%1, %2\;movcs\\t%0, %1
3781    ; cmp\\t%1, %2\;movcs\\t%0, %1\;movcc\\t%0, %2"
3782  "TARGET_ARM"
3783  [(set (reg:CC CC_REGNUM)
3784        (compare:CC (match_dup 1) (match_dup 2)))
3785   (set (match_dup 0)
3786        (if_then_else:SI (geu:SI (reg:CC CC_REGNUM) (const_int 0))
3787                         (match_dup 1)
3788                         (match_dup 2)))]
3789  ""
3790  [(set_attr "conds" "clob")
3791   (set_attr "length" "8,8,12")
3792   (set_attr "type" "store_4")]
3793)
3794
3795(define_expand "uminsi3"
3796  [(parallel [
3797    (set (match_operand:SI 0 "s_register_operand" "")
3798	 (umin:SI (match_operand:SI 1 "s_register_operand" "")
3799		  (match_operand:SI 2 "arm_rhs_operand" "")))
3800    (clobber (reg:CC CC_REGNUM))])]
3801  "TARGET_32BIT"
3802  ""
3803)
3804
3805(define_insn_and_split "*arm_uminsi3"
3806  [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
3807	(umin:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
3808		 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
3809   (clobber (reg:CC CC_REGNUM))]
3810  "TARGET_ARM"
3811  "#"
3812   ; cmp\\t%1, %2\;movcs\\t%0, %2
3813   ; cmp\\t%1, %2\;movcc\\t%0, %1
3814   ; cmp\\t%1, %2\;movcc\\t%0, %1\;movcs\\t%0, %2"
3815  "TARGET_ARM"
3816  [(set (reg:CC CC_REGNUM)
3817        (compare:CC (match_dup 1) (match_dup 2)))
3818   (set (match_dup 0)
3819        (if_then_else:SI (ltu:SI (reg:CC CC_REGNUM) (const_int 0))
3820                         (match_dup 1)
3821                         (match_dup 2)))]
3822  ""
3823  [(set_attr "conds" "clob")
3824   (set_attr "length" "8,8,12")
3825   (set_attr "type" "store_4")]
3826)
3827
3828(define_insn "*store_minmaxsi"
3829  [(set (match_operand:SI 0 "memory_operand" "=m")
3830	(match_operator:SI 3 "minmax_operator"
3831	 [(match_operand:SI 1 "s_register_operand" "r")
3832	  (match_operand:SI 2 "s_register_operand" "r")]))
3833   (clobber (reg:CC CC_REGNUM))]
3834  "TARGET_32BIT && optimize_function_for_size_p (cfun) && !arm_restrict_it"
3835  "*
3836  operands[3] = gen_rtx_fmt_ee (minmax_code (operands[3]), SImode,
3837				operands[1], operands[2]);
3838  output_asm_insn (\"cmp\\t%1, %2\", operands);
3839  if (TARGET_THUMB2)
3840    output_asm_insn (\"ite\t%d3\", operands);
3841  output_asm_insn (\"str%d3\\t%1, %0\", operands);
3842  output_asm_insn (\"str%D3\\t%2, %0\", operands);
3843  return \"\";
3844  "
3845  [(set_attr "conds" "clob")
3846   (set (attr "length")
3847	(if_then_else (eq_attr "is_thumb" "yes")
3848		      (const_int 14)
3849		      (const_int 12)))
3850   (set_attr "type" "store_4")]
3851)
3852
3853; Reject the frame pointer in operand[1], since reloading this after
3854; it has been eliminated can cause carnage.
3855(define_insn "*minmax_arithsi"
3856  [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3857	(match_operator:SI 4 "shiftable_operator"
3858	 [(match_operator:SI 5 "minmax_operator"
3859	   [(match_operand:SI 2 "s_register_operand" "r,r")
3860	    (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
3861	  (match_operand:SI 1 "s_register_operand" "0,?r")]))
3862   (clobber (reg:CC CC_REGNUM))]
3863  "TARGET_32BIT && !arm_eliminable_register (operands[1]) && !arm_restrict_it"
3864  "*
3865  {
3866    enum rtx_code code = GET_CODE (operands[4]);
3867    bool need_else;
3868
3869    if (which_alternative != 0 || operands[3] != const0_rtx
3870        || (code != PLUS && code != IOR && code != XOR))
3871      need_else = true;
3872    else
3873      need_else = false;
3874
3875    operands[5] = gen_rtx_fmt_ee (minmax_code (operands[5]), SImode,
3876				  operands[2], operands[3]);
3877    output_asm_insn (\"cmp\\t%2, %3\", operands);
3878    if (TARGET_THUMB2)
3879      {
3880	if (need_else)
3881	  output_asm_insn (\"ite\\t%d5\", operands);
3882	else
3883	  output_asm_insn (\"it\\t%d5\", operands);
3884      }
3885    output_asm_insn (\"%i4%d5\\t%0, %1, %2\", operands);
3886    if (need_else)
3887      output_asm_insn (\"%i4%D5\\t%0, %1, %3\", operands);
3888    return \"\";
3889  }"
3890  [(set_attr "conds" "clob")
3891   (set (attr "length")
3892	(if_then_else (eq_attr "is_thumb" "yes")
3893		      (const_int 14)
3894		      (const_int 12)))
3895   (set_attr "type" "multiple")]
3896)
3897
3898; Reject the frame pointer in operand[1], since reloading this after
3899; it has been eliminated can cause carnage.
3900(define_insn_and_split "*minmax_arithsi_non_canon"
3901  [(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts")
3902	(minus:SI
3903	 (match_operand:SI 1 "s_register_operand" "0,?Ts")
3904	  (match_operator:SI 4 "minmax_operator"
3905	   [(match_operand:SI 2 "s_register_operand" "Ts,Ts")
3906	    (match_operand:SI 3 "arm_rhs_operand" "TsI,TsI")])))
3907   (clobber (reg:CC CC_REGNUM))]
3908  "TARGET_32BIT && !arm_eliminable_register (operands[1])
3909   && !(arm_restrict_it && CONST_INT_P (operands[3]))"
3910  "#"
3911  "TARGET_32BIT && !arm_eliminable_register (operands[1]) && reload_completed"
3912  [(set (reg:CC CC_REGNUM)
3913        (compare:CC (match_dup 2) (match_dup 3)))
3914
3915   (cond_exec (match_op_dup 4 [(reg:CC CC_REGNUM) (const_int 0)])
3916              (set (match_dup 0)
3917                   (minus:SI (match_dup 1)
3918                             (match_dup 2))))
3919   (cond_exec (match_op_dup 5 [(reg:CC CC_REGNUM) (const_int 0)])
3920              (set (match_dup 0)
3921                   (match_dup 6)))]
3922  {
3923  machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
3924                                           operands[2], operands[3]);
3925  enum rtx_code rc = minmax_code (operands[4]);
3926  operands[4] = gen_rtx_fmt_ee (rc, VOIDmode,
3927                                operands[2], operands[3]);
3928
3929  if (mode == CCFPmode || mode == CCFPEmode)
3930    rc = reverse_condition_maybe_unordered (rc);
3931  else
3932    rc = reverse_condition (rc);
3933  operands[5] = gen_rtx_fmt_ee (rc, SImode, operands[2], operands[3]);
3934  if (CONST_INT_P (operands[3]))
3935    operands[6] = plus_constant (SImode, operands[1], -INTVAL (operands[3]));
3936  else
3937    operands[6] = gen_rtx_MINUS (SImode, operands[1], operands[3]);
3938  }
3939  [(set_attr "conds" "clob")
3940   (set (attr "length")
3941	(if_then_else (eq_attr "is_thumb" "yes")
3942		      (const_int 14)
3943		      (const_int 12)))
3944   (set_attr "type" "multiple")]
3945)
3946
3947(define_code_iterator SAT [smin smax])
3948(define_code_iterator SATrev [smin smax])
3949(define_code_attr SATlo [(smin "1") (smax "2")])
3950(define_code_attr SAThi [(smin "2") (smax "1")])
3951
3952(define_insn "*satsi_<SAT:code>"
3953  [(set (match_operand:SI 0 "s_register_operand" "=r")
3954        (SAT:SI (SATrev:SI (match_operand:SI 3 "s_register_operand" "r")
3955                           (match_operand:SI 1 "const_int_operand" "i"))
3956                (match_operand:SI 2 "const_int_operand" "i")))]
3957  "TARGET_32BIT && arm_arch6 && <SAT:CODE> != <SATrev:CODE>
3958   && arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>], NULL, NULL)"
3959{
3960  int mask;
3961  bool signed_sat;
3962  if (!arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>],
3963                               &mask, &signed_sat))
3964    gcc_unreachable ();
3965
3966  operands[1] = GEN_INT (mask);
3967  if (signed_sat)
3968    return "ssat%?\t%0, %1, %3";
3969  else
3970    return "usat%?\t%0, %1, %3";
3971}
3972  [(set_attr "predicable" "yes")
3973   (set_attr "type" "alus_imm")]
3974)
3975
3976(define_insn "*satsi_<SAT:code>_shift"
3977  [(set (match_operand:SI 0 "s_register_operand" "=r")
3978        (SAT:SI (SATrev:SI (match_operator:SI 3 "sat_shift_operator"
3979                             [(match_operand:SI 4 "s_register_operand" "r")
3980                              (match_operand:SI 5 "const_int_operand" "i")])
3981                           (match_operand:SI 1 "const_int_operand" "i"))
3982                (match_operand:SI 2 "const_int_operand" "i")))]
3983  "TARGET_32BIT && arm_arch6 && <SAT:CODE> != <SATrev:CODE>
3984   && arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>], NULL, NULL)"
3985{
3986  int mask;
3987  bool signed_sat;
3988  if (!arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>],
3989                               &mask, &signed_sat))
3990    gcc_unreachable ();
3991
3992  operands[1] = GEN_INT (mask);
3993  if (signed_sat)
3994    return "ssat%?\t%0, %1, %4%S3";
3995  else
3996    return "usat%?\t%0, %1, %4%S3";
3997}
3998  [(set_attr "predicable" "yes")
3999   (set_attr "shift" "3")
4000   (set_attr "type" "logic_shift_reg")])
4001
4002;; Shift and rotation insns
4003
4004(define_expand "ashldi3"
4005  [(set (match_operand:DI            0 "s_register_operand" "")
4006        (ashift:DI (match_operand:DI 1 "s_register_operand" "")
4007                   (match_operand:SI 2 "general_operand" "")))]
4008  "TARGET_32BIT"
4009  "
4010  if (TARGET_NEON)
4011    {
4012      /* Delay the decision whether to use NEON or core-regs until
4013	 register allocation.  */
4014      emit_insn (gen_ashldi3_neon (operands[0], operands[1], operands[2]));
4015      DONE;
4016    }
4017  else
4018    {
4019      /* Only the NEON case can handle in-memory shift counts.  */
4020      if (!reg_or_int_operand (operands[2], SImode))
4021        operands[2] = force_reg (SImode, operands[2]);
4022    }
4023
4024  if (!CONST_INT_P (operands[2]) && TARGET_REALLY_IWMMXT)
4025    ; /* No special preparation statements; expand pattern as above.  */
4026  else
4027    {
4028      rtx scratch1, scratch2;
4029
4030      /* Ideally we should use iwmmxt here if we could know that operands[1]
4031         ends up already living in an iwmmxt register. Otherwise it's
4032         cheaper to have the alternate code being generated than moving
4033         values to iwmmxt regs and back.  */
4034
4035      /* Expand operation using core-registers.
4036	 'FAIL' would achieve the same thing, but this is a bit smarter.  */
4037      scratch1 = gen_reg_rtx (SImode);
4038      scratch2 = gen_reg_rtx (SImode);
4039      arm_emit_coreregs_64bit_shift (ASHIFT, operands[0], operands[1],
4040				     operands[2], scratch1, scratch2);
4041      DONE;
4042    }
4043  "
4044)
4045
4046(define_expand "ashlsi3"
4047  [(set (match_operand:SI            0 "s_register_operand" "")
4048	(ashift:SI (match_operand:SI 1 "s_register_operand" "")
4049		   (match_operand:SI 2 "arm_rhs_operand" "")))]
4050  "TARGET_EITHER"
4051  "
4052  if (CONST_INT_P (operands[2])
4053      && (UINTVAL (operands[2])) > 31)
4054    {
4055      emit_insn (gen_movsi (operands[0], const0_rtx));
4056      DONE;
4057    }
4058  "
4059)
4060
4061(define_expand "ashrdi3"
4062  [(set (match_operand:DI              0 "s_register_operand" "")
4063        (ashiftrt:DI (match_operand:DI 1 "s_register_operand" "")
4064                     (match_operand:SI 2 "reg_or_int_operand" "")))]
4065  "TARGET_32BIT"
4066  "
4067  if (TARGET_NEON)
4068    {
4069      /* Delay the decision whether to use NEON or core-regs until
4070	 register allocation.  */
4071      emit_insn (gen_ashrdi3_neon (operands[0], operands[1], operands[2]));
4072      DONE;
4073    }
4074
4075  if (!CONST_INT_P (operands[2]) && TARGET_REALLY_IWMMXT)
4076    ; /* No special preparation statements; expand pattern as above.  */
4077  else
4078    {
4079      rtx scratch1, scratch2;
4080
4081      /* Ideally we should use iwmmxt here if we could know that operands[1]
4082         ends up already living in an iwmmxt register. Otherwise it's
4083         cheaper to have the alternate code being generated than moving
4084         values to iwmmxt regs and back.  */
4085
4086      /* Expand operation using core-registers.
4087	 'FAIL' would achieve the same thing, but this is a bit smarter.  */
4088      scratch1 = gen_reg_rtx (SImode);
4089      scratch2 = gen_reg_rtx (SImode);
4090      arm_emit_coreregs_64bit_shift (ASHIFTRT, operands[0], operands[1],
4091				     operands[2], scratch1, scratch2);
4092      DONE;
4093    }
4094  "
4095)
4096
4097(define_expand "ashrsi3"
4098  [(set (match_operand:SI              0 "s_register_operand" "")
4099	(ashiftrt:SI (match_operand:SI 1 "s_register_operand" "")
4100		     (match_operand:SI 2 "arm_rhs_operand" "")))]
4101  "TARGET_EITHER"
4102  "
4103  if (CONST_INT_P (operands[2])
4104      && UINTVAL (operands[2]) > 31)
4105    operands[2] = GEN_INT (31);
4106  "
4107)
4108
4109(define_expand "lshrdi3"
4110  [(set (match_operand:DI              0 "s_register_operand" "")
4111        (lshiftrt:DI (match_operand:DI 1 "s_register_operand" "")
4112                     (match_operand:SI 2 "reg_or_int_operand" "")))]
4113  "TARGET_32BIT"
4114  "
4115  if (TARGET_NEON)
4116    {
4117      /* Delay the decision whether to use NEON or core-regs until
4118	 register allocation.  */
4119      emit_insn (gen_lshrdi3_neon (operands[0], operands[1], operands[2]));
4120      DONE;
4121    }
4122
4123  if (!CONST_INT_P (operands[2]) && TARGET_REALLY_IWMMXT)
4124    ; /* No special preparation statements; expand pattern as above.  */
4125  else
4126    {
4127      rtx scratch1, scratch2;
4128
4129      /* Ideally we should use iwmmxt here if we could know that operands[1]
4130         ends up already living in an iwmmxt register. Otherwise it's
4131         cheaper to have the alternate code being generated than moving
4132         values to iwmmxt regs and back.  */
4133
4134      /* Expand operation using core-registers.
4135	 'FAIL' would achieve the same thing, but this is a bit smarter.  */
4136      scratch1 = gen_reg_rtx (SImode);
4137      scratch2 = gen_reg_rtx (SImode);
4138      arm_emit_coreregs_64bit_shift (LSHIFTRT, operands[0], operands[1],
4139				     operands[2], scratch1, scratch2);
4140      DONE;
4141    }
4142  "
4143)
4144
4145(define_expand "lshrsi3"
4146  [(set (match_operand:SI              0 "s_register_operand" "")
4147	(lshiftrt:SI (match_operand:SI 1 "s_register_operand" "")
4148		     (match_operand:SI 2 "arm_rhs_operand" "")))]
4149  "TARGET_EITHER"
4150  "
4151  if (CONST_INT_P (operands[2])
4152      && (UINTVAL (operands[2])) > 31)
4153    {
4154      emit_insn (gen_movsi (operands[0], const0_rtx));
4155      DONE;
4156    }
4157  "
4158)
4159
4160(define_expand "rotlsi3"
4161  [(set (match_operand:SI              0 "s_register_operand" "")
4162	(rotatert:SI (match_operand:SI 1 "s_register_operand" "")
4163		     (match_operand:SI 2 "reg_or_int_operand" "")))]
4164  "TARGET_32BIT"
4165  "
4166  if (CONST_INT_P (operands[2]))
4167    operands[2] = GEN_INT ((32 - INTVAL (operands[2])) % 32);
4168  else
4169    {
4170      rtx reg = gen_reg_rtx (SImode);
4171      emit_insn (gen_subsi3 (reg, GEN_INT (32), operands[2]));
4172      operands[2] = reg;
4173    }
4174  "
4175)
4176
4177(define_expand "rotrsi3"
4178  [(set (match_operand:SI              0 "s_register_operand" "")
4179	(rotatert:SI (match_operand:SI 1 "s_register_operand" "")
4180		     (match_operand:SI 2 "arm_rhs_operand" "")))]
4181  "TARGET_EITHER"
4182  "
4183  if (TARGET_32BIT)
4184    {
4185      if (CONST_INT_P (operands[2])
4186          && UINTVAL (operands[2]) > 31)
4187        operands[2] = GEN_INT (INTVAL (operands[2]) % 32);
4188    }
4189  else /* TARGET_THUMB1 */
4190    {
4191      if (CONST_INT_P (operands [2]))
4192        operands [2] = force_reg (SImode, operands[2]);
4193    }
4194  "
4195)
4196
4197(define_insn "*arm_shiftsi3"
4198  [(set (match_operand:SI   0 "s_register_operand" "=l,l,r,r")
4199	(match_operator:SI  3 "shift_operator"
4200	 [(match_operand:SI 1 "s_register_operand"  "0,l,r,r")
4201	  (match_operand:SI 2 "reg_or_int_operand" "l,M,M,r")]))]
4202  "TARGET_32BIT"
4203  "* return arm_output_shift(operands, 0);"
4204  [(set_attr "predicable" "yes")
4205   (set_attr "arch" "t2,t2,*,*")
4206   (set_attr "predicable_short_it" "yes,yes,no,no")
4207   (set_attr "length" "4")
4208   (set_attr "shift" "1")
4209   (set_attr "type" "alu_shift_reg,alu_shift_imm,alu_shift_imm,alu_shift_reg")]
4210)
4211
4212(define_insn "*shiftsi3_compare0"
4213  [(set (reg:CC_NOOV CC_REGNUM)
4214	(compare:CC_NOOV (match_operator:SI 3 "shift_operator"
4215			  [(match_operand:SI 1 "s_register_operand" "r,r")
4216			   (match_operand:SI 2 "arm_rhs_operand" "M,r")])
4217			 (const_int 0)))
4218   (set (match_operand:SI 0 "s_register_operand" "=r,r")
4219	(match_op_dup 3 [(match_dup 1) (match_dup 2)]))]
4220  "TARGET_32BIT"
4221  "* return arm_output_shift(operands, 1);"
4222  [(set_attr "conds" "set")
4223   (set_attr "shift" "1")
4224   (set_attr "type" "alus_shift_imm,alus_shift_reg")]
4225)
4226
4227(define_insn "*shiftsi3_compare0_scratch"
4228  [(set (reg:CC_NOOV CC_REGNUM)
4229	(compare:CC_NOOV (match_operator:SI 3 "shift_operator"
4230			  [(match_operand:SI 1 "s_register_operand" "r,r")
4231			   (match_operand:SI 2 "arm_rhs_operand" "M,r")])
4232			 (const_int 0)))
4233   (clobber (match_scratch:SI 0 "=r,r"))]
4234  "TARGET_32BIT"
4235  "* return arm_output_shift(operands, 1);"
4236  [(set_attr "conds" "set")
4237   (set_attr "shift" "1")
4238   (set_attr "type" "shift_imm,shift_reg")]
4239)
4240
4241(define_insn "*not_shiftsi"
4242  [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4243	(not:SI (match_operator:SI 3 "shift_operator"
4244		 [(match_operand:SI 1 "s_register_operand" "r,r")
4245		  (match_operand:SI 2 "shift_amount_operand" "M,rM")])))]
4246  "TARGET_32BIT"
4247  "mvn%?\\t%0, %1%S3"
4248  [(set_attr "predicable" "yes")
4249   (set_attr "shift" "1")
4250   (set_attr "arch" "32,a")
4251   (set_attr "type" "mvn_shift,mvn_shift_reg")])
4252
4253(define_insn "*not_shiftsi_compare0"
4254  [(set (reg:CC_NOOV CC_REGNUM)
4255	(compare:CC_NOOV
4256	 (not:SI (match_operator:SI 3 "shift_operator"
4257		  [(match_operand:SI 1 "s_register_operand" "r,r")
4258		   (match_operand:SI 2 "shift_amount_operand" "M,rM")]))
4259	 (const_int 0)))
4260   (set (match_operand:SI 0 "s_register_operand" "=r,r")
4261	(not:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])))]
4262  "TARGET_32BIT"
4263  "mvns%?\\t%0, %1%S3"
4264  [(set_attr "conds" "set")
4265   (set_attr "shift" "1")
4266   (set_attr "arch" "32,a")
4267   (set_attr "type" "mvn_shift,mvn_shift_reg")])
4268
4269(define_insn "*not_shiftsi_compare0_scratch"
4270  [(set (reg:CC_NOOV CC_REGNUM)
4271	(compare:CC_NOOV
4272	 (not:SI (match_operator:SI 3 "shift_operator"
4273		  [(match_operand:SI 1 "s_register_operand" "r,r")
4274		   (match_operand:SI 2 "shift_amount_operand" "M,rM")]))
4275	 (const_int 0)))
4276   (clobber (match_scratch:SI 0 "=r,r"))]
4277  "TARGET_32BIT"
4278  "mvns%?\\t%0, %1%S3"
4279  [(set_attr "conds" "set")
4280   (set_attr "shift" "1")
4281   (set_attr "arch" "32,a")
4282   (set_attr "type" "mvn_shift,mvn_shift_reg")])
4283
4284;; We don't really have extzv, but defining this using shifts helps
4285;; to reduce register pressure later on.
4286
4287(define_expand "extzv"
4288  [(set (match_operand 0 "s_register_operand" "")
4289	(zero_extract (match_operand 1 "nonimmediate_operand" "")
4290		      (match_operand 2 "const_int_operand" "")
4291		      (match_operand 3 "const_int_operand" "")))]
4292  "TARGET_THUMB1 || arm_arch_thumb2"
4293  "
4294  {
4295    HOST_WIDE_INT lshift = 32 - INTVAL (operands[2]) - INTVAL (operands[3]);
4296    HOST_WIDE_INT rshift = 32 - INTVAL (operands[2]);
4297
4298    if (arm_arch_thumb2)
4299      {
4300	HOST_WIDE_INT width = INTVAL (operands[2]);
4301	HOST_WIDE_INT bitpos = INTVAL (operands[3]);
4302
4303	if (unaligned_access && MEM_P (operands[1])
4304	    && (width == 16 || width == 32) && (bitpos % BITS_PER_UNIT) == 0)
4305	  {
4306	    rtx base_addr;
4307
4308	    if (BYTES_BIG_ENDIAN)
4309	      bitpos = GET_MODE_BITSIZE (GET_MODE (operands[0])) - width
4310		       - bitpos;
4311
4312	    if (width == 32)
4313              {
4314		base_addr = adjust_address (operands[1], SImode,
4315					    bitpos / BITS_PER_UNIT);
4316		emit_insn (gen_unaligned_loadsi (operands[0], base_addr));
4317              }
4318	    else
4319              {
4320		rtx dest = operands[0];
4321		rtx tmp = gen_reg_rtx (SImode);
4322
4323		/* We may get a paradoxical subreg here.  Strip it off.  */
4324		if (GET_CODE (dest) == SUBREG
4325		    && GET_MODE (dest) == SImode
4326		    && GET_MODE (SUBREG_REG (dest)) == HImode)
4327		  dest = SUBREG_REG (dest);
4328
4329		if (GET_MODE_BITSIZE (GET_MODE (dest)) != width)
4330		  FAIL;
4331
4332		base_addr = adjust_address (operands[1], HImode,
4333					    bitpos / BITS_PER_UNIT);
4334		emit_insn (gen_unaligned_loadhiu (tmp, base_addr));
4335		emit_move_insn (gen_lowpart (SImode, dest), tmp);
4336	      }
4337	    DONE;
4338	  }
4339	else if (s_register_operand (operands[1], GET_MODE (operands[1])))
4340	  {
4341	    emit_insn (gen_extzv_t2 (operands[0], operands[1], operands[2],
4342				     operands[3]));
4343	    DONE;
4344	  }
4345	else
4346	  FAIL;
4347      }
4348
4349    if (!s_register_operand (operands[1], GET_MODE (operands[1])))
4350      FAIL;
4351
4352    operands[3] = GEN_INT (rshift);
4353
4354    if (lshift == 0)
4355      {
4356        emit_insn (gen_lshrsi3 (operands[0], operands[1], operands[3]));
4357        DONE;
4358      }
4359
4360    emit_insn (gen_extzv_t1 (operands[0], operands[1], GEN_INT (lshift),
4361			     operands[3], gen_reg_rtx (SImode)));
4362    DONE;
4363  }"
4364)
4365
4366;; Helper for extzv, for the Thumb-1 register-shifts case.
4367
4368(define_expand "extzv_t1"
4369  [(set (match_operand:SI 4 "s_register_operand" "")
4370	(ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
4371		   (match_operand:SI 2 "const_int_operand" "")))
4372   (set (match_operand:SI 0 "s_register_operand" "")
4373	(lshiftrt:SI (match_dup 4)
4374		     (match_operand:SI 3 "const_int_operand" "")))]
4375  "TARGET_THUMB1"
4376  "")
4377
4378(define_expand "extv"
4379  [(set (match_operand 0 "s_register_operand" "")
4380	(sign_extract (match_operand 1 "nonimmediate_operand" "")
4381		      (match_operand 2 "const_int_operand" "")
4382		      (match_operand 3 "const_int_operand" "")))]
4383  "arm_arch_thumb2"
4384{
4385  HOST_WIDE_INT width = INTVAL (operands[2]);
4386  HOST_WIDE_INT bitpos = INTVAL (operands[3]);
4387
4388  if (unaligned_access && MEM_P (operands[1]) && (width == 16 || width == 32)
4389      && (bitpos % BITS_PER_UNIT)  == 0)
4390    {
4391      rtx base_addr;
4392
4393      if (BYTES_BIG_ENDIAN)
4394	bitpos = GET_MODE_BITSIZE (GET_MODE (operands[0])) - width - bitpos;
4395
4396      if (width == 32)
4397        {
4398	  base_addr = adjust_address (operands[1], SImode,
4399				      bitpos / BITS_PER_UNIT);
4400	  emit_insn (gen_unaligned_loadsi (operands[0], base_addr));
4401        }
4402      else
4403        {
4404	  rtx dest = operands[0];
4405	  rtx tmp = gen_reg_rtx (SImode);
4406
4407	  /* We may get a paradoxical subreg here.  Strip it off.  */
4408	  if (GET_CODE (dest) == SUBREG
4409	      && GET_MODE (dest) == SImode
4410	      && GET_MODE (SUBREG_REG (dest)) == HImode)
4411	    dest = SUBREG_REG (dest);
4412
4413	  if (GET_MODE_BITSIZE (GET_MODE (dest)) != width)
4414	    FAIL;
4415
4416	  base_addr = adjust_address (operands[1], HImode,
4417				      bitpos / BITS_PER_UNIT);
4418	  emit_insn (gen_unaligned_loadhis (tmp, base_addr));
4419	  emit_move_insn (gen_lowpart (SImode, dest), tmp);
4420	}
4421
4422      DONE;
4423    }
4424  else if (!s_register_operand (operands[1], GET_MODE (operands[1])))
4425    FAIL;
4426  else if (GET_MODE (operands[0]) == SImode
4427	   && GET_MODE (operands[1]) == SImode)
4428    {
4429      emit_insn (gen_extv_regsi (operands[0], operands[1], operands[2],
4430				 operands[3]));
4431      DONE;
4432    }
4433
4434  FAIL;
4435})
4436
4437; Helper to expand register forms of extv with the proper modes.
4438
4439(define_expand "extv_regsi"
4440  [(set (match_operand:SI 0 "s_register_operand" "")
4441	(sign_extract:SI (match_operand:SI 1 "s_register_operand" "")
4442			 (match_operand 2 "const_int_operand" "")
4443			 (match_operand 3 "const_int_operand" "")))]
4444  ""
4445{
4446})
4447
4448; ARMv6+ unaligned load/store instructions (used for packed structure accesses).
4449
4450(define_insn "unaligned_loadsi"
4451  [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4452	(unspec:SI [(match_operand:SI 1 "memory_operand" "Uw,m")]
4453		   UNSPEC_UNALIGNED_LOAD))]
4454  "unaligned_access"
4455  "ldr%?\t%0, %1\t@ unaligned"
4456  [(set_attr "arch" "t2,any")
4457   (set_attr "length" "2,4")
4458   (set_attr "predicable" "yes")
4459   (set_attr "predicable_short_it" "yes,no")
4460   (set_attr "type" "load_4")])
4461
4462(define_insn "unaligned_loadhis"
4463  [(set (match_operand:SI 0 "s_register_operand" "=r")
4464	(sign_extend:SI
4465	  (unspec:HI [(match_operand:HI 1 "memory_operand" "Uh")]
4466		     UNSPEC_UNALIGNED_LOAD)))]
4467  "unaligned_access"
4468  "ldrsh%?\t%0, %1\t@ unaligned"
4469  [(set_attr "predicable" "yes")
4470   (set_attr "type" "load_byte")])
4471
4472(define_insn "unaligned_loadhiu"
4473  [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4474	(zero_extend:SI
4475	  (unspec:HI [(match_operand:HI 1 "memory_operand" "Uw,m")]
4476		     UNSPEC_UNALIGNED_LOAD)))]
4477  "unaligned_access"
4478  "ldrh%?\t%0, %1\t@ unaligned"
4479  [(set_attr "arch" "t2,any")
4480   (set_attr "length" "2,4")
4481   (set_attr "predicable" "yes")
4482   (set_attr "predicable_short_it" "yes,no")
4483   (set_attr "type" "load_byte")])
4484
4485(define_insn "unaligned_storesi"
4486  [(set (match_operand:SI 0 "memory_operand" "=Uw,m")
4487	(unspec:SI [(match_operand:SI 1 "s_register_operand" "l,r")]
4488		   UNSPEC_UNALIGNED_STORE))]
4489  "unaligned_access"
4490  "str%?\t%1, %0\t@ unaligned"
4491  [(set_attr "arch" "t2,any")
4492   (set_attr "length" "2,4")
4493   (set_attr "predicable" "yes")
4494   (set_attr "predicable_short_it" "yes,no")
4495   (set_attr "type" "store_4")])
4496
4497(define_insn "unaligned_storehi"
4498  [(set (match_operand:HI 0 "memory_operand" "=Uw,m")
4499	(unspec:HI [(match_operand:HI 1 "s_register_operand" "l,r")]
4500		   UNSPEC_UNALIGNED_STORE))]
4501  "unaligned_access"
4502  "strh%?\t%1, %0\t@ unaligned"
4503  [(set_attr "arch" "t2,any")
4504   (set_attr "length" "2,4")
4505   (set_attr "predicable" "yes")
4506   (set_attr "predicable_short_it" "yes,no")
4507   (set_attr "type" "store_4")])
4508
4509
4510(define_insn "*extv_reg"
4511  [(set (match_operand:SI 0 "s_register_operand" "=r")
4512	(sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
4513			  (match_operand:SI 2 "const_int_operand" "n")
4514			  (match_operand:SI 3 "const_int_operand" "n")))]
4515  "arm_arch_thumb2
4516   && IN_RANGE (INTVAL (operands[3]), 0, 31)
4517   && IN_RANGE (INTVAL (operands[2]), 1, 32 - INTVAL (operands[3]))"
4518  "sbfx%?\t%0, %1, %3, %2"
4519  [(set_attr "length" "4")
4520   (set_attr "predicable" "yes")
4521   (set_attr "type" "bfm")]
4522)
4523
4524(define_insn "extzv_t2"
4525  [(set (match_operand:SI 0 "s_register_operand" "=r")
4526	(zero_extract:SI (match_operand:SI 1 "s_register_operand" "r")
4527			  (match_operand:SI 2 "const_int_operand" "n")
4528			  (match_operand:SI 3 "const_int_operand" "n")))]
4529  "arm_arch_thumb2
4530   && IN_RANGE (INTVAL (operands[3]), 0, 31)
4531   && IN_RANGE (INTVAL (operands[2]), 1, 32 - INTVAL (operands[3]))"
4532  "ubfx%?\t%0, %1, %3, %2"
4533  [(set_attr "length" "4")
4534   (set_attr "predicable" "yes")
4535   (set_attr "type" "bfm")]
4536)
4537
4538
4539;; Division instructions
4540(define_insn "divsi3"
4541  [(set (match_operand:SI	  0 "s_register_operand" "=r,r")
4542	(div:SI (match_operand:SI 1 "s_register_operand"  "r,r")
4543		(match_operand:SI 2 "s_register_operand"  "r,r")))]
4544  "TARGET_IDIV"
4545  "@
4546   sdiv%?\t%0, %1, %2
4547   sdiv\t%0, %1, %2"
4548  [(set_attr "arch" "32,v8mb")
4549   (set_attr "predicable" "yes")
4550   (set_attr "type" "sdiv")]
4551)
4552
4553(define_insn "udivsi3"
4554  [(set (match_operand:SI	   0 "s_register_operand" "=r,r")
4555	(udiv:SI (match_operand:SI 1 "s_register_operand"  "r,r")
4556		 (match_operand:SI 2 "s_register_operand"  "r,r")))]
4557  "TARGET_IDIV"
4558  "@
4559   udiv%?\t%0, %1, %2
4560   udiv\t%0, %1, %2"
4561  [(set_attr "arch" "32,v8mb")
4562   (set_attr "predicable" "yes")
4563   (set_attr "type" "udiv")]
4564)
4565
4566
4567;; Unary arithmetic insns
4568
4569(define_expand "negvsi3"
4570  [(match_operand:SI 0 "register_operand")
4571   (match_operand:SI 1 "register_operand")
4572   (match_operand 2 "")]
4573  "TARGET_32BIT"
4574{
4575  emit_insn (gen_subsi3_compare (operands[0], const0_rtx, operands[1]));
4576  arm_gen_unlikely_cbranch (NE, CC_Vmode, operands[2]);
4577
4578  DONE;
4579})
4580
4581(define_expand "negvdi3"
4582  [(match_operand:DI 0 "register_operand")
4583   (match_operand:DI 1 "register_operand")
4584   (match_operand 2 "")]
4585  "TARGET_ARM"
4586{
4587  emit_insn (gen_negdi2_compare (operands[0], operands[1]));
4588  arm_gen_unlikely_cbranch (NE, CC_Vmode, operands[2]);
4589
4590  DONE;
4591})
4592
4593
4594(define_insn_and_split "negdi2_compare"
4595  [(set (reg:CC CC_REGNUM)
4596	(compare:CC
4597	  (const_int 0)
4598	  (match_operand:DI 1 "register_operand" "0,r")))
4599   (set (match_operand:DI 0 "register_operand" "=r,&r")
4600	(minus:DI (const_int 0) (match_dup 1)))]
4601  "TARGET_ARM"
4602  "#"
4603  "&& reload_completed"
4604  [(parallel [(set (reg:CC CC_REGNUM)
4605		   (compare:CC (const_int 0) (match_dup 1)))
4606	      (set (match_dup 0) (minus:SI (const_int 0)
4607					   (match_dup 1)))])
4608   (parallel [(set (reg:CC CC_REGNUM)
4609		   (compare:CC (const_int 0) (match_dup 3)))
4610	     (set (match_dup 2)
4611		  (minus:SI
4612		   (minus:SI (const_int 0) (match_dup 3))
4613		   (ltu:SI (reg:CC_C CC_REGNUM)
4614			   (const_int 0))))])]
4615  {
4616    operands[2] = gen_highpart (SImode, operands[0]);
4617    operands[0] = gen_lowpart (SImode, operands[0]);
4618    operands[3] = gen_highpart (SImode, operands[1]);
4619    operands[1] = gen_lowpart (SImode, operands[1]);
4620  }
4621  [(set_attr "conds" "set")
4622   (set_attr "length" "8")
4623   (set_attr "type" "multiple")]
4624)
4625
4626(define_expand "negdi2"
4627 [(parallel
4628   [(set (match_operand:DI 0 "s_register_operand" "")
4629	 (neg:DI (match_operand:DI 1 "s_register_operand" "")))
4630    (clobber (reg:CC CC_REGNUM))])]
4631  "TARGET_EITHER"
4632  {
4633    if (TARGET_NEON)
4634      {
4635        emit_insn (gen_negdi2_neon (operands[0], operands[1]));
4636	DONE;
4637      }
4638  }
4639)
4640
4641;; The constraints here are to prevent a *partial* overlap (where %Q0 == %R1).
4642;; The first alternative allows the common case of a *full* overlap.
4643(define_insn_and_split "*negdi2_insn"
4644  [(set (match_operand:DI         0 "s_register_operand" "=r,&r")
4645	(neg:DI (match_operand:DI 1 "s_register_operand"  "0,r")))
4646   (clobber (reg:CC CC_REGNUM))]
4647  "TARGET_32BIT"
4648  "#"	; rsbs %Q0, %Q1, #0; rsc %R0, %R1, #0	       (ARM)
4649	; negs %Q0, %Q1    ; sbc %R0, %R1, %R1, lsl #1 (Thumb-2)
4650  "&& reload_completed"
4651  [(parallel [(set (reg:CC CC_REGNUM)
4652		   (compare:CC (const_int 0) (match_dup 1)))
4653	      (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1)))])
4654   (set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3))
4655                                (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
4656  {
4657    operands[2] = gen_highpart (SImode, operands[0]);
4658    operands[0] = gen_lowpart (SImode, operands[0]);
4659    operands[3] = gen_highpart (SImode, operands[1]);
4660    operands[1] = gen_lowpart (SImode, operands[1]);
4661  }
4662  [(set_attr "conds" "clob")
4663   (set_attr "length" "8")
4664   (set_attr "type" "multiple")]
4665)
4666
4667(define_insn "*negsi2_carryin_compare"
4668  [(set (reg:CC CC_REGNUM)
4669	(compare:CC (const_int 0)
4670		    (match_operand:SI 1 "s_register_operand" "r")))
4671   (set (match_operand:SI 0 "s_register_operand" "=r")
4672	(minus:SI (minus:SI (const_int 0)
4673			    (match_dup 1))
4674		  (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
4675  "TARGET_ARM"
4676  "rscs\\t%0, %1, #0"
4677  [(set_attr "conds" "set")
4678   (set_attr "type" "alus_imm")]
4679)
4680
4681(define_expand "negsi2"
4682  [(set (match_operand:SI         0 "s_register_operand" "")
4683	(neg:SI (match_operand:SI 1 "s_register_operand" "")))]
4684  "TARGET_EITHER"
4685  ""
4686)
4687
4688(define_insn "*arm_negsi2"
4689  [(set (match_operand:SI         0 "s_register_operand" "=l,r")
4690	(neg:SI (match_operand:SI 1 "s_register_operand" "l,r")))]
4691  "TARGET_32BIT"
4692  "rsb%?\\t%0, %1, #0"
4693  [(set_attr "predicable" "yes")
4694   (set_attr "predicable_short_it" "yes,no")
4695   (set_attr "arch" "t2,*")
4696   (set_attr "length" "4")
4697   (set_attr "type" "alu_sreg")]
4698)
4699
4700(define_expand "negsf2"
4701  [(set (match_operand:SF         0 "s_register_operand" "")
4702	(neg:SF (match_operand:SF 1 "s_register_operand" "")))]
4703  "TARGET_32BIT && TARGET_HARD_FLOAT"
4704  ""
4705)
4706
4707(define_expand "negdf2"
4708  [(set (match_operand:DF         0 "s_register_operand" "")
4709	(neg:DF (match_operand:DF 1 "s_register_operand" "")))]
4710  "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
4711  "")
4712
4713(define_insn_and_split "*zextendsidi_negsi"
4714  [(set (match_operand:DI 0 "s_register_operand" "=r")
4715        (zero_extend:DI (neg:SI (match_operand:SI 1 "s_register_operand" "r"))))]
4716   "TARGET_32BIT"
4717   "#"
4718   ""
4719   [(set (match_dup 2)
4720         (neg:SI (match_dup 1)))
4721    (set (match_dup 3)
4722         (const_int 0))]
4723   {
4724      operands[2] = gen_lowpart (SImode, operands[0]);
4725      operands[3] = gen_highpart (SImode, operands[0]);
4726   }
4727 [(set_attr "length" "8")
4728  (set_attr "type" "multiple")]
4729)
4730
4731;; Negate an extended 32-bit value.
4732(define_insn_and_split "*negdi_extendsidi"
4733  [(set (match_operand:DI 0 "s_register_operand" "=l,r")
4734	(neg:DI (sign_extend:DI
4735		 (match_operand:SI 1 "s_register_operand" "l,r"))))
4736   (clobber (reg:CC CC_REGNUM))]
4737  "TARGET_32BIT"
4738  "#"
4739  "&& reload_completed"
4740  [(const_int 0)]
4741  {
4742    rtx low = gen_lowpart (SImode, operands[0]);
4743    rtx high = gen_highpart (SImode, operands[0]);
4744
4745    if (reg_overlap_mentioned_p (low, operands[1]))
4746      {
4747	/* Input overlaps the low word of the output.  Use:
4748		asr	Rhi, Rin, #31
4749		rsbs	Rlo, Rin, #0
4750		rsc	Rhi, Rhi, #0 (thumb2: sbc Rhi, Rhi, Rhi, lsl #1).  */
4751	rtx cc_reg = gen_rtx_REG (CC_Cmode, CC_REGNUM);
4752
4753	emit_insn (gen_rtx_SET (high,
4754				gen_rtx_ASHIFTRT (SImode, operands[1],
4755						  GEN_INT (31))));
4756
4757	emit_insn (gen_subsi3_compare (low, const0_rtx, operands[1]));
4758	if (TARGET_ARM)
4759	  emit_insn (gen_rtx_SET (high,
4760				  gen_rtx_MINUS (SImode,
4761						 gen_rtx_MINUS (SImode,
4762								const0_rtx,
4763								high),
4764						 gen_rtx_LTU (SImode,
4765							      cc_reg,
4766							      const0_rtx))));
4767	else
4768	  {
4769	    rtx two_x = gen_rtx_ASHIFT (SImode, high, GEN_INT (1));
4770	    emit_insn (gen_rtx_SET (high,
4771				    gen_rtx_MINUS (SImode,
4772						   gen_rtx_MINUS (SImode,
4773								  high,
4774								  two_x),
4775						   gen_rtx_LTU (SImode,
4776								cc_reg,
4777								const0_rtx))));
4778	  }
4779      }
4780    else
4781      {
4782	/* No overlap, or overlap on high word.  Use:
4783		rsb	Rlo, Rin, #0
4784		bic	Rhi, Rlo, Rin
4785		asr	Rhi, Rhi, #31
4786	   Flags not needed for this sequence.  */
4787	emit_insn (gen_rtx_SET (low, gen_rtx_NEG (SImode, operands[1])));
4788	emit_insn (gen_rtx_SET (high,
4789				gen_rtx_AND (SImode,
4790					     gen_rtx_NOT (SImode, operands[1]),
4791					     low)));
4792	emit_insn (gen_rtx_SET (high,
4793				gen_rtx_ASHIFTRT (SImode, high,
4794						  GEN_INT (31))));
4795      }
4796    DONE;
4797  }
4798  [(set_attr "length" "12")
4799   (set_attr "arch" "t2,*")
4800   (set_attr "type" "multiple")]
4801)
4802
4803(define_insn_and_split "*negdi_zero_extendsidi"
4804  [(set (match_operand:DI 0 "s_register_operand" "=r,&r")
4805	(neg:DI (zero_extend:DI (match_operand:SI 1 "s_register_operand" "0,r"))))
4806   (clobber (reg:CC CC_REGNUM))]
4807  "TARGET_32BIT"
4808  "#" ; "rsbs\\t%Q0, %1, #0\;sbc\\t%R0,%R0,%R0"
4809      ;; Don't care what register is input to sbc,
4810      ;; since we just need to propagate the carry.
4811  "&& reload_completed"
4812  [(parallel [(set (reg:CC CC_REGNUM)
4813                   (compare:CC (const_int 0) (match_dup 1)))
4814              (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1)))])
4815   (set (match_dup 2) (minus:SI (minus:SI (match_dup 2) (match_dup 2))
4816                                (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
4817  {
4818    operands[2] = gen_highpart (SImode, operands[0]);
4819    operands[0] = gen_lowpart (SImode, operands[0]);
4820  }
4821  [(set_attr "conds" "clob")
4822   (set_attr "length" "8")
4823   (set_attr "type" "multiple")]   ;; length in thumb is 4
4824)
4825
4826;; abssi2 doesn't really clobber the condition codes if a different register
4827;; is being set.  To keep things simple, assume during rtl manipulations that
4828;; it does, but tell the final scan operator the truth.  Similarly for
4829;; (neg (abs...))
4830
4831(define_expand "abssi2"
4832  [(parallel
4833    [(set (match_operand:SI         0 "s_register_operand" "")
4834	  (abs:SI (match_operand:SI 1 "s_register_operand" "")))
4835     (clobber (match_dup 2))])]
4836  "TARGET_EITHER"
4837  "
4838  if (TARGET_THUMB1)
4839    operands[2] = gen_rtx_SCRATCH (SImode);
4840  else
4841    operands[2] = gen_rtx_REG (CCmode, CC_REGNUM);
4842")
4843
4844(define_insn_and_split "*arm_abssi2"
4845  [(set (match_operand:SI 0 "s_register_operand" "=r,&r")
4846	(abs:SI (match_operand:SI 1 "s_register_operand" "0,r")))
4847   (clobber (reg:CC CC_REGNUM))]
4848  "TARGET_ARM"
4849  "#"
4850  "&& reload_completed"
4851  [(const_int 0)]
4852  {
4853   /* if (which_alternative == 0) */
4854   if (REGNO(operands[0]) == REGNO(operands[1]))
4855     {
4856      /* Emit the pattern:
4857         cmp\\t%0, #0\;rsblt\\t%0, %0, #0
4858         [(set (reg:CC CC_REGNUM)
4859               (compare:CC (match_dup 0) (const_int 0)))
4860          (cond_exec (lt:CC (reg:CC CC_REGNUM) (const_int 0))
4861                     (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1))))]
4862      */
4863      emit_insn (gen_rtx_SET (gen_rtx_REG (CCmode, CC_REGNUM),
4864                              gen_rtx_COMPARE (CCmode, operands[0], const0_rtx)));
4865      emit_insn (gen_rtx_COND_EXEC (VOIDmode,
4866                                    (gen_rtx_LT (SImode,
4867                                                 gen_rtx_REG (CCmode, CC_REGNUM),
4868                                                 const0_rtx)),
4869                                    (gen_rtx_SET (operands[0],
4870                                                  (gen_rtx_MINUS (SImode,
4871                                                                  const0_rtx,
4872                                                                  operands[1]))))));
4873      DONE;
4874     }
4875   else
4876     {
4877      /* Emit the pattern:
4878         alt1: eor%?\\t%0, %1, %1, asr #31\;sub%?\\t%0, %0, %1, asr #31
4879         [(set (match_dup 0)
4880               (xor:SI (match_dup 1)
4881                       (ashiftrt:SI (match_dup 1) (const_int 31))))
4882          (set (match_dup 0)
4883               (minus:SI (match_dup 0)
4884                      (ashiftrt:SI (match_dup 1) (const_int 31))))]
4885      */
4886      emit_insn (gen_rtx_SET (operands[0],
4887                              gen_rtx_XOR (SImode,
4888                                           gen_rtx_ASHIFTRT (SImode,
4889                                                             operands[1],
4890                                                             GEN_INT (31)),
4891                                           operands[1])));
4892      emit_insn (gen_rtx_SET (operands[0],
4893                              gen_rtx_MINUS (SImode,
4894                                             operands[0],
4895                                             gen_rtx_ASHIFTRT (SImode,
4896                                                               operands[1],
4897                                                               GEN_INT (31)))));
4898      DONE;
4899     }
4900  }
4901  [(set_attr "conds" "clob,*")
4902   (set_attr "shift" "1")
4903   (set_attr "predicable" "no, yes")
4904   (set_attr "length" "8")
4905   (set_attr "type" "multiple")]
4906)
4907
4908(define_insn_and_split "*arm_neg_abssi2"
4909  [(set (match_operand:SI 0 "s_register_operand" "=r,&r")
4910	(neg:SI (abs:SI (match_operand:SI 1 "s_register_operand" "0,r"))))
4911   (clobber (reg:CC CC_REGNUM))]
4912  "TARGET_ARM"
4913  "#"
4914  "&& reload_completed"
4915  [(const_int 0)]
4916  {
4917   /* if (which_alternative == 0) */
4918   if (REGNO (operands[0]) == REGNO (operands[1]))
4919     {
4920      /* Emit the pattern:
4921         cmp\\t%0, #0\;rsbgt\\t%0, %0, #0
4922      */
4923      emit_insn (gen_rtx_SET (gen_rtx_REG (CCmode, CC_REGNUM),
4924                              gen_rtx_COMPARE (CCmode, operands[0], const0_rtx)));
4925      emit_insn (gen_rtx_COND_EXEC (VOIDmode,
4926                                    gen_rtx_GT (SImode,
4927                                                gen_rtx_REG (CCmode, CC_REGNUM),
4928                                                const0_rtx),
4929                                    gen_rtx_SET (operands[0],
4930                                                 (gen_rtx_MINUS (SImode,
4931                                                                 const0_rtx,
4932                                                                 operands[1])))));
4933     }
4934   else
4935     {
4936      /* Emit the pattern:
4937         eor%?\\t%0, %1, %1, asr #31\;rsb%?\\t%0, %0, %1, asr #31
4938      */
4939      emit_insn (gen_rtx_SET (operands[0],
4940                              gen_rtx_XOR (SImode,
4941                                           gen_rtx_ASHIFTRT (SImode,
4942                                                             operands[1],
4943                                                             GEN_INT (31)),
4944                                           operands[1])));
4945      emit_insn (gen_rtx_SET (operands[0],
4946                              gen_rtx_MINUS (SImode,
4947                                             gen_rtx_ASHIFTRT (SImode,
4948                                                               operands[1],
4949                                                               GEN_INT (31)),
4950                                             operands[0])));
4951     }
4952   DONE;
4953  }
4954  [(set_attr "conds" "clob,*")
4955   (set_attr "shift" "1")
4956   (set_attr "predicable" "no, yes")
4957   (set_attr "length" "8")
4958   (set_attr "type" "multiple")]
4959)
4960
4961(define_expand "abssf2"
4962  [(set (match_operand:SF         0 "s_register_operand" "")
4963	(abs:SF (match_operand:SF 1 "s_register_operand" "")))]
4964  "TARGET_32BIT && TARGET_HARD_FLOAT"
4965  "")
4966
4967(define_expand "absdf2"
4968  [(set (match_operand:DF         0 "s_register_operand" "")
4969	(abs:DF (match_operand:DF 1 "s_register_operand" "")))]
4970  "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
4971  "")
4972
4973(define_expand "sqrtsf2"
4974  [(set (match_operand:SF 0 "s_register_operand" "")
4975	(sqrt:SF (match_operand:SF 1 "s_register_operand" "")))]
4976  "TARGET_32BIT && TARGET_HARD_FLOAT"
4977  "")
4978
4979(define_expand "sqrtdf2"
4980  [(set (match_operand:DF 0 "s_register_operand" "")
4981	(sqrt:DF (match_operand:DF 1 "s_register_operand" "")))]
4982  "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
4983  "")
4984
4985(define_expand "one_cmpldi2"
4986  [(set (match_operand:DI 0 "s_register_operand" "")
4987	(not:DI (match_operand:DI 1 "s_register_operand" "")))]
4988  "TARGET_32BIT"
4989  "
4990  if (!TARGET_NEON && !TARGET_IWMMXT)
4991    {
4992      rtx low  = simplify_gen_unary (NOT, SImode,
4993				     gen_lowpart (SImode, operands[1]),
4994				     SImode);
4995      rtx high = simplify_gen_unary (NOT, SImode,
4996				     gen_highpart_mode (SImode, DImode,
4997							operands[1]),
4998				     SImode);
4999
5000      emit_insn (gen_rtx_SET (gen_lowpart (SImode, operands[0]), low));
5001      emit_insn (gen_rtx_SET (gen_highpart (SImode, operands[0]), high));
5002
5003      DONE;
5004    }
5005  /* Otherwise expand pattern as above.  */
5006  "
5007)
5008
5009(define_insn_and_split "*one_cmpldi2_insn"
5010  [(set (match_operand:DI 0 "s_register_operand"	 "=w,&r,&r,?w")
5011	(not:DI (match_operand:DI 1 "s_register_operand" " w, 0, r, w")))]
5012  "TARGET_32BIT"
5013  "@
5014   vmvn\t%P0, %P1
5015   #
5016   #
5017   vmvn\t%P0, %P1"
5018  "TARGET_32BIT && reload_completed
5019   && arm_general_register_operand (operands[0], DImode)"
5020  [(set (match_dup 0) (not:SI (match_dup 1)))
5021   (set (match_dup 2) (not:SI (match_dup 3)))]
5022  "
5023  {
5024    operands[2] = gen_highpart (SImode, operands[0]);
5025    operands[0] = gen_lowpart (SImode, operands[0]);
5026    operands[3] = gen_highpart (SImode, operands[1]);
5027    operands[1] = gen_lowpart (SImode, operands[1]);
5028  }"
5029  [(set_attr "length" "*,8,8,*")
5030   (set_attr "predicable" "no,yes,yes,no")
5031   (set_attr "type" "neon_move,multiple,multiple,neon_move")
5032   (set_attr "arch" "neon_for_64bits,*,*,avoid_neon_for_64bits")]
5033)
5034
5035(define_expand "one_cmplsi2"
5036  [(set (match_operand:SI         0 "s_register_operand" "")
5037	(not:SI (match_operand:SI 1 "s_register_operand" "")))]
5038  "TARGET_EITHER"
5039  ""
5040)
5041
5042(define_insn "*arm_one_cmplsi2"
5043  [(set (match_operand:SI         0 "s_register_operand" "=l,r")
5044	(not:SI (match_operand:SI 1 "s_register_operand"  "l,r")))]
5045  "TARGET_32BIT"
5046  "mvn%?\\t%0, %1"
5047  [(set_attr "predicable" "yes")
5048   (set_attr "predicable_short_it" "yes,no")
5049   (set_attr "arch" "t2,*")
5050   (set_attr "length" "4")
5051   (set_attr "type" "mvn_reg")]
5052)
5053
5054(define_insn "*notsi_compare0"
5055  [(set (reg:CC_NOOV CC_REGNUM)
5056	(compare:CC_NOOV (not:SI (match_operand:SI 1 "s_register_operand" "r"))
5057			 (const_int 0)))
5058   (set (match_operand:SI 0 "s_register_operand" "=r")
5059	(not:SI (match_dup 1)))]
5060  "TARGET_32BIT"
5061  "mvns%?\\t%0, %1"
5062  [(set_attr "conds" "set")
5063   (set_attr "type" "mvn_reg")]
5064)
5065
5066(define_insn "*notsi_compare0_scratch"
5067  [(set (reg:CC_NOOV CC_REGNUM)
5068	(compare:CC_NOOV (not:SI (match_operand:SI 1 "s_register_operand" "r"))
5069			 (const_int 0)))
5070   (clobber (match_scratch:SI 0 "=r"))]
5071  "TARGET_32BIT"
5072  "mvns%?\\t%0, %1"
5073  [(set_attr "conds" "set")
5074   (set_attr "type" "mvn_reg")]
5075)
5076
5077;; Fixed <--> Floating conversion insns
5078
5079(define_expand "floatsihf2"
5080  [(set (match_operand:HF           0 "general_operand" "")
5081	(float:HF (match_operand:SI 1 "general_operand" "")))]
5082  "TARGET_EITHER"
5083  "
5084  {
5085    rtx op1 = gen_reg_rtx (SFmode);
5086    expand_float (op1, operands[1], 0);
5087    op1 = convert_to_mode (HFmode, op1, 0);
5088    emit_move_insn (operands[0], op1);
5089    DONE;
5090  }"
5091)
5092
5093(define_expand "floatdihf2"
5094  [(set (match_operand:HF           0 "general_operand" "")
5095	(float:HF (match_operand:DI 1 "general_operand" "")))]
5096  "TARGET_EITHER"
5097  "
5098  {
5099    rtx op1 = gen_reg_rtx (SFmode);
5100    expand_float (op1, operands[1], 0);
5101    op1 = convert_to_mode (HFmode, op1, 0);
5102    emit_move_insn (operands[0], op1);
5103    DONE;
5104  }"
5105)
5106
5107(define_expand "floatsisf2"
5108  [(set (match_operand:SF           0 "s_register_operand" "")
5109	(float:SF (match_operand:SI 1 "s_register_operand" "")))]
5110  "TARGET_32BIT && TARGET_HARD_FLOAT"
5111  "
5112")
5113
5114(define_expand "floatsidf2"
5115  [(set (match_operand:DF           0 "s_register_operand" "")
5116	(float:DF (match_operand:SI 1 "s_register_operand" "")))]
5117  "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
5118  "
5119")
5120
5121(define_expand "fix_trunchfsi2"
5122  [(set (match_operand:SI         0 "general_operand" "")
5123	(fix:SI (fix:HF (match_operand:HF 1 "general_operand"  ""))))]
5124  "TARGET_EITHER"
5125  "
5126  {
5127    rtx op1 = convert_to_mode (SFmode, operands[1], 0);
5128    expand_fix (operands[0], op1, 0);
5129    DONE;
5130  }"
5131)
5132
5133(define_expand "fix_trunchfdi2"
5134  [(set (match_operand:DI         0 "general_operand" "")
5135	(fix:DI (fix:HF (match_operand:HF 1 "general_operand"  ""))))]
5136  "TARGET_EITHER"
5137  "
5138  {
5139    rtx op1 = convert_to_mode (SFmode, operands[1], 0);
5140    expand_fix (operands[0], op1, 0);
5141    DONE;
5142  }"
5143)
5144
5145(define_expand "fix_truncsfsi2"
5146  [(set (match_operand:SI         0 "s_register_operand" "")
5147	(fix:SI (fix:SF (match_operand:SF 1 "s_register_operand"  ""))))]
5148  "TARGET_32BIT && TARGET_HARD_FLOAT"
5149  "
5150")
5151
5152(define_expand "fix_truncdfsi2"
5153  [(set (match_operand:SI         0 "s_register_operand" "")
5154	(fix:SI (fix:DF (match_operand:DF 1 "s_register_operand"  ""))))]
5155  "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
5156  "
5157")
5158
5159;; Truncation insns
5160
5161(define_expand "truncdfsf2"
5162  [(set (match_operand:SF  0 "s_register_operand" "")
5163	(float_truncate:SF
5164 	 (match_operand:DF 1 "s_register_operand" "")))]
5165  "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
5166  ""
5167)
5168
5169;; DFmode to HFmode conversions on targets without a single-step hardware
5170;; instruction for it would have to go through SFmode.  This is dangerous
5171;; as it introduces double rounding.
5172;;
5173;; Disable this pattern unless we are in an unsafe math mode, or we have
5174;; a single-step instruction.
5175
5176(define_expand "truncdfhf2"
5177  [(set (match_operand:HF  0 "s_register_operand" "")
5178	(float_truncate:HF
5179	 (match_operand:DF 1 "s_register_operand" "")))]
5180  "(TARGET_EITHER && flag_unsafe_math_optimizations)
5181   || (TARGET_32BIT && TARGET_FP16_TO_DOUBLE)"
5182{
5183  /* We don't have a direct instruction for this, so we must be in
5184     an unsafe math mode, and going via SFmode.  */
5185
5186  if (!(TARGET_32BIT && TARGET_FP16_TO_DOUBLE))
5187    {
5188      rtx op1;
5189      op1 = convert_to_mode (SFmode, operands[1], 0);
5190      op1 = convert_to_mode (HFmode, op1, 0);
5191      emit_move_insn (operands[0], op1);
5192      DONE;
5193    }
5194  /* Otherwise, we will pick this up as a single instruction with
5195     no intermediary rounding.  */
5196}
5197)
5198
5199;; Zero and sign extension instructions.
5200
5201(define_insn "zero_extend<mode>di2"
5202  [(set (match_operand:DI 0 "s_register_operand" "=w,r,?r,w")
5203        (zero_extend:DI (match_operand:QHSI 1 "<qhs_zextenddi_op>"
5204					    "<qhs_zextenddi_cstr>")))]
5205  "TARGET_32BIT <qhs_zextenddi_cond>"
5206  "#"
5207  [(set_attr "length" "8,4,8,8")
5208   (set_attr "arch" "neon_for_64bits,*,*,avoid_neon_for_64bits")
5209   (set_attr "ce_count" "2")
5210   (set_attr "predicable" "yes")
5211   (set_attr "type" "multiple,mov_reg,multiple,multiple")]
5212)
5213
5214(define_insn "extend<mode>di2"
5215  [(set (match_operand:DI 0 "s_register_operand" "=w,r,?r,?r,w")
5216        (sign_extend:DI (match_operand:QHSI 1 "<qhs_extenddi_op>"
5217					    "<qhs_extenddi_cstr>")))]
5218  "TARGET_32BIT <qhs_sextenddi_cond>"
5219  "#"
5220  [(set_attr "length" "8,4,8,8,8")
5221   (set_attr "ce_count" "2")
5222   (set_attr "shift" "1")
5223   (set_attr "predicable" "yes")
5224   (set_attr "arch" "neon_for_64bits,*,a,t,avoid_neon_for_64bits")
5225   (set_attr "type" "multiple,mov_reg,multiple,multiple,multiple")]
5226)
5227
5228;; Splits for all extensions to DImode
5229(define_split
5230  [(set (match_operand:DI 0 "s_register_operand" "")
5231        (zero_extend:DI (match_operand 1 "nonimmediate_operand" "")))]
5232  "TARGET_32BIT && reload_completed && !IS_VFP_REGNUM (REGNO (operands[0]))"
5233  [(set (match_dup 0) (match_dup 1))]
5234{
5235  rtx lo_part = gen_lowpart (SImode, operands[0]);
5236  machine_mode src_mode = GET_MODE (operands[1]);
5237
5238  if (REG_P (operands[0])
5239      && !reg_overlap_mentioned_p (operands[0], operands[1]))
5240    emit_clobber (operands[0]);
5241  if (!REG_P (lo_part) || src_mode != SImode
5242      || !rtx_equal_p (lo_part, operands[1]))
5243    {
5244      if (src_mode == SImode)
5245        emit_move_insn (lo_part, operands[1]);
5246      else
5247        emit_insn (gen_rtx_SET (lo_part,
5248				gen_rtx_ZERO_EXTEND (SImode, operands[1])));
5249      operands[1] = lo_part;
5250    }
5251  operands[0] = gen_highpart (SImode, operands[0]);
5252  operands[1] = const0_rtx;
5253})
5254
5255(define_split
5256  [(set (match_operand:DI 0 "s_register_operand" "")
5257        (sign_extend:DI (match_operand 1 "nonimmediate_operand" "")))]
5258  "TARGET_32BIT && reload_completed && !IS_VFP_REGNUM (REGNO (operands[0]))"
5259  [(set (match_dup 0) (ashiftrt:SI (match_dup 1) (const_int 31)))]
5260{
5261  rtx lo_part = gen_lowpart (SImode, operands[0]);
5262  machine_mode src_mode = GET_MODE (operands[1]);
5263
5264  if (REG_P (operands[0])
5265      && !reg_overlap_mentioned_p (operands[0], operands[1]))
5266    emit_clobber (operands[0]);
5267
5268  if (!REG_P (lo_part) || src_mode != SImode
5269      || !rtx_equal_p (lo_part, operands[1]))
5270    {
5271      if (src_mode == SImode)
5272        emit_move_insn (lo_part, operands[1]);
5273      else
5274        emit_insn (gen_rtx_SET (lo_part,
5275				gen_rtx_SIGN_EXTEND (SImode, operands[1])));
5276      operands[1] = lo_part;
5277    }
5278  operands[0] = gen_highpart (SImode, operands[0]);
5279})
5280
5281(define_expand "zero_extendhisi2"
5282  [(set (match_operand:SI 0 "s_register_operand" "")
5283	(zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
5284  "TARGET_EITHER"
5285{
5286  if (TARGET_ARM && !arm_arch4 && MEM_P (operands[1]))
5287    {
5288      emit_insn (gen_movhi_bytes (operands[0], operands[1]));
5289      DONE;
5290    }
5291  if (!arm_arch6 && !MEM_P (operands[1]))
5292    {
5293      rtx t = gen_lowpart (SImode, operands[1]);
5294      rtx tmp = gen_reg_rtx (SImode);
5295      emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (16)));
5296      emit_insn (gen_lshrsi3 (operands[0], tmp, GEN_INT (16)));
5297      DONE;
5298    }
5299})
5300
5301(define_split
5302  [(set (match_operand:SI 0 "s_register_operand" "")
5303	(zero_extend:SI (match_operand:HI 1 "s_register_operand" "")))]
5304  "!TARGET_THUMB2 && !arm_arch6"
5305  [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
5306   (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 16)))]
5307{
5308  operands[2] = gen_lowpart (SImode, operands[1]);
5309})
5310
5311(define_insn "*arm_zero_extendhisi2"
5312  [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5313	(zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
5314  "TARGET_ARM && arm_arch4 && !arm_arch6"
5315  "@
5316   #
5317   ldrh%?\\t%0, %1"
5318  [(set_attr "type" "alu_shift_reg,load_byte")
5319   (set_attr "predicable" "yes")]
5320)
5321
5322(define_insn "*arm_zero_extendhisi2_v6"
5323  [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5324	(zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,Uh")))]
5325  "TARGET_ARM && arm_arch6"
5326  "@
5327   uxth%?\\t%0, %1
5328   ldrh%?\\t%0, %1"
5329  [(set_attr "predicable" "yes")
5330   (set_attr "type" "extend,load_byte")]
5331)
5332
5333(define_insn "*arm_zero_extendhisi2addsi"
5334  [(set (match_operand:SI 0 "s_register_operand" "=r")
5335	(plus:SI (zero_extend:SI (match_operand:HI 1 "s_register_operand" "r"))
5336		 (match_operand:SI 2 "s_register_operand" "r")))]
5337  "TARGET_INT_SIMD"
5338  "uxtah%?\\t%0, %2, %1"
5339  [(set_attr "type" "alu_shift_reg")
5340   (set_attr "predicable" "yes")]
5341)
5342
5343(define_expand "zero_extendqisi2"
5344  [(set (match_operand:SI 0 "s_register_operand" "")
5345	(zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))]
5346  "TARGET_EITHER"
5347{
5348  if (TARGET_ARM && !arm_arch6 && !MEM_P (operands[1]))
5349    {
5350      emit_insn (gen_andsi3 (operands[0],
5351			     gen_lowpart (SImode, operands[1]),
5352					  GEN_INT (255)));
5353      DONE;
5354    }
5355  if (!arm_arch6 && !MEM_P (operands[1]))
5356    {
5357      rtx t = gen_lowpart (SImode, operands[1]);
5358      rtx tmp = gen_reg_rtx (SImode);
5359      emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (24)));
5360      emit_insn (gen_lshrsi3 (operands[0], tmp, GEN_INT (24)));
5361      DONE;
5362    }
5363})
5364
5365(define_split
5366  [(set (match_operand:SI 0 "s_register_operand" "")
5367	(zero_extend:SI (match_operand:QI 1 "s_register_operand" "")))]
5368  "!arm_arch6"
5369  [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 24)))
5370   (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 24)))]
5371{
5372  operands[2] = simplify_gen_subreg (SImode, operands[1], QImode, 0);
5373  if (TARGET_ARM)
5374    {
5375      emit_insn (gen_andsi3 (operands[0], operands[2], GEN_INT (255)));
5376      DONE;
5377    }
5378})
5379
5380(define_insn "*arm_zero_extendqisi2"
5381  [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5382	(zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
5383  "TARGET_ARM && !arm_arch6"
5384  "@
5385   #
5386   ldrb%?\\t%0, %1\\t%@ zero_extendqisi2"
5387  [(set_attr "length" "8,4")
5388   (set_attr "type" "alu_shift_reg,load_byte")
5389   (set_attr "predicable" "yes")]
5390)
5391
5392(define_insn "*arm_zero_extendqisi2_v6"
5393  [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5394	(zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,Uh")))]
5395  "TARGET_ARM && arm_arch6"
5396  "@
5397   uxtb%?\\t%0, %1
5398   ldrb%?\\t%0, %1\\t%@ zero_extendqisi2"
5399  [(set_attr "type" "extend,load_byte")
5400   (set_attr "predicable" "yes")]
5401)
5402
5403(define_insn "*arm_zero_extendqisi2addsi"
5404  [(set (match_operand:SI 0 "s_register_operand" "=r")
5405	(plus:SI (zero_extend:SI (match_operand:QI 1 "s_register_operand" "r"))
5406		 (match_operand:SI 2 "s_register_operand" "r")))]
5407  "TARGET_INT_SIMD"
5408  "uxtab%?\\t%0, %2, %1"
5409  [(set_attr "predicable" "yes")
5410   (set_attr "type" "alu_shift_reg")]
5411)
5412
5413(define_split
5414  [(set (match_operand:SI 0 "s_register_operand" "")
5415	(zero_extend:SI (subreg:QI (match_operand:SI 1 "" "") 0)))
5416   (clobber (match_operand:SI 2 "s_register_operand" ""))]
5417  "TARGET_32BIT && (!MEM_P (operands[1])) && ! BYTES_BIG_ENDIAN"
5418  [(set (match_dup 2) (match_dup 1))
5419   (set (match_dup 0) (and:SI (match_dup 2) (const_int 255)))]
5420  ""
5421)
5422
5423(define_split
5424  [(set (match_operand:SI 0 "s_register_operand" "")
5425	(zero_extend:SI (subreg:QI (match_operand:SI 1 "" "") 3)))
5426   (clobber (match_operand:SI 2 "s_register_operand" ""))]
5427  "TARGET_32BIT && (!MEM_P (operands[1])) && BYTES_BIG_ENDIAN"
5428  [(set (match_dup 2) (match_dup 1))
5429   (set (match_dup 0) (and:SI (match_dup 2) (const_int 255)))]
5430  ""
5431)
5432
5433
5434(define_split
5435  [(set (match_operand:SI 0 "s_register_operand" "")
5436	(IOR_XOR:SI (and:SI (ashift:SI
5437			     (match_operand:SI 1 "s_register_operand" "")
5438			     (match_operand:SI 2 "const_int_operand" ""))
5439			    (match_operand:SI 3 "const_int_operand" ""))
5440		    (zero_extend:SI
5441		     (match_operator 5 "subreg_lowpart_operator"
5442		      [(match_operand:SI 4 "s_register_operand" "")]))))]
5443  "TARGET_32BIT
5444   && (UINTVAL (operands[3])
5445       == (GET_MODE_MASK (GET_MODE (operands[5]))
5446           & (GET_MODE_MASK (GET_MODE (operands[5]))
5447	      << (INTVAL (operands[2])))))"
5448  [(set (match_dup 0) (IOR_XOR:SI (ashift:SI (match_dup 1) (match_dup 2))
5449				  (match_dup 4)))
5450   (set (match_dup 0) (zero_extend:SI (match_dup 5)))]
5451  "operands[5] = gen_lowpart (GET_MODE (operands[5]), operands[0]);"
5452)
5453
5454(define_insn "*compareqi_eq0"
5455  [(set (reg:CC_Z CC_REGNUM)
5456	(compare:CC_Z (match_operand:QI 0 "s_register_operand" "r")
5457			 (const_int 0)))]
5458  "TARGET_32BIT"
5459  "tst%?\\t%0, #255"
5460  [(set_attr "conds" "set")
5461   (set_attr "predicable" "yes")
5462   (set_attr "type" "logic_imm")]
5463)
5464
5465(define_expand "extendhisi2"
5466  [(set (match_operand:SI 0 "s_register_operand" "")
5467	(sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
5468  "TARGET_EITHER"
5469{
5470  if (TARGET_THUMB1)
5471    {
5472      emit_insn (gen_thumb1_extendhisi2 (operands[0], operands[1]));
5473      DONE;
5474    }
5475  if (MEM_P (operands[1]) && TARGET_ARM && !arm_arch4)
5476    {
5477      emit_insn (gen_extendhisi2_mem (operands[0], operands[1]));
5478      DONE;
5479    }
5480
5481  if (!arm_arch6 && !MEM_P (operands[1]))
5482    {
5483      rtx t = gen_lowpart (SImode, operands[1]);
5484      rtx tmp = gen_reg_rtx (SImode);
5485      emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (16)));
5486      emit_insn (gen_ashrsi3 (operands[0], tmp, GEN_INT (16)));
5487      DONE;
5488    }
5489})
5490
5491(define_split
5492  [(parallel
5493    [(set (match_operand:SI 0 "register_operand" "")
5494	  (sign_extend:SI (match_operand:HI 1 "register_operand" "")))
5495     (clobber (match_scratch:SI 2 ""))])]
5496  "!arm_arch6"
5497  [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
5498   (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
5499{
5500  operands[2] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
5501})
5502
5503;; This pattern will only be used when ldsh is not available
5504(define_expand "extendhisi2_mem"
5505  [(set (match_dup 2) (zero_extend:SI (match_operand:HI 1 "" "")))
5506   (set (match_dup 3)
5507	(zero_extend:SI (match_dup 7)))
5508   (set (match_dup 6) (ashift:SI (match_dup 4) (const_int 24)))
5509   (set (match_operand:SI 0 "" "")
5510	(ior:SI (ashiftrt:SI (match_dup 6) (const_int 16)) (match_dup 5)))]
5511  "TARGET_ARM"
5512  "
5513  {
5514    rtx mem1, mem2;
5515    rtx addr = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
5516
5517    mem1 = change_address (operands[1], QImode, addr);
5518    mem2 = change_address (operands[1], QImode,
5519			   plus_constant (Pmode, addr, 1));
5520    operands[0] = gen_lowpart (SImode, operands[0]);
5521    operands[1] = mem1;
5522    operands[2] = gen_reg_rtx (SImode);
5523    operands[3] = gen_reg_rtx (SImode);
5524    operands[6] = gen_reg_rtx (SImode);
5525    operands[7] = mem2;
5526
5527    if (BYTES_BIG_ENDIAN)
5528      {
5529	operands[4] = operands[2];
5530	operands[5] = operands[3];
5531      }
5532    else
5533      {
5534	operands[4] = operands[3];
5535	operands[5] = operands[2];
5536      }
5537  }"
5538)
5539
5540(define_split
5541  [(set (match_operand:SI 0 "register_operand" "")
5542	(sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
5543  "!arm_arch6"
5544  [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
5545   (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
5546{
5547  operands[2] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
5548})
5549
5550(define_insn "*arm_extendhisi2"
5551  [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5552	(sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,Uh")))]
5553  "TARGET_ARM && arm_arch4 && !arm_arch6"
5554  "@
5555   #
5556   ldrsh%?\\t%0, %1"
5557  [(set_attr "length" "8,4")
5558   (set_attr "type" "alu_shift_reg,load_byte")
5559   (set_attr "predicable" "yes")]
5560)
5561
5562;; ??? Check Thumb-2 pool range
5563(define_insn "*arm_extendhisi2_v6"
5564  [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5565	(sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,Uh")))]
5566  "TARGET_32BIT && arm_arch6"
5567  "@
5568   sxth%?\\t%0, %1
5569   ldrsh%?\\t%0, %1"
5570  [(set_attr "type" "extend,load_byte")
5571   (set_attr "predicable" "yes")]
5572)
5573
5574(define_insn "*arm_extendhisi2addsi"
5575  [(set (match_operand:SI 0 "s_register_operand" "=r")
5576	(plus:SI (sign_extend:SI (match_operand:HI 1 "s_register_operand" "r"))
5577		 (match_operand:SI 2 "s_register_operand" "r")))]
5578  "TARGET_INT_SIMD"
5579  "sxtah%?\\t%0, %2, %1"
5580  [(set_attr "type" "alu_shift_reg")]
5581)
5582
5583(define_expand "extendqihi2"
5584  [(set (match_dup 2)
5585	(ashift:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "")
5586		   (const_int 24)))
5587   (set (match_operand:HI 0 "s_register_operand" "")
5588	(ashiftrt:SI (match_dup 2)
5589		     (const_int 24)))]
5590  "TARGET_ARM"
5591  "
5592  {
5593    if (arm_arch4 && MEM_P (operands[1]))
5594      {
5595	emit_insn (gen_rtx_SET (operands[0],
5596				gen_rtx_SIGN_EXTEND (HImode, operands[1])));
5597	DONE;
5598      }
5599    if (!s_register_operand (operands[1], QImode))
5600      operands[1] = copy_to_mode_reg (QImode, operands[1]);
5601    operands[0] = gen_lowpart (SImode, operands[0]);
5602    operands[1] = gen_lowpart (SImode, operands[1]);
5603    operands[2] = gen_reg_rtx (SImode);
5604  }"
5605)
5606
5607(define_insn "*arm_extendqihi_insn"
5608  [(set (match_operand:HI 0 "s_register_operand" "=r")
5609	(sign_extend:HI (match_operand:QI 1 "arm_extendqisi_mem_op" "Uq")))]
5610  "TARGET_ARM && arm_arch4"
5611  "ldrsb%?\\t%0, %1"
5612  [(set_attr "type" "load_byte")
5613   (set_attr "predicable" "yes")]
5614)
5615
5616(define_expand "extendqisi2"
5617  [(set (match_operand:SI 0 "s_register_operand" "")
5618	(sign_extend:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "")))]
5619  "TARGET_EITHER"
5620{
5621  if (!arm_arch4 && MEM_P (operands[1]))
5622    operands[1] = copy_to_mode_reg (QImode, operands[1]);
5623
5624  if (!arm_arch6 && !MEM_P (operands[1]))
5625    {
5626      rtx t = gen_lowpart (SImode, operands[1]);
5627      rtx tmp = gen_reg_rtx (SImode);
5628      emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (24)));
5629      emit_insn (gen_ashrsi3 (operands[0], tmp, GEN_INT (24)));
5630      DONE;
5631    }
5632})
5633
5634(define_split
5635  [(set (match_operand:SI 0 "register_operand" "")
5636	(sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
5637  "!arm_arch6"
5638  [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 24)))
5639   (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 24)))]
5640{
5641  operands[2] = simplify_gen_subreg (SImode, operands[1], QImode, 0);
5642})
5643
5644(define_insn "*arm_extendqisi"
5645  [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5646	(sign_extend:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "r,Uq")))]
5647  "TARGET_ARM && arm_arch4 && !arm_arch6"
5648  "@
5649   #
5650   ldrsb%?\\t%0, %1"
5651  [(set_attr "length" "8,4")
5652   (set_attr "type" "alu_shift_reg,load_byte")
5653   (set_attr "predicable" "yes")]
5654)
5655
5656(define_insn "*arm_extendqisi_v6"
5657  [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5658	(sign_extend:SI
5659	 (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "r,Uq")))]
5660  "TARGET_ARM && arm_arch6"
5661  "@
5662   sxtb%?\\t%0, %1
5663   ldrsb%?\\t%0, %1"
5664  [(set_attr "type" "extend,load_byte")
5665   (set_attr "predicable" "yes")]
5666)
5667
5668(define_insn "*arm_extendqisi2addsi"
5669  [(set (match_operand:SI 0 "s_register_operand" "=r")
5670	(plus:SI (sign_extend:SI (match_operand:QI 1 "s_register_operand" "r"))
5671		 (match_operand:SI 2 "s_register_operand" "r")))]
5672  "TARGET_INT_SIMD"
5673  "sxtab%?\\t%0, %2, %1"
5674  [(set_attr "type" "alu_shift_reg")
5675   (set_attr "predicable" "yes")]
5676)
5677
5678(define_expand "extendsfdf2"
5679  [(set (match_operand:DF                  0 "s_register_operand" "")
5680	(float_extend:DF (match_operand:SF 1 "s_register_operand"  "")))]
5681  "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
5682  ""
5683)
5684
5685;; HFmode -> DFmode conversions where we don't have an instruction for it
5686;; must go through SFmode.
5687;;
5688;; This is always safe for an extend.
5689
5690(define_expand "extendhfdf2"
5691  [(set (match_operand:DF		   0 "s_register_operand" "")
5692	(float_extend:DF (match_operand:HF 1 "s_register_operand" "")))]
5693  "TARGET_EITHER"
5694{
5695  /* We don't have a direct instruction for this, so go via SFmode.  */
5696  if (!(TARGET_32BIT && TARGET_FP16_TO_DOUBLE))
5697    {
5698      rtx op1;
5699      op1 = convert_to_mode (SFmode, operands[1], 0);
5700      op1 = convert_to_mode (DFmode, op1, 0);
5701      emit_insn (gen_movdf (operands[0], op1));
5702      DONE;
5703    }
5704  /* Otherwise, we're done producing RTL and will pick up the correct
5705     pattern to do this with one rounding-step in a single instruction.  */
5706}
5707)
5708
5709;; Move insns (including loads and stores)
5710
5711;; XXX Just some ideas about movti.
5712;; I don't think these are a good idea on the arm, there just aren't enough
5713;; registers
5714;;(define_expand "loadti"
5715;;  [(set (match_operand:TI 0 "s_register_operand" "")
5716;;	(mem:TI (match_operand:SI 1 "address_operand" "")))]
5717;;  "" "")
5718
5719;;(define_expand "storeti"
5720;;  [(set (mem:TI (match_operand:TI 0 "address_operand" ""))
5721;;	(match_operand:TI 1 "s_register_operand" ""))]
5722;;  "" "")
5723
5724;;(define_expand "movti"
5725;;  [(set (match_operand:TI 0 "general_operand" "")
5726;;	(match_operand:TI 1 "general_operand" ""))]
5727;;  ""
5728;;  "
5729;;{
5730;;  rtx insn;
5731;;
5732;;  if (MEM_P (operands[0]) && MEM_P (operands[1]))
5733;;    operands[1] = copy_to_reg (operands[1]);
5734;;  if (MEM_P (operands[0]))
5735;;    insn = gen_storeti (XEXP (operands[0], 0), operands[1]);
5736;;  else if (MEM_P (operands[1]))
5737;;    insn = gen_loadti (operands[0], XEXP (operands[1], 0));
5738;;  else
5739;;    FAIL;
5740;;
5741;;  emit_insn (insn);
5742;;  DONE;
5743;;}")
5744
5745;; Recognize garbage generated above.
5746
5747;;(define_insn ""
5748;;  [(set (match_operand:TI 0 "general_operand" "=r,r,r,<,>,m")
5749;;	(match_operand:TI 1 "general_operand" "<,>,m,r,r,r"))]
5750;;  ""
5751;;  "*
5752;;  {
5753;;    register mem = (which_alternative < 3);
5754;;    register const char *template;
5755;;
5756;;    operands[mem] = XEXP (operands[mem], 0);
5757;;    switch (which_alternative)
5758;;      {
5759;;      case 0: template = \"ldmdb\\t%1!, %M0\"; break;
5760;;      case 1: template = \"ldmia\\t%1!, %M0\"; break;
5761;;      case 2: template = \"ldmia\\t%1, %M0\"; break;
5762;;      case 3: template = \"stmdb\\t%0!, %M1\"; break;
5763;;      case 4: template = \"stmia\\t%0!, %M1\"; break;
5764;;      case 5: template = \"stmia\\t%0, %M1\"; break;
5765;;      }
5766;;    output_asm_insn (template, operands);
5767;;    return \"\";
5768;;  }")
5769
5770(define_expand "movdi"
5771  [(set (match_operand:DI 0 "general_operand" "")
5772	(match_operand:DI 1 "general_operand" ""))]
5773  "TARGET_EITHER"
5774  "
5775  if (can_create_pseudo_p ())
5776    {
5777      if (!REG_P (operands[0]))
5778	operands[1] = force_reg (DImode, operands[1]);
5779    }
5780  if (REG_P (operands[0]) && REGNO (operands[0]) <= LAST_ARM_REGNUM
5781      && !targetm.hard_regno_mode_ok (REGNO (operands[0]), DImode))
5782    {
5783      /* Avoid LDRD's into an odd-numbered register pair in ARM state
5784	 when expanding function calls.  */
5785      gcc_assert (can_create_pseudo_p ());
5786      if (MEM_P (operands[1]) && MEM_VOLATILE_P (operands[1]))
5787	{
5788	  /* Perform load into legal reg pair first, then move.  */
5789	  rtx reg = gen_reg_rtx (DImode);
5790	  emit_insn (gen_movdi (reg, operands[1]));
5791	  operands[1] = reg;
5792	}
5793      emit_move_insn (gen_lowpart (SImode, operands[0]),
5794		      gen_lowpart (SImode, operands[1]));
5795      emit_move_insn (gen_highpart (SImode, operands[0]),
5796		      gen_highpart (SImode, operands[1]));
5797      DONE;
5798    }
5799  else if (REG_P (operands[1]) && REGNO (operands[1]) <= LAST_ARM_REGNUM
5800	   && !targetm.hard_regno_mode_ok (REGNO (operands[1]), DImode))
5801    {
5802      /* Avoid STRD's from an odd-numbered register pair in ARM state
5803	 when expanding function prologue.  */
5804      gcc_assert (can_create_pseudo_p ());
5805      rtx split_dest = (MEM_P (operands[0]) && MEM_VOLATILE_P (operands[0]))
5806		       ? gen_reg_rtx (DImode)
5807		       : operands[0];
5808      emit_move_insn (gen_lowpart (SImode, split_dest),
5809		      gen_lowpart (SImode, operands[1]));
5810      emit_move_insn (gen_highpart (SImode, split_dest),
5811		      gen_highpart (SImode, operands[1]));
5812      if (split_dest != operands[0])
5813	emit_insn (gen_movdi (operands[0], split_dest));
5814      DONE;
5815    }
5816  "
5817)
5818
5819(define_insn "*arm_movdi"
5820  [(set (match_operand:DI 0 "nonimmediate_di_operand" "=r, r, r, q, m")
5821	(match_operand:DI 1 "di_operand"              "rDa,Db,Dc,mi,q"))]
5822  "TARGET_32BIT
5823   && !(TARGET_HARD_FLOAT)
5824   && !TARGET_IWMMXT
5825   && (   register_operand (operands[0], DImode)
5826       || register_operand (operands[1], DImode))"
5827  "*
5828  switch (which_alternative)
5829    {
5830    case 0:
5831    case 1:
5832    case 2:
5833      return \"#\";
5834    default:
5835      return output_move_double (operands, true, NULL);
5836    }
5837  "
5838  [(set_attr "length" "8,12,16,8,8")
5839   (set_attr "type" "multiple,multiple,multiple,load_8,store_8")
5840   (set_attr "arm_pool_range" "*,*,*,1020,*")
5841   (set_attr "arm_neg_pool_range" "*,*,*,1004,*")
5842   (set_attr "thumb2_pool_range" "*,*,*,4094,*")
5843   (set_attr "thumb2_neg_pool_range" "*,*,*,0,*")]
5844)
5845
5846(define_split
5847  [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
5848	(match_operand:ANY64 1 "immediate_operand" ""))]
5849  "TARGET_32BIT
5850   && reload_completed
5851   && (arm_disable_literal_pool
5852       || (arm_const_double_inline_cost (operands[1])
5853	   <= arm_max_const_double_inline_cost ()))"
5854  [(const_int 0)]
5855  "
5856  arm_split_constant (SET, SImode, curr_insn,
5857		      INTVAL (gen_lowpart (SImode, operands[1])),
5858		      gen_lowpart (SImode, operands[0]), NULL_RTX, 0);
5859  arm_split_constant (SET, SImode, curr_insn,
5860		      INTVAL (gen_highpart_mode (SImode,
5861						 GET_MODE (operands[0]),
5862						 operands[1])),
5863		      gen_highpart (SImode, operands[0]), NULL_RTX, 0);
5864  DONE;
5865  "
5866)
5867
5868; If optimizing for size, or if we have load delay slots, then
5869; we want to split the constant into two separate operations.
5870; In both cases this may split a trivial part into a single data op
5871; leaving a single complex constant to load.  We can also get longer
5872; offsets in a LDR which means we get better chances of sharing the pool
5873; entries.  Finally, we can normally do a better job of scheduling
5874; LDR instructions than we can with LDM.
5875; This pattern will only match if the one above did not.
5876(define_split
5877  [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
5878	(match_operand:ANY64 1 "const_double_operand" ""))]
5879  "TARGET_ARM && reload_completed
5880   && arm_const_double_by_parts (operands[1])"
5881  [(set (match_dup 0) (match_dup 1))
5882   (set (match_dup 2) (match_dup 3))]
5883  "
5884  operands[2] = gen_highpart (SImode, operands[0]);
5885  operands[3] = gen_highpart_mode (SImode, GET_MODE (operands[0]),
5886				   operands[1]);
5887  operands[0] = gen_lowpart (SImode, operands[0]);
5888  operands[1] = gen_lowpart (SImode, operands[1]);
5889  "
5890)
5891
5892(define_split
5893  [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
5894	(match_operand:ANY64 1 "arm_general_register_operand" ""))]
5895  "TARGET_EITHER && reload_completed"
5896  [(set (match_dup 0) (match_dup 1))
5897   (set (match_dup 2) (match_dup 3))]
5898  "
5899  operands[2] = gen_highpart (SImode, operands[0]);
5900  operands[3] = gen_highpart (SImode, operands[1]);
5901  operands[0] = gen_lowpart (SImode, operands[0]);
5902  operands[1] = gen_lowpart (SImode, operands[1]);
5903
5904  /* Handle a partial overlap.  */
5905  if (rtx_equal_p (operands[0], operands[3]))
5906    {
5907      rtx tmp0 = operands[0];
5908      rtx tmp1 = operands[1];
5909
5910      operands[0] = operands[2];
5911      operands[1] = operands[3];
5912      operands[2] = tmp0;
5913      operands[3] = tmp1;
5914    }
5915  "
5916)
5917
5918;; We can't actually do base+index doubleword loads if the index and
5919;; destination overlap.  Split here so that we at least have chance to
5920;; schedule.
5921(define_split
5922  [(set (match_operand:DI 0 "s_register_operand" "")
5923	(mem:DI (plus:SI (match_operand:SI 1 "s_register_operand" "")
5924			 (match_operand:SI 2 "s_register_operand" ""))))]
5925  "TARGET_LDRD
5926  && reg_overlap_mentioned_p (operands[0], operands[1])
5927  && reg_overlap_mentioned_p (operands[0], operands[2])"
5928  [(set (match_dup 4)
5929	(plus:SI (match_dup 1)
5930		 (match_dup 2)))
5931   (set (match_dup 0)
5932	(mem:DI (match_dup 4)))]
5933  "
5934  operands[4] = gen_rtx_REG (SImode, REGNO(operands[0]));
5935  "
5936)
5937
5938(define_expand "movsi"
5939  [(set (match_operand:SI 0 "general_operand" "")
5940        (match_operand:SI 1 "general_operand" ""))]
5941  "TARGET_EITHER"
5942  "
5943  {
5944  rtx base, offset, tmp;
5945
5946  if (TARGET_32BIT || TARGET_HAVE_MOVT)
5947    {
5948      /* Everything except mem = const or mem = mem can be done easily.  */
5949      if (MEM_P (operands[0]))
5950        operands[1] = force_reg (SImode, operands[1]);
5951      if (arm_general_register_operand (operands[0], SImode)
5952	  && CONST_INT_P (operands[1])
5953          && !(const_ok_for_arm (INTVAL (operands[1]))
5954               || const_ok_for_arm (~INTVAL (operands[1]))))
5955        {
5956	   if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[1]), SET))
5957	     {
5958		emit_insn (gen_rtx_SET (operands[0], operands[1]));
5959		DONE;
5960	     }
5961	  else
5962	     {
5963		arm_split_constant (SET, SImode, NULL_RTX,
5964	                            INTVAL (operands[1]), operands[0], NULL_RTX,
5965			            optimize && can_create_pseudo_p ());
5966		DONE;
5967	     }
5968        }
5969    }
5970  else /* Target doesn't have MOVT...  */
5971    {
5972      if (can_create_pseudo_p ())
5973        {
5974          if (!REG_P (operands[0]))
5975	    operands[1] = force_reg (SImode, operands[1]);
5976        }
5977    }
5978
5979  if (ARM_OFFSETS_MUST_BE_WITHIN_SECTIONS_P)
5980    {
5981      split_const (operands[1], &base, &offset);
5982      if (GET_CODE (base) == SYMBOL_REF
5983	  && !offset_within_block_p (base, INTVAL (offset)))
5984	{
5985	  tmp = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];
5986	  emit_move_insn (tmp, base);
5987	  emit_insn (gen_addsi3 (operands[0], tmp, offset));
5988	  DONE;
5989	}
5990    }
5991
5992  /* Recognize the case where operand[1] is a reference to thread-local
5993     data and load its address to a register.  */
5994  if (arm_tls_referenced_p (operands[1]))
5995    {
5996      rtx tmp = operands[1];
5997      rtx addend = NULL;
5998
5999      if (GET_CODE (tmp) == CONST && GET_CODE (XEXP (tmp, 0)) == PLUS)
6000        {
6001          addend = XEXP (XEXP (tmp, 0), 1);
6002          tmp = XEXP (XEXP (tmp, 0), 0);
6003        }
6004
6005      gcc_assert (GET_CODE (tmp) == SYMBOL_REF);
6006      gcc_assert (SYMBOL_REF_TLS_MODEL (tmp) != 0);
6007
6008      tmp = legitimize_tls_address (tmp,
6009				    !can_create_pseudo_p () ? operands[0] : 0);
6010      if (addend)
6011        {
6012          tmp = gen_rtx_PLUS (SImode, tmp, addend);
6013          tmp = force_operand (tmp, operands[0]);
6014        }
6015      operands[1] = tmp;
6016    }
6017  else if (flag_pic
6018	   && (CONSTANT_P (operands[1])
6019	       || symbol_mentioned_p (operands[1])
6020	       || label_mentioned_p (operands[1])))
6021      operands[1] = legitimize_pic_address (operands[1], SImode,
6022					    (!can_create_pseudo_p ()
6023					     ? operands[0]
6024					     : 0));
6025  }
6026  "
6027)
6028
6029;; The ARM LO_SUM and HIGH are backwards - HIGH sets the low bits, and
6030;; LO_SUM adds in the high bits.  Fortunately these are opaque operations
6031;; so this does not matter.
6032(define_insn "*arm_movt"
6033  [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r")
6034	(lo_sum:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6035		   (match_operand:SI 2 "general_operand"      "i,i")))]
6036  "TARGET_HAVE_MOVT && arm_valid_symbolic_address_p (operands[2])"
6037  "@
6038   movt%?\t%0, #:upper16:%c2
6039   movt\t%0, #:upper16:%c2"
6040  [(set_attr "arch"  "32,v8mb")
6041   (set_attr "predicable" "yes")
6042   (set_attr "length" "4")
6043   (set_attr "type" "alu_sreg")]
6044)
6045
6046(define_insn "*arm_movsi_insn"
6047  [(set (match_operand:SI 0 "nonimmediate_operand" "=rk,r,r,r,rk,m")
6048	(match_operand:SI 1 "general_operand"      "rk, I,K,j,mi,rk"))]
6049  "TARGET_ARM && !TARGET_IWMMXT && !TARGET_HARD_FLOAT
6050   && (   register_operand (operands[0], SImode)
6051       || register_operand (operands[1], SImode))"
6052  "@
6053   mov%?\\t%0, %1
6054   mov%?\\t%0, %1
6055   mvn%?\\t%0, #%B1
6056   movw%?\\t%0, %1
6057   ldr%?\\t%0, %1
6058   str%?\\t%1, %0"
6059  [(set_attr "type" "mov_reg,mov_imm,mvn_imm,mov_imm,load_4,store_4")
6060   (set_attr "predicable" "yes")
6061   (set_attr "arch" "*,*,*,v6t2,*,*")
6062   (set_attr "pool_range" "*,*,*,*,4096,*")
6063   (set_attr "neg_pool_range" "*,*,*,*,4084,*")]
6064)
6065
6066(define_split
6067  [(set (match_operand:SI 0 "arm_general_register_operand" "")
6068	(match_operand:SI 1 "const_int_operand" ""))]
6069  "(TARGET_32BIT || TARGET_HAVE_MOVT)
6070  && (!(const_ok_for_arm (INTVAL (operands[1]))
6071        || const_ok_for_arm (~INTVAL (operands[1]))))"
6072  [(clobber (const_int 0))]
6073  "
6074  arm_split_constant (SET, SImode, NULL_RTX,
6075                      INTVAL (operands[1]), operands[0], NULL_RTX, 0);
6076  DONE;
6077  "
6078)
6079
6080;; A normal way to do (symbol + offset) requires three instructions at least
6081;; (depends on how big the offset is) as below:
6082;; movw r0, #:lower16:g
6083;; movw r0, #:upper16:g
6084;; adds r0, #4
6085;;
6086;; A better way would be:
6087;; movw r0, #:lower16:g+4
6088;; movw r0, #:upper16:g+4
6089;;
6090;; The limitation of this way is that the length of offset should be a 16-bit
6091;; signed value, because current assembler only supports REL type relocation for
6092;; such case.  If the more powerful RELA type is supported in future, we should
6093;; update this pattern to go with better way.
6094(define_split
6095  [(set (match_operand:SI 0 "arm_general_register_operand" "")
6096	(const:SI (plus:SI (match_operand:SI 1 "general_operand" "")
6097			   (match_operand:SI 2 "const_int_operand" ""))))]
6098  "TARGET_THUMB
6099   && TARGET_HAVE_MOVT
6100   && arm_disable_literal_pool
6101   && reload_completed
6102   && GET_CODE (operands[1]) == SYMBOL_REF"
6103  [(clobber (const_int 0))]
6104  "
6105    int offset = INTVAL (operands[2]);
6106
6107    if (offset < -0x8000 || offset > 0x7fff)
6108      {
6109	arm_emit_movpair (operands[0], operands[1]);
6110	emit_insn (gen_rtx_SET (operands[0],
6111				gen_rtx_PLUS (SImode, operands[0], operands[2])));
6112      }
6113    else
6114      {
6115	rtx op = gen_rtx_CONST (SImode,
6116				gen_rtx_PLUS (SImode, operands[1], operands[2]));
6117	arm_emit_movpair (operands[0], op);
6118      }
6119  "
6120)
6121
6122;; Split symbol_refs at the later stage (after cprop), instead of generating
6123;; movt/movw pair directly at expand.  Otherwise corresponding high_sum
6124;; and lo_sum would be merged back into memory load at cprop.  However,
6125;; if the default is to prefer movt/movw rather than a load from the constant
6126;; pool, the performance is better.
6127(define_split
6128  [(set (match_operand:SI 0 "arm_general_register_operand" "")
6129       (match_operand:SI 1 "general_operand" ""))]
6130  "TARGET_USE_MOVT && GET_CODE (operands[1]) == SYMBOL_REF
6131   && !flag_pic && !target_word_relocations
6132   && !arm_tls_referenced_p (operands[1])"
6133  [(clobber (const_int 0))]
6134{
6135  arm_emit_movpair (operands[0], operands[1]);
6136  DONE;
6137})
6138
6139;; When generating pic, we need to load the symbol offset into a register.
6140;; So that the optimizer does not confuse this with a normal symbol load
6141;; we use an unspec.  The offset will be loaded from a constant pool entry,
6142;; since that is the only type of relocation we can use.
6143
6144;; Wrap calculation of the whole PIC address in a single pattern for the
6145;; benefit of optimizers, particularly, PRE and HOIST.  Calculation of
6146;; a PIC address involves two loads from memory, so we want to CSE it
6147;; as often as possible.
6148;; This pattern will be split into one of the pic_load_addr_* patterns
6149;; and a move after GCSE optimizations.
6150;;
6151;; Note: Update arm.c: legitimize_pic_address() when changing this pattern.
6152(define_expand "calculate_pic_address"
6153  [(set (match_operand:SI 0 "register_operand" "")
6154	(mem:SI (plus:SI (match_operand:SI 1 "register_operand" "")
6155			 (unspec:SI [(match_operand:SI 2 "" "")]
6156				    UNSPEC_PIC_SYM))))]
6157  "flag_pic"
6158)
6159
6160;; Split calculate_pic_address into pic_load_addr_* and a move.
6161(define_split
6162  [(set (match_operand:SI 0 "register_operand" "")
6163	(mem:SI (plus:SI (match_operand:SI 1 "register_operand" "")
6164			 (unspec:SI [(match_operand:SI 2 "" "")]
6165				    UNSPEC_PIC_SYM))))]
6166  "flag_pic"
6167  [(set (match_dup 3) (unspec:SI [(match_dup 2)] UNSPEC_PIC_SYM))
6168   (set (match_dup 0) (mem:SI (plus:SI (match_dup 1) (match_dup 3))))]
6169  "operands[3] = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];"
6170)
6171
6172;; operand1 is the memory address to go into
6173;; pic_load_addr_32bit.
6174;; operand2 is the PIC label to be emitted
6175;; from pic_add_dot_plus_eight.
6176;; We do this to allow hoisting of the entire insn.
6177(define_insn_and_split "pic_load_addr_unified"
6178  [(set (match_operand:SI 0 "s_register_operand" "=r,r,l")
6179	(unspec:SI [(match_operand:SI 1 "" "mX,mX,mX")
6180		    (match_operand:SI 2 "" "")]
6181		    UNSPEC_PIC_UNIFIED))]
6182 "flag_pic"
6183 "#"
6184 "&& reload_completed"
6185 [(set (match_dup 0) (unspec:SI [(match_dup 1)] UNSPEC_PIC_SYM))
6186  (set (match_dup 0) (unspec:SI [(match_dup 0) (match_dup 3)
6187       		     		 (match_dup 2)] UNSPEC_PIC_BASE))]
6188 "operands[3] = TARGET_THUMB ? GEN_INT (4) : GEN_INT (8);"
6189 [(set_attr "type" "load_4,load_4,load_4")
6190  (set_attr "pool_range" "4096,4094,1022")
6191  (set_attr "neg_pool_range" "4084,0,0")
6192  (set_attr "arch"  "a,t2,t1")
6193  (set_attr "length" "8,6,4")]
6194)
6195
6196;; The rather odd constraints on the following are to force reload to leave
6197;; the insn alone, and to force the minipool generation pass to then move
6198;; the GOT symbol to memory.
6199
6200(define_insn "pic_load_addr_32bit"
6201  [(set (match_operand:SI 0 "s_register_operand" "=r")
6202	(unspec:SI [(match_operand:SI 1 "" "mX")] UNSPEC_PIC_SYM))]
6203  "TARGET_32BIT && flag_pic"
6204  "ldr%?\\t%0, %1"
6205  [(set_attr "type" "load_4")
6206   (set (attr "pool_range")
6207	(if_then_else (eq_attr "is_thumb" "no")
6208		      (const_int 4096)
6209		      (const_int 4094)))
6210   (set (attr "neg_pool_range")
6211	(if_then_else (eq_attr "is_thumb" "no")
6212		      (const_int 4084)
6213		      (const_int 0)))]
6214)
6215
6216(define_insn "pic_load_addr_thumb1"
6217  [(set (match_operand:SI 0 "s_register_operand" "=l")
6218	(unspec:SI [(match_operand:SI 1 "" "mX")] UNSPEC_PIC_SYM))]
6219  "TARGET_THUMB1 && flag_pic"
6220  "ldr\\t%0, %1"
6221  [(set_attr "type" "load_4")
6222   (set (attr "pool_range") (const_int 1018))]
6223)
6224
6225(define_insn "pic_add_dot_plus_four"
6226  [(set (match_operand:SI 0 "register_operand" "=r")
6227	(unspec:SI [(match_operand:SI 1 "register_operand" "0")
6228		    (const_int 4)
6229		    (match_operand 2 "" "")]
6230		   UNSPEC_PIC_BASE))]
6231  "TARGET_THUMB"
6232  "*
6233  (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
6234				     INTVAL (operands[2]));
6235  return \"add\\t%0, %|pc\";
6236  "
6237  [(set_attr "length" "2")
6238   (set_attr "type" "alu_sreg")]
6239)
6240
6241(define_insn "pic_add_dot_plus_eight"
6242  [(set (match_operand:SI 0 "register_operand" "=r")
6243	(unspec:SI [(match_operand:SI 1 "register_operand" "r")
6244		    (const_int 8)
6245		    (match_operand 2 "" "")]
6246		   UNSPEC_PIC_BASE))]
6247  "TARGET_ARM"
6248  "*
6249    (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
6250				       INTVAL (operands[2]));
6251    return \"add%?\\t%0, %|pc, %1\";
6252  "
6253  [(set_attr "predicable" "yes")
6254   (set_attr "type" "alu_sreg")]
6255)
6256
6257(define_insn "tls_load_dot_plus_eight"
6258  [(set (match_operand:SI 0 "register_operand" "=r")
6259	(mem:SI (unspec:SI [(match_operand:SI 1 "register_operand" "r")
6260			    (const_int 8)
6261			    (match_operand 2 "" "")]
6262			   UNSPEC_PIC_BASE)))]
6263  "TARGET_ARM"
6264  "*
6265    (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
6266				       INTVAL (operands[2]));
6267    return \"ldr%?\\t%0, [%|pc, %1]\t\t@ tls_load_dot_plus_eight\";
6268  "
6269  [(set_attr "predicable" "yes")
6270   (set_attr "type" "load_4")]
6271)
6272
6273;; PIC references to local variables can generate pic_add_dot_plus_eight
6274;; followed by a load.  These sequences can be crunched down to
6275;; tls_load_dot_plus_eight by a peephole.
6276
6277(define_peephole2
6278  [(set (match_operand:SI 0 "register_operand" "")
6279	(unspec:SI [(match_operand:SI 3 "register_operand" "")
6280		    (const_int 8)
6281		    (match_operand 1 "" "")]
6282		   UNSPEC_PIC_BASE))
6283   (set (match_operand:SI 2 "arm_general_register_operand" "")
6284	(mem:SI (match_dup 0)))]
6285  "TARGET_ARM && peep2_reg_dead_p (2, operands[0])"
6286  [(set (match_dup 2)
6287	(mem:SI (unspec:SI [(match_dup 3)
6288			    (const_int 8)
6289			    (match_dup 1)]
6290			   UNSPEC_PIC_BASE)))]
6291  ""
6292)
6293
6294(define_insn "pic_offset_arm"
6295  [(set (match_operand:SI 0 "register_operand" "=r")
6296	(mem:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
6297			 (unspec:SI [(match_operand:SI 2 "" "X")]
6298				    UNSPEC_PIC_OFFSET))))]
6299  "TARGET_VXWORKS_RTP && TARGET_ARM && flag_pic"
6300  "ldr%?\\t%0, [%1,%2]"
6301  [(set_attr "type" "load_4")]
6302)
6303
6304(define_expand "builtin_setjmp_receiver"
6305  [(label_ref (match_operand 0 "" ""))]
6306  "flag_pic"
6307  "
6308{
6309  /* r3 is clobbered by set/longjmp, so we can use it as a scratch
6310     register.  */
6311  if (arm_pic_register != INVALID_REGNUM)
6312    arm_load_pic_register (1UL << 3);
6313  DONE;
6314}")
6315
6316;; If copying one reg to another we can set the condition codes according to
6317;; its value.  Such a move is common after a return from subroutine and the
6318;; result is being tested against zero.
6319
6320(define_insn "*movsi_compare0"
6321  [(set (reg:CC CC_REGNUM)
6322	(compare:CC (match_operand:SI 1 "s_register_operand" "0,r")
6323		    (const_int 0)))
6324   (set (match_operand:SI 0 "s_register_operand" "=r,r")
6325	(match_dup 1))]
6326  "TARGET_32BIT"
6327  "@
6328   cmp%?\\t%0, #0
6329   subs%?\\t%0, %1, #0"
6330  [(set_attr "conds" "set")
6331   (set_attr "type" "alus_imm,alus_imm")]
6332)
6333
6334;; Subroutine to store a half word from a register into memory.
6335;; Operand 0 is the source register (HImode)
6336;; Operand 1 is the destination address in a register (SImode)
6337
6338;; In both this routine and the next, we must be careful not to spill
6339;; a memory address of reg+large_const into a separate PLUS insn, since this
6340;; can generate unrecognizable rtl.
6341
6342(define_expand "storehi"
6343  [;; store the low byte
6344   (set (match_operand 1 "" "") (match_dup 3))
6345   ;; extract the high byte
6346   (set (match_dup 2)
6347	(ashiftrt:SI (match_operand 0 "" "") (const_int 8)))
6348   ;; store the high byte
6349   (set (match_dup 4) (match_dup 5))]
6350  "TARGET_ARM"
6351  "
6352  {
6353    rtx op1 = operands[1];
6354    rtx addr = XEXP (op1, 0);
6355    enum rtx_code code = GET_CODE (addr);
6356
6357    if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1)))
6358	|| code == MINUS)
6359      op1 = replace_equiv_address (operands[1], force_reg (SImode, addr));
6360
6361    operands[4] = adjust_address (op1, QImode, 1);
6362    operands[1] = adjust_address (operands[1], QImode, 0);
6363    operands[3] = gen_lowpart (QImode, operands[0]);
6364    operands[0] = gen_lowpart (SImode, operands[0]);
6365    operands[2] = gen_reg_rtx (SImode);
6366    operands[5] = gen_lowpart (QImode, operands[2]);
6367  }"
6368)
6369
6370(define_expand "storehi_bigend"
6371  [(set (match_dup 4) (match_dup 3))
6372   (set (match_dup 2)
6373	(ashiftrt:SI (match_operand 0 "" "") (const_int 8)))
6374   (set (match_operand 1 "" "")	(match_dup 5))]
6375  "TARGET_ARM"
6376  "
6377  {
6378    rtx op1 = operands[1];
6379    rtx addr = XEXP (op1, 0);
6380    enum rtx_code code = GET_CODE (addr);
6381
6382    if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1)))
6383	|| code == MINUS)
6384      op1 = replace_equiv_address (op1, force_reg (SImode, addr));
6385
6386    operands[4] = adjust_address (op1, QImode, 1);
6387    operands[1] = adjust_address (operands[1], QImode, 0);
6388    operands[3] = gen_lowpart (QImode, operands[0]);
6389    operands[0] = gen_lowpart (SImode, operands[0]);
6390    operands[2] = gen_reg_rtx (SImode);
6391    operands[5] = gen_lowpart (QImode, operands[2]);
6392  }"
6393)
6394
6395;; Subroutine to store a half word integer constant into memory.
6396(define_expand "storeinthi"
6397  [(set (match_operand 0 "" "")
6398	(match_operand 1 "" ""))
6399   (set (match_dup 3) (match_dup 2))]
6400  "TARGET_ARM"
6401  "
6402  {
6403    HOST_WIDE_INT value = INTVAL (operands[1]);
6404    rtx addr = XEXP (operands[0], 0);
6405    rtx op0 = operands[0];
6406    enum rtx_code code = GET_CODE (addr);
6407
6408    if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1)))
6409	|| code == MINUS)
6410      op0 = replace_equiv_address (op0, force_reg (SImode, addr));
6411
6412    operands[1] = gen_reg_rtx (SImode);
6413    if (BYTES_BIG_ENDIAN)
6414      {
6415	emit_insn (gen_movsi (operands[1], GEN_INT ((value >> 8) & 255)));
6416	if ((value & 255) == ((value >> 8) & 255))
6417	  operands[2] = operands[1];
6418	else
6419	  {
6420	    operands[2] = gen_reg_rtx (SImode);
6421	    emit_insn (gen_movsi (operands[2], GEN_INT (value & 255)));
6422	  }
6423      }
6424    else
6425      {
6426	emit_insn (gen_movsi (operands[1], GEN_INT (value & 255)));
6427	if ((value & 255) == ((value >> 8) & 255))
6428	  operands[2] = operands[1];
6429	else
6430	  {
6431	    operands[2] = gen_reg_rtx (SImode);
6432	    emit_insn (gen_movsi (operands[2], GEN_INT ((value >> 8) & 255)));
6433	  }
6434      }
6435
6436    operands[3] = adjust_address (op0, QImode, 1);
6437    operands[0] = adjust_address (operands[0], QImode, 0);
6438    operands[2] = gen_lowpart (QImode, operands[2]);
6439    operands[1] = gen_lowpart (QImode, operands[1]);
6440  }"
6441)
6442
6443(define_expand "storehi_single_op"
6444  [(set (match_operand:HI 0 "memory_operand" "")
6445	(match_operand:HI 1 "general_operand" ""))]
6446  "TARGET_32BIT && arm_arch4"
6447  "
6448  if (!s_register_operand (operands[1], HImode))
6449    operands[1] = copy_to_mode_reg (HImode, operands[1]);
6450  "
6451)
6452
6453(define_expand "movhi"
6454  [(set (match_operand:HI 0 "general_operand" "")
6455	(match_operand:HI 1 "general_operand" ""))]
6456  "TARGET_EITHER"
6457  "
6458  if (TARGET_ARM)
6459    {
6460      if (can_create_pseudo_p ())
6461        {
6462          if (MEM_P (operands[0]))
6463	    {
6464	      if (arm_arch4)
6465	        {
6466	          emit_insn (gen_storehi_single_op (operands[0], operands[1]));
6467	          DONE;
6468	        }
6469	      if (CONST_INT_P (operands[1]))
6470	        emit_insn (gen_storeinthi (operands[0], operands[1]));
6471	      else
6472	        {
6473	          if (MEM_P (operands[1]))
6474		    operands[1] = force_reg (HImode, operands[1]);
6475	          if (BYTES_BIG_ENDIAN)
6476		    emit_insn (gen_storehi_bigend (operands[1], operands[0]));
6477	          else
6478		   emit_insn (gen_storehi (operands[1], operands[0]));
6479	        }
6480	      DONE;
6481	    }
6482          /* Sign extend a constant, and keep it in an SImode reg.  */
6483          else if (CONST_INT_P (operands[1]))
6484	    {
6485	      rtx reg = gen_reg_rtx (SImode);
6486	      HOST_WIDE_INT val = INTVAL (operands[1]) & 0xffff;
6487
6488	      /* If the constant is already valid, leave it alone.  */
6489	      if (!const_ok_for_arm (val))
6490	        {
6491	          /* If setting all the top bits will make the constant
6492		     loadable in a single instruction, then set them.
6493		     Otherwise, sign extend the number.  */
6494
6495	          if (const_ok_for_arm (~(val | ~0xffff)))
6496		    val |= ~0xffff;
6497	          else if (val & 0x8000)
6498		    val |= ~0xffff;
6499	        }
6500
6501	      emit_insn (gen_movsi (reg, GEN_INT (val)));
6502	      operands[1] = gen_lowpart (HImode, reg);
6503	    }
6504	  else if (arm_arch4 && optimize && can_create_pseudo_p ()
6505		   && MEM_P (operands[1]))
6506	    {
6507	      rtx reg = gen_reg_rtx (SImode);
6508
6509	      emit_insn (gen_zero_extendhisi2 (reg, operands[1]));
6510	      operands[1] = gen_lowpart (HImode, reg);
6511	    }
6512          else if (!arm_arch4)
6513	    {
6514	      if (MEM_P (operands[1]))
6515	        {
6516		  rtx base;
6517		  rtx offset = const0_rtx;
6518		  rtx reg = gen_reg_rtx (SImode);
6519
6520		  if ((REG_P (base = XEXP (operands[1], 0))
6521		       || (GET_CODE (base) == PLUS
6522			   && (CONST_INT_P (offset = XEXP (base, 1)))
6523                           && ((INTVAL(offset) & 1) != 1)
6524			   && REG_P (base = XEXP (base, 0))))
6525		      && REGNO_POINTER_ALIGN (REGNO (base)) >= 32)
6526		    {
6527		      rtx new_rtx;
6528
6529		      new_rtx = widen_memory_access (operands[1], SImode,
6530						     ((INTVAL (offset) & ~3)
6531						      - INTVAL (offset)));
6532		      emit_insn (gen_movsi (reg, new_rtx));
6533		      if (((INTVAL (offset) & 2) != 0)
6534			  ^ (BYTES_BIG_ENDIAN ? 1 : 0))
6535			{
6536			  rtx reg2 = gen_reg_rtx (SImode);
6537
6538			  emit_insn (gen_lshrsi3 (reg2, reg, GEN_INT (16)));
6539			  reg = reg2;
6540			}
6541		    }
6542		  else
6543		    emit_insn (gen_movhi_bytes (reg, operands[1]));
6544
6545		  operands[1] = gen_lowpart (HImode, reg);
6546	       }
6547	   }
6548        }
6549      /* Handle loading a large integer during reload.  */
6550      else if (CONST_INT_P (operands[1])
6551	       && !const_ok_for_arm (INTVAL (operands[1]))
6552	       && !const_ok_for_arm (~INTVAL (operands[1])))
6553        {
6554          /* Writing a constant to memory needs a scratch, which should
6555	     be handled with SECONDARY_RELOADs.  */
6556          gcc_assert (REG_P (operands[0]));
6557
6558          operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
6559          emit_insn (gen_movsi (operands[0], operands[1]));
6560          DONE;
6561       }
6562    }
6563  else if (TARGET_THUMB2)
6564    {
6565      /* Thumb-2 can do everything except mem=mem and mem=const easily.  */
6566      if (can_create_pseudo_p ())
6567	{
6568	  if (!REG_P (operands[0]))
6569	    operands[1] = force_reg (HImode, operands[1]);
6570          /* Zero extend a constant, and keep it in an SImode reg.  */
6571          else if (CONST_INT_P (operands[1]))
6572	    {
6573	      rtx reg = gen_reg_rtx (SImode);
6574	      HOST_WIDE_INT val = INTVAL (operands[1]) & 0xffff;
6575
6576	      emit_insn (gen_movsi (reg, GEN_INT (val)));
6577	      operands[1] = gen_lowpart (HImode, reg);
6578	    }
6579	}
6580    }
6581  else /* TARGET_THUMB1 */
6582    {
6583      if (can_create_pseudo_p ())
6584        {
6585	  if (CONST_INT_P (operands[1]))
6586	    {
6587	      rtx reg = gen_reg_rtx (SImode);
6588
6589	      emit_insn (gen_movsi (reg, operands[1]));
6590	      operands[1] = gen_lowpart (HImode, reg);
6591	    }
6592
6593          /* ??? We shouldn't really get invalid addresses here, but this can
6594	     happen if we are passed a SP (never OK for HImode/QImode) or
6595	     virtual register (also rejected as illegitimate for HImode/QImode)
6596	     relative address.  */
6597          /* ??? This should perhaps be fixed elsewhere, for instance, in
6598	     fixup_stack_1, by checking for other kinds of invalid addresses,
6599	     e.g. a bare reference to a virtual register.  This may confuse the
6600	     alpha though, which must handle this case differently.  */
6601          if (MEM_P (operands[0])
6602	      && !memory_address_p (GET_MODE (operands[0]),
6603				    XEXP (operands[0], 0)))
6604	    operands[0]
6605	      = replace_equiv_address (operands[0],
6606				       copy_to_reg (XEXP (operands[0], 0)));
6607
6608          if (MEM_P (operands[1])
6609	      && !memory_address_p (GET_MODE (operands[1]),
6610				    XEXP (operands[1], 0)))
6611	    operands[1]
6612	      = replace_equiv_address (operands[1],
6613				       copy_to_reg (XEXP (operands[1], 0)));
6614
6615	  if (MEM_P (operands[1]) && optimize > 0)
6616	    {
6617	      rtx reg = gen_reg_rtx (SImode);
6618
6619	      emit_insn (gen_zero_extendhisi2 (reg, operands[1]));
6620	      operands[1] = gen_lowpart (HImode, reg);
6621	    }
6622
6623          if (MEM_P (operands[0]))
6624	    operands[1] = force_reg (HImode, operands[1]);
6625        }
6626      else if (CONST_INT_P (operands[1])
6627	        && !satisfies_constraint_I (operands[1]))
6628        {
6629	  /* Handle loading a large integer during reload.  */
6630
6631          /* Writing a constant to memory needs a scratch, which should
6632	     be handled with SECONDARY_RELOADs.  */
6633          gcc_assert (REG_P (operands[0]));
6634
6635          operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
6636          emit_insn (gen_movsi (operands[0], operands[1]));
6637          DONE;
6638        }
6639    }
6640  "
6641)
6642
6643(define_expand "movhi_bytes"
6644  [(set (match_dup 2) (zero_extend:SI (match_operand:HI 1 "" "")))
6645   (set (match_dup 3)
6646	(zero_extend:SI (match_dup 6)))
6647   (set (match_operand:SI 0 "" "")
6648	 (ior:SI (ashift:SI (match_dup 4) (const_int 8)) (match_dup 5)))]
6649  "TARGET_ARM"
6650  "
6651  {
6652    rtx mem1, mem2;
6653    rtx addr = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
6654
6655    mem1 = change_address (operands[1], QImode, addr);
6656    mem2 = change_address (operands[1], QImode,
6657			   plus_constant (Pmode, addr, 1));
6658    operands[0] = gen_lowpart (SImode, operands[0]);
6659    operands[1] = mem1;
6660    operands[2] = gen_reg_rtx (SImode);
6661    operands[3] = gen_reg_rtx (SImode);
6662    operands[6] = mem2;
6663
6664    if (BYTES_BIG_ENDIAN)
6665      {
6666	operands[4] = operands[2];
6667	operands[5] = operands[3];
6668      }
6669    else
6670      {
6671	operands[4] = operands[3];
6672	operands[5] = operands[2];
6673      }
6674  }"
6675)
6676
6677(define_expand "movhi_bigend"
6678  [(set (match_dup 2)
6679	(rotate:SI (subreg:SI (match_operand:HI 1 "memory_operand" "") 0)
6680		   (const_int 16)))
6681   (set (match_dup 3)
6682	(ashiftrt:SI (match_dup 2) (const_int 16)))
6683   (set (match_operand:HI 0 "s_register_operand" "")
6684	(match_dup 4))]
6685  "TARGET_ARM"
6686  "
6687  operands[2] = gen_reg_rtx (SImode);
6688  operands[3] = gen_reg_rtx (SImode);
6689  operands[4] = gen_lowpart (HImode, operands[3]);
6690  "
6691)
6692
6693;; Pattern to recognize insn generated default case above
6694(define_insn "*movhi_insn_arch4"
6695  [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m,r")
6696	(match_operand:HI 1 "general_operand"      "rIk,K,n,r,mi"))]
6697  "TARGET_ARM
6698   && arm_arch4 && !TARGET_HARD_FLOAT
6699   && (register_operand (operands[0], HImode)
6700       || register_operand (operands[1], HImode))"
6701  "@
6702   mov%?\\t%0, %1\\t%@ movhi
6703   mvn%?\\t%0, #%B1\\t%@ movhi
6704   movw%?\\t%0, %L1\\t%@ movhi
6705   strh%?\\t%1, %0\\t%@ movhi
6706   ldrh%?\\t%0, %1\\t%@ movhi"
6707  [(set_attr "predicable" "yes")
6708   (set_attr "pool_range" "*,*,*,*,256")
6709   (set_attr "neg_pool_range" "*,*,*,*,244")
6710   (set_attr "arch" "*,*,v6t2,*,*")
6711   (set_attr_alternative "type"
6712                         [(if_then_else (match_operand 1 "const_int_operand" "")
6713                                        (const_string "mov_imm" )
6714                                        (const_string "mov_reg"))
6715                          (const_string "mvn_imm")
6716                          (const_string "mov_imm")
6717                          (const_string "store_4")
6718                          (const_string "load_4")])]
6719)
6720
6721(define_insn "*movhi_bytes"
6722  [(set (match_operand:HI 0 "s_register_operand" "=r,r,r")
6723	(match_operand:HI 1 "arm_rhs_operand"  "I,rk,K"))]
6724  "TARGET_ARM && !TARGET_HARD_FLOAT"
6725  "@
6726   mov%?\\t%0, %1\\t%@ movhi
6727   mov%?\\t%0, %1\\t%@ movhi
6728   mvn%?\\t%0, #%B1\\t%@ movhi"
6729  [(set_attr "predicable" "yes")
6730   (set_attr "type" "mov_imm,mov_reg,mvn_imm")]
6731)
6732
6733;; We use a DImode scratch because we may occasionally need an additional
6734;; temporary if the address isn't offsettable -- push_reload doesn't seem
6735;; to take any notice of the "o" constraints on reload_memory_operand operand.
6736(define_expand "reload_outhi"
6737  [(parallel [(match_operand:HI 0 "arm_reload_memory_operand" "=o")
6738	      (match_operand:HI 1 "s_register_operand"        "r")
6739	      (match_operand:DI 2 "s_register_operand"        "=&l")])]
6740  "TARGET_EITHER"
6741  "if (TARGET_ARM)
6742     arm_reload_out_hi (operands);
6743   else
6744     thumb_reload_out_hi (operands);
6745  DONE;
6746  "
6747)
6748
6749(define_expand "reload_inhi"
6750  [(parallel [(match_operand:HI 0 "s_register_operand" "=r")
6751	      (match_operand:HI 1 "arm_reload_memory_operand" "o")
6752	      (match_operand:DI 2 "s_register_operand" "=&r")])]
6753  "TARGET_EITHER"
6754  "
6755  if (TARGET_ARM)
6756    arm_reload_in_hi (operands);
6757  else
6758    thumb_reload_out_hi (operands);
6759  DONE;
6760")
6761
6762(define_expand "movqi"
6763  [(set (match_operand:QI 0 "general_operand" "")
6764        (match_operand:QI 1 "general_operand" ""))]
6765  "TARGET_EITHER"
6766  "
6767  /* Everything except mem = const or mem = mem can be done easily */
6768
6769  if (can_create_pseudo_p ())
6770    {
6771      if (CONST_INT_P (operands[1]))
6772	{
6773	  rtx reg = gen_reg_rtx (SImode);
6774
6775	  /* For thumb we want an unsigned immediate, then we are more likely
6776	     to be able to use a movs insn.  */
6777	  if (TARGET_THUMB)
6778	    operands[1] = GEN_INT (INTVAL (operands[1]) & 255);
6779
6780	  emit_insn (gen_movsi (reg, operands[1]));
6781	  operands[1] = gen_lowpart (QImode, reg);
6782	}
6783
6784      if (TARGET_THUMB)
6785	{
6786          /* ??? We shouldn't really get invalid addresses here, but this can
6787	     happen if we are passed a SP (never OK for HImode/QImode) or
6788	     virtual register (also rejected as illegitimate for HImode/QImode)
6789	     relative address.  */
6790          /* ??? This should perhaps be fixed elsewhere, for instance, in
6791	     fixup_stack_1, by checking for other kinds of invalid addresses,
6792	     e.g. a bare reference to a virtual register.  This may confuse the
6793	     alpha though, which must handle this case differently.  */
6794          if (MEM_P (operands[0])
6795	      && !memory_address_p (GET_MODE (operands[0]),
6796		  		     XEXP (operands[0], 0)))
6797	    operands[0]
6798	      = replace_equiv_address (operands[0],
6799				       copy_to_reg (XEXP (operands[0], 0)));
6800          if (MEM_P (operands[1])
6801	      && !memory_address_p (GET_MODE (operands[1]),
6802				    XEXP (operands[1], 0)))
6803	     operands[1]
6804	       = replace_equiv_address (operands[1],
6805					copy_to_reg (XEXP (operands[1], 0)));
6806	}
6807
6808      if (MEM_P (operands[1]) && optimize > 0)
6809	{
6810	  rtx reg = gen_reg_rtx (SImode);
6811
6812	  emit_insn (gen_zero_extendqisi2 (reg, operands[1]));
6813	  operands[1] = gen_lowpart (QImode, reg);
6814	}
6815
6816      if (MEM_P (operands[0]))
6817	operands[1] = force_reg (QImode, operands[1]);
6818    }
6819  else if (TARGET_THUMB
6820	   && CONST_INT_P (operands[1])
6821	   && !satisfies_constraint_I (operands[1]))
6822    {
6823      /* Handle loading a large integer during reload.  */
6824
6825      /* Writing a constant to memory needs a scratch, which should
6826	 be handled with SECONDARY_RELOADs.  */
6827      gcc_assert (REG_P (operands[0]));
6828
6829      operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
6830      emit_insn (gen_movsi (operands[0], operands[1]));
6831      DONE;
6832    }
6833  "
6834)
6835
6836(define_insn "*arm_movqi_insn"
6837  [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,r,l,r,l,Uu,r,m")
6838	(match_operand:QI 1 "general_operand" "rk,rk,I,Py,K,Uu,l,Uh,r"))]
6839  "TARGET_32BIT
6840   && (   register_operand (operands[0], QImode)
6841       || register_operand (operands[1], QImode))"
6842  "@
6843   mov%?\\t%0, %1
6844   mov%?\\t%0, %1
6845   mov%?\\t%0, %1
6846   mov%?\\t%0, %1
6847   mvn%?\\t%0, #%B1
6848   ldrb%?\\t%0, %1
6849   strb%?\\t%1, %0
6850   ldrb%?\\t%0, %1
6851   strb%?\\t%1, %0"
6852  [(set_attr "type" "mov_reg,mov_reg,mov_imm,mov_imm,mvn_imm,load_4,store_4,load_4,store_4")
6853   (set_attr "predicable" "yes")
6854   (set_attr "predicable_short_it" "yes,yes,no,yes,no,no,no,no,no")
6855   (set_attr "arch" "t2,any,any,t2,any,t2,t2,any,any")
6856   (set_attr "length" "2,4,4,2,4,2,2,4,4")]
6857)
6858
6859;; HFmode moves
6860(define_expand "movhf"
6861  [(set (match_operand:HF 0 "general_operand" "")
6862	(match_operand:HF 1 "general_operand" ""))]
6863  "TARGET_EITHER"
6864  "
6865  if (TARGET_32BIT)
6866    {
6867      if (MEM_P (operands[0]))
6868        operands[1] = force_reg (HFmode, operands[1]);
6869    }
6870  else /* TARGET_THUMB1 */
6871    {
6872      if (can_create_pseudo_p ())
6873        {
6874           if (!REG_P (operands[0]))
6875	     operands[1] = force_reg (HFmode, operands[1]);
6876        }
6877    }
6878  "
6879)
6880
6881(define_insn "*arm32_movhf"
6882  [(set (match_operand:HF 0 "nonimmediate_operand" "=r,m,r,r")
6883	(match_operand:HF 1 "general_operand"	   " m,r,r,F"))]
6884  "TARGET_32BIT && !TARGET_HARD_FLOAT
6885   && (	  s_register_operand (operands[0], HFmode)
6886       || s_register_operand (operands[1], HFmode))"
6887  "*
6888  switch (which_alternative)
6889    {
6890    case 0:	/* ARM register from memory */
6891      return \"ldrh%?\\t%0, %1\\t%@ __fp16\";
6892    case 1:	/* memory from ARM register */
6893      return \"strh%?\\t%1, %0\\t%@ __fp16\";
6894    case 2:	/* ARM register from ARM register */
6895      return \"mov%?\\t%0, %1\\t%@ __fp16\";
6896    case 3:	/* ARM register from constant */
6897      {
6898	long bits;
6899	rtx ops[4];
6900
6901	bits = real_to_target (NULL, CONST_DOUBLE_REAL_VALUE (operands[1]),
6902			       HFmode);
6903	ops[0] = operands[0];
6904	ops[1] = GEN_INT (bits);
6905	ops[2] = GEN_INT (bits & 0xff00);
6906	ops[3] = GEN_INT (bits & 0x00ff);
6907
6908	if (arm_arch_thumb2)
6909	  output_asm_insn (\"movw%?\\t%0, %1\", ops);
6910	else
6911	  output_asm_insn (\"mov%?\\t%0, %2\;orr%?\\t%0, %0, %3\", ops);
6912	return \"\";
6913       }
6914    default:
6915      gcc_unreachable ();
6916    }
6917  "
6918  [(set_attr "conds" "unconditional")
6919   (set_attr "type" "load_4,store_4,mov_reg,multiple")
6920   (set_attr "length" "4,4,4,8")
6921   (set_attr "predicable" "yes")]
6922)
6923
6924(define_expand "movsf"
6925  [(set (match_operand:SF 0 "general_operand" "")
6926	(match_operand:SF 1 "general_operand" ""))]
6927  "TARGET_EITHER"
6928  "
6929  if (TARGET_32BIT)
6930    {
6931      if (MEM_P (operands[0]))
6932        operands[1] = force_reg (SFmode, operands[1]);
6933    }
6934  else /* TARGET_THUMB1 */
6935    {
6936      if (can_create_pseudo_p ())
6937        {
6938           if (!REG_P (operands[0]))
6939	     operands[1] = force_reg (SFmode, operands[1]);
6940        }
6941    }
6942  "
6943)
6944
6945;; Transform a floating-point move of a constant into a core register into
6946;; an SImode operation.
6947(define_split
6948  [(set (match_operand:SF 0 "arm_general_register_operand" "")
6949	(match_operand:SF 1 "immediate_operand" ""))]
6950  "TARGET_EITHER
6951   && reload_completed
6952   && CONST_DOUBLE_P (operands[1])"
6953  [(set (match_dup 2) (match_dup 3))]
6954  "
6955  operands[2] = gen_lowpart (SImode, operands[0]);
6956  operands[3] = gen_lowpart (SImode, operands[1]);
6957  if (operands[2] == 0 || operands[3] == 0)
6958    FAIL;
6959  "
6960)
6961
6962(define_insn "*arm_movsf_soft_insn"
6963  [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,m")
6964	(match_operand:SF 1 "general_operand"  "r,mE,r"))]
6965  "TARGET_32BIT
6966   && TARGET_SOFT_FLOAT
6967   && (!MEM_P (operands[0])
6968       || register_operand (operands[1], SFmode))"
6969  "@
6970   mov%?\\t%0, %1
6971   ldr%?\\t%0, %1\\t%@ float
6972   str%?\\t%1, %0\\t%@ float"
6973  [(set_attr "predicable" "yes")
6974   (set_attr "type" "mov_reg,load_4,store_4")
6975   (set_attr "arm_pool_range" "*,4096,*")
6976   (set_attr "thumb2_pool_range" "*,4094,*")
6977   (set_attr "arm_neg_pool_range" "*,4084,*")
6978   (set_attr "thumb2_neg_pool_range" "*,0,*")]
6979)
6980
6981(define_expand "movdf"
6982  [(set (match_operand:DF 0 "general_operand" "")
6983	(match_operand:DF 1 "general_operand" ""))]
6984  "TARGET_EITHER"
6985  "
6986  if (TARGET_32BIT)
6987    {
6988      if (MEM_P (operands[0]))
6989        operands[1] = force_reg (DFmode, operands[1]);
6990    }
6991  else /* TARGET_THUMB */
6992    {
6993      if (can_create_pseudo_p ())
6994        {
6995          if (!REG_P (operands[0]))
6996	    operands[1] = force_reg (DFmode, operands[1]);
6997        }
6998    }
6999  "
7000)
7001
7002;; Reloading a df mode value stored in integer regs to memory can require a
7003;; scratch reg.
7004(define_expand "reload_outdf"
7005  [(match_operand:DF 0 "arm_reload_memory_operand" "=o")
7006   (match_operand:DF 1 "s_register_operand" "r")
7007   (match_operand:SI 2 "s_register_operand" "=&r")]
7008  "TARGET_THUMB2"
7009  "
7010  {
7011    enum rtx_code code = GET_CODE (XEXP (operands[0], 0));
7012
7013    if (code == REG)
7014      operands[2] = XEXP (operands[0], 0);
7015    else if (code == POST_INC || code == PRE_DEC)
7016      {
7017	operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7018	operands[1] = gen_rtx_SUBREG (DImode, operands[1], 0);
7019	emit_insn (gen_movdi (operands[0], operands[1]));
7020	DONE;
7021      }
7022    else if (code == PRE_INC)
7023      {
7024	rtx reg = XEXP (XEXP (operands[0], 0), 0);
7025
7026	emit_insn (gen_addsi3 (reg, reg, GEN_INT (8)));
7027	operands[2] = reg;
7028      }
7029    else if (code == POST_DEC)
7030      operands[2] = XEXP (XEXP (operands[0], 0), 0);
7031    else
7032      emit_insn (gen_addsi3 (operands[2], XEXP (XEXP (operands[0], 0), 0),
7033			     XEXP (XEXP (operands[0], 0), 1)));
7034
7035    emit_insn (gen_rtx_SET (replace_equiv_address (operands[0], operands[2]),
7036			    operands[1]));
7037
7038    if (code == POST_DEC)
7039      emit_insn (gen_addsi3 (operands[2], operands[2], GEN_INT (-8)));
7040
7041    DONE;
7042  }"
7043)
7044
7045(define_insn "*movdf_soft_insn"
7046  [(set (match_operand:DF 0 "nonimmediate_soft_df_operand" "=r,r,r,q,m")
7047	(match_operand:DF 1 "soft_df_operand" "rDa,Db,Dc,mF,q"))]
7048  "TARGET_32BIT && TARGET_SOFT_FLOAT
7049   && (   register_operand (operands[0], DFmode)
7050       || register_operand (operands[1], DFmode))"
7051  "*
7052  switch (which_alternative)
7053    {
7054    case 0:
7055    case 1:
7056    case 2:
7057      return \"#\";
7058    default:
7059      return output_move_double (operands, true, NULL);
7060    }
7061  "
7062  [(set_attr "length" "8,12,16,8,8")
7063   (set_attr "type" "multiple,multiple,multiple,load_8,store_8")
7064   (set_attr "arm_pool_range" "*,*,*,1020,*")
7065   (set_attr "thumb2_pool_range" "*,*,*,1018,*")
7066   (set_attr "arm_neg_pool_range" "*,*,*,1004,*")
7067   (set_attr "thumb2_neg_pool_range" "*,*,*,0,*")]
7068)
7069
7070
7071;; load- and store-multiple insns
7072;; The arm can load/store any set of registers, provided that they are in
7073;; ascending order, but these expanders assume a contiguous set.
7074
7075(define_expand "load_multiple"
7076  [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
7077                          (match_operand:SI 1 "" ""))
7078                     (use (match_operand:SI 2 "" ""))])]
7079  "TARGET_32BIT"
7080{
7081  HOST_WIDE_INT offset = 0;
7082
7083  /* Support only fixed point registers.  */
7084  if (!CONST_INT_P (operands[2])
7085      || INTVAL (operands[2]) > MAX_LDM_STM_OPS
7086      || INTVAL (operands[2]) < 2
7087      || !MEM_P (operands[1])
7088      || !REG_P (operands[0])
7089      || REGNO (operands[0]) > (LAST_ARM_REGNUM - 1)
7090      || REGNO (operands[0]) + INTVAL (operands[2]) > LAST_ARM_REGNUM)
7091    FAIL;
7092
7093  operands[3]
7094    = arm_gen_load_multiple (arm_regs_in_sequence + REGNO (operands[0]),
7095			     INTVAL (operands[2]),
7096			     force_reg (SImode, XEXP (operands[1], 0)),
7097			     FALSE, operands[1], &offset);
7098})
7099
7100(define_expand "store_multiple"
7101  [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
7102                          (match_operand:SI 1 "" ""))
7103                     (use (match_operand:SI 2 "" ""))])]
7104  "TARGET_32BIT"
7105{
7106  HOST_WIDE_INT offset = 0;
7107
7108  /* Support only fixed point registers.  */
7109  if (!CONST_INT_P (operands[2])
7110      || INTVAL (operands[2]) > MAX_LDM_STM_OPS
7111      || INTVAL (operands[2]) < 2
7112      || !REG_P (operands[1])
7113      || !MEM_P (operands[0])
7114      || REGNO (operands[1]) > (LAST_ARM_REGNUM - 1)
7115      || REGNO (operands[1]) + INTVAL (operands[2]) > LAST_ARM_REGNUM)
7116    FAIL;
7117
7118  operands[3]
7119    = arm_gen_store_multiple (arm_regs_in_sequence + REGNO (operands[1]),
7120			      INTVAL (operands[2]),
7121			      force_reg (SImode, XEXP (operands[0], 0)),
7122			      FALSE, operands[0], &offset);
7123})
7124
7125
7126(define_expand "setmemsi"
7127  [(match_operand:BLK 0 "general_operand" "")
7128   (match_operand:SI 1 "const_int_operand" "")
7129   (match_operand:SI 2 "const_int_operand" "")
7130   (match_operand:SI 3 "const_int_operand" "")]
7131  "TARGET_32BIT"
7132{
7133  if (arm_gen_setmem (operands))
7134    DONE;
7135
7136  FAIL;
7137})
7138
7139
7140;; Move a block of memory if it is word aligned and MORE than 2 words long.
7141;; We could let this apply for blocks of less than this, but it clobbers so
7142;; many registers that there is then probably a better way.
7143
7144(define_expand "movmemqi"
7145  [(match_operand:BLK 0 "general_operand" "")
7146   (match_operand:BLK 1 "general_operand" "")
7147   (match_operand:SI 2 "const_int_operand" "")
7148   (match_operand:SI 3 "const_int_operand" "")]
7149  ""
7150  "
7151  if (TARGET_32BIT)
7152    {
7153      if (TARGET_LDRD && current_tune->prefer_ldrd_strd
7154          && !optimize_function_for_size_p (cfun))
7155        {
7156          if (gen_movmem_ldrd_strd (operands))
7157            DONE;
7158          FAIL;
7159        }
7160
7161      if (arm_gen_movmemqi (operands))
7162        DONE;
7163      FAIL;
7164    }
7165  else /* TARGET_THUMB1 */
7166    {
7167      if (   INTVAL (operands[3]) != 4
7168          || INTVAL (operands[2]) > 48)
7169        FAIL;
7170
7171      thumb_expand_movmemqi (operands);
7172      DONE;
7173    }
7174  "
7175)
7176
7177
7178;; Compare & branch insns
7179;; The range calculations are based as follows:
7180;; For forward branches, the address calculation returns the address of
7181;; the next instruction.  This is 2 beyond the branch instruction.
7182;; For backward branches, the address calculation returns the address of
7183;; the first instruction in this pattern (cmp).  This is 2 before the branch
7184;; instruction for the shortest sequence, and 4 before the branch instruction
7185;; if we have to jump around an unconditional branch.
7186;; To the basic branch range the PC offset must be added (this is +4).
7187;; So for forward branches we have
7188;;   (pos_range - pos_base_offs + pc_offs) = (pos_range - 2 + 4).
7189;; And for backward branches we have
7190;;   (neg_range - neg_base_offs + pc_offs) = (neg_range - (-2 or -4) + 4).
7191;;
7192;; For a 'b'       pos_range = 2046, neg_range = -2048 giving (-2040->2048).
7193;; For a 'b<cond>' pos_range = 254,  neg_range = -256  giving (-250 ->256).
7194
7195(define_expand "cbranchsi4"
7196  [(set (pc) (if_then_else
7197	      (match_operator 0 "expandable_comparison_operator"
7198	       [(match_operand:SI 1 "s_register_operand" "")
7199	        (match_operand:SI 2 "nonmemory_operand" "")])
7200	      (label_ref (match_operand 3 "" ""))
7201	      (pc)))]
7202  "TARGET_EITHER"
7203  "
7204  if (!TARGET_THUMB1)
7205    {
7206      if (!arm_validize_comparison (&operands[0], &operands[1], &operands[2]))
7207        FAIL;
7208      emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
7209				      operands[3]));
7210      DONE;
7211    }
7212  if (thumb1_cmpneg_operand (operands[2], SImode))
7213    {
7214      emit_jump_insn (gen_cbranchsi4_scratch (NULL, operands[1], operands[2],
7215					      operands[3], operands[0]));
7216      DONE;
7217    }
7218  if (!thumb1_cmp_operand (operands[2], SImode))
7219    operands[2] = force_reg (SImode, operands[2]);
7220  ")
7221
7222(define_expand "cbranchsf4"
7223  [(set (pc) (if_then_else
7224	      (match_operator 0 "expandable_comparison_operator"
7225	       [(match_operand:SF 1 "s_register_operand" "")
7226	        (match_operand:SF 2 "vfp_compare_operand" "")])
7227	      (label_ref (match_operand 3 "" ""))
7228	      (pc)))]
7229  "TARGET_32BIT && TARGET_HARD_FLOAT"
7230  "emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
7231				   operands[3])); DONE;"
7232)
7233
7234(define_expand "cbranchdf4"
7235  [(set (pc) (if_then_else
7236	      (match_operator 0 "expandable_comparison_operator"
7237	       [(match_operand:DF 1 "s_register_operand" "")
7238	        (match_operand:DF 2 "vfp_compare_operand" "")])
7239	      (label_ref (match_operand 3 "" ""))
7240	      (pc)))]
7241  "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
7242  "emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
7243				   operands[3])); DONE;"
7244)
7245
7246(define_expand "cbranchdi4"
7247  [(set (pc) (if_then_else
7248	      (match_operator 0 "expandable_comparison_operator"
7249	       [(match_operand:DI 1 "s_register_operand" "")
7250	        (match_operand:DI 2 "cmpdi_operand" "")])
7251	      (label_ref (match_operand 3 "" ""))
7252	      (pc)))]
7253  "TARGET_32BIT"
7254  "{
7255     if (!arm_validize_comparison (&operands[0], &operands[1], &operands[2]))
7256       FAIL;
7257     emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
7258				       operands[3]));
7259     DONE;
7260   }"
7261)
7262
7263;; Comparison and test insns
7264
7265(define_insn "*arm_cmpsi_insn"
7266  [(set (reg:CC CC_REGNUM)
7267	(compare:CC (match_operand:SI 0 "s_register_operand" "l,r,r,r,r")
7268		    (match_operand:SI 1 "arm_add_operand"    "Py,r,r,I,L")))]
7269  "TARGET_32BIT"
7270  "@
7271   cmp%?\\t%0, %1
7272   cmp%?\\t%0, %1
7273   cmp%?\\t%0, %1
7274   cmp%?\\t%0, %1
7275   cmn%?\\t%0, #%n1"
7276  [(set_attr "conds" "set")
7277   (set_attr "arch" "t2,t2,any,any,any")
7278   (set_attr "length" "2,2,4,4,4")
7279   (set_attr "predicable" "yes")
7280   (set_attr "predicable_short_it" "yes,yes,yes,no,no")
7281   (set_attr "type" "alus_imm,alus_sreg,alus_sreg,alus_imm,alus_imm")]
7282)
7283
7284(define_insn "*cmpsi_shiftsi"
7285  [(set (reg:CC CC_REGNUM)
7286	(compare:CC (match_operand:SI   0 "s_register_operand" "r,r,r")
7287		    (match_operator:SI  3 "shift_operator"
7288		     [(match_operand:SI 1 "s_register_operand" "r,r,r")
7289		      (match_operand:SI 2 "shift_amount_operand" "M,r,M")])))]
7290  "TARGET_32BIT"
7291  "cmp\\t%0, %1%S3"
7292  [(set_attr "conds" "set")
7293   (set_attr "shift" "1")
7294   (set_attr "arch" "32,a,a")
7295   (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
7296
7297(define_insn "*cmpsi_shiftsi_swp"
7298  [(set (reg:CC_SWP CC_REGNUM)
7299	(compare:CC_SWP (match_operator:SI 3 "shift_operator"
7300			 [(match_operand:SI 1 "s_register_operand" "r,r,r")
7301			  (match_operand:SI 2 "shift_amount_operand" "M,r,M")])
7302			(match_operand:SI 0 "s_register_operand" "r,r,r")))]
7303  "TARGET_32BIT"
7304  "cmp%?\\t%0, %1%S3"
7305  [(set_attr "conds" "set")
7306   (set_attr "shift" "1")
7307   (set_attr "arch" "32,a,a")
7308   (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
7309
7310(define_insn "*arm_cmpsi_negshiftsi_si"
7311  [(set (reg:CC_Z CC_REGNUM)
7312	(compare:CC_Z
7313	 (neg:SI (match_operator:SI 1 "shift_operator"
7314		    [(match_operand:SI 2 "s_register_operand" "r")
7315		     (match_operand:SI 3 "reg_or_int_operand" "rM")]))
7316	 (match_operand:SI 0 "s_register_operand" "r")))]
7317  "TARGET_ARM"
7318  "cmn%?\\t%0, %2%S1"
7319  [(set_attr "conds" "set")
7320   (set (attr "type") (if_then_else (match_operand 3 "const_int_operand" "")
7321				    (const_string "alus_shift_imm")
7322				    (const_string "alus_shift_reg")))
7323   (set_attr "predicable" "yes")]
7324)
7325
7326;; DImode comparisons.  The generic code generates branches that
7327;; if-conversion can not reduce to a conditional compare, so we do
7328;; that directly.
7329
7330(define_insn_and_split "*arm_cmpdi_insn"
7331  [(set (reg:CC_NCV CC_REGNUM)
7332	(compare:CC_NCV (match_operand:DI 0 "s_register_operand" "r")
7333			(match_operand:DI 1 "arm_di_operand"	   "rDi")))
7334   (clobber (match_scratch:SI 2 "=r"))]
7335  "TARGET_32BIT"
7336  "#"   ; "cmp\\t%Q0, %Q1\;sbcs\\t%2, %R0, %R1"
7337  "&& reload_completed"
7338  [(set (reg:CC CC_REGNUM)
7339        (compare:CC (match_dup 0) (match_dup 1)))
7340   (parallel [(set (reg:CC CC_REGNUM)
7341                   (compare:CC (match_dup 3) (match_dup 4)))
7342              (set (match_dup 2)
7343                   (minus:SI (match_dup 5)
7344                            (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))])]
7345  {
7346    operands[3] = gen_highpart (SImode, operands[0]);
7347    operands[0] = gen_lowpart (SImode, operands[0]);
7348    if (CONST_INT_P (operands[1]))
7349      {
7350        operands[4] = GEN_INT (~INTVAL (gen_highpart_mode (SImode,
7351                                                           DImode,
7352                                                           operands[1])));
7353        operands[5] = gen_rtx_PLUS (SImode, operands[3], operands[4]);
7354      }
7355    else
7356      {
7357        operands[4] = gen_highpart (SImode, operands[1]);
7358        operands[5] = gen_rtx_MINUS (SImode, operands[3], operands[4]);
7359      }
7360    operands[1] = gen_lowpart (SImode, operands[1]);
7361    operands[2] = gen_lowpart (SImode, operands[2]);
7362  }
7363  [(set_attr "conds" "set")
7364   (set_attr "length" "8")
7365   (set_attr "type" "multiple")]
7366)
7367
7368(define_insn_and_split "*arm_cmpdi_unsigned"
7369  [(set (reg:CC_CZ CC_REGNUM)
7370        (compare:CC_CZ (match_operand:DI 0 "s_register_operand" "l,r,r,r")
7371                       (match_operand:DI 1 "arm_di_operand"     "Py,r,Di,rDi")))]
7372
7373  "TARGET_32BIT"
7374  "#"   ; "cmp\\t%R0, %R1\;it eq\;cmpeq\\t%Q0, %Q1"
7375  "&& reload_completed"
7376  [(set (reg:CC CC_REGNUM)
7377        (compare:CC (match_dup 2) (match_dup 3)))
7378   (cond_exec (eq:SI (reg:CC CC_REGNUM) (const_int 0))
7379              (set (reg:CC CC_REGNUM)
7380                   (compare:CC (match_dup 0) (match_dup 1))))]
7381  {
7382    operands[2] = gen_highpart (SImode, operands[0]);
7383    operands[0] = gen_lowpart (SImode, operands[0]);
7384    if (CONST_INT_P (operands[1]))
7385      operands[3] = gen_highpart_mode (SImode, DImode, operands[1]);
7386    else
7387      operands[3] = gen_highpart (SImode, operands[1]);
7388    operands[1] = gen_lowpart (SImode, operands[1]);
7389  }
7390  [(set_attr "conds" "set")
7391   (set_attr "enabled_for_short_it" "yes,yes,no,*")
7392   (set_attr "arch" "t2,t2,t2,a")
7393   (set_attr "length" "6,6,10,8")
7394   (set_attr "type" "multiple")]
7395)
7396
7397(define_insn "*arm_cmpdi_zero"
7398  [(set (reg:CC_Z CC_REGNUM)
7399	(compare:CC_Z (match_operand:DI 0 "s_register_operand" "r")
7400		      (const_int 0)))
7401   (clobber (match_scratch:SI 1 "=r"))]
7402  "TARGET_32BIT"
7403  "orrs%?\\t%1, %Q0, %R0"
7404  [(set_attr "conds" "set")
7405   (set_attr "type" "logics_reg")]
7406)
7407
7408; This insn allows redundant compares to be removed by cse, nothing should
7409; ever appear in the output file since (set (reg x) (reg x)) is a no-op that
7410; is deleted later on. The match_dup will match the mode here, so that
7411; mode changes of the condition codes aren't lost by this even though we don't
7412; specify what they are.
7413
7414(define_insn "*deleted_compare"
7415  [(set (match_operand 0 "cc_register" "") (match_dup 0))]
7416  "TARGET_32BIT"
7417  "\\t%@ deleted compare"
7418  [(set_attr "conds" "set")
7419   (set_attr "length" "0")
7420   (set_attr "type" "no_insn")]
7421)
7422
7423
7424;; Conditional branch insns
7425
7426(define_expand "cbranch_cc"
7427  [(set (pc)
7428	(if_then_else (match_operator 0 "" [(match_operand 1 "" "")
7429					    (match_operand 2 "" "")])
7430		      (label_ref (match_operand 3 "" ""))
7431		      (pc)))]
7432  "TARGET_32BIT"
7433  "operands[1] = arm_gen_compare_reg (GET_CODE (operands[0]),
7434				      operands[1], operands[2], NULL_RTX);
7435   operands[2] = const0_rtx;"
7436)
7437
7438;;
7439;; Patterns to match conditional branch insns.
7440;;
7441
7442(define_insn "arm_cond_branch"
7443  [(set (pc)
7444	(if_then_else (match_operator 1 "arm_comparison_operator"
7445		       [(match_operand 2 "cc_register" "") (const_int 0)])
7446		      (label_ref (match_operand 0 "" ""))
7447		      (pc)))]
7448  "TARGET_32BIT"
7449  "*
7450  if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
7451    {
7452      arm_ccfsm_state += 2;
7453      return \"\";
7454    }
7455  return \"b%d1\\t%l0\";
7456  "
7457  [(set_attr "conds" "use")
7458   (set_attr "type" "branch")
7459   (set (attr "length")
7460	(if_then_else
7461	   (and (match_test "TARGET_THUMB2")
7462		(and (ge (minus (match_dup 0) (pc)) (const_int -250))
7463		     (le (minus (match_dup 0) (pc)) (const_int 256))))
7464	   (const_int 2)
7465	   (const_int 4)))]
7466)
7467
7468(define_insn "*arm_cond_branch_reversed"
7469  [(set (pc)
7470	(if_then_else (match_operator 1 "arm_comparison_operator"
7471		       [(match_operand 2 "cc_register" "") (const_int 0)])
7472		      (pc)
7473		      (label_ref (match_operand 0 "" ""))))]
7474  "TARGET_32BIT"
7475  "*
7476  if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
7477    {
7478      arm_ccfsm_state += 2;
7479      return \"\";
7480    }
7481  return \"b%D1\\t%l0\";
7482  "
7483  [(set_attr "conds" "use")
7484   (set_attr "type" "branch")
7485   (set (attr "length")
7486	(if_then_else
7487	   (and (match_test "TARGET_THUMB2")
7488		(and (ge (minus (match_dup 0) (pc)) (const_int -250))
7489		     (le (minus (match_dup 0) (pc)) (const_int 256))))
7490	   (const_int 2)
7491	   (const_int 4)))]
7492)
7493
7494
7495
7496; scc insns
7497
7498(define_expand "cstore_cc"
7499  [(set (match_operand:SI 0 "s_register_operand" "")
7500	(match_operator:SI 1 "" [(match_operand 2 "" "")
7501				 (match_operand 3 "" "")]))]
7502  "TARGET_32BIT"
7503  "operands[2] = arm_gen_compare_reg (GET_CODE (operands[1]),
7504				      operands[2], operands[3], NULL_RTX);
7505   operands[3] = const0_rtx;"
7506)
7507
7508(define_insn_and_split "*mov_scc"
7509  [(set (match_operand:SI 0 "s_register_operand" "=r")
7510	(match_operator:SI 1 "arm_comparison_operator_mode"
7511	 [(match_operand 2 "cc_register" "") (const_int 0)]))]
7512  "TARGET_ARM"
7513  "#"   ; "mov%D1\\t%0, #0\;mov%d1\\t%0, #1"
7514  "TARGET_ARM"
7515  [(set (match_dup 0)
7516        (if_then_else:SI (match_dup 1)
7517                         (const_int 1)
7518                         (const_int 0)))]
7519  ""
7520  [(set_attr "conds" "use")
7521   (set_attr "length" "8")
7522   (set_attr "type" "multiple")]
7523)
7524
7525(define_insn_and_split "*mov_negscc"
7526  [(set (match_operand:SI 0 "s_register_operand" "=r")
7527	(neg:SI (match_operator:SI 1 "arm_comparison_operator_mode"
7528		 [(match_operand 2 "cc_register" "") (const_int 0)])))]
7529  "TARGET_ARM"
7530  "#"   ; "mov%D1\\t%0, #0\;mvn%d1\\t%0, #0"
7531  "TARGET_ARM"
7532  [(set (match_dup 0)
7533        (if_then_else:SI (match_dup 1)
7534                         (match_dup 3)
7535                         (const_int 0)))]
7536  {
7537    operands[3] = GEN_INT (~0);
7538  }
7539  [(set_attr "conds" "use")
7540   (set_attr "length" "8")
7541   (set_attr "type" "multiple")]
7542)
7543
7544(define_insn_and_split "*mov_notscc"
7545  [(set (match_operand:SI 0 "s_register_operand" "=r")
7546	(not:SI (match_operator:SI 1 "arm_comparison_operator"
7547		 [(match_operand 2 "cc_register" "") (const_int 0)])))]
7548  "TARGET_ARM"
7549  "#"   ; "mvn%D1\\t%0, #0\;mvn%d1\\t%0, #1"
7550  "TARGET_ARM"
7551  [(set (match_dup 0)
7552        (if_then_else:SI (match_dup 1)
7553                         (match_dup 3)
7554                         (match_dup 4)))]
7555  {
7556    operands[3] = GEN_INT (~1);
7557    operands[4] = GEN_INT (~0);
7558  }
7559  [(set_attr "conds" "use")
7560   (set_attr "length" "8")
7561   (set_attr "type" "multiple")]
7562)
7563
7564(define_expand "cstoresi4"
7565  [(set (match_operand:SI 0 "s_register_operand" "")
7566	(match_operator:SI 1 "expandable_comparison_operator"
7567	 [(match_operand:SI 2 "s_register_operand" "")
7568	  (match_operand:SI 3 "reg_or_int_operand" "")]))]
7569  "TARGET_32BIT || TARGET_THUMB1"
7570  "{
7571  rtx op3, scratch, scratch2;
7572
7573  if (!TARGET_THUMB1)
7574    {
7575      if (!arm_add_operand (operands[3], SImode))
7576	operands[3] = force_reg (SImode, operands[3]);
7577      emit_insn (gen_cstore_cc (operands[0], operands[1],
7578				operands[2], operands[3]));
7579      DONE;
7580    }
7581
7582  if (operands[3] == const0_rtx)
7583    {
7584      switch (GET_CODE (operands[1]))
7585	{
7586	case EQ:
7587	  emit_insn (gen_cstoresi_eq0_thumb1 (operands[0], operands[2]));
7588	  break;
7589
7590	case NE:
7591	  emit_insn (gen_cstoresi_ne0_thumb1 (operands[0], operands[2]));
7592	  break;
7593
7594	case LE:
7595          scratch = expand_binop (SImode, add_optab, operands[2], constm1_rtx,
7596				  NULL_RTX, 0, OPTAB_WIDEN);
7597          scratch = expand_binop (SImode, ior_optab, operands[2], scratch,
7598				  NULL_RTX, 0, OPTAB_WIDEN);
7599          expand_binop (SImode, lshr_optab, scratch, GEN_INT (31),
7600			operands[0], 1, OPTAB_WIDEN);
7601	  break;
7602
7603        case GE:
7604          scratch = expand_unop (SImode, one_cmpl_optab, operands[2],
7605				 NULL_RTX, 1);
7606          expand_binop (SImode, lshr_optab, scratch, GEN_INT (31),
7607			NULL_RTX, 1, OPTAB_WIDEN);
7608          break;
7609
7610        case GT:
7611          scratch = expand_binop (SImode, ashr_optab, operands[2],
7612				  GEN_INT (31), NULL_RTX, 0, OPTAB_WIDEN);
7613          scratch = expand_binop (SImode, sub_optab, scratch, operands[2],
7614				  NULL_RTX, 0, OPTAB_WIDEN);
7615          expand_binop (SImode, lshr_optab, scratch, GEN_INT (31), operands[0],
7616			0, OPTAB_WIDEN);
7617          break;
7618
7619	/* LT is handled by generic code.  No need for unsigned with 0.  */
7620	default:
7621	  FAIL;
7622	}
7623      DONE;
7624    }
7625
7626  switch (GET_CODE (operands[1]))
7627    {
7628    case EQ:
7629      scratch = expand_binop (SImode, sub_optab, operands[2], operands[3],
7630			      NULL_RTX, 0, OPTAB_WIDEN);
7631      emit_insn (gen_cstoresi_eq0_thumb1 (operands[0], scratch));
7632      break;
7633
7634    case NE:
7635      scratch = expand_binop (SImode, sub_optab, operands[2], operands[3],
7636			      NULL_RTX, 0, OPTAB_WIDEN);
7637      emit_insn (gen_cstoresi_ne0_thumb1 (operands[0], scratch));
7638      break;
7639
7640    case LE:
7641      op3 = force_reg (SImode, operands[3]);
7642
7643      scratch = expand_binop (SImode, lshr_optab, operands[2], GEN_INT (31),
7644			      NULL_RTX, 1, OPTAB_WIDEN);
7645      scratch2 = expand_binop (SImode, ashr_optab, op3, GEN_INT (31),
7646			      NULL_RTX, 0, OPTAB_WIDEN);
7647      emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch2,
7648					  op3, operands[2]));
7649      break;
7650
7651    case GE:
7652      op3 = operands[3];
7653      if (!thumb1_cmp_operand (op3, SImode))
7654        op3 = force_reg (SImode, op3);
7655      scratch = expand_binop (SImode, ashr_optab, operands[2], GEN_INT (31),
7656			      NULL_RTX, 0, OPTAB_WIDEN);
7657      scratch2 = expand_binop (SImode, lshr_optab, op3, GEN_INT (31),
7658			       NULL_RTX, 1, OPTAB_WIDEN);
7659      emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch2,
7660					  operands[2], op3));
7661      break;
7662
7663    case LEU:
7664      op3 = force_reg (SImode, operands[3]);
7665      scratch = force_reg (SImode, const0_rtx);
7666      emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch,
7667					  op3, operands[2]));
7668      break;
7669
7670    case GEU:
7671      op3 = operands[3];
7672      if (!thumb1_cmp_operand (op3, SImode))
7673        op3 = force_reg (SImode, op3);
7674      scratch = force_reg (SImode, const0_rtx);
7675      emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch,
7676					  operands[2], op3));
7677      break;
7678
7679    case LTU:
7680      op3 = operands[3];
7681      if (!thumb1_cmp_operand (op3, SImode))
7682        op3 = force_reg (SImode, op3);
7683      scratch = gen_reg_rtx (SImode);
7684      emit_insn (gen_cstoresi_ltu_thumb1 (operands[0], operands[2], op3));
7685      break;
7686
7687    case GTU:
7688      op3 = force_reg (SImode, operands[3]);
7689      scratch = gen_reg_rtx (SImode);
7690      emit_insn (gen_cstoresi_ltu_thumb1 (operands[0], op3, operands[2]));
7691      break;
7692
7693    /* No good sequences for GT, LT.  */
7694    default:
7695      FAIL;
7696    }
7697  DONE;
7698}")
7699
7700(define_expand "cstorehf4"
7701  [(set (match_operand:SI 0 "s_register_operand")
7702	(match_operator:SI 1 "expandable_comparison_operator"
7703	 [(match_operand:HF 2 "s_register_operand")
7704	  (match_operand:HF 3 "vfp_compare_operand")]))]
7705  "TARGET_VFP_FP16INST"
7706  {
7707    if (!arm_validize_comparison (&operands[1],
7708				  &operands[2],
7709				  &operands[3]))
7710       FAIL;
7711
7712    emit_insn (gen_cstore_cc (operands[0], operands[1],
7713			      operands[2], operands[3]));
7714    DONE;
7715  }
7716)
7717
7718(define_expand "cstoresf4"
7719  [(set (match_operand:SI 0 "s_register_operand" "")
7720	(match_operator:SI 1 "expandable_comparison_operator"
7721	 [(match_operand:SF 2 "s_register_operand" "")
7722	  (match_operand:SF 3 "vfp_compare_operand" "")]))]
7723  "TARGET_32BIT && TARGET_HARD_FLOAT"
7724  "emit_insn (gen_cstore_cc (operands[0], operands[1],
7725			     operands[2], operands[3])); DONE;"
7726)
7727
7728(define_expand "cstoredf4"
7729  [(set (match_operand:SI 0 "s_register_operand" "")
7730	(match_operator:SI 1 "expandable_comparison_operator"
7731	 [(match_operand:DF 2 "s_register_operand" "")
7732	  (match_operand:DF 3 "vfp_compare_operand" "")]))]
7733  "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
7734  "emit_insn (gen_cstore_cc (operands[0], operands[1],
7735			     operands[2], operands[3])); DONE;"
7736)
7737
7738(define_expand "cstoredi4"
7739  [(set (match_operand:SI 0 "s_register_operand" "")
7740	(match_operator:SI 1 "expandable_comparison_operator"
7741	 [(match_operand:DI 2 "s_register_operand" "")
7742	  (match_operand:DI 3 "cmpdi_operand" "")]))]
7743  "TARGET_32BIT"
7744  "{
7745     if (!arm_validize_comparison (&operands[1],
7746     				   &operands[2],
7747				   &operands[3]))
7748       FAIL;
7749     emit_insn (gen_cstore_cc (operands[0], operands[1], operands[2],
7750		      	         operands[3]));
7751     DONE;
7752   }"
7753)
7754
7755
7756;; Conditional move insns
7757
7758(define_expand "movsicc"
7759  [(set (match_operand:SI 0 "s_register_operand" "")
7760	(if_then_else:SI (match_operand 1 "expandable_comparison_operator" "")
7761			 (match_operand:SI 2 "arm_not_operand" "")
7762			 (match_operand:SI 3 "arm_not_operand" "")))]
7763  "TARGET_32BIT"
7764  "
7765  {
7766    enum rtx_code code;
7767    rtx ccreg;
7768
7769    if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
7770				  &XEXP (operands[1], 1)))
7771      FAIL;
7772
7773    code = GET_CODE (operands[1]);
7774    ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
7775				 XEXP (operands[1], 1), NULL_RTX);
7776    operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7777  }"
7778)
7779
7780(define_expand "movhfcc"
7781  [(set (match_operand:HF 0 "s_register_operand")
7782	(if_then_else:HF (match_operand 1 "arm_cond_move_operator")
7783			 (match_operand:HF 2 "s_register_operand")
7784			 (match_operand:HF 3 "s_register_operand")))]
7785  "TARGET_VFP_FP16INST"
7786  "
7787  {
7788    enum rtx_code code = GET_CODE (operands[1]);
7789    rtx ccreg;
7790
7791    if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
7792				  &XEXP (operands[1], 1)))
7793      FAIL;
7794
7795    code = GET_CODE (operands[1]);
7796    ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
7797				 XEXP (operands[1], 1), NULL_RTX);
7798    operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7799  }"
7800)
7801
7802(define_expand "movsfcc"
7803  [(set (match_operand:SF 0 "s_register_operand" "")
7804	(if_then_else:SF (match_operand 1 "arm_cond_move_operator" "")
7805			 (match_operand:SF 2 "s_register_operand" "")
7806			 (match_operand:SF 3 "s_register_operand" "")))]
7807  "TARGET_32BIT && TARGET_HARD_FLOAT"
7808  "
7809  {
7810    enum rtx_code code = GET_CODE (operands[1]);
7811    rtx ccreg;
7812
7813    if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
7814       				  &XEXP (operands[1], 1)))
7815       FAIL;
7816
7817    code = GET_CODE (operands[1]);
7818    ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
7819				 XEXP (operands[1], 1), NULL_RTX);
7820    operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7821  }"
7822)
7823
7824(define_expand "movdfcc"
7825  [(set (match_operand:DF 0 "s_register_operand" "")
7826	(if_then_else:DF (match_operand 1 "arm_cond_move_operator" "")
7827			 (match_operand:DF 2 "s_register_operand" "")
7828			 (match_operand:DF 3 "s_register_operand" "")))]
7829  "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
7830  "
7831  {
7832    enum rtx_code code = GET_CODE (operands[1]);
7833    rtx ccreg;
7834
7835    if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
7836       				  &XEXP (operands[1], 1)))
7837       FAIL;
7838    code = GET_CODE (operands[1]);
7839    ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
7840				 XEXP (operands[1], 1), NULL_RTX);
7841    operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7842  }"
7843)
7844
7845(define_insn "*cmov<mode>"
7846    [(set (match_operand:SDF 0 "s_register_operand" "=<F_constraint>")
7847	(if_then_else:SDF (match_operator 1 "arm_vsel_comparison_operator"
7848			  [(match_operand 2 "cc_register" "") (const_int 0)])
7849			  (match_operand:SDF 3 "s_register_operand"
7850			                      "<F_constraint>")
7851			  (match_operand:SDF 4 "s_register_operand"
7852			                      "<F_constraint>")))]
7853  "TARGET_HARD_FLOAT && TARGET_VFP5 <vfp_double_cond>"
7854  "*
7855  {
7856    enum arm_cond_code code = maybe_get_arm_condition_code (operands[1]);
7857    switch (code)
7858      {
7859      case ARM_GE:
7860      case ARM_GT:
7861      case ARM_EQ:
7862      case ARM_VS:
7863        return \"vsel%d1.<V_if_elem>\\t%<V_reg>0, %<V_reg>3, %<V_reg>4\";
7864      case ARM_LT:
7865      case ARM_LE:
7866      case ARM_NE:
7867      case ARM_VC:
7868        return \"vsel%D1.<V_if_elem>\\t%<V_reg>0, %<V_reg>4, %<V_reg>3\";
7869      default:
7870        gcc_unreachable ();
7871      }
7872    return \"\";
7873  }"
7874  [(set_attr "conds" "use")
7875   (set_attr "type" "fcsel")]
7876)
7877
7878(define_insn "*cmovhf"
7879    [(set (match_operand:HF 0 "s_register_operand" "=t")
7880	(if_then_else:HF (match_operator 1 "arm_vsel_comparison_operator"
7881			 [(match_operand 2 "cc_register" "") (const_int 0)])
7882			  (match_operand:HF 3 "s_register_operand" "t")
7883			  (match_operand:HF 4 "s_register_operand" "t")))]
7884  "TARGET_VFP_FP16INST"
7885  "*
7886  {
7887    enum arm_cond_code code = maybe_get_arm_condition_code (operands[1]);
7888    switch (code)
7889      {
7890      case ARM_GE:
7891      case ARM_GT:
7892      case ARM_EQ:
7893      case ARM_VS:
7894	return \"vsel%d1.f16\\t%0, %3, %4\";
7895      case ARM_LT:
7896      case ARM_LE:
7897      case ARM_NE:
7898      case ARM_VC:
7899	return \"vsel%D1.f16\\t%0, %4, %3\";
7900      default:
7901	gcc_unreachable ();
7902      }
7903    return \"\";
7904  }"
7905  [(set_attr "conds" "use")
7906   (set_attr "type" "fcsel")]
7907)
7908
7909(define_insn_and_split "*movsicc_insn"
7910  [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r,r,r,r,r")
7911	(if_then_else:SI
7912	 (match_operator 3 "arm_comparison_operator"
7913	  [(match_operand 4 "cc_register" "") (const_int 0)])
7914	 (match_operand:SI 1 "arm_not_operand" "0,0,rI,K,rI,rI,K,K")
7915	 (match_operand:SI 2 "arm_not_operand" "rI,K,0,0,rI,K,rI,K")))]
7916  "TARGET_ARM"
7917  "@
7918   mov%D3\\t%0, %2
7919   mvn%D3\\t%0, #%B2
7920   mov%d3\\t%0, %1
7921   mvn%d3\\t%0, #%B1
7922   #
7923   #
7924   #
7925   #"
7926   ; alt4: mov%d3\\t%0, %1\;mov%D3\\t%0, %2
7927   ; alt5: mov%d3\\t%0, %1\;mvn%D3\\t%0, #%B2
7928   ; alt6: mvn%d3\\t%0, #%B1\;mov%D3\\t%0, %2
7929   ; alt7: mvn%d3\\t%0, #%B1\;mvn%D3\\t%0, #%B2"
7930  "&& reload_completed"
7931  [(const_int 0)]
7932  {
7933    enum rtx_code rev_code;
7934    machine_mode mode;
7935    rtx rev_cond;
7936
7937    emit_insn (gen_rtx_COND_EXEC (VOIDmode,
7938                                  operands[3],
7939                                  gen_rtx_SET (operands[0], operands[1])));
7940
7941    rev_code = GET_CODE (operands[3]);
7942    mode = GET_MODE (operands[4]);
7943    if (mode == CCFPmode || mode == CCFPEmode)
7944      rev_code = reverse_condition_maybe_unordered (rev_code);
7945    else
7946      rev_code = reverse_condition (rev_code);
7947
7948    rev_cond = gen_rtx_fmt_ee (rev_code,
7949                               VOIDmode,
7950                               operands[4],
7951                               const0_rtx);
7952    emit_insn (gen_rtx_COND_EXEC (VOIDmode,
7953                                  rev_cond,
7954                                  gen_rtx_SET (operands[0], operands[2])));
7955    DONE;
7956  }
7957  [(set_attr "length" "4,4,4,4,8,8,8,8")
7958   (set_attr "conds" "use")
7959   (set_attr_alternative "type"
7960                         [(if_then_else (match_operand 2 "const_int_operand" "")
7961                                        (const_string "mov_imm")
7962                                        (const_string "mov_reg"))
7963                          (const_string "mvn_imm")
7964                          (if_then_else (match_operand 1 "const_int_operand" "")
7965                                        (const_string "mov_imm")
7966                                        (const_string "mov_reg"))
7967                          (const_string "mvn_imm")
7968                          (const_string "multiple")
7969                          (const_string "multiple")
7970                          (const_string "multiple")
7971                          (const_string "multiple")])]
7972)
7973
7974(define_insn "*movsfcc_soft_insn"
7975  [(set (match_operand:SF 0 "s_register_operand" "=r,r")
7976	(if_then_else:SF (match_operator 3 "arm_comparison_operator"
7977			  [(match_operand 4 "cc_register" "") (const_int 0)])
7978			 (match_operand:SF 1 "s_register_operand" "0,r")
7979			 (match_operand:SF 2 "s_register_operand" "r,0")))]
7980  "TARGET_ARM && TARGET_SOFT_FLOAT"
7981  "@
7982   mov%D3\\t%0, %2
7983   mov%d3\\t%0, %1"
7984  [(set_attr "conds" "use")
7985   (set_attr "type" "mov_reg")]
7986)
7987
7988
7989;; Jump and linkage insns
7990
7991(define_expand "jump"
7992  [(set (pc)
7993	(label_ref (match_operand 0 "" "")))]
7994  "TARGET_EITHER"
7995  ""
7996)
7997
7998(define_insn "*arm_jump"
7999  [(set (pc)
8000	(label_ref (match_operand 0 "" "")))]
8001  "TARGET_32BIT"
8002  "*
8003  {
8004    if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
8005      {
8006        arm_ccfsm_state += 2;
8007        return \"\";
8008      }
8009    return \"b%?\\t%l0\";
8010  }
8011  "
8012  [(set_attr "predicable" "yes")
8013   (set (attr "length")
8014	(if_then_else
8015	   (and (match_test "TARGET_THUMB2")
8016		(and (ge (minus (match_dup 0) (pc)) (const_int -2044))
8017		     (le (minus (match_dup 0) (pc)) (const_int 2048))))
8018	   (const_int 2)
8019	   (const_int 4)))
8020   (set_attr "type" "branch")]
8021)
8022
8023(define_expand "call"
8024  [(parallel [(call (match_operand 0 "memory_operand" "")
8025	            (match_operand 1 "general_operand" ""))
8026	      (use (match_operand 2 "" ""))
8027	      (clobber (reg:SI LR_REGNUM))])]
8028  "TARGET_EITHER"
8029  "
8030  {
8031    rtx callee, pat;
8032    tree addr = MEM_EXPR (operands[0]);
8033
8034    /* In an untyped call, we can get NULL for operand 2.  */
8035    if (operands[2] == NULL_RTX)
8036      operands[2] = const0_rtx;
8037
8038    /* Decide if we should generate indirect calls by loading the
8039       32-bit address of the callee into a register before performing the
8040       branch and link.  */
8041    callee = XEXP (operands[0], 0);
8042    if (GET_CODE (callee) == SYMBOL_REF
8043	? arm_is_long_call_p (SYMBOL_REF_DECL (callee))
8044	: !REG_P (callee))
8045      XEXP (operands[0], 0) = force_reg (Pmode, callee);
8046
8047    if (detect_cmse_nonsecure_call (addr))
8048      {
8049	pat = gen_nonsecure_call_internal (operands[0], operands[1],
8050					   operands[2]);
8051	emit_call_insn (pat);
8052      }
8053    else
8054      {
8055	pat = gen_call_internal (operands[0], operands[1], operands[2]);
8056	arm_emit_call_insn (pat, XEXP (operands[0], 0), false);
8057      }
8058    DONE;
8059  }"
8060)
8061
8062(define_expand "call_internal"
8063  [(parallel [(call (match_operand 0 "memory_operand" "")
8064	            (match_operand 1 "general_operand" ""))
8065	      (use (match_operand 2 "" ""))
8066	      (clobber (reg:SI LR_REGNUM))])])
8067
8068(define_expand "nonsecure_call_internal"
8069  [(parallel [(call (unspec:SI [(match_operand 0 "memory_operand" "")]
8070			       UNSPEC_NONSECURE_MEM)
8071		    (match_operand 1 "general_operand" ""))
8072	      (use (match_operand 2 "" ""))
8073	      (clobber (reg:SI LR_REGNUM))])]
8074  "use_cmse"
8075  "
8076  {
8077    rtx tmp;
8078    tmp = copy_to_suggested_reg (XEXP (operands[0], 0),
8079				 gen_rtx_REG (SImode, R4_REGNUM),
8080				 SImode);
8081
8082    operands[0] = replace_equiv_address (operands[0], tmp);
8083  }")
8084
8085(define_insn "*call_reg_armv5"
8086  [(call (mem:SI (match_operand:SI 0 "s_register_operand" "r"))
8087         (match_operand 1 "" ""))
8088   (use (match_operand 2 "" ""))
8089   (clobber (reg:SI LR_REGNUM))]
8090  "TARGET_ARM && arm_arch5 && !SIBLING_CALL_P (insn)"
8091  "blx%?\\t%0"
8092  [(set_attr "type" "call")]
8093)
8094
8095(define_insn "*call_reg_arm"
8096  [(call (mem:SI (match_operand:SI 0 "s_register_operand" "r"))
8097         (match_operand 1 "" ""))
8098   (use (match_operand 2 "" ""))
8099   (clobber (reg:SI LR_REGNUM))]
8100  "TARGET_ARM && !arm_arch5 && !SIBLING_CALL_P (insn)"
8101  "*
8102  return output_call (operands);
8103  "
8104  ;; length is worst case, normally it is only two
8105  [(set_attr "length" "12")
8106   (set_attr "type" "call")]
8107)
8108
8109
8110(define_expand "call_value"
8111  [(parallel [(set (match_operand       0 "" "")
8112	           (call (match_operand 1 "memory_operand" "")
8113		         (match_operand 2 "general_operand" "")))
8114	      (use (match_operand 3 "" ""))
8115	      (clobber (reg:SI LR_REGNUM))])]
8116  "TARGET_EITHER"
8117  "
8118  {
8119    rtx pat, callee;
8120    tree addr = MEM_EXPR (operands[1]);
8121
8122    /* In an untyped call, we can get NULL for operand 2.  */
8123    if (operands[3] == 0)
8124      operands[3] = const0_rtx;
8125
8126    /* Decide if we should generate indirect calls by loading the
8127       32-bit address of the callee into a register before performing the
8128       branch and link.  */
8129    callee = XEXP (operands[1], 0);
8130    if (GET_CODE (callee) == SYMBOL_REF
8131	? arm_is_long_call_p (SYMBOL_REF_DECL (callee))
8132	: !REG_P (callee))
8133      XEXP (operands[1], 0) = force_reg (Pmode, callee);
8134
8135    if (detect_cmse_nonsecure_call (addr))
8136      {
8137	pat = gen_nonsecure_call_value_internal (operands[0], operands[1],
8138						 operands[2], operands[3]);
8139	emit_call_insn (pat);
8140      }
8141    else
8142      {
8143	pat = gen_call_value_internal (operands[0], operands[1],
8144				       operands[2], operands[3]);
8145	arm_emit_call_insn (pat, XEXP (operands[1], 0), false);
8146      }
8147    DONE;
8148  }"
8149)
8150
8151(define_expand "call_value_internal"
8152  [(parallel [(set (match_operand       0 "" "")
8153	           (call (match_operand 1 "memory_operand" "")
8154		         (match_operand 2 "general_operand" "")))
8155	      (use (match_operand 3 "" ""))
8156	      (clobber (reg:SI LR_REGNUM))])])
8157
8158(define_expand "nonsecure_call_value_internal"
8159  [(parallel [(set (match_operand       0 "" "")
8160		   (call (unspec:SI [(match_operand 1 "memory_operand" "")]
8161				    UNSPEC_NONSECURE_MEM)
8162			 (match_operand 2 "general_operand" "")))
8163	      (use (match_operand 3 "" ""))
8164	      (clobber (reg:SI LR_REGNUM))])]
8165  "use_cmse"
8166  "
8167  {
8168    rtx tmp;
8169    tmp = copy_to_suggested_reg (XEXP (operands[1], 0),
8170				 gen_rtx_REG (SImode, R4_REGNUM),
8171				 SImode);
8172
8173    operands[1] = replace_equiv_address (operands[1], tmp);
8174  }")
8175
8176(define_insn "*call_value_reg_armv5"
8177  [(set (match_operand 0 "" "")
8178        (call (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
8179	      (match_operand 2 "" "")))
8180   (use (match_operand 3 "" ""))
8181   (clobber (reg:SI LR_REGNUM))]
8182  "TARGET_ARM && arm_arch5 && !SIBLING_CALL_P (insn)"
8183  "blx%?\\t%1"
8184  [(set_attr "type" "call")]
8185)
8186
8187(define_insn "*call_value_reg_arm"
8188  [(set (match_operand 0 "" "")
8189        (call (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
8190	      (match_operand 2 "" "")))
8191   (use (match_operand 3 "" ""))
8192   (clobber (reg:SI LR_REGNUM))]
8193  "TARGET_ARM && !arm_arch5 && !SIBLING_CALL_P (insn)"
8194  "*
8195  return output_call (&operands[1]);
8196  "
8197  [(set_attr "length" "12")
8198   (set_attr "type" "call")]
8199)
8200
8201;; Allow calls to SYMBOL_REFs specially as they are not valid general addresses
8202;; The 'a' causes the operand to be treated as an address, i.e. no '#' output.
8203
8204(define_insn "*call_symbol"
8205  [(call (mem:SI (match_operand:SI 0 "" ""))
8206	 (match_operand 1 "" ""))
8207   (use (match_operand 2 "" ""))
8208   (clobber (reg:SI LR_REGNUM))]
8209  "TARGET_32BIT
8210   && !SIBLING_CALL_P (insn)
8211   && (GET_CODE (operands[0]) == SYMBOL_REF)
8212   && !arm_is_long_call_p (SYMBOL_REF_DECL (operands[0]))"
8213  "*
8214  {
8215   rtx op = operands[0];
8216
8217   /* Switch mode now when possible.  */
8218   if (SYMBOL_REF_DECL (op) && !TREE_PUBLIC (SYMBOL_REF_DECL (op))
8219        && arm_arch5 && arm_change_mode_p (SYMBOL_REF_DECL (op)))
8220      return NEED_PLT_RELOC ? \"blx%?\\t%a0(PLT)\" : \"blx%?\\t(%a0)\";
8221
8222    return NEED_PLT_RELOC ? \"bl%?\\t%a0(PLT)\" : \"bl%?\\t%a0\";
8223  }"
8224  [(set_attr "type" "call")]
8225)
8226
8227(define_insn "*call_value_symbol"
8228  [(set (match_operand 0 "" "")
8229	(call (mem:SI (match_operand:SI 1 "" ""))
8230	(match_operand:SI 2 "" "")))
8231   (use (match_operand 3 "" ""))
8232   (clobber (reg:SI LR_REGNUM))]
8233  "TARGET_32BIT
8234   && !SIBLING_CALL_P (insn)
8235   && (GET_CODE (operands[1]) == SYMBOL_REF)
8236   && !arm_is_long_call_p (SYMBOL_REF_DECL (operands[1]))"
8237  "*
8238  {
8239   rtx op = operands[1];
8240
8241   /* Switch mode now when possible.  */
8242   if (SYMBOL_REF_DECL (op) && !TREE_PUBLIC (SYMBOL_REF_DECL (op))
8243        && arm_arch5 && arm_change_mode_p (SYMBOL_REF_DECL (op)))
8244      return NEED_PLT_RELOC ? \"blx%?\\t%a1(PLT)\" : \"blx%?\\t(%a1)\";
8245
8246    return NEED_PLT_RELOC ? \"bl%?\\t%a1(PLT)\" : \"bl%?\\t%a1\";
8247  }"
8248  [(set_attr "type" "call")]
8249)
8250
8251(define_expand "sibcall_internal"
8252  [(parallel [(call (match_operand 0 "memory_operand" "")
8253		    (match_operand 1 "general_operand" ""))
8254	      (return)
8255	      (use (match_operand 2 "" ""))])])
8256
8257;; We may also be able to do sibcalls for Thumb, but it's much harder...
8258(define_expand "sibcall"
8259  [(parallel [(call (match_operand 0 "memory_operand" "")
8260		    (match_operand 1 "general_operand" ""))
8261	      (return)
8262	      (use (match_operand 2 "" ""))])]
8263  "TARGET_32BIT"
8264  "
8265  {
8266    rtx pat;
8267
8268    if ((!REG_P (XEXP (operands[0], 0))
8269	 && GET_CODE (XEXP (operands[0], 0)) != SYMBOL_REF)
8270	|| (GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
8271	    && arm_is_long_call_p (SYMBOL_REF_DECL (XEXP (operands[0], 0)))))
8272     XEXP (operands[0], 0) = force_reg (SImode, XEXP (operands[0], 0));
8273
8274    if (operands[2] == NULL_RTX)
8275      operands[2] = const0_rtx;
8276
8277    pat = gen_sibcall_internal (operands[0], operands[1], operands[2]);
8278    arm_emit_call_insn (pat, operands[0], true);
8279    DONE;
8280  }"
8281)
8282
8283(define_expand "sibcall_value_internal"
8284  [(parallel [(set (match_operand 0 "" "")
8285		   (call (match_operand 1 "memory_operand" "")
8286			 (match_operand 2 "general_operand" "")))
8287	      (return)
8288	      (use (match_operand 3 "" ""))])])
8289
8290(define_expand "sibcall_value"
8291  [(parallel [(set (match_operand 0 "" "")
8292		   (call (match_operand 1 "memory_operand" "")
8293			 (match_operand 2 "general_operand" "")))
8294	      (return)
8295	      (use (match_operand 3 "" ""))])]
8296  "TARGET_32BIT"
8297  "
8298  {
8299    rtx pat;
8300
8301    if ((!REG_P (XEXP (operands[1], 0))
8302	 && GET_CODE (XEXP (operands[1], 0)) != SYMBOL_REF)
8303	|| (GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
8304	    && arm_is_long_call_p (SYMBOL_REF_DECL (XEXP (operands[1], 0)))))
8305     XEXP (operands[1], 0) = force_reg (SImode, XEXP (operands[1], 0));
8306
8307    if (operands[3] == NULL_RTX)
8308      operands[3] = const0_rtx;
8309
8310    pat = gen_sibcall_value_internal (operands[0], operands[1],
8311                                      operands[2], operands[3]);
8312    arm_emit_call_insn (pat, operands[1], true);
8313    DONE;
8314  }"
8315)
8316
8317(define_insn "*sibcall_insn"
8318 [(call (mem:SI (match_operand:SI 0 "call_insn_operand" "Cs, US"))
8319	(match_operand 1 "" ""))
8320  (return)
8321  (use (match_operand 2 "" ""))]
8322  "TARGET_32BIT && SIBLING_CALL_P (insn)"
8323  "*
8324  if (which_alternative == 1)
8325    return NEED_PLT_RELOC ? \"b%?\\t%a0(PLT)\" : \"b%?\\t%a0\";
8326  else
8327    {
8328      if (arm_arch5 || arm_arch4t)
8329	return \"bx%?\\t%0\\t%@ indirect register sibling call\";
8330      else
8331	return \"mov%?\\t%|pc, %0\\t%@ indirect register sibling call\";
8332    }
8333  "
8334  [(set_attr "type" "call")]
8335)
8336
8337(define_insn "*sibcall_value_insn"
8338 [(set (match_operand 0 "" "")
8339       (call (mem:SI (match_operand:SI 1 "call_insn_operand" "Cs,US"))
8340	     (match_operand 2 "" "")))
8341  (return)
8342  (use (match_operand 3 "" ""))]
8343  "TARGET_32BIT && SIBLING_CALL_P (insn)"
8344  "*
8345  if (which_alternative == 1)
8346   return NEED_PLT_RELOC ? \"b%?\\t%a1(PLT)\" : \"b%?\\t%a1\";
8347  else
8348    {
8349      if (arm_arch5 || arm_arch4t)
8350	return \"bx%?\\t%1\";
8351      else
8352	return \"mov%?\\t%|pc, %1\\t@ indirect sibling call \";
8353    }
8354  "
8355  [(set_attr "type" "call")]
8356)
8357
8358(define_expand "<return_str>return"
8359  [(RETURNS)]
8360  "(TARGET_ARM || (TARGET_THUMB2
8361                   && ARM_FUNC_TYPE (arm_current_func_type ()) == ARM_FT_NORMAL
8362                   && !IS_STACKALIGN (arm_current_func_type ())))
8363    <return_cond_false>"
8364  "
8365  {
8366    if (TARGET_THUMB2)
8367      {
8368        thumb2_expand_return (<return_simple_p>);
8369        DONE;
8370      }
8371  }
8372  "
8373)
8374
8375;; Often the return insn will be the same as loading from memory, so set attr
8376(define_insn "*arm_return"
8377  [(return)]
8378  "TARGET_ARM && USE_RETURN_INSN (FALSE)"
8379  "*
8380  {
8381    if (arm_ccfsm_state == 2)
8382      {
8383        arm_ccfsm_state += 2;
8384        return \"\";
8385      }
8386    return output_return_instruction (const_true_rtx, true, false, false);
8387  }"
8388  [(set_attr "type" "load_4")
8389   (set_attr "length" "12")
8390   (set_attr "predicable" "yes")]
8391)
8392
8393(define_insn "*cond_<return_str>return"
8394  [(set (pc)
8395        (if_then_else (match_operator 0 "arm_comparison_operator"
8396		       [(match_operand 1 "cc_register" "") (const_int 0)])
8397                      (RETURNS)
8398                      (pc)))]
8399  "TARGET_ARM  <return_cond_true>"
8400  "*
8401  {
8402    if (arm_ccfsm_state == 2)
8403      {
8404        arm_ccfsm_state += 2;
8405        return \"\";
8406      }
8407    return output_return_instruction (operands[0], true, false,
8408				      <return_simple_p>);
8409  }"
8410  [(set_attr "conds" "use")
8411   (set_attr "length" "12")
8412   (set_attr "type" "load_4")]
8413)
8414
8415(define_insn "*cond_<return_str>return_inverted"
8416  [(set (pc)
8417        (if_then_else (match_operator 0 "arm_comparison_operator"
8418		       [(match_operand 1 "cc_register" "") (const_int 0)])
8419                      (pc)
8420		      (RETURNS)))]
8421  "TARGET_ARM <return_cond_true>"
8422  "*
8423  {
8424    if (arm_ccfsm_state == 2)
8425      {
8426        arm_ccfsm_state += 2;
8427        return \"\";
8428      }
8429    return output_return_instruction (operands[0], true, true,
8430				      <return_simple_p>);
8431  }"
8432  [(set_attr "conds" "use")
8433   (set_attr "length" "12")
8434   (set_attr "type" "load_4")]
8435)
8436
8437(define_insn "*arm_simple_return"
8438  [(simple_return)]
8439  "TARGET_ARM"
8440  "*
8441  {
8442    if (arm_ccfsm_state == 2)
8443      {
8444        arm_ccfsm_state += 2;
8445        return \"\";
8446      }
8447    return output_return_instruction (const_true_rtx, true, false, true);
8448  }"
8449  [(set_attr "type" "branch")
8450   (set_attr "length" "4")
8451   (set_attr "predicable" "yes")]
8452)
8453
8454;; Generate a sequence of instructions to determine if the processor is
8455;; in 26-bit or 32-bit mode, and return the appropriate return address
8456;; mask.
8457
8458(define_expand "return_addr_mask"
8459  [(set (match_dup 1)
8460      (compare:CC_NOOV (unspec [(const_int 0)] UNSPEC_CHECK_ARCH)
8461		       (const_int 0)))
8462   (set (match_operand:SI 0 "s_register_operand" "")
8463      (if_then_else:SI (eq (match_dup 1) (const_int 0))
8464		       (const_int -1)
8465		       (const_int 67108860)))] ; 0x03fffffc
8466  "TARGET_ARM"
8467  "
8468  operands[1] = gen_rtx_REG (CC_NOOVmode, CC_REGNUM);
8469  ")
8470
8471(define_insn "*check_arch2"
8472  [(set (match_operand:CC_NOOV 0 "cc_register" "")
8473      (compare:CC_NOOV (unspec [(const_int 0)] UNSPEC_CHECK_ARCH)
8474		       (const_int 0)))]
8475  "TARGET_ARM"
8476  "teq\\t%|r0, %|r0\;teq\\t%|pc, %|pc"
8477  [(set_attr "length" "8")
8478   (set_attr "conds" "set")
8479   (set_attr "type" "multiple")]
8480)
8481
8482;; Call subroutine returning any type.
8483
8484(define_expand "untyped_call"
8485  [(parallel [(call (match_operand 0 "" "")
8486		    (const_int 0))
8487	      (match_operand 1 "" "")
8488	      (match_operand 2 "" "")])]
8489  "TARGET_EITHER"
8490  "
8491  {
8492    int i;
8493    rtx par = gen_rtx_PARALLEL (VOIDmode,
8494				rtvec_alloc (XVECLEN (operands[2], 0)));
8495    rtx addr = gen_reg_rtx (Pmode);
8496    rtx mem;
8497    int size = 0;
8498
8499    emit_move_insn (addr, XEXP (operands[1], 0));
8500    mem = change_address (operands[1], BLKmode, addr);
8501
8502    for (i = 0; i < XVECLEN (operands[2], 0); i++)
8503      {
8504	rtx src = SET_SRC (XVECEXP (operands[2], 0, i));
8505
8506	/* Default code only uses r0 as a return value, but we could
8507	   be using anything up to 4 registers.  */
8508	if (REGNO (src) == R0_REGNUM)
8509	  src = gen_rtx_REG (TImode, R0_REGNUM);
8510
8511        XVECEXP (par, 0, i) = gen_rtx_EXPR_LIST (VOIDmode, src,
8512						 GEN_INT (size));
8513        size += GET_MODE_SIZE (GET_MODE (src));
8514      }
8515
8516    emit_call_insn (gen_call_value (par, operands[0], const0_rtx, NULL));
8517
8518    size = 0;
8519
8520    for (i = 0; i < XVECLEN (par, 0); i++)
8521      {
8522	HOST_WIDE_INT offset = 0;
8523	rtx reg = XEXP (XVECEXP (par, 0, i), 0);
8524
8525	if (size != 0)
8526	  emit_move_insn (addr, plus_constant (Pmode, addr, size));
8527
8528	mem = change_address (mem, GET_MODE (reg), NULL);
8529	if (REGNO (reg) == R0_REGNUM)
8530	  {
8531	    /* On thumb we have to use a write-back instruction.  */
8532	    emit_insn (arm_gen_store_multiple (arm_regs_in_sequence, 4, addr,
8533 		       TARGET_THUMB ? TRUE : FALSE, mem, &offset));
8534	    size = TARGET_ARM ? 16 : 0;
8535	  }
8536	else
8537	  {
8538	    emit_move_insn (mem, reg);
8539	    size = GET_MODE_SIZE (GET_MODE (reg));
8540	  }
8541      }
8542
8543    /* The optimizer does not know that the call sets the function value
8544       registers we stored in the result block.  We avoid problems by
8545       claiming that all hard registers are used and clobbered at this
8546       point.  */
8547    emit_insn (gen_blockage ());
8548
8549    DONE;
8550  }"
8551)
8552
8553(define_expand "untyped_return"
8554  [(match_operand:BLK 0 "memory_operand" "")
8555   (match_operand 1 "" "")]
8556  "TARGET_EITHER"
8557  "
8558  {
8559    int i;
8560    rtx addr = gen_reg_rtx (Pmode);
8561    rtx mem;
8562    int size = 0;
8563
8564    emit_move_insn (addr, XEXP (operands[0], 0));
8565    mem = change_address (operands[0], BLKmode, addr);
8566
8567    for (i = 0; i < XVECLEN (operands[1], 0); i++)
8568      {
8569	HOST_WIDE_INT offset = 0;
8570	rtx reg = SET_DEST (XVECEXP (operands[1], 0, i));
8571
8572	if (size != 0)
8573	  emit_move_insn (addr, plus_constant (Pmode, addr, size));
8574
8575	mem = change_address (mem, GET_MODE (reg), NULL);
8576	if (REGNO (reg) == R0_REGNUM)
8577	  {
8578	    /* On thumb we have to use a write-back instruction.  */
8579	    emit_insn (arm_gen_load_multiple (arm_regs_in_sequence, 4, addr,
8580 		       TARGET_THUMB ? TRUE : FALSE, mem, &offset));
8581	    size = TARGET_ARM ? 16 : 0;
8582	  }
8583	else
8584	  {
8585	    emit_move_insn (reg, mem);
8586	    size = GET_MODE_SIZE (GET_MODE (reg));
8587	  }
8588      }
8589
8590    /* Emit USE insns before the return.  */
8591    for (i = 0; i < XVECLEN (operands[1], 0); i++)
8592      emit_use (SET_DEST (XVECEXP (operands[1], 0, i)));
8593
8594    /* Construct the return.  */
8595    expand_naked_return ();
8596
8597    DONE;
8598  }"
8599)
8600
8601;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
8602;; all of memory.  This blocks insns from being moved across this point.
8603
8604(define_insn "blockage"
8605  [(unspec_volatile [(const_int 0)] VUNSPEC_BLOCKAGE)]
8606  "TARGET_EITHER"
8607  ""
8608  [(set_attr "length" "0")
8609   (set_attr "type" "block")]
8610)
8611
8612;; Since we hard code r0 here use the 'o' constraint to prevent
8613;; provoking undefined behaviour in the hardware with putting out
8614;; auto-increment operations with potentially r0 as the base register.
8615(define_insn "probe_stack"
8616  [(set (match_operand:SI 0 "memory_operand" "=o")
8617        (unspec:SI [(const_int 0)] UNSPEC_PROBE_STACK))]
8618  "TARGET_32BIT"
8619  "str%?\\tr0, %0"
8620  [(set_attr "type" "store_4")
8621   (set_attr "predicable" "yes")]
8622)
8623
8624(define_insn "probe_stack_range"
8625  [(set (match_operand:SI 0 "register_operand" "=r")
8626	(unspec_volatile:SI [(match_operand:SI 1 "register_operand" "0")
8627			     (match_operand:SI 2 "register_operand" "r")]
8628			     VUNSPEC_PROBE_STACK_RANGE))]
8629  "TARGET_32BIT"
8630{
8631  return output_probe_stack_range (operands[0], operands[2]);
8632}
8633  [(set_attr "type" "multiple")
8634   (set_attr "conds" "clob")]
8635)
8636
8637(define_expand "casesi"
8638  [(match_operand:SI 0 "s_register_operand" "")	; index to jump on
8639   (match_operand:SI 1 "const_int_operand" "")	; lower bound
8640   (match_operand:SI 2 "const_int_operand" "")	; total range
8641   (match_operand:SI 3 "" "")			; table label
8642   (match_operand:SI 4 "" "")]			; Out of range label
8643  "(TARGET_32BIT || optimize_size || flag_pic) && !target_pure_code"
8644  "
8645  {
8646    enum insn_code code;
8647    if (operands[1] != const0_rtx)
8648      {
8649	rtx reg = gen_reg_rtx (SImode);
8650
8651	emit_insn (gen_addsi3 (reg, operands[0],
8652			       gen_int_mode (-INTVAL (operands[1]),
8653			       		     SImode)));
8654	operands[0] = reg;
8655      }
8656
8657    if (TARGET_ARM)
8658      code = CODE_FOR_arm_casesi_internal;
8659    else if (TARGET_THUMB1)
8660      code = CODE_FOR_thumb1_casesi_internal_pic;
8661    else if (flag_pic)
8662      code = CODE_FOR_thumb2_casesi_internal_pic;
8663    else
8664      code = CODE_FOR_thumb2_casesi_internal;
8665
8666    if (!insn_data[(int) code].operand[1].predicate(operands[2], SImode))
8667      operands[2] = force_reg (SImode, operands[2]);
8668
8669    emit_jump_insn (GEN_FCN ((int) code) (operands[0], operands[2],
8670					  operands[3], operands[4]));
8671    DONE;
8672  }"
8673)
8674
8675;; The USE in this pattern is needed to tell flow analysis that this is
8676;; a CASESI insn.  It has no other purpose.
8677(define_insn "arm_casesi_internal"
8678  [(parallel [(set (pc)
8679	       (if_then_else
8680		(leu (match_operand:SI 0 "s_register_operand" "r")
8681		     (match_operand:SI 1 "arm_rhs_operand" "rI"))
8682		(mem:SI (plus:SI (mult:SI (match_dup 0) (const_int 4))
8683				 (label_ref (match_operand 2 "" ""))))
8684		(label_ref (match_operand 3 "" ""))))
8685	      (clobber (reg:CC CC_REGNUM))
8686	      (use (label_ref (match_dup 2)))])]
8687  "TARGET_ARM"
8688  "*
8689    if (flag_pic)
8690      return \"cmp\\t%0, %1\;addls\\t%|pc, %|pc, %0, asl #2\;b\\t%l3\";
8691    return   \"cmp\\t%0, %1\;ldrls\\t%|pc, [%|pc, %0, asl #2]\;b\\t%l3\";
8692  "
8693  [(set_attr "conds" "clob")
8694   (set_attr "length" "12")
8695   (set_attr "type" "multiple")]
8696)
8697
8698(define_expand "indirect_jump"
8699  [(set (pc)
8700	(match_operand:SI 0 "s_register_operand" ""))]
8701  "TARGET_EITHER"
8702  "
8703  /* Thumb-2 doesn't have mov pc, reg.  Explicitly set the low bit of the
8704     address and use bx.  */
8705  if (TARGET_THUMB2)
8706    {
8707      rtx tmp;
8708      tmp = gen_reg_rtx (SImode);
8709      emit_insn (gen_iorsi3 (tmp, operands[0], GEN_INT(1)));
8710      operands[0] = tmp;
8711    }
8712  "
8713)
8714
8715;; NB Never uses BX.
8716(define_insn "*arm_indirect_jump"
8717  [(set (pc)
8718	(match_operand:SI 0 "s_register_operand" "r"))]
8719  "TARGET_ARM"
8720  "mov%?\\t%|pc, %0\\t%@ indirect register jump"
8721  [(set_attr "predicable" "yes")
8722   (set_attr "type" "branch")]
8723)
8724
8725(define_insn "*load_indirect_jump"
8726  [(set (pc)
8727	(match_operand:SI 0 "memory_operand" "m"))]
8728  "TARGET_ARM"
8729  "ldr%?\\t%|pc, %0\\t%@ indirect memory jump"
8730  [(set_attr "type" "load_4")
8731   (set_attr "pool_range" "4096")
8732   (set_attr "neg_pool_range" "4084")
8733   (set_attr "predicable" "yes")]
8734)
8735
8736
8737;; Misc insns
8738
8739(define_insn "nop"
8740  [(const_int 0)]
8741  "TARGET_EITHER"
8742  "nop"
8743  [(set (attr "length")
8744	(if_then_else (eq_attr "is_thumb" "yes")
8745		      (const_int 2)
8746		      (const_int 4)))
8747   (set_attr "type" "mov_reg")]
8748)
8749
8750(define_insn "trap"
8751  [(trap_if (const_int 1) (const_int 0))]
8752  ""
8753  "*
8754  if (TARGET_ARM)
8755    return \".inst\\t0xe7f000f0\";
8756  else
8757    return \".inst\\t0xdeff\";
8758  "
8759  [(set (attr "length")
8760	(if_then_else (eq_attr "is_thumb" "yes")
8761		      (const_int 2)
8762		      (const_int 4)))
8763   (set_attr "type" "trap")
8764   (set_attr "conds" "unconditional")]
8765)
8766
8767
8768;; Patterns to allow combination of arithmetic, cond code and shifts
8769
8770(define_insn "*<arith_shift_insn>_multsi"
8771  [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8772	(SHIFTABLE_OPS:SI
8773	 (mult:SI (match_operand:SI 2 "s_register_operand" "r,r")
8774		  (match_operand:SI 3 "power_of_two_operand" ""))
8775	 (match_operand:SI 1 "s_register_operand" "rk,<t2_binop0>")))]
8776  "TARGET_32BIT"
8777  "<arith_shift_insn>%?\\t%0, %1, %2, lsl %b3"
8778  [(set_attr "predicable" "yes")
8779   (set_attr "shift" "2")
8780   (set_attr "arch" "a,t2")
8781   (set_attr "type" "alu_shift_imm")])
8782
8783(define_insn "*<arith_shift_insn>_shiftsi"
8784  [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
8785	(SHIFTABLE_OPS:SI
8786	 (match_operator:SI 2 "shift_nomul_operator"
8787	  [(match_operand:SI 3 "s_register_operand" "r,r,r")
8788	   (match_operand:SI 4 "shift_amount_operand" "M,M,r")])
8789	 (match_operand:SI 1 "s_register_operand" "rk,<t2_binop0>,rk")))]
8790  "TARGET_32BIT && GET_CODE (operands[2]) != MULT"
8791  "<arith_shift_insn>%?\\t%0, %1, %3%S2"
8792  [(set_attr "predicable" "yes")
8793   (set_attr "shift" "3")
8794   (set_attr "arch" "a,t2,a")
8795   (set_attr "type" "alu_shift_imm,alu_shift_imm,alu_shift_reg")])
8796
8797(define_split
8798  [(set (match_operand:SI 0 "s_register_operand" "")
8799	(match_operator:SI 1 "shiftable_operator"
8800	 [(match_operator:SI 2 "shiftable_operator"
8801	   [(match_operator:SI 3 "shift_operator"
8802	     [(match_operand:SI 4 "s_register_operand" "")
8803	      (match_operand:SI 5 "reg_or_int_operand" "")])
8804	    (match_operand:SI 6 "s_register_operand" "")])
8805	  (match_operand:SI 7 "arm_rhs_operand" "")]))
8806   (clobber (match_operand:SI 8 "s_register_operand" ""))]
8807  "TARGET_32BIT"
8808  [(set (match_dup 8)
8809	(match_op_dup 2 [(match_op_dup 3 [(match_dup 4) (match_dup 5)])
8810			 (match_dup 6)]))
8811   (set (match_dup 0)
8812	(match_op_dup 1 [(match_dup 8) (match_dup 7)]))]
8813  "")
8814
8815(define_insn "*arith_shiftsi_compare0"
8816  [(set (reg:CC_NOOV CC_REGNUM)
8817        (compare:CC_NOOV
8818	 (match_operator:SI 1 "shiftable_operator"
8819	  [(match_operator:SI 3 "shift_operator"
8820	    [(match_operand:SI 4 "s_register_operand" "r,r")
8821	     (match_operand:SI 5 "shift_amount_operand" "M,r")])
8822	   (match_operand:SI 2 "s_register_operand" "r,r")])
8823	 (const_int 0)))
8824   (set (match_operand:SI 0 "s_register_operand" "=r,r")
8825	(match_op_dup 1 [(match_op_dup 3 [(match_dup 4) (match_dup 5)])
8826			 (match_dup 2)]))]
8827  "TARGET_32BIT"
8828  "%i1s%?\\t%0, %2, %4%S3"
8829  [(set_attr "conds" "set")
8830   (set_attr "shift" "4")
8831   (set_attr "arch" "32,a")
8832   (set_attr "type" "alus_shift_imm,alus_shift_reg")])
8833
8834(define_insn "*arith_shiftsi_compare0_scratch"
8835  [(set (reg:CC_NOOV CC_REGNUM)
8836        (compare:CC_NOOV
8837	 (match_operator:SI 1 "shiftable_operator"
8838	  [(match_operator:SI 3 "shift_operator"
8839	    [(match_operand:SI 4 "s_register_operand" "r,r")
8840	     (match_operand:SI 5 "shift_amount_operand" "M,r")])
8841	   (match_operand:SI 2 "s_register_operand" "r,r")])
8842	 (const_int 0)))
8843   (clobber (match_scratch:SI 0 "=r,r"))]
8844  "TARGET_32BIT"
8845  "%i1s%?\\t%0, %2, %4%S3"
8846  [(set_attr "conds" "set")
8847   (set_attr "shift" "4")
8848   (set_attr "arch" "32,a")
8849   (set_attr "type" "alus_shift_imm,alus_shift_reg")])
8850
8851(define_insn "*sub_shiftsi"
8852  [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8853	(minus:SI (match_operand:SI 1 "s_register_operand" "r,r")
8854		  (match_operator:SI 2 "shift_operator"
8855		   [(match_operand:SI 3 "s_register_operand" "r,r")
8856		    (match_operand:SI 4 "shift_amount_operand" "M,r")])))]
8857  "TARGET_32BIT"
8858  "sub%?\\t%0, %1, %3%S2"
8859  [(set_attr "predicable" "yes")
8860   (set_attr "predicable_short_it" "no")
8861   (set_attr "shift" "3")
8862   (set_attr "arch" "32,a")
8863   (set_attr "type" "alus_shift_imm,alus_shift_reg")])
8864
8865(define_insn "*sub_shiftsi_compare0"
8866  [(set (reg:CC_NOOV CC_REGNUM)
8867	(compare:CC_NOOV
8868	 (minus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
8869		   (match_operator:SI 2 "shift_operator"
8870		    [(match_operand:SI 3 "s_register_operand" "r,r,r")
8871		     (match_operand:SI 4 "shift_amount_operand" "M,r,M")]))
8872	 (const_int 0)))
8873   (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
8874	(minus:SI (match_dup 1)
8875		  (match_op_dup 2 [(match_dup 3) (match_dup 4)])))]
8876  "TARGET_32BIT"
8877  "subs%?\\t%0, %1, %3%S2"
8878  [(set_attr "conds" "set")
8879   (set_attr "shift" "3")
8880   (set_attr "arch" "32,a,a")
8881   (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
8882
8883(define_insn "*sub_shiftsi_compare0_scratch"
8884  [(set (reg:CC_NOOV CC_REGNUM)
8885	(compare:CC_NOOV
8886	 (minus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
8887		   (match_operator:SI 2 "shift_operator"
8888		    [(match_operand:SI 3 "s_register_operand" "r,r,r")
8889		     (match_operand:SI 4 "shift_amount_operand" "M,r,M")]))
8890	 (const_int 0)))
8891   (clobber (match_scratch:SI 0 "=r,r,r"))]
8892  "TARGET_32BIT"
8893  "subs%?\\t%0, %1, %3%S2"
8894  [(set_attr "conds" "set")
8895   (set_attr "shift" "3")
8896   (set_attr "arch" "32,a,a")
8897   (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
8898
8899
8900(define_insn_and_split "*and_scc"
8901  [(set (match_operand:SI 0 "s_register_operand" "=r")
8902	(and:SI (match_operator:SI 1 "arm_comparison_operator"
8903		 [(match_operand 2 "cc_register" "") (const_int 0)])
8904		(match_operand:SI 3 "s_register_operand" "r")))]
8905  "TARGET_ARM"
8906  "#"   ; "mov%D1\\t%0, #0\;and%d1\\t%0, %3, #1"
8907  "&& reload_completed"
8908  [(cond_exec (match_dup 5) (set (match_dup 0) (const_int 0)))
8909   (cond_exec (match_dup 4) (set (match_dup 0)
8910                                 (and:SI (match_dup 3) (const_int 1))))]
8911  {
8912    machine_mode mode = GET_MODE (operands[2]);
8913    enum rtx_code rc = GET_CODE (operands[1]);
8914
8915    /* Note that operands[4] is the same as operands[1],
8916       but with VOIDmode as the result. */
8917    operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
8918    if (mode == CCFPmode || mode == CCFPEmode)
8919      rc = reverse_condition_maybe_unordered (rc);
8920    else
8921      rc = reverse_condition (rc);
8922    operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
8923  }
8924  [(set_attr "conds" "use")
8925   (set_attr "type" "multiple")
8926   (set_attr "length" "8")]
8927)
8928
8929(define_insn_and_split "*ior_scc"
8930  [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8931	(ior:SI (match_operator:SI 1 "arm_comparison_operator"
8932		 [(match_operand 2 "cc_register" "") (const_int 0)])
8933		(match_operand:SI 3 "s_register_operand" "0,?r")))]
8934  "TARGET_ARM"
8935  "@
8936   orr%d1\\t%0, %3, #1
8937   #"
8938  "&& reload_completed
8939   && REGNO (operands [0]) != REGNO (operands[3])"
8940  ;; && which_alternative == 1
8941  ; mov%D1\\t%0, %3\;orr%d1\\t%0, %3, #1
8942  [(cond_exec (match_dup 5) (set (match_dup 0) (match_dup 3)))
8943   (cond_exec (match_dup 4) (set (match_dup 0)
8944                                 (ior:SI (match_dup 3) (const_int 1))))]
8945  {
8946    machine_mode mode = GET_MODE (operands[2]);
8947    enum rtx_code rc = GET_CODE (operands[1]);
8948
8949    /* Note that operands[4] is the same as operands[1],
8950       but with VOIDmode as the result. */
8951    operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
8952    if (mode == CCFPmode || mode == CCFPEmode)
8953      rc = reverse_condition_maybe_unordered (rc);
8954    else
8955      rc = reverse_condition (rc);
8956    operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
8957  }
8958  [(set_attr "conds" "use")
8959   (set_attr "length" "4,8")
8960   (set_attr "type" "logic_imm,multiple")]
8961)
8962
8963; A series of splitters for the compare_scc pattern below.  Note that
8964; order is important.
8965(define_split
8966  [(set (match_operand:SI 0 "s_register_operand" "")
8967	(lt:SI (match_operand:SI 1 "s_register_operand" "")
8968	       (const_int 0)))
8969   (clobber (reg:CC CC_REGNUM))]
8970  "TARGET_32BIT && reload_completed"
8971  [(set (match_dup 0) (lshiftrt:SI (match_dup 1) (const_int 31)))])
8972
8973(define_split
8974  [(set (match_operand:SI 0 "s_register_operand" "")
8975	(ge:SI (match_operand:SI 1 "s_register_operand" "")
8976	       (const_int 0)))
8977   (clobber (reg:CC CC_REGNUM))]
8978  "TARGET_32BIT && reload_completed"
8979  [(set (match_dup 0) (not:SI (match_dup 1)))
8980   (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 31)))])
8981
8982(define_split
8983  [(set (match_operand:SI 0 "s_register_operand" "")
8984	(eq:SI (match_operand:SI 1 "s_register_operand" "")
8985	       (const_int 0)))
8986   (clobber (reg:CC CC_REGNUM))]
8987  "arm_arch5 && TARGET_32BIT"
8988  [(set (match_dup 0) (clz:SI (match_dup 1)))
8989   (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
8990)
8991
8992(define_split
8993  [(set (match_operand:SI 0 "s_register_operand" "")
8994	(eq:SI (match_operand:SI 1 "s_register_operand" "")
8995	       (const_int 0)))
8996   (clobber (reg:CC CC_REGNUM))]
8997  "TARGET_32BIT && reload_completed"
8998  [(parallel
8999    [(set (reg:CC CC_REGNUM)
9000	  (compare:CC (const_int 1) (match_dup 1)))
9001     (set (match_dup 0)
9002	  (minus:SI (const_int 1) (match_dup 1)))])
9003   (cond_exec (ltu:CC (reg:CC CC_REGNUM) (const_int 0))
9004	      (set (match_dup 0) (const_int 0)))])
9005
9006(define_split
9007  [(set (match_operand:SI 0 "s_register_operand" "")
9008	(ne:SI (match_operand:SI 1 "s_register_operand" "")
9009	       (match_operand:SI 2 "const_int_operand" "")))
9010   (clobber (reg:CC CC_REGNUM))]
9011  "TARGET_32BIT && reload_completed"
9012  [(parallel
9013    [(set (reg:CC CC_REGNUM)
9014	  (compare:CC (match_dup 1) (match_dup 2)))
9015     (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 3)))])
9016   (cond_exec (ne:CC (reg:CC CC_REGNUM) (const_int 0))
9017	      (set (match_dup 0) (const_int 1)))]
9018{
9019  operands[3] = GEN_INT (-INTVAL (operands[2]));
9020})
9021
9022(define_split
9023  [(set (match_operand:SI 0 "s_register_operand" "")
9024	(ne:SI (match_operand:SI 1 "s_register_operand" "")
9025	       (match_operand:SI 2 "arm_add_operand" "")))
9026   (clobber (reg:CC CC_REGNUM))]
9027  "TARGET_32BIT && reload_completed"
9028  [(parallel
9029    [(set (reg:CC_NOOV CC_REGNUM)
9030	  (compare:CC_NOOV (minus:SI (match_dup 1) (match_dup 2))
9031			   (const_int 0)))
9032     (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
9033   (cond_exec (ne:CC_NOOV (reg:CC_NOOV CC_REGNUM) (const_int 0))
9034	      (set (match_dup 0) (const_int 1)))])
9035
9036(define_insn_and_split "*compare_scc"
9037  [(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts")
9038	(match_operator:SI 1 "arm_comparison_operator"
9039	 [(match_operand:SI 2 "s_register_operand" "r,r")
9040	  (match_operand:SI 3 "arm_add_operand" "rI,L")]))
9041   (clobber (reg:CC CC_REGNUM))]
9042  "TARGET_32BIT"
9043  "#"
9044  "&& reload_completed"
9045  [(set (reg:CC CC_REGNUM) (compare:CC (match_dup 2) (match_dup 3)))
9046   (cond_exec (match_dup 4) (set (match_dup 0) (const_int 0)))
9047   (cond_exec (match_dup 5) (set (match_dup 0) (const_int 1)))]
9048{
9049  rtx tmp1;
9050  machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
9051					   operands[2], operands[3]);
9052  enum rtx_code rc = GET_CODE (operands[1]);
9053
9054  tmp1 = gen_rtx_REG (mode, CC_REGNUM);
9055
9056  operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, tmp1, const0_rtx);
9057  if (mode == CCFPmode || mode == CCFPEmode)
9058    rc = reverse_condition_maybe_unordered (rc);
9059  else
9060    rc = reverse_condition (rc);
9061  operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, tmp1, const0_rtx);
9062}
9063  [(set_attr "type" "multiple")]
9064)
9065
9066;; Attempt to improve the sequence generated by the compare_scc splitters
9067;; not to use conditional execution.
9068
9069;; Rd = (eq (reg1) (const_int0))  // ARMv5
9070;;	clz Rd, reg1
9071;;	lsr Rd, Rd, #5
9072(define_peephole2
9073  [(set (reg:CC CC_REGNUM)
9074	(compare:CC (match_operand:SI 1 "register_operand" "")
9075		    (const_int 0)))
9076   (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
9077	      (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
9078   (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
9079	      (set (match_dup 0) (const_int 1)))]
9080  "arm_arch5 && TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
9081  [(set (match_dup 0) (clz:SI (match_dup 1)))
9082   (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
9083)
9084
9085;; Rd = (eq (reg1) (const_int0))  // !ARMv5
9086;;	negs Rd, reg1
9087;;	adc  Rd, Rd, reg1
9088(define_peephole2
9089  [(set (reg:CC CC_REGNUM)
9090	(compare:CC (match_operand:SI 1 "register_operand" "")
9091		    (const_int 0)))
9092   (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
9093	      (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
9094   (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
9095	      (set (match_dup 0) (const_int 1)))
9096   (match_scratch:SI 2 "r")]
9097  "TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
9098  [(parallel
9099    [(set (reg:CC CC_REGNUM)
9100	  (compare:CC (const_int 0) (match_dup 1)))
9101     (set (match_dup 2) (minus:SI (const_int 0) (match_dup 1)))])
9102   (set (match_dup 0)
9103	(plus:SI (plus:SI (match_dup 1) (match_dup 2))
9104		 (geu:SI (reg:CC CC_REGNUM) (const_int 0))))]
9105)
9106
9107;; Rd = (eq (reg1) (reg2/imm))	// ARMv5 and optimising for speed.
9108;;	sub  Rd, Reg1, reg2
9109;;	clz  Rd, Rd
9110;;	lsr  Rd, Rd, #5
9111(define_peephole2
9112  [(set (reg:CC CC_REGNUM)
9113	(compare:CC (match_operand:SI 1 "register_operand" "")
9114		    (match_operand:SI 2 "arm_rhs_operand" "")))
9115   (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
9116	      (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
9117   (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
9118	      (set (match_dup 0) (const_int 1)))]
9119  "arm_arch5 && TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)
9120  && !(TARGET_THUMB2 && optimize_insn_for_size_p ())"
9121  [(set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))
9122   (set (match_dup 0) (clz:SI (match_dup 0)))
9123   (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
9124)
9125
9126
9127;; Rd = (eq (reg1) (reg2))	// ! ARMv5 or optimising for size.
9128;;	sub  T1, Reg1, reg2
9129;;	negs Rd, T1
9130;;	adc  Rd, Rd, T1
9131(define_peephole2
9132  [(set (reg:CC CC_REGNUM)
9133	(compare:CC (match_operand:SI 1 "register_operand" "")
9134		    (match_operand:SI 2 "arm_rhs_operand" "")))
9135   (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
9136	      (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
9137   (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
9138	      (set (match_dup 0) (const_int 1)))
9139   (match_scratch:SI 3 "r")]
9140  "TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
9141  [(set (match_dup 3) (match_dup 4))
9142   (parallel
9143    [(set (reg:CC CC_REGNUM)
9144	  (compare:CC (const_int 0) (match_dup 3)))
9145     (set (match_dup 0) (minus:SI (const_int 0) (match_dup 3)))])
9146   (set (match_dup 0)
9147	(plus:SI (plus:SI (match_dup 0) (match_dup 3))
9148		 (geu:SI (reg:CC CC_REGNUM) (const_int 0))))]
9149  "
9150  if (CONST_INT_P (operands[2]))
9151    operands[4] = plus_constant (SImode, operands[1], -INTVAL (operands[2]));
9152  else
9153    operands[4] = gen_rtx_MINUS (SImode, operands[1], operands[2]);
9154  ")
9155
9156(define_insn "*cond_move"
9157  [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9158	(if_then_else:SI (match_operator 3 "equality_operator"
9159			  [(match_operator 4 "arm_comparison_operator"
9160			    [(match_operand 5 "cc_register" "") (const_int 0)])
9161			   (const_int 0)])
9162			 (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
9163			 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))]
9164  "TARGET_ARM"
9165  "*
9166    if (GET_CODE (operands[3]) == NE)
9167      {
9168        if (which_alternative != 1)
9169	  output_asm_insn (\"mov%D4\\t%0, %2\", operands);
9170        if (which_alternative != 0)
9171	  output_asm_insn (\"mov%d4\\t%0, %1\", operands);
9172        return \"\";
9173      }
9174    if (which_alternative != 0)
9175      output_asm_insn (\"mov%D4\\t%0, %1\", operands);
9176    if (which_alternative != 1)
9177      output_asm_insn (\"mov%d4\\t%0, %2\", operands);
9178    return \"\";
9179  "
9180  [(set_attr "conds" "use")
9181   (set_attr_alternative "type"
9182                         [(if_then_else (match_operand 2 "const_int_operand" "")
9183                                        (const_string "mov_imm")
9184                                        (const_string "mov_reg"))
9185                          (if_then_else (match_operand 1 "const_int_operand" "")
9186                                        (const_string "mov_imm")
9187                                        (const_string "mov_reg"))
9188                          (const_string "multiple")])
9189   (set_attr "length" "4,4,8")]
9190)
9191
9192(define_insn "*cond_arith"
9193  [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9194        (match_operator:SI 5 "shiftable_operator"
9195	 [(match_operator:SI 4 "arm_comparison_operator"
9196           [(match_operand:SI 2 "s_register_operand" "r,r")
9197	    (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
9198          (match_operand:SI 1 "s_register_operand" "0,?r")]))
9199   (clobber (reg:CC CC_REGNUM))]
9200  "TARGET_ARM"
9201  "*
9202    if (GET_CODE (operands[4]) == LT && operands[3] == const0_rtx)
9203      return \"%i5\\t%0, %1, %2, lsr #31\";
9204
9205    output_asm_insn (\"cmp\\t%2, %3\", operands);
9206    if (GET_CODE (operands[5]) == AND)
9207      output_asm_insn (\"mov%D4\\t%0, #0\", operands);
9208    else if (GET_CODE (operands[5]) == MINUS)
9209      output_asm_insn (\"rsb%D4\\t%0, %1, #0\", operands);
9210    else if (which_alternative != 0)
9211      output_asm_insn (\"mov%D4\\t%0, %1\", operands);
9212    return \"%i5%d4\\t%0, %1, #1\";
9213  "
9214  [(set_attr "conds" "clob")
9215   (set_attr "length" "12")
9216   (set_attr "type" "multiple")]
9217)
9218
9219(define_insn "*cond_sub"
9220  [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9221        (minus:SI (match_operand:SI 1 "s_register_operand" "0,?r")
9222		  (match_operator:SI 4 "arm_comparison_operator"
9223                   [(match_operand:SI 2 "s_register_operand" "r,r")
9224		    (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
9225   (clobber (reg:CC CC_REGNUM))]
9226  "TARGET_ARM"
9227  "*
9228    output_asm_insn (\"cmp\\t%2, %3\", operands);
9229    if (which_alternative != 0)
9230      output_asm_insn (\"mov%D4\\t%0, %1\", operands);
9231    return \"sub%d4\\t%0, %1, #1\";
9232  "
9233  [(set_attr "conds" "clob")
9234   (set_attr "length" "8,12")
9235   (set_attr "type" "multiple")]
9236)
9237
9238(define_insn "*cmp_ite0"
9239  [(set (match_operand 6 "dominant_cc_register" "")
9240	(compare
9241	 (if_then_else:SI
9242	  (match_operator 4 "arm_comparison_operator"
9243	   [(match_operand:SI 0 "s_register_operand"
9244	        "l,l,l,r,r,r,r,r,r")
9245	    (match_operand:SI 1 "arm_add_operand"
9246	        "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
9247	  (match_operator:SI 5 "arm_comparison_operator"
9248	   [(match_operand:SI 2 "s_register_operand"
9249	        "l,r,r,l,l,r,r,r,r")
9250	    (match_operand:SI 3 "arm_add_operand"
9251	        "lPy,rI,L,lPy,lPy,rI,rI,L,L")])
9252	  (const_int 0))
9253	 (const_int 0)))]
9254  "TARGET_32BIT"
9255  "*
9256  {
9257    static const char * const cmp1[NUM_OF_COND_CMP][2] =
9258    {
9259      {\"cmp%d5\\t%0, %1\",
9260       \"cmp%d4\\t%2, %3\"},
9261      {\"cmn%d5\\t%0, #%n1\",
9262       \"cmp%d4\\t%2, %3\"},
9263      {\"cmp%d5\\t%0, %1\",
9264       \"cmn%d4\\t%2, #%n3\"},
9265      {\"cmn%d5\\t%0, #%n1\",
9266       \"cmn%d4\\t%2, #%n3\"}
9267    };
9268    static const char * const cmp2[NUM_OF_COND_CMP][2] =
9269    {
9270      {\"cmp\\t%2, %3\",
9271       \"cmp\\t%0, %1\"},
9272      {\"cmp\\t%2, %3\",
9273       \"cmn\\t%0, #%n1\"},
9274      {\"cmn\\t%2, #%n3\",
9275       \"cmp\\t%0, %1\"},
9276      {\"cmn\\t%2, #%n3\",
9277       \"cmn\\t%0, #%n1\"}
9278    };
9279    static const char * const ite[2] =
9280    {
9281      \"it\\t%d5\",
9282      \"it\\t%d4\"
9283    };
9284    static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
9285                                   CMP_CMP, CMN_CMP, CMP_CMP,
9286                                   CMN_CMP, CMP_CMN, CMN_CMN};
9287    int swap =
9288      comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
9289
9290    output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
9291    if (TARGET_THUMB2) {
9292      output_asm_insn (ite[swap], operands);
9293    }
9294    output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
9295    return \"\";
9296  }"
9297  [(set_attr "conds" "set")
9298   (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
9299   (set_attr "enabled_for_short_it" "yes,no,no,no,no,no,no,no,no")
9300   (set_attr "type" "multiple")
9301   (set_attr_alternative "length"
9302      [(const_int 6)
9303       (const_int 8)
9304       (const_int 8)
9305       (const_int 8)
9306       (const_int 8)
9307       (if_then_else (eq_attr "is_thumb" "no")
9308           (const_int 8)
9309           (const_int 10))
9310       (if_then_else (eq_attr "is_thumb" "no")
9311           (const_int 8)
9312           (const_int 10))
9313       (if_then_else (eq_attr "is_thumb" "no")
9314           (const_int 8)
9315           (const_int 10))
9316       (if_then_else (eq_attr "is_thumb" "no")
9317           (const_int 8)
9318           (const_int 10))])]
9319)
9320
9321(define_insn "*cmp_ite1"
9322  [(set (match_operand 6 "dominant_cc_register" "")
9323	(compare
9324	 (if_then_else:SI
9325	  (match_operator 4 "arm_comparison_operator"
9326	   [(match_operand:SI 0 "s_register_operand"
9327	        "l,l,l,r,r,r,r,r,r")
9328	    (match_operand:SI 1 "arm_add_operand"
9329	        "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
9330	  (match_operator:SI 5 "arm_comparison_operator"
9331	   [(match_operand:SI 2 "s_register_operand"
9332	        "l,r,r,l,l,r,r,r,r")
9333	    (match_operand:SI 3 "arm_add_operand"
9334	        "lPy,rI,L,lPy,lPy,rI,rI,L,L")])
9335	  (const_int 1))
9336	 (const_int 0)))]
9337  "TARGET_32BIT"
9338  "*
9339  {
9340    static const char * const cmp1[NUM_OF_COND_CMP][2] =
9341    {
9342      {\"cmp\\t%0, %1\",
9343       \"cmp\\t%2, %3\"},
9344      {\"cmn\\t%0, #%n1\",
9345       \"cmp\\t%2, %3\"},
9346      {\"cmp\\t%0, %1\",
9347       \"cmn\\t%2, #%n3\"},
9348      {\"cmn\\t%0, #%n1\",
9349       \"cmn\\t%2, #%n3\"}
9350    };
9351    static const char * const cmp2[NUM_OF_COND_CMP][2] =
9352    {
9353      {\"cmp%d4\\t%2, %3\",
9354       \"cmp%D5\\t%0, %1\"},
9355      {\"cmp%d4\\t%2, %3\",
9356       \"cmn%D5\\t%0, #%n1\"},
9357      {\"cmn%d4\\t%2, #%n3\",
9358       \"cmp%D5\\t%0, %1\"},
9359      {\"cmn%d4\\t%2, #%n3\",
9360       \"cmn%D5\\t%0, #%n1\"}
9361    };
9362    static const char * const ite[2] =
9363    {
9364      \"it\\t%d4\",
9365      \"it\\t%D5\"
9366    };
9367    static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
9368                                   CMP_CMP, CMN_CMP, CMP_CMP,
9369                                   CMN_CMP, CMP_CMN, CMN_CMN};
9370    int swap =
9371      comparison_dominates_p (GET_CODE (operands[5]),
9372			      reverse_condition (GET_CODE (operands[4])));
9373
9374    output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
9375    if (TARGET_THUMB2) {
9376      output_asm_insn (ite[swap], operands);
9377    }
9378    output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
9379    return \"\";
9380  }"
9381  [(set_attr "conds" "set")
9382   (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
9383   (set_attr "enabled_for_short_it" "yes,no,no,no,no,no,no,no,no")
9384   (set_attr_alternative "length"
9385      [(const_int 6)
9386       (const_int 8)
9387       (const_int 8)
9388       (const_int 8)
9389       (const_int 8)
9390       (if_then_else (eq_attr "is_thumb" "no")
9391           (const_int 8)
9392           (const_int 10))
9393       (if_then_else (eq_attr "is_thumb" "no")
9394           (const_int 8)
9395           (const_int 10))
9396       (if_then_else (eq_attr "is_thumb" "no")
9397           (const_int 8)
9398           (const_int 10))
9399       (if_then_else (eq_attr "is_thumb" "no")
9400           (const_int 8)
9401           (const_int 10))])
9402   (set_attr "type" "multiple")]
9403)
9404
9405(define_insn "*cmp_and"
9406  [(set (match_operand 6 "dominant_cc_register" "")
9407	(compare
9408	 (and:SI
9409	  (match_operator 4 "arm_comparison_operator"
9410	   [(match_operand:SI 0 "s_register_operand"
9411	        "l,l,l,r,r,r,r,r,r")
9412	    (match_operand:SI 1 "arm_add_operand"
9413	        "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
9414	  (match_operator:SI 5 "arm_comparison_operator"
9415	   [(match_operand:SI 2 "s_register_operand"
9416	        "l,r,r,l,l,r,r,r,r")
9417	    (match_operand:SI 3 "arm_add_operand"
9418	        "lPy,rI,L,lPy,lPy,rI,rI,L,L")]))
9419	 (const_int 0)))]
9420  "TARGET_32BIT"
9421  "*
9422  {
9423    static const char *const cmp1[NUM_OF_COND_CMP][2] =
9424    {
9425      {\"cmp%d5\\t%0, %1\",
9426       \"cmp%d4\\t%2, %3\"},
9427      {\"cmn%d5\\t%0, #%n1\",
9428       \"cmp%d4\\t%2, %3\"},
9429      {\"cmp%d5\\t%0, %1\",
9430       \"cmn%d4\\t%2, #%n3\"},
9431      {\"cmn%d5\\t%0, #%n1\",
9432       \"cmn%d4\\t%2, #%n3\"}
9433    };
9434    static const char *const cmp2[NUM_OF_COND_CMP][2] =
9435    {
9436      {\"cmp\\t%2, %3\",
9437       \"cmp\\t%0, %1\"},
9438      {\"cmp\\t%2, %3\",
9439       \"cmn\\t%0, #%n1\"},
9440      {\"cmn\\t%2, #%n3\",
9441       \"cmp\\t%0, %1\"},
9442      {\"cmn\\t%2, #%n3\",
9443       \"cmn\\t%0, #%n1\"}
9444    };
9445    static const char *const ite[2] =
9446    {
9447      \"it\\t%d5\",
9448      \"it\\t%d4\"
9449    };
9450    static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
9451                                   CMP_CMP, CMN_CMP, CMP_CMP,
9452                                   CMN_CMP, CMP_CMN, CMN_CMN};
9453    int swap =
9454      comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
9455
9456    output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
9457    if (TARGET_THUMB2) {
9458      output_asm_insn (ite[swap], operands);
9459    }
9460    output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
9461    return \"\";
9462  }"
9463  [(set_attr "conds" "set")
9464   (set_attr "predicable" "no")
9465   (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
9466   (set_attr "enabled_for_short_it" "yes,no,no,no,no,no,no,no,no")
9467   (set_attr_alternative "length"
9468      [(const_int 6)
9469       (const_int 8)
9470       (const_int 8)
9471       (const_int 8)
9472       (const_int 8)
9473       (if_then_else (eq_attr "is_thumb" "no")
9474           (const_int 8)
9475           (const_int 10))
9476       (if_then_else (eq_attr "is_thumb" "no")
9477           (const_int 8)
9478           (const_int 10))
9479       (if_then_else (eq_attr "is_thumb" "no")
9480           (const_int 8)
9481           (const_int 10))
9482       (if_then_else (eq_attr "is_thumb" "no")
9483           (const_int 8)
9484           (const_int 10))])
9485   (set_attr "type" "multiple")]
9486)
9487
9488(define_insn "*cmp_ior"
9489  [(set (match_operand 6 "dominant_cc_register" "")
9490	(compare
9491	 (ior:SI
9492	  (match_operator 4 "arm_comparison_operator"
9493	   [(match_operand:SI 0 "s_register_operand"
9494	        "l,l,l,r,r,r,r,r,r")
9495	    (match_operand:SI 1 "arm_add_operand"
9496	        "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
9497	  (match_operator:SI 5 "arm_comparison_operator"
9498	   [(match_operand:SI 2 "s_register_operand"
9499	        "l,r,r,l,l,r,r,r,r")
9500	    (match_operand:SI 3 "arm_add_operand"
9501	        "lPy,rI,L,lPy,lPy,rI,rI,L,L")]))
9502	 (const_int 0)))]
9503  "TARGET_32BIT"
9504  "*
9505  {
9506    static const char *const cmp1[NUM_OF_COND_CMP][2] =
9507    {
9508      {\"cmp\\t%0, %1\",
9509       \"cmp\\t%2, %3\"},
9510      {\"cmn\\t%0, #%n1\",
9511       \"cmp\\t%2, %3\"},
9512      {\"cmp\\t%0, %1\",
9513       \"cmn\\t%2, #%n3\"},
9514      {\"cmn\\t%0, #%n1\",
9515       \"cmn\\t%2, #%n3\"}
9516    };
9517    static const char *const cmp2[NUM_OF_COND_CMP][2] =
9518    {
9519      {\"cmp%D4\\t%2, %3\",
9520       \"cmp%D5\\t%0, %1\"},
9521      {\"cmp%D4\\t%2, %3\",
9522       \"cmn%D5\\t%0, #%n1\"},
9523      {\"cmn%D4\\t%2, #%n3\",
9524       \"cmp%D5\\t%0, %1\"},
9525      {\"cmn%D4\\t%2, #%n3\",
9526       \"cmn%D5\\t%0, #%n1\"}
9527    };
9528    static const char *const ite[2] =
9529    {
9530      \"it\\t%D4\",
9531      \"it\\t%D5\"
9532    };
9533    static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
9534                                   CMP_CMP, CMN_CMP, CMP_CMP,
9535                                   CMN_CMP, CMP_CMN, CMN_CMN};
9536    int swap =
9537      comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
9538
9539    output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
9540    if (TARGET_THUMB2) {
9541      output_asm_insn (ite[swap], operands);
9542    }
9543    output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
9544    return \"\";
9545  }
9546  "
9547  [(set_attr "conds" "set")
9548   (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
9549   (set_attr "enabled_for_short_it" "yes,no,no,no,no,no,no,no,no")
9550   (set_attr_alternative "length"
9551      [(const_int 6)
9552       (const_int 8)
9553       (const_int 8)
9554       (const_int 8)
9555       (const_int 8)
9556       (if_then_else (eq_attr "is_thumb" "no")
9557           (const_int 8)
9558           (const_int 10))
9559       (if_then_else (eq_attr "is_thumb" "no")
9560           (const_int 8)
9561           (const_int 10))
9562       (if_then_else (eq_attr "is_thumb" "no")
9563           (const_int 8)
9564           (const_int 10))
9565       (if_then_else (eq_attr "is_thumb" "no")
9566           (const_int 8)
9567           (const_int 10))])
9568   (set_attr "type" "multiple")]
9569)
9570
9571(define_insn_and_split "*ior_scc_scc"
9572  [(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts")
9573	(ior:SI (match_operator:SI 3 "arm_comparison_operator"
9574		 [(match_operand:SI 1 "s_register_operand" "l,r")
9575		  (match_operand:SI 2 "arm_add_operand" "lPy,rIL")])
9576		(match_operator:SI 6 "arm_comparison_operator"
9577		 [(match_operand:SI 4 "s_register_operand" "l,r")
9578		  (match_operand:SI 5 "arm_add_operand" "lPy,rIL")])))
9579   (clobber (reg:CC CC_REGNUM))]
9580  "TARGET_32BIT
9581   && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_OR_Y)
9582       != CCmode)"
9583  "#"
9584  "TARGET_32BIT && reload_completed"
9585  [(set (match_dup 7)
9586	(compare
9587	 (ior:SI
9588	  (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9589	  (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9590	 (const_int 0)))
9591   (set (match_dup 0) (ne:SI (match_dup 7) (const_int 0)))]
9592  "operands[7]
9593     = gen_rtx_REG (arm_select_dominance_cc_mode (operands[3], operands[6],
9594						  DOM_CC_X_OR_Y),
9595		    CC_REGNUM);"
9596  [(set_attr "conds" "clob")
9597   (set_attr "enabled_for_short_it" "yes,no")
9598   (set_attr "length" "16")
9599   (set_attr "type" "multiple")]
9600)
9601
9602; If the above pattern is followed by a CMP insn, then the compare is
9603; redundant, since we can rework the conditional instruction that follows.
9604(define_insn_and_split "*ior_scc_scc_cmp"
9605  [(set (match_operand 0 "dominant_cc_register" "")
9606	(compare (ior:SI (match_operator:SI 3 "arm_comparison_operator"
9607			  [(match_operand:SI 1 "s_register_operand" "l,r")
9608			   (match_operand:SI 2 "arm_add_operand" "lPy,rIL")])
9609			 (match_operator:SI 6 "arm_comparison_operator"
9610			  [(match_operand:SI 4 "s_register_operand" "l,r")
9611			   (match_operand:SI 5 "arm_add_operand" "lPy,rIL")]))
9612		 (const_int 0)))
9613   (set (match_operand:SI 7 "s_register_operand" "=Ts,Ts")
9614	(ior:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9615		(match_op_dup 6 [(match_dup 4) (match_dup 5)])))]
9616  "TARGET_32BIT"
9617  "#"
9618  "TARGET_32BIT && reload_completed"
9619  [(set (match_dup 0)
9620	(compare
9621	 (ior:SI
9622	  (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9623	  (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9624	 (const_int 0)))
9625   (set (match_dup 7) (ne:SI (match_dup 0) (const_int 0)))]
9626  ""
9627  [(set_attr "conds" "set")
9628   (set_attr "enabled_for_short_it" "yes,no")
9629   (set_attr "length" "16")
9630   (set_attr "type" "multiple")]
9631)
9632
9633(define_insn_and_split "*and_scc_scc"
9634  [(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts")
9635	(and:SI (match_operator:SI 3 "arm_comparison_operator"
9636		 [(match_operand:SI 1 "s_register_operand" "l,r")
9637		  (match_operand:SI 2 "arm_add_operand" "lPy,rIL")])
9638		(match_operator:SI 6 "arm_comparison_operator"
9639		 [(match_operand:SI 4 "s_register_operand" "l,r")
9640		  (match_operand:SI 5 "arm_add_operand" "lPy,rIL")])))
9641   (clobber (reg:CC CC_REGNUM))]
9642  "TARGET_32BIT
9643   && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
9644       != CCmode)"
9645  "#"
9646  "TARGET_32BIT && reload_completed
9647   && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
9648       != CCmode)"
9649  [(set (match_dup 7)
9650	(compare
9651	 (and:SI
9652	  (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9653	  (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9654	 (const_int 0)))
9655   (set (match_dup 0) (ne:SI (match_dup 7) (const_int 0)))]
9656  "operands[7]
9657     = gen_rtx_REG (arm_select_dominance_cc_mode (operands[3], operands[6],
9658						  DOM_CC_X_AND_Y),
9659		    CC_REGNUM);"
9660  [(set_attr "conds" "clob")
9661   (set_attr "enabled_for_short_it" "yes,no")
9662   (set_attr "length" "16")
9663   (set_attr "type" "multiple")]
9664)
9665
9666; If the above pattern is followed by a CMP insn, then the compare is
9667; redundant, since we can rework the conditional instruction that follows.
9668(define_insn_and_split "*and_scc_scc_cmp"
9669  [(set (match_operand 0 "dominant_cc_register" "")
9670	(compare (and:SI (match_operator:SI 3 "arm_comparison_operator"
9671			  [(match_operand:SI 1 "s_register_operand" "l,r")
9672			   (match_operand:SI 2 "arm_add_operand" "lPy,rIL")])
9673			 (match_operator:SI 6 "arm_comparison_operator"
9674			  [(match_operand:SI 4 "s_register_operand" "l,r")
9675			   (match_operand:SI 5 "arm_add_operand" "lPy,rIL")]))
9676		 (const_int 0)))
9677   (set (match_operand:SI 7 "s_register_operand" "=Ts,Ts")
9678	(and:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9679		(match_op_dup 6 [(match_dup 4) (match_dup 5)])))]
9680  "TARGET_32BIT"
9681  "#"
9682  "TARGET_32BIT && reload_completed"
9683  [(set (match_dup 0)
9684	(compare
9685	 (and:SI
9686	  (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9687	  (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9688	 (const_int 0)))
9689   (set (match_dup 7) (ne:SI (match_dup 0) (const_int 0)))]
9690  ""
9691  [(set_attr "conds" "set")
9692   (set_attr "enabled_for_short_it" "yes,no")
9693   (set_attr "length" "16")
9694   (set_attr "type" "multiple")]
9695)
9696
9697;; If there is no dominance in the comparison, then we can still save an
9698;; instruction in the AND case, since we can know that the second compare
9699;; need only zero the value if false (if true, then the value is already
9700;; correct).
9701(define_insn_and_split "*and_scc_scc_nodom"
9702  [(set (match_operand:SI 0 "s_register_operand" "=&Ts,&Ts,&Ts")
9703	(and:SI (match_operator:SI 3 "arm_comparison_operator"
9704		 [(match_operand:SI 1 "s_register_operand" "r,r,0")
9705		  (match_operand:SI 2 "arm_add_operand" "rIL,0,rIL")])
9706		(match_operator:SI 6 "arm_comparison_operator"
9707		 [(match_operand:SI 4 "s_register_operand" "r,r,r")
9708		  (match_operand:SI 5 "arm_add_operand" "rIL,rIL,rIL")])))
9709   (clobber (reg:CC CC_REGNUM))]
9710  "TARGET_32BIT
9711   && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
9712       == CCmode)"
9713  "#"
9714  "TARGET_32BIT && reload_completed"
9715  [(parallel [(set (match_dup 0)
9716		   (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
9717	      (clobber (reg:CC CC_REGNUM))])
9718   (set (match_dup 7) (match_op_dup 8 [(match_dup 4) (match_dup 5)]))
9719   (set (match_dup 0)
9720	(if_then_else:SI (match_op_dup 6 [(match_dup 7) (const_int 0)])
9721			 (match_dup 0)
9722			 (const_int 0)))]
9723  "operands[7] = gen_rtx_REG (SELECT_CC_MODE (GET_CODE (operands[6]),
9724					      operands[4], operands[5]),
9725			      CC_REGNUM);
9726   operands[8] = gen_rtx_COMPARE (GET_MODE (operands[7]), operands[4],
9727				  operands[5]);"
9728  [(set_attr "conds" "clob")
9729   (set_attr "length" "20")
9730   (set_attr "type" "multiple")]
9731)
9732
9733(define_split
9734  [(set (reg:CC_NOOV CC_REGNUM)
9735	(compare:CC_NOOV (ior:SI
9736			  (and:SI (match_operand:SI 0 "s_register_operand" "")
9737				  (const_int 1))
9738			  (match_operator:SI 1 "arm_comparison_operator"
9739			   [(match_operand:SI 2 "s_register_operand" "")
9740			    (match_operand:SI 3 "arm_add_operand" "")]))
9741			 (const_int 0)))
9742   (clobber (match_operand:SI 4 "s_register_operand" ""))]
9743  "TARGET_ARM"
9744  [(set (match_dup 4)
9745	(ior:SI (match_op_dup 1 [(match_dup 2) (match_dup 3)])
9746		(match_dup 0)))
9747   (set (reg:CC_NOOV CC_REGNUM)
9748	(compare:CC_NOOV (and:SI (match_dup 4) (const_int 1))
9749			 (const_int 0)))]
9750  "")
9751
9752(define_split
9753  [(set (reg:CC_NOOV CC_REGNUM)
9754	(compare:CC_NOOV (ior:SI
9755			  (match_operator:SI 1 "arm_comparison_operator"
9756			   [(match_operand:SI 2 "s_register_operand" "")
9757			    (match_operand:SI 3 "arm_add_operand" "")])
9758			  (and:SI (match_operand:SI 0 "s_register_operand" "")
9759				  (const_int 1)))
9760			 (const_int 0)))
9761   (clobber (match_operand:SI 4 "s_register_operand" ""))]
9762  "TARGET_ARM"
9763  [(set (match_dup 4)
9764	(ior:SI (match_op_dup 1 [(match_dup 2) (match_dup 3)])
9765		(match_dup 0)))
9766   (set (reg:CC_NOOV CC_REGNUM)
9767	(compare:CC_NOOV (and:SI (match_dup 4) (const_int 1))
9768			 (const_int 0)))]
9769  "")
9770;; ??? The conditional patterns above need checking for Thumb-2 usefulness
9771
9772(define_insn_and_split "*negscc"
9773  [(set (match_operand:SI 0 "s_register_operand" "=r")
9774	(neg:SI (match_operator 3 "arm_comparison_operator"
9775		 [(match_operand:SI 1 "s_register_operand" "r")
9776		  (match_operand:SI 2 "arm_rhs_operand" "rI")])))
9777   (clobber (reg:CC CC_REGNUM))]
9778  "TARGET_ARM"
9779  "#"
9780  "&& reload_completed"
9781  [(const_int 0)]
9782  {
9783    rtx cc_reg = gen_rtx_REG (CCmode, CC_REGNUM);
9784
9785    if (GET_CODE (operands[3]) == LT && operands[2] == const0_rtx)
9786       {
9787         /* Emit mov\\t%0, %1, asr #31 */
9788         emit_insn (gen_rtx_SET (operands[0],
9789                                 gen_rtx_ASHIFTRT (SImode,
9790                                                   operands[1],
9791                                                   GEN_INT (31))));
9792         DONE;
9793       }
9794     else if (GET_CODE (operands[3]) == NE)
9795       {
9796        /* Emit subs\\t%0, %1, %2\;mvnne\\t%0, #0 */
9797        if (CONST_INT_P (operands[2]))
9798          emit_insn (gen_cmpsi2_addneg (operands[0], operands[1], operands[2],
9799                                        GEN_INT (- INTVAL (operands[2]))));
9800        else
9801          emit_insn (gen_subsi3_compare (operands[0], operands[1], operands[2]));
9802
9803        emit_insn (gen_rtx_COND_EXEC (VOIDmode,
9804                                      gen_rtx_NE (SImode,
9805                                                  cc_reg,
9806                                                  const0_rtx),
9807                                      gen_rtx_SET (operands[0],
9808                                                   GEN_INT (~0))));
9809        DONE;
9810      }
9811    else
9812      {
9813        /* Emit: cmp\\t%1, %2\;mov%D3\\t%0, #0\;mvn%d3\\t%0, #0 */
9814        emit_insn (gen_rtx_SET (cc_reg,
9815                                gen_rtx_COMPARE (CCmode, operands[1], operands[2])));
9816        enum rtx_code rc = GET_CODE (operands[3]);
9817
9818        rc = reverse_condition (rc);
9819        emit_insn (gen_rtx_COND_EXEC (VOIDmode,
9820                                      gen_rtx_fmt_ee (rc,
9821                                                      VOIDmode,
9822                                                      cc_reg,
9823                                                      const0_rtx),
9824                                      gen_rtx_SET (operands[0], const0_rtx)));
9825        rc = GET_CODE (operands[3]);
9826        emit_insn (gen_rtx_COND_EXEC (VOIDmode,
9827                                      gen_rtx_fmt_ee (rc,
9828                                                      VOIDmode,
9829                                                      cc_reg,
9830                                                      const0_rtx),
9831                                      gen_rtx_SET (operands[0],
9832                                                   GEN_INT (~0))));
9833        DONE;
9834      }
9835     FAIL;
9836  }
9837  [(set_attr "conds" "clob")
9838   (set_attr "length" "12")
9839   (set_attr "type" "multiple")]
9840)
9841
9842(define_insn_and_split "movcond_addsi"
9843  [(set (match_operand:SI 0 "s_register_operand" "=r,l,r")
9844	(if_then_else:SI
9845	 (match_operator 5 "comparison_operator"
9846	  [(plus:SI (match_operand:SI 3 "s_register_operand" "r,r,r")
9847	            (match_operand:SI 4 "arm_add_operand" "rIL,rIL,rIL"))
9848            (const_int 0)])
9849	 (match_operand:SI 1 "arm_rhs_operand" "rI,rPy,r")
9850	 (match_operand:SI 2 "arm_rhs_operand" "rI,rPy,r")))
9851   (clobber (reg:CC CC_REGNUM))]
9852   "TARGET_32BIT"
9853   "#"
9854   "&& reload_completed"
9855  [(set (reg:CC_NOOV CC_REGNUM)
9856	(compare:CC_NOOV
9857	 (plus:SI (match_dup 3)
9858		  (match_dup 4))
9859	 (const_int 0)))
9860   (set (match_dup 0) (match_dup 1))
9861   (cond_exec (match_dup 6)
9862	      (set (match_dup 0) (match_dup 2)))]
9863  "
9864  {
9865    machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[5]),
9866					     operands[3], operands[4]);
9867    enum rtx_code rc = GET_CODE (operands[5]);
9868    operands[6] = gen_rtx_REG (mode, CC_REGNUM);
9869    gcc_assert (!(mode == CCFPmode || mode == CCFPEmode));
9870    if (!REG_P (operands[2]) || REGNO (operands[2]) != REGNO (operands[0]))
9871      rc = reverse_condition (rc);
9872    else
9873      std::swap (operands[1], operands[2]);
9874
9875    operands[6] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
9876  }
9877  "
9878  [(set_attr "conds" "clob")
9879   (set_attr "enabled_for_short_it" "no,yes,yes")
9880   (set_attr "type" "multiple")]
9881)
9882
9883(define_insn "movcond"
9884  [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9885	(if_then_else:SI
9886	 (match_operator 5 "arm_comparison_operator"
9887	  [(match_operand:SI 3 "s_register_operand" "r,r,r")
9888	   (match_operand:SI 4 "arm_add_operand" "rIL,rIL,rIL")])
9889	 (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
9890	 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
9891   (clobber (reg:CC CC_REGNUM))]
9892  "TARGET_ARM"
9893  "*
9894  if (GET_CODE (operands[5]) == LT
9895      && (operands[4] == const0_rtx))
9896    {
9897      if (which_alternative != 1 && REG_P (operands[1]))
9898	{
9899	  if (operands[2] == const0_rtx)
9900	    return \"and\\t%0, %1, %3, asr #31\";
9901	  return \"ands\\t%0, %1, %3, asr #32\;movcc\\t%0, %2\";
9902	}
9903      else if (which_alternative != 0 && REG_P (operands[2]))
9904	{
9905	  if (operands[1] == const0_rtx)
9906	    return \"bic\\t%0, %2, %3, asr #31\";
9907	  return \"bics\\t%0, %2, %3, asr #32\;movcs\\t%0, %1\";
9908	}
9909      /* The only case that falls through to here is when both ops 1 & 2
9910	 are constants.  */
9911    }
9912
9913  if (GET_CODE (operands[5]) == GE
9914      && (operands[4] == const0_rtx))
9915    {
9916      if (which_alternative != 1 && REG_P (operands[1]))
9917	{
9918	  if (operands[2] == const0_rtx)
9919	    return \"bic\\t%0, %1, %3, asr #31\";
9920	  return \"bics\\t%0, %1, %3, asr #32\;movcs\\t%0, %2\";
9921	}
9922      else if (which_alternative != 0 && REG_P (operands[2]))
9923	{
9924	  if (operands[1] == const0_rtx)
9925	    return \"and\\t%0, %2, %3, asr #31\";
9926	  return \"ands\\t%0, %2, %3, asr #32\;movcc\\t%0, %1\";
9927	}
9928      /* The only case that falls through to here is when both ops 1 & 2
9929	 are constants.  */
9930    }
9931  if (CONST_INT_P (operands[4])
9932      && !const_ok_for_arm (INTVAL (operands[4])))
9933    output_asm_insn (\"cmn\\t%3, #%n4\", operands);
9934  else
9935    output_asm_insn (\"cmp\\t%3, %4\", operands);
9936  if (which_alternative != 0)
9937    output_asm_insn (\"mov%d5\\t%0, %1\", operands);
9938  if (which_alternative != 1)
9939    output_asm_insn (\"mov%D5\\t%0, %2\", operands);
9940  return \"\";
9941  "
9942  [(set_attr "conds" "clob")
9943   (set_attr "length" "8,8,12")
9944   (set_attr "type" "multiple")]
9945)
9946
9947;; ??? The patterns below need checking for Thumb-2 usefulness.
9948
9949(define_insn "*ifcompare_plus_move"
9950  [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9951	(if_then_else:SI (match_operator 6 "arm_comparison_operator"
9952			  [(match_operand:SI 4 "s_register_operand" "r,r")
9953			   (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
9954			 (plus:SI
9955			  (match_operand:SI 2 "s_register_operand" "r,r")
9956			  (match_operand:SI 3 "arm_add_operand" "rIL,rIL"))
9957			 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))
9958   (clobber (reg:CC CC_REGNUM))]
9959  "TARGET_ARM"
9960  "#"
9961  [(set_attr "conds" "clob")
9962   (set_attr "length" "8,12")
9963   (set_attr "type" "multiple")]
9964)
9965
9966(define_insn "*if_plus_move"
9967  [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
9968	(if_then_else:SI
9969	 (match_operator 4 "arm_comparison_operator"
9970	  [(match_operand 5 "cc_register" "") (const_int 0)])
9971	 (plus:SI
9972	  (match_operand:SI 2 "s_register_operand" "r,r,r,r")
9973	  (match_operand:SI 3 "arm_add_operand" "rI,L,rI,L"))
9974	 (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")))]
9975  "TARGET_ARM"
9976  "@
9977   add%d4\\t%0, %2, %3
9978   sub%d4\\t%0, %2, #%n3
9979   add%d4\\t%0, %2, %3\;mov%D4\\t%0, %1
9980   sub%d4\\t%0, %2, #%n3\;mov%D4\\t%0, %1"
9981  [(set_attr "conds" "use")
9982   (set_attr "length" "4,4,8,8")
9983   (set_attr_alternative "type"
9984                         [(if_then_else (match_operand 3 "const_int_operand" "")
9985                                        (const_string "alu_imm" )
9986                                        (const_string "alu_sreg"))
9987                          (const_string "alu_imm")
9988                          (const_string "multiple")
9989                          (const_string "multiple")])]
9990)
9991
9992(define_insn "*ifcompare_move_plus"
9993  [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9994	(if_then_else:SI (match_operator 6 "arm_comparison_operator"
9995			  [(match_operand:SI 4 "s_register_operand" "r,r")
9996			   (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
9997			 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
9998			 (plus:SI
9999			  (match_operand:SI 2 "s_register_operand" "r,r")
10000			  (match_operand:SI 3 "arm_add_operand" "rIL,rIL"))))
10001   (clobber (reg:CC CC_REGNUM))]
10002  "TARGET_ARM"
10003  "#"
10004  [(set_attr "conds" "clob")
10005   (set_attr "length" "8,12")
10006   (set_attr "type" "multiple")]
10007)
10008
10009(define_insn "*if_move_plus"
10010  [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
10011	(if_then_else:SI
10012	 (match_operator 4 "arm_comparison_operator"
10013	  [(match_operand 5 "cc_register" "") (const_int 0)])
10014	 (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")
10015	 (plus:SI
10016	  (match_operand:SI 2 "s_register_operand" "r,r,r,r")
10017	  (match_operand:SI 3 "arm_add_operand" "rI,L,rI,L"))))]
10018  "TARGET_ARM"
10019  "@
10020   add%D4\\t%0, %2, %3
10021   sub%D4\\t%0, %2, #%n3
10022   add%D4\\t%0, %2, %3\;mov%d4\\t%0, %1
10023   sub%D4\\t%0, %2, #%n3\;mov%d4\\t%0, %1"
10024  [(set_attr "conds" "use")
10025   (set_attr "length" "4,4,8,8")
10026   (set_attr_alternative "type"
10027                         [(if_then_else (match_operand 3 "const_int_operand" "")
10028                                        (const_string "alu_imm" )
10029                                        (const_string "alu_sreg"))
10030                          (const_string "alu_imm")
10031                          (const_string "multiple")
10032                          (const_string "multiple")])]
10033)
10034
10035(define_insn "*ifcompare_arith_arith"
10036  [(set (match_operand:SI 0 "s_register_operand" "=r")
10037	(if_then_else:SI (match_operator 9 "arm_comparison_operator"
10038			  [(match_operand:SI 5 "s_register_operand" "r")
10039			   (match_operand:SI 6 "arm_add_operand" "rIL")])
10040			 (match_operator:SI 8 "shiftable_operator"
10041			  [(match_operand:SI 1 "s_register_operand" "r")
10042			   (match_operand:SI 2 "arm_rhs_operand" "rI")])
10043			 (match_operator:SI 7 "shiftable_operator"
10044			  [(match_operand:SI 3 "s_register_operand" "r")
10045			   (match_operand:SI 4 "arm_rhs_operand" "rI")])))
10046   (clobber (reg:CC CC_REGNUM))]
10047  "TARGET_ARM"
10048  "#"
10049  [(set_attr "conds" "clob")
10050   (set_attr "length" "12")
10051   (set_attr "type" "multiple")]
10052)
10053
10054(define_insn "*if_arith_arith"
10055  [(set (match_operand:SI 0 "s_register_operand" "=r")
10056	(if_then_else:SI (match_operator 5 "arm_comparison_operator"
10057			  [(match_operand 8 "cc_register" "") (const_int 0)])
10058			 (match_operator:SI 6 "shiftable_operator"
10059			  [(match_operand:SI 1 "s_register_operand" "r")
10060			   (match_operand:SI 2 "arm_rhs_operand" "rI")])
10061			 (match_operator:SI 7 "shiftable_operator"
10062			  [(match_operand:SI 3 "s_register_operand" "r")
10063			   (match_operand:SI 4 "arm_rhs_operand" "rI")])))]
10064  "TARGET_ARM"
10065  "%I6%d5\\t%0, %1, %2\;%I7%D5\\t%0, %3, %4"
10066  [(set_attr "conds" "use")
10067   (set_attr "length" "8")
10068   (set_attr "type" "multiple")]
10069)
10070
10071(define_insn "*ifcompare_arith_move"
10072  [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10073	(if_then_else:SI (match_operator 6 "arm_comparison_operator"
10074			  [(match_operand:SI 2 "s_register_operand" "r,r")
10075			   (match_operand:SI 3 "arm_add_operand" "rIL,rIL")])
10076			 (match_operator:SI 7 "shiftable_operator"
10077			  [(match_operand:SI 4 "s_register_operand" "r,r")
10078			   (match_operand:SI 5 "arm_rhs_operand" "rI,rI")])
10079			 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))
10080   (clobber (reg:CC CC_REGNUM))]
10081  "TARGET_ARM"
10082  "*
10083  /* If we have an operation where (op x 0) is the identity operation and
10084     the conditional operator is LT or GE and we are comparing against zero and
10085     everything is in registers then we can do this in two instructions.  */
10086  if (operands[3] == const0_rtx
10087      && GET_CODE (operands[7]) != AND
10088      && REG_P (operands[5])
10089      && REG_P (operands[1])
10090      && REGNO (operands[1]) == REGNO (operands[4])
10091      && REGNO (operands[4]) != REGNO (operands[0]))
10092    {
10093      if (GET_CODE (operands[6]) == LT)
10094	return \"and\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\";
10095      else if (GET_CODE (operands[6]) == GE)
10096	return \"bic\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\";
10097    }
10098  if (CONST_INT_P (operands[3])
10099      && !const_ok_for_arm (INTVAL (operands[3])))
10100    output_asm_insn (\"cmn\\t%2, #%n3\", operands);
10101  else
10102    output_asm_insn (\"cmp\\t%2, %3\", operands);
10103  output_asm_insn (\"%I7%d6\\t%0, %4, %5\", operands);
10104  if (which_alternative != 0)
10105    return \"mov%D6\\t%0, %1\";
10106  return \"\";
10107  "
10108  [(set_attr "conds" "clob")
10109   (set_attr "length" "8,12")
10110   (set_attr "type" "multiple")]
10111)
10112
10113(define_insn "*if_arith_move"
10114  [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10115	(if_then_else:SI (match_operator 4 "arm_comparison_operator"
10116			  [(match_operand 6 "cc_register" "") (const_int 0)])
10117			 (match_operator:SI 5 "shiftable_operator"
10118			  [(match_operand:SI 2 "s_register_operand" "r,r")
10119			   (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
10120			 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))]
10121  "TARGET_ARM"
10122  "@
10123   %I5%d4\\t%0, %2, %3
10124   %I5%d4\\t%0, %2, %3\;mov%D4\\t%0, %1"
10125  [(set_attr "conds" "use")
10126   (set_attr "length" "4,8")
10127   (set_attr_alternative "type"
10128                         [(if_then_else (match_operand 3 "const_int_operand" "")
10129                                        (const_string "alu_shift_imm" )
10130                                        (const_string "alu_shift_reg"))
10131                          (const_string "multiple")])]
10132)
10133
10134(define_insn "*ifcompare_move_arith"
10135  [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10136	(if_then_else:SI (match_operator 6 "arm_comparison_operator"
10137			  [(match_operand:SI 4 "s_register_operand" "r,r")
10138			   (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
10139			 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
10140			 (match_operator:SI 7 "shiftable_operator"
10141			  [(match_operand:SI 2 "s_register_operand" "r,r")
10142			   (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
10143   (clobber (reg:CC CC_REGNUM))]
10144  "TARGET_ARM"
10145  "*
10146  /* If we have an operation where (op x 0) is the identity operation and
10147     the conditional operator is LT or GE and we are comparing against zero and
10148     everything is in registers then we can do this in two instructions */
10149  if (operands[5] == const0_rtx
10150      && GET_CODE (operands[7]) != AND
10151      && REG_P (operands[3])
10152      && REG_P (operands[1])
10153      && REGNO (operands[1]) == REGNO (operands[2])
10154      && REGNO (operands[2]) != REGNO (operands[0]))
10155    {
10156      if (GET_CODE (operands[6]) == GE)
10157	return \"and\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\";
10158      else if (GET_CODE (operands[6]) == LT)
10159	return \"bic\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\";
10160    }
10161
10162  if (CONST_INT_P (operands[5])
10163      && !const_ok_for_arm (INTVAL (operands[5])))
10164    output_asm_insn (\"cmn\\t%4, #%n5\", operands);
10165  else
10166    output_asm_insn (\"cmp\\t%4, %5\", operands);
10167
10168  if (which_alternative != 0)
10169    output_asm_insn (\"mov%d6\\t%0, %1\", operands);
10170  return \"%I7%D6\\t%0, %2, %3\";
10171  "
10172  [(set_attr "conds" "clob")
10173   (set_attr "length" "8,12")
10174   (set_attr "type" "multiple")]
10175)
10176
10177(define_insn "*if_move_arith"
10178  [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10179	(if_then_else:SI
10180	 (match_operator 4 "arm_comparison_operator"
10181	  [(match_operand 6 "cc_register" "") (const_int 0)])
10182	 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
10183	 (match_operator:SI 5 "shiftable_operator"
10184	  [(match_operand:SI 2 "s_register_operand" "r,r")
10185	   (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))]
10186  "TARGET_ARM"
10187  "@
10188   %I5%D4\\t%0, %2, %3
10189   %I5%D4\\t%0, %2, %3\;mov%d4\\t%0, %1"
10190  [(set_attr "conds" "use")
10191   (set_attr "length" "4,8")
10192   (set_attr_alternative "type"
10193                         [(if_then_else (match_operand 3 "const_int_operand" "")
10194                                        (const_string "alu_shift_imm" )
10195                                        (const_string "alu_shift_reg"))
10196                          (const_string "multiple")])]
10197)
10198
10199(define_insn "*ifcompare_move_not"
10200  [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10201	(if_then_else:SI
10202	 (match_operator 5 "arm_comparison_operator"
10203	  [(match_operand:SI 3 "s_register_operand" "r,r")
10204	   (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
10205	 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
10206	 (not:SI
10207	  (match_operand:SI 2 "s_register_operand" "r,r"))))
10208   (clobber (reg:CC CC_REGNUM))]
10209  "TARGET_ARM"
10210  "#"
10211  [(set_attr "conds" "clob")
10212   (set_attr "length" "8,12")
10213   (set_attr "type" "multiple")]
10214)
10215
10216(define_insn "*if_move_not"
10217  [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
10218	(if_then_else:SI
10219	 (match_operator 4 "arm_comparison_operator"
10220	  [(match_operand 3 "cc_register" "") (const_int 0)])
10221	 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
10222	 (not:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))))]
10223  "TARGET_ARM"
10224  "@
10225   mvn%D4\\t%0, %2
10226   mov%d4\\t%0, %1\;mvn%D4\\t%0, %2
10227   mvn%d4\\t%0, #%B1\;mvn%D4\\t%0, %2"
10228  [(set_attr "conds" "use")
10229   (set_attr "type" "mvn_reg")
10230   (set_attr "length" "4,8,8")
10231   (set_attr "type" "mvn_reg,multiple,multiple")]
10232)
10233
10234(define_insn "*ifcompare_not_move"
10235  [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10236	(if_then_else:SI
10237	 (match_operator 5 "arm_comparison_operator"
10238	  [(match_operand:SI 3 "s_register_operand" "r,r")
10239	   (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
10240	 (not:SI
10241	  (match_operand:SI 2 "s_register_operand" "r,r"))
10242	 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
10243   (clobber (reg:CC CC_REGNUM))]
10244  "TARGET_ARM"
10245  "#"
10246  [(set_attr "conds" "clob")
10247   (set_attr "length" "8,12")
10248   (set_attr "type" "multiple")]
10249)
10250
10251(define_insn "*if_not_move"
10252  [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
10253	(if_then_else:SI
10254	 (match_operator 4 "arm_comparison_operator"
10255	  [(match_operand 3 "cc_register" "") (const_int 0)])
10256	 (not:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))
10257	 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
10258  "TARGET_ARM"
10259  "@
10260   mvn%d4\\t%0, %2
10261   mov%D4\\t%0, %1\;mvn%d4\\t%0, %2
10262   mvn%D4\\t%0, #%B1\;mvn%d4\\t%0, %2"
10263  [(set_attr "conds" "use")
10264   (set_attr "type" "mvn_reg,multiple,multiple")
10265   (set_attr "length" "4,8,8")]
10266)
10267
10268(define_insn "*ifcompare_shift_move"
10269  [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10270	(if_then_else:SI
10271	 (match_operator 6 "arm_comparison_operator"
10272	  [(match_operand:SI 4 "s_register_operand" "r,r")
10273	   (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
10274	 (match_operator:SI 7 "shift_operator"
10275	  [(match_operand:SI 2 "s_register_operand" "r,r")
10276	   (match_operand:SI 3 "arm_rhs_operand" "rM,rM")])
10277	 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
10278   (clobber (reg:CC CC_REGNUM))]
10279  "TARGET_ARM"
10280  "#"
10281  [(set_attr "conds" "clob")
10282   (set_attr "length" "8,12")
10283   (set_attr "type" "multiple")]
10284)
10285
10286(define_insn "*if_shift_move"
10287  [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
10288	(if_then_else:SI
10289	 (match_operator 5 "arm_comparison_operator"
10290	  [(match_operand 6 "cc_register" "") (const_int 0)])
10291	 (match_operator:SI 4 "shift_operator"
10292	  [(match_operand:SI 2 "s_register_operand" "r,r,r")
10293	   (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM")])
10294	 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
10295  "TARGET_ARM"
10296  "@
10297   mov%d5\\t%0, %2%S4
10298   mov%D5\\t%0, %1\;mov%d5\\t%0, %2%S4
10299   mvn%D5\\t%0, #%B1\;mov%d5\\t%0, %2%S4"
10300  [(set_attr "conds" "use")
10301   (set_attr "shift" "2")
10302   (set_attr "length" "4,8,8")
10303   (set_attr_alternative "type"
10304                         [(if_then_else (match_operand 3 "const_int_operand" "")
10305                                        (const_string "mov_shift" )
10306                                        (const_string "mov_shift_reg"))
10307                          (const_string "multiple")
10308                          (const_string "multiple")])]
10309)
10310
10311(define_insn "*ifcompare_move_shift"
10312  [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10313	(if_then_else:SI
10314	 (match_operator 6 "arm_comparison_operator"
10315	  [(match_operand:SI 4 "s_register_operand" "r,r")
10316	   (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
10317	 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
10318	 (match_operator:SI 7 "shift_operator"
10319	  [(match_operand:SI 2 "s_register_operand" "r,r")
10320	   (match_operand:SI 3 "arm_rhs_operand" "rM,rM")])))
10321   (clobber (reg:CC CC_REGNUM))]
10322  "TARGET_ARM"
10323  "#"
10324  [(set_attr "conds" "clob")
10325   (set_attr "length" "8,12")
10326   (set_attr "type" "multiple")]
10327)
10328
10329(define_insn "*if_move_shift"
10330  [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
10331	(if_then_else:SI
10332	 (match_operator 5 "arm_comparison_operator"
10333	  [(match_operand 6 "cc_register" "") (const_int 0)])
10334	 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
10335	 (match_operator:SI 4 "shift_operator"
10336	  [(match_operand:SI 2 "s_register_operand" "r,r,r")
10337	   (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM")])))]
10338  "TARGET_ARM"
10339  "@
10340   mov%D5\\t%0, %2%S4
10341   mov%d5\\t%0, %1\;mov%D5\\t%0, %2%S4
10342   mvn%d5\\t%0, #%B1\;mov%D5\\t%0, %2%S4"
10343  [(set_attr "conds" "use")
10344   (set_attr "shift" "2")
10345   (set_attr "length" "4,8,8")
10346   (set_attr_alternative "type"
10347                         [(if_then_else (match_operand 3 "const_int_operand" "")
10348                                        (const_string "mov_shift" )
10349                                        (const_string "mov_shift_reg"))
10350                          (const_string "multiple")
10351                          (const_string "multiple")])]
10352)
10353
10354(define_insn "*ifcompare_shift_shift"
10355  [(set (match_operand:SI 0 "s_register_operand" "=r")
10356	(if_then_else:SI
10357	 (match_operator 7 "arm_comparison_operator"
10358	  [(match_operand:SI 5 "s_register_operand" "r")
10359	   (match_operand:SI 6 "arm_add_operand" "rIL")])
10360	 (match_operator:SI 8 "shift_operator"
10361	  [(match_operand:SI 1 "s_register_operand" "r")
10362	   (match_operand:SI 2 "arm_rhs_operand" "rM")])
10363	 (match_operator:SI 9 "shift_operator"
10364	  [(match_operand:SI 3 "s_register_operand" "r")
10365	   (match_operand:SI 4 "arm_rhs_operand" "rM")])))
10366   (clobber (reg:CC CC_REGNUM))]
10367  "TARGET_ARM"
10368  "#"
10369  [(set_attr "conds" "clob")
10370   (set_attr "length" "12")
10371   (set_attr "type" "multiple")]
10372)
10373
10374(define_insn "*if_shift_shift"
10375  [(set (match_operand:SI 0 "s_register_operand" "=r")
10376	(if_then_else:SI
10377	 (match_operator 5 "arm_comparison_operator"
10378	  [(match_operand 8 "cc_register" "") (const_int 0)])
10379	 (match_operator:SI 6 "shift_operator"
10380	  [(match_operand:SI 1 "s_register_operand" "r")
10381	   (match_operand:SI 2 "arm_rhs_operand" "rM")])
10382	 (match_operator:SI 7 "shift_operator"
10383	  [(match_operand:SI 3 "s_register_operand" "r")
10384	   (match_operand:SI 4 "arm_rhs_operand" "rM")])))]
10385  "TARGET_ARM"
10386  "mov%d5\\t%0, %1%S6\;mov%D5\\t%0, %3%S7"
10387  [(set_attr "conds" "use")
10388   (set_attr "shift" "1")
10389   (set_attr "length" "8")
10390   (set (attr "type") (if_then_else
10391		        (and (match_operand 2 "const_int_operand" "")
10392                             (match_operand 4 "const_int_operand" ""))
10393		      (const_string "mov_shift")
10394		      (const_string "mov_shift_reg")))]
10395)
10396
10397(define_insn "*ifcompare_not_arith"
10398  [(set (match_operand:SI 0 "s_register_operand" "=r")
10399	(if_then_else:SI
10400	 (match_operator 6 "arm_comparison_operator"
10401	  [(match_operand:SI 4 "s_register_operand" "r")
10402	   (match_operand:SI 5 "arm_add_operand" "rIL")])
10403	 (not:SI (match_operand:SI 1 "s_register_operand" "r"))
10404	 (match_operator:SI 7 "shiftable_operator"
10405	  [(match_operand:SI 2 "s_register_operand" "r")
10406	   (match_operand:SI 3 "arm_rhs_operand" "rI")])))
10407   (clobber (reg:CC CC_REGNUM))]
10408  "TARGET_ARM"
10409  "#"
10410  [(set_attr "conds" "clob")
10411   (set_attr "length" "12")
10412   (set_attr "type" "multiple")]
10413)
10414
10415(define_insn "*if_not_arith"
10416  [(set (match_operand:SI 0 "s_register_operand" "=r")
10417	(if_then_else:SI
10418	 (match_operator 5 "arm_comparison_operator"
10419	  [(match_operand 4 "cc_register" "") (const_int 0)])
10420	 (not:SI (match_operand:SI 1 "s_register_operand" "r"))
10421	 (match_operator:SI 6 "shiftable_operator"
10422	  [(match_operand:SI 2 "s_register_operand" "r")
10423	   (match_operand:SI 3 "arm_rhs_operand" "rI")])))]
10424  "TARGET_ARM"
10425  "mvn%d5\\t%0, %1\;%I6%D5\\t%0, %2, %3"
10426  [(set_attr "conds" "use")
10427   (set_attr "type" "mvn_reg")
10428   (set_attr "length" "8")]
10429)
10430
10431(define_insn "*ifcompare_arith_not"
10432  [(set (match_operand:SI 0 "s_register_operand" "=r")
10433	(if_then_else:SI
10434	 (match_operator 6 "arm_comparison_operator"
10435	  [(match_operand:SI 4 "s_register_operand" "r")
10436	   (match_operand:SI 5 "arm_add_operand" "rIL")])
10437	 (match_operator:SI 7 "shiftable_operator"
10438	  [(match_operand:SI 2 "s_register_operand" "r")
10439	   (match_operand:SI 3 "arm_rhs_operand" "rI")])
10440	 (not:SI (match_operand:SI 1 "s_register_operand" "r"))))
10441   (clobber (reg:CC CC_REGNUM))]
10442  "TARGET_ARM"
10443  "#"
10444  [(set_attr "conds" "clob")
10445   (set_attr "length" "12")
10446   (set_attr "type" "multiple")]
10447)
10448
10449(define_insn "*if_arith_not"
10450  [(set (match_operand:SI 0 "s_register_operand" "=r")
10451	(if_then_else:SI
10452	 (match_operator 5 "arm_comparison_operator"
10453	  [(match_operand 4 "cc_register" "") (const_int 0)])
10454	 (match_operator:SI 6 "shiftable_operator"
10455	  [(match_operand:SI 2 "s_register_operand" "r")
10456	   (match_operand:SI 3 "arm_rhs_operand" "rI")])
10457	 (not:SI (match_operand:SI 1 "s_register_operand" "r"))))]
10458  "TARGET_ARM"
10459  "mvn%D5\\t%0, %1\;%I6%d5\\t%0, %2, %3"
10460  [(set_attr "conds" "use")
10461   (set_attr "type" "multiple")
10462   (set_attr "length" "8")]
10463)
10464
10465(define_insn "*ifcompare_neg_move"
10466  [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10467	(if_then_else:SI
10468	 (match_operator 5 "arm_comparison_operator"
10469	  [(match_operand:SI 3 "s_register_operand" "r,r")
10470	   (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
10471	 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r"))
10472	 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
10473   (clobber (reg:CC CC_REGNUM))]
10474  "TARGET_ARM"
10475  "#"
10476  [(set_attr "conds" "clob")
10477   (set_attr "length" "8,12")
10478   (set_attr "type" "multiple")]
10479)
10480
10481(define_insn_and_split "*if_neg_move"
10482  [(set (match_operand:SI 0 "s_register_operand" "=l,r")
10483	(if_then_else:SI
10484	 (match_operator 4 "arm_comparison_operator"
10485	  [(match_operand 3 "cc_register" "") (const_int 0)])
10486	 (neg:SI (match_operand:SI 2 "s_register_operand" "l,r"))
10487	 (match_operand:SI 1 "s_register_operand" "0,0")))]
10488  "TARGET_32BIT"
10489  "#"
10490  "&& reload_completed"
10491  [(cond_exec (match_op_dup 4 [(match_dup 3) (const_int 0)])
10492	      (set (match_dup 0) (neg:SI (match_dup 2))))]
10493  ""
10494  [(set_attr "conds" "use")
10495   (set_attr "length" "4")
10496   (set_attr "arch" "t2,32")
10497   (set_attr "enabled_for_short_it" "yes,no")
10498   (set_attr "type" "logic_shift_imm")]
10499)
10500
10501(define_insn "*ifcompare_move_neg"
10502  [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10503	(if_then_else:SI
10504	 (match_operator 5 "arm_comparison_operator"
10505	  [(match_operand:SI 3 "s_register_operand" "r,r")
10506	   (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
10507	 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
10508	 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r"))))
10509   (clobber (reg:CC CC_REGNUM))]
10510  "TARGET_ARM"
10511  "#"
10512  [(set_attr "conds" "clob")
10513   (set_attr "length" "8,12")
10514   (set_attr "type" "multiple")]
10515)
10516
10517(define_insn_and_split "*if_move_neg"
10518  [(set (match_operand:SI 0 "s_register_operand" "=l,r")
10519	(if_then_else:SI
10520	 (match_operator 4 "arm_comparison_operator"
10521	  [(match_operand 3 "cc_register" "") (const_int 0)])
10522	 (match_operand:SI 1 "s_register_operand" "0,0")
10523	 (neg:SI (match_operand:SI 2 "s_register_operand" "l,r"))))]
10524  "TARGET_32BIT"
10525  "#"
10526  "&& reload_completed"
10527  [(cond_exec (match_dup 5)
10528	      (set (match_dup 0) (neg:SI (match_dup 2))))]
10529  {
10530    machine_mode mode = GET_MODE (operands[3]);
10531    rtx_code rc = GET_CODE (operands[4]);
10532
10533    if (mode == CCFPmode || mode == CCFPEmode)
10534      rc = reverse_condition_maybe_unordered (rc);
10535    else
10536      rc = reverse_condition (rc);
10537
10538    operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[3], const0_rtx);
10539  }
10540  [(set_attr "conds" "use")
10541   (set_attr "length" "4")
10542   (set_attr "arch" "t2,32")
10543   (set_attr "enabled_for_short_it" "yes,no")
10544   (set_attr "type" "logic_shift_imm")]
10545)
10546
10547(define_insn "*arith_adjacentmem"
10548  [(set (match_operand:SI 0 "s_register_operand" "=r")
10549	(match_operator:SI 1 "shiftable_operator"
10550	 [(match_operand:SI 2 "memory_operand" "m")
10551	  (match_operand:SI 3 "memory_operand" "m")]))
10552   (clobber (match_scratch:SI 4 "=r"))]
10553  "TARGET_ARM && adjacent_mem_locations (operands[2], operands[3])"
10554  "*
10555  {
10556    rtx ldm[3];
10557    rtx arith[4];
10558    rtx base_reg;
10559    HOST_WIDE_INT val1 = 0, val2 = 0;
10560
10561    if (REGNO (operands[0]) > REGNO (operands[4]))
10562      {
10563	ldm[1] = operands[4];
10564	ldm[2] = operands[0];
10565      }
10566    else
10567      {
10568	ldm[1] = operands[0];
10569	ldm[2] = operands[4];
10570      }
10571
10572    base_reg = XEXP (operands[2], 0);
10573
10574    if (!REG_P (base_reg))
10575      {
10576	val1 = INTVAL (XEXP (base_reg, 1));
10577	base_reg = XEXP (base_reg, 0);
10578      }
10579
10580    if (!REG_P (XEXP (operands[3], 0)))
10581      val2 = INTVAL (XEXP (XEXP (operands[3], 0), 1));
10582
10583    arith[0] = operands[0];
10584    arith[3] = operands[1];
10585
10586    if (val1 < val2)
10587      {
10588	arith[1] = ldm[1];
10589	arith[2] = ldm[2];
10590      }
10591    else
10592      {
10593	arith[1] = ldm[2];
10594	arith[2] = ldm[1];
10595      }
10596
10597    ldm[0] = base_reg;
10598    if (val1 !=0 && val2 != 0)
10599      {
10600	rtx ops[3];
10601
10602	if (val1 == 4 || val2 == 4)
10603	  /* Other val must be 8, since we know they are adjacent and neither
10604	     is zero.  */
10605	  output_asm_insn (\"ldmib%?\\t%0, {%1, %2}\", ldm);
10606	else if (const_ok_for_arm (val1) || const_ok_for_arm (-val1))
10607	  {
10608	    ldm[0] = ops[0] = operands[4];
10609	    ops[1] = base_reg;
10610	    ops[2] = GEN_INT (val1);
10611	    output_add_immediate (ops);
10612	    if (val1 < val2)
10613	      output_asm_insn (\"ldmia%?\\t%0, {%1, %2}\", ldm);
10614	    else
10615	      output_asm_insn (\"ldmda%?\\t%0, {%1, %2}\", ldm);
10616	  }
10617	else
10618	  {
10619	    /* Offset is out of range for a single add, so use two ldr.  */
10620	    ops[0] = ldm[1];
10621	    ops[1] = base_reg;
10622	    ops[2] = GEN_INT (val1);
10623	    output_asm_insn (\"ldr%?\\t%0, [%1, %2]\", ops);
10624	    ops[0] = ldm[2];
10625	    ops[2] = GEN_INT (val2);
10626	    output_asm_insn (\"ldr%?\\t%0, [%1, %2]\", ops);
10627	  }
10628      }
10629    else if (val1 != 0)
10630      {
10631	if (val1 < val2)
10632	  output_asm_insn (\"ldmda%?\\t%0, {%1, %2}\", ldm);
10633	else
10634	  output_asm_insn (\"ldmia%?\\t%0, {%1, %2}\", ldm);
10635      }
10636    else
10637      {
10638	if (val1 < val2)
10639	  output_asm_insn (\"ldmia%?\\t%0, {%1, %2}\", ldm);
10640	else
10641	  output_asm_insn (\"ldmda%?\\t%0, {%1, %2}\", ldm);
10642      }
10643    output_asm_insn (\"%I3%?\\t%0, %1, %2\", arith);
10644    return \"\";
10645  }"
10646  [(set_attr "length" "12")
10647   (set_attr "predicable" "yes")
10648   (set_attr "type" "load_4")]
10649)
10650
10651; This pattern is never tried by combine, so do it as a peephole
10652
10653(define_peephole2
10654  [(set (match_operand:SI 0 "arm_general_register_operand" "")
10655	(match_operand:SI 1 "arm_general_register_operand" ""))
10656   (set (reg:CC CC_REGNUM)
10657	(compare:CC (match_dup 1) (const_int 0)))]
10658  "TARGET_ARM"
10659  [(parallel [(set (reg:CC CC_REGNUM) (compare:CC (match_dup 1) (const_int 0)))
10660	      (set (match_dup 0) (match_dup 1))])]
10661  ""
10662)
10663
10664(define_split
10665  [(set (match_operand:SI 0 "s_register_operand" "")
10666	(and:SI (ge:SI (match_operand:SI 1 "s_register_operand" "")
10667		       (const_int 0))
10668		(neg:SI (match_operator:SI 2 "arm_comparison_operator"
10669			 [(match_operand:SI 3 "s_register_operand" "")
10670			  (match_operand:SI 4 "arm_rhs_operand" "")]))))
10671   (clobber (match_operand:SI 5 "s_register_operand" ""))]
10672  "TARGET_ARM"
10673  [(set (match_dup 5) (not:SI (ashiftrt:SI (match_dup 1) (const_int 31))))
10674   (set (match_dup 0) (and:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
10675			      (match_dup 5)))]
10676  ""
10677)
10678
10679;; This split can be used because CC_Z mode implies that the following
10680;; branch will be an equality, or an unsigned inequality, so the sign
10681;; extension is not needed.
10682
10683(define_split
10684  [(set (reg:CC_Z CC_REGNUM)
10685	(compare:CC_Z
10686	 (ashift:SI (subreg:SI (match_operand:QI 0 "memory_operand" "") 0)
10687		    (const_int 24))
10688	 (match_operand 1 "const_int_operand" "")))
10689   (clobber (match_scratch:SI 2 ""))]
10690  "TARGET_ARM
10691   && ((UINTVAL (operands[1]))
10692       == ((UINTVAL (operands[1])) >> 24) << 24)"
10693  [(set (match_dup 2) (zero_extend:SI (match_dup 0)))
10694   (set (reg:CC CC_REGNUM) (compare:CC (match_dup 2) (match_dup 1)))]
10695  "
10696  operands[1] = GEN_INT (((unsigned long) INTVAL (operands[1])) >> 24);
10697  "
10698)
10699;; ??? Check the patterns above for Thumb-2 usefulness
10700
10701(define_expand "prologue"
10702  [(clobber (const_int 0))]
10703  "TARGET_EITHER"
10704  "if (TARGET_32BIT)
10705     arm_expand_prologue ();
10706   else
10707     thumb1_expand_prologue ();
10708  DONE;
10709  "
10710)
10711
10712(define_expand "epilogue"
10713  [(clobber (const_int 0))]
10714  "TARGET_EITHER"
10715  "
10716  if (crtl->calls_eh_return)
10717    emit_insn (gen_force_register_use (gen_rtx_REG (Pmode, 2)));
10718  if (TARGET_THUMB1)
10719   {
10720     thumb1_expand_epilogue ();
10721     emit_jump_insn (gen_rtx_UNSPEC_VOLATILE (VOIDmode,
10722                     gen_rtvec (1, ret_rtx), VUNSPEC_EPILOGUE));
10723   }
10724  else if (HAVE_return)
10725   {
10726     /* HAVE_return is testing for USE_RETURN_INSN (FALSE).  Hence,
10727        no need for explicit testing again.  */
10728     emit_jump_insn (gen_return ());
10729   }
10730  else if (TARGET_32BIT)
10731   {
10732    arm_expand_epilogue (true);
10733   }
10734  DONE;
10735  "
10736)
10737
10738;; Note - although unspec_volatile's USE all hard registers,
10739;; USEs are ignored after relaod has completed.  Thus we need
10740;; to add an unspec of the link register to ensure that flow
10741;; does not think that it is unused by the sibcall branch that
10742;; will replace the standard function epilogue.
10743(define_expand "sibcall_epilogue"
10744   [(parallel [(unspec:SI [(reg:SI LR_REGNUM)] UNSPEC_REGISTER_USE)
10745               (unspec_volatile [(return)] VUNSPEC_EPILOGUE)])]
10746   "TARGET_32BIT"
10747   "
10748   arm_expand_epilogue (false);
10749   DONE;
10750   "
10751)
10752
10753(define_expand "eh_epilogue"
10754  [(use (match_operand:SI 0 "register_operand" ""))
10755   (use (match_operand:SI 1 "register_operand" ""))
10756   (use (match_operand:SI 2 "register_operand" ""))]
10757  "TARGET_EITHER"
10758  "
10759  {
10760    cfun->machine->eh_epilogue_sp_ofs = operands[1];
10761    if (!REG_P (operands[2]) || REGNO (operands[2]) != 2)
10762      {
10763	rtx ra = gen_rtx_REG (Pmode, 2);
10764
10765	emit_move_insn (ra, operands[2]);
10766	operands[2] = ra;
10767      }
10768    /* This is a hack -- we may have crystalized the function type too
10769       early.  */
10770    cfun->machine->func_type = 0;
10771  }"
10772)
10773
10774;; This split is only used during output to reduce the number of patterns
10775;; that need assembler instructions adding to them.  We allowed the setting
10776;; of the conditions to be implicit during rtl generation so that
10777;; the conditional compare patterns would work.  However this conflicts to
10778;; some extent with the conditional data operations, so we have to split them
10779;; up again here.
10780
10781;; ??? Need to audit these splitters for Thumb-2.  Why isn't normal
10782;; conditional execution sufficient?
10783
10784(define_split
10785  [(set (match_operand:SI 0 "s_register_operand" "")
10786	(if_then_else:SI (match_operator 1 "arm_comparison_operator"
10787			  [(match_operand 2 "" "") (match_operand 3 "" "")])
10788			 (match_dup 0)
10789			 (match_operand 4 "" "")))
10790   (clobber (reg:CC CC_REGNUM))]
10791  "TARGET_ARM && reload_completed"
10792  [(set (match_dup 5) (match_dup 6))
10793   (cond_exec (match_dup 7)
10794	      (set (match_dup 0) (match_dup 4)))]
10795  "
10796  {
10797    machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10798					     operands[2], operands[3]);
10799    enum rtx_code rc = GET_CODE (operands[1]);
10800
10801    operands[5] = gen_rtx_REG (mode, CC_REGNUM);
10802    operands[6] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10803    if (mode == CCFPmode || mode == CCFPEmode)
10804      rc = reverse_condition_maybe_unordered (rc);
10805    else
10806      rc = reverse_condition (rc);
10807
10808    operands[7] = gen_rtx_fmt_ee (rc, VOIDmode, operands[5], const0_rtx);
10809  }"
10810)
10811
10812(define_split
10813  [(set (match_operand:SI 0 "s_register_operand" "")
10814	(if_then_else:SI (match_operator 1 "arm_comparison_operator"
10815			  [(match_operand 2 "" "") (match_operand 3 "" "")])
10816			 (match_operand 4 "" "")
10817			 (match_dup 0)))
10818   (clobber (reg:CC CC_REGNUM))]
10819  "TARGET_ARM && reload_completed"
10820  [(set (match_dup 5) (match_dup 6))
10821   (cond_exec (match_op_dup 1 [(match_dup 5) (const_int 0)])
10822	      (set (match_dup 0) (match_dup 4)))]
10823  "
10824  {
10825    machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10826					     operands[2], operands[3]);
10827
10828    operands[5] = gen_rtx_REG (mode, CC_REGNUM);
10829    operands[6] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10830  }"
10831)
10832
10833(define_split
10834  [(set (match_operand:SI 0 "s_register_operand" "")
10835	(if_then_else:SI (match_operator 1 "arm_comparison_operator"
10836			  [(match_operand 2 "" "") (match_operand 3 "" "")])
10837			 (match_operand 4 "" "")
10838			 (match_operand 5 "" "")))
10839   (clobber (reg:CC CC_REGNUM))]
10840  "TARGET_ARM && reload_completed"
10841  [(set (match_dup 6) (match_dup 7))
10842   (cond_exec (match_op_dup 1 [(match_dup 6) (const_int 0)])
10843	      (set (match_dup 0) (match_dup 4)))
10844   (cond_exec (match_dup 8)
10845	      (set (match_dup 0) (match_dup 5)))]
10846  "
10847  {
10848    machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10849					     operands[2], operands[3]);
10850    enum rtx_code rc = GET_CODE (operands[1]);
10851
10852    operands[6] = gen_rtx_REG (mode, CC_REGNUM);
10853    operands[7] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10854    if (mode == CCFPmode || mode == CCFPEmode)
10855      rc = reverse_condition_maybe_unordered (rc);
10856    else
10857      rc = reverse_condition (rc);
10858
10859    operands[8] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
10860  }"
10861)
10862
10863(define_split
10864  [(set (match_operand:SI 0 "s_register_operand" "")
10865	(if_then_else:SI (match_operator 1 "arm_comparison_operator"
10866			  [(match_operand:SI 2 "s_register_operand" "")
10867			   (match_operand:SI 3 "arm_add_operand" "")])
10868			 (match_operand:SI 4 "arm_rhs_operand" "")
10869			 (not:SI
10870			  (match_operand:SI 5 "s_register_operand" ""))))
10871   (clobber (reg:CC CC_REGNUM))]
10872  "TARGET_ARM && reload_completed"
10873  [(set (match_dup 6) (match_dup 7))
10874   (cond_exec (match_op_dup 1 [(match_dup 6) (const_int 0)])
10875	      (set (match_dup 0) (match_dup 4)))
10876   (cond_exec (match_dup 8)
10877	      (set (match_dup 0) (not:SI (match_dup 5))))]
10878  "
10879  {
10880    machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10881					     operands[2], operands[3]);
10882    enum rtx_code rc = GET_CODE (operands[1]);
10883
10884    operands[6] = gen_rtx_REG (mode, CC_REGNUM);
10885    operands[7] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10886    if (mode == CCFPmode || mode == CCFPEmode)
10887      rc = reverse_condition_maybe_unordered (rc);
10888    else
10889      rc = reverse_condition (rc);
10890
10891    operands[8] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
10892  }"
10893)
10894
10895(define_insn "*cond_move_not"
10896  [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10897	(if_then_else:SI (match_operator 4 "arm_comparison_operator"
10898			  [(match_operand 3 "cc_register" "") (const_int 0)])
10899			 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
10900			 (not:SI
10901			  (match_operand:SI 2 "s_register_operand" "r,r"))))]
10902  "TARGET_ARM"
10903  "@
10904   mvn%D4\\t%0, %2
10905   mov%d4\\t%0, %1\;mvn%D4\\t%0, %2"
10906  [(set_attr "conds" "use")
10907   (set_attr "type" "mvn_reg,multiple")
10908   (set_attr "length" "4,8")]
10909)
10910
10911;; The next two patterns occur when an AND operation is followed by a
10912;; scc insn sequence
10913
10914(define_insn "*sign_extract_onebit"
10915  [(set (match_operand:SI 0 "s_register_operand" "=r")
10916	(sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
10917			 (const_int 1)
10918			 (match_operand:SI 2 "const_int_operand" "n")))
10919    (clobber (reg:CC CC_REGNUM))]
10920  "TARGET_ARM"
10921  "*
10922    operands[2] = GEN_INT (1 << INTVAL (operands[2]));
10923    output_asm_insn (\"ands\\t%0, %1, %2\", operands);
10924    return \"mvnne\\t%0, #0\";
10925  "
10926  [(set_attr "conds" "clob")
10927   (set_attr "length" "8")
10928   (set_attr "type" "multiple")]
10929)
10930
10931(define_insn "*not_signextract_onebit"
10932  [(set (match_operand:SI 0 "s_register_operand" "=r")
10933	(not:SI
10934	 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
10935			  (const_int 1)
10936			  (match_operand:SI 2 "const_int_operand" "n"))))
10937   (clobber (reg:CC CC_REGNUM))]
10938  "TARGET_ARM"
10939  "*
10940    operands[2] = GEN_INT (1 << INTVAL (operands[2]));
10941    output_asm_insn (\"tst\\t%1, %2\", operands);
10942    output_asm_insn (\"mvneq\\t%0, #0\", operands);
10943    return \"movne\\t%0, #0\";
10944  "
10945  [(set_attr "conds" "clob")
10946   (set_attr "length" "12")
10947   (set_attr "type" "multiple")]
10948)
10949;; ??? The above patterns need auditing for Thumb-2
10950
10951;; Push multiple registers to the stack.  Registers are in parallel (use ...)
10952;; expressions.  For simplicity, the first register is also in the unspec
10953;; part.
10954;; To avoid the usage of GNU extension, the length attribute is computed
10955;; in a C function arm_attr_length_push_multi.
10956(define_insn "*push_multi"
10957  [(match_parallel 2 "multi_register_push"
10958    [(set (match_operand:BLK 0 "push_mult_memory_operand" "")
10959	  (unspec:BLK [(match_operand:SI 1 "s_register_operand" "")]
10960		      UNSPEC_PUSH_MULT))])]
10961  ""
10962  "*
10963  {
10964    int num_saves = XVECLEN (operands[2], 0);
10965
10966    /* For the StrongARM at least it is faster to
10967       use STR to store only a single register.
10968       In Thumb mode always use push, and the assembler will pick
10969       something appropriate.  */
10970    if (num_saves == 1 && TARGET_ARM)
10971      output_asm_insn (\"str%?\\t%1, [%m0, #-4]!\", operands);
10972    else
10973      {
10974	int i;
10975	char pattern[100];
10976
10977	if (TARGET_32BIT)
10978	    strcpy (pattern, \"push%?\\t{%1\");
10979	else
10980	    strcpy (pattern, \"push\\t{%1\");
10981
10982	for (i = 1; i < num_saves; i++)
10983	  {
10984	    strcat (pattern, \", %|\");
10985	    strcat (pattern,
10986		    reg_names[REGNO (XEXP (XVECEXP (operands[2], 0, i), 0))]);
10987	  }
10988
10989	strcat (pattern, \"}\");
10990	output_asm_insn (pattern, operands);
10991      }
10992
10993    return \"\";
10994  }"
10995  [(set_attr "type" "store_16")
10996   (set (attr "length")
10997	(symbol_ref "arm_attr_length_push_multi (operands[2], operands[1])"))]
10998)
10999
11000(define_insn "stack_tie"
11001  [(set (mem:BLK (scratch))
11002	(unspec:BLK [(match_operand:SI 0 "s_register_operand" "rk")
11003		     (match_operand:SI 1 "s_register_operand" "rk")]
11004		    UNSPEC_PRLG_STK))]
11005  ""
11006  ""
11007  [(set_attr "length" "0")
11008   (set_attr "type" "block")]
11009)
11010
11011;; Pop (as used in epilogue RTL)
11012;;
11013(define_insn "*load_multiple_with_writeback"
11014  [(match_parallel 0 "load_multiple_operation"
11015    [(set (match_operand:SI 1 "s_register_operand" "+rk")
11016          (plus:SI (match_dup 1)
11017                   (match_operand:SI 2 "const_int_I_operand" "I")))
11018     (set (match_operand:SI 3 "s_register_operand" "=rk")
11019          (mem:SI (match_dup 1)))
11020        ])]
11021  "TARGET_32BIT && (reload_in_progress || reload_completed)"
11022  "*
11023  {
11024    arm_output_multireg_pop (operands, /*return_pc=*/false,
11025                                       /*cond=*/const_true_rtx,
11026                                       /*reverse=*/false,
11027                                       /*update=*/true);
11028    return \"\";
11029  }
11030  "
11031  [(set_attr "type" "load_16")
11032   (set_attr "predicable" "yes")
11033   (set (attr "length")
11034	(symbol_ref "arm_attr_length_pop_multi (operands,
11035						/*return_pc=*/false,
11036						/*write_back_p=*/true)"))]
11037)
11038
11039;; Pop with return (as used in epilogue RTL)
11040;;
11041;; This instruction is generated when the registers are popped at the end of
11042;; epilogue.  Here, instead of popping the value into LR and then generating
11043;; jump to LR, value is popped into PC directly.  Hence, the pattern is combined
11044;;  with (return).
11045(define_insn "*pop_multiple_with_writeback_and_return"
11046  [(match_parallel 0 "pop_multiple_return"
11047    [(return)
11048     (set (match_operand:SI 1 "s_register_operand" "+rk")
11049          (plus:SI (match_dup 1)
11050                   (match_operand:SI 2 "const_int_I_operand" "I")))
11051     (set (match_operand:SI 3 "s_register_operand" "=rk")
11052          (mem:SI (match_dup 1)))
11053        ])]
11054  "TARGET_32BIT && (reload_in_progress || reload_completed)"
11055  "*
11056  {
11057    arm_output_multireg_pop (operands, /*return_pc=*/true,
11058                                       /*cond=*/const_true_rtx,
11059                                       /*reverse=*/false,
11060                                       /*update=*/true);
11061    return \"\";
11062  }
11063  "
11064  [(set_attr "type" "load_16")
11065   (set_attr "predicable" "yes")
11066   (set (attr "length")
11067	(symbol_ref "arm_attr_length_pop_multi (operands, /*return_pc=*/true,
11068						/*write_back_p=*/true)"))]
11069)
11070
11071(define_insn "*pop_multiple_with_return"
11072  [(match_parallel 0 "pop_multiple_return"
11073    [(return)
11074     (set (match_operand:SI 2 "s_register_operand" "=rk")
11075          (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
11076        ])]
11077  "TARGET_32BIT && (reload_in_progress || reload_completed)"
11078  "*
11079  {
11080    arm_output_multireg_pop (operands, /*return_pc=*/true,
11081                                       /*cond=*/const_true_rtx,
11082                                       /*reverse=*/false,
11083                                       /*update=*/false);
11084    return \"\";
11085  }
11086  "
11087  [(set_attr "type" "load_16")
11088   (set_attr "predicable" "yes")
11089   (set (attr "length")
11090	(symbol_ref "arm_attr_length_pop_multi (operands, /*return_pc=*/true,
11091						/*write_back_p=*/false)"))]
11092)
11093
11094;; Load into PC and return
11095(define_insn "*ldr_with_return"
11096  [(return)
11097   (set (reg:SI PC_REGNUM)
11098        (mem:SI (post_inc:SI (match_operand:SI 0 "s_register_operand" "+rk"))))]
11099  "TARGET_32BIT && (reload_in_progress || reload_completed)"
11100  "ldr%?\t%|pc, [%0], #4"
11101  [(set_attr "type" "load_4")
11102   (set_attr "predicable" "yes")]
11103)
11104;; Pop for floating point registers (as used in epilogue RTL)
11105(define_insn "*vfp_pop_multiple_with_writeback"
11106  [(match_parallel 0 "pop_multiple_fp"
11107    [(set (match_operand:SI 1 "s_register_operand" "+rk")
11108          (plus:SI (match_dup 1)
11109                   (match_operand:SI 2 "const_int_I_operand" "I")))
11110     (set (match_operand:DF 3 "vfp_hard_register_operand" "")
11111          (mem:DF (match_dup 1)))])]
11112  "TARGET_32BIT && TARGET_HARD_FLOAT"
11113  "*
11114  {
11115    int num_regs = XVECLEN (operands[0], 0);
11116    char pattern[100];
11117    rtx op_list[2];
11118    strcpy (pattern, \"vldm\\t\");
11119    strcat (pattern, reg_names[REGNO (SET_DEST (XVECEXP (operands[0], 0, 0)))]);
11120    strcat (pattern, \"!, {\");
11121    op_list[0] = XEXP (XVECEXP (operands[0], 0, 1), 0);
11122    strcat (pattern, \"%P0\");
11123    if ((num_regs - 1) > 1)
11124      {
11125        strcat (pattern, \"-%P1\");
11126        op_list [1] = XEXP (XVECEXP (operands[0], 0, num_regs - 1), 0);
11127      }
11128
11129    strcat (pattern, \"}\");
11130    output_asm_insn (pattern, op_list);
11131    return \"\";
11132  }
11133  "
11134  [(set_attr "type" "load_16")
11135   (set_attr "conds" "unconditional")
11136   (set_attr "predicable" "no")]
11137)
11138
11139;; Special patterns for dealing with the constant pool
11140
11141(define_insn "align_4"
11142  [(unspec_volatile [(const_int 0)] VUNSPEC_ALIGN)]
11143  "TARGET_EITHER"
11144  "*
11145  assemble_align (32);
11146  return \"\";
11147  "
11148  [(set_attr "type" "no_insn")]
11149)
11150
11151(define_insn "align_8"
11152  [(unspec_volatile [(const_int 0)] VUNSPEC_ALIGN8)]
11153  "TARGET_EITHER"
11154  "*
11155  assemble_align (64);
11156  return \"\";
11157  "
11158  [(set_attr "type" "no_insn")]
11159)
11160
11161(define_insn "consttable_end"
11162  [(unspec_volatile [(const_int 0)] VUNSPEC_POOL_END)]
11163  "TARGET_EITHER"
11164  "*
11165  making_const_table = FALSE;
11166  return \"\";
11167  "
11168  [(set_attr "type" "no_insn")]
11169)
11170
11171(define_insn "consttable_1"
11172  [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_1)]
11173  "TARGET_EITHER"
11174  "*
11175  making_const_table = TRUE;
11176  assemble_integer (operands[0], 1, BITS_PER_WORD, 1);
11177  assemble_zeros (3);
11178  return \"\";
11179  "
11180  [(set_attr "length" "4")
11181   (set_attr "type" "no_insn")]
11182)
11183
11184(define_insn "consttable_2"
11185  [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_2)]
11186  "TARGET_EITHER"
11187  "*
11188  {
11189    rtx x = operands[0];
11190    making_const_table = TRUE;
11191    switch (GET_MODE_CLASS (GET_MODE (x)))
11192      {
11193      case MODE_FLOAT:
11194	arm_emit_fp16_const (x);
11195	break;
11196      default:
11197	assemble_integer (operands[0], 2, BITS_PER_WORD, 1);
11198	assemble_zeros (2);
11199	break;
11200      }
11201    return \"\";
11202  }"
11203  [(set_attr "length" "4")
11204   (set_attr "type" "no_insn")]
11205)
11206
11207(define_insn "consttable_4"
11208  [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_4)]
11209  "TARGET_EITHER"
11210  "*
11211  {
11212    rtx x = operands[0];
11213    making_const_table = TRUE;
11214    scalar_float_mode float_mode;
11215    if (is_a <scalar_float_mode> (GET_MODE (x), &float_mode))
11216      assemble_real (*CONST_DOUBLE_REAL_VALUE (x), float_mode, BITS_PER_WORD);
11217    else
11218      {
11219	/* XXX: Sometimes gcc does something really dumb and ends up with
11220	   a HIGH in a constant pool entry, usually because it's trying to
11221	   load into a VFP register.  We know this will always be used in
11222	   combination with a LO_SUM which ignores the high bits, so just
11223	   strip off the HIGH.  */
11224	if (GET_CODE (x) == HIGH)
11225	  x = XEXP (x, 0);
11226        assemble_integer (x, 4, BITS_PER_WORD, 1);
11227	mark_symbol_refs_as_used (x);
11228      }
11229    return \"\";
11230  }"
11231  [(set_attr "length" "4")
11232   (set_attr "type" "no_insn")]
11233)
11234
11235(define_insn "consttable_8"
11236  [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_8)]
11237  "TARGET_EITHER"
11238  "*
11239  {
11240    making_const_table = TRUE;
11241    scalar_float_mode float_mode;
11242    if (is_a <scalar_float_mode> (GET_MODE (operands[0]), &float_mode))
11243      assemble_real (*CONST_DOUBLE_REAL_VALUE (operands[0]),
11244		     float_mode, BITS_PER_WORD);
11245    else
11246      assemble_integer (operands[0], 8, BITS_PER_WORD, 1);
11247    return \"\";
11248  }"
11249  [(set_attr "length" "8")
11250   (set_attr "type" "no_insn")]
11251)
11252
11253(define_insn "consttable_16"
11254  [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_16)]
11255  "TARGET_EITHER"
11256  "*
11257  {
11258    making_const_table = TRUE;
11259    scalar_float_mode float_mode;
11260    if (is_a <scalar_float_mode> (GET_MODE (operands[0]), &float_mode))
11261      assemble_real (*CONST_DOUBLE_REAL_VALUE (operands[0]),
11262		     float_mode, BITS_PER_WORD);
11263    else
11264      assemble_integer (operands[0], 16, BITS_PER_WORD, 1);
11265    return \"\";
11266  }"
11267  [(set_attr "length" "16")
11268   (set_attr "type" "no_insn")]
11269)
11270
11271;; V5 Instructions,
11272
11273(define_insn "clzsi2"
11274  [(set (match_operand:SI 0 "s_register_operand" "=r")
11275	(clz:SI (match_operand:SI 1 "s_register_operand" "r")))]
11276  "TARGET_32BIT && arm_arch5"
11277  "clz%?\\t%0, %1"
11278  [(set_attr "predicable" "yes")
11279   (set_attr "type" "clz")])
11280
11281(define_insn "rbitsi2"
11282  [(set (match_operand:SI 0 "s_register_operand" "=r")
11283	(unspec:SI [(match_operand:SI 1 "s_register_operand" "r")] UNSPEC_RBIT))]
11284  "TARGET_32BIT && arm_arch_thumb2"
11285  "rbit%?\\t%0, %1"
11286  [(set_attr "predicable" "yes")
11287   (set_attr "type" "clz")])
11288
11289;; Keep this as a CTZ expression until after reload and then split
11290;; into RBIT + CLZ.  Since RBIT is represented as an UNSPEC it is unlikely
11291;; to fold with any other expression.
11292
11293(define_insn_and_split "ctzsi2"
11294 [(set (match_operand:SI           0 "s_register_operand" "=r")
11295       (ctz:SI (match_operand:SI  1 "s_register_operand" "r")))]
11296  "TARGET_32BIT && arm_arch_thumb2"
11297  "#"
11298  "&& reload_completed"
11299  [(const_int 0)]
11300  "
11301  emit_insn (gen_rbitsi2 (operands[0], operands[1]));
11302  emit_insn (gen_clzsi2 (operands[0], operands[0]));
11303  DONE;
11304")
11305
11306;; V5E instructions.
11307
11308(define_insn "prefetch"
11309  [(prefetch (match_operand:SI 0 "address_operand" "p")
11310	     (match_operand:SI 1 "" "")
11311	     (match_operand:SI 2 "" ""))]
11312  "TARGET_32BIT && arm_arch5e"
11313  "pld\\t%a0"
11314  [(set_attr "type" "load_4")]
11315)
11316
11317;; General predication pattern
11318
11319(define_cond_exec
11320  [(match_operator 0 "arm_comparison_operator"
11321    [(match_operand 1 "cc_register" "")
11322     (const_int 0)])]
11323  "TARGET_32BIT
11324   && (!TARGET_NO_VOLATILE_CE || !volatile_refs_p (PATTERN (insn)))"
11325  ""
11326[(set_attr "predicated" "yes")]
11327)
11328
11329(define_insn "force_register_use"
11330  [(unspec:SI [(match_operand:SI 0 "register_operand" "")] UNSPEC_REGISTER_USE)]
11331  ""
11332  "%@ %0 needed"
11333  [(set_attr "length" "0")
11334   (set_attr "type" "no_insn")]
11335)
11336
11337
11338;; Patterns for exception handling
11339
11340(define_expand "eh_return"
11341  [(use (match_operand 0 "general_operand" ""))]
11342  "TARGET_EITHER"
11343  "
11344  {
11345    if (TARGET_32BIT)
11346      emit_insn (gen_arm_eh_return (operands[0]));
11347    else
11348      emit_insn (gen_thumb_eh_return (operands[0]));
11349    DONE;
11350  }"
11351)
11352
11353;; We can't expand this before we know where the link register is stored.
11354(define_insn_and_split "arm_eh_return"
11355  [(unspec_volatile [(match_operand:SI 0 "s_register_operand" "r")]
11356		    VUNSPEC_EH_RETURN)
11357   (clobber (match_scratch:SI 1 "=&r"))]
11358  "TARGET_ARM"
11359  "#"
11360  "&& reload_completed"
11361  [(const_int 0)]
11362  "
11363  {
11364    arm_set_return_address (operands[0], operands[1]);
11365    DONE;
11366  }"
11367)
11368
11369
11370;; TLS support
11371
11372(define_insn "load_tp_hard"
11373  [(set (match_operand:SI 0 "register_operand" "=r")
11374	(unspec:SI [(const_int 0)] UNSPEC_TLS))]
11375  "TARGET_HARD_TP"
11376  "mrc%?\\tp15, 0, %0, c13, c0, 3\\t@ load_tp_hard"
11377  [(set_attr "predicable" "yes")
11378   (set_attr "type" "mrs")]
11379)
11380
11381;; Doesn't clobber R1-R3.  Must use r0 for the first operand.
11382(define_insn "load_tp_soft"
11383  [(set (reg:SI 0) (unspec:SI [(const_int 0)] UNSPEC_TLS))
11384   (clobber (reg:SI LR_REGNUM))
11385   (clobber (reg:SI IP_REGNUM))
11386   (clobber (reg:CC CC_REGNUM))]
11387  "TARGET_SOFT_TP"
11388  "bl\\t__aeabi_read_tp\\t@ load_tp_soft"
11389  [(set_attr "conds" "clob")
11390   (set_attr "type" "branch")]
11391)
11392
11393;; tls descriptor call
11394(define_insn "tlscall"
11395  [(set (reg:SI R0_REGNUM)
11396        (unspec:SI [(reg:SI R0_REGNUM)
11397                    (match_operand:SI 0 "" "X")
11398	            (match_operand 1 "" "")] UNSPEC_TLS))
11399   (clobber (reg:SI R1_REGNUM))
11400   (clobber (reg:SI LR_REGNUM))
11401   (clobber (reg:SI CC_REGNUM))]
11402  "TARGET_GNU2_TLS"
11403  {
11404    targetm.asm_out.internal_label (asm_out_file, "LPIC",
11405				    INTVAL (operands[1]));
11406    return "bl\\t%c0(tlscall)";
11407  }
11408  [(set_attr "conds" "clob")
11409   (set_attr "length" "4")
11410   (set_attr "type" "branch")]
11411)
11412
11413;; For thread pointer builtin
11414(define_expand "get_thread_pointersi"
11415  [(match_operand:SI 0 "s_register_operand" "=r")]
11416 ""
11417 "
11418 {
11419   arm_load_tp (operands[0]);
11420   DONE;
11421 }")
11422
11423;;
11424
11425;; We only care about the lower 16 bits of the constant
11426;; being inserted into the upper 16 bits of the register.
11427(define_insn "*arm_movtas_ze"
11428  [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r,r")
11429                   (const_int 16)
11430                   (const_int 16))
11431        (match_operand:SI 1 "const_int_operand" ""))]
11432  "TARGET_HAVE_MOVT"
11433  "@
11434   movt%?\t%0, %L1
11435   movt\t%0, %L1"
11436 [(set_attr "arch" "32,v8mb")
11437  (set_attr "predicable" "yes")
11438  (set_attr "length" "4")
11439  (set_attr "type" "alu_sreg")]
11440)
11441
11442(define_insn "*arm_rev"
11443  [(set (match_operand:SI 0 "s_register_operand" "=l,l,r")
11444	(bswap:SI (match_operand:SI 1 "s_register_operand" "l,l,r")))]
11445  "arm_arch6"
11446  "@
11447   rev\t%0, %1
11448   rev%?\t%0, %1
11449   rev%?\t%0, %1"
11450  [(set_attr "arch" "t1,t2,32")
11451   (set_attr "length" "2,2,4")
11452   (set_attr "predicable" "no,yes,yes")
11453   (set_attr "type" "rev")]
11454)
11455
11456(define_expand "arm_legacy_rev"
11457  [(set (match_operand:SI 2 "s_register_operand" "")
11458	(xor:SI (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
11459			     (const_int 16))
11460		(match_dup 1)))
11461   (set (match_dup 2)
11462	(lshiftrt:SI (match_dup 2)
11463		     (const_int 8)))
11464   (set (match_operand:SI 3 "s_register_operand" "")
11465	(rotatert:SI (match_dup 1)
11466		     (const_int 8)))
11467   (set (match_dup 2)
11468	(and:SI (match_dup 2)
11469		(const_int -65281)))
11470   (set (match_operand:SI 0 "s_register_operand" "")
11471	(xor:SI (match_dup 3)
11472		(match_dup 2)))]
11473  "TARGET_32BIT"
11474  ""
11475)
11476
11477;; Reuse temporaries to keep register pressure down.
11478(define_expand "thumb_legacy_rev"
11479  [(set (match_operand:SI 2 "s_register_operand" "")
11480     (ashift:SI (match_operand:SI 1 "s_register_operand" "")
11481                (const_int 24)))
11482   (set (match_operand:SI 3 "s_register_operand" "")
11483     (lshiftrt:SI (match_dup 1)
11484		  (const_int 24)))
11485   (set (match_dup 3)
11486     (ior:SI (match_dup 3)
11487	     (match_dup 2)))
11488   (set (match_operand:SI 4 "s_register_operand" "")
11489     (const_int 16))
11490   (set (match_operand:SI 5 "s_register_operand" "")
11491     (rotatert:SI (match_dup 1)
11492		  (match_dup 4)))
11493   (set (match_dup 2)
11494     (ashift:SI (match_dup 5)
11495                (const_int 24)))
11496   (set (match_dup 5)
11497     (lshiftrt:SI (match_dup 5)
11498		  (const_int 24)))
11499   (set (match_dup 5)
11500     (ior:SI (match_dup 5)
11501	     (match_dup 2)))
11502   (set (match_dup 5)
11503     (rotatert:SI (match_dup 5)
11504		  (match_dup 4)))
11505   (set (match_operand:SI 0 "s_register_operand" "")
11506     (ior:SI (match_dup 5)
11507             (match_dup 3)))]
11508  "TARGET_THUMB"
11509  ""
11510)
11511
11512;; ARM-specific expansion of signed mod by power of 2
11513;; using conditional negate.
11514;; For r0 % n where n is a power of 2 produce:
11515;; rsbs    r1, r0, #0
11516;; and     r0, r0, #(n - 1)
11517;; and     r1, r1, #(n - 1)
11518;; rsbpl   r0, r1, #0
11519
11520(define_expand "modsi3"
11521  [(match_operand:SI 0 "register_operand" "")
11522   (match_operand:SI 1 "register_operand" "")
11523   (match_operand:SI 2 "const_int_operand" "")]
11524  "TARGET_32BIT"
11525  {
11526    HOST_WIDE_INT val = INTVAL (operands[2]);
11527
11528    if (val <= 0
11529       || exact_log2 (val) <= 0)
11530      FAIL;
11531
11532    rtx mask = GEN_INT (val - 1);
11533
11534    /* In the special case of x0 % 2 we can do the even shorter:
11535	cmp     r0, #0
11536	and     r0, r0, #1
11537	rsblt   r0, r0, #0.  */
11538
11539    if (val == 2)
11540      {
11541	rtx cc_reg = arm_gen_compare_reg (LT,
11542					  operands[1], const0_rtx, NULL_RTX);
11543	rtx cond = gen_rtx_LT (SImode, cc_reg, const0_rtx);
11544	rtx masked = gen_reg_rtx (SImode);
11545
11546	emit_insn (gen_andsi3 (masked, operands[1], mask));
11547	emit_move_insn (operands[0],
11548			gen_rtx_IF_THEN_ELSE (SImode, cond,
11549					      gen_rtx_NEG (SImode,
11550							   masked),
11551					      masked));
11552	DONE;
11553      }
11554
11555    rtx neg_op = gen_reg_rtx (SImode);
11556    rtx_insn *insn = emit_insn (gen_subsi3_compare0 (neg_op, const0_rtx,
11557						      operands[1]));
11558
11559    /* Extract the condition register and mode.  */
11560    rtx cmp = XVECEXP (PATTERN (insn), 0, 0);
11561    rtx cc_reg = SET_DEST (cmp);
11562    rtx cond = gen_rtx_GE (SImode, cc_reg, const0_rtx);
11563
11564    emit_insn (gen_andsi3 (operands[0], operands[1], mask));
11565
11566    rtx masked_neg = gen_reg_rtx (SImode);
11567    emit_insn (gen_andsi3 (masked_neg, neg_op, mask));
11568
11569    /* We want a conditional negate here, but emitting COND_EXEC rtxes
11570       during expand does not always work.  Do an IF_THEN_ELSE instead.  */
11571    emit_move_insn (operands[0],
11572		    gen_rtx_IF_THEN_ELSE (SImode, cond,
11573					  gen_rtx_NEG (SImode, masked_neg),
11574					  operands[0]));
11575
11576
11577    DONE;
11578  }
11579)
11580
11581(define_expand "bswapsi2"
11582  [(set (match_operand:SI 0 "s_register_operand" "=r")
11583  	(bswap:SI (match_operand:SI 1 "s_register_operand" "r")))]
11584"TARGET_EITHER && (arm_arch6 || !optimize_size)"
11585"
11586    if (!arm_arch6)
11587      {
11588	rtx op2 = gen_reg_rtx (SImode);
11589	rtx op3 = gen_reg_rtx (SImode);
11590
11591	if (TARGET_THUMB)
11592	  {
11593	    rtx op4 = gen_reg_rtx (SImode);
11594	    rtx op5 = gen_reg_rtx (SImode);
11595
11596	    emit_insn (gen_thumb_legacy_rev (operands[0], operands[1],
11597					     op2, op3, op4, op5));
11598	  }
11599	else
11600	  {
11601	    emit_insn (gen_arm_legacy_rev (operands[0], operands[1],
11602					   op2, op3));
11603	  }
11604
11605	DONE;
11606      }
11607  "
11608)
11609
11610;; bswap16 patterns: use revsh and rev16 instructions for the signed
11611;; and unsigned variants, respectively. For rev16, expose
11612;; byte-swapping in the lower 16 bits only.
11613(define_insn "*arm_revsh"
11614  [(set (match_operand:SI 0 "s_register_operand" "=l,l,r")
11615	(sign_extend:SI (bswap:HI (match_operand:HI 1 "s_register_operand" "l,l,r"))))]
11616  "arm_arch6"
11617  "@
11618  revsh\t%0, %1
11619  revsh%?\t%0, %1
11620  revsh%?\t%0, %1"
11621  [(set_attr "arch" "t1,t2,32")
11622   (set_attr "length" "2,2,4")
11623   (set_attr "type" "rev")]
11624)
11625
11626(define_insn "*arm_rev16"
11627  [(set (match_operand:HI 0 "s_register_operand" "=l,l,r")
11628	(bswap:HI (match_operand:HI 1 "s_register_operand" "l,l,r")))]
11629  "arm_arch6"
11630  "@
11631   rev16\t%0, %1
11632   rev16%?\t%0, %1
11633   rev16%?\t%0, %1"
11634  [(set_attr "arch" "t1,t2,32")
11635   (set_attr "length" "2,2,4")
11636   (set_attr "type" "rev")]
11637)
11638
11639;; There are no canonicalisation rules for the position of the lshiftrt, ashift
11640;; operations within an IOR/AND RTX, therefore we have two patterns matching
11641;; each valid permutation.
11642
11643(define_insn "arm_rev16si2"
11644  [(set (match_operand:SI 0 "register_operand" "=l,l,r")
11645        (ior:SI (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "l,l,r")
11646                                   (const_int 8))
11647                        (match_operand:SI 3 "const_int_operand" "n,n,n"))
11648                (and:SI (lshiftrt:SI (match_dup 1)
11649                                     (const_int 8))
11650                        (match_operand:SI 2 "const_int_operand" "n,n,n"))))]
11651  "arm_arch6
11652   && aarch_rev16_shleft_mask_imm_p (operands[3], SImode)
11653   && aarch_rev16_shright_mask_imm_p (operands[2], SImode)"
11654  "rev16\\t%0, %1"
11655  [(set_attr "arch" "t1,t2,32")
11656   (set_attr "length" "2,2,4")
11657   (set_attr "type" "rev")]
11658)
11659
11660(define_insn "arm_rev16si2_alt"
11661  [(set (match_operand:SI 0 "register_operand" "=l,l,r")
11662        (ior:SI (and:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "l,l,r")
11663                                     (const_int 8))
11664                        (match_operand:SI 2 "const_int_operand" "n,n,n"))
11665                (and:SI (ashift:SI (match_dup 1)
11666                                   (const_int 8))
11667                        (match_operand:SI 3 "const_int_operand" "n,n,n"))))]
11668  "arm_arch6
11669   && aarch_rev16_shleft_mask_imm_p (operands[3], SImode)
11670   && aarch_rev16_shright_mask_imm_p (operands[2], SImode)"
11671  "rev16\\t%0, %1"
11672  [(set_attr "arch" "t1,t2,32")
11673   (set_attr "length" "2,2,4")
11674   (set_attr "type" "rev")]
11675)
11676
11677(define_expand "bswaphi2"
11678  [(set (match_operand:HI 0 "s_register_operand" "=r")
11679	(bswap:HI (match_operand:HI 1 "s_register_operand" "r")))]
11680"arm_arch6"
11681""
11682)
11683
11684;; Patterns for LDRD/STRD in Thumb2 mode
11685
11686(define_insn "*thumb2_ldrd"
11687  [(set (match_operand:SI 0 "s_register_operand" "=r")
11688        (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "rk")
11689                         (match_operand:SI 2 "ldrd_strd_offset_operand" "Do"))))
11690   (set (match_operand:SI 3 "s_register_operand" "=r")
11691        (mem:SI (plus:SI (match_dup 1)
11692                         (match_operand:SI 4 "const_int_operand" ""))))]
11693  "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11694     && ((INTVAL (operands[2]) + 4) == INTVAL (operands[4]))
11695     && (operands_ok_ldrd_strd (operands[0], operands[3],
11696                                  operands[1], INTVAL (operands[2]),
11697                                  false, true))"
11698  "ldrd%?\t%0, %3, [%1, %2]"
11699  [(set_attr "type" "load_8")
11700   (set_attr "predicable" "yes")])
11701
11702(define_insn "*thumb2_ldrd_base"
11703  [(set (match_operand:SI 0 "s_register_operand" "=r")
11704        (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
11705   (set (match_operand:SI 2 "s_register_operand" "=r")
11706        (mem:SI (plus:SI (match_dup 1)
11707                         (const_int 4))))]
11708  "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11709     && (operands_ok_ldrd_strd (operands[0], operands[2],
11710                                  operands[1], 0, false, true))"
11711  "ldrd%?\t%0, %2, [%1]"
11712  [(set_attr "type" "load_8")
11713   (set_attr "predicable" "yes")])
11714
11715(define_insn "*thumb2_ldrd_base_neg"
11716  [(set (match_operand:SI 0 "s_register_operand" "=r")
11717	(mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "rk")
11718                         (const_int -4))))
11719   (set (match_operand:SI 2 "s_register_operand" "=r")
11720        (mem:SI (match_dup 1)))]
11721  "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11722     && (operands_ok_ldrd_strd (operands[0], operands[2],
11723                                  operands[1], -4, false, true))"
11724  "ldrd%?\t%0, %2, [%1, #-4]"
11725  [(set_attr "type" "load_8")
11726   (set_attr "predicable" "yes")])
11727
11728(define_insn "*thumb2_strd"
11729  [(set (mem:SI (plus:SI (match_operand:SI 0 "s_register_operand" "rk")
11730                         (match_operand:SI 1 "ldrd_strd_offset_operand" "Do")))
11731        (match_operand:SI 2 "s_register_operand" "r"))
11732   (set (mem:SI (plus:SI (match_dup 0)
11733                         (match_operand:SI 3 "const_int_operand" "")))
11734        (match_operand:SI 4 "s_register_operand" "r"))]
11735  "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11736     && ((INTVAL (operands[1]) + 4) == INTVAL (operands[3]))
11737     && (operands_ok_ldrd_strd (operands[2], operands[4],
11738                                  operands[0], INTVAL (operands[1]),
11739                                  false, false))"
11740  "strd%?\t%2, %4, [%0, %1]"
11741  [(set_attr "type" "store_8")
11742   (set_attr "predicable" "yes")])
11743
11744(define_insn "*thumb2_strd_base"
11745  [(set (mem:SI (match_operand:SI 0 "s_register_operand" "rk"))
11746        (match_operand:SI 1 "s_register_operand" "r"))
11747   (set (mem:SI (plus:SI (match_dup 0)
11748                         (const_int 4)))
11749        (match_operand:SI 2 "s_register_operand" "r"))]
11750  "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11751     && (operands_ok_ldrd_strd (operands[1], operands[2],
11752                                  operands[0], 0, false, false))"
11753  "strd%?\t%1, %2, [%0]"
11754  [(set_attr "type" "store_8")
11755   (set_attr "predicable" "yes")])
11756
11757(define_insn "*thumb2_strd_base_neg"
11758  [(set (mem:SI (plus:SI (match_operand:SI 0 "s_register_operand" "rk")
11759                         (const_int -4)))
11760        (match_operand:SI 1 "s_register_operand" "r"))
11761   (set (mem:SI (match_dup 0))
11762        (match_operand:SI 2 "s_register_operand" "r"))]
11763  "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11764     && (operands_ok_ldrd_strd (operands[1], operands[2],
11765                                  operands[0], -4, false, false))"
11766  "strd%?\t%1, %2, [%0, #-4]"
11767  [(set_attr "type" "store_8")
11768   (set_attr "predicable" "yes")])
11769
11770;; ARMv8 CRC32 instructions.
11771(define_insn "<crc_variant>"
11772  [(set (match_operand:SI 0 "s_register_operand" "=r")
11773        (unspec:SI [(match_operand:SI 1 "s_register_operand" "r")
11774                    (match_operand:<crc_mode> 2 "s_register_operand" "r")]
11775         CRC))]
11776  "TARGET_CRC32"
11777  "<crc_variant>\\t%0, %1, %2"
11778  [(set_attr "type" "crc")
11779   (set_attr "conds" "unconditional")]
11780)
11781
11782;; Load the load/store double peephole optimizations.
11783(include "ldrdstrd.md")
11784
11785;; Load the load/store multiple patterns
11786(include "ldmstm.md")
11787
11788;; Patterns in ldmstm.md don't cover more than 4 registers. This pattern covers
11789;; large lists without explicit writeback generated for APCS_FRAME epilogue.
11790;; The operands are validated through the load_multiple_operation
11791;; match_parallel predicate rather than through constraints so enable it only
11792;; after reload.
11793(define_insn "*load_multiple"
11794  [(match_parallel 0 "load_multiple_operation"
11795    [(set (match_operand:SI 2 "s_register_operand" "=rk")
11796          (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
11797        ])]
11798  "TARGET_32BIT && reload_completed"
11799  "*
11800  {
11801    arm_output_multireg_pop (operands, /*return_pc=*/false,
11802                                       /*cond=*/const_true_rtx,
11803                                       /*reverse=*/false,
11804                                       /*update=*/false);
11805    return \"\";
11806  }
11807  "
11808  [(set_attr "predicable" "yes")]
11809)
11810
11811(define_expand "copysignsf3"
11812  [(match_operand:SF 0 "register_operand")
11813   (match_operand:SF 1 "register_operand")
11814   (match_operand:SF 2 "register_operand")]
11815  "TARGET_SOFT_FLOAT && arm_arch_thumb2"
11816  "{
11817     emit_move_insn (operands[0], operands[2]);
11818     emit_insn (gen_insv_t2 (simplify_gen_subreg (SImode, operands[0], SFmode, 0),
11819		GEN_INT (31), GEN_INT (0),
11820		simplify_gen_subreg (SImode, operands[1], SFmode, 0)));
11821     DONE;
11822  }"
11823)
11824
11825(define_expand "copysigndf3"
11826  [(match_operand:DF 0 "register_operand")
11827   (match_operand:DF 1 "register_operand")
11828   (match_operand:DF 2 "register_operand")]
11829  "TARGET_SOFT_FLOAT && arm_arch_thumb2"
11830  "{
11831     rtx op0_low = gen_lowpart (SImode, operands[0]);
11832     rtx op0_high = gen_highpart (SImode, operands[0]);
11833     rtx op1_low = gen_lowpart (SImode, operands[1]);
11834     rtx op1_high = gen_highpart (SImode, operands[1]);
11835     rtx op2_high = gen_highpart (SImode, operands[2]);
11836
11837     rtx scratch1 = gen_reg_rtx (SImode);
11838     rtx scratch2 = gen_reg_rtx (SImode);
11839     emit_move_insn (scratch1, op2_high);
11840     emit_move_insn (scratch2, op1_high);
11841
11842     emit_insn(gen_rtx_SET(scratch1,
11843			   gen_rtx_LSHIFTRT (SImode, op2_high, GEN_INT(31))));
11844     emit_insn(gen_insv_t2(scratch2, GEN_INT(1), GEN_INT(31), scratch1));
11845     emit_move_insn (op0_low, op1_low);
11846     emit_move_insn (op0_high, scratch2);
11847
11848     DONE;
11849  }"
11850)
11851
11852;; movmisalign patterns for HImode and SImode.
11853(define_expand "movmisalign<mode>"
11854  [(match_operand:HSI 0 "general_operand")
11855   (match_operand:HSI 1 "general_operand")]
11856  "unaligned_access"
11857{
11858  /* This pattern is not permitted to fail during expansion: if both arguments
11859     are non-registers (e.g. memory := constant), force operand 1 into a
11860     register.  */
11861  rtx (* gen_unaligned_load)(rtx, rtx);
11862  rtx tmp_dest = operands[0];
11863  if (!s_register_operand (operands[0], <MODE>mode)
11864      && !s_register_operand (operands[1], <MODE>mode))
11865    operands[1] = force_reg (<MODE>mode, operands[1]);
11866
11867  if (<MODE>mode == HImode)
11868   {
11869    gen_unaligned_load = gen_unaligned_loadhiu;
11870    tmp_dest = gen_reg_rtx (SImode);
11871   }
11872  else
11873    gen_unaligned_load = gen_unaligned_loadsi;
11874
11875  if (MEM_P (operands[1]))
11876   {
11877    emit_insn (gen_unaligned_load (tmp_dest, operands[1]));
11878    if (<MODE>mode == HImode)
11879      emit_move_insn (operands[0], gen_lowpart (HImode, tmp_dest));
11880   }
11881  else
11882    emit_insn (gen_unaligned_store<mode> (operands[0], operands[1]));
11883
11884  DONE;
11885})
11886
11887(define_insn "<cdp>"
11888  [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "n")
11889		     (match_operand:SI 1 "immediate_operand" "n")
11890		     (match_operand:SI 2 "immediate_operand" "n")
11891		     (match_operand:SI 3 "immediate_operand" "n")
11892		     (match_operand:SI 4 "immediate_operand" "n")
11893		     (match_operand:SI 5 "immediate_operand" "n")] CDPI)]
11894  "arm_coproc_builtin_available (VUNSPEC_<CDP>)"
11895{
11896  arm_const_bounds (operands[0], 0, 16);
11897  arm_const_bounds (operands[1], 0, 16);
11898  arm_const_bounds (operands[2], 0, (1 << 5));
11899  arm_const_bounds (operands[3], 0, (1 << 5));
11900  arm_const_bounds (operands[4], 0, (1 << 5));
11901  arm_const_bounds (operands[5], 0, 8);
11902  return "<cdp>\\tp%c0, %1, CR%c2, CR%c3, CR%c4, %5";
11903}
11904  [(set_attr "length" "4")
11905   (set_attr "type" "coproc")])
11906
11907(define_insn "*ldc"
11908  [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "n")
11909		     (match_operand:SI 1 "immediate_operand" "n")
11910		     (match_operand:SI 2 "memory_operand" "Uz")] LDCI)]
11911  "arm_coproc_builtin_available (VUNSPEC_<LDC>)"
11912{
11913  arm_const_bounds (operands[0], 0, 16);
11914  arm_const_bounds (operands[1], 0, (1 << 5));
11915  return "<ldc>\\tp%c0, CR%c1, %2";
11916}
11917  [(set_attr "length" "4")
11918   (set_attr "type" "coproc")])
11919
11920(define_insn "*stc"
11921  [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "n")
11922		     (match_operand:SI 1 "immediate_operand" "n")
11923		     (match_operand:SI 2 "memory_operand" "=Uz")] STCI)]
11924  "arm_coproc_builtin_available (VUNSPEC_<STC>)"
11925{
11926  arm_const_bounds (operands[0], 0, 16);
11927  arm_const_bounds (operands[1], 0, (1 << 5));
11928  return "<stc>\\tp%c0, CR%c1, %2";
11929}
11930  [(set_attr "length" "4")
11931   (set_attr "type" "coproc")])
11932
11933(define_expand "<ldc>"
11934  [(unspec_volatile [(match_operand:SI 0 "immediate_operand")
11935		     (match_operand:SI 1 "immediate_operand")
11936		     (mem:SI (match_operand:SI 2 "s_register_operand"))] LDCI)]
11937  "arm_coproc_builtin_available (VUNSPEC_<LDC>)")
11938
11939(define_expand "<stc>"
11940  [(unspec_volatile [(match_operand:SI 0 "immediate_operand")
11941		     (match_operand:SI 1 "immediate_operand")
11942		     (mem:SI (match_operand:SI 2 "s_register_operand"))] STCI)]
11943  "arm_coproc_builtin_available (VUNSPEC_<STC>)")
11944
11945(define_insn "<mcr>"
11946  [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "n")
11947		     (match_operand:SI 1 "immediate_operand" "n")
11948		     (match_operand:SI 2 "s_register_operand" "r")
11949		     (match_operand:SI 3 "immediate_operand" "n")
11950		     (match_operand:SI 4 "immediate_operand" "n")
11951		     (match_operand:SI 5 "immediate_operand" "n")] MCRI)
11952   (use (match_dup 2))]
11953  "arm_coproc_builtin_available (VUNSPEC_<MCR>)"
11954{
11955  arm_const_bounds (operands[0], 0, 16);
11956  arm_const_bounds (operands[1], 0, 8);
11957  arm_const_bounds (operands[3], 0, (1 << 5));
11958  arm_const_bounds (operands[4], 0, (1 << 5));
11959  arm_const_bounds (operands[5], 0, 8);
11960  return "<mcr>\\tp%c0, %1, %2, CR%c3, CR%c4, %5";
11961}
11962  [(set_attr "length" "4")
11963   (set_attr "type" "coproc")])
11964
11965(define_insn "<mrc>"
11966  [(set (match_operand:SI 0 "s_register_operand" "=r")
11967	(unspec_volatile:SI [(match_operand:SI 1 "immediate_operand" "n")
11968			  (match_operand:SI 2 "immediate_operand" "n")
11969			  (match_operand:SI 3 "immediate_operand" "n")
11970			  (match_operand:SI 4 "immediate_operand" "n")
11971			  (match_operand:SI 5 "immediate_operand" "n")] MRCI))]
11972  "arm_coproc_builtin_available (VUNSPEC_<MRC>)"
11973{
11974  arm_const_bounds (operands[1], 0, 16);
11975  arm_const_bounds (operands[2], 0, 8);
11976  arm_const_bounds (operands[3], 0, (1 << 5));
11977  arm_const_bounds (operands[4], 0, (1 << 5));
11978  arm_const_bounds (operands[5], 0, 8);
11979  return "<mrc>\\tp%c1, %2, %0, CR%c3, CR%c4, %5";
11980}
11981  [(set_attr "length" "4")
11982   (set_attr "type" "coproc")])
11983
11984(define_insn "<mcrr>"
11985  [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "n")
11986		     (match_operand:SI 1 "immediate_operand" "n")
11987		     (match_operand:DI 2 "s_register_operand" "r")
11988		     (match_operand:SI 3 "immediate_operand" "n")] MCRRI)
11989   (use (match_dup 2))]
11990  "arm_coproc_builtin_available (VUNSPEC_<MCRR>)"
11991{
11992  arm_const_bounds (operands[0], 0, 16);
11993  arm_const_bounds (operands[1], 0, 8);
11994  arm_const_bounds (operands[3], 0, (1 << 5));
11995  return "<mcrr>\\tp%c0, %1, %Q2, %R2, CR%c3";
11996}
11997  [(set_attr "length" "4")
11998   (set_attr "type" "coproc")])
11999
12000(define_insn "<mrrc>"
12001  [(set (match_operand:DI 0 "s_register_operand" "=r")
12002	(unspec_volatile:DI [(match_operand:SI 1 "immediate_operand" "n")
12003			  (match_operand:SI 2 "immediate_operand" "n")
12004			  (match_operand:SI 3 "immediate_operand" "n")] MRRCI))]
12005  "arm_coproc_builtin_available (VUNSPEC_<MRRC>)"
12006{
12007  arm_const_bounds (operands[1], 0, 16);
12008  arm_const_bounds (operands[2], 0, 8);
12009  arm_const_bounds (operands[3], 0, (1 << 5));
12010  return "<mrrc>\\tp%c1, %2, %Q0, %R0, CR%c3";
12011}
12012  [(set_attr "length" "4")
12013   (set_attr "type" "coproc")])
12014
12015;; Vector bits common to IWMMXT and Neon
12016(include "vec-common.md")
12017;; Load the Intel Wireless Multimedia Extension patterns
12018(include "iwmmxt.md")
12019;; Load the VFP co-processor patterns
12020(include "vfp.md")
12021;; Thumb-1 patterns
12022(include "thumb1.md")
12023;; Thumb-2 patterns
12024(include "thumb2.md")
12025;; Neon patterns
12026(include "neon.md")
12027;; Crypto patterns
12028(include "crypto.md")
12029;; Synchronization Primitives
12030(include "sync.md")
12031;; Fixed-point patterns
12032(include "arm-fixed.md")
12033