1 ;;- Machine description for ARM for GNU compiler
2 ;; Copyright (C) 1991-2017 Free Software Foundation, Inc.
3 ;; Contributed by Pieter `Tiggr' Schoenmakers (rcpieter@win.tue.nl)
4 ;; and Martin Simmons (@harleqn.co.uk).
5 ;; More major hacks by Richard Earnshaw (rearnsha@arm.com).
7 ;; This file is part of GCC.
9 ;; GCC is free software; you can redistribute it and/or modify it
10 ;; under the terms of the GNU General Public License as published
11 ;; by the Free Software Foundation; either version 3, or (at your
12 ;; option) any later version.
14 ;; GCC is distributed in the hope that it will be useful, but WITHOUT
15 ;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16 ;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
17 ;; License for more details.
19 ;; You should have received a copy of the GNU General Public License
20 ;; along with GCC; see the file COPYING3. If not see
21 ;; <http://www.gnu.org/licenses/>.
23 ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
26 ;;---------------------------------------------------------------------------
29 ;; Register numbers -- All machine registers should be defined here
31 [(R0_REGNUM 0) ; First CORE register
32 (R1_REGNUM 1) ; Second CORE register
33 (IP_REGNUM 12) ; Scratch register
34 (SP_REGNUM 13) ; Stack pointer
35 (LR_REGNUM 14) ; Return address register
36 (PC_REGNUM 15) ; Program counter
37 (LAST_ARM_REGNUM 15) ;
38 (CC_REGNUM 100) ; Condition code pseudo register
39 (VFPCC_REGNUM 101) ; VFP Condition code pseudo register
42 ;; 3rd operand to select_dominance_cc_mode
49 ;; conditional compare combination
60 ;;---------------------------------------------------------------------------
63 ;; Processor type. This is created automatically from arm-cores.def.
64 (include "arm-tune.md")
66 ;; Instruction classification types
69 ; IS_THUMB is set to 'yes' when we are generating Thumb code, and 'no' when
70 ; generating ARM code. This is used to control the length of some insn
71 ; patterns that share the same RTL in both ARM and Thumb code.
72 (define_attr "is_thumb" "yes,no"
73 (const (if_then_else (symbol_ref "TARGET_THUMB")
74 (const_string "yes") (const_string "no"))))
76 ; IS_ARCH6 is set to 'yes' when we are generating code form ARMv6.
77 (define_attr "is_arch6" "no,yes" (const (symbol_ref "arm_arch6")))
79 ; IS_THUMB1 is set to 'yes' iff we are generating Thumb-1 code.
80 (define_attr "is_thumb1" "yes,no"
81 (const (if_then_else (symbol_ref "TARGET_THUMB1")
82 (const_string "yes") (const_string "no"))))
84 ; We use this attribute to disable alternatives that can produce 32-bit
85 ; instructions inside an IT-block in Thumb2 state. ARMv8 deprecates IT blocks
86 ; that contain 32-bit instructions.
87 (define_attr "enabled_for_depr_it" "no,yes" (const_string "yes"))
89 ; This attribute is used to disable a predicated alternative when we have
91 (define_attr "predicable_short_it" "no,yes" (const_string "yes"))
93 ;; Operand number of an input operand that is shifted. Zero if the
94 ;; given instruction does not shift one of its input operands.
95 (define_attr "shift" "" (const_int 0))
97 ;; [For compatibility with AArch64 in pipeline models]
98 ;; Attribute that specifies whether or not the instruction touches fp
100 (define_attr "fp" "no,yes" (const_string "no"))
102 ; Floating Point Unit. If we only have floating point emulation, then there
103 ; is no point in scheduling the floating point insns. (Well, for best
104 ; performance we should try and group them together).
105 (define_attr "fpu" "none,vfp"
106 (const (symbol_ref "arm_fpu_attr")))
108 ; Predicated means that the insn form is conditionally executed based on a
109 ; predicate. We default to 'no' because no Thumb patterns match this rule
110 ; and not all ARM insns do.
111 (define_attr "predicated" "yes,no" (const_string "no"))
113 ; LENGTH of an instruction (in bytes)
114 (define_attr "length" ""
117 ; The architecture which supports the instruction (or alternative).
118 ; This can be "a" for ARM, "t" for either of the Thumbs, "32" for
119 ; TARGET_32BIT, "t1" or "t2" to specify a specific Thumb mode. "v6"
120 ; for ARM or Thumb-2 with arm_arch6, and nov6 for ARM without
121 ; arm_arch6. "v6t2" for Thumb-2 with arm_arch6 and "v8mb" for ARMv8-M
122 ; Baseline. This attribute is used to compute attribute "enabled",
123 ; use type "any" to enable an alternative in all cases.
124 (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"
125 (const_string "any"))
127 (define_attr "arch_enabled" "no,yes"
128 (cond [(eq_attr "arch" "any")
131 (and (eq_attr "arch" "a")
132 (match_test "TARGET_ARM"))
135 (and (eq_attr "arch" "t")
136 (match_test "TARGET_THUMB"))
139 (and (eq_attr "arch" "t1")
140 (match_test "TARGET_THUMB1"))
143 (and (eq_attr "arch" "t2")
144 (match_test "TARGET_THUMB2"))
147 (and (eq_attr "arch" "32")
148 (match_test "TARGET_32BIT"))
151 (and (eq_attr "arch" "v6")
152 (match_test "TARGET_32BIT && arm_arch6"))
155 (and (eq_attr "arch" "nov6")
156 (match_test "TARGET_32BIT && !arm_arch6"))
159 (and (eq_attr "arch" "v6t2")
160 (match_test "TARGET_32BIT && arm_arch6 && arm_arch_thumb2"))
163 (and (eq_attr "arch" "v8mb")
164 (match_test "TARGET_THUMB1 && arm_arch8"))
167 (and (eq_attr "arch" "avoid_neon_for_64bits")
168 (match_test "TARGET_NEON")
169 (not (match_test "TARGET_PREFER_NEON_64BITS")))
172 (and (eq_attr "arch" "neon_for_64bits")
173 (match_test "TARGET_NEON")
174 (match_test "TARGET_PREFER_NEON_64BITS"))
177 (and (eq_attr "arch" "iwmmxt2")
178 (match_test "TARGET_REALLY_IWMMXT2"))
181 (and (eq_attr "arch" "armv6_or_vfpv3")
182 (match_test "arm_arch6 || TARGET_VFP3"))
185 (and (eq_attr "arch" "neon")
186 (match_test "TARGET_NEON"))
190 (const_string "no")))
192 (define_attr "opt" "any,speed,size"
193 (const_string "any"))
195 (define_attr "opt_enabled" "no,yes"
196 (cond [(eq_attr "opt" "any")
199 (and (eq_attr "opt" "speed")
200 (match_test "optimize_function_for_speed_p (cfun)"))
203 (and (eq_attr "opt" "size")
204 (match_test "optimize_function_for_size_p (cfun)"))
205 (const_string "yes")]
206 (const_string "no")))
208 (define_attr "use_literal_pool" "no,yes"
209 (cond [(and (eq_attr "type" "f_loads,f_loadd")
210 (match_test "CONSTANT_P (operands[1])"))
211 (const_string "yes")]
212 (const_string "no")))
214 ; Enable all alternatives that are both arch_enabled and insn_enabled.
215 ; FIXME:: opt_enabled has been temporarily removed till the time we have
216 ; an attribute that allows the use of such alternatives.
217 ; This depends on caching of speed_p, size_p on a per
218 ; alternative basis. The problem is that the enabled attribute
219 ; cannot depend on any state that is not cached or is not constant
220 ; for a compilation unit. We probably need a generic "hot/cold"
221 ; alternative which if implemented can help with this. We disable this
222 ; until such a time as this is implemented and / or the improvements or
223 ; regressions with removing this attribute are double checked.
224 ; See ashldi3_neon and <shift>di3_neon in neon.md.
226 (define_attr "enabled" "no,yes"
227 (cond [(and (eq_attr "predicable_short_it" "no")
228 (and (eq_attr "predicated" "yes")
229 (match_test "arm_restrict_it")))
232 (and (eq_attr "enabled_for_depr_it" "no")
233 (match_test "arm_restrict_it"))
236 (eq_attr "arch_enabled" "no")
238 (const_string "yes")))
240 ; POOL_RANGE is how far away from a constant pool entry that this insn
241 ; can be placed. If the distance is zero, then this insn will never
242 ; reference the pool.
243 ; Note that for Thumb constant pools the PC value is rounded down to the
244 ; nearest multiple of four. Therefore, THUMB2_POOL_RANGE (and POOL_RANGE for
245 ; Thumb insns) should be set to <max_range> - 2.
246 ; NEG_POOL_RANGE is nonzero for insns that can reference a constant pool entry
247 ; before its address. It is set to <max_range> - (8 + <data_size>).
248 (define_attr "arm_pool_range" "" (const_int 0))
249 (define_attr "thumb2_pool_range" "" (const_int 0))
250 (define_attr "arm_neg_pool_range" "" (const_int 0))
251 (define_attr "thumb2_neg_pool_range" "" (const_int 0))
253 (define_attr "pool_range" ""
254 (cond [(eq_attr "is_thumb" "yes") (attr "thumb2_pool_range")]
255 (attr "arm_pool_range")))
256 (define_attr "neg_pool_range" ""
257 (cond [(eq_attr "is_thumb" "yes") (attr "thumb2_neg_pool_range")]
258 (attr "arm_neg_pool_range")))
260 ; An assembler sequence may clobber the condition codes without us knowing.
261 ; If such an insn references the pool, then we have no way of knowing how,
262 ; so use the most conservative value for pool_range.
263 (define_asm_attributes
264 [(set_attr "conds" "clob")
265 (set_attr "length" "4")
266 (set_attr "pool_range" "250")])
268 ; Load scheduling, set from the arm_ld_sched variable
269 ; initialized by arm_option_override()
270 (define_attr "ldsched" "no,yes" (const (symbol_ref "arm_ld_sched")))
272 ; condition codes: this one is used by final_prescan_insn to speed up
273 ; conditionalizing instructions. It saves having to scan the rtl to see if
274 ; it uses or alters the condition codes.
276 ; USE means that the condition codes are used by the insn in the process of
277 ; outputting code, this means (at present) that we can't use the insn in
280 ; SET means that the purpose of the insn is to set the condition codes in a
281 ; well defined manner.
283 ; CLOB means that the condition codes are altered in an undefined manner, if
284 ; they are altered at all
286 ; UNCONDITIONAL means the instruction can not be conditionally executed and
287 ; that the instruction does not use or alter the condition codes.
289 ; NOCOND means that the instruction does not use or alter the condition
290 ; codes but can be converted into a conditionally exectuted instruction.
292 (define_attr "conds" "use,set,clob,unconditional,nocond"
294 (ior (eq_attr "is_thumb1" "yes")
295 (eq_attr "type" "call"))
296 (const_string "clob")
297 (if_then_else (eq_attr "is_neon_type" "no")
298 (const_string "nocond")
299 (const_string "unconditional"))))
301 ; Predicable means that the insn can be conditionally executed based on
302 ; an automatically added predicate (additional patterns are generated by
303 ; gen...). We default to 'no' because no Thumb patterns match this rule
304 ; and not all ARM patterns do.
305 (define_attr "predicable" "no,yes" (const_string "no"))
307 ; Only model the write buffer for ARM6 and ARM7. Earlier processors don't
308 ; have one. Later ones, such as StrongARM, have write-back caches, so don't
309 ; suffer blockages enough to warrant modelling this (and it can adversely
310 ; affect the schedule).
311 (define_attr "model_wbuf" "no,yes" (const (symbol_ref "arm_tune_wbuf")))
313 ; WRITE_CONFLICT implies that a read following an unrelated write is likely
314 ; to stall the processor. Used with model_wbuf above.
315 (define_attr "write_conflict" "no,yes"
316 (if_then_else (eq_attr "type"
319 (const_string "no")))
321 ; Classify the insns into those that take one cycle and those that take more
322 ; than one on the main cpu execution unit.
323 (define_attr "core_cycles" "single,multi"
324 (if_then_else (eq_attr "type"
325 "adc_imm, adc_reg, adcs_imm, adcs_reg, adr, alu_ext, alu_imm, alu_sreg,\
326 alu_shift_imm, alu_shift_reg, alu_dsp_reg, alus_ext, alus_imm, alus_sreg,\
327 alus_shift_imm, alus_shift_reg, bfm, csel, rev, logic_imm, logic_reg,\
328 logic_shift_imm, logic_shift_reg, logics_imm, logics_reg,\
329 logics_shift_imm, logics_shift_reg, extend, shift_imm, float, fcsel,\
330 wmmx_wor, wmmx_wxor, wmmx_wand, wmmx_wandn, wmmx_wmov, wmmx_tmcrr,\
331 wmmx_tmrrc, wmmx_wldr, wmmx_wstr, wmmx_tmcr, wmmx_tmrc, wmmx_wadd,\
332 wmmx_wsub, wmmx_wmul, wmmx_wmac, wmmx_wavg2, wmmx_tinsr, wmmx_textrm,\
333 wmmx_wshufh, wmmx_wcmpeq, wmmx_wcmpgt, wmmx_wmax, wmmx_wmin, wmmx_wpack,\
334 wmmx_wunpckih, wmmx_wunpckil, wmmx_wunpckeh, wmmx_wunpckel, wmmx_wror,\
335 wmmx_wsra, wmmx_wsrl, wmmx_wsll, wmmx_wmadd, wmmx_tmia, wmmx_tmiaph,\
336 wmmx_tmiaxy, wmmx_tbcst, wmmx_tmovmsk, wmmx_wacc, wmmx_waligni,\
337 wmmx_walignr, wmmx_tandc, wmmx_textrc, wmmx_torc, wmmx_torvsc, wmmx_wsad,\
338 wmmx_wabs, wmmx_wabsdiff, wmmx_waddsubhx, wmmx_wsubaddhx, wmmx_wavg4,\
339 wmmx_wmulw, wmmx_wqmulm, wmmx_wqmulwm, wmmx_waddbhus, wmmx_wqmiaxy,\
340 wmmx_wmiaxy, wmmx_wmiawxy, wmmx_wmerge")
341 (const_string "single")
342 (const_string "multi")))
344 ;; FAR_JUMP is "yes" if a BL instruction is used to generate a branch to a
345 ;; distant label. Only applicable to Thumb code.
346 (define_attr "far_jump" "yes,no" (const_string "no"))
349 ;; The number of machine instructions this pattern expands to.
350 ;; Used for Thumb-2 conditional execution.
351 (define_attr "ce_count" "" (const_int 1))
353 ;;---------------------------------------------------------------------------
356 (include "unspecs.md")
358 ;;---------------------------------------------------------------------------
361 (include "iterators.md")
363 ;;---------------------------------------------------------------------------
366 (include "predicates.md")
367 (include "constraints.md")
369 ;;---------------------------------------------------------------------------
370 ;; Pipeline descriptions
372 (define_attr "tune_cortexr4" "yes,no"
374 (eq_attr "tune" "cortexr4,cortexr4f,cortexr5")
376 (const_string "no"))))
378 ;; True if the generic scheduling description should be used.
380 (define_attr "generic_sched" "yes,no"
382 (ior (eq_attr "tune" "fa526,fa626,fa606te,fa626te,fmp626,fa726te,\
383 arm926ejs,arm1020e,arm1026ejs,arm1136js,\
384 arm1136jfs,cortexa5,cortexa7,cortexa8,\
385 cortexa9,cortexa12,cortexa15,cortexa17,\
386 cortexa53,cortexa57,cortexm4,cortexm7,\
387 exynosm1,marvell_pj4,xgene1")
388 (eq_attr "tune_cortexr4" "yes"))
390 (const_string "yes"))))
392 (define_attr "generic_vfp" "yes,no"
394 (and (eq_attr "fpu" "vfp")
395 (eq_attr "tune" "!arm1020e,arm1022e,cortexa5,cortexa7,\
396 cortexa8,cortexa9,cortexa53,cortexm4,\
397 cortexm7,marvell_pj4,xgene1")
398 (eq_attr "tune_cortexr4" "no"))
400 (const_string "no"))))
402 (include "marvell-f-iwmmxt.md")
403 (include "arm-generic.md")
404 (include "arm926ejs.md")
405 (include "arm1020e.md")
406 (include "arm1026ejs.md")
407 (include "arm1136jfs.md")
409 (include "fa606te.md")
410 (include "fa626te.md")
411 (include "fmp626.md")
412 (include "fa726te.md")
413 (include "cortex-a5.md")
414 (include "cortex-a7.md")
415 (include "cortex-a8.md")
416 (include "cortex-a9.md")
417 (include "cortex-a15.md")
418 (include "cortex-a17.md")
419 (include "cortex-a53.md")
420 (include "cortex-a57.md")
421 (include "cortex-r4.md")
422 (include "cortex-r4f.md")
423 (include "cortex-m7.md")
424 (include "cortex-m4.md")
425 (include "cortex-m4-fpu.md")
426 (include "exynos-m1.md")
428 (include "marvell-pj4.md")
429 (include "xgene1.md")
432 ;;---------------------------------------------------------------------------
437 ;; Note: For DImode insns, there is normally no reason why operands should
438 ;; not be in the same register, what we don't want is for something being
439 ;; written to partially overlap something that is an input.
441 (define_expand "adddi3"
443 [(set (match_operand:DI 0 "s_register_operand" "")
444 (plus:DI (match_operand:DI 1 "s_register_operand" "")
445 (match_operand:DI 2 "arm_adddi_operand" "")))
446 (clobber (reg:CC CC_REGNUM))])]
451 if (!REG_P (operands[1]))
452 operands[1] = force_reg (DImode, operands[1]);
453 if (!REG_P (operands[2]))
454 operands[2] = force_reg (DImode, operands[2]);
459 (define_insn_and_split "*arm_adddi3"
460 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r,&r,&r,&r")
461 (plus:DI (match_operand:DI 1 "s_register_operand" "%0, 0, r, 0, r")
462 (match_operand:DI 2 "arm_adddi_operand" "r, 0, r, Dd, Dd")))
463 (clobber (reg:CC CC_REGNUM))]
464 "TARGET_32BIT && !TARGET_NEON"
466 "TARGET_32BIT && reload_completed
467 && ! (TARGET_NEON && IS_VFP_REGNUM (REGNO (operands[0])))"
468 [(parallel [(set (reg:CC_C CC_REGNUM)
469 (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
471 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
472 (set (match_dup 3) (plus:SI (plus:SI (match_dup 4) (match_dup 5))
473 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
476 operands[3] = gen_highpart (SImode, operands[0]);
477 operands[0] = gen_lowpart (SImode, operands[0]);
478 operands[4] = gen_highpart (SImode, operands[1]);
479 operands[1] = gen_lowpart (SImode, operands[1]);
480 operands[5] = gen_highpart_mode (SImode, DImode, operands[2]);
481 operands[2] = gen_lowpart (SImode, operands[2]);
483 [(set_attr "conds" "clob")
484 (set_attr "length" "8")
485 (set_attr "type" "multiple")]
488 (define_insn_and_split "*adddi_sesidi_di"
489 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
490 (plus:DI (sign_extend:DI
491 (match_operand:SI 2 "s_register_operand" "r,r"))
492 (match_operand:DI 1 "s_register_operand" "0,r")))
493 (clobber (reg:CC CC_REGNUM))]
496 "TARGET_32BIT && reload_completed"
497 [(parallel [(set (reg:CC_C CC_REGNUM)
498 (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
500 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
501 (set (match_dup 3) (plus:SI (plus:SI (ashiftrt:SI (match_dup 2)
504 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
507 operands[3] = gen_highpart (SImode, operands[0]);
508 operands[0] = gen_lowpart (SImode, operands[0]);
509 operands[4] = gen_highpart (SImode, operands[1]);
510 operands[1] = gen_lowpart (SImode, operands[1]);
511 operands[2] = gen_lowpart (SImode, operands[2]);
513 [(set_attr "conds" "clob")
514 (set_attr "length" "8")
515 (set_attr "type" "multiple")]
518 (define_insn_and_split "*adddi_zesidi_di"
519 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
520 (plus:DI (zero_extend:DI
521 (match_operand:SI 2 "s_register_operand" "r,r"))
522 (match_operand:DI 1 "s_register_operand" "0,r")))
523 (clobber (reg:CC CC_REGNUM))]
526 "TARGET_32BIT && reload_completed"
527 [(parallel [(set (reg:CC_C CC_REGNUM)
528 (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
530 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
531 (set (match_dup 3) (plus:SI (plus:SI (match_dup 4) (const_int 0))
532 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
535 operands[3] = gen_highpart (SImode, operands[0]);
536 operands[0] = gen_lowpart (SImode, operands[0]);
537 operands[4] = gen_highpart (SImode, operands[1]);
538 operands[1] = gen_lowpart (SImode, operands[1]);
539 operands[2] = gen_lowpart (SImode, operands[2]);
541 [(set_attr "conds" "clob")
542 (set_attr "length" "8")
543 (set_attr "type" "multiple")]
546 (define_expand "addv<mode>4"
547 [(match_operand:SIDI 0 "register_operand")
548 (match_operand:SIDI 1 "register_operand")
549 (match_operand:SIDI 2 "register_operand")
550 (match_operand 3 "")]
553 emit_insn (gen_add<mode>3_compareV (operands[0], operands[1], operands[2]));
554 arm_gen_unlikely_cbranch (NE, CC_Vmode, operands[3]);
559 (define_expand "uaddv<mode>4"
560 [(match_operand:SIDI 0 "register_operand")
561 (match_operand:SIDI 1 "register_operand")
562 (match_operand:SIDI 2 "register_operand")
563 (match_operand 3 "")]
566 emit_insn (gen_add<mode>3_compareC (operands[0], operands[1], operands[2]));
567 arm_gen_unlikely_cbranch (NE, CC_Cmode, operands[3]);
572 (define_expand "addsi3"
573 [(set (match_operand:SI 0 "s_register_operand" "")
574 (plus:SI (match_operand:SI 1 "s_register_operand" "")
575 (match_operand:SI 2 "reg_or_int_operand" "")))]
578 if (TARGET_32BIT && CONST_INT_P (operands[2]))
580 arm_split_constant (PLUS, SImode, NULL_RTX,
581 INTVAL (operands[2]), operands[0], operands[1],
582 optimize && can_create_pseudo_p ());
588 ; If there is a scratch available, this will be faster than synthesizing the
591 [(match_scratch:SI 3 "r")
592 (set (match_operand:SI 0 "arm_general_register_operand" "")
593 (plus:SI (match_operand:SI 1 "arm_general_register_operand" "")
594 (match_operand:SI 2 "const_int_operand" "")))]
596 !(const_ok_for_arm (INTVAL (operands[2]))
597 || const_ok_for_arm (-INTVAL (operands[2])))
598 && const_ok_for_arm (~INTVAL (operands[2]))"
599 [(set (match_dup 3) (match_dup 2))
600 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 3)))]
604 ;; The r/r/k alternative is required when reloading the address
605 ;; (plus (reg rN) (reg sp)) into (reg rN). In this case reload will
606 ;; put the duplicated register first, and not try the commutative version.
607 (define_insn_and_split "*arm_addsi3"
608 [(set (match_operand:SI 0 "s_register_operand" "=rk,l,l ,l ,r ,k ,r,k ,r ,k ,r ,k,k,r ,k ,r")
609 (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")
610 (match_operand:SI 2 "reg_or_int_operand" "rk ,l,Py,Pd,rI,rI,k,rI,Pj,Pj,L ,L,L,PJ,PJ,?n")))]
626 subw%?\\t%0, %1, #%n2
627 subw%?\\t%0, %1, #%n2
630 && CONST_INT_P (operands[2])
631 && !const_ok_for_op (INTVAL (operands[2]), PLUS)
632 && (reload_completed || !arm_eliminable_register (operands[1]))"
633 [(clobber (const_int 0))]
635 arm_split_constant (PLUS, SImode, curr_insn,
636 INTVAL (operands[2]), operands[0],
640 [(set_attr "length" "2,4,4,4,4,4,4,4,4,4,4,4,4,4,4,16")
641 (set_attr "predicable" "yes")
642 (set_attr "predicable_short_it" "yes,yes,yes,yes,no,no,no,no,no,no,no,no,no,no,no,no")
643 (set_attr "arch" "t2,t2,t2,t2,*,*,*,a,t2,t2,*,*,a,t2,t2,*")
644 (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
645 (const_string "alu_imm")
646 (const_string "alu_sreg")))
650 (define_insn_and_split "adddi3_compareV"
651 [(set (reg:CC_V CC_REGNUM)
654 (sign_extend:TI (match_operand:DI 1 "register_operand" "r"))
655 (sign_extend:TI (match_operand:DI 2 "register_operand" "r")))
656 (sign_extend:TI (plus:DI (match_dup 1) (match_dup 2)))))
657 (set (match_operand:DI 0 "register_operand" "=&r")
658 (plus:DI (match_dup 1) (match_dup 2)))]
661 "&& reload_completed"
662 [(parallel [(set (reg:CC_C CC_REGNUM)
663 (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
665 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
666 (parallel [(set (reg:CC_V CC_REGNUM)
669 (sign_extend:DI (match_dup 4))
670 (sign_extend:DI (match_dup 5)))
671 (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0)))
672 (plus:DI (sign_extend:DI
673 (plus:SI (match_dup 4) (match_dup 5)))
674 (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0)))))
675 (set (match_dup 3) (plus:SI (plus:SI
676 (match_dup 4) (match_dup 5))
677 (ltu:SI (reg:CC_C CC_REGNUM)
681 operands[3] = gen_highpart (SImode, operands[0]);
682 operands[0] = gen_lowpart (SImode, operands[0]);
683 operands[4] = gen_highpart (SImode, operands[1]);
684 operands[1] = gen_lowpart (SImode, operands[1]);
685 operands[5] = gen_highpart (SImode, operands[2]);
686 operands[2] = gen_lowpart (SImode, operands[2]);
688 [(set_attr "conds" "set")
689 (set_attr "length" "8")
690 (set_attr "type" "multiple")]
693 (define_insn "addsi3_compareV"
694 [(set (reg:CC_V CC_REGNUM)
697 (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
698 (sign_extend:DI (match_operand:SI 2 "register_operand" "r")))
699 (sign_extend:DI (plus:SI (match_dup 1) (match_dup 2)))))
700 (set (match_operand:SI 0 "register_operand" "=r")
701 (plus:SI (match_dup 1) (match_dup 2)))]
703 "adds%?\\t%0, %1, %2"
704 [(set_attr "conds" "set")
705 (set_attr "type" "alus_sreg")]
708 (define_insn "*addsi3_compareV_upper"
709 [(set (reg:CC_V CC_REGNUM)
713 (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
714 (sign_extend:DI (match_operand:SI 2 "register_operand" "r")))
715 (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0)))
716 (plus:DI (sign_extend:DI
717 (plus:SI (match_dup 1) (match_dup 2)))
718 (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0)))))
719 (set (match_operand:SI 0 "register_operand" "=r")
721 (plus:SI (match_dup 1) (match_dup 2))
722 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
724 "adcs%?\\t%0, %1, %2"
725 [(set_attr "conds" "set")
726 (set_attr "type" "adcs_reg")]
729 (define_insn_and_split "adddi3_compareC"
730 [(set (reg:CC_C CC_REGNUM)
733 (zero_extend:TI (match_operand:DI 1 "register_operand" "r"))
734 (zero_extend:TI (match_operand:DI 2 "register_operand" "r")))
735 (zero_extend:TI (plus:DI (match_dup 1) (match_dup 2)))))
736 (set (match_operand:DI 0 "register_operand" "=&r")
737 (plus:DI (match_dup 1) (match_dup 2)))]
740 "&& reload_completed"
741 [(parallel [(set (reg:CC_C CC_REGNUM)
742 (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
744 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
745 (parallel [(set (reg:CC_C CC_REGNUM)
748 (zero_extend:DI (match_dup 4))
749 (zero_extend:DI (match_dup 5)))
750 (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0)))
751 (plus:DI (zero_extend:DI
752 (plus:SI (match_dup 4) (match_dup 5)))
753 (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0)))))
754 (set (match_dup 3) (plus:SI
755 (plus:SI (match_dup 4) (match_dup 5))
756 (ltu:SI (reg:CC_C CC_REGNUM)
760 operands[3] = gen_highpart (SImode, operands[0]);
761 operands[0] = gen_lowpart (SImode, operands[0]);
762 operands[4] = gen_highpart (SImode, operands[1]);
763 operands[5] = gen_highpart (SImode, operands[2]);
764 operands[1] = gen_lowpart (SImode, operands[1]);
765 operands[2] = gen_lowpart (SImode, operands[2]);
767 [(set_attr "conds" "set")
768 (set_attr "length" "8")
769 (set_attr "type" "multiple")]
772 (define_insn "*addsi3_compareC_upper"
773 [(set (reg:CC_C CC_REGNUM)
777 (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
778 (zero_extend:DI (match_operand:SI 2 "register_operand" "r")))
779 (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0)))
780 (plus:DI (zero_extend:DI
781 (plus:SI (match_dup 1) (match_dup 2)))
782 (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0)))))
783 (set (match_operand:SI 0 "register_operand" "=r")
785 (plus:SI (match_dup 1) (match_dup 2))
786 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
788 "adcs%?\\t%0, %1, %2"
789 [(set_attr "conds" "set")
790 (set_attr "type" "adcs_reg")]
793 (define_insn "addsi3_compareC"
794 [(set (reg:CC_C CC_REGNUM)
797 (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
798 (zero_extend:DI (match_operand:SI 2 "register_operand" "r")))
800 (plus:SI (match_dup 1) (match_dup 2)))))
801 (set (match_operand:SI 0 "register_operand" "=r")
802 (plus:SI (match_dup 1) (match_dup 2)))]
804 "adds%?\\t%0, %1, %2"
805 [(set_attr "conds" "set")
806 (set_attr "type" "alus_sreg")]
809 (define_insn "addsi3_compare0"
810 [(set (reg:CC_NOOV CC_REGNUM)
812 (plus:SI (match_operand:SI 1 "s_register_operand" "r, r,r")
813 (match_operand:SI 2 "arm_add_operand" "I,L,r"))
815 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
816 (plus:SI (match_dup 1) (match_dup 2)))]
820 subs%?\\t%0, %1, #%n2
822 [(set_attr "conds" "set")
823 (set_attr "type" "alus_imm,alus_imm,alus_sreg")]
826 (define_insn "*addsi3_compare0_scratch"
827 [(set (reg:CC_NOOV CC_REGNUM)
829 (plus:SI (match_operand:SI 0 "s_register_operand" "r, r, r")
830 (match_operand:SI 1 "arm_add_operand" "I,L, r"))
837 [(set_attr "conds" "set")
838 (set_attr "predicable" "yes")
839 (set_attr "type" "alus_imm,alus_imm,alus_sreg")]
842 (define_insn "*compare_negsi_si"
843 [(set (reg:CC_Z CC_REGNUM)
845 (neg:SI (match_operand:SI 0 "s_register_operand" "l,r"))
846 (match_operand:SI 1 "s_register_operand" "l,r")))]
849 [(set_attr "conds" "set")
850 (set_attr "predicable" "yes")
851 (set_attr "arch" "t2,*")
852 (set_attr "length" "2,4")
853 (set_attr "predicable_short_it" "yes,no")
854 (set_attr "type" "alus_sreg")]
857 ;; This is the canonicalization of addsi3_compare0_for_combiner when the
858 ;; addend is a constant.
859 (define_insn "cmpsi2_addneg"
860 [(set (reg:CC CC_REGNUM)
862 (match_operand:SI 1 "s_register_operand" "r,r")
863 (match_operand:SI 2 "arm_addimm_operand" "L,I")))
864 (set (match_operand:SI 0 "s_register_operand" "=r,r")
865 (plus:SI (match_dup 1)
866 (match_operand:SI 3 "arm_addimm_operand" "I,L")))]
867 "TARGET_32BIT && INTVAL (operands[2]) == -INTVAL (operands[3])"
870 subs%?\\t%0, %1, #%n3"
871 [(set_attr "conds" "set")
872 (set_attr "type" "alus_sreg")]
875 ;; Convert the sequence
877 ;; cmn rd, #1 (equivalent to cmp rd, #-1)
881 ;; bcs dest ((unsigned)rn >= 1)
882 ;; similarly for the beq variant using bcc.
883 ;; This is a common looping idiom (while (n--))
885 [(set (match_operand:SI 0 "arm_general_register_operand" "")
886 (plus:SI (match_operand:SI 1 "arm_general_register_operand" "")
888 (set (match_operand 2 "cc_register" "")
889 (compare (match_dup 0) (const_int -1)))
891 (if_then_else (match_operator 3 "equality_operator"
892 [(match_dup 2) (const_int 0)])
893 (match_operand 4 "" "")
894 (match_operand 5 "" "")))]
895 "TARGET_32BIT && peep2_reg_dead_p (3, operands[2])"
899 (match_dup 1) (const_int 1)))
900 (set (match_dup 0) (plus:SI (match_dup 1) (const_int -1)))])
902 (if_then_else (match_op_dup 3 [(match_dup 2) (const_int 0)])
905 "operands[2] = gen_rtx_REG (CCmode, CC_REGNUM);
906 operands[3] = gen_rtx_fmt_ee ((GET_CODE (operands[3]) == NE
909 operands[2], const0_rtx);"
912 ;; The next four insns work because they compare the result with one of
913 ;; the operands, and we know that the use of the condition code is
914 ;; either GEU or LTU, so we can use the carry flag from the addition
915 ;; instead of doing the compare a second time.
916 (define_insn "*addsi3_compare_op1"
917 [(set (reg:CC_C CC_REGNUM)
919 (plus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
920 (match_operand:SI 2 "arm_add_operand" "I,L,r"))
922 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
923 (plus:SI (match_dup 1) (match_dup 2)))]
927 subs%?\\t%0, %1, #%n2
929 [(set_attr "conds" "set")
930 (set_attr "type" "alus_imm,alus_imm,alus_sreg")]
933 (define_insn "*addsi3_compare_op2"
934 [(set (reg:CC_C CC_REGNUM)
936 (plus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
937 (match_operand:SI 2 "arm_add_operand" "I,L,r"))
939 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
940 (plus:SI (match_dup 1) (match_dup 2)))]
944 subs%?\\t%0, %1, #%n2
946 [(set_attr "conds" "set")
947 (set_attr "type" "alus_imm,alus_imm,alus_sreg")]
950 (define_insn "*compare_addsi2_op0"
951 [(set (reg:CC_C CC_REGNUM)
953 (plus:SI (match_operand:SI 0 "s_register_operand" "l,l,r,r,r")
954 (match_operand:SI 1 "arm_add_operand" "Pv,l,I,L,r"))
963 [(set_attr "conds" "set")
964 (set_attr "predicable" "yes")
965 (set_attr "arch" "t2,t2,*,*,*")
966 (set_attr "predicable_short_it" "yes,yes,no,no,no")
967 (set_attr "length" "2,2,4,4,4")
968 (set_attr "type" "alus_imm,alus_sreg,alus_imm,alus_imm,alus_sreg")]
971 (define_insn "*compare_addsi2_op1"
972 [(set (reg:CC_C CC_REGNUM)
974 (plus:SI (match_operand:SI 0 "s_register_operand" "l,l,r,r,r")
975 (match_operand:SI 1 "arm_add_operand" "Pv,l,I,L,r"))
984 [(set_attr "conds" "set")
985 (set_attr "predicable" "yes")
986 (set_attr "arch" "t2,t2,*,*,*")
987 (set_attr "predicable_short_it" "yes,yes,no,no,no")
988 (set_attr "length" "2,2,4,4,4")
989 (set_attr "type" "alus_imm,alus_sreg,alus_imm,alus_imm,alus_sreg")]
992 (define_insn "*addsi3_carryin_<optab>"
993 [(set (match_operand:SI 0 "s_register_operand" "=l,r,r")
994 (plus:SI (plus:SI (match_operand:SI 1 "s_register_operand" "%l,r,r")
995 (match_operand:SI 2 "arm_not_operand" "0,rI,K"))
996 (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))))]
1001 sbc%?\\t%0, %1, #%B2"
1002 [(set_attr "conds" "use")
1003 (set_attr "predicable" "yes")
1004 (set_attr "arch" "t2,*,*")
1005 (set_attr "length" "4")
1006 (set_attr "predicable_short_it" "yes,no,no")
1007 (set_attr "type" "adc_reg,adc_reg,adc_imm")]
1010 (define_insn "*addsi3_carryin_alt2_<optab>"
1011 [(set (match_operand:SI 0 "s_register_operand" "=l,r,r")
1012 (plus:SI (plus:SI (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))
1013 (match_operand:SI 1 "s_register_operand" "%l,r,r"))
1014 (match_operand:SI 2 "arm_rhs_operand" "l,rI,K")))]
1019 sbc%?\\t%0, %1, #%B2"
1020 [(set_attr "conds" "use")
1021 (set_attr "predicable" "yes")
1022 (set_attr "arch" "t2,*,*")
1023 (set_attr "length" "4")
1024 (set_attr "predicable_short_it" "yes,no,no")
1025 (set_attr "type" "adc_reg,adc_reg,adc_imm")]
1028 (define_insn "*addsi3_carryin_shift_<optab>"
1029 [(set (match_operand:SI 0 "s_register_operand" "=r")
1031 (match_operator:SI 2 "shift_operator"
1032 [(match_operand:SI 3 "s_register_operand" "r")
1033 (match_operand:SI 4 "reg_or_int_operand" "rM")])
1034 (match_operand:SI 1 "s_register_operand" "r"))
1035 (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))))]
1037 "adc%?\\t%0, %1, %3%S2"
1038 [(set_attr "conds" "use")
1039 (set_attr "predicable" "yes")
1040 (set_attr "predicable_short_it" "no")
1041 (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
1042 (const_string "alu_shift_imm")
1043 (const_string "alu_shift_reg")))]
1046 (define_insn "*addsi3_carryin_clobercc_<optab>"
1047 [(set (match_operand:SI 0 "s_register_operand" "=r")
1048 (plus:SI (plus:SI (match_operand:SI 1 "s_register_operand" "%r")
1049 (match_operand:SI 2 "arm_rhs_operand" "rI"))
1050 (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))))
1051 (clobber (reg:CC CC_REGNUM))]
1053 "adcs%?\\t%0, %1, %2"
1054 [(set_attr "conds" "set")
1055 (set_attr "type" "adcs_reg")]
1058 (define_expand "subv<mode>4"
1059 [(match_operand:SIDI 0 "register_operand")
1060 (match_operand:SIDI 1 "register_operand")
1061 (match_operand:SIDI 2 "register_operand")
1062 (match_operand 3 "")]
1065 emit_insn (gen_sub<mode>3_compare1 (operands[0], operands[1], operands[2]));
1066 arm_gen_unlikely_cbranch (NE, CC_Vmode, operands[3]);
1071 (define_expand "usubv<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 "")]
1078 emit_insn (gen_sub<mode>3_compare1 (operands[0], operands[1], operands[2]));
1079 arm_gen_unlikely_cbranch (LTU, CCmode, operands[3]);
1084 (define_insn_and_split "subdi3_compare1"
1085 [(set (reg:CC CC_REGNUM)
1087 (match_operand:DI 1 "register_operand" "r")
1088 (match_operand:DI 2 "register_operand" "r")))
1089 (set (match_operand:DI 0 "register_operand" "=&r")
1090 (minus:DI (match_dup 1) (match_dup 2)))]
1093 "&& reload_completed"
1094 [(parallel [(set (reg:CC CC_REGNUM)
1095 (compare:CC (match_dup 1) (match_dup 2)))
1096 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1097 (parallel [(set (reg:CC CC_REGNUM)
1098 (compare:CC (match_dup 4) (match_dup 5)))
1099 (set (match_dup 3) (minus:SI (minus:SI (match_dup 4) (match_dup 5))
1100 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))])]
1102 operands[3] = gen_highpart (SImode, operands[0]);
1103 operands[0] = gen_lowpart (SImode, operands[0]);
1104 operands[4] = gen_highpart (SImode, operands[1]);
1105 operands[1] = gen_lowpart (SImode, operands[1]);
1106 operands[5] = gen_highpart (SImode, operands[2]);
1107 operands[2] = gen_lowpart (SImode, operands[2]);
1109 [(set_attr "conds" "set")
1110 (set_attr "length" "8")
1111 (set_attr "type" "multiple")]
1114 (define_insn "subsi3_compare1"
1115 [(set (reg:CC CC_REGNUM)
1117 (match_operand:SI 1 "register_operand" "r")
1118 (match_operand:SI 2 "register_operand" "r")))
1119 (set (match_operand:SI 0 "register_operand" "=r")
1120 (minus:SI (match_dup 1) (match_dup 2)))]
1122 "subs%?\\t%0, %1, %2"
1123 [(set_attr "conds" "set")
1124 (set_attr "type" "alus_sreg")]
1127 (define_insn "*subsi3_carryin"
1128 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
1129 (minus:SI (minus:SI (match_operand:SI 1 "reg_or_int_operand" "r,I,Pz")
1130 (match_operand:SI 2 "s_register_operand" "r,r,r"))
1131 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1136 sbc%?\\t%0, %2, %2, lsl #1"
1137 [(set_attr "conds" "use")
1138 (set_attr "arch" "*,a,t2")
1139 (set_attr "predicable" "yes")
1140 (set_attr "predicable_short_it" "no")
1141 (set_attr "type" "adc_reg,adc_imm,alu_shift_imm")]
1144 (define_insn "*subsi3_carryin_const"
1145 [(set (match_operand:SI 0 "s_register_operand" "=r")
1146 (minus:SI (plus:SI (match_operand:SI 1 "s_register_operand" "r")
1147 (match_operand:SI 2 "arm_not_immediate_operand" "K"))
1148 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1150 "sbc\\t%0, %1, #%B2"
1151 [(set_attr "conds" "use")
1152 (set_attr "type" "adc_imm")]
1155 (define_insn "*subsi3_carryin_compare"
1156 [(set (reg:CC CC_REGNUM)
1157 (compare:CC (match_operand:SI 1 "s_register_operand" "r")
1158 (match_operand:SI 2 "s_register_operand" "r")))
1159 (set (match_operand:SI 0 "s_register_operand" "=r")
1160 (minus:SI (minus:SI (match_dup 1)
1162 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1165 [(set_attr "conds" "set")
1166 (set_attr "type" "adcs_reg")]
1169 (define_insn "*subsi3_carryin_compare_const"
1170 [(set (reg:CC CC_REGNUM)
1171 (compare:CC (match_operand:SI 1 "reg_or_int_operand" "r")
1172 (match_operand:SI 2 "arm_not_operand" "K")))
1173 (set (match_operand:SI 0 "s_register_operand" "=r")
1174 (minus:SI (plus:SI (match_dup 1)
1176 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1178 "sbcs\\t%0, %1, #%B2"
1179 [(set_attr "conds" "set")
1180 (set_attr "type" "adcs_imm")]
1183 (define_insn "*subsi3_carryin_shift"
1184 [(set (match_operand:SI 0 "s_register_operand" "=r")
1186 (match_operand:SI 1 "s_register_operand" "r")
1187 (match_operator:SI 2 "shift_operator"
1188 [(match_operand:SI 3 "s_register_operand" "r")
1189 (match_operand:SI 4 "reg_or_int_operand" "rM")]))
1190 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1192 "sbc%?\\t%0, %1, %3%S2"
1193 [(set_attr "conds" "use")
1194 (set_attr "predicable" "yes")
1195 (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
1196 (const_string "alu_shift_imm")
1197 (const_string "alu_shift_reg")))]
1200 (define_insn "*rsbsi3_carryin_shift"
1201 [(set (match_operand:SI 0 "s_register_operand" "=r")
1203 (match_operator:SI 2 "shift_operator"
1204 [(match_operand:SI 3 "s_register_operand" "r")
1205 (match_operand:SI 4 "reg_or_int_operand" "rM")])
1206 (match_operand:SI 1 "s_register_operand" "r"))
1207 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1209 "rsc%?\\t%0, %1, %3%S2"
1210 [(set_attr "conds" "use")
1211 (set_attr "predicable" "yes")
1212 (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
1213 (const_string "alu_shift_imm")
1214 (const_string "alu_shift_reg")))]
1217 ; transform ((x << y) - 1) to ~(~(x-1) << y) Where X is a constant.
1219 [(set (match_operand:SI 0 "s_register_operand" "")
1220 (plus:SI (ashift:SI (match_operand:SI 1 "const_int_operand" "")
1221 (match_operand:SI 2 "s_register_operand" ""))
1223 (clobber (match_operand:SI 3 "s_register_operand" ""))]
1225 [(set (match_dup 3) (match_dup 1))
1226 (set (match_dup 0) (not:SI (ashift:SI (match_dup 3) (match_dup 2))))]
1228 operands[1] = GEN_INT (~(INTVAL (operands[1]) - 1));
1231 (define_expand "addsf3"
1232 [(set (match_operand:SF 0 "s_register_operand" "")
1233 (plus:SF (match_operand:SF 1 "s_register_operand" "")
1234 (match_operand:SF 2 "s_register_operand" "")))]
1235 "TARGET_32BIT && TARGET_HARD_FLOAT"
1239 (define_expand "adddf3"
1240 [(set (match_operand:DF 0 "s_register_operand" "")
1241 (plus:DF (match_operand:DF 1 "s_register_operand" "")
1242 (match_operand:DF 2 "s_register_operand" "")))]
1243 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
1247 (define_expand "subdi3"
1249 [(set (match_operand:DI 0 "s_register_operand" "")
1250 (minus:DI (match_operand:DI 1 "s_register_operand" "")
1251 (match_operand:DI 2 "s_register_operand" "")))
1252 (clobber (reg:CC CC_REGNUM))])]
1257 if (!REG_P (operands[1]))
1258 operands[1] = force_reg (DImode, operands[1]);
1259 if (!REG_P (operands[2]))
1260 operands[2] = force_reg (DImode, operands[2]);
1265 (define_insn_and_split "*arm_subdi3"
1266 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r,&r")
1267 (minus:DI (match_operand:DI 1 "s_register_operand" "0,r,0")
1268 (match_operand:DI 2 "s_register_operand" "r,0,0")))
1269 (clobber (reg:CC CC_REGNUM))]
1270 "TARGET_32BIT && !TARGET_NEON"
1271 "#" ; "subs\\t%Q0, %Q1, %Q2\;sbc\\t%R0, %R1, %R2"
1272 "&& reload_completed"
1273 [(parallel [(set (reg:CC CC_REGNUM)
1274 (compare:CC (match_dup 1) (match_dup 2)))
1275 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1276 (set (match_dup 3) (minus:SI (minus:SI (match_dup 4) (match_dup 5))
1277 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1279 operands[3] = gen_highpart (SImode, operands[0]);
1280 operands[0] = gen_lowpart (SImode, operands[0]);
1281 operands[4] = gen_highpart (SImode, operands[1]);
1282 operands[1] = gen_lowpart (SImode, operands[1]);
1283 operands[5] = gen_highpart (SImode, operands[2]);
1284 operands[2] = gen_lowpart (SImode, operands[2]);
1286 [(set_attr "conds" "clob")
1287 (set_attr "length" "8")
1288 (set_attr "type" "multiple")]
1291 (define_insn_and_split "*subdi_di_zesidi"
1292 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1293 (minus:DI (match_operand:DI 1 "s_register_operand" "0,r")
1295 (match_operand:SI 2 "s_register_operand" "r,r"))))
1296 (clobber (reg:CC CC_REGNUM))]
1298 "#" ; "subs\\t%Q0, %Q1, %2\;sbc\\t%R0, %R1, #0"
1299 "&& reload_completed"
1300 [(parallel [(set (reg:CC CC_REGNUM)
1301 (compare:CC (match_dup 1) (match_dup 2)))
1302 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1303 (set (match_dup 3) (minus:SI (plus:SI (match_dup 4) (match_dup 5))
1304 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1306 operands[3] = gen_highpart (SImode, operands[0]);
1307 operands[0] = gen_lowpart (SImode, operands[0]);
1308 operands[4] = gen_highpart (SImode, operands[1]);
1309 operands[1] = gen_lowpart (SImode, operands[1]);
1310 operands[5] = GEN_INT (~0);
1312 [(set_attr "conds" "clob")
1313 (set_attr "length" "8")
1314 (set_attr "type" "multiple")]
1317 (define_insn_and_split "*subdi_di_sesidi"
1318 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1319 (minus:DI (match_operand:DI 1 "s_register_operand" "0,r")
1321 (match_operand:SI 2 "s_register_operand" "r,r"))))
1322 (clobber (reg:CC CC_REGNUM))]
1324 "#" ; "subs\\t%Q0, %Q1, %2\;sbc\\t%R0, %R1, %2, asr #31"
1325 "&& reload_completed"
1326 [(parallel [(set (reg:CC CC_REGNUM)
1327 (compare:CC (match_dup 1) (match_dup 2)))
1328 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1329 (set (match_dup 3) (minus:SI (minus:SI (match_dup 4)
1330 (ashiftrt:SI (match_dup 2)
1332 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1334 operands[3] = gen_highpart (SImode, operands[0]);
1335 operands[0] = gen_lowpart (SImode, operands[0]);
1336 operands[4] = gen_highpart (SImode, operands[1]);
1337 operands[1] = gen_lowpart (SImode, operands[1]);
1339 [(set_attr "conds" "clob")
1340 (set_attr "length" "8")
1341 (set_attr "type" "multiple")]
1344 (define_insn_and_split "*subdi_zesidi_di"
1345 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1346 (minus:DI (zero_extend:DI
1347 (match_operand:SI 2 "s_register_operand" "r,r"))
1348 (match_operand:DI 1 "s_register_operand" "0,r")))
1349 (clobber (reg:CC CC_REGNUM))]
1351 "#" ; "rsbs\\t%Q0, %Q1, %2\;rsc\\t%R0, %R1, #0"
1353 ; "subs\\t%Q0, %2, %Q1\;rsc\\t%R0, %R1, #0"
1354 "&& reload_completed"
1355 [(parallel [(set (reg:CC CC_REGNUM)
1356 (compare:CC (match_dup 2) (match_dup 1)))
1357 (set (match_dup 0) (minus:SI (match_dup 2) (match_dup 1)))])
1358 (set (match_dup 3) (minus:SI (minus:SI (const_int 0) (match_dup 4))
1359 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1361 operands[3] = gen_highpart (SImode, operands[0]);
1362 operands[0] = gen_lowpart (SImode, operands[0]);
1363 operands[4] = gen_highpart (SImode, operands[1]);
1364 operands[1] = gen_lowpart (SImode, operands[1]);
1366 [(set_attr "conds" "clob")
1367 (set_attr "length" "8")
1368 (set_attr "type" "multiple")]
1371 (define_insn_and_split "*subdi_sesidi_di"
1372 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1373 (minus:DI (sign_extend:DI
1374 (match_operand:SI 2 "s_register_operand" "r,r"))
1375 (match_operand:DI 1 "s_register_operand" "0,r")))
1376 (clobber (reg:CC CC_REGNUM))]
1378 "#" ; "rsbs\\t%Q0, %Q1, %2\;rsc\\t%R0, %R1, %2, asr #31"
1380 ; "subs\\t%Q0, %2, %Q1\;rsc\\t%R0, %R1, %2, asr #31"
1381 "&& reload_completed"
1382 [(parallel [(set (reg:CC CC_REGNUM)
1383 (compare:CC (match_dup 2) (match_dup 1)))
1384 (set (match_dup 0) (minus:SI (match_dup 2) (match_dup 1)))])
1385 (set (match_dup 3) (minus:SI (minus:SI
1386 (ashiftrt:SI (match_dup 2)
1389 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1391 operands[3] = gen_highpart (SImode, operands[0]);
1392 operands[0] = gen_lowpart (SImode, operands[0]);
1393 operands[4] = gen_highpart (SImode, operands[1]);
1394 operands[1] = gen_lowpart (SImode, operands[1]);
1396 [(set_attr "conds" "clob")
1397 (set_attr "length" "8")
1398 (set_attr "type" "multiple")]
1401 (define_insn_and_split "*subdi_zesidi_zesidi"
1402 [(set (match_operand:DI 0 "s_register_operand" "=r")
1403 (minus:DI (zero_extend:DI
1404 (match_operand:SI 1 "s_register_operand" "r"))
1406 (match_operand:SI 2 "s_register_operand" "r"))))
1407 (clobber (reg:CC CC_REGNUM))]
1409 "#" ; "subs\\t%Q0, %1, %2\;sbc\\t%R0, %1, %1"
1410 "&& reload_completed"
1411 [(parallel [(set (reg:CC CC_REGNUM)
1412 (compare:CC (match_dup 1) (match_dup 2)))
1413 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1414 (set (match_dup 3) (minus:SI (minus:SI (match_dup 1) (match_dup 1))
1415 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1417 operands[3] = gen_highpart (SImode, operands[0]);
1418 operands[0] = gen_lowpart (SImode, operands[0]);
1420 [(set_attr "conds" "clob")
1421 (set_attr "length" "8")
1422 (set_attr "type" "multiple")]
1425 (define_expand "subsi3"
1426 [(set (match_operand:SI 0 "s_register_operand" "")
1427 (minus:SI (match_operand:SI 1 "reg_or_int_operand" "")
1428 (match_operand:SI 2 "s_register_operand" "")))]
1431 if (CONST_INT_P (operands[1]))
1435 if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[1]), MINUS))
1436 operands[1] = force_reg (SImode, operands[1]);
1439 arm_split_constant (MINUS, SImode, NULL_RTX,
1440 INTVAL (operands[1]), operands[0],
1442 optimize && can_create_pseudo_p ());
1446 else /* TARGET_THUMB1 */
1447 operands[1] = force_reg (SImode, operands[1]);
1452 ; ??? Check Thumb-2 split length
1453 (define_insn_and_split "*arm_subsi3_insn"
1454 [(set (match_operand:SI 0 "s_register_operand" "=l,l ,l ,l ,r,r,r,rk,r")
1455 (minus:SI (match_operand:SI 1 "reg_or_int_operand" "l ,0 ,l ,Pz,I,r,r,k ,?n")
1456 (match_operand:SI 2 "reg_or_int_operand" "l ,Py,Pd,l ,r,I,r,r ,r")))]
1468 "&& (CONST_INT_P (operands[1])
1469 && !const_ok_for_arm (INTVAL (operands[1])))"
1470 [(clobber (const_int 0))]
1472 arm_split_constant (MINUS, SImode, curr_insn,
1473 INTVAL (operands[1]), operands[0], operands[2], 0);
1476 [(set_attr "length" "4,4,4,4,4,4,4,4,16")
1477 (set_attr "arch" "t2,t2,t2,t2,*,*,*,*,*")
1478 (set_attr "predicable" "yes")
1479 (set_attr "predicable_short_it" "yes,yes,yes,yes,no,no,no,no,no")
1480 (set_attr "type" "alu_sreg,alu_sreg,alu_sreg,alu_sreg,alu_imm,alu_imm,alu_sreg,alu_sreg,multiple")]
1484 [(match_scratch:SI 3 "r")
1485 (set (match_operand:SI 0 "arm_general_register_operand" "")
1486 (minus:SI (match_operand:SI 1 "const_int_operand" "")
1487 (match_operand:SI 2 "arm_general_register_operand" "")))]
1489 && !const_ok_for_arm (INTVAL (operands[1]))
1490 && const_ok_for_arm (~INTVAL (operands[1]))"
1491 [(set (match_dup 3) (match_dup 1))
1492 (set (match_dup 0) (minus:SI (match_dup 3) (match_dup 2)))]
1496 (define_insn "subsi3_compare0"
1497 [(set (reg:CC_NOOV CC_REGNUM)
1499 (minus:SI (match_operand:SI 1 "arm_rhs_operand" "r,r,I")
1500 (match_operand:SI 2 "arm_rhs_operand" "I,r,r"))
1502 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
1503 (minus:SI (match_dup 1) (match_dup 2)))]
1508 rsbs%?\\t%0, %2, %1"
1509 [(set_attr "conds" "set")
1510 (set_attr "type" "alus_imm,alus_sreg,alus_sreg")]
1513 (define_insn "subsi3_compare"
1514 [(set (reg:CC CC_REGNUM)
1515 (compare:CC (match_operand:SI 1 "arm_rhs_operand" "r,r,I")
1516 (match_operand:SI 2 "arm_rhs_operand" "I,r,r")))
1517 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
1518 (minus:SI (match_dup 1) (match_dup 2)))]
1523 rsbs%?\\t%0, %2, %1"
1524 [(set_attr "conds" "set")
1525 (set_attr "type" "alus_imm,alus_sreg,alus_sreg")]
1528 (define_expand "subsf3"
1529 [(set (match_operand:SF 0 "s_register_operand" "")
1530 (minus:SF (match_operand:SF 1 "s_register_operand" "")
1531 (match_operand:SF 2 "s_register_operand" "")))]
1532 "TARGET_32BIT && TARGET_HARD_FLOAT"
1536 (define_expand "subdf3"
1537 [(set (match_operand:DF 0 "s_register_operand" "")
1538 (minus:DF (match_operand:DF 1 "s_register_operand" "")
1539 (match_operand:DF 2 "s_register_operand" "")))]
1540 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
1545 ;; Multiplication insns
1547 (define_expand "mulhi3"
1548 [(set (match_operand:HI 0 "s_register_operand" "")
1549 (mult:HI (match_operand:HI 1 "s_register_operand" "")
1550 (match_operand:HI 2 "s_register_operand" "")))]
1551 "TARGET_DSP_MULTIPLY"
1554 rtx result = gen_reg_rtx (SImode);
1555 emit_insn (gen_mulhisi3 (result, operands[1], operands[2]));
1556 emit_move_insn (operands[0], gen_lowpart (HImode, result));
1561 (define_expand "mulsi3"
1562 [(set (match_operand:SI 0 "s_register_operand" "")
1563 (mult:SI (match_operand:SI 2 "s_register_operand" "")
1564 (match_operand:SI 1 "s_register_operand" "")))]
1569 ;; Use `&' and then `0' to prevent the operands 0 and 1 being the same
1570 (define_insn "*arm_mulsi3"
1571 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1572 (mult:SI (match_operand:SI 2 "s_register_operand" "r,r")
1573 (match_operand:SI 1 "s_register_operand" "%0,r")))]
1574 "TARGET_32BIT && !arm_arch6"
1575 "mul%?\\t%0, %2, %1"
1576 [(set_attr "type" "mul")
1577 (set_attr "predicable" "yes")]
1580 (define_insn "*arm_mulsi3_v6"
1581 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r")
1582 (mult:SI (match_operand:SI 1 "s_register_operand" "0,l,r")
1583 (match_operand:SI 2 "s_register_operand" "l,0,r")))]
1584 "TARGET_32BIT && arm_arch6"
1585 "mul%?\\t%0, %1, %2"
1586 [(set_attr "type" "mul")
1587 (set_attr "predicable" "yes")
1588 (set_attr "arch" "t2,t2,*")
1589 (set_attr "length" "4")
1590 (set_attr "predicable_short_it" "yes,yes,no")]
1593 (define_insn "*mulsi3_compare0"
1594 [(set (reg:CC_NOOV CC_REGNUM)
1595 (compare:CC_NOOV (mult:SI
1596 (match_operand:SI 2 "s_register_operand" "r,r")
1597 (match_operand:SI 1 "s_register_operand" "%0,r"))
1599 (set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1600 (mult:SI (match_dup 2) (match_dup 1)))]
1601 "TARGET_ARM && !arm_arch6"
1602 "muls%?\\t%0, %2, %1"
1603 [(set_attr "conds" "set")
1604 (set_attr "type" "muls")]
1607 (define_insn "*mulsi3_compare0_v6"
1608 [(set (reg:CC_NOOV CC_REGNUM)
1609 (compare:CC_NOOV (mult:SI
1610 (match_operand:SI 2 "s_register_operand" "r")
1611 (match_operand:SI 1 "s_register_operand" "r"))
1613 (set (match_operand:SI 0 "s_register_operand" "=r")
1614 (mult:SI (match_dup 2) (match_dup 1)))]
1615 "TARGET_ARM && arm_arch6 && optimize_size"
1616 "muls%?\\t%0, %2, %1"
1617 [(set_attr "conds" "set")
1618 (set_attr "type" "muls")]
1621 (define_insn "*mulsi_compare0_scratch"
1622 [(set (reg:CC_NOOV CC_REGNUM)
1623 (compare:CC_NOOV (mult:SI
1624 (match_operand:SI 2 "s_register_operand" "r,r")
1625 (match_operand:SI 1 "s_register_operand" "%0,r"))
1627 (clobber (match_scratch:SI 0 "=&r,&r"))]
1628 "TARGET_ARM && !arm_arch6"
1629 "muls%?\\t%0, %2, %1"
1630 [(set_attr "conds" "set")
1631 (set_attr "type" "muls")]
1634 (define_insn "*mulsi_compare0_scratch_v6"
1635 [(set (reg:CC_NOOV CC_REGNUM)
1636 (compare:CC_NOOV (mult:SI
1637 (match_operand:SI 2 "s_register_operand" "r")
1638 (match_operand:SI 1 "s_register_operand" "r"))
1640 (clobber (match_scratch:SI 0 "=r"))]
1641 "TARGET_ARM && arm_arch6 && optimize_size"
1642 "muls%?\\t%0, %2, %1"
1643 [(set_attr "conds" "set")
1644 (set_attr "type" "muls")]
1647 ;; Unnamed templates to match MLA instruction.
1649 (define_insn "*mulsi3addsi"
1650 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r,&r")
1652 (mult:SI (match_operand:SI 2 "s_register_operand" "r,r,r,r")
1653 (match_operand:SI 1 "s_register_operand" "%0,r,0,r"))
1654 (match_operand:SI 3 "s_register_operand" "r,r,0,0")))]
1655 "TARGET_32BIT && !arm_arch6"
1656 "mla%?\\t%0, %2, %1, %3"
1657 [(set_attr "type" "mla")
1658 (set_attr "predicable" "yes")]
1661 (define_insn "*mulsi3addsi_v6"
1662 [(set (match_operand:SI 0 "s_register_operand" "=r")
1664 (mult:SI (match_operand:SI 2 "s_register_operand" "r")
1665 (match_operand:SI 1 "s_register_operand" "r"))
1666 (match_operand:SI 3 "s_register_operand" "r")))]
1667 "TARGET_32BIT && arm_arch6"
1668 "mla%?\\t%0, %2, %1, %3"
1669 [(set_attr "type" "mla")
1670 (set_attr "predicable" "yes")
1671 (set_attr "predicable_short_it" "no")]
1674 (define_insn "*mulsi3addsi_compare0"
1675 [(set (reg:CC_NOOV CC_REGNUM)
1678 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
1679 (match_operand:SI 1 "s_register_operand" "%0,r,0,r"))
1680 (match_operand:SI 3 "s_register_operand" "r,r,0,0"))
1682 (set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r,&r")
1683 (plus:SI (mult:SI (match_dup 2) (match_dup 1))
1685 "TARGET_ARM && arm_arch6"
1686 "mlas%?\\t%0, %2, %1, %3"
1687 [(set_attr "conds" "set")
1688 (set_attr "type" "mlas")]
1691 (define_insn "*mulsi3addsi_compare0_v6"
1692 [(set (reg:CC_NOOV CC_REGNUM)
1695 (match_operand:SI 2 "s_register_operand" "r")
1696 (match_operand:SI 1 "s_register_operand" "r"))
1697 (match_operand:SI 3 "s_register_operand" "r"))
1699 (set (match_operand:SI 0 "s_register_operand" "=r")
1700 (plus:SI (mult:SI (match_dup 2) (match_dup 1))
1702 "TARGET_ARM && arm_arch6 && optimize_size"
1703 "mlas%?\\t%0, %2, %1, %3"
1704 [(set_attr "conds" "set")
1705 (set_attr "type" "mlas")]
1708 (define_insn "*mulsi3addsi_compare0_scratch"
1709 [(set (reg:CC_NOOV CC_REGNUM)
1712 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
1713 (match_operand:SI 1 "s_register_operand" "%0,r,0,r"))
1714 (match_operand:SI 3 "s_register_operand" "?r,r,0,0"))
1716 (clobber (match_scratch:SI 0 "=&r,&r,&r,&r"))]
1717 "TARGET_ARM && !arm_arch6"
1718 "mlas%?\\t%0, %2, %1, %3"
1719 [(set_attr "conds" "set")
1720 (set_attr "type" "mlas")]
1723 (define_insn "*mulsi3addsi_compare0_scratch_v6"
1724 [(set (reg:CC_NOOV CC_REGNUM)
1727 (match_operand:SI 2 "s_register_operand" "r")
1728 (match_operand:SI 1 "s_register_operand" "r"))
1729 (match_operand:SI 3 "s_register_operand" "r"))
1731 (clobber (match_scratch:SI 0 "=r"))]
1732 "TARGET_ARM && arm_arch6 && optimize_size"
1733 "mlas%?\\t%0, %2, %1, %3"
1734 [(set_attr "conds" "set")
1735 (set_attr "type" "mlas")]
1738 (define_insn "*mulsi3subsi"
1739 [(set (match_operand:SI 0 "s_register_operand" "=r")
1741 (match_operand:SI 3 "s_register_operand" "r")
1742 (mult:SI (match_operand:SI 2 "s_register_operand" "r")
1743 (match_operand:SI 1 "s_register_operand" "r"))))]
1744 "TARGET_32BIT && arm_arch_thumb2"
1745 "mls%?\\t%0, %2, %1, %3"
1746 [(set_attr "type" "mla")
1747 (set_attr "predicable" "yes")
1748 (set_attr "predicable_short_it" "no")]
1751 (define_expand "maddsidi4"
1752 [(set (match_operand:DI 0 "s_register_operand" "")
1755 (sign_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1756 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1757 (match_operand:DI 3 "s_register_operand" "")))]
1758 "TARGET_32BIT && arm_arch3m"
1761 (define_insn "*mulsidi3adddi"
1762 [(set (match_operand:DI 0 "s_register_operand" "=&r")
1765 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "%r"))
1766 (sign_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1767 (match_operand:DI 1 "s_register_operand" "0")))]
1768 "TARGET_32BIT && arm_arch3m && !arm_arch6"
1769 "smlal%?\\t%Q0, %R0, %3, %2"
1770 [(set_attr "type" "smlal")
1771 (set_attr "predicable" "yes")]
1774 (define_insn "*mulsidi3adddi_v6"
1775 [(set (match_operand:DI 0 "s_register_operand" "=r")
1778 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r"))
1779 (sign_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1780 (match_operand:DI 1 "s_register_operand" "0")))]
1781 "TARGET_32BIT && arm_arch6"
1782 "smlal%?\\t%Q0, %R0, %3, %2"
1783 [(set_attr "type" "smlal")
1784 (set_attr "predicable" "yes")
1785 (set_attr "predicable_short_it" "no")]
1788 ;; 32x32->64 widening multiply.
1789 ;; As with mulsi3, the only difference between the v3-5 and v6+
1790 ;; versions of these patterns is the requirement that the output not
1791 ;; overlap the inputs, but that still means we have to have a named
1792 ;; expander and two different starred insns.
1794 (define_expand "mulsidi3"
1795 [(set (match_operand:DI 0 "s_register_operand" "")
1797 (sign_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1798 (sign_extend:DI (match_operand:SI 2 "s_register_operand" ""))))]
1799 "TARGET_32BIT && arm_arch3m"
1803 (define_insn "*mulsidi3_nov6"
1804 [(set (match_operand:DI 0 "s_register_operand" "=&r")
1806 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "%r"))
1807 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1808 "TARGET_32BIT && arm_arch3m && !arm_arch6"
1809 "smull%?\\t%Q0, %R0, %1, %2"
1810 [(set_attr "type" "smull")
1811 (set_attr "predicable" "yes")]
1814 (define_insn "*mulsidi3_v6"
1815 [(set (match_operand:DI 0 "s_register_operand" "=r")
1817 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1818 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1819 "TARGET_32BIT && arm_arch6"
1820 "smull%?\\t%Q0, %R0, %1, %2"
1821 [(set_attr "type" "smull")
1822 (set_attr "predicable" "yes")
1823 (set_attr "predicable_short_it" "no")]
1826 (define_expand "umulsidi3"
1827 [(set (match_operand:DI 0 "s_register_operand" "")
1829 (zero_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1830 (zero_extend:DI (match_operand:SI 2 "s_register_operand" ""))))]
1831 "TARGET_32BIT && arm_arch3m"
1835 (define_insn "*umulsidi3_nov6"
1836 [(set (match_operand:DI 0 "s_register_operand" "=&r")
1838 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "%r"))
1839 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1840 "TARGET_32BIT && arm_arch3m && !arm_arch6"
1841 "umull%?\\t%Q0, %R0, %1, %2"
1842 [(set_attr "type" "umull")
1843 (set_attr "predicable" "yes")]
1846 (define_insn "*umulsidi3_v6"
1847 [(set (match_operand:DI 0 "s_register_operand" "=r")
1849 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1850 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1851 "TARGET_32BIT && arm_arch6"
1852 "umull%?\\t%Q0, %R0, %1, %2"
1853 [(set_attr "type" "umull")
1854 (set_attr "predicable" "yes")
1855 (set_attr "predicable_short_it" "no")]
1858 (define_expand "umaddsidi4"
1859 [(set (match_operand:DI 0 "s_register_operand" "")
1862 (zero_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1863 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1864 (match_operand:DI 3 "s_register_operand" "")))]
1865 "TARGET_32BIT && arm_arch3m"
1868 (define_insn "*umulsidi3adddi"
1869 [(set (match_operand:DI 0 "s_register_operand" "=&r")
1872 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "%r"))
1873 (zero_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1874 (match_operand:DI 1 "s_register_operand" "0")))]
1875 "TARGET_32BIT && arm_arch3m && !arm_arch6"
1876 "umlal%?\\t%Q0, %R0, %3, %2"
1877 [(set_attr "type" "umlal")
1878 (set_attr "predicable" "yes")]
1881 (define_insn "*umulsidi3adddi_v6"
1882 [(set (match_operand:DI 0 "s_register_operand" "=r")
1885 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r"))
1886 (zero_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1887 (match_operand:DI 1 "s_register_operand" "0")))]
1888 "TARGET_32BIT && arm_arch6"
1889 "umlal%?\\t%Q0, %R0, %3, %2"
1890 [(set_attr "type" "umlal")
1891 (set_attr "predicable" "yes")
1892 (set_attr "predicable_short_it" "no")]
1895 (define_expand "smulsi3_highpart"
1897 [(set (match_operand:SI 0 "s_register_operand" "")
1901 (sign_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1902 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1904 (clobber (match_scratch:SI 3 ""))])]
1905 "TARGET_32BIT && arm_arch3m"
1909 (define_insn "*smulsi3_highpart_nov6"
1910 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1914 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "%0,r"))
1915 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r,r")))
1917 (clobber (match_scratch:SI 3 "=&r,&r"))]
1918 "TARGET_32BIT && arm_arch3m && !arm_arch6"
1919 "smull%?\\t%3, %0, %2, %1"
1920 [(set_attr "type" "smull")
1921 (set_attr "predicable" "yes")]
1924 (define_insn "*smulsi3_highpart_v6"
1925 [(set (match_operand:SI 0 "s_register_operand" "=r")
1929 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1930 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r")))
1932 (clobber (match_scratch:SI 3 "=r"))]
1933 "TARGET_32BIT && arm_arch6"
1934 "smull%?\\t%3, %0, %2, %1"
1935 [(set_attr "type" "smull")
1936 (set_attr "predicable" "yes")
1937 (set_attr "predicable_short_it" "no")]
1940 (define_expand "umulsi3_highpart"
1942 [(set (match_operand:SI 0 "s_register_operand" "")
1946 (zero_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1947 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1949 (clobber (match_scratch:SI 3 ""))])]
1950 "TARGET_32BIT && arm_arch3m"
1954 (define_insn "*umulsi3_highpart_nov6"
1955 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1959 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "%0,r"))
1960 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r,r")))
1962 (clobber (match_scratch:SI 3 "=&r,&r"))]
1963 "TARGET_32BIT && arm_arch3m && !arm_arch6"
1964 "umull%?\\t%3, %0, %2, %1"
1965 [(set_attr "type" "umull")
1966 (set_attr "predicable" "yes")]
1969 (define_insn "*umulsi3_highpart_v6"
1970 [(set (match_operand:SI 0 "s_register_operand" "=r")
1974 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1975 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r")))
1977 (clobber (match_scratch:SI 3 "=r"))]
1978 "TARGET_32BIT && arm_arch6"
1979 "umull%?\\t%3, %0, %2, %1"
1980 [(set_attr "type" "umull")
1981 (set_attr "predicable" "yes")
1982 (set_attr "predicable_short_it" "no")]
1985 (define_insn "mulhisi3"
1986 [(set (match_operand:SI 0 "s_register_operand" "=r")
1987 (mult:SI (sign_extend:SI
1988 (match_operand:HI 1 "s_register_operand" "%r"))
1990 (match_operand:HI 2 "s_register_operand" "r"))))]
1991 "TARGET_DSP_MULTIPLY"
1992 "smulbb%?\\t%0, %1, %2"
1993 [(set_attr "type" "smulxy")
1994 (set_attr "predicable" "yes")]
1997 (define_insn "*mulhisi3tb"
1998 [(set (match_operand:SI 0 "s_register_operand" "=r")
1999 (mult:SI (ashiftrt:SI
2000 (match_operand:SI 1 "s_register_operand" "r")
2003 (match_operand:HI 2 "s_register_operand" "r"))))]
2004 "TARGET_DSP_MULTIPLY"
2005 "smultb%?\\t%0, %1, %2"
2006 [(set_attr "type" "smulxy")
2007 (set_attr "predicable" "yes")
2008 (set_attr "predicable_short_it" "no")]
2011 (define_insn "*mulhisi3bt"
2012 [(set (match_operand:SI 0 "s_register_operand" "=r")
2013 (mult:SI (sign_extend:SI
2014 (match_operand:HI 1 "s_register_operand" "r"))
2016 (match_operand:SI 2 "s_register_operand" "r")
2018 "TARGET_DSP_MULTIPLY"
2019 "smulbt%?\\t%0, %1, %2"
2020 [(set_attr "type" "smulxy")
2021 (set_attr "predicable" "yes")
2022 (set_attr "predicable_short_it" "no")]
2025 (define_insn "*mulhisi3tt"
2026 [(set (match_operand:SI 0 "s_register_operand" "=r")
2027 (mult:SI (ashiftrt:SI
2028 (match_operand:SI 1 "s_register_operand" "r")
2031 (match_operand:SI 2 "s_register_operand" "r")
2033 "TARGET_DSP_MULTIPLY"
2034 "smultt%?\\t%0, %1, %2"
2035 [(set_attr "type" "smulxy")
2036 (set_attr "predicable" "yes")
2037 (set_attr "predicable_short_it" "no")]
2040 (define_insn "maddhisi4"
2041 [(set (match_operand:SI 0 "s_register_operand" "=r")
2042 (plus:SI (mult:SI (sign_extend:SI
2043 (match_operand:HI 1 "s_register_operand" "r"))
2045 (match_operand:HI 2 "s_register_operand" "r")))
2046 (match_operand:SI 3 "s_register_operand" "r")))]
2047 "TARGET_DSP_MULTIPLY"
2048 "smlabb%?\\t%0, %1, %2, %3"
2049 [(set_attr "type" "smlaxy")
2050 (set_attr "predicable" "yes")
2051 (set_attr "predicable_short_it" "no")]
2054 ;; Note: there is no maddhisi4ibt because this one is canonical form
2055 (define_insn "*maddhisi4tb"
2056 [(set (match_operand:SI 0 "s_register_operand" "=r")
2057 (plus:SI (mult:SI (ashiftrt:SI
2058 (match_operand:SI 1 "s_register_operand" "r")
2061 (match_operand:HI 2 "s_register_operand" "r")))
2062 (match_operand:SI 3 "s_register_operand" "r")))]
2063 "TARGET_DSP_MULTIPLY"
2064 "smlatb%?\\t%0, %1, %2, %3"
2065 [(set_attr "type" "smlaxy")
2066 (set_attr "predicable" "yes")
2067 (set_attr "predicable_short_it" "no")]
2070 (define_insn "*maddhisi4tt"
2071 [(set (match_operand:SI 0 "s_register_operand" "=r")
2072 (plus:SI (mult:SI (ashiftrt:SI
2073 (match_operand:SI 1 "s_register_operand" "r")
2076 (match_operand:SI 2 "s_register_operand" "r")
2078 (match_operand:SI 3 "s_register_operand" "r")))]
2079 "TARGET_DSP_MULTIPLY"
2080 "smlatt%?\\t%0, %1, %2, %3"
2081 [(set_attr "type" "smlaxy")
2082 (set_attr "predicable" "yes")
2083 (set_attr "predicable_short_it" "no")]
2086 (define_insn "maddhidi4"
2087 [(set (match_operand:DI 0 "s_register_operand" "=r")
2089 (mult:DI (sign_extend:DI
2090 (match_operand:HI 1 "s_register_operand" "r"))
2092 (match_operand:HI 2 "s_register_operand" "r")))
2093 (match_operand:DI 3 "s_register_operand" "0")))]
2094 "TARGET_DSP_MULTIPLY"
2095 "smlalbb%?\\t%Q0, %R0, %1, %2"
2096 [(set_attr "type" "smlalxy")
2097 (set_attr "predicable" "yes")
2098 (set_attr "predicable_short_it" "no")])
2100 ;; Note: there is no maddhidi4ibt because this one is canonical form
2101 (define_insn "*maddhidi4tb"
2102 [(set (match_operand:DI 0 "s_register_operand" "=r")
2104 (mult:DI (sign_extend:DI
2106 (match_operand:SI 1 "s_register_operand" "r")
2109 (match_operand:HI 2 "s_register_operand" "r")))
2110 (match_operand:DI 3 "s_register_operand" "0")))]
2111 "TARGET_DSP_MULTIPLY"
2112 "smlaltb%?\\t%Q0, %R0, %1, %2"
2113 [(set_attr "type" "smlalxy")
2114 (set_attr "predicable" "yes")
2115 (set_attr "predicable_short_it" "no")])
2117 (define_insn "*maddhidi4tt"
2118 [(set (match_operand:DI 0 "s_register_operand" "=r")
2120 (mult:DI (sign_extend:DI
2122 (match_operand:SI 1 "s_register_operand" "r")
2126 (match_operand:SI 2 "s_register_operand" "r")
2128 (match_operand:DI 3 "s_register_operand" "0")))]
2129 "TARGET_DSP_MULTIPLY"
2130 "smlaltt%?\\t%Q0, %R0, %1, %2"
2131 [(set_attr "type" "smlalxy")
2132 (set_attr "predicable" "yes")
2133 (set_attr "predicable_short_it" "no")])
2135 (define_expand "mulsf3"
2136 [(set (match_operand:SF 0 "s_register_operand" "")
2137 (mult:SF (match_operand:SF 1 "s_register_operand" "")
2138 (match_operand:SF 2 "s_register_operand" "")))]
2139 "TARGET_32BIT && TARGET_HARD_FLOAT"
2143 (define_expand "muldf3"
2144 [(set (match_operand:DF 0 "s_register_operand" "")
2145 (mult:DF (match_operand:DF 1 "s_register_operand" "")
2146 (match_operand:DF 2 "s_register_operand" "")))]
2147 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
2153 (define_expand "divsf3"
2154 [(set (match_operand:SF 0 "s_register_operand" "")
2155 (div:SF (match_operand:SF 1 "s_register_operand" "")
2156 (match_operand:SF 2 "s_register_operand" "")))]
2157 "TARGET_32BIT && TARGET_HARD_FLOAT"
2160 (define_expand "divdf3"
2161 [(set (match_operand:DF 0 "s_register_operand" "")
2162 (div:DF (match_operand:DF 1 "s_register_operand" "")
2163 (match_operand:DF 2 "s_register_operand" "")))]
2164 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
2167 ;; Boolean and,ior,xor insns
2169 ;; Split up double word logical operations
2171 ;; Split up simple DImode logical operations. Simply perform the logical
2172 ;; operation on the upper and lower halves of the registers.
2174 [(set (match_operand:DI 0 "s_register_operand" "")
2175 (match_operator:DI 6 "logical_binary_operator"
2176 [(match_operand:DI 1 "s_register_operand" "")
2177 (match_operand:DI 2 "s_register_operand" "")]))]
2178 "TARGET_32BIT && reload_completed
2179 && ! (TARGET_NEON && IS_VFP_REGNUM (REGNO (operands[0])))
2180 && ! IS_IWMMXT_REGNUM (REGNO (operands[0]))"
2181 [(set (match_dup 0) (match_op_dup:SI 6 [(match_dup 1) (match_dup 2)]))
2182 (set (match_dup 3) (match_op_dup:SI 6 [(match_dup 4) (match_dup 5)]))]
2185 operands[3] = gen_highpart (SImode, operands[0]);
2186 operands[0] = gen_lowpart (SImode, operands[0]);
2187 operands[4] = gen_highpart (SImode, operands[1]);
2188 operands[1] = gen_lowpart (SImode, operands[1]);
2189 operands[5] = gen_highpart (SImode, operands[2]);
2190 operands[2] = gen_lowpart (SImode, operands[2]);
2195 [(set (match_operand:DI 0 "s_register_operand" "")
2196 (match_operator:DI 6 "logical_binary_operator"
2197 [(sign_extend:DI (match_operand:SI 2 "s_register_operand" ""))
2198 (match_operand:DI 1 "s_register_operand" "")]))]
2199 "TARGET_32BIT && reload_completed"
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
2202 [(ashiftrt:SI (match_dup 2) (const_int 31))
2206 operands[3] = gen_highpart (SImode, operands[0]);
2207 operands[0] = gen_lowpart (SImode, operands[0]);
2208 operands[4] = gen_highpart (SImode, operands[1]);
2209 operands[1] = gen_lowpart (SImode, operands[1]);
2210 operands[5] = gen_highpart (SImode, operands[2]);
2211 operands[2] = gen_lowpart (SImode, operands[2]);
2215 ;; The zero extend of operand 2 means we can just copy the high part of
2216 ;; operand1 into operand0.
2218 [(set (match_operand:DI 0 "s_register_operand" "")
2220 (zero_extend:DI (match_operand:SI 2 "s_register_operand" ""))
2221 (match_operand:DI 1 "s_register_operand" "")))]
2222 "TARGET_32BIT && operands[0] != operands[1] && reload_completed"
2223 [(set (match_dup 0) (ior:SI (match_dup 1) (match_dup 2)))
2224 (set (match_dup 3) (match_dup 4))]
2227 operands[4] = gen_highpart (SImode, operands[1]);
2228 operands[3] = gen_highpart (SImode, operands[0]);
2229 operands[0] = gen_lowpart (SImode, operands[0]);
2230 operands[1] = gen_lowpart (SImode, operands[1]);
2234 ;; The zero extend of operand 2 means we can just copy the high part of
2235 ;; operand1 into operand0.
2237 [(set (match_operand:DI 0 "s_register_operand" "")
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) (xor:SI (match_dup 1) (match_dup 2)))
2243 (set (match_dup 3) (match_dup 4))]
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]);
2253 (define_expand "anddi3"
2254 [(set (match_operand:DI 0 "s_register_operand" "")
2255 (and:DI (match_operand:DI 1 "s_register_operand" "")
2256 (match_operand:DI 2 "neon_inv_logic_op2" "")))]
2261 (define_insn_and_split "*anddi3_insn"
2262 [(set (match_operand:DI 0 "s_register_operand" "=w,w ,&r,&r,&r,&r,?w,?w")
2263 (and:DI (match_operand:DI 1 "s_register_operand" "%w,0 ,0 ,r ,0 ,r ,w ,0")
2264 (match_operand:DI 2 "arm_anddi_operand_neon" "w ,DL,r ,r ,De,De,w ,DL")))]
2265 "TARGET_32BIT && !TARGET_IWMMXT"
2267 switch (which_alternative)
2269 case 0: /* fall through */
2270 case 6: return "vand\t%P0, %P1, %P2";
2271 case 1: /* fall through */
2272 case 7: return neon_output_logic_immediate ("vand", &operands[2],
2273 DImode, 1, VALID_NEON_QREG_MODE (DImode));
2277 case 5: /* fall through */
2279 default: gcc_unreachable ();
2282 "TARGET_32BIT && !TARGET_IWMMXT && reload_completed
2283 && !(IS_VFP_REGNUM (REGNO (operands[0])))"
2284 [(set (match_dup 3) (match_dup 4))
2285 (set (match_dup 5) (match_dup 6))]
2288 operands[3] = gen_lowpart (SImode, operands[0]);
2289 operands[5] = gen_highpart (SImode, operands[0]);
2291 operands[4] = simplify_gen_binary (AND, SImode,
2292 gen_lowpart (SImode, operands[1]),
2293 gen_lowpart (SImode, operands[2]));
2294 operands[6] = simplify_gen_binary (AND, SImode,
2295 gen_highpart (SImode, operands[1]),
2296 gen_highpart_mode (SImode, DImode, operands[2]));
2299 [(set_attr "type" "neon_logic,neon_logic,multiple,multiple,\
2300 multiple,multiple,neon_logic,neon_logic")
2301 (set_attr "arch" "neon_for_64bits,neon_for_64bits,*,*,*,*,
2302 avoid_neon_for_64bits,avoid_neon_for_64bits")
2303 (set_attr "length" "*,*,8,8,8,8,*,*")
2307 (define_insn_and_split "*anddi_zesidi_di"
2308 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2309 (and:DI (zero_extend:DI
2310 (match_operand:SI 2 "s_register_operand" "r,r"))
2311 (match_operand:DI 1 "s_register_operand" "0,r")))]
2314 "TARGET_32BIT && reload_completed"
2315 ; The zero extend of operand 2 clears the high word of the output
2317 [(set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))
2318 (set (match_dup 3) (const_int 0))]
2321 operands[3] = gen_highpart (SImode, operands[0]);
2322 operands[0] = gen_lowpart (SImode, operands[0]);
2323 operands[1] = gen_lowpart (SImode, operands[1]);
2325 [(set_attr "length" "8")
2326 (set_attr "type" "multiple")]
2329 (define_insn "*anddi_sesdi_di"
2330 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2331 (and:DI (sign_extend:DI
2332 (match_operand:SI 2 "s_register_operand" "r,r"))
2333 (match_operand:DI 1 "s_register_operand" "0,r")))]
2336 [(set_attr "length" "8")
2337 (set_attr "type" "multiple")]
2340 (define_expand "andsi3"
2341 [(set (match_operand:SI 0 "s_register_operand" "")
2342 (and:SI (match_operand:SI 1 "s_register_operand" "")
2343 (match_operand:SI 2 "reg_or_int_operand" "")))]
2348 if (CONST_INT_P (operands[2]))
2350 if (INTVAL (operands[2]) == 255 && arm_arch6)
2352 operands[1] = convert_to_mode (QImode, operands[1], 1);
2353 emit_insn (gen_thumb2_zero_extendqisi2_v6 (operands[0],
2357 else if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[2]), AND))
2358 operands[2] = force_reg (SImode, operands[2]);
2361 arm_split_constant (AND, SImode, NULL_RTX,
2362 INTVAL (operands[2]), operands[0],
2364 optimize && can_create_pseudo_p ());
2370 else /* TARGET_THUMB1 */
2372 if (!CONST_INT_P (operands[2]))
2374 rtx tmp = force_reg (SImode, operands[2]);
2375 if (rtx_equal_p (operands[0], operands[1]))
2379 operands[2] = operands[1];
2387 if (((unsigned HOST_WIDE_INT) ~INTVAL (operands[2])) < 256)
2389 operands[2] = force_reg (SImode,
2390 GEN_INT (~INTVAL (operands[2])));
2392 emit_insn (gen_thumb1_bicsi3 (operands[0], operands[2], operands[1]));
2397 for (i = 9; i <= 31; i++)
2399 if ((HOST_WIDE_INT_1 << i) - 1 == INTVAL (operands[2]))
2401 emit_insn (gen_extzv (operands[0], operands[1], GEN_INT (i),
2405 else if ((HOST_WIDE_INT_1 << i) - 1
2406 == ~INTVAL (operands[2]))
2408 rtx shift = GEN_INT (i);
2409 rtx reg = gen_reg_rtx (SImode);
2411 emit_insn (gen_lshrsi3 (reg, operands[1], shift));
2412 emit_insn (gen_ashlsi3 (operands[0], reg, shift));
2418 operands[2] = force_reg (SImode, operands[2]);
2424 ; ??? Check split length for Thumb-2
2425 (define_insn_and_split "*arm_andsi3_insn"
2426 [(set (match_operand:SI 0 "s_register_operand" "=r,l,r,r,r")
2427 (and:SI (match_operand:SI 1 "s_register_operand" "%r,0,r,r,r")
2428 (match_operand:SI 2 "reg_or_int_operand" "I,l,K,r,?n")))]
2433 bic%?\\t%0, %1, #%B2
2437 && CONST_INT_P (operands[2])
2438 && !(const_ok_for_arm (INTVAL (operands[2]))
2439 || const_ok_for_arm (~INTVAL (operands[2])))"
2440 [(clobber (const_int 0))]
2442 arm_split_constant (AND, SImode, curr_insn,
2443 INTVAL (operands[2]), operands[0], operands[1], 0);
2446 [(set_attr "length" "4,4,4,4,16")
2447 (set_attr "predicable" "yes")
2448 (set_attr "predicable_short_it" "no,yes,no,no,no")
2449 (set_attr "type" "logic_imm,logic_imm,logic_reg,logic_reg,logic_imm")]
2452 (define_insn "*andsi3_compare0"
2453 [(set (reg:CC_NOOV CC_REGNUM)
2455 (and:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
2456 (match_operand:SI 2 "arm_not_operand" "I,K,r"))
2458 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
2459 (and:SI (match_dup 1) (match_dup 2)))]
2463 bics%?\\t%0, %1, #%B2
2464 ands%?\\t%0, %1, %2"
2465 [(set_attr "conds" "set")
2466 (set_attr "type" "logics_imm,logics_imm,logics_reg")]
2469 (define_insn "*andsi3_compare0_scratch"
2470 [(set (reg:CC_NOOV CC_REGNUM)
2472 (and:SI (match_operand:SI 0 "s_register_operand" "r,r,r")
2473 (match_operand:SI 1 "arm_not_operand" "I,K,r"))
2475 (clobber (match_scratch:SI 2 "=X,r,X"))]
2479 bics%?\\t%2, %0, #%B1
2481 [(set_attr "conds" "set")
2482 (set_attr "type" "logics_imm,logics_imm,logics_reg")]
2485 (define_insn "*zeroextractsi_compare0_scratch"
2486 [(set (reg:CC_NOOV CC_REGNUM)
2487 (compare:CC_NOOV (zero_extract:SI
2488 (match_operand:SI 0 "s_register_operand" "r")
2489 (match_operand 1 "const_int_operand" "n")
2490 (match_operand 2 "const_int_operand" "n"))
2493 && (INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) < 32
2494 && INTVAL (operands[1]) > 0
2495 && INTVAL (operands[1]) + (INTVAL (operands[2]) & 1) <= 8
2496 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32)"
2498 operands[1] = GEN_INT (((1 << INTVAL (operands[1])) - 1)
2499 << INTVAL (operands[2]));
2500 output_asm_insn (\"tst%?\\t%0, %1\", operands);
2503 [(set_attr "conds" "set")
2504 (set_attr "predicable" "yes")
2505 (set_attr "predicable_short_it" "no")
2506 (set_attr "type" "logics_imm")]
2509 (define_insn_and_split "*ne_zeroextractsi"
2510 [(set (match_operand:SI 0 "s_register_operand" "=r")
2511 (ne:SI (zero_extract:SI
2512 (match_operand:SI 1 "s_register_operand" "r")
2513 (match_operand:SI 2 "const_int_operand" "n")
2514 (match_operand:SI 3 "const_int_operand" "n"))
2516 (clobber (reg:CC CC_REGNUM))]
2518 && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2519 && INTVAL (operands[2]) > 0
2520 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2521 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)"
2524 && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2525 && INTVAL (operands[2]) > 0
2526 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2527 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)"
2528 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2529 (compare:CC_NOOV (and:SI (match_dup 1) (match_dup 2))
2531 (set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))])
2533 (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2534 (match_dup 0) (const_int 1)))]
2536 operands[2] = GEN_INT (((1 << INTVAL (operands[2])) - 1)
2537 << INTVAL (operands[3]));
2539 [(set_attr "conds" "clob")
2540 (set (attr "length")
2541 (if_then_else (eq_attr "is_thumb" "yes")
2544 (set_attr "type" "multiple")]
2547 (define_insn_and_split "*ne_zeroextractsi_shifted"
2548 [(set (match_operand:SI 0 "s_register_operand" "=r")
2549 (ne:SI (zero_extract:SI
2550 (match_operand:SI 1 "s_register_operand" "r")
2551 (match_operand:SI 2 "const_int_operand" "n")
2554 (clobber (reg:CC CC_REGNUM))]
2558 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2559 (compare:CC_NOOV (ashift:SI (match_dup 1) (match_dup 2))
2561 (set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))])
2563 (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2564 (match_dup 0) (const_int 1)))]
2566 operands[2] = GEN_INT (32 - INTVAL (operands[2]));
2568 [(set_attr "conds" "clob")
2569 (set_attr "length" "8")
2570 (set_attr "type" "multiple")]
2573 (define_insn_and_split "*ite_ne_zeroextractsi"
2574 [(set (match_operand:SI 0 "s_register_operand" "=r")
2575 (if_then_else:SI (ne (zero_extract:SI
2576 (match_operand:SI 1 "s_register_operand" "r")
2577 (match_operand:SI 2 "const_int_operand" "n")
2578 (match_operand:SI 3 "const_int_operand" "n"))
2580 (match_operand:SI 4 "arm_not_operand" "rIK")
2582 (clobber (reg:CC CC_REGNUM))]
2584 && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2585 && INTVAL (operands[2]) > 0
2586 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2587 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)
2588 && !reg_overlap_mentioned_p (operands[0], operands[4])"
2591 && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2592 && INTVAL (operands[2]) > 0
2593 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2594 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)
2595 && !reg_overlap_mentioned_p (operands[0], operands[4])"
2596 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2597 (compare:CC_NOOV (and:SI (match_dup 1) (match_dup 2))
2599 (set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))])
2601 (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2602 (match_dup 0) (match_dup 4)))]
2604 operands[2] = GEN_INT (((1 << INTVAL (operands[2])) - 1)
2605 << INTVAL (operands[3]));
2607 [(set_attr "conds" "clob")
2608 (set_attr "length" "8")
2609 (set_attr "type" "multiple")]
2612 (define_insn_and_split "*ite_ne_zeroextractsi_shifted"
2613 [(set (match_operand:SI 0 "s_register_operand" "=r")
2614 (if_then_else:SI (ne (zero_extract:SI
2615 (match_operand:SI 1 "s_register_operand" "r")
2616 (match_operand:SI 2 "const_int_operand" "n")
2619 (match_operand:SI 3 "arm_not_operand" "rIK")
2621 (clobber (reg:CC CC_REGNUM))]
2622 "TARGET_ARM && !reg_overlap_mentioned_p (operands[0], operands[3])"
2624 "TARGET_ARM && !reg_overlap_mentioned_p (operands[0], operands[3])"
2625 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2626 (compare:CC_NOOV (ashift:SI (match_dup 1) (match_dup 2))
2628 (set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))])
2630 (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2631 (match_dup 0) (match_dup 3)))]
2633 operands[2] = GEN_INT (32 - INTVAL (operands[2]));
2635 [(set_attr "conds" "clob")
2636 (set_attr "length" "8")
2637 (set_attr "type" "multiple")]
2640 ;; ??? Use Thumb-2 has bitfield insert/extract instructions.
2642 [(set (match_operand:SI 0 "s_register_operand" "")
2643 (match_operator:SI 1 "shiftable_operator"
2644 [(zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
2645 (match_operand:SI 3 "const_int_operand" "")
2646 (match_operand:SI 4 "const_int_operand" ""))
2647 (match_operand:SI 5 "s_register_operand" "")]))
2648 (clobber (match_operand:SI 6 "s_register_operand" ""))]
2650 [(set (match_dup 6) (ashift:SI (match_dup 2) (match_dup 3)))
2653 [(lshiftrt:SI (match_dup 6) (match_dup 4))
2656 HOST_WIDE_INT temp = INTVAL (operands[3]);
2658 operands[3] = GEN_INT (32 - temp - INTVAL (operands[4]));
2659 operands[4] = GEN_INT (32 - temp);
2664 [(set (match_operand:SI 0 "s_register_operand" "")
2665 (match_operator:SI 1 "shiftable_operator"
2666 [(sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
2667 (match_operand:SI 3 "const_int_operand" "")
2668 (match_operand:SI 4 "const_int_operand" ""))
2669 (match_operand:SI 5 "s_register_operand" "")]))
2670 (clobber (match_operand:SI 6 "s_register_operand" ""))]
2672 [(set (match_dup 6) (ashift:SI (match_dup 2) (match_dup 3)))
2675 [(ashiftrt:SI (match_dup 6) (match_dup 4))
2678 HOST_WIDE_INT temp = INTVAL (operands[3]);
2680 operands[3] = GEN_INT (32 - temp - INTVAL (operands[4]));
2681 operands[4] = GEN_INT (32 - temp);
2685 ;;; ??? This pattern is bogus. If operand3 has bits outside the range
2686 ;;; represented by the bitfield, then this will produce incorrect results.
2687 ;;; Somewhere, the value needs to be truncated. On targets like the m68k,
2688 ;;; which have a real bit-field insert instruction, the truncation happens
2689 ;;; in the bit-field insert instruction itself. Since arm does not have a
2690 ;;; bit-field insert instruction, we would have to emit code here to truncate
2691 ;;; the value before we insert. This loses some of the advantage of having
2692 ;;; this insv pattern, so this pattern needs to be reevalutated.
2694 (define_expand "insv"
2695 [(set (zero_extract (match_operand 0 "nonimmediate_operand" "")
2696 (match_operand 1 "general_operand" "")
2697 (match_operand 2 "general_operand" ""))
2698 (match_operand 3 "reg_or_int_operand" ""))]
2699 "TARGET_ARM || arm_arch_thumb2"
2702 int start_bit = INTVAL (operands[2]);
2703 int width = INTVAL (operands[1]);
2704 HOST_WIDE_INT mask = (HOST_WIDE_INT_1 << width) - 1;
2705 rtx target, subtarget;
2707 if (arm_arch_thumb2)
2709 if (unaligned_access && MEM_P (operands[0])
2710 && s_register_operand (operands[3], GET_MODE (operands[3]))
2711 && (width == 16 || width == 32) && (start_bit % BITS_PER_UNIT) == 0)
2715 if (BYTES_BIG_ENDIAN)
2716 start_bit = GET_MODE_BITSIZE (GET_MODE (operands[3])) - width
2721 base_addr = adjust_address (operands[0], SImode,
2722 start_bit / BITS_PER_UNIT);
2723 emit_insn (gen_unaligned_storesi (base_addr, operands[3]));
2727 rtx tmp = gen_reg_rtx (HImode);
2729 base_addr = adjust_address (operands[0], HImode,
2730 start_bit / BITS_PER_UNIT);
2731 emit_move_insn (tmp, gen_lowpart (HImode, operands[3]));
2732 emit_insn (gen_unaligned_storehi (base_addr, tmp));
2736 else if (s_register_operand (operands[0], GET_MODE (operands[0])))
2738 bool use_bfi = TRUE;
2740 if (CONST_INT_P (operands[3]))
2742 HOST_WIDE_INT val = INTVAL (operands[3]) & mask;
2746 emit_insn (gen_insv_zero (operands[0], operands[1],
2751 /* See if the set can be done with a single orr instruction. */
2752 if (val == mask && const_ok_for_arm (val << start_bit))
2758 if (!REG_P (operands[3]))
2759 operands[3] = force_reg (SImode, operands[3]);
2761 emit_insn (gen_insv_t2 (operands[0], operands[1], operands[2],
2770 if (!s_register_operand (operands[0], GET_MODE (operands[0])))
2773 target = copy_rtx (operands[0]);
2774 /* Avoid using a subreg as a subtarget, and avoid writing a paradoxical
2775 subreg as the final target. */
2776 if (GET_CODE (target) == SUBREG)
2778 subtarget = gen_reg_rtx (SImode);
2779 if (GET_MODE_SIZE (GET_MODE (SUBREG_REG (target)))
2780 < GET_MODE_SIZE (SImode))
2781 target = SUBREG_REG (target);
2786 if (CONST_INT_P (operands[3]))
2788 /* Since we are inserting a known constant, we may be able to
2789 reduce the number of bits that we have to clear so that
2790 the mask becomes simple. */
2791 /* ??? This code does not check to see if the new mask is actually
2792 simpler. It may not be. */
2793 rtx op1 = gen_reg_rtx (SImode);
2794 /* ??? Truncate operand3 to fit in the bitfield. See comment before
2795 start of this pattern. */
2796 HOST_WIDE_INT op3_value = mask & INTVAL (operands[3]);
2797 HOST_WIDE_INT mask2 = ((mask & ~op3_value) << start_bit);
2799 emit_insn (gen_andsi3 (op1, operands[0],
2800 gen_int_mode (~mask2, SImode)));
2801 emit_insn (gen_iorsi3 (subtarget, op1,
2802 gen_int_mode (op3_value << start_bit, SImode)));
2804 else if (start_bit == 0
2805 && !(const_ok_for_arm (mask)
2806 || const_ok_for_arm (~mask)))
2808 /* A Trick, since we are setting the bottom bits in the word,
2809 we can shift operand[3] up, operand[0] down, OR them together
2810 and rotate the result back again. This takes 3 insns, and
2811 the third might be mergeable into another op. */
2812 /* The shift up copes with the possibility that operand[3] is
2813 wider than the bitfield. */
2814 rtx op0 = gen_reg_rtx (SImode);
2815 rtx op1 = gen_reg_rtx (SImode);
2817 emit_insn (gen_ashlsi3 (op0, operands[3], GEN_INT (32 - width)));
2818 emit_insn (gen_lshrsi3 (op1, operands[0], operands[1]));
2819 emit_insn (gen_iorsi3 (op1, op1, op0));
2820 emit_insn (gen_rotlsi3 (subtarget, op1, operands[1]));
2822 else if ((width + start_bit == 32)
2823 && !(const_ok_for_arm (mask)
2824 || const_ok_for_arm (~mask)))
2826 /* Similar trick, but slightly less efficient. */
2828 rtx op0 = gen_reg_rtx (SImode);
2829 rtx op1 = gen_reg_rtx (SImode);
2831 emit_insn (gen_ashlsi3 (op0, operands[3], GEN_INT (32 - width)));
2832 emit_insn (gen_ashlsi3 (op1, operands[0], operands[1]));
2833 emit_insn (gen_lshrsi3 (op1, op1, operands[1]));
2834 emit_insn (gen_iorsi3 (subtarget, op1, op0));
2838 rtx op0 = gen_int_mode (mask, SImode);
2839 rtx op1 = gen_reg_rtx (SImode);
2840 rtx op2 = gen_reg_rtx (SImode);
2842 if (!(const_ok_for_arm (mask) || const_ok_for_arm (~mask)))
2844 rtx tmp = gen_reg_rtx (SImode);
2846 emit_insn (gen_movsi (tmp, op0));
2850 /* Mask out any bits in operand[3] that are not needed. */
2851 emit_insn (gen_andsi3 (op1, operands[3], op0));
2853 if (CONST_INT_P (op0)
2854 && (const_ok_for_arm (mask << start_bit)
2855 || const_ok_for_arm (~(mask << start_bit))))
2857 op0 = gen_int_mode (~(mask << start_bit), SImode);
2858 emit_insn (gen_andsi3 (op2, operands[0], op0));
2862 if (CONST_INT_P (op0))
2864 rtx tmp = gen_reg_rtx (SImode);
2866 emit_insn (gen_movsi (tmp, op0));
2871 emit_insn (gen_ashlsi3 (op0, op0, operands[2]));
2873 emit_insn (gen_andsi_notsi_si (op2, operands[0], op0));
2877 emit_insn (gen_ashlsi3 (op1, op1, operands[2]));
2879 emit_insn (gen_iorsi3 (subtarget, op1, op2));
2882 if (subtarget != target)
2884 /* If TARGET is still a SUBREG, then it must be wider than a word,
2885 so we must be careful only to set the subword we were asked to. */
2886 if (GET_CODE (target) == SUBREG)
2887 emit_move_insn (target, subtarget);
2889 emit_move_insn (target, gen_lowpart (GET_MODE (target), subtarget));
2896 (define_insn "insv_zero"
2897 [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r")
2898 (match_operand:SI 1 "const_int_M_operand" "M")
2899 (match_operand:SI 2 "const_int_M_operand" "M"))
2903 [(set_attr "length" "4")
2904 (set_attr "predicable" "yes")
2905 (set_attr "predicable_short_it" "no")
2906 (set_attr "type" "bfm")]
2909 (define_insn "insv_t2"
2910 [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r")
2911 (match_operand:SI 1 "const_int_M_operand" "M")
2912 (match_operand:SI 2 "const_int_M_operand" "M"))
2913 (match_operand:SI 3 "s_register_operand" "r"))]
2915 "bfi%?\t%0, %3, %2, %1"
2916 [(set_attr "length" "4")
2917 (set_attr "predicable" "yes")
2918 (set_attr "predicable_short_it" "no")
2919 (set_attr "type" "bfm")]
2922 ; constants for op 2 will never be given to these patterns.
2923 (define_insn_and_split "*anddi_notdi_di"
2924 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2925 (and:DI (not:DI (match_operand:DI 1 "s_register_operand" "0,r"))
2926 (match_operand:DI 2 "s_register_operand" "r,0")))]
2929 "TARGET_32BIT && reload_completed
2930 && ! (TARGET_NEON && IS_VFP_REGNUM (REGNO (operands[0])))
2931 && ! IS_IWMMXT_REGNUM (REGNO (operands[0]))"
2932 [(set (match_dup 0) (and:SI (not:SI (match_dup 1)) (match_dup 2)))
2933 (set (match_dup 3) (and:SI (not:SI (match_dup 4)) (match_dup 5)))]
2936 operands[3] = gen_highpart (SImode, operands[0]);
2937 operands[0] = gen_lowpart (SImode, operands[0]);
2938 operands[4] = gen_highpart (SImode, operands[1]);
2939 operands[1] = gen_lowpart (SImode, operands[1]);
2940 operands[5] = gen_highpart (SImode, operands[2]);
2941 operands[2] = gen_lowpart (SImode, operands[2]);
2943 [(set_attr "length" "8")
2944 (set_attr "predicable" "yes")
2945 (set_attr "type" "multiple")]
2948 (define_insn_and_split "*anddi_notzesidi_di"
2949 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2950 (and:DI (not:DI (zero_extend:DI
2951 (match_operand:SI 2 "s_register_operand" "r,r")))
2952 (match_operand:DI 1 "s_register_operand" "0,?r")))]
2955 bic%?\\t%Q0, %Q1, %2
2957 ; (not (zero_extend ...)) allows us to just copy the high word from
2958 ; operand1 to operand0.
2961 && operands[0] != operands[1]"
2962 [(set (match_dup 0) (and:SI (not:SI (match_dup 2)) (match_dup 1)))
2963 (set (match_dup 3) (match_dup 4))]
2966 operands[3] = gen_highpart (SImode, operands[0]);
2967 operands[0] = gen_lowpart (SImode, operands[0]);
2968 operands[4] = gen_highpart (SImode, operands[1]);
2969 operands[1] = gen_lowpart (SImode, operands[1]);
2971 [(set_attr "length" "4,8")
2972 (set_attr "predicable" "yes")
2973 (set_attr "predicable_short_it" "no")
2974 (set_attr "type" "multiple")]
2977 (define_insn_and_split "*anddi_notdi_zesidi"
2978 [(set (match_operand:DI 0 "s_register_operand" "=r")
2979 (and:DI (not:DI (match_operand:DI 2 "s_register_operand" "r"))
2981 (match_operand:SI 1 "s_register_operand" "r"))))]
2984 "TARGET_32BIT && reload_completed"
2985 [(set (match_dup 0) (and:SI (not:SI (match_dup 2)) (match_dup 1)))
2986 (set (match_dup 3) (const_int 0))]
2989 operands[3] = gen_highpart (SImode, operands[0]);
2990 operands[0] = gen_lowpart (SImode, operands[0]);
2991 operands[2] = gen_lowpart (SImode, operands[2]);
2993 [(set_attr "length" "8")
2994 (set_attr "predicable" "yes")
2995 (set_attr "predicable_short_it" "no")
2996 (set_attr "type" "multiple")]
2999 (define_insn_and_split "*anddi_notsesidi_di"
3000 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
3001 (and:DI (not:DI (sign_extend:DI
3002 (match_operand:SI 2 "s_register_operand" "r,r")))
3003 (match_operand:DI 1 "s_register_operand" "0,r")))]
3006 "TARGET_32BIT && reload_completed"
3007 [(set (match_dup 0) (and:SI (not:SI (match_dup 2)) (match_dup 1)))
3008 (set (match_dup 3) (and:SI (not:SI
3009 (ashiftrt:SI (match_dup 2) (const_int 31)))
3013 operands[3] = gen_highpart (SImode, operands[0]);
3014 operands[0] = gen_lowpart (SImode, operands[0]);
3015 operands[4] = gen_highpart (SImode, operands[1]);
3016 operands[1] = gen_lowpart (SImode, operands[1]);
3018 [(set_attr "length" "8")
3019 (set_attr "predicable" "yes")
3020 (set_attr "predicable_short_it" "no")
3021 (set_attr "type" "multiple")]
3024 (define_insn "andsi_notsi_si"
3025 [(set (match_operand:SI 0 "s_register_operand" "=r")
3026 (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
3027 (match_operand:SI 1 "s_register_operand" "r")))]
3029 "bic%?\\t%0, %1, %2"
3030 [(set_attr "predicable" "yes")
3031 (set_attr "predicable_short_it" "no")
3032 (set_attr "type" "logic_reg")]
3035 (define_insn "andsi_not_shiftsi_si"
3036 [(set (match_operand:SI 0 "s_register_operand" "=r")
3037 (and:SI (not:SI (match_operator:SI 4 "shift_operator"
3038 [(match_operand:SI 2 "s_register_operand" "r")
3039 (match_operand:SI 3 "arm_rhs_operand" "rM")]))
3040 (match_operand:SI 1 "s_register_operand" "r")))]
3042 "bic%?\\t%0, %1, %2%S4"
3043 [(set_attr "predicable" "yes")
3044 (set_attr "shift" "2")
3045 (set (attr "type") (if_then_else (match_operand 3 "const_int_operand" "")
3046 (const_string "logic_shift_imm")
3047 (const_string "logic_shift_reg")))]
3050 ;; Shifted bics pattern used to set up CC status register and not reusing
3051 ;; bics output. Pattern restricts Thumb2 shift operand as bics for Thumb2
3052 ;; does not support shift by register.
3053 (define_insn "andsi_not_shiftsi_si_scc_no_reuse"
3054 [(set (reg:CC_NOOV CC_REGNUM)
3056 (and:SI (not:SI (match_operator:SI 0 "shift_operator"
3057 [(match_operand:SI 1 "s_register_operand" "r")
3058 (match_operand:SI 2 "arm_rhs_operand" "rM")]))
3059 (match_operand:SI 3 "s_register_operand" "r"))
3061 (clobber (match_scratch:SI 4 "=r"))]
3062 "TARGET_ARM || (TARGET_THUMB2 && CONST_INT_P (operands[2]))"
3063 "bics%?\\t%4, %3, %1%S0"
3064 [(set_attr "predicable" "yes")
3065 (set_attr "predicable_short_it" "no")
3066 (set_attr "conds" "set")
3067 (set_attr "shift" "1")
3068 (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
3069 (const_string "logic_shift_imm")
3070 (const_string "logic_shift_reg")))]
3073 ;; Same as andsi_not_shiftsi_si_scc_no_reuse, but the bics result is also
3074 ;; getting reused later.
3075 (define_insn "andsi_not_shiftsi_si_scc"
3076 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
3078 (and:SI (not:SI (match_operator:SI 0 "shift_operator"
3079 [(match_operand:SI 1 "s_register_operand" "r")
3080 (match_operand:SI 2 "arm_rhs_operand" "rM")]))
3081 (match_operand:SI 3 "s_register_operand" "r"))
3083 (set (match_operand:SI 4 "s_register_operand" "=r")
3084 (and:SI (not:SI (match_op_dup 0
3088 "TARGET_ARM || (TARGET_THUMB2 && CONST_INT_P (operands[2]))"
3089 "bics%?\\t%4, %3, %1%S0"
3090 [(set_attr "predicable" "yes")
3091 (set_attr "predicable_short_it" "no")
3092 (set_attr "conds" "set")
3093 (set_attr "shift" "1")
3094 (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
3095 (const_string "logic_shift_imm")
3096 (const_string "logic_shift_reg")))]
3099 (define_insn "*andsi_notsi_si_compare0"
3100 [(set (reg:CC_NOOV CC_REGNUM)
3102 (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
3103 (match_operand:SI 1 "s_register_operand" "r"))
3105 (set (match_operand:SI 0 "s_register_operand" "=r")
3106 (and:SI (not:SI (match_dup 2)) (match_dup 1)))]
3109 [(set_attr "conds" "set")
3110 (set_attr "type" "logics_shift_reg")]
3113 (define_insn "*andsi_notsi_si_compare0_scratch"
3114 [(set (reg:CC_NOOV CC_REGNUM)
3116 (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
3117 (match_operand:SI 1 "s_register_operand" "r"))
3119 (clobber (match_scratch:SI 0 "=r"))]
3122 [(set_attr "conds" "set")
3123 (set_attr "type" "logics_shift_reg")]
3126 (define_expand "iordi3"
3127 [(set (match_operand:DI 0 "s_register_operand" "")
3128 (ior:DI (match_operand:DI 1 "s_register_operand" "")
3129 (match_operand:DI 2 "neon_logic_op2" "")))]
3134 (define_insn_and_split "*iordi3_insn"
3135 [(set (match_operand:DI 0 "s_register_operand" "=w,w ,&r,&r,&r,&r,?w,?w")
3136 (ior:DI (match_operand:DI 1 "s_register_operand" "%w,0 ,0 ,r ,0 ,r ,w ,0")
3137 (match_operand:DI 2 "arm_iordi_operand_neon" "w ,Dl,r ,r ,Df,Df,w ,Dl")))]
3138 "TARGET_32BIT && !TARGET_IWMMXT"
3140 switch (which_alternative)
3142 case 0: /* fall through */
3143 case 6: return "vorr\t%P0, %P1, %P2";
3144 case 1: /* fall through */
3145 case 7: return neon_output_logic_immediate ("vorr", &operands[2],
3146 DImode, 0, VALID_NEON_QREG_MODE (DImode));
3152 default: gcc_unreachable ();
3155 "TARGET_32BIT && !TARGET_IWMMXT && reload_completed
3156 && !(IS_VFP_REGNUM (REGNO (operands[0])))"
3157 [(set (match_dup 3) (match_dup 4))
3158 (set (match_dup 5) (match_dup 6))]
3161 operands[3] = gen_lowpart (SImode, operands[0]);
3162 operands[5] = gen_highpart (SImode, operands[0]);
3164 operands[4] = simplify_gen_binary (IOR, SImode,
3165 gen_lowpart (SImode, operands[1]),
3166 gen_lowpart (SImode, operands[2]));
3167 operands[6] = simplify_gen_binary (IOR, SImode,
3168 gen_highpart (SImode, operands[1]),
3169 gen_highpart_mode (SImode, DImode, operands[2]));
3172 [(set_attr "type" "neon_logic,neon_logic,multiple,multiple,multiple,\
3173 multiple,neon_logic,neon_logic")
3174 (set_attr "length" "*,*,8,8,8,8,*,*")
3175 (set_attr "arch" "neon_for_64bits,neon_for_64bits,*,*,*,*,avoid_neon_for_64bits,avoid_neon_for_64bits")]
3178 (define_insn "*iordi_zesidi_di"
3179 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
3180 (ior:DI (zero_extend:DI
3181 (match_operand:SI 2 "s_register_operand" "r,r"))
3182 (match_operand:DI 1 "s_register_operand" "0,?r")))]
3185 orr%?\\t%Q0, %Q1, %2
3187 [(set_attr "length" "4,8")
3188 (set_attr "predicable" "yes")
3189 (set_attr "predicable_short_it" "no")
3190 (set_attr "type" "logic_reg,multiple")]
3193 (define_insn "*iordi_sesidi_di"
3194 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
3195 (ior:DI (sign_extend:DI
3196 (match_operand:SI 2 "s_register_operand" "r,r"))
3197 (match_operand:DI 1 "s_register_operand" "0,r")))]
3200 [(set_attr "length" "8")
3201 (set_attr "predicable" "yes")
3202 (set_attr "type" "multiple")]
3205 (define_expand "iorsi3"
3206 [(set (match_operand:SI 0 "s_register_operand" "")
3207 (ior:SI (match_operand:SI 1 "s_register_operand" "")
3208 (match_operand:SI 2 "reg_or_int_operand" "")))]
3211 if (CONST_INT_P (operands[2]))
3215 if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[2]), IOR))
3216 operands[2] = force_reg (SImode, operands[2]);
3219 arm_split_constant (IOR, SImode, NULL_RTX,
3220 INTVAL (operands[2]), operands[0],
3222 optimize && can_create_pseudo_p ());
3226 else /* TARGET_THUMB1 */
3228 rtx tmp = force_reg (SImode, operands[2]);
3229 if (rtx_equal_p (operands[0], operands[1]))
3233 operands[2] = operands[1];
3241 (define_insn_and_split "*iorsi3_insn"
3242 [(set (match_operand:SI 0 "s_register_operand" "=r,l,r,r,r")
3243 (ior:SI (match_operand:SI 1 "s_register_operand" "%r,0,r,r,r")
3244 (match_operand:SI 2 "reg_or_int_operand" "I,l,K,r,?n")))]
3249 orn%?\\t%0, %1, #%B2
3253 && CONST_INT_P (operands[2])
3254 && !(const_ok_for_arm (INTVAL (operands[2]))
3255 || (TARGET_THUMB2 && const_ok_for_arm (~INTVAL (operands[2]))))"
3256 [(clobber (const_int 0))]
3258 arm_split_constant (IOR, SImode, curr_insn,
3259 INTVAL (operands[2]), operands[0], operands[1], 0);
3262 [(set_attr "length" "4,4,4,4,16")
3263 (set_attr "arch" "32,t2,t2,32,32")
3264 (set_attr "predicable" "yes")
3265 (set_attr "predicable_short_it" "no,yes,no,no,no")
3266 (set_attr "type" "logic_imm,logic_reg,logic_imm,logic_reg,logic_reg")]
3270 [(match_scratch:SI 3 "r")
3271 (set (match_operand:SI 0 "arm_general_register_operand" "")
3272 (ior:SI (match_operand:SI 1 "arm_general_register_operand" "")
3273 (match_operand:SI 2 "const_int_operand" "")))]
3275 && !const_ok_for_arm (INTVAL (operands[2]))
3276 && const_ok_for_arm (~INTVAL (operands[2]))"
3277 [(set (match_dup 3) (match_dup 2))
3278 (set (match_dup 0) (ior:SI (match_dup 1) (match_dup 3)))]
3282 (define_insn "*iorsi3_compare0"
3283 [(set (reg:CC_NOOV CC_REGNUM)
3284 (compare:CC_NOOV (ior:SI (match_operand:SI 1 "s_register_operand" "%r,r")
3285 (match_operand:SI 2 "arm_rhs_operand" "I,r"))
3287 (set (match_operand:SI 0 "s_register_operand" "=r,r")
3288 (ior:SI (match_dup 1) (match_dup 2)))]
3290 "orrs%?\\t%0, %1, %2"
3291 [(set_attr "conds" "set")
3292 (set_attr "type" "logics_imm,logics_reg")]
3295 (define_insn "*iorsi3_compare0_scratch"
3296 [(set (reg:CC_NOOV CC_REGNUM)
3297 (compare:CC_NOOV (ior:SI (match_operand:SI 1 "s_register_operand" "%r,r")
3298 (match_operand:SI 2 "arm_rhs_operand" "I,r"))
3300 (clobber (match_scratch:SI 0 "=r,r"))]
3302 "orrs%?\\t%0, %1, %2"
3303 [(set_attr "conds" "set")
3304 (set_attr "type" "logics_imm,logics_reg")]
3307 (define_expand "xordi3"
3308 [(set (match_operand:DI 0 "s_register_operand" "")
3309 (xor:DI (match_operand:DI 1 "s_register_operand" "")
3310 (match_operand:DI 2 "arm_xordi_operand" "")))]
3313 /* The iWMMXt pattern for xordi3 accepts only register operands but we want
3314 to reuse this expander for all TARGET_32BIT targets so just force the
3315 constants into a register. Unlike for the anddi3 and iordi3 there are
3316 no NEON instructions that take an immediate. */
3317 if (TARGET_IWMMXT && !REG_P (operands[2]))
3318 operands[2] = force_reg (DImode, operands[2]);
3322 (define_insn_and_split "*xordi3_insn"
3323 [(set (match_operand:DI 0 "s_register_operand" "=w,&r,&r,&r,&r,?w")
3324 (xor:DI (match_operand:DI 1 "s_register_operand" "%w ,0,r ,0 ,r ,w")
3325 (match_operand:DI 2 "arm_xordi_operand" "w ,r ,r ,Dg,Dg,w")))]
3326 "TARGET_32BIT && !TARGET_IWMMXT"
3328 switch (which_alternative)
3333 case 4: /* fall through */
3335 case 0: /* fall through */
3336 case 5: return "veor\t%P0, %P1, %P2";
3337 default: gcc_unreachable ();
3340 "TARGET_32BIT && !TARGET_IWMMXT && reload_completed
3341 && !(IS_VFP_REGNUM (REGNO (operands[0])))"
3342 [(set (match_dup 3) (match_dup 4))
3343 (set (match_dup 5) (match_dup 6))]
3346 operands[3] = gen_lowpart (SImode, operands[0]);
3347 operands[5] = gen_highpart (SImode, operands[0]);
3349 operands[4] = simplify_gen_binary (XOR, SImode,
3350 gen_lowpart (SImode, operands[1]),
3351 gen_lowpart (SImode, operands[2]));
3352 operands[6] = simplify_gen_binary (XOR, SImode,
3353 gen_highpart (SImode, operands[1]),
3354 gen_highpart_mode (SImode, DImode, operands[2]));
3357 [(set_attr "length" "*,8,8,8,8,*")
3358 (set_attr "type" "neon_logic,multiple,multiple,multiple,multiple,neon_logic")
3359 (set_attr "arch" "neon_for_64bits,*,*,*,*,avoid_neon_for_64bits")]
3362 (define_insn "*xordi_zesidi_di"
3363 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
3364 (xor:DI (zero_extend:DI
3365 (match_operand:SI 2 "s_register_operand" "r,r"))
3366 (match_operand:DI 1 "s_register_operand" "0,?r")))]
3369 eor%?\\t%Q0, %Q1, %2
3371 [(set_attr "length" "4,8")
3372 (set_attr "predicable" "yes")
3373 (set_attr "predicable_short_it" "no")
3374 (set_attr "type" "logic_reg")]
3377 (define_insn "*xordi_sesidi_di"
3378 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
3379 (xor:DI (sign_extend:DI
3380 (match_operand:SI 2 "s_register_operand" "r,r"))
3381 (match_operand:DI 1 "s_register_operand" "0,r")))]
3384 [(set_attr "length" "8")
3385 (set_attr "predicable" "yes")
3386 (set_attr "type" "multiple")]
3389 (define_expand "xorsi3"
3390 [(set (match_operand:SI 0 "s_register_operand" "")
3391 (xor:SI (match_operand:SI 1 "s_register_operand" "")
3392 (match_operand:SI 2 "reg_or_int_operand" "")))]
3394 "if (CONST_INT_P (operands[2]))
3398 if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[2]), XOR))
3399 operands[2] = force_reg (SImode, operands[2]);
3402 arm_split_constant (XOR, SImode, NULL_RTX,
3403 INTVAL (operands[2]), operands[0],
3405 optimize && can_create_pseudo_p ());
3409 else /* TARGET_THUMB1 */
3411 rtx tmp = force_reg (SImode, operands[2]);
3412 if (rtx_equal_p (operands[0], operands[1]))
3416 operands[2] = operands[1];
3423 (define_insn_and_split "*arm_xorsi3"
3424 [(set (match_operand:SI 0 "s_register_operand" "=r,l,r,r")
3425 (xor:SI (match_operand:SI 1 "s_register_operand" "%r,0,r,r")
3426 (match_operand:SI 2 "reg_or_int_operand" "I,l,r,?n")))]
3434 && CONST_INT_P (operands[2])
3435 && !const_ok_for_arm (INTVAL (operands[2]))"
3436 [(clobber (const_int 0))]
3438 arm_split_constant (XOR, SImode, curr_insn,
3439 INTVAL (operands[2]), operands[0], operands[1], 0);
3442 [(set_attr "length" "4,4,4,16")
3443 (set_attr "predicable" "yes")
3444 (set_attr "predicable_short_it" "no,yes,no,no")
3445 (set_attr "type" "logic_imm,logic_reg,logic_reg,multiple")]
3448 (define_insn "*xorsi3_compare0"
3449 [(set (reg:CC_NOOV CC_REGNUM)
3450 (compare:CC_NOOV (xor:SI (match_operand:SI 1 "s_register_operand" "r,r")
3451 (match_operand:SI 2 "arm_rhs_operand" "I,r"))
3453 (set (match_operand:SI 0 "s_register_operand" "=r,r")
3454 (xor:SI (match_dup 1) (match_dup 2)))]
3456 "eors%?\\t%0, %1, %2"
3457 [(set_attr "conds" "set")
3458 (set_attr "type" "logics_imm,logics_reg")]
3461 (define_insn "*xorsi3_compare0_scratch"
3462 [(set (reg:CC_NOOV CC_REGNUM)
3463 (compare:CC_NOOV (xor:SI (match_operand:SI 0 "s_register_operand" "r,r")
3464 (match_operand:SI 1 "arm_rhs_operand" "I,r"))
3468 [(set_attr "conds" "set")
3469 (set_attr "type" "logics_imm,logics_reg")]
3472 ; By splitting (IOR (AND (NOT A) (NOT B)) C) as D = AND (IOR A B) (NOT C),
3473 ; (NOT D) we can sometimes merge the final NOT into one of the following
3477 [(set (match_operand:SI 0 "s_register_operand" "")
3478 (ior:SI (and:SI (not:SI (match_operand:SI 1 "s_register_operand" ""))
3479 (not:SI (match_operand:SI 2 "arm_rhs_operand" "")))
3480 (match_operand:SI 3 "arm_rhs_operand" "")))
3481 (clobber (match_operand:SI 4 "s_register_operand" ""))]
3483 [(set (match_dup 4) (and:SI (ior:SI (match_dup 1) (match_dup 2))
3484 (not:SI (match_dup 3))))
3485 (set (match_dup 0) (not:SI (match_dup 4)))]
3489 (define_insn_and_split "*andsi_iorsi3_notsi"
3490 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r")
3491 (and:SI (ior:SI (match_operand:SI 1 "s_register_operand" "%0,r,r")
3492 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI"))
3493 (not:SI (match_operand:SI 3 "arm_rhs_operand" "rI,rI,rI"))))]
3495 "#" ; "orr%?\\t%0, %1, %2\;bic%?\\t%0, %0, %3"
3496 "&& reload_completed"
3497 [(set (match_dup 0) (ior:SI (match_dup 1) (match_dup 2)))
3498 (set (match_dup 0) (and:SI (match_dup 4) (match_dup 5)))]
3500 /* If operands[3] is a constant make sure to fold the NOT into it
3501 to avoid creating a NOT of a CONST_INT. */
3502 rtx not_rtx = simplify_gen_unary (NOT, SImode, operands[3], SImode);
3503 if (CONST_INT_P (not_rtx))
3505 operands[4] = operands[0];
3506 operands[5] = not_rtx;
3510 operands[5] = operands[0];
3511 operands[4] = not_rtx;
3514 [(set_attr "length" "8")
3515 (set_attr "ce_count" "2")
3516 (set_attr "predicable" "yes")
3517 (set_attr "predicable_short_it" "no")
3518 (set_attr "type" "multiple")]
3521 ; ??? Are these four splitters still beneficial when the Thumb-2 bitfield
3522 ; insns are available?
3524 [(set (match_operand:SI 0 "s_register_operand" "")
3525 (match_operator:SI 1 "logical_binary_operator"
3526 [(zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
3527 (match_operand:SI 3 "const_int_operand" "")
3528 (match_operand:SI 4 "const_int_operand" ""))
3529 (match_operator:SI 9 "logical_binary_operator"
3530 [(lshiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3531 (match_operand:SI 6 "const_int_operand" ""))
3532 (match_operand:SI 7 "s_register_operand" "")])]))
3533 (clobber (match_operand:SI 8 "s_register_operand" ""))]
3535 && GET_CODE (operands[1]) == GET_CODE (operands[9])
3536 && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3539 [(ashift:SI (match_dup 2) (match_dup 4))
3543 [(lshiftrt:SI (match_dup 8) (match_dup 6))
3546 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3550 [(set (match_operand:SI 0 "s_register_operand" "")
3551 (match_operator:SI 1 "logical_binary_operator"
3552 [(match_operator:SI 9 "logical_binary_operator"
3553 [(lshiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3554 (match_operand:SI 6 "const_int_operand" ""))
3555 (match_operand:SI 7 "s_register_operand" "")])
3556 (zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
3557 (match_operand:SI 3 "const_int_operand" "")
3558 (match_operand:SI 4 "const_int_operand" ""))]))
3559 (clobber (match_operand:SI 8 "s_register_operand" ""))]
3561 && GET_CODE (operands[1]) == GET_CODE (operands[9])
3562 && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3565 [(ashift:SI (match_dup 2) (match_dup 4))
3569 [(lshiftrt:SI (match_dup 8) (match_dup 6))
3572 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3576 [(set (match_operand:SI 0 "s_register_operand" "")
3577 (match_operator:SI 1 "logical_binary_operator"
3578 [(sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
3579 (match_operand:SI 3 "const_int_operand" "")
3580 (match_operand:SI 4 "const_int_operand" ""))
3581 (match_operator:SI 9 "logical_binary_operator"
3582 [(ashiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3583 (match_operand:SI 6 "const_int_operand" ""))
3584 (match_operand:SI 7 "s_register_operand" "")])]))
3585 (clobber (match_operand:SI 8 "s_register_operand" ""))]
3587 && GET_CODE (operands[1]) == GET_CODE (operands[9])
3588 && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3591 [(ashift:SI (match_dup 2) (match_dup 4))
3595 [(ashiftrt:SI (match_dup 8) (match_dup 6))
3598 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3602 [(set (match_operand:SI 0 "s_register_operand" "")
3603 (match_operator:SI 1 "logical_binary_operator"
3604 [(match_operator:SI 9 "logical_binary_operator"
3605 [(ashiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3606 (match_operand:SI 6 "const_int_operand" ""))
3607 (match_operand:SI 7 "s_register_operand" "")])
3608 (sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
3609 (match_operand:SI 3 "const_int_operand" "")
3610 (match_operand:SI 4 "const_int_operand" ""))]))
3611 (clobber (match_operand:SI 8 "s_register_operand" ""))]
3613 && GET_CODE (operands[1]) == GET_CODE (operands[9])
3614 && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3617 [(ashift:SI (match_dup 2) (match_dup 4))
3621 [(ashiftrt:SI (match_dup 8) (match_dup 6))
3624 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3628 ;; Minimum and maximum insns
3630 (define_expand "smaxsi3"
3632 (set (match_operand:SI 0 "s_register_operand" "")
3633 (smax:SI (match_operand:SI 1 "s_register_operand" "")
3634 (match_operand:SI 2 "arm_rhs_operand" "")))
3635 (clobber (reg:CC CC_REGNUM))])]
3638 if (operands[2] == const0_rtx || operands[2] == constm1_rtx)
3640 /* No need for a clobber of the condition code register here. */
3641 emit_insn (gen_rtx_SET (operands[0],
3642 gen_rtx_SMAX (SImode, operands[1],
3648 (define_insn "*smax_0"
3649 [(set (match_operand:SI 0 "s_register_operand" "=r")
3650 (smax:SI (match_operand:SI 1 "s_register_operand" "r")
3653 "bic%?\\t%0, %1, %1, asr #31"
3654 [(set_attr "predicable" "yes")
3655 (set_attr "predicable_short_it" "no")
3656 (set_attr "type" "logic_shift_reg")]
3659 (define_insn "*smax_m1"
3660 [(set (match_operand:SI 0 "s_register_operand" "=r")
3661 (smax:SI (match_operand:SI 1 "s_register_operand" "r")
3664 "orr%?\\t%0, %1, %1, asr #31"
3665 [(set_attr "predicable" "yes")
3666 (set_attr "predicable_short_it" "no")
3667 (set_attr "type" "logic_shift_reg")]
3670 (define_insn_and_split "*arm_smax_insn"
3671 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3672 (smax:SI (match_operand:SI 1 "s_register_operand" "%0,?r")
3673 (match_operand:SI 2 "arm_rhs_operand" "rI,rI")))
3674 (clobber (reg:CC CC_REGNUM))]
3677 ; cmp\\t%1, %2\;movlt\\t%0, %2
3678 ; cmp\\t%1, %2\;movge\\t%0, %1\;movlt\\t%0, %2"
3680 [(set (reg:CC CC_REGNUM)
3681 (compare:CC (match_dup 1) (match_dup 2)))
3683 (if_then_else:SI (ge:SI (reg:CC CC_REGNUM) (const_int 0))
3687 [(set_attr "conds" "clob")
3688 (set_attr "length" "8,12")
3689 (set_attr "type" "multiple")]
3692 (define_expand "sminsi3"
3694 (set (match_operand:SI 0 "s_register_operand" "")
3695 (smin:SI (match_operand:SI 1 "s_register_operand" "")
3696 (match_operand:SI 2 "arm_rhs_operand" "")))
3697 (clobber (reg:CC CC_REGNUM))])]
3700 if (operands[2] == const0_rtx)
3702 /* No need for a clobber of the condition code register here. */
3703 emit_insn (gen_rtx_SET (operands[0],
3704 gen_rtx_SMIN (SImode, operands[1],
3710 (define_insn "*smin_0"
3711 [(set (match_operand:SI 0 "s_register_operand" "=r")
3712 (smin:SI (match_operand:SI 1 "s_register_operand" "r")
3715 "and%?\\t%0, %1, %1, asr #31"
3716 [(set_attr "predicable" "yes")
3717 (set_attr "predicable_short_it" "no")
3718 (set_attr "type" "logic_shift_reg")]
3721 (define_insn_and_split "*arm_smin_insn"
3722 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3723 (smin:SI (match_operand:SI 1 "s_register_operand" "%0,?r")
3724 (match_operand:SI 2 "arm_rhs_operand" "rI,rI")))
3725 (clobber (reg:CC CC_REGNUM))]
3728 ; cmp\\t%1, %2\;movge\\t%0, %2
3729 ; cmp\\t%1, %2\;movlt\\t%0, %1\;movge\\t%0, %2"
3731 [(set (reg:CC CC_REGNUM)
3732 (compare:CC (match_dup 1) (match_dup 2)))
3734 (if_then_else:SI (lt:SI (reg:CC CC_REGNUM) (const_int 0))
3738 [(set_attr "conds" "clob")
3739 (set_attr "length" "8,12")
3740 (set_attr "type" "multiple,multiple")]
3743 (define_expand "umaxsi3"
3745 (set (match_operand:SI 0 "s_register_operand" "")
3746 (umax:SI (match_operand:SI 1 "s_register_operand" "")
3747 (match_operand:SI 2 "arm_rhs_operand" "")))
3748 (clobber (reg:CC CC_REGNUM))])]
3753 (define_insn_and_split "*arm_umaxsi3"
3754 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
3755 (umax:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
3756 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
3757 (clobber (reg:CC CC_REGNUM))]
3760 ; cmp\\t%1, %2\;movcc\\t%0, %2
3761 ; cmp\\t%1, %2\;movcs\\t%0, %1
3762 ; cmp\\t%1, %2\;movcs\\t%0, %1\;movcc\\t%0, %2"
3764 [(set (reg:CC CC_REGNUM)
3765 (compare:CC (match_dup 1) (match_dup 2)))
3767 (if_then_else:SI (geu:SI (reg:CC CC_REGNUM) (const_int 0))
3771 [(set_attr "conds" "clob")
3772 (set_attr "length" "8,8,12")
3773 (set_attr "type" "store1")]
3776 (define_expand "uminsi3"
3778 (set (match_operand:SI 0 "s_register_operand" "")
3779 (umin:SI (match_operand:SI 1 "s_register_operand" "")
3780 (match_operand:SI 2 "arm_rhs_operand" "")))
3781 (clobber (reg:CC CC_REGNUM))])]
3786 (define_insn_and_split "*arm_uminsi3"
3787 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
3788 (umin:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
3789 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
3790 (clobber (reg:CC CC_REGNUM))]
3793 ; cmp\\t%1, %2\;movcs\\t%0, %2
3794 ; cmp\\t%1, %2\;movcc\\t%0, %1
3795 ; cmp\\t%1, %2\;movcc\\t%0, %1\;movcs\\t%0, %2"
3797 [(set (reg:CC CC_REGNUM)
3798 (compare:CC (match_dup 1) (match_dup 2)))
3800 (if_then_else:SI (ltu:SI (reg:CC CC_REGNUM) (const_int 0))
3804 [(set_attr "conds" "clob")
3805 (set_attr "length" "8,8,12")
3806 (set_attr "type" "store1")]
3809 (define_insn "*store_minmaxsi"
3810 [(set (match_operand:SI 0 "memory_operand" "=m")
3811 (match_operator:SI 3 "minmax_operator"
3812 [(match_operand:SI 1 "s_register_operand" "r")
3813 (match_operand:SI 2 "s_register_operand" "r")]))
3814 (clobber (reg:CC CC_REGNUM))]
3815 "TARGET_32BIT && optimize_function_for_size_p (cfun) && !arm_restrict_it"
3817 operands[3] = gen_rtx_fmt_ee (minmax_code (operands[3]), SImode,
3818 operands[1], operands[2]);
3819 output_asm_insn (\"cmp\\t%1, %2\", operands);
3821 output_asm_insn (\"ite\t%d3\", operands);
3822 output_asm_insn (\"str%d3\\t%1, %0\", operands);
3823 output_asm_insn (\"str%D3\\t%2, %0\", operands);
3826 [(set_attr "conds" "clob")
3827 (set (attr "length")
3828 (if_then_else (eq_attr "is_thumb" "yes")
3831 (set_attr "type" "store1")]
3834 ; Reject the frame pointer in operand[1], since reloading this after
3835 ; it has been eliminated can cause carnage.
3836 (define_insn "*minmax_arithsi"
3837 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3838 (match_operator:SI 4 "shiftable_operator"
3839 [(match_operator:SI 5 "minmax_operator"
3840 [(match_operand:SI 2 "s_register_operand" "r,r")
3841 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
3842 (match_operand:SI 1 "s_register_operand" "0,?r")]))
3843 (clobber (reg:CC CC_REGNUM))]
3844 "TARGET_32BIT && !arm_eliminable_register (operands[1]) && !arm_restrict_it"
3847 enum rtx_code code = GET_CODE (operands[4]);
3850 if (which_alternative != 0 || operands[3] != const0_rtx
3851 || (code != PLUS && code != IOR && code != XOR))
3856 operands[5] = gen_rtx_fmt_ee (minmax_code (operands[5]), SImode,
3857 operands[2], operands[3]);
3858 output_asm_insn (\"cmp\\t%2, %3\", operands);
3862 output_asm_insn (\"ite\\t%d5\", operands);
3864 output_asm_insn (\"it\\t%d5\", operands);
3866 output_asm_insn (\"%i4%d5\\t%0, %1, %2\", operands);
3868 output_asm_insn (\"%i4%D5\\t%0, %1, %3\", operands);
3871 [(set_attr "conds" "clob")
3872 (set (attr "length")
3873 (if_then_else (eq_attr "is_thumb" "yes")
3876 (set_attr "type" "multiple")]
3879 ; Reject the frame pointer in operand[1], since reloading this after
3880 ; it has been eliminated can cause carnage.
3881 (define_insn_and_split "*minmax_arithsi_non_canon"
3882 [(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts")
3884 (match_operand:SI 1 "s_register_operand" "0,?Ts")
3885 (match_operator:SI 4 "minmax_operator"
3886 [(match_operand:SI 2 "s_register_operand" "Ts,Ts")
3887 (match_operand:SI 3 "arm_rhs_operand" "TsI,TsI")])))
3888 (clobber (reg:CC CC_REGNUM))]
3889 "TARGET_32BIT && !arm_eliminable_register (operands[1])
3890 && !(arm_restrict_it && CONST_INT_P (operands[3]))"
3892 "TARGET_32BIT && !arm_eliminable_register (operands[1]) && reload_completed"
3893 [(set (reg:CC CC_REGNUM)
3894 (compare:CC (match_dup 2) (match_dup 3)))
3896 (cond_exec (match_op_dup 4 [(reg:CC CC_REGNUM) (const_int 0)])
3898 (minus:SI (match_dup 1)
3900 (cond_exec (match_op_dup 5 [(reg:CC CC_REGNUM) (const_int 0)])
3904 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
3905 operands[2], operands[3]);
3906 enum rtx_code rc = minmax_code (operands[4]);
3907 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode,
3908 operands[2], operands[3]);
3910 if (mode == CCFPmode || mode == CCFPEmode)
3911 rc = reverse_condition_maybe_unordered (rc);
3913 rc = reverse_condition (rc);
3914 operands[5] = gen_rtx_fmt_ee (rc, SImode, operands[2], operands[3]);
3915 if (CONST_INT_P (operands[3]))
3916 operands[6] = plus_constant (SImode, operands[1], -INTVAL (operands[3]));
3918 operands[6] = gen_rtx_MINUS (SImode, operands[1], operands[3]);
3920 [(set_attr "conds" "clob")
3921 (set (attr "length")
3922 (if_then_else (eq_attr "is_thumb" "yes")
3925 (set_attr "type" "multiple")]
3928 (define_code_iterator SAT [smin smax])
3929 (define_code_iterator SATrev [smin smax])
3930 (define_code_attr SATlo [(smin "1") (smax "2")])
3931 (define_code_attr SAThi [(smin "2") (smax "1")])
3933 (define_insn "*satsi_<SAT:code>"
3934 [(set (match_operand:SI 0 "s_register_operand" "=r")
3935 (SAT:SI (SATrev:SI (match_operand:SI 3 "s_register_operand" "r")
3936 (match_operand:SI 1 "const_int_operand" "i"))
3937 (match_operand:SI 2 "const_int_operand" "i")))]
3938 "TARGET_32BIT && arm_arch6 && <SAT:CODE> != <SATrev:CODE>
3939 && arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>], NULL, NULL)"
3943 if (!arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>],
3944 &mask, &signed_sat))
3947 operands[1] = GEN_INT (mask);
3949 return "ssat%?\t%0, %1, %3";
3951 return "usat%?\t%0, %1, %3";
3953 [(set_attr "predicable" "yes")
3954 (set_attr "predicable_short_it" "no")
3955 (set_attr "type" "alus_imm")]
3958 (define_insn "*satsi_<SAT:code>_shift"
3959 [(set (match_operand:SI 0 "s_register_operand" "=r")
3960 (SAT:SI (SATrev:SI (match_operator:SI 3 "sat_shift_operator"
3961 [(match_operand:SI 4 "s_register_operand" "r")
3962 (match_operand:SI 5 "const_int_operand" "i")])
3963 (match_operand:SI 1 "const_int_operand" "i"))
3964 (match_operand:SI 2 "const_int_operand" "i")))]
3965 "TARGET_32BIT && arm_arch6 && <SAT:CODE> != <SATrev:CODE>
3966 && arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>], NULL, NULL)"
3970 if (!arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>],
3971 &mask, &signed_sat))
3974 operands[1] = GEN_INT (mask);
3976 return "ssat%?\t%0, %1, %4%S3";
3978 return "usat%?\t%0, %1, %4%S3";
3980 [(set_attr "predicable" "yes")
3981 (set_attr "predicable_short_it" "no")
3982 (set_attr "shift" "3")
3983 (set_attr "type" "logic_shift_reg")])
3985 ;; Shift and rotation insns
3987 (define_expand "ashldi3"
3988 [(set (match_operand:DI 0 "s_register_operand" "")
3989 (ashift:DI (match_operand:DI 1 "s_register_operand" "")
3990 (match_operand:SI 2 "general_operand" "")))]
3995 /* Delay the decision whether to use NEON or core-regs until
3996 register allocation. */
3997 emit_insn (gen_ashldi3_neon (operands[0], operands[1], operands[2]));
4002 /* Only the NEON case can handle in-memory shift counts. */
4003 if (!reg_or_int_operand (operands[2], SImode))
4004 operands[2] = force_reg (SImode, operands[2]);
4007 if (!CONST_INT_P (operands[2]) && TARGET_REALLY_IWMMXT)
4008 ; /* No special preparation statements; expand pattern as above. */
4011 rtx scratch1, scratch2;
4013 if (operands[2] == CONST1_RTX (SImode))
4015 emit_insn (gen_arm_ashldi3_1bit (operands[0], operands[1]));
4019 /* Ideally we should use iwmmxt here if we could know that operands[1]
4020 ends up already living in an iwmmxt register. Otherwise it's
4021 cheaper to have the alternate code being generated than moving
4022 values to iwmmxt regs and back. */
4024 /* Expand operation using core-registers.
4025 'FAIL' would achieve the same thing, but this is a bit smarter. */
4026 scratch1 = gen_reg_rtx (SImode);
4027 scratch2 = gen_reg_rtx (SImode);
4028 arm_emit_coreregs_64bit_shift (ASHIFT, operands[0], operands[1],
4029 operands[2], scratch1, scratch2);
4035 (define_insn "arm_ashldi3_1bit"
4036 [(set (match_operand:DI 0 "s_register_operand" "=r,&r")
4037 (ashift:DI (match_operand:DI 1 "s_register_operand" "0,r")
4039 (clobber (reg:CC CC_REGNUM))]
4041 "movs\\t%Q0, %Q1, asl #1\;adc\\t%R0, %R1, %R1"
4042 [(set_attr "conds" "clob")
4043 (set_attr "length" "8")
4044 (set_attr "type" "multiple")]
4047 (define_expand "ashlsi3"
4048 [(set (match_operand:SI 0 "s_register_operand" "")
4049 (ashift:SI (match_operand:SI 1 "s_register_operand" "")
4050 (match_operand:SI 2 "arm_rhs_operand" "")))]
4053 if (CONST_INT_P (operands[2])
4054 && (UINTVAL (operands[2])) > 31)
4056 emit_insn (gen_movsi (operands[0], const0_rtx));
4062 (define_expand "ashrdi3"
4063 [(set (match_operand:DI 0 "s_register_operand" "")
4064 (ashiftrt:DI (match_operand:DI 1 "s_register_operand" "")
4065 (match_operand:SI 2 "reg_or_int_operand" "")))]
4070 /* Delay the decision whether to use NEON or core-regs until
4071 register allocation. */
4072 emit_insn (gen_ashrdi3_neon (operands[0], operands[1], operands[2]));
4076 if (!CONST_INT_P (operands[2]) && TARGET_REALLY_IWMMXT)
4077 ; /* No special preparation statements; expand pattern as above. */
4080 rtx scratch1, scratch2;
4082 if (operands[2] == CONST1_RTX (SImode))
4084 emit_insn (gen_arm_ashrdi3_1bit (operands[0], operands[1]));
4088 /* Ideally we should use iwmmxt here if we could know that operands[1]
4089 ends up already living in an iwmmxt register. Otherwise it's
4090 cheaper to have the alternate code being generated than moving
4091 values to iwmmxt regs and back. */
4093 /* Expand operation using core-registers.
4094 'FAIL' would achieve the same thing, but this is a bit smarter. */
4095 scratch1 = gen_reg_rtx (SImode);
4096 scratch2 = gen_reg_rtx (SImode);
4097 arm_emit_coreregs_64bit_shift (ASHIFTRT, operands[0], operands[1],
4098 operands[2], scratch1, scratch2);
4104 (define_insn "arm_ashrdi3_1bit"
4105 [(set (match_operand:DI 0 "s_register_operand" "=r,&r")
4106 (ashiftrt:DI (match_operand:DI 1 "s_register_operand" "0,r")
4108 (clobber (reg:CC CC_REGNUM))]
4110 "movs\\t%R0, %R1, asr #1\;mov\\t%Q0, %Q1, rrx"
4111 [(set_attr "conds" "clob")
4112 (set_attr "length" "8")
4113 (set_attr "type" "multiple")]
4116 (define_expand "ashrsi3"
4117 [(set (match_operand:SI 0 "s_register_operand" "")
4118 (ashiftrt:SI (match_operand:SI 1 "s_register_operand" "")
4119 (match_operand:SI 2 "arm_rhs_operand" "")))]
4122 if (CONST_INT_P (operands[2])
4123 && UINTVAL (operands[2]) > 31)
4124 operands[2] = GEN_INT (31);
4128 (define_expand "lshrdi3"
4129 [(set (match_operand:DI 0 "s_register_operand" "")
4130 (lshiftrt:DI (match_operand:DI 1 "s_register_operand" "")
4131 (match_operand:SI 2 "reg_or_int_operand" "")))]
4136 /* Delay the decision whether to use NEON or core-regs until
4137 register allocation. */
4138 emit_insn (gen_lshrdi3_neon (operands[0], operands[1], operands[2]));
4142 if (!CONST_INT_P (operands[2]) && TARGET_REALLY_IWMMXT)
4143 ; /* No special preparation statements; expand pattern as above. */
4146 rtx scratch1, scratch2;
4148 if (operands[2] == CONST1_RTX (SImode))
4150 emit_insn (gen_arm_lshrdi3_1bit (operands[0], operands[1]));
4154 /* Ideally we should use iwmmxt here if we could know that operands[1]
4155 ends up already living in an iwmmxt register. Otherwise it's
4156 cheaper to have the alternate code being generated than moving
4157 values to iwmmxt regs and back. */
4159 /* Expand operation using core-registers.
4160 'FAIL' would achieve the same thing, but this is a bit smarter. */
4161 scratch1 = gen_reg_rtx (SImode);
4162 scratch2 = gen_reg_rtx (SImode);
4163 arm_emit_coreregs_64bit_shift (LSHIFTRT, operands[0], operands[1],
4164 operands[2], scratch1, scratch2);
4170 (define_insn "arm_lshrdi3_1bit"
4171 [(set (match_operand:DI 0 "s_register_operand" "=r,&r")
4172 (lshiftrt:DI (match_operand:DI 1 "s_register_operand" "0,r")
4174 (clobber (reg:CC CC_REGNUM))]
4176 "movs\\t%R0, %R1, lsr #1\;mov\\t%Q0, %Q1, rrx"
4177 [(set_attr "conds" "clob")
4178 (set_attr "length" "8")
4179 (set_attr "type" "multiple")]
4182 (define_expand "lshrsi3"
4183 [(set (match_operand:SI 0 "s_register_operand" "")
4184 (lshiftrt:SI (match_operand:SI 1 "s_register_operand" "")
4185 (match_operand:SI 2 "arm_rhs_operand" "")))]
4188 if (CONST_INT_P (operands[2])
4189 && (UINTVAL (operands[2])) > 31)
4191 emit_insn (gen_movsi (operands[0], const0_rtx));
4197 (define_expand "rotlsi3"
4198 [(set (match_operand:SI 0 "s_register_operand" "")
4199 (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
4200 (match_operand:SI 2 "reg_or_int_operand" "")))]
4203 if (CONST_INT_P (operands[2]))
4204 operands[2] = GEN_INT ((32 - INTVAL (operands[2])) % 32);
4207 rtx reg = gen_reg_rtx (SImode);
4208 emit_insn (gen_subsi3 (reg, GEN_INT (32), operands[2]));
4214 (define_expand "rotrsi3"
4215 [(set (match_operand:SI 0 "s_register_operand" "")
4216 (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
4217 (match_operand:SI 2 "arm_rhs_operand" "")))]
4222 if (CONST_INT_P (operands[2])
4223 && UINTVAL (operands[2]) > 31)
4224 operands[2] = GEN_INT (INTVAL (operands[2]) % 32);
4226 else /* TARGET_THUMB1 */
4228 if (CONST_INT_P (operands [2]))
4229 operands [2] = force_reg (SImode, operands[2]);
4234 (define_insn "*arm_shiftsi3"
4235 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r,r")
4236 (match_operator:SI 3 "shift_operator"
4237 [(match_operand:SI 1 "s_register_operand" "0,l,r,r")
4238 (match_operand:SI 2 "reg_or_int_operand" "l,M,M,r")]))]
4240 "* return arm_output_shift(operands, 0);"
4241 [(set_attr "predicable" "yes")
4242 (set_attr "arch" "t2,t2,*,*")
4243 (set_attr "predicable_short_it" "yes,yes,no,no")
4244 (set_attr "length" "4")
4245 (set_attr "shift" "1")
4246 (set_attr "type" "alu_shift_reg,alu_shift_imm,alu_shift_imm,alu_shift_reg")]
4249 (define_insn "*shiftsi3_compare0"
4250 [(set (reg:CC_NOOV CC_REGNUM)
4251 (compare:CC_NOOV (match_operator:SI 3 "shift_operator"
4252 [(match_operand:SI 1 "s_register_operand" "r,r")
4253 (match_operand:SI 2 "arm_rhs_operand" "M,r")])
4255 (set (match_operand:SI 0 "s_register_operand" "=r,r")
4256 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))]
4258 "* return arm_output_shift(operands, 1);"
4259 [(set_attr "conds" "set")
4260 (set_attr "shift" "1")
4261 (set_attr "type" "alus_shift_imm,alus_shift_reg")]
4264 (define_insn "*shiftsi3_compare0_scratch"
4265 [(set (reg:CC_NOOV CC_REGNUM)
4266 (compare:CC_NOOV (match_operator:SI 3 "shift_operator"
4267 [(match_operand:SI 1 "s_register_operand" "r,r")
4268 (match_operand:SI 2 "arm_rhs_operand" "M,r")])
4270 (clobber (match_scratch:SI 0 "=r,r"))]
4272 "* return arm_output_shift(operands, 1);"
4273 [(set_attr "conds" "set")
4274 (set_attr "shift" "1")
4275 (set_attr "type" "shift_imm,shift_reg")]
4278 (define_insn "*not_shiftsi"
4279 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4280 (not:SI (match_operator:SI 3 "shift_operator"
4281 [(match_operand:SI 1 "s_register_operand" "r,r")
4282 (match_operand:SI 2 "shift_amount_operand" "M,rM")])))]
4285 [(set_attr "predicable" "yes")
4286 (set_attr "predicable_short_it" "no")
4287 (set_attr "shift" "1")
4288 (set_attr "arch" "32,a")
4289 (set_attr "type" "mvn_shift,mvn_shift_reg")])
4291 (define_insn "*not_shiftsi_compare0"
4292 [(set (reg:CC_NOOV CC_REGNUM)
4294 (not:SI (match_operator:SI 3 "shift_operator"
4295 [(match_operand:SI 1 "s_register_operand" "r,r")
4296 (match_operand:SI 2 "shift_amount_operand" "M,rM")]))
4298 (set (match_operand:SI 0 "s_register_operand" "=r,r")
4299 (not:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])))]
4301 "mvns%?\\t%0, %1%S3"
4302 [(set_attr "conds" "set")
4303 (set_attr "shift" "1")
4304 (set_attr "arch" "32,a")
4305 (set_attr "type" "mvn_shift,mvn_shift_reg")])
4307 (define_insn "*not_shiftsi_compare0_scratch"
4308 [(set (reg:CC_NOOV CC_REGNUM)
4310 (not:SI (match_operator:SI 3 "shift_operator"
4311 [(match_operand:SI 1 "s_register_operand" "r,r")
4312 (match_operand:SI 2 "shift_amount_operand" "M,rM")]))
4314 (clobber (match_scratch:SI 0 "=r,r"))]
4316 "mvns%?\\t%0, %1%S3"
4317 [(set_attr "conds" "set")
4318 (set_attr "shift" "1")
4319 (set_attr "arch" "32,a")
4320 (set_attr "type" "mvn_shift,mvn_shift_reg")])
4322 ;; We don't really have extzv, but defining this using shifts helps
4323 ;; to reduce register pressure later on.
4325 (define_expand "extzv"
4326 [(set (match_operand 0 "s_register_operand" "")
4327 (zero_extract (match_operand 1 "nonimmediate_operand" "")
4328 (match_operand 2 "const_int_operand" "")
4329 (match_operand 3 "const_int_operand" "")))]
4330 "TARGET_THUMB1 || arm_arch_thumb2"
4333 HOST_WIDE_INT lshift = 32 - INTVAL (operands[2]) - INTVAL (operands[3]);
4334 HOST_WIDE_INT rshift = 32 - INTVAL (operands[2]);
4336 if (arm_arch_thumb2)
4338 HOST_WIDE_INT width = INTVAL (operands[2]);
4339 HOST_WIDE_INT bitpos = INTVAL (operands[3]);
4341 if (unaligned_access && MEM_P (operands[1])
4342 && (width == 16 || width == 32) && (bitpos % BITS_PER_UNIT) == 0)
4346 if (BYTES_BIG_ENDIAN)
4347 bitpos = GET_MODE_BITSIZE (GET_MODE (operands[0])) - width
4352 base_addr = adjust_address (operands[1], SImode,
4353 bitpos / BITS_PER_UNIT);
4354 emit_insn (gen_unaligned_loadsi (operands[0], base_addr));
4358 rtx dest = operands[0];
4359 rtx tmp = gen_reg_rtx (SImode);
4361 /* We may get a paradoxical subreg here. Strip it off. */
4362 if (GET_CODE (dest) == SUBREG
4363 && GET_MODE (dest) == SImode
4364 && GET_MODE (SUBREG_REG (dest)) == HImode)
4365 dest = SUBREG_REG (dest);
4367 if (GET_MODE_BITSIZE (GET_MODE (dest)) != width)
4370 base_addr = adjust_address (operands[1], HImode,
4371 bitpos / BITS_PER_UNIT);
4372 emit_insn (gen_unaligned_loadhiu (tmp, base_addr));
4373 emit_move_insn (gen_lowpart (SImode, dest), tmp);
4377 else if (s_register_operand (operands[1], GET_MODE (operands[1])))
4379 emit_insn (gen_extzv_t2 (operands[0], operands[1], operands[2],
4387 if (!s_register_operand (operands[1], GET_MODE (operands[1])))
4390 operands[3] = GEN_INT (rshift);
4394 emit_insn (gen_lshrsi3 (operands[0], operands[1], operands[3]));
4398 emit_insn (gen_extzv_t1 (operands[0], operands[1], GEN_INT (lshift),
4399 operands[3], gen_reg_rtx (SImode)));
4404 ;; Helper for extzv, for the Thumb-1 register-shifts case.
4406 (define_expand "extzv_t1"
4407 [(set (match_operand:SI 4 "s_register_operand" "")
4408 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
4409 (match_operand:SI 2 "const_int_operand" "")))
4410 (set (match_operand:SI 0 "s_register_operand" "")
4411 (lshiftrt:SI (match_dup 4)
4412 (match_operand:SI 3 "const_int_operand" "")))]
4416 (define_expand "extv"
4417 [(set (match_operand 0 "s_register_operand" "")
4418 (sign_extract (match_operand 1 "nonimmediate_operand" "")
4419 (match_operand 2 "const_int_operand" "")
4420 (match_operand 3 "const_int_operand" "")))]
4423 HOST_WIDE_INT width = INTVAL (operands[2]);
4424 HOST_WIDE_INT bitpos = INTVAL (operands[3]);
4426 if (unaligned_access && MEM_P (operands[1]) && (width == 16 || width == 32)
4427 && (bitpos % BITS_PER_UNIT) == 0)
4431 if (BYTES_BIG_ENDIAN)
4432 bitpos = GET_MODE_BITSIZE (GET_MODE (operands[0])) - width - bitpos;
4436 base_addr = adjust_address (operands[1], SImode,
4437 bitpos / BITS_PER_UNIT);
4438 emit_insn (gen_unaligned_loadsi (operands[0], base_addr));
4442 rtx dest = operands[0];
4443 rtx tmp = gen_reg_rtx (SImode);
4445 /* We may get a paradoxical subreg here. Strip it off. */
4446 if (GET_CODE (dest) == SUBREG
4447 && GET_MODE (dest) == SImode
4448 && GET_MODE (SUBREG_REG (dest)) == HImode)
4449 dest = SUBREG_REG (dest);
4451 if (GET_MODE_BITSIZE (GET_MODE (dest)) != width)
4454 base_addr = adjust_address (operands[1], HImode,
4455 bitpos / BITS_PER_UNIT);
4456 emit_insn (gen_unaligned_loadhis (tmp, base_addr));
4457 emit_move_insn (gen_lowpart (SImode, dest), tmp);
4462 else if (!s_register_operand (operands[1], GET_MODE (operands[1])))
4464 else if (GET_MODE (operands[0]) == SImode
4465 && GET_MODE (operands[1]) == SImode)
4467 emit_insn (gen_extv_regsi (operands[0], operands[1], operands[2],
4475 ; Helper to expand register forms of extv with the proper modes.
4477 (define_expand "extv_regsi"
4478 [(set (match_operand:SI 0 "s_register_operand" "")
4479 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "")
4480 (match_operand 2 "const_int_operand" "")
4481 (match_operand 3 "const_int_operand" "")))]
4486 ; ARMv6+ unaligned load/store instructions (used for packed structure accesses).
4488 (define_insn "unaligned_loadsi"
4489 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4490 (unspec:SI [(match_operand:SI 1 "memory_operand" "Uw,m")]
4491 UNSPEC_UNALIGNED_LOAD))]
4493 "ldr%?\t%0, %1\t@ unaligned"
4494 [(set_attr "arch" "t2,any")
4495 (set_attr "length" "2,4")
4496 (set_attr "predicable" "yes")
4497 (set_attr "predicable_short_it" "yes,no")
4498 (set_attr "type" "load1")])
4500 (define_insn "unaligned_loadhis"
4501 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4503 (unspec:HI [(match_operand:HI 1 "memory_operand" "Uw,Uh")]
4504 UNSPEC_UNALIGNED_LOAD)))]
4506 "ldrsh%?\t%0, %1\t@ unaligned"
4507 [(set_attr "arch" "t2,any")
4508 (set_attr "length" "2,4")
4509 (set_attr "predicable" "yes")
4510 (set_attr "predicable_short_it" "yes,no")
4511 (set_attr "type" "load_byte")])
4513 (define_insn "unaligned_loadhiu"
4514 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4516 (unspec:HI [(match_operand:HI 1 "memory_operand" "Uw,m")]
4517 UNSPEC_UNALIGNED_LOAD)))]
4519 "ldrh%?\t%0, %1\t@ unaligned"
4520 [(set_attr "arch" "t2,any")
4521 (set_attr "length" "2,4")
4522 (set_attr "predicable" "yes")
4523 (set_attr "predicable_short_it" "yes,no")
4524 (set_attr "type" "load_byte")])
4526 (define_insn "unaligned_storesi"
4527 [(set (match_operand:SI 0 "memory_operand" "=Uw,m")
4528 (unspec:SI [(match_operand:SI 1 "s_register_operand" "l,r")]
4529 UNSPEC_UNALIGNED_STORE))]
4531 "str%?\t%1, %0\t@ unaligned"
4532 [(set_attr "arch" "t2,any")
4533 (set_attr "length" "2,4")
4534 (set_attr "predicable" "yes")
4535 (set_attr "predicable_short_it" "yes,no")
4536 (set_attr "type" "store1")])
4538 (define_insn "unaligned_storehi"
4539 [(set (match_operand:HI 0 "memory_operand" "=Uw,m")
4540 (unspec:HI [(match_operand:HI 1 "s_register_operand" "l,r")]
4541 UNSPEC_UNALIGNED_STORE))]
4543 "strh%?\t%1, %0\t@ unaligned"
4544 [(set_attr "arch" "t2,any")
4545 (set_attr "length" "2,4")
4546 (set_attr "predicable" "yes")
4547 (set_attr "predicable_short_it" "yes,no")
4548 (set_attr "type" "store1")])
4551 (define_insn "*extv_reg"
4552 [(set (match_operand:SI 0 "s_register_operand" "=r")
4553 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
4554 (match_operand:SI 2 "const_int_operand" "n")
4555 (match_operand:SI 3 "const_int_operand" "n")))]
4557 && IN_RANGE (INTVAL (operands[3]), 0, 31)
4558 && IN_RANGE (INTVAL (operands[2]), 1, 32 - INTVAL (operands[3]))"
4559 "sbfx%?\t%0, %1, %3, %2"
4560 [(set_attr "length" "4")
4561 (set_attr "predicable" "yes")
4562 (set_attr "predicable_short_it" "no")
4563 (set_attr "type" "bfm")]
4566 (define_insn "extzv_t2"
4567 [(set (match_operand:SI 0 "s_register_operand" "=r")
4568 (zero_extract:SI (match_operand:SI 1 "s_register_operand" "r")
4569 (match_operand:SI 2 "const_int_operand" "n")
4570 (match_operand:SI 3 "const_int_operand" "n")))]
4572 && IN_RANGE (INTVAL (operands[3]), 0, 31)
4573 && IN_RANGE (INTVAL (operands[2]), 1, 32 - INTVAL (operands[3]))"
4574 "ubfx%?\t%0, %1, %3, %2"
4575 [(set_attr "length" "4")
4576 (set_attr "predicable" "yes")
4577 (set_attr "predicable_short_it" "no")
4578 (set_attr "type" "bfm")]
4582 ;; Division instructions
4583 (define_insn "divsi3"
4584 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4585 (div:SI (match_operand:SI 1 "s_register_operand" "r,r")
4586 (match_operand:SI 2 "s_register_operand" "r,r")))]
4591 [(set_attr "arch" "32,v8mb")
4592 (set_attr "predicable" "yes")
4593 (set_attr "predicable_short_it" "no")
4594 (set_attr "type" "sdiv")]
4597 (define_insn "udivsi3"
4598 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4599 (udiv:SI (match_operand:SI 1 "s_register_operand" "r,r")
4600 (match_operand:SI 2 "s_register_operand" "r,r")))]
4605 [(set_attr "arch" "32,v8mb")
4606 (set_attr "predicable" "yes")
4607 (set_attr "predicable_short_it" "no")
4608 (set_attr "type" "udiv")]
4612 ;; Unary arithmetic insns
4614 (define_expand "negvsi3"
4615 [(match_operand:SI 0 "register_operand")
4616 (match_operand:SI 1 "register_operand")
4617 (match_operand 2 "")]
4620 emit_insn (gen_subsi3_compare (operands[0], const0_rtx, operands[1]));
4621 arm_gen_unlikely_cbranch (NE, CC_Vmode, operands[2]);
4626 (define_expand "negvdi3"
4627 [(match_operand:DI 0 "register_operand")
4628 (match_operand:DI 1 "register_operand")
4629 (match_operand 2 "")]
4632 emit_insn (gen_negdi2_compare (operands[0], operands[1]));
4633 arm_gen_unlikely_cbranch (NE, CC_Vmode, operands[2]);
4639 (define_insn_and_split "negdi2_compare"
4640 [(set (reg:CC CC_REGNUM)
4643 (match_operand:DI 1 "register_operand" "0,r")))
4644 (set (match_operand:DI 0 "register_operand" "=r,&r")
4645 (minus:DI (const_int 0) (match_dup 1)))]
4648 "&& reload_completed"
4649 [(parallel [(set (reg:CC CC_REGNUM)
4650 (compare:CC (const_int 0) (match_dup 1)))
4651 (set (match_dup 0) (minus:SI (const_int 0)
4653 (parallel [(set (reg:CC CC_REGNUM)
4654 (compare:CC (const_int 0) (match_dup 3)))
4657 (minus:SI (const_int 0) (match_dup 3))
4658 (ltu:SI (reg:CC_C CC_REGNUM)
4661 operands[2] = gen_highpart (SImode, operands[0]);
4662 operands[0] = gen_lowpart (SImode, operands[0]);
4663 operands[3] = gen_highpart (SImode, operands[1]);
4664 operands[1] = gen_lowpart (SImode, operands[1]);
4666 [(set_attr "conds" "set")
4667 (set_attr "length" "8")
4668 (set_attr "type" "multiple")]
4671 (define_expand "negdi2"
4673 [(set (match_operand:DI 0 "s_register_operand" "")
4674 (neg:DI (match_operand:DI 1 "s_register_operand" "")))
4675 (clobber (reg:CC CC_REGNUM))])]
4680 emit_insn (gen_negdi2_neon (operands[0], operands[1]));
4686 ;; The constraints here are to prevent a *partial* overlap (where %Q0 == %R1).
4687 ;; The first alternative allows the common case of a *full* overlap.
4688 (define_insn_and_split "*negdi2_insn"
4689 [(set (match_operand:DI 0 "s_register_operand" "=r,&r")
4690 (neg:DI (match_operand:DI 1 "s_register_operand" "0,r")))
4691 (clobber (reg:CC CC_REGNUM))]
4693 "#" ; rsbs %Q0, %Q1, #0; rsc %R0, %R1, #0 (ARM)
4694 ; negs %Q0, %Q1 ; sbc %R0, %R1, %R1, lsl #1 (Thumb-2)
4695 "&& reload_completed"
4696 [(parallel [(set (reg:CC CC_REGNUM)
4697 (compare:CC (const_int 0) (match_dup 1)))
4698 (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1)))])
4699 (set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3))
4700 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
4702 operands[2] = gen_highpart (SImode, operands[0]);
4703 operands[0] = gen_lowpart (SImode, operands[0]);
4704 operands[3] = gen_highpart (SImode, operands[1]);
4705 operands[1] = gen_lowpart (SImode, operands[1]);
4707 [(set_attr "conds" "clob")
4708 (set_attr "length" "8")
4709 (set_attr "type" "multiple")]
4712 (define_insn "*negsi2_carryin_compare"
4713 [(set (reg:CC CC_REGNUM)
4714 (compare:CC (const_int 0)
4715 (match_operand:SI 1 "s_register_operand" "r")))
4716 (set (match_operand:SI 0 "s_register_operand" "=r")
4717 (minus:SI (minus:SI (const_int 0)
4719 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
4722 [(set_attr "conds" "set")
4723 (set_attr "type" "alus_imm")]
4726 (define_expand "negsi2"
4727 [(set (match_operand:SI 0 "s_register_operand" "")
4728 (neg:SI (match_operand:SI 1 "s_register_operand" "")))]
4733 (define_insn "*arm_negsi2"
4734 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4735 (neg:SI (match_operand:SI 1 "s_register_operand" "l,r")))]
4737 "rsb%?\\t%0, %1, #0"
4738 [(set_attr "predicable" "yes")
4739 (set_attr "predicable_short_it" "yes,no")
4740 (set_attr "arch" "t2,*")
4741 (set_attr "length" "4")
4742 (set_attr "type" "alu_sreg")]
4745 (define_expand "negsf2"
4746 [(set (match_operand:SF 0 "s_register_operand" "")
4747 (neg:SF (match_operand:SF 1 "s_register_operand" "")))]
4748 "TARGET_32BIT && TARGET_HARD_FLOAT"
4752 (define_expand "negdf2"
4753 [(set (match_operand:DF 0 "s_register_operand" "")
4754 (neg:DF (match_operand:DF 1 "s_register_operand" "")))]
4755 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
4758 (define_insn_and_split "*zextendsidi_negsi"
4759 [(set (match_operand:DI 0 "s_register_operand" "=r")
4760 (zero_extend:DI (neg:SI (match_operand:SI 1 "s_register_operand" "r"))))]
4765 (neg:SI (match_dup 1)))
4769 operands[2] = gen_lowpart (SImode, operands[0]);
4770 operands[3] = gen_highpart (SImode, operands[0]);
4772 [(set_attr "length" "8")
4773 (set_attr "type" "multiple")]
4776 ;; Negate an extended 32-bit value.
4777 (define_insn_and_split "*negdi_extendsidi"
4778 [(set (match_operand:DI 0 "s_register_operand" "=l,r")
4779 (neg:DI (sign_extend:DI
4780 (match_operand:SI 1 "s_register_operand" "l,r"))))
4781 (clobber (reg:CC CC_REGNUM))]
4784 "&& reload_completed"
4787 rtx low = gen_lowpart (SImode, operands[0]);
4788 rtx high = gen_highpart (SImode, operands[0]);
4790 if (reg_overlap_mentioned_p (low, operands[1]))
4792 /* Input overlaps the low word of the output. Use:
4795 rsc Rhi, Rhi, #0 (thumb2: sbc Rhi, Rhi, Rhi, lsl #1). */
4796 rtx cc_reg = gen_rtx_REG (CC_Cmode, CC_REGNUM);
4798 emit_insn (gen_rtx_SET (high,
4799 gen_rtx_ASHIFTRT (SImode, operands[1],
4802 emit_insn (gen_subsi3_compare (low, const0_rtx, operands[1]));
4804 emit_insn (gen_rtx_SET (high,
4805 gen_rtx_MINUS (SImode,
4806 gen_rtx_MINUS (SImode,
4809 gen_rtx_LTU (SImode,
4814 rtx two_x = gen_rtx_ASHIFT (SImode, high, GEN_INT (1));
4815 emit_insn (gen_rtx_SET (high,
4816 gen_rtx_MINUS (SImode,
4817 gen_rtx_MINUS (SImode,
4820 gen_rtx_LTU (SImode,
4827 /* No overlap, or overlap on high word. Use:
4831 Flags not needed for this sequence. */
4832 emit_insn (gen_rtx_SET (low, gen_rtx_NEG (SImode, operands[1])));
4833 emit_insn (gen_rtx_SET (high,
4834 gen_rtx_AND (SImode,
4835 gen_rtx_NOT (SImode, operands[1]),
4837 emit_insn (gen_rtx_SET (high,
4838 gen_rtx_ASHIFTRT (SImode, high,
4843 [(set_attr "length" "12")
4844 (set_attr "arch" "t2,*")
4845 (set_attr "type" "multiple")]
4848 (define_insn_and_split "*negdi_zero_extendsidi"
4849 [(set (match_operand:DI 0 "s_register_operand" "=r,&r")
4850 (neg:DI (zero_extend:DI (match_operand:SI 1 "s_register_operand" "0,r"))))
4851 (clobber (reg:CC CC_REGNUM))]
4853 "#" ; "rsbs\\t%Q0, %1, #0\;sbc\\t%R0,%R0,%R0"
4854 ;; Don't care what register is input to sbc,
4855 ;; since we just need to propagate the carry.
4856 "&& reload_completed"
4857 [(parallel [(set (reg:CC CC_REGNUM)
4858 (compare:CC (const_int 0) (match_dup 1)))
4859 (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1)))])
4860 (set (match_dup 2) (minus:SI (minus:SI (match_dup 2) (match_dup 2))
4861 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
4863 operands[2] = gen_highpart (SImode, operands[0]);
4864 operands[0] = gen_lowpart (SImode, operands[0]);
4866 [(set_attr "conds" "clob")
4867 (set_attr "length" "8")
4868 (set_attr "type" "multiple")] ;; length in thumb is 4
4871 ;; abssi2 doesn't really clobber the condition codes if a different register
4872 ;; is being set. To keep things simple, assume during rtl manipulations that
4873 ;; it does, but tell the final scan operator the truth. Similarly for
4876 (define_expand "abssi2"
4878 [(set (match_operand:SI 0 "s_register_operand" "")
4879 (abs:SI (match_operand:SI 1 "s_register_operand" "")))
4880 (clobber (match_dup 2))])]
4884 operands[2] = gen_rtx_SCRATCH (SImode);
4886 operands[2] = gen_rtx_REG (CCmode, CC_REGNUM);
4889 (define_insn_and_split "*arm_abssi2"
4890 [(set (match_operand:SI 0 "s_register_operand" "=r,&r")
4891 (abs:SI (match_operand:SI 1 "s_register_operand" "0,r")))
4892 (clobber (reg:CC CC_REGNUM))]
4895 "&& reload_completed"
4898 /* if (which_alternative == 0) */
4899 if (REGNO(operands[0]) == REGNO(operands[1]))
4901 /* Emit the pattern:
4902 cmp\\t%0, #0\;rsblt\\t%0, %0, #0
4903 [(set (reg:CC CC_REGNUM)
4904 (compare:CC (match_dup 0) (const_int 0)))
4905 (cond_exec (lt:CC (reg:CC CC_REGNUM) (const_int 0))
4906 (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1))))]
4908 emit_insn (gen_rtx_SET (gen_rtx_REG (CCmode, CC_REGNUM),
4909 gen_rtx_COMPARE (CCmode, operands[0], const0_rtx)));
4910 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
4911 (gen_rtx_LT (SImode,
4912 gen_rtx_REG (CCmode, CC_REGNUM),
4914 (gen_rtx_SET (operands[0],
4915 (gen_rtx_MINUS (SImode,
4922 /* Emit the pattern:
4923 alt1: eor%?\\t%0, %1, %1, asr #31\;sub%?\\t%0, %0, %1, asr #31
4925 (xor:SI (match_dup 1)
4926 (ashiftrt:SI (match_dup 1) (const_int 31))))
4928 (minus:SI (match_dup 0)
4929 (ashiftrt:SI (match_dup 1) (const_int 31))))]
4931 emit_insn (gen_rtx_SET (operands[0],
4932 gen_rtx_XOR (SImode,
4933 gen_rtx_ASHIFTRT (SImode,
4937 emit_insn (gen_rtx_SET (operands[0],
4938 gen_rtx_MINUS (SImode,
4940 gen_rtx_ASHIFTRT (SImode,
4946 [(set_attr "conds" "clob,*")
4947 (set_attr "shift" "1")
4948 (set_attr "predicable" "no, yes")
4949 (set_attr "length" "8")
4950 (set_attr "type" "multiple")]
4953 (define_insn_and_split "*arm_neg_abssi2"
4954 [(set (match_operand:SI 0 "s_register_operand" "=r,&r")
4955 (neg:SI (abs:SI (match_operand:SI 1 "s_register_operand" "0,r"))))
4956 (clobber (reg:CC CC_REGNUM))]
4959 "&& reload_completed"
4962 /* if (which_alternative == 0) */
4963 if (REGNO (operands[0]) == REGNO (operands[1]))
4965 /* Emit the pattern:
4966 cmp\\t%0, #0\;rsbgt\\t%0, %0, #0
4968 emit_insn (gen_rtx_SET (gen_rtx_REG (CCmode, CC_REGNUM),
4969 gen_rtx_COMPARE (CCmode, operands[0], const0_rtx)));
4970 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
4972 gen_rtx_REG (CCmode, CC_REGNUM),
4974 gen_rtx_SET (operands[0],
4975 (gen_rtx_MINUS (SImode,
4981 /* Emit the pattern:
4982 eor%?\\t%0, %1, %1, asr #31\;rsb%?\\t%0, %0, %1, asr #31
4984 emit_insn (gen_rtx_SET (operands[0],
4985 gen_rtx_XOR (SImode,
4986 gen_rtx_ASHIFTRT (SImode,
4990 emit_insn (gen_rtx_SET (operands[0],
4991 gen_rtx_MINUS (SImode,
4992 gen_rtx_ASHIFTRT (SImode,
4999 [(set_attr "conds" "clob,*")
5000 (set_attr "shift" "1")
5001 (set_attr "predicable" "no, yes")
5002 (set_attr "length" "8")
5003 (set_attr "type" "multiple")]
5006 (define_expand "abssf2"
5007 [(set (match_operand:SF 0 "s_register_operand" "")
5008 (abs:SF (match_operand:SF 1 "s_register_operand" "")))]
5009 "TARGET_32BIT && TARGET_HARD_FLOAT"
5012 (define_expand "absdf2"
5013 [(set (match_operand:DF 0 "s_register_operand" "")
5014 (abs:DF (match_operand:DF 1 "s_register_operand" "")))]
5015 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
5018 (define_expand "sqrtsf2"
5019 [(set (match_operand:SF 0 "s_register_operand" "")
5020 (sqrt:SF (match_operand:SF 1 "s_register_operand" "")))]
5021 "TARGET_32BIT && TARGET_HARD_FLOAT"
5024 (define_expand "sqrtdf2"
5025 [(set (match_operand:DF 0 "s_register_operand" "")
5026 (sqrt:DF (match_operand:DF 1 "s_register_operand" "")))]
5027 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
5030 (define_insn_and_split "one_cmpldi2"
5031 [(set (match_operand:DI 0 "s_register_operand" "=w,&r,&r,?w")
5032 (not:DI (match_operand:DI 1 "s_register_operand" " w, 0, r, w")))]
5039 "TARGET_32BIT && reload_completed
5040 && arm_general_register_operand (operands[0], DImode)"
5041 [(set (match_dup 0) (not:SI (match_dup 1)))
5042 (set (match_dup 2) (not:SI (match_dup 3)))]
5045 operands[2] = gen_highpart (SImode, operands[0]);
5046 operands[0] = gen_lowpart (SImode, operands[0]);
5047 operands[3] = gen_highpart (SImode, operands[1]);
5048 operands[1] = gen_lowpart (SImode, operands[1]);
5050 [(set_attr "length" "*,8,8,*")
5051 (set_attr "predicable" "no,yes,yes,no")
5052 (set_attr "type" "neon_move,multiple,multiple,neon_move")
5053 (set_attr "arch" "neon_for_64bits,*,*,avoid_neon_for_64bits")]
5056 (define_expand "one_cmplsi2"
5057 [(set (match_operand:SI 0 "s_register_operand" "")
5058 (not:SI (match_operand:SI 1 "s_register_operand" "")))]
5063 (define_insn "*arm_one_cmplsi2"
5064 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
5065 (not:SI (match_operand:SI 1 "s_register_operand" "l,r")))]
5068 [(set_attr "predicable" "yes")
5069 (set_attr "predicable_short_it" "yes,no")
5070 (set_attr "arch" "t2,*")
5071 (set_attr "length" "4")
5072 (set_attr "type" "mvn_reg")]
5075 (define_insn "*notsi_compare0"
5076 [(set (reg:CC_NOOV CC_REGNUM)
5077 (compare:CC_NOOV (not:SI (match_operand:SI 1 "s_register_operand" "r"))
5079 (set (match_operand:SI 0 "s_register_operand" "=r")
5080 (not:SI (match_dup 1)))]
5083 [(set_attr "conds" "set")
5084 (set_attr "type" "mvn_reg")]
5087 (define_insn "*notsi_compare0_scratch"
5088 [(set (reg:CC_NOOV CC_REGNUM)
5089 (compare:CC_NOOV (not:SI (match_operand:SI 1 "s_register_operand" "r"))
5091 (clobber (match_scratch:SI 0 "=r"))]
5094 [(set_attr "conds" "set")
5095 (set_attr "type" "mvn_reg")]
5098 ;; Fixed <--> Floating conversion insns
5100 (define_expand "floatsihf2"
5101 [(set (match_operand:HF 0 "general_operand" "")
5102 (float:HF (match_operand:SI 1 "general_operand" "")))]
5106 rtx op1 = gen_reg_rtx (SFmode);
5107 expand_float (op1, operands[1], 0);
5108 op1 = convert_to_mode (HFmode, op1, 0);
5109 emit_move_insn (operands[0], op1);
5114 (define_expand "floatdihf2"
5115 [(set (match_operand:HF 0 "general_operand" "")
5116 (float:HF (match_operand:DI 1 "general_operand" "")))]
5120 rtx op1 = gen_reg_rtx (SFmode);
5121 expand_float (op1, operands[1], 0);
5122 op1 = convert_to_mode (HFmode, op1, 0);
5123 emit_move_insn (operands[0], op1);
5128 (define_expand "floatsisf2"
5129 [(set (match_operand:SF 0 "s_register_operand" "")
5130 (float:SF (match_operand:SI 1 "s_register_operand" "")))]
5131 "TARGET_32BIT && TARGET_HARD_FLOAT"
5135 (define_expand "floatsidf2"
5136 [(set (match_operand:DF 0 "s_register_operand" "")
5137 (float:DF (match_operand:SI 1 "s_register_operand" "")))]
5138 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
5142 (define_expand "fix_trunchfsi2"
5143 [(set (match_operand:SI 0 "general_operand" "")
5144 (fix:SI (fix:HF (match_operand:HF 1 "general_operand" ""))))]
5148 rtx op1 = convert_to_mode (SFmode, operands[1], 0);
5149 expand_fix (operands[0], op1, 0);
5154 (define_expand "fix_trunchfdi2"
5155 [(set (match_operand:DI 0 "general_operand" "")
5156 (fix:DI (fix:HF (match_operand:HF 1 "general_operand" ""))))]
5160 rtx op1 = convert_to_mode (SFmode, operands[1], 0);
5161 expand_fix (operands[0], op1, 0);
5166 (define_expand "fix_truncsfsi2"
5167 [(set (match_operand:SI 0 "s_register_operand" "")
5168 (fix:SI (fix:SF (match_operand:SF 1 "s_register_operand" ""))))]
5169 "TARGET_32BIT && TARGET_HARD_FLOAT"
5173 (define_expand "fix_truncdfsi2"
5174 [(set (match_operand:SI 0 "s_register_operand" "")
5175 (fix:SI (fix:DF (match_operand:DF 1 "s_register_operand" ""))))]
5176 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
5182 (define_expand "truncdfsf2"
5183 [(set (match_operand:SF 0 "s_register_operand" "")
5185 (match_operand:DF 1 "s_register_operand" "")))]
5186 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
5190 ;; DFmode to HFmode conversions on targets without a single-step hardware
5191 ;; instruction for it would have to go through SFmode. This is dangerous
5192 ;; as it introduces double rounding.
5194 ;; Disable this pattern unless we are in an unsafe math mode, or we have
5195 ;; a single-step instruction.
5197 (define_expand "truncdfhf2"
5198 [(set (match_operand:HF 0 "s_register_operand" "")
5200 (match_operand:DF 1 "s_register_operand" "")))]
5201 "(TARGET_EITHER && flag_unsafe_math_optimizations)
5202 || (TARGET_32BIT && TARGET_FP16_TO_DOUBLE)"
5204 /* We don't have a direct instruction for this, so we must be in
5205 an unsafe math mode, and going via SFmode. */
5207 if (!(TARGET_32BIT && TARGET_FP16_TO_DOUBLE))
5210 op1 = convert_to_mode (SFmode, operands[1], 0);
5211 op1 = convert_to_mode (HFmode, op1, 0);
5212 emit_move_insn (operands[0], op1);
5215 /* Otherwise, we will pick this up as a single instruction with
5216 no intermediary rounding. */
5220 ;; Zero and sign extension instructions.
5222 (define_insn "zero_extend<mode>di2"
5223 [(set (match_operand:DI 0 "s_register_operand" "=w,r,?r,w")
5224 (zero_extend:DI (match_operand:QHSI 1 "<qhs_zextenddi_op>"
5225 "<qhs_zextenddi_cstr>")))]
5226 "TARGET_32BIT <qhs_zextenddi_cond>"
5228 [(set_attr "length" "8,4,8,8")
5229 (set_attr "arch" "neon_for_64bits,*,*,avoid_neon_for_64bits")
5230 (set_attr "ce_count" "2")
5231 (set_attr "predicable" "yes")
5232 (set_attr "type" "multiple,mov_reg,multiple,multiple")]
5235 (define_insn "extend<mode>di2"
5236 [(set (match_operand:DI 0 "s_register_operand" "=w,r,?r,?r,w")
5237 (sign_extend:DI (match_operand:QHSI 1 "<qhs_extenddi_op>"
5238 "<qhs_extenddi_cstr>")))]
5239 "TARGET_32BIT <qhs_sextenddi_cond>"
5241 [(set_attr "length" "8,4,8,8,8")
5242 (set_attr "ce_count" "2")
5243 (set_attr "shift" "1")
5244 (set_attr "predicable" "yes")
5245 (set_attr "arch" "neon_for_64bits,*,a,t,avoid_neon_for_64bits")
5246 (set_attr "type" "multiple,mov_reg,multiple,multiple,multiple")]
5249 ;; Splits for all extensions to DImode
5251 [(set (match_operand:DI 0 "s_register_operand" "")
5252 (zero_extend:DI (match_operand 1 "nonimmediate_operand" "")))]
5253 "TARGET_32BIT && reload_completed && !IS_VFP_REGNUM (REGNO (operands[0]))"
5254 [(set (match_dup 0) (match_dup 1))]
5256 rtx lo_part = gen_lowpart (SImode, operands[0]);
5257 machine_mode src_mode = GET_MODE (operands[1]);
5259 if (REG_P (operands[0])
5260 && !reg_overlap_mentioned_p (operands[0], operands[1]))
5261 emit_clobber (operands[0]);
5262 if (!REG_P (lo_part) || src_mode != SImode
5263 || !rtx_equal_p (lo_part, operands[1]))
5265 if (src_mode == SImode)
5266 emit_move_insn (lo_part, operands[1]);
5268 emit_insn (gen_rtx_SET (lo_part,
5269 gen_rtx_ZERO_EXTEND (SImode, operands[1])));
5270 operands[1] = lo_part;
5272 operands[0] = gen_highpart (SImode, operands[0]);
5273 operands[1] = const0_rtx;
5277 [(set (match_operand:DI 0 "s_register_operand" "")
5278 (sign_extend:DI (match_operand 1 "nonimmediate_operand" "")))]
5279 "TARGET_32BIT && reload_completed && !IS_VFP_REGNUM (REGNO (operands[0]))"
5280 [(set (match_dup 0) (ashiftrt:SI (match_dup 1) (const_int 31)))]
5282 rtx lo_part = gen_lowpart (SImode, operands[0]);
5283 machine_mode src_mode = GET_MODE (operands[1]);
5285 if (REG_P (operands[0])
5286 && !reg_overlap_mentioned_p (operands[0], operands[1]))
5287 emit_clobber (operands[0]);
5289 if (!REG_P (lo_part) || src_mode != SImode
5290 || !rtx_equal_p (lo_part, operands[1]))
5292 if (src_mode == SImode)
5293 emit_move_insn (lo_part, operands[1]);
5295 emit_insn (gen_rtx_SET (lo_part,
5296 gen_rtx_SIGN_EXTEND (SImode, operands[1])));
5297 operands[1] = lo_part;
5299 operands[0] = gen_highpart (SImode, operands[0]);
5302 (define_expand "zero_extendhisi2"
5303 [(set (match_operand:SI 0 "s_register_operand" "")
5304 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
5307 if (TARGET_ARM && !arm_arch4 && MEM_P (operands[1]))
5309 emit_insn (gen_movhi_bytes (operands[0], operands[1]));
5312 if (!arm_arch6 && !MEM_P (operands[1]))
5314 rtx t = gen_lowpart (SImode, operands[1]);
5315 rtx tmp = gen_reg_rtx (SImode);
5316 emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (16)));
5317 emit_insn (gen_lshrsi3 (operands[0], tmp, GEN_INT (16)));
5323 [(set (match_operand:SI 0 "s_register_operand" "")
5324 (zero_extend:SI (match_operand:HI 1 "s_register_operand" "")))]
5325 "!TARGET_THUMB2 && !arm_arch6"
5326 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
5327 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 16)))]
5329 operands[2] = gen_lowpart (SImode, operands[1]);
5332 (define_insn "*arm_zero_extendhisi2"
5333 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5334 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
5335 "TARGET_ARM && arm_arch4 && !arm_arch6"
5339 [(set_attr "type" "alu_shift_reg,load_byte")
5340 (set_attr "predicable" "yes")]
5343 (define_insn "*arm_zero_extendhisi2_v6"
5344 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5345 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,Uh")))]
5346 "TARGET_ARM && arm_arch6"
5350 [(set_attr "predicable" "yes")
5351 (set_attr "type" "extend,load_byte")]
5354 (define_insn "*arm_zero_extendhisi2addsi"
5355 [(set (match_operand:SI 0 "s_register_operand" "=r")
5356 (plus:SI (zero_extend:SI (match_operand:HI 1 "s_register_operand" "r"))
5357 (match_operand:SI 2 "s_register_operand" "r")))]
5359 "uxtah%?\\t%0, %2, %1"
5360 [(set_attr "type" "alu_shift_reg")
5361 (set_attr "predicable" "yes")
5362 (set_attr "predicable_short_it" "no")]
5365 (define_expand "zero_extendqisi2"
5366 [(set (match_operand:SI 0 "s_register_operand" "")
5367 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))]
5370 if (TARGET_ARM && !arm_arch6 && !MEM_P (operands[1]))
5372 emit_insn (gen_andsi3 (operands[0],
5373 gen_lowpart (SImode, operands[1]),
5377 if (!arm_arch6 && !MEM_P (operands[1]))
5379 rtx t = gen_lowpart (SImode, operands[1]);
5380 rtx tmp = gen_reg_rtx (SImode);
5381 emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (24)));
5382 emit_insn (gen_lshrsi3 (operands[0], tmp, GEN_INT (24)));
5388 [(set (match_operand:SI 0 "s_register_operand" "")
5389 (zero_extend:SI (match_operand:QI 1 "s_register_operand" "")))]
5391 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 24)))
5392 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 24)))]
5394 operands[2] = simplify_gen_subreg (SImode, operands[1], QImode, 0);
5397 emit_insn (gen_andsi3 (operands[0], operands[2], GEN_INT (255)));
5402 (define_insn "*arm_zero_extendqisi2"
5403 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5404 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
5405 "TARGET_ARM && !arm_arch6"
5408 ldrb%?\\t%0, %1\\t%@ zero_extendqisi2"
5409 [(set_attr "length" "8,4")
5410 (set_attr "type" "alu_shift_reg,load_byte")
5411 (set_attr "predicable" "yes")]
5414 (define_insn "*arm_zero_extendqisi2_v6"
5415 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5416 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,Uh")))]
5417 "TARGET_ARM && arm_arch6"
5420 ldrb%?\\t%0, %1\\t%@ zero_extendqisi2"
5421 [(set_attr "type" "extend,load_byte")
5422 (set_attr "predicable" "yes")]
5425 (define_insn "*arm_zero_extendqisi2addsi"
5426 [(set (match_operand:SI 0 "s_register_operand" "=r")
5427 (plus:SI (zero_extend:SI (match_operand:QI 1 "s_register_operand" "r"))
5428 (match_operand:SI 2 "s_register_operand" "r")))]
5430 "uxtab%?\\t%0, %2, %1"
5431 [(set_attr "predicable" "yes")
5432 (set_attr "predicable_short_it" "no")
5433 (set_attr "type" "alu_shift_reg")]
5437 [(set (match_operand:SI 0 "s_register_operand" "")
5438 (zero_extend:SI (subreg:QI (match_operand:SI 1 "" "") 0)))
5439 (clobber (match_operand:SI 2 "s_register_operand" ""))]
5440 "TARGET_32BIT && (!MEM_P (operands[1])) && ! BYTES_BIG_ENDIAN"
5441 [(set (match_dup 2) (match_dup 1))
5442 (set (match_dup 0) (and:SI (match_dup 2) (const_int 255)))]
5447 [(set (match_operand:SI 0 "s_register_operand" "")
5448 (zero_extend:SI (subreg:QI (match_operand:SI 1 "" "") 3)))
5449 (clobber (match_operand:SI 2 "s_register_operand" ""))]
5450 "TARGET_32BIT && (!MEM_P (operands[1])) && BYTES_BIG_ENDIAN"
5451 [(set (match_dup 2) (match_dup 1))
5452 (set (match_dup 0) (and:SI (match_dup 2) (const_int 255)))]
5458 [(set (match_operand:SI 0 "s_register_operand" "")
5459 (IOR_XOR:SI (and:SI (ashift:SI
5460 (match_operand:SI 1 "s_register_operand" "")
5461 (match_operand:SI 2 "const_int_operand" ""))
5462 (match_operand:SI 3 "const_int_operand" ""))
5464 (match_operator 5 "subreg_lowpart_operator"
5465 [(match_operand:SI 4 "s_register_operand" "")]))))]
5467 && (UINTVAL (operands[3])
5468 == (GET_MODE_MASK (GET_MODE (operands[5]))
5469 & (GET_MODE_MASK (GET_MODE (operands[5]))
5470 << (INTVAL (operands[2])))))"
5471 [(set (match_dup 0) (IOR_XOR:SI (ashift:SI (match_dup 1) (match_dup 2))
5473 (set (match_dup 0) (zero_extend:SI (match_dup 5)))]
5474 "operands[5] = gen_lowpart (GET_MODE (operands[5]), operands[0]);"
5477 (define_insn "*compareqi_eq0"
5478 [(set (reg:CC_Z CC_REGNUM)
5479 (compare:CC_Z (match_operand:QI 0 "s_register_operand" "r")
5483 [(set_attr "conds" "set")
5484 (set_attr "predicable" "yes")
5485 (set_attr "predicable_short_it" "no")
5486 (set_attr "type" "logic_imm")]
5489 (define_expand "extendhisi2"
5490 [(set (match_operand:SI 0 "s_register_operand" "")
5491 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
5496 emit_insn (gen_thumb1_extendhisi2 (operands[0], operands[1]));
5499 if (MEM_P (operands[1]) && TARGET_ARM && !arm_arch4)
5501 emit_insn (gen_extendhisi2_mem (operands[0], operands[1]));
5505 if (!arm_arch6 && !MEM_P (operands[1]))
5507 rtx t = gen_lowpart (SImode, operands[1]);
5508 rtx tmp = gen_reg_rtx (SImode);
5509 emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (16)));
5510 emit_insn (gen_ashrsi3 (operands[0], tmp, GEN_INT (16)));
5517 [(set (match_operand:SI 0 "register_operand" "")
5518 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))
5519 (clobber (match_scratch:SI 2 ""))])]
5521 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
5522 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
5524 operands[2] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
5527 ;; This pattern will only be used when ldsh is not available
5528 (define_expand "extendhisi2_mem"
5529 [(set (match_dup 2) (zero_extend:SI (match_operand:HI 1 "" "")))
5531 (zero_extend:SI (match_dup 7)))
5532 (set (match_dup 6) (ashift:SI (match_dup 4) (const_int 24)))
5533 (set (match_operand:SI 0 "" "")
5534 (ior:SI (ashiftrt:SI (match_dup 6) (const_int 16)) (match_dup 5)))]
5539 rtx addr = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
5541 mem1 = change_address (operands[1], QImode, addr);
5542 mem2 = change_address (operands[1], QImode,
5543 plus_constant (Pmode, addr, 1));
5544 operands[0] = gen_lowpart (SImode, operands[0]);
5546 operands[2] = gen_reg_rtx (SImode);
5547 operands[3] = gen_reg_rtx (SImode);
5548 operands[6] = gen_reg_rtx (SImode);
5551 if (BYTES_BIG_ENDIAN)
5553 operands[4] = operands[2];
5554 operands[5] = operands[3];
5558 operands[4] = operands[3];
5559 operands[5] = operands[2];
5565 [(set (match_operand:SI 0 "register_operand" "")
5566 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
5568 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
5569 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
5571 operands[2] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
5574 (define_insn "*arm_extendhisi2"
5575 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5576 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,Uh")))]
5577 "TARGET_ARM && arm_arch4 && !arm_arch6"
5581 [(set_attr "length" "8,4")
5582 (set_attr "type" "alu_shift_reg,load_byte")
5583 (set_attr "predicable" "yes")]
5586 ;; ??? Check Thumb-2 pool range
5587 (define_insn "*arm_extendhisi2_v6"
5588 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5589 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,Uh")))]
5590 "TARGET_32BIT && arm_arch6"
5594 [(set_attr "type" "extend,load_byte")
5595 (set_attr "predicable" "yes")
5596 (set_attr "predicable_short_it" "no")]
5599 (define_insn "*arm_extendhisi2addsi"
5600 [(set (match_operand:SI 0 "s_register_operand" "=r")
5601 (plus:SI (sign_extend:SI (match_operand:HI 1 "s_register_operand" "r"))
5602 (match_operand:SI 2 "s_register_operand" "r")))]
5604 "sxtah%?\\t%0, %2, %1"
5605 [(set_attr "type" "alu_shift_reg")]
5608 (define_expand "extendqihi2"
5610 (ashift:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "")
5612 (set (match_operand:HI 0 "s_register_operand" "")
5613 (ashiftrt:SI (match_dup 2)
5618 if (arm_arch4 && MEM_P (operands[1]))
5620 emit_insn (gen_rtx_SET (operands[0],
5621 gen_rtx_SIGN_EXTEND (HImode, operands[1])));
5624 if (!s_register_operand (operands[1], QImode))
5625 operands[1] = copy_to_mode_reg (QImode, operands[1]);
5626 operands[0] = gen_lowpart (SImode, operands[0]);
5627 operands[1] = gen_lowpart (SImode, operands[1]);
5628 operands[2] = gen_reg_rtx (SImode);
5632 (define_insn "*arm_extendqihi_insn"
5633 [(set (match_operand:HI 0 "s_register_operand" "=r")
5634 (sign_extend:HI (match_operand:QI 1 "arm_extendqisi_mem_op" "Uq")))]
5635 "TARGET_ARM && arm_arch4"
5637 [(set_attr "type" "load_byte")
5638 (set_attr "predicable" "yes")]
5641 (define_expand "extendqisi2"
5642 [(set (match_operand:SI 0 "s_register_operand" "")
5643 (sign_extend:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "")))]
5646 if (!arm_arch4 && MEM_P (operands[1]))
5647 operands[1] = copy_to_mode_reg (QImode, operands[1]);
5649 if (!arm_arch6 && !MEM_P (operands[1]))
5651 rtx t = gen_lowpart (SImode, operands[1]);
5652 rtx tmp = gen_reg_rtx (SImode);
5653 emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (24)));
5654 emit_insn (gen_ashrsi3 (operands[0], tmp, GEN_INT (24)));
5660 [(set (match_operand:SI 0 "register_operand" "")
5661 (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
5663 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 24)))
5664 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 24)))]
5666 operands[2] = simplify_gen_subreg (SImode, operands[1], QImode, 0);
5669 (define_insn "*arm_extendqisi"
5670 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5671 (sign_extend:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "r,Uq")))]
5672 "TARGET_ARM && arm_arch4 && !arm_arch6"
5676 [(set_attr "length" "8,4")
5677 (set_attr "type" "alu_shift_reg,load_byte")
5678 (set_attr "predicable" "yes")]
5681 (define_insn "*arm_extendqisi_v6"
5682 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5684 (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "r,Uq")))]
5685 "TARGET_ARM && arm_arch6"
5689 [(set_attr "type" "extend,load_byte")
5690 (set_attr "predicable" "yes")]
5693 (define_insn "*arm_extendqisi2addsi"
5694 [(set (match_operand:SI 0 "s_register_operand" "=r")
5695 (plus:SI (sign_extend:SI (match_operand:QI 1 "s_register_operand" "r"))
5696 (match_operand:SI 2 "s_register_operand" "r")))]
5698 "sxtab%?\\t%0, %2, %1"
5699 [(set_attr "type" "alu_shift_reg")
5700 (set_attr "predicable" "yes")
5701 (set_attr "predicable_short_it" "no")]
5704 (define_expand "extendsfdf2"
5705 [(set (match_operand:DF 0 "s_register_operand" "")
5706 (float_extend:DF (match_operand:SF 1 "s_register_operand" "")))]
5707 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
5711 ;; HFmode -> DFmode conversions where we don't have an instruction for it
5712 ;; must go through SFmode.
5714 ;; This is always safe for an extend.
5716 (define_expand "extendhfdf2"
5717 [(set (match_operand:DF 0 "s_register_operand" "")
5718 (float_extend:DF (match_operand:HF 1 "s_register_operand" "")))]
5721 /* We don't have a direct instruction for this, so go via SFmode. */
5722 if (!(TARGET_32BIT && TARGET_FP16_TO_DOUBLE))
5725 op1 = convert_to_mode (SFmode, operands[1], 0);
5726 op1 = convert_to_mode (DFmode, op1, 0);
5727 emit_insn (gen_movdf (operands[0], op1));
5730 /* Otherwise, we're done producing RTL and will pick up the correct
5731 pattern to do this with one rounding-step in a single instruction. */
5735 ;; Move insns (including loads and stores)
5737 ;; XXX Just some ideas about movti.
5738 ;; I don't think these are a good idea on the arm, there just aren't enough
5740 ;;(define_expand "loadti"
5741 ;; [(set (match_operand:TI 0 "s_register_operand" "")
5742 ;; (mem:TI (match_operand:SI 1 "address_operand" "")))]
5745 ;;(define_expand "storeti"
5746 ;; [(set (mem:TI (match_operand:TI 0 "address_operand" ""))
5747 ;; (match_operand:TI 1 "s_register_operand" ""))]
5750 ;;(define_expand "movti"
5751 ;; [(set (match_operand:TI 0 "general_operand" "")
5752 ;; (match_operand:TI 1 "general_operand" ""))]
5758 ;; if (MEM_P (operands[0]) && MEM_P (operands[1]))
5759 ;; operands[1] = copy_to_reg (operands[1]);
5760 ;; if (MEM_P (operands[0]))
5761 ;; insn = gen_storeti (XEXP (operands[0], 0), operands[1]);
5762 ;; else if (MEM_P (operands[1]))
5763 ;; insn = gen_loadti (operands[0], XEXP (operands[1], 0));
5767 ;; emit_insn (insn);
5771 ;; Recognize garbage generated above.
5774 ;; [(set (match_operand:TI 0 "general_operand" "=r,r,r,<,>,m")
5775 ;; (match_operand:TI 1 "general_operand" "<,>,m,r,r,r"))]
5779 ;; register mem = (which_alternative < 3);
5780 ;; register const char *template;
5782 ;; operands[mem] = XEXP (operands[mem], 0);
5783 ;; switch (which_alternative)
5785 ;; case 0: template = \"ldmdb\\t%1!, %M0\"; break;
5786 ;; case 1: template = \"ldmia\\t%1!, %M0\"; break;
5787 ;; case 2: template = \"ldmia\\t%1, %M0\"; break;
5788 ;; case 3: template = \"stmdb\\t%0!, %M1\"; break;
5789 ;; case 4: template = \"stmia\\t%0!, %M1\"; break;
5790 ;; case 5: template = \"stmia\\t%0, %M1\"; break;
5792 ;; output_asm_insn (template, operands);
5796 (define_expand "movdi"
5797 [(set (match_operand:DI 0 "general_operand" "")
5798 (match_operand:DI 1 "general_operand" ""))]
5801 if (can_create_pseudo_p ())
5803 if (!REG_P (operands[0]))
5804 operands[1] = force_reg (DImode, operands[1]);
5806 if (REG_P (operands[0]) && REGNO (operands[0]) <= LAST_ARM_REGNUM
5807 && !HARD_REGNO_MODE_OK (REGNO (operands[0]), DImode))
5809 /* Avoid LDRD's into an odd-numbered register pair in ARM state
5810 when expanding function calls. */
5811 gcc_assert (can_create_pseudo_p ());
5812 if (MEM_P (operands[1]) && MEM_VOLATILE_P (operands[1]))
5814 /* Perform load into legal reg pair first, then move. */
5815 rtx reg = gen_reg_rtx (DImode);
5816 emit_insn (gen_movdi (reg, operands[1]));
5819 emit_move_insn (gen_lowpart (SImode, operands[0]),
5820 gen_lowpart (SImode, operands[1]));
5821 emit_move_insn (gen_highpart (SImode, operands[0]),
5822 gen_highpart (SImode, operands[1]));
5825 else if (REG_P (operands[1]) && REGNO (operands[1]) <= LAST_ARM_REGNUM
5826 && !HARD_REGNO_MODE_OK (REGNO (operands[1]), DImode))
5828 /* Avoid STRD's from an odd-numbered register pair in ARM state
5829 when expanding function prologue. */
5830 gcc_assert (can_create_pseudo_p ());
5831 rtx split_dest = (MEM_P (operands[0]) && MEM_VOLATILE_P (operands[0]))
5832 ? gen_reg_rtx (DImode)
5834 emit_move_insn (gen_lowpart (SImode, split_dest),
5835 gen_lowpart (SImode, operands[1]));
5836 emit_move_insn (gen_highpart (SImode, split_dest),
5837 gen_highpart (SImode, operands[1]));
5838 if (split_dest != operands[0])
5839 emit_insn (gen_movdi (operands[0], split_dest));
5845 (define_insn "*arm_movdi"
5846 [(set (match_operand:DI 0 "nonimmediate_di_operand" "=r, r, r, q, m")
5847 (match_operand:DI 1 "di_operand" "rDa,Db,Dc,mi,q"))]
5849 && !(TARGET_HARD_FLOAT)
5851 && ( register_operand (operands[0], DImode)
5852 || register_operand (operands[1], DImode))"
5854 switch (which_alternative)
5861 return output_move_double (operands, true, NULL);
5864 [(set_attr "length" "8,12,16,8,8")
5865 (set_attr "type" "multiple,multiple,multiple,load2,store2")
5866 (set_attr "arm_pool_range" "*,*,*,1020,*")
5867 (set_attr "arm_neg_pool_range" "*,*,*,1004,*")
5868 (set_attr "thumb2_pool_range" "*,*,*,4094,*")
5869 (set_attr "thumb2_neg_pool_range" "*,*,*,0,*")]
5873 [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
5874 (match_operand:ANY64 1 "immediate_operand" ""))]
5877 && (arm_disable_literal_pool
5878 || (arm_const_double_inline_cost (operands[1])
5879 <= arm_max_const_double_inline_cost ()))"
5882 arm_split_constant (SET, SImode, curr_insn,
5883 INTVAL (gen_lowpart (SImode, operands[1])),
5884 gen_lowpart (SImode, operands[0]), NULL_RTX, 0);
5885 arm_split_constant (SET, SImode, curr_insn,
5886 INTVAL (gen_highpart_mode (SImode,
5887 GET_MODE (operands[0]),
5889 gen_highpart (SImode, operands[0]), NULL_RTX, 0);
5894 ; If optimizing for size, or if we have load delay slots, then
5895 ; we want to split the constant into two separate operations.
5896 ; In both cases this may split a trivial part into a single data op
5897 ; leaving a single complex constant to load. We can also get longer
5898 ; offsets in a LDR which means we get better chances of sharing the pool
5899 ; entries. Finally, we can normally do a better job of scheduling
5900 ; LDR instructions than we can with LDM.
5901 ; This pattern will only match if the one above did not.
5903 [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
5904 (match_operand:ANY64 1 "const_double_operand" ""))]
5905 "TARGET_ARM && reload_completed
5906 && arm_const_double_by_parts (operands[1])"
5907 [(set (match_dup 0) (match_dup 1))
5908 (set (match_dup 2) (match_dup 3))]
5910 operands[2] = gen_highpart (SImode, operands[0]);
5911 operands[3] = gen_highpart_mode (SImode, GET_MODE (operands[0]),
5913 operands[0] = gen_lowpart (SImode, operands[0]);
5914 operands[1] = gen_lowpart (SImode, operands[1]);
5919 [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
5920 (match_operand:ANY64 1 "arm_general_register_operand" ""))]
5921 "TARGET_EITHER && reload_completed"
5922 [(set (match_dup 0) (match_dup 1))
5923 (set (match_dup 2) (match_dup 3))]
5925 operands[2] = gen_highpart (SImode, operands[0]);
5926 operands[3] = gen_highpart (SImode, operands[1]);
5927 operands[0] = gen_lowpart (SImode, operands[0]);
5928 operands[1] = gen_lowpart (SImode, operands[1]);
5930 /* Handle a partial overlap. */
5931 if (rtx_equal_p (operands[0], operands[3]))
5933 rtx tmp0 = operands[0];
5934 rtx tmp1 = operands[1];
5936 operands[0] = operands[2];
5937 operands[1] = operands[3];
5944 ;; We can't actually do base+index doubleword loads if the index and
5945 ;; destination overlap. Split here so that we at least have chance to
5948 [(set (match_operand:DI 0 "s_register_operand" "")
5949 (mem:DI (plus:SI (match_operand:SI 1 "s_register_operand" "")
5950 (match_operand:SI 2 "s_register_operand" ""))))]
5952 && reg_overlap_mentioned_p (operands[0], operands[1])
5953 && reg_overlap_mentioned_p (operands[0], operands[2])"
5955 (plus:SI (match_dup 1)
5958 (mem:DI (match_dup 4)))]
5960 operands[4] = gen_rtx_REG (SImode, REGNO(operands[0]));
5964 (define_expand "movsi"
5965 [(set (match_operand:SI 0 "general_operand" "")
5966 (match_operand:SI 1 "general_operand" ""))]
5970 rtx base, offset, tmp;
5972 if (TARGET_32BIT || TARGET_HAVE_MOVT)
5974 /* Everything except mem = const or mem = mem can be done easily. */
5975 if (MEM_P (operands[0]))
5976 operands[1] = force_reg (SImode, operands[1]);
5977 if (arm_general_register_operand (operands[0], SImode)
5978 && CONST_INT_P (operands[1])
5979 && !(const_ok_for_arm (INTVAL (operands[1]))
5980 || const_ok_for_arm (~INTVAL (operands[1]))))
5982 if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[1]), SET))
5984 emit_insn (gen_rtx_SET (operands[0], operands[1]));
5989 arm_split_constant (SET, SImode, NULL_RTX,
5990 INTVAL (operands[1]), operands[0], NULL_RTX,
5991 optimize && can_create_pseudo_p ());
5996 else /* Target doesn't have MOVT... */
5998 if (can_create_pseudo_p ())
6000 if (!REG_P (operands[0]))
6001 operands[1] = force_reg (SImode, operands[1]);
6005 if (ARM_OFFSETS_MUST_BE_WITHIN_SECTIONS_P)
6007 split_const (operands[1], &base, &offset);
6008 if (GET_CODE (base) == SYMBOL_REF
6009 && !offset_within_block_p (base, INTVAL (offset)))
6011 tmp = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];
6012 emit_move_insn (tmp, base);
6013 emit_insn (gen_addsi3 (operands[0], tmp, offset));
6018 /* Recognize the case where operand[1] is a reference to thread-local
6019 data and load its address to a register. */
6020 if (arm_tls_referenced_p (operands[1]))
6022 rtx tmp = operands[1];
6025 if (GET_CODE (tmp) == CONST && GET_CODE (XEXP (tmp, 0)) == PLUS)
6027 addend = XEXP (XEXP (tmp, 0), 1);
6028 tmp = XEXP (XEXP (tmp, 0), 0);
6031 gcc_assert (GET_CODE (tmp) == SYMBOL_REF);
6032 gcc_assert (SYMBOL_REF_TLS_MODEL (tmp) != 0);
6034 tmp = legitimize_tls_address (tmp,
6035 !can_create_pseudo_p () ? operands[0] : 0);
6038 tmp = gen_rtx_PLUS (SImode, tmp, addend);
6039 tmp = force_operand (tmp, operands[0]);
6044 && (CONSTANT_P (operands[1])
6045 || symbol_mentioned_p (operands[1])
6046 || label_mentioned_p (operands[1])))
6047 operands[1] = legitimize_pic_address (operands[1], SImode,
6048 (!can_create_pseudo_p ()
6055 ;; The ARM LO_SUM and HIGH are backwards - HIGH sets the low bits, and
6056 ;; LO_SUM adds in the high bits. Fortunately these are opaque operations
6057 ;; so this does not matter.
6058 (define_insn "*arm_movt"
6059 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r")
6060 (lo_sum:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6061 (match_operand:SI 2 "general_operand" "i,i")))]
6062 "TARGET_HAVE_MOVT && arm_valid_symbolic_address_p (operands[2])"
6064 movt%?\t%0, #:upper16:%c2
6065 movt\t%0, #:upper16:%c2"
6066 [(set_attr "arch" "32,v8mb")
6067 (set_attr "predicable" "yes")
6068 (set_attr "predicable_short_it" "no")
6069 (set_attr "length" "4")
6070 (set_attr "type" "alu_sreg")]
6073 (define_insn "*arm_movsi_insn"
6074 [(set (match_operand:SI 0 "nonimmediate_operand" "=rk,r,r,r,rk,m")
6075 (match_operand:SI 1 "general_operand" "rk, I,K,j,mi,rk"))]
6076 "TARGET_ARM && !TARGET_IWMMXT && !TARGET_HARD_FLOAT
6077 && ( register_operand (operands[0], SImode)
6078 || register_operand (operands[1], SImode))"
6086 [(set_attr "type" "mov_reg,mov_imm,mvn_imm,mov_imm,load1,store1")
6087 (set_attr "predicable" "yes")
6088 (set_attr "arch" "*,*,*,v6t2,*,*")
6089 (set_attr "pool_range" "*,*,*,*,4096,*")
6090 (set_attr "neg_pool_range" "*,*,*,*,4084,*")]
6094 [(set (match_operand:SI 0 "arm_general_register_operand" "")
6095 (match_operand:SI 1 "const_int_operand" ""))]
6096 "(TARGET_32BIT || TARGET_HAVE_MOVT)
6097 && (!(const_ok_for_arm (INTVAL (operands[1]))
6098 || const_ok_for_arm (~INTVAL (operands[1]))))"
6099 [(clobber (const_int 0))]
6101 arm_split_constant (SET, SImode, NULL_RTX,
6102 INTVAL (operands[1]), operands[0], NULL_RTX, 0);
6107 ;; A normal way to do (symbol + offset) requires three instructions at least
6108 ;; (depends on how big the offset is) as below:
6109 ;; movw r0, #:lower16:g
6110 ;; movw r0, #:upper16:g
6113 ;; A better way would be:
6114 ;; movw r0, #:lower16:g+4
6115 ;; movw r0, #:upper16:g+4
6117 ;; The limitation of this way is that the length of offset should be a 16-bit
6118 ;; signed value, because current assembler only supports REL type relocation for
6119 ;; such case. If the more powerful RELA type is supported in future, we should
6120 ;; update this pattern to go with better way.
6122 [(set (match_operand:SI 0 "arm_general_register_operand" "")
6123 (const:SI (plus:SI (match_operand:SI 1 "general_operand" "")
6124 (match_operand:SI 2 "const_int_operand" ""))))]
6127 && arm_disable_literal_pool
6129 && GET_CODE (operands[1]) == SYMBOL_REF"
6130 [(clobber (const_int 0))]
6132 int offset = INTVAL (operands[2]);
6134 if (offset < -0x8000 || offset > 0x7fff)
6136 arm_emit_movpair (operands[0], operands[1]);
6137 emit_insn (gen_rtx_SET (operands[0],
6138 gen_rtx_PLUS (SImode, operands[0], operands[2])));
6142 rtx op = gen_rtx_CONST (SImode,
6143 gen_rtx_PLUS (SImode, operands[1], operands[2]));
6144 arm_emit_movpair (operands[0], op);
6149 ;; Split symbol_refs at the later stage (after cprop), instead of generating
6150 ;; movt/movw pair directly at expand. Otherwise corresponding high_sum
6151 ;; and lo_sum would be merged back into memory load at cprop. However,
6152 ;; if the default is to prefer movt/movw rather than a load from the constant
6153 ;; pool, the performance is better.
6155 [(set (match_operand:SI 0 "arm_general_register_operand" "")
6156 (match_operand:SI 1 "general_operand" ""))]
6157 "TARGET_USE_MOVT && GET_CODE (operands[1]) == SYMBOL_REF
6158 && !flag_pic && !target_word_relocations
6159 && !arm_tls_referenced_p (operands[1])"
6160 [(clobber (const_int 0))]
6162 arm_emit_movpair (operands[0], operands[1]);
6166 ;; When generating pic, we need to load the symbol offset into a register.
6167 ;; So that the optimizer does not confuse this with a normal symbol load
6168 ;; we use an unspec. The offset will be loaded from a constant pool entry,
6169 ;; since that is the only type of relocation we can use.
6171 ;; Wrap calculation of the whole PIC address in a single pattern for the
6172 ;; benefit of optimizers, particularly, PRE and HOIST. Calculation of
6173 ;; a PIC address involves two loads from memory, so we want to CSE it
6174 ;; as often as possible.
6175 ;; This pattern will be split into one of the pic_load_addr_* patterns
6176 ;; and a move after GCSE optimizations.
6178 ;; Note: Update arm.c: legitimize_pic_address() when changing this pattern.
6179 (define_expand "calculate_pic_address"
6180 [(set (match_operand:SI 0 "register_operand" "")
6181 (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "")
6182 (unspec:SI [(match_operand:SI 2 "" "")]
6187 ;; Split calculate_pic_address into pic_load_addr_* and a move.
6189 [(set (match_operand:SI 0 "register_operand" "")
6190 (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "")
6191 (unspec:SI [(match_operand:SI 2 "" "")]
6194 [(set (match_dup 3) (unspec:SI [(match_dup 2)] UNSPEC_PIC_SYM))
6195 (set (match_dup 0) (mem:SI (plus:SI (match_dup 1) (match_dup 3))))]
6196 "operands[3] = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];"
6199 ;; operand1 is the memory address to go into
6200 ;; pic_load_addr_32bit.
6201 ;; operand2 is the PIC label to be emitted
6202 ;; from pic_add_dot_plus_eight.
6203 ;; We do this to allow hoisting of the entire insn.
6204 (define_insn_and_split "pic_load_addr_unified"
6205 [(set (match_operand:SI 0 "s_register_operand" "=r,r,l")
6206 (unspec:SI [(match_operand:SI 1 "" "mX,mX,mX")
6207 (match_operand:SI 2 "" "")]
6208 UNSPEC_PIC_UNIFIED))]
6211 "&& reload_completed"
6212 [(set (match_dup 0) (unspec:SI [(match_dup 1)] UNSPEC_PIC_SYM))
6213 (set (match_dup 0) (unspec:SI [(match_dup 0) (match_dup 3)
6214 (match_dup 2)] UNSPEC_PIC_BASE))]
6215 "operands[3] = TARGET_THUMB ? GEN_INT (4) : GEN_INT (8);"
6216 [(set_attr "type" "load1,load1,load1")
6217 (set_attr "pool_range" "4096,4094,1022")
6218 (set_attr "neg_pool_range" "4084,0,0")
6219 (set_attr "arch" "a,t2,t1")
6220 (set_attr "length" "8,6,4")]
6223 ;; The rather odd constraints on the following are to force reload to leave
6224 ;; the insn alone, and to force the minipool generation pass to then move
6225 ;; the GOT symbol to memory.
6227 (define_insn "pic_load_addr_32bit"
6228 [(set (match_operand:SI 0 "s_register_operand" "=r")
6229 (unspec:SI [(match_operand:SI 1 "" "mX")] UNSPEC_PIC_SYM))]
6230 "TARGET_32BIT && flag_pic"
6232 [(set_attr "type" "load1")
6233 (set (attr "pool_range")
6234 (if_then_else (eq_attr "is_thumb" "no")
6237 (set (attr "neg_pool_range")
6238 (if_then_else (eq_attr "is_thumb" "no")
6243 (define_insn "pic_load_addr_thumb1"
6244 [(set (match_operand:SI 0 "s_register_operand" "=l")
6245 (unspec:SI [(match_operand:SI 1 "" "mX")] UNSPEC_PIC_SYM))]
6246 "TARGET_THUMB1 && flag_pic"
6248 [(set_attr "type" "load1")
6249 (set (attr "pool_range") (const_int 1018))]
6252 (define_insn "pic_add_dot_plus_four"
6253 [(set (match_operand:SI 0 "register_operand" "=r")
6254 (unspec:SI [(match_operand:SI 1 "register_operand" "0")
6256 (match_operand 2 "" "")]
6260 (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
6261 INTVAL (operands[2]));
6262 return \"add\\t%0, %|pc\";
6264 [(set_attr "length" "2")
6265 (set_attr "type" "alu_sreg")]
6268 (define_insn "pic_add_dot_plus_eight"
6269 [(set (match_operand:SI 0 "register_operand" "=r")
6270 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
6272 (match_operand 2 "" "")]
6276 (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
6277 INTVAL (operands[2]));
6278 return \"add%?\\t%0, %|pc, %1\";
6280 [(set_attr "predicable" "yes")
6281 (set_attr "type" "alu_sreg")]
6284 (define_insn "tls_load_dot_plus_eight"
6285 [(set (match_operand:SI 0 "register_operand" "=r")
6286 (mem:SI (unspec:SI [(match_operand:SI 1 "register_operand" "r")
6288 (match_operand 2 "" "")]
6292 (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
6293 INTVAL (operands[2]));
6294 return \"ldr%?\\t%0, [%|pc, %1]\t\t@ tls_load_dot_plus_eight\";
6296 [(set_attr "predicable" "yes")
6297 (set_attr "type" "load1")]
6300 ;; PIC references to local variables can generate pic_add_dot_plus_eight
6301 ;; followed by a load. These sequences can be crunched down to
6302 ;; tls_load_dot_plus_eight by a peephole.
6305 [(set (match_operand:SI 0 "register_operand" "")
6306 (unspec:SI [(match_operand:SI 3 "register_operand" "")
6308 (match_operand 1 "" "")]
6310 (set (match_operand:SI 2 "arm_general_register_operand" "")
6311 (mem:SI (match_dup 0)))]
6312 "TARGET_ARM && peep2_reg_dead_p (2, operands[0])"
6314 (mem:SI (unspec:SI [(match_dup 3)
6321 (define_insn "pic_offset_arm"
6322 [(set (match_operand:SI 0 "register_operand" "=r")
6323 (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
6324 (unspec:SI [(match_operand:SI 2 "" "X")]
6325 UNSPEC_PIC_OFFSET))))]
6326 "TARGET_VXWORKS_RTP && TARGET_ARM && flag_pic"
6327 "ldr%?\\t%0, [%1,%2]"
6328 [(set_attr "type" "load1")]
6331 (define_expand "builtin_setjmp_receiver"
6332 [(label_ref (match_operand 0 "" ""))]
6336 /* r3 is clobbered by set/longjmp, so we can use it as a scratch
6338 if (arm_pic_register != INVALID_REGNUM)
6339 arm_load_pic_register (1UL << 3);
6343 ;; If copying one reg to another we can set the condition codes according to
6344 ;; its value. Such a move is common after a return from subroutine and the
6345 ;; result is being tested against zero.
6347 (define_insn "*movsi_compare0"
6348 [(set (reg:CC CC_REGNUM)
6349 (compare:CC (match_operand:SI 1 "s_register_operand" "0,r")
6351 (set (match_operand:SI 0 "s_register_operand" "=r,r")
6356 subs%?\\t%0, %1, #0"
6357 [(set_attr "conds" "set")
6358 (set_attr "type" "alus_imm,alus_imm")]
6361 ;; Subroutine to store a half word from a register into memory.
6362 ;; Operand 0 is the source register (HImode)
6363 ;; Operand 1 is the destination address in a register (SImode)
6365 ;; In both this routine and the next, we must be careful not to spill
6366 ;; a memory address of reg+large_const into a separate PLUS insn, since this
6367 ;; can generate unrecognizable rtl.
6369 (define_expand "storehi"
6370 [;; store the low byte
6371 (set (match_operand 1 "" "") (match_dup 3))
6372 ;; extract the high byte
6374 (ashiftrt:SI (match_operand 0 "" "") (const_int 8)))
6375 ;; store the high byte
6376 (set (match_dup 4) (match_dup 5))]
6380 rtx op1 = operands[1];
6381 rtx addr = XEXP (op1, 0);
6382 enum rtx_code code = GET_CODE (addr);
6384 if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1)))
6386 op1 = replace_equiv_address (operands[1], force_reg (SImode, addr));
6388 operands[4] = adjust_address (op1, QImode, 1);
6389 operands[1] = adjust_address (operands[1], QImode, 0);
6390 operands[3] = gen_lowpart (QImode, operands[0]);
6391 operands[0] = gen_lowpart (SImode, operands[0]);
6392 operands[2] = gen_reg_rtx (SImode);
6393 operands[5] = gen_lowpart (QImode, operands[2]);
6397 (define_expand "storehi_bigend"
6398 [(set (match_dup 4) (match_dup 3))
6400 (ashiftrt:SI (match_operand 0 "" "") (const_int 8)))
6401 (set (match_operand 1 "" "") (match_dup 5))]
6405 rtx op1 = operands[1];
6406 rtx addr = XEXP (op1, 0);
6407 enum rtx_code code = GET_CODE (addr);
6409 if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1)))
6411 op1 = replace_equiv_address (op1, force_reg (SImode, addr));
6413 operands[4] = adjust_address (op1, QImode, 1);
6414 operands[1] = adjust_address (operands[1], QImode, 0);
6415 operands[3] = gen_lowpart (QImode, operands[0]);
6416 operands[0] = gen_lowpart (SImode, operands[0]);
6417 operands[2] = gen_reg_rtx (SImode);
6418 operands[5] = gen_lowpart (QImode, operands[2]);
6422 ;; Subroutine to store a half word integer constant into memory.
6423 (define_expand "storeinthi"
6424 [(set (match_operand 0 "" "")
6425 (match_operand 1 "" ""))
6426 (set (match_dup 3) (match_dup 2))]
6430 HOST_WIDE_INT value = INTVAL (operands[1]);
6431 rtx addr = XEXP (operands[0], 0);
6432 rtx op0 = operands[0];
6433 enum rtx_code code = GET_CODE (addr);
6435 if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1)))
6437 op0 = replace_equiv_address (op0, force_reg (SImode, addr));
6439 operands[1] = gen_reg_rtx (SImode);
6440 if (BYTES_BIG_ENDIAN)
6442 emit_insn (gen_movsi (operands[1], GEN_INT ((value >> 8) & 255)));
6443 if ((value & 255) == ((value >> 8) & 255))
6444 operands[2] = operands[1];
6447 operands[2] = gen_reg_rtx (SImode);
6448 emit_insn (gen_movsi (operands[2], GEN_INT (value & 255)));
6453 emit_insn (gen_movsi (operands[1], GEN_INT (value & 255)));
6454 if ((value & 255) == ((value >> 8) & 255))
6455 operands[2] = operands[1];
6458 operands[2] = gen_reg_rtx (SImode);
6459 emit_insn (gen_movsi (operands[2], GEN_INT ((value >> 8) & 255)));
6463 operands[3] = adjust_address (op0, QImode, 1);
6464 operands[0] = adjust_address (operands[0], QImode, 0);
6465 operands[2] = gen_lowpart (QImode, operands[2]);
6466 operands[1] = gen_lowpart (QImode, operands[1]);
6470 (define_expand "storehi_single_op"
6471 [(set (match_operand:HI 0 "memory_operand" "")
6472 (match_operand:HI 1 "general_operand" ""))]
6473 "TARGET_32BIT && arm_arch4"
6475 if (!s_register_operand (operands[1], HImode))
6476 operands[1] = copy_to_mode_reg (HImode, operands[1]);
6480 (define_expand "movhi"
6481 [(set (match_operand:HI 0 "general_operand" "")
6482 (match_operand:HI 1 "general_operand" ""))]
6487 if (can_create_pseudo_p ())
6489 if (MEM_P (operands[0]))
6493 emit_insn (gen_storehi_single_op (operands[0], operands[1]));
6496 if (CONST_INT_P (operands[1]))
6497 emit_insn (gen_storeinthi (operands[0], operands[1]));
6500 if (MEM_P (operands[1]))
6501 operands[1] = force_reg (HImode, operands[1]);
6502 if (BYTES_BIG_ENDIAN)
6503 emit_insn (gen_storehi_bigend (operands[1], operands[0]));
6505 emit_insn (gen_storehi (operands[1], operands[0]));
6509 /* Sign extend a constant, and keep it in an SImode reg. */
6510 else if (CONST_INT_P (operands[1]))
6512 rtx reg = gen_reg_rtx (SImode);
6513 HOST_WIDE_INT val = INTVAL (operands[1]) & 0xffff;
6515 /* If the constant is already valid, leave it alone. */
6516 if (!const_ok_for_arm (val))
6518 /* If setting all the top bits will make the constant
6519 loadable in a single instruction, then set them.
6520 Otherwise, sign extend the number. */
6522 if (const_ok_for_arm (~(val | ~0xffff)))
6524 else if (val & 0x8000)
6528 emit_insn (gen_movsi (reg, GEN_INT (val)));
6529 operands[1] = gen_lowpart (HImode, reg);
6531 else if (arm_arch4 && optimize && can_create_pseudo_p ()
6532 && MEM_P (operands[1]))
6534 rtx reg = gen_reg_rtx (SImode);
6536 emit_insn (gen_zero_extendhisi2 (reg, operands[1]));
6537 operands[1] = gen_lowpart (HImode, reg);
6539 else if (!arm_arch4)
6541 if (MEM_P (operands[1]))
6544 rtx offset = const0_rtx;
6545 rtx reg = gen_reg_rtx (SImode);
6547 if ((REG_P (base = XEXP (operands[1], 0))
6548 || (GET_CODE (base) == PLUS
6549 && (CONST_INT_P (offset = XEXP (base, 1)))
6550 && ((INTVAL(offset) & 1) != 1)
6551 && REG_P (base = XEXP (base, 0))))
6552 && REGNO_POINTER_ALIGN (REGNO (base)) >= 32)
6556 new_rtx = widen_memory_access (operands[1], SImode,
6557 ((INTVAL (offset) & ~3)
6558 - INTVAL (offset)));
6559 emit_insn (gen_movsi (reg, new_rtx));
6560 if (((INTVAL (offset) & 2) != 0)
6561 ^ (BYTES_BIG_ENDIAN ? 1 : 0))
6563 rtx reg2 = gen_reg_rtx (SImode);
6565 emit_insn (gen_lshrsi3 (reg2, reg, GEN_INT (16)));
6570 emit_insn (gen_movhi_bytes (reg, operands[1]));
6572 operands[1] = gen_lowpart (HImode, reg);
6576 /* Handle loading a large integer during reload. */
6577 else if (CONST_INT_P (operands[1])
6578 && !const_ok_for_arm (INTVAL (operands[1]))
6579 && !const_ok_for_arm (~INTVAL (operands[1])))
6581 /* Writing a constant to memory needs a scratch, which should
6582 be handled with SECONDARY_RELOADs. */
6583 gcc_assert (REG_P (operands[0]));
6585 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
6586 emit_insn (gen_movsi (operands[0], operands[1]));
6590 else if (TARGET_THUMB2)
6592 /* Thumb-2 can do everything except mem=mem and mem=const easily. */
6593 if (can_create_pseudo_p ())
6595 if (!REG_P (operands[0]))
6596 operands[1] = force_reg (HImode, operands[1]);
6597 /* Zero extend a constant, and keep it in an SImode reg. */
6598 else if (CONST_INT_P (operands[1]))
6600 rtx reg = gen_reg_rtx (SImode);
6601 HOST_WIDE_INT val = INTVAL (operands[1]) & 0xffff;
6603 emit_insn (gen_movsi (reg, GEN_INT (val)));
6604 operands[1] = gen_lowpart (HImode, reg);
6608 else /* TARGET_THUMB1 */
6610 if (can_create_pseudo_p ())
6612 if (CONST_INT_P (operands[1]))
6614 rtx reg = gen_reg_rtx (SImode);
6616 emit_insn (gen_movsi (reg, operands[1]));
6617 operands[1] = gen_lowpart (HImode, reg);
6620 /* ??? We shouldn't really get invalid addresses here, but this can
6621 happen if we are passed a SP (never OK for HImode/QImode) or
6622 virtual register (also rejected as illegitimate for HImode/QImode)
6623 relative address. */
6624 /* ??? This should perhaps be fixed elsewhere, for instance, in
6625 fixup_stack_1, by checking for other kinds of invalid addresses,
6626 e.g. a bare reference to a virtual register. This may confuse the
6627 alpha though, which must handle this case differently. */
6628 if (MEM_P (operands[0])
6629 && !memory_address_p (GET_MODE (operands[0]),
6630 XEXP (operands[0], 0)))
6632 = replace_equiv_address (operands[0],
6633 copy_to_reg (XEXP (operands[0], 0)));
6635 if (MEM_P (operands[1])
6636 && !memory_address_p (GET_MODE (operands[1]),
6637 XEXP (operands[1], 0)))
6639 = replace_equiv_address (operands[1],
6640 copy_to_reg (XEXP (operands[1], 0)));
6642 if (MEM_P (operands[1]) && optimize > 0)
6644 rtx reg = gen_reg_rtx (SImode);
6646 emit_insn (gen_zero_extendhisi2 (reg, operands[1]));
6647 operands[1] = gen_lowpart (HImode, reg);
6650 if (MEM_P (operands[0]))
6651 operands[1] = force_reg (HImode, operands[1]);
6653 else if (CONST_INT_P (operands[1])
6654 && !satisfies_constraint_I (operands[1]))
6656 /* Handle loading a large integer during reload. */
6658 /* Writing a constant to memory needs a scratch, which should
6659 be handled with SECONDARY_RELOADs. */
6660 gcc_assert (REG_P (operands[0]));
6662 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
6663 emit_insn (gen_movsi (operands[0], operands[1]));
6670 (define_expand "movhi_bytes"
6671 [(set (match_dup 2) (zero_extend:SI (match_operand:HI 1 "" "")))
6673 (zero_extend:SI (match_dup 6)))
6674 (set (match_operand:SI 0 "" "")
6675 (ior:SI (ashift:SI (match_dup 4) (const_int 8)) (match_dup 5)))]
6680 rtx addr = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
6682 mem1 = change_address (operands[1], QImode, addr);
6683 mem2 = change_address (operands[1], QImode,
6684 plus_constant (Pmode, addr, 1));
6685 operands[0] = gen_lowpart (SImode, operands[0]);
6687 operands[2] = gen_reg_rtx (SImode);
6688 operands[3] = gen_reg_rtx (SImode);
6691 if (BYTES_BIG_ENDIAN)
6693 operands[4] = operands[2];
6694 operands[5] = operands[3];
6698 operands[4] = operands[3];
6699 operands[5] = operands[2];
6704 (define_expand "movhi_bigend"
6706 (rotate:SI (subreg:SI (match_operand:HI 1 "memory_operand" "") 0)
6709 (ashiftrt:SI (match_dup 2) (const_int 16)))
6710 (set (match_operand:HI 0 "s_register_operand" "")
6714 operands[2] = gen_reg_rtx (SImode);
6715 operands[3] = gen_reg_rtx (SImode);
6716 operands[4] = gen_lowpart (HImode, operands[3]);
6720 ;; Pattern to recognize insn generated default case above
6721 (define_insn "*movhi_insn_arch4"
6722 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m,r")
6723 (match_operand:HI 1 "general_operand" "rIk,K,n,r,mi"))]
6725 && arm_arch4 && !TARGET_HARD_FLOAT
6726 && (register_operand (operands[0], HImode)
6727 || register_operand (operands[1], HImode))"
6729 mov%?\\t%0, %1\\t%@ movhi
6730 mvn%?\\t%0, #%B1\\t%@ movhi
6731 movw%?\\t%0, %L1\\t%@ movhi
6732 strh%?\\t%1, %0\\t%@ movhi
6733 ldrh%?\\t%0, %1\\t%@ movhi"
6734 [(set_attr "predicable" "yes")
6735 (set_attr "pool_range" "*,*,*,*,256")
6736 (set_attr "neg_pool_range" "*,*,*,*,244")
6737 (set_attr "arch" "*,*,v6t2,*,*")
6738 (set_attr_alternative "type"
6739 [(if_then_else (match_operand 1 "const_int_operand" "")
6740 (const_string "mov_imm" )
6741 (const_string "mov_reg"))
6742 (const_string "mvn_imm")
6743 (const_string "mov_imm")
6744 (const_string "store1")
6745 (const_string "load1")])]
6748 (define_insn "*movhi_bytes"
6749 [(set (match_operand:HI 0 "s_register_operand" "=r,r,r")
6750 (match_operand:HI 1 "arm_rhs_operand" "I,rk,K"))]
6751 "TARGET_ARM && !TARGET_HARD_FLOAT"
6753 mov%?\\t%0, %1\\t%@ movhi
6754 mov%?\\t%0, %1\\t%@ movhi
6755 mvn%?\\t%0, #%B1\\t%@ movhi"
6756 [(set_attr "predicable" "yes")
6757 (set_attr "type" "mov_imm,mov_reg,mvn_imm")]
6760 ;; We use a DImode scratch because we may occasionally need an additional
6761 ;; temporary if the address isn't offsettable -- push_reload doesn't seem
6762 ;; to take any notice of the "o" constraints on reload_memory_operand operand.
6763 (define_expand "reload_outhi"
6764 [(parallel [(match_operand:HI 0 "arm_reload_memory_operand" "=o")
6765 (match_operand:HI 1 "s_register_operand" "r")
6766 (match_operand:DI 2 "s_register_operand" "=&l")])]
6769 arm_reload_out_hi (operands);
6771 thumb_reload_out_hi (operands);
6776 (define_expand "reload_inhi"
6777 [(parallel [(match_operand:HI 0 "s_register_operand" "=r")
6778 (match_operand:HI 1 "arm_reload_memory_operand" "o")
6779 (match_operand:DI 2 "s_register_operand" "=&r")])]
6783 arm_reload_in_hi (operands);
6785 thumb_reload_out_hi (operands);
6789 (define_expand "movqi"
6790 [(set (match_operand:QI 0 "general_operand" "")
6791 (match_operand:QI 1 "general_operand" ""))]
6794 /* Everything except mem = const or mem = mem can be done easily */
6796 if (can_create_pseudo_p ())
6798 if (CONST_INT_P (operands[1]))
6800 rtx reg = gen_reg_rtx (SImode);
6802 /* For thumb we want an unsigned immediate, then we are more likely
6803 to be able to use a movs insn. */
6805 operands[1] = GEN_INT (INTVAL (operands[1]) & 255);
6807 emit_insn (gen_movsi (reg, operands[1]));
6808 operands[1] = gen_lowpart (QImode, reg);
6813 /* ??? We shouldn't really get invalid addresses here, but this can
6814 happen if we are passed a SP (never OK for HImode/QImode) or
6815 virtual register (also rejected as illegitimate for HImode/QImode)
6816 relative address. */
6817 /* ??? This should perhaps be fixed elsewhere, for instance, in
6818 fixup_stack_1, by checking for other kinds of invalid addresses,
6819 e.g. a bare reference to a virtual register. This may confuse the
6820 alpha though, which must handle this case differently. */
6821 if (MEM_P (operands[0])
6822 && !memory_address_p (GET_MODE (operands[0]),
6823 XEXP (operands[0], 0)))
6825 = replace_equiv_address (operands[0],
6826 copy_to_reg (XEXP (operands[0], 0)));
6827 if (MEM_P (operands[1])
6828 && !memory_address_p (GET_MODE (operands[1]),
6829 XEXP (operands[1], 0)))
6831 = replace_equiv_address (operands[1],
6832 copy_to_reg (XEXP (operands[1], 0)));
6835 if (MEM_P (operands[1]) && optimize > 0)
6837 rtx reg = gen_reg_rtx (SImode);
6839 emit_insn (gen_zero_extendqisi2 (reg, operands[1]));
6840 operands[1] = gen_lowpart (QImode, reg);
6843 if (MEM_P (operands[0]))
6844 operands[1] = force_reg (QImode, operands[1]);
6846 else if (TARGET_THUMB
6847 && CONST_INT_P (operands[1])
6848 && !satisfies_constraint_I (operands[1]))
6850 /* Handle loading a large integer during reload. */
6852 /* Writing a constant to memory needs a scratch, which should
6853 be handled with SECONDARY_RELOADs. */
6854 gcc_assert (REG_P (operands[0]));
6856 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
6857 emit_insn (gen_movsi (operands[0], operands[1]));
6863 (define_insn "*arm_movqi_insn"
6864 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,r,l,r,l,Uu,r,m")
6865 (match_operand:QI 1 "general_operand" "rk,rk,I,Py,K,Uu,l,Uh,r"))]
6867 && ( register_operand (operands[0], QImode)
6868 || register_operand (operands[1], QImode))"
6879 [(set_attr "type" "mov_reg,mov_reg,mov_imm,mov_imm,mvn_imm,load1,store1,load1,store1")
6880 (set_attr "predicable" "yes")
6881 (set_attr "predicable_short_it" "yes,yes,no,yes,no,no,no,no,no")
6882 (set_attr "arch" "t2,any,any,t2,any,t2,t2,any,any")
6883 (set_attr "length" "2,4,4,2,4,2,2,4,4")]
6887 (define_expand "movhf"
6888 [(set (match_operand:HF 0 "general_operand" "")
6889 (match_operand:HF 1 "general_operand" ""))]
6894 if (MEM_P (operands[0]))
6895 operands[1] = force_reg (HFmode, operands[1]);
6897 else /* TARGET_THUMB1 */
6899 if (can_create_pseudo_p ())
6901 if (!REG_P (operands[0]))
6902 operands[1] = force_reg (HFmode, operands[1]);
6908 (define_insn "*arm32_movhf"
6909 [(set (match_operand:HF 0 "nonimmediate_operand" "=r,m,r,r")
6910 (match_operand:HF 1 "general_operand" " m,r,r,F"))]
6911 "TARGET_32BIT && !TARGET_HARD_FLOAT
6912 && ( s_register_operand (operands[0], HFmode)
6913 || s_register_operand (operands[1], HFmode))"
6915 switch (which_alternative)
6917 case 0: /* ARM register from memory */
6918 return \"ldrh%?\\t%0, %1\\t%@ __fp16\";
6919 case 1: /* memory from ARM register */
6920 return \"strh%?\\t%1, %0\\t%@ __fp16\";
6921 case 2: /* ARM register from ARM register */
6922 return \"mov%?\\t%0, %1\\t%@ __fp16\";
6923 case 3: /* ARM register from constant */
6928 bits = real_to_target (NULL, CONST_DOUBLE_REAL_VALUE (operands[1]),
6930 ops[0] = operands[0];
6931 ops[1] = GEN_INT (bits);
6932 ops[2] = GEN_INT (bits & 0xff00);
6933 ops[3] = GEN_INT (bits & 0x00ff);
6935 if (arm_arch_thumb2)
6936 output_asm_insn (\"movw%?\\t%0, %1\", ops);
6938 output_asm_insn (\"mov%?\\t%0, %2\;orr%?\\t%0, %0, %3\", ops);
6945 [(set_attr "conds" "unconditional")
6946 (set_attr "type" "load1,store1,mov_reg,multiple")
6947 (set_attr "length" "4,4,4,8")
6948 (set_attr "predicable" "yes")
6949 (set_attr "predicable_short_it" "no")]
6952 (define_expand "movsf"
6953 [(set (match_operand:SF 0 "general_operand" "")
6954 (match_operand:SF 1 "general_operand" ""))]
6959 if (MEM_P (operands[0]))
6960 operands[1] = force_reg (SFmode, operands[1]);
6962 else /* TARGET_THUMB1 */
6964 if (can_create_pseudo_p ())
6966 if (!REG_P (operands[0]))
6967 operands[1] = force_reg (SFmode, operands[1]);
6973 ;; Transform a floating-point move of a constant into a core register into
6974 ;; an SImode operation.
6976 [(set (match_operand:SF 0 "arm_general_register_operand" "")
6977 (match_operand:SF 1 "immediate_operand" ""))]
6980 && CONST_DOUBLE_P (operands[1])"
6981 [(set (match_dup 2) (match_dup 3))]
6983 operands[2] = gen_lowpart (SImode, operands[0]);
6984 operands[3] = gen_lowpart (SImode, operands[1]);
6985 if (operands[2] == 0 || operands[3] == 0)
6990 (define_insn "*arm_movsf_soft_insn"
6991 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,m")
6992 (match_operand:SF 1 "general_operand" "r,mE,r"))]
6994 && TARGET_SOFT_FLOAT
6995 && (!MEM_P (operands[0])
6996 || register_operand (operands[1], SFmode))"
6999 ldr%?\\t%0, %1\\t%@ float
7000 str%?\\t%1, %0\\t%@ float"
7001 [(set_attr "predicable" "yes")
7002 (set_attr "predicable_short_it" "no")
7003 (set_attr "type" "mov_reg,load1,store1")
7004 (set_attr "arm_pool_range" "*,4096,*")
7005 (set_attr "thumb2_pool_range" "*,4094,*")
7006 (set_attr "arm_neg_pool_range" "*,4084,*")
7007 (set_attr "thumb2_neg_pool_range" "*,0,*")]
7010 (define_expand "movdf"
7011 [(set (match_operand:DF 0 "general_operand" "")
7012 (match_operand:DF 1 "general_operand" ""))]
7017 if (MEM_P (operands[0]))
7018 operands[1] = force_reg (DFmode, operands[1]);
7020 else /* TARGET_THUMB */
7022 if (can_create_pseudo_p ())
7024 if (!REG_P (operands[0]))
7025 operands[1] = force_reg (DFmode, operands[1]);
7031 ;; Reloading a df mode value stored in integer regs to memory can require a
7033 (define_expand "reload_outdf"
7034 [(match_operand:DF 0 "arm_reload_memory_operand" "=o")
7035 (match_operand:DF 1 "s_register_operand" "r")
7036 (match_operand:SI 2 "s_register_operand" "=&r")]
7040 enum rtx_code code = GET_CODE (XEXP (operands[0], 0));
7043 operands[2] = XEXP (operands[0], 0);
7044 else if (code == POST_INC || code == PRE_DEC)
7046 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7047 operands[1] = gen_rtx_SUBREG (DImode, operands[1], 0);
7048 emit_insn (gen_movdi (operands[0], operands[1]));
7051 else if (code == PRE_INC)
7053 rtx reg = XEXP (XEXP (operands[0], 0), 0);
7055 emit_insn (gen_addsi3 (reg, reg, GEN_INT (8)));
7058 else if (code == POST_DEC)
7059 operands[2] = XEXP (XEXP (operands[0], 0), 0);
7061 emit_insn (gen_addsi3 (operands[2], XEXP (XEXP (operands[0], 0), 0),
7062 XEXP (XEXP (operands[0], 0), 1)));
7064 emit_insn (gen_rtx_SET (replace_equiv_address (operands[0], operands[2]),
7067 if (code == POST_DEC)
7068 emit_insn (gen_addsi3 (operands[2], operands[2], GEN_INT (-8)));
7074 (define_insn "*movdf_soft_insn"
7075 [(set (match_operand:DF 0 "nonimmediate_soft_df_operand" "=r,r,r,q,m")
7076 (match_operand:DF 1 "soft_df_operand" "rDa,Db,Dc,mF,q"))]
7077 "TARGET_32BIT && TARGET_SOFT_FLOAT
7078 && ( register_operand (operands[0], DFmode)
7079 || register_operand (operands[1], DFmode))"
7081 switch (which_alternative)
7088 return output_move_double (operands, true, NULL);
7091 [(set_attr "length" "8,12,16,8,8")
7092 (set_attr "type" "multiple,multiple,multiple,load2,store2")
7093 (set_attr "arm_pool_range" "*,*,*,1020,*")
7094 (set_attr "thumb2_pool_range" "*,*,*,1018,*")
7095 (set_attr "arm_neg_pool_range" "*,*,*,1004,*")
7096 (set_attr "thumb2_neg_pool_range" "*,*,*,0,*")]
7100 ;; load- and store-multiple insns
7101 ;; The arm can load/store any set of registers, provided that they are in
7102 ;; ascending order, but these expanders assume a contiguous set.
7104 (define_expand "load_multiple"
7105 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
7106 (match_operand:SI 1 "" ""))
7107 (use (match_operand:SI 2 "" ""))])]
7110 HOST_WIDE_INT offset = 0;
7112 /* Support only fixed point registers. */
7113 if (!CONST_INT_P (operands[2])
7114 || INTVAL (operands[2]) > MAX_LDM_STM_OPS
7115 || INTVAL (operands[2]) < 2
7116 || !MEM_P (operands[1])
7117 || !REG_P (operands[0])
7118 || REGNO (operands[0]) > (LAST_ARM_REGNUM - 1)
7119 || REGNO (operands[0]) + INTVAL (operands[2]) > LAST_ARM_REGNUM)
7123 = arm_gen_load_multiple (arm_regs_in_sequence + REGNO (operands[0]),
7124 INTVAL (operands[2]),
7125 force_reg (SImode, XEXP (operands[1], 0)),
7126 FALSE, operands[1], &offset);
7129 (define_expand "store_multiple"
7130 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
7131 (match_operand:SI 1 "" ""))
7132 (use (match_operand:SI 2 "" ""))])]
7135 HOST_WIDE_INT offset = 0;
7137 /* Support only fixed point registers. */
7138 if (!CONST_INT_P (operands[2])
7139 || INTVAL (operands[2]) > MAX_LDM_STM_OPS
7140 || INTVAL (operands[2]) < 2
7141 || !REG_P (operands[1])
7142 || !MEM_P (operands[0])
7143 || REGNO (operands[1]) > (LAST_ARM_REGNUM - 1)
7144 || REGNO (operands[1]) + INTVAL (operands[2]) > LAST_ARM_REGNUM)
7148 = arm_gen_store_multiple (arm_regs_in_sequence + REGNO (operands[1]),
7149 INTVAL (operands[2]),
7150 force_reg (SImode, XEXP (operands[0], 0)),
7151 FALSE, operands[0], &offset);
7155 (define_expand "setmemsi"
7156 [(match_operand:BLK 0 "general_operand" "")
7157 (match_operand:SI 1 "const_int_operand" "")
7158 (match_operand:SI 2 "const_int_operand" "")
7159 (match_operand:SI 3 "const_int_operand" "")]
7162 if (arm_gen_setmem (operands))
7169 ;; Move a block of memory if it is word aligned and MORE than 2 words long.
7170 ;; We could let this apply for blocks of less than this, but it clobbers so
7171 ;; many registers that there is then probably a better way.
7173 (define_expand "movmemqi"
7174 [(match_operand:BLK 0 "general_operand" "")
7175 (match_operand:BLK 1 "general_operand" "")
7176 (match_operand:SI 2 "const_int_operand" "")
7177 (match_operand:SI 3 "const_int_operand" "")]
7182 if (TARGET_LDRD && current_tune->prefer_ldrd_strd
7183 && !optimize_function_for_size_p (cfun))
7185 if (gen_movmem_ldrd_strd (operands))
7190 if (arm_gen_movmemqi (operands))
7194 else /* TARGET_THUMB1 */
7196 if ( INTVAL (operands[3]) != 4
7197 || INTVAL (operands[2]) > 48)
7200 thumb_expand_movmemqi (operands);
7207 ;; Compare & branch insns
7208 ;; The range calculations are based as follows:
7209 ;; For forward branches, the address calculation returns the address of
7210 ;; the next instruction. This is 2 beyond the branch instruction.
7211 ;; For backward branches, the address calculation returns the address of
7212 ;; the first instruction in this pattern (cmp). This is 2 before the branch
7213 ;; instruction for the shortest sequence, and 4 before the branch instruction
7214 ;; if we have to jump around an unconditional branch.
7215 ;; To the basic branch range the PC offset must be added (this is +4).
7216 ;; So for forward branches we have
7217 ;; (pos_range - pos_base_offs + pc_offs) = (pos_range - 2 + 4).
7218 ;; And for backward branches we have
7219 ;; (neg_range - neg_base_offs + pc_offs) = (neg_range - (-2 or -4) + 4).
7221 ;; For a 'b' pos_range = 2046, neg_range = -2048 giving (-2040->2048).
7222 ;; For a 'b<cond>' pos_range = 254, neg_range = -256 giving (-250 ->256).
7224 (define_expand "cbranchsi4"
7225 [(set (pc) (if_then_else
7226 (match_operator 0 "expandable_comparison_operator"
7227 [(match_operand:SI 1 "s_register_operand" "")
7228 (match_operand:SI 2 "nonmemory_operand" "")])
7229 (label_ref (match_operand 3 "" ""))
7235 if (!arm_validize_comparison (&operands[0], &operands[1], &operands[2]))
7237 emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
7241 if (thumb1_cmpneg_operand (operands[2], SImode))
7243 emit_jump_insn (gen_cbranchsi4_scratch (NULL, operands[1], operands[2],
7244 operands[3], operands[0]));
7247 if (!thumb1_cmp_operand (operands[2], SImode))
7248 operands[2] = force_reg (SImode, operands[2]);
7251 (define_expand "cbranchsf4"
7252 [(set (pc) (if_then_else
7253 (match_operator 0 "expandable_comparison_operator"
7254 [(match_operand:SF 1 "s_register_operand" "")
7255 (match_operand:SF 2 "vfp_compare_operand" "")])
7256 (label_ref (match_operand 3 "" ""))
7258 "TARGET_32BIT && TARGET_HARD_FLOAT"
7259 "emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
7260 operands[3])); DONE;"
7263 (define_expand "cbranchdf4"
7264 [(set (pc) (if_then_else
7265 (match_operator 0 "expandable_comparison_operator"
7266 [(match_operand:DF 1 "s_register_operand" "")
7267 (match_operand:DF 2 "vfp_compare_operand" "")])
7268 (label_ref (match_operand 3 "" ""))
7270 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
7271 "emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
7272 operands[3])); DONE;"
7275 (define_expand "cbranchdi4"
7276 [(set (pc) (if_then_else
7277 (match_operator 0 "expandable_comparison_operator"
7278 [(match_operand:DI 1 "s_register_operand" "")
7279 (match_operand:DI 2 "cmpdi_operand" "")])
7280 (label_ref (match_operand 3 "" ""))
7284 if (!arm_validize_comparison (&operands[0], &operands[1], &operands[2]))
7286 emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
7292 ;; Comparison and test insns
7294 (define_insn "*arm_cmpsi_insn"
7295 [(set (reg:CC CC_REGNUM)
7296 (compare:CC (match_operand:SI 0 "s_register_operand" "l,r,r,r,r")
7297 (match_operand:SI 1 "arm_add_operand" "Py,r,r,I,L")))]
7305 [(set_attr "conds" "set")
7306 (set_attr "arch" "t2,t2,any,any,any")
7307 (set_attr "length" "2,2,4,4,4")
7308 (set_attr "predicable" "yes")
7309 (set_attr "predicable_short_it" "yes,yes,yes,no,no")
7310 (set_attr "type" "alus_imm,alus_sreg,alus_sreg,alus_imm,alus_imm")]
7313 (define_insn "*cmpsi_shiftsi"
7314 [(set (reg:CC CC_REGNUM)
7315 (compare:CC (match_operand:SI 0 "s_register_operand" "r,r,r")
7316 (match_operator:SI 3 "shift_operator"
7317 [(match_operand:SI 1 "s_register_operand" "r,r,r")
7318 (match_operand:SI 2 "shift_amount_operand" "M,r,M")])))]
7321 [(set_attr "conds" "set")
7322 (set_attr "shift" "1")
7323 (set_attr "arch" "32,a,a")
7324 (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
7326 (define_insn "*cmpsi_shiftsi_swp"
7327 [(set (reg:CC_SWP CC_REGNUM)
7328 (compare:CC_SWP (match_operator:SI 3 "shift_operator"
7329 [(match_operand:SI 1 "s_register_operand" "r,r,r")
7330 (match_operand:SI 2 "shift_amount_operand" "M,r,M")])
7331 (match_operand:SI 0 "s_register_operand" "r,r,r")))]
7334 [(set_attr "conds" "set")
7335 (set_attr "shift" "1")
7336 (set_attr "arch" "32,a,a")
7337 (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
7339 (define_insn "*arm_cmpsi_negshiftsi_si"
7340 [(set (reg:CC_Z CC_REGNUM)
7342 (neg:SI (match_operator:SI 1 "shift_operator"
7343 [(match_operand:SI 2 "s_register_operand" "r")
7344 (match_operand:SI 3 "reg_or_int_operand" "rM")]))
7345 (match_operand:SI 0 "s_register_operand" "r")))]
7348 [(set_attr "conds" "set")
7349 (set (attr "type") (if_then_else (match_operand 3 "const_int_operand" "")
7350 (const_string "alus_shift_imm")
7351 (const_string "alus_shift_reg")))
7352 (set_attr "predicable" "yes")]
7355 ;; DImode comparisons. The generic code generates branches that
7356 ;; if-conversion can not reduce to a conditional compare, so we do
7359 (define_insn_and_split "*arm_cmpdi_insn"
7360 [(set (reg:CC_NCV CC_REGNUM)
7361 (compare:CC_NCV (match_operand:DI 0 "s_register_operand" "r")
7362 (match_operand:DI 1 "arm_di_operand" "rDi")))
7363 (clobber (match_scratch:SI 2 "=r"))]
7365 "#" ; "cmp\\t%Q0, %Q1\;sbcs\\t%2, %R0, %R1"
7366 "&& reload_completed"
7367 [(set (reg:CC CC_REGNUM)
7368 (compare:CC (match_dup 0) (match_dup 1)))
7369 (parallel [(set (reg:CC CC_REGNUM)
7370 (compare:CC (match_dup 3) (match_dup 4)))
7372 (minus:SI (match_dup 5)
7373 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))])]
7375 operands[3] = gen_highpart (SImode, operands[0]);
7376 operands[0] = gen_lowpart (SImode, operands[0]);
7377 if (CONST_INT_P (operands[1]))
7379 operands[4] = GEN_INT (~INTVAL (gen_highpart_mode (SImode,
7382 operands[5] = gen_rtx_PLUS (SImode, operands[3], operands[4]);
7386 operands[4] = gen_highpart (SImode, operands[1]);
7387 operands[5] = gen_rtx_MINUS (SImode, operands[3], operands[4]);
7389 operands[1] = gen_lowpart (SImode, operands[1]);
7390 operands[2] = gen_lowpart (SImode, operands[2]);
7392 [(set_attr "conds" "set")
7393 (set_attr "length" "8")
7394 (set_attr "type" "multiple")]
7397 (define_insn_and_split "*arm_cmpdi_unsigned"
7398 [(set (reg:CC_CZ CC_REGNUM)
7399 (compare:CC_CZ (match_operand:DI 0 "s_register_operand" "l,r,r,r")
7400 (match_operand:DI 1 "arm_di_operand" "Py,r,Di,rDi")))]
7403 "#" ; "cmp\\t%R0, %R1\;it eq\;cmpeq\\t%Q0, %Q1"
7404 "&& reload_completed"
7405 [(set (reg:CC CC_REGNUM)
7406 (compare:CC (match_dup 2) (match_dup 3)))
7407 (cond_exec (eq:SI (reg:CC CC_REGNUM) (const_int 0))
7408 (set (reg:CC CC_REGNUM)
7409 (compare:CC (match_dup 0) (match_dup 1))))]
7411 operands[2] = gen_highpart (SImode, operands[0]);
7412 operands[0] = gen_lowpart (SImode, operands[0]);
7413 if (CONST_INT_P (operands[1]))
7414 operands[3] = gen_highpart_mode (SImode, DImode, operands[1]);
7416 operands[3] = gen_highpart (SImode, operands[1]);
7417 operands[1] = gen_lowpart (SImode, operands[1]);
7419 [(set_attr "conds" "set")
7420 (set_attr "enabled_for_depr_it" "yes,yes,no,*")
7421 (set_attr "arch" "t2,t2,t2,a")
7422 (set_attr "length" "6,6,10,8")
7423 (set_attr "type" "multiple")]
7426 (define_insn "*arm_cmpdi_zero"
7427 [(set (reg:CC_Z CC_REGNUM)
7428 (compare:CC_Z (match_operand:DI 0 "s_register_operand" "r")
7430 (clobber (match_scratch:SI 1 "=r"))]
7432 "orrs%?\\t%1, %Q0, %R0"
7433 [(set_attr "conds" "set")
7434 (set_attr "type" "logics_reg")]
7437 ; This insn allows redundant compares to be removed by cse, nothing should
7438 ; ever appear in the output file since (set (reg x) (reg x)) is a no-op that
7439 ; is deleted later on. The match_dup will match the mode here, so that
7440 ; mode changes of the condition codes aren't lost by this even though we don't
7441 ; specify what they are.
7443 (define_insn "*deleted_compare"
7444 [(set (match_operand 0 "cc_register" "") (match_dup 0))]
7446 "\\t%@ deleted compare"
7447 [(set_attr "conds" "set")
7448 (set_attr "length" "0")
7449 (set_attr "type" "no_insn")]
7453 ;; Conditional branch insns
7455 (define_expand "cbranch_cc"
7457 (if_then_else (match_operator 0 "" [(match_operand 1 "" "")
7458 (match_operand 2 "" "")])
7459 (label_ref (match_operand 3 "" ""))
7462 "operands[1] = arm_gen_compare_reg (GET_CODE (operands[0]),
7463 operands[1], operands[2], NULL_RTX);
7464 operands[2] = const0_rtx;"
7468 ;; Patterns to match conditional branch insns.
7471 (define_insn "arm_cond_branch"
7473 (if_then_else (match_operator 1 "arm_comparison_operator"
7474 [(match_operand 2 "cc_register" "") (const_int 0)])
7475 (label_ref (match_operand 0 "" ""))
7479 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
7481 arm_ccfsm_state += 2;
7484 return \"b%d1\\t%l0\";
7486 [(set_attr "conds" "use")
7487 (set_attr "type" "branch")
7488 (set (attr "length")
7490 (and (match_test "TARGET_THUMB2")
7491 (and (ge (minus (match_dup 0) (pc)) (const_int -250))
7492 (le (minus (match_dup 0) (pc)) (const_int 256))))
7497 (define_insn "*arm_cond_branch_reversed"
7499 (if_then_else (match_operator 1 "arm_comparison_operator"
7500 [(match_operand 2 "cc_register" "") (const_int 0)])
7502 (label_ref (match_operand 0 "" ""))))]
7505 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
7507 arm_ccfsm_state += 2;
7510 return \"b%D1\\t%l0\";
7512 [(set_attr "conds" "use")
7513 (set_attr "type" "branch")
7514 (set (attr "length")
7516 (and (match_test "TARGET_THUMB2")
7517 (and (ge (minus (match_dup 0) (pc)) (const_int -250))
7518 (le (minus (match_dup 0) (pc)) (const_int 256))))
7527 (define_expand "cstore_cc"
7528 [(set (match_operand:SI 0 "s_register_operand" "")
7529 (match_operator:SI 1 "" [(match_operand 2 "" "")
7530 (match_operand 3 "" "")]))]
7532 "operands[2] = arm_gen_compare_reg (GET_CODE (operands[1]),
7533 operands[2], operands[3], NULL_RTX);
7534 operands[3] = const0_rtx;"
7537 (define_insn_and_split "*mov_scc"
7538 [(set (match_operand:SI 0 "s_register_operand" "=r")
7539 (match_operator:SI 1 "arm_comparison_operator_mode"
7540 [(match_operand 2 "cc_register" "") (const_int 0)]))]
7542 "#" ; "mov%D1\\t%0, #0\;mov%d1\\t%0, #1"
7545 (if_then_else:SI (match_dup 1)
7549 [(set_attr "conds" "use")
7550 (set_attr "length" "8")
7551 (set_attr "type" "multiple")]
7554 (define_insn_and_split "*mov_negscc"
7555 [(set (match_operand:SI 0 "s_register_operand" "=r")
7556 (neg:SI (match_operator:SI 1 "arm_comparison_operator_mode"
7557 [(match_operand 2 "cc_register" "") (const_int 0)])))]
7559 "#" ; "mov%D1\\t%0, #0\;mvn%d1\\t%0, #0"
7562 (if_then_else:SI (match_dup 1)
7566 operands[3] = GEN_INT (~0);
7568 [(set_attr "conds" "use")
7569 (set_attr "length" "8")
7570 (set_attr "type" "multiple")]
7573 (define_insn_and_split "*mov_notscc"
7574 [(set (match_operand:SI 0 "s_register_operand" "=r")
7575 (not:SI (match_operator:SI 1 "arm_comparison_operator"
7576 [(match_operand 2 "cc_register" "") (const_int 0)])))]
7578 "#" ; "mvn%D1\\t%0, #0\;mvn%d1\\t%0, #1"
7581 (if_then_else:SI (match_dup 1)
7585 operands[3] = GEN_INT (~1);
7586 operands[4] = GEN_INT (~0);
7588 [(set_attr "conds" "use")
7589 (set_attr "length" "8")
7590 (set_attr "type" "multiple")]
7593 (define_expand "cstoresi4"
7594 [(set (match_operand:SI 0 "s_register_operand" "")
7595 (match_operator:SI 1 "expandable_comparison_operator"
7596 [(match_operand:SI 2 "s_register_operand" "")
7597 (match_operand:SI 3 "reg_or_int_operand" "")]))]
7598 "TARGET_32BIT || TARGET_THUMB1"
7600 rtx op3, scratch, scratch2;
7604 if (!arm_add_operand (operands[3], SImode))
7605 operands[3] = force_reg (SImode, operands[3]);
7606 emit_insn (gen_cstore_cc (operands[0], operands[1],
7607 operands[2], operands[3]));
7611 if (operands[3] == const0_rtx)
7613 switch (GET_CODE (operands[1]))
7616 emit_insn (gen_cstoresi_eq0_thumb1 (operands[0], operands[2]));
7620 emit_insn (gen_cstoresi_ne0_thumb1 (operands[0], operands[2]));
7624 scratch = expand_binop (SImode, add_optab, operands[2], constm1_rtx,
7625 NULL_RTX, 0, OPTAB_WIDEN);
7626 scratch = expand_binop (SImode, ior_optab, operands[2], scratch,
7627 NULL_RTX, 0, OPTAB_WIDEN);
7628 expand_binop (SImode, lshr_optab, scratch, GEN_INT (31),
7629 operands[0], 1, OPTAB_WIDEN);
7633 scratch = expand_unop (SImode, one_cmpl_optab, operands[2],
7635 expand_binop (SImode, lshr_optab, scratch, GEN_INT (31),
7636 NULL_RTX, 1, OPTAB_WIDEN);
7640 scratch = expand_binop (SImode, ashr_optab, operands[2],
7641 GEN_INT (31), NULL_RTX, 0, OPTAB_WIDEN);
7642 scratch = expand_binop (SImode, sub_optab, scratch, operands[2],
7643 NULL_RTX, 0, OPTAB_WIDEN);
7644 expand_binop (SImode, lshr_optab, scratch, GEN_INT (31), operands[0],
7648 /* LT is handled by generic code. No need for unsigned with 0. */
7655 switch (GET_CODE (operands[1]))
7658 scratch = expand_binop (SImode, sub_optab, operands[2], operands[3],
7659 NULL_RTX, 0, OPTAB_WIDEN);
7660 emit_insn (gen_cstoresi_eq0_thumb1 (operands[0], scratch));
7664 scratch = expand_binop (SImode, sub_optab, operands[2], operands[3],
7665 NULL_RTX, 0, OPTAB_WIDEN);
7666 emit_insn (gen_cstoresi_ne0_thumb1 (operands[0], scratch));
7670 op3 = force_reg (SImode, operands[3]);
7672 scratch = expand_binop (SImode, lshr_optab, operands[2], GEN_INT (31),
7673 NULL_RTX, 1, OPTAB_WIDEN);
7674 scratch2 = expand_binop (SImode, ashr_optab, op3, GEN_INT (31),
7675 NULL_RTX, 0, OPTAB_WIDEN);
7676 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch2,
7682 if (!thumb1_cmp_operand (op3, SImode))
7683 op3 = force_reg (SImode, op3);
7684 scratch = expand_binop (SImode, ashr_optab, operands[2], GEN_INT (31),
7685 NULL_RTX, 0, OPTAB_WIDEN);
7686 scratch2 = expand_binop (SImode, lshr_optab, op3, GEN_INT (31),
7687 NULL_RTX, 1, OPTAB_WIDEN);
7688 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch2,
7693 op3 = force_reg (SImode, operands[3]);
7694 scratch = force_reg (SImode, const0_rtx);
7695 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch,
7701 if (!thumb1_cmp_operand (op3, SImode))
7702 op3 = force_reg (SImode, op3);
7703 scratch = force_reg (SImode, const0_rtx);
7704 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch,
7710 if (!thumb1_cmp_operand (op3, SImode))
7711 op3 = force_reg (SImode, op3);
7712 scratch = gen_reg_rtx (SImode);
7713 emit_insn (gen_cstoresi_ltu_thumb1 (operands[0], operands[2], op3));
7717 op3 = force_reg (SImode, operands[3]);
7718 scratch = gen_reg_rtx (SImode);
7719 emit_insn (gen_cstoresi_ltu_thumb1 (operands[0], op3, operands[2]));
7722 /* No good sequences for GT, LT. */
7729 (define_expand "cstorehf4"
7730 [(set (match_operand:SI 0 "s_register_operand")
7731 (match_operator:SI 1 "expandable_comparison_operator"
7732 [(match_operand:HF 2 "s_register_operand")
7733 (match_operand:HF 3 "vfp_compare_operand")]))]
7734 "TARGET_VFP_FP16INST"
7736 if (!arm_validize_comparison (&operands[1],
7741 emit_insn (gen_cstore_cc (operands[0], operands[1],
7742 operands[2], operands[3]));
7747 (define_expand "cstoresf4"
7748 [(set (match_operand:SI 0 "s_register_operand" "")
7749 (match_operator:SI 1 "expandable_comparison_operator"
7750 [(match_operand:SF 2 "s_register_operand" "")
7751 (match_operand:SF 3 "vfp_compare_operand" "")]))]
7752 "TARGET_32BIT && TARGET_HARD_FLOAT"
7753 "emit_insn (gen_cstore_cc (operands[0], operands[1],
7754 operands[2], operands[3])); DONE;"
7757 (define_expand "cstoredf4"
7758 [(set (match_operand:SI 0 "s_register_operand" "")
7759 (match_operator:SI 1 "expandable_comparison_operator"
7760 [(match_operand:DF 2 "s_register_operand" "")
7761 (match_operand:DF 3 "vfp_compare_operand" "")]))]
7762 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
7763 "emit_insn (gen_cstore_cc (operands[0], operands[1],
7764 operands[2], operands[3])); DONE;"
7767 (define_expand "cstoredi4"
7768 [(set (match_operand:SI 0 "s_register_operand" "")
7769 (match_operator:SI 1 "expandable_comparison_operator"
7770 [(match_operand:DI 2 "s_register_operand" "")
7771 (match_operand:DI 3 "cmpdi_operand" "")]))]
7774 if (!arm_validize_comparison (&operands[1],
7778 emit_insn (gen_cstore_cc (operands[0], operands[1], operands[2],
7785 ;; Conditional move insns
7787 (define_expand "movsicc"
7788 [(set (match_operand:SI 0 "s_register_operand" "")
7789 (if_then_else:SI (match_operand 1 "expandable_comparison_operator" "")
7790 (match_operand:SI 2 "arm_not_operand" "")
7791 (match_operand:SI 3 "arm_not_operand" "")))]
7798 if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
7799 &XEXP (operands[1], 1)))
7802 code = GET_CODE (operands[1]);
7803 ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
7804 XEXP (operands[1], 1), NULL_RTX);
7805 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7809 (define_expand "movhfcc"
7810 [(set (match_operand:HF 0 "s_register_operand")
7811 (if_then_else:HF (match_operand 1 "arm_cond_move_operator")
7812 (match_operand:HF 2 "s_register_operand")
7813 (match_operand:HF 3 "s_register_operand")))]
7814 "TARGET_VFP_FP16INST"
7817 enum rtx_code code = GET_CODE (operands[1]);
7820 if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
7821 &XEXP (operands[1], 1)))
7824 code = GET_CODE (operands[1]);
7825 ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
7826 XEXP (operands[1], 1), NULL_RTX);
7827 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7831 (define_expand "movsfcc"
7832 [(set (match_operand:SF 0 "s_register_operand" "")
7833 (if_then_else:SF (match_operand 1 "arm_cond_move_operator" "")
7834 (match_operand:SF 2 "s_register_operand" "")
7835 (match_operand:SF 3 "s_register_operand" "")))]
7836 "TARGET_32BIT && TARGET_HARD_FLOAT"
7839 enum rtx_code code = GET_CODE (operands[1]);
7842 if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
7843 &XEXP (operands[1], 1)))
7846 code = GET_CODE (operands[1]);
7847 ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
7848 XEXP (operands[1], 1), NULL_RTX);
7849 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7853 (define_expand "movdfcc"
7854 [(set (match_operand:DF 0 "s_register_operand" "")
7855 (if_then_else:DF (match_operand 1 "arm_cond_move_operator" "")
7856 (match_operand:DF 2 "s_register_operand" "")
7857 (match_operand:DF 3 "s_register_operand" "")))]
7858 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
7861 enum rtx_code code = GET_CODE (operands[1]);
7864 if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
7865 &XEXP (operands[1], 1)))
7867 code = GET_CODE (operands[1]);
7868 ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
7869 XEXP (operands[1], 1), NULL_RTX);
7870 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7874 (define_insn "*cmov<mode>"
7875 [(set (match_operand:SDF 0 "s_register_operand" "=<F_constraint>")
7876 (if_then_else:SDF (match_operator 1 "arm_vsel_comparison_operator"
7877 [(match_operand 2 "cc_register" "") (const_int 0)])
7878 (match_operand:SDF 3 "s_register_operand"
7880 (match_operand:SDF 4 "s_register_operand"
7881 "<F_constraint>")))]
7882 "TARGET_HARD_FLOAT && TARGET_FPU_ARMV8 <vfp_double_cond>"
7885 enum arm_cond_code code = maybe_get_arm_condition_code (operands[1]);
7892 return \"vsel%d1.<V_if_elem>\\t%<V_reg>0, %<V_reg>3, %<V_reg>4\";
7897 return \"vsel%D1.<V_if_elem>\\t%<V_reg>0, %<V_reg>4, %<V_reg>3\";
7903 [(set_attr "conds" "use")
7904 (set_attr "type" "fcsel")]
7907 (define_insn "*cmovhf"
7908 [(set (match_operand:HF 0 "s_register_operand" "=t")
7909 (if_then_else:HF (match_operator 1 "arm_vsel_comparison_operator"
7910 [(match_operand 2 "cc_register" "") (const_int 0)])
7911 (match_operand:HF 3 "s_register_operand" "t")
7912 (match_operand:HF 4 "s_register_operand" "t")))]
7913 "TARGET_VFP_FP16INST"
7916 enum arm_cond_code code = maybe_get_arm_condition_code (operands[1]);
7923 return \"vsel%d1.f16\\t%0, %3, %4\";
7928 return \"vsel%D1.f16\\t%0, %4, %3\";
7934 [(set_attr "conds" "use")
7935 (set_attr "type" "fcsel")]
7938 (define_insn_and_split "*movsicc_insn"
7939 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r,r,r,r,r")
7941 (match_operator 3 "arm_comparison_operator"
7942 [(match_operand 4 "cc_register" "") (const_int 0)])
7943 (match_operand:SI 1 "arm_not_operand" "0,0,rI,K,rI,rI,K,K")
7944 (match_operand:SI 2 "arm_not_operand" "rI,K,0,0,rI,K,rI,K")))]
7955 ; alt4: mov%d3\\t%0, %1\;mov%D3\\t%0, %2
7956 ; alt5: mov%d3\\t%0, %1\;mvn%D3\\t%0, #%B2
7957 ; alt6: mvn%d3\\t%0, #%B1\;mov%D3\\t%0, %2
7958 ; alt7: mvn%d3\\t%0, #%B1\;mvn%D3\\t%0, #%B2"
7959 "&& reload_completed"
7962 enum rtx_code rev_code;
7966 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
7968 gen_rtx_SET (operands[0], operands[1])));
7970 rev_code = GET_CODE (operands[3]);
7971 mode = GET_MODE (operands[4]);
7972 if (mode == CCFPmode || mode == CCFPEmode)
7973 rev_code = reverse_condition_maybe_unordered (rev_code);
7975 rev_code = reverse_condition (rev_code);
7977 rev_cond = gen_rtx_fmt_ee (rev_code,
7981 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
7983 gen_rtx_SET (operands[0], operands[2])));
7986 [(set_attr "length" "4,4,4,4,8,8,8,8")
7987 (set_attr "conds" "use")
7988 (set_attr_alternative "type"
7989 [(if_then_else (match_operand 2 "const_int_operand" "")
7990 (const_string "mov_imm")
7991 (const_string "mov_reg"))
7992 (const_string "mvn_imm")
7993 (if_then_else (match_operand 1 "const_int_operand" "")
7994 (const_string "mov_imm")
7995 (const_string "mov_reg"))
7996 (const_string "mvn_imm")
7997 (const_string "multiple")
7998 (const_string "multiple")
7999 (const_string "multiple")
8000 (const_string "multiple")])]
8003 (define_insn "*movsfcc_soft_insn"
8004 [(set (match_operand:SF 0 "s_register_operand" "=r,r")
8005 (if_then_else:SF (match_operator 3 "arm_comparison_operator"
8006 [(match_operand 4 "cc_register" "") (const_int 0)])
8007 (match_operand:SF 1 "s_register_operand" "0,r")
8008 (match_operand:SF 2 "s_register_operand" "r,0")))]
8009 "TARGET_ARM && TARGET_SOFT_FLOAT"
8013 [(set_attr "conds" "use")
8014 (set_attr "type" "mov_reg")]
8018 ;; Jump and linkage insns
8020 (define_expand "jump"
8022 (label_ref (match_operand 0 "" "")))]
8027 (define_insn "*arm_jump"
8029 (label_ref (match_operand 0 "" "")))]
8033 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
8035 arm_ccfsm_state += 2;
8038 return \"b%?\\t%l0\";
8041 [(set_attr "predicable" "yes")
8042 (set (attr "length")
8044 (and (match_test "TARGET_THUMB2")
8045 (and (ge (minus (match_dup 0) (pc)) (const_int -2044))
8046 (le (minus (match_dup 0) (pc)) (const_int 2048))))
8049 (set_attr "type" "branch")]
8052 (define_expand "call"
8053 [(parallel [(call (match_operand 0 "memory_operand" "")
8054 (match_operand 1 "general_operand" ""))
8055 (use (match_operand 2 "" ""))
8056 (clobber (reg:SI LR_REGNUM))])]
8061 tree addr = MEM_EXPR (operands[0]);
8063 /* In an untyped call, we can get NULL for operand 2. */
8064 if (operands[2] == NULL_RTX)
8065 operands[2] = const0_rtx;
8067 /* Decide if we should generate indirect calls by loading the
8068 32-bit address of the callee into a register before performing the
8070 callee = XEXP (operands[0], 0);
8071 if (GET_CODE (callee) == SYMBOL_REF
8072 ? arm_is_long_call_p (SYMBOL_REF_DECL (callee))
8074 XEXP (operands[0], 0) = force_reg (Pmode, callee);
8076 if (detect_cmse_nonsecure_call (addr))
8078 pat = gen_nonsecure_call_internal (operands[0], operands[1],
8080 emit_call_insn (pat);
8084 pat = gen_call_internal (operands[0], operands[1], operands[2]);
8085 arm_emit_call_insn (pat, XEXP (operands[0], 0), false);
8091 (define_expand "call_internal"
8092 [(parallel [(call (match_operand 0 "memory_operand" "")
8093 (match_operand 1 "general_operand" ""))
8094 (use (match_operand 2 "" ""))
8095 (clobber (reg:SI LR_REGNUM))])])
8097 (define_expand "nonsecure_call_internal"
8098 [(parallel [(call (unspec:SI [(match_operand 0 "memory_operand" "")]
8099 UNSPEC_NONSECURE_MEM)
8100 (match_operand 1 "general_operand" ""))
8101 (use (match_operand 2 "" ""))
8102 (clobber (reg:SI LR_REGNUM))
8103 (clobber (reg:SI 4))])]
8108 tmp = copy_to_suggested_reg (XEXP (operands[0], 0),
8109 gen_rtx_REG (SImode, 4),
8112 operands[0] = replace_equiv_address (operands[0], tmp);
8115 (define_insn "*call_reg_armv5"
8116 [(call (mem:SI (match_operand:SI 0 "s_register_operand" "r"))
8117 (match_operand 1 "" ""))
8118 (use (match_operand 2 "" ""))
8119 (clobber (reg:SI LR_REGNUM))]
8120 "TARGET_ARM && arm_arch5 && !SIBLING_CALL_P (insn)"
8122 [(set_attr "type" "call")]
8125 (define_insn "*call_reg_arm"
8126 [(call (mem:SI (match_operand:SI 0 "s_register_operand" "r"))
8127 (match_operand 1 "" ""))
8128 (use (match_operand 2 "" ""))
8129 (clobber (reg:SI LR_REGNUM))]
8130 "TARGET_ARM && !arm_arch5 && !SIBLING_CALL_P (insn)"
8132 return output_call (operands);
8134 ;; length is worst case, normally it is only two
8135 [(set_attr "length" "12")
8136 (set_attr "type" "call")]
8140 (define_expand "call_value"
8141 [(parallel [(set (match_operand 0 "" "")
8142 (call (match_operand 1 "memory_operand" "")
8143 (match_operand 2 "general_operand" "")))
8144 (use (match_operand 3 "" ""))
8145 (clobber (reg:SI LR_REGNUM))])]
8150 tree addr = MEM_EXPR (operands[1]);
8152 /* In an untyped call, we can get NULL for operand 2. */
8153 if (operands[3] == 0)
8154 operands[3] = const0_rtx;
8156 /* Decide if we should generate indirect calls by loading the
8157 32-bit address of the callee into a register before performing the
8159 callee = XEXP (operands[1], 0);
8160 if (GET_CODE (callee) == SYMBOL_REF
8161 ? arm_is_long_call_p (SYMBOL_REF_DECL (callee))
8163 XEXP (operands[1], 0) = force_reg (Pmode, callee);
8165 if (detect_cmse_nonsecure_call (addr))
8167 pat = gen_nonsecure_call_value_internal (operands[0], operands[1],
8168 operands[2], operands[3]);
8169 emit_call_insn (pat);
8173 pat = gen_call_value_internal (operands[0], operands[1],
8174 operands[2], operands[3]);
8175 arm_emit_call_insn (pat, XEXP (operands[1], 0), false);
8181 (define_expand "call_value_internal"
8182 [(parallel [(set (match_operand 0 "" "")
8183 (call (match_operand 1 "memory_operand" "")
8184 (match_operand 2 "general_operand" "")))
8185 (use (match_operand 3 "" ""))
8186 (clobber (reg:SI LR_REGNUM))])])
8188 (define_expand "nonsecure_call_value_internal"
8189 [(parallel [(set (match_operand 0 "" "")
8190 (call (unspec:SI [(match_operand 1 "memory_operand" "")]
8191 UNSPEC_NONSECURE_MEM)
8192 (match_operand 2 "general_operand" "")))
8193 (use (match_operand 3 "" ""))
8194 (clobber (reg:SI LR_REGNUM))
8195 (clobber (reg:SI 4))])]
8200 tmp = copy_to_suggested_reg (XEXP (operands[1], 0),
8201 gen_rtx_REG (SImode, 4),
8204 operands[1] = replace_equiv_address (operands[1], tmp);
8207 (define_insn "*call_value_reg_armv5"
8208 [(set (match_operand 0 "" "")
8209 (call (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
8210 (match_operand 2 "" "")))
8211 (use (match_operand 3 "" ""))
8212 (clobber (reg:SI LR_REGNUM))]
8213 "TARGET_ARM && arm_arch5 && !SIBLING_CALL_P (insn)"
8215 [(set_attr "type" "call")]
8218 (define_insn "*call_value_reg_arm"
8219 [(set (match_operand 0 "" "")
8220 (call (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
8221 (match_operand 2 "" "")))
8222 (use (match_operand 3 "" ""))
8223 (clobber (reg:SI LR_REGNUM))]
8224 "TARGET_ARM && !arm_arch5 && !SIBLING_CALL_P (insn)"
8226 return output_call (&operands[1]);
8228 [(set_attr "length" "12")
8229 (set_attr "type" "call")]
8232 ;; Allow calls to SYMBOL_REFs specially as they are not valid general addresses
8233 ;; The 'a' causes the operand to be treated as an address, i.e. no '#' output.
8235 (define_insn "*call_symbol"
8236 [(call (mem:SI (match_operand:SI 0 "" ""))
8237 (match_operand 1 "" ""))
8238 (use (match_operand 2 "" ""))
8239 (clobber (reg:SI LR_REGNUM))]
8241 && !SIBLING_CALL_P (insn)
8242 && (GET_CODE (operands[0]) == SYMBOL_REF)
8243 && !arm_is_long_call_p (SYMBOL_REF_DECL (operands[0]))"
8246 rtx op = operands[0];
8248 /* Switch mode now when possible. */
8249 if (SYMBOL_REF_DECL (op) && !TREE_PUBLIC (SYMBOL_REF_DECL (op))
8250 && arm_arch5 && arm_change_mode_p (SYMBOL_REF_DECL (op)))
8251 return NEED_PLT_RELOC ? \"blx%?\\t%a0(PLT)\" : \"blx%?\\t(%a0)\";
8253 return NEED_PLT_RELOC ? \"bl%?\\t%a0(PLT)\" : \"bl%?\\t%a0\";
8255 [(set_attr "type" "call")]
8258 (define_insn "*call_value_symbol"
8259 [(set (match_operand 0 "" "")
8260 (call (mem:SI (match_operand:SI 1 "" ""))
8261 (match_operand:SI 2 "" "")))
8262 (use (match_operand 3 "" ""))
8263 (clobber (reg:SI LR_REGNUM))]
8265 && !SIBLING_CALL_P (insn)
8266 && (GET_CODE (operands[1]) == SYMBOL_REF)
8267 && !arm_is_long_call_p (SYMBOL_REF_DECL (operands[1]))"
8270 rtx op = operands[1];
8272 /* Switch mode now when possible. */
8273 if (SYMBOL_REF_DECL (op) && !TREE_PUBLIC (SYMBOL_REF_DECL (op))
8274 && arm_arch5 && arm_change_mode_p (SYMBOL_REF_DECL (op)))
8275 return NEED_PLT_RELOC ? \"blx%?\\t%a1(PLT)\" : \"blx%?\\t(%a1)\";
8277 return NEED_PLT_RELOC ? \"bl%?\\t%a1(PLT)\" : \"bl%?\\t%a1\";
8279 [(set_attr "type" "call")]
8282 (define_expand "sibcall_internal"
8283 [(parallel [(call (match_operand 0 "memory_operand" "")
8284 (match_operand 1 "general_operand" ""))
8286 (use (match_operand 2 "" ""))])])
8288 ;; We may also be able to do sibcalls for Thumb, but it's much harder...
8289 (define_expand "sibcall"
8290 [(parallel [(call (match_operand 0 "memory_operand" "")
8291 (match_operand 1 "general_operand" ""))
8293 (use (match_operand 2 "" ""))])]
8299 if ((!REG_P (XEXP (operands[0], 0))
8300 && GET_CODE (XEXP (operands[0], 0)) != SYMBOL_REF)
8301 || (GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
8302 && arm_is_long_call_p (SYMBOL_REF_DECL (XEXP (operands[0], 0)))))
8303 XEXP (operands[0], 0) = force_reg (SImode, XEXP (operands[0], 0));
8305 if (operands[2] == NULL_RTX)
8306 operands[2] = const0_rtx;
8308 pat = gen_sibcall_internal (operands[0], operands[1], operands[2]);
8309 arm_emit_call_insn (pat, operands[0], true);
8314 (define_expand "sibcall_value_internal"
8315 [(parallel [(set (match_operand 0 "" "")
8316 (call (match_operand 1 "memory_operand" "")
8317 (match_operand 2 "general_operand" "")))
8319 (use (match_operand 3 "" ""))])])
8321 (define_expand "sibcall_value"
8322 [(parallel [(set (match_operand 0 "" "")
8323 (call (match_operand 1 "memory_operand" "")
8324 (match_operand 2 "general_operand" "")))
8326 (use (match_operand 3 "" ""))])]
8332 if ((!REG_P (XEXP (operands[1], 0))
8333 && GET_CODE (XEXP (operands[1], 0)) != SYMBOL_REF)
8334 || (GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
8335 && arm_is_long_call_p (SYMBOL_REF_DECL (XEXP (operands[1], 0)))))
8336 XEXP (operands[1], 0) = force_reg (SImode, XEXP (operands[1], 0));
8338 if (operands[3] == NULL_RTX)
8339 operands[3] = const0_rtx;
8341 pat = gen_sibcall_value_internal (operands[0], operands[1],
8342 operands[2], operands[3]);
8343 arm_emit_call_insn (pat, operands[1], true);
8348 (define_insn "*sibcall_insn"
8349 [(call (mem:SI (match_operand:SI 0 "call_insn_operand" "Cs, US"))
8350 (match_operand 1 "" ""))
8352 (use (match_operand 2 "" ""))]
8353 "TARGET_32BIT && SIBLING_CALL_P (insn)"
8355 if (which_alternative == 1)
8356 return NEED_PLT_RELOC ? \"b%?\\t%a0(PLT)\" : \"b%?\\t%a0\";
8359 if (arm_arch5 || arm_arch4t)
8360 return \"bx%?\\t%0\\t%@ indirect register sibling call\";
8362 return \"mov%?\\t%|pc, %0\\t%@ indirect register sibling call\";
8365 [(set_attr "type" "call")]
8368 (define_insn "*sibcall_value_insn"
8369 [(set (match_operand 0 "" "")
8370 (call (mem:SI (match_operand:SI 1 "call_insn_operand" "Cs,US"))
8371 (match_operand 2 "" "")))
8373 (use (match_operand 3 "" ""))]
8374 "TARGET_32BIT && SIBLING_CALL_P (insn)"
8376 if (which_alternative == 1)
8377 return NEED_PLT_RELOC ? \"b%?\\t%a1(PLT)\" : \"b%?\\t%a1\";
8380 if (arm_arch5 || arm_arch4t)
8381 return \"bx%?\\t%1\";
8383 return \"mov%?\\t%|pc, %1\\t@ indirect sibling call \";
8386 [(set_attr "type" "call")]
8389 (define_expand "<return_str>return"
8391 "(TARGET_ARM || (TARGET_THUMB2
8392 && ARM_FUNC_TYPE (arm_current_func_type ()) == ARM_FT_NORMAL
8393 && !IS_STACKALIGN (arm_current_func_type ())))
8394 <return_cond_false>"
8399 thumb2_expand_return (<return_simple_p>);
8406 ;; Often the return insn will be the same as loading from memory, so set attr
8407 (define_insn "*arm_return"
8409 "TARGET_ARM && USE_RETURN_INSN (FALSE)"
8412 if (arm_ccfsm_state == 2)
8414 arm_ccfsm_state += 2;
8417 return output_return_instruction (const_true_rtx, true, false, false);
8419 [(set_attr "type" "load1")
8420 (set_attr "length" "12")
8421 (set_attr "predicable" "yes")]
8424 (define_insn "*cond_<return_str>return"
8426 (if_then_else (match_operator 0 "arm_comparison_operator"
8427 [(match_operand 1 "cc_register" "") (const_int 0)])
8430 "TARGET_ARM <return_cond_true>"
8433 if (arm_ccfsm_state == 2)
8435 arm_ccfsm_state += 2;
8438 return output_return_instruction (operands[0], true, false,
8441 [(set_attr "conds" "use")
8442 (set_attr "length" "12")
8443 (set_attr "type" "load1")]
8446 (define_insn "*cond_<return_str>return_inverted"
8448 (if_then_else (match_operator 0 "arm_comparison_operator"
8449 [(match_operand 1 "cc_register" "") (const_int 0)])
8452 "TARGET_ARM <return_cond_true>"
8455 if (arm_ccfsm_state == 2)
8457 arm_ccfsm_state += 2;
8460 return output_return_instruction (operands[0], true, true,
8463 [(set_attr "conds" "use")
8464 (set_attr "length" "12")
8465 (set_attr "type" "load1")]
8468 (define_insn "*arm_simple_return"
8473 if (arm_ccfsm_state == 2)
8475 arm_ccfsm_state += 2;
8478 return output_return_instruction (const_true_rtx, true, false, true);
8480 [(set_attr "type" "branch")
8481 (set_attr "length" "4")
8482 (set_attr "predicable" "yes")]
8485 ;; Generate a sequence of instructions to determine if the processor is
8486 ;; in 26-bit or 32-bit mode, and return the appropriate return address
8489 (define_expand "return_addr_mask"
8491 (compare:CC_NOOV (unspec [(const_int 0)] UNSPEC_CHECK_ARCH)
8493 (set (match_operand:SI 0 "s_register_operand" "")
8494 (if_then_else:SI (eq (match_dup 1) (const_int 0))
8496 (const_int 67108860)))] ; 0x03fffffc
8499 operands[1] = gen_rtx_REG (CC_NOOVmode, CC_REGNUM);
8502 (define_insn "*check_arch2"
8503 [(set (match_operand:CC_NOOV 0 "cc_register" "")
8504 (compare:CC_NOOV (unspec [(const_int 0)] UNSPEC_CHECK_ARCH)
8507 "teq\\t%|r0, %|r0\;teq\\t%|pc, %|pc"
8508 [(set_attr "length" "8")
8509 (set_attr "conds" "set")
8510 (set_attr "type" "multiple")]
8513 ;; Call subroutine returning any type.
8515 (define_expand "untyped_call"
8516 [(parallel [(call (match_operand 0 "" "")
8518 (match_operand 1 "" "")
8519 (match_operand 2 "" "")])]
8524 rtx par = gen_rtx_PARALLEL (VOIDmode,
8525 rtvec_alloc (XVECLEN (operands[2], 0)));
8526 rtx addr = gen_reg_rtx (Pmode);
8530 emit_move_insn (addr, XEXP (operands[1], 0));
8531 mem = change_address (operands[1], BLKmode, addr);
8533 for (i = 0; i < XVECLEN (operands[2], 0); i++)
8535 rtx src = SET_SRC (XVECEXP (operands[2], 0, i));
8537 /* Default code only uses r0 as a return value, but we could
8538 be using anything up to 4 registers. */
8539 if (REGNO (src) == R0_REGNUM)
8540 src = gen_rtx_REG (TImode, R0_REGNUM);
8542 XVECEXP (par, 0, i) = gen_rtx_EXPR_LIST (VOIDmode, src,
8544 size += GET_MODE_SIZE (GET_MODE (src));
8547 emit_call_insn (gen_call_value (par, operands[0], const0_rtx, NULL));
8551 for (i = 0; i < XVECLEN (par, 0); i++)
8553 HOST_WIDE_INT offset = 0;
8554 rtx reg = XEXP (XVECEXP (par, 0, i), 0);
8557 emit_move_insn (addr, plus_constant (Pmode, addr, size));
8559 mem = change_address (mem, GET_MODE (reg), NULL);
8560 if (REGNO (reg) == R0_REGNUM)
8562 /* On thumb we have to use a write-back instruction. */
8563 emit_insn (arm_gen_store_multiple (arm_regs_in_sequence, 4, addr,
8564 TARGET_THUMB ? TRUE : FALSE, mem, &offset));
8565 size = TARGET_ARM ? 16 : 0;
8569 emit_move_insn (mem, reg);
8570 size = GET_MODE_SIZE (GET_MODE (reg));
8574 /* The optimizer does not know that the call sets the function value
8575 registers we stored in the result block. We avoid problems by
8576 claiming that all hard registers are used and clobbered at this
8578 emit_insn (gen_blockage ());
8584 (define_expand "untyped_return"
8585 [(match_operand:BLK 0 "memory_operand" "")
8586 (match_operand 1 "" "")]
8591 rtx addr = gen_reg_rtx (Pmode);
8595 emit_move_insn (addr, XEXP (operands[0], 0));
8596 mem = change_address (operands[0], BLKmode, addr);
8598 for (i = 0; i < XVECLEN (operands[1], 0); i++)
8600 HOST_WIDE_INT offset = 0;
8601 rtx reg = SET_DEST (XVECEXP (operands[1], 0, i));
8604 emit_move_insn (addr, plus_constant (Pmode, addr, size));
8606 mem = change_address (mem, GET_MODE (reg), NULL);
8607 if (REGNO (reg) == R0_REGNUM)
8609 /* On thumb we have to use a write-back instruction. */
8610 emit_insn (arm_gen_load_multiple (arm_regs_in_sequence, 4, addr,
8611 TARGET_THUMB ? TRUE : FALSE, mem, &offset));
8612 size = TARGET_ARM ? 16 : 0;
8616 emit_move_insn (reg, mem);
8617 size = GET_MODE_SIZE (GET_MODE (reg));
8621 /* Emit USE insns before the return. */
8622 for (i = 0; i < XVECLEN (operands[1], 0); i++)
8623 emit_use (SET_DEST (XVECEXP (operands[1], 0, i)));
8625 /* Construct the return. */
8626 expand_naked_return ();
8632 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
8633 ;; all of memory. This blocks insns from being moved across this point.
8635 (define_insn "blockage"
8636 [(unspec_volatile [(const_int 0)] VUNSPEC_BLOCKAGE)]
8639 [(set_attr "length" "0")
8640 (set_attr "type" "block")]
8643 (define_insn "probe_stack"
8644 [(set (match_operand:SI 0 "memory_operand" "=m")
8645 (unspec:SI [(const_int 0)] UNSPEC_PROBE_STACK))]
8648 [(set_attr "type" "store1")
8649 (set_attr "predicable" "yes")]
8652 (define_insn "probe_stack_range"
8653 [(set (match_operand:SI 0 "register_operand" "=r")
8654 (unspec_volatile:SI [(match_operand:SI 1 "register_operand" "0")
8655 (match_operand:SI 2 "register_operand" "r")]
8656 VUNSPEC_PROBE_STACK_RANGE))]
8659 return output_probe_stack_range (operands[0], operands[2]);
8661 [(set_attr "type" "multiple")
8662 (set_attr "conds" "clob")]
8665 (define_expand "casesi"
8666 [(match_operand:SI 0 "s_register_operand" "") ; index to jump on
8667 (match_operand:SI 1 "const_int_operand" "") ; lower bound
8668 (match_operand:SI 2 "const_int_operand" "") ; total range
8669 (match_operand:SI 3 "" "") ; table label
8670 (match_operand:SI 4 "" "")] ; Out of range label
8671 "(TARGET_32BIT || optimize_size || flag_pic) && !target_pure_code"
8674 enum insn_code code;
8675 if (operands[1] != const0_rtx)
8677 rtx reg = gen_reg_rtx (SImode);
8679 emit_insn (gen_addsi3 (reg, operands[0],
8680 gen_int_mode (-INTVAL (operands[1]),
8686 code = CODE_FOR_arm_casesi_internal;
8687 else if (TARGET_THUMB1)
8688 code = CODE_FOR_thumb1_casesi_internal_pic;
8690 code = CODE_FOR_thumb2_casesi_internal_pic;
8692 code = CODE_FOR_thumb2_casesi_internal;
8694 if (!insn_data[(int) code].operand[1].predicate(operands[2], SImode))
8695 operands[2] = force_reg (SImode, operands[2]);
8697 emit_jump_insn (GEN_FCN ((int) code) (operands[0], operands[2],
8698 operands[3], operands[4]));
8703 ;; The USE in this pattern is needed to tell flow analysis that this is
8704 ;; a CASESI insn. It has no other purpose.
8705 (define_insn "arm_casesi_internal"
8706 [(parallel [(set (pc)
8708 (leu (match_operand:SI 0 "s_register_operand" "r")
8709 (match_operand:SI 1 "arm_rhs_operand" "rI"))
8710 (mem:SI (plus:SI (mult:SI (match_dup 0) (const_int 4))
8711 (label_ref (match_operand 2 "" ""))))
8712 (label_ref (match_operand 3 "" ""))))
8713 (clobber (reg:CC CC_REGNUM))
8714 (use (label_ref (match_dup 2)))])]
8718 return \"cmp\\t%0, %1\;addls\\t%|pc, %|pc, %0, asl #2\;b\\t%l3\";
8719 return \"cmp\\t%0, %1\;ldrls\\t%|pc, [%|pc, %0, asl #2]\;b\\t%l3\";
8721 [(set_attr "conds" "clob")
8722 (set_attr "length" "12")
8723 (set_attr "type" "multiple")]
8726 (define_expand "indirect_jump"
8728 (match_operand:SI 0 "s_register_operand" ""))]
8731 /* Thumb-2 doesn't have mov pc, reg. Explicitly set the low bit of the
8732 address and use bx. */
8736 tmp = gen_reg_rtx (SImode);
8737 emit_insn (gen_iorsi3 (tmp, operands[0], GEN_INT(1)));
8743 ;; NB Never uses BX.
8744 (define_insn "*arm_indirect_jump"
8746 (match_operand:SI 0 "s_register_operand" "r"))]
8748 "mov%?\\t%|pc, %0\\t%@ indirect register jump"
8749 [(set_attr "predicable" "yes")
8750 (set_attr "type" "branch")]
8753 (define_insn "*load_indirect_jump"
8755 (match_operand:SI 0 "memory_operand" "m"))]
8757 "ldr%?\\t%|pc, %0\\t%@ indirect memory jump"
8758 [(set_attr "type" "load1")
8759 (set_attr "pool_range" "4096")
8760 (set_attr "neg_pool_range" "4084")
8761 (set_attr "predicable" "yes")]
8771 [(set (attr "length")
8772 (if_then_else (eq_attr "is_thumb" "yes")
8775 (set_attr "type" "mov_reg")]
8779 [(trap_if (const_int 1) (const_int 0))]
8783 return \".inst\\t0xe7f000f0\";
8785 return \".inst\\t0xdeff\";
8787 [(set (attr "length")
8788 (if_then_else (eq_attr "is_thumb" "yes")
8791 (set_attr "type" "trap")
8792 (set_attr "conds" "unconditional")]
8796 ;; Patterns to allow combination of arithmetic, cond code and shifts
8798 (define_insn "*<arith_shift_insn>_multsi"
8799 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8801 (mult:SI (match_operand:SI 2 "s_register_operand" "r,r")
8802 (match_operand:SI 3 "power_of_two_operand" ""))
8803 (match_operand:SI 1 "s_register_operand" "rk,<t2_binop0>")))]
8805 "<arith_shift_insn>%?\\t%0, %1, %2, lsl %b3"
8806 [(set_attr "predicable" "yes")
8807 (set_attr "predicable_short_it" "no")
8808 (set_attr "shift" "2")
8809 (set_attr "arch" "a,t2")
8810 (set_attr "type" "alu_shift_imm")])
8812 (define_insn "*<arith_shift_insn>_shiftsi"
8813 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
8815 (match_operator:SI 2 "shift_nomul_operator"
8816 [(match_operand:SI 3 "s_register_operand" "r,r,r")
8817 (match_operand:SI 4 "shift_amount_operand" "M,M,r")])
8818 (match_operand:SI 1 "s_register_operand" "rk,<t2_binop0>,rk")))]
8819 "TARGET_32BIT && GET_CODE (operands[2]) != MULT"
8820 "<arith_shift_insn>%?\\t%0, %1, %3%S2"
8821 [(set_attr "predicable" "yes")
8822 (set_attr "predicable_short_it" "no")
8823 (set_attr "shift" "3")
8824 (set_attr "arch" "a,t2,a")
8825 (set_attr "type" "alu_shift_imm,alu_shift_imm,alu_shift_reg")])
8828 [(set (match_operand:SI 0 "s_register_operand" "")
8829 (match_operator:SI 1 "shiftable_operator"
8830 [(match_operator:SI 2 "shiftable_operator"
8831 [(match_operator:SI 3 "shift_operator"
8832 [(match_operand:SI 4 "s_register_operand" "")
8833 (match_operand:SI 5 "reg_or_int_operand" "")])
8834 (match_operand:SI 6 "s_register_operand" "")])
8835 (match_operand:SI 7 "arm_rhs_operand" "")]))
8836 (clobber (match_operand:SI 8 "s_register_operand" ""))]
8839 (match_op_dup 2 [(match_op_dup 3 [(match_dup 4) (match_dup 5)])
8842 (match_op_dup 1 [(match_dup 8) (match_dup 7)]))]
8845 (define_insn "*arith_shiftsi_compare0"
8846 [(set (reg:CC_NOOV CC_REGNUM)
8848 (match_operator:SI 1 "shiftable_operator"
8849 [(match_operator:SI 3 "shift_operator"
8850 [(match_operand:SI 4 "s_register_operand" "r,r")
8851 (match_operand:SI 5 "shift_amount_operand" "M,r")])
8852 (match_operand:SI 2 "s_register_operand" "r,r")])
8854 (set (match_operand:SI 0 "s_register_operand" "=r,r")
8855 (match_op_dup 1 [(match_op_dup 3 [(match_dup 4) (match_dup 5)])
8858 "%i1s%?\\t%0, %2, %4%S3"
8859 [(set_attr "conds" "set")
8860 (set_attr "shift" "4")
8861 (set_attr "arch" "32,a")
8862 (set_attr "type" "alus_shift_imm,alus_shift_reg")])
8864 (define_insn "*arith_shiftsi_compare0_scratch"
8865 [(set (reg:CC_NOOV CC_REGNUM)
8867 (match_operator:SI 1 "shiftable_operator"
8868 [(match_operator:SI 3 "shift_operator"
8869 [(match_operand:SI 4 "s_register_operand" "r,r")
8870 (match_operand:SI 5 "shift_amount_operand" "M,r")])
8871 (match_operand:SI 2 "s_register_operand" "r,r")])
8873 (clobber (match_scratch:SI 0 "=r,r"))]
8875 "%i1s%?\\t%0, %2, %4%S3"
8876 [(set_attr "conds" "set")
8877 (set_attr "shift" "4")
8878 (set_attr "arch" "32,a")
8879 (set_attr "type" "alus_shift_imm,alus_shift_reg")])
8881 (define_insn "*sub_shiftsi"
8882 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8883 (minus:SI (match_operand:SI 1 "s_register_operand" "r,r")
8884 (match_operator:SI 2 "shift_operator"
8885 [(match_operand:SI 3 "s_register_operand" "r,r")
8886 (match_operand:SI 4 "shift_amount_operand" "M,r")])))]
8888 "sub%?\\t%0, %1, %3%S2"
8889 [(set_attr "predicable" "yes")
8890 (set_attr "shift" "3")
8891 (set_attr "arch" "32,a")
8892 (set_attr "type" "alus_shift_imm,alus_shift_reg")])
8894 (define_insn "*sub_shiftsi_compare0"
8895 [(set (reg:CC_NOOV CC_REGNUM)
8897 (minus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
8898 (match_operator:SI 2 "shift_operator"
8899 [(match_operand:SI 3 "s_register_operand" "r,r,r")
8900 (match_operand:SI 4 "shift_amount_operand" "M,r,M")]))
8902 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
8903 (minus:SI (match_dup 1)
8904 (match_op_dup 2 [(match_dup 3) (match_dup 4)])))]
8906 "subs%?\\t%0, %1, %3%S2"
8907 [(set_attr "conds" "set")
8908 (set_attr "shift" "3")
8909 (set_attr "arch" "32,a,a")
8910 (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
8912 (define_insn "*sub_shiftsi_compare0_scratch"
8913 [(set (reg:CC_NOOV CC_REGNUM)
8915 (minus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
8916 (match_operator:SI 2 "shift_operator"
8917 [(match_operand:SI 3 "s_register_operand" "r,r,r")
8918 (match_operand:SI 4 "shift_amount_operand" "M,r,M")]))
8920 (clobber (match_scratch:SI 0 "=r,r,r"))]
8922 "subs%?\\t%0, %1, %3%S2"
8923 [(set_attr "conds" "set")
8924 (set_attr "shift" "3")
8925 (set_attr "arch" "32,a,a")
8926 (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
8929 (define_insn_and_split "*and_scc"
8930 [(set (match_operand:SI 0 "s_register_operand" "=r")
8931 (and:SI (match_operator:SI 1 "arm_comparison_operator"
8932 [(match_operand 2 "cc_register" "") (const_int 0)])
8933 (match_operand:SI 3 "s_register_operand" "r")))]
8935 "#" ; "mov%D1\\t%0, #0\;and%d1\\t%0, %3, #1"
8936 "&& reload_completed"
8937 [(cond_exec (match_dup 5) (set (match_dup 0) (const_int 0)))
8938 (cond_exec (match_dup 4) (set (match_dup 0)
8939 (and:SI (match_dup 3) (const_int 1))))]
8941 machine_mode mode = GET_MODE (operands[2]);
8942 enum rtx_code rc = GET_CODE (operands[1]);
8944 /* Note that operands[4] is the same as operands[1],
8945 but with VOIDmode as the result. */
8946 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
8947 if (mode == CCFPmode || mode == CCFPEmode)
8948 rc = reverse_condition_maybe_unordered (rc);
8950 rc = reverse_condition (rc);
8951 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
8953 [(set_attr "conds" "use")
8954 (set_attr "type" "multiple")
8955 (set_attr "length" "8")]
8958 (define_insn_and_split "*ior_scc"
8959 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8960 (ior:SI (match_operator:SI 1 "arm_comparison_operator"
8961 [(match_operand 2 "cc_register" "") (const_int 0)])
8962 (match_operand:SI 3 "s_register_operand" "0,?r")))]
8967 "&& reload_completed
8968 && REGNO (operands [0]) != REGNO (operands[3])"
8969 ;; && which_alternative == 1
8970 ; mov%D1\\t%0, %3\;orr%d1\\t%0, %3, #1
8971 [(cond_exec (match_dup 5) (set (match_dup 0) (match_dup 3)))
8972 (cond_exec (match_dup 4) (set (match_dup 0)
8973 (ior:SI (match_dup 3) (const_int 1))))]
8975 machine_mode mode = GET_MODE (operands[2]);
8976 enum rtx_code rc = GET_CODE (operands[1]);
8978 /* Note that operands[4] is the same as operands[1],
8979 but with VOIDmode as the result. */
8980 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
8981 if (mode == CCFPmode || mode == CCFPEmode)
8982 rc = reverse_condition_maybe_unordered (rc);
8984 rc = reverse_condition (rc);
8985 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
8987 [(set_attr "conds" "use")
8988 (set_attr "length" "4,8")
8989 (set_attr "type" "logic_imm,multiple")]
8992 ; A series of splitters for the compare_scc pattern below. Note that
8993 ; order is important.
8995 [(set (match_operand:SI 0 "s_register_operand" "")
8996 (lt:SI (match_operand:SI 1 "s_register_operand" "")
8998 (clobber (reg:CC CC_REGNUM))]
8999 "TARGET_32BIT && reload_completed"
9000 [(set (match_dup 0) (lshiftrt:SI (match_dup 1) (const_int 31)))])
9003 [(set (match_operand:SI 0 "s_register_operand" "")
9004 (ge:SI (match_operand:SI 1 "s_register_operand" "")
9006 (clobber (reg:CC CC_REGNUM))]
9007 "TARGET_32BIT && reload_completed"
9008 [(set (match_dup 0) (not:SI (match_dup 1)))
9009 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 31)))])
9012 [(set (match_operand:SI 0 "s_register_operand" "")
9013 (eq:SI (match_operand:SI 1 "s_register_operand" "")
9015 (clobber (reg:CC CC_REGNUM))]
9016 "arm_arch5 && TARGET_32BIT"
9017 [(set (match_dup 0) (clz:SI (match_dup 1)))
9018 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
9022 [(set (match_operand:SI 0 "s_register_operand" "")
9023 (eq:SI (match_operand:SI 1 "s_register_operand" "")
9025 (clobber (reg:CC CC_REGNUM))]
9026 "TARGET_32BIT && reload_completed"
9028 [(set (reg:CC CC_REGNUM)
9029 (compare:CC (const_int 1) (match_dup 1)))
9031 (minus:SI (const_int 1) (match_dup 1)))])
9032 (cond_exec (ltu:CC (reg:CC CC_REGNUM) (const_int 0))
9033 (set (match_dup 0) (const_int 0)))])
9036 [(set (match_operand:SI 0 "s_register_operand" "")
9037 (ne:SI (match_operand:SI 1 "s_register_operand" "")
9038 (match_operand:SI 2 "const_int_operand" "")))
9039 (clobber (reg:CC CC_REGNUM))]
9040 "TARGET_32BIT && reload_completed"
9042 [(set (reg:CC CC_REGNUM)
9043 (compare:CC (match_dup 1) (match_dup 2)))
9044 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 3)))])
9045 (cond_exec (ne:CC (reg:CC CC_REGNUM) (const_int 0))
9046 (set (match_dup 0) (const_int 1)))]
9048 operands[3] = GEN_INT (-INTVAL (operands[2]));
9052 [(set (match_operand:SI 0 "s_register_operand" "")
9053 (ne:SI (match_operand:SI 1 "s_register_operand" "")
9054 (match_operand:SI 2 "arm_add_operand" "")))
9055 (clobber (reg:CC CC_REGNUM))]
9056 "TARGET_32BIT && reload_completed"
9058 [(set (reg:CC_NOOV CC_REGNUM)
9059 (compare:CC_NOOV (minus:SI (match_dup 1) (match_dup 2))
9061 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
9062 (cond_exec (ne:CC_NOOV (reg:CC_NOOV CC_REGNUM) (const_int 0))
9063 (set (match_dup 0) (const_int 1)))])
9065 (define_insn_and_split "*compare_scc"
9066 [(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts")
9067 (match_operator:SI 1 "arm_comparison_operator"
9068 [(match_operand:SI 2 "s_register_operand" "r,r")
9069 (match_operand:SI 3 "arm_add_operand" "rI,L")]))
9070 (clobber (reg:CC CC_REGNUM))]
9073 "&& reload_completed"
9074 [(set (reg:CC CC_REGNUM) (compare:CC (match_dup 2) (match_dup 3)))
9075 (cond_exec (match_dup 4) (set (match_dup 0) (const_int 0)))
9076 (cond_exec (match_dup 5) (set (match_dup 0) (const_int 1)))]
9079 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
9080 operands[2], operands[3]);
9081 enum rtx_code rc = GET_CODE (operands[1]);
9083 tmp1 = gen_rtx_REG (mode, CC_REGNUM);
9085 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, tmp1, const0_rtx);
9086 if (mode == CCFPmode || mode == CCFPEmode)
9087 rc = reverse_condition_maybe_unordered (rc);
9089 rc = reverse_condition (rc);
9090 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, tmp1, const0_rtx);
9092 [(set_attr "type" "multiple")]
9095 ;; Attempt to improve the sequence generated by the compare_scc splitters
9096 ;; not to use conditional execution.
9098 ;; Rd = (eq (reg1) (const_int0)) // ARMv5
9102 [(set (reg:CC CC_REGNUM)
9103 (compare:CC (match_operand:SI 1 "register_operand" "")
9105 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
9106 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
9107 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
9108 (set (match_dup 0) (const_int 1)))]
9109 "arm_arch5 && TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
9110 [(set (match_dup 0) (clz:SI (match_dup 1)))
9111 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
9114 ;; Rd = (eq (reg1) (const_int0)) // !ARMv5
9118 [(set (reg:CC CC_REGNUM)
9119 (compare:CC (match_operand:SI 1 "register_operand" "")
9121 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
9122 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
9123 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
9124 (set (match_dup 0) (const_int 1)))
9125 (match_scratch:SI 2 "r")]
9126 "TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
9128 [(set (reg:CC CC_REGNUM)
9129 (compare:CC (const_int 0) (match_dup 1)))
9130 (set (match_dup 2) (minus:SI (const_int 0) (match_dup 1)))])
9132 (plus:SI (plus:SI (match_dup 1) (match_dup 2))
9133 (geu:SI (reg:CC CC_REGNUM) (const_int 0))))]
9136 ;; Rd = (eq (reg1) (reg2/imm)) // ARMv5 and optimising for speed.
9137 ;; sub Rd, Reg1, reg2
9141 [(set (reg:CC CC_REGNUM)
9142 (compare:CC (match_operand:SI 1 "register_operand" "")
9143 (match_operand:SI 2 "arm_rhs_operand" "")))
9144 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
9145 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
9146 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
9147 (set (match_dup 0) (const_int 1)))]
9148 "arm_arch5 && TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)
9149 && !(TARGET_THUMB2 && optimize_insn_for_size_p ())"
9150 [(set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))
9151 (set (match_dup 0) (clz:SI (match_dup 0)))
9152 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
9156 ;; Rd = (eq (reg1) (reg2)) // ! ARMv5 or optimising for size.
9157 ;; sub T1, Reg1, reg2
9161 [(set (reg:CC CC_REGNUM)
9162 (compare:CC (match_operand:SI 1 "register_operand" "")
9163 (match_operand:SI 2 "arm_rhs_operand" "")))
9164 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
9165 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
9166 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
9167 (set (match_dup 0) (const_int 1)))
9168 (match_scratch:SI 3 "r")]
9169 "TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
9170 [(set (match_dup 3) (match_dup 4))
9172 [(set (reg:CC CC_REGNUM)
9173 (compare:CC (const_int 0) (match_dup 3)))
9174 (set (match_dup 0) (minus:SI (const_int 0) (match_dup 3)))])
9176 (plus:SI (plus:SI (match_dup 0) (match_dup 3))
9177 (geu:SI (reg:CC CC_REGNUM) (const_int 0))))]
9179 if (CONST_INT_P (operands[2]))
9180 operands[4] = plus_constant (SImode, operands[1], -INTVAL (operands[2]));
9182 operands[4] = gen_rtx_MINUS (SImode, operands[1], operands[2]);
9185 (define_insn "*cond_move"
9186 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9187 (if_then_else:SI (match_operator 3 "equality_operator"
9188 [(match_operator 4 "arm_comparison_operator"
9189 [(match_operand 5 "cc_register" "") (const_int 0)])
9191 (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
9192 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))]
9195 if (GET_CODE (operands[3]) == NE)
9197 if (which_alternative != 1)
9198 output_asm_insn (\"mov%D4\\t%0, %2\", operands);
9199 if (which_alternative != 0)
9200 output_asm_insn (\"mov%d4\\t%0, %1\", operands);
9203 if (which_alternative != 0)
9204 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
9205 if (which_alternative != 1)
9206 output_asm_insn (\"mov%d4\\t%0, %2\", operands);
9209 [(set_attr "conds" "use")
9210 (set_attr_alternative "type"
9211 [(if_then_else (match_operand 2 "const_int_operand" "")
9212 (const_string "mov_imm")
9213 (const_string "mov_reg"))
9214 (if_then_else (match_operand 1 "const_int_operand" "")
9215 (const_string "mov_imm")
9216 (const_string "mov_reg"))
9217 (const_string "multiple")])
9218 (set_attr "length" "4,4,8")]
9221 (define_insn "*cond_arith"
9222 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9223 (match_operator:SI 5 "shiftable_operator"
9224 [(match_operator:SI 4 "arm_comparison_operator"
9225 [(match_operand:SI 2 "s_register_operand" "r,r")
9226 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
9227 (match_operand:SI 1 "s_register_operand" "0,?r")]))
9228 (clobber (reg:CC CC_REGNUM))]
9231 if (GET_CODE (operands[4]) == LT && operands[3] == const0_rtx)
9232 return \"%i5\\t%0, %1, %2, lsr #31\";
9234 output_asm_insn (\"cmp\\t%2, %3\", operands);
9235 if (GET_CODE (operands[5]) == AND)
9236 output_asm_insn (\"mov%D4\\t%0, #0\", operands);
9237 else if (GET_CODE (operands[5]) == MINUS)
9238 output_asm_insn (\"rsb%D4\\t%0, %1, #0\", operands);
9239 else if (which_alternative != 0)
9240 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
9241 return \"%i5%d4\\t%0, %1, #1\";
9243 [(set_attr "conds" "clob")
9244 (set_attr "length" "12")
9245 (set_attr "type" "multiple")]
9248 (define_insn "*cond_sub"
9249 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9250 (minus:SI (match_operand:SI 1 "s_register_operand" "0,?r")
9251 (match_operator:SI 4 "arm_comparison_operator"
9252 [(match_operand:SI 2 "s_register_operand" "r,r")
9253 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
9254 (clobber (reg:CC CC_REGNUM))]
9257 output_asm_insn (\"cmp\\t%2, %3\", operands);
9258 if (which_alternative != 0)
9259 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
9260 return \"sub%d4\\t%0, %1, #1\";
9262 [(set_attr "conds" "clob")
9263 (set_attr "length" "8,12")
9264 (set_attr "type" "multiple")]
9267 (define_insn "*cmp_ite0"
9268 [(set (match_operand 6 "dominant_cc_register" "")
9271 (match_operator 4 "arm_comparison_operator"
9272 [(match_operand:SI 0 "s_register_operand"
9273 "l,l,l,r,r,r,r,r,r")
9274 (match_operand:SI 1 "arm_add_operand"
9275 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
9276 (match_operator:SI 5 "arm_comparison_operator"
9277 [(match_operand:SI 2 "s_register_operand"
9278 "l,r,r,l,l,r,r,r,r")
9279 (match_operand:SI 3 "arm_add_operand"
9280 "lPy,rI,L,lPy,lPy,rI,rI,L,L")])
9286 static const char * const cmp1[NUM_OF_COND_CMP][2] =
9288 {\"cmp%d5\\t%0, %1\",
9289 \"cmp%d4\\t%2, %3\"},
9290 {\"cmn%d5\\t%0, #%n1\",
9291 \"cmp%d4\\t%2, %3\"},
9292 {\"cmp%d5\\t%0, %1\",
9293 \"cmn%d4\\t%2, #%n3\"},
9294 {\"cmn%d5\\t%0, #%n1\",
9295 \"cmn%d4\\t%2, #%n3\"}
9297 static const char * const cmp2[NUM_OF_COND_CMP][2] =
9302 \"cmn\\t%0, #%n1\"},
9303 {\"cmn\\t%2, #%n3\",
9305 {\"cmn\\t%2, #%n3\",
9308 static const char * const ite[2] =
9313 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
9314 CMP_CMP, CMN_CMP, CMP_CMP,
9315 CMN_CMP, CMP_CMN, CMN_CMN};
9317 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
9319 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
9320 if (TARGET_THUMB2) {
9321 output_asm_insn (ite[swap], operands);
9323 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
9326 [(set_attr "conds" "set")
9327 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
9328 (set_attr "type" "multiple")
9329 (set_attr_alternative "length"
9335 (if_then_else (eq_attr "is_thumb" "no")
9338 (if_then_else (eq_attr "is_thumb" "no")
9341 (if_then_else (eq_attr "is_thumb" "no")
9344 (if_then_else (eq_attr "is_thumb" "no")
9349 (define_insn "*cmp_ite1"
9350 [(set (match_operand 6 "dominant_cc_register" "")
9353 (match_operator 4 "arm_comparison_operator"
9354 [(match_operand:SI 0 "s_register_operand"
9355 "l,l,l,r,r,r,r,r,r")
9356 (match_operand:SI 1 "arm_add_operand"
9357 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
9358 (match_operator:SI 5 "arm_comparison_operator"
9359 [(match_operand:SI 2 "s_register_operand"
9360 "l,r,r,l,l,r,r,r,r")
9361 (match_operand:SI 3 "arm_add_operand"
9362 "lPy,rI,L,lPy,lPy,rI,rI,L,L")])
9368 static const char * const cmp1[NUM_OF_COND_CMP][2] =
9372 {\"cmn\\t%0, #%n1\",
9375 \"cmn\\t%2, #%n3\"},
9376 {\"cmn\\t%0, #%n1\",
9379 static const char * const cmp2[NUM_OF_COND_CMP][2] =
9381 {\"cmp%d4\\t%2, %3\",
9382 \"cmp%D5\\t%0, %1\"},
9383 {\"cmp%d4\\t%2, %3\",
9384 \"cmn%D5\\t%0, #%n1\"},
9385 {\"cmn%d4\\t%2, #%n3\",
9386 \"cmp%D5\\t%0, %1\"},
9387 {\"cmn%d4\\t%2, #%n3\",
9388 \"cmn%D5\\t%0, #%n1\"}
9390 static const char * const ite[2] =
9395 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
9396 CMP_CMP, CMN_CMP, CMP_CMP,
9397 CMN_CMP, CMP_CMN, CMN_CMN};
9399 comparison_dominates_p (GET_CODE (operands[5]),
9400 reverse_condition (GET_CODE (operands[4])));
9402 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
9403 if (TARGET_THUMB2) {
9404 output_asm_insn (ite[swap], operands);
9406 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
9409 [(set_attr "conds" "set")
9410 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
9411 (set_attr_alternative "length"
9417 (if_then_else (eq_attr "is_thumb" "no")
9420 (if_then_else (eq_attr "is_thumb" "no")
9423 (if_then_else (eq_attr "is_thumb" "no")
9426 (if_then_else (eq_attr "is_thumb" "no")
9429 (set_attr "type" "multiple")]
9432 (define_insn "*cmp_and"
9433 [(set (match_operand 6 "dominant_cc_register" "")
9436 (match_operator 4 "arm_comparison_operator"
9437 [(match_operand:SI 0 "s_register_operand"
9438 "l,l,l,r,r,r,r,r,r")
9439 (match_operand:SI 1 "arm_add_operand"
9440 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
9441 (match_operator:SI 5 "arm_comparison_operator"
9442 [(match_operand:SI 2 "s_register_operand"
9443 "l,r,r,l,l,r,r,r,r")
9444 (match_operand:SI 3 "arm_add_operand"
9445 "lPy,rI,L,lPy,lPy,rI,rI,L,L")]))
9450 static const char *const cmp1[NUM_OF_COND_CMP][2] =
9452 {\"cmp%d5\\t%0, %1\",
9453 \"cmp%d4\\t%2, %3\"},
9454 {\"cmn%d5\\t%0, #%n1\",
9455 \"cmp%d4\\t%2, %3\"},
9456 {\"cmp%d5\\t%0, %1\",
9457 \"cmn%d4\\t%2, #%n3\"},
9458 {\"cmn%d5\\t%0, #%n1\",
9459 \"cmn%d4\\t%2, #%n3\"}
9461 static const char *const cmp2[NUM_OF_COND_CMP][2] =
9466 \"cmn\\t%0, #%n1\"},
9467 {\"cmn\\t%2, #%n3\",
9469 {\"cmn\\t%2, #%n3\",
9472 static const char *const ite[2] =
9477 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
9478 CMP_CMP, CMN_CMP, CMP_CMP,
9479 CMN_CMP, CMP_CMN, CMN_CMN};
9481 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
9483 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
9484 if (TARGET_THUMB2) {
9485 output_asm_insn (ite[swap], operands);
9487 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
9490 [(set_attr "conds" "set")
9491 (set_attr "predicable" "no")
9492 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
9493 (set_attr_alternative "length"
9499 (if_then_else (eq_attr "is_thumb" "no")
9502 (if_then_else (eq_attr "is_thumb" "no")
9505 (if_then_else (eq_attr "is_thumb" "no")
9508 (if_then_else (eq_attr "is_thumb" "no")
9511 (set_attr "type" "multiple")]
9514 (define_insn "*cmp_ior"
9515 [(set (match_operand 6 "dominant_cc_register" "")
9518 (match_operator 4 "arm_comparison_operator"
9519 [(match_operand:SI 0 "s_register_operand"
9520 "l,l,l,r,r,r,r,r,r")
9521 (match_operand:SI 1 "arm_add_operand"
9522 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
9523 (match_operator:SI 5 "arm_comparison_operator"
9524 [(match_operand:SI 2 "s_register_operand"
9525 "l,r,r,l,l,r,r,r,r")
9526 (match_operand:SI 3 "arm_add_operand"
9527 "lPy,rI,L,lPy,lPy,rI,rI,L,L")]))
9532 static const char *const cmp1[NUM_OF_COND_CMP][2] =
9536 {\"cmn\\t%0, #%n1\",
9539 \"cmn\\t%2, #%n3\"},
9540 {\"cmn\\t%0, #%n1\",
9543 static const char *const cmp2[NUM_OF_COND_CMP][2] =
9545 {\"cmp%D4\\t%2, %3\",
9546 \"cmp%D5\\t%0, %1\"},
9547 {\"cmp%D4\\t%2, %3\",
9548 \"cmn%D5\\t%0, #%n1\"},
9549 {\"cmn%D4\\t%2, #%n3\",
9550 \"cmp%D5\\t%0, %1\"},
9551 {\"cmn%D4\\t%2, #%n3\",
9552 \"cmn%D5\\t%0, #%n1\"}
9554 static const char *const ite[2] =
9559 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
9560 CMP_CMP, CMN_CMP, CMP_CMP,
9561 CMN_CMP, CMP_CMN, CMN_CMN};
9563 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
9565 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
9566 if (TARGET_THUMB2) {
9567 output_asm_insn (ite[swap], operands);
9569 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
9573 [(set_attr "conds" "set")
9574 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
9575 (set_attr_alternative "length"
9581 (if_then_else (eq_attr "is_thumb" "no")
9584 (if_then_else (eq_attr "is_thumb" "no")
9587 (if_then_else (eq_attr "is_thumb" "no")
9590 (if_then_else (eq_attr "is_thumb" "no")
9593 (set_attr "type" "multiple")]
9596 (define_insn_and_split "*ior_scc_scc"
9597 [(set (match_operand:SI 0 "s_register_operand" "=Ts")
9598 (ior:SI (match_operator:SI 3 "arm_comparison_operator"
9599 [(match_operand:SI 1 "s_register_operand" "r")
9600 (match_operand:SI 2 "arm_add_operand" "rIL")])
9601 (match_operator:SI 6 "arm_comparison_operator"
9602 [(match_operand:SI 4 "s_register_operand" "r")
9603 (match_operand:SI 5 "arm_add_operand" "rIL")])))
9604 (clobber (reg:CC CC_REGNUM))]
9606 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_OR_Y)
9609 "TARGET_32BIT && reload_completed"
9613 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9614 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9616 (set (match_dup 0) (ne:SI (match_dup 7) (const_int 0)))]
9618 = gen_rtx_REG (arm_select_dominance_cc_mode (operands[3], operands[6],
9621 [(set_attr "conds" "clob")
9622 (set_attr "length" "16")
9623 (set_attr "type" "multiple")]
9626 ; If the above pattern is followed by a CMP insn, then the compare is
9627 ; redundant, since we can rework the conditional instruction that follows.
9628 (define_insn_and_split "*ior_scc_scc_cmp"
9629 [(set (match_operand 0 "dominant_cc_register" "")
9630 (compare (ior:SI (match_operator:SI 3 "arm_comparison_operator"
9631 [(match_operand:SI 1 "s_register_operand" "r")
9632 (match_operand:SI 2 "arm_add_operand" "rIL")])
9633 (match_operator:SI 6 "arm_comparison_operator"
9634 [(match_operand:SI 4 "s_register_operand" "r")
9635 (match_operand:SI 5 "arm_add_operand" "rIL")]))
9637 (set (match_operand:SI 7 "s_register_operand" "=Ts")
9638 (ior:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9639 (match_op_dup 6 [(match_dup 4) (match_dup 5)])))]
9642 "TARGET_32BIT && reload_completed"
9646 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9647 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9649 (set (match_dup 7) (ne:SI (match_dup 0) (const_int 0)))]
9651 [(set_attr "conds" "set")
9652 (set_attr "length" "16")
9653 (set_attr "type" "multiple")]
9656 (define_insn_and_split "*and_scc_scc"
9657 [(set (match_operand:SI 0 "s_register_operand" "=Ts")
9658 (and:SI (match_operator:SI 3 "arm_comparison_operator"
9659 [(match_operand:SI 1 "s_register_operand" "r")
9660 (match_operand:SI 2 "arm_add_operand" "rIL")])
9661 (match_operator:SI 6 "arm_comparison_operator"
9662 [(match_operand:SI 4 "s_register_operand" "r")
9663 (match_operand:SI 5 "arm_add_operand" "rIL")])))
9664 (clobber (reg:CC CC_REGNUM))]
9666 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
9669 "TARGET_32BIT && reload_completed
9670 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
9675 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9676 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9678 (set (match_dup 0) (ne:SI (match_dup 7) (const_int 0)))]
9680 = gen_rtx_REG (arm_select_dominance_cc_mode (operands[3], operands[6],
9683 [(set_attr "conds" "clob")
9684 (set_attr "length" "16")
9685 (set_attr "type" "multiple")]
9688 ; If the above pattern is followed by a CMP insn, then the compare is
9689 ; redundant, since we can rework the conditional instruction that follows.
9690 (define_insn_and_split "*and_scc_scc_cmp"
9691 [(set (match_operand 0 "dominant_cc_register" "")
9692 (compare (and:SI (match_operator:SI 3 "arm_comparison_operator"
9693 [(match_operand:SI 1 "s_register_operand" "r")
9694 (match_operand:SI 2 "arm_add_operand" "rIL")])
9695 (match_operator:SI 6 "arm_comparison_operator"
9696 [(match_operand:SI 4 "s_register_operand" "r")
9697 (match_operand:SI 5 "arm_add_operand" "rIL")]))
9699 (set (match_operand:SI 7 "s_register_operand" "=Ts")
9700 (and:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9701 (match_op_dup 6 [(match_dup 4) (match_dup 5)])))]
9704 "TARGET_32BIT && reload_completed"
9708 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9709 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9711 (set (match_dup 7) (ne:SI (match_dup 0) (const_int 0)))]
9713 [(set_attr "conds" "set")
9714 (set_attr "length" "16")
9715 (set_attr "type" "multiple")]
9718 ;; If there is no dominance in the comparison, then we can still save an
9719 ;; instruction in the AND case, since we can know that the second compare
9720 ;; need only zero the value if false (if true, then the value is already
9722 (define_insn_and_split "*and_scc_scc_nodom"
9723 [(set (match_operand:SI 0 "s_register_operand" "=&Ts,&Ts,&Ts")
9724 (and:SI (match_operator:SI 3 "arm_comparison_operator"
9725 [(match_operand:SI 1 "s_register_operand" "r,r,0")
9726 (match_operand:SI 2 "arm_add_operand" "rIL,0,rIL")])
9727 (match_operator:SI 6 "arm_comparison_operator"
9728 [(match_operand:SI 4 "s_register_operand" "r,r,r")
9729 (match_operand:SI 5 "arm_add_operand" "rIL,rIL,rIL")])))
9730 (clobber (reg:CC CC_REGNUM))]
9732 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
9735 "TARGET_32BIT && reload_completed"
9736 [(parallel [(set (match_dup 0)
9737 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
9738 (clobber (reg:CC CC_REGNUM))])
9739 (set (match_dup 7) (match_op_dup 8 [(match_dup 4) (match_dup 5)]))
9741 (if_then_else:SI (match_op_dup 6 [(match_dup 7) (const_int 0)])
9744 "operands[7] = gen_rtx_REG (SELECT_CC_MODE (GET_CODE (operands[6]),
9745 operands[4], operands[5]),
9747 operands[8] = gen_rtx_COMPARE (GET_MODE (operands[7]), operands[4],
9749 [(set_attr "conds" "clob")
9750 (set_attr "length" "20")
9751 (set_attr "type" "multiple")]
9755 [(set (reg:CC_NOOV CC_REGNUM)
9756 (compare:CC_NOOV (ior:SI
9757 (and:SI (match_operand:SI 0 "s_register_operand" "")
9759 (match_operator:SI 1 "arm_comparison_operator"
9760 [(match_operand:SI 2 "s_register_operand" "")
9761 (match_operand:SI 3 "arm_add_operand" "")]))
9763 (clobber (match_operand:SI 4 "s_register_operand" ""))]
9766 (ior:SI (match_op_dup 1 [(match_dup 2) (match_dup 3)])
9768 (set (reg:CC_NOOV CC_REGNUM)
9769 (compare:CC_NOOV (and:SI (match_dup 4) (const_int 1))
9774 [(set (reg:CC_NOOV CC_REGNUM)
9775 (compare:CC_NOOV (ior:SI
9776 (match_operator:SI 1 "arm_comparison_operator"
9777 [(match_operand:SI 2 "s_register_operand" "")
9778 (match_operand:SI 3 "arm_add_operand" "")])
9779 (and:SI (match_operand:SI 0 "s_register_operand" "")
9782 (clobber (match_operand:SI 4 "s_register_operand" ""))]
9785 (ior:SI (match_op_dup 1 [(match_dup 2) (match_dup 3)])
9787 (set (reg:CC_NOOV CC_REGNUM)
9788 (compare:CC_NOOV (and:SI (match_dup 4) (const_int 1))
9791 ;; ??? The conditional patterns above need checking for Thumb-2 usefulness
9793 (define_insn_and_split "*negscc"
9794 [(set (match_operand:SI 0 "s_register_operand" "=r")
9795 (neg:SI (match_operator 3 "arm_comparison_operator"
9796 [(match_operand:SI 1 "s_register_operand" "r")
9797 (match_operand:SI 2 "arm_rhs_operand" "rI")])))
9798 (clobber (reg:CC CC_REGNUM))]
9801 "&& reload_completed"
9804 rtx cc_reg = gen_rtx_REG (CCmode, CC_REGNUM);
9806 if (GET_CODE (operands[3]) == LT && operands[2] == const0_rtx)
9808 /* Emit mov\\t%0, %1, asr #31 */
9809 emit_insn (gen_rtx_SET (operands[0],
9810 gen_rtx_ASHIFTRT (SImode,
9815 else if (GET_CODE (operands[3]) == NE)
9817 /* Emit subs\\t%0, %1, %2\;mvnne\\t%0, #0 */
9818 if (CONST_INT_P (operands[2]))
9819 emit_insn (gen_cmpsi2_addneg (operands[0], operands[1], operands[2],
9820 GEN_INT (- INTVAL (operands[2]))));
9822 emit_insn (gen_subsi3_compare (operands[0], operands[1], operands[2]));
9824 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
9828 gen_rtx_SET (operands[0],
9834 /* Emit: cmp\\t%1, %2\;mov%D3\\t%0, #0\;mvn%d3\\t%0, #0 */
9835 emit_insn (gen_rtx_SET (cc_reg,
9836 gen_rtx_COMPARE (CCmode, operands[1], operands[2])));
9837 enum rtx_code rc = GET_CODE (operands[3]);
9839 rc = reverse_condition (rc);
9840 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
9845 gen_rtx_SET (operands[0], const0_rtx)));
9846 rc = GET_CODE (operands[3]);
9847 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
9852 gen_rtx_SET (operands[0],
9858 [(set_attr "conds" "clob")
9859 (set_attr "length" "12")
9860 (set_attr "type" "multiple")]
9863 (define_insn_and_split "movcond_addsi"
9864 [(set (match_operand:SI 0 "s_register_operand" "=r,l,r")
9866 (match_operator 5 "comparison_operator"
9867 [(plus:SI (match_operand:SI 3 "s_register_operand" "r,r,r")
9868 (match_operand:SI 4 "arm_add_operand" "rIL,rIL,rIL"))
9870 (match_operand:SI 1 "arm_rhs_operand" "rI,rPy,r")
9871 (match_operand:SI 2 "arm_rhs_operand" "rI,rPy,r")))
9872 (clobber (reg:CC CC_REGNUM))]
9875 "&& reload_completed"
9876 [(set (reg:CC_NOOV CC_REGNUM)
9878 (plus:SI (match_dup 3)
9881 (set (match_dup 0) (match_dup 1))
9882 (cond_exec (match_dup 6)
9883 (set (match_dup 0) (match_dup 2)))]
9886 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[5]),
9887 operands[3], operands[4]);
9888 enum rtx_code rc = GET_CODE (operands[5]);
9889 operands[6] = gen_rtx_REG (mode, CC_REGNUM);
9890 gcc_assert (!(mode == CCFPmode || mode == CCFPEmode));
9891 if (!REG_P (operands[2]) || REGNO (operands[2]) != REGNO (operands[0]))
9892 rc = reverse_condition (rc);
9894 std::swap (operands[1], operands[2]);
9896 operands[6] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
9899 [(set_attr "conds" "clob")
9900 (set_attr "enabled_for_depr_it" "no,yes,yes")
9901 (set_attr "type" "multiple")]
9904 (define_insn "movcond"
9905 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9907 (match_operator 5 "arm_comparison_operator"
9908 [(match_operand:SI 3 "s_register_operand" "r,r,r")
9909 (match_operand:SI 4 "arm_add_operand" "rIL,rIL,rIL")])
9910 (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
9911 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
9912 (clobber (reg:CC CC_REGNUM))]
9915 if (GET_CODE (operands[5]) == LT
9916 && (operands[4] == const0_rtx))
9918 if (which_alternative != 1 && REG_P (operands[1]))
9920 if (operands[2] == const0_rtx)
9921 return \"and\\t%0, %1, %3, asr #31\";
9922 return \"ands\\t%0, %1, %3, asr #32\;movcc\\t%0, %2\";
9924 else if (which_alternative != 0 && REG_P (operands[2]))
9926 if (operands[1] == const0_rtx)
9927 return \"bic\\t%0, %2, %3, asr #31\";
9928 return \"bics\\t%0, %2, %3, asr #32\;movcs\\t%0, %1\";
9930 /* The only case that falls through to here is when both ops 1 & 2
9934 if (GET_CODE (operands[5]) == GE
9935 && (operands[4] == const0_rtx))
9937 if (which_alternative != 1 && REG_P (operands[1]))
9939 if (operands[2] == const0_rtx)
9940 return \"bic\\t%0, %1, %3, asr #31\";
9941 return \"bics\\t%0, %1, %3, asr #32\;movcs\\t%0, %2\";
9943 else if (which_alternative != 0 && REG_P (operands[2]))
9945 if (operands[1] == const0_rtx)
9946 return \"and\\t%0, %2, %3, asr #31\";
9947 return \"ands\\t%0, %2, %3, asr #32\;movcc\\t%0, %1\";
9949 /* The only case that falls through to here is when both ops 1 & 2
9952 if (CONST_INT_P (operands[4])
9953 && !const_ok_for_arm (INTVAL (operands[4])))
9954 output_asm_insn (\"cmn\\t%3, #%n4\", operands);
9956 output_asm_insn (\"cmp\\t%3, %4\", operands);
9957 if (which_alternative != 0)
9958 output_asm_insn (\"mov%d5\\t%0, %1\", operands);
9959 if (which_alternative != 1)
9960 output_asm_insn (\"mov%D5\\t%0, %2\", operands);
9963 [(set_attr "conds" "clob")
9964 (set_attr "length" "8,8,12")
9965 (set_attr "type" "multiple")]
9968 ;; ??? The patterns below need checking for Thumb-2 usefulness.
9970 (define_insn "*ifcompare_plus_move"
9971 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9972 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
9973 [(match_operand:SI 4 "s_register_operand" "r,r")
9974 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
9976 (match_operand:SI 2 "s_register_operand" "r,r")
9977 (match_operand:SI 3 "arm_add_operand" "rIL,rIL"))
9978 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))
9979 (clobber (reg:CC CC_REGNUM))]
9982 [(set_attr "conds" "clob")
9983 (set_attr "length" "8,12")
9984 (set_attr "type" "multiple")]
9987 (define_insn "*if_plus_move"
9988 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
9990 (match_operator 4 "arm_comparison_operator"
9991 [(match_operand 5 "cc_register" "") (const_int 0)])
9993 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
9994 (match_operand:SI 3 "arm_add_operand" "rI,L,rI,L"))
9995 (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")))]
9999 sub%d4\\t%0, %2, #%n3
10000 add%d4\\t%0, %2, %3\;mov%D4\\t%0, %1
10001 sub%d4\\t%0, %2, #%n3\;mov%D4\\t%0, %1"
10002 [(set_attr "conds" "use")
10003 (set_attr "length" "4,4,8,8")
10004 (set_attr_alternative "type"
10005 [(if_then_else (match_operand 3 "const_int_operand" "")
10006 (const_string "alu_imm" )
10007 (const_string "alu_sreg"))
10008 (const_string "alu_imm")
10009 (const_string "multiple")
10010 (const_string "multiple")])]
10013 (define_insn "*ifcompare_move_plus"
10014 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10015 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
10016 [(match_operand:SI 4 "s_register_operand" "r,r")
10017 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
10018 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
10020 (match_operand:SI 2 "s_register_operand" "r,r")
10021 (match_operand:SI 3 "arm_add_operand" "rIL,rIL"))))
10022 (clobber (reg:CC CC_REGNUM))]
10025 [(set_attr "conds" "clob")
10026 (set_attr "length" "8,12")
10027 (set_attr "type" "multiple")]
10030 (define_insn "*if_move_plus"
10031 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
10033 (match_operator 4 "arm_comparison_operator"
10034 [(match_operand 5 "cc_register" "") (const_int 0)])
10035 (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")
10037 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
10038 (match_operand:SI 3 "arm_add_operand" "rI,L,rI,L"))))]
10041 add%D4\\t%0, %2, %3
10042 sub%D4\\t%0, %2, #%n3
10043 add%D4\\t%0, %2, %3\;mov%d4\\t%0, %1
10044 sub%D4\\t%0, %2, #%n3\;mov%d4\\t%0, %1"
10045 [(set_attr "conds" "use")
10046 (set_attr "length" "4,4,8,8")
10047 (set_attr_alternative "type"
10048 [(if_then_else (match_operand 3 "const_int_operand" "")
10049 (const_string "alu_imm" )
10050 (const_string "alu_sreg"))
10051 (const_string "alu_imm")
10052 (const_string "multiple")
10053 (const_string "multiple")])]
10056 (define_insn "*ifcompare_arith_arith"
10057 [(set (match_operand:SI 0 "s_register_operand" "=r")
10058 (if_then_else:SI (match_operator 9 "arm_comparison_operator"
10059 [(match_operand:SI 5 "s_register_operand" "r")
10060 (match_operand:SI 6 "arm_add_operand" "rIL")])
10061 (match_operator:SI 8 "shiftable_operator"
10062 [(match_operand:SI 1 "s_register_operand" "r")
10063 (match_operand:SI 2 "arm_rhs_operand" "rI")])
10064 (match_operator:SI 7 "shiftable_operator"
10065 [(match_operand:SI 3 "s_register_operand" "r")
10066 (match_operand:SI 4 "arm_rhs_operand" "rI")])))
10067 (clobber (reg:CC CC_REGNUM))]
10070 [(set_attr "conds" "clob")
10071 (set_attr "length" "12")
10072 (set_attr "type" "multiple")]
10075 (define_insn "*if_arith_arith"
10076 [(set (match_operand:SI 0 "s_register_operand" "=r")
10077 (if_then_else:SI (match_operator 5 "arm_comparison_operator"
10078 [(match_operand 8 "cc_register" "") (const_int 0)])
10079 (match_operator:SI 6 "shiftable_operator"
10080 [(match_operand:SI 1 "s_register_operand" "r")
10081 (match_operand:SI 2 "arm_rhs_operand" "rI")])
10082 (match_operator:SI 7 "shiftable_operator"
10083 [(match_operand:SI 3 "s_register_operand" "r")
10084 (match_operand:SI 4 "arm_rhs_operand" "rI")])))]
10086 "%I6%d5\\t%0, %1, %2\;%I7%D5\\t%0, %3, %4"
10087 [(set_attr "conds" "use")
10088 (set_attr "length" "8")
10089 (set_attr "type" "multiple")]
10092 (define_insn "*ifcompare_arith_move"
10093 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10094 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
10095 [(match_operand:SI 2 "s_register_operand" "r,r")
10096 (match_operand:SI 3 "arm_add_operand" "rIL,rIL")])
10097 (match_operator:SI 7 "shiftable_operator"
10098 [(match_operand:SI 4 "s_register_operand" "r,r")
10099 (match_operand:SI 5 "arm_rhs_operand" "rI,rI")])
10100 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))
10101 (clobber (reg:CC CC_REGNUM))]
10104 /* If we have an operation where (op x 0) is the identity operation and
10105 the conditional operator is LT or GE and we are comparing against zero and
10106 everything is in registers then we can do this in two instructions. */
10107 if (operands[3] == const0_rtx
10108 && GET_CODE (operands[7]) != AND
10109 && REG_P (operands[5])
10110 && REG_P (operands[1])
10111 && REGNO (operands[1]) == REGNO (operands[4])
10112 && REGNO (operands[4]) != REGNO (operands[0]))
10114 if (GET_CODE (operands[6]) == LT)
10115 return \"and\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\";
10116 else if (GET_CODE (operands[6]) == GE)
10117 return \"bic\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\";
10119 if (CONST_INT_P (operands[3])
10120 && !const_ok_for_arm (INTVAL (operands[3])))
10121 output_asm_insn (\"cmn\\t%2, #%n3\", operands);
10123 output_asm_insn (\"cmp\\t%2, %3\", operands);
10124 output_asm_insn (\"%I7%d6\\t%0, %4, %5\", operands);
10125 if (which_alternative != 0)
10126 return \"mov%D6\\t%0, %1\";
10129 [(set_attr "conds" "clob")
10130 (set_attr "length" "8,12")
10131 (set_attr "type" "multiple")]
10134 (define_insn "*if_arith_move"
10135 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10136 (if_then_else:SI (match_operator 4 "arm_comparison_operator"
10137 [(match_operand 6 "cc_register" "") (const_int 0)])
10138 (match_operator:SI 5 "shiftable_operator"
10139 [(match_operand:SI 2 "s_register_operand" "r,r")
10140 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
10141 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))]
10144 %I5%d4\\t%0, %2, %3
10145 %I5%d4\\t%0, %2, %3\;mov%D4\\t%0, %1"
10146 [(set_attr "conds" "use")
10147 (set_attr "length" "4,8")
10148 (set_attr_alternative "type"
10149 [(if_then_else (match_operand 3 "const_int_operand" "")
10150 (const_string "alu_shift_imm" )
10151 (const_string "alu_shift_reg"))
10152 (const_string "multiple")])]
10155 (define_insn "*ifcompare_move_arith"
10156 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10157 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
10158 [(match_operand:SI 4 "s_register_operand" "r,r")
10159 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
10160 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
10161 (match_operator:SI 7 "shiftable_operator"
10162 [(match_operand:SI 2 "s_register_operand" "r,r")
10163 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
10164 (clobber (reg:CC CC_REGNUM))]
10167 /* If we have an operation where (op x 0) is the identity operation and
10168 the conditional operator is LT or GE and we are comparing against zero and
10169 everything is in registers then we can do this in two instructions */
10170 if (operands[5] == const0_rtx
10171 && GET_CODE (operands[7]) != AND
10172 && REG_P (operands[3])
10173 && REG_P (operands[1])
10174 && REGNO (operands[1]) == REGNO (operands[2])
10175 && REGNO (operands[2]) != REGNO (operands[0]))
10177 if (GET_CODE (operands[6]) == GE)
10178 return \"and\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\";
10179 else if (GET_CODE (operands[6]) == LT)
10180 return \"bic\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\";
10183 if (CONST_INT_P (operands[5])
10184 && !const_ok_for_arm (INTVAL (operands[5])))
10185 output_asm_insn (\"cmn\\t%4, #%n5\", operands);
10187 output_asm_insn (\"cmp\\t%4, %5\", operands);
10189 if (which_alternative != 0)
10190 output_asm_insn (\"mov%d6\\t%0, %1\", operands);
10191 return \"%I7%D6\\t%0, %2, %3\";
10193 [(set_attr "conds" "clob")
10194 (set_attr "length" "8,12")
10195 (set_attr "type" "multiple")]
10198 (define_insn "*if_move_arith"
10199 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10201 (match_operator 4 "arm_comparison_operator"
10202 [(match_operand 6 "cc_register" "") (const_int 0)])
10203 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
10204 (match_operator:SI 5 "shiftable_operator"
10205 [(match_operand:SI 2 "s_register_operand" "r,r")
10206 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))]
10209 %I5%D4\\t%0, %2, %3
10210 %I5%D4\\t%0, %2, %3\;mov%d4\\t%0, %1"
10211 [(set_attr "conds" "use")
10212 (set_attr "length" "4,8")
10213 (set_attr_alternative "type"
10214 [(if_then_else (match_operand 3 "const_int_operand" "")
10215 (const_string "alu_shift_imm" )
10216 (const_string "alu_shift_reg"))
10217 (const_string "multiple")])]
10220 (define_insn "*ifcompare_move_not"
10221 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10223 (match_operator 5 "arm_comparison_operator"
10224 [(match_operand:SI 3 "s_register_operand" "r,r")
10225 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
10226 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
10228 (match_operand:SI 2 "s_register_operand" "r,r"))))
10229 (clobber (reg:CC CC_REGNUM))]
10232 [(set_attr "conds" "clob")
10233 (set_attr "length" "8,12")
10234 (set_attr "type" "multiple")]
10237 (define_insn "*if_move_not"
10238 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
10240 (match_operator 4 "arm_comparison_operator"
10241 [(match_operand 3 "cc_register" "") (const_int 0)])
10242 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
10243 (not:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))))]
10247 mov%d4\\t%0, %1\;mvn%D4\\t%0, %2
10248 mvn%d4\\t%0, #%B1\;mvn%D4\\t%0, %2"
10249 [(set_attr "conds" "use")
10250 (set_attr "type" "mvn_reg")
10251 (set_attr "length" "4,8,8")
10252 (set_attr "type" "mvn_reg,multiple,multiple")]
10255 (define_insn "*ifcompare_not_move"
10256 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10258 (match_operator 5 "arm_comparison_operator"
10259 [(match_operand:SI 3 "s_register_operand" "r,r")
10260 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
10262 (match_operand:SI 2 "s_register_operand" "r,r"))
10263 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
10264 (clobber (reg:CC CC_REGNUM))]
10267 [(set_attr "conds" "clob")
10268 (set_attr "length" "8,12")
10269 (set_attr "type" "multiple")]
10272 (define_insn "*if_not_move"
10273 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
10275 (match_operator 4 "arm_comparison_operator"
10276 [(match_operand 3 "cc_register" "") (const_int 0)])
10277 (not:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))
10278 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
10282 mov%D4\\t%0, %1\;mvn%d4\\t%0, %2
10283 mvn%D4\\t%0, #%B1\;mvn%d4\\t%0, %2"
10284 [(set_attr "conds" "use")
10285 (set_attr "type" "mvn_reg,multiple,multiple")
10286 (set_attr "length" "4,8,8")]
10289 (define_insn "*ifcompare_shift_move"
10290 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10292 (match_operator 6 "arm_comparison_operator"
10293 [(match_operand:SI 4 "s_register_operand" "r,r")
10294 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
10295 (match_operator:SI 7 "shift_operator"
10296 [(match_operand:SI 2 "s_register_operand" "r,r")
10297 (match_operand:SI 3 "arm_rhs_operand" "rM,rM")])
10298 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
10299 (clobber (reg:CC CC_REGNUM))]
10302 [(set_attr "conds" "clob")
10303 (set_attr "length" "8,12")
10304 (set_attr "type" "multiple")]
10307 (define_insn "*if_shift_move"
10308 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
10310 (match_operator 5 "arm_comparison_operator"
10311 [(match_operand 6 "cc_register" "") (const_int 0)])
10312 (match_operator:SI 4 "shift_operator"
10313 [(match_operand:SI 2 "s_register_operand" "r,r,r")
10314 (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM")])
10315 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
10319 mov%D5\\t%0, %1\;mov%d5\\t%0, %2%S4
10320 mvn%D5\\t%0, #%B1\;mov%d5\\t%0, %2%S4"
10321 [(set_attr "conds" "use")
10322 (set_attr "shift" "2")
10323 (set_attr "length" "4,8,8")
10324 (set_attr_alternative "type"
10325 [(if_then_else (match_operand 3 "const_int_operand" "")
10326 (const_string "mov_shift" )
10327 (const_string "mov_shift_reg"))
10328 (const_string "multiple")
10329 (const_string "multiple")])]
10332 (define_insn "*ifcompare_move_shift"
10333 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10335 (match_operator 6 "arm_comparison_operator"
10336 [(match_operand:SI 4 "s_register_operand" "r,r")
10337 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
10338 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
10339 (match_operator:SI 7 "shift_operator"
10340 [(match_operand:SI 2 "s_register_operand" "r,r")
10341 (match_operand:SI 3 "arm_rhs_operand" "rM,rM")])))
10342 (clobber (reg:CC CC_REGNUM))]
10345 [(set_attr "conds" "clob")
10346 (set_attr "length" "8,12")
10347 (set_attr "type" "multiple")]
10350 (define_insn "*if_move_shift"
10351 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
10353 (match_operator 5 "arm_comparison_operator"
10354 [(match_operand 6 "cc_register" "") (const_int 0)])
10355 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
10356 (match_operator:SI 4 "shift_operator"
10357 [(match_operand:SI 2 "s_register_operand" "r,r,r")
10358 (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM")])))]
10362 mov%d5\\t%0, %1\;mov%D5\\t%0, %2%S4
10363 mvn%d5\\t%0, #%B1\;mov%D5\\t%0, %2%S4"
10364 [(set_attr "conds" "use")
10365 (set_attr "shift" "2")
10366 (set_attr "length" "4,8,8")
10367 (set_attr_alternative "type"
10368 [(if_then_else (match_operand 3 "const_int_operand" "")
10369 (const_string "mov_shift" )
10370 (const_string "mov_shift_reg"))
10371 (const_string "multiple")
10372 (const_string "multiple")])]
10375 (define_insn "*ifcompare_shift_shift"
10376 [(set (match_operand:SI 0 "s_register_operand" "=r")
10378 (match_operator 7 "arm_comparison_operator"
10379 [(match_operand:SI 5 "s_register_operand" "r")
10380 (match_operand:SI 6 "arm_add_operand" "rIL")])
10381 (match_operator:SI 8 "shift_operator"
10382 [(match_operand:SI 1 "s_register_operand" "r")
10383 (match_operand:SI 2 "arm_rhs_operand" "rM")])
10384 (match_operator:SI 9 "shift_operator"
10385 [(match_operand:SI 3 "s_register_operand" "r")
10386 (match_operand:SI 4 "arm_rhs_operand" "rM")])))
10387 (clobber (reg:CC CC_REGNUM))]
10390 [(set_attr "conds" "clob")
10391 (set_attr "length" "12")
10392 (set_attr "type" "multiple")]
10395 (define_insn "*if_shift_shift"
10396 [(set (match_operand:SI 0 "s_register_operand" "=r")
10398 (match_operator 5 "arm_comparison_operator"
10399 [(match_operand 8 "cc_register" "") (const_int 0)])
10400 (match_operator:SI 6 "shift_operator"
10401 [(match_operand:SI 1 "s_register_operand" "r")
10402 (match_operand:SI 2 "arm_rhs_operand" "rM")])
10403 (match_operator:SI 7 "shift_operator"
10404 [(match_operand:SI 3 "s_register_operand" "r")
10405 (match_operand:SI 4 "arm_rhs_operand" "rM")])))]
10407 "mov%d5\\t%0, %1%S6\;mov%D5\\t%0, %3%S7"
10408 [(set_attr "conds" "use")
10409 (set_attr "shift" "1")
10410 (set_attr "length" "8")
10411 (set (attr "type") (if_then_else
10412 (and (match_operand 2 "const_int_operand" "")
10413 (match_operand 4 "const_int_operand" ""))
10414 (const_string "mov_shift")
10415 (const_string "mov_shift_reg")))]
10418 (define_insn "*ifcompare_not_arith"
10419 [(set (match_operand:SI 0 "s_register_operand" "=r")
10421 (match_operator 6 "arm_comparison_operator"
10422 [(match_operand:SI 4 "s_register_operand" "r")
10423 (match_operand:SI 5 "arm_add_operand" "rIL")])
10424 (not:SI (match_operand:SI 1 "s_register_operand" "r"))
10425 (match_operator:SI 7 "shiftable_operator"
10426 [(match_operand:SI 2 "s_register_operand" "r")
10427 (match_operand:SI 3 "arm_rhs_operand" "rI")])))
10428 (clobber (reg:CC CC_REGNUM))]
10431 [(set_attr "conds" "clob")
10432 (set_attr "length" "12")
10433 (set_attr "type" "multiple")]
10436 (define_insn "*if_not_arith"
10437 [(set (match_operand:SI 0 "s_register_operand" "=r")
10439 (match_operator 5 "arm_comparison_operator"
10440 [(match_operand 4 "cc_register" "") (const_int 0)])
10441 (not:SI (match_operand:SI 1 "s_register_operand" "r"))
10442 (match_operator:SI 6 "shiftable_operator"
10443 [(match_operand:SI 2 "s_register_operand" "r")
10444 (match_operand:SI 3 "arm_rhs_operand" "rI")])))]
10446 "mvn%d5\\t%0, %1\;%I6%D5\\t%0, %2, %3"
10447 [(set_attr "conds" "use")
10448 (set_attr "type" "mvn_reg")
10449 (set_attr "length" "8")]
10452 (define_insn "*ifcompare_arith_not"
10453 [(set (match_operand:SI 0 "s_register_operand" "=r")
10455 (match_operator 6 "arm_comparison_operator"
10456 [(match_operand:SI 4 "s_register_operand" "r")
10457 (match_operand:SI 5 "arm_add_operand" "rIL")])
10458 (match_operator:SI 7 "shiftable_operator"
10459 [(match_operand:SI 2 "s_register_operand" "r")
10460 (match_operand:SI 3 "arm_rhs_operand" "rI")])
10461 (not:SI (match_operand:SI 1 "s_register_operand" "r"))))
10462 (clobber (reg:CC CC_REGNUM))]
10465 [(set_attr "conds" "clob")
10466 (set_attr "length" "12")
10467 (set_attr "type" "multiple")]
10470 (define_insn "*if_arith_not"
10471 [(set (match_operand:SI 0 "s_register_operand" "=r")
10473 (match_operator 5 "arm_comparison_operator"
10474 [(match_operand 4 "cc_register" "") (const_int 0)])
10475 (match_operator:SI 6 "shiftable_operator"
10476 [(match_operand:SI 2 "s_register_operand" "r")
10477 (match_operand:SI 3 "arm_rhs_operand" "rI")])
10478 (not:SI (match_operand:SI 1 "s_register_operand" "r"))))]
10480 "mvn%D5\\t%0, %1\;%I6%d5\\t%0, %2, %3"
10481 [(set_attr "conds" "use")
10482 (set_attr "type" "multiple")
10483 (set_attr "length" "8")]
10486 (define_insn "*ifcompare_neg_move"
10487 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10489 (match_operator 5 "arm_comparison_operator"
10490 [(match_operand:SI 3 "s_register_operand" "r,r")
10491 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
10492 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r"))
10493 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
10494 (clobber (reg:CC CC_REGNUM))]
10497 [(set_attr "conds" "clob")
10498 (set_attr "length" "8,12")
10499 (set_attr "type" "multiple")]
10502 (define_insn_and_split "*if_neg_move"
10503 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
10505 (match_operator 4 "arm_comparison_operator"
10506 [(match_operand 3 "cc_register" "") (const_int 0)])
10507 (neg:SI (match_operand:SI 2 "s_register_operand" "l,r"))
10508 (match_operand:SI 1 "s_register_operand" "0,0")))]
10511 "&& reload_completed"
10512 [(cond_exec (match_op_dup 4 [(match_dup 3) (const_int 0)])
10513 (set (match_dup 0) (neg:SI (match_dup 2))))]
10515 [(set_attr "conds" "use")
10516 (set_attr "length" "4")
10517 (set_attr "arch" "t2,32")
10518 (set_attr "enabled_for_depr_it" "yes,no")
10519 (set_attr "type" "logic_shift_imm")]
10522 (define_insn "*ifcompare_move_neg"
10523 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10525 (match_operator 5 "arm_comparison_operator"
10526 [(match_operand:SI 3 "s_register_operand" "r,r")
10527 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
10528 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
10529 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r"))))
10530 (clobber (reg:CC CC_REGNUM))]
10533 [(set_attr "conds" "clob")
10534 (set_attr "length" "8,12")
10535 (set_attr "type" "multiple")]
10538 (define_insn_and_split "*if_move_neg"
10539 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
10541 (match_operator 4 "arm_comparison_operator"
10542 [(match_operand 3 "cc_register" "") (const_int 0)])
10543 (match_operand:SI 1 "s_register_operand" "0,0")
10544 (neg:SI (match_operand:SI 2 "s_register_operand" "l,r"))))]
10547 "&& reload_completed"
10548 [(cond_exec (match_dup 5)
10549 (set (match_dup 0) (neg:SI (match_dup 2))))]
10551 machine_mode mode = GET_MODE (operands[3]);
10552 rtx_code rc = GET_CODE (operands[4]);
10554 if (mode == CCFPmode || mode == CCFPEmode)
10555 rc = reverse_condition_maybe_unordered (rc);
10557 rc = reverse_condition (rc);
10559 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[3], const0_rtx);
10561 [(set_attr "conds" "use")
10562 (set_attr "length" "4")
10563 (set_attr "arch" "t2,32")
10564 (set_attr "enabled_for_depr_it" "yes,no")
10565 (set_attr "type" "logic_shift_imm")]
10568 (define_insn "*arith_adjacentmem"
10569 [(set (match_operand:SI 0 "s_register_operand" "=r")
10570 (match_operator:SI 1 "shiftable_operator"
10571 [(match_operand:SI 2 "memory_operand" "m")
10572 (match_operand:SI 3 "memory_operand" "m")]))
10573 (clobber (match_scratch:SI 4 "=r"))]
10574 "TARGET_ARM && adjacent_mem_locations (operands[2], operands[3])"
10580 HOST_WIDE_INT val1 = 0, val2 = 0;
10582 if (REGNO (operands[0]) > REGNO (operands[4]))
10584 ldm[1] = operands[4];
10585 ldm[2] = operands[0];
10589 ldm[1] = operands[0];
10590 ldm[2] = operands[4];
10593 base_reg = XEXP (operands[2], 0);
10595 if (!REG_P (base_reg))
10597 val1 = INTVAL (XEXP (base_reg, 1));
10598 base_reg = XEXP (base_reg, 0);
10601 if (!REG_P (XEXP (operands[3], 0)))
10602 val2 = INTVAL (XEXP (XEXP (operands[3], 0), 1));
10604 arith[0] = operands[0];
10605 arith[3] = operands[1];
10619 if (val1 !=0 && val2 != 0)
10623 if (val1 == 4 || val2 == 4)
10624 /* Other val must be 8, since we know they are adjacent and neither
10626 output_asm_insn (\"ldmib%?\\t%0, {%1, %2}\", ldm);
10627 else if (const_ok_for_arm (val1) || const_ok_for_arm (-val1))
10629 ldm[0] = ops[0] = operands[4];
10631 ops[2] = GEN_INT (val1);
10632 output_add_immediate (ops);
10634 output_asm_insn (\"ldmia%?\\t%0, {%1, %2}\", ldm);
10636 output_asm_insn (\"ldmda%?\\t%0, {%1, %2}\", ldm);
10640 /* Offset is out of range for a single add, so use two ldr. */
10643 ops[2] = GEN_INT (val1);
10644 output_asm_insn (\"ldr%?\\t%0, [%1, %2]\", ops);
10646 ops[2] = GEN_INT (val2);
10647 output_asm_insn (\"ldr%?\\t%0, [%1, %2]\", ops);
10650 else if (val1 != 0)
10653 output_asm_insn (\"ldmda%?\\t%0, {%1, %2}\", ldm);
10655 output_asm_insn (\"ldmia%?\\t%0, {%1, %2}\", ldm);
10660 output_asm_insn (\"ldmia%?\\t%0, {%1, %2}\", ldm);
10662 output_asm_insn (\"ldmda%?\\t%0, {%1, %2}\", ldm);
10664 output_asm_insn (\"%I3%?\\t%0, %1, %2\", arith);
10667 [(set_attr "length" "12")
10668 (set_attr "predicable" "yes")
10669 (set_attr "type" "load1")]
10672 ; This pattern is never tried by combine, so do it as a peephole
10675 [(set (match_operand:SI 0 "arm_general_register_operand" "")
10676 (match_operand:SI 1 "arm_general_register_operand" ""))
10677 (set (reg:CC CC_REGNUM)
10678 (compare:CC (match_dup 1) (const_int 0)))]
10680 [(parallel [(set (reg:CC CC_REGNUM) (compare:CC (match_dup 1) (const_int 0)))
10681 (set (match_dup 0) (match_dup 1))])]
10686 [(set (match_operand:SI 0 "s_register_operand" "")
10687 (and:SI (ge:SI (match_operand:SI 1 "s_register_operand" "")
10689 (neg:SI (match_operator:SI 2 "arm_comparison_operator"
10690 [(match_operand:SI 3 "s_register_operand" "")
10691 (match_operand:SI 4 "arm_rhs_operand" "")]))))
10692 (clobber (match_operand:SI 5 "s_register_operand" ""))]
10694 [(set (match_dup 5) (not:SI (ashiftrt:SI (match_dup 1) (const_int 31))))
10695 (set (match_dup 0) (and:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
10700 ;; This split can be used because CC_Z mode implies that the following
10701 ;; branch will be an equality, or an unsigned inequality, so the sign
10702 ;; extension is not needed.
10705 [(set (reg:CC_Z CC_REGNUM)
10707 (ashift:SI (subreg:SI (match_operand:QI 0 "memory_operand" "") 0)
10709 (match_operand 1 "const_int_operand" "")))
10710 (clobber (match_scratch:SI 2 ""))]
10712 && ((UINTVAL (operands[1]))
10713 == ((UINTVAL (operands[1])) >> 24) << 24)"
10714 [(set (match_dup 2) (zero_extend:SI (match_dup 0)))
10715 (set (reg:CC CC_REGNUM) (compare:CC (match_dup 2) (match_dup 1)))]
10717 operands[1] = GEN_INT (((unsigned long) INTVAL (operands[1])) >> 24);
10720 ;; ??? Check the patterns above for Thumb-2 usefulness
10722 (define_expand "prologue"
10723 [(clobber (const_int 0))]
10726 arm_expand_prologue ();
10728 thumb1_expand_prologue ();
10733 (define_expand "epilogue"
10734 [(clobber (const_int 0))]
10737 if (crtl->calls_eh_return)
10738 emit_insn (gen_force_register_use (gen_rtx_REG (Pmode, 2)));
10741 thumb1_expand_epilogue ();
10742 emit_jump_insn (gen_rtx_UNSPEC_VOLATILE (VOIDmode,
10743 gen_rtvec (1, ret_rtx), VUNSPEC_EPILOGUE));
10745 else if (HAVE_return)
10747 /* HAVE_return is testing for USE_RETURN_INSN (FALSE). Hence,
10748 no need for explicit testing again. */
10749 emit_jump_insn (gen_return ());
10751 else if (TARGET_32BIT)
10753 arm_expand_epilogue (true);
10759 ;; Note - although unspec_volatile's USE all hard registers,
10760 ;; USEs are ignored after relaod has completed. Thus we need
10761 ;; to add an unspec of the link register to ensure that flow
10762 ;; does not think that it is unused by the sibcall branch that
10763 ;; will replace the standard function epilogue.
10764 (define_expand "sibcall_epilogue"
10765 [(parallel [(unspec:SI [(reg:SI LR_REGNUM)] UNSPEC_REGISTER_USE)
10766 (unspec_volatile [(return)] VUNSPEC_EPILOGUE)])]
10769 arm_expand_epilogue (false);
10774 (define_expand "eh_epilogue"
10775 [(use (match_operand:SI 0 "register_operand" ""))
10776 (use (match_operand:SI 1 "register_operand" ""))
10777 (use (match_operand:SI 2 "register_operand" ""))]
10781 cfun->machine->eh_epilogue_sp_ofs = operands[1];
10782 if (!REG_P (operands[2]) || REGNO (operands[2]) != 2)
10784 rtx ra = gen_rtx_REG (Pmode, 2);
10786 emit_move_insn (ra, operands[2]);
10789 /* This is a hack -- we may have crystalized the function type too
10791 cfun->machine->func_type = 0;
10795 ;; This split is only used during output to reduce the number of patterns
10796 ;; that need assembler instructions adding to them. We allowed the setting
10797 ;; of the conditions to be implicit during rtl generation so that
10798 ;; the conditional compare patterns would work. However this conflicts to
10799 ;; some extent with the conditional data operations, so we have to split them
10802 ;; ??? Need to audit these splitters for Thumb-2. Why isn't normal
10803 ;; conditional execution sufficient?
10806 [(set (match_operand:SI 0 "s_register_operand" "")
10807 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10808 [(match_operand 2 "" "") (match_operand 3 "" "")])
10810 (match_operand 4 "" "")))
10811 (clobber (reg:CC CC_REGNUM))]
10812 "TARGET_ARM && reload_completed"
10813 [(set (match_dup 5) (match_dup 6))
10814 (cond_exec (match_dup 7)
10815 (set (match_dup 0) (match_dup 4)))]
10818 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10819 operands[2], operands[3]);
10820 enum rtx_code rc = GET_CODE (operands[1]);
10822 operands[5] = gen_rtx_REG (mode, CC_REGNUM);
10823 operands[6] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10824 if (mode == CCFPmode || mode == CCFPEmode)
10825 rc = reverse_condition_maybe_unordered (rc);
10827 rc = reverse_condition (rc);
10829 operands[7] = gen_rtx_fmt_ee (rc, VOIDmode, operands[5], const0_rtx);
10834 [(set (match_operand:SI 0 "s_register_operand" "")
10835 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10836 [(match_operand 2 "" "") (match_operand 3 "" "")])
10837 (match_operand 4 "" "")
10839 (clobber (reg:CC CC_REGNUM))]
10840 "TARGET_ARM && reload_completed"
10841 [(set (match_dup 5) (match_dup 6))
10842 (cond_exec (match_op_dup 1 [(match_dup 5) (const_int 0)])
10843 (set (match_dup 0) (match_dup 4)))]
10846 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10847 operands[2], operands[3]);
10849 operands[5] = gen_rtx_REG (mode, CC_REGNUM);
10850 operands[6] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10855 [(set (match_operand:SI 0 "s_register_operand" "")
10856 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10857 [(match_operand 2 "" "") (match_operand 3 "" "")])
10858 (match_operand 4 "" "")
10859 (match_operand 5 "" "")))
10860 (clobber (reg:CC CC_REGNUM))]
10861 "TARGET_ARM && reload_completed"
10862 [(set (match_dup 6) (match_dup 7))
10863 (cond_exec (match_op_dup 1 [(match_dup 6) (const_int 0)])
10864 (set (match_dup 0) (match_dup 4)))
10865 (cond_exec (match_dup 8)
10866 (set (match_dup 0) (match_dup 5)))]
10869 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10870 operands[2], operands[3]);
10871 enum rtx_code rc = GET_CODE (operands[1]);
10873 operands[6] = gen_rtx_REG (mode, CC_REGNUM);
10874 operands[7] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10875 if (mode == CCFPmode || mode == CCFPEmode)
10876 rc = reverse_condition_maybe_unordered (rc);
10878 rc = reverse_condition (rc);
10880 operands[8] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
10885 [(set (match_operand:SI 0 "s_register_operand" "")
10886 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10887 [(match_operand:SI 2 "s_register_operand" "")
10888 (match_operand:SI 3 "arm_add_operand" "")])
10889 (match_operand:SI 4 "arm_rhs_operand" "")
10891 (match_operand:SI 5 "s_register_operand" ""))))
10892 (clobber (reg:CC CC_REGNUM))]
10893 "TARGET_ARM && reload_completed"
10894 [(set (match_dup 6) (match_dup 7))
10895 (cond_exec (match_op_dup 1 [(match_dup 6) (const_int 0)])
10896 (set (match_dup 0) (match_dup 4)))
10897 (cond_exec (match_dup 8)
10898 (set (match_dup 0) (not:SI (match_dup 5))))]
10901 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10902 operands[2], operands[3]);
10903 enum rtx_code rc = GET_CODE (operands[1]);
10905 operands[6] = gen_rtx_REG (mode, CC_REGNUM);
10906 operands[7] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10907 if (mode == CCFPmode || mode == CCFPEmode)
10908 rc = reverse_condition_maybe_unordered (rc);
10910 rc = reverse_condition (rc);
10912 operands[8] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
10916 (define_insn "*cond_move_not"
10917 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10918 (if_then_else:SI (match_operator 4 "arm_comparison_operator"
10919 [(match_operand 3 "cc_register" "") (const_int 0)])
10920 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
10922 (match_operand:SI 2 "s_register_operand" "r,r"))))]
10926 mov%d4\\t%0, %1\;mvn%D4\\t%0, %2"
10927 [(set_attr "conds" "use")
10928 (set_attr "type" "mvn_reg,multiple")
10929 (set_attr "length" "4,8")]
10932 ;; The next two patterns occur when an AND operation is followed by a
10933 ;; scc insn sequence
10935 (define_insn "*sign_extract_onebit"
10936 [(set (match_operand:SI 0 "s_register_operand" "=r")
10937 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
10939 (match_operand:SI 2 "const_int_operand" "n")))
10940 (clobber (reg:CC CC_REGNUM))]
10943 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
10944 output_asm_insn (\"ands\\t%0, %1, %2\", operands);
10945 return \"mvnne\\t%0, #0\";
10947 [(set_attr "conds" "clob")
10948 (set_attr "length" "8")
10949 (set_attr "type" "multiple")]
10952 (define_insn "*not_signextract_onebit"
10953 [(set (match_operand:SI 0 "s_register_operand" "=r")
10955 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
10957 (match_operand:SI 2 "const_int_operand" "n"))))
10958 (clobber (reg:CC CC_REGNUM))]
10961 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
10962 output_asm_insn (\"tst\\t%1, %2\", operands);
10963 output_asm_insn (\"mvneq\\t%0, #0\", operands);
10964 return \"movne\\t%0, #0\";
10966 [(set_attr "conds" "clob")
10967 (set_attr "length" "12")
10968 (set_attr "type" "multiple")]
10970 ;; ??? The above patterns need auditing for Thumb-2
10972 ;; Push multiple registers to the stack. Registers are in parallel (use ...)
10973 ;; expressions. For simplicity, the first register is also in the unspec
10975 ;; To avoid the usage of GNU extension, the length attribute is computed
10976 ;; in a C function arm_attr_length_push_multi.
10977 (define_insn "*push_multi"
10978 [(match_parallel 2 "multi_register_push"
10979 [(set (match_operand:BLK 0 "push_mult_memory_operand" "")
10980 (unspec:BLK [(match_operand:SI 1 "s_register_operand" "")]
10981 UNSPEC_PUSH_MULT))])]
10985 int num_saves = XVECLEN (operands[2], 0);
10987 /* For the StrongARM at least it is faster to
10988 use STR to store only a single register.
10989 In Thumb mode always use push, and the assembler will pick
10990 something appropriate. */
10991 if (num_saves == 1 && TARGET_ARM)
10992 output_asm_insn (\"str%?\\t%1, [%m0, #-4]!\", operands);
10999 strcpy (pattern, \"push%?\\t{%1\");
11001 strcpy (pattern, \"push\\t{%1\");
11003 for (i = 1; i < num_saves; i++)
11005 strcat (pattern, \", %|\");
11007 reg_names[REGNO (XEXP (XVECEXP (operands[2], 0, i), 0))]);
11010 strcat (pattern, \"}\");
11011 output_asm_insn (pattern, operands);
11016 [(set_attr "type" "store4")
11017 (set (attr "length")
11018 (symbol_ref "arm_attr_length_push_multi (operands[2], operands[1])"))]
11021 (define_insn "stack_tie"
11022 [(set (mem:BLK (scratch))
11023 (unspec:BLK [(match_operand:SI 0 "s_register_operand" "rk")
11024 (match_operand:SI 1 "s_register_operand" "rk")]
11028 [(set_attr "length" "0")
11029 (set_attr "type" "block")]
11032 ;; Pop (as used in epilogue RTL)
11034 (define_insn "*load_multiple_with_writeback"
11035 [(match_parallel 0 "load_multiple_operation"
11036 [(set (match_operand:SI 1 "s_register_operand" "+rk")
11037 (plus:SI (match_dup 1)
11038 (match_operand:SI 2 "const_int_I_operand" "I")))
11039 (set (match_operand:SI 3 "s_register_operand" "=rk")
11040 (mem:SI (match_dup 1)))
11042 "TARGET_32BIT && (reload_in_progress || reload_completed)"
11045 arm_output_multireg_pop (operands, /*return_pc=*/false,
11046 /*cond=*/const_true_rtx,
11052 [(set_attr "type" "load4")
11053 (set_attr "predicable" "yes")
11054 (set (attr "length")
11055 (symbol_ref "arm_attr_length_pop_multi (operands,
11056 /*return_pc=*/false,
11057 /*write_back_p=*/true)"))]
11060 ;; Pop with return (as used in epilogue RTL)
11062 ;; This instruction is generated when the registers are popped at the end of
11063 ;; epilogue. Here, instead of popping the value into LR and then generating
11064 ;; jump to LR, value is popped into PC directly. Hence, the pattern is combined
11066 (define_insn "*pop_multiple_with_writeback_and_return"
11067 [(match_parallel 0 "pop_multiple_return"
11069 (set (match_operand:SI 1 "s_register_operand" "+rk")
11070 (plus:SI (match_dup 1)
11071 (match_operand:SI 2 "const_int_I_operand" "I")))
11072 (set (match_operand:SI 3 "s_register_operand" "=rk")
11073 (mem:SI (match_dup 1)))
11075 "TARGET_32BIT && (reload_in_progress || reload_completed)"
11078 arm_output_multireg_pop (operands, /*return_pc=*/true,
11079 /*cond=*/const_true_rtx,
11085 [(set_attr "type" "load4")
11086 (set_attr "predicable" "yes")
11087 (set (attr "length")
11088 (symbol_ref "arm_attr_length_pop_multi (operands, /*return_pc=*/true,
11089 /*write_back_p=*/true)"))]
11092 (define_insn "*pop_multiple_with_return"
11093 [(match_parallel 0 "pop_multiple_return"
11095 (set (match_operand:SI 2 "s_register_operand" "=rk")
11096 (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
11098 "TARGET_32BIT && (reload_in_progress || reload_completed)"
11101 arm_output_multireg_pop (operands, /*return_pc=*/true,
11102 /*cond=*/const_true_rtx,
11108 [(set_attr "type" "load4")
11109 (set_attr "predicable" "yes")
11110 (set (attr "length")
11111 (symbol_ref "arm_attr_length_pop_multi (operands, /*return_pc=*/true,
11112 /*write_back_p=*/false)"))]
11115 ;; Load into PC and return
11116 (define_insn "*ldr_with_return"
11118 (set (reg:SI PC_REGNUM)
11119 (mem:SI (post_inc:SI (match_operand:SI 0 "s_register_operand" "+rk"))))]
11120 "TARGET_32BIT && (reload_in_progress || reload_completed)"
11121 "ldr%?\t%|pc, [%0], #4"
11122 [(set_attr "type" "load1")
11123 (set_attr "predicable" "yes")]
11125 ;; Pop for floating point registers (as used in epilogue RTL)
11126 (define_insn "*vfp_pop_multiple_with_writeback"
11127 [(match_parallel 0 "pop_multiple_fp"
11128 [(set (match_operand:SI 1 "s_register_operand" "+rk")
11129 (plus:SI (match_dup 1)
11130 (match_operand:SI 2 "const_int_I_operand" "I")))
11131 (set (match_operand:DF 3 "vfp_hard_register_operand" "")
11132 (mem:DF (match_dup 1)))])]
11133 "TARGET_32BIT && TARGET_HARD_FLOAT"
11136 int num_regs = XVECLEN (operands[0], 0);
11139 strcpy (pattern, \"vldm\\t\");
11140 strcat (pattern, reg_names[REGNO (SET_DEST (XVECEXP (operands[0], 0, 0)))]);
11141 strcat (pattern, \"!, {\");
11142 op_list[0] = XEXP (XVECEXP (operands[0], 0, 1), 0);
11143 strcat (pattern, \"%P0\");
11144 if ((num_regs - 1) > 1)
11146 strcat (pattern, \"-%P1\");
11147 op_list [1] = XEXP (XVECEXP (operands[0], 0, num_regs - 1), 0);
11150 strcat (pattern, \"}\");
11151 output_asm_insn (pattern, op_list);
11155 [(set_attr "type" "load4")
11156 (set_attr "conds" "unconditional")
11157 (set_attr "predicable" "no")]
11160 ;; Special patterns for dealing with the constant pool
11162 (define_insn "align_4"
11163 [(unspec_volatile [(const_int 0)] VUNSPEC_ALIGN)]
11166 assemble_align (32);
11169 [(set_attr "type" "no_insn")]
11172 (define_insn "align_8"
11173 [(unspec_volatile [(const_int 0)] VUNSPEC_ALIGN8)]
11176 assemble_align (64);
11179 [(set_attr "type" "no_insn")]
11182 (define_insn "consttable_end"
11183 [(unspec_volatile [(const_int 0)] VUNSPEC_POOL_END)]
11186 making_const_table = FALSE;
11189 [(set_attr "type" "no_insn")]
11192 (define_insn "consttable_1"
11193 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_1)]
11196 making_const_table = TRUE;
11197 assemble_integer (operands[0], 1, BITS_PER_WORD, 1);
11198 assemble_zeros (3);
11201 [(set_attr "length" "4")
11202 (set_attr "type" "no_insn")]
11205 (define_insn "consttable_2"
11206 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_2)]
11210 rtx x = operands[0];
11211 making_const_table = TRUE;
11212 switch (GET_MODE_CLASS (GET_MODE (x)))
11215 arm_emit_fp16_const (x);
11218 assemble_integer (operands[0], 2, BITS_PER_WORD, 1);
11219 assemble_zeros (2);
11224 [(set_attr "length" "4")
11225 (set_attr "type" "no_insn")]
11228 (define_insn "consttable_4"
11229 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_4)]
11233 rtx x = operands[0];
11234 making_const_table = TRUE;
11235 switch (GET_MODE_CLASS (GET_MODE (x)))
11238 assemble_real (*CONST_DOUBLE_REAL_VALUE (x), GET_MODE (x),
11242 /* XXX: Sometimes gcc does something really dumb and ends up with
11243 a HIGH in a constant pool entry, usually because it's trying to
11244 load into a VFP register. We know this will always be used in
11245 combination with a LO_SUM which ignores the high bits, so just
11246 strip off the HIGH. */
11247 if (GET_CODE (x) == HIGH)
11249 assemble_integer (x, 4, BITS_PER_WORD, 1);
11250 mark_symbol_refs_as_used (x);
11255 [(set_attr "length" "4")
11256 (set_attr "type" "no_insn")]
11259 (define_insn "consttable_8"
11260 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_8)]
11264 making_const_table = TRUE;
11265 switch (GET_MODE_CLASS (GET_MODE (operands[0])))
11268 assemble_real (*CONST_DOUBLE_REAL_VALUE (operands[0]),
11269 GET_MODE (operands[0]), BITS_PER_WORD);
11272 assemble_integer (operands[0], 8, BITS_PER_WORD, 1);
11277 [(set_attr "length" "8")
11278 (set_attr "type" "no_insn")]
11281 (define_insn "consttable_16"
11282 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_16)]
11286 making_const_table = TRUE;
11287 switch (GET_MODE_CLASS (GET_MODE (operands[0])))
11290 assemble_real (*CONST_DOUBLE_REAL_VALUE (operands[0]),
11291 GET_MODE (operands[0]), BITS_PER_WORD);
11294 assemble_integer (operands[0], 16, BITS_PER_WORD, 1);
11299 [(set_attr "length" "16")
11300 (set_attr "type" "no_insn")]
11303 ;; V5 Instructions,
11305 (define_insn "clzsi2"
11306 [(set (match_operand:SI 0 "s_register_operand" "=r")
11307 (clz:SI (match_operand:SI 1 "s_register_operand" "r")))]
11308 "TARGET_32BIT && arm_arch5"
11310 [(set_attr "predicable" "yes")
11311 (set_attr "predicable_short_it" "no")
11312 (set_attr "type" "clz")])
11314 (define_insn "rbitsi2"
11315 [(set (match_operand:SI 0 "s_register_operand" "=r")
11316 (unspec:SI [(match_operand:SI 1 "s_register_operand" "r")] UNSPEC_RBIT))]
11317 "TARGET_32BIT && arm_arch_thumb2"
11319 [(set_attr "predicable" "yes")
11320 (set_attr "predicable_short_it" "no")
11321 (set_attr "type" "clz")])
11323 ;; Keep this as a CTZ expression until after reload and then split
11324 ;; into RBIT + CLZ. Since RBIT is represented as an UNSPEC it is unlikely
11325 ;; to fold with any other expression.
11327 (define_insn_and_split "ctzsi2"
11328 [(set (match_operand:SI 0 "s_register_operand" "=r")
11329 (ctz:SI (match_operand:SI 1 "s_register_operand" "r")))]
11330 "TARGET_32BIT && arm_arch_thumb2"
11332 "&& reload_completed"
11335 emit_insn (gen_rbitsi2 (operands[0], operands[1]));
11336 emit_insn (gen_clzsi2 (operands[0], operands[0]));
11340 ;; V5E instructions.
11342 (define_insn "prefetch"
11343 [(prefetch (match_operand:SI 0 "address_operand" "p")
11344 (match_operand:SI 1 "" "")
11345 (match_operand:SI 2 "" ""))]
11346 "TARGET_32BIT && arm_arch5e"
11348 [(set_attr "type" "load1")]
11351 ;; General predication pattern
11354 [(match_operator 0 "arm_comparison_operator"
11355 [(match_operand 1 "cc_register" "")
11358 && (!TARGET_NO_VOLATILE_CE || !volatile_refs_p (PATTERN (insn)))"
11360 [(set_attr "predicated" "yes")]
11363 (define_insn "force_register_use"
11364 [(unspec:SI [(match_operand:SI 0 "register_operand" "")] UNSPEC_REGISTER_USE)]
11367 [(set_attr "length" "0")
11368 (set_attr "type" "no_insn")]
11372 ;; Patterns for exception handling
11374 (define_expand "eh_return"
11375 [(use (match_operand 0 "general_operand" ""))]
11380 emit_insn (gen_arm_eh_return (operands[0]));
11382 emit_insn (gen_thumb_eh_return (operands[0]));
11387 ;; We can't expand this before we know where the link register is stored.
11388 (define_insn_and_split "arm_eh_return"
11389 [(unspec_volatile [(match_operand:SI 0 "s_register_operand" "r")]
11391 (clobber (match_scratch:SI 1 "=&r"))]
11394 "&& reload_completed"
11398 arm_set_return_address (operands[0], operands[1]);
11406 (define_insn "load_tp_hard"
11407 [(set (match_operand:SI 0 "register_operand" "=r")
11408 (unspec:SI [(const_int 0)] UNSPEC_TLS))]
11410 "mrc%?\\tp15, 0, %0, c13, c0, 3\\t@ load_tp_hard"
11411 [(set_attr "predicable" "yes")
11412 (set_attr "type" "mrs")]
11415 ;; Doesn't clobber R1-R3. Must use r0 for the first operand.
11416 (define_insn "load_tp_soft"
11417 [(set (reg:SI 0) (unspec:SI [(const_int 0)] UNSPEC_TLS))
11418 (clobber (reg:SI LR_REGNUM))
11419 (clobber (reg:SI IP_REGNUM))
11420 (clobber (reg:CC CC_REGNUM))]
11422 "bl\\t__aeabi_read_tp\\t@ load_tp_soft"
11423 [(set_attr "conds" "clob")
11424 (set_attr "type" "branch")]
11427 ;; tls descriptor call
11428 (define_insn "tlscall"
11429 [(set (reg:SI R0_REGNUM)
11430 (unspec:SI [(reg:SI R0_REGNUM)
11431 (match_operand:SI 0 "" "X")
11432 (match_operand 1 "" "")] UNSPEC_TLS))
11433 (clobber (reg:SI R1_REGNUM))
11434 (clobber (reg:SI LR_REGNUM))
11435 (clobber (reg:SI CC_REGNUM))]
11438 targetm.asm_out.internal_label (asm_out_file, "LPIC",
11439 INTVAL (operands[1]));
11440 return "bl\\t%c0(tlscall)";
11442 [(set_attr "conds" "clob")
11443 (set_attr "length" "4")
11444 (set_attr "type" "branch")]
11447 ;; For thread pointer builtin
11448 (define_expand "get_thread_pointersi"
11449 [(match_operand:SI 0 "s_register_operand" "=r")]
11453 arm_load_tp (operands[0]);
11459 ;; We only care about the lower 16 bits of the constant
11460 ;; being inserted into the upper 16 bits of the register.
11461 (define_insn "*arm_movtas_ze"
11462 [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r,r")
11465 (match_operand:SI 1 "const_int_operand" ""))]
11470 [(set_attr "arch" "32,v8mb")
11471 (set_attr "predicable" "yes")
11472 (set_attr "predicable_short_it" "no")
11473 (set_attr "length" "4")
11474 (set_attr "type" "alu_sreg")]
11477 (define_insn "*arm_rev"
11478 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r")
11479 (bswap:SI (match_operand:SI 1 "s_register_operand" "l,l,r")))]
11485 [(set_attr "arch" "t1,t2,32")
11486 (set_attr "length" "2,2,4")
11487 (set_attr "predicable" "no,yes,yes")
11488 (set_attr "predicable_short_it" "no")
11489 (set_attr "type" "rev")]
11492 (define_expand "arm_legacy_rev"
11493 [(set (match_operand:SI 2 "s_register_operand" "")
11494 (xor:SI (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
11498 (lshiftrt:SI (match_dup 2)
11500 (set (match_operand:SI 3 "s_register_operand" "")
11501 (rotatert:SI (match_dup 1)
11504 (and:SI (match_dup 2)
11505 (const_int -65281)))
11506 (set (match_operand:SI 0 "s_register_operand" "")
11507 (xor:SI (match_dup 3)
11513 ;; Reuse temporaries to keep register pressure down.
11514 (define_expand "thumb_legacy_rev"
11515 [(set (match_operand:SI 2 "s_register_operand" "")
11516 (ashift:SI (match_operand:SI 1 "s_register_operand" "")
11518 (set (match_operand:SI 3 "s_register_operand" "")
11519 (lshiftrt:SI (match_dup 1)
11522 (ior:SI (match_dup 3)
11524 (set (match_operand:SI 4 "s_register_operand" "")
11526 (set (match_operand:SI 5 "s_register_operand" "")
11527 (rotatert:SI (match_dup 1)
11530 (ashift:SI (match_dup 5)
11533 (lshiftrt:SI (match_dup 5)
11536 (ior:SI (match_dup 5)
11539 (rotatert:SI (match_dup 5)
11541 (set (match_operand:SI 0 "s_register_operand" "")
11542 (ior:SI (match_dup 5)
11548 ;; ARM-specific expansion of signed mod by power of 2
11549 ;; using conditional negate.
11550 ;; For r0 % n where n is a power of 2 produce:
11552 ;; and r0, r0, #(n - 1)
11553 ;; and r1, r1, #(n - 1)
11554 ;; rsbpl r0, r1, #0
11556 (define_expand "modsi3"
11557 [(match_operand:SI 0 "register_operand" "")
11558 (match_operand:SI 1 "register_operand" "")
11559 (match_operand:SI 2 "const_int_operand" "")]
11562 HOST_WIDE_INT val = INTVAL (operands[2]);
11565 || exact_log2 (val) <= 0)
11568 rtx mask = GEN_INT (val - 1);
11570 /* In the special case of x0 % 2 we can do the even shorter:
11573 rsblt r0, r0, #0. */
11577 rtx cc_reg = arm_gen_compare_reg (LT,
11578 operands[1], const0_rtx, NULL_RTX);
11579 rtx cond = gen_rtx_LT (SImode, cc_reg, const0_rtx);
11580 rtx masked = gen_reg_rtx (SImode);
11582 emit_insn (gen_andsi3 (masked, operands[1], mask));
11583 emit_move_insn (operands[0],
11584 gen_rtx_IF_THEN_ELSE (SImode, cond,
11585 gen_rtx_NEG (SImode,
11591 rtx neg_op = gen_reg_rtx (SImode);
11592 rtx_insn *insn = emit_insn (gen_subsi3_compare0 (neg_op, const0_rtx,
11595 /* Extract the condition register and mode. */
11596 rtx cmp = XVECEXP (PATTERN (insn), 0, 0);
11597 rtx cc_reg = SET_DEST (cmp);
11598 rtx cond = gen_rtx_GE (SImode, cc_reg, const0_rtx);
11600 emit_insn (gen_andsi3 (operands[0], operands[1], mask));
11602 rtx masked_neg = gen_reg_rtx (SImode);
11603 emit_insn (gen_andsi3 (masked_neg, neg_op, mask));
11605 /* We want a conditional negate here, but emitting COND_EXEC rtxes
11606 during expand does not always work. Do an IF_THEN_ELSE instead. */
11607 emit_move_insn (operands[0],
11608 gen_rtx_IF_THEN_ELSE (SImode, cond,
11609 gen_rtx_NEG (SImode, masked_neg),
11617 (define_expand "bswapsi2"
11618 [(set (match_operand:SI 0 "s_register_operand" "=r")
11619 (bswap:SI (match_operand:SI 1 "s_register_operand" "r")))]
11620 "TARGET_EITHER && (arm_arch6 || !optimize_size)"
11624 rtx op2 = gen_reg_rtx (SImode);
11625 rtx op3 = gen_reg_rtx (SImode);
11629 rtx op4 = gen_reg_rtx (SImode);
11630 rtx op5 = gen_reg_rtx (SImode);
11632 emit_insn (gen_thumb_legacy_rev (operands[0], operands[1],
11633 op2, op3, op4, op5));
11637 emit_insn (gen_arm_legacy_rev (operands[0], operands[1],
11646 ;; bswap16 patterns: use revsh and rev16 instructions for the signed
11647 ;; and unsigned variants, respectively. For rev16, expose
11648 ;; byte-swapping in the lower 16 bits only.
11649 (define_insn "*arm_revsh"
11650 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r")
11651 (sign_extend:SI (bswap:HI (match_operand:HI 1 "s_register_operand" "l,l,r"))))]
11657 [(set_attr "arch" "t1,t2,32")
11658 (set_attr "length" "2,2,4")
11659 (set_attr "type" "rev")]
11662 (define_insn "*arm_rev16"
11663 [(set (match_operand:HI 0 "s_register_operand" "=l,l,r")
11664 (bswap:HI (match_operand:HI 1 "s_register_operand" "l,l,r")))]
11670 [(set_attr "arch" "t1,t2,32")
11671 (set_attr "length" "2,2,4")
11672 (set_attr "type" "rev")]
11675 ;; There are no canonicalisation rules for the position of the lshiftrt, ashift
11676 ;; operations within an IOR/AND RTX, therefore we have two patterns matching
11677 ;; each valid permutation.
11679 (define_insn "arm_rev16si2"
11680 [(set (match_operand:SI 0 "register_operand" "=l,l,r")
11681 (ior:SI (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "l,l,r")
11683 (match_operand:SI 3 "const_int_operand" "n,n,n"))
11684 (and:SI (lshiftrt:SI (match_dup 1)
11686 (match_operand:SI 2 "const_int_operand" "n,n,n"))))]
11688 && aarch_rev16_shleft_mask_imm_p (operands[3], SImode)
11689 && aarch_rev16_shright_mask_imm_p (operands[2], SImode)"
11691 [(set_attr "arch" "t1,t2,32")
11692 (set_attr "length" "2,2,4")
11693 (set_attr "type" "rev")]
11696 (define_insn "arm_rev16si2_alt"
11697 [(set (match_operand:SI 0 "register_operand" "=l,l,r")
11698 (ior:SI (and:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "l,l,r")
11700 (match_operand:SI 2 "const_int_operand" "n,n,n"))
11701 (and:SI (ashift:SI (match_dup 1)
11703 (match_operand:SI 3 "const_int_operand" "n,n,n"))))]
11705 && aarch_rev16_shleft_mask_imm_p (operands[3], SImode)
11706 && aarch_rev16_shright_mask_imm_p (operands[2], SImode)"
11708 [(set_attr "arch" "t1,t2,32")
11709 (set_attr "length" "2,2,4")
11710 (set_attr "type" "rev")]
11713 (define_expand "bswaphi2"
11714 [(set (match_operand:HI 0 "s_register_operand" "=r")
11715 (bswap:HI (match_operand:HI 1 "s_register_operand" "r")))]
11720 ;; Patterns for LDRD/STRD in Thumb2 mode
11722 (define_insn "*thumb2_ldrd"
11723 [(set (match_operand:SI 0 "s_register_operand" "=r")
11724 (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "rk")
11725 (match_operand:SI 2 "ldrd_strd_offset_operand" "Do"))))
11726 (set (match_operand:SI 3 "s_register_operand" "=r")
11727 (mem:SI (plus:SI (match_dup 1)
11728 (match_operand:SI 4 "const_int_operand" ""))))]
11729 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11730 && ((INTVAL (operands[2]) + 4) == INTVAL (operands[4]))
11731 && (operands_ok_ldrd_strd (operands[0], operands[3],
11732 operands[1], INTVAL (operands[2]),
11734 "ldrd%?\t%0, %3, [%1, %2]"
11735 [(set_attr "type" "load2")
11736 (set_attr "predicable" "yes")
11737 (set_attr "predicable_short_it" "no")])
11739 (define_insn "*thumb2_ldrd_base"
11740 [(set (match_operand:SI 0 "s_register_operand" "=r")
11741 (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
11742 (set (match_operand:SI 2 "s_register_operand" "=r")
11743 (mem:SI (plus:SI (match_dup 1)
11745 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11746 && (operands_ok_ldrd_strd (operands[0], operands[2],
11747 operands[1], 0, false, true))"
11748 "ldrd%?\t%0, %2, [%1]"
11749 [(set_attr "type" "load2")
11750 (set_attr "predicable" "yes")
11751 (set_attr "predicable_short_it" "no")])
11753 (define_insn "*thumb2_ldrd_base_neg"
11754 [(set (match_operand:SI 0 "s_register_operand" "=r")
11755 (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "rk")
11757 (set (match_operand:SI 2 "s_register_operand" "=r")
11758 (mem:SI (match_dup 1)))]
11759 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11760 && (operands_ok_ldrd_strd (operands[0], operands[2],
11761 operands[1], -4, false, true))"
11762 "ldrd%?\t%0, %2, [%1, #-4]"
11763 [(set_attr "type" "load2")
11764 (set_attr "predicable" "yes")
11765 (set_attr "predicable_short_it" "no")])
11767 (define_insn "*thumb2_strd"
11768 [(set (mem:SI (plus:SI (match_operand:SI 0 "s_register_operand" "rk")
11769 (match_operand:SI 1 "ldrd_strd_offset_operand" "Do")))
11770 (match_operand:SI 2 "s_register_operand" "r"))
11771 (set (mem:SI (plus:SI (match_dup 0)
11772 (match_operand:SI 3 "const_int_operand" "")))
11773 (match_operand:SI 4 "s_register_operand" "r"))]
11774 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11775 && ((INTVAL (operands[1]) + 4) == INTVAL (operands[3]))
11776 && (operands_ok_ldrd_strd (operands[2], operands[4],
11777 operands[0], INTVAL (operands[1]),
11779 "strd%?\t%2, %4, [%0, %1]"
11780 [(set_attr "type" "store2")
11781 (set_attr "predicable" "yes")
11782 (set_attr "predicable_short_it" "no")])
11784 (define_insn "*thumb2_strd_base"
11785 [(set (mem:SI (match_operand:SI 0 "s_register_operand" "rk"))
11786 (match_operand:SI 1 "s_register_operand" "r"))
11787 (set (mem:SI (plus:SI (match_dup 0)
11789 (match_operand:SI 2 "s_register_operand" "r"))]
11790 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11791 && (operands_ok_ldrd_strd (operands[1], operands[2],
11792 operands[0], 0, false, false))"
11793 "strd%?\t%1, %2, [%0]"
11794 [(set_attr "type" "store2")
11795 (set_attr "predicable" "yes")
11796 (set_attr "predicable_short_it" "no")])
11798 (define_insn "*thumb2_strd_base_neg"
11799 [(set (mem:SI (plus:SI (match_operand:SI 0 "s_register_operand" "rk")
11801 (match_operand:SI 1 "s_register_operand" "r"))
11802 (set (mem:SI (match_dup 0))
11803 (match_operand:SI 2 "s_register_operand" "r"))]
11804 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11805 && (operands_ok_ldrd_strd (operands[1], operands[2],
11806 operands[0], -4, false, false))"
11807 "strd%?\t%1, %2, [%0, #-4]"
11808 [(set_attr "type" "store2")
11809 (set_attr "predicable" "yes")
11810 (set_attr "predicable_short_it" "no")])
11812 ;; ARMv8 CRC32 instructions.
11813 (define_insn "<crc_variant>"
11814 [(set (match_operand:SI 0 "s_register_operand" "=r")
11815 (unspec:SI [(match_operand:SI 1 "s_register_operand" "r")
11816 (match_operand:<crc_mode> 2 "s_register_operand" "r")]
11819 "<crc_variant>\\t%0, %1, %2"
11820 [(set_attr "type" "crc")
11821 (set_attr "conds" "unconditional")]
11824 ;; Load the load/store double peephole optimizations.
11825 (include "ldrdstrd.md")
11827 ;; Load the load/store multiple patterns
11828 (include "ldmstm.md")
11830 ;; Patterns in ldmstm.md don't cover more than 4 registers. This pattern covers
11831 ;; large lists without explicit writeback generated for APCS_FRAME epilogue.
11832 ;; The operands are validated through the load_multiple_operation
11833 ;; match_parallel predicate rather than through constraints so enable it only
11835 (define_insn "*load_multiple"
11836 [(match_parallel 0 "load_multiple_operation"
11837 [(set (match_operand:SI 2 "s_register_operand" "=rk")
11838 (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
11840 "TARGET_32BIT && reload_completed"
11843 arm_output_multireg_pop (operands, /*return_pc=*/false,
11844 /*cond=*/const_true_rtx,
11850 [(set_attr "predicable" "yes")]
11853 (define_expand "copysignsf3"
11854 [(match_operand:SF 0 "register_operand")
11855 (match_operand:SF 1 "register_operand")
11856 (match_operand:SF 2 "register_operand")]
11857 "TARGET_SOFT_FLOAT && arm_arch_thumb2"
11859 emit_move_insn (operands[0], operands[2]);
11860 emit_insn (gen_insv_t2 (simplify_gen_subreg (SImode, operands[0], SFmode, 0),
11861 GEN_INT (31), GEN_INT (0),
11862 simplify_gen_subreg (SImode, operands[1], SFmode, 0)));
11867 (define_expand "copysigndf3"
11868 [(match_operand:DF 0 "register_operand")
11869 (match_operand:DF 1 "register_operand")
11870 (match_operand:DF 2 "register_operand")]
11871 "TARGET_SOFT_FLOAT && arm_arch_thumb2"
11873 rtx op0_low = gen_lowpart (SImode, operands[0]);
11874 rtx op0_high = gen_highpart (SImode, operands[0]);
11875 rtx op1_low = gen_lowpart (SImode, operands[1]);
11876 rtx op1_high = gen_highpart (SImode, operands[1]);
11877 rtx op2_high = gen_highpart (SImode, operands[2]);
11879 rtx scratch1 = gen_reg_rtx (SImode);
11880 rtx scratch2 = gen_reg_rtx (SImode);
11881 emit_move_insn (scratch1, op2_high);
11882 emit_move_insn (scratch2, op1_high);
11884 emit_insn(gen_rtx_SET(scratch1,
11885 gen_rtx_LSHIFTRT (SImode, op2_high, GEN_INT(31))));
11886 emit_insn(gen_insv_t2(scratch2, GEN_INT(1), GEN_INT(31), scratch1));
11887 emit_move_insn (op0_low, op1_low);
11888 emit_move_insn (op0_high, scratch2);
11894 ;; movmisalign patterns for HImode and SImode.
11895 (define_expand "movmisalign<mode>"
11896 [(match_operand:HSI 0 "general_operand")
11897 (match_operand:HSI 1 "general_operand")]
11900 /* This pattern is not permitted to fail during expansion: if both arguments
11901 are non-registers (e.g. memory := constant), force operand 1 into a
11903 rtx (* gen_unaligned_load)(rtx, rtx);
11904 rtx tmp_dest = operands[0];
11905 if (!s_register_operand (operands[0], <MODE>mode)
11906 && !s_register_operand (operands[1], <MODE>mode))
11907 operands[1] = force_reg (<MODE>mode, operands[1]);
11909 if (<MODE>mode == HImode)
11911 gen_unaligned_load = gen_unaligned_loadhiu;
11912 tmp_dest = gen_reg_rtx (SImode);
11915 gen_unaligned_load = gen_unaligned_loadsi;
11917 if (MEM_P (operands[1]))
11919 emit_insn (gen_unaligned_load (tmp_dest, operands[1]));
11920 if (<MODE>mode == HImode)
11921 emit_move_insn (operands[0], gen_lowpart (HImode, tmp_dest));
11924 emit_insn (gen_unaligned_store<mode> (operands[0], operands[1]));
11929 (define_insn "<cdp>"
11930 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "n")
11931 (match_operand:SI 1 "immediate_operand" "n")
11932 (match_operand:SI 2 "immediate_operand" "n")
11933 (match_operand:SI 3 "immediate_operand" "n")
11934 (match_operand:SI 4 "immediate_operand" "n")
11935 (match_operand:SI 5 "immediate_operand" "n")] CDPI)]
11936 "arm_coproc_builtin_available (VUNSPEC_<CDP>)"
11938 arm_const_bounds (operands[0], 0, 16);
11939 arm_const_bounds (operands[1], 0, 16);
11940 arm_const_bounds (operands[2], 0, (1 << 5));
11941 arm_const_bounds (operands[3], 0, (1 << 5));
11942 arm_const_bounds (operands[4], 0, (1 << 5));
11943 arm_const_bounds (operands[5], 0, 8);
11944 return "<cdp>\\tp%c0, %1, CR%c2, CR%c3, CR%c4, %5";
11946 [(set_attr "length" "4")
11947 (set_attr "type" "coproc")])
11949 (define_insn "*ldc"
11950 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "n")
11951 (match_operand:SI 1 "immediate_operand" "n")
11952 (match_operand:SI 2 "memory_operand" "Uz")] LDCI)]
11953 "arm_coproc_builtin_available (VUNSPEC_<LDC>)"
11955 arm_const_bounds (operands[0], 0, 16);
11956 arm_const_bounds (operands[1], 0, (1 << 5));
11957 return "<ldc>\\tp%c0, CR%c1, %2";
11959 [(set_attr "length" "4")
11960 (set_attr "type" "coproc")])
11962 (define_insn "*stc"
11963 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "n")
11964 (match_operand:SI 1 "immediate_operand" "n")
11965 (match_operand:SI 2 "memory_operand" "=Uz")] STCI)]
11966 "arm_coproc_builtin_available (VUNSPEC_<STC>)"
11968 arm_const_bounds (operands[0], 0, 16);
11969 arm_const_bounds (operands[1], 0, (1 << 5));
11970 return "<stc>\\tp%c0, CR%c1, %2";
11972 [(set_attr "length" "4")
11973 (set_attr "type" "coproc")])
11975 (define_expand "<ldc>"
11976 [(unspec_volatile [(match_operand:SI 0 "immediate_operand")
11977 (match_operand:SI 1 "immediate_operand")
11978 (mem:SI (match_operand:SI 2 "s_register_operand"))] LDCI)]
11979 "arm_coproc_builtin_available (VUNSPEC_<LDC>)")
11981 (define_expand "<stc>"
11982 [(unspec_volatile [(match_operand:SI 0 "immediate_operand")
11983 (match_operand:SI 1 "immediate_operand")
11984 (mem:SI (match_operand:SI 2 "s_register_operand"))] STCI)]
11985 "arm_coproc_builtin_available (VUNSPEC_<STC>)")
11987 (define_insn "<mcr>"
11988 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "n")
11989 (match_operand:SI 1 "immediate_operand" "n")
11990 (match_operand:SI 2 "s_register_operand" "r")
11991 (match_operand:SI 3 "immediate_operand" "n")
11992 (match_operand:SI 4 "immediate_operand" "n")
11993 (match_operand:SI 5 "immediate_operand" "n")] MCRI)
11994 (use (match_dup 2))]
11995 "arm_coproc_builtin_available (VUNSPEC_<MCR>)"
11997 arm_const_bounds (operands[0], 0, 16);
11998 arm_const_bounds (operands[1], 0, 8);
11999 arm_const_bounds (operands[3], 0, (1 << 5));
12000 arm_const_bounds (operands[4], 0, (1 << 5));
12001 arm_const_bounds (operands[5], 0, 8);
12002 return "<mcr>\\tp%c0, %1, %2, CR%c3, CR%c4, %5";
12004 [(set_attr "length" "4")
12005 (set_attr "type" "coproc")])
12007 (define_insn "<mrc>"
12008 [(set (match_operand:SI 0 "s_register_operand" "=r")
12009 (unspec_volatile:SI [(match_operand:SI 1 "immediate_operand" "n")
12010 (match_operand:SI 2 "immediate_operand" "n")
12011 (match_operand:SI 3 "immediate_operand" "n")
12012 (match_operand:SI 4 "immediate_operand" "n")
12013 (match_operand:SI 5 "immediate_operand" "n")] MRCI))]
12014 "arm_coproc_builtin_available (VUNSPEC_<MRC>)"
12016 arm_const_bounds (operands[1], 0, 16);
12017 arm_const_bounds (operands[2], 0, 8);
12018 arm_const_bounds (operands[3], 0, (1 << 5));
12019 arm_const_bounds (operands[4], 0, (1 << 5));
12020 arm_const_bounds (operands[5], 0, 8);
12021 return "<mrc>\\tp%c1, %2, %0, CR%c3, CR%c4, %5";
12023 [(set_attr "length" "4")
12024 (set_attr "type" "coproc")])
12026 (define_insn "<mcrr>"
12027 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "n")
12028 (match_operand:SI 1 "immediate_operand" "n")
12029 (match_operand:DI 2 "s_register_operand" "r")
12030 (match_operand:SI 3 "immediate_operand" "n")] MCRRI)
12031 (use (match_dup 2))]
12032 "arm_coproc_builtin_available (VUNSPEC_<MCRR>)"
12034 arm_const_bounds (operands[0], 0, 16);
12035 arm_const_bounds (operands[1], 0, 8);
12036 arm_const_bounds (operands[3], 0, (1 << 5));
12037 return "<mcrr>\\tp%c0, %1, %Q2, %R2, CR%c3";
12039 [(set_attr "length" "4")
12040 (set_attr "type" "coproc")])
12042 (define_insn "<mrrc>"
12043 [(set (match_operand:DI 0 "s_register_operand" "=r")
12044 (unspec_volatile:DI [(match_operand:SI 1 "immediate_operand" "n")
12045 (match_operand:SI 2 "immediate_operand" "n")
12046 (match_operand:SI 3 "immediate_operand" "n")] MRRCI))]
12047 "arm_coproc_builtin_available (VUNSPEC_<MRRC>)"
12049 arm_const_bounds (operands[1], 0, 16);
12050 arm_const_bounds (operands[2], 0, 8);
12051 arm_const_bounds (operands[3], 0, (1 << 5));
12052 return "<mrrc>\\tp%c1, %2, %Q0, %R0, CR%c3";
12054 [(set_attr "length" "4")
12055 (set_attr "type" "coproc")])
12057 ;; Vector bits common to IWMMXT and Neon
12058 (include "vec-common.md")
12059 ;; Load the Intel Wireless Multimedia Extension patterns
12060 (include "iwmmxt.md")
12061 ;; Load the VFP co-processor patterns
12063 ;; Thumb-1 patterns
12064 (include "thumb1.md")
12065 ;; Thumb-2 patterns
12066 (include "thumb2.md")
12068 (include "neon.md")
12070 (include "crypto.md")
12071 ;; Synchronization Primitives
12072 (include "sync.md")
12073 ;; Fixed-point patterns
12074 (include "arm-fixed.md")