]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/config/arm/arm.md
2019-06-27 Aaron Sawdey <acsawdey@linux.ibm.com>
[thirdparty/gcc.git] / gcc / config / arm / arm.md
1 ;;- Machine description for ARM for GNU compiler
2 ;; Copyright (C) 1991-2019 Free Software Foundation, Inc.
3 ;; Contributed by Pieter `Tiggr' Schoenmakers (rcpieter@win.tue.nl)
4 ;; and Martin Simmons (@harleqn.co.uk).
5 ;; More major hacks by Richard Earnshaw (rearnsha@arm.com).
6
7 ;; This file is part of GCC.
8
9 ;; GCC is free software; you can redistribute it and/or modify it
10 ;; under the terms of the GNU General Public License as published
11 ;; by the Free Software Foundation; either version 3, or (at your
12 ;; option) any later version.
13
14 ;; GCC is distributed in the hope that it will be useful, but WITHOUT
15 ;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16 ;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
17 ;; License for more details.
18
19 ;; You should have received a copy of the GNU General Public License
20 ;; along with GCC; see the file COPYING3. If not see
21 ;; <http://www.gnu.org/licenses/>.
22
23 ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
24
25 \f
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 \f
61 ;;---------------------------------------------------------------------------
62 ;; Attributes
63
64 ;; Processor type. This is created automatically from arm-cores.def.
65 (include "arm-tune.md")
66
67 ;; Instruction classification types
68 (include "types.md")
69
70 ; IS_THUMB is set to 'yes' when we are generating Thumb code, and 'no' when
71 ; generating ARM code. This is used to control the length of some insn
72 ; patterns that share the same RTL in both ARM and Thumb code.
73 (define_attr "is_thumb" "yes,no"
74 (const (if_then_else (symbol_ref "TARGET_THUMB")
75 (const_string "yes") (const_string "no"))))
76
77 ; IS_ARCH6 is set to 'yes' when we are generating code form ARMv6.
78 (define_attr "is_arch6" "no,yes" (const (symbol_ref "arm_arch6")))
79
80 ; IS_THUMB1 is set to 'yes' iff we are generating Thumb-1 code.
81 (define_attr "is_thumb1" "yes,no"
82 (const (if_then_else (symbol_ref "TARGET_THUMB1")
83 (const_string "yes") (const_string "no"))))
84
85 ; Mark an instruction as suitable for "short IT" blocks in Thumb-2.
86 ; The arm_restrict_it flag enables the "short IT" feature which
87 ; restricts IT blocks to a single 16-bit instruction.
88 ; This attribute should only be used on 16-bit Thumb-2 instructions
89 ; which may be predicated (the "predicable" attribute must be set).
90 (define_attr "predicable_short_it" "no,yes" (const_string "no"))
91
92 ; Mark an instruction as suitable for "short IT" blocks in Thumb-2.
93 ; This attribute should only be used on instructions which may emit
94 ; an IT block in their expansion which is not a short IT.
95 (define_attr "enabled_for_short_it" "no,yes" (const_string "yes"))
96
97 ;; Operand number of an input operand that is shifted. Zero if the
98 ;; given instruction does not shift one of its input operands.
99 (define_attr "shift" "" (const_int 0))
100
101 ;; [For compatibility with AArch64 in pipeline models]
102 ;; Attribute that specifies whether or not the instruction touches fp
103 ;; registers.
104 (define_attr "fp" "no,yes" (const_string "no"))
105
106 ; Floating Point Unit. If we only have floating point emulation, then there
107 ; is no point in scheduling the floating point insns. (Well, for best
108 ; performance we should try and group them together).
109 (define_attr "fpu" "none,vfp"
110 (const (symbol_ref "arm_fpu_attr")))
111
112 ; Predicated means that the insn form is conditionally executed based on a
113 ; predicate. We default to 'no' because no Thumb patterns match this rule
114 ; and not all ARM insns do.
115 (define_attr "predicated" "yes,no" (const_string "no"))
116
117 ; LENGTH of an instruction (in bytes)
118 (define_attr "length" ""
119 (const_int 4))
120
121 ; The architecture which supports the instruction (or alternative).
122 ; This can be "a" for ARM, "t" for either of the Thumbs, "32" for
123 ; TARGET_32BIT, "t1" or "t2" to specify a specific Thumb mode. "v6"
124 ; for ARM or Thumb-2 with arm_arch6, and nov6 for ARM without
125 ; arm_arch6. "v6t2" for Thumb-2 with arm_arch6 and "v8mb" for ARMv8-M
126 ; Baseline. This attribute is used to compute attribute "enabled",
127 ; use type "any" to enable an alternative in all cases.
128 (define_attr "arch" "any,a,t,32,t1,t2,v6,nov6,v6t2,v8mb,neon_for_64bits,avoid_neon_for_64bits,iwmmxt,iwmmxt2,armv6_or_vfpv3,neon"
129 (const_string "any"))
130
131 (define_attr "arch_enabled" "no,yes"
132 (cond [(eq_attr "arch" "any")
133 (const_string "yes")
134
135 (and (eq_attr "arch" "a")
136 (match_test "TARGET_ARM"))
137 (const_string "yes")
138
139 (and (eq_attr "arch" "t")
140 (match_test "TARGET_THUMB"))
141 (const_string "yes")
142
143 (and (eq_attr "arch" "t1")
144 (match_test "TARGET_THUMB1"))
145 (const_string "yes")
146
147 (and (eq_attr "arch" "t2")
148 (match_test "TARGET_THUMB2"))
149 (const_string "yes")
150
151 (and (eq_attr "arch" "32")
152 (match_test "TARGET_32BIT"))
153 (const_string "yes")
154
155 (and (eq_attr "arch" "v6")
156 (match_test "TARGET_32BIT && arm_arch6"))
157 (const_string "yes")
158
159 (and (eq_attr "arch" "nov6")
160 (match_test "TARGET_32BIT && !arm_arch6"))
161 (const_string "yes")
162
163 (and (eq_attr "arch" "v6t2")
164 (match_test "TARGET_32BIT && arm_arch6 && arm_arch_thumb2"))
165 (const_string "yes")
166
167 (and (eq_attr "arch" "v8mb")
168 (match_test "TARGET_THUMB1 && arm_arch8"))
169 (const_string "yes")
170
171 (and (eq_attr "arch" "avoid_neon_for_64bits")
172 (match_test "TARGET_NEON")
173 (not (match_test "TARGET_PREFER_NEON_64BITS")))
174 (const_string "yes")
175
176 (and (eq_attr "arch" "neon_for_64bits")
177 (match_test "TARGET_NEON")
178 (match_test "TARGET_PREFER_NEON_64BITS"))
179 (const_string "yes")
180
181 (and (eq_attr "arch" "iwmmxt2")
182 (match_test "TARGET_REALLY_IWMMXT2"))
183 (const_string "yes")
184
185 (and (eq_attr "arch" "armv6_or_vfpv3")
186 (match_test "arm_arch6 || TARGET_VFP3"))
187 (const_string "yes")
188
189 (and (eq_attr "arch" "neon")
190 (match_test "TARGET_NEON"))
191 (const_string "yes")
192 ]
193
194 (const_string "no")))
195
196 (define_attr "opt" "any,speed,size"
197 (const_string "any"))
198
199 (define_attr "opt_enabled" "no,yes"
200 (cond [(eq_attr "opt" "any")
201 (const_string "yes")
202
203 (and (eq_attr "opt" "speed")
204 (match_test "optimize_function_for_speed_p (cfun)"))
205 (const_string "yes")
206
207 (and (eq_attr "opt" "size")
208 (match_test "optimize_function_for_size_p (cfun)"))
209 (const_string "yes")]
210 (const_string "no")))
211
212 (define_attr "use_literal_pool" "no,yes"
213 (cond [(and (eq_attr "type" "f_loads,f_loadd")
214 (match_test "CONSTANT_P (operands[1])"))
215 (const_string "yes")]
216 (const_string "no")))
217
218 ; Enable all alternatives that are both arch_enabled and insn_enabled.
219 ; FIXME:: opt_enabled has been temporarily removed till the time we have
220 ; an attribute that allows the use of such alternatives.
221 ; This depends on caching of speed_p, size_p on a per
222 ; alternative basis. The problem is that the enabled attribute
223 ; cannot depend on any state that is not cached or is not constant
224 ; for a compilation unit. We probably need a generic "hot/cold"
225 ; alternative which if implemented can help with this. We disable this
226 ; until such a time as this is implemented and / or the improvements or
227 ; regressions with removing this attribute are double checked.
228 ; See ashldi3_neon and <shift>di3_neon in neon.md.
229
230 (define_attr "enabled" "no,yes"
231 (cond [(and (eq_attr "predicable_short_it" "no")
232 (and (eq_attr "predicated" "yes")
233 (match_test "arm_restrict_it")))
234 (const_string "no")
235
236 (and (eq_attr "enabled_for_short_it" "no")
237 (match_test "arm_restrict_it"))
238 (const_string "no")
239
240 (eq_attr "arch_enabled" "no")
241 (const_string "no")]
242 (const_string "yes")))
243
244 ; POOL_RANGE is how far away from a constant pool entry that this insn
245 ; can be placed. If the distance is zero, then this insn will never
246 ; reference the pool.
247 ; Note that for Thumb constant pools the PC value is rounded down to the
248 ; nearest multiple of four. Therefore, THUMB2_POOL_RANGE (and POOL_RANGE for
249 ; Thumb insns) should be set to <max_range> - 2.
250 ; NEG_POOL_RANGE is nonzero for insns that can reference a constant pool entry
251 ; before its address. It is set to <max_range> - (8 + <data_size>).
252 (define_attr "arm_pool_range" "" (const_int 0))
253 (define_attr "thumb2_pool_range" "" (const_int 0))
254 (define_attr "arm_neg_pool_range" "" (const_int 0))
255 (define_attr "thumb2_neg_pool_range" "" (const_int 0))
256
257 (define_attr "pool_range" ""
258 (cond [(eq_attr "is_thumb" "yes") (attr "thumb2_pool_range")]
259 (attr "arm_pool_range")))
260 (define_attr "neg_pool_range" ""
261 (cond [(eq_attr "is_thumb" "yes") (attr "thumb2_neg_pool_range")]
262 (attr "arm_neg_pool_range")))
263
264 ; An assembler sequence may clobber the condition codes without us knowing.
265 ; If such an insn references the pool, then we have no way of knowing how,
266 ; so use the most conservative value for pool_range.
267 (define_asm_attributes
268 [(set_attr "conds" "clob")
269 (set_attr "length" "4")
270 (set_attr "pool_range" "250")])
271
272 ; Load scheduling, set from the arm_ld_sched variable
273 ; initialized by arm_option_override()
274 (define_attr "ldsched" "no,yes" (const (symbol_ref "arm_ld_sched")))
275
276 ; condition codes: this one is used by final_prescan_insn to speed up
277 ; conditionalizing instructions. It saves having to scan the rtl to see if
278 ; it uses or alters the condition codes.
279 ;
280 ; USE means that the condition codes are used by the insn in the process of
281 ; outputting code, this means (at present) that we can't use the insn in
282 ; inlined branches
283 ;
284 ; SET means that the purpose of the insn is to set the condition codes in a
285 ; well defined manner.
286 ;
287 ; CLOB means that the condition codes are altered in an undefined manner, if
288 ; they are altered at all
289 ;
290 ; UNCONDITIONAL means the instruction cannot be conditionally executed and
291 ; that the instruction does not use or alter the condition codes.
292 ;
293 ; NOCOND means that the instruction does not use or alter the condition
294 ; codes but can be converted into a conditionally exectuted instruction.
295
296 (define_attr "conds" "use,set,clob,unconditional,nocond"
297 (if_then_else
298 (ior (eq_attr "is_thumb1" "yes")
299 (eq_attr "type" "call"))
300 (const_string "clob")
301 (if_then_else (eq_attr "is_neon_type" "no")
302 (const_string "nocond")
303 (const_string "unconditional"))))
304
305 ; Predicable means that the insn can be conditionally executed based on
306 ; an automatically added predicate (additional patterns are generated by
307 ; gen...). We default to 'no' because no Thumb patterns match this rule
308 ; and not all ARM patterns do.
309 (define_attr "predicable" "no,yes" (const_string "no"))
310
311 ; Only model the write buffer for ARM6 and ARM7. Earlier processors don't
312 ; have one. Later ones, such as StrongARM, have write-back caches, so don't
313 ; suffer blockages enough to warrant modelling this (and it can adversely
314 ; affect the schedule).
315 (define_attr "model_wbuf" "no,yes" (const (symbol_ref "arm_tune_wbuf")))
316
317 ; WRITE_CONFLICT implies that a read following an unrelated write is likely
318 ; to stall the processor. Used with model_wbuf above.
319 (define_attr "write_conflict" "no,yes"
320 (if_then_else (eq_attr "type"
321 "block,call,load_4")
322 (const_string "yes")
323 (const_string "no")))
324
325 ; Classify the insns into those that take one cycle and those that take more
326 ; than one on the main cpu execution unit.
327 (define_attr "core_cycles" "single,multi"
328 (if_then_else (eq_attr "type"
329 "adc_imm, adc_reg, adcs_imm, adcs_reg, adr, alu_ext, alu_imm, alu_sreg,\
330 alu_shift_imm, alu_shift_reg, alu_dsp_reg, alus_ext, alus_imm, alus_sreg,\
331 alus_shift_imm, alus_shift_reg, bfm, csel, rev, logic_imm, logic_reg,\
332 logic_shift_imm, logic_shift_reg, logics_imm, logics_reg,\
333 logics_shift_imm, logics_shift_reg, extend, shift_imm, float, fcsel,\
334 wmmx_wor, wmmx_wxor, wmmx_wand, wmmx_wandn, wmmx_wmov, wmmx_tmcrr,\
335 wmmx_tmrrc, wmmx_wldr, wmmx_wstr, wmmx_tmcr, wmmx_tmrc, wmmx_wadd,\
336 wmmx_wsub, wmmx_wmul, wmmx_wmac, wmmx_wavg2, wmmx_tinsr, wmmx_textrm,\
337 wmmx_wshufh, wmmx_wcmpeq, wmmx_wcmpgt, wmmx_wmax, wmmx_wmin, wmmx_wpack,\
338 wmmx_wunpckih, wmmx_wunpckil, wmmx_wunpckeh, wmmx_wunpckel, wmmx_wror,\
339 wmmx_wsra, wmmx_wsrl, wmmx_wsll, wmmx_wmadd, wmmx_tmia, wmmx_tmiaph,\
340 wmmx_tmiaxy, wmmx_tbcst, wmmx_tmovmsk, wmmx_wacc, wmmx_waligni,\
341 wmmx_walignr, wmmx_tandc, wmmx_textrc, wmmx_torc, wmmx_torvsc, wmmx_wsad,\
342 wmmx_wabs, wmmx_wabsdiff, wmmx_waddsubhx, wmmx_wsubaddhx, wmmx_wavg4,\
343 wmmx_wmulw, wmmx_wqmulm, wmmx_wqmulwm, wmmx_waddbhus, wmmx_wqmiaxy,\
344 wmmx_wmiaxy, wmmx_wmiawxy, wmmx_wmerge")
345 (const_string "single")
346 (const_string "multi")))
347
348 ;; FAR_JUMP is "yes" if a BL instruction is used to generate a branch to a
349 ;; distant label. Only applicable to Thumb code.
350 (define_attr "far_jump" "yes,no" (const_string "no"))
351
352
353 ;; The number of machine instructions this pattern expands to.
354 ;; Used for Thumb-2 conditional execution.
355 (define_attr "ce_count" "" (const_int 1))
356
357 ;;---------------------------------------------------------------------------
358 ;; Unspecs
359
360 (include "unspecs.md")
361
362 ;;---------------------------------------------------------------------------
363 ;; Mode iterators
364
365 (include "iterators.md")
366
367 ;;---------------------------------------------------------------------------
368 ;; Predicates
369
370 (include "predicates.md")
371 (include "constraints.md")
372
373 ;;---------------------------------------------------------------------------
374 ;; Pipeline descriptions
375
376 (define_attr "tune_cortexr4" "yes,no"
377 (const (if_then_else
378 (eq_attr "tune" "cortexr4,cortexr4f,cortexr5")
379 (const_string "yes")
380 (const_string "no"))))
381
382 ;; True if the generic scheduling description should be used.
383
384 (define_attr "generic_sched" "yes,no"
385 (const (if_then_else
386 (ior (eq_attr "tune" "fa526,fa626,fa606te,fa626te,fmp626,fa726te,\
387 arm926ejs,arm10e,arm1026ejs,arm1136js,\
388 arm1136jfs,cortexa5,cortexa7,cortexa8,\
389 cortexa9,cortexa12,cortexa15,cortexa17,\
390 cortexa53,cortexa57,cortexm4,cortexm7,\
391 exynosm1,marvell_pj4,xgene1")
392 (eq_attr "tune_cortexr4" "yes"))
393 (const_string "no")
394 (const_string "yes"))))
395
396 (define_attr "generic_vfp" "yes,no"
397 (const (if_then_else
398 (and (eq_attr "fpu" "vfp")
399 (eq_attr "tune" "!arm10e,cortexa5,cortexa7,\
400 cortexa8,cortexa9,cortexa53,cortexm4,\
401 cortexm7,marvell_pj4,xgene1")
402 (eq_attr "tune_cortexr4" "no"))
403 (const_string "yes")
404 (const_string "no"))))
405
406 (include "marvell-f-iwmmxt.md")
407 (include "arm-generic.md")
408 (include "arm926ejs.md")
409 (include "arm1020e.md")
410 (include "arm1026ejs.md")
411 (include "arm1136jfs.md")
412 (include "fa526.md")
413 (include "fa606te.md")
414 (include "fa626te.md")
415 (include "fmp626.md")
416 (include "fa726te.md")
417 (include "cortex-a5.md")
418 (include "cortex-a7.md")
419 (include "cortex-a8.md")
420 (include "cortex-a9.md")
421 (include "cortex-a15.md")
422 (include "cortex-a17.md")
423 (include "cortex-a53.md")
424 (include "cortex-a57.md")
425 (include "cortex-r4.md")
426 (include "cortex-r4f.md")
427 (include "cortex-m7.md")
428 (include "cortex-m4.md")
429 (include "cortex-m4-fpu.md")
430 (include "exynos-m1.md")
431 (include "vfp11.md")
432 (include "marvell-pj4.md")
433 (include "xgene1.md")
434
435 \f
436 ;;---------------------------------------------------------------------------
437 ;; Insn patterns
438 ;;
439 ;; Addition insns.
440
441 ;; Note: For DImode insns, there is normally no reason why operands should
442 ;; not be in the same register, what we don't want is for something being
443 ;; written to partially overlap something that is an input.
444
445 (define_expand "adddi3"
446 [(parallel
447 [(set (match_operand:DI 0 "s_register_operand" "")
448 (plus:DI (match_operand:DI 1 "s_register_operand" "")
449 (match_operand:DI 2 "arm_adddi_operand" "")))
450 (clobber (reg:CC CC_REGNUM))])]
451 "TARGET_EITHER"
452 "
453 if (TARGET_THUMB1)
454 {
455 if (!REG_P (operands[1]))
456 operands[1] = force_reg (DImode, operands[1]);
457 if (!REG_P (operands[2]))
458 operands[2] = force_reg (DImode, operands[2]);
459 }
460 "
461 )
462
463 (define_insn_and_split "*arm_adddi3"
464 [(set (match_operand:DI 0 "arm_general_register_operand" "=&r,&r,&r,&r,&r")
465 (plus:DI (match_operand:DI 1 "arm_general_register_operand" "%0, 0, r, 0, r")
466 (match_operand:DI 2 "arm_general_adddi_operand" "r, 0, r, Dd, Dd")))
467 (clobber (reg:CC CC_REGNUM))]
468 "TARGET_32BIT && !TARGET_NEON"
469 "#"
470 "TARGET_32BIT && ((!TARGET_NEON && !TARGET_IWMMXT) || reload_completed)"
471 [(parallel [(set (reg:CC_C CC_REGNUM)
472 (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
473 (match_dup 1)))
474 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
475 (set (match_dup 3) (plus:SI (plus:SI (match_dup 4) (match_dup 5))
476 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
477 "
478 {
479 operands[3] = gen_highpart (SImode, operands[0]);
480 operands[0] = gen_lowpart (SImode, operands[0]);
481 operands[4] = gen_highpart (SImode, operands[1]);
482 operands[1] = gen_lowpart (SImode, operands[1]);
483 operands[5] = gen_highpart_mode (SImode, DImode, operands[2]);
484 operands[2] = gen_lowpart (SImode, operands[2]);
485 }"
486 [(set_attr "conds" "clob")
487 (set_attr "length" "8")
488 (set_attr "type" "multiple")]
489 )
490
491 (define_insn_and_split "*adddi_sesidi_di"
492 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
493 (plus:DI (sign_extend:DI
494 (match_operand:SI 2 "s_register_operand" "r,r"))
495 (match_operand:DI 1 "s_register_operand" "0,r")))
496 (clobber (reg:CC CC_REGNUM))]
497 "TARGET_32BIT"
498 "#"
499 "TARGET_32BIT && reload_completed"
500 [(parallel [(set (reg:CC_C CC_REGNUM)
501 (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
502 (match_dup 1)))
503 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
504 (set (match_dup 3) (plus:SI (plus:SI (ashiftrt:SI (match_dup 2)
505 (const_int 31))
506 (match_dup 4))
507 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
508 "
509 {
510 operands[3] = gen_highpart (SImode, operands[0]);
511 operands[0] = gen_lowpart (SImode, operands[0]);
512 operands[4] = gen_highpart (SImode, operands[1]);
513 operands[1] = gen_lowpart (SImode, operands[1]);
514 operands[2] = gen_lowpart (SImode, operands[2]);
515 }"
516 [(set_attr "conds" "clob")
517 (set_attr "length" "8")
518 (set_attr "type" "multiple")]
519 )
520
521 (define_insn_and_split "*adddi_zesidi_di"
522 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
523 (plus:DI (zero_extend:DI
524 (match_operand:SI 2 "s_register_operand" "r,r"))
525 (match_operand:DI 1 "s_register_operand" "0,r")))
526 (clobber (reg:CC CC_REGNUM))]
527 "TARGET_32BIT"
528 "#"
529 "TARGET_32BIT && reload_completed"
530 [(parallel [(set (reg:CC_C CC_REGNUM)
531 (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
532 (match_dup 1)))
533 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
534 (set (match_dup 3) (plus:SI (plus:SI (match_dup 4) (const_int 0))
535 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
536 "
537 {
538 operands[3] = gen_highpart (SImode, operands[0]);
539 operands[0] = gen_lowpart (SImode, operands[0]);
540 operands[4] = gen_highpart (SImode, operands[1]);
541 operands[1] = gen_lowpart (SImode, operands[1]);
542 operands[2] = gen_lowpart (SImode, operands[2]);
543 }"
544 [(set_attr "conds" "clob")
545 (set_attr "length" "8")
546 (set_attr "type" "multiple")]
547 )
548
549 (define_expand "addv<mode>4"
550 [(match_operand:SIDI 0 "register_operand")
551 (match_operand:SIDI 1 "register_operand")
552 (match_operand:SIDI 2 "register_operand")
553 (match_operand 3 "")]
554 "TARGET_32BIT"
555 {
556 emit_insn (gen_add<mode>3_compareV (operands[0], operands[1], operands[2]));
557 arm_gen_unlikely_cbranch (NE, CC_Vmode, operands[3]);
558
559 DONE;
560 })
561
562 (define_expand "uaddv<mode>4"
563 [(match_operand:SIDI 0 "register_operand")
564 (match_operand:SIDI 1 "register_operand")
565 (match_operand:SIDI 2 "register_operand")
566 (match_operand 3 "")]
567 "TARGET_32BIT"
568 {
569 emit_insn (gen_add<mode>3_compareC (operands[0], operands[1], operands[2]));
570 arm_gen_unlikely_cbranch (NE, CC_Cmode, operands[3]);
571
572 DONE;
573 })
574
575 (define_expand "addsi3"
576 [(set (match_operand:SI 0 "s_register_operand" "")
577 (plus:SI (match_operand:SI 1 "s_register_operand" "")
578 (match_operand:SI 2 "reg_or_int_operand" "")))]
579 "TARGET_EITHER"
580 "
581 if (TARGET_32BIT && CONST_INT_P (operands[2]))
582 {
583 arm_split_constant (PLUS, SImode, NULL_RTX,
584 INTVAL (operands[2]), operands[0], operands[1],
585 optimize && can_create_pseudo_p ());
586 DONE;
587 }
588 "
589 )
590
591 ; If there is a scratch available, this will be faster than synthesizing the
592 ; addition.
593 (define_peephole2
594 [(match_scratch:SI 3 "r")
595 (set (match_operand:SI 0 "arm_general_register_operand" "")
596 (plus:SI (match_operand:SI 1 "arm_general_register_operand" "")
597 (match_operand:SI 2 "const_int_operand" "")))]
598 "TARGET_32BIT &&
599 !(const_ok_for_arm (INTVAL (operands[2]))
600 || const_ok_for_arm (-INTVAL (operands[2])))
601 && const_ok_for_arm (~INTVAL (operands[2]))"
602 [(set (match_dup 3) (match_dup 2))
603 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 3)))]
604 ""
605 )
606
607 ;; The r/r/k alternative is required when reloading the address
608 ;; (plus (reg rN) (reg sp)) into (reg rN). In this case reload will
609 ;; put the duplicated register first, and not try the commutative version.
610 (define_insn_and_split "*arm_addsi3"
611 [(set (match_operand:SI 0 "s_register_operand" "=rk,l,l ,l ,r ,k ,r,k ,r ,k ,r ,k,k,r ,k ,r")
612 (plus:SI (match_operand:SI 1 "s_register_operand" "%0 ,l,0 ,l ,rk,k ,r,r ,rk,k ,rk,k,r,rk,k ,rk")
613 (match_operand:SI 2 "reg_or_int_operand" "rk ,l,Py,Pd,rI,rI,k,rI,Pj,Pj,L ,L,L,PJ,PJ,?n")))]
614 "TARGET_32BIT"
615 "@
616 add%?\\t%0, %0, %2
617 add%?\\t%0, %1, %2
618 add%?\\t%0, %1, %2
619 add%?\\t%0, %1, %2
620 add%?\\t%0, %1, %2
621 add%?\\t%0, %1, %2
622 add%?\\t%0, %2, %1
623 add%?\\t%0, %1, %2
624 addw%?\\t%0, %1, %2
625 addw%?\\t%0, %1, %2
626 sub%?\\t%0, %1, #%n2
627 sub%?\\t%0, %1, #%n2
628 sub%?\\t%0, %1, #%n2
629 subw%?\\t%0, %1, #%n2
630 subw%?\\t%0, %1, #%n2
631 #"
632 "TARGET_32BIT
633 && CONST_INT_P (operands[2])
634 && !const_ok_for_op (INTVAL (operands[2]), PLUS)
635 && (reload_completed || !arm_eliminable_register (operands[1]))"
636 [(clobber (const_int 0))]
637 "
638 arm_split_constant (PLUS, SImode, curr_insn,
639 INTVAL (operands[2]), operands[0],
640 operands[1], 0);
641 DONE;
642 "
643 [(set_attr "length" "2,4,4,4,4,4,4,4,4,4,4,4,4,4,4,16")
644 (set_attr "predicable" "yes")
645 (set_attr "predicable_short_it" "yes,yes,yes,yes,no,no,no,no,no,no,no,no,no,no,no,no")
646 (set_attr "arch" "t2,t2,t2,t2,*,*,*,a,t2,t2,*,*,a,t2,t2,*")
647 (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
648 (const_string "alu_imm")
649 (const_string "alu_sreg")))
650 ]
651 )
652
653 (define_insn_and_split "adddi3_compareV"
654 [(set (reg:CC_V CC_REGNUM)
655 (ne:CC_V
656 (plus:TI
657 (sign_extend:TI (match_operand:DI 1 "register_operand" "r"))
658 (sign_extend:TI (match_operand:DI 2 "register_operand" "r")))
659 (sign_extend:TI (plus:DI (match_dup 1) (match_dup 2)))))
660 (set (match_operand:DI 0 "register_operand" "=&r")
661 (plus:DI (match_dup 1) (match_dup 2)))]
662 "TARGET_32BIT"
663 "#"
664 "&& reload_completed"
665 [(parallel [(set (reg:CC_C CC_REGNUM)
666 (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
667 (match_dup 1)))
668 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
669 (parallel [(set (reg:CC_V CC_REGNUM)
670 (ne:CC_V
671 (plus:DI (plus:DI
672 (sign_extend:DI (match_dup 4))
673 (sign_extend:DI (match_dup 5)))
674 (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0)))
675 (plus:DI (sign_extend:DI
676 (plus:SI (match_dup 4) (match_dup 5)))
677 (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0)))))
678 (set (match_dup 3) (plus:SI (plus:SI
679 (match_dup 4) (match_dup 5))
680 (ltu:SI (reg:CC_C CC_REGNUM)
681 (const_int 0))))])]
682 "
683 {
684 operands[3] = gen_highpart (SImode, operands[0]);
685 operands[0] = gen_lowpart (SImode, operands[0]);
686 operands[4] = gen_highpart (SImode, operands[1]);
687 operands[1] = gen_lowpart (SImode, operands[1]);
688 operands[5] = gen_highpart (SImode, operands[2]);
689 operands[2] = gen_lowpart (SImode, operands[2]);
690 }"
691 [(set_attr "conds" "set")
692 (set_attr "length" "8")
693 (set_attr "type" "multiple")]
694 )
695
696 (define_insn "addsi3_compareV"
697 [(set (reg:CC_V CC_REGNUM)
698 (ne:CC_V
699 (plus:DI
700 (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
701 (sign_extend:DI (match_operand:SI 2 "register_operand" "r")))
702 (sign_extend:DI (plus:SI (match_dup 1) (match_dup 2)))))
703 (set (match_operand:SI 0 "register_operand" "=r")
704 (plus:SI (match_dup 1) (match_dup 2)))]
705 "TARGET_32BIT"
706 "adds%?\\t%0, %1, %2"
707 [(set_attr "conds" "set")
708 (set_attr "type" "alus_sreg")]
709 )
710
711 (define_insn "*addsi3_compareV_upper"
712 [(set (reg:CC_V CC_REGNUM)
713 (ne:CC_V
714 (plus:DI
715 (plus:DI
716 (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
717 (sign_extend:DI (match_operand:SI 2 "register_operand" "r")))
718 (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0)))
719 (plus:DI (sign_extend:DI
720 (plus:SI (match_dup 1) (match_dup 2)))
721 (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0)))))
722 (set (match_operand:SI 0 "register_operand" "=r")
723 (plus:SI
724 (plus:SI (match_dup 1) (match_dup 2))
725 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
726 "TARGET_32BIT"
727 "adcs%?\\t%0, %1, %2"
728 [(set_attr "conds" "set")
729 (set_attr "type" "adcs_reg")]
730 )
731
732 (define_insn_and_split "adddi3_compareC"
733 [(set (reg:CC_C CC_REGNUM)
734 (ne:CC_C
735 (plus:TI
736 (zero_extend:TI (match_operand:DI 1 "register_operand" "r"))
737 (zero_extend:TI (match_operand:DI 2 "register_operand" "r")))
738 (zero_extend:TI (plus:DI (match_dup 1) (match_dup 2)))))
739 (set (match_operand:DI 0 "register_operand" "=&r")
740 (plus:DI (match_dup 1) (match_dup 2)))]
741 "TARGET_32BIT"
742 "#"
743 "&& reload_completed"
744 [(parallel [(set (reg:CC_C CC_REGNUM)
745 (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
746 (match_dup 1)))
747 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
748 (parallel [(set (reg:CC_C CC_REGNUM)
749 (ne:CC_C
750 (plus:DI (plus:DI
751 (zero_extend:DI (match_dup 4))
752 (zero_extend:DI (match_dup 5)))
753 (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0)))
754 (plus:DI (zero_extend:DI
755 (plus:SI (match_dup 4) (match_dup 5)))
756 (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0)))))
757 (set (match_dup 3) (plus:SI
758 (plus:SI (match_dup 4) (match_dup 5))
759 (ltu:SI (reg:CC_C CC_REGNUM)
760 (const_int 0))))])]
761 "
762 {
763 operands[3] = gen_highpart (SImode, operands[0]);
764 operands[0] = gen_lowpart (SImode, operands[0]);
765 operands[4] = gen_highpart (SImode, operands[1]);
766 operands[5] = gen_highpart (SImode, operands[2]);
767 operands[1] = gen_lowpart (SImode, operands[1]);
768 operands[2] = gen_lowpart (SImode, operands[2]);
769 }"
770 [(set_attr "conds" "set")
771 (set_attr "length" "8")
772 (set_attr "type" "multiple")]
773 )
774
775 (define_insn "*addsi3_compareC_upper"
776 [(set (reg:CC_C CC_REGNUM)
777 (ne:CC_C
778 (plus:DI
779 (plus:DI
780 (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
781 (zero_extend:DI (match_operand:SI 2 "register_operand" "r")))
782 (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0)))
783 (plus:DI (zero_extend:DI
784 (plus:SI (match_dup 1) (match_dup 2)))
785 (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0)))))
786 (set (match_operand:SI 0 "register_operand" "=r")
787 (plus:SI
788 (plus:SI (match_dup 1) (match_dup 2))
789 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
790 "TARGET_32BIT"
791 "adcs%?\\t%0, %1, %2"
792 [(set_attr "conds" "set")
793 (set_attr "type" "adcs_reg")]
794 )
795
796 (define_insn "addsi3_compareC"
797 [(set (reg:CC_C CC_REGNUM)
798 (ne:CC_C
799 (plus:DI
800 (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
801 (zero_extend:DI (match_operand:SI 2 "register_operand" "r")))
802 (zero_extend:DI
803 (plus:SI (match_dup 1) (match_dup 2)))))
804 (set (match_operand:SI 0 "register_operand" "=r")
805 (plus:SI (match_dup 1) (match_dup 2)))]
806 "TARGET_32BIT"
807 "adds%?\\t%0, %1, %2"
808 [(set_attr "conds" "set")
809 (set_attr "type" "alus_sreg")]
810 )
811
812 (define_insn "addsi3_compare0"
813 [(set (reg:CC_NOOV CC_REGNUM)
814 (compare:CC_NOOV
815 (plus:SI (match_operand:SI 1 "s_register_operand" "r, r,r")
816 (match_operand:SI 2 "arm_add_operand" "I,L,r"))
817 (const_int 0)))
818 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
819 (plus:SI (match_dup 1) (match_dup 2)))]
820 "TARGET_ARM"
821 "@
822 adds%?\\t%0, %1, %2
823 subs%?\\t%0, %1, #%n2
824 adds%?\\t%0, %1, %2"
825 [(set_attr "conds" "set")
826 (set_attr "type" "alus_imm,alus_imm,alus_sreg")]
827 )
828
829 (define_insn "*addsi3_compare0_scratch"
830 [(set (reg:CC_NOOV CC_REGNUM)
831 (compare:CC_NOOV
832 (plus:SI (match_operand:SI 0 "s_register_operand" "r, r, r")
833 (match_operand:SI 1 "arm_add_operand" "I,L, r"))
834 (const_int 0)))]
835 "TARGET_ARM"
836 "@
837 cmn%?\\t%0, %1
838 cmp%?\\t%0, #%n1
839 cmn%?\\t%0, %1"
840 [(set_attr "conds" "set")
841 (set_attr "predicable" "yes")
842 (set_attr "type" "alus_imm,alus_imm,alus_sreg")]
843 )
844
845 (define_insn "*compare_negsi_si"
846 [(set (reg:CC_Z CC_REGNUM)
847 (compare:CC_Z
848 (neg:SI (match_operand:SI 0 "s_register_operand" "l,r"))
849 (match_operand:SI 1 "s_register_operand" "l,r")))]
850 "TARGET_32BIT"
851 "cmn%?\\t%1, %0"
852 [(set_attr "conds" "set")
853 (set_attr "predicable" "yes")
854 (set_attr "arch" "t2,*")
855 (set_attr "length" "2,4")
856 (set_attr "predicable_short_it" "yes,no")
857 (set_attr "type" "alus_sreg")]
858 )
859
860 ;; This is the canonicalization of subsi3_compare when the
861 ;; addend is a constant.
862 (define_insn "cmpsi2_addneg"
863 [(set (reg:CC CC_REGNUM)
864 (compare:CC
865 (match_operand:SI 1 "s_register_operand" "r,r")
866 (match_operand:SI 2 "arm_addimm_operand" "I,L")))
867 (set (match_operand:SI 0 "s_register_operand" "=r,r")
868 (plus:SI (match_dup 1)
869 (match_operand:SI 3 "arm_addimm_operand" "L,I")))]
870 "TARGET_32BIT
871 && (INTVAL (operands[2])
872 == trunc_int_for_mode (-INTVAL (operands[3]), SImode))"
873 {
874 /* For 0 and INT_MIN it is essential that we use subs, as adds will result
875 in different condition codes (like cmn rather than like cmp), so that
876 alternative comes first. Both alternatives can match for any 0x??000000
877 where except for 0 and INT_MIN it doesn't matter what we choose, and also
878 for -1 and 1 with TARGET_THUMB2, in that case prefer instruction with #1
879 as it is shorter. */
880 if (which_alternative == 0 && operands[3] != const1_rtx)
881 return "subs%?\\t%0, %1, #%n3";
882 else
883 return "adds%?\\t%0, %1, %3";
884 }
885 [(set_attr "conds" "set")
886 (set_attr "type" "alus_sreg")]
887 )
888
889 ;; Convert the sequence
890 ;; sub rd, rn, #1
891 ;; cmn rd, #1 (equivalent to cmp rd, #-1)
892 ;; bne dest
893 ;; into
894 ;; subs rd, rn, #1
895 ;; bcs dest ((unsigned)rn >= 1)
896 ;; similarly for the beq variant using bcc.
897 ;; This is a common looping idiom (while (n--))
898 (define_peephole2
899 [(set (match_operand:SI 0 "arm_general_register_operand" "")
900 (plus:SI (match_operand:SI 1 "arm_general_register_operand" "")
901 (const_int -1)))
902 (set (match_operand 2 "cc_register" "")
903 (compare (match_dup 0) (const_int -1)))
904 (set (pc)
905 (if_then_else (match_operator 3 "equality_operator"
906 [(match_dup 2) (const_int 0)])
907 (match_operand 4 "" "")
908 (match_operand 5 "" "")))]
909 "TARGET_32BIT && peep2_reg_dead_p (3, operands[2])"
910 [(parallel[
911 (set (match_dup 2)
912 (compare:CC
913 (match_dup 1) (const_int 1)))
914 (set (match_dup 0) (plus:SI (match_dup 1) (const_int -1)))])
915 (set (pc)
916 (if_then_else (match_op_dup 3 [(match_dup 2) (const_int 0)])
917 (match_dup 4)
918 (match_dup 5)))]
919 "operands[2] = gen_rtx_REG (CCmode, CC_REGNUM);
920 operands[3] = gen_rtx_fmt_ee ((GET_CODE (operands[3]) == NE
921 ? GEU : LTU),
922 VOIDmode,
923 operands[2], const0_rtx);"
924 )
925
926 ;; The next four insns work because they compare the result with one of
927 ;; the operands, and we know that the use of the condition code is
928 ;; either GEU or LTU, so we can use the carry flag from the addition
929 ;; instead of doing the compare a second time.
930 (define_insn "*addsi3_compare_op1"
931 [(set (reg:CC_C CC_REGNUM)
932 (compare:CC_C
933 (plus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
934 (match_operand:SI 2 "arm_add_operand" "I,L,r"))
935 (match_dup 1)))
936 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
937 (plus:SI (match_dup 1) (match_dup 2)))]
938 "TARGET_32BIT"
939 "@
940 adds%?\\t%0, %1, %2
941 subs%?\\t%0, %1, #%n2
942 adds%?\\t%0, %1, %2"
943 [(set_attr "conds" "set")
944 (set_attr "type" "alus_imm,alus_imm,alus_sreg")]
945 )
946
947 (define_insn "*addsi3_compare_op2"
948 [(set (reg:CC_C CC_REGNUM)
949 (compare:CC_C
950 (plus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
951 (match_operand:SI 2 "arm_add_operand" "I,L,r"))
952 (match_dup 2)))
953 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
954 (plus:SI (match_dup 1) (match_dup 2)))]
955 "TARGET_32BIT"
956 "@
957 adds%?\\t%0, %1, %2
958 subs%?\\t%0, %1, #%n2
959 adds%?\\t%0, %1, %2"
960 [(set_attr "conds" "set")
961 (set_attr "type" "alus_imm,alus_imm,alus_sreg")]
962 )
963
964 (define_insn "*compare_addsi2_op0"
965 [(set (reg:CC_C CC_REGNUM)
966 (compare:CC_C
967 (plus:SI (match_operand:SI 0 "s_register_operand" "l,l,r,r,r")
968 (match_operand:SI 1 "arm_add_operand" "Pv,l,I,L,r"))
969 (match_dup 0)))]
970 "TARGET_32BIT"
971 "@
972 cmp%?\\t%0, #%n1
973 cmn%?\\t%0, %1
974 cmn%?\\t%0, %1
975 cmp%?\\t%0, #%n1
976 cmn%?\\t%0, %1"
977 [(set_attr "conds" "set")
978 (set_attr "predicable" "yes")
979 (set_attr "arch" "t2,t2,*,*,*")
980 (set_attr "predicable_short_it" "yes,yes,no,no,no")
981 (set_attr "length" "2,2,4,4,4")
982 (set_attr "type" "alus_imm,alus_sreg,alus_imm,alus_imm,alus_sreg")]
983 )
984
985 (define_insn "*compare_addsi2_op1"
986 [(set (reg:CC_C CC_REGNUM)
987 (compare:CC_C
988 (plus:SI (match_operand:SI 0 "s_register_operand" "l,l,r,r,r")
989 (match_operand:SI 1 "arm_add_operand" "Pv,l,I,L,r"))
990 (match_dup 1)))]
991 "TARGET_32BIT"
992 "@
993 cmp%?\\t%0, #%n1
994 cmn%?\\t%0, %1
995 cmn%?\\t%0, %1
996 cmp%?\\t%0, #%n1
997 cmn%?\\t%0, %1"
998 [(set_attr "conds" "set")
999 (set_attr "predicable" "yes")
1000 (set_attr "arch" "t2,t2,*,*,*")
1001 (set_attr "predicable_short_it" "yes,yes,no,no,no")
1002 (set_attr "length" "2,2,4,4,4")
1003 (set_attr "type" "alus_imm,alus_sreg,alus_imm,alus_imm,alus_sreg")]
1004 )
1005
1006 (define_insn "*addsi3_carryin_<optab>"
1007 [(set (match_operand:SI 0 "s_register_operand" "=l,r,r")
1008 (plus:SI (plus:SI (match_operand:SI 1 "s_register_operand" "%l,r,r")
1009 (match_operand:SI 2 "arm_not_operand" "0,rI,K"))
1010 (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))))]
1011 "TARGET_32BIT"
1012 "@
1013 adc%?\\t%0, %1, %2
1014 adc%?\\t%0, %1, %2
1015 sbc%?\\t%0, %1, #%B2"
1016 [(set_attr "conds" "use")
1017 (set_attr "predicable" "yes")
1018 (set_attr "arch" "t2,*,*")
1019 (set_attr "length" "4")
1020 (set_attr "predicable_short_it" "yes,no,no")
1021 (set_attr "type" "adc_reg,adc_reg,adc_imm")]
1022 )
1023
1024 (define_insn "*addsi3_carryin_alt2_<optab>"
1025 [(set (match_operand:SI 0 "s_register_operand" "=l,r,r")
1026 (plus:SI (plus:SI (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))
1027 (match_operand:SI 1 "s_register_operand" "%l,r,r"))
1028 (match_operand:SI 2 "arm_rhs_operand" "l,rI,K")))]
1029 "TARGET_32BIT"
1030 "@
1031 adc%?\\t%0, %1, %2
1032 adc%?\\t%0, %1, %2
1033 sbc%?\\t%0, %1, #%B2"
1034 [(set_attr "conds" "use")
1035 (set_attr "predicable" "yes")
1036 (set_attr "arch" "t2,*,*")
1037 (set_attr "length" "4")
1038 (set_attr "predicable_short_it" "yes,no,no")
1039 (set_attr "type" "adc_reg,adc_reg,adc_imm")]
1040 )
1041
1042 (define_insn "*addsi3_carryin_shift_<optab>"
1043 [(set (match_operand:SI 0 "s_register_operand" "=r")
1044 (plus:SI (plus:SI
1045 (match_operator:SI 2 "shift_operator"
1046 [(match_operand:SI 3 "s_register_operand" "r")
1047 (match_operand:SI 4 "reg_or_int_operand" "rM")])
1048 (match_operand:SI 1 "s_register_operand" "r"))
1049 (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))))]
1050 "TARGET_32BIT"
1051 "adc%?\\t%0, %1, %3%S2"
1052 [(set_attr "conds" "use")
1053 (set_attr "predicable" "yes")
1054 (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
1055 (const_string "alu_shift_imm")
1056 (const_string "alu_shift_reg")))]
1057 )
1058
1059 (define_insn "*addsi3_carryin_clobercc_<optab>"
1060 [(set (match_operand:SI 0 "s_register_operand" "=r")
1061 (plus:SI (plus:SI (match_operand:SI 1 "s_register_operand" "%r")
1062 (match_operand:SI 2 "arm_rhs_operand" "rI"))
1063 (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))))
1064 (clobber (reg:CC CC_REGNUM))]
1065 "TARGET_32BIT"
1066 "adcs%?\\t%0, %1, %2"
1067 [(set_attr "conds" "set")
1068 (set_attr "type" "adcs_reg")]
1069 )
1070
1071 (define_expand "subv<mode>4"
1072 [(match_operand:SIDI 0 "register_operand")
1073 (match_operand:SIDI 1 "register_operand")
1074 (match_operand:SIDI 2 "register_operand")
1075 (match_operand 3 "")]
1076 "TARGET_32BIT"
1077 {
1078 emit_insn (gen_sub<mode>3_compare1 (operands[0], operands[1], operands[2]));
1079 arm_gen_unlikely_cbranch (NE, CC_Vmode, operands[3]);
1080
1081 DONE;
1082 })
1083
1084 (define_expand "usubv<mode>4"
1085 [(match_operand:SIDI 0 "register_operand")
1086 (match_operand:SIDI 1 "register_operand")
1087 (match_operand:SIDI 2 "register_operand")
1088 (match_operand 3 "")]
1089 "TARGET_32BIT"
1090 {
1091 emit_insn (gen_sub<mode>3_compare1 (operands[0], operands[1], operands[2]));
1092 arm_gen_unlikely_cbranch (LTU, CCmode, operands[3]);
1093
1094 DONE;
1095 })
1096
1097 (define_insn_and_split "subdi3_compare1"
1098 [(set (reg:CC CC_REGNUM)
1099 (compare:CC
1100 (match_operand:DI 1 "register_operand" "r")
1101 (match_operand:DI 2 "register_operand" "r")))
1102 (set (match_operand:DI 0 "register_operand" "=&r")
1103 (minus:DI (match_dup 1) (match_dup 2)))]
1104 "TARGET_32BIT"
1105 "#"
1106 "&& reload_completed"
1107 [(parallel [(set (reg:CC CC_REGNUM)
1108 (compare:CC (match_dup 1) (match_dup 2)))
1109 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1110 (parallel [(set (reg:CC CC_REGNUM)
1111 (compare:CC (match_dup 4) (match_dup 5)))
1112 (set (match_dup 3) (minus:SI (minus:SI (match_dup 4) (match_dup 5))
1113 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))])]
1114 {
1115 operands[3] = gen_highpart (SImode, operands[0]);
1116 operands[0] = gen_lowpart (SImode, operands[0]);
1117 operands[4] = gen_highpart (SImode, operands[1]);
1118 operands[1] = gen_lowpart (SImode, operands[1]);
1119 operands[5] = gen_highpart (SImode, operands[2]);
1120 operands[2] = gen_lowpart (SImode, operands[2]);
1121 }
1122 [(set_attr "conds" "set")
1123 (set_attr "length" "8")
1124 (set_attr "type" "multiple")]
1125 )
1126
1127 (define_insn "subsi3_compare1"
1128 [(set (reg:CC CC_REGNUM)
1129 (compare:CC
1130 (match_operand:SI 1 "register_operand" "r")
1131 (match_operand:SI 2 "register_operand" "r")))
1132 (set (match_operand:SI 0 "register_operand" "=r")
1133 (minus:SI (match_dup 1) (match_dup 2)))]
1134 "TARGET_32BIT"
1135 "subs%?\\t%0, %1, %2"
1136 [(set_attr "conds" "set")
1137 (set_attr "type" "alus_sreg")]
1138 )
1139
1140 (define_insn "*subsi3_carryin"
1141 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
1142 (minus:SI (minus:SI (match_operand:SI 1 "reg_or_int_operand" "r,I,Pz")
1143 (match_operand:SI 2 "s_register_operand" "r,r,r"))
1144 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1145 "TARGET_32BIT"
1146 "@
1147 sbc%?\\t%0, %1, %2
1148 rsc%?\\t%0, %2, %1
1149 sbc%?\\t%0, %2, %2, lsl #1"
1150 [(set_attr "conds" "use")
1151 (set_attr "arch" "*,a,t2")
1152 (set_attr "predicable" "yes")
1153 (set_attr "type" "adc_reg,adc_imm,alu_shift_imm")]
1154 )
1155
1156 (define_insn "*subsi3_carryin_const"
1157 [(set (match_operand:SI 0 "s_register_operand" "=r")
1158 (minus:SI (plus:SI (match_operand:SI 1 "s_register_operand" "r")
1159 (match_operand:SI 2 "arm_neg_immediate_operand" "L"))
1160 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1161 "TARGET_32BIT"
1162 "sbc\\t%0, %1, #%n2"
1163 [(set_attr "conds" "use")
1164 (set_attr "type" "adc_imm")]
1165 )
1166
1167 (define_insn "*subsi3_carryin_const0"
1168 [(set (match_operand:SI 0 "s_register_operand" "=r")
1169 (minus:SI (match_operand:SI 1 "s_register_operand" "r")
1170 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1171 "TARGET_32BIT"
1172 "sbc\\t%0, %1, #0"
1173 [(set_attr "conds" "use")
1174 (set_attr "type" "adc_imm")]
1175 )
1176
1177 (define_insn "*subsi3_carryin_compare"
1178 [(set (reg:CC CC_REGNUM)
1179 (compare:CC (match_operand:SI 1 "s_register_operand" "r")
1180 (match_operand:SI 2 "s_register_operand" "r")))
1181 (set (match_operand:SI 0 "s_register_operand" "=r")
1182 (minus:SI (minus:SI (match_dup 1)
1183 (match_dup 2))
1184 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1185 "TARGET_32BIT"
1186 "sbcs\\t%0, %1, %2"
1187 [(set_attr "conds" "set")
1188 (set_attr "type" "adcs_reg")]
1189 )
1190
1191 (define_insn "*subsi3_carryin_compare_const"
1192 [(set (reg:CC CC_REGNUM)
1193 (compare:CC (match_operand:SI 1 "reg_or_int_operand" "r")
1194 (match_operand:SI 2 "const_int_I_operand" "I")))
1195 (set (match_operand:SI 0 "s_register_operand" "=r")
1196 (minus:SI (plus:SI (match_dup 1)
1197 (match_operand:SI 3 "arm_neg_immediate_operand" "L"))
1198 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1199 "TARGET_32BIT
1200 && (INTVAL (operands[2])
1201 == trunc_int_for_mode (-INTVAL (operands[3]), SImode))"
1202 "sbcs\\t%0, %1, #%n3"
1203 [(set_attr "conds" "set")
1204 (set_attr "type" "adcs_imm")]
1205 )
1206
1207 (define_insn "*subsi3_carryin_compare_const0"
1208 [(set (reg:CC CC_REGNUM)
1209 (compare:CC (match_operand:SI 1 "reg_or_int_operand" "r")
1210 (const_int 0)))
1211 (set (match_operand:SI 0 "s_register_operand" "=r")
1212 (minus:SI (match_dup 1)
1213 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1214 "TARGET_32BIT"
1215 "sbcs\\t%0, %1, #0"
1216 [(set_attr "conds" "set")
1217 (set_attr "type" "adcs_imm")]
1218 )
1219
1220 (define_insn "*subsi3_carryin_shift"
1221 [(set (match_operand:SI 0 "s_register_operand" "=r")
1222 (minus:SI (minus:SI
1223 (match_operand:SI 1 "s_register_operand" "r")
1224 (match_operator:SI 2 "shift_operator"
1225 [(match_operand:SI 3 "s_register_operand" "r")
1226 (match_operand:SI 4 "reg_or_int_operand" "rM")]))
1227 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1228 "TARGET_32BIT"
1229 "sbc%?\\t%0, %1, %3%S2"
1230 [(set_attr "conds" "use")
1231 (set_attr "predicable" "yes")
1232 (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
1233 (const_string "alu_shift_imm")
1234 (const_string "alu_shift_reg")))]
1235 )
1236
1237 (define_insn "*rsbsi3_carryin_shift"
1238 [(set (match_operand:SI 0 "s_register_operand" "=r")
1239 (minus:SI (minus:SI
1240 (match_operator:SI 2 "shift_operator"
1241 [(match_operand:SI 3 "s_register_operand" "r")
1242 (match_operand:SI 4 "reg_or_int_operand" "rM")])
1243 (match_operand:SI 1 "s_register_operand" "r"))
1244 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1245 "TARGET_ARM"
1246 "rsc%?\\t%0, %1, %3%S2"
1247 [(set_attr "conds" "use")
1248 (set_attr "predicable" "yes")
1249 (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
1250 (const_string "alu_shift_imm")
1251 (const_string "alu_shift_reg")))]
1252 )
1253
1254 ; transform ((x << y) - 1) to ~(~(x-1) << y) Where X is a constant.
1255 (define_split
1256 [(set (match_operand:SI 0 "s_register_operand" "")
1257 (plus:SI (ashift:SI (match_operand:SI 1 "const_int_operand" "")
1258 (match_operand:SI 2 "s_register_operand" ""))
1259 (const_int -1)))
1260 (clobber (match_operand:SI 3 "s_register_operand" ""))]
1261 "TARGET_32BIT"
1262 [(set (match_dup 3) (match_dup 1))
1263 (set (match_dup 0) (not:SI (ashift:SI (match_dup 3) (match_dup 2))))]
1264 "
1265 operands[1] = GEN_INT (~(INTVAL (operands[1]) - 1));
1266 ")
1267
1268 (define_expand "addsf3"
1269 [(set (match_operand:SF 0 "s_register_operand" "")
1270 (plus:SF (match_operand:SF 1 "s_register_operand" "")
1271 (match_operand:SF 2 "s_register_operand" "")))]
1272 "TARGET_32BIT && TARGET_HARD_FLOAT"
1273 "
1274 ")
1275
1276 (define_expand "adddf3"
1277 [(set (match_operand:DF 0 "s_register_operand" "")
1278 (plus:DF (match_operand:DF 1 "s_register_operand" "")
1279 (match_operand:DF 2 "s_register_operand" "")))]
1280 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
1281 "
1282 ")
1283
1284 (define_expand "subdi3"
1285 [(parallel
1286 [(set (match_operand:DI 0 "s_register_operand" "")
1287 (minus:DI (match_operand:DI 1 "s_register_operand" "")
1288 (match_operand:DI 2 "s_register_operand" "")))
1289 (clobber (reg:CC CC_REGNUM))])]
1290 "TARGET_EITHER"
1291 "
1292 if (TARGET_THUMB1)
1293 {
1294 if (!REG_P (operands[1]))
1295 operands[1] = force_reg (DImode, operands[1]);
1296 if (!REG_P (operands[2]))
1297 operands[2] = force_reg (DImode, operands[2]);
1298 }
1299 "
1300 )
1301
1302 (define_insn_and_split "*arm_subdi3"
1303 [(set (match_operand:DI 0 "arm_general_register_operand" "=&r,&r,&r")
1304 (minus:DI (match_operand:DI 1 "arm_general_register_operand" "0,r,0")
1305 (match_operand:DI 2 "arm_general_register_operand" "r,0,0")))
1306 (clobber (reg:CC CC_REGNUM))]
1307 "TARGET_32BIT && !TARGET_NEON"
1308 "#" ; "subs\\t%Q0, %Q1, %Q2\;sbc\\t%R0, %R1, %R2"
1309 "&& (!TARGET_IWMMXT || reload_completed)"
1310 [(parallel [(set (reg:CC CC_REGNUM)
1311 (compare:CC (match_dup 1) (match_dup 2)))
1312 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1313 (set (match_dup 3) (minus:SI (minus:SI (match_dup 4) (match_dup 5))
1314 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1315 {
1316 operands[3] = gen_highpart (SImode, operands[0]);
1317 operands[0] = gen_lowpart (SImode, operands[0]);
1318 operands[4] = gen_highpart (SImode, operands[1]);
1319 operands[1] = gen_lowpart (SImode, operands[1]);
1320 operands[5] = gen_highpart (SImode, operands[2]);
1321 operands[2] = gen_lowpart (SImode, operands[2]);
1322 }
1323 [(set_attr "conds" "clob")
1324 (set_attr "length" "8")
1325 (set_attr "type" "multiple")]
1326 )
1327
1328 (define_insn_and_split "*subdi_di_zesidi"
1329 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1330 (minus:DI (match_operand:DI 1 "s_register_operand" "0,r")
1331 (zero_extend:DI
1332 (match_operand:SI 2 "s_register_operand" "r,r"))))
1333 (clobber (reg:CC CC_REGNUM))]
1334 "TARGET_32BIT"
1335 "#" ; "subs\\t%Q0, %Q1, %2\;sbc\\t%R0, %R1, #0"
1336 "&& reload_completed"
1337 [(parallel [(set (reg:CC CC_REGNUM)
1338 (compare:CC (match_dup 1) (match_dup 2)))
1339 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1340 (set (match_dup 3) (minus:SI (match_dup 4)
1341 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1342 {
1343 operands[3] = gen_highpart (SImode, operands[0]);
1344 operands[0] = gen_lowpart (SImode, operands[0]);
1345 operands[4] = gen_highpart (SImode, operands[1]);
1346 operands[1] = gen_lowpart (SImode, operands[1]);
1347 }
1348 [(set_attr "conds" "clob")
1349 (set_attr "length" "8")
1350 (set_attr "type" "multiple")]
1351 )
1352
1353 (define_insn_and_split "*subdi_di_sesidi"
1354 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1355 (minus:DI (match_operand:DI 1 "s_register_operand" "0,r")
1356 (sign_extend:DI
1357 (match_operand:SI 2 "s_register_operand" "r,r"))))
1358 (clobber (reg:CC CC_REGNUM))]
1359 "TARGET_32BIT"
1360 "#" ; "subs\\t%Q0, %Q1, %2\;sbc\\t%R0, %R1, %2, asr #31"
1361 "&& reload_completed"
1362 [(parallel [(set (reg:CC CC_REGNUM)
1363 (compare:CC (match_dup 1) (match_dup 2)))
1364 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1365 (set (match_dup 3) (minus:SI (minus:SI (match_dup 4)
1366 (ashiftrt:SI (match_dup 2)
1367 (const_int 31)))
1368 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1369 {
1370 operands[3] = gen_highpart (SImode, operands[0]);
1371 operands[0] = gen_lowpart (SImode, operands[0]);
1372 operands[4] = gen_highpart (SImode, operands[1]);
1373 operands[1] = gen_lowpart (SImode, operands[1]);
1374 }
1375 [(set_attr "conds" "clob")
1376 (set_attr "length" "8")
1377 (set_attr "type" "multiple")]
1378 )
1379
1380 (define_insn_and_split "*subdi_zesidi_di"
1381 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1382 (minus:DI (zero_extend:DI
1383 (match_operand:SI 2 "s_register_operand" "r,r"))
1384 (match_operand:DI 1 "s_register_operand" "0,r")))
1385 (clobber (reg:CC CC_REGNUM))]
1386 "TARGET_ARM"
1387 "#" ; "rsbs\\t%Q0, %Q1, %2\;rsc\\t%R0, %R1, #0"
1388 ; is equivalent to:
1389 ; "subs\\t%Q0, %2, %Q1\;rsc\\t%R0, %R1, #0"
1390 "&& reload_completed"
1391 [(parallel [(set (reg:CC CC_REGNUM)
1392 (compare:CC (match_dup 2) (match_dup 1)))
1393 (set (match_dup 0) (minus:SI (match_dup 2) (match_dup 1)))])
1394 (set (match_dup 3) (minus:SI (minus:SI (const_int 0) (match_dup 4))
1395 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1396 {
1397 operands[3] = gen_highpart (SImode, operands[0]);
1398 operands[0] = gen_lowpart (SImode, operands[0]);
1399 operands[4] = gen_highpart (SImode, operands[1]);
1400 operands[1] = gen_lowpart (SImode, operands[1]);
1401 }
1402 [(set_attr "conds" "clob")
1403 (set_attr "length" "8")
1404 (set_attr "type" "multiple")]
1405 )
1406
1407 (define_insn_and_split "*subdi_sesidi_di"
1408 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1409 (minus:DI (sign_extend:DI
1410 (match_operand:SI 2 "s_register_operand" "r,r"))
1411 (match_operand:DI 1 "s_register_operand" "0,r")))
1412 (clobber (reg:CC CC_REGNUM))]
1413 "TARGET_ARM"
1414 "#" ; "rsbs\\t%Q0, %Q1, %2\;rsc\\t%R0, %R1, %2, asr #31"
1415 ; is equivalent to:
1416 ; "subs\\t%Q0, %2, %Q1\;rsc\\t%R0, %R1, %2, asr #31"
1417 "&& reload_completed"
1418 [(parallel [(set (reg:CC CC_REGNUM)
1419 (compare:CC (match_dup 2) (match_dup 1)))
1420 (set (match_dup 0) (minus:SI (match_dup 2) (match_dup 1)))])
1421 (set (match_dup 3) (minus:SI (minus:SI
1422 (ashiftrt:SI (match_dup 2)
1423 (const_int 31))
1424 (match_dup 4))
1425 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1426 {
1427 operands[3] = gen_highpart (SImode, operands[0]);
1428 operands[0] = gen_lowpart (SImode, operands[0]);
1429 operands[4] = gen_highpart (SImode, operands[1]);
1430 operands[1] = gen_lowpart (SImode, operands[1]);
1431 }
1432 [(set_attr "conds" "clob")
1433 (set_attr "length" "8")
1434 (set_attr "type" "multiple")]
1435 )
1436
1437 (define_insn_and_split "*subdi_zesidi_zesidi"
1438 [(set (match_operand:DI 0 "s_register_operand" "=r")
1439 (minus:DI (zero_extend:DI
1440 (match_operand:SI 1 "s_register_operand" "r"))
1441 (zero_extend:DI
1442 (match_operand:SI 2 "s_register_operand" "r"))))
1443 (clobber (reg:CC CC_REGNUM))]
1444 "TARGET_32BIT"
1445 "#" ; "subs\\t%Q0, %1, %2\;sbc\\t%R0, %1, %1"
1446 "&& reload_completed"
1447 [(parallel [(set (reg:CC CC_REGNUM)
1448 (compare:CC (match_dup 1) (match_dup 2)))
1449 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1450 (set (match_dup 3) (minus:SI (minus:SI (match_dup 1) (match_dup 1))
1451 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1452 {
1453 operands[3] = gen_highpart (SImode, operands[0]);
1454 operands[0] = gen_lowpart (SImode, operands[0]);
1455 }
1456 [(set_attr "conds" "clob")
1457 (set_attr "length" "8")
1458 (set_attr "type" "multiple")]
1459 )
1460
1461 (define_expand "subsi3"
1462 [(set (match_operand:SI 0 "s_register_operand" "")
1463 (minus:SI (match_operand:SI 1 "reg_or_int_operand" "")
1464 (match_operand:SI 2 "s_register_operand" "")))]
1465 "TARGET_EITHER"
1466 "
1467 if (CONST_INT_P (operands[1]))
1468 {
1469 if (TARGET_32BIT)
1470 {
1471 if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[1]), MINUS))
1472 operands[1] = force_reg (SImode, operands[1]);
1473 else
1474 {
1475 arm_split_constant (MINUS, SImode, NULL_RTX,
1476 INTVAL (operands[1]), operands[0],
1477 operands[2],
1478 optimize && can_create_pseudo_p ());
1479 DONE;
1480 }
1481 }
1482 else /* TARGET_THUMB1 */
1483 operands[1] = force_reg (SImode, operands[1]);
1484 }
1485 "
1486 )
1487
1488 ; ??? Check Thumb-2 split length
1489 (define_insn_and_split "*arm_subsi3_insn"
1490 [(set (match_operand:SI 0 "s_register_operand" "=l,l ,l ,l ,r,r,r,rk,r")
1491 (minus:SI (match_operand:SI 1 "reg_or_int_operand" "l ,0 ,l ,Pz,I,r,r,k ,?n")
1492 (match_operand:SI 2 "reg_or_int_operand" "l ,Py,Pd,l ,r,I,r,r ,r")))]
1493 "TARGET_32BIT"
1494 "@
1495 sub%?\\t%0, %1, %2
1496 sub%?\\t%0, %2
1497 sub%?\\t%0, %1, %2
1498 rsb%?\\t%0, %2, %1
1499 rsb%?\\t%0, %2, %1
1500 sub%?\\t%0, %1, %2
1501 sub%?\\t%0, %1, %2
1502 sub%?\\t%0, %1, %2
1503 #"
1504 "&& (CONST_INT_P (operands[1])
1505 && !const_ok_for_arm (INTVAL (operands[1])))"
1506 [(clobber (const_int 0))]
1507 "
1508 arm_split_constant (MINUS, SImode, curr_insn,
1509 INTVAL (operands[1]), operands[0], operands[2], 0);
1510 DONE;
1511 "
1512 [(set_attr "length" "4,4,4,4,4,4,4,4,16")
1513 (set_attr "arch" "t2,t2,t2,t2,*,*,*,*,*")
1514 (set_attr "predicable" "yes")
1515 (set_attr "predicable_short_it" "yes,yes,yes,yes,no,no,no,no,no")
1516 (set_attr "type" "alu_sreg,alu_sreg,alu_sreg,alu_sreg,alu_imm,alu_imm,alu_sreg,alu_sreg,multiple")]
1517 )
1518
1519 (define_peephole2
1520 [(match_scratch:SI 3 "r")
1521 (set (match_operand:SI 0 "arm_general_register_operand" "")
1522 (minus:SI (match_operand:SI 1 "const_int_operand" "")
1523 (match_operand:SI 2 "arm_general_register_operand" "")))]
1524 "TARGET_32BIT
1525 && !const_ok_for_arm (INTVAL (operands[1]))
1526 && const_ok_for_arm (~INTVAL (operands[1]))"
1527 [(set (match_dup 3) (match_dup 1))
1528 (set (match_dup 0) (minus:SI (match_dup 3) (match_dup 2)))]
1529 ""
1530 )
1531
1532 (define_insn "subsi3_compare0"
1533 [(set (reg:CC_NOOV CC_REGNUM)
1534 (compare:CC_NOOV
1535 (minus:SI (match_operand:SI 1 "arm_rhs_operand" "r,r,I")
1536 (match_operand:SI 2 "arm_rhs_operand" "I,r,r"))
1537 (const_int 0)))
1538 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
1539 (minus:SI (match_dup 1) (match_dup 2)))]
1540 "TARGET_32BIT"
1541 "@
1542 subs%?\\t%0, %1, %2
1543 subs%?\\t%0, %1, %2
1544 rsbs%?\\t%0, %2, %1"
1545 [(set_attr "conds" "set")
1546 (set_attr "type" "alus_imm,alus_sreg,alus_sreg")]
1547 )
1548
1549 (define_insn "subsi3_compare"
1550 [(set (reg:CC CC_REGNUM)
1551 (compare:CC (match_operand:SI 1 "arm_rhs_operand" "r,r,I")
1552 (match_operand:SI 2 "arm_rhs_operand" "I,r,r")))
1553 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
1554 (minus:SI (match_dup 1) (match_dup 2)))]
1555 "TARGET_32BIT"
1556 "@
1557 subs%?\\t%0, %1, %2
1558 subs%?\\t%0, %1, %2
1559 rsbs%?\\t%0, %2, %1"
1560 [(set_attr "conds" "set")
1561 (set_attr "type" "alus_imm,alus_sreg,alus_sreg")]
1562 )
1563
1564 (define_expand "subsf3"
1565 [(set (match_operand:SF 0 "s_register_operand" "")
1566 (minus:SF (match_operand:SF 1 "s_register_operand" "")
1567 (match_operand:SF 2 "s_register_operand" "")))]
1568 "TARGET_32BIT && TARGET_HARD_FLOAT"
1569 "
1570 ")
1571
1572 (define_expand "subdf3"
1573 [(set (match_operand:DF 0 "s_register_operand" "")
1574 (minus:DF (match_operand:DF 1 "s_register_operand" "")
1575 (match_operand:DF 2 "s_register_operand" "")))]
1576 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
1577 "
1578 ")
1579
1580 \f
1581 ;; Multiplication insns
1582
1583 (define_expand "mulhi3"
1584 [(set (match_operand:HI 0 "s_register_operand" "")
1585 (mult:HI (match_operand:HI 1 "s_register_operand" "")
1586 (match_operand:HI 2 "s_register_operand" "")))]
1587 "TARGET_DSP_MULTIPLY"
1588 "
1589 {
1590 rtx result = gen_reg_rtx (SImode);
1591 emit_insn (gen_mulhisi3 (result, operands[1], operands[2]));
1592 emit_move_insn (operands[0], gen_lowpart (HImode, result));
1593 DONE;
1594 }"
1595 )
1596
1597 (define_expand "mulsi3"
1598 [(set (match_operand:SI 0 "s_register_operand" "")
1599 (mult:SI (match_operand:SI 2 "s_register_operand" "")
1600 (match_operand:SI 1 "s_register_operand" "")))]
1601 "TARGET_EITHER"
1602 ""
1603 )
1604
1605 ;; Use `&' and then `0' to prevent the operands 0 and 1 being the same
1606 (define_insn "*arm_mulsi3"
1607 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1608 (mult:SI (match_operand:SI 2 "s_register_operand" "r,r")
1609 (match_operand:SI 1 "s_register_operand" "%0,r")))]
1610 "TARGET_32BIT && !arm_arch6"
1611 "mul%?\\t%0, %2, %1"
1612 [(set_attr "type" "mul")
1613 (set_attr "predicable" "yes")]
1614 )
1615
1616 (define_insn "*arm_mulsi3_v6"
1617 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r")
1618 (mult:SI (match_operand:SI 1 "s_register_operand" "0,l,r")
1619 (match_operand:SI 2 "s_register_operand" "l,0,r")))]
1620 "TARGET_32BIT && arm_arch6"
1621 "mul%?\\t%0, %1, %2"
1622 [(set_attr "type" "mul")
1623 (set_attr "predicable" "yes")
1624 (set_attr "arch" "t2,t2,*")
1625 (set_attr "length" "4")
1626 (set_attr "predicable_short_it" "yes,yes,no")]
1627 )
1628
1629 (define_insn "*mulsi3_compare0"
1630 [(set (reg:CC_NOOV CC_REGNUM)
1631 (compare:CC_NOOV (mult:SI
1632 (match_operand:SI 2 "s_register_operand" "r,r")
1633 (match_operand:SI 1 "s_register_operand" "%0,r"))
1634 (const_int 0)))
1635 (set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1636 (mult:SI (match_dup 2) (match_dup 1)))]
1637 "TARGET_ARM && !arm_arch6"
1638 "muls%?\\t%0, %2, %1"
1639 [(set_attr "conds" "set")
1640 (set_attr "type" "muls")]
1641 )
1642
1643 (define_insn "*mulsi3_compare0_v6"
1644 [(set (reg:CC_NOOV CC_REGNUM)
1645 (compare:CC_NOOV (mult:SI
1646 (match_operand:SI 2 "s_register_operand" "r")
1647 (match_operand:SI 1 "s_register_operand" "r"))
1648 (const_int 0)))
1649 (set (match_operand:SI 0 "s_register_operand" "=r")
1650 (mult:SI (match_dup 2) (match_dup 1)))]
1651 "TARGET_ARM && arm_arch6 && optimize_size"
1652 "muls%?\\t%0, %2, %1"
1653 [(set_attr "conds" "set")
1654 (set_attr "type" "muls")]
1655 )
1656
1657 (define_insn "*mulsi_compare0_scratch"
1658 [(set (reg:CC_NOOV CC_REGNUM)
1659 (compare:CC_NOOV (mult:SI
1660 (match_operand:SI 2 "s_register_operand" "r,r")
1661 (match_operand:SI 1 "s_register_operand" "%0,r"))
1662 (const_int 0)))
1663 (clobber (match_scratch:SI 0 "=&r,&r"))]
1664 "TARGET_ARM && !arm_arch6"
1665 "muls%?\\t%0, %2, %1"
1666 [(set_attr "conds" "set")
1667 (set_attr "type" "muls")]
1668 )
1669
1670 (define_insn "*mulsi_compare0_scratch_v6"
1671 [(set (reg:CC_NOOV CC_REGNUM)
1672 (compare:CC_NOOV (mult:SI
1673 (match_operand:SI 2 "s_register_operand" "r")
1674 (match_operand:SI 1 "s_register_operand" "r"))
1675 (const_int 0)))
1676 (clobber (match_scratch:SI 0 "=r"))]
1677 "TARGET_ARM && arm_arch6 && optimize_size"
1678 "muls%?\\t%0, %2, %1"
1679 [(set_attr "conds" "set")
1680 (set_attr "type" "muls")]
1681 )
1682
1683 ;; Unnamed templates to match MLA instruction.
1684
1685 (define_insn "*mulsi3addsi"
1686 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r,&r")
1687 (plus:SI
1688 (mult:SI (match_operand:SI 2 "s_register_operand" "r,r,r,r")
1689 (match_operand:SI 1 "s_register_operand" "%0,r,0,r"))
1690 (match_operand:SI 3 "s_register_operand" "r,r,0,0")))]
1691 "TARGET_32BIT && !arm_arch6"
1692 "mla%?\\t%0, %2, %1, %3"
1693 [(set_attr "type" "mla")
1694 (set_attr "predicable" "yes")]
1695 )
1696
1697 (define_insn "*mulsi3addsi_v6"
1698 [(set (match_operand:SI 0 "s_register_operand" "=r")
1699 (plus:SI
1700 (mult:SI (match_operand:SI 2 "s_register_operand" "r")
1701 (match_operand:SI 1 "s_register_operand" "r"))
1702 (match_operand:SI 3 "s_register_operand" "r")))]
1703 "TARGET_32BIT && arm_arch6"
1704 "mla%?\\t%0, %2, %1, %3"
1705 [(set_attr "type" "mla")
1706 (set_attr "predicable" "yes")]
1707 )
1708
1709 (define_insn "*mulsi3addsi_compare0"
1710 [(set (reg:CC_NOOV CC_REGNUM)
1711 (compare:CC_NOOV
1712 (plus:SI (mult:SI
1713 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
1714 (match_operand:SI 1 "s_register_operand" "%0,r,0,r"))
1715 (match_operand:SI 3 "s_register_operand" "r,r,0,0"))
1716 (const_int 0)))
1717 (set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r,&r")
1718 (plus:SI (mult:SI (match_dup 2) (match_dup 1))
1719 (match_dup 3)))]
1720 "TARGET_ARM && arm_arch6"
1721 "mlas%?\\t%0, %2, %1, %3"
1722 [(set_attr "conds" "set")
1723 (set_attr "type" "mlas")]
1724 )
1725
1726 (define_insn "*mulsi3addsi_compare0_v6"
1727 [(set (reg:CC_NOOV CC_REGNUM)
1728 (compare:CC_NOOV
1729 (plus:SI (mult:SI
1730 (match_operand:SI 2 "s_register_operand" "r")
1731 (match_operand:SI 1 "s_register_operand" "r"))
1732 (match_operand:SI 3 "s_register_operand" "r"))
1733 (const_int 0)))
1734 (set (match_operand:SI 0 "s_register_operand" "=r")
1735 (plus:SI (mult:SI (match_dup 2) (match_dup 1))
1736 (match_dup 3)))]
1737 "TARGET_ARM && arm_arch6 && optimize_size"
1738 "mlas%?\\t%0, %2, %1, %3"
1739 [(set_attr "conds" "set")
1740 (set_attr "type" "mlas")]
1741 )
1742
1743 (define_insn "*mulsi3addsi_compare0_scratch"
1744 [(set (reg:CC_NOOV CC_REGNUM)
1745 (compare:CC_NOOV
1746 (plus:SI (mult:SI
1747 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
1748 (match_operand:SI 1 "s_register_operand" "%0,r,0,r"))
1749 (match_operand:SI 3 "s_register_operand" "?r,r,0,0"))
1750 (const_int 0)))
1751 (clobber (match_scratch:SI 0 "=&r,&r,&r,&r"))]
1752 "TARGET_ARM && !arm_arch6"
1753 "mlas%?\\t%0, %2, %1, %3"
1754 [(set_attr "conds" "set")
1755 (set_attr "type" "mlas")]
1756 )
1757
1758 (define_insn "*mulsi3addsi_compare0_scratch_v6"
1759 [(set (reg:CC_NOOV CC_REGNUM)
1760 (compare:CC_NOOV
1761 (plus:SI (mult:SI
1762 (match_operand:SI 2 "s_register_operand" "r")
1763 (match_operand:SI 1 "s_register_operand" "r"))
1764 (match_operand:SI 3 "s_register_operand" "r"))
1765 (const_int 0)))
1766 (clobber (match_scratch:SI 0 "=r"))]
1767 "TARGET_ARM && arm_arch6 && optimize_size"
1768 "mlas%?\\t%0, %2, %1, %3"
1769 [(set_attr "conds" "set")
1770 (set_attr "type" "mlas")]
1771 )
1772
1773 (define_insn "*mulsi3subsi"
1774 [(set (match_operand:SI 0 "s_register_operand" "=r")
1775 (minus:SI
1776 (match_operand:SI 3 "s_register_operand" "r")
1777 (mult:SI (match_operand:SI 2 "s_register_operand" "r")
1778 (match_operand:SI 1 "s_register_operand" "r"))))]
1779 "TARGET_32BIT && arm_arch_thumb2"
1780 "mls%?\\t%0, %2, %1, %3"
1781 [(set_attr "type" "mla")
1782 (set_attr "predicable" "yes")]
1783 )
1784
1785 (define_expand "maddsidi4"
1786 [(set (match_operand:DI 0 "s_register_operand" "")
1787 (plus:DI
1788 (mult:DI
1789 (sign_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1790 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1791 (match_operand:DI 3 "s_register_operand" "")))]
1792 "TARGET_32BIT"
1793 "")
1794
1795 (define_insn "*mulsidi3adddi"
1796 [(set (match_operand:DI 0 "s_register_operand" "=&r")
1797 (plus:DI
1798 (mult:DI
1799 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "%r"))
1800 (sign_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1801 (match_operand:DI 1 "s_register_operand" "0")))]
1802 "TARGET_32BIT && !arm_arch6"
1803 "smlal%?\\t%Q0, %R0, %3, %2"
1804 [(set_attr "type" "smlal")
1805 (set_attr "predicable" "yes")]
1806 )
1807
1808 (define_insn "*mulsidi3adddi_v6"
1809 [(set (match_operand:DI 0 "s_register_operand" "=r")
1810 (plus:DI
1811 (mult:DI
1812 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r"))
1813 (sign_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1814 (match_operand:DI 1 "s_register_operand" "0")))]
1815 "TARGET_32BIT && arm_arch6"
1816 "smlal%?\\t%Q0, %R0, %3, %2"
1817 [(set_attr "type" "smlal")
1818 (set_attr "predicable" "yes")]
1819 )
1820
1821 ;; 32x32->64 widening multiply.
1822 ;; As with mulsi3, the only difference between the v3-5 and v6+
1823 ;; versions of these patterns is the requirement that the output not
1824 ;; overlap the inputs, but that still means we have to have a named
1825 ;; expander and two different starred insns.
1826
1827 (define_expand "mulsidi3"
1828 [(set (match_operand:DI 0 "s_register_operand" "")
1829 (mult:DI
1830 (sign_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1831 (sign_extend:DI (match_operand:SI 2 "s_register_operand" ""))))]
1832 "TARGET_32BIT"
1833 ""
1834 )
1835
1836 (define_insn "*mulsidi3_nov6"
1837 [(set (match_operand:DI 0 "s_register_operand" "=&r")
1838 (mult:DI
1839 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "%r"))
1840 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1841 "TARGET_32BIT && !arm_arch6"
1842 "smull%?\\t%Q0, %R0, %1, %2"
1843 [(set_attr "type" "smull")
1844 (set_attr "predicable" "yes")]
1845 )
1846
1847 (define_insn "*mulsidi3_v6"
1848 [(set (match_operand:DI 0 "s_register_operand" "=r")
1849 (mult:DI
1850 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1851 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1852 "TARGET_32BIT && arm_arch6"
1853 "smull%?\\t%Q0, %R0, %1, %2"
1854 [(set_attr "type" "smull")
1855 (set_attr "predicable" "yes")]
1856 )
1857
1858 (define_expand "umulsidi3"
1859 [(set (match_operand:DI 0 "s_register_operand" "")
1860 (mult:DI
1861 (zero_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1862 (zero_extend:DI (match_operand:SI 2 "s_register_operand" ""))))]
1863 "TARGET_32BIT"
1864 ""
1865 )
1866
1867 (define_insn "*umulsidi3_nov6"
1868 [(set (match_operand:DI 0 "s_register_operand" "=&r")
1869 (mult:DI
1870 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "%r"))
1871 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1872 "TARGET_32BIT && !arm_arch6"
1873 "umull%?\\t%Q0, %R0, %1, %2"
1874 [(set_attr "type" "umull")
1875 (set_attr "predicable" "yes")]
1876 )
1877
1878 (define_insn "*umulsidi3_v6"
1879 [(set (match_operand:DI 0 "s_register_operand" "=r")
1880 (mult:DI
1881 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1882 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1883 "TARGET_32BIT && arm_arch6"
1884 "umull%?\\t%Q0, %R0, %1, %2"
1885 [(set_attr "type" "umull")
1886 (set_attr "predicable" "yes")]
1887 )
1888
1889 (define_expand "umaddsidi4"
1890 [(set (match_operand:DI 0 "s_register_operand" "")
1891 (plus:DI
1892 (mult:DI
1893 (zero_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1894 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1895 (match_operand:DI 3 "s_register_operand" "")))]
1896 "TARGET_32BIT"
1897 "")
1898
1899 (define_insn "*umulsidi3adddi"
1900 [(set (match_operand:DI 0 "s_register_operand" "=&r")
1901 (plus:DI
1902 (mult:DI
1903 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "%r"))
1904 (zero_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1905 (match_operand:DI 1 "s_register_operand" "0")))]
1906 "TARGET_32BIT && !arm_arch6"
1907 "umlal%?\\t%Q0, %R0, %3, %2"
1908 [(set_attr "type" "umlal")
1909 (set_attr "predicable" "yes")]
1910 )
1911
1912 (define_insn "*umulsidi3adddi_v6"
1913 [(set (match_operand:DI 0 "s_register_operand" "=r")
1914 (plus:DI
1915 (mult:DI
1916 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r"))
1917 (zero_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1918 (match_operand:DI 1 "s_register_operand" "0")))]
1919 "TARGET_32BIT && arm_arch6"
1920 "umlal%?\\t%Q0, %R0, %3, %2"
1921 [(set_attr "type" "umlal")
1922 (set_attr "predicable" "yes")]
1923 )
1924
1925 (define_expand "smulsi3_highpart"
1926 [(parallel
1927 [(set (match_operand:SI 0 "s_register_operand" "")
1928 (truncate:SI
1929 (lshiftrt:DI
1930 (mult:DI
1931 (sign_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1932 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1933 (const_int 32))))
1934 (clobber (match_scratch:SI 3 ""))])]
1935 "TARGET_32BIT"
1936 ""
1937 )
1938
1939 (define_insn "*smulsi3_highpart_nov6"
1940 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1941 (truncate:SI
1942 (lshiftrt:DI
1943 (mult:DI
1944 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "%0,r"))
1945 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r,r")))
1946 (const_int 32))))
1947 (clobber (match_scratch:SI 3 "=&r,&r"))]
1948 "TARGET_32BIT && !arm_arch6"
1949 "smull%?\\t%3, %0, %2, %1"
1950 [(set_attr "type" "smull")
1951 (set_attr "predicable" "yes")]
1952 )
1953
1954 (define_insn "*smulsi3_highpart_v6"
1955 [(set (match_operand:SI 0 "s_register_operand" "=r")
1956 (truncate:SI
1957 (lshiftrt:DI
1958 (mult:DI
1959 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1960 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r")))
1961 (const_int 32))))
1962 (clobber (match_scratch:SI 3 "=r"))]
1963 "TARGET_32BIT && arm_arch6"
1964 "smull%?\\t%3, %0, %2, %1"
1965 [(set_attr "type" "smull")
1966 (set_attr "predicable" "yes")]
1967 )
1968
1969 (define_expand "umulsi3_highpart"
1970 [(parallel
1971 [(set (match_operand:SI 0 "s_register_operand" "")
1972 (truncate:SI
1973 (lshiftrt:DI
1974 (mult:DI
1975 (zero_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1976 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1977 (const_int 32))))
1978 (clobber (match_scratch:SI 3 ""))])]
1979 "TARGET_32BIT"
1980 ""
1981 )
1982
1983 (define_insn "*umulsi3_highpart_nov6"
1984 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1985 (truncate:SI
1986 (lshiftrt:DI
1987 (mult:DI
1988 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "%0,r"))
1989 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r,r")))
1990 (const_int 32))))
1991 (clobber (match_scratch:SI 3 "=&r,&r"))]
1992 "TARGET_32BIT && !arm_arch6"
1993 "umull%?\\t%3, %0, %2, %1"
1994 [(set_attr "type" "umull")
1995 (set_attr "predicable" "yes")]
1996 )
1997
1998 (define_insn "*umulsi3_highpart_v6"
1999 [(set (match_operand:SI 0 "s_register_operand" "=r")
2000 (truncate:SI
2001 (lshiftrt:DI
2002 (mult:DI
2003 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
2004 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r")))
2005 (const_int 32))))
2006 (clobber (match_scratch:SI 3 "=r"))]
2007 "TARGET_32BIT && arm_arch6"
2008 "umull%?\\t%3, %0, %2, %1"
2009 [(set_attr "type" "umull")
2010 (set_attr "predicable" "yes")]
2011 )
2012
2013 (define_insn "mulhisi3"
2014 [(set (match_operand:SI 0 "s_register_operand" "=r")
2015 (mult:SI (sign_extend:SI
2016 (match_operand:HI 1 "s_register_operand" "%r"))
2017 (sign_extend:SI
2018 (match_operand:HI 2 "s_register_operand" "r"))))]
2019 "TARGET_DSP_MULTIPLY"
2020 "smulbb%?\\t%0, %1, %2"
2021 [(set_attr "type" "smulxy")
2022 (set_attr "predicable" "yes")]
2023 )
2024
2025 (define_insn "*mulhisi3tb"
2026 [(set (match_operand:SI 0 "s_register_operand" "=r")
2027 (mult:SI (ashiftrt:SI
2028 (match_operand:SI 1 "s_register_operand" "r")
2029 (const_int 16))
2030 (sign_extend:SI
2031 (match_operand:HI 2 "s_register_operand" "r"))))]
2032 "TARGET_DSP_MULTIPLY"
2033 "smultb%?\\t%0, %1, %2"
2034 [(set_attr "type" "smulxy")
2035 (set_attr "predicable" "yes")]
2036 )
2037
2038 (define_insn "*mulhisi3bt"
2039 [(set (match_operand:SI 0 "s_register_operand" "=r")
2040 (mult:SI (sign_extend:SI
2041 (match_operand:HI 1 "s_register_operand" "r"))
2042 (ashiftrt:SI
2043 (match_operand:SI 2 "s_register_operand" "r")
2044 (const_int 16))))]
2045 "TARGET_DSP_MULTIPLY"
2046 "smulbt%?\\t%0, %1, %2"
2047 [(set_attr "type" "smulxy")
2048 (set_attr "predicable" "yes")]
2049 )
2050
2051 (define_insn "*mulhisi3tt"
2052 [(set (match_operand:SI 0 "s_register_operand" "=r")
2053 (mult:SI (ashiftrt:SI
2054 (match_operand:SI 1 "s_register_operand" "r")
2055 (const_int 16))
2056 (ashiftrt:SI
2057 (match_operand:SI 2 "s_register_operand" "r")
2058 (const_int 16))))]
2059 "TARGET_DSP_MULTIPLY"
2060 "smultt%?\\t%0, %1, %2"
2061 [(set_attr "type" "smulxy")
2062 (set_attr "predicable" "yes")]
2063 )
2064
2065 (define_insn "maddhisi4"
2066 [(set (match_operand:SI 0 "s_register_operand" "=r")
2067 (plus:SI (mult:SI (sign_extend:SI
2068 (match_operand:HI 1 "s_register_operand" "r"))
2069 (sign_extend:SI
2070 (match_operand:HI 2 "s_register_operand" "r")))
2071 (match_operand:SI 3 "s_register_operand" "r")))]
2072 "TARGET_DSP_MULTIPLY"
2073 "smlabb%?\\t%0, %1, %2, %3"
2074 [(set_attr "type" "smlaxy")
2075 (set_attr "predicable" "yes")]
2076 )
2077
2078 ;; Note: there is no maddhisi4ibt because this one is canonical form
2079 (define_insn "*maddhisi4tb"
2080 [(set (match_operand:SI 0 "s_register_operand" "=r")
2081 (plus:SI (mult:SI (ashiftrt:SI
2082 (match_operand:SI 1 "s_register_operand" "r")
2083 (const_int 16))
2084 (sign_extend:SI
2085 (match_operand:HI 2 "s_register_operand" "r")))
2086 (match_operand:SI 3 "s_register_operand" "r")))]
2087 "TARGET_DSP_MULTIPLY"
2088 "smlatb%?\\t%0, %1, %2, %3"
2089 [(set_attr "type" "smlaxy")
2090 (set_attr "predicable" "yes")]
2091 )
2092
2093 (define_insn "*maddhisi4tt"
2094 [(set (match_operand:SI 0 "s_register_operand" "=r")
2095 (plus:SI (mult:SI (ashiftrt:SI
2096 (match_operand:SI 1 "s_register_operand" "r")
2097 (const_int 16))
2098 (ashiftrt:SI
2099 (match_operand:SI 2 "s_register_operand" "r")
2100 (const_int 16)))
2101 (match_operand:SI 3 "s_register_operand" "r")))]
2102 "TARGET_DSP_MULTIPLY"
2103 "smlatt%?\\t%0, %1, %2, %3"
2104 [(set_attr "type" "smlaxy")
2105 (set_attr "predicable" "yes")]
2106 )
2107
2108 (define_insn "maddhidi4"
2109 [(set (match_operand:DI 0 "s_register_operand" "=r")
2110 (plus:DI
2111 (mult:DI (sign_extend:DI
2112 (match_operand:HI 1 "s_register_operand" "r"))
2113 (sign_extend:DI
2114 (match_operand:HI 2 "s_register_operand" "r")))
2115 (match_operand:DI 3 "s_register_operand" "0")))]
2116 "TARGET_DSP_MULTIPLY"
2117 "smlalbb%?\\t%Q0, %R0, %1, %2"
2118 [(set_attr "type" "smlalxy")
2119 (set_attr "predicable" "yes")])
2120
2121 ;; Note: there is no maddhidi4ibt because this one is canonical form
2122 (define_insn "*maddhidi4tb"
2123 [(set (match_operand:DI 0 "s_register_operand" "=r")
2124 (plus:DI
2125 (mult:DI (sign_extend:DI
2126 (ashiftrt:SI
2127 (match_operand:SI 1 "s_register_operand" "r")
2128 (const_int 16)))
2129 (sign_extend:DI
2130 (match_operand:HI 2 "s_register_operand" "r")))
2131 (match_operand:DI 3 "s_register_operand" "0")))]
2132 "TARGET_DSP_MULTIPLY"
2133 "smlaltb%?\\t%Q0, %R0, %1, %2"
2134 [(set_attr "type" "smlalxy")
2135 (set_attr "predicable" "yes")])
2136
2137 (define_insn "*maddhidi4tt"
2138 [(set (match_operand:DI 0 "s_register_operand" "=r")
2139 (plus:DI
2140 (mult:DI (sign_extend:DI
2141 (ashiftrt:SI
2142 (match_operand:SI 1 "s_register_operand" "r")
2143 (const_int 16)))
2144 (sign_extend:DI
2145 (ashiftrt:SI
2146 (match_operand:SI 2 "s_register_operand" "r")
2147 (const_int 16))))
2148 (match_operand:DI 3 "s_register_operand" "0")))]
2149 "TARGET_DSP_MULTIPLY"
2150 "smlaltt%?\\t%Q0, %R0, %1, %2"
2151 [(set_attr "type" "smlalxy")
2152 (set_attr "predicable" "yes")])
2153
2154 (define_expand "mulsf3"
2155 [(set (match_operand:SF 0 "s_register_operand" "")
2156 (mult:SF (match_operand:SF 1 "s_register_operand" "")
2157 (match_operand:SF 2 "s_register_operand" "")))]
2158 "TARGET_32BIT && TARGET_HARD_FLOAT"
2159 "
2160 ")
2161
2162 (define_expand "muldf3"
2163 [(set (match_operand:DF 0 "s_register_operand" "")
2164 (mult:DF (match_operand:DF 1 "s_register_operand" "")
2165 (match_operand:DF 2 "s_register_operand" "")))]
2166 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
2167 "
2168 ")
2169 \f
2170 ;; Division insns
2171
2172 (define_expand "divsf3"
2173 [(set (match_operand:SF 0 "s_register_operand" "")
2174 (div:SF (match_operand:SF 1 "s_register_operand" "")
2175 (match_operand:SF 2 "s_register_operand" "")))]
2176 "TARGET_32BIT && TARGET_HARD_FLOAT"
2177 "")
2178
2179 (define_expand "divdf3"
2180 [(set (match_operand:DF 0 "s_register_operand" "")
2181 (div:DF (match_operand:DF 1 "s_register_operand" "")
2182 (match_operand:DF 2 "s_register_operand" "")))]
2183 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
2184 "")
2185 \f
2186 ;; Boolean and,ior,xor insns
2187
2188 ;; Split up double word logical operations
2189
2190 ;; Split up simple DImode logical operations. Simply perform the logical
2191 ;; operation on the upper and lower halves of the registers.
2192 (define_split
2193 [(set (match_operand:DI 0 "s_register_operand" "")
2194 (match_operator:DI 6 "logical_binary_operator"
2195 [(match_operand:DI 1 "s_register_operand" "")
2196 (match_operand:DI 2 "s_register_operand" "")]))]
2197 "TARGET_32BIT && reload_completed
2198 && ! (TARGET_NEON && IS_VFP_REGNUM (REGNO (operands[0])))
2199 && ! IS_IWMMXT_REGNUM (REGNO (operands[0]))"
2200 [(set (match_dup 0) (match_op_dup:SI 6 [(match_dup 1) (match_dup 2)]))
2201 (set (match_dup 3) (match_op_dup:SI 6 [(match_dup 4) (match_dup 5)]))]
2202 "
2203 {
2204 operands[3] = gen_highpart (SImode, operands[0]);
2205 operands[0] = gen_lowpart (SImode, operands[0]);
2206 operands[4] = gen_highpart (SImode, operands[1]);
2207 operands[1] = gen_lowpart (SImode, operands[1]);
2208 operands[5] = gen_highpart (SImode, operands[2]);
2209 operands[2] = gen_lowpart (SImode, operands[2]);
2210 }"
2211 )
2212
2213 (define_split
2214 [(set (match_operand:DI 0 "s_register_operand" "")
2215 (match_operator:DI 6 "logical_binary_operator"
2216 [(sign_extend:DI (match_operand:SI 2 "s_register_operand" ""))
2217 (match_operand:DI 1 "s_register_operand" "")]))]
2218 "TARGET_32BIT && reload_completed"
2219 [(set (match_dup 0) (match_op_dup:SI 6 [(match_dup 1) (match_dup 2)]))
2220 (set (match_dup 3) (match_op_dup:SI 6
2221 [(ashiftrt:SI (match_dup 2) (const_int 31))
2222 (match_dup 4)]))]
2223 "
2224 {
2225 operands[3] = gen_highpart (SImode, operands[0]);
2226 operands[0] = gen_lowpart (SImode, operands[0]);
2227 operands[4] = gen_highpart (SImode, operands[1]);
2228 operands[1] = gen_lowpart (SImode, operands[1]);
2229 operands[5] = gen_highpart (SImode, operands[2]);
2230 operands[2] = gen_lowpart (SImode, operands[2]);
2231 }"
2232 )
2233
2234 ;; The zero extend of operand 2 means we can just copy the high part of
2235 ;; operand1 into operand0.
2236 (define_split
2237 [(set (match_operand:DI 0 "s_register_operand" "")
2238 (ior:DI
2239 (zero_extend:DI (match_operand:SI 2 "s_register_operand" ""))
2240 (match_operand:DI 1 "s_register_operand" "")))]
2241 "TARGET_32BIT && operands[0] != operands[1] && reload_completed"
2242 [(set (match_dup 0) (ior:SI (match_dup 1) (match_dup 2)))
2243 (set (match_dup 3) (match_dup 4))]
2244 "
2245 {
2246 operands[4] = gen_highpart (SImode, operands[1]);
2247 operands[3] = gen_highpart (SImode, operands[0]);
2248 operands[0] = gen_lowpart (SImode, operands[0]);
2249 operands[1] = gen_lowpart (SImode, operands[1]);
2250 }"
2251 )
2252
2253 ;; The zero extend of operand 2 means we can just copy the high part of
2254 ;; operand1 into operand0.
2255 (define_split
2256 [(set (match_operand:DI 0 "s_register_operand" "")
2257 (xor:DI
2258 (zero_extend:DI (match_operand:SI 2 "s_register_operand" ""))
2259 (match_operand:DI 1 "s_register_operand" "")))]
2260 "TARGET_32BIT && operands[0] != operands[1] && reload_completed"
2261 [(set (match_dup 0) (xor:SI (match_dup 1) (match_dup 2)))
2262 (set (match_dup 3) (match_dup 4))]
2263 "
2264 {
2265 operands[4] = gen_highpart (SImode, operands[1]);
2266 operands[3] = gen_highpart (SImode, operands[0]);
2267 operands[0] = gen_lowpart (SImode, operands[0]);
2268 operands[1] = gen_lowpart (SImode, operands[1]);
2269 }"
2270 )
2271
2272 (define_expand "anddi3"
2273 [(set (match_operand:DI 0 "s_register_operand" "")
2274 (and:DI (match_operand:DI 1 "s_register_operand" "")
2275 (match_operand:DI 2 "neon_inv_logic_op2" "")))]
2276 "TARGET_32BIT"
2277 "
2278 if (!TARGET_NEON && !TARGET_IWMMXT)
2279 {
2280 rtx low = simplify_gen_binary (AND, SImode,
2281 gen_lowpart (SImode, operands[1]),
2282 gen_lowpart (SImode, operands[2]));
2283 rtx high = simplify_gen_binary (AND, SImode,
2284 gen_highpart (SImode, operands[1]),
2285 gen_highpart_mode (SImode, DImode,
2286 operands[2]));
2287
2288 emit_insn (gen_rtx_SET (gen_lowpart (SImode, operands[0]), low));
2289 emit_insn (gen_rtx_SET (gen_highpart (SImode, operands[0]), high));
2290
2291 DONE;
2292 }
2293 /* Otherwise expand pattern as above. */
2294 "
2295 )
2296
2297 (define_insn_and_split "*anddi3_insn"
2298 [(set (match_operand:DI 0 "s_register_operand" "=w,w ,&r,&r,&r,&r,?w,?w")
2299 (and:DI (match_operand:DI 1 "s_register_operand" "%w,0 ,0 ,r ,0 ,r ,w ,0")
2300 (match_operand:DI 2 "arm_anddi_operand_neon" "w ,DL,r ,r ,De,De,w ,DL")))]
2301 "TARGET_32BIT && !TARGET_IWMMXT"
2302 {
2303 switch (which_alternative)
2304 {
2305 case 0: /* fall through */
2306 case 6: return "vand\t%P0, %P1, %P2";
2307 case 1: /* fall through */
2308 case 7: return neon_output_logic_immediate ("vand", &operands[2],
2309 DImode, 1, VALID_NEON_QREG_MODE (DImode));
2310 case 2:
2311 case 3:
2312 case 4:
2313 case 5: /* fall through */
2314 return "#";
2315 default: gcc_unreachable ();
2316 }
2317 }
2318 "TARGET_32BIT && !TARGET_IWMMXT && reload_completed
2319 && !(IS_VFP_REGNUM (REGNO (operands[0])))"
2320 [(set (match_dup 3) (match_dup 4))
2321 (set (match_dup 5) (match_dup 6))]
2322 "
2323 {
2324 operands[3] = gen_lowpart (SImode, operands[0]);
2325 operands[5] = gen_highpart (SImode, operands[0]);
2326
2327 operands[4] = simplify_gen_binary (AND, SImode,
2328 gen_lowpart (SImode, operands[1]),
2329 gen_lowpart (SImode, operands[2]));
2330 operands[6] = simplify_gen_binary (AND, SImode,
2331 gen_highpart (SImode, operands[1]),
2332 gen_highpart_mode (SImode, DImode, operands[2]));
2333
2334 }"
2335 [(set_attr "type" "neon_logic,neon_logic,multiple,multiple,\
2336 multiple,multiple,neon_logic,neon_logic")
2337 (set_attr "arch" "neon_for_64bits,neon_for_64bits,*,*,*,*,
2338 avoid_neon_for_64bits,avoid_neon_for_64bits")
2339 (set_attr "length" "*,*,8,8,8,8,*,*")
2340 ]
2341 )
2342
2343 (define_insn_and_split "*anddi_zesidi_di"
2344 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2345 (and:DI (zero_extend:DI
2346 (match_operand:SI 2 "s_register_operand" "r,r"))
2347 (match_operand:DI 1 "s_register_operand" "0,r")))]
2348 "TARGET_32BIT"
2349 "#"
2350 "TARGET_32BIT && reload_completed"
2351 ; The zero extend of operand 2 clears the high word of the output
2352 ; operand.
2353 [(set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))
2354 (set (match_dup 3) (const_int 0))]
2355 "
2356 {
2357 operands[3] = gen_highpart (SImode, operands[0]);
2358 operands[0] = gen_lowpart (SImode, operands[0]);
2359 operands[1] = gen_lowpart (SImode, operands[1]);
2360 }"
2361 [(set_attr "length" "8")
2362 (set_attr "type" "multiple")]
2363 )
2364
2365 (define_insn "*anddi_sesdi_di"
2366 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2367 (and:DI (sign_extend:DI
2368 (match_operand:SI 2 "s_register_operand" "r,r"))
2369 (match_operand:DI 1 "s_register_operand" "0,r")))]
2370 "TARGET_32BIT"
2371 "#"
2372 [(set_attr "length" "8")
2373 (set_attr "type" "multiple")]
2374 )
2375
2376 (define_expand "andsi3"
2377 [(set (match_operand:SI 0 "s_register_operand" "")
2378 (and:SI (match_operand:SI 1 "s_register_operand" "")
2379 (match_operand:SI 2 "reg_or_int_operand" "")))]
2380 "TARGET_EITHER"
2381 "
2382 if (TARGET_32BIT)
2383 {
2384 if (CONST_INT_P (operands[2]))
2385 {
2386 if (INTVAL (operands[2]) == 255 && arm_arch6)
2387 {
2388 operands[1] = convert_to_mode (QImode, operands[1], 1);
2389 emit_insn (gen_thumb2_zero_extendqisi2_v6 (operands[0],
2390 operands[1]));
2391 DONE;
2392 }
2393 else if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[2]), AND))
2394 operands[2] = force_reg (SImode, operands[2]);
2395 else
2396 {
2397 arm_split_constant (AND, SImode, NULL_RTX,
2398 INTVAL (operands[2]), operands[0],
2399 operands[1],
2400 optimize && can_create_pseudo_p ());
2401
2402 DONE;
2403 }
2404 }
2405 }
2406 else /* TARGET_THUMB1 */
2407 {
2408 if (!CONST_INT_P (operands[2]))
2409 {
2410 rtx tmp = force_reg (SImode, operands[2]);
2411 if (rtx_equal_p (operands[0], operands[1]))
2412 operands[2] = tmp;
2413 else
2414 {
2415 operands[2] = operands[1];
2416 operands[1] = tmp;
2417 }
2418 }
2419 else
2420 {
2421 int i;
2422
2423 if (((unsigned HOST_WIDE_INT) ~INTVAL (operands[2])) < 256)
2424 {
2425 operands[2] = force_reg (SImode,
2426 GEN_INT (~INTVAL (operands[2])));
2427
2428 emit_insn (gen_thumb1_bicsi3 (operands[0], operands[2], operands[1]));
2429
2430 DONE;
2431 }
2432
2433 for (i = 9; i <= 31; i++)
2434 {
2435 if ((HOST_WIDE_INT_1 << i) - 1 == INTVAL (operands[2]))
2436 {
2437 emit_insn (gen_extzv (operands[0], operands[1], GEN_INT (i),
2438 const0_rtx));
2439 DONE;
2440 }
2441 else if ((HOST_WIDE_INT_1 << i) - 1
2442 == ~INTVAL (operands[2]))
2443 {
2444 rtx shift = GEN_INT (i);
2445 rtx reg = gen_reg_rtx (SImode);
2446
2447 emit_insn (gen_lshrsi3 (reg, operands[1], shift));
2448 emit_insn (gen_ashlsi3 (operands[0], reg, shift));
2449
2450 DONE;
2451 }
2452 }
2453
2454 operands[2] = force_reg (SImode, operands[2]);
2455 }
2456 }
2457 "
2458 )
2459
2460 ; ??? Check split length for Thumb-2
2461 (define_insn_and_split "*arm_andsi3_insn"
2462 [(set (match_operand:SI 0 "s_register_operand" "=r,l,r,r,r")
2463 (and:SI (match_operand:SI 1 "s_register_operand" "%r,0,r,r,r")
2464 (match_operand:SI 2 "reg_or_int_operand" "I,l,K,r,?n")))]
2465 "TARGET_32BIT"
2466 "@
2467 and%?\\t%0, %1, %2
2468 and%?\\t%0, %1, %2
2469 bic%?\\t%0, %1, #%B2
2470 and%?\\t%0, %1, %2
2471 #"
2472 "TARGET_32BIT
2473 && CONST_INT_P (operands[2])
2474 && !(const_ok_for_arm (INTVAL (operands[2]))
2475 || const_ok_for_arm (~INTVAL (operands[2])))"
2476 [(clobber (const_int 0))]
2477 "
2478 arm_split_constant (AND, SImode, curr_insn,
2479 INTVAL (operands[2]), operands[0], operands[1], 0);
2480 DONE;
2481 "
2482 [(set_attr "length" "4,4,4,4,16")
2483 (set_attr "predicable" "yes")
2484 (set_attr "predicable_short_it" "no,yes,no,no,no")
2485 (set_attr "type" "logic_imm,logic_imm,logic_reg,logic_reg,logic_imm")]
2486 )
2487
2488 (define_insn "*andsi3_compare0"
2489 [(set (reg:CC_NOOV CC_REGNUM)
2490 (compare:CC_NOOV
2491 (and:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
2492 (match_operand:SI 2 "arm_not_operand" "I,K,r"))
2493 (const_int 0)))
2494 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
2495 (and:SI (match_dup 1) (match_dup 2)))]
2496 "TARGET_32BIT"
2497 "@
2498 ands%?\\t%0, %1, %2
2499 bics%?\\t%0, %1, #%B2
2500 ands%?\\t%0, %1, %2"
2501 [(set_attr "conds" "set")
2502 (set_attr "type" "logics_imm,logics_imm,logics_reg")]
2503 )
2504
2505 (define_insn "*andsi3_compare0_scratch"
2506 [(set (reg:CC_NOOV CC_REGNUM)
2507 (compare:CC_NOOV
2508 (and:SI (match_operand:SI 0 "s_register_operand" "r,r,r")
2509 (match_operand:SI 1 "arm_not_operand" "I,K,r"))
2510 (const_int 0)))
2511 (clobber (match_scratch:SI 2 "=X,r,X"))]
2512 "TARGET_32BIT"
2513 "@
2514 tst%?\\t%0, %1
2515 bics%?\\t%2, %0, #%B1
2516 tst%?\\t%0, %1"
2517 [(set_attr "conds" "set")
2518 (set_attr "type" "logics_imm,logics_imm,logics_reg")]
2519 )
2520
2521 (define_insn "*zeroextractsi_compare0_scratch"
2522 [(set (reg:CC_NOOV CC_REGNUM)
2523 (compare:CC_NOOV (zero_extract:SI
2524 (match_operand:SI 0 "s_register_operand" "r")
2525 (match_operand 1 "const_int_operand" "n")
2526 (match_operand 2 "const_int_operand" "n"))
2527 (const_int 0)))]
2528 "TARGET_32BIT
2529 && (INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) < 32
2530 && INTVAL (operands[1]) > 0
2531 && INTVAL (operands[1]) + (INTVAL (operands[2]) & 1) <= 8
2532 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32)"
2533 "*
2534 operands[1] = GEN_INT (((1 << INTVAL (operands[1])) - 1)
2535 << INTVAL (operands[2]));
2536 output_asm_insn (\"tst%?\\t%0, %1\", operands);
2537 return \"\";
2538 "
2539 [(set_attr "conds" "set")
2540 (set_attr "predicable" "yes")
2541 (set_attr "type" "logics_imm")]
2542 )
2543
2544 (define_insn_and_split "*ne_zeroextractsi"
2545 [(set (match_operand:SI 0 "s_register_operand" "=r")
2546 (ne:SI (zero_extract:SI
2547 (match_operand:SI 1 "s_register_operand" "r")
2548 (match_operand:SI 2 "const_int_operand" "n")
2549 (match_operand:SI 3 "const_int_operand" "n"))
2550 (const_int 0)))
2551 (clobber (reg:CC CC_REGNUM))]
2552 "TARGET_32BIT
2553 && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2554 && INTVAL (operands[2]) > 0
2555 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2556 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)"
2557 "#"
2558 "TARGET_32BIT
2559 && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2560 && INTVAL (operands[2]) > 0
2561 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2562 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)"
2563 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2564 (compare:CC_NOOV (and:SI (match_dup 1) (match_dup 2))
2565 (const_int 0)))
2566 (set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))])
2567 (set (match_dup 0)
2568 (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2569 (match_dup 0) (const_int 1)))]
2570 "
2571 operands[2] = GEN_INT (((1 << INTVAL (operands[2])) - 1)
2572 << INTVAL (operands[3]));
2573 "
2574 [(set_attr "conds" "clob")
2575 (set (attr "length")
2576 (if_then_else (eq_attr "is_thumb" "yes")
2577 (const_int 12)
2578 (const_int 8)))
2579 (set_attr "type" "multiple")]
2580 )
2581
2582 (define_insn_and_split "*ne_zeroextractsi_shifted"
2583 [(set (match_operand:SI 0 "s_register_operand" "=r")
2584 (ne:SI (zero_extract:SI
2585 (match_operand:SI 1 "s_register_operand" "r")
2586 (match_operand:SI 2 "const_int_operand" "n")
2587 (const_int 0))
2588 (const_int 0)))
2589 (clobber (reg:CC CC_REGNUM))]
2590 "TARGET_ARM"
2591 "#"
2592 "TARGET_ARM"
2593 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2594 (compare:CC_NOOV (ashift:SI (match_dup 1) (match_dup 2))
2595 (const_int 0)))
2596 (set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))])
2597 (set (match_dup 0)
2598 (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2599 (match_dup 0) (const_int 1)))]
2600 "
2601 operands[2] = GEN_INT (32 - INTVAL (operands[2]));
2602 "
2603 [(set_attr "conds" "clob")
2604 (set_attr "length" "8")
2605 (set_attr "type" "multiple")]
2606 )
2607
2608 (define_insn_and_split "*ite_ne_zeroextractsi"
2609 [(set (match_operand:SI 0 "s_register_operand" "=r")
2610 (if_then_else:SI (ne (zero_extract:SI
2611 (match_operand:SI 1 "s_register_operand" "r")
2612 (match_operand:SI 2 "const_int_operand" "n")
2613 (match_operand:SI 3 "const_int_operand" "n"))
2614 (const_int 0))
2615 (match_operand:SI 4 "arm_not_operand" "rIK")
2616 (const_int 0)))
2617 (clobber (reg:CC CC_REGNUM))]
2618 "TARGET_ARM
2619 && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2620 && INTVAL (operands[2]) > 0
2621 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2622 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)
2623 && !reg_overlap_mentioned_p (operands[0], operands[4])"
2624 "#"
2625 "TARGET_ARM
2626 && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2627 && INTVAL (operands[2]) > 0
2628 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2629 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)
2630 && !reg_overlap_mentioned_p (operands[0], operands[4])"
2631 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2632 (compare:CC_NOOV (and:SI (match_dup 1) (match_dup 2))
2633 (const_int 0)))
2634 (set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))])
2635 (set (match_dup 0)
2636 (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2637 (match_dup 0) (match_dup 4)))]
2638 "
2639 operands[2] = GEN_INT (((1 << INTVAL (operands[2])) - 1)
2640 << INTVAL (operands[3]));
2641 "
2642 [(set_attr "conds" "clob")
2643 (set_attr "length" "8")
2644 (set_attr "type" "multiple")]
2645 )
2646
2647 (define_insn_and_split "*ite_ne_zeroextractsi_shifted"
2648 [(set (match_operand:SI 0 "s_register_operand" "=r")
2649 (if_then_else:SI (ne (zero_extract:SI
2650 (match_operand:SI 1 "s_register_operand" "r")
2651 (match_operand:SI 2 "const_int_operand" "n")
2652 (const_int 0))
2653 (const_int 0))
2654 (match_operand:SI 3 "arm_not_operand" "rIK")
2655 (const_int 0)))
2656 (clobber (reg:CC CC_REGNUM))]
2657 "TARGET_ARM && !reg_overlap_mentioned_p (operands[0], operands[3])"
2658 "#"
2659 "TARGET_ARM && !reg_overlap_mentioned_p (operands[0], operands[3])"
2660 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2661 (compare:CC_NOOV (ashift:SI (match_dup 1) (match_dup 2))
2662 (const_int 0)))
2663 (set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))])
2664 (set (match_dup 0)
2665 (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2666 (match_dup 0) (match_dup 3)))]
2667 "
2668 operands[2] = GEN_INT (32 - INTVAL (operands[2]));
2669 "
2670 [(set_attr "conds" "clob")
2671 (set_attr "length" "8")
2672 (set_attr "type" "multiple")]
2673 )
2674
2675 ;; ??? Use Thumb-2 has bitfield insert/extract instructions.
2676 (define_split
2677 [(set (match_operand:SI 0 "s_register_operand" "")
2678 (match_operator:SI 1 "shiftable_operator"
2679 [(zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
2680 (match_operand:SI 3 "const_int_operand" "")
2681 (match_operand:SI 4 "const_int_operand" ""))
2682 (match_operand:SI 5 "s_register_operand" "")]))
2683 (clobber (match_operand:SI 6 "s_register_operand" ""))]
2684 "TARGET_ARM"
2685 [(set (match_dup 6) (ashift:SI (match_dup 2) (match_dup 3)))
2686 (set (match_dup 0)
2687 (match_op_dup 1
2688 [(lshiftrt:SI (match_dup 6) (match_dup 4))
2689 (match_dup 5)]))]
2690 "{
2691 HOST_WIDE_INT temp = INTVAL (operands[3]);
2692
2693 operands[3] = GEN_INT (32 - temp - INTVAL (operands[4]));
2694 operands[4] = GEN_INT (32 - temp);
2695 }"
2696 )
2697
2698 (define_split
2699 [(set (match_operand:SI 0 "s_register_operand" "")
2700 (match_operator:SI 1 "shiftable_operator"
2701 [(sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
2702 (match_operand:SI 3 "const_int_operand" "")
2703 (match_operand:SI 4 "const_int_operand" ""))
2704 (match_operand:SI 5 "s_register_operand" "")]))
2705 (clobber (match_operand:SI 6 "s_register_operand" ""))]
2706 "TARGET_ARM"
2707 [(set (match_dup 6) (ashift:SI (match_dup 2) (match_dup 3)))
2708 (set (match_dup 0)
2709 (match_op_dup 1
2710 [(ashiftrt:SI (match_dup 6) (match_dup 4))
2711 (match_dup 5)]))]
2712 "{
2713 HOST_WIDE_INT temp = INTVAL (operands[3]);
2714
2715 operands[3] = GEN_INT (32 - temp - INTVAL (operands[4]));
2716 operands[4] = GEN_INT (32 - temp);
2717 }"
2718 )
2719
2720 ;;; ??? This pattern is bogus. If operand3 has bits outside the range
2721 ;;; represented by the bitfield, then this will produce incorrect results.
2722 ;;; Somewhere, the value needs to be truncated. On targets like the m68k,
2723 ;;; which have a real bit-field insert instruction, the truncation happens
2724 ;;; in the bit-field insert instruction itself. Since arm does not have a
2725 ;;; bit-field insert instruction, we would have to emit code here to truncate
2726 ;;; the value before we insert. This loses some of the advantage of having
2727 ;;; this insv pattern, so this pattern needs to be reevalutated.
2728
2729 (define_expand "insv"
2730 [(set (zero_extract (match_operand 0 "nonimmediate_operand" "")
2731 (match_operand 1 "general_operand" "")
2732 (match_operand 2 "general_operand" ""))
2733 (match_operand 3 "reg_or_int_operand" ""))]
2734 "TARGET_ARM || arm_arch_thumb2"
2735 "
2736 {
2737 int start_bit = INTVAL (operands[2]);
2738 int width = INTVAL (operands[1]);
2739 HOST_WIDE_INT mask = (HOST_WIDE_INT_1 << width) - 1;
2740 rtx target, subtarget;
2741
2742 if (arm_arch_thumb2)
2743 {
2744 if (unaligned_access && MEM_P (operands[0])
2745 && s_register_operand (operands[3], GET_MODE (operands[3]))
2746 && (width == 16 || width == 32) && (start_bit % BITS_PER_UNIT) == 0)
2747 {
2748 rtx base_addr;
2749
2750 if (BYTES_BIG_ENDIAN)
2751 start_bit = GET_MODE_BITSIZE (GET_MODE (operands[3])) - width
2752 - start_bit;
2753
2754 if (width == 32)
2755 {
2756 base_addr = adjust_address (operands[0], SImode,
2757 start_bit / BITS_PER_UNIT);
2758 emit_insn (gen_unaligned_storesi (base_addr, operands[3]));
2759 }
2760 else
2761 {
2762 rtx tmp = gen_reg_rtx (HImode);
2763
2764 base_addr = adjust_address (operands[0], HImode,
2765 start_bit / BITS_PER_UNIT);
2766 emit_move_insn (tmp, gen_lowpart (HImode, operands[3]));
2767 emit_insn (gen_unaligned_storehi (base_addr, tmp));
2768 }
2769 DONE;
2770 }
2771 else if (s_register_operand (operands[0], GET_MODE (operands[0])))
2772 {
2773 bool use_bfi = TRUE;
2774
2775 if (CONST_INT_P (operands[3]))
2776 {
2777 HOST_WIDE_INT val = INTVAL (operands[3]) & mask;
2778
2779 if (val == 0)
2780 {
2781 emit_insn (gen_insv_zero (operands[0], operands[1],
2782 operands[2]));
2783 DONE;
2784 }
2785
2786 /* See if the set can be done with a single orr instruction. */
2787 if (val == mask && const_ok_for_arm (val << start_bit))
2788 use_bfi = FALSE;
2789 }
2790
2791 if (use_bfi)
2792 {
2793 if (!REG_P (operands[3]))
2794 operands[3] = force_reg (SImode, operands[3]);
2795
2796 emit_insn (gen_insv_t2 (operands[0], operands[1], operands[2],
2797 operands[3]));
2798 DONE;
2799 }
2800 }
2801 else
2802 FAIL;
2803 }
2804
2805 if (!s_register_operand (operands[0], GET_MODE (operands[0])))
2806 FAIL;
2807
2808 target = copy_rtx (operands[0]);
2809 /* Avoid using a subreg as a subtarget, and avoid writing a paradoxical
2810 subreg as the final target. */
2811 if (GET_CODE (target) == SUBREG)
2812 {
2813 subtarget = gen_reg_rtx (SImode);
2814 if (GET_MODE_SIZE (GET_MODE (SUBREG_REG (target)))
2815 < GET_MODE_SIZE (SImode))
2816 target = SUBREG_REG (target);
2817 }
2818 else
2819 subtarget = target;
2820
2821 if (CONST_INT_P (operands[3]))
2822 {
2823 /* Since we are inserting a known constant, we may be able to
2824 reduce the number of bits that we have to clear so that
2825 the mask becomes simple. */
2826 /* ??? This code does not check to see if the new mask is actually
2827 simpler. It may not be. */
2828 rtx op1 = gen_reg_rtx (SImode);
2829 /* ??? Truncate operand3 to fit in the bitfield. See comment before
2830 start of this pattern. */
2831 HOST_WIDE_INT op3_value = mask & INTVAL (operands[3]);
2832 HOST_WIDE_INT mask2 = ((mask & ~op3_value) << start_bit);
2833
2834 emit_insn (gen_andsi3 (op1, operands[0],
2835 gen_int_mode (~mask2, SImode)));
2836 emit_insn (gen_iorsi3 (subtarget, op1,
2837 gen_int_mode (op3_value << start_bit, SImode)));
2838 }
2839 else if (start_bit == 0
2840 && !(const_ok_for_arm (mask)
2841 || const_ok_for_arm (~mask)))
2842 {
2843 /* A Trick, since we are setting the bottom bits in the word,
2844 we can shift operand[3] up, operand[0] down, OR them together
2845 and rotate the result back again. This takes 3 insns, and
2846 the third might be mergeable into another op. */
2847 /* The shift up copes with the possibility that operand[3] is
2848 wider than the bitfield. */
2849 rtx op0 = gen_reg_rtx (SImode);
2850 rtx op1 = gen_reg_rtx (SImode);
2851
2852 emit_insn (gen_ashlsi3 (op0, operands[3], GEN_INT (32 - width)));
2853 emit_insn (gen_lshrsi3 (op1, operands[0], operands[1]));
2854 emit_insn (gen_iorsi3 (op1, op1, op0));
2855 emit_insn (gen_rotlsi3 (subtarget, op1, operands[1]));
2856 }
2857 else if ((width + start_bit == 32)
2858 && !(const_ok_for_arm (mask)
2859 || const_ok_for_arm (~mask)))
2860 {
2861 /* Similar trick, but slightly less efficient. */
2862
2863 rtx op0 = gen_reg_rtx (SImode);
2864 rtx op1 = gen_reg_rtx (SImode);
2865
2866 emit_insn (gen_ashlsi3 (op0, operands[3], GEN_INT (32 - width)));
2867 emit_insn (gen_ashlsi3 (op1, operands[0], operands[1]));
2868 emit_insn (gen_lshrsi3 (op1, op1, operands[1]));
2869 emit_insn (gen_iorsi3 (subtarget, op1, op0));
2870 }
2871 else
2872 {
2873 rtx op0 = gen_int_mode (mask, SImode);
2874 rtx op1 = gen_reg_rtx (SImode);
2875 rtx op2 = gen_reg_rtx (SImode);
2876
2877 if (!(const_ok_for_arm (mask) || const_ok_for_arm (~mask)))
2878 {
2879 rtx tmp = gen_reg_rtx (SImode);
2880
2881 emit_insn (gen_movsi (tmp, op0));
2882 op0 = tmp;
2883 }
2884
2885 /* Mask out any bits in operand[3] that are not needed. */
2886 emit_insn (gen_andsi3 (op1, operands[3], op0));
2887
2888 if (CONST_INT_P (op0)
2889 && (const_ok_for_arm (mask << start_bit)
2890 || const_ok_for_arm (~(mask << start_bit))))
2891 {
2892 op0 = gen_int_mode (~(mask << start_bit), SImode);
2893 emit_insn (gen_andsi3 (op2, operands[0], op0));
2894 }
2895 else
2896 {
2897 if (CONST_INT_P (op0))
2898 {
2899 rtx tmp = gen_reg_rtx (SImode);
2900
2901 emit_insn (gen_movsi (tmp, op0));
2902 op0 = tmp;
2903 }
2904
2905 if (start_bit != 0)
2906 emit_insn (gen_ashlsi3 (op0, op0, operands[2]));
2907
2908 emit_insn (gen_andsi_notsi_si (op2, operands[0], op0));
2909 }
2910
2911 if (start_bit != 0)
2912 emit_insn (gen_ashlsi3 (op1, op1, operands[2]));
2913
2914 emit_insn (gen_iorsi3 (subtarget, op1, op2));
2915 }
2916
2917 if (subtarget != target)
2918 {
2919 /* If TARGET is still a SUBREG, then it must be wider than a word,
2920 so we must be careful only to set the subword we were asked to. */
2921 if (GET_CODE (target) == SUBREG)
2922 emit_move_insn (target, subtarget);
2923 else
2924 emit_move_insn (target, gen_lowpart (GET_MODE (target), subtarget));
2925 }
2926
2927 DONE;
2928 }"
2929 )
2930
2931 (define_insn "insv_zero"
2932 [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r")
2933 (match_operand:SI 1 "const_int_M_operand" "M")
2934 (match_operand:SI 2 "const_int_M_operand" "M"))
2935 (const_int 0))]
2936 "arm_arch_thumb2"
2937 "bfc%?\t%0, %2, %1"
2938 [(set_attr "length" "4")
2939 (set_attr "predicable" "yes")
2940 (set_attr "type" "bfm")]
2941 )
2942
2943 (define_insn "insv_t2"
2944 [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r")
2945 (match_operand:SI 1 "const_int_M_operand" "M")
2946 (match_operand:SI 2 "const_int_M_operand" "M"))
2947 (match_operand:SI 3 "s_register_operand" "r"))]
2948 "arm_arch_thumb2"
2949 "bfi%?\t%0, %3, %2, %1"
2950 [(set_attr "length" "4")
2951 (set_attr "predicable" "yes")
2952 (set_attr "type" "bfm")]
2953 )
2954
2955 ; constants for op 2 will never be given to these patterns.
2956 (define_insn_and_split "*anddi_notdi_di"
2957 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2958 (and:DI (not:DI (match_operand:DI 1 "s_register_operand" "0,r"))
2959 (match_operand:DI 2 "s_register_operand" "r,0")))]
2960 "TARGET_32BIT"
2961 "#"
2962 "TARGET_32BIT && reload_completed
2963 && ! (TARGET_NEON && IS_VFP_REGNUM (REGNO (operands[0])))
2964 && ! IS_IWMMXT_REGNUM (REGNO (operands[0]))"
2965 [(set (match_dup 0) (and:SI (not:SI (match_dup 1)) (match_dup 2)))
2966 (set (match_dup 3) (and:SI (not:SI (match_dup 4)) (match_dup 5)))]
2967 "
2968 {
2969 operands[3] = gen_highpart (SImode, operands[0]);
2970 operands[0] = gen_lowpart (SImode, operands[0]);
2971 operands[4] = gen_highpart (SImode, operands[1]);
2972 operands[1] = gen_lowpart (SImode, operands[1]);
2973 operands[5] = gen_highpart (SImode, operands[2]);
2974 operands[2] = gen_lowpart (SImode, operands[2]);
2975 }"
2976 [(set_attr "length" "8")
2977 (set_attr "predicable" "yes")
2978 (set_attr "type" "multiple")]
2979 )
2980
2981 (define_insn_and_split "*anddi_notzesidi_di"
2982 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2983 (and:DI (not:DI (zero_extend:DI
2984 (match_operand:SI 2 "s_register_operand" "r,r")))
2985 (match_operand:DI 1 "s_register_operand" "0,?r")))]
2986 "TARGET_32BIT"
2987 "@
2988 bic%?\\t%Q0, %Q1, %2
2989 #"
2990 ; (not (zero_extend ...)) allows us to just copy the high word from
2991 ; operand1 to operand0.
2992 "TARGET_32BIT
2993 && reload_completed
2994 && operands[0] != operands[1]"
2995 [(set (match_dup 0) (and:SI (not:SI (match_dup 2)) (match_dup 1)))
2996 (set (match_dup 3) (match_dup 4))]
2997 "
2998 {
2999 operands[3] = gen_highpart (SImode, operands[0]);
3000 operands[0] = gen_lowpart (SImode, operands[0]);
3001 operands[4] = gen_highpart (SImode, operands[1]);
3002 operands[1] = gen_lowpart (SImode, operands[1]);
3003 }"
3004 [(set_attr "length" "4,8")
3005 (set_attr "predicable" "yes")
3006 (set_attr "type" "multiple")]
3007 )
3008
3009 (define_insn_and_split "*anddi_notdi_zesidi"
3010 [(set (match_operand:DI 0 "s_register_operand" "=r")
3011 (and:DI (not:DI (match_operand:DI 2 "s_register_operand" "r"))
3012 (zero_extend:DI
3013 (match_operand:SI 1 "s_register_operand" "r"))))]
3014 "TARGET_32BIT"
3015 "#"
3016 "TARGET_32BIT && reload_completed"
3017 [(set (match_dup 0) (and:SI (not:SI (match_dup 2)) (match_dup 1)))
3018 (set (match_dup 3) (const_int 0))]
3019 "
3020 {
3021 operands[3] = gen_highpart (SImode, operands[0]);
3022 operands[0] = gen_lowpart (SImode, operands[0]);
3023 operands[2] = gen_lowpart (SImode, operands[2]);
3024 }"
3025 [(set_attr "length" "8")
3026 (set_attr "predicable" "yes")
3027 (set_attr "type" "multiple")]
3028 )
3029
3030 (define_insn_and_split "*anddi_notsesidi_di"
3031 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
3032 (and:DI (not:DI (sign_extend:DI
3033 (match_operand:SI 2 "s_register_operand" "r,r")))
3034 (match_operand:DI 1 "s_register_operand" "0,r")))]
3035 "TARGET_32BIT"
3036 "#"
3037 "TARGET_32BIT && reload_completed"
3038 [(set (match_dup 0) (and:SI (not:SI (match_dup 2)) (match_dup 1)))
3039 (set (match_dup 3) (and:SI (not:SI
3040 (ashiftrt:SI (match_dup 2) (const_int 31)))
3041 (match_dup 4)))]
3042 "
3043 {
3044 operands[3] = gen_highpart (SImode, operands[0]);
3045 operands[0] = gen_lowpart (SImode, operands[0]);
3046 operands[4] = gen_highpart (SImode, operands[1]);
3047 operands[1] = gen_lowpart (SImode, operands[1]);
3048 }"
3049 [(set_attr "length" "8")
3050 (set_attr "predicable" "yes")
3051 (set_attr "type" "multiple")]
3052 )
3053
3054 (define_insn "andsi_notsi_si"
3055 [(set (match_operand:SI 0 "s_register_operand" "=r")
3056 (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
3057 (match_operand:SI 1 "s_register_operand" "r")))]
3058 "TARGET_32BIT"
3059 "bic%?\\t%0, %1, %2"
3060 [(set_attr "predicable" "yes")
3061 (set_attr "type" "logic_reg")]
3062 )
3063
3064 (define_insn "andsi_not_shiftsi_si"
3065 [(set (match_operand:SI 0 "s_register_operand" "=r")
3066 (and:SI (not:SI (match_operator:SI 4 "shift_operator"
3067 [(match_operand:SI 2 "s_register_operand" "r")
3068 (match_operand:SI 3 "arm_rhs_operand" "rM")]))
3069 (match_operand:SI 1 "s_register_operand" "r")))]
3070 "TARGET_ARM"
3071 "bic%?\\t%0, %1, %2%S4"
3072 [(set_attr "predicable" "yes")
3073 (set_attr "shift" "2")
3074 (set (attr "type") (if_then_else (match_operand 3 "const_int_operand" "")
3075 (const_string "logic_shift_imm")
3076 (const_string "logic_shift_reg")))]
3077 )
3078
3079 ;; Shifted bics pattern used to set up CC status register and not reusing
3080 ;; bics output. Pattern restricts Thumb2 shift operand as bics for Thumb2
3081 ;; does not support shift by register.
3082 (define_insn "andsi_not_shiftsi_si_scc_no_reuse"
3083 [(set (reg:CC_NOOV CC_REGNUM)
3084 (compare:CC_NOOV
3085 (and:SI (not:SI (match_operator:SI 0 "shift_operator"
3086 [(match_operand:SI 1 "s_register_operand" "r")
3087 (match_operand:SI 2 "arm_rhs_operand" "rM")]))
3088 (match_operand:SI 3 "s_register_operand" "r"))
3089 (const_int 0)))
3090 (clobber (match_scratch:SI 4 "=r"))]
3091 "TARGET_ARM || (TARGET_THUMB2 && CONST_INT_P (operands[2]))"
3092 "bics%?\\t%4, %3, %1%S0"
3093 [(set_attr "predicable" "yes")
3094 (set_attr "conds" "set")
3095 (set_attr "shift" "1")
3096 (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
3097 (const_string "logic_shift_imm")
3098 (const_string "logic_shift_reg")))]
3099 )
3100
3101 ;; Same as andsi_not_shiftsi_si_scc_no_reuse, but the bics result is also
3102 ;; getting reused later.
3103 (define_insn "andsi_not_shiftsi_si_scc"
3104 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
3105 (compare:CC_NOOV
3106 (and:SI (not:SI (match_operator:SI 0 "shift_operator"
3107 [(match_operand:SI 1 "s_register_operand" "r")
3108 (match_operand:SI 2 "arm_rhs_operand" "rM")]))
3109 (match_operand:SI 3 "s_register_operand" "r"))
3110 (const_int 0)))
3111 (set (match_operand:SI 4 "s_register_operand" "=r")
3112 (and:SI (not:SI (match_op_dup 0
3113 [(match_dup 1)
3114 (match_dup 2)]))
3115 (match_dup 3)))])]
3116 "TARGET_ARM || (TARGET_THUMB2 && CONST_INT_P (operands[2]))"
3117 "bics%?\\t%4, %3, %1%S0"
3118 [(set_attr "predicable" "yes")
3119 (set_attr "conds" "set")
3120 (set_attr "shift" "1")
3121 (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
3122 (const_string "logic_shift_imm")
3123 (const_string "logic_shift_reg")))]
3124 )
3125
3126 (define_insn "*andsi_notsi_si_compare0"
3127 [(set (reg:CC_NOOV CC_REGNUM)
3128 (compare:CC_NOOV
3129 (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
3130 (match_operand:SI 1 "s_register_operand" "r"))
3131 (const_int 0)))
3132 (set (match_operand:SI 0 "s_register_operand" "=r")
3133 (and:SI (not:SI (match_dup 2)) (match_dup 1)))]
3134 "TARGET_32BIT"
3135 "bics\\t%0, %1, %2"
3136 [(set_attr "conds" "set")
3137 (set_attr "type" "logics_shift_reg")]
3138 )
3139
3140 (define_insn "*andsi_notsi_si_compare0_scratch"
3141 [(set (reg:CC_NOOV CC_REGNUM)
3142 (compare:CC_NOOV
3143 (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
3144 (match_operand:SI 1 "s_register_operand" "r"))
3145 (const_int 0)))
3146 (clobber (match_scratch:SI 0 "=r"))]
3147 "TARGET_32BIT"
3148 "bics\\t%0, %1, %2"
3149 [(set_attr "conds" "set")
3150 (set_attr "type" "logics_shift_reg")]
3151 )
3152
3153 (define_expand "iordi3"
3154 [(set (match_operand:DI 0 "s_register_operand" "")
3155 (ior:DI (match_operand:DI 1 "s_register_operand" "")
3156 (match_operand:DI 2 "neon_logic_op2" "")))]
3157 "TARGET_32BIT"
3158 "
3159 if (!TARGET_NEON && !TARGET_IWMMXT)
3160 {
3161 rtx low = simplify_gen_binary (IOR, SImode,
3162 gen_lowpart (SImode, operands[1]),
3163 gen_lowpart (SImode, operands[2]));
3164 rtx high = simplify_gen_binary (IOR, SImode,
3165 gen_highpart (SImode, operands[1]),
3166 gen_highpart_mode (SImode, DImode,
3167 operands[2]));
3168
3169 emit_insn (gen_rtx_SET (gen_lowpart (SImode, operands[0]), low));
3170 emit_insn (gen_rtx_SET (gen_highpart (SImode, operands[0]), high));
3171
3172 DONE;
3173 }
3174 /* Otherwise expand pattern as above. */
3175 "
3176 )
3177
3178 (define_insn_and_split "*iordi3_insn"
3179 [(set (match_operand:DI 0 "s_register_operand" "=w,w ,&r,&r,&r,&r,?w,?w")
3180 (ior:DI (match_operand:DI 1 "s_register_operand" "%w,0 ,0 ,r ,0 ,r ,w ,0")
3181 (match_operand:DI 2 "arm_iordi_operand_neon" "w ,Dl,r ,r ,Df,Df,w ,Dl")))]
3182 "TARGET_32BIT && !TARGET_IWMMXT"
3183 {
3184 switch (which_alternative)
3185 {
3186 case 0: /* fall through */
3187 case 6: return "vorr\t%P0, %P1, %P2";
3188 case 1: /* fall through */
3189 case 7: return neon_output_logic_immediate ("vorr", &operands[2],
3190 DImode, 0, VALID_NEON_QREG_MODE (DImode));
3191 case 2:
3192 case 3:
3193 case 4:
3194 case 5:
3195 return "#";
3196 default: gcc_unreachable ();
3197 }
3198 }
3199 "TARGET_32BIT && !TARGET_IWMMXT && reload_completed
3200 && !(IS_VFP_REGNUM (REGNO (operands[0])))"
3201 [(set (match_dup 3) (match_dup 4))
3202 (set (match_dup 5) (match_dup 6))]
3203 "
3204 {
3205 operands[3] = gen_lowpart (SImode, operands[0]);
3206 operands[5] = gen_highpart (SImode, operands[0]);
3207
3208 operands[4] = simplify_gen_binary (IOR, SImode,
3209 gen_lowpart (SImode, operands[1]),
3210 gen_lowpart (SImode, operands[2]));
3211 operands[6] = simplify_gen_binary (IOR, SImode,
3212 gen_highpart (SImode, operands[1]),
3213 gen_highpart_mode (SImode, DImode, operands[2]));
3214
3215 }"
3216 [(set_attr "type" "neon_logic,neon_logic,multiple,multiple,multiple,\
3217 multiple,neon_logic,neon_logic")
3218 (set_attr "length" "*,*,8,8,8,8,*,*")
3219 (set_attr "arch" "neon_for_64bits,neon_for_64bits,*,*,*,*,avoid_neon_for_64bits,avoid_neon_for_64bits")]
3220 )
3221
3222 (define_insn "*iordi_zesidi_di"
3223 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
3224 (ior:DI (zero_extend:DI
3225 (match_operand:SI 2 "s_register_operand" "r,r"))
3226 (match_operand:DI 1 "s_register_operand" "0,?r")))]
3227 "TARGET_32BIT"
3228 "@
3229 orr%?\\t%Q0, %Q1, %2
3230 #"
3231 [(set_attr "length" "4,8")
3232 (set_attr "predicable" "yes")
3233 (set_attr "type" "logic_reg,multiple")]
3234 )
3235
3236 (define_insn "*iordi_sesidi_di"
3237 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
3238 (ior:DI (sign_extend:DI
3239 (match_operand:SI 2 "s_register_operand" "r,r"))
3240 (match_operand:DI 1 "s_register_operand" "0,r")))]
3241 "TARGET_32BIT"
3242 "#"
3243 [(set_attr "length" "8")
3244 (set_attr "predicable" "yes")
3245 (set_attr "type" "multiple")]
3246 )
3247
3248 (define_expand "iorsi3"
3249 [(set (match_operand:SI 0 "s_register_operand" "")
3250 (ior:SI (match_operand:SI 1 "s_register_operand" "")
3251 (match_operand:SI 2 "reg_or_int_operand" "")))]
3252 "TARGET_EITHER"
3253 "
3254 if (CONST_INT_P (operands[2]))
3255 {
3256 if (TARGET_32BIT)
3257 {
3258 if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[2]), IOR))
3259 operands[2] = force_reg (SImode, operands[2]);
3260 else
3261 {
3262 arm_split_constant (IOR, SImode, NULL_RTX,
3263 INTVAL (operands[2]), operands[0],
3264 operands[1],
3265 optimize && can_create_pseudo_p ());
3266 DONE;
3267 }
3268 }
3269 else /* TARGET_THUMB1 */
3270 {
3271 rtx tmp = force_reg (SImode, operands[2]);
3272 if (rtx_equal_p (operands[0], operands[1]))
3273 operands[2] = tmp;
3274 else
3275 {
3276 operands[2] = operands[1];
3277 operands[1] = tmp;
3278 }
3279 }
3280 }
3281 "
3282 )
3283
3284 (define_insn_and_split "*iorsi3_insn"
3285 [(set (match_operand:SI 0 "s_register_operand" "=r,l,r,r,r")
3286 (ior:SI (match_operand:SI 1 "s_register_operand" "%r,0,r,r,r")
3287 (match_operand:SI 2 "reg_or_int_operand" "I,l,K,r,?n")))]
3288 "TARGET_32BIT"
3289 "@
3290 orr%?\\t%0, %1, %2
3291 orr%?\\t%0, %1, %2
3292 orn%?\\t%0, %1, #%B2
3293 orr%?\\t%0, %1, %2
3294 #"
3295 "TARGET_32BIT
3296 && CONST_INT_P (operands[2])
3297 && !(const_ok_for_arm (INTVAL (operands[2]))
3298 || (TARGET_THUMB2 && const_ok_for_arm (~INTVAL (operands[2]))))"
3299 [(clobber (const_int 0))]
3300 {
3301 arm_split_constant (IOR, SImode, curr_insn,
3302 INTVAL (operands[2]), operands[0], operands[1], 0);
3303 DONE;
3304 }
3305 [(set_attr "length" "4,4,4,4,16")
3306 (set_attr "arch" "32,t2,t2,32,32")
3307 (set_attr "predicable" "yes")
3308 (set_attr "predicable_short_it" "no,yes,no,no,no")
3309 (set_attr "type" "logic_imm,logic_reg,logic_imm,logic_reg,logic_reg")]
3310 )
3311
3312 (define_peephole2
3313 [(match_scratch:SI 3 "r")
3314 (set (match_operand:SI 0 "arm_general_register_operand" "")
3315 (ior:SI (match_operand:SI 1 "arm_general_register_operand" "")
3316 (match_operand:SI 2 "const_int_operand" "")))]
3317 "TARGET_ARM
3318 && !const_ok_for_arm (INTVAL (operands[2]))
3319 && const_ok_for_arm (~INTVAL (operands[2]))"
3320 [(set (match_dup 3) (match_dup 2))
3321 (set (match_dup 0) (ior:SI (match_dup 1) (match_dup 3)))]
3322 ""
3323 )
3324
3325 (define_insn "*iorsi3_compare0"
3326 [(set (reg:CC_NOOV CC_REGNUM)
3327 (compare:CC_NOOV (ior:SI (match_operand:SI 1 "s_register_operand" "%r,r")
3328 (match_operand:SI 2 "arm_rhs_operand" "I,r"))
3329 (const_int 0)))
3330 (set (match_operand:SI 0 "s_register_operand" "=r,r")
3331 (ior:SI (match_dup 1) (match_dup 2)))]
3332 "TARGET_32BIT"
3333 "orrs%?\\t%0, %1, %2"
3334 [(set_attr "conds" "set")
3335 (set_attr "type" "logics_imm,logics_reg")]
3336 )
3337
3338 (define_insn "*iorsi3_compare0_scratch"
3339 [(set (reg:CC_NOOV CC_REGNUM)
3340 (compare:CC_NOOV (ior:SI (match_operand:SI 1 "s_register_operand" "%r,r")
3341 (match_operand:SI 2 "arm_rhs_operand" "I,r"))
3342 (const_int 0)))
3343 (clobber (match_scratch:SI 0 "=r,r"))]
3344 "TARGET_32BIT"
3345 "orrs%?\\t%0, %1, %2"
3346 [(set_attr "conds" "set")
3347 (set_attr "type" "logics_imm,logics_reg")]
3348 )
3349
3350 (define_expand "xordi3"
3351 [(set (match_operand:DI 0 "s_register_operand" "")
3352 (xor:DI (match_operand:DI 1 "s_register_operand" "")
3353 (match_operand:DI 2 "arm_xordi_operand" "")))]
3354 "TARGET_32BIT"
3355 {
3356 /* The iWMMXt pattern for xordi3 accepts only register operands but we want
3357 to reuse this expander for all TARGET_32BIT targets so just force the
3358 constants into a register. Unlike for the anddi3 and iordi3 there are
3359 no NEON instructions that take an immediate. */
3360 if (TARGET_IWMMXT && !REG_P (operands[2]))
3361 operands[2] = force_reg (DImode, operands[2]);
3362 if (!TARGET_NEON && !TARGET_IWMMXT)
3363 {
3364 rtx low = simplify_gen_binary (XOR, SImode,
3365 gen_lowpart (SImode, operands[1]),
3366 gen_lowpart (SImode, operands[2]));
3367 rtx high = simplify_gen_binary (XOR, SImode,
3368 gen_highpart (SImode, operands[1]),
3369 gen_highpart_mode (SImode, DImode,
3370 operands[2]));
3371
3372 emit_insn (gen_rtx_SET (gen_lowpart (SImode, operands[0]), low));
3373 emit_insn (gen_rtx_SET (gen_highpart (SImode, operands[0]), high));
3374
3375 DONE;
3376 }
3377 /* Otherwise expand pattern as above. */
3378 }
3379 )
3380
3381 (define_insn_and_split "*xordi3_insn"
3382 [(set (match_operand:DI 0 "s_register_operand" "=w,&r,&r,&r,&r,?w")
3383 (xor:DI (match_operand:DI 1 "s_register_operand" "%w ,0,r ,0 ,r ,w")
3384 (match_operand:DI 2 "arm_xordi_operand" "w ,r ,r ,Dg,Dg,w")))]
3385 "TARGET_32BIT && !TARGET_IWMMXT"
3386 {
3387 switch (which_alternative)
3388 {
3389 case 1:
3390 case 2:
3391 case 3:
3392 case 4: /* fall through */
3393 return "#";
3394 case 0: /* fall through */
3395 case 5: return "veor\t%P0, %P1, %P2";
3396 default: gcc_unreachable ();
3397 }
3398 }
3399 "TARGET_32BIT && !TARGET_IWMMXT && reload_completed
3400 && !(IS_VFP_REGNUM (REGNO (operands[0])))"
3401 [(set (match_dup 3) (match_dup 4))
3402 (set (match_dup 5) (match_dup 6))]
3403 "
3404 {
3405 operands[3] = gen_lowpart (SImode, operands[0]);
3406 operands[5] = gen_highpart (SImode, operands[0]);
3407
3408 operands[4] = simplify_gen_binary (XOR, SImode,
3409 gen_lowpart (SImode, operands[1]),
3410 gen_lowpart (SImode, operands[2]));
3411 operands[6] = simplify_gen_binary (XOR, SImode,
3412 gen_highpart (SImode, operands[1]),
3413 gen_highpart_mode (SImode, DImode, operands[2]));
3414
3415 }"
3416 [(set_attr "length" "*,8,8,8,8,*")
3417 (set_attr "type" "neon_logic,multiple,multiple,multiple,multiple,neon_logic")
3418 (set_attr "arch" "neon_for_64bits,*,*,*,*,avoid_neon_for_64bits")]
3419 )
3420
3421 (define_insn "*xordi_zesidi_di"
3422 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
3423 (xor:DI (zero_extend:DI
3424 (match_operand:SI 2 "s_register_operand" "r,r"))
3425 (match_operand:DI 1 "s_register_operand" "0,?r")))]
3426 "TARGET_32BIT"
3427 "@
3428 eor%?\\t%Q0, %Q1, %2
3429 #"
3430 [(set_attr "length" "4,8")
3431 (set_attr "predicable" "yes")
3432 (set_attr "type" "logic_reg")]
3433 )
3434
3435 (define_insn "*xordi_sesidi_di"
3436 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
3437 (xor:DI (sign_extend:DI
3438 (match_operand:SI 2 "s_register_operand" "r,r"))
3439 (match_operand:DI 1 "s_register_operand" "0,r")))]
3440 "TARGET_32BIT"
3441 "#"
3442 [(set_attr "length" "8")
3443 (set_attr "predicable" "yes")
3444 (set_attr "type" "multiple")]
3445 )
3446
3447 (define_expand "xorsi3"
3448 [(set (match_operand:SI 0 "s_register_operand" "")
3449 (xor:SI (match_operand:SI 1 "s_register_operand" "")
3450 (match_operand:SI 2 "reg_or_int_operand" "")))]
3451 "TARGET_EITHER"
3452 "if (CONST_INT_P (operands[2]))
3453 {
3454 if (TARGET_32BIT)
3455 {
3456 if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[2]), XOR))
3457 operands[2] = force_reg (SImode, operands[2]);
3458 else
3459 {
3460 arm_split_constant (XOR, SImode, NULL_RTX,
3461 INTVAL (operands[2]), operands[0],
3462 operands[1],
3463 optimize && can_create_pseudo_p ());
3464 DONE;
3465 }
3466 }
3467 else /* TARGET_THUMB1 */
3468 {
3469 rtx tmp = force_reg (SImode, operands[2]);
3470 if (rtx_equal_p (operands[0], operands[1]))
3471 operands[2] = tmp;
3472 else
3473 {
3474 operands[2] = operands[1];
3475 operands[1] = tmp;
3476 }
3477 }
3478 }"
3479 )
3480
3481 (define_insn_and_split "*arm_xorsi3"
3482 [(set (match_operand:SI 0 "s_register_operand" "=r,l,r,r")
3483 (xor:SI (match_operand:SI 1 "s_register_operand" "%r,0,r,r")
3484 (match_operand:SI 2 "reg_or_int_operand" "I,l,r,?n")))]
3485 "TARGET_32BIT"
3486 "@
3487 eor%?\\t%0, %1, %2
3488 eor%?\\t%0, %1, %2
3489 eor%?\\t%0, %1, %2
3490 #"
3491 "TARGET_32BIT
3492 && CONST_INT_P (operands[2])
3493 && !const_ok_for_arm (INTVAL (operands[2]))"
3494 [(clobber (const_int 0))]
3495 {
3496 arm_split_constant (XOR, SImode, curr_insn,
3497 INTVAL (operands[2]), operands[0], operands[1], 0);
3498 DONE;
3499 }
3500 [(set_attr "length" "4,4,4,16")
3501 (set_attr "predicable" "yes")
3502 (set_attr "predicable_short_it" "no,yes,no,no")
3503 (set_attr "type" "logic_imm,logic_reg,logic_reg,multiple")]
3504 )
3505
3506 (define_insn "*xorsi3_compare0"
3507 [(set (reg:CC_NOOV CC_REGNUM)
3508 (compare:CC_NOOV (xor:SI (match_operand:SI 1 "s_register_operand" "r,r")
3509 (match_operand:SI 2 "arm_rhs_operand" "I,r"))
3510 (const_int 0)))
3511 (set (match_operand:SI 0 "s_register_operand" "=r,r")
3512 (xor:SI (match_dup 1) (match_dup 2)))]
3513 "TARGET_32BIT"
3514 "eors%?\\t%0, %1, %2"
3515 [(set_attr "conds" "set")
3516 (set_attr "type" "logics_imm,logics_reg")]
3517 )
3518
3519 (define_insn "*xorsi3_compare0_scratch"
3520 [(set (reg:CC_NOOV CC_REGNUM)
3521 (compare:CC_NOOV (xor:SI (match_operand:SI 0 "s_register_operand" "r,r")
3522 (match_operand:SI 1 "arm_rhs_operand" "I,r"))
3523 (const_int 0)))]
3524 "TARGET_32BIT"
3525 "teq%?\\t%0, %1"
3526 [(set_attr "conds" "set")
3527 (set_attr "type" "logics_imm,logics_reg")]
3528 )
3529
3530 ; By splitting (IOR (AND (NOT A) (NOT B)) C) as D = AND (IOR A B) (NOT C),
3531 ; (NOT D) we can sometimes merge the final NOT into one of the following
3532 ; insns.
3533
3534 (define_split
3535 [(set (match_operand:SI 0 "s_register_operand" "")
3536 (ior:SI (and:SI (not:SI (match_operand:SI 1 "s_register_operand" ""))
3537 (not:SI (match_operand:SI 2 "arm_rhs_operand" "")))
3538 (match_operand:SI 3 "arm_rhs_operand" "")))
3539 (clobber (match_operand:SI 4 "s_register_operand" ""))]
3540 "TARGET_32BIT"
3541 [(set (match_dup 4) (and:SI (ior:SI (match_dup 1) (match_dup 2))
3542 (not:SI (match_dup 3))))
3543 (set (match_dup 0) (not:SI (match_dup 4)))]
3544 ""
3545 )
3546
3547 (define_insn_and_split "*andsi_iorsi3_notsi"
3548 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r")
3549 (and:SI (ior:SI (match_operand:SI 1 "s_register_operand" "%0,r,r")
3550 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI"))
3551 (not:SI (match_operand:SI 3 "arm_rhs_operand" "rI,rI,rI"))))]
3552 "TARGET_32BIT"
3553 "#" ; "orr%?\\t%0, %1, %2\;bic%?\\t%0, %0, %3"
3554 "&& reload_completed"
3555 [(set (match_dup 0) (ior:SI (match_dup 1) (match_dup 2)))
3556 (set (match_dup 0) (and:SI (match_dup 4) (match_dup 5)))]
3557 {
3558 /* If operands[3] is a constant make sure to fold the NOT into it
3559 to avoid creating a NOT of a CONST_INT. */
3560 rtx not_rtx = simplify_gen_unary (NOT, SImode, operands[3], SImode);
3561 if (CONST_INT_P (not_rtx))
3562 {
3563 operands[4] = operands[0];
3564 operands[5] = not_rtx;
3565 }
3566 else
3567 {
3568 operands[5] = operands[0];
3569 operands[4] = not_rtx;
3570 }
3571 }
3572 [(set_attr "length" "8")
3573 (set_attr "ce_count" "2")
3574 (set_attr "predicable" "yes")
3575 (set_attr "type" "multiple")]
3576 )
3577
3578 ; ??? Are these four splitters still beneficial when the Thumb-2 bitfield
3579 ; insns are available?
3580 (define_split
3581 [(set (match_operand:SI 0 "s_register_operand" "")
3582 (match_operator:SI 1 "logical_binary_operator"
3583 [(zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
3584 (match_operand:SI 3 "const_int_operand" "")
3585 (match_operand:SI 4 "const_int_operand" ""))
3586 (match_operator:SI 9 "logical_binary_operator"
3587 [(lshiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3588 (match_operand:SI 6 "const_int_operand" ""))
3589 (match_operand:SI 7 "s_register_operand" "")])]))
3590 (clobber (match_operand:SI 8 "s_register_operand" ""))]
3591 "TARGET_32BIT
3592 && GET_CODE (operands[1]) == GET_CODE (operands[9])
3593 && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3594 [(set (match_dup 8)
3595 (match_op_dup 1
3596 [(ashift:SI (match_dup 2) (match_dup 4))
3597 (match_dup 5)]))
3598 (set (match_dup 0)
3599 (match_op_dup 1
3600 [(lshiftrt:SI (match_dup 8) (match_dup 6))
3601 (match_dup 7)]))]
3602 "
3603 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3604 ")
3605
3606 (define_split
3607 [(set (match_operand:SI 0 "s_register_operand" "")
3608 (match_operator:SI 1 "logical_binary_operator"
3609 [(match_operator:SI 9 "logical_binary_operator"
3610 [(lshiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3611 (match_operand:SI 6 "const_int_operand" ""))
3612 (match_operand:SI 7 "s_register_operand" "")])
3613 (zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
3614 (match_operand:SI 3 "const_int_operand" "")
3615 (match_operand:SI 4 "const_int_operand" ""))]))
3616 (clobber (match_operand:SI 8 "s_register_operand" ""))]
3617 "TARGET_32BIT
3618 && GET_CODE (operands[1]) == GET_CODE (operands[9])
3619 && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3620 [(set (match_dup 8)
3621 (match_op_dup 1
3622 [(ashift:SI (match_dup 2) (match_dup 4))
3623 (match_dup 5)]))
3624 (set (match_dup 0)
3625 (match_op_dup 1
3626 [(lshiftrt:SI (match_dup 8) (match_dup 6))
3627 (match_dup 7)]))]
3628 "
3629 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3630 ")
3631
3632 (define_split
3633 [(set (match_operand:SI 0 "s_register_operand" "")
3634 (match_operator:SI 1 "logical_binary_operator"
3635 [(sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
3636 (match_operand:SI 3 "const_int_operand" "")
3637 (match_operand:SI 4 "const_int_operand" ""))
3638 (match_operator:SI 9 "logical_binary_operator"
3639 [(ashiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3640 (match_operand:SI 6 "const_int_operand" ""))
3641 (match_operand:SI 7 "s_register_operand" "")])]))
3642 (clobber (match_operand:SI 8 "s_register_operand" ""))]
3643 "TARGET_32BIT
3644 && GET_CODE (operands[1]) == GET_CODE (operands[9])
3645 && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3646 [(set (match_dup 8)
3647 (match_op_dup 1
3648 [(ashift:SI (match_dup 2) (match_dup 4))
3649 (match_dup 5)]))
3650 (set (match_dup 0)
3651 (match_op_dup 1
3652 [(ashiftrt:SI (match_dup 8) (match_dup 6))
3653 (match_dup 7)]))]
3654 "
3655 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3656 ")
3657
3658 (define_split
3659 [(set (match_operand:SI 0 "s_register_operand" "")
3660 (match_operator:SI 1 "logical_binary_operator"
3661 [(match_operator:SI 9 "logical_binary_operator"
3662 [(ashiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3663 (match_operand:SI 6 "const_int_operand" ""))
3664 (match_operand:SI 7 "s_register_operand" "")])
3665 (sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
3666 (match_operand:SI 3 "const_int_operand" "")
3667 (match_operand:SI 4 "const_int_operand" ""))]))
3668 (clobber (match_operand:SI 8 "s_register_operand" ""))]
3669 "TARGET_32BIT
3670 && GET_CODE (operands[1]) == GET_CODE (operands[9])
3671 && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3672 [(set (match_dup 8)
3673 (match_op_dup 1
3674 [(ashift:SI (match_dup 2) (match_dup 4))
3675 (match_dup 5)]))
3676 (set (match_dup 0)
3677 (match_op_dup 1
3678 [(ashiftrt:SI (match_dup 8) (match_dup 6))
3679 (match_dup 7)]))]
3680 "
3681 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3682 ")
3683 \f
3684
3685 ;; Minimum and maximum insns
3686
3687 (define_expand "smaxsi3"
3688 [(parallel [
3689 (set (match_operand:SI 0 "s_register_operand" "")
3690 (smax:SI (match_operand:SI 1 "s_register_operand" "")
3691 (match_operand:SI 2 "arm_rhs_operand" "")))
3692 (clobber (reg:CC CC_REGNUM))])]
3693 "TARGET_32BIT"
3694 "
3695 if (operands[2] == const0_rtx || operands[2] == constm1_rtx)
3696 {
3697 /* No need for a clobber of the condition code register here. */
3698 emit_insn (gen_rtx_SET (operands[0],
3699 gen_rtx_SMAX (SImode, operands[1],
3700 operands[2])));
3701 DONE;
3702 }
3703 ")
3704
3705 (define_insn "*smax_0"
3706 [(set (match_operand:SI 0 "s_register_operand" "=r")
3707 (smax:SI (match_operand:SI 1 "s_register_operand" "r")
3708 (const_int 0)))]
3709 "TARGET_32BIT"
3710 "bic%?\\t%0, %1, %1, asr #31"
3711 [(set_attr "predicable" "yes")
3712 (set_attr "type" "logic_shift_reg")]
3713 )
3714
3715 (define_insn "*smax_m1"
3716 [(set (match_operand:SI 0 "s_register_operand" "=r")
3717 (smax:SI (match_operand:SI 1 "s_register_operand" "r")
3718 (const_int -1)))]
3719 "TARGET_32BIT"
3720 "orr%?\\t%0, %1, %1, asr #31"
3721 [(set_attr "predicable" "yes")
3722 (set_attr "type" "logic_shift_reg")]
3723 )
3724
3725 (define_insn_and_split "*arm_smax_insn"
3726 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3727 (smax:SI (match_operand:SI 1 "s_register_operand" "%0,?r")
3728 (match_operand:SI 2 "arm_rhs_operand" "rI,rI")))
3729 (clobber (reg:CC CC_REGNUM))]
3730 "TARGET_ARM"
3731 "#"
3732 ; cmp\\t%1, %2\;movlt\\t%0, %2
3733 ; cmp\\t%1, %2\;movge\\t%0, %1\;movlt\\t%0, %2"
3734 "TARGET_ARM"
3735 [(set (reg:CC CC_REGNUM)
3736 (compare:CC (match_dup 1) (match_dup 2)))
3737 (set (match_dup 0)
3738 (if_then_else:SI (ge:SI (reg:CC CC_REGNUM) (const_int 0))
3739 (match_dup 1)
3740 (match_dup 2)))]
3741 ""
3742 [(set_attr "conds" "clob")
3743 (set_attr "length" "8,12")
3744 (set_attr "type" "multiple")]
3745 )
3746
3747 (define_expand "sminsi3"
3748 [(parallel [
3749 (set (match_operand:SI 0 "s_register_operand" "")
3750 (smin:SI (match_operand:SI 1 "s_register_operand" "")
3751 (match_operand:SI 2 "arm_rhs_operand" "")))
3752 (clobber (reg:CC CC_REGNUM))])]
3753 "TARGET_32BIT"
3754 "
3755 if (operands[2] == const0_rtx)
3756 {
3757 /* No need for a clobber of the condition code register here. */
3758 emit_insn (gen_rtx_SET (operands[0],
3759 gen_rtx_SMIN (SImode, operands[1],
3760 operands[2])));
3761 DONE;
3762 }
3763 ")
3764
3765 (define_insn "*smin_0"
3766 [(set (match_operand:SI 0 "s_register_operand" "=r")
3767 (smin:SI (match_operand:SI 1 "s_register_operand" "r")
3768 (const_int 0)))]
3769 "TARGET_32BIT"
3770 "and%?\\t%0, %1, %1, asr #31"
3771 [(set_attr "predicable" "yes")
3772 (set_attr "type" "logic_shift_reg")]
3773 )
3774
3775 (define_insn_and_split "*arm_smin_insn"
3776 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3777 (smin:SI (match_operand:SI 1 "s_register_operand" "%0,?r")
3778 (match_operand:SI 2 "arm_rhs_operand" "rI,rI")))
3779 (clobber (reg:CC CC_REGNUM))]
3780 "TARGET_ARM"
3781 "#"
3782 ; cmp\\t%1, %2\;movge\\t%0, %2
3783 ; cmp\\t%1, %2\;movlt\\t%0, %1\;movge\\t%0, %2"
3784 "TARGET_ARM"
3785 [(set (reg:CC CC_REGNUM)
3786 (compare:CC (match_dup 1) (match_dup 2)))
3787 (set (match_dup 0)
3788 (if_then_else:SI (lt:SI (reg:CC CC_REGNUM) (const_int 0))
3789 (match_dup 1)
3790 (match_dup 2)))]
3791 ""
3792 [(set_attr "conds" "clob")
3793 (set_attr "length" "8,12")
3794 (set_attr "type" "multiple,multiple")]
3795 )
3796
3797 (define_expand "umaxsi3"
3798 [(parallel [
3799 (set (match_operand:SI 0 "s_register_operand" "")
3800 (umax:SI (match_operand:SI 1 "s_register_operand" "")
3801 (match_operand:SI 2 "arm_rhs_operand" "")))
3802 (clobber (reg:CC CC_REGNUM))])]
3803 "TARGET_32BIT"
3804 ""
3805 )
3806
3807 (define_insn_and_split "*arm_umaxsi3"
3808 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
3809 (umax:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
3810 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
3811 (clobber (reg:CC CC_REGNUM))]
3812 "TARGET_ARM"
3813 "#"
3814 ; cmp\\t%1, %2\;movcc\\t%0, %2
3815 ; cmp\\t%1, %2\;movcs\\t%0, %1
3816 ; cmp\\t%1, %2\;movcs\\t%0, %1\;movcc\\t%0, %2"
3817 "TARGET_ARM"
3818 [(set (reg:CC CC_REGNUM)
3819 (compare:CC (match_dup 1) (match_dup 2)))
3820 (set (match_dup 0)
3821 (if_then_else:SI (geu:SI (reg:CC CC_REGNUM) (const_int 0))
3822 (match_dup 1)
3823 (match_dup 2)))]
3824 ""
3825 [(set_attr "conds" "clob")
3826 (set_attr "length" "8,8,12")
3827 (set_attr "type" "store_4")]
3828 )
3829
3830 (define_expand "uminsi3"
3831 [(parallel [
3832 (set (match_operand:SI 0 "s_register_operand" "")
3833 (umin:SI (match_operand:SI 1 "s_register_operand" "")
3834 (match_operand:SI 2 "arm_rhs_operand" "")))
3835 (clobber (reg:CC CC_REGNUM))])]
3836 "TARGET_32BIT"
3837 ""
3838 )
3839
3840 (define_insn_and_split "*arm_uminsi3"
3841 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
3842 (umin:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
3843 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
3844 (clobber (reg:CC CC_REGNUM))]
3845 "TARGET_ARM"
3846 "#"
3847 ; cmp\\t%1, %2\;movcs\\t%0, %2
3848 ; cmp\\t%1, %2\;movcc\\t%0, %1
3849 ; cmp\\t%1, %2\;movcc\\t%0, %1\;movcs\\t%0, %2"
3850 "TARGET_ARM"
3851 [(set (reg:CC CC_REGNUM)
3852 (compare:CC (match_dup 1) (match_dup 2)))
3853 (set (match_dup 0)
3854 (if_then_else:SI (ltu:SI (reg:CC CC_REGNUM) (const_int 0))
3855 (match_dup 1)
3856 (match_dup 2)))]
3857 ""
3858 [(set_attr "conds" "clob")
3859 (set_attr "length" "8,8,12")
3860 (set_attr "type" "store_4")]
3861 )
3862
3863 (define_insn "*store_minmaxsi"
3864 [(set (match_operand:SI 0 "memory_operand" "=m")
3865 (match_operator:SI 3 "minmax_operator"
3866 [(match_operand:SI 1 "s_register_operand" "r")
3867 (match_operand:SI 2 "s_register_operand" "r")]))
3868 (clobber (reg:CC CC_REGNUM))]
3869 "TARGET_32BIT && optimize_function_for_size_p (cfun) && !arm_restrict_it"
3870 "*
3871 operands[3] = gen_rtx_fmt_ee (minmax_code (operands[3]), SImode,
3872 operands[1], operands[2]);
3873 output_asm_insn (\"cmp\\t%1, %2\", operands);
3874 if (TARGET_THUMB2)
3875 output_asm_insn (\"ite\t%d3\", operands);
3876 output_asm_insn (\"str%d3\\t%1, %0\", operands);
3877 output_asm_insn (\"str%D3\\t%2, %0\", operands);
3878 return \"\";
3879 "
3880 [(set_attr "conds" "clob")
3881 (set (attr "length")
3882 (if_then_else (eq_attr "is_thumb" "yes")
3883 (const_int 14)
3884 (const_int 12)))
3885 (set_attr "type" "store_4")]
3886 )
3887
3888 ; Reject the frame pointer in operand[1], since reloading this after
3889 ; it has been eliminated can cause carnage.
3890 (define_insn "*minmax_arithsi"
3891 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3892 (match_operator:SI 4 "shiftable_operator"
3893 [(match_operator:SI 5 "minmax_operator"
3894 [(match_operand:SI 2 "s_register_operand" "r,r")
3895 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
3896 (match_operand:SI 1 "s_register_operand" "0,?r")]))
3897 (clobber (reg:CC CC_REGNUM))]
3898 "TARGET_32BIT && !arm_eliminable_register (operands[1]) && !arm_restrict_it"
3899 "*
3900 {
3901 enum rtx_code code = GET_CODE (operands[4]);
3902 bool need_else;
3903
3904 if (which_alternative != 0 || operands[3] != const0_rtx
3905 || (code != PLUS && code != IOR && code != XOR))
3906 need_else = true;
3907 else
3908 need_else = false;
3909
3910 operands[5] = gen_rtx_fmt_ee (minmax_code (operands[5]), SImode,
3911 operands[2], operands[3]);
3912 output_asm_insn (\"cmp\\t%2, %3\", operands);
3913 if (TARGET_THUMB2)
3914 {
3915 if (need_else)
3916 output_asm_insn (\"ite\\t%d5\", operands);
3917 else
3918 output_asm_insn (\"it\\t%d5\", operands);
3919 }
3920 output_asm_insn (\"%i4%d5\\t%0, %1, %2\", operands);
3921 if (need_else)
3922 output_asm_insn (\"%i4%D5\\t%0, %1, %3\", operands);
3923 return \"\";
3924 }"
3925 [(set_attr "conds" "clob")
3926 (set (attr "length")
3927 (if_then_else (eq_attr "is_thumb" "yes")
3928 (const_int 14)
3929 (const_int 12)))
3930 (set_attr "type" "multiple")]
3931 )
3932
3933 ; Reject the frame pointer in operand[1], since reloading this after
3934 ; it has been eliminated can cause carnage.
3935 (define_insn_and_split "*minmax_arithsi_non_canon"
3936 [(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts")
3937 (minus:SI
3938 (match_operand:SI 1 "s_register_operand" "0,?Ts")
3939 (match_operator:SI 4 "minmax_operator"
3940 [(match_operand:SI 2 "s_register_operand" "Ts,Ts")
3941 (match_operand:SI 3 "arm_rhs_operand" "TsI,TsI")])))
3942 (clobber (reg:CC CC_REGNUM))]
3943 "TARGET_32BIT && !arm_eliminable_register (operands[1])
3944 && !(arm_restrict_it && CONST_INT_P (operands[3]))"
3945 "#"
3946 "TARGET_32BIT && !arm_eliminable_register (operands[1]) && reload_completed"
3947 [(set (reg:CC CC_REGNUM)
3948 (compare:CC (match_dup 2) (match_dup 3)))
3949
3950 (cond_exec (match_op_dup 4 [(reg:CC CC_REGNUM) (const_int 0)])
3951 (set (match_dup 0)
3952 (minus:SI (match_dup 1)
3953 (match_dup 2))))
3954 (cond_exec (match_op_dup 5 [(reg:CC CC_REGNUM) (const_int 0)])
3955 (set (match_dup 0)
3956 (match_dup 6)))]
3957 {
3958 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
3959 operands[2], operands[3]);
3960 enum rtx_code rc = minmax_code (operands[4]);
3961 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode,
3962 operands[2], operands[3]);
3963
3964 if (mode == CCFPmode || mode == CCFPEmode)
3965 rc = reverse_condition_maybe_unordered (rc);
3966 else
3967 rc = reverse_condition (rc);
3968 operands[5] = gen_rtx_fmt_ee (rc, SImode, operands[2], operands[3]);
3969 if (CONST_INT_P (operands[3]))
3970 operands[6] = plus_constant (SImode, operands[1], -INTVAL (operands[3]));
3971 else
3972 operands[6] = gen_rtx_MINUS (SImode, operands[1], operands[3]);
3973 }
3974 [(set_attr "conds" "clob")
3975 (set (attr "length")
3976 (if_then_else (eq_attr "is_thumb" "yes")
3977 (const_int 14)
3978 (const_int 12)))
3979 (set_attr "type" "multiple")]
3980 )
3981
3982 (define_code_iterator SAT [smin smax])
3983 (define_code_iterator SATrev [smin smax])
3984 (define_code_attr SATlo [(smin "1") (smax "2")])
3985 (define_code_attr SAThi [(smin "2") (smax "1")])
3986
3987 (define_insn "*satsi_<SAT:code>"
3988 [(set (match_operand:SI 0 "s_register_operand" "=r")
3989 (SAT:SI (SATrev:SI (match_operand:SI 3 "s_register_operand" "r")
3990 (match_operand:SI 1 "const_int_operand" "i"))
3991 (match_operand:SI 2 "const_int_operand" "i")))]
3992 "TARGET_32BIT && arm_arch6 && <SAT:CODE> != <SATrev:CODE>
3993 && arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>], NULL, NULL)"
3994 {
3995 int mask;
3996 bool signed_sat;
3997 if (!arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>],
3998 &mask, &signed_sat))
3999 gcc_unreachable ();
4000
4001 operands[1] = GEN_INT (mask);
4002 if (signed_sat)
4003 return "ssat%?\t%0, %1, %3";
4004 else
4005 return "usat%?\t%0, %1, %3";
4006 }
4007 [(set_attr "predicable" "yes")
4008 (set_attr "type" "alus_imm")]
4009 )
4010
4011 (define_insn "*satsi_<SAT:code>_shift"
4012 [(set (match_operand:SI 0 "s_register_operand" "=r")
4013 (SAT:SI (SATrev:SI (match_operator:SI 3 "sat_shift_operator"
4014 [(match_operand:SI 4 "s_register_operand" "r")
4015 (match_operand:SI 5 "const_int_operand" "i")])
4016 (match_operand:SI 1 "const_int_operand" "i"))
4017 (match_operand:SI 2 "const_int_operand" "i")))]
4018 "TARGET_32BIT && arm_arch6 && <SAT:CODE> != <SATrev:CODE>
4019 && arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>], NULL, NULL)"
4020 {
4021 int mask;
4022 bool signed_sat;
4023 if (!arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>],
4024 &mask, &signed_sat))
4025 gcc_unreachable ();
4026
4027 operands[1] = GEN_INT (mask);
4028 if (signed_sat)
4029 return "ssat%?\t%0, %1, %4%S3";
4030 else
4031 return "usat%?\t%0, %1, %4%S3";
4032 }
4033 [(set_attr "predicable" "yes")
4034 (set_attr "shift" "3")
4035 (set_attr "type" "logic_shift_reg")])
4036 \f
4037 ;; Shift and rotation insns
4038
4039 (define_expand "ashldi3"
4040 [(set (match_operand:DI 0 "s_register_operand" "")
4041 (ashift:DI (match_operand:DI 1 "s_register_operand" "")
4042 (match_operand:SI 2 "general_operand" "")))]
4043 "TARGET_32BIT"
4044 "
4045 if (TARGET_NEON)
4046 {
4047 /* Delay the decision whether to use NEON or core-regs until
4048 register allocation. */
4049 emit_insn (gen_ashldi3_neon (operands[0], operands[1], operands[2]));
4050 DONE;
4051 }
4052 else
4053 {
4054 /* Only the NEON case can handle in-memory shift counts. */
4055 if (!reg_or_int_operand (operands[2], SImode))
4056 operands[2] = force_reg (SImode, operands[2]);
4057 }
4058
4059 if (!CONST_INT_P (operands[2]) && TARGET_REALLY_IWMMXT)
4060 ; /* No special preparation statements; expand pattern as above. */
4061 else
4062 {
4063 rtx scratch1, scratch2;
4064
4065 /* Ideally we should use iwmmxt here if we could know that operands[1]
4066 ends up already living in an iwmmxt register. Otherwise it's
4067 cheaper to have the alternate code being generated than moving
4068 values to iwmmxt regs and back. */
4069
4070 /* Expand operation using core-registers.
4071 'FAIL' would achieve the same thing, but this is a bit smarter. */
4072 scratch1 = gen_reg_rtx (SImode);
4073 scratch2 = gen_reg_rtx (SImode);
4074 arm_emit_coreregs_64bit_shift (ASHIFT, operands[0], operands[1],
4075 operands[2], scratch1, scratch2);
4076 DONE;
4077 }
4078 "
4079 )
4080
4081 (define_expand "ashlsi3"
4082 [(set (match_operand:SI 0 "s_register_operand" "")
4083 (ashift:SI (match_operand:SI 1 "s_register_operand" "")
4084 (match_operand:SI 2 "arm_rhs_operand" "")))]
4085 "TARGET_EITHER"
4086 "
4087 if (CONST_INT_P (operands[2])
4088 && (UINTVAL (operands[2])) > 31)
4089 {
4090 emit_insn (gen_movsi (operands[0], const0_rtx));
4091 DONE;
4092 }
4093 "
4094 )
4095
4096 (define_expand "ashrdi3"
4097 [(set (match_operand:DI 0 "s_register_operand" "")
4098 (ashiftrt:DI (match_operand:DI 1 "s_register_operand" "")
4099 (match_operand:SI 2 "reg_or_int_operand" "")))]
4100 "TARGET_32BIT"
4101 "
4102 if (TARGET_NEON)
4103 {
4104 /* Delay the decision whether to use NEON or core-regs until
4105 register allocation. */
4106 emit_insn (gen_ashrdi3_neon (operands[0], operands[1], operands[2]));
4107 DONE;
4108 }
4109
4110 if (!CONST_INT_P (operands[2]) && TARGET_REALLY_IWMMXT)
4111 ; /* No special preparation statements; expand pattern as above. */
4112 else
4113 {
4114 rtx scratch1, scratch2;
4115
4116 /* Ideally we should use iwmmxt here if we could know that operands[1]
4117 ends up already living in an iwmmxt register. Otherwise it's
4118 cheaper to have the alternate code being generated than moving
4119 values to iwmmxt regs and back. */
4120
4121 /* Expand operation using core-registers.
4122 'FAIL' would achieve the same thing, but this is a bit smarter. */
4123 scratch1 = gen_reg_rtx (SImode);
4124 scratch2 = gen_reg_rtx (SImode);
4125 arm_emit_coreregs_64bit_shift (ASHIFTRT, operands[0], operands[1],
4126 operands[2], scratch1, scratch2);
4127 DONE;
4128 }
4129 "
4130 )
4131
4132 (define_expand "ashrsi3"
4133 [(set (match_operand:SI 0 "s_register_operand" "")
4134 (ashiftrt:SI (match_operand:SI 1 "s_register_operand" "")
4135 (match_operand:SI 2 "arm_rhs_operand" "")))]
4136 "TARGET_EITHER"
4137 "
4138 if (CONST_INT_P (operands[2])
4139 && UINTVAL (operands[2]) > 31)
4140 operands[2] = GEN_INT (31);
4141 "
4142 )
4143
4144 (define_expand "lshrdi3"
4145 [(set (match_operand:DI 0 "s_register_operand" "")
4146 (lshiftrt:DI (match_operand:DI 1 "s_register_operand" "")
4147 (match_operand:SI 2 "reg_or_int_operand" "")))]
4148 "TARGET_32BIT"
4149 "
4150 if (TARGET_NEON)
4151 {
4152 /* Delay the decision whether to use NEON or core-regs until
4153 register allocation. */
4154 emit_insn (gen_lshrdi3_neon (operands[0], operands[1], operands[2]));
4155 DONE;
4156 }
4157
4158 if (!CONST_INT_P (operands[2]) && TARGET_REALLY_IWMMXT)
4159 ; /* No special preparation statements; expand pattern as above. */
4160 else
4161 {
4162 rtx scratch1, scratch2;
4163
4164 /* Ideally we should use iwmmxt here if we could know that operands[1]
4165 ends up already living in an iwmmxt register. Otherwise it's
4166 cheaper to have the alternate code being generated than moving
4167 values to iwmmxt regs and back. */
4168
4169 /* Expand operation using core-registers.
4170 'FAIL' would achieve the same thing, but this is a bit smarter. */
4171 scratch1 = gen_reg_rtx (SImode);
4172 scratch2 = gen_reg_rtx (SImode);
4173 arm_emit_coreregs_64bit_shift (LSHIFTRT, operands[0], operands[1],
4174 operands[2], scratch1, scratch2);
4175 DONE;
4176 }
4177 "
4178 )
4179
4180 (define_expand "lshrsi3"
4181 [(set (match_operand:SI 0 "s_register_operand" "")
4182 (lshiftrt:SI (match_operand:SI 1 "s_register_operand" "")
4183 (match_operand:SI 2 "arm_rhs_operand" "")))]
4184 "TARGET_EITHER"
4185 "
4186 if (CONST_INT_P (operands[2])
4187 && (UINTVAL (operands[2])) > 31)
4188 {
4189 emit_insn (gen_movsi (operands[0], const0_rtx));
4190 DONE;
4191 }
4192 "
4193 )
4194
4195 (define_expand "rotlsi3"
4196 [(set (match_operand:SI 0 "s_register_operand" "")
4197 (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
4198 (match_operand:SI 2 "reg_or_int_operand" "")))]
4199 "TARGET_32BIT"
4200 "
4201 if (CONST_INT_P (operands[2]))
4202 operands[2] = GEN_INT ((32 - INTVAL (operands[2])) % 32);
4203 else
4204 {
4205 rtx reg = gen_reg_rtx (SImode);
4206 emit_insn (gen_subsi3 (reg, GEN_INT (32), operands[2]));
4207 operands[2] = reg;
4208 }
4209 "
4210 )
4211
4212 (define_expand "rotrsi3"
4213 [(set (match_operand:SI 0 "s_register_operand" "")
4214 (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
4215 (match_operand:SI 2 "arm_rhs_operand" "")))]
4216 "TARGET_EITHER"
4217 "
4218 if (TARGET_32BIT)
4219 {
4220 if (CONST_INT_P (operands[2])
4221 && UINTVAL (operands[2]) > 31)
4222 operands[2] = GEN_INT (INTVAL (operands[2]) % 32);
4223 }
4224 else /* TARGET_THUMB1 */
4225 {
4226 if (CONST_INT_P (operands [2]))
4227 operands [2] = force_reg (SImode, operands[2]);
4228 }
4229 "
4230 )
4231
4232 (define_insn "*arm_shiftsi3"
4233 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r,r")
4234 (match_operator:SI 3 "shift_operator"
4235 [(match_operand:SI 1 "s_register_operand" "0,l,r,r")
4236 (match_operand:SI 2 "reg_or_int_operand" "l,M,M,r")]))]
4237 "TARGET_32BIT"
4238 "* return arm_output_shift(operands, 0);"
4239 [(set_attr "predicable" "yes")
4240 (set_attr "arch" "t2,t2,*,*")
4241 (set_attr "predicable_short_it" "yes,yes,no,no")
4242 (set_attr "length" "4")
4243 (set_attr "shift" "1")
4244 (set_attr "type" "alu_shift_reg,alu_shift_imm,alu_shift_imm,alu_shift_reg")]
4245 )
4246
4247 (define_insn "*shiftsi3_compare0"
4248 [(set (reg:CC_NOOV CC_REGNUM)
4249 (compare:CC_NOOV (match_operator:SI 3 "shift_operator"
4250 [(match_operand:SI 1 "s_register_operand" "r,r")
4251 (match_operand:SI 2 "arm_rhs_operand" "M,r")])
4252 (const_int 0)))
4253 (set (match_operand:SI 0 "s_register_operand" "=r,r")
4254 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))]
4255 "TARGET_32BIT"
4256 "* return arm_output_shift(operands, 1);"
4257 [(set_attr "conds" "set")
4258 (set_attr "shift" "1")
4259 (set_attr "type" "alus_shift_imm,alus_shift_reg")]
4260 )
4261
4262 (define_insn "*shiftsi3_compare0_scratch"
4263 [(set (reg:CC_NOOV CC_REGNUM)
4264 (compare:CC_NOOV (match_operator:SI 3 "shift_operator"
4265 [(match_operand:SI 1 "s_register_operand" "r,r")
4266 (match_operand:SI 2 "arm_rhs_operand" "M,r")])
4267 (const_int 0)))
4268 (clobber (match_scratch:SI 0 "=r,r"))]
4269 "TARGET_32BIT"
4270 "* return arm_output_shift(operands, 1);"
4271 [(set_attr "conds" "set")
4272 (set_attr "shift" "1")
4273 (set_attr "type" "shift_imm,shift_reg")]
4274 )
4275
4276 (define_insn "*not_shiftsi"
4277 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4278 (not:SI (match_operator:SI 3 "shift_operator"
4279 [(match_operand:SI 1 "s_register_operand" "r,r")
4280 (match_operand:SI 2 "shift_amount_operand" "M,rM")])))]
4281 "TARGET_32BIT"
4282 "mvn%?\\t%0, %1%S3"
4283 [(set_attr "predicable" "yes")
4284 (set_attr "shift" "1")
4285 (set_attr "arch" "32,a")
4286 (set_attr "type" "mvn_shift,mvn_shift_reg")])
4287
4288 (define_insn "*not_shiftsi_compare0"
4289 [(set (reg:CC_NOOV CC_REGNUM)
4290 (compare:CC_NOOV
4291 (not:SI (match_operator:SI 3 "shift_operator"
4292 [(match_operand:SI 1 "s_register_operand" "r,r")
4293 (match_operand:SI 2 "shift_amount_operand" "M,rM")]))
4294 (const_int 0)))
4295 (set (match_operand:SI 0 "s_register_operand" "=r,r")
4296 (not:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])))]
4297 "TARGET_32BIT"
4298 "mvns%?\\t%0, %1%S3"
4299 [(set_attr "conds" "set")
4300 (set_attr "shift" "1")
4301 (set_attr "arch" "32,a")
4302 (set_attr "type" "mvn_shift,mvn_shift_reg")])
4303
4304 (define_insn "*not_shiftsi_compare0_scratch"
4305 [(set (reg:CC_NOOV CC_REGNUM)
4306 (compare:CC_NOOV
4307 (not:SI (match_operator:SI 3 "shift_operator"
4308 [(match_operand:SI 1 "s_register_operand" "r,r")
4309 (match_operand:SI 2 "shift_amount_operand" "M,rM")]))
4310 (const_int 0)))
4311 (clobber (match_scratch:SI 0 "=r,r"))]
4312 "TARGET_32BIT"
4313 "mvns%?\\t%0, %1%S3"
4314 [(set_attr "conds" "set")
4315 (set_attr "shift" "1")
4316 (set_attr "arch" "32,a")
4317 (set_attr "type" "mvn_shift,mvn_shift_reg")])
4318
4319 ;; We don't really have extzv, but defining this using shifts helps
4320 ;; to reduce register pressure later on.
4321
4322 (define_expand "extzv"
4323 [(set (match_operand 0 "s_register_operand" "")
4324 (zero_extract (match_operand 1 "nonimmediate_operand" "")
4325 (match_operand 2 "const_int_operand" "")
4326 (match_operand 3 "const_int_operand" "")))]
4327 "TARGET_THUMB1 || arm_arch_thumb2"
4328 "
4329 {
4330 HOST_WIDE_INT lshift = 32 - INTVAL (operands[2]) - INTVAL (operands[3]);
4331 HOST_WIDE_INT rshift = 32 - INTVAL (operands[2]);
4332
4333 if (arm_arch_thumb2)
4334 {
4335 HOST_WIDE_INT width = INTVAL (operands[2]);
4336 HOST_WIDE_INT bitpos = INTVAL (operands[3]);
4337
4338 if (unaligned_access && MEM_P (operands[1])
4339 && (width == 16 || width == 32) && (bitpos % BITS_PER_UNIT) == 0)
4340 {
4341 rtx base_addr;
4342
4343 if (BYTES_BIG_ENDIAN)
4344 bitpos = GET_MODE_BITSIZE (GET_MODE (operands[0])) - width
4345 - bitpos;
4346
4347 if (width == 32)
4348 {
4349 base_addr = adjust_address (operands[1], SImode,
4350 bitpos / BITS_PER_UNIT);
4351 emit_insn (gen_unaligned_loadsi (operands[0], base_addr));
4352 }
4353 else
4354 {
4355 rtx dest = operands[0];
4356 rtx tmp = gen_reg_rtx (SImode);
4357
4358 /* We may get a paradoxical subreg here. Strip it off. */
4359 if (GET_CODE (dest) == SUBREG
4360 && GET_MODE (dest) == SImode
4361 && GET_MODE (SUBREG_REG (dest)) == HImode)
4362 dest = SUBREG_REG (dest);
4363
4364 if (GET_MODE_BITSIZE (GET_MODE (dest)) != width)
4365 FAIL;
4366
4367 base_addr = adjust_address (operands[1], HImode,
4368 bitpos / BITS_PER_UNIT);
4369 emit_insn (gen_unaligned_loadhiu (tmp, base_addr));
4370 emit_move_insn (gen_lowpart (SImode, dest), tmp);
4371 }
4372 DONE;
4373 }
4374 else if (s_register_operand (operands[1], GET_MODE (operands[1])))
4375 {
4376 emit_insn (gen_extzv_t2 (operands[0], operands[1], operands[2],
4377 operands[3]));
4378 DONE;
4379 }
4380 else
4381 FAIL;
4382 }
4383
4384 if (!s_register_operand (operands[1], GET_MODE (operands[1])))
4385 FAIL;
4386
4387 operands[3] = GEN_INT (rshift);
4388
4389 if (lshift == 0)
4390 {
4391 emit_insn (gen_lshrsi3 (operands[0], operands[1], operands[3]));
4392 DONE;
4393 }
4394
4395 emit_insn (gen_extzv_t1 (operands[0], operands[1], GEN_INT (lshift),
4396 operands[3], gen_reg_rtx (SImode)));
4397 DONE;
4398 }"
4399 )
4400
4401 ;; Helper for extzv, for the Thumb-1 register-shifts case.
4402
4403 (define_expand "extzv_t1"
4404 [(set (match_operand:SI 4 "s_register_operand" "")
4405 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
4406 (match_operand:SI 2 "const_int_operand" "")))
4407 (set (match_operand:SI 0 "s_register_operand" "")
4408 (lshiftrt:SI (match_dup 4)
4409 (match_operand:SI 3 "const_int_operand" "")))]
4410 "TARGET_THUMB1"
4411 "")
4412
4413 (define_expand "extv"
4414 [(set (match_operand 0 "s_register_operand" "")
4415 (sign_extract (match_operand 1 "nonimmediate_operand" "")
4416 (match_operand 2 "const_int_operand" "")
4417 (match_operand 3 "const_int_operand" "")))]
4418 "arm_arch_thumb2"
4419 {
4420 HOST_WIDE_INT width = INTVAL (operands[2]);
4421 HOST_WIDE_INT bitpos = INTVAL (operands[3]);
4422
4423 if (unaligned_access && MEM_P (operands[1]) && (width == 16 || width == 32)
4424 && (bitpos % BITS_PER_UNIT) == 0)
4425 {
4426 rtx base_addr;
4427
4428 if (BYTES_BIG_ENDIAN)
4429 bitpos = GET_MODE_BITSIZE (GET_MODE (operands[0])) - width - bitpos;
4430
4431 if (width == 32)
4432 {
4433 base_addr = adjust_address (operands[1], SImode,
4434 bitpos / BITS_PER_UNIT);
4435 emit_insn (gen_unaligned_loadsi (operands[0], base_addr));
4436 }
4437 else
4438 {
4439 rtx dest = operands[0];
4440 rtx tmp = gen_reg_rtx (SImode);
4441
4442 /* We may get a paradoxical subreg here. Strip it off. */
4443 if (GET_CODE (dest) == SUBREG
4444 && GET_MODE (dest) == SImode
4445 && GET_MODE (SUBREG_REG (dest)) == HImode)
4446 dest = SUBREG_REG (dest);
4447
4448 if (GET_MODE_BITSIZE (GET_MODE (dest)) != width)
4449 FAIL;
4450
4451 base_addr = adjust_address (operands[1], HImode,
4452 bitpos / BITS_PER_UNIT);
4453 emit_insn (gen_unaligned_loadhis (tmp, base_addr));
4454 emit_move_insn (gen_lowpart (SImode, dest), tmp);
4455 }
4456
4457 DONE;
4458 }
4459 else if (!s_register_operand (operands[1], GET_MODE (operands[1])))
4460 FAIL;
4461 else if (GET_MODE (operands[0]) == SImode
4462 && GET_MODE (operands[1]) == SImode)
4463 {
4464 emit_insn (gen_extv_regsi (operands[0], operands[1], operands[2],
4465 operands[3]));
4466 DONE;
4467 }
4468
4469 FAIL;
4470 })
4471
4472 ; Helper to expand register forms of extv with the proper modes.
4473
4474 (define_expand "extv_regsi"
4475 [(set (match_operand:SI 0 "s_register_operand" "")
4476 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "")
4477 (match_operand 2 "const_int_operand" "")
4478 (match_operand 3 "const_int_operand" "")))]
4479 ""
4480 {
4481 })
4482
4483 ; ARMv6+ unaligned load/store instructions (used for packed structure accesses).
4484
4485 (define_insn "unaligned_loadsi"
4486 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r")
4487 (unspec:SI [(match_operand:SI 1 "memory_operand" "m,Uw,m")]
4488 UNSPEC_UNALIGNED_LOAD))]
4489 "unaligned_access"
4490 "@
4491 ldr\t%0, %1\t@ unaligned
4492 ldr%?\t%0, %1\t@ unaligned
4493 ldr%?\t%0, %1\t@ unaligned"
4494 [(set_attr "arch" "t1,t2,32")
4495 (set_attr "length" "2,2,4")
4496 (set_attr "predicable" "no,yes,yes")
4497 (set_attr "predicable_short_it" "no,yes,no")
4498 (set_attr "type" "load_4")])
4499
4500 ;; The 16-bit Thumb1 variant of ldrsh requires two registers in the
4501 ;; address (there's no immediate format). That's tricky to support
4502 ;; here and we don't really need this pattern for that case, so only
4503 ;; enable for 32-bit ISAs.
4504 (define_insn "unaligned_loadhis"
4505 [(set (match_operand:SI 0 "s_register_operand" "=r")
4506 (sign_extend:SI
4507 (unspec:HI [(match_operand:HI 1 "memory_operand" "Uh")]
4508 UNSPEC_UNALIGNED_LOAD)))]
4509 "unaligned_access && TARGET_32BIT"
4510 "ldrsh%?\t%0, %1\t@ unaligned"
4511 [(set_attr "predicable" "yes")
4512 (set_attr "type" "load_byte")])
4513
4514 (define_insn "unaligned_loadhiu"
4515 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r")
4516 (zero_extend:SI
4517 (unspec:HI [(match_operand:HI 1 "memory_operand" "m,Uw,m")]
4518 UNSPEC_UNALIGNED_LOAD)))]
4519 "unaligned_access"
4520 "@
4521 ldrh\t%0, %1\t@ unaligned
4522 ldrh%?\t%0, %1\t@ unaligned
4523 ldrh%?\t%0, %1\t@ unaligned"
4524 [(set_attr "arch" "t1,t2,32")
4525 (set_attr "length" "2,2,4")
4526 (set_attr "predicable" "no,yes,yes")
4527 (set_attr "predicable_short_it" "no,yes,no")
4528 (set_attr "type" "load_byte")])
4529
4530 (define_insn "unaligned_storesi"
4531 [(set (match_operand:SI 0 "memory_operand" "=m,Uw,m")
4532 (unspec:SI [(match_operand:SI 1 "s_register_operand" "l,l,r")]
4533 UNSPEC_UNALIGNED_STORE))]
4534 "unaligned_access"
4535 "@
4536 str\t%1, %0\t@ unaligned
4537 str%?\t%1, %0\t@ unaligned
4538 str%?\t%1, %0\t@ unaligned"
4539 [(set_attr "arch" "t1,t2,32")
4540 (set_attr "length" "2,2,4")
4541 (set_attr "predicable" "no,yes,yes")
4542 (set_attr "predicable_short_it" "no,yes,no")
4543 (set_attr "type" "store_4")])
4544
4545 (define_insn "unaligned_storehi"
4546 [(set (match_operand:HI 0 "memory_operand" "=m,Uw,m")
4547 (unspec:HI [(match_operand:HI 1 "s_register_operand" "l,l,r")]
4548 UNSPEC_UNALIGNED_STORE))]
4549 "unaligned_access"
4550 "@
4551 strh\t%1, %0\t@ unaligned
4552 strh%?\t%1, %0\t@ unaligned
4553 strh%?\t%1, %0\t@ unaligned"
4554 [(set_attr "arch" "t1,t2,32")
4555 (set_attr "length" "2,2,4")
4556 (set_attr "predicable" "no,yes,yes")
4557 (set_attr "predicable_short_it" "no,yes,no")
4558 (set_attr "type" "store_4")])
4559
4560
4561 (define_insn "*extv_reg"
4562 [(set (match_operand:SI 0 "s_register_operand" "=r")
4563 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
4564 (match_operand:SI 2 "const_int_operand" "n")
4565 (match_operand:SI 3 "const_int_operand" "n")))]
4566 "arm_arch_thumb2
4567 && IN_RANGE (INTVAL (operands[3]), 0, 31)
4568 && IN_RANGE (INTVAL (operands[2]), 1, 32 - INTVAL (operands[3]))"
4569 "sbfx%?\t%0, %1, %3, %2"
4570 [(set_attr "length" "4")
4571 (set_attr "predicable" "yes")
4572 (set_attr "type" "bfm")]
4573 )
4574
4575 (define_insn "extzv_t2"
4576 [(set (match_operand:SI 0 "s_register_operand" "=r")
4577 (zero_extract:SI (match_operand:SI 1 "s_register_operand" "r")
4578 (match_operand:SI 2 "const_int_operand" "n")
4579 (match_operand:SI 3 "const_int_operand" "n")))]
4580 "arm_arch_thumb2
4581 && IN_RANGE (INTVAL (operands[3]), 0, 31)
4582 && IN_RANGE (INTVAL (operands[2]), 1, 32 - INTVAL (operands[3]))"
4583 "ubfx%?\t%0, %1, %3, %2"
4584 [(set_attr "length" "4")
4585 (set_attr "predicable" "yes")
4586 (set_attr "type" "bfm")]
4587 )
4588
4589
4590 ;; Division instructions
4591 (define_insn "divsi3"
4592 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4593 (div:SI (match_operand:SI 1 "s_register_operand" "r,r")
4594 (match_operand:SI 2 "s_register_operand" "r,r")))]
4595 "TARGET_IDIV"
4596 "@
4597 sdiv%?\t%0, %1, %2
4598 sdiv\t%0, %1, %2"
4599 [(set_attr "arch" "32,v8mb")
4600 (set_attr "predicable" "yes")
4601 (set_attr "type" "sdiv")]
4602 )
4603
4604 (define_insn "udivsi3"
4605 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4606 (udiv:SI (match_operand:SI 1 "s_register_operand" "r,r")
4607 (match_operand:SI 2 "s_register_operand" "r,r")))]
4608 "TARGET_IDIV"
4609 "@
4610 udiv%?\t%0, %1, %2
4611 udiv\t%0, %1, %2"
4612 [(set_attr "arch" "32,v8mb")
4613 (set_attr "predicable" "yes")
4614 (set_attr "type" "udiv")]
4615 )
4616
4617 \f
4618 ;; Unary arithmetic insns
4619
4620 (define_expand "negvsi3"
4621 [(match_operand:SI 0 "register_operand")
4622 (match_operand:SI 1 "register_operand")
4623 (match_operand 2 "")]
4624 "TARGET_32BIT"
4625 {
4626 emit_insn (gen_subsi3_compare (operands[0], const0_rtx, operands[1]));
4627 arm_gen_unlikely_cbranch (NE, CC_Vmode, operands[2]);
4628
4629 DONE;
4630 })
4631
4632 (define_expand "negvdi3"
4633 [(match_operand:DI 0 "register_operand")
4634 (match_operand:DI 1 "register_operand")
4635 (match_operand 2 "")]
4636 "TARGET_ARM"
4637 {
4638 emit_insn (gen_negdi2_compare (operands[0], operands[1]));
4639 arm_gen_unlikely_cbranch (NE, CC_Vmode, operands[2]);
4640
4641 DONE;
4642 })
4643
4644
4645 (define_insn_and_split "negdi2_compare"
4646 [(set (reg:CC CC_REGNUM)
4647 (compare:CC
4648 (const_int 0)
4649 (match_operand:DI 1 "register_operand" "0,r")))
4650 (set (match_operand:DI 0 "register_operand" "=r,&r")
4651 (minus:DI (const_int 0) (match_dup 1)))]
4652 "TARGET_ARM"
4653 "#"
4654 "&& reload_completed"
4655 [(parallel [(set (reg:CC CC_REGNUM)
4656 (compare:CC (const_int 0) (match_dup 1)))
4657 (set (match_dup 0) (minus:SI (const_int 0)
4658 (match_dup 1)))])
4659 (parallel [(set (reg:CC CC_REGNUM)
4660 (compare:CC (const_int 0) (match_dup 3)))
4661 (set (match_dup 2)
4662 (minus:SI
4663 (minus:SI (const_int 0) (match_dup 3))
4664 (ltu:SI (reg:CC_C CC_REGNUM)
4665 (const_int 0))))])]
4666 {
4667 operands[2] = gen_highpart (SImode, operands[0]);
4668 operands[0] = gen_lowpart (SImode, operands[0]);
4669 operands[3] = gen_highpart (SImode, operands[1]);
4670 operands[1] = gen_lowpart (SImode, operands[1]);
4671 }
4672 [(set_attr "conds" "set")
4673 (set_attr "length" "8")
4674 (set_attr "type" "multiple")]
4675 )
4676
4677 (define_expand "negdi2"
4678 [(parallel
4679 [(set (match_operand:DI 0 "s_register_operand" "")
4680 (neg:DI (match_operand:DI 1 "s_register_operand" "")))
4681 (clobber (reg:CC CC_REGNUM))])]
4682 "TARGET_EITHER"
4683 {
4684 if (TARGET_NEON)
4685 {
4686 emit_insn (gen_negdi2_neon (operands[0], operands[1]));
4687 DONE;
4688 }
4689 }
4690 )
4691
4692 ;; The constraints here are to prevent a *partial* overlap (where %Q0 == %R1).
4693 ;; The first alternative allows the common case of a *full* overlap.
4694 (define_insn_and_split "*negdi2_insn"
4695 [(set (match_operand:DI 0 "s_register_operand" "=r,&r")
4696 (neg:DI (match_operand:DI 1 "s_register_operand" "0,r")))
4697 (clobber (reg:CC CC_REGNUM))]
4698 "TARGET_32BIT"
4699 "#" ; rsbs %Q0, %Q1, #0; rsc %R0, %R1, #0 (ARM)
4700 ; negs %Q0, %Q1 ; sbc %R0, %R1, %R1, lsl #1 (Thumb-2)
4701 "&& reload_completed"
4702 [(parallel [(set (reg:CC CC_REGNUM)
4703 (compare:CC (const_int 0) (match_dup 1)))
4704 (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1)))])
4705 (set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3))
4706 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
4707 {
4708 operands[2] = gen_highpart (SImode, operands[0]);
4709 operands[0] = gen_lowpart (SImode, operands[0]);
4710 operands[3] = gen_highpart (SImode, operands[1]);
4711 operands[1] = gen_lowpart (SImode, operands[1]);
4712 }
4713 [(set_attr "conds" "clob")
4714 (set_attr "length" "8")
4715 (set_attr "type" "multiple")]
4716 )
4717
4718 (define_insn "*negsi2_carryin_compare"
4719 [(set (reg:CC CC_REGNUM)
4720 (compare:CC (const_int 0)
4721 (match_operand:SI 1 "s_register_operand" "r")))
4722 (set (match_operand:SI 0 "s_register_operand" "=r")
4723 (minus:SI (minus:SI (const_int 0)
4724 (match_dup 1))
4725 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
4726 "TARGET_ARM"
4727 "rscs\\t%0, %1, #0"
4728 [(set_attr "conds" "set")
4729 (set_attr "type" "alus_imm")]
4730 )
4731
4732 (define_expand "negsi2"
4733 [(set (match_operand:SI 0 "s_register_operand" "")
4734 (neg:SI (match_operand:SI 1 "s_register_operand" "")))]
4735 "TARGET_EITHER"
4736 ""
4737 )
4738
4739 (define_insn "*arm_negsi2"
4740 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4741 (neg:SI (match_operand:SI 1 "s_register_operand" "l,r")))]
4742 "TARGET_32BIT"
4743 "rsb%?\\t%0, %1, #0"
4744 [(set_attr "predicable" "yes")
4745 (set_attr "predicable_short_it" "yes,no")
4746 (set_attr "arch" "t2,*")
4747 (set_attr "length" "4")
4748 (set_attr "type" "alu_sreg")]
4749 )
4750
4751 (define_expand "negsf2"
4752 [(set (match_operand:SF 0 "s_register_operand" "")
4753 (neg:SF (match_operand:SF 1 "s_register_operand" "")))]
4754 "TARGET_32BIT && TARGET_HARD_FLOAT"
4755 ""
4756 )
4757
4758 (define_expand "negdf2"
4759 [(set (match_operand:DF 0 "s_register_operand" "")
4760 (neg:DF (match_operand:DF 1 "s_register_operand" "")))]
4761 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
4762 "")
4763
4764 (define_insn_and_split "*zextendsidi_negsi"
4765 [(set (match_operand:DI 0 "s_register_operand" "=r")
4766 (zero_extend:DI (neg:SI (match_operand:SI 1 "s_register_operand" "r"))))]
4767 "TARGET_32BIT"
4768 "#"
4769 ""
4770 [(set (match_dup 2)
4771 (neg:SI (match_dup 1)))
4772 (set (match_dup 3)
4773 (const_int 0))]
4774 {
4775 operands[2] = gen_lowpart (SImode, operands[0]);
4776 operands[3] = gen_highpart (SImode, operands[0]);
4777 }
4778 [(set_attr "length" "8")
4779 (set_attr "type" "multiple")]
4780 )
4781
4782 ;; Negate an extended 32-bit value.
4783 (define_insn_and_split "*negdi_extendsidi"
4784 [(set (match_operand:DI 0 "s_register_operand" "=l,r")
4785 (neg:DI (sign_extend:DI
4786 (match_operand:SI 1 "s_register_operand" "l,r"))))
4787 (clobber (reg:CC CC_REGNUM))]
4788 "TARGET_32BIT"
4789 "#"
4790 "&& reload_completed"
4791 [(const_int 0)]
4792 {
4793 rtx low = gen_lowpart (SImode, operands[0]);
4794 rtx high = gen_highpart (SImode, operands[0]);
4795
4796 if (reg_overlap_mentioned_p (low, operands[1]))
4797 {
4798 /* Input overlaps the low word of the output. Use:
4799 asr Rhi, Rin, #31
4800 rsbs Rlo, Rin, #0
4801 rsc Rhi, Rhi, #0 (thumb2: sbc Rhi, Rhi, Rhi, lsl #1). */
4802 rtx cc_reg = gen_rtx_REG (CC_Cmode, CC_REGNUM);
4803
4804 emit_insn (gen_rtx_SET (high,
4805 gen_rtx_ASHIFTRT (SImode, operands[1],
4806 GEN_INT (31))));
4807
4808 emit_insn (gen_subsi3_compare (low, const0_rtx, operands[1]));
4809 if (TARGET_ARM)
4810 emit_insn (gen_rtx_SET (high,
4811 gen_rtx_MINUS (SImode,
4812 gen_rtx_MINUS (SImode,
4813 const0_rtx,
4814 high),
4815 gen_rtx_LTU (SImode,
4816 cc_reg,
4817 const0_rtx))));
4818 else
4819 {
4820 rtx two_x = gen_rtx_ASHIFT (SImode, high, GEN_INT (1));
4821 emit_insn (gen_rtx_SET (high,
4822 gen_rtx_MINUS (SImode,
4823 gen_rtx_MINUS (SImode,
4824 high,
4825 two_x),
4826 gen_rtx_LTU (SImode,
4827 cc_reg,
4828 const0_rtx))));
4829 }
4830 }
4831 else
4832 {
4833 /* No overlap, or overlap on high word. Use:
4834 rsb Rlo, Rin, #0
4835 bic Rhi, Rlo, Rin
4836 asr Rhi, Rhi, #31
4837 Flags not needed for this sequence. */
4838 emit_insn (gen_rtx_SET (low, gen_rtx_NEG (SImode, operands[1])));
4839 emit_insn (gen_rtx_SET (high,
4840 gen_rtx_AND (SImode,
4841 gen_rtx_NOT (SImode, operands[1]),
4842 low)));
4843 emit_insn (gen_rtx_SET (high,
4844 gen_rtx_ASHIFTRT (SImode, high,
4845 GEN_INT (31))));
4846 }
4847 DONE;
4848 }
4849 [(set_attr "length" "12")
4850 (set_attr "arch" "t2,*")
4851 (set_attr "type" "multiple")]
4852 )
4853
4854 (define_insn_and_split "*negdi_zero_extendsidi"
4855 [(set (match_operand:DI 0 "s_register_operand" "=r,&r")
4856 (neg:DI (zero_extend:DI (match_operand:SI 1 "s_register_operand" "0,r"))))
4857 (clobber (reg:CC CC_REGNUM))]
4858 "TARGET_32BIT"
4859 "#" ; "rsbs\\t%Q0, %1, #0\;sbc\\t%R0,%R0,%R0"
4860 ;; Don't care what register is input to sbc,
4861 ;; since we just need to propagate the carry.
4862 "&& reload_completed"
4863 [(parallel [(set (reg:CC CC_REGNUM)
4864 (compare:CC (const_int 0) (match_dup 1)))
4865 (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1)))])
4866 (set (match_dup 2) (minus:SI (minus:SI (match_dup 2) (match_dup 2))
4867 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
4868 {
4869 operands[2] = gen_highpart (SImode, operands[0]);
4870 operands[0] = gen_lowpart (SImode, operands[0]);
4871 }
4872 [(set_attr "conds" "clob")
4873 (set_attr "length" "8")
4874 (set_attr "type" "multiple")] ;; length in thumb is 4
4875 )
4876
4877 ;; abssi2 doesn't really clobber the condition codes if a different register
4878 ;; is being set. To keep things simple, assume during rtl manipulations that
4879 ;; it does, but tell the final scan operator the truth. Similarly for
4880 ;; (neg (abs...))
4881
4882 (define_expand "abssi2"
4883 [(parallel
4884 [(set (match_operand:SI 0 "s_register_operand" "")
4885 (abs:SI (match_operand:SI 1 "s_register_operand" "")))
4886 (clobber (match_dup 2))])]
4887 "TARGET_EITHER"
4888 "
4889 if (TARGET_THUMB1)
4890 operands[2] = gen_rtx_SCRATCH (SImode);
4891 else
4892 operands[2] = gen_rtx_REG (CCmode, CC_REGNUM);
4893 ")
4894
4895 (define_insn_and_split "*arm_abssi2"
4896 [(set (match_operand:SI 0 "s_register_operand" "=r,&r")
4897 (abs:SI (match_operand:SI 1 "s_register_operand" "0,r")))
4898 (clobber (reg:CC CC_REGNUM))]
4899 "TARGET_ARM"
4900 "#"
4901 "&& reload_completed"
4902 [(const_int 0)]
4903 {
4904 /* if (which_alternative == 0) */
4905 if (REGNO(operands[0]) == REGNO(operands[1]))
4906 {
4907 /* Emit the pattern:
4908 cmp\\t%0, #0\;rsblt\\t%0, %0, #0
4909 [(set (reg:CC CC_REGNUM)
4910 (compare:CC (match_dup 0) (const_int 0)))
4911 (cond_exec (lt:CC (reg:CC CC_REGNUM) (const_int 0))
4912 (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1))))]
4913 */
4914 emit_insn (gen_rtx_SET (gen_rtx_REG (CCmode, CC_REGNUM),
4915 gen_rtx_COMPARE (CCmode, operands[0], const0_rtx)));
4916 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
4917 (gen_rtx_LT (SImode,
4918 gen_rtx_REG (CCmode, CC_REGNUM),
4919 const0_rtx)),
4920 (gen_rtx_SET (operands[0],
4921 (gen_rtx_MINUS (SImode,
4922 const0_rtx,
4923 operands[1]))))));
4924 DONE;
4925 }
4926 else
4927 {
4928 /* Emit the pattern:
4929 alt1: eor%?\\t%0, %1, %1, asr #31\;sub%?\\t%0, %0, %1, asr #31
4930 [(set (match_dup 0)
4931 (xor:SI (match_dup 1)
4932 (ashiftrt:SI (match_dup 1) (const_int 31))))
4933 (set (match_dup 0)
4934 (minus:SI (match_dup 0)
4935 (ashiftrt:SI (match_dup 1) (const_int 31))))]
4936 */
4937 emit_insn (gen_rtx_SET (operands[0],
4938 gen_rtx_XOR (SImode,
4939 gen_rtx_ASHIFTRT (SImode,
4940 operands[1],
4941 GEN_INT (31)),
4942 operands[1])));
4943 emit_insn (gen_rtx_SET (operands[0],
4944 gen_rtx_MINUS (SImode,
4945 operands[0],
4946 gen_rtx_ASHIFTRT (SImode,
4947 operands[1],
4948 GEN_INT (31)))));
4949 DONE;
4950 }
4951 }
4952 [(set_attr "conds" "clob,*")
4953 (set_attr "shift" "1")
4954 (set_attr "predicable" "no, yes")
4955 (set_attr "length" "8")
4956 (set_attr "type" "multiple")]
4957 )
4958
4959 (define_insn_and_split "*arm_neg_abssi2"
4960 [(set (match_operand:SI 0 "s_register_operand" "=r,&r")
4961 (neg:SI (abs:SI (match_operand:SI 1 "s_register_operand" "0,r"))))
4962 (clobber (reg:CC CC_REGNUM))]
4963 "TARGET_ARM"
4964 "#"
4965 "&& reload_completed"
4966 [(const_int 0)]
4967 {
4968 /* if (which_alternative == 0) */
4969 if (REGNO (operands[0]) == REGNO (operands[1]))
4970 {
4971 /* Emit the pattern:
4972 cmp\\t%0, #0\;rsbgt\\t%0, %0, #0
4973 */
4974 emit_insn (gen_rtx_SET (gen_rtx_REG (CCmode, CC_REGNUM),
4975 gen_rtx_COMPARE (CCmode, operands[0], const0_rtx)));
4976 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
4977 gen_rtx_GT (SImode,
4978 gen_rtx_REG (CCmode, CC_REGNUM),
4979 const0_rtx),
4980 gen_rtx_SET (operands[0],
4981 (gen_rtx_MINUS (SImode,
4982 const0_rtx,
4983 operands[1])))));
4984 }
4985 else
4986 {
4987 /* Emit the pattern:
4988 eor%?\\t%0, %1, %1, asr #31\;rsb%?\\t%0, %0, %1, asr #31
4989 */
4990 emit_insn (gen_rtx_SET (operands[0],
4991 gen_rtx_XOR (SImode,
4992 gen_rtx_ASHIFTRT (SImode,
4993 operands[1],
4994 GEN_INT (31)),
4995 operands[1])));
4996 emit_insn (gen_rtx_SET (operands[0],
4997 gen_rtx_MINUS (SImode,
4998 gen_rtx_ASHIFTRT (SImode,
4999 operands[1],
5000 GEN_INT (31)),
5001 operands[0])));
5002 }
5003 DONE;
5004 }
5005 [(set_attr "conds" "clob,*")
5006 (set_attr "shift" "1")
5007 (set_attr "predicable" "no, yes")
5008 (set_attr "length" "8")
5009 (set_attr "type" "multiple")]
5010 )
5011
5012 (define_expand "abssf2"
5013 [(set (match_operand:SF 0 "s_register_operand" "")
5014 (abs:SF (match_operand:SF 1 "s_register_operand" "")))]
5015 "TARGET_32BIT && TARGET_HARD_FLOAT"
5016 "")
5017
5018 (define_expand "absdf2"
5019 [(set (match_operand:DF 0 "s_register_operand" "")
5020 (abs:DF (match_operand:DF 1 "s_register_operand" "")))]
5021 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
5022 "")
5023
5024 (define_expand "sqrtsf2"
5025 [(set (match_operand:SF 0 "s_register_operand" "")
5026 (sqrt:SF (match_operand:SF 1 "s_register_operand" "")))]
5027 "TARGET_32BIT && TARGET_HARD_FLOAT"
5028 "")
5029
5030 (define_expand "sqrtdf2"
5031 [(set (match_operand:DF 0 "s_register_operand" "")
5032 (sqrt:DF (match_operand:DF 1 "s_register_operand" "")))]
5033 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
5034 "")
5035
5036 (define_expand "one_cmpldi2"
5037 [(set (match_operand:DI 0 "s_register_operand" "")
5038 (not:DI (match_operand:DI 1 "s_register_operand" "")))]
5039 "TARGET_32BIT"
5040 "
5041 if (!TARGET_NEON && !TARGET_IWMMXT)
5042 {
5043 rtx low = simplify_gen_unary (NOT, SImode,
5044 gen_lowpart (SImode, operands[1]),
5045 SImode);
5046 rtx high = simplify_gen_unary (NOT, SImode,
5047 gen_highpart_mode (SImode, DImode,
5048 operands[1]),
5049 SImode);
5050
5051 emit_insn (gen_rtx_SET (gen_lowpart (SImode, operands[0]), low));
5052 emit_insn (gen_rtx_SET (gen_highpart (SImode, operands[0]), high));
5053
5054 DONE;
5055 }
5056 /* Otherwise expand pattern as above. */
5057 "
5058 )
5059
5060 (define_insn_and_split "*one_cmpldi2_insn"
5061 [(set (match_operand:DI 0 "s_register_operand" "=w,&r,&r,?w")
5062 (not:DI (match_operand:DI 1 "s_register_operand" " w, 0, r, w")))]
5063 "TARGET_32BIT"
5064 "@
5065 vmvn\t%P0, %P1
5066 #
5067 #
5068 vmvn\t%P0, %P1"
5069 "TARGET_32BIT && reload_completed
5070 && arm_general_register_operand (operands[0], DImode)"
5071 [(set (match_dup 0) (not:SI (match_dup 1)))
5072 (set (match_dup 2) (not:SI (match_dup 3)))]
5073 "
5074 {
5075 operands[2] = gen_highpart (SImode, operands[0]);
5076 operands[0] = gen_lowpart (SImode, operands[0]);
5077 operands[3] = gen_highpart (SImode, operands[1]);
5078 operands[1] = gen_lowpart (SImode, operands[1]);
5079 }"
5080 [(set_attr "length" "*,8,8,*")
5081 (set_attr "predicable" "no,yes,yes,no")
5082 (set_attr "type" "neon_move,multiple,multiple,neon_move")
5083 (set_attr "arch" "neon_for_64bits,*,*,avoid_neon_for_64bits")]
5084 )
5085
5086 (define_expand "one_cmplsi2"
5087 [(set (match_operand:SI 0 "s_register_operand" "")
5088 (not:SI (match_operand:SI 1 "s_register_operand" "")))]
5089 "TARGET_EITHER"
5090 ""
5091 )
5092
5093 (define_insn "*arm_one_cmplsi2"
5094 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
5095 (not:SI (match_operand:SI 1 "s_register_operand" "l,r")))]
5096 "TARGET_32BIT"
5097 "mvn%?\\t%0, %1"
5098 [(set_attr "predicable" "yes")
5099 (set_attr "predicable_short_it" "yes,no")
5100 (set_attr "arch" "t2,*")
5101 (set_attr "length" "4")
5102 (set_attr "type" "mvn_reg")]
5103 )
5104
5105 (define_insn "*notsi_compare0"
5106 [(set (reg:CC_NOOV CC_REGNUM)
5107 (compare:CC_NOOV (not:SI (match_operand:SI 1 "s_register_operand" "r"))
5108 (const_int 0)))
5109 (set (match_operand:SI 0 "s_register_operand" "=r")
5110 (not:SI (match_dup 1)))]
5111 "TARGET_32BIT"
5112 "mvns%?\\t%0, %1"
5113 [(set_attr "conds" "set")
5114 (set_attr "type" "mvn_reg")]
5115 )
5116
5117 (define_insn "*notsi_compare0_scratch"
5118 [(set (reg:CC_NOOV CC_REGNUM)
5119 (compare:CC_NOOV (not:SI (match_operand:SI 1 "s_register_operand" "r"))
5120 (const_int 0)))
5121 (clobber (match_scratch:SI 0 "=r"))]
5122 "TARGET_32BIT"
5123 "mvns%?\\t%0, %1"
5124 [(set_attr "conds" "set")
5125 (set_attr "type" "mvn_reg")]
5126 )
5127 \f
5128 ;; Fixed <--> Floating conversion insns
5129
5130 (define_expand "floatsihf2"
5131 [(set (match_operand:HF 0 "general_operand" "")
5132 (float:HF (match_operand:SI 1 "general_operand" "")))]
5133 "TARGET_EITHER"
5134 "
5135 {
5136 rtx op1 = gen_reg_rtx (SFmode);
5137 expand_float (op1, operands[1], 0);
5138 op1 = convert_to_mode (HFmode, op1, 0);
5139 emit_move_insn (operands[0], op1);
5140 DONE;
5141 }"
5142 )
5143
5144 (define_expand "floatdihf2"
5145 [(set (match_operand:HF 0 "general_operand" "")
5146 (float:HF (match_operand:DI 1 "general_operand" "")))]
5147 "TARGET_EITHER"
5148 "
5149 {
5150 rtx op1 = gen_reg_rtx (SFmode);
5151 expand_float (op1, operands[1], 0);
5152 op1 = convert_to_mode (HFmode, op1, 0);
5153 emit_move_insn (operands[0], op1);
5154 DONE;
5155 }"
5156 )
5157
5158 (define_expand "floatsisf2"
5159 [(set (match_operand:SF 0 "s_register_operand" "")
5160 (float:SF (match_operand:SI 1 "s_register_operand" "")))]
5161 "TARGET_32BIT && TARGET_HARD_FLOAT"
5162 "
5163 ")
5164
5165 (define_expand "floatsidf2"
5166 [(set (match_operand:DF 0 "s_register_operand" "")
5167 (float:DF (match_operand:SI 1 "s_register_operand" "")))]
5168 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
5169 "
5170 ")
5171
5172 (define_expand "fix_trunchfsi2"
5173 [(set (match_operand:SI 0 "general_operand" "")
5174 (fix:SI (fix:HF (match_operand:HF 1 "general_operand" ""))))]
5175 "TARGET_EITHER"
5176 "
5177 {
5178 rtx op1 = convert_to_mode (SFmode, operands[1], 0);
5179 expand_fix (operands[0], op1, 0);
5180 DONE;
5181 }"
5182 )
5183
5184 (define_expand "fix_trunchfdi2"
5185 [(set (match_operand:DI 0 "general_operand" "")
5186 (fix:DI (fix:HF (match_operand:HF 1 "general_operand" ""))))]
5187 "TARGET_EITHER"
5188 "
5189 {
5190 rtx op1 = convert_to_mode (SFmode, operands[1], 0);
5191 expand_fix (operands[0], op1, 0);
5192 DONE;
5193 }"
5194 )
5195
5196 (define_expand "fix_truncsfsi2"
5197 [(set (match_operand:SI 0 "s_register_operand" "")
5198 (fix:SI (fix:SF (match_operand:SF 1 "s_register_operand" ""))))]
5199 "TARGET_32BIT && TARGET_HARD_FLOAT"
5200 "
5201 ")
5202
5203 (define_expand "fix_truncdfsi2"
5204 [(set (match_operand:SI 0 "s_register_operand" "")
5205 (fix:SI (fix:DF (match_operand:DF 1 "s_register_operand" ""))))]
5206 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
5207 "
5208 ")
5209
5210 ;; Truncation insns
5211
5212 (define_expand "truncdfsf2"
5213 [(set (match_operand:SF 0 "s_register_operand" "")
5214 (float_truncate:SF
5215 (match_operand:DF 1 "s_register_operand" "")))]
5216 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
5217 ""
5218 )
5219
5220 ;; DFmode to HFmode conversions on targets without a single-step hardware
5221 ;; instruction for it would have to go through SFmode. This is dangerous
5222 ;; as it introduces double rounding.
5223 ;;
5224 ;; Disable this pattern unless we are in an unsafe math mode, or we have
5225 ;; a single-step instruction.
5226
5227 (define_expand "truncdfhf2"
5228 [(set (match_operand:HF 0 "s_register_operand" "")
5229 (float_truncate:HF
5230 (match_operand:DF 1 "s_register_operand" "")))]
5231 "(TARGET_EITHER && flag_unsafe_math_optimizations)
5232 || (TARGET_32BIT && TARGET_FP16_TO_DOUBLE)"
5233 {
5234 /* We don't have a direct instruction for this, so we must be in
5235 an unsafe math mode, and going via SFmode. */
5236
5237 if (!(TARGET_32BIT && TARGET_FP16_TO_DOUBLE))
5238 {
5239 rtx op1;
5240 op1 = convert_to_mode (SFmode, operands[1], 0);
5241 op1 = convert_to_mode (HFmode, op1, 0);
5242 emit_move_insn (operands[0], op1);
5243 DONE;
5244 }
5245 /* Otherwise, we will pick this up as a single instruction with
5246 no intermediary rounding. */
5247 }
5248 )
5249 \f
5250 ;; Zero and sign extension instructions.
5251
5252 (define_insn "zero_extend<mode>di2"
5253 [(set (match_operand:DI 0 "s_register_operand" "=w,r,?r,w")
5254 (zero_extend:DI (match_operand:QHSI 1 "<qhs_zextenddi_op>"
5255 "<qhs_zextenddi_cstr>")))]
5256 "TARGET_32BIT <qhs_zextenddi_cond>"
5257 "#"
5258 [(set_attr "length" "8,4,8,8")
5259 (set_attr "arch" "neon_for_64bits,*,*,avoid_neon_for_64bits")
5260 (set_attr "ce_count" "2")
5261 (set_attr "predicable" "yes")
5262 (set_attr "type" "multiple,mov_reg,multiple,multiple")]
5263 )
5264
5265 (define_insn "extend<mode>di2"
5266 [(set (match_operand:DI 0 "s_register_operand" "=w,r,?r,?r,w")
5267 (sign_extend:DI (match_operand:QHSI 1 "<qhs_extenddi_op>"
5268 "<qhs_extenddi_cstr>")))]
5269 "TARGET_32BIT <qhs_sextenddi_cond>"
5270 "#"
5271 [(set_attr "length" "8,4,8,8,8")
5272 (set_attr "ce_count" "2")
5273 (set_attr "shift" "1")
5274 (set_attr "predicable" "yes")
5275 (set_attr "arch" "neon_for_64bits,*,a,t,avoid_neon_for_64bits")
5276 (set_attr "type" "multiple,mov_reg,multiple,multiple,multiple")]
5277 )
5278
5279 ;; Splits for all extensions to DImode
5280 (define_split
5281 [(set (match_operand:DI 0 "s_register_operand" "")
5282 (zero_extend:DI (match_operand 1 "nonimmediate_operand" "")))]
5283 "TARGET_32BIT && reload_completed && !IS_VFP_REGNUM (REGNO (operands[0]))"
5284 [(set (match_dup 0) (match_dup 1))]
5285 {
5286 rtx lo_part = gen_lowpart (SImode, operands[0]);
5287 machine_mode src_mode = GET_MODE (operands[1]);
5288
5289 if (REG_P (operands[0])
5290 && !reg_overlap_mentioned_p (operands[0], operands[1]))
5291 emit_clobber (operands[0]);
5292 if (!REG_P (lo_part) || src_mode != SImode
5293 || !rtx_equal_p (lo_part, operands[1]))
5294 {
5295 if (src_mode == SImode)
5296 emit_move_insn (lo_part, operands[1]);
5297 else
5298 emit_insn (gen_rtx_SET (lo_part,
5299 gen_rtx_ZERO_EXTEND (SImode, operands[1])));
5300 operands[1] = lo_part;
5301 }
5302 operands[0] = gen_highpart (SImode, operands[0]);
5303 operands[1] = const0_rtx;
5304 })
5305
5306 (define_split
5307 [(set (match_operand:DI 0 "s_register_operand" "")
5308 (sign_extend:DI (match_operand 1 "nonimmediate_operand" "")))]
5309 "TARGET_32BIT && reload_completed && !IS_VFP_REGNUM (REGNO (operands[0]))"
5310 [(set (match_dup 0) (ashiftrt:SI (match_dup 1) (const_int 31)))]
5311 {
5312 rtx lo_part = gen_lowpart (SImode, operands[0]);
5313 machine_mode src_mode = GET_MODE (operands[1]);
5314
5315 if (REG_P (operands[0])
5316 && !reg_overlap_mentioned_p (operands[0], operands[1]))
5317 emit_clobber (operands[0]);
5318
5319 if (!REG_P (lo_part) || src_mode != SImode
5320 || !rtx_equal_p (lo_part, operands[1]))
5321 {
5322 if (src_mode == SImode)
5323 emit_move_insn (lo_part, operands[1]);
5324 else
5325 emit_insn (gen_rtx_SET (lo_part,
5326 gen_rtx_SIGN_EXTEND (SImode, operands[1])));
5327 operands[1] = lo_part;
5328 }
5329 operands[0] = gen_highpart (SImode, operands[0]);
5330 })
5331
5332 (define_expand "zero_extendhisi2"
5333 [(set (match_operand:SI 0 "s_register_operand" "")
5334 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
5335 "TARGET_EITHER"
5336 {
5337 if (TARGET_ARM && !arm_arch4 && MEM_P (operands[1]))
5338 {
5339 emit_insn (gen_movhi_bytes (operands[0], operands[1]));
5340 DONE;
5341 }
5342 if (!arm_arch6 && !MEM_P (operands[1]))
5343 {
5344 rtx t = gen_lowpart (SImode, operands[1]);
5345 rtx tmp = gen_reg_rtx (SImode);
5346 emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (16)));
5347 emit_insn (gen_lshrsi3 (operands[0], tmp, GEN_INT (16)));
5348 DONE;
5349 }
5350 })
5351
5352 (define_split
5353 [(set (match_operand:SI 0 "s_register_operand" "")
5354 (zero_extend:SI (match_operand:HI 1 "s_register_operand" "")))]
5355 "!TARGET_THUMB2 && !arm_arch6"
5356 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
5357 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 16)))]
5358 {
5359 operands[2] = gen_lowpart (SImode, operands[1]);
5360 })
5361
5362 (define_insn "*arm_zero_extendhisi2"
5363 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5364 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
5365 "TARGET_ARM && arm_arch4 && !arm_arch6"
5366 "@
5367 #
5368 ldrh%?\\t%0, %1"
5369 [(set_attr "type" "alu_shift_reg,load_byte")
5370 (set_attr "predicable" "yes")]
5371 )
5372
5373 (define_insn "*arm_zero_extendhisi2_v6"
5374 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5375 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,Uh")))]
5376 "TARGET_ARM && arm_arch6"
5377 "@
5378 uxth%?\\t%0, %1
5379 ldrh%?\\t%0, %1"
5380 [(set_attr "predicable" "yes")
5381 (set_attr "type" "extend,load_byte")]
5382 )
5383
5384 (define_insn "*arm_zero_extendhisi2addsi"
5385 [(set (match_operand:SI 0 "s_register_operand" "=r")
5386 (plus:SI (zero_extend:SI (match_operand:HI 1 "s_register_operand" "r"))
5387 (match_operand:SI 2 "s_register_operand" "r")))]
5388 "TARGET_INT_SIMD"
5389 "uxtah%?\\t%0, %2, %1"
5390 [(set_attr "type" "alu_shift_reg")
5391 (set_attr "predicable" "yes")]
5392 )
5393
5394 (define_expand "zero_extendqisi2"
5395 [(set (match_operand:SI 0 "s_register_operand" "")
5396 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))]
5397 "TARGET_EITHER"
5398 {
5399 if (TARGET_ARM && !arm_arch6 && !MEM_P (operands[1]))
5400 {
5401 emit_insn (gen_andsi3 (operands[0],
5402 gen_lowpart (SImode, operands[1]),
5403 GEN_INT (255)));
5404 DONE;
5405 }
5406 if (!arm_arch6 && !MEM_P (operands[1]))
5407 {
5408 rtx t = gen_lowpart (SImode, operands[1]);
5409 rtx tmp = gen_reg_rtx (SImode);
5410 emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (24)));
5411 emit_insn (gen_lshrsi3 (operands[0], tmp, GEN_INT (24)));
5412 DONE;
5413 }
5414 })
5415
5416 (define_split
5417 [(set (match_operand:SI 0 "s_register_operand" "")
5418 (zero_extend:SI (match_operand:QI 1 "s_register_operand" "")))]
5419 "!arm_arch6"
5420 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 24)))
5421 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 24)))]
5422 {
5423 operands[2] = simplify_gen_subreg (SImode, operands[1], QImode, 0);
5424 if (TARGET_ARM)
5425 {
5426 emit_insn (gen_andsi3 (operands[0], operands[2], GEN_INT (255)));
5427 DONE;
5428 }
5429 })
5430
5431 (define_insn "*arm_zero_extendqisi2"
5432 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5433 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
5434 "TARGET_ARM && !arm_arch6"
5435 "@
5436 #
5437 ldrb%?\\t%0, %1\\t%@ zero_extendqisi2"
5438 [(set_attr "length" "8,4")
5439 (set_attr "type" "alu_shift_reg,load_byte")
5440 (set_attr "predicable" "yes")]
5441 )
5442
5443 (define_insn "*arm_zero_extendqisi2_v6"
5444 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5445 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,Uh")))]
5446 "TARGET_ARM && arm_arch6"
5447 "@
5448 uxtb%?\\t%0, %1
5449 ldrb%?\\t%0, %1\\t%@ zero_extendqisi2"
5450 [(set_attr "type" "extend,load_byte")
5451 (set_attr "predicable" "yes")]
5452 )
5453
5454 (define_insn "*arm_zero_extendqisi2addsi"
5455 [(set (match_operand:SI 0 "s_register_operand" "=r")
5456 (plus:SI (zero_extend:SI (match_operand:QI 1 "s_register_operand" "r"))
5457 (match_operand:SI 2 "s_register_operand" "r")))]
5458 "TARGET_INT_SIMD"
5459 "uxtab%?\\t%0, %2, %1"
5460 [(set_attr "predicable" "yes")
5461 (set_attr "type" "alu_shift_reg")]
5462 )
5463
5464 (define_split
5465 [(set (match_operand:SI 0 "s_register_operand" "")
5466 (zero_extend:SI (subreg:QI (match_operand:SI 1 "" "") 0)))
5467 (clobber (match_operand:SI 2 "s_register_operand" ""))]
5468 "TARGET_32BIT && (!MEM_P (operands[1])) && ! BYTES_BIG_ENDIAN"
5469 [(set (match_dup 2) (match_dup 1))
5470 (set (match_dup 0) (and:SI (match_dup 2) (const_int 255)))]
5471 ""
5472 )
5473
5474 (define_split
5475 [(set (match_operand:SI 0 "s_register_operand" "")
5476 (zero_extend:SI (subreg:QI (match_operand:SI 1 "" "") 3)))
5477 (clobber (match_operand:SI 2 "s_register_operand" ""))]
5478 "TARGET_32BIT && (!MEM_P (operands[1])) && BYTES_BIG_ENDIAN"
5479 [(set (match_dup 2) (match_dup 1))
5480 (set (match_dup 0) (and:SI (match_dup 2) (const_int 255)))]
5481 ""
5482 )
5483
5484
5485 (define_split
5486 [(set (match_operand:SI 0 "s_register_operand" "")
5487 (IOR_XOR:SI (and:SI (ashift:SI
5488 (match_operand:SI 1 "s_register_operand" "")
5489 (match_operand:SI 2 "const_int_operand" ""))
5490 (match_operand:SI 3 "const_int_operand" ""))
5491 (zero_extend:SI
5492 (match_operator 5 "subreg_lowpart_operator"
5493 [(match_operand:SI 4 "s_register_operand" "")]))))]
5494 "TARGET_32BIT
5495 && (UINTVAL (operands[3])
5496 == (GET_MODE_MASK (GET_MODE (operands[5]))
5497 & (GET_MODE_MASK (GET_MODE (operands[5]))
5498 << (INTVAL (operands[2])))))"
5499 [(set (match_dup 0) (IOR_XOR:SI (ashift:SI (match_dup 1) (match_dup 2))
5500 (match_dup 4)))
5501 (set (match_dup 0) (zero_extend:SI (match_dup 5)))]
5502 "operands[5] = gen_lowpart (GET_MODE (operands[5]), operands[0]);"
5503 )
5504
5505 (define_insn "*compareqi_eq0"
5506 [(set (reg:CC_Z CC_REGNUM)
5507 (compare:CC_Z (match_operand:QI 0 "s_register_operand" "r")
5508 (const_int 0)))]
5509 "TARGET_32BIT"
5510 "tst%?\\t%0, #255"
5511 [(set_attr "conds" "set")
5512 (set_attr "predicable" "yes")
5513 (set_attr "type" "logic_imm")]
5514 )
5515
5516 (define_expand "extendhisi2"
5517 [(set (match_operand:SI 0 "s_register_operand" "")
5518 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
5519 "TARGET_EITHER"
5520 {
5521 if (TARGET_THUMB1)
5522 {
5523 emit_insn (gen_thumb1_extendhisi2 (operands[0], operands[1]));
5524 DONE;
5525 }
5526 if (MEM_P (operands[1]) && TARGET_ARM && !arm_arch4)
5527 {
5528 emit_insn (gen_extendhisi2_mem (operands[0], operands[1]));
5529 DONE;
5530 }
5531
5532 if (!arm_arch6 && !MEM_P (operands[1]))
5533 {
5534 rtx t = gen_lowpart (SImode, operands[1]);
5535 rtx tmp = gen_reg_rtx (SImode);
5536 emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (16)));
5537 emit_insn (gen_ashrsi3 (operands[0], tmp, GEN_INT (16)));
5538 DONE;
5539 }
5540 })
5541
5542 (define_split
5543 [(parallel
5544 [(set (match_operand:SI 0 "register_operand" "")
5545 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))
5546 (clobber (match_scratch:SI 2 ""))])]
5547 "!arm_arch6"
5548 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
5549 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
5550 {
5551 operands[2] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
5552 })
5553
5554 ;; This pattern will only be used when ldsh is not available
5555 (define_expand "extendhisi2_mem"
5556 [(set (match_dup 2) (zero_extend:SI (match_operand:HI 1 "" "")))
5557 (set (match_dup 3)
5558 (zero_extend:SI (match_dup 7)))
5559 (set (match_dup 6) (ashift:SI (match_dup 4) (const_int 24)))
5560 (set (match_operand:SI 0 "" "")
5561 (ior:SI (ashiftrt:SI (match_dup 6) (const_int 16)) (match_dup 5)))]
5562 "TARGET_ARM"
5563 "
5564 {
5565 rtx mem1, mem2;
5566 rtx addr = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
5567
5568 mem1 = change_address (operands[1], QImode, addr);
5569 mem2 = change_address (operands[1], QImode,
5570 plus_constant (Pmode, addr, 1));
5571 operands[0] = gen_lowpart (SImode, operands[0]);
5572 operands[1] = mem1;
5573 operands[2] = gen_reg_rtx (SImode);
5574 operands[3] = gen_reg_rtx (SImode);
5575 operands[6] = gen_reg_rtx (SImode);
5576 operands[7] = mem2;
5577
5578 if (BYTES_BIG_ENDIAN)
5579 {
5580 operands[4] = operands[2];
5581 operands[5] = operands[3];
5582 }
5583 else
5584 {
5585 operands[4] = operands[3];
5586 operands[5] = operands[2];
5587 }
5588 }"
5589 )
5590
5591 (define_split
5592 [(set (match_operand:SI 0 "register_operand" "")
5593 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
5594 "!arm_arch6"
5595 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
5596 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
5597 {
5598 operands[2] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
5599 })
5600
5601 (define_insn "*arm_extendhisi2"
5602 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5603 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,Uh")))]
5604 "TARGET_ARM && arm_arch4 && !arm_arch6"
5605 "@
5606 #
5607 ldrsh%?\\t%0, %1"
5608 [(set_attr "length" "8,4")
5609 (set_attr "type" "alu_shift_reg,load_byte")
5610 (set_attr "predicable" "yes")]
5611 )
5612
5613 ;; ??? Check Thumb-2 pool range
5614 (define_insn "*arm_extendhisi2_v6"
5615 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5616 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,Uh")))]
5617 "TARGET_32BIT && arm_arch6"
5618 "@
5619 sxth%?\\t%0, %1
5620 ldrsh%?\\t%0, %1"
5621 [(set_attr "type" "extend,load_byte")
5622 (set_attr "predicable" "yes")]
5623 )
5624
5625 (define_insn "*arm_extendhisi2addsi"
5626 [(set (match_operand:SI 0 "s_register_operand" "=r")
5627 (plus:SI (sign_extend:SI (match_operand:HI 1 "s_register_operand" "r"))
5628 (match_operand:SI 2 "s_register_operand" "r")))]
5629 "TARGET_INT_SIMD"
5630 "sxtah%?\\t%0, %2, %1"
5631 [(set_attr "type" "alu_shift_reg")]
5632 )
5633
5634 (define_expand "extendqihi2"
5635 [(set (match_dup 2)
5636 (ashift:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "")
5637 (const_int 24)))
5638 (set (match_operand:HI 0 "s_register_operand" "")
5639 (ashiftrt:SI (match_dup 2)
5640 (const_int 24)))]
5641 "TARGET_ARM"
5642 "
5643 {
5644 if (arm_arch4 && MEM_P (operands[1]))
5645 {
5646 emit_insn (gen_rtx_SET (operands[0],
5647 gen_rtx_SIGN_EXTEND (HImode, operands[1])));
5648 DONE;
5649 }
5650 if (!s_register_operand (operands[1], QImode))
5651 operands[1] = copy_to_mode_reg (QImode, operands[1]);
5652 operands[0] = gen_lowpart (SImode, operands[0]);
5653 operands[1] = gen_lowpart (SImode, operands[1]);
5654 operands[2] = gen_reg_rtx (SImode);
5655 }"
5656 )
5657
5658 (define_insn "*arm_extendqihi_insn"
5659 [(set (match_operand:HI 0 "s_register_operand" "=r")
5660 (sign_extend:HI (match_operand:QI 1 "arm_extendqisi_mem_op" "Uq")))]
5661 "TARGET_ARM && arm_arch4"
5662 "ldrsb%?\\t%0, %1"
5663 [(set_attr "type" "load_byte")
5664 (set_attr "predicable" "yes")]
5665 )
5666
5667 (define_expand "extendqisi2"
5668 [(set (match_operand:SI 0 "s_register_operand" "")
5669 (sign_extend:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "")))]
5670 "TARGET_EITHER"
5671 {
5672 if (!arm_arch4 && MEM_P (operands[1]))
5673 operands[1] = copy_to_mode_reg (QImode, operands[1]);
5674
5675 if (!arm_arch6 && !MEM_P (operands[1]))
5676 {
5677 rtx t = gen_lowpart (SImode, operands[1]);
5678 rtx tmp = gen_reg_rtx (SImode);
5679 emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (24)));
5680 emit_insn (gen_ashrsi3 (operands[0], tmp, GEN_INT (24)));
5681 DONE;
5682 }
5683 })
5684
5685 (define_split
5686 [(set (match_operand:SI 0 "register_operand" "")
5687 (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
5688 "!arm_arch6"
5689 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 24)))
5690 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 24)))]
5691 {
5692 operands[2] = simplify_gen_subreg (SImode, operands[1], QImode, 0);
5693 })
5694
5695 (define_insn "*arm_extendqisi"
5696 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5697 (sign_extend:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "r,Uq")))]
5698 "TARGET_ARM && arm_arch4 && !arm_arch6"
5699 "@
5700 #
5701 ldrsb%?\\t%0, %1"
5702 [(set_attr "length" "8,4")
5703 (set_attr "type" "alu_shift_reg,load_byte")
5704 (set_attr "predicable" "yes")]
5705 )
5706
5707 (define_insn "*arm_extendqisi_v6"
5708 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5709 (sign_extend:SI
5710 (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "r,Uq")))]
5711 "TARGET_ARM && arm_arch6"
5712 "@
5713 sxtb%?\\t%0, %1
5714 ldrsb%?\\t%0, %1"
5715 [(set_attr "type" "extend,load_byte")
5716 (set_attr "predicable" "yes")]
5717 )
5718
5719 (define_insn "*arm_extendqisi2addsi"
5720 [(set (match_operand:SI 0 "s_register_operand" "=r")
5721 (plus:SI (sign_extend:SI (match_operand:QI 1 "s_register_operand" "r"))
5722 (match_operand:SI 2 "s_register_operand" "r")))]
5723 "TARGET_INT_SIMD"
5724 "sxtab%?\\t%0, %2, %1"
5725 [(set_attr "type" "alu_shift_reg")
5726 (set_attr "predicable" "yes")]
5727 )
5728
5729 (define_expand "extendsfdf2"
5730 [(set (match_operand:DF 0 "s_register_operand" "")
5731 (float_extend:DF (match_operand:SF 1 "s_register_operand" "")))]
5732 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
5733 ""
5734 )
5735
5736 ;; HFmode -> DFmode conversions where we don't have an instruction for it
5737 ;; must go through SFmode.
5738 ;;
5739 ;; This is always safe for an extend.
5740
5741 (define_expand "extendhfdf2"
5742 [(set (match_operand:DF 0 "s_register_operand" "")
5743 (float_extend:DF (match_operand:HF 1 "s_register_operand" "")))]
5744 "TARGET_EITHER"
5745 {
5746 /* We don't have a direct instruction for this, so go via SFmode. */
5747 if (!(TARGET_32BIT && TARGET_FP16_TO_DOUBLE))
5748 {
5749 rtx op1;
5750 op1 = convert_to_mode (SFmode, operands[1], 0);
5751 op1 = convert_to_mode (DFmode, op1, 0);
5752 emit_insn (gen_movdf (operands[0], op1));
5753 DONE;
5754 }
5755 /* Otherwise, we're done producing RTL and will pick up the correct
5756 pattern to do this with one rounding-step in a single instruction. */
5757 }
5758 )
5759 \f
5760 ;; Move insns (including loads and stores)
5761
5762 ;; XXX Just some ideas about movti.
5763 ;; I don't think these are a good idea on the arm, there just aren't enough
5764 ;; registers
5765 ;;(define_expand "loadti"
5766 ;; [(set (match_operand:TI 0 "s_register_operand" "")
5767 ;; (mem:TI (match_operand:SI 1 "address_operand" "")))]
5768 ;; "" "")
5769
5770 ;;(define_expand "storeti"
5771 ;; [(set (mem:TI (match_operand:TI 0 "address_operand" ""))
5772 ;; (match_operand:TI 1 "s_register_operand" ""))]
5773 ;; "" "")
5774
5775 ;;(define_expand "movti"
5776 ;; [(set (match_operand:TI 0 "general_operand" "")
5777 ;; (match_operand:TI 1 "general_operand" ""))]
5778 ;; ""
5779 ;; "
5780 ;;{
5781 ;; rtx insn;
5782 ;;
5783 ;; if (MEM_P (operands[0]) && MEM_P (operands[1]))
5784 ;; operands[1] = copy_to_reg (operands[1]);
5785 ;; if (MEM_P (operands[0]))
5786 ;; insn = gen_storeti (XEXP (operands[0], 0), operands[1]);
5787 ;; else if (MEM_P (operands[1]))
5788 ;; insn = gen_loadti (operands[0], XEXP (operands[1], 0));
5789 ;; else
5790 ;; FAIL;
5791 ;;
5792 ;; emit_insn (insn);
5793 ;; DONE;
5794 ;;}")
5795
5796 ;; Recognize garbage generated above.
5797
5798 ;;(define_insn ""
5799 ;; [(set (match_operand:TI 0 "general_operand" "=r,r,r,<,>,m")
5800 ;; (match_operand:TI 1 "general_operand" "<,>,m,r,r,r"))]
5801 ;; ""
5802 ;; "*
5803 ;; {
5804 ;; register mem = (which_alternative < 3);
5805 ;; register const char *template;
5806 ;;
5807 ;; operands[mem] = XEXP (operands[mem], 0);
5808 ;; switch (which_alternative)
5809 ;; {
5810 ;; case 0: template = \"ldmdb\\t%1!, %M0\"; break;
5811 ;; case 1: template = \"ldmia\\t%1!, %M0\"; break;
5812 ;; case 2: template = \"ldmia\\t%1, %M0\"; break;
5813 ;; case 3: template = \"stmdb\\t%0!, %M1\"; break;
5814 ;; case 4: template = \"stmia\\t%0!, %M1\"; break;
5815 ;; case 5: template = \"stmia\\t%0, %M1\"; break;
5816 ;; }
5817 ;; output_asm_insn (template, operands);
5818 ;; return \"\";
5819 ;; }")
5820
5821 (define_expand "movdi"
5822 [(set (match_operand:DI 0 "general_operand" "")
5823 (match_operand:DI 1 "general_operand" ""))]
5824 "TARGET_EITHER"
5825 "
5826 if (can_create_pseudo_p ())
5827 {
5828 if (!REG_P (operands[0]))
5829 operands[1] = force_reg (DImode, operands[1]);
5830 }
5831 if (REG_P (operands[0]) && REGNO (operands[0]) <= LAST_ARM_REGNUM
5832 && !targetm.hard_regno_mode_ok (REGNO (operands[0]), DImode))
5833 {
5834 /* Avoid LDRD's into an odd-numbered register pair in ARM state
5835 when expanding function calls. */
5836 gcc_assert (can_create_pseudo_p ());
5837 if (MEM_P (operands[1]) && MEM_VOLATILE_P (operands[1]))
5838 {
5839 /* Perform load into legal reg pair first, then move. */
5840 rtx reg = gen_reg_rtx (DImode);
5841 emit_insn (gen_movdi (reg, operands[1]));
5842 operands[1] = reg;
5843 }
5844 emit_move_insn (gen_lowpart (SImode, operands[0]),
5845 gen_lowpart (SImode, operands[1]));
5846 emit_move_insn (gen_highpart (SImode, operands[0]),
5847 gen_highpart (SImode, operands[1]));
5848 DONE;
5849 }
5850 else if (REG_P (operands[1]) && REGNO (operands[1]) <= LAST_ARM_REGNUM
5851 && !targetm.hard_regno_mode_ok (REGNO (operands[1]), DImode))
5852 {
5853 /* Avoid STRD's from an odd-numbered register pair in ARM state
5854 when expanding function prologue. */
5855 gcc_assert (can_create_pseudo_p ());
5856 rtx split_dest = (MEM_P (operands[0]) && MEM_VOLATILE_P (operands[0]))
5857 ? gen_reg_rtx (DImode)
5858 : operands[0];
5859 emit_move_insn (gen_lowpart (SImode, split_dest),
5860 gen_lowpart (SImode, operands[1]));
5861 emit_move_insn (gen_highpart (SImode, split_dest),
5862 gen_highpart (SImode, operands[1]));
5863 if (split_dest != operands[0])
5864 emit_insn (gen_movdi (operands[0], split_dest));
5865 DONE;
5866 }
5867 "
5868 )
5869
5870 (define_insn "*arm_movdi"
5871 [(set (match_operand:DI 0 "nonimmediate_di_operand" "=r, r, r, r, m")
5872 (match_operand:DI 1 "di_operand" "rDa,Db,Dc,mi,r"))]
5873 "TARGET_32BIT
5874 && !(TARGET_HARD_FLOAT)
5875 && !TARGET_IWMMXT
5876 && ( register_operand (operands[0], DImode)
5877 || register_operand (operands[1], DImode))"
5878 "*
5879 switch (which_alternative)
5880 {
5881 case 0:
5882 case 1:
5883 case 2:
5884 return \"#\";
5885 case 3:
5886 /* Cannot load it directly, split to load it via MOV / MOVT. */
5887 if (!MEM_P (operands[1]) && arm_disable_literal_pool)
5888 return \"#\";
5889 /* Fall through. */
5890 default:
5891 return output_move_double (operands, true, NULL);
5892 }
5893 "
5894 [(set_attr "length" "8,12,16,8,8")
5895 (set_attr "type" "multiple,multiple,multiple,load_8,store_8")
5896 (set_attr "arm_pool_range" "*,*,*,1020,*")
5897 (set_attr "arm_neg_pool_range" "*,*,*,1004,*")
5898 (set_attr "thumb2_pool_range" "*,*,*,4094,*")
5899 (set_attr "thumb2_neg_pool_range" "*,*,*,0,*")]
5900 )
5901
5902 (define_split
5903 [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
5904 (match_operand:ANY64 1 "immediate_operand" ""))]
5905 "TARGET_32BIT
5906 && reload_completed
5907 && (arm_disable_literal_pool
5908 || (arm_const_double_inline_cost (operands[1])
5909 <= arm_max_const_double_inline_cost ()))"
5910 [(const_int 0)]
5911 "
5912 arm_split_constant (SET, SImode, curr_insn,
5913 INTVAL (gen_lowpart (SImode, operands[1])),
5914 gen_lowpart (SImode, operands[0]), NULL_RTX, 0);
5915 arm_split_constant (SET, SImode, curr_insn,
5916 INTVAL (gen_highpart_mode (SImode,
5917 GET_MODE (operands[0]),
5918 operands[1])),
5919 gen_highpart (SImode, operands[0]), NULL_RTX, 0);
5920 DONE;
5921 "
5922 )
5923
5924 ; If optimizing for size, or if we have load delay slots, then
5925 ; we want to split the constant into two separate operations.
5926 ; In both cases this may split a trivial part into a single data op
5927 ; leaving a single complex constant to load. We can also get longer
5928 ; offsets in a LDR which means we get better chances of sharing the pool
5929 ; entries. Finally, we can normally do a better job of scheduling
5930 ; LDR instructions than we can with LDM.
5931 ; This pattern will only match if the one above did not.
5932 (define_split
5933 [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
5934 (match_operand:ANY64 1 "const_double_operand" ""))]
5935 "TARGET_ARM && reload_completed
5936 && arm_const_double_by_parts (operands[1])"
5937 [(set (match_dup 0) (match_dup 1))
5938 (set (match_dup 2) (match_dup 3))]
5939 "
5940 operands[2] = gen_highpart (SImode, operands[0]);
5941 operands[3] = gen_highpart_mode (SImode, GET_MODE (operands[0]),
5942 operands[1]);
5943 operands[0] = gen_lowpart (SImode, operands[0]);
5944 operands[1] = gen_lowpart (SImode, operands[1]);
5945 "
5946 )
5947
5948 (define_split
5949 [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
5950 (match_operand:ANY64 1 "arm_general_register_operand" ""))]
5951 "TARGET_EITHER && reload_completed"
5952 [(set (match_dup 0) (match_dup 1))
5953 (set (match_dup 2) (match_dup 3))]
5954 "
5955 operands[2] = gen_highpart (SImode, operands[0]);
5956 operands[3] = gen_highpart (SImode, operands[1]);
5957 operands[0] = gen_lowpart (SImode, operands[0]);
5958 operands[1] = gen_lowpart (SImode, operands[1]);
5959
5960 /* Handle a partial overlap. */
5961 if (rtx_equal_p (operands[0], operands[3]))
5962 {
5963 rtx tmp0 = operands[0];
5964 rtx tmp1 = operands[1];
5965
5966 operands[0] = operands[2];
5967 operands[1] = operands[3];
5968 operands[2] = tmp0;
5969 operands[3] = tmp1;
5970 }
5971 "
5972 )
5973
5974 ;; We can't actually do base+index doubleword loads if the index and
5975 ;; destination overlap. Split here so that we at least have chance to
5976 ;; schedule.
5977 (define_split
5978 [(set (match_operand:DI 0 "s_register_operand" "")
5979 (mem:DI (plus:SI (match_operand:SI 1 "s_register_operand" "")
5980 (match_operand:SI 2 "s_register_operand" ""))))]
5981 "TARGET_LDRD
5982 && reg_overlap_mentioned_p (operands[0], operands[1])
5983 && reg_overlap_mentioned_p (operands[0], operands[2])"
5984 [(set (match_dup 4)
5985 (plus:SI (match_dup 1)
5986 (match_dup 2)))
5987 (set (match_dup 0)
5988 (mem:DI (match_dup 4)))]
5989 "
5990 operands[4] = gen_rtx_REG (SImode, REGNO(operands[0]));
5991 "
5992 )
5993
5994 (define_expand "movsi"
5995 [(set (match_operand:SI 0 "general_operand" "")
5996 (match_operand:SI 1 "general_operand" ""))]
5997 "TARGET_EITHER"
5998 "
5999 {
6000 rtx base, offset, tmp;
6001
6002 if (TARGET_32BIT || TARGET_HAVE_MOVT)
6003 {
6004 /* Everything except mem = const or mem = mem can be done easily. */
6005 if (MEM_P (operands[0]))
6006 operands[1] = force_reg (SImode, operands[1]);
6007 if (arm_general_register_operand (operands[0], SImode)
6008 && CONST_INT_P (operands[1])
6009 && !(const_ok_for_arm (INTVAL (operands[1]))
6010 || const_ok_for_arm (~INTVAL (operands[1]))))
6011 {
6012 if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[1]), SET))
6013 {
6014 emit_insn (gen_rtx_SET (operands[0], operands[1]));
6015 DONE;
6016 }
6017 else
6018 {
6019 arm_split_constant (SET, SImode, NULL_RTX,
6020 INTVAL (operands[1]), operands[0], NULL_RTX,
6021 optimize && can_create_pseudo_p ());
6022 DONE;
6023 }
6024 }
6025 }
6026 else /* Target doesn't have MOVT... */
6027 {
6028 if (can_create_pseudo_p ())
6029 {
6030 if (!REG_P (operands[0]))
6031 operands[1] = force_reg (SImode, operands[1]);
6032 }
6033 }
6034
6035 split_const (operands[1], &base, &offset);
6036 if (INTVAL (offset) != 0
6037 && targetm.cannot_force_const_mem (SImode, operands[1]))
6038 {
6039 tmp = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];
6040 emit_move_insn (tmp, base);
6041 emit_insn (gen_addsi3 (operands[0], tmp, offset));
6042 DONE;
6043 }
6044
6045 tmp = can_create_pseudo_p () ? NULL_RTX : operands[0];
6046
6047 /* Recognize the case where operand[1] is a reference to thread-local
6048 data and load its address to a register. Offsets have been split off
6049 already. */
6050 if (arm_tls_referenced_p (operands[1]))
6051 operands[1] = legitimize_tls_address (operands[1], tmp);
6052 else if (flag_pic
6053 && (CONSTANT_P (operands[1])
6054 || symbol_mentioned_p (operands[1])
6055 || label_mentioned_p (operands[1])))
6056 operands[1] =
6057 legitimize_pic_address (operands[1], SImode, tmp, NULL_RTX, false);
6058 }
6059 "
6060 )
6061
6062 ;; The ARM LO_SUM and HIGH are backwards - HIGH sets the low bits, and
6063 ;; LO_SUM adds in the high bits. Fortunately these are opaque operations
6064 ;; so this does not matter.
6065 (define_insn "*arm_movt"
6066 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r")
6067 (lo_sum:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6068 (match_operand:SI 2 "general_operand" "i,i")))]
6069 "TARGET_HAVE_MOVT && arm_valid_symbolic_address_p (operands[2])"
6070 "@
6071 movt%?\t%0, #:upper16:%c2
6072 movt\t%0, #:upper16:%c2"
6073 [(set_attr "arch" "32,v8mb")
6074 (set_attr "predicable" "yes")
6075 (set_attr "length" "4")
6076 (set_attr "type" "alu_sreg")]
6077 )
6078
6079 (define_insn "*arm_movsi_insn"
6080 [(set (match_operand:SI 0 "nonimmediate_operand" "=rk,r,r,r,rk,m")
6081 (match_operand:SI 1 "general_operand" "rk, I,K,j,mi,rk"))]
6082 "TARGET_ARM && !TARGET_IWMMXT && !TARGET_HARD_FLOAT
6083 && ( register_operand (operands[0], SImode)
6084 || register_operand (operands[1], SImode))"
6085 "@
6086 mov%?\\t%0, %1
6087 mov%?\\t%0, %1
6088 mvn%?\\t%0, #%B1
6089 movw%?\\t%0, %1
6090 ldr%?\\t%0, %1
6091 str%?\\t%1, %0"
6092 [(set_attr "type" "mov_reg,mov_imm,mvn_imm,mov_imm,load_4,store_4")
6093 (set_attr "predicable" "yes")
6094 (set_attr "arch" "*,*,*,v6t2,*,*")
6095 (set_attr "pool_range" "*,*,*,*,4096,*")
6096 (set_attr "neg_pool_range" "*,*,*,*,4084,*")]
6097 )
6098
6099 (define_split
6100 [(set (match_operand:SI 0 "arm_general_register_operand" "")
6101 (match_operand:SI 1 "const_int_operand" ""))]
6102 "(TARGET_32BIT || TARGET_HAVE_MOVT)
6103 && (!(const_ok_for_arm (INTVAL (operands[1]))
6104 || const_ok_for_arm (~INTVAL (operands[1]))))"
6105 [(clobber (const_int 0))]
6106 "
6107 arm_split_constant (SET, SImode, NULL_RTX,
6108 INTVAL (operands[1]), operands[0], NULL_RTX, 0);
6109 DONE;
6110 "
6111 )
6112
6113 ;; A normal way to do (symbol + offset) requires three instructions at least
6114 ;; (depends on how big the offset is) as below:
6115 ;; movw r0, #:lower16:g
6116 ;; movw r0, #:upper16:g
6117 ;; adds r0, #4
6118 ;;
6119 ;; A better way would be:
6120 ;; movw r0, #:lower16:g+4
6121 ;; movw r0, #:upper16:g+4
6122 ;;
6123 ;; The limitation of this way is that the length of offset should be a 16-bit
6124 ;; signed value, because current assembler only supports REL type relocation for
6125 ;; such case. If the more powerful RELA type is supported in future, we should
6126 ;; update this pattern to go with better way.
6127 (define_split
6128 [(set (match_operand:SI 0 "arm_general_register_operand" "")
6129 (const:SI (plus:SI (match_operand:SI 1 "general_operand" "")
6130 (match_operand:SI 2 "const_int_operand" ""))))]
6131 "TARGET_THUMB
6132 && TARGET_HAVE_MOVT
6133 && arm_disable_literal_pool
6134 && reload_completed
6135 && GET_CODE (operands[1]) == SYMBOL_REF"
6136 [(clobber (const_int 0))]
6137 "
6138 int offset = INTVAL (operands[2]);
6139
6140 if (offset < -0x8000 || offset > 0x7fff)
6141 {
6142 arm_emit_movpair (operands[0], operands[1]);
6143 emit_insn (gen_rtx_SET (operands[0],
6144 gen_rtx_PLUS (SImode, operands[0], operands[2])));
6145 }
6146 else
6147 {
6148 rtx op = gen_rtx_CONST (SImode,
6149 gen_rtx_PLUS (SImode, operands[1], operands[2]));
6150 arm_emit_movpair (operands[0], op);
6151 }
6152 "
6153 )
6154
6155 ;; Split symbol_refs at the later stage (after cprop), instead of generating
6156 ;; movt/movw pair directly at expand. Otherwise corresponding high_sum
6157 ;; and lo_sum would be merged back into memory load at cprop. However,
6158 ;; if the default is to prefer movt/movw rather than a load from the constant
6159 ;; pool, the performance is better.
6160 (define_split
6161 [(set (match_operand:SI 0 "arm_general_register_operand" "")
6162 (match_operand:SI 1 "general_operand" ""))]
6163 "TARGET_USE_MOVT && GET_CODE (operands[1]) == SYMBOL_REF
6164 && !target_word_relocations
6165 && !arm_tls_referenced_p (operands[1])"
6166 [(clobber (const_int 0))]
6167 {
6168 arm_emit_movpair (operands[0], operands[1]);
6169 DONE;
6170 })
6171
6172 ;; When generating pic, we need to load the symbol offset into a register.
6173 ;; So that the optimizer does not confuse this with a normal symbol load
6174 ;; we use an unspec. The offset will be loaded from a constant pool entry,
6175 ;; since that is the only type of relocation we can use.
6176
6177 ;; Wrap calculation of the whole PIC address in a single pattern for the
6178 ;; benefit of optimizers, particularly, PRE and HOIST. Calculation of
6179 ;; a PIC address involves two loads from memory, so we want to CSE it
6180 ;; as often as possible.
6181 ;; This pattern will be split into one of the pic_load_addr_* patterns
6182 ;; and a move after GCSE optimizations.
6183 ;;
6184 ;; Note: Update arm.c: legitimize_pic_address() when changing this pattern.
6185 (define_expand "calculate_pic_address"
6186 [(set (match_operand:SI 0 "register_operand" "")
6187 (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "")
6188 (unspec:SI [(match_operand:SI 2 "" "")]
6189 UNSPEC_PIC_SYM))))]
6190 "flag_pic"
6191 )
6192
6193 ;; Split calculate_pic_address into pic_load_addr_* and a move.
6194 (define_split
6195 [(set (match_operand:SI 0 "register_operand" "")
6196 (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "")
6197 (unspec:SI [(match_operand:SI 2 "" "")]
6198 UNSPEC_PIC_SYM))))]
6199 "flag_pic"
6200 [(set (match_dup 3) (unspec:SI [(match_dup 2)] UNSPEC_PIC_SYM))
6201 (set (match_dup 0) (mem:SI (plus:SI (match_dup 1) (match_dup 3))))]
6202 "operands[3] = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];"
6203 )
6204
6205 ;; operand1 is the memory address to go into
6206 ;; pic_load_addr_32bit.
6207 ;; operand2 is the PIC label to be emitted
6208 ;; from pic_add_dot_plus_eight.
6209 ;; We do this to allow hoisting of the entire insn.
6210 (define_insn_and_split "pic_load_addr_unified"
6211 [(set (match_operand:SI 0 "s_register_operand" "=r,r,l")
6212 (unspec:SI [(match_operand:SI 1 "" "mX,mX,mX")
6213 (match_operand:SI 2 "" "")]
6214 UNSPEC_PIC_UNIFIED))]
6215 "flag_pic"
6216 "#"
6217 "&& reload_completed"
6218 [(set (match_dup 0) (unspec:SI [(match_dup 1)] UNSPEC_PIC_SYM))
6219 (set (match_dup 0) (unspec:SI [(match_dup 0) (match_dup 3)
6220 (match_dup 2)] UNSPEC_PIC_BASE))]
6221 "operands[3] = TARGET_THUMB ? GEN_INT (4) : GEN_INT (8);"
6222 [(set_attr "type" "load_4,load_4,load_4")
6223 (set_attr "pool_range" "4096,4094,1022")
6224 (set_attr "neg_pool_range" "4084,0,0")
6225 (set_attr "arch" "a,t2,t1")
6226 (set_attr "length" "8,6,4")]
6227 )
6228
6229 ;; The rather odd constraints on the following are to force reload to leave
6230 ;; the insn alone, and to force the minipool generation pass to then move
6231 ;; the GOT symbol to memory.
6232
6233 (define_insn "pic_load_addr_32bit"
6234 [(set (match_operand:SI 0 "s_register_operand" "=r")
6235 (unspec:SI [(match_operand:SI 1 "" "mX")] UNSPEC_PIC_SYM))]
6236 "TARGET_32BIT && flag_pic"
6237 "ldr%?\\t%0, %1"
6238 [(set_attr "type" "load_4")
6239 (set (attr "pool_range")
6240 (if_then_else (eq_attr "is_thumb" "no")
6241 (const_int 4096)
6242 (const_int 4094)))
6243 (set (attr "neg_pool_range")
6244 (if_then_else (eq_attr "is_thumb" "no")
6245 (const_int 4084)
6246 (const_int 0)))]
6247 )
6248
6249 (define_insn "pic_load_addr_thumb1"
6250 [(set (match_operand:SI 0 "s_register_operand" "=l")
6251 (unspec:SI [(match_operand:SI 1 "" "mX")] UNSPEC_PIC_SYM))]
6252 "TARGET_THUMB1 && flag_pic"
6253 "ldr\\t%0, %1"
6254 [(set_attr "type" "load_4")
6255 (set (attr "pool_range") (const_int 1018))]
6256 )
6257
6258 (define_insn "pic_add_dot_plus_four"
6259 [(set (match_operand:SI 0 "register_operand" "=r")
6260 (unspec:SI [(match_operand:SI 1 "register_operand" "0")
6261 (const_int 4)
6262 (match_operand 2 "" "")]
6263 UNSPEC_PIC_BASE))]
6264 "TARGET_THUMB"
6265 "*
6266 (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
6267 INTVAL (operands[2]));
6268 return \"add\\t%0, %|pc\";
6269 "
6270 [(set_attr "length" "2")
6271 (set_attr "type" "alu_sreg")]
6272 )
6273
6274 (define_insn "pic_add_dot_plus_eight"
6275 [(set (match_operand:SI 0 "register_operand" "=r")
6276 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
6277 (const_int 8)
6278 (match_operand 2 "" "")]
6279 UNSPEC_PIC_BASE))]
6280 "TARGET_ARM"
6281 "*
6282 (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
6283 INTVAL (operands[2]));
6284 return \"add%?\\t%0, %|pc, %1\";
6285 "
6286 [(set_attr "predicable" "yes")
6287 (set_attr "type" "alu_sreg")]
6288 )
6289
6290 (define_insn "tls_load_dot_plus_eight"
6291 [(set (match_operand:SI 0 "register_operand" "=r")
6292 (mem:SI (unspec:SI [(match_operand:SI 1 "register_operand" "r")
6293 (const_int 8)
6294 (match_operand 2 "" "")]
6295 UNSPEC_PIC_BASE)))]
6296 "TARGET_ARM"
6297 "*
6298 (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
6299 INTVAL (operands[2]));
6300 return \"ldr%?\\t%0, [%|pc, %1]\t\t@ tls_load_dot_plus_eight\";
6301 "
6302 [(set_attr "predicable" "yes")
6303 (set_attr "type" "load_4")]
6304 )
6305
6306 ;; PIC references to local variables can generate pic_add_dot_plus_eight
6307 ;; followed by a load. These sequences can be crunched down to
6308 ;; tls_load_dot_plus_eight by a peephole.
6309
6310 (define_peephole2
6311 [(set (match_operand:SI 0 "register_operand" "")
6312 (unspec:SI [(match_operand:SI 3 "register_operand" "")
6313 (const_int 8)
6314 (match_operand 1 "" "")]
6315 UNSPEC_PIC_BASE))
6316 (set (match_operand:SI 2 "arm_general_register_operand" "")
6317 (mem:SI (match_dup 0)))]
6318 "TARGET_ARM && peep2_reg_dead_p (2, operands[0])"
6319 [(set (match_dup 2)
6320 (mem:SI (unspec:SI [(match_dup 3)
6321 (const_int 8)
6322 (match_dup 1)]
6323 UNSPEC_PIC_BASE)))]
6324 ""
6325 )
6326
6327 (define_insn "pic_offset_arm"
6328 [(set (match_operand:SI 0 "register_operand" "=r")
6329 (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
6330 (unspec:SI [(match_operand:SI 2 "" "X")]
6331 UNSPEC_PIC_OFFSET))))]
6332 "TARGET_VXWORKS_RTP && TARGET_ARM && flag_pic"
6333 "ldr%?\\t%0, [%1,%2]"
6334 [(set_attr "type" "load_4")]
6335 )
6336
6337 (define_expand "builtin_setjmp_receiver"
6338 [(label_ref (match_operand 0 "" ""))]
6339 "flag_pic"
6340 "
6341 {
6342 /* r3 is clobbered by set/longjmp, so we can use it as a scratch
6343 register. */
6344 if (arm_pic_register != INVALID_REGNUM)
6345 arm_load_pic_register (1UL << 3, NULL_RTX);
6346 DONE;
6347 }")
6348
6349 ;; If copying one reg to another we can set the condition codes according to
6350 ;; its value. Such a move is common after a return from subroutine and the
6351 ;; result is being tested against zero.
6352
6353 (define_insn "*movsi_compare0"
6354 [(set (reg:CC CC_REGNUM)
6355 (compare:CC (match_operand:SI 1 "s_register_operand" "0,r")
6356 (const_int 0)))
6357 (set (match_operand:SI 0 "s_register_operand" "=r,r")
6358 (match_dup 1))]
6359 "TARGET_32BIT"
6360 "@
6361 cmp%?\\t%0, #0
6362 subs%?\\t%0, %1, #0"
6363 [(set_attr "conds" "set")
6364 (set_attr "type" "alus_imm,alus_imm")]
6365 )
6366
6367 ;; Subroutine to store a half word from a register into memory.
6368 ;; Operand 0 is the source register (HImode)
6369 ;; Operand 1 is the destination address in a register (SImode)
6370
6371 ;; In both this routine and the next, we must be careful not to spill
6372 ;; a memory address of reg+large_const into a separate PLUS insn, since this
6373 ;; can generate unrecognizable rtl.
6374
6375 (define_expand "storehi"
6376 [;; store the low byte
6377 (set (match_operand 1 "" "") (match_dup 3))
6378 ;; extract the high byte
6379 (set (match_dup 2)
6380 (ashiftrt:SI (match_operand 0 "" "") (const_int 8)))
6381 ;; store the high byte
6382 (set (match_dup 4) (match_dup 5))]
6383 "TARGET_ARM"
6384 "
6385 {
6386 rtx op1 = operands[1];
6387 rtx addr = XEXP (op1, 0);
6388 enum rtx_code code = GET_CODE (addr);
6389
6390 if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1)))
6391 || code == MINUS)
6392 op1 = replace_equiv_address (operands[1], force_reg (SImode, addr));
6393
6394 operands[4] = adjust_address (op1, QImode, 1);
6395 operands[1] = adjust_address (operands[1], QImode, 0);
6396 operands[3] = gen_lowpart (QImode, operands[0]);
6397 operands[0] = gen_lowpart (SImode, operands[0]);
6398 operands[2] = gen_reg_rtx (SImode);
6399 operands[5] = gen_lowpart (QImode, operands[2]);
6400 }"
6401 )
6402
6403 (define_expand "storehi_bigend"
6404 [(set (match_dup 4) (match_dup 3))
6405 (set (match_dup 2)
6406 (ashiftrt:SI (match_operand 0 "" "") (const_int 8)))
6407 (set (match_operand 1 "" "") (match_dup 5))]
6408 "TARGET_ARM"
6409 "
6410 {
6411 rtx op1 = operands[1];
6412 rtx addr = XEXP (op1, 0);
6413 enum rtx_code code = GET_CODE (addr);
6414
6415 if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1)))
6416 || code == MINUS)
6417 op1 = replace_equiv_address (op1, force_reg (SImode, addr));
6418
6419 operands[4] = adjust_address (op1, QImode, 1);
6420 operands[1] = adjust_address (operands[1], QImode, 0);
6421 operands[3] = gen_lowpart (QImode, operands[0]);
6422 operands[0] = gen_lowpart (SImode, operands[0]);
6423 operands[2] = gen_reg_rtx (SImode);
6424 operands[5] = gen_lowpart (QImode, operands[2]);
6425 }"
6426 )
6427
6428 ;; Subroutine to store a half word integer constant into memory.
6429 (define_expand "storeinthi"
6430 [(set (match_operand 0 "" "")
6431 (match_operand 1 "" ""))
6432 (set (match_dup 3) (match_dup 2))]
6433 "TARGET_ARM"
6434 "
6435 {
6436 HOST_WIDE_INT value = INTVAL (operands[1]);
6437 rtx addr = XEXP (operands[0], 0);
6438 rtx op0 = operands[0];
6439 enum rtx_code code = GET_CODE (addr);
6440
6441 if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1)))
6442 || code == MINUS)
6443 op0 = replace_equiv_address (op0, force_reg (SImode, addr));
6444
6445 operands[1] = gen_reg_rtx (SImode);
6446 if (BYTES_BIG_ENDIAN)
6447 {
6448 emit_insn (gen_movsi (operands[1], GEN_INT ((value >> 8) & 255)));
6449 if ((value & 255) == ((value >> 8) & 255))
6450 operands[2] = operands[1];
6451 else
6452 {
6453 operands[2] = gen_reg_rtx (SImode);
6454 emit_insn (gen_movsi (operands[2], GEN_INT (value & 255)));
6455 }
6456 }
6457 else
6458 {
6459 emit_insn (gen_movsi (operands[1], GEN_INT (value & 255)));
6460 if ((value & 255) == ((value >> 8) & 255))
6461 operands[2] = operands[1];
6462 else
6463 {
6464 operands[2] = gen_reg_rtx (SImode);
6465 emit_insn (gen_movsi (operands[2], GEN_INT ((value >> 8) & 255)));
6466 }
6467 }
6468
6469 operands[3] = adjust_address (op0, QImode, 1);
6470 operands[0] = adjust_address (operands[0], QImode, 0);
6471 operands[2] = gen_lowpart (QImode, operands[2]);
6472 operands[1] = gen_lowpart (QImode, operands[1]);
6473 }"
6474 )
6475
6476 (define_expand "storehi_single_op"
6477 [(set (match_operand:HI 0 "memory_operand" "")
6478 (match_operand:HI 1 "general_operand" ""))]
6479 "TARGET_32BIT && arm_arch4"
6480 "
6481 if (!s_register_operand (operands[1], HImode))
6482 operands[1] = copy_to_mode_reg (HImode, operands[1]);
6483 "
6484 )
6485
6486 (define_expand "movhi"
6487 [(set (match_operand:HI 0 "general_operand" "")
6488 (match_operand:HI 1 "general_operand" ""))]
6489 "TARGET_EITHER"
6490 "
6491 if (TARGET_ARM)
6492 {
6493 if (can_create_pseudo_p ())
6494 {
6495 if (MEM_P (operands[0]))
6496 {
6497 if (arm_arch4)
6498 {
6499 emit_insn (gen_storehi_single_op (operands[0], operands[1]));
6500 DONE;
6501 }
6502 if (CONST_INT_P (operands[1]))
6503 emit_insn (gen_storeinthi (operands[0], operands[1]));
6504 else
6505 {
6506 if (MEM_P (operands[1]))
6507 operands[1] = force_reg (HImode, operands[1]);
6508 if (BYTES_BIG_ENDIAN)
6509 emit_insn (gen_storehi_bigend (operands[1], operands[0]));
6510 else
6511 emit_insn (gen_storehi (operands[1], operands[0]));
6512 }
6513 DONE;
6514 }
6515 /* Sign extend a constant, and keep it in an SImode reg. */
6516 else if (CONST_INT_P (operands[1]))
6517 {
6518 rtx reg = gen_reg_rtx (SImode);
6519 HOST_WIDE_INT val = INTVAL (operands[1]) & 0xffff;
6520
6521 /* If the constant is already valid, leave it alone. */
6522 if (!const_ok_for_arm (val))
6523 {
6524 /* If setting all the top bits will make the constant
6525 loadable in a single instruction, then set them.
6526 Otherwise, sign extend the number. */
6527
6528 if (const_ok_for_arm (~(val | ~0xffff)))
6529 val |= ~0xffff;
6530 else if (val & 0x8000)
6531 val |= ~0xffff;
6532 }
6533
6534 emit_insn (gen_movsi (reg, GEN_INT (val)));
6535 operands[1] = gen_lowpart (HImode, reg);
6536 }
6537 else if (arm_arch4 && optimize && can_create_pseudo_p ()
6538 && MEM_P (operands[1]))
6539 {
6540 rtx reg = gen_reg_rtx (SImode);
6541
6542 emit_insn (gen_zero_extendhisi2 (reg, operands[1]));
6543 operands[1] = gen_lowpart (HImode, reg);
6544 }
6545 else if (!arm_arch4)
6546 {
6547 if (MEM_P (operands[1]))
6548 {
6549 rtx base;
6550 rtx offset = const0_rtx;
6551 rtx reg = gen_reg_rtx (SImode);
6552
6553 if ((REG_P (base = XEXP (operands[1], 0))
6554 || (GET_CODE (base) == PLUS
6555 && (CONST_INT_P (offset = XEXP (base, 1)))
6556 && ((INTVAL(offset) & 1) != 1)
6557 && REG_P (base = XEXP (base, 0))))
6558 && REGNO_POINTER_ALIGN (REGNO (base)) >= 32)
6559 {
6560 rtx new_rtx;
6561
6562 new_rtx = widen_memory_access (operands[1], SImode,
6563 ((INTVAL (offset) & ~3)
6564 - INTVAL (offset)));
6565 emit_insn (gen_movsi (reg, new_rtx));
6566 if (((INTVAL (offset) & 2) != 0)
6567 ^ (BYTES_BIG_ENDIAN ? 1 : 0))
6568 {
6569 rtx reg2 = gen_reg_rtx (SImode);
6570
6571 emit_insn (gen_lshrsi3 (reg2, reg, GEN_INT (16)));
6572 reg = reg2;
6573 }
6574 }
6575 else
6576 emit_insn (gen_movhi_bytes (reg, operands[1]));
6577
6578 operands[1] = gen_lowpart (HImode, reg);
6579 }
6580 }
6581 }
6582 /* Handle loading a large integer during reload. */
6583 else if (CONST_INT_P (operands[1])
6584 && !const_ok_for_arm (INTVAL (operands[1]))
6585 && !const_ok_for_arm (~INTVAL (operands[1])))
6586 {
6587 /* Writing a constant to memory needs a scratch, which should
6588 be handled with SECONDARY_RELOADs. */
6589 gcc_assert (REG_P (operands[0]));
6590
6591 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
6592 emit_insn (gen_movsi (operands[0], operands[1]));
6593 DONE;
6594 }
6595 }
6596 else if (TARGET_THUMB2)
6597 {
6598 /* Thumb-2 can do everything except mem=mem and mem=const easily. */
6599 if (can_create_pseudo_p ())
6600 {
6601 if (!REG_P (operands[0]))
6602 operands[1] = force_reg (HImode, operands[1]);
6603 /* Zero extend a constant, and keep it in an SImode reg. */
6604 else if (CONST_INT_P (operands[1]))
6605 {
6606 rtx reg = gen_reg_rtx (SImode);
6607 HOST_WIDE_INT val = INTVAL (operands[1]) & 0xffff;
6608
6609 emit_insn (gen_movsi (reg, GEN_INT (val)));
6610 operands[1] = gen_lowpart (HImode, reg);
6611 }
6612 }
6613 }
6614 else /* TARGET_THUMB1 */
6615 {
6616 if (can_create_pseudo_p ())
6617 {
6618 if (CONST_INT_P (operands[1]))
6619 {
6620 rtx reg = gen_reg_rtx (SImode);
6621
6622 emit_insn (gen_movsi (reg, operands[1]));
6623 operands[1] = gen_lowpart (HImode, reg);
6624 }
6625
6626 /* ??? We shouldn't really get invalid addresses here, but this can
6627 happen if we are passed a SP (never OK for HImode/QImode) or
6628 virtual register (also rejected as illegitimate for HImode/QImode)
6629 relative address. */
6630 /* ??? This should perhaps be fixed elsewhere, for instance, in
6631 fixup_stack_1, by checking for other kinds of invalid addresses,
6632 e.g. a bare reference to a virtual register. This may confuse the
6633 alpha though, which must handle this case differently. */
6634 if (MEM_P (operands[0])
6635 && !memory_address_p (GET_MODE (operands[0]),
6636 XEXP (operands[0], 0)))
6637 operands[0]
6638 = replace_equiv_address (operands[0],
6639 copy_to_reg (XEXP (operands[0], 0)));
6640
6641 if (MEM_P (operands[1])
6642 && !memory_address_p (GET_MODE (operands[1]),
6643 XEXP (operands[1], 0)))
6644 operands[1]
6645 = replace_equiv_address (operands[1],
6646 copy_to_reg (XEXP (operands[1], 0)));
6647
6648 if (MEM_P (operands[1]) && optimize > 0)
6649 {
6650 rtx reg = gen_reg_rtx (SImode);
6651
6652 emit_insn (gen_zero_extendhisi2 (reg, operands[1]));
6653 operands[1] = gen_lowpart (HImode, reg);
6654 }
6655
6656 if (MEM_P (operands[0]))
6657 operands[1] = force_reg (HImode, operands[1]);
6658 }
6659 else if (CONST_INT_P (operands[1])
6660 && !satisfies_constraint_I (operands[1]))
6661 {
6662 /* Handle loading a large integer during reload. */
6663
6664 /* Writing a constant to memory needs a scratch, which should
6665 be handled with SECONDARY_RELOADs. */
6666 gcc_assert (REG_P (operands[0]));
6667
6668 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
6669 emit_insn (gen_movsi (operands[0], operands[1]));
6670 DONE;
6671 }
6672 }
6673 "
6674 )
6675
6676 (define_expand "movhi_bytes"
6677 [(set (match_dup 2) (zero_extend:SI (match_operand:HI 1 "" "")))
6678 (set (match_dup 3)
6679 (zero_extend:SI (match_dup 6)))
6680 (set (match_operand:SI 0 "" "")
6681 (ior:SI (ashift:SI (match_dup 4) (const_int 8)) (match_dup 5)))]
6682 "TARGET_ARM"
6683 "
6684 {
6685 rtx mem1, mem2;
6686 rtx addr = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
6687
6688 mem1 = change_address (operands[1], QImode, addr);
6689 mem2 = change_address (operands[1], QImode,
6690 plus_constant (Pmode, addr, 1));
6691 operands[0] = gen_lowpart (SImode, operands[0]);
6692 operands[1] = mem1;
6693 operands[2] = gen_reg_rtx (SImode);
6694 operands[3] = gen_reg_rtx (SImode);
6695 operands[6] = mem2;
6696
6697 if (BYTES_BIG_ENDIAN)
6698 {
6699 operands[4] = operands[2];
6700 operands[5] = operands[3];
6701 }
6702 else
6703 {
6704 operands[4] = operands[3];
6705 operands[5] = operands[2];
6706 }
6707 }"
6708 )
6709
6710 (define_expand "movhi_bigend"
6711 [(set (match_dup 2)
6712 (rotate:SI (subreg:SI (match_operand:HI 1 "memory_operand" "") 0)
6713 (const_int 16)))
6714 (set (match_dup 3)
6715 (ashiftrt:SI (match_dup 2) (const_int 16)))
6716 (set (match_operand:HI 0 "s_register_operand" "")
6717 (match_dup 4))]
6718 "TARGET_ARM"
6719 "
6720 operands[2] = gen_reg_rtx (SImode);
6721 operands[3] = gen_reg_rtx (SImode);
6722 operands[4] = gen_lowpart (HImode, operands[3]);
6723 "
6724 )
6725
6726 ;; Pattern to recognize insn generated default case above
6727 (define_insn "*movhi_insn_arch4"
6728 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m,r")
6729 (match_operand:HI 1 "general_operand" "rIk,K,n,r,mi"))]
6730 "TARGET_ARM
6731 && arm_arch4 && !TARGET_HARD_FLOAT
6732 && (register_operand (operands[0], HImode)
6733 || register_operand (operands[1], HImode))"
6734 "@
6735 mov%?\\t%0, %1\\t%@ movhi
6736 mvn%?\\t%0, #%B1\\t%@ movhi
6737 movw%?\\t%0, %L1\\t%@ movhi
6738 strh%?\\t%1, %0\\t%@ movhi
6739 ldrh%?\\t%0, %1\\t%@ movhi"
6740 [(set_attr "predicable" "yes")
6741 (set_attr "pool_range" "*,*,*,*,256")
6742 (set_attr "neg_pool_range" "*,*,*,*,244")
6743 (set_attr "arch" "*,*,v6t2,*,*")
6744 (set_attr_alternative "type"
6745 [(if_then_else (match_operand 1 "const_int_operand" "")
6746 (const_string "mov_imm" )
6747 (const_string "mov_reg"))
6748 (const_string "mvn_imm")
6749 (const_string "mov_imm")
6750 (const_string "store_4")
6751 (const_string "load_4")])]
6752 )
6753
6754 (define_insn "*movhi_bytes"
6755 [(set (match_operand:HI 0 "s_register_operand" "=r,r,r")
6756 (match_operand:HI 1 "arm_rhs_operand" "I,rk,K"))]
6757 "TARGET_ARM && !TARGET_HARD_FLOAT"
6758 "@
6759 mov%?\\t%0, %1\\t%@ movhi
6760 mov%?\\t%0, %1\\t%@ movhi
6761 mvn%?\\t%0, #%B1\\t%@ movhi"
6762 [(set_attr "predicable" "yes")
6763 (set_attr "type" "mov_imm,mov_reg,mvn_imm")]
6764 )
6765
6766 ;; We use a DImode scratch because we may occasionally need an additional
6767 ;; temporary if the address isn't offsettable -- push_reload doesn't seem
6768 ;; to take any notice of the "o" constraints on reload_memory_operand operand.
6769 (define_expand "reload_outhi"
6770 [(parallel [(match_operand:HI 0 "arm_reload_memory_operand" "=o")
6771 (match_operand:HI 1 "s_register_operand" "r")
6772 (match_operand:DI 2 "s_register_operand" "=&l")])]
6773 "TARGET_EITHER"
6774 "if (TARGET_ARM)
6775 arm_reload_out_hi (operands);
6776 else
6777 thumb_reload_out_hi (operands);
6778 DONE;
6779 "
6780 )
6781
6782 (define_expand "reload_inhi"
6783 [(parallel [(match_operand:HI 0 "s_register_operand" "=r")
6784 (match_operand:HI 1 "arm_reload_memory_operand" "o")
6785 (match_operand:DI 2 "s_register_operand" "=&r")])]
6786 "TARGET_EITHER"
6787 "
6788 if (TARGET_ARM)
6789 arm_reload_in_hi (operands);
6790 else
6791 thumb_reload_out_hi (operands);
6792 DONE;
6793 ")
6794
6795 (define_expand "movqi"
6796 [(set (match_operand:QI 0 "general_operand" "")
6797 (match_operand:QI 1 "general_operand" ""))]
6798 "TARGET_EITHER"
6799 "
6800 /* Everything except mem = const or mem = mem can be done easily */
6801
6802 if (can_create_pseudo_p ())
6803 {
6804 if (CONST_INT_P (operands[1]))
6805 {
6806 rtx reg = gen_reg_rtx (SImode);
6807
6808 /* For thumb we want an unsigned immediate, then we are more likely
6809 to be able to use a movs insn. */
6810 if (TARGET_THUMB)
6811 operands[1] = GEN_INT (INTVAL (operands[1]) & 255);
6812
6813 emit_insn (gen_movsi (reg, operands[1]));
6814 operands[1] = gen_lowpart (QImode, reg);
6815 }
6816
6817 if (TARGET_THUMB)
6818 {
6819 /* ??? We shouldn't really get invalid addresses here, but this can
6820 happen if we are passed a SP (never OK for HImode/QImode) or
6821 virtual register (also rejected as illegitimate for HImode/QImode)
6822 relative address. */
6823 /* ??? This should perhaps be fixed elsewhere, for instance, in
6824 fixup_stack_1, by checking for other kinds of invalid addresses,
6825 e.g. a bare reference to a virtual register. This may confuse the
6826 alpha though, which must handle this case differently. */
6827 if (MEM_P (operands[0])
6828 && !memory_address_p (GET_MODE (operands[0]),
6829 XEXP (operands[0], 0)))
6830 operands[0]
6831 = replace_equiv_address (operands[0],
6832 copy_to_reg (XEXP (operands[0], 0)));
6833 if (MEM_P (operands[1])
6834 && !memory_address_p (GET_MODE (operands[1]),
6835 XEXP (operands[1], 0)))
6836 operands[1]
6837 = replace_equiv_address (operands[1],
6838 copy_to_reg (XEXP (operands[1], 0)));
6839 }
6840
6841 if (MEM_P (operands[1]) && optimize > 0)
6842 {
6843 rtx reg = gen_reg_rtx (SImode);
6844
6845 emit_insn (gen_zero_extendqisi2 (reg, operands[1]));
6846 operands[1] = gen_lowpart (QImode, reg);
6847 }
6848
6849 if (MEM_P (operands[0]))
6850 operands[1] = force_reg (QImode, operands[1]);
6851 }
6852 else if (TARGET_THUMB
6853 && CONST_INT_P (operands[1])
6854 && !satisfies_constraint_I (operands[1]))
6855 {
6856 /* Handle loading a large integer during reload. */
6857
6858 /* Writing a constant to memory needs a scratch, which should
6859 be handled with SECONDARY_RELOADs. */
6860 gcc_assert (REG_P (operands[0]));
6861
6862 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
6863 emit_insn (gen_movsi (operands[0], operands[1]));
6864 DONE;
6865 }
6866 "
6867 )
6868
6869 (define_insn "*arm_movqi_insn"
6870 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,r,l,r,l,Uu,r,m")
6871 (match_operand:QI 1 "general_operand" "rk,rk,I,Py,K,Uu,l,Uh,r"))]
6872 "TARGET_32BIT
6873 && ( register_operand (operands[0], QImode)
6874 || register_operand (operands[1], QImode))"
6875 "@
6876 mov%?\\t%0, %1
6877 mov%?\\t%0, %1
6878 mov%?\\t%0, %1
6879 mov%?\\t%0, %1
6880 mvn%?\\t%0, #%B1
6881 ldrb%?\\t%0, %1
6882 strb%?\\t%1, %0
6883 ldrb%?\\t%0, %1
6884 strb%?\\t%1, %0"
6885 [(set_attr "type" "mov_reg,mov_reg,mov_imm,mov_imm,mvn_imm,load_4,store_4,load_4,store_4")
6886 (set_attr "predicable" "yes")
6887 (set_attr "predicable_short_it" "yes,yes,no,yes,no,no,no,no,no")
6888 (set_attr "arch" "t2,any,any,t2,any,t2,t2,any,any")
6889 (set_attr "length" "2,4,4,2,4,2,2,4,4")]
6890 )
6891
6892 ;; HFmode moves
6893 (define_expand "movhf"
6894 [(set (match_operand:HF 0 "general_operand" "")
6895 (match_operand:HF 1 "general_operand" ""))]
6896 "TARGET_EITHER"
6897 "
6898 if (TARGET_32BIT)
6899 {
6900 if (MEM_P (operands[0]))
6901 operands[1] = force_reg (HFmode, operands[1]);
6902 }
6903 else /* TARGET_THUMB1 */
6904 {
6905 if (can_create_pseudo_p ())
6906 {
6907 if (!REG_P (operands[0]))
6908 operands[1] = force_reg (HFmode, operands[1]);
6909 }
6910 }
6911 "
6912 )
6913
6914 (define_insn "*arm32_movhf"
6915 [(set (match_operand:HF 0 "nonimmediate_operand" "=r,m,r,r")
6916 (match_operand:HF 1 "general_operand" " m,r,r,F"))]
6917 "TARGET_32BIT && !TARGET_HARD_FLOAT
6918 && ( s_register_operand (operands[0], HFmode)
6919 || s_register_operand (operands[1], HFmode))"
6920 "*
6921 switch (which_alternative)
6922 {
6923 case 0: /* ARM register from memory */
6924 return \"ldrh%?\\t%0, %1\\t%@ __fp16\";
6925 case 1: /* memory from ARM register */
6926 return \"strh%?\\t%1, %0\\t%@ __fp16\";
6927 case 2: /* ARM register from ARM register */
6928 return \"mov%?\\t%0, %1\\t%@ __fp16\";
6929 case 3: /* ARM register from constant */
6930 {
6931 long bits;
6932 rtx ops[4];
6933
6934 bits = real_to_target (NULL, CONST_DOUBLE_REAL_VALUE (operands[1]),
6935 HFmode);
6936 ops[0] = operands[0];
6937 ops[1] = GEN_INT (bits);
6938 ops[2] = GEN_INT (bits & 0xff00);
6939 ops[3] = GEN_INT (bits & 0x00ff);
6940
6941 if (arm_arch_thumb2)
6942 output_asm_insn (\"movw%?\\t%0, %1\", ops);
6943 else
6944 output_asm_insn (\"mov%?\\t%0, %2\;orr%?\\t%0, %0, %3\", ops);
6945 return \"\";
6946 }
6947 default:
6948 gcc_unreachable ();
6949 }
6950 "
6951 [(set_attr "conds" "unconditional")
6952 (set_attr "type" "load_4,store_4,mov_reg,multiple")
6953 (set_attr "length" "4,4,4,8")
6954 (set_attr "predicable" "yes")]
6955 )
6956
6957 (define_expand "movsf"
6958 [(set (match_operand:SF 0 "general_operand" "")
6959 (match_operand:SF 1 "general_operand" ""))]
6960 "TARGET_EITHER"
6961 "
6962 if (TARGET_32BIT)
6963 {
6964 if (MEM_P (operands[0]))
6965 operands[1] = force_reg (SFmode, operands[1]);
6966 }
6967 else /* TARGET_THUMB1 */
6968 {
6969 if (can_create_pseudo_p ())
6970 {
6971 if (!REG_P (operands[0]))
6972 operands[1] = force_reg (SFmode, operands[1]);
6973 }
6974 }
6975
6976 /* Cannot load it directly, generate a load with clobber so that it can be
6977 loaded via GPR with MOV / MOVT. */
6978 if (arm_disable_literal_pool
6979 && (REG_P (operands[0]) || SUBREG_P (operands[0]))
6980 && CONST_DOUBLE_P (operands[1])
6981 && TARGET_HARD_FLOAT
6982 && !vfp3_const_double_rtx (operands[1]))
6983 {
6984 rtx clobreg = gen_reg_rtx (SFmode);
6985 emit_insn (gen_no_literal_pool_sf_immediate (operands[0], operands[1],
6986 clobreg));
6987 DONE;
6988 }
6989 "
6990 )
6991
6992 ;; Transform a floating-point move of a constant into a core register into
6993 ;; an SImode operation.
6994 (define_split
6995 [(set (match_operand:SF 0 "arm_general_register_operand" "")
6996 (match_operand:SF 1 "immediate_operand" ""))]
6997 "TARGET_EITHER
6998 && reload_completed
6999 && CONST_DOUBLE_P (operands[1])"
7000 [(set (match_dup 2) (match_dup 3))]
7001 "
7002 operands[2] = gen_lowpart (SImode, operands[0]);
7003 operands[3] = gen_lowpart (SImode, operands[1]);
7004 if (operands[2] == 0 || operands[3] == 0)
7005 FAIL;
7006 "
7007 )
7008
7009 (define_insn "*arm_movsf_soft_insn"
7010 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,m")
7011 (match_operand:SF 1 "general_operand" "r,mE,r"))]
7012 "TARGET_32BIT
7013 && TARGET_SOFT_FLOAT
7014 && (!MEM_P (operands[0])
7015 || register_operand (operands[1], SFmode))"
7016 {
7017 switch (which_alternative)
7018 {
7019 case 0: return \"mov%?\\t%0, %1\";
7020 case 1:
7021 /* Cannot load it directly, split to load it via MOV / MOVT. */
7022 if (!MEM_P (operands[1]) && arm_disable_literal_pool)
7023 return \"#\";
7024 return \"ldr%?\\t%0, %1\\t%@ float\";
7025 case 2: return \"str%?\\t%1, %0\\t%@ float\";
7026 default: gcc_unreachable ();
7027 }
7028 }
7029 [(set_attr "predicable" "yes")
7030 (set_attr "type" "mov_reg,load_4,store_4")
7031 (set_attr "arm_pool_range" "*,4096,*")
7032 (set_attr "thumb2_pool_range" "*,4094,*")
7033 (set_attr "arm_neg_pool_range" "*,4084,*")
7034 (set_attr "thumb2_neg_pool_range" "*,0,*")]
7035 )
7036
7037 ;; Splitter for the above.
7038 (define_split
7039 [(set (match_operand:SF 0 "s_register_operand")
7040 (match_operand:SF 1 "const_double_operand"))]
7041 "arm_disable_literal_pool && TARGET_SOFT_FLOAT"
7042 [(const_int 0)]
7043 {
7044 long buf;
7045 real_to_target (&buf, CONST_DOUBLE_REAL_VALUE (operands[1]), SFmode);
7046 rtx cst = gen_int_mode (buf, SImode);
7047 emit_move_insn (simplify_gen_subreg (SImode, operands[0], SFmode, 0), cst);
7048 DONE;
7049 }
7050 )
7051
7052 (define_expand "movdf"
7053 [(set (match_operand:DF 0 "general_operand" "")
7054 (match_operand:DF 1 "general_operand" ""))]
7055 "TARGET_EITHER"
7056 "
7057 if (TARGET_32BIT)
7058 {
7059 if (MEM_P (operands[0]))
7060 operands[1] = force_reg (DFmode, operands[1]);
7061 }
7062 else /* TARGET_THUMB */
7063 {
7064 if (can_create_pseudo_p ())
7065 {
7066 if (!REG_P (operands[0]))
7067 operands[1] = force_reg (DFmode, operands[1]);
7068 }
7069 }
7070
7071 /* Cannot load it directly, generate a load with clobber so that it can be
7072 loaded via GPR with MOV / MOVT. */
7073 if (arm_disable_literal_pool
7074 && (REG_P (operands[0]) || SUBREG_P (operands[0]))
7075 && CONSTANT_P (operands[1])
7076 && TARGET_HARD_FLOAT
7077 && !arm_const_double_rtx (operands[1])
7078 && !(TARGET_VFP_DOUBLE && vfp3_const_double_rtx (operands[1])))
7079 {
7080 rtx clobreg = gen_reg_rtx (DFmode);
7081 emit_insn (gen_no_literal_pool_df_immediate (operands[0], operands[1],
7082 clobreg));
7083 DONE;
7084 }
7085 "
7086 )
7087
7088 ;; Reloading a df mode value stored in integer regs to memory can require a
7089 ;; scratch reg.
7090 (define_expand "reload_outdf"
7091 [(match_operand:DF 0 "arm_reload_memory_operand" "=o")
7092 (match_operand:DF 1 "s_register_operand" "r")
7093 (match_operand:SI 2 "s_register_operand" "=&r")]
7094 "TARGET_THUMB2"
7095 "
7096 {
7097 enum rtx_code code = GET_CODE (XEXP (operands[0], 0));
7098
7099 if (code == REG)
7100 operands[2] = XEXP (operands[0], 0);
7101 else if (code == POST_INC || code == PRE_DEC)
7102 {
7103 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7104 operands[1] = gen_rtx_SUBREG (DImode, operands[1], 0);
7105 emit_insn (gen_movdi (operands[0], operands[1]));
7106 DONE;
7107 }
7108 else if (code == PRE_INC)
7109 {
7110 rtx reg = XEXP (XEXP (operands[0], 0), 0);
7111
7112 emit_insn (gen_addsi3 (reg, reg, GEN_INT (8)));
7113 operands[2] = reg;
7114 }
7115 else if (code == POST_DEC)
7116 operands[2] = XEXP (XEXP (operands[0], 0), 0);
7117 else
7118 emit_insn (gen_addsi3 (operands[2], XEXP (XEXP (operands[0], 0), 0),
7119 XEXP (XEXP (operands[0], 0), 1)));
7120
7121 emit_insn (gen_rtx_SET (replace_equiv_address (operands[0], operands[2]),
7122 operands[1]));
7123
7124 if (code == POST_DEC)
7125 emit_insn (gen_addsi3 (operands[2], operands[2], GEN_INT (-8)));
7126
7127 DONE;
7128 }"
7129 )
7130
7131 (define_insn "*movdf_soft_insn"
7132 [(set (match_operand:DF 0 "nonimmediate_soft_df_operand" "=r,r,r,r,m")
7133 (match_operand:DF 1 "soft_df_operand" "rDa,Db,Dc,mF,r"))]
7134 "TARGET_32BIT && TARGET_SOFT_FLOAT
7135 && ( register_operand (operands[0], DFmode)
7136 || register_operand (operands[1], DFmode))"
7137 "*
7138 switch (which_alternative)
7139 {
7140 case 0:
7141 case 1:
7142 case 2:
7143 return \"#\";
7144 case 3:
7145 /* Cannot load it directly, split to load it via MOV / MOVT. */
7146 if (!MEM_P (operands[1]) && arm_disable_literal_pool)
7147 return \"#\";
7148 /* Fall through. */
7149 default:
7150 return output_move_double (operands, true, NULL);
7151 }
7152 "
7153 [(set_attr "length" "8,12,16,8,8")
7154 (set_attr "type" "multiple,multiple,multiple,load_8,store_8")
7155 (set_attr "arm_pool_range" "*,*,*,1020,*")
7156 (set_attr "thumb2_pool_range" "*,*,*,1018,*")
7157 (set_attr "arm_neg_pool_range" "*,*,*,1004,*")
7158 (set_attr "thumb2_neg_pool_range" "*,*,*,0,*")]
7159 )
7160
7161 ;; Splitter for the above.
7162 (define_split
7163 [(set (match_operand:DF 0 "s_register_operand")
7164 (match_operand:DF 1 "const_double_operand"))]
7165 "arm_disable_literal_pool && TARGET_SOFT_FLOAT"
7166 [(const_int 0)]
7167 {
7168 long buf[2];
7169 int order = BYTES_BIG_ENDIAN ? 1 : 0;
7170 real_to_target (buf, CONST_DOUBLE_REAL_VALUE (operands[1]), DFmode);
7171 unsigned HOST_WIDE_INT ival = zext_hwi (buf[order], 32);
7172 ival |= (zext_hwi (buf[1 - order], 32) << 32);
7173 rtx cst = gen_int_mode (ival, DImode);
7174 emit_move_insn (simplify_gen_subreg (DImode, operands[0], DFmode, 0), cst);
7175 DONE;
7176 }
7177 )
7178 \f
7179
7180 ;; load- and store-multiple insns
7181 ;; The arm can load/store any set of registers, provided that they are in
7182 ;; ascending order, but these expanders assume a contiguous set.
7183
7184 (define_expand "load_multiple"
7185 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
7186 (match_operand:SI 1 "" ""))
7187 (use (match_operand:SI 2 "" ""))])]
7188 "TARGET_32BIT"
7189 {
7190 HOST_WIDE_INT offset = 0;
7191
7192 /* Support only fixed point registers. */
7193 if (!CONST_INT_P (operands[2])
7194 || INTVAL (operands[2]) > MAX_LDM_STM_OPS
7195 || INTVAL (operands[2]) < 2
7196 || !MEM_P (operands[1])
7197 || !REG_P (operands[0])
7198 || REGNO (operands[0]) > (LAST_ARM_REGNUM - 1)
7199 || REGNO (operands[0]) + INTVAL (operands[2]) > LAST_ARM_REGNUM)
7200 FAIL;
7201
7202 operands[3]
7203 = arm_gen_load_multiple (arm_regs_in_sequence + REGNO (operands[0]),
7204 INTVAL (operands[2]),
7205 force_reg (SImode, XEXP (operands[1], 0)),
7206 FALSE, operands[1], &offset);
7207 })
7208
7209 (define_expand "store_multiple"
7210 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
7211 (match_operand:SI 1 "" ""))
7212 (use (match_operand:SI 2 "" ""))])]
7213 "TARGET_32BIT"
7214 {
7215 HOST_WIDE_INT offset = 0;
7216
7217 /* Support only fixed point registers. */
7218 if (!CONST_INT_P (operands[2])
7219 || INTVAL (operands[2]) > MAX_LDM_STM_OPS
7220 || INTVAL (operands[2]) < 2
7221 || !REG_P (operands[1])
7222 || !MEM_P (operands[0])
7223 || REGNO (operands[1]) > (LAST_ARM_REGNUM - 1)
7224 || REGNO (operands[1]) + INTVAL (operands[2]) > LAST_ARM_REGNUM)
7225 FAIL;
7226
7227 operands[3]
7228 = arm_gen_store_multiple (arm_regs_in_sequence + REGNO (operands[1]),
7229 INTVAL (operands[2]),
7230 force_reg (SImode, XEXP (operands[0], 0)),
7231 FALSE, operands[0], &offset);
7232 })
7233
7234
7235 (define_expand "setmemsi"
7236 [(match_operand:BLK 0 "general_operand" "")
7237 (match_operand:SI 1 "const_int_operand" "")
7238 (match_operand:SI 2 "const_int_operand" "")
7239 (match_operand:SI 3 "const_int_operand" "")]
7240 "TARGET_32BIT"
7241 {
7242 if (arm_gen_setmem (operands))
7243 DONE;
7244
7245 FAIL;
7246 })
7247
7248
7249 ;; Move a block of memory if it is word aligned and MORE than 2 words long.
7250 ;; We could let this apply for blocks of less than this, but it clobbers so
7251 ;; many registers that there is then probably a better way.
7252
7253 (define_expand "cpymemqi"
7254 [(match_operand:BLK 0 "general_operand" "")
7255 (match_operand:BLK 1 "general_operand" "")
7256 (match_operand:SI 2 "const_int_operand" "")
7257 (match_operand:SI 3 "const_int_operand" "")]
7258 ""
7259 "
7260 if (TARGET_32BIT)
7261 {
7262 if (TARGET_LDRD && current_tune->prefer_ldrd_strd
7263 && !optimize_function_for_size_p (cfun))
7264 {
7265 if (gen_cpymem_ldrd_strd (operands))
7266 DONE;
7267 FAIL;
7268 }
7269
7270 if (arm_gen_cpymemqi (operands))
7271 DONE;
7272 FAIL;
7273 }
7274 else /* TARGET_THUMB1 */
7275 {
7276 if ( INTVAL (operands[3]) != 4
7277 || INTVAL (operands[2]) > 48)
7278 FAIL;
7279
7280 thumb_expand_cpymemqi (operands);
7281 DONE;
7282 }
7283 "
7284 )
7285 \f
7286
7287 ;; Compare & branch insns
7288 ;; The range calculations are based as follows:
7289 ;; For forward branches, the address calculation returns the address of
7290 ;; the next instruction. This is 2 beyond the branch instruction.
7291 ;; For backward branches, the address calculation returns the address of
7292 ;; the first instruction in this pattern (cmp). This is 2 before the branch
7293 ;; instruction for the shortest sequence, and 4 before the branch instruction
7294 ;; if we have to jump around an unconditional branch.
7295 ;; To the basic branch range the PC offset must be added (this is +4).
7296 ;; So for forward branches we have
7297 ;; (pos_range - pos_base_offs + pc_offs) = (pos_range - 2 + 4).
7298 ;; And for backward branches we have
7299 ;; (neg_range - neg_base_offs + pc_offs) = (neg_range - (-2 or -4) + 4).
7300 ;;
7301 ;; For a 'b' pos_range = 2046, neg_range = -2048 giving (-2040->2048).
7302 ;; For a 'b<cond>' pos_range = 254, neg_range = -256 giving (-250 ->256).
7303
7304 (define_expand "cbranchsi4"
7305 [(set (pc) (if_then_else
7306 (match_operator 0 "expandable_comparison_operator"
7307 [(match_operand:SI 1 "s_register_operand" "")
7308 (match_operand:SI 2 "nonmemory_operand" "")])
7309 (label_ref (match_operand 3 "" ""))
7310 (pc)))]
7311 "TARGET_EITHER"
7312 "
7313 if (!TARGET_THUMB1)
7314 {
7315 if (!arm_validize_comparison (&operands[0], &operands[1], &operands[2]))
7316 FAIL;
7317 emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
7318 operands[3]));
7319 DONE;
7320 }
7321 if (thumb1_cmpneg_operand (operands[2], SImode))
7322 {
7323 emit_jump_insn (gen_cbranchsi4_scratch (NULL, operands[1], operands[2],
7324 operands[3], operands[0]));
7325 DONE;
7326 }
7327 if (!thumb1_cmp_operand (operands[2], SImode))
7328 operands[2] = force_reg (SImode, operands[2]);
7329 ")
7330
7331 (define_expand "cbranchsf4"
7332 [(set (pc) (if_then_else
7333 (match_operator 0 "expandable_comparison_operator"
7334 [(match_operand:SF 1 "s_register_operand" "")
7335 (match_operand:SF 2 "vfp_compare_operand" "")])
7336 (label_ref (match_operand 3 "" ""))
7337 (pc)))]
7338 "TARGET_32BIT && TARGET_HARD_FLOAT"
7339 "emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
7340 operands[3])); DONE;"
7341 )
7342
7343 (define_expand "cbranchdf4"
7344 [(set (pc) (if_then_else
7345 (match_operator 0 "expandable_comparison_operator"
7346 [(match_operand:DF 1 "s_register_operand" "")
7347 (match_operand:DF 2 "vfp_compare_operand" "")])
7348 (label_ref (match_operand 3 "" ""))
7349 (pc)))]
7350 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
7351 "emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
7352 operands[3])); DONE;"
7353 )
7354
7355 (define_expand "cbranchdi4"
7356 [(set (pc) (if_then_else
7357 (match_operator 0 "expandable_comparison_operator"
7358 [(match_operand:DI 1 "s_register_operand" "")
7359 (match_operand:DI 2 "cmpdi_operand" "")])
7360 (label_ref (match_operand 3 "" ""))
7361 (pc)))]
7362 "TARGET_32BIT"
7363 "{
7364 if (!arm_validize_comparison (&operands[0], &operands[1], &operands[2]))
7365 FAIL;
7366 emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
7367 operands[3]));
7368 DONE;
7369 }"
7370 )
7371
7372 ;; Comparison and test insns
7373
7374 (define_insn "*arm_cmpsi_insn"
7375 [(set (reg:CC CC_REGNUM)
7376 (compare:CC (match_operand:SI 0 "s_register_operand" "l,r,r,r,r")
7377 (match_operand:SI 1 "arm_add_operand" "Py,r,r,I,L")))]
7378 "TARGET_32BIT"
7379 "@
7380 cmp%?\\t%0, %1
7381 cmp%?\\t%0, %1
7382 cmp%?\\t%0, %1
7383 cmp%?\\t%0, %1
7384 cmn%?\\t%0, #%n1"
7385 [(set_attr "conds" "set")
7386 (set_attr "arch" "t2,t2,any,any,any")
7387 (set_attr "length" "2,2,4,4,4")
7388 (set_attr "predicable" "yes")
7389 (set_attr "predicable_short_it" "yes,yes,yes,no,no")
7390 (set_attr "type" "alus_imm,alus_sreg,alus_sreg,alus_imm,alus_imm")]
7391 )
7392
7393 (define_insn "*cmpsi_shiftsi"
7394 [(set (reg:CC CC_REGNUM)
7395 (compare:CC (match_operand:SI 0 "s_register_operand" "r,r,r")
7396 (match_operator:SI 3 "shift_operator"
7397 [(match_operand:SI 1 "s_register_operand" "r,r,r")
7398 (match_operand:SI 2 "shift_amount_operand" "M,r,M")])))]
7399 "TARGET_32BIT"
7400 "cmp\\t%0, %1%S3"
7401 [(set_attr "conds" "set")
7402 (set_attr "shift" "1")
7403 (set_attr "arch" "32,a,a")
7404 (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
7405
7406 (define_insn "*cmpsi_shiftsi_swp"
7407 [(set (reg:CC_SWP CC_REGNUM)
7408 (compare:CC_SWP (match_operator:SI 3 "shift_operator"
7409 [(match_operand:SI 1 "s_register_operand" "r,r,r")
7410 (match_operand:SI 2 "shift_amount_operand" "M,r,M")])
7411 (match_operand:SI 0 "s_register_operand" "r,r,r")))]
7412 "TARGET_32BIT"
7413 "cmp%?\\t%0, %1%S3"
7414 [(set_attr "conds" "set")
7415 (set_attr "shift" "1")
7416 (set_attr "arch" "32,a,a")
7417 (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
7418
7419 (define_insn "*arm_cmpsi_negshiftsi_si"
7420 [(set (reg:CC_Z CC_REGNUM)
7421 (compare:CC_Z
7422 (neg:SI (match_operator:SI 1 "shift_operator"
7423 [(match_operand:SI 2 "s_register_operand" "r")
7424 (match_operand:SI 3 "reg_or_int_operand" "rM")]))
7425 (match_operand:SI 0 "s_register_operand" "r")))]
7426 "TARGET_ARM"
7427 "cmn%?\\t%0, %2%S1"
7428 [(set_attr "conds" "set")
7429 (set (attr "type") (if_then_else (match_operand 3 "const_int_operand" "")
7430 (const_string "alus_shift_imm")
7431 (const_string "alus_shift_reg")))
7432 (set_attr "predicable" "yes")]
7433 )
7434
7435 ;; DImode comparisons. The generic code generates branches that
7436 ;; if-conversion cannot reduce to a conditional compare, so we do
7437 ;; that directly.
7438
7439 (define_insn_and_split "*arm_cmpdi_insn"
7440 [(set (reg:CC_NCV CC_REGNUM)
7441 (compare:CC_NCV (match_operand:DI 0 "s_register_operand" "r")
7442 (match_operand:DI 1 "arm_di_operand" "rDi")))
7443 (clobber (match_scratch:SI 2 "=r"))]
7444 "TARGET_32BIT"
7445 "#" ; "cmp\\t%Q0, %Q1\;sbcs\\t%2, %R0, %R1"
7446 "&& reload_completed"
7447 [(set (reg:CC CC_REGNUM)
7448 (compare:CC (match_dup 0) (match_dup 1)))
7449 (parallel [(set (reg:CC CC_REGNUM)
7450 (compare:CC (match_dup 3) (match_dup 4)))
7451 (set (match_dup 2)
7452 (minus:SI (match_dup 5)
7453 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))])]
7454 {
7455 operands[3] = gen_highpart (SImode, operands[0]);
7456 operands[0] = gen_lowpart (SImode, operands[0]);
7457 if (CONST_INT_P (operands[1]))
7458 {
7459 operands[4] = gen_highpart_mode (SImode, DImode, operands[1]);
7460 if (operands[4] == const0_rtx)
7461 operands[5] = operands[3];
7462 else
7463 operands[5] = gen_rtx_PLUS (SImode, operands[3],
7464 gen_int_mode (-UINTVAL (operands[4]),
7465 SImode));
7466 }
7467 else
7468 {
7469 operands[4] = gen_highpart (SImode, operands[1]);
7470 operands[5] = gen_rtx_MINUS (SImode, operands[3], operands[4]);
7471 }
7472 operands[1] = gen_lowpart (SImode, operands[1]);
7473 operands[2] = gen_lowpart (SImode, operands[2]);
7474 }
7475 [(set_attr "conds" "set")
7476 (set_attr "length" "8")
7477 (set_attr "type" "multiple")]
7478 )
7479
7480 (define_insn_and_split "*arm_cmpdi_unsigned"
7481 [(set (reg:CC_CZ CC_REGNUM)
7482 (compare:CC_CZ (match_operand:DI 0 "s_register_operand" "l,r,r,r")
7483 (match_operand:DI 1 "arm_di_operand" "Py,r,Di,rDi")))]
7484
7485 "TARGET_32BIT"
7486 "#" ; "cmp\\t%R0, %R1\;it eq\;cmpeq\\t%Q0, %Q1"
7487 "&& reload_completed"
7488 [(set (reg:CC CC_REGNUM)
7489 (compare:CC (match_dup 2) (match_dup 3)))
7490 (cond_exec (eq:SI (reg:CC CC_REGNUM) (const_int 0))
7491 (set (reg:CC CC_REGNUM)
7492 (compare:CC (match_dup 0) (match_dup 1))))]
7493 {
7494 operands[2] = gen_highpart (SImode, operands[0]);
7495 operands[0] = gen_lowpart (SImode, operands[0]);
7496 if (CONST_INT_P (operands[1]))
7497 operands[3] = gen_highpart_mode (SImode, DImode, operands[1]);
7498 else
7499 operands[3] = gen_highpart (SImode, operands[1]);
7500 operands[1] = gen_lowpart (SImode, operands[1]);
7501 }
7502 [(set_attr "conds" "set")
7503 (set_attr "enabled_for_short_it" "yes,yes,no,*")
7504 (set_attr "arch" "t2,t2,t2,a")
7505 (set_attr "length" "6,6,10,8")
7506 (set_attr "type" "multiple")]
7507 )
7508
7509 (define_insn "*arm_cmpdi_zero"
7510 [(set (reg:CC_Z CC_REGNUM)
7511 (compare:CC_Z (match_operand:DI 0 "s_register_operand" "r")
7512 (const_int 0)))
7513 (clobber (match_scratch:SI 1 "=r"))]
7514 "TARGET_32BIT"
7515 "orrs%?\\t%1, %Q0, %R0"
7516 [(set_attr "conds" "set")
7517 (set_attr "type" "logics_reg")]
7518 )
7519
7520 ; This insn allows redundant compares to be removed by cse, nothing should
7521 ; ever appear in the output file since (set (reg x) (reg x)) is a no-op that
7522 ; is deleted later on. The match_dup will match the mode here, so that
7523 ; mode changes of the condition codes aren't lost by this even though we don't
7524 ; specify what they are.
7525
7526 (define_insn "*deleted_compare"
7527 [(set (match_operand 0 "cc_register" "") (match_dup 0))]
7528 "TARGET_32BIT"
7529 "\\t%@ deleted compare"
7530 [(set_attr "conds" "set")
7531 (set_attr "length" "0")
7532 (set_attr "type" "no_insn")]
7533 )
7534
7535 \f
7536 ;; Conditional branch insns
7537
7538 (define_expand "cbranch_cc"
7539 [(set (pc)
7540 (if_then_else (match_operator 0 "" [(match_operand 1 "" "")
7541 (match_operand 2 "" "")])
7542 (label_ref (match_operand 3 "" ""))
7543 (pc)))]
7544 "TARGET_32BIT"
7545 "operands[1] = arm_gen_compare_reg (GET_CODE (operands[0]),
7546 operands[1], operands[2], NULL_RTX);
7547 operands[2] = const0_rtx;"
7548 )
7549
7550 ;;
7551 ;; Patterns to match conditional branch insns.
7552 ;;
7553
7554 (define_insn "arm_cond_branch"
7555 [(set (pc)
7556 (if_then_else (match_operator 1 "arm_comparison_operator"
7557 [(match_operand 2 "cc_register" "") (const_int 0)])
7558 (label_ref (match_operand 0 "" ""))
7559 (pc)))]
7560 "TARGET_32BIT"
7561 "*
7562 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
7563 {
7564 arm_ccfsm_state += 2;
7565 return \"\";
7566 }
7567 return \"b%d1\\t%l0\";
7568 "
7569 [(set_attr "conds" "use")
7570 (set_attr "type" "branch")
7571 (set (attr "length")
7572 (if_then_else
7573 (and (match_test "TARGET_THUMB2")
7574 (and (ge (minus (match_dup 0) (pc)) (const_int -250))
7575 (le (minus (match_dup 0) (pc)) (const_int 256))))
7576 (const_int 2)
7577 (const_int 4)))]
7578 )
7579
7580 (define_insn "*arm_cond_branch_reversed"
7581 [(set (pc)
7582 (if_then_else (match_operator 1 "arm_comparison_operator"
7583 [(match_operand 2 "cc_register" "") (const_int 0)])
7584 (pc)
7585 (label_ref (match_operand 0 "" ""))))]
7586 "TARGET_32BIT"
7587 "*
7588 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
7589 {
7590 arm_ccfsm_state += 2;
7591 return \"\";
7592 }
7593 return \"b%D1\\t%l0\";
7594 "
7595 [(set_attr "conds" "use")
7596 (set_attr "type" "branch")
7597 (set (attr "length")
7598 (if_then_else
7599 (and (match_test "TARGET_THUMB2")
7600 (and (ge (minus (match_dup 0) (pc)) (const_int -250))
7601 (le (minus (match_dup 0) (pc)) (const_int 256))))
7602 (const_int 2)
7603 (const_int 4)))]
7604 )
7605
7606 \f
7607
7608 ; scc insns
7609
7610 (define_expand "cstore_cc"
7611 [(set (match_operand:SI 0 "s_register_operand" "")
7612 (match_operator:SI 1 "" [(match_operand 2 "" "")
7613 (match_operand 3 "" "")]))]
7614 "TARGET_32BIT"
7615 "operands[2] = arm_gen_compare_reg (GET_CODE (operands[1]),
7616 operands[2], operands[3], NULL_RTX);
7617 operands[3] = const0_rtx;"
7618 )
7619
7620 (define_insn_and_split "*mov_scc"
7621 [(set (match_operand:SI 0 "s_register_operand" "=r")
7622 (match_operator:SI 1 "arm_comparison_operator_mode"
7623 [(match_operand 2 "cc_register" "") (const_int 0)]))]
7624 "TARGET_ARM"
7625 "#" ; "mov%D1\\t%0, #0\;mov%d1\\t%0, #1"
7626 "TARGET_ARM"
7627 [(set (match_dup 0)
7628 (if_then_else:SI (match_dup 1)
7629 (const_int 1)
7630 (const_int 0)))]
7631 ""
7632 [(set_attr "conds" "use")
7633 (set_attr "length" "8")
7634 (set_attr "type" "multiple")]
7635 )
7636
7637 (define_insn_and_split "*mov_negscc"
7638 [(set (match_operand:SI 0 "s_register_operand" "=r")
7639 (neg:SI (match_operator:SI 1 "arm_comparison_operator_mode"
7640 [(match_operand 2 "cc_register" "") (const_int 0)])))]
7641 "TARGET_ARM"
7642 "#" ; "mov%D1\\t%0, #0\;mvn%d1\\t%0, #0"
7643 "TARGET_ARM"
7644 [(set (match_dup 0)
7645 (if_then_else:SI (match_dup 1)
7646 (match_dup 3)
7647 (const_int 0)))]
7648 {
7649 operands[3] = GEN_INT (~0);
7650 }
7651 [(set_attr "conds" "use")
7652 (set_attr "length" "8")
7653 (set_attr "type" "multiple")]
7654 )
7655
7656 (define_insn_and_split "*mov_notscc"
7657 [(set (match_operand:SI 0 "s_register_operand" "=r")
7658 (not:SI (match_operator:SI 1 "arm_comparison_operator"
7659 [(match_operand 2 "cc_register" "") (const_int 0)])))]
7660 "TARGET_ARM"
7661 "#" ; "mvn%D1\\t%0, #0\;mvn%d1\\t%0, #1"
7662 "TARGET_ARM"
7663 [(set (match_dup 0)
7664 (if_then_else:SI (match_dup 1)
7665 (match_dup 3)
7666 (match_dup 4)))]
7667 {
7668 operands[3] = GEN_INT (~1);
7669 operands[4] = GEN_INT (~0);
7670 }
7671 [(set_attr "conds" "use")
7672 (set_attr "length" "8")
7673 (set_attr "type" "multiple")]
7674 )
7675
7676 (define_expand "cstoresi4"
7677 [(set (match_operand:SI 0 "s_register_operand" "")
7678 (match_operator:SI 1 "expandable_comparison_operator"
7679 [(match_operand:SI 2 "s_register_operand" "")
7680 (match_operand:SI 3 "reg_or_int_operand" "")]))]
7681 "TARGET_32BIT || TARGET_THUMB1"
7682 "{
7683 rtx op3, scratch, scratch2;
7684
7685 if (!TARGET_THUMB1)
7686 {
7687 if (!arm_add_operand (operands[3], SImode))
7688 operands[3] = force_reg (SImode, operands[3]);
7689 emit_insn (gen_cstore_cc (operands[0], operands[1],
7690 operands[2], operands[3]));
7691 DONE;
7692 }
7693
7694 if (operands[3] == const0_rtx)
7695 {
7696 switch (GET_CODE (operands[1]))
7697 {
7698 case EQ:
7699 emit_insn (gen_cstoresi_eq0_thumb1 (operands[0], operands[2]));
7700 break;
7701
7702 case NE:
7703 emit_insn (gen_cstoresi_ne0_thumb1 (operands[0], operands[2]));
7704 break;
7705
7706 case LE:
7707 scratch = expand_binop (SImode, add_optab, operands[2], constm1_rtx,
7708 NULL_RTX, 0, OPTAB_WIDEN);
7709 scratch = expand_binop (SImode, ior_optab, operands[2], scratch,
7710 NULL_RTX, 0, OPTAB_WIDEN);
7711 expand_binop (SImode, lshr_optab, scratch, GEN_INT (31),
7712 operands[0], 1, OPTAB_WIDEN);
7713 break;
7714
7715 case GE:
7716 scratch = expand_unop (SImode, one_cmpl_optab, operands[2],
7717 NULL_RTX, 1);
7718 expand_binop (SImode, lshr_optab, scratch, GEN_INT (31),
7719 NULL_RTX, 1, OPTAB_WIDEN);
7720 break;
7721
7722 case GT:
7723 scratch = expand_binop (SImode, ashr_optab, operands[2],
7724 GEN_INT (31), NULL_RTX, 0, OPTAB_WIDEN);
7725 scratch = expand_binop (SImode, sub_optab, scratch, operands[2],
7726 NULL_RTX, 0, OPTAB_WIDEN);
7727 expand_binop (SImode, lshr_optab, scratch, GEN_INT (31), operands[0],
7728 0, OPTAB_WIDEN);
7729 break;
7730
7731 /* LT is handled by generic code. No need for unsigned with 0. */
7732 default:
7733 FAIL;
7734 }
7735 DONE;
7736 }
7737
7738 switch (GET_CODE (operands[1]))
7739 {
7740 case EQ:
7741 scratch = expand_binop (SImode, sub_optab, operands[2], operands[3],
7742 NULL_RTX, 0, OPTAB_WIDEN);
7743 emit_insn (gen_cstoresi_eq0_thumb1 (operands[0], scratch));
7744 break;
7745
7746 case NE:
7747 scratch = expand_binop (SImode, sub_optab, operands[2], operands[3],
7748 NULL_RTX, 0, OPTAB_WIDEN);
7749 emit_insn (gen_cstoresi_ne0_thumb1 (operands[0], scratch));
7750 break;
7751
7752 case LE:
7753 op3 = force_reg (SImode, operands[3]);
7754
7755 scratch = expand_binop (SImode, lshr_optab, operands[2], GEN_INT (31),
7756 NULL_RTX, 1, OPTAB_WIDEN);
7757 scratch2 = expand_binop (SImode, ashr_optab, op3, GEN_INT (31),
7758 NULL_RTX, 0, OPTAB_WIDEN);
7759 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch2,
7760 op3, operands[2]));
7761 break;
7762
7763 case GE:
7764 op3 = operands[3];
7765 if (!thumb1_cmp_operand (op3, SImode))
7766 op3 = force_reg (SImode, op3);
7767 scratch = expand_binop (SImode, ashr_optab, operands[2], GEN_INT (31),
7768 NULL_RTX, 0, OPTAB_WIDEN);
7769 scratch2 = expand_binop (SImode, lshr_optab, op3, GEN_INT (31),
7770 NULL_RTX, 1, OPTAB_WIDEN);
7771 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch2,
7772 operands[2], op3));
7773 break;
7774
7775 case LEU:
7776 op3 = force_reg (SImode, operands[3]);
7777 scratch = force_reg (SImode, const0_rtx);
7778 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch,
7779 op3, operands[2]));
7780 break;
7781
7782 case GEU:
7783 op3 = operands[3];
7784 if (!thumb1_cmp_operand (op3, SImode))
7785 op3 = force_reg (SImode, op3);
7786 scratch = force_reg (SImode, const0_rtx);
7787 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch,
7788 operands[2], op3));
7789 break;
7790
7791 case LTU:
7792 op3 = operands[3];
7793 if (!thumb1_cmp_operand (op3, SImode))
7794 op3 = force_reg (SImode, op3);
7795 scratch = gen_reg_rtx (SImode);
7796 emit_insn (gen_cstoresi_ltu_thumb1 (operands[0], operands[2], op3));
7797 break;
7798
7799 case GTU:
7800 op3 = force_reg (SImode, operands[3]);
7801 scratch = gen_reg_rtx (SImode);
7802 emit_insn (gen_cstoresi_ltu_thumb1 (operands[0], op3, operands[2]));
7803 break;
7804
7805 /* No good sequences for GT, LT. */
7806 default:
7807 FAIL;
7808 }
7809 DONE;
7810 }")
7811
7812 (define_expand "cstorehf4"
7813 [(set (match_operand:SI 0 "s_register_operand")
7814 (match_operator:SI 1 "expandable_comparison_operator"
7815 [(match_operand:HF 2 "s_register_operand")
7816 (match_operand:HF 3 "vfp_compare_operand")]))]
7817 "TARGET_VFP_FP16INST"
7818 {
7819 if (!arm_validize_comparison (&operands[1],
7820 &operands[2],
7821 &operands[3]))
7822 FAIL;
7823
7824 emit_insn (gen_cstore_cc (operands[0], operands[1],
7825 operands[2], operands[3]));
7826 DONE;
7827 }
7828 )
7829
7830 (define_expand "cstoresf4"
7831 [(set (match_operand:SI 0 "s_register_operand" "")
7832 (match_operator:SI 1 "expandable_comparison_operator"
7833 [(match_operand:SF 2 "s_register_operand" "")
7834 (match_operand:SF 3 "vfp_compare_operand" "")]))]
7835 "TARGET_32BIT && TARGET_HARD_FLOAT"
7836 "emit_insn (gen_cstore_cc (operands[0], operands[1],
7837 operands[2], operands[3])); DONE;"
7838 )
7839
7840 (define_expand "cstoredf4"
7841 [(set (match_operand:SI 0 "s_register_operand" "")
7842 (match_operator:SI 1 "expandable_comparison_operator"
7843 [(match_operand:DF 2 "s_register_operand" "")
7844 (match_operand:DF 3 "vfp_compare_operand" "")]))]
7845 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
7846 "emit_insn (gen_cstore_cc (operands[0], operands[1],
7847 operands[2], operands[3])); DONE;"
7848 )
7849
7850 (define_expand "cstoredi4"
7851 [(set (match_operand:SI 0 "s_register_operand" "")
7852 (match_operator:SI 1 "expandable_comparison_operator"
7853 [(match_operand:DI 2 "s_register_operand" "")
7854 (match_operand:DI 3 "cmpdi_operand" "")]))]
7855 "TARGET_32BIT"
7856 "{
7857 if (!arm_validize_comparison (&operands[1],
7858 &operands[2],
7859 &operands[3]))
7860 FAIL;
7861 emit_insn (gen_cstore_cc (operands[0], operands[1], operands[2],
7862 operands[3]));
7863 DONE;
7864 }"
7865 )
7866
7867 \f
7868 ;; Conditional move insns
7869
7870 (define_expand "movsicc"
7871 [(set (match_operand:SI 0 "s_register_operand" "")
7872 (if_then_else:SI (match_operand 1 "expandable_comparison_operator" "")
7873 (match_operand:SI 2 "arm_not_operand" "")
7874 (match_operand:SI 3 "arm_not_operand" "")))]
7875 "TARGET_32BIT"
7876 "
7877 {
7878 enum rtx_code code;
7879 rtx ccreg;
7880
7881 if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
7882 &XEXP (operands[1], 1)))
7883 FAIL;
7884
7885 code = GET_CODE (operands[1]);
7886 ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
7887 XEXP (operands[1], 1), NULL_RTX);
7888 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7889 }"
7890 )
7891
7892 (define_expand "movhfcc"
7893 [(set (match_operand:HF 0 "s_register_operand")
7894 (if_then_else:HF (match_operand 1 "arm_cond_move_operator")
7895 (match_operand:HF 2 "s_register_operand")
7896 (match_operand:HF 3 "s_register_operand")))]
7897 "TARGET_VFP_FP16INST"
7898 "
7899 {
7900 enum rtx_code code = GET_CODE (operands[1]);
7901 rtx ccreg;
7902
7903 if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
7904 &XEXP (operands[1], 1)))
7905 FAIL;
7906
7907 code = GET_CODE (operands[1]);
7908 ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
7909 XEXP (operands[1], 1), NULL_RTX);
7910 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7911 }"
7912 )
7913
7914 (define_expand "movsfcc"
7915 [(set (match_operand:SF 0 "s_register_operand" "")
7916 (if_then_else:SF (match_operand 1 "arm_cond_move_operator" "")
7917 (match_operand:SF 2 "s_register_operand" "")
7918 (match_operand:SF 3 "s_register_operand" "")))]
7919 "TARGET_32BIT && TARGET_HARD_FLOAT"
7920 "
7921 {
7922 enum rtx_code code = GET_CODE (operands[1]);
7923 rtx ccreg;
7924
7925 if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
7926 &XEXP (operands[1], 1)))
7927 FAIL;
7928
7929 code = GET_CODE (operands[1]);
7930 ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
7931 XEXP (operands[1], 1), NULL_RTX);
7932 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7933 }"
7934 )
7935
7936 (define_expand "movdfcc"
7937 [(set (match_operand:DF 0 "s_register_operand" "")
7938 (if_then_else:DF (match_operand 1 "arm_cond_move_operator" "")
7939 (match_operand:DF 2 "s_register_operand" "")
7940 (match_operand:DF 3 "s_register_operand" "")))]
7941 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
7942 "
7943 {
7944 enum rtx_code code = GET_CODE (operands[1]);
7945 rtx ccreg;
7946
7947 if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
7948 &XEXP (operands[1], 1)))
7949 FAIL;
7950 code = GET_CODE (operands[1]);
7951 ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
7952 XEXP (operands[1], 1), NULL_RTX);
7953 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7954 }"
7955 )
7956
7957 (define_insn "*cmov<mode>"
7958 [(set (match_operand:SDF 0 "s_register_operand" "=<F_constraint>")
7959 (if_then_else:SDF (match_operator 1 "arm_vsel_comparison_operator"
7960 [(match_operand 2 "cc_register" "") (const_int 0)])
7961 (match_operand:SDF 3 "s_register_operand"
7962 "<F_constraint>")
7963 (match_operand:SDF 4 "s_register_operand"
7964 "<F_constraint>")))]
7965 "TARGET_HARD_FLOAT && TARGET_VFP5 <vfp_double_cond>"
7966 "*
7967 {
7968 enum arm_cond_code code = maybe_get_arm_condition_code (operands[1]);
7969 switch (code)
7970 {
7971 case ARM_GE:
7972 case ARM_GT:
7973 case ARM_EQ:
7974 case ARM_VS:
7975 return \"vsel%d1.<V_if_elem>\\t%<V_reg>0, %<V_reg>3, %<V_reg>4\";
7976 case ARM_LT:
7977 case ARM_LE:
7978 case ARM_NE:
7979 case ARM_VC:
7980 return \"vsel%D1.<V_if_elem>\\t%<V_reg>0, %<V_reg>4, %<V_reg>3\";
7981 default:
7982 gcc_unreachable ();
7983 }
7984 return \"\";
7985 }"
7986 [(set_attr "conds" "use")
7987 (set_attr "type" "fcsel")]
7988 )
7989
7990 (define_insn "*cmovhf"
7991 [(set (match_operand:HF 0 "s_register_operand" "=t")
7992 (if_then_else:HF (match_operator 1 "arm_vsel_comparison_operator"
7993 [(match_operand 2 "cc_register" "") (const_int 0)])
7994 (match_operand:HF 3 "s_register_operand" "t")
7995 (match_operand:HF 4 "s_register_operand" "t")))]
7996 "TARGET_VFP_FP16INST"
7997 "*
7998 {
7999 enum arm_cond_code code = maybe_get_arm_condition_code (operands[1]);
8000 switch (code)
8001 {
8002 case ARM_GE:
8003 case ARM_GT:
8004 case ARM_EQ:
8005 case ARM_VS:
8006 return \"vsel%d1.f16\\t%0, %3, %4\";
8007 case ARM_LT:
8008 case ARM_LE:
8009 case ARM_NE:
8010 case ARM_VC:
8011 return \"vsel%D1.f16\\t%0, %4, %3\";
8012 default:
8013 gcc_unreachable ();
8014 }
8015 return \"\";
8016 }"
8017 [(set_attr "conds" "use")
8018 (set_attr "type" "fcsel")]
8019 )
8020
8021 (define_insn_and_split "*movsicc_insn"
8022 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r,r,r,r,r")
8023 (if_then_else:SI
8024 (match_operator 3 "arm_comparison_operator"
8025 [(match_operand 4 "cc_register" "") (const_int 0)])
8026 (match_operand:SI 1 "arm_not_operand" "0,0,rI,K,rI,rI,K,K")
8027 (match_operand:SI 2 "arm_not_operand" "rI,K,0,0,rI,K,rI,K")))]
8028 "TARGET_ARM"
8029 "@
8030 mov%D3\\t%0, %2
8031 mvn%D3\\t%0, #%B2
8032 mov%d3\\t%0, %1
8033 mvn%d3\\t%0, #%B1
8034 #
8035 #
8036 #
8037 #"
8038 ; alt4: mov%d3\\t%0, %1\;mov%D3\\t%0, %2
8039 ; alt5: mov%d3\\t%0, %1\;mvn%D3\\t%0, #%B2
8040 ; alt6: mvn%d3\\t%0, #%B1\;mov%D3\\t%0, %2
8041 ; alt7: mvn%d3\\t%0, #%B1\;mvn%D3\\t%0, #%B2"
8042 "&& reload_completed"
8043 [(const_int 0)]
8044 {
8045 enum rtx_code rev_code;
8046 machine_mode mode;
8047 rtx rev_cond;
8048
8049 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
8050 operands[3],
8051 gen_rtx_SET (operands[0], operands[1])));
8052
8053 rev_code = GET_CODE (operands[3]);
8054 mode = GET_MODE (operands[4]);
8055 if (mode == CCFPmode || mode == CCFPEmode)
8056 rev_code = reverse_condition_maybe_unordered (rev_code);
8057 else
8058 rev_code = reverse_condition (rev_code);
8059
8060 rev_cond = gen_rtx_fmt_ee (rev_code,
8061 VOIDmode,
8062 operands[4],
8063 const0_rtx);
8064 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
8065 rev_cond,
8066 gen_rtx_SET (operands[0], operands[2])));
8067 DONE;
8068 }
8069 [(set_attr "length" "4,4,4,4,8,8,8,8")
8070 (set_attr "conds" "use")
8071 (set_attr_alternative "type"
8072 [(if_then_else (match_operand 2 "const_int_operand" "")
8073 (const_string "mov_imm")
8074 (const_string "mov_reg"))
8075 (const_string "mvn_imm")
8076 (if_then_else (match_operand 1 "const_int_operand" "")
8077 (const_string "mov_imm")
8078 (const_string "mov_reg"))
8079 (const_string "mvn_imm")
8080 (const_string "multiple")
8081 (const_string "multiple")
8082 (const_string "multiple")
8083 (const_string "multiple")])]
8084 )
8085
8086 (define_insn "*movsfcc_soft_insn"
8087 [(set (match_operand:SF 0 "s_register_operand" "=r,r")
8088 (if_then_else:SF (match_operator 3 "arm_comparison_operator"
8089 [(match_operand 4 "cc_register" "") (const_int 0)])
8090 (match_operand:SF 1 "s_register_operand" "0,r")
8091 (match_operand:SF 2 "s_register_operand" "r,0")))]
8092 "TARGET_ARM && TARGET_SOFT_FLOAT"
8093 "@
8094 mov%D3\\t%0, %2
8095 mov%d3\\t%0, %1"
8096 [(set_attr "conds" "use")
8097 (set_attr "type" "mov_reg")]
8098 )
8099
8100 \f
8101 ;; Jump and linkage insns
8102
8103 (define_expand "jump"
8104 [(set (pc)
8105 (label_ref (match_operand 0 "" "")))]
8106 "TARGET_EITHER"
8107 ""
8108 )
8109
8110 (define_insn "*arm_jump"
8111 [(set (pc)
8112 (label_ref (match_operand 0 "" "")))]
8113 "TARGET_32BIT"
8114 "*
8115 {
8116 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
8117 {
8118 arm_ccfsm_state += 2;
8119 return \"\";
8120 }
8121 return \"b%?\\t%l0\";
8122 }
8123 "
8124 [(set_attr "predicable" "yes")
8125 (set (attr "length")
8126 (if_then_else
8127 (and (match_test "TARGET_THUMB2")
8128 (and (ge (minus (match_dup 0) (pc)) (const_int -2044))
8129 (le (minus (match_dup 0) (pc)) (const_int 2048))))
8130 (const_int 2)
8131 (const_int 4)))
8132 (set_attr "type" "branch")]
8133 )
8134
8135 (define_expand "call"
8136 [(parallel [(call (match_operand 0 "memory_operand" "")
8137 (match_operand 1 "general_operand" ""))
8138 (use (match_operand 2 "" ""))
8139 (clobber (reg:SI LR_REGNUM))])]
8140 "TARGET_EITHER"
8141 "
8142 {
8143 rtx callee, pat;
8144 tree addr = MEM_EXPR (operands[0]);
8145
8146 /* In an untyped call, we can get NULL for operand 2. */
8147 if (operands[2] == NULL_RTX)
8148 operands[2] = const0_rtx;
8149
8150 /* Decide if we should generate indirect calls by loading the
8151 32-bit address of the callee into a register before performing the
8152 branch and link. */
8153 callee = XEXP (operands[0], 0);
8154 if (GET_CODE (callee) == SYMBOL_REF
8155 ? arm_is_long_call_p (SYMBOL_REF_DECL (callee))
8156 : !REG_P (callee))
8157 XEXP (operands[0], 0) = force_reg (Pmode, callee);
8158
8159 if (detect_cmse_nonsecure_call (addr))
8160 {
8161 pat = gen_nonsecure_call_internal (operands[0], operands[1],
8162 operands[2]);
8163 emit_call_insn (pat);
8164 }
8165 else
8166 {
8167 pat = gen_call_internal (operands[0], operands[1], operands[2]);
8168 arm_emit_call_insn (pat, XEXP (operands[0], 0), false);
8169 }
8170 DONE;
8171 }"
8172 )
8173
8174 (define_expand "call_internal"
8175 [(parallel [(call (match_operand 0 "memory_operand" "")
8176 (match_operand 1 "general_operand" ""))
8177 (use (match_operand 2 "" ""))
8178 (clobber (reg:SI LR_REGNUM))])])
8179
8180 (define_expand "nonsecure_call_internal"
8181 [(parallel [(call (unspec:SI [(match_operand 0 "memory_operand" "")]
8182 UNSPEC_NONSECURE_MEM)
8183 (match_operand 1 "general_operand" ""))
8184 (use (match_operand 2 "" ""))
8185 (clobber (reg:SI LR_REGNUM))])]
8186 "use_cmse"
8187 "
8188 {
8189 rtx tmp;
8190 tmp = copy_to_suggested_reg (XEXP (operands[0], 0),
8191 gen_rtx_REG (SImode, R4_REGNUM),
8192 SImode);
8193
8194 operands[0] = replace_equiv_address (operands[0], tmp);
8195 }")
8196
8197 (define_insn "*call_reg_armv5"
8198 [(call (mem:SI (match_operand:SI 0 "s_register_operand" "r"))
8199 (match_operand 1 "" ""))
8200 (use (match_operand 2 "" ""))
8201 (clobber (reg:SI LR_REGNUM))]
8202 "TARGET_ARM && arm_arch5t && !SIBLING_CALL_P (insn)"
8203 "blx%?\\t%0"
8204 [(set_attr "type" "call")]
8205 )
8206
8207 (define_insn "*call_reg_arm"
8208 [(call (mem:SI (match_operand:SI 0 "s_register_operand" "r"))
8209 (match_operand 1 "" ""))
8210 (use (match_operand 2 "" ""))
8211 (clobber (reg:SI LR_REGNUM))]
8212 "TARGET_ARM && !arm_arch5t && !SIBLING_CALL_P (insn)"
8213 "*
8214 return output_call (operands);
8215 "
8216 ;; length is worst case, normally it is only two
8217 [(set_attr "length" "12")
8218 (set_attr "type" "call")]
8219 )
8220
8221
8222 (define_expand "call_value"
8223 [(parallel [(set (match_operand 0 "" "")
8224 (call (match_operand 1 "memory_operand" "")
8225 (match_operand 2 "general_operand" "")))
8226 (use (match_operand 3 "" ""))
8227 (clobber (reg:SI LR_REGNUM))])]
8228 "TARGET_EITHER"
8229 "
8230 {
8231 rtx pat, callee;
8232 tree addr = MEM_EXPR (operands[1]);
8233
8234 /* In an untyped call, we can get NULL for operand 2. */
8235 if (operands[3] == 0)
8236 operands[3] = const0_rtx;
8237
8238 /* Decide if we should generate indirect calls by loading the
8239 32-bit address of the callee into a register before performing the
8240 branch and link. */
8241 callee = XEXP (operands[1], 0);
8242 if (GET_CODE (callee) == SYMBOL_REF
8243 ? arm_is_long_call_p (SYMBOL_REF_DECL (callee))
8244 : !REG_P (callee))
8245 XEXP (operands[1], 0) = force_reg (Pmode, callee);
8246
8247 if (detect_cmse_nonsecure_call (addr))
8248 {
8249 pat = gen_nonsecure_call_value_internal (operands[0], operands[1],
8250 operands[2], operands[3]);
8251 emit_call_insn (pat);
8252 }
8253 else
8254 {
8255 pat = gen_call_value_internal (operands[0], operands[1],
8256 operands[2], operands[3]);
8257 arm_emit_call_insn (pat, XEXP (operands[1], 0), false);
8258 }
8259 DONE;
8260 }"
8261 )
8262
8263 (define_expand "call_value_internal"
8264 [(parallel [(set (match_operand 0 "" "")
8265 (call (match_operand 1 "memory_operand" "")
8266 (match_operand 2 "general_operand" "")))
8267 (use (match_operand 3 "" ""))
8268 (clobber (reg:SI LR_REGNUM))])])
8269
8270 (define_expand "nonsecure_call_value_internal"
8271 [(parallel [(set (match_operand 0 "" "")
8272 (call (unspec:SI [(match_operand 1 "memory_operand" "")]
8273 UNSPEC_NONSECURE_MEM)
8274 (match_operand 2 "general_operand" "")))
8275 (use (match_operand 3 "" ""))
8276 (clobber (reg:SI LR_REGNUM))])]
8277 "use_cmse"
8278 "
8279 {
8280 rtx tmp;
8281 tmp = copy_to_suggested_reg (XEXP (operands[1], 0),
8282 gen_rtx_REG (SImode, R4_REGNUM),
8283 SImode);
8284
8285 operands[1] = replace_equiv_address (operands[1], tmp);
8286 }")
8287
8288 (define_insn "*call_value_reg_armv5"
8289 [(set (match_operand 0 "" "")
8290 (call (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
8291 (match_operand 2 "" "")))
8292 (use (match_operand 3 "" ""))
8293 (clobber (reg:SI LR_REGNUM))]
8294 "TARGET_ARM && arm_arch5t && !SIBLING_CALL_P (insn)"
8295 "blx%?\\t%1"
8296 [(set_attr "type" "call")]
8297 )
8298
8299 (define_insn "*call_value_reg_arm"
8300 [(set (match_operand 0 "" "")
8301 (call (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
8302 (match_operand 2 "" "")))
8303 (use (match_operand 3 "" ""))
8304 (clobber (reg:SI LR_REGNUM))]
8305 "TARGET_ARM && !arm_arch5t && !SIBLING_CALL_P (insn)"
8306 "*
8307 return output_call (&operands[1]);
8308 "
8309 [(set_attr "length" "12")
8310 (set_attr "type" "call")]
8311 )
8312
8313 ;; Allow calls to SYMBOL_REFs specially as they are not valid general addresses
8314 ;; The 'a' causes the operand to be treated as an address, i.e. no '#' output.
8315
8316 (define_insn "*call_symbol"
8317 [(call (mem:SI (match_operand:SI 0 "" ""))
8318 (match_operand 1 "" ""))
8319 (use (match_operand 2 "" ""))
8320 (clobber (reg:SI LR_REGNUM))]
8321 "TARGET_32BIT
8322 && !SIBLING_CALL_P (insn)
8323 && (GET_CODE (operands[0]) == SYMBOL_REF)
8324 && !arm_is_long_call_p (SYMBOL_REF_DECL (operands[0]))"
8325 "*
8326 {
8327 rtx op = operands[0];
8328
8329 /* Switch mode now when possible. */
8330 if (SYMBOL_REF_DECL (op) && !TREE_PUBLIC (SYMBOL_REF_DECL (op))
8331 && arm_arch5t && arm_change_mode_p (SYMBOL_REF_DECL (op)))
8332 return NEED_PLT_RELOC ? \"blx%?\\t%a0(PLT)\" : \"blx%?\\t(%a0)\";
8333
8334 return NEED_PLT_RELOC ? \"bl%?\\t%a0(PLT)\" : \"bl%?\\t%a0\";
8335 }"
8336 [(set_attr "type" "call")]
8337 )
8338
8339 (define_insn "*call_value_symbol"
8340 [(set (match_operand 0 "" "")
8341 (call (mem:SI (match_operand:SI 1 "" ""))
8342 (match_operand:SI 2 "" "")))
8343 (use (match_operand 3 "" ""))
8344 (clobber (reg:SI LR_REGNUM))]
8345 "TARGET_32BIT
8346 && !SIBLING_CALL_P (insn)
8347 && (GET_CODE (operands[1]) == SYMBOL_REF)
8348 && !arm_is_long_call_p (SYMBOL_REF_DECL (operands[1]))"
8349 "*
8350 {
8351 rtx op = operands[1];
8352
8353 /* Switch mode now when possible. */
8354 if (SYMBOL_REF_DECL (op) && !TREE_PUBLIC (SYMBOL_REF_DECL (op))
8355 && arm_arch5t && arm_change_mode_p (SYMBOL_REF_DECL (op)))
8356 return NEED_PLT_RELOC ? \"blx%?\\t%a1(PLT)\" : \"blx%?\\t(%a1)\";
8357
8358 return NEED_PLT_RELOC ? \"bl%?\\t%a1(PLT)\" : \"bl%?\\t%a1\";
8359 }"
8360 [(set_attr "type" "call")]
8361 )
8362
8363 (define_expand "sibcall_internal"
8364 [(parallel [(call (match_operand 0 "memory_operand" "")
8365 (match_operand 1 "general_operand" ""))
8366 (return)
8367 (use (match_operand 2 "" ""))])])
8368
8369 ;; We may also be able to do sibcalls for Thumb, but it's much harder...
8370 (define_expand "sibcall"
8371 [(parallel [(call (match_operand 0 "memory_operand" "")
8372 (match_operand 1 "general_operand" ""))
8373 (return)
8374 (use (match_operand 2 "" ""))])]
8375 "TARGET_32BIT"
8376 "
8377 {
8378 rtx pat;
8379
8380 if ((!REG_P (XEXP (operands[0], 0))
8381 && GET_CODE (XEXP (operands[0], 0)) != SYMBOL_REF)
8382 || (GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
8383 && arm_is_long_call_p (SYMBOL_REF_DECL (XEXP (operands[0], 0)))))
8384 XEXP (operands[0], 0) = force_reg (SImode, XEXP (operands[0], 0));
8385
8386 if (operands[2] == NULL_RTX)
8387 operands[2] = const0_rtx;
8388
8389 pat = gen_sibcall_internal (operands[0], operands[1], operands[2]);
8390 arm_emit_call_insn (pat, operands[0], true);
8391 DONE;
8392 }"
8393 )
8394
8395 (define_expand "sibcall_value_internal"
8396 [(parallel [(set (match_operand 0 "" "")
8397 (call (match_operand 1 "memory_operand" "")
8398 (match_operand 2 "general_operand" "")))
8399 (return)
8400 (use (match_operand 3 "" ""))])])
8401
8402 (define_expand "sibcall_value"
8403 [(parallel [(set (match_operand 0 "" "")
8404 (call (match_operand 1 "memory_operand" "")
8405 (match_operand 2 "general_operand" "")))
8406 (return)
8407 (use (match_operand 3 "" ""))])]
8408 "TARGET_32BIT"
8409 "
8410 {
8411 rtx pat;
8412
8413 if ((!REG_P (XEXP (operands[1], 0))
8414 && GET_CODE (XEXP (operands[1], 0)) != SYMBOL_REF)
8415 || (GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
8416 && arm_is_long_call_p (SYMBOL_REF_DECL (XEXP (operands[1], 0)))))
8417 XEXP (operands[1], 0) = force_reg (SImode, XEXP (operands[1], 0));
8418
8419 if (operands[3] == NULL_RTX)
8420 operands[3] = const0_rtx;
8421
8422 pat = gen_sibcall_value_internal (operands[0], operands[1],
8423 operands[2], operands[3]);
8424 arm_emit_call_insn (pat, operands[1], true);
8425 DONE;
8426 }"
8427 )
8428
8429 (define_insn "*sibcall_insn"
8430 [(call (mem:SI (match_operand:SI 0 "call_insn_operand" "Cs, US"))
8431 (match_operand 1 "" ""))
8432 (return)
8433 (use (match_operand 2 "" ""))]
8434 "TARGET_32BIT && SIBLING_CALL_P (insn)"
8435 "*
8436 if (which_alternative == 1)
8437 return NEED_PLT_RELOC ? \"b%?\\t%a0(PLT)\" : \"b%?\\t%a0\";
8438 else
8439 {
8440 if (arm_arch5t || arm_arch4t)
8441 return \"bx%?\\t%0\\t%@ indirect register sibling call\";
8442 else
8443 return \"mov%?\\t%|pc, %0\\t%@ indirect register sibling call\";
8444 }
8445 "
8446 [(set_attr "type" "call")]
8447 )
8448
8449 (define_insn "*sibcall_value_insn"
8450 [(set (match_operand 0 "" "")
8451 (call (mem:SI (match_operand:SI 1 "call_insn_operand" "Cs,US"))
8452 (match_operand 2 "" "")))
8453 (return)
8454 (use (match_operand 3 "" ""))]
8455 "TARGET_32BIT && SIBLING_CALL_P (insn)"
8456 "*
8457 if (which_alternative == 1)
8458 return NEED_PLT_RELOC ? \"b%?\\t%a1(PLT)\" : \"b%?\\t%a1\";
8459 else
8460 {
8461 if (arm_arch5t || arm_arch4t)
8462 return \"bx%?\\t%1\";
8463 else
8464 return \"mov%?\\t%|pc, %1\\t@ indirect sibling call \";
8465 }
8466 "
8467 [(set_attr "type" "call")]
8468 )
8469
8470 (define_expand "<return_str>return"
8471 [(RETURNS)]
8472 "(TARGET_ARM || (TARGET_THUMB2
8473 && ARM_FUNC_TYPE (arm_current_func_type ()) == ARM_FT_NORMAL
8474 && !IS_STACKALIGN (arm_current_func_type ())))
8475 <return_cond_false>"
8476 "
8477 {
8478 if (TARGET_THUMB2)
8479 {
8480 thumb2_expand_return (<return_simple_p>);
8481 DONE;
8482 }
8483 }
8484 "
8485 )
8486
8487 ;; Often the return insn will be the same as loading from memory, so set attr
8488 (define_insn "*arm_return"
8489 [(return)]
8490 "TARGET_ARM && USE_RETURN_INSN (FALSE)"
8491 "*
8492 {
8493 if (arm_ccfsm_state == 2)
8494 {
8495 arm_ccfsm_state += 2;
8496 return \"\";
8497 }
8498 return output_return_instruction (const_true_rtx, true, false, false);
8499 }"
8500 [(set_attr "type" "load_4")
8501 (set_attr "length" "12")
8502 (set_attr "predicable" "yes")]
8503 )
8504
8505 (define_insn "*cond_<return_str>return"
8506 [(set (pc)
8507 (if_then_else (match_operator 0 "arm_comparison_operator"
8508 [(match_operand 1 "cc_register" "") (const_int 0)])
8509 (RETURNS)
8510 (pc)))]
8511 "TARGET_ARM <return_cond_true>"
8512 "*
8513 {
8514 if (arm_ccfsm_state == 2)
8515 {
8516 arm_ccfsm_state += 2;
8517 return \"\";
8518 }
8519 return output_return_instruction (operands[0], true, false,
8520 <return_simple_p>);
8521 }"
8522 [(set_attr "conds" "use")
8523 (set_attr "length" "12")
8524 (set_attr "type" "load_4")]
8525 )
8526
8527 (define_insn "*cond_<return_str>return_inverted"
8528 [(set (pc)
8529 (if_then_else (match_operator 0 "arm_comparison_operator"
8530 [(match_operand 1 "cc_register" "") (const_int 0)])
8531 (pc)
8532 (RETURNS)))]
8533 "TARGET_ARM <return_cond_true>"
8534 "*
8535 {
8536 if (arm_ccfsm_state == 2)
8537 {
8538 arm_ccfsm_state += 2;
8539 return \"\";
8540 }
8541 return output_return_instruction (operands[0], true, true,
8542 <return_simple_p>);
8543 }"
8544 [(set_attr "conds" "use")
8545 (set_attr "length" "12")
8546 (set_attr "type" "load_4")]
8547 )
8548
8549 (define_insn "*arm_simple_return"
8550 [(simple_return)]
8551 "TARGET_ARM"
8552 "*
8553 {
8554 if (arm_ccfsm_state == 2)
8555 {
8556 arm_ccfsm_state += 2;
8557 return \"\";
8558 }
8559 return output_return_instruction (const_true_rtx, true, false, true);
8560 }"
8561 [(set_attr "type" "branch")
8562 (set_attr "length" "4")
8563 (set_attr "predicable" "yes")]
8564 )
8565
8566 ;; Generate a sequence of instructions to determine if the processor is
8567 ;; in 26-bit or 32-bit mode, and return the appropriate return address
8568 ;; mask.
8569
8570 (define_expand "return_addr_mask"
8571 [(set (match_dup 1)
8572 (compare:CC_NOOV (unspec [(const_int 0)] UNSPEC_CHECK_ARCH)
8573 (const_int 0)))
8574 (set (match_operand:SI 0 "s_register_operand" "")
8575 (if_then_else:SI (eq (match_dup 1) (const_int 0))
8576 (const_int -1)
8577 (const_int 67108860)))] ; 0x03fffffc
8578 "TARGET_ARM"
8579 "
8580 operands[1] = gen_rtx_REG (CC_NOOVmode, CC_REGNUM);
8581 ")
8582
8583 (define_insn "*check_arch2"
8584 [(set (match_operand:CC_NOOV 0 "cc_register" "")
8585 (compare:CC_NOOV (unspec [(const_int 0)] UNSPEC_CHECK_ARCH)
8586 (const_int 0)))]
8587 "TARGET_ARM"
8588 "teq\\t%|r0, %|r0\;teq\\t%|pc, %|pc"
8589 [(set_attr "length" "8")
8590 (set_attr "conds" "set")
8591 (set_attr "type" "multiple")]
8592 )
8593
8594 ;; Call subroutine returning any type.
8595
8596 (define_expand "untyped_call"
8597 [(parallel [(call (match_operand 0 "" "")
8598 (const_int 0))
8599 (match_operand 1 "" "")
8600 (match_operand 2 "" "")])]
8601 "TARGET_EITHER"
8602 "
8603 {
8604 int i;
8605 rtx par = gen_rtx_PARALLEL (VOIDmode,
8606 rtvec_alloc (XVECLEN (operands[2], 0)));
8607 rtx addr = gen_reg_rtx (Pmode);
8608 rtx mem;
8609 int size = 0;
8610
8611 emit_move_insn (addr, XEXP (operands[1], 0));
8612 mem = change_address (operands[1], BLKmode, addr);
8613
8614 for (i = 0; i < XVECLEN (operands[2], 0); i++)
8615 {
8616 rtx src = SET_SRC (XVECEXP (operands[2], 0, i));
8617
8618 /* Default code only uses r0 as a return value, but we could
8619 be using anything up to 4 registers. */
8620 if (REGNO (src) == R0_REGNUM)
8621 src = gen_rtx_REG (TImode, R0_REGNUM);
8622
8623 XVECEXP (par, 0, i) = gen_rtx_EXPR_LIST (VOIDmode, src,
8624 GEN_INT (size));
8625 size += GET_MODE_SIZE (GET_MODE (src));
8626 }
8627
8628 emit_call_insn (gen_call_value (par, operands[0], const0_rtx, NULL));
8629
8630 size = 0;
8631
8632 for (i = 0; i < XVECLEN (par, 0); i++)
8633 {
8634 HOST_WIDE_INT offset = 0;
8635 rtx reg = XEXP (XVECEXP (par, 0, i), 0);
8636
8637 if (size != 0)
8638 emit_move_insn (addr, plus_constant (Pmode, addr, size));
8639
8640 mem = change_address (mem, GET_MODE (reg), NULL);
8641 if (REGNO (reg) == R0_REGNUM)
8642 {
8643 /* On thumb we have to use a write-back instruction. */
8644 emit_insn (arm_gen_store_multiple (arm_regs_in_sequence, 4, addr,
8645 TARGET_THUMB ? TRUE : FALSE, mem, &offset));
8646 size = TARGET_ARM ? 16 : 0;
8647 }
8648 else
8649 {
8650 emit_move_insn (mem, reg);
8651 size = GET_MODE_SIZE (GET_MODE (reg));
8652 }
8653 }
8654
8655 /* The optimizer does not know that the call sets the function value
8656 registers we stored in the result block. We avoid problems by
8657 claiming that all hard registers are used and clobbered at this
8658 point. */
8659 emit_insn (gen_blockage ());
8660
8661 DONE;
8662 }"
8663 )
8664
8665 (define_expand "untyped_return"
8666 [(match_operand:BLK 0 "memory_operand" "")
8667 (match_operand 1 "" "")]
8668 "TARGET_EITHER"
8669 "
8670 {
8671 int i;
8672 rtx addr = gen_reg_rtx (Pmode);
8673 rtx mem;
8674 int size = 0;
8675
8676 emit_move_insn (addr, XEXP (operands[0], 0));
8677 mem = change_address (operands[0], BLKmode, addr);
8678
8679 for (i = 0; i < XVECLEN (operands[1], 0); i++)
8680 {
8681 HOST_WIDE_INT offset = 0;
8682 rtx reg = SET_DEST (XVECEXP (operands[1], 0, i));
8683
8684 if (size != 0)
8685 emit_move_insn (addr, plus_constant (Pmode, addr, size));
8686
8687 mem = change_address (mem, GET_MODE (reg), NULL);
8688 if (REGNO (reg) == R0_REGNUM)
8689 {
8690 /* On thumb we have to use a write-back instruction. */
8691 emit_insn (arm_gen_load_multiple (arm_regs_in_sequence, 4, addr,
8692 TARGET_THUMB ? TRUE : FALSE, mem, &offset));
8693 size = TARGET_ARM ? 16 : 0;
8694 }
8695 else
8696 {
8697 emit_move_insn (reg, mem);
8698 size = GET_MODE_SIZE (GET_MODE (reg));
8699 }
8700 }
8701
8702 /* Emit USE insns before the return. */
8703 for (i = 0; i < XVECLEN (operands[1], 0); i++)
8704 emit_use (SET_DEST (XVECEXP (operands[1], 0, i)));
8705
8706 /* Construct the return. */
8707 expand_naked_return ();
8708
8709 DONE;
8710 }"
8711 )
8712
8713 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
8714 ;; all of memory. This blocks insns from being moved across this point.
8715
8716 (define_insn "blockage"
8717 [(unspec_volatile [(const_int 0)] VUNSPEC_BLOCKAGE)]
8718 "TARGET_EITHER"
8719 ""
8720 [(set_attr "length" "0")
8721 (set_attr "type" "block")]
8722 )
8723
8724 ;; Since we hard code r0 here use the 'o' constraint to prevent
8725 ;; provoking undefined behaviour in the hardware with putting out
8726 ;; auto-increment operations with potentially r0 as the base register.
8727 (define_insn "probe_stack"
8728 [(set (match_operand:SI 0 "memory_operand" "=o")
8729 (unspec:SI [(const_int 0)] UNSPEC_PROBE_STACK))]
8730 "TARGET_32BIT"
8731 "str%?\\tr0, %0"
8732 [(set_attr "type" "store_4")
8733 (set_attr "predicable" "yes")]
8734 )
8735
8736 (define_insn "probe_stack_range"
8737 [(set (match_operand:SI 0 "register_operand" "=r")
8738 (unspec_volatile:SI [(match_operand:SI 1 "register_operand" "0")
8739 (match_operand:SI 2 "register_operand" "r")]
8740 VUNSPEC_PROBE_STACK_RANGE))]
8741 "TARGET_32BIT"
8742 {
8743 return output_probe_stack_range (operands[0], operands[2]);
8744 }
8745 [(set_attr "type" "multiple")
8746 (set_attr "conds" "clob")]
8747 )
8748
8749 ;; Named patterns for stack smashing protection.
8750 (define_expand "stack_protect_combined_set"
8751 [(parallel
8752 [(set (match_operand:SI 0 "memory_operand" "")
8753 (unspec:SI [(match_operand:SI 1 "guard_operand" "")]
8754 UNSPEC_SP_SET))
8755 (clobber (match_scratch:SI 2 ""))
8756 (clobber (match_scratch:SI 3 ""))])]
8757 ""
8758 ""
8759 )
8760
8761 ;; Use a separate insn from the above expand to be able to have the mem outside
8762 ;; the operand #1 when register allocation comes. This is needed to avoid LRA
8763 ;; try to reload the guard since we need to control how PIC access is done in
8764 ;; the -fpic/-fPIC case (see COMPUTE_NOW parameter when calling
8765 ;; legitimize_pic_address ()).
8766 (define_insn_and_split "*stack_protect_combined_set_insn"
8767 [(set (match_operand:SI 0 "memory_operand" "=m,m")
8768 (unspec:SI [(mem:SI (match_operand:SI 1 "guard_addr_operand" "X,X"))]
8769 UNSPEC_SP_SET))
8770 (clobber (match_scratch:SI 2 "=&l,&r"))
8771 (clobber (match_scratch:SI 3 "=&l,&r"))]
8772 ""
8773 "#"
8774 "reload_completed"
8775 [(parallel [(set (match_dup 0) (unspec:SI [(mem:SI (match_dup 2))]
8776 UNSPEC_SP_SET))
8777 (clobber (match_dup 2))])]
8778 "
8779 {
8780 if (flag_pic)
8781 {
8782 /* Forces recomputing of GOT base now. */
8783 legitimize_pic_address (operands[1], SImode, operands[2], operands[3],
8784 true /*compute_now*/);
8785 }
8786 else
8787 {
8788 if (address_operand (operands[1], SImode))
8789 operands[2] = operands[1];
8790 else
8791 {
8792 rtx mem = XEXP (force_const_mem (SImode, operands[1]), 0);
8793 emit_move_insn (operands[2], mem);
8794 }
8795 }
8796 }"
8797 [(set_attr "arch" "t1,32")]
8798 )
8799
8800 (define_insn "*stack_protect_set_insn"
8801 [(set (match_operand:SI 0 "memory_operand" "=m,m")
8802 (unspec:SI [(mem:SI (match_operand:SI 1 "register_operand" "+&l,&r"))]
8803 UNSPEC_SP_SET))
8804 (clobber (match_dup 1))]
8805 ""
8806 "@
8807 ldr\\t%1, [%1]\;str\\t%1, %0\;movs\t%1,#0
8808 ldr\\t%1, [%1]\;str\\t%1, %0\;mov\t%1,#0"
8809 [(set_attr "length" "8,12")
8810 (set_attr "conds" "clob,nocond")
8811 (set_attr "type" "multiple")
8812 (set_attr "arch" "t1,32")]
8813 )
8814
8815 (define_expand "stack_protect_combined_test"
8816 [(parallel
8817 [(set (pc)
8818 (if_then_else
8819 (eq (match_operand:SI 0 "memory_operand" "")
8820 (unspec:SI [(match_operand:SI 1 "guard_operand" "")]
8821 UNSPEC_SP_TEST))
8822 (label_ref (match_operand 2))
8823 (pc)))
8824 (clobber (match_scratch:SI 3 ""))
8825 (clobber (match_scratch:SI 4 ""))
8826 (clobber (reg:CC CC_REGNUM))])]
8827 ""
8828 ""
8829 )
8830
8831 ;; Use a separate insn from the above expand to be able to have the mem outside
8832 ;; the operand #1 when register allocation comes. This is needed to avoid LRA
8833 ;; try to reload the guard since we need to control how PIC access is done in
8834 ;; the -fpic/-fPIC case (see COMPUTE_NOW parameter when calling
8835 ;; legitimize_pic_address ()).
8836 (define_insn_and_split "*stack_protect_combined_test_insn"
8837 [(set (pc)
8838 (if_then_else
8839 (eq (match_operand:SI 0 "memory_operand" "m,m")
8840 (unspec:SI [(mem:SI (match_operand:SI 1 "guard_addr_operand" "X,X"))]
8841 UNSPEC_SP_TEST))
8842 (label_ref (match_operand 2))
8843 (pc)))
8844 (clobber (match_scratch:SI 3 "=&l,&r"))
8845 (clobber (match_scratch:SI 4 "=&l,&r"))
8846 (clobber (reg:CC CC_REGNUM))]
8847 ""
8848 "#"
8849 "reload_completed"
8850 [(const_int 0)]
8851 {
8852 rtx eq;
8853
8854 if (flag_pic)
8855 {
8856 /* Forces recomputing of GOT base now. */
8857 legitimize_pic_address (operands[1], SImode, operands[3], operands[4],
8858 true /*compute_now*/);
8859 }
8860 else
8861 {
8862 if (address_operand (operands[1], SImode))
8863 operands[3] = operands[1];
8864 else
8865 {
8866 rtx mem = XEXP (force_const_mem (SImode, operands[1]), 0);
8867 emit_move_insn (operands[3], mem);
8868 }
8869 }
8870 if (TARGET_32BIT)
8871 {
8872 emit_insn (gen_arm_stack_protect_test_insn (operands[4], operands[0],
8873 operands[3]));
8874 rtx cc_reg = gen_rtx_REG (CC_Zmode, CC_REGNUM);
8875 eq = gen_rtx_EQ (CC_Zmode, cc_reg, const0_rtx);
8876 emit_jump_insn (gen_arm_cond_branch (operands[2], eq, cc_reg));
8877 }
8878 else
8879 {
8880 emit_insn (gen_thumb1_stack_protect_test_insn (operands[4], operands[0],
8881 operands[3]));
8882 eq = gen_rtx_EQ (VOIDmode, operands[4], const0_rtx);
8883 emit_jump_insn (gen_cbranchsi4 (eq, operands[4], const0_rtx,
8884 operands[2]));
8885 }
8886 DONE;
8887 }
8888 [(set_attr "arch" "t1,32")]
8889 )
8890
8891 (define_insn "arm_stack_protect_test_insn"
8892 [(set (reg:CC_Z CC_REGNUM)
8893 (compare:CC_Z (unspec:SI [(match_operand:SI 1 "memory_operand" "m,m")
8894 (mem:SI (match_operand:SI 2 "register_operand" "+l,r"))]
8895 UNSPEC_SP_TEST)
8896 (const_int 0)))
8897 (clobber (match_operand:SI 0 "register_operand" "=&l,&r"))
8898 (clobber (match_dup 2))]
8899 "TARGET_32BIT"
8900 "ldr\t%0, [%2]\;ldr\t%2, %1\;eors\t%0, %2, %0"
8901 [(set_attr "length" "8,12")
8902 (set_attr "conds" "set")
8903 (set_attr "type" "multiple")
8904 (set_attr "arch" "t,32")]
8905 )
8906
8907 (define_expand "casesi"
8908 [(match_operand:SI 0 "s_register_operand" "") ; index to jump on
8909 (match_operand:SI 1 "const_int_operand" "") ; lower bound
8910 (match_operand:SI 2 "const_int_operand" "") ; total range
8911 (match_operand:SI 3 "" "") ; table label
8912 (match_operand:SI 4 "" "")] ; Out of range label
8913 "(TARGET_32BIT || optimize_size || flag_pic) && !target_pure_code"
8914 "
8915 {
8916 enum insn_code code;
8917 if (operands[1] != const0_rtx)
8918 {
8919 rtx reg = gen_reg_rtx (SImode);
8920
8921 emit_insn (gen_addsi3 (reg, operands[0],
8922 gen_int_mode (-INTVAL (operands[1]),
8923 SImode)));
8924 operands[0] = reg;
8925 }
8926
8927 if (TARGET_ARM)
8928 code = CODE_FOR_arm_casesi_internal;
8929 else if (TARGET_THUMB1)
8930 code = CODE_FOR_thumb1_casesi_internal_pic;
8931 else if (flag_pic)
8932 code = CODE_FOR_thumb2_casesi_internal_pic;
8933 else
8934 code = CODE_FOR_thumb2_casesi_internal;
8935
8936 if (!insn_data[(int) code].operand[1].predicate(operands[2], SImode))
8937 operands[2] = force_reg (SImode, operands[2]);
8938
8939 emit_jump_insn (GEN_FCN ((int) code) (operands[0], operands[2],
8940 operands[3], operands[4]));
8941 DONE;
8942 }"
8943 )
8944
8945 ;; The USE in this pattern is needed to tell flow analysis that this is
8946 ;; a CASESI insn. It has no other purpose.
8947 (define_expand "arm_casesi_internal"
8948 [(parallel [(set (pc)
8949 (if_then_else
8950 (leu (match_operand:SI 0 "s_register_operand")
8951 (match_operand:SI 1 "arm_rhs_operand"))
8952 (match_dup 4)
8953 (label_ref:SI (match_operand 3 ""))))
8954 (clobber (reg:CC CC_REGNUM))
8955 (use (label_ref:SI (match_operand 2 "")))])]
8956 "TARGET_ARM"
8957 {
8958 operands[4] = gen_rtx_MULT (SImode, operands[0], GEN_INT (4));
8959 operands[4] = gen_rtx_PLUS (SImode, operands[4],
8960 gen_rtx_LABEL_REF (SImode, operands[2]));
8961 operands[4] = gen_rtx_MEM (SImode, operands[4]);
8962 MEM_READONLY_P (operands[4]) = 1;
8963 MEM_NOTRAP_P (operands[4]) = 1;
8964 })
8965
8966 (define_insn "*arm_casesi_internal"
8967 [(parallel [(set (pc)
8968 (if_then_else
8969 (leu (match_operand:SI 0 "s_register_operand" "r")
8970 (match_operand:SI 1 "arm_rhs_operand" "rI"))
8971 (mem:SI (plus:SI (mult:SI (match_dup 0) (const_int 4))
8972 (label_ref:SI (match_operand 2 "" ""))))
8973 (label_ref:SI (match_operand 3 "" ""))))
8974 (clobber (reg:CC CC_REGNUM))
8975 (use (label_ref:SI (match_dup 2)))])]
8976 "TARGET_ARM"
8977 "*
8978 if (flag_pic)
8979 return \"cmp\\t%0, %1\;addls\\t%|pc, %|pc, %0, asl #2\;b\\t%l3\";
8980 return \"cmp\\t%0, %1\;ldrls\\t%|pc, [%|pc, %0, asl #2]\;b\\t%l3\";
8981 "
8982 [(set_attr "conds" "clob")
8983 (set_attr "length" "12")
8984 (set_attr "type" "multiple")]
8985 )
8986
8987 (define_expand "indirect_jump"
8988 [(set (pc)
8989 (match_operand:SI 0 "s_register_operand" ""))]
8990 "TARGET_EITHER"
8991 "
8992 /* Thumb-2 doesn't have mov pc, reg. Explicitly set the low bit of the
8993 address and use bx. */
8994 if (TARGET_THUMB2)
8995 {
8996 rtx tmp;
8997 tmp = gen_reg_rtx (SImode);
8998 emit_insn (gen_iorsi3 (tmp, operands[0], GEN_INT(1)));
8999 operands[0] = tmp;
9000 }
9001 "
9002 )
9003
9004 ;; NB Never uses BX.
9005 (define_insn "*arm_indirect_jump"
9006 [(set (pc)
9007 (match_operand:SI 0 "s_register_operand" "r"))]
9008 "TARGET_ARM"
9009 "mov%?\\t%|pc, %0\\t%@ indirect register jump"
9010 [(set_attr "predicable" "yes")
9011 (set_attr "type" "branch")]
9012 )
9013
9014 (define_insn "*load_indirect_jump"
9015 [(set (pc)
9016 (match_operand:SI 0 "memory_operand" "m"))]
9017 "TARGET_ARM"
9018 "ldr%?\\t%|pc, %0\\t%@ indirect memory jump"
9019 [(set_attr "type" "load_4")
9020 (set_attr "pool_range" "4096")
9021 (set_attr "neg_pool_range" "4084")
9022 (set_attr "predicable" "yes")]
9023 )
9024
9025 \f
9026 ;; Misc insns
9027
9028 (define_insn "nop"
9029 [(const_int 0)]
9030 "TARGET_EITHER"
9031 "nop"
9032 [(set (attr "length")
9033 (if_then_else (eq_attr "is_thumb" "yes")
9034 (const_int 2)
9035 (const_int 4)))
9036 (set_attr "type" "mov_reg")]
9037 )
9038
9039 (define_insn "trap"
9040 [(trap_if (const_int 1) (const_int 0))]
9041 ""
9042 "*
9043 if (TARGET_ARM)
9044 return \".inst\\t0xe7f000f0\";
9045 else
9046 return \".inst\\t0xdeff\";
9047 "
9048 [(set (attr "length")
9049 (if_then_else (eq_attr "is_thumb" "yes")
9050 (const_int 2)
9051 (const_int 4)))
9052 (set_attr "type" "trap")
9053 (set_attr "conds" "unconditional")]
9054 )
9055
9056 \f
9057 ;; Patterns to allow combination of arithmetic, cond code and shifts
9058
9059 (define_insn "*<arith_shift_insn>_multsi"
9060 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9061 (SHIFTABLE_OPS:SI
9062 (mult:SI (match_operand:SI 2 "s_register_operand" "r,r")
9063 (match_operand:SI 3 "power_of_two_operand" ""))
9064 (match_operand:SI 1 "s_register_operand" "rk,<t2_binop0>")))]
9065 "TARGET_32BIT"
9066 "<arith_shift_insn>%?\\t%0, %1, %2, lsl %b3"
9067 [(set_attr "predicable" "yes")
9068 (set_attr "shift" "2")
9069 (set_attr "arch" "a,t2")
9070 (set_attr "type" "alu_shift_imm")])
9071
9072 (define_insn "*<arith_shift_insn>_shiftsi"
9073 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9074 (SHIFTABLE_OPS:SI
9075 (match_operator:SI 2 "shift_nomul_operator"
9076 [(match_operand:SI 3 "s_register_operand" "r,r,r")
9077 (match_operand:SI 4 "shift_amount_operand" "M,M,r")])
9078 (match_operand:SI 1 "s_register_operand" "rk,<t2_binop0>,rk")))]
9079 "TARGET_32BIT && GET_CODE (operands[2]) != MULT"
9080 "<arith_shift_insn>%?\\t%0, %1, %3%S2"
9081 [(set_attr "predicable" "yes")
9082 (set_attr "shift" "3")
9083 (set_attr "arch" "a,t2,a")
9084 (set_attr "type" "alu_shift_imm,alu_shift_imm,alu_shift_reg")])
9085
9086 (define_split
9087 [(set (match_operand:SI 0 "s_register_operand" "")
9088 (match_operator:SI 1 "shiftable_operator"
9089 [(match_operator:SI 2 "shiftable_operator"
9090 [(match_operator:SI 3 "shift_operator"
9091 [(match_operand:SI 4 "s_register_operand" "")
9092 (match_operand:SI 5 "reg_or_int_operand" "")])
9093 (match_operand:SI 6 "s_register_operand" "")])
9094 (match_operand:SI 7 "arm_rhs_operand" "")]))
9095 (clobber (match_operand:SI 8 "s_register_operand" ""))]
9096 "TARGET_32BIT"
9097 [(set (match_dup 8)
9098 (match_op_dup 2 [(match_op_dup 3 [(match_dup 4) (match_dup 5)])
9099 (match_dup 6)]))
9100 (set (match_dup 0)
9101 (match_op_dup 1 [(match_dup 8) (match_dup 7)]))]
9102 "")
9103
9104 (define_insn "*arith_shiftsi_compare0"
9105 [(set (reg:CC_NOOV CC_REGNUM)
9106 (compare:CC_NOOV
9107 (match_operator:SI 1 "shiftable_operator"
9108 [(match_operator:SI 3 "shift_operator"
9109 [(match_operand:SI 4 "s_register_operand" "r,r")
9110 (match_operand:SI 5 "shift_amount_operand" "M,r")])
9111 (match_operand:SI 2 "s_register_operand" "r,r")])
9112 (const_int 0)))
9113 (set (match_operand:SI 0 "s_register_operand" "=r,r")
9114 (match_op_dup 1 [(match_op_dup 3 [(match_dup 4) (match_dup 5)])
9115 (match_dup 2)]))]
9116 "TARGET_32BIT"
9117 "%i1s%?\\t%0, %2, %4%S3"
9118 [(set_attr "conds" "set")
9119 (set_attr "shift" "4")
9120 (set_attr "arch" "32,a")
9121 (set_attr "type" "alus_shift_imm,alus_shift_reg")])
9122
9123 (define_insn "*arith_shiftsi_compare0_scratch"
9124 [(set (reg:CC_NOOV CC_REGNUM)
9125 (compare:CC_NOOV
9126 (match_operator:SI 1 "shiftable_operator"
9127 [(match_operator:SI 3 "shift_operator"
9128 [(match_operand:SI 4 "s_register_operand" "r,r")
9129 (match_operand:SI 5 "shift_amount_operand" "M,r")])
9130 (match_operand:SI 2 "s_register_operand" "r,r")])
9131 (const_int 0)))
9132 (clobber (match_scratch:SI 0 "=r,r"))]
9133 "TARGET_32BIT"
9134 "%i1s%?\\t%0, %2, %4%S3"
9135 [(set_attr "conds" "set")
9136 (set_attr "shift" "4")
9137 (set_attr "arch" "32,a")
9138 (set_attr "type" "alus_shift_imm,alus_shift_reg")])
9139
9140 (define_insn "*sub_shiftsi"
9141 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9142 (minus:SI (match_operand:SI 1 "s_register_operand" "r,r")
9143 (match_operator:SI 2 "shift_operator"
9144 [(match_operand:SI 3 "s_register_operand" "r,r")
9145 (match_operand:SI 4 "shift_amount_operand" "M,r")])))]
9146 "TARGET_32BIT"
9147 "sub%?\\t%0, %1, %3%S2"
9148 [(set_attr "predicable" "yes")
9149 (set_attr "predicable_short_it" "no")
9150 (set_attr "shift" "3")
9151 (set_attr "arch" "32,a")
9152 (set_attr "type" "alus_shift_imm,alus_shift_reg")])
9153
9154 (define_insn "*sub_shiftsi_compare0"
9155 [(set (reg:CC_NOOV CC_REGNUM)
9156 (compare:CC_NOOV
9157 (minus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
9158 (match_operator:SI 2 "shift_operator"
9159 [(match_operand:SI 3 "s_register_operand" "r,r,r")
9160 (match_operand:SI 4 "shift_amount_operand" "M,r,M")]))
9161 (const_int 0)))
9162 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9163 (minus:SI (match_dup 1)
9164 (match_op_dup 2 [(match_dup 3) (match_dup 4)])))]
9165 "TARGET_32BIT"
9166 "subs%?\\t%0, %1, %3%S2"
9167 [(set_attr "conds" "set")
9168 (set_attr "shift" "3")
9169 (set_attr "arch" "32,a,a")
9170 (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
9171
9172 (define_insn "*sub_shiftsi_compare0_scratch"
9173 [(set (reg:CC_NOOV CC_REGNUM)
9174 (compare:CC_NOOV
9175 (minus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
9176 (match_operator:SI 2 "shift_operator"
9177 [(match_operand:SI 3 "s_register_operand" "r,r,r")
9178 (match_operand:SI 4 "shift_amount_operand" "M,r,M")]))
9179 (const_int 0)))
9180 (clobber (match_scratch:SI 0 "=r,r,r"))]
9181 "TARGET_32BIT"
9182 "subs%?\\t%0, %1, %3%S2"
9183 [(set_attr "conds" "set")
9184 (set_attr "shift" "3")
9185 (set_attr "arch" "32,a,a")
9186 (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
9187 \f
9188
9189 (define_insn_and_split "*and_scc"
9190 [(set (match_operand:SI 0 "s_register_operand" "=r")
9191 (and:SI (match_operator:SI 1 "arm_comparison_operator"
9192 [(match_operand 2 "cc_register" "") (const_int 0)])
9193 (match_operand:SI 3 "s_register_operand" "r")))]
9194 "TARGET_ARM"
9195 "#" ; "mov%D1\\t%0, #0\;and%d1\\t%0, %3, #1"
9196 "&& reload_completed"
9197 [(cond_exec (match_dup 5) (set (match_dup 0) (const_int 0)))
9198 (cond_exec (match_dup 4) (set (match_dup 0)
9199 (and:SI (match_dup 3) (const_int 1))))]
9200 {
9201 machine_mode mode = GET_MODE (operands[2]);
9202 enum rtx_code rc = GET_CODE (operands[1]);
9203
9204 /* Note that operands[4] is the same as operands[1],
9205 but with VOIDmode as the result. */
9206 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
9207 if (mode == CCFPmode || mode == CCFPEmode)
9208 rc = reverse_condition_maybe_unordered (rc);
9209 else
9210 rc = reverse_condition (rc);
9211 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
9212 }
9213 [(set_attr "conds" "use")
9214 (set_attr "type" "multiple")
9215 (set_attr "length" "8")]
9216 )
9217
9218 (define_insn_and_split "*ior_scc"
9219 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9220 (ior:SI (match_operator:SI 1 "arm_comparison_operator"
9221 [(match_operand 2 "cc_register" "") (const_int 0)])
9222 (match_operand:SI 3 "s_register_operand" "0,?r")))]
9223 "TARGET_ARM"
9224 "@
9225 orr%d1\\t%0, %3, #1
9226 #"
9227 "&& reload_completed
9228 && REGNO (operands [0]) != REGNO (operands[3])"
9229 ;; && which_alternative == 1
9230 ; mov%D1\\t%0, %3\;orr%d1\\t%0, %3, #1
9231 [(cond_exec (match_dup 5) (set (match_dup 0) (match_dup 3)))
9232 (cond_exec (match_dup 4) (set (match_dup 0)
9233 (ior:SI (match_dup 3) (const_int 1))))]
9234 {
9235 machine_mode mode = GET_MODE (operands[2]);
9236 enum rtx_code rc = GET_CODE (operands[1]);
9237
9238 /* Note that operands[4] is the same as operands[1],
9239 but with VOIDmode as the result. */
9240 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
9241 if (mode == CCFPmode || mode == CCFPEmode)
9242 rc = reverse_condition_maybe_unordered (rc);
9243 else
9244 rc = reverse_condition (rc);
9245 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
9246 }
9247 [(set_attr "conds" "use")
9248 (set_attr "length" "4,8")
9249 (set_attr "type" "logic_imm,multiple")]
9250 )
9251
9252 ; A series of splitters for the compare_scc pattern below. Note that
9253 ; order is important.
9254 (define_split
9255 [(set (match_operand:SI 0 "s_register_operand" "")
9256 (lt:SI (match_operand:SI 1 "s_register_operand" "")
9257 (const_int 0)))
9258 (clobber (reg:CC CC_REGNUM))]
9259 "TARGET_32BIT && reload_completed"
9260 [(set (match_dup 0) (lshiftrt:SI (match_dup 1) (const_int 31)))])
9261
9262 (define_split
9263 [(set (match_operand:SI 0 "s_register_operand" "")
9264 (ge:SI (match_operand:SI 1 "s_register_operand" "")
9265 (const_int 0)))
9266 (clobber (reg:CC CC_REGNUM))]
9267 "TARGET_32BIT && reload_completed"
9268 [(set (match_dup 0) (not:SI (match_dup 1)))
9269 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 31)))])
9270
9271 (define_split
9272 [(set (match_operand:SI 0 "s_register_operand" "")
9273 (eq:SI (match_operand:SI 1 "s_register_operand" "")
9274 (const_int 0)))
9275 (clobber (reg:CC CC_REGNUM))]
9276 "arm_arch5t && TARGET_32BIT"
9277 [(set (match_dup 0) (clz:SI (match_dup 1)))
9278 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
9279 )
9280
9281 (define_split
9282 [(set (match_operand:SI 0 "s_register_operand" "")
9283 (eq:SI (match_operand:SI 1 "s_register_operand" "")
9284 (const_int 0)))
9285 (clobber (reg:CC CC_REGNUM))]
9286 "TARGET_32BIT && reload_completed"
9287 [(parallel
9288 [(set (reg:CC CC_REGNUM)
9289 (compare:CC (const_int 1) (match_dup 1)))
9290 (set (match_dup 0)
9291 (minus:SI (const_int 1) (match_dup 1)))])
9292 (cond_exec (ltu:CC (reg:CC CC_REGNUM) (const_int 0))
9293 (set (match_dup 0) (const_int 0)))])
9294
9295 (define_split
9296 [(set (match_operand:SI 0 "s_register_operand" "")
9297 (ne:SI (match_operand:SI 1 "s_register_operand" "")
9298 (match_operand:SI 2 "const_int_operand" "")))
9299 (clobber (reg:CC CC_REGNUM))]
9300 "TARGET_32BIT && reload_completed"
9301 [(parallel
9302 [(set (reg:CC CC_REGNUM)
9303 (compare:CC (match_dup 1) (match_dup 2)))
9304 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 3)))])
9305 (cond_exec (ne:CC (reg:CC CC_REGNUM) (const_int 0))
9306 (set (match_dup 0) (const_int 1)))]
9307 {
9308 operands[3] = gen_int_mode (-INTVAL (operands[2]), SImode);
9309 })
9310
9311 (define_split
9312 [(set (match_operand:SI 0 "s_register_operand" "")
9313 (ne:SI (match_operand:SI 1 "s_register_operand" "")
9314 (match_operand:SI 2 "arm_add_operand" "")))
9315 (clobber (reg:CC CC_REGNUM))]
9316 "TARGET_32BIT && reload_completed"
9317 [(parallel
9318 [(set (reg:CC_NOOV CC_REGNUM)
9319 (compare:CC_NOOV (minus:SI (match_dup 1) (match_dup 2))
9320 (const_int 0)))
9321 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
9322 (cond_exec (ne:CC_NOOV (reg:CC_NOOV CC_REGNUM) (const_int 0))
9323 (set (match_dup 0) (const_int 1)))])
9324
9325 (define_insn_and_split "*compare_scc"
9326 [(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts")
9327 (match_operator:SI 1 "arm_comparison_operator"
9328 [(match_operand:SI 2 "s_register_operand" "r,r")
9329 (match_operand:SI 3 "arm_add_operand" "rI,L")]))
9330 (clobber (reg:CC CC_REGNUM))]
9331 "TARGET_32BIT"
9332 "#"
9333 "&& reload_completed"
9334 [(set (reg:CC CC_REGNUM) (compare:CC (match_dup 2) (match_dup 3)))
9335 (cond_exec (match_dup 4) (set (match_dup 0) (const_int 0)))
9336 (cond_exec (match_dup 5) (set (match_dup 0) (const_int 1)))]
9337 {
9338 rtx tmp1;
9339 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
9340 operands[2], operands[3]);
9341 enum rtx_code rc = GET_CODE (operands[1]);
9342
9343 tmp1 = gen_rtx_REG (mode, CC_REGNUM);
9344
9345 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, tmp1, const0_rtx);
9346 if (mode == CCFPmode || mode == CCFPEmode)
9347 rc = reverse_condition_maybe_unordered (rc);
9348 else
9349 rc = reverse_condition (rc);
9350 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, tmp1, const0_rtx);
9351 }
9352 [(set_attr "type" "multiple")]
9353 )
9354
9355 ;; Attempt to improve the sequence generated by the compare_scc splitters
9356 ;; not to use conditional execution.
9357
9358 ;; Rd = (eq (reg1) (const_int0)) // ARMv5
9359 ;; clz Rd, reg1
9360 ;; lsr Rd, Rd, #5
9361 (define_peephole2
9362 [(set (reg:CC CC_REGNUM)
9363 (compare:CC (match_operand:SI 1 "register_operand" "")
9364 (const_int 0)))
9365 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
9366 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
9367 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
9368 (set (match_dup 0) (const_int 1)))]
9369 "arm_arch5t && TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
9370 [(set (match_dup 0) (clz:SI (match_dup 1)))
9371 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
9372 )
9373
9374 ;; Rd = (eq (reg1) (const_int0)) // !ARMv5
9375 ;; negs Rd, reg1
9376 ;; adc Rd, Rd, reg1
9377 (define_peephole2
9378 [(set (reg:CC CC_REGNUM)
9379 (compare:CC (match_operand:SI 1 "register_operand" "")
9380 (const_int 0)))
9381 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
9382 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
9383 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
9384 (set (match_dup 0) (const_int 1)))
9385 (match_scratch:SI 2 "r")]
9386 "TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
9387 [(parallel
9388 [(set (reg:CC CC_REGNUM)
9389 (compare:CC (const_int 0) (match_dup 1)))
9390 (set (match_dup 2) (minus:SI (const_int 0) (match_dup 1)))])
9391 (set (match_dup 0)
9392 (plus:SI (plus:SI (match_dup 1) (match_dup 2))
9393 (geu:SI (reg:CC CC_REGNUM) (const_int 0))))]
9394 )
9395
9396 ;; Rd = (eq (reg1) (reg2/imm)) // ARMv5 and optimising for speed.
9397 ;; sub Rd, Reg1, reg2
9398 ;; clz Rd, Rd
9399 ;; lsr Rd, Rd, #5
9400 (define_peephole2
9401 [(set (reg:CC CC_REGNUM)
9402 (compare:CC (match_operand:SI 1 "register_operand" "")
9403 (match_operand:SI 2 "arm_rhs_operand" "")))
9404 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
9405 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
9406 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
9407 (set (match_dup 0) (const_int 1)))]
9408 "arm_arch5t && TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)
9409 && !(TARGET_THUMB2 && optimize_insn_for_size_p ())"
9410 [(set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))
9411 (set (match_dup 0) (clz:SI (match_dup 0)))
9412 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
9413 )
9414
9415
9416 ;; Rd = (eq (reg1) (reg2)) // ! ARMv5 or optimising for size.
9417 ;; sub T1, Reg1, reg2
9418 ;; negs Rd, T1
9419 ;; adc Rd, Rd, T1
9420 (define_peephole2
9421 [(set (reg:CC CC_REGNUM)
9422 (compare:CC (match_operand:SI 1 "register_operand" "")
9423 (match_operand:SI 2 "arm_rhs_operand" "")))
9424 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
9425 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
9426 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
9427 (set (match_dup 0) (const_int 1)))
9428 (match_scratch:SI 3 "r")]
9429 "TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
9430 [(set (match_dup 3) (match_dup 4))
9431 (parallel
9432 [(set (reg:CC CC_REGNUM)
9433 (compare:CC (const_int 0) (match_dup 3)))
9434 (set (match_dup 0) (minus:SI (const_int 0) (match_dup 3)))])
9435 (set (match_dup 0)
9436 (plus:SI (plus:SI (match_dup 0) (match_dup 3))
9437 (geu:SI (reg:CC CC_REGNUM) (const_int 0))))]
9438 "
9439 if (CONST_INT_P (operands[2]))
9440 operands[4] = plus_constant (SImode, operands[1], -INTVAL (operands[2]));
9441 else
9442 operands[4] = gen_rtx_MINUS (SImode, operands[1], operands[2]);
9443 ")
9444
9445 (define_insn "*cond_move"
9446 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9447 (if_then_else:SI (match_operator 3 "equality_operator"
9448 [(match_operator 4 "arm_comparison_operator"
9449 [(match_operand 5 "cc_register" "") (const_int 0)])
9450 (const_int 0)])
9451 (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
9452 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))]
9453 "TARGET_ARM"
9454 "*
9455 if (GET_CODE (operands[3]) == NE)
9456 {
9457 if (which_alternative != 1)
9458 output_asm_insn (\"mov%D4\\t%0, %2\", operands);
9459 if (which_alternative != 0)
9460 output_asm_insn (\"mov%d4\\t%0, %1\", operands);
9461 return \"\";
9462 }
9463 if (which_alternative != 0)
9464 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
9465 if (which_alternative != 1)
9466 output_asm_insn (\"mov%d4\\t%0, %2\", operands);
9467 return \"\";
9468 "
9469 [(set_attr "conds" "use")
9470 (set_attr_alternative "type"
9471 [(if_then_else (match_operand 2 "const_int_operand" "")
9472 (const_string "mov_imm")
9473 (const_string "mov_reg"))
9474 (if_then_else (match_operand 1 "const_int_operand" "")
9475 (const_string "mov_imm")
9476 (const_string "mov_reg"))
9477 (const_string "multiple")])
9478 (set_attr "length" "4,4,8")]
9479 )
9480
9481 (define_insn "*cond_arith"
9482 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9483 (match_operator:SI 5 "shiftable_operator"
9484 [(match_operator:SI 4 "arm_comparison_operator"
9485 [(match_operand:SI 2 "s_register_operand" "r,r")
9486 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
9487 (match_operand:SI 1 "s_register_operand" "0,?r")]))
9488 (clobber (reg:CC CC_REGNUM))]
9489 "TARGET_ARM"
9490 "*
9491 if (GET_CODE (operands[4]) == LT && operands[3] == const0_rtx)
9492 return \"%i5\\t%0, %1, %2, lsr #31\";
9493
9494 output_asm_insn (\"cmp\\t%2, %3\", operands);
9495 if (GET_CODE (operands[5]) == AND)
9496 output_asm_insn (\"mov%D4\\t%0, #0\", operands);
9497 else if (GET_CODE (operands[5]) == MINUS)
9498 output_asm_insn (\"rsb%D4\\t%0, %1, #0\", operands);
9499 else if (which_alternative != 0)
9500 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
9501 return \"%i5%d4\\t%0, %1, #1\";
9502 "
9503 [(set_attr "conds" "clob")
9504 (set_attr "length" "12")
9505 (set_attr "type" "multiple")]
9506 )
9507
9508 (define_insn "*cond_sub"
9509 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9510 (minus:SI (match_operand:SI 1 "s_register_operand" "0,?r")
9511 (match_operator:SI 4 "arm_comparison_operator"
9512 [(match_operand:SI 2 "s_register_operand" "r,r")
9513 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
9514 (clobber (reg:CC CC_REGNUM))]
9515 "TARGET_ARM"
9516 "*
9517 output_asm_insn (\"cmp\\t%2, %3\", operands);
9518 if (which_alternative != 0)
9519 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
9520 return \"sub%d4\\t%0, %1, #1\";
9521 "
9522 [(set_attr "conds" "clob")
9523 (set_attr "length" "8,12")
9524 (set_attr "type" "multiple")]
9525 )
9526
9527 (define_insn "*cmp_ite0"
9528 [(set (match_operand 6 "dominant_cc_register" "")
9529 (compare
9530 (if_then_else:SI
9531 (match_operator 4 "arm_comparison_operator"
9532 [(match_operand:SI 0 "s_register_operand"
9533 "l,l,l,r,r,r,r,r,r")
9534 (match_operand:SI 1 "arm_add_operand"
9535 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
9536 (match_operator:SI 5 "arm_comparison_operator"
9537 [(match_operand:SI 2 "s_register_operand"
9538 "l,r,r,l,l,r,r,r,r")
9539 (match_operand:SI 3 "arm_add_operand"
9540 "lPy,rI,L,lPy,lPy,rI,rI,L,L")])
9541 (const_int 0))
9542 (const_int 0)))]
9543 "TARGET_32BIT"
9544 "*
9545 {
9546 static const char * const cmp1[NUM_OF_COND_CMP][2] =
9547 {
9548 {\"cmp%d5\\t%0, %1\",
9549 \"cmp%d4\\t%2, %3\"},
9550 {\"cmn%d5\\t%0, #%n1\",
9551 \"cmp%d4\\t%2, %3\"},
9552 {\"cmp%d5\\t%0, %1\",
9553 \"cmn%d4\\t%2, #%n3\"},
9554 {\"cmn%d5\\t%0, #%n1\",
9555 \"cmn%d4\\t%2, #%n3\"}
9556 };
9557 static const char * const cmp2[NUM_OF_COND_CMP][2] =
9558 {
9559 {\"cmp\\t%2, %3\",
9560 \"cmp\\t%0, %1\"},
9561 {\"cmp\\t%2, %3\",
9562 \"cmn\\t%0, #%n1\"},
9563 {\"cmn\\t%2, #%n3\",
9564 \"cmp\\t%0, %1\"},
9565 {\"cmn\\t%2, #%n3\",
9566 \"cmn\\t%0, #%n1\"}
9567 };
9568 static const char * const ite[2] =
9569 {
9570 \"it\\t%d5\",
9571 \"it\\t%d4\"
9572 };
9573 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
9574 CMP_CMP, CMN_CMP, CMP_CMP,
9575 CMN_CMP, CMP_CMN, CMN_CMN};
9576 int swap =
9577 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
9578
9579 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
9580 if (TARGET_THUMB2) {
9581 output_asm_insn (ite[swap], operands);
9582 }
9583 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
9584 return \"\";
9585 }"
9586 [(set_attr "conds" "set")
9587 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
9588 (set_attr "enabled_for_short_it" "yes,no,no,no,no,no,no,no,no")
9589 (set_attr "type" "multiple")
9590 (set_attr_alternative "length"
9591 [(const_int 6)
9592 (const_int 8)
9593 (const_int 8)
9594 (const_int 8)
9595 (const_int 8)
9596 (if_then_else (eq_attr "is_thumb" "no")
9597 (const_int 8)
9598 (const_int 10))
9599 (if_then_else (eq_attr "is_thumb" "no")
9600 (const_int 8)
9601 (const_int 10))
9602 (if_then_else (eq_attr "is_thumb" "no")
9603 (const_int 8)
9604 (const_int 10))
9605 (if_then_else (eq_attr "is_thumb" "no")
9606 (const_int 8)
9607 (const_int 10))])]
9608 )
9609
9610 (define_insn "*cmp_ite1"
9611 [(set (match_operand 6 "dominant_cc_register" "")
9612 (compare
9613 (if_then_else:SI
9614 (match_operator 4 "arm_comparison_operator"
9615 [(match_operand:SI 0 "s_register_operand"
9616 "l,l,l,r,r,r,r,r,r")
9617 (match_operand:SI 1 "arm_add_operand"
9618 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
9619 (match_operator:SI 5 "arm_comparison_operator"
9620 [(match_operand:SI 2 "s_register_operand"
9621 "l,r,r,l,l,r,r,r,r")
9622 (match_operand:SI 3 "arm_add_operand"
9623 "lPy,rI,L,lPy,lPy,rI,rI,L,L")])
9624 (const_int 1))
9625 (const_int 0)))]
9626 "TARGET_32BIT"
9627 "*
9628 {
9629 static const char * const cmp1[NUM_OF_COND_CMP][2] =
9630 {
9631 {\"cmp\\t%0, %1\",
9632 \"cmp\\t%2, %3\"},
9633 {\"cmn\\t%0, #%n1\",
9634 \"cmp\\t%2, %3\"},
9635 {\"cmp\\t%0, %1\",
9636 \"cmn\\t%2, #%n3\"},
9637 {\"cmn\\t%0, #%n1\",
9638 \"cmn\\t%2, #%n3\"}
9639 };
9640 static const char * const cmp2[NUM_OF_COND_CMP][2] =
9641 {
9642 {\"cmp%d4\\t%2, %3\",
9643 \"cmp%D5\\t%0, %1\"},
9644 {\"cmp%d4\\t%2, %3\",
9645 \"cmn%D5\\t%0, #%n1\"},
9646 {\"cmn%d4\\t%2, #%n3\",
9647 \"cmp%D5\\t%0, %1\"},
9648 {\"cmn%d4\\t%2, #%n3\",
9649 \"cmn%D5\\t%0, #%n1\"}
9650 };
9651 static const char * const ite[2] =
9652 {
9653 \"it\\t%d4\",
9654 \"it\\t%D5\"
9655 };
9656 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
9657 CMP_CMP, CMN_CMP, CMP_CMP,
9658 CMN_CMP, CMP_CMN, CMN_CMN};
9659 int swap =
9660 comparison_dominates_p (GET_CODE (operands[5]),
9661 reverse_condition (GET_CODE (operands[4])));
9662
9663 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
9664 if (TARGET_THUMB2) {
9665 output_asm_insn (ite[swap], operands);
9666 }
9667 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
9668 return \"\";
9669 }"
9670 [(set_attr "conds" "set")
9671 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
9672 (set_attr "enabled_for_short_it" "yes,no,no,no,no,no,no,no,no")
9673 (set_attr_alternative "length"
9674 [(const_int 6)
9675 (const_int 8)
9676 (const_int 8)
9677 (const_int 8)
9678 (const_int 8)
9679 (if_then_else (eq_attr "is_thumb" "no")
9680 (const_int 8)
9681 (const_int 10))
9682 (if_then_else (eq_attr "is_thumb" "no")
9683 (const_int 8)
9684 (const_int 10))
9685 (if_then_else (eq_attr "is_thumb" "no")
9686 (const_int 8)
9687 (const_int 10))
9688 (if_then_else (eq_attr "is_thumb" "no")
9689 (const_int 8)
9690 (const_int 10))])
9691 (set_attr "type" "multiple")]
9692 )
9693
9694 (define_insn "*cmp_and"
9695 [(set (match_operand 6 "dominant_cc_register" "")
9696 (compare
9697 (and:SI
9698 (match_operator 4 "arm_comparison_operator"
9699 [(match_operand:SI 0 "s_register_operand"
9700 "l,l,l,r,r,r,r,r,r")
9701 (match_operand:SI 1 "arm_add_operand"
9702 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
9703 (match_operator:SI 5 "arm_comparison_operator"
9704 [(match_operand:SI 2 "s_register_operand"
9705 "l,r,r,l,l,r,r,r,r")
9706 (match_operand:SI 3 "arm_add_operand"
9707 "lPy,rI,L,lPy,lPy,rI,rI,L,L")]))
9708 (const_int 0)))]
9709 "TARGET_32BIT"
9710 "*
9711 {
9712 static const char *const cmp1[NUM_OF_COND_CMP][2] =
9713 {
9714 {\"cmp%d5\\t%0, %1\",
9715 \"cmp%d4\\t%2, %3\"},
9716 {\"cmn%d5\\t%0, #%n1\",
9717 \"cmp%d4\\t%2, %3\"},
9718 {\"cmp%d5\\t%0, %1\",
9719 \"cmn%d4\\t%2, #%n3\"},
9720 {\"cmn%d5\\t%0, #%n1\",
9721 \"cmn%d4\\t%2, #%n3\"}
9722 };
9723 static const char *const cmp2[NUM_OF_COND_CMP][2] =
9724 {
9725 {\"cmp\\t%2, %3\",
9726 \"cmp\\t%0, %1\"},
9727 {\"cmp\\t%2, %3\",
9728 \"cmn\\t%0, #%n1\"},
9729 {\"cmn\\t%2, #%n3\",
9730 \"cmp\\t%0, %1\"},
9731 {\"cmn\\t%2, #%n3\",
9732 \"cmn\\t%0, #%n1\"}
9733 };
9734 static const char *const ite[2] =
9735 {
9736 \"it\\t%d5\",
9737 \"it\\t%d4\"
9738 };
9739 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
9740 CMP_CMP, CMN_CMP, CMP_CMP,
9741 CMN_CMP, CMP_CMN, CMN_CMN};
9742 int swap =
9743 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
9744
9745 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
9746 if (TARGET_THUMB2) {
9747 output_asm_insn (ite[swap], operands);
9748 }
9749 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
9750 return \"\";
9751 }"
9752 [(set_attr "conds" "set")
9753 (set_attr "predicable" "no")
9754 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
9755 (set_attr "enabled_for_short_it" "yes,no,no,no,no,no,no,no,no")
9756 (set_attr_alternative "length"
9757 [(const_int 6)
9758 (const_int 8)
9759 (const_int 8)
9760 (const_int 8)
9761 (const_int 8)
9762 (if_then_else (eq_attr "is_thumb" "no")
9763 (const_int 8)
9764 (const_int 10))
9765 (if_then_else (eq_attr "is_thumb" "no")
9766 (const_int 8)
9767 (const_int 10))
9768 (if_then_else (eq_attr "is_thumb" "no")
9769 (const_int 8)
9770 (const_int 10))
9771 (if_then_else (eq_attr "is_thumb" "no")
9772 (const_int 8)
9773 (const_int 10))])
9774 (set_attr "type" "multiple")]
9775 )
9776
9777 (define_insn "*cmp_ior"
9778 [(set (match_operand 6 "dominant_cc_register" "")
9779 (compare
9780 (ior:SI
9781 (match_operator 4 "arm_comparison_operator"
9782 [(match_operand:SI 0 "s_register_operand"
9783 "l,l,l,r,r,r,r,r,r")
9784 (match_operand:SI 1 "arm_add_operand"
9785 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
9786 (match_operator:SI 5 "arm_comparison_operator"
9787 [(match_operand:SI 2 "s_register_operand"
9788 "l,r,r,l,l,r,r,r,r")
9789 (match_operand:SI 3 "arm_add_operand"
9790 "lPy,rI,L,lPy,lPy,rI,rI,L,L")]))
9791 (const_int 0)))]
9792 "TARGET_32BIT"
9793 "*
9794 {
9795 static const char *const cmp1[NUM_OF_COND_CMP][2] =
9796 {
9797 {\"cmp\\t%0, %1\",
9798 \"cmp\\t%2, %3\"},
9799 {\"cmn\\t%0, #%n1\",
9800 \"cmp\\t%2, %3\"},
9801 {\"cmp\\t%0, %1\",
9802 \"cmn\\t%2, #%n3\"},
9803 {\"cmn\\t%0, #%n1\",
9804 \"cmn\\t%2, #%n3\"}
9805 };
9806 static const char *const cmp2[NUM_OF_COND_CMP][2] =
9807 {
9808 {\"cmp%D4\\t%2, %3\",
9809 \"cmp%D5\\t%0, %1\"},
9810 {\"cmp%D4\\t%2, %3\",
9811 \"cmn%D5\\t%0, #%n1\"},
9812 {\"cmn%D4\\t%2, #%n3\",
9813 \"cmp%D5\\t%0, %1\"},
9814 {\"cmn%D4\\t%2, #%n3\",
9815 \"cmn%D5\\t%0, #%n1\"}
9816 };
9817 static const char *const ite[2] =
9818 {
9819 \"it\\t%D4\",
9820 \"it\\t%D5\"
9821 };
9822 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
9823 CMP_CMP, CMN_CMP, CMP_CMP,
9824 CMN_CMP, CMP_CMN, CMN_CMN};
9825 int swap =
9826 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
9827
9828 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
9829 if (TARGET_THUMB2) {
9830 output_asm_insn (ite[swap], operands);
9831 }
9832 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
9833 return \"\";
9834 }
9835 "
9836 [(set_attr "conds" "set")
9837 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
9838 (set_attr "enabled_for_short_it" "yes,no,no,no,no,no,no,no,no")
9839 (set_attr_alternative "length"
9840 [(const_int 6)
9841 (const_int 8)
9842 (const_int 8)
9843 (const_int 8)
9844 (const_int 8)
9845 (if_then_else (eq_attr "is_thumb" "no")
9846 (const_int 8)
9847 (const_int 10))
9848 (if_then_else (eq_attr "is_thumb" "no")
9849 (const_int 8)
9850 (const_int 10))
9851 (if_then_else (eq_attr "is_thumb" "no")
9852 (const_int 8)
9853 (const_int 10))
9854 (if_then_else (eq_attr "is_thumb" "no")
9855 (const_int 8)
9856 (const_int 10))])
9857 (set_attr "type" "multiple")]
9858 )
9859
9860 (define_insn_and_split "*ior_scc_scc"
9861 [(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts")
9862 (ior:SI (match_operator:SI 3 "arm_comparison_operator"
9863 [(match_operand:SI 1 "s_register_operand" "l,r")
9864 (match_operand:SI 2 "arm_add_operand" "lPy,rIL")])
9865 (match_operator:SI 6 "arm_comparison_operator"
9866 [(match_operand:SI 4 "s_register_operand" "l,r")
9867 (match_operand:SI 5 "arm_add_operand" "lPy,rIL")])))
9868 (clobber (reg:CC CC_REGNUM))]
9869 "TARGET_32BIT
9870 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_OR_Y)
9871 != CCmode)"
9872 "#"
9873 "TARGET_32BIT && reload_completed"
9874 [(set (match_dup 7)
9875 (compare
9876 (ior:SI
9877 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9878 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9879 (const_int 0)))
9880 (set (match_dup 0) (ne:SI (match_dup 7) (const_int 0)))]
9881 "operands[7]
9882 = gen_rtx_REG (arm_select_dominance_cc_mode (operands[3], operands[6],
9883 DOM_CC_X_OR_Y),
9884 CC_REGNUM);"
9885 [(set_attr "conds" "clob")
9886 (set_attr "enabled_for_short_it" "yes,no")
9887 (set_attr "length" "16")
9888 (set_attr "type" "multiple")]
9889 )
9890
9891 ; If the above pattern is followed by a CMP insn, then the compare is
9892 ; redundant, since we can rework the conditional instruction that follows.
9893 (define_insn_and_split "*ior_scc_scc_cmp"
9894 [(set (match_operand 0 "dominant_cc_register" "")
9895 (compare (ior:SI (match_operator:SI 3 "arm_comparison_operator"
9896 [(match_operand:SI 1 "s_register_operand" "l,r")
9897 (match_operand:SI 2 "arm_add_operand" "lPy,rIL")])
9898 (match_operator:SI 6 "arm_comparison_operator"
9899 [(match_operand:SI 4 "s_register_operand" "l,r")
9900 (match_operand:SI 5 "arm_add_operand" "lPy,rIL")]))
9901 (const_int 0)))
9902 (set (match_operand:SI 7 "s_register_operand" "=Ts,Ts")
9903 (ior:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9904 (match_op_dup 6 [(match_dup 4) (match_dup 5)])))]
9905 "TARGET_32BIT"
9906 "#"
9907 "TARGET_32BIT && reload_completed"
9908 [(set (match_dup 0)
9909 (compare
9910 (ior:SI
9911 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9912 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9913 (const_int 0)))
9914 (set (match_dup 7) (ne:SI (match_dup 0) (const_int 0)))]
9915 ""
9916 [(set_attr "conds" "set")
9917 (set_attr "enabled_for_short_it" "yes,no")
9918 (set_attr "length" "16")
9919 (set_attr "type" "multiple")]
9920 )
9921
9922 (define_insn_and_split "*and_scc_scc"
9923 [(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts")
9924 (and:SI (match_operator:SI 3 "arm_comparison_operator"
9925 [(match_operand:SI 1 "s_register_operand" "l,r")
9926 (match_operand:SI 2 "arm_add_operand" "lPy,rIL")])
9927 (match_operator:SI 6 "arm_comparison_operator"
9928 [(match_operand:SI 4 "s_register_operand" "l,r")
9929 (match_operand:SI 5 "arm_add_operand" "lPy,rIL")])))
9930 (clobber (reg:CC CC_REGNUM))]
9931 "TARGET_32BIT
9932 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
9933 != CCmode)"
9934 "#"
9935 "TARGET_32BIT && reload_completed
9936 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
9937 != CCmode)"
9938 [(set (match_dup 7)
9939 (compare
9940 (and:SI
9941 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9942 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9943 (const_int 0)))
9944 (set (match_dup 0) (ne:SI (match_dup 7) (const_int 0)))]
9945 "operands[7]
9946 = gen_rtx_REG (arm_select_dominance_cc_mode (operands[3], operands[6],
9947 DOM_CC_X_AND_Y),
9948 CC_REGNUM);"
9949 [(set_attr "conds" "clob")
9950 (set_attr "enabled_for_short_it" "yes,no")
9951 (set_attr "length" "16")
9952 (set_attr "type" "multiple")]
9953 )
9954
9955 ; If the above pattern is followed by a CMP insn, then the compare is
9956 ; redundant, since we can rework the conditional instruction that follows.
9957 (define_insn_and_split "*and_scc_scc_cmp"
9958 [(set (match_operand 0 "dominant_cc_register" "")
9959 (compare (and:SI (match_operator:SI 3 "arm_comparison_operator"
9960 [(match_operand:SI 1 "s_register_operand" "l,r")
9961 (match_operand:SI 2 "arm_add_operand" "lPy,rIL")])
9962 (match_operator:SI 6 "arm_comparison_operator"
9963 [(match_operand:SI 4 "s_register_operand" "l,r")
9964 (match_operand:SI 5 "arm_add_operand" "lPy,rIL")]))
9965 (const_int 0)))
9966 (set (match_operand:SI 7 "s_register_operand" "=Ts,Ts")
9967 (and:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9968 (match_op_dup 6 [(match_dup 4) (match_dup 5)])))]
9969 "TARGET_32BIT"
9970 "#"
9971 "TARGET_32BIT && reload_completed"
9972 [(set (match_dup 0)
9973 (compare
9974 (and:SI
9975 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9976 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9977 (const_int 0)))
9978 (set (match_dup 7) (ne:SI (match_dup 0) (const_int 0)))]
9979 ""
9980 [(set_attr "conds" "set")
9981 (set_attr "enabled_for_short_it" "yes,no")
9982 (set_attr "length" "16")
9983 (set_attr "type" "multiple")]
9984 )
9985
9986 ;; If there is no dominance in the comparison, then we can still save an
9987 ;; instruction in the AND case, since we can know that the second compare
9988 ;; need only zero the value if false (if true, then the value is already
9989 ;; correct).
9990 (define_insn_and_split "*and_scc_scc_nodom"
9991 [(set (match_operand:SI 0 "s_register_operand" "=&Ts,&Ts,&Ts")
9992 (and:SI (match_operator:SI 3 "arm_comparison_operator"
9993 [(match_operand:SI 1 "s_register_operand" "r,r,0")
9994 (match_operand:SI 2 "arm_add_operand" "rIL,0,rIL")])
9995 (match_operator:SI 6 "arm_comparison_operator"
9996 [(match_operand:SI 4 "s_register_operand" "r,r,r")
9997 (match_operand:SI 5 "arm_add_operand" "rIL,rIL,rIL")])))
9998 (clobber (reg:CC CC_REGNUM))]
9999 "TARGET_32BIT
10000 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
10001 == CCmode)"
10002 "#"
10003 "TARGET_32BIT && reload_completed"
10004 [(parallel [(set (match_dup 0)
10005 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
10006 (clobber (reg:CC CC_REGNUM))])
10007 (set (match_dup 7) (match_op_dup 8 [(match_dup 4) (match_dup 5)]))
10008 (set (match_dup 0)
10009 (if_then_else:SI (match_op_dup 6 [(match_dup 7) (const_int 0)])
10010 (match_dup 0)
10011 (const_int 0)))]
10012 "operands[7] = gen_rtx_REG (SELECT_CC_MODE (GET_CODE (operands[6]),
10013 operands[4], operands[5]),
10014 CC_REGNUM);
10015 operands[8] = gen_rtx_COMPARE (GET_MODE (operands[7]), operands[4],
10016 operands[5]);"
10017 [(set_attr "conds" "clob")
10018 (set_attr "length" "20")
10019 (set_attr "type" "multiple")]
10020 )
10021
10022 (define_split
10023 [(set (reg:CC_NOOV CC_REGNUM)
10024 (compare:CC_NOOV (ior:SI
10025 (and:SI (match_operand:SI 0 "s_register_operand" "")
10026 (const_int 1))
10027 (match_operator:SI 1 "arm_comparison_operator"
10028 [(match_operand:SI 2 "s_register_operand" "")
10029 (match_operand:SI 3 "arm_add_operand" "")]))
10030 (const_int 0)))
10031 (clobber (match_operand:SI 4 "s_register_operand" ""))]
10032 "TARGET_ARM"
10033 [(set (match_dup 4)
10034 (ior:SI (match_op_dup 1 [(match_dup 2) (match_dup 3)])
10035 (match_dup 0)))
10036 (set (reg:CC_NOOV CC_REGNUM)
10037 (compare:CC_NOOV (and:SI (match_dup 4) (const_int 1))
10038 (const_int 0)))]
10039 "")
10040
10041 (define_split
10042 [(set (reg:CC_NOOV CC_REGNUM)
10043 (compare:CC_NOOV (ior:SI
10044 (match_operator:SI 1 "arm_comparison_operator"
10045 [(match_operand:SI 2 "s_register_operand" "")
10046 (match_operand:SI 3 "arm_add_operand" "")])
10047 (and:SI (match_operand:SI 0 "s_register_operand" "")
10048 (const_int 1)))
10049 (const_int 0)))
10050 (clobber (match_operand:SI 4 "s_register_operand" ""))]
10051 "TARGET_ARM"
10052 [(set (match_dup 4)
10053 (ior:SI (match_op_dup 1 [(match_dup 2) (match_dup 3)])
10054 (match_dup 0)))
10055 (set (reg:CC_NOOV CC_REGNUM)
10056 (compare:CC_NOOV (and:SI (match_dup 4) (const_int 1))
10057 (const_int 0)))]
10058 "")
10059 ;; ??? The conditional patterns above need checking for Thumb-2 usefulness
10060
10061 (define_insn_and_split "*negscc"
10062 [(set (match_operand:SI 0 "s_register_operand" "=r")
10063 (neg:SI (match_operator 3 "arm_comparison_operator"
10064 [(match_operand:SI 1 "s_register_operand" "r")
10065 (match_operand:SI 2 "arm_rhs_operand" "rI")])))
10066 (clobber (reg:CC CC_REGNUM))]
10067 "TARGET_ARM"
10068 "#"
10069 "&& reload_completed"
10070 [(const_int 0)]
10071 {
10072 rtx cc_reg = gen_rtx_REG (CCmode, CC_REGNUM);
10073
10074 if (GET_CODE (operands[3]) == LT && operands[2] == const0_rtx)
10075 {
10076 /* Emit mov\\t%0, %1, asr #31 */
10077 emit_insn (gen_rtx_SET (operands[0],
10078 gen_rtx_ASHIFTRT (SImode,
10079 operands[1],
10080 GEN_INT (31))));
10081 DONE;
10082 }
10083 else if (GET_CODE (operands[3]) == NE)
10084 {
10085 /* Emit subs\\t%0, %1, %2\;mvnne\\t%0, #0 */
10086 if (CONST_INT_P (operands[2]))
10087 emit_insn (gen_cmpsi2_addneg (operands[0], operands[1], operands[2],
10088 gen_int_mode (-INTVAL (operands[2]),
10089 SImode)));
10090 else
10091 emit_insn (gen_subsi3_compare (operands[0], operands[1], operands[2]));
10092
10093 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
10094 gen_rtx_NE (SImode,
10095 cc_reg,
10096 const0_rtx),
10097 gen_rtx_SET (operands[0],
10098 GEN_INT (~0))));
10099 DONE;
10100 }
10101 else
10102 {
10103 /* Emit: cmp\\t%1, %2\;mov%D3\\t%0, #0\;mvn%d3\\t%0, #0 */
10104 emit_insn (gen_rtx_SET (cc_reg,
10105 gen_rtx_COMPARE (CCmode, operands[1], operands[2])));
10106 enum rtx_code rc = GET_CODE (operands[3]);
10107
10108 rc = reverse_condition (rc);
10109 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
10110 gen_rtx_fmt_ee (rc,
10111 VOIDmode,
10112 cc_reg,
10113 const0_rtx),
10114 gen_rtx_SET (operands[0], const0_rtx)));
10115 rc = GET_CODE (operands[3]);
10116 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
10117 gen_rtx_fmt_ee (rc,
10118 VOIDmode,
10119 cc_reg,
10120 const0_rtx),
10121 gen_rtx_SET (operands[0],
10122 GEN_INT (~0))));
10123 DONE;
10124 }
10125 FAIL;
10126 }
10127 [(set_attr "conds" "clob")
10128 (set_attr "length" "12")
10129 (set_attr "type" "multiple")]
10130 )
10131
10132 (define_insn_and_split "movcond_addsi"
10133 [(set (match_operand:SI 0 "s_register_operand" "=r,l,r")
10134 (if_then_else:SI
10135 (match_operator 5 "comparison_operator"
10136 [(plus:SI (match_operand:SI 3 "s_register_operand" "r,r,r")
10137 (match_operand:SI 4 "arm_add_operand" "rIL,rIL,rIL"))
10138 (const_int 0)])
10139 (match_operand:SI 1 "arm_rhs_operand" "rI,rPy,r")
10140 (match_operand:SI 2 "arm_rhs_operand" "rI,rPy,r")))
10141 (clobber (reg:CC CC_REGNUM))]
10142 "TARGET_32BIT"
10143 "#"
10144 "&& reload_completed"
10145 [(set (reg:CC_NOOV CC_REGNUM)
10146 (compare:CC_NOOV
10147 (plus:SI (match_dup 3)
10148 (match_dup 4))
10149 (const_int 0)))
10150 (set (match_dup 0) (match_dup 1))
10151 (cond_exec (match_dup 6)
10152 (set (match_dup 0) (match_dup 2)))]
10153 "
10154 {
10155 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[5]),
10156 operands[3], operands[4]);
10157 enum rtx_code rc = GET_CODE (operands[5]);
10158 operands[6] = gen_rtx_REG (mode, CC_REGNUM);
10159 gcc_assert (!(mode == CCFPmode || mode == CCFPEmode));
10160 if (!REG_P (operands[2]) || REGNO (operands[2]) != REGNO (operands[0]))
10161 rc = reverse_condition (rc);
10162 else
10163 std::swap (operands[1], operands[2]);
10164
10165 operands[6] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
10166 }
10167 "
10168 [(set_attr "conds" "clob")
10169 (set_attr "enabled_for_short_it" "no,yes,yes")
10170 (set_attr "type" "multiple")]
10171 )
10172
10173 (define_insn "movcond"
10174 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
10175 (if_then_else:SI
10176 (match_operator 5 "arm_comparison_operator"
10177 [(match_operand:SI 3 "s_register_operand" "r,r,r")
10178 (match_operand:SI 4 "arm_add_operand" "rIL,rIL,rIL")])
10179 (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
10180 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
10181 (clobber (reg:CC CC_REGNUM))]
10182 "TARGET_ARM"
10183 "*
10184 if (GET_CODE (operands[5]) == LT
10185 && (operands[4] == const0_rtx))
10186 {
10187 if (which_alternative != 1 && REG_P (operands[1]))
10188 {
10189 if (operands[2] == const0_rtx)
10190 return \"and\\t%0, %1, %3, asr #31\";
10191 return \"ands\\t%0, %1, %3, asr #32\;movcc\\t%0, %2\";
10192 }
10193 else if (which_alternative != 0 && REG_P (operands[2]))
10194 {
10195 if (operands[1] == const0_rtx)
10196 return \"bic\\t%0, %2, %3, asr #31\";
10197 return \"bics\\t%0, %2, %3, asr #32\;movcs\\t%0, %1\";
10198 }
10199 /* The only case that falls through to here is when both ops 1 & 2
10200 are constants. */
10201 }
10202
10203 if (GET_CODE (operands[5]) == GE
10204 && (operands[4] == const0_rtx))
10205 {
10206 if (which_alternative != 1 && REG_P (operands[1]))
10207 {
10208 if (operands[2] == const0_rtx)
10209 return \"bic\\t%0, %1, %3, asr #31\";
10210 return \"bics\\t%0, %1, %3, asr #32\;movcs\\t%0, %2\";
10211 }
10212 else if (which_alternative != 0 && REG_P (operands[2]))
10213 {
10214 if (operands[1] == const0_rtx)
10215 return \"and\\t%0, %2, %3, asr #31\";
10216 return \"ands\\t%0, %2, %3, asr #32\;movcc\\t%0, %1\";
10217 }
10218 /* The only case that falls through to here is when both ops 1 & 2
10219 are constants. */
10220 }
10221 if (CONST_INT_P (operands[4])
10222 && !const_ok_for_arm (INTVAL (operands[4])))
10223 output_asm_insn (\"cmn\\t%3, #%n4\", operands);
10224 else
10225 output_asm_insn (\"cmp\\t%3, %4\", operands);
10226 if (which_alternative != 0)
10227 output_asm_insn (\"mov%d5\\t%0, %1\", operands);
10228 if (which_alternative != 1)
10229 output_asm_insn (\"mov%D5\\t%0, %2\", operands);
10230 return \"\";
10231 "
10232 [(set_attr "conds" "clob")
10233 (set_attr "length" "8,8,12")
10234 (set_attr "type" "multiple")]
10235 )
10236
10237 ;; ??? The patterns below need checking for Thumb-2 usefulness.
10238
10239 (define_insn "*ifcompare_plus_move"
10240 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10241 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
10242 [(match_operand:SI 4 "s_register_operand" "r,r")
10243 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
10244 (plus:SI
10245 (match_operand:SI 2 "s_register_operand" "r,r")
10246 (match_operand:SI 3 "arm_add_operand" "rIL,rIL"))
10247 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))
10248 (clobber (reg:CC CC_REGNUM))]
10249 "TARGET_ARM"
10250 "#"
10251 [(set_attr "conds" "clob")
10252 (set_attr "length" "8,12")
10253 (set_attr "type" "multiple")]
10254 )
10255
10256 (define_insn "*if_plus_move"
10257 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
10258 (if_then_else:SI
10259 (match_operator 4 "arm_comparison_operator"
10260 [(match_operand 5 "cc_register" "") (const_int 0)])
10261 (plus:SI
10262 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
10263 (match_operand:SI 3 "arm_add_operand" "rI,L,rI,L"))
10264 (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")))]
10265 "TARGET_ARM"
10266 "@
10267 add%d4\\t%0, %2, %3
10268 sub%d4\\t%0, %2, #%n3
10269 add%d4\\t%0, %2, %3\;mov%D4\\t%0, %1
10270 sub%d4\\t%0, %2, #%n3\;mov%D4\\t%0, %1"
10271 [(set_attr "conds" "use")
10272 (set_attr "length" "4,4,8,8")
10273 (set_attr_alternative "type"
10274 [(if_then_else (match_operand 3 "const_int_operand" "")
10275 (const_string "alu_imm" )
10276 (const_string "alu_sreg"))
10277 (const_string "alu_imm")
10278 (const_string "multiple")
10279 (const_string "multiple")])]
10280 )
10281
10282 (define_insn "*ifcompare_move_plus"
10283 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10284 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
10285 [(match_operand:SI 4 "s_register_operand" "r,r")
10286 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
10287 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
10288 (plus:SI
10289 (match_operand:SI 2 "s_register_operand" "r,r")
10290 (match_operand:SI 3 "arm_add_operand" "rIL,rIL"))))
10291 (clobber (reg:CC CC_REGNUM))]
10292 "TARGET_ARM"
10293 "#"
10294 [(set_attr "conds" "clob")
10295 (set_attr "length" "8,12")
10296 (set_attr "type" "multiple")]
10297 )
10298
10299 (define_insn "*if_move_plus"
10300 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
10301 (if_then_else:SI
10302 (match_operator 4 "arm_comparison_operator"
10303 [(match_operand 5 "cc_register" "") (const_int 0)])
10304 (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")
10305 (plus:SI
10306 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
10307 (match_operand:SI 3 "arm_add_operand" "rI,L,rI,L"))))]
10308 "TARGET_ARM"
10309 "@
10310 add%D4\\t%0, %2, %3
10311 sub%D4\\t%0, %2, #%n3
10312 add%D4\\t%0, %2, %3\;mov%d4\\t%0, %1
10313 sub%D4\\t%0, %2, #%n3\;mov%d4\\t%0, %1"
10314 [(set_attr "conds" "use")
10315 (set_attr "length" "4,4,8,8")
10316 (set_attr_alternative "type"
10317 [(if_then_else (match_operand 3 "const_int_operand" "")
10318 (const_string "alu_imm" )
10319 (const_string "alu_sreg"))
10320 (const_string "alu_imm")
10321 (const_string "multiple")
10322 (const_string "multiple")])]
10323 )
10324
10325 (define_insn "*ifcompare_arith_arith"
10326 [(set (match_operand:SI 0 "s_register_operand" "=r")
10327 (if_then_else:SI (match_operator 9 "arm_comparison_operator"
10328 [(match_operand:SI 5 "s_register_operand" "r")
10329 (match_operand:SI 6 "arm_add_operand" "rIL")])
10330 (match_operator:SI 8 "shiftable_operator"
10331 [(match_operand:SI 1 "s_register_operand" "r")
10332 (match_operand:SI 2 "arm_rhs_operand" "rI")])
10333 (match_operator:SI 7 "shiftable_operator"
10334 [(match_operand:SI 3 "s_register_operand" "r")
10335 (match_operand:SI 4 "arm_rhs_operand" "rI")])))
10336 (clobber (reg:CC CC_REGNUM))]
10337 "TARGET_ARM"
10338 "#"
10339 [(set_attr "conds" "clob")
10340 (set_attr "length" "12")
10341 (set_attr "type" "multiple")]
10342 )
10343
10344 (define_insn "*if_arith_arith"
10345 [(set (match_operand:SI 0 "s_register_operand" "=r")
10346 (if_then_else:SI (match_operator 5 "arm_comparison_operator"
10347 [(match_operand 8 "cc_register" "") (const_int 0)])
10348 (match_operator:SI 6 "shiftable_operator"
10349 [(match_operand:SI 1 "s_register_operand" "r")
10350 (match_operand:SI 2 "arm_rhs_operand" "rI")])
10351 (match_operator:SI 7 "shiftable_operator"
10352 [(match_operand:SI 3 "s_register_operand" "r")
10353 (match_operand:SI 4 "arm_rhs_operand" "rI")])))]
10354 "TARGET_ARM"
10355 "%I6%d5\\t%0, %1, %2\;%I7%D5\\t%0, %3, %4"
10356 [(set_attr "conds" "use")
10357 (set_attr "length" "8")
10358 (set_attr "type" "multiple")]
10359 )
10360
10361 (define_insn "*ifcompare_arith_move"
10362 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10363 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
10364 [(match_operand:SI 2 "s_register_operand" "r,r")
10365 (match_operand:SI 3 "arm_add_operand" "rIL,rIL")])
10366 (match_operator:SI 7 "shiftable_operator"
10367 [(match_operand:SI 4 "s_register_operand" "r,r")
10368 (match_operand:SI 5 "arm_rhs_operand" "rI,rI")])
10369 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))
10370 (clobber (reg:CC CC_REGNUM))]
10371 "TARGET_ARM"
10372 "*
10373 /* If we have an operation where (op x 0) is the identity operation and
10374 the conditional operator is LT or GE and we are comparing against zero and
10375 everything is in registers then we can do this in two instructions. */
10376 if (operands[3] == const0_rtx
10377 && GET_CODE (operands[7]) != AND
10378 && REG_P (operands[5])
10379 && REG_P (operands[1])
10380 && REGNO (operands[1]) == REGNO (operands[4])
10381 && REGNO (operands[4]) != REGNO (operands[0]))
10382 {
10383 if (GET_CODE (operands[6]) == LT)
10384 return \"and\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\";
10385 else if (GET_CODE (operands[6]) == GE)
10386 return \"bic\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\";
10387 }
10388 if (CONST_INT_P (operands[3])
10389 && !const_ok_for_arm (INTVAL (operands[3])))
10390 output_asm_insn (\"cmn\\t%2, #%n3\", operands);
10391 else
10392 output_asm_insn (\"cmp\\t%2, %3\", operands);
10393 output_asm_insn (\"%I7%d6\\t%0, %4, %5\", operands);
10394 if (which_alternative != 0)
10395 return \"mov%D6\\t%0, %1\";
10396 return \"\";
10397 "
10398 [(set_attr "conds" "clob")
10399 (set_attr "length" "8,12")
10400 (set_attr "type" "multiple")]
10401 )
10402
10403 (define_insn "*if_arith_move"
10404 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10405 (if_then_else:SI (match_operator 4 "arm_comparison_operator"
10406 [(match_operand 6 "cc_register" "") (const_int 0)])
10407 (match_operator:SI 5 "shiftable_operator"
10408 [(match_operand:SI 2 "s_register_operand" "r,r")
10409 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
10410 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))]
10411 "TARGET_ARM"
10412 "@
10413 %I5%d4\\t%0, %2, %3
10414 %I5%d4\\t%0, %2, %3\;mov%D4\\t%0, %1"
10415 [(set_attr "conds" "use")
10416 (set_attr "length" "4,8")
10417 (set_attr_alternative "type"
10418 [(if_then_else (match_operand 3 "const_int_operand" "")
10419 (const_string "alu_shift_imm" )
10420 (const_string "alu_shift_reg"))
10421 (const_string "multiple")])]
10422 )
10423
10424 (define_insn "*ifcompare_move_arith"
10425 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10426 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
10427 [(match_operand:SI 4 "s_register_operand" "r,r")
10428 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
10429 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
10430 (match_operator:SI 7 "shiftable_operator"
10431 [(match_operand:SI 2 "s_register_operand" "r,r")
10432 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
10433 (clobber (reg:CC CC_REGNUM))]
10434 "TARGET_ARM"
10435 "*
10436 /* If we have an operation where (op x 0) is the identity operation and
10437 the conditional operator is LT or GE and we are comparing against zero and
10438 everything is in registers then we can do this in two instructions */
10439 if (operands[5] == const0_rtx
10440 && GET_CODE (operands[7]) != AND
10441 && REG_P (operands[3])
10442 && REG_P (operands[1])
10443 && REGNO (operands[1]) == REGNO (operands[2])
10444 && REGNO (operands[2]) != REGNO (operands[0]))
10445 {
10446 if (GET_CODE (operands[6]) == GE)
10447 return \"and\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\";
10448 else if (GET_CODE (operands[6]) == LT)
10449 return \"bic\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\";
10450 }
10451
10452 if (CONST_INT_P (operands[5])
10453 && !const_ok_for_arm (INTVAL (operands[5])))
10454 output_asm_insn (\"cmn\\t%4, #%n5\", operands);
10455 else
10456 output_asm_insn (\"cmp\\t%4, %5\", operands);
10457
10458 if (which_alternative != 0)
10459 output_asm_insn (\"mov%d6\\t%0, %1\", operands);
10460 return \"%I7%D6\\t%0, %2, %3\";
10461 "
10462 [(set_attr "conds" "clob")
10463 (set_attr "length" "8,12")
10464 (set_attr "type" "multiple")]
10465 )
10466
10467 (define_insn "*if_move_arith"
10468 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10469 (if_then_else:SI
10470 (match_operator 4 "arm_comparison_operator"
10471 [(match_operand 6 "cc_register" "") (const_int 0)])
10472 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
10473 (match_operator:SI 5 "shiftable_operator"
10474 [(match_operand:SI 2 "s_register_operand" "r,r")
10475 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))]
10476 "TARGET_ARM"
10477 "@
10478 %I5%D4\\t%0, %2, %3
10479 %I5%D4\\t%0, %2, %3\;mov%d4\\t%0, %1"
10480 [(set_attr "conds" "use")
10481 (set_attr "length" "4,8")
10482 (set_attr_alternative "type"
10483 [(if_then_else (match_operand 3 "const_int_operand" "")
10484 (const_string "alu_shift_imm" )
10485 (const_string "alu_shift_reg"))
10486 (const_string "multiple")])]
10487 )
10488
10489 (define_insn "*ifcompare_move_not"
10490 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10491 (if_then_else:SI
10492 (match_operator 5 "arm_comparison_operator"
10493 [(match_operand:SI 3 "s_register_operand" "r,r")
10494 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
10495 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
10496 (not:SI
10497 (match_operand:SI 2 "s_register_operand" "r,r"))))
10498 (clobber (reg:CC CC_REGNUM))]
10499 "TARGET_ARM"
10500 "#"
10501 [(set_attr "conds" "clob")
10502 (set_attr "length" "8,12")
10503 (set_attr "type" "multiple")]
10504 )
10505
10506 (define_insn "*if_move_not"
10507 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
10508 (if_then_else:SI
10509 (match_operator 4 "arm_comparison_operator"
10510 [(match_operand 3 "cc_register" "") (const_int 0)])
10511 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
10512 (not:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))))]
10513 "TARGET_ARM"
10514 "@
10515 mvn%D4\\t%0, %2
10516 mov%d4\\t%0, %1\;mvn%D4\\t%0, %2
10517 mvn%d4\\t%0, #%B1\;mvn%D4\\t%0, %2"
10518 [(set_attr "conds" "use")
10519 (set_attr "type" "mvn_reg")
10520 (set_attr "length" "4,8,8")
10521 (set_attr "type" "mvn_reg,multiple,multiple")]
10522 )
10523
10524 (define_insn "*ifcompare_not_move"
10525 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10526 (if_then_else:SI
10527 (match_operator 5 "arm_comparison_operator"
10528 [(match_operand:SI 3 "s_register_operand" "r,r")
10529 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
10530 (not:SI
10531 (match_operand:SI 2 "s_register_operand" "r,r"))
10532 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
10533 (clobber (reg:CC CC_REGNUM))]
10534 "TARGET_ARM"
10535 "#"
10536 [(set_attr "conds" "clob")
10537 (set_attr "length" "8,12")
10538 (set_attr "type" "multiple")]
10539 )
10540
10541 (define_insn "*if_not_move"
10542 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
10543 (if_then_else:SI
10544 (match_operator 4 "arm_comparison_operator"
10545 [(match_operand 3 "cc_register" "") (const_int 0)])
10546 (not:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))
10547 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
10548 "TARGET_ARM"
10549 "@
10550 mvn%d4\\t%0, %2
10551 mov%D4\\t%0, %1\;mvn%d4\\t%0, %2
10552 mvn%D4\\t%0, #%B1\;mvn%d4\\t%0, %2"
10553 [(set_attr "conds" "use")
10554 (set_attr "type" "mvn_reg,multiple,multiple")
10555 (set_attr "length" "4,8,8")]
10556 )
10557
10558 (define_insn "*ifcompare_shift_move"
10559 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10560 (if_then_else:SI
10561 (match_operator 6 "arm_comparison_operator"
10562 [(match_operand:SI 4 "s_register_operand" "r,r")
10563 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
10564 (match_operator:SI 7 "shift_operator"
10565 [(match_operand:SI 2 "s_register_operand" "r,r")
10566 (match_operand:SI 3 "arm_rhs_operand" "rM,rM")])
10567 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
10568 (clobber (reg:CC CC_REGNUM))]
10569 "TARGET_ARM"
10570 "#"
10571 [(set_attr "conds" "clob")
10572 (set_attr "length" "8,12")
10573 (set_attr "type" "multiple")]
10574 )
10575
10576 (define_insn "*if_shift_move"
10577 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
10578 (if_then_else:SI
10579 (match_operator 5 "arm_comparison_operator"
10580 [(match_operand 6 "cc_register" "") (const_int 0)])
10581 (match_operator:SI 4 "shift_operator"
10582 [(match_operand:SI 2 "s_register_operand" "r,r,r")
10583 (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM")])
10584 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
10585 "TARGET_ARM"
10586 "@
10587 mov%d5\\t%0, %2%S4
10588 mov%D5\\t%0, %1\;mov%d5\\t%0, %2%S4
10589 mvn%D5\\t%0, #%B1\;mov%d5\\t%0, %2%S4"
10590 [(set_attr "conds" "use")
10591 (set_attr "shift" "2")
10592 (set_attr "length" "4,8,8")
10593 (set_attr_alternative "type"
10594 [(if_then_else (match_operand 3 "const_int_operand" "")
10595 (const_string "mov_shift" )
10596 (const_string "mov_shift_reg"))
10597 (const_string "multiple")
10598 (const_string "multiple")])]
10599 )
10600
10601 (define_insn "*ifcompare_move_shift"
10602 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10603 (if_then_else:SI
10604 (match_operator 6 "arm_comparison_operator"
10605 [(match_operand:SI 4 "s_register_operand" "r,r")
10606 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
10607 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
10608 (match_operator:SI 7 "shift_operator"
10609 [(match_operand:SI 2 "s_register_operand" "r,r")
10610 (match_operand:SI 3 "arm_rhs_operand" "rM,rM")])))
10611 (clobber (reg:CC CC_REGNUM))]
10612 "TARGET_ARM"
10613 "#"
10614 [(set_attr "conds" "clob")
10615 (set_attr "length" "8,12")
10616 (set_attr "type" "multiple")]
10617 )
10618
10619 (define_insn "*if_move_shift"
10620 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
10621 (if_then_else:SI
10622 (match_operator 5 "arm_comparison_operator"
10623 [(match_operand 6 "cc_register" "") (const_int 0)])
10624 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
10625 (match_operator:SI 4 "shift_operator"
10626 [(match_operand:SI 2 "s_register_operand" "r,r,r")
10627 (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM")])))]
10628 "TARGET_ARM"
10629 "@
10630 mov%D5\\t%0, %2%S4
10631 mov%d5\\t%0, %1\;mov%D5\\t%0, %2%S4
10632 mvn%d5\\t%0, #%B1\;mov%D5\\t%0, %2%S4"
10633 [(set_attr "conds" "use")
10634 (set_attr "shift" "2")
10635 (set_attr "length" "4,8,8")
10636 (set_attr_alternative "type"
10637 [(if_then_else (match_operand 3 "const_int_operand" "")
10638 (const_string "mov_shift" )
10639 (const_string "mov_shift_reg"))
10640 (const_string "multiple")
10641 (const_string "multiple")])]
10642 )
10643
10644 (define_insn "*ifcompare_shift_shift"
10645 [(set (match_operand:SI 0 "s_register_operand" "=r")
10646 (if_then_else:SI
10647 (match_operator 7 "arm_comparison_operator"
10648 [(match_operand:SI 5 "s_register_operand" "r")
10649 (match_operand:SI 6 "arm_add_operand" "rIL")])
10650 (match_operator:SI 8 "shift_operator"
10651 [(match_operand:SI 1 "s_register_operand" "r")
10652 (match_operand:SI 2 "arm_rhs_operand" "rM")])
10653 (match_operator:SI 9 "shift_operator"
10654 [(match_operand:SI 3 "s_register_operand" "r")
10655 (match_operand:SI 4 "arm_rhs_operand" "rM")])))
10656 (clobber (reg:CC CC_REGNUM))]
10657 "TARGET_ARM"
10658 "#"
10659 [(set_attr "conds" "clob")
10660 (set_attr "length" "12")
10661 (set_attr "type" "multiple")]
10662 )
10663
10664 (define_insn "*if_shift_shift"
10665 [(set (match_operand:SI 0 "s_register_operand" "=r")
10666 (if_then_else:SI
10667 (match_operator 5 "arm_comparison_operator"
10668 [(match_operand 8 "cc_register" "") (const_int 0)])
10669 (match_operator:SI 6 "shift_operator"
10670 [(match_operand:SI 1 "s_register_operand" "r")
10671 (match_operand:SI 2 "arm_rhs_operand" "rM")])
10672 (match_operator:SI 7 "shift_operator"
10673 [(match_operand:SI 3 "s_register_operand" "r")
10674 (match_operand:SI 4 "arm_rhs_operand" "rM")])))]
10675 "TARGET_ARM"
10676 "mov%d5\\t%0, %1%S6\;mov%D5\\t%0, %3%S7"
10677 [(set_attr "conds" "use")
10678 (set_attr "shift" "1")
10679 (set_attr "length" "8")
10680 (set (attr "type") (if_then_else
10681 (and (match_operand 2 "const_int_operand" "")
10682 (match_operand 4 "const_int_operand" ""))
10683 (const_string "mov_shift")
10684 (const_string "mov_shift_reg")))]
10685 )
10686
10687 (define_insn "*ifcompare_not_arith"
10688 [(set (match_operand:SI 0 "s_register_operand" "=r")
10689 (if_then_else:SI
10690 (match_operator 6 "arm_comparison_operator"
10691 [(match_operand:SI 4 "s_register_operand" "r")
10692 (match_operand:SI 5 "arm_add_operand" "rIL")])
10693 (not:SI (match_operand:SI 1 "s_register_operand" "r"))
10694 (match_operator:SI 7 "shiftable_operator"
10695 [(match_operand:SI 2 "s_register_operand" "r")
10696 (match_operand:SI 3 "arm_rhs_operand" "rI")])))
10697 (clobber (reg:CC CC_REGNUM))]
10698 "TARGET_ARM"
10699 "#"
10700 [(set_attr "conds" "clob")
10701 (set_attr "length" "12")
10702 (set_attr "type" "multiple")]
10703 )
10704
10705 (define_insn "*if_not_arith"
10706 [(set (match_operand:SI 0 "s_register_operand" "=r")
10707 (if_then_else:SI
10708 (match_operator 5 "arm_comparison_operator"
10709 [(match_operand 4 "cc_register" "") (const_int 0)])
10710 (not:SI (match_operand:SI 1 "s_register_operand" "r"))
10711 (match_operator:SI 6 "shiftable_operator"
10712 [(match_operand:SI 2 "s_register_operand" "r")
10713 (match_operand:SI 3 "arm_rhs_operand" "rI")])))]
10714 "TARGET_ARM"
10715 "mvn%d5\\t%0, %1\;%I6%D5\\t%0, %2, %3"
10716 [(set_attr "conds" "use")
10717 (set_attr "type" "mvn_reg")
10718 (set_attr "length" "8")]
10719 )
10720
10721 (define_insn "*ifcompare_arith_not"
10722 [(set (match_operand:SI 0 "s_register_operand" "=r")
10723 (if_then_else:SI
10724 (match_operator 6 "arm_comparison_operator"
10725 [(match_operand:SI 4 "s_register_operand" "r")
10726 (match_operand:SI 5 "arm_add_operand" "rIL")])
10727 (match_operator:SI 7 "shiftable_operator"
10728 [(match_operand:SI 2 "s_register_operand" "r")
10729 (match_operand:SI 3 "arm_rhs_operand" "rI")])
10730 (not:SI (match_operand:SI 1 "s_register_operand" "r"))))
10731 (clobber (reg:CC CC_REGNUM))]
10732 "TARGET_ARM"
10733 "#"
10734 [(set_attr "conds" "clob")
10735 (set_attr "length" "12")
10736 (set_attr "type" "multiple")]
10737 )
10738
10739 (define_insn "*if_arith_not"
10740 [(set (match_operand:SI 0 "s_register_operand" "=r")
10741 (if_then_else:SI
10742 (match_operator 5 "arm_comparison_operator"
10743 [(match_operand 4 "cc_register" "") (const_int 0)])
10744 (match_operator:SI 6 "shiftable_operator"
10745 [(match_operand:SI 2 "s_register_operand" "r")
10746 (match_operand:SI 3 "arm_rhs_operand" "rI")])
10747 (not:SI (match_operand:SI 1 "s_register_operand" "r"))))]
10748 "TARGET_ARM"
10749 "mvn%D5\\t%0, %1\;%I6%d5\\t%0, %2, %3"
10750 [(set_attr "conds" "use")
10751 (set_attr "type" "multiple")
10752 (set_attr "length" "8")]
10753 )
10754
10755 (define_insn "*ifcompare_neg_move"
10756 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10757 (if_then_else:SI
10758 (match_operator 5 "arm_comparison_operator"
10759 [(match_operand:SI 3 "s_register_operand" "r,r")
10760 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
10761 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r"))
10762 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
10763 (clobber (reg:CC CC_REGNUM))]
10764 "TARGET_ARM"
10765 "#"
10766 [(set_attr "conds" "clob")
10767 (set_attr "length" "8,12")
10768 (set_attr "type" "multiple")]
10769 )
10770
10771 (define_insn_and_split "*if_neg_move"
10772 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
10773 (if_then_else:SI
10774 (match_operator 4 "arm_comparison_operator"
10775 [(match_operand 3 "cc_register" "") (const_int 0)])
10776 (neg:SI (match_operand:SI 2 "s_register_operand" "l,r"))
10777 (match_operand:SI 1 "s_register_operand" "0,0")))]
10778 "TARGET_32BIT"
10779 "#"
10780 "&& reload_completed"
10781 [(cond_exec (match_op_dup 4 [(match_dup 3) (const_int 0)])
10782 (set (match_dup 0) (neg:SI (match_dup 2))))]
10783 ""
10784 [(set_attr "conds" "use")
10785 (set_attr "length" "4")
10786 (set_attr "arch" "t2,32")
10787 (set_attr "enabled_for_short_it" "yes,no")
10788 (set_attr "type" "logic_shift_imm")]
10789 )
10790
10791 (define_insn "*ifcompare_move_neg"
10792 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10793 (if_then_else:SI
10794 (match_operator 5 "arm_comparison_operator"
10795 [(match_operand:SI 3 "s_register_operand" "r,r")
10796 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
10797 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
10798 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r"))))
10799 (clobber (reg:CC CC_REGNUM))]
10800 "TARGET_ARM"
10801 "#"
10802 [(set_attr "conds" "clob")
10803 (set_attr "length" "8,12")
10804 (set_attr "type" "multiple")]
10805 )
10806
10807 (define_insn_and_split "*if_move_neg"
10808 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
10809 (if_then_else:SI
10810 (match_operator 4 "arm_comparison_operator"
10811 [(match_operand 3 "cc_register" "") (const_int 0)])
10812 (match_operand:SI 1 "s_register_operand" "0,0")
10813 (neg:SI (match_operand:SI 2 "s_register_operand" "l,r"))))]
10814 "TARGET_32BIT"
10815 "#"
10816 "&& reload_completed"
10817 [(cond_exec (match_dup 5)
10818 (set (match_dup 0) (neg:SI (match_dup 2))))]
10819 {
10820 machine_mode mode = GET_MODE (operands[3]);
10821 rtx_code rc = GET_CODE (operands[4]);
10822
10823 if (mode == CCFPmode || mode == CCFPEmode)
10824 rc = reverse_condition_maybe_unordered (rc);
10825 else
10826 rc = reverse_condition (rc);
10827
10828 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[3], const0_rtx);
10829 }
10830 [(set_attr "conds" "use")
10831 (set_attr "length" "4")
10832 (set_attr "arch" "t2,32")
10833 (set_attr "enabled_for_short_it" "yes,no")
10834 (set_attr "type" "logic_shift_imm")]
10835 )
10836
10837 (define_insn "*arith_adjacentmem"
10838 [(set (match_operand:SI 0 "s_register_operand" "=r")
10839 (match_operator:SI 1 "shiftable_operator"
10840 [(match_operand:SI 2 "memory_operand" "m")
10841 (match_operand:SI 3 "memory_operand" "m")]))
10842 (clobber (match_scratch:SI 4 "=r"))]
10843 "TARGET_ARM && adjacent_mem_locations (operands[2], operands[3])"
10844 "*
10845 {
10846 rtx ldm[3];
10847 rtx arith[4];
10848 rtx base_reg;
10849 HOST_WIDE_INT val1 = 0, val2 = 0;
10850
10851 if (REGNO (operands[0]) > REGNO (operands[4]))
10852 {
10853 ldm[1] = operands[4];
10854 ldm[2] = operands[0];
10855 }
10856 else
10857 {
10858 ldm[1] = operands[0];
10859 ldm[2] = operands[4];
10860 }
10861
10862 base_reg = XEXP (operands[2], 0);
10863
10864 if (!REG_P (base_reg))
10865 {
10866 val1 = INTVAL (XEXP (base_reg, 1));
10867 base_reg = XEXP (base_reg, 0);
10868 }
10869
10870 if (!REG_P (XEXP (operands[3], 0)))
10871 val2 = INTVAL (XEXP (XEXP (operands[3], 0), 1));
10872
10873 arith[0] = operands[0];
10874 arith[3] = operands[1];
10875
10876 if (val1 < val2)
10877 {
10878 arith[1] = ldm[1];
10879 arith[2] = ldm[2];
10880 }
10881 else
10882 {
10883 arith[1] = ldm[2];
10884 arith[2] = ldm[1];
10885 }
10886
10887 ldm[0] = base_reg;
10888 if (val1 !=0 && val2 != 0)
10889 {
10890 rtx ops[3];
10891
10892 if (val1 == 4 || val2 == 4)
10893 /* Other val must be 8, since we know they are adjacent and neither
10894 is zero. */
10895 output_asm_insn (\"ldmib%?\\t%0, {%1, %2}\", ldm);
10896 else if (const_ok_for_arm (val1) || const_ok_for_arm (-val1))
10897 {
10898 ldm[0] = ops[0] = operands[4];
10899 ops[1] = base_reg;
10900 ops[2] = GEN_INT (val1);
10901 output_add_immediate (ops);
10902 if (val1 < val2)
10903 output_asm_insn (\"ldmia%?\\t%0, {%1, %2}\", ldm);
10904 else
10905 output_asm_insn (\"ldmda%?\\t%0, {%1, %2}\", ldm);
10906 }
10907 else
10908 {
10909 /* Offset is out of range for a single add, so use two ldr. */
10910 ops[0] = ldm[1];
10911 ops[1] = base_reg;
10912 ops[2] = GEN_INT (val1);
10913 output_asm_insn (\"ldr%?\\t%0, [%1, %2]\", ops);
10914 ops[0] = ldm[2];
10915 ops[2] = GEN_INT (val2);
10916 output_asm_insn (\"ldr%?\\t%0, [%1, %2]\", ops);
10917 }
10918 }
10919 else if (val1 != 0)
10920 {
10921 if (val1 < val2)
10922 output_asm_insn (\"ldmda%?\\t%0, {%1, %2}\", ldm);
10923 else
10924 output_asm_insn (\"ldmia%?\\t%0, {%1, %2}\", ldm);
10925 }
10926 else
10927 {
10928 if (val1 < val2)
10929 output_asm_insn (\"ldmia%?\\t%0, {%1, %2}\", ldm);
10930 else
10931 output_asm_insn (\"ldmda%?\\t%0, {%1, %2}\", ldm);
10932 }
10933 output_asm_insn (\"%I3%?\\t%0, %1, %2\", arith);
10934 return \"\";
10935 }"
10936 [(set_attr "length" "12")
10937 (set_attr "predicable" "yes")
10938 (set_attr "type" "load_4")]
10939 )
10940
10941 ; This pattern is never tried by combine, so do it as a peephole
10942
10943 (define_peephole2
10944 [(set (match_operand:SI 0 "arm_general_register_operand" "")
10945 (match_operand:SI 1 "arm_general_register_operand" ""))
10946 (set (reg:CC CC_REGNUM)
10947 (compare:CC (match_dup 1) (const_int 0)))]
10948 "TARGET_ARM"
10949 [(parallel [(set (reg:CC CC_REGNUM) (compare:CC (match_dup 1) (const_int 0)))
10950 (set (match_dup 0) (match_dup 1))])]
10951 ""
10952 )
10953
10954 (define_split
10955 [(set (match_operand:SI 0 "s_register_operand" "")
10956 (and:SI (ge:SI (match_operand:SI 1 "s_register_operand" "")
10957 (const_int 0))
10958 (neg:SI (match_operator:SI 2 "arm_comparison_operator"
10959 [(match_operand:SI 3 "s_register_operand" "")
10960 (match_operand:SI 4 "arm_rhs_operand" "")]))))
10961 (clobber (match_operand:SI 5 "s_register_operand" ""))]
10962 "TARGET_ARM"
10963 [(set (match_dup 5) (not:SI (ashiftrt:SI (match_dup 1) (const_int 31))))
10964 (set (match_dup 0) (and:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
10965 (match_dup 5)))]
10966 ""
10967 )
10968
10969 ;; This split can be used because CC_Z mode implies that the following
10970 ;; branch will be an equality, or an unsigned inequality, so the sign
10971 ;; extension is not needed.
10972
10973 (define_split
10974 [(set (reg:CC_Z CC_REGNUM)
10975 (compare:CC_Z
10976 (ashift:SI (subreg:SI (match_operand:QI 0 "memory_operand" "") 0)
10977 (const_int 24))
10978 (match_operand 1 "const_int_operand" "")))
10979 (clobber (match_scratch:SI 2 ""))]
10980 "TARGET_ARM
10981 && ((UINTVAL (operands[1]))
10982 == ((UINTVAL (operands[1])) >> 24) << 24)"
10983 [(set (match_dup 2) (zero_extend:SI (match_dup 0)))
10984 (set (reg:CC CC_REGNUM) (compare:CC (match_dup 2) (match_dup 1)))]
10985 "
10986 operands[1] = GEN_INT (((unsigned long) INTVAL (operands[1])) >> 24);
10987 "
10988 )
10989 ;; ??? Check the patterns above for Thumb-2 usefulness
10990
10991 (define_expand "prologue"
10992 [(clobber (const_int 0))]
10993 "TARGET_EITHER"
10994 "if (TARGET_32BIT)
10995 arm_expand_prologue ();
10996 else
10997 thumb1_expand_prologue ();
10998 DONE;
10999 "
11000 )
11001
11002 (define_expand "epilogue"
11003 [(clobber (const_int 0))]
11004 "TARGET_EITHER"
11005 "
11006 if (crtl->calls_eh_return)
11007 emit_insn (gen_force_register_use (gen_rtx_REG (Pmode, 2)));
11008 if (TARGET_THUMB1)
11009 {
11010 thumb1_expand_epilogue ();
11011 emit_jump_insn (gen_rtx_UNSPEC_VOLATILE (VOIDmode,
11012 gen_rtvec (1, ret_rtx), VUNSPEC_EPILOGUE));
11013 }
11014 else if (HAVE_return)
11015 {
11016 /* HAVE_return is testing for USE_RETURN_INSN (FALSE). Hence,
11017 no need for explicit testing again. */
11018 emit_jump_insn (gen_return ());
11019 }
11020 else if (TARGET_32BIT)
11021 {
11022 arm_expand_epilogue (true);
11023 }
11024 DONE;
11025 "
11026 )
11027
11028 ;; Note - although unspec_volatile's USE all hard registers,
11029 ;; USEs are ignored after relaod has completed. Thus we need
11030 ;; to add an unspec of the link register to ensure that flow
11031 ;; does not think that it is unused by the sibcall branch that
11032 ;; will replace the standard function epilogue.
11033 (define_expand "sibcall_epilogue"
11034 [(parallel [(unspec:SI [(reg:SI LR_REGNUM)] UNSPEC_REGISTER_USE)
11035 (unspec_volatile [(return)] VUNSPEC_EPILOGUE)])]
11036 "TARGET_32BIT"
11037 "
11038 arm_expand_epilogue (false);
11039 DONE;
11040 "
11041 )
11042
11043 (define_expand "eh_epilogue"
11044 [(use (match_operand:SI 0 "register_operand" ""))
11045 (use (match_operand:SI 1 "register_operand" ""))
11046 (use (match_operand:SI 2 "register_operand" ""))]
11047 "TARGET_EITHER"
11048 "
11049 {
11050 cfun->machine->eh_epilogue_sp_ofs = operands[1];
11051 if (!REG_P (operands[2]) || REGNO (operands[2]) != 2)
11052 {
11053 rtx ra = gen_rtx_REG (Pmode, 2);
11054
11055 emit_move_insn (ra, operands[2]);
11056 operands[2] = ra;
11057 }
11058 /* This is a hack -- we may have crystalized the function type too
11059 early. */
11060 cfun->machine->func_type = 0;
11061 }"
11062 )
11063
11064 ;; This split is only used during output to reduce the number of patterns
11065 ;; that need assembler instructions adding to them. We allowed the setting
11066 ;; of the conditions to be implicit during rtl generation so that
11067 ;; the conditional compare patterns would work. However this conflicts to
11068 ;; some extent with the conditional data operations, so we have to split them
11069 ;; up again here.
11070
11071 ;; ??? Need to audit these splitters for Thumb-2. Why isn't normal
11072 ;; conditional execution sufficient?
11073
11074 (define_split
11075 [(set (match_operand:SI 0 "s_register_operand" "")
11076 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
11077 [(match_operand 2 "" "") (match_operand 3 "" "")])
11078 (match_dup 0)
11079 (match_operand 4 "" "")))
11080 (clobber (reg:CC CC_REGNUM))]
11081 "TARGET_ARM && reload_completed"
11082 [(set (match_dup 5) (match_dup 6))
11083 (cond_exec (match_dup 7)
11084 (set (match_dup 0) (match_dup 4)))]
11085 "
11086 {
11087 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
11088 operands[2], operands[3]);
11089 enum rtx_code rc = GET_CODE (operands[1]);
11090
11091 operands[5] = gen_rtx_REG (mode, CC_REGNUM);
11092 operands[6] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
11093 if (mode == CCFPmode || mode == CCFPEmode)
11094 rc = reverse_condition_maybe_unordered (rc);
11095 else
11096 rc = reverse_condition (rc);
11097
11098 operands[7] = gen_rtx_fmt_ee (rc, VOIDmode, operands[5], const0_rtx);
11099 }"
11100 )
11101
11102 (define_split
11103 [(set (match_operand:SI 0 "s_register_operand" "")
11104 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
11105 [(match_operand 2 "" "") (match_operand 3 "" "")])
11106 (match_operand 4 "" "")
11107 (match_dup 0)))
11108 (clobber (reg:CC CC_REGNUM))]
11109 "TARGET_ARM && reload_completed"
11110 [(set (match_dup 5) (match_dup 6))
11111 (cond_exec (match_op_dup 1 [(match_dup 5) (const_int 0)])
11112 (set (match_dup 0) (match_dup 4)))]
11113 "
11114 {
11115 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
11116 operands[2], operands[3]);
11117
11118 operands[5] = gen_rtx_REG (mode, CC_REGNUM);
11119 operands[6] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
11120 }"
11121 )
11122
11123 (define_split
11124 [(set (match_operand:SI 0 "s_register_operand" "")
11125 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
11126 [(match_operand 2 "" "") (match_operand 3 "" "")])
11127 (match_operand 4 "" "")
11128 (match_operand 5 "" "")))
11129 (clobber (reg:CC CC_REGNUM))]
11130 "TARGET_ARM && reload_completed"
11131 [(set (match_dup 6) (match_dup 7))
11132 (cond_exec (match_op_dup 1 [(match_dup 6) (const_int 0)])
11133 (set (match_dup 0) (match_dup 4)))
11134 (cond_exec (match_dup 8)
11135 (set (match_dup 0) (match_dup 5)))]
11136 "
11137 {
11138 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
11139 operands[2], operands[3]);
11140 enum rtx_code rc = GET_CODE (operands[1]);
11141
11142 operands[6] = gen_rtx_REG (mode, CC_REGNUM);
11143 operands[7] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
11144 if (mode == CCFPmode || mode == CCFPEmode)
11145 rc = reverse_condition_maybe_unordered (rc);
11146 else
11147 rc = reverse_condition (rc);
11148
11149 operands[8] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
11150 }"
11151 )
11152
11153 (define_split
11154 [(set (match_operand:SI 0 "s_register_operand" "")
11155 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
11156 [(match_operand:SI 2 "s_register_operand" "")
11157 (match_operand:SI 3 "arm_add_operand" "")])
11158 (match_operand:SI 4 "arm_rhs_operand" "")
11159 (not:SI
11160 (match_operand:SI 5 "s_register_operand" ""))))
11161 (clobber (reg:CC CC_REGNUM))]
11162 "TARGET_ARM && reload_completed"
11163 [(set (match_dup 6) (match_dup 7))
11164 (cond_exec (match_op_dup 1 [(match_dup 6) (const_int 0)])
11165 (set (match_dup 0) (match_dup 4)))
11166 (cond_exec (match_dup 8)
11167 (set (match_dup 0) (not:SI (match_dup 5))))]
11168 "
11169 {
11170 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
11171 operands[2], operands[3]);
11172 enum rtx_code rc = GET_CODE (operands[1]);
11173
11174 operands[6] = gen_rtx_REG (mode, CC_REGNUM);
11175 operands[7] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
11176 if (mode == CCFPmode || mode == CCFPEmode)
11177 rc = reverse_condition_maybe_unordered (rc);
11178 else
11179 rc = reverse_condition (rc);
11180
11181 operands[8] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
11182 }"
11183 )
11184
11185 (define_insn "*cond_move_not"
11186 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
11187 (if_then_else:SI (match_operator 4 "arm_comparison_operator"
11188 [(match_operand 3 "cc_register" "") (const_int 0)])
11189 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
11190 (not:SI
11191 (match_operand:SI 2 "s_register_operand" "r,r"))))]
11192 "TARGET_ARM"
11193 "@
11194 mvn%D4\\t%0, %2
11195 mov%d4\\t%0, %1\;mvn%D4\\t%0, %2"
11196 [(set_attr "conds" "use")
11197 (set_attr "type" "mvn_reg,multiple")
11198 (set_attr "length" "4,8")]
11199 )
11200
11201 ;; The next two patterns occur when an AND operation is followed by a
11202 ;; scc insn sequence
11203
11204 (define_insn "*sign_extract_onebit"
11205 [(set (match_operand:SI 0 "s_register_operand" "=r")
11206 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
11207 (const_int 1)
11208 (match_operand:SI 2 "const_int_operand" "n")))
11209 (clobber (reg:CC CC_REGNUM))]
11210 "TARGET_ARM"
11211 "*
11212 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
11213 output_asm_insn (\"ands\\t%0, %1, %2\", operands);
11214 return \"mvnne\\t%0, #0\";
11215 "
11216 [(set_attr "conds" "clob")
11217 (set_attr "length" "8")
11218 (set_attr "type" "multiple")]
11219 )
11220
11221 (define_insn "*not_signextract_onebit"
11222 [(set (match_operand:SI 0 "s_register_operand" "=r")
11223 (not:SI
11224 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
11225 (const_int 1)
11226 (match_operand:SI 2 "const_int_operand" "n"))))
11227 (clobber (reg:CC CC_REGNUM))]
11228 "TARGET_ARM"
11229 "*
11230 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
11231 output_asm_insn (\"tst\\t%1, %2\", operands);
11232 output_asm_insn (\"mvneq\\t%0, #0\", operands);
11233 return \"movne\\t%0, #0\";
11234 "
11235 [(set_attr "conds" "clob")
11236 (set_attr "length" "12")
11237 (set_attr "type" "multiple")]
11238 )
11239 ;; ??? The above patterns need auditing for Thumb-2
11240
11241 ;; Push multiple registers to the stack. Registers are in parallel (use ...)
11242 ;; expressions. For simplicity, the first register is also in the unspec
11243 ;; part.
11244 ;; To avoid the usage of GNU extension, the length attribute is computed
11245 ;; in a C function arm_attr_length_push_multi.
11246 (define_insn "*push_multi"
11247 [(match_parallel 2 "multi_register_push"
11248 [(set (match_operand:BLK 0 "push_mult_memory_operand" "")
11249 (unspec:BLK [(match_operand:SI 1 "s_register_operand" "")]
11250 UNSPEC_PUSH_MULT))])]
11251 ""
11252 "*
11253 {
11254 int num_saves = XVECLEN (operands[2], 0);
11255
11256 /* For the StrongARM at least it is faster to
11257 use STR to store only a single register.
11258 In Thumb mode always use push, and the assembler will pick
11259 something appropriate. */
11260 if (num_saves == 1 && TARGET_ARM)
11261 output_asm_insn (\"str%?\\t%1, [%m0, #-4]!\", operands);
11262 else
11263 {
11264 int i;
11265 char pattern[100];
11266
11267 if (TARGET_32BIT)
11268 strcpy (pattern, \"push%?\\t{%1\");
11269 else
11270 strcpy (pattern, \"push\\t{%1\");
11271
11272 for (i = 1; i < num_saves; i++)
11273 {
11274 strcat (pattern, \", %|\");
11275 strcat (pattern,
11276 reg_names[REGNO (XEXP (XVECEXP (operands[2], 0, i), 0))]);
11277 }
11278
11279 strcat (pattern, \"}\");
11280 output_asm_insn (pattern, operands);
11281 }
11282
11283 return \"\";
11284 }"
11285 [(set_attr "type" "store_16")
11286 (set (attr "length")
11287 (symbol_ref "arm_attr_length_push_multi (operands[2], operands[1])"))]
11288 )
11289
11290 (define_insn "stack_tie"
11291 [(set (mem:BLK (scratch))
11292 (unspec:BLK [(match_operand:SI 0 "s_register_operand" "rk")
11293 (match_operand:SI 1 "s_register_operand" "rk")]
11294 UNSPEC_PRLG_STK))]
11295 ""
11296 ""
11297 [(set_attr "length" "0")
11298 (set_attr "type" "block")]
11299 )
11300
11301 ;; Pop (as used in epilogue RTL)
11302 ;;
11303 (define_insn "*load_multiple_with_writeback"
11304 [(match_parallel 0 "load_multiple_operation"
11305 [(set (match_operand:SI 1 "s_register_operand" "+rk")
11306 (plus:SI (match_dup 1)
11307 (match_operand:SI 2 "const_int_I_operand" "I")))
11308 (set (match_operand:SI 3 "s_register_operand" "=rk")
11309 (mem:SI (match_dup 1)))
11310 ])]
11311 "TARGET_32BIT && (reload_in_progress || reload_completed)"
11312 "*
11313 {
11314 arm_output_multireg_pop (operands, /*return_pc=*/false,
11315 /*cond=*/const_true_rtx,
11316 /*reverse=*/false,
11317 /*update=*/true);
11318 return \"\";
11319 }
11320 "
11321 [(set_attr "type" "load_16")
11322 (set_attr "predicable" "yes")
11323 (set (attr "length")
11324 (symbol_ref "arm_attr_length_pop_multi (operands,
11325 /*return_pc=*/false,
11326 /*write_back_p=*/true)"))]
11327 )
11328
11329 ;; Pop with return (as used in epilogue RTL)
11330 ;;
11331 ;; This instruction is generated when the registers are popped at the end of
11332 ;; epilogue. Here, instead of popping the value into LR and then generating
11333 ;; jump to LR, value is popped into PC directly. Hence, the pattern is combined
11334 ;; with (return).
11335 (define_insn "*pop_multiple_with_writeback_and_return"
11336 [(match_parallel 0 "pop_multiple_return"
11337 [(return)
11338 (set (match_operand:SI 1 "s_register_operand" "+rk")
11339 (plus:SI (match_dup 1)
11340 (match_operand:SI 2 "const_int_I_operand" "I")))
11341 (set (match_operand:SI 3 "s_register_operand" "=rk")
11342 (mem:SI (match_dup 1)))
11343 ])]
11344 "TARGET_32BIT && (reload_in_progress || reload_completed)"
11345 "*
11346 {
11347 arm_output_multireg_pop (operands, /*return_pc=*/true,
11348 /*cond=*/const_true_rtx,
11349 /*reverse=*/false,
11350 /*update=*/true);
11351 return \"\";
11352 }
11353 "
11354 [(set_attr "type" "load_16")
11355 (set_attr "predicable" "yes")
11356 (set (attr "length")
11357 (symbol_ref "arm_attr_length_pop_multi (operands, /*return_pc=*/true,
11358 /*write_back_p=*/true)"))]
11359 )
11360
11361 (define_insn "*pop_multiple_with_return"
11362 [(match_parallel 0 "pop_multiple_return"
11363 [(return)
11364 (set (match_operand:SI 2 "s_register_operand" "=rk")
11365 (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
11366 ])]
11367 "TARGET_32BIT && (reload_in_progress || reload_completed)"
11368 "*
11369 {
11370 arm_output_multireg_pop (operands, /*return_pc=*/true,
11371 /*cond=*/const_true_rtx,
11372 /*reverse=*/false,
11373 /*update=*/false);
11374 return \"\";
11375 }
11376 "
11377 [(set_attr "type" "load_16")
11378 (set_attr "predicable" "yes")
11379 (set (attr "length")
11380 (symbol_ref "arm_attr_length_pop_multi (operands, /*return_pc=*/true,
11381 /*write_back_p=*/false)"))]
11382 )
11383
11384 ;; Load into PC and return
11385 (define_insn "*ldr_with_return"
11386 [(return)
11387 (set (reg:SI PC_REGNUM)
11388 (mem:SI (post_inc:SI (match_operand:SI 0 "s_register_operand" "+rk"))))]
11389 "TARGET_32BIT && (reload_in_progress || reload_completed)"
11390 "ldr%?\t%|pc, [%0], #4"
11391 [(set_attr "type" "load_4")
11392 (set_attr "predicable" "yes")]
11393 )
11394 ;; Pop for floating point registers (as used in epilogue RTL)
11395 (define_insn "*vfp_pop_multiple_with_writeback"
11396 [(match_parallel 0 "pop_multiple_fp"
11397 [(set (match_operand:SI 1 "s_register_operand" "+rk")
11398 (plus:SI (match_dup 1)
11399 (match_operand:SI 2 "const_int_I_operand" "I")))
11400 (set (match_operand:DF 3 "vfp_hard_register_operand" "")
11401 (mem:DF (match_dup 1)))])]
11402 "TARGET_32BIT && TARGET_HARD_FLOAT"
11403 "*
11404 {
11405 int num_regs = XVECLEN (operands[0], 0);
11406 char pattern[100];
11407 rtx op_list[2];
11408 strcpy (pattern, \"vldm\\t\");
11409 strcat (pattern, reg_names[REGNO (SET_DEST (XVECEXP (operands[0], 0, 0)))]);
11410 strcat (pattern, \"!, {\");
11411 op_list[0] = XEXP (XVECEXP (operands[0], 0, 1), 0);
11412 strcat (pattern, \"%P0\");
11413 if ((num_regs - 1) > 1)
11414 {
11415 strcat (pattern, \"-%P1\");
11416 op_list [1] = XEXP (XVECEXP (operands[0], 0, num_regs - 1), 0);
11417 }
11418
11419 strcat (pattern, \"}\");
11420 output_asm_insn (pattern, op_list);
11421 return \"\";
11422 }
11423 "
11424 [(set_attr "type" "load_16")
11425 (set_attr "conds" "unconditional")
11426 (set_attr "predicable" "no")]
11427 )
11428
11429 ;; Special patterns for dealing with the constant pool
11430
11431 (define_insn "align_4"
11432 [(unspec_volatile [(const_int 0)] VUNSPEC_ALIGN)]
11433 "TARGET_EITHER"
11434 "*
11435 assemble_align (32);
11436 return \"\";
11437 "
11438 [(set_attr "type" "no_insn")]
11439 )
11440
11441 (define_insn "align_8"
11442 [(unspec_volatile [(const_int 0)] VUNSPEC_ALIGN8)]
11443 "TARGET_EITHER"
11444 "*
11445 assemble_align (64);
11446 return \"\";
11447 "
11448 [(set_attr "type" "no_insn")]
11449 )
11450
11451 (define_insn "consttable_end"
11452 [(unspec_volatile [(const_int 0)] VUNSPEC_POOL_END)]
11453 "TARGET_EITHER"
11454 "*
11455 making_const_table = FALSE;
11456 return \"\";
11457 "
11458 [(set_attr "type" "no_insn")]
11459 )
11460
11461 (define_insn "consttable_1"
11462 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_1)]
11463 "TARGET_EITHER"
11464 "*
11465 making_const_table = TRUE;
11466 assemble_integer (operands[0], 1, BITS_PER_WORD, 1);
11467 assemble_zeros (3);
11468 return \"\";
11469 "
11470 [(set_attr "length" "4")
11471 (set_attr "type" "no_insn")]
11472 )
11473
11474 (define_insn "consttable_2"
11475 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_2)]
11476 "TARGET_EITHER"
11477 "*
11478 {
11479 rtx x = operands[0];
11480 making_const_table = TRUE;
11481 switch (GET_MODE_CLASS (GET_MODE (x)))
11482 {
11483 case MODE_FLOAT:
11484 arm_emit_fp16_const (x);
11485 break;
11486 default:
11487 assemble_integer (operands[0], 2, BITS_PER_WORD, 1);
11488 assemble_zeros (2);
11489 break;
11490 }
11491 return \"\";
11492 }"
11493 [(set_attr "length" "4")
11494 (set_attr "type" "no_insn")]
11495 )
11496
11497 (define_insn "consttable_4"
11498 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_4)]
11499 "TARGET_EITHER"
11500 "*
11501 {
11502 rtx x = operands[0];
11503 making_const_table = TRUE;
11504 scalar_float_mode float_mode;
11505 if (is_a <scalar_float_mode> (GET_MODE (x), &float_mode))
11506 assemble_real (*CONST_DOUBLE_REAL_VALUE (x), float_mode, BITS_PER_WORD);
11507 else
11508 {
11509 /* XXX: Sometimes gcc does something really dumb and ends up with
11510 a HIGH in a constant pool entry, usually because it's trying to
11511 load into a VFP register. We know this will always be used in
11512 combination with a LO_SUM which ignores the high bits, so just
11513 strip off the HIGH. */
11514 if (GET_CODE (x) == HIGH)
11515 x = XEXP (x, 0);
11516 assemble_integer (x, 4, BITS_PER_WORD, 1);
11517 mark_symbol_refs_as_used (x);
11518 }
11519 return \"\";
11520 }"
11521 [(set_attr "length" "4")
11522 (set_attr "type" "no_insn")]
11523 )
11524
11525 (define_insn "consttable_8"
11526 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_8)]
11527 "TARGET_EITHER"
11528 "*
11529 {
11530 making_const_table = TRUE;
11531 scalar_float_mode float_mode;
11532 if (is_a <scalar_float_mode> (GET_MODE (operands[0]), &float_mode))
11533 assemble_real (*CONST_DOUBLE_REAL_VALUE (operands[0]),
11534 float_mode, BITS_PER_WORD);
11535 else
11536 assemble_integer (operands[0], 8, BITS_PER_WORD, 1);
11537 return \"\";
11538 }"
11539 [(set_attr "length" "8")
11540 (set_attr "type" "no_insn")]
11541 )
11542
11543 (define_insn "consttable_16"
11544 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_16)]
11545 "TARGET_EITHER"
11546 "*
11547 {
11548 making_const_table = TRUE;
11549 scalar_float_mode float_mode;
11550 if (is_a <scalar_float_mode> (GET_MODE (operands[0]), &float_mode))
11551 assemble_real (*CONST_DOUBLE_REAL_VALUE (operands[0]),
11552 float_mode, BITS_PER_WORD);
11553 else
11554 assemble_integer (operands[0], 16, BITS_PER_WORD, 1);
11555 return \"\";
11556 }"
11557 [(set_attr "length" "16")
11558 (set_attr "type" "no_insn")]
11559 )
11560
11561 ;; V5 Instructions,
11562
11563 (define_insn "clzsi2"
11564 [(set (match_operand:SI 0 "s_register_operand" "=r")
11565 (clz:SI (match_operand:SI 1 "s_register_operand" "r")))]
11566 "TARGET_32BIT && arm_arch5t"
11567 "clz%?\\t%0, %1"
11568 [(set_attr "predicable" "yes")
11569 (set_attr "type" "clz")])
11570
11571 (define_insn "rbitsi2"
11572 [(set (match_operand:SI 0 "s_register_operand" "=r")
11573 (unspec:SI [(match_operand:SI 1 "s_register_operand" "r")] UNSPEC_RBIT))]
11574 "TARGET_32BIT && arm_arch_thumb2"
11575 "rbit%?\\t%0, %1"
11576 [(set_attr "predicable" "yes")
11577 (set_attr "type" "clz")])
11578
11579 ;; Keep this as a CTZ expression until after reload and then split
11580 ;; into RBIT + CLZ. Since RBIT is represented as an UNSPEC it is unlikely
11581 ;; to fold with any other expression.
11582
11583 (define_insn_and_split "ctzsi2"
11584 [(set (match_operand:SI 0 "s_register_operand" "=r")
11585 (ctz:SI (match_operand:SI 1 "s_register_operand" "r")))]
11586 "TARGET_32BIT && arm_arch_thumb2"
11587 "#"
11588 "&& reload_completed"
11589 [(const_int 0)]
11590 "
11591 emit_insn (gen_rbitsi2 (operands[0], operands[1]));
11592 emit_insn (gen_clzsi2 (operands[0], operands[0]));
11593 DONE;
11594 ")
11595
11596 ;; V5E instructions.
11597
11598 (define_insn "prefetch"
11599 [(prefetch (match_operand:SI 0 "address_operand" "p")
11600 (match_operand:SI 1 "" "")
11601 (match_operand:SI 2 "" ""))]
11602 "TARGET_32BIT && arm_arch5te"
11603 "pld\\t%a0"
11604 [(set_attr "type" "load_4")]
11605 )
11606
11607 ;; General predication pattern
11608
11609 (define_cond_exec
11610 [(match_operator 0 "arm_comparison_operator"
11611 [(match_operand 1 "cc_register" "")
11612 (const_int 0)])]
11613 "TARGET_32BIT
11614 && (!TARGET_NO_VOLATILE_CE || !volatile_refs_p (PATTERN (insn)))"
11615 ""
11616 [(set_attr "predicated" "yes")]
11617 )
11618
11619 (define_insn "force_register_use"
11620 [(unspec:SI [(match_operand:SI 0 "register_operand" "")] UNSPEC_REGISTER_USE)]
11621 ""
11622 "%@ %0 needed"
11623 [(set_attr "length" "0")
11624 (set_attr "type" "no_insn")]
11625 )
11626
11627
11628 ;; Patterns for exception handling
11629
11630 (define_expand "eh_return"
11631 [(use (match_operand 0 "general_operand" ""))]
11632 "TARGET_EITHER"
11633 "
11634 {
11635 if (TARGET_32BIT)
11636 emit_insn (gen_arm_eh_return (operands[0]));
11637 else
11638 emit_insn (gen_thumb_eh_return (operands[0]));
11639 DONE;
11640 }"
11641 )
11642
11643 ;; We can't expand this before we know where the link register is stored.
11644 (define_insn_and_split "arm_eh_return"
11645 [(unspec_volatile [(match_operand:SI 0 "s_register_operand" "r")]
11646 VUNSPEC_EH_RETURN)
11647 (clobber (match_scratch:SI 1 "=&r"))]
11648 "TARGET_ARM"
11649 "#"
11650 "&& reload_completed"
11651 [(const_int 0)]
11652 "
11653 {
11654 arm_set_return_address (operands[0], operands[1]);
11655 DONE;
11656 }"
11657 )
11658
11659 \f
11660 ;; TLS support
11661
11662 (define_insn "load_tp_hard"
11663 [(set (match_operand:SI 0 "register_operand" "=r")
11664 (unspec:SI [(const_int 0)] UNSPEC_TLS))]
11665 "TARGET_HARD_TP"
11666 "mrc%?\\tp15, 0, %0, c13, c0, 3\\t@ load_tp_hard"
11667 [(set_attr "predicable" "yes")
11668 (set_attr "type" "mrs")]
11669 )
11670
11671 ;; Doesn't clobber R1-R3. Must use r0 for the first operand.
11672 (define_insn "load_tp_soft"
11673 [(set (reg:SI 0) (unspec:SI [(const_int 0)] UNSPEC_TLS))
11674 (clobber (reg:SI LR_REGNUM))
11675 (clobber (reg:SI IP_REGNUM))
11676 (clobber (reg:CC CC_REGNUM))]
11677 "TARGET_SOFT_TP"
11678 "bl\\t__aeabi_read_tp\\t@ load_tp_soft"
11679 [(set_attr "conds" "clob")
11680 (set_attr "type" "branch")]
11681 )
11682
11683 ;; tls descriptor call
11684 (define_insn "tlscall"
11685 [(set (reg:SI R0_REGNUM)
11686 (unspec:SI [(reg:SI R0_REGNUM)
11687 (match_operand:SI 0 "" "X")
11688 (match_operand 1 "" "")] UNSPEC_TLS))
11689 (clobber (reg:SI R1_REGNUM))
11690 (clobber (reg:SI LR_REGNUM))
11691 (clobber (reg:SI CC_REGNUM))]
11692 "TARGET_GNU2_TLS"
11693 {
11694 targetm.asm_out.internal_label (asm_out_file, "LPIC",
11695 INTVAL (operands[1]));
11696 return "bl\\t%c0(tlscall)";
11697 }
11698 [(set_attr "conds" "clob")
11699 (set_attr "length" "4")
11700 (set_attr "type" "branch")]
11701 )
11702
11703 ;; For thread pointer builtin
11704 (define_expand "get_thread_pointersi"
11705 [(match_operand:SI 0 "s_register_operand" "=r")]
11706 ""
11707 "
11708 {
11709 arm_load_tp (operands[0]);
11710 DONE;
11711 }")
11712
11713 ;;
11714
11715 ;; We only care about the lower 16 bits of the constant
11716 ;; being inserted into the upper 16 bits of the register.
11717 (define_insn "*arm_movtas_ze"
11718 [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r,r")
11719 (const_int 16)
11720 (const_int 16))
11721 (match_operand:SI 1 "const_int_operand" ""))]
11722 "TARGET_HAVE_MOVT"
11723 "@
11724 movt%?\t%0, %L1
11725 movt\t%0, %L1"
11726 [(set_attr "arch" "32,v8mb")
11727 (set_attr "predicable" "yes")
11728 (set_attr "length" "4")
11729 (set_attr "type" "alu_sreg")]
11730 )
11731
11732 (define_insn "*arm_rev"
11733 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r")
11734 (bswap:SI (match_operand:SI 1 "s_register_operand" "l,l,r")))]
11735 "arm_arch6"
11736 "@
11737 rev\t%0, %1
11738 rev%?\t%0, %1
11739 rev%?\t%0, %1"
11740 [(set_attr "arch" "t1,t2,32")
11741 (set_attr "length" "2,2,4")
11742 (set_attr "predicable" "no,yes,yes")
11743 (set_attr "type" "rev")]
11744 )
11745
11746 (define_expand "arm_legacy_rev"
11747 [(set (match_operand:SI 2 "s_register_operand" "")
11748 (xor:SI (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
11749 (const_int 16))
11750 (match_dup 1)))
11751 (set (match_dup 2)
11752 (lshiftrt:SI (match_dup 2)
11753 (const_int 8)))
11754 (set (match_operand:SI 3 "s_register_operand" "")
11755 (rotatert:SI (match_dup 1)
11756 (const_int 8)))
11757 (set (match_dup 2)
11758 (and:SI (match_dup 2)
11759 (const_int -65281)))
11760 (set (match_operand:SI 0 "s_register_operand" "")
11761 (xor:SI (match_dup 3)
11762 (match_dup 2)))]
11763 "TARGET_32BIT"
11764 ""
11765 )
11766
11767 ;; Reuse temporaries to keep register pressure down.
11768 (define_expand "thumb_legacy_rev"
11769 [(set (match_operand:SI 2 "s_register_operand" "")
11770 (ashift:SI (match_operand:SI 1 "s_register_operand" "")
11771 (const_int 24)))
11772 (set (match_operand:SI 3 "s_register_operand" "")
11773 (lshiftrt:SI (match_dup 1)
11774 (const_int 24)))
11775 (set (match_dup 3)
11776 (ior:SI (match_dup 3)
11777 (match_dup 2)))
11778 (set (match_operand:SI 4 "s_register_operand" "")
11779 (const_int 16))
11780 (set (match_operand:SI 5 "s_register_operand" "")
11781 (rotatert:SI (match_dup 1)
11782 (match_dup 4)))
11783 (set (match_dup 2)
11784 (ashift:SI (match_dup 5)
11785 (const_int 24)))
11786 (set (match_dup 5)
11787 (lshiftrt:SI (match_dup 5)
11788 (const_int 24)))
11789 (set (match_dup 5)
11790 (ior:SI (match_dup 5)
11791 (match_dup 2)))
11792 (set (match_dup 5)
11793 (rotatert:SI (match_dup 5)
11794 (match_dup 4)))
11795 (set (match_operand:SI 0 "s_register_operand" "")
11796 (ior:SI (match_dup 5)
11797 (match_dup 3)))]
11798 "TARGET_THUMB"
11799 ""
11800 )
11801
11802 ;; ARM-specific expansion of signed mod by power of 2
11803 ;; using conditional negate.
11804 ;; For r0 % n where n is a power of 2 produce:
11805 ;; rsbs r1, r0, #0
11806 ;; and r0, r0, #(n - 1)
11807 ;; and r1, r1, #(n - 1)
11808 ;; rsbpl r0, r1, #0
11809
11810 (define_expand "modsi3"
11811 [(match_operand:SI 0 "register_operand" "")
11812 (match_operand:SI 1 "register_operand" "")
11813 (match_operand:SI 2 "const_int_operand" "")]
11814 "TARGET_32BIT"
11815 {
11816 HOST_WIDE_INT val = INTVAL (operands[2]);
11817
11818 if (val <= 0
11819 || exact_log2 (val) <= 0)
11820 FAIL;
11821
11822 rtx mask = GEN_INT (val - 1);
11823
11824 /* In the special case of x0 % 2 we can do the even shorter:
11825 cmp r0, #0
11826 and r0, r0, #1
11827 rsblt r0, r0, #0. */
11828
11829 if (val == 2)
11830 {
11831 rtx cc_reg = arm_gen_compare_reg (LT,
11832 operands[1], const0_rtx, NULL_RTX);
11833 rtx cond = gen_rtx_LT (SImode, cc_reg, const0_rtx);
11834 rtx masked = gen_reg_rtx (SImode);
11835
11836 emit_insn (gen_andsi3 (masked, operands[1], mask));
11837 emit_move_insn (operands[0],
11838 gen_rtx_IF_THEN_ELSE (SImode, cond,
11839 gen_rtx_NEG (SImode,
11840 masked),
11841 masked));
11842 DONE;
11843 }
11844
11845 rtx neg_op = gen_reg_rtx (SImode);
11846 rtx_insn *insn = emit_insn (gen_subsi3_compare0 (neg_op, const0_rtx,
11847 operands[1]));
11848
11849 /* Extract the condition register and mode. */
11850 rtx cmp = XVECEXP (PATTERN (insn), 0, 0);
11851 rtx cc_reg = SET_DEST (cmp);
11852 rtx cond = gen_rtx_GE (SImode, cc_reg, const0_rtx);
11853
11854 emit_insn (gen_andsi3 (operands[0], operands[1], mask));
11855
11856 rtx masked_neg = gen_reg_rtx (SImode);
11857 emit_insn (gen_andsi3 (masked_neg, neg_op, mask));
11858
11859 /* We want a conditional negate here, but emitting COND_EXEC rtxes
11860 during expand does not always work. Do an IF_THEN_ELSE instead. */
11861 emit_move_insn (operands[0],
11862 gen_rtx_IF_THEN_ELSE (SImode, cond,
11863 gen_rtx_NEG (SImode, masked_neg),
11864 operands[0]));
11865
11866
11867 DONE;
11868 }
11869 )
11870
11871 (define_expand "bswapsi2"
11872 [(set (match_operand:SI 0 "s_register_operand" "=r")
11873 (bswap:SI (match_operand:SI 1 "s_register_operand" "r")))]
11874 "TARGET_EITHER && (arm_arch6 || !optimize_size)"
11875 "
11876 if (!arm_arch6)
11877 {
11878 rtx op2 = gen_reg_rtx (SImode);
11879 rtx op3 = gen_reg_rtx (SImode);
11880
11881 if (TARGET_THUMB)
11882 {
11883 rtx op4 = gen_reg_rtx (SImode);
11884 rtx op5 = gen_reg_rtx (SImode);
11885
11886 emit_insn (gen_thumb_legacy_rev (operands[0], operands[1],
11887 op2, op3, op4, op5));
11888 }
11889 else
11890 {
11891 emit_insn (gen_arm_legacy_rev (operands[0], operands[1],
11892 op2, op3));
11893 }
11894
11895 DONE;
11896 }
11897 "
11898 )
11899
11900 ;; bswap16 patterns: use revsh and rev16 instructions for the signed
11901 ;; and unsigned variants, respectively. For rev16, expose
11902 ;; byte-swapping in the lower 16 bits only.
11903 (define_insn "*arm_revsh"
11904 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r")
11905 (sign_extend:SI (bswap:HI (match_operand:HI 1 "s_register_operand" "l,l,r"))))]
11906 "arm_arch6"
11907 "@
11908 revsh\t%0, %1
11909 revsh%?\t%0, %1
11910 revsh%?\t%0, %1"
11911 [(set_attr "arch" "t1,t2,32")
11912 (set_attr "length" "2,2,4")
11913 (set_attr "type" "rev")]
11914 )
11915
11916 (define_insn "*arm_rev16"
11917 [(set (match_operand:HI 0 "s_register_operand" "=l,l,r")
11918 (bswap:HI (match_operand:HI 1 "s_register_operand" "l,l,r")))]
11919 "arm_arch6"
11920 "@
11921 rev16\t%0, %1
11922 rev16%?\t%0, %1
11923 rev16%?\t%0, %1"
11924 [(set_attr "arch" "t1,t2,32")
11925 (set_attr "length" "2,2,4")
11926 (set_attr "type" "rev")]
11927 )
11928
11929 ;; There are no canonicalisation rules for the position of the lshiftrt, ashift
11930 ;; operations within an IOR/AND RTX, therefore we have two patterns matching
11931 ;; each valid permutation.
11932
11933 (define_insn "arm_rev16si2"
11934 [(set (match_operand:SI 0 "register_operand" "=l,l,r")
11935 (ior:SI (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "l,l,r")
11936 (const_int 8))
11937 (match_operand:SI 3 "const_int_operand" "n,n,n"))
11938 (and:SI (lshiftrt:SI (match_dup 1)
11939 (const_int 8))
11940 (match_operand:SI 2 "const_int_operand" "n,n,n"))))]
11941 "arm_arch6
11942 && aarch_rev16_shleft_mask_imm_p (operands[3], SImode)
11943 && aarch_rev16_shright_mask_imm_p (operands[2], SImode)"
11944 "rev16\\t%0, %1"
11945 [(set_attr "arch" "t1,t2,32")
11946 (set_attr "length" "2,2,4")
11947 (set_attr "type" "rev")]
11948 )
11949
11950 (define_insn "arm_rev16si2_alt"
11951 [(set (match_operand:SI 0 "register_operand" "=l,l,r")
11952 (ior:SI (and:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "l,l,r")
11953 (const_int 8))
11954 (match_operand:SI 2 "const_int_operand" "n,n,n"))
11955 (and:SI (ashift:SI (match_dup 1)
11956 (const_int 8))
11957 (match_operand:SI 3 "const_int_operand" "n,n,n"))))]
11958 "arm_arch6
11959 && aarch_rev16_shleft_mask_imm_p (operands[3], SImode)
11960 && aarch_rev16_shright_mask_imm_p (operands[2], SImode)"
11961 "rev16\\t%0, %1"
11962 [(set_attr "arch" "t1,t2,32")
11963 (set_attr "length" "2,2,4")
11964 (set_attr "type" "rev")]
11965 )
11966
11967 (define_expand "bswaphi2"
11968 [(set (match_operand:HI 0 "s_register_operand" "=r")
11969 (bswap:HI (match_operand:HI 1 "s_register_operand" "r")))]
11970 "arm_arch6"
11971 ""
11972 )
11973
11974 ;; Patterns for LDRD/STRD in Thumb2 mode
11975
11976 (define_insn "*thumb2_ldrd"
11977 [(set (match_operand:SI 0 "s_register_operand" "=r")
11978 (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "rk")
11979 (match_operand:SI 2 "ldrd_strd_offset_operand" "Do"))))
11980 (set (match_operand:SI 3 "s_register_operand" "=r")
11981 (mem:SI (plus:SI (match_dup 1)
11982 (match_operand:SI 4 "const_int_operand" ""))))]
11983 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11984 && ((INTVAL (operands[2]) + 4) == INTVAL (operands[4]))
11985 && (operands_ok_ldrd_strd (operands[0], operands[3],
11986 operands[1], INTVAL (operands[2]),
11987 false, true))"
11988 "ldrd%?\t%0, %3, [%1, %2]"
11989 [(set_attr "type" "load_8")
11990 (set_attr "predicable" "yes")])
11991
11992 (define_insn "*thumb2_ldrd_base"
11993 [(set (match_operand:SI 0 "s_register_operand" "=r")
11994 (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
11995 (set (match_operand:SI 2 "s_register_operand" "=r")
11996 (mem:SI (plus:SI (match_dup 1)
11997 (const_int 4))))]
11998 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11999 && (operands_ok_ldrd_strd (operands[0], operands[2],
12000 operands[1], 0, false, true))"
12001 "ldrd%?\t%0, %2, [%1]"
12002 [(set_attr "type" "load_8")
12003 (set_attr "predicable" "yes")])
12004
12005 (define_insn "*thumb2_ldrd_base_neg"
12006 [(set (match_operand:SI 0 "s_register_operand" "=r")
12007 (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "rk")
12008 (const_int -4))))
12009 (set (match_operand:SI 2 "s_register_operand" "=r")
12010 (mem:SI (match_dup 1)))]
12011 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
12012 && (operands_ok_ldrd_strd (operands[0], operands[2],
12013 operands[1], -4, false, true))"
12014 "ldrd%?\t%0, %2, [%1, #-4]"
12015 [(set_attr "type" "load_8")
12016 (set_attr "predicable" "yes")])
12017
12018 (define_insn "*thumb2_strd"
12019 [(set (mem:SI (plus:SI (match_operand:SI 0 "s_register_operand" "rk")
12020 (match_operand:SI 1 "ldrd_strd_offset_operand" "Do")))
12021 (match_operand:SI 2 "s_register_operand" "r"))
12022 (set (mem:SI (plus:SI (match_dup 0)
12023 (match_operand:SI 3 "const_int_operand" "")))
12024 (match_operand:SI 4 "s_register_operand" "r"))]
12025 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
12026 && ((INTVAL (operands[1]) + 4) == INTVAL (operands[3]))
12027 && (operands_ok_ldrd_strd (operands[2], operands[4],
12028 operands[0], INTVAL (operands[1]),
12029 false, false))"
12030 "strd%?\t%2, %4, [%0, %1]"
12031 [(set_attr "type" "store_8")
12032 (set_attr "predicable" "yes")])
12033
12034 (define_insn "*thumb2_strd_base"
12035 [(set (mem:SI (match_operand:SI 0 "s_register_operand" "rk"))
12036 (match_operand:SI 1 "s_register_operand" "r"))
12037 (set (mem:SI (plus:SI (match_dup 0)
12038 (const_int 4)))
12039 (match_operand:SI 2 "s_register_operand" "r"))]
12040 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
12041 && (operands_ok_ldrd_strd (operands[1], operands[2],
12042 operands[0], 0, false, false))"
12043 "strd%?\t%1, %2, [%0]"
12044 [(set_attr "type" "store_8")
12045 (set_attr "predicable" "yes")])
12046
12047 (define_insn "*thumb2_strd_base_neg"
12048 [(set (mem:SI (plus:SI (match_operand:SI 0 "s_register_operand" "rk")
12049 (const_int -4)))
12050 (match_operand:SI 1 "s_register_operand" "r"))
12051 (set (mem:SI (match_dup 0))
12052 (match_operand:SI 2 "s_register_operand" "r"))]
12053 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
12054 && (operands_ok_ldrd_strd (operands[1], operands[2],
12055 operands[0], -4, false, false))"
12056 "strd%?\t%1, %2, [%0, #-4]"
12057 [(set_attr "type" "store_8")
12058 (set_attr "predicable" "yes")])
12059
12060 ;; ARMv8 CRC32 instructions.
12061 (define_insn "<crc_variant>"
12062 [(set (match_operand:SI 0 "s_register_operand" "=r")
12063 (unspec:SI [(match_operand:SI 1 "s_register_operand" "r")
12064 (match_operand:<crc_mode> 2 "s_register_operand" "r")]
12065 CRC))]
12066 "TARGET_CRC32"
12067 "<crc_variant>\\t%0, %1, %2"
12068 [(set_attr "type" "crc")
12069 (set_attr "conds" "unconditional")]
12070 )
12071
12072 ;; Load the load/store double peephole optimizations.
12073 (include "ldrdstrd.md")
12074
12075 ;; Load the load/store multiple patterns
12076 (include "ldmstm.md")
12077
12078 ;; Patterns in ldmstm.md don't cover more than 4 registers. This pattern covers
12079 ;; large lists without explicit writeback generated for APCS_FRAME epilogue.
12080 ;; The operands are validated through the load_multiple_operation
12081 ;; match_parallel predicate rather than through constraints so enable it only
12082 ;; after reload.
12083 (define_insn "*load_multiple"
12084 [(match_parallel 0 "load_multiple_operation"
12085 [(set (match_operand:SI 2 "s_register_operand" "=rk")
12086 (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
12087 ])]
12088 "TARGET_32BIT && reload_completed"
12089 "*
12090 {
12091 arm_output_multireg_pop (operands, /*return_pc=*/false,
12092 /*cond=*/const_true_rtx,
12093 /*reverse=*/false,
12094 /*update=*/false);
12095 return \"\";
12096 }
12097 "
12098 [(set_attr "predicable" "yes")]
12099 )
12100
12101 (define_expand "copysignsf3"
12102 [(match_operand:SF 0 "register_operand")
12103 (match_operand:SF 1 "register_operand")
12104 (match_operand:SF 2 "register_operand")]
12105 "TARGET_SOFT_FLOAT && arm_arch_thumb2"
12106 "{
12107 emit_move_insn (operands[0], operands[2]);
12108 emit_insn (gen_insv_t2 (simplify_gen_subreg (SImode, operands[0], SFmode, 0),
12109 GEN_INT (31), GEN_INT (0),
12110 simplify_gen_subreg (SImode, operands[1], SFmode, 0)));
12111 DONE;
12112 }"
12113 )
12114
12115 (define_expand "copysigndf3"
12116 [(match_operand:DF 0 "register_operand")
12117 (match_operand:DF 1 "register_operand")
12118 (match_operand:DF 2 "register_operand")]
12119 "TARGET_SOFT_FLOAT && arm_arch_thumb2"
12120 "{
12121 rtx op0_low = gen_lowpart (SImode, operands[0]);
12122 rtx op0_high = gen_highpart (SImode, operands[0]);
12123 rtx op1_low = gen_lowpart (SImode, operands[1]);
12124 rtx op1_high = gen_highpart (SImode, operands[1]);
12125 rtx op2_high = gen_highpart (SImode, operands[2]);
12126
12127 rtx scratch1 = gen_reg_rtx (SImode);
12128 rtx scratch2 = gen_reg_rtx (SImode);
12129 emit_move_insn (scratch1, op2_high);
12130 emit_move_insn (scratch2, op1_high);
12131
12132 emit_insn(gen_rtx_SET(scratch1,
12133 gen_rtx_LSHIFTRT (SImode, op2_high, GEN_INT(31))));
12134 emit_insn(gen_insv_t2(scratch2, GEN_INT(1), GEN_INT(31), scratch1));
12135 emit_move_insn (op0_low, op1_low);
12136 emit_move_insn (op0_high, scratch2);
12137
12138 DONE;
12139 }"
12140 )
12141
12142 ;; movmisalign patterns for HImode and SImode.
12143 (define_expand "movmisalign<mode>"
12144 [(match_operand:HSI 0 "general_operand")
12145 (match_operand:HSI 1 "general_operand")]
12146 "unaligned_access"
12147 {
12148 /* This pattern is not permitted to fail during expansion: if both arguments
12149 are non-registers (e.g. memory := constant), force operand 1 into a
12150 register. */
12151 rtx (* gen_unaligned_load)(rtx, rtx);
12152 rtx tmp_dest = operands[0];
12153 if (!s_register_operand (operands[0], <MODE>mode)
12154 && !s_register_operand (operands[1], <MODE>mode))
12155 operands[1] = force_reg (<MODE>mode, operands[1]);
12156
12157 if (<MODE>mode == HImode)
12158 {
12159 gen_unaligned_load = gen_unaligned_loadhiu;
12160 tmp_dest = gen_reg_rtx (SImode);
12161 }
12162 else
12163 gen_unaligned_load = gen_unaligned_loadsi;
12164
12165 if (MEM_P (operands[1]))
12166 {
12167 emit_insn (gen_unaligned_load (tmp_dest, operands[1]));
12168 if (<MODE>mode == HImode)
12169 emit_move_insn (operands[0], gen_lowpart (HImode, tmp_dest));
12170 }
12171 else
12172 emit_insn (gen_unaligned_store<mode> (operands[0], operands[1]));
12173
12174 DONE;
12175 })
12176
12177 (define_insn "<cdp>"
12178 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "n")
12179 (match_operand:SI 1 "immediate_operand" "n")
12180 (match_operand:SI 2 "immediate_operand" "n")
12181 (match_operand:SI 3 "immediate_operand" "n")
12182 (match_operand:SI 4 "immediate_operand" "n")
12183 (match_operand:SI 5 "immediate_operand" "n")] CDPI)]
12184 "arm_coproc_builtin_available (VUNSPEC_<CDP>)"
12185 {
12186 arm_const_bounds (operands[0], 0, 16);
12187 arm_const_bounds (operands[1], 0, 16);
12188 arm_const_bounds (operands[2], 0, (1 << 5));
12189 arm_const_bounds (operands[3], 0, (1 << 5));
12190 arm_const_bounds (operands[4], 0, (1 << 5));
12191 arm_const_bounds (operands[5], 0, 8);
12192 return "<cdp>\\tp%c0, %1, CR%c2, CR%c3, CR%c4, %5";
12193 }
12194 [(set_attr "length" "4")
12195 (set_attr "type" "coproc")])
12196
12197 (define_insn "*ldc"
12198 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "n")
12199 (match_operand:SI 1 "immediate_operand" "n")
12200 (match_operand:SI 2 "memory_operand" "Uz")] LDCI)]
12201 "arm_coproc_builtin_available (VUNSPEC_<LDC>)"
12202 {
12203 arm_const_bounds (operands[0], 0, 16);
12204 arm_const_bounds (operands[1], 0, (1 << 5));
12205 return "<ldc>\\tp%c0, CR%c1, %2";
12206 }
12207 [(set_attr "length" "4")
12208 (set_attr "type" "coproc")])
12209
12210 (define_insn "*stc"
12211 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "n")
12212 (match_operand:SI 1 "immediate_operand" "n")
12213 (match_operand:SI 2 "memory_operand" "=Uz")] STCI)]
12214 "arm_coproc_builtin_available (VUNSPEC_<STC>)"
12215 {
12216 arm_const_bounds (operands[0], 0, 16);
12217 arm_const_bounds (operands[1], 0, (1 << 5));
12218 return "<stc>\\tp%c0, CR%c1, %2";
12219 }
12220 [(set_attr "length" "4")
12221 (set_attr "type" "coproc")])
12222
12223 (define_expand "<ldc>"
12224 [(unspec_volatile [(match_operand:SI 0 "immediate_operand")
12225 (match_operand:SI 1 "immediate_operand")
12226 (mem:SI (match_operand:SI 2 "s_register_operand"))] LDCI)]
12227 "arm_coproc_builtin_available (VUNSPEC_<LDC>)")
12228
12229 (define_expand "<stc>"
12230 [(unspec_volatile [(match_operand:SI 0 "immediate_operand")
12231 (match_operand:SI 1 "immediate_operand")
12232 (mem:SI (match_operand:SI 2 "s_register_operand"))] STCI)]
12233 "arm_coproc_builtin_available (VUNSPEC_<STC>)")
12234
12235 (define_insn "<mcr>"
12236 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "n")
12237 (match_operand:SI 1 "immediate_operand" "n")
12238 (match_operand:SI 2 "s_register_operand" "r")
12239 (match_operand:SI 3 "immediate_operand" "n")
12240 (match_operand:SI 4 "immediate_operand" "n")
12241 (match_operand:SI 5 "immediate_operand" "n")] MCRI)
12242 (use (match_dup 2))]
12243 "arm_coproc_builtin_available (VUNSPEC_<MCR>)"
12244 {
12245 arm_const_bounds (operands[0], 0, 16);
12246 arm_const_bounds (operands[1], 0, 8);
12247 arm_const_bounds (operands[3], 0, (1 << 5));
12248 arm_const_bounds (operands[4], 0, (1 << 5));
12249 arm_const_bounds (operands[5], 0, 8);
12250 return "<mcr>\\tp%c0, %1, %2, CR%c3, CR%c4, %5";
12251 }
12252 [(set_attr "length" "4")
12253 (set_attr "type" "coproc")])
12254
12255 (define_insn "<mrc>"
12256 [(set (match_operand:SI 0 "s_register_operand" "=r")
12257 (unspec_volatile:SI [(match_operand:SI 1 "immediate_operand" "n")
12258 (match_operand:SI 2 "immediate_operand" "n")
12259 (match_operand:SI 3 "immediate_operand" "n")
12260 (match_operand:SI 4 "immediate_operand" "n")
12261 (match_operand:SI 5 "immediate_operand" "n")] MRCI))]
12262 "arm_coproc_builtin_available (VUNSPEC_<MRC>)"
12263 {
12264 arm_const_bounds (operands[1], 0, 16);
12265 arm_const_bounds (operands[2], 0, 8);
12266 arm_const_bounds (operands[3], 0, (1 << 5));
12267 arm_const_bounds (operands[4], 0, (1 << 5));
12268 arm_const_bounds (operands[5], 0, 8);
12269 return "<mrc>\\tp%c1, %2, %0, CR%c3, CR%c4, %5";
12270 }
12271 [(set_attr "length" "4")
12272 (set_attr "type" "coproc")])
12273
12274 (define_insn "<mcrr>"
12275 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "n")
12276 (match_operand:SI 1 "immediate_operand" "n")
12277 (match_operand:DI 2 "s_register_operand" "r")
12278 (match_operand:SI 3 "immediate_operand" "n")] MCRRI)
12279 (use (match_dup 2))]
12280 "arm_coproc_builtin_available (VUNSPEC_<MCRR>)"
12281 {
12282 arm_const_bounds (operands[0], 0, 16);
12283 arm_const_bounds (operands[1], 0, 8);
12284 arm_const_bounds (operands[3], 0, (1 << 5));
12285 return "<mcrr>\\tp%c0, %1, %Q2, %R2, CR%c3";
12286 }
12287 [(set_attr "length" "4")
12288 (set_attr "type" "coproc")])
12289
12290 (define_insn "<mrrc>"
12291 [(set (match_operand:DI 0 "s_register_operand" "=r")
12292 (unspec_volatile:DI [(match_operand:SI 1 "immediate_operand" "n")
12293 (match_operand:SI 2 "immediate_operand" "n")
12294 (match_operand:SI 3 "immediate_operand" "n")] MRRCI))]
12295 "arm_coproc_builtin_available (VUNSPEC_<MRRC>)"
12296 {
12297 arm_const_bounds (operands[1], 0, 16);
12298 arm_const_bounds (operands[2], 0, 8);
12299 arm_const_bounds (operands[3], 0, (1 << 5));
12300 return "<mrrc>\\tp%c1, %2, %Q0, %R0, CR%c3";
12301 }
12302 [(set_attr "length" "4")
12303 (set_attr "type" "coproc")])
12304
12305 (define_expand "speculation_barrier"
12306 [(unspec_volatile [(const_int 0)] VUNSPEC_SPECULATION_BARRIER)]
12307 "TARGET_EITHER"
12308 "
12309 /* For thumb1 (except Armv8 derivatives), and for pre-Armv7 we don't
12310 have a usable barrier (and probably don't need one in practice).
12311 But to be safe if such code is run on later architectures, call a
12312 helper function in libgcc that will do the thing for the active
12313 system. */
12314 if (!(arm_arch7 || arm_arch8))
12315 {
12316 arm_emit_speculation_barrier_function ();
12317 DONE;
12318 }
12319 "
12320 )
12321
12322 ;; Generate a hard speculation barrier when we have not enabled speculation
12323 ;; tracking.
12324 (define_insn "*speculation_barrier_insn"
12325 [(unspec_volatile [(const_int 0)] VUNSPEC_SPECULATION_BARRIER)]
12326 "arm_arch7 || arm_arch8"
12327 "isb\;dsb\\tsy"
12328 [(set_attr "type" "block")
12329 (set_attr "length" "8")]
12330 )
12331
12332 ;; Vector bits common to IWMMXT and Neon
12333 (include "vec-common.md")
12334 ;; Load the Intel Wireless Multimedia Extension patterns
12335 (include "iwmmxt.md")
12336 ;; Load the VFP co-processor patterns
12337 (include "vfp.md")
12338 ;; Thumb-1 patterns
12339 (include "thumb1.md")
12340 ;; Thumb-2 patterns
12341 (include "thumb2.md")
12342 ;; Neon patterns
12343 (include "neon.md")
12344 ;; Crypto patterns
12345 (include "crypto.md")
12346 ;; Synchronization Primitives
12347 (include "sync.md")
12348 ;; Fixed-point patterns
12349 (include "arm-fixed.md")