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 && TARGET_VFP"
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 /* If we're optimizing for size, we prefer the libgcc calls. */
4020 if (optimize_function_for_size_p (cfun))
4023 /* Expand operation using core-registers.
4024 'FAIL' would achieve the same thing, but this is a bit smarter. */
4025 scratch1 = gen_reg_rtx (SImode);
4026 scratch2 = gen_reg_rtx (SImode);
4027 arm_emit_coreregs_64bit_shift (ASHIFT, operands[0], operands[1],
4028 operands[2], scratch1, scratch2);
4034 (define_insn "arm_ashldi3_1bit"
4035 [(set (match_operand:DI 0 "s_register_operand" "=r,&r")
4036 (ashift:DI (match_operand:DI 1 "s_register_operand" "0,r")
4038 (clobber (reg:CC CC_REGNUM))]
4040 "movs\\t%Q0, %Q1, asl #1\;adc\\t%R0, %R1, %R1"
4041 [(set_attr "conds" "clob")
4042 (set_attr "length" "8")
4043 (set_attr "type" "multiple")]
4046 (define_expand "ashlsi3"
4047 [(set (match_operand:SI 0 "s_register_operand" "")
4048 (ashift:SI (match_operand:SI 1 "s_register_operand" "")
4049 (match_operand:SI 2 "arm_rhs_operand" "")))]
4052 if (CONST_INT_P (operands[2])
4053 && (UINTVAL (operands[2])) > 31)
4055 emit_insn (gen_movsi (operands[0], const0_rtx));
4061 (define_expand "ashrdi3"
4062 [(set (match_operand:DI 0 "s_register_operand" "")
4063 (ashiftrt:DI (match_operand:DI 1 "s_register_operand" "")
4064 (match_operand:SI 2 "reg_or_int_operand" "")))]
4069 /* Delay the decision whether to use NEON or core-regs until
4070 register allocation. */
4071 emit_insn (gen_ashrdi3_neon (operands[0], operands[1], operands[2]));
4075 if (!CONST_INT_P (operands[2]) && TARGET_REALLY_IWMMXT)
4076 ; /* No special preparation statements; expand pattern as above. */
4079 rtx scratch1, scratch2;
4081 if (operands[2] == CONST1_RTX (SImode))
4083 emit_insn (gen_arm_ashrdi3_1bit (operands[0], operands[1]));
4087 /* Ideally we should use iwmmxt here if we could know that operands[1]
4088 ends up already living in an iwmmxt register. Otherwise it's
4089 cheaper to have the alternate code being generated than moving
4090 values to iwmmxt regs and back. */
4092 /* If we're optimizing for size, we prefer the libgcc calls. */
4093 if (optimize_function_for_size_p (cfun))
4096 /* Expand operation using core-registers.
4097 'FAIL' would achieve the same thing, but this is a bit smarter. */
4098 scratch1 = gen_reg_rtx (SImode);
4099 scratch2 = gen_reg_rtx (SImode);
4100 arm_emit_coreregs_64bit_shift (ASHIFTRT, operands[0], operands[1],
4101 operands[2], scratch1, scratch2);
4107 (define_insn "arm_ashrdi3_1bit"
4108 [(set (match_operand:DI 0 "s_register_operand" "=r,&r")
4109 (ashiftrt:DI (match_operand:DI 1 "s_register_operand" "0,r")
4111 (clobber (reg:CC CC_REGNUM))]
4113 "movs\\t%R0, %R1, asr #1\;mov\\t%Q0, %Q1, rrx"
4114 [(set_attr "conds" "clob")
4115 (set_attr "length" "8")
4116 (set_attr "type" "multiple")]
4119 (define_expand "ashrsi3"
4120 [(set (match_operand:SI 0 "s_register_operand" "")
4121 (ashiftrt:SI (match_operand:SI 1 "s_register_operand" "")
4122 (match_operand:SI 2 "arm_rhs_operand" "")))]
4125 if (CONST_INT_P (operands[2])
4126 && UINTVAL (operands[2]) > 31)
4127 operands[2] = GEN_INT (31);
4131 (define_expand "lshrdi3"
4132 [(set (match_operand:DI 0 "s_register_operand" "")
4133 (lshiftrt:DI (match_operand:DI 1 "s_register_operand" "")
4134 (match_operand:SI 2 "reg_or_int_operand" "")))]
4139 /* Delay the decision whether to use NEON or core-regs until
4140 register allocation. */
4141 emit_insn (gen_lshrdi3_neon (operands[0], operands[1], operands[2]));
4145 if (!CONST_INT_P (operands[2]) && TARGET_REALLY_IWMMXT)
4146 ; /* No special preparation statements; expand pattern as above. */
4149 rtx scratch1, scratch2;
4151 if (operands[2] == CONST1_RTX (SImode))
4153 emit_insn (gen_arm_lshrdi3_1bit (operands[0], operands[1]));
4157 /* Ideally we should use iwmmxt here if we could know that operands[1]
4158 ends up already living in an iwmmxt register. Otherwise it's
4159 cheaper to have the alternate code being generated than moving
4160 values to iwmmxt regs and back. */
4162 /* If we're optimizing for size, we prefer the libgcc calls. */
4163 if (optimize_function_for_size_p (cfun))
4166 /* Expand operation using core-registers.
4167 'FAIL' would achieve the same thing, but this is a bit smarter. */
4168 scratch1 = gen_reg_rtx (SImode);
4169 scratch2 = gen_reg_rtx (SImode);
4170 arm_emit_coreregs_64bit_shift (LSHIFTRT, operands[0], operands[1],
4171 operands[2], scratch1, scratch2);
4177 (define_insn "arm_lshrdi3_1bit"
4178 [(set (match_operand:DI 0 "s_register_operand" "=r,&r")
4179 (lshiftrt:DI (match_operand:DI 1 "s_register_operand" "0,r")
4181 (clobber (reg:CC CC_REGNUM))]
4183 "movs\\t%R0, %R1, lsr #1\;mov\\t%Q0, %Q1, rrx"
4184 [(set_attr "conds" "clob")
4185 (set_attr "length" "8")
4186 (set_attr "type" "multiple")]
4189 (define_expand "lshrsi3"
4190 [(set (match_operand:SI 0 "s_register_operand" "")
4191 (lshiftrt:SI (match_operand:SI 1 "s_register_operand" "")
4192 (match_operand:SI 2 "arm_rhs_operand" "")))]
4195 if (CONST_INT_P (operands[2])
4196 && (UINTVAL (operands[2])) > 31)
4198 emit_insn (gen_movsi (operands[0], const0_rtx));
4204 (define_expand "rotlsi3"
4205 [(set (match_operand:SI 0 "s_register_operand" "")
4206 (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
4207 (match_operand:SI 2 "reg_or_int_operand" "")))]
4210 if (CONST_INT_P (operands[2]))
4211 operands[2] = GEN_INT ((32 - INTVAL (operands[2])) % 32);
4214 rtx reg = gen_reg_rtx (SImode);
4215 emit_insn (gen_subsi3 (reg, GEN_INT (32), operands[2]));
4221 (define_expand "rotrsi3"
4222 [(set (match_operand:SI 0 "s_register_operand" "")
4223 (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
4224 (match_operand:SI 2 "arm_rhs_operand" "")))]
4229 if (CONST_INT_P (operands[2])
4230 && UINTVAL (operands[2]) > 31)
4231 operands[2] = GEN_INT (INTVAL (operands[2]) % 32);
4233 else /* TARGET_THUMB1 */
4235 if (CONST_INT_P (operands [2]))
4236 operands [2] = force_reg (SImode, operands[2]);
4241 (define_insn "*arm_shiftsi3"
4242 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r,r")
4243 (match_operator:SI 3 "shift_operator"
4244 [(match_operand:SI 1 "s_register_operand" "0,l,r,r")
4245 (match_operand:SI 2 "reg_or_int_operand" "l,M,M,r")]))]
4247 "* return arm_output_shift(operands, 0);"
4248 [(set_attr "predicable" "yes")
4249 (set_attr "arch" "t2,t2,*,*")
4250 (set_attr "predicable_short_it" "yes,yes,no,no")
4251 (set_attr "length" "4")
4252 (set_attr "shift" "1")
4253 (set_attr "type" "alu_shift_reg,alu_shift_imm,alu_shift_imm,alu_shift_reg")]
4256 (define_insn "*shiftsi3_compare0"
4257 [(set (reg:CC_NOOV CC_REGNUM)
4258 (compare:CC_NOOV (match_operator:SI 3 "shift_operator"
4259 [(match_operand:SI 1 "s_register_operand" "r,r")
4260 (match_operand:SI 2 "arm_rhs_operand" "M,r")])
4262 (set (match_operand:SI 0 "s_register_operand" "=r,r")
4263 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))]
4265 "* return arm_output_shift(operands, 1);"
4266 [(set_attr "conds" "set")
4267 (set_attr "shift" "1")
4268 (set_attr "type" "alus_shift_imm,alus_shift_reg")]
4271 (define_insn "*shiftsi3_compare0_scratch"
4272 [(set (reg:CC_NOOV CC_REGNUM)
4273 (compare:CC_NOOV (match_operator:SI 3 "shift_operator"
4274 [(match_operand:SI 1 "s_register_operand" "r,r")
4275 (match_operand:SI 2 "arm_rhs_operand" "M,r")])
4277 (clobber (match_scratch:SI 0 "=r,r"))]
4279 "* return arm_output_shift(operands, 1);"
4280 [(set_attr "conds" "set")
4281 (set_attr "shift" "1")
4282 (set_attr "type" "shift_imm,shift_reg")]
4285 (define_insn "*not_shiftsi"
4286 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4287 (not:SI (match_operator:SI 3 "shift_operator"
4288 [(match_operand:SI 1 "s_register_operand" "r,r")
4289 (match_operand:SI 2 "shift_amount_operand" "M,rM")])))]
4292 [(set_attr "predicable" "yes")
4293 (set_attr "predicable_short_it" "no")
4294 (set_attr "shift" "1")
4295 (set_attr "arch" "32,a")
4296 (set_attr "type" "mvn_shift,mvn_shift_reg")])
4298 (define_insn "*not_shiftsi_compare0"
4299 [(set (reg:CC_NOOV CC_REGNUM)
4301 (not:SI (match_operator:SI 3 "shift_operator"
4302 [(match_operand:SI 1 "s_register_operand" "r,r")
4303 (match_operand:SI 2 "shift_amount_operand" "M,rM")]))
4305 (set (match_operand:SI 0 "s_register_operand" "=r,r")
4306 (not:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])))]
4308 "mvns%?\\t%0, %1%S3"
4309 [(set_attr "conds" "set")
4310 (set_attr "shift" "1")
4311 (set_attr "arch" "32,a")
4312 (set_attr "type" "mvn_shift,mvn_shift_reg")])
4314 (define_insn "*not_shiftsi_compare0_scratch"
4315 [(set (reg:CC_NOOV CC_REGNUM)
4317 (not:SI (match_operator:SI 3 "shift_operator"
4318 [(match_operand:SI 1 "s_register_operand" "r,r")
4319 (match_operand:SI 2 "shift_amount_operand" "M,rM")]))
4321 (clobber (match_scratch:SI 0 "=r,r"))]
4323 "mvns%?\\t%0, %1%S3"
4324 [(set_attr "conds" "set")
4325 (set_attr "shift" "1")
4326 (set_attr "arch" "32,a")
4327 (set_attr "type" "mvn_shift,mvn_shift_reg")])
4329 ;; We don't really have extzv, but defining this using shifts helps
4330 ;; to reduce register pressure later on.
4332 (define_expand "extzv"
4333 [(set (match_operand 0 "s_register_operand" "")
4334 (zero_extract (match_operand 1 "nonimmediate_operand" "")
4335 (match_operand 2 "const_int_operand" "")
4336 (match_operand 3 "const_int_operand" "")))]
4337 "TARGET_THUMB1 || arm_arch_thumb2"
4340 HOST_WIDE_INT lshift = 32 - INTVAL (operands[2]) - INTVAL (operands[3]);
4341 HOST_WIDE_INT rshift = 32 - INTVAL (operands[2]);
4343 if (arm_arch_thumb2)
4345 HOST_WIDE_INT width = INTVAL (operands[2]);
4346 HOST_WIDE_INT bitpos = INTVAL (operands[3]);
4348 if (unaligned_access && MEM_P (operands[1])
4349 && (width == 16 || width == 32) && (bitpos % BITS_PER_UNIT) == 0)
4353 if (BYTES_BIG_ENDIAN)
4354 bitpos = GET_MODE_BITSIZE (GET_MODE (operands[0])) - width
4359 base_addr = adjust_address (operands[1], SImode,
4360 bitpos / BITS_PER_UNIT);
4361 emit_insn (gen_unaligned_loadsi (operands[0], base_addr));
4365 rtx dest = operands[0];
4366 rtx tmp = gen_reg_rtx (SImode);
4368 /* We may get a paradoxical subreg here. Strip it off. */
4369 if (GET_CODE (dest) == SUBREG
4370 && GET_MODE (dest) == SImode
4371 && GET_MODE (SUBREG_REG (dest)) == HImode)
4372 dest = SUBREG_REG (dest);
4374 if (GET_MODE_BITSIZE (GET_MODE (dest)) != width)
4377 base_addr = adjust_address (operands[1], HImode,
4378 bitpos / BITS_PER_UNIT);
4379 emit_insn (gen_unaligned_loadhiu (tmp, base_addr));
4380 emit_move_insn (gen_lowpart (SImode, dest), tmp);
4384 else if (s_register_operand (operands[1], GET_MODE (operands[1])))
4386 emit_insn (gen_extzv_t2 (operands[0], operands[1], operands[2],
4394 if (!s_register_operand (operands[1], GET_MODE (operands[1])))
4397 operands[3] = GEN_INT (rshift);
4401 emit_insn (gen_lshrsi3 (operands[0], operands[1], operands[3]));
4405 emit_insn (gen_extzv_t1 (operands[0], operands[1], GEN_INT (lshift),
4406 operands[3], gen_reg_rtx (SImode)));
4411 ;; Helper for extzv, for the Thumb-1 register-shifts case.
4413 (define_expand "extzv_t1"
4414 [(set (match_operand:SI 4 "s_register_operand" "")
4415 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
4416 (match_operand:SI 2 "const_int_operand" "")))
4417 (set (match_operand:SI 0 "s_register_operand" "")
4418 (lshiftrt:SI (match_dup 4)
4419 (match_operand:SI 3 "const_int_operand" "")))]
4423 (define_expand "extv"
4424 [(set (match_operand 0 "s_register_operand" "")
4425 (sign_extract (match_operand 1 "nonimmediate_operand" "")
4426 (match_operand 2 "const_int_operand" "")
4427 (match_operand 3 "const_int_operand" "")))]
4430 HOST_WIDE_INT width = INTVAL (operands[2]);
4431 HOST_WIDE_INT bitpos = INTVAL (operands[3]);
4433 if (unaligned_access && MEM_P (operands[1]) && (width == 16 || width == 32)
4434 && (bitpos % BITS_PER_UNIT) == 0)
4438 if (BYTES_BIG_ENDIAN)
4439 bitpos = GET_MODE_BITSIZE (GET_MODE (operands[0])) - width - bitpos;
4443 base_addr = adjust_address (operands[1], SImode,
4444 bitpos / BITS_PER_UNIT);
4445 emit_insn (gen_unaligned_loadsi (operands[0], base_addr));
4449 rtx dest = operands[0];
4450 rtx tmp = gen_reg_rtx (SImode);
4452 /* We may get a paradoxical subreg here. Strip it off. */
4453 if (GET_CODE (dest) == SUBREG
4454 && GET_MODE (dest) == SImode
4455 && GET_MODE (SUBREG_REG (dest)) == HImode)
4456 dest = SUBREG_REG (dest);
4458 if (GET_MODE_BITSIZE (GET_MODE (dest)) != width)
4461 base_addr = adjust_address (operands[1], HImode,
4462 bitpos / BITS_PER_UNIT);
4463 emit_insn (gen_unaligned_loadhis (tmp, base_addr));
4464 emit_move_insn (gen_lowpart (SImode, dest), tmp);
4469 else if (!s_register_operand (operands[1], GET_MODE (operands[1])))
4471 else if (GET_MODE (operands[0]) == SImode
4472 && GET_MODE (operands[1]) == SImode)
4474 emit_insn (gen_extv_regsi (operands[0], operands[1], operands[2],
4482 ; Helper to expand register forms of extv with the proper modes.
4484 (define_expand "extv_regsi"
4485 [(set (match_operand:SI 0 "s_register_operand" "")
4486 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "")
4487 (match_operand 2 "const_int_operand" "")
4488 (match_operand 3 "const_int_operand" "")))]
4493 ; ARMv6+ unaligned load/store instructions (used for packed structure accesses).
4495 (define_insn "unaligned_loadsi"
4496 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4497 (unspec:SI [(match_operand:SI 1 "memory_operand" "Uw,m")]
4498 UNSPEC_UNALIGNED_LOAD))]
4500 "ldr%?\t%0, %1\t@ unaligned"
4501 [(set_attr "arch" "t2,any")
4502 (set_attr "length" "2,4")
4503 (set_attr "predicable" "yes")
4504 (set_attr "predicable_short_it" "yes,no")
4505 (set_attr "type" "load1")])
4507 (define_insn "unaligned_loadhis"
4508 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4510 (unspec:HI [(match_operand:HI 1 "memory_operand" "Uw,Uh")]
4511 UNSPEC_UNALIGNED_LOAD)))]
4513 "ldrsh%?\t%0, %1\t@ unaligned"
4514 [(set_attr "arch" "t2,any")
4515 (set_attr "length" "2,4")
4516 (set_attr "predicable" "yes")
4517 (set_attr "predicable_short_it" "yes,no")
4518 (set_attr "type" "load_byte")])
4520 (define_insn "unaligned_loadhiu"
4521 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4523 (unspec:HI [(match_operand:HI 1 "memory_operand" "Uw,m")]
4524 UNSPEC_UNALIGNED_LOAD)))]
4526 "ldrh%?\t%0, %1\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" "load_byte")])
4533 (define_insn "unaligned_storesi"
4534 [(set (match_operand:SI 0 "memory_operand" "=Uw,m")
4535 (unspec:SI [(match_operand:SI 1 "s_register_operand" "l,r")]
4536 UNSPEC_UNALIGNED_STORE))]
4538 "str%?\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")])
4545 (define_insn "unaligned_storehi"
4546 [(set (match_operand:HI 0 "memory_operand" "=Uw,m")
4547 (unspec:HI [(match_operand:HI 1 "s_register_operand" "l,r")]
4548 UNSPEC_UNALIGNED_STORE))]
4550 "strh%?\t%1, %0\t@ unaligned"
4551 [(set_attr "arch" "t2,any")
4552 (set_attr "length" "2,4")
4553 (set_attr "predicable" "yes")
4554 (set_attr "predicable_short_it" "yes,no")
4555 (set_attr "type" "store1")])
4558 (define_insn "*extv_reg"
4559 [(set (match_operand:SI 0 "s_register_operand" "=r")
4560 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
4561 (match_operand:SI 2 "const_int_M_operand" "M")
4562 (match_operand:SI 3 "const_int_M_operand" "M")))]
4564 "sbfx%?\t%0, %1, %3, %2"
4565 [(set_attr "length" "4")
4566 (set_attr "predicable" "yes")
4567 (set_attr "predicable_short_it" "no")
4568 (set_attr "type" "bfm")]
4571 (define_insn "extzv_t2"
4572 [(set (match_operand:SI 0 "s_register_operand" "=r")
4573 (zero_extract:SI (match_operand:SI 1 "s_register_operand" "r")
4574 (match_operand:SI 2 "const_int_M_operand" "M")
4575 (match_operand:SI 3 "const_int_M_operand" "M")))]
4577 "ubfx%?\t%0, %1, %3, %2"
4578 [(set_attr "length" "4")
4579 (set_attr "predicable" "yes")
4580 (set_attr "predicable_short_it" "no")
4581 (set_attr "type" "bfm")]
4585 ;; Division instructions
4586 (define_insn "divsi3"
4587 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4588 (div:SI (match_operand:SI 1 "s_register_operand" "r,r")
4589 (match_operand:SI 2 "s_register_operand" "r,r")))]
4594 [(set_attr "arch" "32,v8mb")
4595 (set_attr "predicable" "yes")
4596 (set_attr "predicable_short_it" "no")
4597 (set_attr "type" "sdiv")]
4600 (define_insn "udivsi3"
4601 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4602 (udiv:SI (match_operand:SI 1 "s_register_operand" "r,r")
4603 (match_operand:SI 2 "s_register_operand" "r,r")))]
4608 [(set_attr "arch" "32,v8mb")
4609 (set_attr "predicable" "yes")
4610 (set_attr "predicable_short_it" "no")
4611 (set_attr "type" "udiv")]
4615 ;; Unary arithmetic insns
4617 (define_expand "negvsi3"
4618 [(match_operand:SI 0 "register_operand")
4619 (match_operand:SI 1 "register_operand")
4620 (match_operand 2 "")]
4623 emit_insn (gen_subsi3_compare (operands[0], const0_rtx, operands[1]));
4624 arm_gen_unlikely_cbranch (NE, CC_Vmode, operands[2]);
4629 (define_expand "negvdi3"
4630 [(match_operand:DI 0 "register_operand")
4631 (match_operand:DI 1 "register_operand")
4632 (match_operand 2 "")]
4635 emit_insn (gen_negdi2_compare (operands[0], operands[1]));
4636 arm_gen_unlikely_cbranch (NE, CC_Vmode, operands[2]);
4642 (define_insn_and_split "negdi2_compare"
4643 [(set (reg:CC CC_REGNUM)
4646 (match_operand:DI 1 "register_operand" "0,r")))
4647 (set (match_operand:DI 0 "register_operand" "=r,&r")
4648 (minus:DI (const_int 0) (match_dup 1)))]
4651 "&& reload_completed"
4652 [(parallel [(set (reg:CC CC_REGNUM)
4653 (compare:CC (const_int 0) (match_dup 1)))
4654 (set (match_dup 0) (minus:SI (const_int 0)
4656 (parallel [(set (reg:CC CC_REGNUM)
4657 (compare:CC (const_int 0) (match_dup 3)))
4660 (minus:SI (const_int 0) (match_dup 3))
4661 (ltu:SI (reg:CC_C CC_REGNUM)
4664 operands[2] = gen_highpart (SImode, operands[0]);
4665 operands[0] = gen_lowpart (SImode, operands[0]);
4666 operands[3] = gen_highpart (SImode, operands[1]);
4667 operands[1] = gen_lowpart (SImode, operands[1]);
4669 [(set_attr "conds" "set")
4670 (set_attr "length" "8")
4671 (set_attr "type" "multiple")]
4674 (define_expand "negdi2"
4676 [(set (match_operand:DI 0 "s_register_operand" "")
4677 (neg:DI (match_operand:DI 1 "s_register_operand" "")))
4678 (clobber (reg:CC CC_REGNUM))])]
4683 emit_insn (gen_negdi2_neon (operands[0], operands[1]));
4689 ;; The constraints here are to prevent a *partial* overlap (where %Q0 == %R1).
4690 ;; The first alternative allows the common case of a *full* overlap.
4691 (define_insn_and_split "*arm_negdi2"
4692 [(set (match_operand:DI 0 "s_register_operand" "=r,&r")
4693 (neg:DI (match_operand:DI 1 "s_register_operand" "0,r")))
4694 (clobber (reg:CC CC_REGNUM))]
4696 "#" ; "rsbs\\t%Q0, %Q1, #0\;rsc\\t%R0, %R1, #0"
4697 "&& reload_completed"
4698 [(parallel [(set (reg:CC CC_REGNUM)
4699 (compare:CC (const_int 0) (match_dup 1)))
4700 (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1)))])
4701 (set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3))
4702 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
4704 operands[2] = gen_highpart (SImode, operands[0]);
4705 operands[0] = gen_lowpart (SImode, operands[0]);
4706 operands[3] = gen_highpart (SImode, operands[1]);
4707 operands[1] = gen_lowpart (SImode, operands[1]);
4709 [(set_attr "conds" "clob")
4710 (set_attr "length" "8")
4711 (set_attr "type" "multiple")]
4714 (define_insn "*negsi2_carryin_compare"
4715 [(set (reg:CC CC_REGNUM)
4716 (compare:CC (const_int 0)
4717 (match_operand:SI 1 "s_register_operand" "r")))
4718 (set (match_operand:SI 0 "s_register_operand" "=r")
4719 (minus:SI (minus:SI (const_int 0)
4721 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
4724 [(set_attr "conds" "set")
4725 (set_attr "type" "alus_imm")]
4728 (define_expand "negsi2"
4729 [(set (match_operand:SI 0 "s_register_operand" "")
4730 (neg:SI (match_operand:SI 1 "s_register_operand" "")))]
4735 (define_insn "*arm_negsi2"
4736 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4737 (neg:SI (match_operand:SI 1 "s_register_operand" "l,r")))]
4739 "rsb%?\\t%0, %1, #0"
4740 [(set_attr "predicable" "yes")
4741 (set_attr "predicable_short_it" "yes,no")
4742 (set_attr "arch" "t2,*")
4743 (set_attr "length" "4")
4744 (set_attr "type" "alu_sreg")]
4747 (define_expand "negsf2"
4748 [(set (match_operand:SF 0 "s_register_operand" "")
4749 (neg:SF (match_operand:SF 1 "s_register_operand" "")))]
4750 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
4754 (define_expand "negdf2"
4755 [(set (match_operand:DF 0 "s_register_operand" "")
4756 (neg:DF (match_operand:DF 1 "s_register_operand" "")))]
4757 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
4760 (define_insn_and_split "*zextendsidi_negsi"
4761 [(set (match_operand:DI 0 "s_register_operand" "=r")
4762 (zero_extend:DI (neg:SI (match_operand:SI 1 "s_register_operand" "r"))))]
4767 (neg:SI (match_dup 1)))
4771 operands[2] = gen_lowpart (SImode, operands[0]);
4772 operands[3] = gen_highpart (SImode, operands[0]);
4774 [(set_attr "length" "8")
4775 (set_attr "type" "multiple")]
4778 ;; Negate an extended 32-bit value.
4779 (define_insn_and_split "*negdi_extendsidi"
4780 [(set (match_operand:DI 0 "s_register_operand" "=l,r")
4781 (neg:DI (sign_extend:DI
4782 (match_operand:SI 1 "s_register_operand" "l,r"))))
4783 (clobber (reg:CC CC_REGNUM))]
4786 "&& reload_completed"
4789 rtx low = gen_lowpart (SImode, operands[0]);
4790 rtx high = gen_highpart (SImode, operands[0]);
4792 if (reg_overlap_mentioned_p (low, operands[1]))
4794 /* Input overlaps the low word of the output. Use:
4797 rsc Rhi, Rhi, #0 (thumb2: sbc Rhi, Rhi, Rhi, lsl #1). */
4798 rtx cc_reg = gen_rtx_REG (CC_Cmode, CC_REGNUM);
4800 emit_insn (gen_rtx_SET (high,
4801 gen_rtx_ASHIFTRT (SImode, operands[1],
4804 emit_insn (gen_subsi3_compare (low, const0_rtx, operands[1]));
4806 emit_insn (gen_rtx_SET (high,
4807 gen_rtx_MINUS (SImode,
4808 gen_rtx_MINUS (SImode,
4811 gen_rtx_LTU (SImode,
4816 rtx two_x = gen_rtx_ASHIFT (SImode, high, GEN_INT (1));
4817 emit_insn (gen_rtx_SET (high,
4818 gen_rtx_MINUS (SImode,
4819 gen_rtx_MINUS (SImode,
4822 gen_rtx_LTU (SImode,
4829 /* No overlap, or overlap on high word. Use:
4833 Flags not needed for this sequence. */
4834 emit_insn (gen_rtx_SET (low, gen_rtx_NEG (SImode, operands[1])));
4835 emit_insn (gen_rtx_SET (high,
4836 gen_rtx_AND (SImode,
4837 gen_rtx_NOT (SImode, operands[1]),
4839 emit_insn (gen_rtx_SET (high,
4840 gen_rtx_ASHIFTRT (SImode, high,
4845 [(set_attr "length" "12")
4846 (set_attr "arch" "t2,*")
4847 (set_attr "type" "multiple")]
4850 (define_insn_and_split "*negdi_zero_extendsidi"
4851 [(set (match_operand:DI 0 "s_register_operand" "=r,&r")
4852 (neg:DI (zero_extend:DI (match_operand:SI 1 "s_register_operand" "0,r"))))
4853 (clobber (reg:CC CC_REGNUM))]
4855 "#" ; "rsbs\\t%Q0, %1, #0\;sbc\\t%R0,%R0,%R0"
4856 ;; Don't care what register is input to sbc,
4857 ;; since we just need to propagate the carry.
4858 "&& reload_completed"
4859 [(parallel [(set (reg:CC CC_REGNUM)
4860 (compare:CC (const_int 0) (match_dup 1)))
4861 (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1)))])
4862 (set (match_dup 2) (minus:SI (minus:SI (match_dup 2) (match_dup 2))
4863 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
4865 operands[2] = gen_highpart (SImode, operands[0]);
4866 operands[0] = gen_lowpart (SImode, operands[0]);
4868 [(set_attr "conds" "clob")
4869 (set_attr "length" "8")
4870 (set_attr "type" "multiple")] ;; length in thumb is 4
4873 ;; abssi2 doesn't really clobber the condition codes if a different register
4874 ;; is being set. To keep things simple, assume during rtl manipulations that
4875 ;; it does, but tell the final scan operator the truth. Similarly for
4878 (define_expand "abssi2"
4880 [(set (match_operand:SI 0 "s_register_operand" "")
4881 (abs:SI (match_operand:SI 1 "s_register_operand" "")))
4882 (clobber (match_dup 2))])]
4886 operands[2] = gen_rtx_SCRATCH (SImode);
4888 operands[2] = gen_rtx_REG (CCmode, CC_REGNUM);
4891 (define_insn_and_split "*arm_abssi2"
4892 [(set (match_operand:SI 0 "s_register_operand" "=r,&r")
4893 (abs:SI (match_operand:SI 1 "s_register_operand" "0,r")))
4894 (clobber (reg:CC CC_REGNUM))]
4897 "&& reload_completed"
4900 /* if (which_alternative == 0) */
4901 if (REGNO(operands[0]) == REGNO(operands[1]))
4903 /* Emit the pattern:
4904 cmp\\t%0, #0\;rsblt\\t%0, %0, #0
4905 [(set (reg:CC CC_REGNUM)
4906 (compare:CC (match_dup 0) (const_int 0)))
4907 (cond_exec (lt:CC (reg:CC CC_REGNUM) (const_int 0))
4908 (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1))))]
4910 emit_insn (gen_rtx_SET (gen_rtx_REG (CCmode, CC_REGNUM),
4911 gen_rtx_COMPARE (CCmode, operands[0], const0_rtx)));
4912 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
4913 (gen_rtx_LT (SImode,
4914 gen_rtx_REG (CCmode, CC_REGNUM),
4916 (gen_rtx_SET (operands[0],
4917 (gen_rtx_MINUS (SImode,
4924 /* Emit the pattern:
4925 alt1: eor%?\\t%0, %1, %1, asr #31\;sub%?\\t%0, %0, %1, asr #31
4927 (xor:SI (match_dup 1)
4928 (ashiftrt:SI (match_dup 1) (const_int 31))))
4930 (minus:SI (match_dup 0)
4931 (ashiftrt:SI (match_dup 1) (const_int 31))))]
4933 emit_insn (gen_rtx_SET (operands[0],
4934 gen_rtx_XOR (SImode,
4935 gen_rtx_ASHIFTRT (SImode,
4939 emit_insn (gen_rtx_SET (operands[0],
4940 gen_rtx_MINUS (SImode,
4942 gen_rtx_ASHIFTRT (SImode,
4948 [(set_attr "conds" "clob,*")
4949 (set_attr "shift" "1")
4950 (set_attr "predicable" "no, yes")
4951 (set_attr "length" "8")
4952 (set_attr "type" "multiple")]
4955 (define_insn_and_split "*arm_neg_abssi2"
4956 [(set (match_operand:SI 0 "s_register_operand" "=r,&r")
4957 (neg:SI (abs:SI (match_operand:SI 1 "s_register_operand" "0,r"))))
4958 (clobber (reg:CC CC_REGNUM))]
4961 "&& reload_completed"
4964 /* if (which_alternative == 0) */
4965 if (REGNO (operands[0]) == REGNO (operands[1]))
4967 /* Emit the pattern:
4968 cmp\\t%0, #0\;rsbgt\\t%0, %0, #0
4970 emit_insn (gen_rtx_SET (gen_rtx_REG (CCmode, CC_REGNUM),
4971 gen_rtx_COMPARE (CCmode, operands[0], const0_rtx)));
4972 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
4974 gen_rtx_REG (CCmode, CC_REGNUM),
4976 gen_rtx_SET (operands[0],
4977 (gen_rtx_MINUS (SImode,
4983 /* Emit the pattern:
4984 eor%?\\t%0, %1, %1, asr #31\;rsb%?\\t%0, %0, %1, asr #31
4986 emit_insn (gen_rtx_SET (operands[0],
4987 gen_rtx_XOR (SImode,
4988 gen_rtx_ASHIFTRT (SImode,
4992 emit_insn (gen_rtx_SET (operands[0],
4993 gen_rtx_MINUS (SImode,
4994 gen_rtx_ASHIFTRT (SImode,
5001 [(set_attr "conds" "clob,*")
5002 (set_attr "shift" "1")
5003 (set_attr "predicable" "no, yes")
5004 (set_attr "length" "8")
5005 (set_attr "type" "multiple")]
5008 (define_expand "abssf2"
5009 [(set (match_operand:SF 0 "s_register_operand" "")
5010 (abs:SF (match_operand:SF 1 "s_register_operand" "")))]
5011 "TARGET_32BIT && TARGET_HARD_FLOAT"
5014 (define_expand "absdf2"
5015 [(set (match_operand:DF 0 "s_register_operand" "")
5016 (abs:DF (match_operand:DF 1 "s_register_operand" "")))]
5017 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
5020 (define_expand "sqrtsf2"
5021 [(set (match_operand:SF 0 "s_register_operand" "")
5022 (sqrt:SF (match_operand:SF 1 "s_register_operand" "")))]
5023 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
5026 (define_expand "sqrtdf2"
5027 [(set (match_operand:DF 0 "s_register_operand" "")
5028 (sqrt:DF (match_operand:DF 1 "s_register_operand" "")))]
5029 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
5032 (define_insn_and_split "one_cmpldi2"
5033 [(set (match_operand:DI 0 "s_register_operand" "=w,&r,&r,?w")
5034 (not:DI (match_operand:DI 1 "s_register_operand" " w, 0, r, w")))]
5041 "TARGET_32BIT && reload_completed
5042 && arm_general_register_operand (operands[0], DImode)"
5043 [(set (match_dup 0) (not:SI (match_dup 1)))
5044 (set (match_dup 2) (not:SI (match_dup 3)))]
5047 operands[2] = gen_highpart (SImode, operands[0]);
5048 operands[0] = gen_lowpart (SImode, operands[0]);
5049 operands[3] = gen_highpart (SImode, operands[1]);
5050 operands[1] = gen_lowpart (SImode, operands[1]);
5052 [(set_attr "length" "*,8,8,*")
5053 (set_attr "predicable" "no,yes,yes,no")
5054 (set_attr "type" "neon_move,multiple,multiple,neon_move")
5055 (set_attr "arch" "neon_for_64bits,*,*,avoid_neon_for_64bits")]
5058 (define_expand "one_cmplsi2"
5059 [(set (match_operand:SI 0 "s_register_operand" "")
5060 (not:SI (match_operand:SI 1 "s_register_operand" "")))]
5065 (define_insn "*arm_one_cmplsi2"
5066 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
5067 (not:SI (match_operand:SI 1 "s_register_operand" "l,r")))]
5070 [(set_attr "predicable" "yes")
5071 (set_attr "predicable_short_it" "yes,no")
5072 (set_attr "arch" "t2,*")
5073 (set_attr "length" "4")
5074 (set_attr "type" "mvn_reg")]
5077 (define_insn "*notsi_compare0"
5078 [(set (reg:CC_NOOV CC_REGNUM)
5079 (compare:CC_NOOV (not:SI (match_operand:SI 1 "s_register_operand" "r"))
5081 (set (match_operand:SI 0 "s_register_operand" "=r")
5082 (not:SI (match_dup 1)))]
5085 [(set_attr "conds" "set")
5086 (set_attr "type" "mvn_reg")]
5089 (define_insn "*notsi_compare0_scratch"
5090 [(set (reg:CC_NOOV CC_REGNUM)
5091 (compare:CC_NOOV (not:SI (match_operand:SI 1 "s_register_operand" "r"))
5093 (clobber (match_scratch:SI 0 "=r"))]
5096 [(set_attr "conds" "set")
5097 (set_attr "type" "mvn_reg")]
5100 ;; Fixed <--> Floating conversion insns
5102 (define_expand "floatsihf2"
5103 [(set (match_operand:HF 0 "general_operand" "")
5104 (float:HF (match_operand:SI 1 "general_operand" "")))]
5108 rtx op1 = gen_reg_rtx (SFmode);
5109 expand_float (op1, operands[1], 0);
5110 op1 = convert_to_mode (HFmode, op1, 0);
5111 emit_move_insn (operands[0], op1);
5116 (define_expand "floatdihf2"
5117 [(set (match_operand:HF 0 "general_operand" "")
5118 (float:HF (match_operand:DI 1 "general_operand" "")))]
5122 rtx op1 = gen_reg_rtx (SFmode);
5123 expand_float (op1, operands[1], 0);
5124 op1 = convert_to_mode (HFmode, op1, 0);
5125 emit_move_insn (operands[0], op1);
5130 (define_expand "floatsisf2"
5131 [(set (match_operand:SF 0 "s_register_operand" "")
5132 (float:SF (match_operand:SI 1 "s_register_operand" "")))]
5133 "TARGET_32BIT && TARGET_HARD_FLOAT"
5137 (define_expand "floatsidf2"
5138 [(set (match_operand:DF 0 "s_register_operand" "")
5139 (float:DF (match_operand:SI 1 "s_register_operand" "")))]
5140 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
5144 (define_expand "fix_trunchfsi2"
5145 [(set (match_operand:SI 0 "general_operand" "")
5146 (fix:SI (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_trunchfdi2"
5157 [(set (match_operand:DI 0 "general_operand" "")
5158 (fix:DI (fix:HF (match_operand:HF 1 "general_operand" ""))))]
5162 rtx op1 = convert_to_mode (SFmode, operands[1], 0);
5163 expand_fix (operands[0], op1, 0);
5168 (define_expand "fix_truncsfsi2"
5169 [(set (match_operand:SI 0 "s_register_operand" "")
5170 (fix:SI (fix:SF (match_operand:SF 1 "s_register_operand" ""))))]
5171 "TARGET_32BIT && TARGET_HARD_FLOAT"
5175 (define_expand "fix_truncdfsi2"
5176 [(set (match_operand:SI 0 "s_register_operand" "")
5177 (fix:SI (fix:DF (match_operand:DF 1 "s_register_operand" ""))))]
5178 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
5184 (define_expand "truncdfsf2"
5185 [(set (match_operand:SF 0 "s_register_operand" "")
5187 (match_operand:DF 1 "s_register_operand" "")))]
5188 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
5192 ;; DFmode to HFmode conversions have to go through SFmode.
5193 (define_expand "truncdfhf2"
5194 [(set (match_operand:HF 0 "general_operand" "")
5196 (match_operand:DF 1 "general_operand" "")))]
5201 op1 = convert_to_mode (SFmode, operands[1], 0);
5202 op1 = convert_to_mode (HFmode, op1, 0);
5203 emit_move_insn (operands[0], op1);
5208 ;; Zero and sign extension instructions.
5210 (define_insn "zero_extend<mode>di2"
5211 [(set (match_operand:DI 0 "s_register_operand" "=w,r,?r,w")
5212 (zero_extend:DI (match_operand:QHSI 1 "<qhs_zextenddi_op>"
5213 "<qhs_zextenddi_cstr>")))]
5214 "TARGET_32BIT <qhs_zextenddi_cond>"
5216 [(set_attr "length" "8,4,8,8")
5217 (set_attr "arch" "neon_for_64bits,*,*,avoid_neon_for_64bits")
5218 (set_attr "ce_count" "2")
5219 (set_attr "predicable" "yes")
5220 (set_attr "type" "multiple,mov_reg,multiple,multiple")]
5223 (define_insn "extend<mode>di2"
5224 [(set (match_operand:DI 0 "s_register_operand" "=w,r,?r,?r,w")
5225 (sign_extend:DI (match_operand:QHSI 1 "<qhs_extenddi_op>"
5226 "<qhs_extenddi_cstr>")))]
5227 "TARGET_32BIT <qhs_sextenddi_cond>"
5229 [(set_attr "length" "8,4,8,8,8")
5230 (set_attr "ce_count" "2")
5231 (set_attr "shift" "1")
5232 (set_attr "predicable" "yes")
5233 (set_attr "arch" "neon_for_64bits,*,a,t,avoid_neon_for_64bits")
5234 (set_attr "type" "multiple,mov_reg,multiple,multiple,multiple")]
5237 ;; Splits for all extensions to DImode
5239 [(set (match_operand:DI 0 "s_register_operand" "")
5240 (zero_extend:DI (match_operand 1 "nonimmediate_operand" "")))]
5241 "TARGET_32BIT && reload_completed && !IS_VFP_REGNUM (REGNO (operands[0]))"
5242 [(set (match_dup 0) (match_dup 1))]
5244 rtx lo_part = gen_lowpart (SImode, operands[0]);
5245 machine_mode src_mode = GET_MODE (operands[1]);
5247 if (REG_P (operands[0])
5248 && !reg_overlap_mentioned_p (operands[0], operands[1]))
5249 emit_clobber (operands[0]);
5250 if (!REG_P (lo_part) || src_mode != SImode
5251 || !rtx_equal_p (lo_part, operands[1]))
5253 if (src_mode == SImode)
5254 emit_move_insn (lo_part, operands[1]);
5256 emit_insn (gen_rtx_SET (lo_part,
5257 gen_rtx_ZERO_EXTEND (SImode, operands[1])));
5258 operands[1] = lo_part;
5260 operands[0] = gen_highpart (SImode, operands[0]);
5261 operands[1] = const0_rtx;
5265 [(set (match_operand:DI 0 "s_register_operand" "")
5266 (sign_extend:DI (match_operand 1 "nonimmediate_operand" "")))]
5267 "TARGET_32BIT && reload_completed && !IS_VFP_REGNUM (REGNO (operands[0]))"
5268 [(set (match_dup 0) (ashiftrt:SI (match_dup 1) (const_int 31)))]
5270 rtx lo_part = gen_lowpart (SImode, operands[0]);
5271 machine_mode src_mode = GET_MODE (operands[1]);
5273 if (REG_P (operands[0])
5274 && !reg_overlap_mentioned_p (operands[0], operands[1]))
5275 emit_clobber (operands[0]);
5277 if (!REG_P (lo_part) || src_mode != SImode
5278 || !rtx_equal_p (lo_part, operands[1]))
5280 if (src_mode == SImode)
5281 emit_move_insn (lo_part, operands[1]);
5283 emit_insn (gen_rtx_SET (lo_part,
5284 gen_rtx_SIGN_EXTEND (SImode, operands[1])));
5285 operands[1] = lo_part;
5287 operands[0] = gen_highpart (SImode, operands[0]);
5290 (define_expand "zero_extendhisi2"
5291 [(set (match_operand:SI 0 "s_register_operand" "")
5292 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
5295 if (TARGET_ARM && !arm_arch4 && MEM_P (operands[1]))
5297 emit_insn (gen_movhi_bytes (operands[0], operands[1]));
5300 if (!arm_arch6 && !MEM_P (operands[1]))
5302 rtx t = gen_lowpart (SImode, operands[1]);
5303 rtx tmp = gen_reg_rtx (SImode);
5304 emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (16)));
5305 emit_insn (gen_lshrsi3 (operands[0], tmp, GEN_INT (16)));
5311 [(set (match_operand:SI 0 "s_register_operand" "")
5312 (zero_extend:SI (match_operand:HI 1 "s_register_operand" "")))]
5313 "!TARGET_THUMB2 && !arm_arch6"
5314 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
5315 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 16)))]
5317 operands[2] = gen_lowpart (SImode, operands[1]);
5320 (define_insn "*arm_zero_extendhisi2"
5321 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5322 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
5323 "TARGET_ARM && arm_arch4 && !arm_arch6"
5327 [(set_attr "type" "alu_shift_reg,load_byte")
5328 (set_attr "predicable" "yes")]
5331 (define_insn "*arm_zero_extendhisi2_v6"
5332 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5333 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,Uh")))]
5334 "TARGET_ARM && arm_arch6"
5338 [(set_attr "predicable" "yes")
5339 (set_attr "type" "extend,load_byte")]
5342 (define_insn "*arm_zero_extendhisi2addsi"
5343 [(set (match_operand:SI 0 "s_register_operand" "=r")
5344 (plus:SI (zero_extend:SI (match_operand:HI 1 "s_register_operand" "r"))
5345 (match_operand:SI 2 "s_register_operand" "r")))]
5347 "uxtah%?\\t%0, %2, %1"
5348 [(set_attr "type" "alu_shift_reg")
5349 (set_attr "predicable" "yes")
5350 (set_attr "predicable_short_it" "no")]
5353 (define_expand "zero_extendqisi2"
5354 [(set (match_operand:SI 0 "s_register_operand" "")
5355 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))]
5358 if (TARGET_ARM && !arm_arch6 && !MEM_P (operands[1]))
5360 emit_insn (gen_andsi3 (operands[0],
5361 gen_lowpart (SImode, operands[1]),
5365 if (!arm_arch6 && !MEM_P (operands[1]))
5367 rtx t = gen_lowpart (SImode, operands[1]);
5368 rtx tmp = gen_reg_rtx (SImode);
5369 emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (24)));
5370 emit_insn (gen_lshrsi3 (operands[0], tmp, GEN_INT (24)));
5376 [(set (match_operand:SI 0 "s_register_operand" "")
5377 (zero_extend:SI (match_operand:QI 1 "s_register_operand" "")))]
5379 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 24)))
5380 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 24)))]
5382 operands[2] = simplify_gen_subreg (SImode, operands[1], QImode, 0);
5385 emit_insn (gen_andsi3 (operands[0], operands[2], GEN_INT (255)));
5390 (define_insn "*arm_zero_extendqisi2"
5391 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5392 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
5393 "TARGET_ARM && !arm_arch6"
5396 ldrb%?\\t%0, %1\\t%@ zero_extendqisi2"
5397 [(set_attr "length" "8,4")
5398 (set_attr "type" "alu_shift_reg,load_byte")
5399 (set_attr "predicable" "yes")]
5402 (define_insn "*arm_zero_extendqisi2_v6"
5403 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5404 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,Uh")))]
5405 "TARGET_ARM && arm_arch6"
5408 ldrb%?\\t%0, %1\\t%@ zero_extendqisi2"
5409 [(set_attr "type" "extend,load_byte")
5410 (set_attr "predicable" "yes")]
5413 (define_insn "*arm_zero_extendqisi2addsi"
5414 [(set (match_operand:SI 0 "s_register_operand" "=r")
5415 (plus:SI (zero_extend:SI (match_operand:QI 1 "s_register_operand" "r"))
5416 (match_operand:SI 2 "s_register_operand" "r")))]
5418 "uxtab%?\\t%0, %2, %1"
5419 [(set_attr "predicable" "yes")
5420 (set_attr "predicable_short_it" "no")
5421 (set_attr "type" "alu_shift_reg")]
5425 [(set (match_operand:SI 0 "s_register_operand" "")
5426 (zero_extend:SI (subreg:QI (match_operand:SI 1 "" "") 0)))
5427 (clobber (match_operand:SI 2 "s_register_operand" ""))]
5428 "TARGET_32BIT && (!MEM_P (operands[1])) && ! BYTES_BIG_ENDIAN"
5429 [(set (match_dup 2) (match_dup 1))
5430 (set (match_dup 0) (and:SI (match_dup 2) (const_int 255)))]
5435 [(set (match_operand:SI 0 "s_register_operand" "")
5436 (zero_extend:SI (subreg:QI (match_operand:SI 1 "" "") 3)))
5437 (clobber (match_operand:SI 2 "s_register_operand" ""))]
5438 "TARGET_32BIT && (!MEM_P (operands[1])) && BYTES_BIG_ENDIAN"
5439 [(set (match_dup 2) (match_dup 1))
5440 (set (match_dup 0) (and:SI (match_dup 2) (const_int 255)))]
5446 [(set (match_operand:SI 0 "s_register_operand" "")
5447 (IOR_XOR:SI (and:SI (ashift:SI
5448 (match_operand:SI 1 "s_register_operand" "")
5449 (match_operand:SI 2 "const_int_operand" ""))
5450 (match_operand:SI 3 "const_int_operand" ""))
5452 (match_operator 5 "subreg_lowpart_operator"
5453 [(match_operand:SI 4 "s_register_operand" "")]))))]
5455 && (UINTVAL (operands[3])
5456 == (GET_MODE_MASK (GET_MODE (operands[5]))
5457 & (GET_MODE_MASK (GET_MODE (operands[5]))
5458 << (INTVAL (operands[2])))))"
5459 [(set (match_dup 0) (IOR_XOR:SI (ashift:SI (match_dup 1) (match_dup 2))
5461 (set (match_dup 0) (zero_extend:SI (match_dup 5)))]
5462 "operands[5] = gen_lowpart (GET_MODE (operands[5]), operands[0]);"
5465 (define_insn "*compareqi_eq0"
5466 [(set (reg:CC_Z CC_REGNUM)
5467 (compare:CC_Z (match_operand:QI 0 "s_register_operand" "r")
5471 [(set_attr "conds" "set")
5472 (set_attr "predicable" "yes")
5473 (set_attr "predicable_short_it" "no")
5474 (set_attr "type" "logic_imm")]
5477 (define_expand "extendhisi2"
5478 [(set (match_operand:SI 0 "s_register_operand" "")
5479 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
5484 emit_insn (gen_thumb1_extendhisi2 (operands[0], operands[1]));
5487 if (MEM_P (operands[1]) && TARGET_ARM && !arm_arch4)
5489 emit_insn (gen_extendhisi2_mem (operands[0], operands[1]));
5493 if (!arm_arch6 && !MEM_P (operands[1]))
5495 rtx t = gen_lowpart (SImode, operands[1]);
5496 rtx tmp = gen_reg_rtx (SImode);
5497 emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (16)));
5498 emit_insn (gen_ashrsi3 (operands[0], tmp, GEN_INT (16)));
5505 [(set (match_operand:SI 0 "register_operand" "")
5506 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))
5507 (clobber (match_scratch:SI 2 ""))])]
5509 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
5510 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
5512 operands[2] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
5515 ;; This pattern will only be used when ldsh is not available
5516 (define_expand "extendhisi2_mem"
5517 [(set (match_dup 2) (zero_extend:SI (match_operand:HI 1 "" "")))
5519 (zero_extend:SI (match_dup 7)))
5520 (set (match_dup 6) (ashift:SI (match_dup 4) (const_int 24)))
5521 (set (match_operand:SI 0 "" "")
5522 (ior:SI (ashiftrt:SI (match_dup 6) (const_int 16)) (match_dup 5)))]
5527 rtx addr = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
5529 mem1 = change_address (operands[1], QImode, addr);
5530 mem2 = change_address (operands[1], QImode,
5531 plus_constant (Pmode, addr, 1));
5532 operands[0] = gen_lowpart (SImode, operands[0]);
5534 operands[2] = gen_reg_rtx (SImode);
5535 operands[3] = gen_reg_rtx (SImode);
5536 operands[6] = gen_reg_rtx (SImode);
5539 if (BYTES_BIG_ENDIAN)
5541 operands[4] = operands[2];
5542 operands[5] = operands[3];
5546 operands[4] = operands[3];
5547 operands[5] = operands[2];
5553 [(set (match_operand:SI 0 "register_operand" "")
5554 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
5556 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
5557 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
5559 operands[2] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
5562 (define_insn "*arm_extendhisi2"
5563 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5564 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,Uh")))]
5565 "TARGET_ARM && arm_arch4 && !arm_arch6"
5569 [(set_attr "length" "8,4")
5570 (set_attr "type" "alu_shift_reg,load_byte")
5571 (set_attr "predicable" "yes")]
5574 ;; ??? Check Thumb-2 pool range
5575 (define_insn "*arm_extendhisi2_v6"
5576 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5577 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,Uh")))]
5578 "TARGET_32BIT && arm_arch6"
5582 [(set_attr "type" "extend,load_byte")
5583 (set_attr "predicable" "yes")
5584 (set_attr "predicable_short_it" "no")]
5587 (define_insn "*arm_extendhisi2addsi"
5588 [(set (match_operand:SI 0 "s_register_operand" "=r")
5589 (plus:SI (sign_extend:SI (match_operand:HI 1 "s_register_operand" "r"))
5590 (match_operand:SI 2 "s_register_operand" "r")))]
5592 "sxtah%?\\t%0, %2, %1"
5593 [(set_attr "type" "alu_shift_reg")]
5596 (define_expand "extendqihi2"
5598 (ashift:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "")
5600 (set (match_operand:HI 0 "s_register_operand" "")
5601 (ashiftrt:SI (match_dup 2)
5606 if (arm_arch4 && MEM_P (operands[1]))
5608 emit_insn (gen_rtx_SET (operands[0],
5609 gen_rtx_SIGN_EXTEND (HImode, operands[1])));
5612 if (!s_register_operand (operands[1], QImode))
5613 operands[1] = copy_to_mode_reg (QImode, operands[1]);
5614 operands[0] = gen_lowpart (SImode, operands[0]);
5615 operands[1] = gen_lowpart (SImode, operands[1]);
5616 operands[2] = gen_reg_rtx (SImode);
5620 (define_insn "*arm_extendqihi_insn"
5621 [(set (match_operand:HI 0 "s_register_operand" "=r")
5622 (sign_extend:HI (match_operand:QI 1 "arm_extendqisi_mem_op" "Uq")))]
5623 "TARGET_ARM && arm_arch4"
5625 [(set_attr "type" "load_byte")
5626 (set_attr "predicable" "yes")]
5629 (define_expand "extendqisi2"
5630 [(set (match_operand:SI 0 "s_register_operand" "")
5631 (sign_extend:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "")))]
5634 if (!arm_arch4 && MEM_P (operands[1]))
5635 operands[1] = copy_to_mode_reg (QImode, operands[1]);
5637 if (!arm_arch6 && !MEM_P (operands[1]))
5639 rtx t = gen_lowpart (SImode, operands[1]);
5640 rtx tmp = gen_reg_rtx (SImode);
5641 emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (24)));
5642 emit_insn (gen_ashrsi3 (operands[0], tmp, GEN_INT (24)));
5648 [(set (match_operand:SI 0 "register_operand" "")
5649 (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
5651 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 24)))
5652 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 24)))]
5654 operands[2] = simplify_gen_subreg (SImode, operands[1], QImode, 0);
5657 (define_insn "*arm_extendqisi"
5658 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5659 (sign_extend:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "r,Uq")))]
5660 "TARGET_ARM && arm_arch4 && !arm_arch6"
5664 [(set_attr "length" "8,4")
5665 (set_attr "type" "alu_shift_reg,load_byte")
5666 (set_attr "predicable" "yes")]
5669 (define_insn "*arm_extendqisi_v6"
5670 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5672 (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "r,Uq")))]
5673 "TARGET_ARM && arm_arch6"
5677 [(set_attr "type" "extend,load_byte")
5678 (set_attr "predicable" "yes")]
5681 (define_insn "*arm_extendqisi2addsi"
5682 [(set (match_operand:SI 0 "s_register_operand" "=r")
5683 (plus:SI (sign_extend:SI (match_operand:QI 1 "s_register_operand" "r"))
5684 (match_operand:SI 2 "s_register_operand" "r")))]
5686 "sxtab%?\\t%0, %2, %1"
5687 [(set_attr "type" "alu_shift_reg")
5688 (set_attr "predicable" "yes")
5689 (set_attr "predicable_short_it" "no")]
5692 (define_expand "extendsfdf2"
5693 [(set (match_operand:DF 0 "s_register_operand" "")
5694 (float_extend:DF (match_operand:SF 1 "s_register_operand" "")))]
5695 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
5699 ;; HFmode -> DFmode conversions have to go through SFmode.
5700 (define_expand "extendhfdf2"
5701 [(set (match_operand:DF 0 "general_operand" "")
5702 (float_extend:DF (match_operand:HF 1 "general_operand" "")))]
5707 op1 = convert_to_mode (SFmode, operands[1], 0);
5708 op1 = convert_to_mode (DFmode, op1, 0);
5709 emit_insn (gen_movdf (operands[0], op1));
5714 ;; Move insns (including loads and stores)
5716 ;; XXX Just some ideas about movti.
5717 ;; I don't think these are a good idea on the arm, there just aren't enough
5719 ;;(define_expand "loadti"
5720 ;; [(set (match_operand:TI 0 "s_register_operand" "")
5721 ;; (mem:TI (match_operand:SI 1 "address_operand" "")))]
5724 ;;(define_expand "storeti"
5725 ;; [(set (mem:TI (match_operand:TI 0 "address_operand" ""))
5726 ;; (match_operand:TI 1 "s_register_operand" ""))]
5729 ;;(define_expand "movti"
5730 ;; [(set (match_operand:TI 0 "general_operand" "")
5731 ;; (match_operand:TI 1 "general_operand" ""))]
5737 ;; if (MEM_P (operands[0]) && MEM_P (operands[1]))
5738 ;; operands[1] = copy_to_reg (operands[1]);
5739 ;; if (MEM_P (operands[0]))
5740 ;; insn = gen_storeti (XEXP (operands[0], 0), operands[1]);
5741 ;; else if (MEM_P (operands[1]))
5742 ;; insn = gen_loadti (operands[0], XEXP (operands[1], 0));
5746 ;; emit_insn (insn);
5750 ;; Recognize garbage generated above.
5753 ;; [(set (match_operand:TI 0 "general_operand" "=r,r,r,<,>,m")
5754 ;; (match_operand:TI 1 "general_operand" "<,>,m,r,r,r"))]
5758 ;; register mem = (which_alternative < 3);
5759 ;; register const char *template;
5761 ;; operands[mem] = XEXP (operands[mem], 0);
5762 ;; switch (which_alternative)
5764 ;; case 0: template = \"ldmdb\\t%1!, %M0\"; break;
5765 ;; case 1: template = \"ldmia\\t%1!, %M0\"; break;
5766 ;; case 2: template = \"ldmia\\t%1, %M0\"; break;
5767 ;; case 3: template = \"stmdb\\t%0!, %M1\"; break;
5768 ;; case 4: template = \"stmia\\t%0!, %M1\"; break;
5769 ;; case 5: template = \"stmia\\t%0, %M1\"; break;
5771 ;; output_asm_insn (template, operands);
5775 (define_expand "movdi"
5776 [(set (match_operand:DI 0 "general_operand" "")
5777 (match_operand:DI 1 "general_operand" ""))]
5780 if (can_create_pseudo_p ())
5782 if (!REG_P (operands[0]))
5783 operands[1] = force_reg (DImode, operands[1]);
5785 if (REG_P (operands[0]) && REGNO (operands[0]) <= LAST_ARM_REGNUM
5786 && !HARD_REGNO_MODE_OK (REGNO (operands[0]), DImode))
5788 /* Avoid LDRD's into an odd-numbered register pair in ARM state
5789 when expanding function calls. */
5790 gcc_assert (can_create_pseudo_p ());
5791 if (MEM_P (operands[1]) && MEM_VOLATILE_P (operands[1]))
5793 /* Perform load into legal reg pair first, then move. */
5794 rtx reg = gen_reg_rtx (DImode);
5795 emit_insn (gen_movdi (reg, operands[1]));
5798 emit_move_insn (gen_lowpart (SImode, operands[0]),
5799 gen_lowpart (SImode, operands[1]));
5800 emit_move_insn (gen_highpart (SImode, operands[0]),
5801 gen_highpart (SImode, operands[1]));
5804 else if (REG_P (operands[1]) && REGNO (operands[1]) <= LAST_ARM_REGNUM
5805 && !HARD_REGNO_MODE_OK (REGNO (operands[1]), DImode))
5807 /* Avoid STRD's from an odd-numbered register pair in ARM state
5808 when expanding function prologue. */
5809 gcc_assert (can_create_pseudo_p ());
5810 rtx split_dest = (MEM_P (operands[0]) && MEM_VOLATILE_P (operands[0]))
5811 ? gen_reg_rtx (DImode)
5813 emit_move_insn (gen_lowpart (SImode, split_dest),
5814 gen_lowpart (SImode, operands[1]));
5815 emit_move_insn (gen_highpart (SImode, split_dest),
5816 gen_highpart (SImode, operands[1]));
5817 if (split_dest != operands[0])
5818 emit_insn (gen_movdi (operands[0], split_dest));
5824 (define_insn "*arm_movdi"
5825 [(set (match_operand:DI 0 "nonimmediate_di_operand" "=r, r, r, q, m")
5826 (match_operand:DI 1 "di_operand" "rDa,Db,Dc,mi,q"))]
5828 && !(TARGET_HARD_FLOAT && TARGET_VFP)
5830 && ( register_operand (operands[0], DImode)
5831 || register_operand (operands[1], DImode))"
5833 switch (which_alternative)
5840 return output_move_double (operands, true, NULL);
5843 [(set_attr "length" "8,12,16,8,8")
5844 (set_attr "type" "multiple,multiple,multiple,load2,store2")
5845 (set_attr "arm_pool_range" "*,*,*,1020,*")
5846 (set_attr "arm_neg_pool_range" "*,*,*,1004,*")
5847 (set_attr "thumb2_pool_range" "*,*,*,4094,*")
5848 (set_attr "thumb2_neg_pool_range" "*,*,*,0,*")]
5852 [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
5853 (match_operand:ANY64 1 "immediate_operand" ""))]
5856 && (arm_const_double_inline_cost (operands[1])
5857 <= arm_max_const_double_inline_cost ())"
5860 arm_split_constant (SET, SImode, curr_insn,
5861 INTVAL (gen_lowpart (SImode, operands[1])),
5862 gen_lowpart (SImode, operands[0]), NULL_RTX, 0);
5863 arm_split_constant (SET, SImode, curr_insn,
5864 INTVAL (gen_highpart_mode (SImode,
5865 GET_MODE (operands[0]),
5867 gen_highpart (SImode, operands[0]), NULL_RTX, 0);
5872 ; If optimizing for size, or if we have load delay slots, then
5873 ; we want to split the constant into two separate operations.
5874 ; In both cases this may split a trivial part into a single data op
5875 ; leaving a single complex constant to load. We can also get longer
5876 ; offsets in a LDR which means we get better chances of sharing the pool
5877 ; entries. Finally, we can normally do a better job of scheduling
5878 ; LDR instructions than we can with LDM.
5879 ; This pattern will only match if the one above did not.
5881 [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
5882 (match_operand:ANY64 1 "const_double_operand" ""))]
5883 "TARGET_ARM && reload_completed
5884 && arm_const_double_by_parts (operands[1])"
5885 [(set (match_dup 0) (match_dup 1))
5886 (set (match_dup 2) (match_dup 3))]
5888 operands[2] = gen_highpart (SImode, operands[0]);
5889 operands[3] = gen_highpart_mode (SImode, GET_MODE (operands[0]),
5891 operands[0] = gen_lowpart (SImode, operands[0]);
5892 operands[1] = gen_lowpart (SImode, operands[1]);
5897 [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
5898 (match_operand:ANY64 1 "arm_general_register_operand" ""))]
5899 "TARGET_EITHER && reload_completed"
5900 [(set (match_dup 0) (match_dup 1))
5901 (set (match_dup 2) (match_dup 3))]
5903 operands[2] = gen_highpart (SImode, operands[0]);
5904 operands[3] = gen_highpart (SImode, operands[1]);
5905 operands[0] = gen_lowpart (SImode, operands[0]);
5906 operands[1] = gen_lowpart (SImode, operands[1]);
5908 /* Handle a partial overlap. */
5909 if (rtx_equal_p (operands[0], operands[3]))
5911 rtx tmp0 = operands[0];
5912 rtx tmp1 = operands[1];
5914 operands[0] = operands[2];
5915 operands[1] = operands[3];
5922 ;; We can't actually do base+index doubleword loads if the index and
5923 ;; destination overlap. Split here so that we at least have chance to
5926 [(set (match_operand:DI 0 "s_register_operand" "")
5927 (mem:DI (plus:SI (match_operand:SI 1 "s_register_operand" "")
5928 (match_operand:SI 2 "s_register_operand" ""))))]
5930 && reg_overlap_mentioned_p (operands[0], operands[1])
5931 && reg_overlap_mentioned_p (operands[0], operands[2])"
5933 (plus:SI (match_dup 1)
5936 (mem:DI (match_dup 4)))]
5938 operands[4] = gen_rtx_REG (SImode, REGNO(operands[0]));
5942 (define_expand "movsi"
5943 [(set (match_operand:SI 0 "general_operand" "")
5944 (match_operand:SI 1 "general_operand" ""))]
5948 rtx base, offset, tmp;
5952 /* Everything except mem = const or mem = mem can be done easily. */
5953 if (MEM_P (operands[0]))
5954 operands[1] = force_reg (SImode, operands[1]);
5955 if (arm_general_register_operand (operands[0], SImode)
5956 && CONST_INT_P (operands[1])
5957 && !(const_ok_for_arm (INTVAL (operands[1]))
5958 || const_ok_for_arm (~INTVAL (operands[1]))))
5960 if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[1]), SET))
5962 emit_insn (gen_rtx_SET (operands[0], operands[1]));
5967 arm_split_constant (SET, SImode, NULL_RTX,
5968 INTVAL (operands[1]), operands[0], NULL_RTX,
5969 optimize && can_create_pseudo_p ());
5974 else /* TARGET_THUMB1... */
5976 if (can_create_pseudo_p ())
5978 if (!REG_P (operands[0]))
5979 operands[1] = force_reg (SImode, operands[1]);
5983 if (ARM_OFFSETS_MUST_BE_WITHIN_SECTIONS_P)
5985 split_const (operands[1], &base, &offset);
5986 if (GET_CODE (base) == SYMBOL_REF
5987 && !offset_within_block_p (base, INTVAL (offset)))
5989 tmp = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];
5990 emit_move_insn (tmp, base);
5991 emit_insn (gen_addsi3 (operands[0], tmp, offset));
5996 /* Recognize the case where operand[1] is a reference to thread-local
5997 data and load its address to a register. */
5998 if (arm_tls_referenced_p (operands[1]))
6000 rtx tmp = operands[1];
6003 if (GET_CODE (tmp) == CONST && GET_CODE (XEXP (tmp, 0)) == PLUS)
6005 addend = XEXP (XEXP (tmp, 0), 1);
6006 tmp = XEXP (XEXP (tmp, 0), 0);
6009 gcc_assert (GET_CODE (tmp) == SYMBOL_REF);
6010 gcc_assert (SYMBOL_REF_TLS_MODEL (tmp) != 0);
6012 tmp = legitimize_tls_address (tmp,
6013 !can_create_pseudo_p () ? operands[0] : 0);
6016 tmp = gen_rtx_PLUS (SImode, tmp, addend);
6017 tmp = force_operand (tmp, operands[0]);
6022 && (CONSTANT_P (operands[1])
6023 || symbol_mentioned_p (operands[1])
6024 || label_mentioned_p (operands[1])))
6025 operands[1] = legitimize_pic_address (operands[1], SImode,
6026 (!can_create_pseudo_p ()
6033 ;; The ARM LO_SUM and HIGH are backwards - HIGH sets the low bits, and
6034 ;; LO_SUM adds in the high bits. Fortunately these are opaque operations
6035 ;; so this does not matter.
6036 (define_insn "*arm_movt"
6037 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r")
6038 (lo_sum:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6039 (match_operand:SI 2 "general_operand" "i,i")))]
6040 "TARGET_HAVE_MOVT && arm_valid_symbolic_address_p (operands[2])"
6042 movt%?\t%0, #:upper16:%c2
6043 movt\t%0, #:upper16:%c2"
6044 [(set_attr "arch" "32,v8mb")
6045 (set_attr "predicable" "yes")
6046 (set_attr "predicable_short_it" "no")
6047 (set_attr "length" "4")
6048 (set_attr "type" "alu_sreg")]
6051 (define_insn "*arm_movsi_insn"
6052 [(set (match_operand:SI 0 "nonimmediate_operand" "=rk,r,r,r,rk,m")
6053 (match_operand:SI 1 "general_operand" "rk, I,K,j,mi,rk"))]
6054 "TARGET_ARM && ! TARGET_IWMMXT
6055 && !(TARGET_HARD_FLOAT && TARGET_VFP)
6056 && ( register_operand (operands[0], SImode)
6057 || register_operand (operands[1], SImode))"
6065 [(set_attr "type" "mov_reg,mov_imm,mvn_imm,mov_imm,load1,store1")
6066 (set_attr "predicable" "yes")
6067 (set_attr "arch" "*,*,*,v6t2,*,*")
6068 (set_attr "pool_range" "*,*,*,*,4096,*")
6069 (set_attr "neg_pool_range" "*,*,*,*,4084,*")]
6073 [(set (match_operand:SI 0 "arm_general_register_operand" "")
6074 (match_operand:SI 1 "const_int_operand" ""))]
6076 && (!(const_ok_for_arm (INTVAL (operands[1]))
6077 || const_ok_for_arm (~INTVAL (operands[1]))))"
6078 [(clobber (const_int 0))]
6080 arm_split_constant (SET, SImode, NULL_RTX,
6081 INTVAL (operands[1]), operands[0], NULL_RTX, 0);
6086 ;; A normal way to do (symbol + offset) requires three instructions at least
6087 ;; (depends on how big the offset is) as below:
6088 ;; movw r0, #:lower16:g
6089 ;; movw r0, #:upper16:g
6092 ;; A better way would be:
6093 ;; movw r0, #:lower16:g+4
6094 ;; movw r0, #:upper16:g+4
6096 ;; The limitation of this way is that the length of offset should be a 16-bit
6097 ;; signed value, because current assembler only supports REL type relocation for
6098 ;; such case. If the more powerful RELA type is supported in future, we should
6099 ;; update this pattern to go with better way.
6101 [(set (match_operand:SI 0 "arm_general_register_operand" "")
6102 (const:SI (plus:SI (match_operand:SI 1 "general_operand" "")
6103 (match_operand:SI 2 "const_int_operand" ""))))]
6106 && arm_disable_literal_pool
6108 && GET_CODE (operands[1]) == SYMBOL_REF"
6109 [(clobber (const_int 0))]
6111 int offset = INTVAL (operands[2]);
6113 if (offset < -0x8000 || offset > 0x7fff)
6115 arm_emit_movpair (operands[0], operands[1]);
6116 emit_insn (gen_rtx_SET (operands[0],
6117 gen_rtx_PLUS (SImode, operands[0], operands[2])));
6121 rtx op = gen_rtx_CONST (SImode,
6122 gen_rtx_PLUS (SImode, operands[1], operands[2]));
6123 arm_emit_movpair (operands[0], op);
6128 ;; Split symbol_refs at the later stage (after cprop), instead of generating
6129 ;; movt/movw pair directly at expand. Otherwise corresponding high_sum
6130 ;; and lo_sum would be merged back into memory load at cprop. However,
6131 ;; if the default is to prefer movt/movw rather than a load from the constant
6132 ;; pool, the performance is better.
6134 [(set (match_operand:SI 0 "arm_general_register_operand" "")
6135 (match_operand:SI 1 "general_operand" ""))]
6136 "TARGET_USE_MOVT && GET_CODE (operands[1]) == SYMBOL_REF
6137 && !flag_pic && !target_word_relocations
6138 && !arm_tls_referenced_p (operands[1])"
6139 [(clobber (const_int 0))]
6141 arm_emit_movpair (operands[0], operands[1]);
6145 ;; When generating pic, we need to load the symbol offset into a register.
6146 ;; So that the optimizer does not confuse this with a normal symbol load
6147 ;; we use an unspec. The offset will be loaded from a constant pool entry,
6148 ;; since that is the only type of relocation we can use.
6150 ;; Wrap calculation of the whole PIC address in a single pattern for the
6151 ;; benefit of optimizers, particularly, PRE and HOIST. Calculation of
6152 ;; a PIC address involves two loads from memory, so we want to CSE it
6153 ;; as often as possible.
6154 ;; This pattern will be split into one of the pic_load_addr_* patterns
6155 ;; and a move after GCSE optimizations.
6157 ;; Note: Update arm.c: legitimize_pic_address() when changing this pattern.
6158 (define_expand "calculate_pic_address"
6159 [(set (match_operand:SI 0 "register_operand" "")
6160 (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "")
6161 (unspec:SI [(match_operand:SI 2 "" "")]
6166 ;; Split calculate_pic_address into pic_load_addr_* and a move.
6168 [(set (match_operand:SI 0 "register_operand" "")
6169 (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "")
6170 (unspec:SI [(match_operand:SI 2 "" "")]
6173 [(set (match_dup 3) (unspec:SI [(match_dup 2)] UNSPEC_PIC_SYM))
6174 (set (match_dup 0) (mem:SI (plus:SI (match_dup 1) (match_dup 3))))]
6175 "operands[3] = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];"
6178 ;; operand1 is the memory address to go into
6179 ;; pic_load_addr_32bit.
6180 ;; operand2 is the PIC label to be emitted
6181 ;; from pic_add_dot_plus_eight.
6182 ;; We do this to allow hoisting of the entire insn.
6183 (define_insn_and_split "pic_load_addr_unified"
6184 [(set (match_operand:SI 0 "s_register_operand" "=r,r,l")
6185 (unspec:SI [(match_operand:SI 1 "" "mX,mX,mX")
6186 (match_operand:SI 2 "" "")]
6187 UNSPEC_PIC_UNIFIED))]
6190 "&& reload_completed"
6191 [(set (match_dup 0) (unspec:SI [(match_dup 1)] UNSPEC_PIC_SYM))
6192 (set (match_dup 0) (unspec:SI [(match_dup 0) (match_dup 3)
6193 (match_dup 2)] UNSPEC_PIC_BASE))]
6194 "operands[3] = TARGET_THUMB ? GEN_INT (4) : GEN_INT (8);"
6195 [(set_attr "type" "load1,load1,load1")
6196 (set_attr "pool_range" "4096,4094,1022")
6197 (set_attr "neg_pool_range" "4084,0,0")
6198 (set_attr "arch" "a,t2,t1")
6199 (set_attr "length" "8,6,4")]
6202 ;; The rather odd constraints on the following are to force reload to leave
6203 ;; the insn alone, and to force the minipool generation pass to then move
6204 ;; the GOT symbol to memory.
6206 (define_insn "pic_load_addr_32bit"
6207 [(set (match_operand:SI 0 "s_register_operand" "=r")
6208 (unspec:SI [(match_operand:SI 1 "" "mX")] UNSPEC_PIC_SYM))]
6209 "TARGET_32BIT && flag_pic"
6211 [(set_attr "type" "load1")
6212 (set (attr "pool_range")
6213 (if_then_else (eq_attr "is_thumb" "no")
6216 (set (attr "neg_pool_range")
6217 (if_then_else (eq_attr "is_thumb" "no")
6222 (define_insn "pic_load_addr_thumb1"
6223 [(set (match_operand:SI 0 "s_register_operand" "=l")
6224 (unspec:SI [(match_operand:SI 1 "" "mX")] UNSPEC_PIC_SYM))]
6225 "TARGET_THUMB1 && flag_pic"
6227 [(set_attr "type" "load1")
6228 (set (attr "pool_range") (const_int 1018))]
6231 (define_insn "pic_add_dot_plus_four"
6232 [(set (match_operand:SI 0 "register_operand" "=r")
6233 (unspec:SI [(match_operand:SI 1 "register_operand" "0")
6235 (match_operand 2 "" "")]
6239 (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
6240 INTVAL (operands[2]));
6241 return \"add\\t%0, %|pc\";
6243 [(set_attr "length" "2")
6244 (set_attr "type" "alu_sreg")]
6247 (define_insn "pic_add_dot_plus_eight"
6248 [(set (match_operand:SI 0 "register_operand" "=r")
6249 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
6251 (match_operand 2 "" "")]
6255 (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
6256 INTVAL (operands[2]));
6257 return \"add%?\\t%0, %|pc, %1\";
6259 [(set_attr "predicable" "yes")
6260 (set_attr "type" "alu_sreg")]
6263 (define_insn "tls_load_dot_plus_eight"
6264 [(set (match_operand:SI 0 "register_operand" "=r")
6265 (mem:SI (unspec:SI [(match_operand:SI 1 "register_operand" "r")
6267 (match_operand 2 "" "")]
6271 (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
6272 INTVAL (operands[2]));
6273 return \"ldr%?\\t%0, [%|pc, %1]\t\t@ tls_load_dot_plus_eight\";
6275 [(set_attr "predicable" "yes")
6276 (set_attr "type" "load1")]
6279 ;; PIC references to local variables can generate pic_add_dot_plus_eight
6280 ;; followed by a load. These sequences can be crunched down to
6281 ;; tls_load_dot_plus_eight by a peephole.
6284 [(set (match_operand:SI 0 "register_operand" "")
6285 (unspec:SI [(match_operand:SI 3 "register_operand" "")
6287 (match_operand 1 "" "")]
6289 (set (match_operand:SI 2 "arm_general_register_operand" "")
6290 (mem:SI (match_dup 0)))]
6291 "TARGET_ARM && peep2_reg_dead_p (2, operands[0])"
6293 (mem:SI (unspec:SI [(match_dup 3)
6300 (define_insn "pic_offset_arm"
6301 [(set (match_operand:SI 0 "register_operand" "=r")
6302 (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
6303 (unspec:SI [(match_operand:SI 2 "" "X")]
6304 UNSPEC_PIC_OFFSET))))]
6305 "TARGET_VXWORKS_RTP && TARGET_ARM && flag_pic"
6306 "ldr%?\\t%0, [%1,%2]"
6307 [(set_attr "type" "load1")]
6310 (define_expand "builtin_setjmp_receiver"
6311 [(label_ref (match_operand 0 "" ""))]
6315 /* r3 is clobbered by set/longjmp, so we can use it as a scratch
6317 if (arm_pic_register != INVALID_REGNUM)
6318 arm_load_pic_register (1UL << 3);
6322 ;; If copying one reg to another we can set the condition codes according to
6323 ;; its value. Such a move is common after a return from subroutine and the
6324 ;; result is being tested against zero.
6326 (define_insn "*movsi_compare0"
6327 [(set (reg:CC CC_REGNUM)
6328 (compare:CC (match_operand:SI 1 "s_register_operand" "0,r")
6330 (set (match_operand:SI 0 "s_register_operand" "=r,r")
6335 subs%?\\t%0, %1, #0"
6336 [(set_attr "conds" "set")
6337 (set_attr "type" "alus_imm,alus_imm")]
6340 ;; Subroutine to store a half word from a register into memory.
6341 ;; Operand 0 is the source register (HImode)
6342 ;; Operand 1 is the destination address in a register (SImode)
6344 ;; In both this routine and the next, we must be careful not to spill
6345 ;; a memory address of reg+large_const into a separate PLUS insn, since this
6346 ;; can generate unrecognizable rtl.
6348 (define_expand "storehi"
6349 [;; store the low byte
6350 (set (match_operand 1 "" "") (match_dup 3))
6351 ;; extract the high byte
6353 (ashiftrt:SI (match_operand 0 "" "") (const_int 8)))
6354 ;; store the high byte
6355 (set (match_dup 4) (match_dup 5))]
6359 rtx op1 = operands[1];
6360 rtx addr = XEXP (op1, 0);
6361 enum rtx_code code = GET_CODE (addr);
6363 if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1)))
6365 op1 = replace_equiv_address (operands[1], force_reg (SImode, addr));
6367 operands[4] = adjust_address (op1, QImode, 1);
6368 operands[1] = adjust_address (operands[1], QImode, 0);
6369 operands[3] = gen_lowpart (QImode, operands[0]);
6370 operands[0] = gen_lowpart (SImode, operands[0]);
6371 operands[2] = gen_reg_rtx (SImode);
6372 operands[5] = gen_lowpart (QImode, operands[2]);
6376 (define_expand "storehi_bigend"
6377 [(set (match_dup 4) (match_dup 3))
6379 (ashiftrt:SI (match_operand 0 "" "") (const_int 8)))
6380 (set (match_operand 1 "" "") (match_dup 5))]
6384 rtx op1 = operands[1];
6385 rtx addr = XEXP (op1, 0);
6386 enum rtx_code code = GET_CODE (addr);
6388 if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1)))
6390 op1 = replace_equiv_address (op1, force_reg (SImode, addr));
6392 operands[4] = adjust_address (op1, QImode, 1);
6393 operands[1] = adjust_address (operands[1], QImode, 0);
6394 operands[3] = gen_lowpart (QImode, operands[0]);
6395 operands[0] = gen_lowpart (SImode, operands[0]);
6396 operands[2] = gen_reg_rtx (SImode);
6397 operands[5] = gen_lowpart (QImode, operands[2]);
6401 ;; Subroutine to store a half word integer constant into memory.
6402 (define_expand "storeinthi"
6403 [(set (match_operand 0 "" "")
6404 (match_operand 1 "" ""))
6405 (set (match_dup 3) (match_dup 2))]
6409 HOST_WIDE_INT value = INTVAL (operands[1]);
6410 rtx addr = XEXP (operands[0], 0);
6411 rtx op0 = operands[0];
6412 enum rtx_code code = GET_CODE (addr);
6414 if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1)))
6416 op0 = replace_equiv_address (op0, force_reg (SImode, addr));
6418 operands[1] = gen_reg_rtx (SImode);
6419 if (BYTES_BIG_ENDIAN)
6421 emit_insn (gen_movsi (operands[1], GEN_INT ((value >> 8) & 255)));
6422 if ((value & 255) == ((value >> 8) & 255))
6423 operands[2] = operands[1];
6426 operands[2] = gen_reg_rtx (SImode);
6427 emit_insn (gen_movsi (operands[2], GEN_INT (value & 255)));
6432 emit_insn (gen_movsi (operands[1], GEN_INT (value & 255)));
6433 if ((value & 255) == ((value >> 8) & 255))
6434 operands[2] = operands[1];
6437 operands[2] = gen_reg_rtx (SImode);
6438 emit_insn (gen_movsi (operands[2], GEN_INT ((value >> 8) & 255)));
6442 operands[3] = adjust_address (op0, QImode, 1);
6443 operands[0] = adjust_address (operands[0], QImode, 0);
6444 operands[2] = gen_lowpart (QImode, operands[2]);
6445 operands[1] = gen_lowpart (QImode, operands[1]);
6449 (define_expand "storehi_single_op"
6450 [(set (match_operand:HI 0 "memory_operand" "")
6451 (match_operand:HI 1 "general_operand" ""))]
6452 "TARGET_32BIT && arm_arch4"
6454 if (!s_register_operand (operands[1], HImode))
6455 operands[1] = copy_to_mode_reg (HImode, operands[1]);
6459 (define_expand "movhi"
6460 [(set (match_operand:HI 0 "general_operand" "")
6461 (match_operand:HI 1 "general_operand" ""))]
6466 if (can_create_pseudo_p ())
6468 if (MEM_P (operands[0]))
6472 emit_insn (gen_storehi_single_op (operands[0], operands[1]));
6475 if (CONST_INT_P (operands[1]))
6476 emit_insn (gen_storeinthi (operands[0], operands[1]));
6479 if (MEM_P (operands[1]))
6480 operands[1] = force_reg (HImode, operands[1]);
6481 if (BYTES_BIG_ENDIAN)
6482 emit_insn (gen_storehi_bigend (operands[1], operands[0]));
6484 emit_insn (gen_storehi (operands[1], operands[0]));
6488 /* Sign extend a constant, and keep it in an SImode reg. */
6489 else if (CONST_INT_P (operands[1]))
6491 rtx reg = gen_reg_rtx (SImode);
6492 HOST_WIDE_INT val = INTVAL (operands[1]) & 0xffff;
6494 /* If the constant is already valid, leave it alone. */
6495 if (!const_ok_for_arm (val))
6497 /* If setting all the top bits will make the constant
6498 loadable in a single instruction, then set them.
6499 Otherwise, sign extend the number. */
6501 if (const_ok_for_arm (~(val | ~0xffff)))
6503 else if (val & 0x8000)
6507 emit_insn (gen_movsi (reg, GEN_INT (val)));
6508 operands[1] = gen_lowpart (HImode, reg);
6510 else if (arm_arch4 && optimize && can_create_pseudo_p ()
6511 && MEM_P (operands[1]))
6513 rtx reg = gen_reg_rtx (SImode);
6515 emit_insn (gen_zero_extendhisi2 (reg, operands[1]));
6516 operands[1] = gen_lowpart (HImode, reg);
6518 else if (!arm_arch4)
6520 if (MEM_P (operands[1]))
6523 rtx offset = const0_rtx;
6524 rtx reg = gen_reg_rtx (SImode);
6526 if ((REG_P (base = XEXP (operands[1], 0))
6527 || (GET_CODE (base) == PLUS
6528 && (CONST_INT_P (offset = XEXP (base, 1)))
6529 && ((INTVAL(offset) & 1) != 1)
6530 && REG_P (base = XEXP (base, 0))))
6531 && REGNO_POINTER_ALIGN (REGNO (base)) >= 32)
6535 new_rtx = widen_memory_access (operands[1], SImode,
6536 ((INTVAL (offset) & ~3)
6537 - INTVAL (offset)));
6538 emit_insn (gen_movsi (reg, new_rtx));
6539 if (((INTVAL (offset) & 2) != 0)
6540 ^ (BYTES_BIG_ENDIAN ? 1 : 0))
6542 rtx reg2 = gen_reg_rtx (SImode);
6544 emit_insn (gen_lshrsi3 (reg2, reg, GEN_INT (16)));
6549 emit_insn (gen_movhi_bytes (reg, operands[1]));
6551 operands[1] = gen_lowpart (HImode, reg);
6555 /* Handle loading a large integer during reload. */
6556 else if (CONST_INT_P (operands[1])
6557 && !const_ok_for_arm (INTVAL (operands[1]))
6558 && !const_ok_for_arm (~INTVAL (operands[1])))
6560 /* Writing a constant to memory needs a scratch, which should
6561 be handled with SECONDARY_RELOADs. */
6562 gcc_assert (REG_P (operands[0]));
6564 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
6565 emit_insn (gen_movsi (operands[0], operands[1]));
6569 else if (TARGET_THUMB2)
6571 /* Thumb-2 can do everything except mem=mem and mem=const easily. */
6572 if (can_create_pseudo_p ())
6574 if (!REG_P (operands[0]))
6575 operands[1] = force_reg (HImode, operands[1]);
6576 /* Zero extend a constant, and keep it in an SImode reg. */
6577 else if (CONST_INT_P (operands[1]))
6579 rtx reg = gen_reg_rtx (SImode);
6580 HOST_WIDE_INT val = INTVAL (operands[1]) & 0xffff;
6582 emit_insn (gen_movsi (reg, GEN_INT (val)));
6583 operands[1] = gen_lowpart (HImode, reg);
6587 else /* TARGET_THUMB1 */
6589 if (can_create_pseudo_p ())
6591 if (CONST_INT_P (operands[1]))
6593 rtx reg = gen_reg_rtx (SImode);
6595 emit_insn (gen_movsi (reg, operands[1]));
6596 operands[1] = gen_lowpart (HImode, reg);
6599 /* ??? We shouldn't really get invalid addresses here, but this can
6600 happen if we are passed a SP (never OK for HImode/QImode) or
6601 virtual register (also rejected as illegitimate for HImode/QImode)
6602 relative address. */
6603 /* ??? This should perhaps be fixed elsewhere, for instance, in
6604 fixup_stack_1, by checking for other kinds of invalid addresses,
6605 e.g. a bare reference to a virtual register. This may confuse the
6606 alpha though, which must handle this case differently. */
6607 if (MEM_P (operands[0])
6608 && !memory_address_p (GET_MODE (operands[0]),
6609 XEXP (operands[0], 0)))
6611 = replace_equiv_address (operands[0],
6612 copy_to_reg (XEXP (operands[0], 0)));
6614 if (MEM_P (operands[1])
6615 && !memory_address_p (GET_MODE (operands[1]),
6616 XEXP (operands[1], 0)))
6618 = replace_equiv_address (operands[1],
6619 copy_to_reg (XEXP (operands[1], 0)));
6621 if (MEM_P (operands[1]) && optimize > 0)
6623 rtx reg = gen_reg_rtx (SImode);
6625 emit_insn (gen_zero_extendhisi2 (reg, operands[1]));
6626 operands[1] = gen_lowpart (HImode, reg);
6629 if (MEM_P (operands[0]))
6630 operands[1] = force_reg (HImode, operands[1]);
6632 else if (CONST_INT_P (operands[1])
6633 && !satisfies_constraint_I (operands[1]))
6635 /* Handle loading a large integer during reload. */
6637 /* Writing a constant to memory needs a scratch, which should
6638 be handled with SECONDARY_RELOADs. */
6639 gcc_assert (REG_P (operands[0]));
6641 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
6642 emit_insn (gen_movsi (operands[0], operands[1]));
6649 (define_expand "movhi_bytes"
6650 [(set (match_dup 2) (zero_extend:SI (match_operand:HI 1 "" "")))
6652 (zero_extend:SI (match_dup 6)))
6653 (set (match_operand:SI 0 "" "")
6654 (ior:SI (ashift:SI (match_dup 4) (const_int 8)) (match_dup 5)))]
6659 rtx addr = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
6661 mem1 = change_address (operands[1], QImode, addr);
6662 mem2 = change_address (operands[1], QImode,
6663 plus_constant (Pmode, addr, 1));
6664 operands[0] = gen_lowpart (SImode, operands[0]);
6666 operands[2] = gen_reg_rtx (SImode);
6667 operands[3] = gen_reg_rtx (SImode);
6670 if (BYTES_BIG_ENDIAN)
6672 operands[4] = operands[2];
6673 operands[5] = operands[3];
6677 operands[4] = operands[3];
6678 operands[5] = operands[2];
6683 (define_expand "movhi_bigend"
6685 (rotate:SI (subreg:SI (match_operand:HI 1 "memory_operand" "") 0)
6688 (ashiftrt:SI (match_dup 2) (const_int 16)))
6689 (set (match_operand:HI 0 "s_register_operand" "")
6693 operands[2] = gen_reg_rtx (SImode);
6694 operands[3] = gen_reg_rtx (SImode);
6695 operands[4] = gen_lowpart (HImode, operands[3]);
6699 ;; Pattern to recognize insn generated default case above
6700 (define_insn "*movhi_insn_arch4"
6701 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m,r")
6702 (match_operand:HI 1 "general_operand" "rIk,K,n,r,mi"))]
6704 && arm_arch4 && !(TARGET_HARD_FLOAT && TARGET_VFP)
6705 && (register_operand (operands[0], HImode)
6706 || register_operand (operands[1], HImode))"
6708 mov%?\\t%0, %1\\t%@ movhi
6709 mvn%?\\t%0, #%B1\\t%@ movhi
6710 movw%?\\t%0, %L1\\t%@ movhi
6711 strh%?\\t%1, %0\\t%@ movhi
6712 ldrh%?\\t%0, %1\\t%@ movhi"
6713 [(set_attr "predicable" "yes")
6714 (set_attr "pool_range" "*,*,*,*,256")
6715 (set_attr "neg_pool_range" "*,*,*,*,244")
6716 (set_attr "arch" "*,*,v6t2,*,*")
6717 (set_attr_alternative "type"
6718 [(if_then_else (match_operand 1 "const_int_operand" "")
6719 (const_string "mov_imm" )
6720 (const_string "mov_reg"))
6721 (const_string "mvn_imm")
6722 (const_string "mov_imm")
6723 (const_string "store1")
6724 (const_string "load1")])]
6727 (define_insn "*movhi_bytes"
6728 [(set (match_operand:HI 0 "s_register_operand" "=r,r,r")
6729 (match_operand:HI 1 "arm_rhs_operand" "I,rk,K"))]
6730 "TARGET_ARM && !(TARGET_HARD_FLOAT && TARGET_VFP)"
6732 mov%?\\t%0, %1\\t%@ movhi
6733 mov%?\\t%0, %1\\t%@ movhi
6734 mvn%?\\t%0, #%B1\\t%@ movhi"
6735 [(set_attr "predicable" "yes")
6736 (set_attr "type" "mov_imm,mov_reg,mvn_imm")]
6739 ;; We use a DImode scratch because we may occasionally need an additional
6740 ;; temporary if the address isn't offsettable -- push_reload doesn't seem
6741 ;; to take any notice of the "o" constraints on reload_memory_operand operand.
6742 (define_expand "reload_outhi"
6743 [(parallel [(match_operand:HI 0 "arm_reload_memory_operand" "=o")
6744 (match_operand:HI 1 "s_register_operand" "r")
6745 (match_operand:DI 2 "s_register_operand" "=&l")])]
6748 arm_reload_out_hi (operands);
6750 thumb_reload_out_hi (operands);
6755 (define_expand "reload_inhi"
6756 [(parallel [(match_operand:HI 0 "s_register_operand" "=r")
6757 (match_operand:HI 1 "arm_reload_memory_operand" "o")
6758 (match_operand:DI 2 "s_register_operand" "=&r")])]
6762 arm_reload_in_hi (operands);
6764 thumb_reload_out_hi (operands);
6768 (define_expand "movqi"
6769 [(set (match_operand:QI 0 "general_operand" "")
6770 (match_operand:QI 1 "general_operand" ""))]
6773 /* Everything except mem = const or mem = mem can be done easily */
6775 if (can_create_pseudo_p ())
6777 if (CONST_INT_P (operands[1]))
6779 rtx reg = gen_reg_rtx (SImode);
6781 /* For thumb we want an unsigned immediate, then we are more likely
6782 to be able to use a movs insn. */
6784 operands[1] = GEN_INT (INTVAL (operands[1]) & 255);
6786 emit_insn (gen_movsi (reg, operands[1]));
6787 operands[1] = gen_lowpart (QImode, reg);
6792 /* ??? We shouldn't really get invalid addresses here, but this can
6793 happen if we are passed a SP (never OK for HImode/QImode) or
6794 virtual register (also rejected as illegitimate for HImode/QImode)
6795 relative address. */
6796 /* ??? This should perhaps be fixed elsewhere, for instance, in
6797 fixup_stack_1, by checking for other kinds of invalid addresses,
6798 e.g. a bare reference to a virtual register. This may confuse the
6799 alpha though, which must handle this case differently. */
6800 if (MEM_P (operands[0])
6801 && !memory_address_p (GET_MODE (operands[0]),
6802 XEXP (operands[0], 0)))
6804 = replace_equiv_address (operands[0],
6805 copy_to_reg (XEXP (operands[0], 0)));
6806 if (MEM_P (operands[1])
6807 && !memory_address_p (GET_MODE (operands[1]),
6808 XEXP (operands[1], 0)))
6810 = replace_equiv_address (operands[1],
6811 copy_to_reg (XEXP (operands[1], 0)));
6814 if (MEM_P (operands[1]) && optimize > 0)
6816 rtx reg = gen_reg_rtx (SImode);
6818 emit_insn (gen_zero_extendqisi2 (reg, operands[1]));
6819 operands[1] = gen_lowpart (QImode, reg);
6822 if (MEM_P (operands[0]))
6823 operands[1] = force_reg (QImode, operands[1]);
6825 else if (TARGET_THUMB
6826 && CONST_INT_P (operands[1])
6827 && !satisfies_constraint_I (operands[1]))
6829 /* Handle loading a large integer during reload. */
6831 /* Writing a constant to memory needs a scratch, which should
6832 be handled with SECONDARY_RELOADs. */
6833 gcc_assert (REG_P (operands[0]));
6835 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
6836 emit_insn (gen_movsi (operands[0], operands[1]));
6842 (define_insn "*arm_movqi_insn"
6843 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,r,l,r,l,Uu,r,m")
6844 (match_operand:QI 1 "general_operand" "rk,rk,I,Py,K,Uu,l,Uh,r"))]
6846 && ( register_operand (operands[0], QImode)
6847 || register_operand (operands[1], QImode))"
6858 [(set_attr "type" "mov_reg,mov_reg,mov_imm,mov_imm,mvn_imm,load1,store1,load1,store1")
6859 (set_attr "predicable" "yes")
6860 (set_attr "predicable_short_it" "yes,yes,no,yes,no,no,no,no,no")
6861 (set_attr "arch" "t2,any,any,t2,any,t2,t2,any,any")
6862 (set_attr "length" "2,4,4,2,4,2,2,4,4")]
6866 (define_expand "movhf"
6867 [(set (match_operand:HF 0 "general_operand" "")
6868 (match_operand:HF 1 "general_operand" ""))]
6873 if (MEM_P (operands[0]))
6874 operands[1] = force_reg (HFmode, operands[1]);
6876 else /* TARGET_THUMB1 */
6878 if (can_create_pseudo_p ())
6880 if (!REG_P (operands[0]))
6881 operands[1] = force_reg (HFmode, operands[1]);
6887 (define_insn "*arm32_movhf"
6888 [(set (match_operand:HF 0 "nonimmediate_operand" "=r,m,r,r")
6889 (match_operand:HF 1 "general_operand" " m,r,r,F"))]
6890 "TARGET_32BIT && !(TARGET_HARD_FLOAT && TARGET_VFP)
6891 && ( s_register_operand (operands[0], HFmode)
6892 || s_register_operand (operands[1], HFmode))"
6894 switch (which_alternative)
6896 case 0: /* ARM register from memory */
6897 return \"ldrh%?\\t%0, %1\\t%@ __fp16\";
6898 case 1: /* memory from ARM register */
6899 return \"strh%?\\t%1, %0\\t%@ __fp16\";
6900 case 2: /* ARM register from ARM register */
6901 return \"mov%?\\t%0, %1\\t%@ __fp16\";
6902 case 3: /* ARM register from constant */
6907 bits = real_to_target (NULL, CONST_DOUBLE_REAL_VALUE (operands[1]),
6909 ops[0] = operands[0];
6910 ops[1] = GEN_INT (bits);
6911 ops[2] = GEN_INT (bits & 0xff00);
6912 ops[3] = GEN_INT (bits & 0x00ff);
6914 if (arm_arch_thumb2)
6915 output_asm_insn (\"movw%?\\t%0, %1\", ops);
6917 output_asm_insn (\"mov%?\\t%0, %2\;orr%?\\t%0, %0, %3\", ops);
6924 [(set_attr "conds" "unconditional")
6925 (set_attr "type" "load1,store1,mov_reg,multiple")
6926 (set_attr "length" "4,4,4,8")
6927 (set_attr "predicable" "yes")
6928 (set_attr "predicable_short_it" "no")]
6931 (define_expand "movsf"
6932 [(set (match_operand:SF 0 "general_operand" "")
6933 (match_operand:SF 1 "general_operand" ""))]
6938 if (MEM_P (operands[0]))
6939 operands[1] = force_reg (SFmode, operands[1]);
6941 else /* TARGET_THUMB1 */
6943 if (can_create_pseudo_p ())
6945 if (!REG_P (operands[0]))
6946 operands[1] = force_reg (SFmode, operands[1]);
6952 ;; Transform a floating-point move of a constant into a core register into
6953 ;; an SImode operation.
6955 [(set (match_operand:SF 0 "arm_general_register_operand" "")
6956 (match_operand:SF 1 "immediate_operand" ""))]
6959 && CONST_DOUBLE_P (operands[1])"
6960 [(set (match_dup 2) (match_dup 3))]
6962 operands[2] = gen_lowpart (SImode, operands[0]);
6963 operands[3] = gen_lowpart (SImode, operands[1]);
6964 if (operands[2] == 0 || operands[3] == 0)
6969 (define_insn "*arm_movsf_soft_insn"
6970 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,m")
6971 (match_operand:SF 1 "general_operand" "r,mE,r"))]
6973 && TARGET_SOFT_FLOAT
6974 && (!MEM_P (operands[0])
6975 || register_operand (operands[1], SFmode))"
6978 ldr%?\\t%0, %1\\t%@ float
6979 str%?\\t%1, %0\\t%@ float"
6980 [(set_attr "predicable" "yes")
6981 (set_attr "predicable_short_it" "no")
6982 (set_attr "type" "mov_reg,load1,store1")
6983 (set_attr "arm_pool_range" "*,4096,*")
6984 (set_attr "thumb2_pool_range" "*,4094,*")
6985 (set_attr "arm_neg_pool_range" "*,4084,*")
6986 (set_attr "thumb2_neg_pool_range" "*,0,*")]
6989 (define_expand "movdf"
6990 [(set (match_operand:DF 0 "general_operand" "")
6991 (match_operand:DF 1 "general_operand" ""))]
6996 if (MEM_P (operands[0]))
6997 operands[1] = force_reg (DFmode, operands[1]);
6999 else /* TARGET_THUMB */
7001 if (can_create_pseudo_p ())
7003 if (!REG_P (operands[0]))
7004 operands[1] = force_reg (DFmode, operands[1]);
7010 ;; Reloading a df mode value stored in integer regs to memory can require a
7012 (define_expand "reload_outdf"
7013 [(match_operand:DF 0 "arm_reload_memory_operand" "=o")
7014 (match_operand:DF 1 "s_register_operand" "r")
7015 (match_operand:SI 2 "s_register_operand" "=&r")]
7019 enum rtx_code code = GET_CODE (XEXP (operands[0], 0));
7022 operands[2] = XEXP (operands[0], 0);
7023 else if (code == POST_INC || code == PRE_DEC)
7025 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7026 operands[1] = gen_rtx_SUBREG (DImode, operands[1], 0);
7027 emit_insn (gen_movdi (operands[0], operands[1]));
7030 else if (code == PRE_INC)
7032 rtx reg = XEXP (XEXP (operands[0], 0), 0);
7034 emit_insn (gen_addsi3 (reg, reg, GEN_INT (8)));
7037 else if (code == POST_DEC)
7038 operands[2] = XEXP (XEXP (operands[0], 0), 0);
7040 emit_insn (gen_addsi3 (operands[2], XEXP (XEXP (operands[0], 0), 0),
7041 XEXP (XEXP (operands[0], 0), 1)));
7043 emit_insn (gen_rtx_SET (replace_equiv_address (operands[0], operands[2]),
7046 if (code == POST_DEC)
7047 emit_insn (gen_addsi3 (operands[2], operands[2], GEN_INT (-8)));
7053 (define_insn "*movdf_soft_insn"
7054 [(set (match_operand:DF 0 "nonimmediate_soft_df_operand" "=r,r,r,q,m")
7055 (match_operand:DF 1 "soft_df_operand" "rDa,Db,Dc,mF,q"))]
7056 "TARGET_32BIT && TARGET_SOFT_FLOAT
7057 && ( register_operand (operands[0], DFmode)
7058 || register_operand (operands[1], DFmode))"
7060 switch (which_alternative)
7067 return output_move_double (operands, true, NULL);
7070 [(set_attr "length" "8,12,16,8,8")
7071 (set_attr "type" "multiple,multiple,multiple,load2,store2")
7072 (set_attr "arm_pool_range" "*,*,*,1020,*")
7073 (set_attr "thumb2_pool_range" "*,*,*,1018,*")
7074 (set_attr "arm_neg_pool_range" "*,*,*,1004,*")
7075 (set_attr "thumb2_neg_pool_range" "*,*,*,0,*")]
7079 ;; load- and store-multiple insns
7080 ;; The arm can load/store any set of registers, provided that they are in
7081 ;; ascending order, but these expanders assume a contiguous set.
7083 (define_expand "load_multiple"
7084 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
7085 (match_operand:SI 1 "" ""))
7086 (use (match_operand:SI 2 "" ""))])]
7089 HOST_WIDE_INT offset = 0;
7091 /* Support only fixed point registers. */
7092 if (!CONST_INT_P (operands[2])
7093 || INTVAL (operands[2]) > MAX_LDM_STM_OPS
7094 || INTVAL (operands[2]) < 2
7095 || !MEM_P (operands[1])
7096 || !REG_P (operands[0])
7097 || REGNO (operands[0]) > (LAST_ARM_REGNUM - 1)
7098 || REGNO (operands[0]) + INTVAL (operands[2]) > LAST_ARM_REGNUM)
7102 = arm_gen_load_multiple (arm_regs_in_sequence + REGNO (operands[0]),
7103 INTVAL (operands[2]),
7104 force_reg (SImode, XEXP (operands[1], 0)),
7105 FALSE, operands[1], &offset);
7108 (define_expand "store_multiple"
7109 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
7110 (match_operand:SI 1 "" ""))
7111 (use (match_operand:SI 2 "" ""))])]
7114 HOST_WIDE_INT offset = 0;
7116 /* Support only fixed point registers. */
7117 if (!CONST_INT_P (operands[2])
7118 || INTVAL (operands[2]) > MAX_LDM_STM_OPS
7119 || INTVAL (operands[2]) < 2
7120 || !REG_P (operands[1])
7121 || !MEM_P (operands[0])
7122 || REGNO (operands[1]) > (LAST_ARM_REGNUM - 1)
7123 || REGNO (operands[1]) + INTVAL (operands[2]) > LAST_ARM_REGNUM)
7127 = arm_gen_store_multiple (arm_regs_in_sequence + REGNO (operands[1]),
7128 INTVAL (operands[2]),
7129 force_reg (SImode, XEXP (operands[0], 0)),
7130 FALSE, operands[0], &offset);
7134 (define_expand "setmemsi"
7135 [(match_operand:BLK 0 "general_operand" "")
7136 (match_operand:SI 1 "const_int_operand" "")
7137 (match_operand:SI 2 "const_int_operand" "")
7138 (match_operand:SI 3 "const_int_operand" "")]
7141 if (arm_gen_setmem (operands))
7148 ;; Move a block of memory if it is word aligned and MORE than 2 words long.
7149 ;; We could let this apply for blocks of less than this, but it clobbers so
7150 ;; many registers that there is then probably a better way.
7152 (define_expand "movmemqi"
7153 [(match_operand:BLK 0 "general_operand" "")
7154 (match_operand:BLK 1 "general_operand" "")
7155 (match_operand:SI 2 "const_int_operand" "")
7156 (match_operand:SI 3 "const_int_operand" "")]
7161 if (TARGET_LDRD && current_tune->prefer_ldrd_strd
7162 && !optimize_function_for_size_p (cfun))
7164 if (gen_movmem_ldrd_strd (operands))
7169 if (arm_gen_movmemqi (operands))
7173 else /* TARGET_THUMB1 */
7175 if ( INTVAL (operands[3]) != 4
7176 || INTVAL (operands[2]) > 48)
7179 thumb_expand_movmemqi (operands);
7186 ;; Compare & branch insns
7187 ;; The range calculations are based as follows:
7188 ;; For forward branches, the address calculation returns the address of
7189 ;; the next instruction. This is 2 beyond the branch instruction.
7190 ;; For backward branches, the address calculation returns the address of
7191 ;; the first instruction in this pattern (cmp). This is 2 before the branch
7192 ;; instruction for the shortest sequence, and 4 before the branch instruction
7193 ;; if we have to jump around an unconditional branch.
7194 ;; To the basic branch range the PC offset must be added (this is +4).
7195 ;; So for forward branches we have
7196 ;; (pos_range - pos_base_offs + pc_offs) = (pos_range - 2 + 4).
7197 ;; And for backward branches we have
7198 ;; (neg_range - neg_base_offs + pc_offs) = (neg_range - (-2 or -4) + 4).
7200 ;; For a 'b' pos_range = 2046, neg_range = -2048 giving (-2040->2048).
7201 ;; For a 'b<cond>' pos_range = 254, neg_range = -256 giving (-250 ->256).
7203 (define_expand "cbranchsi4"
7204 [(set (pc) (if_then_else
7205 (match_operator 0 "expandable_comparison_operator"
7206 [(match_operand:SI 1 "s_register_operand" "")
7207 (match_operand:SI 2 "nonmemory_operand" "")])
7208 (label_ref (match_operand 3 "" ""))
7214 if (!arm_validize_comparison (&operands[0], &operands[1], &operands[2]))
7216 emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
7220 if (thumb1_cmpneg_operand (operands[2], SImode))
7222 emit_jump_insn (gen_cbranchsi4_scratch (NULL, operands[1], operands[2],
7223 operands[3], operands[0]));
7226 if (!thumb1_cmp_operand (operands[2], SImode))
7227 operands[2] = force_reg (SImode, operands[2]);
7230 (define_expand "cbranchsf4"
7231 [(set (pc) (if_then_else
7232 (match_operator 0 "expandable_comparison_operator"
7233 [(match_operand:SF 1 "s_register_operand" "")
7234 (match_operand:SF 2 "arm_float_compare_operand" "")])
7235 (label_ref (match_operand 3 "" ""))
7237 "TARGET_32BIT && TARGET_HARD_FLOAT"
7238 "emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
7239 operands[3])); DONE;"
7242 (define_expand "cbranchdf4"
7243 [(set (pc) (if_then_else
7244 (match_operator 0 "expandable_comparison_operator"
7245 [(match_operand:DF 1 "s_register_operand" "")
7246 (match_operand:DF 2 "arm_float_compare_operand" "")])
7247 (label_ref (match_operand 3 "" ""))
7249 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
7250 "emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
7251 operands[3])); DONE;"
7254 (define_expand "cbranchdi4"
7255 [(set (pc) (if_then_else
7256 (match_operator 0 "expandable_comparison_operator"
7257 [(match_operand:DI 1 "s_register_operand" "")
7258 (match_operand:DI 2 "cmpdi_operand" "")])
7259 (label_ref (match_operand 3 "" ""))
7263 if (!arm_validize_comparison (&operands[0], &operands[1], &operands[2]))
7265 emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
7271 ;; Comparison and test insns
7273 (define_insn "*arm_cmpsi_insn"
7274 [(set (reg:CC CC_REGNUM)
7275 (compare:CC (match_operand:SI 0 "s_register_operand" "l,r,r,r,r")
7276 (match_operand:SI 1 "arm_add_operand" "Py,r,r,I,L")))]
7284 [(set_attr "conds" "set")
7285 (set_attr "arch" "t2,t2,any,any,any")
7286 (set_attr "length" "2,2,4,4,4")
7287 (set_attr "predicable" "yes")
7288 (set_attr "predicable_short_it" "yes,yes,yes,no,no")
7289 (set_attr "type" "alus_imm,alus_sreg,alus_sreg,alus_imm,alus_imm")]
7292 (define_insn "*cmpsi_shiftsi"
7293 [(set (reg:CC CC_REGNUM)
7294 (compare:CC (match_operand:SI 0 "s_register_operand" "r,r,r")
7295 (match_operator:SI 3 "shift_operator"
7296 [(match_operand:SI 1 "s_register_operand" "r,r,r")
7297 (match_operand:SI 2 "shift_amount_operand" "M,r,M")])))]
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 "*cmpsi_shiftsi_swp"
7306 [(set (reg:CC_SWP CC_REGNUM)
7307 (compare:CC_SWP (match_operator:SI 3 "shift_operator"
7308 [(match_operand:SI 1 "s_register_operand" "r,r,r")
7309 (match_operand:SI 2 "shift_amount_operand" "M,r,M")])
7310 (match_operand:SI 0 "s_register_operand" "r,r,r")))]
7313 [(set_attr "conds" "set")
7314 (set_attr "shift" "1")
7315 (set_attr "arch" "32,a,a")
7316 (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
7318 (define_insn "*arm_cmpsi_negshiftsi_si"
7319 [(set (reg:CC_Z CC_REGNUM)
7321 (neg:SI (match_operator:SI 1 "shift_operator"
7322 [(match_operand:SI 2 "s_register_operand" "r")
7323 (match_operand:SI 3 "reg_or_int_operand" "rM")]))
7324 (match_operand:SI 0 "s_register_operand" "r")))]
7327 [(set_attr "conds" "set")
7328 (set (attr "type") (if_then_else (match_operand 3 "const_int_operand" "")
7329 (const_string "alus_shift_imm")
7330 (const_string "alus_shift_reg")))
7331 (set_attr "predicable" "yes")]
7334 ;; DImode comparisons. The generic code generates branches that
7335 ;; if-conversion can not reduce to a conditional compare, so we do
7338 (define_insn_and_split "*arm_cmpdi_insn"
7339 [(set (reg:CC_NCV CC_REGNUM)
7340 (compare:CC_NCV (match_operand:DI 0 "s_register_operand" "r")
7341 (match_operand:DI 1 "arm_di_operand" "rDi")))
7342 (clobber (match_scratch:SI 2 "=r"))]
7344 "#" ; "cmp\\t%Q0, %Q1\;sbcs\\t%2, %R0, %R1"
7345 "&& reload_completed"
7346 [(set (reg:CC CC_REGNUM)
7347 (compare:CC (match_dup 0) (match_dup 1)))
7348 (parallel [(set (reg:CC CC_REGNUM)
7349 (compare:CC (match_dup 3) (match_dup 4)))
7351 (minus:SI (match_dup 5)
7352 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))])]
7354 operands[3] = gen_highpart (SImode, operands[0]);
7355 operands[0] = gen_lowpart (SImode, operands[0]);
7356 if (CONST_INT_P (operands[1]))
7358 operands[4] = GEN_INT (~INTVAL (gen_highpart_mode (SImode,
7361 operands[5] = gen_rtx_PLUS (SImode, operands[3], operands[4]);
7365 operands[4] = gen_highpart (SImode, operands[1]);
7366 operands[5] = gen_rtx_MINUS (SImode, operands[3], operands[4]);
7368 operands[1] = gen_lowpart (SImode, operands[1]);
7369 operands[2] = gen_lowpart (SImode, operands[2]);
7371 [(set_attr "conds" "set")
7372 (set_attr "length" "8")
7373 (set_attr "type" "multiple")]
7376 (define_insn_and_split "*arm_cmpdi_unsigned"
7377 [(set (reg:CC_CZ CC_REGNUM)
7378 (compare:CC_CZ (match_operand:DI 0 "s_register_operand" "l,r,r,r")
7379 (match_operand:DI 1 "arm_di_operand" "Py,r,Di,rDi")))]
7382 "#" ; "cmp\\t%R0, %R1\;it eq\;cmpeq\\t%Q0, %Q1"
7383 "&& reload_completed"
7384 [(set (reg:CC CC_REGNUM)
7385 (compare:CC (match_dup 2) (match_dup 3)))
7386 (cond_exec (eq:SI (reg:CC CC_REGNUM) (const_int 0))
7387 (set (reg:CC CC_REGNUM)
7388 (compare:CC (match_dup 0) (match_dup 1))))]
7390 operands[2] = gen_highpart (SImode, operands[0]);
7391 operands[0] = gen_lowpart (SImode, operands[0]);
7392 if (CONST_INT_P (operands[1]))
7393 operands[3] = gen_highpart_mode (SImode, DImode, operands[1]);
7395 operands[3] = gen_highpart (SImode, operands[1]);
7396 operands[1] = gen_lowpart (SImode, operands[1]);
7398 [(set_attr "conds" "set")
7399 (set_attr "enabled_for_depr_it" "yes,yes,no,*")
7400 (set_attr "arch" "t2,t2,t2,a")
7401 (set_attr "length" "6,6,10,8")
7402 (set_attr "type" "multiple")]
7405 (define_insn "*arm_cmpdi_zero"
7406 [(set (reg:CC_Z CC_REGNUM)
7407 (compare:CC_Z (match_operand:DI 0 "s_register_operand" "r")
7409 (clobber (match_scratch:SI 1 "=r"))]
7411 "orrs%?\\t%1, %Q0, %R0"
7412 [(set_attr "conds" "set")
7413 (set_attr "type" "logics_reg")]
7416 ; This insn allows redundant compares to be removed by cse, nothing should
7417 ; ever appear in the output file since (set (reg x) (reg x)) is a no-op that
7418 ; is deleted later on. The match_dup will match the mode here, so that
7419 ; mode changes of the condition codes aren't lost by this even though we don't
7420 ; specify what they are.
7422 (define_insn "*deleted_compare"
7423 [(set (match_operand 0 "cc_register" "") (match_dup 0))]
7425 "\\t%@ deleted compare"
7426 [(set_attr "conds" "set")
7427 (set_attr "length" "0")
7428 (set_attr "type" "no_insn")]
7432 ;; Conditional branch insns
7434 (define_expand "cbranch_cc"
7436 (if_then_else (match_operator 0 "" [(match_operand 1 "" "")
7437 (match_operand 2 "" "")])
7438 (label_ref (match_operand 3 "" ""))
7441 "operands[1] = arm_gen_compare_reg (GET_CODE (operands[0]),
7442 operands[1], operands[2], NULL_RTX);
7443 operands[2] = const0_rtx;"
7447 ;; Patterns to match conditional branch insns.
7450 (define_insn "arm_cond_branch"
7452 (if_then_else (match_operator 1 "arm_comparison_operator"
7453 [(match_operand 2 "cc_register" "") (const_int 0)])
7454 (label_ref (match_operand 0 "" ""))
7458 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
7460 arm_ccfsm_state += 2;
7463 return \"b%d1\\t%l0\";
7465 [(set_attr "conds" "use")
7466 (set_attr "type" "branch")
7467 (set (attr "length")
7469 (and (match_test "TARGET_THUMB2")
7470 (and (ge (minus (match_dup 0) (pc)) (const_int -250))
7471 (le (minus (match_dup 0) (pc)) (const_int 256))))
7476 (define_insn "*arm_cond_branch_reversed"
7478 (if_then_else (match_operator 1 "arm_comparison_operator"
7479 [(match_operand 2 "cc_register" "") (const_int 0)])
7481 (label_ref (match_operand 0 "" ""))))]
7484 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
7486 arm_ccfsm_state += 2;
7489 return \"b%D1\\t%l0\";
7491 [(set_attr "conds" "use")
7492 (set_attr "type" "branch")
7493 (set (attr "length")
7495 (and (match_test "TARGET_THUMB2")
7496 (and (ge (minus (match_dup 0) (pc)) (const_int -250))
7497 (le (minus (match_dup 0) (pc)) (const_int 256))))
7506 (define_expand "cstore_cc"
7507 [(set (match_operand:SI 0 "s_register_operand" "")
7508 (match_operator:SI 1 "" [(match_operand 2 "" "")
7509 (match_operand 3 "" "")]))]
7511 "operands[2] = arm_gen_compare_reg (GET_CODE (operands[1]),
7512 operands[2], operands[3], NULL_RTX);
7513 operands[3] = const0_rtx;"
7516 (define_insn_and_split "*mov_scc"
7517 [(set (match_operand:SI 0 "s_register_operand" "=r")
7518 (match_operator:SI 1 "arm_comparison_operator_mode"
7519 [(match_operand 2 "cc_register" "") (const_int 0)]))]
7521 "#" ; "mov%D1\\t%0, #0\;mov%d1\\t%0, #1"
7524 (if_then_else:SI (match_dup 1)
7528 [(set_attr "conds" "use")
7529 (set_attr "length" "8")
7530 (set_attr "type" "multiple")]
7533 (define_insn_and_split "*mov_negscc"
7534 [(set (match_operand:SI 0 "s_register_operand" "=r")
7535 (neg:SI (match_operator:SI 1 "arm_comparison_operator_mode"
7536 [(match_operand 2 "cc_register" "") (const_int 0)])))]
7538 "#" ; "mov%D1\\t%0, #0\;mvn%d1\\t%0, #0"
7541 (if_then_else:SI (match_dup 1)
7545 operands[3] = GEN_INT (~0);
7547 [(set_attr "conds" "use")
7548 (set_attr "length" "8")
7549 (set_attr "type" "multiple")]
7552 (define_insn_and_split "*mov_notscc"
7553 [(set (match_operand:SI 0 "s_register_operand" "=r")
7554 (not:SI (match_operator:SI 1 "arm_comparison_operator"
7555 [(match_operand 2 "cc_register" "") (const_int 0)])))]
7557 "#" ; "mvn%D1\\t%0, #0\;mvn%d1\\t%0, #1"
7560 (if_then_else:SI (match_dup 1)
7564 operands[3] = GEN_INT (~1);
7565 operands[4] = GEN_INT (~0);
7567 [(set_attr "conds" "use")
7568 (set_attr "length" "8")
7569 (set_attr "type" "multiple")]
7572 (define_expand "cstoresi4"
7573 [(set (match_operand:SI 0 "s_register_operand" "")
7574 (match_operator:SI 1 "expandable_comparison_operator"
7575 [(match_operand:SI 2 "s_register_operand" "")
7576 (match_operand:SI 3 "reg_or_int_operand" "")]))]
7577 "TARGET_32BIT || TARGET_THUMB1"
7579 rtx op3, scratch, scratch2;
7583 if (!arm_add_operand (operands[3], SImode))
7584 operands[3] = force_reg (SImode, operands[3]);
7585 emit_insn (gen_cstore_cc (operands[0], operands[1],
7586 operands[2], operands[3]));
7590 if (operands[3] == const0_rtx)
7592 switch (GET_CODE (operands[1]))
7595 emit_insn (gen_cstoresi_eq0_thumb1 (operands[0], operands[2]));
7599 emit_insn (gen_cstoresi_ne0_thumb1 (operands[0], operands[2]));
7603 scratch = expand_binop (SImode, add_optab, operands[2], constm1_rtx,
7604 NULL_RTX, 0, OPTAB_WIDEN);
7605 scratch = expand_binop (SImode, ior_optab, operands[2], scratch,
7606 NULL_RTX, 0, OPTAB_WIDEN);
7607 expand_binop (SImode, lshr_optab, scratch, GEN_INT (31),
7608 operands[0], 1, OPTAB_WIDEN);
7612 scratch = expand_unop (SImode, one_cmpl_optab, operands[2],
7614 expand_binop (SImode, lshr_optab, scratch, GEN_INT (31),
7615 NULL_RTX, 1, OPTAB_WIDEN);
7619 scratch = expand_binop (SImode, ashr_optab, operands[2],
7620 GEN_INT (31), NULL_RTX, 0, OPTAB_WIDEN);
7621 scratch = expand_binop (SImode, sub_optab, scratch, operands[2],
7622 NULL_RTX, 0, OPTAB_WIDEN);
7623 expand_binop (SImode, lshr_optab, scratch, GEN_INT (31), operands[0],
7627 /* LT is handled by generic code. No need for unsigned with 0. */
7634 switch (GET_CODE (operands[1]))
7637 scratch = expand_binop (SImode, sub_optab, operands[2], operands[3],
7638 NULL_RTX, 0, OPTAB_WIDEN);
7639 emit_insn (gen_cstoresi_eq0_thumb1 (operands[0], scratch));
7643 scratch = expand_binop (SImode, sub_optab, operands[2], operands[3],
7644 NULL_RTX, 0, OPTAB_WIDEN);
7645 emit_insn (gen_cstoresi_ne0_thumb1 (operands[0], scratch));
7649 op3 = force_reg (SImode, operands[3]);
7651 scratch = expand_binop (SImode, lshr_optab, operands[2], GEN_INT (31),
7652 NULL_RTX, 1, OPTAB_WIDEN);
7653 scratch2 = expand_binop (SImode, ashr_optab, op3, GEN_INT (31),
7654 NULL_RTX, 0, OPTAB_WIDEN);
7655 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch2,
7661 if (!thumb1_cmp_operand (op3, SImode))
7662 op3 = force_reg (SImode, op3);
7663 scratch = expand_binop (SImode, ashr_optab, operands[2], GEN_INT (31),
7664 NULL_RTX, 0, OPTAB_WIDEN);
7665 scratch2 = expand_binop (SImode, lshr_optab, op3, GEN_INT (31),
7666 NULL_RTX, 1, OPTAB_WIDEN);
7667 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch2,
7672 op3 = force_reg (SImode, operands[3]);
7673 scratch = force_reg (SImode, const0_rtx);
7674 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch,
7680 if (!thumb1_cmp_operand (op3, SImode))
7681 op3 = force_reg (SImode, op3);
7682 scratch = force_reg (SImode, const0_rtx);
7683 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch,
7689 if (!thumb1_cmp_operand (op3, SImode))
7690 op3 = force_reg (SImode, op3);
7691 scratch = gen_reg_rtx (SImode);
7692 emit_insn (gen_cstoresi_ltu_thumb1 (operands[0], operands[2], op3));
7696 op3 = force_reg (SImode, operands[3]);
7697 scratch = gen_reg_rtx (SImode);
7698 emit_insn (gen_cstoresi_ltu_thumb1 (operands[0], op3, operands[2]));
7701 /* No good sequences for GT, LT. */
7708 (define_expand "cstorehf4"
7709 [(set (match_operand:SI 0 "s_register_operand")
7710 (match_operator:SI 1 "expandable_comparison_operator"
7711 [(match_operand:HF 2 "s_register_operand")
7712 (match_operand:HF 3 "arm_float_compare_operand")]))]
7713 "TARGET_VFP_FP16INST"
7715 if (!arm_validize_comparison (&operands[1],
7720 emit_insn (gen_cstore_cc (operands[0], operands[1],
7721 operands[2], operands[3]));
7726 (define_expand "cstoresf4"
7727 [(set (match_operand:SI 0 "s_register_operand" "")
7728 (match_operator:SI 1 "expandable_comparison_operator"
7729 [(match_operand:SF 2 "s_register_operand" "")
7730 (match_operand:SF 3 "arm_float_compare_operand" "")]))]
7731 "TARGET_32BIT && TARGET_HARD_FLOAT"
7732 "emit_insn (gen_cstore_cc (operands[0], operands[1],
7733 operands[2], operands[3])); DONE;"
7736 (define_expand "cstoredf4"
7737 [(set (match_operand:SI 0 "s_register_operand" "")
7738 (match_operator:SI 1 "expandable_comparison_operator"
7739 [(match_operand:DF 2 "s_register_operand" "")
7740 (match_operand:DF 3 "arm_float_compare_operand" "")]))]
7741 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
7742 "emit_insn (gen_cstore_cc (operands[0], operands[1],
7743 operands[2], operands[3])); DONE;"
7746 (define_expand "cstoredi4"
7747 [(set (match_operand:SI 0 "s_register_operand" "")
7748 (match_operator:SI 1 "expandable_comparison_operator"
7749 [(match_operand:DI 2 "s_register_operand" "")
7750 (match_operand:DI 3 "cmpdi_operand" "")]))]
7753 if (!arm_validize_comparison (&operands[1],
7757 emit_insn (gen_cstore_cc (operands[0], operands[1], operands[2],
7764 ;; Conditional move insns
7766 (define_expand "movsicc"
7767 [(set (match_operand:SI 0 "s_register_operand" "")
7768 (if_then_else:SI (match_operand 1 "expandable_comparison_operator" "")
7769 (match_operand:SI 2 "arm_not_operand" "")
7770 (match_operand:SI 3 "arm_not_operand" "")))]
7777 if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
7778 &XEXP (operands[1], 1)))
7781 code = GET_CODE (operands[1]);
7782 ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
7783 XEXP (operands[1], 1), NULL_RTX);
7784 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7788 (define_expand "movhfcc"
7789 [(set (match_operand:HF 0 "s_register_operand")
7790 (if_then_else:HF (match_operand 1 "arm_cond_move_operator")
7791 (match_operand:HF 2 "s_register_operand")
7792 (match_operand:HF 3 "s_register_operand")))]
7793 "TARGET_VFP_FP16INST"
7796 enum rtx_code code = GET_CODE (operands[1]);
7799 if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
7800 &XEXP (operands[1], 1)))
7803 code = GET_CODE (operands[1]);
7804 ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
7805 XEXP (operands[1], 1), NULL_RTX);
7806 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7810 (define_expand "movsfcc"
7811 [(set (match_operand:SF 0 "s_register_operand" "")
7812 (if_then_else:SF (match_operand 1 "arm_cond_move_operator" "")
7813 (match_operand:SF 2 "s_register_operand" "")
7814 (match_operand:SF 3 "s_register_operand" "")))]
7815 "TARGET_32BIT && TARGET_HARD_FLOAT"
7818 enum rtx_code code = GET_CODE (operands[1]);
7821 if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
7822 &XEXP (operands[1], 1)))
7825 code = GET_CODE (operands[1]);
7826 ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
7827 XEXP (operands[1], 1), NULL_RTX);
7828 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7832 (define_expand "movdfcc"
7833 [(set (match_operand:DF 0 "s_register_operand" "")
7834 (if_then_else:DF (match_operand 1 "arm_cond_move_operator" "")
7835 (match_operand:DF 2 "s_register_operand" "")
7836 (match_operand:DF 3 "s_register_operand" "")))]
7837 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
7840 enum rtx_code code = GET_CODE (operands[1]);
7843 if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
7844 &XEXP (operands[1], 1)))
7846 code = GET_CODE (operands[1]);
7847 ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
7848 XEXP (operands[1], 1), NULL_RTX);
7849 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7853 (define_insn "*cmov<mode>"
7854 [(set (match_operand:SDF 0 "s_register_operand" "=<F_constraint>")
7855 (if_then_else:SDF (match_operator 1 "arm_vsel_comparison_operator"
7856 [(match_operand 2 "cc_register" "") (const_int 0)])
7857 (match_operand:SDF 3 "s_register_operand"
7859 (match_operand:SDF 4 "s_register_operand"
7860 "<F_constraint>")))]
7861 "TARGET_HARD_FLOAT && TARGET_FPU_ARMV8 <vfp_double_cond>"
7864 enum arm_cond_code code = maybe_get_arm_condition_code (operands[1]);
7871 return \"vsel%d1.<V_if_elem>\\t%<V_reg>0, %<V_reg>3, %<V_reg>4\";
7876 return \"vsel%D1.<V_if_elem>\\t%<V_reg>0, %<V_reg>4, %<V_reg>3\";
7882 [(set_attr "conds" "use")
7883 (set_attr "type" "fcsel")]
7886 (define_insn "*cmovhf"
7887 [(set (match_operand:HF 0 "s_register_operand" "=t")
7888 (if_then_else:HF (match_operator 1 "arm_vsel_comparison_operator"
7889 [(match_operand 2 "cc_register" "") (const_int 0)])
7890 (match_operand:HF 3 "s_register_operand" "t")
7891 (match_operand:HF 4 "s_register_operand" "t")))]
7892 "TARGET_VFP_FP16INST"
7895 enum arm_cond_code code = maybe_get_arm_condition_code (operands[1]);
7902 return \"vsel%d1.f16\\t%0, %3, %4\";
7907 return \"vsel%D1.f16\\t%0, %4, %3\";
7913 [(set_attr "conds" "use")
7914 (set_attr "type" "fcsel")]
7917 (define_insn_and_split "*movsicc_insn"
7918 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r,r,r,r,r")
7920 (match_operator 3 "arm_comparison_operator"
7921 [(match_operand 4 "cc_register" "") (const_int 0)])
7922 (match_operand:SI 1 "arm_not_operand" "0,0,rI,K,rI,rI,K,K")
7923 (match_operand:SI 2 "arm_not_operand" "rI,K,0,0,rI,K,rI,K")))]
7934 ; alt4: mov%d3\\t%0, %1\;mov%D3\\t%0, %2
7935 ; alt5: mov%d3\\t%0, %1\;mvn%D3\\t%0, #%B2
7936 ; alt6: mvn%d3\\t%0, #%B1\;mov%D3\\t%0, %2
7937 ; alt7: mvn%d3\\t%0, #%B1\;mvn%D3\\t%0, #%B2"
7938 "&& reload_completed"
7941 enum rtx_code rev_code;
7945 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
7947 gen_rtx_SET (operands[0], operands[1])));
7949 rev_code = GET_CODE (operands[3]);
7950 mode = GET_MODE (operands[4]);
7951 if (mode == CCFPmode || mode == CCFPEmode)
7952 rev_code = reverse_condition_maybe_unordered (rev_code);
7954 rev_code = reverse_condition (rev_code);
7956 rev_cond = gen_rtx_fmt_ee (rev_code,
7960 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
7962 gen_rtx_SET (operands[0], operands[2])));
7965 [(set_attr "length" "4,4,4,4,8,8,8,8")
7966 (set_attr "conds" "use")
7967 (set_attr_alternative "type"
7968 [(if_then_else (match_operand 2 "const_int_operand" "")
7969 (const_string "mov_imm")
7970 (const_string "mov_reg"))
7971 (const_string "mvn_imm")
7972 (if_then_else (match_operand 1 "const_int_operand" "")
7973 (const_string "mov_imm")
7974 (const_string "mov_reg"))
7975 (const_string "mvn_imm")
7976 (const_string "multiple")
7977 (const_string "multiple")
7978 (const_string "multiple")
7979 (const_string "multiple")])]
7982 (define_insn "*movsfcc_soft_insn"
7983 [(set (match_operand:SF 0 "s_register_operand" "=r,r")
7984 (if_then_else:SF (match_operator 3 "arm_comparison_operator"
7985 [(match_operand 4 "cc_register" "") (const_int 0)])
7986 (match_operand:SF 1 "s_register_operand" "0,r")
7987 (match_operand:SF 2 "s_register_operand" "r,0")))]
7988 "TARGET_ARM && TARGET_SOFT_FLOAT"
7992 [(set_attr "conds" "use")
7993 (set_attr "type" "mov_reg")]
7997 ;; Jump and linkage insns
7999 (define_expand "jump"
8001 (label_ref (match_operand 0 "" "")))]
8006 (define_insn "*arm_jump"
8008 (label_ref (match_operand 0 "" "")))]
8012 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
8014 arm_ccfsm_state += 2;
8017 return \"b%?\\t%l0\";
8020 [(set_attr "predicable" "yes")
8021 (set (attr "length")
8023 (and (match_test "TARGET_THUMB2")
8024 (and (ge (minus (match_dup 0) (pc)) (const_int -2044))
8025 (le (minus (match_dup 0) (pc)) (const_int 2048))))
8028 (set_attr "type" "branch")]
8031 (define_expand "call"
8032 [(parallel [(call (match_operand 0 "memory_operand" "")
8033 (match_operand 1 "general_operand" ""))
8034 (use (match_operand 2 "" ""))
8035 (clobber (reg:SI LR_REGNUM))])]
8041 /* In an untyped call, we can get NULL for operand 2. */
8042 if (operands[2] == NULL_RTX)
8043 operands[2] = const0_rtx;
8045 /* Decide if we should generate indirect calls by loading the
8046 32-bit address of the callee into a register before performing the
8048 callee = XEXP (operands[0], 0);
8049 if (GET_CODE (callee) == SYMBOL_REF
8050 ? arm_is_long_call_p (SYMBOL_REF_DECL (callee))
8052 XEXP (operands[0], 0) = force_reg (Pmode, callee);
8054 pat = gen_call_internal (operands[0], operands[1], operands[2]);
8055 arm_emit_call_insn (pat, XEXP (operands[0], 0), false);
8060 (define_expand "call_internal"
8061 [(parallel [(call (match_operand 0 "memory_operand" "")
8062 (match_operand 1 "general_operand" ""))
8063 (use (match_operand 2 "" ""))
8064 (clobber (reg:SI LR_REGNUM))])])
8066 (define_insn "*call_reg_armv5"
8067 [(call (mem:SI (match_operand:SI 0 "s_register_operand" "r"))
8068 (match_operand 1 "" ""))
8069 (use (match_operand 2 "" ""))
8070 (clobber (reg:SI LR_REGNUM))]
8071 "TARGET_ARM && arm_arch5 && !SIBLING_CALL_P (insn)"
8073 [(set_attr "type" "call")]
8076 (define_insn "*call_reg_arm"
8077 [(call (mem:SI (match_operand:SI 0 "s_register_operand" "r"))
8078 (match_operand 1 "" ""))
8079 (use (match_operand 2 "" ""))
8080 (clobber (reg:SI LR_REGNUM))]
8081 "TARGET_ARM && !arm_arch5 && !SIBLING_CALL_P (insn)"
8083 return output_call (operands);
8085 ;; length is worst case, normally it is only two
8086 [(set_attr "length" "12")
8087 (set_attr "type" "call")]
8091 (define_expand "call_value"
8092 [(parallel [(set (match_operand 0 "" "")
8093 (call (match_operand 1 "memory_operand" "")
8094 (match_operand 2 "general_operand" "")))
8095 (use (match_operand 3 "" ""))
8096 (clobber (reg:SI LR_REGNUM))])]
8102 /* In an untyped call, we can get NULL for operand 2. */
8103 if (operands[3] == 0)
8104 operands[3] = const0_rtx;
8106 /* Decide if we should generate indirect calls by loading the
8107 32-bit address of the callee into a register before performing the
8109 callee = XEXP (operands[1], 0);
8110 if (GET_CODE (callee) == SYMBOL_REF
8111 ? arm_is_long_call_p (SYMBOL_REF_DECL (callee))
8113 XEXP (operands[1], 0) = force_reg (Pmode, callee);
8115 pat = gen_call_value_internal (operands[0], operands[1],
8116 operands[2], operands[3]);
8117 arm_emit_call_insn (pat, XEXP (operands[1], 0), false);
8122 (define_expand "call_value_internal"
8123 [(parallel [(set (match_operand 0 "" "")
8124 (call (match_operand 1 "memory_operand" "")
8125 (match_operand 2 "general_operand" "")))
8126 (use (match_operand 3 "" ""))
8127 (clobber (reg:SI LR_REGNUM))])])
8129 (define_insn "*call_value_reg_armv5"
8130 [(set (match_operand 0 "" "")
8131 (call (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
8132 (match_operand 2 "" "")))
8133 (use (match_operand 3 "" ""))
8134 (clobber (reg:SI LR_REGNUM))]
8135 "TARGET_ARM && arm_arch5 && !SIBLING_CALL_P (insn)"
8137 [(set_attr "type" "call")]
8140 (define_insn "*call_value_reg_arm"
8141 [(set (match_operand 0 "" "")
8142 (call (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
8143 (match_operand 2 "" "")))
8144 (use (match_operand 3 "" ""))
8145 (clobber (reg:SI LR_REGNUM))]
8146 "TARGET_ARM && !arm_arch5 && !SIBLING_CALL_P (insn)"
8148 return output_call (&operands[1]);
8150 [(set_attr "length" "12")
8151 (set_attr "type" "call")]
8154 ;; Allow calls to SYMBOL_REFs specially as they are not valid general addresses
8155 ;; The 'a' causes the operand to be treated as an address, i.e. no '#' output.
8157 (define_insn "*call_symbol"
8158 [(call (mem:SI (match_operand:SI 0 "" ""))
8159 (match_operand 1 "" ""))
8160 (use (match_operand 2 "" ""))
8161 (clobber (reg:SI LR_REGNUM))]
8163 && !SIBLING_CALL_P (insn)
8164 && (GET_CODE (operands[0]) == SYMBOL_REF)
8165 && !arm_is_long_call_p (SYMBOL_REF_DECL (operands[0]))"
8168 rtx op = operands[0];
8170 /* Switch mode now when possible. */
8171 if (SYMBOL_REF_DECL (op) && !TREE_PUBLIC (SYMBOL_REF_DECL (op))
8172 && arm_arch5 && arm_change_mode_p (SYMBOL_REF_DECL (op)))
8173 return NEED_PLT_RELOC ? \"blx%?\\t%a0(PLT)\" : \"blx%?\\t(%a0)\";
8175 return NEED_PLT_RELOC ? \"bl%?\\t%a0(PLT)\" : \"bl%?\\t%a0\";
8177 [(set_attr "type" "call")]
8180 (define_insn "*call_value_symbol"
8181 [(set (match_operand 0 "" "")
8182 (call (mem:SI (match_operand:SI 1 "" ""))
8183 (match_operand:SI 2 "" "")))
8184 (use (match_operand 3 "" ""))
8185 (clobber (reg:SI LR_REGNUM))]
8187 && !SIBLING_CALL_P (insn)
8188 && (GET_CODE (operands[1]) == SYMBOL_REF)
8189 && !arm_is_long_call_p (SYMBOL_REF_DECL (operands[1]))"
8192 rtx op = operands[1];
8194 /* Switch mode now when possible. */
8195 if (SYMBOL_REF_DECL (op) && !TREE_PUBLIC (SYMBOL_REF_DECL (op))
8196 && arm_arch5 && arm_change_mode_p (SYMBOL_REF_DECL (op)))
8197 return NEED_PLT_RELOC ? \"blx%?\\t%a1(PLT)\" : \"blx%?\\t(%a1)\";
8199 return NEED_PLT_RELOC ? \"bl%?\\t%a1(PLT)\" : \"bl%?\\t%a1\";
8201 [(set_attr "type" "call")]
8204 (define_expand "sibcall_internal"
8205 [(parallel [(call (match_operand 0 "memory_operand" "")
8206 (match_operand 1 "general_operand" ""))
8208 (use (match_operand 2 "" ""))])])
8210 ;; We may also be able to do sibcalls for Thumb, but it's much harder...
8211 (define_expand "sibcall"
8212 [(parallel [(call (match_operand 0 "memory_operand" "")
8213 (match_operand 1 "general_operand" ""))
8215 (use (match_operand 2 "" ""))])]
8221 if ((!REG_P (XEXP (operands[0], 0))
8222 && GET_CODE (XEXP (operands[0], 0)) != SYMBOL_REF)
8223 || (GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
8224 && arm_is_long_call_p (SYMBOL_REF_DECL (XEXP (operands[0], 0)))))
8225 XEXP (operands[0], 0) = force_reg (SImode, XEXP (operands[0], 0));
8227 if (operands[2] == NULL_RTX)
8228 operands[2] = const0_rtx;
8230 pat = gen_sibcall_internal (operands[0], operands[1], operands[2]);
8231 arm_emit_call_insn (pat, operands[0], true);
8236 (define_expand "sibcall_value_internal"
8237 [(parallel [(set (match_operand 0 "" "")
8238 (call (match_operand 1 "memory_operand" "")
8239 (match_operand 2 "general_operand" "")))
8241 (use (match_operand 3 "" ""))])])
8243 (define_expand "sibcall_value"
8244 [(parallel [(set (match_operand 0 "" "")
8245 (call (match_operand 1 "memory_operand" "")
8246 (match_operand 2 "general_operand" "")))
8248 (use (match_operand 3 "" ""))])]
8254 if ((!REG_P (XEXP (operands[1], 0))
8255 && GET_CODE (XEXP (operands[1], 0)) != SYMBOL_REF)
8256 || (GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
8257 && arm_is_long_call_p (SYMBOL_REF_DECL (XEXP (operands[1], 0)))))
8258 XEXP (operands[1], 0) = force_reg (SImode, XEXP (operands[1], 0));
8260 if (operands[3] == NULL_RTX)
8261 operands[3] = const0_rtx;
8263 pat = gen_sibcall_value_internal (operands[0], operands[1],
8264 operands[2], operands[3]);
8265 arm_emit_call_insn (pat, operands[1], true);
8270 (define_insn "*sibcall_insn"
8271 [(call (mem:SI (match_operand:SI 0 "call_insn_operand" "Cs, US"))
8272 (match_operand 1 "" ""))
8274 (use (match_operand 2 "" ""))]
8275 "TARGET_32BIT && SIBLING_CALL_P (insn)"
8277 if (which_alternative == 1)
8278 return NEED_PLT_RELOC ? \"b%?\\t%a0(PLT)\" : \"b%?\\t%a0\";
8281 if (arm_arch5 || arm_arch4t)
8282 return \"bx%?\\t%0\\t%@ indirect register sibling call\";
8284 return \"mov%?\\t%|pc, %0\\t%@ indirect register sibling call\";
8287 [(set_attr "type" "call")]
8290 (define_insn "*sibcall_value_insn"
8291 [(set (match_operand 0 "" "")
8292 (call (mem:SI (match_operand:SI 1 "call_insn_operand" "Cs,US"))
8293 (match_operand 2 "" "")))
8295 (use (match_operand 3 "" ""))]
8296 "TARGET_32BIT && SIBLING_CALL_P (insn)"
8298 if (which_alternative == 1)
8299 return NEED_PLT_RELOC ? \"b%?\\t%a1(PLT)\" : \"b%?\\t%a1\";
8302 if (arm_arch5 || arm_arch4t)
8303 return \"bx%?\\t%1\";
8305 return \"mov%?\\t%|pc, %1\\t@ indirect sibling call \";
8308 [(set_attr "type" "call")]
8311 (define_expand "<return_str>return"
8313 "(TARGET_ARM || (TARGET_THUMB2
8314 && ARM_FUNC_TYPE (arm_current_func_type ()) == ARM_FT_NORMAL
8315 && !IS_STACKALIGN (arm_current_func_type ())))
8316 <return_cond_false>"
8321 thumb2_expand_return (<return_simple_p>);
8328 ;; Often the return insn will be the same as loading from memory, so set attr
8329 (define_insn "*arm_return"
8331 "TARGET_ARM && USE_RETURN_INSN (FALSE)"
8334 if (arm_ccfsm_state == 2)
8336 arm_ccfsm_state += 2;
8339 return output_return_instruction (const_true_rtx, true, false, false);
8341 [(set_attr "type" "load1")
8342 (set_attr "length" "12")
8343 (set_attr "predicable" "yes")]
8346 (define_insn "*cond_<return_str>return"
8348 (if_then_else (match_operator 0 "arm_comparison_operator"
8349 [(match_operand 1 "cc_register" "") (const_int 0)])
8352 "TARGET_ARM <return_cond_true>"
8355 if (arm_ccfsm_state == 2)
8357 arm_ccfsm_state += 2;
8360 return output_return_instruction (operands[0], true, false,
8363 [(set_attr "conds" "use")
8364 (set_attr "length" "12")
8365 (set_attr "type" "load1")]
8368 (define_insn "*cond_<return_str>return_inverted"
8370 (if_then_else (match_operator 0 "arm_comparison_operator"
8371 [(match_operand 1 "cc_register" "") (const_int 0)])
8374 "TARGET_ARM <return_cond_true>"
8377 if (arm_ccfsm_state == 2)
8379 arm_ccfsm_state += 2;
8382 return output_return_instruction (operands[0], true, true,
8385 [(set_attr "conds" "use")
8386 (set_attr "length" "12")
8387 (set_attr "type" "load1")]
8390 (define_insn "*arm_simple_return"
8395 if (arm_ccfsm_state == 2)
8397 arm_ccfsm_state += 2;
8400 return output_return_instruction (const_true_rtx, true, false, true);
8402 [(set_attr "type" "branch")
8403 (set_attr "length" "4")
8404 (set_attr "predicable" "yes")]
8407 ;; Generate a sequence of instructions to determine if the processor is
8408 ;; in 26-bit or 32-bit mode, and return the appropriate return address
8411 (define_expand "return_addr_mask"
8413 (compare:CC_NOOV (unspec [(const_int 0)] UNSPEC_CHECK_ARCH)
8415 (set (match_operand:SI 0 "s_register_operand" "")
8416 (if_then_else:SI (eq (match_dup 1) (const_int 0))
8418 (const_int 67108860)))] ; 0x03fffffc
8421 operands[1] = gen_rtx_REG (CC_NOOVmode, CC_REGNUM);
8424 (define_insn "*check_arch2"
8425 [(set (match_operand:CC_NOOV 0 "cc_register" "")
8426 (compare:CC_NOOV (unspec [(const_int 0)] UNSPEC_CHECK_ARCH)
8429 "teq\\t%|r0, %|r0\;teq\\t%|pc, %|pc"
8430 [(set_attr "length" "8")
8431 (set_attr "conds" "set")
8432 (set_attr "type" "multiple")]
8435 ;; Call subroutine returning any type.
8437 (define_expand "untyped_call"
8438 [(parallel [(call (match_operand 0 "" "")
8440 (match_operand 1 "" "")
8441 (match_operand 2 "" "")])]
8446 rtx par = gen_rtx_PARALLEL (VOIDmode,
8447 rtvec_alloc (XVECLEN (operands[2], 0)));
8448 rtx addr = gen_reg_rtx (Pmode);
8452 emit_move_insn (addr, XEXP (operands[1], 0));
8453 mem = change_address (operands[1], BLKmode, addr);
8455 for (i = 0; i < XVECLEN (operands[2], 0); i++)
8457 rtx src = SET_SRC (XVECEXP (operands[2], 0, i));
8459 /* Default code only uses r0 as a return value, but we could
8460 be using anything up to 4 registers. */
8461 if (REGNO (src) == R0_REGNUM)
8462 src = gen_rtx_REG (TImode, R0_REGNUM);
8464 XVECEXP (par, 0, i) = gen_rtx_EXPR_LIST (VOIDmode, src,
8466 size += GET_MODE_SIZE (GET_MODE (src));
8469 emit_call_insn (gen_call_value (par, operands[0], const0_rtx, NULL));
8473 for (i = 0; i < XVECLEN (par, 0); i++)
8475 HOST_WIDE_INT offset = 0;
8476 rtx reg = XEXP (XVECEXP (par, 0, i), 0);
8479 emit_move_insn (addr, plus_constant (Pmode, addr, size));
8481 mem = change_address (mem, GET_MODE (reg), NULL);
8482 if (REGNO (reg) == R0_REGNUM)
8484 /* On thumb we have to use a write-back instruction. */
8485 emit_insn (arm_gen_store_multiple (arm_regs_in_sequence, 4, addr,
8486 TARGET_THUMB ? TRUE : FALSE, mem, &offset));
8487 size = TARGET_ARM ? 16 : 0;
8491 emit_move_insn (mem, reg);
8492 size = GET_MODE_SIZE (GET_MODE (reg));
8496 /* The optimizer does not know that the call sets the function value
8497 registers we stored in the result block. We avoid problems by
8498 claiming that all hard registers are used and clobbered at this
8500 emit_insn (gen_blockage ());
8506 (define_expand "untyped_return"
8507 [(match_operand:BLK 0 "memory_operand" "")
8508 (match_operand 1 "" "")]
8513 rtx addr = gen_reg_rtx (Pmode);
8517 emit_move_insn (addr, XEXP (operands[0], 0));
8518 mem = change_address (operands[0], BLKmode, addr);
8520 for (i = 0; i < XVECLEN (operands[1], 0); i++)
8522 HOST_WIDE_INT offset = 0;
8523 rtx reg = SET_DEST (XVECEXP (operands[1], 0, i));
8526 emit_move_insn (addr, plus_constant (Pmode, addr, size));
8528 mem = change_address (mem, GET_MODE (reg), NULL);
8529 if (REGNO (reg) == R0_REGNUM)
8531 /* On thumb we have to use a write-back instruction. */
8532 emit_insn (arm_gen_load_multiple (arm_regs_in_sequence, 4, addr,
8533 TARGET_THUMB ? TRUE : FALSE, mem, &offset));
8534 size = TARGET_ARM ? 16 : 0;
8538 emit_move_insn (reg, mem);
8539 size = GET_MODE_SIZE (GET_MODE (reg));
8543 /* Emit USE insns before the return. */
8544 for (i = 0; i < XVECLEN (operands[1], 0); i++)
8545 emit_use (SET_DEST (XVECEXP (operands[1], 0, i)));
8547 /* Construct the return. */
8548 expand_naked_return ();
8554 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
8555 ;; all of memory. This blocks insns from being moved across this point.
8557 (define_insn "blockage"
8558 [(unspec_volatile [(const_int 0)] VUNSPEC_BLOCKAGE)]
8561 [(set_attr "length" "0")
8562 (set_attr "type" "block")]
8565 (define_insn "probe_stack"
8566 [(set (match_operand:SI 0 "memory_operand" "=m")
8567 (unspec:SI [(const_int 0)] UNSPEC_PROBE_STACK))]
8570 [(set_attr "type" "store1")
8571 (set_attr "predicable" "yes")]
8574 (define_insn "probe_stack_range"
8575 [(set (match_operand:SI 0 "register_operand" "=r")
8576 (unspec_volatile:SI [(match_operand:SI 1 "register_operand" "0")
8577 (match_operand:SI 2 "register_operand" "r")]
8578 VUNSPEC_PROBE_STACK_RANGE))]
8581 return output_probe_stack_range (operands[0], operands[2]);
8583 [(set_attr "type" "multiple")
8584 (set_attr "conds" "clob")]
8587 (define_expand "casesi"
8588 [(match_operand:SI 0 "s_register_operand" "") ; index to jump on
8589 (match_operand:SI 1 "const_int_operand" "") ; lower bound
8590 (match_operand:SI 2 "const_int_operand" "") ; total range
8591 (match_operand:SI 3 "" "") ; table label
8592 (match_operand:SI 4 "" "")] ; Out of range label
8593 "(TARGET_32BIT || optimize_size || flag_pic) && !target_pure_code"
8596 enum insn_code code;
8597 if (operands[1] != const0_rtx)
8599 rtx reg = gen_reg_rtx (SImode);
8601 emit_insn (gen_addsi3 (reg, operands[0],
8602 gen_int_mode (-INTVAL (operands[1]),
8608 code = CODE_FOR_arm_casesi_internal;
8609 else if (TARGET_THUMB1)
8610 code = CODE_FOR_thumb1_casesi_internal_pic;
8612 code = CODE_FOR_thumb2_casesi_internal_pic;
8614 code = CODE_FOR_thumb2_casesi_internal;
8616 if (!insn_data[(int) code].operand[1].predicate(operands[2], SImode))
8617 operands[2] = force_reg (SImode, operands[2]);
8619 emit_jump_insn (GEN_FCN ((int) code) (operands[0], operands[2],
8620 operands[3], operands[4]));
8625 ;; The USE in this pattern is needed to tell flow analysis that this is
8626 ;; a CASESI insn. It has no other purpose.
8627 (define_insn "arm_casesi_internal"
8628 [(parallel [(set (pc)
8630 (leu (match_operand:SI 0 "s_register_operand" "r")
8631 (match_operand:SI 1 "arm_rhs_operand" "rI"))
8632 (mem:SI (plus:SI (mult:SI (match_dup 0) (const_int 4))
8633 (label_ref (match_operand 2 "" ""))))
8634 (label_ref (match_operand 3 "" ""))))
8635 (clobber (reg:CC CC_REGNUM))
8636 (use (label_ref (match_dup 2)))])]
8640 return \"cmp\\t%0, %1\;addls\\t%|pc, %|pc, %0, asl #2\;b\\t%l3\";
8641 return \"cmp\\t%0, %1\;ldrls\\t%|pc, [%|pc, %0, asl #2]\;b\\t%l3\";
8643 [(set_attr "conds" "clob")
8644 (set_attr "length" "12")
8645 (set_attr "type" "multiple")]
8648 (define_expand "indirect_jump"
8650 (match_operand:SI 0 "s_register_operand" ""))]
8653 /* Thumb-2 doesn't have mov pc, reg. Explicitly set the low bit of the
8654 address and use bx. */
8658 tmp = gen_reg_rtx (SImode);
8659 emit_insn (gen_iorsi3 (tmp, operands[0], GEN_INT(1)));
8665 ;; NB Never uses BX.
8666 (define_insn "*arm_indirect_jump"
8668 (match_operand:SI 0 "s_register_operand" "r"))]
8670 "mov%?\\t%|pc, %0\\t%@ indirect register jump"
8671 [(set_attr "predicable" "yes")
8672 (set_attr "type" "branch")]
8675 (define_insn "*load_indirect_jump"
8677 (match_operand:SI 0 "memory_operand" "m"))]
8679 "ldr%?\\t%|pc, %0\\t%@ indirect memory jump"
8680 [(set_attr "type" "load1")
8681 (set_attr "pool_range" "4096")
8682 (set_attr "neg_pool_range" "4084")
8683 (set_attr "predicable" "yes")]
8693 [(set (attr "length")
8694 (if_then_else (eq_attr "is_thumb" "yes")
8697 (set_attr "type" "mov_reg")]
8701 [(trap_if (const_int 1) (const_int 0))]
8705 return \".inst\\t0xe7f000f0\";
8707 return \".inst\\t0xdeff\";
8709 [(set (attr "length")
8710 (if_then_else (eq_attr "is_thumb" "yes")
8713 (set_attr "type" "trap")
8714 (set_attr "conds" "unconditional")]
8718 ;; Patterns to allow combination of arithmetic, cond code and shifts
8720 (define_insn "*<arith_shift_insn>_multsi"
8721 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8723 (mult:SI (match_operand:SI 2 "s_register_operand" "r,r")
8724 (match_operand:SI 3 "power_of_two_operand" ""))
8725 (match_operand:SI 1 "s_register_operand" "rk,<t2_binop0>")))]
8727 "<arith_shift_insn>%?\\t%0, %1, %2, lsl %b3"
8728 [(set_attr "predicable" "yes")
8729 (set_attr "predicable_short_it" "no")
8730 (set_attr "shift" "2")
8731 (set_attr "arch" "a,t2")
8732 (set_attr "type" "alu_shift_imm")])
8734 (define_insn "*<arith_shift_insn>_shiftsi"
8735 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
8737 (match_operator:SI 2 "shift_nomul_operator"
8738 [(match_operand:SI 3 "s_register_operand" "r,r,r")
8739 (match_operand:SI 4 "shift_amount_operand" "M,M,r")])
8740 (match_operand:SI 1 "s_register_operand" "rk,<t2_binop0>,rk")))]
8741 "TARGET_32BIT && GET_CODE (operands[2]) != MULT"
8742 "<arith_shift_insn>%?\\t%0, %1, %3%S2"
8743 [(set_attr "predicable" "yes")
8744 (set_attr "predicable_short_it" "no")
8745 (set_attr "shift" "3")
8746 (set_attr "arch" "a,t2,a")
8747 (set_attr "type" "alu_shift_imm,alu_shift_imm,alu_shift_reg")])
8750 [(set (match_operand:SI 0 "s_register_operand" "")
8751 (match_operator:SI 1 "shiftable_operator"
8752 [(match_operator:SI 2 "shiftable_operator"
8753 [(match_operator:SI 3 "shift_operator"
8754 [(match_operand:SI 4 "s_register_operand" "")
8755 (match_operand:SI 5 "reg_or_int_operand" "")])
8756 (match_operand:SI 6 "s_register_operand" "")])
8757 (match_operand:SI 7 "arm_rhs_operand" "")]))
8758 (clobber (match_operand:SI 8 "s_register_operand" ""))]
8761 (match_op_dup 2 [(match_op_dup 3 [(match_dup 4) (match_dup 5)])
8764 (match_op_dup 1 [(match_dup 8) (match_dup 7)]))]
8767 (define_insn "*arith_shiftsi_compare0"
8768 [(set (reg:CC_NOOV CC_REGNUM)
8770 (match_operator:SI 1 "shiftable_operator"
8771 [(match_operator:SI 3 "shift_operator"
8772 [(match_operand:SI 4 "s_register_operand" "r,r")
8773 (match_operand:SI 5 "shift_amount_operand" "M,r")])
8774 (match_operand:SI 2 "s_register_operand" "r,r")])
8776 (set (match_operand:SI 0 "s_register_operand" "=r,r")
8777 (match_op_dup 1 [(match_op_dup 3 [(match_dup 4) (match_dup 5)])
8780 "%i1s%?\\t%0, %2, %4%S3"
8781 [(set_attr "conds" "set")
8782 (set_attr "shift" "4")
8783 (set_attr "arch" "32,a")
8784 (set_attr "type" "alus_shift_imm,alus_shift_reg")])
8786 (define_insn "*arith_shiftsi_compare0_scratch"
8787 [(set (reg:CC_NOOV CC_REGNUM)
8789 (match_operator:SI 1 "shiftable_operator"
8790 [(match_operator:SI 3 "shift_operator"
8791 [(match_operand:SI 4 "s_register_operand" "r,r")
8792 (match_operand:SI 5 "shift_amount_operand" "M,r")])
8793 (match_operand:SI 2 "s_register_operand" "r,r")])
8795 (clobber (match_scratch:SI 0 "=r,r"))]
8797 "%i1s%?\\t%0, %2, %4%S3"
8798 [(set_attr "conds" "set")
8799 (set_attr "shift" "4")
8800 (set_attr "arch" "32,a")
8801 (set_attr "type" "alus_shift_imm,alus_shift_reg")])
8803 (define_insn "*sub_shiftsi"
8804 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8805 (minus:SI (match_operand:SI 1 "s_register_operand" "r,r")
8806 (match_operator:SI 2 "shift_operator"
8807 [(match_operand:SI 3 "s_register_operand" "r,r")
8808 (match_operand:SI 4 "shift_amount_operand" "M,r")])))]
8810 "sub%?\\t%0, %1, %3%S2"
8811 [(set_attr "predicable" "yes")
8812 (set_attr "shift" "3")
8813 (set_attr "arch" "32,a")
8814 (set_attr "type" "alus_shift_imm,alus_shift_reg")])
8816 (define_insn "*sub_shiftsi_compare0"
8817 [(set (reg:CC_NOOV CC_REGNUM)
8819 (minus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
8820 (match_operator:SI 2 "shift_operator"
8821 [(match_operand:SI 3 "s_register_operand" "r,r,r")
8822 (match_operand:SI 4 "shift_amount_operand" "M,r,M")]))
8824 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
8825 (minus:SI (match_dup 1)
8826 (match_op_dup 2 [(match_dup 3) (match_dup 4)])))]
8828 "subs%?\\t%0, %1, %3%S2"
8829 [(set_attr "conds" "set")
8830 (set_attr "shift" "3")
8831 (set_attr "arch" "32,a,a")
8832 (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
8834 (define_insn "*sub_shiftsi_compare0_scratch"
8835 [(set (reg:CC_NOOV CC_REGNUM)
8837 (minus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
8838 (match_operator:SI 2 "shift_operator"
8839 [(match_operand:SI 3 "s_register_operand" "r,r,r")
8840 (match_operand:SI 4 "shift_amount_operand" "M,r,M")]))
8842 (clobber (match_scratch:SI 0 "=r,r,r"))]
8844 "subs%?\\t%0, %1, %3%S2"
8845 [(set_attr "conds" "set")
8846 (set_attr "shift" "3")
8847 (set_attr "arch" "32,a,a")
8848 (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
8851 (define_insn_and_split "*and_scc"
8852 [(set (match_operand:SI 0 "s_register_operand" "=r")
8853 (and:SI (match_operator:SI 1 "arm_comparison_operator"
8854 [(match_operand 2 "cc_register" "") (const_int 0)])
8855 (match_operand:SI 3 "s_register_operand" "r")))]
8857 "#" ; "mov%D1\\t%0, #0\;and%d1\\t%0, %3, #1"
8858 "&& reload_completed"
8859 [(cond_exec (match_dup 5) (set (match_dup 0) (const_int 0)))
8860 (cond_exec (match_dup 4) (set (match_dup 0)
8861 (and:SI (match_dup 3) (const_int 1))))]
8863 machine_mode mode = GET_MODE (operands[2]);
8864 enum rtx_code rc = GET_CODE (operands[1]);
8866 /* Note that operands[4] is the same as operands[1],
8867 but with VOIDmode as the result. */
8868 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
8869 if (mode == CCFPmode || mode == CCFPEmode)
8870 rc = reverse_condition_maybe_unordered (rc);
8872 rc = reverse_condition (rc);
8873 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
8875 [(set_attr "conds" "use")
8876 (set_attr "type" "multiple")
8877 (set_attr "length" "8")]
8880 (define_insn_and_split "*ior_scc"
8881 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8882 (ior:SI (match_operator:SI 1 "arm_comparison_operator"
8883 [(match_operand 2 "cc_register" "") (const_int 0)])
8884 (match_operand:SI 3 "s_register_operand" "0,?r")))]
8889 "&& reload_completed
8890 && REGNO (operands [0]) != REGNO (operands[3])"
8891 ;; && which_alternative == 1
8892 ; mov%D1\\t%0, %3\;orr%d1\\t%0, %3, #1
8893 [(cond_exec (match_dup 5) (set (match_dup 0) (match_dup 3)))
8894 (cond_exec (match_dup 4) (set (match_dup 0)
8895 (ior:SI (match_dup 3) (const_int 1))))]
8897 machine_mode mode = GET_MODE (operands[2]);
8898 enum rtx_code rc = GET_CODE (operands[1]);
8900 /* Note that operands[4] is the same as operands[1],
8901 but with VOIDmode as the result. */
8902 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
8903 if (mode == CCFPmode || mode == CCFPEmode)
8904 rc = reverse_condition_maybe_unordered (rc);
8906 rc = reverse_condition (rc);
8907 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
8909 [(set_attr "conds" "use")
8910 (set_attr "length" "4,8")
8911 (set_attr "type" "logic_imm,multiple")]
8914 ; A series of splitters for the compare_scc pattern below. Note that
8915 ; order is important.
8917 [(set (match_operand:SI 0 "s_register_operand" "")
8918 (lt:SI (match_operand:SI 1 "s_register_operand" "")
8920 (clobber (reg:CC CC_REGNUM))]
8921 "TARGET_32BIT && reload_completed"
8922 [(set (match_dup 0) (lshiftrt:SI (match_dup 1) (const_int 31)))])
8925 [(set (match_operand:SI 0 "s_register_operand" "")
8926 (ge:SI (match_operand:SI 1 "s_register_operand" "")
8928 (clobber (reg:CC CC_REGNUM))]
8929 "TARGET_32BIT && reload_completed"
8930 [(set (match_dup 0) (not:SI (match_dup 1)))
8931 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 31)))])
8934 [(set (match_operand:SI 0 "s_register_operand" "")
8935 (eq:SI (match_operand:SI 1 "s_register_operand" "")
8937 (clobber (reg:CC CC_REGNUM))]
8938 "arm_arch5 && TARGET_32BIT"
8939 [(set (match_dup 0) (clz:SI (match_dup 1)))
8940 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
8944 [(set (match_operand:SI 0 "s_register_operand" "")
8945 (eq:SI (match_operand:SI 1 "s_register_operand" "")
8947 (clobber (reg:CC CC_REGNUM))]
8948 "TARGET_32BIT && reload_completed"
8950 [(set (reg:CC CC_REGNUM)
8951 (compare:CC (const_int 1) (match_dup 1)))
8953 (minus:SI (const_int 1) (match_dup 1)))])
8954 (cond_exec (ltu:CC (reg:CC CC_REGNUM) (const_int 0))
8955 (set (match_dup 0) (const_int 0)))])
8958 [(set (match_operand:SI 0 "s_register_operand" "")
8959 (ne:SI (match_operand:SI 1 "s_register_operand" "")
8960 (match_operand:SI 2 "const_int_operand" "")))
8961 (clobber (reg:CC CC_REGNUM))]
8962 "TARGET_32BIT && reload_completed"
8964 [(set (reg:CC CC_REGNUM)
8965 (compare:CC (match_dup 1) (match_dup 2)))
8966 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 3)))])
8967 (cond_exec (ne:CC (reg:CC CC_REGNUM) (const_int 0))
8968 (set (match_dup 0) (const_int 1)))]
8970 operands[3] = GEN_INT (-INTVAL (operands[2]));
8974 [(set (match_operand:SI 0 "s_register_operand" "")
8975 (ne:SI (match_operand:SI 1 "s_register_operand" "")
8976 (match_operand:SI 2 "arm_add_operand" "")))
8977 (clobber (reg:CC CC_REGNUM))]
8978 "TARGET_32BIT && reload_completed"
8980 [(set (reg:CC_NOOV CC_REGNUM)
8981 (compare:CC_NOOV (minus:SI (match_dup 1) (match_dup 2))
8983 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
8984 (cond_exec (ne:CC_NOOV (reg:CC_NOOV CC_REGNUM) (const_int 0))
8985 (set (match_dup 0) (const_int 1)))])
8987 (define_insn_and_split "*compare_scc"
8988 [(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts")
8989 (match_operator:SI 1 "arm_comparison_operator"
8990 [(match_operand:SI 2 "s_register_operand" "r,r")
8991 (match_operand:SI 3 "arm_add_operand" "rI,L")]))
8992 (clobber (reg:CC CC_REGNUM))]
8995 "&& reload_completed"
8996 [(set (reg:CC CC_REGNUM) (compare:CC (match_dup 2) (match_dup 3)))
8997 (cond_exec (match_dup 4) (set (match_dup 0) (const_int 0)))
8998 (cond_exec (match_dup 5) (set (match_dup 0) (const_int 1)))]
9001 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
9002 operands[2], operands[3]);
9003 enum rtx_code rc = GET_CODE (operands[1]);
9005 tmp1 = gen_rtx_REG (mode, CC_REGNUM);
9007 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, tmp1, const0_rtx);
9008 if (mode == CCFPmode || mode == CCFPEmode)
9009 rc = reverse_condition_maybe_unordered (rc);
9011 rc = reverse_condition (rc);
9012 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, tmp1, const0_rtx);
9014 [(set_attr "type" "multiple")]
9017 ;; Attempt to improve the sequence generated by the compare_scc splitters
9018 ;; not to use conditional execution.
9020 ;; Rd = (eq (reg1) (const_int0)) // ARMv5
9024 [(set (reg:CC CC_REGNUM)
9025 (compare:CC (match_operand:SI 1 "register_operand" "")
9027 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
9028 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
9029 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
9030 (set (match_dup 0) (const_int 1)))]
9031 "arm_arch5 && TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
9032 [(set (match_dup 0) (clz:SI (match_dup 1)))
9033 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
9036 ;; Rd = (eq (reg1) (const_int0)) // !ARMv5
9040 [(set (reg:CC CC_REGNUM)
9041 (compare:CC (match_operand:SI 1 "register_operand" "")
9043 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
9044 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
9045 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
9046 (set (match_dup 0) (const_int 1)))
9047 (match_scratch:SI 2 "r")]
9048 "TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
9050 [(set (reg:CC CC_REGNUM)
9051 (compare:CC (const_int 0) (match_dup 1)))
9052 (set (match_dup 2) (minus:SI (const_int 0) (match_dup 1)))])
9054 (plus:SI (plus:SI (match_dup 1) (match_dup 2))
9055 (geu:SI (reg:CC CC_REGNUM) (const_int 0))))]
9058 ;; Rd = (eq (reg1) (reg2/imm)) // ARMv5 and optimising for speed.
9059 ;; sub Rd, Reg1, reg2
9063 [(set (reg:CC CC_REGNUM)
9064 (compare:CC (match_operand:SI 1 "register_operand" "")
9065 (match_operand:SI 2 "arm_rhs_operand" "")))
9066 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
9067 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
9068 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
9069 (set (match_dup 0) (const_int 1)))]
9070 "arm_arch5 && TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)
9071 && !(TARGET_THUMB2 && optimize_insn_for_size_p ())"
9072 [(set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))
9073 (set (match_dup 0) (clz:SI (match_dup 0)))
9074 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
9078 ;; Rd = (eq (reg1) (reg2)) // ! ARMv5 or optimising for size.
9079 ;; sub T1, Reg1, reg2
9083 [(set (reg:CC CC_REGNUM)
9084 (compare:CC (match_operand:SI 1 "register_operand" "")
9085 (match_operand:SI 2 "arm_rhs_operand" "")))
9086 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
9087 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
9088 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
9089 (set (match_dup 0) (const_int 1)))
9090 (match_scratch:SI 3 "r")]
9091 "TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
9092 [(set (match_dup 3) (match_dup 4))
9094 [(set (reg:CC CC_REGNUM)
9095 (compare:CC (const_int 0) (match_dup 3)))
9096 (set (match_dup 0) (minus:SI (const_int 0) (match_dup 3)))])
9098 (plus:SI (plus:SI (match_dup 0) (match_dup 3))
9099 (geu:SI (reg:CC CC_REGNUM) (const_int 0))))]
9101 if (CONST_INT_P (operands[2]))
9102 operands[4] = plus_constant (SImode, operands[1], -INTVAL (operands[2]));
9104 operands[4] = gen_rtx_MINUS (SImode, operands[1], operands[2]);
9107 (define_insn "*cond_move"
9108 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9109 (if_then_else:SI (match_operator 3 "equality_operator"
9110 [(match_operator 4 "arm_comparison_operator"
9111 [(match_operand 5 "cc_register" "") (const_int 0)])
9113 (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
9114 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))]
9117 if (GET_CODE (operands[3]) == NE)
9119 if (which_alternative != 1)
9120 output_asm_insn (\"mov%D4\\t%0, %2\", operands);
9121 if (which_alternative != 0)
9122 output_asm_insn (\"mov%d4\\t%0, %1\", operands);
9125 if (which_alternative != 0)
9126 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
9127 if (which_alternative != 1)
9128 output_asm_insn (\"mov%d4\\t%0, %2\", operands);
9131 [(set_attr "conds" "use")
9132 (set_attr_alternative "type"
9133 [(if_then_else (match_operand 2 "const_int_operand" "")
9134 (const_string "mov_imm")
9135 (const_string "mov_reg"))
9136 (if_then_else (match_operand 1 "const_int_operand" "")
9137 (const_string "mov_imm")
9138 (const_string "mov_reg"))
9139 (const_string "multiple")])
9140 (set_attr "length" "4,4,8")]
9143 (define_insn "*cond_arith"
9144 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9145 (match_operator:SI 5 "shiftable_operator"
9146 [(match_operator:SI 4 "arm_comparison_operator"
9147 [(match_operand:SI 2 "s_register_operand" "r,r")
9148 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
9149 (match_operand:SI 1 "s_register_operand" "0,?r")]))
9150 (clobber (reg:CC CC_REGNUM))]
9153 if (GET_CODE (operands[4]) == LT && operands[3] == const0_rtx)
9154 return \"%i5\\t%0, %1, %2, lsr #31\";
9156 output_asm_insn (\"cmp\\t%2, %3\", operands);
9157 if (GET_CODE (operands[5]) == AND)
9158 output_asm_insn (\"mov%D4\\t%0, #0\", operands);
9159 else if (GET_CODE (operands[5]) == MINUS)
9160 output_asm_insn (\"rsb%D4\\t%0, %1, #0\", operands);
9161 else if (which_alternative != 0)
9162 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
9163 return \"%i5%d4\\t%0, %1, #1\";
9165 [(set_attr "conds" "clob")
9166 (set_attr "length" "12")
9167 (set_attr "type" "multiple")]
9170 (define_insn "*cond_sub"
9171 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9172 (minus:SI (match_operand:SI 1 "s_register_operand" "0,?r")
9173 (match_operator:SI 4 "arm_comparison_operator"
9174 [(match_operand:SI 2 "s_register_operand" "r,r")
9175 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
9176 (clobber (reg:CC CC_REGNUM))]
9179 output_asm_insn (\"cmp\\t%2, %3\", operands);
9180 if (which_alternative != 0)
9181 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
9182 return \"sub%d4\\t%0, %1, #1\";
9184 [(set_attr "conds" "clob")
9185 (set_attr "length" "8,12")
9186 (set_attr "type" "multiple")]
9189 (define_insn "*cmp_ite0"
9190 [(set (match_operand 6 "dominant_cc_register" "")
9193 (match_operator 4 "arm_comparison_operator"
9194 [(match_operand:SI 0 "s_register_operand"
9195 "l,l,l,r,r,r,r,r,r")
9196 (match_operand:SI 1 "arm_add_operand"
9197 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
9198 (match_operator:SI 5 "arm_comparison_operator"
9199 [(match_operand:SI 2 "s_register_operand"
9200 "l,r,r,l,l,r,r,r,r")
9201 (match_operand:SI 3 "arm_add_operand"
9202 "lPy,rI,L,lPy,lPy,rI,rI,L,L")])
9208 static const char * const cmp1[NUM_OF_COND_CMP][2] =
9210 {\"cmp%d5\\t%0, %1\",
9211 \"cmp%d4\\t%2, %3\"},
9212 {\"cmn%d5\\t%0, #%n1\",
9213 \"cmp%d4\\t%2, %3\"},
9214 {\"cmp%d5\\t%0, %1\",
9215 \"cmn%d4\\t%2, #%n3\"},
9216 {\"cmn%d5\\t%0, #%n1\",
9217 \"cmn%d4\\t%2, #%n3\"}
9219 static const char * const cmp2[NUM_OF_COND_CMP][2] =
9224 \"cmn\\t%0, #%n1\"},
9225 {\"cmn\\t%2, #%n3\",
9227 {\"cmn\\t%2, #%n3\",
9230 static const char * const ite[2] =
9235 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
9236 CMP_CMP, CMN_CMP, CMP_CMP,
9237 CMN_CMP, CMP_CMN, CMN_CMN};
9239 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
9241 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
9242 if (TARGET_THUMB2) {
9243 output_asm_insn (ite[swap], operands);
9245 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
9248 [(set_attr "conds" "set")
9249 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
9250 (set_attr "type" "multiple")
9251 (set_attr_alternative "length"
9257 (if_then_else (eq_attr "is_thumb" "no")
9260 (if_then_else (eq_attr "is_thumb" "no")
9263 (if_then_else (eq_attr "is_thumb" "no")
9266 (if_then_else (eq_attr "is_thumb" "no")
9271 (define_insn "*cmp_ite1"
9272 [(set (match_operand 6 "dominant_cc_register" "")
9275 (match_operator 4 "arm_comparison_operator"
9276 [(match_operand:SI 0 "s_register_operand"
9277 "l,l,l,r,r,r,r,r,r")
9278 (match_operand:SI 1 "arm_add_operand"
9279 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
9280 (match_operator:SI 5 "arm_comparison_operator"
9281 [(match_operand:SI 2 "s_register_operand"
9282 "l,r,r,l,l,r,r,r,r")
9283 (match_operand:SI 3 "arm_add_operand"
9284 "lPy,rI,L,lPy,lPy,rI,rI,L,L")])
9290 static const char * const cmp1[NUM_OF_COND_CMP][2] =
9294 {\"cmn\\t%0, #%n1\",
9297 \"cmn\\t%2, #%n3\"},
9298 {\"cmn\\t%0, #%n1\",
9301 static const char * const cmp2[NUM_OF_COND_CMP][2] =
9303 {\"cmp%d4\\t%2, %3\",
9304 \"cmp%D5\\t%0, %1\"},
9305 {\"cmp%d4\\t%2, %3\",
9306 \"cmn%D5\\t%0, #%n1\"},
9307 {\"cmn%d4\\t%2, #%n3\",
9308 \"cmp%D5\\t%0, %1\"},
9309 {\"cmn%d4\\t%2, #%n3\",
9310 \"cmn%D5\\t%0, #%n1\"}
9312 static const char * const ite[2] =
9317 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
9318 CMP_CMP, CMN_CMP, CMP_CMP,
9319 CMN_CMP, CMP_CMN, CMN_CMN};
9321 comparison_dominates_p (GET_CODE (operands[5]),
9322 reverse_condition (GET_CODE (operands[4])));
9324 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
9325 if (TARGET_THUMB2) {
9326 output_asm_insn (ite[swap], operands);
9328 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
9331 [(set_attr "conds" "set")
9332 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
9333 (set_attr_alternative "length"
9339 (if_then_else (eq_attr "is_thumb" "no")
9342 (if_then_else (eq_attr "is_thumb" "no")
9345 (if_then_else (eq_attr "is_thumb" "no")
9348 (if_then_else (eq_attr "is_thumb" "no")
9351 (set_attr "type" "multiple")]
9354 (define_insn "*cmp_and"
9355 [(set (match_operand 6 "dominant_cc_register" "")
9358 (match_operator 4 "arm_comparison_operator"
9359 [(match_operand:SI 0 "s_register_operand"
9360 "l,l,l,r,r,r,r,r,r")
9361 (match_operand:SI 1 "arm_add_operand"
9362 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
9363 (match_operator:SI 5 "arm_comparison_operator"
9364 [(match_operand:SI 2 "s_register_operand"
9365 "l,r,r,l,l,r,r,r,r")
9366 (match_operand:SI 3 "arm_add_operand"
9367 "lPy,rI,L,lPy,lPy,rI,rI,L,L")]))
9372 static const char *const cmp1[NUM_OF_COND_CMP][2] =
9374 {\"cmp%d5\\t%0, %1\",
9375 \"cmp%d4\\t%2, %3\"},
9376 {\"cmn%d5\\t%0, #%n1\",
9377 \"cmp%d4\\t%2, %3\"},
9378 {\"cmp%d5\\t%0, %1\",
9379 \"cmn%d4\\t%2, #%n3\"},
9380 {\"cmn%d5\\t%0, #%n1\",
9381 \"cmn%d4\\t%2, #%n3\"}
9383 static const char *const cmp2[NUM_OF_COND_CMP][2] =
9388 \"cmn\\t%0, #%n1\"},
9389 {\"cmn\\t%2, #%n3\",
9391 {\"cmn\\t%2, #%n3\",
9394 static const char *const ite[2] =
9399 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
9400 CMP_CMP, CMN_CMP, CMP_CMP,
9401 CMN_CMP, CMP_CMN, CMN_CMN};
9403 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
9405 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
9406 if (TARGET_THUMB2) {
9407 output_asm_insn (ite[swap], operands);
9409 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
9412 [(set_attr "conds" "set")
9413 (set_attr "predicable" "no")
9414 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
9415 (set_attr_alternative "length"
9421 (if_then_else (eq_attr "is_thumb" "no")
9424 (if_then_else (eq_attr "is_thumb" "no")
9427 (if_then_else (eq_attr "is_thumb" "no")
9430 (if_then_else (eq_attr "is_thumb" "no")
9433 (set_attr "type" "multiple")]
9436 (define_insn "*cmp_ior"
9437 [(set (match_operand 6 "dominant_cc_register" "")
9440 (match_operator 4 "arm_comparison_operator"
9441 [(match_operand:SI 0 "s_register_operand"
9442 "l,l,l,r,r,r,r,r,r")
9443 (match_operand:SI 1 "arm_add_operand"
9444 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
9445 (match_operator:SI 5 "arm_comparison_operator"
9446 [(match_operand:SI 2 "s_register_operand"
9447 "l,r,r,l,l,r,r,r,r")
9448 (match_operand:SI 3 "arm_add_operand"
9449 "lPy,rI,L,lPy,lPy,rI,rI,L,L")]))
9454 static const char *const cmp1[NUM_OF_COND_CMP][2] =
9458 {\"cmn\\t%0, #%n1\",
9461 \"cmn\\t%2, #%n3\"},
9462 {\"cmn\\t%0, #%n1\",
9465 static const char *const cmp2[NUM_OF_COND_CMP][2] =
9467 {\"cmp%D4\\t%2, %3\",
9468 \"cmp%D5\\t%0, %1\"},
9469 {\"cmp%D4\\t%2, %3\",
9470 \"cmn%D5\\t%0, #%n1\"},
9471 {\"cmn%D4\\t%2, #%n3\",
9472 \"cmp%D5\\t%0, %1\"},
9473 {\"cmn%D4\\t%2, #%n3\",
9474 \"cmn%D5\\t%0, #%n1\"}
9476 static const char *const ite[2] =
9481 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
9482 CMP_CMP, CMN_CMP, CMP_CMP,
9483 CMN_CMP, CMP_CMN, CMN_CMN};
9485 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
9487 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
9488 if (TARGET_THUMB2) {
9489 output_asm_insn (ite[swap], operands);
9491 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
9495 [(set_attr "conds" "set")
9496 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
9497 (set_attr_alternative "length"
9503 (if_then_else (eq_attr "is_thumb" "no")
9506 (if_then_else (eq_attr "is_thumb" "no")
9509 (if_then_else (eq_attr "is_thumb" "no")
9512 (if_then_else (eq_attr "is_thumb" "no")
9515 (set_attr "type" "multiple")]
9518 (define_insn_and_split "*ior_scc_scc"
9519 [(set (match_operand:SI 0 "s_register_operand" "=Ts")
9520 (ior:SI (match_operator:SI 3 "arm_comparison_operator"
9521 [(match_operand:SI 1 "s_register_operand" "r")
9522 (match_operand:SI 2 "arm_add_operand" "rIL")])
9523 (match_operator:SI 6 "arm_comparison_operator"
9524 [(match_operand:SI 4 "s_register_operand" "r")
9525 (match_operand:SI 5 "arm_add_operand" "rIL")])))
9526 (clobber (reg:CC CC_REGNUM))]
9528 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_OR_Y)
9531 "TARGET_32BIT && reload_completed"
9535 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9536 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9538 (set (match_dup 0) (ne:SI (match_dup 7) (const_int 0)))]
9540 = gen_rtx_REG (arm_select_dominance_cc_mode (operands[3], operands[6],
9543 [(set_attr "conds" "clob")
9544 (set_attr "length" "16")
9545 (set_attr "type" "multiple")]
9548 ; If the above pattern is followed by a CMP insn, then the compare is
9549 ; redundant, since we can rework the conditional instruction that follows.
9550 (define_insn_and_split "*ior_scc_scc_cmp"
9551 [(set (match_operand 0 "dominant_cc_register" "")
9552 (compare (ior:SI (match_operator:SI 3 "arm_comparison_operator"
9553 [(match_operand:SI 1 "s_register_operand" "r")
9554 (match_operand:SI 2 "arm_add_operand" "rIL")])
9555 (match_operator:SI 6 "arm_comparison_operator"
9556 [(match_operand:SI 4 "s_register_operand" "r")
9557 (match_operand:SI 5 "arm_add_operand" "rIL")]))
9559 (set (match_operand:SI 7 "s_register_operand" "=Ts")
9560 (ior:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9561 (match_op_dup 6 [(match_dup 4) (match_dup 5)])))]
9564 "TARGET_32BIT && reload_completed"
9568 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9569 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9571 (set (match_dup 7) (ne:SI (match_dup 0) (const_int 0)))]
9573 [(set_attr "conds" "set")
9574 (set_attr "length" "16")
9575 (set_attr "type" "multiple")]
9578 (define_insn_and_split "*and_scc_scc"
9579 [(set (match_operand:SI 0 "s_register_operand" "=Ts")
9580 (and:SI (match_operator:SI 3 "arm_comparison_operator"
9581 [(match_operand:SI 1 "s_register_operand" "r")
9582 (match_operand:SI 2 "arm_add_operand" "rIL")])
9583 (match_operator:SI 6 "arm_comparison_operator"
9584 [(match_operand:SI 4 "s_register_operand" "r")
9585 (match_operand:SI 5 "arm_add_operand" "rIL")])))
9586 (clobber (reg:CC CC_REGNUM))]
9588 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
9591 "TARGET_32BIT && reload_completed
9592 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
9597 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9598 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9600 (set (match_dup 0) (ne:SI (match_dup 7) (const_int 0)))]
9602 = gen_rtx_REG (arm_select_dominance_cc_mode (operands[3], operands[6],
9605 [(set_attr "conds" "clob")
9606 (set_attr "length" "16")
9607 (set_attr "type" "multiple")]
9610 ; If the above pattern is followed by a CMP insn, then the compare is
9611 ; redundant, since we can rework the conditional instruction that follows.
9612 (define_insn_and_split "*and_scc_scc_cmp"
9613 [(set (match_operand 0 "dominant_cc_register" "")
9614 (compare (and:SI (match_operator:SI 3 "arm_comparison_operator"
9615 [(match_operand:SI 1 "s_register_operand" "r")
9616 (match_operand:SI 2 "arm_add_operand" "rIL")])
9617 (match_operator:SI 6 "arm_comparison_operator"
9618 [(match_operand:SI 4 "s_register_operand" "r")
9619 (match_operand:SI 5 "arm_add_operand" "rIL")]))
9621 (set (match_operand:SI 7 "s_register_operand" "=Ts")
9622 (and:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9623 (match_op_dup 6 [(match_dup 4) (match_dup 5)])))]
9626 "TARGET_32BIT && reload_completed"
9630 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9631 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9633 (set (match_dup 7) (ne:SI (match_dup 0) (const_int 0)))]
9635 [(set_attr "conds" "set")
9636 (set_attr "length" "16")
9637 (set_attr "type" "multiple")]
9640 ;; If there is no dominance in the comparison, then we can still save an
9641 ;; instruction in the AND case, since we can know that the second compare
9642 ;; need only zero the value if false (if true, then the value is already
9644 (define_insn_and_split "*and_scc_scc_nodom"
9645 [(set (match_operand:SI 0 "s_register_operand" "=&Ts,&Ts,&Ts")
9646 (and:SI (match_operator:SI 3 "arm_comparison_operator"
9647 [(match_operand:SI 1 "s_register_operand" "r,r,0")
9648 (match_operand:SI 2 "arm_add_operand" "rIL,0,rIL")])
9649 (match_operator:SI 6 "arm_comparison_operator"
9650 [(match_operand:SI 4 "s_register_operand" "r,r,r")
9651 (match_operand:SI 5 "arm_add_operand" "rIL,rIL,rIL")])))
9652 (clobber (reg:CC CC_REGNUM))]
9654 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
9657 "TARGET_32BIT && reload_completed"
9658 [(parallel [(set (match_dup 0)
9659 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
9660 (clobber (reg:CC CC_REGNUM))])
9661 (set (match_dup 7) (match_op_dup 8 [(match_dup 4) (match_dup 5)]))
9663 (if_then_else:SI (match_op_dup 6 [(match_dup 7) (const_int 0)])
9666 "operands[7] = gen_rtx_REG (SELECT_CC_MODE (GET_CODE (operands[6]),
9667 operands[4], operands[5]),
9669 operands[8] = gen_rtx_COMPARE (GET_MODE (operands[7]), operands[4],
9671 [(set_attr "conds" "clob")
9672 (set_attr "length" "20")
9673 (set_attr "type" "multiple")]
9677 [(set (reg:CC_NOOV CC_REGNUM)
9678 (compare:CC_NOOV (ior:SI
9679 (and:SI (match_operand:SI 0 "s_register_operand" "")
9681 (match_operator:SI 1 "arm_comparison_operator"
9682 [(match_operand:SI 2 "s_register_operand" "")
9683 (match_operand:SI 3 "arm_add_operand" "")]))
9685 (clobber (match_operand:SI 4 "s_register_operand" ""))]
9688 (ior:SI (match_op_dup 1 [(match_dup 2) (match_dup 3)])
9690 (set (reg:CC_NOOV CC_REGNUM)
9691 (compare:CC_NOOV (and:SI (match_dup 4) (const_int 1))
9696 [(set (reg:CC_NOOV CC_REGNUM)
9697 (compare:CC_NOOV (ior:SI
9698 (match_operator:SI 1 "arm_comparison_operator"
9699 [(match_operand:SI 2 "s_register_operand" "")
9700 (match_operand:SI 3 "arm_add_operand" "")])
9701 (and:SI (match_operand:SI 0 "s_register_operand" "")
9704 (clobber (match_operand:SI 4 "s_register_operand" ""))]
9707 (ior:SI (match_op_dup 1 [(match_dup 2) (match_dup 3)])
9709 (set (reg:CC_NOOV CC_REGNUM)
9710 (compare:CC_NOOV (and:SI (match_dup 4) (const_int 1))
9713 ;; ??? The conditional patterns above need checking for Thumb-2 usefulness
9715 (define_insn_and_split "*negscc"
9716 [(set (match_operand:SI 0 "s_register_operand" "=r")
9717 (neg:SI (match_operator 3 "arm_comparison_operator"
9718 [(match_operand:SI 1 "s_register_operand" "r")
9719 (match_operand:SI 2 "arm_rhs_operand" "rI")])))
9720 (clobber (reg:CC CC_REGNUM))]
9723 "&& reload_completed"
9726 rtx cc_reg = gen_rtx_REG (CCmode, CC_REGNUM);
9728 if (GET_CODE (operands[3]) == LT && operands[2] == const0_rtx)
9730 /* Emit mov\\t%0, %1, asr #31 */
9731 emit_insn (gen_rtx_SET (operands[0],
9732 gen_rtx_ASHIFTRT (SImode,
9737 else if (GET_CODE (operands[3]) == NE)
9739 /* Emit subs\\t%0, %1, %2\;mvnne\\t%0, #0 */
9740 if (CONST_INT_P (operands[2]))
9741 emit_insn (gen_cmpsi2_addneg (operands[0], operands[1], operands[2],
9742 GEN_INT (- INTVAL (operands[2]))));
9744 emit_insn (gen_subsi3_compare (operands[0], operands[1], operands[2]));
9746 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
9750 gen_rtx_SET (operands[0],
9756 /* Emit: cmp\\t%1, %2\;mov%D3\\t%0, #0\;mvn%d3\\t%0, #0 */
9757 emit_insn (gen_rtx_SET (cc_reg,
9758 gen_rtx_COMPARE (CCmode, operands[1], operands[2])));
9759 enum rtx_code rc = GET_CODE (operands[3]);
9761 rc = reverse_condition (rc);
9762 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
9767 gen_rtx_SET (operands[0], const0_rtx)));
9768 rc = GET_CODE (operands[3]);
9769 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
9774 gen_rtx_SET (operands[0],
9780 [(set_attr "conds" "clob")
9781 (set_attr "length" "12")
9782 (set_attr "type" "multiple")]
9785 (define_insn_and_split "movcond_addsi"
9786 [(set (match_operand:SI 0 "s_register_operand" "=r,l,r")
9788 (match_operator 5 "comparison_operator"
9789 [(plus:SI (match_operand:SI 3 "s_register_operand" "r,r,r")
9790 (match_operand:SI 4 "arm_add_operand" "rIL,rIL,rIL"))
9792 (match_operand:SI 1 "arm_rhs_operand" "rI,rPy,r")
9793 (match_operand:SI 2 "arm_rhs_operand" "rI,rPy,r")))
9794 (clobber (reg:CC CC_REGNUM))]
9797 "&& reload_completed"
9798 [(set (reg:CC_NOOV CC_REGNUM)
9800 (plus:SI (match_dup 3)
9803 (set (match_dup 0) (match_dup 1))
9804 (cond_exec (match_dup 6)
9805 (set (match_dup 0) (match_dup 2)))]
9808 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[5]),
9809 operands[3], operands[4]);
9810 enum rtx_code rc = GET_CODE (operands[5]);
9811 operands[6] = gen_rtx_REG (mode, CC_REGNUM);
9812 gcc_assert (!(mode == CCFPmode || mode == CCFPEmode));
9813 if (!REG_P (operands[2]) || REGNO (operands[2]) != REGNO (operands[0]))
9814 rc = reverse_condition (rc);
9816 std::swap (operands[1], operands[2]);
9818 operands[6] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
9821 [(set_attr "conds" "clob")
9822 (set_attr "enabled_for_depr_it" "no,yes,yes")
9823 (set_attr "type" "multiple")]
9826 (define_insn "movcond"
9827 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9829 (match_operator 5 "arm_comparison_operator"
9830 [(match_operand:SI 3 "s_register_operand" "r,r,r")
9831 (match_operand:SI 4 "arm_add_operand" "rIL,rIL,rIL")])
9832 (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
9833 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
9834 (clobber (reg:CC CC_REGNUM))]
9837 if (GET_CODE (operands[5]) == LT
9838 && (operands[4] == const0_rtx))
9840 if (which_alternative != 1 && REG_P (operands[1]))
9842 if (operands[2] == const0_rtx)
9843 return \"and\\t%0, %1, %3, asr #31\";
9844 return \"ands\\t%0, %1, %3, asr #32\;movcc\\t%0, %2\";
9846 else if (which_alternative != 0 && REG_P (operands[2]))
9848 if (operands[1] == const0_rtx)
9849 return \"bic\\t%0, %2, %3, asr #31\";
9850 return \"bics\\t%0, %2, %3, asr #32\;movcs\\t%0, %1\";
9852 /* The only case that falls through to here is when both ops 1 & 2
9856 if (GET_CODE (operands[5]) == GE
9857 && (operands[4] == const0_rtx))
9859 if (which_alternative != 1 && REG_P (operands[1]))
9861 if (operands[2] == const0_rtx)
9862 return \"bic\\t%0, %1, %3, asr #31\";
9863 return \"bics\\t%0, %1, %3, asr #32\;movcs\\t%0, %2\";
9865 else if (which_alternative != 0 && REG_P (operands[2]))
9867 if (operands[1] == const0_rtx)
9868 return \"and\\t%0, %2, %3, asr #31\";
9869 return \"ands\\t%0, %2, %3, asr #32\;movcc\\t%0, %1\";
9871 /* The only case that falls through to here is when both ops 1 & 2
9874 if (CONST_INT_P (operands[4])
9875 && !const_ok_for_arm (INTVAL (operands[4])))
9876 output_asm_insn (\"cmn\\t%3, #%n4\", operands);
9878 output_asm_insn (\"cmp\\t%3, %4\", operands);
9879 if (which_alternative != 0)
9880 output_asm_insn (\"mov%d5\\t%0, %1\", operands);
9881 if (which_alternative != 1)
9882 output_asm_insn (\"mov%D5\\t%0, %2\", operands);
9885 [(set_attr "conds" "clob")
9886 (set_attr "length" "8,8,12")
9887 (set_attr "type" "multiple")]
9890 ;; ??? The patterns below need checking for Thumb-2 usefulness.
9892 (define_insn "*ifcompare_plus_move"
9893 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9894 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
9895 [(match_operand:SI 4 "s_register_operand" "r,r")
9896 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
9898 (match_operand:SI 2 "s_register_operand" "r,r")
9899 (match_operand:SI 3 "arm_add_operand" "rIL,rIL"))
9900 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))
9901 (clobber (reg:CC CC_REGNUM))]
9904 [(set_attr "conds" "clob")
9905 (set_attr "length" "8,12")
9906 (set_attr "type" "multiple")]
9909 (define_insn "*if_plus_move"
9910 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
9912 (match_operator 4 "arm_comparison_operator"
9913 [(match_operand 5 "cc_register" "") (const_int 0)])
9915 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
9916 (match_operand:SI 3 "arm_add_operand" "rI,L,rI,L"))
9917 (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")))]
9921 sub%d4\\t%0, %2, #%n3
9922 add%d4\\t%0, %2, %3\;mov%D4\\t%0, %1
9923 sub%d4\\t%0, %2, #%n3\;mov%D4\\t%0, %1"
9924 [(set_attr "conds" "use")
9925 (set_attr "length" "4,4,8,8")
9926 (set_attr_alternative "type"
9927 [(if_then_else (match_operand 3 "const_int_operand" "")
9928 (const_string "alu_imm" )
9929 (const_string "alu_sreg"))
9930 (const_string "alu_imm")
9931 (const_string "multiple")
9932 (const_string "multiple")])]
9935 (define_insn "*ifcompare_move_plus"
9936 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9937 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
9938 [(match_operand:SI 4 "s_register_operand" "r,r")
9939 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
9940 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
9942 (match_operand:SI 2 "s_register_operand" "r,r")
9943 (match_operand:SI 3 "arm_add_operand" "rIL,rIL"))))
9944 (clobber (reg:CC CC_REGNUM))]
9947 [(set_attr "conds" "clob")
9948 (set_attr "length" "8,12")
9949 (set_attr "type" "multiple")]
9952 (define_insn "*if_move_plus"
9953 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
9955 (match_operator 4 "arm_comparison_operator"
9956 [(match_operand 5 "cc_register" "") (const_int 0)])
9957 (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")
9959 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
9960 (match_operand:SI 3 "arm_add_operand" "rI,L,rI,L"))))]
9964 sub%D4\\t%0, %2, #%n3
9965 add%D4\\t%0, %2, %3\;mov%d4\\t%0, %1
9966 sub%D4\\t%0, %2, #%n3\;mov%d4\\t%0, %1"
9967 [(set_attr "conds" "use")
9968 (set_attr "length" "4,4,8,8")
9969 (set_attr_alternative "type"
9970 [(if_then_else (match_operand 3 "const_int_operand" "")
9971 (const_string "alu_imm" )
9972 (const_string "alu_sreg"))
9973 (const_string "alu_imm")
9974 (const_string "multiple")
9975 (const_string "multiple")])]
9978 (define_insn "*ifcompare_arith_arith"
9979 [(set (match_operand:SI 0 "s_register_operand" "=r")
9980 (if_then_else:SI (match_operator 9 "arm_comparison_operator"
9981 [(match_operand:SI 5 "s_register_operand" "r")
9982 (match_operand:SI 6 "arm_add_operand" "rIL")])
9983 (match_operator:SI 8 "shiftable_operator"
9984 [(match_operand:SI 1 "s_register_operand" "r")
9985 (match_operand:SI 2 "arm_rhs_operand" "rI")])
9986 (match_operator:SI 7 "shiftable_operator"
9987 [(match_operand:SI 3 "s_register_operand" "r")
9988 (match_operand:SI 4 "arm_rhs_operand" "rI")])))
9989 (clobber (reg:CC CC_REGNUM))]
9992 [(set_attr "conds" "clob")
9993 (set_attr "length" "12")
9994 (set_attr "type" "multiple")]
9997 (define_insn "*if_arith_arith"
9998 [(set (match_operand:SI 0 "s_register_operand" "=r")
9999 (if_then_else:SI (match_operator 5 "arm_comparison_operator"
10000 [(match_operand 8 "cc_register" "") (const_int 0)])
10001 (match_operator:SI 6 "shiftable_operator"
10002 [(match_operand:SI 1 "s_register_operand" "r")
10003 (match_operand:SI 2 "arm_rhs_operand" "rI")])
10004 (match_operator:SI 7 "shiftable_operator"
10005 [(match_operand:SI 3 "s_register_operand" "r")
10006 (match_operand:SI 4 "arm_rhs_operand" "rI")])))]
10008 "%I6%d5\\t%0, %1, %2\;%I7%D5\\t%0, %3, %4"
10009 [(set_attr "conds" "use")
10010 (set_attr "length" "8")
10011 (set_attr "type" "multiple")]
10014 (define_insn "*ifcompare_arith_move"
10015 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10016 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
10017 [(match_operand:SI 2 "s_register_operand" "r,r")
10018 (match_operand:SI 3 "arm_add_operand" "rIL,rIL")])
10019 (match_operator:SI 7 "shiftable_operator"
10020 [(match_operand:SI 4 "s_register_operand" "r,r")
10021 (match_operand:SI 5 "arm_rhs_operand" "rI,rI")])
10022 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))
10023 (clobber (reg:CC CC_REGNUM))]
10026 /* If we have an operation where (op x 0) is the identity operation and
10027 the conditional operator is LT or GE and we are comparing against zero and
10028 everything is in registers then we can do this in two instructions. */
10029 if (operands[3] == const0_rtx
10030 && GET_CODE (operands[7]) != AND
10031 && REG_P (operands[5])
10032 && REG_P (operands[1])
10033 && REGNO (operands[1]) == REGNO (operands[4])
10034 && REGNO (operands[4]) != REGNO (operands[0]))
10036 if (GET_CODE (operands[6]) == LT)
10037 return \"and\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\";
10038 else if (GET_CODE (operands[6]) == GE)
10039 return \"bic\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\";
10041 if (CONST_INT_P (operands[3])
10042 && !const_ok_for_arm (INTVAL (operands[3])))
10043 output_asm_insn (\"cmn\\t%2, #%n3\", operands);
10045 output_asm_insn (\"cmp\\t%2, %3\", operands);
10046 output_asm_insn (\"%I7%d6\\t%0, %4, %5\", operands);
10047 if (which_alternative != 0)
10048 return \"mov%D6\\t%0, %1\";
10051 [(set_attr "conds" "clob")
10052 (set_attr "length" "8,12")
10053 (set_attr "type" "multiple")]
10056 (define_insn "*if_arith_move"
10057 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10058 (if_then_else:SI (match_operator 4 "arm_comparison_operator"
10059 [(match_operand 6 "cc_register" "") (const_int 0)])
10060 (match_operator:SI 5 "shiftable_operator"
10061 [(match_operand:SI 2 "s_register_operand" "r,r")
10062 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
10063 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))]
10066 %I5%d4\\t%0, %2, %3
10067 %I5%d4\\t%0, %2, %3\;mov%D4\\t%0, %1"
10068 [(set_attr "conds" "use")
10069 (set_attr "length" "4,8")
10070 (set_attr_alternative "type"
10071 [(if_then_else (match_operand 3 "const_int_operand" "")
10072 (const_string "alu_shift_imm" )
10073 (const_string "alu_shift_reg"))
10074 (const_string "multiple")])]
10077 (define_insn "*ifcompare_move_arith"
10078 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10079 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
10080 [(match_operand:SI 4 "s_register_operand" "r,r")
10081 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
10082 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
10083 (match_operator:SI 7 "shiftable_operator"
10084 [(match_operand:SI 2 "s_register_operand" "r,r")
10085 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
10086 (clobber (reg:CC CC_REGNUM))]
10089 /* If we have an operation where (op x 0) is the identity operation and
10090 the conditional operator is LT or GE and we are comparing against zero and
10091 everything is in registers then we can do this in two instructions */
10092 if (operands[5] == const0_rtx
10093 && GET_CODE (operands[7]) != AND
10094 && REG_P (operands[3])
10095 && REG_P (operands[1])
10096 && REGNO (operands[1]) == REGNO (operands[2])
10097 && REGNO (operands[2]) != REGNO (operands[0]))
10099 if (GET_CODE (operands[6]) == GE)
10100 return \"and\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\";
10101 else if (GET_CODE (operands[6]) == LT)
10102 return \"bic\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\";
10105 if (CONST_INT_P (operands[5])
10106 && !const_ok_for_arm (INTVAL (operands[5])))
10107 output_asm_insn (\"cmn\\t%4, #%n5\", operands);
10109 output_asm_insn (\"cmp\\t%4, %5\", operands);
10111 if (which_alternative != 0)
10112 output_asm_insn (\"mov%d6\\t%0, %1\", operands);
10113 return \"%I7%D6\\t%0, %2, %3\";
10115 [(set_attr "conds" "clob")
10116 (set_attr "length" "8,12")
10117 (set_attr "type" "multiple")]
10120 (define_insn "*if_move_arith"
10121 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10123 (match_operator 4 "arm_comparison_operator"
10124 [(match_operand 6 "cc_register" "") (const_int 0)])
10125 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
10126 (match_operator:SI 5 "shiftable_operator"
10127 [(match_operand:SI 2 "s_register_operand" "r,r")
10128 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))]
10131 %I5%D4\\t%0, %2, %3
10132 %I5%D4\\t%0, %2, %3\;mov%d4\\t%0, %1"
10133 [(set_attr "conds" "use")
10134 (set_attr "length" "4,8")
10135 (set_attr_alternative "type"
10136 [(if_then_else (match_operand 3 "const_int_operand" "")
10137 (const_string "alu_shift_imm" )
10138 (const_string "alu_shift_reg"))
10139 (const_string "multiple")])]
10142 (define_insn "*ifcompare_move_not"
10143 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10145 (match_operator 5 "arm_comparison_operator"
10146 [(match_operand:SI 3 "s_register_operand" "r,r")
10147 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
10148 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
10150 (match_operand:SI 2 "s_register_operand" "r,r"))))
10151 (clobber (reg:CC CC_REGNUM))]
10154 [(set_attr "conds" "clob")
10155 (set_attr "length" "8,12")
10156 (set_attr "type" "multiple")]
10159 (define_insn "*if_move_not"
10160 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
10162 (match_operator 4 "arm_comparison_operator"
10163 [(match_operand 3 "cc_register" "") (const_int 0)])
10164 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
10165 (not:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))))]
10169 mov%d4\\t%0, %1\;mvn%D4\\t%0, %2
10170 mvn%d4\\t%0, #%B1\;mvn%D4\\t%0, %2"
10171 [(set_attr "conds" "use")
10172 (set_attr "type" "mvn_reg")
10173 (set_attr "length" "4,8,8")
10174 (set_attr "type" "mvn_reg,multiple,multiple")]
10177 (define_insn "*ifcompare_not_move"
10178 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10180 (match_operator 5 "arm_comparison_operator"
10181 [(match_operand:SI 3 "s_register_operand" "r,r")
10182 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
10184 (match_operand:SI 2 "s_register_operand" "r,r"))
10185 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
10186 (clobber (reg:CC CC_REGNUM))]
10189 [(set_attr "conds" "clob")
10190 (set_attr "length" "8,12")
10191 (set_attr "type" "multiple")]
10194 (define_insn "*if_not_move"
10195 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
10197 (match_operator 4 "arm_comparison_operator"
10198 [(match_operand 3 "cc_register" "") (const_int 0)])
10199 (not:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))
10200 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
10204 mov%D4\\t%0, %1\;mvn%d4\\t%0, %2
10205 mvn%D4\\t%0, #%B1\;mvn%d4\\t%0, %2"
10206 [(set_attr "conds" "use")
10207 (set_attr "type" "mvn_reg,multiple,multiple")
10208 (set_attr "length" "4,8,8")]
10211 (define_insn "*ifcompare_shift_move"
10212 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10214 (match_operator 6 "arm_comparison_operator"
10215 [(match_operand:SI 4 "s_register_operand" "r,r")
10216 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
10217 (match_operator:SI 7 "shift_operator"
10218 [(match_operand:SI 2 "s_register_operand" "r,r")
10219 (match_operand:SI 3 "arm_rhs_operand" "rM,rM")])
10220 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
10221 (clobber (reg:CC CC_REGNUM))]
10224 [(set_attr "conds" "clob")
10225 (set_attr "length" "8,12")
10226 (set_attr "type" "multiple")]
10229 (define_insn "*if_shift_move"
10230 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
10232 (match_operator 5 "arm_comparison_operator"
10233 [(match_operand 6 "cc_register" "") (const_int 0)])
10234 (match_operator:SI 4 "shift_operator"
10235 [(match_operand:SI 2 "s_register_operand" "r,r,r")
10236 (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM")])
10237 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
10241 mov%D5\\t%0, %1\;mov%d5\\t%0, %2%S4
10242 mvn%D5\\t%0, #%B1\;mov%d5\\t%0, %2%S4"
10243 [(set_attr "conds" "use")
10244 (set_attr "shift" "2")
10245 (set_attr "length" "4,8,8")
10246 (set_attr_alternative "type"
10247 [(if_then_else (match_operand 3 "const_int_operand" "")
10248 (const_string "mov_shift" )
10249 (const_string "mov_shift_reg"))
10250 (const_string "multiple")
10251 (const_string "multiple")])]
10254 (define_insn "*ifcompare_move_shift"
10255 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10257 (match_operator 6 "arm_comparison_operator"
10258 [(match_operand:SI 4 "s_register_operand" "r,r")
10259 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
10260 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
10261 (match_operator:SI 7 "shift_operator"
10262 [(match_operand:SI 2 "s_register_operand" "r,r")
10263 (match_operand:SI 3 "arm_rhs_operand" "rM,rM")])))
10264 (clobber (reg:CC CC_REGNUM))]
10267 [(set_attr "conds" "clob")
10268 (set_attr "length" "8,12")
10269 (set_attr "type" "multiple")]
10272 (define_insn "*if_move_shift"
10273 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
10275 (match_operator 5 "arm_comparison_operator"
10276 [(match_operand 6 "cc_register" "") (const_int 0)])
10277 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
10278 (match_operator:SI 4 "shift_operator"
10279 [(match_operand:SI 2 "s_register_operand" "r,r,r")
10280 (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM")])))]
10284 mov%d5\\t%0, %1\;mov%D5\\t%0, %2%S4
10285 mvn%d5\\t%0, #%B1\;mov%D5\\t%0, %2%S4"
10286 [(set_attr "conds" "use")
10287 (set_attr "shift" "2")
10288 (set_attr "length" "4,8,8")
10289 (set_attr_alternative "type"
10290 [(if_then_else (match_operand 3 "const_int_operand" "")
10291 (const_string "mov_shift" )
10292 (const_string "mov_shift_reg"))
10293 (const_string "multiple")
10294 (const_string "multiple")])]
10297 (define_insn "*ifcompare_shift_shift"
10298 [(set (match_operand:SI 0 "s_register_operand" "=r")
10300 (match_operator 7 "arm_comparison_operator"
10301 [(match_operand:SI 5 "s_register_operand" "r")
10302 (match_operand:SI 6 "arm_add_operand" "rIL")])
10303 (match_operator:SI 8 "shift_operator"
10304 [(match_operand:SI 1 "s_register_operand" "r")
10305 (match_operand:SI 2 "arm_rhs_operand" "rM")])
10306 (match_operator:SI 9 "shift_operator"
10307 [(match_operand:SI 3 "s_register_operand" "r")
10308 (match_operand:SI 4 "arm_rhs_operand" "rM")])))
10309 (clobber (reg:CC CC_REGNUM))]
10312 [(set_attr "conds" "clob")
10313 (set_attr "length" "12")
10314 (set_attr "type" "multiple")]
10317 (define_insn "*if_shift_shift"
10318 [(set (match_operand:SI 0 "s_register_operand" "=r")
10320 (match_operator 5 "arm_comparison_operator"
10321 [(match_operand 8 "cc_register" "") (const_int 0)])
10322 (match_operator:SI 6 "shift_operator"
10323 [(match_operand:SI 1 "s_register_operand" "r")
10324 (match_operand:SI 2 "arm_rhs_operand" "rM")])
10325 (match_operator:SI 7 "shift_operator"
10326 [(match_operand:SI 3 "s_register_operand" "r")
10327 (match_operand:SI 4 "arm_rhs_operand" "rM")])))]
10329 "mov%d5\\t%0, %1%S6\;mov%D5\\t%0, %3%S7"
10330 [(set_attr "conds" "use")
10331 (set_attr "shift" "1")
10332 (set_attr "length" "8")
10333 (set (attr "type") (if_then_else
10334 (and (match_operand 2 "const_int_operand" "")
10335 (match_operand 4 "const_int_operand" ""))
10336 (const_string "mov_shift")
10337 (const_string "mov_shift_reg")))]
10340 (define_insn "*ifcompare_not_arith"
10341 [(set (match_operand:SI 0 "s_register_operand" "=r")
10343 (match_operator 6 "arm_comparison_operator"
10344 [(match_operand:SI 4 "s_register_operand" "r")
10345 (match_operand:SI 5 "arm_add_operand" "rIL")])
10346 (not:SI (match_operand:SI 1 "s_register_operand" "r"))
10347 (match_operator:SI 7 "shiftable_operator"
10348 [(match_operand:SI 2 "s_register_operand" "r")
10349 (match_operand:SI 3 "arm_rhs_operand" "rI")])))
10350 (clobber (reg:CC CC_REGNUM))]
10353 [(set_attr "conds" "clob")
10354 (set_attr "length" "12")
10355 (set_attr "type" "multiple")]
10358 (define_insn "*if_not_arith"
10359 [(set (match_operand:SI 0 "s_register_operand" "=r")
10361 (match_operator 5 "arm_comparison_operator"
10362 [(match_operand 4 "cc_register" "") (const_int 0)])
10363 (not:SI (match_operand:SI 1 "s_register_operand" "r"))
10364 (match_operator:SI 6 "shiftable_operator"
10365 [(match_operand:SI 2 "s_register_operand" "r")
10366 (match_operand:SI 3 "arm_rhs_operand" "rI")])))]
10368 "mvn%d5\\t%0, %1\;%I6%D5\\t%0, %2, %3"
10369 [(set_attr "conds" "use")
10370 (set_attr "type" "mvn_reg")
10371 (set_attr "length" "8")]
10374 (define_insn "*ifcompare_arith_not"
10375 [(set (match_operand:SI 0 "s_register_operand" "=r")
10377 (match_operator 6 "arm_comparison_operator"
10378 [(match_operand:SI 4 "s_register_operand" "r")
10379 (match_operand:SI 5 "arm_add_operand" "rIL")])
10380 (match_operator:SI 7 "shiftable_operator"
10381 [(match_operand:SI 2 "s_register_operand" "r")
10382 (match_operand:SI 3 "arm_rhs_operand" "rI")])
10383 (not:SI (match_operand:SI 1 "s_register_operand" "r"))))
10384 (clobber (reg:CC CC_REGNUM))]
10387 [(set_attr "conds" "clob")
10388 (set_attr "length" "12")
10389 (set_attr "type" "multiple")]
10392 (define_insn "*if_arith_not"
10393 [(set (match_operand:SI 0 "s_register_operand" "=r")
10395 (match_operator 5 "arm_comparison_operator"
10396 [(match_operand 4 "cc_register" "") (const_int 0)])
10397 (match_operator:SI 6 "shiftable_operator"
10398 [(match_operand:SI 2 "s_register_operand" "r")
10399 (match_operand:SI 3 "arm_rhs_operand" "rI")])
10400 (not:SI (match_operand:SI 1 "s_register_operand" "r"))))]
10402 "mvn%D5\\t%0, %1\;%I6%d5\\t%0, %2, %3"
10403 [(set_attr "conds" "use")
10404 (set_attr "type" "multiple")
10405 (set_attr "length" "8")]
10408 (define_insn "*ifcompare_neg_move"
10409 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10411 (match_operator 5 "arm_comparison_operator"
10412 [(match_operand:SI 3 "s_register_operand" "r,r")
10413 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
10414 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r"))
10415 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
10416 (clobber (reg:CC CC_REGNUM))]
10419 [(set_attr "conds" "clob")
10420 (set_attr "length" "8,12")
10421 (set_attr "type" "multiple")]
10424 (define_insn_and_split "*if_neg_move"
10425 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
10427 (match_operator 4 "arm_comparison_operator"
10428 [(match_operand 3 "cc_register" "") (const_int 0)])
10429 (neg:SI (match_operand:SI 2 "s_register_operand" "l,r"))
10430 (match_operand:SI 1 "s_register_operand" "0,0")))]
10433 "&& reload_completed"
10434 [(cond_exec (match_op_dup 4 [(match_dup 3) (const_int 0)])
10435 (set (match_dup 0) (neg:SI (match_dup 2))))]
10437 [(set_attr "conds" "use")
10438 (set_attr "length" "4")
10439 (set_attr "arch" "t2,32")
10440 (set_attr "enabled_for_depr_it" "yes,no")
10441 (set_attr "type" "logic_shift_imm")]
10444 (define_insn "*ifcompare_move_neg"
10445 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10447 (match_operator 5 "arm_comparison_operator"
10448 [(match_operand:SI 3 "s_register_operand" "r,r")
10449 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
10450 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
10451 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r"))))
10452 (clobber (reg:CC CC_REGNUM))]
10455 [(set_attr "conds" "clob")
10456 (set_attr "length" "8,12")
10457 (set_attr "type" "multiple")]
10460 (define_insn_and_split "*if_move_neg"
10461 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
10463 (match_operator 4 "arm_comparison_operator"
10464 [(match_operand 3 "cc_register" "") (const_int 0)])
10465 (match_operand:SI 1 "s_register_operand" "0,0")
10466 (neg:SI (match_operand:SI 2 "s_register_operand" "l,r"))))]
10469 "&& reload_completed"
10470 [(cond_exec (match_dup 5)
10471 (set (match_dup 0) (neg:SI (match_dup 2))))]
10473 machine_mode mode = GET_MODE (operands[3]);
10474 rtx_code rc = GET_CODE (operands[4]);
10476 if (mode == CCFPmode || mode == CCFPEmode)
10477 rc = reverse_condition_maybe_unordered (rc);
10479 rc = reverse_condition (rc);
10481 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[3], const0_rtx);
10483 [(set_attr "conds" "use")
10484 (set_attr "length" "4")
10485 (set_attr "arch" "t2,32")
10486 (set_attr "enabled_for_depr_it" "yes,no")
10487 (set_attr "type" "logic_shift_imm")]
10490 (define_insn "*arith_adjacentmem"
10491 [(set (match_operand:SI 0 "s_register_operand" "=r")
10492 (match_operator:SI 1 "shiftable_operator"
10493 [(match_operand:SI 2 "memory_operand" "m")
10494 (match_operand:SI 3 "memory_operand" "m")]))
10495 (clobber (match_scratch:SI 4 "=r"))]
10496 "TARGET_ARM && adjacent_mem_locations (operands[2], operands[3])"
10502 HOST_WIDE_INT val1 = 0, val2 = 0;
10504 if (REGNO (operands[0]) > REGNO (operands[4]))
10506 ldm[1] = operands[4];
10507 ldm[2] = operands[0];
10511 ldm[1] = operands[0];
10512 ldm[2] = operands[4];
10515 base_reg = XEXP (operands[2], 0);
10517 if (!REG_P (base_reg))
10519 val1 = INTVAL (XEXP (base_reg, 1));
10520 base_reg = XEXP (base_reg, 0);
10523 if (!REG_P (XEXP (operands[3], 0)))
10524 val2 = INTVAL (XEXP (XEXP (operands[3], 0), 1));
10526 arith[0] = operands[0];
10527 arith[3] = operands[1];
10541 if (val1 !=0 && val2 != 0)
10545 if (val1 == 4 || val2 == 4)
10546 /* Other val must be 8, since we know they are adjacent and neither
10548 output_asm_insn (\"ldmib%?\\t%0, {%1, %2}\", ldm);
10549 else if (const_ok_for_arm (val1) || const_ok_for_arm (-val1))
10551 ldm[0] = ops[0] = operands[4];
10553 ops[2] = GEN_INT (val1);
10554 output_add_immediate (ops);
10556 output_asm_insn (\"ldmia%?\\t%0, {%1, %2}\", ldm);
10558 output_asm_insn (\"ldmda%?\\t%0, {%1, %2}\", ldm);
10562 /* Offset is out of range for a single add, so use two ldr. */
10565 ops[2] = GEN_INT (val1);
10566 output_asm_insn (\"ldr%?\\t%0, [%1, %2]\", ops);
10568 ops[2] = GEN_INT (val2);
10569 output_asm_insn (\"ldr%?\\t%0, [%1, %2]\", ops);
10572 else if (val1 != 0)
10575 output_asm_insn (\"ldmda%?\\t%0, {%1, %2}\", ldm);
10577 output_asm_insn (\"ldmia%?\\t%0, {%1, %2}\", ldm);
10582 output_asm_insn (\"ldmia%?\\t%0, {%1, %2}\", ldm);
10584 output_asm_insn (\"ldmda%?\\t%0, {%1, %2}\", ldm);
10586 output_asm_insn (\"%I3%?\\t%0, %1, %2\", arith);
10589 [(set_attr "length" "12")
10590 (set_attr "predicable" "yes")
10591 (set_attr "type" "load1")]
10594 ; This pattern is never tried by combine, so do it as a peephole
10597 [(set (match_operand:SI 0 "arm_general_register_operand" "")
10598 (match_operand:SI 1 "arm_general_register_operand" ""))
10599 (set (reg:CC CC_REGNUM)
10600 (compare:CC (match_dup 1) (const_int 0)))]
10602 [(parallel [(set (reg:CC CC_REGNUM) (compare:CC (match_dup 1) (const_int 0)))
10603 (set (match_dup 0) (match_dup 1))])]
10608 [(set (match_operand:SI 0 "s_register_operand" "")
10609 (and:SI (ge:SI (match_operand:SI 1 "s_register_operand" "")
10611 (neg:SI (match_operator:SI 2 "arm_comparison_operator"
10612 [(match_operand:SI 3 "s_register_operand" "")
10613 (match_operand:SI 4 "arm_rhs_operand" "")]))))
10614 (clobber (match_operand:SI 5 "s_register_operand" ""))]
10616 [(set (match_dup 5) (not:SI (ashiftrt:SI (match_dup 1) (const_int 31))))
10617 (set (match_dup 0) (and:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
10622 ;; This split can be used because CC_Z mode implies that the following
10623 ;; branch will be an equality, or an unsigned inequality, so the sign
10624 ;; extension is not needed.
10627 [(set (reg:CC_Z CC_REGNUM)
10629 (ashift:SI (subreg:SI (match_operand:QI 0 "memory_operand" "") 0)
10631 (match_operand 1 "const_int_operand" "")))
10632 (clobber (match_scratch:SI 2 ""))]
10634 && ((UINTVAL (operands[1]))
10635 == ((UINTVAL (operands[1])) >> 24) << 24)"
10636 [(set (match_dup 2) (zero_extend:SI (match_dup 0)))
10637 (set (reg:CC CC_REGNUM) (compare:CC (match_dup 2) (match_dup 1)))]
10639 operands[1] = GEN_INT (((unsigned long) INTVAL (operands[1])) >> 24);
10642 ;; ??? Check the patterns above for Thumb-2 usefulness
10644 (define_expand "prologue"
10645 [(clobber (const_int 0))]
10648 arm_expand_prologue ();
10650 thumb1_expand_prologue ();
10655 (define_expand "epilogue"
10656 [(clobber (const_int 0))]
10659 if (crtl->calls_eh_return)
10660 emit_insn (gen_force_register_use (gen_rtx_REG (Pmode, 2)));
10663 thumb1_expand_epilogue ();
10664 emit_jump_insn (gen_rtx_UNSPEC_VOLATILE (VOIDmode,
10665 gen_rtvec (1, ret_rtx), VUNSPEC_EPILOGUE));
10667 else if (HAVE_return)
10669 /* HAVE_return is testing for USE_RETURN_INSN (FALSE). Hence,
10670 no need for explicit testing again. */
10671 emit_jump_insn (gen_return ());
10673 else if (TARGET_32BIT)
10675 arm_expand_epilogue (true);
10681 ;; Note - although unspec_volatile's USE all hard registers,
10682 ;; USEs are ignored after relaod has completed. Thus we need
10683 ;; to add an unspec of the link register to ensure that flow
10684 ;; does not think that it is unused by the sibcall branch that
10685 ;; will replace the standard function epilogue.
10686 (define_expand "sibcall_epilogue"
10687 [(parallel [(unspec:SI [(reg:SI LR_REGNUM)] UNSPEC_REGISTER_USE)
10688 (unspec_volatile [(return)] VUNSPEC_EPILOGUE)])]
10691 arm_expand_epilogue (false);
10696 (define_expand "eh_epilogue"
10697 [(use (match_operand:SI 0 "register_operand" ""))
10698 (use (match_operand:SI 1 "register_operand" ""))
10699 (use (match_operand:SI 2 "register_operand" ""))]
10703 cfun->machine->eh_epilogue_sp_ofs = operands[1];
10704 if (!REG_P (operands[2]) || REGNO (operands[2]) != 2)
10706 rtx ra = gen_rtx_REG (Pmode, 2);
10708 emit_move_insn (ra, operands[2]);
10711 /* This is a hack -- we may have crystalized the function type too
10713 cfun->machine->func_type = 0;
10717 ;; This split is only used during output to reduce the number of patterns
10718 ;; that need assembler instructions adding to them. We allowed the setting
10719 ;; of the conditions to be implicit during rtl generation so that
10720 ;; the conditional compare patterns would work. However this conflicts to
10721 ;; some extent with the conditional data operations, so we have to split them
10724 ;; ??? Need to audit these splitters for Thumb-2. Why isn't normal
10725 ;; conditional execution sufficient?
10728 [(set (match_operand:SI 0 "s_register_operand" "")
10729 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10730 [(match_operand 2 "" "") (match_operand 3 "" "")])
10732 (match_operand 4 "" "")))
10733 (clobber (reg:CC CC_REGNUM))]
10734 "TARGET_ARM && reload_completed"
10735 [(set (match_dup 5) (match_dup 6))
10736 (cond_exec (match_dup 7)
10737 (set (match_dup 0) (match_dup 4)))]
10740 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10741 operands[2], operands[3]);
10742 enum rtx_code rc = GET_CODE (operands[1]);
10744 operands[5] = gen_rtx_REG (mode, CC_REGNUM);
10745 operands[6] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10746 if (mode == CCFPmode || mode == CCFPEmode)
10747 rc = reverse_condition_maybe_unordered (rc);
10749 rc = reverse_condition (rc);
10751 operands[7] = gen_rtx_fmt_ee (rc, VOIDmode, operands[5], const0_rtx);
10756 [(set (match_operand:SI 0 "s_register_operand" "")
10757 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10758 [(match_operand 2 "" "") (match_operand 3 "" "")])
10759 (match_operand 4 "" "")
10761 (clobber (reg:CC CC_REGNUM))]
10762 "TARGET_ARM && reload_completed"
10763 [(set (match_dup 5) (match_dup 6))
10764 (cond_exec (match_op_dup 1 [(match_dup 5) (const_int 0)])
10765 (set (match_dup 0) (match_dup 4)))]
10768 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10769 operands[2], operands[3]);
10771 operands[5] = gen_rtx_REG (mode, CC_REGNUM);
10772 operands[6] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10777 [(set (match_operand:SI 0 "s_register_operand" "")
10778 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10779 [(match_operand 2 "" "") (match_operand 3 "" "")])
10780 (match_operand 4 "" "")
10781 (match_operand 5 "" "")))
10782 (clobber (reg:CC CC_REGNUM))]
10783 "TARGET_ARM && reload_completed"
10784 [(set (match_dup 6) (match_dup 7))
10785 (cond_exec (match_op_dup 1 [(match_dup 6) (const_int 0)])
10786 (set (match_dup 0) (match_dup 4)))
10787 (cond_exec (match_dup 8)
10788 (set (match_dup 0) (match_dup 5)))]
10791 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10792 operands[2], operands[3]);
10793 enum rtx_code rc = GET_CODE (operands[1]);
10795 operands[6] = gen_rtx_REG (mode, CC_REGNUM);
10796 operands[7] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10797 if (mode == CCFPmode || mode == CCFPEmode)
10798 rc = reverse_condition_maybe_unordered (rc);
10800 rc = reverse_condition (rc);
10802 operands[8] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
10807 [(set (match_operand:SI 0 "s_register_operand" "")
10808 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10809 [(match_operand:SI 2 "s_register_operand" "")
10810 (match_operand:SI 3 "arm_add_operand" "")])
10811 (match_operand:SI 4 "arm_rhs_operand" "")
10813 (match_operand:SI 5 "s_register_operand" ""))))
10814 (clobber (reg:CC CC_REGNUM))]
10815 "TARGET_ARM && reload_completed"
10816 [(set (match_dup 6) (match_dup 7))
10817 (cond_exec (match_op_dup 1 [(match_dup 6) (const_int 0)])
10818 (set (match_dup 0) (match_dup 4)))
10819 (cond_exec (match_dup 8)
10820 (set (match_dup 0) (not:SI (match_dup 5))))]
10823 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10824 operands[2], operands[3]);
10825 enum rtx_code rc = GET_CODE (operands[1]);
10827 operands[6] = gen_rtx_REG (mode, CC_REGNUM);
10828 operands[7] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10829 if (mode == CCFPmode || mode == CCFPEmode)
10830 rc = reverse_condition_maybe_unordered (rc);
10832 rc = reverse_condition (rc);
10834 operands[8] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
10838 (define_insn "*cond_move_not"
10839 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10840 (if_then_else:SI (match_operator 4 "arm_comparison_operator"
10841 [(match_operand 3 "cc_register" "") (const_int 0)])
10842 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
10844 (match_operand:SI 2 "s_register_operand" "r,r"))))]
10848 mov%d4\\t%0, %1\;mvn%D4\\t%0, %2"
10849 [(set_attr "conds" "use")
10850 (set_attr "type" "mvn_reg,multiple")
10851 (set_attr "length" "4,8")]
10854 ;; The next two patterns occur when an AND operation is followed by a
10855 ;; scc insn sequence
10857 (define_insn "*sign_extract_onebit"
10858 [(set (match_operand:SI 0 "s_register_operand" "=r")
10859 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
10861 (match_operand:SI 2 "const_int_operand" "n")))
10862 (clobber (reg:CC CC_REGNUM))]
10865 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
10866 output_asm_insn (\"ands\\t%0, %1, %2\", operands);
10867 return \"mvnne\\t%0, #0\";
10869 [(set_attr "conds" "clob")
10870 (set_attr "length" "8")
10871 (set_attr "type" "multiple")]
10874 (define_insn "*not_signextract_onebit"
10875 [(set (match_operand:SI 0 "s_register_operand" "=r")
10877 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
10879 (match_operand:SI 2 "const_int_operand" "n"))))
10880 (clobber (reg:CC CC_REGNUM))]
10883 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
10884 output_asm_insn (\"tst\\t%1, %2\", operands);
10885 output_asm_insn (\"mvneq\\t%0, #0\", operands);
10886 return \"movne\\t%0, #0\";
10888 [(set_attr "conds" "clob")
10889 (set_attr "length" "12")
10890 (set_attr "type" "multiple")]
10892 ;; ??? The above patterns need auditing for Thumb-2
10894 ;; Push multiple registers to the stack. Registers are in parallel (use ...)
10895 ;; expressions. For simplicity, the first register is also in the unspec
10897 ;; To avoid the usage of GNU extension, the length attribute is computed
10898 ;; in a C function arm_attr_length_push_multi.
10899 (define_insn "*push_multi"
10900 [(match_parallel 2 "multi_register_push"
10901 [(set (match_operand:BLK 0 "push_mult_memory_operand" "")
10902 (unspec:BLK [(match_operand:SI 1 "s_register_operand" "")]
10903 UNSPEC_PUSH_MULT))])]
10907 int num_saves = XVECLEN (operands[2], 0);
10909 /* For the StrongARM at least it is faster to
10910 use STR to store only a single register.
10911 In Thumb mode always use push, and the assembler will pick
10912 something appropriate. */
10913 if (num_saves == 1 && TARGET_ARM)
10914 output_asm_insn (\"str%?\\t%1, [%m0, #-4]!\", operands);
10921 strcpy (pattern, \"push%?\\t{%1\");
10923 strcpy (pattern, \"push\\t{%1\");
10925 for (i = 1; i < num_saves; i++)
10927 strcat (pattern, \", %|\");
10929 reg_names[REGNO (XEXP (XVECEXP (operands[2], 0, i), 0))]);
10932 strcat (pattern, \"}\");
10933 output_asm_insn (pattern, operands);
10938 [(set_attr "type" "store4")
10939 (set (attr "length")
10940 (symbol_ref "arm_attr_length_push_multi (operands[2], operands[1])"))]
10943 (define_insn "stack_tie"
10944 [(set (mem:BLK (scratch))
10945 (unspec:BLK [(match_operand:SI 0 "s_register_operand" "rk")
10946 (match_operand:SI 1 "s_register_operand" "rk")]
10950 [(set_attr "length" "0")
10951 (set_attr "type" "block")]
10954 ;; Pop (as used in epilogue RTL)
10956 (define_insn "*load_multiple_with_writeback"
10957 [(match_parallel 0 "load_multiple_operation"
10958 [(set (match_operand:SI 1 "s_register_operand" "+rk")
10959 (plus:SI (match_dup 1)
10960 (match_operand:SI 2 "const_int_I_operand" "I")))
10961 (set (match_operand:SI 3 "s_register_operand" "=rk")
10962 (mem:SI (match_dup 1)))
10964 "TARGET_32BIT && (reload_in_progress || reload_completed)"
10967 arm_output_multireg_pop (operands, /*return_pc=*/false,
10968 /*cond=*/const_true_rtx,
10974 [(set_attr "type" "load4")
10975 (set_attr "predicable" "yes")
10976 (set (attr "length")
10977 (symbol_ref "arm_attr_length_pop_multi (operands,
10978 /*return_pc=*/false,
10979 /*write_back_p=*/true)"))]
10982 ;; Pop with return (as used in epilogue RTL)
10984 ;; This instruction is generated when the registers are popped at the end of
10985 ;; epilogue. Here, instead of popping the value into LR and then generating
10986 ;; jump to LR, value is popped into PC directly. Hence, the pattern is combined
10988 (define_insn "*pop_multiple_with_writeback_and_return"
10989 [(match_parallel 0 "pop_multiple_return"
10991 (set (match_operand:SI 1 "s_register_operand" "+rk")
10992 (plus:SI (match_dup 1)
10993 (match_operand:SI 2 "const_int_I_operand" "I")))
10994 (set (match_operand:SI 3 "s_register_operand" "=rk")
10995 (mem:SI (match_dup 1)))
10997 "TARGET_32BIT && (reload_in_progress || reload_completed)"
11000 arm_output_multireg_pop (operands, /*return_pc=*/true,
11001 /*cond=*/const_true_rtx,
11007 [(set_attr "type" "load4")
11008 (set_attr "predicable" "yes")
11009 (set (attr "length")
11010 (symbol_ref "arm_attr_length_pop_multi (operands, /*return_pc=*/true,
11011 /*write_back_p=*/true)"))]
11014 (define_insn "*pop_multiple_with_return"
11015 [(match_parallel 0 "pop_multiple_return"
11017 (set (match_operand:SI 2 "s_register_operand" "=rk")
11018 (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
11020 "TARGET_32BIT && (reload_in_progress || reload_completed)"
11023 arm_output_multireg_pop (operands, /*return_pc=*/true,
11024 /*cond=*/const_true_rtx,
11030 [(set_attr "type" "load4")
11031 (set_attr "predicable" "yes")
11032 (set (attr "length")
11033 (symbol_ref "arm_attr_length_pop_multi (operands, /*return_pc=*/true,
11034 /*write_back_p=*/false)"))]
11037 ;; Load into PC and return
11038 (define_insn "*ldr_with_return"
11040 (set (reg:SI PC_REGNUM)
11041 (mem:SI (post_inc:SI (match_operand:SI 0 "s_register_operand" "+rk"))))]
11042 "TARGET_32BIT && (reload_in_progress || reload_completed)"
11043 "ldr%?\t%|pc, [%0], #4"
11044 [(set_attr "type" "load1")
11045 (set_attr "predicable" "yes")]
11047 ;; Pop for floating point registers (as used in epilogue RTL)
11048 (define_insn "*vfp_pop_multiple_with_writeback"
11049 [(match_parallel 0 "pop_multiple_fp"
11050 [(set (match_operand:SI 1 "s_register_operand" "+rk")
11051 (plus:SI (match_dup 1)
11052 (match_operand:SI 2 "const_int_I_operand" "I")))
11053 (set (match_operand:DF 3 "vfp_hard_register_operand" "")
11054 (mem:DF (match_dup 1)))])]
11055 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
11058 int num_regs = XVECLEN (operands[0], 0);
11061 strcpy (pattern, \"vldm\\t\");
11062 strcat (pattern, reg_names[REGNO (SET_DEST (XVECEXP (operands[0], 0, 0)))]);
11063 strcat (pattern, \"!, {\");
11064 op_list[0] = XEXP (XVECEXP (operands[0], 0, 1), 0);
11065 strcat (pattern, \"%P0\");
11066 if ((num_regs - 1) > 1)
11068 strcat (pattern, \"-%P1\");
11069 op_list [1] = XEXP (XVECEXP (operands[0], 0, num_regs - 1), 0);
11072 strcat (pattern, \"}\");
11073 output_asm_insn (pattern, op_list);
11077 [(set_attr "type" "load4")
11078 (set_attr "conds" "unconditional")
11079 (set_attr "predicable" "no")]
11082 ;; Special patterns for dealing with the constant pool
11084 (define_insn "align_4"
11085 [(unspec_volatile [(const_int 0)] VUNSPEC_ALIGN)]
11088 assemble_align (32);
11091 [(set_attr "type" "no_insn")]
11094 (define_insn "align_8"
11095 [(unspec_volatile [(const_int 0)] VUNSPEC_ALIGN8)]
11098 assemble_align (64);
11101 [(set_attr "type" "no_insn")]
11104 (define_insn "consttable_end"
11105 [(unspec_volatile [(const_int 0)] VUNSPEC_POOL_END)]
11108 making_const_table = FALSE;
11111 [(set_attr "type" "no_insn")]
11114 (define_insn "consttable_1"
11115 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_1)]
11118 making_const_table = TRUE;
11119 assemble_integer (operands[0], 1, BITS_PER_WORD, 1);
11120 assemble_zeros (3);
11123 [(set_attr "length" "4")
11124 (set_attr "type" "no_insn")]
11127 (define_insn "consttable_2"
11128 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_2)]
11132 rtx x = operands[0];
11133 making_const_table = TRUE;
11134 switch (GET_MODE_CLASS (GET_MODE (x)))
11137 arm_emit_fp16_const (x);
11140 assemble_integer (operands[0], 2, BITS_PER_WORD, 1);
11141 assemble_zeros (2);
11146 [(set_attr "length" "4")
11147 (set_attr "type" "no_insn")]
11150 (define_insn "consttable_4"
11151 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_4)]
11155 rtx x = operands[0];
11156 making_const_table = TRUE;
11157 switch (GET_MODE_CLASS (GET_MODE (x)))
11160 assemble_real (*CONST_DOUBLE_REAL_VALUE (x), GET_MODE (x),
11164 /* XXX: Sometimes gcc does something really dumb and ends up with
11165 a HIGH in a constant pool entry, usually because it's trying to
11166 load into a VFP register. We know this will always be used in
11167 combination with a LO_SUM which ignores the high bits, so just
11168 strip off the HIGH. */
11169 if (GET_CODE (x) == HIGH)
11171 assemble_integer (x, 4, BITS_PER_WORD, 1);
11172 mark_symbol_refs_as_used (x);
11177 [(set_attr "length" "4")
11178 (set_attr "type" "no_insn")]
11181 (define_insn "consttable_8"
11182 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_8)]
11186 making_const_table = TRUE;
11187 switch (GET_MODE_CLASS (GET_MODE (operands[0])))
11190 assemble_real (*CONST_DOUBLE_REAL_VALUE (operands[0]),
11191 GET_MODE (operands[0]), BITS_PER_WORD);
11194 assemble_integer (operands[0], 8, BITS_PER_WORD, 1);
11199 [(set_attr "length" "8")
11200 (set_attr "type" "no_insn")]
11203 (define_insn "consttable_16"
11204 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_16)]
11208 making_const_table = TRUE;
11209 switch (GET_MODE_CLASS (GET_MODE (operands[0])))
11212 assemble_real (*CONST_DOUBLE_REAL_VALUE (operands[0]),
11213 GET_MODE (operands[0]), BITS_PER_WORD);
11216 assemble_integer (operands[0], 16, BITS_PER_WORD, 1);
11221 [(set_attr "length" "16")
11222 (set_attr "type" "no_insn")]
11225 ;; V5 Instructions,
11227 (define_insn "clzsi2"
11228 [(set (match_operand:SI 0 "s_register_operand" "=r")
11229 (clz:SI (match_operand:SI 1 "s_register_operand" "r")))]
11230 "TARGET_32BIT && arm_arch5"
11232 [(set_attr "predicable" "yes")
11233 (set_attr "predicable_short_it" "no")
11234 (set_attr "type" "clz")])
11236 (define_insn "rbitsi2"
11237 [(set (match_operand:SI 0 "s_register_operand" "=r")
11238 (unspec:SI [(match_operand:SI 1 "s_register_operand" "r")] UNSPEC_RBIT))]
11239 "TARGET_32BIT && arm_arch_thumb2"
11241 [(set_attr "predicable" "yes")
11242 (set_attr "predicable_short_it" "no")
11243 (set_attr "type" "clz")])
11245 ;; Keep this as a CTZ expression until after reload and then split
11246 ;; into RBIT + CLZ. Since RBIT is represented as an UNSPEC it is unlikely
11247 ;; to fold with any other expression.
11249 (define_insn_and_split "ctzsi2"
11250 [(set (match_operand:SI 0 "s_register_operand" "=r")
11251 (ctz:SI (match_operand:SI 1 "s_register_operand" "r")))]
11252 "TARGET_32BIT && arm_arch_thumb2"
11254 "&& reload_completed"
11257 emit_insn (gen_rbitsi2 (operands[0], operands[1]));
11258 emit_insn (gen_clzsi2 (operands[0], operands[0]));
11262 ;; V5E instructions.
11264 (define_insn "prefetch"
11265 [(prefetch (match_operand:SI 0 "address_operand" "p")
11266 (match_operand:SI 1 "" "")
11267 (match_operand:SI 2 "" ""))]
11268 "TARGET_32BIT && arm_arch5e"
11270 [(set_attr "type" "load1")]
11273 ;; General predication pattern
11276 [(match_operator 0 "arm_comparison_operator"
11277 [(match_operand 1 "cc_register" "")
11280 && (!TARGET_NO_VOLATILE_CE || !volatile_refs_p (PATTERN (insn)))"
11282 [(set_attr "predicated" "yes")]
11285 (define_insn "force_register_use"
11286 [(unspec:SI [(match_operand:SI 0 "register_operand" "")] UNSPEC_REGISTER_USE)]
11289 [(set_attr "length" "0")
11290 (set_attr "type" "no_insn")]
11294 ;; Patterns for exception handling
11296 (define_expand "eh_return"
11297 [(use (match_operand 0 "general_operand" ""))]
11302 emit_insn (gen_arm_eh_return (operands[0]));
11304 emit_insn (gen_thumb_eh_return (operands[0]));
11309 ;; We can't expand this before we know where the link register is stored.
11310 (define_insn_and_split "arm_eh_return"
11311 [(unspec_volatile [(match_operand:SI 0 "s_register_operand" "r")]
11313 (clobber (match_scratch:SI 1 "=&r"))]
11316 "&& reload_completed"
11320 arm_set_return_address (operands[0], operands[1]);
11328 (define_insn "load_tp_hard"
11329 [(set (match_operand:SI 0 "register_operand" "=r")
11330 (unspec:SI [(const_int 0)] UNSPEC_TLS))]
11332 "mrc%?\\tp15, 0, %0, c13, c0, 3\\t@ load_tp_hard"
11333 [(set_attr "predicable" "yes")
11334 (set_attr "type" "mrs")]
11337 ;; Doesn't clobber R1-R3. Must use r0 for the first operand.
11338 (define_insn "load_tp_soft"
11339 [(set (reg:SI 0) (unspec:SI [(const_int 0)] UNSPEC_TLS))
11340 (clobber (reg:SI LR_REGNUM))
11341 (clobber (reg:SI IP_REGNUM))
11342 (clobber (reg:CC CC_REGNUM))]
11344 "bl\\t__aeabi_read_tp\\t@ load_tp_soft"
11345 [(set_attr "conds" "clob")
11346 (set_attr "type" "branch")]
11349 ;; tls descriptor call
11350 (define_insn "tlscall"
11351 [(set (reg:SI R0_REGNUM)
11352 (unspec:SI [(reg:SI R0_REGNUM)
11353 (match_operand:SI 0 "" "X")
11354 (match_operand 1 "" "")] UNSPEC_TLS))
11355 (clobber (reg:SI R1_REGNUM))
11356 (clobber (reg:SI LR_REGNUM))
11357 (clobber (reg:SI CC_REGNUM))]
11360 targetm.asm_out.internal_label (asm_out_file, "LPIC",
11361 INTVAL (operands[1]));
11362 return "bl\\t%c0(tlscall)";
11364 [(set_attr "conds" "clob")
11365 (set_attr "length" "4")
11366 (set_attr "type" "branch")]
11369 ;; For thread pointer builtin
11370 (define_expand "get_thread_pointersi"
11371 [(match_operand:SI 0 "s_register_operand" "=r")]
11375 arm_load_tp (operands[0]);
11381 ;; We only care about the lower 16 bits of the constant
11382 ;; being inserted into the upper 16 bits of the register.
11383 (define_insn "*arm_movtas_ze"
11384 [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r,r")
11387 (match_operand:SI 1 "const_int_operand" ""))]
11392 [(set_attr "arch" "32,v8mb")
11393 (set_attr "predicable" "yes")
11394 (set_attr "predicable_short_it" "no")
11395 (set_attr "length" "4")
11396 (set_attr "type" "alu_sreg")]
11399 (define_insn "*arm_rev"
11400 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r")
11401 (bswap:SI (match_operand:SI 1 "s_register_operand" "l,l,r")))]
11407 [(set_attr "arch" "t1,t2,32")
11408 (set_attr "length" "2,2,4")
11409 (set_attr "predicable" "no,yes,yes")
11410 (set_attr "predicable_short_it" "no")
11411 (set_attr "type" "rev")]
11414 (define_expand "arm_legacy_rev"
11415 [(set (match_operand:SI 2 "s_register_operand" "")
11416 (xor:SI (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
11420 (lshiftrt:SI (match_dup 2)
11422 (set (match_operand:SI 3 "s_register_operand" "")
11423 (rotatert:SI (match_dup 1)
11426 (and:SI (match_dup 2)
11427 (const_int -65281)))
11428 (set (match_operand:SI 0 "s_register_operand" "")
11429 (xor:SI (match_dup 3)
11435 ;; Reuse temporaries to keep register pressure down.
11436 (define_expand "thumb_legacy_rev"
11437 [(set (match_operand:SI 2 "s_register_operand" "")
11438 (ashift:SI (match_operand:SI 1 "s_register_operand" "")
11440 (set (match_operand:SI 3 "s_register_operand" "")
11441 (lshiftrt:SI (match_dup 1)
11444 (ior:SI (match_dup 3)
11446 (set (match_operand:SI 4 "s_register_operand" "")
11448 (set (match_operand:SI 5 "s_register_operand" "")
11449 (rotatert:SI (match_dup 1)
11452 (ashift:SI (match_dup 5)
11455 (lshiftrt:SI (match_dup 5)
11458 (ior:SI (match_dup 5)
11461 (rotatert:SI (match_dup 5)
11463 (set (match_operand:SI 0 "s_register_operand" "")
11464 (ior:SI (match_dup 5)
11470 ;; ARM-specific expansion of signed mod by power of 2
11471 ;; using conditional negate.
11472 ;; For r0 % n where n is a power of 2 produce:
11474 ;; and r0, r0, #(n - 1)
11475 ;; and r1, r1, #(n - 1)
11476 ;; rsbpl r0, r1, #0
11478 (define_expand "modsi3"
11479 [(match_operand:SI 0 "register_operand" "")
11480 (match_operand:SI 1 "register_operand" "")
11481 (match_operand:SI 2 "const_int_operand" "")]
11484 HOST_WIDE_INT val = INTVAL (operands[2]);
11487 || exact_log2 (val) <= 0)
11490 rtx mask = GEN_INT (val - 1);
11492 /* In the special case of x0 % 2 we can do the even shorter:
11495 rsblt r0, r0, #0. */
11499 rtx cc_reg = arm_gen_compare_reg (LT,
11500 operands[1], const0_rtx, NULL_RTX);
11501 rtx cond = gen_rtx_LT (SImode, cc_reg, const0_rtx);
11502 rtx masked = gen_reg_rtx (SImode);
11504 emit_insn (gen_andsi3 (masked, operands[1], mask));
11505 emit_move_insn (operands[0],
11506 gen_rtx_IF_THEN_ELSE (SImode, cond,
11507 gen_rtx_NEG (SImode,
11513 rtx neg_op = gen_reg_rtx (SImode);
11514 rtx_insn *insn = emit_insn (gen_subsi3_compare0 (neg_op, const0_rtx,
11517 /* Extract the condition register and mode. */
11518 rtx cmp = XVECEXP (PATTERN (insn), 0, 0);
11519 rtx cc_reg = SET_DEST (cmp);
11520 rtx cond = gen_rtx_GE (SImode, cc_reg, const0_rtx);
11522 emit_insn (gen_andsi3 (operands[0], operands[1], mask));
11524 rtx masked_neg = gen_reg_rtx (SImode);
11525 emit_insn (gen_andsi3 (masked_neg, neg_op, mask));
11527 /* We want a conditional negate here, but emitting COND_EXEC rtxes
11528 during expand does not always work. Do an IF_THEN_ELSE instead. */
11529 emit_move_insn (operands[0],
11530 gen_rtx_IF_THEN_ELSE (SImode, cond,
11531 gen_rtx_NEG (SImode, masked_neg),
11539 (define_expand "bswapsi2"
11540 [(set (match_operand:SI 0 "s_register_operand" "=r")
11541 (bswap:SI (match_operand:SI 1 "s_register_operand" "r")))]
11542 "TARGET_EITHER && (arm_arch6 || !optimize_size)"
11546 rtx op2 = gen_reg_rtx (SImode);
11547 rtx op3 = gen_reg_rtx (SImode);
11551 rtx op4 = gen_reg_rtx (SImode);
11552 rtx op5 = gen_reg_rtx (SImode);
11554 emit_insn (gen_thumb_legacy_rev (operands[0], operands[1],
11555 op2, op3, op4, op5));
11559 emit_insn (gen_arm_legacy_rev (operands[0], operands[1],
11568 ;; bswap16 patterns: use revsh and rev16 instructions for the signed
11569 ;; and unsigned variants, respectively. For rev16, expose
11570 ;; byte-swapping in the lower 16 bits only.
11571 (define_insn "*arm_revsh"
11572 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r")
11573 (sign_extend:SI (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 (define_insn "*arm_rev16"
11585 [(set (match_operand:HI 0 "s_register_operand" "=l,l,r")
11586 (bswap:HI (match_operand:HI 1 "s_register_operand" "l,l,r")))]
11592 [(set_attr "arch" "t1,t2,32")
11593 (set_attr "length" "2,2,4")
11594 (set_attr "type" "rev")]
11597 ;; There are no canonicalisation rules for the position of the lshiftrt, ashift
11598 ;; operations within an IOR/AND RTX, therefore we have two patterns matching
11599 ;; each valid permutation.
11601 (define_insn "arm_rev16si2"
11602 [(set (match_operand:SI 0 "register_operand" "=l,l,r")
11603 (ior:SI (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "l,l,r")
11605 (match_operand:SI 3 "const_int_operand" "n,n,n"))
11606 (and:SI (lshiftrt:SI (match_dup 1)
11608 (match_operand:SI 2 "const_int_operand" "n,n,n"))))]
11610 && aarch_rev16_shleft_mask_imm_p (operands[3], SImode)
11611 && aarch_rev16_shright_mask_imm_p (operands[2], SImode)"
11613 [(set_attr "arch" "t1,t2,32")
11614 (set_attr "length" "2,2,4")
11615 (set_attr "type" "rev")]
11618 (define_insn "arm_rev16si2_alt"
11619 [(set (match_operand:SI 0 "register_operand" "=l,l,r")
11620 (ior:SI (and:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "l,l,r")
11622 (match_operand:SI 2 "const_int_operand" "n,n,n"))
11623 (and:SI (ashift:SI (match_dup 1)
11625 (match_operand:SI 3 "const_int_operand" "n,n,n"))))]
11627 && aarch_rev16_shleft_mask_imm_p (operands[3], SImode)
11628 && aarch_rev16_shright_mask_imm_p (operands[2], SImode)"
11630 [(set_attr "arch" "t1,t2,32")
11631 (set_attr "length" "2,2,4")
11632 (set_attr "type" "rev")]
11635 (define_expand "bswaphi2"
11636 [(set (match_operand:HI 0 "s_register_operand" "=r")
11637 (bswap:HI (match_operand:HI 1 "s_register_operand" "r")))]
11642 ;; Patterns for LDRD/STRD in Thumb2 mode
11644 (define_insn "*thumb2_ldrd"
11645 [(set (match_operand:SI 0 "s_register_operand" "=r")
11646 (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "rk")
11647 (match_operand:SI 2 "ldrd_strd_offset_operand" "Do"))))
11648 (set (match_operand:SI 3 "s_register_operand" "=r")
11649 (mem:SI (plus:SI (match_dup 1)
11650 (match_operand:SI 4 "const_int_operand" ""))))]
11651 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11652 && current_tune->prefer_ldrd_strd
11653 && ((INTVAL (operands[2]) + 4) == INTVAL (operands[4]))
11654 && (operands_ok_ldrd_strd (operands[0], operands[3],
11655 operands[1], INTVAL (operands[2]),
11657 "ldrd%?\t%0, %3, [%1, %2]"
11658 [(set_attr "type" "load2")
11659 (set_attr "predicable" "yes")
11660 (set_attr "predicable_short_it" "no")])
11662 (define_insn "*thumb2_ldrd_base"
11663 [(set (match_operand:SI 0 "s_register_operand" "=r")
11664 (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
11665 (set (match_operand:SI 2 "s_register_operand" "=r")
11666 (mem:SI (plus:SI (match_dup 1)
11668 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11669 && current_tune->prefer_ldrd_strd
11670 && (operands_ok_ldrd_strd (operands[0], operands[2],
11671 operands[1], 0, false, true))"
11672 "ldrd%?\t%0, %2, [%1]"
11673 [(set_attr "type" "load2")
11674 (set_attr "predicable" "yes")
11675 (set_attr "predicable_short_it" "no")])
11677 (define_insn "*thumb2_ldrd_base_neg"
11678 [(set (match_operand:SI 0 "s_register_operand" "=r")
11679 (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "rk")
11681 (set (match_operand:SI 2 "s_register_operand" "=r")
11682 (mem:SI (match_dup 1)))]
11683 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11684 && current_tune->prefer_ldrd_strd
11685 && (operands_ok_ldrd_strd (operands[0], operands[2],
11686 operands[1], -4, false, true))"
11687 "ldrd%?\t%0, %2, [%1, #-4]"
11688 [(set_attr "type" "load2")
11689 (set_attr "predicable" "yes")
11690 (set_attr "predicable_short_it" "no")])
11692 (define_insn "*thumb2_strd"
11693 [(set (mem:SI (plus:SI (match_operand:SI 0 "s_register_operand" "rk")
11694 (match_operand:SI 1 "ldrd_strd_offset_operand" "Do")))
11695 (match_operand:SI 2 "s_register_operand" "r"))
11696 (set (mem:SI (plus:SI (match_dup 0)
11697 (match_operand:SI 3 "const_int_operand" "")))
11698 (match_operand:SI 4 "s_register_operand" "r"))]
11699 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11700 && current_tune->prefer_ldrd_strd
11701 && ((INTVAL (operands[1]) + 4) == INTVAL (operands[3]))
11702 && (operands_ok_ldrd_strd (operands[2], operands[4],
11703 operands[0], INTVAL (operands[1]),
11705 "strd%?\t%2, %4, [%0, %1]"
11706 [(set_attr "type" "store2")
11707 (set_attr "predicable" "yes")
11708 (set_attr "predicable_short_it" "no")])
11710 (define_insn "*thumb2_strd_base"
11711 [(set (mem:SI (match_operand:SI 0 "s_register_operand" "rk"))
11712 (match_operand:SI 1 "s_register_operand" "r"))
11713 (set (mem:SI (plus:SI (match_dup 0)
11715 (match_operand:SI 2 "s_register_operand" "r"))]
11716 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11717 && current_tune->prefer_ldrd_strd
11718 && (operands_ok_ldrd_strd (operands[1], operands[2],
11719 operands[0], 0, false, false))"
11720 "strd%?\t%1, %2, [%0]"
11721 [(set_attr "type" "store2")
11722 (set_attr "predicable" "yes")
11723 (set_attr "predicable_short_it" "no")])
11725 (define_insn "*thumb2_strd_base_neg"
11726 [(set (mem:SI (plus:SI (match_operand:SI 0 "s_register_operand" "rk")
11728 (match_operand:SI 1 "s_register_operand" "r"))
11729 (set (mem:SI (match_dup 0))
11730 (match_operand:SI 2 "s_register_operand" "r"))]
11731 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11732 && current_tune->prefer_ldrd_strd
11733 && (operands_ok_ldrd_strd (operands[1], operands[2],
11734 operands[0], -4, false, false))"
11735 "strd%?\t%1, %2, [%0, #-4]"
11736 [(set_attr "type" "store2")
11737 (set_attr "predicable" "yes")
11738 (set_attr "predicable_short_it" "no")])
11740 ;; ARMv8 CRC32 instructions.
11741 (define_insn "<crc_variant>"
11742 [(set (match_operand:SI 0 "s_register_operand" "=r")
11743 (unspec:SI [(match_operand:SI 1 "s_register_operand" "r")
11744 (match_operand:<crc_mode> 2 "s_register_operand" "r")]
11747 "<crc_variant>\\t%0, %1, %2"
11748 [(set_attr "type" "crc")
11749 (set_attr "conds" "unconditional")]
11752 ;; Load the load/store double peephole optimizations.
11753 (include "ldrdstrd.md")
11755 ;; Load the load/store multiple patterns
11756 (include "ldmstm.md")
11758 ;; Patterns in ldmstm.md don't cover more than 4 registers. This pattern covers
11759 ;; large lists without explicit writeback generated for APCS_FRAME epilogue.
11760 (define_insn "*load_multiple"
11761 [(match_parallel 0 "load_multiple_operation"
11762 [(set (match_operand:SI 2 "s_register_operand" "=rk")
11763 (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
11768 arm_output_multireg_pop (operands, /*return_pc=*/false,
11769 /*cond=*/const_true_rtx,
11775 [(set_attr "predicable" "yes")]
11778 (define_expand "copysignsf3"
11779 [(match_operand:SF 0 "register_operand")
11780 (match_operand:SF 1 "register_operand")
11781 (match_operand:SF 2 "register_operand")]
11782 "TARGET_SOFT_FLOAT && arm_arch_thumb2"
11784 emit_move_insn (operands[0], operands[2]);
11785 emit_insn (gen_insv_t2 (simplify_gen_subreg (SImode, operands[0], SFmode, 0),
11786 GEN_INT (31), GEN_INT (0),
11787 simplify_gen_subreg (SImode, operands[1], SFmode, 0)));
11792 (define_expand "copysigndf3"
11793 [(match_operand:DF 0 "register_operand")
11794 (match_operand:DF 1 "register_operand")
11795 (match_operand:DF 2 "register_operand")]
11796 "TARGET_SOFT_FLOAT && arm_arch_thumb2"
11798 rtx op0_low = gen_lowpart (SImode, operands[0]);
11799 rtx op0_high = gen_highpart (SImode, operands[0]);
11800 rtx op1_low = gen_lowpart (SImode, operands[1]);
11801 rtx op1_high = gen_highpart (SImode, operands[1]);
11802 rtx op2_high = gen_highpart (SImode, operands[2]);
11804 rtx scratch1 = gen_reg_rtx (SImode);
11805 rtx scratch2 = gen_reg_rtx (SImode);
11806 emit_move_insn (scratch1, op2_high);
11807 emit_move_insn (scratch2, op1_high);
11809 emit_insn(gen_rtx_SET(scratch1,
11810 gen_rtx_LSHIFTRT (SImode, op2_high, GEN_INT(31))));
11811 emit_insn(gen_insv_t2(scratch2, GEN_INT(1), GEN_INT(31), scratch1));
11812 emit_move_insn (op0_low, op1_low);
11813 emit_move_insn (op0_high, scratch2);
11819 ;; movmisalign patterns for HImode and SImode.
11820 (define_expand "movmisalign<mode>"
11821 [(match_operand:HSI 0 "general_operand")
11822 (match_operand:HSI 1 "general_operand")]
11825 /* This pattern is not permitted to fail during expansion: if both arguments
11826 are non-registers (e.g. memory := constant), force operand 1 into a
11828 rtx (* gen_unaligned_load)(rtx, rtx);
11829 rtx tmp_dest = operands[0];
11830 if (!s_register_operand (operands[0], <MODE>mode)
11831 && !s_register_operand (operands[1], <MODE>mode))
11832 operands[1] = force_reg (<MODE>mode, operands[1]);
11834 if (<MODE>mode == HImode)
11836 gen_unaligned_load = gen_unaligned_loadhiu;
11837 tmp_dest = gen_reg_rtx (SImode);
11840 gen_unaligned_load = gen_unaligned_loadsi;
11842 if (MEM_P (operands[1]))
11844 emit_insn (gen_unaligned_load (tmp_dest, operands[1]));
11845 if (<MODE>mode == HImode)
11846 emit_move_insn (operands[0], gen_lowpart (HImode, tmp_dest));
11849 emit_insn (gen_unaligned_store<mode> (operands[0], operands[1]));
11854 ;; Vector bits common to IWMMXT and Neon
11855 (include "vec-common.md")
11856 ;; Load the Intel Wireless Multimedia Extension patterns
11857 (include "iwmmxt.md")
11858 ;; Load the VFP co-processor patterns
11860 ;; Thumb-1 patterns
11861 (include "thumb1.md")
11862 ;; Thumb-2 patterns
11863 (include "thumb2.md")
11865 (include "neon.md")
11867 (include "crypto.md")
11868 ;; Synchronization Primitives
11869 (include "sync.md")
11870 ;; Fixed-point patterns
11871 (include "arm-fixed.md")