1 ;;- Machine description for ARM for GNU compiler
2 ;; Copyright (C) 1991-2016 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 (and (eq_attr "use_literal_pool" "yes")
237 (match_test "arm_disable_literal_pool"))
240 (eq_attr "arch_enabled" "no")
242 (const_string "yes")))
244 ; POOL_RANGE is how far away from a constant pool entry that this insn
245 ; can be placed. If the distance is zero, then this insn will never
246 ; reference the pool.
247 ; Note that for Thumb constant pools the PC value is rounded down to the
248 ; nearest multiple of four. Therefore, THUMB2_POOL_RANGE (and POOL_RANGE for
249 ; Thumb insns) should be set to <max_range> - 2.
250 ; NEG_POOL_RANGE is nonzero for insns that can reference a constant pool entry
251 ; before its address. It is set to <max_range> - (8 + <data_size>).
252 (define_attr "arm_pool_range" "" (const_int 0))
253 (define_attr "thumb2_pool_range" "" (const_int 0))
254 (define_attr "arm_neg_pool_range" "" (const_int 0))
255 (define_attr "thumb2_neg_pool_range" "" (const_int 0))
257 (define_attr "pool_range" ""
258 (cond [(eq_attr "is_thumb" "yes") (attr "thumb2_pool_range")]
259 (attr "arm_pool_range")))
260 (define_attr "neg_pool_range" ""
261 (cond [(eq_attr "is_thumb" "yes") (attr "thumb2_neg_pool_range")]
262 (attr "arm_neg_pool_range")))
264 ; An assembler sequence may clobber the condition codes without us knowing.
265 ; If such an insn references the pool, then we have no way of knowing how,
266 ; so use the most conservative value for pool_range.
267 (define_asm_attributes
268 [(set_attr "conds" "clob")
269 (set_attr "length" "4")
270 (set_attr "pool_range" "250")])
272 ; Load scheduling, set from the arm_ld_sched variable
273 ; initialized by arm_option_override()
274 (define_attr "ldsched" "no,yes" (const (symbol_ref "arm_ld_sched")))
276 ; condition codes: this one is used by final_prescan_insn to speed up
277 ; conditionalizing instructions. It saves having to scan the rtl to see if
278 ; it uses or alters the condition codes.
280 ; USE means that the condition codes are used by the insn in the process of
281 ; outputting code, this means (at present) that we can't use the insn in
284 ; SET means that the purpose of the insn is to set the condition codes in a
285 ; well defined manner.
287 ; CLOB means that the condition codes are altered in an undefined manner, if
288 ; they are altered at all
290 ; UNCONDITIONAL means the instruction can not be conditionally executed and
291 ; that the instruction does not use or alter the condition codes.
293 ; NOCOND means that the instruction does not use or alter the condition
294 ; codes but can be converted into a conditionally exectuted instruction.
296 (define_attr "conds" "use,set,clob,unconditional,nocond"
298 (ior (eq_attr "is_thumb1" "yes")
299 (eq_attr "type" "call"))
300 (const_string "clob")
301 (if_then_else (eq_attr "is_neon_type" "no")
302 (const_string "nocond")
303 (const_string "unconditional"))))
305 ; Predicable means that the insn can be conditionally executed based on
306 ; an automatically added predicate (additional patterns are generated by
307 ; gen...). We default to 'no' because no Thumb patterns match this rule
308 ; and not all ARM patterns do.
309 (define_attr "predicable" "no,yes" (const_string "no"))
311 ; Only model the write buffer for ARM6 and ARM7. Earlier processors don't
312 ; have one. Later ones, such as StrongARM, have write-back caches, so don't
313 ; suffer blockages enough to warrant modelling this (and it can adversely
314 ; affect the schedule).
315 (define_attr "model_wbuf" "no,yes" (const (symbol_ref "arm_tune_wbuf")))
317 ; WRITE_CONFLICT implies that a read following an unrelated write is likely
318 ; to stall the processor. Used with model_wbuf above.
319 (define_attr "write_conflict" "no,yes"
320 (if_then_else (eq_attr "type"
323 (const_string "no")))
325 ; Classify the insns into those that take one cycle and those that take more
326 ; than one on the main cpu execution unit.
327 (define_attr "core_cycles" "single,multi"
328 (if_then_else (eq_attr "type"
329 "adc_imm, adc_reg, adcs_imm, adcs_reg, adr, alu_ext, alu_imm, alu_sreg,\
330 alu_shift_imm, alu_shift_reg, alu_dsp_reg, alus_ext, alus_imm, alus_sreg,\
331 alus_shift_imm, alus_shift_reg, bfm, csel, rev, logic_imm, logic_reg,\
332 logic_shift_imm, logic_shift_reg, logics_imm, logics_reg,\
333 logics_shift_imm, logics_shift_reg, extend, shift_imm, float, fcsel,\
334 wmmx_wor, wmmx_wxor, wmmx_wand, wmmx_wandn, wmmx_wmov, wmmx_tmcrr,\
335 wmmx_tmrrc, wmmx_wldr, wmmx_wstr, wmmx_tmcr, wmmx_tmrc, wmmx_wadd,\
336 wmmx_wsub, wmmx_wmul, wmmx_wmac, wmmx_wavg2, wmmx_tinsr, wmmx_textrm,\
337 wmmx_wshufh, wmmx_wcmpeq, wmmx_wcmpgt, wmmx_wmax, wmmx_wmin, wmmx_wpack,\
338 wmmx_wunpckih, wmmx_wunpckil, wmmx_wunpckeh, wmmx_wunpckel, wmmx_wror,\
339 wmmx_wsra, wmmx_wsrl, wmmx_wsll, wmmx_wmadd, wmmx_tmia, wmmx_tmiaph,\
340 wmmx_tmiaxy, wmmx_tbcst, wmmx_tmovmsk, wmmx_wacc, wmmx_waligni,\
341 wmmx_walignr, wmmx_tandc, wmmx_textrc, wmmx_torc, wmmx_torvsc, wmmx_wsad,\
342 wmmx_wabs, wmmx_wabsdiff, wmmx_waddsubhx, wmmx_wsubaddhx, wmmx_wavg4,\
343 wmmx_wmulw, wmmx_wqmulm, wmmx_wqmulwm, wmmx_waddbhus, wmmx_wqmiaxy,\
344 wmmx_wmiaxy, wmmx_wmiawxy, wmmx_wmerge")
345 (const_string "single")
346 (const_string "multi")))
348 ;; FAR_JUMP is "yes" if a BL instruction is used to generate a branch to a
349 ;; distant label. Only applicable to Thumb code.
350 (define_attr "far_jump" "yes,no" (const_string "no"))
353 ;; The number of machine instructions this pattern expands to.
354 ;; Used for Thumb-2 conditional execution.
355 (define_attr "ce_count" "" (const_int 1))
357 ;;---------------------------------------------------------------------------
360 (include "unspecs.md")
362 ;;---------------------------------------------------------------------------
365 (include "iterators.md")
367 ;;---------------------------------------------------------------------------
370 (include "predicates.md")
371 (include "constraints.md")
373 ;;---------------------------------------------------------------------------
374 ;; Pipeline descriptions
376 (define_attr "tune_cortexr4" "yes,no"
378 (eq_attr "tune" "cortexr4,cortexr4f,cortexr5")
380 (const_string "no"))))
382 ;; True if the generic scheduling description should be used.
384 (define_attr "generic_sched" "yes,no"
386 (ior (eq_attr "tune" "fa526,fa626,fa606te,fa626te,fmp626,fa726te,\
387 arm926ejs,arm1020e,arm1026ejs,arm1136js,\
388 arm1136jfs,cortexa5,cortexa7,cortexa8,\
389 cortexa9,cortexa12,cortexa15,cortexa17,\
390 cortexa53,cortexa57,cortexm4,cortexm7,\
391 exynosm1,marvell_pj4,xgene1")
392 (eq_attr "tune_cortexr4" "yes"))
394 (const_string "yes"))))
396 (define_attr "generic_vfp" "yes,no"
398 (and (eq_attr "fpu" "vfp")
399 (eq_attr "tune" "!arm1020e,arm1022e,cortexa5,cortexa7,\
400 cortexa8,cortexa9,cortexa53,cortexm4,\
401 cortexm7,marvell_pj4,xgene1")
402 (eq_attr "tune_cortexr4" "no"))
404 (const_string "no"))))
406 (include "marvell-f-iwmmxt.md")
407 (include "arm-generic.md")
408 (include "arm926ejs.md")
409 (include "arm1020e.md")
410 (include "arm1026ejs.md")
411 (include "arm1136jfs.md")
413 (include "fa606te.md")
414 (include "fa626te.md")
415 (include "fmp626.md")
416 (include "fa726te.md")
417 (include "cortex-a5.md")
418 (include "cortex-a7.md")
419 (include "cortex-a8.md")
420 (include "cortex-a9.md")
421 (include "cortex-a15.md")
422 (include "cortex-a17.md")
423 (include "cortex-a53.md")
424 (include "cortex-a57.md")
425 (include "cortex-r4.md")
426 (include "cortex-r4f.md")
427 (include "cortex-m7.md")
428 (include "cortex-m4.md")
429 (include "cortex-m4-fpu.md")
430 (include "exynos-m1.md")
432 (include "marvell-pj4.md")
433 (include "xgene1.md")
436 ;;---------------------------------------------------------------------------
441 ;; Note: For DImode insns, there is normally no reason why operands should
442 ;; not be in the same register, what we don't want is for something being
443 ;; written to partially overlap something that is an input.
445 (define_expand "adddi3"
447 [(set (match_operand:DI 0 "s_register_operand" "")
448 (plus:DI (match_operand:DI 1 "s_register_operand" "")
449 (match_operand:DI 2 "arm_adddi_operand" "")))
450 (clobber (reg:CC CC_REGNUM))])]
455 if (!REG_P (operands[1]))
456 operands[1] = force_reg (DImode, operands[1]);
457 if (!REG_P (operands[2]))
458 operands[2] = force_reg (DImode, operands[2]);
463 (define_insn_and_split "*arm_adddi3"
464 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r,&r,&r,&r")
465 (plus:DI (match_operand:DI 1 "s_register_operand" "%0, 0, r, 0, r")
466 (match_operand:DI 2 "arm_adddi_operand" "r, 0, r, Dd, Dd")))
467 (clobber (reg:CC CC_REGNUM))]
468 "TARGET_32BIT && !TARGET_NEON"
470 "TARGET_32BIT && reload_completed
471 && ! (TARGET_NEON && IS_VFP_REGNUM (REGNO (operands[0])))"
472 [(parallel [(set (reg:CC_C CC_REGNUM)
473 (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
475 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
476 (set (match_dup 3) (plus:SI (plus:SI (match_dup 4) (match_dup 5))
477 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
480 operands[3] = gen_highpart (SImode, operands[0]);
481 operands[0] = gen_lowpart (SImode, operands[0]);
482 operands[4] = gen_highpart (SImode, operands[1]);
483 operands[1] = gen_lowpart (SImode, operands[1]);
484 operands[5] = gen_highpart_mode (SImode, DImode, operands[2]);
485 operands[2] = gen_lowpart (SImode, operands[2]);
487 [(set_attr "conds" "clob")
488 (set_attr "length" "8")
489 (set_attr "type" "multiple")]
492 (define_insn_and_split "*adddi_sesidi_di"
493 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
494 (plus:DI (sign_extend:DI
495 (match_operand:SI 2 "s_register_operand" "r,r"))
496 (match_operand:DI 1 "s_register_operand" "0,r")))
497 (clobber (reg:CC CC_REGNUM))]
500 "TARGET_32BIT && reload_completed"
501 [(parallel [(set (reg:CC_C CC_REGNUM)
502 (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
504 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
505 (set (match_dup 3) (plus:SI (plus:SI (ashiftrt:SI (match_dup 2)
508 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
511 operands[3] = gen_highpart (SImode, operands[0]);
512 operands[0] = gen_lowpart (SImode, operands[0]);
513 operands[4] = gen_highpart (SImode, operands[1]);
514 operands[1] = gen_lowpart (SImode, operands[1]);
515 operands[2] = gen_lowpart (SImode, operands[2]);
517 [(set_attr "conds" "clob")
518 (set_attr "length" "8")
519 (set_attr "type" "multiple")]
522 (define_insn_and_split "*adddi_zesidi_di"
523 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
524 (plus:DI (zero_extend:DI
525 (match_operand:SI 2 "s_register_operand" "r,r"))
526 (match_operand:DI 1 "s_register_operand" "0,r")))
527 (clobber (reg:CC CC_REGNUM))]
530 "TARGET_32BIT && reload_completed"
531 [(parallel [(set (reg:CC_C CC_REGNUM)
532 (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
534 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
535 (set (match_dup 3) (plus:SI (plus:SI (match_dup 4) (const_int 0))
536 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
539 operands[3] = gen_highpart (SImode, operands[0]);
540 operands[0] = gen_lowpart (SImode, operands[0]);
541 operands[4] = gen_highpart (SImode, operands[1]);
542 operands[1] = gen_lowpart (SImode, operands[1]);
543 operands[2] = gen_lowpart (SImode, operands[2]);
545 [(set_attr "conds" "clob")
546 (set_attr "length" "8")
547 (set_attr "type" "multiple")]
550 (define_expand "addv<mode>4"
551 [(match_operand:SIDI 0 "register_operand")
552 (match_operand:SIDI 1 "register_operand")
553 (match_operand:SIDI 2 "register_operand")
554 (match_operand 3 "")]
557 emit_insn (gen_add<mode>3_compareV (operands[0], operands[1], operands[2]));
558 arm_gen_unlikely_cbranch (NE, CC_Vmode, operands[3]);
563 (define_expand "uaddv<mode>4"
564 [(match_operand:SIDI 0 "register_operand")
565 (match_operand:SIDI 1 "register_operand")
566 (match_operand:SIDI 2 "register_operand")
567 (match_operand 3 "")]
570 emit_insn (gen_add<mode>3_compareC (operands[0], operands[1], operands[2]));
571 arm_gen_unlikely_cbranch (NE, CC_Cmode, operands[3]);
576 (define_expand "addsi3"
577 [(set (match_operand:SI 0 "s_register_operand" "")
578 (plus:SI (match_operand:SI 1 "s_register_operand" "")
579 (match_operand:SI 2 "reg_or_int_operand" "")))]
582 if (TARGET_32BIT && CONST_INT_P (operands[2]))
584 arm_split_constant (PLUS, SImode, NULL_RTX,
585 INTVAL (operands[2]), operands[0], operands[1],
586 optimize && can_create_pseudo_p ());
592 ; If there is a scratch available, this will be faster than synthesizing the
595 [(match_scratch:SI 3 "r")
596 (set (match_operand:SI 0 "arm_general_register_operand" "")
597 (plus:SI (match_operand:SI 1 "arm_general_register_operand" "")
598 (match_operand:SI 2 "const_int_operand" "")))]
600 !(const_ok_for_arm (INTVAL (operands[2]))
601 || const_ok_for_arm (-INTVAL (operands[2])))
602 && const_ok_for_arm (~INTVAL (operands[2]))"
603 [(set (match_dup 3) (match_dup 2))
604 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 3)))]
608 ;; The r/r/k alternative is required when reloading the address
609 ;; (plus (reg rN) (reg sp)) into (reg rN). In this case reload will
610 ;; put the duplicated register first, and not try the commutative version.
611 (define_insn_and_split "*arm_addsi3"
612 [(set (match_operand:SI 0 "s_register_operand" "=rk,l,l ,l ,r ,k ,r,r ,k ,r ,k,k,r ,k ,r")
613 (plus:SI (match_operand:SI 1 "s_register_operand" "%0 ,l,0 ,l ,rk,k ,r,rk,k ,rk,k,r,rk,k ,rk")
614 (match_operand:SI 2 "reg_or_int_operand" "rk ,l,Py,Pd,rI,rI,k,Pj,Pj,L ,L,L,PJ,PJ,?n")))]
629 subw%?\\t%0, %1, #%n2
630 subw%?\\t%0, %1, #%n2
633 && CONST_INT_P (operands[2])
634 && !const_ok_for_op (INTVAL (operands[2]), PLUS)
635 && (reload_completed || !arm_eliminable_register (operands[1]))"
636 [(clobber (const_int 0))]
638 arm_split_constant (PLUS, SImode, curr_insn,
639 INTVAL (operands[2]), operands[0],
643 [(set_attr "length" "2,4,4,4,4,4,4,4,4,4,4,4,4,4,16")
644 (set_attr "predicable" "yes")
645 (set_attr "predicable_short_it" "yes,yes,yes,yes,no,no,no,no,no,no,no,no,no,no,no")
646 (set_attr "arch" "t2,t2,t2,t2,*,*,*,t2,t2,*,*,a,t2,t2,*")
647 (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
648 (const_string "alu_imm")
649 (const_string "alu_sreg")))
653 (define_insn_and_split "adddi3_compareV"
654 [(set (reg:CC_V CC_REGNUM)
657 (sign_extend:TI (match_operand:DI 1 "register_operand" "r"))
658 (sign_extend:TI (match_operand:DI 2 "register_operand" "r")))
659 (sign_extend:TI (plus:DI (match_dup 1) (match_dup 2)))))
660 (set (match_operand:DI 0 "register_operand" "=&r")
661 (plus:DI (match_dup 1) (match_dup 2)))]
664 "&& reload_completed"
665 [(parallel [(set (reg:CC_C CC_REGNUM)
666 (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
668 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
669 (parallel [(set (reg:CC_V CC_REGNUM)
672 (sign_extend:DI (match_dup 4))
673 (sign_extend:DI (match_dup 5)))
674 (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0)))
675 (plus:DI (sign_extend:DI
676 (plus:SI (match_dup 4) (match_dup 5)))
677 (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0)))))
678 (set (match_dup 3) (plus:SI (plus:SI
679 (match_dup 4) (match_dup 5))
680 (ltu:SI (reg:CC_C CC_REGNUM)
684 operands[3] = gen_highpart (SImode, operands[0]);
685 operands[0] = gen_lowpart (SImode, operands[0]);
686 operands[4] = gen_highpart (SImode, operands[1]);
687 operands[1] = gen_lowpart (SImode, operands[1]);
688 operands[5] = gen_highpart (SImode, operands[2]);
689 operands[2] = gen_lowpart (SImode, operands[2]);
691 [(set_attr "conds" "set")
692 (set_attr "length" "8")
693 (set_attr "type" "multiple")]
696 (define_insn "addsi3_compareV"
697 [(set (reg:CC_V CC_REGNUM)
700 (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
701 (sign_extend:DI (match_operand:SI 2 "register_operand" "r")))
702 (sign_extend:DI (plus:SI (match_dup 1) (match_dup 2)))))
703 (set (match_operand:SI 0 "register_operand" "=r")
704 (plus:SI (match_dup 1) (match_dup 2)))]
706 "adds%?\\t%0, %1, %2"
707 [(set_attr "conds" "set")
708 (set_attr "type" "alus_sreg")]
711 (define_insn "*addsi3_compareV_upper"
712 [(set (reg:CC_V CC_REGNUM)
716 (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
717 (sign_extend:DI (match_operand:SI 2 "register_operand" "r")))
718 (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0)))
719 (plus:DI (sign_extend:DI
720 (plus:SI (match_dup 1) (match_dup 2)))
721 (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0)))))
722 (set (match_operand:SI 0 "register_operand" "=r")
724 (plus:SI (match_dup 1) (match_dup 2))
725 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
727 "adcs%?\\t%0, %1, %2"
728 [(set_attr "conds" "set")
729 (set_attr "type" "adcs_reg")]
732 (define_insn_and_split "adddi3_compareC"
733 [(set (reg:CC_C CC_REGNUM)
736 (zero_extend:TI (match_operand:DI 1 "register_operand" "r"))
737 (zero_extend:TI (match_operand:DI 2 "register_operand" "r")))
738 (zero_extend:TI (plus:DI (match_dup 1) (match_dup 2)))))
739 (set (match_operand:DI 0 "register_operand" "=&r")
740 (plus:DI (match_dup 1) (match_dup 2)))]
743 "&& reload_completed"
744 [(parallel [(set (reg:CC_C CC_REGNUM)
745 (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
747 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
748 (parallel [(set (reg:CC_C CC_REGNUM)
751 (zero_extend:DI (match_dup 4))
752 (zero_extend:DI (match_dup 5)))
753 (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0)))
754 (plus:DI (zero_extend:DI
755 (plus:SI (match_dup 4) (match_dup 5)))
756 (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0)))))
757 (set (match_dup 3) (plus:SI
758 (plus:SI (match_dup 4) (match_dup 5))
759 (ltu:SI (reg:CC_C CC_REGNUM)
763 operands[3] = gen_highpart (SImode, operands[0]);
764 operands[0] = gen_lowpart (SImode, operands[0]);
765 operands[4] = gen_highpart (SImode, operands[1]);
766 operands[5] = gen_highpart (SImode, operands[2]);
767 operands[1] = gen_lowpart (SImode, operands[1]);
768 operands[2] = gen_lowpart (SImode, operands[2]);
770 [(set_attr "conds" "set")
771 (set_attr "length" "8")
772 (set_attr "type" "multiple")]
775 (define_insn "*addsi3_compareC_upper"
776 [(set (reg:CC_C CC_REGNUM)
780 (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
781 (zero_extend:DI (match_operand:SI 2 "register_operand" "r")))
782 (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0)))
783 (plus:DI (zero_extend:DI
784 (plus:SI (match_dup 1) (match_dup 2)))
785 (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0)))))
786 (set (match_operand:SI 0 "register_operand" "=r")
788 (plus:SI (match_dup 1) (match_dup 2))
789 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
791 "adcs%?\\t%0, %1, %2"
792 [(set_attr "conds" "set")
793 (set_attr "type" "adcs_reg")]
796 (define_insn "addsi3_compareC"
797 [(set (reg:CC_C CC_REGNUM)
800 (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
801 (zero_extend:DI (match_operand:SI 2 "register_operand" "r")))
803 (plus:SI (match_dup 1) (match_dup 2)))))
804 (set (match_operand:SI 0 "register_operand" "=r")
805 (plus:SI (match_dup 1) (match_dup 2)))]
807 "adds%?\\t%0, %1, %2"
808 [(set_attr "conds" "set")
809 (set_attr "type" "alus_sreg")]
812 (define_insn "addsi3_compare0"
813 [(set (reg:CC_NOOV CC_REGNUM)
815 (plus:SI (match_operand:SI 1 "s_register_operand" "r, r,r")
816 (match_operand:SI 2 "arm_add_operand" "I,L,r"))
818 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
819 (plus:SI (match_dup 1) (match_dup 2)))]
823 subs%?\\t%0, %1, #%n2
825 [(set_attr "conds" "set")
826 (set_attr "type" "alus_imm,alus_imm,alus_sreg")]
829 (define_insn "*addsi3_compare0_scratch"
830 [(set (reg:CC_NOOV CC_REGNUM)
832 (plus:SI (match_operand:SI 0 "s_register_operand" "r, r, r")
833 (match_operand:SI 1 "arm_add_operand" "I,L, r"))
840 [(set_attr "conds" "set")
841 (set_attr "predicable" "yes")
842 (set_attr "type" "alus_imm,alus_imm,alus_sreg")]
845 (define_insn "*compare_negsi_si"
846 [(set (reg:CC_Z CC_REGNUM)
848 (neg:SI (match_operand:SI 0 "s_register_operand" "l,r"))
849 (match_operand:SI 1 "s_register_operand" "l,r")))]
852 [(set_attr "conds" "set")
853 (set_attr "predicable" "yes")
854 (set_attr "arch" "t2,*")
855 (set_attr "length" "2,4")
856 (set_attr "predicable_short_it" "yes,no")
857 (set_attr "type" "alus_sreg")]
860 ;; This is the canonicalization of addsi3_compare0_for_combiner when the
861 ;; addend is a constant.
862 (define_insn "cmpsi2_addneg"
863 [(set (reg:CC CC_REGNUM)
865 (match_operand:SI 1 "s_register_operand" "r,r")
866 (match_operand:SI 2 "arm_addimm_operand" "L,I")))
867 (set (match_operand:SI 0 "s_register_operand" "=r,r")
868 (plus:SI (match_dup 1)
869 (match_operand:SI 3 "arm_addimm_operand" "I,L")))]
870 "TARGET_32BIT && INTVAL (operands[2]) == -INTVAL (operands[3])"
873 subs%?\\t%0, %1, #%n3"
874 [(set_attr "conds" "set")
875 (set_attr "type" "alus_sreg")]
878 ;; Convert the sequence
880 ;; cmn rd, #1 (equivalent to cmp rd, #-1)
884 ;; bcs dest ((unsigned)rn >= 1)
885 ;; similarly for the beq variant using bcc.
886 ;; This is a common looping idiom (while (n--))
888 [(set (match_operand:SI 0 "arm_general_register_operand" "")
889 (plus:SI (match_operand:SI 1 "arm_general_register_operand" "")
891 (set (match_operand 2 "cc_register" "")
892 (compare (match_dup 0) (const_int -1)))
894 (if_then_else (match_operator 3 "equality_operator"
895 [(match_dup 2) (const_int 0)])
896 (match_operand 4 "" "")
897 (match_operand 5 "" "")))]
898 "TARGET_32BIT && peep2_reg_dead_p (3, operands[2])"
902 (match_dup 1) (const_int 1)))
903 (set (match_dup 0) (plus:SI (match_dup 1) (const_int -1)))])
905 (if_then_else (match_op_dup 3 [(match_dup 2) (const_int 0)])
908 "operands[2] = gen_rtx_REG (CCmode, CC_REGNUM);
909 operands[3] = gen_rtx_fmt_ee ((GET_CODE (operands[3]) == NE
912 operands[2], const0_rtx);"
915 ;; The next four insns work because they compare the result with one of
916 ;; the operands, and we know that the use of the condition code is
917 ;; either GEU or LTU, so we can use the carry flag from the addition
918 ;; instead of doing the compare a second time.
919 (define_insn "*addsi3_compare_op1"
920 [(set (reg:CC_C CC_REGNUM)
922 (plus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
923 (match_operand:SI 2 "arm_add_operand" "I,L,r"))
925 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
926 (plus:SI (match_dup 1) (match_dup 2)))]
930 subs%?\\t%0, %1, #%n2
932 [(set_attr "conds" "set")
933 (set_attr "type" "alus_imm,alus_imm,alus_sreg")]
936 (define_insn "*addsi3_compare_op2"
937 [(set (reg:CC_C CC_REGNUM)
939 (plus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
940 (match_operand:SI 2 "arm_add_operand" "I,L,r"))
942 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
943 (plus:SI (match_dup 1) (match_dup 2)))]
947 subs%?\\t%0, %1, #%n2
949 [(set_attr "conds" "set")
950 (set_attr "type" "alus_imm,alus_imm,alus_sreg")]
953 (define_insn "*compare_addsi2_op0"
954 [(set (reg:CC_C CC_REGNUM)
956 (plus:SI (match_operand:SI 0 "s_register_operand" "l,l,r,r,r")
957 (match_operand:SI 1 "arm_add_operand" "Pv,l,I,L,r"))
966 [(set_attr "conds" "set")
967 (set_attr "predicable" "yes")
968 (set_attr "arch" "t2,t2,*,*,*")
969 (set_attr "predicable_short_it" "yes,yes,no,no,no")
970 (set_attr "length" "2,2,4,4,4")
971 (set_attr "type" "alus_imm,alus_sreg,alus_imm,alus_imm,alus_sreg")]
974 (define_insn "*compare_addsi2_op1"
975 [(set (reg:CC_C CC_REGNUM)
977 (plus:SI (match_operand:SI 0 "s_register_operand" "l,l,r,r,r")
978 (match_operand:SI 1 "arm_add_operand" "Pv,l,I,L,r"))
987 [(set_attr "conds" "set")
988 (set_attr "predicable" "yes")
989 (set_attr "arch" "t2,t2,*,*,*")
990 (set_attr "predicable_short_it" "yes,yes,no,no,no")
991 (set_attr "length" "2,2,4,4,4")
992 (set_attr "type" "alus_imm,alus_sreg,alus_imm,alus_imm,alus_sreg")]
995 (define_insn "*addsi3_carryin_<optab>"
996 [(set (match_operand:SI 0 "s_register_operand" "=l,r,r")
997 (plus:SI (plus:SI (match_operand:SI 1 "s_register_operand" "%l,r,r")
998 (match_operand:SI 2 "arm_not_operand" "0,rI,K"))
999 (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))))]
1004 sbc%?\\t%0, %1, #%B2"
1005 [(set_attr "conds" "use")
1006 (set_attr "predicable" "yes")
1007 (set_attr "arch" "t2,*,*")
1008 (set_attr "length" "4")
1009 (set_attr "predicable_short_it" "yes,no,no")
1010 (set_attr "type" "adc_reg,adc_reg,adc_imm")]
1013 (define_insn "*addsi3_carryin_alt2_<optab>"
1014 [(set (match_operand:SI 0 "s_register_operand" "=l,r,r")
1015 (plus:SI (plus:SI (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))
1016 (match_operand:SI 1 "s_register_operand" "%l,r,r"))
1017 (match_operand:SI 2 "arm_rhs_operand" "l,rI,K")))]
1022 sbc%?\\t%0, %1, #%B2"
1023 [(set_attr "conds" "use")
1024 (set_attr "predicable" "yes")
1025 (set_attr "arch" "t2,*,*")
1026 (set_attr "length" "4")
1027 (set_attr "predicable_short_it" "yes,no,no")
1028 (set_attr "type" "adc_reg,adc_reg,adc_imm")]
1031 (define_insn "*addsi3_carryin_shift_<optab>"
1032 [(set (match_operand:SI 0 "s_register_operand" "=r")
1034 (match_operator:SI 2 "shift_operator"
1035 [(match_operand:SI 3 "s_register_operand" "r")
1036 (match_operand:SI 4 "reg_or_int_operand" "rM")])
1037 (match_operand:SI 1 "s_register_operand" "r"))
1038 (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))))]
1040 "adc%?\\t%0, %1, %3%S2"
1041 [(set_attr "conds" "use")
1042 (set_attr "predicable" "yes")
1043 (set_attr "predicable_short_it" "no")
1044 (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
1045 (const_string "alu_shift_imm")
1046 (const_string "alu_shift_reg")))]
1049 (define_insn "*addsi3_carryin_clobercc_<optab>"
1050 [(set (match_operand:SI 0 "s_register_operand" "=r")
1051 (plus:SI (plus:SI (match_operand:SI 1 "s_register_operand" "%r")
1052 (match_operand:SI 2 "arm_rhs_operand" "rI"))
1053 (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))))
1054 (clobber (reg:CC CC_REGNUM))]
1056 "adcs%?\\t%0, %1, %2"
1057 [(set_attr "conds" "set")
1058 (set_attr "type" "adcs_reg")]
1061 (define_expand "subv<mode>4"
1062 [(match_operand:SIDI 0 "register_operand")
1063 (match_operand:SIDI 1 "register_operand")
1064 (match_operand:SIDI 2 "register_operand")
1065 (match_operand 3 "")]
1068 emit_insn (gen_sub<mode>3_compare1 (operands[0], operands[1], operands[2]));
1069 arm_gen_unlikely_cbranch (NE, CC_Vmode, operands[3]);
1074 (define_expand "usubv<mode>4"
1075 [(match_operand:SIDI 0 "register_operand")
1076 (match_operand:SIDI 1 "register_operand")
1077 (match_operand:SIDI 2 "register_operand")
1078 (match_operand 3 "")]
1081 emit_insn (gen_sub<mode>3_compare1 (operands[0], operands[1], operands[2]));
1082 arm_gen_unlikely_cbranch (LTU, CCmode, operands[3]);
1087 (define_insn_and_split "subdi3_compare1"
1088 [(set (reg:CC CC_REGNUM)
1090 (match_operand:DI 1 "register_operand" "r")
1091 (match_operand:DI 2 "register_operand" "r")))
1092 (set (match_operand:DI 0 "register_operand" "=&r")
1093 (minus:DI (match_dup 1) (match_dup 2)))]
1096 "&& reload_completed"
1097 [(parallel [(set (reg:CC CC_REGNUM)
1098 (compare:CC (match_dup 1) (match_dup 2)))
1099 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1100 (parallel [(set (reg:CC CC_REGNUM)
1101 (compare:CC (match_dup 4) (match_dup 5)))
1102 (set (match_dup 3) (minus:SI (minus:SI (match_dup 4) (match_dup 5))
1103 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))])]
1105 operands[3] = gen_highpart (SImode, operands[0]);
1106 operands[0] = gen_lowpart (SImode, operands[0]);
1107 operands[4] = gen_highpart (SImode, operands[1]);
1108 operands[1] = gen_lowpart (SImode, operands[1]);
1109 operands[5] = gen_highpart (SImode, operands[2]);
1110 operands[2] = gen_lowpart (SImode, operands[2]);
1112 [(set_attr "conds" "set")
1113 (set_attr "length" "8")
1114 (set_attr "type" "multiple")]
1117 (define_insn "subsi3_compare1"
1118 [(set (reg:CC CC_REGNUM)
1120 (match_operand:SI 1 "register_operand" "r")
1121 (match_operand:SI 2 "register_operand" "r")))
1122 (set (match_operand:SI 0 "register_operand" "=r")
1123 (minus:SI (match_dup 1) (match_dup 2)))]
1125 "subs%?\\t%0, %1, %2"
1126 [(set_attr "conds" "set")
1127 (set_attr "type" "alus_sreg")]
1130 (define_insn "*subsi3_carryin"
1131 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
1132 (minus:SI (minus:SI (match_operand:SI 1 "reg_or_int_operand" "r,I")
1133 (match_operand:SI 2 "s_register_operand" "r,r"))
1134 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1139 [(set_attr "conds" "use")
1140 (set_attr "arch" "*,a")
1141 (set_attr "predicable" "yes")
1142 (set_attr "predicable_short_it" "no")
1143 (set_attr "type" "adc_reg,adc_imm")]
1146 (define_insn "*subsi3_carryin_const"
1147 [(set (match_operand:SI 0 "s_register_operand" "=r")
1148 (minus:SI (plus:SI (match_operand:SI 1 "s_register_operand" "r")
1149 (match_operand:SI 2 "arm_not_immediate_operand" "K"))
1150 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1152 "sbc\\t%0, %1, #%B2"
1153 [(set_attr "conds" "use")
1154 (set_attr "type" "adc_imm")]
1157 (define_insn "*subsi3_carryin_compare"
1158 [(set (reg:CC CC_REGNUM)
1159 (compare:CC (match_operand:SI 1 "s_register_operand" "r")
1160 (match_operand:SI 2 "s_register_operand" "r")))
1161 (set (match_operand:SI 0 "s_register_operand" "=r")
1162 (minus:SI (minus:SI (match_dup 1)
1164 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1167 [(set_attr "conds" "set")
1168 (set_attr "type" "adcs_reg")]
1171 (define_insn "*subsi3_carryin_compare_const"
1172 [(set (reg:CC CC_REGNUM)
1173 (compare:CC (match_operand:SI 1 "reg_or_int_operand" "r")
1174 (match_operand:SI 2 "arm_not_operand" "K")))
1175 (set (match_operand:SI 0 "s_register_operand" "=r")
1176 (minus:SI (plus:SI (match_dup 1)
1178 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1180 "sbcs\\t%0, %1, #%B2"
1181 [(set_attr "conds" "set")
1182 (set_attr "type" "adcs_imm")]
1185 (define_insn "*subsi3_carryin_shift"
1186 [(set (match_operand:SI 0 "s_register_operand" "=r")
1188 (match_operand:SI 1 "s_register_operand" "r")
1189 (match_operator:SI 2 "shift_operator"
1190 [(match_operand:SI 3 "s_register_operand" "r")
1191 (match_operand:SI 4 "reg_or_int_operand" "rM")]))
1192 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1194 "sbc%?\\t%0, %1, %3%S2"
1195 [(set_attr "conds" "use")
1196 (set_attr "predicable" "yes")
1197 (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
1198 (const_string "alu_shift_imm")
1199 (const_string "alu_shift_reg")))]
1202 (define_insn "*rsbsi3_carryin_shift"
1203 [(set (match_operand:SI 0 "s_register_operand" "=r")
1205 (match_operator:SI 2 "shift_operator"
1206 [(match_operand:SI 3 "s_register_operand" "r")
1207 (match_operand:SI 4 "reg_or_int_operand" "rM")])
1208 (match_operand:SI 1 "s_register_operand" "r"))
1209 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1211 "rsc%?\\t%0, %1, %3%S2"
1212 [(set_attr "conds" "use")
1213 (set_attr "predicable" "yes")
1214 (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
1215 (const_string "alu_shift_imm")
1216 (const_string "alu_shift_reg")))]
1219 ; transform ((x << y) - 1) to ~(~(x-1) << y) Where X is a constant.
1221 [(set (match_operand:SI 0 "s_register_operand" "")
1222 (plus:SI (ashift:SI (match_operand:SI 1 "const_int_operand" "")
1223 (match_operand:SI 2 "s_register_operand" ""))
1225 (clobber (match_operand:SI 3 "s_register_operand" ""))]
1227 [(set (match_dup 3) (match_dup 1))
1228 (set (match_dup 0) (not:SI (ashift:SI (match_dup 3) (match_dup 2))))]
1230 operands[1] = GEN_INT (~(INTVAL (operands[1]) - 1));
1233 (define_expand "addsf3"
1234 [(set (match_operand:SF 0 "s_register_operand" "")
1235 (plus:SF (match_operand:SF 1 "s_register_operand" "")
1236 (match_operand:SF 2 "s_register_operand" "")))]
1237 "TARGET_32BIT && TARGET_HARD_FLOAT"
1241 (define_expand "adddf3"
1242 [(set (match_operand:DF 0 "s_register_operand" "")
1243 (plus:DF (match_operand:DF 1 "s_register_operand" "")
1244 (match_operand:DF 2 "s_register_operand" "")))]
1245 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
1249 (define_expand "subdi3"
1251 [(set (match_operand:DI 0 "s_register_operand" "")
1252 (minus:DI (match_operand:DI 1 "s_register_operand" "")
1253 (match_operand:DI 2 "s_register_operand" "")))
1254 (clobber (reg:CC CC_REGNUM))])]
1259 if (!REG_P (operands[1]))
1260 operands[1] = force_reg (DImode, operands[1]);
1261 if (!REG_P (operands[2]))
1262 operands[2] = force_reg (DImode, operands[2]);
1267 (define_insn_and_split "*arm_subdi3"
1268 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r,&r")
1269 (minus:DI (match_operand:DI 1 "s_register_operand" "0,r,0")
1270 (match_operand:DI 2 "s_register_operand" "r,0,0")))
1271 (clobber (reg:CC CC_REGNUM))]
1272 "TARGET_32BIT && !TARGET_NEON"
1273 "#" ; "subs\\t%Q0, %Q1, %Q2\;sbc\\t%R0, %R1, %R2"
1274 "&& reload_completed"
1275 [(parallel [(set (reg:CC CC_REGNUM)
1276 (compare:CC (match_dup 1) (match_dup 2)))
1277 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1278 (set (match_dup 3) (minus:SI (minus:SI (match_dup 4) (match_dup 5))
1279 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1281 operands[3] = gen_highpart (SImode, operands[0]);
1282 operands[0] = gen_lowpart (SImode, operands[0]);
1283 operands[4] = gen_highpart (SImode, operands[1]);
1284 operands[1] = gen_lowpart (SImode, operands[1]);
1285 operands[5] = gen_highpart (SImode, operands[2]);
1286 operands[2] = gen_lowpart (SImode, operands[2]);
1288 [(set_attr "conds" "clob")
1289 (set_attr "length" "8")
1290 (set_attr "type" "multiple")]
1293 (define_insn_and_split "*subdi_di_zesidi"
1294 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1295 (minus:DI (match_operand:DI 1 "s_register_operand" "0,r")
1297 (match_operand:SI 2 "s_register_operand" "r,r"))))
1298 (clobber (reg:CC CC_REGNUM))]
1300 "#" ; "subs\\t%Q0, %Q1, %2\;sbc\\t%R0, %R1, #0"
1301 "&& reload_completed"
1302 [(parallel [(set (reg:CC CC_REGNUM)
1303 (compare:CC (match_dup 1) (match_dup 2)))
1304 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1305 (set (match_dup 3) (minus:SI (plus:SI (match_dup 4) (match_dup 5))
1306 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1308 operands[3] = gen_highpart (SImode, operands[0]);
1309 operands[0] = gen_lowpart (SImode, operands[0]);
1310 operands[4] = gen_highpart (SImode, operands[1]);
1311 operands[1] = gen_lowpart (SImode, operands[1]);
1312 operands[5] = GEN_INT (~0);
1314 [(set_attr "conds" "clob")
1315 (set_attr "length" "8")
1316 (set_attr "type" "multiple")]
1319 (define_insn_and_split "*subdi_di_sesidi"
1320 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1321 (minus:DI (match_operand:DI 1 "s_register_operand" "0,r")
1323 (match_operand:SI 2 "s_register_operand" "r,r"))))
1324 (clobber (reg:CC CC_REGNUM))]
1326 "#" ; "subs\\t%Q0, %Q1, %2\;sbc\\t%R0, %R1, %2, asr #31"
1327 "&& reload_completed"
1328 [(parallel [(set (reg:CC CC_REGNUM)
1329 (compare:CC (match_dup 1) (match_dup 2)))
1330 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1331 (set (match_dup 3) (minus:SI (minus:SI (match_dup 4)
1332 (ashiftrt:SI (match_dup 2)
1334 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1336 operands[3] = gen_highpart (SImode, operands[0]);
1337 operands[0] = gen_lowpart (SImode, operands[0]);
1338 operands[4] = gen_highpart (SImode, operands[1]);
1339 operands[1] = gen_lowpart (SImode, operands[1]);
1341 [(set_attr "conds" "clob")
1342 (set_attr "length" "8")
1343 (set_attr "type" "multiple")]
1346 (define_insn_and_split "*subdi_zesidi_di"
1347 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1348 (minus:DI (zero_extend:DI
1349 (match_operand:SI 2 "s_register_operand" "r,r"))
1350 (match_operand:DI 1 "s_register_operand" "0,r")))
1351 (clobber (reg:CC CC_REGNUM))]
1353 "#" ; "rsbs\\t%Q0, %Q1, %2\;rsc\\t%R0, %R1, #0"
1355 ; "subs\\t%Q0, %2, %Q1\;rsc\\t%R0, %R1, #0"
1356 "&& reload_completed"
1357 [(parallel [(set (reg:CC CC_REGNUM)
1358 (compare:CC (match_dup 2) (match_dup 1)))
1359 (set (match_dup 0) (minus:SI (match_dup 2) (match_dup 1)))])
1360 (set (match_dup 3) (minus:SI (minus:SI (const_int 0) (match_dup 4))
1361 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1363 operands[3] = gen_highpart (SImode, operands[0]);
1364 operands[0] = gen_lowpart (SImode, operands[0]);
1365 operands[4] = gen_highpart (SImode, operands[1]);
1366 operands[1] = gen_lowpart (SImode, operands[1]);
1368 [(set_attr "conds" "clob")
1369 (set_attr "length" "8")
1370 (set_attr "type" "multiple")]
1373 (define_insn_and_split "*subdi_sesidi_di"
1374 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1375 (minus:DI (sign_extend:DI
1376 (match_operand:SI 2 "s_register_operand" "r,r"))
1377 (match_operand:DI 1 "s_register_operand" "0,r")))
1378 (clobber (reg:CC CC_REGNUM))]
1380 "#" ; "rsbs\\t%Q0, %Q1, %2\;rsc\\t%R0, %R1, %2, asr #31"
1382 ; "subs\\t%Q0, %2, %Q1\;rsc\\t%R0, %R1, %2, asr #31"
1383 "&& reload_completed"
1384 [(parallel [(set (reg:CC CC_REGNUM)
1385 (compare:CC (match_dup 2) (match_dup 1)))
1386 (set (match_dup 0) (minus:SI (match_dup 2) (match_dup 1)))])
1387 (set (match_dup 3) (minus:SI (minus:SI
1388 (ashiftrt:SI (match_dup 2)
1391 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1393 operands[3] = gen_highpart (SImode, operands[0]);
1394 operands[0] = gen_lowpart (SImode, operands[0]);
1395 operands[4] = gen_highpart (SImode, operands[1]);
1396 operands[1] = gen_lowpart (SImode, operands[1]);
1398 [(set_attr "conds" "clob")
1399 (set_attr "length" "8")
1400 (set_attr "type" "multiple")]
1403 (define_insn_and_split "*subdi_zesidi_zesidi"
1404 [(set (match_operand:DI 0 "s_register_operand" "=r")
1405 (minus:DI (zero_extend:DI
1406 (match_operand:SI 1 "s_register_operand" "r"))
1408 (match_operand:SI 2 "s_register_operand" "r"))))
1409 (clobber (reg:CC CC_REGNUM))]
1411 "#" ; "subs\\t%Q0, %1, %2\;sbc\\t%R0, %1, %1"
1412 "&& reload_completed"
1413 [(parallel [(set (reg:CC CC_REGNUM)
1414 (compare:CC (match_dup 1) (match_dup 2)))
1415 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1416 (set (match_dup 3) (minus:SI (minus:SI (match_dup 1) (match_dup 1))
1417 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1419 operands[3] = gen_highpart (SImode, operands[0]);
1420 operands[0] = gen_lowpart (SImode, operands[0]);
1422 [(set_attr "conds" "clob")
1423 (set_attr "length" "8")
1424 (set_attr "type" "multiple")]
1427 (define_expand "subsi3"
1428 [(set (match_operand:SI 0 "s_register_operand" "")
1429 (minus:SI (match_operand:SI 1 "reg_or_int_operand" "")
1430 (match_operand:SI 2 "s_register_operand" "")))]
1433 if (CONST_INT_P (operands[1]))
1437 if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[1]), MINUS))
1438 operands[1] = force_reg (SImode, operands[1]);
1441 arm_split_constant (MINUS, SImode, NULL_RTX,
1442 INTVAL (operands[1]), operands[0],
1444 optimize && can_create_pseudo_p ());
1448 else /* TARGET_THUMB1 */
1449 operands[1] = force_reg (SImode, operands[1]);
1454 ; ??? Check Thumb-2 split length
1455 (define_insn_and_split "*arm_subsi3_insn"
1456 [(set (match_operand:SI 0 "s_register_operand" "=l,l ,l ,l ,r,r,r,rk,r")
1457 (minus:SI (match_operand:SI 1 "reg_or_int_operand" "l ,0 ,l ,Pz,I,r,r,k ,?n")
1458 (match_operand:SI 2 "reg_or_int_operand" "l ,Py,Pd,l ,r,I,r,r ,r")))]
1470 "&& (CONST_INT_P (operands[1])
1471 && !const_ok_for_arm (INTVAL (operands[1])))"
1472 [(clobber (const_int 0))]
1474 arm_split_constant (MINUS, SImode, curr_insn,
1475 INTVAL (operands[1]), operands[0], operands[2], 0);
1478 [(set_attr "length" "4,4,4,4,4,4,4,4,16")
1479 (set_attr "arch" "t2,t2,t2,t2,*,*,*,*,*")
1480 (set_attr "predicable" "yes")
1481 (set_attr "predicable_short_it" "yes,yes,yes,yes,no,no,no,no,no")
1482 (set_attr "type" "alu_sreg,alu_sreg,alu_sreg,alu_sreg,alu_imm,alu_imm,alu_sreg,alu_sreg,multiple")]
1486 [(match_scratch:SI 3 "r")
1487 (set (match_operand:SI 0 "arm_general_register_operand" "")
1488 (minus:SI (match_operand:SI 1 "const_int_operand" "")
1489 (match_operand:SI 2 "arm_general_register_operand" "")))]
1491 && !const_ok_for_arm (INTVAL (operands[1]))
1492 && const_ok_for_arm (~INTVAL (operands[1]))"
1493 [(set (match_dup 3) (match_dup 1))
1494 (set (match_dup 0) (minus:SI (match_dup 3) (match_dup 2)))]
1498 (define_insn "subsi3_compare0"
1499 [(set (reg:CC_NOOV CC_REGNUM)
1501 (minus:SI (match_operand:SI 1 "arm_rhs_operand" "r,r,I")
1502 (match_operand:SI 2 "arm_rhs_operand" "I,r,r"))
1504 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
1505 (minus:SI (match_dup 1) (match_dup 2)))]
1510 rsbs%?\\t%0, %2, %1"
1511 [(set_attr "conds" "set")
1512 (set_attr "type" "alus_imm,alus_sreg,alus_sreg")]
1515 (define_insn "subsi3_compare"
1516 [(set (reg:CC CC_REGNUM)
1517 (compare:CC (match_operand:SI 1 "arm_rhs_operand" "r,r,I")
1518 (match_operand:SI 2 "arm_rhs_operand" "I,r,r")))
1519 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
1520 (minus:SI (match_dup 1) (match_dup 2)))]
1525 rsbs%?\\t%0, %2, %1"
1526 [(set_attr "conds" "set")
1527 (set_attr "type" "alus_imm,alus_sreg,alus_sreg")]
1530 (define_expand "subsf3"
1531 [(set (match_operand:SF 0 "s_register_operand" "")
1532 (minus:SF (match_operand:SF 1 "s_register_operand" "")
1533 (match_operand:SF 2 "s_register_operand" "")))]
1534 "TARGET_32BIT && TARGET_HARD_FLOAT"
1538 (define_expand "subdf3"
1539 [(set (match_operand:DF 0 "s_register_operand" "")
1540 (minus:DF (match_operand:DF 1 "s_register_operand" "")
1541 (match_operand:DF 2 "s_register_operand" "")))]
1542 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
1547 ;; Multiplication insns
1549 (define_expand "mulhi3"
1550 [(set (match_operand:HI 0 "s_register_operand" "")
1551 (mult:HI (match_operand:HI 1 "s_register_operand" "")
1552 (match_operand:HI 2 "s_register_operand" "")))]
1553 "TARGET_DSP_MULTIPLY"
1556 rtx result = gen_reg_rtx (SImode);
1557 emit_insn (gen_mulhisi3 (result, operands[1], operands[2]));
1558 emit_move_insn (operands[0], gen_lowpart (HImode, result));
1563 (define_expand "mulsi3"
1564 [(set (match_operand:SI 0 "s_register_operand" "")
1565 (mult:SI (match_operand:SI 2 "s_register_operand" "")
1566 (match_operand:SI 1 "s_register_operand" "")))]
1571 ;; Use `&' and then `0' to prevent the operands 0 and 1 being the same
1572 (define_insn "*arm_mulsi3"
1573 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1574 (mult:SI (match_operand:SI 2 "s_register_operand" "r,r")
1575 (match_operand:SI 1 "s_register_operand" "%0,r")))]
1576 "TARGET_32BIT && !arm_arch6"
1577 "mul%?\\t%0, %2, %1"
1578 [(set_attr "type" "mul")
1579 (set_attr "predicable" "yes")]
1582 (define_insn "*arm_mulsi3_v6"
1583 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r")
1584 (mult:SI (match_operand:SI 1 "s_register_operand" "0,l,r")
1585 (match_operand:SI 2 "s_register_operand" "l,0,r")))]
1586 "TARGET_32BIT && arm_arch6"
1587 "mul%?\\t%0, %1, %2"
1588 [(set_attr "type" "mul")
1589 (set_attr "predicable" "yes")
1590 (set_attr "arch" "t2,t2,*")
1591 (set_attr "length" "4")
1592 (set_attr "predicable_short_it" "yes,yes,no")]
1595 (define_insn "*mulsi3_compare0"
1596 [(set (reg:CC_NOOV CC_REGNUM)
1597 (compare:CC_NOOV (mult:SI
1598 (match_operand:SI 2 "s_register_operand" "r,r")
1599 (match_operand:SI 1 "s_register_operand" "%0,r"))
1601 (set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1602 (mult:SI (match_dup 2) (match_dup 1)))]
1603 "TARGET_ARM && !arm_arch6"
1604 "muls%?\\t%0, %2, %1"
1605 [(set_attr "conds" "set")
1606 (set_attr "type" "muls")]
1609 (define_insn "*mulsi3_compare0_v6"
1610 [(set (reg:CC_NOOV CC_REGNUM)
1611 (compare:CC_NOOV (mult:SI
1612 (match_operand:SI 2 "s_register_operand" "r")
1613 (match_operand:SI 1 "s_register_operand" "r"))
1615 (set (match_operand:SI 0 "s_register_operand" "=r")
1616 (mult:SI (match_dup 2) (match_dup 1)))]
1617 "TARGET_ARM && arm_arch6 && optimize_size"
1618 "muls%?\\t%0, %2, %1"
1619 [(set_attr "conds" "set")
1620 (set_attr "type" "muls")]
1623 (define_insn "*mulsi_compare0_scratch"
1624 [(set (reg:CC_NOOV CC_REGNUM)
1625 (compare:CC_NOOV (mult:SI
1626 (match_operand:SI 2 "s_register_operand" "r,r")
1627 (match_operand:SI 1 "s_register_operand" "%0,r"))
1629 (clobber (match_scratch:SI 0 "=&r,&r"))]
1630 "TARGET_ARM && !arm_arch6"
1631 "muls%?\\t%0, %2, %1"
1632 [(set_attr "conds" "set")
1633 (set_attr "type" "muls")]
1636 (define_insn "*mulsi_compare0_scratch_v6"
1637 [(set (reg:CC_NOOV CC_REGNUM)
1638 (compare:CC_NOOV (mult:SI
1639 (match_operand:SI 2 "s_register_operand" "r")
1640 (match_operand:SI 1 "s_register_operand" "r"))
1642 (clobber (match_scratch:SI 0 "=r"))]
1643 "TARGET_ARM && arm_arch6 && optimize_size"
1644 "muls%?\\t%0, %2, %1"
1645 [(set_attr "conds" "set")
1646 (set_attr "type" "muls")]
1649 ;; Unnamed templates to match MLA instruction.
1651 (define_insn "*mulsi3addsi"
1652 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r,&r")
1654 (mult:SI (match_operand:SI 2 "s_register_operand" "r,r,r,r")
1655 (match_operand:SI 1 "s_register_operand" "%0,r,0,r"))
1656 (match_operand:SI 3 "s_register_operand" "r,r,0,0")))]
1657 "TARGET_32BIT && !arm_arch6"
1658 "mla%?\\t%0, %2, %1, %3"
1659 [(set_attr "type" "mla")
1660 (set_attr "predicable" "yes")]
1663 (define_insn "*mulsi3addsi_v6"
1664 [(set (match_operand:SI 0 "s_register_operand" "=r")
1666 (mult:SI (match_operand:SI 2 "s_register_operand" "r")
1667 (match_operand:SI 1 "s_register_operand" "r"))
1668 (match_operand:SI 3 "s_register_operand" "r")))]
1669 "TARGET_32BIT && arm_arch6"
1670 "mla%?\\t%0, %2, %1, %3"
1671 [(set_attr "type" "mla")
1672 (set_attr "predicable" "yes")
1673 (set_attr "predicable_short_it" "no")]
1676 (define_insn "*mulsi3addsi_compare0"
1677 [(set (reg:CC_NOOV CC_REGNUM)
1680 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
1681 (match_operand:SI 1 "s_register_operand" "%0,r,0,r"))
1682 (match_operand:SI 3 "s_register_operand" "r,r,0,0"))
1684 (set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r,&r")
1685 (plus:SI (mult:SI (match_dup 2) (match_dup 1))
1687 "TARGET_ARM && arm_arch6"
1688 "mlas%?\\t%0, %2, %1, %3"
1689 [(set_attr "conds" "set")
1690 (set_attr "type" "mlas")]
1693 (define_insn "*mulsi3addsi_compare0_v6"
1694 [(set (reg:CC_NOOV CC_REGNUM)
1697 (match_operand:SI 2 "s_register_operand" "r")
1698 (match_operand:SI 1 "s_register_operand" "r"))
1699 (match_operand:SI 3 "s_register_operand" "r"))
1701 (set (match_operand:SI 0 "s_register_operand" "=r")
1702 (plus:SI (mult:SI (match_dup 2) (match_dup 1))
1704 "TARGET_ARM && arm_arch6 && optimize_size"
1705 "mlas%?\\t%0, %2, %1, %3"
1706 [(set_attr "conds" "set")
1707 (set_attr "type" "mlas")]
1710 (define_insn "*mulsi3addsi_compare0_scratch"
1711 [(set (reg:CC_NOOV CC_REGNUM)
1714 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
1715 (match_operand:SI 1 "s_register_operand" "%0,r,0,r"))
1716 (match_operand:SI 3 "s_register_operand" "?r,r,0,0"))
1718 (clobber (match_scratch:SI 0 "=&r,&r,&r,&r"))]
1719 "TARGET_ARM && !arm_arch6"
1720 "mlas%?\\t%0, %2, %1, %3"
1721 [(set_attr "conds" "set")
1722 (set_attr "type" "mlas")]
1725 (define_insn "*mulsi3addsi_compare0_scratch_v6"
1726 [(set (reg:CC_NOOV CC_REGNUM)
1729 (match_operand:SI 2 "s_register_operand" "r")
1730 (match_operand:SI 1 "s_register_operand" "r"))
1731 (match_operand:SI 3 "s_register_operand" "r"))
1733 (clobber (match_scratch:SI 0 "=r"))]
1734 "TARGET_ARM && arm_arch6 && optimize_size"
1735 "mlas%?\\t%0, %2, %1, %3"
1736 [(set_attr "conds" "set")
1737 (set_attr "type" "mlas")]
1740 (define_insn "*mulsi3subsi"
1741 [(set (match_operand:SI 0 "s_register_operand" "=r")
1743 (match_operand:SI 3 "s_register_operand" "r")
1744 (mult:SI (match_operand:SI 2 "s_register_operand" "r")
1745 (match_operand:SI 1 "s_register_operand" "r"))))]
1746 "TARGET_32BIT && arm_arch_thumb2"
1747 "mls%?\\t%0, %2, %1, %3"
1748 [(set_attr "type" "mla")
1749 (set_attr "predicable" "yes")
1750 (set_attr "predicable_short_it" "no")]
1753 (define_expand "maddsidi4"
1754 [(set (match_operand:DI 0 "s_register_operand" "")
1757 (sign_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1758 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1759 (match_operand:DI 3 "s_register_operand" "")))]
1760 "TARGET_32BIT && arm_arch3m"
1763 (define_insn "*mulsidi3adddi"
1764 [(set (match_operand:DI 0 "s_register_operand" "=&r")
1767 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "%r"))
1768 (sign_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1769 (match_operand:DI 1 "s_register_operand" "0")))]
1770 "TARGET_32BIT && arm_arch3m && !arm_arch6"
1771 "smlal%?\\t%Q0, %R0, %3, %2"
1772 [(set_attr "type" "smlal")
1773 (set_attr "predicable" "yes")]
1776 (define_insn "*mulsidi3adddi_v6"
1777 [(set (match_operand:DI 0 "s_register_operand" "=r")
1780 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r"))
1781 (sign_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1782 (match_operand:DI 1 "s_register_operand" "0")))]
1783 "TARGET_32BIT && arm_arch6"
1784 "smlal%?\\t%Q0, %R0, %3, %2"
1785 [(set_attr "type" "smlal")
1786 (set_attr "predicable" "yes")
1787 (set_attr "predicable_short_it" "no")]
1790 ;; 32x32->64 widening multiply.
1791 ;; As with mulsi3, the only difference between the v3-5 and v6+
1792 ;; versions of these patterns is the requirement that the output not
1793 ;; overlap the inputs, but that still means we have to have a named
1794 ;; expander and two different starred insns.
1796 (define_expand "mulsidi3"
1797 [(set (match_operand:DI 0 "s_register_operand" "")
1799 (sign_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1800 (sign_extend:DI (match_operand:SI 2 "s_register_operand" ""))))]
1801 "TARGET_32BIT && arm_arch3m"
1805 (define_insn "*mulsidi3_nov6"
1806 [(set (match_operand:DI 0 "s_register_operand" "=&r")
1808 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "%r"))
1809 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1810 "TARGET_32BIT && arm_arch3m && !arm_arch6"
1811 "smull%?\\t%Q0, %R0, %1, %2"
1812 [(set_attr "type" "smull")
1813 (set_attr "predicable" "yes")]
1816 (define_insn "*mulsidi3_v6"
1817 [(set (match_operand:DI 0 "s_register_operand" "=r")
1819 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1820 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1821 "TARGET_32BIT && arm_arch6"
1822 "smull%?\\t%Q0, %R0, %1, %2"
1823 [(set_attr "type" "smull")
1824 (set_attr "predicable" "yes")
1825 (set_attr "predicable_short_it" "no")]
1828 (define_expand "umulsidi3"
1829 [(set (match_operand:DI 0 "s_register_operand" "")
1831 (zero_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1832 (zero_extend:DI (match_operand:SI 2 "s_register_operand" ""))))]
1833 "TARGET_32BIT && arm_arch3m"
1837 (define_insn "*umulsidi3_nov6"
1838 [(set (match_operand:DI 0 "s_register_operand" "=&r")
1840 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "%r"))
1841 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1842 "TARGET_32BIT && arm_arch3m && !arm_arch6"
1843 "umull%?\\t%Q0, %R0, %1, %2"
1844 [(set_attr "type" "umull")
1845 (set_attr "predicable" "yes")]
1848 (define_insn "*umulsidi3_v6"
1849 [(set (match_operand:DI 0 "s_register_operand" "=r")
1851 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1852 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1853 "TARGET_32BIT && arm_arch6"
1854 "umull%?\\t%Q0, %R0, %1, %2"
1855 [(set_attr "type" "umull")
1856 (set_attr "predicable" "yes")
1857 (set_attr "predicable_short_it" "no")]
1860 (define_expand "umaddsidi4"
1861 [(set (match_operand:DI 0 "s_register_operand" "")
1864 (zero_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1865 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1866 (match_operand:DI 3 "s_register_operand" "")))]
1867 "TARGET_32BIT && arm_arch3m"
1870 (define_insn "*umulsidi3adddi"
1871 [(set (match_operand:DI 0 "s_register_operand" "=&r")
1874 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "%r"))
1875 (zero_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1876 (match_operand:DI 1 "s_register_operand" "0")))]
1877 "TARGET_32BIT && arm_arch3m && !arm_arch6"
1878 "umlal%?\\t%Q0, %R0, %3, %2"
1879 [(set_attr "type" "umlal")
1880 (set_attr "predicable" "yes")]
1883 (define_insn "*umulsidi3adddi_v6"
1884 [(set (match_operand:DI 0 "s_register_operand" "=r")
1887 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r"))
1888 (zero_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1889 (match_operand:DI 1 "s_register_operand" "0")))]
1890 "TARGET_32BIT && arm_arch6"
1891 "umlal%?\\t%Q0, %R0, %3, %2"
1892 [(set_attr "type" "umlal")
1893 (set_attr "predicable" "yes")
1894 (set_attr "predicable_short_it" "no")]
1897 (define_expand "smulsi3_highpart"
1899 [(set (match_operand:SI 0 "s_register_operand" "")
1903 (sign_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1904 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1906 (clobber (match_scratch:SI 3 ""))])]
1907 "TARGET_32BIT && arm_arch3m"
1911 (define_insn "*smulsi3_highpart_nov6"
1912 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1916 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "%0,r"))
1917 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r,r")))
1919 (clobber (match_scratch:SI 3 "=&r,&r"))]
1920 "TARGET_32BIT && arm_arch3m && !arm_arch6"
1921 "smull%?\\t%3, %0, %2, %1"
1922 [(set_attr "type" "smull")
1923 (set_attr "predicable" "yes")]
1926 (define_insn "*smulsi3_highpart_v6"
1927 [(set (match_operand:SI 0 "s_register_operand" "=r")
1931 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1932 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r")))
1934 (clobber (match_scratch:SI 3 "=r"))]
1935 "TARGET_32BIT && arm_arch6"
1936 "smull%?\\t%3, %0, %2, %1"
1937 [(set_attr "type" "smull")
1938 (set_attr "predicable" "yes")
1939 (set_attr "predicable_short_it" "no")]
1942 (define_expand "umulsi3_highpart"
1944 [(set (match_operand:SI 0 "s_register_operand" "")
1948 (zero_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1949 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1951 (clobber (match_scratch:SI 3 ""))])]
1952 "TARGET_32BIT && arm_arch3m"
1956 (define_insn "*umulsi3_highpart_nov6"
1957 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1961 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "%0,r"))
1962 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r,r")))
1964 (clobber (match_scratch:SI 3 "=&r,&r"))]
1965 "TARGET_32BIT && arm_arch3m && !arm_arch6"
1966 "umull%?\\t%3, %0, %2, %1"
1967 [(set_attr "type" "umull")
1968 (set_attr "predicable" "yes")]
1971 (define_insn "*umulsi3_highpart_v6"
1972 [(set (match_operand:SI 0 "s_register_operand" "=r")
1976 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1977 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r")))
1979 (clobber (match_scratch:SI 3 "=r"))]
1980 "TARGET_32BIT && arm_arch6"
1981 "umull%?\\t%3, %0, %2, %1"
1982 [(set_attr "type" "umull")
1983 (set_attr "predicable" "yes")
1984 (set_attr "predicable_short_it" "no")]
1987 (define_insn "mulhisi3"
1988 [(set (match_operand:SI 0 "s_register_operand" "=r")
1989 (mult:SI (sign_extend:SI
1990 (match_operand:HI 1 "s_register_operand" "%r"))
1992 (match_operand:HI 2 "s_register_operand" "r"))))]
1993 "TARGET_DSP_MULTIPLY"
1994 "smulbb%?\\t%0, %1, %2"
1995 [(set_attr "type" "smulxy")
1996 (set_attr "predicable" "yes")]
1999 (define_insn "*mulhisi3tb"
2000 [(set (match_operand:SI 0 "s_register_operand" "=r")
2001 (mult:SI (ashiftrt:SI
2002 (match_operand:SI 1 "s_register_operand" "r")
2005 (match_operand:HI 2 "s_register_operand" "r"))))]
2006 "TARGET_DSP_MULTIPLY"
2007 "smultb%?\\t%0, %1, %2"
2008 [(set_attr "type" "smulxy")
2009 (set_attr "predicable" "yes")
2010 (set_attr "predicable_short_it" "no")]
2013 (define_insn "*mulhisi3bt"
2014 [(set (match_operand:SI 0 "s_register_operand" "=r")
2015 (mult:SI (sign_extend:SI
2016 (match_operand:HI 1 "s_register_operand" "r"))
2018 (match_operand:SI 2 "s_register_operand" "r")
2020 "TARGET_DSP_MULTIPLY"
2021 "smulbt%?\\t%0, %1, %2"
2022 [(set_attr "type" "smulxy")
2023 (set_attr "predicable" "yes")
2024 (set_attr "predicable_short_it" "no")]
2027 (define_insn "*mulhisi3tt"
2028 [(set (match_operand:SI 0 "s_register_operand" "=r")
2029 (mult:SI (ashiftrt:SI
2030 (match_operand:SI 1 "s_register_operand" "r")
2033 (match_operand:SI 2 "s_register_operand" "r")
2035 "TARGET_DSP_MULTIPLY"
2036 "smultt%?\\t%0, %1, %2"
2037 [(set_attr "type" "smulxy")
2038 (set_attr "predicable" "yes")
2039 (set_attr "predicable_short_it" "no")]
2042 (define_insn "maddhisi4"
2043 [(set (match_operand:SI 0 "s_register_operand" "=r")
2044 (plus:SI (mult:SI (sign_extend:SI
2045 (match_operand:HI 1 "s_register_operand" "r"))
2047 (match_operand:HI 2 "s_register_operand" "r")))
2048 (match_operand:SI 3 "s_register_operand" "r")))]
2049 "TARGET_DSP_MULTIPLY"
2050 "smlabb%?\\t%0, %1, %2, %3"
2051 [(set_attr "type" "smlaxy")
2052 (set_attr "predicable" "yes")
2053 (set_attr "predicable_short_it" "no")]
2056 ;; Note: there is no maddhisi4ibt because this one is canonical form
2057 (define_insn "*maddhisi4tb"
2058 [(set (match_operand:SI 0 "s_register_operand" "=r")
2059 (plus:SI (mult:SI (ashiftrt:SI
2060 (match_operand:SI 1 "s_register_operand" "r")
2063 (match_operand:HI 2 "s_register_operand" "r")))
2064 (match_operand:SI 3 "s_register_operand" "r")))]
2065 "TARGET_DSP_MULTIPLY"
2066 "smlatb%?\\t%0, %1, %2, %3"
2067 [(set_attr "type" "smlaxy")
2068 (set_attr "predicable" "yes")
2069 (set_attr "predicable_short_it" "no")]
2072 (define_insn "*maddhisi4tt"
2073 [(set (match_operand:SI 0 "s_register_operand" "=r")
2074 (plus:SI (mult:SI (ashiftrt:SI
2075 (match_operand:SI 1 "s_register_operand" "r")
2078 (match_operand:SI 2 "s_register_operand" "r")
2080 (match_operand:SI 3 "s_register_operand" "r")))]
2081 "TARGET_DSP_MULTIPLY"
2082 "smlatt%?\\t%0, %1, %2, %3"
2083 [(set_attr "type" "smlaxy")
2084 (set_attr "predicable" "yes")
2085 (set_attr "predicable_short_it" "no")]
2088 (define_insn "maddhidi4"
2089 [(set (match_operand:DI 0 "s_register_operand" "=r")
2091 (mult:DI (sign_extend:DI
2092 (match_operand:HI 1 "s_register_operand" "r"))
2094 (match_operand:HI 2 "s_register_operand" "r")))
2095 (match_operand:DI 3 "s_register_operand" "0")))]
2096 "TARGET_DSP_MULTIPLY"
2097 "smlalbb%?\\t%Q0, %R0, %1, %2"
2098 [(set_attr "type" "smlalxy")
2099 (set_attr "predicable" "yes")
2100 (set_attr "predicable_short_it" "no")])
2102 ;; Note: there is no maddhidi4ibt because this one is canonical form
2103 (define_insn "*maddhidi4tb"
2104 [(set (match_operand:DI 0 "s_register_operand" "=r")
2106 (mult:DI (sign_extend:DI
2108 (match_operand:SI 1 "s_register_operand" "r")
2111 (match_operand:HI 2 "s_register_operand" "r")))
2112 (match_operand:DI 3 "s_register_operand" "0")))]
2113 "TARGET_DSP_MULTIPLY"
2114 "smlaltb%?\\t%Q0, %R0, %1, %2"
2115 [(set_attr "type" "smlalxy")
2116 (set_attr "predicable" "yes")
2117 (set_attr "predicable_short_it" "no")])
2119 (define_insn "*maddhidi4tt"
2120 [(set (match_operand:DI 0 "s_register_operand" "=r")
2122 (mult:DI (sign_extend:DI
2124 (match_operand:SI 1 "s_register_operand" "r")
2128 (match_operand:SI 2 "s_register_operand" "r")
2130 (match_operand:DI 3 "s_register_operand" "0")))]
2131 "TARGET_DSP_MULTIPLY"
2132 "smlaltt%?\\t%Q0, %R0, %1, %2"
2133 [(set_attr "type" "smlalxy")
2134 (set_attr "predicable" "yes")
2135 (set_attr "predicable_short_it" "no")])
2137 (define_expand "mulsf3"
2138 [(set (match_operand:SF 0 "s_register_operand" "")
2139 (mult:SF (match_operand:SF 1 "s_register_operand" "")
2140 (match_operand:SF 2 "s_register_operand" "")))]
2141 "TARGET_32BIT && TARGET_HARD_FLOAT"
2145 (define_expand "muldf3"
2146 [(set (match_operand:DF 0 "s_register_operand" "")
2147 (mult:DF (match_operand:DF 1 "s_register_operand" "")
2148 (match_operand:DF 2 "s_register_operand" "")))]
2149 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
2155 (define_expand "divsf3"
2156 [(set (match_operand:SF 0 "s_register_operand" "")
2157 (div:SF (match_operand:SF 1 "s_register_operand" "")
2158 (match_operand:SF 2 "s_register_operand" "")))]
2159 "TARGET_32BIT && TARGET_HARD_FLOAT"
2162 (define_expand "divdf3"
2163 [(set (match_operand:DF 0 "s_register_operand" "")
2164 (div:DF (match_operand:DF 1 "s_register_operand" "")
2165 (match_operand:DF 2 "s_register_operand" "")))]
2166 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
2169 ;; Boolean and,ior,xor insns
2171 ;; Split up double word logical operations
2173 ;; Split up simple DImode logical operations. Simply perform the logical
2174 ;; operation on the upper and lower halves of the registers.
2176 [(set (match_operand:DI 0 "s_register_operand" "")
2177 (match_operator:DI 6 "logical_binary_operator"
2178 [(match_operand:DI 1 "s_register_operand" "")
2179 (match_operand:DI 2 "s_register_operand" "")]))]
2180 "TARGET_32BIT && reload_completed
2181 && ! (TARGET_NEON && IS_VFP_REGNUM (REGNO (operands[0])))
2182 && ! IS_IWMMXT_REGNUM (REGNO (operands[0]))"
2183 [(set (match_dup 0) (match_op_dup:SI 6 [(match_dup 1) (match_dup 2)]))
2184 (set (match_dup 3) (match_op_dup:SI 6 [(match_dup 4) (match_dup 5)]))]
2187 operands[3] = gen_highpart (SImode, operands[0]);
2188 operands[0] = gen_lowpart (SImode, operands[0]);
2189 operands[4] = gen_highpart (SImode, operands[1]);
2190 operands[1] = gen_lowpart (SImode, operands[1]);
2191 operands[5] = gen_highpart (SImode, operands[2]);
2192 operands[2] = gen_lowpart (SImode, operands[2]);
2197 [(set (match_operand:DI 0 "s_register_operand" "")
2198 (match_operator:DI 6 "logical_binary_operator"
2199 [(sign_extend:DI (match_operand:SI 2 "s_register_operand" ""))
2200 (match_operand:DI 1 "s_register_operand" "")]))]
2201 "TARGET_32BIT && reload_completed"
2202 [(set (match_dup 0) (match_op_dup:SI 6 [(match_dup 1) (match_dup 2)]))
2203 (set (match_dup 3) (match_op_dup:SI 6
2204 [(ashiftrt:SI (match_dup 2) (const_int 31))
2208 operands[3] = gen_highpart (SImode, operands[0]);
2209 operands[0] = gen_lowpart (SImode, operands[0]);
2210 operands[4] = gen_highpart (SImode, operands[1]);
2211 operands[1] = gen_lowpart (SImode, operands[1]);
2212 operands[5] = gen_highpart (SImode, operands[2]);
2213 operands[2] = gen_lowpart (SImode, operands[2]);
2217 ;; The zero extend of operand 2 means we can just copy the high part of
2218 ;; operand1 into operand0.
2220 [(set (match_operand:DI 0 "s_register_operand" "")
2222 (zero_extend:DI (match_operand:SI 2 "s_register_operand" ""))
2223 (match_operand:DI 1 "s_register_operand" "")))]
2224 "TARGET_32BIT && operands[0] != operands[1] && reload_completed"
2225 [(set (match_dup 0) (ior:SI (match_dup 1) (match_dup 2)))
2226 (set (match_dup 3) (match_dup 4))]
2229 operands[4] = gen_highpart (SImode, operands[1]);
2230 operands[3] = gen_highpart (SImode, operands[0]);
2231 operands[0] = gen_lowpart (SImode, operands[0]);
2232 operands[1] = gen_lowpart (SImode, operands[1]);
2236 ;; The zero extend of operand 2 means we can just copy the high part of
2237 ;; operand1 into operand0.
2239 [(set (match_operand:DI 0 "s_register_operand" "")
2241 (zero_extend:DI (match_operand:SI 2 "s_register_operand" ""))
2242 (match_operand:DI 1 "s_register_operand" "")))]
2243 "TARGET_32BIT && operands[0] != operands[1] && reload_completed"
2244 [(set (match_dup 0) (xor:SI (match_dup 1) (match_dup 2)))
2245 (set (match_dup 3) (match_dup 4))]
2248 operands[4] = gen_highpart (SImode, operands[1]);
2249 operands[3] = gen_highpart (SImode, operands[0]);
2250 operands[0] = gen_lowpart (SImode, operands[0]);
2251 operands[1] = gen_lowpart (SImode, operands[1]);
2255 (define_expand "anddi3"
2256 [(set (match_operand:DI 0 "s_register_operand" "")
2257 (and:DI (match_operand:DI 1 "s_register_operand" "")
2258 (match_operand:DI 2 "neon_inv_logic_op2" "")))]
2263 (define_insn_and_split "*anddi3_insn"
2264 [(set (match_operand:DI 0 "s_register_operand" "=w,w ,&r,&r,&r,&r,?w,?w")
2265 (and:DI (match_operand:DI 1 "s_register_operand" "%w,0 ,0 ,r ,0 ,r ,w ,0")
2266 (match_operand:DI 2 "arm_anddi_operand_neon" "w ,DL,r ,r ,De,De,w ,DL")))]
2267 "TARGET_32BIT && !TARGET_IWMMXT"
2269 switch (which_alternative)
2271 case 0: /* fall through */
2272 case 6: return "vand\t%P0, %P1, %P2";
2273 case 1: /* fall through */
2274 case 7: return neon_output_logic_immediate ("vand", &operands[2],
2275 DImode, 1, VALID_NEON_QREG_MODE (DImode));
2279 case 5: /* fall through */
2281 default: gcc_unreachable ();
2284 "TARGET_32BIT && !TARGET_IWMMXT && reload_completed
2285 && !(IS_VFP_REGNUM (REGNO (operands[0])))"
2286 [(set (match_dup 3) (match_dup 4))
2287 (set (match_dup 5) (match_dup 6))]
2290 operands[3] = gen_lowpart (SImode, operands[0]);
2291 operands[5] = gen_highpart (SImode, operands[0]);
2293 operands[4] = simplify_gen_binary (AND, SImode,
2294 gen_lowpart (SImode, operands[1]),
2295 gen_lowpart (SImode, operands[2]));
2296 operands[6] = simplify_gen_binary (AND, SImode,
2297 gen_highpart (SImode, operands[1]),
2298 gen_highpart_mode (SImode, DImode, operands[2]));
2301 [(set_attr "type" "neon_logic,neon_logic,multiple,multiple,\
2302 multiple,multiple,neon_logic,neon_logic")
2303 (set_attr "arch" "neon_for_64bits,neon_for_64bits,*,*,*,*,
2304 avoid_neon_for_64bits,avoid_neon_for_64bits")
2305 (set_attr "length" "*,*,8,8,8,8,*,*")
2309 (define_insn_and_split "*anddi_zesidi_di"
2310 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2311 (and:DI (zero_extend:DI
2312 (match_operand:SI 2 "s_register_operand" "r,r"))
2313 (match_operand:DI 1 "s_register_operand" "0,r")))]
2316 "TARGET_32BIT && reload_completed"
2317 ; The zero extend of operand 2 clears the high word of the output
2319 [(set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))
2320 (set (match_dup 3) (const_int 0))]
2323 operands[3] = gen_highpart (SImode, operands[0]);
2324 operands[0] = gen_lowpart (SImode, operands[0]);
2325 operands[1] = gen_lowpart (SImode, operands[1]);
2327 [(set_attr "length" "8")
2328 (set_attr "type" "multiple")]
2331 (define_insn "*anddi_sesdi_di"
2332 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2333 (and:DI (sign_extend:DI
2334 (match_operand:SI 2 "s_register_operand" "r,r"))
2335 (match_operand:DI 1 "s_register_operand" "0,r")))]
2338 [(set_attr "length" "8")
2339 (set_attr "type" "multiple")]
2342 (define_expand "andsi3"
2343 [(set (match_operand:SI 0 "s_register_operand" "")
2344 (and:SI (match_operand:SI 1 "s_register_operand" "")
2345 (match_operand:SI 2 "reg_or_int_operand" "")))]
2350 if (CONST_INT_P (operands[2]))
2352 if (INTVAL (operands[2]) == 255 && arm_arch6)
2354 operands[1] = convert_to_mode (QImode, operands[1], 1);
2355 emit_insn (gen_thumb2_zero_extendqisi2_v6 (operands[0],
2359 else if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[2]), AND))
2360 operands[2] = force_reg (SImode, operands[2]);
2363 arm_split_constant (AND, SImode, NULL_RTX,
2364 INTVAL (operands[2]), operands[0],
2366 optimize && can_create_pseudo_p ());
2372 else /* TARGET_THUMB1 */
2374 if (!CONST_INT_P (operands[2]))
2376 rtx tmp = force_reg (SImode, operands[2]);
2377 if (rtx_equal_p (operands[0], operands[1]))
2381 operands[2] = operands[1];
2389 if (((unsigned HOST_WIDE_INT) ~INTVAL (operands[2])) < 256)
2391 operands[2] = force_reg (SImode,
2392 GEN_INT (~INTVAL (operands[2])));
2394 emit_insn (gen_thumb1_bicsi3 (operands[0], operands[2], operands[1]));
2399 for (i = 9; i <= 31; i++)
2401 if ((HOST_WIDE_INT_1 << i) - 1 == INTVAL (operands[2]))
2403 emit_insn (gen_extzv (operands[0], operands[1], GEN_INT (i),
2407 else if ((HOST_WIDE_INT_1 << i) - 1
2408 == ~INTVAL (operands[2]))
2410 rtx shift = GEN_INT (i);
2411 rtx reg = gen_reg_rtx (SImode);
2413 emit_insn (gen_lshrsi3 (reg, operands[1], shift));
2414 emit_insn (gen_ashlsi3 (operands[0], reg, shift));
2420 operands[2] = force_reg (SImode, operands[2]);
2426 ; ??? Check split length for Thumb-2
2427 (define_insn_and_split "*arm_andsi3_insn"
2428 [(set (match_operand:SI 0 "s_register_operand" "=r,l,r,r,r")
2429 (and:SI (match_operand:SI 1 "s_register_operand" "%r,0,r,r,r")
2430 (match_operand:SI 2 "reg_or_int_operand" "I,l,K,r,?n")))]
2435 bic%?\\t%0, %1, #%B2
2439 && CONST_INT_P (operands[2])
2440 && !(const_ok_for_arm (INTVAL (operands[2]))
2441 || const_ok_for_arm (~INTVAL (operands[2])))"
2442 [(clobber (const_int 0))]
2444 arm_split_constant (AND, SImode, curr_insn,
2445 INTVAL (operands[2]), operands[0], operands[1], 0);
2448 [(set_attr "length" "4,4,4,4,16")
2449 (set_attr "predicable" "yes")
2450 (set_attr "predicable_short_it" "no,yes,no,no,no")
2451 (set_attr "type" "logic_imm,logic_imm,logic_reg,logic_reg,logic_imm")]
2454 (define_insn "*andsi3_compare0"
2455 [(set (reg:CC_NOOV CC_REGNUM)
2457 (and:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
2458 (match_operand:SI 2 "arm_not_operand" "I,K,r"))
2460 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
2461 (and:SI (match_dup 1) (match_dup 2)))]
2465 bics%?\\t%0, %1, #%B2
2466 ands%?\\t%0, %1, %2"
2467 [(set_attr "conds" "set")
2468 (set_attr "type" "logics_imm,logics_imm,logics_reg")]
2471 (define_insn "*andsi3_compare0_scratch"
2472 [(set (reg:CC_NOOV CC_REGNUM)
2474 (and:SI (match_operand:SI 0 "s_register_operand" "r,r,r")
2475 (match_operand:SI 1 "arm_not_operand" "I,K,r"))
2477 (clobber (match_scratch:SI 2 "=X,r,X"))]
2481 bics%?\\t%2, %0, #%B1
2483 [(set_attr "conds" "set")
2484 (set_attr "type" "logics_imm,logics_imm,logics_reg")]
2487 (define_insn "*zeroextractsi_compare0_scratch"
2488 [(set (reg:CC_NOOV CC_REGNUM)
2489 (compare:CC_NOOV (zero_extract:SI
2490 (match_operand:SI 0 "s_register_operand" "r")
2491 (match_operand 1 "const_int_operand" "n")
2492 (match_operand 2 "const_int_operand" "n"))
2495 && (INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) < 32
2496 && INTVAL (operands[1]) > 0
2497 && INTVAL (operands[1]) + (INTVAL (operands[2]) & 1) <= 8
2498 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32)"
2500 operands[1] = GEN_INT (((1 << INTVAL (operands[1])) - 1)
2501 << INTVAL (operands[2]));
2502 output_asm_insn (\"tst%?\\t%0, %1\", operands);
2505 [(set_attr "conds" "set")
2506 (set_attr "predicable" "yes")
2507 (set_attr "predicable_short_it" "no")
2508 (set_attr "type" "logics_imm")]
2511 (define_insn_and_split "*ne_zeroextractsi"
2512 [(set (match_operand:SI 0 "s_register_operand" "=r")
2513 (ne:SI (zero_extract:SI
2514 (match_operand:SI 1 "s_register_operand" "r")
2515 (match_operand:SI 2 "const_int_operand" "n")
2516 (match_operand:SI 3 "const_int_operand" "n"))
2518 (clobber (reg:CC CC_REGNUM))]
2520 && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2521 && INTVAL (operands[2]) > 0
2522 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2523 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)"
2526 && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2527 && INTVAL (operands[2]) > 0
2528 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2529 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)"
2530 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2531 (compare:CC_NOOV (and:SI (match_dup 1) (match_dup 2))
2533 (set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))])
2535 (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2536 (match_dup 0) (const_int 1)))]
2538 operands[2] = GEN_INT (((1 << INTVAL (operands[2])) - 1)
2539 << INTVAL (operands[3]));
2541 [(set_attr "conds" "clob")
2542 (set (attr "length")
2543 (if_then_else (eq_attr "is_thumb" "yes")
2546 (set_attr "type" "multiple")]
2549 (define_insn_and_split "*ne_zeroextractsi_shifted"
2550 [(set (match_operand:SI 0 "s_register_operand" "=r")
2551 (ne:SI (zero_extract:SI
2552 (match_operand:SI 1 "s_register_operand" "r")
2553 (match_operand:SI 2 "const_int_operand" "n")
2556 (clobber (reg:CC CC_REGNUM))]
2560 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2561 (compare:CC_NOOV (ashift:SI (match_dup 1) (match_dup 2))
2563 (set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))])
2565 (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2566 (match_dup 0) (const_int 1)))]
2568 operands[2] = GEN_INT (32 - INTVAL (operands[2]));
2570 [(set_attr "conds" "clob")
2571 (set_attr "length" "8")
2572 (set_attr "type" "multiple")]
2575 (define_insn_and_split "*ite_ne_zeroextractsi"
2576 [(set (match_operand:SI 0 "s_register_operand" "=r")
2577 (if_then_else:SI (ne (zero_extract:SI
2578 (match_operand:SI 1 "s_register_operand" "r")
2579 (match_operand:SI 2 "const_int_operand" "n")
2580 (match_operand:SI 3 "const_int_operand" "n"))
2582 (match_operand:SI 4 "arm_not_operand" "rIK")
2584 (clobber (reg:CC CC_REGNUM))]
2586 && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2587 && INTVAL (operands[2]) > 0
2588 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2589 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)
2590 && !reg_overlap_mentioned_p (operands[0], operands[4])"
2593 && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2594 && INTVAL (operands[2]) > 0
2595 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2596 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)
2597 && !reg_overlap_mentioned_p (operands[0], operands[4])"
2598 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2599 (compare:CC_NOOV (and:SI (match_dup 1) (match_dup 2))
2601 (set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))])
2603 (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2604 (match_dup 0) (match_dup 4)))]
2606 operands[2] = GEN_INT (((1 << INTVAL (operands[2])) - 1)
2607 << INTVAL (operands[3]));
2609 [(set_attr "conds" "clob")
2610 (set_attr "length" "8")
2611 (set_attr "type" "multiple")]
2614 (define_insn_and_split "*ite_ne_zeroextractsi_shifted"
2615 [(set (match_operand:SI 0 "s_register_operand" "=r")
2616 (if_then_else:SI (ne (zero_extract:SI
2617 (match_operand:SI 1 "s_register_operand" "r")
2618 (match_operand:SI 2 "const_int_operand" "n")
2621 (match_operand:SI 3 "arm_not_operand" "rIK")
2623 (clobber (reg:CC CC_REGNUM))]
2624 "TARGET_ARM && !reg_overlap_mentioned_p (operands[0], operands[3])"
2626 "TARGET_ARM && !reg_overlap_mentioned_p (operands[0], operands[3])"
2627 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2628 (compare:CC_NOOV (ashift:SI (match_dup 1) (match_dup 2))
2630 (set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))])
2632 (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2633 (match_dup 0) (match_dup 3)))]
2635 operands[2] = GEN_INT (32 - INTVAL (operands[2]));
2637 [(set_attr "conds" "clob")
2638 (set_attr "length" "8")
2639 (set_attr "type" "multiple")]
2642 ;; ??? Use Thumb-2 has bitfield insert/extract instructions.
2644 [(set (match_operand:SI 0 "s_register_operand" "")
2645 (match_operator:SI 1 "shiftable_operator"
2646 [(zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
2647 (match_operand:SI 3 "const_int_operand" "")
2648 (match_operand:SI 4 "const_int_operand" ""))
2649 (match_operand:SI 5 "s_register_operand" "")]))
2650 (clobber (match_operand:SI 6 "s_register_operand" ""))]
2652 [(set (match_dup 6) (ashift:SI (match_dup 2) (match_dup 3)))
2655 [(lshiftrt:SI (match_dup 6) (match_dup 4))
2658 HOST_WIDE_INT temp = INTVAL (operands[3]);
2660 operands[3] = GEN_INT (32 - temp - INTVAL (operands[4]));
2661 operands[4] = GEN_INT (32 - temp);
2666 [(set (match_operand:SI 0 "s_register_operand" "")
2667 (match_operator:SI 1 "shiftable_operator"
2668 [(sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
2669 (match_operand:SI 3 "const_int_operand" "")
2670 (match_operand:SI 4 "const_int_operand" ""))
2671 (match_operand:SI 5 "s_register_operand" "")]))
2672 (clobber (match_operand:SI 6 "s_register_operand" ""))]
2674 [(set (match_dup 6) (ashift:SI (match_dup 2) (match_dup 3)))
2677 [(ashiftrt:SI (match_dup 6) (match_dup 4))
2680 HOST_WIDE_INT temp = INTVAL (operands[3]);
2682 operands[3] = GEN_INT (32 - temp - INTVAL (operands[4]));
2683 operands[4] = GEN_INT (32 - temp);
2687 ;;; ??? This pattern is bogus. If operand3 has bits outside the range
2688 ;;; represented by the bitfield, then this will produce incorrect results.
2689 ;;; Somewhere, the value needs to be truncated. On targets like the m68k,
2690 ;;; which have a real bit-field insert instruction, the truncation happens
2691 ;;; in the bit-field insert instruction itself. Since arm does not have a
2692 ;;; bit-field insert instruction, we would have to emit code here to truncate
2693 ;;; the value before we insert. This loses some of the advantage of having
2694 ;;; this insv pattern, so this pattern needs to be reevalutated.
2696 (define_expand "insv"
2697 [(set (zero_extract (match_operand 0 "nonimmediate_operand" "")
2698 (match_operand 1 "general_operand" "")
2699 (match_operand 2 "general_operand" ""))
2700 (match_operand 3 "reg_or_int_operand" ""))]
2701 "TARGET_ARM || arm_arch_thumb2"
2704 int start_bit = INTVAL (operands[2]);
2705 int width = INTVAL (operands[1]);
2706 HOST_WIDE_INT mask = (HOST_WIDE_INT_1 << width) - 1;
2707 rtx target, subtarget;
2709 if (arm_arch_thumb2)
2711 if (unaligned_access && MEM_P (operands[0])
2712 && s_register_operand (operands[3], GET_MODE (operands[3]))
2713 && (width == 16 || width == 32) && (start_bit % BITS_PER_UNIT) == 0)
2717 if (BYTES_BIG_ENDIAN)
2718 start_bit = GET_MODE_BITSIZE (GET_MODE (operands[3])) - width
2723 base_addr = adjust_address (operands[0], SImode,
2724 start_bit / BITS_PER_UNIT);
2725 emit_insn (gen_unaligned_storesi (base_addr, operands[3]));
2729 rtx tmp = gen_reg_rtx (HImode);
2731 base_addr = adjust_address (operands[0], HImode,
2732 start_bit / BITS_PER_UNIT);
2733 emit_move_insn (tmp, gen_lowpart (HImode, operands[3]));
2734 emit_insn (gen_unaligned_storehi (base_addr, tmp));
2738 else if (s_register_operand (operands[0], GET_MODE (operands[0])))
2740 bool use_bfi = TRUE;
2742 if (CONST_INT_P (operands[3]))
2744 HOST_WIDE_INT val = INTVAL (operands[3]) & mask;
2748 emit_insn (gen_insv_zero (operands[0], operands[1],
2753 /* See if the set can be done with a single orr instruction. */
2754 if (val == mask && const_ok_for_arm (val << start_bit))
2760 if (!REG_P (operands[3]))
2761 operands[3] = force_reg (SImode, operands[3]);
2763 emit_insn (gen_insv_t2 (operands[0], operands[1], operands[2],
2772 if (!s_register_operand (operands[0], GET_MODE (operands[0])))
2775 target = copy_rtx (operands[0]);
2776 /* Avoid using a subreg as a subtarget, and avoid writing a paradoxical
2777 subreg as the final target. */
2778 if (GET_CODE (target) == SUBREG)
2780 subtarget = gen_reg_rtx (SImode);
2781 if (GET_MODE_SIZE (GET_MODE (SUBREG_REG (target)))
2782 < GET_MODE_SIZE (SImode))
2783 target = SUBREG_REG (target);
2788 if (CONST_INT_P (operands[3]))
2790 /* Since we are inserting a known constant, we may be able to
2791 reduce the number of bits that we have to clear so that
2792 the mask becomes simple. */
2793 /* ??? This code does not check to see if the new mask is actually
2794 simpler. It may not be. */
2795 rtx op1 = gen_reg_rtx (SImode);
2796 /* ??? Truncate operand3 to fit in the bitfield. See comment before
2797 start of this pattern. */
2798 HOST_WIDE_INT op3_value = mask & INTVAL (operands[3]);
2799 HOST_WIDE_INT mask2 = ((mask & ~op3_value) << start_bit);
2801 emit_insn (gen_andsi3 (op1, operands[0],
2802 gen_int_mode (~mask2, SImode)));
2803 emit_insn (gen_iorsi3 (subtarget, op1,
2804 gen_int_mode (op3_value << start_bit, SImode)));
2806 else if (start_bit == 0
2807 && !(const_ok_for_arm (mask)
2808 || const_ok_for_arm (~mask)))
2810 /* A Trick, since we are setting the bottom bits in the word,
2811 we can shift operand[3] up, operand[0] down, OR them together
2812 and rotate the result back again. This takes 3 insns, and
2813 the third might be mergeable into another op. */
2814 /* The shift up copes with the possibility that operand[3] is
2815 wider than the bitfield. */
2816 rtx op0 = gen_reg_rtx (SImode);
2817 rtx op1 = gen_reg_rtx (SImode);
2819 emit_insn (gen_ashlsi3 (op0, operands[3], GEN_INT (32 - width)));
2820 emit_insn (gen_lshrsi3 (op1, operands[0], operands[1]));
2821 emit_insn (gen_iorsi3 (op1, op1, op0));
2822 emit_insn (gen_rotlsi3 (subtarget, op1, operands[1]));
2824 else if ((width + start_bit == 32)
2825 && !(const_ok_for_arm (mask)
2826 || const_ok_for_arm (~mask)))
2828 /* Similar trick, but slightly less efficient. */
2830 rtx op0 = gen_reg_rtx (SImode);
2831 rtx op1 = gen_reg_rtx (SImode);
2833 emit_insn (gen_ashlsi3 (op0, operands[3], GEN_INT (32 - width)));
2834 emit_insn (gen_ashlsi3 (op1, operands[0], operands[1]));
2835 emit_insn (gen_lshrsi3 (op1, op1, operands[1]));
2836 emit_insn (gen_iorsi3 (subtarget, op1, op0));
2840 rtx op0 = gen_int_mode (mask, SImode);
2841 rtx op1 = gen_reg_rtx (SImode);
2842 rtx op2 = gen_reg_rtx (SImode);
2844 if (!(const_ok_for_arm (mask) || const_ok_for_arm (~mask)))
2846 rtx tmp = gen_reg_rtx (SImode);
2848 emit_insn (gen_movsi (tmp, op0));
2852 /* Mask out any bits in operand[3] that are not needed. */
2853 emit_insn (gen_andsi3 (op1, operands[3], op0));
2855 if (CONST_INT_P (op0)
2856 && (const_ok_for_arm (mask << start_bit)
2857 || const_ok_for_arm (~(mask << start_bit))))
2859 op0 = gen_int_mode (~(mask << start_bit), SImode);
2860 emit_insn (gen_andsi3 (op2, operands[0], op0));
2864 if (CONST_INT_P (op0))
2866 rtx tmp = gen_reg_rtx (SImode);
2868 emit_insn (gen_movsi (tmp, op0));
2873 emit_insn (gen_ashlsi3 (op0, op0, operands[2]));
2875 emit_insn (gen_andsi_notsi_si (op2, operands[0], op0));
2879 emit_insn (gen_ashlsi3 (op1, op1, operands[2]));
2881 emit_insn (gen_iorsi3 (subtarget, op1, op2));
2884 if (subtarget != target)
2886 /* If TARGET is still a SUBREG, then it must be wider than a word,
2887 so we must be careful only to set the subword we were asked to. */
2888 if (GET_CODE (target) == SUBREG)
2889 emit_move_insn (target, subtarget);
2891 emit_move_insn (target, gen_lowpart (GET_MODE (target), subtarget));
2898 (define_insn "insv_zero"
2899 [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r")
2900 (match_operand:SI 1 "const_int_M_operand" "M")
2901 (match_operand:SI 2 "const_int_M_operand" "M"))
2905 [(set_attr "length" "4")
2906 (set_attr "predicable" "yes")
2907 (set_attr "predicable_short_it" "no")
2908 (set_attr "type" "bfm")]
2911 (define_insn "insv_t2"
2912 [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r")
2913 (match_operand:SI 1 "const_int_M_operand" "M")
2914 (match_operand:SI 2 "const_int_M_operand" "M"))
2915 (match_operand:SI 3 "s_register_operand" "r"))]
2917 "bfi%?\t%0, %3, %2, %1"
2918 [(set_attr "length" "4")
2919 (set_attr "predicable" "yes")
2920 (set_attr "predicable_short_it" "no")
2921 (set_attr "type" "bfm")]
2924 ; constants for op 2 will never be given to these patterns.
2925 (define_insn_and_split "*anddi_notdi_di"
2926 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2927 (and:DI (not:DI (match_operand:DI 1 "s_register_operand" "0,r"))
2928 (match_operand:DI 2 "s_register_operand" "r,0")))]
2931 "TARGET_32BIT && reload_completed
2932 && ! (TARGET_NEON && IS_VFP_REGNUM (REGNO (operands[0])))
2933 && ! IS_IWMMXT_REGNUM (REGNO (operands[0]))"
2934 [(set (match_dup 0) (and:SI (not:SI (match_dup 1)) (match_dup 2)))
2935 (set (match_dup 3) (and:SI (not:SI (match_dup 4)) (match_dup 5)))]
2938 operands[3] = gen_highpart (SImode, operands[0]);
2939 operands[0] = gen_lowpart (SImode, operands[0]);
2940 operands[4] = gen_highpart (SImode, operands[1]);
2941 operands[1] = gen_lowpart (SImode, operands[1]);
2942 operands[5] = gen_highpart (SImode, operands[2]);
2943 operands[2] = gen_lowpart (SImode, operands[2]);
2945 [(set_attr "length" "8")
2946 (set_attr "predicable" "yes")
2947 (set_attr "type" "multiple")]
2950 (define_insn_and_split "*anddi_notzesidi_di"
2951 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2952 (and:DI (not:DI (zero_extend:DI
2953 (match_operand:SI 2 "s_register_operand" "r,r")))
2954 (match_operand:DI 1 "s_register_operand" "0,?r")))]
2957 bic%?\\t%Q0, %Q1, %2
2959 ; (not (zero_extend ...)) allows us to just copy the high word from
2960 ; operand1 to operand0.
2963 && operands[0] != operands[1]"
2964 [(set (match_dup 0) (and:SI (not:SI (match_dup 2)) (match_dup 1)))
2965 (set (match_dup 3) (match_dup 4))]
2968 operands[3] = gen_highpart (SImode, operands[0]);
2969 operands[0] = gen_lowpart (SImode, operands[0]);
2970 operands[4] = gen_highpart (SImode, operands[1]);
2971 operands[1] = gen_lowpart (SImode, operands[1]);
2973 [(set_attr "length" "4,8")
2974 (set_attr "predicable" "yes")
2975 (set_attr "predicable_short_it" "no")
2976 (set_attr "type" "multiple")]
2979 (define_insn_and_split "*anddi_notdi_zesidi"
2980 [(set (match_operand:DI 0 "s_register_operand" "=r")
2981 (and:DI (not:DI (match_operand:DI 2 "s_register_operand" "r"))
2983 (match_operand:SI 1 "s_register_operand" "r"))))]
2986 "TARGET_32BIT && reload_completed"
2987 [(set (match_dup 0) (and:SI (not:SI (match_dup 2)) (match_dup 1)))
2988 (set (match_dup 3) (const_int 0))]
2991 operands[3] = gen_highpart (SImode, operands[0]);
2992 operands[0] = gen_lowpart (SImode, operands[0]);
2993 operands[2] = gen_lowpart (SImode, operands[2]);
2995 [(set_attr "length" "8")
2996 (set_attr "predicable" "yes")
2997 (set_attr "predicable_short_it" "no")
2998 (set_attr "type" "multiple")]
3001 (define_insn_and_split "*anddi_notsesidi_di"
3002 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
3003 (and:DI (not:DI (sign_extend:DI
3004 (match_operand:SI 2 "s_register_operand" "r,r")))
3005 (match_operand:DI 1 "s_register_operand" "0,r")))]
3008 "TARGET_32BIT && reload_completed"
3009 [(set (match_dup 0) (and:SI (not:SI (match_dup 2)) (match_dup 1)))
3010 (set (match_dup 3) (and:SI (not:SI
3011 (ashiftrt:SI (match_dup 2) (const_int 31)))
3015 operands[3] = gen_highpart (SImode, operands[0]);
3016 operands[0] = gen_lowpart (SImode, operands[0]);
3017 operands[4] = gen_highpart (SImode, operands[1]);
3018 operands[1] = gen_lowpart (SImode, operands[1]);
3020 [(set_attr "length" "8")
3021 (set_attr "predicable" "yes")
3022 (set_attr "predicable_short_it" "no")
3023 (set_attr "type" "multiple")]
3026 (define_insn "andsi_notsi_si"
3027 [(set (match_operand:SI 0 "s_register_operand" "=r")
3028 (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
3029 (match_operand:SI 1 "s_register_operand" "r")))]
3031 "bic%?\\t%0, %1, %2"
3032 [(set_attr "predicable" "yes")
3033 (set_attr "predicable_short_it" "no")
3034 (set_attr "type" "logic_reg")]
3037 (define_insn "andsi_not_shiftsi_si"
3038 [(set (match_operand:SI 0 "s_register_operand" "=r")
3039 (and:SI (not:SI (match_operator:SI 4 "shift_operator"
3040 [(match_operand:SI 2 "s_register_operand" "r")
3041 (match_operand:SI 3 "arm_rhs_operand" "rM")]))
3042 (match_operand:SI 1 "s_register_operand" "r")))]
3044 "bic%?\\t%0, %1, %2%S4"
3045 [(set_attr "predicable" "yes")
3046 (set_attr "shift" "2")
3047 (set (attr "type") (if_then_else (match_operand 3 "const_int_operand" "")
3048 (const_string "logic_shift_imm")
3049 (const_string "logic_shift_reg")))]
3052 ;; Shifted bics pattern used to set up CC status register and not reusing
3053 ;; bics output. Pattern restricts Thumb2 shift operand as bics for Thumb2
3054 ;; does not support shift by register.
3055 (define_insn "andsi_not_shiftsi_si_scc_no_reuse"
3056 [(set (reg:CC_NOOV CC_REGNUM)
3058 (and:SI (not:SI (match_operator:SI 0 "shift_operator"
3059 [(match_operand:SI 1 "s_register_operand" "r")
3060 (match_operand:SI 2 "arm_rhs_operand" "rM")]))
3061 (match_operand:SI 3 "s_register_operand" "r"))
3063 (clobber (match_scratch:SI 4 "=r"))]
3064 "TARGET_ARM || (TARGET_THUMB2 && CONST_INT_P (operands[2]))"
3065 "bics%?\\t%4, %3, %1%S0"
3066 [(set_attr "predicable" "yes")
3067 (set_attr "predicable_short_it" "no")
3068 (set_attr "conds" "set")
3069 (set_attr "shift" "1")
3070 (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
3071 (const_string "logic_shift_imm")
3072 (const_string "logic_shift_reg")))]
3075 ;; Same as andsi_not_shiftsi_si_scc_no_reuse, but the bics result is also
3076 ;; getting reused later.
3077 (define_insn "andsi_not_shiftsi_si_scc"
3078 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
3080 (and:SI (not:SI (match_operator:SI 0 "shift_operator"
3081 [(match_operand:SI 1 "s_register_operand" "r")
3082 (match_operand:SI 2 "arm_rhs_operand" "rM")]))
3083 (match_operand:SI 3 "s_register_operand" "r"))
3085 (set (match_operand:SI 4 "s_register_operand" "=r")
3086 (and:SI (not:SI (match_op_dup 0
3090 "TARGET_ARM || (TARGET_THUMB2 && CONST_INT_P (operands[2]))"
3091 "bics%?\\t%4, %3, %1%S0"
3092 [(set_attr "predicable" "yes")
3093 (set_attr "predicable_short_it" "no")
3094 (set_attr "conds" "set")
3095 (set_attr "shift" "1")
3096 (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
3097 (const_string "logic_shift_imm")
3098 (const_string "logic_shift_reg")))]
3101 (define_insn "*andsi_notsi_si_compare0"
3102 [(set (reg:CC_NOOV CC_REGNUM)
3104 (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
3105 (match_operand:SI 1 "s_register_operand" "r"))
3107 (set (match_operand:SI 0 "s_register_operand" "=r")
3108 (and:SI (not:SI (match_dup 2)) (match_dup 1)))]
3111 [(set_attr "conds" "set")
3112 (set_attr "type" "logics_shift_reg")]
3115 (define_insn "*andsi_notsi_si_compare0_scratch"
3116 [(set (reg:CC_NOOV CC_REGNUM)
3118 (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
3119 (match_operand:SI 1 "s_register_operand" "r"))
3121 (clobber (match_scratch:SI 0 "=r"))]
3124 [(set_attr "conds" "set")
3125 (set_attr "type" "logics_shift_reg")]
3128 (define_expand "iordi3"
3129 [(set (match_operand:DI 0 "s_register_operand" "")
3130 (ior:DI (match_operand:DI 1 "s_register_operand" "")
3131 (match_operand:DI 2 "neon_logic_op2" "")))]
3136 (define_insn_and_split "*iordi3_insn"
3137 [(set (match_operand:DI 0 "s_register_operand" "=w,w ,&r,&r,&r,&r,?w,?w")
3138 (ior:DI (match_operand:DI 1 "s_register_operand" "%w,0 ,0 ,r ,0 ,r ,w ,0")
3139 (match_operand:DI 2 "arm_iordi_operand_neon" "w ,Dl,r ,r ,Df,Df,w ,Dl")))]
3140 "TARGET_32BIT && !TARGET_IWMMXT"
3142 switch (which_alternative)
3144 case 0: /* fall through */
3145 case 6: return "vorr\t%P0, %P1, %P2";
3146 case 1: /* fall through */
3147 case 7: return neon_output_logic_immediate ("vorr", &operands[2],
3148 DImode, 0, VALID_NEON_QREG_MODE (DImode));
3154 default: gcc_unreachable ();
3157 "TARGET_32BIT && !TARGET_IWMMXT && reload_completed
3158 && !(IS_VFP_REGNUM (REGNO (operands[0])))"
3159 [(set (match_dup 3) (match_dup 4))
3160 (set (match_dup 5) (match_dup 6))]
3163 operands[3] = gen_lowpart (SImode, operands[0]);
3164 operands[5] = gen_highpart (SImode, operands[0]);
3166 operands[4] = simplify_gen_binary (IOR, SImode,
3167 gen_lowpart (SImode, operands[1]),
3168 gen_lowpart (SImode, operands[2]));
3169 operands[6] = simplify_gen_binary (IOR, SImode,
3170 gen_highpart (SImode, operands[1]),
3171 gen_highpart_mode (SImode, DImode, operands[2]));
3174 [(set_attr "type" "neon_logic,neon_logic,multiple,multiple,multiple,\
3175 multiple,neon_logic,neon_logic")
3176 (set_attr "length" "*,*,8,8,8,8,*,*")
3177 (set_attr "arch" "neon_for_64bits,neon_for_64bits,*,*,*,*,avoid_neon_for_64bits,avoid_neon_for_64bits")]
3180 (define_insn "*iordi_zesidi_di"
3181 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
3182 (ior:DI (zero_extend:DI
3183 (match_operand:SI 2 "s_register_operand" "r,r"))
3184 (match_operand:DI 1 "s_register_operand" "0,?r")))]
3187 orr%?\\t%Q0, %Q1, %2
3189 [(set_attr "length" "4,8")
3190 (set_attr "predicable" "yes")
3191 (set_attr "predicable_short_it" "no")
3192 (set_attr "type" "logic_reg,multiple")]
3195 (define_insn "*iordi_sesidi_di"
3196 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
3197 (ior:DI (sign_extend:DI
3198 (match_operand:SI 2 "s_register_operand" "r,r"))
3199 (match_operand:DI 1 "s_register_operand" "0,r")))]
3202 [(set_attr "length" "8")
3203 (set_attr "predicable" "yes")
3204 (set_attr "type" "multiple")]
3207 (define_expand "iorsi3"
3208 [(set (match_operand:SI 0 "s_register_operand" "")
3209 (ior:SI (match_operand:SI 1 "s_register_operand" "")
3210 (match_operand:SI 2 "reg_or_int_operand" "")))]
3213 if (CONST_INT_P (operands[2]))
3217 if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[2]), IOR))
3218 operands[2] = force_reg (SImode, operands[2]);
3221 arm_split_constant (IOR, SImode, NULL_RTX,
3222 INTVAL (operands[2]), operands[0],
3224 optimize && can_create_pseudo_p ());
3228 else /* TARGET_THUMB1 */
3230 rtx tmp = force_reg (SImode, operands[2]);
3231 if (rtx_equal_p (operands[0], operands[1]))
3235 operands[2] = operands[1];
3243 (define_insn_and_split "*iorsi3_insn"
3244 [(set (match_operand:SI 0 "s_register_operand" "=r,l,r,r,r")
3245 (ior:SI (match_operand:SI 1 "s_register_operand" "%r,0,r,r,r")
3246 (match_operand:SI 2 "reg_or_int_operand" "I,l,K,r,?n")))]
3251 orn%?\\t%0, %1, #%B2
3255 && CONST_INT_P (operands[2])
3256 && !(const_ok_for_arm (INTVAL (operands[2]))
3257 || (TARGET_THUMB2 && const_ok_for_arm (~INTVAL (operands[2]))))"
3258 [(clobber (const_int 0))]
3260 arm_split_constant (IOR, SImode, curr_insn,
3261 INTVAL (operands[2]), operands[0], operands[1], 0);
3264 [(set_attr "length" "4,4,4,4,16")
3265 (set_attr "arch" "32,t2,t2,32,32")
3266 (set_attr "predicable" "yes")
3267 (set_attr "predicable_short_it" "no,yes,no,no,no")
3268 (set_attr "type" "logic_imm,logic_reg,logic_imm,logic_reg,logic_reg")]
3272 [(match_scratch:SI 3 "r")
3273 (set (match_operand:SI 0 "arm_general_register_operand" "")
3274 (ior:SI (match_operand:SI 1 "arm_general_register_operand" "")
3275 (match_operand:SI 2 "const_int_operand" "")))]
3277 && !const_ok_for_arm (INTVAL (operands[2]))
3278 && const_ok_for_arm (~INTVAL (operands[2]))"
3279 [(set (match_dup 3) (match_dup 2))
3280 (set (match_dup 0) (ior:SI (match_dup 1) (match_dup 3)))]
3284 (define_insn "*iorsi3_compare0"
3285 [(set (reg:CC_NOOV CC_REGNUM)
3286 (compare:CC_NOOV (ior:SI (match_operand:SI 1 "s_register_operand" "%r,r")
3287 (match_operand:SI 2 "arm_rhs_operand" "I,r"))
3289 (set (match_operand:SI 0 "s_register_operand" "=r,r")
3290 (ior:SI (match_dup 1) (match_dup 2)))]
3292 "orrs%?\\t%0, %1, %2"
3293 [(set_attr "conds" "set")
3294 (set_attr "type" "logics_imm,logics_reg")]
3297 (define_insn "*iorsi3_compare0_scratch"
3298 [(set (reg:CC_NOOV CC_REGNUM)
3299 (compare:CC_NOOV (ior:SI (match_operand:SI 1 "s_register_operand" "%r,r")
3300 (match_operand:SI 2 "arm_rhs_operand" "I,r"))
3302 (clobber (match_scratch:SI 0 "=r,r"))]
3304 "orrs%?\\t%0, %1, %2"
3305 [(set_attr "conds" "set")
3306 (set_attr "type" "logics_imm,logics_reg")]
3309 (define_expand "xordi3"
3310 [(set (match_operand:DI 0 "s_register_operand" "")
3311 (xor:DI (match_operand:DI 1 "s_register_operand" "")
3312 (match_operand:DI 2 "arm_xordi_operand" "")))]
3317 (define_insn_and_split "*xordi3_insn"
3318 [(set (match_operand:DI 0 "s_register_operand" "=w,&r,&r,&r,&r,?w")
3319 (xor:DI (match_operand:DI 1 "s_register_operand" "%w ,0,r ,0 ,r ,w")
3320 (match_operand:DI 2 "arm_xordi_operand" "w ,r ,r ,Dg,Dg,w")))]
3321 "TARGET_32BIT && !TARGET_IWMMXT"
3323 switch (which_alternative)
3328 case 4: /* fall through */
3330 case 0: /* fall through */
3331 case 5: return "veor\t%P0, %P1, %P2";
3332 default: gcc_unreachable ();
3335 "TARGET_32BIT && !TARGET_IWMMXT && reload_completed
3336 && !(IS_VFP_REGNUM (REGNO (operands[0])))"
3337 [(set (match_dup 3) (match_dup 4))
3338 (set (match_dup 5) (match_dup 6))]
3341 operands[3] = gen_lowpart (SImode, operands[0]);
3342 operands[5] = gen_highpart (SImode, operands[0]);
3344 operands[4] = simplify_gen_binary (XOR, SImode,
3345 gen_lowpart (SImode, operands[1]),
3346 gen_lowpart (SImode, operands[2]));
3347 operands[6] = simplify_gen_binary (XOR, SImode,
3348 gen_highpart (SImode, operands[1]),
3349 gen_highpart_mode (SImode, DImode, operands[2]));
3352 [(set_attr "length" "*,8,8,8,8,*")
3353 (set_attr "type" "neon_logic,multiple,multiple,multiple,multiple,neon_logic")
3354 (set_attr "arch" "neon_for_64bits,*,*,*,*,avoid_neon_for_64bits")]
3357 (define_insn "*xordi_zesidi_di"
3358 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
3359 (xor:DI (zero_extend:DI
3360 (match_operand:SI 2 "s_register_operand" "r,r"))
3361 (match_operand:DI 1 "s_register_operand" "0,?r")))]
3364 eor%?\\t%Q0, %Q1, %2
3366 [(set_attr "length" "4,8")
3367 (set_attr "predicable" "yes")
3368 (set_attr "predicable_short_it" "no")
3369 (set_attr "type" "logic_reg")]
3372 (define_insn "*xordi_sesidi_di"
3373 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
3374 (xor:DI (sign_extend:DI
3375 (match_operand:SI 2 "s_register_operand" "r,r"))
3376 (match_operand:DI 1 "s_register_operand" "0,r")))]
3379 [(set_attr "length" "8")
3380 (set_attr "predicable" "yes")
3381 (set_attr "type" "multiple")]
3384 (define_expand "xorsi3"
3385 [(set (match_operand:SI 0 "s_register_operand" "")
3386 (xor:SI (match_operand:SI 1 "s_register_operand" "")
3387 (match_operand:SI 2 "reg_or_int_operand" "")))]
3389 "if (CONST_INT_P (operands[2]))
3393 if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[2]), XOR))
3394 operands[2] = force_reg (SImode, operands[2]);
3397 arm_split_constant (XOR, SImode, NULL_RTX,
3398 INTVAL (operands[2]), operands[0],
3400 optimize && can_create_pseudo_p ());
3404 else /* TARGET_THUMB1 */
3406 rtx tmp = force_reg (SImode, operands[2]);
3407 if (rtx_equal_p (operands[0], operands[1]))
3411 operands[2] = operands[1];
3418 (define_insn_and_split "*arm_xorsi3"
3419 [(set (match_operand:SI 0 "s_register_operand" "=r,l,r,r")
3420 (xor:SI (match_operand:SI 1 "s_register_operand" "%r,0,r,r")
3421 (match_operand:SI 2 "reg_or_int_operand" "I,l,r,?n")))]
3429 && CONST_INT_P (operands[2])
3430 && !const_ok_for_arm (INTVAL (operands[2]))"
3431 [(clobber (const_int 0))]
3433 arm_split_constant (XOR, SImode, curr_insn,
3434 INTVAL (operands[2]), operands[0], operands[1], 0);
3437 [(set_attr "length" "4,4,4,16")
3438 (set_attr "predicable" "yes")
3439 (set_attr "predicable_short_it" "no,yes,no,no")
3440 (set_attr "type" "logic_imm,logic_reg,logic_reg,multiple")]
3443 (define_insn "*xorsi3_compare0"
3444 [(set (reg:CC_NOOV CC_REGNUM)
3445 (compare:CC_NOOV (xor:SI (match_operand:SI 1 "s_register_operand" "r,r")
3446 (match_operand:SI 2 "arm_rhs_operand" "I,r"))
3448 (set (match_operand:SI 0 "s_register_operand" "=r,r")
3449 (xor:SI (match_dup 1) (match_dup 2)))]
3451 "eors%?\\t%0, %1, %2"
3452 [(set_attr "conds" "set")
3453 (set_attr "type" "logics_imm,logics_reg")]
3456 (define_insn "*xorsi3_compare0_scratch"
3457 [(set (reg:CC_NOOV CC_REGNUM)
3458 (compare:CC_NOOV (xor:SI (match_operand:SI 0 "s_register_operand" "r,r")
3459 (match_operand:SI 1 "arm_rhs_operand" "I,r"))
3463 [(set_attr "conds" "set")
3464 (set_attr "type" "logics_imm,logics_reg")]
3467 ; By splitting (IOR (AND (NOT A) (NOT B)) C) as D = AND (IOR A B) (NOT C),
3468 ; (NOT D) we can sometimes merge the final NOT into one of the following
3472 [(set (match_operand:SI 0 "s_register_operand" "")
3473 (ior:SI (and:SI (not:SI (match_operand:SI 1 "s_register_operand" ""))
3474 (not:SI (match_operand:SI 2 "arm_rhs_operand" "")))
3475 (match_operand:SI 3 "arm_rhs_operand" "")))
3476 (clobber (match_operand:SI 4 "s_register_operand" ""))]
3478 [(set (match_dup 4) (and:SI (ior:SI (match_dup 1) (match_dup 2))
3479 (not:SI (match_dup 3))))
3480 (set (match_dup 0) (not:SI (match_dup 4)))]
3484 (define_insn_and_split "*andsi_iorsi3_notsi"
3485 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r")
3486 (and:SI (ior:SI (match_operand:SI 1 "s_register_operand" "%0,r,r")
3487 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI"))
3488 (not:SI (match_operand:SI 3 "arm_rhs_operand" "rI,rI,rI"))))]
3490 "#" ; "orr%?\\t%0, %1, %2\;bic%?\\t%0, %0, %3"
3491 "&& reload_completed"
3492 [(set (match_dup 0) (ior:SI (match_dup 1) (match_dup 2)))
3493 (set (match_dup 0) (and:SI (match_dup 4) (match_dup 5)))]
3495 /* If operands[3] is a constant make sure to fold the NOT into it
3496 to avoid creating a NOT of a CONST_INT. */
3497 rtx not_rtx = simplify_gen_unary (NOT, SImode, operands[3], SImode);
3498 if (CONST_INT_P (not_rtx))
3500 operands[4] = operands[0];
3501 operands[5] = not_rtx;
3505 operands[5] = operands[0];
3506 operands[4] = not_rtx;
3509 [(set_attr "length" "8")
3510 (set_attr "ce_count" "2")
3511 (set_attr "predicable" "yes")
3512 (set_attr "predicable_short_it" "no")
3513 (set_attr "type" "multiple")]
3516 ; ??? Are these four splitters still beneficial when the Thumb-2 bitfield
3517 ; insns are available?
3519 [(set (match_operand:SI 0 "s_register_operand" "")
3520 (match_operator:SI 1 "logical_binary_operator"
3521 [(zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
3522 (match_operand:SI 3 "const_int_operand" "")
3523 (match_operand:SI 4 "const_int_operand" ""))
3524 (match_operator:SI 9 "logical_binary_operator"
3525 [(lshiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3526 (match_operand:SI 6 "const_int_operand" ""))
3527 (match_operand:SI 7 "s_register_operand" "")])]))
3528 (clobber (match_operand:SI 8 "s_register_operand" ""))]
3530 && GET_CODE (operands[1]) == GET_CODE (operands[9])
3531 && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3534 [(ashift:SI (match_dup 2) (match_dup 4))
3538 [(lshiftrt:SI (match_dup 8) (match_dup 6))
3541 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3545 [(set (match_operand:SI 0 "s_register_operand" "")
3546 (match_operator:SI 1 "logical_binary_operator"
3547 [(match_operator:SI 9 "logical_binary_operator"
3548 [(lshiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3549 (match_operand:SI 6 "const_int_operand" ""))
3550 (match_operand:SI 7 "s_register_operand" "")])
3551 (zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
3552 (match_operand:SI 3 "const_int_operand" "")
3553 (match_operand:SI 4 "const_int_operand" ""))]))
3554 (clobber (match_operand:SI 8 "s_register_operand" ""))]
3556 && GET_CODE (operands[1]) == GET_CODE (operands[9])
3557 && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3560 [(ashift:SI (match_dup 2) (match_dup 4))
3564 [(lshiftrt:SI (match_dup 8) (match_dup 6))
3567 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3571 [(set (match_operand:SI 0 "s_register_operand" "")
3572 (match_operator:SI 1 "logical_binary_operator"
3573 [(sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
3574 (match_operand:SI 3 "const_int_operand" "")
3575 (match_operand:SI 4 "const_int_operand" ""))
3576 (match_operator:SI 9 "logical_binary_operator"
3577 [(ashiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3578 (match_operand:SI 6 "const_int_operand" ""))
3579 (match_operand:SI 7 "s_register_operand" "")])]))
3580 (clobber (match_operand:SI 8 "s_register_operand" ""))]
3582 && GET_CODE (operands[1]) == GET_CODE (operands[9])
3583 && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3586 [(ashift:SI (match_dup 2) (match_dup 4))
3590 [(ashiftrt:SI (match_dup 8) (match_dup 6))
3593 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3597 [(set (match_operand:SI 0 "s_register_operand" "")
3598 (match_operator:SI 1 "logical_binary_operator"
3599 [(match_operator:SI 9 "logical_binary_operator"
3600 [(ashiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3601 (match_operand:SI 6 "const_int_operand" ""))
3602 (match_operand:SI 7 "s_register_operand" "")])
3603 (sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
3604 (match_operand:SI 3 "const_int_operand" "")
3605 (match_operand:SI 4 "const_int_operand" ""))]))
3606 (clobber (match_operand:SI 8 "s_register_operand" ""))]
3608 && GET_CODE (operands[1]) == GET_CODE (operands[9])
3609 && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3612 [(ashift:SI (match_dup 2) (match_dup 4))
3616 [(ashiftrt:SI (match_dup 8) (match_dup 6))
3619 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3623 ;; Minimum and maximum insns
3625 (define_expand "smaxsi3"
3627 (set (match_operand:SI 0 "s_register_operand" "")
3628 (smax:SI (match_operand:SI 1 "s_register_operand" "")
3629 (match_operand:SI 2 "arm_rhs_operand" "")))
3630 (clobber (reg:CC CC_REGNUM))])]
3633 if (operands[2] == const0_rtx || operands[2] == constm1_rtx)
3635 /* No need for a clobber of the condition code register here. */
3636 emit_insn (gen_rtx_SET (operands[0],
3637 gen_rtx_SMAX (SImode, operands[1],
3643 (define_insn "*smax_0"
3644 [(set (match_operand:SI 0 "s_register_operand" "=r")
3645 (smax:SI (match_operand:SI 1 "s_register_operand" "r")
3648 "bic%?\\t%0, %1, %1, asr #31"
3649 [(set_attr "predicable" "yes")
3650 (set_attr "predicable_short_it" "no")
3651 (set_attr "type" "logic_shift_reg")]
3654 (define_insn "*smax_m1"
3655 [(set (match_operand:SI 0 "s_register_operand" "=r")
3656 (smax:SI (match_operand:SI 1 "s_register_operand" "r")
3659 "orr%?\\t%0, %1, %1, asr #31"
3660 [(set_attr "predicable" "yes")
3661 (set_attr "predicable_short_it" "no")
3662 (set_attr "type" "logic_shift_reg")]
3665 (define_insn_and_split "*arm_smax_insn"
3666 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3667 (smax:SI (match_operand:SI 1 "s_register_operand" "%0,?r")
3668 (match_operand:SI 2 "arm_rhs_operand" "rI,rI")))
3669 (clobber (reg:CC CC_REGNUM))]
3672 ; cmp\\t%1, %2\;movlt\\t%0, %2
3673 ; cmp\\t%1, %2\;movge\\t%0, %1\;movlt\\t%0, %2"
3675 [(set (reg:CC CC_REGNUM)
3676 (compare:CC (match_dup 1) (match_dup 2)))
3678 (if_then_else:SI (ge:SI (reg:CC CC_REGNUM) (const_int 0))
3682 [(set_attr "conds" "clob")
3683 (set_attr "length" "8,12")
3684 (set_attr "type" "multiple")]
3687 (define_expand "sminsi3"
3689 (set (match_operand:SI 0 "s_register_operand" "")
3690 (smin:SI (match_operand:SI 1 "s_register_operand" "")
3691 (match_operand:SI 2 "arm_rhs_operand" "")))
3692 (clobber (reg:CC CC_REGNUM))])]
3695 if (operands[2] == const0_rtx)
3697 /* No need for a clobber of the condition code register here. */
3698 emit_insn (gen_rtx_SET (operands[0],
3699 gen_rtx_SMIN (SImode, operands[1],
3705 (define_insn "*smin_0"
3706 [(set (match_operand:SI 0 "s_register_operand" "=r")
3707 (smin:SI (match_operand:SI 1 "s_register_operand" "r")
3710 "and%?\\t%0, %1, %1, asr #31"
3711 [(set_attr "predicable" "yes")
3712 (set_attr "predicable_short_it" "no")
3713 (set_attr "type" "logic_shift_reg")]
3716 (define_insn_and_split "*arm_smin_insn"
3717 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3718 (smin:SI (match_operand:SI 1 "s_register_operand" "%0,?r")
3719 (match_operand:SI 2 "arm_rhs_operand" "rI,rI")))
3720 (clobber (reg:CC CC_REGNUM))]
3723 ; cmp\\t%1, %2\;movge\\t%0, %2
3724 ; cmp\\t%1, %2\;movlt\\t%0, %1\;movge\\t%0, %2"
3726 [(set (reg:CC CC_REGNUM)
3727 (compare:CC (match_dup 1) (match_dup 2)))
3729 (if_then_else:SI (lt:SI (reg:CC CC_REGNUM) (const_int 0))
3733 [(set_attr "conds" "clob")
3734 (set_attr "length" "8,12")
3735 (set_attr "type" "multiple,multiple")]
3738 (define_expand "umaxsi3"
3740 (set (match_operand:SI 0 "s_register_operand" "")
3741 (umax:SI (match_operand:SI 1 "s_register_operand" "")
3742 (match_operand:SI 2 "arm_rhs_operand" "")))
3743 (clobber (reg:CC CC_REGNUM))])]
3748 (define_insn_and_split "*arm_umaxsi3"
3749 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
3750 (umax:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
3751 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
3752 (clobber (reg:CC CC_REGNUM))]
3755 ; cmp\\t%1, %2\;movcc\\t%0, %2
3756 ; cmp\\t%1, %2\;movcs\\t%0, %1
3757 ; cmp\\t%1, %2\;movcs\\t%0, %1\;movcc\\t%0, %2"
3759 [(set (reg:CC CC_REGNUM)
3760 (compare:CC (match_dup 1) (match_dup 2)))
3762 (if_then_else:SI (geu:SI (reg:CC CC_REGNUM) (const_int 0))
3766 [(set_attr "conds" "clob")
3767 (set_attr "length" "8,8,12")
3768 (set_attr "type" "store1")]
3771 (define_expand "uminsi3"
3773 (set (match_operand:SI 0 "s_register_operand" "")
3774 (umin:SI (match_operand:SI 1 "s_register_operand" "")
3775 (match_operand:SI 2 "arm_rhs_operand" "")))
3776 (clobber (reg:CC CC_REGNUM))])]
3781 (define_insn_and_split "*arm_uminsi3"
3782 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
3783 (umin:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
3784 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
3785 (clobber (reg:CC CC_REGNUM))]
3788 ; cmp\\t%1, %2\;movcs\\t%0, %2
3789 ; cmp\\t%1, %2\;movcc\\t%0, %1
3790 ; cmp\\t%1, %2\;movcc\\t%0, %1\;movcs\\t%0, %2"
3792 [(set (reg:CC CC_REGNUM)
3793 (compare:CC (match_dup 1) (match_dup 2)))
3795 (if_then_else:SI (ltu:SI (reg:CC CC_REGNUM) (const_int 0))
3799 [(set_attr "conds" "clob")
3800 (set_attr "length" "8,8,12")
3801 (set_attr "type" "store1")]
3804 (define_insn "*store_minmaxsi"
3805 [(set (match_operand:SI 0 "memory_operand" "=m")
3806 (match_operator:SI 3 "minmax_operator"
3807 [(match_operand:SI 1 "s_register_operand" "r")
3808 (match_operand:SI 2 "s_register_operand" "r")]))
3809 (clobber (reg:CC CC_REGNUM))]
3810 "TARGET_32BIT && optimize_function_for_size_p (cfun) && !arm_restrict_it"
3812 operands[3] = gen_rtx_fmt_ee (minmax_code (operands[3]), SImode,
3813 operands[1], operands[2]);
3814 output_asm_insn (\"cmp\\t%1, %2\", operands);
3816 output_asm_insn (\"ite\t%d3\", operands);
3817 output_asm_insn (\"str%d3\\t%1, %0\", operands);
3818 output_asm_insn (\"str%D3\\t%2, %0\", operands);
3821 [(set_attr "conds" "clob")
3822 (set (attr "length")
3823 (if_then_else (eq_attr "is_thumb" "yes")
3826 (set_attr "type" "store1")]
3829 ; Reject the frame pointer in operand[1], since reloading this after
3830 ; it has been eliminated can cause carnage.
3831 (define_insn "*minmax_arithsi"
3832 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3833 (match_operator:SI 4 "shiftable_operator"
3834 [(match_operator:SI 5 "minmax_operator"
3835 [(match_operand:SI 2 "s_register_operand" "r,r")
3836 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
3837 (match_operand:SI 1 "s_register_operand" "0,?r")]))
3838 (clobber (reg:CC CC_REGNUM))]
3839 "TARGET_32BIT && !arm_eliminable_register (operands[1]) && !arm_restrict_it"
3842 enum rtx_code code = GET_CODE (operands[4]);
3845 if (which_alternative != 0 || operands[3] != const0_rtx
3846 || (code != PLUS && code != IOR && code != XOR))
3851 operands[5] = gen_rtx_fmt_ee (minmax_code (operands[5]), SImode,
3852 operands[2], operands[3]);
3853 output_asm_insn (\"cmp\\t%2, %3\", operands);
3857 output_asm_insn (\"ite\\t%d5\", operands);
3859 output_asm_insn (\"it\\t%d5\", operands);
3861 output_asm_insn (\"%i4%d5\\t%0, %1, %2\", operands);
3863 output_asm_insn (\"%i4%D5\\t%0, %1, %3\", operands);
3866 [(set_attr "conds" "clob")
3867 (set (attr "length")
3868 (if_then_else (eq_attr "is_thumb" "yes")
3871 (set_attr "type" "multiple")]
3874 ; Reject the frame pointer in operand[1], since reloading this after
3875 ; it has been eliminated can cause carnage.
3876 (define_insn_and_split "*minmax_arithsi_non_canon"
3877 [(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts")
3879 (match_operand:SI 1 "s_register_operand" "0,?Ts")
3880 (match_operator:SI 4 "minmax_operator"
3881 [(match_operand:SI 2 "s_register_operand" "Ts,Ts")
3882 (match_operand:SI 3 "arm_rhs_operand" "TsI,TsI")])))
3883 (clobber (reg:CC CC_REGNUM))]
3884 "TARGET_32BIT && !arm_eliminable_register (operands[1])
3885 && !(arm_restrict_it && CONST_INT_P (operands[3]))"
3887 "TARGET_32BIT && !arm_eliminable_register (operands[1]) && reload_completed"
3888 [(set (reg:CC CC_REGNUM)
3889 (compare:CC (match_dup 2) (match_dup 3)))
3891 (cond_exec (match_op_dup 4 [(reg:CC CC_REGNUM) (const_int 0)])
3893 (minus:SI (match_dup 1)
3895 (cond_exec (match_op_dup 5 [(reg:CC CC_REGNUM) (const_int 0)])
3899 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
3900 operands[2], operands[3]);
3901 enum rtx_code rc = minmax_code (operands[4]);
3902 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode,
3903 operands[2], operands[3]);
3905 if (mode == CCFPmode || mode == CCFPEmode)
3906 rc = reverse_condition_maybe_unordered (rc);
3908 rc = reverse_condition (rc);
3909 operands[5] = gen_rtx_fmt_ee (rc, SImode, operands[2], operands[3]);
3910 if (CONST_INT_P (operands[3]))
3911 operands[6] = plus_constant (SImode, operands[1], -INTVAL (operands[3]));
3913 operands[6] = gen_rtx_MINUS (SImode, operands[1], operands[3]);
3915 [(set_attr "conds" "clob")
3916 (set (attr "length")
3917 (if_then_else (eq_attr "is_thumb" "yes")
3920 (set_attr "type" "multiple")]
3923 (define_code_iterator SAT [smin smax])
3924 (define_code_iterator SATrev [smin smax])
3925 (define_code_attr SATlo [(smin "1") (smax "2")])
3926 (define_code_attr SAThi [(smin "2") (smax "1")])
3928 (define_insn "*satsi_<SAT:code>"
3929 [(set (match_operand:SI 0 "s_register_operand" "=r")
3930 (SAT:SI (SATrev:SI (match_operand:SI 3 "s_register_operand" "r")
3931 (match_operand:SI 1 "const_int_operand" "i"))
3932 (match_operand:SI 2 "const_int_operand" "i")))]
3933 "TARGET_32BIT && arm_arch6 && <SAT:CODE> != <SATrev:CODE>
3934 && arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>], NULL, NULL)"
3938 if (!arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>],
3939 &mask, &signed_sat))
3942 operands[1] = GEN_INT (mask);
3944 return "ssat%?\t%0, %1, %3";
3946 return "usat%?\t%0, %1, %3";
3948 [(set_attr "predicable" "yes")
3949 (set_attr "predicable_short_it" "no")
3950 (set_attr "type" "alus_imm")]
3953 (define_insn "*satsi_<SAT:code>_shift"
3954 [(set (match_operand:SI 0 "s_register_operand" "=r")
3955 (SAT:SI (SATrev:SI (match_operator:SI 3 "sat_shift_operator"
3956 [(match_operand:SI 4 "s_register_operand" "r")
3957 (match_operand:SI 5 "const_int_operand" "i")])
3958 (match_operand:SI 1 "const_int_operand" "i"))
3959 (match_operand:SI 2 "const_int_operand" "i")))]
3960 "TARGET_32BIT && arm_arch6 && <SAT:CODE> != <SATrev:CODE>
3961 && arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>], NULL, NULL)"
3965 if (!arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>],
3966 &mask, &signed_sat))
3969 operands[1] = GEN_INT (mask);
3971 return "ssat%?\t%0, %1, %4%S3";
3973 return "usat%?\t%0, %1, %4%S3";
3975 [(set_attr "predicable" "yes")
3976 (set_attr "predicable_short_it" "no")
3977 (set_attr "shift" "3")
3978 (set_attr "type" "logic_shift_reg")])
3980 ;; Shift and rotation insns
3982 (define_expand "ashldi3"
3983 [(set (match_operand:DI 0 "s_register_operand" "")
3984 (ashift:DI (match_operand:DI 1 "s_register_operand" "")
3985 (match_operand:SI 2 "general_operand" "")))]
3990 /* Delay the decision whether to use NEON or core-regs until
3991 register allocation. */
3992 emit_insn (gen_ashldi3_neon (operands[0], operands[1], operands[2]));
3997 /* Only the NEON case can handle in-memory shift counts. */
3998 if (!reg_or_int_operand (operands[2], SImode))
3999 operands[2] = force_reg (SImode, operands[2]);
4002 if (!CONST_INT_P (operands[2]) && TARGET_REALLY_IWMMXT)
4003 ; /* No special preparation statements; expand pattern as above. */
4006 rtx scratch1, scratch2;
4008 if (operands[2] == CONST1_RTX (SImode))
4010 emit_insn (gen_arm_ashldi3_1bit (operands[0], operands[1]));
4014 /* Ideally we should use iwmmxt here if we could know that operands[1]
4015 ends up already living in an iwmmxt register. Otherwise it's
4016 cheaper to have the alternate code being generated than moving
4017 values to iwmmxt regs and back. */
4019 /* Expand operation using core-registers.
4020 'FAIL' would achieve the same thing, but this is a bit smarter. */
4021 scratch1 = gen_reg_rtx (SImode);
4022 scratch2 = gen_reg_rtx (SImode);
4023 arm_emit_coreregs_64bit_shift (ASHIFT, operands[0], operands[1],
4024 operands[2], scratch1, scratch2);
4030 (define_insn "arm_ashldi3_1bit"
4031 [(set (match_operand:DI 0 "s_register_operand" "=r,&r")
4032 (ashift:DI (match_operand:DI 1 "s_register_operand" "0,r")
4034 (clobber (reg:CC CC_REGNUM))]
4036 "movs\\t%Q0, %Q1, asl #1\;adc\\t%R0, %R1, %R1"
4037 [(set_attr "conds" "clob")
4038 (set_attr "length" "8")
4039 (set_attr "type" "multiple")]
4042 (define_expand "ashlsi3"
4043 [(set (match_operand:SI 0 "s_register_operand" "")
4044 (ashift:SI (match_operand:SI 1 "s_register_operand" "")
4045 (match_operand:SI 2 "arm_rhs_operand" "")))]
4048 if (CONST_INT_P (operands[2])
4049 && (UINTVAL (operands[2])) > 31)
4051 emit_insn (gen_movsi (operands[0], const0_rtx));
4057 (define_expand "ashrdi3"
4058 [(set (match_operand:DI 0 "s_register_operand" "")
4059 (ashiftrt:DI (match_operand:DI 1 "s_register_operand" "")
4060 (match_operand:SI 2 "reg_or_int_operand" "")))]
4065 /* Delay the decision whether to use NEON or core-regs until
4066 register allocation. */
4067 emit_insn (gen_ashrdi3_neon (operands[0], operands[1], operands[2]));
4071 if (!CONST_INT_P (operands[2]) && TARGET_REALLY_IWMMXT)
4072 ; /* No special preparation statements; expand pattern as above. */
4075 rtx scratch1, scratch2;
4077 if (operands[2] == CONST1_RTX (SImode))
4079 emit_insn (gen_arm_ashrdi3_1bit (operands[0], operands[1]));
4083 /* Ideally we should use iwmmxt here if we could know that operands[1]
4084 ends up already living in an iwmmxt register. Otherwise it's
4085 cheaper to have the alternate code being generated than moving
4086 values to iwmmxt regs and back. */
4088 /* Expand operation using core-registers.
4089 'FAIL' would achieve the same thing, but this is a bit smarter. */
4090 scratch1 = gen_reg_rtx (SImode);
4091 scratch2 = gen_reg_rtx (SImode);
4092 arm_emit_coreregs_64bit_shift (ASHIFTRT, operands[0], operands[1],
4093 operands[2], scratch1, scratch2);
4099 (define_insn "arm_ashrdi3_1bit"
4100 [(set (match_operand:DI 0 "s_register_operand" "=r,&r")
4101 (ashiftrt:DI (match_operand:DI 1 "s_register_operand" "0,r")
4103 (clobber (reg:CC CC_REGNUM))]
4105 "movs\\t%R0, %R1, asr #1\;mov\\t%Q0, %Q1, rrx"
4106 [(set_attr "conds" "clob")
4107 (set_attr "length" "8")
4108 (set_attr "type" "multiple")]
4111 (define_expand "ashrsi3"
4112 [(set (match_operand:SI 0 "s_register_operand" "")
4113 (ashiftrt:SI (match_operand:SI 1 "s_register_operand" "")
4114 (match_operand:SI 2 "arm_rhs_operand" "")))]
4117 if (CONST_INT_P (operands[2])
4118 && UINTVAL (operands[2]) > 31)
4119 operands[2] = GEN_INT (31);
4123 (define_expand "lshrdi3"
4124 [(set (match_operand:DI 0 "s_register_operand" "")
4125 (lshiftrt:DI (match_operand:DI 1 "s_register_operand" "")
4126 (match_operand:SI 2 "reg_or_int_operand" "")))]
4131 /* Delay the decision whether to use NEON or core-regs until
4132 register allocation. */
4133 emit_insn (gen_lshrdi3_neon (operands[0], operands[1], operands[2]));
4137 if (!CONST_INT_P (operands[2]) && TARGET_REALLY_IWMMXT)
4138 ; /* No special preparation statements; expand pattern as above. */
4141 rtx scratch1, scratch2;
4143 if (operands[2] == CONST1_RTX (SImode))
4145 emit_insn (gen_arm_lshrdi3_1bit (operands[0], operands[1]));
4149 /* Ideally we should use iwmmxt here if we could know that operands[1]
4150 ends up already living in an iwmmxt register. Otherwise it's
4151 cheaper to have the alternate code being generated than moving
4152 values to iwmmxt regs and back. */
4154 /* Expand operation using core-registers.
4155 'FAIL' would achieve the same thing, but this is a bit smarter. */
4156 scratch1 = gen_reg_rtx (SImode);
4157 scratch2 = gen_reg_rtx (SImode);
4158 arm_emit_coreregs_64bit_shift (LSHIFTRT, operands[0], operands[1],
4159 operands[2], scratch1, scratch2);
4165 (define_insn "arm_lshrdi3_1bit"
4166 [(set (match_operand:DI 0 "s_register_operand" "=r,&r")
4167 (lshiftrt:DI (match_operand:DI 1 "s_register_operand" "0,r")
4169 (clobber (reg:CC CC_REGNUM))]
4171 "movs\\t%R0, %R1, lsr #1\;mov\\t%Q0, %Q1, rrx"
4172 [(set_attr "conds" "clob")
4173 (set_attr "length" "8")
4174 (set_attr "type" "multiple")]
4177 (define_expand "lshrsi3"
4178 [(set (match_operand:SI 0 "s_register_operand" "")
4179 (lshiftrt:SI (match_operand:SI 1 "s_register_operand" "")
4180 (match_operand:SI 2 "arm_rhs_operand" "")))]
4183 if (CONST_INT_P (operands[2])
4184 && (UINTVAL (operands[2])) > 31)
4186 emit_insn (gen_movsi (operands[0], const0_rtx));
4192 (define_expand "rotlsi3"
4193 [(set (match_operand:SI 0 "s_register_operand" "")
4194 (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
4195 (match_operand:SI 2 "reg_or_int_operand" "")))]
4198 if (CONST_INT_P (operands[2]))
4199 operands[2] = GEN_INT ((32 - INTVAL (operands[2])) % 32);
4202 rtx reg = gen_reg_rtx (SImode);
4203 emit_insn (gen_subsi3 (reg, GEN_INT (32), operands[2]));
4209 (define_expand "rotrsi3"
4210 [(set (match_operand:SI 0 "s_register_operand" "")
4211 (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
4212 (match_operand:SI 2 "arm_rhs_operand" "")))]
4217 if (CONST_INT_P (operands[2])
4218 && UINTVAL (operands[2]) > 31)
4219 operands[2] = GEN_INT (INTVAL (operands[2]) % 32);
4221 else /* TARGET_THUMB1 */
4223 if (CONST_INT_P (operands [2]))
4224 operands [2] = force_reg (SImode, operands[2]);
4229 (define_insn "*arm_shiftsi3"
4230 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r,r")
4231 (match_operator:SI 3 "shift_operator"
4232 [(match_operand:SI 1 "s_register_operand" "0,l,r,r")
4233 (match_operand:SI 2 "reg_or_int_operand" "l,M,M,r")]))]
4235 "* return arm_output_shift(operands, 0);"
4236 [(set_attr "predicable" "yes")
4237 (set_attr "arch" "t2,t2,*,*")
4238 (set_attr "predicable_short_it" "yes,yes,no,no")
4239 (set_attr "length" "4")
4240 (set_attr "shift" "1")
4241 (set_attr "type" "alu_shift_reg,alu_shift_imm,alu_shift_imm,alu_shift_reg")]
4244 (define_insn "*shiftsi3_compare0"
4245 [(set (reg:CC_NOOV CC_REGNUM)
4246 (compare:CC_NOOV (match_operator:SI 3 "shift_operator"
4247 [(match_operand:SI 1 "s_register_operand" "r,r")
4248 (match_operand:SI 2 "arm_rhs_operand" "M,r")])
4250 (set (match_operand:SI 0 "s_register_operand" "=r,r")
4251 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))]
4253 "* return arm_output_shift(operands, 1);"
4254 [(set_attr "conds" "set")
4255 (set_attr "shift" "1")
4256 (set_attr "type" "alus_shift_imm,alus_shift_reg")]
4259 (define_insn "*shiftsi3_compare0_scratch"
4260 [(set (reg:CC_NOOV CC_REGNUM)
4261 (compare:CC_NOOV (match_operator:SI 3 "shift_operator"
4262 [(match_operand:SI 1 "s_register_operand" "r,r")
4263 (match_operand:SI 2 "arm_rhs_operand" "M,r")])
4265 (clobber (match_scratch:SI 0 "=r,r"))]
4267 "* return arm_output_shift(operands, 1);"
4268 [(set_attr "conds" "set")
4269 (set_attr "shift" "1")
4270 (set_attr "type" "shift_imm,shift_reg")]
4273 (define_insn "*not_shiftsi"
4274 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4275 (not:SI (match_operator:SI 3 "shift_operator"
4276 [(match_operand:SI 1 "s_register_operand" "r,r")
4277 (match_operand:SI 2 "shift_amount_operand" "M,rM")])))]
4280 [(set_attr "predicable" "yes")
4281 (set_attr "predicable_short_it" "no")
4282 (set_attr "shift" "1")
4283 (set_attr "arch" "32,a")
4284 (set_attr "type" "mvn_shift,mvn_shift_reg")])
4286 (define_insn "*not_shiftsi_compare0"
4287 [(set (reg:CC_NOOV CC_REGNUM)
4289 (not:SI (match_operator:SI 3 "shift_operator"
4290 [(match_operand:SI 1 "s_register_operand" "r,r")
4291 (match_operand:SI 2 "shift_amount_operand" "M,rM")]))
4293 (set (match_operand:SI 0 "s_register_operand" "=r,r")
4294 (not:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])))]
4296 "mvns%?\\t%0, %1%S3"
4297 [(set_attr "conds" "set")
4298 (set_attr "shift" "1")
4299 (set_attr "arch" "32,a")
4300 (set_attr "type" "mvn_shift,mvn_shift_reg")])
4302 (define_insn "*not_shiftsi_compare0_scratch"
4303 [(set (reg:CC_NOOV CC_REGNUM)
4305 (not:SI (match_operator:SI 3 "shift_operator"
4306 [(match_operand:SI 1 "s_register_operand" "r,r")
4307 (match_operand:SI 2 "shift_amount_operand" "M,rM")]))
4309 (clobber (match_scratch:SI 0 "=r,r"))]
4311 "mvns%?\\t%0, %1%S3"
4312 [(set_attr "conds" "set")
4313 (set_attr "shift" "1")
4314 (set_attr "arch" "32,a")
4315 (set_attr "type" "mvn_shift,mvn_shift_reg")])
4317 ;; We don't really have extzv, but defining this using shifts helps
4318 ;; to reduce register pressure later on.
4320 (define_expand "extzv"
4321 [(set (match_operand 0 "s_register_operand" "")
4322 (zero_extract (match_operand 1 "nonimmediate_operand" "")
4323 (match_operand 2 "const_int_operand" "")
4324 (match_operand 3 "const_int_operand" "")))]
4325 "TARGET_THUMB1 || arm_arch_thumb2"
4328 HOST_WIDE_INT lshift = 32 - INTVAL (operands[2]) - INTVAL (operands[3]);
4329 HOST_WIDE_INT rshift = 32 - INTVAL (operands[2]);
4331 if (arm_arch_thumb2)
4333 HOST_WIDE_INT width = INTVAL (operands[2]);
4334 HOST_WIDE_INT bitpos = INTVAL (operands[3]);
4336 if (unaligned_access && MEM_P (operands[1])
4337 && (width == 16 || width == 32) && (bitpos % BITS_PER_UNIT) == 0)
4341 if (BYTES_BIG_ENDIAN)
4342 bitpos = GET_MODE_BITSIZE (GET_MODE (operands[0])) - width
4347 base_addr = adjust_address (operands[1], SImode,
4348 bitpos / BITS_PER_UNIT);
4349 emit_insn (gen_unaligned_loadsi (operands[0], base_addr));
4353 rtx dest = operands[0];
4354 rtx tmp = gen_reg_rtx (SImode);
4356 /* We may get a paradoxical subreg here. Strip it off. */
4357 if (GET_CODE (dest) == SUBREG
4358 && GET_MODE (dest) == SImode
4359 && GET_MODE (SUBREG_REG (dest)) == HImode)
4360 dest = SUBREG_REG (dest);
4362 if (GET_MODE_BITSIZE (GET_MODE (dest)) != width)
4365 base_addr = adjust_address (operands[1], HImode,
4366 bitpos / BITS_PER_UNIT);
4367 emit_insn (gen_unaligned_loadhiu (tmp, base_addr));
4368 emit_move_insn (gen_lowpart (SImode, dest), tmp);
4372 else if (s_register_operand (operands[1], GET_MODE (operands[1])))
4374 emit_insn (gen_extzv_t2 (operands[0], operands[1], operands[2],
4382 if (!s_register_operand (operands[1], GET_MODE (operands[1])))
4385 operands[3] = GEN_INT (rshift);
4389 emit_insn (gen_lshrsi3 (operands[0], operands[1], operands[3]));
4393 emit_insn (gen_extzv_t1 (operands[0], operands[1], GEN_INT (lshift),
4394 operands[3], gen_reg_rtx (SImode)));
4399 ;; Helper for extzv, for the Thumb-1 register-shifts case.
4401 (define_expand "extzv_t1"
4402 [(set (match_operand:SI 4 "s_register_operand" "")
4403 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
4404 (match_operand:SI 2 "const_int_operand" "")))
4405 (set (match_operand:SI 0 "s_register_operand" "")
4406 (lshiftrt:SI (match_dup 4)
4407 (match_operand:SI 3 "const_int_operand" "")))]
4411 (define_expand "extv"
4412 [(set (match_operand 0 "s_register_operand" "")
4413 (sign_extract (match_operand 1 "nonimmediate_operand" "")
4414 (match_operand 2 "const_int_operand" "")
4415 (match_operand 3 "const_int_operand" "")))]
4418 HOST_WIDE_INT width = INTVAL (operands[2]);
4419 HOST_WIDE_INT bitpos = INTVAL (operands[3]);
4421 if (unaligned_access && MEM_P (operands[1]) && (width == 16 || width == 32)
4422 && (bitpos % BITS_PER_UNIT) == 0)
4426 if (BYTES_BIG_ENDIAN)
4427 bitpos = GET_MODE_BITSIZE (GET_MODE (operands[0])) - width - bitpos;
4431 base_addr = adjust_address (operands[1], SImode,
4432 bitpos / BITS_PER_UNIT);
4433 emit_insn (gen_unaligned_loadsi (operands[0], base_addr));
4437 rtx dest = operands[0];
4438 rtx tmp = gen_reg_rtx (SImode);
4440 /* We may get a paradoxical subreg here. Strip it off. */
4441 if (GET_CODE (dest) == SUBREG
4442 && GET_MODE (dest) == SImode
4443 && GET_MODE (SUBREG_REG (dest)) == HImode)
4444 dest = SUBREG_REG (dest);
4446 if (GET_MODE_BITSIZE (GET_MODE (dest)) != width)
4449 base_addr = adjust_address (operands[1], HImode,
4450 bitpos / BITS_PER_UNIT);
4451 emit_insn (gen_unaligned_loadhis (tmp, base_addr));
4452 emit_move_insn (gen_lowpart (SImode, dest), tmp);
4457 else if (!s_register_operand (operands[1], GET_MODE (operands[1])))
4459 else if (GET_MODE (operands[0]) == SImode
4460 && GET_MODE (operands[1]) == SImode)
4462 emit_insn (gen_extv_regsi (operands[0], operands[1], operands[2],
4470 ; Helper to expand register forms of extv with the proper modes.
4472 (define_expand "extv_regsi"
4473 [(set (match_operand:SI 0 "s_register_operand" "")
4474 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "")
4475 (match_operand 2 "const_int_operand" "")
4476 (match_operand 3 "const_int_operand" "")))]
4481 ; ARMv6+ unaligned load/store instructions (used for packed structure accesses).
4483 (define_insn "unaligned_loadsi"
4484 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4485 (unspec:SI [(match_operand:SI 1 "memory_operand" "Uw,m")]
4486 UNSPEC_UNALIGNED_LOAD))]
4488 "ldr%?\t%0, %1\t@ unaligned"
4489 [(set_attr "arch" "t2,any")
4490 (set_attr "length" "2,4")
4491 (set_attr "predicable" "yes")
4492 (set_attr "predicable_short_it" "yes,no")
4493 (set_attr "type" "load1")])
4495 (define_insn "unaligned_loadhis"
4496 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4498 (unspec:HI [(match_operand:HI 1 "memory_operand" "Uw,Uh")]
4499 UNSPEC_UNALIGNED_LOAD)))]
4501 "ldrsh%?\t%0, %1\t@ unaligned"
4502 [(set_attr "arch" "t2,any")
4503 (set_attr "length" "2,4")
4504 (set_attr "predicable" "yes")
4505 (set_attr "predicable_short_it" "yes,no")
4506 (set_attr "type" "load_byte")])
4508 (define_insn "unaligned_loadhiu"
4509 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4511 (unspec:HI [(match_operand:HI 1 "memory_operand" "Uw,m")]
4512 UNSPEC_UNALIGNED_LOAD)))]
4514 "ldrh%?\t%0, %1\t@ unaligned"
4515 [(set_attr "arch" "t2,any")
4516 (set_attr "length" "2,4")
4517 (set_attr "predicable" "yes")
4518 (set_attr "predicable_short_it" "yes,no")
4519 (set_attr "type" "load_byte")])
4521 (define_insn "unaligned_storesi"
4522 [(set (match_operand:SI 0 "memory_operand" "=Uw,m")
4523 (unspec:SI [(match_operand:SI 1 "s_register_operand" "l,r")]
4524 UNSPEC_UNALIGNED_STORE))]
4526 "str%?\t%1, %0\t@ unaligned"
4527 [(set_attr "arch" "t2,any")
4528 (set_attr "length" "2,4")
4529 (set_attr "predicable" "yes")
4530 (set_attr "predicable_short_it" "yes,no")
4531 (set_attr "type" "store1")])
4533 (define_insn "unaligned_storehi"
4534 [(set (match_operand:HI 0 "memory_operand" "=Uw,m")
4535 (unspec:HI [(match_operand:HI 1 "s_register_operand" "l,r")]
4536 UNSPEC_UNALIGNED_STORE))]
4538 "strh%?\t%1, %0\t@ unaligned"
4539 [(set_attr "arch" "t2,any")
4540 (set_attr "length" "2,4")
4541 (set_attr "predicable" "yes")
4542 (set_attr "predicable_short_it" "yes,no")
4543 (set_attr "type" "store1")])
4546 (define_insn "*extv_reg"
4547 [(set (match_operand:SI 0 "s_register_operand" "=r")
4548 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
4549 (match_operand:SI 2 "const_int_M_operand" "M")
4550 (match_operand:SI 3 "const_int_M_operand" "M")))]
4552 "sbfx%?\t%0, %1, %3, %2"
4553 [(set_attr "length" "4")
4554 (set_attr "predicable" "yes")
4555 (set_attr "predicable_short_it" "no")
4556 (set_attr "type" "bfm")]
4559 (define_insn "extzv_t2"
4560 [(set (match_operand:SI 0 "s_register_operand" "=r")
4561 (zero_extract:SI (match_operand:SI 1 "s_register_operand" "r")
4562 (match_operand:SI 2 "const_int_M_operand" "M")
4563 (match_operand:SI 3 "const_int_M_operand" "M")))]
4565 "ubfx%?\t%0, %1, %3, %2"
4566 [(set_attr "length" "4")
4567 (set_attr "predicable" "yes")
4568 (set_attr "predicable_short_it" "no")
4569 (set_attr "type" "bfm")]
4573 ;; Division instructions
4574 (define_insn "divsi3"
4575 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4576 (div:SI (match_operand:SI 1 "s_register_operand" "r,r")
4577 (match_operand:SI 2 "s_register_operand" "r,r")))]
4582 [(set_attr "arch" "32,v8mb")
4583 (set_attr "predicable" "yes")
4584 (set_attr "predicable_short_it" "no")
4585 (set_attr "type" "sdiv")]
4588 (define_insn "udivsi3"
4589 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4590 (udiv:SI (match_operand:SI 1 "s_register_operand" "r,r")
4591 (match_operand:SI 2 "s_register_operand" "r,r")))]
4596 [(set_attr "arch" "32,v8mb")
4597 (set_attr "predicable" "yes")
4598 (set_attr "predicable_short_it" "no")
4599 (set_attr "type" "udiv")]
4603 ;; Unary arithmetic insns
4605 (define_expand "negvsi3"
4606 [(match_operand:SI 0 "register_operand")
4607 (match_operand:SI 1 "register_operand")
4608 (match_operand 2 "")]
4611 emit_insn (gen_subsi3_compare (operands[0], const0_rtx, operands[1]));
4612 arm_gen_unlikely_cbranch (NE, CC_Vmode, operands[2]);
4617 (define_expand "negvdi3"
4618 [(match_operand:DI 0 "register_operand")
4619 (match_operand:DI 1 "register_operand")
4620 (match_operand 2 "")]
4623 emit_insn (gen_negdi2_compare (operands[0], operands[1]));
4624 arm_gen_unlikely_cbranch (NE, CC_Vmode, operands[2]);
4630 (define_insn_and_split "negdi2_compare"
4631 [(set (reg:CC CC_REGNUM)
4634 (match_operand:DI 1 "register_operand" "0,r")))
4635 (set (match_operand:DI 0 "register_operand" "=r,&r")
4636 (minus:DI (const_int 0) (match_dup 1)))]
4639 "&& reload_completed"
4640 [(parallel [(set (reg:CC CC_REGNUM)
4641 (compare:CC (const_int 0) (match_dup 1)))
4642 (set (match_dup 0) (minus:SI (const_int 0)
4644 (parallel [(set (reg:CC CC_REGNUM)
4645 (compare:CC (const_int 0) (match_dup 3)))
4648 (minus:SI (const_int 0) (match_dup 3))
4649 (ltu:SI (reg:CC_C CC_REGNUM)
4652 operands[2] = gen_highpart (SImode, operands[0]);
4653 operands[0] = gen_lowpart (SImode, operands[0]);
4654 operands[3] = gen_highpart (SImode, operands[1]);
4655 operands[1] = gen_lowpart (SImode, operands[1]);
4657 [(set_attr "conds" "set")
4658 (set_attr "length" "8")
4659 (set_attr "type" "multiple")]
4662 (define_expand "negdi2"
4664 [(set (match_operand:DI 0 "s_register_operand" "")
4665 (neg:DI (match_operand:DI 1 "s_register_operand" "")))
4666 (clobber (reg:CC CC_REGNUM))])]
4671 emit_insn (gen_negdi2_neon (operands[0], operands[1]));
4677 ;; The constraints here are to prevent a *partial* overlap (where %Q0 == %R1).
4678 ;; The first alternative allows the common case of a *full* overlap.
4679 (define_insn_and_split "*arm_negdi2"
4680 [(set (match_operand:DI 0 "s_register_operand" "=r,&r")
4681 (neg:DI (match_operand:DI 1 "s_register_operand" "0,r")))
4682 (clobber (reg:CC CC_REGNUM))]
4684 "#" ; "rsbs\\t%Q0, %Q1, #0\;rsc\\t%R0, %R1, #0"
4685 "&& reload_completed"
4686 [(parallel [(set (reg:CC CC_REGNUM)
4687 (compare:CC (const_int 0) (match_dup 1)))
4688 (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1)))])
4689 (set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3))
4690 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
4692 operands[2] = gen_highpart (SImode, operands[0]);
4693 operands[0] = gen_lowpart (SImode, operands[0]);
4694 operands[3] = gen_highpart (SImode, operands[1]);
4695 operands[1] = gen_lowpart (SImode, operands[1]);
4697 [(set_attr "conds" "clob")
4698 (set_attr "length" "8")
4699 (set_attr "type" "multiple")]
4702 (define_insn "*negsi2_carryin_compare"
4703 [(set (reg:CC CC_REGNUM)
4704 (compare:CC (const_int 0)
4705 (match_operand:SI 1 "s_register_operand" "r")))
4706 (set (match_operand:SI 0 "s_register_operand" "=r")
4707 (minus:SI (minus:SI (const_int 0)
4709 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
4712 [(set_attr "conds" "set")
4713 (set_attr "type" "alus_imm")]
4716 (define_expand "negsi2"
4717 [(set (match_operand:SI 0 "s_register_operand" "")
4718 (neg:SI (match_operand:SI 1 "s_register_operand" "")))]
4723 (define_insn "*arm_negsi2"
4724 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4725 (neg:SI (match_operand:SI 1 "s_register_operand" "l,r")))]
4727 "rsb%?\\t%0, %1, #0"
4728 [(set_attr "predicable" "yes")
4729 (set_attr "predicable_short_it" "yes,no")
4730 (set_attr "arch" "t2,*")
4731 (set_attr "length" "4")
4732 (set_attr "type" "alu_sreg")]
4735 (define_expand "negsf2"
4736 [(set (match_operand:SF 0 "s_register_operand" "")
4737 (neg:SF (match_operand:SF 1 "s_register_operand" "")))]
4738 "TARGET_32BIT && TARGET_HARD_FLOAT"
4742 (define_expand "negdf2"
4743 [(set (match_operand:DF 0 "s_register_operand" "")
4744 (neg:DF (match_operand:DF 1 "s_register_operand" "")))]
4745 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
4748 (define_insn_and_split "*zextendsidi_negsi"
4749 [(set (match_operand:DI 0 "s_register_operand" "=r")
4750 (zero_extend:DI (neg:SI (match_operand:SI 1 "s_register_operand" "r"))))]
4755 (neg:SI (match_dup 1)))
4759 operands[2] = gen_lowpart (SImode, operands[0]);
4760 operands[3] = gen_highpart (SImode, operands[0]);
4762 [(set_attr "length" "8")
4763 (set_attr "type" "multiple")]
4766 ;; Negate an extended 32-bit value.
4767 (define_insn_and_split "*negdi_extendsidi"
4768 [(set (match_operand:DI 0 "s_register_operand" "=l,r")
4769 (neg:DI (sign_extend:DI
4770 (match_operand:SI 1 "s_register_operand" "l,r"))))
4771 (clobber (reg:CC CC_REGNUM))]
4774 "&& reload_completed"
4777 rtx low = gen_lowpart (SImode, operands[0]);
4778 rtx high = gen_highpart (SImode, operands[0]);
4780 if (reg_overlap_mentioned_p (low, operands[1]))
4782 /* Input overlaps the low word of the output. Use:
4785 rsc Rhi, Rhi, #0 (thumb2: sbc Rhi, Rhi, Rhi, lsl #1). */
4786 rtx cc_reg = gen_rtx_REG (CC_Cmode, CC_REGNUM);
4788 emit_insn (gen_rtx_SET (high,
4789 gen_rtx_ASHIFTRT (SImode, operands[1],
4792 emit_insn (gen_subsi3_compare (low, const0_rtx, operands[1]));
4794 emit_insn (gen_rtx_SET (high,
4795 gen_rtx_MINUS (SImode,
4796 gen_rtx_MINUS (SImode,
4799 gen_rtx_LTU (SImode,
4804 rtx two_x = gen_rtx_ASHIFT (SImode, high, GEN_INT (1));
4805 emit_insn (gen_rtx_SET (high,
4806 gen_rtx_MINUS (SImode,
4807 gen_rtx_MINUS (SImode,
4810 gen_rtx_LTU (SImode,
4817 /* No overlap, or overlap on high word. Use:
4821 Flags not needed for this sequence. */
4822 emit_insn (gen_rtx_SET (low, gen_rtx_NEG (SImode, operands[1])));
4823 emit_insn (gen_rtx_SET (high,
4824 gen_rtx_AND (SImode,
4825 gen_rtx_NOT (SImode, operands[1]),
4827 emit_insn (gen_rtx_SET (high,
4828 gen_rtx_ASHIFTRT (SImode, high,
4833 [(set_attr "length" "12")
4834 (set_attr "arch" "t2,*")
4835 (set_attr "type" "multiple")]
4838 (define_insn_and_split "*negdi_zero_extendsidi"
4839 [(set (match_operand:DI 0 "s_register_operand" "=r,&r")
4840 (neg:DI (zero_extend:DI (match_operand:SI 1 "s_register_operand" "0,r"))))
4841 (clobber (reg:CC CC_REGNUM))]
4843 "#" ; "rsbs\\t%Q0, %1, #0\;sbc\\t%R0,%R0,%R0"
4844 ;; Don't care what register is input to sbc,
4845 ;; since we just need to propagate the carry.
4846 "&& reload_completed"
4847 [(parallel [(set (reg:CC CC_REGNUM)
4848 (compare:CC (const_int 0) (match_dup 1)))
4849 (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1)))])
4850 (set (match_dup 2) (minus:SI (minus:SI (match_dup 2) (match_dup 2))
4851 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
4853 operands[2] = gen_highpart (SImode, operands[0]);
4854 operands[0] = gen_lowpart (SImode, operands[0]);
4856 [(set_attr "conds" "clob")
4857 (set_attr "length" "8")
4858 (set_attr "type" "multiple")] ;; length in thumb is 4
4861 ;; abssi2 doesn't really clobber the condition codes if a different register
4862 ;; is being set. To keep things simple, assume during rtl manipulations that
4863 ;; it does, but tell the final scan operator the truth. Similarly for
4866 (define_expand "abssi2"
4868 [(set (match_operand:SI 0 "s_register_operand" "")
4869 (abs:SI (match_operand:SI 1 "s_register_operand" "")))
4870 (clobber (match_dup 2))])]
4874 operands[2] = gen_rtx_SCRATCH (SImode);
4876 operands[2] = gen_rtx_REG (CCmode, CC_REGNUM);
4879 (define_insn_and_split "*arm_abssi2"
4880 [(set (match_operand:SI 0 "s_register_operand" "=r,&r")
4881 (abs:SI (match_operand:SI 1 "s_register_operand" "0,r")))
4882 (clobber (reg:CC CC_REGNUM))]
4885 "&& reload_completed"
4888 /* if (which_alternative == 0) */
4889 if (REGNO(operands[0]) == REGNO(operands[1]))
4891 /* Emit the pattern:
4892 cmp\\t%0, #0\;rsblt\\t%0, %0, #0
4893 [(set (reg:CC CC_REGNUM)
4894 (compare:CC (match_dup 0) (const_int 0)))
4895 (cond_exec (lt:CC (reg:CC CC_REGNUM) (const_int 0))
4896 (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1))))]
4898 emit_insn (gen_rtx_SET (gen_rtx_REG (CCmode, CC_REGNUM),
4899 gen_rtx_COMPARE (CCmode, operands[0], const0_rtx)));
4900 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
4901 (gen_rtx_LT (SImode,
4902 gen_rtx_REG (CCmode, CC_REGNUM),
4904 (gen_rtx_SET (operands[0],
4905 (gen_rtx_MINUS (SImode,
4912 /* Emit the pattern:
4913 alt1: eor%?\\t%0, %1, %1, asr #31\;sub%?\\t%0, %0, %1, asr #31
4915 (xor:SI (match_dup 1)
4916 (ashiftrt:SI (match_dup 1) (const_int 31))))
4918 (minus:SI (match_dup 0)
4919 (ashiftrt:SI (match_dup 1) (const_int 31))))]
4921 emit_insn (gen_rtx_SET (operands[0],
4922 gen_rtx_XOR (SImode,
4923 gen_rtx_ASHIFTRT (SImode,
4927 emit_insn (gen_rtx_SET (operands[0],
4928 gen_rtx_MINUS (SImode,
4930 gen_rtx_ASHIFTRT (SImode,
4936 [(set_attr "conds" "clob,*")
4937 (set_attr "shift" "1")
4938 (set_attr "predicable" "no, yes")
4939 (set_attr "length" "8")
4940 (set_attr "type" "multiple")]
4943 (define_insn_and_split "*arm_neg_abssi2"
4944 [(set (match_operand:SI 0 "s_register_operand" "=r,&r")
4945 (neg:SI (abs:SI (match_operand:SI 1 "s_register_operand" "0,r"))))
4946 (clobber (reg:CC CC_REGNUM))]
4949 "&& reload_completed"
4952 /* if (which_alternative == 0) */
4953 if (REGNO (operands[0]) == REGNO (operands[1]))
4955 /* Emit the pattern:
4956 cmp\\t%0, #0\;rsbgt\\t%0, %0, #0
4958 emit_insn (gen_rtx_SET (gen_rtx_REG (CCmode, CC_REGNUM),
4959 gen_rtx_COMPARE (CCmode, operands[0], const0_rtx)));
4960 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
4962 gen_rtx_REG (CCmode, CC_REGNUM),
4964 gen_rtx_SET (operands[0],
4965 (gen_rtx_MINUS (SImode,
4971 /* Emit the pattern:
4972 eor%?\\t%0, %1, %1, asr #31\;rsb%?\\t%0, %0, %1, asr #31
4974 emit_insn (gen_rtx_SET (operands[0],
4975 gen_rtx_XOR (SImode,
4976 gen_rtx_ASHIFTRT (SImode,
4980 emit_insn (gen_rtx_SET (operands[0],
4981 gen_rtx_MINUS (SImode,
4982 gen_rtx_ASHIFTRT (SImode,
4989 [(set_attr "conds" "clob,*")
4990 (set_attr "shift" "1")
4991 (set_attr "predicable" "no, yes")
4992 (set_attr "length" "8")
4993 (set_attr "type" "multiple")]
4996 (define_expand "abssf2"
4997 [(set (match_operand:SF 0 "s_register_operand" "")
4998 (abs:SF (match_operand:SF 1 "s_register_operand" "")))]
4999 "TARGET_32BIT && TARGET_HARD_FLOAT"
5002 (define_expand "absdf2"
5003 [(set (match_operand:DF 0 "s_register_operand" "")
5004 (abs:DF (match_operand:DF 1 "s_register_operand" "")))]
5005 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
5008 (define_expand "sqrtsf2"
5009 [(set (match_operand:SF 0 "s_register_operand" "")
5010 (sqrt:SF (match_operand:SF 1 "s_register_operand" "")))]
5011 "TARGET_32BIT && TARGET_HARD_FLOAT"
5014 (define_expand "sqrtdf2"
5015 [(set (match_operand:DF 0 "s_register_operand" "")
5016 (sqrt:DF (match_operand:DF 1 "s_register_operand" "")))]
5017 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
5020 (define_insn_and_split "one_cmpldi2"
5021 [(set (match_operand:DI 0 "s_register_operand" "=w,&r,&r,?w")
5022 (not:DI (match_operand:DI 1 "s_register_operand" " w, 0, r, w")))]
5029 "TARGET_32BIT && reload_completed
5030 && arm_general_register_operand (operands[0], DImode)"
5031 [(set (match_dup 0) (not:SI (match_dup 1)))
5032 (set (match_dup 2) (not:SI (match_dup 3)))]
5035 operands[2] = gen_highpart (SImode, operands[0]);
5036 operands[0] = gen_lowpart (SImode, operands[0]);
5037 operands[3] = gen_highpart (SImode, operands[1]);
5038 operands[1] = gen_lowpart (SImode, operands[1]);
5040 [(set_attr "length" "*,8,8,*")
5041 (set_attr "predicable" "no,yes,yes,no")
5042 (set_attr "type" "neon_move,multiple,multiple,neon_move")
5043 (set_attr "arch" "neon_for_64bits,*,*,avoid_neon_for_64bits")]
5046 (define_expand "one_cmplsi2"
5047 [(set (match_operand:SI 0 "s_register_operand" "")
5048 (not:SI (match_operand:SI 1 "s_register_operand" "")))]
5053 (define_insn "*arm_one_cmplsi2"
5054 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
5055 (not:SI (match_operand:SI 1 "s_register_operand" "l,r")))]
5058 [(set_attr "predicable" "yes")
5059 (set_attr "predicable_short_it" "yes,no")
5060 (set_attr "arch" "t2,*")
5061 (set_attr "length" "4")
5062 (set_attr "type" "mvn_reg")]
5065 (define_insn "*notsi_compare0"
5066 [(set (reg:CC_NOOV CC_REGNUM)
5067 (compare:CC_NOOV (not:SI (match_operand:SI 1 "s_register_operand" "r"))
5069 (set (match_operand:SI 0 "s_register_operand" "=r")
5070 (not:SI (match_dup 1)))]
5073 [(set_attr "conds" "set")
5074 (set_attr "type" "mvn_reg")]
5077 (define_insn "*notsi_compare0_scratch"
5078 [(set (reg:CC_NOOV CC_REGNUM)
5079 (compare:CC_NOOV (not:SI (match_operand:SI 1 "s_register_operand" "r"))
5081 (clobber (match_scratch:SI 0 "=r"))]
5084 [(set_attr "conds" "set")
5085 (set_attr "type" "mvn_reg")]
5088 ;; Fixed <--> Floating conversion insns
5090 (define_expand "floatsihf2"
5091 [(set (match_operand:HF 0 "general_operand" "")
5092 (float:HF (match_operand:SI 1 "general_operand" "")))]
5096 rtx op1 = gen_reg_rtx (SFmode);
5097 expand_float (op1, operands[1], 0);
5098 op1 = convert_to_mode (HFmode, op1, 0);
5099 emit_move_insn (operands[0], op1);
5104 (define_expand "floatdihf2"
5105 [(set (match_operand:HF 0 "general_operand" "")
5106 (float:HF (match_operand:DI 1 "general_operand" "")))]
5110 rtx op1 = gen_reg_rtx (SFmode);
5111 expand_float (op1, operands[1], 0);
5112 op1 = convert_to_mode (HFmode, op1, 0);
5113 emit_move_insn (operands[0], op1);
5118 (define_expand "floatsisf2"
5119 [(set (match_operand:SF 0 "s_register_operand" "")
5120 (float:SF (match_operand:SI 1 "s_register_operand" "")))]
5121 "TARGET_32BIT && TARGET_HARD_FLOAT"
5125 (define_expand "floatsidf2"
5126 [(set (match_operand:DF 0 "s_register_operand" "")
5127 (float:DF (match_operand:SI 1 "s_register_operand" "")))]
5128 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
5132 (define_expand "fix_trunchfsi2"
5133 [(set (match_operand:SI 0 "general_operand" "")
5134 (fix:SI (fix:HF (match_operand:HF 1 "general_operand" ""))))]
5138 rtx op1 = convert_to_mode (SFmode, operands[1], 0);
5139 expand_fix (operands[0], op1, 0);
5144 (define_expand "fix_trunchfdi2"
5145 [(set (match_operand:DI 0 "general_operand" "")
5146 (fix:DI (fix:HF (match_operand:HF 1 "general_operand" ""))))]
5150 rtx op1 = convert_to_mode (SFmode, operands[1], 0);
5151 expand_fix (operands[0], op1, 0);
5156 (define_expand "fix_truncsfsi2"
5157 [(set (match_operand:SI 0 "s_register_operand" "")
5158 (fix:SI (fix:SF (match_operand:SF 1 "s_register_operand" ""))))]
5159 "TARGET_32BIT && TARGET_HARD_FLOAT"
5163 (define_expand "fix_truncdfsi2"
5164 [(set (match_operand:SI 0 "s_register_operand" "")
5165 (fix:SI (fix:DF (match_operand:DF 1 "s_register_operand" ""))))]
5166 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
5172 (define_expand "truncdfsf2"
5173 [(set (match_operand:SF 0 "s_register_operand" "")
5175 (match_operand:DF 1 "s_register_operand" "")))]
5176 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
5180 ;; DFmode to HFmode conversions have to go through SFmode.
5181 (define_expand "truncdfhf2"
5182 [(set (match_operand:HF 0 "general_operand" "")
5184 (match_operand:DF 1 "general_operand" "")))]
5189 op1 = convert_to_mode (SFmode, operands[1], 0);
5190 op1 = convert_to_mode (HFmode, op1, 0);
5191 emit_move_insn (operands[0], op1);
5196 ;; Zero and sign extension instructions.
5198 (define_insn "zero_extend<mode>di2"
5199 [(set (match_operand:DI 0 "s_register_operand" "=w,r,?r,w")
5200 (zero_extend:DI (match_operand:QHSI 1 "<qhs_zextenddi_op>"
5201 "<qhs_zextenddi_cstr>")))]
5202 "TARGET_32BIT <qhs_zextenddi_cond>"
5204 [(set_attr "length" "8,4,8,8")
5205 (set_attr "arch" "neon_for_64bits,*,*,avoid_neon_for_64bits")
5206 (set_attr "ce_count" "2")
5207 (set_attr "predicable" "yes")
5208 (set_attr "type" "multiple,mov_reg,multiple,multiple")]
5211 (define_insn "extend<mode>di2"
5212 [(set (match_operand:DI 0 "s_register_operand" "=w,r,?r,?r,w")
5213 (sign_extend:DI (match_operand:QHSI 1 "<qhs_extenddi_op>"
5214 "<qhs_extenddi_cstr>")))]
5215 "TARGET_32BIT <qhs_sextenddi_cond>"
5217 [(set_attr "length" "8,4,8,8,8")
5218 (set_attr "ce_count" "2")
5219 (set_attr "shift" "1")
5220 (set_attr "predicable" "yes")
5221 (set_attr "arch" "neon_for_64bits,*,a,t,avoid_neon_for_64bits")
5222 (set_attr "type" "multiple,mov_reg,multiple,multiple,multiple")]
5225 ;; Splits for all extensions to DImode
5227 [(set (match_operand:DI 0 "s_register_operand" "")
5228 (zero_extend:DI (match_operand 1 "nonimmediate_operand" "")))]
5229 "TARGET_32BIT && reload_completed && !IS_VFP_REGNUM (REGNO (operands[0]))"
5230 [(set (match_dup 0) (match_dup 1))]
5232 rtx lo_part = gen_lowpart (SImode, operands[0]);
5233 machine_mode src_mode = GET_MODE (operands[1]);
5235 if (REG_P (operands[0])
5236 && !reg_overlap_mentioned_p (operands[0], operands[1]))
5237 emit_clobber (operands[0]);
5238 if (!REG_P (lo_part) || src_mode != SImode
5239 || !rtx_equal_p (lo_part, operands[1]))
5241 if (src_mode == SImode)
5242 emit_move_insn (lo_part, operands[1]);
5244 emit_insn (gen_rtx_SET (lo_part,
5245 gen_rtx_ZERO_EXTEND (SImode, operands[1])));
5246 operands[1] = lo_part;
5248 operands[0] = gen_highpart (SImode, operands[0]);
5249 operands[1] = const0_rtx;
5253 [(set (match_operand:DI 0 "s_register_operand" "")
5254 (sign_extend:DI (match_operand 1 "nonimmediate_operand" "")))]
5255 "TARGET_32BIT && reload_completed && !IS_VFP_REGNUM (REGNO (operands[0]))"
5256 [(set (match_dup 0) (ashiftrt:SI (match_dup 1) (const_int 31)))]
5258 rtx lo_part = gen_lowpart (SImode, operands[0]);
5259 machine_mode src_mode = GET_MODE (operands[1]);
5261 if (REG_P (operands[0])
5262 && !reg_overlap_mentioned_p (operands[0], operands[1]))
5263 emit_clobber (operands[0]);
5265 if (!REG_P (lo_part) || src_mode != SImode
5266 || !rtx_equal_p (lo_part, operands[1]))
5268 if (src_mode == SImode)
5269 emit_move_insn (lo_part, operands[1]);
5271 emit_insn (gen_rtx_SET (lo_part,
5272 gen_rtx_SIGN_EXTEND (SImode, operands[1])));
5273 operands[1] = lo_part;
5275 operands[0] = gen_highpart (SImode, operands[0]);
5278 (define_expand "zero_extendhisi2"
5279 [(set (match_operand:SI 0 "s_register_operand" "")
5280 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
5283 if (TARGET_ARM && !arm_arch4 && MEM_P (operands[1]))
5285 emit_insn (gen_movhi_bytes (operands[0], operands[1]));
5288 if (!arm_arch6 && !MEM_P (operands[1]))
5290 rtx t = gen_lowpart (SImode, operands[1]);
5291 rtx tmp = gen_reg_rtx (SImode);
5292 emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (16)));
5293 emit_insn (gen_lshrsi3 (operands[0], tmp, GEN_INT (16)));
5299 [(set (match_operand:SI 0 "s_register_operand" "")
5300 (zero_extend:SI (match_operand:HI 1 "s_register_operand" "")))]
5301 "!TARGET_THUMB2 && !arm_arch6"
5302 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
5303 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 16)))]
5305 operands[2] = gen_lowpart (SImode, operands[1]);
5308 (define_insn "*arm_zero_extendhisi2"
5309 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5310 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
5311 "TARGET_ARM && arm_arch4 && !arm_arch6"
5315 [(set_attr "type" "alu_shift_reg,load_byte")
5316 (set_attr "predicable" "yes")]
5319 (define_insn "*arm_zero_extendhisi2_v6"
5320 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5321 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,Uh")))]
5322 "TARGET_ARM && arm_arch6"
5326 [(set_attr "predicable" "yes")
5327 (set_attr "type" "extend,load_byte")]
5330 (define_insn "*arm_zero_extendhisi2addsi"
5331 [(set (match_operand:SI 0 "s_register_operand" "=r")
5332 (plus:SI (zero_extend:SI (match_operand:HI 1 "s_register_operand" "r"))
5333 (match_operand:SI 2 "s_register_operand" "r")))]
5335 "uxtah%?\\t%0, %2, %1"
5336 [(set_attr "type" "alu_shift_reg")
5337 (set_attr "predicable" "yes")
5338 (set_attr "predicable_short_it" "no")]
5341 (define_expand "zero_extendqisi2"
5342 [(set (match_operand:SI 0 "s_register_operand" "")
5343 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))]
5346 if (TARGET_ARM && !arm_arch6 && !MEM_P (operands[1]))
5348 emit_insn (gen_andsi3 (operands[0],
5349 gen_lowpart (SImode, operands[1]),
5353 if (!arm_arch6 && !MEM_P (operands[1]))
5355 rtx t = gen_lowpart (SImode, operands[1]);
5356 rtx tmp = gen_reg_rtx (SImode);
5357 emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (24)));
5358 emit_insn (gen_lshrsi3 (operands[0], tmp, GEN_INT (24)));
5364 [(set (match_operand:SI 0 "s_register_operand" "")
5365 (zero_extend:SI (match_operand:QI 1 "s_register_operand" "")))]
5367 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 24)))
5368 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 24)))]
5370 operands[2] = simplify_gen_subreg (SImode, operands[1], QImode, 0);
5373 emit_insn (gen_andsi3 (operands[0], operands[2], GEN_INT (255)));
5378 (define_insn "*arm_zero_extendqisi2"
5379 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5380 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
5381 "TARGET_ARM && !arm_arch6"
5384 ldrb%?\\t%0, %1\\t%@ zero_extendqisi2"
5385 [(set_attr "length" "8,4")
5386 (set_attr "type" "alu_shift_reg,load_byte")
5387 (set_attr "predicable" "yes")]
5390 (define_insn "*arm_zero_extendqisi2_v6"
5391 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5392 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,Uh")))]
5393 "TARGET_ARM && arm_arch6"
5396 ldrb%?\\t%0, %1\\t%@ zero_extendqisi2"
5397 [(set_attr "type" "extend,load_byte")
5398 (set_attr "predicable" "yes")]
5401 (define_insn "*arm_zero_extendqisi2addsi"
5402 [(set (match_operand:SI 0 "s_register_operand" "=r")
5403 (plus:SI (zero_extend:SI (match_operand:QI 1 "s_register_operand" "r"))
5404 (match_operand:SI 2 "s_register_operand" "r")))]
5406 "uxtab%?\\t%0, %2, %1"
5407 [(set_attr "predicable" "yes")
5408 (set_attr "predicable_short_it" "no")
5409 (set_attr "type" "alu_shift_reg")]
5413 [(set (match_operand:SI 0 "s_register_operand" "")
5414 (zero_extend:SI (subreg:QI (match_operand:SI 1 "" "") 0)))
5415 (clobber (match_operand:SI 2 "s_register_operand" ""))]
5416 "TARGET_32BIT && (!MEM_P (operands[1])) && ! BYTES_BIG_ENDIAN"
5417 [(set (match_dup 2) (match_dup 1))
5418 (set (match_dup 0) (and:SI (match_dup 2) (const_int 255)))]
5423 [(set (match_operand:SI 0 "s_register_operand" "")
5424 (zero_extend:SI (subreg:QI (match_operand:SI 1 "" "") 3)))
5425 (clobber (match_operand:SI 2 "s_register_operand" ""))]
5426 "TARGET_32BIT && (!MEM_P (operands[1])) && BYTES_BIG_ENDIAN"
5427 [(set (match_dup 2) (match_dup 1))
5428 (set (match_dup 0) (and:SI (match_dup 2) (const_int 255)))]
5434 [(set (match_operand:SI 0 "s_register_operand" "")
5435 (IOR_XOR:SI (and:SI (ashift:SI
5436 (match_operand:SI 1 "s_register_operand" "")
5437 (match_operand:SI 2 "const_int_operand" ""))
5438 (match_operand:SI 3 "const_int_operand" ""))
5440 (match_operator 5 "subreg_lowpart_operator"
5441 [(match_operand:SI 4 "s_register_operand" "")]))))]
5443 && (UINTVAL (operands[3])
5444 == (GET_MODE_MASK (GET_MODE (operands[5]))
5445 & (GET_MODE_MASK (GET_MODE (operands[5]))
5446 << (INTVAL (operands[2])))))"
5447 [(set (match_dup 0) (IOR_XOR:SI (ashift:SI (match_dup 1) (match_dup 2))
5449 (set (match_dup 0) (zero_extend:SI (match_dup 5)))]
5450 "operands[5] = gen_lowpart (GET_MODE (operands[5]), operands[0]);"
5453 (define_insn "*compareqi_eq0"
5454 [(set (reg:CC_Z CC_REGNUM)
5455 (compare:CC_Z (match_operand:QI 0 "s_register_operand" "r")
5459 [(set_attr "conds" "set")
5460 (set_attr "predicable" "yes")
5461 (set_attr "predicable_short_it" "no")
5462 (set_attr "type" "logic_imm")]
5465 (define_expand "extendhisi2"
5466 [(set (match_operand:SI 0 "s_register_operand" "")
5467 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
5472 emit_insn (gen_thumb1_extendhisi2 (operands[0], operands[1]));
5475 if (MEM_P (operands[1]) && TARGET_ARM && !arm_arch4)
5477 emit_insn (gen_extendhisi2_mem (operands[0], operands[1]));
5481 if (!arm_arch6 && !MEM_P (operands[1]))
5483 rtx t = gen_lowpart (SImode, operands[1]);
5484 rtx tmp = gen_reg_rtx (SImode);
5485 emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (16)));
5486 emit_insn (gen_ashrsi3 (operands[0], tmp, GEN_INT (16)));
5493 [(set (match_operand:SI 0 "register_operand" "")
5494 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))
5495 (clobber (match_scratch:SI 2 ""))])]
5497 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
5498 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
5500 operands[2] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
5503 ;; This pattern will only be used when ldsh is not available
5504 (define_expand "extendhisi2_mem"
5505 [(set (match_dup 2) (zero_extend:SI (match_operand:HI 1 "" "")))
5507 (zero_extend:SI (match_dup 7)))
5508 (set (match_dup 6) (ashift:SI (match_dup 4) (const_int 24)))
5509 (set (match_operand:SI 0 "" "")
5510 (ior:SI (ashiftrt:SI (match_dup 6) (const_int 16)) (match_dup 5)))]
5515 rtx addr = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
5517 mem1 = change_address (operands[1], QImode, addr);
5518 mem2 = change_address (operands[1], QImode,
5519 plus_constant (Pmode, addr, 1));
5520 operands[0] = gen_lowpart (SImode, operands[0]);
5522 operands[2] = gen_reg_rtx (SImode);
5523 operands[3] = gen_reg_rtx (SImode);
5524 operands[6] = gen_reg_rtx (SImode);
5527 if (BYTES_BIG_ENDIAN)
5529 operands[4] = operands[2];
5530 operands[5] = operands[3];
5534 operands[4] = operands[3];
5535 operands[5] = operands[2];
5541 [(set (match_operand:SI 0 "register_operand" "")
5542 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
5544 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
5545 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
5547 operands[2] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
5550 (define_insn "*arm_extendhisi2"
5551 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5552 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,Uh")))]
5553 "TARGET_ARM && arm_arch4 && !arm_arch6"
5557 [(set_attr "length" "8,4")
5558 (set_attr "type" "alu_shift_reg,load_byte")
5559 (set_attr "predicable" "yes")]
5562 ;; ??? Check Thumb-2 pool range
5563 (define_insn "*arm_extendhisi2_v6"
5564 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5565 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,Uh")))]
5566 "TARGET_32BIT && arm_arch6"
5570 [(set_attr "type" "extend,load_byte")
5571 (set_attr "predicable" "yes")
5572 (set_attr "predicable_short_it" "no")]
5575 (define_insn "*arm_extendhisi2addsi"
5576 [(set (match_operand:SI 0 "s_register_operand" "=r")
5577 (plus:SI (sign_extend:SI (match_operand:HI 1 "s_register_operand" "r"))
5578 (match_operand:SI 2 "s_register_operand" "r")))]
5580 "sxtah%?\\t%0, %2, %1"
5581 [(set_attr "type" "alu_shift_reg")]
5584 (define_expand "extendqihi2"
5586 (ashift:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "")
5588 (set (match_operand:HI 0 "s_register_operand" "")
5589 (ashiftrt:SI (match_dup 2)
5594 if (arm_arch4 && MEM_P (operands[1]))
5596 emit_insn (gen_rtx_SET (operands[0],
5597 gen_rtx_SIGN_EXTEND (HImode, operands[1])));
5600 if (!s_register_operand (operands[1], QImode))
5601 operands[1] = copy_to_mode_reg (QImode, operands[1]);
5602 operands[0] = gen_lowpart (SImode, operands[0]);
5603 operands[1] = gen_lowpart (SImode, operands[1]);
5604 operands[2] = gen_reg_rtx (SImode);
5608 (define_insn "*arm_extendqihi_insn"
5609 [(set (match_operand:HI 0 "s_register_operand" "=r")
5610 (sign_extend:HI (match_operand:QI 1 "arm_extendqisi_mem_op" "Uq")))]
5611 "TARGET_ARM && arm_arch4"
5613 [(set_attr "type" "load_byte")
5614 (set_attr "predicable" "yes")]
5617 (define_expand "extendqisi2"
5618 [(set (match_operand:SI 0 "s_register_operand" "")
5619 (sign_extend:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "")))]
5622 if (!arm_arch4 && MEM_P (operands[1]))
5623 operands[1] = copy_to_mode_reg (QImode, operands[1]);
5625 if (!arm_arch6 && !MEM_P (operands[1]))
5627 rtx t = gen_lowpart (SImode, operands[1]);
5628 rtx tmp = gen_reg_rtx (SImode);
5629 emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (24)));
5630 emit_insn (gen_ashrsi3 (operands[0], tmp, GEN_INT (24)));
5636 [(set (match_operand:SI 0 "register_operand" "")
5637 (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
5639 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 24)))
5640 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 24)))]
5642 operands[2] = simplify_gen_subreg (SImode, operands[1], QImode, 0);
5645 (define_insn "*arm_extendqisi"
5646 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5647 (sign_extend:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "r,Uq")))]
5648 "TARGET_ARM && arm_arch4 && !arm_arch6"
5652 [(set_attr "length" "8,4")
5653 (set_attr "type" "alu_shift_reg,load_byte")
5654 (set_attr "predicable" "yes")]
5657 (define_insn "*arm_extendqisi_v6"
5658 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5660 (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "r,Uq")))]
5661 "TARGET_ARM && arm_arch6"
5665 [(set_attr "type" "extend,load_byte")
5666 (set_attr "predicable" "yes")]
5669 (define_insn "*arm_extendqisi2addsi"
5670 [(set (match_operand:SI 0 "s_register_operand" "=r")
5671 (plus:SI (sign_extend:SI (match_operand:QI 1 "s_register_operand" "r"))
5672 (match_operand:SI 2 "s_register_operand" "r")))]
5674 "sxtab%?\\t%0, %2, %1"
5675 [(set_attr "type" "alu_shift_reg")
5676 (set_attr "predicable" "yes")
5677 (set_attr "predicable_short_it" "no")]
5680 (define_expand "extendsfdf2"
5681 [(set (match_operand:DF 0 "s_register_operand" "")
5682 (float_extend:DF (match_operand:SF 1 "s_register_operand" "")))]
5683 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
5687 ;; HFmode -> DFmode conversions have to go through SFmode.
5688 (define_expand "extendhfdf2"
5689 [(set (match_operand:DF 0 "general_operand" "")
5690 (float_extend:DF (match_operand:HF 1 "general_operand" "")))]
5695 op1 = convert_to_mode (SFmode, operands[1], 0);
5696 op1 = convert_to_mode (DFmode, op1, 0);
5697 emit_insn (gen_movdf (operands[0], op1));
5702 ;; Move insns (including loads and stores)
5704 ;; XXX Just some ideas about movti.
5705 ;; I don't think these are a good idea on the arm, there just aren't enough
5707 ;;(define_expand "loadti"
5708 ;; [(set (match_operand:TI 0 "s_register_operand" "")
5709 ;; (mem:TI (match_operand:SI 1 "address_operand" "")))]
5712 ;;(define_expand "storeti"
5713 ;; [(set (mem:TI (match_operand:TI 0 "address_operand" ""))
5714 ;; (match_operand:TI 1 "s_register_operand" ""))]
5717 ;;(define_expand "movti"
5718 ;; [(set (match_operand:TI 0 "general_operand" "")
5719 ;; (match_operand:TI 1 "general_operand" ""))]
5725 ;; if (MEM_P (operands[0]) && MEM_P (operands[1]))
5726 ;; operands[1] = copy_to_reg (operands[1]);
5727 ;; if (MEM_P (operands[0]))
5728 ;; insn = gen_storeti (XEXP (operands[0], 0), operands[1]);
5729 ;; else if (MEM_P (operands[1]))
5730 ;; insn = gen_loadti (operands[0], XEXP (operands[1], 0));
5734 ;; emit_insn (insn);
5738 ;; Recognize garbage generated above.
5741 ;; [(set (match_operand:TI 0 "general_operand" "=r,r,r,<,>,m")
5742 ;; (match_operand:TI 1 "general_operand" "<,>,m,r,r,r"))]
5746 ;; register mem = (which_alternative < 3);
5747 ;; register const char *template;
5749 ;; operands[mem] = XEXP (operands[mem], 0);
5750 ;; switch (which_alternative)
5752 ;; case 0: template = \"ldmdb\\t%1!, %M0\"; break;
5753 ;; case 1: template = \"ldmia\\t%1!, %M0\"; break;
5754 ;; case 2: template = \"ldmia\\t%1, %M0\"; break;
5755 ;; case 3: template = \"stmdb\\t%0!, %M1\"; break;
5756 ;; case 4: template = \"stmia\\t%0!, %M1\"; break;
5757 ;; case 5: template = \"stmia\\t%0, %M1\"; break;
5759 ;; output_asm_insn (template, operands);
5763 (define_expand "movdi"
5764 [(set (match_operand:DI 0 "general_operand" "")
5765 (match_operand:DI 1 "general_operand" ""))]
5768 if (can_create_pseudo_p ())
5770 if (!REG_P (operands[0]))
5771 operands[1] = force_reg (DImode, operands[1]);
5773 if (REG_P (operands[0]) && REGNO (operands[0]) <= LAST_ARM_REGNUM
5774 && !HARD_REGNO_MODE_OK (REGNO (operands[0]), DImode))
5776 /* Avoid LDRD's into an odd-numbered register pair in ARM state
5777 when expanding function calls. */
5778 gcc_assert (can_create_pseudo_p ());
5779 if (MEM_P (operands[1]) && MEM_VOLATILE_P (operands[1]))
5781 /* Perform load into legal reg pair first, then move. */
5782 rtx reg = gen_reg_rtx (DImode);
5783 emit_insn (gen_movdi (reg, operands[1]));
5786 emit_move_insn (gen_lowpart (SImode, operands[0]),
5787 gen_lowpart (SImode, operands[1]));
5788 emit_move_insn (gen_highpart (SImode, operands[0]),
5789 gen_highpart (SImode, operands[1]));
5792 else if (REG_P (operands[1]) && REGNO (operands[1]) <= LAST_ARM_REGNUM
5793 && !HARD_REGNO_MODE_OK (REGNO (operands[1]), DImode))
5795 /* Avoid STRD's from an odd-numbered register pair in ARM state
5796 when expanding function prologue. */
5797 gcc_assert (can_create_pseudo_p ());
5798 rtx split_dest = (MEM_P (operands[0]) && MEM_VOLATILE_P (operands[0]))
5799 ? gen_reg_rtx (DImode)
5801 emit_move_insn (gen_lowpart (SImode, split_dest),
5802 gen_lowpart (SImode, operands[1]));
5803 emit_move_insn (gen_highpart (SImode, split_dest),
5804 gen_highpart (SImode, operands[1]));
5805 if (split_dest != operands[0])
5806 emit_insn (gen_movdi (operands[0], split_dest));
5812 (define_insn "*arm_movdi"
5813 [(set (match_operand:DI 0 "nonimmediate_di_operand" "=r, r, r, q, m")
5814 (match_operand:DI 1 "di_operand" "rDa,Db,Dc,mi,q"))]
5816 && !(TARGET_HARD_FLOAT)
5818 && ( register_operand (operands[0], DImode)
5819 || register_operand (operands[1], DImode))"
5821 switch (which_alternative)
5828 return output_move_double (operands, true, NULL);
5831 [(set_attr "length" "8,12,16,8,8")
5832 (set_attr "type" "multiple,multiple,multiple,load2,store2")
5833 (set_attr "arm_pool_range" "*,*,*,1020,*")
5834 (set_attr "arm_neg_pool_range" "*,*,*,1004,*")
5835 (set_attr "thumb2_pool_range" "*,*,*,4094,*")
5836 (set_attr "thumb2_neg_pool_range" "*,*,*,0,*")]
5840 [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
5841 (match_operand:ANY64 1 "immediate_operand" ""))]
5844 && (arm_const_double_inline_cost (operands[1])
5845 <= arm_max_const_double_inline_cost ())"
5848 arm_split_constant (SET, SImode, curr_insn,
5849 INTVAL (gen_lowpart (SImode, operands[1])),
5850 gen_lowpart (SImode, operands[0]), NULL_RTX, 0);
5851 arm_split_constant (SET, SImode, curr_insn,
5852 INTVAL (gen_highpart_mode (SImode,
5853 GET_MODE (operands[0]),
5855 gen_highpart (SImode, operands[0]), NULL_RTX, 0);
5860 ; If optimizing for size, or if we have load delay slots, then
5861 ; we want to split the constant into two separate operations.
5862 ; In both cases this may split a trivial part into a single data op
5863 ; leaving a single complex constant to load. We can also get longer
5864 ; offsets in a LDR which means we get better chances of sharing the pool
5865 ; entries. Finally, we can normally do a better job of scheduling
5866 ; LDR instructions than we can with LDM.
5867 ; This pattern will only match if the one above did not.
5869 [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
5870 (match_operand:ANY64 1 "const_double_operand" ""))]
5871 "TARGET_ARM && reload_completed
5872 && arm_const_double_by_parts (operands[1])"
5873 [(set (match_dup 0) (match_dup 1))
5874 (set (match_dup 2) (match_dup 3))]
5876 operands[2] = gen_highpart (SImode, operands[0]);
5877 operands[3] = gen_highpart_mode (SImode, GET_MODE (operands[0]),
5879 operands[0] = gen_lowpart (SImode, operands[0]);
5880 operands[1] = gen_lowpart (SImode, operands[1]);
5885 [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
5886 (match_operand:ANY64 1 "arm_general_register_operand" ""))]
5887 "TARGET_EITHER && reload_completed"
5888 [(set (match_dup 0) (match_dup 1))
5889 (set (match_dup 2) (match_dup 3))]
5891 operands[2] = gen_highpart (SImode, operands[0]);
5892 operands[3] = gen_highpart (SImode, operands[1]);
5893 operands[0] = gen_lowpart (SImode, operands[0]);
5894 operands[1] = gen_lowpart (SImode, operands[1]);
5896 /* Handle a partial overlap. */
5897 if (rtx_equal_p (operands[0], operands[3]))
5899 rtx tmp0 = operands[0];
5900 rtx tmp1 = operands[1];
5902 operands[0] = operands[2];
5903 operands[1] = operands[3];
5910 ;; We can't actually do base+index doubleword loads if the index and
5911 ;; destination overlap. Split here so that we at least have chance to
5914 [(set (match_operand:DI 0 "s_register_operand" "")
5915 (mem:DI (plus:SI (match_operand:SI 1 "s_register_operand" "")
5916 (match_operand:SI 2 "s_register_operand" ""))))]
5918 && reg_overlap_mentioned_p (operands[0], operands[1])
5919 && reg_overlap_mentioned_p (operands[0], operands[2])"
5921 (plus:SI (match_dup 1)
5924 (mem:DI (match_dup 4)))]
5926 operands[4] = gen_rtx_REG (SImode, REGNO(operands[0]));
5930 (define_expand "movsi"
5931 [(set (match_operand:SI 0 "general_operand" "")
5932 (match_operand:SI 1 "general_operand" ""))]
5936 rtx base, offset, tmp;
5940 /* Everything except mem = const or mem = mem can be done easily. */
5941 if (MEM_P (operands[0]))
5942 operands[1] = force_reg (SImode, operands[1]);
5943 if (arm_general_register_operand (operands[0], SImode)
5944 && CONST_INT_P (operands[1])
5945 && !(const_ok_for_arm (INTVAL (operands[1]))
5946 || const_ok_for_arm (~INTVAL (operands[1]))))
5948 if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[1]), SET))
5950 emit_insn (gen_rtx_SET (operands[0], operands[1]));
5955 arm_split_constant (SET, SImode, NULL_RTX,
5956 INTVAL (operands[1]), operands[0], NULL_RTX,
5957 optimize && can_create_pseudo_p ());
5962 else /* TARGET_THUMB1... */
5964 if (can_create_pseudo_p ())
5966 if (!REG_P (operands[0]))
5967 operands[1] = force_reg (SImode, operands[1]);
5971 if (ARM_OFFSETS_MUST_BE_WITHIN_SECTIONS_P)
5973 split_const (operands[1], &base, &offset);
5974 if (GET_CODE (base) == SYMBOL_REF
5975 && !offset_within_block_p (base, INTVAL (offset)))
5977 tmp = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];
5978 emit_move_insn (tmp, base);
5979 emit_insn (gen_addsi3 (operands[0], tmp, offset));
5984 /* Recognize the case where operand[1] is a reference to thread-local
5985 data and load its address to a register. */
5986 if (arm_tls_referenced_p (operands[1]))
5988 rtx tmp = operands[1];
5991 if (GET_CODE (tmp) == CONST && GET_CODE (XEXP (tmp, 0)) == PLUS)
5993 addend = XEXP (XEXP (tmp, 0), 1);
5994 tmp = XEXP (XEXP (tmp, 0), 0);
5997 gcc_assert (GET_CODE (tmp) == SYMBOL_REF);
5998 gcc_assert (SYMBOL_REF_TLS_MODEL (tmp) != 0);
6000 tmp = legitimize_tls_address (tmp,
6001 !can_create_pseudo_p () ? operands[0] : 0);
6004 tmp = gen_rtx_PLUS (SImode, tmp, addend);
6005 tmp = force_operand (tmp, operands[0]);
6010 && (CONSTANT_P (operands[1])
6011 || symbol_mentioned_p (operands[1])
6012 || label_mentioned_p (operands[1])))
6013 operands[1] = legitimize_pic_address (operands[1], SImode,
6014 (!can_create_pseudo_p ()
6021 ;; The ARM LO_SUM and HIGH are backwards - HIGH sets the low bits, and
6022 ;; LO_SUM adds in the high bits. Fortunately these are opaque operations
6023 ;; so this does not matter.
6024 (define_insn "*arm_movt"
6025 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r")
6026 (lo_sum:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6027 (match_operand:SI 2 "general_operand" "i,i")))]
6028 "TARGET_HAVE_MOVT && arm_valid_symbolic_address_p (operands[2])"
6030 movt%?\t%0, #:upper16:%c2
6031 movt\t%0, #:upper16:%c2"
6032 [(set_attr "arch" "32,v8mb")
6033 (set_attr "predicable" "yes")
6034 (set_attr "predicable_short_it" "no")
6035 (set_attr "length" "4")
6036 (set_attr "type" "alu_sreg")]
6039 (define_insn "*arm_movsi_insn"
6040 [(set (match_operand:SI 0 "nonimmediate_operand" "=rk,r,r,r,rk,m")
6041 (match_operand:SI 1 "general_operand" "rk, I,K,j,mi,rk"))]
6042 "TARGET_ARM && !TARGET_IWMMXT && !TARGET_HARD_FLOAT
6043 && ( register_operand (operands[0], SImode)
6044 || register_operand (operands[1], SImode))"
6052 [(set_attr "type" "mov_reg,mov_imm,mvn_imm,mov_imm,load1,store1")
6053 (set_attr "predicable" "yes")
6054 (set_attr "arch" "*,*,*,v6t2,*,*")
6055 (set_attr "pool_range" "*,*,*,*,4096,*")
6056 (set_attr "neg_pool_range" "*,*,*,*,4084,*")]
6060 [(set (match_operand:SI 0 "arm_general_register_operand" "")
6061 (match_operand:SI 1 "const_int_operand" ""))]
6063 && (!(const_ok_for_arm (INTVAL (operands[1]))
6064 || const_ok_for_arm (~INTVAL (operands[1]))))"
6065 [(clobber (const_int 0))]
6067 arm_split_constant (SET, SImode, NULL_RTX,
6068 INTVAL (operands[1]), operands[0], NULL_RTX, 0);
6073 ;; A normal way to do (symbol + offset) requires three instructions at least
6074 ;; (depends on how big the offset is) as below:
6075 ;; movw r0, #:lower16:g
6076 ;; movw r0, #:upper16:g
6079 ;; A better way would be:
6080 ;; movw r0, #:lower16:g+4
6081 ;; movw r0, #:upper16:g+4
6083 ;; The limitation of this way is that the length of offset should be a 16-bit
6084 ;; signed value, because current assembler only supports REL type relocation for
6085 ;; such case. If the more powerful RELA type is supported in future, we should
6086 ;; update this pattern to go with better way.
6088 [(set (match_operand:SI 0 "arm_general_register_operand" "")
6089 (const:SI (plus:SI (match_operand:SI 1 "general_operand" "")
6090 (match_operand:SI 2 "const_int_operand" ""))))]
6093 && arm_disable_literal_pool
6095 && GET_CODE (operands[1]) == SYMBOL_REF"
6096 [(clobber (const_int 0))]
6098 int offset = INTVAL (operands[2]);
6100 if (offset < -0x8000 || offset > 0x7fff)
6102 arm_emit_movpair (operands[0], operands[1]);
6103 emit_insn (gen_rtx_SET (operands[0],
6104 gen_rtx_PLUS (SImode, operands[0], operands[2])));
6108 rtx op = gen_rtx_CONST (SImode,
6109 gen_rtx_PLUS (SImode, operands[1], operands[2]));
6110 arm_emit_movpair (operands[0], op);
6115 ;; Split symbol_refs at the later stage (after cprop), instead of generating
6116 ;; movt/movw pair directly at expand. Otherwise corresponding high_sum
6117 ;; and lo_sum would be merged back into memory load at cprop. However,
6118 ;; if the default is to prefer movt/movw rather than a load from the constant
6119 ;; pool, the performance is better.
6121 [(set (match_operand:SI 0 "arm_general_register_operand" "")
6122 (match_operand:SI 1 "general_operand" ""))]
6123 "TARGET_USE_MOVT && GET_CODE (operands[1]) == SYMBOL_REF
6124 && !flag_pic && !target_word_relocations
6125 && !arm_tls_referenced_p (operands[1])"
6126 [(clobber (const_int 0))]
6128 arm_emit_movpair (operands[0], operands[1]);
6132 ;; When generating pic, we need to load the symbol offset into a register.
6133 ;; So that the optimizer does not confuse this with a normal symbol load
6134 ;; we use an unspec. The offset will be loaded from a constant pool entry,
6135 ;; since that is the only type of relocation we can use.
6137 ;; Wrap calculation of the whole PIC address in a single pattern for the
6138 ;; benefit of optimizers, particularly, PRE and HOIST. Calculation of
6139 ;; a PIC address involves two loads from memory, so we want to CSE it
6140 ;; as often as possible.
6141 ;; This pattern will be split into one of the pic_load_addr_* patterns
6142 ;; and a move after GCSE optimizations.
6144 ;; Note: Update arm.c: legitimize_pic_address() when changing this pattern.
6145 (define_expand "calculate_pic_address"
6146 [(set (match_operand:SI 0 "register_operand" "")
6147 (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "")
6148 (unspec:SI [(match_operand:SI 2 "" "")]
6153 ;; Split calculate_pic_address into pic_load_addr_* and a move.
6155 [(set (match_operand:SI 0 "register_operand" "")
6156 (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "")
6157 (unspec:SI [(match_operand:SI 2 "" "")]
6160 [(set (match_dup 3) (unspec:SI [(match_dup 2)] UNSPEC_PIC_SYM))
6161 (set (match_dup 0) (mem:SI (plus:SI (match_dup 1) (match_dup 3))))]
6162 "operands[3] = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];"
6165 ;; operand1 is the memory address to go into
6166 ;; pic_load_addr_32bit.
6167 ;; operand2 is the PIC label to be emitted
6168 ;; from pic_add_dot_plus_eight.
6169 ;; We do this to allow hoisting of the entire insn.
6170 (define_insn_and_split "pic_load_addr_unified"
6171 [(set (match_operand:SI 0 "s_register_operand" "=r,r,l")
6172 (unspec:SI [(match_operand:SI 1 "" "mX,mX,mX")
6173 (match_operand:SI 2 "" "")]
6174 UNSPEC_PIC_UNIFIED))]
6177 "&& reload_completed"
6178 [(set (match_dup 0) (unspec:SI [(match_dup 1)] UNSPEC_PIC_SYM))
6179 (set (match_dup 0) (unspec:SI [(match_dup 0) (match_dup 3)
6180 (match_dup 2)] UNSPEC_PIC_BASE))]
6181 "operands[3] = TARGET_THUMB ? GEN_INT (4) : GEN_INT (8);"
6182 [(set_attr "type" "load1,load1,load1")
6183 (set_attr "pool_range" "4096,4094,1022")
6184 (set_attr "neg_pool_range" "4084,0,0")
6185 (set_attr "arch" "a,t2,t1")
6186 (set_attr "length" "8,6,4")]
6189 ;; The rather odd constraints on the following are to force reload to leave
6190 ;; the insn alone, and to force the minipool generation pass to then move
6191 ;; the GOT symbol to memory.
6193 (define_insn "pic_load_addr_32bit"
6194 [(set (match_operand:SI 0 "s_register_operand" "=r")
6195 (unspec:SI [(match_operand:SI 1 "" "mX")] UNSPEC_PIC_SYM))]
6196 "TARGET_32BIT && flag_pic"
6198 [(set_attr "type" "load1")
6199 (set (attr "pool_range")
6200 (if_then_else (eq_attr "is_thumb" "no")
6203 (set (attr "neg_pool_range")
6204 (if_then_else (eq_attr "is_thumb" "no")
6209 (define_insn "pic_load_addr_thumb1"
6210 [(set (match_operand:SI 0 "s_register_operand" "=l")
6211 (unspec:SI [(match_operand:SI 1 "" "mX")] UNSPEC_PIC_SYM))]
6212 "TARGET_THUMB1 && flag_pic"
6214 [(set_attr "type" "load1")
6215 (set (attr "pool_range") (const_int 1018))]
6218 (define_insn "pic_add_dot_plus_four"
6219 [(set (match_operand:SI 0 "register_operand" "=r")
6220 (unspec:SI [(match_operand:SI 1 "register_operand" "0")
6222 (match_operand 2 "" "")]
6226 (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
6227 INTVAL (operands[2]));
6228 return \"add\\t%0, %|pc\";
6230 [(set_attr "length" "2")
6231 (set_attr "type" "alu_sreg")]
6234 (define_insn "pic_add_dot_plus_eight"
6235 [(set (match_operand:SI 0 "register_operand" "=r")
6236 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
6238 (match_operand 2 "" "")]
6242 (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
6243 INTVAL (operands[2]));
6244 return \"add%?\\t%0, %|pc, %1\";
6246 [(set_attr "predicable" "yes")
6247 (set_attr "type" "alu_sreg")]
6250 (define_insn "tls_load_dot_plus_eight"
6251 [(set (match_operand:SI 0 "register_operand" "=r")
6252 (mem:SI (unspec:SI [(match_operand:SI 1 "register_operand" "r")
6254 (match_operand 2 "" "")]
6258 (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
6259 INTVAL (operands[2]));
6260 return \"ldr%?\\t%0, [%|pc, %1]\t\t@ tls_load_dot_plus_eight\";
6262 [(set_attr "predicable" "yes")
6263 (set_attr "type" "load1")]
6266 ;; PIC references to local variables can generate pic_add_dot_plus_eight
6267 ;; followed by a load. These sequences can be crunched down to
6268 ;; tls_load_dot_plus_eight by a peephole.
6271 [(set (match_operand:SI 0 "register_operand" "")
6272 (unspec:SI [(match_operand:SI 3 "register_operand" "")
6274 (match_operand 1 "" "")]
6276 (set (match_operand:SI 2 "arm_general_register_operand" "")
6277 (mem:SI (match_dup 0)))]
6278 "TARGET_ARM && peep2_reg_dead_p (2, operands[0])"
6280 (mem:SI (unspec:SI [(match_dup 3)
6287 (define_insn "pic_offset_arm"
6288 [(set (match_operand:SI 0 "register_operand" "=r")
6289 (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
6290 (unspec:SI [(match_operand:SI 2 "" "X")]
6291 UNSPEC_PIC_OFFSET))))]
6292 "TARGET_VXWORKS_RTP && TARGET_ARM && flag_pic"
6293 "ldr%?\\t%0, [%1,%2]"
6294 [(set_attr "type" "load1")]
6297 (define_expand "builtin_setjmp_receiver"
6298 [(label_ref (match_operand 0 "" ""))]
6302 /* r3 is clobbered by set/longjmp, so we can use it as a scratch
6304 if (arm_pic_register != INVALID_REGNUM)
6305 arm_load_pic_register (1UL << 3);
6309 ;; If copying one reg to another we can set the condition codes according to
6310 ;; its value. Such a move is common after a return from subroutine and the
6311 ;; result is being tested against zero.
6313 (define_insn "*movsi_compare0"
6314 [(set (reg:CC CC_REGNUM)
6315 (compare:CC (match_operand:SI 1 "s_register_operand" "0,r")
6317 (set (match_operand:SI 0 "s_register_operand" "=r,r")
6322 subs%?\\t%0, %1, #0"
6323 [(set_attr "conds" "set")
6324 (set_attr "type" "alus_imm,alus_imm")]
6327 ;; Subroutine to store a half word from a register into memory.
6328 ;; Operand 0 is the source register (HImode)
6329 ;; Operand 1 is the destination address in a register (SImode)
6331 ;; In both this routine and the next, we must be careful not to spill
6332 ;; a memory address of reg+large_const into a separate PLUS insn, since this
6333 ;; can generate unrecognizable rtl.
6335 (define_expand "storehi"
6336 [;; store the low byte
6337 (set (match_operand 1 "" "") (match_dup 3))
6338 ;; extract the high byte
6340 (ashiftrt:SI (match_operand 0 "" "") (const_int 8)))
6341 ;; store the high byte
6342 (set (match_dup 4) (match_dup 5))]
6346 rtx op1 = operands[1];
6347 rtx addr = XEXP (op1, 0);
6348 enum rtx_code code = GET_CODE (addr);
6350 if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1)))
6352 op1 = replace_equiv_address (operands[1], force_reg (SImode, addr));
6354 operands[4] = adjust_address (op1, QImode, 1);
6355 operands[1] = adjust_address (operands[1], QImode, 0);
6356 operands[3] = gen_lowpart (QImode, operands[0]);
6357 operands[0] = gen_lowpart (SImode, operands[0]);
6358 operands[2] = gen_reg_rtx (SImode);
6359 operands[5] = gen_lowpart (QImode, operands[2]);
6363 (define_expand "storehi_bigend"
6364 [(set (match_dup 4) (match_dup 3))
6366 (ashiftrt:SI (match_operand 0 "" "") (const_int 8)))
6367 (set (match_operand 1 "" "") (match_dup 5))]
6371 rtx op1 = operands[1];
6372 rtx addr = XEXP (op1, 0);
6373 enum rtx_code code = GET_CODE (addr);
6375 if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1)))
6377 op1 = replace_equiv_address (op1, force_reg (SImode, addr));
6379 operands[4] = adjust_address (op1, QImode, 1);
6380 operands[1] = adjust_address (operands[1], QImode, 0);
6381 operands[3] = gen_lowpart (QImode, operands[0]);
6382 operands[0] = gen_lowpart (SImode, operands[0]);
6383 operands[2] = gen_reg_rtx (SImode);
6384 operands[5] = gen_lowpart (QImode, operands[2]);
6388 ;; Subroutine to store a half word integer constant into memory.
6389 (define_expand "storeinthi"
6390 [(set (match_operand 0 "" "")
6391 (match_operand 1 "" ""))
6392 (set (match_dup 3) (match_dup 2))]
6396 HOST_WIDE_INT value = INTVAL (operands[1]);
6397 rtx addr = XEXP (operands[0], 0);
6398 rtx op0 = operands[0];
6399 enum rtx_code code = GET_CODE (addr);
6401 if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1)))
6403 op0 = replace_equiv_address (op0, force_reg (SImode, addr));
6405 operands[1] = gen_reg_rtx (SImode);
6406 if (BYTES_BIG_ENDIAN)
6408 emit_insn (gen_movsi (operands[1], GEN_INT ((value >> 8) & 255)));
6409 if ((value & 255) == ((value >> 8) & 255))
6410 operands[2] = operands[1];
6413 operands[2] = gen_reg_rtx (SImode);
6414 emit_insn (gen_movsi (operands[2], GEN_INT (value & 255)));
6419 emit_insn (gen_movsi (operands[1], GEN_INT (value & 255)));
6420 if ((value & 255) == ((value >> 8) & 255))
6421 operands[2] = operands[1];
6424 operands[2] = gen_reg_rtx (SImode);
6425 emit_insn (gen_movsi (operands[2], GEN_INT ((value >> 8) & 255)));
6429 operands[3] = adjust_address (op0, QImode, 1);
6430 operands[0] = adjust_address (operands[0], QImode, 0);
6431 operands[2] = gen_lowpart (QImode, operands[2]);
6432 operands[1] = gen_lowpart (QImode, operands[1]);
6436 (define_expand "storehi_single_op"
6437 [(set (match_operand:HI 0 "memory_operand" "")
6438 (match_operand:HI 1 "general_operand" ""))]
6439 "TARGET_32BIT && arm_arch4"
6441 if (!s_register_operand (operands[1], HImode))
6442 operands[1] = copy_to_mode_reg (HImode, operands[1]);
6446 (define_expand "movhi"
6447 [(set (match_operand:HI 0 "general_operand" "")
6448 (match_operand:HI 1 "general_operand" ""))]
6453 if (can_create_pseudo_p ())
6455 if (MEM_P (operands[0]))
6459 emit_insn (gen_storehi_single_op (operands[0], operands[1]));
6462 if (CONST_INT_P (operands[1]))
6463 emit_insn (gen_storeinthi (operands[0], operands[1]));
6466 if (MEM_P (operands[1]))
6467 operands[1] = force_reg (HImode, operands[1]);
6468 if (BYTES_BIG_ENDIAN)
6469 emit_insn (gen_storehi_bigend (operands[1], operands[0]));
6471 emit_insn (gen_storehi (operands[1], operands[0]));
6475 /* Sign extend a constant, and keep it in an SImode reg. */
6476 else if (CONST_INT_P (operands[1]))
6478 rtx reg = gen_reg_rtx (SImode);
6479 HOST_WIDE_INT val = INTVAL (operands[1]) & 0xffff;
6481 /* If the constant is already valid, leave it alone. */
6482 if (!const_ok_for_arm (val))
6484 /* If setting all the top bits will make the constant
6485 loadable in a single instruction, then set them.
6486 Otherwise, sign extend the number. */
6488 if (const_ok_for_arm (~(val | ~0xffff)))
6490 else if (val & 0x8000)
6494 emit_insn (gen_movsi (reg, GEN_INT (val)));
6495 operands[1] = gen_lowpart (HImode, reg);
6497 else if (arm_arch4 && optimize && can_create_pseudo_p ()
6498 && MEM_P (operands[1]))
6500 rtx reg = gen_reg_rtx (SImode);
6502 emit_insn (gen_zero_extendhisi2 (reg, operands[1]));
6503 operands[1] = gen_lowpart (HImode, reg);
6505 else if (!arm_arch4)
6507 if (MEM_P (operands[1]))
6510 rtx offset = const0_rtx;
6511 rtx reg = gen_reg_rtx (SImode);
6513 if ((REG_P (base = XEXP (operands[1], 0))
6514 || (GET_CODE (base) == PLUS
6515 && (CONST_INT_P (offset = XEXP (base, 1)))
6516 && ((INTVAL(offset) & 1) != 1)
6517 && REG_P (base = XEXP (base, 0))))
6518 && REGNO_POINTER_ALIGN (REGNO (base)) >= 32)
6522 new_rtx = widen_memory_access (operands[1], SImode,
6523 ((INTVAL (offset) & ~3)
6524 - INTVAL (offset)));
6525 emit_insn (gen_movsi (reg, new_rtx));
6526 if (((INTVAL (offset) & 2) != 0)
6527 ^ (BYTES_BIG_ENDIAN ? 1 : 0))
6529 rtx reg2 = gen_reg_rtx (SImode);
6531 emit_insn (gen_lshrsi3 (reg2, reg, GEN_INT (16)));
6536 emit_insn (gen_movhi_bytes (reg, operands[1]));
6538 operands[1] = gen_lowpart (HImode, reg);
6542 /* Handle loading a large integer during reload. */
6543 else if (CONST_INT_P (operands[1])
6544 && !const_ok_for_arm (INTVAL (operands[1]))
6545 && !const_ok_for_arm (~INTVAL (operands[1])))
6547 /* Writing a constant to memory needs a scratch, which should
6548 be handled with SECONDARY_RELOADs. */
6549 gcc_assert (REG_P (operands[0]));
6551 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
6552 emit_insn (gen_movsi (operands[0], operands[1]));
6556 else if (TARGET_THUMB2)
6558 /* Thumb-2 can do everything except mem=mem and mem=const easily. */
6559 if (can_create_pseudo_p ())
6561 if (!REG_P (operands[0]))
6562 operands[1] = force_reg (HImode, operands[1]);
6563 /* Zero extend a constant, and keep it in an SImode reg. */
6564 else if (CONST_INT_P (operands[1]))
6566 rtx reg = gen_reg_rtx (SImode);
6567 HOST_WIDE_INT val = INTVAL (operands[1]) & 0xffff;
6569 emit_insn (gen_movsi (reg, GEN_INT (val)));
6570 operands[1] = gen_lowpart (HImode, reg);
6574 else /* TARGET_THUMB1 */
6576 if (can_create_pseudo_p ())
6578 if (CONST_INT_P (operands[1]))
6580 rtx reg = gen_reg_rtx (SImode);
6582 emit_insn (gen_movsi (reg, operands[1]));
6583 operands[1] = gen_lowpart (HImode, reg);
6586 /* ??? We shouldn't really get invalid addresses here, but this can
6587 happen if we are passed a SP (never OK for HImode/QImode) or
6588 virtual register (also rejected as illegitimate for HImode/QImode)
6589 relative address. */
6590 /* ??? This should perhaps be fixed elsewhere, for instance, in
6591 fixup_stack_1, by checking for other kinds of invalid addresses,
6592 e.g. a bare reference to a virtual register. This may confuse the
6593 alpha though, which must handle this case differently. */
6594 if (MEM_P (operands[0])
6595 && !memory_address_p (GET_MODE (operands[0]),
6596 XEXP (operands[0], 0)))
6598 = replace_equiv_address (operands[0],
6599 copy_to_reg (XEXP (operands[0], 0)));
6601 if (MEM_P (operands[1])
6602 && !memory_address_p (GET_MODE (operands[1]),
6603 XEXP (operands[1], 0)))
6605 = replace_equiv_address (operands[1],
6606 copy_to_reg (XEXP (operands[1], 0)));
6608 if (MEM_P (operands[1]) && optimize > 0)
6610 rtx reg = gen_reg_rtx (SImode);
6612 emit_insn (gen_zero_extendhisi2 (reg, operands[1]));
6613 operands[1] = gen_lowpart (HImode, reg);
6616 if (MEM_P (operands[0]))
6617 operands[1] = force_reg (HImode, operands[1]);
6619 else if (CONST_INT_P (operands[1])
6620 && !satisfies_constraint_I (operands[1]))
6622 /* Handle loading a large integer during reload. */
6624 /* Writing a constant to memory needs a scratch, which should
6625 be handled with SECONDARY_RELOADs. */
6626 gcc_assert (REG_P (operands[0]));
6628 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
6629 emit_insn (gen_movsi (operands[0], operands[1]));
6636 (define_expand "movhi_bytes"
6637 [(set (match_dup 2) (zero_extend:SI (match_operand:HI 1 "" "")))
6639 (zero_extend:SI (match_dup 6)))
6640 (set (match_operand:SI 0 "" "")
6641 (ior:SI (ashift:SI (match_dup 4) (const_int 8)) (match_dup 5)))]
6646 rtx addr = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
6648 mem1 = change_address (operands[1], QImode, addr);
6649 mem2 = change_address (operands[1], QImode,
6650 plus_constant (Pmode, addr, 1));
6651 operands[0] = gen_lowpart (SImode, operands[0]);
6653 operands[2] = gen_reg_rtx (SImode);
6654 operands[3] = gen_reg_rtx (SImode);
6657 if (BYTES_BIG_ENDIAN)
6659 operands[4] = operands[2];
6660 operands[5] = operands[3];
6664 operands[4] = operands[3];
6665 operands[5] = operands[2];
6670 (define_expand "movhi_bigend"
6672 (rotate:SI (subreg:SI (match_operand:HI 1 "memory_operand" "") 0)
6675 (ashiftrt:SI (match_dup 2) (const_int 16)))
6676 (set (match_operand:HI 0 "s_register_operand" "")
6680 operands[2] = gen_reg_rtx (SImode);
6681 operands[3] = gen_reg_rtx (SImode);
6682 operands[4] = gen_lowpart (HImode, operands[3]);
6686 ;; Pattern to recognize insn generated default case above
6687 (define_insn "*movhi_insn_arch4"
6688 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m,r")
6689 (match_operand:HI 1 "general_operand" "rIk,K,n,r,mi"))]
6691 && arm_arch4 && !TARGET_HARD_FLOAT
6692 && (register_operand (operands[0], HImode)
6693 || register_operand (operands[1], HImode))"
6695 mov%?\\t%0, %1\\t%@ movhi
6696 mvn%?\\t%0, #%B1\\t%@ movhi
6697 movw%?\\t%0, %L1\\t%@ movhi
6698 strh%?\\t%1, %0\\t%@ movhi
6699 ldrh%?\\t%0, %1\\t%@ movhi"
6700 [(set_attr "predicable" "yes")
6701 (set_attr "pool_range" "*,*,*,*,256")
6702 (set_attr "neg_pool_range" "*,*,*,*,244")
6703 (set_attr "arch" "*,*,v6t2,*,*")
6704 (set_attr_alternative "type"
6705 [(if_then_else (match_operand 1 "const_int_operand" "")
6706 (const_string "mov_imm" )
6707 (const_string "mov_reg"))
6708 (const_string "mvn_imm")
6709 (const_string "mov_imm")
6710 (const_string "store1")
6711 (const_string "load1")])]
6714 (define_insn "*movhi_bytes"
6715 [(set (match_operand:HI 0 "s_register_operand" "=r,r,r")
6716 (match_operand:HI 1 "arm_rhs_operand" "I,rk,K"))]
6717 "TARGET_ARM && !TARGET_HARD_FLOAT"
6719 mov%?\\t%0, %1\\t%@ movhi
6720 mov%?\\t%0, %1\\t%@ movhi
6721 mvn%?\\t%0, #%B1\\t%@ movhi"
6722 [(set_attr "predicable" "yes")
6723 (set_attr "type" "mov_imm,mov_reg,mvn_imm")]
6726 ;; We use a DImode scratch because we may occasionally need an additional
6727 ;; temporary if the address isn't offsettable -- push_reload doesn't seem
6728 ;; to take any notice of the "o" constraints on reload_memory_operand operand.
6729 (define_expand "reload_outhi"
6730 [(parallel [(match_operand:HI 0 "arm_reload_memory_operand" "=o")
6731 (match_operand:HI 1 "s_register_operand" "r")
6732 (match_operand:DI 2 "s_register_operand" "=&l")])]
6735 arm_reload_out_hi (operands);
6737 thumb_reload_out_hi (operands);
6742 (define_expand "reload_inhi"
6743 [(parallel [(match_operand:HI 0 "s_register_operand" "=r")
6744 (match_operand:HI 1 "arm_reload_memory_operand" "o")
6745 (match_operand:DI 2 "s_register_operand" "=&r")])]
6749 arm_reload_in_hi (operands);
6751 thumb_reload_out_hi (operands);
6755 (define_expand "movqi"
6756 [(set (match_operand:QI 0 "general_operand" "")
6757 (match_operand:QI 1 "general_operand" ""))]
6760 /* Everything except mem = const or mem = mem can be done easily */
6762 if (can_create_pseudo_p ())
6764 if (CONST_INT_P (operands[1]))
6766 rtx reg = gen_reg_rtx (SImode);
6768 /* For thumb we want an unsigned immediate, then we are more likely
6769 to be able to use a movs insn. */
6771 operands[1] = GEN_INT (INTVAL (operands[1]) & 255);
6773 emit_insn (gen_movsi (reg, operands[1]));
6774 operands[1] = gen_lowpart (QImode, reg);
6779 /* ??? We shouldn't really get invalid addresses here, but this can
6780 happen if we are passed a SP (never OK for HImode/QImode) or
6781 virtual register (also rejected as illegitimate for HImode/QImode)
6782 relative address. */
6783 /* ??? This should perhaps be fixed elsewhere, for instance, in
6784 fixup_stack_1, by checking for other kinds of invalid addresses,
6785 e.g. a bare reference to a virtual register. This may confuse the
6786 alpha though, which must handle this case differently. */
6787 if (MEM_P (operands[0])
6788 && !memory_address_p (GET_MODE (operands[0]),
6789 XEXP (operands[0], 0)))
6791 = replace_equiv_address (operands[0],
6792 copy_to_reg (XEXP (operands[0], 0)));
6793 if (MEM_P (operands[1])
6794 && !memory_address_p (GET_MODE (operands[1]),
6795 XEXP (operands[1], 0)))
6797 = replace_equiv_address (operands[1],
6798 copy_to_reg (XEXP (operands[1], 0)));
6801 if (MEM_P (operands[1]) && optimize > 0)
6803 rtx reg = gen_reg_rtx (SImode);
6805 emit_insn (gen_zero_extendqisi2 (reg, operands[1]));
6806 operands[1] = gen_lowpart (QImode, reg);
6809 if (MEM_P (operands[0]))
6810 operands[1] = force_reg (QImode, operands[1]);
6812 else if (TARGET_THUMB
6813 && CONST_INT_P (operands[1])
6814 && !satisfies_constraint_I (operands[1]))
6816 /* Handle loading a large integer during reload. */
6818 /* Writing a constant to memory needs a scratch, which should
6819 be handled with SECONDARY_RELOADs. */
6820 gcc_assert (REG_P (operands[0]));
6822 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
6823 emit_insn (gen_movsi (operands[0], operands[1]));
6829 (define_insn "*arm_movqi_insn"
6830 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,r,l,r,l,Uu,r,m")
6831 (match_operand:QI 1 "general_operand" "rk,rk,I,Py,K,Uu,l,Uh,r"))]
6833 && ( register_operand (operands[0], QImode)
6834 || register_operand (operands[1], QImode))"
6845 [(set_attr "type" "mov_reg,mov_reg,mov_imm,mov_imm,mvn_imm,load1,store1,load1,store1")
6846 (set_attr "predicable" "yes")
6847 (set_attr "predicable_short_it" "yes,yes,no,yes,no,no,no,no,no")
6848 (set_attr "arch" "t2,any,any,t2,any,t2,t2,any,any")
6849 (set_attr "length" "2,4,4,2,4,2,2,4,4")]
6853 (define_expand "movhf"
6854 [(set (match_operand:HF 0 "general_operand" "")
6855 (match_operand:HF 1 "general_operand" ""))]
6860 if (MEM_P (operands[0]))
6861 operands[1] = force_reg (HFmode, operands[1]);
6863 else /* TARGET_THUMB1 */
6865 if (can_create_pseudo_p ())
6867 if (!REG_P (operands[0]))
6868 operands[1] = force_reg (HFmode, operands[1]);
6874 (define_insn "*arm32_movhf"
6875 [(set (match_operand:HF 0 "nonimmediate_operand" "=r,m,r,r")
6876 (match_operand:HF 1 "general_operand" " m,r,r,F"))]
6877 "TARGET_32BIT && !TARGET_HARD_FLOAT
6878 && ( s_register_operand (operands[0], HFmode)
6879 || s_register_operand (operands[1], HFmode))"
6881 switch (which_alternative)
6883 case 0: /* ARM register from memory */
6884 return \"ldrh%?\\t%0, %1\\t%@ __fp16\";
6885 case 1: /* memory from ARM register */
6886 return \"strh%?\\t%1, %0\\t%@ __fp16\";
6887 case 2: /* ARM register from ARM register */
6888 return \"mov%?\\t%0, %1\\t%@ __fp16\";
6889 case 3: /* ARM register from constant */
6894 bits = real_to_target (NULL, CONST_DOUBLE_REAL_VALUE (operands[1]),
6896 ops[0] = operands[0];
6897 ops[1] = GEN_INT (bits);
6898 ops[2] = GEN_INT (bits & 0xff00);
6899 ops[3] = GEN_INT (bits & 0x00ff);
6901 if (arm_arch_thumb2)
6902 output_asm_insn (\"movw%?\\t%0, %1\", ops);
6904 output_asm_insn (\"mov%?\\t%0, %2\;orr%?\\t%0, %0, %3\", ops);
6911 [(set_attr "conds" "unconditional")
6912 (set_attr "type" "load1,store1,mov_reg,multiple")
6913 (set_attr "length" "4,4,4,8")
6914 (set_attr "predicable" "yes")
6915 (set_attr "predicable_short_it" "no")]
6918 (define_expand "movsf"
6919 [(set (match_operand:SF 0 "general_operand" "")
6920 (match_operand:SF 1 "general_operand" ""))]
6925 if (MEM_P (operands[0]))
6926 operands[1] = force_reg (SFmode, operands[1]);
6928 else /* TARGET_THUMB1 */
6930 if (can_create_pseudo_p ())
6932 if (!REG_P (operands[0]))
6933 operands[1] = force_reg (SFmode, operands[1]);
6939 ;; Transform a floating-point move of a constant into a core register into
6940 ;; an SImode operation.
6942 [(set (match_operand:SF 0 "arm_general_register_operand" "")
6943 (match_operand:SF 1 "immediate_operand" ""))]
6946 && CONST_DOUBLE_P (operands[1])"
6947 [(set (match_dup 2) (match_dup 3))]
6949 operands[2] = gen_lowpart (SImode, operands[0]);
6950 operands[3] = gen_lowpart (SImode, operands[1]);
6951 if (operands[2] == 0 || operands[3] == 0)
6956 (define_insn "*arm_movsf_soft_insn"
6957 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,m")
6958 (match_operand:SF 1 "general_operand" "r,mE,r"))]
6960 && TARGET_SOFT_FLOAT
6961 && (!MEM_P (operands[0])
6962 || register_operand (operands[1], SFmode))"
6965 ldr%?\\t%0, %1\\t%@ float
6966 str%?\\t%1, %0\\t%@ float"
6967 [(set_attr "predicable" "yes")
6968 (set_attr "predicable_short_it" "no")
6969 (set_attr "type" "mov_reg,load1,store1")
6970 (set_attr "arm_pool_range" "*,4096,*")
6971 (set_attr "thumb2_pool_range" "*,4094,*")
6972 (set_attr "arm_neg_pool_range" "*,4084,*")
6973 (set_attr "thumb2_neg_pool_range" "*,0,*")]
6976 (define_expand "movdf"
6977 [(set (match_operand:DF 0 "general_operand" "")
6978 (match_operand:DF 1 "general_operand" ""))]
6983 if (MEM_P (operands[0]))
6984 operands[1] = force_reg (DFmode, operands[1]);
6986 else /* TARGET_THUMB */
6988 if (can_create_pseudo_p ())
6990 if (!REG_P (operands[0]))
6991 operands[1] = force_reg (DFmode, operands[1]);
6997 ;; Reloading a df mode value stored in integer regs to memory can require a
6999 (define_expand "reload_outdf"
7000 [(match_operand:DF 0 "arm_reload_memory_operand" "=o")
7001 (match_operand:DF 1 "s_register_operand" "r")
7002 (match_operand:SI 2 "s_register_operand" "=&r")]
7006 enum rtx_code code = GET_CODE (XEXP (operands[0], 0));
7009 operands[2] = XEXP (operands[0], 0);
7010 else if (code == POST_INC || code == PRE_DEC)
7012 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7013 operands[1] = gen_rtx_SUBREG (DImode, operands[1], 0);
7014 emit_insn (gen_movdi (operands[0], operands[1]));
7017 else if (code == PRE_INC)
7019 rtx reg = XEXP (XEXP (operands[0], 0), 0);
7021 emit_insn (gen_addsi3 (reg, reg, GEN_INT (8)));
7024 else if (code == POST_DEC)
7025 operands[2] = XEXP (XEXP (operands[0], 0), 0);
7027 emit_insn (gen_addsi3 (operands[2], XEXP (XEXP (operands[0], 0), 0),
7028 XEXP (XEXP (operands[0], 0), 1)));
7030 emit_insn (gen_rtx_SET (replace_equiv_address (operands[0], operands[2]),
7033 if (code == POST_DEC)
7034 emit_insn (gen_addsi3 (operands[2], operands[2], GEN_INT (-8)));
7040 (define_insn "*movdf_soft_insn"
7041 [(set (match_operand:DF 0 "nonimmediate_soft_df_operand" "=r,r,r,q,m")
7042 (match_operand:DF 1 "soft_df_operand" "rDa,Db,Dc,mF,q"))]
7043 "TARGET_32BIT && TARGET_SOFT_FLOAT
7044 && ( register_operand (operands[0], DFmode)
7045 || register_operand (operands[1], DFmode))"
7047 switch (which_alternative)
7054 return output_move_double (operands, true, NULL);
7057 [(set_attr "length" "8,12,16,8,8")
7058 (set_attr "type" "multiple,multiple,multiple,load2,store2")
7059 (set_attr "arm_pool_range" "*,*,*,1020,*")
7060 (set_attr "thumb2_pool_range" "*,*,*,1018,*")
7061 (set_attr "arm_neg_pool_range" "*,*,*,1004,*")
7062 (set_attr "thumb2_neg_pool_range" "*,*,*,0,*")]
7066 ;; load- and store-multiple insns
7067 ;; The arm can load/store any set of registers, provided that they are in
7068 ;; ascending order, but these expanders assume a contiguous set.
7070 (define_expand "load_multiple"
7071 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
7072 (match_operand:SI 1 "" ""))
7073 (use (match_operand:SI 2 "" ""))])]
7076 HOST_WIDE_INT offset = 0;
7078 /* Support only fixed point registers. */
7079 if (!CONST_INT_P (operands[2])
7080 || INTVAL (operands[2]) > MAX_LDM_STM_OPS
7081 || INTVAL (operands[2]) < 2
7082 || !MEM_P (operands[1])
7083 || !REG_P (operands[0])
7084 || REGNO (operands[0]) > (LAST_ARM_REGNUM - 1)
7085 || REGNO (operands[0]) + INTVAL (operands[2]) > LAST_ARM_REGNUM)
7089 = arm_gen_load_multiple (arm_regs_in_sequence + REGNO (operands[0]),
7090 INTVAL (operands[2]),
7091 force_reg (SImode, XEXP (operands[1], 0)),
7092 FALSE, operands[1], &offset);
7095 (define_expand "store_multiple"
7096 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
7097 (match_operand:SI 1 "" ""))
7098 (use (match_operand:SI 2 "" ""))])]
7101 HOST_WIDE_INT offset = 0;
7103 /* Support only fixed point registers. */
7104 if (!CONST_INT_P (operands[2])
7105 || INTVAL (operands[2]) > MAX_LDM_STM_OPS
7106 || INTVAL (operands[2]) < 2
7107 || !REG_P (operands[1])
7108 || !MEM_P (operands[0])
7109 || REGNO (operands[1]) > (LAST_ARM_REGNUM - 1)
7110 || REGNO (operands[1]) + INTVAL (operands[2]) > LAST_ARM_REGNUM)
7114 = arm_gen_store_multiple (arm_regs_in_sequence + REGNO (operands[1]),
7115 INTVAL (operands[2]),
7116 force_reg (SImode, XEXP (operands[0], 0)),
7117 FALSE, operands[0], &offset);
7121 (define_expand "setmemsi"
7122 [(match_operand:BLK 0 "general_operand" "")
7123 (match_operand:SI 1 "const_int_operand" "")
7124 (match_operand:SI 2 "const_int_operand" "")
7125 (match_operand:SI 3 "const_int_operand" "")]
7128 if (arm_gen_setmem (operands))
7135 ;; Move a block of memory if it is word aligned and MORE than 2 words long.
7136 ;; We could let this apply for blocks of less than this, but it clobbers so
7137 ;; many registers that there is then probably a better way.
7139 (define_expand "movmemqi"
7140 [(match_operand:BLK 0 "general_operand" "")
7141 (match_operand:BLK 1 "general_operand" "")
7142 (match_operand:SI 2 "const_int_operand" "")
7143 (match_operand:SI 3 "const_int_operand" "")]
7148 if (TARGET_LDRD && current_tune->prefer_ldrd_strd
7149 && !optimize_function_for_size_p (cfun))
7151 if (gen_movmem_ldrd_strd (operands))
7156 if (arm_gen_movmemqi (operands))
7160 else /* TARGET_THUMB1 */
7162 if ( INTVAL (operands[3]) != 4
7163 || INTVAL (operands[2]) > 48)
7166 thumb_expand_movmemqi (operands);
7173 ;; Compare & branch insns
7174 ;; The range calculations are based as follows:
7175 ;; For forward branches, the address calculation returns the address of
7176 ;; the next instruction. This is 2 beyond the branch instruction.
7177 ;; For backward branches, the address calculation returns the address of
7178 ;; the first instruction in this pattern (cmp). This is 2 before the branch
7179 ;; instruction for the shortest sequence, and 4 before the branch instruction
7180 ;; if we have to jump around an unconditional branch.
7181 ;; To the basic branch range the PC offset must be added (this is +4).
7182 ;; So for forward branches we have
7183 ;; (pos_range - pos_base_offs + pc_offs) = (pos_range - 2 + 4).
7184 ;; And for backward branches we have
7185 ;; (neg_range - neg_base_offs + pc_offs) = (neg_range - (-2 or -4) + 4).
7187 ;; For a 'b' pos_range = 2046, neg_range = -2048 giving (-2040->2048).
7188 ;; For a 'b<cond>' pos_range = 254, neg_range = -256 giving (-250 ->256).
7190 (define_expand "cbranchsi4"
7191 [(set (pc) (if_then_else
7192 (match_operator 0 "expandable_comparison_operator"
7193 [(match_operand:SI 1 "s_register_operand" "")
7194 (match_operand:SI 2 "nonmemory_operand" "")])
7195 (label_ref (match_operand 3 "" ""))
7201 if (!arm_validize_comparison (&operands[0], &operands[1], &operands[2]))
7203 emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
7207 if (thumb1_cmpneg_operand (operands[2], SImode))
7209 emit_jump_insn (gen_cbranchsi4_scratch (NULL, operands[1], operands[2],
7210 operands[3], operands[0]));
7213 if (!thumb1_cmp_operand (operands[2], SImode))
7214 operands[2] = force_reg (SImode, operands[2]);
7217 (define_expand "cbranchsf4"
7218 [(set (pc) (if_then_else
7219 (match_operator 0 "expandable_comparison_operator"
7220 [(match_operand:SF 1 "s_register_operand" "")
7221 (match_operand:SF 2 "vfp_compare_operand" "")])
7222 (label_ref (match_operand 3 "" ""))
7224 "TARGET_32BIT && TARGET_HARD_FLOAT"
7225 "emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
7226 operands[3])); DONE;"
7229 (define_expand "cbranchdf4"
7230 [(set (pc) (if_then_else
7231 (match_operator 0 "expandable_comparison_operator"
7232 [(match_operand:DF 1 "s_register_operand" "")
7233 (match_operand:DF 2 "vfp_compare_operand" "")])
7234 (label_ref (match_operand 3 "" ""))
7236 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
7237 "emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
7238 operands[3])); DONE;"
7241 (define_expand "cbranchdi4"
7242 [(set (pc) (if_then_else
7243 (match_operator 0 "expandable_comparison_operator"
7244 [(match_operand:DI 1 "s_register_operand" "")
7245 (match_operand:DI 2 "cmpdi_operand" "")])
7246 (label_ref (match_operand 3 "" ""))
7250 if (!arm_validize_comparison (&operands[0], &operands[1], &operands[2]))
7252 emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
7258 ;; Comparison and test insns
7260 (define_insn "*arm_cmpsi_insn"
7261 [(set (reg:CC CC_REGNUM)
7262 (compare:CC (match_operand:SI 0 "s_register_operand" "l,r,r,r,r")
7263 (match_operand:SI 1 "arm_add_operand" "Py,r,r,I,L")))]
7271 [(set_attr "conds" "set")
7272 (set_attr "arch" "t2,t2,any,any,any")
7273 (set_attr "length" "2,2,4,4,4")
7274 (set_attr "predicable" "yes")
7275 (set_attr "predicable_short_it" "yes,yes,yes,no,no")
7276 (set_attr "type" "alus_imm,alus_sreg,alus_sreg,alus_imm,alus_imm")]
7279 (define_insn "*cmpsi_shiftsi"
7280 [(set (reg:CC CC_REGNUM)
7281 (compare:CC (match_operand:SI 0 "s_register_operand" "r,r,r")
7282 (match_operator:SI 3 "shift_operator"
7283 [(match_operand:SI 1 "s_register_operand" "r,r,r")
7284 (match_operand:SI 2 "shift_amount_operand" "M,r,M")])))]
7287 [(set_attr "conds" "set")
7288 (set_attr "shift" "1")
7289 (set_attr "arch" "32,a,a")
7290 (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
7292 (define_insn "*cmpsi_shiftsi_swp"
7293 [(set (reg:CC_SWP CC_REGNUM)
7294 (compare:CC_SWP (match_operator:SI 3 "shift_operator"
7295 [(match_operand:SI 1 "s_register_operand" "r,r,r")
7296 (match_operand:SI 2 "shift_amount_operand" "M,r,M")])
7297 (match_operand:SI 0 "s_register_operand" "r,r,r")))]
7300 [(set_attr "conds" "set")
7301 (set_attr "shift" "1")
7302 (set_attr "arch" "32,a,a")
7303 (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
7305 (define_insn "*arm_cmpsi_negshiftsi_si"
7306 [(set (reg:CC_Z CC_REGNUM)
7308 (neg:SI (match_operator:SI 1 "shift_operator"
7309 [(match_operand:SI 2 "s_register_operand" "r")
7310 (match_operand:SI 3 "reg_or_int_operand" "rM")]))
7311 (match_operand:SI 0 "s_register_operand" "r")))]
7314 [(set_attr "conds" "set")
7315 (set (attr "type") (if_then_else (match_operand 3 "const_int_operand" "")
7316 (const_string "alus_shift_imm")
7317 (const_string "alus_shift_reg")))
7318 (set_attr "predicable" "yes")]
7321 ;; DImode comparisons. The generic code generates branches that
7322 ;; if-conversion can not reduce to a conditional compare, so we do
7325 (define_insn_and_split "*arm_cmpdi_insn"
7326 [(set (reg:CC_NCV CC_REGNUM)
7327 (compare:CC_NCV (match_operand:DI 0 "s_register_operand" "r")
7328 (match_operand:DI 1 "arm_di_operand" "rDi")))
7329 (clobber (match_scratch:SI 2 "=r"))]
7331 "#" ; "cmp\\t%Q0, %Q1\;sbcs\\t%2, %R0, %R1"
7332 "&& reload_completed"
7333 [(set (reg:CC CC_REGNUM)
7334 (compare:CC (match_dup 0) (match_dup 1)))
7335 (parallel [(set (reg:CC CC_REGNUM)
7336 (compare:CC (match_dup 3) (match_dup 4)))
7338 (minus:SI (match_dup 5)
7339 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))])]
7341 operands[3] = gen_highpart (SImode, operands[0]);
7342 operands[0] = gen_lowpart (SImode, operands[0]);
7343 if (CONST_INT_P (operands[1]))
7345 operands[4] = GEN_INT (~INTVAL (gen_highpart_mode (SImode,
7348 operands[5] = gen_rtx_PLUS (SImode, operands[3], operands[4]);
7352 operands[4] = gen_highpart (SImode, operands[1]);
7353 operands[5] = gen_rtx_MINUS (SImode, operands[3], operands[4]);
7355 operands[1] = gen_lowpart (SImode, operands[1]);
7356 operands[2] = gen_lowpart (SImode, operands[2]);
7358 [(set_attr "conds" "set")
7359 (set_attr "length" "8")
7360 (set_attr "type" "multiple")]
7363 (define_insn_and_split "*arm_cmpdi_unsigned"
7364 [(set (reg:CC_CZ CC_REGNUM)
7365 (compare:CC_CZ (match_operand:DI 0 "s_register_operand" "l,r,r,r")
7366 (match_operand:DI 1 "arm_di_operand" "Py,r,Di,rDi")))]
7369 "#" ; "cmp\\t%R0, %R1\;it eq\;cmpeq\\t%Q0, %Q1"
7370 "&& reload_completed"
7371 [(set (reg:CC CC_REGNUM)
7372 (compare:CC (match_dup 2) (match_dup 3)))
7373 (cond_exec (eq:SI (reg:CC CC_REGNUM) (const_int 0))
7374 (set (reg:CC CC_REGNUM)
7375 (compare:CC (match_dup 0) (match_dup 1))))]
7377 operands[2] = gen_highpart (SImode, operands[0]);
7378 operands[0] = gen_lowpart (SImode, operands[0]);
7379 if (CONST_INT_P (operands[1]))
7380 operands[3] = gen_highpart_mode (SImode, DImode, operands[1]);
7382 operands[3] = gen_highpart (SImode, operands[1]);
7383 operands[1] = gen_lowpart (SImode, operands[1]);
7385 [(set_attr "conds" "set")
7386 (set_attr "enabled_for_depr_it" "yes,yes,no,*")
7387 (set_attr "arch" "t2,t2,t2,a")
7388 (set_attr "length" "6,6,10,8")
7389 (set_attr "type" "multiple")]
7392 (define_insn "*arm_cmpdi_zero"
7393 [(set (reg:CC_Z CC_REGNUM)
7394 (compare:CC_Z (match_operand:DI 0 "s_register_operand" "r")
7396 (clobber (match_scratch:SI 1 "=r"))]
7398 "orrs%?\\t%1, %Q0, %R0"
7399 [(set_attr "conds" "set")
7400 (set_attr "type" "logics_reg")]
7403 ; This insn allows redundant compares to be removed by cse, nothing should
7404 ; ever appear in the output file since (set (reg x) (reg x)) is a no-op that
7405 ; is deleted later on. The match_dup will match the mode here, so that
7406 ; mode changes of the condition codes aren't lost by this even though we don't
7407 ; specify what they are.
7409 (define_insn "*deleted_compare"
7410 [(set (match_operand 0 "cc_register" "") (match_dup 0))]
7412 "\\t%@ deleted compare"
7413 [(set_attr "conds" "set")
7414 (set_attr "length" "0")
7415 (set_attr "type" "no_insn")]
7419 ;; Conditional branch insns
7421 (define_expand "cbranch_cc"
7423 (if_then_else (match_operator 0 "" [(match_operand 1 "" "")
7424 (match_operand 2 "" "")])
7425 (label_ref (match_operand 3 "" ""))
7428 "operands[1] = arm_gen_compare_reg (GET_CODE (operands[0]),
7429 operands[1], operands[2], NULL_RTX);
7430 operands[2] = const0_rtx;"
7434 ;; Patterns to match conditional branch insns.
7437 (define_insn "arm_cond_branch"
7439 (if_then_else (match_operator 1 "arm_comparison_operator"
7440 [(match_operand 2 "cc_register" "") (const_int 0)])
7441 (label_ref (match_operand 0 "" ""))
7445 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
7447 arm_ccfsm_state += 2;
7450 return \"b%d1\\t%l0\";
7452 [(set_attr "conds" "use")
7453 (set_attr "type" "branch")
7454 (set (attr "length")
7456 (and (match_test "TARGET_THUMB2")
7457 (and (ge (minus (match_dup 0) (pc)) (const_int -250))
7458 (le (minus (match_dup 0) (pc)) (const_int 256))))
7463 (define_insn "*arm_cond_branch_reversed"
7465 (if_then_else (match_operator 1 "arm_comparison_operator"
7466 [(match_operand 2 "cc_register" "") (const_int 0)])
7468 (label_ref (match_operand 0 "" ""))))]
7471 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
7473 arm_ccfsm_state += 2;
7476 return \"b%D1\\t%l0\";
7478 [(set_attr "conds" "use")
7479 (set_attr "type" "branch")
7480 (set (attr "length")
7482 (and (match_test "TARGET_THUMB2")
7483 (and (ge (minus (match_dup 0) (pc)) (const_int -250))
7484 (le (minus (match_dup 0) (pc)) (const_int 256))))
7493 (define_expand "cstore_cc"
7494 [(set (match_operand:SI 0 "s_register_operand" "")
7495 (match_operator:SI 1 "" [(match_operand 2 "" "")
7496 (match_operand 3 "" "")]))]
7498 "operands[2] = arm_gen_compare_reg (GET_CODE (operands[1]),
7499 operands[2], operands[3], NULL_RTX);
7500 operands[3] = const0_rtx;"
7503 (define_insn_and_split "*mov_scc"
7504 [(set (match_operand:SI 0 "s_register_operand" "=r")
7505 (match_operator:SI 1 "arm_comparison_operator_mode"
7506 [(match_operand 2 "cc_register" "") (const_int 0)]))]
7508 "#" ; "mov%D1\\t%0, #0\;mov%d1\\t%0, #1"
7511 (if_then_else:SI (match_dup 1)
7515 [(set_attr "conds" "use")
7516 (set_attr "length" "8")
7517 (set_attr "type" "multiple")]
7520 (define_insn_and_split "*mov_negscc"
7521 [(set (match_operand:SI 0 "s_register_operand" "=r")
7522 (neg:SI (match_operator:SI 1 "arm_comparison_operator_mode"
7523 [(match_operand 2 "cc_register" "") (const_int 0)])))]
7525 "#" ; "mov%D1\\t%0, #0\;mvn%d1\\t%0, #0"
7528 (if_then_else:SI (match_dup 1)
7532 operands[3] = GEN_INT (~0);
7534 [(set_attr "conds" "use")
7535 (set_attr "length" "8")
7536 (set_attr "type" "multiple")]
7539 (define_insn_and_split "*mov_notscc"
7540 [(set (match_operand:SI 0 "s_register_operand" "=r")
7541 (not:SI (match_operator:SI 1 "arm_comparison_operator"
7542 [(match_operand 2 "cc_register" "") (const_int 0)])))]
7544 "#" ; "mvn%D1\\t%0, #0\;mvn%d1\\t%0, #1"
7547 (if_then_else:SI (match_dup 1)
7551 operands[3] = GEN_INT (~1);
7552 operands[4] = GEN_INT (~0);
7554 [(set_attr "conds" "use")
7555 (set_attr "length" "8")
7556 (set_attr "type" "multiple")]
7559 (define_expand "cstoresi4"
7560 [(set (match_operand:SI 0 "s_register_operand" "")
7561 (match_operator:SI 1 "expandable_comparison_operator"
7562 [(match_operand:SI 2 "s_register_operand" "")
7563 (match_operand:SI 3 "reg_or_int_operand" "")]))]
7564 "TARGET_32BIT || TARGET_THUMB1"
7566 rtx op3, scratch, scratch2;
7570 if (!arm_add_operand (operands[3], SImode))
7571 operands[3] = force_reg (SImode, operands[3]);
7572 emit_insn (gen_cstore_cc (operands[0], operands[1],
7573 operands[2], operands[3]));
7577 if (operands[3] == const0_rtx)
7579 switch (GET_CODE (operands[1]))
7582 emit_insn (gen_cstoresi_eq0_thumb1 (operands[0], operands[2]));
7586 emit_insn (gen_cstoresi_ne0_thumb1 (operands[0], operands[2]));
7590 scratch = expand_binop (SImode, add_optab, operands[2], constm1_rtx,
7591 NULL_RTX, 0, OPTAB_WIDEN);
7592 scratch = expand_binop (SImode, ior_optab, operands[2], scratch,
7593 NULL_RTX, 0, OPTAB_WIDEN);
7594 expand_binop (SImode, lshr_optab, scratch, GEN_INT (31),
7595 operands[0], 1, OPTAB_WIDEN);
7599 scratch = expand_unop (SImode, one_cmpl_optab, operands[2],
7601 expand_binop (SImode, lshr_optab, scratch, GEN_INT (31),
7602 NULL_RTX, 1, OPTAB_WIDEN);
7606 scratch = expand_binop (SImode, ashr_optab, operands[2],
7607 GEN_INT (31), NULL_RTX, 0, OPTAB_WIDEN);
7608 scratch = expand_binop (SImode, sub_optab, scratch, operands[2],
7609 NULL_RTX, 0, OPTAB_WIDEN);
7610 expand_binop (SImode, lshr_optab, scratch, GEN_INT (31), operands[0],
7614 /* LT is handled by generic code. No need for unsigned with 0. */
7621 switch (GET_CODE (operands[1]))
7624 scratch = expand_binop (SImode, sub_optab, operands[2], operands[3],
7625 NULL_RTX, 0, OPTAB_WIDEN);
7626 emit_insn (gen_cstoresi_eq0_thumb1 (operands[0], scratch));
7630 scratch = expand_binop (SImode, sub_optab, operands[2], operands[3],
7631 NULL_RTX, 0, OPTAB_WIDEN);
7632 emit_insn (gen_cstoresi_ne0_thumb1 (operands[0], scratch));
7636 op3 = force_reg (SImode, operands[3]);
7638 scratch = expand_binop (SImode, lshr_optab, operands[2], GEN_INT (31),
7639 NULL_RTX, 1, OPTAB_WIDEN);
7640 scratch2 = expand_binop (SImode, ashr_optab, op3, GEN_INT (31),
7641 NULL_RTX, 0, OPTAB_WIDEN);
7642 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch2,
7648 if (!thumb1_cmp_operand (op3, SImode))
7649 op3 = force_reg (SImode, op3);
7650 scratch = expand_binop (SImode, ashr_optab, operands[2], GEN_INT (31),
7651 NULL_RTX, 0, OPTAB_WIDEN);
7652 scratch2 = expand_binop (SImode, lshr_optab, op3, GEN_INT (31),
7653 NULL_RTX, 1, OPTAB_WIDEN);
7654 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch2,
7659 op3 = force_reg (SImode, operands[3]);
7660 scratch = force_reg (SImode, const0_rtx);
7661 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch,
7667 if (!thumb1_cmp_operand (op3, SImode))
7668 op3 = force_reg (SImode, op3);
7669 scratch = force_reg (SImode, const0_rtx);
7670 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch,
7676 if (!thumb1_cmp_operand (op3, SImode))
7677 op3 = force_reg (SImode, op3);
7678 scratch = gen_reg_rtx (SImode);
7679 emit_insn (gen_cstoresi_ltu_thumb1 (operands[0], operands[2], op3));
7683 op3 = force_reg (SImode, operands[3]);
7684 scratch = gen_reg_rtx (SImode);
7685 emit_insn (gen_cstoresi_ltu_thumb1 (operands[0], op3, operands[2]));
7688 /* No good sequences for GT, LT. */
7695 (define_expand "cstorehf4"
7696 [(set (match_operand:SI 0 "s_register_operand")
7697 (match_operator:SI 1 "expandable_comparison_operator"
7698 [(match_operand:HF 2 "s_register_operand")
7699 (match_operand:HF 3 "vfp_compare_operand")]))]
7700 "TARGET_VFP_FP16INST"
7702 if (!arm_validize_comparison (&operands[1],
7707 emit_insn (gen_cstore_cc (operands[0], operands[1],
7708 operands[2], operands[3]));
7713 (define_expand "cstoresf4"
7714 [(set (match_operand:SI 0 "s_register_operand" "")
7715 (match_operator:SI 1 "expandable_comparison_operator"
7716 [(match_operand:SF 2 "s_register_operand" "")
7717 (match_operand:SF 3 "vfp_compare_operand" "")]))]
7718 "TARGET_32BIT && TARGET_HARD_FLOAT"
7719 "emit_insn (gen_cstore_cc (operands[0], operands[1],
7720 operands[2], operands[3])); DONE;"
7723 (define_expand "cstoredf4"
7724 [(set (match_operand:SI 0 "s_register_operand" "")
7725 (match_operator:SI 1 "expandable_comparison_operator"
7726 [(match_operand:DF 2 "s_register_operand" "")
7727 (match_operand:DF 3 "vfp_compare_operand" "")]))]
7728 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
7729 "emit_insn (gen_cstore_cc (operands[0], operands[1],
7730 operands[2], operands[3])); DONE;"
7733 (define_expand "cstoredi4"
7734 [(set (match_operand:SI 0 "s_register_operand" "")
7735 (match_operator:SI 1 "expandable_comparison_operator"
7736 [(match_operand:DI 2 "s_register_operand" "")
7737 (match_operand:DI 3 "cmpdi_operand" "")]))]
7740 if (!arm_validize_comparison (&operands[1],
7744 emit_insn (gen_cstore_cc (operands[0], operands[1], operands[2],
7751 ;; Conditional move insns
7753 (define_expand "movsicc"
7754 [(set (match_operand:SI 0 "s_register_operand" "")
7755 (if_then_else:SI (match_operand 1 "expandable_comparison_operator" "")
7756 (match_operand:SI 2 "arm_not_operand" "")
7757 (match_operand:SI 3 "arm_not_operand" "")))]
7764 if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
7765 &XEXP (operands[1], 1)))
7768 code = GET_CODE (operands[1]);
7769 ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
7770 XEXP (operands[1], 1), NULL_RTX);
7771 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7775 (define_expand "movhfcc"
7776 [(set (match_operand:HF 0 "s_register_operand")
7777 (if_then_else:HF (match_operand 1 "arm_cond_move_operator")
7778 (match_operand:HF 2 "s_register_operand")
7779 (match_operand:HF 3 "s_register_operand")))]
7780 "TARGET_VFP_FP16INST"
7783 enum rtx_code code = GET_CODE (operands[1]);
7786 if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
7787 &XEXP (operands[1], 1)))
7790 code = GET_CODE (operands[1]);
7791 ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
7792 XEXP (operands[1], 1), NULL_RTX);
7793 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7797 (define_expand "movsfcc"
7798 [(set (match_operand:SF 0 "s_register_operand" "")
7799 (if_then_else:SF (match_operand 1 "arm_cond_move_operator" "")
7800 (match_operand:SF 2 "s_register_operand" "")
7801 (match_operand:SF 3 "s_register_operand" "")))]
7802 "TARGET_32BIT && TARGET_HARD_FLOAT"
7805 enum rtx_code code = GET_CODE (operands[1]);
7808 if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
7809 &XEXP (operands[1], 1)))
7812 code = GET_CODE (operands[1]);
7813 ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
7814 XEXP (operands[1], 1), NULL_RTX);
7815 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7819 (define_expand "movdfcc"
7820 [(set (match_operand:DF 0 "s_register_operand" "")
7821 (if_then_else:DF (match_operand 1 "arm_cond_move_operator" "")
7822 (match_operand:DF 2 "s_register_operand" "")
7823 (match_operand:DF 3 "s_register_operand" "")))]
7824 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
7827 enum rtx_code code = GET_CODE (operands[1]);
7830 if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
7831 &XEXP (operands[1], 1)))
7833 code = GET_CODE (operands[1]);
7834 ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
7835 XEXP (operands[1], 1), NULL_RTX);
7836 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7840 (define_insn "*cmov<mode>"
7841 [(set (match_operand:SDF 0 "s_register_operand" "=<F_constraint>")
7842 (if_then_else:SDF (match_operator 1 "arm_vsel_comparison_operator"
7843 [(match_operand 2 "cc_register" "") (const_int 0)])
7844 (match_operand:SDF 3 "s_register_operand"
7846 (match_operand:SDF 4 "s_register_operand"
7847 "<F_constraint>")))]
7848 "TARGET_HARD_FLOAT && TARGET_FPU_ARMV8 <vfp_double_cond>"
7851 enum arm_cond_code code = maybe_get_arm_condition_code (operands[1]);
7858 return \"vsel%d1.<V_if_elem>\\t%<V_reg>0, %<V_reg>3, %<V_reg>4\";
7863 return \"vsel%D1.<V_if_elem>\\t%<V_reg>0, %<V_reg>4, %<V_reg>3\";
7869 [(set_attr "conds" "use")
7870 (set_attr "type" "fcsel")]
7873 (define_insn "*cmovhf"
7874 [(set (match_operand:HF 0 "s_register_operand" "=t")
7875 (if_then_else:HF (match_operator 1 "arm_vsel_comparison_operator"
7876 [(match_operand 2 "cc_register" "") (const_int 0)])
7877 (match_operand:HF 3 "s_register_operand" "t")
7878 (match_operand:HF 4 "s_register_operand" "t")))]
7879 "TARGET_VFP_FP16INST"
7882 enum arm_cond_code code = maybe_get_arm_condition_code (operands[1]);
7889 return \"vsel%d1.f16\\t%0, %3, %4\";
7894 return \"vsel%D1.f16\\t%0, %4, %3\";
7900 [(set_attr "conds" "use")
7901 (set_attr "type" "fcsel")]
7904 (define_insn_and_split "*movsicc_insn"
7905 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r,r,r,r,r")
7907 (match_operator 3 "arm_comparison_operator"
7908 [(match_operand 4 "cc_register" "") (const_int 0)])
7909 (match_operand:SI 1 "arm_not_operand" "0,0,rI,K,rI,rI,K,K")
7910 (match_operand:SI 2 "arm_not_operand" "rI,K,0,0,rI,K,rI,K")))]
7921 ; alt4: mov%d3\\t%0, %1\;mov%D3\\t%0, %2
7922 ; alt5: mov%d3\\t%0, %1\;mvn%D3\\t%0, #%B2
7923 ; alt6: mvn%d3\\t%0, #%B1\;mov%D3\\t%0, %2
7924 ; alt7: mvn%d3\\t%0, #%B1\;mvn%D3\\t%0, #%B2"
7925 "&& reload_completed"
7928 enum rtx_code rev_code;
7932 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
7934 gen_rtx_SET (operands[0], operands[1])));
7936 rev_code = GET_CODE (operands[3]);
7937 mode = GET_MODE (operands[4]);
7938 if (mode == CCFPmode || mode == CCFPEmode)
7939 rev_code = reverse_condition_maybe_unordered (rev_code);
7941 rev_code = reverse_condition (rev_code);
7943 rev_cond = gen_rtx_fmt_ee (rev_code,
7947 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
7949 gen_rtx_SET (operands[0], operands[2])));
7952 [(set_attr "length" "4,4,4,4,8,8,8,8")
7953 (set_attr "conds" "use")
7954 (set_attr_alternative "type"
7955 [(if_then_else (match_operand 2 "const_int_operand" "")
7956 (const_string "mov_imm")
7957 (const_string "mov_reg"))
7958 (const_string "mvn_imm")
7959 (if_then_else (match_operand 1 "const_int_operand" "")
7960 (const_string "mov_imm")
7961 (const_string "mov_reg"))
7962 (const_string "mvn_imm")
7963 (const_string "multiple")
7964 (const_string "multiple")
7965 (const_string "multiple")
7966 (const_string "multiple")])]
7969 (define_insn "*movsfcc_soft_insn"
7970 [(set (match_operand:SF 0 "s_register_operand" "=r,r")
7971 (if_then_else:SF (match_operator 3 "arm_comparison_operator"
7972 [(match_operand 4 "cc_register" "") (const_int 0)])
7973 (match_operand:SF 1 "s_register_operand" "0,r")
7974 (match_operand:SF 2 "s_register_operand" "r,0")))]
7975 "TARGET_ARM && TARGET_SOFT_FLOAT"
7979 [(set_attr "conds" "use")
7980 (set_attr "type" "mov_reg")]
7984 ;; Jump and linkage insns
7986 (define_expand "jump"
7988 (label_ref (match_operand 0 "" "")))]
7993 (define_insn "*arm_jump"
7995 (label_ref (match_operand 0 "" "")))]
7999 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
8001 arm_ccfsm_state += 2;
8004 return \"b%?\\t%l0\";
8007 [(set_attr "predicable" "yes")
8008 (set (attr "length")
8010 (and (match_test "TARGET_THUMB2")
8011 (and (ge (minus (match_dup 0) (pc)) (const_int -2044))
8012 (le (minus (match_dup 0) (pc)) (const_int 2048))))
8015 (set_attr "type" "branch")]
8018 (define_expand "call"
8019 [(parallel [(call (match_operand 0 "memory_operand" "")
8020 (match_operand 1 "general_operand" ""))
8021 (use (match_operand 2 "" ""))
8022 (clobber (reg:SI LR_REGNUM))])]
8028 /* In an untyped call, we can get NULL for operand 2. */
8029 if (operands[2] == NULL_RTX)
8030 operands[2] = const0_rtx;
8032 /* Decide if we should generate indirect calls by loading the
8033 32-bit address of the callee into a register before performing the
8035 callee = XEXP (operands[0], 0);
8036 if (GET_CODE (callee) == SYMBOL_REF
8037 ? arm_is_long_call_p (SYMBOL_REF_DECL (callee))
8039 XEXP (operands[0], 0) = force_reg (Pmode, callee);
8041 pat = gen_call_internal (operands[0], operands[1], operands[2]);
8042 arm_emit_call_insn (pat, XEXP (operands[0], 0), false);
8047 (define_expand "call_internal"
8048 [(parallel [(call (match_operand 0 "memory_operand" "")
8049 (match_operand 1 "general_operand" ""))
8050 (use (match_operand 2 "" ""))
8051 (clobber (reg:SI LR_REGNUM))])])
8053 (define_insn "*call_reg_armv5"
8054 [(call (mem:SI (match_operand:SI 0 "s_register_operand" "r"))
8055 (match_operand 1 "" ""))
8056 (use (match_operand 2 "" ""))
8057 (clobber (reg:SI LR_REGNUM))]
8058 "TARGET_ARM && arm_arch5 && !SIBLING_CALL_P (insn)"
8060 [(set_attr "type" "call")]
8063 (define_insn "*call_reg_arm"
8064 [(call (mem:SI (match_operand:SI 0 "s_register_operand" "r"))
8065 (match_operand 1 "" ""))
8066 (use (match_operand 2 "" ""))
8067 (clobber (reg:SI LR_REGNUM))]
8068 "TARGET_ARM && !arm_arch5 && !SIBLING_CALL_P (insn)"
8070 return output_call (operands);
8072 ;; length is worst case, normally it is only two
8073 [(set_attr "length" "12")
8074 (set_attr "type" "call")]
8078 (define_expand "call_value"
8079 [(parallel [(set (match_operand 0 "" "")
8080 (call (match_operand 1 "memory_operand" "")
8081 (match_operand 2 "general_operand" "")))
8082 (use (match_operand 3 "" ""))
8083 (clobber (reg:SI LR_REGNUM))])]
8089 /* In an untyped call, we can get NULL for operand 2. */
8090 if (operands[3] == 0)
8091 operands[3] = const0_rtx;
8093 /* Decide if we should generate indirect calls by loading the
8094 32-bit address of the callee into a register before performing the
8096 callee = XEXP (operands[1], 0);
8097 if (GET_CODE (callee) == SYMBOL_REF
8098 ? arm_is_long_call_p (SYMBOL_REF_DECL (callee))
8100 XEXP (operands[1], 0) = force_reg (Pmode, callee);
8102 pat = gen_call_value_internal (operands[0], operands[1],
8103 operands[2], operands[3]);
8104 arm_emit_call_insn (pat, XEXP (operands[1], 0), false);
8109 (define_expand "call_value_internal"
8110 [(parallel [(set (match_operand 0 "" "")
8111 (call (match_operand 1 "memory_operand" "")
8112 (match_operand 2 "general_operand" "")))
8113 (use (match_operand 3 "" ""))
8114 (clobber (reg:SI LR_REGNUM))])])
8116 (define_insn "*call_value_reg_armv5"
8117 [(set (match_operand 0 "" "")
8118 (call (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
8119 (match_operand 2 "" "")))
8120 (use (match_operand 3 "" ""))
8121 (clobber (reg:SI LR_REGNUM))]
8122 "TARGET_ARM && arm_arch5 && !SIBLING_CALL_P (insn)"
8124 [(set_attr "type" "call")]
8127 (define_insn "*call_value_reg_arm"
8128 [(set (match_operand 0 "" "")
8129 (call (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
8130 (match_operand 2 "" "")))
8131 (use (match_operand 3 "" ""))
8132 (clobber (reg:SI LR_REGNUM))]
8133 "TARGET_ARM && !arm_arch5 && !SIBLING_CALL_P (insn)"
8135 return output_call (&operands[1]);
8137 [(set_attr "length" "12")
8138 (set_attr "type" "call")]
8141 ;; Allow calls to SYMBOL_REFs specially as they are not valid general addresses
8142 ;; The 'a' causes the operand to be treated as an address, i.e. no '#' output.
8144 (define_insn "*call_symbol"
8145 [(call (mem:SI (match_operand:SI 0 "" ""))
8146 (match_operand 1 "" ""))
8147 (use (match_operand 2 "" ""))
8148 (clobber (reg:SI LR_REGNUM))]
8150 && !SIBLING_CALL_P (insn)
8151 && (GET_CODE (operands[0]) == SYMBOL_REF)
8152 && !arm_is_long_call_p (SYMBOL_REF_DECL (operands[0]))"
8155 rtx op = operands[0];
8157 /* Switch mode now when possible. */
8158 if (SYMBOL_REF_DECL (op) && !TREE_PUBLIC (SYMBOL_REF_DECL (op))
8159 && arm_arch5 && arm_change_mode_p (SYMBOL_REF_DECL (op)))
8160 return NEED_PLT_RELOC ? \"blx%?\\t%a0(PLT)\" : \"blx%?\\t(%a0)\";
8162 return NEED_PLT_RELOC ? \"bl%?\\t%a0(PLT)\" : \"bl%?\\t%a0\";
8164 [(set_attr "type" "call")]
8167 (define_insn "*call_value_symbol"
8168 [(set (match_operand 0 "" "")
8169 (call (mem:SI (match_operand:SI 1 "" ""))
8170 (match_operand:SI 2 "" "")))
8171 (use (match_operand 3 "" ""))
8172 (clobber (reg:SI LR_REGNUM))]
8174 && !SIBLING_CALL_P (insn)
8175 && (GET_CODE (operands[1]) == SYMBOL_REF)
8176 && !arm_is_long_call_p (SYMBOL_REF_DECL (operands[1]))"
8179 rtx op = operands[1];
8181 /* Switch mode now when possible. */
8182 if (SYMBOL_REF_DECL (op) && !TREE_PUBLIC (SYMBOL_REF_DECL (op))
8183 && arm_arch5 && arm_change_mode_p (SYMBOL_REF_DECL (op)))
8184 return NEED_PLT_RELOC ? \"blx%?\\t%a1(PLT)\" : \"blx%?\\t(%a1)\";
8186 return NEED_PLT_RELOC ? \"bl%?\\t%a1(PLT)\" : \"bl%?\\t%a1\";
8188 [(set_attr "type" "call")]
8191 (define_expand "sibcall_internal"
8192 [(parallel [(call (match_operand 0 "memory_operand" "")
8193 (match_operand 1 "general_operand" ""))
8195 (use (match_operand 2 "" ""))])])
8197 ;; We may also be able to do sibcalls for Thumb, but it's much harder...
8198 (define_expand "sibcall"
8199 [(parallel [(call (match_operand 0 "memory_operand" "")
8200 (match_operand 1 "general_operand" ""))
8202 (use (match_operand 2 "" ""))])]
8208 if ((!REG_P (XEXP (operands[0], 0))
8209 && GET_CODE (XEXP (operands[0], 0)) != SYMBOL_REF)
8210 || (GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
8211 && arm_is_long_call_p (SYMBOL_REF_DECL (XEXP (operands[0], 0)))))
8212 XEXP (operands[0], 0) = force_reg (SImode, XEXP (operands[0], 0));
8214 if (operands[2] == NULL_RTX)
8215 operands[2] = const0_rtx;
8217 pat = gen_sibcall_internal (operands[0], operands[1], operands[2]);
8218 arm_emit_call_insn (pat, operands[0], true);
8223 (define_expand "sibcall_value_internal"
8224 [(parallel [(set (match_operand 0 "" "")
8225 (call (match_operand 1 "memory_operand" "")
8226 (match_operand 2 "general_operand" "")))
8228 (use (match_operand 3 "" ""))])])
8230 (define_expand "sibcall_value"
8231 [(parallel [(set (match_operand 0 "" "")
8232 (call (match_operand 1 "memory_operand" "")
8233 (match_operand 2 "general_operand" "")))
8235 (use (match_operand 3 "" ""))])]
8241 if ((!REG_P (XEXP (operands[1], 0))
8242 && GET_CODE (XEXP (operands[1], 0)) != SYMBOL_REF)
8243 || (GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
8244 && arm_is_long_call_p (SYMBOL_REF_DECL (XEXP (operands[1], 0)))))
8245 XEXP (operands[1], 0) = force_reg (SImode, XEXP (operands[1], 0));
8247 if (operands[3] == NULL_RTX)
8248 operands[3] = const0_rtx;
8250 pat = gen_sibcall_value_internal (operands[0], operands[1],
8251 operands[2], operands[3]);
8252 arm_emit_call_insn (pat, operands[1], true);
8257 (define_insn "*sibcall_insn"
8258 [(call (mem:SI (match_operand:SI 0 "call_insn_operand" "Cs, US"))
8259 (match_operand 1 "" ""))
8261 (use (match_operand 2 "" ""))]
8262 "TARGET_32BIT && SIBLING_CALL_P (insn)"
8264 if (which_alternative == 1)
8265 return NEED_PLT_RELOC ? \"b%?\\t%a0(PLT)\" : \"b%?\\t%a0\";
8268 if (arm_arch5 || arm_arch4t)
8269 return \"bx%?\\t%0\\t%@ indirect register sibling call\";
8271 return \"mov%?\\t%|pc, %0\\t%@ indirect register sibling call\";
8274 [(set_attr "type" "call")]
8277 (define_insn "*sibcall_value_insn"
8278 [(set (match_operand 0 "" "")
8279 (call (mem:SI (match_operand:SI 1 "call_insn_operand" "Cs,US"))
8280 (match_operand 2 "" "")))
8282 (use (match_operand 3 "" ""))]
8283 "TARGET_32BIT && SIBLING_CALL_P (insn)"
8285 if (which_alternative == 1)
8286 return NEED_PLT_RELOC ? \"b%?\\t%a1(PLT)\" : \"b%?\\t%a1\";
8289 if (arm_arch5 || arm_arch4t)
8290 return \"bx%?\\t%1\";
8292 return \"mov%?\\t%|pc, %1\\t@ indirect sibling call \";
8295 [(set_attr "type" "call")]
8298 (define_expand "<return_str>return"
8300 "(TARGET_ARM || (TARGET_THUMB2
8301 && ARM_FUNC_TYPE (arm_current_func_type ()) == ARM_FT_NORMAL
8302 && !IS_STACKALIGN (arm_current_func_type ())))
8303 <return_cond_false>"
8308 thumb2_expand_return (<return_simple_p>);
8315 ;; Often the return insn will be the same as loading from memory, so set attr
8316 (define_insn "*arm_return"
8318 "TARGET_ARM && USE_RETURN_INSN (FALSE)"
8321 if (arm_ccfsm_state == 2)
8323 arm_ccfsm_state += 2;
8326 return output_return_instruction (const_true_rtx, true, false, false);
8328 [(set_attr "type" "load1")
8329 (set_attr "length" "12")
8330 (set_attr "predicable" "yes")]
8333 (define_insn "*cond_<return_str>return"
8335 (if_then_else (match_operator 0 "arm_comparison_operator"
8336 [(match_operand 1 "cc_register" "") (const_int 0)])
8339 "TARGET_ARM <return_cond_true>"
8342 if (arm_ccfsm_state == 2)
8344 arm_ccfsm_state += 2;
8347 return output_return_instruction (operands[0], true, false,
8350 [(set_attr "conds" "use")
8351 (set_attr "length" "12")
8352 (set_attr "type" "load1")]
8355 (define_insn "*cond_<return_str>return_inverted"
8357 (if_then_else (match_operator 0 "arm_comparison_operator"
8358 [(match_operand 1 "cc_register" "") (const_int 0)])
8361 "TARGET_ARM <return_cond_true>"
8364 if (arm_ccfsm_state == 2)
8366 arm_ccfsm_state += 2;
8369 return output_return_instruction (operands[0], true, true,
8372 [(set_attr "conds" "use")
8373 (set_attr "length" "12")
8374 (set_attr "type" "load1")]
8377 (define_insn "*arm_simple_return"
8382 if (arm_ccfsm_state == 2)
8384 arm_ccfsm_state += 2;
8387 return output_return_instruction (const_true_rtx, true, false, true);
8389 [(set_attr "type" "branch")
8390 (set_attr "length" "4")
8391 (set_attr "predicable" "yes")]
8394 ;; Generate a sequence of instructions to determine if the processor is
8395 ;; in 26-bit or 32-bit mode, and return the appropriate return address
8398 (define_expand "return_addr_mask"
8400 (compare:CC_NOOV (unspec [(const_int 0)] UNSPEC_CHECK_ARCH)
8402 (set (match_operand:SI 0 "s_register_operand" "")
8403 (if_then_else:SI (eq (match_dup 1) (const_int 0))
8405 (const_int 67108860)))] ; 0x03fffffc
8408 operands[1] = gen_rtx_REG (CC_NOOVmode, CC_REGNUM);
8411 (define_insn "*check_arch2"
8412 [(set (match_operand:CC_NOOV 0 "cc_register" "")
8413 (compare:CC_NOOV (unspec [(const_int 0)] UNSPEC_CHECK_ARCH)
8416 "teq\\t%|r0, %|r0\;teq\\t%|pc, %|pc"
8417 [(set_attr "length" "8")
8418 (set_attr "conds" "set")
8419 (set_attr "type" "multiple")]
8422 ;; Call subroutine returning any type.
8424 (define_expand "untyped_call"
8425 [(parallel [(call (match_operand 0 "" "")
8427 (match_operand 1 "" "")
8428 (match_operand 2 "" "")])]
8433 rtx par = gen_rtx_PARALLEL (VOIDmode,
8434 rtvec_alloc (XVECLEN (operands[2], 0)));
8435 rtx addr = gen_reg_rtx (Pmode);
8439 emit_move_insn (addr, XEXP (operands[1], 0));
8440 mem = change_address (operands[1], BLKmode, addr);
8442 for (i = 0; i < XVECLEN (operands[2], 0); i++)
8444 rtx src = SET_SRC (XVECEXP (operands[2], 0, i));
8446 /* Default code only uses r0 as a return value, but we could
8447 be using anything up to 4 registers. */
8448 if (REGNO (src) == R0_REGNUM)
8449 src = gen_rtx_REG (TImode, R0_REGNUM);
8451 XVECEXP (par, 0, i) = gen_rtx_EXPR_LIST (VOIDmode, src,
8453 size += GET_MODE_SIZE (GET_MODE (src));
8456 emit_call_insn (gen_call_value (par, operands[0], const0_rtx, NULL));
8460 for (i = 0; i < XVECLEN (par, 0); i++)
8462 HOST_WIDE_INT offset = 0;
8463 rtx reg = XEXP (XVECEXP (par, 0, i), 0);
8466 emit_move_insn (addr, plus_constant (Pmode, addr, size));
8468 mem = change_address (mem, GET_MODE (reg), NULL);
8469 if (REGNO (reg) == R0_REGNUM)
8471 /* On thumb we have to use a write-back instruction. */
8472 emit_insn (arm_gen_store_multiple (arm_regs_in_sequence, 4, addr,
8473 TARGET_THUMB ? TRUE : FALSE, mem, &offset));
8474 size = TARGET_ARM ? 16 : 0;
8478 emit_move_insn (mem, reg);
8479 size = GET_MODE_SIZE (GET_MODE (reg));
8483 /* The optimizer does not know that the call sets the function value
8484 registers we stored in the result block. We avoid problems by
8485 claiming that all hard registers are used and clobbered at this
8487 emit_insn (gen_blockage ());
8493 (define_expand "untyped_return"
8494 [(match_operand:BLK 0 "memory_operand" "")
8495 (match_operand 1 "" "")]
8500 rtx addr = gen_reg_rtx (Pmode);
8504 emit_move_insn (addr, XEXP (operands[0], 0));
8505 mem = change_address (operands[0], BLKmode, addr);
8507 for (i = 0; i < XVECLEN (operands[1], 0); i++)
8509 HOST_WIDE_INT offset = 0;
8510 rtx reg = SET_DEST (XVECEXP (operands[1], 0, i));
8513 emit_move_insn (addr, plus_constant (Pmode, addr, size));
8515 mem = change_address (mem, GET_MODE (reg), NULL);
8516 if (REGNO (reg) == R0_REGNUM)
8518 /* On thumb we have to use a write-back instruction. */
8519 emit_insn (arm_gen_load_multiple (arm_regs_in_sequence, 4, addr,
8520 TARGET_THUMB ? TRUE : FALSE, mem, &offset));
8521 size = TARGET_ARM ? 16 : 0;
8525 emit_move_insn (reg, mem);
8526 size = GET_MODE_SIZE (GET_MODE (reg));
8530 /* Emit USE insns before the return. */
8531 for (i = 0; i < XVECLEN (operands[1], 0); i++)
8532 emit_use (SET_DEST (XVECEXP (operands[1], 0, i)));
8534 /* Construct the return. */
8535 expand_naked_return ();
8541 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
8542 ;; all of memory. This blocks insns from being moved across this point.
8544 (define_insn "blockage"
8545 [(unspec_volatile [(const_int 0)] VUNSPEC_BLOCKAGE)]
8548 [(set_attr "length" "0")
8549 (set_attr "type" "block")]
8552 (define_insn "probe_stack"
8553 [(set (match_operand:SI 0 "memory_operand" "=m")
8554 (unspec:SI [(const_int 0)] UNSPEC_PROBE_STACK))]
8557 [(set_attr "type" "store1")
8558 (set_attr "predicable" "yes")]
8561 (define_insn "probe_stack_range"
8562 [(set (match_operand:SI 0 "register_operand" "=r")
8563 (unspec_volatile:SI [(match_operand:SI 1 "register_operand" "0")
8564 (match_operand:SI 2 "register_operand" "r")]
8565 VUNSPEC_PROBE_STACK_RANGE))]
8568 return output_probe_stack_range (operands[0], operands[2]);
8570 [(set_attr "type" "multiple")
8571 (set_attr "conds" "clob")]
8574 (define_expand "casesi"
8575 [(match_operand:SI 0 "s_register_operand" "") ; index to jump on
8576 (match_operand:SI 1 "const_int_operand" "") ; lower bound
8577 (match_operand:SI 2 "const_int_operand" "") ; total range
8578 (match_operand:SI 3 "" "") ; table label
8579 (match_operand:SI 4 "" "")] ; Out of range label
8580 "(TARGET_32BIT || optimize_size || flag_pic) && !target_pure_code"
8583 enum insn_code code;
8584 if (operands[1] != const0_rtx)
8586 rtx reg = gen_reg_rtx (SImode);
8588 emit_insn (gen_addsi3 (reg, operands[0],
8589 gen_int_mode (-INTVAL (operands[1]),
8595 code = CODE_FOR_arm_casesi_internal;
8596 else if (TARGET_THUMB1)
8597 code = CODE_FOR_thumb1_casesi_internal_pic;
8599 code = CODE_FOR_thumb2_casesi_internal_pic;
8601 code = CODE_FOR_thumb2_casesi_internal;
8603 if (!insn_data[(int) code].operand[1].predicate(operands[2], SImode))
8604 operands[2] = force_reg (SImode, operands[2]);
8606 emit_jump_insn (GEN_FCN ((int) code) (operands[0], operands[2],
8607 operands[3], operands[4]));
8612 ;; The USE in this pattern is needed to tell flow analysis that this is
8613 ;; a CASESI insn. It has no other purpose.
8614 (define_insn "arm_casesi_internal"
8615 [(parallel [(set (pc)
8617 (leu (match_operand:SI 0 "s_register_operand" "r")
8618 (match_operand:SI 1 "arm_rhs_operand" "rI"))
8619 (mem:SI (plus:SI (mult:SI (match_dup 0) (const_int 4))
8620 (label_ref (match_operand 2 "" ""))))
8621 (label_ref (match_operand 3 "" ""))))
8622 (clobber (reg:CC CC_REGNUM))
8623 (use (label_ref (match_dup 2)))])]
8627 return \"cmp\\t%0, %1\;addls\\t%|pc, %|pc, %0, asl #2\;b\\t%l3\";
8628 return \"cmp\\t%0, %1\;ldrls\\t%|pc, [%|pc, %0, asl #2]\;b\\t%l3\";
8630 [(set_attr "conds" "clob")
8631 (set_attr "length" "12")
8632 (set_attr "type" "multiple")]
8635 (define_expand "indirect_jump"
8637 (match_operand:SI 0 "s_register_operand" ""))]
8640 /* Thumb-2 doesn't have mov pc, reg. Explicitly set the low bit of the
8641 address and use bx. */
8645 tmp = gen_reg_rtx (SImode);
8646 emit_insn (gen_iorsi3 (tmp, operands[0], GEN_INT(1)));
8652 ;; NB Never uses BX.
8653 (define_insn "*arm_indirect_jump"
8655 (match_operand:SI 0 "s_register_operand" "r"))]
8657 "mov%?\\t%|pc, %0\\t%@ indirect register jump"
8658 [(set_attr "predicable" "yes")
8659 (set_attr "type" "branch")]
8662 (define_insn "*load_indirect_jump"
8664 (match_operand:SI 0 "memory_operand" "m"))]
8666 "ldr%?\\t%|pc, %0\\t%@ indirect memory jump"
8667 [(set_attr "type" "load1")
8668 (set_attr "pool_range" "4096")
8669 (set_attr "neg_pool_range" "4084")
8670 (set_attr "predicable" "yes")]
8680 [(set (attr "length")
8681 (if_then_else (eq_attr "is_thumb" "yes")
8684 (set_attr "type" "mov_reg")]
8688 [(trap_if (const_int 1) (const_int 0))]
8692 return \".inst\\t0xe7f000f0\";
8694 return \".inst\\t0xdeff\";
8696 [(set (attr "length")
8697 (if_then_else (eq_attr "is_thumb" "yes")
8700 (set_attr "type" "trap")
8701 (set_attr "conds" "unconditional")]
8705 ;; Patterns to allow combination of arithmetic, cond code and shifts
8707 (define_insn "*<arith_shift_insn>_multsi"
8708 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8710 (mult:SI (match_operand:SI 2 "s_register_operand" "r,r")
8711 (match_operand:SI 3 "power_of_two_operand" ""))
8712 (match_operand:SI 1 "s_register_operand" "rk,<t2_binop0>")))]
8714 "<arith_shift_insn>%?\\t%0, %1, %2, lsl %b3"
8715 [(set_attr "predicable" "yes")
8716 (set_attr "predicable_short_it" "no")
8717 (set_attr "shift" "2")
8718 (set_attr "arch" "a,t2")
8719 (set_attr "type" "alu_shift_imm")])
8721 (define_insn "*<arith_shift_insn>_shiftsi"
8722 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
8724 (match_operator:SI 2 "shift_nomul_operator"
8725 [(match_operand:SI 3 "s_register_operand" "r,r,r")
8726 (match_operand:SI 4 "shift_amount_operand" "M,M,r")])
8727 (match_operand:SI 1 "s_register_operand" "rk,<t2_binop0>,rk")))]
8728 "TARGET_32BIT && GET_CODE (operands[2]) != MULT"
8729 "<arith_shift_insn>%?\\t%0, %1, %3%S2"
8730 [(set_attr "predicable" "yes")
8731 (set_attr "predicable_short_it" "no")
8732 (set_attr "shift" "3")
8733 (set_attr "arch" "a,t2,a")
8734 (set_attr "type" "alu_shift_imm,alu_shift_imm,alu_shift_reg")])
8737 [(set (match_operand:SI 0 "s_register_operand" "")
8738 (match_operator:SI 1 "shiftable_operator"
8739 [(match_operator:SI 2 "shiftable_operator"
8740 [(match_operator:SI 3 "shift_operator"
8741 [(match_operand:SI 4 "s_register_operand" "")
8742 (match_operand:SI 5 "reg_or_int_operand" "")])
8743 (match_operand:SI 6 "s_register_operand" "")])
8744 (match_operand:SI 7 "arm_rhs_operand" "")]))
8745 (clobber (match_operand:SI 8 "s_register_operand" ""))]
8748 (match_op_dup 2 [(match_op_dup 3 [(match_dup 4) (match_dup 5)])
8751 (match_op_dup 1 [(match_dup 8) (match_dup 7)]))]
8754 (define_insn "*arith_shiftsi_compare0"
8755 [(set (reg:CC_NOOV CC_REGNUM)
8757 (match_operator:SI 1 "shiftable_operator"
8758 [(match_operator:SI 3 "shift_operator"
8759 [(match_operand:SI 4 "s_register_operand" "r,r")
8760 (match_operand:SI 5 "shift_amount_operand" "M,r")])
8761 (match_operand:SI 2 "s_register_operand" "r,r")])
8763 (set (match_operand:SI 0 "s_register_operand" "=r,r")
8764 (match_op_dup 1 [(match_op_dup 3 [(match_dup 4) (match_dup 5)])
8767 "%i1s%?\\t%0, %2, %4%S3"
8768 [(set_attr "conds" "set")
8769 (set_attr "shift" "4")
8770 (set_attr "arch" "32,a")
8771 (set_attr "type" "alus_shift_imm,alus_shift_reg")])
8773 (define_insn "*arith_shiftsi_compare0_scratch"
8774 [(set (reg:CC_NOOV CC_REGNUM)
8776 (match_operator:SI 1 "shiftable_operator"
8777 [(match_operator:SI 3 "shift_operator"
8778 [(match_operand:SI 4 "s_register_operand" "r,r")
8779 (match_operand:SI 5 "shift_amount_operand" "M,r")])
8780 (match_operand:SI 2 "s_register_operand" "r,r")])
8782 (clobber (match_scratch:SI 0 "=r,r"))]
8784 "%i1s%?\\t%0, %2, %4%S3"
8785 [(set_attr "conds" "set")
8786 (set_attr "shift" "4")
8787 (set_attr "arch" "32,a")
8788 (set_attr "type" "alus_shift_imm,alus_shift_reg")])
8790 (define_insn "*sub_shiftsi"
8791 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8792 (minus:SI (match_operand:SI 1 "s_register_operand" "r,r")
8793 (match_operator:SI 2 "shift_operator"
8794 [(match_operand:SI 3 "s_register_operand" "r,r")
8795 (match_operand:SI 4 "shift_amount_operand" "M,r")])))]
8797 "sub%?\\t%0, %1, %3%S2"
8798 [(set_attr "predicable" "yes")
8799 (set_attr "shift" "3")
8800 (set_attr "arch" "32,a")
8801 (set_attr "type" "alus_shift_imm,alus_shift_reg")])
8803 (define_insn "*sub_shiftsi_compare0"
8804 [(set (reg:CC_NOOV CC_REGNUM)
8806 (minus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
8807 (match_operator:SI 2 "shift_operator"
8808 [(match_operand:SI 3 "s_register_operand" "r,r,r")
8809 (match_operand:SI 4 "shift_amount_operand" "M,r,M")]))
8811 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
8812 (minus:SI (match_dup 1)
8813 (match_op_dup 2 [(match_dup 3) (match_dup 4)])))]
8815 "subs%?\\t%0, %1, %3%S2"
8816 [(set_attr "conds" "set")
8817 (set_attr "shift" "3")
8818 (set_attr "arch" "32,a,a")
8819 (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
8821 (define_insn "*sub_shiftsi_compare0_scratch"
8822 [(set (reg:CC_NOOV CC_REGNUM)
8824 (minus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
8825 (match_operator:SI 2 "shift_operator"
8826 [(match_operand:SI 3 "s_register_operand" "r,r,r")
8827 (match_operand:SI 4 "shift_amount_operand" "M,r,M")]))
8829 (clobber (match_scratch:SI 0 "=r,r,r"))]
8831 "subs%?\\t%0, %1, %3%S2"
8832 [(set_attr "conds" "set")
8833 (set_attr "shift" "3")
8834 (set_attr "arch" "32,a,a")
8835 (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
8838 (define_insn_and_split "*and_scc"
8839 [(set (match_operand:SI 0 "s_register_operand" "=r")
8840 (and:SI (match_operator:SI 1 "arm_comparison_operator"
8841 [(match_operand 2 "cc_register" "") (const_int 0)])
8842 (match_operand:SI 3 "s_register_operand" "r")))]
8844 "#" ; "mov%D1\\t%0, #0\;and%d1\\t%0, %3, #1"
8845 "&& reload_completed"
8846 [(cond_exec (match_dup 5) (set (match_dup 0) (const_int 0)))
8847 (cond_exec (match_dup 4) (set (match_dup 0)
8848 (and:SI (match_dup 3) (const_int 1))))]
8850 machine_mode mode = GET_MODE (operands[2]);
8851 enum rtx_code rc = GET_CODE (operands[1]);
8853 /* Note that operands[4] is the same as operands[1],
8854 but with VOIDmode as the result. */
8855 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
8856 if (mode == CCFPmode || mode == CCFPEmode)
8857 rc = reverse_condition_maybe_unordered (rc);
8859 rc = reverse_condition (rc);
8860 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
8862 [(set_attr "conds" "use")
8863 (set_attr "type" "multiple")
8864 (set_attr "length" "8")]
8867 (define_insn_and_split "*ior_scc"
8868 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8869 (ior:SI (match_operator:SI 1 "arm_comparison_operator"
8870 [(match_operand 2 "cc_register" "") (const_int 0)])
8871 (match_operand:SI 3 "s_register_operand" "0,?r")))]
8876 "&& reload_completed
8877 && REGNO (operands [0]) != REGNO (operands[3])"
8878 ;; && which_alternative == 1
8879 ; mov%D1\\t%0, %3\;orr%d1\\t%0, %3, #1
8880 [(cond_exec (match_dup 5) (set (match_dup 0) (match_dup 3)))
8881 (cond_exec (match_dup 4) (set (match_dup 0)
8882 (ior:SI (match_dup 3) (const_int 1))))]
8884 machine_mode mode = GET_MODE (operands[2]);
8885 enum rtx_code rc = GET_CODE (operands[1]);
8887 /* Note that operands[4] is the same as operands[1],
8888 but with VOIDmode as the result. */
8889 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
8890 if (mode == CCFPmode || mode == CCFPEmode)
8891 rc = reverse_condition_maybe_unordered (rc);
8893 rc = reverse_condition (rc);
8894 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
8896 [(set_attr "conds" "use")
8897 (set_attr "length" "4,8")
8898 (set_attr "type" "logic_imm,multiple")]
8901 ; A series of splitters for the compare_scc pattern below. Note that
8902 ; order is important.
8904 [(set (match_operand:SI 0 "s_register_operand" "")
8905 (lt:SI (match_operand:SI 1 "s_register_operand" "")
8907 (clobber (reg:CC CC_REGNUM))]
8908 "TARGET_32BIT && reload_completed"
8909 [(set (match_dup 0) (lshiftrt:SI (match_dup 1) (const_int 31)))])
8912 [(set (match_operand:SI 0 "s_register_operand" "")
8913 (ge:SI (match_operand:SI 1 "s_register_operand" "")
8915 (clobber (reg:CC CC_REGNUM))]
8916 "TARGET_32BIT && reload_completed"
8917 [(set (match_dup 0) (not:SI (match_dup 1)))
8918 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 31)))])
8921 [(set (match_operand:SI 0 "s_register_operand" "")
8922 (eq:SI (match_operand:SI 1 "s_register_operand" "")
8924 (clobber (reg:CC CC_REGNUM))]
8925 "arm_arch5 && TARGET_32BIT"
8926 [(set (match_dup 0) (clz:SI (match_dup 1)))
8927 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
8931 [(set (match_operand:SI 0 "s_register_operand" "")
8932 (eq:SI (match_operand:SI 1 "s_register_operand" "")
8934 (clobber (reg:CC CC_REGNUM))]
8935 "TARGET_32BIT && reload_completed"
8937 [(set (reg:CC CC_REGNUM)
8938 (compare:CC (const_int 1) (match_dup 1)))
8940 (minus:SI (const_int 1) (match_dup 1)))])
8941 (cond_exec (ltu:CC (reg:CC CC_REGNUM) (const_int 0))
8942 (set (match_dup 0) (const_int 0)))])
8945 [(set (match_operand:SI 0 "s_register_operand" "")
8946 (ne:SI (match_operand:SI 1 "s_register_operand" "")
8947 (match_operand:SI 2 "const_int_operand" "")))
8948 (clobber (reg:CC CC_REGNUM))]
8949 "TARGET_32BIT && reload_completed"
8951 [(set (reg:CC CC_REGNUM)
8952 (compare:CC (match_dup 1) (match_dup 2)))
8953 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 3)))])
8954 (cond_exec (ne:CC (reg:CC CC_REGNUM) (const_int 0))
8955 (set (match_dup 0) (const_int 1)))]
8957 operands[3] = GEN_INT (-INTVAL (operands[2]));
8961 [(set (match_operand:SI 0 "s_register_operand" "")
8962 (ne:SI (match_operand:SI 1 "s_register_operand" "")
8963 (match_operand:SI 2 "arm_add_operand" "")))
8964 (clobber (reg:CC CC_REGNUM))]
8965 "TARGET_32BIT && reload_completed"
8967 [(set (reg:CC_NOOV CC_REGNUM)
8968 (compare:CC_NOOV (minus:SI (match_dup 1) (match_dup 2))
8970 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
8971 (cond_exec (ne:CC_NOOV (reg:CC_NOOV CC_REGNUM) (const_int 0))
8972 (set (match_dup 0) (const_int 1)))])
8974 (define_insn_and_split "*compare_scc"
8975 [(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts")
8976 (match_operator:SI 1 "arm_comparison_operator"
8977 [(match_operand:SI 2 "s_register_operand" "r,r")
8978 (match_operand:SI 3 "arm_add_operand" "rI,L")]))
8979 (clobber (reg:CC CC_REGNUM))]
8982 "&& reload_completed"
8983 [(set (reg:CC CC_REGNUM) (compare:CC (match_dup 2) (match_dup 3)))
8984 (cond_exec (match_dup 4) (set (match_dup 0) (const_int 0)))
8985 (cond_exec (match_dup 5) (set (match_dup 0) (const_int 1)))]
8988 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
8989 operands[2], operands[3]);
8990 enum rtx_code rc = GET_CODE (operands[1]);
8992 tmp1 = gen_rtx_REG (mode, CC_REGNUM);
8994 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, tmp1, const0_rtx);
8995 if (mode == CCFPmode || mode == CCFPEmode)
8996 rc = reverse_condition_maybe_unordered (rc);
8998 rc = reverse_condition (rc);
8999 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, tmp1, const0_rtx);
9001 [(set_attr "type" "multiple")]
9004 ;; Attempt to improve the sequence generated by the compare_scc splitters
9005 ;; not to use conditional execution.
9007 ;; Rd = (eq (reg1) (const_int0)) // ARMv5
9011 [(set (reg:CC CC_REGNUM)
9012 (compare:CC (match_operand:SI 1 "register_operand" "")
9014 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
9015 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
9016 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
9017 (set (match_dup 0) (const_int 1)))]
9018 "arm_arch5 && TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
9019 [(set (match_dup 0) (clz:SI (match_dup 1)))
9020 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
9023 ;; Rd = (eq (reg1) (const_int0)) // !ARMv5
9027 [(set (reg:CC CC_REGNUM)
9028 (compare:CC (match_operand:SI 1 "register_operand" "")
9030 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
9031 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
9032 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
9033 (set (match_dup 0) (const_int 1)))
9034 (match_scratch:SI 2 "r")]
9035 "TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
9037 [(set (reg:CC CC_REGNUM)
9038 (compare:CC (const_int 0) (match_dup 1)))
9039 (set (match_dup 2) (minus:SI (const_int 0) (match_dup 1)))])
9041 (plus:SI (plus:SI (match_dup 1) (match_dup 2))
9042 (geu:SI (reg:CC CC_REGNUM) (const_int 0))))]
9045 ;; Rd = (eq (reg1) (reg2/imm)) // ARMv5 and optimising for speed.
9046 ;; sub Rd, Reg1, reg2
9050 [(set (reg:CC CC_REGNUM)
9051 (compare:CC (match_operand:SI 1 "register_operand" "")
9052 (match_operand:SI 2 "arm_rhs_operand" "")))
9053 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
9054 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
9055 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
9056 (set (match_dup 0) (const_int 1)))]
9057 "arm_arch5 && TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)
9058 && !(TARGET_THUMB2 && optimize_insn_for_size_p ())"
9059 [(set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))
9060 (set (match_dup 0) (clz:SI (match_dup 0)))
9061 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
9065 ;; Rd = (eq (reg1) (reg2)) // ! ARMv5 or optimising for size.
9066 ;; sub T1, Reg1, reg2
9070 [(set (reg:CC CC_REGNUM)
9071 (compare:CC (match_operand:SI 1 "register_operand" "")
9072 (match_operand:SI 2 "arm_rhs_operand" "")))
9073 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
9074 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
9075 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
9076 (set (match_dup 0) (const_int 1)))
9077 (match_scratch:SI 3 "r")]
9078 "TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
9079 [(set (match_dup 3) (match_dup 4))
9081 [(set (reg:CC CC_REGNUM)
9082 (compare:CC (const_int 0) (match_dup 3)))
9083 (set (match_dup 0) (minus:SI (const_int 0) (match_dup 3)))])
9085 (plus:SI (plus:SI (match_dup 0) (match_dup 3))
9086 (geu:SI (reg:CC CC_REGNUM) (const_int 0))))]
9088 if (CONST_INT_P (operands[2]))
9089 operands[4] = plus_constant (SImode, operands[1], -INTVAL (operands[2]));
9091 operands[4] = gen_rtx_MINUS (SImode, operands[1], operands[2]);
9094 (define_insn "*cond_move"
9095 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9096 (if_then_else:SI (match_operator 3 "equality_operator"
9097 [(match_operator 4 "arm_comparison_operator"
9098 [(match_operand 5 "cc_register" "") (const_int 0)])
9100 (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
9101 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))]
9104 if (GET_CODE (operands[3]) == NE)
9106 if (which_alternative != 1)
9107 output_asm_insn (\"mov%D4\\t%0, %2\", operands);
9108 if (which_alternative != 0)
9109 output_asm_insn (\"mov%d4\\t%0, %1\", operands);
9112 if (which_alternative != 0)
9113 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
9114 if (which_alternative != 1)
9115 output_asm_insn (\"mov%d4\\t%0, %2\", operands);
9118 [(set_attr "conds" "use")
9119 (set_attr_alternative "type"
9120 [(if_then_else (match_operand 2 "const_int_operand" "")
9121 (const_string "mov_imm")
9122 (const_string "mov_reg"))
9123 (if_then_else (match_operand 1 "const_int_operand" "")
9124 (const_string "mov_imm")
9125 (const_string "mov_reg"))
9126 (const_string "multiple")])
9127 (set_attr "length" "4,4,8")]
9130 (define_insn "*cond_arith"
9131 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9132 (match_operator:SI 5 "shiftable_operator"
9133 [(match_operator:SI 4 "arm_comparison_operator"
9134 [(match_operand:SI 2 "s_register_operand" "r,r")
9135 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
9136 (match_operand:SI 1 "s_register_operand" "0,?r")]))
9137 (clobber (reg:CC CC_REGNUM))]
9140 if (GET_CODE (operands[4]) == LT && operands[3] == const0_rtx)
9141 return \"%i5\\t%0, %1, %2, lsr #31\";
9143 output_asm_insn (\"cmp\\t%2, %3\", operands);
9144 if (GET_CODE (operands[5]) == AND)
9145 output_asm_insn (\"mov%D4\\t%0, #0\", operands);
9146 else if (GET_CODE (operands[5]) == MINUS)
9147 output_asm_insn (\"rsb%D4\\t%0, %1, #0\", operands);
9148 else if (which_alternative != 0)
9149 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
9150 return \"%i5%d4\\t%0, %1, #1\";
9152 [(set_attr "conds" "clob")
9153 (set_attr "length" "12")
9154 (set_attr "type" "multiple")]
9157 (define_insn "*cond_sub"
9158 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9159 (minus:SI (match_operand:SI 1 "s_register_operand" "0,?r")
9160 (match_operator:SI 4 "arm_comparison_operator"
9161 [(match_operand:SI 2 "s_register_operand" "r,r")
9162 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
9163 (clobber (reg:CC CC_REGNUM))]
9166 output_asm_insn (\"cmp\\t%2, %3\", operands);
9167 if (which_alternative != 0)
9168 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
9169 return \"sub%d4\\t%0, %1, #1\";
9171 [(set_attr "conds" "clob")
9172 (set_attr "length" "8,12")
9173 (set_attr "type" "multiple")]
9176 (define_insn "*cmp_ite0"
9177 [(set (match_operand 6 "dominant_cc_register" "")
9180 (match_operator 4 "arm_comparison_operator"
9181 [(match_operand:SI 0 "s_register_operand"
9182 "l,l,l,r,r,r,r,r,r")
9183 (match_operand:SI 1 "arm_add_operand"
9184 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
9185 (match_operator:SI 5 "arm_comparison_operator"
9186 [(match_operand:SI 2 "s_register_operand"
9187 "l,r,r,l,l,r,r,r,r")
9188 (match_operand:SI 3 "arm_add_operand"
9189 "lPy,rI,L,lPy,lPy,rI,rI,L,L")])
9195 static const char * const cmp1[NUM_OF_COND_CMP][2] =
9197 {\"cmp%d5\\t%0, %1\",
9198 \"cmp%d4\\t%2, %3\"},
9199 {\"cmn%d5\\t%0, #%n1\",
9200 \"cmp%d4\\t%2, %3\"},
9201 {\"cmp%d5\\t%0, %1\",
9202 \"cmn%d4\\t%2, #%n3\"},
9203 {\"cmn%d5\\t%0, #%n1\",
9204 \"cmn%d4\\t%2, #%n3\"}
9206 static const char * const cmp2[NUM_OF_COND_CMP][2] =
9211 \"cmn\\t%0, #%n1\"},
9212 {\"cmn\\t%2, #%n3\",
9214 {\"cmn\\t%2, #%n3\",
9217 static const char * const ite[2] =
9222 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
9223 CMP_CMP, CMN_CMP, CMP_CMP,
9224 CMN_CMP, CMP_CMN, CMN_CMN};
9226 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
9228 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
9229 if (TARGET_THUMB2) {
9230 output_asm_insn (ite[swap], operands);
9232 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
9235 [(set_attr "conds" "set")
9236 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
9237 (set_attr "type" "multiple")
9238 (set_attr_alternative "length"
9244 (if_then_else (eq_attr "is_thumb" "no")
9247 (if_then_else (eq_attr "is_thumb" "no")
9250 (if_then_else (eq_attr "is_thumb" "no")
9253 (if_then_else (eq_attr "is_thumb" "no")
9258 (define_insn "*cmp_ite1"
9259 [(set (match_operand 6 "dominant_cc_register" "")
9262 (match_operator 4 "arm_comparison_operator"
9263 [(match_operand:SI 0 "s_register_operand"
9264 "l,l,l,r,r,r,r,r,r")
9265 (match_operand:SI 1 "arm_add_operand"
9266 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
9267 (match_operator:SI 5 "arm_comparison_operator"
9268 [(match_operand:SI 2 "s_register_operand"
9269 "l,r,r,l,l,r,r,r,r")
9270 (match_operand:SI 3 "arm_add_operand"
9271 "lPy,rI,L,lPy,lPy,rI,rI,L,L")])
9277 static const char * const cmp1[NUM_OF_COND_CMP][2] =
9281 {\"cmn\\t%0, #%n1\",
9284 \"cmn\\t%2, #%n3\"},
9285 {\"cmn\\t%0, #%n1\",
9288 static const char * const cmp2[NUM_OF_COND_CMP][2] =
9290 {\"cmp%d4\\t%2, %3\",
9291 \"cmp%D5\\t%0, %1\"},
9292 {\"cmp%d4\\t%2, %3\",
9293 \"cmn%D5\\t%0, #%n1\"},
9294 {\"cmn%d4\\t%2, #%n3\",
9295 \"cmp%D5\\t%0, %1\"},
9296 {\"cmn%d4\\t%2, #%n3\",
9297 \"cmn%D5\\t%0, #%n1\"}
9299 static const char * const ite[2] =
9304 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
9305 CMP_CMP, CMN_CMP, CMP_CMP,
9306 CMN_CMP, CMP_CMN, CMN_CMN};
9308 comparison_dominates_p (GET_CODE (operands[5]),
9309 reverse_condition (GET_CODE (operands[4])));
9311 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
9312 if (TARGET_THUMB2) {
9313 output_asm_insn (ite[swap], operands);
9315 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
9318 [(set_attr "conds" "set")
9319 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
9320 (set_attr_alternative "length"
9326 (if_then_else (eq_attr "is_thumb" "no")
9329 (if_then_else (eq_attr "is_thumb" "no")
9332 (if_then_else (eq_attr "is_thumb" "no")
9335 (if_then_else (eq_attr "is_thumb" "no")
9338 (set_attr "type" "multiple")]
9341 (define_insn "*cmp_and"
9342 [(set (match_operand 6 "dominant_cc_register" "")
9345 (match_operator 4 "arm_comparison_operator"
9346 [(match_operand:SI 0 "s_register_operand"
9347 "l,l,l,r,r,r,r,r,r")
9348 (match_operand:SI 1 "arm_add_operand"
9349 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
9350 (match_operator:SI 5 "arm_comparison_operator"
9351 [(match_operand:SI 2 "s_register_operand"
9352 "l,r,r,l,l,r,r,r,r")
9353 (match_operand:SI 3 "arm_add_operand"
9354 "lPy,rI,L,lPy,lPy,rI,rI,L,L")]))
9359 static const char *const cmp1[NUM_OF_COND_CMP][2] =
9361 {\"cmp%d5\\t%0, %1\",
9362 \"cmp%d4\\t%2, %3\"},
9363 {\"cmn%d5\\t%0, #%n1\",
9364 \"cmp%d4\\t%2, %3\"},
9365 {\"cmp%d5\\t%0, %1\",
9366 \"cmn%d4\\t%2, #%n3\"},
9367 {\"cmn%d5\\t%0, #%n1\",
9368 \"cmn%d4\\t%2, #%n3\"}
9370 static const char *const cmp2[NUM_OF_COND_CMP][2] =
9375 \"cmn\\t%0, #%n1\"},
9376 {\"cmn\\t%2, #%n3\",
9378 {\"cmn\\t%2, #%n3\",
9381 static const char *const ite[2] =
9386 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
9387 CMP_CMP, CMN_CMP, CMP_CMP,
9388 CMN_CMP, CMP_CMN, CMN_CMN};
9390 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
9392 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
9393 if (TARGET_THUMB2) {
9394 output_asm_insn (ite[swap], operands);
9396 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
9399 [(set_attr "conds" "set")
9400 (set_attr "predicable" "no")
9401 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
9402 (set_attr_alternative "length"
9408 (if_then_else (eq_attr "is_thumb" "no")
9411 (if_then_else (eq_attr "is_thumb" "no")
9414 (if_then_else (eq_attr "is_thumb" "no")
9417 (if_then_else (eq_attr "is_thumb" "no")
9420 (set_attr "type" "multiple")]
9423 (define_insn "*cmp_ior"
9424 [(set (match_operand 6 "dominant_cc_register" "")
9427 (match_operator 4 "arm_comparison_operator"
9428 [(match_operand:SI 0 "s_register_operand"
9429 "l,l,l,r,r,r,r,r,r")
9430 (match_operand:SI 1 "arm_add_operand"
9431 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
9432 (match_operator:SI 5 "arm_comparison_operator"
9433 [(match_operand:SI 2 "s_register_operand"
9434 "l,r,r,l,l,r,r,r,r")
9435 (match_operand:SI 3 "arm_add_operand"
9436 "lPy,rI,L,lPy,lPy,rI,rI,L,L")]))
9441 static const char *const cmp1[NUM_OF_COND_CMP][2] =
9445 {\"cmn\\t%0, #%n1\",
9448 \"cmn\\t%2, #%n3\"},
9449 {\"cmn\\t%0, #%n1\",
9452 static const char *const cmp2[NUM_OF_COND_CMP][2] =
9454 {\"cmp%D4\\t%2, %3\",
9455 \"cmp%D5\\t%0, %1\"},
9456 {\"cmp%D4\\t%2, %3\",
9457 \"cmn%D5\\t%0, #%n1\"},
9458 {\"cmn%D4\\t%2, #%n3\",
9459 \"cmp%D5\\t%0, %1\"},
9460 {\"cmn%D4\\t%2, #%n3\",
9461 \"cmn%D5\\t%0, #%n1\"}
9463 static const char *const ite[2] =
9468 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
9469 CMP_CMP, CMN_CMP, CMP_CMP,
9470 CMN_CMP, CMP_CMN, CMN_CMN};
9472 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
9474 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
9475 if (TARGET_THUMB2) {
9476 output_asm_insn (ite[swap], operands);
9478 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
9482 [(set_attr "conds" "set")
9483 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
9484 (set_attr_alternative "length"
9490 (if_then_else (eq_attr "is_thumb" "no")
9493 (if_then_else (eq_attr "is_thumb" "no")
9496 (if_then_else (eq_attr "is_thumb" "no")
9499 (if_then_else (eq_attr "is_thumb" "no")
9502 (set_attr "type" "multiple")]
9505 (define_insn_and_split "*ior_scc_scc"
9506 [(set (match_operand:SI 0 "s_register_operand" "=Ts")
9507 (ior:SI (match_operator:SI 3 "arm_comparison_operator"
9508 [(match_operand:SI 1 "s_register_operand" "r")
9509 (match_operand:SI 2 "arm_add_operand" "rIL")])
9510 (match_operator:SI 6 "arm_comparison_operator"
9511 [(match_operand:SI 4 "s_register_operand" "r")
9512 (match_operand:SI 5 "arm_add_operand" "rIL")])))
9513 (clobber (reg:CC CC_REGNUM))]
9515 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_OR_Y)
9518 "TARGET_32BIT && reload_completed"
9522 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9523 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9525 (set (match_dup 0) (ne:SI (match_dup 7) (const_int 0)))]
9527 = gen_rtx_REG (arm_select_dominance_cc_mode (operands[3], operands[6],
9530 [(set_attr "conds" "clob")
9531 (set_attr "length" "16")
9532 (set_attr "type" "multiple")]
9535 ; If the above pattern is followed by a CMP insn, then the compare is
9536 ; redundant, since we can rework the conditional instruction that follows.
9537 (define_insn_and_split "*ior_scc_scc_cmp"
9538 [(set (match_operand 0 "dominant_cc_register" "")
9539 (compare (ior:SI (match_operator:SI 3 "arm_comparison_operator"
9540 [(match_operand:SI 1 "s_register_operand" "r")
9541 (match_operand:SI 2 "arm_add_operand" "rIL")])
9542 (match_operator:SI 6 "arm_comparison_operator"
9543 [(match_operand:SI 4 "s_register_operand" "r")
9544 (match_operand:SI 5 "arm_add_operand" "rIL")]))
9546 (set (match_operand:SI 7 "s_register_operand" "=Ts")
9547 (ior:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9548 (match_op_dup 6 [(match_dup 4) (match_dup 5)])))]
9551 "TARGET_32BIT && reload_completed"
9555 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9556 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9558 (set (match_dup 7) (ne:SI (match_dup 0) (const_int 0)))]
9560 [(set_attr "conds" "set")
9561 (set_attr "length" "16")
9562 (set_attr "type" "multiple")]
9565 (define_insn_and_split "*and_scc_scc"
9566 [(set (match_operand:SI 0 "s_register_operand" "=Ts")
9567 (and:SI (match_operator:SI 3 "arm_comparison_operator"
9568 [(match_operand:SI 1 "s_register_operand" "r")
9569 (match_operand:SI 2 "arm_add_operand" "rIL")])
9570 (match_operator:SI 6 "arm_comparison_operator"
9571 [(match_operand:SI 4 "s_register_operand" "r")
9572 (match_operand:SI 5 "arm_add_operand" "rIL")])))
9573 (clobber (reg:CC CC_REGNUM))]
9575 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
9578 "TARGET_32BIT && reload_completed
9579 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
9584 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9585 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9587 (set (match_dup 0) (ne:SI (match_dup 7) (const_int 0)))]
9589 = gen_rtx_REG (arm_select_dominance_cc_mode (operands[3], operands[6],
9592 [(set_attr "conds" "clob")
9593 (set_attr "length" "16")
9594 (set_attr "type" "multiple")]
9597 ; If the above pattern is followed by a CMP insn, then the compare is
9598 ; redundant, since we can rework the conditional instruction that follows.
9599 (define_insn_and_split "*and_scc_scc_cmp"
9600 [(set (match_operand 0 "dominant_cc_register" "")
9601 (compare (and:SI (match_operator:SI 3 "arm_comparison_operator"
9602 [(match_operand:SI 1 "s_register_operand" "r")
9603 (match_operand:SI 2 "arm_add_operand" "rIL")])
9604 (match_operator:SI 6 "arm_comparison_operator"
9605 [(match_operand:SI 4 "s_register_operand" "r")
9606 (match_operand:SI 5 "arm_add_operand" "rIL")]))
9608 (set (match_operand:SI 7 "s_register_operand" "=Ts")
9609 (and:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9610 (match_op_dup 6 [(match_dup 4) (match_dup 5)])))]
9613 "TARGET_32BIT && reload_completed"
9617 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9618 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9620 (set (match_dup 7) (ne:SI (match_dup 0) (const_int 0)))]
9622 [(set_attr "conds" "set")
9623 (set_attr "length" "16")
9624 (set_attr "type" "multiple")]
9627 ;; If there is no dominance in the comparison, then we can still save an
9628 ;; instruction in the AND case, since we can know that the second compare
9629 ;; need only zero the value if false (if true, then the value is already
9631 (define_insn_and_split "*and_scc_scc_nodom"
9632 [(set (match_operand:SI 0 "s_register_operand" "=&Ts,&Ts,&Ts")
9633 (and:SI (match_operator:SI 3 "arm_comparison_operator"
9634 [(match_operand:SI 1 "s_register_operand" "r,r,0")
9635 (match_operand:SI 2 "arm_add_operand" "rIL,0,rIL")])
9636 (match_operator:SI 6 "arm_comparison_operator"
9637 [(match_operand:SI 4 "s_register_operand" "r,r,r")
9638 (match_operand:SI 5 "arm_add_operand" "rIL,rIL,rIL")])))
9639 (clobber (reg:CC CC_REGNUM))]
9641 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
9644 "TARGET_32BIT && reload_completed"
9645 [(parallel [(set (match_dup 0)
9646 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
9647 (clobber (reg:CC CC_REGNUM))])
9648 (set (match_dup 7) (match_op_dup 8 [(match_dup 4) (match_dup 5)]))
9650 (if_then_else:SI (match_op_dup 6 [(match_dup 7) (const_int 0)])
9653 "operands[7] = gen_rtx_REG (SELECT_CC_MODE (GET_CODE (operands[6]),
9654 operands[4], operands[5]),
9656 operands[8] = gen_rtx_COMPARE (GET_MODE (operands[7]), operands[4],
9658 [(set_attr "conds" "clob")
9659 (set_attr "length" "20")
9660 (set_attr "type" "multiple")]
9664 [(set (reg:CC_NOOV CC_REGNUM)
9665 (compare:CC_NOOV (ior:SI
9666 (and:SI (match_operand:SI 0 "s_register_operand" "")
9668 (match_operator:SI 1 "arm_comparison_operator"
9669 [(match_operand:SI 2 "s_register_operand" "")
9670 (match_operand:SI 3 "arm_add_operand" "")]))
9672 (clobber (match_operand:SI 4 "s_register_operand" ""))]
9675 (ior:SI (match_op_dup 1 [(match_dup 2) (match_dup 3)])
9677 (set (reg:CC_NOOV CC_REGNUM)
9678 (compare:CC_NOOV (and:SI (match_dup 4) (const_int 1))
9683 [(set (reg:CC_NOOV CC_REGNUM)
9684 (compare:CC_NOOV (ior:SI
9685 (match_operator:SI 1 "arm_comparison_operator"
9686 [(match_operand:SI 2 "s_register_operand" "")
9687 (match_operand:SI 3 "arm_add_operand" "")])
9688 (and:SI (match_operand:SI 0 "s_register_operand" "")
9691 (clobber (match_operand:SI 4 "s_register_operand" ""))]
9694 (ior:SI (match_op_dup 1 [(match_dup 2) (match_dup 3)])
9696 (set (reg:CC_NOOV CC_REGNUM)
9697 (compare:CC_NOOV (and:SI (match_dup 4) (const_int 1))
9700 ;; ??? The conditional patterns above need checking for Thumb-2 usefulness
9702 (define_insn_and_split "*negscc"
9703 [(set (match_operand:SI 0 "s_register_operand" "=r")
9704 (neg:SI (match_operator 3 "arm_comparison_operator"
9705 [(match_operand:SI 1 "s_register_operand" "r")
9706 (match_operand:SI 2 "arm_rhs_operand" "rI")])))
9707 (clobber (reg:CC CC_REGNUM))]
9710 "&& reload_completed"
9713 rtx cc_reg = gen_rtx_REG (CCmode, CC_REGNUM);
9715 if (GET_CODE (operands[3]) == LT && operands[2] == const0_rtx)
9717 /* Emit mov\\t%0, %1, asr #31 */
9718 emit_insn (gen_rtx_SET (operands[0],
9719 gen_rtx_ASHIFTRT (SImode,
9724 else if (GET_CODE (operands[3]) == NE)
9726 /* Emit subs\\t%0, %1, %2\;mvnne\\t%0, #0 */
9727 if (CONST_INT_P (operands[2]))
9728 emit_insn (gen_cmpsi2_addneg (operands[0], operands[1], operands[2],
9729 GEN_INT (- INTVAL (operands[2]))));
9731 emit_insn (gen_subsi3_compare (operands[0], operands[1], operands[2]));
9733 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
9737 gen_rtx_SET (operands[0],
9743 /* Emit: cmp\\t%1, %2\;mov%D3\\t%0, #0\;mvn%d3\\t%0, #0 */
9744 emit_insn (gen_rtx_SET (cc_reg,
9745 gen_rtx_COMPARE (CCmode, operands[1], operands[2])));
9746 enum rtx_code rc = GET_CODE (operands[3]);
9748 rc = reverse_condition (rc);
9749 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
9754 gen_rtx_SET (operands[0], const0_rtx)));
9755 rc = GET_CODE (operands[3]);
9756 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
9761 gen_rtx_SET (operands[0],
9767 [(set_attr "conds" "clob")
9768 (set_attr "length" "12")
9769 (set_attr "type" "multiple")]
9772 (define_insn_and_split "movcond_addsi"
9773 [(set (match_operand:SI 0 "s_register_operand" "=r,l,r")
9775 (match_operator 5 "comparison_operator"
9776 [(plus:SI (match_operand:SI 3 "s_register_operand" "r,r,r")
9777 (match_operand:SI 4 "arm_add_operand" "rIL,rIL,rIL"))
9779 (match_operand:SI 1 "arm_rhs_operand" "rI,rPy,r")
9780 (match_operand:SI 2 "arm_rhs_operand" "rI,rPy,r")))
9781 (clobber (reg:CC CC_REGNUM))]
9784 "&& reload_completed"
9785 [(set (reg:CC_NOOV CC_REGNUM)
9787 (plus:SI (match_dup 3)
9790 (set (match_dup 0) (match_dup 1))
9791 (cond_exec (match_dup 6)
9792 (set (match_dup 0) (match_dup 2)))]
9795 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[5]),
9796 operands[3], operands[4]);
9797 enum rtx_code rc = GET_CODE (operands[5]);
9798 operands[6] = gen_rtx_REG (mode, CC_REGNUM);
9799 gcc_assert (!(mode == CCFPmode || mode == CCFPEmode));
9800 if (!REG_P (operands[2]) || REGNO (operands[2]) != REGNO (operands[0]))
9801 rc = reverse_condition (rc);
9803 std::swap (operands[1], operands[2]);
9805 operands[6] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
9808 [(set_attr "conds" "clob")
9809 (set_attr "enabled_for_depr_it" "no,yes,yes")
9810 (set_attr "type" "multiple")]
9813 (define_insn "movcond"
9814 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9816 (match_operator 5 "arm_comparison_operator"
9817 [(match_operand:SI 3 "s_register_operand" "r,r,r")
9818 (match_operand:SI 4 "arm_add_operand" "rIL,rIL,rIL")])
9819 (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
9820 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
9821 (clobber (reg:CC CC_REGNUM))]
9824 if (GET_CODE (operands[5]) == LT
9825 && (operands[4] == const0_rtx))
9827 if (which_alternative != 1 && REG_P (operands[1]))
9829 if (operands[2] == const0_rtx)
9830 return \"and\\t%0, %1, %3, asr #31\";
9831 return \"ands\\t%0, %1, %3, asr #32\;movcc\\t%0, %2\";
9833 else if (which_alternative != 0 && REG_P (operands[2]))
9835 if (operands[1] == const0_rtx)
9836 return \"bic\\t%0, %2, %3, asr #31\";
9837 return \"bics\\t%0, %2, %3, asr #32\;movcs\\t%0, %1\";
9839 /* The only case that falls through to here is when both ops 1 & 2
9843 if (GET_CODE (operands[5]) == GE
9844 && (operands[4] == const0_rtx))
9846 if (which_alternative != 1 && REG_P (operands[1]))
9848 if (operands[2] == const0_rtx)
9849 return \"bic\\t%0, %1, %3, asr #31\";
9850 return \"bics\\t%0, %1, %3, asr #32\;movcs\\t%0, %2\";
9852 else if (which_alternative != 0 && REG_P (operands[2]))
9854 if (operands[1] == const0_rtx)
9855 return \"and\\t%0, %2, %3, asr #31\";
9856 return \"ands\\t%0, %2, %3, asr #32\;movcc\\t%0, %1\";
9858 /* The only case that falls through to here is when both ops 1 & 2
9861 if (CONST_INT_P (operands[4])
9862 && !const_ok_for_arm (INTVAL (operands[4])))
9863 output_asm_insn (\"cmn\\t%3, #%n4\", operands);
9865 output_asm_insn (\"cmp\\t%3, %4\", operands);
9866 if (which_alternative != 0)
9867 output_asm_insn (\"mov%d5\\t%0, %1\", operands);
9868 if (which_alternative != 1)
9869 output_asm_insn (\"mov%D5\\t%0, %2\", operands);
9872 [(set_attr "conds" "clob")
9873 (set_attr "length" "8,8,12")
9874 (set_attr "type" "multiple")]
9877 ;; ??? The patterns below need checking for Thumb-2 usefulness.
9879 (define_insn "*ifcompare_plus_move"
9880 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9881 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
9882 [(match_operand:SI 4 "s_register_operand" "r,r")
9883 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
9885 (match_operand:SI 2 "s_register_operand" "r,r")
9886 (match_operand:SI 3 "arm_add_operand" "rIL,rIL"))
9887 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))
9888 (clobber (reg:CC CC_REGNUM))]
9891 [(set_attr "conds" "clob")
9892 (set_attr "length" "8,12")
9893 (set_attr "type" "multiple")]
9896 (define_insn "*if_plus_move"
9897 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
9899 (match_operator 4 "arm_comparison_operator"
9900 [(match_operand 5 "cc_register" "") (const_int 0)])
9902 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
9903 (match_operand:SI 3 "arm_add_operand" "rI,L,rI,L"))
9904 (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")))]
9908 sub%d4\\t%0, %2, #%n3
9909 add%d4\\t%0, %2, %3\;mov%D4\\t%0, %1
9910 sub%d4\\t%0, %2, #%n3\;mov%D4\\t%0, %1"
9911 [(set_attr "conds" "use")
9912 (set_attr "length" "4,4,8,8")
9913 (set_attr_alternative "type"
9914 [(if_then_else (match_operand 3 "const_int_operand" "")
9915 (const_string "alu_imm" )
9916 (const_string "alu_sreg"))
9917 (const_string "alu_imm")
9918 (const_string "multiple")
9919 (const_string "multiple")])]
9922 (define_insn "*ifcompare_move_plus"
9923 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9924 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
9925 [(match_operand:SI 4 "s_register_operand" "r,r")
9926 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
9927 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
9929 (match_operand:SI 2 "s_register_operand" "r,r")
9930 (match_operand:SI 3 "arm_add_operand" "rIL,rIL"))))
9931 (clobber (reg:CC CC_REGNUM))]
9934 [(set_attr "conds" "clob")
9935 (set_attr "length" "8,12")
9936 (set_attr "type" "multiple")]
9939 (define_insn "*if_move_plus"
9940 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
9942 (match_operator 4 "arm_comparison_operator"
9943 [(match_operand 5 "cc_register" "") (const_int 0)])
9944 (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")
9946 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
9947 (match_operand:SI 3 "arm_add_operand" "rI,L,rI,L"))))]
9951 sub%D4\\t%0, %2, #%n3
9952 add%D4\\t%0, %2, %3\;mov%d4\\t%0, %1
9953 sub%D4\\t%0, %2, #%n3\;mov%d4\\t%0, %1"
9954 [(set_attr "conds" "use")
9955 (set_attr "length" "4,4,8,8")
9956 (set_attr_alternative "type"
9957 [(if_then_else (match_operand 3 "const_int_operand" "")
9958 (const_string "alu_imm" )
9959 (const_string "alu_sreg"))
9960 (const_string "alu_imm")
9961 (const_string "multiple")
9962 (const_string "multiple")])]
9965 (define_insn "*ifcompare_arith_arith"
9966 [(set (match_operand:SI 0 "s_register_operand" "=r")
9967 (if_then_else:SI (match_operator 9 "arm_comparison_operator"
9968 [(match_operand:SI 5 "s_register_operand" "r")
9969 (match_operand:SI 6 "arm_add_operand" "rIL")])
9970 (match_operator:SI 8 "shiftable_operator"
9971 [(match_operand:SI 1 "s_register_operand" "r")
9972 (match_operand:SI 2 "arm_rhs_operand" "rI")])
9973 (match_operator:SI 7 "shiftable_operator"
9974 [(match_operand:SI 3 "s_register_operand" "r")
9975 (match_operand:SI 4 "arm_rhs_operand" "rI")])))
9976 (clobber (reg:CC CC_REGNUM))]
9979 [(set_attr "conds" "clob")
9980 (set_attr "length" "12")
9981 (set_attr "type" "multiple")]
9984 (define_insn "*if_arith_arith"
9985 [(set (match_operand:SI 0 "s_register_operand" "=r")
9986 (if_then_else:SI (match_operator 5 "arm_comparison_operator"
9987 [(match_operand 8 "cc_register" "") (const_int 0)])
9988 (match_operator:SI 6 "shiftable_operator"
9989 [(match_operand:SI 1 "s_register_operand" "r")
9990 (match_operand:SI 2 "arm_rhs_operand" "rI")])
9991 (match_operator:SI 7 "shiftable_operator"
9992 [(match_operand:SI 3 "s_register_operand" "r")
9993 (match_operand:SI 4 "arm_rhs_operand" "rI")])))]
9995 "%I6%d5\\t%0, %1, %2\;%I7%D5\\t%0, %3, %4"
9996 [(set_attr "conds" "use")
9997 (set_attr "length" "8")
9998 (set_attr "type" "multiple")]
10001 (define_insn "*ifcompare_arith_move"
10002 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10003 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
10004 [(match_operand:SI 2 "s_register_operand" "r,r")
10005 (match_operand:SI 3 "arm_add_operand" "rIL,rIL")])
10006 (match_operator:SI 7 "shiftable_operator"
10007 [(match_operand:SI 4 "s_register_operand" "r,r")
10008 (match_operand:SI 5 "arm_rhs_operand" "rI,rI")])
10009 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))
10010 (clobber (reg:CC CC_REGNUM))]
10013 /* If we have an operation where (op x 0) is the identity operation and
10014 the conditional operator is LT or GE and we are comparing against zero and
10015 everything is in registers then we can do this in two instructions. */
10016 if (operands[3] == const0_rtx
10017 && GET_CODE (operands[7]) != AND
10018 && REG_P (operands[5])
10019 && REG_P (operands[1])
10020 && REGNO (operands[1]) == REGNO (operands[4])
10021 && REGNO (operands[4]) != REGNO (operands[0]))
10023 if (GET_CODE (operands[6]) == LT)
10024 return \"and\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\";
10025 else if (GET_CODE (operands[6]) == GE)
10026 return \"bic\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\";
10028 if (CONST_INT_P (operands[3])
10029 && !const_ok_for_arm (INTVAL (operands[3])))
10030 output_asm_insn (\"cmn\\t%2, #%n3\", operands);
10032 output_asm_insn (\"cmp\\t%2, %3\", operands);
10033 output_asm_insn (\"%I7%d6\\t%0, %4, %5\", operands);
10034 if (which_alternative != 0)
10035 return \"mov%D6\\t%0, %1\";
10038 [(set_attr "conds" "clob")
10039 (set_attr "length" "8,12")
10040 (set_attr "type" "multiple")]
10043 (define_insn "*if_arith_move"
10044 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10045 (if_then_else:SI (match_operator 4 "arm_comparison_operator"
10046 [(match_operand 6 "cc_register" "") (const_int 0)])
10047 (match_operator:SI 5 "shiftable_operator"
10048 [(match_operand:SI 2 "s_register_operand" "r,r")
10049 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
10050 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))]
10053 %I5%d4\\t%0, %2, %3
10054 %I5%d4\\t%0, %2, %3\;mov%D4\\t%0, %1"
10055 [(set_attr "conds" "use")
10056 (set_attr "length" "4,8")
10057 (set_attr_alternative "type"
10058 [(if_then_else (match_operand 3 "const_int_operand" "")
10059 (const_string "alu_shift_imm" )
10060 (const_string "alu_shift_reg"))
10061 (const_string "multiple")])]
10064 (define_insn "*ifcompare_move_arith"
10065 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10066 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
10067 [(match_operand:SI 4 "s_register_operand" "r,r")
10068 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
10069 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
10070 (match_operator:SI 7 "shiftable_operator"
10071 [(match_operand:SI 2 "s_register_operand" "r,r")
10072 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
10073 (clobber (reg:CC CC_REGNUM))]
10076 /* If we have an operation where (op x 0) is the identity operation and
10077 the conditional operator is LT or GE and we are comparing against zero and
10078 everything is in registers then we can do this in two instructions */
10079 if (operands[5] == const0_rtx
10080 && GET_CODE (operands[7]) != AND
10081 && REG_P (operands[3])
10082 && REG_P (operands[1])
10083 && REGNO (operands[1]) == REGNO (operands[2])
10084 && REGNO (operands[2]) != REGNO (operands[0]))
10086 if (GET_CODE (operands[6]) == GE)
10087 return \"and\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\";
10088 else if (GET_CODE (operands[6]) == LT)
10089 return \"bic\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\";
10092 if (CONST_INT_P (operands[5])
10093 && !const_ok_for_arm (INTVAL (operands[5])))
10094 output_asm_insn (\"cmn\\t%4, #%n5\", operands);
10096 output_asm_insn (\"cmp\\t%4, %5\", operands);
10098 if (which_alternative != 0)
10099 output_asm_insn (\"mov%d6\\t%0, %1\", operands);
10100 return \"%I7%D6\\t%0, %2, %3\";
10102 [(set_attr "conds" "clob")
10103 (set_attr "length" "8,12")
10104 (set_attr "type" "multiple")]
10107 (define_insn "*if_move_arith"
10108 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10110 (match_operator 4 "arm_comparison_operator"
10111 [(match_operand 6 "cc_register" "") (const_int 0)])
10112 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
10113 (match_operator:SI 5 "shiftable_operator"
10114 [(match_operand:SI 2 "s_register_operand" "r,r")
10115 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))]
10118 %I5%D4\\t%0, %2, %3
10119 %I5%D4\\t%0, %2, %3\;mov%d4\\t%0, %1"
10120 [(set_attr "conds" "use")
10121 (set_attr "length" "4,8")
10122 (set_attr_alternative "type"
10123 [(if_then_else (match_operand 3 "const_int_operand" "")
10124 (const_string "alu_shift_imm" )
10125 (const_string "alu_shift_reg"))
10126 (const_string "multiple")])]
10129 (define_insn "*ifcompare_move_not"
10130 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10132 (match_operator 5 "arm_comparison_operator"
10133 [(match_operand:SI 3 "s_register_operand" "r,r")
10134 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
10135 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
10137 (match_operand:SI 2 "s_register_operand" "r,r"))))
10138 (clobber (reg:CC CC_REGNUM))]
10141 [(set_attr "conds" "clob")
10142 (set_attr "length" "8,12")
10143 (set_attr "type" "multiple")]
10146 (define_insn "*if_move_not"
10147 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
10149 (match_operator 4 "arm_comparison_operator"
10150 [(match_operand 3 "cc_register" "") (const_int 0)])
10151 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
10152 (not:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))))]
10156 mov%d4\\t%0, %1\;mvn%D4\\t%0, %2
10157 mvn%d4\\t%0, #%B1\;mvn%D4\\t%0, %2"
10158 [(set_attr "conds" "use")
10159 (set_attr "type" "mvn_reg")
10160 (set_attr "length" "4,8,8")
10161 (set_attr "type" "mvn_reg,multiple,multiple")]
10164 (define_insn "*ifcompare_not_move"
10165 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10167 (match_operator 5 "arm_comparison_operator"
10168 [(match_operand:SI 3 "s_register_operand" "r,r")
10169 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
10171 (match_operand:SI 2 "s_register_operand" "r,r"))
10172 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
10173 (clobber (reg:CC CC_REGNUM))]
10176 [(set_attr "conds" "clob")
10177 (set_attr "length" "8,12")
10178 (set_attr "type" "multiple")]
10181 (define_insn "*if_not_move"
10182 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
10184 (match_operator 4 "arm_comparison_operator"
10185 [(match_operand 3 "cc_register" "") (const_int 0)])
10186 (not:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))
10187 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
10191 mov%D4\\t%0, %1\;mvn%d4\\t%0, %2
10192 mvn%D4\\t%0, #%B1\;mvn%d4\\t%0, %2"
10193 [(set_attr "conds" "use")
10194 (set_attr "type" "mvn_reg,multiple,multiple")
10195 (set_attr "length" "4,8,8")]
10198 (define_insn "*ifcompare_shift_move"
10199 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10201 (match_operator 6 "arm_comparison_operator"
10202 [(match_operand:SI 4 "s_register_operand" "r,r")
10203 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
10204 (match_operator:SI 7 "shift_operator"
10205 [(match_operand:SI 2 "s_register_operand" "r,r")
10206 (match_operand:SI 3 "arm_rhs_operand" "rM,rM")])
10207 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
10208 (clobber (reg:CC CC_REGNUM))]
10211 [(set_attr "conds" "clob")
10212 (set_attr "length" "8,12")
10213 (set_attr "type" "multiple")]
10216 (define_insn "*if_shift_move"
10217 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
10219 (match_operator 5 "arm_comparison_operator"
10220 [(match_operand 6 "cc_register" "") (const_int 0)])
10221 (match_operator:SI 4 "shift_operator"
10222 [(match_operand:SI 2 "s_register_operand" "r,r,r")
10223 (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM")])
10224 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
10228 mov%D5\\t%0, %1\;mov%d5\\t%0, %2%S4
10229 mvn%D5\\t%0, #%B1\;mov%d5\\t%0, %2%S4"
10230 [(set_attr "conds" "use")
10231 (set_attr "shift" "2")
10232 (set_attr "length" "4,8,8")
10233 (set_attr_alternative "type"
10234 [(if_then_else (match_operand 3 "const_int_operand" "")
10235 (const_string "mov_shift" )
10236 (const_string "mov_shift_reg"))
10237 (const_string "multiple")
10238 (const_string "multiple")])]
10241 (define_insn "*ifcompare_move_shift"
10242 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10244 (match_operator 6 "arm_comparison_operator"
10245 [(match_operand:SI 4 "s_register_operand" "r,r")
10246 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
10247 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
10248 (match_operator:SI 7 "shift_operator"
10249 [(match_operand:SI 2 "s_register_operand" "r,r")
10250 (match_operand:SI 3 "arm_rhs_operand" "rM,rM")])))
10251 (clobber (reg:CC CC_REGNUM))]
10254 [(set_attr "conds" "clob")
10255 (set_attr "length" "8,12")
10256 (set_attr "type" "multiple")]
10259 (define_insn "*if_move_shift"
10260 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
10262 (match_operator 5 "arm_comparison_operator"
10263 [(match_operand 6 "cc_register" "") (const_int 0)])
10264 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
10265 (match_operator:SI 4 "shift_operator"
10266 [(match_operand:SI 2 "s_register_operand" "r,r,r")
10267 (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM")])))]
10271 mov%d5\\t%0, %1\;mov%D5\\t%0, %2%S4
10272 mvn%d5\\t%0, #%B1\;mov%D5\\t%0, %2%S4"
10273 [(set_attr "conds" "use")
10274 (set_attr "shift" "2")
10275 (set_attr "length" "4,8,8")
10276 (set_attr_alternative "type"
10277 [(if_then_else (match_operand 3 "const_int_operand" "")
10278 (const_string "mov_shift" )
10279 (const_string "mov_shift_reg"))
10280 (const_string "multiple")
10281 (const_string "multiple")])]
10284 (define_insn "*ifcompare_shift_shift"
10285 [(set (match_operand:SI 0 "s_register_operand" "=r")
10287 (match_operator 7 "arm_comparison_operator"
10288 [(match_operand:SI 5 "s_register_operand" "r")
10289 (match_operand:SI 6 "arm_add_operand" "rIL")])
10290 (match_operator:SI 8 "shift_operator"
10291 [(match_operand:SI 1 "s_register_operand" "r")
10292 (match_operand:SI 2 "arm_rhs_operand" "rM")])
10293 (match_operator:SI 9 "shift_operator"
10294 [(match_operand:SI 3 "s_register_operand" "r")
10295 (match_operand:SI 4 "arm_rhs_operand" "rM")])))
10296 (clobber (reg:CC CC_REGNUM))]
10299 [(set_attr "conds" "clob")
10300 (set_attr "length" "12")
10301 (set_attr "type" "multiple")]
10304 (define_insn "*if_shift_shift"
10305 [(set (match_operand:SI 0 "s_register_operand" "=r")
10307 (match_operator 5 "arm_comparison_operator"
10308 [(match_operand 8 "cc_register" "") (const_int 0)])
10309 (match_operator:SI 6 "shift_operator"
10310 [(match_operand:SI 1 "s_register_operand" "r")
10311 (match_operand:SI 2 "arm_rhs_operand" "rM")])
10312 (match_operator:SI 7 "shift_operator"
10313 [(match_operand:SI 3 "s_register_operand" "r")
10314 (match_operand:SI 4 "arm_rhs_operand" "rM")])))]
10316 "mov%d5\\t%0, %1%S6\;mov%D5\\t%0, %3%S7"
10317 [(set_attr "conds" "use")
10318 (set_attr "shift" "1")
10319 (set_attr "length" "8")
10320 (set (attr "type") (if_then_else
10321 (and (match_operand 2 "const_int_operand" "")
10322 (match_operand 4 "const_int_operand" ""))
10323 (const_string "mov_shift")
10324 (const_string "mov_shift_reg")))]
10327 (define_insn "*ifcompare_not_arith"
10328 [(set (match_operand:SI 0 "s_register_operand" "=r")
10330 (match_operator 6 "arm_comparison_operator"
10331 [(match_operand:SI 4 "s_register_operand" "r")
10332 (match_operand:SI 5 "arm_add_operand" "rIL")])
10333 (not:SI (match_operand:SI 1 "s_register_operand" "r"))
10334 (match_operator:SI 7 "shiftable_operator"
10335 [(match_operand:SI 2 "s_register_operand" "r")
10336 (match_operand:SI 3 "arm_rhs_operand" "rI")])))
10337 (clobber (reg:CC CC_REGNUM))]
10340 [(set_attr "conds" "clob")
10341 (set_attr "length" "12")
10342 (set_attr "type" "multiple")]
10345 (define_insn "*if_not_arith"
10346 [(set (match_operand:SI 0 "s_register_operand" "=r")
10348 (match_operator 5 "arm_comparison_operator"
10349 [(match_operand 4 "cc_register" "") (const_int 0)])
10350 (not:SI (match_operand:SI 1 "s_register_operand" "r"))
10351 (match_operator:SI 6 "shiftable_operator"
10352 [(match_operand:SI 2 "s_register_operand" "r")
10353 (match_operand:SI 3 "arm_rhs_operand" "rI")])))]
10355 "mvn%d5\\t%0, %1\;%I6%D5\\t%0, %2, %3"
10356 [(set_attr "conds" "use")
10357 (set_attr "type" "mvn_reg")
10358 (set_attr "length" "8")]
10361 (define_insn "*ifcompare_arith_not"
10362 [(set (match_operand:SI 0 "s_register_operand" "=r")
10364 (match_operator 6 "arm_comparison_operator"
10365 [(match_operand:SI 4 "s_register_operand" "r")
10366 (match_operand:SI 5 "arm_add_operand" "rIL")])
10367 (match_operator:SI 7 "shiftable_operator"
10368 [(match_operand:SI 2 "s_register_operand" "r")
10369 (match_operand:SI 3 "arm_rhs_operand" "rI")])
10370 (not:SI (match_operand:SI 1 "s_register_operand" "r"))))
10371 (clobber (reg:CC CC_REGNUM))]
10374 [(set_attr "conds" "clob")
10375 (set_attr "length" "12")
10376 (set_attr "type" "multiple")]
10379 (define_insn "*if_arith_not"
10380 [(set (match_operand:SI 0 "s_register_operand" "=r")
10382 (match_operator 5 "arm_comparison_operator"
10383 [(match_operand 4 "cc_register" "") (const_int 0)])
10384 (match_operator:SI 6 "shiftable_operator"
10385 [(match_operand:SI 2 "s_register_operand" "r")
10386 (match_operand:SI 3 "arm_rhs_operand" "rI")])
10387 (not:SI (match_operand:SI 1 "s_register_operand" "r"))))]
10389 "mvn%D5\\t%0, %1\;%I6%d5\\t%0, %2, %3"
10390 [(set_attr "conds" "use")
10391 (set_attr "type" "multiple")
10392 (set_attr "length" "8")]
10395 (define_insn "*ifcompare_neg_move"
10396 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10398 (match_operator 5 "arm_comparison_operator"
10399 [(match_operand:SI 3 "s_register_operand" "r,r")
10400 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
10401 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r"))
10402 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
10403 (clobber (reg:CC CC_REGNUM))]
10406 [(set_attr "conds" "clob")
10407 (set_attr "length" "8,12")
10408 (set_attr "type" "multiple")]
10411 (define_insn_and_split "*if_neg_move"
10412 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
10414 (match_operator 4 "arm_comparison_operator"
10415 [(match_operand 3 "cc_register" "") (const_int 0)])
10416 (neg:SI (match_operand:SI 2 "s_register_operand" "l,r"))
10417 (match_operand:SI 1 "s_register_operand" "0,0")))]
10420 "&& reload_completed"
10421 [(cond_exec (match_op_dup 4 [(match_dup 3) (const_int 0)])
10422 (set (match_dup 0) (neg:SI (match_dup 2))))]
10424 [(set_attr "conds" "use")
10425 (set_attr "length" "4")
10426 (set_attr "arch" "t2,32")
10427 (set_attr "enabled_for_depr_it" "yes,no")
10428 (set_attr "type" "logic_shift_imm")]
10431 (define_insn "*ifcompare_move_neg"
10432 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10434 (match_operator 5 "arm_comparison_operator"
10435 [(match_operand:SI 3 "s_register_operand" "r,r")
10436 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
10437 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
10438 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r"))))
10439 (clobber (reg:CC CC_REGNUM))]
10442 [(set_attr "conds" "clob")
10443 (set_attr "length" "8,12")
10444 (set_attr "type" "multiple")]
10447 (define_insn_and_split "*if_move_neg"
10448 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
10450 (match_operator 4 "arm_comparison_operator"
10451 [(match_operand 3 "cc_register" "") (const_int 0)])
10452 (match_operand:SI 1 "s_register_operand" "0,0")
10453 (neg:SI (match_operand:SI 2 "s_register_operand" "l,r"))))]
10456 "&& reload_completed"
10457 [(cond_exec (match_dup 5)
10458 (set (match_dup 0) (neg:SI (match_dup 2))))]
10460 machine_mode mode = GET_MODE (operands[3]);
10461 rtx_code rc = GET_CODE (operands[4]);
10463 if (mode == CCFPmode || mode == CCFPEmode)
10464 rc = reverse_condition_maybe_unordered (rc);
10466 rc = reverse_condition (rc);
10468 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[3], const0_rtx);
10470 [(set_attr "conds" "use")
10471 (set_attr "length" "4")
10472 (set_attr "arch" "t2,32")
10473 (set_attr "enabled_for_depr_it" "yes,no")
10474 (set_attr "type" "logic_shift_imm")]
10477 (define_insn "*arith_adjacentmem"
10478 [(set (match_operand:SI 0 "s_register_operand" "=r")
10479 (match_operator:SI 1 "shiftable_operator"
10480 [(match_operand:SI 2 "memory_operand" "m")
10481 (match_operand:SI 3 "memory_operand" "m")]))
10482 (clobber (match_scratch:SI 4 "=r"))]
10483 "TARGET_ARM && adjacent_mem_locations (operands[2], operands[3])"
10489 HOST_WIDE_INT val1 = 0, val2 = 0;
10491 if (REGNO (operands[0]) > REGNO (operands[4]))
10493 ldm[1] = operands[4];
10494 ldm[2] = operands[0];
10498 ldm[1] = operands[0];
10499 ldm[2] = operands[4];
10502 base_reg = XEXP (operands[2], 0);
10504 if (!REG_P (base_reg))
10506 val1 = INTVAL (XEXP (base_reg, 1));
10507 base_reg = XEXP (base_reg, 0);
10510 if (!REG_P (XEXP (operands[3], 0)))
10511 val2 = INTVAL (XEXP (XEXP (operands[3], 0), 1));
10513 arith[0] = operands[0];
10514 arith[3] = operands[1];
10528 if (val1 !=0 && val2 != 0)
10532 if (val1 == 4 || val2 == 4)
10533 /* Other val must be 8, since we know they are adjacent and neither
10535 output_asm_insn (\"ldmib%?\\t%0, {%1, %2}\", ldm);
10536 else if (const_ok_for_arm (val1) || const_ok_for_arm (-val1))
10538 ldm[0] = ops[0] = operands[4];
10540 ops[2] = GEN_INT (val1);
10541 output_add_immediate (ops);
10543 output_asm_insn (\"ldmia%?\\t%0, {%1, %2}\", ldm);
10545 output_asm_insn (\"ldmda%?\\t%0, {%1, %2}\", ldm);
10549 /* Offset is out of range for a single add, so use two ldr. */
10552 ops[2] = GEN_INT (val1);
10553 output_asm_insn (\"ldr%?\\t%0, [%1, %2]\", ops);
10555 ops[2] = GEN_INT (val2);
10556 output_asm_insn (\"ldr%?\\t%0, [%1, %2]\", ops);
10559 else if (val1 != 0)
10562 output_asm_insn (\"ldmda%?\\t%0, {%1, %2}\", ldm);
10564 output_asm_insn (\"ldmia%?\\t%0, {%1, %2}\", ldm);
10569 output_asm_insn (\"ldmia%?\\t%0, {%1, %2}\", ldm);
10571 output_asm_insn (\"ldmda%?\\t%0, {%1, %2}\", ldm);
10573 output_asm_insn (\"%I3%?\\t%0, %1, %2\", arith);
10576 [(set_attr "length" "12")
10577 (set_attr "predicable" "yes")
10578 (set_attr "type" "load1")]
10581 ; This pattern is never tried by combine, so do it as a peephole
10584 [(set (match_operand:SI 0 "arm_general_register_operand" "")
10585 (match_operand:SI 1 "arm_general_register_operand" ""))
10586 (set (reg:CC CC_REGNUM)
10587 (compare:CC (match_dup 1) (const_int 0)))]
10589 [(parallel [(set (reg:CC CC_REGNUM) (compare:CC (match_dup 1) (const_int 0)))
10590 (set (match_dup 0) (match_dup 1))])]
10595 [(set (match_operand:SI 0 "s_register_operand" "")
10596 (and:SI (ge:SI (match_operand:SI 1 "s_register_operand" "")
10598 (neg:SI (match_operator:SI 2 "arm_comparison_operator"
10599 [(match_operand:SI 3 "s_register_operand" "")
10600 (match_operand:SI 4 "arm_rhs_operand" "")]))))
10601 (clobber (match_operand:SI 5 "s_register_operand" ""))]
10603 [(set (match_dup 5) (not:SI (ashiftrt:SI (match_dup 1) (const_int 31))))
10604 (set (match_dup 0) (and:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
10609 ;; This split can be used because CC_Z mode implies that the following
10610 ;; branch will be an equality, or an unsigned inequality, so the sign
10611 ;; extension is not needed.
10614 [(set (reg:CC_Z CC_REGNUM)
10616 (ashift:SI (subreg:SI (match_operand:QI 0 "memory_operand" "") 0)
10618 (match_operand 1 "const_int_operand" "")))
10619 (clobber (match_scratch:SI 2 ""))]
10621 && ((UINTVAL (operands[1]))
10622 == ((UINTVAL (operands[1])) >> 24) << 24)"
10623 [(set (match_dup 2) (zero_extend:SI (match_dup 0)))
10624 (set (reg:CC CC_REGNUM) (compare:CC (match_dup 2) (match_dup 1)))]
10626 operands[1] = GEN_INT (((unsigned long) INTVAL (operands[1])) >> 24);
10629 ;; ??? Check the patterns above for Thumb-2 usefulness
10631 (define_expand "prologue"
10632 [(clobber (const_int 0))]
10635 arm_expand_prologue ();
10637 thumb1_expand_prologue ();
10642 (define_expand "epilogue"
10643 [(clobber (const_int 0))]
10646 if (crtl->calls_eh_return)
10647 emit_insn (gen_force_register_use (gen_rtx_REG (Pmode, 2)));
10650 thumb1_expand_epilogue ();
10651 emit_jump_insn (gen_rtx_UNSPEC_VOLATILE (VOIDmode,
10652 gen_rtvec (1, ret_rtx), VUNSPEC_EPILOGUE));
10654 else if (HAVE_return)
10656 /* HAVE_return is testing for USE_RETURN_INSN (FALSE). Hence,
10657 no need for explicit testing again. */
10658 emit_jump_insn (gen_return ());
10660 else if (TARGET_32BIT)
10662 arm_expand_epilogue (true);
10668 ;; Note - although unspec_volatile's USE all hard registers,
10669 ;; USEs are ignored after relaod has completed. Thus we need
10670 ;; to add an unspec of the link register to ensure that flow
10671 ;; does not think that it is unused by the sibcall branch that
10672 ;; will replace the standard function epilogue.
10673 (define_expand "sibcall_epilogue"
10674 [(parallel [(unspec:SI [(reg:SI LR_REGNUM)] UNSPEC_REGISTER_USE)
10675 (unspec_volatile [(return)] VUNSPEC_EPILOGUE)])]
10678 arm_expand_epilogue (false);
10683 (define_expand "eh_epilogue"
10684 [(use (match_operand:SI 0 "register_operand" ""))
10685 (use (match_operand:SI 1 "register_operand" ""))
10686 (use (match_operand:SI 2 "register_operand" ""))]
10690 cfun->machine->eh_epilogue_sp_ofs = operands[1];
10691 if (!REG_P (operands[2]) || REGNO (operands[2]) != 2)
10693 rtx ra = gen_rtx_REG (Pmode, 2);
10695 emit_move_insn (ra, operands[2]);
10698 /* This is a hack -- we may have crystalized the function type too
10700 cfun->machine->func_type = 0;
10704 ;; This split is only used during output to reduce the number of patterns
10705 ;; that need assembler instructions adding to them. We allowed the setting
10706 ;; of the conditions to be implicit during rtl generation so that
10707 ;; the conditional compare patterns would work. However this conflicts to
10708 ;; some extent with the conditional data operations, so we have to split them
10711 ;; ??? Need to audit these splitters for Thumb-2. Why isn't normal
10712 ;; conditional execution sufficient?
10715 [(set (match_operand:SI 0 "s_register_operand" "")
10716 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10717 [(match_operand 2 "" "") (match_operand 3 "" "")])
10719 (match_operand 4 "" "")))
10720 (clobber (reg:CC CC_REGNUM))]
10721 "TARGET_ARM && reload_completed"
10722 [(set (match_dup 5) (match_dup 6))
10723 (cond_exec (match_dup 7)
10724 (set (match_dup 0) (match_dup 4)))]
10727 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10728 operands[2], operands[3]);
10729 enum rtx_code rc = GET_CODE (operands[1]);
10731 operands[5] = gen_rtx_REG (mode, CC_REGNUM);
10732 operands[6] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10733 if (mode == CCFPmode || mode == CCFPEmode)
10734 rc = reverse_condition_maybe_unordered (rc);
10736 rc = reverse_condition (rc);
10738 operands[7] = gen_rtx_fmt_ee (rc, VOIDmode, operands[5], const0_rtx);
10743 [(set (match_operand:SI 0 "s_register_operand" "")
10744 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10745 [(match_operand 2 "" "") (match_operand 3 "" "")])
10746 (match_operand 4 "" "")
10748 (clobber (reg:CC CC_REGNUM))]
10749 "TARGET_ARM && reload_completed"
10750 [(set (match_dup 5) (match_dup 6))
10751 (cond_exec (match_op_dup 1 [(match_dup 5) (const_int 0)])
10752 (set (match_dup 0) (match_dup 4)))]
10755 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10756 operands[2], operands[3]);
10758 operands[5] = gen_rtx_REG (mode, CC_REGNUM);
10759 operands[6] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10764 [(set (match_operand:SI 0 "s_register_operand" "")
10765 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10766 [(match_operand 2 "" "") (match_operand 3 "" "")])
10767 (match_operand 4 "" "")
10768 (match_operand 5 "" "")))
10769 (clobber (reg:CC CC_REGNUM))]
10770 "TARGET_ARM && reload_completed"
10771 [(set (match_dup 6) (match_dup 7))
10772 (cond_exec (match_op_dup 1 [(match_dup 6) (const_int 0)])
10773 (set (match_dup 0) (match_dup 4)))
10774 (cond_exec (match_dup 8)
10775 (set (match_dup 0) (match_dup 5)))]
10778 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10779 operands[2], operands[3]);
10780 enum rtx_code rc = GET_CODE (operands[1]);
10782 operands[6] = gen_rtx_REG (mode, CC_REGNUM);
10783 operands[7] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10784 if (mode == CCFPmode || mode == CCFPEmode)
10785 rc = reverse_condition_maybe_unordered (rc);
10787 rc = reverse_condition (rc);
10789 operands[8] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
10794 [(set (match_operand:SI 0 "s_register_operand" "")
10795 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10796 [(match_operand:SI 2 "s_register_operand" "")
10797 (match_operand:SI 3 "arm_add_operand" "")])
10798 (match_operand:SI 4 "arm_rhs_operand" "")
10800 (match_operand:SI 5 "s_register_operand" ""))))
10801 (clobber (reg:CC CC_REGNUM))]
10802 "TARGET_ARM && reload_completed"
10803 [(set (match_dup 6) (match_dup 7))
10804 (cond_exec (match_op_dup 1 [(match_dup 6) (const_int 0)])
10805 (set (match_dup 0) (match_dup 4)))
10806 (cond_exec (match_dup 8)
10807 (set (match_dup 0) (not:SI (match_dup 5))))]
10810 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10811 operands[2], operands[3]);
10812 enum rtx_code rc = GET_CODE (operands[1]);
10814 operands[6] = gen_rtx_REG (mode, CC_REGNUM);
10815 operands[7] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10816 if (mode == CCFPmode || mode == CCFPEmode)
10817 rc = reverse_condition_maybe_unordered (rc);
10819 rc = reverse_condition (rc);
10821 operands[8] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
10825 (define_insn "*cond_move_not"
10826 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10827 (if_then_else:SI (match_operator 4 "arm_comparison_operator"
10828 [(match_operand 3 "cc_register" "") (const_int 0)])
10829 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
10831 (match_operand:SI 2 "s_register_operand" "r,r"))))]
10835 mov%d4\\t%0, %1\;mvn%D4\\t%0, %2"
10836 [(set_attr "conds" "use")
10837 (set_attr "type" "mvn_reg,multiple")
10838 (set_attr "length" "4,8")]
10841 ;; The next two patterns occur when an AND operation is followed by a
10842 ;; scc insn sequence
10844 (define_insn "*sign_extract_onebit"
10845 [(set (match_operand:SI 0 "s_register_operand" "=r")
10846 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
10848 (match_operand:SI 2 "const_int_operand" "n")))
10849 (clobber (reg:CC CC_REGNUM))]
10852 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
10853 output_asm_insn (\"ands\\t%0, %1, %2\", operands);
10854 return \"mvnne\\t%0, #0\";
10856 [(set_attr "conds" "clob")
10857 (set_attr "length" "8")
10858 (set_attr "type" "multiple")]
10861 (define_insn "*not_signextract_onebit"
10862 [(set (match_operand:SI 0 "s_register_operand" "=r")
10864 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
10866 (match_operand:SI 2 "const_int_operand" "n"))))
10867 (clobber (reg:CC CC_REGNUM))]
10870 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
10871 output_asm_insn (\"tst\\t%1, %2\", operands);
10872 output_asm_insn (\"mvneq\\t%0, #0\", operands);
10873 return \"movne\\t%0, #0\";
10875 [(set_attr "conds" "clob")
10876 (set_attr "length" "12")
10877 (set_attr "type" "multiple")]
10879 ;; ??? The above patterns need auditing for Thumb-2
10881 ;; Push multiple registers to the stack. Registers are in parallel (use ...)
10882 ;; expressions. For simplicity, the first register is also in the unspec
10884 ;; To avoid the usage of GNU extension, the length attribute is computed
10885 ;; in a C function arm_attr_length_push_multi.
10886 (define_insn "*push_multi"
10887 [(match_parallel 2 "multi_register_push"
10888 [(set (match_operand:BLK 0 "push_mult_memory_operand" "")
10889 (unspec:BLK [(match_operand:SI 1 "s_register_operand" "")]
10890 UNSPEC_PUSH_MULT))])]
10894 int num_saves = XVECLEN (operands[2], 0);
10896 /* For the StrongARM at least it is faster to
10897 use STR to store only a single register.
10898 In Thumb mode always use push, and the assembler will pick
10899 something appropriate. */
10900 if (num_saves == 1 && TARGET_ARM)
10901 output_asm_insn (\"str%?\\t%1, [%m0, #-4]!\", operands);
10908 strcpy (pattern, \"push%?\\t{%1\");
10910 strcpy (pattern, \"push\\t{%1\");
10912 for (i = 1; i < num_saves; i++)
10914 strcat (pattern, \", %|\");
10916 reg_names[REGNO (XEXP (XVECEXP (operands[2], 0, i), 0))]);
10919 strcat (pattern, \"}\");
10920 output_asm_insn (pattern, operands);
10925 [(set_attr "type" "store4")
10926 (set (attr "length")
10927 (symbol_ref "arm_attr_length_push_multi (operands[2], operands[1])"))]
10930 (define_insn "stack_tie"
10931 [(set (mem:BLK (scratch))
10932 (unspec:BLK [(match_operand:SI 0 "s_register_operand" "rk")
10933 (match_operand:SI 1 "s_register_operand" "rk")]
10937 [(set_attr "length" "0")
10938 (set_attr "type" "block")]
10941 ;; Pop (as used in epilogue RTL)
10943 (define_insn "*load_multiple_with_writeback"
10944 [(match_parallel 0 "load_multiple_operation"
10945 [(set (match_operand:SI 1 "s_register_operand" "+rk")
10946 (plus:SI (match_dup 1)
10947 (match_operand:SI 2 "const_int_I_operand" "I")))
10948 (set (match_operand:SI 3 "s_register_operand" "=rk")
10949 (mem:SI (match_dup 1)))
10951 "TARGET_32BIT && (reload_in_progress || reload_completed)"
10954 arm_output_multireg_pop (operands, /*return_pc=*/false,
10955 /*cond=*/const_true_rtx,
10961 [(set_attr "type" "load4")
10962 (set_attr "predicable" "yes")
10963 (set (attr "length")
10964 (symbol_ref "arm_attr_length_pop_multi (operands,
10965 /*return_pc=*/false,
10966 /*write_back_p=*/true)"))]
10969 ;; Pop with return (as used in epilogue RTL)
10971 ;; This instruction is generated when the registers are popped at the end of
10972 ;; epilogue. Here, instead of popping the value into LR and then generating
10973 ;; jump to LR, value is popped into PC directly. Hence, the pattern is combined
10975 (define_insn "*pop_multiple_with_writeback_and_return"
10976 [(match_parallel 0 "pop_multiple_return"
10978 (set (match_operand:SI 1 "s_register_operand" "+rk")
10979 (plus:SI (match_dup 1)
10980 (match_operand:SI 2 "const_int_I_operand" "I")))
10981 (set (match_operand:SI 3 "s_register_operand" "=rk")
10982 (mem:SI (match_dup 1)))
10984 "TARGET_32BIT && (reload_in_progress || reload_completed)"
10987 arm_output_multireg_pop (operands, /*return_pc=*/true,
10988 /*cond=*/const_true_rtx,
10994 [(set_attr "type" "load4")
10995 (set_attr "predicable" "yes")
10996 (set (attr "length")
10997 (symbol_ref "arm_attr_length_pop_multi (operands, /*return_pc=*/true,
10998 /*write_back_p=*/true)"))]
11001 (define_insn "*pop_multiple_with_return"
11002 [(match_parallel 0 "pop_multiple_return"
11004 (set (match_operand:SI 2 "s_register_operand" "=rk")
11005 (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
11007 "TARGET_32BIT && (reload_in_progress || reload_completed)"
11010 arm_output_multireg_pop (operands, /*return_pc=*/true,
11011 /*cond=*/const_true_rtx,
11017 [(set_attr "type" "load4")
11018 (set_attr "predicable" "yes")
11019 (set (attr "length")
11020 (symbol_ref "arm_attr_length_pop_multi (operands, /*return_pc=*/true,
11021 /*write_back_p=*/false)"))]
11024 ;; Load into PC and return
11025 (define_insn "*ldr_with_return"
11027 (set (reg:SI PC_REGNUM)
11028 (mem:SI (post_inc:SI (match_operand:SI 0 "s_register_operand" "+rk"))))]
11029 "TARGET_32BIT && (reload_in_progress || reload_completed)"
11030 "ldr%?\t%|pc, [%0], #4"
11031 [(set_attr "type" "load1")
11032 (set_attr "predicable" "yes")]
11034 ;; Pop for floating point registers (as used in epilogue RTL)
11035 (define_insn "*vfp_pop_multiple_with_writeback"
11036 [(match_parallel 0 "pop_multiple_fp"
11037 [(set (match_operand:SI 1 "s_register_operand" "+rk")
11038 (plus:SI (match_dup 1)
11039 (match_operand:SI 2 "const_int_I_operand" "I")))
11040 (set (match_operand:DF 3 "vfp_hard_register_operand" "")
11041 (mem:DF (match_dup 1)))])]
11042 "TARGET_32BIT && TARGET_HARD_FLOAT"
11045 int num_regs = XVECLEN (operands[0], 0);
11048 strcpy (pattern, \"vldm\\t\");
11049 strcat (pattern, reg_names[REGNO (SET_DEST (XVECEXP (operands[0], 0, 0)))]);
11050 strcat (pattern, \"!, {\");
11051 op_list[0] = XEXP (XVECEXP (operands[0], 0, 1), 0);
11052 strcat (pattern, \"%P0\");
11053 if ((num_regs - 1) > 1)
11055 strcat (pattern, \"-%P1\");
11056 op_list [1] = XEXP (XVECEXP (operands[0], 0, num_regs - 1), 0);
11059 strcat (pattern, \"}\");
11060 output_asm_insn (pattern, op_list);
11064 [(set_attr "type" "load4")
11065 (set_attr "conds" "unconditional")
11066 (set_attr "predicable" "no")]
11069 ;; Special patterns for dealing with the constant pool
11071 (define_insn "align_4"
11072 [(unspec_volatile [(const_int 0)] VUNSPEC_ALIGN)]
11075 assemble_align (32);
11078 [(set_attr "type" "no_insn")]
11081 (define_insn "align_8"
11082 [(unspec_volatile [(const_int 0)] VUNSPEC_ALIGN8)]
11085 assemble_align (64);
11088 [(set_attr "type" "no_insn")]
11091 (define_insn "consttable_end"
11092 [(unspec_volatile [(const_int 0)] VUNSPEC_POOL_END)]
11095 making_const_table = FALSE;
11098 [(set_attr "type" "no_insn")]
11101 (define_insn "consttable_1"
11102 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_1)]
11105 making_const_table = TRUE;
11106 assemble_integer (operands[0], 1, BITS_PER_WORD, 1);
11107 assemble_zeros (3);
11110 [(set_attr "length" "4")
11111 (set_attr "type" "no_insn")]
11114 (define_insn "consttable_2"
11115 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_2)]
11119 rtx x = operands[0];
11120 making_const_table = TRUE;
11121 switch (GET_MODE_CLASS (GET_MODE (x)))
11124 arm_emit_fp16_const (x);
11127 assemble_integer (operands[0], 2, BITS_PER_WORD, 1);
11128 assemble_zeros (2);
11133 [(set_attr "length" "4")
11134 (set_attr "type" "no_insn")]
11137 (define_insn "consttable_4"
11138 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_4)]
11142 rtx x = operands[0];
11143 making_const_table = TRUE;
11144 switch (GET_MODE_CLASS (GET_MODE (x)))
11147 assemble_real (*CONST_DOUBLE_REAL_VALUE (x), GET_MODE (x),
11151 /* XXX: Sometimes gcc does something really dumb and ends up with
11152 a HIGH in a constant pool entry, usually because it's trying to
11153 load into a VFP register. We know this will always be used in
11154 combination with a LO_SUM which ignores the high bits, so just
11155 strip off the HIGH. */
11156 if (GET_CODE (x) == HIGH)
11158 assemble_integer (x, 4, BITS_PER_WORD, 1);
11159 mark_symbol_refs_as_used (x);
11164 [(set_attr "length" "4")
11165 (set_attr "type" "no_insn")]
11168 (define_insn "consttable_8"
11169 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_8)]
11173 making_const_table = TRUE;
11174 switch (GET_MODE_CLASS (GET_MODE (operands[0])))
11177 assemble_real (*CONST_DOUBLE_REAL_VALUE (operands[0]),
11178 GET_MODE (operands[0]), BITS_PER_WORD);
11181 assemble_integer (operands[0], 8, BITS_PER_WORD, 1);
11186 [(set_attr "length" "8")
11187 (set_attr "type" "no_insn")]
11190 (define_insn "consttable_16"
11191 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_16)]
11195 making_const_table = TRUE;
11196 switch (GET_MODE_CLASS (GET_MODE (operands[0])))
11199 assemble_real (*CONST_DOUBLE_REAL_VALUE (operands[0]),
11200 GET_MODE (operands[0]), BITS_PER_WORD);
11203 assemble_integer (operands[0], 16, BITS_PER_WORD, 1);
11208 [(set_attr "length" "16")
11209 (set_attr "type" "no_insn")]
11212 ;; V5 Instructions,
11214 (define_insn "clzsi2"
11215 [(set (match_operand:SI 0 "s_register_operand" "=r")
11216 (clz:SI (match_operand:SI 1 "s_register_operand" "r")))]
11217 "TARGET_32BIT && arm_arch5"
11219 [(set_attr "predicable" "yes")
11220 (set_attr "predicable_short_it" "no")
11221 (set_attr "type" "clz")])
11223 (define_insn "rbitsi2"
11224 [(set (match_operand:SI 0 "s_register_operand" "=r")
11225 (unspec:SI [(match_operand:SI 1 "s_register_operand" "r")] UNSPEC_RBIT))]
11226 "TARGET_32BIT && arm_arch_thumb2"
11228 [(set_attr "predicable" "yes")
11229 (set_attr "predicable_short_it" "no")
11230 (set_attr "type" "clz")])
11232 ;; Keep this as a CTZ expression until after reload and then split
11233 ;; into RBIT + CLZ. Since RBIT is represented as an UNSPEC it is unlikely
11234 ;; to fold with any other expression.
11236 (define_insn_and_split "ctzsi2"
11237 [(set (match_operand:SI 0 "s_register_operand" "=r")
11238 (ctz:SI (match_operand:SI 1 "s_register_operand" "r")))]
11239 "TARGET_32BIT && arm_arch_thumb2"
11241 "&& reload_completed"
11244 emit_insn (gen_rbitsi2 (operands[0], operands[1]));
11245 emit_insn (gen_clzsi2 (operands[0], operands[0]));
11249 ;; V5E instructions.
11251 (define_insn "prefetch"
11252 [(prefetch (match_operand:SI 0 "address_operand" "p")
11253 (match_operand:SI 1 "" "")
11254 (match_operand:SI 2 "" ""))]
11255 "TARGET_32BIT && arm_arch5e"
11257 [(set_attr "type" "load1")]
11260 ;; General predication pattern
11263 [(match_operator 0 "arm_comparison_operator"
11264 [(match_operand 1 "cc_register" "")
11267 && (!TARGET_NO_VOLATILE_CE || !volatile_refs_p (PATTERN (insn)))"
11269 [(set_attr "predicated" "yes")]
11272 (define_insn "force_register_use"
11273 [(unspec:SI [(match_operand:SI 0 "register_operand" "")] UNSPEC_REGISTER_USE)]
11276 [(set_attr "length" "0")
11277 (set_attr "type" "no_insn")]
11281 ;; Patterns for exception handling
11283 (define_expand "eh_return"
11284 [(use (match_operand 0 "general_operand" ""))]
11289 emit_insn (gen_arm_eh_return (operands[0]));
11291 emit_insn (gen_thumb_eh_return (operands[0]));
11296 ;; We can't expand this before we know where the link register is stored.
11297 (define_insn_and_split "arm_eh_return"
11298 [(unspec_volatile [(match_operand:SI 0 "s_register_operand" "r")]
11300 (clobber (match_scratch:SI 1 "=&r"))]
11303 "&& reload_completed"
11307 arm_set_return_address (operands[0], operands[1]);
11315 (define_insn "load_tp_hard"
11316 [(set (match_operand:SI 0 "register_operand" "=r")
11317 (unspec:SI [(const_int 0)] UNSPEC_TLS))]
11319 "mrc%?\\tp15, 0, %0, c13, c0, 3\\t@ load_tp_hard"
11320 [(set_attr "predicable" "yes")
11321 (set_attr "type" "mrs")]
11324 ;; Doesn't clobber R1-R3. Must use r0 for the first operand.
11325 (define_insn "load_tp_soft"
11326 [(set (reg:SI 0) (unspec:SI [(const_int 0)] UNSPEC_TLS))
11327 (clobber (reg:SI LR_REGNUM))
11328 (clobber (reg:SI IP_REGNUM))
11329 (clobber (reg:CC CC_REGNUM))]
11331 "bl\\t__aeabi_read_tp\\t@ load_tp_soft"
11332 [(set_attr "conds" "clob")
11333 (set_attr "type" "branch")]
11336 ;; tls descriptor call
11337 (define_insn "tlscall"
11338 [(set (reg:SI R0_REGNUM)
11339 (unspec:SI [(reg:SI R0_REGNUM)
11340 (match_operand:SI 0 "" "X")
11341 (match_operand 1 "" "")] UNSPEC_TLS))
11342 (clobber (reg:SI R1_REGNUM))
11343 (clobber (reg:SI LR_REGNUM))
11344 (clobber (reg:SI CC_REGNUM))]
11347 targetm.asm_out.internal_label (asm_out_file, "LPIC",
11348 INTVAL (operands[1]));
11349 return "bl\\t%c0(tlscall)";
11351 [(set_attr "conds" "clob")
11352 (set_attr "length" "4")
11353 (set_attr "type" "branch")]
11356 ;; For thread pointer builtin
11357 (define_expand "get_thread_pointersi"
11358 [(match_operand:SI 0 "s_register_operand" "=r")]
11362 arm_load_tp (operands[0]);
11368 ;; We only care about the lower 16 bits of the constant
11369 ;; being inserted into the upper 16 bits of the register.
11370 (define_insn "*arm_movtas_ze"
11371 [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r,r")
11374 (match_operand:SI 1 "const_int_operand" ""))]
11379 [(set_attr "arch" "32,v8mb")
11380 (set_attr "predicable" "yes")
11381 (set_attr "predicable_short_it" "no")
11382 (set_attr "length" "4")
11383 (set_attr "type" "alu_sreg")]
11386 (define_insn "*arm_rev"
11387 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r")
11388 (bswap:SI (match_operand:SI 1 "s_register_operand" "l,l,r")))]
11394 [(set_attr "arch" "t1,t2,32")
11395 (set_attr "length" "2,2,4")
11396 (set_attr "predicable" "no,yes,yes")
11397 (set_attr "predicable_short_it" "no")
11398 (set_attr "type" "rev")]
11401 (define_expand "arm_legacy_rev"
11402 [(set (match_operand:SI 2 "s_register_operand" "")
11403 (xor:SI (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
11407 (lshiftrt:SI (match_dup 2)
11409 (set (match_operand:SI 3 "s_register_operand" "")
11410 (rotatert:SI (match_dup 1)
11413 (and:SI (match_dup 2)
11414 (const_int -65281)))
11415 (set (match_operand:SI 0 "s_register_operand" "")
11416 (xor:SI (match_dup 3)
11422 ;; Reuse temporaries to keep register pressure down.
11423 (define_expand "thumb_legacy_rev"
11424 [(set (match_operand:SI 2 "s_register_operand" "")
11425 (ashift:SI (match_operand:SI 1 "s_register_operand" "")
11427 (set (match_operand:SI 3 "s_register_operand" "")
11428 (lshiftrt:SI (match_dup 1)
11431 (ior:SI (match_dup 3)
11433 (set (match_operand:SI 4 "s_register_operand" "")
11435 (set (match_operand:SI 5 "s_register_operand" "")
11436 (rotatert:SI (match_dup 1)
11439 (ashift:SI (match_dup 5)
11442 (lshiftrt:SI (match_dup 5)
11445 (ior:SI (match_dup 5)
11448 (rotatert:SI (match_dup 5)
11450 (set (match_operand:SI 0 "s_register_operand" "")
11451 (ior:SI (match_dup 5)
11457 ;; ARM-specific expansion of signed mod by power of 2
11458 ;; using conditional negate.
11459 ;; For r0 % n where n is a power of 2 produce:
11461 ;; and r0, r0, #(n - 1)
11462 ;; and r1, r1, #(n - 1)
11463 ;; rsbpl r0, r1, #0
11465 (define_expand "modsi3"
11466 [(match_operand:SI 0 "register_operand" "")
11467 (match_operand:SI 1 "register_operand" "")
11468 (match_operand:SI 2 "const_int_operand" "")]
11471 HOST_WIDE_INT val = INTVAL (operands[2]);
11474 || exact_log2 (val) <= 0)
11477 rtx mask = GEN_INT (val - 1);
11479 /* In the special case of x0 % 2 we can do the even shorter:
11482 rsblt r0, r0, #0. */
11486 rtx cc_reg = arm_gen_compare_reg (LT,
11487 operands[1], const0_rtx, NULL_RTX);
11488 rtx cond = gen_rtx_LT (SImode, cc_reg, const0_rtx);
11489 rtx masked = gen_reg_rtx (SImode);
11491 emit_insn (gen_andsi3 (masked, operands[1], mask));
11492 emit_move_insn (operands[0],
11493 gen_rtx_IF_THEN_ELSE (SImode, cond,
11494 gen_rtx_NEG (SImode,
11500 rtx neg_op = gen_reg_rtx (SImode);
11501 rtx_insn *insn = emit_insn (gen_subsi3_compare0 (neg_op, const0_rtx,
11504 /* Extract the condition register and mode. */
11505 rtx cmp = XVECEXP (PATTERN (insn), 0, 0);
11506 rtx cc_reg = SET_DEST (cmp);
11507 rtx cond = gen_rtx_GE (SImode, cc_reg, const0_rtx);
11509 emit_insn (gen_andsi3 (operands[0], operands[1], mask));
11511 rtx masked_neg = gen_reg_rtx (SImode);
11512 emit_insn (gen_andsi3 (masked_neg, neg_op, mask));
11514 /* We want a conditional negate here, but emitting COND_EXEC rtxes
11515 during expand does not always work. Do an IF_THEN_ELSE instead. */
11516 emit_move_insn (operands[0],
11517 gen_rtx_IF_THEN_ELSE (SImode, cond,
11518 gen_rtx_NEG (SImode, masked_neg),
11526 (define_expand "bswapsi2"
11527 [(set (match_operand:SI 0 "s_register_operand" "=r")
11528 (bswap:SI (match_operand:SI 1 "s_register_operand" "r")))]
11529 "TARGET_EITHER && (arm_arch6 || !optimize_size)"
11533 rtx op2 = gen_reg_rtx (SImode);
11534 rtx op3 = gen_reg_rtx (SImode);
11538 rtx op4 = gen_reg_rtx (SImode);
11539 rtx op5 = gen_reg_rtx (SImode);
11541 emit_insn (gen_thumb_legacy_rev (operands[0], operands[1],
11542 op2, op3, op4, op5));
11546 emit_insn (gen_arm_legacy_rev (operands[0], operands[1],
11555 ;; bswap16 patterns: use revsh and rev16 instructions for the signed
11556 ;; and unsigned variants, respectively. For rev16, expose
11557 ;; byte-swapping in the lower 16 bits only.
11558 (define_insn "*arm_revsh"
11559 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r")
11560 (sign_extend:SI (bswap:HI (match_operand:HI 1 "s_register_operand" "l,l,r"))))]
11566 [(set_attr "arch" "t1,t2,32")
11567 (set_attr "length" "2,2,4")
11568 (set_attr "type" "rev")]
11571 (define_insn "*arm_rev16"
11572 [(set (match_operand:HI 0 "s_register_operand" "=l,l,r")
11573 (bswap:HI (match_operand:HI 1 "s_register_operand" "l,l,r")))]
11579 [(set_attr "arch" "t1,t2,32")
11580 (set_attr "length" "2,2,4")
11581 (set_attr "type" "rev")]
11584 ;; There are no canonicalisation rules for the position of the lshiftrt, ashift
11585 ;; operations within an IOR/AND RTX, therefore we have two patterns matching
11586 ;; each valid permutation.
11588 (define_insn "arm_rev16si2"
11589 [(set (match_operand:SI 0 "register_operand" "=l,l,r")
11590 (ior:SI (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "l,l,r")
11592 (match_operand:SI 3 "const_int_operand" "n,n,n"))
11593 (and:SI (lshiftrt:SI (match_dup 1)
11595 (match_operand:SI 2 "const_int_operand" "n,n,n"))))]
11597 && aarch_rev16_shleft_mask_imm_p (operands[3], SImode)
11598 && aarch_rev16_shright_mask_imm_p (operands[2], SImode)"
11600 [(set_attr "arch" "t1,t2,32")
11601 (set_attr "length" "2,2,4")
11602 (set_attr "type" "rev")]
11605 (define_insn "arm_rev16si2_alt"
11606 [(set (match_operand:SI 0 "register_operand" "=l,l,r")
11607 (ior:SI (and:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "l,l,r")
11609 (match_operand:SI 2 "const_int_operand" "n,n,n"))
11610 (and:SI (ashift:SI (match_dup 1)
11612 (match_operand:SI 3 "const_int_operand" "n,n,n"))))]
11614 && aarch_rev16_shleft_mask_imm_p (operands[3], SImode)
11615 && aarch_rev16_shright_mask_imm_p (operands[2], SImode)"
11617 [(set_attr "arch" "t1,t2,32")
11618 (set_attr "length" "2,2,4")
11619 (set_attr "type" "rev")]
11622 (define_expand "bswaphi2"
11623 [(set (match_operand:HI 0 "s_register_operand" "=r")
11624 (bswap:HI (match_operand:HI 1 "s_register_operand" "r")))]
11629 ;; Patterns for LDRD/STRD in Thumb2 mode
11631 (define_insn "*thumb2_ldrd"
11632 [(set (match_operand:SI 0 "s_register_operand" "=r")
11633 (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "rk")
11634 (match_operand:SI 2 "ldrd_strd_offset_operand" "Do"))))
11635 (set (match_operand:SI 3 "s_register_operand" "=r")
11636 (mem:SI (plus:SI (match_dup 1)
11637 (match_operand:SI 4 "const_int_operand" ""))))]
11638 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11639 && current_tune->prefer_ldrd_strd
11640 && ((INTVAL (operands[2]) + 4) == INTVAL (operands[4]))
11641 && (operands_ok_ldrd_strd (operands[0], operands[3],
11642 operands[1], INTVAL (operands[2]),
11644 "ldrd%?\t%0, %3, [%1, %2]"
11645 [(set_attr "type" "load2")
11646 (set_attr "predicable" "yes")
11647 (set_attr "predicable_short_it" "no")])
11649 (define_insn "*thumb2_ldrd_base"
11650 [(set (match_operand:SI 0 "s_register_operand" "=r")
11651 (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
11652 (set (match_operand:SI 2 "s_register_operand" "=r")
11653 (mem:SI (plus:SI (match_dup 1)
11655 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11656 && current_tune->prefer_ldrd_strd
11657 && (operands_ok_ldrd_strd (operands[0], operands[2],
11658 operands[1], 0, false, true))"
11659 "ldrd%?\t%0, %2, [%1]"
11660 [(set_attr "type" "load2")
11661 (set_attr "predicable" "yes")
11662 (set_attr "predicable_short_it" "no")])
11664 (define_insn "*thumb2_ldrd_base_neg"
11665 [(set (match_operand:SI 0 "s_register_operand" "=r")
11666 (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "rk")
11668 (set (match_operand:SI 2 "s_register_operand" "=r")
11669 (mem:SI (match_dup 1)))]
11670 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11671 && current_tune->prefer_ldrd_strd
11672 && (operands_ok_ldrd_strd (operands[0], operands[2],
11673 operands[1], -4, false, true))"
11674 "ldrd%?\t%0, %2, [%1, #-4]"
11675 [(set_attr "type" "load2")
11676 (set_attr "predicable" "yes")
11677 (set_attr "predicable_short_it" "no")])
11679 (define_insn "*thumb2_strd"
11680 [(set (mem:SI (plus:SI (match_operand:SI 0 "s_register_operand" "rk")
11681 (match_operand:SI 1 "ldrd_strd_offset_operand" "Do")))
11682 (match_operand:SI 2 "s_register_operand" "r"))
11683 (set (mem:SI (plus:SI (match_dup 0)
11684 (match_operand:SI 3 "const_int_operand" "")))
11685 (match_operand:SI 4 "s_register_operand" "r"))]
11686 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11687 && current_tune->prefer_ldrd_strd
11688 && ((INTVAL (operands[1]) + 4) == INTVAL (operands[3]))
11689 && (operands_ok_ldrd_strd (operands[2], operands[4],
11690 operands[0], INTVAL (operands[1]),
11692 "strd%?\t%2, %4, [%0, %1]"
11693 [(set_attr "type" "store2")
11694 (set_attr "predicable" "yes")
11695 (set_attr "predicable_short_it" "no")])
11697 (define_insn "*thumb2_strd_base"
11698 [(set (mem:SI (match_operand:SI 0 "s_register_operand" "rk"))
11699 (match_operand:SI 1 "s_register_operand" "r"))
11700 (set (mem:SI (plus:SI (match_dup 0)
11702 (match_operand:SI 2 "s_register_operand" "r"))]
11703 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11704 && current_tune->prefer_ldrd_strd
11705 && (operands_ok_ldrd_strd (operands[1], operands[2],
11706 operands[0], 0, false, false))"
11707 "strd%?\t%1, %2, [%0]"
11708 [(set_attr "type" "store2")
11709 (set_attr "predicable" "yes")
11710 (set_attr "predicable_short_it" "no")])
11712 (define_insn "*thumb2_strd_base_neg"
11713 [(set (mem:SI (plus:SI (match_operand:SI 0 "s_register_operand" "rk")
11715 (match_operand:SI 1 "s_register_operand" "r"))
11716 (set (mem:SI (match_dup 0))
11717 (match_operand:SI 2 "s_register_operand" "r"))]
11718 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11719 && current_tune->prefer_ldrd_strd
11720 && (operands_ok_ldrd_strd (operands[1], operands[2],
11721 operands[0], -4, false, false))"
11722 "strd%?\t%1, %2, [%0, #-4]"
11723 [(set_attr "type" "store2")
11724 (set_attr "predicable" "yes")
11725 (set_attr "predicable_short_it" "no")])
11727 ;; ARMv8 CRC32 instructions.
11728 (define_insn "<crc_variant>"
11729 [(set (match_operand:SI 0 "s_register_operand" "=r")
11730 (unspec:SI [(match_operand:SI 1 "s_register_operand" "r")
11731 (match_operand:<crc_mode> 2 "s_register_operand" "r")]
11734 "<crc_variant>\\t%0, %1, %2"
11735 [(set_attr "type" "crc")
11736 (set_attr "conds" "unconditional")]
11739 ;; Load the load/store double peephole optimizations.
11740 (include "ldrdstrd.md")
11742 ;; Load the load/store multiple patterns
11743 (include "ldmstm.md")
11745 ;; Patterns in ldmstm.md don't cover more than 4 registers. This pattern covers
11746 ;; large lists without explicit writeback generated for APCS_FRAME epilogue.
11747 (define_insn "*load_multiple"
11748 [(match_parallel 0 "load_multiple_operation"
11749 [(set (match_operand:SI 2 "s_register_operand" "=rk")
11750 (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
11755 arm_output_multireg_pop (operands, /*return_pc=*/false,
11756 /*cond=*/const_true_rtx,
11762 [(set_attr "predicable" "yes")]
11765 (define_expand "copysignsf3"
11766 [(match_operand:SF 0 "register_operand")
11767 (match_operand:SF 1 "register_operand")
11768 (match_operand:SF 2 "register_operand")]
11769 "TARGET_SOFT_FLOAT && arm_arch_thumb2"
11771 emit_move_insn (operands[0], operands[2]);
11772 emit_insn (gen_insv_t2 (simplify_gen_subreg (SImode, operands[0], SFmode, 0),
11773 GEN_INT (31), GEN_INT (0),
11774 simplify_gen_subreg (SImode, operands[1], SFmode, 0)));
11779 (define_expand "copysigndf3"
11780 [(match_operand:DF 0 "register_operand")
11781 (match_operand:DF 1 "register_operand")
11782 (match_operand:DF 2 "register_operand")]
11783 "TARGET_SOFT_FLOAT && arm_arch_thumb2"
11785 rtx op0_low = gen_lowpart (SImode, operands[0]);
11786 rtx op0_high = gen_highpart (SImode, operands[0]);
11787 rtx op1_low = gen_lowpart (SImode, operands[1]);
11788 rtx op1_high = gen_highpart (SImode, operands[1]);
11789 rtx op2_high = gen_highpart (SImode, operands[2]);
11791 rtx scratch1 = gen_reg_rtx (SImode);
11792 rtx scratch2 = gen_reg_rtx (SImode);
11793 emit_move_insn (scratch1, op2_high);
11794 emit_move_insn (scratch2, op1_high);
11796 emit_insn(gen_rtx_SET(scratch1,
11797 gen_rtx_LSHIFTRT (SImode, op2_high, GEN_INT(31))));
11798 emit_insn(gen_insv_t2(scratch2, GEN_INT(1), GEN_INT(31), scratch1));
11799 emit_move_insn (op0_low, op1_low);
11800 emit_move_insn (op0_high, scratch2);
11806 ;; movmisalign patterns for HImode and SImode.
11807 (define_expand "movmisalign<mode>"
11808 [(match_operand:HSI 0 "general_operand")
11809 (match_operand:HSI 1 "general_operand")]
11812 /* This pattern is not permitted to fail during expansion: if both arguments
11813 are non-registers (e.g. memory := constant), force operand 1 into a
11815 rtx (* gen_unaligned_load)(rtx, rtx);
11816 rtx tmp_dest = operands[0];
11817 if (!s_register_operand (operands[0], <MODE>mode)
11818 && !s_register_operand (operands[1], <MODE>mode))
11819 operands[1] = force_reg (<MODE>mode, operands[1]);
11821 if (<MODE>mode == HImode)
11823 gen_unaligned_load = gen_unaligned_loadhiu;
11824 tmp_dest = gen_reg_rtx (SImode);
11827 gen_unaligned_load = gen_unaligned_loadsi;
11829 if (MEM_P (operands[1]))
11831 emit_insn (gen_unaligned_load (tmp_dest, operands[1]));
11832 if (<MODE>mode == HImode)
11833 emit_move_insn (operands[0], gen_lowpart (HImode, tmp_dest));
11836 emit_insn (gen_unaligned_store<mode> (operands[0], operands[1]));
11841 ;; Vector bits common to IWMMXT and Neon
11842 (include "vec-common.md")
11843 ;; Load the Intel Wireless Multimedia Extension patterns
11844 (include "iwmmxt.md")
11845 ;; Load the VFP co-processor patterns
11847 ;; Thumb-1 patterns
11848 (include "thumb1.md")
11849 ;; Thumb-2 patterns
11850 (include "thumb2.md")
11852 (include "neon.md")
11854 (include "crypto.md")
11855 ;; Synchronization Primitives
11856 (include "sync.md")
11857 ;; Fixed-point patterns
11858 (include "arm-fixed.md")