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,k ,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,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,rI,Pj,Pj,L ,L,L,PJ,PJ,?n")))]
630 subw%?\\t%0, %1, #%n2
631 subw%?\\t%0, %1, #%n2
634 && CONST_INT_P (operands[2])
635 && !const_ok_for_op (INTVAL (operands[2]), PLUS)
636 && (reload_completed || !arm_eliminable_register (operands[1]))"
637 [(clobber (const_int 0))]
639 arm_split_constant (PLUS, SImode, curr_insn,
640 INTVAL (operands[2]), operands[0],
644 [(set_attr "length" "2,4,4,4,4,4,4,4,4,4,4,4,4,4,4,16")
645 (set_attr "predicable" "yes")
646 (set_attr "predicable_short_it" "yes,yes,yes,yes,no,no,no,no,no,no,no,no,no,no,no,no")
647 (set_attr "arch" "t2,t2,t2,t2,*,*,*,a,t2,t2,*,*,a,t2,t2,*")
648 (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
649 (const_string "alu_imm")
650 (const_string "alu_sreg")))
654 (define_insn_and_split "adddi3_compareV"
655 [(set (reg:CC_V CC_REGNUM)
658 (sign_extend:TI (match_operand:DI 1 "register_operand" "r"))
659 (sign_extend:TI (match_operand:DI 2 "register_operand" "r")))
660 (sign_extend:TI (plus:DI (match_dup 1) (match_dup 2)))))
661 (set (match_operand:DI 0 "register_operand" "=&r")
662 (plus:DI (match_dup 1) (match_dup 2)))]
665 "&& reload_completed"
666 [(parallel [(set (reg:CC_C CC_REGNUM)
667 (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
669 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
670 (parallel [(set (reg:CC_V CC_REGNUM)
673 (sign_extend:DI (match_dup 4))
674 (sign_extend:DI (match_dup 5)))
675 (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0)))
676 (plus:DI (sign_extend:DI
677 (plus:SI (match_dup 4) (match_dup 5)))
678 (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0)))))
679 (set (match_dup 3) (plus:SI (plus:SI
680 (match_dup 4) (match_dup 5))
681 (ltu:SI (reg:CC_C CC_REGNUM)
685 operands[3] = gen_highpart (SImode, operands[0]);
686 operands[0] = gen_lowpart (SImode, operands[0]);
687 operands[4] = gen_highpart (SImode, operands[1]);
688 operands[1] = gen_lowpart (SImode, operands[1]);
689 operands[5] = gen_highpart (SImode, operands[2]);
690 operands[2] = gen_lowpart (SImode, operands[2]);
692 [(set_attr "conds" "set")
693 (set_attr "length" "8")
694 (set_attr "type" "multiple")]
697 (define_insn "addsi3_compareV"
698 [(set (reg:CC_V CC_REGNUM)
701 (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
702 (sign_extend:DI (match_operand:SI 2 "register_operand" "r")))
703 (sign_extend:DI (plus:SI (match_dup 1) (match_dup 2)))))
704 (set (match_operand:SI 0 "register_operand" "=r")
705 (plus:SI (match_dup 1) (match_dup 2)))]
707 "adds%?\\t%0, %1, %2"
708 [(set_attr "conds" "set")
709 (set_attr "type" "alus_sreg")]
712 (define_insn "*addsi3_compareV_upper"
713 [(set (reg:CC_V CC_REGNUM)
717 (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
718 (sign_extend:DI (match_operand:SI 2 "register_operand" "r")))
719 (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0)))
720 (plus:DI (sign_extend:DI
721 (plus:SI (match_dup 1) (match_dup 2)))
722 (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0)))))
723 (set (match_operand:SI 0 "register_operand" "=r")
725 (plus:SI (match_dup 1) (match_dup 2))
726 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
728 "adcs%?\\t%0, %1, %2"
729 [(set_attr "conds" "set")
730 (set_attr "type" "adcs_reg")]
733 (define_insn_and_split "adddi3_compareC"
734 [(set (reg:CC_C CC_REGNUM)
737 (zero_extend:TI (match_operand:DI 1 "register_operand" "r"))
738 (zero_extend:TI (match_operand:DI 2 "register_operand" "r")))
739 (zero_extend:TI (plus:DI (match_dup 1) (match_dup 2)))))
740 (set (match_operand:DI 0 "register_operand" "=&r")
741 (plus:DI (match_dup 1) (match_dup 2)))]
744 "&& reload_completed"
745 [(parallel [(set (reg:CC_C CC_REGNUM)
746 (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
748 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
749 (parallel [(set (reg:CC_C CC_REGNUM)
752 (zero_extend:DI (match_dup 4))
753 (zero_extend:DI (match_dup 5)))
754 (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0)))
755 (plus:DI (zero_extend:DI
756 (plus:SI (match_dup 4) (match_dup 5)))
757 (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0)))))
758 (set (match_dup 3) (plus:SI
759 (plus:SI (match_dup 4) (match_dup 5))
760 (ltu:SI (reg:CC_C CC_REGNUM)
764 operands[3] = gen_highpart (SImode, operands[0]);
765 operands[0] = gen_lowpart (SImode, operands[0]);
766 operands[4] = gen_highpart (SImode, operands[1]);
767 operands[5] = gen_highpart (SImode, operands[2]);
768 operands[1] = gen_lowpart (SImode, operands[1]);
769 operands[2] = gen_lowpart (SImode, operands[2]);
771 [(set_attr "conds" "set")
772 (set_attr "length" "8")
773 (set_attr "type" "multiple")]
776 (define_insn "*addsi3_compareC_upper"
777 [(set (reg:CC_C CC_REGNUM)
781 (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
782 (zero_extend:DI (match_operand:SI 2 "register_operand" "r")))
783 (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0)))
784 (plus:DI (zero_extend:DI
785 (plus:SI (match_dup 1) (match_dup 2)))
786 (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0)))))
787 (set (match_operand:SI 0 "register_operand" "=r")
789 (plus:SI (match_dup 1) (match_dup 2))
790 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
792 "adcs%?\\t%0, %1, %2"
793 [(set_attr "conds" "set")
794 (set_attr "type" "adcs_reg")]
797 (define_insn "addsi3_compareC"
798 [(set (reg:CC_C CC_REGNUM)
801 (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
802 (zero_extend:DI (match_operand:SI 2 "register_operand" "r")))
804 (plus:SI (match_dup 1) (match_dup 2)))))
805 (set (match_operand:SI 0 "register_operand" "=r")
806 (plus:SI (match_dup 1) (match_dup 2)))]
808 "adds%?\\t%0, %1, %2"
809 [(set_attr "conds" "set")
810 (set_attr "type" "alus_sreg")]
813 (define_insn "addsi3_compare0"
814 [(set (reg:CC_NOOV CC_REGNUM)
816 (plus:SI (match_operand:SI 1 "s_register_operand" "r, r,r")
817 (match_operand:SI 2 "arm_add_operand" "I,L,r"))
819 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
820 (plus:SI (match_dup 1) (match_dup 2)))]
824 subs%?\\t%0, %1, #%n2
826 [(set_attr "conds" "set")
827 (set_attr "type" "alus_imm,alus_imm,alus_sreg")]
830 (define_insn "*addsi3_compare0_scratch"
831 [(set (reg:CC_NOOV CC_REGNUM)
833 (plus:SI (match_operand:SI 0 "s_register_operand" "r, r, r")
834 (match_operand:SI 1 "arm_add_operand" "I,L, r"))
841 [(set_attr "conds" "set")
842 (set_attr "predicable" "yes")
843 (set_attr "type" "alus_imm,alus_imm,alus_sreg")]
846 (define_insn "*compare_negsi_si"
847 [(set (reg:CC_Z CC_REGNUM)
849 (neg:SI (match_operand:SI 0 "s_register_operand" "l,r"))
850 (match_operand:SI 1 "s_register_operand" "l,r")))]
853 [(set_attr "conds" "set")
854 (set_attr "predicable" "yes")
855 (set_attr "arch" "t2,*")
856 (set_attr "length" "2,4")
857 (set_attr "predicable_short_it" "yes,no")
858 (set_attr "type" "alus_sreg")]
861 ;; This is the canonicalization of addsi3_compare0_for_combiner when the
862 ;; addend is a constant.
863 (define_insn "cmpsi2_addneg"
864 [(set (reg:CC CC_REGNUM)
866 (match_operand:SI 1 "s_register_operand" "r,r")
867 (match_operand:SI 2 "arm_addimm_operand" "L,I")))
868 (set (match_operand:SI 0 "s_register_operand" "=r,r")
869 (plus:SI (match_dup 1)
870 (match_operand:SI 3 "arm_addimm_operand" "I,L")))]
871 "TARGET_32BIT && INTVAL (operands[2]) == -INTVAL (operands[3])"
874 subs%?\\t%0, %1, #%n3"
875 [(set_attr "conds" "set")
876 (set_attr "type" "alus_sreg")]
879 ;; Convert the sequence
881 ;; cmn rd, #1 (equivalent to cmp rd, #-1)
885 ;; bcs dest ((unsigned)rn >= 1)
886 ;; similarly for the beq variant using bcc.
887 ;; This is a common looping idiom (while (n--))
889 [(set (match_operand:SI 0 "arm_general_register_operand" "")
890 (plus:SI (match_operand:SI 1 "arm_general_register_operand" "")
892 (set (match_operand 2 "cc_register" "")
893 (compare (match_dup 0) (const_int -1)))
895 (if_then_else (match_operator 3 "equality_operator"
896 [(match_dup 2) (const_int 0)])
897 (match_operand 4 "" "")
898 (match_operand 5 "" "")))]
899 "TARGET_32BIT && peep2_reg_dead_p (3, operands[2])"
903 (match_dup 1) (const_int 1)))
904 (set (match_dup 0) (plus:SI (match_dup 1) (const_int -1)))])
906 (if_then_else (match_op_dup 3 [(match_dup 2) (const_int 0)])
909 "operands[2] = gen_rtx_REG (CCmode, CC_REGNUM);
910 operands[3] = gen_rtx_fmt_ee ((GET_CODE (operands[3]) == NE
913 operands[2], const0_rtx);"
916 ;; The next four insns work because they compare the result with one of
917 ;; the operands, and we know that the use of the condition code is
918 ;; either GEU or LTU, so we can use the carry flag from the addition
919 ;; instead of doing the compare a second time.
920 (define_insn "*addsi3_compare_op1"
921 [(set (reg:CC_C CC_REGNUM)
923 (plus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
924 (match_operand:SI 2 "arm_add_operand" "I,L,r"))
926 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
927 (plus:SI (match_dup 1) (match_dup 2)))]
931 subs%?\\t%0, %1, #%n2
933 [(set_attr "conds" "set")
934 (set_attr "type" "alus_imm,alus_imm,alus_sreg")]
937 (define_insn "*addsi3_compare_op2"
938 [(set (reg:CC_C CC_REGNUM)
940 (plus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
941 (match_operand:SI 2 "arm_add_operand" "I,L,r"))
943 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
944 (plus:SI (match_dup 1) (match_dup 2)))]
948 subs%?\\t%0, %1, #%n2
950 [(set_attr "conds" "set")
951 (set_attr "type" "alus_imm,alus_imm,alus_sreg")]
954 (define_insn "*compare_addsi2_op0"
955 [(set (reg:CC_C CC_REGNUM)
957 (plus:SI (match_operand:SI 0 "s_register_operand" "l,l,r,r,r")
958 (match_operand:SI 1 "arm_add_operand" "Pv,l,I,L,r"))
967 [(set_attr "conds" "set")
968 (set_attr "predicable" "yes")
969 (set_attr "arch" "t2,t2,*,*,*")
970 (set_attr "predicable_short_it" "yes,yes,no,no,no")
971 (set_attr "length" "2,2,4,4,4")
972 (set_attr "type" "alus_imm,alus_sreg,alus_imm,alus_imm,alus_sreg")]
975 (define_insn "*compare_addsi2_op1"
976 [(set (reg:CC_C CC_REGNUM)
978 (plus:SI (match_operand:SI 0 "s_register_operand" "l,l,r,r,r")
979 (match_operand:SI 1 "arm_add_operand" "Pv,l,I,L,r"))
988 [(set_attr "conds" "set")
989 (set_attr "predicable" "yes")
990 (set_attr "arch" "t2,t2,*,*,*")
991 (set_attr "predicable_short_it" "yes,yes,no,no,no")
992 (set_attr "length" "2,2,4,4,4")
993 (set_attr "type" "alus_imm,alus_sreg,alus_imm,alus_imm,alus_sreg")]
996 (define_insn "*addsi3_carryin_<optab>"
997 [(set (match_operand:SI 0 "s_register_operand" "=l,r,r")
998 (plus:SI (plus:SI (match_operand:SI 1 "s_register_operand" "%l,r,r")
999 (match_operand:SI 2 "arm_not_operand" "0,rI,K"))
1000 (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))))]
1005 sbc%?\\t%0, %1, #%B2"
1006 [(set_attr "conds" "use")
1007 (set_attr "predicable" "yes")
1008 (set_attr "arch" "t2,*,*")
1009 (set_attr "length" "4")
1010 (set_attr "predicable_short_it" "yes,no,no")
1011 (set_attr "type" "adc_reg,adc_reg,adc_imm")]
1014 (define_insn "*addsi3_carryin_alt2_<optab>"
1015 [(set (match_operand:SI 0 "s_register_operand" "=l,r,r")
1016 (plus:SI (plus:SI (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))
1017 (match_operand:SI 1 "s_register_operand" "%l,r,r"))
1018 (match_operand:SI 2 "arm_rhs_operand" "l,rI,K")))]
1023 sbc%?\\t%0, %1, #%B2"
1024 [(set_attr "conds" "use")
1025 (set_attr "predicable" "yes")
1026 (set_attr "arch" "t2,*,*")
1027 (set_attr "length" "4")
1028 (set_attr "predicable_short_it" "yes,no,no")
1029 (set_attr "type" "adc_reg,adc_reg,adc_imm")]
1032 (define_insn "*addsi3_carryin_shift_<optab>"
1033 [(set (match_operand:SI 0 "s_register_operand" "=r")
1035 (match_operator:SI 2 "shift_operator"
1036 [(match_operand:SI 3 "s_register_operand" "r")
1037 (match_operand:SI 4 "reg_or_int_operand" "rM")])
1038 (match_operand:SI 1 "s_register_operand" "r"))
1039 (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))))]
1041 "adc%?\\t%0, %1, %3%S2"
1042 [(set_attr "conds" "use")
1043 (set_attr "predicable" "yes")
1044 (set_attr "predicable_short_it" "no")
1045 (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
1046 (const_string "alu_shift_imm")
1047 (const_string "alu_shift_reg")))]
1050 (define_insn "*addsi3_carryin_clobercc_<optab>"
1051 [(set (match_operand:SI 0 "s_register_operand" "=r")
1052 (plus:SI (plus:SI (match_operand:SI 1 "s_register_operand" "%r")
1053 (match_operand:SI 2 "arm_rhs_operand" "rI"))
1054 (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))))
1055 (clobber (reg:CC CC_REGNUM))]
1057 "adcs%?\\t%0, %1, %2"
1058 [(set_attr "conds" "set")
1059 (set_attr "type" "adcs_reg")]
1062 (define_expand "subv<mode>4"
1063 [(match_operand:SIDI 0 "register_operand")
1064 (match_operand:SIDI 1 "register_operand")
1065 (match_operand:SIDI 2 "register_operand")
1066 (match_operand 3 "")]
1069 emit_insn (gen_sub<mode>3_compare1 (operands[0], operands[1], operands[2]));
1070 arm_gen_unlikely_cbranch (NE, CC_Vmode, operands[3]);
1075 (define_expand "usubv<mode>4"
1076 [(match_operand:SIDI 0 "register_operand")
1077 (match_operand:SIDI 1 "register_operand")
1078 (match_operand:SIDI 2 "register_operand")
1079 (match_operand 3 "")]
1082 emit_insn (gen_sub<mode>3_compare1 (operands[0], operands[1], operands[2]));
1083 arm_gen_unlikely_cbranch (LTU, CCmode, operands[3]);
1088 (define_insn_and_split "subdi3_compare1"
1089 [(set (reg:CC CC_REGNUM)
1091 (match_operand:DI 1 "register_operand" "r")
1092 (match_operand:DI 2 "register_operand" "r")))
1093 (set (match_operand:DI 0 "register_operand" "=&r")
1094 (minus:DI (match_dup 1) (match_dup 2)))]
1097 "&& reload_completed"
1098 [(parallel [(set (reg:CC CC_REGNUM)
1099 (compare:CC (match_dup 1) (match_dup 2)))
1100 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1101 (parallel [(set (reg:CC CC_REGNUM)
1102 (compare:CC (match_dup 4) (match_dup 5)))
1103 (set (match_dup 3) (minus:SI (minus:SI (match_dup 4) (match_dup 5))
1104 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))])]
1106 operands[3] = gen_highpart (SImode, operands[0]);
1107 operands[0] = gen_lowpart (SImode, operands[0]);
1108 operands[4] = gen_highpart (SImode, operands[1]);
1109 operands[1] = gen_lowpart (SImode, operands[1]);
1110 operands[5] = gen_highpart (SImode, operands[2]);
1111 operands[2] = gen_lowpart (SImode, operands[2]);
1113 [(set_attr "conds" "set")
1114 (set_attr "length" "8")
1115 (set_attr "type" "multiple")]
1118 (define_insn "subsi3_compare1"
1119 [(set (reg:CC CC_REGNUM)
1121 (match_operand:SI 1 "register_operand" "r")
1122 (match_operand:SI 2 "register_operand" "r")))
1123 (set (match_operand:SI 0 "register_operand" "=r")
1124 (minus:SI (match_dup 1) (match_dup 2)))]
1126 "subs%?\\t%0, %1, %2"
1127 [(set_attr "conds" "set")
1128 (set_attr "type" "alus_sreg")]
1131 (define_insn "*subsi3_carryin"
1132 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
1133 (minus:SI (minus:SI (match_operand:SI 1 "reg_or_int_operand" "r,I")
1134 (match_operand:SI 2 "s_register_operand" "r,r"))
1135 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1140 [(set_attr "conds" "use")
1141 (set_attr "arch" "*,a")
1142 (set_attr "predicable" "yes")
1143 (set_attr "predicable_short_it" "no")
1144 (set_attr "type" "adc_reg,adc_imm")]
1147 (define_insn "*subsi3_carryin_const"
1148 [(set (match_operand:SI 0 "s_register_operand" "=r")
1149 (minus:SI (plus:SI (match_operand:SI 1 "s_register_operand" "r")
1150 (match_operand:SI 2 "arm_not_immediate_operand" "K"))
1151 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1153 "sbc\\t%0, %1, #%B2"
1154 [(set_attr "conds" "use")
1155 (set_attr "type" "adc_imm")]
1158 (define_insn "*subsi3_carryin_compare"
1159 [(set (reg:CC CC_REGNUM)
1160 (compare:CC (match_operand:SI 1 "s_register_operand" "r")
1161 (match_operand:SI 2 "s_register_operand" "r")))
1162 (set (match_operand:SI 0 "s_register_operand" "=r")
1163 (minus:SI (minus:SI (match_dup 1)
1165 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1168 [(set_attr "conds" "set")
1169 (set_attr "type" "adcs_reg")]
1172 (define_insn "*subsi3_carryin_compare_const"
1173 [(set (reg:CC CC_REGNUM)
1174 (compare:CC (match_operand:SI 1 "reg_or_int_operand" "r")
1175 (match_operand:SI 2 "arm_not_operand" "K")))
1176 (set (match_operand:SI 0 "s_register_operand" "=r")
1177 (minus:SI (plus:SI (match_dup 1)
1179 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1181 "sbcs\\t%0, %1, #%B2"
1182 [(set_attr "conds" "set")
1183 (set_attr "type" "adcs_imm")]
1186 (define_insn "*subsi3_carryin_shift"
1187 [(set (match_operand:SI 0 "s_register_operand" "=r")
1189 (match_operand:SI 1 "s_register_operand" "r")
1190 (match_operator:SI 2 "shift_operator"
1191 [(match_operand:SI 3 "s_register_operand" "r")
1192 (match_operand:SI 4 "reg_or_int_operand" "rM")]))
1193 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1195 "sbc%?\\t%0, %1, %3%S2"
1196 [(set_attr "conds" "use")
1197 (set_attr "predicable" "yes")
1198 (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
1199 (const_string "alu_shift_imm")
1200 (const_string "alu_shift_reg")))]
1203 (define_insn "*rsbsi3_carryin_shift"
1204 [(set (match_operand:SI 0 "s_register_operand" "=r")
1206 (match_operator:SI 2 "shift_operator"
1207 [(match_operand:SI 3 "s_register_operand" "r")
1208 (match_operand:SI 4 "reg_or_int_operand" "rM")])
1209 (match_operand:SI 1 "s_register_operand" "r"))
1210 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1212 "rsc%?\\t%0, %1, %3%S2"
1213 [(set_attr "conds" "use")
1214 (set_attr "predicable" "yes")
1215 (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
1216 (const_string "alu_shift_imm")
1217 (const_string "alu_shift_reg")))]
1220 ; transform ((x << y) - 1) to ~(~(x-1) << y) Where X is a constant.
1222 [(set (match_operand:SI 0 "s_register_operand" "")
1223 (plus:SI (ashift:SI (match_operand:SI 1 "const_int_operand" "")
1224 (match_operand:SI 2 "s_register_operand" ""))
1226 (clobber (match_operand:SI 3 "s_register_operand" ""))]
1228 [(set (match_dup 3) (match_dup 1))
1229 (set (match_dup 0) (not:SI (ashift:SI (match_dup 3) (match_dup 2))))]
1231 operands[1] = GEN_INT (~(INTVAL (operands[1]) - 1));
1234 (define_expand "addsf3"
1235 [(set (match_operand:SF 0 "s_register_operand" "")
1236 (plus:SF (match_operand:SF 1 "s_register_operand" "")
1237 (match_operand:SF 2 "s_register_operand" "")))]
1238 "TARGET_32BIT && TARGET_HARD_FLOAT"
1242 (define_expand "adddf3"
1243 [(set (match_operand:DF 0 "s_register_operand" "")
1244 (plus:DF (match_operand:DF 1 "s_register_operand" "")
1245 (match_operand:DF 2 "s_register_operand" "")))]
1246 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
1250 (define_expand "subdi3"
1252 [(set (match_operand:DI 0 "s_register_operand" "")
1253 (minus:DI (match_operand:DI 1 "s_register_operand" "")
1254 (match_operand:DI 2 "s_register_operand" "")))
1255 (clobber (reg:CC CC_REGNUM))])]
1260 if (!REG_P (operands[1]))
1261 operands[1] = force_reg (DImode, operands[1]);
1262 if (!REG_P (operands[2]))
1263 operands[2] = force_reg (DImode, operands[2]);
1268 (define_insn_and_split "*arm_subdi3"
1269 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r,&r")
1270 (minus:DI (match_operand:DI 1 "s_register_operand" "0,r,0")
1271 (match_operand:DI 2 "s_register_operand" "r,0,0")))
1272 (clobber (reg:CC CC_REGNUM))]
1273 "TARGET_32BIT && !TARGET_NEON"
1274 "#" ; "subs\\t%Q0, %Q1, %Q2\;sbc\\t%R0, %R1, %R2"
1275 "&& reload_completed"
1276 [(parallel [(set (reg:CC CC_REGNUM)
1277 (compare:CC (match_dup 1) (match_dup 2)))
1278 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1279 (set (match_dup 3) (minus:SI (minus:SI (match_dup 4) (match_dup 5))
1280 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1282 operands[3] = gen_highpart (SImode, operands[0]);
1283 operands[0] = gen_lowpart (SImode, operands[0]);
1284 operands[4] = gen_highpart (SImode, operands[1]);
1285 operands[1] = gen_lowpart (SImode, operands[1]);
1286 operands[5] = gen_highpart (SImode, operands[2]);
1287 operands[2] = gen_lowpart (SImode, operands[2]);
1289 [(set_attr "conds" "clob")
1290 (set_attr "length" "8")
1291 (set_attr "type" "multiple")]
1294 (define_insn_and_split "*subdi_di_zesidi"
1295 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1296 (minus:DI (match_operand:DI 1 "s_register_operand" "0,r")
1298 (match_operand:SI 2 "s_register_operand" "r,r"))))
1299 (clobber (reg:CC CC_REGNUM))]
1301 "#" ; "subs\\t%Q0, %Q1, %2\;sbc\\t%R0, %R1, #0"
1302 "&& reload_completed"
1303 [(parallel [(set (reg:CC CC_REGNUM)
1304 (compare:CC (match_dup 1) (match_dup 2)))
1305 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1306 (set (match_dup 3) (minus:SI (plus:SI (match_dup 4) (match_dup 5))
1307 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1309 operands[3] = gen_highpart (SImode, operands[0]);
1310 operands[0] = gen_lowpart (SImode, operands[0]);
1311 operands[4] = gen_highpart (SImode, operands[1]);
1312 operands[1] = gen_lowpart (SImode, operands[1]);
1313 operands[5] = GEN_INT (~0);
1315 [(set_attr "conds" "clob")
1316 (set_attr "length" "8")
1317 (set_attr "type" "multiple")]
1320 (define_insn_and_split "*subdi_di_sesidi"
1321 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1322 (minus:DI (match_operand:DI 1 "s_register_operand" "0,r")
1324 (match_operand:SI 2 "s_register_operand" "r,r"))))
1325 (clobber (reg:CC CC_REGNUM))]
1327 "#" ; "subs\\t%Q0, %Q1, %2\;sbc\\t%R0, %R1, %2, asr #31"
1328 "&& reload_completed"
1329 [(parallel [(set (reg:CC CC_REGNUM)
1330 (compare:CC (match_dup 1) (match_dup 2)))
1331 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1332 (set (match_dup 3) (minus:SI (minus:SI (match_dup 4)
1333 (ashiftrt:SI (match_dup 2)
1335 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1337 operands[3] = gen_highpart (SImode, operands[0]);
1338 operands[0] = gen_lowpart (SImode, operands[0]);
1339 operands[4] = gen_highpart (SImode, operands[1]);
1340 operands[1] = gen_lowpart (SImode, operands[1]);
1342 [(set_attr "conds" "clob")
1343 (set_attr "length" "8")
1344 (set_attr "type" "multiple")]
1347 (define_insn_and_split "*subdi_zesidi_di"
1348 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1349 (minus:DI (zero_extend:DI
1350 (match_operand:SI 2 "s_register_operand" "r,r"))
1351 (match_operand:DI 1 "s_register_operand" "0,r")))
1352 (clobber (reg:CC CC_REGNUM))]
1354 "#" ; "rsbs\\t%Q0, %Q1, %2\;rsc\\t%R0, %R1, #0"
1356 ; "subs\\t%Q0, %2, %Q1\;rsc\\t%R0, %R1, #0"
1357 "&& reload_completed"
1358 [(parallel [(set (reg:CC CC_REGNUM)
1359 (compare:CC (match_dup 2) (match_dup 1)))
1360 (set (match_dup 0) (minus:SI (match_dup 2) (match_dup 1)))])
1361 (set (match_dup 3) (minus:SI (minus:SI (const_int 0) (match_dup 4))
1362 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1364 operands[3] = gen_highpart (SImode, operands[0]);
1365 operands[0] = gen_lowpart (SImode, operands[0]);
1366 operands[4] = gen_highpart (SImode, operands[1]);
1367 operands[1] = gen_lowpart (SImode, operands[1]);
1369 [(set_attr "conds" "clob")
1370 (set_attr "length" "8")
1371 (set_attr "type" "multiple")]
1374 (define_insn_and_split "*subdi_sesidi_di"
1375 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1376 (minus:DI (sign_extend:DI
1377 (match_operand:SI 2 "s_register_operand" "r,r"))
1378 (match_operand:DI 1 "s_register_operand" "0,r")))
1379 (clobber (reg:CC CC_REGNUM))]
1381 "#" ; "rsbs\\t%Q0, %Q1, %2\;rsc\\t%R0, %R1, %2, asr #31"
1383 ; "subs\\t%Q0, %2, %Q1\;rsc\\t%R0, %R1, %2, asr #31"
1384 "&& reload_completed"
1385 [(parallel [(set (reg:CC CC_REGNUM)
1386 (compare:CC (match_dup 2) (match_dup 1)))
1387 (set (match_dup 0) (minus:SI (match_dup 2) (match_dup 1)))])
1388 (set (match_dup 3) (minus:SI (minus:SI
1389 (ashiftrt:SI (match_dup 2)
1392 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1394 operands[3] = gen_highpart (SImode, operands[0]);
1395 operands[0] = gen_lowpart (SImode, operands[0]);
1396 operands[4] = gen_highpart (SImode, operands[1]);
1397 operands[1] = gen_lowpart (SImode, operands[1]);
1399 [(set_attr "conds" "clob")
1400 (set_attr "length" "8")
1401 (set_attr "type" "multiple")]
1404 (define_insn_and_split "*subdi_zesidi_zesidi"
1405 [(set (match_operand:DI 0 "s_register_operand" "=r")
1406 (minus:DI (zero_extend:DI
1407 (match_operand:SI 1 "s_register_operand" "r"))
1409 (match_operand:SI 2 "s_register_operand" "r"))))
1410 (clobber (reg:CC CC_REGNUM))]
1412 "#" ; "subs\\t%Q0, %1, %2\;sbc\\t%R0, %1, %1"
1413 "&& reload_completed"
1414 [(parallel [(set (reg:CC CC_REGNUM)
1415 (compare:CC (match_dup 1) (match_dup 2)))
1416 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1417 (set (match_dup 3) (minus:SI (minus:SI (match_dup 1) (match_dup 1))
1418 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1420 operands[3] = gen_highpart (SImode, operands[0]);
1421 operands[0] = gen_lowpart (SImode, operands[0]);
1423 [(set_attr "conds" "clob")
1424 (set_attr "length" "8")
1425 (set_attr "type" "multiple")]
1428 (define_expand "subsi3"
1429 [(set (match_operand:SI 0 "s_register_operand" "")
1430 (minus:SI (match_operand:SI 1 "reg_or_int_operand" "")
1431 (match_operand:SI 2 "s_register_operand" "")))]
1434 if (CONST_INT_P (operands[1]))
1438 if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[1]), MINUS))
1439 operands[1] = force_reg (SImode, operands[1]);
1442 arm_split_constant (MINUS, SImode, NULL_RTX,
1443 INTVAL (operands[1]), operands[0],
1445 optimize && can_create_pseudo_p ());
1449 else /* TARGET_THUMB1 */
1450 operands[1] = force_reg (SImode, operands[1]);
1455 ; ??? Check Thumb-2 split length
1456 (define_insn_and_split "*arm_subsi3_insn"
1457 [(set (match_operand:SI 0 "s_register_operand" "=l,l ,l ,l ,r,r,r,rk,r")
1458 (minus:SI (match_operand:SI 1 "reg_or_int_operand" "l ,0 ,l ,Pz,I,r,r,k ,?n")
1459 (match_operand:SI 2 "reg_or_int_operand" "l ,Py,Pd,l ,r,I,r,r ,r")))]
1471 "&& (CONST_INT_P (operands[1])
1472 && !const_ok_for_arm (INTVAL (operands[1])))"
1473 [(clobber (const_int 0))]
1475 arm_split_constant (MINUS, SImode, curr_insn,
1476 INTVAL (operands[1]), operands[0], operands[2], 0);
1479 [(set_attr "length" "4,4,4,4,4,4,4,4,16")
1480 (set_attr "arch" "t2,t2,t2,t2,*,*,*,*,*")
1481 (set_attr "predicable" "yes")
1482 (set_attr "predicable_short_it" "yes,yes,yes,yes,no,no,no,no,no")
1483 (set_attr "type" "alu_sreg,alu_sreg,alu_sreg,alu_sreg,alu_imm,alu_imm,alu_sreg,alu_sreg,multiple")]
1487 [(match_scratch:SI 3 "r")
1488 (set (match_operand:SI 0 "arm_general_register_operand" "")
1489 (minus:SI (match_operand:SI 1 "const_int_operand" "")
1490 (match_operand:SI 2 "arm_general_register_operand" "")))]
1492 && !const_ok_for_arm (INTVAL (operands[1]))
1493 && const_ok_for_arm (~INTVAL (operands[1]))"
1494 [(set (match_dup 3) (match_dup 1))
1495 (set (match_dup 0) (minus:SI (match_dup 3) (match_dup 2)))]
1499 (define_insn "subsi3_compare0"
1500 [(set (reg:CC_NOOV CC_REGNUM)
1502 (minus:SI (match_operand:SI 1 "arm_rhs_operand" "r,r,I")
1503 (match_operand:SI 2 "arm_rhs_operand" "I,r,r"))
1505 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
1506 (minus:SI (match_dup 1) (match_dup 2)))]
1511 rsbs%?\\t%0, %2, %1"
1512 [(set_attr "conds" "set")
1513 (set_attr "type" "alus_imm,alus_sreg,alus_sreg")]
1516 (define_insn "subsi3_compare"
1517 [(set (reg:CC CC_REGNUM)
1518 (compare:CC (match_operand:SI 1 "arm_rhs_operand" "r,r,I")
1519 (match_operand:SI 2 "arm_rhs_operand" "I,r,r")))
1520 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
1521 (minus:SI (match_dup 1) (match_dup 2)))]
1526 rsbs%?\\t%0, %2, %1"
1527 [(set_attr "conds" "set")
1528 (set_attr "type" "alus_imm,alus_sreg,alus_sreg")]
1531 (define_expand "subsf3"
1532 [(set (match_operand:SF 0 "s_register_operand" "")
1533 (minus:SF (match_operand:SF 1 "s_register_operand" "")
1534 (match_operand:SF 2 "s_register_operand" "")))]
1535 "TARGET_32BIT && TARGET_HARD_FLOAT"
1539 (define_expand "subdf3"
1540 [(set (match_operand:DF 0 "s_register_operand" "")
1541 (minus:DF (match_operand:DF 1 "s_register_operand" "")
1542 (match_operand:DF 2 "s_register_operand" "")))]
1543 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
1548 ;; Multiplication insns
1550 (define_expand "mulhi3"
1551 [(set (match_operand:HI 0 "s_register_operand" "")
1552 (mult:HI (match_operand:HI 1 "s_register_operand" "")
1553 (match_operand:HI 2 "s_register_operand" "")))]
1554 "TARGET_DSP_MULTIPLY"
1557 rtx result = gen_reg_rtx (SImode);
1558 emit_insn (gen_mulhisi3 (result, operands[1], operands[2]));
1559 emit_move_insn (operands[0], gen_lowpart (HImode, result));
1564 (define_expand "mulsi3"
1565 [(set (match_operand:SI 0 "s_register_operand" "")
1566 (mult:SI (match_operand:SI 2 "s_register_operand" "")
1567 (match_operand:SI 1 "s_register_operand" "")))]
1572 ;; Use `&' and then `0' to prevent the operands 0 and 1 being the same
1573 (define_insn "*arm_mulsi3"
1574 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1575 (mult:SI (match_operand:SI 2 "s_register_operand" "r,r")
1576 (match_operand:SI 1 "s_register_operand" "%0,r")))]
1577 "TARGET_32BIT && !arm_arch6"
1578 "mul%?\\t%0, %2, %1"
1579 [(set_attr "type" "mul")
1580 (set_attr "predicable" "yes")]
1583 (define_insn "*arm_mulsi3_v6"
1584 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r")
1585 (mult:SI (match_operand:SI 1 "s_register_operand" "0,l,r")
1586 (match_operand:SI 2 "s_register_operand" "l,0,r")))]
1587 "TARGET_32BIT && arm_arch6"
1588 "mul%?\\t%0, %1, %2"
1589 [(set_attr "type" "mul")
1590 (set_attr "predicable" "yes")
1591 (set_attr "arch" "t2,t2,*")
1592 (set_attr "length" "4")
1593 (set_attr "predicable_short_it" "yes,yes,no")]
1596 (define_insn "*mulsi3_compare0"
1597 [(set (reg:CC_NOOV CC_REGNUM)
1598 (compare:CC_NOOV (mult:SI
1599 (match_operand:SI 2 "s_register_operand" "r,r")
1600 (match_operand:SI 1 "s_register_operand" "%0,r"))
1602 (set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1603 (mult:SI (match_dup 2) (match_dup 1)))]
1604 "TARGET_ARM && !arm_arch6"
1605 "muls%?\\t%0, %2, %1"
1606 [(set_attr "conds" "set")
1607 (set_attr "type" "muls")]
1610 (define_insn "*mulsi3_compare0_v6"
1611 [(set (reg:CC_NOOV CC_REGNUM)
1612 (compare:CC_NOOV (mult:SI
1613 (match_operand:SI 2 "s_register_operand" "r")
1614 (match_operand:SI 1 "s_register_operand" "r"))
1616 (set (match_operand:SI 0 "s_register_operand" "=r")
1617 (mult:SI (match_dup 2) (match_dup 1)))]
1618 "TARGET_ARM && arm_arch6 && optimize_size"
1619 "muls%?\\t%0, %2, %1"
1620 [(set_attr "conds" "set")
1621 (set_attr "type" "muls")]
1624 (define_insn "*mulsi_compare0_scratch"
1625 [(set (reg:CC_NOOV CC_REGNUM)
1626 (compare:CC_NOOV (mult:SI
1627 (match_operand:SI 2 "s_register_operand" "r,r")
1628 (match_operand:SI 1 "s_register_operand" "%0,r"))
1630 (clobber (match_scratch:SI 0 "=&r,&r"))]
1631 "TARGET_ARM && !arm_arch6"
1632 "muls%?\\t%0, %2, %1"
1633 [(set_attr "conds" "set")
1634 (set_attr "type" "muls")]
1637 (define_insn "*mulsi_compare0_scratch_v6"
1638 [(set (reg:CC_NOOV CC_REGNUM)
1639 (compare:CC_NOOV (mult:SI
1640 (match_operand:SI 2 "s_register_operand" "r")
1641 (match_operand:SI 1 "s_register_operand" "r"))
1643 (clobber (match_scratch:SI 0 "=r"))]
1644 "TARGET_ARM && arm_arch6 && optimize_size"
1645 "muls%?\\t%0, %2, %1"
1646 [(set_attr "conds" "set")
1647 (set_attr "type" "muls")]
1650 ;; Unnamed templates to match MLA instruction.
1652 (define_insn "*mulsi3addsi"
1653 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r,&r")
1655 (mult:SI (match_operand:SI 2 "s_register_operand" "r,r,r,r")
1656 (match_operand:SI 1 "s_register_operand" "%0,r,0,r"))
1657 (match_operand:SI 3 "s_register_operand" "r,r,0,0")))]
1658 "TARGET_32BIT && !arm_arch6"
1659 "mla%?\\t%0, %2, %1, %3"
1660 [(set_attr "type" "mla")
1661 (set_attr "predicable" "yes")]
1664 (define_insn "*mulsi3addsi_v6"
1665 [(set (match_operand:SI 0 "s_register_operand" "=r")
1667 (mult:SI (match_operand:SI 2 "s_register_operand" "r")
1668 (match_operand:SI 1 "s_register_operand" "r"))
1669 (match_operand:SI 3 "s_register_operand" "r")))]
1670 "TARGET_32BIT && arm_arch6"
1671 "mla%?\\t%0, %2, %1, %3"
1672 [(set_attr "type" "mla")
1673 (set_attr "predicable" "yes")
1674 (set_attr "predicable_short_it" "no")]
1677 (define_insn "*mulsi3addsi_compare0"
1678 [(set (reg:CC_NOOV CC_REGNUM)
1681 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
1682 (match_operand:SI 1 "s_register_operand" "%0,r,0,r"))
1683 (match_operand:SI 3 "s_register_operand" "r,r,0,0"))
1685 (set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r,&r")
1686 (plus:SI (mult:SI (match_dup 2) (match_dup 1))
1688 "TARGET_ARM && arm_arch6"
1689 "mlas%?\\t%0, %2, %1, %3"
1690 [(set_attr "conds" "set")
1691 (set_attr "type" "mlas")]
1694 (define_insn "*mulsi3addsi_compare0_v6"
1695 [(set (reg:CC_NOOV CC_REGNUM)
1698 (match_operand:SI 2 "s_register_operand" "r")
1699 (match_operand:SI 1 "s_register_operand" "r"))
1700 (match_operand:SI 3 "s_register_operand" "r"))
1702 (set (match_operand:SI 0 "s_register_operand" "=r")
1703 (plus:SI (mult:SI (match_dup 2) (match_dup 1))
1705 "TARGET_ARM && arm_arch6 && optimize_size"
1706 "mlas%?\\t%0, %2, %1, %3"
1707 [(set_attr "conds" "set")
1708 (set_attr "type" "mlas")]
1711 (define_insn "*mulsi3addsi_compare0_scratch"
1712 [(set (reg:CC_NOOV CC_REGNUM)
1715 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
1716 (match_operand:SI 1 "s_register_operand" "%0,r,0,r"))
1717 (match_operand:SI 3 "s_register_operand" "?r,r,0,0"))
1719 (clobber (match_scratch:SI 0 "=&r,&r,&r,&r"))]
1720 "TARGET_ARM && !arm_arch6"
1721 "mlas%?\\t%0, %2, %1, %3"
1722 [(set_attr "conds" "set")
1723 (set_attr "type" "mlas")]
1726 (define_insn "*mulsi3addsi_compare0_scratch_v6"
1727 [(set (reg:CC_NOOV CC_REGNUM)
1730 (match_operand:SI 2 "s_register_operand" "r")
1731 (match_operand:SI 1 "s_register_operand" "r"))
1732 (match_operand:SI 3 "s_register_operand" "r"))
1734 (clobber (match_scratch:SI 0 "=r"))]
1735 "TARGET_ARM && arm_arch6 && optimize_size"
1736 "mlas%?\\t%0, %2, %1, %3"
1737 [(set_attr "conds" "set")
1738 (set_attr "type" "mlas")]
1741 (define_insn "*mulsi3subsi"
1742 [(set (match_operand:SI 0 "s_register_operand" "=r")
1744 (match_operand:SI 3 "s_register_operand" "r")
1745 (mult:SI (match_operand:SI 2 "s_register_operand" "r")
1746 (match_operand:SI 1 "s_register_operand" "r"))))]
1747 "TARGET_32BIT && arm_arch_thumb2"
1748 "mls%?\\t%0, %2, %1, %3"
1749 [(set_attr "type" "mla")
1750 (set_attr "predicable" "yes")
1751 (set_attr "predicable_short_it" "no")]
1754 (define_expand "maddsidi4"
1755 [(set (match_operand:DI 0 "s_register_operand" "")
1758 (sign_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1759 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1760 (match_operand:DI 3 "s_register_operand" "")))]
1761 "TARGET_32BIT && arm_arch3m"
1764 (define_insn "*mulsidi3adddi"
1765 [(set (match_operand:DI 0 "s_register_operand" "=&r")
1768 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "%r"))
1769 (sign_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1770 (match_operand:DI 1 "s_register_operand" "0")))]
1771 "TARGET_32BIT && arm_arch3m && !arm_arch6"
1772 "smlal%?\\t%Q0, %R0, %3, %2"
1773 [(set_attr "type" "smlal")
1774 (set_attr "predicable" "yes")]
1777 (define_insn "*mulsidi3adddi_v6"
1778 [(set (match_operand:DI 0 "s_register_operand" "=r")
1781 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r"))
1782 (sign_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1783 (match_operand:DI 1 "s_register_operand" "0")))]
1784 "TARGET_32BIT && arm_arch6"
1785 "smlal%?\\t%Q0, %R0, %3, %2"
1786 [(set_attr "type" "smlal")
1787 (set_attr "predicable" "yes")
1788 (set_attr "predicable_short_it" "no")]
1791 ;; 32x32->64 widening multiply.
1792 ;; As with mulsi3, the only difference between the v3-5 and v6+
1793 ;; versions of these patterns is the requirement that the output not
1794 ;; overlap the inputs, but that still means we have to have a named
1795 ;; expander and two different starred insns.
1797 (define_expand "mulsidi3"
1798 [(set (match_operand:DI 0 "s_register_operand" "")
1800 (sign_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1801 (sign_extend:DI (match_operand:SI 2 "s_register_operand" ""))))]
1802 "TARGET_32BIT && arm_arch3m"
1806 (define_insn "*mulsidi3_nov6"
1807 [(set (match_operand:DI 0 "s_register_operand" "=&r")
1809 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "%r"))
1810 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1811 "TARGET_32BIT && arm_arch3m && !arm_arch6"
1812 "smull%?\\t%Q0, %R0, %1, %2"
1813 [(set_attr "type" "smull")
1814 (set_attr "predicable" "yes")]
1817 (define_insn "*mulsidi3_v6"
1818 [(set (match_operand:DI 0 "s_register_operand" "=r")
1820 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1821 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1822 "TARGET_32BIT && arm_arch6"
1823 "smull%?\\t%Q0, %R0, %1, %2"
1824 [(set_attr "type" "smull")
1825 (set_attr "predicable" "yes")
1826 (set_attr "predicable_short_it" "no")]
1829 (define_expand "umulsidi3"
1830 [(set (match_operand:DI 0 "s_register_operand" "")
1832 (zero_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1833 (zero_extend:DI (match_operand:SI 2 "s_register_operand" ""))))]
1834 "TARGET_32BIT && arm_arch3m"
1838 (define_insn "*umulsidi3_nov6"
1839 [(set (match_operand:DI 0 "s_register_operand" "=&r")
1841 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "%r"))
1842 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1843 "TARGET_32BIT && arm_arch3m && !arm_arch6"
1844 "umull%?\\t%Q0, %R0, %1, %2"
1845 [(set_attr "type" "umull")
1846 (set_attr "predicable" "yes")]
1849 (define_insn "*umulsidi3_v6"
1850 [(set (match_operand:DI 0 "s_register_operand" "=r")
1852 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1853 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1854 "TARGET_32BIT && arm_arch6"
1855 "umull%?\\t%Q0, %R0, %1, %2"
1856 [(set_attr "type" "umull")
1857 (set_attr "predicable" "yes")
1858 (set_attr "predicable_short_it" "no")]
1861 (define_expand "umaddsidi4"
1862 [(set (match_operand:DI 0 "s_register_operand" "")
1865 (zero_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1866 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1867 (match_operand:DI 3 "s_register_operand" "")))]
1868 "TARGET_32BIT && arm_arch3m"
1871 (define_insn "*umulsidi3adddi"
1872 [(set (match_operand:DI 0 "s_register_operand" "=&r")
1875 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "%r"))
1876 (zero_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1877 (match_operand:DI 1 "s_register_operand" "0")))]
1878 "TARGET_32BIT && arm_arch3m && !arm_arch6"
1879 "umlal%?\\t%Q0, %R0, %3, %2"
1880 [(set_attr "type" "umlal")
1881 (set_attr "predicable" "yes")]
1884 (define_insn "*umulsidi3adddi_v6"
1885 [(set (match_operand:DI 0 "s_register_operand" "=r")
1888 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r"))
1889 (zero_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1890 (match_operand:DI 1 "s_register_operand" "0")))]
1891 "TARGET_32BIT && arm_arch6"
1892 "umlal%?\\t%Q0, %R0, %3, %2"
1893 [(set_attr "type" "umlal")
1894 (set_attr "predicable" "yes")
1895 (set_attr "predicable_short_it" "no")]
1898 (define_expand "smulsi3_highpart"
1900 [(set (match_operand:SI 0 "s_register_operand" "")
1904 (sign_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1905 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1907 (clobber (match_scratch:SI 3 ""))])]
1908 "TARGET_32BIT && arm_arch3m"
1912 (define_insn "*smulsi3_highpart_nov6"
1913 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1917 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "%0,r"))
1918 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r,r")))
1920 (clobber (match_scratch:SI 3 "=&r,&r"))]
1921 "TARGET_32BIT && arm_arch3m && !arm_arch6"
1922 "smull%?\\t%3, %0, %2, %1"
1923 [(set_attr "type" "smull")
1924 (set_attr "predicable" "yes")]
1927 (define_insn "*smulsi3_highpart_v6"
1928 [(set (match_operand:SI 0 "s_register_operand" "=r")
1932 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1933 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r")))
1935 (clobber (match_scratch:SI 3 "=r"))]
1936 "TARGET_32BIT && arm_arch6"
1937 "smull%?\\t%3, %0, %2, %1"
1938 [(set_attr "type" "smull")
1939 (set_attr "predicable" "yes")
1940 (set_attr "predicable_short_it" "no")]
1943 (define_expand "umulsi3_highpart"
1945 [(set (match_operand:SI 0 "s_register_operand" "")
1949 (zero_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1950 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1952 (clobber (match_scratch:SI 3 ""))])]
1953 "TARGET_32BIT && arm_arch3m"
1957 (define_insn "*umulsi3_highpart_nov6"
1958 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1962 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "%0,r"))
1963 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r,r")))
1965 (clobber (match_scratch:SI 3 "=&r,&r"))]
1966 "TARGET_32BIT && arm_arch3m && !arm_arch6"
1967 "umull%?\\t%3, %0, %2, %1"
1968 [(set_attr "type" "umull")
1969 (set_attr "predicable" "yes")]
1972 (define_insn "*umulsi3_highpart_v6"
1973 [(set (match_operand:SI 0 "s_register_operand" "=r")
1977 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1978 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r")))
1980 (clobber (match_scratch:SI 3 "=r"))]
1981 "TARGET_32BIT && arm_arch6"
1982 "umull%?\\t%3, %0, %2, %1"
1983 [(set_attr "type" "umull")
1984 (set_attr "predicable" "yes")
1985 (set_attr "predicable_short_it" "no")]
1988 (define_insn "mulhisi3"
1989 [(set (match_operand:SI 0 "s_register_operand" "=r")
1990 (mult:SI (sign_extend:SI
1991 (match_operand:HI 1 "s_register_operand" "%r"))
1993 (match_operand:HI 2 "s_register_operand" "r"))))]
1994 "TARGET_DSP_MULTIPLY"
1995 "smulbb%?\\t%0, %1, %2"
1996 [(set_attr "type" "smulxy")
1997 (set_attr "predicable" "yes")]
2000 (define_insn "*mulhisi3tb"
2001 [(set (match_operand:SI 0 "s_register_operand" "=r")
2002 (mult:SI (ashiftrt:SI
2003 (match_operand:SI 1 "s_register_operand" "r")
2006 (match_operand:HI 2 "s_register_operand" "r"))))]
2007 "TARGET_DSP_MULTIPLY"
2008 "smultb%?\\t%0, %1, %2"
2009 [(set_attr "type" "smulxy")
2010 (set_attr "predicable" "yes")
2011 (set_attr "predicable_short_it" "no")]
2014 (define_insn "*mulhisi3bt"
2015 [(set (match_operand:SI 0 "s_register_operand" "=r")
2016 (mult:SI (sign_extend:SI
2017 (match_operand:HI 1 "s_register_operand" "r"))
2019 (match_operand:SI 2 "s_register_operand" "r")
2021 "TARGET_DSP_MULTIPLY"
2022 "smulbt%?\\t%0, %1, %2"
2023 [(set_attr "type" "smulxy")
2024 (set_attr "predicable" "yes")
2025 (set_attr "predicable_short_it" "no")]
2028 (define_insn "*mulhisi3tt"
2029 [(set (match_operand:SI 0 "s_register_operand" "=r")
2030 (mult:SI (ashiftrt:SI
2031 (match_operand:SI 1 "s_register_operand" "r")
2034 (match_operand:SI 2 "s_register_operand" "r")
2036 "TARGET_DSP_MULTIPLY"
2037 "smultt%?\\t%0, %1, %2"
2038 [(set_attr "type" "smulxy")
2039 (set_attr "predicable" "yes")
2040 (set_attr "predicable_short_it" "no")]
2043 (define_insn "maddhisi4"
2044 [(set (match_operand:SI 0 "s_register_operand" "=r")
2045 (plus:SI (mult:SI (sign_extend:SI
2046 (match_operand:HI 1 "s_register_operand" "r"))
2048 (match_operand:HI 2 "s_register_operand" "r")))
2049 (match_operand:SI 3 "s_register_operand" "r")))]
2050 "TARGET_DSP_MULTIPLY"
2051 "smlabb%?\\t%0, %1, %2, %3"
2052 [(set_attr "type" "smlaxy")
2053 (set_attr "predicable" "yes")
2054 (set_attr "predicable_short_it" "no")]
2057 ;; Note: there is no maddhisi4ibt because this one is canonical form
2058 (define_insn "*maddhisi4tb"
2059 [(set (match_operand:SI 0 "s_register_operand" "=r")
2060 (plus:SI (mult:SI (ashiftrt:SI
2061 (match_operand:SI 1 "s_register_operand" "r")
2064 (match_operand:HI 2 "s_register_operand" "r")))
2065 (match_operand:SI 3 "s_register_operand" "r")))]
2066 "TARGET_DSP_MULTIPLY"
2067 "smlatb%?\\t%0, %1, %2, %3"
2068 [(set_attr "type" "smlaxy")
2069 (set_attr "predicable" "yes")
2070 (set_attr "predicable_short_it" "no")]
2073 (define_insn "*maddhisi4tt"
2074 [(set (match_operand:SI 0 "s_register_operand" "=r")
2075 (plus:SI (mult:SI (ashiftrt:SI
2076 (match_operand:SI 1 "s_register_operand" "r")
2079 (match_operand:SI 2 "s_register_operand" "r")
2081 (match_operand:SI 3 "s_register_operand" "r")))]
2082 "TARGET_DSP_MULTIPLY"
2083 "smlatt%?\\t%0, %1, %2, %3"
2084 [(set_attr "type" "smlaxy")
2085 (set_attr "predicable" "yes")
2086 (set_attr "predicable_short_it" "no")]
2089 (define_insn "maddhidi4"
2090 [(set (match_operand:DI 0 "s_register_operand" "=r")
2092 (mult:DI (sign_extend:DI
2093 (match_operand:HI 1 "s_register_operand" "r"))
2095 (match_operand:HI 2 "s_register_operand" "r")))
2096 (match_operand:DI 3 "s_register_operand" "0")))]
2097 "TARGET_DSP_MULTIPLY"
2098 "smlalbb%?\\t%Q0, %R0, %1, %2"
2099 [(set_attr "type" "smlalxy")
2100 (set_attr "predicable" "yes")
2101 (set_attr "predicable_short_it" "no")])
2103 ;; Note: there is no maddhidi4ibt because this one is canonical form
2104 (define_insn "*maddhidi4tb"
2105 [(set (match_operand:DI 0 "s_register_operand" "=r")
2107 (mult:DI (sign_extend:DI
2109 (match_operand:SI 1 "s_register_operand" "r")
2112 (match_operand:HI 2 "s_register_operand" "r")))
2113 (match_operand:DI 3 "s_register_operand" "0")))]
2114 "TARGET_DSP_MULTIPLY"
2115 "smlaltb%?\\t%Q0, %R0, %1, %2"
2116 [(set_attr "type" "smlalxy")
2117 (set_attr "predicable" "yes")
2118 (set_attr "predicable_short_it" "no")])
2120 (define_insn "*maddhidi4tt"
2121 [(set (match_operand:DI 0 "s_register_operand" "=r")
2123 (mult:DI (sign_extend:DI
2125 (match_operand:SI 1 "s_register_operand" "r")
2129 (match_operand:SI 2 "s_register_operand" "r")
2131 (match_operand:DI 3 "s_register_operand" "0")))]
2132 "TARGET_DSP_MULTIPLY"
2133 "smlaltt%?\\t%Q0, %R0, %1, %2"
2134 [(set_attr "type" "smlalxy")
2135 (set_attr "predicable" "yes")
2136 (set_attr "predicable_short_it" "no")])
2138 (define_expand "mulsf3"
2139 [(set (match_operand:SF 0 "s_register_operand" "")
2140 (mult:SF (match_operand:SF 1 "s_register_operand" "")
2141 (match_operand:SF 2 "s_register_operand" "")))]
2142 "TARGET_32BIT && TARGET_HARD_FLOAT"
2146 (define_expand "muldf3"
2147 [(set (match_operand:DF 0 "s_register_operand" "")
2148 (mult:DF (match_operand:DF 1 "s_register_operand" "")
2149 (match_operand:DF 2 "s_register_operand" "")))]
2150 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
2156 (define_expand "divsf3"
2157 [(set (match_operand:SF 0 "s_register_operand" "")
2158 (div:SF (match_operand:SF 1 "s_register_operand" "")
2159 (match_operand:SF 2 "s_register_operand" "")))]
2160 "TARGET_32BIT && TARGET_HARD_FLOAT"
2163 (define_expand "divdf3"
2164 [(set (match_operand:DF 0 "s_register_operand" "")
2165 (div:DF (match_operand:DF 1 "s_register_operand" "")
2166 (match_operand:DF 2 "s_register_operand" "")))]
2167 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
2170 ;; Boolean and,ior,xor insns
2172 ;; Split up double word logical operations
2174 ;; Split up simple DImode logical operations. Simply perform the logical
2175 ;; operation on the upper and lower halves of the registers.
2177 [(set (match_operand:DI 0 "s_register_operand" "")
2178 (match_operator:DI 6 "logical_binary_operator"
2179 [(match_operand:DI 1 "s_register_operand" "")
2180 (match_operand:DI 2 "s_register_operand" "")]))]
2181 "TARGET_32BIT && reload_completed
2182 && ! (TARGET_NEON && IS_VFP_REGNUM (REGNO (operands[0])))
2183 && ! IS_IWMMXT_REGNUM (REGNO (operands[0]))"
2184 [(set (match_dup 0) (match_op_dup:SI 6 [(match_dup 1) (match_dup 2)]))
2185 (set (match_dup 3) (match_op_dup:SI 6 [(match_dup 4) (match_dup 5)]))]
2188 operands[3] = gen_highpart (SImode, operands[0]);
2189 operands[0] = gen_lowpart (SImode, operands[0]);
2190 operands[4] = gen_highpart (SImode, operands[1]);
2191 operands[1] = gen_lowpart (SImode, operands[1]);
2192 operands[5] = gen_highpart (SImode, operands[2]);
2193 operands[2] = gen_lowpart (SImode, operands[2]);
2198 [(set (match_operand:DI 0 "s_register_operand" "")
2199 (match_operator:DI 6 "logical_binary_operator"
2200 [(sign_extend:DI (match_operand:SI 2 "s_register_operand" ""))
2201 (match_operand:DI 1 "s_register_operand" "")]))]
2202 "TARGET_32BIT && reload_completed"
2203 [(set (match_dup 0) (match_op_dup:SI 6 [(match_dup 1) (match_dup 2)]))
2204 (set (match_dup 3) (match_op_dup:SI 6
2205 [(ashiftrt:SI (match_dup 2) (const_int 31))
2209 operands[3] = gen_highpart (SImode, operands[0]);
2210 operands[0] = gen_lowpart (SImode, operands[0]);
2211 operands[4] = gen_highpart (SImode, operands[1]);
2212 operands[1] = gen_lowpart (SImode, operands[1]);
2213 operands[5] = gen_highpart (SImode, operands[2]);
2214 operands[2] = gen_lowpart (SImode, operands[2]);
2218 ;; The zero extend of operand 2 means we can just copy the high part of
2219 ;; operand1 into operand0.
2221 [(set (match_operand:DI 0 "s_register_operand" "")
2223 (zero_extend:DI (match_operand:SI 2 "s_register_operand" ""))
2224 (match_operand:DI 1 "s_register_operand" "")))]
2225 "TARGET_32BIT && operands[0] != operands[1] && reload_completed"
2226 [(set (match_dup 0) (ior:SI (match_dup 1) (match_dup 2)))
2227 (set (match_dup 3) (match_dup 4))]
2230 operands[4] = gen_highpart (SImode, operands[1]);
2231 operands[3] = gen_highpart (SImode, operands[0]);
2232 operands[0] = gen_lowpart (SImode, operands[0]);
2233 operands[1] = gen_lowpart (SImode, operands[1]);
2237 ;; The zero extend of operand 2 means we can just copy the high part of
2238 ;; operand1 into operand0.
2240 [(set (match_operand:DI 0 "s_register_operand" "")
2242 (zero_extend:DI (match_operand:SI 2 "s_register_operand" ""))
2243 (match_operand:DI 1 "s_register_operand" "")))]
2244 "TARGET_32BIT && operands[0] != operands[1] && reload_completed"
2245 [(set (match_dup 0) (xor:SI (match_dup 1) (match_dup 2)))
2246 (set (match_dup 3) (match_dup 4))]
2249 operands[4] = gen_highpart (SImode, operands[1]);
2250 operands[3] = gen_highpart (SImode, operands[0]);
2251 operands[0] = gen_lowpart (SImode, operands[0]);
2252 operands[1] = gen_lowpart (SImode, operands[1]);
2256 (define_expand "anddi3"
2257 [(set (match_operand:DI 0 "s_register_operand" "")
2258 (and:DI (match_operand:DI 1 "s_register_operand" "")
2259 (match_operand:DI 2 "neon_inv_logic_op2" "")))]
2264 (define_insn_and_split "*anddi3_insn"
2265 [(set (match_operand:DI 0 "s_register_operand" "=w,w ,&r,&r,&r,&r,?w,?w")
2266 (and:DI (match_operand:DI 1 "s_register_operand" "%w,0 ,0 ,r ,0 ,r ,w ,0")
2267 (match_operand:DI 2 "arm_anddi_operand_neon" "w ,DL,r ,r ,De,De,w ,DL")))]
2268 "TARGET_32BIT && !TARGET_IWMMXT"
2270 switch (which_alternative)
2272 case 0: /* fall through */
2273 case 6: return "vand\t%P0, %P1, %P2";
2274 case 1: /* fall through */
2275 case 7: return neon_output_logic_immediate ("vand", &operands[2],
2276 DImode, 1, VALID_NEON_QREG_MODE (DImode));
2280 case 5: /* fall through */
2282 default: gcc_unreachable ();
2285 "TARGET_32BIT && !TARGET_IWMMXT && reload_completed
2286 && !(IS_VFP_REGNUM (REGNO (operands[0])))"
2287 [(set (match_dup 3) (match_dup 4))
2288 (set (match_dup 5) (match_dup 6))]
2291 operands[3] = gen_lowpart (SImode, operands[0]);
2292 operands[5] = gen_highpart (SImode, operands[0]);
2294 operands[4] = simplify_gen_binary (AND, SImode,
2295 gen_lowpart (SImode, operands[1]),
2296 gen_lowpart (SImode, operands[2]));
2297 operands[6] = simplify_gen_binary (AND, SImode,
2298 gen_highpart (SImode, operands[1]),
2299 gen_highpart_mode (SImode, DImode, operands[2]));
2302 [(set_attr "type" "neon_logic,neon_logic,multiple,multiple,\
2303 multiple,multiple,neon_logic,neon_logic")
2304 (set_attr "arch" "neon_for_64bits,neon_for_64bits,*,*,*,*,
2305 avoid_neon_for_64bits,avoid_neon_for_64bits")
2306 (set_attr "length" "*,*,8,8,8,8,*,*")
2310 (define_insn_and_split "*anddi_zesidi_di"
2311 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2312 (and:DI (zero_extend:DI
2313 (match_operand:SI 2 "s_register_operand" "r,r"))
2314 (match_operand:DI 1 "s_register_operand" "0,r")))]
2317 "TARGET_32BIT && reload_completed"
2318 ; The zero extend of operand 2 clears the high word of the output
2320 [(set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))
2321 (set (match_dup 3) (const_int 0))]
2324 operands[3] = gen_highpart (SImode, operands[0]);
2325 operands[0] = gen_lowpart (SImode, operands[0]);
2326 operands[1] = gen_lowpart (SImode, operands[1]);
2328 [(set_attr "length" "8")
2329 (set_attr "type" "multiple")]
2332 (define_insn "*anddi_sesdi_di"
2333 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2334 (and:DI (sign_extend:DI
2335 (match_operand:SI 2 "s_register_operand" "r,r"))
2336 (match_operand:DI 1 "s_register_operand" "0,r")))]
2339 [(set_attr "length" "8")
2340 (set_attr "type" "multiple")]
2343 (define_expand "andsi3"
2344 [(set (match_operand:SI 0 "s_register_operand" "")
2345 (and:SI (match_operand:SI 1 "s_register_operand" "")
2346 (match_operand:SI 2 "reg_or_int_operand" "")))]
2351 if (CONST_INT_P (operands[2]))
2353 if (INTVAL (operands[2]) == 255 && arm_arch6)
2355 operands[1] = convert_to_mode (QImode, operands[1], 1);
2356 emit_insn (gen_thumb2_zero_extendqisi2_v6 (operands[0],
2360 else if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[2]), AND))
2361 operands[2] = force_reg (SImode, operands[2]);
2364 arm_split_constant (AND, SImode, NULL_RTX,
2365 INTVAL (operands[2]), operands[0],
2367 optimize && can_create_pseudo_p ());
2373 else /* TARGET_THUMB1 */
2375 if (!CONST_INT_P (operands[2]))
2377 rtx tmp = force_reg (SImode, operands[2]);
2378 if (rtx_equal_p (operands[0], operands[1]))
2382 operands[2] = operands[1];
2390 if (((unsigned HOST_WIDE_INT) ~INTVAL (operands[2])) < 256)
2392 operands[2] = force_reg (SImode,
2393 GEN_INT (~INTVAL (operands[2])));
2395 emit_insn (gen_thumb1_bicsi3 (operands[0], operands[2], operands[1]));
2400 for (i = 9; i <= 31; i++)
2402 if ((HOST_WIDE_INT_1 << i) - 1 == INTVAL (operands[2]))
2404 emit_insn (gen_extzv (operands[0], operands[1], GEN_INT (i),
2408 else if ((HOST_WIDE_INT_1 << i) - 1
2409 == ~INTVAL (operands[2]))
2411 rtx shift = GEN_INT (i);
2412 rtx reg = gen_reg_rtx (SImode);
2414 emit_insn (gen_lshrsi3 (reg, operands[1], shift));
2415 emit_insn (gen_ashlsi3 (operands[0], reg, shift));
2421 operands[2] = force_reg (SImode, operands[2]);
2427 ; ??? Check split length for Thumb-2
2428 (define_insn_and_split "*arm_andsi3_insn"
2429 [(set (match_operand:SI 0 "s_register_operand" "=r,l,r,r,r")
2430 (and:SI (match_operand:SI 1 "s_register_operand" "%r,0,r,r,r")
2431 (match_operand:SI 2 "reg_or_int_operand" "I,l,K,r,?n")))]
2436 bic%?\\t%0, %1, #%B2
2440 && CONST_INT_P (operands[2])
2441 && !(const_ok_for_arm (INTVAL (operands[2]))
2442 || const_ok_for_arm (~INTVAL (operands[2])))"
2443 [(clobber (const_int 0))]
2445 arm_split_constant (AND, SImode, curr_insn,
2446 INTVAL (operands[2]), operands[0], operands[1], 0);
2449 [(set_attr "length" "4,4,4,4,16")
2450 (set_attr "predicable" "yes")
2451 (set_attr "predicable_short_it" "no,yes,no,no,no")
2452 (set_attr "type" "logic_imm,logic_imm,logic_reg,logic_reg,logic_imm")]
2455 (define_insn "*andsi3_compare0"
2456 [(set (reg:CC_NOOV CC_REGNUM)
2458 (and:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
2459 (match_operand:SI 2 "arm_not_operand" "I,K,r"))
2461 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
2462 (and:SI (match_dup 1) (match_dup 2)))]
2466 bics%?\\t%0, %1, #%B2
2467 ands%?\\t%0, %1, %2"
2468 [(set_attr "conds" "set")
2469 (set_attr "type" "logics_imm,logics_imm,logics_reg")]
2472 (define_insn "*andsi3_compare0_scratch"
2473 [(set (reg:CC_NOOV CC_REGNUM)
2475 (and:SI (match_operand:SI 0 "s_register_operand" "r,r,r")
2476 (match_operand:SI 1 "arm_not_operand" "I,K,r"))
2478 (clobber (match_scratch:SI 2 "=X,r,X"))]
2482 bics%?\\t%2, %0, #%B1
2484 [(set_attr "conds" "set")
2485 (set_attr "type" "logics_imm,logics_imm,logics_reg")]
2488 (define_insn "*zeroextractsi_compare0_scratch"
2489 [(set (reg:CC_NOOV CC_REGNUM)
2490 (compare:CC_NOOV (zero_extract:SI
2491 (match_operand:SI 0 "s_register_operand" "r")
2492 (match_operand 1 "const_int_operand" "n")
2493 (match_operand 2 "const_int_operand" "n"))
2496 && (INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) < 32
2497 && INTVAL (operands[1]) > 0
2498 && INTVAL (operands[1]) + (INTVAL (operands[2]) & 1) <= 8
2499 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32)"
2501 operands[1] = GEN_INT (((1 << INTVAL (operands[1])) - 1)
2502 << INTVAL (operands[2]));
2503 output_asm_insn (\"tst%?\\t%0, %1\", operands);
2506 [(set_attr "conds" "set")
2507 (set_attr "predicable" "yes")
2508 (set_attr "predicable_short_it" "no")
2509 (set_attr "type" "logics_imm")]
2512 (define_insn_and_split "*ne_zeroextractsi"
2513 [(set (match_operand:SI 0 "s_register_operand" "=r")
2514 (ne:SI (zero_extract:SI
2515 (match_operand:SI 1 "s_register_operand" "r")
2516 (match_operand:SI 2 "const_int_operand" "n")
2517 (match_operand:SI 3 "const_int_operand" "n"))
2519 (clobber (reg:CC CC_REGNUM))]
2521 && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2522 && INTVAL (operands[2]) > 0
2523 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2524 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)"
2527 && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2528 && INTVAL (operands[2]) > 0
2529 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2530 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)"
2531 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2532 (compare:CC_NOOV (and:SI (match_dup 1) (match_dup 2))
2534 (set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))])
2536 (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2537 (match_dup 0) (const_int 1)))]
2539 operands[2] = GEN_INT (((1 << INTVAL (operands[2])) - 1)
2540 << INTVAL (operands[3]));
2542 [(set_attr "conds" "clob")
2543 (set (attr "length")
2544 (if_then_else (eq_attr "is_thumb" "yes")
2547 (set_attr "type" "multiple")]
2550 (define_insn_and_split "*ne_zeroextractsi_shifted"
2551 [(set (match_operand:SI 0 "s_register_operand" "=r")
2552 (ne:SI (zero_extract:SI
2553 (match_operand:SI 1 "s_register_operand" "r")
2554 (match_operand:SI 2 "const_int_operand" "n")
2557 (clobber (reg:CC CC_REGNUM))]
2561 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2562 (compare:CC_NOOV (ashift:SI (match_dup 1) (match_dup 2))
2564 (set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))])
2566 (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2567 (match_dup 0) (const_int 1)))]
2569 operands[2] = GEN_INT (32 - INTVAL (operands[2]));
2571 [(set_attr "conds" "clob")
2572 (set_attr "length" "8")
2573 (set_attr "type" "multiple")]
2576 (define_insn_and_split "*ite_ne_zeroextractsi"
2577 [(set (match_operand:SI 0 "s_register_operand" "=r")
2578 (if_then_else:SI (ne (zero_extract:SI
2579 (match_operand:SI 1 "s_register_operand" "r")
2580 (match_operand:SI 2 "const_int_operand" "n")
2581 (match_operand:SI 3 "const_int_operand" "n"))
2583 (match_operand:SI 4 "arm_not_operand" "rIK")
2585 (clobber (reg:CC CC_REGNUM))]
2587 && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2588 && INTVAL (operands[2]) > 0
2589 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2590 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)
2591 && !reg_overlap_mentioned_p (operands[0], operands[4])"
2594 && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2595 && INTVAL (operands[2]) > 0
2596 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2597 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)
2598 && !reg_overlap_mentioned_p (operands[0], operands[4])"
2599 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2600 (compare:CC_NOOV (and:SI (match_dup 1) (match_dup 2))
2602 (set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))])
2604 (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2605 (match_dup 0) (match_dup 4)))]
2607 operands[2] = GEN_INT (((1 << INTVAL (operands[2])) - 1)
2608 << INTVAL (operands[3]));
2610 [(set_attr "conds" "clob")
2611 (set_attr "length" "8")
2612 (set_attr "type" "multiple")]
2615 (define_insn_and_split "*ite_ne_zeroextractsi_shifted"
2616 [(set (match_operand:SI 0 "s_register_operand" "=r")
2617 (if_then_else:SI (ne (zero_extract:SI
2618 (match_operand:SI 1 "s_register_operand" "r")
2619 (match_operand:SI 2 "const_int_operand" "n")
2622 (match_operand:SI 3 "arm_not_operand" "rIK")
2624 (clobber (reg:CC CC_REGNUM))]
2625 "TARGET_ARM && !reg_overlap_mentioned_p (operands[0], operands[3])"
2627 "TARGET_ARM && !reg_overlap_mentioned_p (operands[0], operands[3])"
2628 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2629 (compare:CC_NOOV (ashift:SI (match_dup 1) (match_dup 2))
2631 (set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))])
2633 (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2634 (match_dup 0) (match_dup 3)))]
2636 operands[2] = GEN_INT (32 - INTVAL (operands[2]));
2638 [(set_attr "conds" "clob")
2639 (set_attr "length" "8")
2640 (set_attr "type" "multiple")]
2643 ;; ??? Use Thumb-2 has bitfield insert/extract instructions.
2645 [(set (match_operand:SI 0 "s_register_operand" "")
2646 (match_operator:SI 1 "shiftable_operator"
2647 [(zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
2648 (match_operand:SI 3 "const_int_operand" "")
2649 (match_operand:SI 4 "const_int_operand" ""))
2650 (match_operand:SI 5 "s_register_operand" "")]))
2651 (clobber (match_operand:SI 6 "s_register_operand" ""))]
2653 [(set (match_dup 6) (ashift:SI (match_dup 2) (match_dup 3)))
2656 [(lshiftrt:SI (match_dup 6) (match_dup 4))
2659 HOST_WIDE_INT temp = INTVAL (operands[3]);
2661 operands[3] = GEN_INT (32 - temp - INTVAL (operands[4]));
2662 operands[4] = GEN_INT (32 - temp);
2667 [(set (match_operand:SI 0 "s_register_operand" "")
2668 (match_operator:SI 1 "shiftable_operator"
2669 [(sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
2670 (match_operand:SI 3 "const_int_operand" "")
2671 (match_operand:SI 4 "const_int_operand" ""))
2672 (match_operand:SI 5 "s_register_operand" "")]))
2673 (clobber (match_operand:SI 6 "s_register_operand" ""))]
2675 [(set (match_dup 6) (ashift:SI (match_dup 2) (match_dup 3)))
2678 [(ashiftrt:SI (match_dup 6) (match_dup 4))
2681 HOST_WIDE_INT temp = INTVAL (operands[3]);
2683 operands[3] = GEN_INT (32 - temp - INTVAL (operands[4]));
2684 operands[4] = GEN_INT (32 - temp);
2688 ;;; ??? This pattern is bogus. If operand3 has bits outside the range
2689 ;;; represented by the bitfield, then this will produce incorrect results.
2690 ;;; Somewhere, the value needs to be truncated. On targets like the m68k,
2691 ;;; which have a real bit-field insert instruction, the truncation happens
2692 ;;; in the bit-field insert instruction itself. Since arm does not have a
2693 ;;; bit-field insert instruction, we would have to emit code here to truncate
2694 ;;; the value before we insert. This loses some of the advantage of having
2695 ;;; this insv pattern, so this pattern needs to be reevalutated.
2697 (define_expand "insv"
2698 [(set (zero_extract (match_operand 0 "nonimmediate_operand" "")
2699 (match_operand 1 "general_operand" "")
2700 (match_operand 2 "general_operand" ""))
2701 (match_operand 3 "reg_or_int_operand" ""))]
2702 "TARGET_ARM || arm_arch_thumb2"
2705 int start_bit = INTVAL (operands[2]);
2706 int width = INTVAL (operands[1]);
2707 HOST_WIDE_INT mask = (HOST_WIDE_INT_1 << width) - 1;
2708 rtx target, subtarget;
2710 if (arm_arch_thumb2)
2712 if (unaligned_access && MEM_P (operands[0])
2713 && s_register_operand (operands[3], GET_MODE (operands[3]))
2714 && (width == 16 || width == 32) && (start_bit % BITS_PER_UNIT) == 0)
2718 if (BYTES_BIG_ENDIAN)
2719 start_bit = GET_MODE_BITSIZE (GET_MODE (operands[3])) - width
2724 base_addr = adjust_address (operands[0], SImode,
2725 start_bit / BITS_PER_UNIT);
2726 emit_insn (gen_unaligned_storesi (base_addr, operands[3]));
2730 rtx tmp = gen_reg_rtx (HImode);
2732 base_addr = adjust_address (operands[0], HImode,
2733 start_bit / BITS_PER_UNIT);
2734 emit_move_insn (tmp, gen_lowpart (HImode, operands[3]));
2735 emit_insn (gen_unaligned_storehi (base_addr, tmp));
2739 else if (s_register_operand (operands[0], GET_MODE (operands[0])))
2741 bool use_bfi = TRUE;
2743 if (CONST_INT_P (operands[3]))
2745 HOST_WIDE_INT val = INTVAL (operands[3]) & mask;
2749 emit_insn (gen_insv_zero (operands[0], operands[1],
2754 /* See if the set can be done with a single orr instruction. */
2755 if (val == mask && const_ok_for_arm (val << start_bit))
2761 if (!REG_P (operands[3]))
2762 operands[3] = force_reg (SImode, operands[3]);
2764 emit_insn (gen_insv_t2 (operands[0], operands[1], operands[2],
2773 if (!s_register_operand (operands[0], GET_MODE (operands[0])))
2776 target = copy_rtx (operands[0]);
2777 /* Avoid using a subreg as a subtarget, and avoid writing a paradoxical
2778 subreg as the final target. */
2779 if (GET_CODE (target) == SUBREG)
2781 subtarget = gen_reg_rtx (SImode);
2782 if (GET_MODE_SIZE (GET_MODE (SUBREG_REG (target)))
2783 < GET_MODE_SIZE (SImode))
2784 target = SUBREG_REG (target);
2789 if (CONST_INT_P (operands[3]))
2791 /* Since we are inserting a known constant, we may be able to
2792 reduce the number of bits that we have to clear so that
2793 the mask becomes simple. */
2794 /* ??? This code does not check to see if the new mask is actually
2795 simpler. It may not be. */
2796 rtx op1 = gen_reg_rtx (SImode);
2797 /* ??? Truncate operand3 to fit in the bitfield. See comment before
2798 start of this pattern. */
2799 HOST_WIDE_INT op3_value = mask & INTVAL (operands[3]);
2800 HOST_WIDE_INT mask2 = ((mask & ~op3_value) << start_bit);
2802 emit_insn (gen_andsi3 (op1, operands[0],
2803 gen_int_mode (~mask2, SImode)));
2804 emit_insn (gen_iorsi3 (subtarget, op1,
2805 gen_int_mode (op3_value << start_bit, SImode)));
2807 else if (start_bit == 0
2808 && !(const_ok_for_arm (mask)
2809 || const_ok_for_arm (~mask)))
2811 /* A Trick, since we are setting the bottom bits in the word,
2812 we can shift operand[3] up, operand[0] down, OR them together
2813 and rotate the result back again. This takes 3 insns, and
2814 the third might be mergeable into another op. */
2815 /* The shift up copes with the possibility that operand[3] is
2816 wider than the bitfield. */
2817 rtx op0 = gen_reg_rtx (SImode);
2818 rtx op1 = gen_reg_rtx (SImode);
2820 emit_insn (gen_ashlsi3 (op0, operands[3], GEN_INT (32 - width)));
2821 emit_insn (gen_lshrsi3 (op1, operands[0], operands[1]));
2822 emit_insn (gen_iorsi3 (op1, op1, op0));
2823 emit_insn (gen_rotlsi3 (subtarget, op1, operands[1]));
2825 else if ((width + start_bit == 32)
2826 && !(const_ok_for_arm (mask)
2827 || const_ok_for_arm (~mask)))
2829 /* Similar trick, but slightly less efficient. */
2831 rtx op0 = gen_reg_rtx (SImode);
2832 rtx op1 = gen_reg_rtx (SImode);
2834 emit_insn (gen_ashlsi3 (op0, operands[3], GEN_INT (32 - width)));
2835 emit_insn (gen_ashlsi3 (op1, operands[0], operands[1]));
2836 emit_insn (gen_lshrsi3 (op1, op1, operands[1]));
2837 emit_insn (gen_iorsi3 (subtarget, op1, op0));
2841 rtx op0 = gen_int_mode (mask, SImode);
2842 rtx op1 = gen_reg_rtx (SImode);
2843 rtx op2 = gen_reg_rtx (SImode);
2845 if (!(const_ok_for_arm (mask) || const_ok_for_arm (~mask)))
2847 rtx tmp = gen_reg_rtx (SImode);
2849 emit_insn (gen_movsi (tmp, op0));
2853 /* Mask out any bits in operand[3] that are not needed. */
2854 emit_insn (gen_andsi3 (op1, operands[3], op0));
2856 if (CONST_INT_P (op0)
2857 && (const_ok_for_arm (mask << start_bit)
2858 || const_ok_for_arm (~(mask << start_bit))))
2860 op0 = gen_int_mode (~(mask << start_bit), SImode);
2861 emit_insn (gen_andsi3 (op2, operands[0], op0));
2865 if (CONST_INT_P (op0))
2867 rtx tmp = gen_reg_rtx (SImode);
2869 emit_insn (gen_movsi (tmp, op0));
2874 emit_insn (gen_ashlsi3 (op0, op0, operands[2]));
2876 emit_insn (gen_andsi_notsi_si (op2, operands[0], op0));
2880 emit_insn (gen_ashlsi3 (op1, op1, operands[2]));
2882 emit_insn (gen_iorsi3 (subtarget, op1, op2));
2885 if (subtarget != target)
2887 /* If TARGET is still a SUBREG, then it must be wider than a word,
2888 so we must be careful only to set the subword we were asked to. */
2889 if (GET_CODE (target) == SUBREG)
2890 emit_move_insn (target, subtarget);
2892 emit_move_insn (target, gen_lowpart (GET_MODE (target), subtarget));
2899 (define_insn "insv_zero"
2900 [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r")
2901 (match_operand:SI 1 "const_int_M_operand" "M")
2902 (match_operand:SI 2 "const_int_M_operand" "M"))
2906 [(set_attr "length" "4")
2907 (set_attr "predicable" "yes")
2908 (set_attr "predicable_short_it" "no")
2909 (set_attr "type" "bfm")]
2912 (define_insn "insv_t2"
2913 [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r")
2914 (match_operand:SI 1 "const_int_M_operand" "M")
2915 (match_operand:SI 2 "const_int_M_operand" "M"))
2916 (match_operand:SI 3 "s_register_operand" "r"))]
2918 "bfi%?\t%0, %3, %2, %1"
2919 [(set_attr "length" "4")
2920 (set_attr "predicable" "yes")
2921 (set_attr "predicable_short_it" "no")
2922 (set_attr "type" "bfm")]
2925 ; constants for op 2 will never be given to these patterns.
2926 (define_insn_and_split "*anddi_notdi_di"
2927 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2928 (and:DI (not:DI (match_operand:DI 1 "s_register_operand" "0,r"))
2929 (match_operand:DI 2 "s_register_operand" "r,0")))]
2932 "TARGET_32BIT && reload_completed
2933 && ! (TARGET_NEON && IS_VFP_REGNUM (REGNO (operands[0])))
2934 && ! IS_IWMMXT_REGNUM (REGNO (operands[0]))"
2935 [(set (match_dup 0) (and:SI (not:SI (match_dup 1)) (match_dup 2)))
2936 (set (match_dup 3) (and:SI (not:SI (match_dup 4)) (match_dup 5)))]
2939 operands[3] = gen_highpart (SImode, operands[0]);
2940 operands[0] = gen_lowpart (SImode, operands[0]);
2941 operands[4] = gen_highpart (SImode, operands[1]);
2942 operands[1] = gen_lowpart (SImode, operands[1]);
2943 operands[5] = gen_highpart (SImode, operands[2]);
2944 operands[2] = gen_lowpart (SImode, operands[2]);
2946 [(set_attr "length" "8")
2947 (set_attr "predicable" "yes")
2948 (set_attr "type" "multiple")]
2951 (define_insn_and_split "*anddi_notzesidi_di"
2952 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2953 (and:DI (not:DI (zero_extend:DI
2954 (match_operand:SI 2 "s_register_operand" "r,r")))
2955 (match_operand:DI 1 "s_register_operand" "0,?r")))]
2958 bic%?\\t%Q0, %Q1, %2
2960 ; (not (zero_extend ...)) allows us to just copy the high word from
2961 ; operand1 to operand0.
2964 && operands[0] != operands[1]"
2965 [(set (match_dup 0) (and:SI (not:SI (match_dup 2)) (match_dup 1)))
2966 (set (match_dup 3) (match_dup 4))]
2969 operands[3] = gen_highpart (SImode, operands[0]);
2970 operands[0] = gen_lowpart (SImode, operands[0]);
2971 operands[4] = gen_highpart (SImode, operands[1]);
2972 operands[1] = gen_lowpart (SImode, operands[1]);
2974 [(set_attr "length" "4,8")
2975 (set_attr "predicable" "yes")
2976 (set_attr "predicable_short_it" "no")
2977 (set_attr "type" "multiple")]
2980 (define_insn_and_split "*anddi_notdi_zesidi"
2981 [(set (match_operand:DI 0 "s_register_operand" "=r")
2982 (and:DI (not:DI (match_operand:DI 2 "s_register_operand" "r"))
2984 (match_operand:SI 1 "s_register_operand" "r"))))]
2987 "TARGET_32BIT && reload_completed"
2988 [(set (match_dup 0) (and:SI (not:SI (match_dup 2)) (match_dup 1)))
2989 (set (match_dup 3) (const_int 0))]
2992 operands[3] = gen_highpart (SImode, operands[0]);
2993 operands[0] = gen_lowpart (SImode, operands[0]);
2994 operands[2] = gen_lowpart (SImode, operands[2]);
2996 [(set_attr "length" "8")
2997 (set_attr "predicable" "yes")
2998 (set_attr "predicable_short_it" "no")
2999 (set_attr "type" "multiple")]
3002 (define_insn_and_split "*anddi_notsesidi_di"
3003 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
3004 (and:DI (not:DI (sign_extend:DI
3005 (match_operand:SI 2 "s_register_operand" "r,r")))
3006 (match_operand:DI 1 "s_register_operand" "0,r")))]
3009 "TARGET_32BIT && reload_completed"
3010 [(set (match_dup 0) (and:SI (not:SI (match_dup 2)) (match_dup 1)))
3011 (set (match_dup 3) (and:SI (not:SI
3012 (ashiftrt:SI (match_dup 2) (const_int 31)))
3016 operands[3] = gen_highpart (SImode, operands[0]);
3017 operands[0] = gen_lowpart (SImode, operands[0]);
3018 operands[4] = gen_highpart (SImode, operands[1]);
3019 operands[1] = gen_lowpart (SImode, operands[1]);
3021 [(set_attr "length" "8")
3022 (set_attr "predicable" "yes")
3023 (set_attr "predicable_short_it" "no")
3024 (set_attr "type" "multiple")]
3027 (define_insn "andsi_notsi_si"
3028 [(set (match_operand:SI 0 "s_register_operand" "=r")
3029 (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
3030 (match_operand:SI 1 "s_register_operand" "r")))]
3032 "bic%?\\t%0, %1, %2"
3033 [(set_attr "predicable" "yes")
3034 (set_attr "predicable_short_it" "no")
3035 (set_attr "type" "logic_reg")]
3038 (define_insn "andsi_not_shiftsi_si"
3039 [(set (match_operand:SI 0 "s_register_operand" "=r")
3040 (and:SI (not:SI (match_operator:SI 4 "shift_operator"
3041 [(match_operand:SI 2 "s_register_operand" "r")
3042 (match_operand:SI 3 "arm_rhs_operand" "rM")]))
3043 (match_operand:SI 1 "s_register_operand" "r")))]
3045 "bic%?\\t%0, %1, %2%S4"
3046 [(set_attr "predicable" "yes")
3047 (set_attr "shift" "2")
3048 (set (attr "type") (if_then_else (match_operand 3 "const_int_operand" "")
3049 (const_string "logic_shift_imm")
3050 (const_string "logic_shift_reg")))]
3053 ;; Shifted bics pattern used to set up CC status register and not reusing
3054 ;; bics output. Pattern restricts Thumb2 shift operand as bics for Thumb2
3055 ;; does not support shift by register.
3056 (define_insn "andsi_not_shiftsi_si_scc_no_reuse"
3057 [(set (reg:CC_NOOV CC_REGNUM)
3059 (and:SI (not:SI (match_operator:SI 0 "shift_operator"
3060 [(match_operand:SI 1 "s_register_operand" "r")
3061 (match_operand:SI 2 "arm_rhs_operand" "rM")]))
3062 (match_operand:SI 3 "s_register_operand" "r"))
3064 (clobber (match_scratch:SI 4 "=r"))]
3065 "TARGET_ARM || (TARGET_THUMB2 && CONST_INT_P (operands[2]))"
3066 "bics%?\\t%4, %3, %1%S0"
3067 [(set_attr "predicable" "yes")
3068 (set_attr "predicable_short_it" "no")
3069 (set_attr "conds" "set")
3070 (set_attr "shift" "1")
3071 (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
3072 (const_string "logic_shift_imm")
3073 (const_string "logic_shift_reg")))]
3076 ;; Same as andsi_not_shiftsi_si_scc_no_reuse, but the bics result is also
3077 ;; getting reused later.
3078 (define_insn "andsi_not_shiftsi_si_scc"
3079 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
3081 (and:SI (not:SI (match_operator:SI 0 "shift_operator"
3082 [(match_operand:SI 1 "s_register_operand" "r")
3083 (match_operand:SI 2 "arm_rhs_operand" "rM")]))
3084 (match_operand:SI 3 "s_register_operand" "r"))
3086 (set (match_operand:SI 4 "s_register_operand" "=r")
3087 (and:SI (not:SI (match_op_dup 0
3091 "TARGET_ARM || (TARGET_THUMB2 && CONST_INT_P (operands[2]))"
3092 "bics%?\\t%4, %3, %1%S0"
3093 [(set_attr "predicable" "yes")
3094 (set_attr "predicable_short_it" "no")
3095 (set_attr "conds" "set")
3096 (set_attr "shift" "1")
3097 (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
3098 (const_string "logic_shift_imm")
3099 (const_string "logic_shift_reg")))]
3102 (define_insn "*andsi_notsi_si_compare0"
3103 [(set (reg:CC_NOOV CC_REGNUM)
3105 (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
3106 (match_operand:SI 1 "s_register_operand" "r"))
3108 (set (match_operand:SI 0 "s_register_operand" "=r")
3109 (and:SI (not:SI (match_dup 2)) (match_dup 1)))]
3112 [(set_attr "conds" "set")
3113 (set_attr "type" "logics_shift_reg")]
3116 (define_insn "*andsi_notsi_si_compare0_scratch"
3117 [(set (reg:CC_NOOV CC_REGNUM)
3119 (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
3120 (match_operand:SI 1 "s_register_operand" "r"))
3122 (clobber (match_scratch:SI 0 "=r"))]
3125 [(set_attr "conds" "set")
3126 (set_attr "type" "logics_shift_reg")]
3129 (define_expand "iordi3"
3130 [(set (match_operand:DI 0 "s_register_operand" "")
3131 (ior:DI (match_operand:DI 1 "s_register_operand" "")
3132 (match_operand:DI 2 "neon_logic_op2" "")))]
3137 (define_insn_and_split "*iordi3_insn"
3138 [(set (match_operand:DI 0 "s_register_operand" "=w,w ,&r,&r,&r,&r,?w,?w")
3139 (ior:DI (match_operand:DI 1 "s_register_operand" "%w,0 ,0 ,r ,0 ,r ,w ,0")
3140 (match_operand:DI 2 "arm_iordi_operand_neon" "w ,Dl,r ,r ,Df,Df,w ,Dl")))]
3141 "TARGET_32BIT && !TARGET_IWMMXT"
3143 switch (which_alternative)
3145 case 0: /* fall through */
3146 case 6: return "vorr\t%P0, %P1, %P2";
3147 case 1: /* fall through */
3148 case 7: return neon_output_logic_immediate ("vorr", &operands[2],
3149 DImode, 0, VALID_NEON_QREG_MODE (DImode));
3155 default: gcc_unreachable ();
3158 "TARGET_32BIT && !TARGET_IWMMXT && reload_completed
3159 && !(IS_VFP_REGNUM (REGNO (operands[0])))"
3160 [(set (match_dup 3) (match_dup 4))
3161 (set (match_dup 5) (match_dup 6))]
3164 operands[3] = gen_lowpart (SImode, operands[0]);
3165 operands[5] = gen_highpart (SImode, operands[0]);
3167 operands[4] = simplify_gen_binary (IOR, SImode,
3168 gen_lowpart (SImode, operands[1]),
3169 gen_lowpart (SImode, operands[2]));
3170 operands[6] = simplify_gen_binary (IOR, SImode,
3171 gen_highpart (SImode, operands[1]),
3172 gen_highpart_mode (SImode, DImode, operands[2]));
3175 [(set_attr "type" "neon_logic,neon_logic,multiple,multiple,multiple,\
3176 multiple,neon_logic,neon_logic")
3177 (set_attr "length" "*,*,8,8,8,8,*,*")
3178 (set_attr "arch" "neon_for_64bits,neon_for_64bits,*,*,*,*,avoid_neon_for_64bits,avoid_neon_for_64bits")]
3181 (define_insn "*iordi_zesidi_di"
3182 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
3183 (ior:DI (zero_extend:DI
3184 (match_operand:SI 2 "s_register_operand" "r,r"))
3185 (match_operand:DI 1 "s_register_operand" "0,?r")))]
3188 orr%?\\t%Q0, %Q1, %2
3190 [(set_attr "length" "4,8")
3191 (set_attr "predicable" "yes")
3192 (set_attr "predicable_short_it" "no")
3193 (set_attr "type" "logic_reg,multiple")]
3196 (define_insn "*iordi_sesidi_di"
3197 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
3198 (ior:DI (sign_extend:DI
3199 (match_operand:SI 2 "s_register_operand" "r,r"))
3200 (match_operand:DI 1 "s_register_operand" "0,r")))]
3203 [(set_attr "length" "8")
3204 (set_attr "predicable" "yes")
3205 (set_attr "type" "multiple")]
3208 (define_expand "iorsi3"
3209 [(set (match_operand:SI 0 "s_register_operand" "")
3210 (ior:SI (match_operand:SI 1 "s_register_operand" "")
3211 (match_operand:SI 2 "reg_or_int_operand" "")))]
3214 if (CONST_INT_P (operands[2]))
3218 if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[2]), IOR))
3219 operands[2] = force_reg (SImode, operands[2]);
3222 arm_split_constant (IOR, SImode, NULL_RTX,
3223 INTVAL (operands[2]), operands[0],
3225 optimize && can_create_pseudo_p ());
3229 else /* TARGET_THUMB1 */
3231 rtx tmp = force_reg (SImode, operands[2]);
3232 if (rtx_equal_p (operands[0], operands[1]))
3236 operands[2] = operands[1];
3244 (define_insn_and_split "*iorsi3_insn"
3245 [(set (match_operand:SI 0 "s_register_operand" "=r,l,r,r,r")
3246 (ior:SI (match_operand:SI 1 "s_register_operand" "%r,0,r,r,r")
3247 (match_operand:SI 2 "reg_or_int_operand" "I,l,K,r,?n")))]
3252 orn%?\\t%0, %1, #%B2
3256 && CONST_INT_P (operands[2])
3257 && !(const_ok_for_arm (INTVAL (operands[2]))
3258 || (TARGET_THUMB2 && const_ok_for_arm (~INTVAL (operands[2]))))"
3259 [(clobber (const_int 0))]
3261 arm_split_constant (IOR, SImode, curr_insn,
3262 INTVAL (operands[2]), operands[0], operands[1], 0);
3265 [(set_attr "length" "4,4,4,4,16")
3266 (set_attr "arch" "32,t2,t2,32,32")
3267 (set_attr "predicable" "yes")
3268 (set_attr "predicable_short_it" "no,yes,no,no,no")
3269 (set_attr "type" "logic_imm,logic_reg,logic_imm,logic_reg,logic_reg")]
3273 [(match_scratch:SI 3 "r")
3274 (set (match_operand:SI 0 "arm_general_register_operand" "")
3275 (ior:SI (match_operand:SI 1 "arm_general_register_operand" "")
3276 (match_operand:SI 2 "const_int_operand" "")))]
3278 && !const_ok_for_arm (INTVAL (operands[2]))
3279 && const_ok_for_arm (~INTVAL (operands[2]))"
3280 [(set (match_dup 3) (match_dup 2))
3281 (set (match_dup 0) (ior:SI (match_dup 1) (match_dup 3)))]
3285 (define_insn "*iorsi3_compare0"
3286 [(set (reg:CC_NOOV CC_REGNUM)
3287 (compare:CC_NOOV (ior:SI (match_operand:SI 1 "s_register_operand" "%r,r")
3288 (match_operand:SI 2 "arm_rhs_operand" "I,r"))
3290 (set (match_operand:SI 0 "s_register_operand" "=r,r")
3291 (ior:SI (match_dup 1) (match_dup 2)))]
3293 "orrs%?\\t%0, %1, %2"
3294 [(set_attr "conds" "set")
3295 (set_attr "type" "logics_imm,logics_reg")]
3298 (define_insn "*iorsi3_compare0_scratch"
3299 [(set (reg:CC_NOOV CC_REGNUM)
3300 (compare:CC_NOOV (ior:SI (match_operand:SI 1 "s_register_operand" "%r,r")
3301 (match_operand:SI 2 "arm_rhs_operand" "I,r"))
3303 (clobber (match_scratch:SI 0 "=r,r"))]
3305 "orrs%?\\t%0, %1, %2"
3306 [(set_attr "conds" "set")
3307 (set_attr "type" "logics_imm,logics_reg")]
3310 (define_expand "xordi3"
3311 [(set (match_operand:DI 0 "s_register_operand" "")
3312 (xor:DI (match_operand:DI 1 "s_register_operand" "")
3313 (match_operand:DI 2 "arm_xordi_operand" "")))]
3318 (define_insn_and_split "*xordi3_insn"
3319 [(set (match_operand:DI 0 "s_register_operand" "=w,&r,&r,&r,&r,?w")
3320 (xor:DI (match_operand:DI 1 "s_register_operand" "%w ,0,r ,0 ,r ,w")
3321 (match_operand:DI 2 "arm_xordi_operand" "w ,r ,r ,Dg,Dg,w")))]
3322 "TARGET_32BIT && !TARGET_IWMMXT"
3324 switch (which_alternative)
3329 case 4: /* fall through */
3331 case 0: /* fall through */
3332 case 5: return "veor\t%P0, %P1, %P2";
3333 default: gcc_unreachable ();
3336 "TARGET_32BIT && !TARGET_IWMMXT && reload_completed
3337 && !(IS_VFP_REGNUM (REGNO (operands[0])))"
3338 [(set (match_dup 3) (match_dup 4))
3339 (set (match_dup 5) (match_dup 6))]
3342 operands[3] = gen_lowpart (SImode, operands[0]);
3343 operands[5] = gen_highpart (SImode, operands[0]);
3345 operands[4] = simplify_gen_binary (XOR, SImode,
3346 gen_lowpart (SImode, operands[1]),
3347 gen_lowpart (SImode, operands[2]));
3348 operands[6] = simplify_gen_binary (XOR, SImode,
3349 gen_highpart (SImode, operands[1]),
3350 gen_highpart_mode (SImode, DImode, operands[2]));
3353 [(set_attr "length" "*,8,8,8,8,*")
3354 (set_attr "type" "neon_logic,multiple,multiple,multiple,multiple,neon_logic")
3355 (set_attr "arch" "neon_for_64bits,*,*,*,*,avoid_neon_for_64bits")]
3358 (define_insn "*xordi_zesidi_di"
3359 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
3360 (xor:DI (zero_extend:DI
3361 (match_operand:SI 2 "s_register_operand" "r,r"))
3362 (match_operand:DI 1 "s_register_operand" "0,?r")))]
3365 eor%?\\t%Q0, %Q1, %2
3367 [(set_attr "length" "4,8")
3368 (set_attr "predicable" "yes")
3369 (set_attr "predicable_short_it" "no")
3370 (set_attr "type" "logic_reg")]
3373 (define_insn "*xordi_sesidi_di"
3374 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
3375 (xor:DI (sign_extend:DI
3376 (match_operand:SI 2 "s_register_operand" "r,r"))
3377 (match_operand:DI 1 "s_register_operand" "0,r")))]
3380 [(set_attr "length" "8")
3381 (set_attr "predicable" "yes")
3382 (set_attr "type" "multiple")]
3385 (define_expand "xorsi3"
3386 [(set (match_operand:SI 0 "s_register_operand" "")
3387 (xor:SI (match_operand:SI 1 "s_register_operand" "")
3388 (match_operand:SI 2 "reg_or_int_operand" "")))]
3390 "if (CONST_INT_P (operands[2]))
3394 if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[2]), XOR))
3395 operands[2] = force_reg (SImode, operands[2]);
3398 arm_split_constant (XOR, SImode, NULL_RTX,
3399 INTVAL (operands[2]), operands[0],
3401 optimize && can_create_pseudo_p ());
3405 else /* TARGET_THUMB1 */
3407 rtx tmp = force_reg (SImode, operands[2]);
3408 if (rtx_equal_p (operands[0], operands[1]))
3412 operands[2] = operands[1];
3419 (define_insn_and_split "*arm_xorsi3"
3420 [(set (match_operand:SI 0 "s_register_operand" "=r,l,r,r")
3421 (xor:SI (match_operand:SI 1 "s_register_operand" "%r,0,r,r")
3422 (match_operand:SI 2 "reg_or_int_operand" "I,l,r,?n")))]
3430 && CONST_INT_P (operands[2])
3431 && !const_ok_for_arm (INTVAL (operands[2]))"
3432 [(clobber (const_int 0))]
3434 arm_split_constant (XOR, SImode, curr_insn,
3435 INTVAL (operands[2]), operands[0], operands[1], 0);
3438 [(set_attr "length" "4,4,4,16")
3439 (set_attr "predicable" "yes")
3440 (set_attr "predicable_short_it" "no,yes,no,no")
3441 (set_attr "type" "logic_imm,logic_reg,logic_reg,multiple")]
3444 (define_insn "*xorsi3_compare0"
3445 [(set (reg:CC_NOOV CC_REGNUM)
3446 (compare:CC_NOOV (xor:SI (match_operand:SI 1 "s_register_operand" "r,r")
3447 (match_operand:SI 2 "arm_rhs_operand" "I,r"))
3449 (set (match_operand:SI 0 "s_register_operand" "=r,r")
3450 (xor:SI (match_dup 1) (match_dup 2)))]
3452 "eors%?\\t%0, %1, %2"
3453 [(set_attr "conds" "set")
3454 (set_attr "type" "logics_imm,logics_reg")]
3457 (define_insn "*xorsi3_compare0_scratch"
3458 [(set (reg:CC_NOOV CC_REGNUM)
3459 (compare:CC_NOOV (xor:SI (match_operand:SI 0 "s_register_operand" "r,r")
3460 (match_operand:SI 1 "arm_rhs_operand" "I,r"))
3464 [(set_attr "conds" "set")
3465 (set_attr "type" "logics_imm,logics_reg")]
3468 ; By splitting (IOR (AND (NOT A) (NOT B)) C) as D = AND (IOR A B) (NOT C),
3469 ; (NOT D) we can sometimes merge the final NOT into one of the following
3473 [(set (match_operand:SI 0 "s_register_operand" "")
3474 (ior:SI (and:SI (not:SI (match_operand:SI 1 "s_register_operand" ""))
3475 (not:SI (match_operand:SI 2 "arm_rhs_operand" "")))
3476 (match_operand:SI 3 "arm_rhs_operand" "")))
3477 (clobber (match_operand:SI 4 "s_register_operand" ""))]
3479 [(set (match_dup 4) (and:SI (ior:SI (match_dup 1) (match_dup 2))
3480 (not:SI (match_dup 3))))
3481 (set (match_dup 0) (not:SI (match_dup 4)))]
3485 (define_insn_and_split "*andsi_iorsi3_notsi"
3486 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r")
3487 (and:SI (ior:SI (match_operand:SI 1 "s_register_operand" "%0,r,r")
3488 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI"))
3489 (not:SI (match_operand:SI 3 "arm_rhs_operand" "rI,rI,rI"))))]
3491 "#" ; "orr%?\\t%0, %1, %2\;bic%?\\t%0, %0, %3"
3492 "&& reload_completed"
3493 [(set (match_dup 0) (ior:SI (match_dup 1) (match_dup 2)))
3494 (set (match_dup 0) (and:SI (match_dup 4) (match_dup 5)))]
3496 /* If operands[3] is a constant make sure to fold the NOT into it
3497 to avoid creating a NOT of a CONST_INT. */
3498 rtx not_rtx = simplify_gen_unary (NOT, SImode, operands[3], SImode);
3499 if (CONST_INT_P (not_rtx))
3501 operands[4] = operands[0];
3502 operands[5] = not_rtx;
3506 operands[5] = operands[0];
3507 operands[4] = not_rtx;
3510 [(set_attr "length" "8")
3511 (set_attr "ce_count" "2")
3512 (set_attr "predicable" "yes")
3513 (set_attr "predicable_short_it" "no")
3514 (set_attr "type" "multiple")]
3517 ; ??? Are these four splitters still beneficial when the Thumb-2 bitfield
3518 ; insns are available?
3520 [(set (match_operand:SI 0 "s_register_operand" "")
3521 (match_operator:SI 1 "logical_binary_operator"
3522 [(zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
3523 (match_operand:SI 3 "const_int_operand" "")
3524 (match_operand:SI 4 "const_int_operand" ""))
3525 (match_operator:SI 9 "logical_binary_operator"
3526 [(lshiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3527 (match_operand:SI 6 "const_int_operand" ""))
3528 (match_operand:SI 7 "s_register_operand" "")])]))
3529 (clobber (match_operand:SI 8 "s_register_operand" ""))]
3531 && GET_CODE (operands[1]) == GET_CODE (operands[9])
3532 && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3535 [(ashift:SI (match_dup 2) (match_dup 4))
3539 [(lshiftrt:SI (match_dup 8) (match_dup 6))
3542 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3546 [(set (match_operand:SI 0 "s_register_operand" "")
3547 (match_operator:SI 1 "logical_binary_operator"
3548 [(match_operator:SI 9 "logical_binary_operator"
3549 [(lshiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3550 (match_operand:SI 6 "const_int_operand" ""))
3551 (match_operand:SI 7 "s_register_operand" "")])
3552 (zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
3553 (match_operand:SI 3 "const_int_operand" "")
3554 (match_operand:SI 4 "const_int_operand" ""))]))
3555 (clobber (match_operand:SI 8 "s_register_operand" ""))]
3557 && GET_CODE (operands[1]) == GET_CODE (operands[9])
3558 && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3561 [(ashift:SI (match_dup 2) (match_dup 4))
3565 [(lshiftrt:SI (match_dup 8) (match_dup 6))
3568 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3572 [(set (match_operand:SI 0 "s_register_operand" "")
3573 (match_operator:SI 1 "logical_binary_operator"
3574 [(sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
3575 (match_operand:SI 3 "const_int_operand" "")
3576 (match_operand:SI 4 "const_int_operand" ""))
3577 (match_operator:SI 9 "logical_binary_operator"
3578 [(ashiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3579 (match_operand:SI 6 "const_int_operand" ""))
3580 (match_operand:SI 7 "s_register_operand" "")])]))
3581 (clobber (match_operand:SI 8 "s_register_operand" ""))]
3583 && GET_CODE (operands[1]) == GET_CODE (operands[9])
3584 && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3587 [(ashift:SI (match_dup 2) (match_dup 4))
3591 [(ashiftrt:SI (match_dup 8) (match_dup 6))
3594 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3598 [(set (match_operand:SI 0 "s_register_operand" "")
3599 (match_operator:SI 1 "logical_binary_operator"
3600 [(match_operator:SI 9 "logical_binary_operator"
3601 [(ashiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3602 (match_operand:SI 6 "const_int_operand" ""))
3603 (match_operand:SI 7 "s_register_operand" "")])
3604 (sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
3605 (match_operand:SI 3 "const_int_operand" "")
3606 (match_operand:SI 4 "const_int_operand" ""))]))
3607 (clobber (match_operand:SI 8 "s_register_operand" ""))]
3609 && GET_CODE (operands[1]) == GET_CODE (operands[9])
3610 && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3613 [(ashift:SI (match_dup 2) (match_dup 4))
3617 [(ashiftrt:SI (match_dup 8) (match_dup 6))
3620 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3624 ;; Minimum and maximum insns
3626 (define_expand "smaxsi3"
3628 (set (match_operand:SI 0 "s_register_operand" "")
3629 (smax:SI (match_operand:SI 1 "s_register_operand" "")
3630 (match_operand:SI 2 "arm_rhs_operand" "")))
3631 (clobber (reg:CC CC_REGNUM))])]
3634 if (operands[2] == const0_rtx || operands[2] == constm1_rtx)
3636 /* No need for a clobber of the condition code register here. */
3637 emit_insn (gen_rtx_SET (operands[0],
3638 gen_rtx_SMAX (SImode, operands[1],
3644 (define_insn "*smax_0"
3645 [(set (match_operand:SI 0 "s_register_operand" "=r")
3646 (smax:SI (match_operand:SI 1 "s_register_operand" "r")
3649 "bic%?\\t%0, %1, %1, asr #31"
3650 [(set_attr "predicable" "yes")
3651 (set_attr "predicable_short_it" "no")
3652 (set_attr "type" "logic_shift_reg")]
3655 (define_insn "*smax_m1"
3656 [(set (match_operand:SI 0 "s_register_operand" "=r")
3657 (smax:SI (match_operand:SI 1 "s_register_operand" "r")
3660 "orr%?\\t%0, %1, %1, asr #31"
3661 [(set_attr "predicable" "yes")
3662 (set_attr "predicable_short_it" "no")
3663 (set_attr "type" "logic_shift_reg")]
3666 (define_insn_and_split "*arm_smax_insn"
3667 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3668 (smax:SI (match_operand:SI 1 "s_register_operand" "%0,?r")
3669 (match_operand:SI 2 "arm_rhs_operand" "rI,rI")))
3670 (clobber (reg:CC CC_REGNUM))]
3673 ; cmp\\t%1, %2\;movlt\\t%0, %2
3674 ; cmp\\t%1, %2\;movge\\t%0, %1\;movlt\\t%0, %2"
3676 [(set (reg:CC CC_REGNUM)
3677 (compare:CC (match_dup 1) (match_dup 2)))
3679 (if_then_else:SI (ge:SI (reg:CC CC_REGNUM) (const_int 0))
3683 [(set_attr "conds" "clob")
3684 (set_attr "length" "8,12")
3685 (set_attr "type" "multiple")]
3688 (define_expand "sminsi3"
3690 (set (match_operand:SI 0 "s_register_operand" "")
3691 (smin:SI (match_operand:SI 1 "s_register_operand" "")
3692 (match_operand:SI 2 "arm_rhs_operand" "")))
3693 (clobber (reg:CC CC_REGNUM))])]
3696 if (operands[2] == const0_rtx)
3698 /* No need for a clobber of the condition code register here. */
3699 emit_insn (gen_rtx_SET (operands[0],
3700 gen_rtx_SMIN (SImode, operands[1],
3706 (define_insn "*smin_0"
3707 [(set (match_operand:SI 0 "s_register_operand" "=r")
3708 (smin:SI (match_operand:SI 1 "s_register_operand" "r")
3711 "and%?\\t%0, %1, %1, asr #31"
3712 [(set_attr "predicable" "yes")
3713 (set_attr "predicable_short_it" "no")
3714 (set_attr "type" "logic_shift_reg")]
3717 (define_insn_and_split "*arm_smin_insn"
3718 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3719 (smin:SI (match_operand:SI 1 "s_register_operand" "%0,?r")
3720 (match_operand:SI 2 "arm_rhs_operand" "rI,rI")))
3721 (clobber (reg:CC CC_REGNUM))]
3724 ; cmp\\t%1, %2\;movge\\t%0, %2
3725 ; cmp\\t%1, %2\;movlt\\t%0, %1\;movge\\t%0, %2"
3727 [(set (reg:CC CC_REGNUM)
3728 (compare:CC (match_dup 1) (match_dup 2)))
3730 (if_then_else:SI (lt:SI (reg:CC CC_REGNUM) (const_int 0))
3734 [(set_attr "conds" "clob")
3735 (set_attr "length" "8,12")
3736 (set_attr "type" "multiple,multiple")]
3739 (define_expand "umaxsi3"
3741 (set (match_operand:SI 0 "s_register_operand" "")
3742 (umax:SI (match_operand:SI 1 "s_register_operand" "")
3743 (match_operand:SI 2 "arm_rhs_operand" "")))
3744 (clobber (reg:CC CC_REGNUM))])]
3749 (define_insn_and_split "*arm_umaxsi3"
3750 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
3751 (umax:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
3752 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
3753 (clobber (reg:CC CC_REGNUM))]
3756 ; cmp\\t%1, %2\;movcc\\t%0, %2
3757 ; cmp\\t%1, %2\;movcs\\t%0, %1
3758 ; cmp\\t%1, %2\;movcs\\t%0, %1\;movcc\\t%0, %2"
3760 [(set (reg:CC CC_REGNUM)
3761 (compare:CC (match_dup 1) (match_dup 2)))
3763 (if_then_else:SI (geu:SI (reg:CC CC_REGNUM) (const_int 0))
3767 [(set_attr "conds" "clob")
3768 (set_attr "length" "8,8,12")
3769 (set_attr "type" "store1")]
3772 (define_expand "uminsi3"
3774 (set (match_operand:SI 0 "s_register_operand" "")
3775 (umin:SI (match_operand:SI 1 "s_register_operand" "")
3776 (match_operand:SI 2 "arm_rhs_operand" "")))
3777 (clobber (reg:CC CC_REGNUM))])]
3782 (define_insn_and_split "*arm_uminsi3"
3783 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
3784 (umin:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
3785 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
3786 (clobber (reg:CC CC_REGNUM))]
3789 ; cmp\\t%1, %2\;movcs\\t%0, %2
3790 ; cmp\\t%1, %2\;movcc\\t%0, %1
3791 ; cmp\\t%1, %2\;movcc\\t%0, %1\;movcs\\t%0, %2"
3793 [(set (reg:CC CC_REGNUM)
3794 (compare:CC (match_dup 1) (match_dup 2)))
3796 (if_then_else:SI (ltu:SI (reg:CC CC_REGNUM) (const_int 0))
3800 [(set_attr "conds" "clob")
3801 (set_attr "length" "8,8,12")
3802 (set_attr "type" "store1")]
3805 (define_insn "*store_minmaxsi"
3806 [(set (match_operand:SI 0 "memory_operand" "=m")
3807 (match_operator:SI 3 "minmax_operator"
3808 [(match_operand:SI 1 "s_register_operand" "r")
3809 (match_operand:SI 2 "s_register_operand" "r")]))
3810 (clobber (reg:CC CC_REGNUM))]
3811 "TARGET_32BIT && optimize_function_for_size_p (cfun) && !arm_restrict_it"
3813 operands[3] = gen_rtx_fmt_ee (minmax_code (operands[3]), SImode,
3814 operands[1], operands[2]);
3815 output_asm_insn (\"cmp\\t%1, %2\", operands);
3817 output_asm_insn (\"ite\t%d3\", operands);
3818 output_asm_insn (\"str%d3\\t%1, %0\", operands);
3819 output_asm_insn (\"str%D3\\t%2, %0\", operands);
3822 [(set_attr "conds" "clob")
3823 (set (attr "length")
3824 (if_then_else (eq_attr "is_thumb" "yes")
3827 (set_attr "type" "store1")]
3830 ; Reject the frame pointer in operand[1], since reloading this after
3831 ; it has been eliminated can cause carnage.
3832 (define_insn "*minmax_arithsi"
3833 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3834 (match_operator:SI 4 "shiftable_operator"
3835 [(match_operator:SI 5 "minmax_operator"
3836 [(match_operand:SI 2 "s_register_operand" "r,r")
3837 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
3838 (match_operand:SI 1 "s_register_operand" "0,?r")]))
3839 (clobber (reg:CC CC_REGNUM))]
3840 "TARGET_32BIT && !arm_eliminable_register (operands[1]) && !arm_restrict_it"
3843 enum rtx_code code = GET_CODE (operands[4]);
3846 if (which_alternative != 0 || operands[3] != const0_rtx
3847 || (code != PLUS && code != IOR && code != XOR))
3852 operands[5] = gen_rtx_fmt_ee (minmax_code (operands[5]), SImode,
3853 operands[2], operands[3]);
3854 output_asm_insn (\"cmp\\t%2, %3\", operands);
3858 output_asm_insn (\"ite\\t%d5\", operands);
3860 output_asm_insn (\"it\\t%d5\", operands);
3862 output_asm_insn (\"%i4%d5\\t%0, %1, %2\", operands);
3864 output_asm_insn (\"%i4%D5\\t%0, %1, %3\", operands);
3867 [(set_attr "conds" "clob")
3868 (set (attr "length")
3869 (if_then_else (eq_attr "is_thumb" "yes")
3872 (set_attr "type" "multiple")]
3875 ; Reject the frame pointer in operand[1], since reloading this after
3876 ; it has been eliminated can cause carnage.
3877 (define_insn_and_split "*minmax_arithsi_non_canon"
3878 [(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts")
3880 (match_operand:SI 1 "s_register_operand" "0,?Ts")
3881 (match_operator:SI 4 "minmax_operator"
3882 [(match_operand:SI 2 "s_register_operand" "Ts,Ts")
3883 (match_operand:SI 3 "arm_rhs_operand" "TsI,TsI")])))
3884 (clobber (reg:CC CC_REGNUM))]
3885 "TARGET_32BIT && !arm_eliminable_register (operands[1])
3886 && !(arm_restrict_it && CONST_INT_P (operands[3]))"
3888 "TARGET_32BIT && !arm_eliminable_register (operands[1]) && reload_completed"
3889 [(set (reg:CC CC_REGNUM)
3890 (compare:CC (match_dup 2) (match_dup 3)))
3892 (cond_exec (match_op_dup 4 [(reg:CC CC_REGNUM) (const_int 0)])
3894 (minus:SI (match_dup 1)
3896 (cond_exec (match_op_dup 5 [(reg:CC CC_REGNUM) (const_int 0)])
3900 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
3901 operands[2], operands[3]);
3902 enum rtx_code rc = minmax_code (operands[4]);
3903 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode,
3904 operands[2], operands[3]);
3906 if (mode == CCFPmode || mode == CCFPEmode)
3907 rc = reverse_condition_maybe_unordered (rc);
3909 rc = reverse_condition (rc);
3910 operands[5] = gen_rtx_fmt_ee (rc, SImode, operands[2], operands[3]);
3911 if (CONST_INT_P (operands[3]))
3912 operands[6] = plus_constant (SImode, operands[1], -INTVAL (operands[3]));
3914 operands[6] = gen_rtx_MINUS (SImode, operands[1], operands[3]);
3916 [(set_attr "conds" "clob")
3917 (set (attr "length")
3918 (if_then_else (eq_attr "is_thumb" "yes")
3921 (set_attr "type" "multiple")]
3924 (define_code_iterator SAT [smin smax])
3925 (define_code_iterator SATrev [smin smax])
3926 (define_code_attr SATlo [(smin "1") (smax "2")])
3927 (define_code_attr SAThi [(smin "2") (smax "1")])
3929 (define_insn "*satsi_<SAT:code>"
3930 [(set (match_operand:SI 0 "s_register_operand" "=r")
3931 (SAT:SI (SATrev:SI (match_operand:SI 3 "s_register_operand" "r")
3932 (match_operand:SI 1 "const_int_operand" "i"))
3933 (match_operand:SI 2 "const_int_operand" "i")))]
3934 "TARGET_32BIT && arm_arch6 && <SAT:CODE> != <SATrev:CODE>
3935 && arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>], NULL, NULL)"
3939 if (!arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>],
3940 &mask, &signed_sat))
3943 operands[1] = GEN_INT (mask);
3945 return "ssat%?\t%0, %1, %3";
3947 return "usat%?\t%0, %1, %3";
3949 [(set_attr "predicable" "yes")
3950 (set_attr "predicable_short_it" "no")
3951 (set_attr "type" "alus_imm")]
3954 (define_insn "*satsi_<SAT:code>_shift"
3955 [(set (match_operand:SI 0 "s_register_operand" "=r")
3956 (SAT:SI (SATrev:SI (match_operator:SI 3 "sat_shift_operator"
3957 [(match_operand:SI 4 "s_register_operand" "r")
3958 (match_operand:SI 5 "const_int_operand" "i")])
3959 (match_operand:SI 1 "const_int_operand" "i"))
3960 (match_operand:SI 2 "const_int_operand" "i")))]
3961 "TARGET_32BIT && arm_arch6 && <SAT:CODE> != <SATrev:CODE>
3962 && arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>], NULL, NULL)"
3966 if (!arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>],
3967 &mask, &signed_sat))
3970 operands[1] = GEN_INT (mask);
3972 return "ssat%?\t%0, %1, %4%S3";
3974 return "usat%?\t%0, %1, %4%S3";
3976 [(set_attr "predicable" "yes")
3977 (set_attr "predicable_short_it" "no")
3978 (set_attr "shift" "3")
3979 (set_attr "type" "logic_shift_reg")])
3981 ;; Shift and rotation insns
3983 (define_expand "ashldi3"
3984 [(set (match_operand:DI 0 "s_register_operand" "")
3985 (ashift:DI (match_operand:DI 1 "s_register_operand" "")
3986 (match_operand:SI 2 "general_operand" "")))]
3991 /* Delay the decision whether to use NEON or core-regs until
3992 register allocation. */
3993 emit_insn (gen_ashldi3_neon (operands[0], operands[1], operands[2]));
3998 /* Only the NEON case can handle in-memory shift counts. */
3999 if (!reg_or_int_operand (operands[2], SImode))
4000 operands[2] = force_reg (SImode, operands[2]);
4003 if (!CONST_INT_P (operands[2]) && TARGET_REALLY_IWMMXT)
4004 ; /* No special preparation statements; expand pattern as above. */
4007 rtx scratch1, scratch2;
4009 if (operands[2] == CONST1_RTX (SImode))
4011 emit_insn (gen_arm_ashldi3_1bit (operands[0], operands[1]));
4015 /* Ideally we should use iwmmxt here if we could know that operands[1]
4016 ends up already living in an iwmmxt register. Otherwise it's
4017 cheaper to have the alternate code being generated than moving
4018 values to iwmmxt regs and back. */
4020 /* Expand operation using core-registers.
4021 'FAIL' would achieve the same thing, but this is a bit smarter. */
4022 scratch1 = gen_reg_rtx (SImode);
4023 scratch2 = gen_reg_rtx (SImode);
4024 arm_emit_coreregs_64bit_shift (ASHIFT, operands[0], operands[1],
4025 operands[2], scratch1, scratch2);
4031 (define_insn "arm_ashldi3_1bit"
4032 [(set (match_operand:DI 0 "s_register_operand" "=r,&r")
4033 (ashift:DI (match_operand:DI 1 "s_register_operand" "0,r")
4035 (clobber (reg:CC CC_REGNUM))]
4037 "movs\\t%Q0, %Q1, asl #1\;adc\\t%R0, %R1, %R1"
4038 [(set_attr "conds" "clob")
4039 (set_attr "length" "8")
4040 (set_attr "type" "multiple")]
4043 (define_expand "ashlsi3"
4044 [(set (match_operand:SI 0 "s_register_operand" "")
4045 (ashift:SI (match_operand:SI 1 "s_register_operand" "")
4046 (match_operand:SI 2 "arm_rhs_operand" "")))]
4049 if (CONST_INT_P (operands[2])
4050 && (UINTVAL (operands[2])) > 31)
4052 emit_insn (gen_movsi (operands[0], const0_rtx));
4058 (define_expand "ashrdi3"
4059 [(set (match_operand:DI 0 "s_register_operand" "")
4060 (ashiftrt:DI (match_operand:DI 1 "s_register_operand" "")
4061 (match_operand:SI 2 "reg_or_int_operand" "")))]
4066 /* Delay the decision whether to use NEON or core-regs until
4067 register allocation. */
4068 emit_insn (gen_ashrdi3_neon (operands[0], operands[1], operands[2]));
4072 if (!CONST_INT_P (operands[2]) && TARGET_REALLY_IWMMXT)
4073 ; /* No special preparation statements; expand pattern as above. */
4076 rtx scratch1, scratch2;
4078 if (operands[2] == CONST1_RTX (SImode))
4080 emit_insn (gen_arm_ashrdi3_1bit (operands[0], operands[1]));
4084 /* Ideally we should use iwmmxt here if we could know that operands[1]
4085 ends up already living in an iwmmxt register. Otherwise it's
4086 cheaper to have the alternate code being generated than moving
4087 values to iwmmxt regs and back. */
4089 /* Expand operation using core-registers.
4090 'FAIL' would achieve the same thing, but this is a bit smarter. */
4091 scratch1 = gen_reg_rtx (SImode);
4092 scratch2 = gen_reg_rtx (SImode);
4093 arm_emit_coreregs_64bit_shift (ASHIFTRT, operands[0], operands[1],
4094 operands[2], scratch1, scratch2);
4100 (define_insn "arm_ashrdi3_1bit"
4101 [(set (match_operand:DI 0 "s_register_operand" "=r,&r")
4102 (ashiftrt:DI (match_operand:DI 1 "s_register_operand" "0,r")
4104 (clobber (reg:CC CC_REGNUM))]
4106 "movs\\t%R0, %R1, asr #1\;mov\\t%Q0, %Q1, rrx"
4107 [(set_attr "conds" "clob")
4108 (set_attr "length" "8")
4109 (set_attr "type" "multiple")]
4112 (define_expand "ashrsi3"
4113 [(set (match_operand:SI 0 "s_register_operand" "")
4114 (ashiftrt:SI (match_operand:SI 1 "s_register_operand" "")
4115 (match_operand:SI 2 "arm_rhs_operand" "")))]
4118 if (CONST_INT_P (operands[2])
4119 && UINTVAL (operands[2]) > 31)
4120 operands[2] = GEN_INT (31);
4124 (define_expand "lshrdi3"
4125 [(set (match_operand:DI 0 "s_register_operand" "")
4126 (lshiftrt:DI (match_operand:DI 1 "s_register_operand" "")
4127 (match_operand:SI 2 "reg_or_int_operand" "")))]
4132 /* Delay the decision whether to use NEON or core-regs until
4133 register allocation. */
4134 emit_insn (gen_lshrdi3_neon (operands[0], operands[1], operands[2]));
4138 if (!CONST_INT_P (operands[2]) && TARGET_REALLY_IWMMXT)
4139 ; /* No special preparation statements; expand pattern as above. */
4142 rtx scratch1, scratch2;
4144 if (operands[2] == CONST1_RTX (SImode))
4146 emit_insn (gen_arm_lshrdi3_1bit (operands[0], operands[1]));
4150 /* Ideally we should use iwmmxt here if we could know that operands[1]
4151 ends up already living in an iwmmxt register. Otherwise it's
4152 cheaper to have the alternate code being generated than moving
4153 values to iwmmxt regs and back. */
4155 /* Expand operation using core-registers.
4156 'FAIL' would achieve the same thing, but this is a bit smarter. */
4157 scratch1 = gen_reg_rtx (SImode);
4158 scratch2 = gen_reg_rtx (SImode);
4159 arm_emit_coreregs_64bit_shift (LSHIFTRT, operands[0], operands[1],
4160 operands[2], scratch1, scratch2);
4166 (define_insn "arm_lshrdi3_1bit"
4167 [(set (match_operand:DI 0 "s_register_operand" "=r,&r")
4168 (lshiftrt:DI (match_operand:DI 1 "s_register_operand" "0,r")
4170 (clobber (reg:CC CC_REGNUM))]
4172 "movs\\t%R0, %R1, lsr #1\;mov\\t%Q0, %Q1, rrx"
4173 [(set_attr "conds" "clob")
4174 (set_attr "length" "8")
4175 (set_attr "type" "multiple")]
4178 (define_expand "lshrsi3"
4179 [(set (match_operand:SI 0 "s_register_operand" "")
4180 (lshiftrt:SI (match_operand:SI 1 "s_register_operand" "")
4181 (match_operand:SI 2 "arm_rhs_operand" "")))]
4184 if (CONST_INT_P (operands[2])
4185 && (UINTVAL (operands[2])) > 31)
4187 emit_insn (gen_movsi (operands[0], const0_rtx));
4193 (define_expand "rotlsi3"
4194 [(set (match_operand:SI 0 "s_register_operand" "")
4195 (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
4196 (match_operand:SI 2 "reg_or_int_operand" "")))]
4199 if (CONST_INT_P (operands[2]))
4200 operands[2] = GEN_INT ((32 - INTVAL (operands[2])) % 32);
4203 rtx reg = gen_reg_rtx (SImode);
4204 emit_insn (gen_subsi3 (reg, GEN_INT (32), operands[2]));
4210 (define_expand "rotrsi3"
4211 [(set (match_operand:SI 0 "s_register_operand" "")
4212 (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
4213 (match_operand:SI 2 "arm_rhs_operand" "")))]
4218 if (CONST_INT_P (operands[2])
4219 && UINTVAL (operands[2]) > 31)
4220 operands[2] = GEN_INT (INTVAL (operands[2]) % 32);
4222 else /* TARGET_THUMB1 */
4224 if (CONST_INT_P (operands [2]))
4225 operands [2] = force_reg (SImode, operands[2]);
4230 (define_insn "*arm_shiftsi3"
4231 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r,r")
4232 (match_operator:SI 3 "shift_operator"
4233 [(match_operand:SI 1 "s_register_operand" "0,l,r,r")
4234 (match_operand:SI 2 "reg_or_int_operand" "l,M,M,r")]))]
4236 "* return arm_output_shift(operands, 0);"
4237 [(set_attr "predicable" "yes")
4238 (set_attr "arch" "t2,t2,*,*")
4239 (set_attr "predicable_short_it" "yes,yes,no,no")
4240 (set_attr "length" "4")
4241 (set_attr "shift" "1")
4242 (set_attr "type" "alu_shift_reg,alu_shift_imm,alu_shift_imm,alu_shift_reg")]
4245 (define_insn "*shiftsi3_compare0"
4246 [(set (reg:CC_NOOV CC_REGNUM)
4247 (compare:CC_NOOV (match_operator:SI 3 "shift_operator"
4248 [(match_operand:SI 1 "s_register_operand" "r,r")
4249 (match_operand:SI 2 "arm_rhs_operand" "M,r")])
4251 (set (match_operand:SI 0 "s_register_operand" "=r,r")
4252 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))]
4254 "* return arm_output_shift(operands, 1);"
4255 [(set_attr "conds" "set")
4256 (set_attr "shift" "1")
4257 (set_attr "type" "alus_shift_imm,alus_shift_reg")]
4260 (define_insn "*shiftsi3_compare0_scratch"
4261 [(set (reg:CC_NOOV CC_REGNUM)
4262 (compare:CC_NOOV (match_operator:SI 3 "shift_operator"
4263 [(match_operand:SI 1 "s_register_operand" "r,r")
4264 (match_operand:SI 2 "arm_rhs_operand" "M,r")])
4266 (clobber (match_scratch:SI 0 "=r,r"))]
4268 "* return arm_output_shift(operands, 1);"
4269 [(set_attr "conds" "set")
4270 (set_attr "shift" "1")
4271 (set_attr "type" "shift_imm,shift_reg")]
4274 (define_insn "*not_shiftsi"
4275 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4276 (not:SI (match_operator:SI 3 "shift_operator"
4277 [(match_operand:SI 1 "s_register_operand" "r,r")
4278 (match_operand:SI 2 "shift_amount_operand" "M,rM")])))]
4281 [(set_attr "predicable" "yes")
4282 (set_attr "predicable_short_it" "no")
4283 (set_attr "shift" "1")
4284 (set_attr "arch" "32,a")
4285 (set_attr "type" "mvn_shift,mvn_shift_reg")])
4287 (define_insn "*not_shiftsi_compare0"
4288 [(set (reg:CC_NOOV CC_REGNUM)
4290 (not:SI (match_operator:SI 3 "shift_operator"
4291 [(match_operand:SI 1 "s_register_operand" "r,r")
4292 (match_operand:SI 2 "shift_amount_operand" "M,rM")]))
4294 (set (match_operand:SI 0 "s_register_operand" "=r,r")
4295 (not:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])))]
4297 "mvns%?\\t%0, %1%S3"
4298 [(set_attr "conds" "set")
4299 (set_attr "shift" "1")
4300 (set_attr "arch" "32,a")
4301 (set_attr "type" "mvn_shift,mvn_shift_reg")])
4303 (define_insn "*not_shiftsi_compare0_scratch"
4304 [(set (reg:CC_NOOV CC_REGNUM)
4306 (not:SI (match_operator:SI 3 "shift_operator"
4307 [(match_operand:SI 1 "s_register_operand" "r,r")
4308 (match_operand:SI 2 "shift_amount_operand" "M,rM")]))
4310 (clobber (match_scratch:SI 0 "=r,r"))]
4312 "mvns%?\\t%0, %1%S3"
4313 [(set_attr "conds" "set")
4314 (set_attr "shift" "1")
4315 (set_attr "arch" "32,a")
4316 (set_attr "type" "mvn_shift,mvn_shift_reg")])
4318 ;; We don't really have extzv, but defining this using shifts helps
4319 ;; to reduce register pressure later on.
4321 (define_expand "extzv"
4322 [(set (match_operand 0 "s_register_operand" "")
4323 (zero_extract (match_operand 1 "nonimmediate_operand" "")
4324 (match_operand 2 "const_int_operand" "")
4325 (match_operand 3 "const_int_operand" "")))]
4326 "TARGET_THUMB1 || arm_arch_thumb2"
4329 HOST_WIDE_INT lshift = 32 - INTVAL (operands[2]) - INTVAL (operands[3]);
4330 HOST_WIDE_INT rshift = 32 - INTVAL (operands[2]);
4332 if (arm_arch_thumb2)
4334 HOST_WIDE_INT width = INTVAL (operands[2]);
4335 HOST_WIDE_INT bitpos = INTVAL (operands[3]);
4337 if (unaligned_access && MEM_P (operands[1])
4338 && (width == 16 || width == 32) && (bitpos % BITS_PER_UNIT) == 0)
4342 if (BYTES_BIG_ENDIAN)
4343 bitpos = GET_MODE_BITSIZE (GET_MODE (operands[0])) - width
4348 base_addr = adjust_address (operands[1], SImode,
4349 bitpos / BITS_PER_UNIT);
4350 emit_insn (gen_unaligned_loadsi (operands[0], base_addr));
4354 rtx dest = operands[0];
4355 rtx tmp = gen_reg_rtx (SImode);
4357 /* We may get a paradoxical subreg here. Strip it off. */
4358 if (GET_CODE (dest) == SUBREG
4359 && GET_MODE (dest) == SImode
4360 && GET_MODE (SUBREG_REG (dest)) == HImode)
4361 dest = SUBREG_REG (dest);
4363 if (GET_MODE_BITSIZE (GET_MODE (dest)) != width)
4366 base_addr = adjust_address (operands[1], HImode,
4367 bitpos / BITS_PER_UNIT);
4368 emit_insn (gen_unaligned_loadhiu (tmp, base_addr));
4369 emit_move_insn (gen_lowpart (SImode, dest), tmp);
4373 else if (s_register_operand (operands[1], GET_MODE (operands[1])))
4375 emit_insn (gen_extzv_t2 (operands[0], operands[1], operands[2],
4383 if (!s_register_operand (operands[1], GET_MODE (operands[1])))
4386 operands[3] = GEN_INT (rshift);
4390 emit_insn (gen_lshrsi3 (operands[0], operands[1], operands[3]));
4394 emit_insn (gen_extzv_t1 (operands[0], operands[1], GEN_INT (lshift),
4395 operands[3], gen_reg_rtx (SImode)));
4400 ;; Helper for extzv, for the Thumb-1 register-shifts case.
4402 (define_expand "extzv_t1"
4403 [(set (match_operand:SI 4 "s_register_operand" "")
4404 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
4405 (match_operand:SI 2 "const_int_operand" "")))
4406 (set (match_operand:SI 0 "s_register_operand" "")
4407 (lshiftrt:SI (match_dup 4)
4408 (match_operand:SI 3 "const_int_operand" "")))]
4412 (define_expand "extv"
4413 [(set (match_operand 0 "s_register_operand" "")
4414 (sign_extract (match_operand 1 "nonimmediate_operand" "")
4415 (match_operand 2 "const_int_operand" "")
4416 (match_operand 3 "const_int_operand" "")))]
4419 HOST_WIDE_INT width = INTVAL (operands[2]);
4420 HOST_WIDE_INT bitpos = INTVAL (operands[3]);
4422 if (unaligned_access && MEM_P (operands[1]) && (width == 16 || width == 32)
4423 && (bitpos % BITS_PER_UNIT) == 0)
4427 if (BYTES_BIG_ENDIAN)
4428 bitpos = GET_MODE_BITSIZE (GET_MODE (operands[0])) - width - bitpos;
4432 base_addr = adjust_address (operands[1], SImode,
4433 bitpos / BITS_PER_UNIT);
4434 emit_insn (gen_unaligned_loadsi (operands[0], base_addr));
4438 rtx dest = operands[0];
4439 rtx tmp = gen_reg_rtx (SImode);
4441 /* We may get a paradoxical subreg here. Strip it off. */
4442 if (GET_CODE (dest) == SUBREG
4443 && GET_MODE (dest) == SImode
4444 && GET_MODE (SUBREG_REG (dest)) == HImode)
4445 dest = SUBREG_REG (dest);
4447 if (GET_MODE_BITSIZE (GET_MODE (dest)) != width)
4450 base_addr = adjust_address (operands[1], HImode,
4451 bitpos / BITS_PER_UNIT);
4452 emit_insn (gen_unaligned_loadhis (tmp, base_addr));
4453 emit_move_insn (gen_lowpart (SImode, dest), tmp);
4458 else if (!s_register_operand (operands[1], GET_MODE (operands[1])))
4460 else if (GET_MODE (operands[0]) == SImode
4461 && GET_MODE (operands[1]) == SImode)
4463 emit_insn (gen_extv_regsi (operands[0], operands[1], operands[2],
4471 ; Helper to expand register forms of extv with the proper modes.
4473 (define_expand "extv_regsi"
4474 [(set (match_operand:SI 0 "s_register_operand" "")
4475 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "")
4476 (match_operand 2 "const_int_operand" "")
4477 (match_operand 3 "const_int_operand" "")))]
4482 ; ARMv6+ unaligned load/store instructions (used for packed structure accesses).
4484 (define_insn "unaligned_loadsi"
4485 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4486 (unspec:SI [(match_operand:SI 1 "memory_operand" "Uw,m")]
4487 UNSPEC_UNALIGNED_LOAD))]
4489 "ldr%?\t%0, %1\t@ unaligned"
4490 [(set_attr "arch" "t2,any")
4491 (set_attr "length" "2,4")
4492 (set_attr "predicable" "yes")
4493 (set_attr "predicable_short_it" "yes,no")
4494 (set_attr "type" "load1")])
4496 (define_insn "unaligned_loadhis"
4497 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4499 (unspec:HI [(match_operand:HI 1 "memory_operand" "Uw,Uh")]
4500 UNSPEC_UNALIGNED_LOAD)))]
4502 "ldrsh%?\t%0, %1\t@ unaligned"
4503 [(set_attr "arch" "t2,any")
4504 (set_attr "length" "2,4")
4505 (set_attr "predicable" "yes")
4506 (set_attr "predicable_short_it" "yes,no")
4507 (set_attr "type" "load_byte")])
4509 (define_insn "unaligned_loadhiu"
4510 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4512 (unspec:HI [(match_operand:HI 1 "memory_operand" "Uw,m")]
4513 UNSPEC_UNALIGNED_LOAD)))]
4515 "ldrh%?\t%0, %1\t@ unaligned"
4516 [(set_attr "arch" "t2,any")
4517 (set_attr "length" "2,4")
4518 (set_attr "predicable" "yes")
4519 (set_attr "predicable_short_it" "yes,no")
4520 (set_attr "type" "load_byte")])
4522 (define_insn "unaligned_storesi"
4523 [(set (match_operand:SI 0 "memory_operand" "=Uw,m")
4524 (unspec:SI [(match_operand:SI 1 "s_register_operand" "l,r")]
4525 UNSPEC_UNALIGNED_STORE))]
4527 "str%?\t%1, %0\t@ unaligned"
4528 [(set_attr "arch" "t2,any")
4529 (set_attr "length" "2,4")
4530 (set_attr "predicable" "yes")
4531 (set_attr "predicable_short_it" "yes,no")
4532 (set_attr "type" "store1")])
4534 (define_insn "unaligned_storehi"
4535 [(set (match_operand:HI 0 "memory_operand" "=Uw,m")
4536 (unspec:HI [(match_operand:HI 1 "s_register_operand" "l,r")]
4537 UNSPEC_UNALIGNED_STORE))]
4539 "strh%?\t%1, %0\t@ unaligned"
4540 [(set_attr "arch" "t2,any")
4541 (set_attr "length" "2,4")
4542 (set_attr "predicable" "yes")
4543 (set_attr "predicable_short_it" "yes,no")
4544 (set_attr "type" "store1")])
4547 (define_insn "*extv_reg"
4548 [(set (match_operand:SI 0 "s_register_operand" "=r")
4549 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
4550 (match_operand:SI 2 "const_int_operand" "n")
4551 (match_operand:SI 3 "const_int_operand" "n")))]
4553 && IN_RANGE (INTVAL (operands[3]), 0, 31)
4554 && IN_RANGE (INTVAL (operands[2]), 1, 32 - INTVAL (operands[3]))"
4555 "sbfx%?\t%0, %1, %3, %2"
4556 [(set_attr "length" "4")
4557 (set_attr "predicable" "yes")
4558 (set_attr "predicable_short_it" "no")
4559 (set_attr "type" "bfm")]
4562 (define_insn "extzv_t2"
4563 [(set (match_operand:SI 0 "s_register_operand" "=r")
4564 (zero_extract:SI (match_operand:SI 1 "s_register_operand" "r")
4565 (match_operand:SI 2 "const_int_operand" "n")
4566 (match_operand:SI 3 "const_int_operand" "n")))]
4568 && IN_RANGE (INTVAL (operands[3]), 0, 31)
4569 && IN_RANGE (INTVAL (operands[2]), 1, 32 - INTVAL (operands[3]))"
4570 "ubfx%?\t%0, %1, %3, %2"
4571 [(set_attr "length" "4")
4572 (set_attr "predicable" "yes")
4573 (set_attr "predicable_short_it" "no")
4574 (set_attr "type" "bfm")]
4578 ;; Division instructions
4579 (define_insn "divsi3"
4580 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4581 (div:SI (match_operand:SI 1 "s_register_operand" "r,r")
4582 (match_operand:SI 2 "s_register_operand" "r,r")))]
4587 [(set_attr "arch" "32,v8mb")
4588 (set_attr "predicable" "yes")
4589 (set_attr "predicable_short_it" "no")
4590 (set_attr "type" "sdiv")]
4593 (define_insn "udivsi3"
4594 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4595 (udiv:SI (match_operand:SI 1 "s_register_operand" "r,r")
4596 (match_operand:SI 2 "s_register_operand" "r,r")))]
4601 [(set_attr "arch" "32,v8mb")
4602 (set_attr "predicable" "yes")
4603 (set_attr "predicable_short_it" "no")
4604 (set_attr "type" "udiv")]
4608 ;; Unary arithmetic insns
4610 (define_expand "negvsi3"
4611 [(match_operand:SI 0 "register_operand")
4612 (match_operand:SI 1 "register_operand")
4613 (match_operand 2 "")]
4616 emit_insn (gen_subsi3_compare (operands[0], const0_rtx, operands[1]));
4617 arm_gen_unlikely_cbranch (NE, CC_Vmode, operands[2]);
4622 (define_expand "negvdi3"
4623 [(match_operand:DI 0 "register_operand")
4624 (match_operand:DI 1 "register_operand")
4625 (match_operand 2 "")]
4628 emit_insn (gen_negdi2_compare (operands[0], operands[1]));
4629 arm_gen_unlikely_cbranch (NE, CC_Vmode, operands[2]);
4635 (define_insn_and_split "negdi2_compare"
4636 [(set (reg:CC CC_REGNUM)
4639 (match_operand:DI 1 "register_operand" "0,r")))
4640 (set (match_operand:DI 0 "register_operand" "=r,&r")
4641 (minus:DI (const_int 0) (match_dup 1)))]
4644 "&& reload_completed"
4645 [(parallel [(set (reg:CC CC_REGNUM)
4646 (compare:CC (const_int 0) (match_dup 1)))
4647 (set (match_dup 0) (minus:SI (const_int 0)
4649 (parallel [(set (reg:CC CC_REGNUM)
4650 (compare:CC (const_int 0) (match_dup 3)))
4653 (minus:SI (const_int 0) (match_dup 3))
4654 (ltu:SI (reg:CC_C CC_REGNUM)
4657 operands[2] = gen_highpart (SImode, operands[0]);
4658 operands[0] = gen_lowpart (SImode, operands[0]);
4659 operands[3] = gen_highpart (SImode, operands[1]);
4660 operands[1] = gen_lowpart (SImode, operands[1]);
4662 [(set_attr "conds" "set")
4663 (set_attr "length" "8")
4664 (set_attr "type" "multiple")]
4667 (define_expand "negdi2"
4669 [(set (match_operand:DI 0 "s_register_operand" "")
4670 (neg:DI (match_operand:DI 1 "s_register_operand" "")))
4671 (clobber (reg:CC CC_REGNUM))])]
4676 emit_insn (gen_negdi2_neon (operands[0], operands[1]));
4682 ;; The constraints here are to prevent a *partial* overlap (where %Q0 == %R1).
4683 ;; The first alternative allows the common case of a *full* overlap.
4684 (define_insn_and_split "*arm_negdi2"
4685 [(set (match_operand:DI 0 "s_register_operand" "=r,&r")
4686 (neg:DI (match_operand:DI 1 "s_register_operand" "0,r")))
4687 (clobber (reg:CC CC_REGNUM))]
4689 "#" ; "rsbs\\t%Q0, %Q1, #0\;rsc\\t%R0, %R1, #0"
4690 "&& reload_completed"
4691 [(parallel [(set (reg:CC CC_REGNUM)
4692 (compare:CC (const_int 0) (match_dup 1)))
4693 (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1)))])
4694 (set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3))
4695 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
4697 operands[2] = gen_highpart (SImode, operands[0]);
4698 operands[0] = gen_lowpart (SImode, operands[0]);
4699 operands[3] = gen_highpart (SImode, operands[1]);
4700 operands[1] = gen_lowpart (SImode, operands[1]);
4702 [(set_attr "conds" "clob")
4703 (set_attr "length" "8")
4704 (set_attr "type" "multiple")]
4707 (define_insn "*negsi2_carryin_compare"
4708 [(set (reg:CC CC_REGNUM)
4709 (compare:CC (const_int 0)
4710 (match_operand:SI 1 "s_register_operand" "r")))
4711 (set (match_operand:SI 0 "s_register_operand" "=r")
4712 (minus:SI (minus:SI (const_int 0)
4714 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
4717 [(set_attr "conds" "set")
4718 (set_attr "type" "alus_imm")]
4721 (define_expand "negsi2"
4722 [(set (match_operand:SI 0 "s_register_operand" "")
4723 (neg:SI (match_operand:SI 1 "s_register_operand" "")))]
4728 (define_insn "*arm_negsi2"
4729 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4730 (neg:SI (match_operand:SI 1 "s_register_operand" "l,r")))]
4732 "rsb%?\\t%0, %1, #0"
4733 [(set_attr "predicable" "yes")
4734 (set_attr "predicable_short_it" "yes,no")
4735 (set_attr "arch" "t2,*")
4736 (set_attr "length" "4")
4737 (set_attr "type" "alu_sreg")]
4740 (define_expand "negsf2"
4741 [(set (match_operand:SF 0 "s_register_operand" "")
4742 (neg:SF (match_operand:SF 1 "s_register_operand" "")))]
4743 "TARGET_32BIT && TARGET_HARD_FLOAT"
4747 (define_expand "negdf2"
4748 [(set (match_operand:DF 0 "s_register_operand" "")
4749 (neg:DF (match_operand:DF 1 "s_register_operand" "")))]
4750 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
4753 (define_insn_and_split "*zextendsidi_negsi"
4754 [(set (match_operand:DI 0 "s_register_operand" "=r")
4755 (zero_extend:DI (neg:SI (match_operand:SI 1 "s_register_operand" "r"))))]
4760 (neg:SI (match_dup 1)))
4764 operands[2] = gen_lowpart (SImode, operands[0]);
4765 operands[3] = gen_highpart (SImode, operands[0]);
4767 [(set_attr "length" "8")
4768 (set_attr "type" "multiple")]
4771 ;; Negate an extended 32-bit value.
4772 (define_insn_and_split "*negdi_extendsidi"
4773 [(set (match_operand:DI 0 "s_register_operand" "=l,r")
4774 (neg:DI (sign_extend:DI
4775 (match_operand:SI 1 "s_register_operand" "l,r"))))
4776 (clobber (reg:CC CC_REGNUM))]
4779 "&& reload_completed"
4782 rtx low = gen_lowpart (SImode, operands[0]);
4783 rtx high = gen_highpart (SImode, operands[0]);
4785 if (reg_overlap_mentioned_p (low, operands[1]))
4787 /* Input overlaps the low word of the output. Use:
4790 rsc Rhi, Rhi, #0 (thumb2: sbc Rhi, Rhi, Rhi, lsl #1). */
4791 rtx cc_reg = gen_rtx_REG (CC_Cmode, CC_REGNUM);
4793 emit_insn (gen_rtx_SET (high,
4794 gen_rtx_ASHIFTRT (SImode, operands[1],
4797 emit_insn (gen_subsi3_compare (low, const0_rtx, operands[1]));
4799 emit_insn (gen_rtx_SET (high,
4800 gen_rtx_MINUS (SImode,
4801 gen_rtx_MINUS (SImode,
4804 gen_rtx_LTU (SImode,
4809 rtx two_x = gen_rtx_ASHIFT (SImode, high, GEN_INT (1));
4810 emit_insn (gen_rtx_SET (high,
4811 gen_rtx_MINUS (SImode,
4812 gen_rtx_MINUS (SImode,
4815 gen_rtx_LTU (SImode,
4822 /* No overlap, or overlap on high word. Use:
4826 Flags not needed for this sequence. */
4827 emit_insn (gen_rtx_SET (low, gen_rtx_NEG (SImode, operands[1])));
4828 emit_insn (gen_rtx_SET (high,
4829 gen_rtx_AND (SImode,
4830 gen_rtx_NOT (SImode, operands[1]),
4832 emit_insn (gen_rtx_SET (high,
4833 gen_rtx_ASHIFTRT (SImode, high,
4838 [(set_attr "length" "12")
4839 (set_attr "arch" "t2,*")
4840 (set_attr "type" "multiple")]
4843 (define_insn_and_split "*negdi_zero_extendsidi"
4844 [(set (match_operand:DI 0 "s_register_operand" "=r,&r")
4845 (neg:DI (zero_extend:DI (match_operand:SI 1 "s_register_operand" "0,r"))))
4846 (clobber (reg:CC CC_REGNUM))]
4848 "#" ; "rsbs\\t%Q0, %1, #0\;sbc\\t%R0,%R0,%R0"
4849 ;; Don't care what register is input to sbc,
4850 ;; since we just need to propagate the carry.
4851 "&& reload_completed"
4852 [(parallel [(set (reg:CC CC_REGNUM)
4853 (compare:CC (const_int 0) (match_dup 1)))
4854 (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1)))])
4855 (set (match_dup 2) (minus:SI (minus:SI (match_dup 2) (match_dup 2))
4856 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
4858 operands[2] = gen_highpart (SImode, operands[0]);
4859 operands[0] = gen_lowpart (SImode, operands[0]);
4861 [(set_attr "conds" "clob")
4862 (set_attr "length" "8")
4863 (set_attr "type" "multiple")] ;; length in thumb is 4
4866 ;; abssi2 doesn't really clobber the condition codes if a different register
4867 ;; is being set. To keep things simple, assume during rtl manipulations that
4868 ;; it does, but tell the final scan operator the truth. Similarly for
4871 (define_expand "abssi2"
4873 [(set (match_operand:SI 0 "s_register_operand" "")
4874 (abs:SI (match_operand:SI 1 "s_register_operand" "")))
4875 (clobber (match_dup 2))])]
4879 operands[2] = gen_rtx_SCRATCH (SImode);
4881 operands[2] = gen_rtx_REG (CCmode, CC_REGNUM);
4884 (define_insn_and_split "*arm_abssi2"
4885 [(set (match_operand:SI 0 "s_register_operand" "=r,&r")
4886 (abs:SI (match_operand:SI 1 "s_register_operand" "0,r")))
4887 (clobber (reg:CC CC_REGNUM))]
4890 "&& reload_completed"
4893 /* if (which_alternative == 0) */
4894 if (REGNO(operands[0]) == REGNO(operands[1]))
4896 /* Emit the pattern:
4897 cmp\\t%0, #0\;rsblt\\t%0, %0, #0
4898 [(set (reg:CC CC_REGNUM)
4899 (compare:CC (match_dup 0) (const_int 0)))
4900 (cond_exec (lt:CC (reg:CC CC_REGNUM) (const_int 0))
4901 (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1))))]
4903 emit_insn (gen_rtx_SET (gen_rtx_REG (CCmode, CC_REGNUM),
4904 gen_rtx_COMPARE (CCmode, operands[0], const0_rtx)));
4905 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
4906 (gen_rtx_LT (SImode,
4907 gen_rtx_REG (CCmode, CC_REGNUM),
4909 (gen_rtx_SET (operands[0],
4910 (gen_rtx_MINUS (SImode,
4917 /* Emit the pattern:
4918 alt1: eor%?\\t%0, %1, %1, asr #31\;sub%?\\t%0, %0, %1, asr #31
4920 (xor:SI (match_dup 1)
4921 (ashiftrt:SI (match_dup 1) (const_int 31))))
4923 (minus:SI (match_dup 0)
4924 (ashiftrt:SI (match_dup 1) (const_int 31))))]
4926 emit_insn (gen_rtx_SET (operands[0],
4927 gen_rtx_XOR (SImode,
4928 gen_rtx_ASHIFTRT (SImode,
4932 emit_insn (gen_rtx_SET (operands[0],
4933 gen_rtx_MINUS (SImode,
4935 gen_rtx_ASHIFTRT (SImode,
4941 [(set_attr "conds" "clob,*")
4942 (set_attr "shift" "1")
4943 (set_attr "predicable" "no, yes")
4944 (set_attr "length" "8")
4945 (set_attr "type" "multiple")]
4948 (define_insn_and_split "*arm_neg_abssi2"
4949 [(set (match_operand:SI 0 "s_register_operand" "=r,&r")
4950 (neg:SI (abs:SI (match_operand:SI 1 "s_register_operand" "0,r"))))
4951 (clobber (reg:CC CC_REGNUM))]
4954 "&& reload_completed"
4957 /* if (which_alternative == 0) */
4958 if (REGNO (operands[0]) == REGNO (operands[1]))
4960 /* Emit the pattern:
4961 cmp\\t%0, #0\;rsbgt\\t%0, %0, #0
4963 emit_insn (gen_rtx_SET (gen_rtx_REG (CCmode, CC_REGNUM),
4964 gen_rtx_COMPARE (CCmode, operands[0], const0_rtx)));
4965 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
4967 gen_rtx_REG (CCmode, CC_REGNUM),
4969 gen_rtx_SET (operands[0],
4970 (gen_rtx_MINUS (SImode,
4976 /* Emit the pattern:
4977 eor%?\\t%0, %1, %1, asr #31\;rsb%?\\t%0, %0, %1, asr #31
4979 emit_insn (gen_rtx_SET (operands[0],
4980 gen_rtx_XOR (SImode,
4981 gen_rtx_ASHIFTRT (SImode,
4985 emit_insn (gen_rtx_SET (operands[0],
4986 gen_rtx_MINUS (SImode,
4987 gen_rtx_ASHIFTRT (SImode,
4994 [(set_attr "conds" "clob,*")
4995 (set_attr "shift" "1")
4996 (set_attr "predicable" "no, yes")
4997 (set_attr "length" "8")
4998 (set_attr "type" "multiple")]
5001 (define_expand "abssf2"
5002 [(set (match_operand:SF 0 "s_register_operand" "")
5003 (abs:SF (match_operand:SF 1 "s_register_operand" "")))]
5004 "TARGET_32BIT && TARGET_HARD_FLOAT"
5007 (define_expand "absdf2"
5008 [(set (match_operand:DF 0 "s_register_operand" "")
5009 (abs:DF (match_operand:DF 1 "s_register_operand" "")))]
5010 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
5013 (define_expand "sqrtsf2"
5014 [(set (match_operand:SF 0 "s_register_operand" "")
5015 (sqrt:SF (match_operand:SF 1 "s_register_operand" "")))]
5016 "TARGET_32BIT && TARGET_HARD_FLOAT"
5019 (define_expand "sqrtdf2"
5020 [(set (match_operand:DF 0 "s_register_operand" "")
5021 (sqrt:DF (match_operand:DF 1 "s_register_operand" "")))]
5022 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
5025 (define_insn_and_split "one_cmpldi2"
5026 [(set (match_operand:DI 0 "s_register_operand" "=w,&r,&r,?w")
5027 (not:DI (match_operand:DI 1 "s_register_operand" " w, 0, r, w")))]
5034 "TARGET_32BIT && reload_completed
5035 && arm_general_register_operand (operands[0], DImode)"
5036 [(set (match_dup 0) (not:SI (match_dup 1)))
5037 (set (match_dup 2) (not:SI (match_dup 3)))]
5040 operands[2] = gen_highpart (SImode, operands[0]);
5041 operands[0] = gen_lowpart (SImode, operands[0]);
5042 operands[3] = gen_highpart (SImode, operands[1]);
5043 operands[1] = gen_lowpart (SImode, operands[1]);
5045 [(set_attr "length" "*,8,8,*")
5046 (set_attr "predicable" "no,yes,yes,no")
5047 (set_attr "type" "neon_move,multiple,multiple,neon_move")
5048 (set_attr "arch" "neon_for_64bits,*,*,avoid_neon_for_64bits")]
5051 (define_expand "one_cmplsi2"
5052 [(set (match_operand:SI 0 "s_register_operand" "")
5053 (not:SI (match_operand:SI 1 "s_register_operand" "")))]
5058 (define_insn "*arm_one_cmplsi2"
5059 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
5060 (not:SI (match_operand:SI 1 "s_register_operand" "l,r")))]
5063 [(set_attr "predicable" "yes")
5064 (set_attr "predicable_short_it" "yes,no")
5065 (set_attr "arch" "t2,*")
5066 (set_attr "length" "4")
5067 (set_attr "type" "mvn_reg")]
5070 (define_insn "*notsi_compare0"
5071 [(set (reg:CC_NOOV CC_REGNUM)
5072 (compare:CC_NOOV (not:SI (match_operand:SI 1 "s_register_operand" "r"))
5074 (set (match_operand:SI 0 "s_register_operand" "=r")
5075 (not:SI (match_dup 1)))]
5078 [(set_attr "conds" "set")
5079 (set_attr "type" "mvn_reg")]
5082 (define_insn "*notsi_compare0_scratch"
5083 [(set (reg:CC_NOOV CC_REGNUM)
5084 (compare:CC_NOOV (not:SI (match_operand:SI 1 "s_register_operand" "r"))
5086 (clobber (match_scratch:SI 0 "=r"))]
5089 [(set_attr "conds" "set")
5090 (set_attr "type" "mvn_reg")]
5093 ;; Fixed <--> Floating conversion insns
5095 (define_expand "floatsihf2"
5096 [(set (match_operand:HF 0 "general_operand" "")
5097 (float:HF (match_operand:SI 1 "general_operand" "")))]
5101 rtx op1 = gen_reg_rtx (SFmode);
5102 expand_float (op1, operands[1], 0);
5103 op1 = convert_to_mode (HFmode, op1, 0);
5104 emit_move_insn (operands[0], op1);
5109 (define_expand "floatdihf2"
5110 [(set (match_operand:HF 0 "general_operand" "")
5111 (float:HF (match_operand:DI 1 "general_operand" "")))]
5115 rtx op1 = gen_reg_rtx (SFmode);
5116 expand_float (op1, operands[1], 0);
5117 op1 = convert_to_mode (HFmode, op1, 0);
5118 emit_move_insn (operands[0], op1);
5123 (define_expand "floatsisf2"
5124 [(set (match_operand:SF 0 "s_register_operand" "")
5125 (float:SF (match_operand:SI 1 "s_register_operand" "")))]
5126 "TARGET_32BIT && TARGET_HARD_FLOAT"
5130 (define_expand "floatsidf2"
5131 [(set (match_operand:DF 0 "s_register_operand" "")
5132 (float:DF (match_operand:SI 1 "s_register_operand" "")))]
5133 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
5137 (define_expand "fix_trunchfsi2"
5138 [(set (match_operand:SI 0 "general_operand" "")
5139 (fix:SI (fix:HF (match_operand:HF 1 "general_operand" ""))))]
5143 rtx op1 = convert_to_mode (SFmode, operands[1], 0);
5144 expand_fix (operands[0], op1, 0);
5149 (define_expand "fix_trunchfdi2"
5150 [(set (match_operand:DI 0 "general_operand" "")
5151 (fix:DI (fix:HF (match_operand:HF 1 "general_operand" ""))))]
5155 rtx op1 = convert_to_mode (SFmode, operands[1], 0);
5156 expand_fix (operands[0], op1, 0);
5161 (define_expand "fix_truncsfsi2"
5162 [(set (match_operand:SI 0 "s_register_operand" "")
5163 (fix:SI (fix:SF (match_operand:SF 1 "s_register_operand" ""))))]
5164 "TARGET_32BIT && TARGET_HARD_FLOAT"
5168 (define_expand "fix_truncdfsi2"
5169 [(set (match_operand:SI 0 "s_register_operand" "")
5170 (fix:SI (fix:DF (match_operand:DF 1 "s_register_operand" ""))))]
5171 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
5177 (define_expand "truncdfsf2"
5178 [(set (match_operand:SF 0 "s_register_operand" "")
5180 (match_operand:DF 1 "s_register_operand" "")))]
5181 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
5185 ;; DFmode to HFmode conversions have to go through SFmode.
5186 (define_expand "truncdfhf2"
5187 [(set (match_operand:HF 0 "general_operand" "")
5189 (match_operand:DF 1 "general_operand" "")))]
5194 op1 = convert_to_mode (SFmode, operands[1], 0);
5195 op1 = convert_to_mode (HFmode, op1, 0);
5196 emit_move_insn (operands[0], op1);
5201 ;; Zero and sign extension instructions.
5203 (define_insn "zero_extend<mode>di2"
5204 [(set (match_operand:DI 0 "s_register_operand" "=w,r,?r,w")
5205 (zero_extend:DI (match_operand:QHSI 1 "<qhs_zextenddi_op>"
5206 "<qhs_zextenddi_cstr>")))]
5207 "TARGET_32BIT <qhs_zextenddi_cond>"
5209 [(set_attr "length" "8,4,8,8")
5210 (set_attr "arch" "neon_for_64bits,*,*,avoid_neon_for_64bits")
5211 (set_attr "ce_count" "2")
5212 (set_attr "predicable" "yes")
5213 (set_attr "type" "multiple,mov_reg,multiple,multiple")]
5216 (define_insn "extend<mode>di2"
5217 [(set (match_operand:DI 0 "s_register_operand" "=w,r,?r,?r,w")
5218 (sign_extend:DI (match_operand:QHSI 1 "<qhs_extenddi_op>"
5219 "<qhs_extenddi_cstr>")))]
5220 "TARGET_32BIT <qhs_sextenddi_cond>"
5222 [(set_attr "length" "8,4,8,8,8")
5223 (set_attr "ce_count" "2")
5224 (set_attr "shift" "1")
5225 (set_attr "predicable" "yes")
5226 (set_attr "arch" "neon_for_64bits,*,a,t,avoid_neon_for_64bits")
5227 (set_attr "type" "multiple,mov_reg,multiple,multiple,multiple")]
5230 ;; Splits for all extensions to DImode
5232 [(set (match_operand:DI 0 "s_register_operand" "")
5233 (zero_extend:DI (match_operand 1 "nonimmediate_operand" "")))]
5234 "TARGET_32BIT && reload_completed && !IS_VFP_REGNUM (REGNO (operands[0]))"
5235 [(set (match_dup 0) (match_dup 1))]
5237 rtx lo_part = gen_lowpart (SImode, operands[0]);
5238 machine_mode src_mode = GET_MODE (operands[1]);
5240 if (REG_P (operands[0])
5241 && !reg_overlap_mentioned_p (operands[0], operands[1]))
5242 emit_clobber (operands[0]);
5243 if (!REG_P (lo_part) || src_mode != SImode
5244 || !rtx_equal_p (lo_part, operands[1]))
5246 if (src_mode == SImode)
5247 emit_move_insn (lo_part, operands[1]);
5249 emit_insn (gen_rtx_SET (lo_part,
5250 gen_rtx_ZERO_EXTEND (SImode, operands[1])));
5251 operands[1] = lo_part;
5253 operands[0] = gen_highpart (SImode, operands[0]);
5254 operands[1] = const0_rtx;
5258 [(set (match_operand:DI 0 "s_register_operand" "")
5259 (sign_extend:DI (match_operand 1 "nonimmediate_operand" "")))]
5260 "TARGET_32BIT && reload_completed && !IS_VFP_REGNUM (REGNO (operands[0]))"
5261 [(set (match_dup 0) (ashiftrt:SI (match_dup 1) (const_int 31)))]
5263 rtx lo_part = gen_lowpart (SImode, operands[0]);
5264 machine_mode src_mode = GET_MODE (operands[1]);
5266 if (REG_P (operands[0])
5267 && !reg_overlap_mentioned_p (operands[0], operands[1]))
5268 emit_clobber (operands[0]);
5270 if (!REG_P (lo_part) || src_mode != SImode
5271 || !rtx_equal_p (lo_part, operands[1]))
5273 if (src_mode == SImode)
5274 emit_move_insn (lo_part, operands[1]);
5276 emit_insn (gen_rtx_SET (lo_part,
5277 gen_rtx_SIGN_EXTEND (SImode, operands[1])));
5278 operands[1] = lo_part;
5280 operands[0] = gen_highpart (SImode, operands[0]);
5283 (define_expand "zero_extendhisi2"
5284 [(set (match_operand:SI 0 "s_register_operand" "")
5285 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
5288 if (TARGET_ARM && !arm_arch4 && MEM_P (operands[1]))
5290 emit_insn (gen_movhi_bytes (operands[0], operands[1]));
5293 if (!arm_arch6 && !MEM_P (operands[1]))
5295 rtx t = gen_lowpart (SImode, operands[1]);
5296 rtx tmp = gen_reg_rtx (SImode);
5297 emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (16)));
5298 emit_insn (gen_lshrsi3 (operands[0], tmp, GEN_INT (16)));
5304 [(set (match_operand:SI 0 "s_register_operand" "")
5305 (zero_extend:SI (match_operand:HI 1 "s_register_operand" "")))]
5306 "!TARGET_THUMB2 && !arm_arch6"
5307 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
5308 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 16)))]
5310 operands[2] = gen_lowpart (SImode, operands[1]);
5313 (define_insn "*arm_zero_extendhisi2"
5314 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5315 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
5316 "TARGET_ARM && arm_arch4 && !arm_arch6"
5320 [(set_attr "type" "alu_shift_reg,load_byte")
5321 (set_attr "predicable" "yes")]
5324 (define_insn "*arm_zero_extendhisi2_v6"
5325 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5326 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,Uh")))]
5327 "TARGET_ARM && arm_arch6"
5331 [(set_attr "predicable" "yes")
5332 (set_attr "type" "extend,load_byte")]
5335 (define_insn "*arm_zero_extendhisi2addsi"
5336 [(set (match_operand:SI 0 "s_register_operand" "=r")
5337 (plus:SI (zero_extend:SI (match_operand:HI 1 "s_register_operand" "r"))
5338 (match_operand:SI 2 "s_register_operand" "r")))]
5340 "uxtah%?\\t%0, %2, %1"
5341 [(set_attr "type" "alu_shift_reg")
5342 (set_attr "predicable" "yes")
5343 (set_attr "predicable_short_it" "no")]
5346 (define_expand "zero_extendqisi2"
5347 [(set (match_operand:SI 0 "s_register_operand" "")
5348 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))]
5351 if (TARGET_ARM && !arm_arch6 && !MEM_P (operands[1]))
5353 emit_insn (gen_andsi3 (operands[0],
5354 gen_lowpart (SImode, operands[1]),
5358 if (!arm_arch6 && !MEM_P (operands[1]))
5360 rtx t = gen_lowpart (SImode, operands[1]);
5361 rtx tmp = gen_reg_rtx (SImode);
5362 emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (24)));
5363 emit_insn (gen_lshrsi3 (operands[0], tmp, GEN_INT (24)));
5369 [(set (match_operand:SI 0 "s_register_operand" "")
5370 (zero_extend:SI (match_operand:QI 1 "s_register_operand" "")))]
5372 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 24)))
5373 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 24)))]
5375 operands[2] = simplify_gen_subreg (SImode, operands[1], QImode, 0);
5378 emit_insn (gen_andsi3 (operands[0], operands[2], GEN_INT (255)));
5383 (define_insn "*arm_zero_extendqisi2"
5384 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5385 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
5386 "TARGET_ARM && !arm_arch6"
5389 ldrb%?\\t%0, %1\\t%@ zero_extendqisi2"
5390 [(set_attr "length" "8,4")
5391 (set_attr "type" "alu_shift_reg,load_byte")
5392 (set_attr "predicable" "yes")]
5395 (define_insn "*arm_zero_extendqisi2_v6"
5396 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5397 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,Uh")))]
5398 "TARGET_ARM && arm_arch6"
5401 ldrb%?\\t%0, %1\\t%@ zero_extendqisi2"
5402 [(set_attr "type" "extend,load_byte")
5403 (set_attr "predicable" "yes")]
5406 (define_insn "*arm_zero_extendqisi2addsi"
5407 [(set (match_operand:SI 0 "s_register_operand" "=r")
5408 (plus:SI (zero_extend:SI (match_operand:QI 1 "s_register_operand" "r"))
5409 (match_operand:SI 2 "s_register_operand" "r")))]
5411 "uxtab%?\\t%0, %2, %1"
5412 [(set_attr "predicable" "yes")
5413 (set_attr "predicable_short_it" "no")
5414 (set_attr "type" "alu_shift_reg")]
5418 [(set (match_operand:SI 0 "s_register_operand" "")
5419 (zero_extend:SI (subreg:QI (match_operand:SI 1 "" "") 0)))
5420 (clobber (match_operand:SI 2 "s_register_operand" ""))]
5421 "TARGET_32BIT && (!MEM_P (operands[1])) && ! BYTES_BIG_ENDIAN"
5422 [(set (match_dup 2) (match_dup 1))
5423 (set (match_dup 0) (and:SI (match_dup 2) (const_int 255)))]
5428 [(set (match_operand:SI 0 "s_register_operand" "")
5429 (zero_extend:SI (subreg:QI (match_operand:SI 1 "" "") 3)))
5430 (clobber (match_operand:SI 2 "s_register_operand" ""))]
5431 "TARGET_32BIT && (!MEM_P (operands[1])) && BYTES_BIG_ENDIAN"
5432 [(set (match_dup 2) (match_dup 1))
5433 (set (match_dup 0) (and:SI (match_dup 2) (const_int 255)))]
5439 [(set (match_operand:SI 0 "s_register_operand" "")
5440 (IOR_XOR:SI (and:SI (ashift:SI
5441 (match_operand:SI 1 "s_register_operand" "")
5442 (match_operand:SI 2 "const_int_operand" ""))
5443 (match_operand:SI 3 "const_int_operand" ""))
5445 (match_operator 5 "subreg_lowpart_operator"
5446 [(match_operand:SI 4 "s_register_operand" "")]))))]
5448 && (UINTVAL (operands[3])
5449 == (GET_MODE_MASK (GET_MODE (operands[5]))
5450 & (GET_MODE_MASK (GET_MODE (operands[5]))
5451 << (INTVAL (operands[2])))))"
5452 [(set (match_dup 0) (IOR_XOR:SI (ashift:SI (match_dup 1) (match_dup 2))
5454 (set (match_dup 0) (zero_extend:SI (match_dup 5)))]
5455 "operands[5] = gen_lowpart (GET_MODE (operands[5]), operands[0]);"
5458 (define_insn "*compareqi_eq0"
5459 [(set (reg:CC_Z CC_REGNUM)
5460 (compare:CC_Z (match_operand:QI 0 "s_register_operand" "r")
5464 [(set_attr "conds" "set")
5465 (set_attr "predicable" "yes")
5466 (set_attr "predicable_short_it" "no")
5467 (set_attr "type" "logic_imm")]
5470 (define_expand "extendhisi2"
5471 [(set (match_operand:SI 0 "s_register_operand" "")
5472 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
5477 emit_insn (gen_thumb1_extendhisi2 (operands[0], operands[1]));
5480 if (MEM_P (operands[1]) && TARGET_ARM && !arm_arch4)
5482 emit_insn (gen_extendhisi2_mem (operands[0], operands[1]));
5486 if (!arm_arch6 && !MEM_P (operands[1]))
5488 rtx t = gen_lowpart (SImode, operands[1]);
5489 rtx tmp = gen_reg_rtx (SImode);
5490 emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (16)));
5491 emit_insn (gen_ashrsi3 (operands[0], tmp, GEN_INT (16)));
5498 [(set (match_operand:SI 0 "register_operand" "")
5499 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))
5500 (clobber (match_scratch:SI 2 ""))])]
5502 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
5503 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
5505 operands[2] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
5508 ;; This pattern will only be used when ldsh is not available
5509 (define_expand "extendhisi2_mem"
5510 [(set (match_dup 2) (zero_extend:SI (match_operand:HI 1 "" "")))
5512 (zero_extend:SI (match_dup 7)))
5513 (set (match_dup 6) (ashift:SI (match_dup 4) (const_int 24)))
5514 (set (match_operand:SI 0 "" "")
5515 (ior:SI (ashiftrt:SI (match_dup 6) (const_int 16)) (match_dup 5)))]
5520 rtx addr = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
5522 mem1 = change_address (operands[1], QImode, addr);
5523 mem2 = change_address (operands[1], QImode,
5524 plus_constant (Pmode, addr, 1));
5525 operands[0] = gen_lowpart (SImode, operands[0]);
5527 operands[2] = gen_reg_rtx (SImode);
5528 operands[3] = gen_reg_rtx (SImode);
5529 operands[6] = gen_reg_rtx (SImode);
5532 if (BYTES_BIG_ENDIAN)
5534 operands[4] = operands[2];
5535 operands[5] = operands[3];
5539 operands[4] = operands[3];
5540 operands[5] = operands[2];
5546 [(set (match_operand:SI 0 "register_operand" "")
5547 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
5549 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
5550 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
5552 operands[2] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
5555 (define_insn "*arm_extendhisi2"
5556 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5557 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,Uh")))]
5558 "TARGET_ARM && arm_arch4 && !arm_arch6"
5562 [(set_attr "length" "8,4")
5563 (set_attr "type" "alu_shift_reg,load_byte")
5564 (set_attr "predicable" "yes")]
5567 ;; ??? Check Thumb-2 pool range
5568 (define_insn "*arm_extendhisi2_v6"
5569 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5570 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,Uh")))]
5571 "TARGET_32BIT && arm_arch6"
5575 [(set_attr "type" "extend,load_byte")
5576 (set_attr "predicable" "yes")
5577 (set_attr "predicable_short_it" "no")]
5580 (define_insn "*arm_extendhisi2addsi"
5581 [(set (match_operand:SI 0 "s_register_operand" "=r")
5582 (plus:SI (sign_extend:SI (match_operand:HI 1 "s_register_operand" "r"))
5583 (match_operand:SI 2 "s_register_operand" "r")))]
5585 "sxtah%?\\t%0, %2, %1"
5586 [(set_attr "type" "alu_shift_reg")]
5589 (define_expand "extendqihi2"
5591 (ashift:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "")
5593 (set (match_operand:HI 0 "s_register_operand" "")
5594 (ashiftrt:SI (match_dup 2)
5599 if (arm_arch4 && MEM_P (operands[1]))
5601 emit_insn (gen_rtx_SET (operands[0],
5602 gen_rtx_SIGN_EXTEND (HImode, operands[1])));
5605 if (!s_register_operand (operands[1], QImode))
5606 operands[1] = copy_to_mode_reg (QImode, operands[1]);
5607 operands[0] = gen_lowpart (SImode, operands[0]);
5608 operands[1] = gen_lowpart (SImode, operands[1]);
5609 operands[2] = gen_reg_rtx (SImode);
5613 (define_insn "*arm_extendqihi_insn"
5614 [(set (match_operand:HI 0 "s_register_operand" "=r")
5615 (sign_extend:HI (match_operand:QI 1 "arm_extendqisi_mem_op" "Uq")))]
5616 "TARGET_ARM && arm_arch4"
5618 [(set_attr "type" "load_byte")
5619 (set_attr "predicable" "yes")]
5622 (define_expand "extendqisi2"
5623 [(set (match_operand:SI 0 "s_register_operand" "")
5624 (sign_extend:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "")))]
5627 if (!arm_arch4 && MEM_P (operands[1]))
5628 operands[1] = copy_to_mode_reg (QImode, operands[1]);
5630 if (!arm_arch6 && !MEM_P (operands[1]))
5632 rtx t = gen_lowpart (SImode, operands[1]);
5633 rtx tmp = gen_reg_rtx (SImode);
5634 emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (24)));
5635 emit_insn (gen_ashrsi3 (operands[0], tmp, GEN_INT (24)));
5641 [(set (match_operand:SI 0 "register_operand" "")
5642 (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
5644 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 24)))
5645 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 24)))]
5647 operands[2] = simplify_gen_subreg (SImode, operands[1], QImode, 0);
5650 (define_insn "*arm_extendqisi"
5651 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5652 (sign_extend:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "r,Uq")))]
5653 "TARGET_ARM && arm_arch4 && !arm_arch6"
5657 [(set_attr "length" "8,4")
5658 (set_attr "type" "alu_shift_reg,load_byte")
5659 (set_attr "predicable" "yes")]
5662 (define_insn "*arm_extendqisi_v6"
5663 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5665 (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "r,Uq")))]
5666 "TARGET_ARM && arm_arch6"
5670 [(set_attr "type" "extend,load_byte")
5671 (set_attr "predicable" "yes")]
5674 (define_insn "*arm_extendqisi2addsi"
5675 [(set (match_operand:SI 0 "s_register_operand" "=r")
5676 (plus:SI (sign_extend:SI (match_operand:QI 1 "s_register_operand" "r"))
5677 (match_operand:SI 2 "s_register_operand" "r")))]
5679 "sxtab%?\\t%0, %2, %1"
5680 [(set_attr "type" "alu_shift_reg")
5681 (set_attr "predicable" "yes")
5682 (set_attr "predicable_short_it" "no")]
5685 (define_expand "extendsfdf2"
5686 [(set (match_operand:DF 0 "s_register_operand" "")
5687 (float_extend:DF (match_operand:SF 1 "s_register_operand" "")))]
5688 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
5692 ;; HFmode -> DFmode conversions have to go through SFmode.
5693 (define_expand "extendhfdf2"
5694 [(set (match_operand:DF 0 "general_operand" "")
5695 (float_extend:DF (match_operand:HF 1 "general_operand" "")))]
5700 op1 = convert_to_mode (SFmode, operands[1], 0);
5701 op1 = convert_to_mode (DFmode, op1, 0);
5702 emit_insn (gen_movdf (operands[0], op1));
5707 ;; Move insns (including loads and stores)
5709 ;; XXX Just some ideas about movti.
5710 ;; I don't think these are a good idea on the arm, there just aren't enough
5712 ;;(define_expand "loadti"
5713 ;; [(set (match_operand:TI 0 "s_register_operand" "")
5714 ;; (mem:TI (match_operand:SI 1 "address_operand" "")))]
5717 ;;(define_expand "storeti"
5718 ;; [(set (mem:TI (match_operand:TI 0 "address_operand" ""))
5719 ;; (match_operand:TI 1 "s_register_operand" ""))]
5722 ;;(define_expand "movti"
5723 ;; [(set (match_operand:TI 0 "general_operand" "")
5724 ;; (match_operand:TI 1 "general_operand" ""))]
5730 ;; if (MEM_P (operands[0]) && MEM_P (operands[1]))
5731 ;; operands[1] = copy_to_reg (operands[1]);
5732 ;; if (MEM_P (operands[0]))
5733 ;; insn = gen_storeti (XEXP (operands[0], 0), operands[1]);
5734 ;; else if (MEM_P (operands[1]))
5735 ;; insn = gen_loadti (operands[0], XEXP (operands[1], 0));
5739 ;; emit_insn (insn);
5743 ;; Recognize garbage generated above.
5746 ;; [(set (match_operand:TI 0 "general_operand" "=r,r,r,<,>,m")
5747 ;; (match_operand:TI 1 "general_operand" "<,>,m,r,r,r"))]
5751 ;; register mem = (which_alternative < 3);
5752 ;; register const char *template;
5754 ;; operands[mem] = XEXP (operands[mem], 0);
5755 ;; switch (which_alternative)
5757 ;; case 0: template = \"ldmdb\\t%1!, %M0\"; break;
5758 ;; case 1: template = \"ldmia\\t%1!, %M0\"; break;
5759 ;; case 2: template = \"ldmia\\t%1, %M0\"; break;
5760 ;; case 3: template = \"stmdb\\t%0!, %M1\"; break;
5761 ;; case 4: template = \"stmia\\t%0!, %M1\"; break;
5762 ;; case 5: template = \"stmia\\t%0, %M1\"; break;
5764 ;; output_asm_insn (template, operands);
5768 (define_expand "movdi"
5769 [(set (match_operand:DI 0 "general_operand" "")
5770 (match_operand:DI 1 "general_operand" ""))]
5773 if (can_create_pseudo_p ())
5775 if (!REG_P (operands[0]))
5776 operands[1] = force_reg (DImode, operands[1]);
5778 if (REG_P (operands[0]) && REGNO (operands[0]) <= LAST_ARM_REGNUM
5779 && !HARD_REGNO_MODE_OK (REGNO (operands[0]), DImode))
5781 /* Avoid LDRD's into an odd-numbered register pair in ARM state
5782 when expanding function calls. */
5783 gcc_assert (can_create_pseudo_p ());
5784 if (MEM_P (operands[1]) && MEM_VOLATILE_P (operands[1]))
5786 /* Perform load into legal reg pair first, then move. */
5787 rtx reg = gen_reg_rtx (DImode);
5788 emit_insn (gen_movdi (reg, operands[1]));
5791 emit_move_insn (gen_lowpart (SImode, operands[0]),
5792 gen_lowpart (SImode, operands[1]));
5793 emit_move_insn (gen_highpart (SImode, operands[0]),
5794 gen_highpart (SImode, operands[1]));
5797 else if (REG_P (operands[1]) && REGNO (operands[1]) <= LAST_ARM_REGNUM
5798 && !HARD_REGNO_MODE_OK (REGNO (operands[1]), DImode))
5800 /* Avoid STRD's from an odd-numbered register pair in ARM state
5801 when expanding function prologue. */
5802 gcc_assert (can_create_pseudo_p ());
5803 rtx split_dest = (MEM_P (operands[0]) && MEM_VOLATILE_P (operands[0]))
5804 ? gen_reg_rtx (DImode)
5806 emit_move_insn (gen_lowpart (SImode, split_dest),
5807 gen_lowpart (SImode, operands[1]));
5808 emit_move_insn (gen_highpart (SImode, split_dest),
5809 gen_highpart (SImode, operands[1]));
5810 if (split_dest != operands[0])
5811 emit_insn (gen_movdi (operands[0], split_dest));
5817 (define_insn "*arm_movdi"
5818 [(set (match_operand:DI 0 "nonimmediate_di_operand" "=r, r, r, q, m")
5819 (match_operand:DI 1 "di_operand" "rDa,Db,Dc,mi,q"))]
5821 && !(TARGET_HARD_FLOAT)
5823 && ( register_operand (operands[0], DImode)
5824 || register_operand (operands[1], DImode))"
5826 switch (which_alternative)
5833 return output_move_double (operands, true, NULL);
5836 [(set_attr "length" "8,12,16,8,8")
5837 (set_attr "type" "multiple,multiple,multiple,load2,store2")
5838 (set_attr "arm_pool_range" "*,*,*,1020,*")
5839 (set_attr "arm_neg_pool_range" "*,*,*,1004,*")
5840 (set_attr "thumb2_pool_range" "*,*,*,4094,*")
5841 (set_attr "thumb2_neg_pool_range" "*,*,*,0,*")]
5845 [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
5846 (match_operand:ANY64 1 "immediate_operand" ""))]
5849 && (arm_const_double_inline_cost (operands[1])
5850 <= arm_max_const_double_inline_cost ())"
5853 arm_split_constant (SET, SImode, curr_insn,
5854 INTVAL (gen_lowpart (SImode, operands[1])),
5855 gen_lowpart (SImode, operands[0]), NULL_RTX, 0);
5856 arm_split_constant (SET, SImode, curr_insn,
5857 INTVAL (gen_highpart_mode (SImode,
5858 GET_MODE (operands[0]),
5860 gen_highpart (SImode, operands[0]), NULL_RTX, 0);
5865 ; If optimizing for size, or if we have load delay slots, then
5866 ; we want to split the constant into two separate operations.
5867 ; In both cases this may split a trivial part into a single data op
5868 ; leaving a single complex constant to load. We can also get longer
5869 ; offsets in a LDR which means we get better chances of sharing the pool
5870 ; entries. Finally, we can normally do a better job of scheduling
5871 ; LDR instructions than we can with LDM.
5872 ; This pattern will only match if the one above did not.
5874 [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
5875 (match_operand:ANY64 1 "const_double_operand" ""))]
5876 "TARGET_ARM && reload_completed
5877 && arm_const_double_by_parts (operands[1])"
5878 [(set (match_dup 0) (match_dup 1))
5879 (set (match_dup 2) (match_dup 3))]
5881 operands[2] = gen_highpart (SImode, operands[0]);
5882 operands[3] = gen_highpart_mode (SImode, GET_MODE (operands[0]),
5884 operands[0] = gen_lowpart (SImode, operands[0]);
5885 operands[1] = gen_lowpart (SImode, operands[1]);
5890 [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
5891 (match_operand:ANY64 1 "arm_general_register_operand" ""))]
5892 "TARGET_EITHER && reload_completed"
5893 [(set (match_dup 0) (match_dup 1))
5894 (set (match_dup 2) (match_dup 3))]
5896 operands[2] = gen_highpart (SImode, operands[0]);
5897 operands[3] = gen_highpart (SImode, operands[1]);
5898 operands[0] = gen_lowpart (SImode, operands[0]);
5899 operands[1] = gen_lowpart (SImode, operands[1]);
5901 /* Handle a partial overlap. */
5902 if (rtx_equal_p (operands[0], operands[3]))
5904 rtx tmp0 = operands[0];
5905 rtx tmp1 = operands[1];
5907 operands[0] = operands[2];
5908 operands[1] = operands[3];
5915 ;; We can't actually do base+index doubleword loads if the index and
5916 ;; destination overlap. Split here so that we at least have chance to
5919 [(set (match_operand:DI 0 "s_register_operand" "")
5920 (mem:DI (plus:SI (match_operand:SI 1 "s_register_operand" "")
5921 (match_operand:SI 2 "s_register_operand" ""))))]
5923 && reg_overlap_mentioned_p (operands[0], operands[1])
5924 && reg_overlap_mentioned_p (operands[0], operands[2])"
5926 (plus:SI (match_dup 1)
5929 (mem:DI (match_dup 4)))]
5931 operands[4] = gen_rtx_REG (SImode, REGNO(operands[0]));
5935 (define_expand "movsi"
5936 [(set (match_operand:SI 0 "general_operand" "")
5937 (match_operand:SI 1 "general_operand" ""))]
5941 rtx base, offset, tmp;
5945 /* Everything except mem = const or mem = mem can be done easily. */
5946 if (MEM_P (operands[0]))
5947 operands[1] = force_reg (SImode, operands[1]);
5948 if (arm_general_register_operand (operands[0], SImode)
5949 && CONST_INT_P (operands[1])
5950 && !(const_ok_for_arm (INTVAL (operands[1]))
5951 || const_ok_for_arm (~INTVAL (operands[1]))))
5953 if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[1]), SET))
5955 emit_insn (gen_rtx_SET (operands[0], operands[1]));
5960 arm_split_constant (SET, SImode, NULL_RTX,
5961 INTVAL (operands[1]), operands[0], NULL_RTX,
5962 optimize && can_create_pseudo_p ());
5967 else /* TARGET_THUMB1... */
5969 if (can_create_pseudo_p ())
5971 if (!REG_P (operands[0]))
5972 operands[1] = force_reg (SImode, operands[1]);
5976 if (ARM_OFFSETS_MUST_BE_WITHIN_SECTIONS_P)
5978 split_const (operands[1], &base, &offset);
5979 if (GET_CODE (base) == SYMBOL_REF
5980 && !offset_within_block_p (base, INTVAL (offset)))
5982 tmp = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];
5983 emit_move_insn (tmp, base);
5984 emit_insn (gen_addsi3 (operands[0], tmp, offset));
5989 /* Recognize the case where operand[1] is a reference to thread-local
5990 data and load its address to a register. */
5991 if (arm_tls_referenced_p (operands[1]))
5993 rtx tmp = operands[1];
5996 if (GET_CODE (tmp) == CONST && GET_CODE (XEXP (tmp, 0)) == PLUS)
5998 addend = XEXP (XEXP (tmp, 0), 1);
5999 tmp = XEXP (XEXP (tmp, 0), 0);
6002 gcc_assert (GET_CODE (tmp) == SYMBOL_REF);
6003 gcc_assert (SYMBOL_REF_TLS_MODEL (tmp) != 0);
6005 tmp = legitimize_tls_address (tmp,
6006 !can_create_pseudo_p () ? operands[0] : 0);
6009 tmp = gen_rtx_PLUS (SImode, tmp, addend);
6010 tmp = force_operand (tmp, operands[0]);
6015 && (CONSTANT_P (operands[1])
6016 || symbol_mentioned_p (operands[1])
6017 || label_mentioned_p (operands[1])))
6018 operands[1] = legitimize_pic_address (operands[1], SImode,
6019 (!can_create_pseudo_p ()
6026 ;; The ARM LO_SUM and HIGH are backwards - HIGH sets the low bits, and
6027 ;; LO_SUM adds in the high bits. Fortunately these are opaque operations
6028 ;; so this does not matter.
6029 (define_insn "*arm_movt"
6030 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r")
6031 (lo_sum:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6032 (match_operand:SI 2 "general_operand" "i,i")))]
6033 "TARGET_HAVE_MOVT && arm_valid_symbolic_address_p (operands[2])"
6035 movt%?\t%0, #:upper16:%c2
6036 movt\t%0, #:upper16:%c2"
6037 [(set_attr "arch" "32,v8mb")
6038 (set_attr "predicable" "yes")
6039 (set_attr "predicable_short_it" "no")
6040 (set_attr "length" "4")
6041 (set_attr "type" "alu_sreg")]
6044 (define_insn "*arm_movsi_insn"
6045 [(set (match_operand:SI 0 "nonimmediate_operand" "=rk,r,r,r,rk,m")
6046 (match_operand:SI 1 "general_operand" "rk, I,K,j,mi,rk"))]
6047 "TARGET_ARM && !TARGET_IWMMXT && !TARGET_HARD_FLOAT
6048 && ( register_operand (operands[0], SImode)
6049 || register_operand (operands[1], SImode))"
6057 [(set_attr "type" "mov_reg,mov_imm,mvn_imm,mov_imm,load1,store1")
6058 (set_attr "predicable" "yes")
6059 (set_attr "arch" "*,*,*,v6t2,*,*")
6060 (set_attr "pool_range" "*,*,*,*,4096,*")
6061 (set_attr "neg_pool_range" "*,*,*,*,4084,*")]
6065 [(set (match_operand:SI 0 "arm_general_register_operand" "")
6066 (match_operand:SI 1 "const_int_operand" ""))]
6068 && (!(const_ok_for_arm (INTVAL (operands[1]))
6069 || const_ok_for_arm (~INTVAL (operands[1]))))"
6070 [(clobber (const_int 0))]
6072 arm_split_constant (SET, SImode, NULL_RTX,
6073 INTVAL (operands[1]), operands[0], NULL_RTX, 0);
6078 ;; A normal way to do (symbol + offset) requires three instructions at least
6079 ;; (depends on how big the offset is) as below:
6080 ;; movw r0, #:lower16:g
6081 ;; movw r0, #:upper16:g
6084 ;; A better way would be:
6085 ;; movw r0, #:lower16:g+4
6086 ;; movw r0, #:upper16:g+4
6088 ;; The limitation of this way is that the length of offset should be a 16-bit
6089 ;; signed value, because current assembler only supports REL type relocation for
6090 ;; such case. If the more powerful RELA type is supported in future, we should
6091 ;; update this pattern to go with better way.
6093 [(set (match_operand:SI 0 "arm_general_register_operand" "")
6094 (const:SI (plus:SI (match_operand:SI 1 "general_operand" "")
6095 (match_operand:SI 2 "const_int_operand" ""))))]
6098 && arm_disable_literal_pool
6100 && GET_CODE (operands[1]) == SYMBOL_REF"
6101 [(clobber (const_int 0))]
6103 int offset = INTVAL (operands[2]);
6105 if (offset < -0x8000 || offset > 0x7fff)
6107 arm_emit_movpair (operands[0], operands[1]);
6108 emit_insn (gen_rtx_SET (operands[0],
6109 gen_rtx_PLUS (SImode, operands[0], operands[2])));
6113 rtx op = gen_rtx_CONST (SImode,
6114 gen_rtx_PLUS (SImode, operands[1], operands[2]));
6115 arm_emit_movpair (operands[0], op);
6120 ;; Split symbol_refs at the later stage (after cprop), instead of generating
6121 ;; movt/movw pair directly at expand. Otherwise corresponding high_sum
6122 ;; and lo_sum would be merged back into memory load at cprop. However,
6123 ;; if the default is to prefer movt/movw rather than a load from the constant
6124 ;; pool, the performance is better.
6126 [(set (match_operand:SI 0 "arm_general_register_operand" "")
6127 (match_operand:SI 1 "general_operand" ""))]
6128 "TARGET_USE_MOVT && GET_CODE (operands[1]) == SYMBOL_REF
6129 && !flag_pic && !target_word_relocations
6130 && !arm_tls_referenced_p (operands[1])"
6131 [(clobber (const_int 0))]
6133 arm_emit_movpair (operands[0], operands[1]);
6137 ;; When generating pic, we need to load the symbol offset into a register.
6138 ;; So that the optimizer does not confuse this with a normal symbol load
6139 ;; we use an unspec. The offset will be loaded from a constant pool entry,
6140 ;; since that is the only type of relocation we can use.
6142 ;; Wrap calculation of the whole PIC address in a single pattern for the
6143 ;; benefit of optimizers, particularly, PRE and HOIST. Calculation of
6144 ;; a PIC address involves two loads from memory, so we want to CSE it
6145 ;; as often as possible.
6146 ;; This pattern will be split into one of the pic_load_addr_* patterns
6147 ;; and a move after GCSE optimizations.
6149 ;; Note: Update arm.c: legitimize_pic_address() when changing this pattern.
6150 (define_expand "calculate_pic_address"
6151 [(set (match_operand:SI 0 "register_operand" "")
6152 (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "")
6153 (unspec:SI [(match_operand:SI 2 "" "")]
6158 ;; Split calculate_pic_address into pic_load_addr_* and a move.
6160 [(set (match_operand:SI 0 "register_operand" "")
6161 (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "")
6162 (unspec:SI [(match_operand:SI 2 "" "")]
6165 [(set (match_dup 3) (unspec:SI [(match_dup 2)] UNSPEC_PIC_SYM))
6166 (set (match_dup 0) (mem:SI (plus:SI (match_dup 1) (match_dup 3))))]
6167 "operands[3] = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];"
6170 ;; operand1 is the memory address to go into
6171 ;; pic_load_addr_32bit.
6172 ;; operand2 is the PIC label to be emitted
6173 ;; from pic_add_dot_plus_eight.
6174 ;; We do this to allow hoisting of the entire insn.
6175 (define_insn_and_split "pic_load_addr_unified"
6176 [(set (match_operand:SI 0 "s_register_operand" "=r,r,l")
6177 (unspec:SI [(match_operand:SI 1 "" "mX,mX,mX")
6178 (match_operand:SI 2 "" "")]
6179 UNSPEC_PIC_UNIFIED))]
6182 "&& reload_completed"
6183 [(set (match_dup 0) (unspec:SI [(match_dup 1)] UNSPEC_PIC_SYM))
6184 (set (match_dup 0) (unspec:SI [(match_dup 0) (match_dup 3)
6185 (match_dup 2)] UNSPEC_PIC_BASE))]
6186 "operands[3] = TARGET_THUMB ? GEN_INT (4) : GEN_INT (8);"
6187 [(set_attr "type" "load1,load1,load1")
6188 (set_attr "pool_range" "4096,4094,1022")
6189 (set_attr "neg_pool_range" "4084,0,0")
6190 (set_attr "arch" "a,t2,t1")
6191 (set_attr "length" "8,6,4")]
6194 ;; The rather odd constraints on the following are to force reload to leave
6195 ;; the insn alone, and to force the minipool generation pass to then move
6196 ;; the GOT symbol to memory.
6198 (define_insn "pic_load_addr_32bit"
6199 [(set (match_operand:SI 0 "s_register_operand" "=r")
6200 (unspec:SI [(match_operand:SI 1 "" "mX")] UNSPEC_PIC_SYM))]
6201 "TARGET_32BIT && flag_pic"
6203 [(set_attr "type" "load1")
6204 (set (attr "pool_range")
6205 (if_then_else (eq_attr "is_thumb" "no")
6208 (set (attr "neg_pool_range")
6209 (if_then_else (eq_attr "is_thumb" "no")
6214 (define_insn "pic_load_addr_thumb1"
6215 [(set (match_operand:SI 0 "s_register_operand" "=l")
6216 (unspec:SI [(match_operand:SI 1 "" "mX")] UNSPEC_PIC_SYM))]
6217 "TARGET_THUMB1 && flag_pic"
6219 [(set_attr "type" "load1")
6220 (set (attr "pool_range") (const_int 1018))]
6223 (define_insn "pic_add_dot_plus_four"
6224 [(set (match_operand:SI 0 "register_operand" "=r")
6225 (unspec:SI [(match_operand:SI 1 "register_operand" "0")
6227 (match_operand 2 "" "")]
6231 (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
6232 INTVAL (operands[2]));
6233 return \"add\\t%0, %|pc\";
6235 [(set_attr "length" "2")
6236 (set_attr "type" "alu_sreg")]
6239 (define_insn "pic_add_dot_plus_eight"
6240 [(set (match_operand:SI 0 "register_operand" "=r")
6241 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
6243 (match_operand 2 "" "")]
6247 (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
6248 INTVAL (operands[2]));
6249 return \"add%?\\t%0, %|pc, %1\";
6251 [(set_attr "predicable" "yes")
6252 (set_attr "type" "alu_sreg")]
6255 (define_insn "tls_load_dot_plus_eight"
6256 [(set (match_operand:SI 0 "register_operand" "=r")
6257 (mem:SI (unspec:SI [(match_operand:SI 1 "register_operand" "r")
6259 (match_operand 2 "" "")]
6263 (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
6264 INTVAL (operands[2]));
6265 return \"ldr%?\\t%0, [%|pc, %1]\t\t@ tls_load_dot_plus_eight\";
6267 [(set_attr "predicable" "yes")
6268 (set_attr "type" "load1")]
6271 ;; PIC references to local variables can generate pic_add_dot_plus_eight
6272 ;; followed by a load. These sequences can be crunched down to
6273 ;; tls_load_dot_plus_eight by a peephole.
6276 [(set (match_operand:SI 0 "register_operand" "")
6277 (unspec:SI [(match_operand:SI 3 "register_operand" "")
6279 (match_operand 1 "" "")]
6281 (set (match_operand:SI 2 "arm_general_register_operand" "")
6282 (mem:SI (match_dup 0)))]
6283 "TARGET_ARM && peep2_reg_dead_p (2, operands[0])"
6285 (mem:SI (unspec:SI [(match_dup 3)
6292 (define_insn "pic_offset_arm"
6293 [(set (match_operand:SI 0 "register_operand" "=r")
6294 (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
6295 (unspec:SI [(match_operand:SI 2 "" "X")]
6296 UNSPEC_PIC_OFFSET))))]
6297 "TARGET_VXWORKS_RTP && TARGET_ARM && flag_pic"
6298 "ldr%?\\t%0, [%1,%2]"
6299 [(set_attr "type" "load1")]
6302 (define_expand "builtin_setjmp_receiver"
6303 [(label_ref (match_operand 0 "" ""))]
6307 /* r3 is clobbered by set/longjmp, so we can use it as a scratch
6309 if (arm_pic_register != INVALID_REGNUM)
6310 arm_load_pic_register (1UL << 3);
6314 ;; If copying one reg to another we can set the condition codes according to
6315 ;; its value. Such a move is common after a return from subroutine and the
6316 ;; result is being tested against zero.
6318 (define_insn "*movsi_compare0"
6319 [(set (reg:CC CC_REGNUM)
6320 (compare:CC (match_operand:SI 1 "s_register_operand" "0,r")
6322 (set (match_operand:SI 0 "s_register_operand" "=r,r")
6327 subs%?\\t%0, %1, #0"
6328 [(set_attr "conds" "set")
6329 (set_attr "type" "alus_imm,alus_imm")]
6332 ;; Subroutine to store a half word from a register into memory.
6333 ;; Operand 0 is the source register (HImode)
6334 ;; Operand 1 is the destination address in a register (SImode)
6336 ;; In both this routine and the next, we must be careful not to spill
6337 ;; a memory address of reg+large_const into a separate PLUS insn, since this
6338 ;; can generate unrecognizable rtl.
6340 (define_expand "storehi"
6341 [;; store the low byte
6342 (set (match_operand 1 "" "") (match_dup 3))
6343 ;; extract the high byte
6345 (ashiftrt:SI (match_operand 0 "" "") (const_int 8)))
6346 ;; store the high byte
6347 (set (match_dup 4) (match_dup 5))]
6351 rtx op1 = operands[1];
6352 rtx addr = XEXP (op1, 0);
6353 enum rtx_code code = GET_CODE (addr);
6355 if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1)))
6357 op1 = replace_equiv_address (operands[1], force_reg (SImode, addr));
6359 operands[4] = adjust_address (op1, QImode, 1);
6360 operands[1] = adjust_address (operands[1], QImode, 0);
6361 operands[3] = gen_lowpart (QImode, operands[0]);
6362 operands[0] = gen_lowpart (SImode, operands[0]);
6363 operands[2] = gen_reg_rtx (SImode);
6364 operands[5] = gen_lowpart (QImode, operands[2]);
6368 (define_expand "storehi_bigend"
6369 [(set (match_dup 4) (match_dup 3))
6371 (ashiftrt:SI (match_operand 0 "" "") (const_int 8)))
6372 (set (match_operand 1 "" "") (match_dup 5))]
6376 rtx op1 = operands[1];
6377 rtx addr = XEXP (op1, 0);
6378 enum rtx_code code = GET_CODE (addr);
6380 if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1)))
6382 op1 = replace_equiv_address (op1, force_reg (SImode, addr));
6384 operands[4] = adjust_address (op1, QImode, 1);
6385 operands[1] = adjust_address (operands[1], QImode, 0);
6386 operands[3] = gen_lowpart (QImode, operands[0]);
6387 operands[0] = gen_lowpart (SImode, operands[0]);
6388 operands[2] = gen_reg_rtx (SImode);
6389 operands[5] = gen_lowpart (QImode, operands[2]);
6393 ;; Subroutine to store a half word integer constant into memory.
6394 (define_expand "storeinthi"
6395 [(set (match_operand 0 "" "")
6396 (match_operand 1 "" ""))
6397 (set (match_dup 3) (match_dup 2))]
6401 HOST_WIDE_INT value = INTVAL (operands[1]);
6402 rtx addr = XEXP (operands[0], 0);
6403 rtx op0 = operands[0];
6404 enum rtx_code code = GET_CODE (addr);
6406 if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1)))
6408 op0 = replace_equiv_address (op0, force_reg (SImode, addr));
6410 operands[1] = gen_reg_rtx (SImode);
6411 if (BYTES_BIG_ENDIAN)
6413 emit_insn (gen_movsi (operands[1], GEN_INT ((value >> 8) & 255)));
6414 if ((value & 255) == ((value >> 8) & 255))
6415 operands[2] = operands[1];
6418 operands[2] = gen_reg_rtx (SImode);
6419 emit_insn (gen_movsi (operands[2], GEN_INT (value & 255)));
6424 emit_insn (gen_movsi (operands[1], GEN_INT (value & 255)));
6425 if ((value & 255) == ((value >> 8) & 255))
6426 operands[2] = operands[1];
6429 operands[2] = gen_reg_rtx (SImode);
6430 emit_insn (gen_movsi (operands[2], GEN_INT ((value >> 8) & 255)));
6434 operands[3] = adjust_address (op0, QImode, 1);
6435 operands[0] = adjust_address (operands[0], QImode, 0);
6436 operands[2] = gen_lowpart (QImode, operands[2]);
6437 operands[1] = gen_lowpart (QImode, operands[1]);
6441 (define_expand "storehi_single_op"
6442 [(set (match_operand:HI 0 "memory_operand" "")
6443 (match_operand:HI 1 "general_operand" ""))]
6444 "TARGET_32BIT && arm_arch4"
6446 if (!s_register_operand (operands[1], HImode))
6447 operands[1] = copy_to_mode_reg (HImode, operands[1]);
6451 (define_expand "movhi"
6452 [(set (match_operand:HI 0 "general_operand" "")
6453 (match_operand:HI 1 "general_operand" ""))]
6458 if (can_create_pseudo_p ())
6460 if (MEM_P (operands[0]))
6464 emit_insn (gen_storehi_single_op (operands[0], operands[1]));
6467 if (CONST_INT_P (operands[1]))
6468 emit_insn (gen_storeinthi (operands[0], operands[1]));
6471 if (MEM_P (operands[1]))
6472 operands[1] = force_reg (HImode, operands[1]);
6473 if (BYTES_BIG_ENDIAN)
6474 emit_insn (gen_storehi_bigend (operands[1], operands[0]));
6476 emit_insn (gen_storehi (operands[1], operands[0]));
6480 /* Sign extend a constant, and keep it in an SImode reg. */
6481 else if (CONST_INT_P (operands[1]))
6483 rtx reg = gen_reg_rtx (SImode);
6484 HOST_WIDE_INT val = INTVAL (operands[1]) & 0xffff;
6486 /* If the constant is already valid, leave it alone. */
6487 if (!const_ok_for_arm (val))
6489 /* If setting all the top bits will make the constant
6490 loadable in a single instruction, then set them.
6491 Otherwise, sign extend the number. */
6493 if (const_ok_for_arm (~(val | ~0xffff)))
6495 else if (val & 0x8000)
6499 emit_insn (gen_movsi (reg, GEN_INT (val)));
6500 operands[1] = gen_lowpart (HImode, reg);
6502 else if (arm_arch4 && optimize && can_create_pseudo_p ()
6503 && MEM_P (operands[1]))
6505 rtx reg = gen_reg_rtx (SImode);
6507 emit_insn (gen_zero_extendhisi2 (reg, operands[1]));
6508 operands[1] = gen_lowpart (HImode, reg);
6510 else if (!arm_arch4)
6512 if (MEM_P (operands[1]))
6515 rtx offset = const0_rtx;
6516 rtx reg = gen_reg_rtx (SImode);
6518 if ((REG_P (base = XEXP (operands[1], 0))
6519 || (GET_CODE (base) == PLUS
6520 && (CONST_INT_P (offset = XEXP (base, 1)))
6521 && ((INTVAL(offset) & 1) != 1)
6522 && REG_P (base = XEXP (base, 0))))
6523 && REGNO_POINTER_ALIGN (REGNO (base)) >= 32)
6527 new_rtx = widen_memory_access (operands[1], SImode,
6528 ((INTVAL (offset) & ~3)
6529 - INTVAL (offset)));
6530 emit_insn (gen_movsi (reg, new_rtx));
6531 if (((INTVAL (offset) & 2) != 0)
6532 ^ (BYTES_BIG_ENDIAN ? 1 : 0))
6534 rtx reg2 = gen_reg_rtx (SImode);
6536 emit_insn (gen_lshrsi3 (reg2, reg, GEN_INT (16)));
6541 emit_insn (gen_movhi_bytes (reg, operands[1]));
6543 operands[1] = gen_lowpart (HImode, reg);
6547 /* Handle loading a large integer during reload. */
6548 else if (CONST_INT_P (operands[1])
6549 && !const_ok_for_arm (INTVAL (operands[1]))
6550 && !const_ok_for_arm (~INTVAL (operands[1])))
6552 /* Writing a constant to memory needs a scratch, which should
6553 be handled with SECONDARY_RELOADs. */
6554 gcc_assert (REG_P (operands[0]));
6556 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
6557 emit_insn (gen_movsi (operands[0], operands[1]));
6561 else if (TARGET_THUMB2)
6563 /* Thumb-2 can do everything except mem=mem and mem=const easily. */
6564 if (can_create_pseudo_p ())
6566 if (!REG_P (operands[0]))
6567 operands[1] = force_reg (HImode, operands[1]);
6568 /* Zero extend a constant, and keep it in an SImode reg. */
6569 else if (CONST_INT_P (operands[1]))
6571 rtx reg = gen_reg_rtx (SImode);
6572 HOST_WIDE_INT val = INTVAL (operands[1]) & 0xffff;
6574 emit_insn (gen_movsi (reg, GEN_INT (val)));
6575 operands[1] = gen_lowpart (HImode, reg);
6579 else /* TARGET_THUMB1 */
6581 if (can_create_pseudo_p ())
6583 if (CONST_INT_P (operands[1]))
6585 rtx reg = gen_reg_rtx (SImode);
6587 emit_insn (gen_movsi (reg, operands[1]));
6588 operands[1] = gen_lowpart (HImode, reg);
6591 /* ??? We shouldn't really get invalid addresses here, but this can
6592 happen if we are passed a SP (never OK for HImode/QImode) or
6593 virtual register (also rejected as illegitimate for HImode/QImode)
6594 relative address. */
6595 /* ??? This should perhaps be fixed elsewhere, for instance, in
6596 fixup_stack_1, by checking for other kinds of invalid addresses,
6597 e.g. a bare reference to a virtual register. This may confuse the
6598 alpha though, which must handle this case differently. */
6599 if (MEM_P (operands[0])
6600 && !memory_address_p (GET_MODE (operands[0]),
6601 XEXP (operands[0], 0)))
6603 = replace_equiv_address (operands[0],
6604 copy_to_reg (XEXP (operands[0], 0)));
6606 if (MEM_P (operands[1])
6607 && !memory_address_p (GET_MODE (operands[1]),
6608 XEXP (operands[1], 0)))
6610 = replace_equiv_address (operands[1],
6611 copy_to_reg (XEXP (operands[1], 0)));
6613 if (MEM_P (operands[1]) && optimize > 0)
6615 rtx reg = gen_reg_rtx (SImode);
6617 emit_insn (gen_zero_extendhisi2 (reg, operands[1]));
6618 operands[1] = gen_lowpart (HImode, reg);
6621 if (MEM_P (operands[0]))
6622 operands[1] = force_reg (HImode, operands[1]);
6624 else if (CONST_INT_P (operands[1])
6625 && !satisfies_constraint_I (operands[1]))
6627 /* Handle loading a large integer during reload. */
6629 /* Writing a constant to memory needs a scratch, which should
6630 be handled with SECONDARY_RELOADs. */
6631 gcc_assert (REG_P (operands[0]));
6633 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
6634 emit_insn (gen_movsi (operands[0], operands[1]));
6641 (define_expand "movhi_bytes"
6642 [(set (match_dup 2) (zero_extend:SI (match_operand:HI 1 "" "")))
6644 (zero_extend:SI (match_dup 6)))
6645 (set (match_operand:SI 0 "" "")
6646 (ior:SI (ashift:SI (match_dup 4) (const_int 8)) (match_dup 5)))]
6651 rtx addr = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
6653 mem1 = change_address (operands[1], QImode, addr);
6654 mem2 = change_address (operands[1], QImode,
6655 plus_constant (Pmode, addr, 1));
6656 operands[0] = gen_lowpart (SImode, operands[0]);
6658 operands[2] = gen_reg_rtx (SImode);
6659 operands[3] = gen_reg_rtx (SImode);
6662 if (BYTES_BIG_ENDIAN)
6664 operands[4] = operands[2];
6665 operands[5] = operands[3];
6669 operands[4] = operands[3];
6670 operands[5] = operands[2];
6675 (define_expand "movhi_bigend"
6677 (rotate:SI (subreg:SI (match_operand:HI 1 "memory_operand" "") 0)
6680 (ashiftrt:SI (match_dup 2) (const_int 16)))
6681 (set (match_operand:HI 0 "s_register_operand" "")
6685 operands[2] = gen_reg_rtx (SImode);
6686 operands[3] = gen_reg_rtx (SImode);
6687 operands[4] = gen_lowpart (HImode, operands[3]);
6691 ;; Pattern to recognize insn generated default case above
6692 (define_insn "*movhi_insn_arch4"
6693 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m,r")
6694 (match_operand:HI 1 "general_operand" "rIk,K,n,r,mi"))]
6696 && arm_arch4 && !TARGET_HARD_FLOAT
6697 && (register_operand (operands[0], HImode)
6698 || register_operand (operands[1], HImode))"
6700 mov%?\\t%0, %1\\t%@ movhi
6701 mvn%?\\t%0, #%B1\\t%@ movhi
6702 movw%?\\t%0, %L1\\t%@ movhi
6703 strh%?\\t%1, %0\\t%@ movhi
6704 ldrh%?\\t%0, %1\\t%@ movhi"
6705 [(set_attr "predicable" "yes")
6706 (set_attr "pool_range" "*,*,*,*,256")
6707 (set_attr "neg_pool_range" "*,*,*,*,244")
6708 (set_attr "arch" "*,*,v6t2,*,*")
6709 (set_attr_alternative "type"
6710 [(if_then_else (match_operand 1 "const_int_operand" "")
6711 (const_string "mov_imm" )
6712 (const_string "mov_reg"))
6713 (const_string "mvn_imm")
6714 (const_string "mov_imm")
6715 (const_string "store1")
6716 (const_string "load1")])]
6719 (define_insn "*movhi_bytes"
6720 [(set (match_operand:HI 0 "s_register_operand" "=r,r,r")
6721 (match_operand:HI 1 "arm_rhs_operand" "I,rk,K"))]
6722 "TARGET_ARM && !TARGET_HARD_FLOAT"
6724 mov%?\\t%0, %1\\t%@ movhi
6725 mov%?\\t%0, %1\\t%@ movhi
6726 mvn%?\\t%0, #%B1\\t%@ movhi"
6727 [(set_attr "predicable" "yes")
6728 (set_attr "type" "mov_imm,mov_reg,mvn_imm")]
6731 ;; We use a DImode scratch because we may occasionally need an additional
6732 ;; temporary if the address isn't offsettable -- push_reload doesn't seem
6733 ;; to take any notice of the "o" constraints on reload_memory_operand operand.
6734 (define_expand "reload_outhi"
6735 [(parallel [(match_operand:HI 0 "arm_reload_memory_operand" "=o")
6736 (match_operand:HI 1 "s_register_operand" "r")
6737 (match_operand:DI 2 "s_register_operand" "=&l")])]
6740 arm_reload_out_hi (operands);
6742 thumb_reload_out_hi (operands);
6747 (define_expand "reload_inhi"
6748 [(parallel [(match_operand:HI 0 "s_register_operand" "=r")
6749 (match_operand:HI 1 "arm_reload_memory_operand" "o")
6750 (match_operand:DI 2 "s_register_operand" "=&r")])]
6754 arm_reload_in_hi (operands);
6756 thumb_reload_out_hi (operands);
6760 (define_expand "movqi"
6761 [(set (match_operand:QI 0 "general_operand" "")
6762 (match_operand:QI 1 "general_operand" ""))]
6765 /* Everything except mem = const or mem = mem can be done easily */
6767 if (can_create_pseudo_p ())
6769 if (CONST_INT_P (operands[1]))
6771 rtx reg = gen_reg_rtx (SImode);
6773 /* For thumb we want an unsigned immediate, then we are more likely
6774 to be able to use a movs insn. */
6776 operands[1] = GEN_INT (INTVAL (operands[1]) & 255);
6778 emit_insn (gen_movsi (reg, operands[1]));
6779 operands[1] = gen_lowpart (QImode, reg);
6784 /* ??? We shouldn't really get invalid addresses here, but this can
6785 happen if we are passed a SP (never OK for HImode/QImode) or
6786 virtual register (also rejected as illegitimate for HImode/QImode)
6787 relative address. */
6788 /* ??? This should perhaps be fixed elsewhere, for instance, in
6789 fixup_stack_1, by checking for other kinds of invalid addresses,
6790 e.g. a bare reference to a virtual register. This may confuse the
6791 alpha though, which must handle this case differently. */
6792 if (MEM_P (operands[0])
6793 && !memory_address_p (GET_MODE (operands[0]),
6794 XEXP (operands[0], 0)))
6796 = replace_equiv_address (operands[0],
6797 copy_to_reg (XEXP (operands[0], 0)));
6798 if (MEM_P (operands[1])
6799 && !memory_address_p (GET_MODE (operands[1]),
6800 XEXP (operands[1], 0)))
6802 = replace_equiv_address (operands[1],
6803 copy_to_reg (XEXP (operands[1], 0)));
6806 if (MEM_P (operands[1]) && optimize > 0)
6808 rtx reg = gen_reg_rtx (SImode);
6810 emit_insn (gen_zero_extendqisi2 (reg, operands[1]));
6811 operands[1] = gen_lowpart (QImode, reg);
6814 if (MEM_P (operands[0]))
6815 operands[1] = force_reg (QImode, operands[1]);
6817 else if (TARGET_THUMB
6818 && CONST_INT_P (operands[1])
6819 && !satisfies_constraint_I (operands[1]))
6821 /* Handle loading a large integer during reload. */
6823 /* Writing a constant to memory needs a scratch, which should
6824 be handled with SECONDARY_RELOADs. */
6825 gcc_assert (REG_P (operands[0]));
6827 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
6828 emit_insn (gen_movsi (operands[0], operands[1]));
6834 (define_insn "*arm_movqi_insn"
6835 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,r,l,r,l,Uu,r,m")
6836 (match_operand:QI 1 "general_operand" "rk,rk,I,Py,K,Uu,l,Uh,r"))]
6838 && ( register_operand (operands[0], QImode)
6839 || register_operand (operands[1], QImode))"
6850 [(set_attr "type" "mov_reg,mov_reg,mov_imm,mov_imm,mvn_imm,load1,store1,load1,store1")
6851 (set_attr "predicable" "yes")
6852 (set_attr "predicable_short_it" "yes,yes,no,yes,no,no,no,no,no")
6853 (set_attr "arch" "t2,any,any,t2,any,t2,t2,any,any")
6854 (set_attr "length" "2,4,4,2,4,2,2,4,4")]
6858 (define_expand "movhf"
6859 [(set (match_operand:HF 0 "general_operand" "")
6860 (match_operand:HF 1 "general_operand" ""))]
6865 if (MEM_P (operands[0]))
6866 operands[1] = force_reg (HFmode, operands[1]);
6868 else /* TARGET_THUMB1 */
6870 if (can_create_pseudo_p ())
6872 if (!REG_P (operands[0]))
6873 operands[1] = force_reg (HFmode, operands[1]);
6879 (define_insn "*arm32_movhf"
6880 [(set (match_operand:HF 0 "nonimmediate_operand" "=r,m,r,r")
6881 (match_operand:HF 1 "general_operand" " m,r,r,F"))]
6882 "TARGET_32BIT && !TARGET_HARD_FLOAT
6883 && ( s_register_operand (operands[0], HFmode)
6884 || s_register_operand (operands[1], HFmode))"
6886 switch (which_alternative)
6888 case 0: /* ARM register from memory */
6889 return \"ldrh%?\\t%0, %1\\t%@ __fp16\";
6890 case 1: /* memory from ARM register */
6891 return \"strh%?\\t%1, %0\\t%@ __fp16\";
6892 case 2: /* ARM register from ARM register */
6893 return \"mov%?\\t%0, %1\\t%@ __fp16\";
6894 case 3: /* ARM register from constant */
6899 bits = real_to_target (NULL, CONST_DOUBLE_REAL_VALUE (operands[1]),
6901 ops[0] = operands[0];
6902 ops[1] = GEN_INT (bits);
6903 ops[2] = GEN_INT (bits & 0xff00);
6904 ops[3] = GEN_INT (bits & 0x00ff);
6906 if (arm_arch_thumb2)
6907 output_asm_insn (\"movw%?\\t%0, %1\", ops);
6909 output_asm_insn (\"mov%?\\t%0, %2\;orr%?\\t%0, %0, %3\", ops);
6916 [(set_attr "conds" "unconditional")
6917 (set_attr "type" "load1,store1,mov_reg,multiple")
6918 (set_attr "length" "4,4,4,8")
6919 (set_attr "predicable" "yes")
6920 (set_attr "predicable_short_it" "no")]
6923 (define_expand "movsf"
6924 [(set (match_operand:SF 0 "general_operand" "")
6925 (match_operand:SF 1 "general_operand" ""))]
6930 if (MEM_P (operands[0]))
6931 operands[1] = force_reg (SFmode, operands[1]);
6933 else /* TARGET_THUMB1 */
6935 if (can_create_pseudo_p ())
6937 if (!REG_P (operands[0]))
6938 operands[1] = force_reg (SFmode, operands[1]);
6944 ;; Transform a floating-point move of a constant into a core register into
6945 ;; an SImode operation.
6947 [(set (match_operand:SF 0 "arm_general_register_operand" "")
6948 (match_operand:SF 1 "immediate_operand" ""))]
6951 && CONST_DOUBLE_P (operands[1])"
6952 [(set (match_dup 2) (match_dup 3))]
6954 operands[2] = gen_lowpart (SImode, operands[0]);
6955 operands[3] = gen_lowpart (SImode, operands[1]);
6956 if (operands[2] == 0 || operands[3] == 0)
6961 (define_insn "*arm_movsf_soft_insn"
6962 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,m")
6963 (match_operand:SF 1 "general_operand" "r,mE,r"))]
6965 && TARGET_SOFT_FLOAT
6966 && (!MEM_P (operands[0])
6967 || register_operand (operands[1], SFmode))"
6970 ldr%?\\t%0, %1\\t%@ float
6971 str%?\\t%1, %0\\t%@ float"
6972 [(set_attr "predicable" "yes")
6973 (set_attr "predicable_short_it" "no")
6974 (set_attr "type" "mov_reg,load1,store1")
6975 (set_attr "arm_pool_range" "*,4096,*")
6976 (set_attr "thumb2_pool_range" "*,4094,*")
6977 (set_attr "arm_neg_pool_range" "*,4084,*")
6978 (set_attr "thumb2_neg_pool_range" "*,0,*")]
6981 (define_expand "movdf"
6982 [(set (match_operand:DF 0 "general_operand" "")
6983 (match_operand:DF 1 "general_operand" ""))]
6988 if (MEM_P (operands[0]))
6989 operands[1] = force_reg (DFmode, operands[1]);
6991 else /* TARGET_THUMB */
6993 if (can_create_pseudo_p ())
6995 if (!REG_P (operands[0]))
6996 operands[1] = force_reg (DFmode, operands[1]);
7002 ;; Reloading a df mode value stored in integer regs to memory can require a
7004 (define_expand "reload_outdf"
7005 [(match_operand:DF 0 "arm_reload_memory_operand" "=o")
7006 (match_operand:DF 1 "s_register_operand" "r")
7007 (match_operand:SI 2 "s_register_operand" "=&r")]
7011 enum rtx_code code = GET_CODE (XEXP (operands[0], 0));
7014 operands[2] = XEXP (operands[0], 0);
7015 else if (code == POST_INC || code == PRE_DEC)
7017 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7018 operands[1] = gen_rtx_SUBREG (DImode, operands[1], 0);
7019 emit_insn (gen_movdi (operands[0], operands[1]));
7022 else if (code == PRE_INC)
7024 rtx reg = XEXP (XEXP (operands[0], 0), 0);
7026 emit_insn (gen_addsi3 (reg, reg, GEN_INT (8)));
7029 else if (code == POST_DEC)
7030 operands[2] = XEXP (XEXP (operands[0], 0), 0);
7032 emit_insn (gen_addsi3 (operands[2], XEXP (XEXP (operands[0], 0), 0),
7033 XEXP (XEXP (operands[0], 0), 1)));
7035 emit_insn (gen_rtx_SET (replace_equiv_address (operands[0], operands[2]),
7038 if (code == POST_DEC)
7039 emit_insn (gen_addsi3 (operands[2], operands[2], GEN_INT (-8)));
7045 (define_insn "*movdf_soft_insn"
7046 [(set (match_operand:DF 0 "nonimmediate_soft_df_operand" "=r,r,r,q,m")
7047 (match_operand:DF 1 "soft_df_operand" "rDa,Db,Dc,mF,q"))]
7048 "TARGET_32BIT && TARGET_SOFT_FLOAT
7049 && ( register_operand (operands[0], DFmode)
7050 || register_operand (operands[1], DFmode))"
7052 switch (which_alternative)
7059 return output_move_double (operands, true, NULL);
7062 [(set_attr "length" "8,12,16,8,8")
7063 (set_attr "type" "multiple,multiple,multiple,load2,store2")
7064 (set_attr "arm_pool_range" "*,*,*,1020,*")
7065 (set_attr "thumb2_pool_range" "*,*,*,1018,*")
7066 (set_attr "arm_neg_pool_range" "*,*,*,1004,*")
7067 (set_attr "thumb2_neg_pool_range" "*,*,*,0,*")]
7071 ;; load- and store-multiple insns
7072 ;; The arm can load/store any set of registers, provided that they are in
7073 ;; ascending order, but these expanders assume a contiguous set.
7075 (define_expand "load_multiple"
7076 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
7077 (match_operand:SI 1 "" ""))
7078 (use (match_operand:SI 2 "" ""))])]
7081 HOST_WIDE_INT offset = 0;
7083 /* Support only fixed point registers. */
7084 if (!CONST_INT_P (operands[2])
7085 || INTVAL (operands[2]) > MAX_LDM_STM_OPS
7086 || INTVAL (operands[2]) < 2
7087 || !MEM_P (operands[1])
7088 || !REG_P (operands[0])
7089 || REGNO (operands[0]) > (LAST_ARM_REGNUM - 1)
7090 || REGNO (operands[0]) + INTVAL (operands[2]) > LAST_ARM_REGNUM)
7094 = arm_gen_load_multiple (arm_regs_in_sequence + REGNO (operands[0]),
7095 INTVAL (operands[2]),
7096 force_reg (SImode, XEXP (operands[1], 0)),
7097 FALSE, operands[1], &offset);
7100 (define_expand "store_multiple"
7101 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
7102 (match_operand:SI 1 "" ""))
7103 (use (match_operand:SI 2 "" ""))])]
7106 HOST_WIDE_INT offset = 0;
7108 /* Support only fixed point registers. */
7109 if (!CONST_INT_P (operands[2])
7110 || INTVAL (operands[2]) > MAX_LDM_STM_OPS
7111 || INTVAL (operands[2]) < 2
7112 || !REG_P (operands[1])
7113 || !MEM_P (operands[0])
7114 || REGNO (operands[1]) > (LAST_ARM_REGNUM - 1)
7115 || REGNO (operands[1]) + INTVAL (operands[2]) > LAST_ARM_REGNUM)
7119 = arm_gen_store_multiple (arm_regs_in_sequence + REGNO (operands[1]),
7120 INTVAL (operands[2]),
7121 force_reg (SImode, XEXP (operands[0], 0)),
7122 FALSE, operands[0], &offset);
7126 (define_expand "setmemsi"
7127 [(match_operand:BLK 0 "general_operand" "")
7128 (match_operand:SI 1 "const_int_operand" "")
7129 (match_operand:SI 2 "const_int_operand" "")
7130 (match_operand:SI 3 "const_int_operand" "")]
7133 if (arm_gen_setmem (operands))
7140 ;; Move a block of memory if it is word aligned and MORE than 2 words long.
7141 ;; We could let this apply for blocks of less than this, but it clobbers so
7142 ;; many registers that there is then probably a better way.
7144 (define_expand "movmemqi"
7145 [(match_operand:BLK 0 "general_operand" "")
7146 (match_operand:BLK 1 "general_operand" "")
7147 (match_operand:SI 2 "const_int_operand" "")
7148 (match_operand:SI 3 "const_int_operand" "")]
7153 if (TARGET_LDRD && current_tune->prefer_ldrd_strd
7154 && !optimize_function_for_size_p (cfun))
7156 if (gen_movmem_ldrd_strd (operands))
7161 if (arm_gen_movmemqi (operands))
7165 else /* TARGET_THUMB1 */
7167 if ( INTVAL (operands[3]) != 4
7168 || INTVAL (operands[2]) > 48)
7171 thumb_expand_movmemqi (operands);
7178 ;; Compare & branch insns
7179 ;; The range calculations are based as follows:
7180 ;; For forward branches, the address calculation returns the address of
7181 ;; the next instruction. This is 2 beyond the branch instruction.
7182 ;; For backward branches, the address calculation returns the address of
7183 ;; the first instruction in this pattern (cmp). This is 2 before the branch
7184 ;; instruction for the shortest sequence, and 4 before the branch instruction
7185 ;; if we have to jump around an unconditional branch.
7186 ;; To the basic branch range the PC offset must be added (this is +4).
7187 ;; So for forward branches we have
7188 ;; (pos_range - pos_base_offs + pc_offs) = (pos_range - 2 + 4).
7189 ;; And for backward branches we have
7190 ;; (neg_range - neg_base_offs + pc_offs) = (neg_range - (-2 or -4) + 4).
7192 ;; For a 'b' pos_range = 2046, neg_range = -2048 giving (-2040->2048).
7193 ;; For a 'b<cond>' pos_range = 254, neg_range = -256 giving (-250 ->256).
7195 (define_expand "cbranchsi4"
7196 [(set (pc) (if_then_else
7197 (match_operator 0 "expandable_comparison_operator"
7198 [(match_operand:SI 1 "s_register_operand" "")
7199 (match_operand:SI 2 "nonmemory_operand" "")])
7200 (label_ref (match_operand 3 "" ""))
7206 if (!arm_validize_comparison (&operands[0], &operands[1], &operands[2]))
7208 emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
7212 if (thumb1_cmpneg_operand (operands[2], SImode))
7214 emit_jump_insn (gen_cbranchsi4_scratch (NULL, operands[1], operands[2],
7215 operands[3], operands[0]));
7218 if (!thumb1_cmp_operand (operands[2], SImode))
7219 operands[2] = force_reg (SImode, operands[2]);
7222 (define_expand "cbranchsf4"
7223 [(set (pc) (if_then_else
7224 (match_operator 0 "expandable_comparison_operator"
7225 [(match_operand:SF 1 "s_register_operand" "")
7226 (match_operand:SF 2 "vfp_compare_operand" "")])
7227 (label_ref (match_operand 3 "" ""))
7229 "TARGET_32BIT && TARGET_HARD_FLOAT"
7230 "emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
7231 operands[3])); DONE;"
7234 (define_expand "cbranchdf4"
7235 [(set (pc) (if_then_else
7236 (match_operator 0 "expandable_comparison_operator"
7237 [(match_operand:DF 1 "s_register_operand" "")
7238 (match_operand:DF 2 "vfp_compare_operand" "")])
7239 (label_ref (match_operand 3 "" ""))
7241 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
7242 "emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
7243 operands[3])); DONE;"
7246 (define_expand "cbranchdi4"
7247 [(set (pc) (if_then_else
7248 (match_operator 0 "expandable_comparison_operator"
7249 [(match_operand:DI 1 "s_register_operand" "")
7250 (match_operand:DI 2 "cmpdi_operand" "")])
7251 (label_ref (match_operand 3 "" ""))
7255 if (!arm_validize_comparison (&operands[0], &operands[1], &operands[2]))
7257 emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
7263 ;; Comparison and test insns
7265 (define_insn "*arm_cmpsi_insn"
7266 [(set (reg:CC CC_REGNUM)
7267 (compare:CC (match_operand:SI 0 "s_register_operand" "l,r,r,r,r")
7268 (match_operand:SI 1 "arm_add_operand" "Py,r,r,I,L")))]
7276 [(set_attr "conds" "set")
7277 (set_attr "arch" "t2,t2,any,any,any")
7278 (set_attr "length" "2,2,4,4,4")
7279 (set_attr "predicable" "yes")
7280 (set_attr "predicable_short_it" "yes,yes,yes,no,no")
7281 (set_attr "type" "alus_imm,alus_sreg,alus_sreg,alus_imm,alus_imm")]
7284 (define_insn "*cmpsi_shiftsi"
7285 [(set (reg:CC CC_REGNUM)
7286 (compare:CC (match_operand:SI 0 "s_register_operand" "r,r,r")
7287 (match_operator:SI 3 "shift_operator"
7288 [(match_operand:SI 1 "s_register_operand" "r,r,r")
7289 (match_operand:SI 2 "shift_amount_operand" "M,r,M")])))]
7292 [(set_attr "conds" "set")
7293 (set_attr "shift" "1")
7294 (set_attr "arch" "32,a,a")
7295 (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
7297 (define_insn "*cmpsi_shiftsi_swp"
7298 [(set (reg:CC_SWP CC_REGNUM)
7299 (compare:CC_SWP (match_operator:SI 3 "shift_operator"
7300 [(match_operand:SI 1 "s_register_operand" "r,r,r")
7301 (match_operand:SI 2 "shift_amount_operand" "M,r,M")])
7302 (match_operand:SI 0 "s_register_operand" "r,r,r")))]
7305 [(set_attr "conds" "set")
7306 (set_attr "shift" "1")
7307 (set_attr "arch" "32,a,a")
7308 (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
7310 (define_insn "*arm_cmpsi_negshiftsi_si"
7311 [(set (reg:CC_Z CC_REGNUM)
7313 (neg:SI (match_operator:SI 1 "shift_operator"
7314 [(match_operand:SI 2 "s_register_operand" "r")
7315 (match_operand:SI 3 "reg_or_int_operand" "rM")]))
7316 (match_operand:SI 0 "s_register_operand" "r")))]
7319 [(set_attr "conds" "set")
7320 (set (attr "type") (if_then_else (match_operand 3 "const_int_operand" "")
7321 (const_string "alus_shift_imm")
7322 (const_string "alus_shift_reg")))
7323 (set_attr "predicable" "yes")]
7326 ;; DImode comparisons. The generic code generates branches that
7327 ;; if-conversion can not reduce to a conditional compare, so we do
7330 (define_insn_and_split "*arm_cmpdi_insn"
7331 [(set (reg:CC_NCV CC_REGNUM)
7332 (compare:CC_NCV (match_operand:DI 0 "s_register_operand" "r")
7333 (match_operand:DI 1 "arm_di_operand" "rDi")))
7334 (clobber (match_scratch:SI 2 "=r"))]
7336 "#" ; "cmp\\t%Q0, %Q1\;sbcs\\t%2, %R0, %R1"
7337 "&& reload_completed"
7338 [(set (reg:CC CC_REGNUM)
7339 (compare:CC (match_dup 0) (match_dup 1)))
7340 (parallel [(set (reg:CC CC_REGNUM)
7341 (compare:CC (match_dup 3) (match_dup 4)))
7343 (minus:SI (match_dup 5)
7344 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))])]
7346 operands[3] = gen_highpart (SImode, operands[0]);
7347 operands[0] = gen_lowpart (SImode, operands[0]);
7348 if (CONST_INT_P (operands[1]))
7350 operands[4] = GEN_INT (~INTVAL (gen_highpart_mode (SImode,
7353 operands[5] = gen_rtx_PLUS (SImode, operands[3], operands[4]);
7357 operands[4] = gen_highpart (SImode, operands[1]);
7358 operands[5] = gen_rtx_MINUS (SImode, operands[3], operands[4]);
7360 operands[1] = gen_lowpart (SImode, operands[1]);
7361 operands[2] = gen_lowpart (SImode, operands[2]);
7363 [(set_attr "conds" "set")
7364 (set_attr "length" "8")
7365 (set_attr "type" "multiple")]
7368 (define_insn_and_split "*arm_cmpdi_unsigned"
7369 [(set (reg:CC_CZ CC_REGNUM)
7370 (compare:CC_CZ (match_operand:DI 0 "s_register_operand" "l,r,r,r")
7371 (match_operand:DI 1 "arm_di_operand" "Py,r,Di,rDi")))]
7374 "#" ; "cmp\\t%R0, %R1\;it eq\;cmpeq\\t%Q0, %Q1"
7375 "&& reload_completed"
7376 [(set (reg:CC CC_REGNUM)
7377 (compare:CC (match_dup 2) (match_dup 3)))
7378 (cond_exec (eq:SI (reg:CC CC_REGNUM) (const_int 0))
7379 (set (reg:CC CC_REGNUM)
7380 (compare:CC (match_dup 0) (match_dup 1))))]
7382 operands[2] = gen_highpart (SImode, operands[0]);
7383 operands[0] = gen_lowpart (SImode, operands[0]);
7384 if (CONST_INT_P (operands[1]))
7385 operands[3] = gen_highpart_mode (SImode, DImode, operands[1]);
7387 operands[3] = gen_highpart (SImode, operands[1]);
7388 operands[1] = gen_lowpart (SImode, operands[1]);
7390 [(set_attr "conds" "set")
7391 (set_attr "enabled_for_depr_it" "yes,yes,no,*")
7392 (set_attr "arch" "t2,t2,t2,a")
7393 (set_attr "length" "6,6,10,8")
7394 (set_attr "type" "multiple")]
7397 (define_insn "*arm_cmpdi_zero"
7398 [(set (reg:CC_Z CC_REGNUM)
7399 (compare:CC_Z (match_operand:DI 0 "s_register_operand" "r")
7401 (clobber (match_scratch:SI 1 "=r"))]
7403 "orrs%?\\t%1, %Q0, %R0"
7404 [(set_attr "conds" "set")
7405 (set_attr "type" "logics_reg")]
7408 ; This insn allows redundant compares to be removed by cse, nothing should
7409 ; ever appear in the output file since (set (reg x) (reg x)) is a no-op that
7410 ; is deleted later on. The match_dup will match the mode here, so that
7411 ; mode changes of the condition codes aren't lost by this even though we don't
7412 ; specify what they are.
7414 (define_insn "*deleted_compare"
7415 [(set (match_operand 0 "cc_register" "") (match_dup 0))]
7417 "\\t%@ deleted compare"
7418 [(set_attr "conds" "set")
7419 (set_attr "length" "0")
7420 (set_attr "type" "no_insn")]
7424 ;; Conditional branch insns
7426 (define_expand "cbranch_cc"
7428 (if_then_else (match_operator 0 "" [(match_operand 1 "" "")
7429 (match_operand 2 "" "")])
7430 (label_ref (match_operand 3 "" ""))
7433 "operands[1] = arm_gen_compare_reg (GET_CODE (operands[0]),
7434 operands[1], operands[2], NULL_RTX);
7435 operands[2] = const0_rtx;"
7439 ;; Patterns to match conditional branch insns.
7442 (define_insn "arm_cond_branch"
7444 (if_then_else (match_operator 1 "arm_comparison_operator"
7445 [(match_operand 2 "cc_register" "") (const_int 0)])
7446 (label_ref (match_operand 0 "" ""))
7450 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
7452 arm_ccfsm_state += 2;
7455 return \"b%d1\\t%l0\";
7457 [(set_attr "conds" "use")
7458 (set_attr "type" "branch")
7459 (set (attr "length")
7461 (and (match_test "TARGET_THUMB2")
7462 (and (ge (minus (match_dup 0) (pc)) (const_int -250))
7463 (le (minus (match_dup 0) (pc)) (const_int 256))))
7468 (define_insn "*arm_cond_branch_reversed"
7470 (if_then_else (match_operator 1 "arm_comparison_operator"
7471 [(match_operand 2 "cc_register" "") (const_int 0)])
7473 (label_ref (match_operand 0 "" ""))))]
7476 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
7478 arm_ccfsm_state += 2;
7481 return \"b%D1\\t%l0\";
7483 [(set_attr "conds" "use")
7484 (set_attr "type" "branch")
7485 (set (attr "length")
7487 (and (match_test "TARGET_THUMB2")
7488 (and (ge (minus (match_dup 0) (pc)) (const_int -250))
7489 (le (minus (match_dup 0) (pc)) (const_int 256))))
7498 (define_expand "cstore_cc"
7499 [(set (match_operand:SI 0 "s_register_operand" "")
7500 (match_operator:SI 1 "" [(match_operand 2 "" "")
7501 (match_operand 3 "" "")]))]
7503 "operands[2] = arm_gen_compare_reg (GET_CODE (operands[1]),
7504 operands[2], operands[3], NULL_RTX);
7505 operands[3] = const0_rtx;"
7508 (define_insn_and_split "*mov_scc"
7509 [(set (match_operand:SI 0 "s_register_operand" "=r")
7510 (match_operator:SI 1 "arm_comparison_operator_mode"
7511 [(match_operand 2 "cc_register" "") (const_int 0)]))]
7513 "#" ; "mov%D1\\t%0, #0\;mov%d1\\t%0, #1"
7516 (if_then_else:SI (match_dup 1)
7520 [(set_attr "conds" "use")
7521 (set_attr "length" "8")
7522 (set_attr "type" "multiple")]
7525 (define_insn_and_split "*mov_negscc"
7526 [(set (match_operand:SI 0 "s_register_operand" "=r")
7527 (neg:SI (match_operator:SI 1 "arm_comparison_operator_mode"
7528 [(match_operand 2 "cc_register" "") (const_int 0)])))]
7530 "#" ; "mov%D1\\t%0, #0\;mvn%d1\\t%0, #0"
7533 (if_then_else:SI (match_dup 1)
7537 operands[3] = GEN_INT (~0);
7539 [(set_attr "conds" "use")
7540 (set_attr "length" "8")
7541 (set_attr "type" "multiple")]
7544 (define_insn_and_split "*mov_notscc"
7545 [(set (match_operand:SI 0 "s_register_operand" "=r")
7546 (not:SI (match_operator:SI 1 "arm_comparison_operator"
7547 [(match_operand 2 "cc_register" "") (const_int 0)])))]
7549 "#" ; "mvn%D1\\t%0, #0\;mvn%d1\\t%0, #1"
7552 (if_then_else:SI (match_dup 1)
7556 operands[3] = GEN_INT (~1);
7557 operands[4] = GEN_INT (~0);
7559 [(set_attr "conds" "use")
7560 (set_attr "length" "8")
7561 (set_attr "type" "multiple")]
7564 (define_expand "cstoresi4"
7565 [(set (match_operand:SI 0 "s_register_operand" "")
7566 (match_operator:SI 1 "expandable_comparison_operator"
7567 [(match_operand:SI 2 "s_register_operand" "")
7568 (match_operand:SI 3 "reg_or_int_operand" "")]))]
7569 "TARGET_32BIT || TARGET_THUMB1"
7571 rtx op3, scratch, scratch2;
7575 if (!arm_add_operand (operands[3], SImode))
7576 operands[3] = force_reg (SImode, operands[3]);
7577 emit_insn (gen_cstore_cc (operands[0], operands[1],
7578 operands[2], operands[3]));
7582 if (operands[3] == const0_rtx)
7584 switch (GET_CODE (operands[1]))
7587 emit_insn (gen_cstoresi_eq0_thumb1 (operands[0], operands[2]));
7591 emit_insn (gen_cstoresi_ne0_thumb1 (operands[0], operands[2]));
7595 scratch = expand_binop (SImode, add_optab, operands[2], constm1_rtx,
7596 NULL_RTX, 0, OPTAB_WIDEN);
7597 scratch = expand_binop (SImode, ior_optab, operands[2], scratch,
7598 NULL_RTX, 0, OPTAB_WIDEN);
7599 expand_binop (SImode, lshr_optab, scratch, GEN_INT (31),
7600 operands[0], 1, OPTAB_WIDEN);
7604 scratch = expand_unop (SImode, one_cmpl_optab, operands[2],
7606 expand_binop (SImode, lshr_optab, scratch, GEN_INT (31),
7607 NULL_RTX, 1, OPTAB_WIDEN);
7611 scratch = expand_binop (SImode, ashr_optab, operands[2],
7612 GEN_INT (31), NULL_RTX, 0, OPTAB_WIDEN);
7613 scratch = expand_binop (SImode, sub_optab, scratch, operands[2],
7614 NULL_RTX, 0, OPTAB_WIDEN);
7615 expand_binop (SImode, lshr_optab, scratch, GEN_INT (31), operands[0],
7619 /* LT is handled by generic code. No need for unsigned with 0. */
7626 switch (GET_CODE (operands[1]))
7629 scratch = expand_binop (SImode, sub_optab, operands[2], operands[3],
7630 NULL_RTX, 0, OPTAB_WIDEN);
7631 emit_insn (gen_cstoresi_eq0_thumb1 (operands[0], scratch));
7635 scratch = expand_binop (SImode, sub_optab, operands[2], operands[3],
7636 NULL_RTX, 0, OPTAB_WIDEN);
7637 emit_insn (gen_cstoresi_ne0_thumb1 (operands[0], scratch));
7641 op3 = force_reg (SImode, operands[3]);
7643 scratch = expand_binop (SImode, lshr_optab, operands[2], GEN_INT (31),
7644 NULL_RTX, 1, OPTAB_WIDEN);
7645 scratch2 = expand_binop (SImode, ashr_optab, op3, GEN_INT (31),
7646 NULL_RTX, 0, OPTAB_WIDEN);
7647 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch2,
7653 if (!thumb1_cmp_operand (op3, SImode))
7654 op3 = force_reg (SImode, op3);
7655 scratch = expand_binop (SImode, ashr_optab, operands[2], GEN_INT (31),
7656 NULL_RTX, 0, OPTAB_WIDEN);
7657 scratch2 = expand_binop (SImode, lshr_optab, op3, GEN_INT (31),
7658 NULL_RTX, 1, OPTAB_WIDEN);
7659 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch2,
7664 op3 = force_reg (SImode, operands[3]);
7665 scratch = force_reg (SImode, const0_rtx);
7666 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch,
7672 if (!thumb1_cmp_operand (op3, SImode))
7673 op3 = force_reg (SImode, op3);
7674 scratch = force_reg (SImode, const0_rtx);
7675 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch,
7681 if (!thumb1_cmp_operand (op3, SImode))
7682 op3 = force_reg (SImode, op3);
7683 scratch = gen_reg_rtx (SImode);
7684 emit_insn (gen_cstoresi_ltu_thumb1 (operands[0], operands[2], op3));
7688 op3 = force_reg (SImode, operands[3]);
7689 scratch = gen_reg_rtx (SImode);
7690 emit_insn (gen_cstoresi_ltu_thumb1 (operands[0], op3, operands[2]));
7693 /* No good sequences for GT, LT. */
7700 (define_expand "cstorehf4"
7701 [(set (match_operand:SI 0 "s_register_operand")
7702 (match_operator:SI 1 "expandable_comparison_operator"
7703 [(match_operand:HF 2 "s_register_operand")
7704 (match_operand:HF 3 "vfp_compare_operand")]))]
7705 "TARGET_VFP_FP16INST"
7707 if (!arm_validize_comparison (&operands[1],
7712 emit_insn (gen_cstore_cc (operands[0], operands[1],
7713 operands[2], operands[3]));
7718 (define_expand "cstoresf4"
7719 [(set (match_operand:SI 0 "s_register_operand" "")
7720 (match_operator:SI 1 "expandable_comparison_operator"
7721 [(match_operand:SF 2 "s_register_operand" "")
7722 (match_operand:SF 3 "vfp_compare_operand" "")]))]
7723 "TARGET_32BIT && TARGET_HARD_FLOAT"
7724 "emit_insn (gen_cstore_cc (operands[0], operands[1],
7725 operands[2], operands[3])); DONE;"
7728 (define_expand "cstoredf4"
7729 [(set (match_operand:SI 0 "s_register_operand" "")
7730 (match_operator:SI 1 "expandable_comparison_operator"
7731 [(match_operand:DF 2 "s_register_operand" "")
7732 (match_operand:DF 3 "vfp_compare_operand" "")]))]
7733 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
7734 "emit_insn (gen_cstore_cc (operands[0], operands[1],
7735 operands[2], operands[3])); DONE;"
7738 (define_expand "cstoredi4"
7739 [(set (match_operand:SI 0 "s_register_operand" "")
7740 (match_operator:SI 1 "expandable_comparison_operator"
7741 [(match_operand:DI 2 "s_register_operand" "")
7742 (match_operand:DI 3 "cmpdi_operand" "")]))]
7745 if (!arm_validize_comparison (&operands[1],
7749 emit_insn (gen_cstore_cc (operands[0], operands[1], operands[2],
7756 ;; Conditional move insns
7758 (define_expand "movsicc"
7759 [(set (match_operand:SI 0 "s_register_operand" "")
7760 (if_then_else:SI (match_operand 1 "expandable_comparison_operator" "")
7761 (match_operand:SI 2 "arm_not_operand" "")
7762 (match_operand:SI 3 "arm_not_operand" "")))]
7769 if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
7770 &XEXP (operands[1], 1)))
7773 code = GET_CODE (operands[1]);
7774 ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
7775 XEXP (operands[1], 1), NULL_RTX);
7776 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7780 (define_expand "movhfcc"
7781 [(set (match_operand:HF 0 "s_register_operand")
7782 (if_then_else:HF (match_operand 1 "arm_cond_move_operator")
7783 (match_operand:HF 2 "s_register_operand")
7784 (match_operand:HF 3 "s_register_operand")))]
7785 "TARGET_VFP_FP16INST"
7788 enum rtx_code code = GET_CODE (operands[1]);
7791 if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
7792 &XEXP (operands[1], 1)))
7795 code = GET_CODE (operands[1]);
7796 ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
7797 XEXP (operands[1], 1), NULL_RTX);
7798 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7802 (define_expand "movsfcc"
7803 [(set (match_operand:SF 0 "s_register_operand" "")
7804 (if_then_else:SF (match_operand 1 "arm_cond_move_operator" "")
7805 (match_operand:SF 2 "s_register_operand" "")
7806 (match_operand:SF 3 "s_register_operand" "")))]
7807 "TARGET_32BIT && TARGET_HARD_FLOAT"
7810 enum rtx_code code = GET_CODE (operands[1]);
7813 if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
7814 &XEXP (operands[1], 1)))
7817 code = GET_CODE (operands[1]);
7818 ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
7819 XEXP (operands[1], 1), NULL_RTX);
7820 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7824 (define_expand "movdfcc"
7825 [(set (match_operand:DF 0 "s_register_operand" "")
7826 (if_then_else:DF (match_operand 1 "arm_cond_move_operator" "")
7827 (match_operand:DF 2 "s_register_operand" "")
7828 (match_operand:DF 3 "s_register_operand" "")))]
7829 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
7832 enum rtx_code code = GET_CODE (operands[1]);
7835 if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
7836 &XEXP (operands[1], 1)))
7838 code = GET_CODE (operands[1]);
7839 ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
7840 XEXP (operands[1], 1), NULL_RTX);
7841 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7845 (define_insn "*cmov<mode>"
7846 [(set (match_operand:SDF 0 "s_register_operand" "=<F_constraint>")
7847 (if_then_else:SDF (match_operator 1 "arm_vsel_comparison_operator"
7848 [(match_operand 2 "cc_register" "") (const_int 0)])
7849 (match_operand:SDF 3 "s_register_operand"
7851 (match_operand:SDF 4 "s_register_operand"
7852 "<F_constraint>")))]
7853 "TARGET_HARD_FLOAT && TARGET_FPU_ARMV8 <vfp_double_cond>"
7856 enum arm_cond_code code = maybe_get_arm_condition_code (operands[1]);
7863 return \"vsel%d1.<V_if_elem>\\t%<V_reg>0, %<V_reg>3, %<V_reg>4\";
7868 return \"vsel%D1.<V_if_elem>\\t%<V_reg>0, %<V_reg>4, %<V_reg>3\";
7874 [(set_attr "conds" "use")
7875 (set_attr "type" "fcsel")]
7878 (define_insn "*cmovhf"
7879 [(set (match_operand:HF 0 "s_register_operand" "=t")
7880 (if_then_else:HF (match_operator 1 "arm_vsel_comparison_operator"
7881 [(match_operand 2 "cc_register" "") (const_int 0)])
7882 (match_operand:HF 3 "s_register_operand" "t")
7883 (match_operand:HF 4 "s_register_operand" "t")))]
7884 "TARGET_VFP_FP16INST"
7887 enum arm_cond_code code = maybe_get_arm_condition_code (operands[1]);
7894 return \"vsel%d1.f16\\t%0, %3, %4\";
7899 return \"vsel%D1.f16\\t%0, %4, %3\";
7905 [(set_attr "conds" "use")
7906 (set_attr "type" "fcsel")]
7909 (define_insn_and_split "*movsicc_insn"
7910 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r,r,r,r,r")
7912 (match_operator 3 "arm_comparison_operator"
7913 [(match_operand 4 "cc_register" "") (const_int 0)])
7914 (match_operand:SI 1 "arm_not_operand" "0,0,rI,K,rI,rI,K,K")
7915 (match_operand:SI 2 "arm_not_operand" "rI,K,0,0,rI,K,rI,K")))]
7926 ; alt4: mov%d3\\t%0, %1\;mov%D3\\t%0, %2
7927 ; alt5: mov%d3\\t%0, %1\;mvn%D3\\t%0, #%B2
7928 ; alt6: mvn%d3\\t%0, #%B1\;mov%D3\\t%0, %2
7929 ; alt7: mvn%d3\\t%0, #%B1\;mvn%D3\\t%0, #%B2"
7930 "&& reload_completed"
7933 enum rtx_code rev_code;
7937 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
7939 gen_rtx_SET (operands[0], operands[1])));
7941 rev_code = GET_CODE (operands[3]);
7942 mode = GET_MODE (operands[4]);
7943 if (mode == CCFPmode || mode == CCFPEmode)
7944 rev_code = reverse_condition_maybe_unordered (rev_code);
7946 rev_code = reverse_condition (rev_code);
7948 rev_cond = gen_rtx_fmt_ee (rev_code,
7952 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
7954 gen_rtx_SET (operands[0], operands[2])));
7957 [(set_attr "length" "4,4,4,4,8,8,8,8")
7958 (set_attr "conds" "use")
7959 (set_attr_alternative "type"
7960 [(if_then_else (match_operand 2 "const_int_operand" "")
7961 (const_string "mov_imm")
7962 (const_string "mov_reg"))
7963 (const_string "mvn_imm")
7964 (if_then_else (match_operand 1 "const_int_operand" "")
7965 (const_string "mov_imm")
7966 (const_string "mov_reg"))
7967 (const_string "mvn_imm")
7968 (const_string "multiple")
7969 (const_string "multiple")
7970 (const_string "multiple")
7971 (const_string "multiple")])]
7974 (define_insn "*movsfcc_soft_insn"
7975 [(set (match_operand:SF 0 "s_register_operand" "=r,r")
7976 (if_then_else:SF (match_operator 3 "arm_comparison_operator"
7977 [(match_operand 4 "cc_register" "") (const_int 0)])
7978 (match_operand:SF 1 "s_register_operand" "0,r")
7979 (match_operand:SF 2 "s_register_operand" "r,0")))]
7980 "TARGET_ARM && TARGET_SOFT_FLOAT"
7984 [(set_attr "conds" "use")
7985 (set_attr "type" "mov_reg")]
7989 ;; Jump and linkage insns
7991 (define_expand "jump"
7993 (label_ref (match_operand 0 "" "")))]
7998 (define_insn "*arm_jump"
8000 (label_ref (match_operand 0 "" "")))]
8004 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
8006 arm_ccfsm_state += 2;
8009 return \"b%?\\t%l0\";
8012 [(set_attr "predicable" "yes")
8013 (set (attr "length")
8015 (and (match_test "TARGET_THUMB2")
8016 (and (ge (minus (match_dup 0) (pc)) (const_int -2044))
8017 (le (minus (match_dup 0) (pc)) (const_int 2048))))
8020 (set_attr "type" "branch")]
8023 (define_expand "call"
8024 [(parallel [(call (match_operand 0 "memory_operand" "")
8025 (match_operand 1 "general_operand" ""))
8026 (use (match_operand 2 "" ""))
8027 (clobber (reg:SI LR_REGNUM))])]
8033 /* In an untyped call, we can get NULL for operand 2. */
8034 if (operands[2] == NULL_RTX)
8035 operands[2] = const0_rtx;
8037 /* Decide if we should generate indirect calls by loading the
8038 32-bit address of the callee into a register before performing the
8040 callee = XEXP (operands[0], 0);
8041 if (GET_CODE (callee) == SYMBOL_REF
8042 ? arm_is_long_call_p (SYMBOL_REF_DECL (callee))
8044 XEXP (operands[0], 0) = force_reg (Pmode, callee);
8046 pat = gen_call_internal (operands[0], operands[1], operands[2]);
8047 arm_emit_call_insn (pat, XEXP (operands[0], 0), false);
8052 (define_expand "call_internal"
8053 [(parallel [(call (match_operand 0 "memory_operand" "")
8054 (match_operand 1 "general_operand" ""))
8055 (use (match_operand 2 "" ""))
8056 (clobber (reg:SI LR_REGNUM))])])
8058 (define_insn "*call_reg_armv5"
8059 [(call (mem:SI (match_operand:SI 0 "s_register_operand" "r"))
8060 (match_operand 1 "" ""))
8061 (use (match_operand 2 "" ""))
8062 (clobber (reg:SI LR_REGNUM))]
8063 "TARGET_ARM && arm_arch5 && !SIBLING_CALL_P (insn)"
8065 [(set_attr "type" "call")]
8068 (define_insn "*call_reg_arm"
8069 [(call (mem:SI (match_operand:SI 0 "s_register_operand" "r"))
8070 (match_operand 1 "" ""))
8071 (use (match_operand 2 "" ""))
8072 (clobber (reg:SI LR_REGNUM))]
8073 "TARGET_ARM && !arm_arch5 && !SIBLING_CALL_P (insn)"
8075 return output_call (operands);
8077 ;; length is worst case, normally it is only two
8078 [(set_attr "length" "12")
8079 (set_attr "type" "call")]
8083 (define_expand "call_value"
8084 [(parallel [(set (match_operand 0 "" "")
8085 (call (match_operand 1 "memory_operand" "")
8086 (match_operand 2 "general_operand" "")))
8087 (use (match_operand 3 "" ""))
8088 (clobber (reg:SI LR_REGNUM))])]
8094 /* In an untyped call, we can get NULL for operand 2. */
8095 if (operands[3] == 0)
8096 operands[3] = const0_rtx;
8098 /* Decide if we should generate indirect calls by loading the
8099 32-bit address of the callee into a register before performing the
8101 callee = XEXP (operands[1], 0);
8102 if (GET_CODE (callee) == SYMBOL_REF
8103 ? arm_is_long_call_p (SYMBOL_REF_DECL (callee))
8105 XEXP (operands[1], 0) = force_reg (Pmode, callee);
8107 pat = gen_call_value_internal (operands[0], operands[1],
8108 operands[2], operands[3]);
8109 arm_emit_call_insn (pat, XEXP (operands[1], 0), false);
8114 (define_expand "call_value_internal"
8115 [(parallel [(set (match_operand 0 "" "")
8116 (call (match_operand 1 "memory_operand" "")
8117 (match_operand 2 "general_operand" "")))
8118 (use (match_operand 3 "" ""))
8119 (clobber (reg:SI LR_REGNUM))])])
8121 (define_insn "*call_value_reg_armv5"
8122 [(set (match_operand 0 "" "")
8123 (call (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
8124 (match_operand 2 "" "")))
8125 (use (match_operand 3 "" ""))
8126 (clobber (reg:SI LR_REGNUM))]
8127 "TARGET_ARM && arm_arch5 && !SIBLING_CALL_P (insn)"
8129 [(set_attr "type" "call")]
8132 (define_insn "*call_value_reg_arm"
8133 [(set (match_operand 0 "" "")
8134 (call (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
8135 (match_operand 2 "" "")))
8136 (use (match_operand 3 "" ""))
8137 (clobber (reg:SI LR_REGNUM))]
8138 "TARGET_ARM && !arm_arch5 && !SIBLING_CALL_P (insn)"
8140 return output_call (&operands[1]);
8142 [(set_attr "length" "12")
8143 (set_attr "type" "call")]
8146 ;; Allow calls to SYMBOL_REFs specially as they are not valid general addresses
8147 ;; The 'a' causes the operand to be treated as an address, i.e. no '#' output.
8149 (define_insn "*call_symbol"
8150 [(call (mem:SI (match_operand:SI 0 "" ""))
8151 (match_operand 1 "" ""))
8152 (use (match_operand 2 "" ""))
8153 (clobber (reg:SI LR_REGNUM))]
8155 && !SIBLING_CALL_P (insn)
8156 && (GET_CODE (operands[0]) == SYMBOL_REF)
8157 && !arm_is_long_call_p (SYMBOL_REF_DECL (operands[0]))"
8160 rtx op = operands[0];
8162 /* Switch mode now when possible. */
8163 if (SYMBOL_REF_DECL (op) && !TREE_PUBLIC (SYMBOL_REF_DECL (op))
8164 && arm_arch5 && arm_change_mode_p (SYMBOL_REF_DECL (op)))
8165 return NEED_PLT_RELOC ? \"blx%?\\t%a0(PLT)\" : \"blx%?\\t(%a0)\";
8167 return NEED_PLT_RELOC ? \"bl%?\\t%a0(PLT)\" : \"bl%?\\t%a0\";
8169 [(set_attr "type" "call")]
8172 (define_insn "*call_value_symbol"
8173 [(set (match_operand 0 "" "")
8174 (call (mem:SI (match_operand:SI 1 "" ""))
8175 (match_operand:SI 2 "" "")))
8176 (use (match_operand 3 "" ""))
8177 (clobber (reg:SI LR_REGNUM))]
8179 && !SIBLING_CALL_P (insn)
8180 && (GET_CODE (operands[1]) == SYMBOL_REF)
8181 && !arm_is_long_call_p (SYMBOL_REF_DECL (operands[1]))"
8184 rtx op = operands[1];
8186 /* Switch mode now when possible. */
8187 if (SYMBOL_REF_DECL (op) && !TREE_PUBLIC (SYMBOL_REF_DECL (op))
8188 && arm_arch5 && arm_change_mode_p (SYMBOL_REF_DECL (op)))
8189 return NEED_PLT_RELOC ? \"blx%?\\t%a1(PLT)\" : \"blx%?\\t(%a1)\";
8191 return NEED_PLT_RELOC ? \"bl%?\\t%a1(PLT)\" : \"bl%?\\t%a1\";
8193 [(set_attr "type" "call")]
8196 (define_expand "sibcall_internal"
8197 [(parallel [(call (match_operand 0 "memory_operand" "")
8198 (match_operand 1 "general_operand" ""))
8200 (use (match_operand 2 "" ""))])])
8202 ;; We may also be able to do sibcalls for Thumb, but it's much harder...
8203 (define_expand "sibcall"
8204 [(parallel [(call (match_operand 0 "memory_operand" "")
8205 (match_operand 1 "general_operand" ""))
8207 (use (match_operand 2 "" ""))])]
8213 if ((!REG_P (XEXP (operands[0], 0))
8214 && GET_CODE (XEXP (operands[0], 0)) != SYMBOL_REF)
8215 || (GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
8216 && arm_is_long_call_p (SYMBOL_REF_DECL (XEXP (operands[0], 0)))))
8217 XEXP (operands[0], 0) = force_reg (SImode, XEXP (operands[0], 0));
8219 if (operands[2] == NULL_RTX)
8220 operands[2] = const0_rtx;
8222 pat = gen_sibcall_internal (operands[0], operands[1], operands[2]);
8223 arm_emit_call_insn (pat, operands[0], true);
8228 (define_expand "sibcall_value_internal"
8229 [(parallel [(set (match_operand 0 "" "")
8230 (call (match_operand 1 "memory_operand" "")
8231 (match_operand 2 "general_operand" "")))
8233 (use (match_operand 3 "" ""))])])
8235 (define_expand "sibcall_value"
8236 [(parallel [(set (match_operand 0 "" "")
8237 (call (match_operand 1 "memory_operand" "")
8238 (match_operand 2 "general_operand" "")))
8240 (use (match_operand 3 "" ""))])]
8246 if ((!REG_P (XEXP (operands[1], 0))
8247 && GET_CODE (XEXP (operands[1], 0)) != SYMBOL_REF)
8248 || (GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
8249 && arm_is_long_call_p (SYMBOL_REF_DECL (XEXP (operands[1], 0)))))
8250 XEXP (operands[1], 0) = force_reg (SImode, XEXP (operands[1], 0));
8252 if (operands[3] == NULL_RTX)
8253 operands[3] = const0_rtx;
8255 pat = gen_sibcall_value_internal (operands[0], operands[1],
8256 operands[2], operands[3]);
8257 arm_emit_call_insn (pat, operands[1], true);
8262 (define_insn "*sibcall_insn"
8263 [(call (mem:SI (match_operand:SI 0 "call_insn_operand" "Cs, US"))
8264 (match_operand 1 "" ""))
8266 (use (match_operand 2 "" ""))]
8267 "TARGET_32BIT && SIBLING_CALL_P (insn)"
8269 if (which_alternative == 1)
8270 return NEED_PLT_RELOC ? \"b%?\\t%a0(PLT)\" : \"b%?\\t%a0\";
8273 if (arm_arch5 || arm_arch4t)
8274 return \"bx%?\\t%0\\t%@ indirect register sibling call\";
8276 return \"mov%?\\t%|pc, %0\\t%@ indirect register sibling call\";
8279 [(set_attr "type" "call")]
8282 (define_insn "*sibcall_value_insn"
8283 [(set (match_operand 0 "" "")
8284 (call (mem:SI (match_operand:SI 1 "call_insn_operand" "Cs,US"))
8285 (match_operand 2 "" "")))
8287 (use (match_operand 3 "" ""))]
8288 "TARGET_32BIT && SIBLING_CALL_P (insn)"
8290 if (which_alternative == 1)
8291 return NEED_PLT_RELOC ? \"b%?\\t%a1(PLT)\" : \"b%?\\t%a1\";
8294 if (arm_arch5 || arm_arch4t)
8295 return \"bx%?\\t%1\";
8297 return \"mov%?\\t%|pc, %1\\t@ indirect sibling call \";
8300 [(set_attr "type" "call")]
8303 (define_expand "<return_str>return"
8305 "(TARGET_ARM || (TARGET_THUMB2
8306 && ARM_FUNC_TYPE (arm_current_func_type ()) == ARM_FT_NORMAL
8307 && !IS_STACKALIGN (arm_current_func_type ())))
8308 <return_cond_false>"
8313 thumb2_expand_return (<return_simple_p>);
8320 ;; Often the return insn will be the same as loading from memory, so set attr
8321 (define_insn "*arm_return"
8323 "TARGET_ARM && USE_RETURN_INSN (FALSE)"
8326 if (arm_ccfsm_state == 2)
8328 arm_ccfsm_state += 2;
8331 return output_return_instruction (const_true_rtx, true, false, false);
8333 [(set_attr "type" "load1")
8334 (set_attr "length" "12")
8335 (set_attr "predicable" "yes")]
8338 (define_insn "*cond_<return_str>return"
8340 (if_then_else (match_operator 0 "arm_comparison_operator"
8341 [(match_operand 1 "cc_register" "") (const_int 0)])
8344 "TARGET_ARM <return_cond_true>"
8347 if (arm_ccfsm_state == 2)
8349 arm_ccfsm_state += 2;
8352 return output_return_instruction (operands[0], true, false,
8355 [(set_attr "conds" "use")
8356 (set_attr "length" "12")
8357 (set_attr "type" "load1")]
8360 (define_insn "*cond_<return_str>return_inverted"
8362 (if_then_else (match_operator 0 "arm_comparison_operator"
8363 [(match_operand 1 "cc_register" "") (const_int 0)])
8366 "TARGET_ARM <return_cond_true>"
8369 if (arm_ccfsm_state == 2)
8371 arm_ccfsm_state += 2;
8374 return output_return_instruction (operands[0], true, true,
8377 [(set_attr "conds" "use")
8378 (set_attr "length" "12")
8379 (set_attr "type" "load1")]
8382 (define_insn "*arm_simple_return"
8387 if (arm_ccfsm_state == 2)
8389 arm_ccfsm_state += 2;
8392 return output_return_instruction (const_true_rtx, true, false, true);
8394 [(set_attr "type" "branch")
8395 (set_attr "length" "4")
8396 (set_attr "predicable" "yes")]
8399 ;; Generate a sequence of instructions to determine if the processor is
8400 ;; in 26-bit or 32-bit mode, and return the appropriate return address
8403 (define_expand "return_addr_mask"
8405 (compare:CC_NOOV (unspec [(const_int 0)] UNSPEC_CHECK_ARCH)
8407 (set (match_operand:SI 0 "s_register_operand" "")
8408 (if_then_else:SI (eq (match_dup 1) (const_int 0))
8410 (const_int 67108860)))] ; 0x03fffffc
8413 operands[1] = gen_rtx_REG (CC_NOOVmode, CC_REGNUM);
8416 (define_insn "*check_arch2"
8417 [(set (match_operand:CC_NOOV 0 "cc_register" "")
8418 (compare:CC_NOOV (unspec [(const_int 0)] UNSPEC_CHECK_ARCH)
8421 "teq\\t%|r0, %|r0\;teq\\t%|pc, %|pc"
8422 [(set_attr "length" "8")
8423 (set_attr "conds" "set")
8424 (set_attr "type" "multiple")]
8427 ;; Call subroutine returning any type.
8429 (define_expand "untyped_call"
8430 [(parallel [(call (match_operand 0 "" "")
8432 (match_operand 1 "" "")
8433 (match_operand 2 "" "")])]
8438 rtx par = gen_rtx_PARALLEL (VOIDmode,
8439 rtvec_alloc (XVECLEN (operands[2], 0)));
8440 rtx addr = gen_reg_rtx (Pmode);
8444 emit_move_insn (addr, XEXP (operands[1], 0));
8445 mem = change_address (operands[1], BLKmode, addr);
8447 for (i = 0; i < XVECLEN (operands[2], 0); i++)
8449 rtx src = SET_SRC (XVECEXP (operands[2], 0, i));
8451 /* Default code only uses r0 as a return value, but we could
8452 be using anything up to 4 registers. */
8453 if (REGNO (src) == R0_REGNUM)
8454 src = gen_rtx_REG (TImode, R0_REGNUM);
8456 XVECEXP (par, 0, i) = gen_rtx_EXPR_LIST (VOIDmode, src,
8458 size += GET_MODE_SIZE (GET_MODE (src));
8461 emit_call_insn (gen_call_value (par, operands[0], const0_rtx, NULL));
8465 for (i = 0; i < XVECLEN (par, 0); i++)
8467 HOST_WIDE_INT offset = 0;
8468 rtx reg = XEXP (XVECEXP (par, 0, i), 0);
8471 emit_move_insn (addr, plus_constant (Pmode, addr, size));
8473 mem = change_address (mem, GET_MODE (reg), NULL);
8474 if (REGNO (reg) == R0_REGNUM)
8476 /* On thumb we have to use a write-back instruction. */
8477 emit_insn (arm_gen_store_multiple (arm_regs_in_sequence, 4, addr,
8478 TARGET_THUMB ? TRUE : FALSE, mem, &offset));
8479 size = TARGET_ARM ? 16 : 0;
8483 emit_move_insn (mem, reg);
8484 size = GET_MODE_SIZE (GET_MODE (reg));
8488 /* The optimizer does not know that the call sets the function value
8489 registers we stored in the result block. We avoid problems by
8490 claiming that all hard registers are used and clobbered at this
8492 emit_insn (gen_blockage ());
8498 (define_expand "untyped_return"
8499 [(match_operand:BLK 0 "memory_operand" "")
8500 (match_operand 1 "" "")]
8505 rtx addr = gen_reg_rtx (Pmode);
8509 emit_move_insn (addr, XEXP (operands[0], 0));
8510 mem = change_address (operands[0], BLKmode, addr);
8512 for (i = 0; i < XVECLEN (operands[1], 0); i++)
8514 HOST_WIDE_INT offset = 0;
8515 rtx reg = SET_DEST (XVECEXP (operands[1], 0, i));
8518 emit_move_insn (addr, plus_constant (Pmode, addr, size));
8520 mem = change_address (mem, GET_MODE (reg), NULL);
8521 if (REGNO (reg) == R0_REGNUM)
8523 /* On thumb we have to use a write-back instruction. */
8524 emit_insn (arm_gen_load_multiple (arm_regs_in_sequence, 4, addr,
8525 TARGET_THUMB ? TRUE : FALSE, mem, &offset));
8526 size = TARGET_ARM ? 16 : 0;
8530 emit_move_insn (reg, mem);
8531 size = GET_MODE_SIZE (GET_MODE (reg));
8535 /* Emit USE insns before the return. */
8536 for (i = 0; i < XVECLEN (operands[1], 0); i++)
8537 emit_use (SET_DEST (XVECEXP (operands[1], 0, i)));
8539 /* Construct the return. */
8540 expand_naked_return ();
8546 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
8547 ;; all of memory. This blocks insns from being moved across this point.
8549 (define_insn "blockage"
8550 [(unspec_volatile [(const_int 0)] VUNSPEC_BLOCKAGE)]
8553 [(set_attr "length" "0")
8554 (set_attr "type" "block")]
8557 (define_insn "probe_stack"
8558 [(set (match_operand:SI 0 "memory_operand" "=m")
8559 (unspec:SI [(const_int 0)] UNSPEC_PROBE_STACK))]
8562 [(set_attr "type" "store1")
8563 (set_attr "predicable" "yes")]
8566 (define_insn "probe_stack_range"
8567 [(set (match_operand:SI 0 "register_operand" "=r")
8568 (unspec_volatile:SI [(match_operand:SI 1 "register_operand" "0")
8569 (match_operand:SI 2 "register_operand" "r")]
8570 VUNSPEC_PROBE_STACK_RANGE))]
8573 return output_probe_stack_range (operands[0], operands[2]);
8575 [(set_attr "type" "multiple")
8576 (set_attr "conds" "clob")]
8579 (define_expand "casesi"
8580 [(match_operand:SI 0 "s_register_operand" "") ; index to jump on
8581 (match_operand:SI 1 "const_int_operand" "") ; lower bound
8582 (match_operand:SI 2 "const_int_operand" "") ; total range
8583 (match_operand:SI 3 "" "") ; table label
8584 (match_operand:SI 4 "" "")] ; Out of range label
8585 "(TARGET_32BIT || optimize_size || flag_pic) && !target_pure_code"
8588 enum insn_code code;
8589 if (operands[1] != const0_rtx)
8591 rtx reg = gen_reg_rtx (SImode);
8593 emit_insn (gen_addsi3 (reg, operands[0],
8594 gen_int_mode (-INTVAL (operands[1]),
8600 code = CODE_FOR_arm_casesi_internal;
8601 else if (TARGET_THUMB1)
8602 code = CODE_FOR_thumb1_casesi_internal_pic;
8604 code = CODE_FOR_thumb2_casesi_internal_pic;
8606 code = CODE_FOR_thumb2_casesi_internal;
8608 if (!insn_data[(int) code].operand[1].predicate(operands[2], SImode))
8609 operands[2] = force_reg (SImode, operands[2]);
8611 emit_jump_insn (GEN_FCN ((int) code) (operands[0], operands[2],
8612 operands[3], operands[4]));
8617 ;; The USE in this pattern is needed to tell flow analysis that this is
8618 ;; a CASESI insn. It has no other purpose.
8619 (define_insn "arm_casesi_internal"
8620 [(parallel [(set (pc)
8622 (leu (match_operand:SI 0 "s_register_operand" "r")
8623 (match_operand:SI 1 "arm_rhs_operand" "rI"))
8624 (mem:SI (plus:SI (mult:SI (match_dup 0) (const_int 4))
8625 (label_ref (match_operand 2 "" ""))))
8626 (label_ref (match_operand 3 "" ""))))
8627 (clobber (reg:CC CC_REGNUM))
8628 (use (label_ref (match_dup 2)))])]
8632 return \"cmp\\t%0, %1\;addls\\t%|pc, %|pc, %0, asl #2\;b\\t%l3\";
8633 return \"cmp\\t%0, %1\;ldrls\\t%|pc, [%|pc, %0, asl #2]\;b\\t%l3\";
8635 [(set_attr "conds" "clob")
8636 (set_attr "length" "12")
8637 (set_attr "type" "multiple")]
8640 (define_expand "indirect_jump"
8642 (match_operand:SI 0 "s_register_operand" ""))]
8645 /* Thumb-2 doesn't have mov pc, reg. Explicitly set the low bit of the
8646 address and use bx. */
8650 tmp = gen_reg_rtx (SImode);
8651 emit_insn (gen_iorsi3 (tmp, operands[0], GEN_INT(1)));
8657 ;; NB Never uses BX.
8658 (define_insn "*arm_indirect_jump"
8660 (match_operand:SI 0 "s_register_operand" "r"))]
8662 "mov%?\\t%|pc, %0\\t%@ indirect register jump"
8663 [(set_attr "predicable" "yes")
8664 (set_attr "type" "branch")]
8667 (define_insn "*load_indirect_jump"
8669 (match_operand:SI 0 "memory_operand" "m"))]
8671 "ldr%?\\t%|pc, %0\\t%@ indirect memory jump"
8672 [(set_attr "type" "load1")
8673 (set_attr "pool_range" "4096")
8674 (set_attr "neg_pool_range" "4084")
8675 (set_attr "predicable" "yes")]
8685 [(set (attr "length")
8686 (if_then_else (eq_attr "is_thumb" "yes")
8689 (set_attr "type" "mov_reg")]
8693 [(trap_if (const_int 1) (const_int 0))]
8697 return \".inst\\t0xe7f000f0\";
8699 return \".inst\\t0xdeff\";
8701 [(set (attr "length")
8702 (if_then_else (eq_attr "is_thumb" "yes")
8705 (set_attr "type" "trap")
8706 (set_attr "conds" "unconditional")]
8710 ;; Patterns to allow combination of arithmetic, cond code and shifts
8712 (define_insn "*<arith_shift_insn>_multsi"
8713 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8715 (mult:SI (match_operand:SI 2 "s_register_operand" "r,r")
8716 (match_operand:SI 3 "power_of_two_operand" ""))
8717 (match_operand:SI 1 "s_register_operand" "rk,<t2_binop0>")))]
8719 "<arith_shift_insn>%?\\t%0, %1, %2, lsl %b3"
8720 [(set_attr "predicable" "yes")
8721 (set_attr "predicable_short_it" "no")
8722 (set_attr "shift" "2")
8723 (set_attr "arch" "a,t2")
8724 (set_attr "type" "alu_shift_imm")])
8726 (define_insn "*<arith_shift_insn>_shiftsi"
8727 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
8729 (match_operator:SI 2 "shift_nomul_operator"
8730 [(match_operand:SI 3 "s_register_operand" "r,r,r")
8731 (match_operand:SI 4 "shift_amount_operand" "M,M,r")])
8732 (match_operand:SI 1 "s_register_operand" "rk,<t2_binop0>,rk")))]
8733 "TARGET_32BIT && GET_CODE (operands[2]) != MULT"
8734 "<arith_shift_insn>%?\\t%0, %1, %3%S2"
8735 [(set_attr "predicable" "yes")
8736 (set_attr "predicable_short_it" "no")
8737 (set_attr "shift" "3")
8738 (set_attr "arch" "a,t2,a")
8739 (set_attr "type" "alu_shift_imm,alu_shift_imm,alu_shift_reg")])
8742 [(set (match_operand:SI 0 "s_register_operand" "")
8743 (match_operator:SI 1 "shiftable_operator"
8744 [(match_operator:SI 2 "shiftable_operator"
8745 [(match_operator:SI 3 "shift_operator"
8746 [(match_operand:SI 4 "s_register_operand" "")
8747 (match_operand:SI 5 "reg_or_int_operand" "")])
8748 (match_operand:SI 6 "s_register_operand" "")])
8749 (match_operand:SI 7 "arm_rhs_operand" "")]))
8750 (clobber (match_operand:SI 8 "s_register_operand" ""))]
8753 (match_op_dup 2 [(match_op_dup 3 [(match_dup 4) (match_dup 5)])
8756 (match_op_dup 1 [(match_dup 8) (match_dup 7)]))]
8759 (define_insn "*arith_shiftsi_compare0"
8760 [(set (reg:CC_NOOV CC_REGNUM)
8762 (match_operator:SI 1 "shiftable_operator"
8763 [(match_operator:SI 3 "shift_operator"
8764 [(match_operand:SI 4 "s_register_operand" "r,r")
8765 (match_operand:SI 5 "shift_amount_operand" "M,r")])
8766 (match_operand:SI 2 "s_register_operand" "r,r")])
8768 (set (match_operand:SI 0 "s_register_operand" "=r,r")
8769 (match_op_dup 1 [(match_op_dup 3 [(match_dup 4) (match_dup 5)])
8772 "%i1s%?\\t%0, %2, %4%S3"
8773 [(set_attr "conds" "set")
8774 (set_attr "shift" "4")
8775 (set_attr "arch" "32,a")
8776 (set_attr "type" "alus_shift_imm,alus_shift_reg")])
8778 (define_insn "*arith_shiftsi_compare0_scratch"
8779 [(set (reg:CC_NOOV CC_REGNUM)
8781 (match_operator:SI 1 "shiftable_operator"
8782 [(match_operator:SI 3 "shift_operator"
8783 [(match_operand:SI 4 "s_register_operand" "r,r")
8784 (match_operand:SI 5 "shift_amount_operand" "M,r")])
8785 (match_operand:SI 2 "s_register_operand" "r,r")])
8787 (clobber (match_scratch:SI 0 "=r,r"))]
8789 "%i1s%?\\t%0, %2, %4%S3"
8790 [(set_attr "conds" "set")
8791 (set_attr "shift" "4")
8792 (set_attr "arch" "32,a")
8793 (set_attr "type" "alus_shift_imm,alus_shift_reg")])
8795 (define_insn "*sub_shiftsi"
8796 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8797 (minus:SI (match_operand:SI 1 "s_register_operand" "r,r")
8798 (match_operator:SI 2 "shift_operator"
8799 [(match_operand:SI 3 "s_register_operand" "r,r")
8800 (match_operand:SI 4 "shift_amount_operand" "M,r")])))]
8802 "sub%?\\t%0, %1, %3%S2"
8803 [(set_attr "predicable" "yes")
8804 (set_attr "shift" "3")
8805 (set_attr "arch" "32,a")
8806 (set_attr "type" "alus_shift_imm,alus_shift_reg")])
8808 (define_insn "*sub_shiftsi_compare0"
8809 [(set (reg:CC_NOOV CC_REGNUM)
8811 (minus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
8812 (match_operator:SI 2 "shift_operator"
8813 [(match_operand:SI 3 "s_register_operand" "r,r,r")
8814 (match_operand:SI 4 "shift_amount_operand" "M,r,M")]))
8816 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
8817 (minus:SI (match_dup 1)
8818 (match_op_dup 2 [(match_dup 3) (match_dup 4)])))]
8820 "subs%?\\t%0, %1, %3%S2"
8821 [(set_attr "conds" "set")
8822 (set_attr "shift" "3")
8823 (set_attr "arch" "32,a,a")
8824 (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
8826 (define_insn "*sub_shiftsi_compare0_scratch"
8827 [(set (reg:CC_NOOV CC_REGNUM)
8829 (minus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
8830 (match_operator:SI 2 "shift_operator"
8831 [(match_operand:SI 3 "s_register_operand" "r,r,r")
8832 (match_operand:SI 4 "shift_amount_operand" "M,r,M")]))
8834 (clobber (match_scratch:SI 0 "=r,r,r"))]
8836 "subs%?\\t%0, %1, %3%S2"
8837 [(set_attr "conds" "set")
8838 (set_attr "shift" "3")
8839 (set_attr "arch" "32,a,a")
8840 (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
8843 (define_insn_and_split "*and_scc"
8844 [(set (match_operand:SI 0 "s_register_operand" "=r")
8845 (and:SI (match_operator:SI 1 "arm_comparison_operator"
8846 [(match_operand 2 "cc_register" "") (const_int 0)])
8847 (match_operand:SI 3 "s_register_operand" "r")))]
8849 "#" ; "mov%D1\\t%0, #0\;and%d1\\t%0, %3, #1"
8850 "&& reload_completed"
8851 [(cond_exec (match_dup 5) (set (match_dup 0) (const_int 0)))
8852 (cond_exec (match_dup 4) (set (match_dup 0)
8853 (and:SI (match_dup 3) (const_int 1))))]
8855 machine_mode mode = GET_MODE (operands[2]);
8856 enum rtx_code rc = GET_CODE (operands[1]);
8858 /* Note that operands[4] is the same as operands[1],
8859 but with VOIDmode as the result. */
8860 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
8861 if (mode == CCFPmode || mode == CCFPEmode)
8862 rc = reverse_condition_maybe_unordered (rc);
8864 rc = reverse_condition (rc);
8865 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
8867 [(set_attr "conds" "use")
8868 (set_attr "type" "multiple")
8869 (set_attr "length" "8")]
8872 (define_insn_and_split "*ior_scc"
8873 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8874 (ior:SI (match_operator:SI 1 "arm_comparison_operator"
8875 [(match_operand 2 "cc_register" "") (const_int 0)])
8876 (match_operand:SI 3 "s_register_operand" "0,?r")))]
8881 "&& reload_completed
8882 && REGNO (operands [0]) != REGNO (operands[3])"
8883 ;; && which_alternative == 1
8884 ; mov%D1\\t%0, %3\;orr%d1\\t%0, %3, #1
8885 [(cond_exec (match_dup 5) (set (match_dup 0) (match_dup 3)))
8886 (cond_exec (match_dup 4) (set (match_dup 0)
8887 (ior:SI (match_dup 3) (const_int 1))))]
8889 machine_mode mode = GET_MODE (operands[2]);
8890 enum rtx_code rc = GET_CODE (operands[1]);
8892 /* Note that operands[4] is the same as operands[1],
8893 but with VOIDmode as the result. */
8894 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
8895 if (mode == CCFPmode || mode == CCFPEmode)
8896 rc = reverse_condition_maybe_unordered (rc);
8898 rc = reverse_condition (rc);
8899 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
8901 [(set_attr "conds" "use")
8902 (set_attr "length" "4,8")
8903 (set_attr "type" "logic_imm,multiple")]
8906 ; A series of splitters for the compare_scc pattern below. Note that
8907 ; order is important.
8909 [(set (match_operand:SI 0 "s_register_operand" "")
8910 (lt:SI (match_operand:SI 1 "s_register_operand" "")
8912 (clobber (reg:CC CC_REGNUM))]
8913 "TARGET_32BIT && reload_completed"
8914 [(set (match_dup 0) (lshiftrt:SI (match_dup 1) (const_int 31)))])
8917 [(set (match_operand:SI 0 "s_register_operand" "")
8918 (ge:SI (match_operand:SI 1 "s_register_operand" "")
8920 (clobber (reg:CC CC_REGNUM))]
8921 "TARGET_32BIT && reload_completed"
8922 [(set (match_dup 0) (not:SI (match_dup 1)))
8923 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 31)))])
8926 [(set (match_operand:SI 0 "s_register_operand" "")
8927 (eq:SI (match_operand:SI 1 "s_register_operand" "")
8929 (clobber (reg:CC CC_REGNUM))]
8930 "arm_arch5 && TARGET_32BIT"
8931 [(set (match_dup 0) (clz:SI (match_dup 1)))
8932 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
8936 [(set (match_operand:SI 0 "s_register_operand" "")
8937 (eq:SI (match_operand:SI 1 "s_register_operand" "")
8939 (clobber (reg:CC CC_REGNUM))]
8940 "TARGET_32BIT && reload_completed"
8942 [(set (reg:CC CC_REGNUM)
8943 (compare:CC (const_int 1) (match_dup 1)))
8945 (minus:SI (const_int 1) (match_dup 1)))])
8946 (cond_exec (ltu:CC (reg:CC CC_REGNUM) (const_int 0))
8947 (set (match_dup 0) (const_int 0)))])
8950 [(set (match_operand:SI 0 "s_register_operand" "")
8951 (ne:SI (match_operand:SI 1 "s_register_operand" "")
8952 (match_operand:SI 2 "const_int_operand" "")))
8953 (clobber (reg:CC CC_REGNUM))]
8954 "TARGET_32BIT && reload_completed"
8956 [(set (reg:CC CC_REGNUM)
8957 (compare:CC (match_dup 1) (match_dup 2)))
8958 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 3)))])
8959 (cond_exec (ne:CC (reg:CC CC_REGNUM) (const_int 0))
8960 (set (match_dup 0) (const_int 1)))]
8962 operands[3] = GEN_INT (-INTVAL (operands[2]));
8966 [(set (match_operand:SI 0 "s_register_operand" "")
8967 (ne:SI (match_operand:SI 1 "s_register_operand" "")
8968 (match_operand:SI 2 "arm_add_operand" "")))
8969 (clobber (reg:CC CC_REGNUM))]
8970 "TARGET_32BIT && reload_completed"
8972 [(set (reg:CC_NOOV CC_REGNUM)
8973 (compare:CC_NOOV (minus:SI (match_dup 1) (match_dup 2))
8975 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
8976 (cond_exec (ne:CC_NOOV (reg:CC_NOOV CC_REGNUM) (const_int 0))
8977 (set (match_dup 0) (const_int 1)))])
8979 (define_insn_and_split "*compare_scc"
8980 [(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts")
8981 (match_operator:SI 1 "arm_comparison_operator"
8982 [(match_operand:SI 2 "s_register_operand" "r,r")
8983 (match_operand:SI 3 "arm_add_operand" "rI,L")]))
8984 (clobber (reg:CC CC_REGNUM))]
8987 "&& reload_completed"
8988 [(set (reg:CC CC_REGNUM) (compare:CC (match_dup 2) (match_dup 3)))
8989 (cond_exec (match_dup 4) (set (match_dup 0) (const_int 0)))
8990 (cond_exec (match_dup 5) (set (match_dup 0) (const_int 1)))]
8993 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
8994 operands[2], operands[3]);
8995 enum rtx_code rc = GET_CODE (operands[1]);
8997 tmp1 = gen_rtx_REG (mode, CC_REGNUM);
8999 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, tmp1, const0_rtx);
9000 if (mode == CCFPmode || mode == CCFPEmode)
9001 rc = reverse_condition_maybe_unordered (rc);
9003 rc = reverse_condition (rc);
9004 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, tmp1, const0_rtx);
9006 [(set_attr "type" "multiple")]
9009 ;; Attempt to improve the sequence generated by the compare_scc splitters
9010 ;; not to use conditional execution.
9012 ;; Rd = (eq (reg1) (const_int0)) // ARMv5
9016 [(set (reg:CC CC_REGNUM)
9017 (compare:CC (match_operand:SI 1 "register_operand" "")
9019 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
9020 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
9021 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
9022 (set (match_dup 0) (const_int 1)))]
9023 "arm_arch5 && TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
9024 [(set (match_dup 0) (clz:SI (match_dup 1)))
9025 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
9028 ;; Rd = (eq (reg1) (const_int0)) // !ARMv5
9032 [(set (reg:CC CC_REGNUM)
9033 (compare:CC (match_operand:SI 1 "register_operand" "")
9035 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
9036 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
9037 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
9038 (set (match_dup 0) (const_int 1)))
9039 (match_scratch:SI 2 "r")]
9040 "TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
9042 [(set (reg:CC CC_REGNUM)
9043 (compare:CC (const_int 0) (match_dup 1)))
9044 (set (match_dup 2) (minus:SI (const_int 0) (match_dup 1)))])
9046 (plus:SI (plus:SI (match_dup 1) (match_dup 2))
9047 (geu:SI (reg:CC CC_REGNUM) (const_int 0))))]
9050 ;; Rd = (eq (reg1) (reg2/imm)) // ARMv5 and optimising for speed.
9051 ;; sub Rd, Reg1, reg2
9055 [(set (reg:CC CC_REGNUM)
9056 (compare:CC (match_operand:SI 1 "register_operand" "")
9057 (match_operand:SI 2 "arm_rhs_operand" "")))
9058 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
9059 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
9060 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
9061 (set (match_dup 0) (const_int 1)))]
9062 "arm_arch5 && TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)
9063 && !(TARGET_THUMB2 && optimize_insn_for_size_p ())"
9064 [(set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))
9065 (set (match_dup 0) (clz:SI (match_dup 0)))
9066 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
9070 ;; Rd = (eq (reg1) (reg2)) // ! ARMv5 or optimising for size.
9071 ;; sub T1, Reg1, reg2
9075 [(set (reg:CC CC_REGNUM)
9076 (compare:CC (match_operand:SI 1 "register_operand" "")
9077 (match_operand:SI 2 "arm_rhs_operand" "")))
9078 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
9079 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
9080 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
9081 (set (match_dup 0) (const_int 1)))
9082 (match_scratch:SI 3 "r")]
9083 "TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
9084 [(set (match_dup 3) (match_dup 4))
9086 [(set (reg:CC CC_REGNUM)
9087 (compare:CC (const_int 0) (match_dup 3)))
9088 (set (match_dup 0) (minus:SI (const_int 0) (match_dup 3)))])
9090 (plus:SI (plus:SI (match_dup 0) (match_dup 3))
9091 (geu:SI (reg:CC CC_REGNUM) (const_int 0))))]
9093 if (CONST_INT_P (operands[2]))
9094 operands[4] = plus_constant (SImode, operands[1], -INTVAL (operands[2]));
9096 operands[4] = gen_rtx_MINUS (SImode, operands[1], operands[2]);
9099 (define_insn "*cond_move"
9100 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9101 (if_then_else:SI (match_operator 3 "equality_operator"
9102 [(match_operator 4 "arm_comparison_operator"
9103 [(match_operand 5 "cc_register" "") (const_int 0)])
9105 (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
9106 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))]
9109 if (GET_CODE (operands[3]) == NE)
9111 if (which_alternative != 1)
9112 output_asm_insn (\"mov%D4\\t%0, %2\", operands);
9113 if (which_alternative != 0)
9114 output_asm_insn (\"mov%d4\\t%0, %1\", operands);
9117 if (which_alternative != 0)
9118 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
9119 if (which_alternative != 1)
9120 output_asm_insn (\"mov%d4\\t%0, %2\", operands);
9123 [(set_attr "conds" "use")
9124 (set_attr_alternative "type"
9125 [(if_then_else (match_operand 2 "const_int_operand" "")
9126 (const_string "mov_imm")
9127 (const_string "mov_reg"))
9128 (if_then_else (match_operand 1 "const_int_operand" "")
9129 (const_string "mov_imm")
9130 (const_string "mov_reg"))
9131 (const_string "multiple")])
9132 (set_attr "length" "4,4,8")]
9135 (define_insn "*cond_arith"
9136 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9137 (match_operator:SI 5 "shiftable_operator"
9138 [(match_operator:SI 4 "arm_comparison_operator"
9139 [(match_operand:SI 2 "s_register_operand" "r,r")
9140 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
9141 (match_operand:SI 1 "s_register_operand" "0,?r")]))
9142 (clobber (reg:CC CC_REGNUM))]
9145 if (GET_CODE (operands[4]) == LT && operands[3] == const0_rtx)
9146 return \"%i5\\t%0, %1, %2, lsr #31\";
9148 output_asm_insn (\"cmp\\t%2, %3\", operands);
9149 if (GET_CODE (operands[5]) == AND)
9150 output_asm_insn (\"mov%D4\\t%0, #0\", operands);
9151 else if (GET_CODE (operands[5]) == MINUS)
9152 output_asm_insn (\"rsb%D4\\t%0, %1, #0\", operands);
9153 else if (which_alternative != 0)
9154 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
9155 return \"%i5%d4\\t%0, %1, #1\";
9157 [(set_attr "conds" "clob")
9158 (set_attr "length" "12")
9159 (set_attr "type" "multiple")]
9162 (define_insn "*cond_sub"
9163 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9164 (minus:SI (match_operand:SI 1 "s_register_operand" "0,?r")
9165 (match_operator:SI 4 "arm_comparison_operator"
9166 [(match_operand:SI 2 "s_register_operand" "r,r")
9167 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
9168 (clobber (reg:CC CC_REGNUM))]
9171 output_asm_insn (\"cmp\\t%2, %3\", operands);
9172 if (which_alternative != 0)
9173 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
9174 return \"sub%d4\\t%0, %1, #1\";
9176 [(set_attr "conds" "clob")
9177 (set_attr "length" "8,12")
9178 (set_attr "type" "multiple")]
9181 (define_insn "*cmp_ite0"
9182 [(set (match_operand 6 "dominant_cc_register" "")
9185 (match_operator 4 "arm_comparison_operator"
9186 [(match_operand:SI 0 "s_register_operand"
9187 "l,l,l,r,r,r,r,r,r")
9188 (match_operand:SI 1 "arm_add_operand"
9189 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
9190 (match_operator:SI 5 "arm_comparison_operator"
9191 [(match_operand:SI 2 "s_register_operand"
9192 "l,r,r,l,l,r,r,r,r")
9193 (match_operand:SI 3 "arm_add_operand"
9194 "lPy,rI,L,lPy,lPy,rI,rI,L,L")])
9200 static const char * const cmp1[NUM_OF_COND_CMP][2] =
9202 {\"cmp%d5\\t%0, %1\",
9203 \"cmp%d4\\t%2, %3\"},
9204 {\"cmn%d5\\t%0, #%n1\",
9205 \"cmp%d4\\t%2, %3\"},
9206 {\"cmp%d5\\t%0, %1\",
9207 \"cmn%d4\\t%2, #%n3\"},
9208 {\"cmn%d5\\t%0, #%n1\",
9209 \"cmn%d4\\t%2, #%n3\"}
9211 static const char * const cmp2[NUM_OF_COND_CMP][2] =
9216 \"cmn\\t%0, #%n1\"},
9217 {\"cmn\\t%2, #%n3\",
9219 {\"cmn\\t%2, #%n3\",
9222 static const char * const ite[2] =
9227 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
9228 CMP_CMP, CMN_CMP, CMP_CMP,
9229 CMN_CMP, CMP_CMN, CMN_CMN};
9231 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
9233 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
9234 if (TARGET_THUMB2) {
9235 output_asm_insn (ite[swap], operands);
9237 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
9240 [(set_attr "conds" "set")
9241 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
9242 (set_attr "type" "multiple")
9243 (set_attr_alternative "length"
9249 (if_then_else (eq_attr "is_thumb" "no")
9252 (if_then_else (eq_attr "is_thumb" "no")
9255 (if_then_else (eq_attr "is_thumb" "no")
9258 (if_then_else (eq_attr "is_thumb" "no")
9263 (define_insn "*cmp_ite1"
9264 [(set (match_operand 6 "dominant_cc_register" "")
9267 (match_operator 4 "arm_comparison_operator"
9268 [(match_operand:SI 0 "s_register_operand"
9269 "l,l,l,r,r,r,r,r,r")
9270 (match_operand:SI 1 "arm_add_operand"
9271 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
9272 (match_operator:SI 5 "arm_comparison_operator"
9273 [(match_operand:SI 2 "s_register_operand"
9274 "l,r,r,l,l,r,r,r,r")
9275 (match_operand:SI 3 "arm_add_operand"
9276 "lPy,rI,L,lPy,lPy,rI,rI,L,L")])
9282 static const char * const cmp1[NUM_OF_COND_CMP][2] =
9286 {\"cmn\\t%0, #%n1\",
9289 \"cmn\\t%2, #%n3\"},
9290 {\"cmn\\t%0, #%n1\",
9293 static const char * const cmp2[NUM_OF_COND_CMP][2] =
9295 {\"cmp%d4\\t%2, %3\",
9296 \"cmp%D5\\t%0, %1\"},
9297 {\"cmp%d4\\t%2, %3\",
9298 \"cmn%D5\\t%0, #%n1\"},
9299 {\"cmn%d4\\t%2, #%n3\",
9300 \"cmp%D5\\t%0, %1\"},
9301 {\"cmn%d4\\t%2, #%n3\",
9302 \"cmn%D5\\t%0, #%n1\"}
9304 static const char * const ite[2] =
9309 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
9310 CMP_CMP, CMN_CMP, CMP_CMP,
9311 CMN_CMP, CMP_CMN, CMN_CMN};
9313 comparison_dominates_p (GET_CODE (operands[5]),
9314 reverse_condition (GET_CODE (operands[4])));
9316 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
9317 if (TARGET_THUMB2) {
9318 output_asm_insn (ite[swap], operands);
9320 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
9323 [(set_attr "conds" "set")
9324 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
9325 (set_attr_alternative "length"
9331 (if_then_else (eq_attr "is_thumb" "no")
9334 (if_then_else (eq_attr "is_thumb" "no")
9337 (if_then_else (eq_attr "is_thumb" "no")
9340 (if_then_else (eq_attr "is_thumb" "no")
9343 (set_attr "type" "multiple")]
9346 (define_insn "*cmp_and"
9347 [(set (match_operand 6 "dominant_cc_register" "")
9350 (match_operator 4 "arm_comparison_operator"
9351 [(match_operand:SI 0 "s_register_operand"
9352 "l,l,l,r,r,r,r,r,r")
9353 (match_operand:SI 1 "arm_add_operand"
9354 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
9355 (match_operator:SI 5 "arm_comparison_operator"
9356 [(match_operand:SI 2 "s_register_operand"
9357 "l,r,r,l,l,r,r,r,r")
9358 (match_operand:SI 3 "arm_add_operand"
9359 "lPy,rI,L,lPy,lPy,rI,rI,L,L")]))
9364 static const char *const cmp1[NUM_OF_COND_CMP][2] =
9366 {\"cmp%d5\\t%0, %1\",
9367 \"cmp%d4\\t%2, %3\"},
9368 {\"cmn%d5\\t%0, #%n1\",
9369 \"cmp%d4\\t%2, %3\"},
9370 {\"cmp%d5\\t%0, %1\",
9371 \"cmn%d4\\t%2, #%n3\"},
9372 {\"cmn%d5\\t%0, #%n1\",
9373 \"cmn%d4\\t%2, #%n3\"}
9375 static const char *const cmp2[NUM_OF_COND_CMP][2] =
9380 \"cmn\\t%0, #%n1\"},
9381 {\"cmn\\t%2, #%n3\",
9383 {\"cmn\\t%2, #%n3\",
9386 static const char *const ite[2] =
9391 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
9392 CMP_CMP, CMN_CMP, CMP_CMP,
9393 CMN_CMP, CMP_CMN, CMN_CMN};
9395 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
9397 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
9398 if (TARGET_THUMB2) {
9399 output_asm_insn (ite[swap], operands);
9401 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
9404 [(set_attr "conds" "set")
9405 (set_attr "predicable" "no")
9406 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
9407 (set_attr_alternative "length"
9413 (if_then_else (eq_attr "is_thumb" "no")
9416 (if_then_else (eq_attr "is_thumb" "no")
9419 (if_then_else (eq_attr "is_thumb" "no")
9422 (if_then_else (eq_attr "is_thumb" "no")
9425 (set_attr "type" "multiple")]
9428 (define_insn "*cmp_ior"
9429 [(set (match_operand 6 "dominant_cc_register" "")
9432 (match_operator 4 "arm_comparison_operator"
9433 [(match_operand:SI 0 "s_register_operand"
9434 "l,l,l,r,r,r,r,r,r")
9435 (match_operand:SI 1 "arm_add_operand"
9436 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
9437 (match_operator:SI 5 "arm_comparison_operator"
9438 [(match_operand:SI 2 "s_register_operand"
9439 "l,r,r,l,l,r,r,r,r")
9440 (match_operand:SI 3 "arm_add_operand"
9441 "lPy,rI,L,lPy,lPy,rI,rI,L,L")]))
9446 static const char *const cmp1[NUM_OF_COND_CMP][2] =
9450 {\"cmn\\t%0, #%n1\",
9453 \"cmn\\t%2, #%n3\"},
9454 {\"cmn\\t%0, #%n1\",
9457 static const char *const cmp2[NUM_OF_COND_CMP][2] =
9459 {\"cmp%D4\\t%2, %3\",
9460 \"cmp%D5\\t%0, %1\"},
9461 {\"cmp%D4\\t%2, %3\",
9462 \"cmn%D5\\t%0, #%n1\"},
9463 {\"cmn%D4\\t%2, #%n3\",
9464 \"cmp%D5\\t%0, %1\"},
9465 {\"cmn%D4\\t%2, #%n3\",
9466 \"cmn%D5\\t%0, #%n1\"}
9468 static const char *const ite[2] =
9473 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
9474 CMP_CMP, CMN_CMP, CMP_CMP,
9475 CMN_CMP, CMP_CMN, CMN_CMN};
9477 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
9479 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
9480 if (TARGET_THUMB2) {
9481 output_asm_insn (ite[swap], operands);
9483 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
9487 [(set_attr "conds" "set")
9488 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
9489 (set_attr_alternative "length"
9495 (if_then_else (eq_attr "is_thumb" "no")
9498 (if_then_else (eq_attr "is_thumb" "no")
9501 (if_then_else (eq_attr "is_thumb" "no")
9504 (if_then_else (eq_attr "is_thumb" "no")
9507 (set_attr "type" "multiple")]
9510 (define_insn_and_split "*ior_scc_scc"
9511 [(set (match_operand:SI 0 "s_register_operand" "=Ts")
9512 (ior:SI (match_operator:SI 3 "arm_comparison_operator"
9513 [(match_operand:SI 1 "s_register_operand" "r")
9514 (match_operand:SI 2 "arm_add_operand" "rIL")])
9515 (match_operator:SI 6 "arm_comparison_operator"
9516 [(match_operand:SI 4 "s_register_operand" "r")
9517 (match_operand:SI 5 "arm_add_operand" "rIL")])))
9518 (clobber (reg:CC CC_REGNUM))]
9520 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_OR_Y)
9523 "TARGET_32BIT && reload_completed"
9527 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9528 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9530 (set (match_dup 0) (ne:SI (match_dup 7) (const_int 0)))]
9532 = gen_rtx_REG (arm_select_dominance_cc_mode (operands[3], operands[6],
9535 [(set_attr "conds" "clob")
9536 (set_attr "length" "16")
9537 (set_attr "type" "multiple")]
9540 ; If the above pattern is followed by a CMP insn, then the compare is
9541 ; redundant, since we can rework the conditional instruction that follows.
9542 (define_insn_and_split "*ior_scc_scc_cmp"
9543 [(set (match_operand 0 "dominant_cc_register" "")
9544 (compare (ior:SI (match_operator:SI 3 "arm_comparison_operator"
9545 [(match_operand:SI 1 "s_register_operand" "r")
9546 (match_operand:SI 2 "arm_add_operand" "rIL")])
9547 (match_operator:SI 6 "arm_comparison_operator"
9548 [(match_operand:SI 4 "s_register_operand" "r")
9549 (match_operand:SI 5 "arm_add_operand" "rIL")]))
9551 (set (match_operand:SI 7 "s_register_operand" "=Ts")
9552 (ior:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9553 (match_op_dup 6 [(match_dup 4) (match_dup 5)])))]
9556 "TARGET_32BIT && reload_completed"
9560 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9561 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9563 (set (match_dup 7) (ne:SI (match_dup 0) (const_int 0)))]
9565 [(set_attr "conds" "set")
9566 (set_attr "length" "16")
9567 (set_attr "type" "multiple")]
9570 (define_insn_and_split "*and_scc_scc"
9571 [(set (match_operand:SI 0 "s_register_operand" "=Ts")
9572 (and:SI (match_operator:SI 3 "arm_comparison_operator"
9573 [(match_operand:SI 1 "s_register_operand" "r")
9574 (match_operand:SI 2 "arm_add_operand" "rIL")])
9575 (match_operator:SI 6 "arm_comparison_operator"
9576 [(match_operand:SI 4 "s_register_operand" "r")
9577 (match_operand:SI 5 "arm_add_operand" "rIL")])))
9578 (clobber (reg:CC CC_REGNUM))]
9580 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
9583 "TARGET_32BIT && reload_completed
9584 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
9589 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9590 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9592 (set (match_dup 0) (ne:SI (match_dup 7) (const_int 0)))]
9594 = gen_rtx_REG (arm_select_dominance_cc_mode (operands[3], operands[6],
9597 [(set_attr "conds" "clob")
9598 (set_attr "length" "16")
9599 (set_attr "type" "multiple")]
9602 ; If the above pattern is followed by a CMP insn, then the compare is
9603 ; redundant, since we can rework the conditional instruction that follows.
9604 (define_insn_and_split "*and_scc_scc_cmp"
9605 [(set (match_operand 0 "dominant_cc_register" "")
9606 (compare (and:SI (match_operator:SI 3 "arm_comparison_operator"
9607 [(match_operand:SI 1 "s_register_operand" "r")
9608 (match_operand:SI 2 "arm_add_operand" "rIL")])
9609 (match_operator:SI 6 "arm_comparison_operator"
9610 [(match_operand:SI 4 "s_register_operand" "r")
9611 (match_operand:SI 5 "arm_add_operand" "rIL")]))
9613 (set (match_operand:SI 7 "s_register_operand" "=Ts")
9614 (and:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9615 (match_op_dup 6 [(match_dup 4) (match_dup 5)])))]
9618 "TARGET_32BIT && reload_completed"
9622 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9623 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9625 (set (match_dup 7) (ne:SI (match_dup 0) (const_int 0)))]
9627 [(set_attr "conds" "set")
9628 (set_attr "length" "16")
9629 (set_attr "type" "multiple")]
9632 ;; If there is no dominance in the comparison, then we can still save an
9633 ;; instruction in the AND case, since we can know that the second compare
9634 ;; need only zero the value if false (if true, then the value is already
9636 (define_insn_and_split "*and_scc_scc_nodom"
9637 [(set (match_operand:SI 0 "s_register_operand" "=&Ts,&Ts,&Ts")
9638 (and:SI (match_operator:SI 3 "arm_comparison_operator"
9639 [(match_operand:SI 1 "s_register_operand" "r,r,0")
9640 (match_operand:SI 2 "arm_add_operand" "rIL,0,rIL")])
9641 (match_operator:SI 6 "arm_comparison_operator"
9642 [(match_operand:SI 4 "s_register_operand" "r,r,r")
9643 (match_operand:SI 5 "arm_add_operand" "rIL,rIL,rIL")])))
9644 (clobber (reg:CC CC_REGNUM))]
9646 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
9649 "TARGET_32BIT && reload_completed"
9650 [(parallel [(set (match_dup 0)
9651 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
9652 (clobber (reg:CC CC_REGNUM))])
9653 (set (match_dup 7) (match_op_dup 8 [(match_dup 4) (match_dup 5)]))
9655 (if_then_else:SI (match_op_dup 6 [(match_dup 7) (const_int 0)])
9658 "operands[7] = gen_rtx_REG (SELECT_CC_MODE (GET_CODE (operands[6]),
9659 operands[4], operands[5]),
9661 operands[8] = gen_rtx_COMPARE (GET_MODE (operands[7]), operands[4],
9663 [(set_attr "conds" "clob")
9664 (set_attr "length" "20")
9665 (set_attr "type" "multiple")]
9669 [(set (reg:CC_NOOV CC_REGNUM)
9670 (compare:CC_NOOV (ior:SI
9671 (and:SI (match_operand:SI 0 "s_register_operand" "")
9673 (match_operator:SI 1 "arm_comparison_operator"
9674 [(match_operand:SI 2 "s_register_operand" "")
9675 (match_operand:SI 3 "arm_add_operand" "")]))
9677 (clobber (match_operand:SI 4 "s_register_operand" ""))]
9680 (ior:SI (match_op_dup 1 [(match_dup 2) (match_dup 3)])
9682 (set (reg:CC_NOOV CC_REGNUM)
9683 (compare:CC_NOOV (and:SI (match_dup 4) (const_int 1))
9688 [(set (reg:CC_NOOV CC_REGNUM)
9689 (compare:CC_NOOV (ior:SI
9690 (match_operator:SI 1 "arm_comparison_operator"
9691 [(match_operand:SI 2 "s_register_operand" "")
9692 (match_operand:SI 3 "arm_add_operand" "")])
9693 (and:SI (match_operand:SI 0 "s_register_operand" "")
9696 (clobber (match_operand:SI 4 "s_register_operand" ""))]
9699 (ior:SI (match_op_dup 1 [(match_dup 2) (match_dup 3)])
9701 (set (reg:CC_NOOV CC_REGNUM)
9702 (compare:CC_NOOV (and:SI (match_dup 4) (const_int 1))
9705 ;; ??? The conditional patterns above need checking for Thumb-2 usefulness
9707 (define_insn_and_split "*negscc"
9708 [(set (match_operand:SI 0 "s_register_operand" "=r")
9709 (neg:SI (match_operator 3 "arm_comparison_operator"
9710 [(match_operand:SI 1 "s_register_operand" "r")
9711 (match_operand:SI 2 "arm_rhs_operand" "rI")])))
9712 (clobber (reg:CC CC_REGNUM))]
9715 "&& reload_completed"
9718 rtx cc_reg = gen_rtx_REG (CCmode, CC_REGNUM);
9720 if (GET_CODE (operands[3]) == LT && operands[2] == const0_rtx)
9722 /* Emit mov\\t%0, %1, asr #31 */
9723 emit_insn (gen_rtx_SET (operands[0],
9724 gen_rtx_ASHIFTRT (SImode,
9729 else if (GET_CODE (operands[3]) == NE)
9731 /* Emit subs\\t%0, %1, %2\;mvnne\\t%0, #0 */
9732 if (CONST_INT_P (operands[2]))
9733 emit_insn (gen_cmpsi2_addneg (operands[0], operands[1], operands[2],
9734 GEN_INT (- INTVAL (operands[2]))));
9736 emit_insn (gen_subsi3_compare (operands[0], operands[1], operands[2]));
9738 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
9742 gen_rtx_SET (operands[0],
9748 /* Emit: cmp\\t%1, %2\;mov%D3\\t%0, #0\;mvn%d3\\t%0, #0 */
9749 emit_insn (gen_rtx_SET (cc_reg,
9750 gen_rtx_COMPARE (CCmode, operands[1], operands[2])));
9751 enum rtx_code rc = GET_CODE (operands[3]);
9753 rc = reverse_condition (rc);
9754 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
9759 gen_rtx_SET (operands[0], const0_rtx)));
9760 rc = GET_CODE (operands[3]);
9761 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
9766 gen_rtx_SET (operands[0],
9772 [(set_attr "conds" "clob")
9773 (set_attr "length" "12")
9774 (set_attr "type" "multiple")]
9777 (define_insn_and_split "movcond_addsi"
9778 [(set (match_operand:SI 0 "s_register_operand" "=r,l,r")
9780 (match_operator 5 "comparison_operator"
9781 [(plus:SI (match_operand:SI 3 "s_register_operand" "r,r,r")
9782 (match_operand:SI 4 "arm_add_operand" "rIL,rIL,rIL"))
9784 (match_operand:SI 1 "arm_rhs_operand" "rI,rPy,r")
9785 (match_operand:SI 2 "arm_rhs_operand" "rI,rPy,r")))
9786 (clobber (reg:CC CC_REGNUM))]
9789 "&& reload_completed"
9790 [(set (reg:CC_NOOV CC_REGNUM)
9792 (plus:SI (match_dup 3)
9795 (set (match_dup 0) (match_dup 1))
9796 (cond_exec (match_dup 6)
9797 (set (match_dup 0) (match_dup 2)))]
9800 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[5]),
9801 operands[3], operands[4]);
9802 enum rtx_code rc = GET_CODE (operands[5]);
9803 operands[6] = gen_rtx_REG (mode, CC_REGNUM);
9804 gcc_assert (!(mode == CCFPmode || mode == CCFPEmode));
9805 if (!REG_P (operands[2]) || REGNO (operands[2]) != REGNO (operands[0]))
9806 rc = reverse_condition (rc);
9808 std::swap (operands[1], operands[2]);
9810 operands[6] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
9813 [(set_attr "conds" "clob")
9814 (set_attr "enabled_for_depr_it" "no,yes,yes")
9815 (set_attr "type" "multiple")]
9818 (define_insn "movcond"
9819 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9821 (match_operator 5 "arm_comparison_operator"
9822 [(match_operand:SI 3 "s_register_operand" "r,r,r")
9823 (match_operand:SI 4 "arm_add_operand" "rIL,rIL,rIL")])
9824 (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
9825 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
9826 (clobber (reg:CC CC_REGNUM))]
9829 if (GET_CODE (operands[5]) == LT
9830 && (operands[4] == const0_rtx))
9832 if (which_alternative != 1 && REG_P (operands[1]))
9834 if (operands[2] == const0_rtx)
9835 return \"and\\t%0, %1, %3, asr #31\";
9836 return \"ands\\t%0, %1, %3, asr #32\;movcc\\t%0, %2\";
9838 else if (which_alternative != 0 && REG_P (operands[2]))
9840 if (operands[1] == const0_rtx)
9841 return \"bic\\t%0, %2, %3, asr #31\";
9842 return \"bics\\t%0, %2, %3, asr #32\;movcs\\t%0, %1\";
9844 /* The only case that falls through to here is when both ops 1 & 2
9848 if (GET_CODE (operands[5]) == GE
9849 && (operands[4] == const0_rtx))
9851 if (which_alternative != 1 && REG_P (operands[1]))
9853 if (operands[2] == const0_rtx)
9854 return \"bic\\t%0, %1, %3, asr #31\";
9855 return \"bics\\t%0, %1, %3, asr #32\;movcs\\t%0, %2\";
9857 else if (which_alternative != 0 && REG_P (operands[2]))
9859 if (operands[1] == const0_rtx)
9860 return \"and\\t%0, %2, %3, asr #31\";
9861 return \"ands\\t%0, %2, %3, asr #32\;movcc\\t%0, %1\";
9863 /* The only case that falls through to here is when both ops 1 & 2
9866 if (CONST_INT_P (operands[4])
9867 && !const_ok_for_arm (INTVAL (operands[4])))
9868 output_asm_insn (\"cmn\\t%3, #%n4\", operands);
9870 output_asm_insn (\"cmp\\t%3, %4\", operands);
9871 if (which_alternative != 0)
9872 output_asm_insn (\"mov%d5\\t%0, %1\", operands);
9873 if (which_alternative != 1)
9874 output_asm_insn (\"mov%D5\\t%0, %2\", operands);
9877 [(set_attr "conds" "clob")
9878 (set_attr "length" "8,8,12")
9879 (set_attr "type" "multiple")]
9882 ;; ??? The patterns below need checking for Thumb-2 usefulness.
9884 (define_insn "*ifcompare_plus_move"
9885 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9886 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
9887 [(match_operand:SI 4 "s_register_operand" "r,r")
9888 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
9890 (match_operand:SI 2 "s_register_operand" "r,r")
9891 (match_operand:SI 3 "arm_add_operand" "rIL,rIL"))
9892 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))
9893 (clobber (reg:CC CC_REGNUM))]
9896 [(set_attr "conds" "clob")
9897 (set_attr "length" "8,12")
9898 (set_attr "type" "multiple")]
9901 (define_insn "*if_plus_move"
9902 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
9904 (match_operator 4 "arm_comparison_operator"
9905 [(match_operand 5 "cc_register" "") (const_int 0)])
9907 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
9908 (match_operand:SI 3 "arm_add_operand" "rI,L,rI,L"))
9909 (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")))]
9913 sub%d4\\t%0, %2, #%n3
9914 add%d4\\t%0, %2, %3\;mov%D4\\t%0, %1
9915 sub%d4\\t%0, %2, #%n3\;mov%D4\\t%0, %1"
9916 [(set_attr "conds" "use")
9917 (set_attr "length" "4,4,8,8")
9918 (set_attr_alternative "type"
9919 [(if_then_else (match_operand 3 "const_int_operand" "")
9920 (const_string "alu_imm" )
9921 (const_string "alu_sreg"))
9922 (const_string "alu_imm")
9923 (const_string "multiple")
9924 (const_string "multiple")])]
9927 (define_insn "*ifcompare_move_plus"
9928 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9929 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
9930 [(match_operand:SI 4 "s_register_operand" "r,r")
9931 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
9932 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
9934 (match_operand:SI 2 "s_register_operand" "r,r")
9935 (match_operand:SI 3 "arm_add_operand" "rIL,rIL"))))
9936 (clobber (reg:CC CC_REGNUM))]
9939 [(set_attr "conds" "clob")
9940 (set_attr "length" "8,12")
9941 (set_attr "type" "multiple")]
9944 (define_insn "*if_move_plus"
9945 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
9947 (match_operator 4 "arm_comparison_operator"
9948 [(match_operand 5 "cc_register" "") (const_int 0)])
9949 (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")
9951 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
9952 (match_operand:SI 3 "arm_add_operand" "rI,L,rI,L"))))]
9956 sub%D4\\t%0, %2, #%n3
9957 add%D4\\t%0, %2, %3\;mov%d4\\t%0, %1
9958 sub%D4\\t%0, %2, #%n3\;mov%d4\\t%0, %1"
9959 [(set_attr "conds" "use")
9960 (set_attr "length" "4,4,8,8")
9961 (set_attr_alternative "type"
9962 [(if_then_else (match_operand 3 "const_int_operand" "")
9963 (const_string "alu_imm" )
9964 (const_string "alu_sreg"))
9965 (const_string "alu_imm")
9966 (const_string "multiple")
9967 (const_string "multiple")])]
9970 (define_insn "*ifcompare_arith_arith"
9971 [(set (match_operand:SI 0 "s_register_operand" "=r")
9972 (if_then_else:SI (match_operator 9 "arm_comparison_operator"
9973 [(match_operand:SI 5 "s_register_operand" "r")
9974 (match_operand:SI 6 "arm_add_operand" "rIL")])
9975 (match_operator:SI 8 "shiftable_operator"
9976 [(match_operand:SI 1 "s_register_operand" "r")
9977 (match_operand:SI 2 "arm_rhs_operand" "rI")])
9978 (match_operator:SI 7 "shiftable_operator"
9979 [(match_operand:SI 3 "s_register_operand" "r")
9980 (match_operand:SI 4 "arm_rhs_operand" "rI")])))
9981 (clobber (reg:CC CC_REGNUM))]
9984 [(set_attr "conds" "clob")
9985 (set_attr "length" "12")
9986 (set_attr "type" "multiple")]
9989 (define_insn "*if_arith_arith"
9990 [(set (match_operand:SI 0 "s_register_operand" "=r")
9991 (if_then_else:SI (match_operator 5 "arm_comparison_operator"
9992 [(match_operand 8 "cc_register" "") (const_int 0)])
9993 (match_operator:SI 6 "shiftable_operator"
9994 [(match_operand:SI 1 "s_register_operand" "r")
9995 (match_operand:SI 2 "arm_rhs_operand" "rI")])
9996 (match_operator:SI 7 "shiftable_operator"
9997 [(match_operand:SI 3 "s_register_operand" "r")
9998 (match_operand:SI 4 "arm_rhs_operand" "rI")])))]
10000 "%I6%d5\\t%0, %1, %2\;%I7%D5\\t%0, %3, %4"
10001 [(set_attr "conds" "use")
10002 (set_attr "length" "8")
10003 (set_attr "type" "multiple")]
10006 (define_insn "*ifcompare_arith_move"
10007 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10008 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
10009 [(match_operand:SI 2 "s_register_operand" "r,r")
10010 (match_operand:SI 3 "arm_add_operand" "rIL,rIL")])
10011 (match_operator:SI 7 "shiftable_operator"
10012 [(match_operand:SI 4 "s_register_operand" "r,r")
10013 (match_operand:SI 5 "arm_rhs_operand" "rI,rI")])
10014 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))
10015 (clobber (reg:CC CC_REGNUM))]
10018 /* If we have an operation where (op x 0) is the identity operation and
10019 the conditional operator is LT or GE and we are comparing against zero and
10020 everything is in registers then we can do this in two instructions. */
10021 if (operands[3] == const0_rtx
10022 && GET_CODE (operands[7]) != AND
10023 && REG_P (operands[5])
10024 && REG_P (operands[1])
10025 && REGNO (operands[1]) == REGNO (operands[4])
10026 && REGNO (operands[4]) != REGNO (operands[0]))
10028 if (GET_CODE (operands[6]) == LT)
10029 return \"and\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\";
10030 else if (GET_CODE (operands[6]) == GE)
10031 return \"bic\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\";
10033 if (CONST_INT_P (operands[3])
10034 && !const_ok_for_arm (INTVAL (operands[3])))
10035 output_asm_insn (\"cmn\\t%2, #%n3\", operands);
10037 output_asm_insn (\"cmp\\t%2, %3\", operands);
10038 output_asm_insn (\"%I7%d6\\t%0, %4, %5\", operands);
10039 if (which_alternative != 0)
10040 return \"mov%D6\\t%0, %1\";
10043 [(set_attr "conds" "clob")
10044 (set_attr "length" "8,12")
10045 (set_attr "type" "multiple")]
10048 (define_insn "*if_arith_move"
10049 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10050 (if_then_else:SI (match_operator 4 "arm_comparison_operator"
10051 [(match_operand 6 "cc_register" "") (const_int 0)])
10052 (match_operator:SI 5 "shiftable_operator"
10053 [(match_operand:SI 2 "s_register_operand" "r,r")
10054 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
10055 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))]
10058 %I5%d4\\t%0, %2, %3
10059 %I5%d4\\t%0, %2, %3\;mov%D4\\t%0, %1"
10060 [(set_attr "conds" "use")
10061 (set_attr "length" "4,8")
10062 (set_attr_alternative "type"
10063 [(if_then_else (match_operand 3 "const_int_operand" "")
10064 (const_string "alu_shift_imm" )
10065 (const_string "alu_shift_reg"))
10066 (const_string "multiple")])]
10069 (define_insn "*ifcompare_move_arith"
10070 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10071 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
10072 [(match_operand:SI 4 "s_register_operand" "r,r")
10073 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
10074 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
10075 (match_operator:SI 7 "shiftable_operator"
10076 [(match_operand:SI 2 "s_register_operand" "r,r")
10077 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
10078 (clobber (reg:CC CC_REGNUM))]
10081 /* If we have an operation where (op x 0) is the identity operation and
10082 the conditional operator is LT or GE and we are comparing against zero and
10083 everything is in registers then we can do this in two instructions */
10084 if (operands[5] == const0_rtx
10085 && GET_CODE (operands[7]) != AND
10086 && REG_P (operands[3])
10087 && REG_P (operands[1])
10088 && REGNO (operands[1]) == REGNO (operands[2])
10089 && REGNO (operands[2]) != REGNO (operands[0]))
10091 if (GET_CODE (operands[6]) == GE)
10092 return \"and\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\";
10093 else if (GET_CODE (operands[6]) == LT)
10094 return \"bic\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\";
10097 if (CONST_INT_P (operands[5])
10098 && !const_ok_for_arm (INTVAL (operands[5])))
10099 output_asm_insn (\"cmn\\t%4, #%n5\", operands);
10101 output_asm_insn (\"cmp\\t%4, %5\", operands);
10103 if (which_alternative != 0)
10104 output_asm_insn (\"mov%d6\\t%0, %1\", operands);
10105 return \"%I7%D6\\t%0, %2, %3\";
10107 [(set_attr "conds" "clob")
10108 (set_attr "length" "8,12")
10109 (set_attr "type" "multiple")]
10112 (define_insn "*if_move_arith"
10113 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10115 (match_operator 4 "arm_comparison_operator"
10116 [(match_operand 6 "cc_register" "") (const_int 0)])
10117 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
10118 (match_operator:SI 5 "shiftable_operator"
10119 [(match_operand:SI 2 "s_register_operand" "r,r")
10120 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))]
10123 %I5%D4\\t%0, %2, %3
10124 %I5%D4\\t%0, %2, %3\;mov%d4\\t%0, %1"
10125 [(set_attr "conds" "use")
10126 (set_attr "length" "4,8")
10127 (set_attr_alternative "type"
10128 [(if_then_else (match_operand 3 "const_int_operand" "")
10129 (const_string "alu_shift_imm" )
10130 (const_string "alu_shift_reg"))
10131 (const_string "multiple")])]
10134 (define_insn "*ifcompare_move_not"
10135 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10137 (match_operator 5 "arm_comparison_operator"
10138 [(match_operand:SI 3 "s_register_operand" "r,r")
10139 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
10140 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
10142 (match_operand:SI 2 "s_register_operand" "r,r"))))
10143 (clobber (reg:CC CC_REGNUM))]
10146 [(set_attr "conds" "clob")
10147 (set_attr "length" "8,12")
10148 (set_attr "type" "multiple")]
10151 (define_insn "*if_move_not"
10152 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
10154 (match_operator 4 "arm_comparison_operator"
10155 [(match_operand 3 "cc_register" "") (const_int 0)])
10156 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
10157 (not:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))))]
10161 mov%d4\\t%0, %1\;mvn%D4\\t%0, %2
10162 mvn%d4\\t%0, #%B1\;mvn%D4\\t%0, %2"
10163 [(set_attr "conds" "use")
10164 (set_attr "type" "mvn_reg")
10165 (set_attr "length" "4,8,8")
10166 (set_attr "type" "mvn_reg,multiple,multiple")]
10169 (define_insn "*ifcompare_not_move"
10170 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10172 (match_operator 5 "arm_comparison_operator"
10173 [(match_operand:SI 3 "s_register_operand" "r,r")
10174 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
10176 (match_operand:SI 2 "s_register_operand" "r,r"))
10177 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
10178 (clobber (reg:CC CC_REGNUM))]
10181 [(set_attr "conds" "clob")
10182 (set_attr "length" "8,12")
10183 (set_attr "type" "multiple")]
10186 (define_insn "*if_not_move"
10187 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
10189 (match_operator 4 "arm_comparison_operator"
10190 [(match_operand 3 "cc_register" "") (const_int 0)])
10191 (not:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))
10192 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
10196 mov%D4\\t%0, %1\;mvn%d4\\t%0, %2
10197 mvn%D4\\t%0, #%B1\;mvn%d4\\t%0, %2"
10198 [(set_attr "conds" "use")
10199 (set_attr "type" "mvn_reg,multiple,multiple")
10200 (set_attr "length" "4,8,8")]
10203 (define_insn "*ifcompare_shift_move"
10204 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10206 (match_operator 6 "arm_comparison_operator"
10207 [(match_operand:SI 4 "s_register_operand" "r,r")
10208 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
10209 (match_operator:SI 7 "shift_operator"
10210 [(match_operand:SI 2 "s_register_operand" "r,r")
10211 (match_operand:SI 3 "arm_rhs_operand" "rM,rM")])
10212 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
10213 (clobber (reg:CC CC_REGNUM))]
10216 [(set_attr "conds" "clob")
10217 (set_attr "length" "8,12")
10218 (set_attr "type" "multiple")]
10221 (define_insn "*if_shift_move"
10222 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
10224 (match_operator 5 "arm_comparison_operator"
10225 [(match_operand 6 "cc_register" "") (const_int 0)])
10226 (match_operator:SI 4 "shift_operator"
10227 [(match_operand:SI 2 "s_register_operand" "r,r,r")
10228 (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM")])
10229 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
10233 mov%D5\\t%0, %1\;mov%d5\\t%0, %2%S4
10234 mvn%D5\\t%0, #%B1\;mov%d5\\t%0, %2%S4"
10235 [(set_attr "conds" "use")
10236 (set_attr "shift" "2")
10237 (set_attr "length" "4,8,8")
10238 (set_attr_alternative "type"
10239 [(if_then_else (match_operand 3 "const_int_operand" "")
10240 (const_string "mov_shift" )
10241 (const_string "mov_shift_reg"))
10242 (const_string "multiple")
10243 (const_string "multiple")])]
10246 (define_insn "*ifcompare_move_shift"
10247 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10249 (match_operator 6 "arm_comparison_operator"
10250 [(match_operand:SI 4 "s_register_operand" "r,r")
10251 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
10252 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
10253 (match_operator:SI 7 "shift_operator"
10254 [(match_operand:SI 2 "s_register_operand" "r,r")
10255 (match_operand:SI 3 "arm_rhs_operand" "rM,rM")])))
10256 (clobber (reg:CC CC_REGNUM))]
10259 [(set_attr "conds" "clob")
10260 (set_attr "length" "8,12")
10261 (set_attr "type" "multiple")]
10264 (define_insn "*if_move_shift"
10265 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
10267 (match_operator 5 "arm_comparison_operator"
10268 [(match_operand 6 "cc_register" "") (const_int 0)])
10269 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
10270 (match_operator:SI 4 "shift_operator"
10271 [(match_operand:SI 2 "s_register_operand" "r,r,r")
10272 (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM")])))]
10276 mov%d5\\t%0, %1\;mov%D5\\t%0, %2%S4
10277 mvn%d5\\t%0, #%B1\;mov%D5\\t%0, %2%S4"
10278 [(set_attr "conds" "use")
10279 (set_attr "shift" "2")
10280 (set_attr "length" "4,8,8")
10281 (set_attr_alternative "type"
10282 [(if_then_else (match_operand 3 "const_int_operand" "")
10283 (const_string "mov_shift" )
10284 (const_string "mov_shift_reg"))
10285 (const_string "multiple")
10286 (const_string "multiple")])]
10289 (define_insn "*ifcompare_shift_shift"
10290 [(set (match_operand:SI 0 "s_register_operand" "=r")
10292 (match_operator 7 "arm_comparison_operator"
10293 [(match_operand:SI 5 "s_register_operand" "r")
10294 (match_operand:SI 6 "arm_add_operand" "rIL")])
10295 (match_operator:SI 8 "shift_operator"
10296 [(match_operand:SI 1 "s_register_operand" "r")
10297 (match_operand:SI 2 "arm_rhs_operand" "rM")])
10298 (match_operator:SI 9 "shift_operator"
10299 [(match_operand:SI 3 "s_register_operand" "r")
10300 (match_operand:SI 4 "arm_rhs_operand" "rM")])))
10301 (clobber (reg:CC CC_REGNUM))]
10304 [(set_attr "conds" "clob")
10305 (set_attr "length" "12")
10306 (set_attr "type" "multiple")]
10309 (define_insn "*if_shift_shift"
10310 [(set (match_operand:SI 0 "s_register_operand" "=r")
10312 (match_operator 5 "arm_comparison_operator"
10313 [(match_operand 8 "cc_register" "") (const_int 0)])
10314 (match_operator:SI 6 "shift_operator"
10315 [(match_operand:SI 1 "s_register_operand" "r")
10316 (match_operand:SI 2 "arm_rhs_operand" "rM")])
10317 (match_operator:SI 7 "shift_operator"
10318 [(match_operand:SI 3 "s_register_operand" "r")
10319 (match_operand:SI 4 "arm_rhs_operand" "rM")])))]
10321 "mov%d5\\t%0, %1%S6\;mov%D5\\t%0, %3%S7"
10322 [(set_attr "conds" "use")
10323 (set_attr "shift" "1")
10324 (set_attr "length" "8")
10325 (set (attr "type") (if_then_else
10326 (and (match_operand 2 "const_int_operand" "")
10327 (match_operand 4 "const_int_operand" ""))
10328 (const_string "mov_shift")
10329 (const_string "mov_shift_reg")))]
10332 (define_insn "*ifcompare_not_arith"
10333 [(set (match_operand:SI 0 "s_register_operand" "=r")
10335 (match_operator 6 "arm_comparison_operator"
10336 [(match_operand:SI 4 "s_register_operand" "r")
10337 (match_operand:SI 5 "arm_add_operand" "rIL")])
10338 (not:SI (match_operand:SI 1 "s_register_operand" "r"))
10339 (match_operator:SI 7 "shiftable_operator"
10340 [(match_operand:SI 2 "s_register_operand" "r")
10341 (match_operand:SI 3 "arm_rhs_operand" "rI")])))
10342 (clobber (reg:CC CC_REGNUM))]
10345 [(set_attr "conds" "clob")
10346 (set_attr "length" "12")
10347 (set_attr "type" "multiple")]
10350 (define_insn "*if_not_arith"
10351 [(set (match_operand:SI 0 "s_register_operand" "=r")
10353 (match_operator 5 "arm_comparison_operator"
10354 [(match_operand 4 "cc_register" "") (const_int 0)])
10355 (not:SI (match_operand:SI 1 "s_register_operand" "r"))
10356 (match_operator:SI 6 "shiftable_operator"
10357 [(match_operand:SI 2 "s_register_operand" "r")
10358 (match_operand:SI 3 "arm_rhs_operand" "rI")])))]
10360 "mvn%d5\\t%0, %1\;%I6%D5\\t%0, %2, %3"
10361 [(set_attr "conds" "use")
10362 (set_attr "type" "mvn_reg")
10363 (set_attr "length" "8")]
10366 (define_insn "*ifcompare_arith_not"
10367 [(set (match_operand:SI 0 "s_register_operand" "=r")
10369 (match_operator 6 "arm_comparison_operator"
10370 [(match_operand:SI 4 "s_register_operand" "r")
10371 (match_operand:SI 5 "arm_add_operand" "rIL")])
10372 (match_operator:SI 7 "shiftable_operator"
10373 [(match_operand:SI 2 "s_register_operand" "r")
10374 (match_operand:SI 3 "arm_rhs_operand" "rI")])
10375 (not:SI (match_operand:SI 1 "s_register_operand" "r"))))
10376 (clobber (reg:CC CC_REGNUM))]
10379 [(set_attr "conds" "clob")
10380 (set_attr "length" "12")
10381 (set_attr "type" "multiple")]
10384 (define_insn "*if_arith_not"
10385 [(set (match_operand:SI 0 "s_register_operand" "=r")
10387 (match_operator 5 "arm_comparison_operator"
10388 [(match_operand 4 "cc_register" "") (const_int 0)])
10389 (match_operator:SI 6 "shiftable_operator"
10390 [(match_operand:SI 2 "s_register_operand" "r")
10391 (match_operand:SI 3 "arm_rhs_operand" "rI")])
10392 (not:SI (match_operand:SI 1 "s_register_operand" "r"))))]
10394 "mvn%D5\\t%0, %1\;%I6%d5\\t%0, %2, %3"
10395 [(set_attr "conds" "use")
10396 (set_attr "type" "multiple")
10397 (set_attr "length" "8")]
10400 (define_insn "*ifcompare_neg_move"
10401 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10403 (match_operator 5 "arm_comparison_operator"
10404 [(match_operand:SI 3 "s_register_operand" "r,r")
10405 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
10406 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r"))
10407 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
10408 (clobber (reg:CC CC_REGNUM))]
10411 [(set_attr "conds" "clob")
10412 (set_attr "length" "8,12")
10413 (set_attr "type" "multiple")]
10416 (define_insn_and_split "*if_neg_move"
10417 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
10419 (match_operator 4 "arm_comparison_operator"
10420 [(match_operand 3 "cc_register" "") (const_int 0)])
10421 (neg:SI (match_operand:SI 2 "s_register_operand" "l,r"))
10422 (match_operand:SI 1 "s_register_operand" "0,0")))]
10425 "&& reload_completed"
10426 [(cond_exec (match_op_dup 4 [(match_dup 3) (const_int 0)])
10427 (set (match_dup 0) (neg:SI (match_dup 2))))]
10429 [(set_attr "conds" "use")
10430 (set_attr "length" "4")
10431 (set_attr "arch" "t2,32")
10432 (set_attr "enabled_for_depr_it" "yes,no")
10433 (set_attr "type" "logic_shift_imm")]
10436 (define_insn "*ifcompare_move_neg"
10437 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10439 (match_operator 5 "arm_comparison_operator"
10440 [(match_operand:SI 3 "s_register_operand" "r,r")
10441 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
10442 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
10443 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r"))))
10444 (clobber (reg:CC CC_REGNUM))]
10447 [(set_attr "conds" "clob")
10448 (set_attr "length" "8,12")
10449 (set_attr "type" "multiple")]
10452 (define_insn_and_split "*if_move_neg"
10453 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
10455 (match_operator 4 "arm_comparison_operator"
10456 [(match_operand 3 "cc_register" "") (const_int 0)])
10457 (match_operand:SI 1 "s_register_operand" "0,0")
10458 (neg:SI (match_operand:SI 2 "s_register_operand" "l,r"))))]
10461 "&& reload_completed"
10462 [(cond_exec (match_dup 5)
10463 (set (match_dup 0) (neg:SI (match_dup 2))))]
10465 machine_mode mode = GET_MODE (operands[3]);
10466 rtx_code rc = GET_CODE (operands[4]);
10468 if (mode == CCFPmode || mode == CCFPEmode)
10469 rc = reverse_condition_maybe_unordered (rc);
10471 rc = reverse_condition (rc);
10473 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[3], const0_rtx);
10475 [(set_attr "conds" "use")
10476 (set_attr "length" "4")
10477 (set_attr "arch" "t2,32")
10478 (set_attr "enabled_for_depr_it" "yes,no")
10479 (set_attr "type" "logic_shift_imm")]
10482 (define_insn "*arith_adjacentmem"
10483 [(set (match_operand:SI 0 "s_register_operand" "=r")
10484 (match_operator:SI 1 "shiftable_operator"
10485 [(match_operand:SI 2 "memory_operand" "m")
10486 (match_operand:SI 3 "memory_operand" "m")]))
10487 (clobber (match_scratch:SI 4 "=r"))]
10488 "TARGET_ARM && adjacent_mem_locations (operands[2], operands[3])"
10494 HOST_WIDE_INT val1 = 0, val2 = 0;
10496 if (REGNO (operands[0]) > REGNO (operands[4]))
10498 ldm[1] = operands[4];
10499 ldm[2] = operands[0];
10503 ldm[1] = operands[0];
10504 ldm[2] = operands[4];
10507 base_reg = XEXP (operands[2], 0);
10509 if (!REG_P (base_reg))
10511 val1 = INTVAL (XEXP (base_reg, 1));
10512 base_reg = XEXP (base_reg, 0);
10515 if (!REG_P (XEXP (operands[3], 0)))
10516 val2 = INTVAL (XEXP (XEXP (operands[3], 0), 1));
10518 arith[0] = operands[0];
10519 arith[3] = operands[1];
10533 if (val1 !=0 && val2 != 0)
10537 if (val1 == 4 || val2 == 4)
10538 /* Other val must be 8, since we know they are adjacent and neither
10540 output_asm_insn (\"ldmib%?\\t%0, {%1, %2}\", ldm);
10541 else if (const_ok_for_arm (val1) || const_ok_for_arm (-val1))
10543 ldm[0] = ops[0] = operands[4];
10545 ops[2] = GEN_INT (val1);
10546 output_add_immediate (ops);
10548 output_asm_insn (\"ldmia%?\\t%0, {%1, %2}\", ldm);
10550 output_asm_insn (\"ldmda%?\\t%0, {%1, %2}\", ldm);
10554 /* Offset is out of range for a single add, so use two ldr. */
10557 ops[2] = GEN_INT (val1);
10558 output_asm_insn (\"ldr%?\\t%0, [%1, %2]\", ops);
10560 ops[2] = GEN_INT (val2);
10561 output_asm_insn (\"ldr%?\\t%0, [%1, %2]\", ops);
10564 else if (val1 != 0)
10567 output_asm_insn (\"ldmda%?\\t%0, {%1, %2}\", ldm);
10569 output_asm_insn (\"ldmia%?\\t%0, {%1, %2}\", ldm);
10574 output_asm_insn (\"ldmia%?\\t%0, {%1, %2}\", ldm);
10576 output_asm_insn (\"ldmda%?\\t%0, {%1, %2}\", ldm);
10578 output_asm_insn (\"%I3%?\\t%0, %1, %2\", arith);
10581 [(set_attr "length" "12")
10582 (set_attr "predicable" "yes")
10583 (set_attr "type" "load1")]
10586 ; This pattern is never tried by combine, so do it as a peephole
10589 [(set (match_operand:SI 0 "arm_general_register_operand" "")
10590 (match_operand:SI 1 "arm_general_register_operand" ""))
10591 (set (reg:CC CC_REGNUM)
10592 (compare:CC (match_dup 1) (const_int 0)))]
10594 [(parallel [(set (reg:CC CC_REGNUM) (compare:CC (match_dup 1) (const_int 0)))
10595 (set (match_dup 0) (match_dup 1))])]
10600 [(set (match_operand:SI 0 "s_register_operand" "")
10601 (and:SI (ge:SI (match_operand:SI 1 "s_register_operand" "")
10603 (neg:SI (match_operator:SI 2 "arm_comparison_operator"
10604 [(match_operand:SI 3 "s_register_operand" "")
10605 (match_operand:SI 4 "arm_rhs_operand" "")]))))
10606 (clobber (match_operand:SI 5 "s_register_operand" ""))]
10608 [(set (match_dup 5) (not:SI (ashiftrt:SI (match_dup 1) (const_int 31))))
10609 (set (match_dup 0) (and:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
10614 ;; This split can be used because CC_Z mode implies that the following
10615 ;; branch will be an equality, or an unsigned inequality, so the sign
10616 ;; extension is not needed.
10619 [(set (reg:CC_Z CC_REGNUM)
10621 (ashift:SI (subreg:SI (match_operand:QI 0 "memory_operand" "") 0)
10623 (match_operand 1 "const_int_operand" "")))
10624 (clobber (match_scratch:SI 2 ""))]
10626 && ((UINTVAL (operands[1]))
10627 == ((UINTVAL (operands[1])) >> 24) << 24)"
10628 [(set (match_dup 2) (zero_extend:SI (match_dup 0)))
10629 (set (reg:CC CC_REGNUM) (compare:CC (match_dup 2) (match_dup 1)))]
10631 operands[1] = GEN_INT (((unsigned long) INTVAL (operands[1])) >> 24);
10634 ;; ??? Check the patterns above for Thumb-2 usefulness
10636 (define_expand "prologue"
10637 [(clobber (const_int 0))]
10640 arm_expand_prologue ();
10642 thumb1_expand_prologue ();
10647 (define_expand "epilogue"
10648 [(clobber (const_int 0))]
10651 if (crtl->calls_eh_return)
10652 emit_insn (gen_force_register_use (gen_rtx_REG (Pmode, 2)));
10655 thumb1_expand_epilogue ();
10656 emit_jump_insn (gen_rtx_UNSPEC_VOLATILE (VOIDmode,
10657 gen_rtvec (1, ret_rtx), VUNSPEC_EPILOGUE));
10659 else if (HAVE_return)
10661 /* HAVE_return is testing for USE_RETURN_INSN (FALSE). Hence,
10662 no need for explicit testing again. */
10663 emit_jump_insn (gen_return ());
10665 else if (TARGET_32BIT)
10667 arm_expand_epilogue (true);
10673 ;; Note - although unspec_volatile's USE all hard registers,
10674 ;; USEs are ignored after relaod has completed. Thus we need
10675 ;; to add an unspec of the link register to ensure that flow
10676 ;; does not think that it is unused by the sibcall branch that
10677 ;; will replace the standard function epilogue.
10678 (define_expand "sibcall_epilogue"
10679 [(parallel [(unspec:SI [(reg:SI LR_REGNUM)] UNSPEC_REGISTER_USE)
10680 (unspec_volatile [(return)] VUNSPEC_EPILOGUE)])]
10683 arm_expand_epilogue (false);
10688 (define_expand "eh_epilogue"
10689 [(use (match_operand:SI 0 "register_operand" ""))
10690 (use (match_operand:SI 1 "register_operand" ""))
10691 (use (match_operand:SI 2 "register_operand" ""))]
10695 cfun->machine->eh_epilogue_sp_ofs = operands[1];
10696 if (!REG_P (operands[2]) || REGNO (operands[2]) != 2)
10698 rtx ra = gen_rtx_REG (Pmode, 2);
10700 emit_move_insn (ra, operands[2]);
10703 /* This is a hack -- we may have crystalized the function type too
10705 cfun->machine->func_type = 0;
10709 ;; This split is only used during output to reduce the number of patterns
10710 ;; that need assembler instructions adding to them. We allowed the setting
10711 ;; of the conditions to be implicit during rtl generation so that
10712 ;; the conditional compare patterns would work. However this conflicts to
10713 ;; some extent with the conditional data operations, so we have to split them
10716 ;; ??? Need to audit these splitters for Thumb-2. Why isn't normal
10717 ;; conditional execution sufficient?
10720 [(set (match_operand:SI 0 "s_register_operand" "")
10721 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10722 [(match_operand 2 "" "") (match_operand 3 "" "")])
10724 (match_operand 4 "" "")))
10725 (clobber (reg:CC CC_REGNUM))]
10726 "TARGET_ARM && reload_completed"
10727 [(set (match_dup 5) (match_dup 6))
10728 (cond_exec (match_dup 7)
10729 (set (match_dup 0) (match_dup 4)))]
10732 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10733 operands[2], operands[3]);
10734 enum rtx_code rc = GET_CODE (operands[1]);
10736 operands[5] = gen_rtx_REG (mode, CC_REGNUM);
10737 operands[6] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10738 if (mode == CCFPmode || mode == CCFPEmode)
10739 rc = reverse_condition_maybe_unordered (rc);
10741 rc = reverse_condition (rc);
10743 operands[7] = gen_rtx_fmt_ee (rc, VOIDmode, operands[5], const0_rtx);
10748 [(set (match_operand:SI 0 "s_register_operand" "")
10749 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10750 [(match_operand 2 "" "") (match_operand 3 "" "")])
10751 (match_operand 4 "" "")
10753 (clobber (reg:CC CC_REGNUM))]
10754 "TARGET_ARM && reload_completed"
10755 [(set (match_dup 5) (match_dup 6))
10756 (cond_exec (match_op_dup 1 [(match_dup 5) (const_int 0)])
10757 (set (match_dup 0) (match_dup 4)))]
10760 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10761 operands[2], operands[3]);
10763 operands[5] = gen_rtx_REG (mode, CC_REGNUM);
10764 operands[6] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10769 [(set (match_operand:SI 0 "s_register_operand" "")
10770 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10771 [(match_operand 2 "" "") (match_operand 3 "" "")])
10772 (match_operand 4 "" "")
10773 (match_operand 5 "" "")))
10774 (clobber (reg:CC CC_REGNUM))]
10775 "TARGET_ARM && reload_completed"
10776 [(set (match_dup 6) (match_dup 7))
10777 (cond_exec (match_op_dup 1 [(match_dup 6) (const_int 0)])
10778 (set (match_dup 0) (match_dup 4)))
10779 (cond_exec (match_dup 8)
10780 (set (match_dup 0) (match_dup 5)))]
10783 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10784 operands[2], operands[3]);
10785 enum rtx_code rc = GET_CODE (operands[1]);
10787 operands[6] = gen_rtx_REG (mode, CC_REGNUM);
10788 operands[7] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10789 if (mode == CCFPmode || mode == CCFPEmode)
10790 rc = reverse_condition_maybe_unordered (rc);
10792 rc = reverse_condition (rc);
10794 operands[8] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
10799 [(set (match_operand:SI 0 "s_register_operand" "")
10800 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10801 [(match_operand:SI 2 "s_register_operand" "")
10802 (match_operand:SI 3 "arm_add_operand" "")])
10803 (match_operand:SI 4 "arm_rhs_operand" "")
10805 (match_operand:SI 5 "s_register_operand" ""))))
10806 (clobber (reg:CC CC_REGNUM))]
10807 "TARGET_ARM && reload_completed"
10808 [(set (match_dup 6) (match_dup 7))
10809 (cond_exec (match_op_dup 1 [(match_dup 6) (const_int 0)])
10810 (set (match_dup 0) (match_dup 4)))
10811 (cond_exec (match_dup 8)
10812 (set (match_dup 0) (not:SI (match_dup 5))))]
10815 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10816 operands[2], operands[3]);
10817 enum rtx_code rc = GET_CODE (operands[1]);
10819 operands[6] = gen_rtx_REG (mode, CC_REGNUM);
10820 operands[7] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10821 if (mode == CCFPmode || mode == CCFPEmode)
10822 rc = reverse_condition_maybe_unordered (rc);
10824 rc = reverse_condition (rc);
10826 operands[8] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
10830 (define_insn "*cond_move_not"
10831 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10832 (if_then_else:SI (match_operator 4 "arm_comparison_operator"
10833 [(match_operand 3 "cc_register" "") (const_int 0)])
10834 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
10836 (match_operand:SI 2 "s_register_operand" "r,r"))))]
10840 mov%d4\\t%0, %1\;mvn%D4\\t%0, %2"
10841 [(set_attr "conds" "use")
10842 (set_attr "type" "mvn_reg,multiple")
10843 (set_attr "length" "4,8")]
10846 ;; The next two patterns occur when an AND operation is followed by a
10847 ;; scc insn sequence
10849 (define_insn "*sign_extract_onebit"
10850 [(set (match_operand:SI 0 "s_register_operand" "=r")
10851 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
10853 (match_operand:SI 2 "const_int_operand" "n")))
10854 (clobber (reg:CC CC_REGNUM))]
10857 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
10858 output_asm_insn (\"ands\\t%0, %1, %2\", operands);
10859 return \"mvnne\\t%0, #0\";
10861 [(set_attr "conds" "clob")
10862 (set_attr "length" "8")
10863 (set_attr "type" "multiple")]
10866 (define_insn "*not_signextract_onebit"
10867 [(set (match_operand:SI 0 "s_register_operand" "=r")
10869 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
10871 (match_operand:SI 2 "const_int_operand" "n"))))
10872 (clobber (reg:CC CC_REGNUM))]
10875 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
10876 output_asm_insn (\"tst\\t%1, %2\", operands);
10877 output_asm_insn (\"mvneq\\t%0, #0\", operands);
10878 return \"movne\\t%0, #0\";
10880 [(set_attr "conds" "clob")
10881 (set_attr "length" "12")
10882 (set_attr "type" "multiple")]
10884 ;; ??? The above patterns need auditing for Thumb-2
10886 ;; Push multiple registers to the stack. Registers are in parallel (use ...)
10887 ;; expressions. For simplicity, the first register is also in the unspec
10889 ;; To avoid the usage of GNU extension, the length attribute is computed
10890 ;; in a C function arm_attr_length_push_multi.
10891 (define_insn "*push_multi"
10892 [(match_parallel 2 "multi_register_push"
10893 [(set (match_operand:BLK 0 "push_mult_memory_operand" "")
10894 (unspec:BLK [(match_operand:SI 1 "s_register_operand" "")]
10895 UNSPEC_PUSH_MULT))])]
10899 int num_saves = XVECLEN (operands[2], 0);
10901 /* For the StrongARM at least it is faster to
10902 use STR to store only a single register.
10903 In Thumb mode always use push, and the assembler will pick
10904 something appropriate. */
10905 if (num_saves == 1 && TARGET_ARM)
10906 output_asm_insn (\"str%?\\t%1, [%m0, #-4]!\", operands);
10913 strcpy (pattern, \"push%?\\t{%1\");
10915 strcpy (pattern, \"push\\t{%1\");
10917 for (i = 1; i < num_saves; i++)
10919 strcat (pattern, \", %|\");
10921 reg_names[REGNO (XEXP (XVECEXP (operands[2], 0, i), 0))]);
10924 strcat (pattern, \"}\");
10925 output_asm_insn (pattern, operands);
10930 [(set_attr "type" "store4")
10931 (set (attr "length")
10932 (symbol_ref "arm_attr_length_push_multi (operands[2], operands[1])"))]
10935 (define_insn "stack_tie"
10936 [(set (mem:BLK (scratch))
10937 (unspec:BLK [(match_operand:SI 0 "s_register_operand" "rk")
10938 (match_operand:SI 1 "s_register_operand" "rk")]
10942 [(set_attr "length" "0")
10943 (set_attr "type" "block")]
10946 ;; Pop (as used in epilogue RTL)
10948 (define_insn "*load_multiple_with_writeback"
10949 [(match_parallel 0 "load_multiple_operation"
10950 [(set (match_operand:SI 1 "s_register_operand" "+rk")
10951 (plus:SI (match_dup 1)
10952 (match_operand:SI 2 "const_int_I_operand" "I")))
10953 (set (match_operand:SI 3 "s_register_operand" "=rk")
10954 (mem:SI (match_dup 1)))
10956 "TARGET_32BIT && (reload_in_progress || reload_completed)"
10959 arm_output_multireg_pop (operands, /*return_pc=*/false,
10960 /*cond=*/const_true_rtx,
10966 [(set_attr "type" "load4")
10967 (set_attr "predicable" "yes")
10968 (set (attr "length")
10969 (symbol_ref "arm_attr_length_pop_multi (operands,
10970 /*return_pc=*/false,
10971 /*write_back_p=*/true)"))]
10974 ;; Pop with return (as used in epilogue RTL)
10976 ;; This instruction is generated when the registers are popped at the end of
10977 ;; epilogue. Here, instead of popping the value into LR and then generating
10978 ;; jump to LR, value is popped into PC directly. Hence, the pattern is combined
10980 (define_insn "*pop_multiple_with_writeback_and_return"
10981 [(match_parallel 0 "pop_multiple_return"
10983 (set (match_operand:SI 1 "s_register_operand" "+rk")
10984 (plus:SI (match_dup 1)
10985 (match_operand:SI 2 "const_int_I_operand" "I")))
10986 (set (match_operand:SI 3 "s_register_operand" "=rk")
10987 (mem:SI (match_dup 1)))
10989 "TARGET_32BIT && (reload_in_progress || reload_completed)"
10992 arm_output_multireg_pop (operands, /*return_pc=*/true,
10993 /*cond=*/const_true_rtx,
10999 [(set_attr "type" "load4")
11000 (set_attr "predicable" "yes")
11001 (set (attr "length")
11002 (symbol_ref "arm_attr_length_pop_multi (operands, /*return_pc=*/true,
11003 /*write_back_p=*/true)"))]
11006 (define_insn "*pop_multiple_with_return"
11007 [(match_parallel 0 "pop_multiple_return"
11009 (set (match_operand:SI 2 "s_register_operand" "=rk")
11010 (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
11012 "TARGET_32BIT && (reload_in_progress || reload_completed)"
11015 arm_output_multireg_pop (operands, /*return_pc=*/true,
11016 /*cond=*/const_true_rtx,
11022 [(set_attr "type" "load4")
11023 (set_attr "predicable" "yes")
11024 (set (attr "length")
11025 (symbol_ref "arm_attr_length_pop_multi (operands, /*return_pc=*/true,
11026 /*write_back_p=*/false)"))]
11029 ;; Load into PC and return
11030 (define_insn "*ldr_with_return"
11032 (set (reg:SI PC_REGNUM)
11033 (mem:SI (post_inc:SI (match_operand:SI 0 "s_register_operand" "+rk"))))]
11034 "TARGET_32BIT && (reload_in_progress || reload_completed)"
11035 "ldr%?\t%|pc, [%0], #4"
11036 [(set_attr "type" "load1")
11037 (set_attr "predicable" "yes")]
11039 ;; Pop for floating point registers (as used in epilogue RTL)
11040 (define_insn "*vfp_pop_multiple_with_writeback"
11041 [(match_parallel 0 "pop_multiple_fp"
11042 [(set (match_operand:SI 1 "s_register_operand" "+rk")
11043 (plus:SI (match_dup 1)
11044 (match_operand:SI 2 "const_int_I_operand" "I")))
11045 (set (match_operand:DF 3 "vfp_hard_register_operand" "")
11046 (mem:DF (match_dup 1)))])]
11047 "TARGET_32BIT && TARGET_HARD_FLOAT"
11050 int num_regs = XVECLEN (operands[0], 0);
11053 strcpy (pattern, \"vldm\\t\");
11054 strcat (pattern, reg_names[REGNO (SET_DEST (XVECEXP (operands[0], 0, 0)))]);
11055 strcat (pattern, \"!, {\");
11056 op_list[0] = XEXP (XVECEXP (operands[0], 0, 1), 0);
11057 strcat (pattern, \"%P0\");
11058 if ((num_regs - 1) > 1)
11060 strcat (pattern, \"-%P1\");
11061 op_list [1] = XEXP (XVECEXP (operands[0], 0, num_regs - 1), 0);
11064 strcat (pattern, \"}\");
11065 output_asm_insn (pattern, op_list);
11069 [(set_attr "type" "load4")
11070 (set_attr "conds" "unconditional")
11071 (set_attr "predicable" "no")]
11074 ;; Special patterns for dealing with the constant pool
11076 (define_insn "align_4"
11077 [(unspec_volatile [(const_int 0)] VUNSPEC_ALIGN)]
11080 assemble_align (32);
11083 [(set_attr "type" "no_insn")]
11086 (define_insn "align_8"
11087 [(unspec_volatile [(const_int 0)] VUNSPEC_ALIGN8)]
11090 assemble_align (64);
11093 [(set_attr "type" "no_insn")]
11096 (define_insn "consttable_end"
11097 [(unspec_volatile [(const_int 0)] VUNSPEC_POOL_END)]
11100 making_const_table = FALSE;
11103 [(set_attr "type" "no_insn")]
11106 (define_insn "consttable_1"
11107 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_1)]
11110 making_const_table = TRUE;
11111 assemble_integer (operands[0], 1, BITS_PER_WORD, 1);
11112 assemble_zeros (3);
11115 [(set_attr "length" "4")
11116 (set_attr "type" "no_insn")]
11119 (define_insn "consttable_2"
11120 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_2)]
11124 rtx x = operands[0];
11125 making_const_table = TRUE;
11126 switch (GET_MODE_CLASS (GET_MODE (x)))
11129 arm_emit_fp16_const (x);
11132 assemble_integer (operands[0], 2, BITS_PER_WORD, 1);
11133 assemble_zeros (2);
11138 [(set_attr "length" "4")
11139 (set_attr "type" "no_insn")]
11142 (define_insn "consttable_4"
11143 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_4)]
11147 rtx x = operands[0];
11148 making_const_table = TRUE;
11149 switch (GET_MODE_CLASS (GET_MODE (x)))
11152 assemble_real (*CONST_DOUBLE_REAL_VALUE (x), GET_MODE (x),
11156 /* XXX: Sometimes gcc does something really dumb and ends up with
11157 a HIGH in a constant pool entry, usually because it's trying to
11158 load into a VFP register. We know this will always be used in
11159 combination with a LO_SUM which ignores the high bits, so just
11160 strip off the HIGH. */
11161 if (GET_CODE (x) == HIGH)
11163 assemble_integer (x, 4, BITS_PER_WORD, 1);
11164 mark_symbol_refs_as_used (x);
11169 [(set_attr "length" "4")
11170 (set_attr "type" "no_insn")]
11173 (define_insn "consttable_8"
11174 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_8)]
11178 making_const_table = TRUE;
11179 switch (GET_MODE_CLASS (GET_MODE (operands[0])))
11182 assemble_real (*CONST_DOUBLE_REAL_VALUE (operands[0]),
11183 GET_MODE (operands[0]), BITS_PER_WORD);
11186 assemble_integer (operands[0], 8, BITS_PER_WORD, 1);
11191 [(set_attr "length" "8")
11192 (set_attr "type" "no_insn")]
11195 (define_insn "consttable_16"
11196 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_16)]
11200 making_const_table = TRUE;
11201 switch (GET_MODE_CLASS (GET_MODE (operands[0])))
11204 assemble_real (*CONST_DOUBLE_REAL_VALUE (operands[0]),
11205 GET_MODE (operands[0]), BITS_PER_WORD);
11208 assemble_integer (operands[0], 16, BITS_PER_WORD, 1);
11213 [(set_attr "length" "16")
11214 (set_attr "type" "no_insn")]
11217 ;; V5 Instructions,
11219 (define_insn "clzsi2"
11220 [(set (match_operand:SI 0 "s_register_operand" "=r")
11221 (clz:SI (match_operand:SI 1 "s_register_operand" "r")))]
11222 "TARGET_32BIT && arm_arch5"
11224 [(set_attr "predicable" "yes")
11225 (set_attr "predicable_short_it" "no")
11226 (set_attr "type" "clz")])
11228 (define_insn "rbitsi2"
11229 [(set (match_operand:SI 0 "s_register_operand" "=r")
11230 (unspec:SI [(match_operand:SI 1 "s_register_operand" "r")] UNSPEC_RBIT))]
11231 "TARGET_32BIT && arm_arch_thumb2"
11233 [(set_attr "predicable" "yes")
11234 (set_attr "predicable_short_it" "no")
11235 (set_attr "type" "clz")])
11237 ;; Keep this as a CTZ expression until after reload and then split
11238 ;; into RBIT + CLZ. Since RBIT is represented as an UNSPEC it is unlikely
11239 ;; to fold with any other expression.
11241 (define_insn_and_split "ctzsi2"
11242 [(set (match_operand:SI 0 "s_register_operand" "=r")
11243 (ctz:SI (match_operand:SI 1 "s_register_operand" "r")))]
11244 "TARGET_32BIT && arm_arch_thumb2"
11246 "&& reload_completed"
11249 emit_insn (gen_rbitsi2 (operands[0], operands[1]));
11250 emit_insn (gen_clzsi2 (operands[0], operands[0]));
11254 ;; V5E instructions.
11256 (define_insn "prefetch"
11257 [(prefetch (match_operand:SI 0 "address_operand" "p")
11258 (match_operand:SI 1 "" "")
11259 (match_operand:SI 2 "" ""))]
11260 "TARGET_32BIT && arm_arch5e"
11262 [(set_attr "type" "load1")]
11265 ;; General predication pattern
11268 [(match_operator 0 "arm_comparison_operator"
11269 [(match_operand 1 "cc_register" "")
11272 && (!TARGET_NO_VOLATILE_CE || !volatile_refs_p (PATTERN (insn)))"
11274 [(set_attr "predicated" "yes")]
11277 (define_insn "force_register_use"
11278 [(unspec:SI [(match_operand:SI 0 "register_operand" "")] UNSPEC_REGISTER_USE)]
11281 [(set_attr "length" "0")
11282 (set_attr "type" "no_insn")]
11286 ;; Patterns for exception handling
11288 (define_expand "eh_return"
11289 [(use (match_operand 0 "general_operand" ""))]
11294 emit_insn (gen_arm_eh_return (operands[0]));
11296 emit_insn (gen_thumb_eh_return (operands[0]));
11301 ;; We can't expand this before we know where the link register is stored.
11302 (define_insn_and_split "arm_eh_return"
11303 [(unspec_volatile [(match_operand:SI 0 "s_register_operand" "r")]
11305 (clobber (match_scratch:SI 1 "=&r"))]
11308 "&& reload_completed"
11312 arm_set_return_address (operands[0], operands[1]);
11320 (define_insn "load_tp_hard"
11321 [(set (match_operand:SI 0 "register_operand" "=r")
11322 (unspec:SI [(const_int 0)] UNSPEC_TLS))]
11324 "mrc%?\\tp15, 0, %0, c13, c0, 3\\t@ load_tp_hard"
11325 [(set_attr "predicable" "yes")
11326 (set_attr "type" "mrs")]
11329 ;; Doesn't clobber R1-R3. Must use r0 for the first operand.
11330 (define_insn "load_tp_soft"
11331 [(set (reg:SI 0) (unspec:SI [(const_int 0)] UNSPEC_TLS))
11332 (clobber (reg:SI LR_REGNUM))
11333 (clobber (reg:SI IP_REGNUM))
11334 (clobber (reg:CC CC_REGNUM))]
11336 "bl\\t__aeabi_read_tp\\t@ load_tp_soft"
11337 [(set_attr "conds" "clob")
11338 (set_attr "type" "branch")]
11341 ;; tls descriptor call
11342 (define_insn "tlscall"
11343 [(set (reg:SI R0_REGNUM)
11344 (unspec:SI [(reg:SI R0_REGNUM)
11345 (match_operand:SI 0 "" "X")
11346 (match_operand 1 "" "")] UNSPEC_TLS))
11347 (clobber (reg:SI R1_REGNUM))
11348 (clobber (reg:SI LR_REGNUM))
11349 (clobber (reg:SI CC_REGNUM))]
11352 targetm.asm_out.internal_label (asm_out_file, "LPIC",
11353 INTVAL (operands[1]));
11354 return "bl\\t%c0(tlscall)";
11356 [(set_attr "conds" "clob")
11357 (set_attr "length" "4")
11358 (set_attr "type" "branch")]
11361 ;; For thread pointer builtin
11362 (define_expand "get_thread_pointersi"
11363 [(match_operand:SI 0 "s_register_operand" "=r")]
11367 arm_load_tp (operands[0]);
11373 ;; We only care about the lower 16 bits of the constant
11374 ;; being inserted into the upper 16 bits of the register.
11375 (define_insn "*arm_movtas_ze"
11376 [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r,r")
11379 (match_operand:SI 1 "const_int_operand" ""))]
11384 [(set_attr "arch" "32,v8mb")
11385 (set_attr "predicable" "yes")
11386 (set_attr "predicable_short_it" "no")
11387 (set_attr "length" "4")
11388 (set_attr "type" "alu_sreg")]
11391 (define_insn "*arm_rev"
11392 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r")
11393 (bswap:SI (match_operand:SI 1 "s_register_operand" "l,l,r")))]
11399 [(set_attr "arch" "t1,t2,32")
11400 (set_attr "length" "2,2,4")
11401 (set_attr "predicable" "no,yes,yes")
11402 (set_attr "predicable_short_it" "no")
11403 (set_attr "type" "rev")]
11406 (define_expand "arm_legacy_rev"
11407 [(set (match_operand:SI 2 "s_register_operand" "")
11408 (xor:SI (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
11412 (lshiftrt:SI (match_dup 2)
11414 (set (match_operand:SI 3 "s_register_operand" "")
11415 (rotatert:SI (match_dup 1)
11418 (and:SI (match_dup 2)
11419 (const_int -65281)))
11420 (set (match_operand:SI 0 "s_register_operand" "")
11421 (xor:SI (match_dup 3)
11427 ;; Reuse temporaries to keep register pressure down.
11428 (define_expand "thumb_legacy_rev"
11429 [(set (match_operand:SI 2 "s_register_operand" "")
11430 (ashift:SI (match_operand:SI 1 "s_register_operand" "")
11432 (set (match_operand:SI 3 "s_register_operand" "")
11433 (lshiftrt:SI (match_dup 1)
11436 (ior:SI (match_dup 3)
11438 (set (match_operand:SI 4 "s_register_operand" "")
11440 (set (match_operand:SI 5 "s_register_operand" "")
11441 (rotatert:SI (match_dup 1)
11444 (ashift:SI (match_dup 5)
11447 (lshiftrt:SI (match_dup 5)
11450 (ior:SI (match_dup 5)
11453 (rotatert:SI (match_dup 5)
11455 (set (match_operand:SI 0 "s_register_operand" "")
11456 (ior:SI (match_dup 5)
11462 ;; ARM-specific expansion of signed mod by power of 2
11463 ;; using conditional negate.
11464 ;; For r0 % n where n is a power of 2 produce:
11466 ;; and r0, r0, #(n - 1)
11467 ;; and r1, r1, #(n - 1)
11468 ;; rsbpl r0, r1, #0
11470 (define_expand "modsi3"
11471 [(match_operand:SI 0 "register_operand" "")
11472 (match_operand:SI 1 "register_operand" "")
11473 (match_operand:SI 2 "const_int_operand" "")]
11476 HOST_WIDE_INT val = INTVAL (operands[2]);
11479 || exact_log2 (val) <= 0)
11482 rtx mask = GEN_INT (val - 1);
11484 /* In the special case of x0 % 2 we can do the even shorter:
11487 rsblt r0, r0, #0. */
11491 rtx cc_reg = arm_gen_compare_reg (LT,
11492 operands[1], const0_rtx, NULL_RTX);
11493 rtx cond = gen_rtx_LT (SImode, cc_reg, const0_rtx);
11494 rtx masked = gen_reg_rtx (SImode);
11496 emit_insn (gen_andsi3 (masked, operands[1], mask));
11497 emit_move_insn (operands[0],
11498 gen_rtx_IF_THEN_ELSE (SImode, cond,
11499 gen_rtx_NEG (SImode,
11505 rtx neg_op = gen_reg_rtx (SImode);
11506 rtx_insn *insn = emit_insn (gen_subsi3_compare0 (neg_op, const0_rtx,
11509 /* Extract the condition register and mode. */
11510 rtx cmp = XVECEXP (PATTERN (insn), 0, 0);
11511 rtx cc_reg = SET_DEST (cmp);
11512 rtx cond = gen_rtx_GE (SImode, cc_reg, const0_rtx);
11514 emit_insn (gen_andsi3 (operands[0], operands[1], mask));
11516 rtx masked_neg = gen_reg_rtx (SImode);
11517 emit_insn (gen_andsi3 (masked_neg, neg_op, mask));
11519 /* We want a conditional negate here, but emitting COND_EXEC rtxes
11520 during expand does not always work. Do an IF_THEN_ELSE instead. */
11521 emit_move_insn (operands[0],
11522 gen_rtx_IF_THEN_ELSE (SImode, cond,
11523 gen_rtx_NEG (SImode, masked_neg),
11531 (define_expand "bswapsi2"
11532 [(set (match_operand:SI 0 "s_register_operand" "=r")
11533 (bswap:SI (match_operand:SI 1 "s_register_operand" "r")))]
11534 "TARGET_EITHER && (arm_arch6 || !optimize_size)"
11538 rtx op2 = gen_reg_rtx (SImode);
11539 rtx op3 = gen_reg_rtx (SImode);
11543 rtx op4 = gen_reg_rtx (SImode);
11544 rtx op5 = gen_reg_rtx (SImode);
11546 emit_insn (gen_thumb_legacy_rev (operands[0], operands[1],
11547 op2, op3, op4, op5));
11551 emit_insn (gen_arm_legacy_rev (operands[0], operands[1],
11560 ;; bswap16 patterns: use revsh and rev16 instructions for the signed
11561 ;; and unsigned variants, respectively. For rev16, expose
11562 ;; byte-swapping in the lower 16 bits only.
11563 (define_insn "*arm_revsh"
11564 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r")
11565 (sign_extend:SI (bswap:HI (match_operand:HI 1 "s_register_operand" "l,l,r"))))]
11571 [(set_attr "arch" "t1,t2,32")
11572 (set_attr "length" "2,2,4")
11573 (set_attr "type" "rev")]
11576 (define_insn "*arm_rev16"
11577 [(set (match_operand:HI 0 "s_register_operand" "=l,l,r")
11578 (bswap:HI (match_operand:HI 1 "s_register_operand" "l,l,r")))]
11584 [(set_attr "arch" "t1,t2,32")
11585 (set_attr "length" "2,2,4")
11586 (set_attr "type" "rev")]
11589 ;; There are no canonicalisation rules for the position of the lshiftrt, ashift
11590 ;; operations within an IOR/AND RTX, therefore we have two patterns matching
11591 ;; each valid permutation.
11593 (define_insn "arm_rev16si2"
11594 [(set (match_operand:SI 0 "register_operand" "=l,l,r")
11595 (ior:SI (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "l,l,r")
11597 (match_operand:SI 3 "const_int_operand" "n,n,n"))
11598 (and:SI (lshiftrt:SI (match_dup 1)
11600 (match_operand:SI 2 "const_int_operand" "n,n,n"))))]
11602 && aarch_rev16_shleft_mask_imm_p (operands[3], SImode)
11603 && aarch_rev16_shright_mask_imm_p (operands[2], SImode)"
11605 [(set_attr "arch" "t1,t2,32")
11606 (set_attr "length" "2,2,4")
11607 (set_attr "type" "rev")]
11610 (define_insn "arm_rev16si2_alt"
11611 [(set (match_operand:SI 0 "register_operand" "=l,l,r")
11612 (ior:SI (and:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "l,l,r")
11614 (match_operand:SI 2 "const_int_operand" "n,n,n"))
11615 (and:SI (ashift:SI (match_dup 1)
11617 (match_operand:SI 3 "const_int_operand" "n,n,n"))))]
11619 && aarch_rev16_shleft_mask_imm_p (operands[3], SImode)
11620 && aarch_rev16_shright_mask_imm_p (operands[2], SImode)"
11622 [(set_attr "arch" "t1,t2,32")
11623 (set_attr "length" "2,2,4")
11624 (set_attr "type" "rev")]
11627 (define_expand "bswaphi2"
11628 [(set (match_operand:HI 0 "s_register_operand" "=r")
11629 (bswap:HI (match_operand:HI 1 "s_register_operand" "r")))]
11634 ;; Patterns for LDRD/STRD in Thumb2 mode
11636 (define_insn "*thumb2_ldrd"
11637 [(set (match_operand:SI 0 "s_register_operand" "=r")
11638 (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "rk")
11639 (match_operand:SI 2 "ldrd_strd_offset_operand" "Do"))))
11640 (set (match_operand:SI 3 "s_register_operand" "=r")
11641 (mem:SI (plus:SI (match_dup 1)
11642 (match_operand:SI 4 "const_int_operand" ""))))]
11643 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11644 && current_tune->prefer_ldrd_strd
11645 && ((INTVAL (operands[2]) + 4) == INTVAL (operands[4]))
11646 && (operands_ok_ldrd_strd (operands[0], operands[3],
11647 operands[1], INTVAL (operands[2]),
11649 "ldrd%?\t%0, %3, [%1, %2]"
11650 [(set_attr "type" "load2")
11651 (set_attr "predicable" "yes")
11652 (set_attr "predicable_short_it" "no")])
11654 (define_insn "*thumb2_ldrd_base"
11655 [(set (match_operand:SI 0 "s_register_operand" "=r")
11656 (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
11657 (set (match_operand:SI 2 "s_register_operand" "=r")
11658 (mem:SI (plus:SI (match_dup 1)
11660 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11661 && current_tune->prefer_ldrd_strd
11662 && (operands_ok_ldrd_strd (operands[0], operands[2],
11663 operands[1], 0, false, true))"
11664 "ldrd%?\t%0, %2, [%1]"
11665 [(set_attr "type" "load2")
11666 (set_attr "predicable" "yes")
11667 (set_attr "predicable_short_it" "no")])
11669 (define_insn "*thumb2_ldrd_base_neg"
11670 [(set (match_operand:SI 0 "s_register_operand" "=r")
11671 (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "rk")
11673 (set (match_operand:SI 2 "s_register_operand" "=r")
11674 (mem:SI (match_dup 1)))]
11675 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11676 && current_tune->prefer_ldrd_strd
11677 && (operands_ok_ldrd_strd (operands[0], operands[2],
11678 operands[1], -4, false, true))"
11679 "ldrd%?\t%0, %2, [%1, #-4]"
11680 [(set_attr "type" "load2")
11681 (set_attr "predicable" "yes")
11682 (set_attr "predicable_short_it" "no")])
11684 (define_insn "*thumb2_strd"
11685 [(set (mem:SI (plus:SI (match_operand:SI 0 "s_register_operand" "rk")
11686 (match_operand:SI 1 "ldrd_strd_offset_operand" "Do")))
11687 (match_operand:SI 2 "s_register_operand" "r"))
11688 (set (mem:SI (plus:SI (match_dup 0)
11689 (match_operand:SI 3 "const_int_operand" "")))
11690 (match_operand:SI 4 "s_register_operand" "r"))]
11691 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11692 && current_tune->prefer_ldrd_strd
11693 && ((INTVAL (operands[1]) + 4) == INTVAL (operands[3]))
11694 && (operands_ok_ldrd_strd (operands[2], operands[4],
11695 operands[0], INTVAL (operands[1]),
11697 "strd%?\t%2, %4, [%0, %1]"
11698 [(set_attr "type" "store2")
11699 (set_attr "predicable" "yes")
11700 (set_attr "predicable_short_it" "no")])
11702 (define_insn "*thumb2_strd_base"
11703 [(set (mem:SI (match_operand:SI 0 "s_register_operand" "rk"))
11704 (match_operand:SI 1 "s_register_operand" "r"))
11705 (set (mem:SI (plus:SI (match_dup 0)
11707 (match_operand:SI 2 "s_register_operand" "r"))]
11708 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11709 && current_tune->prefer_ldrd_strd
11710 && (operands_ok_ldrd_strd (operands[1], operands[2],
11711 operands[0], 0, false, false))"
11712 "strd%?\t%1, %2, [%0]"
11713 [(set_attr "type" "store2")
11714 (set_attr "predicable" "yes")
11715 (set_attr "predicable_short_it" "no")])
11717 (define_insn "*thumb2_strd_base_neg"
11718 [(set (mem:SI (plus:SI (match_operand:SI 0 "s_register_operand" "rk")
11720 (match_operand:SI 1 "s_register_operand" "r"))
11721 (set (mem:SI (match_dup 0))
11722 (match_operand:SI 2 "s_register_operand" "r"))]
11723 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11724 && current_tune->prefer_ldrd_strd
11725 && (operands_ok_ldrd_strd (operands[1], operands[2],
11726 operands[0], -4, false, false))"
11727 "strd%?\t%1, %2, [%0, #-4]"
11728 [(set_attr "type" "store2")
11729 (set_attr "predicable" "yes")
11730 (set_attr "predicable_short_it" "no")])
11732 ;; ARMv8 CRC32 instructions.
11733 (define_insn "<crc_variant>"
11734 [(set (match_operand:SI 0 "s_register_operand" "=r")
11735 (unspec:SI [(match_operand:SI 1 "s_register_operand" "r")
11736 (match_operand:<crc_mode> 2 "s_register_operand" "r")]
11739 "<crc_variant>\\t%0, %1, %2"
11740 [(set_attr "type" "crc")
11741 (set_attr "conds" "unconditional")]
11744 ;; Load the load/store double peephole optimizations.
11745 (include "ldrdstrd.md")
11747 ;; Load the load/store multiple patterns
11748 (include "ldmstm.md")
11750 ;; Patterns in ldmstm.md don't cover more than 4 registers. This pattern covers
11751 ;; large lists without explicit writeback generated for APCS_FRAME epilogue.
11752 (define_insn "*load_multiple"
11753 [(match_parallel 0 "load_multiple_operation"
11754 [(set (match_operand:SI 2 "s_register_operand" "=rk")
11755 (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
11760 arm_output_multireg_pop (operands, /*return_pc=*/false,
11761 /*cond=*/const_true_rtx,
11767 [(set_attr "predicable" "yes")]
11770 (define_expand "copysignsf3"
11771 [(match_operand:SF 0 "register_operand")
11772 (match_operand:SF 1 "register_operand")
11773 (match_operand:SF 2 "register_operand")]
11774 "TARGET_SOFT_FLOAT && arm_arch_thumb2"
11776 emit_move_insn (operands[0], operands[2]);
11777 emit_insn (gen_insv_t2 (simplify_gen_subreg (SImode, operands[0], SFmode, 0),
11778 GEN_INT (31), GEN_INT (0),
11779 simplify_gen_subreg (SImode, operands[1], SFmode, 0)));
11784 (define_expand "copysigndf3"
11785 [(match_operand:DF 0 "register_operand")
11786 (match_operand:DF 1 "register_operand")
11787 (match_operand:DF 2 "register_operand")]
11788 "TARGET_SOFT_FLOAT && arm_arch_thumb2"
11790 rtx op0_low = gen_lowpart (SImode, operands[0]);
11791 rtx op0_high = gen_highpart (SImode, operands[0]);
11792 rtx op1_low = gen_lowpart (SImode, operands[1]);
11793 rtx op1_high = gen_highpart (SImode, operands[1]);
11794 rtx op2_high = gen_highpart (SImode, operands[2]);
11796 rtx scratch1 = gen_reg_rtx (SImode);
11797 rtx scratch2 = gen_reg_rtx (SImode);
11798 emit_move_insn (scratch1, op2_high);
11799 emit_move_insn (scratch2, op1_high);
11801 emit_insn(gen_rtx_SET(scratch1,
11802 gen_rtx_LSHIFTRT (SImode, op2_high, GEN_INT(31))));
11803 emit_insn(gen_insv_t2(scratch2, GEN_INT(1), GEN_INT(31), scratch1));
11804 emit_move_insn (op0_low, op1_low);
11805 emit_move_insn (op0_high, scratch2);
11811 ;; movmisalign patterns for HImode and SImode.
11812 (define_expand "movmisalign<mode>"
11813 [(match_operand:HSI 0 "general_operand")
11814 (match_operand:HSI 1 "general_operand")]
11817 /* This pattern is not permitted to fail during expansion: if both arguments
11818 are non-registers (e.g. memory := constant), force operand 1 into a
11820 rtx (* gen_unaligned_load)(rtx, rtx);
11821 rtx tmp_dest = operands[0];
11822 if (!s_register_operand (operands[0], <MODE>mode)
11823 && !s_register_operand (operands[1], <MODE>mode))
11824 operands[1] = force_reg (<MODE>mode, operands[1]);
11826 if (<MODE>mode == HImode)
11828 gen_unaligned_load = gen_unaligned_loadhiu;
11829 tmp_dest = gen_reg_rtx (SImode);
11832 gen_unaligned_load = gen_unaligned_loadsi;
11834 if (MEM_P (operands[1]))
11836 emit_insn (gen_unaligned_load (tmp_dest, operands[1]));
11837 if (<MODE>mode == HImode)
11838 emit_move_insn (operands[0], gen_lowpart (HImode, tmp_dest));
11841 emit_insn (gen_unaligned_store<mode> (operands[0], operands[1]));
11846 ;; Vector bits common to IWMMXT and Neon
11847 (include "vec-common.md")
11848 ;; Load the Intel Wireless Multimedia Extension patterns
11849 (include "iwmmxt.md")
11850 ;; Load the VFP co-processor patterns
11852 ;; Thumb-1 patterns
11853 (include "thumb1.md")
11854 ;; Thumb-2 patterns
11855 (include "thumb2.md")
11857 (include "neon.md")
11859 (include "crypto.md")
11860 ;; Synchronization Primitives
11861 (include "sync.md")
11862 ;; Fixed-point patterns
11863 (include "arm-fixed.md")