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,l,r")
4452	(unspec:SI [(match_operand:SI 1 "memory_operand" "m,Uw,m")]
4453		   UNSPEC_UNALIGNED_LOAD))]
4454  "unaligned_access"
4455  "@
4456   ldr\t%0, %1\t@ unaligned
4457   ldr%?\t%0, %1\t@ unaligned
4458   ldr%?\t%0, %1\t@ unaligned"
4459  [(set_attr "arch" "t1,t2,32")
4460   (set_attr "length" "2,2,4")
4461   (set_attr "predicable" "no,yes,yes")
4462   (set_attr "predicable_short_it" "no,yes,no")
4463   (set_attr "type" "load_4")])
4464
4465;; The 16-bit Thumb1 variant of ldrsh requires two registers in the
4466;; address (there's no immediate format).  That's tricky to support
4467;; here and we don't really need this pattern for that case, so only
4468;; enable for 32-bit ISAs.
4469(define_insn "unaligned_loadhis"
4470  [(set (match_operand:SI 0 "s_register_operand" "=r")
4471	(sign_extend:SI
4472	  (unspec:HI [(match_operand:HI 1 "memory_operand" "Uh")]
4473		     UNSPEC_UNALIGNED_LOAD)))]
4474  "unaligned_access && TARGET_32BIT"
4475  "ldrsh%?\t%0, %1\t@ unaligned"
4476  [(set_attr "predicable" "yes")
4477   (set_attr "type" "load_byte")])
4478
4479(define_insn "unaligned_loadhiu"
4480  [(set (match_operand:SI 0 "s_register_operand" "=l,l,r")
4481	(zero_extend:SI
4482	  (unspec:HI [(match_operand:HI 1 "memory_operand" "m,Uw,m")]
4483		     UNSPEC_UNALIGNED_LOAD)))]
4484  "unaligned_access"
4485  "@
4486   ldrh\t%0, %1\t@ unaligned
4487   ldrh%?\t%0, %1\t@ unaligned
4488   ldrh%?\t%0, %1\t@ unaligned"
4489  [(set_attr "arch" "t1,t2,32")
4490   (set_attr "length" "2,2,4")
4491   (set_attr "predicable" "no,yes,yes")
4492   (set_attr "predicable_short_it" "no,yes,no")
4493   (set_attr "type" "load_byte")])
4494
4495(define_insn "unaligned_storesi"
4496  [(set (match_operand:SI 0 "memory_operand" "=m,Uw,m")
4497	(unspec:SI [(match_operand:SI 1 "s_register_operand" "l,l,r")]
4498		   UNSPEC_UNALIGNED_STORE))]
4499  "unaligned_access"
4500  "@
4501   str\t%1, %0\t@ unaligned
4502   str%?\t%1, %0\t@ unaligned
4503   str%?\t%1, %0\t@ unaligned"
4504  [(set_attr "arch" "t1,t2,32")
4505   (set_attr "length" "2,2,4")
4506   (set_attr "predicable" "no,yes,yes")
4507   (set_attr "predicable_short_it" "no,yes,no")
4508   (set_attr "type" "store_4")])
4509
4510(define_insn "unaligned_storehi"
4511  [(set (match_operand:HI 0 "memory_operand" "=m,Uw,m")
4512	(unspec:HI [(match_operand:HI 1 "s_register_operand" "l,l,r")]
4513		   UNSPEC_UNALIGNED_STORE))]
4514  "unaligned_access"
4515  "@
4516   strh\t%1, %0\t@ unaligned
4517   strh%?\t%1, %0\t@ unaligned
4518   strh%?\t%1, %0\t@ unaligned"
4519  [(set_attr "arch" "t1,t2,32")
4520   (set_attr "length" "2,2,4")
4521   (set_attr "predicable" "no,yes,yes")
4522   (set_attr "predicable_short_it" "no,yes,no")
4523   (set_attr "type" "store_4")])
4524
4525
4526(define_insn "*extv_reg"
4527  [(set (match_operand:SI 0 "s_register_operand" "=r")
4528	(sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
4529			  (match_operand:SI 2 "const_int_operand" "n")
4530			  (match_operand:SI 3 "const_int_operand" "n")))]
4531  "arm_arch_thumb2
4532   && IN_RANGE (INTVAL (operands[3]), 0, 31)
4533   && IN_RANGE (INTVAL (operands[2]), 1, 32 - INTVAL (operands[3]))"
4534  "sbfx%?\t%0, %1, %3, %2"
4535  [(set_attr "length" "4")
4536   (set_attr "predicable" "yes")
4537   (set_attr "type" "bfm")]
4538)
4539
4540(define_insn "extzv_t2"
4541  [(set (match_operand:SI 0 "s_register_operand" "=r")
4542	(zero_extract:SI (match_operand:SI 1 "s_register_operand" "r")
4543			  (match_operand:SI 2 "const_int_operand" "n")
4544			  (match_operand:SI 3 "const_int_operand" "n")))]
4545  "arm_arch_thumb2
4546   && IN_RANGE (INTVAL (operands[3]), 0, 31)
4547   && IN_RANGE (INTVAL (operands[2]), 1, 32 - INTVAL (operands[3]))"
4548  "ubfx%?\t%0, %1, %3, %2"
4549  [(set_attr "length" "4")
4550   (set_attr "predicable" "yes")
4551   (set_attr "type" "bfm")]
4552)
4553
4554
4555;; Division instructions
4556(define_insn "divsi3"
4557  [(set (match_operand:SI	  0 "s_register_operand" "=r,r")
4558	(div:SI (match_operand:SI 1 "s_register_operand"  "r,r")
4559		(match_operand:SI 2 "s_register_operand"  "r,r")))]
4560  "TARGET_IDIV"
4561  "@
4562   sdiv%?\t%0, %1, %2
4563   sdiv\t%0, %1, %2"
4564  [(set_attr "arch" "32,v8mb")
4565   (set_attr "predicable" "yes")
4566   (set_attr "type" "sdiv")]
4567)
4568
4569(define_insn "udivsi3"
4570  [(set (match_operand:SI	   0 "s_register_operand" "=r,r")
4571	(udiv:SI (match_operand:SI 1 "s_register_operand"  "r,r")
4572		 (match_operand:SI 2 "s_register_operand"  "r,r")))]
4573  "TARGET_IDIV"
4574  "@
4575   udiv%?\t%0, %1, %2
4576   udiv\t%0, %1, %2"
4577  [(set_attr "arch" "32,v8mb")
4578   (set_attr "predicable" "yes")
4579   (set_attr "type" "udiv")]
4580)
4581
4582
4583;; Unary arithmetic insns
4584
4585(define_expand "negvsi3"
4586  [(match_operand:SI 0 "register_operand")
4587   (match_operand:SI 1 "register_operand")
4588   (match_operand 2 "")]
4589  "TARGET_32BIT"
4590{
4591  emit_insn (gen_subsi3_compare (operands[0], const0_rtx, operands[1]));
4592  arm_gen_unlikely_cbranch (NE, CC_Vmode, operands[2]);
4593
4594  DONE;
4595})
4596
4597(define_expand "negvdi3"
4598  [(match_operand:DI 0 "register_operand")
4599   (match_operand:DI 1 "register_operand")
4600   (match_operand 2 "")]
4601  "TARGET_ARM"
4602{
4603  emit_insn (gen_negdi2_compare (operands[0], operands[1]));
4604  arm_gen_unlikely_cbranch (NE, CC_Vmode, operands[2]);
4605
4606  DONE;
4607})
4608
4609
4610(define_insn_and_split "negdi2_compare"
4611  [(set (reg:CC CC_REGNUM)
4612	(compare:CC
4613	  (const_int 0)
4614	  (match_operand:DI 1 "register_operand" "0,r")))
4615   (set (match_operand:DI 0 "register_operand" "=r,&r")
4616	(minus:DI (const_int 0) (match_dup 1)))]
4617  "TARGET_ARM"
4618  "#"
4619  "&& reload_completed"
4620  [(parallel [(set (reg:CC CC_REGNUM)
4621		   (compare:CC (const_int 0) (match_dup 1)))
4622	      (set (match_dup 0) (minus:SI (const_int 0)
4623					   (match_dup 1)))])
4624   (parallel [(set (reg:CC CC_REGNUM)
4625		   (compare:CC (const_int 0) (match_dup 3)))
4626	     (set (match_dup 2)
4627		  (minus:SI
4628		   (minus:SI (const_int 0) (match_dup 3))
4629		   (ltu:SI (reg:CC_C CC_REGNUM)
4630			   (const_int 0))))])]
4631  {
4632    operands[2] = gen_highpart (SImode, operands[0]);
4633    operands[0] = gen_lowpart (SImode, operands[0]);
4634    operands[3] = gen_highpart (SImode, operands[1]);
4635    operands[1] = gen_lowpart (SImode, operands[1]);
4636  }
4637  [(set_attr "conds" "set")
4638   (set_attr "length" "8")
4639   (set_attr "type" "multiple")]
4640)
4641
4642(define_expand "negdi2"
4643 [(parallel
4644   [(set (match_operand:DI 0 "s_register_operand" "")
4645	 (neg:DI (match_operand:DI 1 "s_register_operand" "")))
4646    (clobber (reg:CC CC_REGNUM))])]
4647  "TARGET_EITHER"
4648  {
4649    if (TARGET_NEON)
4650      {
4651        emit_insn (gen_negdi2_neon (operands[0], operands[1]));
4652	DONE;
4653      }
4654  }
4655)
4656
4657;; The constraints here are to prevent a *partial* overlap (where %Q0 == %R1).
4658;; The first alternative allows the common case of a *full* overlap.
4659(define_insn_and_split "*negdi2_insn"
4660  [(set (match_operand:DI         0 "s_register_operand" "=r,&r")
4661	(neg:DI (match_operand:DI 1 "s_register_operand"  "0,r")))
4662   (clobber (reg:CC CC_REGNUM))]
4663  "TARGET_32BIT"
4664  "#"	; rsbs %Q0, %Q1, #0; rsc %R0, %R1, #0	       (ARM)
4665	; negs %Q0, %Q1    ; sbc %R0, %R1, %R1, lsl #1 (Thumb-2)
4666  "&& reload_completed"
4667  [(parallel [(set (reg:CC CC_REGNUM)
4668		   (compare:CC (const_int 0) (match_dup 1)))
4669	      (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1)))])
4670   (set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3))
4671                                (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
4672  {
4673    operands[2] = gen_highpart (SImode, operands[0]);
4674    operands[0] = gen_lowpart (SImode, operands[0]);
4675    operands[3] = gen_highpart (SImode, operands[1]);
4676    operands[1] = gen_lowpart (SImode, operands[1]);
4677  }
4678  [(set_attr "conds" "clob")
4679   (set_attr "length" "8")
4680   (set_attr "type" "multiple")]
4681)
4682
4683(define_insn "*negsi2_carryin_compare"
4684  [(set (reg:CC CC_REGNUM)
4685	(compare:CC (const_int 0)
4686		    (match_operand:SI 1 "s_register_operand" "r")))
4687   (set (match_operand:SI 0 "s_register_operand" "=r")
4688	(minus:SI (minus:SI (const_int 0)
4689			    (match_dup 1))
4690		  (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
4691  "TARGET_ARM"
4692  "rscs\\t%0, %1, #0"
4693  [(set_attr "conds" "set")
4694   (set_attr "type" "alus_imm")]
4695)
4696
4697(define_expand "negsi2"
4698  [(set (match_operand:SI         0 "s_register_operand" "")
4699	(neg:SI (match_operand:SI 1 "s_register_operand" "")))]
4700  "TARGET_EITHER"
4701  ""
4702)
4703
4704(define_insn "*arm_negsi2"
4705  [(set (match_operand:SI         0 "s_register_operand" "=l,r")
4706	(neg:SI (match_operand:SI 1 "s_register_operand" "l,r")))]
4707  "TARGET_32BIT"
4708  "rsb%?\\t%0, %1, #0"
4709  [(set_attr "predicable" "yes")
4710   (set_attr "predicable_short_it" "yes,no")
4711   (set_attr "arch" "t2,*")
4712   (set_attr "length" "4")
4713   (set_attr "type" "alu_sreg")]
4714)
4715
4716(define_expand "negsf2"
4717  [(set (match_operand:SF         0 "s_register_operand" "")
4718	(neg:SF (match_operand:SF 1 "s_register_operand" "")))]
4719  "TARGET_32BIT && TARGET_HARD_FLOAT"
4720  ""
4721)
4722
4723(define_expand "negdf2"
4724  [(set (match_operand:DF         0 "s_register_operand" "")
4725	(neg:DF (match_operand:DF 1 "s_register_operand" "")))]
4726  "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
4727  "")
4728
4729(define_insn_and_split "*zextendsidi_negsi"
4730  [(set (match_operand:DI 0 "s_register_operand" "=r")
4731        (zero_extend:DI (neg:SI (match_operand:SI 1 "s_register_operand" "r"))))]
4732   "TARGET_32BIT"
4733   "#"
4734   ""
4735   [(set (match_dup 2)
4736         (neg:SI (match_dup 1)))
4737    (set (match_dup 3)
4738         (const_int 0))]
4739   {
4740      operands[2] = gen_lowpart (SImode, operands[0]);
4741      operands[3] = gen_highpart (SImode, operands[0]);
4742   }
4743 [(set_attr "length" "8")
4744  (set_attr "type" "multiple")]
4745)
4746
4747;; Negate an extended 32-bit value.
4748(define_insn_and_split "*negdi_extendsidi"
4749  [(set (match_operand:DI 0 "s_register_operand" "=l,r")
4750	(neg:DI (sign_extend:DI
4751		 (match_operand:SI 1 "s_register_operand" "l,r"))))
4752   (clobber (reg:CC CC_REGNUM))]
4753  "TARGET_32BIT"
4754  "#"
4755  "&& reload_completed"
4756  [(const_int 0)]
4757  {
4758    rtx low = gen_lowpart (SImode, operands[0]);
4759    rtx high = gen_highpart (SImode, operands[0]);
4760
4761    if (reg_overlap_mentioned_p (low, operands[1]))
4762      {
4763	/* Input overlaps the low word of the output.  Use:
4764		asr	Rhi, Rin, #31
4765		rsbs	Rlo, Rin, #0
4766		rsc	Rhi, Rhi, #0 (thumb2: sbc Rhi, Rhi, Rhi, lsl #1).  */
4767	rtx cc_reg = gen_rtx_REG (CC_Cmode, CC_REGNUM);
4768
4769	emit_insn (gen_rtx_SET (high,
4770				gen_rtx_ASHIFTRT (SImode, operands[1],
4771						  GEN_INT (31))));
4772
4773	emit_insn (gen_subsi3_compare (low, const0_rtx, operands[1]));
4774	if (TARGET_ARM)
4775	  emit_insn (gen_rtx_SET (high,
4776				  gen_rtx_MINUS (SImode,
4777						 gen_rtx_MINUS (SImode,
4778								const0_rtx,
4779								high),
4780						 gen_rtx_LTU (SImode,
4781							      cc_reg,
4782							      const0_rtx))));
4783	else
4784	  {
4785	    rtx two_x = gen_rtx_ASHIFT (SImode, high, GEN_INT (1));
4786	    emit_insn (gen_rtx_SET (high,
4787				    gen_rtx_MINUS (SImode,
4788						   gen_rtx_MINUS (SImode,
4789								  high,
4790								  two_x),
4791						   gen_rtx_LTU (SImode,
4792								cc_reg,
4793								const0_rtx))));
4794	  }
4795      }
4796    else
4797      {
4798	/* No overlap, or overlap on high word.  Use:
4799		rsb	Rlo, Rin, #0
4800		bic	Rhi, Rlo, Rin
4801		asr	Rhi, Rhi, #31
4802	   Flags not needed for this sequence.  */
4803	emit_insn (gen_rtx_SET (low, gen_rtx_NEG (SImode, operands[1])));
4804	emit_insn (gen_rtx_SET (high,
4805				gen_rtx_AND (SImode,
4806					     gen_rtx_NOT (SImode, operands[1]),
4807					     low)));
4808	emit_insn (gen_rtx_SET (high,
4809				gen_rtx_ASHIFTRT (SImode, high,
4810						  GEN_INT (31))));
4811      }
4812    DONE;
4813  }
4814  [(set_attr "length" "12")
4815   (set_attr "arch" "t2,*")
4816   (set_attr "type" "multiple")]
4817)
4818
4819(define_insn_and_split "*negdi_zero_extendsidi"
4820  [(set (match_operand:DI 0 "s_register_operand" "=r,&r")
4821	(neg:DI (zero_extend:DI (match_operand:SI 1 "s_register_operand" "0,r"))))
4822   (clobber (reg:CC CC_REGNUM))]
4823  "TARGET_32BIT"
4824  "#" ; "rsbs\\t%Q0, %1, #0\;sbc\\t%R0,%R0,%R0"
4825      ;; Don't care what register is input to sbc,
4826      ;; since we just need to propagate the carry.
4827  "&& reload_completed"
4828  [(parallel [(set (reg:CC CC_REGNUM)
4829                   (compare:CC (const_int 0) (match_dup 1)))
4830              (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1)))])
4831   (set (match_dup 2) (minus:SI (minus:SI (match_dup 2) (match_dup 2))
4832                                (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
4833  {
4834    operands[2] = gen_highpart (SImode, operands[0]);
4835    operands[0] = gen_lowpart (SImode, operands[0]);
4836  }
4837  [(set_attr "conds" "clob")
4838   (set_attr "length" "8")
4839   (set_attr "type" "multiple")]   ;; length in thumb is 4
4840)
4841
4842;; abssi2 doesn't really clobber the condition codes if a different register
4843;; is being set.  To keep things simple, assume during rtl manipulations that
4844;; it does, but tell the final scan operator the truth.  Similarly for
4845;; (neg (abs...))
4846
4847(define_expand "abssi2"
4848  [(parallel
4849    [(set (match_operand:SI         0 "s_register_operand" "")
4850	  (abs:SI (match_operand:SI 1 "s_register_operand" "")))
4851     (clobber (match_dup 2))])]
4852  "TARGET_EITHER"
4853  "
4854  if (TARGET_THUMB1)
4855    operands[2] = gen_rtx_SCRATCH (SImode);
4856  else
4857    operands[2] = gen_rtx_REG (CCmode, CC_REGNUM);
4858")
4859
4860(define_insn_and_split "*arm_abssi2"
4861  [(set (match_operand:SI 0 "s_register_operand" "=r,&r")
4862	(abs:SI (match_operand:SI 1 "s_register_operand" "0,r")))
4863   (clobber (reg:CC CC_REGNUM))]
4864  "TARGET_ARM"
4865  "#"
4866  "&& reload_completed"
4867  [(const_int 0)]
4868  {
4869   /* if (which_alternative == 0) */
4870   if (REGNO(operands[0]) == REGNO(operands[1]))
4871     {
4872      /* Emit the pattern:
4873         cmp\\t%0, #0\;rsblt\\t%0, %0, #0
4874         [(set (reg:CC CC_REGNUM)
4875               (compare:CC (match_dup 0) (const_int 0)))
4876          (cond_exec (lt:CC (reg:CC CC_REGNUM) (const_int 0))
4877                     (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1))))]
4878      */
4879      emit_insn (gen_rtx_SET (gen_rtx_REG (CCmode, CC_REGNUM),
4880                              gen_rtx_COMPARE (CCmode, operands[0], const0_rtx)));
4881      emit_insn (gen_rtx_COND_EXEC (VOIDmode,
4882                                    (gen_rtx_LT (SImode,
4883                                                 gen_rtx_REG (CCmode, CC_REGNUM),
4884                                                 const0_rtx)),
4885                                    (gen_rtx_SET (operands[0],
4886                                                  (gen_rtx_MINUS (SImode,
4887                                                                  const0_rtx,
4888                                                                  operands[1]))))));
4889      DONE;
4890     }
4891   else
4892     {
4893      /* Emit the pattern:
4894         alt1: eor%?\\t%0, %1, %1, asr #31\;sub%?\\t%0, %0, %1, asr #31
4895         [(set (match_dup 0)
4896               (xor:SI (match_dup 1)
4897                       (ashiftrt:SI (match_dup 1) (const_int 31))))
4898          (set (match_dup 0)
4899               (minus:SI (match_dup 0)
4900                      (ashiftrt:SI (match_dup 1) (const_int 31))))]
4901      */
4902      emit_insn (gen_rtx_SET (operands[0],
4903                              gen_rtx_XOR (SImode,
4904                                           gen_rtx_ASHIFTRT (SImode,
4905                                                             operands[1],
4906                                                             GEN_INT (31)),
4907                                           operands[1])));
4908      emit_insn (gen_rtx_SET (operands[0],
4909                              gen_rtx_MINUS (SImode,
4910                                             operands[0],
4911                                             gen_rtx_ASHIFTRT (SImode,
4912                                                               operands[1],
4913                                                               GEN_INT (31)))));
4914      DONE;
4915     }
4916  }
4917  [(set_attr "conds" "clob,*")
4918   (set_attr "shift" "1")
4919   (set_attr "predicable" "no, yes")
4920   (set_attr "length" "8")
4921   (set_attr "type" "multiple")]
4922)
4923
4924(define_insn_and_split "*arm_neg_abssi2"
4925  [(set (match_operand:SI 0 "s_register_operand" "=r,&r")
4926	(neg:SI (abs:SI (match_operand:SI 1 "s_register_operand" "0,r"))))
4927   (clobber (reg:CC CC_REGNUM))]
4928  "TARGET_ARM"
4929  "#"
4930  "&& reload_completed"
4931  [(const_int 0)]
4932  {
4933   /* if (which_alternative == 0) */
4934   if (REGNO (operands[0]) == REGNO (operands[1]))
4935     {
4936      /* Emit the pattern:
4937         cmp\\t%0, #0\;rsbgt\\t%0, %0, #0
4938      */
4939      emit_insn (gen_rtx_SET (gen_rtx_REG (CCmode, CC_REGNUM),
4940                              gen_rtx_COMPARE (CCmode, operands[0], const0_rtx)));
4941      emit_insn (gen_rtx_COND_EXEC (VOIDmode,
4942                                    gen_rtx_GT (SImode,
4943                                                gen_rtx_REG (CCmode, CC_REGNUM),
4944                                                const0_rtx),
4945                                    gen_rtx_SET (operands[0],
4946                                                 (gen_rtx_MINUS (SImode,
4947                                                                 const0_rtx,
4948                                                                 operands[1])))));
4949     }
4950   else
4951     {
4952      /* Emit the pattern:
4953         eor%?\\t%0, %1, %1, asr #31\;rsb%?\\t%0, %0, %1, asr #31
4954      */
4955      emit_insn (gen_rtx_SET (operands[0],
4956                              gen_rtx_XOR (SImode,
4957                                           gen_rtx_ASHIFTRT (SImode,
4958                                                             operands[1],
4959                                                             GEN_INT (31)),
4960                                           operands[1])));
4961      emit_insn (gen_rtx_SET (operands[0],
4962                              gen_rtx_MINUS (SImode,
4963                                             gen_rtx_ASHIFTRT (SImode,
4964                                                               operands[1],
4965                                                               GEN_INT (31)),
4966                                             operands[0])));
4967     }
4968   DONE;
4969  }
4970  [(set_attr "conds" "clob,*")
4971   (set_attr "shift" "1")
4972   (set_attr "predicable" "no, yes")
4973   (set_attr "length" "8")
4974   (set_attr "type" "multiple")]
4975)
4976
4977(define_expand "abssf2"
4978  [(set (match_operand:SF         0 "s_register_operand" "")
4979	(abs:SF (match_operand:SF 1 "s_register_operand" "")))]
4980  "TARGET_32BIT && TARGET_HARD_FLOAT"
4981  "")
4982
4983(define_expand "absdf2"
4984  [(set (match_operand:DF         0 "s_register_operand" "")
4985	(abs:DF (match_operand:DF 1 "s_register_operand" "")))]
4986  "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
4987  "")
4988
4989(define_expand "sqrtsf2"
4990  [(set (match_operand:SF 0 "s_register_operand" "")
4991	(sqrt:SF (match_operand:SF 1 "s_register_operand" "")))]
4992  "TARGET_32BIT && TARGET_HARD_FLOAT"
4993  "")
4994
4995(define_expand "sqrtdf2"
4996  [(set (match_operand:DF 0 "s_register_operand" "")
4997	(sqrt:DF (match_operand:DF 1 "s_register_operand" "")))]
4998  "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
4999  "")
5000
5001(define_expand "one_cmpldi2"
5002  [(set (match_operand:DI 0 "s_register_operand" "")
5003	(not:DI (match_operand:DI 1 "s_register_operand" "")))]
5004  "TARGET_32BIT"
5005  "
5006  if (!TARGET_NEON && !TARGET_IWMMXT)
5007    {
5008      rtx low  = simplify_gen_unary (NOT, SImode,
5009				     gen_lowpart (SImode, operands[1]),
5010				     SImode);
5011      rtx high = simplify_gen_unary (NOT, SImode,
5012				     gen_highpart_mode (SImode, DImode,
5013							operands[1]),
5014				     SImode);
5015
5016      emit_insn (gen_rtx_SET (gen_lowpart (SImode, operands[0]), low));
5017      emit_insn (gen_rtx_SET (gen_highpart (SImode, operands[0]), high));
5018
5019      DONE;
5020    }
5021  /* Otherwise expand pattern as above.  */
5022  "
5023)
5024
5025(define_insn_and_split "*one_cmpldi2_insn"
5026  [(set (match_operand:DI 0 "s_register_operand"	 "=w,&r,&r,?w")
5027	(not:DI (match_operand:DI 1 "s_register_operand" " w, 0, r, w")))]
5028  "TARGET_32BIT"
5029  "@
5030   vmvn\t%P0, %P1
5031   #
5032   #
5033   vmvn\t%P0, %P1"
5034  "TARGET_32BIT && reload_completed
5035   && arm_general_register_operand (operands[0], DImode)"
5036  [(set (match_dup 0) (not:SI (match_dup 1)))
5037   (set (match_dup 2) (not:SI (match_dup 3)))]
5038  "
5039  {
5040    operands[2] = gen_highpart (SImode, operands[0]);
5041    operands[0] = gen_lowpart (SImode, operands[0]);
5042    operands[3] = gen_highpart (SImode, operands[1]);
5043    operands[1] = gen_lowpart (SImode, operands[1]);
5044  }"
5045  [(set_attr "length" "*,8,8,*")
5046   (set_attr "predicable" "no,yes,yes,no")
5047   (set_attr "type" "neon_move,multiple,multiple,neon_move")
5048   (set_attr "arch" "neon_for_64bits,*,*,avoid_neon_for_64bits")]
5049)
5050
5051(define_expand "one_cmplsi2"
5052  [(set (match_operand:SI         0 "s_register_operand" "")
5053	(not:SI (match_operand:SI 1 "s_register_operand" "")))]
5054  "TARGET_EITHER"
5055  ""
5056)
5057
5058(define_insn "*arm_one_cmplsi2"
5059  [(set (match_operand:SI         0 "s_register_operand" "=l,r")
5060	(not:SI (match_operand:SI 1 "s_register_operand"  "l,r")))]
5061  "TARGET_32BIT"
5062  "mvn%?\\t%0, %1"
5063  [(set_attr "predicable" "yes")
5064   (set_attr "predicable_short_it" "yes,no")
5065   (set_attr "arch" "t2,*")
5066   (set_attr "length" "4")
5067   (set_attr "type" "mvn_reg")]
5068)
5069
5070(define_insn "*notsi_compare0"
5071  [(set (reg:CC_NOOV CC_REGNUM)
5072	(compare:CC_NOOV (not:SI (match_operand:SI 1 "s_register_operand" "r"))
5073			 (const_int 0)))
5074   (set (match_operand:SI 0 "s_register_operand" "=r")
5075	(not:SI (match_dup 1)))]
5076  "TARGET_32BIT"
5077  "mvns%?\\t%0, %1"
5078  [(set_attr "conds" "set")
5079   (set_attr "type" "mvn_reg")]
5080)
5081
5082(define_insn "*notsi_compare0_scratch"
5083  [(set (reg:CC_NOOV CC_REGNUM)
5084	(compare:CC_NOOV (not:SI (match_operand:SI 1 "s_register_operand" "r"))
5085			 (const_int 0)))
5086   (clobber (match_scratch:SI 0 "=r"))]
5087  "TARGET_32BIT"
5088  "mvns%?\\t%0, %1"
5089  [(set_attr "conds" "set")
5090   (set_attr "type" "mvn_reg")]
5091)
5092
5093;; Fixed <--> Floating conversion insns
5094
5095(define_expand "floatsihf2"
5096  [(set (match_operand:HF           0 "general_operand" "")
5097	(float:HF (match_operand:SI 1 "general_operand" "")))]
5098  "TARGET_EITHER"
5099  "
5100  {
5101    rtx op1 = gen_reg_rtx (SFmode);
5102    expand_float (op1, operands[1], 0);
5103    op1 = convert_to_mode (HFmode, op1, 0);
5104    emit_move_insn (operands[0], op1);
5105    DONE;
5106  }"
5107)
5108
5109(define_expand "floatdihf2"
5110  [(set (match_operand:HF           0 "general_operand" "")
5111	(float:HF (match_operand:DI 1 "general_operand" "")))]
5112  "TARGET_EITHER"
5113  "
5114  {
5115    rtx op1 = gen_reg_rtx (SFmode);
5116    expand_float (op1, operands[1], 0);
5117    op1 = convert_to_mode (HFmode, op1, 0);
5118    emit_move_insn (operands[0], op1);
5119    DONE;
5120  }"
5121)
5122
5123(define_expand "floatsisf2"
5124  [(set (match_operand:SF           0 "s_register_operand" "")
5125	(float:SF (match_operand:SI 1 "s_register_operand" "")))]
5126  "TARGET_32BIT && TARGET_HARD_FLOAT"
5127  "
5128")
5129
5130(define_expand "floatsidf2"
5131  [(set (match_operand:DF           0 "s_register_operand" "")
5132	(float:DF (match_operand:SI 1 "s_register_operand" "")))]
5133  "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
5134  "
5135")
5136
5137(define_expand "fix_trunchfsi2"
5138  [(set (match_operand:SI         0 "general_operand" "")
5139	(fix:SI (fix:HF (match_operand:HF 1 "general_operand"  ""))))]
5140  "TARGET_EITHER"
5141  "
5142  {
5143    rtx op1 = convert_to_mode (SFmode, operands[1], 0);
5144    expand_fix (operands[0], op1, 0);
5145    DONE;
5146  }"
5147)
5148
5149(define_expand "fix_trunchfdi2"
5150  [(set (match_operand:DI         0 "general_operand" "")
5151	(fix:DI (fix:HF (match_operand:HF 1 "general_operand"  ""))))]
5152  "TARGET_EITHER"
5153  "
5154  {
5155    rtx op1 = convert_to_mode (SFmode, operands[1], 0);
5156    expand_fix (operands[0], op1, 0);
5157    DONE;
5158  }"
5159)
5160
5161(define_expand "fix_truncsfsi2"
5162  [(set (match_operand:SI         0 "s_register_operand" "")
5163	(fix:SI (fix:SF (match_operand:SF 1 "s_register_operand"  ""))))]
5164  "TARGET_32BIT && TARGET_HARD_FLOAT"
5165  "
5166")
5167
5168(define_expand "fix_truncdfsi2"
5169  [(set (match_operand:SI         0 "s_register_operand" "")
5170	(fix:SI (fix:DF (match_operand:DF 1 "s_register_operand"  ""))))]
5171  "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
5172  "
5173")
5174
5175;; Truncation insns
5176
5177(define_expand "truncdfsf2"
5178  [(set (match_operand:SF  0 "s_register_operand" "")
5179	(float_truncate:SF
5180 	 (match_operand:DF 1 "s_register_operand" "")))]
5181  "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
5182  ""
5183)
5184
5185;; DFmode to HFmode conversions on targets without a single-step hardware
5186;; instruction for it would have to go through SFmode.  This is dangerous
5187;; as it introduces double rounding.
5188;;
5189;; Disable this pattern unless we are in an unsafe math mode, or we have
5190;; a single-step instruction.
5191
5192(define_expand "truncdfhf2"
5193  [(set (match_operand:HF  0 "s_register_operand" "")
5194	(float_truncate:HF
5195	 (match_operand:DF 1 "s_register_operand" "")))]
5196  "(TARGET_EITHER && flag_unsafe_math_optimizations)
5197   || (TARGET_32BIT && TARGET_FP16_TO_DOUBLE)"
5198{
5199  /* We don't have a direct instruction for this, so we must be in
5200     an unsafe math mode, and going via SFmode.  */
5201
5202  if (!(TARGET_32BIT && TARGET_FP16_TO_DOUBLE))
5203    {
5204      rtx op1;
5205      op1 = convert_to_mode (SFmode, operands[1], 0);
5206      op1 = convert_to_mode (HFmode, op1, 0);
5207      emit_move_insn (operands[0], op1);
5208      DONE;
5209    }
5210  /* Otherwise, we will pick this up as a single instruction with
5211     no intermediary rounding.  */
5212}
5213)
5214
5215;; Zero and sign extension instructions.
5216
5217(define_insn "zero_extend<mode>di2"
5218  [(set (match_operand:DI 0 "s_register_operand" "=w,r,?r,w")
5219        (zero_extend:DI (match_operand:QHSI 1 "<qhs_zextenddi_op>"
5220					    "<qhs_zextenddi_cstr>")))]
5221  "TARGET_32BIT <qhs_zextenddi_cond>"
5222  "#"
5223  [(set_attr "length" "8,4,8,8")
5224   (set_attr "arch" "neon_for_64bits,*,*,avoid_neon_for_64bits")
5225   (set_attr "ce_count" "2")
5226   (set_attr "predicable" "yes")
5227   (set_attr "type" "multiple,mov_reg,multiple,multiple")]
5228)
5229
5230(define_insn "extend<mode>di2"
5231  [(set (match_operand:DI 0 "s_register_operand" "=w,r,?r,?r,w")
5232        (sign_extend:DI (match_operand:QHSI 1 "<qhs_extenddi_op>"
5233					    "<qhs_extenddi_cstr>")))]
5234  "TARGET_32BIT <qhs_sextenddi_cond>"
5235  "#"
5236  [(set_attr "length" "8,4,8,8,8")
5237   (set_attr "ce_count" "2")
5238   (set_attr "shift" "1")
5239   (set_attr "predicable" "yes")
5240   (set_attr "arch" "neon_for_64bits,*,a,t,avoid_neon_for_64bits")
5241   (set_attr "type" "multiple,mov_reg,multiple,multiple,multiple")]
5242)
5243
5244;; Splits for all extensions to DImode
5245(define_split
5246  [(set (match_operand:DI 0 "s_register_operand" "")
5247        (zero_extend:DI (match_operand 1 "nonimmediate_operand" "")))]
5248  "TARGET_32BIT && reload_completed && !IS_VFP_REGNUM (REGNO (operands[0]))"
5249  [(set (match_dup 0) (match_dup 1))]
5250{
5251  rtx lo_part = gen_lowpart (SImode, operands[0]);
5252  machine_mode src_mode = GET_MODE (operands[1]);
5253
5254  if (REG_P (operands[0])
5255      && !reg_overlap_mentioned_p (operands[0], operands[1]))
5256    emit_clobber (operands[0]);
5257  if (!REG_P (lo_part) || src_mode != SImode
5258      || !rtx_equal_p (lo_part, operands[1]))
5259    {
5260      if (src_mode == SImode)
5261        emit_move_insn (lo_part, operands[1]);
5262      else
5263        emit_insn (gen_rtx_SET (lo_part,
5264				gen_rtx_ZERO_EXTEND (SImode, operands[1])));
5265      operands[1] = lo_part;
5266    }
5267  operands[0] = gen_highpart (SImode, operands[0]);
5268  operands[1] = const0_rtx;
5269})
5270
5271(define_split
5272  [(set (match_operand:DI 0 "s_register_operand" "")
5273        (sign_extend:DI (match_operand 1 "nonimmediate_operand" "")))]
5274  "TARGET_32BIT && reload_completed && !IS_VFP_REGNUM (REGNO (operands[0]))"
5275  [(set (match_dup 0) (ashiftrt:SI (match_dup 1) (const_int 31)))]
5276{
5277  rtx lo_part = gen_lowpart (SImode, operands[0]);
5278  machine_mode src_mode = GET_MODE (operands[1]);
5279
5280  if (REG_P (operands[0])
5281      && !reg_overlap_mentioned_p (operands[0], operands[1]))
5282    emit_clobber (operands[0]);
5283
5284  if (!REG_P (lo_part) || src_mode != SImode
5285      || !rtx_equal_p (lo_part, operands[1]))
5286    {
5287      if (src_mode == SImode)
5288        emit_move_insn (lo_part, operands[1]);
5289      else
5290        emit_insn (gen_rtx_SET (lo_part,
5291				gen_rtx_SIGN_EXTEND (SImode, operands[1])));
5292      operands[1] = lo_part;
5293    }
5294  operands[0] = gen_highpart (SImode, operands[0]);
5295})
5296
5297(define_expand "zero_extendhisi2"
5298  [(set (match_operand:SI 0 "s_register_operand" "")
5299	(zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
5300  "TARGET_EITHER"
5301{
5302  if (TARGET_ARM && !arm_arch4 && MEM_P (operands[1]))
5303    {
5304      emit_insn (gen_movhi_bytes (operands[0], operands[1]));
5305      DONE;
5306    }
5307  if (!arm_arch6 && !MEM_P (operands[1]))
5308    {
5309      rtx t = gen_lowpart (SImode, operands[1]);
5310      rtx tmp = gen_reg_rtx (SImode);
5311      emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (16)));
5312      emit_insn (gen_lshrsi3 (operands[0], tmp, GEN_INT (16)));
5313      DONE;
5314    }
5315})
5316
5317(define_split
5318  [(set (match_operand:SI 0 "s_register_operand" "")
5319	(zero_extend:SI (match_operand:HI 1 "s_register_operand" "")))]
5320  "!TARGET_THUMB2 && !arm_arch6"
5321  [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
5322   (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 16)))]
5323{
5324  operands[2] = gen_lowpart (SImode, operands[1]);
5325})
5326
5327(define_insn "*arm_zero_extendhisi2"
5328  [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5329	(zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
5330  "TARGET_ARM && arm_arch4 && !arm_arch6"
5331  "@
5332   #
5333   ldrh%?\\t%0, %1"
5334  [(set_attr "type" "alu_shift_reg,load_byte")
5335   (set_attr "predicable" "yes")]
5336)
5337
5338(define_insn "*arm_zero_extendhisi2_v6"
5339  [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5340	(zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,Uh")))]
5341  "TARGET_ARM && arm_arch6"
5342  "@
5343   uxth%?\\t%0, %1
5344   ldrh%?\\t%0, %1"
5345  [(set_attr "predicable" "yes")
5346   (set_attr "type" "extend,load_byte")]
5347)
5348
5349(define_insn "*arm_zero_extendhisi2addsi"
5350  [(set (match_operand:SI 0 "s_register_operand" "=r")
5351	(plus:SI (zero_extend:SI (match_operand:HI 1 "s_register_operand" "r"))
5352		 (match_operand:SI 2 "s_register_operand" "r")))]
5353  "TARGET_INT_SIMD"
5354  "uxtah%?\\t%0, %2, %1"
5355  [(set_attr "type" "alu_shift_reg")
5356   (set_attr "predicable" "yes")]
5357)
5358
5359(define_expand "zero_extendqisi2"
5360  [(set (match_operand:SI 0 "s_register_operand" "")
5361	(zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))]
5362  "TARGET_EITHER"
5363{
5364  if (TARGET_ARM && !arm_arch6 && !MEM_P (operands[1]))
5365    {
5366      emit_insn (gen_andsi3 (operands[0],
5367			     gen_lowpart (SImode, operands[1]),
5368					  GEN_INT (255)));
5369      DONE;
5370    }
5371  if (!arm_arch6 && !MEM_P (operands[1]))
5372    {
5373      rtx t = gen_lowpart (SImode, operands[1]);
5374      rtx tmp = gen_reg_rtx (SImode);
5375      emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (24)));
5376      emit_insn (gen_lshrsi3 (operands[0], tmp, GEN_INT (24)));
5377      DONE;
5378    }
5379})
5380
5381(define_split
5382  [(set (match_operand:SI 0 "s_register_operand" "")
5383	(zero_extend:SI (match_operand:QI 1 "s_register_operand" "")))]
5384  "!arm_arch6"
5385  [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 24)))
5386   (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 24)))]
5387{
5388  operands[2] = simplify_gen_subreg (SImode, operands[1], QImode, 0);
5389  if (TARGET_ARM)
5390    {
5391      emit_insn (gen_andsi3 (operands[0], operands[2], GEN_INT (255)));
5392      DONE;
5393    }
5394})
5395
5396(define_insn "*arm_zero_extendqisi2"
5397  [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5398	(zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
5399  "TARGET_ARM && !arm_arch6"
5400  "@
5401   #
5402   ldrb%?\\t%0, %1\\t%@ zero_extendqisi2"
5403  [(set_attr "length" "8,4")
5404   (set_attr "type" "alu_shift_reg,load_byte")
5405   (set_attr "predicable" "yes")]
5406)
5407
5408(define_insn "*arm_zero_extendqisi2_v6"
5409  [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5410	(zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,Uh")))]
5411  "TARGET_ARM && arm_arch6"
5412  "@
5413   uxtb%?\\t%0, %1
5414   ldrb%?\\t%0, %1\\t%@ zero_extendqisi2"
5415  [(set_attr "type" "extend,load_byte")
5416   (set_attr "predicable" "yes")]
5417)
5418
5419(define_insn "*arm_zero_extendqisi2addsi"
5420  [(set (match_operand:SI 0 "s_register_operand" "=r")
5421	(plus:SI (zero_extend:SI (match_operand:QI 1 "s_register_operand" "r"))
5422		 (match_operand:SI 2 "s_register_operand" "r")))]
5423  "TARGET_INT_SIMD"
5424  "uxtab%?\\t%0, %2, %1"
5425  [(set_attr "predicable" "yes")
5426   (set_attr "type" "alu_shift_reg")]
5427)
5428
5429(define_split
5430  [(set (match_operand:SI 0 "s_register_operand" "")
5431	(zero_extend:SI (subreg:QI (match_operand:SI 1 "" "") 0)))
5432   (clobber (match_operand:SI 2 "s_register_operand" ""))]
5433  "TARGET_32BIT && (!MEM_P (operands[1])) && ! BYTES_BIG_ENDIAN"
5434  [(set (match_dup 2) (match_dup 1))
5435   (set (match_dup 0) (and:SI (match_dup 2) (const_int 255)))]
5436  ""
5437)
5438
5439(define_split
5440  [(set (match_operand:SI 0 "s_register_operand" "")
5441	(zero_extend:SI (subreg:QI (match_operand:SI 1 "" "") 3)))
5442   (clobber (match_operand:SI 2 "s_register_operand" ""))]
5443  "TARGET_32BIT && (!MEM_P (operands[1])) && BYTES_BIG_ENDIAN"
5444  [(set (match_dup 2) (match_dup 1))
5445   (set (match_dup 0) (and:SI (match_dup 2) (const_int 255)))]
5446  ""
5447)
5448
5449
5450(define_split
5451  [(set (match_operand:SI 0 "s_register_operand" "")
5452	(IOR_XOR:SI (and:SI (ashift:SI
5453			     (match_operand:SI 1 "s_register_operand" "")
5454			     (match_operand:SI 2 "const_int_operand" ""))
5455			    (match_operand:SI 3 "const_int_operand" ""))
5456		    (zero_extend:SI
5457		     (match_operator 5 "subreg_lowpart_operator"
5458		      [(match_operand:SI 4 "s_register_operand" "")]))))]
5459  "TARGET_32BIT
5460   && (UINTVAL (operands[3])
5461       == (GET_MODE_MASK (GET_MODE (operands[5]))
5462           & (GET_MODE_MASK (GET_MODE (operands[5]))
5463	      << (INTVAL (operands[2])))))"
5464  [(set (match_dup 0) (IOR_XOR:SI (ashift:SI (match_dup 1) (match_dup 2))
5465				  (match_dup 4)))
5466   (set (match_dup 0) (zero_extend:SI (match_dup 5)))]
5467  "operands[5] = gen_lowpart (GET_MODE (operands[5]), operands[0]);"
5468)
5469
5470(define_insn "*compareqi_eq0"
5471  [(set (reg:CC_Z CC_REGNUM)
5472	(compare:CC_Z (match_operand:QI 0 "s_register_operand" "r")
5473			 (const_int 0)))]
5474  "TARGET_32BIT"
5475  "tst%?\\t%0, #255"
5476  [(set_attr "conds" "set")
5477   (set_attr "predicable" "yes")
5478   (set_attr "type" "logic_imm")]
5479)
5480
5481(define_expand "extendhisi2"
5482  [(set (match_operand:SI 0 "s_register_operand" "")
5483	(sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
5484  "TARGET_EITHER"
5485{
5486  if (TARGET_THUMB1)
5487    {
5488      emit_insn (gen_thumb1_extendhisi2 (operands[0], operands[1]));
5489      DONE;
5490    }
5491  if (MEM_P (operands[1]) && TARGET_ARM && !arm_arch4)
5492    {
5493      emit_insn (gen_extendhisi2_mem (operands[0], operands[1]));
5494      DONE;
5495    }
5496
5497  if (!arm_arch6 && !MEM_P (operands[1]))
5498    {
5499      rtx t = gen_lowpart (SImode, operands[1]);
5500      rtx tmp = gen_reg_rtx (SImode);
5501      emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (16)));
5502      emit_insn (gen_ashrsi3 (operands[0], tmp, GEN_INT (16)));
5503      DONE;
5504    }
5505})
5506
5507(define_split
5508  [(parallel
5509    [(set (match_operand:SI 0 "register_operand" "")
5510	  (sign_extend:SI (match_operand:HI 1 "register_operand" "")))
5511     (clobber (match_scratch:SI 2 ""))])]
5512  "!arm_arch6"
5513  [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
5514   (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
5515{
5516  operands[2] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
5517})
5518
5519;; This pattern will only be used when ldsh is not available
5520(define_expand "extendhisi2_mem"
5521  [(set (match_dup 2) (zero_extend:SI (match_operand:HI 1 "" "")))
5522   (set (match_dup 3)
5523	(zero_extend:SI (match_dup 7)))
5524   (set (match_dup 6) (ashift:SI (match_dup 4) (const_int 24)))
5525   (set (match_operand:SI 0 "" "")
5526	(ior:SI (ashiftrt:SI (match_dup 6) (const_int 16)) (match_dup 5)))]
5527  "TARGET_ARM"
5528  "
5529  {
5530    rtx mem1, mem2;
5531    rtx addr = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
5532
5533    mem1 = change_address (operands[1], QImode, addr);
5534    mem2 = change_address (operands[1], QImode,
5535			   plus_constant (Pmode, addr, 1));
5536    operands[0] = gen_lowpart (SImode, operands[0]);
5537    operands[1] = mem1;
5538    operands[2] = gen_reg_rtx (SImode);
5539    operands[3] = gen_reg_rtx (SImode);
5540    operands[6] = gen_reg_rtx (SImode);
5541    operands[7] = mem2;
5542
5543    if (BYTES_BIG_ENDIAN)
5544      {
5545	operands[4] = operands[2];
5546	operands[5] = operands[3];
5547      }
5548    else
5549      {
5550	operands[4] = operands[3];
5551	operands[5] = operands[2];
5552      }
5553  }"
5554)
5555
5556(define_split
5557  [(set (match_operand:SI 0 "register_operand" "")
5558	(sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
5559  "!arm_arch6"
5560  [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
5561   (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
5562{
5563  operands[2] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
5564})
5565
5566(define_insn "*arm_extendhisi2"
5567  [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5568	(sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,Uh")))]
5569  "TARGET_ARM && arm_arch4 && !arm_arch6"
5570  "@
5571   #
5572   ldrsh%?\\t%0, %1"
5573  [(set_attr "length" "8,4")
5574   (set_attr "type" "alu_shift_reg,load_byte")
5575   (set_attr "predicable" "yes")]
5576)
5577
5578;; ??? Check Thumb-2 pool range
5579(define_insn "*arm_extendhisi2_v6"
5580  [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5581	(sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,Uh")))]
5582  "TARGET_32BIT && arm_arch6"
5583  "@
5584   sxth%?\\t%0, %1
5585   ldrsh%?\\t%0, %1"
5586  [(set_attr "type" "extend,load_byte")
5587   (set_attr "predicable" "yes")]
5588)
5589
5590(define_insn "*arm_extendhisi2addsi"
5591  [(set (match_operand:SI 0 "s_register_operand" "=r")
5592	(plus:SI (sign_extend:SI (match_operand:HI 1 "s_register_operand" "r"))
5593		 (match_operand:SI 2 "s_register_operand" "r")))]
5594  "TARGET_INT_SIMD"
5595  "sxtah%?\\t%0, %2, %1"
5596  [(set_attr "type" "alu_shift_reg")]
5597)
5598
5599(define_expand "extendqihi2"
5600  [(set (match_dup 2)
5601	(ashift:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "")
5602		   (const_int 24)))
5603   (set (match_operand:HI 0 "s_register_operand" "")
5604	(ashiftrt:SI (match_dup 2)
5605		     (const_int 24)))]
5606  "TARGET_ARM"
5607  "
5608  {
5609    if (arm_arch4 && MEM_P (operands[1]))
5610      {
5611	emit_insn (gen_rtx_SET (operands[0],
5612				gen_rtx_SIGN_EXTEND (HImode, operands[1])));
5613	DONE;
5614      }
5615    if (!s_register_operand (operands[1], QImode))
5616      operands[1] = copy_to_mode_reg (QImode, operands[1]);
5617    operands[0] = gen_lowpart (SImode, operands[0]);
5618    operands[1] = gen_lowpart (SImode, operands[1]);
5619    operands[2] = gen_reg_rtx (SImode);
5620  }"
5621)
5622
5623(define_insn "*arm_extendqihi_insn"
5624  [(set (match_operand:HI 0 "s_register_operand" "=r")
5625	(sign_extend:HI (match_operand:QI 1 "arm_extendqisi_mem_op" "Uq")))]
5626  "TARGET_ARM && arm_arch4"
5627  "ldrsb%?\\t%0, %1"
5628  [(set_attr "type" "load_byte")
5629   (set_attr "predicable" "yes")]
5630)
5631
5632(define_expand "extendqisi2"
5633  [(set (match_operand:SI 0 "s_register_operand" "")
5634	(sign_extend:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "")))]
5635  "TARGET_EITHER"
5636{
5637  if (!arm_arch4 && MEM_P (operands[1]))
5638    operands[1] = copy_to_mode_reg (QImode, operands[1]);
5639
5640  if (!arm_arch6 && !MEM_P (operands[1]))
5641    {
5642      rtx t = gen_lowpart (SImode, operands[1]);
5643      rtx tmp = gen_reg_rtx (SImode);
5644      emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (24)));
5645      emit_insn (gen_ashrsi3 (operands[0], tmp, GEN_INT (24)));
5646      DONE;
5647    }
5648})
5649
5650(define_split
5651  [(set (match_operand:SI 0 "register_operand" "")
5652	(sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
5653  "!arm_arch6"
5654  [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 24)))
5655   (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 24)))]
5656{
5657  operands[2] = simplify_gen_subreg (SImode, operands[1], QImode, 0);
5658})
5659
5660(define_insn "*arm_extendqisi"
5661  [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5662	(sign_extend:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "r,Uq")))]
5663  "TARGET_ARM && arm_arch4 && !arm_arch6"
5664  "@
5665   #
5666   ldrsb%?\\t%0, %1"
5667  [(set_attr "length" "8,4")
5668   (set_attr "type" "alu_shift_reg,load_byte")
5669   (set_attr "predicable" "yes")]
5670)
5671
5672(define_insn "*arm_extendqisi_v6"
5673  [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5674	(sign_extend:SI
5675	 (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "r,Uq")))]
5676  "TARGET_ARM && arm_arch6"
5677  "@
5678   sxtb%?\\t%0, %1
5679   ldrsb%?\\t%0, %1"
5680  [(set_attr "type" "extend,load_byte")
5681   (set_attr "predicable" "yes")]
5682)
5683
5684(define_insn "*arm_extendqisi2addsi"
5685  [(set (match_operand:SI 0 "s_register_operand" "=r")
5686	(plus:SI (sign_extend:SI (match_operand:QI 1 "s_register_operand" "r"))
5687		 (match_operand:SI 2 "s_register_operand" "r")))]
5688  "TARGET_INT_SIMD"
5689  "sxtab%?\\t%0, %2, %1"
5690  [(set_attr "type" "alu_shift_reg")
5691   (set_attr "predicable" "yes")]
5692)
5693
5694(define_expand "extendsfdf2"
5695  [(set (match_operand:DF                  0 "s_register_operand" "")
5696	(float_extend:DF (match_operand:SF 1 "s_register_operand"  "")))]
5697  "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
5698  ""
5699)
5700
5701;; HFmode -> DFmode conversions where we don't have an instruction for it
5702;; must go through SFmode.
5703;;
5704;; This is always safe for an extend.
5705
5706(define_expand "extendhfdf2"
5707  [(set (match_operand:DF		   0 "s_register_operand" "")
5708	(float_extend:DF (match_operand:HF 1 "s_register_operand" "")))]
5709  "TARGET_EITHER"
5710{
5711  /* We don't have a direct instruction for this, so go via SFmode.  */
5712  if (!(TARGET_32BIT && TARGET_FP16_TO_DOUBLE))
5713    {
5714      rtx op1;
5715      op1 = convert_to_mode (SFmode, operands[1], 0);
5716      op1 = convert_to_mode (DFmode, op1, 0);
5717      emit_insn (gen_movdf (operands[0], op1));
5718      DONE;
5719    }
5720  /* Otherwise, we're done producing RTL and will pick up the correct
5721     pattern to do this with one rounding-step in a single instruction.  */
5722}
5723)
5724
5725;; Move insns (including loads and stores)
5726
5727;; XXX Just some ideas about movti.
5728;; I don't think these are a good idea on the arm, there just aren't enough
5729;; registers
5730;;(define_expand "loadti"
5731;;  [(set (match_operand:TI 0 "s_register_operand" "")
5732;;	(mem:TI (match_operand:SI 1 "address_operand" "")))]
5733;;  "" "")
5734
5735;;(define_expand "storeti"
5736;;  [(set (mem:TI (match_operand:TI 0 "address_operand" ""))
5737;;	(match_operand:TI 1 "s_register_operand" ""))]
5738;;  "" "")
5739
5740;;(define_expand "movti"
5741;;  [(set (match_operand:TI 0 "general_operand" "")
5742;;	(match_operand:TI 1 "general_operand" ""))]
5743;;  ""
5744;;  "
5745;;{
5746;;  rtx insn;
5747;;
5748;;  if (MEM_P (operands[0]) && MEM_P (operands[1]))
5749;;    operands[1] = copy_to_reg (operands[1]);
5750;;  if (MEM_P (operands[0]))
5751;;    insn = gen_storeti (XEXP (operands[0], 0), operands[1]);
5752;;  else if (MEM_P (operands[1]))
5753;;    insn = gen_loadti (operands[0], XEXP (operands[1], 0));
5754;;  else
5755;;    FAIL;
5756;;
5757;;  emit_insn (insn);
5758;;  DONE;
5759;;}")
5760
5761;; Recognize garbage generated above.
5762
5763;;(define_insn ""
5764;;  [(set (match_operand:TI 0 "general_operand" "=r,r,r,<,>,m")
5765;;	(match_operand:TI 1 "general_operand" "<,>,m,r,r,r"))]
5766;;  ""
5767;;  "*
5768;;  {
5769;;    register mem = (which_alternative < 3);
5770;;    register const char *template;
5771;;
5772;;    operands[mem] = XEXP (operands[mem], 0);
5773;;    switch (which_alternative)
5774;;      {
5775;;      case 0: template = \"ldmdb\\t%1!, %M0\"; break;
5776;;      case 1: template = \"ldmia\\t%1!, %M0\"; break;
5777;;      case 2: template = \"ldmia\\t%1, %M0\"; break;
5778;;      case 3: template = \"stmdb\\t%0!, %M1\"; break;
5779;;      case 4: template = \"stmia\\t%0!, %M1\"; break;
5780;;      case 5: template = \"stmia\\t%0, %M1\"; break;
5781;;      }
5782;;    output_asm_insn (template, operands);
5783;;    return \"\";
5784;;  }")
5785
5786(define_expand "movdi"
5787  [(set (match_operand:DI 0 "general_operand" "")
5788	(match_operand:DI 1 "general_operand" ""))]
5789  "TARGET_EITHER"
5790  "
5791  if (can_create_pseudo_p ())
5792    {
5793      if (!REG_P (operands[0]))
5794	operands[1] = force_reg (DImode, operands[1]);
5795    }
5796  if (REG_P (operands[0]) && REGNO (operands[0]) <= LAST_ARM_REGNUM
5797      && !targetm.hard_regno_mode_ok (REGNO (operands[0]), DImode))
5798    {
5799      /* Avoid LDRD's into an odd-numbered register pair in ARM state
5800	 when expanding function calls.  */
5801      gcc_assert (can_create_pseudo_p ());
5802      if (MEM_P (operands[1]) && MEM_VOLATILE_P (operands[1]))
5803	{
5804	  /* Perform load into legal reg pair first, then move.  */
5805	  rtx reg = gen_reg_rtx (DImode);
5806	  emit_insn (gen_movdi (reg, operands[1]));
5807	  operands[1] = reg;
5808	}
5809      emit_move_insn (gen_lowpart (SImode, operands[0]),
5810		      gen_lowpart (SImode, operands[1]));
5811      emit_move_insn (gen_highpart (SImode, operands[0]),
5812		      gen_highpart (SImode, operands[1]));
5813      DONE;
5814    }
5815  else if (REG_P (operands[1]) && REGNO (operands[1]) <= LAST_ARM_REGNUM
5816	   && !targetm.hard_regno_mode_ok (REGNO (operands[1]), DImode))
5817    {
5818      /* Avoid STRD's from an odd-numbered register pair in ARM state
5819	 when expanding function prologue.  */
5820      gcc_assert (can_create_pseudo_p ());
5821      rtx split_dest = (MEM_P (operands[0]) && MEM_VOLATILE_P (operands[0]))
5822		       ? gen_reg_rtx (DImode)
5823		       : operands[0];
5824      emit_move_insn (gen_lowpart (SImode, split_dest),
5825		      gen_lowpart (SImode, operands[1]));
5826      emit_move_insn (gen_highpart (SImode, split_dest),
5827		      gen_highpart (SImode, operands[1]));
5828      if (split_dest != operands[0])
5829	emit_insn (gen_movdi (operands[0], split_dest));
5830      DONE;
5831    }
5832  "
5833)
5834
5835(define_insn "*arm_movdi"
5836  [(set (match_operand:DI 0 "nonimmediate_di_operand" "=r, r, r, q, m")
5837	(match_operand:DI 1 "di_operand"              "rDa,Db,Dc,mi,q"))]
5838  "TARGET_32BIT
5839   && !(TARGET_HARD_FLOAT)
5840   && !TARGET_IWMMXT
5841   && (   register_operand (operands[0], DImode)
5842       || register_operand (operands[1], DImode))"
5843  "*
5844  switch (which_alternative)
5845    {
5846    case 0:
5847    case 1:
5848    case 2:
5849      return \"#\";
5850    default:
5851      return output_move_double (operands, true, NULL);
5852    }
5853  "
5854  [(set_attr "length" "8,12,16,8,8")
5855   (set_attr "type" "multiple,multiple,multiple,load_8,store_8")
5856   (set_attr "arm_pool_range" "*,*,*,1020,*")
5857   (set_attr "arm_neg_pool_range" "*,*,*,1004,*")
5858   (set_attr "thumb2_pool_range" "*,*,*,4094,*")
5859   (set_attr "thumb2_neg_pool_range" "*,*,*,0,*")]
5860)
5861
5862(define_split
5863  [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
5864	(match_operand:ANY64 1 "immediate_operand" ""))]
5865  "TARGET_32BIT
5866   && reload_completed
5867   && (arm_disable_literal_pool
5868       || (arm_const_double_inline_cost (operands[1])
5869	   <= arm_max_const_double_inline_cost ()))"
5870  [(const_int 0)]
5871  "
5872  arm_split_constant (SET, SImode, curr_insn,
5873		      INTVAL (gen_lowpart (SImode, operands[1])),
5874		      gen_lowpart (SImode, operands[0]), NULL_RTX, 0);
5875  arm_split_constant (SET, SImode, curr_insn,
5876		      INTVAL (gen_highpart_mode (SImode,
5877						 GET_MODE (operands[0]),
5878						 operands[1])),
5879		      gen_highpart (SImode, operands[0]), NULL_RTX, 0);
5880  DONE;
5881  "
5882)
5883
5884; If optimizing for size, or if we have load delay slots, then
5885; we want to split the constant into two separate operations.
5886; In both cases this may split a trivial part into a single data op
5887; leaving a single complex constant to load.  We can also get longer
5888; offsets in a LDR which means we get better chances of sharing the pool
5889; entries.  Finally, we can normally do a better job of scheduling
5890; LDR instructions than we can with LDM.
5891; This pattern will only match if the one above did not.
5892(define_split
5893  [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
5894	(match_operand:ANY64 1 "const_double_operand" ""))]
5895  "TARGET_ARM && reload_completed
5896   && arm_const_double_by_parts (operands[1])"
5897  [(set (match_dup 0) (match_dup 1))
5898   (set (match_dup 2) (match_dup 3))]
5899  "
5900  operands[2] = gen_highpart (SImode, operands[0]);
5901  operands[3] = gen_highpart_mode (SImode, GET_MODE (operands[0]),
5902				   operands[1]);
5903  operands[0] = gen_lowpart (SImode, operands[0]);
5904  operands[1] = gen_lowpart (SImode, operands[1]);
5905  "
5906)
5907
5908(define_split
5909  [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
5910	(match_operand:ANY64 1 "arm_general_register_operand" ""))]
5911  "TARGET_EITHER && reload_completed"
5912  [(set (match_dup 0) (match_dup 1))
5913   (set (match_dup 2) (match_dup 3))]
5914  "
5915  operands[2] = gen_highpart (SImode, operands[0]);
5916  operands[3] = gen_highpart (SImode, operands[1]);
5917  operands[0] = gen_lowpart (SImode, operands[0]);
5918  operands[1] = gen_lowpart (SImode, operands[1]);
5919
5920  /* Handle a partial overlap.  */
5921  if (rtx_equal_p (operands[0], operands[3]))
5922    {
5923      rtx tmp0 = operands[0];
5924      rtx tmp1 = operands[1];
5925
5926      operands[0] = operands[2];
5927      operands[1] = operands[3];
5928      operands[2] = tmp0;
5929      operands[3] = tmp1;
5930    }
5931  "
5932)
5933
5934;; We can't actually do base+index doubleword loads if the index and
5935;; destination overlap.  Split here so that we at least have chance to
5936;; schedule.
5937(define_split
5938  [(set (match_operand:DI 0 "s_register_operand" "")
5939	(mem:DI (plus:SI (match_operand:SI 1 "s_register_operand" "")
5940			 (match_operand:SI 2 "s_register_operand" ""))))]
5941  "TARGET_LDRD
5942  && reg_overlap_mentioned_p (operands[0], operands[1])
5943  && reg_overlap_mentioned_p (operands[0], operands[2])"
5944  [(set (match_dup 4)
5945	(plus:SI (match_dup 1)
5946		 (match_dup 2)))
5947   (set (match_dup 0)
5948	(mem:DI (match_dup 4)))]
5949  "
5950  operands[4] = gen_rtx_REG (SImode, REGNO(operands[0]));
5951  "
5952)
5953
5954(define_expand "movsi"
5955  [(set (match_operand:SI 0 "general_operand" "")
5956        (match_operand:SI 1 "general_operand" ""))]
5957  "TARGET_EITHER"
5958  "
5959  {
5960  rtx base, offset, tmp;
5961
5962  if (TARGET_32BIT || TARGET_HAVE_MOVT)
5963    {
5964      /* Everything except mem = const or mem = mem can be done easily.  */
5965      if (MEM_P (operands[0]))
5966        operands[1] = force_reg (SImode, operands[1]);
5967      if (arm_general_register_operand (operands[0], SImode)
5968	  && CONST_INT_P (operands[1])
5969          && !(const_ok_for_arm (INTVAL (operands[1]))
5970               || const_ok_for_arm (~INTVAL (operands[1]))))
5971        {
5972	   if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[1]), SET))
5973	     {
5974		emit_insn (gen_rtx_SET (operands[0], operands[1]));
5975		DONE;
5976	     }
5977	  else
5978	     {
5979		arm_split_constant (SET, SImode, NULL_RTX,
5980	                            INTVAL (operands[1]), operands[0], NULL_RTX,
5981			            optimize && can_create_pseudo_p ());
5982		DONE;
5983	     }
5984        }
5985    }
5986  else /* Target doesn't have MOVT...  */
5987    {
5988      if (can_create_pseudo_p ())
5989        {
5990          if (!REG_P (operands[0]))
5991	    operands[1] = force_reg (SImode, operands[1]);
5992        }
5993    }
5994
5995  split_const (operands[1], &base, &offset);
5996  if (INTVAL (offset) != 0
5997      && targetm.cannot_force_const_mem (SImode, operands[1]))
5998    {
5999      tmp = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];
6000      emit_move_insn (tmp, base);
6001      emit_insn (gen_addsi3 (operands[0], tmp, offset));
6002      DONE;
6003    }
6004
6005  tmp = can_create_pseudo_p () ? NULL_RTX : operands[0];
6006
6007  /* Recognize the case where operand[1] is a reference to thread-local
6008     data and load its address to a register.  Offsets have been split off
6009     already.  */
6010  if (arm_tls_referenced_p (operands[1]))
6011    operands[1] = legitimize_tls_address (operands[1], tmp);
6012  else if (flag_pic
6013	   && (CONSTANT_P (operands[1])
6014	       || symbol_mentioned_p (operands[1])
6015	       || label_mentioned_p (operands[1])))
6016    operands[1] =
6017      legitimize_pic_address (operands[1], SImode, tmp);
6018  }
6019  "
6020)
6021
6022;; The ARM LO_SUM and HIGH are backwards - HIGH sets the low bits, and
6023;; LO_SUM adds in the high bits.  Fortunately these are opaque operations
6024;; so this does not matter.
6025(define_insn "*arm_movt"
6026  [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r")
6027	(lo_sum:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6028		   (match_operand:SI 2 "general_operand"      "i,i")))]
6029  "TARGET_HAVE_MOVT && arm_valid_symbolic_address_p (operands[2])"
6030  "@
6031   movt%?\t%0, #:upper16:%c2
6032   movt\t%0, #:upper16:%c2"
6033  [(set_attr "arch"  "32,v8mb")
6034   (set_attr "predicable" "yes")
6035   (set_attr "length" "4")
6036   (set_attr "type" "alu_sreg")]
6037)
6038
6039(define_insn "*arm_movsi_insn"
6040  [(set (match_operand:SI 0 "nonimmediate_operand" "=rk,r,r,r,rk,m")
6041	(match_operand:SI 1 "general_operand"      "rk, I,K,j,mi,rk"))]
6042  "TARGET_ARM && !TARGET_IWMMXT && !TARGET_HARD_FLOAT
6043   && (   register_operand (operands[0], SImode)
6044       || register_operand (operands[1], SImode))"
6045  "@
6046   mov%?\\t%0, %1
6047   mov%?\\t%0, %1
6048   mvn%?\\t%0, #%B1
6049   movw%?\\t%0, %1
6050   ldr%?\\t%0, %1
6051   str%?\\t%1, %0"
6052  [(set_attr "type" "mov_reg,mov_imm,mvn_imm,mov_imm,load_4,store_4")
6053   (set_attr "predicable" "yes")
6054   (set_attr "arch" "*,*,*,v6t2,*,*")
6055   (set_attr "pool_range" "*,*,*,*,4096,*")
6056   (set_attr "neg_pool_range" "*,*,*,*,4084,*")]
6057)
6058
6059(define_split
6060  [(set (match_operand:SI 0 "arm_general_register_operand" "")
6061	(match_operand:SI 1 "const_int_operand" ""))]
6062  "(TARGET_32BIT || TARGET_HAVE_MOVT)
6063  && (!(const_ok_for_arm (INTVAL (operands[1]))
6064        || const_ok_for_arm (~INTVAL (operands[1]))))"
6065  [(clobber (const_int 0))]
6066  "
6067  arm_split_constant (SET, SImode, NULL_RTX,
6068                      INTVAL (operands[1]), operands[0], NULL_RTX, 0);
6069  DONE;
6070  "
6071)
6072
6073;; A normal way to do (symbol + offset) requires three instructions at least
6074;; (depends on how big the offset is) as below:
6075;; movw r0, #:lower16:g
6076;; movw r0, #:upper16:g
6077;; adds r0, #4
6078;;
6079;; A better way would be:
6080;; movw r0, #:lower16:g+4
6081;; movw r0, #:upper16:g+4
6082;;
6083;; The limitation of this way is that the length of offset should be a 16-bit
6084;; signed value, because current assembler only supports REL type relocation for
6085;; such case.  If the more powerful RELA type is supported in future, we should
6086;; update this pattern to go with better way.
6087(define_split
6088  [(set (match_operand:SI 0 "arm_general_register_operand" "")
6089	(const:SI (plus:SI (match_operand:SI 1 "general_operand" "")
6090			   (match_operand:SI 2 "const_int_operand" ""))))]
6091  "TARGET_THUMB
6092   && TARGET_HAVE_MOVT
6093   && arm_disable_literal_pool
6094   && reload_completed
6095   && GET_CODE (operands[1]) == SYMBOL_REF"
6096  [(clobber (const_int 0))]
6097  "
6098    int offset = INTVAL (operands[2]);
6099
6100    if (offset < -0x8000 || offset > 0x7fff)
6101      {
6102	arm_emit_movpair (operands[0], operands[1]);
6103	emit_insn (gen_rtx_SET (operands[0],
6104				gen_rtx_PLUS (SImode, operands[0], operands[2])));
6105      }
6106    else
6107      {
6108	rtx op = gen_rtx_CONST (SImode,
6109				gen_rtx_PLUS (SImode, operands[1], operands[2]));
6110	arm_emit_movpair (operands[0], op);
6111      }
6112  "
6113)
6114
6115;; Split symbol_refs at the later stage (after cprop), instead of generating
6116;; movt/movw pair directly at expand.  Otherwise corresponding high_sum
6117;; and lo_sum would be merged back into memory load at cprop.  However,
6118;; if the default is to prefer movt/movw rather than a load from the constant
6119;; pool, the performance is better.
6120(define_split
6121  [(set (match_operand:SI 0 "arm_general_register_operand" "")
6122       (match_operand:SI 1 "general_operand" ""))]
6123  "TARGET_USE_MOVT && GET_CODE (operands[1]) == SYMBOL_REF
6124   && !flag_pic && !target_word_relocations
6125   && !arm_tls_referenced_p (operands[1])"
6126  [(clobber (const_int 0))]
6127{
6128  arm_emit_movpair (operands[0], operands[1]);
6129  DONE;
6130})
6131
6132;; When generating pic, we need to load the symbol offset into a register.
6133;; So that the optimizer does not confuse this with a normal symbol load
6134;; we use an unspec.  The offset will be loaded from a constant pool entry,
6135;; since that is the only type of relocation we can use.
6136
6137;; Wrap calculation of the whole PIC address in a single pattern for the
6138;; benefit of optimizers, particularly, PRE and HOIST.  Calculation of
6139;; a PIC address involves two loads from memory, so we want to CSE it
6140;; as often as possible.
6141;; This pattern will be split into one of the pic_load_addr_* patterns
6142;; and a move after GCSE optimizations.
6143;;
6144;; Note: Update arm.c: legitimize_pic_address() when changing this pattern.
6145(define_expand "calculate_pic_address"
6146  [(set (match_operand:SI 0 "register_operand" "")
6147	(mem:SI (plus:SI (match_operand:SI 1 "register_operand" "")
6148			 (unspec:SI [(match_operand:SI 2 "" "")]
6149				    UNSPEC_PIC_SYM))))]
6150  "flag_pic"
6151)
6152
6153;; Split calculate_pic_address into pic_load_addr_* and a move.
6154(define_split
6155  [(set (match_operand:SI 0 "register_operand" "")
6156	(mem:SI (plus:SI (match_operand:SI 1 "register_operand" "")
6157			 (unspec:SI [(match_operand:SI 2 "" "")]
6158				    UNSPEC_PIC_SYM))))]
6159  "flag_pic"
6160  [(set (match_dup 3) (unspec:SI [(match_dup 2)] UNSPEC_PIC_SYM))
6161   (set (match_dup 0) (mem:SI (plus:SI (match_dup 1) (match_dup 3))))]
6162  "operands[3] = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];"
6163)
6164
6165;; operand1 is the memory address to go into
6166;; pic_load_addr_32bit.
6167;; operand2 is the PIC label to be emitted
6168;; from pic_add_dot_plus_eight.
6169;; We do this to allow hoisting of the entire insn.
6170(define_insn_and_split "pic_load_addr_unified"
6171  [(set (match_operand:SI 0 "s_register_operand" "=r,r,l")
6172	(unspec:SI [(match_operand:SI 1 "" "mX,mX,mX")
6173		    (match_operand:SI 2 "" "")]
6174		    UNSPEC_PIC_UNIFIED))]
6175 "flag_pic"
6176 "#"
6177 "&& reload_completed"
6178 [(set (match_dup 0) (unspec:SI [(match_dup 1)] UNSPEC_PIC_SYM))
6179  (set (match_dup 0) (unspec:SI [(match_dup 0) (match_dup 3)
6180       		     		 (match_dup 2)] UNSPEC_PIC_BASE))]
6181 "operands[3] = TARGET_THUMB ? GEN_INT (4) : GEN_INT (8);"
6182 [(set_attr "type" "load_4,load_4,load_4")
6183  (set_attr "pool_range" "4096,4094,1022")
6184  (set_attr "neg_pool_range" "4084,0,0")
6185  (set_attr "arch"  "a,t2,t1")
6186  (set_attr "length" "8,6,4")]
6187)
6188
6189;; The rather odd constraints on the following are to force reload to leave
6190;; the insn alone, and to force the minipool generation pass to then move
6191;; the GOT symbol to memory.
6192
6193(define_insn "pic_load_addr_32bit"
6194  [(set (match_operand:SI 0 "s_register_operand" "=r")
6195	(unspec:SI [(match_operand:SI 1 "" "mX")] UNSPEC_PIC_SYM))]
6196  "TARGET_32BIT && flag_pic"
6197  "ldr%?\\t%0, %1"
6198  [(set_attr "type" "load_4")
6199   (set (attr "pool_range")
6200	(if_then_else (eq_attr "is_thumb" "no")
6201		      (const_int 4096)
6202		      (const_int 4094)))
6203   (set (attr "neg_pool_range")
6204	(if_then_else (eq_attr "is_thumb" "no")
6205		      (const_int 4084)
6206		      (const_int 0)))]
6207)
6208
6209(define_insn "pic_load_addr_thumb1"
6210  [(set (match_operand:SI 0 "s_register_operand" "=l")
6211	(unspec:SI [(match_operand:SI 1 "" "mX")] UNSPEC_PIC_SYM))]
6212  "TARGET_THUMB1 && flag_pic"
6213  "ldr\\t%0, %1"
6214  [(set_attr "type" "load_4")
6215   (set (attr "pool_range") (const_int 1018))]
6216)
6217
6218(define_insn "pic_add_dot_plus_four"
6219  [(set (match_operand:SI 0 "register_operand" "=r")
6220	(unspec:SI [(match_operand:SI 1 "register_operand" "0")
6221		    (const_int 4)
6222		    (match_operand 2 "" "")]
6223		   UNSPEC_PIC_BASE))]
6224  "TARGET_THUMB"
6225  "*
6226  (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
6227				     INTVAL (operands[2]));
6228  return \"add\\t%0, %|pc\";
6229  "
6230  [(set_attr "length" "2")
6231   (set_attr "type" "alu_sreg")]
6232)
6233
6234(define_insn "pic_add_dot_plus_eight"
6235  [(set (match_operand:SI 0 "register_operand" "=r")
6236	(unspec:SI [(match_operand:SI 1 "register_operand" "r")
6237		    (const_int 8)
6238		    (match_operand 2 "" "")]
6239		   UNSPEC_PIC_BASE))]
6240  "TARGET_ARM"
6241  "*
6242    (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
6243				       INTVAL (operands[2]));
6244    return \"add%?\\t%0, %|pc, %1\";
6245  "
6246  [(set_attr "predicable" "yes")
6247   (set_attr "type" "alu_sreg")]
6248)
6249
6250(define_insn "tls_load_dot_plus_eight"
6251  [(set (match_operand:SI 0 "register_operand" "=r")
6252	(mem:SI (unspec:SI [(match_operand:SI 1 "register_operand" "r")
6253			    (const_int 8)
6254			    (match_operand 2 "" "")]
6255			   UNSPEC_PIC_BASE)))]
6256  "TARGET_ARM"
6257  "*
6258    (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
6259				       INTVAL (operands[2]));
6260    return \"ldr%?\\t%0, [%|pc, %1]\t\t@ tls_load_dot_plus_eight\";
6261  "
6262  [(set_attr "predicable" "yes")
6263   (set_attr "type" "load_4")]
6264)
6265
6266;; PIC references to local variables can generate pic_add_dot_plus_eight
6267;; followed by a load.  These sequences can be crunched down to
6268;; tls_load_dot_plus_eight by a peephole.
6269
6270(define_peephole2
6271  [(set (match_operand:SI 0 "register_operand" "")
6272	(unspec:SI [(match_operand:SI 3 "register_operand" "")
6273		    (const_int 8)
6274		    (match_operand 1 "" "")]
6275		   UNSPEC_PIC_BASE))
6276   (set (match_operand:SI 2 "arm_general_register_operand" "")
6277	(mem:SI (match_dup 0)))]
6278  "TARGET_ARM && peep2_reg_dead_p (2, operands[0])"
6279  [(set (match_dup 2)
6280	(mem:SI (unspec:SI [(match_dup 3)
6281			    (const_int 8)
6282			    (match_dup 1)]
6283			   UNSPEC_PIC_BASE)))]
6284  ""
6285)
6286
6287(define_insn "pic_offset_arm"
6288  [(set (match_operand:SI 0 "register_operand" "=r")
6289	(mem:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
6290			 (unspec:SI [(match_operand:SI 2 "" "X")]
6291				    UNSPEC_PIC_OFFSET))))]
6292  "TARGET_VXWORKS_RTP && TARGET_ARM && flag_pic"
6293  "ldr%?\\t%0, [%1,%2]"
6294  [(set_attr "type" "load_4")]
6295)
6296
6297(define_expand "builtin_setjmp_receiver"
6298  [(label_ref (match_operand 0 "" ""))]
6299  "flag_pic"
6300  "
6301{
6302  /* r3 is clobbered by set/longjmp, so we can use it as a scratch
6303     register.  */
6304  if (arm_pic_register != INVALID_REGNUM)
6305    arm_load_pic_register (1UL << 3);
6306  DONE;
6307}")
6308
6309;; If copying one reg to another we can set the condition codes according to
6310;; its value.  Such a move is common after a return from subroutine and the
6311;; result is being tested against zero.
6312
6313(define_insn "*movsi_compare0"
6314  [(set (reg:CC CC_REGNUM)
6315	(compare:CC (match_operand:SI 1 "s_register_operand" "0,r")
6316		    (const_int 0)))
6317   (set (match_operand:SI 0 "s_register_operand" "=r,r")
6318	(match_dup 1))]
6319  "TARGET_32BIT"
6320  "@
6321   cmp%?\\t%0, #0
6322   subs%?\\t%0, %1, #0"
6323  [(set_attr "conds" "set")
6324   (set_attr "type" "alus_imm,alus_imm")]
6325)
6326
6327;; Subroutine to store a half word from a register into memory.
6328;; Operand 0 is the source register (HImode)
6329;; Operand 1 is the destination address in a register (SImode)
6330
6331;; In both this routine and the next, we must be careful not to spill
6332;; a memory address of reg+large_const into a separate PLUS insn, since this
6333;; can generate unrecognizable rtl.
6334
6335(define_expand "storehi"
6336  [;; store the low byte
6337   (set (match_operand 1 "" "") (match_dup 3))
6338   ;; extract the high byte
6339   (set (match_dup 2)
6340	(ashiftrt:SI (match_operand 0 "" "") (const_int 8)))
6341   ;; store the high byte
6342   (set (match_dup 4) (match_dup 5))]
6343  "TARGET_ARM"
6344  "
6345  {
6346    rtx op1 = operands[1];
6347    rtx addr = XEXP (op1, 0);
6348    enum rtx_code code = GET_CODE (addr);
6349
6350    if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1)))
6351	|| code == MINUS)
6352      op1 = replace_equiv_address (operands[1], force_reg (SImode, addr));
6353
6354    operands[4] = adjust_address (op1, QImode, 1);
6355    operands[1] = adjust_address (operands[1], QImode, 0);
6356    operands[3] = gen_lowpart (QImode, operands[0]);
6357    operands[0] = gen_lowpart (SImode, operands[0]);
6358    operands[2] = gen_reg_rtx (SImode);
6359    operands[5] = gen_lowpart (QImode, operands[2]);
6360  }"
6361)
6362
6363(define_expand "storehi_bigend"
6364  [(set (match_dup 4) (match_dup 3))
6365   (set (match_dup 2)
6366	(ashiftrt:SI (match_operand 0 "" "") (const_int 8)))
6367   (set (match_operand 1 "" "")	(match_dup 5))]
6368  "TARGET_ARM"
6369  "
6370  {
6371    rtx op1 = operands[1];
6372    rtx addr = XEXP (op1, 0);
6373    enum rtx_code code = GET_CODE (addr);
6374
6375    if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1)))
6376	|| code == MINUS)
6377      op1 = replace_equiv_address (op1, force_reg (SImode, addr));
6378
6379    operands[4] = adjust_address (op1, QImode, 1);
6380    operands[1] = adjust_address (operands[1], QImode, 0);
6381    operands[3] = gen_lowpart (QImode, operands[0]);
6382    operands[0] = gen_lowpart (SImode, operands[0]);
6383    operands[2] = gen_reg_rtx (SImode);
6384    operands[5] = gen_lowpart (QImode, operands[2]);
6385  }"
6386)
6387
6388;; Subroutine to store a half word integer constant into memory.
6389(define_expand "storeinthi"
6390  [(set (match_operand 0 "" "")
6391	(match_operand 1 "" ""))
6392   (set (match_dup 3) (match_dup 2))]
6393  "TARGET_ARM"
6394  "
6395  {
6396    HOST_WIDE_INT value = INTVAL (operands[1]);
6397    rtx addr = XEXP (operands[0], 0);
6398    rtx op0 = operands[0];
6399    enum rtx_code code = GET_CODE (addr);
6400
6401    if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1)))
6402	|| code == MINUS)
6403      op0 = replace_equiv_address (op0, force_reg (SImode, addr));
6404
6405    operands[1] = gen_reg_rtx (SImode);
6406    if (BYTES_BIG_ENDIAN)
6407      {
6408	emit_insn (gen_movsi (operands[1], GEN_INT ((value >> 8) & 255)));
6409	if ((value & 255) == ((value >> 8) & 255))
6410	  operands[2] = operands[1];
6411	else
6412	  {
6413	    operands[2] = gen_reg_rtx (SImode);
6414	    emit_insn (gen_movsi (operands[2], GEN_INT (value & 255)));
6415	  }
6416      }
6417    else
6418      {
6419	emit_insn (gen_movsi (operands[1], GEN_INT (value & 255)));
6420	if ((value & 255) == ((value >> 8) & 255))
6421	  operands[2] = operands[1];
6422	else
6423	  {
6424	    operands[2] = gen_reg_rtx (SImode);
6425	    emit_insn (gen_movsi (operands[2], GEN_INT ((value >> 8) & 255)));
6426	  }
6427      }
6428
6429    operands[3] = adjust_address (op0, QImode, 1);
6430    operands[0] = adjust_address (operands[0], QImode, 0);
6431    operands[2] = gen_lowpart (QImode, operands[2]);
6432    operands[1] = gen_lowpart (QImode, operands[1]);
6433  }"
6434)
6435
6436(define_expand "storehi_single_op"
6437  [(set (match_operand:HI 0 "memory_operand" "")
6438	(match_operand:HI 1 "general_operand" ""))]
6439  "TARGET_32BIT && arm_arch4"
6440  "
6441  if (!s_register_operand (operands[1], HImode))
6442    operands[1] = copy_to_mode_reg (HImode, operands[1]);
6443  "
6444)
6445
6446(define_expand "movhi"
6447  [(set (match_operand:HI 0 "general_operand" "")
6448	(match_operand:HI 1 "general_operand" ""))]
6449  "TARGET_EITHER"
6450  "
6451  if (TARGET_ARM)
6452    {
6453      if (can_create_pseudo_p ())
6454        {
6455          if (MEM_P (operands[0]))
6456	    {
6457	      if (arm_arch4)
6458	        {
6459	          emit_insn (gen_storehi_single_op (operands[0], operands[1]));
6460	          DONE;
6461	        }
6462	      if (CONST_INT_P (operands[1]))
6463	        emit_insn (gen_storeinthi (operands[0], operands[1]));
6464	      else
6465	        {
6466	          if (MEM_P (operands[1]))
6467		    operands[1] = force_reg (HImode, operands[1]);
6468	          if (BYTES_BIG_ENDIAN)
6469		    emit_insn (gen_storehi_bigend (operands[1], operands[0]));
6470	          else
6471		   emit_insn (gen_storehi (operands[1], operands[0]));
6472	        }
6473	      DONE;
6474	    }
6475          /* Sign extend a constant, and keep it in an SImode reg.  */
6476          else if (CONST_INT_P (operands[1]))
6477	    {
6478	      rtx reg = gen_reg_rtx (SImode);
6479	      HOST_WIDE_INT val = INTVAL (operands[1]) & 0xffff;
6480
6481	      /* If the constant is already valid, leave it alone.  */
6482	      if (!const_ok_for_arm (val))
6483	        {
6484	          /* If setting all the top bits will make the constant
6485		     loadable in a single instruction, then set them.
6486		     Otherwise, sign extend the number.  */
6487
6488	          if (const_ok_for_arm (~(val | ~0xffff)))
6489		    val |= ~0xffff;
6490	          else if (val & 0x8000)
6491		    val |= ~0xffff;
6492	        }
6493
6494	      emit_insn (gen_movsi (reg, GEN_INT (val)));
6495	      operands[1] = gen_lowpart (HImode, reg);
6496	    }
6497	  else if (arm_arch4 && optimize && can_create_pseudo_p ()
6498		   && MEM_P (operands[1]))
6499	    {
6500	      rtx reg = gen_reg_rtx (SImode);
6501
6502	      emit_insn (gen_zero_extendhisi2 (reg, operands[1]));
6503	      operands[1] = gen_lowpart (HImode, reg);
6504	    }
6505          else if (!arm_arch4)
6506	    {
6507	      if (MEM_P (operands[1]))
6508	        {
6509		  rtx base;
6510		  rtx offset = const0_rtx;
6511		  rtx reg = gen_reg_rtx (SImode);
6512
6513		  if ((REG_P (base = XEXP (operands[1], 0))
6514		       || (GET_CODE (base) == PLUS
6515			   && (CONST_INT_P (offset = XEXP (base, 1)))
6516                           && ((INTVAL(offset) & 1) != 1)
6517			   && REG_P (base = XEXP (base, 0))))
6518		      && REGNO_POINTER_ALIGN (REGNO (base)) >= 32)
6519		    {
6520		      rtx new_rtx;
6521
6522		      new_rtx = widen_memory_access (operands[1], SImode,
6523						     ((INTVAL (offset) & ~3)
6524						      - INTVAL (offset)));
6525		      emit_insn (gen_movsi (reg, new_rtx));
6526		      if (((INTVAL (offset) & 2) != 0)
6527			  ^ (BYTES_BIG_ENDIAN ? 1 : 0))
6528			{
6529			  rtx reg2 = gen_reg_rtx (SImode);
6530
6531			  emit_insn (gen_lshrsi3 (reg2, reg, GEN_INT (16)));
6532			  reg = reg2;
6533			}
6534		    }
6535		  else
6536		    emit_insn (gen_movhi_bytes (reg, operands[1]));
6537
6538		  operands[1] = gen_lowpart (HImode, reg);
6539	       }
6540	   }
6541        }
6542      /* Handle loading a large integer during reload.  */
6543      else if (CONST_INT_P (operands[1])
6544	       && !const_ok_for_arm (INTVAL (operands[1]))
6545	       && !const_ok_for_arm (~INTVAL (operands[1])))
6546        {
6547          /* Writing a constant to memory needs a scratch, which should
6548	     be handled with SECONDARY_RELOADs.  */
6549          gcc_assert (REG_P (operands[0]));
6550
6551          operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
6552          emit_insn (gen_movsi (operands[0], operands[1]));
6553          DONE;
6554       }
6555    }
6556  else if (TARGET_THUMB2)
6557    {
6558      /* Thumb-2 can do everything except mem=mem and mem=const easily.  */
6559      if (can_create_pseudo_p ())
6560	{
6561	  if (!REG_P (operands[0]))
6562	    operands[1] = force_reg (HImode, operands[1]);
6563          /* Zero extend a constant, and keep it in an SImode reg.  */
6564          else if (CONST_INT_P (operands[1]))
6565	    {
6566	      rtx reg = gen_reg_rtx (SImode);
6567	      HOST_WIDE_INT val = INTVAL (operands[1]) & 0xffff;
6568
6569	      emit_insn (gen_movsi (reg, GEN_INT (val)));
6570	      operands[1] = gen_lowpart (HImode, reg);
6571	    }
6572	}
6573    }
6574  else /* TARGET_THUMB1 */
6575    {
6576      if (can_create_pseudo_p ())
6577        {
6578	  if (CONST_INT_P (operands[1]))
6579	    {
6580	      rtx reg = gen_reg_rtx (SImode);
6581
6582	      emit_insn (gen_movsi (reg, operands[1]));
6583	      operands[1] = gen_lowpart (HImode, reg);
6584	    }
6585
6586          /* ??? We shouldn't really get invalid addresses here, but this can
6587	     happen if we are passed a SP (never OK for HImode/QImode) or
6588	     virtual register (also rejected as illegitimate for HImode/QImode)
6589	     relative address.  */
6590          /* ??? This should perhaps be fixed elsewhere, for instance, in
6591	     fixup_stack_1, by checking for other kinds of invalid addresses,
6592	     e.g. a bare reference to a virtual register.  This may confuse the
6593	     alpha though, which must handle this case differently.  */
6594          if (MEM_P (operands[0])
6595	      && !memory_address_p (GET_MODE (operands[0]),
6596				    XEXP (operands[0], 0)))
6597	    operands[0]
6598	      = replace_equiv_address (operands[0],
6599				       copy_to_reg (XEXP (operands[0], 0)));
6600
6601          if (MEM_P (operands[1])
6602	      && !memory_address_p (GET_MODE (operands[1]),
6603				    XEXP (operands[1], 0)))
6604	    operands[1]
6605	      = replace_equiv_address (operands[1],
6606				       copy_to_reg (XEXP (operands[1], 0)));
6607
6608	  if (MEM_P (operands[1]) && optimize > 0)
6609	    {
6610	      rtx reg = gen_reg_rtx (SImode);
6611
6612	      emit_insn (gen_zero_extendhisi2 (reg, operands[1]));
6613	      operands[1] = gen_lowpart (HImode, reg);
6614	    }
6615
6616          if (MEM_P (operands[0]))
6617	    operands[1] = force_reg (HImode, operands[1]);
6618        }
6619      else if (CONST_INT_P (operands[1])
6620	        && !satisfies_constraint_I (operands[1]))
6621        {
6622	  /* Handle loading a large integer during reload.  */
6623
6624          /* Writing a constant to memory needs a scratch, which should
6625	     be handled with SECONDARY_RELOADs.  */
6626          gcc_assert (REG_P (operands[0]));
6627
6628          operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
6629          emit_insn (gen_movsi (operands[0], operands[1]));
6630          DONE;
6631        }
6632    }
6633  "
6634)
6635
6636(define_expand "movhi_bytes"
6637  [(set (match_dup 2) (zero_extend:SI (match_operand:HI 1 "" "")))
6638   (set (match_dup 3)
6639	(zero_extend:SI (match_dup 6)))
6640   (set (match_operand:SI 0 "" "")
6641	 (ior:SI (ashift:SI (match_dup 4) (const_int 8)) (match_dup 5)))]
6642  "TARGET_ARM"
6643  "
6644  {
6645    rtx mem1, mem2;
6646    rtx addr = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
6647
6648    mem1 = change_address (operands[1], QImode, addr);
6649    mem2 = change_address (operands[1], QImode,
6650			   plus_constant (Pmode, addr, 1));
6651    operands[0] = gen_lowpart (SImode, operands[0]);
6652    operands[1] = mem1;
6653    operands[2] = gen_reg_rtx (SImode);
6654    operands[3] = gen_reg_rtx (SImode);
6655    operands[6] = mem2;
6656
6657    if (BYTES_BIG_ENDIAN)
6658      {
6659	operands[4] = operands[2];
6660	operands[5] = operands[3];
6661      }
6662    else
6663      {
6664	operands[4] = operands[3];
6665	operands[5] = operands[2];
6666      }
6667  }"
6668)
6669
6670(define_expand "movhi_bigend"
6671  [(set (match_dup 2)
6672	(rotate:SI (subreg:SI (match_operand:HI 1 "memory_operand" "") 0)
6673		   (const_int 16)))
6674   (set (match_dup 3)
6675	(ashiftrt:SI (match_dup 2) (const_int 16)))
6676   (set (match_operand:HI 0 "s_register_operand" "")
6677	(match_dup 4))]
6678  "TARGET_ARM"
6679  "
6680  operands[2] = gen_reg_rtx (SImode);
6681  operands[3] = gen_reg_rtx (SImode);
6682  operands[4] = gen_lowpart (HImode, operands[3]);
6683  "
6684)
6685
6686;; Pattern to recognize insn generated default case above
6687(define_insn "*movhi_insn_arch4"
6688  [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m,r")
6689	(match_operand:HI 1 "general_operand"      "rIk,K,n,r,mi"))]
6690  "TARGET_ARM
6691   && arm_arch4 && !TARGET_HARD_FLOAT
6692   && (register_operand (operands[0], HImode)
6693       || register_operand (operands[1], HImode))"
6694  "@
6695   mov%?\\t%0, %1\\t%@ movhi
6696   mvn%?\\t%0, #%B1\\t%@ movhi
6697   movw%?\\t%0, %L1\\t%@ movhi
6698   strh%?\\t%1, %0\\t%@ movhi
6699   ldrh%?\\t%0, %1\\t%@ movhi"
6700  [(set_attr "predicable" "yes")
6701   (set_attr "pool_range" "*,*,*,*,256")
6702   (set_attr "neg_pool_range" "*,*,*,*,244")
6703   (set_attr "arch" "*,*,v6t2,*,*")
6704   (set_attr_alternative "type"
6705                         [(if_then_else (match_operand 1 "const_int_operand" "")
6706                                        (const_string "mov_imm" )
6707                                        (const_string "mov_reg"))
6708                          (const_string "mvn_imm")
6709                          (const_string "mov_imm")
6710                          (const_string "store_4")
6711                          (const_string "load_4")])]
6712)
6713
6714(define_insn "*movhi_bytes"
6715  [(set (match_operand:HI 0 "s_register_operand" "=r,r,r")
6716	(match_operand:HI 1 "arm_rhs_operand"  "I,rk,K"))]
6717  "TARGET_ARM && !TARGET_HARD_FLOAT"
6718  "@
6719   mov%?\\t%0, %1\\t%@ movhi
6720   mov%?\\t%0, %1\\t%@ movhi
6721   mvn%?\\t%0, #%B1\\t%@ movhi"
6722  [(set_attr "predicable" "yes")
6723   (set_attr "type" "mov_imm,mov_reg,mvn_imm")]
6724)
6725
6726;; We use a DImode scratch because we may occasionally need an additional
6727;; temporary if the address isn't offsettable -- push_reload doesn't seem
6728;; to take any notice of the "o" constraints on reload_memory_operand operand.
6729(define_expand "reload_outhi"
6730  [(parallel [(match_operand:HI 0 "arm_reload_memory_operand" "=o")
6731	      (match_operand:HI 1 "s_register_operand"        "r")
6732	      (match_operand:DI 2 "s_register_operand"        "=&l")])]
6733  "TARGET_EITHER"
6734  "if (TARGET_ARM)
6735     arm_reload_out_hi (operands);
6736   else
6737     thumb_reload_out_hi (operands);
6738  DONE;
6739  "
6740)
6741
6742(define_expand "reload_inhi"
6743  [(parallel [(match_operand:HI 0 "s_register_operand" "=r")
6744	      (match_operand:HI 1 "arm_reload_memory_operand" "o")
6745	      (match_operand:DI 2 "s_register_operand" "=&r")])]
6746  "TARGET_EITHER"
6747  "
6748  if (TARGET_ARM)
6749    arm_reload_in_hi (operands);
6750  else
6751    thumb_reload_out_hi (operands);
6752  DONE;
6753")
6754
6755(define_expand "movqi"
6756  [(set (match_operand:QI 0 "general_operand" "")
6757        (match_operand:QI 1 "general_operand" ""))]
6758  "TARGET_EITHER"
6759  "
6760  /* Everything except mem = const or mem = mem can be done easily */
6761
6762  if (can_create_pseudo_p ())
6763    {
6764      if (CONST_INT_P (operands[1]))
6765	{
6766	  rtx reg = gen_reg_rtx (SImode);
6767
6768	  /* For thumb we want an unsigned immediate, then we are more likely
6769	     to be able to use a movs insn.  */
6770	  if (TARGET_THUMB)
6771	    operands[1] = GEN_INT (INTVAL (operands[1]) & 255);
6772
6773	  emit_insn (gen_movsi (reg, operands[1]));
6774	  operands[1] = gen_lowpart (QImode, reg);
6775	}
6776
6777      if (TARGET_THUMB)
6778	{
6779          /* ??? We shouldn't really get invalid addresses here, but this can
6780	     happen if we are passed a SP (never OK for HImode/QImode) or
6781	     virtual register (also rejected as illegitimate for HImode/QImode)
6782	     relative address.  */
6783          /* ??? This should perhaps be fixed elsewhere, for instance, in
6784	     fixup_stack_1, by checking for other kinds of invalid addresses,
6785	     e.g. a bare reference to a virtual register.  This may confuse the
6786	     alpha though, which must handle this case differently.  */
6787          if (MEM_P (operands[0])
6788	      && !memory_address_p (GET_MODE (operands[0]),
6789		  		     XEXP (operands[0], 0)))
6790	    operands[0]
6791	      = replace_equiv_address (operands[0],
6792				       copy_to_reg (XEXP (operands[0], 0)));
6793          if (MEM_P (operands[1])
6794	      && !memory_address_p (GET_MODE (operands[1]),
6795				    XEXP (operands[1], 0)))
6796	     operands[1]
6797	       = replace_equiv_address (operands[1],
6798					copy_to_reg (XEXP (operands[1], 0)));
6799	}
6800
6801      if (MEM_P (operands[1]) && optimize > 0)
6802	{
6803	  rtx reg = gen_reg_rtx (SImode);
6804
6805	  emit_insn (gen_zero_extendqisi2 (reg, operands[1]));
6806	  operands[1] = gen_lowpart (QImode, reg);
6807	}
6808
6809      if (MEM_P (operands[0]))
6810	operands[1] = force_reg (QImode, operands[1]);
6811    }
6812  else if (TARGET_THUMB
6813	   && CONST_INT_P (operands[1])
6814	   && !satisfies_constraint_I (operands[1]))
6815    {
6816      /* Handle loading a large integer during reload.  */
6817
6818      /* Writing a constant to memory needs a scratch, which should
6819	 be handled with SECONDARY_RELOADs.  */
6820      gcc_assert (REG_P (operands[0]));
6821
6822      operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
6823      emit_insn (gen_movsi (operands[0], operands[1]));
6824      DONE;
6825    }
6826  "
6827)
6828
6829(define_insn "*arm_movqi_insn"
6830  [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,r,l,r,l,Uu,r,m")
6831	(match_operand:QI 1 "general_operand" "rk,rk,I,Py,K,Uu,l,Uh,r"))]
6832  "TARGET_32BIT
6833   && (   register_operand (operands[0], QImode)
6834       || register_operand (operands[1], QImode))"
6835  "@
6836   mov%?\\t%0, %1
6837   mov%?\\t%0, %1
6838   mov%?\\t%0, %1
6839   mov%?\\t%0, %1
6840   mvn%?\\t%0, #%B1
6841   ldrb%?\\t%0, %1
6842   strb%?\\t%1, %0
6843   ldrb%?\\t%0, %1
6844   strb%?\\t%1, %0"
6845  [(set_attr "type" "mov_reg,mov_reg,mov_imm,mov_imm,mvn_imm,load_4,store_4,load_4,store_4")
6846   (set_attr "predicable" "yes")
6847   (set_attr "predicable_short_it" "yes,yes,no,yes,no,no,no,no,no")
6848   (set_attr "arch" "t2,any,any,t2,any,t2,t2,any,any")
6849   (set_attr "length" "2,4,4,2,4,2,2,4,4")]
6850)
6851
6852;; HFmode moves
6853(define_expand "movhf"
6854  [(set (match_operand:HF 0 "general_operand" "")
6855	(match_operand:HF 1 "general_operand" ""))]
6856  "TARGET_EITHER"
6857  "
6858  if (TARGET_32BIT)
6859    {
6860      if (MEM_P (operands[0]))
6861        operands[1] = force_reg (HFmode, operands[1]);
6862    }
6863  else /* TARGET_THUMB1 */
6864    {
6865      if (can_create_pseudo_p ())
6866        {
6867           if (!REG_P (operands[0]))
6868	     operands[1] = force_reg (HFmode, operands[1]);
6869        }
6870    }
6871  "
6872)
6873
6874(define_insn "*arm32_movhf"
6875  [(set (match_operand:HF 0 "nonimmediate_operand" "=r,m,r,r")
6876	(match_operand:HF 1 "general_operand"	   " m,r,r,F"))]
6877  "TARGET_32BIT && !TARGET_HARD_FLOAT
6878   && (	  s_register_operand (operands[0], HFmode)
6879       || s_register_operand (operands[1], HFmode))"
6880  "*
6881  switch (which_alternative)
6882    {
6883    case 0:	/* ARM register from memory */
6884      return \"ldrh%?\\t%0, %1\\t%@ __fp16\";
6885    case 1:	/* memory from ARM register */
6886      return \"strh%?\\t%1, %0\\t%@ __fp16\";
6887    case 2:	/* ARM register from ARM register */
6888      return \"mov%?\\t%0, %1\\t%@ __fp16\";
6889    case 3:	/* ARM register from constant */
6890      {
6891	long bits;
6892	rtx ops[4];
6893
6894	bits = real_to_target (NULL, CONST_DOUBLE_REAL_VALUE (operands[1]),
6895			       HFmode);
6896	ops[0] = operands[0];
6897	ops[1] = GEN_INT (bits);
6898	ops[2] = GEN_INT (bits & 0xff00);
6899	ops[3] = GEN_INT (bits & 0x00ff);
6900
6901	if (arm_arch_thumb2)
6902	  output_asm_insn (\"movw%?\\t%0, %1\", ops);
6903	else
6904	  output_asm_insn (\"mov%?\\t%0, %2\;orr%?\\t%0, %0, %3\", ops);
6905	return \"\";
6906       }
6907    default:
6908      gcc_unreachable ();
6909    }
6910  "
6911  [(set_attr "conds" "unconditional")
6912   (set_attr "type" "load_4,store_4,mov_reg,multiple")
6913   (set_attr "length" "4,4,4,8")
6914   (set_attr "predicable" "yes")]
6915)
6916
6917(define_expand "movsf"
6918  [(set (match_operand:SF 0 "general_operand" "")
6919	(match_operand:SF 1 "general_operand" ""))]
6920  "TARGET_EITHER"
6921  "
6922  if (TARGET_32BIT)
6923    {
6924      if (MEM_P (operands[0]))
6925        operands[1] = force_reg (SFmode, operands[1]);
6926    }
6927  else /* TARGET_THUMB1 */
6928    {
6929      if (can_create_pseudo_p ())
6930        {
6931           if (!REG_P (operands[0]))
6932	     operands[1] = force_reg (SFmode, operands[1]);
6933        }
6934    }
6935  "
6936)
6937
6938;; Transform a floating-point move of a constant into a core register into
6939;; an SImode operation.
6940(define_split
6941  [(set (match_operand:SF 0 "arm_general_register_operand" "")
6942	(match_operand:SF 1 "immediate_operand" ""))]
6943  "TARGET_EITHER
6944   && reload_completed
6945   && CONST_DOUBLE_P (operands[1])"
6946  [(set (match_dup 2) (match_dup 3))]
6947  "
6948  operands[2] = gen_lowpart (SImode, operands[0]);
6949  operands[3] = gen_lowpart (SImode, operands[1]);
6950  if (operands[2] == 0 || operands[3] == 0)
6951    FAIL;
6952  "
6953)
6954
6955(define_insn "*arm_movsf_soft_insn"
6956  [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,m")
6957	(match_operand:SF 1 "general_operand"  "r,mE,r"))]
6958  "TARGET_32BIT
6959   && TARGET_SOFT_FLOAT
6960   && (!MEM_P (operands[0])
6961       || register_operand (operands[1], SFmode))"
6962  "@
6963   mov%?\\t%0, %1
6964   ldr%?\\t%0, %1\\t%@ float
6965   str%?\\t%1, %0\\t%@ float"
6966  [(set_attr "predicable" "yes")
6967   (set_attr "type" "mov_reg,load_4,store_4")
6968   (set_attr "arm_pool_range" "*,4096,*")
6969   (set_attr "thumb2_pool_range" "*,4094,*")
6970   (set_attr "arm_neg_pool_range" "*,4084,*")
6971   (set_attr "thumb2_neg_pool_range" "*,0,*")]
6972)
6973
6974(define_expand "movdf"
6975  [(set (match_operand:DF 0 "general_operand" "")
6976	(match_operand:DF 1 "general_operand" ""))]
6977  "TARGET_EITHER"
6978  "
6979  if (TARGET_32BIT)
6980    {
6981      if (MEM_P (operands[0]))
6982        operands[1] = force_reg (DFmode, operands[1]);
6983    }
6984  else /* TARGET_THUMB */
6985    {
6986      if (can_create_pseudo_p ())
6987        {
6988          if (!REG_P (operands[0]))
6989	    operands[1] = force_reg (DFmode, operands[1]);
6990        }
6991    }
6992  "
6993)
6994
6995;; Reloading a df mode value stored in integer regs to memory can require a
6996;; scratch reg.
6997(define_expand "reload_outdf"
6998  [(match_operand:DF 0 "arm_reload_memory_operand" "=o")
6999   (match_operand:DF 1 "s_register_operand" "r")
7000   (match_operand:SI 2 "s_register_operand" "=&r")]
7001  "TARGET_THUMB2"
7002  "
7003  {
7004    enum rtx_code code = GET_CODE (XEXP (operands[0], 0));
7005
7006    if (code == REG)
7007      operands[2] = XEXP (operands[0], 0);
7008    else if (code == POST_INC || code == PRE_DEC)
7009      {
7010	operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7011	operands[1] = gen_rtx_SUBREG (DImode, operands[1], 0);
7012	emit_insn (gen_movdi (operands[0], operands[1]));
7013	DONE;
7014      }
7015    else if (code == PRE_INC)
7016      {
7017	rtx reg = XEXP (XEXP (operands[0], 0), 0);
7018
7019	emit_insn (gen_addsi3 (reg, reg, GEN_INT (8)));
7020	operands[2] = reg;
7021      }
7022    else if (code == POST_DEC)
7023      operands[2] = XEXP (XEXP (operands[0], 0), 0);
7024    else
7025      emit_insn (gen_addsi3 (operands[2], XEXP (XEXP (operands[0], 0), 0),
7026			     XEXP (XEXP (operands[0], 0), 1)));
7027
7028    emit_insn (gen_rtx_SET (replace_equiv_address (operands[0], operands[2]),
7029			    operands[1]));
7030
7031    if (code == POST_DEC)
7032      emit_insn (gen_addsi3 (operands[2], operands[2], GEN_INT (-8)));
7033
7034    DONE;
7035  }"
7036)
7037
7038(define_insn "*movdf_soft_insn"
7039  [(set (match_operand:DF 0 "nonimmediate_soft_df_operand" "=r,r,r,q,m")
7040	(match_operand:DF 1 "soft_df_operand" "rDa,Db,Dc,mF,q"))]
7041  "TARGET_32BIT && TARGET_SOFT_FLOAT
7042   && (   register_operand (operands[0], DFmode)
7043       || register_operand (operands[1], DFmode))"
7044  "*
7045  switch (which_alternative)
7046    {
7047    case 0:
7048    case 1:
7049    case 2:
7050      return \"#\";
7051    default:
7052      return output_move_double (operands, true, NULL);
7053    }
7054  "
7055  [(set_attr "length" "8,12,16,8,8")
7056   (set_attr "type" "multiple,multiple,multiple,load_8,store_8")
7057   (set_attr "arm_pool_range" "*,*,*,1020,*")
7058   (set_attr "thumb2_pool_range" "*,*,*,1018,*")
7059   (set_attr "arm_neg_pool_range" "*,*,*,1004,*")
7060   (set_attr "thumb2_neg_pool_range" "*,*,*,0,*")]
7061)
7062
7063
7064;; load- and store-multiple insns
7065;; The arm can load/store any set of registers, provided that they are in
7066;; ascending order, but these expanders assume a contiguous set.
7067
7068(define_expand "load_multiple"
7069  [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
7070                          (match_operand:SI 1 "" ""))
7071                     (use (match_operand:SI 2 "" ""))])]
7072  "TARGET_32BIT"
7073{
7074  HOST_WIDE_INT offset = 0;
7075
7076  /* Support only fixed point registers.  */
7077  if (!CONST_INT_P (operands[2])
7078      || INTVAL (operands[2]) > MAX_LDM_STM_OPS
7079      || INTVAL (operands[2]) < 2
7080      || !MEM_P (operands[1])
7081      || !REG_P (operands[0])
7082      || REGNO (operands[0]) > (LAST_ARM_REGNUM - 1)
7083      || REGNO (operands[0]) + INTVAL (operands[2]) > LAST_ARM_REGNUM)
7084    FAIL;
7085
7086  operands[3]
7087    = arm_gen_load_multiple (arm_regs_in_sequence + REGNO (operands[0]),
7088			     INTVAL (operands[2]),
7089			     force_reg (SImode, XEXP (operands[1], 0)),
7090			     FALSE, operands[1], &offset);
7091})
7092
7093(define_expand "store_multiple"
7094  [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
7095                          (match_operand:SI 1 "" ""))
7096                     (use (match_operand:SI 2 "" ""))])]
7097  "TARGET_32BIT"
7098{
7099  HOST_WIDE_INT offset = 0;
7100
7101  /* Support only fixed point registers.  */
7102  if (!CONST_INT_P (operands[2])
7103      || INTVAL (operands[2]) > MAX_LDM_STM_OPS
7104      || INTVAL (operands[2]) < 2
7105      || !REG_P (operands[1])
7106      || !MEM_P (operands[0])
7107      || REGNO (operands[1]) > (LAST_ARM_REGNUM - 1)
7108      || REGNO (operands[1]) + INTVAL (operands[2]) > LAST_ARM_REGNUM)
7109    FAIL;
7110
7111  operands[3]
7112    = arm_gen_store_multiple (arm_regs_in_sequence + REGNO (operands[1]),
7113			      INTVAL (operands[2]),
7114			      force_reg (SImode, XEXP (operands[0], 0)),
7115			      FALSE, operands[0], &offset);
7116})
7117
7118
7119(define_expand "setmemsi"
7120  [(match_operand:BLK 0 "general_operand" "")
7121   (match_operand:SI 1 "const_int_operand" "")
7122   (match_operand:SI 2 "const_int_operand" "")
7123   (match_operand:SI 3 "const_int_operand" "")]
7124  "TARGET_32BIT"
7125{
7126  if (arm_gen_setmem (operands))
7127    DONE;
7128
7129  FAIL;
7130})
7131
7132
7133;; Move a block of memory if it is word aligned and MORE than 2 words long.
7134;; We could let this apply for blocks of less than this, but it clobbers so
7135;; many registers that there is then probably a better way.
7136
7137(define_expand "movmemqi"
7138  [(match_operand:BLK 0 "general_operand" "")
7139   (match_operand:BLK 1 "general_operand" "")
7140   (match_operand:SI 2 "const_int_operand" "")
7141   (match_operand:SI 3 "const_int_operand" "")]
7142  ""
7143  "
7144  if (TARGET_32BIT)
7145    {
7146      if (TARGET_LDRD && current_tune->prefer_ldrd_strd
7147          && !optimize_function_for_size_p (cfun))
7148        {
7149          if (gen_movmem_ldrd_strd (operands))
7150            DONE;
7151          FAIL;
7152        }
7153
7154      if (arm_gen_movmemqi (operands))
7155        DONE;
7156      FAIL;
7157    }
7158  else /* TARGET_THUMB1 */
7159    {
7160      if (   INTVAL (operands[3]) != 4
7161          || INTVAL (operands[2]) > 48)
7162        FAIL;
7163
7164      thumb_expand_movmemqi (operands);
7165      DONE;
7166    }
7167  "
7168)
7169
7170
7171;; Compare & branch insns
7172;; The range calculations are based as follows:
7173;; For forward branches, the address calculation returns the address of
7174;; the next instruction.  This is 2 beyond the branch instruction.
7175;; For backward branches, the address calculation returns the address of
7176;; the first instruction in this pattern (cmp).  This is 2 before the branch
7177;; instruction for the shortest sequence, and 4 before the branch instruction
7178;; if we have to jump around an unconditional branch.
7179;; To the basic branch range the PC offset must be added (this is +4).
7180;; So for forward branches we have
7181;;   (pos_range - pos_base_offs + pc_offs) = (pos_range - 2 + 4).
7182;; And for backward branches we have
7183;;   (neg_range - neg_base_offs + pc_offs) = (neg_range - (-2 or -4) + 4).
7184;;
7185;; For a 'b'       pos_range = 2046, neg_range = -2048 giving (-2040->2048).
7186;; For a 'b<cond>' pos_range = 254,  neg_range = -256  giving (-250 ->256).
7187
7188(define_expand "cbranchsi4"
7189  [(set (pc) (if_then_else
7190	      (match_operator 0 "expandable_comparison_operator"
7191	       [(match_operand:SI 1 "s_register_operand" "")
7192	        (match_operand:SI 2 "nonmemory_operand" "")])
7193	      (label_ref (match_operand 3 "" ""))
7194	      (pc)))]
7195  "TARGET_EITHER"
7196  "
7197  if (!TARGET_THUMB1)
7198    {
7199      if (!arm_validize_comparison (&operands[0], &operands[1], &operands[2]))
7200        FAIL;
7201      emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
7202				      operands[3]));
7203      DONE;
7204    }
7205  if (thumb1_cmpneg_operand (operands[2], SImode))
7206    {
7207      emit_jump_insn (gen_cbranchsi4_scratch (NULL, operands[1], operands[2],
7208					      operands[3], operands[0]));
7209      DONE;
7210    }
7211  if (!thumb1_cmp_operand (operands[2], SImode))
7212    operands[2] = force_reg (SImode, operands[2]);
7213  ")
7214
7215(define_expand "cbranchsf4"
7216  [(set (pc) (if_then_else
7217	      (match_operator 0 "expandable_comparison_operator"
7218	       [(match_operand:SF 1 "s_register_operand" "")
7219	        (match_operand:SF 2 "vfp_compare_operand" "")])
7220	      (label_ref (match_operand 3 "" ""))
7221	      (pc)))]
7222  "TARGET_32BIT && TARGET_HARD_FLOAT"
7223  "emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
7224				   operands[3])); DONE;"
7225)
7226
7227(define_expand "cbranchdf4"
7228  [(set (pc) (if_then_else
7229	      (match_operator 0 "expandable_comparison_operator"
7230	       [(match_operand:DF 1 "s_register_operand" "")
7231	        (match_operand:DF 2 "vfp_compare_operand" "")])
7232	      (label_ref (match_operand 3 "" ""))
7233	      (pc)))]
7234  "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
7235  "emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
7236				   operands[3])); DONE;"
7237)
7238
7239(define_expand "cbranchdi4"
7240  [(set (pc) (if_then_else
7241	      (match_operator 0 "expandable_comparison_operator"
7242	       [(match_operand:DI 1 "s_register_operand" "")
7243	        (match_operand:DI 2 "cmpdi_operand" "")])
7244	      (label_ref (match_operand 3 "" ""))
7245	      (pc)))]
7246  "TARGET_32BIT"
7247  "{
7248     if (!arm_validize_comparison (&operands[0], &operands[1], &operands[2]))
7249       FAIL;
7250     emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
7251				       operands[3]));
7252     DONE;
7253   }"
7254)
7255
7256;; Comparison and test insns
7257
7258(define_insn "*arm_cmpsi_insn"
7259  [(set (reg:CC CC_REGNUM)
7260	(compare:CC (match_operand:SI 0 "s_register_operand" "l,r,r,r,r")
7261		    (match_operand:SI 1 "arm_add_operand"    "Py,r,r,I,L")))]
7262  "TARGET_32BIT"
7263  "@
7264   cmp%?\\t%0, %1
7265   cmp%?\\t%0, %1
7266   cmp%?\\t%0, %1
7267   cmp%?\\t%0, %1
7268   cmn%?\\t%0, #%n1"
7269  [(set_attr "conds" "set")
7270   (set_attr "arch" "t2,t2,any,any,any")
7271   (set_attr "length" "2,2,4,4,4")
7272   (set_attr "predicable" "yes")
7273   (set_attr "predicable_short_it" "yes,yes,yes,no,no")
7274   (set_attr "type" "alus_imm,alus_sreg,alus_sreg,alus_imm,alus_imm")]
7275)
7276
7277(define_insn "*cmpsi_shiftsi"
7278  [(set (reg:CC CC_REGNUM)
7279	(compare:CC (match_operand:SI   0 "s_register_operand" "r,r,r")
7280		    (match_operator:SI  3 "shift_operator"
7281		     [(match_operand:SI 1 "s_register_operand" "r,r,r")
7282		      (match_operand:SI 2 "shift_amount_operand" "M,r,M")])))]
7283  "TARGET_32BIT"
7284  "cmp\\t%0, %1%S3"
7285  [(set_attr "conds" "set")
7286   (set_attr "shift" "1")
7287   (set_attr "arch" "32,a,a")
7288   (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
7289
7290(define_insn "*cmpsi_shiftsi_swp"
7291  [(set (reg:CC_SWP CC_REGNUM)
7292	(compare:CC_SWP (match_operator:SI 3 "shift_operator"
7293			 [(match_operand:SI 1 "s_register_operand" "r,r,r")
7294			  (match_operand:SI 2 "shift_amount_operand" "M,r,M")])
7295			(match_operand:SI 0 "s_register_operand" "r,r,r")))]
7296  "TARGET_32BIT"
7297  "cmp%?\\t%0, %1%S3"
7298  [(set_attr "conds" "set")
7299   (set_attr "shift" "1")
7300   (set_attr "arch" "32,a,a")
7301   (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
7302
7303(define_insn "*arm_cmpsi_negshiftsi_si"
7304  [(set (reg:CC_Z CC_REGNUM)
7305	(compare:CC_Z
7306	 (neg:SI (match_operator:SI 1 "shift_operator"
7307		    [(match_operand:SI 2 "s_register_operand" "r")
7308		     (match_operand:SI 3 "reg_or_int_operand" "rM")]))
7309	 (match_operand:SI 0 "s_register_operand" "r")))]
7310  "TARGET_ARM"
7311  "cmn%?\\t%0, %2%S1"
7312  [(set_attr "conds" "set")
7313   (set (attr "type") (if_then_else (match_operand 3 "const_int_operand" "")
7314				    (const_string "alus_shift_imm")
7315				    (const_string "alus_shift_reg")))
7316   (set_attr "predicable" "yes")]
7317)
7318
7319;; DImode comparisons.  The generic code generates branches that
7320;; if-conversion can not reduce to a conditional compare, so we do
7321;; that directly.
7322
7323(define_insn_and_split "*arm_cmpdi_insn"
7324  [(set (reg:CC_NCV CC_REGNUM)
7325	(compare:CC_NCV (match_operand:DI 0 "s_register_operand" "r")
7326			(match_operand:DI 1 "arm_di_operand"	   "rDi")))
7327   (clobber (match_scratch:SI 2 "=r"))]
7328  "TARGET_32BIT"
7329  "#"   ; "cmp\\t%Q0, %Q1\;sbcs\\t%2, %R0, %R1"
7330  "&& reload_completed"
7331  [(set (reg:CC CC_REGNUM)
7332        (compare:CC (match_dup 0) (match_dup 1)))
7333   (parallel [(set (reg:CC CC_REGNUM)
7334                   (compare:CC (match_dup 3) (match_dup 4)))
7335              (set (match_dup 2)
7336                   (minus:SI (match_dup 5)
7337                            (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))])]
7338  {
7339    operands[3] = gen_highpart (SImode, operands[0]);
7340    operands[0] = gen_lowpart (SImode, operands[0]);
7341    if (CONST_INT_P (operands[1]))
7342      {
7343        operands[4] = GEN_INT (~INTVAL (gen_highpart_mode (SImode,
7344                                                           DImode,
7345                                                           operands[1])));
7346        operands[5] = gen_rtx_PLUS (SImode, operands[3], operands[4]);
7347      }
7348    else
7349      {
7350        operands[4] = gen_highpart (SImode, operands[1]);
7351        operands[5] = gen_rtx_MINUS (SImode, operands[3], operands[4]);
7352      }
7353    operands[1] = gen_lowpart (SImode, operands[1]);
7354    operands[2] = gen_lowpart (SImode, operands[2]);
7355  }
7356  [(set_attr "conds" "set")
7357   (set_attr "length" "8")
7358   (set_attr "type" "multiple")]
7359)
7360
7361(define_insn_and_split "*arm_cmpdi_unsigned"
7362  [(set (reg:CC_CZ CC_REGNUM)
7363        (compare:CC_CZ (match_operand:DI 0 "s_register_operand" "l,r,r,r")
7364                       (match_operand:DI 1 "arm_di_operand"     "Py,r,Di,rDi")))]
7365
7366  "TARGET_32BIT"
7367  "#"   ; "cmp\\t%R0, %R1\;it eq\;cmpeq\\t%Q0, %Q1"
7368  "&& reload_completed"
7369  [(set (reg:CC CC_REGNUM)
7370        (compare:CC (match_dup 2) (match_dup 3)))
7371   (cond_exec (eq:SI (reg:CC CC_REGNUM) (const_int 0))
7372              (set (reg:CC CC_REGNUM)
7373                   (compare:CC (match_dup 0) (match_dup 1))))]
7374  {
7375    operands[2] = gen_highpart (SImode, operands[0]);
7376    operands[0] = gen_lowpart (SImode, operands[0]);
7377    if (CONST_INT_P (operands[1]))
7378      operands[3] = gen_highpart_mode (SImode, DImode, operands[1]);
7379    else
7380      operands[3] = gen_highpart (SImode, operands[1]);
7381    operands[1] = gen_lowpart (SImode, operands[1]);
7382  }
7383  [(set_attr "conds" "set")
7384   (set_attr "enabled_for_short_it" "yes,yes,no,*")
7385   (set_attr "arch" "t2,t2,t2,a")
7386   (set_attr "length" "6,6,10,8")
7387   (set_attr "type" "multiple")]
7388)
7389
7390(define_insn "*arm_cmpdi_zero"
7391  [(set (reg:CC_Z CC_REGNUM)
7392	(compare:CC_Z (match_operand:DI 0 "s_register_operand" "r")
7393		      (const_int 0)))
7394   (clobber (match_scratch:SI 1 "=r"))]
7395  "TARGET_32BIT"
7396  "orrs%?\\t%1, %Q0, %R0"
7397  [(set_attr "conds" "set")
7398   (set_attr "type" "logics_reg")]
7399)
7400
7401; This insn allows redundant compares to be removed by cse, nothing should
7402; ever appear in the output file since (set (reg x) (reg x)) is a no-op that
7403; is deleted later on. The match_dup will match the mode here, so that
7404; mode changes of the condition codes aren't lost by this even though we don't
7405; specify what they are.
7406
7407(define_insn "*deleted_compare"
7408  [(set (match_operand 0 "cc_register" "") (match_dup 0))]
7409  "TARGET_32BIT"
7410  "\\t%@ deleted compare"
7411  [(set_attr "conds" "set")
7412   (set_attr "length" "0")
7413   (set_attr "type" "no_insn")]
7414)
7415
7416
7417;; Conditional branch insns
7418
7419(define_expand "cbranch_cc"
7420  [(set (pc)
7421	(if_then_else (match_operator 0 "" [(match_operand 1 "" "")
7422					    (match_operand 2 "" "")])
7423		      (label_ref (match_operand 3 "" ""))
7424		      (pc)))]
7425  "TARGET_32BIT"
7426  "operands[1] = arm_gen_compare_reg (GET_CODE (operands[0]),
7427				      operands[1], operands[2], NULL_RTX);
7428   operands[2] = const0_rtx;"
7429)
7430
7431;;
7432;; Patterns to match conditional branch insns.
7433;;
7434
7435(define_insn "arm_cond_branch"
7436  [(set (pc)
7437	(if_then_else (match_operator 1 "arm_comparison_operator"
7438		       [(match_operand 2 "cc_register" "") (const_int 0)])
7439		      (label_ref (match_operand 0 "" ""))
7440		      (pc)))]
7441  "TARGET_32BIT"
7442  "*
7443  if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
7444    {
7445      arm_ccfsm_state += 2;
7446      return \"\";
7447    }
7448  return \"b%d1\\t%l0\";
7449  "
7450  [(set_attr "conds" "use")
7451   (set_attr "type" "branch")
7452   (set (attr "length")
7453	(if_then_else
7454	   (and (match_test "TARGET_THUMB2")
7455		(and (ge (minus (match_dup 0) (pc)) (const_int -250))
7456		     (le (minus (match_dup 0) (pc)) (const_int 256))))
7457	   (const_int 2)
7458	   (const_int 4)))]
7459)
7460
7461(define_insn "*arm_cond_branch_reversed"
7462  [(set (pc)
7463	(if_then_else (match_operator 1 "arm_comparison_operator"
7464		       [(match_operand 2 "cc_register" "") (const_int 0)])
7465		      (pc)
7466		      (label_ref (match_operand 0 "" ""))))]
7467  "TARGET_32BIT"
7468  "*
7469  if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
7470    {
7471      arm_ccfsm_state += 2;
7472      return \"\";
7473    }
7474  return \"b%D1\\t%l0\";
7475  "
7476  [(set_attr "conds" "use")
7477   (set_attr "type" "branch")
7478   (set (attr "length")
7479	(if_then_else
7480	   (and (match_test "TARGET_THUMB2")
7481		(and (ge (minus (match_dup 0) (pc)) (const_int -250))
7482		     (le (minus (match_dup 0) (pc)) (const_int 256))))
7483	   (const_int 2)
7484	   (const_int 4)))]
7485)
7486
7487
7488
7489; scc insns
7490
7491(define_expand "cstore_cc"
7492  [(set (match_operand:SI 0 "s_register_operand" "")
7493	(match_operator:SI 1 "" [(match_operand 2 "" "")
7494				 (match_operand 3 "" "")]))]
7495  "TARGET_32BIT"
7496  "operands[2] = arm_gen_compare_reg (GET_CODE (operands[1]),
7497				      operands[2], operands[3], NULL_RTX);
7498   operands[3] = const0_rtx;"
7499)
7500
7501(define_insn_and_split "*mov_scc"
7502  [(set (match_operand:SI 0 "s_register_operand" "=r")
7503	(match_operator:SI 1 "arm_comparison_operator_mode"
7504	 [(match_operand 2 "cc_register" "") (const_int 0)]))]
7505  "TARGET_ARM"
7506  "#"   ; "mov%D1\\t%0, #0\;mov%d1\\t%0, #1"
7507  "TARGET_ARM"
7508  [(set (match_dup 0)
7509        (if_then_else:SI (match_dup 1)
7510                         (const_int 1)
7511                         (const_int 0)))]
7512  ""
7513  [(set_attr "conds" "use")
7514   (set_attr "length" "8")
7515   (set_attr "type" "multiple")]
7516)
7517
7518(define_insn_and_split "*mov_negscc"
7519  [(set (match_operand:SI 0 "s_register_operand" "=r")
7520	(neg:SI (match_operator:SI 1 "arm_comparison_operator_mode"
7521		 [(match_operand 2 "cc_register" "") (const_int 0)])))]
7522  "TARGET_ARM"
7523  "#"   ; "mov%D1\\t%0, #0\;mvn%d1\\t%0, #0"
7524  "TARGET_ARM"
7525  [(set (match_dup 0)
7526        (if_then_else:SI (match_dup 1)
7527                         (match_dup 3)
7528                         (const_int 0)))]
7529  {
7530    operands[3] = GEN_INT (~0);
7531  }
7532  [(set_attr "conds" "use")
7533   (set_attr "length" "8")
7534   (set_attr "type" "multiple")]
7535)
7536
7537(define_insn_and_split "*mov_notscc"
7538  [(set (match_operand:SI 0 "s_register_operand" "=r")
7539	(not:SI (match_operator:SI 1 "arm_comparison_operator"
7540		 [(match_operand 2 "cc_register" "") (const_int 0)])))]
7541  "TARGET_ARM"
7542  "#"   ; "mvn%D1\\t%0, #0\;mvn%d1\\t%0, #1"
7543  "TARGET_ARM"
7544  [(set (match_dup 0)
7545        (if_then_else:SI (match_dup 1)
7546                         (match_dup 3)
7547                         (match_dup 4)))]
7548  {
7549    operands[3] = GEN_INT (~1);
7550    operands[4] = GEN_INT (~0);
7551  }
7552  [(set_attr "conds" "use")
7553   (set_attr "length" "8")
7554   (set_attr "type" "multiple")]
7555)
7556
7557(define_expand "cstoresi4"
7558  [(set (match_operand:SI 0 "s_register_operand" "")
7559	(match_operator:SI 1 "expandable_comparison_operator"
7560	 [(match_operand:SI 2 "s_register_operand" "")
7561	  (match_operand:SI 3 "reg_or_int_operand" "")]))]
7562  "TARGET_32BIT || TARGET_THUMB1"
7563  "{
7564  rtx op3, scratch, scratch2;
7565
7566  if (!TARGET_THUMB1)
7567    {
7568      if (!arm_add_operand (operands[3], SImode))
7569	operands[3] = force_reg (SImode, operands[3]);
7570      emit_insn (gen_cstore_cc (operands[0], operands[1],
7571				operands[2], operands[3]));
7572      DONE;
7573    }
7574
7575  if (operands[3] == const0_rtx)
7576    {
7577      switch (GET_CODE (operands[1]))
7578	{
7579	case EQ:
7580	  emit_insn (gen_cstoresi_eq0_thumb1 (operands[0], operands[2]));
7581	  break;
7582
7583	case NE:
7584	  emit_insn (gen_cstoresi_ne0_thumb1 (operands[0], operands[2]));
7585	  break;
7586
7587	case LE:
7588          scratch = expand_binop (SImode, add_optab, operands[2], constm1_rtx,
7589				  NULL_RTX, 0, OPTAB_WIDEN);
7590          scratch = expand_binop (SImode, ior_optab, operands[2], scratch,
7591				  NULL_RTX, 0, OPTAB_WIDEN);
7592          expand_binop (SImode, lshr_optab, scratch, GEN_INT (31),
7593			operands[0], 1, OPTAB_WIDEN);
7594	  break;
7595
7596        case GE:
7597          scratch = expand_unop (SImode, one_cmpl_optab, operands[2],
7598				 NULL_RTX, 1);
7599          expand_binop (SImode, lshr_optab, scratch, GEN_INT (31),
7600			NULL_RTX, 1, OPTAB_WIDEN);
7601          break;
7602
7603        case GT:
7604          scratch = expand_binop (SImode, ashr_optab, operands[2],
7605				  GEN_INT (31), NULL_RTX, 0, OPTAB_WIDEN);
7606          scratch = expand_binop (SImode, sub_optab, scratch, operands[2],
7607				  NULL_RTX, 0, OPTAB_WIDEN);
7608          expand_binop (SImode, lshr_optab, scratch, GEN_INT (31), operands[0],
7609			0, OPTAB_WIDEN);
7610          break;
7611
7612	/* LT is handled by generic code.  No need for unsigned with 0.  */
7613	default:
7614	  FAIL;
7615	}
7616      DONE;
7617    }
7618
7619  switch (GET_CODE (operands[1]))
7620    {
7621    case EQ:
7622      scratch = expand_binop (SImode, sub_optab, operands[2], operands[3],
7623			      NULL_RTX, 0, OPTAB_WIDEN);
7624      emit_insn (gen_cstoresi_eq0_thumb1 (operands[0], scratch));
7625      break;
7626
7627    case NE:
7628      scratch = expand_binop (SImode, sub_optab, operands[2], operands[3],
7629			      NULL_RTX, 0, OPTAB_WIDEN);
7630      emit_insn (gen_cstoresi_ne0_thumb1 (operands[0], scratch));
7631      break;
7632
7633    case LE:
7634      op3 = force_reg (SImode, operands[3]);
7635
7636      scratch = expand_binop (SImode, lshr_optab, operands[2], GEN_INT (31),
7637			      NULL_RTX, 1, OPTAB_WIDEN);
7638      scratch2 = expand_binop (SImode, ashr_optab, op3, GEN_INT (31),
7639			      NULL_RTX, 0, OPTAB_WIDEN);
7640      emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch2,
7641					  op3, operands[2]));
7642      break;
7643
7644    case GE:
7645      op3 = operands[3];
7646      if (!thumb1_cmp_operand (op3, SImode))
7647        op3 = force_reg (SImode, op3);
7648      scratch = expand_binop (SImode, ashr_optab, operands[2], GEN_INT (31),
7649			      NULL_RTX, 0, OPTAB_WIDEN);
7650      scratch2 = expand_binop (SImode, lshr_optab, op3, GEN_INT (31),
7651			       NULL_RTX, 1, OPTAB_WIDEN);
7652      emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch2,
7653					  operands[2], op3));
7654      break;
7655
7656    case LEU:
7657      op3 = force_reg (SImode, operands[3]);
7658      scratch = force_reg (SImode, const0_rtx);
7659      emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch,
7660					  op3, operands[2]));
7661      break;
7662
7663    case GEU:
7664      op3 = operands[3];
7665      if (!thumb1_cmp_operand (op3, SImode))
7666        op3 = force_reg (SImode, op3);
7667      scratch = force_reg (SImode, const0_rtx);
7668      emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch,
7669					  operands[2], op3));
7670      break;
7671
7672    case LTU:
7673      op3 = operands[3];
7674      if (!thumb1_cmp_operand (op3, SImode))
7675        op3 = force_reg (SImode, op3);
7676      scratch = gen_reg_rtx (SImode);
7677      emit_insn (gen_cstoresi_ltu_thumb1 (operands[0], operands[2], op3));
7678      break;
7679
7680    case GTU:
7681      op3 = force_reg (SImode, operands[3]);
7682      scratch = gen_reg_rtx (SImode);
7683      emit_insn (gen_cstoresi_ltu_thumb1 (operands[0], op3, operands[2]));
7684      break;
7685
7686    /* No good sequences for GT, LT.  */
7687    default:
7688      FAIL;
7689    }
7690  DONE;
7691}")
7692
7693(define_expand "cstorehf4"
7694  [(set (match_operand:SI 0 "s_register_operand")
7695	(match_operator:SI 1 "expandable_comparison_operator"
7696	 [(match_operand:HF 2 "s_register_operand")
7697	  (match_operand:HF 3 "vfp_compare_operand")]))]
7698  "TARGET_VFP_FP16INST"
7699  {
7700    if (!arm_validize_comparison (&operands[1],
7701				  &operands[2],
7702				  &operands[3]))
7703       FAIL;
7704
7705    emit_insn (gen_cstore_cc (operands[0], operands[1],
7706			      operands[2], operands[3]));
7707    DONE;
7708  }
7709)
7710
7711(define_expand "cstoresf4"
7712  [(set (match_operand:SI 0 "s_register_operand" "")
7713	(match_operator:SI 1 "expandable_comparison_operator"
7714	 [(match_operand:SF 2 "s_register_operand" "")
7715	  (match_operand:SF 3 "vfp_compare_operand" "")]))]
7716  "TARGET_32BIT && TARGET_HARD_FLOAT"
7717  "emit_insn (gen_cstore_cc (operands[0], operands[1],
7718			     operands[2], operands[3])); DONE;"
7719)
7720
7721(define_expand "cstoredf4"
7722  [(set (match_operand:SI 0 "s_register_operand" "")
7723	(match_operator:SI 1 "expandable_comparison_operator"
7724	 [(match_operand:DF 2 "s_register_operand" "")
7725	  (match_operand:DF 3 "vfp_compare_operand" "")]))]
7726  "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
7727  "emit_insn (gen_cstore_cc (operands[0], operands[1],
7728			     operands[2], operands[3])); DONE;"
7729)
7730
7731(define_expand "cstoredi4"
7732  [(set (match_operand:SI 0 "s_register_operand" "")
7733	(match_operator:SI 1 "expandable_comparison_operator"
7734	 [(match_operand:DI 2 "s_register_operand" "")
7735	  (match_operand:DI 3 "cmpdi_operand" "")]))]
7736  "TARGET_32BIT"
7737  "{
7738     if (!arm_validize_comparison (&operands[1],
7739     				   &operands[2],
7740				   &operands[3]))
7741       FAIL;
7742     emit_insn (gen_cstore_cc (operands[0], operands[1], operands[2],
7743		      	         operands[3]));
7744     DONE;
7745   }"
7746)
7747
7748
7749;; Conditional move insns
7750
7751(define_expand "movsicc"
7752  [(set (match_operand:SI 0 "s_register_operand" "")
7753	(if_then_else:SI (match_operand 1 "expandable_comparison_operator" "")
7754			 (match_operand:SI 2 "arm_not_operand" "")
7755			 (match_operand:SI 3 "arm_not_operand" "")))]
7756  "TARGET_32BIT"
7757  "
7758  {
7759    enum rtx_code code;
7760    rtx ccreg;
7761
7762    if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
7763				  &XEXP (operands[1], 1)))
7764      FAIL;
7765
7766    code = GET_CODE (operands[1]);
7767    ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
7768				 XEXP (operands[1], 1), NULL_RTX);
7769    operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7770  }"
7771)
7772
7773(define_expand "movhfcc"
7774  [(set (match_operand:HF 0 "s_register_operand")
7775	(if_then_else:HF (match_operand 1 "arm_cond_move_operator")
7776			 (match_operand:HF 2 "s_register_operand")
7777			 (match_operand:HF 3 "s_register_operand")))]
7778  "TARGET_VFP_FP16INST"
7779  "
7780  {
7781    enum rtx_code code = GET_CODE (operands[1]);
7782    rtx ccreg;
7783
7784    if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
7785				  &XEXP (operands[1], 1)))
7786      FAIL;
7787
7788    code = GET_CODE (operands[1]);
7789    ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
7790				 XEXP (operands[1], 1), NULL_RTX);
7791    operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7792  }"
7793)
7794
7795(define_expand "movsfcc"
7796  [(set (match_operand:SF 0 "s_register_operand" "")
7797	(if_then_else:SF (match_operand 1 "arm_cond_move_operator" "")
7798			 (match_operand:SF 2 "s_register_operand" "")
7799			 (match_operand:SF 3 "s_register_operand" "")))]
7800  "TARGET_32BIT && TARGET_HARD_FLOAT"
7801  "
7802  {
7803    enum rtx_code code = GET_CODE (operands[1]);
7804    rtx ccreg;
7805
7806    if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
7807       				  &XEXP (operands[1], 1)))
7808       FAIL;
7809
7810    code = GET_CODE (operands[1]);
7811    ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
7812				 XEXP (operands[1], 1), NULL_RTX);
7813    operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7814  }"
7815)
7816
7817(define_expand "movdfcc"
7818  [(set (match_operand:DF 0 "s_register_operand" "")
7819	(if_then_else:DF (match_operand 1 "arm_cond_move_operator" "")
7820			 (match_operand:DF 2 "s_register_operand" "")
7821			 (match_operand:DF 3 "s_register_operand" "")))]
7822  "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
7823  "
7824  {
7825    enum rtx_code code = GET_CODE (operands[1]);
7826    rtx ccreg;
7827
7828    if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
7829       				  &XEXP (operands[1], 1)))
7830       FAIL;
7831    code = GET_CODE (operands[1]);
7832    ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
7833				 XEXP (operands[1], 1), NULL_RTX);
7834    operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7835  }"
7836)
7837
7838(define_insn "*cmov<mode>"
7839    [(set (match_operand:SDF 0 "s_register_operand" "=<F_constraint>")
7840	(if_then_else:SDF (match_operator 1 "arm_vsel_comparison_operator"
7841			  [(match_operand 2 "cc_register" "") (const_int 0)])
7842			  (match_operand:SDF 3 "s_register_operand"
7843			                      "<F_constraint>")
7844			  (match_operand:SDF 4 "s_register_operand"
7845			                      "<F_constraint>")))]
7846  "TARGET_HARD_FLOAT && TARGET_VFP5 <vfp_double_cond>"
7847  "*
7848  {
7849    enum arm_cond_code code = maybe_get_arm_condition_code (operands[1]);
7850    switch (code)
7851      {
7852      case ARM_GE:
7853      case ARM_GT:
7854      case ARM_EQ:
7855      case ARM_VS:
7856        return \"vsel%d1.<V_if_elem>\\t%<V_reg>0, %<V_reg>3, %<V_reg>4\";
7857      case ARM_LT:
7858      case ARM_LE:
7859      case ARM_NE:
7860      case ARM_VC:
7861        return \"vsel%D1.<V_if_elem>\\t%<V_reg>0, %<V_reg>4, %<V_reg>3\";
7862      default:
7863        gcc_unreachable ();
7864      }
7865    return \"\";
7866  }"
7867  [(set_attr "conds" "use")
7868   (set_attr "type" "fcsel")]
7869)
7870
7871(define_insn "*cmovhf"
7872    [(set (match_operand:HF 0 "s_register_operand" "=t")
7873	(if_then_else:HF (match_operator 1 "arm_vsel_comparison_operator"
7874			 [(match_operand 2 "cc_register" "") (const_int 0)])
7875			  (match_operand:HF 3 "s_register_operand" "t")
7876			  (match_operand:HF 4 "s_register_operand" "t")))]
7877  "TARGET_VFP_FP16INST"
7878  "*
7879  {
7880    enum arm_cond_code code = maybe_get_arm_condition_code (operands[1]);
7881    switch (code)
7882      {
7883      case ARM_GE:
7884      case ARM_GT:
7885      case ARM_EQ:
7886      case ARM_VS:
7887	return \"vsel%d1.f16\\t%0, %3, %4\";
7888      case ARM_LT:
7889      case ARM_LE:
7890      case ARM_NE:
7891      case ARM_VC:
7892	return \"vsel%D1.f16\\t%0, %4, %3\";
7893      default:
7894	gcc_unreachable ();
7895      }
7896    return \"\";
7897  }"
7898  [(set_attr "conds" "use")
7899   (set_attr "type" "fcsel")]
7900)
7901
7902(define_insn_and_split "*movsicc_insn"
7903  [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r,r,r,r,r")
7904	(if_then_else:SI
7905	 (match_operator 3 "arm_comparison_operator"
7906	  [(match_operand 4 "cc_register" "") (const_int 0)])
7907	 (match_operand:SI 1 "arm_not_operand" "0,0,rI,K,rI,rI,K,K")
7908	 (match_operand:SI 2 "arm_not_operand" "rI,K,0,0,rI,K,rI,K")))]
7909  "TARGET_ARM"
7910  "@
7911   mov%D3\\t%0, %2
7912   mvn%D3\\t%0, #%B2
7913   mov%d3\\t%0, %1
7914   mvn%d3\\t%0, #%B1
7915   #
7916   #
7917   #
7918   #"
7919   ; alt4: mov%d3\\t%0, %1\;mov%D3\\t%0, %2
7920   ; alt5: mov%d3\\t%0, %1\;mvn%D3\\t%0, #%B2
7921   ; alt6: mvn%d3\\t%0, #%B1\;mov%D3\\t%0, %2
7922   ; alt7: mvn%d3\\t%0, #%B1\;mvn%D3\\t%0, #%B2"
7923  "&& reload_completed"
7924  [(const_int 0)]
7925  {
7926    enum rtx_code rev_code;
7927    machine_mode mode;
7928    rtx rev_cond;
7929
7930    emit_insn (gen_rtx_COND_EXEC (VOIDmode,
7931                                  operands[3],
7932                                  gen_rtx_SET (operands[0], operands[1])));
7933
7934    rev_code = GET_CODE (operands[3]);
7935    mode = GET_MODE (operands[4]);
7936    if (mode == CCFPmode || mode == CCFPEmode)
7937      rev_code = reverse_condition_maybe_unordered (rev_code);
7938    else
7939      rev_code = reverse_condition (rev_code);
7940
7941    rev_cond = gen_rtx_fmt_ee (rev_code,
7942                               VOIDmode,
7943                               operands[4],
7944                               const0_rtx);
7945    emit_insn (gen_rtx_COND_EXEC (VOIDmode,
7946                                  rev_cond,
7947                                  gen_rtx_SET (operands[0], operands[2])));
7948    DONE;
7949  }
7950  [(set_attr "length" "4,4,4,4,8,8,8,8")
7951   (set_attr "conds" "use")
7952   (set_attr_alternative "type"
7953                         [(if_then_else (match_operand 2 "const_int_operand" "")
7954                                        (const_string "mov_imm")
7955                                        (const_string "mov_reg"))
7956                          (const_string "mvn_imm")
7957                          (if_then_else (match_operand 1 "const_int_operand" "")
7958                                        (const_string "mov_imm")
7959                                        (const_string "mov_reg"))
7960                          (const_string "mvn_imm")
7961                          (const_string "multiple")
7962                          (const_string "multiple")
7963                          (const_string "multiple")
7964                          (const_string "multiple")])]
7965)
7966
7967(define_insn "*movsfcc_soft_insn"
7968  [(set (match_operand:SF 0 "s_register_operand" "=r,r")
7969	(if_then_else:SF (match_operator 3 "arm_comparison_operator"
7970			  [(match_operand 4 "cc_register" "") (const_int 0)])
7971			 (match_operand:SF 1 "s_register_operand" "0,r")
7972			 (match_operand:SF 2 "s_register_operand" "r,0")))]
7973  "TARGET_ARM && TARGET_SOFT_FLOAT"
7974  "@
7975   mov%D3\\t%0, %2
7976   mov%d3\\t%0, %1"
7977  [(set_attr "conds" "use")
7978   (set_attr "type" "mov_reg")]
7979)
7980
7981
7982;; Jump and linkage insns
7983
7984(define_expand "jump"
7985  [(set (pc)
7986	(label_ref (match_operand 0 "" "")))]
7987  "TARGET_EITHER"
7988  ""
7989)
7990
7991(define_insn "*arm_jump"
7992  [(set (pc)
7993	(label_ref (match_operand 0 "" "")))]
7994  "TARGET_32BIT"
7995  "*
7996  {
7997    if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
7998      {
7999        arm_ccfsm_state += 2;
8000        return \"\";
8001      }
8002    return \"b%?\\t%l0\";
8003  }
8004  "
8005  [(set_attr "predicable" "yes")
8006   (set (attr "length")
8007	(if_then_else
8008	   (and (match_test "TARGET_THUMB2")
8009		(and (ge (minus (match_dup 0) (pc)) (const_int -2044))
8010		     (le (minus (match_dup 0) (pc)) (const_int 2048))))
8011	   (const_int 2)
8012	   (const_int 4)))
8013   (set_attr "type" "branch")]
8014)
8015
8016(define_expand "call"
8017  [(parallel [(call (match_operand 0 "memory_operand" "")
8018	            (match_operand 1 "general_operand" ""))
8019	      (use (match_operand 2 "" ""))
8020	      (clobber (reg:SI LR_REGNUM))])]
8021  "TARGET_EITHER"
8022  "
8023  {
8024    rtx callee, pat;
8025    tree addr = MEM_EXPR (operands[0]);
8026
8027    /* In an untyped call, we can get NULL for operand 2.  */
8028    if (operands[2] == NULL_RTX)
8029      operands[2] = const0_rtx;
8030
8031    /* Decide if we should generate indirect calls by loading the
8032       32-bit address of the callee into a register before performing the
8033       branch and link.  */
8034    callee = XEXP (operands[0], 0);
8035    if (GET_CODE (callee) == SYMBOL_REF
8036	? arm_is_long_call_p (SYMBOL_REF_DECL (callee))
8037	: !REG_P (callee))
8038      XEXP (operands[0], 0) = force_reg (Pmode, callee);
8039
8040    if (detect_cmse_nonsecure_call (addr))
8041      {
8042	pat = gen_nonsecure_call_internal (operands[0], operands[1],
8043					   operands[2]);
8044	emit_call_insn (pat);
8045      }
8046    else
8047      {
8048	pat = gen_call_internal (operands[0], operands[1], operands[2]);
8049	arm_emit_call_insn (pat, XEXP (operands[0], 0), false);
8050      }
8051    DONE;
8052  }"
8053)
8054
8055(define_expand "call_internal"
8056  [(parallel [(call (match_operand 0 "memory_operand" "")
8057	            (match_operand 1 "general_operand" ""))
8058	      (use (match_operand 2 "" ""))
8059	      (clobber (reg:SI LR_REGNUM))])])
8060
8061(define_expand "nonsecure_call_internal"
8062  [(parallel [(call (unspec:SI [(match_operand 0 "memory_operand" "")]
8063			       UNSPEC_NONSECURE_MEM)
8064		    (match_operand 1 "general_operand" ""))
8065	      (use (match_operand 2 "" ""))
8066	      (clobber (reg:SI LR_REGNUM))])]
8067  "use_cmse"
8068  "
8069  {
8070    rtx tmp;
8071    tmp = copy_to_suggested_reg (XEXP (operands[0], 0),
8072				 gen_rtx_REG (SImode, R4_REGNUM),
8073				 SImode);
8074
8075    operands[0] = replace_equiv_address (operands[0], tmp);
8076  }")
8077
8078(define_insn "*call_reg_armv5"
8079  [(call (mem:SI (match_operand:SI 0 "s_register_operand" "r"))
8080         (match_operand 1 "" ""))
8081   (use (match_operand 2 "" ""))
8082   (clobber (reg:SI LR_REGNUM))]
8083  "TARGET_ARM && arm_arch5 && !SIBLING_CALL_P (insn)"
8084  "blx%?\\t%0"
8085  [(set_attr "type" "call")]
8086)
8087
8088(define_insn "*call_reg_arm"
8089  [(call (mem:SI (match_operand:SI 0 "s_register_operand" "r"))
8090         (match_operand 1 "" ""))
8091   (use (match_operand 2 "" ""))
8092   (clobber (reg:SI LR_REGNUM))]
8093  "TARGET_ARM && !arm_arch5 && !SIBLING_CALL_P (insn)"
8094  "*
8095  return output_call (operands);
8096  "
8097  ;; length is worst case, normally it is only two
8098  [(set_attr "length" "12")
8099   (set_attr "type" "call")]
8100)
8101
8102
8103(define_expand "call_value"
8104  [(parallel [(set (match_operand       0 "" "")
8105	           (call (match_operand 1 "memory_operand" "")
8106		         (match_operand 2 "general_operand" "")))
8107	      (use (match_operand 3 "" ""))
8108	      (clobber (reg:SI LR_REGNUM))])]
8109  "TARGET_EITHER"
8110  "
8111  {
8112    rtx pat, callee;
8113    tree addr = MEM_EXPR (operands[1]);
8114
8115    /* In an untyped call, we can get NULL for operand 2.  */
8116    if (operands[3] == 0)
8117      operands[3] = const0_rtx;
8118
8119    /* Decide if we should generate indirect calls by loading the
8120       32-bit address of the callee into a register before performing the
8121       branch and link.  */
8122    callee = XEXP (operands[1], 0);
8123    if (GET_CODE (callee) == SYMBOL_REF
8124	? arm_is_long_call_p (SYMBOL_REF_DECL (callee))
8125	: !REG_P (callee))
8126      XEXP (operands[1], 0) = force_reg (Pmode, callee);
8127
8128    if (detect_cmse_nonsecure_call (addr))
8129      {
8130	pat = gen_nonsecure_call_value_internal (operands[0], operands[1],
8131						 operands[2], operands[3]);
8132	emit_call_insn (pat);
8133      }
8134    else
8135      {
8136	pat = gen_call_value_internal (operands[0], operands[1],
8137				       operands[2], operands[3]);
8138	arm_emit_call_insn (pat, XEXP (operands[1], 0), false);
8139      }
8140    DONE;
8141  }"
8142)
8143
8144(define_expand "call_value_internal"
8145  [(parallel [(set (match_operand       0 "" "")
8146	           (call (match_operand 1 "memory_operand" "")
8147		         (match_operand 2 "general_operand" "")))
8148	      (use (match_operand 3 "" ""))
8149	      (clobber (reg:SI LR_REGNUM))])])
8150
8151(define_expand "nonsecure_call_value_internal"
8152  [(parallel [(set (match_operand       0 "" "")
8153		   (call (unspec:SI [(match_operand 1 "memory_operand" "")]
8154				    UNSPEC_NONSECURE_MEM)
8155			 (match_operand 2 "general_operand" "")))
8156	      (use (match_operand 3 "" ""))
8157	      (clobber (reg:SI LR_REGNUM))])]
8158  "use_cmse"
8159  "
8160  {
8161    rtx tmp;
8162    tmp = copy_to_suggested_reg (XEXP (operands[1], 0),
8163				 gen_rtx_REG (SImode, R4_REGNUM),
8164				 SImode);
8165
8166    operands[1] = replace_equiv_address (operands[1], tmp);
8167  }")
8168
8169(define_insn "*call_value_reg_armv5"
8170  [(set (match_operand 0 "" "")
8171        (call (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
8172	      (match_operand 2 "" "")))
8173   (use (match_operand 3 "" ""))
8174   (clobber (reg:SI LR_REGNUM))]
8175  "TARGET_ARM && arm_arch5 && !SIBLING_CALL_P (insn)"
8176  "blx%?\\t%1"
8177  [(set_attr "type" "call")]
8178)
8179
8180(define_insn "*call_value_reg_arm"
8181  [(set (match_operand 0 "" "")
8182        (call (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
8183	      (match_operand 2 "" "")))
8184   (use (match_operand 3 "" ""))
8185   (clobber (reg:SI LR_REGNUM))]
8186  "TARGET_ARM && !arm_arch5 && !SIBLING_CALL_P (insn)"
8187  "*
8188  return output_call (&operands[1]);
8189  "
8190  [(set_attr "length" "12")
8191   (set_attr "type" "call")]
8192)
8193
8194;; Allow calls to SYMBOL_REFs specially as they are not valid general addresses
8195;; The 'a' causes the operand to be treated as an address, i.e. no '#' output.
8196
8197(define_insn "*call_symbol"
8198  [(call (mem:SI (match_operand:SI 0 "" ""))
8199	 (match_operand 1 "" ""))
8200   (use (match_operand 2 "" ""))
8201   (clobber (reg:SI LR_REGNUM))]
8202  "TARGET_32BIT
8203   && !SIBLING_CALL_P (insn)
8204   && (GET_CODE (operands[0]) == SYMBOL_REF)
8205   && !arm_is_long_call_p (SYMBOL_REF_DECL (operands[0]))"
8206  "*
8207  {
8208   rtx op = operands[0];
8209
8210   /* Switch mode now when possible.  */
8211   if (SYMBOL_REF_DECL (op) && !TREE_PUBLIC (SYMBOL_REF_DECL (op))
8212        && arm_arch5 && arm_change_mode_p (SYMBOL_REF_DECL (op)))
8213      return NEED_PLT_RELOC ? \"blx%?\\t%a0(PLT)\" : \"blx%?\\t(%a0)\";
8214
8215    return NEED_PLT_RELOC ? \"bl%?\\t%a0(PLT)\" : \"bl%?\\t%a0\";
8216  }"
8217  [(set_attr "type" "call")]
8218)
8219
8220(define_insn "*call_value_symbol"
8221  [(set (match_operand 0 "" "")
8222	(call (mem:SI (match_operand:SI 1 "" ""))
8223	(match_operand:SI 2 "" "")))
8224   (use (match_operand 3 "" ""))
8225   (clobber (reg:SI LR_REGNUM))]
8226  "TARGET_32BIT
8227   && !SIBLING_CALL_P (insn)
8228   && (GET_CODE (operands[1]) == SYMBOL_REF)
8229   && !arm_is_long_call_p (SYMBOL_REF_DECL (operands[1]))"
8230  "*
8231  {
8232   rtx op = operands[1];
8233
8234   /* Switch mode now when possible.  */
8235   if (SYMBOL_REF_DECL (op) && !TREE_PUBLIC (SYMBOL_REF_DECL (op))
8236        && arm_arch5 && arm_change_mode_p (SYMBOL_REF_DECL (op)))
8237      return NEED_PLT_RELOC ? \"blx%?\\t%a1(PLT)\" : \"blx%?\\t(%a1)\";
8238
8239    return NEED_PLT_RELOC ? \"bl%?\\t%a1(PLT)\" : \"bl%?\\t%a1\";
8240  }"
8241  [(set_attr "type" "call")]
8242)
8243
8244(define_expand "sibcall_internal"
8245  [(parallel [(call (match_operand 0 "memory_operand" "")
8246		    (match_operand 1 "general_operand" ""))
8247	      (return)
8248	      (use (match_operand 2 "" ""))])])
8249
8250;; We may also be able to do sibcalls for Thumb, but it's much harder...
8251(define_expand "sibcall"
8252  [(parallel [(call (match_operand 0 "memory_operand" "")
8253		    (match_operand 1 "general_operand" ""))
8254	      (return)
8255	      (use (match_operand 2 "" ""))])]
8256  "TARGET_32BIT"
8257  "
8258  {
8259    rtx pat;
8260
8261    if ((!REG_P (XEXP (operands[0], 0))
8262	 && GET_CODE (XEXP (operands[0], 0)) != SYMBOL_REF)
8263	|| (GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
8264	    && arm_is_long_call_p (SYMBOL_REF_DECL (XEXP (operands[0], 0)))))
8265     XEXP (operands[0], 0) = force_reg (SImode, XEXP (operands[0], 0));
8266
8267    if (operands[2] == NULL_RTX)
8268      operands[2] = const0_rtx;
8269
8270    pat = gen_sibcall_internal (operands[0], operands[1], operands[2]);
8271    arm_emit_call_insn (pat, operands[0], true);
8272    DONE;
8273  }"
8274)
8275
8276(define_expand "sibcall_value_internal"
8277  [(parallel [(set (match_operand 0 "" "")
8278		   (call (match_operand 1 "memory_operand" "")
8279			 (match_operand 2 "general_operand" "")))
8280	      (return)
8281	      (use (match_operand 3 "" ""))])])
8282
8283(define_expand "sibcall_value"
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  "TARGET_32BIT"
8290  "
8291  {
8292    rtx pat;
8293
8294    if ((!REG_P (XEXP (operands[1], 0))
8295	 && GET_CODE (XEXP (operands[1], 0)) != SYMBOL_REF)
8296	|| (GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
8297	    && arm_is_long_call_p (SYMBOL_REF_DECL (XEXP (operands[1], 0)))))
8298     XEXP (operands[1], 0) = force_reg (SImode, XEXP (operands[1], 0));
8299
8300    if (operands[3] == NULL_RTX)
8301      operands[3] = const0_rtx;
8302
8303    pat = gen_sibcall_value_internal (operands[0], operands[1],
8304                                      operands[2], operands[3]);
8305    arm_emit_call_insn (pat, operands[1], true);
8306    DONE;
8307  }"
8308)
8309
8310(define_insn "*sibcall_insn"
8311 [(call (mem:SI (match_operand:SI 0 "call_insn_operand" "Cs, US"))
8312	(match_operand 1 "" ""))
8313  (return)
8314  (use (match_operand 2 "" ""))]
8315  "TARGET_32BIT && SIBLING_CALL_P (insn)"
8316  "*
8317  if (which_alternative == 1)
8318    return NEED_PLT_RELOC ? \"b%?\\t%a0(PLT)\" : \"b%?\\t%a0\";
8319  else
8320    {
8321      if (arm_arch5 || arm_arch4t)
8322	return \"bx%?\\t%0\\t%@ indirect register sibling call\";
8323      else
8324	return \"mov%?\\t%|pc, %0\\t%@ indirect register sibling call\";
8325    }
8326  "
8327  [(set_attr "type" "call")]
8328)
8329
8330(define_insn "*sibcall_value_insn"
8331 [(set (match_operand 0 "" "")
8332       (call (mem:SI (match_operand:SI 1 "call_insn_operand" "Cs,US"))
8333	     (match_operand 2 "" "")))
8334  (return)
8335  (use (match_operand 3 "" ""))]
8336  "TARGET_32BIT && SIBLING_CALL_P (insn)"
8337  "*
8338  if (which_alternative == 1)
8339   return NEED_PLT_RELOC ? \"b%?\\t%a1(PLT)\" : \"b%?\\t%a1\";
8340  else
8341    {
8342      if (arm_arch5 || arm_arch4t)
8343	return \"bx%?\\t%1\";
8344      else
8345	return \"mov%?\\t%|pc, %1\\t@ indirect sibling call \";
8346    }
8347  "
8348  [(set_attr "type" "call")]
8349)
8350
8351(define_expand "<return_str>return"
8352  [(RETURNS)]
8353  "(TARGET_ARM || (TARGET_THUMB2
8354                   && ARM_FUNC_TYPE (arm_current_func_type ()) == ARM_FT_NORMAL
8355                   && !IS_STACKALIGN (arm_current_func_type ())))
8356    <return_cond_false>"
8357  "
8358  {
8359    if (TARGET_THUMB2)
8360      {
8361        thumb2_expand_return (<return_simple_p>);
8362        DONE;
8363      }
8364  }
8365  "
8366)
8367
8368;; Often the return insn will be the same as loading from memory, so set attr
8369(define_insn "*arm_return"
8370  [(return)]
8371  "TARGET_ARM && USE_RETURN_INSN (FALSE)"
8372  "*
8373  {
8374    if (arm_ccfsm_state == 2)
8375      {
8376        arm_ccfsm_state += 2;
8377        return \"\";
8378      }
8379    return output_return_instruction (const_true_rtx, true, false, false);
8380  }"
8381  [(set_attr "type" "load_4")
8382   (set_attr "length" "12")
8383   (set_attr "predicable" "yes")]
8384)
8385
8386(define_insn "*cond_<return_str>return"
8387  [(set (pc)
8388        (if_then_else (match_operator 0 "arm_comparison_operator"
8389		       [(match_operand 1 "cc_register" "") (const_int 0)])
8390                      (RETURNS)
8391                      (pc)))]
8392  "TARGET_ARM  <return_cond_true>"
8393  "*
8394  {
8395    if (arm_ccfsm_state == 2)
8396      {
8397        arm_ccfsm_state += 2;
8398        return \"\";
8399      }
8400    return output_return_instruction (operands[0], true, false,
8401				      <return_simple_p>);
8402  }"
8403  [(set_attr "conds" "use")
8404   (set_attr "length" "12")
8405   (set_attr "type" "load_4")]
8406)
8407
8408(define_insn "*cond_<return_str>return_inverted"
8409  [(set (pc)
8410        (if_then_else (match_operator 0 "arm_comparison_operator"
8411		       [(match_operand 1 "cc_register" "") (const_int 0)])
8412                      (pc)
8413		      (RETURNS)))]
8414  "TARGET_ARM <return_cond_true>"
8415  "*
8416  {
8417    if (arm_ccfsm_state == 2)
8418      {
8419        arm_ccfsm_state += 2;
8420        return \"\";
8421      }
8422    return output_return_instruction (operands[0], true, true,
8423				      <return_simple_p>);
8424  }"
8425  [(set_attr "conds" "use")
8426   (set_attr "length" "12")
8427   (set_attr "type" "load_4")]
8428)
8429
8430(define_insn "*arm_simple_return"
8431  [(simple_return)]
8432  "TARGET_ARM"
8433  "*
8434  {
8435    if (arm_ccfsm_state == 2)
8436      {
8437        arm_ccfsm_state += 2;
8438        return \"\";
8439      }
8440    return output_return_instruction (const_true_rtx, true, false, true);
8441  }"
8442  [(set_attr "type" "branch")
8443   (set_attr "length" "4")
8444   (set_attr "predicable" "yes")]
8445)
8446
8447;; Generate a sequence of instructions to determine if the processor is
8448;; in 26-bit or 32-bit mode, and return the appropriate return address
8449;; mask.
8450
8451(define_expand "return_addr_mask"
8452  [(set (match_dup 1)
8453      (compare:CC_NOOV (unspec [(const_int 0)] UNSPEC_CHECK_ARCH)
8454		       (const_int 0)))
8455   (set (match_operand:SI 0 "s_register_operand" "")
8456      (if_then_else:SI (eq (match_dup 1) (const_int 0))
8457		       (const_int -1)
8458		       (const_int 67108860)))] ; 0x03fffffc
8459  "TARGET_ARM"
8460  "
8461  operands[1] = gen_rtx_REG (CC_NOOVmode, CC_REGNUM);
8462  ")
8463
8464(define_insn "*check_arch2"
8465  [(set (match_operand:CC_NOOV 0 "cc_register" "")
8466      (compare:CC_NOOV (unspec [(const_int 0)] UNSPEC_CHECK_ARCH)
8467		       (const_int 0)))]
8468  "TARGET_ARM"
8469  "teq\\t%|r0, %|r0\;teq\\t%|pc, %|pc"
8470  [(set_attr "length" "8")
8471   (set_attr "conds" "set")
8472   (set_attr "type" "multiple")]
8473)
8474
8475;; Call subroutine returning any type.
8476
8477(define_expand "untyped_call"
8478  [(parallel [(call (match_operand 0 "" "")
8479		    (const_int 0))
8480	      (match_operand 1 "" "")
8481	      (match_operand 2 "" "")])]
8482  "TARGET_EITHER"
8483  "
8484  {
8485    int i;
8486    rtx par = gen_rtx_PARALLEL (VOIDmode,
8487				rtvec_alloc (XVECLEN (operands[2], 0)));
8488    rtx addr = gen_reg_rtx (Pmode);
8489    rtx mem;
8490    int size = 0;
8491
8492    emit_move_insn (addr, XEXP (operands[1], 0));
8493    mem = change_address (operands[1], BLKmode, addr);
8494
8495    for (i = 0; i < XVECLEN (operands[2], 0); i++)
8496      {
8497	rtx src = SET_SRC (XVECEXP (operands[2], 0, i));
8498
8499	/* Default code only uses r0 as a return value, but we could
8500	   be using anything up to 4 registers.  */
8501	if (REGNO (src) == R0_REGNUM)
8502	  src = gen_rtx_REG (TImode, R0_REGNUM);
8503
8504        XVECEXP (par, 0, i) = gen_rtx_EXPR_LIST (VOIDmode, src,
8505						 GEN_INT (size));
8506        size += GET_MODE_SIZE (GET_MODE (src));
8507      }
8508
8509    emit_call_insn (gen_call_value (par, operands[0], const0_rtx, NULL));
8510
8511    size = 0;
8512
8513    for (i = 0; i < XVECLEN (par, 0); i++)
8514      {
8515	HOST_WIDE_INT offset = 0;
8516	rtx reg = XEXP (XVECEXP (par, 0, i), 0);
8517
8518	if (size != 0)
8519	  emit_move_insn (addr, plus_constant (Pmode, addr, size));
8520
8521	mem = change_address (mem, GET_MODE (reg), NULL);
8522	if (REGNO (reg) == R0_REGNUM)
8523	  {
8524	    /* On thumb we have to use a write-back instruction.  */
8525	    emit_insn (arm_gen_store_multiple (arm_regs_in_sequence, 4, addr,
8526 		       TARGET_THUMB ? TRUE : FALSE, mem, &offset));
8527	    size = TARGET_ARM ? 16 : 0;
8528	  }
8529	else
8530	  {
8531	    emit_move_insn (mem, reg);
8532	    size = GET_MODE_SIZE (GET_MODE (reg));
8533	  }
8534      }
8535
8536    /* The optimizer does not know that the call sets the function value
8537       registers we stored in the result block.  We avoid problems by
8538       claiming that all hard registers are used and clobbered at this
8539       point.  */
8540    emit_insn (gen_blockage ());
8541
8542    DONE;
8543  }"
8544)
8545
8546(define_expand "untyped_return"
8547  [(match_operand:BLK 0 "memory_operand" "")
8548   (match_operand 1 "" "")]
8549  "TARGET_EITHER"
8550  "
8551  {
8552    int i;
8553    rtx addr = gen_reg_rtx (Pmode);
8554    rtx mem;
8555    int size = 0;
8556
8557    emit_move_insn (addr, XEXP (operands[0], 0));
8558    mem = change_address (operands[0], BLKmode, addr);
8559
8560    for (i = 0; i < XVECLEN (operands[1], 0); i++)
8561      {
8562	HOST_WIDE_INT offset = 0;
8563	rtx reg = SET_DEST (XVECEXP (operands[1], 0, i));
8564
8565	if (size != 0)
8566	  emit_move_insn (addr, plus_constant (Pmode, addr, size));
8567
8568	mem = change_address (mem, GET_MODE (reg), NULL);
8569	if (REGNO (reg) == R0_REGNUM)
8570	  {
8571	    /* On thumb we have to use a write-back instruction.  */
8572	    emit_insn (arm_gen_load_multiple (arm_regs_in_sequence, 4, addr,
8573 		       TARGET_THUMB ? TRUE : FALSE, mem, &offset));
8574	    size = TARGET_ARM ? 16 : 0;
8575	  }
8576	else
8577	  {
8578	    emit_move_insn (reg, mem);
8579	    size = GET_MODE_SIZE (GET_MODE (reg));
8580	  }
8581      }
8582
8583    /* Emit USE insns before the return.  */
8584    for (i = 0; i < XVECLEN (operands[1], 0); i++)
8585      emit_use (SET_DEST (XVECEXP (operands[1], 0, i)));
8586
8587    /* Construct the return.  */
8588    expand_naked_return ();
8589
8590    DONE;
8591  }"
8592)
8593
8594;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
8595;; all of memory.  This blocks insns from being moved across this point.
8596
8597(define_insn "blockage"
8598  [(unspec_volatile [(const_int 0)] VUNSPEC_BLOCKAGE)]
8599  "TARGET_EITHER"
8600  ""
8601  [(set_attr "length" "0")
8602   (set_attr "type" "block")]
8603)
8604
8605;; Since we hard code r0 here use the 'o' constraint to prevent
8606;; provoking undefined behaviour in the hardware with putting out
8607;; auto-increment operations with potentially r0 as the base register.
8608(define_insn "probe_stack"
8609  [(set (match_operand:SI 0 "memory_operand" "=o")
8610        (unspec:SI [(const_int 0)] UNSPEC_PROBE_STACK))]
8611  "TARGET_32BIT"
8612  "str%?\\tr0, %0"
8613  [(set_attr "type" "store_4")
8614   (set_attr "predicable" "yes")]
8615)
8616
8617(define_insn "probe_stack_range"
8618  [(set (match_operand:SI 0 "register_operand" "=r")
8619	(unspec_volatile:SI [(match_operand:SI 1 "register_operand" "0")
8620			     (match_operand:SI 2 "register_operand" "r")]
8621			     VUNSPEC_PROBE_STACK_RANGE))]
8622  "TARGET_32BIT"
8623{
8624  return output_probe_stack_range (operands[0], operands[2]);
8625}
8626  [(set_attr "type" "multiple")
8627   (set_attr "conds" "clob")]
8628)
8629
8630(define_expand "casesi"
8631  [(match_operand:SI 0 "s_register_operand" "")	; index to jump on
8632   (match_operand:SI 1 "const_int_operand" "")	; lower bound
8633   (match_operand:SI 2 "const_int_operand" "")	; total range
8634   (match_operand:SI 3 "" "")			; table label
8635   (match_operand:SI 4 "" "")]			; Out of range label
8636  "(TARGET_32BIT || optimize_size || flag_pic) && !target_pure_code"
8637  "
8638  {
8639    enum insn_code code;
8640    if (operands[1] != const0_rtx)
8641      {
8642	rtx reg = gen_reg_rtx (SImode);
8643
8644	emit_insn (gen_addsi3 (reg, operands[0],
8645			       gen_int_mode (-INTVAL (operands[1]),
8646			       		     SImode)));
8647	operands[0] = reg;
8648      }
8649
8650    if (TARGET_ARM)
8651      code = CODE_FOR_arm_casesi_internal;
8652    else if (TARGET_THUMB1)
8653      code = CODE_FOR_thumb1_casesi_internal_pic;
8654    else if (flag_pic)
8655      code = CODE_FOR_thumb2_casesi_internal_pic;
8656    else
8657      code = CODE_FOR_thumb2_casesi_internal;
8658
8659    if (!insn_data[(int) code].operand[1].predicate(operands[2], SImode))
8660      operands[2] = force_reg (SImode, operands[2]);
8661
8662    emit_jump_insn (GEN_FCN ((int) code) (operands[0], operands[2],
8663					  operands[3], operands[4]));
8664    DONE;
8665  }"
8666)
8667
8668;; The USE in this pattern is needed to tell flow analysis that this is
8669;; a CASESI insn.  It has no other purpose.
8670(define_insn "arm_casesi_internal"
8671  [(parallel [(set (pc)
8672	       (if_then_else
8673		(leu (match_operand:SI 0 "s_register_operand" "r")
8674		     (match_operand:SI 1 "arm_rhs_operand" "rI"))
8675		(mem:SI (plus:SI (mult:SI (match_dup 0) (const_int 4))
8676				 (label_ref (match_operand 2 "" ""))))
8677		(label_ref (match_operand 3 "" ""))))
8678	      (clobber (reg:CC CC_REGNUM))
8679	      (use (label_ref (match_dup 2)))])]
8680  "TARGET_ARM"
8681  "*
8682    if (flag_pic)
8683      return \"cmp\\t%0, %1\;addls\\t%|pc, %|pc, %0, asl #2\;b\\t%l3\";
8684    return   \"cmp\\t%0, %1\;ldrls\\t%|pc, [%|pc, %0, asl #2]\;b\\t%l3\";
8685  "
8686  [(set_attr "conds" "clob")
8687   (set_attr "length" "12")
8688   (set_attr "type" "multiple")]
8689)
8690
8691(define_expand "indirect_jump"
8692  [(set (pc)
8693	(match_operand:SI 0 "s_register_operand" ""))]
8694  "TARGET_EITHER"
8695  "
8696  /* Thumb-2 doesn't have mov pc, reg.  Explicitly set the low bit of the
8697     address and use bx.  */
8698  if (TARGET_THUMB2)
8699    {
8700      rtx tmp;
8701      tmp = gen_reg_rtx (SImode);
8702      emit_insn (gen_iorsi3 (tmp, operands[0], GEN_INT(1)));
8703      operands[0] = tmp;
8704    }
8705  "
8706)
8707
8708;; NB Never uses BX.
8709(define_insn "*arm_indirect_jump"
8710  [(set (pc)
8711	(match_operand:SI 0 "s_register_operand" "r"))]
8712  "TARGET_ARM"
8713  "mov%?\\t%|pc, %0\\t%@ indirect register jump"
8714  [(set_attr "predicable" "yes")
8715   (set_attr "type" "branch")]
8716)
8717
8718(define_insn "*load_indirect_jump"
8719  [(set (pc)
8720	(match_operand:SI 0 "memory_operand" "m"))]
8721  "TARGET_ARM"
8722  "ldr%?\\t%|pc, %0\\t%@ indirect memory jump"
8723  [(set_attr "type" "load_4")
8724   (set_attr "pool_range" "4096")
8725   (set_attr "neg_pool_range" "4084")
8726   (set_attr "predicable" "yes")]
8727)
8728
8729
8730;; Misc insns
8731
8732(define_insn "nop"
8733  [(const_int 0)]
8734  "TARGET_EITHER"
8735  "nop"
8736  [(set (attr "length")
8737	(if_then_else (eq_attr "is_thumb" "yes")
8738		      (const_int 2)
8739		      (const_int 4)))
8740   (set_attr "type" "mov_reg")]
8741)
8742
8743(define_insn "trap"
8744  [(trap_if (const_int 1) (const_int 0))]
8745  ""
8746  "*
8747  if (TARGET_ARM)
8748    return \".inst\\t0xe7f000f0\";
8749  else
8750    return \".inst\\t0xdeff\";
8751  "
8752  [(set (attr "length")
8753	(if_then_else (eq_attr "is_thumb" "yes")
8754		      (const_int 2)
8755		      (const_int 4)))
8756   (set_attr "type" "trap")
8757   (set_attr "conds" "unconditional")]
8758)
8759
8760
8761;; Patterns to allow combination of arithmetic, cond code and shifts
8762
8763(define_insn "*<arith_shift_insn>_multsi"
8764  [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8765	(SHIFTABLE_OPS:SI
8766	 (mult:SI (match_operand:SI 2 "s_register_operand" "r,r")
8767		  (match_operand:SI 3 "power_of_two_operand" ""))
8768	 (match_operand:SI 1 "s_register_operand" "rk,<t2_binop0>")))]
8769  "TARGET_32BIT"
8770  "<arith_shift_insn>%?\\t%0, %1, %2, lsl %b3"
8771  [(set_attr "predicable" "yes")
8772   (set_attr "shift" "2")
8773   (set_attr "arch" "a,t2")
8774   (set_attr "type" "alu_shift_imm")])
8775
8776(define_insn "*<arith_shift_insn>_shiftsi"
8777  [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
8778	(SHIFTABLE_OPS:SI
8779	 (match_operator:SI 2 "shift_nomul_operator"
8780	  [(match_operand:SI 3 "s_register_operand" "r,r,r")
8781	   (match_operand:SI 4 "shift_amount_operand" "M,M,r")])
8782	 (match_operand:SI 1 "s_register_operand" "rk,<t2_binop0>,rk")))]
8783  "TARGET_32BIT && GET_CODE (operands[2]) != MULT"
8784  "<arith_shift_insn>%?\\t%0, %1, %3%S2"
8785  [(set_attr "predicable" "yes")
8786   (set_attr "shift" "3")
8787   (set_attr "arch" "a,t2,a")
8788   (set_attr "type" "alu_shift_imm,alu_shift_imm,alu_shift_reg")])
8789
8790(define_split
8791  [(set (match_operand:SI 0 "s_register_operand" "")
8792	(match_operator:SI 1 "shiftable_operator"
8793	 [(match_operator:SI 2 "shiftable_operator"
8794	   [(match_operator:SI 3 "shift_operator"
8795	     [(match_operand:SI 4 "s_register_operand" "")
8796	      (match_operand:SI 5 "reg_or_int_operand" "")])
8797	    (match_operand:SI 6 "s_register_operand" "")])
8798	  (match_operand:SI 7 "arm_rhs_operand" "")]))
8799   (clobber (match_operand:SI 8 "s_register_operand" ""))]
8800  "TARGET_32BIT"
8801  [(set (match_dup 8)
8802	(match_op_dup 2 [(match_op_dup 3 [(match_dup 4) (match_dup 5)])
8803			 (match_dup 6)]))
8804   (set (match_dup 0)
8805	(match_op_dup 1 [(match_dup 8) (match_dup 7)]))]
8806  "")
8807
8808(define_insn "*arith_shiftsi_compare0"
8809  [(set (reg:CC_NOOV CC_REGNUM)
8810        (compare:CC_NOOV
8811	 (match_operator:SI 1 "shiftable_operator"
8812	  [(match_operator:SI 3 "shift_operator"
8813	    [(match_operand:SI 4 "s_register_operand" "r,r")
8814	     (match_operand:SI 5 "shift_amount_operand" "M,r")])
8815	   (match_operand:SI 2 "s_register_operand" "r,r")])
8816	 (const_int 0)))
8817   (set (match_operand:SI 0 "s_register_operand" "=r,r")
8818	(match_op_dup 1 [(match_op_dup 3 [(match_dup 4) (match_dup 5)])
8819			 (match_dup 2)]))]
8820  "TARGET_32BIT"
8821  "%i1s%?\\t%0, %2, %4%S3"
8822  [(set_attr "conds" "set")
8823   (set_attr "shift" "4")
8824   (set_attr "arch" "32,a")
8825   (set_attr "type" "alus_shift_imm,alus_shift_reg")])
8826
8827(define_insn "*arith_shiftsi_compare0_scratch"
8828  [(set (reg:CC_NOOV CC_REGNUM)
8829        (compare:CC_NOOV
8830	 (match_operator:SI 1 "shiftable_operator"
8831	  [(match_operator:SI 3 "shift_operator"
8832	    [(match_operand:SI 4 "s_register_operand" "r,r")
8833	     (match_operand:SI 5 "shift_amount_operand" "M,r")])
8834	   (match_operand:SI 2 "s_register_operand" "r,r")])
8835	 (const_int 0)))
8836   (clobber (match_scratch:SI 0 "=r,r"))]
8837  "TARGET_32BIT"
8838  "%i1s%?\\t%0, %2, %4%S3"
8839  [(set_attr "conds" "set")
8840   (set_attr "shift" "4")
8841   (set_attr "arch" "32,a")
8842   (set_attr "type" "alus_shift_imm,alus_shift_reg")])
8843
8844(define_insn "*sub_shiftsi"
8845  [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8846	(minus:SI (match_operand:SI 1 "s_register_operand" "r,r")
8847		  (match_operator:SI 2 "shift_operator"
8848		   [(match_operand:SI 3 "s_register_operand" "r,r")
8849		    (match_operand:SI 4 "shift_amount_operand" "M,r")])))]
8850  "TARGET_32BIT"
8851  "sub%?\\t%0, %1, %3%S2"
8852  [(set_attr "predicable" "yes")
8853   (set_attr "predicable_short_it" "no")
8854   (set_attr "shift" "3")
8855   (set_attr "arch" "32,a")
8856   (set_attr "type" "alus_shift_imm,alus_shift_reg")])
8857
8858(define_insn "*sub_shiftsi_compare0"
8859  [(set (reg:CC_NOOV CC_REGNUM)
8860	(compare:CC_NOOV
8861	 (minus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
8862		   (match_operator:SI 2 "shift_operator"
8863		    [(match_operand:SI 3 "s_register_operand" "r,r,r")
8864		     (match_operand:SI 4 "shift_amount_operand" "M,r,M")]))
8865	 (const_int 0)))
8866   (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
8867	(minus:SI (match_dup 1)
8868		  (match_op_dup 2 [(match_dup 3) (match_dup 4)])))]
8869  "TARGET_32BIT"
8870  "subs%?\\t%0, %1, %3%S2"
8871  [(set_attr "conds" "set")
8872   (set_attr "shift" "3")
8873   (set_attr "arch" "32,a,a")
8874   (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
8875
8876(define_insn "*sub_shiftsi_compare0_scratch"
8877  [(set (reg:CC_NOOV CC_REGNUM)
8878	(compare:CC_NOOV
8879	 (minus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
8880		   (match_operator:SI 2 "shift_operator"
8881		    [(match_operand:SI 3 "s_register_operand" "r,r,r")
8882		     (match_operand:SI 4 "shift_amount_operand" "M,r,M")]))
8883	 (const_int 0)))
8884   (clobber (match_scratch:SI 0 "=r,r,r"))]
8885  "TARGET_32BIT"
8886  "subs%?\\t%0, %1, %3%S2"
8887  [(set_attr "conds" "set")
8888   (set_attr "shift" "3")
8889   (set_attr "arch" "32,a,a")
8890   (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
8891
8892
8893(define_insn_and_split "*and_scc"
8894  [(set (match_operand:SI 0 "s_register_operand" "=r")
8895	(and:SI (match_operator:SI 1 "arm_comparison_operator"
8896		 [(match_operand 2 "cc_register" "") (const_int 0)])
8897		(match_operand:SI 3 "s_register_operand" "r")))]
8898  "TARGET_ARM"
8899  "#"   ; "mov%D1\\t%0, #0\;and%d1\\t%0, %3, #1"
8900  "&& reload_completed"
8901  [(cond_exec (match_dup 5) (set (match_dup 0) (const_int 0)))
8902   (cond_exec (match_dup 4) (set (match_dup 0)
8903                                 (and:SI (match_dup 3) (const_int 1))))]
8904  {
8905    machine_mode mode = GET_MODE (operands[2]);
8906    enum rtx_code rc = GET_CODE (operands[1]);
8907
8908    /* Note that operands[4] is the same as operands[1],
8909       but with VOIDmode as the result. */
8910    operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
8911    if (mode == CCFPmode || mode == CCFPEmode)
8912      rc = reverse_condition_maybe_unordered (rc);
8913    else
8914      rc = reverse_condition (rc);
8915    operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
8916  }
8917  [(set_attr "conds" "use")
8918   (set_attr "type" "multiple")
8919   (set_attr "length" "8")]
8920)
8921
8922(define_insn_and_split "*ior_scc"
8923  [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8924	(ior:SI (match_operator:SI 1 "arm_comparison_operator"
8925		 [(match_operand 2 "cc_register" "") (const_int 0)])
8926		(match_operand:SI 3 "s_register_operand" "0,?r")))]
8927  "TARGET_ARM"
8928  "@
8929   orr%d1\\t%0, %3, #1
8930   #"
8931  "&& reload_completed
8932   && REGNO (operands [0]) != REGNO (operands[3])"
8933  ;; && which_alternative == 1
8934  ; mov%D1\\t%0, %3\;orr%d1\\t%0, %3, #1
8935  [(cond_exec (match_dup 5) (set (match_dup 0) (match_dup 3)))
8936   (cond_exec (match_dup 4) (set (match_dup 0)
8937                                 (ior:SI (match_dup 3) (const_int 1))))]
8938  {
8939    machine_mode mode = GET_MODE (operands[2]);
8940    enum rtx_code rc = GET_CODE (operands[1]);
8941
8942    /* Note that operands[4] is the same as operands[1],
8943       but with VOIDmode as the result. */
8944    operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
8945    if (mode == CCFPmode || mode == CCFPEmode)
8946      rc = reverse_condition_maybe_unordered (rc);
8947    else
8948      rc = reverse_condition (rc);
8949    operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
8950  }
8951  [(set_attr "conds" "use")
8952   (set_attr "length" "4,8")
8953   (set_attr "type" "logic_imm,multiple")]
8954)
8955
8956; A series of splitters for the compare_scc pattern below.  Note that
8957; order is important.
8958(define_split
8959  [(set (match_operand:SI 0 "s_register_operand" "")
8960	(lt:SI (match_operand:SI 1 "s_register_operand" "")
8961	       (const_int 0)))
8962   (clobber (reg:CC CC_REGNUM))]
8963  "TARGET_32BIT && reload_completed"
8964  [(set (match_dup 0) (lshiftrt:SI (match_dup 1) (const_int 31)))])
8965
8966(define_split
8967  [(set (match_operand:SI 0 "s_register_operand" "")
8968	(ge:SI (match_operand:SI 1 "s_register_operand" "")
8969	       (const_int 0)))
8970   (clobber (reg:CC CC_REGNUM))]
8971  "TARGET_32BIT && reload_completed"
8972  [(set (match_dup 0) (not:SI (match_dup 1)))
8973   (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 31)))])
8974
8975(define_split
8976  [(set (match_operand:SI 0 "s_register_operand" "")
8977	(eq:SI (match_operand:SI 1 "s_register_operand" "")
8978	       (const_int 0)))
8979   (clobber (reg:CC CC_REGNUM))]
8980  "arm_arch5 && TARGET_32BIT"
8981  [(set (match_dup 0) (clz:SI (match_dup 1)))
8982   (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
8983)
8984
8985(define_split
8986  [(set (match_operand:SI 0 "s_register_operand" "")
8987	(eq:SI (match_operand:SI 1 "s_register_operand" "")
8988	       (const_int 0)))
8989   (clobber (reg:CC CC_REGNUM))]
8990  "TARGET_32BIT && reload_completed"
8991  [(parallel
8992    [(set (reg:CC CC_REGNUM)
8993	  (compare:CC (const_int 1) (match_dup 1)))
8994     (set (match_dup 0)
8995	  (minus:SI (const_int 1) (match_dup 1)))])
8996   (cond_exec (ltu:CC (reg:CC CC_REGNUM) (const_int 0))
8997	      (set (match_dup 0) (const_int 0)))])
8998
8999(define_split
9000  [(set (match_operand:SI 0 "s_register_operand" "")
9001	(ne:SI (match_operand:SI 1 "s_register_operand" "")
9002	       (match_operand:SI 2 "const_int_operand" "")))
9003   (clobber (reg:CC CC_REGNUM))]
9004  "TARGET_32BIT && reload_completed"
9005  [(parallel
9006    [(set (reg:CC CC_REGNUM)
9007	  (compare:CC (match_dup 1) (match_dup 2)))
9008     (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 3)))])
9009   (cond_exec (ne:CC (reg:CC CC_REGNUM) (const_int 0))
9010	      (set (match_dup 0) (const_int 1)))]
9011{
9012  operands[3] = GEN_INT (-INTVAL (operands[2]));
9013})
9014
9015(define_split
9016  [(set (match_operand:SI 0 "s_register_operand" "")
9017	(ne:SI (match_operand:SI 1 "s_register_operand" "")
9018	       (match_operand:SI 2 "arm_add_operand" "")))
9019   (clobber (reg:CC CC_REGNUM))]
9020  "TARGET_32BIT && reload_completed"
9021  [(parallel
9022    [(set (reg:CC_NOOV CC_REGNUM)
9023	  (compare:CC_NOOV (minus:SI (match_dup 1) (match_dup 2))
9024			   (const_int 0)))
9025     (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
9026   (cond_exec (ne:CC_NOOV (reg:CC_NOOV CC_REGNUM) (const_int 0))
9027	      (set (match_dup 0) (const_int 1)))])
9028
9029(define_insn_and_split "*compare_scc"
9030  [(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts")
9031	(match_operator:SI 1 "arm_comparison_operator"
9032	 [(match_operand:SI 2 "s_register_operand" "r,r")
9033	  (match_operand:SI 3 "arm_add_operand" "rI,L")]))
9034   (clobber (reg:CC CC_REGNUM))]
9035  "TARGET_32BIT"
9036  "#"
9037  "&& reload_completed"
9038  [(set (reg:CC CC_REGNUM) (compare:CC (match_dup 2) (match_dup 3)))
9039   (cond_exec (match_dup 4) (set (match_dup 0) (const_int 0)))
9040   (cond_exec (match_dup 5) (set (match_dup 0) (const_int 1)))]
9041{
9042  rtx tmp1;
9043  machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
9044					   operands[2], operands[3]);
9045  enum rtx_code rc = GET_CODE (operands[1]);
9046
9047  tmp1 = gen_rtx_REG (mode, CC_REGNUM);
9048
9049  operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, tmp1, const0_rtx);
9050  if (mode == CCFPmode || mode == CCFPEmode)
9051    rc = reverse_condition_maybe_unordered (rc);
9052  else
9053    rc = reverse_condition (rc);
9054  operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, tmp1, const0_rtx);
9055}
9056  [(set_attr "type" "multiple")]
9057)
9058
9059;; Attempt to improve the sequence generated by the compare_scc splitters
9060;; not to use conditional execution.
9061
9062;; Rd = (eq (reg1) (const_int0))  // ARMv5
9063;;	clz Rd, reg1
9064;;	lsr Rd, Rd, #5
9065(define_peephole2
9066  [(set (reg:CC CC_REGNUM)
9067	(compare:CC (match_operand:SI 1 "register_operand" "")
9068		    (const_int 0)))
9069   (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
9070	      (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
9071   (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
9072	      (set (match_dup 0) (const_int 1)))]
9073  "arm_arch5 && TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
9074  [(set (match_dup 0) (clz:SI (match_dup 1)))
9075   (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
9076)
9077
9078;; Rd = (eq (reg1) (const_int0))  // !ARMv5
9079;;	negs Rd, reg1
9080;;	adc  Rd, Rd, reg1
9081(define_peephole2
9082  [(set (reg:CC CC_REGNUM)
9083	(compare:CC (match_operand:SI 1 "register_operand" "")
9084		    (const_int 0)))
9085   (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
9086	      (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
9087   (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
9088	      (set (match_dup 0) (const_int 1)))
9089   (match_scratch:SI 2 "r")]
9090  "TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
9091  [(parallel
9092    [(set (reg:CC CC_REGNUM)
9093	  (compare:CC (const_int 0) (match_dup 1)))
9094     (set (match_dup 2) (minus:SI (const_int 0) (match_dup 1)))])
9095   (set (match_dup 0)
9096	(plus:SI (plus:SI (match_dup 1) (match_dup 2))
9097		 (geu:SI (reg:CC CC_REGNUM) (const_int 0))))]
9098)
9099
9100;; Rd = (eq (reg1) (reg2/imm))	// ARMv5 and optimising for speed.
9101;;	sub  Rd, Reg1, reg2
9102;;	clz  Rd, Rd
9103;;	lsr  Rd, Rd, #5
9104(define_peephole2
9105  [(set (reg:CC CC_REGNUM)
9106	(compare:CC (match_operand:SI 1 "register_operand" "")
9107		    (match_operand:SI 2 "arm_rhs_operand" "")))
9108   (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
9109	      (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
9110   (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
9111	      (set (match_dup 0) (const_int 1)))]
9112  "arm_arch5 && TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)
9113  && !(TARGET_THUMB2 && optimize_insn_for_size_p ())"
9114  [(set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))
9115   (set (match_dup 0) (clz:SI (match_dup 0)))
9116   (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
9117)
9118
9119
9120;; Rd = (eq (reg1) (reg2))	// ! ARMv5 or optimising for size.
9121;;	sub  T1, Reg1, reg2
9122;;	negs Rd, T1
9123;;	adc  Rd, Rd, T1
9124(define_peephole2
9125  [(set (reg:CC CC_REGNUM)
9126	(compare:CC (match_operand:SI 1 "register_operand" "")
9127		    (match_operand:SI 2 "arm_rhs_operand" "")))
9128   (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
9129	      (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
9130   (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
9131	      (set (match_dup 0) (const_int 1)))
9132   (match_scratch:SI 3 "r")]
9133  "TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
9134  [(set (match_dup 3) (match_dup 4))
9135   (parallel
9136    [(set (reg:CC CC_REGNUM)
9137	  (compare:CC (const_int 0) (match_dup 3)))
9138     (set (match_dup 0) (minus:SI (const_int 0) (match_dup 3)))])
9139   (set (match_dup 0)
9140	(plus:SI (plus:SI (match_dup 0) (match_dup 3))
9141		 (geu:SI (reg:CC CC_REGNUM) (const_int 0))))]
9142  "
9143  if (CONST_INT_P (operands[2]))
9144    operands[4] = plus_constant (SImode, operands[1], -INTVAL (operands[2]));
9145  else
9146    operands[4] = gen_rtx_MINUS (SImode, operands[1], operands[2]);
9147  ")
9148
9149(define_insn "*cond_move"
9150  [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9151	(if_then_else:SI (match_operator 3 "equality_operator"
9152			  [(match_operator 4 "arm_comparison_operator"
9153			    [(match_operand 5 "cc_register" "") (const_int 0)])
9154			   (const_int 0)])
9155			 (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
9156			 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))]
9157  "TARGET_ARM"
9158  "*
9159    if (GET_CODE (operands[3]) == NE)
9160      {
9161        if (which_alternative != 1)
9162	  output_asm_insn (\"mov%D4\\t%0, %2\", operands);
9163        if (which_alternative != 0)
9164	  output_asm_insn (\"mov%d4\\t%0, %1\", operands);
9165        return \"\";
9166      }
9167    if (which_alternative != 0)
9168      output_asm_insn (\"mov%D4\\t%0, %1\", operands);
9169    if (which_alternative != 1)
9170      output_asm_insn (\"mov%d4\\t%0, %2\", operands);
9171    return \"\";
9172  "
9173  [(set_attr "conds" "use")
9174   (set_attr_alternative "type"
9175                         [(if_then_else (match_operand 2 "const_int_operand" "")
9176                                        (const_string "mov_imm")
9177                                        (const_string "mov_reg"))
9178                          (if_then_else (match_operand 1 "const_int_operand" "")
9179                                        (const_string "mov_imm")
9180                                        (const_string "mov_reg"))
9181                          (const_string "multiple")])
9182   (set_attr "length" "4,4,8")]
9183)
9184
9185(define_insn "*cond_arith"
9186  [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9187        (match_operator:SI 5 "shiftable_operator"
9188	 [(match_operator:SI 4 "arm_comparison_operator"
9189           [(match_operand:SI 2 "s_register_operand" "r,r")
9190	    (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
9191          (match_operand:SI 1 "s_register_operand" "0,?r")]))
9192   (clobber (reg:CC CC_REGNUM))]
9193  "TARGET_ARM"
9194  "*
9195    if (GET_CODE (operands[4]) == LT && operands[3] == const0_rtx)
9196      return \"%i5\\t%0, %1, %2, lsr #31\";
9197
9198    output_asm_insn (\"cmp\\t%2, %3\", operands);
9199    if (GET_CODE (operands[5]) == AND)
9200      output_asm_insn (\"mov%D4\\t%0, #0\", operands);
9201    else if (GET_CODE (operands[5]) == MINUS)
9202      output_asm_insn (\"rsb%D4\\t%0, %1, #0\", operands);
9203    else if (which_alternative != 0)
9204      output_asm_insn (\"mov%D4\\t%0, %1\", operands);
9205    return \"%i5%d4\\t%0, %1, #1\";
9206  "
9207  [(set_attr "conds" "clob")
9208   (set_attr "length" "12")
9209   (set_attr "type" "multiple")]
9210)
9211
9212(define_insn "*cond_sub"
9213  [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9214        (minus:SI (match_operand:SI 1 "s_register_operand" "0,?r")
9215		  (match_operator:SI 4 "arm_comparison_operator"
9216                   [(match_operand:SI 2 "s_register_operand" "r,r")
9217		    (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
9218   (clobber (reg:CC CC_REGNUM))]
9219  "TARGET_ARM"
9220  "*
9221    output_asm_insn (\"cmp\\t%2, %3\", operands);
9222    if (which_alternative != 0)
9223      output_asm_insn (\"mov%D4\\t%0, %1\", operands);
9224    return \"sub%d4\\t%0, %1, #1\";
9225  "
9226  [(set_attr "conds" "clob")
9227   (set_attr "length" "8,12")
9228   (set_attr "type" "multiple")]
9229)
9230
9231(define_insn "*cmp_ite0"
9232  [(set (match_operand 6 "dominant_cc_register" "")
9233	(compare
9234	 (if_then_else:SI
9235	  (match_operator 4 "arm_comparison_operator"
9236	   [(match_operand:SI 0 "s_register_operand"
9237	        "l,l,l,r,r,r,r,r,r")
9238	    (match_operand:SI 1 "arm_add_operand"
9239	        "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
9240	  (match_operator:SI 5 "arm_comparison_operator"
9241	   [(match_operand:SI 2 "s_register_operand"
9242	        "l,r,r,l,l,r,r,r,r")
9243	    (match_operand:SI 3 "arm_add_operand"
9244	        "lPy,rI,L,lPy,lPy,rI,rI,L,L")])
9245	  (const_int 0))
9246	 (const_int 0)))]
9247  "TARGET_32BIT"
9248  "*
9249  {
9250    static const char * const cmp1[NUM_OF_COND_CMP][2] =
9251    {
9252      {\"cmp%d5\\t%0, %1\",
9253       \"cmp%d4\\t%2, %3\"},
9254      {\"cmn%d5\\t%0, #%n1\",
9255       \"cmp%d4\\t%2, %3\"},
9256      {\"cmp%d5\\t%0, %1\",
9257       \"cmn%d4\\t%2, #%n3\"},
9258      {\"cmn%d5\\t%0, #%n1\",
9259       \"cmn%d4\\t%2, #%n3\"}
9260    };
9261    static const char * const cmp2[NUM_OF_COND_CMP][2] =
9262    {
9263      {\"cmp\\t%2, %3\",
9264       \"cmp\\t%0, %1\"},
9265      {\"cmp\\t%2, %3\",
9266       \"cmn\\t%0, #%n1\"},
9267      {\"cmn\\t%2, #%n3\",
9268       \"cmp\\t%0, %1\"},
9269      {\"cmn\\t%2, #%n3\",
9270       \"cmn\\t%0, #%n1\"}
9271    };
9272    static const char * const ite[2] =
9273    {
9274      \"it\\t%d5\",
9275      \"it\\t%d4\"
9276    };
9277    static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
9278                                   CMP_CMP, CMN_CMP, CMP_CMP,
9279                                   CMN_CMP, CMP_CMN, CMN_CMN};
9280    int swap =
9281      comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
9282
9283    output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
9284    if (TARGET_THUMB2) {
9285      output_asm_insn (ite[swap], operands);
9286    }
9287    output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
9288    return \"\";
9289  }"
9290  [(set_attr "conds" "set")
9291   (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
9292   (set_attr "enabled_for_short_it" "yes,no,no,no,no,no,no,no,no")
9293   (set_attr "type" "multiple")
9294   (set_attr_alternative "length"
9295      [(const_int 6)
9296       (const_int 8)
9297       (const_int 8)
9298       (const_int 8)
9299       (const_int 8)
9300       (if_then_else (eq_attr "is_thumb" "no")
9301           (const_int 8)
9302           (const_int 10))
9303       (if_then_else (eq_attr "is_thumb" "no")
9304           (const_int 8)
9305           (const_int 10))
9306       (if_then_else (eq_attr "is_thumb" "no")
9307           (const_int 8)
9308           (const_int 10))
9309       (if_then_else (eq_attr "is_thumb" "no")
9310           (const_int 8)
9311           (const_int 10))])]
9312)
9313
9314(define_insn "*cmp_ite1"
9315  [(set (match_operand 6 "dominant_cc_register" "")
9316	(compare
9317	 (if_then_else:SI
9318	  (match_operator 4 "arm_comparison_operator"
9319	   [(match_operand:SI 0 "s_register_operand"
9320	        "l,l,l,r,r,r,r,r,r")
9321	    (match_operand:SI 1 "arm_add_operand"
9322	        "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
9323	  (match_operator:SI 5 "arm_comparison_operator"
9324	   [(match_operand:SI 2 "s_register_operand"
9325	        "l,r,r,l,l,r,r,r,r")
9326	    (match_operand:SI 3 "arm_add_operand"
9327	        "lPy,rI,L,lPy,lPy,rI,rI,L,L")])
9328	  (const_int 1))
9329	 (const_int 0)))]
9330  "TARGET_32BIT"
9331  "*
9332  {
9333    static const char * const cmp1[NUM_OF_COND_CMP][2] =
9334    {
9335      {\"cmp\\t%0, %1\",
9336       \"cmp\\t%2, %3\"},
9337      {\"cmn\\t%0, #%n1\",
9338       \"cmp\\t%2, %3\"},
9339      {\"cmp\\t%0, %1\",
9340       \"cmn\\t%2, #%n3\"},
9341      {\"cmn\\t%0, #%n1\",
9342       \"cmn\\t%2, #%n3\"}
9343    };
9344    static const char * const cmp2[NUM_OF_COND_CMP][2] =
9345    {
9346      {\"cmp%d4\\t%2, %3\",
9347       \"cmp%D5\\t%0, %1\"},
9348      {\"cmp%d4\\t%2, %3\",
9349       \"cmn%D5\\t%0, #%n1\"},
9350      {\"cmn%d4\\t%2, #%n3\",
9351       \"cmp%D5\\t%0, %1\"},
9352      {\"cmn%d4\\t%2, #%n3\",
9353       \"cmn%D5\\t%0, #%n1\"}
9354    };
9355    static const char * const ite[2] =
9356    {
9357      \"it\\t%d4\",
9358      \"it\\t%D5\"
9359    };
9360    static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
9361                                   CMP_CMP, CMN_CMP, CMP_CMP,
9362                                   CMN_CMP, CMP_CMN, CMN_CMN};
9363    int swap =
9364      comparison_dominates_p (GET_CODE (operands[5]),
9365			      reverse_condition (GET_CODE (operands[4])));
9366
9367    output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
9368    if (TARGET_THUMB2) {
9369      output_asm_insn (ite[swap], operands);
9370    }
9371    output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
9372    return \"\";
9373  }"
9374  [(set_attr "conds" "set")
9375   (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
9376   (set_attr "enabled_for_short_it" "yes,no,no,no,no,no,no,no,no")
9377   (set_attr_alternative "length"
9378      [(const_int 6)
9379       (const_int 8)
9380       (const_int 8)
9381       (const_int 8)
9382       (const_int 8)
9383       (if_then_else (eq_attr "is_thumb" "no")
9384           (const_int 8)
9385           (const_int 10))
9386       (if_then_else (eq_attr "is_thumb" "no")
9387           (const_int 8)
9388           (const_int 10))
9389       (if_then_else (eq_attr "is_thumb" "no")
9390           (const_int 8)
9391           (const_int 10))
9392       (if_then_else (eq_attr "is_thumb" "no")
9393           (const_int 8)
9394           (const_int 10))])
9395   (set_attr "type" "multiple")]
9396)
9397
9398(define_insn "*cmp_and"
9399  [(set (match_operand 6 "dominant_cc_register" "")
9400	(compare
9401	 (and:SI
9402	  (match_operator 4 "arm_comparison_operator"
9403	   [(match_operand:SI 0 "s_register_operand"
9404	        "l,l,l,r,r,r,r,r,r")
9405	    (match_operand:SI 1 "arm_add_operand"
9406	        "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
9407	  (match_operator:SI 5 "arm_comparison_operator"
9408	   [(match_operand:SI 2 "s_register_operand"
9409	        "l,r,r,l,l,r,r,r,r")
9410	    (match_operand:SI 3 "arm_add_operand"
9411	        "lPy,rI,L,lPy,lPy,rI,rI,L,L")]))
9412	 (const_int 0)))]
9413  "TARGET_32BIT"
9414  "*
9415  {
9416    static const char *const cmp1[NUM_OF_COND_CMP][2] =
9417    {
9418      {\"cmp%d5\\t%0, %1\",
9419       \"cmp%d4\\t%2, %3\"},
9420      {\"cmn%d5\\t%0, #%n1\",
9421       \"cmp%d4\\t%2, %3\"},
9422      {\"cmp%d5\\t%0, %1\",
9423       \"cmn%d4\\t%2, #%n3\"},
9424      {\"cmn%d5\\t%0, #%n1\",
9425       \"cmn%d4\\t%2, #%n3\"}
9426    };
9427    static const char *const cmp2[NUM_OF_COND_CMP][2] =
9428    {
9429      {\"cmp\\t%2, %3\",
9430       \"cmp\\t%0, %1\"},
9431      {\"cmp\\t%2, %3\",
9432       \"cmn\\t%0, #%n1\"},
9433      {\"cmn\\t%2, #%n3\",
9434       \"cmp\\t%0, %1\"},
9435      {\"cmn\\t%2, #%n3\",
9436       \"cmn\\t%0, #%n1\"}
9437    };
9438    static const char *const ite[2] =
9439    {
9440      \"it\\t%d5\",
9441      \"it\\t%d4\"
9442    };
9443    static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
9444                                   CMP_CMP, CMN_CMP, CMP_CMP,
9445                                   CMN_CMP, CMP_CMN, CMN_CMN};
9446    int swap =
9447      comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
9448
9449    output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
9450    if (TARGET_THUMB2) {
9451      output_asm_insn (ite[swap], operands);
9452    }
9453    output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
9454    return \"\";
9455  }"
9456  [(set_attr "conds" "set")
9457   (set_attr "predicable" "no")
9458   (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
9459   (set_attr "enabled_for_short_it" "yes,no,no,no,no,no,no,no,no")
9460   (set_attr_alternative "length"
9461      [(const_int 6)
9462       (const_int 8)
9463       (const_int 8)
9464       (const_int 8)
9465       (const_int 8)
9466       (if_then_else (eq_attr "is_thumb" "no")
9467           (const_int 8)
9468           (const_int 10))
9469       (if_then_else (eq_attr "is_thumb" "no")
9470           (const_int 8)
9471           (const_int 10))
9472       (if_then_else (eq_attr "is_thumb" "no")
9473           (const_int 8)
9474           (const_int 10))
9475       (if_then_else (eq_attr "is_thumb" "no")
9476           (const_int 8)
9477           (const_int 10))])
9478   (set_attr "type" "multiple")]
9479)
9480
9481(define_insn "*cmp_ior"
9482  [(set (match_operand 6 "dominant_cc_register" "")
9483	(compare
9484	 (ior:SI
9485	  (match_operator 4 "arm_comparison_operator"
9486	   [(match_operand:SI 0 "s_register_operand"
9487	        "l,l,l,r,r,r,r,r,r")
9488	    (match_operand:SI 1 "arm_add_operand"
9489	        "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
9490	  (match_operator:SI 5 "arm_comparison_operator"
9491	   [(match_operand:SI 2 "s_register_operand"
9492	        "l,r,r,l,l,r,r,r,r")
9493	    (match_operand:SI 3 "arm_add_operand"
9494	        "lPy,rI,L,lPy,lPy,rI,rI,L,L")]))
9495	 (const_int 0)))]
9496  "TARGET_32BIT"
9497  "*
9498  {
9499    static const char *const cmp1[NUM_OF_COND_CMP][2] =
9500    {
9501      {\"cmp\\t%0, %1\",
9502       \"cmp\\t%2, %3\"},
9503      {\"cmn\\t%0, #%n1\",
9504       \"cmp\\t%2, %3\"},
9505      {\"cmp\\t%0, %1\",
9506       \"cmn\\t%2, #%n3\"},
9507      {\"cmn\\t%0, #%n1\",
9508       \"cmn\\t%2, #%n3\"}
9509    };
9510    static const char *const cmp2[NUM_OF_COND_CMP][2] =
9511    {
9512      {\"cmp%D4\\t%2, %3\",
9513       \"cmp%D5\\t%0, %1\"},
9514      {\"cmp%D4\\t%2, %3\",
9515       \"cmn%D5\\t%0, #%n1\"},
9516      {\"cmn%D4\\t%2, #%n3\",
9517       \"cmp%D5\\t%0, %1\"},
9518      {\"cmn%D4\\t%2, #%n3\",
9519       \"cmn%D5\\t%0, #%n1\"}
9520    };
9521    static const char *const ite[2] =
9522    {
9523      \"it\\t%D4\",
9524      \"it\\t%D5\"
9525    };
9526    static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
9527                                   CMP_CMP, CMN_CMP, CMP_CMP,
9528                                   CMN_CMP, CMP_CMN, CMN_CMN};
9529    int swap =
9530      comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
9531
9532    output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
9533    if (TARGET_THUMB2) {
9534      output_asm_insn (ite[swap], operands);
9535    }
9536    output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
9537    return \"\";
9538  }
9539  "
9540  [(set_attr "conds" "set")
9541   (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
9542   (set_attr "enabled_for_short_it" "yes,no,no,no,no,no,no,no,no")
9543   (set_attr_alternative "length"
9544      [(const_int 6)
9545       (const_int 8)
9546       (const_int 8)
9547       (const_int 8)
9548       (const_int 8)
9549       (if_then_else (eq_attr "is_thumb" "no")
9550           (const_int 8)
9551           (const_int 10))
9552       (if_then_else (eq_attr "is_thumb" "no")
9553           (const_int 8)
9554           (const_int 10))
9555       (if_then_else (eq_attr "is_thumb" "no")
9556           (const_int 8)
9557           (const_int 10))
9558       (if_then_else (eq_attr "is_thumb" "no")
9559           (const_int 8)
9560           (const_int 10))])
9561   (set_attr "type" "multiple")]
9562)
9563
9564(define_insn_and_split "*ior_scc_scc"
9565  [(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts")
9566	(ior:SI (match_operator:SI 3 "arm_comparison_operator"
9567		 [(match_operand:SI 1 "s_register_operand" "l,r")
9568		  (match_operand:SI 2 "arm_add_operand" "lPy,rIL")])
9569		(match_operator:SI 6 "arm_comparison_operator"
9570		 [(match_operand:SI 4 "s_register_operand" "l,r")
9571		  (match_operand:SI 5 "arm_add_operand" "lPy,rIL")])))
9572   (clobber (reg:CC CC_REGNUM))]
9573  "TARGET_32BIT
9574   && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_OR_Y)
9575       != CCmode)"
9576  "#"
9577  "TARGET_32BIT && reload_completed"
9578  [(set (match_dup 7)
9579	(compare
9580	 (ior:SI
9581	  (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9582	  (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9583	 (const_int 0)))
9584   (set (match_dup 0) (ne:SI (match_dup 7) (const_int 0)))]
9585  "operands[7]
9586     = gen_rtx_REG (arm_select_dominance_cc_mode (operands[3], operands[6],
9587						  DOM_CC_X_OR_Y),
9588		    CC_REGNUM);"
9589  [(set_attr "conds" "clob")
9590   (set_attr "enabled_for_short_it" "yes,no")
9591   (set_attr "length" "16")
9592   (set_attr "type" "multiple")]
9593)
9594
9595; If the above pattern is followed by a CMP insn, then the compare is
9596; redundant, since we can rework the conditional instruction that follows.
9597(define_insn_and_split "*ior_scc_scc_cmp"
9598  [(set (match_operand 0 "dominant_cc_register" "")
9599	(compare (ior:SI (match_operator:SI 3 "arm_comparison_operator"
9600			  [(match_operand:SI 1 "s_register_operand" "l,r")
9601			   (match_operand:SI 2 "arm_add_operand" "lPy,rIL")])
9602			 (match_operator:SI 6 "arm_comparison_operator"
9603			  [(match_operand:SI 4 "s_register_operand" "l,r")
9604			   (match_operand:SI 5 "arm_add_operand" "lPy,rIL")]))
9605		 (const_int 0)))
9606   (set (match_operand:SI 7 "s_register_operand" "=Ts,Ts")
9607	(ior:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9608		(match_op_dup 6 [(match_dup 4) (match_dup 5)])))]
9609  "TARGET_32BIT"
9610  "#"
9611  "TARGET_32BIT && reload_completed"
9612  [(set (match_dup 0)
9613	(compare
9614	 (ior:SI
9615	  (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9616	  (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9617	 (const_int 0)))
9618   (set (match_dup 7) (ne:SI (match_dup 0) (const_int 0)))]
9619  ""
9620  [(set_attr "conds" "set")
9621   (set_attr "enabled_for_short_it" "yes,no")
9622   (set_attr "length" "16")
9623   (set_attr "type" "multiple")]
9624)
9625
9626(define_insn_and_split "*and_scc_scc"
9627  [(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts")
9628	(and:SI (match_operator:SI 3 "arm_comparison_operator"
9629		 [(match_operand:SI 1 "s_register_operand" "l,r")
9630		  (match_operand:SI 2 "arm_add_operand" "lPy,rIL")])
9631		(match_operator:SI 6 "arm_comparison_operator"
9632		 [(match_operand:SI 4 "s_register_operand" "l,r")
9633		  (match_operand:SI 5 "arm_add_operand" "lPy,rIL")])))
9634   (clobber (reg:CC CC_REGNUM))]
9635  "TARGET_32BIT
9636   && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
9637       != CCmode)"
9638  "#"
9639  "TARGET_32BIT && reload_completed
9640   && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
9641       != CCmode)"
9642  [(set (match_dup 7)
9643	(compare
9644	 (and:SI
9645	  (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9646	  (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9647	 (const_int 0)))
9648   (set (match_dup 0) (ne:SI (match_dup 7) (const_int 0)))]
9649  "operands[7]
9650     = gen_rtx_REG (arm_select_dominance_cc_mode (operands[3], operands[6],
9651						  DOM_CC_X_AND_Y),
9652		    CC_REGNUM);"
9653  [(set_attr "conds" "clob")
9654   (set_attr "enabled_for_short_it" "yes,no")
9655   (set_attr "length" "16")
9656   (set_attr "type" "multiple")]
9657)
9658
9659; If the above pattern is followed by a CMP insn, then the compare is
9660; redundant, since we can rework the conditional instruction that follows.
9661(define_insn_and_split "*and_scc_scc_cmp"
9662  [(set (match_operand 0 "dominant_cc_register" "")
9663	(compare (and:SI (match_operator:SI 3 "arm_comparison_operator"
9664			  [(match_operand:SI 1 "s_register_operand" "l,r")
9665			   (match_operand:SI 2 "arm_add_operand" "lPy,rIL")])
9666			 (match_operator:SI 6 "arm_comparison_operator"
9667			  [(match_operand:SI 4 "s_register_operand" "l,r")
9668			   (match_operand:SI 5 "arm_add_operand" "lPy,rIL")]))
9669		 (const_int 0)))
9670   (set (match_operand:SI 7 "s_register_operand" "=Ts,Ts")
9671	(and:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9672		(match_op_dup 6 [(match_dup 4) (match_dup 5)])))]
9673  "TARGET_32BIT"
9674  "#"
9675  "TARGET_32BIT && reload_completed"
9676  [(set (match_dup 0)
9677	(compare
9678	 (and:SI
9679	  (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9680	  (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9681	 (const_int 0)))
9682   (set (match_dup 7) (ne:SI (match_dup 0) (const_int 0)))]
9683  ""
9684  [(set_attr "conds" "set")
9685   (set_attr "enabled_for_short_it" "yes,no")
9686   (set_attr "length" "16")
9687   (set_attr "type" "multiple")]
9688)
9689
9690;; If there is no dominance in the comparison, then we can still save an
9691;; instruction in the AND case, since we can know that the second compare
9692;; need only zero the value if false (if true, then the value is already
9693;; correct).
9694(define_insn_and_split "*and_scc_scc_nodom"
9695  [(set (match_operand:SI 0 "s_register_operand" "=&Ts,&Ts,&Ts")
9696	(and:SI (match_operator:SI 3 "arm_comparison_operator"
9697		 [(match_operand:SI 1 "s_register_operand" "r,r,0")
9698		  (match_operand:SI 2 "arm_add_operand" "rIL,0,rIL")])
9699		(match_operator:SI 6 "arm_comparison_operator"
9700		 [(match_operand:SI 4 "s_register_operand" "r,r,r")
9701		  (match_operand:SI 5 "arm_add_operand" "rIL,rIL,rIL")])))
9702   (clobber (reg:CC CC_REGNUM))]
9703  "TARGET_32BIT
9704   && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
9705       == CCmode)"
9706  "#"
9707  "TARGET_32BIT && reload_completed"
9708  [(parallel [(set (match_dup 0)
9709		   (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
9710	      (clobber (reg:CC CC_REGNUM))])
9711   (set (match_dup 7) (match_op_dup 8 [(match_dup 4) (match_dup 5)]))
9712   (set (match_dup 0)
9713	(if_then_else:SI (match_op_dup 6 [(match_dup 7) (const_int 0)])
9714			 (match_dup 0)
9715			 (const_int 0)))]
9716  "operands[7] = gen_rtx_REG (SELECT_CC_MODE (GET_CODE (operands[6]),
9717					      operands[4], operands[5]),
9718			      CC_REGNUM);
9719   operands[8] = gen_rtx_COMPARE (GET_MODE (operands[7]), operands[4],
9720				  operands[5]);"
9721  [(set_attr "conds" "clob")
9722   (set_attr "length" "20")
9723   (set_attr "type" "multiple")]
9724)
9725
9726(define_split
9727  [(set (reg:CC_NOOV CC_REGNUM)
9728	(compare:CC_NOOV (ior:SI
9729			  (and:SI (match_operand:SI 0 "s_register_operand" "")
9730				  (const_int 1))
9731			  (match_operator:SI 1 "arm_comparison_operator"
9732			   [(match_operand:SI 2 "s_register_operand" "")
9733			    (match_operand:SI 3 "arm_add_operand" "")]))
9734			 (const_int 0)))
9735   (clobber (match_operand:SI 4 "s_register_operand" ""))]
9736  "TARGET_ARM"
9737  [(set (match_dup 4)
9738	(ior:SI (match_op_dup 1 [(match_dup 2) (match_dup 3)])
9739		(match_dup 0)))
9740   (set (reg:CC_NOOV CC_REGNUM)
9741	(compare:CC_NOOV (and:SI (match_dup 4) (const_int 1))
9742			 (const_int 0)))]
9743  "")
9744
9745(define_split
9746  [(set (reg:CC_NOOV CC_REGNUM)
9747	(compare:CC_NOOV (ior:SI
9748			  (match_operator:SI 1 "arm_comparison_operator"
9749			   [(match_operand:SI 2 "s_register_operand" "")
9750			    (match_operand:SI 3 "arm_add_operand" "")])
9751			  (and:SI (match_operand:SI 0 "s_register_operand" "")
9752				  (const_int 1)))
9753			 (const_int 0)))
9754   (clobber (match_operand:SI 4 "s_register_operand" ""))]
9755  "TARGET_ARM"
9756  [(set (match_dup 4)
9757	(ior:SI (match_op_dup 1 [(match_dup 2) (match_dup 3)])
9758		(match_dup 0)))
9759   (set (reg:CC_NOOV CC_REGNUM)
9760	(compare:CC_NOOV (and:SI (match_dup 4) (const_int 1))
9761			 (const_int 0)))]
9762  "")
9763;; ??? The conditional patterns above need checking for Thumb-2 usefulness
9764
9765(define_insn_and_split "*negscc"
9766  [(set (match_operand:SI 0 "s_register_operand" "=r")
9767	(neg:SI (match_operator 3 "arm_comparison_operator"
9768		 [(match_operand:SI 1 "s_register_operand" "r")
9769		  (match_operand:SI 2 "arm_rhs_operand" "rI")])))
9770   (clobber (reg:CC CC_REGNUM))]
9771  "TARGET_ARM"
9772  "#"
9773  "&& reload_completed"
9774  [(const_int 0)]
9775  {
9776    rtx cc_reg = gen_rtx_REG (CCmode, CC_REGNUM);
9777
9778    if (GET_CODE (operands[3]) == LT && operands[2] == const0_rtx)
9779       {
9780         /* Emit mov\\t%0, %1, asr #31 */
9781         emit_insn (gen_rtx_SET (operands[0],
9782                                 gen_rtx_ASHIFTRT (SImode,
9783                                                   operands[1],
9784                                                   GEN_INT (31))));
9785         DONE;
9786       }
9787     else if (GET_CODE (operands[3]) == NE)
9788       {
9789        /* Emit subs\\t%0, %1, %2\;mvnne\\t%0, #0 */
9790        if (CONST_INT_P (operands[2]))
9791          emit_insn (gen_cmpsi2_addneg (operands[0], operands[1], operands[2],
9792                                        GEN_INT (- INTVAL (operands[2]))));
9793        else
9794          emit_insn (gen_subsi3_compare (operands[0], operands[1], operands[2]));
9795
9796        emit_insn (gen_rtx_COND_EXEC (VOIDmode,
9797                                      gen_rtx_NE (SImode,
9798                                                  cc_reg,
9799                                                  const0_rtx),
9800                                      gen_rtx_SET (operands[0],
9801                                                   GEN_INT (~0))));
9802        DONE;
9803      }
9804    else
9805      {
9806        /* Emit: cmp\\t%1, %2\;mov%D3\\t%0, #0\;mvn%d3\\t%0, #0 */
9807        emit_insn (gen_rtx_SET (cc_reg,
9808                                gen_rtx_COMPARE (CCmode, operands[1], operands[2])));
9809        enum rtx_code rc = GET_CODE (operands[3]);
9810
9811        rc = reverse_condition (rc);
9812        emit_insn (gen_rtx_COND_EXEC (VOIDmode,
9813                                      gen_rtx_fmt_ee (rc,
9814                                                      VOIDmode,
9815                                                      cc_reg,
9816                                                      const0_rtx),
9817                                      gen_rtx_SET (operands[0], const0_rtx)));
9818        rc = GET_CODE (operands[3]);
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],
9825                                                   GEN_INT (~0))));
9826        DONE;
9827      }
9828     FAIL;
9829  }
9830  [(set_attr "conds" "clob")
9831   (set_attr "length" "12")
9832   (set_attr "type" "multiple")]
9833)
9834
9835(define_insn_and_split "movcond_addsi"
9836  [(set (match_operand:SI 0 "s_register_operand" "=r,l,r")
9837	(if_then_else:SI
9838	 (match_operator 5 "comparison_operator"
9839	  [(plus:SI (match_operand:SI 3 "s_register_operand" "r,r,r")
9840	            (match_operand:SI 4 "arm_add_operand" "rIL,rIL,rIL"))
9841            (const_int 0)])
9842	 (match_operand:SI 1 "arm_rhs_operand" "rI,rPy,r")
9843	 (match_operand:SI 2 "arm_rhs_operand" "rI,rPy,r")))
9844   (clobber (reg:CC CC_REGNUM))]
9845   "TARGET_32BIT"
9846   "#"
9847   "&& reload_completed"
9848  [(set (reg:CC_NOOV CC_REGNUM)
9849	(compare:CC_NOOV
9850	 (plus:SI (match_dup 3)
9851		  (match_dup 4))
9852	 (const_int 0)))
9853   (set (match_dup 0) (match_dup 1))
9854   (cond_exec (match_dup 6)
9855	      (set (match_dup 0) (match_dup 2)))]
9856  "
9857  {
9858    machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[5]),
9859					     operands[3], operands[4]);
9860    enum rtx_code rc = GET_CODE (operands[5]);
9861    operands[6] = gen_rtx_REG (mode, CC_REGNUM);
9862    gcc_assert (!(mode == CCFPmode || mode == CCFPEmode));
9863    if (!REG_P (operands[2]) || REGNO (operands[2]) != REGNO (operands[0]))
9864      rc = reverse_condition (rc);
9865    else
9866      std::swap (operands[1], operands[2]);
9867
9868    operands[6] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
9869  }
9870  "
9871  [(set_attr "conds" "clob")
9872   (set_attr "enabled_for_short_it" "no,yes,yes")
9873   (set_attr "type" "multiple")]
9874)
9875
9876(define_insn "movcond"
9877  [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9878	(if_then_else:SI
9879	 (match_operator 5 "arm_comparison_operator"
9880	  [(match_operand:SI 3 "s_register_operand" "r,r,r")
9881	   (match_operand:SI 4 "arm_add_operand" "rIL,rIL,rIL")])
9882	 (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
9883	 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
9884   (clobber (reg:CC CC_REGNUM))]
9885  "TARGET_ARM"
9886  "*
9887  if (GET_CODE (operands[5]) == LT
9888      && (operands[4] == const0_rtx))
9889    {
9890      if (which_alternative != 1 && REG_P (operands[1]))
9891	{
9892	  if (operands[2] == const0_rtx)
9893	    return \"and\\t%0, %1, %3, asr #31\";
9894	  return \"ands\\t%0, %1, %3, asr #32\;movcc\\t%0, %2\";
9895	}
9896      else if (which_alternative != 0 && REG_P (operands[2]))
9897	{
9898	  if (operands[1] == const0_rtx)
9899	    return \"bic\\t%0, %2, %3, asr #31\";
9900	  return \"bics\\t%0, %2, %3, asr #32\;movcs\\t%0, %1\";
9901	}
9902      /* The only case that falls through to here is when both ops 1 & 2
9903	 are constants.  */
9904    }
9905
9906  if (GET_CODE (operands[5]) == GE
9907      && (operands[4] == const0_rtx))
9908    {
9909      if (which_alternative != 1 && REG_P (operands[1]))
9910	{
9911	  if (operands[2] == const0_rtx)
9912	    return \"bic\\t%0, %1, %3, asr #31\";
9913	  return \"bics\\t%0, %1, %3, asr #32\;movcs\\t%0, %2\";
9914	}
9915      else if (which_alternative != 0 && REG_P (operands[2]))
9916	{
9917	  if (operands[1] == const0_rtx)
9918	    return \"and\\t%0, %2, %3, asr #31\";
9919	  return \"ands\\t%0, %2, %3, asr #32\;movcc\\t%0, %1\";
9920	}
9921      /* The only case that falls through to here is when both ops 1 & 2
9922	 are constants.  */
9923    }
9924  if (CONST_INT_P (operands[4])
9925      && !const_ok_for_arm (INTVAL (operands[4])))
9926    output_asm_insn (\"cmn\\t%3, #%n4\", operands);
9927  else
9928    output_asm_insn (\"cmp\\t%3, %4\", operands);
9929  if (which_alternative != 0)
9930    output_asm_insn (\"mov%d5\\t%0, %1\", operands);
9931  if (which_alternative != 1)
9932    output_asm_insn (\"mov%D5\\t%0, %2\", operands);
9933  return \"\";
9934  "
9935  [(set_attr "conds" "clob")
9936   (set_attr "length" "8,8,12")
9937   (set_attr "type" "multiple")]
9938)
9939
9940;; ??? The patterns below need checking for Thumb-2 usefulness.
9941
9942(define_insn "*ifcompare_plus_move"
9943  [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9944	(if_then_else:SI (match_operator 6 "arm_comparison_operator"
9945			  [(match_operand:SI 4 "s_register_operand" "r,r")
9946			   (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
9947			 (plus:SI
9948			  (match_operand:SI 2 "s_register_operand" "r,r")
9949			  (match_operand:SI 3 "arm_add_operand" "rIL,rIL"))
9950			 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))
9951   (clobber (reg:CC CC_REGNUM))]
9952  "TARGET_ARM"
9953  "#"
9954  [(set_attr "conds" "clob")
9955   (set_attr "length" "8,12")
9956   (set_attr "type" "multiple")]
9957)
9958
9959(define_insn "*if_plus_move"
9960  [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
9961	(if_then_else:SI
9962	 (match_operator 4 "arm_comparison_operator"
9963	  [(match_operand 5 "cc_register" "") (const_int 0)])
9964	 (plus:SI
9965	  (match_operand:SI 2 "s_register_operand" "r,r,r,r")
9966	  (match_operand:SI 3 "arm_add_operand" "rI,L,rI,L"))
9967	 (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")))]
9968  "TARGET_ARM"
9969  "@
9970   add%d4\\t%0, %2, %3
9971   sub%d4\\t%0, %2, #%n3
9972   add%d4\\t%0, %2, %3\;mov%D4\\t%0, %1
9973   sub%d4\\t%0, %2, #%n3\;mov%D4\\t%0, %1"
9974  [(set_attr "conds" "use")
9975   (set_attr "length" "4,4,8,8")
9976   (set_attr_alternative "type"
9977                         [(if_then_else (match_operand 3 "const_int_operand" "")
9978                                        (const_string "alu_imm" )
9979                                        (const_string "alu_sreg"))
9980                          (const_string "alu_imm")
9981                          (const_string "multiple")
9982                          (const_string "multiple")])]
9983)
9984
9985(define_insn "*ifcompare_move_plus"
9986  [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9987	(if_then_else:SI (match_operator 6 "arm_comparison_operator"
9988			  [(match_operand:SI 4 "s_register_operand" "r,r")
9989			   (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
9990			 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
9991			 (plus:SI
9992			  (match_operand:SI 2 "s_register_operand" "r,r")
9993			  (match_operand:SI 3 "arm_add_operand" "rIL,rIL"))))
9994   (clobber (reg:CC CC_REGNUM))]
9995  "TARGET_ARM"
9996  "#"
9997  [(set_attr "conds" "clob")
9998   (set_attr "length" "8,12")
9999   (set_attr "type" "multiple")]
10000)
10001
10002(define_insn "*if_move_plus"
10003  [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
10004	(if_then_else:SI
10005	 (match_operator 4 "arm_comparison_operator"
10006	  [(match_operand 5 "cc_register" "") (const_int 0)])
10007	 (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")
10008	 (plus:SI
10009	  (match_operand:SI 2 "s_register_operand" "r,r,r,r")
10010	  (match_operand:SI 3 "arm_add_operand" "rI,L,rI,L"))))]
10011  "TARGET_ARM"
10012  "@
10013   add%D4\\t%0, %2, %3
10014   sub%D4\\t%0, %2, #%n3
10015   add%D4\\t%0, %2, %3\;mov%d4\\t%0, %1
10016   sub%D4\\t%0, %2, #%n3\;mov%d4\\t%0, %1"
10017  [(set_attr "conds" "use")
10018   (set_attr "length" "4,4,8,8")
10019   (set_attr_alternative "type"
10020                         [(if_then_else (match_operand 3 "const_int_operand" "")
10021                                        (const_string "alu_imm" )
10022                                        (const_string "alu_sreg"))
10023                          (const_string "alu_imm")
10024                          (const_string "multiple")
10025                          (const_string "multiple")])]
10026)
10027
10028(define_insn "*ifcompare_arith_arith"
10029  [(set (match_operand:SI 0 "s_register_operand" "=r")
10030	(if_then_else:SI (match_operator 9 "arm_comparison_operator"
10031			  [(match_operand:SI 5 "s_register_operand" "r")
10032			   (match_operand:SI 6 "arm_add_operand" "rIL")])
10033			 (match_operator:SI 8 "shiftable_operator"
10034			  [(match_operand:SI 1 "s_register_operand" "r")
10035			   (match_operand:SI 2 "arm_rhs_operand" "rI")])
10036			 (match_operator:SI 7 "shiftable_operator"
10037			  [(match_operand:SI 3 "s_register_operand" "r")
10038			   (match_operand:SI 4 "arm_rhs_operand" "rI")])))
10039   (clobber (reg:CC CC_REGNUM))]
10040  "TARGET_ARM"
10041  "#"
10042  [(set_attr "conds" "clob")
10043   (set_attr "length" "12")
10044   (set_attr "type" "multiple")]
10045)
10046
10047(define_insn "*if_arith_arith"
10048  [(set (match_operand:SI 0 "s_register_operand" "=r")
10049	(if_then_else:SI (match_operator 5 "arm_comparison_operator"
10050			  [(match_operand 8 "cc_register" "") (const_int 0)])
10051			 (match_operator:SI 6 "shiftable_operator"
10052			  [(match_operand:SI 1 "s_register_operand" "r")
10053			   (match_operand:SI 2 "arm_rhs_operand" "rI")])
10054			 (match_operator:SI 7 "shiftable_operator"
10055			  [(match_operand:SI 3 "s_register_operand" "r")
10056			   (match_operand:SI 4 "arm_rhs_operand" "rI")])))]
10057  "TARGET_ARM"
10058  "%I6%d5\\t%0, %1, %2\;%I7%D5\\t%0, %3, %4"
10059  [(set_attr "conds" "use")
10060   (set_attr "length" "8")
10061   (set_attr "type" "multiple")]
10062)
10063
10064(define_insn "*ifcompare_arith_move"
10065  [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10066	(if_then_else:SI (match_operator 6 "arm_comparison_operator"
10067			  [(match_operand:SI 2 "s_register_operand" "r,r")
10068			   (match_operand:SI 3 "arm_add_operand" "rIL,rIL")])
10069			 (match_operator:SI 7 "shiftable_operator"
10070			  [(match_operand:SI 4 "s_register_operand" "r,r")
10071			   (match_operand:SI 5 "arm_rhs_operand" "rI,rI")])
10072			 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))
10073   (clobber (reg:CC CC_REGNUM))]
10074  "TARGET_ARM"
10075  "*
10076  /* If we have an operation where (op x 0) is the identity operation and
10077     the conditional operator is LT or GE and we are comparing against zero and
10078     everything is in registers then we can do this in two instructions.  */
10079  if (operands[3] == const0_rtx
10080      && GET_CODE (operands[7]) != AND
10081      && REG_P (operands[5])
10082      && REG_P (operands[1])
10083      && REGNO (operands[1]) == REGNO (operands[4])
10084      && REGNO (operands[4]) != REGNO (operands[0]))
10085    {
10086      if (GET_CODE (operands[6]) == LT)
10087	return \"and\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\";
10088      else if (GET_CODE (operands[6]) == GE)
10089	return \"bic\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\";
10090    }
10091  if (CONST_INT_P (operands[3])
10092      && !const_ok_for_arm (INTVAL (operands[3])))
10093    output_asm_insn (\"cmn\\t%2, #%n3\", operands);
10094  else
10095    output_asm_insn (\"cmp\\t%2, %3\", operands);
10096  output_asm_insn (\"%I7%d6\\t%0, %4, %5\", operands);
10097  if (which_alternative != 0)
10098    return \"mov%D6\\t%0, %1\";
10099  return \"\";
10100  "
10101  [(set_attr "conds" "clob")
10102   (set_attr "length" "8,12")
10103   (set_attr "type" "multiple")]
10104)
10105
10106(define_insn "*if_arith_move"
10107  [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10108	(if_then_else:SI (match_operator 4 "arm_comparison_operator"
10109			  [(match_operand 6 "cc_register" "") (const_int 0)])
10110			 (match_operator:SI 5 "shiftable_operator"
10111			  [(match_operand:SI 2 "s_register_operand" "r,r")
10112			   (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
10113			 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))]
10114  "TARGET_ARM"
10115  "@
10116   %I5%d4\\t%0, %2, %3
10117   %I5%d4\\t%0, %2, %3\;mov%D4\\t%0, %1"
10118  [(set_attr "conds" "use")
10119   (set_attr "length" "4,8")
10120   (set_attr_alternative "type"
10121                         [(if_then_else (match_operand 3 "const_int_operand" "")
10122                                        (const_string "alu_shift_imm" )
10123                                        (const_string "alu_shift_reg"))
10124                          (const_string "multiple")])]
10125)
10126
10127(define_insn "*ifcompare_move_arith"
10128  [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10129	(if_then_else:SI (match_operator 6 "arm_comparison_operator"
10130			  [(match_operand:SI 4 "s_register_operand" "r,r")
10131			   (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
10132			 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
10133			 (match_operator:SI 7 "shiftable_operator"
10134			  [(match_operand:SI 2 "s_register_operand" "r,r")
10135			   (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
10136   (clobber (reg:CC CC_REGNUM))]
10137  "TARGET_ARM"
10138  "*
10139  /* If we have an operation where (op x 0) is the identity operation and
10140     the conditional operator is LT or GE and we are comparing against zero and
10141     everything is in registers then we can do this in two instructions */
10142  if (operands[5] == const0_rtx
10143      && GET_CODE (operands[7]) != AND
10144      && REG_P (operands[3])
10145      && REG_P (operands[1])
10146      && REGNO (operands[1]) == REGNO (operands[2])
10147      && REGNO (operands[2]) != REGNO (operands[0]))
10148    {
10149      if (GET_CODE (operands[6]) == GE)
10150	return \"and\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\";
10151      else if (GET_CODE (operands[6]) == LT)
10152	return \"bic\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\";
10153    }
10154
10155  if (CONST_INT_P (operands[5])
10156      && !const_ok_for_arm (INTVAL (operands[5])))
10157    output_asm_insn (\"cmn\\t%4, #%n5\", operands);
10158  else
10159    output_asm_insn (\"cmp\\t%4, %5\", operands);
10160
10161  if (which_alternative != 0)
10162    output_asm_insn (\"mov%d6\\t%0, %1\", operands);
10163  return \"%I7%D6\\t%0, %2, %3\";
10164  "
10165  [(set_attr "conds" "clob")
10166   (set_attr "length" "8,12")
10167   (set_attr "type" "multiple")]
10168)
10169
10170(define_insn "*if_move_arith"
10171  [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10172	(if_then_else:SI
10173	 (match_operator 4 "arm_comparison_operator"
10174	  [(match_operand 6 "cc_register" "") (const_int 0)])
10175	 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
10176	 (match_operator:SI 5 "shiftable_operator"
10177	  [(match_operand:SI 2 "s_register_operand" "r,r")
10178	   (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))]
10179  "TARGET_ARM"
10180  "@
10181   %I5%D4\\t%0, %2, %3
10182   %I5%D4\\t%0, %2, %3\;mov%d4\\t%0, %1"
10183  [(set_attr "conds" "use")
10184   (set_attr "length" "4,8")
10185   (set_attr_alternative "type"
10186                         [(if_then_else (match_operand 3 "const_int_operand" "")
10187                                        (const_string "alu_shift_imm" )
10188                                        (const_string "alu_shift_reg"))
10189                          (const_string "multiple")])]
10190)
10191
10192(define_insn "*ifcompare_move_not"
10193  [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10194	(if_then_else:SI
10195	 (match_operator 5 "arm_comparison_operator"
10196	  [(match_operand:SI 3 "s_register_operand" "r,r")
10197	   (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
10198	 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
10199	 (not:SI
10200	  (match_operand:SI 2 "s_register_operand" "r,r"))))
10201   (clobber (reg:CC CC_REGNUM))]
10202  "TARGET_ARM"
10203  "#"
10204  [(set_attr "conds" "clob")
10205   (set_attr "length" "8,12")
10206   (set_attr "type" "multiple")]
10207)
10208
10209(define_insn "*if_move_not"
10210  [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
10211	(if_then_else:SI
10212	 (match_operator 4 "arm_comparison_operator"
10213	  [(match_operand 3 "cc_register" "") (const_int 0)])
10214	 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
10215	 (not:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))))]
10216  "TARGET_ARM"
10217  "@
10218   mvn%D4\\t%0, %2
10219   mov%d4\\t%0, %1\;mvn%D4\\t%0, %2
10220   mvn%d4\\t%0, #%B1\;mvn%D4\\t%0, %2"
10221  [(set_attr "conds" "use")
10222   (set_attr "type" "mvn_reg")
10223   (set_attr "length" "4,8,8")
10224   (set_attr "type" "mvn_reg,multiple,multiple")]
10225)
10226
10227(define_insn "*ifcompare_not_move"
10228  [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10229	(if_then_else:SI
10230	 (match_operator 5 "arm_comparison_operator"
10231	  [(match_operand:SI 3 "s_register_operand" "r,r")
10232	   (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
10233	 (not:SI
10234	  (match_operand:SI 2 "s_register_operand" "r,r"))
10235	 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
10236   (clobber (reg:CC CC_REGNUM))]
10237  "TARGET_ARM"
10238  "#"
10239  [(set_attr "conds" "clob")
10240   (set_attr "length" "8,12")
10241   (set_attr "type" "multiple")]
10242)
10243
10244(define_insn "*if_not_move"
10245  [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
10246	(if_then_else:SI
10247	 (match_operator 4 "arm_comparison_operator"
10248	  [(match_operand 3 "cc_register" "") (const_int 0)])
10249	 (not:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))
10250	 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
10251  "TARGET_ARM"
10252  "@
10253   mvn%d4\\t%0, %2
10254   mov%D4\\t%0, %1\;mvn%d4\\t%0, %2
10255   mvn%D4\\t%0, #%B1\;mvn%d4\\t%0, %2"
10256  [(set_attr "conds" "use")
10257   (set_attr "type" "mvn_reg,multiple,multiple")
10258   (set_attr "length" "4,8,8")]
10259)
10260
10261(define_insn "*ifcompare_shift_move"
10262  [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10263	(if_then_else:SI
10264	 (match_operator 6 "arm_comparison_operator"
10265	  [(match_operand:SI 4 "s_register_operand" "r,r")
10266	   (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
10267	 (match_operator:SI 7 "shift_operator"
10268	  [(match_operand:SI 2 "s_register_operand" "r,r")
10269	   (match_operand:SI 3 "arm_rhs_operand" "rM,rM")])
10270	 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
10271   (clobber (reg:CC CC_REGNUM))]
10272  "TARGET_ARM"
10273  "#"
10274  [(set_attr "conds" "clob")
10275   (set_attr "length" "8,12")
10276   (set_attr "type" "multiple")]
10277)
10278
10279(define_insn "*if_shift_move"
10280  [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
10281	(if_then_else:SI
10282	 (match_operator 5 "arm_comparison_operator"
10283	  [(match_operand 6 "cc_register" "") (const_int 0)])
10284	 (match_operator:SI 4 "shift_operator"
10285	  [(match_operand:SI 2 "s_register_operand" "r,r,r")
10286	   (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM")])
10287	 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
10288  "TARGET_ARM"
10289  "@
10290   mov%d5\\t%0, %2%S4
10291   mov%D5\\t%0, %1\;mov%d5\\t%0, %2%S4
10292   mvn%D5\\t%0, #%B1\;mov%d5\\t%0, %2%S4"
10293  [(set_attr "conds" "use")
10294   (set_attr "shift" "2")
10295   (set_attr "length" "4,8,8")
10296   (set_attr_alternative "type"
10297                         [(if_then_else (match_operand 3 "const_int_operand" "")
10298                                        (const_string "mov_shift" )
10299                                        (const_string "mov_shift_reg"))
10300                          (const_string "multiple")
10301                          (const_string "multiple")])]
10302)
10303
10304(define_insn "*ifcompare_move_shift"
10305  [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10306	(if_then_else:SI
10307	 (match_operator 6 "arm_comparison_operator"
10308	  [(match_operand:SI 4 "s_register_operand" "r,r")
10309	   (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
10310	 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
10311	 (match_operator:SI 7 "shift_operator"
10312	  [(match_operand:SI 2 "s_register_operand" "r,r")
10313	   (match_operand:SI 3 "arm_rhs_operand" "rM,rM")])))
10314   (clobber (reg:CC CC_REGNUM))]
10315  "TARGET_ARM"
10316  "#"
10317  [(set_attr "conds" "clob")
10318   (set_attr "length" "8,12")
10319   (set_attr "type" "multiple")]
10320)
10321
10322(define_insn "*if_move_shift"
10323  [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
10324	(if_then_else:SI
10325	 (match_operator 5 "arm_comparison_operator"
10326	  [(match_operand 6 "cc_register" "") (const_int 0)])
10327	 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
10328	 (match_operator:SI 4 "shift_operator"
10329	  [(match_operand:SI 2 "s_register_operand" "r,r,r")
10330	   (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM")])))]
10331  "TARGET_ARM"
10332  "@
10333   mov%D5\\t%0, %2%S4
10334   mov%d5\\t%0, %1\;mov%D5\\t%0, %2%S4
10335   mvn%d5\\t%0, #%B1\;mov%D5\\t%0, %2%S4"
10336  [(set_attr "conds" "use")
10337   (set_attr "shift" "2")
10338   (set_attr "length" "4,8,8")
10339   (set_attr_alternative "type"
10340                         [(if_then_else (match_operand 3 "const_int_operand" "")
10341                                        (const_string "mov_shift" )
10342                                        (const_string "mov_shift_reg"))
10343                          (const_string "multiple")
10344                          (const_string "multiple")])]
10345)
10346
10347(define_insn "*ifcompare_shift_shift"
10348  [(set (match_operand:SI 0 "s_register_operand" "=r")
10349	(if_then_else:SI
10350	 (match_operator 7 "arm_comparison_operator"
10351	  [(match_operand:SI 5 "s_register_operand" "r")
10352	   (match_operand:SI 6 "arm_add_operand" "rIL")])
10353	 (match_operator:SI 8 "shift_operator"
10354	  [(match_operand:SI 1 "s_register_operand" "r")
10355	   (match_operand:SI 2 "arm_rhs_operand" "rM")])
10356	 (match_operator:SI 9 "shift_operator"
10357	  [(match_operand:SI 3 "s_register_operand" "r")
10358	   (match_operand:SI 4 "arm_rhs_operand" "rM")])))
10359   (clobber (reg:CC CC_REGNUM))]
10360  "TARGET_ARM"
10361  "#"
10362  [(set_attr "conds" "clob")
10363   (set_attr "length" "12")
10364   (set_attr "type" "multiple")]
10365)
10366
10367(define_insn "*if_shift_shift"
10368  [(set (match_operand:SI 0 "s_register_operand" "=r")
10369	(if_then_else:SI
10370	 (match_operator 5 "arm_comparison_operator"
10371	  [(match_operand 8 "cc_register" "") (const_int 0)])
10372	 (match_operator:SI 6 "shift_operator"
10373	  [(match_operand:SI 1 "s_register_operand" "r")
10374	   (match_operand:SI 2 "arm_rhs_operand" "rM")])
10375	 (match_operator:SI 7 "shift_operator"
10376	  [(match_operand:SI 3 "s_register_operand" "r")
10377	   (match_operand:SI 4 "arm_rhs_operand" "rM")])))]
10378  "TARGET_ARM"
10379  "mov%d5\\t%0, %1%S6\;mov%D5\\t%0, %3%S7"
10380  [(set_attr "conds" "use")
10381   (set_attr "shift" "1")
10382   (set_attr "length" "8")
10383   (set (attr "type") (if_then_else
10384		        (and (match_operand 2 "const_int_operand" "")
10385                             (match_operand 4 "const_int_operand" ""))
10386		      (const_string "mov_shift")
10387		      (const_string "mov_shift_reg")))]
10388)
10389
10390(define_insn "*ifcompare_not_arith"
10391  [(set (match_operand:SI 0 "s_register_operand" "=r")
10392	(if_then_else:SI
10393	 (match_operator 6 "arm_comparison_operator"
10394	  [(match_operand:SI 4 "s_register_operand" "r")
10395	   (match_operand:SI 5 "arm_add_operand" "rIL")])
10396	 (not:SI (match_operand:SI 1 "s_register_operand" "r"))
10397	 (match_operator:SI 7 "shiftable_operator"
10398	  [(match_operand:SI 2 "s_register_operand" "r")
10399	   (match_operand:SI 3 "arm_rhs_operand" "rI")])))
10400   (clobber (reg:CC CC_REGNUM))]
10401  "TARGET_ARM"
10402  "#"
10403  [(set_attr "conds" "clob")
10404   (set_attr "length" "12")
10405   (set_attr "type" "multiple")]
10406)
10407
10408(define_insn "*if_not_arith"
10409  [(set (match_operand:SI 0 "s_register_operand" "=r")
10410	(if_then_else:SI
10411	 (match_operator 5 "arm_comparison_operator"
10412	  [(match_operand 4 "cc_register" "") (const_int 0)])
10413	 (not:SI (match_operand:SI 1 "s_register_operand" "r"))
10414	 (match_operator:SI 6 "shiftable_operator"
10415	  [(match_operand:SI 2 "s_register_operand" "r")
10416	   (match_operand:SI 3 "arm_rhs_operand" "rI")])))]
10417  "TARGET_ARM"
10418  "mvn%d5\\t%0, %1\;%I6%D5\\t%0, %2, %3"
10419  [(set_attr "conds" "use")
10420   (set_attr "type" "mvn_reg")
10421   (set_attr "length" "8")]
10422)
10423
10424(define_insn "*ifcompare_arith_not"
10425  [(set (match_operand:SI 0 "s_register_operand" "=r")
10426	(if_then_else:SI
10427	 (match_operator 6 "arm_comparison_operator"
10428	  [(match_operand:SI 4 "s_register_operand" "r")
10429	   (match_operand:SI 5 "arm_add_operand" "rIL")])
10430	 (match_operator:SI 7 "shiftable_operator"
10431	  [(match_operand:SI 2 "s_register_operand" "r")
10432	   (match_operand:SI 3 "arm_rhs_operand" "rI")])
10433	 (not:SI (match_operand:SI 1 "s_register_operand" "r"))))
10434   (clobber (reg:CC CC_REGNUM))]
10435  "TARGET_ARM"
10436  "#"
10437  [(set_attr "conds" "clob")
10438   (set_attr "length" "12")
10439   (set_attr "type" "multiple")]
10440)
10441
10442(define_insn "*if_arith_not"
10443  [(set (match_operand:SI 0 "s_register_operand" "=r")
10444	(if_then_else:SI
10445	 (match_operator 5 "arm_comparison_operator"
10446	  [(match_operand 4 "cc_register" "") (const_int 0)])
10447	 (match_operator:SI 6 "shiftable_operator"
10448	  [(match_operand:SI 2 "s_register_operand" "r")
10449	   (match_operand:SI 3 "arm_rhs_operand" "rI")])
10450	 (not:SI (match_operand:SI 1 "s_register_operand" "r"))))]
10451  "TARGET_ARM"
10452  "mvn%D5\\t%0, %1\;%I6%d5\\t%0, %2, %3"
10453  [(set_attr "conds" "use")
10454   (set_attr "type" "multiple")
10455   (set_attr "length" "8")]
10456)
10457
10458(define_insn "*ifcompare_neg_move"
10459  [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10460	(if_then_else:SI
10461	 (match_operator 5 "arm_comparison_operator"
10462	  [(match_operand:SI 3 "s_register_operand" "r,r")
10463	   (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
10464	 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r"))
10465	 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
10466   (clobber (reg:CC CC_REGNUM))]
10467  "TARGET_ARM"
10468  "#"
10469  [(set_attr "conds" "clob")
10470   (set_attr "length" "8,12")
10471   (set_attr "type" "multiple")]
10472)
10473
10474(define_insn_and_split "*if_neg_move"
10475  [(set (match_operand:SI 0 "s_register_operand" "=l,r")
10476	(if_then_else:SI
10477	 (match_operator 4 "arm_comparison_operator"
10478	  [(match_operand 3 "cc_register" "") (const_int 0)])
10479	 (neg:SI (match_operand:SI 2 "s_register_operand" "l,r"))
10480	 (match_operand:SI 1 "s_register_operand" "0,0")))]
10481  "TARGET_32BIT"
10482  "#"
10483  "&& reload_completed"
10484  [(cond_exec (match_op_dup 4 [(match_dup 3) (const_int 0)])
10485	      (set (match_dup 0) (neg:SI (match_dup 2))))]
10486  ""
10487  [(set_attr "conds" "use")
10488   (set_attr "length" "4")
10489   (set_attr "arch" "t2,32")
10490   (set_attr "enabled_for_short_it" "yes,no")
10491   (set_attr "type" "logic_shift_imm")]
10492)
10493
10494(define_insn "*ifcompare_move_neg"
10495  [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10496	(if_then_else:SI
10497	 (match_operator 5 "arm_comparison_operator"
10498	  [(match_operand:SI 3 "s_register_operand" "r,r")
10499	   (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
10500	 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
10501	 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r"))))
10502   (clobber (reg:CC CC_REGNUM))]
10503  "TARGET_ARM"
10504  "#"
10505  [(set_attr "conds" "clob")
10506   (set_attr "length" "8,12")
10507   (set_attr "type" "multiple")]
10508)
10509
10510(define_insn_and_split "*if_move_neg"
10511  [(set (match_operand:SI 0 "s_register_operand" "=l,r")
10512	(if_then_else:SI
10513	 (match_operator 4 "arm_comparison_operator"
10514	  [(match_operand 3 "cc_register" "") (const_int 0)])
10515	 (match_operand:SI 1 "s_register_operand" "0,0")
10516	 (neg:SI (match_operand:SI 2 "s_register_operand" "l,r"))))]
10517  "TARGET_32BIT"
10518  "#"
10519  "&& reload_completed"
10520  [(cond_exec (match_dup 5)
10521	      (set (match_dup 0) (neg:SI (match_dup 2))))]
10522  {
10523    machine_mode mode = GET_MODE (operands[3]);
10524    rtx_code rc = GET_CODE (operands[4]);
10525
10526    if (mode == CCFPmode || mode == CCFPEmode)
10527      rc = reverse_condition_maybe_unordered (rc);
10528    else
10529      rc = reverse_condition (rc);
10530
10531    operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[3], const0_rtx);
10532  }
10533  [(set_attr "conds" "use")
10534   (set_attr "length" "4")
10535   (set_attr "arch" "t2,32")
10536   (set_attr "enabled_for_short_it" "yes,no")
10537   (set_attr "type" "logic_shift_imm")]
10538)
10539
10540(define_insn "*arith_adjacentmem"
10541  [(set (match_operand:SI 0 "s_register_operand" "=r")
10542	(match_operator:SI 1 "shiftable_operator"
10543	 [(match_operand:SI 2 "memory_operand" "m")
10544	  (match_operand:SI 3 "memory_operand" "m")]))
10545   (clobber (match_scratch:SI 4 "=r"))]
10546  "TARGET_ARM && adjacent_mem_locations (operands[2], operands[3])"
10547  "*
10548  {
10549    rtx ldm[3];
10550    rtx arith[4];
10551    rtx base_reg;
10552    HOST_WIDE_INT val1 = 0, val2 = 0;
10553
10554    if (REGNO (operands[0]) > REGNO (operands[4]))
10555      {
10556	ldm[1] = operands[4];
10557	ldm[2] = operands[0];
10558      }
10559    else
10560      {
10561	ldm[1] = operands[0];
10562	ldm[2] = operands[4];
10563      }
10564
10565    base_reg = XEXP (operands[2], 0);
10566
10567    if (!REG_P (base_reg))
10568      {
10569	val1 = INTVAL (XEXP (base_reg, 1));
10570	base_reg = XEXP (base_reg, 0);
10571      }
10572
10573    if (!REG_P (XEXP (operands[3], 0)))
10574      val2 = INTVAL (XEXP (XEXP (operands[3], 0), 1));
10575
10576    arith[0] = operands[0];
10577    arith[3] = operands[1];
10578
10579    if (val1 < val2)
10580      {
10581	arith[1] = ldm[1];
10582	arith[2] = ldm[2];
10583      }
10584    else
10585      {
10586	arith[1] = ldm[2];
10587	arith[2] = ldm[1];
10588      }
10589
10590    ldm[0] = base_reg;
10591    if (val1 !=0 && val2 != 0)
10592      {
10593	rtx ops[3];
10594
10595	if (val1 == 4 || val2 == 4)
10596	  /* Other val must be 8, since we know they are adjacent and neither
10597	     is zero.  */
10598	  output_asm_insn (\"ldmib%?\\t%0, {%1, %2}\", ldm);
10599	else if (const_ok_for_arm (val1) || const_ok_for_arm (-val1))
10600	  {
10601	    ldm[0] = ops[0] = operands[4];
10602	    ops[1] = base_reg;
10603	    ops[2] = GEN_INT (val1);
10604	    output_add_immediate (ops);
10605	    if (val1 < val2)
10606	      output_asm_insn (\"ldmia%?\\t%0, {%1, %2}\", ldm);
10607	    else
10608	      output_asm_insn (\"ldmda%?\\t%0, {%1, %2}\", ldm);
10609	  }
10610	else
10611	  {
10612	    /* Offset is out of range for a single add, so use two ldr.  */
10613	    ops[0] = ldm[1];
10614	    ops[1] = base_reg;
10615	    ops[2] = GEN_INT (val1);
10616	    output_asm_insn (\"ldr%?\\t%0, [%1, %2]\", ops);
10617	    ops[0] = ldm[2];
10618	    ops[2] = GEN_INT (val2);
10619	    output_asm_insn (\"ldr%?\\t%0, [%1, %2]\", ops);
10620	  }
10621      }
10622    else if (val1 != 0)
10623      {
10624	if (val1 < val2)
10625	  output_asm_insn (\"ldmda%?\\t%0, {%1, %2}\", ldm);
10626	else
10627	  output_asm_insn (\"ldmia%?\\t%0, {%1, %2}\", ldm);
10628      }
10629    else
10630      {
10631	if (val1 < val2)
10632	  output_asm_insn (\"ldmia%?\\t%0, {%1, %2}\", ldm);
10633	else
10634	  output_asm_insn (\"ldmda%?\\t%0, {%1, %2}\", ldm);
10635      }
10636    output_asm_insn (\"%I3%?\\t%0, %1, %2\", arith);
10637    return \"\";
10638  }"
10639  [(set_attr "length" "12")
10640   (set_attr "predicable" "yes")
10641   (set_attr "type" "load_4")]
10642)
10643
10644; This pattern is never tried by combine, so do it as a peephole
10645
10646(define_peephole2
10647  [(set (match_operand:SI 0 "arm_general_register_operand" "")
10648	(match_operand:SI 1 "arm_general_register_operand" ""))
10649   (set (reg:CC CC_REGNUM)
10650	(compare:CC (match_dup 1) (const_int 0)))]
10651  "TARGET_ARM"
10652  [(parallel [(set (reg:CC CC_REGNUM) (compare:CC (match_dup 1) (const_int 0)))
10653	      (set (match_dup 0) (match_dup 1))])]
10654  ""
10655)
10656
10657(define_split
10658  [(set (match_operand:SI 0 "s_register_operand" "")
10659	(and:SI (ge:SI (match_operand:SI 1 "s_register_operand" "")
10660		       (const_int 0))
10661		(neg:SI (match_operator:SI 2 "arm_comparison_operator"
10662			 [(match_operand:SI 3 "s_register_operand" "")
10663			  (match_operand:SI 4 "arm_rhs_operand" "")]))))
10664   (clobber (match_operand:SI 5 "s_register_operand" ""))]
10665  "TARGET_ARM"
10666  [(set (match_dup 5) (not:SI (ashiftrt:SI (match_dup 1) (const_int 31))))
10667   (set (match_dup 0) (and:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
10668			      (match_dup 5)))]
10669  ""
10670)
10671
10672;; This split can be used because CC_Z mode implies that the following
10673;; branch will be an equality, or an unsigned inequality, so the sign
10674;; extension is not needed.
10675
10676(define_split
10677  [(set (reg:CC_Z CC_REGNUM)
10678	(compare:CC_Z
10679	 (ashift:SI (subreg:SI (match_operand:QI 0 "memory_operand" "") 0)
10680		    (const_int 24))
10681	 (match_operand 1 "const_int_operand" "")))
10682   (clobber (match_scratch:SI 2 ""))]
10683  "TARGET_ARM
10684   && ((UINTVAL (operands[1]))
10685       == ((UINTVAL (operands[1])) >> 24) << 24)"
10686  [(set (match_dup 2) (zero_extend:SI (match_dup 0)))
10687   (set (reg:CC CC_REGNUM) (compare:CC (match_dup 2) (match_dup 1)))]
10688  "
10689  operands[1] = GEN_INT (((unsigned long) INTVAL (operands[1])) >> 24);
10690  "
10691)
10692;; ??? Check the patterns above for Thumb-2 usefulness
10693
10694(define_expand "prologue"
10695  [(clobber (const_int 0))]
10696  "TARGET_EITHER"
10697  "if (TARGET_32BIT)
10698     arm_expand_prologue ();
10699   else
10700     thumb1_expand_prologue ();
10701  DONE;
10702  "
10703)
10704
10705(define_expand "epilogue"
10706  [(clobber (const_int 0))]
10707  "TARGET_EITHER"
10708  "
10709  if (crtl->calls_eh_return)
10710    emit_insn (gen_force_register_use (gen_rtx_REG (Pmode, 2)));
10711  if (TARGET_THUMB1)
10712   {
10713     thumb1_expand_epilogue ();
10714     emit_jump_insn (gen_rtx_UNSPEC_VOLATILE (VOIDmode,
10715                     gen_rtvec (1, ret_rtx), VUNSPEC_EPILOGUE));
10716   }
10717  else if (HAVE_return)
10718   {
10719     /* HAVE_return is testing for USE_RETURN_INSN (FALSE).  Hence,
10720        no need for explicit testing again.  */
10721     emit_jump_insn (gen_return ());
10722   }
10723  else if (TARGET_32BIT)
10724   {
10725    arm_expand_epilogue (true);
10726   }
10727  DONE;
10728  "
10729)
10730
10731;; Note - although unspec_volatile's USE all hard registers,
10732;; USEs are ignored after relaod has completed.  Thus we need
10733;; to add an unspec of the link register to ensure that flow
10734;; does not think that it is unused by the sibcall branch that
10735;; will replace the standard function epilogue.
10736(define_expand "sibcall_epilogue"
10737   [(parallel [(unspec:SI [(reg:SI LR_REGNUM)] UNSPEC_REGISTER_USE)
10738               (unspec_volatile [(return)] VUNSPEC_EPILOGUE)])]
10739   "TARGET_32BIT"
10740   "
10741   arm_expand_epilogue (false);
10742   DONE;
10743   "
10744)
10745
10746(define_expand "eh_epilogue"
10747  [(use (match_operand:SI 0 "register_operand" ""))
10748   (use (match_operand:SI 1 "register_operand" ""))
10749   (use (match_operand:SI 2 "register_operand" ""))]
10750  "TARGET_EITHER"
10751  "
10752  {
10753    cfun->machine->eh_epilogue_sp_ofs = operands[1];
10754    if (!REG_P (operands[2]) || REGNO (operands[2]) != 2)
10755      {
10756	rtx ra = gen_rtx_REG (Pmode, 2);
10757
10758	emit_move_insn (ra, operands[2]);
10759	operands[2] = ra;
10760      }
10761    /* This is a hack -- we may have crystalized the function type too
10762       early.  */
10763    cfun->machine->func_type = 0;
10764  }"
10765)
10766
10767;; This split is only used during output to reduce the number of patterns
10768;; that need assembler instructions adding to them.  We allowed the setting
10769;; of the conditions to be implicit during rtl generation so that
10770;; the conditional compare patterns would work.  However this conflicts to
10771;; some extent with the conditional data operations, so we have to split them
10772;; up again here.
10773
10774;; ??? Need to audit these splitters for Thumb-2.  Why isn't normal
10775;; conditional execution sufficient?
10776
10777(define_split
10778  [(set (match_operand:SI 0 "s_register_operand" "")
10779	(if_then_else:SI (match_operator 1 "arm_comparison_operator"
10780			  [(match_operand 2 "" "") (match_operand 3 "" "")])
10781			 (match_dup 0)
10782			 (match_operand 4 "" "")))
10783   (clobber (reg:CC CC_REGNUM))]
10784  "TARGET_ARM && reload_completed"
10785  [(set (match_dup 5) (match_dup 6))
10786   (cond_exec (match_dup 7)
10787	      (set (match_dup 0) (match_dup 4)))]
10788  "
10789  {
10790    machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10791					     operands[2], operands[3]);
10792    enum rtx_code rc = GET_CODE (operands[1]);
10793
10794    operands[5] = gen_rtx_REG (mode, CC_REGNUM);
10795    operands[6] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10796    if (mode == CCFPmode || mode == CCFPEmode)
10797      rc = reverse_condition_maybe_unordered (rc);
10798    else
10799      rc = reverse_condition (rc);
10800
10801    operands[7] = gen_rtx_fmt_ee (rc, VOIDmode, operands[5], const0_rtx);
10802  }"
10803)
10804
10805(define_split
10806  [(set (match_operand:SI 0 "s_register_operand" "")
10807	(if_then_else:SI (match_operator 1 "arm_comparison_operator"
10808			  [(match_operand 2 "" "") (match_operand 3 "" "")])
10809			 (match_operand 4 "" "")
10810			 (match_dup 0)))
10811   (clobber (reg:CC CC_REGNUM))]
10812  "TARGET_ARM && reload_completed"
10813  [(set (match_dup 5) (match_dup 6))
10814   (cond_exec (match_op_dup 1 [(match_dup 5) (const_int 0)])
10815	      (set (match_dup 0) (match_dup 4)))]
10816  "
10817  {
10818    machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10819					     operands[2], operands[3]);
10820
10821    operands[5] = gen_rtx_REG (mode, CC_REGNUM);
10822    operands[6] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10823  }"
10824)
10825
10826(define_split
10827  [(set (match_operand:SI 0 "s_register_operand" "")
10828	(if_then_else:SI (match_operator 1 "arm_comparison_operator"
10829			  [(match_operand 2 "" "") (match_operand 3 "" "")])
10830			 (match_operand 4 "" "")
10831			 (match_operand 5 "" "")))
10832   (clobber (reg:CC CC_REGNUM))]
10833  "TARGET_ARM && reload_completed"
10834  [(set (match_dup 6) (match_dup 7))
10835   (cond_exec (match_op_dup 1 [(match_dup 6) (const_int 0)])
10836	      (set (match_dup 0) (match_dup 4)))
10837   (cond_exec (match_dup 8)
10838	      (set (match_dup 0) (match_dup 5)))]
10839  "
10840  {
10841    machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10842					     operands[2], operands[3]);
10843    enum rtx_code rc = GET_CODE (operands[1]);
10844
10845    operands[6] = gen_rtx_REG (mode, CC_REGNUM);
10846    operands[7] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10847    if (mode == CCFPmode || mode == CCFPEmode)
10848      rc = reverse_condition_maybe_unordered (rc);
10849    else
10850      rc = reverse_condition (rc);
10851
10852    operands[8] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
10853  }"
10854)
10855
10856(define_split
10857  [(set (match_operand:SI 0 "s_register_operand" "")
10858	(if_then_else:SI (match_operator 1 "arm_comparison_operator"
10859			  [(match_operand:SI 2 "s_register_operand" "")
10860			   (match_operand:SI 3 "arm_add_operand" "")])
10861			 (match_operand:SI 4 "arm_rhs_operand" "")
10862			 (not:SI
10863			  (match_operand:SI 5 "s_register_operand" ""))))
10864   (clobber (reg:CC CC_REGNUM))]
10865  "TARGET_ARM && reload_completed"
10866  [(set (match_dup 6) (match_dup 7))
10867   (cond_exec (match_op_dup 1 [(match_dup 6) (const_int 0)])
10868	      (set (match_dup 0) (match_dup 4)))
10869   (cond_exec (match_dup 8)
10870	      (set (match_dup 0) (not:SI (match_dup 5))))]
10871  "
10872  {
10873    machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10874					     operands[2], operands[3]);
10875    enum rtx_code rc = GET_CODE (operands[1]);
10876
10877    operands[6] = gen_rtx_REG (mode, CC_REGNUM);
10878    operands[7] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10879    if (mode == CCFPmode || mode == CCFPEmode)
10880      rc = reverse_condition_maybe_unordered (rc);
10881    else
10882      rc = reverse_condition (rc);
10883
10884    operands[8] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
10885  }"
10886)
10887
10888(define_insn "*cond_move_not"
10889  [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10890	(if_then_else:SI (match_operator 4 "arm_comparison_operator"
10891			  [(match_operand 3 "cc_register" "") (const_int 0)])
10892			 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
10893			 (not:SI
10894			  (match_operand:SI 2 "s_register_operand" "r,r"))))]
10895  "TARGET_ARM"
10896  "@
10897   mvn%D4\\t%0, %2
10898   mov%d4\\t%0, %1\;mvn%D4\\t%0, %2"
10899  [(set_attr "conds" "use")
10900   (set_attr "type" "mvn_reg,multiple")
10901   (set_attr "length" "4,8")]
10902)
10903
10904;; The next two patterns occur when an AND operation is followed by a
10905;; scc insn sequence
10906
10907(define_insn "*sign_extract_onebit"
10908  [(set (match_operand:SI 0 "s_register_operand" "=r")
10909	(sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
10910			 (const_int 1)
10911			 (match_operand:SI 2 "const_int_operand" "n")))
10912    (clobber (reg:CC CC_REGNUM))]
10913  "TARGET_ARM"
10914  "*
10915    operands[2] = GEN_INT (1 << INTVAL (operands[2]));
10916    output_asm_insn (\"ands\\t%0, %1, %2\", operands);
10917    return \"mvnne\\t%0, #0\";
10918  "
10919  [(set_attr "conds" "clob")
10920   (set_attr "length" "8")
10921   (set_attr "type" "multiple")]
10922)
10923
10924(define_insn "*not_signextract_onebit"
10925  [(set (match_operand:SI 0 "s_register_operand" "=r")
10926	(not:SI
10927	 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
10928			  (const_int 1)
10929			  (match_operand:SI 2 "const_int_operand" "n"))))
10930   (clobber (reg:CC CC_REGNUM))]
10931  "TARGET_ARM"
10932  "*
10933    operands[2] = GEN_INT (1 << INTVAL (operands[2]));
10934    output_asm_insn (\"tst\\t%1, %2\", operands);
10935    output_asm_insn (\"mvneq\\t%0, #0\", operands);
10936    return \"movne\\t%0, #0\";
10937  "
10938  [(set_attr "conds" "clob")
10939   (set_attr "length" "12")
10940   (set_attr "type" "multiple")]
10941)
10942;; ??? The above patterns need auditing for Thumb-2
10943
10944;; Push multiple registers to the stack.  Registers are in parallel (use ...)
10945;; expressions.  For simplicity, the first register is also in the unspec
10946;; part.
10947;; To avoid the usage of GNU extension, the length attribute is computed
10948;; in a C function arm_attr_length_push_multi.
10949(define_insn "*push_multi"
10950  [(match_parallel 2 "multi_register_push"
10951    [(set (match_operand:BLK 0 "push_mult_memory_operand" "")
10952	  (unspec:BLK [(match_operand:SI 1 "s_register_operand" "")]
10953		      UNSPEC_PUSH_MULT))])]
10954  ""
10955  "*
10956  {
10957    int num_saves = XVECLEN (operands[2], 0);
10958
10959    /* For the StrongARM at least it is faster to
10960       use STR to store only a single register.
10961       In Thumb mode always use push, and the assembler will pick
10962       something appropriate.  */
10963    if (num_saves == 1 && TARGET_ARM)
10964      output_asm_insn (\"str%?\\t%1, [%m0, #-4]!\", operands);
10965    else
10966      {
10967	int i;
10968	char pattern[100];
10969
10970	if (TARGET_32BIT)
10971	    strcpy (pattern, \"push%?\\t{%1\");
10972	else
10973	    strcpy (pattern, \"push\\t{%1\");
10974
10975	for (i = 1; i < num_saves; i++)
10976	  {
10977	    strcat (pattern, \", %|\");
10978	    strcat (pattern,
10979		    reg_names[REGNO (XEXP (XVECEXP (operands[2], 0, i), 0))]);
10980	  }
10981
10982	strcat (pattern, \"}\");
10983	output_asm_insn (pattern, operands);
10984      }
10985
10986    return \"\";
10987  }"
10988  [(set_attr "type" "store_16")
10989   (set (attr "length")
10990	(symbol_ref "arm_attr_length_push_multi (operands[2], operands[1])"))]
10991)
10992
10993(define_insn "stack_tie"
10994  [(set (mem:BLK (scratch))
10995	(unspec:BLK [(match_operand:SI 0 "s_register_operand" "rk")
10996		     (match_operand:SI 1 "s_register_operand" "rk")]
10997		    UNSPEC_PRLG_STK))]
10998  ""
10999  ""
11000  [(set_attr "length" "0")
11001   (set_attr "type" "block")]
11002)
11003
11004;; Pop (as used in epilogue RTL)
11005;;
11006(define_insn "*load_multiple_with_writeback"
11007  [(match_parallel 0 "load_multiple_operation"
11008    [(set (match_operand:SI 1 "s_register_operand" "+rk")
11009          (plus:SI (match_dup 1)
11010                   (match_operand:SI 2 "const_int_I_operand" "I")))
11011     (set (match_operand:SI 3 "s_register_operand" "=rk")
11012          (mem:SI (match_dup 1)))
11013        ])]
11014  "TARGET_32BIT && (reload_in_progress || reload_completed)"
11015  "*
11016  {
11017    arm_output_multireg_pop (operands, /*return_pc=*/false,
11018                                       /*cond=*/const_true_rtx,
11019                                       /*reverse=*/false,
11020                                       /*update=*/true);
11021    return \"\";
11022  }
11023  "
11024  [(set_attr "type" "load_16")
11025   (set_attr "predicable" "yes")
11026   (set (attr "length")
11027	(symbol_ref "arm_attr_length_pop_multi (operands,
11028						/*return_pc=*/false,
11029						/*write_back_p=*/true)"))]
11030)
11031
11032;; Pop with return (as used in epilogue RTL)
11033;;
11034;; This instruction is generated when the registers are popped at the end of
11035;; epilogue.  Here, instead of popping the value into LR and then generating
11036;; jump to LR, value is popped into PC directly.  Hence, the pattern is combined
11037;;  with (return).
11038(define_insn "*pop_multiple_with_writeback_and_return"
11039  [(match_parallel 0 "pop_multiple_return"
11040    [(return)
11041     (set (match_operand:SI 1 "s_register_operand" "+rk")
11042          (plus:SI (match_dup 1)
11043                   (match_operand:SI 2 "const_int_I_operand" "I")))
11044     (set (match_operand:SI 3 "s_register_operand" "=rk")
11045          (mem:SI (match_dup 1)))
11046        ])]
11047  "TARGET_32BIT && (reload_in_progress || reload_completed)"
11048  "*
11049  {
11050    arm_output_multireg_pop (operands, /*return_pc=*/true,
11051                                       /*cond=*/const_true_rtx,
11052                                       /*reverse=*/false,
11053                                       /*update=*/true);
11054    return \"\";
11055  }
11056  "
11057  [(set_attr "type" "load_16")
11058   (set_attr "predicable" "yes")
11059   (set (attr "length")
11060	(symbol_ref "arm_attr_length_pop_multi (operands, /*return_pc=*/true,
11061						/*write_back_p=*/true)"))]
11062)
11063
11064(define_insn "*pop_multiple_with_return"
11065  [(match_parallel 0 "pop_multiple_return"
11066    [(return)
11067     (set (match_operand:SI 2 "s_register_operand" "=rk")
11068          (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
11069        ])]
11070  "TARGET_32BIT && (reload_in_progress || reload_completed)"
11071  "*
11072  {
11073    arm_output_multireg_pop (operands, /*return_pc=*/true,
11074                                       /*cond=*/const_true_rtx,
11075                                       /*reverse=*/false,
11076                                       /*update=*/false);
11077    return \"\";
11078  }
11079  "
11080  [(set_attr "type" "load_16")
11081   (set_attr "predicable" "yes")
11082   (set (attr "length")
11083	(symbol_ref "arm_attr_length_pop_multi (operands, /*return_pc=*/true,
11084						/*write_back_p=*/false)"))]
11085)
11086
11087;; Load into PC and return
11088(define_insn "*ldr_with_return"
11089  [(return)
11090   (set (reg:SI PC_REGNUM)
11091        (mem:SI (post_inc:SI (match_operand:SI 0 "s_register_operand" "+rk"))))]
11092  "TARGET_32BIT && (reload_in_progress || reload_completed)"
11093  "ldr%?\t%|pc, [%0], #4"
11094  [(set_attr "type" "load_4")
11095   (set_attr "predicable" "yes")]
11096)
11097;; Pop for floating point registers (as used in epilogue RTL)
11098(define_insn "*vfp_pop_multiple_with_writeback"
11099  [(match_parallel 0 "pop_multiple_fp"
11100    [(set (match_operand:SI 1 "s_register_operand" "+rk")
11101          (plus:SI (match_dup 1)
11102                   (match_operand:SI 2 "const_int_I_operand" "I")))
11103     (set (match_operand:DF 3 "vfp_hard_register_operand" "")
11104          (mem:DF (match_dup 1)))])]
11105  "TARGET_32BIT && TARGET_HARD_FLOAT"
11106  "*
11107  {
11108    int num_regs = XVECLEN (operands[0], 0);
11109    char pattern[100];
11110    rtx op_list[2];
11111    strcpy (pattern, \"vldm\\t\");
11112    strcat (pattern, reg_names[REGNO (SET_DEST (XVECEXP (operands[0], 0, 0)))]);
11113    strcat (pattern, \"!, {\");
11114    op_list[0] = XEXP (XVECEXP (operands[0], 0, 1), 0);
11115    strcat (pattern, \"%P0\");
11116    if ((num_regs - 1) > 1)
11117      {
11118        strcat (pattern, \"-%P1\");
11119        op_list [1] = XEXP (XVECEXP (operands[0], 0, num_regs - 1), 0);
11120      }
11121
11122    strcat (pattern, \"}\");
11123    output_asm_insn (pattern, op_list);
11124    return \"\";
11125  }
11126  "
11127  [(set_attr "type" "load_16")
11128   (set_attr "conds" "unconditional")
11129   (set_attr "predicable" "no")]
11130)
11131
11132;; Special patterns for dealing with the constant pool
11133
11134(define_insn "align_4"
11135  [(unspec_volatile [(const_int 0)] VUNSPEC_ALIGN)]
11136  "TARGET_EITHER"
11137  "*
11138  assemble_align (32);
11139  return \"\";
11140  "
11141  [(set_attr "type" "no_insn")]
11142)
11143
11144(define_insn "align_8"
11145  [(unspec_volatile [(const_int 0)] VUNSPEC_ALIGN8)]
11146  "TARGET_EITHER"
11147  "*
11148  assemble_align (64);
11149  return \"\";
11150  "
11151  [(set_attr "type" "no_insn")]
11152)
11153
11154(define_insn "consttable_end"
11155  [(unspec_volatile [(const_int 0)] VUNSPEC_POOL_END)]
11156  "TARGET_EITHER"
11157  "*
11158  making_const_table = FALSE;
11159  return \"\";
11160  "
11161  [(set_attr "type" "no_insn")]
11162)
11163
11164(define_insn "consttable_1"
11165  [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_1)]
11166  "TARGET_EITHER"
11167  "*
11168  making_const_table = TRUE;
11169  assemble_integer (operands[0], 1, BITS_PER_WORD, 1);
11170  assemble_zeros (3);
11171  return \"\";
11172  "
11173  [(set_attr "length" "4")
11174   (set_attr "type" "no_insn")]
11175)
11176
11177(define_insn "consttable_2"
11178  [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_2)]
11179  "TARGET_EITHER"
11180  "*
11181  {
11182    rtx x = operands[0];
11183    making_const_table = TRUE;
11184    switch (GET_MODE_CLASS (GET_MODE (x)))
11185      {
11186      case MODE_FLOAT:
11187	arm_emit_fp16_const (x);
11188	break;
11189      default:
11190	assemble_integer (operands[0], 2, BITS_PER_WORD, 1);
11191	assemble_zeros (2);
11192	break;
11193      }
11194    return \"\";
11195  }"
11196  [(set_attr "length" "4")
11197   (set_attr "type" "no_insn")]
11198)
11199
11200(define_insn "consttable_4"
11201  [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_4)]
11202  "TARGET_EITHER"
11203  "*
11204  {
11205    rtx x = operands[0];
11206    making_const_table = TRUE;
11207    scalar_float_mode float_mode;
11208    if (is_a <scalar_float_mode> (GET_MODE (x), &float_mode))
11209      assemble_real (*CONST_DOUBLE_REAL_VALUE (x), float_mode, BITS_PER_WORD);
11210    else
11211      {
11212	/* XXX: Sometimes gcc does something really dumb and ends up with
11213	   a HIGH in a constant pool entry, usually because it's trying to
11214	   load into a VFP register.  We know this will always be used in
11215	   combination with a LO_SUM which ignores the high bits, so just
11216	   strip off the HIGH.  */
11217	if (GET_CODE (x) == HIGH)
11218	  x = XEXP (x, 0);
11219        assemble_integer (x, 4, BITS_PER_WORD, 1);
11220	mark_symbol_refs_as_used (x);
11221      }
11222    return \"\";
11223  }"
11224  [(set_attr "length" "4")
11225   (set_attr "type" "no_insn")]
11226)
11227
11228(define_insn "consttable_8"
11229  [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_8)]
11230  "TARGET_EITHER"
11231  "*
11232  {
11233    making_const_table = TRUE;
11234    scalar_float_mode float_mode;
11235    if (is_a <scalar_float_mode> (GET_MODE (operands[0]), &float_mode))
11236      assemble_real (*CONST_DOUBLE_REAL_VALUE (operands[0]),
11237		     float_mode, BITS_PER_WORD);
11238    else
11239      assemble_integer (operands[0], 8, BITS_PER_WORD, 1);
11240    return \"\";
11241  }"
11242  [(set_attr "length" "8")
11243   (set_attr "type" "no_insn")]
11244)
11245
11246(define_insn "consttable_16"
11247  [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_16)]
11248  "TARGET_EITHER"
11249  "*
11250  {
11251    making_const_table = TRUE;
11252    scalar_float_mode float_mode;
11253    if (is_a <scalar_float_mode> (GET_MODE (operands[0]), &float_mode))
11254      assemble_real (*CONST_DOUBLE_REAL_VALUE (operands[0]),
11255		     float_mode, BITS_PER_WORD);
11256    else
11257      assemble_integer (operands[0], 16, BITS_PER_WORD, 1);
11258    return \"\";
11259  }"
11260  [(set_attr "length" "16")
11261   (set_attr "type" "no_insn")]
11262)
11263
11264;; V5 Instructions,
11265
11266(define_insn "clzsi2"
11267  [(set (match_operand:SI 0 "s_register_operand" "=r")
11268	(clz:SI (match_operand:SI 1 "s_register_operand" "r")))]
11269  "TARGET_32BIT && arm_arch5"
11270  "clz%?\\t%0, %1"
11271  [(set_attr "predicable" "yes")
11272   (set_attr "type" "clz")])
11273
11274(define_insn "rbitsi2"
11275  [(set (match_operand:SI 0 "s_register_operand" "=r")
11276	(unspec:SI [(match_operand:SI 1 "s_register_operand" "r")] UNSPEC_RBIT))]
11277  "TARGET_32BIT && arm_arch_thumb2"
11278  "rbit%?\\t%0, %1"
11279  [(set_attr "predicable" "yes")
11280   (set_attr "type" "clz")])
11281
11282;; Keep this as a CTZ expression until after reload and then split
11283;; into RBIT + CLZ.  Since RBIT is represented as an UNSPEC it is unlikely
11284;; to fold with any other expression.
11285
11286(define_insn_and_split "ctzsi2"
11287 [(set (match_operand:SI           0 "s_register_operand" "=r")
11288       (ctz:SI (match_operand:SI  1 "s_register_operand" "r")))]
11289  "TARGET_32BIT && arm_arch_thumb2"
11290  "#"
11291  "&& reload_completed"
11292  [(const_int 0)]
11293  "
11294  emit_insn (gen_rbitsi2 (operands[0], operands[1]));
11295  emit_insn (gen_clzsi2 (operands[0], operands[0]));
11296  DONE;
11297")
11298
11299;; V5E instructions.
11300
11301(define_insn "prefetch"
11302  [(prefetch (match_operand:SI 0 "address_operand" "p")
11303	     (match_operand:SI 1 "" "")
11304	     (match_operand:SI 2 "" ""))]
11305  "TARGET_32BIT && arm_arch5e"
11306  "pld\\t%a0"
11307  [(set_attr "type" "load_4")]
11308)
11309
11310;; General predication pattern
11311
11312(define_cond_exec
11313  [(match_operator 0 "arm_comparison_operator"
11314    [(match_operand 1 "cc_register" "")
11315     (const_int 0)])]
11316  "TARGET_32BIT
11317   && (!TARGET_NO_VOLATILE_CE || !volatile_refs_p (PATTERN (insn)))"
11318  ""
11319[(set_attr "predicated" "yes")]
11320)
11321
11322(define_insn "force_register_use"
11323  [(unspec:SI [(match_operand:SI 0 "register_operand" "")] UNSPEC_REGISTER_USE)]
11324  ""
11325  "%@ %0 needed"
11326  [(set_attr "length" "0")
11327   (set_attr "type" "no_insn")]
11328)
11329
11330
11331;; Patterns for exception handling
11332
11333(define_expand "eh_return"
11334  [(use (match_operand 0 "general_operand" ""))]
11335  "TARGET_EITHER"
11336  "
11337  {
11338    if (TARGET_32BIT)
11339      emit_insn (gen_arm_eh_return (operands[0]));
11340    else
11341      emit_insn (gen_thumb_eh_return (operands[0]));
11342    DONE;
11343  }"
11344)
11345
11346;; We can't expand this before we know where the link register is stored.
11347(define_insn_and_split "arm_eh_return"
11348  [(unspec_volatile [(match_operand:SI 0 "s_register_operand" "r")]
11349		    VUNSPEC_EH_RETURN)
11350   (clobber (match_scratch:SI 1 "=&r"))]
11351  "TARGET_ARM"
11352  "#"
11353  "&& reload_completed"
11354  [(const_int 0)]
11355  "
11356  {
11357    arm_set_return_address (operands[0], operands[1]);
11358    DONE;
11359  }"
11360)
11361
11362
11363;; TLS support
11364
11365(define_insn "load_tp_hard"
11366  [(set (match_operand:SI 0 "register_operand" "=r")
11367	(unspec:SI [(const_int 0)] UNSPEC_TLS))]
11368  "TARGET_HARD_TP"
11369  "mrc%?\\tp15, 0, %0, c13, c0, 3\\t@ load_tp_hard"
11370  [(set_attr "predicable" "yes")
11371   (set_attr "type" "mrs")]
11372)
11373
11374;; Doesn't clobber R1-R3.  Must use r0 for the first operand.
11375(define_insn "load_tp_soft"
11376  [(set (reg:SI 0) (unspec:SI [(const_int 0)] UNSPEC_TLS))
11377   (clobber (reg:SI LR_REGNUM))
11378   (clobber (reg:SI IP_REGNUM))
11379   (clobber (reg:CC CC_REGNUM))]
11380  "TARGET_SOFT_TP"
11381  "bl\\t__aeabi_read_tp\\t@ load_tp_soft"
11382  [(set_attr "conds" "clob")
11383   (set_attr "type" "branch")]
11384)
11385
11386;; tls descriptor call
11387(define_insn "tlscall"
11388  [(set (reg:SI R0_REGNUM)
11389        (unspec:SI [(reg:SI R0_REGNUM)
11390                    (match_operand:SI 0 "" "X")
11391	            (match_operand 1 "" "")] UNSPEC_TLS))
11392   (clobber (reg:SI R1_REGNUM))
11393   (clobber (reg:SI LR_REGNUM))
11394   (clobber (reg:SI CC_REGNUM))]
11395  "TARGET_GNU2_TLS"
11396  {
11397    targetm.asm_out.internal_label (asm_out_file, "LPIC",
11398				    INTVAL (operands[1]));
11399    return "bl\\t%c0(tlscall)";
11400  }
11401  [(set_attr "conds" "clob")
11402   (set_attr "length" "4")
11403   (set_attr "type" "branch")]
11404)
11405
11406;; For thread pointer builtin
11407(define_expand "get_thread_pointersi"
11408  [(match_operand:SI 0 "s_register_operand" "=r")]
11409 ""
11410 "
11411 {
11412   arm_load_tp (operands[0]);
11413   DONE;
11414 }")
11415
11416;;
11417
11418;; We only care about the lower 16 bits of the constant
11419;; being inserted into the upper 16 bits of the register.
11420(define_insn "*arm_movtas_ze"
11421  [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r,r")
11422                   (const_int 16)
11423                   (const_int 16))
11424        (match_operand:SI 1 "const_int_operand" ""))]
11425  "TARGET_HAVE_MOVT"
11426  "@
11427   movt%?\t%0, %L1
11428   movt\t%0, %L1"
11429 [(set_attr "arch" "32,v8mb")
11430  (set_attr "predicable" "yes")
11431  (set_attr "length" "4")
11432  (set_attr "type" "alu_sreg")]
11433)
11434
11435(define_insn "*arm_rev"
11436  [(set (match_operand:SI 0 "s_register_operand" "=l,l,r")
11437	(bswap:SI (match_operand:SI 1 "s_register_operand" "l,l,r")))]
11438  "arm_arch6"
11439  "@
11440   rev\t%0, %1
11441   rev%?\t%0, %1
11442   rev%?\t%0, %1"
11443  [(set_attr "arch" "t1,t2,32")
11444   (set_attr "length" "2,2,4")
11445   (set_attr "predicable" "no,yes,yes")
11446   (set_attr "type" "rev")]
11447)
11448
11449(define_expand "arm_legacy_rev"
11450  [(set (match_operand:SI 2 "s_register_operand" "")
11451	(xor:SI (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
11452			     (const_int 16))
11453		(match_dup 1)))
11454   (set (match_dup 2)
11455	(lshiftrt:SI (match_dup 2)
11456		     (const_int 8)))
11457   (set (match_operand:SI 3 "s_register_operand" "")
11458	(rotatert:SI (match_dup 1)
11459		     (const_int 8)))
11460   (set (match_dup 2)
11461	(and:SI (match_dup 2)
11462		(const_int -65281)))
11463   (set (match_operand:SI 0 "s_register_operand" "")
11464	(xor:SI (match_dup 3)
11465		(match_dup 2)))]
11466  "TARGET_32BIT"
11467  ""
11468)
11469
11470;; Reuse temporaries to keep register pressure down.
11471(define_expand "thumb_legacy_rev"
11472  [(set (match_operand:SI 2 "s_register_operand" "")
11473     (ashift:SI (match_operand:SI 1 "s_register_operand" "")
11474                (const_int 24)))
11475   (set (match_operand:SI 3 "s_register_operand" "")
11476     (lshiftrt:SI (match_dup 1)
11477		  (const_int 24)))
11478   (set (match_dup 3)
11479     (ior:SI (match_dup 3)
11480	     (match_dup 2)))
11481   (set (match_operand:SI 4 "s_register_operand" "")
11482     (const_int 16))
11483   (set (match_operand:SI 5 "s_register_operand" "")
11484     (rotatert:SI (match_dup 1)
11485		  (match_dup 4)))
11486   (set (match_dup 2)
11487     (ashift:SI (match_dup 5)
11488                (const_int 24)))
11489   (set (match_dup 5)
11490     (lshiftrt:SI (match_dup 5)
11491		  (const_int 24)))
11492   (set (match_dup 5)
11493     (ior:SI (match_dup 5)
11494	     (match_dup 2)))
11495   (set (match_dup 5)
11496     (rotatert:SI (match_dup 5)
11497		  (match_dup 4)))
11498   (set (match_operand:SI 0 "s_register_operand" "")
11499     (ior:SI (match_dup 5)
11500             (match_dup 3)))]
11501  "TARGET_THUMB"
11502  ""
11503)
11504
11505;; ARM-specific expansion of signed mod by power of 2
11506;; using conditional negate.
11507;; For r0 % n where n is a power of 2 produce:
11508;; rsbs    r1, r0, #0
11509;; and     r0, r0, #(n - 1)
11510;; and     r1, r1, #(n - 1)
11511;; rsbpl   r0, r1, #0
11512
11513(define_expand "modsi3"
11514  [(match_operand:SI 0 "register_operand" "")
11515   (match_operand:SI 1 "register_operand" "")
11516   (match_operand:SI 2 "const_int_operand" "")]
11517  "TARGET_32BIT"
11518  {
11519    HOST_WIDE_INT val = INTVAL (operands[2]);
11520
11521    if (val <= 0
11522       || exact_log2 (val) <= 0)
11523      FAIL;
11524
11525    rtx mask = GEN_INT (val - 1);
11526
11527    /* In the special case of x0 % 2 we can do the even shorter:
11528	cmp     r0, #0
11529	and     r0, r0, #1
11530	rsblt   r0, r0, #0.  */
11531
11532    if (val == 2)
11533      {
11534	rtx cc_reg = arm_gen_compare_reg (LT,
11535					  operands[1], const0_rtx, NULL_RTX);
11536	rtx cond = gen_rtx_LT (SImode, cc_reg, const0_rtx);
11537	rtx masked = gen_reg_rtx (SImode);
11538
11539	emit_insn (gen_andsi3 (masked, operands[1], mask));
11540	emit_move_insn (operands[0],
11541			gen_rtx_IF_THEN_ELSE (SImode, cond,
11542					      gen_rtx_NEG (SImode,
11543							   masked),
11544					      masked));
11545	DONE;
11546      }
11547
11548    rtx neg_op = gen_reg_rtx (SImode);
11549    rtx_insn *insn = emit_insn (gen_subsi3_compare0 (neg_op, const0_rtx,
11550						      operands[1]));
11551
11552    /* Extract the condition register and mode.  */
11553    rtx cmp = XVECEXP (PATTERN (insn), 0, 0);
11554    rtx cc_reg = SET_DEST (cmp);
11555    rtx cond = gen_rtx_GE (SImode, cc_reg, const0_rtx);
11556
11557    emit_insn (gen_andsi3 (operands[0], operands[1], mask));
11558
11559    rtx masked_neg = gen_reg_rtx (SImode);
11560    emit_insn (gen_andsi3 (masked_neg, neg_op, mask));
11561
11562    /* We want a conditional negate here, but emitting COND_EXEC rtxes
11563       during expand does not always work.  Do an IF_THEN_ELSE instead.  */
11564    emit_move_insn (operands[0],
11565		    gen_rtx_IF_THEN_ELSE (SImode, cond,
11566					  gen_rtx_NEG (SImode, masked_neg),
11567					  operands[0]));
11568
11569
11570    DONE;
11571  }
11572)
11573
11574(define_expand "bswapsi2"
11575  [(set (match_operand:SI 0 "s_register_operand" "=r")
11576  	(bswap:SI (match_operand:SI 1 "s_register_operand" "r")))]
11577"TARGET_EITHER && (arm_arch6 || !optimize_size)"
11578"
11579    if (!arm_arch6)
11580      {
11581	rtx op2 = gen_reg_rtx (SImode);
11582	rtx op3 = gen_reg_rtx (SImode);
11583
11584	if (TARGET_THUMB)
11585	  {
11586	    rtx op4 = gen_reg_rtx (SImode);
11587	    rtx op5 = gen_reg_rtx (SImode);
11588
11589	    emit_insn (gen_thumb_legacy_rev (operands[0], operands[1],
11590					     op2, op3, op4, op5));
11591	  }
11592	else
11593	  {
11594	    emit_insn (gen_arm_legacy_rev (operands[0], operands[1],
11595					   op2, op3));
11596	  }
11597
11598	DONE;
11599      }
11600  "
11601)
11602
11603;; bswap16 patterns: use revsh and rev16 instructions for the signed
11604;; and unsigned variants, respectively. For rev16, expose
11605;; byte-swapping in the lower 16 bits only.
11606(define_insn "*arm_revsh"
11607  [(set (match_operand:SI 0 "s_register_operand" "=l,l,r")
11608	(sign_extend:SI (bswap:HI (match_operand:HI 1 "s_register_operand" "l,l,r"))))]
11609  "arm_arch6"
11610  "@
11611  revsh\t%0, %1
11612  revsh%?\t%0, %1
11613  revsh%?\t%0, %1"
11614  [(set_attr "arch" "t1,t2,32")
11615   (set_attr "length" "2,2,4")
11616   (set_attr "type" "rev")]
11617)
11618
11619(define_insn "*arm_rev16"
11620  [(set (match_operand:HI 0 "s_register_operand" "=l,l,r")
11621	(bswap:HI (match_operand:HI 1 "s_register_operand" "l,l,r")))]
11622  "arm_arch6"
11623  "@
11624   rev16\t%0, %1
11625   rev16%?\t%0, %1
11626   rev16%?\t%0, %1"
11627  [(set_attr "arch" "t1,t2,32")
11628   (set_attr "length" "2,2,4")
11629   (set_attr "type" "rev")]
11630)
11631
11632;; There are no canonicalisation rules for the position of the lshiftrt, ashift
11633;; operations within an IOR/AND RTX, therefore we have two patterns matching
11634;; each valid permutation.
11635
11636(define_insn "arm_rev16si2"
11637  [(set (match_operand:SI 0 "register_operand" "=l,l,r")
11638        (ior:SI (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "l,l,r")
11639                                   (const_int 8))
11640                        (match_operand:SI 3 "const_int_operand" "n,n,n"))
11641                (and:SI (lshiftrt:SI (match_dup 1)
11642                                     (const_int 8))
11643                        (match_operand:SI 2 "const_int_operand" "n,n,n"))))]
11644  "arm_arch6
11645   && aarch_rev16_shleft_mask_imm_p (operands[3], SImode)
11646   && aarch_rev16_shright_mask_imm_p (operands[2], SImode)"
11647  "rev16\\t%0, %1"
11648  [(set_attr "arch" "t1,t2,32")
11649   (set_attr "length" "2,2,4")
11650   (set_attr "type" "rev")]
11651)
11652
11653(define_insn "arm_rev16si2_alt"
11654  [(set (match_operand:SI 0 "register_operand" "=l,l,r")
11655        (ior:SI (and:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "l,l,r")
11656                                     (const_int 8))
11657                        (match_operand:SI 2 "const_int_operand" "n,n,n"))
11658                (and:SI (ashift:SI (match_dup 1)
11659                                   (const_int 8))
11660                        (match_operand:SI 3 "const_int_operand" "n,n,n"))))]
11661  "arm_arch6
11662   && aarch_rev16_shleft_mask_imm_p (operands[3], SImode)
11663   && aarch_rev16_shright_mask_imm_p (operands[2], SImode)"
11664  "rev16\\t%0, %1"
11665  [(set_attr "arch" "t1,t2,32")
11666   (set_attr "length" "2,2,4")
11667   (set_attr "type" "rev")]
11668)
11669
11670(define_expand "bswaphi2"
11671  [(set (match_operand:HI 0 "s_register_operand" "=r")
11672	(bswap:HI (match_operand:HI 1 "s_register_operand" "r")))]
11673"arm_arch6"
11674""
11675)
11676
11677;; Patterns for LDRD/STRD in Thumb2 mode
11678
11679(define_insn "*thumb2_ldrd"
11680  [(set (match_operand:SI 0 "s_register_operand" "=r")
11681        (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "rk")
11682                         (match_operand:SI 2 "ldrd_strd_offset_operand" "Do"))))
11683   (set (match_operand:SI 3 "s_register_operand" "=r")
11684        (mem:SI (plus:SI (match_dup 1)
11685                         (match_operand:SI 4 "const_int_operand" ""))))]
11686  "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11687     && ((INTVAL (operands[2]) + 4) == INTVAL (operands[4]))
11688     && (operands_ok_ldrd_strd (operands[0], operands[3],
11689                                  operands[1], INTVAL (operands[2]),
11690                                  false, true))"
11691  "ldrd%?\t%0, %3, [%1, %2]"
11692  [(set_attr "type" "load_8")
11693   (set_attr "predicable" "yes")])
11694
11695(define_insn "*thumb2_ldrd_base"
11696  [(set (match_operand:SI 0 "s_register_operand" "=r")
11697        (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
11698   (set (match_operand:SI 2 "s_register_operand" "=r")
11699        (mem:SI (plus:SI (match_dup 1)
11700                         (const_int 4))))]
11701  "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11702     && (operands_ok_ldrd_strd (operands[0], operands[2],
11703                                  operands[1], 0, false, true))"
11704  "ldrd%?\t%0, %2, [%1]"
11705  [(set_attr "type" "load_8")
11706   (set_attr "predicable" "yes")])
11707
11708(define_insn "*thumb2_ldrd_base_neg"
11709  [(set (match_operand:SI 0 "s_register_operand" "=r")
11710	(mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "rk")
11711                         (const_int -4))))
11712   (set (match_operand:SI 2 "s_register_operand" "=r")
11713        (mem:SI (match_dup 1)))]
11714  "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11715     && (operands_ok_ldrd_strd (operands[0], operands[2],
11716                                  operands[1], -4, false, true))"
11717  "ldrd%?\t%0, %2, [%1, #-4]"
11718  [(set_attr "type" "load_8")
11719   (set_attr "predicable" "yes")])
11720
11721(define_insn "*thumb2_strd"
11722  [(set (mem:SI (plus:SI (match_operand:SI 0 "s_register_operand" "rk")
11723                         (match_operand:SI 1 "ldrd_strd_offset_operand" "Do")))
11724        (match_operand:SI 2 "s_register_operand" "r"))
11725   (set (mem:SI (plus:SI (match_dup 0)
11726                         (match_operand:SI 3 "const_int_operand" "")))
11727        (match_operand:SI 4 "s_register_operand" "r"))]
11728  "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11729     && ((INTVAL (operands[1]) + 4) == INTVAL (operands[3]))
11730     && (operands_ok_ldrd_strd (operands[2], operands[4],
11731                                  operands[0], INTVAL (operands[1]),
11732                                  false, false))"
11733  "strd%?\t%2, %4, [%0, %1]"
11734  [(set_attr "type" "store_8")
11735   (set_attr "predicable" "yes")])
11736
11737(define_insn "*thumb2_strd_base"
11738  [(set (mem:SI (match_operand:SI 0 "s_register_operand" "rk"))
11739        (match_operand:SI 1 "s_register_operand" "r"))
11740   (set (mem:SI (plus:SI (match_dup 0)
11741                         (const_int 4)))
11742        (match_operand:SI 2 "s_register_operand" "r"))]
11743  "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11744     && (operands_ok_ldrd_strd (operands[1], operands[2],
11745                                  operands[0], 0, false, false))"
11746  "strd%?\t%1, %2, [%0]"
11747  [(set_attr "type" "store_8")
11748   (set_attr "predicable" "yes")])
11749
11750(define_insn "*thumb2_strd_base_neg"
11751  [(set (mem:SI (plus:SI (match_operand:SI 0 "s_register_operand" "rk")
11752                         (const_int -4)))
11753        (match_operand:SI 1 "s_register_operand" "r"))
11754   (set (mem:SI (match_dup 0))
11755        (match_operand:SI 2 "s_register_operand" "r"))]
11756  "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11757     && (operands_ok_ldrd_strd (operands[1], operands[2],
11758                                  operands[0], -4, false, false))"
11759  "strd%?\t%1, %2, [%0, #-4]"
11760  [(set_attr "type" "store_8")
11761   (set_attr "predicable" "yes")])
11762
11763;; ARMv8 CRC32 instructions.
11764(define_insn "<crc_variant>"
11765  [(set (match_operand:SI 0 "s_register_operand" "=r")
11766        (unspec:SI [(match_operand:SI 1 "s_register_operand" "r")
11767                    (match_operand:<crc_mode> 2 "s_register_operand" "r")]
11768         CRC))]
11769  "TARGET_CRC32"
11770  "<crc_variant>\\t%0, %1, %2"
11771  [(set_attr "type" "crc")
11772   (set_attr "conds" "unconditional")]
11773)
11774
11775;; Load the load/store double peephole optimizations.
11776(include "ldrdstrd.md")
11777
11778;; Load the load/store multiple patterns
11779(include "ldmstm.md")
11780
11781;; Patterns in ldmstm.md don't cover more than 4 registers. This pattern covers
11782;; large lists without explicit writeback generated for APCS_FRAME epilogue.
11783;; The operands are validated through the load_multiple_operation
11784;; match_parallel predicate rather than through constraints so enable it only
11785;; after reload.
11786(define_insn "*load_multiple"
11787  [(match_parallel 0 "load_multiple_operation"
11788    [(set (match_operand:SI 2 "s_register_operand" "=rk")
11789          (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
11790        ])]
11791  "TARGET_32BIT && reload_completed"
11792  "*
11793  {
11794    arm_output_multireg_pop (operands, /*return_pc=*/false,
11795                                       /*cond=*/const_true_rtx,
11796                                       /*reverse=*/false,
11797                                       /*update=*/false);
11798    return \"\";
11799  }
11800  "
11801  [(set_attr "predicable" "yes")]
11802)
11803
11804(define_expand "copysignsf3"
11805  [(match_operand:SF 0 "register_operand")
11806   (match_operand:SF 1 "register_operand")
11807   (match_operand:SF 2 "register_operand")]
11808  "TARGET_SOFT_FLOAT && arm_arch_thumb2"
11809  "{
11810     emit_move_insn (operands[0], operands[2]);
11811     emit_insn (gen_insv_t2 (simplify_gen_subreg (SImode, operands[0], SFmode, 0),
11812		GEN_INT (31), GEN_INT (0),
11813		simplify_gen_subreg (SImode, operands[1], SFmode, 0)));
11814     DONE;
11815  }"
11816)
11817
11818(define_expand "copysigndf3"
11819  [(match_operand:DF 0 "register_operand")
11820   (match_operand:DF 1 "register_operand")
11821   (match_operand:DF 2 "register_operand")]
11822  "TARGET_SOFT_FLOAT && arm_arch_thumb2"
11823  "{
11824     rtx op0_low = gen_lowpart (SImode, operands[0]);
11825     rtx op0_high = gen_highpart (SImode, operands[0]);
11826     rtx op1_low = gen_lowpart (SImode, operands[1]);
11827     rtx op1_high = gen_highpart (SImode, operands[1]);
11828     rtx op2_high = gen_highpart (SImode, operands[2]);
11829
11830     rtx scratch1 = gen_reg_rtx (SImode);
11831     rtx scratch2 = gen_reg_rtx (SImode);
11832     emit_move_insn (scratch1, op2_high);
11833     emit_move_insn (scratch2, op1_high);
11834
11835     emit_insn(gen_rtx_SET(scratch1,
11836			   gen_rtx_LSHIFTRT (SImode, op2_high, GEN_INT(31))));
11837     emit_insn(gen_insv_t2(scratch2, GEN_INT(1), GEN_INT(31), scratch1));
11838     emit_move_insn (op0_low, op1_low);
11839     emit_move_insn (op0_high, scratch2);
11840
11841     DONE;
11842  }"
11843)
11844
11845;; movmisalign patterns for HImode and SImode.
11846(define_expand "movmisalign<mode>"
11847  [(match_operand:HSI 0 "general_operand")
11848   (match_operand:HSI 1 "general_operand")]
11849  "unaligned_access"
11850{
11851  /* This pattern is not permitted to fail during expansion: if both arguments
11852     are non-registers (e.g. memory := constant), force operand 1 into a
11853     register.  */
11854  rtx (* gen_unaligned_load)(rtx, rtx);
11855  rtx tmp_dest = operands[0];
11856  if (!s_register_operand (operands[0], <MODE>mode)
11857      && !s_register_operand (operands[1], <MODE>mode))
11858    operands[1] = force_reg (<MODE>mode, operands[1]);
11859
11860  if (<MODE>mode == HImode)
11861   {
11862    gen_unaligned_load = gen_unaligned_loadhiu;
11863    tmp_dest = gen_reg_rtx (SImode);
11864   }
11865  else
11866    gen_unaligned_load = gen_unaligned_loadsi;
11867
11868  if (MEM_P (operands[1]))
11869   {
11870    emit_insn (gen_unaligned_load (tmp_dest, operands[1]));
11871    if (<MODE>mode == HImode)
11872      emit_move_insn (operands[0], gen_lowpart (HImode, tmp_dest));
11873   }
11874  else
11875    emit_insn (gen_unaligned_store<mode> (operands[0], operands[1]));
11876
11877  DONE;
11878})
11879
11880(define_insn "<cdp>"
11881  [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "n")
11882		     (match_operand:SI 1 "immediate_operand" "n")
11883		     (match_operand:SI 2 "immediate_operand" "n")
11884		     (match_operand:SI 3 "immediate_operand" "n")
11885		     (match_operand:SI 4 "immediate_operand" "n")
11886		     (match_operand:SI 5 "immediate_operand" "n")] CDPI)]
11887  "arm_coproc_builtin_available (VUNSPEC_<CDP>)"
11888{
11889  arm_const_bounds (operands[0], 0, 16);
11890  arm_const_bounds (operands[1], 0, 16);
11891  arm_const_bounds (operands[2], 0, (1 << 5));
11892  arm_const_bounds (operands[3], 0, (1 << 5));
11893  arm_const_bounds (operands[4], 0, (1 << 5));
11894  arm_const_bounds (operands[5], 0, 8);
11895  return "<cdp>\\tp%c0, %1, CR%c2, CR%c3, CR%c4, %5";
11896}
11897  [(set_attr "length" "4")
11898   (set_attr "type" "coproc")])
11899
11900(define_insn "*ldc"
11901  [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "n")
11902		     (match_operand:SI 1 "immediate_operand" "n")
11903		     (match_operand:SI 2 "memory_operand" "Uz")] LDCI)]
11904  "arm_coproc_builtin_available (VUNSPEC_<LDC>)"
11905{
11906  arm_const_bounds (operands[0], 0, 16);
11907  arm_const_bounds (operands[1], 0, (1 << 5));
11908  return "<ldc>\\tp%c0, CR%c1, %2";
11909}
11910  [(set_attr "length" "4")
11911   (set_attr "type" "coproc")])
11912
11913(define_insn "*stc"
11914  [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "n")
11915		     (match_operand:SI 1 "immediate_operand" "n")
11916		     (match_operand:SI 2 "memory_operand" "=Uz")] STCI)]
11917  "arm_coproc_builtin_available (VUNSPEC_<STC>)"
11918{
11919  arm_const_bounds (operands[0], 0, 16);
11920  arm_const_bounds (operands[1], 0, (1 << 5));
11921  return "<stc>\\tp%c0, CR%c1, %2";
11922}
11923  [(set_attr "length" "4")
11924   (set_attr "type" "coproc")])
11925
11926(define_expand "<ldc>"
11927  [(unspec_volatile [(match_operand:SI 0 "immediate_operand")
11928		     (match_operand:SI 1 "immediate_operand")
11929		     (mem:SI (match_operand:SI 2 "s_register_operand"))] LDCI)]
11930  "arm_coproc_builtin_available (VUNSPEC_<LDC>)")
11931
11932(define_expand "<stc>"
11933  [(unspec_volatile [(match_operand:SI 0 "immediate_operand")
11934		     (match_operand:SI 1 "immediate_operand")
11935		     (mem:SI (match_operand:SI 2 "s_register_operand"))] STCI)]
11936  "arm_coproc_builtin_available (VUNSPEC_<STC>)")
11937
11938(define_insn "<mcr>"
11939  [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "n")
11940		     (match_operand:SI 1 "immediate_operand" "n")
11941		     (match_operand:SI 2 "s_register_operand" "r")
11942		     (match_operand:SI 3 "immediate_operand" "n")
11943		     (match_operand:SI 4 "immediate_operand" "n")
11944		     (match_operand:SI 5 "immediate_operand" "n")] MCRI)
11945   (use (match_dup 2))]
11946  "arm_coproc_builtin_available (VUNSPEC_<MCR>)"
11947{
11948  arm_const_bounds (operands[0], 0, 16);
11949  arm_const_bounds (operands[1], 0, 8);
11950  arm_const_bounds (operands[3], 0, (1 << 5));
11951  arm_const_bounds (operands[4], 0, (1 << 5));
11952  arm_const_bounds (operands[5], 0, 8);
11953  return "<mcr>\\tp%c0, %1, %2, CR%c3, CR%c4, %5";
11954}
11955  [(set_attr "length" "4")
11956   (set_attr "type" "coproc")])
11957
11958(define_insn "<mrc>"
11959  [(set (match_operand:SI 0 "s_register_operand" "=r")
11960	(unspec_volatile:SI [(match_operand:SI 1 "immediate_operand" "n")
11961			  (match_operand:SI 2 "immediate_operand" "n")
11962			  (match_operand:SI 3 "immediate_operand" "n")
11963			  (match_operand:SI 4 "immediate_operand" "n")
11964			  (match_operand:SI 5 "immediate_operand" "n")] MRCI))]
11965  "arm_coproc_builtin_available (VUNSPEC_<MRC>)"
11966{
11967  arm_const_bounds (operands[1], 0, 16);
11968  arm_const_bounds (operands[2], 0, 8);
11969  arm_const_bounds (operands[3], 0, (1 << 5));
11970  arm_const_bounds (operands[4], 0, (1 << 5));
11971  arm_const_bounds (operands[5], 0, 8);
11972  return "<mrc>\\tp%c1, %2, %0, CR%c3, CR%c4, %5";
11973}
11974  [(set_attr "length" "4")
11975   (set_attr "type" "coproc")])
11976
11977(define_insn "<mcrr>"
11978  [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "n")
11979		     (match_operand:SI 1 "immediate_operand" "n")
11980		     (match_operand:DI 2 "s_register_operand" "r")
11981		     (match_operand:SI 3 "immediate_operand" "n")] MCRRI)
11982   (use (match_dup 2))]
11983  "arm_coproc_builtin_available (VUNSPEC_<MCRR>)"
11984{
11985  arm_const_bounds (operands[0], 0, 16);
11986  arm_const_bounds (operands[1], 0, 8);
11987  arm_const_bounds (operands[3], 0, (1 << 5));
11988  return "<mcrr>\\tp%c0, %1, %Q2, %R2, CR%c3";
11989}
11990  [(set_attr "length" "4")
11991   (set_attr "type" "coproc")])
11992
11993(define_insn "<mrrc>"
11994  [(set (match_operand:DI 0 "s_register_operand" "=r")
11995	(unspec_volatile:DI [(match_operand:SI 1 "immediate_operand" "n")
11996			  (match_operand:SI 2 "immediate_operand" "n")
11997			  (match_operand:SI 3 "immediate_operand" "n")] MRRCI))]
11998  "arm_coproc_builtin_available (VUNSPEC_<MRRC>)"
11999{
12000  arm_const_bounds (operands[1], 0, 16);
12001  arm_const_bounds (operands[2], 0, 8);
12002  arm_const_bounds (operands[3], 0, (1 << 5));
12003  return "<mrrc>\\tp%c1, %2, %Q0, %R0, CR%c3";
12004}
12005  [(set_attr "length" "4")
12006   (set_attr "type" "coproc")])
12007
12008;; Vector bits common to IWMMXT and Neon
12009(include "vec-common.md")
12010;; Load the Intel Wireless Multimedia Extension patterns
12011(include "iwmmxt.md")
12012;; Load the VFP co-processor patterns
12013(include "vfp.md")
12014;; Thumb-1 patterns
12015(include "thumb1.md")
12016;; Thumb-2 patterns
12017(include "thumb2.md")
12018;; Neon patterns
12019(include "neon.md")
12020;; Crypto patterns
12021(include "crypto.md")
12022;; Synchronization Primitives
12023(include "sync.md")
12024;; Fixed-point patterns
12025(include "arm-fixed.md")
12026